r189711 - Consolidating the notion of a GNU attribute parameter with the attribute argument list.

Aaron Ballman aaron at aaronballman.com
Fri Aug 30 18:11:41 PDT 2013


Author: aaronballman
Date: Fri Aug 30 20:11:41 2013
New Revision: 189711

URL: http://llvm.org/viewvc/llvm-project?rev=189711&view=rev
Log:
Consolidating the notion of a GNU attribute parameter with the attribute argument list.

Added:
    cfe/trunk/test/Sema/attr-endian.c
Modified:
    cfe/trunk/include/clang/Sema/AttributeList.h
    cfe/trunk/lib/Parse/ParseDecl.cpp
    cfe/trunk/lib/Parse/ParseDeclCXX.cpp
    cfe/trunk/lib/Sema/AttributeList.cpp
    cfe/trunk/lib/Sema/SemaDeclAttr.cpp
    cfe/trunk/lib/Sema/SemaType.cpp
    cfe/trunk/lib/Sema/TargetAttributesSema.cpp
    cfe/trunk/test/Sema/callingconv.c
    cfe/trunk/test/Sema/warn-type-safety.c
    cfe/trunk/test/SemaObjC/arc.m
    cfe/trunk/test/SemaOpenCL/endian-attr.cl

Modified: cfe/trunk/include/clang/Sema/AttributeList.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/AttributeList.h?rev=189711&r1=189710&r2=189711&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/AttributeList.h (original)
+++ cfe/trunk/include/clang/Sema/AttributeList.h Fri Aug 30 20:11:41 2013
@@ -19,6 +19,7 @@
 #include "clang/Basic/VersionTuple.h"
 #include "clang/Sema/Ownership.h"
 #include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/PointerUnion.h"
 #include "llvm/Support/Allocator.h"
 #include <cassert>
 
@@ -44,6 +45,18 @@ struct AvailabilityChange {
   bool isValid() const { return !Version.empty(); }
 };
 
+/// \brief Wraps an identifier and optional source location for the identifier.
+/// It is expected that these will be created from the ASTContext memory pool.
+struct IdentifierLoc {
+  SourceLocation Loc;
+  IdentifierInfo *Ident;
+};
+
+/// \brief A union of the various pointer types that can be passed to an
+/// AttributeList as an argument.
+typedef llvm::PointerUnion<Expr*, IdentifierLoc*> ArgsUnion;
+typedef llvm::SmallVector<ArgsUnion, 12U> ArgsVector;
+
 /// AttributeList - Represents a syntactic attribute.
 ///
 /// For a GNU attribute, there are four forms of this construct:
@@ -66,13 +79,12 @@ public:
     /// __ptr16, alignas(...), etc.
     AS_Keyword
   };
+
 private:
   IdentifierInfo *AttrName;
   IdentifierInfo *ScopeName;
-  IdentifierInfo *ParmName;
   SourceRange AttrRange;
   SourceLocation ScopeLoc;
-  SourceLocation ParmLoc;
   SourceLocation EllipsisLoc;
 
   /// The number of expression arguments this attribute has.
@@ -100,6 +112,9 @@ private:
   /// Microsoft __delcspec(property) attribute.
   unsigned IsProperty : 1;
 
+  /// True if this has a ParsedType
+  unsigned HasParsedType : 1;
+
   unsigned AttrKind : 8;
 
   /// \brief The location of the 'unavailable' keyword in an
@@ -114,22 +129,27 @@ private:
   /// The next attribute allocated in the current Pool.
   AttributeList *NextInPool;
 
-  Expr **getArgsBuffer() {
-    return reinterpret_cast<Expr**>(this+1);
+  /// Arguments, if any, are stored immediately following the object.
+  ArgsUnion *getArgsBuffer() {
+    return reinterpret_cast<ArgsUnion*>(this+1);
   }
-  Expr * const *getArgsBuffer() const {
-    return reinterpret_cast<Expr* const *>(this+1);
+  ArgsUnion const *getArgsBuffer() const {
+    return reinterpret_cast<ArgsUnion const *>(this+1);
   }
 
   enum AvailabilitySlot {
     IntroducedSlot, DeprecatedSlot, ObsoletedSlot
   };
 
-  AvailabilityChange &getAvailabilitySlot(AvailabilitySlot index) {
-    return reinterpret_cast<AvailabilityChange*>(this+1)[index];
+  /// Availability information is stored immediately following the arguments,
+  /// if any, at the end of the object.
+  AvailabilityChange &getAvailabilitySlot(AvailabilitySlot index) {    
+    return reinterpret_cast<AvailabilityChange*>(getArgsBuffer()
+                                                 + NumArgs)[index];
   }
   const AvailabilityChange &getAvailabilitySlot(AvailabilitySlot index) const {
-    return reinterpret_cast<const AvailabilityChange*>(this+1)[index];
+    return reinterpret_cast<const AvailabilityChange*>(getArgsBuffer()
+                                                       + NumArgs)[index];
   }
 
 public:
@@ -145,14 +165,20 @@ public:
   };
 
 private:
+  /// Type tag information is stored immediately following the arguments, if
+  /// any, at the end of the object.  They are mutually exlusive with
+  /// availability slots.
   TypeTagForDatatypeData &getTypeTagForDatatypeDataSlot() {
-    return *reinterpret_cast<TypeTagForDatatypeData *>(this + 1);
+    return *reinterpret_cast<TypeTagForDatatypeData*>(getArgsBuffer()+NumArgs);
   }
 
   const TypeTagForDatatypeData &getTypeTagForDatatypeDataSlot() const {
-    return *reinterpret_cast<const TypeTagForDatatypeData *>(this + 1);
+    return *reinterpret_cast<const TypeTagForDatatypeData*>(getArgsBuffer()
+                                                            + NumArgs);
   }
 
+  /// The type buffer immediately follows the object and are mutually exclusive
+  /// with arguments.
   ParsedType &getTypeBuffer() {
     return *reinterpret_cast<ParsedType *>(this + 1);
   }
@@ -161,6 +187,8 @@ private:
     return *reinterpret_cast<const ParsedType *>(this + 1);
   }
 
+  /// The property data immediately follows the object is is mutually exclusive
+  /// with arguments.
   PropertyData &getPropertyDataBuffer() {
     assert(IsProperty);
     return *reinterpret_cast<PropertyData*>(this + 1);
@@ -181,36 +209,34 @@ private:
   /// Constructor for attributes with expression arguments.
   AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
                 IdentifierInfo *scopeName, SourceLocation scopeLoc,
-                IdentifierInfo *parmName, SourceLocation parmLoc,
-                Expr **args, unsigned numArgs,
+                ArgsUnion *args, unsigned numArgs,
                 Syntax syntaxUsed, SourceLocation ellipsisLoc)
-    : AttrName(attrName), ScopeName(scopeName), ParmName(parmName),
-      AttrRange(attrRange), ScopeLoc(scopeLoc), ParmLoc(parmLoc),
-      EllipsisLoc(ellipsisLoc), NumArgs(numArgs), SyntaxUsed(syntaxUsed),
-      Invalid(false), UsedAsTypeAttr(false), IsAvailability(false),
-      IsTypeTagForDatatype(false), IsProperty(false), NextInPosition(0),
-      NextInPool(0) {
-    if (numArgs) memcpy(getArgsBuffer(), args, numArgs * sizeof(Expr*));
+    : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
+      ScopeLoc(scopeLoc), EllipsisLoc(ellipsisLoc), NumArgs(numArgs),
+      SyntaxUsed(syntaxUsed), Invalid(false), UsedAsTypeAttr(false),
+      IsAvailability(false), IsTypeTagForDatatype(false), IsProperty(false),
+      HasParsedType(false), NextInPosition(0), NextInPool(0) {
+    if (numArgs) memcpy(getArgsBuffer(), args, numArgs * sizeof(ArgsUnion));
     AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
   }
 
   /// Constructor for availability attributes.
   AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
                 IdentifierInfo *scopeName, SourceLocation scopeLoc,
-                IdentifierInfo *parmName, SourceLocation parmLoc,
-                const AvailabilityChange &introduced,
+                IdentifierLoc *Parm, const AvailabilityChange &introduced,
                 const AvailabilityChange &deprecated,
                 const AvailabilityChange &obsoleted,
                 SourceLocation unavailable, 
                 const Expr *messageExpr,
                 Syntax syntaxUsed)
-    : AttrName(attrName), ScopeName(scopeName), ParmName(parmName),
-      AttrRange(attrRange), ScopeLoc(scopeLoc), ParmLoc(parmLoc), EllipsisLoc(),
-      NumArgs(0), SyntaxUsed(syntaxUsed),
+    : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
+      ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(1), SyntaxUsed(syntaxUsed),
       Invalid(false), UsedAsTypeAttr(false), IsAvailability(true),
-      IsTypeTagForDatatype(false), IsProperty(false),
+      IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(false),
       UnavailableLoc(unavailable), MessageExpr(messageExpr),
       NextInPosition(0), NextInPool(0) {
+    ArgsUnion PVal(Parm);
+    memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion));
     new (&getAvailabilitySlot(IntroducedSlot)) AvailabilityChange(introduced);
     new (&getAvailabilitySlot(DeprecatedSlot)) AvailabilityChange(deprecated);
     new (&getAvailabilitySlot(ObsoletedSlot)) AvailabilityChange(obsoleted);
@@ -220,16 +246,15 @@ private:
   /// Constructor for type_tag_for_datatype attribute.
   AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
                 IdentifierInfo *scopeName, SourceLocation scopeLoc,
-                IdentifierInfo *argumentKindName,
-                SourceLocation argumentKindLoc,
-                ParsedType matchingCType, bool layoutCompatible,
-                bool mustBeNull, Syntax syntaxUsed)
-    : AttrName(attrName), ScopeName(scopeName), ParmName(argumentKindName),
-      AttrRange(attrRange), ScopeLoc(scopeLoc), ParmLoc(argumentKindLoc),
-      EllipsisLoc(), NumArgs(0), SyntaxUsed(syntaxUsed),
+                IdentifierLoc *ArgKind, ParsedType matchingCType,
+                bool layoutCompatible, bool mustBeNull, Syntax syntaxUsed)
+    : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
+      ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(1), SyntaxUsed(syntaxUsed),
       Invalid(false), UsedAsTypeAttr(false), IsAvailability(false),
-      IsTypeTagForDatatype(true), IsProperty(false), NextInPosition(NULL),
-      NextInPool(NULL) {
+      IsTypeTagForDatatype(true), IsProperty(false), HasParsedType(false),
+      NextInPosition(NULL), NextInPool(NULL) {
+    ArgsUnion PVal(ArgKind);
+    memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion));
     TypeTagForDatatypeData &ExtraData = getTypeTagForDatatypeDataSlot();
     new (&ExtraData.MatchingCType) ParsedType(matchingCType);
     ExtraData.LayoutCompatible = layoutCompatible;
@@ -240,14 +265,12 @@ private:
   /// Constructor for attributes with a single type argument.
   AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
                 IdentifierInfo *scopeName, SourceLocation scopeLoc,
-                IdentifierInfo *parmName, SourceLocation parmLoc,
                 ParsedType typeArg, Syntax syntaxUsed)
-      : AttrName(attrName), ScopeName(scopeName), ParmName(parmName),
-        AttrRange(attrRange), ScopeLoc(scopeLoc), ParmLoc(parmLoc),
-        EllipsisLoc(), NumArgs(1), SyntaxUsed(syntaxUsed), Invalid(false),
-        UsedAsTypeAttr(false), IsAvailability(false),
-        IsTypeTagForDatatype(false), IsProperty(false), NextInPosition(0),
-        NextInPool(0) {
+      : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
+        ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(0), SyntaxUsed(syntaxUsed),
+        Invalid(false), UsedAsTypeAttr(false), IsAvailability(false),
+        IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(true),
+        NextInPosition(0), NextInPool(0) {
     new (&getTypeBuffer()) ParsedType(typeArg);
     AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
   }
@@ -255,15 +278,13 @@ private:
   /// Constructor for microsoft __declspec(property) attribute.
   AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
                 IdentifierInfo *scopeName, SourceLocation scopeLoc,
-                IdentifierInfo *parmName, SourceLocation parmLoc,
                 IdentifierInfo *getterId, IdentifierInfo *setterId,
                 Syntax syntaxUsed)
