diff options
Diffstat (limited to 'lib/Sema/SemaAttr.cpp')
-rw-r--r-- | lib/Sema/SemaAttr.cpp | 84 |
1 files changed, 38 insertions, 46 deletions
diff --git a/lib/Sema/SemaAttr.cpp b/lib/Sema/SemaAttr.cpp index 1bf8444c42b74..0a5335a2be05e 100644 --- a/lib/Sema/SemaAttr.cpp +++ b/lib/Sema/SemaAttr.cpp @@ -32,8 +32,8 @@ namespace { /// Stack - Entries in the #pragma pack stack, consisting of saved /// alignments and optional names. stack_ty Stack; - - public: + + public: PragmaPackStack() : Alignment(0) {} void setAlignment(unsigned A) { Alignment = A; } @@ -56,14 +56,14 @@ namespace { bool PragmaPackStack::pop(IdentifierInfo *Name) { if (Stack.empty()) return false; - + // If name is empty just pop top. if (!Name) { Alignment = Stack.back().first; Stack.pop_back(); return true; - } - + } + // Otherwise, find the named record. for (unsigned i = Stack.size(); i != 0; ) { --i; @@ -74,7 +74,7 @@ bool PragmaPackStack::pop(IdentifierInfo *Name) { return true; } } - + return false; } @@ -93,8 +93,8 @@ unsigned Sema::getPragmaPackAlignment() const { return 0; } -void Sema::ActOnPragmaPack(PragmaPackKind Kind, IdentifierInfo *Name, - ExprTy *alignment, SourceLocation PragmaLoc, +void Sema::ActOnPragmaPack(PragmaPackKind Kind, IdentifierInfo *Name, + ExprTy *alignment, SourceLocation PragmaLoc, SourceLocation LParenLoc, SourceLocation RParenLoc) { Expr *Alignment = static_cast<Expr *>(alignment); @@ -102,7 +102,7 @@ void Sema::ActOnPragmaPack(PragmaPackKind Kind, IdentifierInfo *Name, unsigned AlignmentVal = 0; if (Alignment) { llvm::APSInt Val; - + // pack(0) is like pack(), which just works out since that is what // we use 0 for in PackAttr. if (!Alignment->isIntegerConstantExpr(Val, Context) || @@ -115,12 +115,12 @@ void Sema::ActOnPragmaPack(PragmaPackKind Kind, IdentifierInfo *Name, AlignmentVal = (unsigned) Val.getZExtValue(); } - + if (PackContext == 0) PackContext = new PragmaPackStack(); - + PragmaPackStack *Context = static_cast<PragmaPackStack*>(PackContext); - + switch (Kind) { case Action::PPK_Default: // pack([n]) Context->setAlignment(AlignmentVal); @@ -140,15 +140,15 @@ void Sema::ActOnPragmaPack(PragmaPackKind Kind, IdentifierInfo *Name, Context->push(Name); // Set the new alignment if specified. if (Alignment) - Context->setAlignment(AlignmentVal); + Context->setAlignment(AlignmentVal); break; case Action::PPK_Pop: // pack(pop [, id] [, n]) // MSDN, C/C++ Preprocessor Reference > Pragma Directives > pack: // "#pragma pack(pop, identifier, n) is undefined" if (Alignment && Name) - Diag(PragmaLoc, diag::warn_pragma_pack_pop_identifer_and_alignment); - + Diag(PragmaLoc, diag::warn_pragma_pack_pop_identifer_and_alignment); + // Do the pop. if (!Context->pop(Name)) { // If a name was specified then failure indicates the name @@ -170,42 +170,34 @@ void Sema::ActOnPragmaPack(PragmaPackKind Kind, IdentifierInfo *Name, } } -void Sema::ActOnPragmaUnused(ExprTy **Exprs, unsigned NumExprs, +void Sema::ActOnPragmaUnused(const Token *Identifiers, unsigned NumIdentifiers, + Scope *curScope, SourceLocation PragmaLoc, SourceLocation LParenLoc, SourceLocation RParenLoc) { - - // Verify that all of the expressions are valid before - // modifying the attributes of any referenced decl. - Expr *ErrorExpr = 0; - - for (unsigned i = 0; i < NumExprs; ++i) { - Expr *Ex = (Expr*) Exprs[i]; - if (!isa<DeclRefExpr>(Ex)) { - ErrorExpr = Ex; - break; - } - Decl *d = cast<DeclRefExpr>(Ex)->getDecl();; + for (unsigned i = 0; i < NumIdentifiers; ++i) { + const Token &Tok = Identifiers[i]; + IdentifierInfo *Name = Tok.getIdentifierInfo(); + LookupResult Lookup; + LookupParsedName(Lookup, curScope, NULL, Name,LookupOrdinaryName, + false, true, Tok.getLocation()); + // FIXME: Handle Lookup.isAmbiguous? - if (!isa<VarDecl>(d) || !cast<VarDecl>(d)->hasLocalStorage()) { - ErrorExpr = Ex; - break; + NamedDecl *ND = Lookup.getAsSingleDecl(Context); + + if (!ND) { + Diag(PragmaLoc, diag::warn_pragma_unused_undeclared_var) + << Name << SourceRange(Tok.getLocation()); + continue; } - } - - // Delete the expressions if we encountered any error. - if (ErrorExpr) { - Diag(ErrorExpr->getLocStart(), diag::warn_pragma_unused_expected_localvar); - for (unsigned i = 0; i < NumExprs; ++i) - ((Expr*) Exprs[i])->Destroy(Context); - return; - } - - // Otherwise, add the 'unused' attribute to each referenced declaration. - for (unsigned i = 0; i < NumExprs; ++i) { - DeclRefExpr *DR = (DeclRefExpr*) Exprs[i]; - DR->getDecl()->addAttr(::new (Context) UnusedAttr()); - DR->Destroy(Context); + + if (!isa<VarDecl>(ND) || !cast<VarDecl>(ND)->hasLocalStorage()) { + Diag(PragmaLoc, diag::warn_pragma_unused_expected_localvar) + << Name << SourceRange(Tok.getLocation()); + continue; + } + + ND->addAttr(::new (Context) UnusedAttr()); } } |