blob: c22c7c620c9cab007d352979dc0ad9a467a7e589 [file] [log] [blame]
Bill Wendling44426052012-12-20 19:22:21 +00001//===--- SemaAttr.cpp - Semantic Analysis for Attributes ------------------===//
Chris Lattner2eccbc12009-02-17 00:57:29 +00002//
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//
Chris Lattner31180bb2009-02-17 01:09:29 +000010// This file implements semantic analysis for non-trivial attributes and
11// pragmas.
Chris Lattner2eccbc12009-02-17 00:57:29 +000012//
13//===----------------------------------------------------------------------===//
14
John McCall83024632010-08-25 22:03:47 +000015#include "clang/Sema/SemaInternal.h"
Reid Klecknere43f0fe2013-05-08 13:44:39 +000016#include "clang/AST/ASTConsumer.h"
Alexis Huntdcfba7b2010-08-18 23:23:40 +000017#include "clang/AST/Attr.h"
Chris Lattner2eccbc12009-02-17 00:57:29 +000018#include "clang/AST/Expr.h"
Daniel Dunbarbd606522010-05-27 00:35:16 +000019#include "clang/Basic/TargetInfo.h"
20#include "clang/Lex/Preprocessor.h"
Chandler Carruth3a022472012-12-04 09:13:33 +000021#include "clang/Sema/Lookup.h"
Chris Lattner2eccbc12009-02-17 00:57:29 +000022using namespace clang;
23
Chris Lattner31180bb2009-02-17 01:09:29 +000024//===----------------------------------------------------------------------===//
Daniel Dunbar69dac582010-05-27 00:04:40 +000025// Pragma 'pack' and 'options align'
Chris Lattner31180bb2009-02-17 01:09:29 +000026//===----------------------------------------------------------------------===//
27
28namespace {
Daniel Dunbar4dbe15d2010-05-27 02:25:27 +000029 struct PackStackEntry {
Daniel Dunbar6da10982010-05-27 05:45:51 +000030 // We just use a sentinel to represent when the stack is set to mac68k
31 // alignment.
32 static const unsigned kMac68kAlignmentSentinel = ~0U;
33
Daniel Dunbar4dbe15d2010-05-27 02:25:27 +000034 unsigned Alignment;
35 IdentifierInfo *Name;
36 };
37
Chris Lattner31180bb2009-02-17 01:09:29 +000038 /// PragmaPackStack - Simple class to wrap the stack used by #pragma
39 /// pack.
40 class PragmaPackStack {
Daniel Dunbar4dbe15d2010-05-27 02:25:27 +000041 typedef std::vector<PackStackEntry> stack_ty;
Chris Lattner31180bb2009-02-17 01:09:29 +000042
43 /// Alignment - The current user specified alignment.
44 unsigned Alignment;
45
46 /// Stack - Entries in the #pragma pack stack, consisting of saved
47 /// alignments and optional names.
48 stack_ty Stack;
Mike Stump11289f42009-09-09 15:08:12 +000049
50 public:
Chris Lattner31180bb2009-02-17 01:09:29 +000051 PragmaPackStack() : Alignment(0) {}
52
53 void setAlignment(unsigned A) { Alignment = A; }
54 unsigned getAlignment() { return Alignment; }
55
56 /// push - Push the current alignment onto the stack, optionally
57 /// using the given \arg Name for the record, if non-zero.
58 void push(IdentifierInfo *Name) {
Daniel Dunbar4dbe15d2010-05-27 02:25:27 +000059 PackStackEntry PSE = { Alignment, Name };
60 Stack.push_back(PSE);
Chris Lattner31180bb2009-02-17 01:09:29 +000061 }
62
63 /// pop - Pop a record from the stack and restore the current
64 /// alignment to the previous value. If \arg Name is non-zero then
65 /// the first such named record is popped, otherwise the top record
66 /// is popped. Returns true if the pop succeeded.
Daniel Dunbar84336ba2010-07-16 04:54:16 +000067 bool pop(IdentifierInfo *Name, bool IsReset);
Chris Lattner31180bb2009-02-17 01:09:29 +000068 };
69} // end anonymous namespace.
70
Daniel Dunbar84336ba2010-07-16 04:54:16 +000071bool PragmaPackStack::pop(IdentifierInfo *Name, bool IsReset) {
Chris Lattner31180bb2009-02-17 01:09:29 +000072 // If name is empty just pop top.
73 if (!Name) {
Daniel Dunbar84336ba2010-07-16 04:54:16 +000074 // An empty stack is a special case...
75 if (Stack.empty()) {
76 // If this isn't a reset, it is always an error.
77 if (!IsReset)
78 return false;
79
80 // Otherwise, it is an error only if some alignment has been set.
81 if (!Alignment)
82 return false;
83
84 // Otherwise, reset to the default alignment.
85 Alignment = 0;
86 } else {
87 Alignment = Stack.back().Alignment;
88 Stack.pop_back();
89 }
90
Chris Lattner31180bb2009-02-17 01:09:29 +000091 return true;
Mike Stump11289f42009-09-09 15:08:12 +000092 }
93
Chris Lattner31180bb2009-02-17 01:09:29 +000094 // Otherwise, find the named record.
95 for (unsigned i = Stack.size(); i != 0; ) {
96 --i;
Daniel Dunbar4dbe15d2010-05-27 02:25:27 +000097 if (Stack[i].Name == Name) {
Chris Lattner31180bb2009-02-17 01:09:29 +000098 // Found it, pop up to and including this record.
Daniel Dunbar4dbe15d2010-05-27 02:25:27 +000099 Alignment = Stack[i].Alignment;
Chris Lattner31180bb2009-02-17 01:09:29 +0000100 Stack.erase(Stack.begin() + i, Stack.end());
101 return true;
102 }
103 }
Mike Stump11289f42009-09-09 15:08:12 +0000104
Chris Lattner31180bb2009-02-17 01:09:29 +0000105 return false;
106}
107
Denis Zobnin2290dac2016-04-29 11:27:00 +0000108Sema::PragmaStackSentinelRAII::PragmaStackSentinelRAII(Sema &S,
109 StringRef SlotLabel,
110 bool ShouldAct)
111 : S(S), SlotLabel(SlotLabel), ShouldAct(ShouldAct) {
112 if (ShouldAct) {
113 S.VtorDispStack.SentinelAction(PSK_Push, SlotLabel);
114 S.DataSegStack.SentinelAction(PSK_Push, SlotLabel);
115 S.BSSSegStack.SentinelAction(PSK_Push, SlotLabel);
116 S.ConstSegStack.SentinelAction(PSK_Push, SlotLabel);
117 S.CodeSegStack.SentinelAction(PSK_Push, SlotLabel);
118 }
119}
120
121Sema::PragmaStackSentinelRAII::~PragmaStackSentinelRAII() {
122 if (ShouldAct) {
123 S.VtorDispStack.SentinelAction(PSK_Pop, SlotLabel);
124 S.DataSegStack.SentinelAction(PSK_Pop, SlotLabel);
125 S.BSSSegStack.SentinelAction(PSK_Pop, SlotLabel);
126 S.ConstSegStack.SentinelAction(PSK_Pop, SlotLabel);
127 S.CodeSegStack.SentinelAction(PSK_Pop, SlotLabel);
128 }
129}
Chris Lattner31180bb2009-02-17 01:09:29 +0000130
131/// FreePackedContext - Deallocate and null out PackContext.
132void Sema::FreePackedContext() {
133 delete static_cast<PragmaPackStack*>(PackContext);
Craig Topperc3ec1492014-05-26 06:22:03 +0000134 PackContext = nullptr;
Chris Lattner31180bb2009-02-17 01:09:29 +0000135}
136
Daniel Dunbar8804f2e2010-05-27 01:53:40 +0000137void Sema::AddAlignmentAttributesForRecord(RecordDecl *RD) {
138 // If there is no pack context, we don't need any attributes.
139 if (!PackContext)
140 return;
141
142 PragmaPackStack *Stack = static_cast<PragmaPackStack*>(PackContext);
143
144 // Otherwise, check to see if we need a max field alignment attribute.
Daniel Dunbar6da10982010-05-27 05:45:51 +0000145 if (unsigned Alignment = Stack->getAlignment()) {
146 if (Alignment == PackStackEntry::kMac68kAlignmentSentinel)
Aaron Ballman36a53502014-01-16 13:03:14 +0000147 RD->addAttr(AlignMac68kAttr::CreateImplicit(Context));
Daniel Dunbar6da10982010-05-27 05:45:51 +0000148 else
Aaron Ballman36a53502014-01-16 13:03:14 +0000149 RD->addAttr(MaxFieldAlignmentAttr::CreateImplicit(Context,
Alexis Huntdcfba7b2010-08-18 23:23:40 +0000150 Alignment * 8));
Daniel Dunbar6da10982010-05-27 05:45:51 +0000151 }
Chris Lattner31180bb2009-02-17 01:09:29 +0000152}
153
Fariborz Jahanian6b4e26b2011-04-26 17:54:40 +0000154void Sema::AddMsStructLayoutForRecord(RecordDecl *RD) {
Reid Klecknerc0dca6d2014-02-12 23:50:26 +0000155 if (MSStructPragmaOn)
David Majnemer8ab003a2015-02-02 19:30:52 +0000156 RD->addAttr(MSStructAttr::CreateImplicit(Context));
Reid Klecknerc0dca6d2014-02-12 23:50:26 +0000157
158 // FIXME: We should merge AddAlignmentAttributesForRecord with
159 // AddMsStructLayoutForRecord into AddPragmaAttributesForRecord, which takes
160 // all active pragmas and applies them as attributes to class definitions.
Denis Zobnin2290dac2016-04-29 11:27:00 +0000161 if (VtorDispStack.CurrentValue != getLangOpts().VtorDispMode)
Reid Klecknerc0dca6d2014-02-12 23:50:26 +0000162 RD->addAttr(
Denis Zobnin2290dac2016-04-29 11:27:00 +0000163 MSVtorDispAttr::CreateImplicit(Context, VtorDispStack.CurrentValue));
Fariborz Jahanian6b4e26b2011-04-26 17:54:40 +0000164}
165
Daniel Dunbar69dac582010-05-27 00:04:40 +0000166void Sema::ActOnPragmaOptionsAlign(PragmaOptionsAlignKind Kind,
Eli Friedman68be1642012-10-04 02:36:51 +0000167 SourceLocation PragmaLoc) {
Craig Topperc3ec1492014-05-26 06:22:03 +0000168 if (!PackContext)
Daniel Dunbar69dac582010-05-27 00:04:40 +0000169 PackContext = new PragmaPackStack();
170
171 PragmaPackStack *Context = static_cast<PragmaPackStack*>(PackContext);
172
Daniel Dunbar69dac582010-05-27 00:04:40 +0000173 switch (Kind) {
Daniel Dunbar663e8092010-05-27 18:42:09 +0000174 // For all targets we support native and natural are the same.
175 //
176 // FIXME: This is not true on Darwin/PPC.
177 case POAK_Native:
Daniel Dunbar5794c6f2010-05-28 19:43:33 +0000178 case POAK_Power:
Daniel Dunbara6885662010-05-28 20:08:00 +0000179 case POAK_Natural:
Craig Topperc3ec1492014-05-26 06:22:03 +0000180 Context->push(nullptr);
Daniel Dunbar5794c6f2010-05-28 19:43:33 +0000181 Context->setAlignment(0);
182 break;
183
Daniel Dunbar9c84d4a2010-05-27 18:42:17 +0000184 // Note that '#pragma options align=packed' is not equivalent to attribute
185 // packed, it has a different precedence relative to attribute aligned.
186 case POAK_Packed:
Craig Topperc3ec1492014-05-26 06:22:03 +0000187 Context->push(nullptr);
Daniel Dunbar9c84d4a2010-05-27 18:42:17 +0000188 Context->setAlignment(1);
189 break;
190
Daniel Dunbarbd606522010-05-27 00:35:16 +0000191 case POAK_Mac68k:
192 // Check if the target supports this.
Alp Tokerb6cc5922014-05-03 03:45:55 +0000193 if (!this->Context.getTargetInfo().hasAlignMac68kSupport()) {
Daniel Dunbarbd606522010-05-27 00:35:16 +0000194 Diag(PragmaLoc, diag::err_pragma_options_align_mac68k_target_unsupported);
195 return;
Daniel Dunbarbd606522010-05-27 00:35:16 +0000196 }
Craig Topperc3ec1492014-05-26 06:22:03 +0000197 Context->push(nullptr);
Daniel Dunbar6da10982010-05-27 05:45:51 +0000198 Context->setAlignment(PackStackEntry::kMac68kAlignmentSentinel);
Daniel Dunbarbd606522010-05-27 00:35:16 +0000199 break;
200
Eli Friedman68be1642012-10-04 02:36:51 +0000201 case POAK_Reset:
202 // Reset just pops the top of the stack, or resets the current alignment to
203 // default.
Craig Topperc3ec1492014-05-26 06:22:03 +0000204 if (!Context->pop(nullptr, /*IsReset=*/true)) {
Eli Friedman68be1642012-10-04 02:36:51 +0000205 Diag(PragmaLoc, diag::warn_pragma_options_align_reset_failed)
206 << "stack empty";
207 }
Daniel Dunbar69dac582010-05-27 00:04:40 +0000208 break;
209 }
210}
211
Mike Stump11289f42009-09-09 15:08:12 +0000212void Sema::ActOnPragmaPack(PragmaPackKind Kind, IdentifierInfo *Name,
Richard Trieu2bd04012011-09-09 02:00:50 +0000213 Expr *alignment, SourceLocation PragmaLoc,
Chris Lattner2eccbc12009-02-17 00:57:29 +0000214 SourceLocation LParenLoc, SourceLocation RParenLoc) {
215 Expr *Alignment = static_cast<Expr *>(alignment);
216
217 // If specified then alignment must be a "small" power of two.
218 unsigned AlignmentVal = 0;
219 if (Alignment) {
220 llvm::APSInt Val;
Mike Stump11289f42009-09-09 15:08:12 +0000221
Daniel Dunbare03c6102009-03-06 20:45:54 +0000222 // pack(0) is like pack(), which just works out since that is what
223 // we use 0 for in PackAttr.
Douglas Gregorbdb604a2010-05-18 23:01:22 +0000224 if (Alignment->isTypeDependent() ||
225 Alignment->isValueDependent() ||
226 !Alignment->isIntegerConstantExpr(Val, Context) ||
Daniel Dunbare03c6102009-03-06 20:45:54 +0000227 !(Val == 0 || Val.isPowerOf2()) ||
Chris Lattner2eccbc12009-02-17 00:57:29 +0000228 Val.getZExtValue() > 16) {
229 Diag(PragmaLoc, diag::warn_pragma_pack_invalid_alignment);
Chris Lattner2eccbc12009-02-17 00:57:29 +0000230 return; // Ignore
231 }
232
233 AlignmentVal = (unsigned) Val.getZExtValue();
234 }
Mike Stump11289f42009-09-09 15:08:12 +0000235
Craig Topperc3ec1492014-05-26 06:22:03 +0000236 if (!PackContext)
Chris Lattner31180bb2009-02-17 01:09:29 +0000237 PackContext = new PragmaPackStack();
Mike Stump11289f42009-09-09 15:08:12 +0000238
Chris Lattner31180bb2009-02-17 01:09:29 +0000239 PragmaPackStack *Context = static_cast<PragmaPackStack*>(PackContext);
Mike Stump11289f42009-09-09 15:08:12 +0000240
Chris Lattner2eccbc12009-02-17 00:57:29 +0000241 switch (Kind) {
John McCallfaf5fb42010-08-26 23:41:50 +0000242 case Sema::PPK_Default: // pack([n])
Chris Lattner31180bb2009-02-17 01:09:29 +0000243 Context->setAlignment(AlignmentVal);
Chris Lattner2eccbc12009-02-17 00:57:29 +0000244 break;
245
John McCallfaf5fb42010-08-26 23:41:50 +0000246 case Sema::PPK_Show: // pack(show)
Chris Lattner2eccbc12009-02-17 00:57:29 +0000247 // Show the current alignment, making sure to show the right value
248 // for the default.
Chris Lattner31180bb2009-02-17 01:09:29 +0000249 AlignmentVal = Context->getAlignment();
Chris Lattner2eccbc12009-02-17 00:57:29 +0000250 // FIXME: This should come from the target.
251 if (AlignmentVal == 0)
252 AlignmentVal = 8;
Daniel Dunbar6da10982010-05-27 05:45:51 +0000253 if (AlignmentVal == PackStackEntry::kMac68kAlignmentSentinel)
254 Diag(PragmaLoc, diag::warn_pragma_pack_show) << "mac68k";
255 else
256 Diag(PragmaLoc, diag::warn_pragma_pack_show) << AlignmentVal;
Chris Lattner2eccbc12009-02-17 00:57:29 +0000257 break;
258
John McCallfaf5fb42010-08-26 23:41:50 +0000259 case Sema::PPK_Push: // pack(push [, id] [, [n])
Chris Lattner31180bb2009-02-17 01:09:29 +0000260 Context->push(Name);
Chris Lattner2eccbc12009-02-17 00:57:29 +0000261 // Set the new alignment if specified.
262 if (Alignment)
Mike Stump11289f42009-09-09 15:08:12 +0000263 Context->setAlignment(AlignmentVal);
Chris Lattner2eccbc12009-02-17 00:57:29 +0000264 break;
265
John McCallfaf5fb42010-08-26 23:41:50 +0000266 case Sema::PPK_Pop: // pack(pop [, id] [, n])
Chris Lattner2eccbc12009-02-17 00:57:29 +0000267 // MSDN, C/C++ Preprocessor Reference > Pragma Directives > pack:
268 // "#pragma pack(pop, identifier, n) is undefined"
269 if (Alignment && Name)
Mike Stump11289f42009-09-09 15:08:12 +0000270 Diag(PragmaLoc, diag::warn_pragma_pack_pop_identifer_and_alignment);
271
Chris Lattner2eccbc12009-02-17 00:57:29 +0000272 // Do the pop.
Daniel Dunbar84336ba2010-07-16 04:54:16 +0000273 if (!Context->pop(Name, /*IsReset=*/false)) {
Chris Lattner2eccbc12009-02-17 00:57:29 +0000274 // If a name was specified then failure indicates the name
275 // wasn't found. Otherwise failure indicates the stack was
276 // empty.
Reid Klecknerc0dca6d2014-02-12 23:50:26 +0000277 Diag(PragmaLoc, diag::warn_pragma_pop_failed)
278 << "pack" << (Name ? "no record matching name" : "stack empty");
Chris Lattner2eccbc12009-02-17 00:57:29 +0000279
280 // FIXME: Warn about popping named records as MSVC does.
281 } else {
282 // Pop succeeded, set the new alignment if specified.
283 if (Alignment)
Chris Lattner31180bb2009-02-17 01:09:29 +0000284 Context->setAlignment(AlignmentVal);
Chris Lattner2eccbc12009-02-17 00:57:29 +0000285 }
286 break;
Chris Lattner2eccbc12009-02-17 00:57:29 +0000287 }
288}
289
Fariborz Jahanian743dda42011-04-25 18:49:15 +0000290void Sema::ActOnPragmaMSStruct(PragmaMSStructKind Kind) {
291 MSStructPragmaOn = (Kind == PMSST_ON);
292}
293
Nico Weber66220292016-03-02 17:28:48 +0000294void Sema::ActOnPragmaMSComment(SourceLocation CommentLoc,
295 PragmaMSCommentKind Kind, StringRef Arg) {
296 auto *PCD = PragmaCommentDecl::Create(
297 Context, Context.getTranslationUnitDecl(), CommentLoc, Kind, Arg);
298 Context.getTranslationUnitDecl()->addDecl(PCD);
299 Consumer.HandleTopLevelDecl(DeclGroupRef(PCD));
Reid Klecknere43f0fe2013-05-08 13:44:39 +0000300}
301
Nico Webercbbaeb12016-03-02 19:28:54 +0000302void Sema::ActOnPragmaDetectMismatch(SourceLocation Loc, StringRef Name,
303 StringRef Value) {
304 auto *PDMD = PragmaDetectMismatchDecl::Create(
305 Context, Context.getTranslationUnitDecl(), Loc, Name, Value);
306 Context.getTranslationUnitDecl()->addDecl(PDMD);
307 Consumer.HandleTopLevelDecl(DeclGroupRef(PDMD));
Aaron Ballman5d041be2013-06-04 02:07:14 +0000308}
309
David Majnemer4bb09802014-02-10 19:50:15 +0000310void Sema::ActOnPragmaMSPointersToMembers(
David Majnemer86c318f2014-02-11 21:05:00 +0000311 LangOptions::PragmaMSPointersToMembersKind RepresentationMethod,
David Majnemer4bb09802014-02-10 19:50:15 +0000312 SourceLocation PragmaLoc) {
313 MSPointerToMemberRepresentationMethod = RepresentationMethod;
314 ImplicitMSInheritanceAttrLoc = PragmaLoc;
315}
316
Denis Zobnin2290dac2016-04-29 11:27:00 +0000317void Sema::ActOnPragmaMSVtorDisp(PragmaMsStackAction Action,
Reid Klecknerc0dca6d2014-02-12 23:50:26 +0000318 SourceLocation PragmaLoc,
319 MSVtorDispAttr::Mode Mode) {
Denis Zobnin2290dac2016-04-29 11:27:00 +0000320 if (Action & PSK_Pop && VtorDispStack.Stack.empty())
321 Diag(PragmaLoc, diag::warn_pragma_pop_failed) << "vtordisp"
322 << "stack empty";
323 VtorDispStack.Act(PragmaLoc, Action, StringRef(), Mode);
Reid Klecknerc0dca6d2014-02-12 23:50:26 +0000324}
325
Warren Huntc3b18962014-04-08 22:30:47 +0000326template<typename ValueType>
327void Sema::PragmaStack<ValueType>::Act(SourceLocation PragmaLocation,
328 PragmaMsStackAction Action,
329 llvm::StringRef StackSlotLabel,
330 ValueType Value) {
331 if (Action == PSK_Reset) {
Denis Zobnin2290dac2016-04-29 11:27:00 +0000332 CurrentValue = DefaultValue;
Warren Huntc3b18962014-04-08 22:30:47 +0000333 return;
334 }
335 if (Action & PSK_Push)
336 Stack.push_back(Slot(StackSlotLabel, CurrentValue, CurrentPragmaLocation));
337 else if (Action & PSK_Pop) {
338 if (!StackSlotLabel.empty()) {
339 // If we've got a label, try to find it and jump there.
340 auto I = std::find_if(Stack.rbegin(), Stack.rend(),
341 [&](const Slot &x) { return x.StackSlotLabel == StackSlotLabel; });
342 // If we found the label so pop from there.
343 if (I != Stack.rend()) {
344 CurrentValue = I->Value;
345 CurrentPragmaLocation = I->PragmaLocation;
346 Stack.erase(std::prev(I.base()), Stack.end());
347 }
348 } else if (!Stack.empty()) {
349 // We don't have a label, just pop the last entry.
350 CurrentValue = Stack.back().Value;
351 CurrentPragmaLocation = Stack.back().PragmaLocation;
352 Stack.pop_back();
353 }
354 }
355 if (Action & PSK_Set) {
356 CurrentValue = Value;
357 CurrentPragmaLocation = PragmaLocation;
358 }
359}
360
Craig Topperbf3e3272014-08-30 16:55:52 +0000361bool Sema::UnifySection(StringRef SectionName,
Warren Huntc3b18962014-04-08 22:30:47 +0000362 int SectionFlags,
363 DeclaratorDecl *Decl) {
Hans Wennborg899ded92014-10-16 20:52:46 +0000364 auto Section = Context.SectionInfos.find(SectionName);
365 if (Section == Context.SectionInfos.end()) {
366 Context.SectionInfos[SectionName] =
367 ASTContext::SectionInfo(Decl, SourceLocation(), SectionFlags);
Warren Huntc3b18962014-04-08 22:30:47 +0000368 return false;
369 }
370 // A pre-declared section takes precedence w/o diagnostic.
371 if (Section->second.SectionFlags == SectionFlags ||
Hans Wennborg899ded92014-10-16 20:52:46 +0000372 !(Section->second.SectionFlags & ASTContext::PSF_Implicit))
Warren Huntc3b18962014-04-08 22:30:47 +0000373 return false;
374 auto OtherDecl = Section->second.Decl;
375 Diag(Decl->getLocation(), diag::err_section_conflict)
376 << Decl << OtherDecl;
377 Diag(OtherDecl->getLocation(), diag::note_declared_at)
378 << OtherDecl->getName();
379 if (auto A = Decl->getAttr<SectionAttr>())
380 if (A->isImplicit())
381 Diag(A->getLocation(), diag::note_pragma_entered_here);
382 if (auto A = OtherDecl->getAttr<SectionAttr>())
383 if (A->isImplicit())
384 Diag(A->getLocation(), diag::note_pragma_entered_here);
Ehsan Akhgari0b510602014-09-22 19:46:39 +0000385 return true;
Warren Huntc3b18962014-04-08 22:30:47 +0000386}
387
Craig Topperbf3e3272014-08-30 16:55:52 +0000388bool Sema::UnifySection(StringRef SectionName,
Warren Huntc3b18962014-04-08 22:30:47 +0000389 int SectionFlags,
390 SourceLocation PragmaSectionLocation) {
Hans Wennborg899ded92014-10-16 20:52:46 +0000391 auto Section = Context.SectionInfos.find(SectionName);
392 if (Section != Context.SectionInfos.end()) {
Warren Huntc3b18962014-04-08 22:30:47 +0000393 if (Section->second.SectionFlags == SectionFlags)
394 return false;
Hans Wennborg899ded92014-10-16 20:52:46 +0000395 if (!(Section->second.SectionFlags & ASTContext::PSF_Implicit)) {
Warren Huntc3b18962014-04-08 22:30:47 +0000396 Diag(PragmaSectionLocation, diag::err_section_conflict)
397 << "this" << "a prior #pragma section";
398 Diag(Section->second.PragmaSectionLocation,
399 diag::note_pragma_entered_here);
400 return true;
401 }
402 }
Hans Wennborg899ded92014-10-16 20:52:46 +0000403 Context.SectionInfos[SectionName] =
404 ASTContext::SectionInfo(nullptr, PragmaSectionLocation, SectionFlags);
Warren Huntc3b18962014-04-08 22:30:47 +0000405 return false;
406}
407
408/// \brief Called on well formed \#pragma bss_seg().
409void Sema::ActOnPragmaMSSeg(SourceLocation PragmaLocation,
410 PragmaMsStackAction Action,
411 llvm::StringRef StackSlotLabel,
412 StringLiteral *SegmentName,
413 llvm::StringRef PragmaName) {
414 PragmaStack<StringLiteral *> *Stack =
415 llvm::StringSwitch<PragmaStack<StringLiteral *> *>(PragmaName)
416 .Case("data_seg", &DataSegStack)
417 .Case("bss_seg", &BSSSegStack)
418 .Case("const_seg", &ConstSegStack)
419 .Case("code_seg", &CodeSegStack);
420 if (Action & PSK_Pop && Stack->Stack.empty())
421 Diag(PragmaLocation, diag::warn_pragma_pop_failed) << PragmaName
422 << "stack empty";
Reid Kleckner2a133222015-03-04 23:39:17 +0000423 if (SegmentName &&
424 !checkSectionName(SegmentName->getLocStart(), SegmentName->getString()))
425 return;
Warren Huntc3b18962014-04-08 22:30:47 +0000426 Stack->Act(PragmaLocation, Action, StackSlotLabel, SegmentName);
427}
428
429/// \brief Called on well formed \#pragma bss_seg().
430void Sema::ActOnPragmaMSSection(SourceLocation PragmaLocation,
431 int SectionFlags, StringLiteral *SegmentName) {
432 UnifySection(SegmentName->getString(), SectionFlags, PragmaLocation);
433}
434
Reid Kleckner1a711b12014-07-22 00:53:05 +0000435void Sema::ActOnPragmaMSInitSeg(SourceLocation PragmaLocation,
436 StringLiteral *SegmentName) {
437 // There's no stack to maintain, so we just have a current section. When we
438 // see the default section, reset our current section back to null so we stop
439 // tacking on unnecessary attributes.
440 CurInitSeg = SegmentName->getString() == ".CRT$XCU" ? nullptr : SegmentName;
441 CurInitSegLoc = PragmaLocation;
442}
443
Argyrios Kyrtzidisee569622011-01-17 18:58:44 +0000444void Sema::ActOnPragmaUnused(const Token &IdTok, Scope *curScope,
445 SourceLocation PragmaLoc) {
Ted Kremenekfd14fad2009-03-23 22:28:25 +0000446
Argyrios Kyrtzidisee569622011-01-17 18:58:44 +0000447 IdentifierInfo *Name = IdTok.getIdentifierInfo();
448 LookupResult Lookup(*this, Name, IdTok.getLocation(), LookupOrdinaryName);
Craig Topperc3ec1492014-05-26 06:22:03 +0000449 LookupParsedName(Lookup, curScope, nullptr, true);
Ted Kremenekfd14fad2009-03-23 22:28:25 +0000450
Argyrios Kyrtzidisee569622011-01-17 18:58:44 +0000451 if (Lookup.empty()) {
452 Diag(PragmaLoc, diag::warn_pragma_unused_undeclared_var)
453 << Name << SourceRange(IdTok.getLocation());
454 return;
Ted Kremenekfd14fad2009-03-23 22:28:25 +0000455 }
Argyrios Kyrtzidisee569622011-01-17 18:58:44 +0000456
457 VarDecl *VD = Lookup.getAsSingle<VarDecl>();
Argyrios Kyrtzidisff115a22011-01-27 18:16:48 +0000458 if (!VD) {
459 Diag(PragmaLoc, diag::warn_pragma_unused_expected_var_arg)
Argyrios Kyrtzidisee569622011-01-17 18:58:44 +0000460 << Name << SourceRange(IdTok.getLocation());
461 return;
462 }
463
464 // Warn if this was used before being marked unused.
465 if (VD->isUsed())
466 Diag(PragmaLoc, diag::warn_used_but_marked_unused) << Name;
467
Aaron Ballman0bcd6c12016-03-09 16:48:08 +0000468 VD->addAttr(UnusedAttr::CreateImplicit(Context, UnusedAttr::GNU_unused,
469 IdTok.getLocation()));
Ted Kremenekfd14fad2009-03-23 22:28:25 +0000470}
Eli Friedman570024a2010-08-05 06:57:20 +0000471
John McCall32f5fe12011-09-30 05:12:12 +0000472void Sema::AddCFAuditedAttribute(Decl *D) {
473 SourceLocation Loc = PP.getPragmaARCCFCodeAuditedLoc();
474 if (!Loc.isValid()) return;
475
476 // Don't add a redundant or conflicting attribute.
477 if (D->hasAttr<CFAuditedTransferAttr>() ||
478 D->hasAttr<CFUnknownTransferAttr>())
479 return;
480
Aaron Ballman36a53502014-01-16 13:03:14 +0000481 D->addAttr(CFAuditedTransferAttr::CreateImplicit(Context, Loc));
John McCall32f5fe12011-09-30 05:12:12 +0000482}
483
Dario Domizioli13a0a382014-05-23 12:13:25 +0000484void Sema::ActOnPragmaOptimize(bool On, SourceLocation PragmaLoc) {
485 if(On)
486 OptimizeOffPragmaLocation = SourceLocation();
487 else
488 OptimizeOffPragmaLocation = PragmaLoc;
489}
490
491void Sema::AddRangeBasedOptnone(FunctionDecl *FD) {
492 // In the future, check other pragmas if they're implemented (e.g. pragma
493 // optimize 0 will probably map to this functionality too).
494 if(OptimizeOffPragmaLocation.isValid())
495 AddOptnoneAttributeIfNoConflicts(FD, OptimizeOffPragmaLocation);
496}
497
498void Sema::AddOptnoneAttributeIfNoConflicts(FunctionDecl *FD,
499 SourceLocation Loc) {
500 // Don't add a conflicting attribute. No diagnostic is needed.
501 if (FD->hasAttr<MinSizeAttr>() || FD->hasAttr<AlwaysInlineAttr>())
502 return;
503
504 // Add attributes only if required. Optnone requires noinline as well, but if
505 // either is already present then don't bother adding them.
506 if (!FD->hasAttr<OptimizeNoneAttr>())
507 FD->addAttr(OptimizeNoneAttr::CreateImplicit(Context, Loc));
508 if (!FD->hasAttr<NoInlineAttr>())
509 FD->addAttr(NoInlineAttr::CreateImplicit(Context, Loc));
510}
511
John McCall2faf32c2010-12-10 02:59:44 +0000512typedef std::vector<std::pair<unsigned, SourceLocation> > VisStack;
Alp Tokerceb95c42014-03-02 03:20:16 +0000513enum : unsigned { NoVisibility = ~0U };
Eli Friedman570024a2010-08-05 06:57:20 +0000514
515void Sema::AddPushedVisibilityAttribute(Decl *D) {
516 if (!VisContext)
517 return;
518
Rafael Espindola54606d52012-12-25 07:31:49 +0000519 NamedDecl *ND = dyn_cast<NamedDecl>(D);
John McCalld041a9b2013-02-20 01:54:26 +0000520 if (ND && ND->getExplicitVisibility(NamedDecl::VisibilityForValue))
Eli Friedman570024a2010-08-05 06:57:20 +0000521 return;
522
523 VisStack *Stack = static_cast<VisStack*>(VisContext);
John McCall2faf32c2010-12-10 02:59:44 +0000524 unsigned rawType = Stack->back().first;
525 if (rawType == NoVisibility) return;
526
527 VisibilityAttr::VisibilityType type
528 = (VisibilityAttr::VisibilityType) rawType;
Alexis Huntdcfba7b2010-08-18 23:23:40 +0000529 SourceLocation loc = Stack->back().second;
Eli Friedman570024a2010-08-05 06:57:20 +0000530
Aaron Ballman36a53502014-01-16 13:03:14 +0000531 D->addAttr(VisibilityAttr::CreateImplicit(Context, type, loc));
Eli Friedman570024a2010-08-05 06:57:20 +0000532}
533
534/// FreeVisContext - Deallocate and null out VisContext.
535void Sema::FreeVisContext() {
536 delete static_cast<VisStack*>(VisContext);
Craig Topperc3ec1492014-05-26 06:22:03 +0000537 VisContext = nullptr;
Eli Friedman570024a2010-08-05 06:57:20 +0000538}
539
John McCall2faf32c2010-12-10 02:59:44 +0000540static void PushPragmaVisibility(Sema &S, unsigned type, SourceLocation loc) {
John McCallb1be5232010-08-26 09:15:37 +0000541 // Put visibility on stack.
542 if (!S.VisContext)
543 S.VisContext = new VisStack;
544
545 VisStack *Stack = static_cast<VisStack*>(S.VisContext);
546 Stack->push_back(std::make_pair(type, loc));
547}
548
Rafael Espindolade15baf2012-01-21 05:43:40 +0000549void Sema::ActOnPragmaVisibility(const IdentifierInfo* VisType,
Eli Friedman570024a2010-08-05 06:57:20 +0000550 SourceLocation PragmaLoc) {
Rafael Espindolade15baf2012-01-21 05:43:40 +0000551 if (VisType) {
Eli Friedman570024a2010-08-05 06:57:20 +0000552 // Compute visibility to use.
Aaron Ballman682ee422013-09-11 19:47:58 +0000553 VisibilityAttr::VisibilityType T;
554 if (!VisibilityAttr::ConvertStrToVisibilityType(VisType->getName(), T)) {
555 Diag(PragmaLoc, diag::warn_attribute_unknown_visibility) << VisType;
Eli Friedman570024a2010-08-05 06:57:20 +0000556 return;
557 }
Aaron Ballman682ee422013-09-11 19:47:58 +0000558 PushPragmaVisibility(*this, T, PragmaLoc);
Eli Friedman570024a2010-08-05 06:57:20 +0000559 } else {
Rafael Espindola6d65d7b2012-02-01 23:24:59 +0000560 PopPragmaVisibility(false, PragmaLoc);
Eli Friedman570024a2010-08-05 06:57:20 +0000561 }
562}
563
Peter Collingbourne564c0fa2011-02-14 01:42:35 +0000564void Sema::ActOnPragmaFPContract(tok::OnOffSwitch OOS) {
565 switch (OOS) {
566 case tok::OOS_ON:
567 FPFeatures.fp_contract = 1;
568 break;
569 case tok::OOS_OFF:
570 FPFeatures.fp_contract = 0;
571 break;
572 case tok::OOS_DEFAULT:
David Blaikiebbafb8a2012-03-11 07:00:24 +0000573 FPFeatures.fp_contract = getLangOpts().DefaultFPContract;
Peter Collingbourne564c0fa2011-02-14 01:42:35 +0000574 break;
575 }
576}
577
Rafael Espindola6d65d7b2012-02-01 23:24:59 +0000578void Sema::PushNamespaceVisibilityAttr(const VisibilityAttr *Attr,
579 SourceLocation Loc) {
John McCall2faf32c2010-12-10 02:59:44 +0000580 // Visibility calculations will consider the namespace's visibility.
581 // Here we just want to note that we're in a visibility context
582 // which overrides any enclosing #pragma context, but doesn't itself
583 // contribute visibility.
Rafael Espindola6d65d7b2012-02-01 23:24:59 +0000584 PushPragmaVisibility(*this, NoVisibility, Loc);
Eli Friedman570024a2010-08-05 06:57:20 +0000585}
586
Rafael Espindola6d65d7b2012-02-01 23:24:59 +0000587void Sema::PopPragmaVisibility(bool IsNamespaceEnd, SourceLocation EndLoc) {
588 if (!VisContext) {
589 Diag(EndLoc, diag::err_pragma_pop_visibility_mismatch);
590 return;
Eli Friedman570024a2010-08-05 06:57:20 +0000591 }
Rafael Espindola6d65d7b2012-02-01 23:24:59 +0000592
593 // Pop visibility from stack
594 VisStack *Stack = static_cast<VisStack*>(VisContext);
595
596 const std::pair<unsigned, SourceLocation> *Back = &Stack->back();
597 bool StartsWithPragma = Back->first != NoVisibility;
598 if (StartsWithPragma && IsNamespaceEnd) {
599 Diag(Back->second, diag::err_pragma_push_visibility_mismatch);
600 Diag(EndLoc, diag::note_surrounding_namespace_ends_here);
601
602 // For better error recovery, eat all pushes inside the namespace.
603 do {
604 Stack->pop_back();
605 Back = &Stack->back();
606 StartsWithPragma = Back->first != NoVisibility;
607 } while (StartsWithPragma);
608 } else if (!StartsWithPragma && !IsNamespaceEnd) {
609 Diag(EndLoc, diag::err_pragma_pop_visibility_mismatch);
610 Diag(Back->second, diag::note_surrounding_namespace_starts_here);
611 return;
612 }
613
614 Stack->pop_back();
615 // To simplify the implementation, never keep around an empty stack.
616 if (Stack->empty())
617 FreeVisContext();
Eli Friedman570024a2010-08-05 06:57:20 +0000618}