-    : AttrName(attrName), ScopeName(scopeName), ParmName(parmName),
-      AttrRange(attrRange), ScopeLoc(scopeLoc), ParmLoc(parmLoc),
-      SyntaxUsed(syntaxUsed),
+    : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
+      ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(0), SyntaxUsed(syntaxUsed),
       Invalid(false), UsedAsTypeAttr(false), IsAvailability(false),
-      IsTypeTagForDatatype(false), IsProperty(true), NextInPosition(0),
-      NextInPool(0) {
+      IsTypeTagForDatatype(false), IsProperty(true), HasParsedType(false),
+      NextInPosition(0), NextInPool(0) {
     new (&getPropertyDataBuffer()) PropertyData(getterId, setterId);
     AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
   }
@@ -288,8 +309,7 @@ public:
   IdentifierInfo *getScopeName() const { return ScopeName; }
   SourceLocation getScopeLoc() const { return ScopeLoc; }
   
-  IdentifierInfo *getParameterName() const { return ParmName; }
-  SourceLocation getParameterLoc() const { return ParmLoc; }
+  bool hasParsedType() const { return HasParsedType; }
 
   /// Is this the Microsoft __declspec(property) attribute?
   bool isDeclspecPropertyAttribute() const  {
@@ -326,21 +346,31 @@ public:
   /// getNumArgs - Return the number of actual arguments to this attribute.
   unsigned getNumArgs() const { return NumArgs; }
 
-  /// hasParameterOrArguments - Return true if this attribute has a parameter,
-  /// or has a non empty argument expression list.
-  bool hasParameterOrArguments() const { return ParmName || NumArgs; }
-
   /// getArg - Return the specified argument.
-  Expr *getArg(unsigned Arg) const {
+  ArgsUnion getArg(unsigned Arg) const {
     assert(Arg < NumArgs && "Arg access out of range!");
     return getArgsBuffer()[Arg];
   }
 
+  bool isArgExpr(unsigned Arg) const {
+    return Arg < NumArgs && getArg(Arg).is<Expr*>();
+  }
+  Expr *getArgAsExpr(unsigned Arg) const {
+    return getArg(Arg).get<Expr*>();
+  }
+
+  bool isArgIdent(unsigned Arg) const {
+    return Arg < NumArgs && getArg(Arg).is<IdentifierLoc*>();
+  }
+  IdentifierLoc *getArgAsIdent(unsigned Arg) const {
+    return getArg(Arg).get<IdentifierLoc*>();
+  }
+
   class arg_iterator {
-    Expr * const *X;
+    ArgsUnion const *X;
     unsigned Idx;
   public:
-    arg_iterator(Expr * const *x, unsigned idx) : X(x), Idx(idx) {}
+    arg_iterator(ArgsUnion const *x, unsigned idx) : X(x), Idx(idx) {}
 
     arg_iterator& operator++() {
       ++Idx;
@@ -357,7 +387,7 @@ public:
       return !operator==(I);
     }
 
-    Expr* operator*() const {
+    ArgsUnion operator*() const {
       return X[Idx];
     }
 
@@ -445,11 +475,13 @@ public:
     /// which we want to ensure is a multiple of sizeof(void*).
     AvailabilityAllocSize =
       sizeof(AttributeList)
-      + ((3 * sizeof(AvailabilityChange) + sizeof(void*) - 1)
+      + ((3 * sizeof(AvailabilityChange) + sizeof(void*) +
+         sizeof(ArgsUnion) - 1)
          / sizeof(void*) * sizeof(void*)),
     TypeTagForDatatypeAllocSize =
       sizeof(AttributeList)
-      + (sizeof(AttributeList::TypeTagForDatatypeData) + sizeof(void *) - 1)
+      + (sizeof(AttributeList::TypeTagForDatatypeData) + sizeof(void *) +
+         sizeof(ArgsUnion) - 1)
         / sizeof(void*) * sizeof(void*),
     PropertyAllocSize =
       sizeof(AttributeList)
@@ -541,22 +573,20 @@ public:
 
   AttributeList *create(IdentifierInfo *attrName, SourceRange attrRange,
                         IdentifierInfo *scopeName, SourceLocation scopeLoc,
-                        IdentifierInfo *parmName, SourceLocation parmLoc,
-                        Expr **args, unsigned numArgs,
+                        ArgsUnion *args, unsigned numArgs,
                         AttributeList::Syntax syntax,
                         SourceLocation ellipsisLoc = SourceLocation()) {
     void *memory = allocate(sizeof(AttributeList)
-                            + numArgs * sizeof(Expr*));
+                            + numArgs * sizeof(ArgsUnion));
     return add(new (memory) AttributeList(attrName, attrRange,
                                           scopeName, scopeLoc,
-                                          parmName, parmLoc,
                                           args, numArgs, syntax,
                                           ellipsisLoc));
   }
 
   AttributeList *create(IdentifierInfo *attrName, SourceRange attrRange,
                         IdentifierInfo *scopeName, SourceLocation scopeLoc,
-                        IdentifierInfo *parmName, SourceLocation parmLoc,
+                        IdentifierLoc *Param,
                         const AvailabilityChange &introduced,
                         const AvailabilityChange &deprecated,
                         const AvailabilityChange &obsoleted,
@@ -566,9 +596,9 @@ public:
     void *memory = allocate(AttributeFactory::AvailabilityAllocSize);
     return add(new (memory) AttributeList(attrName, attrRange,
                                           scopeName, scopeLoc,
-                                          parmName, parmLoc,
-                                          introduced, deprecated, obsoleted,
-                                          unavailable, MessageExpr, syntax));
+                                          Param, introduced, deprecated,
+                                          obsoleted, unavailable, MessageExpr,
+                                          syntax));
   }
 
   AttributeList *createIntegerAttribute(ASTContext &C, IdentifierInfo *Name,
@@ -577,40 +607,35 @@ public:
   AttributeList *createTypeTagForDatatype(
                     IdentifierInfo *attrName, SourceRange attrRange,
                     IdentifierInfo *scopeName, SourceLocation scopeLoc,
-                    IdentifierInfo *argumentKindName,
-                    SourceLocation argumentKindLoc,
-                    ParsedType matchingCType, bool layoutCompatible,
-                    bool mustBeNull, AttributeList::Syntax syntax) {
+                    IdentifierLoc *argumentKind, ParsedType matchingCType,
+                    bool layoutCompatible, bool mustBeNull,
+                    AttributeList::Syntax syntax) {
     void *memory = allocate(AttributeFactory::TypeTagForDatatypeAllocSize);
     return add(new (memory) AttributeList(attrName, attrRange,
                                           scopeName, scopeLoc,
-                                          argumentKindName, argumentKindLoc,
-                                          matchingCType, layoutCompatible,
-                                          mustBeNull, syntax));
+                                          argumentKind, matchingCType,
+                                          layoutCompatible, mustBeNull,
+                                          syntax));
   }
 
   AttributeList *createTypeAttribute(
                     IdentifierInfo *attrName, SourceRange attrRange,
                     IdentifierInfo *scopeName, SourceLocation scopeLoc,
-                    IdentifierInfo *parmName, SourceLocation parmLoc,
                     ParsedType typeArg, AttributeList::Syntax syntaxUsed) {
     void *memory = allocate(sizeof(AttributeList) + sizeof(void *));
     return add(new (memory) AttributeList(attrName, attrRange,
                                           scopeName, scopeLoc,
-                                          parmName, parmLoc,
                                           typeArg, syntaxUsed));
   }
 
   AttributeList *createPropertyAttribute(
                     IdentifierInfo *attrName, SourceRange attrRange,
                     IdentifierInfo *scopeName, SourceLocation scopeLoc,
-                    IdentifierInfo *parmName, SourceLocation parmLoc,
                     IdentifierInfo *getterId, IdentifierInfo *setterId,
                     AttributeList::Syntax syntaxUsed) {
     void *memory = allocate(AttributeFactory::PropertyAllocSize);
     return add(new (memory) AttributeList(attrName, attrRange,
                                           scopeName, scopeLoc,
-                                          parmName, parmLoc,
                                           getterId, setterId,
                                           syntaxUsed));
   }
@@ -709,13 +734,12 @@ public:
   /// Add attribute with expression arguments.
   AttributeList *addNew(IdentifierInfo *attrName, SourceRange attrRange,
                         IdentifierInfo *scopeName, SourceLocation scopeLoc,
-                        IdentifierInfo *parmName, SourceLocation parmLoc,
-                        Expr **args, unsigned numArgs,
+                        ArgsUnion *args, unsigned numArgs,
                         AttributeList::Syntax syntax,
                         SourceLocation ellipsisLoc = SourceLocation()) {
     AttributeList *attr =
-      pool.create(attrName, attrRange, scopeName, scopeLoc, parmName, parmLoc,
-                  args, numArgs, syntax, ellipsisLoc);
+      pool.create(attrName, attrRange, scopeName, scopeLoc, args, numArgs,
+                  syntax, ellipsisLoc);
     add(attr);
     return attr;
   }
@@ -723,7 +747,7 @@ public:
   /// Add availability attribute.
   AttributeList *addNew(IdentifierInfo *attrName, SourceRange attrRange,
                         IdentifierInfo *scopeName, SourceLocation scopeLoc,
-                        IdentifierInfo *parmName, SourceLocation parmLoc,
+                        IdentifierLoc *Param,
                         const AvailabilityChange &introduced,
                         const AvailabilityChange &deprecated,
                         const AvailabilityChange &obsoleted,
@@ -731,9 +755,8 @@ public:
                         const Expr *MessageExpr,
                         AttributeList::Syntax syntax) {
     AttributeList *attr =
-      pool.create(attrName, attrRange, scopeName, scopeLoc, parmName, parmLoc,
-                  introduced, deprecated, obsoleted, unavailable,
-                  MessageExpr, syntax);
+      pool.create(attrName, attrRange, scopeName, scopeLoc, Param, introduced,
+                  deprecated, obsoleted, unavailable, MessageExpr, syntax);
     add(attr);
     return attr;
   }
@@ -742,16 +765,14 @@ public:
   AttributeList *addNewTypeTagForDatatype(
                         IdentifierInfo *attrName, SourceRange attrRange,
                         IdentifierInfo *scopeName, SourceLocation scopeLoc,
-                        IdentifierInfo *argumentKindName,
-                        SourceLocation argumentKindLoc,
-                        ParsedType matchingCType, bool layoutCompatible,
-                        bool mustBeNull, AttributeList::Syntax syntax) {
+                        IdentifierLoc *argumentKind, ParsedType matchingCType,
+                        bool layoutCompatible, bool mustBeNull,
+                        AttributeList::Syntax syntax) {
     AttributeList *attr =
       pool.createTypeTagForDatatype(attrName, attrRange,
                                     scopeName, scopeLoc,
-                                    argumentKindName, argumentKindLoc,
-                                    matchingCType, layoutCompatible,
-                                    mustBeNull, syntax);
+                                    argumentKind, matchingCType,
+                                    layoutCompatible, mustBeNull, syntax);
     add(attr);
     return attr;
   }
@@ -760,11 +781,10 @@ public:
   AttributeList *
   addNewTypeAttr(IdentifierInfo *attrName, SourceRange attrRange,
                  IdentifierInfo *scopeName, SourceLocation scopeLoc,
-                 IdentifierInfo *parmName, SourceLocation parmLoc,
                  ParsedType typeArg, AttributeList::Syntax syntaxUsed) {
     AttributeList *attr =
         pool.createTypeAttribute(attrName, attrRange, scopeName, scopeLoc,
-                                 parmName, parmLoc, typeArg, syntaxUsed);
+                                 typeArg, syntaxUsed);
     add(attr);
     return attr;
   }
