clang API Documentation
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 }