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