SemaAttr.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619
  1. //===--- SemaAttr.cpp - Semantic Analysis for Attributes ------------------===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // This file implements semantic analysis for non-trivial attributes and
  11. // pragmas.
  12. //
  13. //===----------------------------------------------------------------------===//
  14. #include "clang/Sema/SemaInternal.h"
  15. #include "clang/AST/ASTConsumer.h"
  16. #include "clang/AST/Attr.h"
  17. #include "clang/AST/Expr.h"
  18. #include "clang/Basic/TargetInfo.h"
  19. #include "clang/Lex/Preprocessor.h"
  20. #include "clang/Sema/Lookup.h"
  21. using namespace clang;
  22. //===----------------------------------------------------------------------===//
  23. // Pragma 'pack' and 'options align'
  24. //===----------------------------------------------------------------------===//
  25. namespace {
  26. struct PackStackEntry {
  27. // We just use a sentinel to represent when the stack is set to mac68k
  28. // alignment.
  29. static const unsigned kMac68kAlignmentSentinel = ~0U;
  30. unsigned Alignment;
  31. IdentifierInfo *Name;
  32. };
  33. /// PragmaPackStack - Simple class to wrap the stack used by #pragma
  34. /// pack.
  35. class PragmaPackStack {
  36. typedef std::vector<PackStackEntry> stack_ty;
  37. /// Alignment - The current user specified alignment.
  38. unsigned Alignment;
  39. /// Stack - Entries in the #pragma pack stack, consisting of saved
  40. /// alignments and optional names.
  41. stack_ty Stack;
  42. public:
  43. PragmaPackStack() : Alignment(0) {}
  44. void setAlignment(unsigned A) { Alignment = A; }
  45. unsigned getAlignment() { return Alignment; }
  46. /// push - Push the current alignment onto the stack, optionally
  47. /// using the given \arg Name for the record, if non-zero.
  48. void push(IdentifierInfo *Name) {
  49. PackStackEntry PSE = { Alignment, Name };
  50. Stack.push_back(PSE);
  51. }
  52. /// pop - Pop a record from the stack and restore the current
  53. /// alignment to the previous value. If \arg Name is non-zero then
  54. /// the first such named record is popped, otherwise the top record
  55. /// is popped. Returns true if the pop succeeded.
  56. bool pop(IdentifierInfo *Name, bool IsReset);
  57. };
  58. } // end anonymous namespace.
  59. bool PragmaPackStack::pop(IdentifierInfo *Name, bool IsReset) {
  60. // If name is empty just pop top.
  61. if (!Name) {
  62. // An empty stack is a special case...
  63. if (Stack.empty()) {
  64. // If this isn't a reset, it is always an error.
  65. if (!IsReset)
  66. return false;
  67. // Otherwise, it is an error only if some alignment has been set.
  68. if (!Alignment)
  69. return false;
  70. // Otherwise, reset to the default alignment.
  71. Alignment = 0;
  72. } else {
  73. Alignment = Stack.back().Alignment;
  74. Stack.pop_back();
  75. }
  76. return true;
  77. }
  78. // Otherwise, find the named record.
  79. for (unsigned i = Stack.size(); i != 0; ) {
  80. --i;
  81. if (Stack[i].Name == Name) {
  82. // Found it, pop up to and including this record.
  83. Alignment = Stack[i].Alignment;
  84. Stack.erase(Stack.begin() + i, Stack.end());
  85. return true;
  86. }
  87. }
  88. return false;
  89. }
  90. /// FreePackedContext - Deallocate and null out PackContext.
  91. void Sema::FreePackedContext() {
  92. delete static_cast<PragmaPackStack*>(PackContext);
  93. PackContext = nullptr;
  94. }
  95. void Sema::AddAlignmentAttributesForRecord(RecordDecl *RD) {
  96. // If there is no pack context, we don't need any attributes.
  97. if (!PackContext)
  98. return;
  99. PragmaPackStack *Stack = static_cast<PragmaPackStack*>(PackContext);
  100. // Otherwise, check to see if we need a max field alignment attribute.
  101. if (unsigned Alignment = Stack->getAlignment()) {
  102. if (Alignment == PackStackEntry::kMac68kAlignmentSentinel)
  103. RD->addAttr(AlignMac68kAttr::CreateImplicit(Context));
  104. else
  105. RD->addAttr(MaxFieldAlignmentAttr::CreateImplicit(Context,
  106. Alignment * 8));
  107. }
  108. }
  109. void Sema::AddMsStructLayoutForRecord(RecordDecl *RD) {
  110. if (MSStructPragmaOn)
  111. RD->addAttr(MSStructAttr::CreateImplicit(Context));
  112. // FIXME: We should merge AddAlignmentAttributesForRecord with
  113. // AddMsStructLayoutForRecord into AddPragmaAttributesForRecord, which takes
  114. // all active pragmas and applies them as attributes to class definitions.
  115. if (VtorDispModeStack.back() != getLangOpts().VtorDispMode)
  116. RD->addAttr(
  117. MSVtorDispAttr::CreateImplicit(Context, VtorDispModeStack.back()));
  118. }
  119. void Sema::ActOnPragmaOptionsAlign(PragmaOptionsAlignKind Kind,
  120. SourceLocation PragmaLoc) {
  121. if (!PackContext)
  122. PackContext = new PragmaPackStack();
  123. PragmaPackStack *Context = static_cast<PragmaPackStack*>(PackContext);
  124. switch (Kind) {
  125. // For all targets we support native and natural are the same.
  126. //
  127. // FIXME: This is not true on Darwin/PPC.
  128. case POAK_Native:
  129. case POAK_Power:
  130. case POAK_Natural:
  131. Context->push(nullptr);
  132. Context->setAlignment(0);
  133. break;
  134. // Note that '#pragma options align=packed' is not equivalent to attribute
  135. // packed, it has a different precedence relative to attribute aligned.
  136. case POAK_Packed:
  137. Context->push(nullptr);
  138. Context->setAlignment(1);
  139. break;
  140. case POAK_Mac68k:
  141. // Check if the target supports this.
  142. if (!this->Context.getTargetInfo().hasAlignMac68kSupport()) {
  143. Diag(PragmaLoc, diag::err_pragma_options_align_mac68k_target_unsupported);
  144. return;
  145. }
  146. Context->push(nullptr);
  147. Context->setAlignment(PackStackEntry::kMac68kAlignmentSentinel);
  148. break;
  149. case POAK_Reset:
  150. // Reset just pops the top of the stack, or resets the current alignment to
  151. // default.
  152. if (!Context->pop(nullptr, /*IsReset=*/true)) {
  153. Diag(PragmaLoc, diag::warn_pragma_options_align_reset_failed)
  154. << "stack empty";
  155. }
  156. break;
  157. }
  158. }
  159. void Sema::ActOnPragmaPack(PragmaPackKind Kind, IdentifierInfo *Name,
  160. Expr *alignment, SourceLocation PragmaLoc,
  161. SourceLocation LParenLoc, SourceLocation RParenLoc) {
  162. Expr *Alignment = static_cast<Expr *>(alignment);
  163. // If specified then alignment must be a "small" power of two.
  164. unsigned AlignmentVal = 0;
  165. if (Alignment) {
  166. llvm::APSInt Val;
  167. // pack(0) is like pack(), which just works out since that is what
  168. // we use 0 for in PackAttr.
  169. if (Alignment->isTypeDependent() ||
  170. Alignment->isValueDependent() ||
  171. !Alignment->isIntegerConstantExpr(Val, Context) ||
  172. !(Val == 0 || Val.isPowerOf2()) ||
  173. Val.getZExtValue() > 16) {
  174. Diag(PragmaLoc, diag::warn_pragma_pack_invalid_alignment);
  175. return; // Ignore
  176. }
  177. AlignmentVal = (unsigned) Val.getZExtValue();
  178. }
  179. if (!PackContext)
  180. PackContext = new PragmaPackStack();
  181. PragmaPackStack *Context = static_cast<PragmaPackStack*>(PackContext);
  182. switch (Kind) {
  183. case Sema::PPK_Default: // pack([n])
  184. Context->setAlignment(AlignmentVal);
  185. break;
  186. case Sema::PPK_Show: // pack(show)
  187. // Show the current alignment, making sure to show the right value
  188. // for the default.
  189. AlignmentVal = Context->getAlignment();
  190. // FIXME: This should come from the target.
  191. if (AlignmentVal == 0)
  192. AlignmentVal = 8;
  193. if (AlignmentVal == PackStackEntry::kMac68kAlignmentSentinel)
  194. Diag(PragmaLoc, diag::warn_pragma_pack_show) << "mac68k";
  195. else
  196. Diag(PragmaLoc, diag::warn_pragma_pack_show) << AlignmentVal;
  197. break;
  198. case Sema::PPK_Push: // pack(push [, id] [, [n])
  199. Context->push(Name);
  200. // Set the new alignment if specified.
  201. if (Alignment)
  202. Context->setAlignment(AlignmentVal);
  203. break;
  204. case Sema::PPK_Pop: // pack(pop [, id] [, n])
  205. // MSDN, C/C++ Preprocessor Reference > Pragma Directives > pack:
  206. // "#pragma pack(pop, identifier, n) is undefined"
  207. if (Alignment && Name)
  208. Diag(PragmaLoc, diag::warn_pragma_pack_pop_identifer_and_alignment);
  209. // Do the pop.
  210. if (!Context->pop(Name, /*IsReset=*/false)) {
  211. // If a name was specified then failure indicates the name
  212. // wasn't found. Otherwise failure indicates the stack was
  213. // empty.
  214. Diag(PragmaLoc, diag::warn_pragma_pop_failed)
  215. << "pack" << (Name ? "no record matching name" : "stack empty");
  216. // FIXME: Warn about popping named records as MSVC does.
  217. } else {
  218. // Pop succeeded, set the new alignment if specified.
  219. if (Alignment)
  220. Context->setAlignment(AlignmentVal);
  221. }
  222. break;
  223. }
  224. }
  225. void Sema::ActOnPragmaMSStruct(PragmaMSStructKind Kind) {
  226. MSStructPragmaOn = (Kind == PMSST_ON);
  227. }
  228. void Sema::ActOnPragmaMSComment(PragmaMSCommentKind Kind, StringRef Arg) {
  229. // FIXME: Serialize this.
  230. switch (Kind) {
  231. case PCK_Unknown:
  232. llvm_unreachable("unexpected pragma comment kind");
  233. case PCK_Linker:
  234. Consumer.HandleLinkerOptionPragma(Arg);
  235. return;
  236. case PCK_Lib:
  237. Consumer.HandleDependentLibrary(Arg);
  238. return;
  239. case PCK_Compiler:
  240. case PCK_ExeStr:
  241. case PCK_User:
  242. return; // We ignore all of these.
  243. }
  244. llvm_unreachable("invalid pragma comment kind");
  245. }
  246. void Sema::ActOnPragmaDetectMismatch(StringRef Name, StringRef Value) {
  247. // FIXME: Serialize this.
  248. Consumer.HandleDetectMismatch(Name, Value);
  249. }
  250. void Sema::ActOnPragmaMSPointersToMembers(
  251. LangOptions::PragmaMSPointersToMembersKind RepresentationMethod,
  252. SourceLocation PragmaLoc) {
  253. MSPointerToMemberRepresentationMethod = RepresentationMethod;
  254. ImplicitMSInheritanceAttrLoc = PragmaLoc;
  255. }
  256. void Sema::ActOnPragmaMSVtorDisp(PragmaVtorDispKind Kind,
  257. SourceLocation PragmaLoc,
  258. MSVtorDispAttr::Mode Mode) {
  259. switch (Kind) {
  260. case PVDK_Set:
  261. VtorDispModeStack.back() = Mode;
  262. break;
  263. case PVDK_Push:
  264. VtorDispModeStack.push_back(Mode);
  265. break;
  266. case PVDK_Reset:
  267. VtorDispModeStack.clear();
  268. VtorDispModeStack.push_back(MSVtorDispAttr::Mode(LangOpts.VtorDispMode));
  269. break;
  270. case PVDK_Pop:
  271. VtorDispModeStack.pop_back();
  272. if (VtorDispModeStack.empty()) {
  273. Diag(PragmaLoc, diag::warn_pragma_pop_failed) << "vtordisp"
  274. << "stack empty";
  275. VtorDispModeStack.push_back(MSVtorDispAttr::Mode(LangOpts.VtorDispMode));
  276. }
  277. break;
  278. }
  279. }
  280. template<typename ValueType>
  281. void Sema::PragmaStack<ValueType>::Act(SourceLocation PragmaLocation,
  282. PragmaMsStackAction Action,
  283. llvm::StringRef StackSlotLabel,
  284. ValueType Value) {
  285. if (Action == PSK_Reset) {
  286. CurrentValue = nullptr;
  287. return;
  288. }
  289. if (Action & PSK_Push)
  290. Stack.push_back(Slot(StackSlotLabel, CurrentValue, CurrentPragmaLocation));
  291. else if (Action & PSK_Pop) {
  292. if (!StackSlotLabel.empty()) {
  293. // If we've got a label, try to find it and jump there.
  294. auto I = std::find_if(Stack.rbegin(), Stack.rend(),
  295. [&](const Slot &x) { return x.StackSlotLabel == StackSlotLabel; });
  296. // If we found the label so pop from there.
  297. if (I != Stack.rend()) {
  298. CurrentValue = I->Value;
  299. CurrentPragmaLocation = I->PragmaLocation;
  300. Stack.erase(std::prev(I.base()), Stack.end());
  301. }
  302. } else if (!Stack.empty()) {
  303. // We don't have a label, just pop the last entry.
  304. CurrentValue = Stack.back().Value;
  305. CurrentPragmaLocation = Stack.back().PragmaLocation;
  306. Stack.pop_back();
  307. }
  308. }
  309. if (Action & PSK_Set) {
  310. CurrentValue = Value;
  311. CurrentPragmaLocation = PragmaLocation;
  312. }
  313. }
  314. bool Sema::UnifySection(StringRef SectionName,
  315. int SectionFlags,
  316. DeclaratorDecl *Decl) {
  317. auto Section = Context.SectionInfos.find(SectionName);
  318. if (Section == Context.SectionInfos.end()) {
  319. Context.SectionInfos[SectionName] =
  320. ASTContext::SectionInfo(Decl, SourceLocation(), SectionFlags);
  321. return false;
  322. }
  323. // A pre-declared section takes precedence w/o diagnostic.
  324. if (Section->second.SectionFlags == SectionFlags ||
  325. !(Section->second.SectionFlags & ASTContext::PSF_Implicit))
  326. return false;
  327. auto OtherDecl = Section->second.Decl;
  328. Diag(Decl->getLocation(), diag::err_section_conflict)
  329. << Decl << OtherDecl;
  330. Diag(OtherDecl->getLocation(), diag::note_declared_at)
  331. << OtherDecl->getName();
  332. if (auto A = Decl->getAttr<SectionAttr>())
  333. if (A->isImplicit())
  334. Diag(A->getLocation(), diag::note_pragma_entered_here);
  335. if (auto A = OtherDecl->getAttr<SectionAttr>())
  336. if (A->isImplicit())
  337. Diag(A->getLocation(), diag::note_pragma_entered_here);
  338. return true;
  339. }
  340. bool Sema::UnifySection(StringRef SectionName,
  341. int SectionFlags,
  342. SourceLocation PragmaSectionLocation) {
  343. auto Section = Context.SectionInfos.find(SectionName);
  344. if (Section != Context.SectionInfos.end()) {
  345. if (Section->second.SectionFlags == SectionFlags)
  346. return false;
  347. if (!(Section->second.SectionFlags & ASTContext::PSF_Implicit)) {
  348. Diag(PragmaSectionLocation, diag::err_section_conflict)
  349. << "this" << "a prior #pragma section";
  350. Diag(Section->second.PragmaSectionLocation,
  351. diag::note_pragma_entered_here);
  352. return true;
  353. }
  354. }
  355. Context.SectionInfos[SectionName] =
  356. ASTContext::SectionInfo(nullptr, PragmaSectionLocation, SectionFlags);
  357. return false;
  358. }
  359. /// \brief Called on well formed \#pragma bss_seg().
  360. void Sema::ActOnPragmaMSSeg(SourceLocation PragmaLocation,
  361. PragmaMsStackAction Action,
  362. llvm::StringRef StackSlotLabel,
  363. StringLiteral *SegmentName,
  364. llvm::StringRef PragmaName) {
  365. PragmaStack<StringLiteral *> *Stack =
  366. llvm::StringSwitch<PragmaStack<StringLiteral *> *>(PragmaName)
  367. .Case("data_seg", &DataSegStack)
  368. .Case("bss_seg", &BSSSegStack)
  369. .Case("const_seg", &ConstSegStack)
  370. .Case("code_seg", &CodeSegStack);
  371. if (Action & PSK_Pop && Stack->Stack.empty())
  372. Diag(PragmaLocation, diag::warn_pragma_pop_failed) << PragmaName
  373. << "stack empty";
  374. if (SegmentName &&
  375. !checkSectionName(SegmentName->getLocStart(), SegmentName->getString()))
  376. return;
  377. Stack->Act(PragmaLocation, Action, StackSlotLabel, SegmentName);
  378. }
  379. /// \brief Called on well formed \#pragma bss_seg().
  380. void Sema::ActOnPragmaMSSection(SourceLocation PragmaLocation,
  381. int SectionFlags, StringLiteral *SegmentName) {
  382. UnifySection(SegmentName->getString(), SectionFlags, PragmaLocation);
  383. }
  384. void Sema::ActOnPragmaMSInitSeg(SourceLocation PragmaLocation,
  385. StringLiteral *SegmentName) {
  386. // There's no stack to maintain, so we just have a current section. When we
  387. // see the default section, reset our current section back to null so we stop
  388. // tacking on unnecessary attributes.
  389. CurInitSeg = SegmentName->getString() == ".CRT$XCU" ? nullptr : SegmentName;
  390. CurInitSegLoc = PragmaLocation;
  391. }
  392. void Sema::ActOnPragmaUnused(const Token &IdTok, Scope *curScope,
  393. SourceLocation PragmaLoc) {
  394. IdentifierInfo *Name = IdTok.getIdentifierInfo();
  395. LookupResult Lookup(*this, Name, IdTok.getLocation(), LookupOrdinaryName);
  396. LookupParsedName(Lookup, curScope, nullptr, true);
  397. if (Lookup.empty()) {
  398. Diag(PragmaLoc, diag::warn_pragma_unused_undeclared_var)
  399. << Name << SourceRange(IdTok.getLocation());
  400. return;
  401. }
  402. VarDecl *VD = Lookup.getAsSingle<VarDecl>();
  403. if (!VD) {
  404. Diag(PragmaLoc, diag::warn_pragma_unused_expected_var_arg)
  405. << Name << SourceRange(IdTok.getLocation());
  406. return;
  407. }
  408. // Warn if this was used before being marked unused.
  409. if (VD->isUsed())
  410. Diag(PragmaLoc, diag::warn_used_but_marked_unused) << Name;
  411. VD->addAttr(UnusedAttr::CreateImplicit(Context, IdTok.getLocation()));
  412. }
  413. void Sema::AddCFAuditedAttribute(Decl *D) {
  414. SourceLocation Loc = PP.getPragmaARCCFCodeAuditedLoc();
  415. if (!Loc.isValid()) return;
  416. // Don't add a redundant or conflicting attribute.
  417. if (D->hasAttr<CFAuditedTransferAttr>() ||
  418. D->hasAttr<CFUnknownTransferAttr>())
  419. return;
  420. D->addAttr(CFAuditedTransferAttr::CreateImplicit(Context, Loc));
  421. }
  422. void Sema::ActOnPragmaOptimize(bool On, SourceLocation PragmaLoc) {
  423. if(On)
  424. OptimizeOffPragmaLocation = SourceLocation();
  425. else
  426. OptimizeOffPragmaLocation = PragmaLoc;
  427. }
  428. void Sema::AddRangeBasedOptnone(FunctionDecl *FD) {
  429. // In the future, check other pragmas if they're implemented (e.g. pragma
  430. // optimize 0 will probably map to this functionality too).
  431. if(OptimizeOffPragmaLocation.isValid())
  432. AddOptnoneAttributeIfNoConflicts(FD, OptimizeOffPragmaLocation);
  433. }
  434. void Sema::AddOptnoneAttributeIfNoConflicts(FunctionDecl *FD,
  435. SourceLocation Loc) {
  436. // Don't add a conflicting attribute. No diagnostic is needed.
  437. if (FD->hasAttr<MinSizeAttr>() || FD->hasAttr<AlwaysInlineAttr>())
  438. return;
  439. // Add attributes only if required. Optnone requires noinline as well, but if
  440. // either is already present then don't bother adding them.
  441. if (!FD->hasAttr<OptimizeNoneAttr>())
  442. FD->addAttr(OptimizeNoneAttr::CreateImplicit(Context, Loc));
  443. if (!FD->hasAttr<NoInlineAttr>())
  444. FD->addAttr(NoInlineAttr::CreateImplicit(Context, Loc));
  445. }
  446. typedef std::vector<std::pair<unsigned, SourceLocation> > VisStack;
  447. enum : unsigned { NoVisibility = ~0U };
  448. void Sema::AddPushedVisibilityAttribute(Decl *D) {
  449. if (!VisContext)
  450. return;
  451. NamedDecl *ND = dyn_cast<NamedDecl>(D);
  452. if (ND && ND->getExplicitVisibility(NamedDecl::VisibilityForValue))
  453. return;
  454. VisStack *Stack = static_cast<VisStack*>(VisContext);
  455. unsigned rawType = Stack->back().first;
  456. if (rawType == NoVisibility) return;
  457. VisibilityAttr::VisibilityType type
  458. = (VisibilityAttr::VisibilityType) rawType;
  459. SourceLocation loc = Stack->back().second;
  460. D->addAttr(VisibilityAttr::CreateImplicit(Context, type, loc));
  461. }
  462. /// FreeVisContext - Deallocate and null out VisContext.
  463. void Sema::FreeVisContext() {
  464. delete static_cast<VisStack*>(VisContext);
  465. VisContext = nullptr;
  466. }
  467. static void PushPragmaVisibility(Sema &S, unsigned type, SourceLocation loc) {
  468. // Put visibility on stack.
  469. if (!S.VisContext)
  470. S.VisContext = new VisStack;
  471. VisStack *Stack = static_cast<VisStack*>(S.VisContext);
  472. Stack->push_back(std::make_pair(type, loc));
  473. }
  474. void Sema::ActOnPragmaVisibility(const IdentifierInfo* VisType,
  475. SourceLocation PragmaLoc) {
  476. if (VisType) {
  477. // Compute visibility to use.
  478. VisibilityAttr::VisibilityType T;
  479. if (!VisibilityAttr::ConvertStrToVisibilityType(VisType->getName(), T)) {
  480. Diag(PragmaLoc, diag::warn_attribute_unknown_visibility) << VisType;
  481. return;
  482. }
  483. PushPragmaVisibility(*this, T, PragmaLoc);
  484. } else {
  485. PopPragmaVisibility(false, PragmaLoc);
  486. }
  487. }
  488. void Sema::ActOnPragmaFPContract(tok::OnOffSwitch OOS) {
  489. switch (OOS) {
  490. case tok::OOS_ON:
  491. FPFeatures.fp_contract = 1;
  492. break;
  493. case tok::OOS_OFF:
  494. FPFeatures.fp_contract = 0;
  495. break;
  496. case tok::OOS_DEFAULT:
  497. FPFeatures.fp_contract = getLangOpts().DefaultFPContract;
  498. break;
  499. }
  500. }
  501. void Sema::PushNamespaceVisibilityAttr(const VisibilityAttr *Attr,
  502. SourceLocation Loc) {
  503. // Visibility calculations will consider the namespace's visibility.
  504. // Here we just want to note that we're in a visibility context
  505. // which overrides any enclosing #pragma context, but doesn't itself
  506. // contribute visibility.
  507. PushPragmaVisibility(*this, NoVisibility, Loc);
  508. }
  509. void Sema::PopPragmaVisibility(bool IsNamespaceEnd, SourceLocation EndLoc) {
  510. if (!VisContext) {
  511. Diag(EndLoc, diag::err_pragma_pop_visibility_mismatch);
  512. return;
  513. }
  514. // Pop visibility from stack
  515. VisStack *Stack = static_cast<VisStack*>(VisContext);
  516. const std::pair<unsigned, SourceLocation> *Back = &Stack->back();
  517. bool StartsWithPragma = Back->first != NoVisibility;
  518. if (StartsWithPragma && IsNamespaceEnd) {
  519. Diag(Back->second, diag::err_pragma_push_visibility_mismatch);
  520. Diag(EndLoc, diag::note_surrounding_namespace_ends_here);
  521. // For better error recovery, eat all pushes inside the namespace.
  522. do {
  523. Stack->pop_back();
  524. Back = &Stack->back();
  525. StartsWithPragma = Back->first != NoVisibility;
  526. } while (StartsWithPragma);
  527. } else if (!StartsWithPragma && !IsNamespaceEnd) {
  528. Diag(EndLoc, diag::err_pragma_pop_visibility_mismatch);
  529. Diag(Back->second, diag::note_surrounding_namespace_starts_here);
  530. return;
  531. }
  532. Stack->pop_back();
  533. // To simplify the implementation, never keep around an empty stack.
  534. if (Stack->empty())
  535. FreeVisContext();
  536. }