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