blob: 96793d5a40a1e531097a1713215b09b107a18a22 [file] [log] [blame]
Chris Lattner5a0c3512009-02-17 00:57:29 +00001//===--- 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//
Chris Lattner574aa402009-02-17 01:09:29 +000010// This file implements semantic analysis for non-trivial attributes and
11// pragmas.
Chris Lattner5a0c3512009-02-17 00:57:29 +000012//
13//===----------------------------------------------------------------------===//
14
Douglas Gregore737f502010-08-12 20:07:10 +000015#include "clang/Sema/Sema.h"
16#include "clang/Sema/Lookup.h"
Chris Lattner5a0c3512009-02-17 00:57:29 +000017#include "clang/AST/Expr.h"
Daniel Dunbar613fd672010-05-27 00:35:16 +000018#include "clang/Basic/TargetInfo.h"
19#include "clang/Lex/Preprocessor.h"
Chris Lattner5a0c3512009-02-17 00:57:29 +000020using namespace clang;
21
Chris Lattner574aa402009-02-17 01:09:29 +000022//===----------------------------------------------------------------------===//
Daniel Dunbarea75a822010-05-27 00:04:40 +000023// Pragma 'pack' and 'options align'
Chris Lattner574aa402009-02-17 01:09:29 +000024//===----------------------------------------------------------------------===//
25
26namespace {
Daniel Dunbarae2232b2010-05-27 02:25:27 +000027 struct PackStackEntry {
Daniel Dunbarc6082fe2010-05-27 05:45:51 +000028 // We just use a sentinel to represent when the stack is set to mac68k
29 // alignment.
30 static const unsigned kMac68kAlignmentSentinel = ~0U;
31
Daniel Dunbarae2232b2010-05-27 02:25:27 +000032 unsigned Alignment;
33 IdentifierInfo *Name;
34 };
35
Chris Lattner574aa402009-02-17 01:09:29 +000036 /// PragmaPackStack - Simple class to wrap the stack used by #pragma
37 /// pack.
38 class PragmaPackStack {
Daniel Dunbarae2232b2010-05-27 02:25:27 +000039 typedef std::vector<PackStackEntry> stack_ty;
Chris Lattner574aa402009-02-17 01:09:29 +000040
41 /// Alignment - The current user specified alignment.
42 unsigned Alignment;
43
44 /// Stack - Entries in the #pragma pack stack, consisting of saved
45 /// alignments and optional names.
46 stack_ty Stack;
Mike Stump1eb44332009-09-09 15:08:12 +000047
48 public:
Chris Lattner574aa402009-02-17 01:09:29 +000049 PragmaPackStack() : Alignment(0) {}
50
51 void setAlignment(unsigned A) { Alignment = A; }
52 unsigned getAlignment() { return Alignment; }
53
54 /// push - Push the current alignment onto the stack, optionally
55 /// using the given \arg Name for the record, if non-zero.
56 void push(IdentifierInfo *Name) {
Daniel Dunbarae2232b2010-05-27 02:25:27 +000057 PackStackEntry PSE = { Alignment, Name };
58 Stack.push_back(PSE);
Chris Lattner574aa402009-02-17 01:09:29 +000059 }
60
61 /// pop - Pop a record from the stack and restore the current
62 /// alignment to the previous value. If \arg Name is non-zero then
63 /// the first such named record is popped, otherwise the top record
64 /// is popped. Returns true if the pop succeeded.
Daniel Dunbarddc6ff62010-07-16 04:54:16 +000065 bool pop(IdentifierInfo *Name, bool IsReset);
Chris Lattner574aa402009-02-17 01:09:29 +000066 };
67} // end anonymous namespace.
68
Daniel Dunbarddc6ff62010-07-16 04:54:16 +000069bool PragmaPackStack::pop(IdentifierInfo *Name, bool IsReset) {
Chris Lattner574aa402009-02-17 01:09:29 +000070 // If name is empty just pop top.
71 if (!Name) {
Daniel Dunbarddc6ff62010-07-16 04:54:16 +000072 // An empty stack is a special case...
73 if (Stack.empty()) {
74 // If this isn't a reset, it is always an error.
75 if (!IsReset)
76 return false;
77
78 // Otherwise, it is an error only if some alignment has been set.
79 if (!Alignment)
80 return false;
81
82 // Otherwise, reset to the default alignment.
83 Alignment = 0;
84 } else {
85 Alignment = Stack.back().Alignment;
86 Stack.pop_back();
87 }
88
Chris Lattner574aa402009-02-17 01:09:29 +000089 return true;
Mike Stump1eb44332009-09-09 15:08:12 +000090 }
91
Chris Lattner574aa402009-02-17 01:09:29 +000092 // Otherwise, find the named record.
93 for (unsigned i = Stack.size(); i != 0; ) {
94 --i;
Daniel Dunbarae2232b2010-05-27 02:25:27 +000095 if (Stack[i].Name == Name) {
Chris Lattner574aa402009-02-17 01:09:29 +000096 // Found it, pop up to and including this record.
Daniel Dunbarae2232b2010-05-27 02:25:27 +000097 Alignment = Stack[i].Alignment;
Chris Lattner574aa402009-02-17 01:09:29 +000098 Stack.erase(Stack.begin() + i, Stack.end());
99 return true;
100 }
101 }
Mike Stump1eb44332009-09-09 15:08:12 +0000102
Chris Lattner574aa402009-02-17 01:09:29 +0000103 return false;
104}
105
106
107/// FreePackedContext - Deallocate and null out PackContext.
108void Sema::FreePackedContext() {
109 delete static_cast<PragmaPackStack*>(PackContext);
110 PackContext = 0;
111}
112
Daniel Dunbar9f21f892010-05-27 01:53:40 +0000113void Sema::AddAlignmentAttributesForRecord(RecordDecl *RD) {
114 // If there is no pack context, we don't need any attributes.
115 if (!PackContext)
116 return;
117
118 PragmaPackStack *Stack = static_cast<PragmaPackStack*>(PackContext);
119
120 // Otherwise, check to see if we need a max field alignment attribute.
Daniel Dunbarc6082fe2010-05-27 05:45:51 +0000121 if (unsigned Alignment = Stack->getAlignment()) {
122 if (Alignment == PackStackEntry::kMac68kAlignmentSentinel)
123 RD->addAttr(::new (Context) AlignMac68kAttr());
124 else
125 RD->addAttr(::new (Context) MaxFieldAlignmentAttr(Alignment * 8));
126 }
Chris Lattner574aa402009-02-17 01:09:29 +0000127}
128
Daniel Dunbarea75a822010-05-27 00:04:40 +0000129void Sema::ActOnPragmaOptionsAlign(PragmaOptionsAlignKind Kind,
130 SourceLocation PragmaLoc,
131 SourceLocation KindLoc) {
132 if (PackContext == 0)
133 PackContext = new PragmaPackStack();
134
135 PragmaPackStack *Context = static_cast<PragmaPackStack*>(PackContext);
136
Daniel Dunbarddc6ff62010-07-16 04:54:16 +0000137 // Reset just pops the top of the stack, or resets the current alignment to
138 // default.
Daniel Dunbarea75a822010-05-27 00:04:40 +0000139 if (Kind == Action::POAK_Reset) {
Daniel Dunbarddc6ff62010-07-16 04:54:16 +0000140 if (!Context->pop(0, /*IsReset=*/true)) {
Daniel Dunbarea75a822010-05-27 00:04:40 +0000141 Diag(PragmaLoc, diag::warn_pragma_options_align_reset_failed)
142 << "stack empty";
143 }
144 return;
145 }
146
Daniel Dunbarea75a822010-05-27 00:04:40 +0000147 switch (Kind) {
Daniel Dunbar638e7cf2010-05-27 18:42:09 +0000148 // For all targets we support native and natural are the same.
149 //
150 // FIXME: This is not true on Darwin/PPC.
151 case POAK_Native:
Daniel Dunbar450f7932010-05-28 19:43:33 +0000152 case POAK_Power:
Daniel Dunbard6b305d2010-05-28 20:08:00 +0000153 case POAK_Natural:
Daniel Dunbar450f7932010-05-28 19:43:33 +0000154 Context->push(0);
155 Context->setAlignment(0);
156 break;
157
Daniel Dunbar6f739142010-05-27 18:42:17 +0000158 // Note that '#pragma options align=packed' is not equivalent to attribute
159 // packed, it has a different precedence relative to attribute aligned.
160 case POAK_Packed:
161 Context->push(0);
162 Context->setAlignment(1);
163 break;
164
Daniel Dunbar613fd672010-05-27 00:35:16 +0000165 case POAK_Mac68k:
166 // Check if the target supports this.
167 if (!PP.getTargetInfo().hasAlignMac68kSupport()) {
168 Diag(PragmaLoc, diag::err_pragma_options_align_mac68k_target_unsupported);
169 return;
Daniel Dunbar613fd672010-05-27 00:35:16 +0000170 }
Daniel Dunbarc6082fe2010-05-27 05:45:51 +0000171 Context->push(0);
172 Context->setAlignment(PackStackEntry::kMac68kAlignmentSentinel);
Daniel Dunbar613fd672010-05-27 00:35:16 +0000173 break;
174
Daniel Dunbarea75a822010-05-27 00:04:40 +0000175 default:
176 Diag(PragmaLoc, diag::warn_pragma_options_align_unsupported_option)
177 << KindLoc;
178 break;
179 }
180}
181
Mike Stump1eb44332009-09-09 15:08:12 +0000182void Sema::ActOnPragmaPack(PragmaPackKind Kind, IdentifierInfo *Name,
183 ExprTy *alignment, SourceLocation PragmaLoc,
Chris Lattner5a0c3512009-02-17 00:57:29 +0000184 SourceLocation LParenLoc, SourceLocation RParenLoc) {
185 Expr *Alignment = static_cast<Expr *>(alignment);
186
187 // If specified then alignment must be a "small" power of two.
188 unsigned AlignmentVal = 0;
189 if (Alignment) {
190 llvm::APSInt Val;
Mike Stump1eb44332009-09-09 15:08:12 +0000191
Daniel Dunbar79cd1162009-03-06 20:45:54 +0000192 // pack(0) is like pack(), which just works out since that is what
193 // we use 0 for in PackAttr.
Douglas Gregorac06a0e2010-05-18 23:01:22 +0000194 if (Alignment->isTypeDependent() ||
195 Alignment->isValueDependent() ||
196 !Alignment->isIntegerConstantExpr(Val, Context) ||
Daniel Dunbar79cd1162009-03-06 20:45:54 +0000197 !(Val == 0 || Val.isPowerOf2()) ||
Chris Lattner5a0c3512009-02-17 00:57:29 +0000198 Val.getZExtValue() > 16) {
199 Diag(PragmaLoc, diag::warn_pragma_pack_invalid_alignment);
Chris Lattner5a0c3512009-02-17 00:57:29 +0000200 return; // Ignore
201 }
202
203 AlignmentVal = (unsigned) Val.getZExtValue();
204 }
Mike Stump1eb44332009-09-09 15:08:12 +0000205
Chris Lattner574aa402009-02-17 01:09:29 +0000206 if (PackContext == 0)
207 PackContext = new PragmaPackStack();
Mike Stump1eb44332009-09-09 15:08:12 +0000208
Chris Lattner574aa402009-02-17 01:09:29 +0000209 PragmaPackStack *Context = static_cast<PragmaPackStack*>(PackContext);
Mike Stump1eb44332009-09-09 15:08:12 +0000210
Chris Lattner5a0c3512009-02-17 00:57:29 +0000211 switch (Kind) {
212 case Action::PPK_Default: // pack([n])
Chris Lattner574aa402009-02-17 01:09:29 +0000213 Context->setAlignment(AlignmentVal);
Chris Lattner5a0c3512009-02-17 00:57:29 +0000214 break;
215
216 case Action::PPK_Show: // pack(show)
217 // Show the current alignment, making sure to show the right value
218 // for the default.
Chris Lattner574aa402009-02-17 01:09:29 +0000219 AlignmentVal = Context->getAlignment();
Chris Lattner5a0c3512009-02-17 00:57:29 +0000220 // FIXME: This should come from the target.
221 if (AlignmentVal == 0)
222 AlignmentVal = 8;
Daniel Dunbarc6082fe2010-05-27 05:45:51 +0000223 if (AlignmentVal == PackStackEntry::kMac68kAlignmentSentinel)
224 Diag(PragmaLoc, diag::warn_pragma_pack_show) << "mac68k";
225 else
226 Diag(PragmaLoc, diag::warn_pragma_pack_show) << AlignmentVal;
Chris Lattner5a0c3512009-02-17 00:57:29 +0000227 break;
228
229 case Action::PPK_Push: // pack(push [, id] [, [n])
Chris Lattner574aa402009-02-17 01:09:29 +0000230 Context->push(Name);
Chris Lattner5a0c3512009-02-17 00:57:29 +0000231 // Set the new alignment if specified.
232 if (Alignment)
Mike Stump1eb44332009-09-09 15:08:12 +0000233 Context->setAlignment(AlignmentVal);
Chris Lattner5a0c3512009-02-17 00:57:29 +0000234 break;
235
236 case Action::PPK_Pop: // pack(pop [, id] [, n])
237 // MSDN, C/C++ Preprocessor Reference > Pragma Directives > pack:
238 // "#pragma pack(pop, identifier, n) is undefined"
239 if (Alignment && Name)
Mike Stump1eb44332009-09-09 15:08:12 +0000240 Diag(PragmaLoc, diag::warn_pragma_pack_pop_identifer_and_alignment);
241
Chris Lattner5a0c3512009-02-17 00:57:29 +0000242 // Do the pop.
Daniel Dunbarddc6ff62010-07-16 04:54:16 +0000243 if (!Context->pop(Name, /*IsReset=*/false)) {
Chris Lattner5a0c3512009-02-17 00:57:29 +0000244 // If a name was specified then failure indicates the name
245 // wasn't found. Otherwise failure indicates the stack was
246 // empty.
247 Diag(PragmaLoc, diag::warn_pragma_pack_pop_failed)
248 << (Name ? "no record matching name" : "stack empty");
249
250 // FIXME: Warn about popping named records as MSVC does.
251 } else {
252 // Pop succeeded, set the new alignment if specified.
253 if (Alignment)
Chris Lattner574aa402009-02-17 01:09:29 +0000254 Context->setAlignment(AlignmentVal);
Chris Lattner5a0c3512009-02-17 00:57:29 +0000255 }
256 break;
257
258 default:
259 assert(0 && "Invalid #pragma pack kind.");
260 }
261}
262
Ted Kremenek7a02a372009-08-03 23:24:57 +0000263void Sema::ActOnPragmaUnused(const Token *Identifiers, unsigned NumIdentifiers,
264 Scope *curScope,
Ted Kremenek4726d032009-03-23 22:28:25 +0000265 SourceLocation PragmaLoc,
266 SourceLocation LParenLoc,
267 SourceLocation RParenLoc) {
Ted Kremenek4726d032009-03-23 22:28:25 +0000268
Ted Kremenek7a02a372009-08-03 23:24:57 +0000269 for (unsigned i = 0; i < NumIdentifiers; ++i) {
270 const Token &Tok = Identifiers[i];
Mike Stump1eb44332009-09-09 15:08:12 +0000271 IdentifierInfo *Name = Tok.getIdentifierInfo();
John McCalla24dc2e2009-11-17 02:14:36 +0000272 LookupResult Lookup(*this, Name, Tok.getLocation(), LookupOrdinaryName);
273 LookupParsedName(Lookup, curScope, NULL, true);
Ted Kremenek4726d032009-03-23 22:28:25 +0000274
John McCall1bcee0a2009-12-02 08:25:40 +0000275 if (Lookup.empty()) {
Ted Kremenek7a02a372009-08-03 23:24:57 +0000276 Diag(PragmaLoc, diag::warn_pragma_unused_undeclared_var)
277 << Name << SourceRange(Tok.getLocation());
278 continue;
Ted Kremenek4726d032009-03-23 22:28:25 +0000279 }
Mike Stump1eb44332009-09-09 15:08:12 +0000280
John McCall1bcee0a2009-12-02 08:25:40 +0000281 VarDecl *VD = Lookup.getAsSingle<VarDecl>();
282 if (!VD || !VD->hasLocalStorage()) {
Ted Kremenek7a02a372009-08-03 23:24:57 +0000283 Diag(PragmaLoc, diag::warn_pragma_unused_expected_localvar)
284 << Name << SourceRange(Tok.getLocation());
285 continue;
286 }
Mike Stump1eb44332009-09-09 15:08:12 +0000287
John McCall1bcee0a2009-12-02 08:25:40 +0000288 VD->addAttr(::new (Context) UnusedAttr());
Ted Kremenek4726d032009-03-23 22:28:25 +0000289 }
290}
Eli Friedmanaa8b0d12010-08-05 06:57:20 +0000291
292typedef std::vector<VisibilityAttr::VisibilityTypes> VisStack;
293
294void Sema::AddPushedVisibilityAttribute(Decl *D) {
295 if (!VisContext)
296 return;
297
298 if (D->hasAttr<VisibilityAttr>())
299 return;
300
301 VisStack *Stack = static_cast<VisStack*>(VisContext);
302 VisibilityAttr::VisibilityTypes type = Stack->back();
303
304 D->addAttr(::new (Context) VisibilityAttr(type, true));
305}
306
307/// FreeVisContext - Deallocate and null out VisContext.
308void Sema::FreeVisContext() {
309 delete static_cast<VisStack*>(VisContext);
310 VisContext = 0;
311}
312
313void Sema::ActOnPragmaVisibility(bool IsPush, const IdentifierInfo* VisType,
314 SourceLocation PragmaLoc) {
315 if (IsPush) {
316 // Compute visibility to use.
317 VisibilityAttr::VisibilityTypes type;
318 if (VisType->isStr("default"))
319 type = VisibilityAttr::DefaultVisibility;
320 else if (VisType->isStr("hidden"))
321 type = VisibilityAttr::HiddenVisibility;
322 else if (VisType->isStr("internal"))
323 type = VisibilityAttr::HiddenVisibility; // FIXME
324 else if (VisType->isStr("protected"))
325 type = VisibilityAttr::ProtectedVisibility;
326 else {
327 Diag(PragmaLoc, diag::warn_attribute_unknown_visibility) <<
328 VisType->getName();
329 return;
330 }
331 PushPragmaVisibility(type);
332 } else {
333 PopPragmaVisibility();
334 }
335}
336
337void Sema::PushPragmaVisibility(VisibilityAttr::VisibilityTypes type) {
338 // Put visibility on stack.
339 if (!VisContext)
340 VisContext = new VisStack;
341
342 VisStack *Stack = static_cast<VisStack*>(VisContext);
343 Stack->push_back(type);
344}
345
346void Sema::PopPragmaVisibility() {
347 // Pop visibility from stack, if there is one on the stack.
348 if (VisContext) {
349 VisStack *Stack = static_cast<VisStack*>(VisContext);
350
351 Stack->pop_back();
352 // To simplify the implementation, never keep around an empty stack.
353 if (Stack->empty())
354 FreeVisContext();
355 }
356 // FIXME: Add diag for pop without push.
357}