clang API Documentation

SemaAttr.cpp
Go to the documentation of this file.
00001 //===--- SemaAttr.cpp - Semantic Analysis for Attributes ------------------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file implements semantic analysis for non-trivial attributes and
00011 // pragmas.
00012 //
00013 //===----------------------------------------------------------------------===//
00014 
00015 #include "clang/Sema/SemaInternal.h"
00016 #include "clang/Sema/Lookup.h"
00017 #include "clang/AST/Attr.h"
00018 #include "clang/AST/Expr.h"
00019 #include "clang/Basic/TargetInfo.h"
00020 #include "clang/Lex/Preprocessor.h"
00021 using namespace clang;
00022 
00023 //===----------------------------------------------------------------------===//
00024 // Pragma 'pack' and 'options align'
00025 //===----------------------------------------------------------------------===//
00026 
00027 namespace {
00028   struct PackStackEntry {
00029     // We just use a sentinel to represent when the stack is set to mac68k
00030     // alignment.
00031     static const unsigned kMac68kAlignmentSentinel = ~0U;
00032 
00033     unsigned Alignment;
00034     IdentifierInfo *Name;
00035   };
00036 
00037   /// PragmaPackStack - Simple class to wrap the stack used by #pragma
00038   /// pack.
00039   class PragmaPackStack {
00040     typedef std::vector<PackStackEntry> stack_ty;
00041 
00042     /// Alignment - The current user specified alignment.
00043     unsigned Alignment;
00044 
00045     /// Stack - Entries in the #pragma pack stack, consisting of saved
00046     /// alignments and optional names.
00047     stack_ty Stack;
00048 
00049   public:
00050     PragmaPackStack() : Alignment(0) {}
00051 
00052     void setAlignment(unsigned A) { Alignment = A; }
00053     unsigned getAlignment() { return Alignment; }
00054 
00055     /// push - Push the current alignment onto the stack, optionally
00056     /// using the given \arg Name for the record, if non-zero.
00057     void push(IdentifierInfo *Name) {
00058       PackStackEntry PSE = { Alignment, Name };
00059       Stack.push_back(PSE);
00060     }
00061 
00062     /// pop - Pop a record from the stack and restore the current
00063     /// alignment to the previous value. If \arg Name is non-zero then
00064     /// the first such named record is popped, otherwise the top record
00065     /// is popped. Returns true if the pop succeeded.
00066     bool pop(IdentifierInfo *Name, bool IsReset);
00067   };
00068 }  // end anonymous namespace.
00069 
00070 bool PragmaPackStack::pop(IdentifierInfo *Name, bool IsReset) {
00071   // If name is empty just pop top.
00072   if (!Name) {
00073     // An empty stack is a special case...
00074     if (Stack.empty()) {
00075       // If this isn't a reset, it is always an error.
00076       if (!IsReset)
00077         return false;
00078 
00079       // Otherwise, it is an error only if some alignment has been set.
00080       if (!Alignment)
00081         return false;
00082 
00083       // Otherwise, reset to the default alignment.
00084       Alignment = 0;
00085     } else {
00086       Alignment = Stack.back().Alignment;
00087       Stack.pop_back();
00088     }
00089 
00090     return true;
00091   }
00092 
00093   // Otherwise, find the named record.
00094   for (unsigned i = Stack.size(); i != 0; ) {
00095     --i;
00096     if (Stack[i].Name == Name) {
00097       // Found it, pop up to and including this record.
00098       Alignment = Stack[i].Alignment;
00099       Stack.erase(Stack.begin() + i, Stack.end());
00100       return true;
00101     }
00102   }
00103 
00104   return false;
00105 }
00106 
00107 
00108 /// FreePackedContext - Deallocate and null out PackContext.
00109 void Sema::FreePackedContext() {
00110   delete static_cast<PragmaPackStack*>(PackContext);
00111   PackContext = 0;
00112 }
00113 
00114 void Sema::AddAlignmentAttributesForRecord(RecordDecl *RD) {
00115   // If there is no pack context, we don't need any attributes.
00116   if (!PackContext)
00117     return;
00118 
00119   PragmaPackStack *Stack = static_cast<PragmaPackStack*>(PackContext);
00120 
00121   // Otherwise, check to see if we need a max field alignment attribute.
00122   if (unsigned Alignment = Stack->getAlignment()) {
00123     if (Alignment == PackStackEntry::kMac68kAlignmentSentinel)
00124       RD->addAttr(::new (Context) AlignMac68kAttr(SourceLocation(), Context));
00125     else
00126       RD->addAttr(::new (Context) MaxFieldAlignmentAttr(SourceLocation(),
00127                                                         Context,
00128                                                         Alignment * 8));
00129   }
00130 }
00131 
00132 void Sema::AddMsStructLayoutForRecord(RecordDecl *RD) {
00133   if (!MSStructPragmaOn)
00134     return;
00135   RD->addAttr(::new (Context) MsStructAttr(SourceLocation(), Context));
00136 }
00137 
00138 void Sema::ActOnPragmaOptionsAlign(PragmaOptionsAlignKind Kind,
00139                                    SourceLocation PragmaLoc,
00140                                    SourceLocation KindLoc) {
00141   if (PackContext == 0)
00142     PackContext = new PragmaPackStack();
00143 
00144   PragmaPackStack *Context = static_cast<PragmaPackStack*>(PackContext);
00145 
00146   // Reset just pops the top of the stack, or resets the current alignment to
00147   // default.
00148   if (Kind == Sema::POAK_Reset) {
00149     if (!Context->pop(0, /*IsReset=*/true)) {
00150       Diag(PragmaLoc, diag::warn_pragma_options_align_reset_failed)
00151         << "stack empty";
00152     }
00153     return;
00154   }
00155 
00156   switch (Kind) {
00157     // For all targets we support native and natural are the same.
00158     //
00159     // FIXME: This is not true on Darwin/PPC.
00160   case POAK_Native:
00161   case POAK_Power:
00162   case POAK_Natural:
00163     Context->push(0);
00164     Context->setAlignment(0);
00165     break;
00166 
00167     // Note that '#pragma options align=packed' is not equivalent to attribute
00168     // packed, it has a different precedence relative to attribute aligned.
00169   case POAK_Packed:
00170     Context->push(0);
00171     Context->setAlignment(1);
00172     break;
00173 
00174   case POAK_Mac68k:
00175     // Check if the target supports this.
00176     if (!PP.getTargetInfo().hasAlignMac68kSupport()) {
00177       Diag(PragmaLoc, diag::err_pragma_options_align_mac68k_target_unsupported);
00178       return;
00179     }
00180     Context->push(0);
00181     Context->setAlignment(PackStackEntry::kMac68kAlignmentSentinel);
00182     break;
00183 
00184   default:
00185     Diag(PragmaLoc, diag::warn_pragma_options_align_unsupported_option)
00186       << KindLoc;
00187     break;
00188   }
00189 }
00190 
00191 void Sema::ActOnPragmaPack(PragmaPackKind Kind, IdentifierInfo *Name,
00192                            Expr *alignment, SourceLocation PragmaLoc,
00193                            SourceLocation LParenLoc, SourceLocation RParenLoc) {
00194   Expr *Alignment = static_cast<Expr *>(alignment);
00195 
00196   // If specified then alignment must be a "small" power of two.
00197   unsigned AlignmentVal = 0;
00198   if (Alignment) {
00199     llvm::APSInt Val;
00200 
00201     // pack(0) is like pack(), which just works out since that is what
00202     // we use 0 for in PackAttr.
00203     if (Alignment->isTypeDependent() ||
00204         Alignment->isValueDependent() ||
00205         !Alignment->isIntegerConstantExpr(Val, Context) ||
00206         !(Val == 0 || Val.isPowerOf2()) ||
00207         Val.getZExtValue() > 16) {
00208       Diag(PragmaLoc, diag::warn_pragma_pack_invalid_alignment);
00209       return; // Ignore
00210     }
00211 
00212     AlignmentVal = (unsigned) Val.getZExtValue();
00213   }
00214 
00215   if (PackContext == 0)
00216     PackContext = new PragmaPackStack();
00217 
00218   PragmaPackStack *Context = static_cast<PragmaPackStack*>(PackContext);
00219 
00220   switch (Kind) {
00221   case Sema::PPK_Default: // pack([n])
00222     Context->setAlignment(AlignmentVal);
00223     break;
00224 
00225   case Sema::PPK_Show: // pack(show)
00226     // Show the current alignment, making sure to show the right value
00227     // for the default.
00228     AlignmentVal = Context->getAlignment();
00229     // FIXME: This should come from the target.
00230     if (AlignmentVal == 0)
00231       AlignmentVal = 8;
00232     if (AlignmentVal == PackStackEntry::kMac68kAlignmentSentinel)
00233       Diag(PragmaLoc, diag::warn_pragma_pack_show) << "mac68k";
00234     else
00235       Diag(PragmaLoc, diag::warn_pragma_pack_show) << AlignmentVal;
00236     break;
00237 
00238   case Sema::PPK_Push: // pack(push [, id] [, [n])
00239     Context->push(Name);
00240     // Set the new alignment if specified.
00241     if (Alignment)
00242       Context->setAlignment(AlignmentVal);
00243     break;
00244 
00245   case Sema::PPK_Pop: // pack(pop [, id] [,  n])
00246     // MSDN, C/C++ Preprocessor Reference > Pragma Directives > pack:
00247     // "#pragma pack(pop, identifier, n) is undefined"
00248     if (Alignment && Name)
00249       Diag(PragmaLoc, diag::warn_pragma_pack_pop_identifer_and_alignment);
00250 
00251     // Do the pop.
00252     if (!Context->pop(Name, /*IsReset=*/false)) {
00253       // If a name was specified then failure indicates the name
00254       // wasn't found. Otherwise failure indicates the stack was
00255       // empty.
00256       Diag(PragmaLoc, diag::warn_pragma_pack_pop_failed)
00257         << (Name ? "no record matching name" : "stack empty");
00258 
00259       // FIXME: Warn about popping named records as MSVC does.
00260     } else {
00261       // Pop succeeded, set the new alignment if specified.
00262       if (Alignment)
00263         Context->setAlignment(AlignmentVal);
00264     }
00265     break;
00266   }
00267 }
00268 
00269 void Sema::ActOnPragmaMSStruct(PragmaMSStructKind Kind) { 
00270   MSStructPragmaOn = (Kind == PMSST_ON);
00271 }
00272 
00273 void Sema::ActOnPragmaUnused(const Token &IdTok, Scope *curScope,
00274                              SourceLocation PragmaLoc) {
00275 
00276   IdentifierInfo *Name = IdTok.getIdentifierInfo();
00277   LookupResult Lookup(*this, Name, IdTok.getLocation(), LookupOrdinaryName);
00278   LookupParsedName(Lookup, curScope, NULL, true);
00279 
00280   if (Lookup.empty()) {
00281     Diag(PragmaLoc, diag::warn_pragma_unused_undeclared_var)
00282       << Name << SourceRange(IdTok.getLocation());
00283     return;
00284   }
00285 
00286   VarDecl *VD = Lookup.getAsSingle<VarDecl>();
00287   if (!VD) {
00288     Diag(PragmaLoc, diag::warn_pragma_unused_expected_var_arg)
00289       << Name << SourceRange(IdTok.getLocation());
00290     return;
00291   }
00292 
00293   // Warn if this was used before being marked unused.
00294   if (VD->isUsed())
00295     Diag(PragmaLoc, diag::warn_used_but_marked_unused) << Name;
00296 
00297   VD->addAttr(::new (Context) UnusedAttr(IdTok.getLocation(), Context));
00298 }
00299 
00300 void Sema::AddCFAuditedAttribute(Decl *D) {
00301   SourceLocation Loc = PP.getPragmaARCCFCodeAuditedLoc();
00302   if (!Loc.isValid()) return;
00303 
00304   // Don't add a redundant or conflicting attribute.
00305   if (D->hasAttr<CFAuditedTransferAttr>() ||
00306       D->hasAttr<CFUnknownTransferAttr>())
00307     return;
00308 
00309   D->addAttr(::new (Context) CFAuditedTransferAttr(Loc, Context));
00310 }
00311 
00312 typedef std::vector<std::pair<unsigned, SourceLocation> > VisStack;
00313 enum { NoVisibility = (unsigned) -1 };
00314 
00315 void Sema::AddPushedVisibilityAttribute(Decl *D) {
00316   if (!VisContext)
00317     return;
00318 
00319   if (isa<NamedDecl>(D) && cast<NamedDecl>(D)->getExplicitVisibility())
00320     return;
00321 
00322   VisStack *Stack = static_cast<VisStack*>(VisContext);
00323   unsigned rawType = Stack->back().first;
00324   if (rawType == NoVisibility) return;
00325 
00326   VisibilityAttr::VisibilityType type
00327     = (VisibilityAttr::VisibilityType) rawType;
00328   SourceLocation loc = Stack->back().second;
00329 
00330   D->addAttr(::new (Context) VisibilityAttr(loc, Context, type));
00331 }
00332 
00333 /// FreeVisContext - Deallocate and null out VisContext.
00334 void Sema::FreeVisContext() {
00335   delete static_cast<VisStack*>(VisContext);
00336   VisContext = 0;
00337 }
00338 
00339 static void PushPragmaVisibility(Sema &S, unsigned type, SourceLocation loc) {
00340   // Put visibility on stack.
00341   if (!S.VisContext)
00342     S.VisContext = new VisStack;
00343 
00344   VisStack *Stack = static_cast<VisStack*>(S.VisContext);
00345   Stack->push_back(std::make_pair(type, loc));
00346 }
00347 
00348 void Sema::ActOnPragmaVisibility(const IdentifierInfo* VisType,
00349                                  SourceLocation PragmaLoc) {
00350   if (VisType) {
00351     // Compute visibility to use.
00352     VisibilityAttr::VisibilityType type;
00353     if (VisType->isStr("default"))
00354       type = VisibilityAttr::Default;
00355     else if (VisType->isStr("hidden"))
00356       type = VisibilityAttr::Hidden;
00357     else if (VisType->isStr("internal"))
00358       type = VisibilityAttr::Hidden; // FIXME
00359     else if (VisType->isStr("protected"))
00360       type = VisibilityAttr::Protected;
00361     else {
00362       Diag(PragmaLoc, diag::warn_attribute_unknown_visibility) <<
00363         VisType->getName();
00364       return;
00365     }
00366     PushPragmaVisibility(*this, type, PragmaLoc);
00367   } else {
00368     PopPragmaVisibility(false, PragmaLoc);
00369   }
00370 }
00371 
00372 void Sema::ActOnPragmaFPContract(tok::OnOffSwitch OOS) {
00373   switch (OOS) {
00374   case tok::OOS_ON:
00375     FPFeatures.fp_contract = 1;
00376     break;
00377   case tok::OOS_OFF:
00378     FPFeatures.fp_contract = 0; 
00379     break;
00380   case tok::OOS_DEFAULT:
00381     FPFeatures.fp_contract = getLangOpts().DefaultFPContract;
00382     break;
00383   }
00384 }
00385 
00386 void Sema::PushNamespaceVisibilityAttr(const VisibilityAttr *Attr,
00387                                        SourceLocation Loc) {
00388   // Visibility calculations will consider the namespace's visibility.
00389   // Here we just want to note that we're in a visibility context
00390   // which overrides any enclosing #pragma context, but doesn't itself
00391   // contribute visibility.
00392   PushPragmaVisibility(*this, NoVisibility, Loc);
00393 }
00394 
00395 void Sema::PopPragmaVisibility(bool IsNamespaceEnd, SourceLocation EndLoc) {
00396   if (!VisContext) {
00397     Diag(EndLoc, diag::err_pragma_pop_visibility_mismatch);
00398     return;
00399   }
00400 
00401   // Pop visibility from stack
00402   VisStack *Stack = static_cast<VisStack*>(VisContext);
00403 
00404   const std::pair<unsigned, SourceLocation> *Back = &Stack->back();
00405   bool StartsWithPragma = Back->first != NoVisibility;
00406   if (StartsWithPragma && IsNamespaceEnd) {
00407     Diag(Back->second, diag::err_pragma_push_visibility_mismatch);
00408     Diag(EndLoc, diag::note_surrounding_namespace_ends_here);
00409 
00410     // For better error recovery, eat all pushes inside the namespace.
00411     do {
00412       Stack->pop_back();
00413       Back = &Stack->back();
00414       StartsWithPragma = Back->first != NoVisibility;
00415     } while (StartsWithPragma);
00416   } else if (!StartsWithPragma && !IsNamespaceEnd) {
00417     Diag(EndLoc, diag::err_pragma_pop_visibility_mismatch);
00418     Diag(Back->second, diag::note_surrounding_namespace_starts_here);
00419     return;
00420   }
00421 
00422   Stack->pop_back();
00423   // To simplify the implementation, never keep around an empty stack.
00424   if (Stack->empty())
00425     FreeVisContext();
00426 }