clang API Documentation

SemaAttr.cpp
Go to the documentation of this file.
00001 //===--- SemaAttr.cpp - Semantic Analysis for Attributes ------------------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file implements semantic analysis for non-trivial attributes and
00011 // pragmas.
00012 //
00013 //===----------------------------------------------------------------------===//
00014 
00015 #include "clang/Sema/SemaInternal.h"
00016 #include "clang/AST/ASTConsumer.h"
00017 #include "clang/AST/Attr.h"
00018 #include "clang/AST/Expr.h"
00019 #include "clang/Basic/TargetInfo.h"
00020 #include "clang/Lex/Preprocessor.h"
00021 #include "clang/Sema/Lookup.h"
00022 using namespace clang;
00023 
00024 //===----------------------------------------------------------------------===//
00025 // Pragma 'pack' and 'options align'
00026 //===----------------------------------------------------------------------===//
00027 
00028 namespace {
00029   struct PackStackEntry {
00030     // We just use a sentinel to represent when the stack is set to mac68k
00031     // alignment.
00032     static const unsigned kMac68kAlignmentSentinel = ~0U;
00033 
00034     unsigned Alignment;
00035     IdentifierInfo *Name;
00036   };
00037 
00038   /// PragmaPackStack - Simple class to wrap the stack used by #pragma
00039   /// pack.
00040   class PragmaPackStack {
00041     typedef std::vector<PackStackEntry> stack_ty;
00042 
00043     /// Alignment - The current user specified alignment.
00044     unsigned Alignment;
00045 
00046     /// Stack - Entries in the #pragma pack stack, consisting of saved
00047     /// alignments and optional names.
00048     stack_ty Stack;
00049 
00050   public:
00051     PragmaPackStack() : Alignment(0) {}
00052 
00053     void setAlignment(unsigned A) { Alignment = A; }
00054     unsigned getAlignment() { return Alignment; }
00055 
00056     /// push - Push the current alignment onto the stack, optionally
00057     /// using the given \arg Name for the record, if non-zero.
00058     void push(IdentifierInfo *Name) {
00059       PackStackEntry PSE = { Alignment, Name };
00060       Stack.push_back(PSE);
00061     }
00062 
00063     /// pop - Pop a record from the stack and restore the current
00064     /// alignment to the previous value. If \arg Name is non-zero then
00065     /// the first such named record is popped, otherwise the top record
00066     /// is popped. Returns true if the pop succeeded.
00067     bool pop(IdentifierInfo *Name, bool IsReset);
00068   };
00069 }  // end anonymous namespace.
00070 
00071 bool PragmaPackStack::pop(IdentifierInfo *Name, bool IsReset) {
00072   // If name is empty just pop top.
00073   if (!Name) {
00074     // An empty stack is a special case...
00075     if (Stack.empty()) {
00076       // If this isn't a reset, it is always an error.
00077       if (!IsReset)
00078         return false;
00079 
00080       // Otherwise, it is an error only if some alignment has been set.
00081       if (!Alignment)
00082         return false;
00083 
00084       // Otherwise, reset to the default alignment.
00085       Alignment = 0;
00086     } else {
00087       Alignment = Stack.back().Alignment;
00088       Stack.pop_back();
00089     }
00090 
00091     return true;
00092   }
00093 
00094   // Otherwise, find the named record.
00095   for (unsigned i = Stack.size(); i != 0; ) {
00096     --i;
00097     if (Stack[i].Name == Name) {
00098       // Found it, pop up to and including this record.
00099       Alignment = Stack[i].Alignment;
00100       Stack.erase(Stack.begin() + i, Stack.end());
00101       return true;
00102     }
00103   }
00104 
00105   return false;
00106 }
00107 
00108 
00109 /// FreePackedContext - Deallocate and null out PackContext.
00110 void Sema::FreePackedContext() {
00111   delete static_cast<PragmaPackStack*>(PackContext);
00112   PackContext = nullptr;
00113 }
00114 
00115 void Sema::AddAlignmentAttributesForRecord(RecordDecl *RD) {
00116   // If there is no pack context, we don't need any attributes.
00117   if (!PackContext)
00118     return;
00119 
00120   PragmaPackStack *Stack = static_cast<PragmaPackStack*>(PackContext);
00121 
00122   // Otherwise, check to see if we need a max field alignment attribute.
00123   if (unsigned Alignment = Stack->getAlignment()) {
00124     if (Alignment == PackStackEntry::kMac68kAlignmentSentinel)
00125       RD->addAttr(AlignMac68kAttr::CreateImplicit(Context));
00126     else
00127       RD->addAttr(MaxFieldAlignmentAttr::CreateImplicit(Context,
00128                                                         Alignment * 8));
00129   }
00130 }
00131 
00132 void Sema::AddMsStructLayoutForRecord(RecordDecl *RD) {
00133   if (MSStructPragmaOn)
00134     RD->addAttr(MsStructAttr::CreateImplicit(Context));
00135 
00136   // FIXME: We should merge AddAlignmentAttributesForRecord with
00137   // AddMsStructLayoutForRecord into AddPragmaAttributesForRecord, which takes
00138   // all active pragmas and applies them as attributes to class definitions.
00139   if (VtorDispModeStack.back() != getLangOpts().VtorDispMode)
00140     RD->addAttr(
00141         MSVtorDispAttr::CreateImplicit(Context, VtorDispModeStack.back()));
00142 }
00143 
00144 void Sema::ActOnPragmaOptionsAlign(PragmaOptionsAlignKind Kind,
00145                                    SourceLocation PragmaLoc) {
00146   if (!PackContext)
00147     PackContext = new PragmaPackStack();
00148 
00149   PragmaPackStack *Context = static_cast<PragmaPackStack*>(PackContext);
00150 
00151   switch (Kind) {
00152     // For all targets we support native and natural are the same.
00153     //
00154     // FIXME: This is not true on Darwin/PPC.
00155   case POAK_Native:
00156   case POAK_Power:
00157   case POAK_Natural:
00158     Context->push(nullptr);
00159     Context->setAlignment(0);
00160     break;
00161 
00162     // Note that '#pragma options align=packed' is not equivalent to attribute
00163     // packed, it has a different precedence relative to attribute aligned.
00164   case POAK_Packed:
00165     Context->push(nullptr);
00166     Context->setAlignment(1);
00167     break;
00168 
00169   case POAK_Mac68k:
00170     // Check if the target supports this.
00171     if (!this->Context.getTargetInfo().hasAlignMac68kSupport()) {
00172       Diag(PragmaLoc, diag::err_pragma_options_align_mac68k_target_unsupported);
00173       return;
00174     }
00175     Context->push(nullptr);
00176     Context->setAlignment(PackStackEntry::kMac68kAlignmentSentinel);
00177     break;
00178 
00179   case POAK_Reset:
00180     // Reset just pops the top of the stack, or resets the current alignment to
00181     // default.
00182     if (!Context->pop(nullptr, /*IsReset=*/true)) {
00183       Diag(PragmaLoc, diag::warn_pragma_options_align_reset_failed)
00184         << "stack empty";
00185     }
00186     break;
00187   }
00188 }
00189 
00190 void Sema::ActOnPragmaPack(PragmaPackKind Kind, IdentifierInfo *Name,
00191                            Expr *alignment, SourceLocation PragmaLoc,
00192                            SourceLocation LParenLoc, SourceLocation RParenLoc) {
00193   Expr *Alignment = static_cast<Expr *>(alignment);
00194 
00195   // If specified then alignment must be a "small" power of two.
00196   unsigned AlignmentVal = 0;
00197   if (Alignment) {
00198     llvm::APSInt Val;
00199 
00200     // pack(0) is like pack(), which just works out since that is what
00201     // we use 0 for in PackAttr.
00202     if (Alignment->isTypeDependent() ||
00203         Alignment->isValueDependent() ||
00204         !Alignment->isIntegerConstantExpr(Val, Context) ||
00205         !(Val == 0 || Val.isPowerOf2()) ||
00206         Val.getZExtValue() > 16) {
00207       Diag(PragmaLoc, diag::warn_pragma_pack_invalid_alignment);
00208       return; // Ignore
00209     }
00210 
00211     AlignmentVal = (unsigned) Val.getZExtValue();
00212   }
00213 
00214   if (!PackContext)
00215     PackContext = new PragmaPackStack();
00216 
00217   PragmaPackStack *Context = static_cast<PragmaPackStack*>(PackContext);
00218 
00219   switch (Kind) {
00220   case Sema::PPK_Default: // pack([n])
00221     Context->setAlignment(AlignmentVal);
00222     break;
00223 
00224   case Sema::PPK_Show: // pack(show)
00225     // Show the current alignment, making sure to show the right value
00226     // for the default.
00227     AlignmentVal = Context->getAlignment();
00228     // FIXME: This should come from the target.
00229     if (AlignmentVal == 0)
00230       AlignmentVal = 8;
00231     if (AlignmentVal == PackStackEntry::kMac68kAlignmentSentinel)
00232       Diag(PragmaLoc, diag::warn_pragma_pack_show) << "mac68k";
00233     else
00234       Diag(PragmaLoc, diag::warn_pragma_pack_show) << AlignmentVal;
00235     break;
00236 
00237   case Sema::PPK_Push: // pack(push [, id] [, [n])
00238     Context->push(Name);
00239     // Set the new alignment if specified.
00240     if (Alignment)
00241       Context->setAlignment(AlignmentVal);
00242     break;
00243 
00244   case Sema::PPK_Pop: // pack(pop [, id] [,  n])
00245     // MSDN, C/C++ Preprocessor Reference > Pragma Directives > pack:
00246     // "#pragma pack(pop, identifier, n) is undefined"
00247     if (Alignment && Name)
00248       Diag(PragmaLoc, diag::warn_pragma_pack_pop_identifer_and_alignment);
00249 
00250     // Do the pop.
00251     if (!Context->pop(Name, /*IsReset=*/false)) {
00252       // If a name was specified then failure indicates the name
00253       // wasn't found. Otherwise failure indicates the stack was
00254       // empty.
00255       Diag(PragmaLoc, diag::warn_pragma_pop_failed)
00256           << "pack" << (Name ? "no record matching name" : "stack empty");
00257 
00258       // FIXME: Warn about popping named records as MSVC does.
00259     } else {
00260       // Pop succeeded, set the new alignment if specified.
00261       if (Alignment)
00262         Context->setAlignment(AlignmentVal);
00263     }
00264     break;
00265   }
00266 }
00267 
00268 void Sema::ActOnPragmaMSStruct(PragmaMSStructKind Kind) { 
00269   MSStructPragmaOn = (Kind == PMSST_ON);
00270 }
00271 
00272 void Sema::ActOnPragmaMSComment(PragmaMSCommentKind Kind, StringRef Arg) {
00273   // FIXME: Serialize this.
00274   switch (Kind) {
00275   case PCK_Unknown:
00276     llvm_unreachable("unexpected pragma comment kind");
00277   case PCK_Linker:
00278     Consumer.HandleLinkerOptionPragma(Arg);
00279     return;
00280   case PCK_Lib:
00281     Consumer.HandleDependentLibrary(Arg);
00282     return;
00283   case PCK_Compiler:
00284   case PCK_ExeStr:
00285   case PCK_User:
00286     return;  // We ignore all of these.
00287   }
00288   llvm_unreachable("invalid pragma comment kind");
00289 }
00290 
00291 void Sema::ActOnPragmaDetectMismatch(StringRef Name, StringRef Value) {
00292   // FIXME: Serialize this.
00293   Consumer.HandleDetectMismatch(Name, Value);
00294 }
00295 
00296 void Sema::ActOnPragmaMSPointersToMembers(
00297     LangOptions::PragmaMSPointersToMembersKind RepresentationMethod,
00298     SourceLocation PragmaLoc) {
00299   MSPointerToMemberRepresentationMethod = RepresentationMethod;
00300   ImplicitMSInheritanceAttrLoc = PragmaLoc;
00301 }
00302 
00303 void Sema::ActOnPragmaMSVtorDisp(PragmaVtorDispKind Kind,
00304                                  SourceLocation PragmaLoc,
00305                                  MSVtorDispAttr::Mode Mode) {
00306   switch (Kind) {
00307   case PVDK_Set:
00308     VtorDispModeStack.back() = Mode;
00309     break;
00310   case PVDK_Push:
00311     VtorDispModeStack.push_back(Mode);
00312     break;
00313   case PVDK_Reset:
00314     VtorDispModeStack.clear();
00315     VtorDispModeStack.push_back(MSVtorDispAttr::Mode(LangOpts.VtorDispMode));
00316     break;
00317   case PVDK_Pop:
00318     VtorDispModeStack.pop_back();
00319     if (VtorDispModeStack.empty()) {
00320       Diag(PragmaLoc, diag::warn_pragma_pop_failed) << "vtordisp"
00321                                                     << "stack empty";
00322       VtorDispModeStack.push_back(MSVtorDispAttr::Mode(LangOpts.VtorDispMode));
00323     }
00324     break;
00325   }
00326 }
00327 
00328 template<typename ValueType>
00329 void Sema::PragmaStack<ValueType>::Act(SourceLocation PragmaLocation,
00330                                        PragmaMsStackAction Action,
00331                                        llvm::StringRef StackSlotLabel,
00332                                        ValueType Value) {
00333   if (Action == PSK_Reset) {
00334     CurrentValue = nullptr;
00335     return;
00336   }
00337   if (Action & PSK_Push)
00338     Stack.push_back(Slot(StackSlotLabel, CurrentValue, CurrentPragmaLocation));
00339   else if (Action & PSK_Pop) {
00340     if (!StackSlotLabel.empty()) {
00341       // If we've got a label, try to find it and jump there.
00342       auto I = std::find_if(Stack.rbegin(), Stack.rend(),
00343         [&](const Slot &x) { return x.StackSlotLabel == StackSlotLabel; });
00344       // If we found the label so pop from there.
00345       if (I != Stack.rend()) {
00346         CurrentValue = I->Value;
00347         CurrentPragmaLocation = I->PragmaLocation;
00348         Stack.erase(std::prev(I.base()), Stack.end());
00349       }
00350     } else if (!Stack.empty()) {
00351       // We don't have a label, just pop the last entry.
00352       CurrentValue = Stack.back().Value;
00353       CurrentPragmaLocation = Stack.back().PragmaLocation;
00354       Stack.pop_back();
00355     }
00356   }
00357   if (Action & PSK_Set) {
00358     CurrentValue = Value;
00359     CurrentPragmaLocation = PragmaLocation;
00360   }
00361 }
00362 
00363 bool Sema::UnifySection(StringRef SectionName,
00364                         int SectionFlags,
00365                         DeclaratorDecl *Decl) {
00366   auto Section = Context.SectionInfos.find(SectionName);
00367   if (Section == Context.SectionInfos.end()) {
00368     Context.SectionInfos[SectionName] =
00369         ASTContext::SectionInfo(Decl, SourceLocation(), SectionFlags);
00370     return false;
00371   }
00372   // A pre-declared section takes precedence w/o diagnostic.
00373   if (Section->second.SectionFlags == SectionFlags ||
00374       !(Section->second.SectionFlags & ASTContext::PSF_Implicit))
00375     return false;
00376   auto OtherDecl = Section->second.Decl;
00377   Diag(Decl->getLocation(), diag::err_section_conflict)
00378       << Decl << OtherDecl;
00379   Diag(OtherDecl->getLocation(), diag::note_declared_at)
00380       << OtherDecl->getName();
00381   if (auto A = Decl->getAttr<SectionAttr>())
00382     if (A->isImplicit())
00383       Diag(A->getLocation(), diag::note_pragma_entered_here);
00384   if (auto A = OtherDecl->getAttr<SectionAttr>())
00385     if (A->isImplicit())
00386       Diag(A->getLocation(), diag::note_pragma_entered_here);
00387   return true;
00388 }
00389 
00390 bool Sema::UnifySection(StringRef SectionName,
00391                         int SectionFlags,
00392                         SourceLocation PragmaSectionLocation) {
00393   auto Section = Context.SectionInfos.find(SectionName);
00394   if (Section != Context.SectionInfos.end()) {
00395     if (Section->second.SectionFlags == SectionFlags)
00396       return false;
00397     if (!(Section->second.SectionFlags & ASTContext::PSF_Implicit)) {
00398       Diag(PragmaSectionLocation, diag::err_section_conflict)
00399           << "this" << "a prior #pragma section";
00400       Diag(Section->second.PragmaSectionLocation,
00401            diag::note_pragma_entered_here);
00402       return true;
00403     }
00404   }
00405   Context.SectionInfos[SectionName] =
00406       ASTContext::SectionInfo(nullptr, PragmaSectionLocation, SectionFlags);
00407   return false;
00408 }
00409 
00410 /// \brief Called on well formed \#pragma bss_seg().
00411 void Sema::ActOnPragmaMSSeg(SourceLocation PragmaLocation,
00412                             PragmaMsStackAction Action,
00413                             llvm::StringRef StackSlotLabel,
00414                             StringLiteral *SegmentName,
00415                             llvm::StringRef PragmaName) {
00416   PragmaStack<StringLiteral *> *Stack =
00417     llvm::StringSwitch<PragmaStack<StringLiteral *> *>(PragmaName)
00418         .Case("data_seg", &DataSegStack)
00419         .Case("bss_seg", &BSSSegStack)
00420         .Case("const_seg", &ConstSegStack)
00421         .Case("code_seg", &CodeSegStack);
00422   if (Action & PSK_Pop && Stack->Stack.empty())
00423     Diag(PragmaLocation, diag::warn_pragma_pop_failed) << PragmaName
00424         << "stack empty";
00425   Stack->Act(PragmaLocation, Action, StackSlotLabel, SegmentName);
00426 }
00427 
00428 /// \brief Called on well formed \#pragma bss_seg().
00429 void Sema::ActOnPragmaMSSection(SourceLocation PragmaLocation,
00430                                 int SectionFlags, StringLiteral *SegmentName) {
00431   UnifySection(SegmentName->getString(), SectionFlags, PragmaLocation);
00432 }
00433 
00434 void Sema::ActOnPragmaMSInitSeg(SourceLocation PragmaLocation,
00435                                 StringLiteral *SegmentName) {
00436   // There's no stack to maintain, so we just have a current section.  When we
00437   // see the default section, reset our current section back to null so we stop
00438   // tacking on unnecessary attributes.
00439   CurInitSeg = SegmentName->getString() == ".CRT$XCU" ? nullptr : SegmentName;
00440   CurInitSegLoc = PragmaLocation;
00441 }
00442 
00443 void Sema::ActOnPragmaUnused(const Token &IdTok, Scope *curScope,
00444                              SourceLocation PragmaLoc) {
00445 
00446   IdentifierInfo *Name = IdTok.getIdentifierInfo();
00447   LookupResult Lookup(*this, Name, IdTok.getLocation(), LookupOrdinaryName);
00448   LookupParsedName(Lookup, curScope, nullptr, true);
00449 
00450   if (Lookup.empty()) {
00451     Diag(PragmaLoc, diag::warn_pragma_unused_undeclared_var)
00452       << Name << SourceRange(IdTok.getLocation());
00453     return;
00454   }
00455 
00456   VarDecl *VD = Lookup.getAsSingle<VarDecl>();
00457   if (!VD) {
00458     Diag(PragmaLoc, diag::warn_pragma_unused_expected_var_arg)
00459       << Name << SourceRange(IdTok.getLocation());
00460     return;
00461   }
00462 
00463   // Warn if this was used before being marked unused.
00464   if (VD->isUsed())
00465     Diag(PragmaLoc, diag::warn_used_but_marked_unused) << Name;
00466 
00467   VD->addAttr(UnusedAttr::CreateImplicit(Context, IdTok.getLocation()));
00468 }
00469 
00470 void Sema::AddCFAuditedAttribute(Decl *D) {
00471   SourceLocation Loc = PP.getPragmaARCCFCodeAuditedLoc();
00472   if (!Loc.isValid()) return;
00473 
00474   // Don't add a redundant or conflicting attribute.
00475   if (D->hasAttr<CFAuditedTransferAttr>() ||
00476       D->hasAttr<CFUnknownTransferAttr>())
00477     return;
00478 
00479   D->addAttr(CFAuditedTransferAttr::CreateImplicit(Context, Loc));
00480 }
00481 
00482 void Sema::ActOnPragmaOptimize(bool On, SourceLocation PragmaLoc) {
00483   if(On)
00484     OptimizeOffPragmaLocation = SourceLocation();
00485   else
00486     OptimizeOffPragmaLocation = PragmaLoc;
00487 }
00488 
00489 void Sema::AddRangeBasedOptnone(FunctionDecl *FD) {
00490   // In the future, check other pragmas if they're implemented (e.g. pragma
00491   // optimize 0 will probably map to this functionality too).
00492   if(OptimizeOffPragmaLocation.isValid())
00493     AddOptnoneAttributeIfNoConflicts(FD, OptimizeOffPragmaLocation);
00494 }
00495 
00496 void Sema::AddOptnoneAttributeIfNoConflicts(FunctionDecl *FD, 
00497                                             SourceLocation Loc) {
00498   // Don't add a conflicting attribute. No diagnostic is needed.
00499   if (FD->hasAttr<MinSizeAttr>() || FD->hasAttr<AlwaysInlineAttr>())
00500     return;
00501 
00502   // Add attributes only if required. Optnone requires noinline as well, but if
00503   // either is already present then don't bother adding them.
00504   if (!FD->hasAttr<OptimizeNoneAttr>())
00505     FD->addAttr(OptimizeNoneAttr::CreateImplicit(Context, Loc));
00506   if (!FD->hasAttr<NoInlineAttr>())
00507     FD->addAttr(NoInlineAttr::CreateImplicit(Context, Loc));
00508 }
00509 
00510 typedef std::vector<std::pair<unsigned, SourceLocation> > VisStack;
00511 enum : unsigned { NoVisibility = ~0U };
00512 
00513 void Sema::AddPushedVisibilityAttribute(Decl *D) {
00514   if (!VisContext)
00515     return;
00516 
00517   NamedDecl *ND = dyn_cast<NamedDecl>(D);
00518   if (ND && ND->getExplicitVisibility(NamedDecl::VisibilityForValue))
00519     return;
00520 
00521   VisStack *Stack = static_cast<VisStack*>(VisContext);
00522   unsigned rawType = Stack->back().first;
00523   if (rawType == NoVisibility) return;
00524 
00525   VisibilityAttr::VisibilityType type
00526     = (VisibilityAttr::VisibilityType) rawType;
00527   SourceLocation loc = Stack->back().second;
00528 
00529   D->addAttr(VisibilityAttr::CreateImplicit(Context, type, loc));
00530 }
00531 
00532 /// FreeVisContext - Deallocate and null out VisContext.
00533 void Sema::FreeVisContext() {
00534   delete static_cast<VisStack*>(VisContext);
00535   VisContext = nullptr;
00536 }
00537 
00538 static void PushPragmaVisibility(Sema &S, unsigned type, SourceLocation loc) {
00539   // Put visibility on stack.
00540   if (!S.VisContext)
00541     S.VisContext = new VisStack;
00542 
00543   VisStack *Stack = static_cast<VisStack*>(S.VisContext);
00544   Stack->push_back(std::make_pair(type, loc));
00545 }
00546 
00547 void Sema::ActOnPragmaVisibility(const IdentifierInfo* VisType,
00548                                  SourceLocation PragmaLoc) {
00549   if (VisType) {
00550     // Compute visibility to use.
00551     VisibilityAttr::VisibilityType T;
00552     if (!VisibilityAttr::ConvertStrToVisibilityType(VisType->getName(), T)) {
00553       Diag(PragmaLoc, diag::warn_attribute_unknown_visibility) << VisType;
00554       return;
00555     }
00556     PushPragmaVisibility(*this, T, PragmaLoc);
00557   } else {
00558     PopPragmaVisibility(false, PragmaLoc);
00559   }
00560 }
00561 
00562 void Sema::ActOnPragmaFPContract(tok::OnOffSwitch OOS) {
00563   switch (OOS) {
00564   case tok::OOS_ON:
00565     FPFeatures.fp_contract = 1;
00566     break;
00567   case tok::OOS_OFF:
00568     FPFeatures.fp_contract = 0; 
00569     break;
00570   case tok::OOS_DEFAULT:
00571     FPFeatures.fp_contract = getLangOpts().DefaultFPContract;
00572     break;
00573   }
00574 }
00575 
00576 void Sema::PushNamespaceVisibilityAttr(const VisibilityAttr *Attr,
00577                                        SourceLocation Loc) {
00578   // Visibility calculations will consider the namespace's visibility.
00579   // Here we just want to note that we're in a visibility context
00580   // which overrides any enclosing #pragma context, but doesn't itself
00581   // contribute visibility.
00582   PushPragmaVisibility(*this, NoVisibility, Loc);
00583 }
00584 
00585 void Sema::PopPragmaVisibility(bool IsNamespaceEnd, SourceLocation EndLoc) {
00586   if (!VisContext) {
00587     Diag(EndLoc, diag::err_pragma_pop_visibility_mismatch);
00588     return;
00589   }
00590 
00591   // Pop visibility from stack
00592   VisStack *Stack = static_cast<VisStack*>(VisContext);
00593 
00594   const std::pair<unsigned, SourceLocation> *Back = &Stack->back();
00595   bool StartsWithPragma = Back->first != NoVisibility;
00596   if (StartsWithPragma && IsNamespaceEnd) {
00597     Diag(Back->second, diag::err_pragma_push_visibility_mismatch);
00598     Diag(EndLoc, diag::note_surrounding_namespace_ends_here);
00599 
00600     // For better error recovery, eat all pushes inside the namespace.
00601     do {
00602       Stack->pop_back();
00603       Back = &Stack->back();
00604       StartsWithPragma = Back->first != NoVisibility;
00605     } while (StartsWithPragma);
00606   } else if (!StartsWithPragma && !IsNamespaceEnd) {
00607     Diag(EndLoc, diag::err_pragma_pop_visibility_mismatch);
00608     Diag(Back->second, diag::note_surrounding_namespace_starts_here);
00609     return;
00610   }
00611 
00612   Stack->pop_back();
00613   // To simplify the implementation, never keep around an empty stack.
00614   if (Stack->empty())
00615     FreeVisContext();
00616 }