@@ -773,13 +793,11 @@ public:
   AttributeList *
   addNewPropertyAttr(IdentifierInfo *attrName, SourceRange attrRange,
                  IdentifierInfo *scopeName, SourceLocation scopeLoc,
-                 IdentifierInfo *parmName, SourceLocation parmLoc,
                  IdentifierInfo *getterId, IdentifierInfo *setterId,
                  AttributeList::Syntax syntaxUsed) {
     AttributeList *attr =
         pool.createPropertyAttribute(attrName, attrRange, scopeName, scopeLoc,
-                                     parmName, parmLoc, getterId, setterId,
-                                     syntaxUsed);
+                                     getterId, setterId, syntaxUsed);
     add(attr);
     return attr;
   }

Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=189711&r1=189710&r2=189711&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Fri Aug 30 20:11:41 2013
@@ -164,8 +164,8 @@ void Parser::ParseGNUAttributes(ParsedAt
                                 0, SourceLocation(), AttributeList::AS_GNU);
         }
       } else {
-        attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc,
-                     0, SourceLocation(), 0, 0, AttributeList::AS_GNU);
+        attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, 0,
+                     AttributeList::AS_GNU);
       }
     }
     if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen))
@@ -217,9 +217,8 @@ void Parser::ParseGNUAttributeArgs(Ident
 
   ConsumeParen(); // ignore the left paren loc for now
 
-  IdentifierInfo *ParmName = 0;
-  SourceLocation ParmLoc;
   bool BuiltinType = false;
+  ArgsVector ArgExprs;
 
   TypeResult T;
   SourceRange TypeRange;
@@ -248,7 +247,7 @@ void Parser::ParseGNUAttributeArgs(Ident
     TypeParsed = true;
     break;
 
-  case tok::identifier:
+  case tok::identifier: {
     if (AttrName->isStr("vec_type_hint")) {
       T = ParseTypeName(&TypeRange);
       TypeParsed = true;
@@ -258,22 +257,24 @@ void Parser::ParseGNUAttributeArgs(Ident
     // break out to handle it below.
     if (attributeHasExprArgs(*AttrName))
       break;
-    ParmName = Tok.getIdentifierInfo();
-    ParmLoc = ConsumeToken();
-    break;
+
+    IdentifierLoc *Param = ::new (Actions.Context) IdentifierLoc;
+    Param->Ident = Tok.getIdentifierInfo();
+    Param->Loc = ConsumeToken();
+    ArgExprs.push_back(Param);
+  } break;
 
   default:
     break;
   }
 
-  ExprVector ArgExprs;
   bool isInvalid = false;
   bool isParmType = false;
 
   if (!BuiltinType && !AttrName->isStr("vec_type_hint") &&
-      (ParmLoc.isValid() ? Tok.is(tok::comma) : Tok.isNot(tok::r_paren))) {
+      (!ArgExprs.empty() ? Tok.is(tok::comma) : Tok.isNot(tok::r_paren))) {
     // Eat the comma.
-    if (ParmLoc.isValid())
+    if (!ArgExprs.empty())
       ConsumeToken();
 
     // Parse the non-empty comma-separated list of expressions.
@@ -322,11 +323,11 @@ void Parser::ParseGNUAttributeArgs(Ident
     SourceLocation AttrLoc = ScopeLoc.isValid() ? ScopeLoc : AttrNameLoc;
     if (isParmType) {
       Attrs.addNewTypeAttr(AttrName, SourceRange(AttrLoc, RParen), ScopeName,
-                           ScopeLoc, ParmName, ParmLoc, T.get(), Syntax);
+                           ScopeLoc, T.get(), Syntax);
     } else {
       AttributeList *attr = Attrs.addNew(
-          AttrName, SourceRange(AttrLoc, RParen), ScopeName, ScopeLoc, ParmName,
-          ParmLoc, ArgExprs.data(), ArgExprs.size(), Syntax);
+          AttrName, SourceRange(AttrLoc, RParen), ScopeName, ScopeLoc,
+          ArgExprs.data(), ArgExprs.size(), Syntax);
       if (BuiltinType &&
           attr->getKind() == AttributeList::AT_IBOutletCollection)
         Diag(Tok, diag::err_iboutletcollection_builtintype);
@@ -350,9 +351,9 @@ void Parser::ParseMicrosoftDeclSpecWithS
     T.skipToEnd();
     return;
   }
-  Expr *ExprList = ArgExpr.take();
-  Attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, SourceLocation(),
-               &ExprList, 1, AttributeList::AS_Declspec);
+  ArgsUnion ExprList = ArgExpr.take();
+  Attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, &ExprList, 1,
+               AttributeList::AS_Declspec);
 
   T.consumeClose();
 }
@@ -400,8 +401,7 @@ void Parser::ParseComplexMicrosoftDeclSp
     if (Tok.getKind() == tok::l_paren)
       ParseMicrosoftDeclSpecWithSingleArg(Ident, Loc, Attrs);
     else
-      Attrs.addNew(Ident, Loc, 0, Loc, 0, SourceLocation(), 0, 0,
-                   AttributeList::AS_Declspec);
+      Attrs.addNew(Ident, Loc, 0, Loc, 0, 0, AttributeList::AS_Declspec);
   } else if (Ident->getName() == "property") {
     // The property declspec is more complex in that it can take one or two
     // assignment expressions as a parameter, but the lhs of the assignment
@@ -514,8 +514,7 @@ void Parser::ParseComplexMicrosoftDeclSp
 
     // Only add the property attribute if it was well-formed.
     if (!HasInvalidAccessor) {
-      Attrs.addNewPropertyAttr(Ident, Loc, 0, SourceLocation(), 0,
-                               SourceLocation(),
+      Attrs.addNewPropertyAttr(Ident, Loc, 0, SourceLocation(),
                                AccessorNames[AK_Get], AccessorNames[AK_Put],
                                AttributeList::AS_Declspec);
     }
@@ -589,8 +588,8 @@ void Parser::ParseMicrosoftDeclSpec(Pars
       //
       // Alternatively, if the identifier is a simple one, then it requires no
       // arguments and can be turned into an attribute directly.
-      Attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, SourceLocation(),
-                   0, 0, AttributeList::AS_Declspec);
+      Attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, 0,
+                   AttributeList::AS_Declspec);
     else
       ParseComplexMicrosoftDeclSpec(AttrName, AttrNameLoc, Attrs);
   }
@@ -606,8 +605,8 @@ void Parser::ParseMicrosoftTypeAttribute
          Tok.is(tok::kw___sptr) || Tok.is(tok::kw___uptr)) {
     IdentifierInfo *AttrName = Tok.getIdentifierInfo();
     SourceLocation AttrNameLoc = ConsumeToken();
-    attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0,
-                 SourceLocation(), 0, 0, AttributeList::AS_Keyword);
+    attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, 0,
+                 AttributeList::AS_Keyword);
   }
 }
 
@@ -616,8 +615,8 @@ void Parser::ParseBorlandTypeAttributes(
   while (Tok.is(tok::kw___pascal)) {
     IdentifierInfo *AttrName = Tok.getIdentifierInfo();
     SourceLocation AttrNameLoc = ConsumeToken();
-    attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0,
-                 SourceLocation(), 0, 0, AttributeList::AS_Keyword);
+    attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, 0,
+                 AttributeList::AS_Keyword);
   }
 }
 
@@ -626,8 +625,8 @@ void Parser::ParseOpenCLAttributes(Parse
   while (Tok.is(tok::kw___kernel)) {
     IdentifierInfo *AttrName = Tok.getIdentifierInfo();
     SourceLocation AttrNameLoc = ConsumeToken();
-    attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0,
-                 SourceLocation(), 0, 0, AttributeList::AS_Keyword);
+    attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, 0,
+                 AttributeList::AS_Keyword);
   }
 }
 
@@ -811,9 +810,6 @@ void Parser::ParseAvailabilityAttribute(
                                         SourceLocation AvailabilityLoc,
                                         ParsedAttributes &attrs,
                                         SourceLocation *endLoc) {
-  SourceLocation PlatformLoc;
-  IdentifierInfo *Platform = 0;
-
   enum { Introduced, Deprecated, Obsoleted, Unknown };
   AvailabilityChange Changes[Unknown];
   ExprResult MessageExpr;
@@ -831,8 +827,10 @@ void Parser::ParseAvailabilityAttribute(
     SkipUntil(tok::r_paren);
     return;
   }
-  Platform = Tok.getIdentifierInfo();
-  PlatformLoc = ConsumeToken();
+
+  IdentifierLoc *Platform = new (Actions.Context) IdentifierLoc;
+  Platform->Ident = Tok.getIdentifierInfo();
+  Platform->Loc = ConsumeToken();
 
   // Parse the ',' following the platform name.
   if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "", tok::r_paren))
@@ -961,7 +959,7 @@ void Parser::ParseAvailabilityAttribute(
   attrs.addNew(&Availability,
                SourceRange(AvailabilityLoc, T.getCloseLocation()),
                0, AvailabilityLoc,
-               Platform, PlatformLoc,
+               Platform,
                Changes[Introduced],
                Changes[Deprecated],
                Changes[Obsoleted],
@@ -1162,7 +1160,7 @@ void Parser::ParseThreadSafetyAttribute(
   BalancedDelimiterTracker T(*this, tok::l_paren);
   T.consumeOpen();
 
-  ExprVector ArgExprs;
+  ArgsVector ArgExprs;
   bool ArgExprsOk = true;
 
   // now parse the list of expressions
@@ -1182,8 +1180,8 @@ void Parser::ParseThreadSafetyAttribute(
   }
   // Match the ')'.
   if (ArgExprsOk && !T.consumeClose()) {
-    Attrs.addNew(&AttrName, AttrNameLoc, 0, AttrNameLoc, 0, SourceLocation(),
-                 ArgExprs.data(), ArgExprs.size(), AttributeList::AS_GNU);
+    Attrs.addNew(&AttrName, AttrNameLoc, 0, AttrNameLoc, ArgExprs.data(),
+                 ArgExprs.size(), AttributeList::AS_GNU);
   }
   if (EndLoc)
     *EndLoc = T.getCloseLocation();
@@ -1203,8 +1201,9 @@ void Parser::ParseTypeTagForDatatypeAttr
     T.skipToEnd();
     return;
   }
-  IdentifierInfo *ArgumentKind = Tok.getIdentifierInfo();
-  SourceLocation ArgumentKindLoc = ConsumeToken();
+  IdentifierLoc *ArgumentKind = new (Actions.Context) IdentifierLoc;
+  ArgumentKind->Ident = Tok.getIdentifierInfo();
+  ArgumentKind->Loc = ConsumeToken();
 
   if (Tok.isNot(tok::comma)) {
     Diag(Tok, diag::err_expected_comma);
@@ -1244,9 +1243,9 @@ void Parser::ParseTypeTagForDatatypeAttr
 
   if (!T.consumeClose()) {
     Attrs.addNewTypeTagForDatatype(&AttrName, AttrNameLoc, 0, AttrNameLoc,
-                                   ArgumentKind, ArgumentKindLoc,
-                                   MatchingCType.release(), LayoutCompatible,
-                                   MustBeNull, AttributeList::AS_GNU);
+                                   ArgumentKind, MatchingCType.release(),
+                                   LayoutCompatible, MustBeNull,
+                                   AttributeList::AS_GNU);
   }
 
   if (EndLoc)
@@ -2312,10 +2311,10 @@ void Parser::ParseAlignmentSpecifier(Par
   if (EndLoc)
     *EndLoc = T.getCloseLocation();
 
-  ExprVector ArgExprs;
+  ArgsVector ArgExprs;
   ArgExprs.push_back(ArgExpr.release());
-  Attrs.addNew(KWName, KWLoc, 0, KWLoc, 0, T.getOpenLocation(),
-               ArgExprs.data(), 1, AttributeList::AS_Keyword, EllipsisLoc);
+  Attrs.addNew(KWName, KWLoc, 0, KWLoc, ArgExprs.data(), 1,
+               AttributeList::AS_Keyword, EllipsisLoc);
 }
 
 /// ParseDeclarationSpecifiers
@@ -2740,8 +2739,8 @@ void Parser::ParseDeclarationSpecifiers(
       SourceLocation AttrNameLoc = Tok.getLocation();
       // FIXME: This does not work correctly if it is set to be a declspec
       //        attribute, and a GNU attribute is simply incorrect.
-      DS.getAttributes().addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0,
-                                SourceLocation(), 0, 0, AttributeList::AS_GNU);
+      DS.getAttributes().addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, 0,
+                                AttributeList::AS_GNU);
       break;
     }
 

Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=189711&r1=189710&r2=189711&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Fri Aug 30 20:11:41 2013
@@ -987,8 +987,8 @@ void Parser::ParseMicrosoftInheritanceCl
          Tok.is(tok::kw___virtual_inheritance)) {
     IdentifierInfo *AttrName = Tok.getIdentifierInfo();
     SourceLocation AttrNameLoc = ConsumeToken();
-    attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0,
-                 SourceLocation(), 0, 0, AttributeList::AS_GNU);
+    attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, 0,
+                 AttributeList::AS_GNU);
   }
 }
 
