clang API Documentation
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 }