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