SemaAttr.cpp revision ff214ccaf21d9165c10c89ba0a63659969a8cdbb
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 "Sema.h" 16#include "Lookup.h" 17#include "clang/AST/Expr.h" 18#include "clang/Basic/TargetInfo.h" 19#include "clang/Lex/Preprocessor.h" 20using namespace clang; 21 22//===----------------------------------------------------------------------===// 23// Pragma 'pack' and 'options align' 24//===----------------------------------------------------------------------===// 25 26namespace { 27 struct PackStackEntry { 28 unsigned Alignment; 29 IdentifierInfo *Name; 30 }; 31 32 /// PragmaPackStack - Simple class to wrap the stack used by #pragma 33 /// pack. 34 class PragmaPackStack { 35 typedef std::vector<PackStackEntry> stack_ty; 36 37 /// Alignment - The current user specified alignment. 38 unsigned Alignment; 39 40 /// Stack - Entries in the #pragma pack stack, consisting of saved 41 /// alignments and optional names. 42 stack_ty Stack; 43 44 public: 45 PragmaPackStack() : Alignment(0) {} 46 47 void setAlignment(unsigned A) { Alignment = A; } 48 unsigned getAlignment() { return Alignment; } 49 50 /// push - Push the current alignment onto the stack, optionally 51 /// using the given \arg Name for the record, if non-zero. 52 void push(IdentifierInfo *Name) { 53 PackStackEntry PSE = { Alignment, Name }; 54 Stack.push_back(PSE); 55 } 56 57 /// pop - Pop a record from the stack and restore the current 58 /// alignment to the previous value. If \arg Name is non-zero then 59 /// the first such named record is popped, otherwise the top record 60 /// is popped. Returns true if the pop succeeded. 61 bool pop(IdentifierInfo *Name); 62 }; 63} // end anonymous namespace. 64 65bool PragmaPackStack::pop(IdentifierInfo *Name) { 66 if (Stack.empty()) 67 return false; 68 69 // If name is empty just pop top. 70 if (!Name) { 71 Alignment = Stack.back().Alignment; 72 Stack.pop_back(); 73 return true; 74 } 75 76 // Otherwise, find the named record. 77 for (unsigned i = Stack.size(); i != 0; ) { 78 --i; 79 if (Stack[i].Name == Name) { 80 // Found it, pop up to and including this record. 81 Alignment = Stack[i].Alignment; 82 Stack.erase(Stack.begin() + i, Stack.end()); 83 return true; 84 } 85 } 86 87 return false; 88} 89 90 91/// FreePackedContext - Deallocate and null out PackContext. 92void Sema::FreePackedContext() { 93 delete static_cast<PragmaPackStack*>(PackContext); 94 PackContext = 0; 95} 96 97void Sema::AddAlignmentAttributesForRecord(RecordDecl *RD) { 98 // If there is no pack context, we don't need any attributes. 99 if (!PackContext) 100 return; 101 102 PragmaPackStack *Stack = static_cast<PragmaPackStack*>(PackContext); 103 104 // Otherwise, check to see if we need a max field alignment attribute. 105 if (unsigned Alignment = Stack->getAlignment()) 106 RD->addAttr(::new (Context) MaxFieldAlignmentAttr(Alignment * 8)); 107} 108 109void Sema::ActOnPragmaOptionsAlign(PragmaOptionsAlignKind Kind, 110 SourceLocation PragmaLoc, 111 SourceLocation KindLoc) { 112 if (PackContext == 0) 113 PackContext = new PragmaPackStack(); 114 115 PragmaPackStack *Context = static_cast<PragmaPackStack*>(PackContext); 116 117 // Reset just pops the top of the stack. 118 if (Kind == Action::POAK_Reset) { 119 // Do the pop. 120 if (!Context->pop(0)) { 121 // If a name was specified then failure indicates the name 122 // wasn't found. Otherwise failure indicates the stack was 123 // empty. 124 Diag(PragmaLoc, diag::warn_pragma_options_align_reset_failed) 125 << "stack empty"; 126 } 127 return; 128 } 129 130 // We don't support #pragma options align=power. 131 switch (Kind) { 132 case POAK_Natural: 133 Context->push(0); 134 Context->setAlignment(0); 135 break; 136 137 case POAK_Mac68k: 138 // Check if the target supports this. 139 if (!PP.getTargetInfo().hasAlignMac68kSupport()) { 140 Diag(PragmaLoc, diag::err_pragma_options_align_mac68k_target_unsupported); 141 return; 142 } else { 143 // Otherwise, just warn about it for now. 144 Diag(PragmaLoc, diag::warn_pragma_options_align_unsupported_option) 145 << KindLoc; 146 } 147 break; 148 149 default: 150 Diag(PragmaLoc, diag::warn_pragma_options_align_unsupported_option) 151 << KindLoc; 152 break; 153 } 154} 155 156void Sema::ActOnPragmaPack(PragmaPackKind Kind, IdentifierInfo *Name, 157 ExprTy *alignment, SourceLocation PragmaLoc, 158 SourceLocation LParenLoc, SourceLocation RParenLoc) { 159 Expr *Alignment = static_cast<Expr *>(alignment); 160 161 // If specified then alignment must be a "small" power of two. 162 unsigned AlignmentVal = 0; 163 if (Alignment) { 164 llvm::APSInt Val; 165 166 // pack(0) is like pack(), which just works out since that is what 167 // we use 0 for in PackAttr. 168 if (Alignment->isTypeDependent() || 169 Alignment->isValueDependent() || 170 !Alignment->isIntegerConstantExpr(Val, Context) || 171 !(Val == 0 || Val.isPowerOf2()) || 172 Val.getZExtValue() > 16) { 173 Diag(PragmaLoc, diag::warn_pragma_pack_invalid_alignment); 174 Alignment->Destroy(Context); 175 return; // Ignore 176 } 177 178 AlignmentVal = (unsigned) Val.getZExtValue(); 179 } 180 181 if (PackContext == 0) 182 PackContext = new PragmaPackStack(); 183 184 PragmaPackStack *Context = static_cast<PragmaPackStack*>(PackContext); 185 186 switch (Kind) { 187 case Action::PPK_Default: // pack([n]) 188 Context->setAlignment(AlignmentVal); 189 break; 190 191 case Action::PPK_Show: // pack(show) 192 // Show the current alignment, making sure to show the right value 193 // for the default. 194 AlignmentVal = Context->getAlignment(); 195 // FIXME: This should come from the target. 196 if (AlignmentVal == 0) 197 AlignmentVal = 8; 198 Diag(PragmaLoc, diag::warn_pragma_pack_show) << AlignmentVal; 199 break; 200 201 case Action::PPK_Push: // pack(push [, id] [, [n]) 202 Context->push(Name); 203 // Set the new alignment if specified. 204 if (Alignment) 205 Context->setAlignment(AlignmentVal); 206 break; 207 208 case Action::PPK_Pop: // pack(pop [, id] [, n]) 209 // MSDN, C/C++ Preprocessor Reference > Pragma Directives > pack: 210 // "#pragma pack(pop, identifier, n) is undefined" 211 if (Alignment && Name) 212 Diag(PragmaLoc, diag::warn_pragma_pack_pop_identifer_and_alignment); 213 214 // Do the pop. 215 if (!Context->pop(Name)) { 216 // If a name was specified then failure indicates the name 217 // wasn't found. Otherwise failure indicates the stack was 218 // empty. 219 Diag(PragmaLoc, diag::warn_pragma_pack_pop_failed) 220 << (Name ? "no record matching name" : "stack empty"); 221 222 // FIXME: Warn about popping named records as MSVC does. 223 } else { 224 // Pop succeeded, set the new alignment if specified. 225 if (Alignment) 226 Context->setAlignment(AlignmentVal); 227 } 228 break; 229 230 default: 231 assert(0 && "Invalid #pragma pack kind."); 232 } 233} 234 235void Sema::ActOnPragmaUnused(const Token *Identifiers, unsigned NumIdentifiers, 236 Scope *curScope, 237 SourceLocation PragmaLoc, 238 SourceLocation LParenLoc, 239 SourceLocation RParenLoc) { 240 241 for (unsigned i = 0; i < NumIdentifiers; ++i) { 242 const Token &Tok = Identifiers[i]; 243 IdentifierInfo *Name = Tok.getIdentifierInfo(); 244 LookupResult Lookup(*this, Name, Tok.getLocation(), LookupOrdinaryName); 245 LookupParsedName(Lookup, curScope, NULL, true); 246 247 if (Lookup.empty()) { 248 Diag(PragmaLoc, diag::warn_pragma_unused_undeclared_var) 249 << Name << SourceRange(Tok.getLocation()); 250 continue; 251 } 252 253 VarDecl *VD = Lookup.getAsSingle<VarDecl>(); 254 if (!VD || !VD->hasLocalStorage()) { 255 Diag(PragmaLoc, diag::warn_pragma_unused_expected_localvar) 256 << Name << SourceRange(Tok.getLocation()); 257 continue; 258 } 259 260 VD->addAttr(::new (Context) UnusedAttr()); 261 } 262} 263