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 
15 #include "clang/Sema/SemaInternal.h"
16 #include "clang/AST/ASTConsumer.h"
17 #include "clang/AST/Attr.h"
18 #include "clang/AST/Expr.h"
19 #include "clang/Basic/TargetInfo.h"
20 #include "clang/Lex/Preprocessor.h"
21 #include "clang/Sema/Lookup.h"
22 using namespace clang;
23 
24 //===----------------------------------------------------------------------===//
25 // Pragma 'pack' and 'options align'
26 //===----------------------------------------------------------------------===//
27 
28 namespace {
29   struct PackStackEntry {
30     // We just use a sentinel to represent when the stack is set to mac68k
31     // alignment.
32     static const unsigned kMac68kAlignmentSentinel = ~0U;
33 
34     unsigned Alignment;
35     IdentifierInfo *Name;
36   };
37 
38   /// PragmaPackStack - Simple class to wrap the stack used by #pragma
39   /// pack.
40   class PragmaPackStack {
41     typedef std::vector<PackStackEntry> stack_ty;
42 
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;
49 
50   public:
51     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) {
59       PackStackEntry PSE = { Alignment, Name };
60       Stack.push_back(PSE);
61     }
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.
67     bool pop(IdentifierInfo *Name, bool IsReset);
68   };
69 }  // end anonymous namespace.
70 
71 bool PragmaPackStack::pop(IdentifierInfo *Name, bool IsReset) {
72   // If name is empty just pop top.
73   if (!Name) {
74     // 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 
91     return true;
92   }
93 
94   // Otherwise, find the named record.
95   for (unsigned i = Stack.size(); i != 0; ) {
96     --i;
97     if (Stack[i].Name == Name) {
98       // Found it, pop up to and including this record.
99       Alignment = Stack[i].Alignment;
100       Stack.erase(Stack.begin() + i, Stack.end());
101       return true;
102     }
103   }
104 
105   return false;
106 }
107 
108 
109 /// FreePackedContext - Deallocate and null out PackContext.
110 void Sema::FreePackedContext() {
111   delete static_cast<PragmaPackStack*>(PackContext);
112   PackContext = 0;
113 }
114 
115 void Sema::AddAlignmentAttributesForRecord(RecordDecl *RD) {
116   // If there is no pack context, we don't need any attributes.
117   if (!PackContext)
118     return;
119 
120   PragmaPackStack *Stack = static_cast<PragmaPackStack*>(PackContext);
121 
122   // Otherwise, check to see if we need a max field alignment attribute.
123   if (unsigned Alignment = Stack->getAlignment()) {
124     if (Alignment == PackStackEntry::kMac68kAlignmentSentinel)
125       RD->addAttr(AlignMac68kAttr::CreateImplicit(Context));
126     else
127       RD->addAttr(MaxFieldAlignmentAttr::CreateImplicit(Context,
128                                                         Alignment * 8));
129   }
130 }
131 
132 void Sema::AddMsStructLayoutForRecord(RecordDecl *RD) {
133   if (!MSStructPragmaOn)
134     return;
135   RD->addAttr(MsStructAttr::CreateImplicit(Context));
136 }
137 
138 void Sema::ActOnPragmaOptionsAlign(PragmaOptionsAlignKind Kind,
139                                    SourceLocation PragmaLoc) {
140   if (PackContext == 0)
141     PackContext = new PragmaPackStack();
142 
143   PragmaPackStack *Context = static_cast<PragmaPackStack*>(PackContext);
144 
145   switch (Kind) {
146     // For all targets we support native and natural are the same.
147     //
148     // FIXME: This is not true on Darwin/PPC.
149   case POAK_Native:
150   case POAK_Power:
151   case POAK_Natural:
152     Context->push(0);
153     Context->setAlignment(0);
154     break;
155 
156     // Note that '#pragma options align=packed' is not equivalent to attribute
157     // packed, it has a different precedence relative to attribute aligned.
158   case POAK_Packed:
159     Context->push(0);
160     Context->setAlignment(1);
161     break;
162 
163   case POAK_Mac68k:
164     // Check if the target supports this.
165     if (!PP.getTargetInfo().hasAlignMac68kSupport()) {
166       Diag(PragmaLoc, diag::err_pragma_options_align_mac68k_target_unsupported);
167       return;
168     }
169     Context->push(0);
170     Context->setAlignment(PackStackEntry::kMac68kAlignmentSentinel);
171     break;
172 
173   case POAK_Reset:
174     // Reset just pops the top of the stack, or resets the current alignment to
175     // default.
176     if (!Context->pop(0, /*IsReset=*/true)) {
177       Diag(PragmaLoc, diag::warn_pragma_options_align_reset_failed)
178         << "stack empty";
179     }
180     break;
181   }
182 }
183 
184 void Sema::ActOnPragmaPack(PragmaPackKind Kind, IdentifierInfo *Name,
185                            Expr *alignment, SourceLocation PragmaLoc,
186                            SourceLocation LParenLoc, SourceLocation RParenLoc) {
187   Expr *Alignment = static_cast<Expr *>(alignment);
188 
189   // If specified then alignment must be a "small" power of two.
190   unsigned AlignmentVal = 0;
191   if (Alignment) {
192     llvm::APSInt Val;
193 
194     // pack(0) is like pack(), which just works out since that is what
195     // we use 0 for in PackAttr.
196     if (Alignment->isTypeDependent() ||
197         Alignment->isValueDependent() ||
198         !Alignment->isIntegerConstantExpr(Val, Context) ||
199         !(Val == 0 || Val.isPowerOf2()) ||
200         Val.getZExtValue() > 16) {
201       Diag(PragmaLoc, diag::warn_pragma_pack_invalid_alignment);
202       return; // Ignore
203     }
204 
205     AlignmentVal = (unsigned) Val.getZExtValue();
206   }
207 
208   if (PackContext == 0)
209     PackContext = new PragmaPackStack();
210 
211   PragmaPackStack *Context = static_cast<PragmaPackStack*>(PackContext);
212 
213   switch (Kind) {
214   case Sema::PPK_Default: // pack([n])
215     Context->setAlignment(AlignmentVal);
216     break;
217 
218   case Sema::PPK_Show: // pack(show)
219     // Show the current alignment, making sure to show the right value
220     // for the default.
221     AlignmentVal = Context->getAlignment();
222     // FIXME: This should come from the target.
223     if (AlignmentVal == 0)
224       AlignmentVal = 8;
225     if (AlignmentVal == PackStackEntry::kMac68kAlignmentSentinel)
226       Diag(PragmaLoc, diag::warn_pragma_pack_show) << "mac68k";
227     else
228       Diag(PragmaLoc, diag::warn_pragma_pack_show) << AlignmentVal;
229     break;
230 
231   case Sema::PPK_Push: // pack(push [, id] [, [n])
232     Context->push(Name);
233     // Set the new alignment if specified.
234     if (Alignment)
235       Context->setAlignment(AlignmentVal);
236     break;
237 
238   case Sema::PPK_Pop: // pack(pop [, id] [,  n])
239     // MSDN, C/C++ Preprocessor Reference > Pragma Directives > pack:
240     // "#pragma pack(pop, identifier, n) is undefined"
241     if (Alignment && Name)
242       Diag(PragmaLoc, diag::warn_pragma_pack_pop_identifer_and_alignment);
243 
244     // Do the pop.
245     if (!Context->pop(Name, /*IsReset=*/false)) {
246       // If a name was specified then failure indicates the name
247       // wasn't found. Otherwise failure indicates the stack was
248       // empty.
249       Diag(PragmaLoc, diag::warn_pragma_pack_pop_failed)
250         << (Name ? "no record matching name" : "stack empty");
251 
252       // FIXME: Warn about popping named records as MSVC does.
253     } else {
254       // Pop succeeded, set the new alignment if specified.
255       if (Alignment)
256         Context->setAlignment(AlignmentVal);
257     }
258     break;
259   }
260 }
261 
262 void Sema::ActOnPragmaMSStruct(PragmaMSStructKind Kind) {
263   MSStructPragmaOn = (Kind == PMSST_ON);
264 }
265 
266 void Sema::ActOnPragmaMSComment(PragmaMSCommentKind Kind, StringRef Arg) {
267   // FIXME: Serialize this.
268   switch (Kind) {
269   case PCK_Unknown:
270     llvm_unreachable("unexpected pragma comment kind");
271   case PCK_Linker:
272     Consumer.HandleLinkerOptionPragma(Arg);
273     return;
274   case PCK_Lib:
275     Consumer.HandleDependentLibrary(Arg);
276     return;
277   case PCK_Compiler:
278   case PCK_ExeStr:
279   case PCK_User:
280     return;  // We ignore all of these.
281   }
282   llvm_unreachable("invalid pragma comment kind");
283 }
284 
285 void Sema::ActOnPragmaDetectMismatch(StringRef Name, StringRef Value) {
286   // FIXME: Serialize this.
287   Consumer.HandleDetectMismatch(Name, Value);
288 }
289 
290 void Sema::ActOnPragmaUnused(const Token &IdTok, Scope *curScope,
291                              SourceLocation PragmaLoc) {
292 
293   IdentifierInfo *Name = IdTok.getIdentifierInfo();
294   LookupResult Lookup(*this, Name, IdTok.getLocation(), LookupOrdinaryName);
295   LookupParsedName(Lookup, curScope, NULL, true);
296 
297   if (Lookup.empty()) {
298     Diag(PragmaLoc, diag::warn_pragma_unused_undeclared_var)
299       << Name << SourceRange(IdTok.getLocation());
300     return;
301   }
302 
303   VarDecl *VD = Lookup.getAsSingle<VarDecl>();
304   if (!VD) {
305     Diag(PragmaLoc, diag::warn_pragma_unused_expected_var_arg)
306       << Name << SourceRange(IdTok.getLocation());
307     return;
308   }
309 
310   // Warn if this was used before being marked unused.
311   if (VD->isUsed())
312     Diag(PragmaLoc, diag::warn_used_but_marked_unused) << Name;
313 
314   VD->addAttr(UnusedAttr::CreateImplicit(Context, IdTok.getLocation()));
315 }
316 
317 void Sema::AddCFAuditedAttribute(Decl *D) {
318   SourceLocation Loc = PP.getPragmaARCCFCodeAuditedLoc();
319   if (!Loc.isValid()) return;
320 
321   // Don't add a redundant or conflicting attribute.
322   if (D->hasAttr<CFAuditedTransferAttr>() ||
323       D->hasAttr<CFUnknownTransferAttr>())
324     return;
325 
326   D->addAttr(CFAuditedTransferAttr::CreateImplicit(Context, Loc));
327 }
328 
329 typedef std::vector<std::pair<unsigned, SourceLocation> > VisStack;
330 enum { NoVisibility = (unsigned) -1 };
331 
332 void Sema::AddPushedVisibilityAttribute(Decl *D) {
333   if (!VisContext)
334     return;
335 
336   NamedDecl *ND = dyn_cast<NamedDecl>(D);
337   if (ND && ND->getExplicitVisibility(NamedDecl::VisibilityForValue))
338     return;
339 
340   VisStack *Stack = static_cast<VisStack*>(VisContext);
341   unsigned rawType = Stack->back().first;
342   if (rawType == NoVisibility) return;
343 
344   VisibilityAttr::VisibilityType type
345     = (VisibilityAttr::VisibilityType) rawType;
346   SourceLocation loc = Stack->back().second;
347 
348   D->addAttr(VisibilityAttr::CreateImplicit(Context, type, loc));
349 }
350 
351 /// FreeVisContext - Deallocate and null out VisContext.
352 void Sema::FreeVisContext() {
353   delete static_cast<VisStack*>(VisContext);
354   VisContext = 0;
355 }
356 
357 static void PushPragmaVisibility(Sema &S, unsigned type, SourceLocation loc) {
358   // Put visibility on stack.
359   if (!S.VisContext)
360     S.VisContext = new VisStack;
361 
362   VisStack *Stack = static_cast<VisStack*>(S.VisContext);
363   Stack->push_back(std::make_pair(type, loc));
364 }
365 
366 void Sema::ActOnPragmaVisibility(const IdentifierInfo* VisType,
367                                  SourceLocation PragmaLoc) {
368   if (VisType) {
369     // Compute visibility to use.
370     VisibilityAttr::VisibilityType T;
371     if (!VisibilityAttr::ConvertStrToVisibilityType(VisType->getName(), T)) {
372       Diag(PragmaLoc, diag::warn_attribute_unknown_visibility) << VisType;
373       return;
374     }
375     PushPragmaVisibility(*this, T, PragmaLoc);
376   } else {
377     PopPragmaVisibility(false, PragmaLoc);
378   }
379 }
380 
381 void Sema::ActOnPragmaFPContract(tok::OnOffSwitch OOS) {
382   switch (OOS) {
383   case tok::OOS_ON:
384     FPFeatures.fp_contract = 1;
385     break;
386   case tok::OOS_OFF:
387     FPFeatures.fp_contract = 0;
388     break;
389   case tok::OOS_DEFAULT:
390     FPFeatures.fp_contract = getLangOpts().DefaultFPContract;
391     break;
392   }
393 }
394 
395 void Sema::PushNamespaceVisibilityAttr(const VisibilityAttr *Attr,
396                                        SourceLocation Loc) {
397   // Visibility calculations will consider the namespace's visibility.
398   // Here we just want to note that we're in a visibility context
399   // which overrides any enclosing #pragma context, but doesn't itself
400   // contribute visibility.
401   PushPragmaVisibility(*this, NoVisibility, Loc);
402 }
403 
404 void Sema::PopPragmaVisibility(bool IsNamespaceEnd, SourceLocation EndLoc) {
405   if (!VisContext) {
406     Diag(EndLoc, diag::err_pragma_pop_visibility_mismatch);
407     return;
408   }
409 
410   // Pop visibility from stack
411   VisStack *Stack = static_cast<VisStack*>(VisContext);
412 
413   const std::pair<unsigned, SourceLocation> *Back = &Stack->back();
414   bool StartsWithPragma = Back->first != NoVisibility;
415   if (StartsWithPragma && IsNamespaceEnd) {
416     Diag(Back->second, diag::err_pragma_push_visibility_mismatch);
417     Diag(EndLoc, diag::note_surrounding_namespace_ends_here);
418 
419     // For better error recovery, eat all pushes inside the namespace.
420     do {
421       Stack->pop_back();
422       Back = &Stack->back();
423       StartsWithPragma = Back->first != NoVisibility;
424     } while (StartsWithPragma);
425   } else if (!StartsWithPragma && !IsNamespaceEnd) {
426     Diag(EndLoc, diag::err_pragma_pop_visibility_mismatch);
427     Diag(Back->second, diag::note_surrounding_namespace_starts_here);
428     return;
429   }
430 
431   Stack->pop_back();
432   // To simplify the implementation, never keep around an empty stack.
433   if (Stack->empty())
434     FreeVisContext();
435 }
436