SemaAttr.cpp revision 1eb4433ac451dc16f4133a88af2d002ac26c58ef
15a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner//===--- SemaAttr.cpp - Semantic Analysis for Attributes ------------------===// 25a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner// 35a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner// The LLVM Compiler Infrastructure 45a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner// 55a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner// This file is distributed under the University of Illinois Open Source 65a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner// License. See LICENSE.TXT for details. 75a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner// 85a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner//===----------------------------------------------------------------------===// 95a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner// 10574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner// This file implements semantic analysis for non-trivial attributes and 11574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner// pragmas. 125a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner// 135a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner//===----------------------------------------------------------------------===// 145a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner 155a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner#include "Sema.h" 165a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner#include "clang/AST/Expr.h" 175a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattnerusing namespace clang; 185a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner 19574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner//===----------------------------------------------------------------------===// 20574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner// Pragma Packed 21574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner//===----------------------------------------------------------------------===// 22574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner 23574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattnernamespace { 24574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner /// PragmaPackStack - Simple class to wrap the stack used by #pragma 25574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner /// pack. 26574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner class PragmaPackStack { 27574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner typedef std::vector< std::pair<unsigned, IdentifierInfo*> > stack_ty; 28574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner 29574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner /// Alignment - The current user specified alignment. 30574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner unsigned Alignment; 31574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner 32574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner /// Stack - Entries in the #pragma pack stack, consisting of saved 33574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner /// alignments and optional names. 34574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner stack_ty Stack; 351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump public: 37574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner PragmaPackStack() : Alignment(0) {} 38574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner 39574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner void setAlignment(unsigned A) { Alignment = A; } 40574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner unsigned getAlignment() { return Alignment; } 41574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner 42574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner /// push - Push the current alignment onto the stack, optionally 43574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner /// using the given \arg Name for the record, if non-zero. 44574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner void push(IdentifierInfo *Name) { 45574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner Stack.push_back(std::make_pair(Alignment, Name)); 46574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner } 47574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner 48574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner /// pop - Pop a record from the stack and restore the current 49574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner /// alignment to the previous value. If \arg Name is non-zero then 50574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner /// the first such named record is popped, otherwise the top record 51574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner /// is popped. Returns true if the pop succeeded. 52574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner bool pop(IdentifierInfo *Name); 53574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner }; 54574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner} // end anonymous namespace. 55574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner 56574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattnerbool PragmaPackStack::pop(IdentifierInfo *Name) { 57574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner if (Stack.empty()) 58574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner return false; 591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 60574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner // If name is empty just pop top. 61574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner if (!Name) { 62574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner Alignment = Stack.back().first; 63574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner Stack.pop_back(); 64574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner return true; 651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 67574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner // Otherwise, find the named record. 68574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner for (unsigned i = Stack.size(); i != 0; ) { 69574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner --i; 70574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner if (Stack[i].second == Name) { 71574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner // Found it, pop up to and including this record. 72574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner Alignment = Stack[i].first; 73574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner Stack.erase(Stack.begin() + i, Stack.end()); 74574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner return true; 75574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner } 76574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner } 771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 78574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner return false; 79574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner} 80574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner 81574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner 82574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner/// FreePackedContext - Deallocate and null out PackContext. 83574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattnervoid Sema::FreePackedContext() { 84574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner delete static_cast<PragmaPackStack*>(PackContext); 85574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner PackContext = 0; 86574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner} 87574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner 88574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner/// getPragmaPackAlignment() - Return the current alignment as specified by 89574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner/// the current #pragma pack directive, or 0 if none is currently active. 90574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattnerunsigned Sema::getPragmaPackAlignment() const { 91574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner if (PackContext) 92574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner return static_cast<PragmaPackStack*>(PackContext)->getAlignment(); 93574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner return 0; 94574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner} 95574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner 961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpvoid Sema::ActOnPragmaPack(PragmaPackKind Kind, IdentifierInfo *Name, 971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump ExprTy *alignment, SourceLocation PragmaLoc, 985a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner SourceLocation LParenLoc, SourceLocation RParenLoc) { 995a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner Expr *Alignment = static_cast<Expr *>(alignment); 1005a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner 1015a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner // If specified then alignment must be a "small" power of two. 1025a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner unsigned AlignmentVal = 0; 1035a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner if (Alignment) { 1045a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner llvm::APSInt Val; 1051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 10679cd11620c6f05dbf7bb706744eba354574e8b54Daniel Dunbar // pack(0) is like pack(), which just works out since that is what 10779cd11620c6f05dbf7bb706744eba354574e8b54Daniel Dunbar // we use 0 for in PackAttr. 1085a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner if (!Alignment->isIntegerConstantExpr(Val, Context) || 10979cd11620c6f05dbf7bb706744eba354574e8b54Daniel Dunbar !(Val == 0 || Val.isPowerOf2()) || 1105a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner Val.getZExtValue() > 16) { 1115a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner Diag(PragmaLoc, diag::warn_pragma_pack_invalid_alignment); 1125a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner Alignment->Destroy(Context); 1135a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner return; // Ignore 1145a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner } 1155a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner 1165a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner AlignmentVal = (unsigned) Val.getZExtValue(); 1175a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner } 1181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 119574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner if (PackContext == 0) 120574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner PackContext = new PragmaPackStack(); 1211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 122574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner PragmaPackStack *Context = static_cast<PragmaPackStack*>(PackContext); 1231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1245a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner switch (Kind) { 1255a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner case Action::PPK_Default: // pack([n]) 126574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner Context->setAlignment(AlignmentVal); 1275a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner break; 1285a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner 1295a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner case Action::PPK_Show: // pack(show) 1305a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner // Show the current alignment, making sure to show the right value 1315a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner // for the default. 132574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner AlignmentVal = Context->getAlignment(); 1335a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner // FIXME: This should come from the target. 1345a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner if (AlignmentVal == 0) 1355a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner AlignmentVal = 8; 1365a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner Diag(PragmaLoc, diag::warn_pragma_pack_show) << AlignmentVal; 1375a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner break; 1385a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner 1395a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner case Action::PPK_Push: // pack(push [, id] [, [n]) 140574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner Context->push(Name); 1415a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner // Set the new alignment if specified. 1425a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner if (Alignment) 1431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Context->setAlignment(AlignmentVal); 1445a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner break; 1455a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner 1465a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner case Action::PPK_Pop: // pack(pop [, id] [, n]) 1475a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner // MSDN, C/C++ Preprocessor Reference > Pragma Directives > pack: 1485a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner // "#pragma pack(pop, identifier, n) is undefined" 1495a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner if (Alignment && Name) 1501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Diag(PragmaLoc, diag::warn_pragma_pack_pop_identifer_and_alignment); 1511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1525a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner // Do the pop. 153574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner if (!Context->pop(Name)) { 1545a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner // If a name was specified then failure indicates the name 1555a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner // wasn't found. Otherwise failure indicates the stack was 1565a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner // empty. 1575a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner Diag(PragmaLoc, diag::warn_pragma_pack_pop_failed) 1585a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner << (Name ? "no record matching name" : "stack empty"); 1595a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner 1605a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner // FIXME: Warn about popping named records as MSVC does. 1615a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner } else { 1625a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner // Pop succeeded, set the new alignment if specified. 1635a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner if (Alignment) 164574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner Context->setAlignment(AlignmentVal); 1655a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner } 1665a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner break; 1675a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner 1685a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner default: 1695a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner assert(0 && "Invalid #pragma pack kind."); 1705a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner } 1715a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner} 1725a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner 1737a02a3733cdd2ca672902d869fda4ef2e3f05052Ted Kremenekvoid Sema::ActOnPragmaUnused(const Token *Identifiers, unsigned NumIdentifiers, 1747a02a3733cdd2ca672902d869fda4ef2e3f05052Ted Kremenek Scope *curScope, 1754726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek SourceLocation PragmaLoc, 1764726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek SourceLocation LParenLoc, 1774726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek SourceLocation RParenLoc) { 1784726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek 1797a02a3733cdd2ca672902d869fda4ef2e3f05052Ted Kremenek for (unsigned i = 0; i < NumIdentifiers; ++i) { 1807a02a3733cdd2ca672902d869fda4ef2e3f05052Ted Kremenek const Token &Tok = Identifiers[i]; 1811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump IdentifierInfo *Name = Tok.getIdentifierInfo(); 1827a02a3733cdd2ca672902d869fda4ef2e3f05052Ted Kremenek const LookupResult &Lookup = LookupParsedName(curScope, NULL, Name, 1837a02a3733cdd2ca672902d869fda4ef2e3f05052Ted Kremenek LookupOrdinaryName, 1847a02a3733cdd2ca672902d869fda4ef2e3f05052Ted Kremenek false, true, 1857a02a3733cdd2ca672902d869fda4ef2e3f05052Ted Kremenek Tok.getLocation()); 1867a02a3733cdd2ca672902d869fda4ef2e3f05052Ted Kremenek // FIXME: Handle Lookup.isAmbiguous? 1877a02a3733cdd2ca672902d869fda4ef2e3f05052Ted Kremenek 1887a02a3733cdd2ca672902d869fda4ef2e3f05052Ted Kremenek NamedDecl *ND = Lookup.getAsDecl(); 1897a02a3733cdd2ca672902d869fda4ef2e3f05052Ted Kremenek 1901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (!ND) { 1917a02a3733cdd2ca672902d869fda4ef2e3f05052Ted Kremenek Diag(PragmaLoc, diag::warn_pragma_unused_undeclared_var) 1927a02a3733cdd2ca672902d869fda4ef2e3f05052Ted Kremenek << Name << SourceRange(Tok.getLocation()); 1937a02a3733cdd2ca672902d869fda4ef2e3f05052Ted Kremenek continue; 1944726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek } 1951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1967a02a3733cdd2ca672902d869fda4ef2e3f05052Ted Kremenek if (!isa<VarDecl>(ND) || !cast<VarDecl>(ND)->hasLocalStorage()) { 1977a02a3733cdd2ca672902d869fda4ef2e3f05052Ted Kremenek Diag(PragmaLoc, diag::warn_pragma_unused_expected_localvar) 1987a02a3733cdd2ca672902d869fda4ef2e3f05052Ted Kremenek << Name << SourceRange(Tok.getLocation()); 1997a02a3733cdd2ca672902d869fda4ef2e3f05052Ted Kremenek continue; 2007a02a3733cdd2ca672902d869fda4ef2e3f05052Ted Kremenek } 2011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2027a02a3733cdd2ca672902d869fda4ef2e3f05052Ted Kremenek ND->addAttr(::new (Context) UnusedAttr()); 2034726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek } 2044726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek} 205