@@ -3245,8 +3245,7 @@ void Parser::ParseCXX11AttributeSpecifie
       attrs.addNew(AttrName,
                    SourceRange(ScopeLoc.isValid() ? ScopeLoc : AttrLoc,
                                AttrLoc),
-                   ScopeName, ScopeLoc, 0,
-                   SourceLocation(), 0, 0, AttributeList::AS_CXX11);
+                   ScopeName, ScopeLoc, 0, 0, AttributeList::AS_CXX11);
 
     if (Tok.is(tok::ellipsis)) {
       ConsumeToken();

Modified: cfe/trunk/lib/Sema/AttributeList.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/AttributeList.cpp?rev=189711&r1=189710&r2=189711&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/AttributeList.cpp (original)
+++ cfe/trunk/lib/Sema/AttributeList.cpp Fri Aug 30 20:11:41 2013
@@ -25,7 +25,7 @@ size_t AttributeList::allocated_size() c
     return AttributeFactory::TypeTagForDatatypeAllocSize;
   else if (IsProperty)
     return AttributeFactory::PropertyAllocSize;
-  return (sizeof(AttributeList) + NumArgs * sizeof(Expr*));
+  return (sizeof(AttributeList) + NumArgs * sizeof(ArgsUnion));
 }
 
 AttributeFactory::AttributeFactory() {
@@ -98,10 +98,9 @@ void AttributePool::takePool(AttributeLi
 AttributeList *
 AttributePool::createIntegerAttribute(ASTContext &C, IdentifierInfo *Name,
                                       SourceLocation TokLoc, int Arg) {
-  Expr *IArg = IntegerLiteral::Create(C, llvm::APInt(32, (uint64_t) Arg),
+  ArgsUnion IArg = IntegerLiteral::Create(C, llvm::APInt(32, (uint64_t) Arg),
                                       C.IntTy, TokLoc);
-  return create(Name, TokLoc, 0, TokLoc, 0, TokLoc, &IArg, 1,
-                AttributeList::AS_GNU);
+  return create(Name, TokLoc, 0, TokLoc, &IArg, 1, AttributeList::AS_GNU);
 }
 
 #include "clang/Sema/AttrParsedAttrKinds.inc"

Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=189711&r1=189710&r2=189711&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Fri Aug 30 20:11:41 2013
@@ -419,7 +419,7 @@ static void checkAttrArgsAreLockableObjs
                                          int Sidx = 0,
                                          bool ParamIdxOk = false) {
   for(unsigned Idx = Sidx; Idx < Attr.getNumArgs(); ++Idx) {
-    Expr *ArgExp = Attr.getArg(Idx);
+    Expr *ArgExp = Attr.getArgAsExpr(Idx);
 
     if (ArgExp->isTypeDependent()) {
       // FIXME -- need to check this again on template instantiation
@@ -815,7 +815,7 @@ static bool checkTryLockFunAttrCommon(Se
     return false;
   }
 
-  if (!isIntOrBool(Attr.getArg(0))) {
+  if (!isIntOrBool(Attr.getArgAsExpr(0))) {
     S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
       << Attr.getName() << 1 << AANT_ArgumentIntOrBool;
     return false;
@@ -833,11 +833,10 @@ static void handleSharedTrylockFunctionA
   if (!checkTryLockFunAttrCommon(S, D, Attr, Args))
     return;
 
-  unsigned Size = Args.size();
-  Expr **StartArg = Size == 0 ? 0 : &Args[0];
   D->addAttr(::new (S.Context)
              SharedTrylockFunctionAttr(Attr.getRange(), S.Context,
-                                       Attr.getArg(0), StartArg, Size,
+                                       Attr.getArgAsExpr(0),
+                                       Args.data(), Args.size(),
                                        Attr.getAttributeSpellingListIndex()));
 }
 
@@ -847,11 +846,10 @@ static void handleExclusiveTrylockFuncti
   if (!checkTryLockFunAttrCommon(S, D, Attr, Args))
     return;
 
-  unsigned Size = Args.size();
-  Expr **StartArg = Size == 0 ? 0 : &Args[0];
   D->addAttr(::new (S.Context)
              ExclusiveTrylockFunctionAttr(Attr.getRange(), S.Context,
-                                          Attr.getArg(0), StartArg, Size,
+                                          Attr.getArgAsExpr(0),
+                                          Args.data(), Args.size(),
                                           Attr.getAttributeSpellingListIndex()));
 }
 
@@ -1177,7 +1175,7 @@ static void handleIBOutletCollection(Sem
                                      const AttributeList &Attr) {
 
   // The iboutletcollection attribute can have zero or one arguments.
-  if (Attr.getParameterName() && Attr.getNumArgs() > 0) {
+  if (Attr.getNumArgs() > 1) {
     S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
       << Attr.getName() << 1;
     return;
@@ -1186,9 +1184,15 @@ static void handleIBOutletCollection(Sem
   if (!checkIBOutletCommon(S, D, Attr))
     return;
 
-  IdentifierInfo *II = Attr.getParameterName();
-  if (!II)
+  IdentifierLoc *IL = Attr.isArgIdent(0) ? Attr.getArgAsIdent(0) : 0;
+  IdentifierInfo *II;
+  SourceLocation ILS;
+  if (IL) {
+    II = IL->Ident;
+    ILS = IL->Loc;
+  } else {
     II = &S.Context.Idents.get("NSObject");
+  }
   
   ParsedType TypeRep = S.getTypeName(*II, Attr.getLoc(), 
                         S.getScopeForContext(D->getDeclContext()->getParent()));
@@ -1206,8 +1210,7 @@ static void handleIBOutletCollection(Sem
     return;
   }
   D->addAttr(::new (S.Context)
-             IBOutletCollectionAttr(Attr.getRange(),S.Context,
-                                    QT, Attr.getParameterLoc(),
+             IBOutletCollectionAttr(Attr.getRange(), S.Context, QT, ILS,
                                     Attr.getAttributeSpellingListIndex()));
 }
 
@@ -1238,7 +1241,7 @@ static void handleAllocSizeAttr(Sema &S,
 
   SmallVector<unsigned, 8> SizeArgs;
   for (unsigned i = 0; i < Attr.getNumArgs(); ++i) {
-    Expr *Ex = Attr.getArg(i);
+    Expr *Ex = Attr.getArgAsExpr(i);
     uint64_t Idx;
     if (!checkFunctionOrMethodArgumentIndex(S, D, Attr.getName()->getName(),
                                             Attr.getLoc(), i + 1, Ex, Idx))
@@ -1278,7 +1281,7 @@ static void handleNonNullAttr(Sema &S, D
 
   SmallVector<unsigned, 8> NonNullArgs;
   for (unsigned i = 0; i < Attr.getNumArgs(); ++i) {
-    Expr *Ex = Attr.getArg(i);
+    Expr *Ex = Attr.getArgAsExpr(i);
     uint64_t Idx;
     if (!checkFunctionOrMethodArgumentIndex(S, D, Attr.getName()->getName(),
                                             Attr.getLoc(), i + 1, Ex, Idx))
@@ -1336,7 +1339,7 @@ static void handleOwnershipAttr(Sema &S,
   // after being held.  free() should be __attribute((ownership_takes)), whereas
   // a list append function may well be __attribute((ownership_holds)).
 
-  if (!AL.getParameterName()) {
+  if (!AL.isArgIdent(0)) {
     S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
       << AL.getName()->getName() << 1 << AANT_ArgumentString;
     return;
@@ -1346,7 +1349,7 @@ static void handleOwnershipAttr(Sema &S,
   switch (AL.getKind()) {
   case AttributeList::AT_ownership_takes:
     K = OwnershipAttr::Takes;
-    if (AL.getNumArgs() < 1) {
+    if (AL.getNumArgs() < 2) {
       S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments)
         << AL.getName() << 2;
       return;
@@ -1354,7 +1357,7 @@ static void handleOwnershipAttr(Sema &S,
     break;
   case AttributeList::AT_ownership_holds:
     K = OwnershipAttr::Holds;
-    if (AL.getNumArgs() < 1) {
+    if (AL.getNumArgs() < 2) {
       S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments)
         << AL.getName() << 2;
       return;
@@ -1362,9 +1365,9 @@ static void handleOwnershipAttr(Sema &S,
     break;
   case AttributeList::AT_ownership_returns:
     K = OwnershipAttr::Returns;
-    if (AL.getNumArgs() > 1) {
+    if (AL.getNumArgs() > 2) {
       S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments)
-        << AL.getName() << AL.getNumArgs() + 1;
+        << AL.getName() << AL.getNumArgs() + 2;
       return;
     }
     break;
@@ -1379,7 +1382,7 @@ static void handleOwnershipAttr(Sema &S,
     return;
   }
 
-  StringRef Module = AL.getParameterName()->getName();
+  StringRef Module = AL.getArgAsIdent(0)->Ident->getName();
 
   // Normalize the argument, __foo__ becomes foo.
   if (Module.startswith("__") && Module.endswith("__"))
@@ -1387,11 +1390,11 @@ static void handleOwnershipAttr(Sema &S,
 
 
   SmallVector<unsigned, 8> OwnershipArgs;
-  for (unsigned i = 0; i < AL.getNumArgs(); ++i) {
-    Expr *Ex = AL.getArg(i);
+  for (unsigned i = 1; i < AL.getNumArgs(); ++i) {
+    Expr *Ex = AL.getArgAsExpr(i);
     uint64_t Idx;
     if (!checkFunctionOrMethodArgumentIndex(S, D, AL.getName()->getName(),
-                                            AL.getLoc(), i + 1, Ex, Idx))
+                                            AL.getLoc(), i, Ex, Idx))
       return;
 
     switch (K) {
@@ -1410,9 +1413,9 @@ static void handleOwnershipAttr(Sema &S,
       break;
     }
     case OwnershipAttr::Returns: {
-      if (AL.getNumArgs() > 1) {
+      if (AL.getNumArgs() > 2) {
           // Is the function argument an integer type?
-          Expr *IdxExpr = AL.getArg(0);
+          Expr *IdxExpr = AL.getArgAsExpr(1);
           llvm::APSInt ArgNum(32);
           if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent()
               || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) {
@@ -1514,8 +1517,8 @@ static void handleWeakRefAttr(Sema &S, D
   // static ((alias ("y"), weakref)).
   // Should we? How to check that weakref is before or after alias?
 
-  if (Attr.getNumArgs() == 1) {
-    Expr *Arg = Attr.getArg(0);
+  if (Attr.isArgExpr(0)) {
+    Expr *Arg = Attr.getArgAsExpr(0);
     Arg = Arg->IgnoreParenCasts();
     StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
 
@@ -1540,9 +1543,9 @@ static void handleAliasAttr(Sema &S, Dec
   if (!checkAttributeNumArgs(S, Attr, 1))
     return;
 
-  Expr *Arg = Attr.getArg(0);
-  Arg = Arg->IgnoreParenCasts();
-  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
+  StringLiteral *Str = 0;
+  if (Attr.isArgExpr(0))
+    Str = dyn_cast<StringLiteral>(Attr.getArgAsExpr(0)->IgnoreParenCasts());
 
   if (!Str || !Str->isAscii()) {
     S.Diag(Attr.getLoc(), diag::err_attribute_argument_type)
@@ -1639,11 +1642,8 @@ static void handleNakedAttr(Sema &S, Dec
 static void handleAlwaysInlineAttr(Sema &S, Decl *D,
                                    const AttributeList &Attr) {
   // Check the attribute arguments.
-  if (Attr.hasParameterOrArguments()) {
-    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
-      << Attr.getName() << 0;
+  if (!checkAttributeNumArgs(S, Attr, 0))
     return;
-  }
 
   if (!isa<FunctionDecl>(D)) {
     S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
@@ -1662,7 +1662,7 @@ static void handleTLSModelAttr(Sema &S,
   if (!checkAttributeNumArgs(S, Attr, 1))
     return;
 
-  Expr *Arg = Attr.getArg(0);
+  Expr *Arg = Attr.getArgAsExpr(0);
   Arg = Arg->IgnoreParenCasts();
   StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
 
@@ -1694,11 +1694,8 @@ static void handleTLSModelAttr(Sema &S,
 
 static void handleMallocAttr(Sema &S, Decl *D, const AttributeList &Attr) {
   // Check the attribute arguments.
-  if (Attr.hasParameterOrArguments()) {
-    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
-      << Attr.getName() << 0;
+  if (!checkAttributeNumArgs(S, Attr, 0))
     return;
-  }
 
   if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
     QualType RetTy = FD->getResultType();
@@ -1765,9 +1762,7 @@ static void handleNoReturnAttr(Sema &S,
 }
 
 bool Sema::CheckNoReturnAttr(const AttributeList &attr) {
-  if (attr.hasParameterOrArguments()) {
-    Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments)
-      << attr.getName() << 0;
+  if (!checkAttributeNumArgs(*this, attr, 0)) {
     attr.setInvalid();
     return true;
   }
@@ -1904,11 +1899,8 @@ static void handleDependencyAttr(Sema &S
 
 static void handleUnusedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
   // check the attribute arguments.
-  if (Attr.hasParameterOrArguments()) {
-    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
-      << Attr.getName() << 0;
+  if (!checkAttributeNumArgs(S, Attr, 0))
     return;
-  }
 
   if (!isa<VarDecl>(D) && !isa<ObjCIvarDecl>(D) && !isFunctionOrMethod(D) &&
       !isa<TypeDecl>(D) && !isa<LabelDecl>(D) && !isa<FieldDecl>(D)) {
@@ -1925,11 +1917,8 @@ static void handleUnusedAttr(Sema &S, De
 static void handleReturnsTwiceAttr(Sema &S, Decl *D,
                                    const AttributeList &Attr) {
   // check the attribute arguments.
-  if (Attr.hasParameterOrArguments()) {
-    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
-      << Attr.getName() << 0;
+  if (!checkAttributeNumArgs(S, Attr, 0))
     return;
-  }
 
   if (!isa<FunctionDecl>(D)) {
     S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
@@ -1944,11 +1933,8 @@ static void handleReturnsTwiceAttr(Sema
 
 static void handleUsedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
   // check the attribute arguments.
-  if (Attr.hasParameterOrArguments()) {
-    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
-      << Attr.getName() << 0;
+  if (!checkAttributeNumArgs(S, Attr, 0))
     return;
-  }
 
   if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
     if (VD->hasLocalStorage()) {
@@ -1975,7 +1961,7 @@ static void handleConstructorAttr(Sema &
 
   int priority = 65535; // FIXME: Do not hardcode such constants.
   if (Attr.getNumArgs() > 0) {
-    Expr *E = Attr.getArg(0);
+    Expr *E = Attr.getArgAsExpr(0);
     llvm::APSInt Idx(32);
     if (E->isTypeDependent() || E->isValueDependent() ||
         !E->isIntegerConstantExpr(Idx, S.Context)) {
@@ -2007,7 +1993,7 @@ static void handleDestructorAttr(Sema &S
 
   int priority = 65535; // FIXME: Do not hardcode such constants.
   if (Attr.getNumArgs() > 0) {
-    Expr *E = Attr.getArg(0);
+    Expr *E = Attr.getArgAsExpr(0);
     llvm::APSInt Idx(32);
     if (E->isTypeDependent() || E->isValueDependent() ||
         !E->isIntegerConstantExpr(Idx, S.Context)) {
@@ -2041,11 +2027,12 @@ static void handleAttrWithMessage(Sema &
 
   // Handle the case where the attribute has a text message.
   StringRef Str;
-  if (NumArgs == 1) {
-    StringLiteral *SE = dyn_cast<StringLiteral>(Attr.getArg(0));
+  if (Attr.isArgExpr(0)) {
+    StringLiteral *SE = dyn_cast<StringLiteral>(Attr.getArgAsExpr(0));
     if (!SE) {
-      S.Diag(Attr.getArg(0)->getLocStart(), diag::err_attribute_argument_type)
-        << Attr.getName() << AANT_ArgumentString;
+      S.Diag(Attr.getArgAsExpr(0)->getLocStart(),
+             diag::err_attribute_argument_type) << Attr.getName()
+        << AANT_ArgumentString;
       return;
     }
     Str = SE->getString();
@@ -2280,13 +2267,15 @@ AvailabilityAttr *Sema::mergeAvailabilit
 
 static void handleAvailabilityAttr(Sema &S, Decl *D,
                                    const AttributeList &Attr) {
-  IdentifierInfo *Platform = Attr.getParameterName();
-  SourceLocation PlatformLoc = Attr.getParameterLoc();
+  if (!checkAttributeNumArgs(S, Attr, 1))
+    return;
+  IdentifierLoc *Platform = Attr.getArgAsIdent(0);
   unsigned Index = Attr.getAttributeSpellingListIndex();
   
-  if (AvailabilityAttr::getPrettyPlatformName(Platform->getName()).empty())
-    S.Diag(PlatformLoc, diag::warn_availability_unknown_platform)
-      << Platform;
+  IdentifierInfo *II = Platform->Ident;
+  if (AvailabilityAttr::getPrettyPlatformName(II->getName()).empty())
+    S.Diag(Platform->Loc, diag::warn_availability_unknown_platform)
+      << Platform->Ident;
 
   NamedDecl *ND = dyn_cast<NamedDecl>(D);
   if (!ND) {
@@ -2304,8 +2293,7 @@ static void handleAvailabilityAttr(Sema
   if (SE)
     Str = SE->getString();
 
-  AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(ND, Attr.getRange(),
-                                                      Platform,
+  AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(ND, Attr.getRange(), II,
                                                       Introduced.Version,
                                                       Deprecated.Version,
                                                       Obsoleted.Version,
@@ -2369,7 +2357,7 @@ static void handleVisibilityAttr(Sema &S
   if (!checkAttributeNumArgs(S, Attr, 1))
     return;
 
-  Expr *Arg = Attr.getArg(0);
+  Expr *Arg = Attr.getArgAsExpr(0);
   Arg = Arg->IgnoreParenCasts();
   StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
 
@@ -2424,19 +2412,18 @@ static void handleObjCMethodFamilyAttr(S
     return;
   }
 
-  if (Attr.getNumArgs() != 0 || !Attr.getParameterName()) {
-    if (!Attr.getParameterName() && Attr.getNumArgs() == 1) {
-      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
-        << Attr.getName() << 1 << AANT_ArgumentString;
-    } else {
-      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
-        << Attr.getName() << 0;
-    }
-    Attr.setInvalid();
+  if (!Attr.isArgIdent(0)) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
+      << Attr.getName() << 1 << AANT_ArgumentIdentifier;
     return;
   }
+  
+  if (!checkAttributeNumArgs(S, Attr, 1))
+    return;
+
+  IdentifierLoc *IL = Attr.getArgAsIdent(0);
 
-  StringRef param = Attr.getParameterName()->getName();
+  StringRef param = IL->Ident->getName();
   ObjCMethodFamilyAttr::FamilyKind family;
   if (param == "none")
     family = ObjCMethodFamilyAttr::OMF_None;
@@ -2453,7 +2440,7 @@ static void handleObjCMethodFamilyAttr(S
   else {
     // Just warn and ignore it.  This is future-proof against new
     // families being used in system headers.
-    S.Diag(Attr.getParameterLoc(), diag::warn_unknown_method_family);
+    S.Diag(IL->Loc, diag::warn_unknown_method_family);
     return;
   }
 
@@ -2533,24 +2520,22 @@ handleOverloadableAttr(Sema &S, Decl *D,
 }
 
 static void handleBlocksAttr(Sema &S, Decl *D, const AttributeList &Attr) {
-  if (!Attr.getParameterName()) {
+  if (!Attr.isArgIdent(0)) {
     S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
-      << Attr.getName() << 1 << AANT_ArgumentString;
+      << Attr.getName() << 1 << AANT_ArgumentIdentifier;
     return;
   }
-
-  if (Attr.getNumArgs() != 0) {
-    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
-      << Attr.getName() << 1;
+  
+  if (!checkAttributeNumArgs(S, Attr, 1))
     return;
-  }
 
+  IdentifierInfo *II = Attr.getArgAsIdent(0)->Ident;
   BlocksAttr::BlockType type;
-  if (Attr.getParameterName()->isStr("byref"))
+  if (II->isStr("byref"))
     type = BlocksAttr::ByRef;
   else {
-    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
-      << "blocks" << Attr.getParameterName();
+    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) << "blocks"
+      << II;
     return;
   }
 
@@ -2568,7 +2553,7 @@ static void handleSentinelAttr(Sema &S,
 
   unsigned sentinel = 0;
   if (Attr.getNumArgs() > 0) {
-    Expr *E = Attr.getArg(0);
+    Expr *E = Attr.getArgAsExpr(0);
     llvm::APSInt Idx(32);
     if (E->isTypeDependent() || E->isValueDependent() ||
         !E->isIntegerConstantExpr(Idx, S.Context)) {
@@ -2589,7 +2574,7 @@ static void handleSentinelAttr(Sema &S,
 
   unsigned nullPos = 0;
   if (Attr.getNumArgs() > 1) {
-    Expr *E = Attr.getArg(1);
+    Expr *E = Attr.getArgAsExpr(1);
     llvm::APSInt Idx(32);
     if (E->isTypeDependent() || E->isValueDependent() ||
         !E->isIntegerConstantExpr(Idx, S.Context)) {
@@ -2696,11 +2681,8 @@ static void handleWarnUnusedResult(Sema
 
 static void handleWeakAttr(Sema &S, Decl *D, const AttributeList &Attr) {
   // check the attribute arguments.
-  if (Attr.hasParameterOrArguments()) {
-    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
-      << Attr.getName() << 0;
+  if (!checkAttributeNumArgs(S, Attr, 0))
     return;
-  }
 
   if (!isa<VarDecl>(D) && !isa<FunctionDecl>(D)) {
     if (isa<CXXRecordDecl>(D)) {
@@ -2758,7 +2740,7 @@ static void handleWorkGroupSize(Sema &S,
 
   unsigned WGSize[3];
   for (unsigned i = 0; i < 3; ++i) {
-    Expr *E = Attr.getArg(i);
+    Expr *E = Attr.getArgAsExpr(i);
     llvm::APSInt ArgNum(32);
     if (E->isTypeDependent() || E->isValueDependent() ||
         !E->isIntegerConstantExpr(ArgNum, S.Context)) {
@@ -2807,9 +2789,14 @@ static void handleWorkGroupSize(Sema &S,
 static void handleVecTypeHint(Sema &S, Decl *D, const AttributeList &Attr) {
   assert(Attr.getKind() == AttributeList::AT_VecTypeHint);
 
-  // Attribute has 1 argument.
-  if (!checkAttributeNumArgs(S, Attr, 1))
+  if (!checkAttributeNumArgs(S, Attr, 0))
+    return;
+
+  if (!Attr.hasParsedType()) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
+      << Attr.getName() << 1;
     return;
+  }
 
   QualType ParmType = S.GetTypeFromParser(Attr.getTypeArg());
 
@@ -2835,10 +2822,19 @@ static void handleVecTypeHint(Sema &S, D
 }
 
 static void handleEndianAttr(Sema &S, Decl *D, const AttributeList &Attr) {
+  if (!Attr.isArgIdent(0)) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
+     << Attr.getName() << 1 << AANT_ArgumentIdentifier;
+    return;
+  }
+  
+  if (!checkAttributeNumArgs(S, Attr, 1))
+    return;
+
   if (!dyn_cast<VarDecl>(D))
-    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) << "endian"
-                                                                << 9;
-  StringRef EndianType = Attr.getParameterName()->getName();
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedVariable;
+  StringRef EndianType = Attr.getArgAsIdent(0)->Ident->getName();
   if (EndianType != "host" && EndianType != "device")
     S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_endian) << EndianType;
 }
@@ -2864,7 +2860,7 @@ static void handleSectionAttr(Sema &S, D
 
   // Make sure that there is a string literal as the sections's single
   // argument.
-  Expr *ArgExpr = Attr.getArg(0);
+  Expr *ArgExpr = Attr.getArgAsExpr(0);
   StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr);
   if (!SE) {
     S.Diag(ArgExpr->getLocStart(), diag::err_attribute_argument_type)
@@ -2895,12 +2891,8 @@ static void handleSectionAttr(Sema &S, D
 
 
 static void handleNothrowAttr(Sema &S, Decl *D, const AttributeList &Attr) {
-  // check the attribute arguments.
-  if (Attr.hasParameterOrArguments()) {
-    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
-      << Attr.getName() << 0;
+  if (!checkAttributeNumArgs(S, Attr, 0))
     return;
-  }
   
   if (NoThrowAttr *Existing = D->getAttr<NoThrowAttr>()) {
     if (Existing->getLocation().isInvalid())
@@ -2913,12 +2905,8 @@ static void handleNothrowAttr(Sema &S, D
 }
 
 static void handleConstAttr(Sema &S, Decl *D, const AttributeList &Attr) {
-  // check the attribute arguments.
-  if (Attr.hasParameterOrArguments()) {
-    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
-      << Attr.getName() << 0;
+  if (!checkAttributeNumArgs(S, Attr, 0))
     return;
-  }
 
   if (ConstAttr *Existing = D->getAttr<ConstAttr>()) {
    if (Existing->getLocation().isInvalid())
@@ -2941,17 +2929,14 @@ static void handlePureAttr(Sema &S, Decl
 }
 
 static void handleCleanupAttr(Sema &S, Decl *D, const AttributeList &Attr) {
-  if (!Attr.getParameterName()) {
+  if (!Attr.isArgIdent(0)) {
     S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
       << Attr.getName() << 1;
     return;
   }
-
-  if (Attr.getNumArgs() != 0) {
-    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
-      << Attr.getName() << 1;
+  
+  if (!checkAttributeNumArgs(S, Attr, 1))
     return;
-  }
 
   VarDecl *VD = dyn_cast<VarDecl>(D);
 
@@ -2960,29 +2945,27 @@ static void handleCleanupAttr(Sema &S, D
     return;
   }
 
+  IdentifierLoc *IL = Attr.getArgAsIdent(0);
+
   // Look up the function
   // FIXME: Lookup probably isn't looking in the right place
   NamedDecl *CleanupDecl
-    = S.LookupSingleName(S.TUScope, Attr.getParameterName(),
-                         Attr.getParameterLoc(), Sema::LookupOrdinaryName);
+    = S.LookupSingleName(S.TUScope, IL->Ident, IL->Loc,
+                         Sema::LookupOrdinaryName);
   if (!CleanupDecl) {
-    S.Diag(Attr.getParameterLoc(), diag::err_attribute_cleanup_arg_not_found) <<
-      Attr.getParameterName();
+    S.Diag(IL->Loc, diag::err_attribute_cleanup_arg_not_found) << IL->Ident;
     return;
   }
 
   FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl);
   if (!FD) {
-    S.Diag(Attr.getParameterLoc(),
-           diag::err_attribute_cleanup_arg_not_function)
-      << Attr.getParameterName();
+    S.Diag(IL->Loc, diag::err_attribute_cleanup_arg_not_function) << IL->Ident;
     return;
   }
 
   if (FD->getNumParams() != 1) {
-    S.Diag(Attr.getParameterLoc(),
-           diag::err_attribute_cleanup_func_must_take_one_arg)
-      << Attr.getParameterName();
+    S.Diag(IL->Loc, diag::err_attribute_cleanup_func_must_take_one_arg)
+      << IL->Ident;
     return;
   }
 
@@ -2992,17 +2975,16 @@ static void handleCleanupAttr(Sema &S, D
   QualType ParamTy = FD->getParamDecl(0)->getType();
   if (S.CheckAssignmentConstraints(FD->getParamDecl(0)->getLocation(),
                                    ParamTy, Ty) != Sema::Compatible) {
-    S.Diag(Attr.getParameterLoc(),
-           diag::err_attribute_cleanup_func_arg_incompatible_type) <<
-      Attr.getParameterName() << ParamTy << Ty;
+    S.Diag(IL->Loc, diag::err_attribute_cleanup_func_arg_incompatible_type) <<
+      IL->Ident << ParamTy << Ty;
     return;
   }
 
   D->addAttr(::new (S.Context)
              CleanupAttr(Attr.getRange(), S.Context, FD,
                          Attr.getAttributeSpellingListIndex()));
-  S.MarkFunctionReferenced(Attr.getParameterLoc(), FD);
-  S.DiagnoseUseOfDecl(FD, Attr.getParameterLoc());
+  S.MarkFunctionReferenced(IL->Loc, FD);
+  S.DiagnoseUseOfDecl(FD, IL->Loc);
 }
 
 /// Handle __attribute__((format_arg((idx)))) attribute based on
@@ -3017,7 +2999,7 @@ static void handleFormatArgAttr(Sema &S,
     return;
   }
 
-  Expr *IdxExpr = Attr.getArg(0);
+  Expr *IdxExpr = Attr.getArgAsExpr(0);
   uint64_t ArgIdx;
   if (!checkFunctionOrMethodArgumentIndex(S, D, Attr.getName()->getName(),
                                           Attr.getLoc(), 1, IdxExpr, ArgIdx))
@@ -3114,7 +3096,7 @@ static void handleInitPriorityAttr(Sema
     Attr.setInvalid();
     return;
   }
-  Expr *priorityExpr = Attr.getArg(0);
+  Expr *priorityExpr = Attr.getArgAsExpr(0);
   
   llvm::APSInt priority(32);
   if (priorityExpr->isTypeDependent() || priorityExpr->isValueDependent() ||
@@ -3164,18 +3146,14 @@ FormatAttr *Sema::mergeFormatAttr(Decl *
 /// Handle __attribute__((format(type,idx,firstarg))) attributes based on
 /// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
 static void handleFormatAttr(Sema &S, Decl *D, const AttributeList &Attr) {
-
-  if (!Attr.getParameterName()) {
+  if (!Attr.isArgIdent(0)) {
     S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
-      << Attr.getName() << 1 << AANT_ArgumentString;
+      << Attr.getName() << 1 << AANT_ArgumentIdentifier;
     return;
   }
-
-  if (Attr.getNumArgs() != 2) {
-    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
-      << Attr.getName() << 3;
+  
+  if (!checkAttributeNumArgs(S, Attr, 3))
     return;
-  }
 
   if (!isFunctionOrMethodOrBlock(D) || !hasFunctionProto(D)) {
     S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
@@ -3189,7 +3167,8 @@ static void handleFormatAttr(Sema &S, De
   unsigned NumArgs  = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
   unsigned FirstIdx = 1;
 
-  StringRef Format = Attr.getParameterName()->getName();
+  IdentifierInfo *II = Attr.getArgAsIdent(0)->Ident;
+  StringRef Format = II->getName();
 
   // Normalize the argument, __foo__ becomes foo.
   if (Format.startswith("__") && Format.endswith("__"))
@@ -3203,12 +3182,12 @@ static void handleFormatAttr(Sema &S, De
   
   if (Kind == InvalidFormat) {
     S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
-      << "format" << Attr.getParameterName()->getName();
+      << "format" << II->getName();
     return;
   }
 
   // checks for the 2nd argument
-  Expr *IdxExpr = Attr.getArg(0);
+  Expr *IdxExpr = Attr.getArgAsExpr(1);
   llvm::APSInt Idx(32);
   if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() ||
       !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
@@ -3264,7 +3243,7 @@ static void handleFormatAttr(Sema &S, De
   }
 
   // check the 3rd argument
-  Expr *FirstArgExpr = Attr.getArg(1);
+  Expr *FirstArgExpr = Attr.getArgAsExpr(2);
   llvm::APSInt FirstArg(32);
   if (FirstArgExpr->isTypeDependent() || FirstArgExpr->isValueDependent() ||
       !FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) {
@@ -3381,7 +3360,7 @@ static void handleAnnotateAttr(Sema &S,
   if (!checkAttributeNumArgs(S, Attr, 1))
     return;
 
-  Expr *ArgExpr = Attr.getArg(0);
+  Expr *ArgExpr = Attr.getArgAsExpr(0);
   StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr);
 
   // Make sure that there is a string literal as the annotation's single
@@ -3419,7 +3398,7 @@ static void handleAlignedAttr(Sema &S, D
     return;
   }
 
-  Expr *E = Attr.getArg(0);
+  Expr *E = Attr.getArgAsExpr(0);
   if (Attr.isPackExpansion() && !E->containsUnexpandedParameterPack()) {
     S.Diag(Attr.getEllipsisLoc(),
            diag::err_pack_expansion_without_parameter_packs);
@@ -3576,20 +3555,17 @@ void Sema::CheckAlignasUnderalignment(De
 static void handleModeAttr(Sema &S, Decl *D, const AttributeList &Attr) {
   // This attribute isn't documented, but glibc uses it.  It changes
   // the width of an int or unsigned int to the specified size.
-
-  // Check that there aren't any arguments
-  if (!checkAttributeNumArgs(S, Attr, 0))
-    return;
-
-
-  IdentifierInfo *Name = Attr.getParameterName();
-  if (!Name) {
+  if (!Attr.isArgIdent(0)) {
     S.Diag(Attr.getLoc(), diag::err_attribute_argument_type) << Attr.getName()
       << AANT_ArgumentIdentifier;
     return;
   }
+  
+  if (!checkAttributeNumArgs(S, Attr, 1))
+    return;
 
-  StringRef Str = Attr.getParameterName()->getName();
+  IdentifierInfo *Name = Attr.getArgAsIdent(0)->Ident;
+  StringRef Str = Name->getName();
 
   // Normalize the attribute name, __foo__ becomes foo.
   if (Str.startswith("__") && Str.endswith("__"))
@@ -3808,12 +3784,8 @@ static void handleNoInstrumentFunctionAt
 
 static void handleConstantAttr(Sema &S, Decl *D, const AttributeList &Attr) {
   if (S.LangOpts.CUDA) {
-    // check the attribute arguments.
-    if (Attr.hasParameterOrArguments()) {
-      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
-        << Attr.getName() << 0;
+    if (!checkAttributeNumArgs(S, Attr, 0))
       return;
-    }
 
     if (!isa<VarDecl>(D)) {
       S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
@@ -4041,7 +4013,7 @@ static void handleOpenCLKernelAttr(Sema
 }
 
 static void handleOpenCLImageAccessAttr(Sema &S, Decl *D, const AttributeList &Attr){
-  Expr *E = Attr.getArg(0);
+  Expr *E = Attr.getArgAsExpr(0);
   llvm::APSInt ArgNum(32);
   if (E->isTypeDependent() || E->isValueDependent() ||
       !E->isIntegerConstantExpr(ArgNum, S.Context)) {
@@ -4061,9 +4033,7 @@ bool Sema::CheckCallingConvAttr(const At
     return true;
 
   unsigned ReqArgs = attr.getKind() == AttributeList::AT_Pcs ? 1 : 0;
-  if (attr.getNumArgs() != ReqArgs || attr.getParameterName()) {
-    Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments)
-      << attr.getName() << ReqArgs;
+  if (!checkAttributeNumArgs(*this, attr, ReqArgs)) {
     attr.setInvalid();
     return true;
   }
@@ -4085,8 +4055,10 @@ bool Sema::CheckCallingConvAttr(const At
                                                              CC_C;
     break;
   case AttributeList::AT_Pcs: {
-    Expr *Arg = attr.getArg(0);
-    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
+    StringLiteral *Str = 0;
+    if (attr.isArgExpr(0))
+      Str = dyn_cast<StringLiteral>(attr.getArgAsExpr(0));
+    
     if (!Str || !Str->isAscii()) {
       Diag(attr.getLoc(), diag::err_attribute_argument_type) << attr.getName()
         << AANT_ArgumentString;
@@ -4156,7 +4128,7 @@ bool Sema::CheckRegparmAttr(const Attrib
     return true;
   }
 
-  Expr *NumParamsExpr = Attr.getArg(0);
+  Expr *NumParamsExpr = Attr.getArgAsExpr(0);
   llvm::APSInt NumParams(32);
   if (NumParamsExpr->isTypeDependent() || NumParamsExpr->isValueDependent() ||
       !NumParamsExpr->isIntegerConstantExpr(NumParams, Context)) {
@@ -4200,7 +4172,7 @@ static void handleLaunchBoundsAttr(Sema
       return;
     }
 
-    Expr *MaxThreadsExpr = Attr.getArg(0);
+    Expr *MaxThreadsExpr = Attr.getArgAsExpr(0);
     llvm::APSInt MaxThreads(32);
     if (MaxThreadsExpr->isTypeDependent() ||
         MaxThreadsExpr->isValueDependent() ||
@@ -4213,7 +4185,7 @@ static void handleLaunchBoundsAttr(Sema
 
     llvm::APSInt MinBlocks(32);
     if (Attr.getNumArgs() > 1) {
-      Expr *MinBlocksExpr = Attr.getArg(1);
+      Expr *MinBlocksExpr = Attr.getArgAsExpr(1);
       if (MinBlocksExpr->isTypeDependent() ||
           MinBlocksExpr->isValueDependent() ||
           !MinBlocksExpr->isIntegerConstantExpr(MinBlocks, S.Context)) {
@@ -4236,20 +4208,17 @@ static void handleLaunchBoundsAttr(Sema
 
 static void handleArgumentWithTypeTagAttr(Sema &S, Decl *D,
                                           const AttributeList &Attr) {
-  StringRef AttrName = Attr.getName()->getName();
-  if (!Attr.getParameterName()) {
+  if (!Attr.isArgIdent(0)) {
     S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
       << Attr.getName() << /* arg num = */ 1 << AANT_ArgumentIdentifier;
     return;
   }
-
-  if (Attr.getNumArgs() != 2) {
-    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
-      << Attr.getName() << /* required args = */ 3;
+  
+  if (!checkAttributeNumArgs(S, Attr, 3))
     return;
-  }
 
-  IdentifierInfo *ArgumentKind = Attr.getParameterName();
+  StringRef AttrName = Attr.getName()->getName();
+  IdentifierInfo *ArgumentKind = Attr.getArgAsIdent(0)->Ident;
 
   if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) {
     S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
@@ -4260,13 +4229,13 @@ static void handleArgumentWithTypeTagAtt
   uint64_t ArgumentIdx;
   if (!checkFunctionOrMethodArgumentIndex(S, D, AttrName,
                                           Attr.getLoc(), 2,
-                                          Attr.getArg(0), ArgumentIdx))
+                                          Attr.getArgAsExpr(1), ArgumentIdx))
     return;
 
   uint64_t TypeTagIdx;
   if (!checkFunctionOrMethodArgumentIndex(S, D, AttrName,
                                           Attr.getLoc(), 3,
-                                          Attr.getArg(1), TypeTagIdx))
+                                          Attr.getArgAsExpr(2), TypeTagIdx))
     return;
 
   bool IsPointer = (AttrName == "pointer_with_type_tag");
@@ -4287,13 +4256,16 @@ static void handleArgumentWithTypeTagAtt
 
 static void handleTypeTagForDatatypeAttr(Sema &S, Decl *D,
                                          const AttributeList &Attr) {
-  IdentifierInfo *PointerKind = Attr.getParameterName();
-  if (!PointerKind) {
+  if (!Attr.isArgIdent(0)) {
     S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
       << Attr.getName() << 1 << AANT_ArgumentIdentifier;
     return;
   }
+  
+  if (!checkAttributeNumArgs(S, Attr, 1))
+    return;
 
+  IdentifierInfo *PointerKind = Attr.getArgAsIdent(0)->Ident;
   QualType MatchingCType = S.GetTypeFromParser(Attr.getMatchingCType(), NULL);
 
   D->addAttr(::new (S.Context)
@@ -4544,14 +4516,14 @@ static void handleNSBridgedAttr(Sema &S,
       << Attr.getRange() << Attr.getName() << ExpectedStruct;
   }
 
-  IdentifierInfo *ParmName = Attr.getParameterName();
+  IdentifierLoc *Parm = Attr.isArgIdent(0) ? Attr.getArgAsIdent(0) : 0;
 
   // In Objective-C, verify that the type names an Objective-C type.
   // We don't want to check this outside of ObjC because people sometimes
   // do crazy C declarations of Objective-C types.
-  if (ParmName && S.getLangOpts().ObjC1) {
+  if (Parm && S.getLangOpts().ObjC1) {
     // Check for an existing type with this name.
-    LookupResult R(S, DeclarationName(ParmName), Attr.getParameterLoc(),
+    LookupResult R(S, DeclarationName(Parm->Ident), Parm->Loc,
                    Sema::LookupOrdinaryName);
     if (S.LookupName(R, Sc)) {
       NamedDecl *Target = R.getFoundDecl();
@@ -4563,7 +4535,7 @@ static void handleNSBridgedAttr(Sema &S,
   }
 
   D->addAttr(::new (S.Context)
-             NSBridgedAttr(Attr.getRange(), S.Context, ParmName,
+             NSBridgedAttr(Attr.getRange(), S.Context, Parm ? Parm->Ident : 0,
                            Attr.getAttributeSpellingListIndex()));
 }
 
@@ -4644,7 +4616,7 @@ static void handleUuidAttr(Sema &S, Decl
   if (!checkAttributeNumArgs(S, Attr, 1))
     return;
 
-  Expr *Arg = Attr.getArg(0);
+  Expr *Arg = Attr.getArgAsExpr(0);
   StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
   if (!Str || !Str->isAscii()) {
     S.Diag(Attr.getLoc(), diag::err_attribute_argument_type)

Modified: cfe/trunk/lib/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=189711&r1=189710&r2=189711&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaType.cpp (original)
+++ cfe/trunk/lib/Sema/SemaType.cpp Fri Aug 30 20:11:41 2013
@@ -81,10 +81,11 @@ static void diagnoseBadTypeAttribute(Sem
   StringRef name = attr.getName()->getName();
 
   // The GC attributes are usually written with macros;  special-case them.
-  if (useExpansionLoc && loc.isMacroID() && attr.getParameterName()) {
-    if (attr.getParameterName()->isStr("strong")) {
+  IdentifierInfo *II = attr.isArgIdent(0) ? attr.getArgAsIdent(0)->Ident : 0;
+  if (useExpansionLoc && loc.isMacroID() && II) {
+    if (II->isStr("strong")) {
       if (S.findMacroSpelling(loc, "__strong")) name = "__strong";
-    } else if (attr.getParameterName()->isStr("weak")) {
+    } else if (II->isStr("weak")) {
       if (S.findMacroSpelling(loc, "__weak")) name = "__weak";
     }
   }
@@ -3291,13 +3292,18 @@ static void transferARCOwnershipToDeclar
   case Qualifiers::OCL_Autoreleasing: attrStr = "autoreleasing"; break;
   }
 
+  IdentifierLoc *Arg = new (S.Context) IdentifierLoc;
+  Arg->Ident = &S.Context.Idents.get(attrStr);
+  Arg->Loc = SourceLocation();
+
+  ArgsUnion Args(Arg);
+
   // If there wasn't one, add one (with an invalid source location
   // so that we don't make an AttributedType for it).
   AttributeList *attr = D.getAttributePool()
     .create(&S.Context.Idents.get("objc_ownership"), SourceLocation(),
             /*scope*/ 0, SourceLocation(),
-            &S.Context.Idents.get(attrStr), SourceLocation(),
-            /*args*/ 0, 0, AttributeList::AS_GNU);
+            /*args*/ &Args, 1, AttributeList::AS_GNU);
   spliceAttrIntoList(*attr, chunk.getAttrListRef());
 
   // TODO: mark whether we did this inference?
@@ -3435,10 +3441,10 @@ static void fillAttributedTypeLoc(Attrib
   }
 
   TL.setAttrNameLoc(attrs->getLoc());
-  if (TL.hasAttrExprOperand())
-    TL.setAttrExprOperand(attrs->getArg(0));
-  else if (TL.hasAttrEnumOperand())
-    TL.setAttrEnumOperandLoc(attrs->getParameterLoc());
+  if (TL.hasAttrExprOperand() && attrs->isArgExpr(0))
+    TL.setAttrExprOperand(attrs->getArgAsExpr(0));
+  else if (TL.hasAttrEnumOperand() && attrs->isArgIdent(0))
+    TL.setAttrEnumOperandLoc(attrs->getArgAsIdent(0)->Loc);
 
   // FIXME: preserve this information to here.
   if (TL.hasAttrOperand())
@@ -3902,7 +3908,7 @@ static void HandleAddressSpaceTypeAttrib
     Attr.setInvalid();
     return;
   }
-  Expr *ASArgExpr = static_cast<Expr *>(Attr.getArg(0));
+  Expr *ASArgExpr = static_cast<Expr *>(Attr.getArgAsExpr(0));
   llvm::APSInt addrSpace(32);
   if (ASArgExpr->isTypeDependent() || ASArgExpr->isValueDependent() ||
       !ASArgExpr->isIntegerConstantExpr(addrSpace, S.Context)) {
@@ -4002,7 +4008,7 @@ static bool handleObjCOwnershipTypeAttr(
   if (AttrLoc.isMacroID())
     AttrLoc = S.getSourceManager().getImmediateExpansionRange(AttrLoc).first;
 
-  if (!attr.getParameterName()) {
+  if (!attr.isArgIdent(0)) {
     S.Diag(AttrLoc, diag::err_attribute_argument_type)
       << attr.getName() << AANT_ArgumentString;
     attr.setInvalid();
@@ -4014,18 +4020,19 @@ static bool handleObjCOwnershipTypeAttr(
   if (!S.getLangOpts().ObjCAutoRefCount)
     return true;
 
+  IdentifierInfo *II = attr.getArgAsIdent(0)->Ident;
   Qualifiers::ObjCLifetime lifetime;
-  if (attr.getParameterName()->isStr("none"))
+  if (II->isStr("none"))
     lifetime = Qualifiers::OCL_ExplicitNone;
-  else if (attr.getParameterName()->isStr("strong"))
+  else if (II->isStr("strong"))
     lifetime = Qualifiers::OCL_Strong;
-  else if (attr.getParameterName()->isStr("weak"))
+  else if (II->isStr("weak"))
     lifetime = Qualifiers::OCL_Weak;
-  else if (attr.getParameterName()->isStr("autoreleasing"))
+  else if (II->isStr("autoreleasing"))
     lifetime = Qualifiers::OCL_Autoreleasing;
   else {
     S.Diag(AttrLoc, diag::warn_attribute_type_not_supported)
-      << "objc_ownership" << attr.getParameterName();
+      << "objc_ownership" << II;
     attr.setInvalid();
     return true;
   }
@@ -4136,28 +4143,30 @@ static bool handleObjCGCTypeAttr(TypePro
     attr.setInvalid();
     return true;
   }
-
+  
   // Check the attribute arguments.
-  if (!attr.getParameterName()) {
+  if (!attr.isArgIdent(0)) {
     S.Diag(attr.getLoc(), diag::err_attribute_argument_type)
       << attr.getName() << AANT_ArgumentString;
     attr.setInvalid();
     return true;
   }
   Qualifiers::GC GCAttr;
-  if (attr.getNumArgs() != 0) {
+  if (attr.getNumArgs() > 1) {
     S.Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments)
       << attr.getName() << 1;
     attr.setInvalid();
     return true;
   }
-  if (attr.getParameterName()->isStr("weak"))
+
+  IdentifierInfo *II = attr.getArgAsIdent(0)->Ident;
+  if (II->isStr("weak"))
     GCAttr = Qualifiers::Weak;
-  else if (attr.getParameterName()->isStr("strong"))
+  else if (II->isStr("strong"))
     GCAttr = Qualifiers::Strong;
   else {
     S.Diag(attr.getLoc(), diag::warn_attribute_type_not_supported)
-      << "objc_gc" << attr.getParameterName();
+      << "objc_gc" << II;
     attr.setInvalid();
     return true;
   }
@@ -4383,7 +4392,7 @@ static AttributedType::Kind getCCTypeAtt
     return AttributedType::attr_pascal;
   case AttributeList::AT_Pcs: {
     // We know attr is valid so it can only have one of two strings args.
-    StringLiteral *Str = cast<StringLiteral>(Attr.getArg(0));
+    StringLiteral *Str = cast<StringLiteral>(Attr.getArgAsExpr(0));
     return llvm::StringSwitch<AttributedType::Kind>(Str->getString())
         .Case("aapcs", AttributedType::attr_pcs)
         .Case("aapcs-vfp", AttributedType::attr_pcs_vfp);
@@ -4567,7 +4576,7 @@ static void HandleOpenCLImageAccessAttri
     Attr.setInvalid();
     return;
   }
-  Expr *sizeExpr = static_cast<Expr *>(Attr.getArg(0));
+  Expr *sizeExpr = static_cast<Expr *>(Attr.getArgAsExpr(0));
   llvm::APSInt arg(32);
   if (sizeExpr->isTypeDependent() || sizeExpr->isValueDependent() ||
       !sizeExpr->isIntegerConstantExpr(arg, S.Context)) {
@@ -4609,7 +4618,7 @@ static void HandleVectorSizeAttr(QualTyp
     Attr.setInvalid();
     return;
   }
-  Expr *sizeExpr = static_cast<Expr *>(Attr.getArg(0));
+  Expr *sizeExpr = static_cast<Expr *>(Attr.getArgAsExpr(0));
   llvm::APSInt vecSize(32);
   if (sizeExpr->isTypeDependent() || sizeExpr->isValueDependent() ||
       !sizeExpr->isIntegerConstantExpr(vecSize, S.Context)) {
@@ -4661,14 +4670,21 @@ static void HandleVectorSizeAttr(QualTyp
 static void HandleExtVectorTypeAttr(QualType &CurType,
                                     const AttributeList &Attr,
                                     Sema &S) {
+  // check the attribute arguments.
+  if (Attr.getNumArgs() != 1) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
+      << Attr.getName() << 1;
+    return;
+  }
+
   Expr *sizeExpr;
 
   // Special case where the argument is a template id.
-  if (Attr.getParameterName()) {
+  if (Attr.isArgIdent(0)) {
     CXXScopeSpec SS;
     SourceLocation TemplateKWLoc;
     UnqualifiedId id;
-    id.setIdentifier(Attr.getParameterName(), Attr.getLoc());
+    id.setIdentifier(Attr.getArgAsIdent(0)->Ident, Attr.getLoc());
 
     ExprResult Size = S.ActOnIdExpression(S.getCurScope(), SS, TemplateKWLoc,
                                           id, false, false);
@@ -4677,13 +4693,7 @@ static void HandleExtVectorTypeAttr(Qual
 
     sizeExpr = Size.get();
   } else {
-    // check the attribute arguments.
-    if (Attr.getNumArgs() != 1) {
-      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
-        << Attr.getName() << 1;
-      return;
-    }
-    sizeExpr = Attr.getArg(0);
+    sizeExpr = Attr.getArgAsExpr(0);
   }
 
   // Create the vector type.
@@ -4746,7 +4756,7 @@ static void HandleNeonVectorTypeAttr(Qua
     return;
   }
   // The number of elements must be an ICE.
-  Expr *numEltsExpr = static_cast<Expr *>(Attr.getArg(0));
+  Expr *numEltsExpr = static_cast<Expr *>(Attr.getArgAsExpr(0));
   llvm::APSInt numEltsInt(32);
   if (numEltsExpr->isTypeDependent() || numEltsExpr->isValueDependent() ||
       !numEltsExpr->isIntegerConstantExpr(numEltsInt, S.Context)) {

Modified: cfe/trunk/lib/Sema/TargetAttributesSema.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TargetAttributesSema.cpp?rev=189711&r1=189710&r2=189711&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/TargetAttributesSema.cpp (original)
+++ cfe/trunk/lib/Sema/TargetAttributesSema.cpp Fri Aug 30 20:11:41 2013
@@ -37,7 +37,7 @@ static void HandleMSP430InterruptAttr(De
 
     // FIXME: Check for decl - it should be void ()(void).
 
-    Expr *NumParamsExpr = static_cast<Expr *>(Attr.getArg(0));
+    Expr *NumParamsExpr = static_cast<Expr *>(Attr.getArgAsExpr(0));
     llvm::APSInt NumParams(32);
     if (!NumParamsExpr->isIntegerConstantExpr(NumParams, S.Context)) {
       S.Diag(Attr.getLoc(), diag::err_attribute_argument_type)
@@ -235,7 +235,7 @@ namespace {
 
 static void HandleMips16Attr(Decl *D, const AttributeList &Attr, Sema &S) {
   // check the attribute arguments.
-  if (Attr.hasParameterOrArguments()) {
+  if (Attr.getNumArgs()) {
     S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
       << Attr.getName() << 0;
     return;
@@ -252,7 +252,7 @@ static void HandleMips16Attr(Decl *D, co
 
 static void HandleNoMips16Attr(Decl *D, const AttributeList &Attr, Sema &S) {
   // check the attribute arguments.
-  if (Attr.hasParameterOrArguments()) {
+  if (Attr.getNumArgs()) {
     S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
       << Attr.getName() << 0;
     return;

Added: cfe/trunk/test/Sema/attr-endian.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/attr-endian.c?rev=189711&view=auto
==============================================================================
--- cfe/trunk/test/Sema/attr-endian.c (added)
+++ cfe/trunk/test/Sema/attr-endian.c Fri Aug 30 20:11:41 2013
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only
+
+int p1 __attribute__((endian(host)));
+int p2 __attribute__((endian(device)));
+
+int p3 __attribute__((endian));	// expected-error {{'endian' attribute requires parameter 1 to be an identifier}}
+int p4 __attribute__((endian("host")));	// expected-error {{'endian' attribute requires parameter 1 to be an identifier}}
+int p5 __attribute__((endian(host, 15)));	// expected-error {{'endian' attribute takes one argument}}
+int p6 __attribute__((endian(strange)));	// expected-warning {{unknown endian 'strange'}}
+
+void func(void) __attribute__((endian(host))); // expected-warning {{'endian' attribute only applies to variables}}

Modified: cfe/trunk/test/Sema/callingconv.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/callingconv.c?rev=189711&r1=189710&r2=189711&view=diff
==============================================================================
--- cfe/trunk/test/Sema/callingconv.c (original)
+++ cfe/trunk/test/Sema/callingconv.c Fri Aug 30 20:11:41 2013
@@ -38,7 +38,7 @@ Handler H = foo;
 
 int __attribute__((pcs("aapcs", "aapcs"))) pcs1(void); // expected-error {{'pcs' attribute takes one argument}}
 int __attribute__((pcs())) pcs2(void); // expected-error {{'pcs' attribute takes one argument}}
-int __attribute__((pcs(pcs1))) pcs3(void); // expected-error {{'pcs' attribute takes one argument}}
+int __attribute__((pcs(pcs1))) pcs3(void); // expected-error {{'pcs' attribute requires a string}}
 int __attribute__((pcs(0))) pcs4(void); // expected-error {{'pcs' attribute requires a string}}
 /* These are ignored because the target is i386 and not ARM */
 int __attribute__((pcs("aapcs"))) pcs5(void); // expected-warning {{calling convention 'pcs' ignored for this target}}

Modified: cfe/trunk/test/Sema/warn-type-safety.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/warn-type-safety.c?rev=189711&r1=189710&r2=189711&view=diff
==============================================================================
--- cfe/trunk/test/Sema/warn-type-safety.c (original)
+++ cfe/trunk/test/Sema/warn-type-safety.c Fri Aug 30 20:11:41 2013
@@ -7,7 +7,7 @@ struct A {};
 typedef struct A *MPI_Datatype;
 
 int wrong1(void *buf, MPI_Datatype datatype)
-    __attribute__(( pointer_with_type_tag )); // expected-error {{attribute requires parameter 1 to be an identifier}}
+    __attribute__(( pointer_with_type_tag )); // expected-error {{'pointer_with_type_tag' attribute requires parameter 1 to be an identifier}}
 
 int wrong2(void *buf, MPI_Datatype datatype)
     __attribute__(( pointer_with_type_tag(mpi,0,7) )); // expected-error {{attribute parameter 2 is out of bounds}}
@@ -39,7 +39,7 @@ int wrong10(double buf, MPI_Datatype typ
 
 
 extern struct A datatype_wrong1
-    __attribute__(( type_tag_for_datatype )); // expected-error {{attribute requires parameter 1 to be an identifier}}
+    __attribute__(( type_tag_for_datatype )); // expected-error {{'type_tag_for_datatype' attribute requires parameter 1 to be an identifier}}
 
 extern struct A datatype_wrong2
     __attribute__(( type_tag_for_datatype(mpi,1,2) )); // expected-error {{expected a type}}

Modified: cfe/trunk/test/SemaObjC/arc.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/arc.m?rev=189711&r1=189710&r2=189711&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/arc.m (original)
+++ cfe/trunk/test/SemaObjC/arc.m Fri Aug 30 20:11:41 2013
@@ -87,6 +87,8 @@ void test1(A *a) {
 + (id)alloc;
 - (id)initWithInt: (int) i;
 - (id)myInit __attribute__((objc_method_family(init)));
+- (id)myBadInit __attribute__((objc_method_family(12)));  // expected-error {{'objc_method_family' attribute requires parameter 1 to be an identifier}}
+
 @end
 
 void rdar8861761() {

Modified: cfe/trunk/test/SemaOpenCL/endian-attr.cl
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaOpenCL/endian-attr.cl?rev=189711&r1=189710&r2=189711&view=diff
==============================================================================
--- cfe/trunk/test/SemaOpenCL/endian-attr.cl (original)
+++ cfe/trunk/test/SemaOpenCL/endian-attr.cl Fri Aug 30 20:11:41 2013
@@ -6,4 +6,4 @@ constant long b __attribute__((endian(de
 
 constant long c __attribute__((endian(none))) = 100; // expected-warning {{unknown endian 'none'}}
 
-void func() __attribute__((endian(host))); // expected-warning {{endian attribute only applies to variables}}
+void func() __attribute__((endian(host))); // expected-warning {{'endian' attribute only applies to variables}}





More information about the cfe-commits mailing list