]> granicus.if.org Git - clang/commitdiff
Refactor how we collect attributes during parsing, and add slots for attributes
authorJohn McCall <rjmccall@apple.com>
Fri, 24 Dec 2010 02:08:15 +0000 (02:08 +0000)
committerJohn McCall <rjmccall@apple.com>
Fri, 24 Dec 2010 02:08:15 +0000 (02:08 +0000)
on array and function declarators.  This is pretty far from complete, and I'll
revisit it later if someone doesn't beat me to it.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@122535 91177308-0d34-0410-b5e6-96231b3b80d8

18 files changed:
include/clang/Parse/Parser.h
include/clang/Sema/AttributeList.h
include/clang/Sema/DeclSpec.h
lib/AST/ASTContext.cpp
lib/Parse/ParseDecl.cpp
lib/Parse/ParseDeclCXX.cpp
lib/Parse/ParseExpr.cpp
lib/Parse/ParseExprCXX.cpp
lib/Parse/ParseObjc.cpp
lib/Parse/ParseStmt.cpp
lib/Parse/ParseTemplate.cpp
lib/Parse/ParseTentative.cpp
lib/Parse/Parser.cpp
lib/Sema/AttributeList.cpp
lib/Sema/DeclSpec.cpp
lib/Sema/SemaDecl.cpp
lib/Sema/SemaDeclAttr.cpp
lib/Sema/SemaType.cpp

index 3b6aceb5cd474ef023aaea4076d49d2a9b45044f..db4d1b7a4b77650ec8fb7e002218967ebce7e47e 100644 (file)
@@ -920,14 +920,17 @@ private:
 
   //===--------------------------------------------------------------------===//
   // C99 6.9: External Definitions.
-  DeclGroupPtrTy ParseExternalDeclaration(CXX0XAttributeList Attr,
+  struct ParsedAttributesWithRange : ParsedAttributes {
+    SourceRange Range;
+  };
+
+  DeclGroupPtrTy ParseExternalDeclaration(ParsedAttributesWithRange &attrs,
                                           ParsingDeclSpec *DS = 0);
   bool isDeclarationAfterDeclarator() const;
   bool isStartOfFunctionDefinition(const ParsingDeclarator &Declarator);
-  DeclGroupPtrTy ParseDeclarationOrFunctionDefinition(AttributeList *Attr,
-            AccessSpecifier AS = AS_none);
+  DeclGroupPtrTy ParseDeclarationOrFunctionDefinition(ParsedAttributes &attrs,
+                                                  AccessSpecifier AS = AS_none);
   DeclGroupPtrTy ParseDeclarationOrFunctionDefinition(ParsingDeclSpec &DS,
-                                                  AttributeList *Attr,
                                                   AccessSpecifier AS = AS_none);
   
   Decl *ParseFunctionDefinition(ParsingDeclarator &D,
@@ -942,7 +945,7 @@ private:
   Decl *ParseObjCAtDirectives();
   Decl *ParseObjCAtClassDeclaration(SourceLocation atLoc);
   Decl *ParseObjCAtInterfaceDeclaration(SourceLocation atLoc,
-                                          AttributeList *prefixAttrs = 0);
+                                        ParsedAttributes &prefixAttrs);
   void ParseObjCClassInstanceVariables(Decl *interfaceDecl,
                                        tok::ObjCKeywordKind visibility,
                                        SourceLocation atLoc);
@@ -955,7 +958,7 @@ private:
   void ParseObjCInterfaceDeclList(Decl *interfaceDecl,
                                   tok::ObjCKeywordKind contextKey);
   Decl *ParseObjCAtProtocolDeclaration(SourceLocation atLoc,
-                                           AttributeList *prefixAttrs = 0);
+                                       ParsedAttributes &prefixAttrs);
 
   Decl *ObjCImpDecl;
   llvm::SmallVector<Decl *, 4> PendingObjCImpDecl;
@@ -1189,25 +1192,25 @@ private:
   }
   StmtResult ParseStatementOrDeclaration(StmtVector& Stmts,
                                          bool OnlyStatement = false);
-  StmtResult ParseLabeledStatement(AttributeList *Attr);
-  StmtResult ParseCaseStatement(AttributeList *Attr);
-  StmtResult ParseDefaultStatement(AttributeList *Attr);
-  StmtResult ParseCompoundStatement(AttributeList *Attr,
+  StmtResult ParseLabeledStatement(ParsedAttributes &Attr);
+  StmtResult ParseCaseStatement(ParsedAttributes &Attr);
+  StmtResult ParseDefaultStatement(ParsedAttributes &Attr);
+  StmtResult ParseCompoundStatement(ParsedAttributes &Attr,
                                           bool isStmtExpr = false);
   StmtResult ParseCompoundStatementBody(bool isStmtExpr = false);
   bool ParseParenExprOrCondition(ExprResult &ExprResult,
                                  Decl *&DeclResult,
                                  SourceLocation Loc,
                                  bool ConvertToBoolean);
-  StmtResult ParseIfStatement(AttributeList *Attr);
-  StmtResult ParseSwitchStatement(AttributeList *Attr);
-  StmtResult ParseWhileStatement(AttributeList *Attr);
-  StmtResult ParseDoStatement(AttributeList *Attr);
-  StmtResult ParseForStatement(AttributeList *Attr);
-  StmtResult ParseGotoStatement(AttributeList *Attr);
-  StmtResult ParseContinueStatement(AttributeList *Attr);
-  StmtResult ParseBreakStatement(AttributeList *Attr);
-  StmtResult ParseReturnStatement(AttributeList *Attr);
+  StmtResult ParseIfStatement(ParsedAttributes &Attr);
+  StmtResult ParseSwitchStatement(ParsedAttributes &Attr);
+  StmtResult ParseWhileStatement(ParsedAttributes &Attr);
+  StmtResult ParseDoStatement(ParsedAttributes &Attr);
+  StmtResult ParseForStatement(ParsedAttributes &Attr);
+  StmtResult ParseGotoStatement(ParsedAttributes &Attr);
+  StmtResult ParseContinueStatement(ParsedAttributes &Attr);
+  StmtResult ParseBreakStatement(ParsedAttributes &Attr);
+  StmtResult ParseReturnStatement(ParsedAttributes &Attr);
   StmtResult ParseAsmStatement(bool &msAsm);
   StmtResult FuzzyParseMicrosoftAsmStatement(SourceLocation AsmLoc);
   bool ParseAsmOperandsOpt(llvm::SmallVectorImpl<IdentifierInfo *> &Names,
@@ -1217,7 +1220,7 @@ private:
   //===--------------------------------------------------------------------===//
   // C++ 6: Statements and Blocks
 
-  StmtResult ParseCXXTryBlock(AttributeList *Attr);
+  StmtResult ParseCXXTryBlock(ParsedAttributes &Attr);
   StmtResult ParseCXXTryBlockCommon(SourceLocation TryLoc);
   StmtResult ParseCXXCatchBlock();
 
@@ -1244,11 +1247,11 @@ private:
 
   DeclGroupPtrTy ParseDeclaration(StmtVector &Stmts,
                                   unsigned Context, SourceLocation &DeclEnd,
-                                  CXX0XAttributeList Attr);
+                                  ParsedAttributesWithRange &attrs);
   DeclGroupPtrTy ParseSimpleDeclaration(StmtVector &Stmts,
                                         unsigned Context,
                                         SourceLocation &DeclEnd,
-                                        AttributeList *Attr,
+                                        ParsedAttributes &attrs,
                                         bool RequireSemi);
   DeclGroupPtrTy ParseDeclGroup(ParsingDeclSpec &DS, unsigned Context,
                                 bool AllowFunctionDefinitions,
@@ -1447,14 +1450,64 @@ private:
 
   TypeResult ParseTypeName(SourceRange *Range = 0);
   void ParseBlockId();
-  // EndLoc, if non-NULL, is filled with the location of the last token of
-  // the attribute list.
-  CXX0XAttributeList ParseCXX0XAttributes(SourceLocation *EndLoc = 0);
-  void ParseMicrosoftAttributes();
-  AttributeList *ParseGNUAttributes(SourceLocation *EndLoc = 0);
-  AttributeList *ParseMicrosoftDeclSpec(AttributeList* CurrAttr = 0);
-  AttributeList *ParseMicrosoftTypeAttributes(AttributeList* CurrAttr = 0);
-  AttributeList *ParseBorlandTypeAttributes(AttributeList* CurrAttr = 0);
+
+  void ProhibitAttributes(ParsedAttributesWithRange &attrs) {
+    if (!attrs.Range.isValid()) return;
+    DiagnoseProhibitedAttributes(attrs);
+  }
+  void DiagnoseProhibitedAttributes(ParsedAttributesWithRange &attrs);
+
+  void MaybeParseGNUAttributes(Declarator &D) {
+    if (Tok.is(tok::kw___attribute)) {
+      ParsedAttributes attrs;
+      SourceLocation endLoc;
+      ParseGNUAttributes(attrs, &endLoc);
+      D.addAttributes(attrs.getList(), endLoc);
+    }
+  }
+  void MaybeParseGNUAttributes(ParsedAttributes &attrs,
+                               SourceLocation *endLoc = 0) {
+    if (Tok.is(tok::kw___attribute))
+      ParseGNUAttributes(attrs, endLoc);
+  }
+  void ParseGNUAttributes(ParsedAttributes &attrs,
+                          SourceLocation *endLoc = 0);
+
+  void MaybeParseCXX0XAttributes(Declarator &D) {
+    if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier()) {
+      ParsedAttributesWithRange attrs;
+      SourceLocation endLoc;
+      ParseCXX0XAttributes(attrs, &endLoc);
+      D.addAttributes(attrs.getList(), endLoc);
+    }
+  }
+  void MaybeParseCXX0XAttributes(ParsedAttributes &attrs,
+                                 SourceLocation *endLoc = 0) {
+    if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier()) {
+      ParsedAttributesWithRange attrsWithRange;
+      ParseCXX0XAttributes(attrsWithRange, endLoc);
+      attrs.append(attrsWithRange.getList());
+    }
+  }
+  void MaybeParseCXX0XAttributes(ParsedAttributesWithRange &attrs,
+                                 SourceLocation *endLoc = 0) {
+    if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier())
+      ParseCXX0XAttributes(attrs, endLoc);
+  }
+  void ParseCXX0XAttributes(ParsedAttributesWithRange &attrs,
+                            SourceLocation *EndLoc = 0);
+
+  void MaybeParseMicrosoftAttributes(ParsedAttributes &attrs,
+                                     SourceLocation *endLoc = 0) {
+    if (getLang().Microsoft && Tok.is(tok::l_square))
+      ParseMicrosoftAttributes(attrs, endLoc);
+  }
+  void ParseMicrosoftAttributes(ParsedAttributes &attrs,
+                                SourceLocation *endLoc = 0);
+  void ParseMicrosoftDeclSpec(ParsedAttributes &attrs);
+  void ParseMicrosoftTypeAttributes(ParsedAttributes &attrs);
+  void ParseBorlandTypeAttributes(ParsedAttributes &attrs);
+
   void ParseTypeofSpecifier(DeclSpec &DS);
   void ParseDecltypeSpecifier(DeclSpec &DS);
   
@@ -1499,12 +1552,13 @@ private:
   typedef void (Parser::*DirectDeclParseFunction)(Declarator&);
   void ParseDeclaratorInternal(Declarator &D,
                                DirectDeclParseFunction DirectDeclParser);
+
   void ParseTypeQualifierListOpt(DeclSpec &DS, bool GNUAttributesAllowed = true,
                                  bool CXX0XAttributesAllowed = true);
   void ParseDirectDeclarator(Declarator &D);
   void ParseParenDeclarator(Declarator &D);
   void ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
-                               AttributeList *AttrList = 0,
+                               ParsedAttributes &attrs,
                                bool RequiresArg = false);
   void ParseFunctionDeclaratorIdentifierList(SourceLocation LParenLoc,
                                              IdentifierInfo *FirstIdent,
@@ -1524,10 +1578,11 @@ private:
   Decl *ParseUsingDirectiveOrDeclaration(unsigned Context,
                                          const ParsedTemplateInfo &TemplateInfo,
                                          SourceLocation &DeclEnd,
-                                         CXX0XAttributeList Attrs);
+                                         ParsedAttributesWithRange &attrs);
   Decl *ParseUsingDirective(unsigned Context,
                             SourceLocation UsingLoc,
-                            SourceLocation &DeclEnd, AttributeList *Attr);
+                            SourceLocation &DeclEnd,
+                            ParsedAttributes &attrs);
   Decl *ParseUsingDeclaration(unsigned Context,
                               const ParsedTemplateInfo &TemplateInfo,
                               SourceLocation UsingLoc,
index 69170fa23ce5c0d7f3f4bef6496ec2a94e70f9ff..0dab6669798b71c7539593e15ae1b613f4e4737f 100644 (file)
@@ -56,7 +56,7 @@ private:
                 IdentifierInfo *ScopeName, SourceLocation ScopeLoc,
                 IdentifierInfo *ParmName, SourceLocation ParmLoc,
                 Expr **args, unsigned numargs,
-                AttributeList *Next, bool declspec, bool cxx0x);
+                bool declspec, bool cxx0x);
 public:
   class Factory {
     llvm::BumpPtrAllocator Alloc;
@@ -66,12 +66,11 @@ public:
     AttributeList *Create(IdentifierInfo *AttrName, SourceLocation AttrLoc,
       IdentifierInfo *ScopeName, SourceLocation ScopeLoc,
       IdentifierInfo *ParmName, SourceLocation ParmLoc,
-      Expr **args, unsigned numargs,
-      AttributeList *Next, bool declspec = false, bool cxx0x = false) {
+      Expr **args, unsigned numargs, bool declspec = false, bool cxx0x = false) {
         AttributeList *Mem = Alloc.Allocate<AttributeList>();
         new (Mem) AttributeList(Alloc, AttrName, AttrLoc, ScopeName, ScopeLoc,
                                 ParmName, ParmLoc, args, numargs,
-                                Next, declspec, cxx0x);
+                                declspec, cxx0x);
         return Mem;
       }
   };
@@ -266,6 +265,47 @@ struct CXX0XAttributeList {
   }
 };
 
+/// ParsedAttributes - A collection of parsed attributes.  Currently
+/// we don't differentiate between the various attribute syntaxes,
+/// which is basically silly.
+///
+/// Right now this is a very lightweight container, but the expectation
+/// is that this will become significantly more serious.
+class ParsedAttributes {
+public:
+  ParsedAttributes() : list(0) {}
+
+  bool empty() const { return list == 0; }
+
+  void add(AttributeList *newAttr) {
+    assert(newAttr);
+    assert(newAttr->getNext() == 0);
+    newAttr->setNext(list);
+    list = newAttr;
+  }
+
+  void append(AttributeList *newList) {
+    if (!newList) return;
+
+    AttributeList *lastInNewList = newList;
+    while (AttributeList *next = lastInNewList->getNext())
+      lastInNewList = next;
+
+    lastInNewList->setNext(list);
+    list = newList;
+  }
+
+  void set(AttributeList *newList) {
+    list = newList;
+  }
+
+  void clear() { list = 0; }
+  AttributeList *getList() const { return list; }
+
+private:
+  AttributeList *list;
+};
+
 }  // end namespace clang
 
 #endif
index 3a57657e60db08dc2b196d20bdb8fd1e7ce9ebb6..7cc5b8f7a3aa7efb0a02056a5e6dd8a18fd7309a 100644 (file)
@@ -170,32 +170,32 @@ private:
 
   // storage-class-specifier
   /*SCS*/unsigned StorageClassSpec : 3;
-  bool SCS_thread_specified : 1;
-  bool SCS_extern_in_linkage_spec : 1;
+  unsigned SCS_thread_specified : 1;
+  unsigned SCS_extern_in_linkage_spec : 1;
 
   // type-specifier
   /*TSW*/unsigned TypeSpecWidth : 2;
   /*TSC*/unsigned TypeSpecComplex : 2;
   /*TSS*/unsigned TypeSpecSign : 2;
   /*TST*/unsigned TypeSpecType : 5;
-  bool TypeAltiVecVector : 1;
-  bool TypeAltiVecPixel : 1;
-  bool TypeAltiVecBool : 1;
-  bool TypeSpecOwned : 1;
+  unsigned TypeAltiVecVector : 1;
+  unsigned TypeAltiVecPixel : 1;
+  unsigned TypeAltiVecBool : 1;
+  unsigned TypeSpecOwned : 1;
 
   // type-qualifiers
   unsigned TypeQualifiers : 3;  // Bitwise OR of TQ.
 
   // function-specifier
-  bool FS_inline_specified : 1;
-  bool FS_virtual_specified : 1;
-  bool FS_explicit_specified : 1;
+  unsigned FS_inline_specified : 1;
+  unsigned FS_virtual_specified : 1;
+  unsigned FS_explicit_specified : 1;
 
   // friend-specifier
-  bool Friend_specified : 1;
+  unsigned Friend_specified : 1;
 
   // constexpr-specifier
-  bool Constexpr_specified : 1;
+  unsigned Constexpr_specified : 1;
 
   /*SCS*/unsigned StorageClassSpecAsWritten : 3;
 
@@ -206,7 +206,7 @@ private:
   };
 
   // attributes.
-  AttributeList *AttrList;
+  ParsedAttributes Attrs;
 
   // Scope specifier for the type spec, if applicable.
   CXXScopeSpec TypeScope;
@@ -268,7 +268,6 @@ public:
       Friend_specified(false),
       Constexpr_specified(false),
       StorageClassSpecAsWritten(SCS_unspecified),
-      AttrList(0),
       ProtocolQualifiers(0),
       NumProtocolQualifiers(0),
       ProtocolLocs(0),
@@ -473,19 +472,29 @@ public:
   /// short __attribute__((unused)) __attribute__((deprecated))
   /// int __attribute__((may_alias)) __attribute__((aligned(16))) var;
   ///
-  void AddAttributes(AttributeList *alist) {
-    AttrList = addAttributeLists(AttrList, alist);
+  void addAttributes(AttributeList *AL) {
+    Attrs.append(AL);
   }
-  void SetAttributes(AttributeList *AL) { AttrList = AL; }
-  const AttributeList *getAttributes() const { return AttrList; }
-  AttributeList *getAttributes() { return AttrList; }
+  void aetAttributes(AttributeList *AL) {
+    Attrs.set(AL);
+  }
+
+  bool hasAttributes() const { return !Attrs.empty(); }
+
+  ParsedAttributes &getAttributes() { return Attrs; }
+  const ParsedAttributes &getAttributes() const { return Attrs; }
 
   /// TakeAttributes - Return the current attribute list and remove them from
   /// the DeclSpec so that it doesn't own them.
-  AttributeList *TakeAttributes() {
-    AttributeList *AL = AttrList;
-    AttrList = 0;
-    return AL;
+  ParsedAttributes takeAttributes() {
+    ParsedAttributes saved = Attrs;
+    Attrs.clear();
+    return saved;
+  }
+
+  void takeAttributesFrom(ParsedAttributes &attrs) {
+    Attrs.append(attrs.getList());
+    attrs.clear();
   }
 
   typedef Decl * const *ProtocolQualifierListTy;
@@ -809,25 +818,27 @@ struct DeclaratorChunk {
   /// EndLoc - If valid, the place where this chunck ends.
   SourceLocation EndLoc;
 
-  struct PointerTypeInfo {
+  struct TypeInfoCommon {
+    AttributeList *AttrList;
+  };
+
+  struct PointerTypeInfo : TypeInfoCommon {
     /// The type qualifiers: const/volatile/restrict.
     unsigned TypeQuals : 3;
-    AttributeList *AttrList;
     void destroy() {
     }
   };
 
-  struct ReferenceTypeInfo {
+  struct ReferenceTypeInfo : TypeInfoCommon {
     /// The type qualifier: restrict. [GNU] C++ extension
     bool HasRestrict : 1;
     /// True if this is an lvalue reference, false if it's an rvalue reference.
     bool LValueRef : 1;
-    AttributeList *AttrList;
     void destroy() {
     }
   };
 
-  struct ArrayTypeInfo {
+  struct ArrayTypeInfo : TypeInfoCommon {
     /// The type qualifiers for the array: const/volatile/restrict.
     unsigned TypeQuals : 3;
 
@@ -841,6 +852,7 @@ struct DeclaratorChunk {
     /// Since the parser is multi-purpose, and we don't want to impose a root
     /// expression class on all clients, NumElts is untyped.
     Expr *NumElts;
+
     void destroy() {}
   };
 
@@ -875,29 +887,29 @@ struct DeclaratorChunk {
     SourceRange Range;
   };
 
-  struct FunctionTypeInfo {
+  struct FunctionTypeInfo : TypeInfoCommon {
     /// hasPrototype - This is true if the function had at least one typed
     /// argument.  If the function is () or (a,b,c), then it has no prototype,
     /// and is treated as a K&R-style function.
-    bool hasPrototype : 1;
+    unsigned hasPrototype : 1;
 
     /// isVariadic - If this function has a prototype, and if that
     /// proto ends with ',...)', this is true. When true, EllipsisLoc
     /// contains the location of the ellipsis.
-    bool isVariadic : 1;
+    unsigned isVariadic : 1;
 
     /// The type qualifiers: const/volatile/restrict.
     /// The qualifier bitmask values are the same as in QualType.
     unsigned TypeQuals : 3;
 
     /// hasExceptionSpec - True if the function has an exception specification.
-    bool hasExceptionSpec : 1;
+    unsigned hasExceptionSpec : 1;
 
     /// hasAnyExceptionSpec - True if the function has a throw(...) specifier.
-    bool hasAnyExceptionSpec : 1;
+    unsigned hasAnyExceptionSpec : 1;
 
     /// DeleteArgInfo - If this is true, we need to delete[] ArgInfo.
-    bool DeleteArgInfo : 1;
+    unsigned DeleteArgInfo : 1;
 
     /// When isVariadic is true, the location of the ellipsis in the source.
     unsigned EllipsisLoc;
@@ -960,19 +972,18 @@ struct DeclaratorChunk {
     }
   };
 
-  struct BlockPointerTypeInfo {
+  struct BlockPointerTypeInfo : TypeInfoCommon {
     /// For now, sema will catch these as invalid.
     /// The type qualifiers: const/volatile/restrict.
     unsigned TypeQuals : 3;
-    AttributeList *AttrList;
+
     void destroy() {
     }
   };
 
-  struct MemberPointerTypeInfo {
+  struct MemberPointerTypeInfo : TypeInfoCommon {
     /// The type qualifiers: const/volatile/restrict.
     unsigned TypeQuals : 3;
-    AttributeList *AttrList;
     // CXXScopeSpec has a constructor, so it can't be a direct member.
     // So we need some pointer-aligned storage and a bit of trickery.
     union {
@@ -1019,8 +1030,8 @@ struct DeclaratorChunk {
     case Pointer:       return Ptr.AttrList;
     case Reference:     return Ref.AttrList;
     case MemberPointer: return Mem.AttrList;
-    case Array:         return 0;
-    case Function:      return 0;
+    case Array:         return Arr.AttrList;
+    case Function:      return Fun.AttrList;
     case BlockPointer:  return Cls.AttrList;
     case Paren:         return 0;
     }
@@ -1032,37 +1043,40 @@ struct DeclaratorChunk {
   /// getPointer - Return a DeclaratorChunk for a pointer.
   ///
   static DeclaratorChunk getPointer(unsigned TypeQuals, SourceLocation Loc,
-                                    AttributeList *AL) {
+                                    const ParsedAttributes &attrs) {
     DeclaratorChunk I;
     I.Kind          = Pointer;
     I.Loc           = Loc;
     I.Ptr.TypeQuals = TypeQuals;
-    I.Ptr.AttrList  = AL;
+    I.Ptr.AttrList  = attrs.getList();
     return I;
   }
 
   /// getReference - Return a DeclaratorChunk for a reference.
   ///
   static DeclaratorChunk getReference(unsigned TypeQuals, SourceLocation Loc,
-                                      AttributeList *AL, bool lvalue) {
+                                      const ParsedAttributes &attrs,
+                                      bool lvalue) {
     DeclaratorChunk I;
     I.Kind            = Reference;
     I.Loc             = Loc;
     I.Ref.HasRestrict = (TypeQuals & DeclSpec::TQ_restrict) != 0;
     I.Ref.LValueRef   = lvalue;
-    I.Ref.AttrList  = AL;
+    I.Ref.AttrList    = attrs.getList();
     return I;
   }
 
   /// getArray - Return a DeclaratorChunk for an array.
   ///
-  static DeclaratorChunk getArray(unsigned TypeQuals, bool isStatic,
-                                  bool isStar, Expr *NumElts,
+  static DeclaratorChunk getArray(unsigned TypeQuals,
+                                  const ParsedAttributes &attrs,
+                                  bool isStatic, bool isStar, Expr *NumElts,
                                   SourceLocation LBLoc, SourceLocation RBLoc) {
     DeclaratorChunk I;
     I.Kind          = Array;
     I.Loc           = LBLoc;
     I.EndLoc        = RBLoc;
+    I.Arr.AttrList  = attrs.getList();
     I.Arr.TypeQuals = TypeQuals;
     I.Arr.hasStatic = isStatic;
     I.Arr.isStar    = isStar;
@@ -1072,7 +1086,8 @@ struct DeclaratorChunk {
 
   /// DeclaratorChunk::getFunction - Return a DeclaratorChunk for a function.
   /// "TheDeclarator" is the declarator that this will be added to.
-  static DeclaratorChunk getFunction(bool hasProto, bool isVariadic,
+  static DeclaratorChunk getFunction(const ParsedAttributes &attrs,
+                                     bool hasProto, bool isVariadic,
                                      SourceLocation EllipsisLoc,
                                      ParamInfo *ArgInfo, unsigned NumArgs,
                                      unsigned TypeQuals, bool hasExceptionSpec,
@@ -1088,24 +1103,24 @@ struct DeclaratorChunk {
   /// getBlockPointer - Return a DeclaratorChunk for a block.
   ///
   static DeclaratorChunk getBlockPointer(unsigned TypeQuals, SourceLocation Loc,
-                                         AttributeList *AL) {
+                                         const ParsedAttributes &attrs) {
     DeclaratorChunk I;
     I.Kind          = BlockPointer;
     I.Loc           = Loc;
     I.Cls.TypeQuals = TypeQuals;
-    I.Cls.AttrList  = AL;
+    I.Cls.AttrList  = attrs.getList();
     return I;
   }
 
   static DeclaratorChunk getMemberPointer(const CXXScopeSpec &SS,
                                           unsigned TypeQuals,
                                           SourceLocation Loc,
-                                          AttributeList *AL) {
+                                          const ParsedAttributes &attrs) {
     DeclaratorChunk I;
     I.Kind          = MemberPointer;
     I.Loc           = Loc;
     I.Mem.TypeQuals = TypeQuals;
-    I.Mem.AttrList  = AL;
+    I.Mem.AttrList  = attrs.getList();
     new (I.Mem.ScopeMem.Mem) CXXScopeSpec(SS);
     return I;
   }
@@ -1399,19 +1414,23 @@ public:
   ///                                 __attribute__((common,deprecated));
   ///
   /// Also extends the range of the declarator.
-  void AddAttributes(AttributeList *alist, SourceLocation LastLoc) {
+  void addAttributes(AttributeList *alist, SourceLocation LastLoc) {
     AttrList = addAttributeLists(AttrList, alist);
 
     if (!LastLoc.isInvalid())
       SetRangeEnd(LastLoc);
   }
 
+  void addAttributes(const ParsedAttributes &attrs) {
+    addAttributes(attrs.getList(), SourceLocation());
+  }
+
   const AttributeList *getAttributes() const { return AttrList; }
   AttributeList *getAttributes() { return AttrList; }
 
   /// hasAttributes - do we contain any attributes?
   bool hasAttributes() const {
-    if (getAttributes() || getDeclSpec().getAttributes()) return true;
+    if (getAttributes() || getDeclSpec().hasAttributes()) return true;
     for (unsigned i = 0, e = getNumTypeObjects(); i != e; ++i)
       if (getTypeObject(i).getAttrs())
         return true;
index eaf222cafad80e70b5b2a4e4b584db0bc291291a..b145683ce5e5cc82b52f3381f74d361b7492c621 100644 (file)
@@ -1119,8 +1119,8 @@ QualType ASTContext::getObjCGCQualType(QualType T,
   if (CanT.getObjCGCAttr() == GCAttr)
     return T;
 
-  if (T->isPointerType()) {
-    QualType Pointee = T->getAs<PointerType>()->getPointeeType();
+  if (const PointerType *ptr = T->getAs<PointerType>()) {
+    QualType Pointee = ptr->getPointeeType();
     if (Pointee->isAnyPointerType()) {
       QualType ResultType = getObjCGCQualType(Pointee, GCAttr);
       return getPointerType(ResultType);
index f627b2c9f42e6a78830f054aebb74d8cb1ba3cb1..ab9173ffab0bd96add4f1ce4f1a48473a800d915 100644 (file)
@@ -82,21 +82,20 @@ TypeResult Parser::ParseTypeName(SourceRange *Range) {
 /// attributes are very simple in practice. Until we find a bug, I don't see
 /// a pressing need to implement the 2 token lookahead.
 
-AttributeList *Parser::ParseGNUAttributes(SourceLocation *EndLoc) {
+void Parser::ParseGNUAttributes(ParsedAttributes &attrs,
+                                SourceLocation *endLoc) {
   assert(Tok.is(tok::kw___attribute) && "Not a GNU attribute list!");
 
-  AttributeList *CurrAttr = 0;
-
   while (Tok.is(tok::kw___attribute)) {
     ConsumeToken();
     if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
                          "attribute")) {
       SkipUntil(tok::r_paren, true); // skip until ) or ;
-      return CurrAttr;
+      return;
     }
     if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after, "(")) {
       SkipUntil(tok::r_paren, true); // skip until ) or ;
-      return CurrAttr;
+      return;
     }
     // Parse the attribute-list. e.g. __attribute__(( weak, alias("__f") ))
     while (Tok.is(tok::identifier) || isDeclarationSpecifier() ||
@@ -122,8 +121,8 @@ AttributeList *Parser::ParseGNUAttributes(SourceLocation *EndLoc) {
           if (Tok.is(tok::r_paren)) {
             // __attribute__(( mode(byte) ))
             ConsumeParen(); // ignore the right paren loc for now
-            CurrAttr = AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc,
-                                          ParmName, ParmLoc, 0, 0, CurrAttr);
+            attrs.add(AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc,
+                                         ParmName, ParmLoc, 0, 0));
           } else if (Tok.is(tok::comma)) {
             ConsumeToken();
             // __attribute__(( format(printf, 1, 2) ))
@@ -146,10 +145,9 @@ AttributeList *Parser::ParseGNUAttributes(SourceLocation *EndLoc) {
             }
             if (ArgExprsOk && Tok.is(tok::r_paren)) {
               ConsumeParen(); // ignore the right paren loc for now
-              CurrAttr = AttrFactory.Create(AttrName, AttrNameLoc, 0,
-                                            AttrNameLoc, ParmName, ParmLoc,
-                                            ArgExprs.take(), ArgExprs.size(),
-                                            CurrAttr);
+              attrs.add(AttrFactory.Create(AttrName, AttrNameLoc, 0,
+                                           AttrNameLoc, ParmName, ParmLoc,
+                                           ArgExprs.take(), ArgExprs.size()));
             }
           }
         } else { // not an identifier
@@ -158,8 +156,8 @@ AttributeList *Parser::ParseGNUAttributes(SourceLocation *EndLoc) {
           // parse a possibly empty comma separated list of expressions
             // __attribute__(( nonnull() ))
             ConsumeParen(); // ignore the right paren loc for now
-            CurrAttr = AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc,
-                                          0, SourceLocation(), 0, 0, CurrAttr);
+            attrs.add(AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc,
+                                         0, SourceLocation(), 0, 0));
             break;
           case tok::kw_char:
           case tok::kw_wchar_t:
@@ -174,10 +172,12 @@ AttributeList *Parser::ParseGNUAttributes(SourceLocation *EndLoc) {
           case tok::kw_float:
           case tok::kw_double:
           case tok::kw_void:
-          case tok::kw_typeof:
-            CurrAttr = AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc,
-                                          0, SourceLocation(), 0, 0, CurrAttr);
-            if (CurrAttr->getKind() == AttributeList::AT_IBOutletCollection)
+          case tok::kw_typeof: {
+            AttributeList *attr
+                     = AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc,
+                                          0, SourceLocation(), 0, 0);
+            attrs.add(attr);
+            if (attr->getKind() == AttributeList::AT_IBOutletCollection)
               Diag(Tok, diag::err_iboutletcollection_builtintype);
             // If it's a builtin type name, eat it and expect a rparen
             // __attribute__(( vec_type_hint(char) ))
@@ -185,6 +185,7 @@ AttributeList *Parser::ParseGNUAttributes(SourceLocation *EndLoc) {
             if (Tok.is(tok::r_paren))
               ConsumeParen();
             break;
+          }
           default:
             // __attribute__(( aligned(16) ))
             ExprVector ArgExprs(Actions);
@@ -207,17 +208,16 @@ AttributeList *Parser::ParseGNUAttributes(SourceLocation *EndLoc) {
             // Match the ')'.
             if (ArgExprsOk && Tok.is(tok::r_paren)) {
               ConsumeParen(); // ignore the right paren loc for now
-              CurrAttr = AttrFactory.Create(AttrName, AttrNameLoc, 0,
-                           AttrNameLoc, 0, SourceLocation(), ArgExprs.take(),
-                           ArgExprs.size(),
-                           CurrAttr);
+              attrs.add(AttrFactory.Create(AttrName, AttrNameLoc, 0,
+                                           AttrNameLoc, 0, SourceLocation(),
+                                           ArgExprs.take(), ArgExprs.size()));
             }
             break;
           }
         }
       } else {
-        CurrAttr = AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc,
-                                      0, SourceLocation(), 0, 0, CurrAttr);
+        attrs.add(AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc,
+                                     0, SourceLocation(), 0, 0));
       }
     }
     if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen))
@@ -226,10 +226,9 @@ AttributeList *Parser::ParseGNUAttributes(SourceLocation *EndLoc) {
     if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen)) {
       SkipUntil(tok::r_paren, false);
     }
-    if (EndLoc)
-      *EndLoc = Loc;
+    if (endLoc)
+      *endLoc = Loc;
   }
-  return CurrAttr;
 }
 
 /// ParseMicrosoftDeclSpec - Parse an __declspec construct
@@ -241,14 +240,14 @@ AttributeList *Parser::ParseGNUAttributes(SourceLocation *EndLoc) {
 ///             extended-decl-modifier[opt]
 ///             extended-decl-modifier extended-decl-modifier-seq
 
-AttributeList* Parser::ParseMicrosoftDeclSpec(AttributeList *CurrAttr) {
+void Parser::ParseMicrosoftDeclSpec(ParsedAttributes &attrs) {
   assert(Tok.is(tok::kw___declspec) && "Not a declspec!");
 
   ConsumeToken();
   if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
                        "declspec")) {
     SkipUntil(tok::r_paren, true); // skip until ) or ;
-    return CurrAttr;
+    return;
   }
   while (Tok.getIdentifierInfo()) {
     IdentifierInfo *AttrName = Tok.getIdentifierInfo();
@@ -260,23 +259,22 @@ AttributeList* Parser::ParseMicrosoftDeclSpec(AttributeList *CurrAttr) {
       ExprResult ArgExpr(ParseAssignmentExpression());
       if (!ArgExpr.isInvalid()) {
         Expr *ExprList = ArgExpr.take();
-        CurrAttr = AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc, 0,
-                                      SourceLocation(), &ExprList, 1,
-                                      CurrAttr, true);
+        attrs.add(AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc, 0,
+                                     SourceLocation(), &ExprList, 1, true));
       }
       if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen))
         SkipUntil(tok::r_paren, false);
     } else {
-      CurrAttr = AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc,
-                                    0, SourceLocation(), 0, 0, CurrAttr, true);
+      attrs.add(AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc,
+                                   0, SourceLocation(), 0, 0, true));
     }
   }
   if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen))
     SkipUntil(tok::r_paren, false);
-  return CurrAttr;
+  return;
 }
 
-AttributeList* Parser::ParseMicrosoftTypeAttributes(AttributeList *CurrAttr) {
+void Parser::ParseMicrosoftTypeAttributes(ParsedAttributes &attrs) {
   // Treat these like attributes
   // FIXME: Allow Sema to distinguish between these and real attributes!
   while (Tok.is(tok::kw___fastcall) || Tok.is(tok::kw___stdcall) ||
@@ -287,21 +285,24 @@ AttributeList* Parser::ParseMicrosoftTypeAttributes(AttributeList *CurrAttr) {
     if (Tok.is(tok::kw___ptr64) || Tok.is(tok::kw___w64))
       // FIXME: Support these properly!
       continue;
-    CurrAttr = AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc, 0,
-                                  SourceLocation(), 0, 0, CurrAttr, true);
+    attrs.add(AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc, 0,
+                                 SourceLocation(), 0, 0, true));
   }
-  return CurrAttr;
 }
 
-AttributeList* Parser::ParseBorlandTypeAttributes(AttributeList *CurrAttr) {
+void Parser::ParseBorlandTypeAttributes(ParsedAttributes &attrs) {
   // Treat these like attributes
   while (Tok.is(tok::kw___pascal)) {
     IdentifierInfo *AttrName = Tok.getIdentifierInfo();
     SourceLocation AttrNameLoc = ConsumeToken();
-    CurrAttr = AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc, 0,
-                                  SourceLocation(), 0, 0, CurrAttr, true);
+    attrs.add(AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc, 0,
+                                 SourceLocation(), 0, 0, true));
   }
-  return CurrAttr;
+}
+
+void Parser::DiagnoseProhibitedAttributes(ParsedAttributesWithRange &attrs) {
+  Diag(attrs.Range.getBegin(), diag::err_attributes_not_allowed)
+    << attrs.Range;
 }
 
 /// ParseDeclaration - Parse a full 'declaration', which consists of
@@ -323,49 +324,40 @@ AttributeList* Parser::ParseBorlandTypeAttributes(AttributeList *CurrAttr) {
 Parser::DeclGroupPtrTy Parser::ParseDeclaration(StmtVector &Stmts,
                                                 unsigned Context,
                                                 SourceLocation &DeclEnd,
-                                                CXX0XAttributeList Attr) {
+                                          ParsedAttributesWithRange &attrs) {
   ParenBraceBracketBalancer BalancerRAIIObj(*this);
   
   Decl *SingleDecl = 0;
   switch (Tok.getKind()) {
   case tok::kw_template:
   case tok::kw_export:
-    if (Attr.HasAttr)
-      Diag(Attr.Range.getBegin(), diag::err_attributes_not_allowed)
-        << Attr.Range;
+    ProhibitAttributes(attrs);
     SingleDecl = ParseDeclarationStartingWithTemplate(Context, DeclEnd);
     break;
   case tok::kw_inline:
     // Could be the start of an inline namespace. Allowed as an ext in C++03.
     if (getLang().CPlusPlus && NextToken().is(tok::kw_namespace)) {
-      if (Attr.HasAttr)
-        Diag(Attr.Range.getBegin(), diag::err_attributes_not_allowed)
-          << Attr.Range;
+      ProhibitAttributes(attrs);
       SourceLocation InlineLoc = ConsumeToken();
       SingleDecl = ParseNamespace(Context, DeclEnd, InlineLoc);
       break;
     }
-    return ParseSimpleDeclaration(Stmts, Context, DeclEnd, Attr.AttrList
+    return ParseSimpleDeclaration(Stmts, Context, DeclEnd, attrs
                                   true);
   case tok::kw_namespace:
-    if (Attr.HasAttr)
-      Diag(Attr.Range.getBegin(), diag::err_attributes_not_allowed)
-        << Attr.Range;
+    ProhibitAttributes(attrs);
     SingleDecl = ParseNamespace(Context, DeclEnd);
     break;
   case tok::kw_using:
     SingleDecl = ParseUsingDirectiveOrDeclaration(Context, ParsedTemplateInfo(),
-                                                  DeclEnd, Attr);
+                                                  DeclEnd, attrs);
     break;
   case tok::kw_static_assert:
-    if (Attr.HasAttr)
-      Diag(Attr.Range.getBegin(), diag::err_attributes_not_allowed)
-        << Attr.Range;
+    ProhibitAttributes(attrs);
     SingleDecl = ParseStaticAssertDeclaration(DeclEnd);
     break;
   default:
-    return ParseSimpleDeclaration(Stmts, Context, DeclEnd, Attr.AttrList, 
-                                  true);
+    return ParseSimpleDeclaration(Stmts, Context, DeclEnd, attrs, true);
   }
   
   // This routine returns a DeclGroup, if the thing we parsed only contains a
@@ -383,12 +375,11 @@ Parser::DeclGroupPtrTy Parser::ParseDeclaration(StmtVector &Stmts,
 Parser::DeclGroupPtrTy Parser::ParseSimpleDeclaration(StmtVector &Stmts, 
                                                       unsigned Context,
                                                       SourceLocation &DeclEnd,
-                                                      AttributeList *Attr,
+                                                      ParsedAttributes &attrs,
                                                       bool RequireSemi) {
   // Parse the common declaration-specifiers piece.
   ParsingDeclSpec DS(*this);
-  if (Attr)
-    DS.AddAttributes(Attr);
+  DS.takeAttributesFrom(attrs);
   ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS_none,
                             getDeclSpecContextFromDeclaratorContext(Context));
   StmtResult R = Actions.ActOnVlaStmt(DS);
@@ -482,11 +473,7 @@ Parser::DeclGroupPtrTy Parser::ParseDeclGroup(ParsingDeclSpec &DS,
     //    short __attribute__((common)) var;    -> declspec
     //    short var __attribute__((common));    -> declarator
     //    short x, __attribute__((common)) var;    -> declarator
-    if (Tok.is(tok::kw___attribute)) {
-      SourceLocation Loc;
-      AttributeList *AttrList = ParseGNUAttributes(&Loc);
-      D.AddAttributes(AttrList, Loc);
-    }
+    MaybeParseGNUAttributes(D);
 
     ParseDeclarator(D);
 
@@ -555,12 +542,7 @@ Decl *Parser::ParseDeclarationAfterDeclarator(Declarator &D,
     D.SetRangeEnd(Loc);
   }
 
-  // If attributes are present, parse them.
-  if (Tok.is(tok::kw___attribute)) {
-    SourceLocation Loc;
-    AttributeList *AttrList = ParseGNUAttributes(&Loc);
-    D.AddAttributes(AttrList, Loc);
-  }
+  MaybeParseGNUAttributes(D);
 
   // Inform the current actions module that we just parsed this declarator.
   Decl *ThisDecl = 0;
@@ -688,7 +670,7 @@ void Parser::ParseSpecifierQualifierList(DeclSpec &DS) {
   // Validate declspec for type-name.
   unsigned Specs = DS.getParsedSpecifiers();
   if (Specs == DeclSpec::PQ_None && !DS.getNumProtocolQualifiers() &&
-      !DS.getAttributes())
+      !DS.hasAttributes())
     Diag(Tok, diag::err_typename_requires_specqual);
 
   // Issue diagnostic and remove storage class if present.
@@ -1191,12 +1173,12 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
 
     // GNU attributes support.
     case tok::kw___attribute:
-      DS.AddAttributes(ParseGNUAttributes());
+      ParseGNUAttributes(DS.getAttributes());
       continue;
 
     // Microsoft declspec support.
     case tok::kw___declspec:
-      DS.AddAttributes(ParseMicrosoftDeclSpec());
+      ParseMicrosoftDeclSpec(DS.getAttributes());
       continue;
 
     // Microsoft single token adornments.
@@ -1210,12 +1192,12 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
     case tok::kw___stdcall:
     case tok::kw___fastcall:
     case tok::kw___thiscall:
-      DS.AddAttributes(ParseMicrosoftTypeAttributes());
+      ParseMicrosoftTypeAttributes(DS.getAttributes());
       continue;
 
     // Borland single token adornments.
     case tok::kw___pascal:
-      DS.AddAttributes(ParseBorlandTypeAttributes());
+      ParseBorlandTypeAttributes(DS.getAttributes());
       continue;
 
     // storage-class-specifier
@@ -1692,11 +1674,11 @@ bool Parser::ParseOptionalTypeSpecifier(DeclSpec &DS, bool& isInvalid,
   case tok::kw___stdcall:
   case tok::kw___fastcall:
   case tok::kw___thiscall:
-    DS.AddAttributes(ParseMicrosoftTypeAttributes());
+    ParseMicrosoftTypeAttributes(DS.getAttributes());
     return true;
 
   case tok::kw___pascal:
-    DS.AddAttributes(ParseBorlandTypeAttributes());
+    ParseBorlandTypeAttributes(DS.getAttributes());
     return true;
 
   default:
@@ -1759,11 +1741,8 @@ ParseStructDeclaration(DeclSpec &DS, FieldCallback &Fields) {
     FieldDeclarator DeclaratorInfo(DS);
 
     // Attributes are only allowed here on successive declarators.
-    if (!FirstDeclarator && Tok.is(tok::kw___attribute)) {
-      SourceLocation Loc;
-      AttributeList *AttrList = ParseGNUAttributes(&Loc);
-      DeclaratorInfo.D.AddAttributes(AttrList, Loc);
-    }
+    if (!FirstDeclarator)
+      MaybeParseGNUAttributes(DeclaratorInfo.D);
 
     /// struct-declarator: declarator
     /// struct-declarator: declarator[opt] ':' constant-expression
@@ -1783,11 +1762,7 @@ ParseStructDeclaration(DeclSpec &DS, FieldCallback &Fields) {
     }
 
     // If attributes exist after the declarator, parse them.
-    if (Tok.is(tok::kw___attribute)) {
-      SourceLocation Loc;
-      AttributeList *AttrList = ParseGNUAttributes(&Loc);
-      DeclaratorInfo.D.AddAttributes(AttrList, Loc);
-    }
+    MaybeParseGNUAttributes(DeclaratorInfo.D);
 
     // We're done with this declarator;  invoke the callback.
     Decl *D = Fields.invoke(DeclaratorInfo);
@@ -1908,15 +1883,14 @@ void Parser::ParseStructUnionBody(SourceLocation RecordLoc,
 
   SourceLocation RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBraceLoc);
 
-  AttributeList *AttrList = 0;
+  ParsedAttributes attrs;
   // If attributes exist after struct contents, parse them.
-  if (Tok.is(tok::kw___attribute))
-    AttrList = ParseGNUAttributes();
+  MaybeParseGNUAttributes(attrs);
 
   Actions.ActOnFields(getCurScope(),
                       RecordLoc, TagDecl, FieldDecls.data(), FieldDecls.size(),
                       LBraceLoc, RBraceLoc,
-                      AttrList);
+                      attrs.getList());
   StructScope.Exit();
   Actions.ActOnTagFinishDefinition(getCurScope(), TagDecl, RBraceLoc);
 }
@@ -1958,10 +1932,9 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
     ConsumeCodeCompletionToken();
   }
   
-  AttributeList *Attr = 0;
   // If attributes exist after tag, parse them.
-  if (Tok.is(tok::kw___attribute))
-    Attr = ParseGNUAttributes();
+  ParsedAttributes attrs;
+  MaybeParseGNUAttributes(attrs);
 
   CXXScopeSpec &SS = DS.getTypeSpecScope();
   if (getLang().CPlusPlus) {
@@ -2102,7 +2075,7 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
   const char *PrevSpec = 0;
   unsigned DiagID;
   Decl *TagDecl = Actions.ActOnTag(getCurScope(), DeclSpec::TST_enum, TUK,
-                                   StartLoc, SS, Name, NameLoc, Attr,
+                                   StartLoc, SS, Name, NameLoc, attrs.getList(),
                                    AS,
                                    MultiTemplateParamsArg(Actions),
                                    Owned, IsDependent, IsScopedEnum,
@@ -2185,9 +2158,8 @@ void Parser::ParseEnumBody(SourceLocation StartLoc, Decl *EnumDecl) {
     SourceLocation IdentLoc = ConsumeToken();
 
     // If attributes exist after the enumerator, parse them.
-    AttributeList *Attr = 0;
-    if (Tok.is(tok::kw___attribute))
-      Attr = ParseGNUAttributes();
+    ParsedAttributes attrs;
+    MaybeParseGNUAttributes(attrs);
 
     SourceLocation EqualLoc;
     ExprResult AssignedVal;
@@ -2202,7 +2174,7 @@ void Parser::ParseEnumBody(SourceLocation StartLoc, Decl *EnumDecl) {
     Decl *EnumConstDecl = Actions.ActOnEnumConstant(getCurScope(), EnumDecl,
                                                     LastEnumConstDecl,
                                                     IdentLoc, Ident,
-                                                    Attr, EqualLoc,
+                                                    attrs.getList(), EqualLoc,
                                                     AssignedVal.release());
     EnumConstantDecls.push_back(EnumConstDecl);
     LastEnumConstDecl = EnumConstDecl;
@@ -2229,14 +2201,13 @@ void Parser::ParseEnumBody(SourceLocation StartLoc, Decl *EnumDecl) {
   // Eat the }.
   SourceLocation RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBraceLoc);
 
-  AttributeList *Attr = 0;
   // If attributes exist after the identifier list, parse them.
-  if (Tok.is(tok::kw___attribute))
-    Attr = ParseGNUAttributes(); // FIXME: where do they do?
+  ParsedAttributes attrs;
+  MaybeParseGNUAttributes(attrs);
 
   Actions.ActOnEnumBody(StartLoc, LBraceLoc, RBraceLoc, EnumDecl,
                         EnumConstantDecls.data(), EnumConstantDecls.size(),
-                        getCurScope(), Attr);
+                        getCurScope(), attrs.getList());
 
   EnumScope.Exit();
   Actions.ActOnTagFinishDefinition(getCurScope(), EnumDecl, RBraceLoc);
@@ -2567,9 +2538,10 @@ void Parser::ParseTypeQualifierListOpt(DeclSpec &DS,
                                        bool CXX0XAttributesAllowed) {
   if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier()) {
     SourceLocation Loc = Tok.getLocation();
-    CXX0XAttributeList Attr = ParseCXX0XAttributes();
+    ParsedAttributesWithRange attrs;
+    ParseCXX0XAttributes(attrs);
     if (CXX0XAttributesAllowed)
-      DS.AddAttributes(Attr.AttrList);
+      DS.takeAttributesFrom(attrs);
     else
       Diag(Loc, diag::err_attributes_not_allowed);
   }
@@ -2605,19 +2577,19 @@ void Parser::ParseTypeQualifierListOpt(DeclSpec &DS,
     case tok::kw___fastcall:
     case tok::kw___thiscall:
       if (VendorAttributesAllowed) {
-        DS.AddAttributes(ParseMicrosoftTypeAttributes());
+        ParseMicrosoftTypeAttributes(DS.getAttributes());
         continue;
       }
       goto DoneWithTypeQuals;
     case tok::kw___pascal:
       if (VendorAttributesAllowed) {
-        DS.AddAttributes(ParseBorlandTypeAttributes());
+        ParseBorlandTypeAttributes(DS.getAttributes());
         continue;
       }
       goto DoneWithTypeQuals;
     case tok::kw___attribute:
       if (VendorAttributesAllowed) {
-        DS.AddAttributes(ParseGNUAttributes());
+        ParseGNUAttributes(DS.getAttributes());
         continue; // do *not* consume the next token!
       }
       // otherwise, FALL THROUGH!
@@ -2703,7 +2675,7 @@ void Parser::ParseDeclaratorInternal(Declarator &D,
       // Sema will have to catch (syntactically invalid) pointers into global
       // scope. It has to catch pointers into namespace scope anyway.
       D.AddTypeInfo(DeclaratorChunk::getMemberPointer(SS,DS.getTypeQualifiers(),
-                                                      Loc, DS.TakeAttributes()),
+                                                      Loc, DS.takeAttributes()),
                     /* Don't replace range end. */SourceLocation());
       return;
     }
@@ -2737,12 +2709,12 @@ void Parser::ParseDeclaratorInternal(Declarator &D,
     if (Kind == tok::star)
       // Remember that we parsed a pointer type, and remember the type-quals.
       D.AddTypeInfo(DeclaratorChunk::getPointer(DS.getTypeQualifiers(), Loc,
-                                                DS.TakeAttributes()),
+                                                DS.takeAttributes()),
                     SourceLocation());
     else
       // Remember that we parsed a Block type, and remember the type-quals.
       D.AddTypeInfo(DeclaratorChunk::getBlockPointer(DS.getTypeQualifiers(),
-                                                     Loc, DS.TakeAttributes()),
+                                                     Loc, DS.takeAttributes()),
                     SourceLocation());
   } else {
     // Is a reference
@@ -2794,7 +2766,7 @@ void Parser::ParseDeclaratorInternal(Declarator &D,
 
     // Remember that we parsed a reference type. It doesn't have type-quals.
     D.AddTypeInfo(DeclaratorChunk::getReference(DS.getTypeQualifiers(), Loc,
-                                                DS.TakeAttributes(),
+                                                DS.takeAttributes(),
                                                 Kind == tok::amp),
                   SourceLocation());
   }
@@ -2946,12 +2918,8 @@ void Parser::ParseDirectDeclarator(Declarator &D) {
          "Haven't past the location of the identifier yet?");
 
   // Don't parse attributes unless we have an identifier.
-  if (D.getIdentifier() && getLang().CPlusPlus0x
-   && isCXX0XAttributeSpecifier(true)) {
-    SourceLocation AttrEndLoc;
-    CXX0XAttributeList Attr = ParseCXX0XAttributes();
-    D.AddAttributes(Attr.AttrList, AttrEndLoc);
-  }
+  if (D.getIdentifier())
+    MaybeParseCXX0XAttributes(D);
 
   while (1) {
     if (Tok.is(tok::l_paren)) {
@@ -2965,7 +2933,8 @@ void Parser::ParseDirectDeclarator(Declarator &D) {
         if (!isCXXFunctionDeclarator(warnIfAmbiguous))
           break;
       }
-      ParseFunctionDeclarator(ConsumeParen(), D);
+      ParsedAttributes attrs;
+      ParseFunctionDeclarator(ConsumeParen(), D, attrs);
     } else if (Tok.is(tok::l_square)) {
       ParseBracketDeclarator(D);
     } else {
@@ -3001,10 +2970,10 @@ void Parser::ParseParenDeclarator(Declarator &D) {
   // In either case, we need to eat any attributes to be able to determine what
   // sort of paren this is.
   //
-  AttributeList *AttrList = 0;
+  ParsedAttributes attrs;
   bool RequiresArg = false;
   if (Tok.is(tok::kw___attribute)) {
-    AttrList = ParseGNUAttributes();
+    ParseGNUAttributes(attrs);
 
     // We require that the argument list (if this is a non-grouping paren) be
     // present even if the attribute list was empty.
@@ -3014,11 +2983,11 @@ void Parser::ParseParenDeclarator(Declarator &D) {
   if  (Tok.is(tok::kw___cdecl) || Tok.is(tok::kw___stdcall) ||
        Tok.is(tok::kw___thiscall) || Tok.is(tok::kw___fastcall) ||
        Tok.is(tok::kw___w64) || Tok.is(tok::kw___ptr64)) {
-    AttrList = ParseMicrosoftTypeAttributes(AttrList);
+    ParseMicrosoftTypeAttributes(attrs);
   }
   // Eat any Borland extensions.
   if  (Tok.is(tok::kw___pascal))
-    AttrList = ParseBorlandTypeAttributes(AttrList);
+    ParseBorlandTypeAttributes(attrs);
 
   // If we haven't past the identifier yet (or where the identifier would be
   // stored, if this is an abstract declarator), then this is probably just
@@ -3047,8 +3016,8 @@ void Parser::ParseParenDeclarator(Declarator &D) {
   if (isGrouping) {
     bool hadGroupingParens = D.hasGroupingParens();
     D.setGroupingParens(true);
-    if (AttrList)
-      D.AddAttributes(AttrList, SourceLocation());
+    if (!attrs.empty())
+      D.addAttributes(attrs.getList(), SourceLocation());
 
     ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
     // Match the ')'.
@@ -3065,7 +3034,7 @@ void Parser::ParseParenDeclarator(Declarator &D) {
   // ParseFunctionDeclarator to handle of argument list.
   D.SetIdentifier(0, Tok.getLocation());
 
-  ParseFunctionDeclarator(StartLoc, D, AttrList, RequiresArg);
+  ParseFunctionDeclarator(StartLoc, D, attrs, RequiresArg);
 }
 
 /// ParseFunctionDeclarator - We are after the identifier and have parsed the
@@ -3101,7 +3070,7 @@ void Parser::ParseParenDeclarator(Declarator &D) {
 /// and "exception-specification[opt]".
 ///
 void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
-                                     AttributeList *AttrList,
+                                     ParsedAttributes &attrs,
                                      bool RequiresArg) {
   // lparen is already consumed!
   assert(D.isPastIdentifier() && "Should not call before identifier!");
@@ -3124,6 +3093,8 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
     llvm::SmallVector<ParsedType, 2> Exceptions;
     llvm::SmallVector<SourceRange, 2> ExceptionRanges;
     if (getLang().CPlusPlus) {
+      MaybeParseCXX0XAttributes(attrs);
+
       ParseTypeQualifierListOpt(DS, false /*no attributes*/);
       if (!DS.getSourceRange().getEnd().isInvalid())
         EndLoc = DS.getSourceRange().getEnd();
@@ -3146,7 +3117,8 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
 
     // Remember that we parsed a function type, and remember the attributes.
     // int() -> no prototype, no '...'.
-    D.AddTypeInfo(DeclaratorChunk::getFunction(/*prototype*/getLang().CPlusPlus,
+    D.AddTypeInfo(DeclaratorChunk::getFunction(attrs,
+                                               /*prototype*/getLang().CPlusPlus,
                                                /*variadic*/ false,
                                                SourceLocation(),
                                                /*arglist*/ 0, 0,
@@ -3219,22 +3191,21 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
       EllipsisLoc = ConsumeToken();     // Consume the ellipsis.
       break;
     }
+
+    // Parse the declaration-specifiers.
+    // Just use the ParsingDeclaration "scope" of the declarator.
+    DeclSpec DS;
        
     // Skip any Microsoft attributes before a param.
     if (getLang().Microsoft && Tok.is(tok::l_square))
-      ParseMicrosoftAttributes();
+      ParseMicrosoftAttributes(DS.getAttributes());
 
     SourceLocation DSStart = Tok.getLocation();
 
-    // Parse the declaration-specifiers.
-    // Just use the ParsingDeclaration "scope" of the declarator.
-    DeclSpec DS;
-
     // If the caller parsed attributes for the first argument, add them now.
-    if (AttrList) {
-      DS.AddAttributes(AttrList);
-      AttrList = 0;  // Only apply the attributes to the first parameter.
-    }
+    // Take them so that we only apply the attributes to the first parameter.
+    DS.takeAttributesFrom(attrs);
+
     ParseDeclarationSpecifiers(DS);
 
     // Parse the declarator.  This is "PrototypeContext", because we must
@@ -3243,11 +3214,7 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
     ParseDeclarator(ParmDecl);
 
     // Parse GNU attributes, if present.
-    if (Tok.is(tok::kw___attribute)) {
-      SourceLocation Loc;
-      AttributeList *AttrList = ParseGNUAttributes(&Loc);
-      ParmDecl.AddAttributes(AttrList, Loc);
-    }
+    MaybeParseGNUAttributes(ParmDecl);
 
     // Remember this parsed parameter in ParamInfo.
     IdentifierInfo *ParmII = ParmDecl.getIdentifier();
@@ -3362,6 +3329,8 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
   llvm::SmallVector<SourceRange, 2> ExceptionRanges;
   
   if (getLang().CPlusPlus) {
+    MaybeParseCXX0XAttributes(attrs);
+
     // Parse cv-qualifier-seq[opt].
     ParseTypeQualifierListOpt(DS, false /*no attributes*/);
       if (!DS.getSourceRange().getEnd().isInvalid())
@@ -3390,7 +3359,8 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
   PrototypeScope.Exit();
 
   // Remember that we parsed a function type, and remember the attributes.
-  D.AddTypeInfo(DeclaratorChunk::getFunction(/*proto*/true, IsVariadic,
+  D.AddTypeInfo(DeclaratorChunk::getFunction(attrs,
+                                             /*proto*/true, IsVariadic,
                                              EllipsisLoc,
                                              ParamInfo.data(), ParamInfo.size(),
                                              DS.getTypeQualifiers(),
@@ -3470,7 +3440,8 @@ void Parser::ParseFunctionDeclaratorIdentifierList(SourceLocation LParenLoc,
   // Remember that we parsed a function type, and remember the attributes.  This
   // function type is always a K&R style function type, which is not varargs and
   // has no prototype.
-  D.AddTypeInfo(DeclaratorChunk::getFunction(/*proto*/false, /*varargs*/false,
+  D.AddTypeInfo(DeclaratorChunk::getFunction(ParsedAttributes(),
+                                             /*proto*/false, /*varargs*/false,
                                              SourceLocation(),
                                              &ParamInfo[0], ParamInfo.size(),
                                              /*TypeQuals*/0,
@@ -3492,15 +3463,12 @@ void Parser::ParseBracketDeclarator(Declarator &D) {
   // This code does a fast path to handle some of the most obvious cases.
   if (Tok.getKind() == tok::r_square) {
     SourceLocation EndLoc = MatchRHSPunctuation(tok::r_square, StartLoc);
-    //FIXME: Use these
-    CXX0XAttributeList Attr;
-    if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier(true)) {
-      Attr = ParseCXX0XAttributes();
-    }
+    ParsedAttributes attrs;
+    MaybeParseCXX0XAttributes(attrs);
     
     // Remember that we parsed the empty array type.
     ExprResult NumElements;
-    D.AddTypeInfo(DeclaratorChunk::getArray(0, false, false, 0,
+    D.AddTypeInfo(DeclaratorChunk::getArray(0, attrs, false, false, 0,
                                             StartLoc, EndLoc),
                   EndLoc);
     return;
@@ -3511,18 +3479,12 @@ void Parser::ParseBracketDeclarator(Declarator &D) {
     ConsumeToken();
 
     SourceLocation EndLoc = MatchRHSPunctuation(tok::r_square, StartLoc);
-    //FIXME: Use these
-    CXX0XAttributeList Attr;
-    if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier()) {
-      Attr = ParseCXX0XAttributes();
-    }
-
-    // If there was an error parsing the assignment-expression, recover.
-    if (ExprRes.isInvalid())
-      ExprRes.release();  // Deallocate expr, just use [].
+    ParsedAttributes attrs;
+    MaybeParseCXX0XAttributes(attrs);
 
     // Remember that we parsed a array type, and remember its features.
-    D.AddTypeInfo(DeclaratorChunk::getArray(0, false, 0, ExprRes.release(),
+    D.AddTypeInfo(DeclaratorChunk::getArray(0, attrs, false, 0,
+                                            ExprRes.release(),
                                             StartLoc, EndLoc),
                   EndLoc);
     return;
@@ -3583,14 +3545,11 @@ void Parser::ParseBracketDeclarator(Declarator &D) {
 
   SourceLocation EndLoc = MatchRHSPunctuation(tok::r_square, StartLoc);
 
-  //FIXME: Use these
-  CXX0XAttributeList Attr;
-  if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier()) {
-    Attr = ParseCXX0XAttributes();
-  }
+  ParsedAttributes attrs;
+  MaybeParseCXX0XAttributes(attrs);
 
   // Remember that we parsed a array type, and remember its features.
-  D.AddTypeInfo(DeclaratorChunk::getArray(DS.getTypeQualifiers(),
+  D.AddTypeInfo(DeclaratorChunk::getArray(DS.getTypeQualifiers(), attrs,
                                           StaticLoc.isValid(), isStar,
                                           NumElements.release(),
                                           StartLoc, EndLoc),
index e1f7f7bdc5891e3263af7cb2c2193b22db844329..fe2390f1aa062c38a959a6886584a12ff1c9b240 100644 (file)
@@ -69,16 +69,16 @@ Decl *Parser::ParseNamespace(unsigned Context,
   }
 
   // Read label attributes, if present.
-  AttributeList *AttrList = 0;
+  ParsedAttributes attrs;
   if (Tok.is(tok::kw___attribute)) {
     attrTok = Tok;
 
     // FIXME: save these somewhere.
-    AttrList = ParseGNUAttributes();
+    ParseGNUAttributes(attrs);
   }
 
   if (Tok.is(tok::equal)) {
-    if (AttrList)
+    if (!attrs.empty())
       Diag(attrTok, diag::err_unexpected_namespace_attributes_alias);
     if (InlineLoc.isValid())
       Diag(InlineLoc, diag::err_inline_namespace_alias)
@@ -112,18 +112,16 @@ Decl *Parser::ParseNamespace(unsigned Context,
 
   Decl *NamespcDecl =
     Actions.ActOnStartNamespaceDef(getCurScope(), InlineLoc, IdentLoc, Ident,
-                                   LBrace, AttrList);
+                                   LBrace, attrs.getList());
 
   PrettyDeclStackTraceEntry CrashInfo(Actions, NamespcDecl, NamespaceLoc,
                                       "parsing namespace");
 
   while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
-    CXX0XAttributeList Attr;
-    if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier())
-      Attr = ParseCXX0XAttributes();
-    if (getLang().Microsoft && Tok.is(tok::l_square))
-      ParseMicrosoftAttributes();
-    ParseExternalDeclaration(Attr);
+    ParsedAttributesWithRange attrs;
+    MaybeParseCXX0XAttributes(attrs);
+    MaybeParseMicrosoftAttributes(attrs);
+    ParseExternalDeclaration(attrs);
   }
 
   // Leave the namespace scope.
@@ -201,34 +199,27 @@ Decl *Parser::ParseLinkage(ParsingDeclSpec &DS, unsigned Context) {
                                        Tok.is(tok::l_brace)? Tok.getLocation()
                                                            : SourceLocation());
 
-  CXX0XAttributeList Attr;
-  if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier())
-    Attr = ParseCXX0XAttributes();
-
-  if (getLang().Microsoft && Tok.is(tok::l_square))
-    ParseMicrosoftAttributes();
+  ParsedAttributesWithRange attrs;
+  MaybeParseCXX0XAttributes(attrs);
+  MaybeParseMicrosoftAttributes(attrs);
 
   if (Tok.isNot(tok::l_brace)) {
     DS.setExternInLinkageSpec(true);
-    ParseExternalDeclaration(Attr, &DS);
+    ParseExternalDeclaration(attrs, &DS);
     return Actions.ActOnFinishLinkageSpecification(getCurScope(), LinkageSpec,
                                                    SourceLocation());
   }
 
   DS.abort();
 
-  if (Attr.HasAttr)
-    Diag(Attr.Range.getBegin(), diag::err_attributes_not_allowed)
-      << Attr.Range;
+  ProhibitAttributes(attrs);
 
   SourceLocation LBrace = ConsumeBrace();
   while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
-    CXX0XAttributeList Attr;
-    if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier())
-      Attr = ParseCXX0XAttributes();
-    if (getLang().Microsoft && Tok.is(tok::l_square))
-      ParseMicrosoftAttributes();
-    ParseExternalDeclaration(Attr);
+    ParsedAttributesWithRange attrs;
+    MaybeParseCXX0XAttributes(attrs);
+    MaybeParseMicrosoftAttributes(attrs);
+    ParseExternalDeclaration(attrs);
   }
 
   SourceLocation RBrace = MatchRHSPunctuation(tok::r_brace, LBrace);
@@ -241,7 +232,7 @@ Decl *Parser::ParseLinkage(ParsingDeclSpec &DS, unsigned Context) {
 Decl *Parser::ParseUsingDirectiveOrDeclaration(unsigned Context,
                                          const ParsedTemplateInfo &TemplateInfo,
                                                SourceLocation &DeclEnd,
-                                               CXX0XAttributeList Attr) {
+                                             ParsedAttributesWithRange &attrs) {
   assert(Tok.is(tok::kw_using) && "Not using token");
 
   // Eat 'using'.
@@ -261,15 +252,13 @@ Decl *Parser::ParseUsingDirectiveOrDeclaration(unsigned Context,
         << R << FixItHint::CreateRemoval(R);
     }
 
-    return ParseUsingDirective(Context, UsingLoc, DeclEnd, Attr.AttrList);
+    return ParseUsingDirective(Context, UsingLoc, DeclEnd, attrs);
   }
 
   // Otherwise, it must be a using-declaration.
 
   // Using declarations can't have attributes.
-  if (Attr.HasAttr)
-    Diag(Attr.Range.getBegin(), diag::err_attributes_not_allowed)
-      << Attr.Range;
+  ProhibitAttributes(attrs);
 
   return ParseUsingDeclaration(Context, TemplateInfo, UsingLoc, DeclEnd);
 }
@@ -287,7 +276,7 @@ Decl *Parser::ParseUsingDirectiveOrDeclaration(unsigned Context,
 Decl *Parser::ParseUsingDirective(unsigned Context,
                                   SourceLocation UsingLoc,
                                   SourceLocation &DeclEnd,
-                                  AttributeList *Attr) {
+                                  ParsedAttributes &attrs) {
   assert(Tok.is(tok::kw_namespace) && "Not 'namespace' token");
 
   // Eat 'namespace'.
@@ -322,7 +311,7 @@ Decl *Parser::ParseUsingDirective(unsigned Context,
   bool GNUAttr = false;
   if (Tok.is(tok::kw___attribute)) {
     GNUAttr = true;
-    Attr = addAttributeLists(Attr, ParseGNUAttributes());
+    ParseGNUAttributes(attrs);
   }
 
   // Eat ';'.
@@ -333,7 +322,7 @@ Decl *Parser::ParseUsingDirective(unsigned Context,
                    "", tok::semi);
 
   return Actions.ActOnUsingDirective(getCurScope(), UsingLoc, NamespcLoc, SS,
-                                      IdentLoc, NamespcName, Attr);
+                                     IdentLoc, NamespcName, attrs.getList());
 }
 
 /// ParseUsingDeclaration - Parse C++ using-declaration. Assumes that
@@ -391,14 +380,13 @@ Decl *Parser::ParseUsingDeclaration(unsigned Context,
   }
 
   // Parse (optional) attributes (most likely GNU strong-using extension).
-  AttributeList *AttrList = 0;
-  if (Tok.is(tok::kw___attribute))
-    AttrList = ParseGNUAttributes();
+  ParsedAttributes attrs;
+  MaybeParseGNUAttributes(attrs);
 
   // Eat ';'.
   DeclEnd = Tok.getLocation();
   ExpectAndConsume(tok::semi, diag::err_expected_semi_after,
-                   AttrList ? "attributes list" : "using declaration",
+                   !attrs.empty() ? "attributes list" : "using declaration",
                    tok::semi);
 
   // Diagnose an attempt to declare a templated using-declaration.
@@ -414,7 +402,8 @@ Decl *Parser::ParseUsingDeclaration(unsigned Context,
   }
 
   return Actions.ActOnUsingDeclaration(getCurScope(), AS, true, UsingLoc, SS,
-                                       Name, AttrList, IsTypeName, TypenameLoc);
+                                       Name, attrs.getList(),
+                                       IsTypeName, TypenameLoc);
 }
 
 /// ParseStaticAssertDeclaration - Parse C++0x static_assert-declaratoion.
@@ -685,20 +674,19 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
     SuppressingAccessChecks = true;
   }
 
-  AttributeList *AttrList = 0;
+  ParsedAttributes attrs;
   // If attributes exist after tag, parse them.
   if (Tok.is(tok::kw___attribute))
-    AttrList = ParseGNUAttributes();
+    ParseGNUAttributes(attrs);
 
   // If declspecs exist after tag, parse them.
   while (Tok.is(tok::kw___declspec))
-    AttrList = ParseMicrosoftDeclSpec(AttrList);
+    ParseMicrosoftDeclSpec(attrs);
 
   // If C++0x attributes exist here, parse them.
   // FIXME: Are we consistent with the ordering of parsing of different
   // styles of attributes?
-  if (isCXX0XAttributeSpecifier())
-    AttrList = addAttributeLists(AttrList, ParseCXX0XAttributes().AttrList);
+  MaybeParseCXX0XAttributes(attrs);
 
   if (TagType == DeclSpec::TST_struct && Tok.is(tok::kw___is_pod)) {
     // GNU libstdc++ 4.2 uses __is_pod as the name of a struct template, but
@@ -892,7 +880,7 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
                                              TemplateId->LAngleLoc,
                                              TemplateArgsPtr,
                                              TemplateId->RAngleLoc,
-                                             AttrList);
+                                             attrs.getList());
 
     // Friend template-ids are treated as references unless
     // they have template headers, in which case they're ill-formed
@@ -954,7 +942,7 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
                        TemplateId->LAngleLoc,
                        TemplateArgsPtr,
                        TemplateId->RAngleLoc,
-                       AttrList,
+                       attrs.getList(),
                        MultiTemplateParamsArg(Actions,
                                     TemplateParams? &(*TemplateParams)[0] : 0,
                                  TemplateParams? TemplateParams->size() : 0));
@@ -972,13 +960,13 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
                                            TemplateInfo.ExternLoc,
                                            TemplateInfo.TemplateLoc,
                                            TagType, StartLoc, SS, Name,
-                                           NameLoc, AttrList);
+                                           NameLoc, attrs.getList());
   } else if (TUK == Sema::TUK_Friend &&
              TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate) {
     TagOrTempResult =
       Actions.ActOnTemplatedFriendTag(getCurScope(), DS.getFriendSpecLoc(),
                                       TagType, StartLoc, SS,
-                                      Name, NameLoc, AttrList,
+                                      Name, NameLoc, attrs.getList(),
                                       MultiTemplateParamsArg(Actions,
                                     TemplateParams? &(*TemplateParams)[0] : 0,
                                  TemplateParams? TemplateParams->size() : 0));
@@ -1000,7 +988,7 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
 
     // Declaration or definition of a class type
     TagOrTempResult = Actions.ActOnTag(getCurScope(), TagType, TUK, StartLoc,
-                                       SS, Name, NameLoc, AttrList, AS,
+                                       SS, Name, NameLoc, attrs.getList(), AS,
                                        TParams, Owned, IsDependent, false,
                                        false, clang::TypeResult());
 
@@ -1364,19 +1352,15 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
   // is a bitfield.
   ColonProtectionRAIIObject X(*this);
 
-  CXX0XAttributeList AttrList;
+  ParsedAttributesWithRange attrs;
   // Optional C++0x attribute-specifier
-  if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier())
-    AttrList = ParseCXX0XAttributes();
-  if (getLang().Microsoft && Tok.is(tok::l_square))
-    ParseMicrosoftAttributes();
+  MaybeParseCXX0XAttributes(attrs);
+  MaybeParseMicrosoftAttributes(attrs);
 
   if (Tok.is(tok::kw_using)) {
     // FIXME: Check for template aliases
 
-    if (AttrList.HasAttr)
-      Diag(AttrList.Range.getBegin(), diag::err_attributes_not_allowed)
-        << AttrList.Range;
+    ProhibitAttributes(attrs);
 
     // Eat 'using'.
     SourceLocation UsingLoc = ConsumeToken();
@@ -1397,7 +1381,7 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
   // decl-specifier-seq:
   // Parse the common declaration-specifiers piece.
   ParsingDeclSpec DS(*this, TemplateDiags);
-  DS.AddAttributes(AttrList.AttrList);
+  DS.takeAttributesFrom(attrs);
   ParseDeclarationSpecifiers(DS, TemplateInfo, AS, DSC_class);
 
   MultiTemplateParamsArg TemplateParams(Actions,
@@ -1430,11 +1414,7 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
     }
 
     // If attributes exist after the declarator, but before an '{', parse them.
-    if (Tok.is(tok::kw___attribute)) {
-      SourceLocation Loc;
-      AttributeList *AttrList = ParseGNUAttributes(&Loc);
-      DeclaratorInfo.AddAttributes(AttrList, Loc);
-    }
+    MaybeParseGNUAttributes(DeclaratorInfo);
 
     // function-definition:
     if (Tok.is(tok::l_brace)
@@ -1518,11 +1498,7 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
     }
 
     // If attributes exist after the declarator, parse them.
-    if (Tok.is(tok::kw___attribute)) {
-      SourceLocation Loc;
-      AttributeList *AttrList = ParseGNUAttributes(&Loc);
-      DeclaratorInfo.AddAttributes(AttrList, Loc);
-    }
+    MaybeParseGNUAttributes(DeclaratorInfo);
 
     // NOTE: If Sema is the Action module and declarator is an instance field,
     // this call will *not* return the created decl; It will return null.
@@ -1569,11 +1545,7 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
     Deleted = false;
 
     // Attributes are only allowed on the second declarator.
-    if (Tok.is(tok::kw___attribute)) {
-      SourceLocation Loc;
-      AttributeList *AttrList = ParseGNUAttributes(&Loc);
-      DeclaratorInfo.AddAttributes(AttrList, Loc);
-    }
+    MaybeParseGNUAttributes(DeclaratorInfo);
 
     if (Tok.isNot(tok::colon))
       ParseDeclarator(DeclaratorInfo);
@@ -1708,14 +1680,13 @@ void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc,
   }
 
   // If attributes exist after class contents, parse them.
-  AttributeList *AttrList = 0;
-  if (Tok.is(tok::kw___attribute))
-    AttrList = ParseGNUAttributes();
+  ParsedAttributes attrs;
+  MaybeParseGNUAttributes(attrs);
 
   if (TagDecl)
     Actions.ActOnFinishCXXMemberSpecification(getCurScope(), RecordLoc, TagDecl,
                                               LBraceLoc, RBraceLoc,
-                                              AttrList);
+                                              attrs.getList());
 
   // C++ 9.2p2: Within the class member-specification, the class is regarded as
   // complete within function bodies, default arguments,
@@ -2043,12 +2014,12 @@ void Parser::PopParsingClass() {
 ///         '[' balanced-token-seq ']'
 ///         '{' balanced-token-seq '}'
 ///         any token but '(', ')', '[', ']', '{', or '}'
-CXX0XAttributeList Parser::ParseCXX0XAttributes(SourceLocation *EndLoc) {
+void Parser::ParseCXX0XAttributes(ParsedAttributesWithRange &attrs,
+                                  SourceLocation *endLoc) {
   assert(Tok.is(tok::l_square) && NextToken().is(tok::l_square)
       && "Not a C++0x attribute list");
 
   SourceLocation StartLoc = Tok.getLocation(), Loc;
-  AttributeList *CurrAttr = 0;
 
   ConsumeBracket();
   ConsumeBracket();
@@ -2104,9 +2075,8 @@ CXX0XAttributeList Parser::ParseCXX0XAttributes(SourceLocation *EndLoc) {
           break;
         }
 
-        CurrAttr = AttrFactory.Create(AttrName, AttrLoc, 0, AttrLoc, 0,
-                                      SourceLocation(), 0, 0, CurrAttr, false,
-                                      true);
+        attrs.add(AttrFactory.Create(AttrName, AttrLoc, 0, AttrLoc, 0,
+                                     SourceLocation(), 0, 0, false, true));
         AttrParsed = true;
         break;
       }
@@ -2126,9 +2096,9 @@ CXX0XAttributeList Parser::ParseCXX0XAttributes(SourceLocation *EndLoc) {
 
         ExprVector ArgExprs(Actions);
         ArgExprs.push_back(ArgExpr.release());
-        CurrAttr = AttrFactory.Create(AttrName, AttrLoc, 0, AttrLoc,
-                                      0, ParamLoc, ArgExprs.take(), 1, CurrAttr,
-                                      false, true);
+        attrs.add(AttrFactory.Create(AttrName, AttrLoc, 0, AttrLoc,
+                                     0, ParamLoc, ArgExprs.take(), 1,
+                                     false, true));
 
         AttrParsed = true;
         break;
@@ -2153,8 +2123,7 @@ CXX0XAttributeList Parser::ParseCXX0XAttributes(SourceLocation *EndLoc) {
   if (ExpectAndConsume(tok::r_square, diag::err_expected_rsquare))
     SkipUntil(tok::r_square, false);
 
-  CXX0XAttributeList Attr (CurrAttr, SourceRange(StartLoc, Loc), true);
-  return Attr;
+  attrs.Range = SourceRange(StartLoc, Loc);
 }
 
 /// ParseCXX0XAlignArgument - Parse the argument to C++0x's [[align]]
@@ -2185,12 +2154,14 @@ ExprResult Parser::ParseCXX0XAlignArgument(SourceLocation Start) {
 /// [MS] ms-attribute-seq:
 ///             ms-attribute[opt]
 ///             ms-attribute ms-attribute-seq
-void Parser::ParseMicrosoftAttributes() {
+void Parser::ParseMicrosoftAttributes(ParsedAttributes &attrs,
+                                      SourceLocation *endLoc) {
   assert(Tok.is(tok::l_square) && "Not a Microsoft attribute list");
 
   while (Tok.is(tok::l_square)) {
     ConsumeBracket();
     SkipUntil(tok::r_square, true, true);
+    if (endLoc) *endLoc = Tok.getLocation();
     ExpectAndConsume(tok::r_square, diag::err_expected_rsquare);
   }
 }
index 47b60b5f477da2eb2de1bf40184c15aea9b4f27c..92bbbd7bf9ac9c107640fca30f30ee5bcea3e744 100644 (file)
@@ -1522,7 +1522,8 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr,
   
   if (ExprType >= CompoundStmt && Tok.is(tok::l_brace)) {
     Diag(Tok, diag::ext_gnu_statement_expr);
-    StmtResult Stmt(ParseCompoundStatement(0, true));
+    ParsedAttributes attrs;
+    StmtResult Stmt(ParseCompoundStatement(attrs, true));
     ExprType = CompoundStmt;
 
     // If the substmt parsed correctly, build the AST node.
@@ -1741,14 +1742,9 @@ void Parser::ParseBlockId() {
   ParseDeclarator(DeclaratorInfo);
 
   // We do this for: ^ __attribute__((noreturn)) {, as DS has the attributes.
-  DeclaratorInfo.AddAttributes(DS.TakeAttributes(),
-                               SourceLocation());
+  DeclaratorInfo.addAttributes(DS.takeAttributes());
 
-  if (Tok.is(tok::kw___attribute)) {
-    SourceLocation Loc;
-    AttributeList *AttrList = ParseGNUAttributes(&Loc);
-    DeclaratorInfo.AddAttributes(AttrList, Loc);
-  }
+  MaybeParseGNUAttributes(DeclaratorInfo);
 
   // Inform sema that we are starting a block.
   Actions.ActOnBlockArguments(DeclaratorInfo, getCurScope());
@@ -1806,11 +1802,7 @@ ExprResult Parser::ParseBlockLiteralExpression() {
       return ExprError();
     }
 
-    if (Tok.is(tok::kw___attribute)) {
-      SourceLocation Loc;
-      AttributeList *AttrList = ParseGNUAttributes(&Loc);
-      ParamInfo.AddAttributes(AttrList, Loc);
-    }
+    MaybeParseGNUAttributes(ParamInfo);
 
     // Inform sema that we are starting a block.
     Actions.ActOnBlockArguments(ParamInfo, getCurScope());
@@ -1818,7 +1810,8 @@ ExprResult Parser::ParseBlockLiteralExpression() {
     ParseBlockId();
   } else {
     // Otherwise, pretend we saw (void).
-    ParamInfo.AddTypeInfo(DeclaratorChunk::getFunction(true, false,
+    ParamInfo.AddTypeInfo(DeclaratorChunk::getFunction(ParsedAttributes(),
+                                                       true, false,
                                                        SourceLocation(),
                                                        0, 0, 0,
                                                        false, SourceLocation(),
@@ -1827,11 +1820,7 @@ ExprResult Parser::ParseBlockLiteralExpression() {
                                                        ParamInfo),
                           CaretLoc);
 
-    if (Tok.is(tok::kw___attribute)) {
-      SourceLocation Loc;
-      AttributeList *AttrList = ParseGNUAttributes(&Loc);
-      ParamInfo.AddAttributes(AttrList, Loc);
-    }
+    MaybeParseGNUAttributes(ParamInfo);
 
     // Inform sema that we are starting a block.
     Actions.ActOnBlockArguments(ParamInfo, getCurScope());
index 8014dbd50e020c707b8310379d25a3528b15393e..bf4b5f4b166121330310ef1879572e2a3113d5c5 100644 (file)
@@ -810,15 +810,11 @@ bool Parser::ParseCXXCondition(ExprResult &ExprOut,
   }
 
   // If attributes are present, parse them.
-  if (Tok.is(tok::kw___attribute)) {
-    SourceLocation Loc;
-    AttributeList *AttrList = ParseGNUAttributes(&Loc);
-    DeclaratorInfo.AddAttributes(AttrList, Loc);
-  }
+  MaybeParseGNUAttributes(DeclaratorInfo);
 
   // Type-check the declaration itself.
   DeclResult Dcl = Actions.ActOnCXXConditionDeclaration(getCurScope(), 
-                                                                DeclaratorInfo);
+                                                        DeclaratorInfo);
   DeclOut = Dcl.get();
   ExprOut = ExprError();
 
@@ -1729,7 +1725,8 @@ void Parser::ParseDirectNewDeclarator(Declarator &D) {
     first = false;
 
     SourceLocation RLoc = MatchRHSPunctuation(tok::r_square, LLoc);
-    D.AddTypeInfo(DeclaratorChunk::getArray(0, /*static=*/false, /*star=*/false,
+    D.AddTypeInfo(DeclaratorChunk::getArray(0, ParsedAttributes(),
+                                            /*static=*/false, /*star=*/false,
                                             Size.release(), LLoc, RLoc),
                   RLoc);
 
index cd1321ed83248fe2d3a7d17668dc5a979902a18f..c48f6803b01ce3007da5686303b0c31f04e33d22 100644 (file)
@@ -40,10 +40,14 @@ Decl *Parser::ParseObjCAtDirectives() {
   switch (Tok.getObjCKeywordID()) {
   case tok::objc_class:
     return ParseObjCAtClassDeclaration(AtLoc);
-  case tok::objc_interface:
-    return ParseObjCAtInterfaceDeclaration(AtLoc);
-  case tok::objc_protocol:
-    return ParseObjCAtProtocolDeclaration(AtLoc);
+  case tok::objc_interface: {
+    ParsedAttributes attrs;
+    return ParseObjCAtInterfaceDeclaration(AtLoc, attrs);
+  }
+  case tok::objc_protocol: {
+    ParsedAttributes attrs;
+    return ParseObjCAtProtocolDeclaration(AtLoc, attrs);
+  }
   case tok::objc_implementation:
     return ParseObjCAtImplementationDeclaration(AtLoc);
   case tok::objc_end:
@@ -124,8 +128,8 @@ Decl *Parser::ParseObjCAtClassDeclaration(SourceLocation atLoc) {
 ///     __attribute__((unavailable))
 ///     __attribute__((objc_exception)) - used by NSException on 64-bit
 ///
-Decl *Parser::ParseObjCAtInterfaceDeclaration(
-  SourceLocation atLoc, AttributeList *attrList) {
+Decl *Parser::ParseObjCAtInterfaceDeclaration(SourceLocation atLoc,
+                                              ParsedAttributes &attrs) {
   assert(Tok.isObjCAtKeyword(tok::objc_interface) &&
          "ParseObjCAtInterfaceDeclaration(): Expected @interface");
   ConsumeToken(); // the "interface" identifier
@@ -178,7 +182,7 @@ Decl *Parser::ParseObjCAtInterfaceDeclaration(
                                     LAngleLoc, EndProtoLoc))
       return 0;
 
-    if (attrList) // categories don't support attributes.
+    if (!attrs.empty()) // categories don't support attributes.
       Diag(Tok, diag::err_objc_no_attributes_on_category);
 
     Decl *CategoryType =
@@ -230,7 +234,7 @@ Decl *Parser::ParseObjCAtInterfaceDeclaration(
                                      superClassId, superClassLoc,
                                      ProtocolRefs.data(), ProtocolRefs.size(),
                                      ProtocolLocs.data(),
-                                     EndProtoLoc, attrList);
+                                     EndProtoLoc, attrs.getList());
 
   if (Tok.is(tok::l_brace))
     ParseObjCClassInstanceVariables(ClsType, tok::objc_protected, atLoc);
@@ -365,7 +369,8 @@ void Parser::ParseObjCInterfaceDeclList(Decl *interfaceDecl,
 
       // FIXME: as the name implies, this rule allows function definitions.
       // We could pass a flag or check for functions during semantic analysis.
-      allTUVariables.push_back(ParseDeclarationOrFunctionDefinition(0));
+      ParsedAttributes attrs;
+      allTUVariables.push_back(ParseDeclarationOrFunctionDefinition(attrs));
       continue;
     }
 
@@ -830,9 +835,9 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
     ReturnType = ParseObjCTypeName(DSRet, false);
 
   // If attributes exist before the method, parse them.
-  AttributeList *MethodAttrs = 0;
-  if (getLang().ObjC2 && Tok.is(tok::kw___attribute))
-    MethodAttrs = ParseGNUAttributes();
+  ParsedAttributes attrs;
+  if (getLang().ObjC2)
+    MaybeParseGNUAttributes(attrs);
 
   if (Tok.is(tok::code_completion)) {
     Actions.CodeCompleteObjCMethodDecl(getCurScope(), mType == tok::minus, 
@@ -856,8 +861,8 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
   llvm::SmallVector<DeclaratorChunk::ParamInfo, 8> CParamInfo;
   if (Tok.isNot(tok::colon)) {
     // If attributes exist after the method, parse them.
-    if (getLang().ObjC2 && Tok.is(tok::kw___attribute))
-      MethodAttrs = addAttributeLists(MethodAttrs, ParseGNUAttributes());
+    if (getLang().ObjC2)
+      MaybeParseGNUAttributes(attrs);
 
     Selector Sel = PP.getSelectorTable().getNullarySelector(SelIdent);
     Decl *Result
@@ -865,7 +870,7 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
                                           mType, IDecl, DSRet, ReturnType, Sel,
                                           0, 
                                           CParamInfo.data(), CParamInfo.size(),
-                                          MethodAttrs, MethodImplKind);
+                                          attrs.getList(), MethodImplKind);
     PD.complete(Result);
     return Result;
   }
@@ -889,8 +894,11 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
 
     // If attributes exist before the argument name, parse them.
     ArgInfo.ArgAttrs = 0;
-    if (getLang().ObjC2 && Tok.is(tok::kw___attribute))
-      ArgInfo.ArgAttrs = ParseGNUAttributes();
+    if (getLang().ObjC2) {
+      ParsedAttributes attrs;
+      MaybeParseGNUAttributes(attrs);
+      ArgInfo.ArgAttrs = attrs.getList();
+    }
 
     // Code completion for the next piece of the selector.
     if (Tok.is(tok::code_completion)) {
@@ -964,8 +972,8 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
 
   // FIXME: Add support for optional parameter list...
   // If attributes exist after the method, parse them.
-  if (getLang().ObjC2 && Tok.is(tok::kw___attribute))
-    MethodAttrs = addAttributeLists(MethodAttrs, ParseGNUAttributes());
+  if (getLang().ObjC2)
+    MaybeParseGNUAttributes(attrs);
 
   if (KeyIdents.size() == 0)
     return 0;
@@ -976,7 +984,7 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
                                         mType, IDecl, DSRet, ReturnType, Sel,
                                         &ArgInfos[0], 
                                         CParamInfo.data(), CParamInfo.size(),
-                                        MethodAttrs,
+                                        attrs.getList(),
                                         MethodImplKind, isVariadic);
   PD.complete(Result);
   return Result;
@@ -1184,7 +1192,7 @@ void Parser::ParseObjCClassInstanceVariables(Decl *interfaceDecl,
 ///   identifier-list ;": objc-interface-decl-list may not start with a
 ///   semicolon in the first alternative if objc-protocol-refs are omitted.
 Decl *Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc,
-                                                      AttributeList *attrList) {
+                                             ParsedAttributes &attrs) {
   assert(Tok.isObjCAtKeyword(tok::objc_protocol) &&
          "ParseObjCAtProtocolDeclaration(): Expected @protocol");
   ConsumeToken(); // the "protocol" identifier
@@ -1206,7 +1214,7 @@ Decl *Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc,
     IdentifierLocPair ProtoInfo(protocolName, nameLoc);
     ConsumeToken();
     return Actions.ActOnForwardProtocolDeclaration(AtLoc, &ProtoInfo, 1,
-                                                   attrList);
+                                                   attrs.getList());
   }
 
   if (Tok.is(tok::comma)) { // list of forward declarations.
@@ -1235,7 +1243,7 @@ Decl *Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc,
     return Actions.ActOnForwardProtocolDeclaration(AtLoc,
                                                    &ProtocolRefs[0],
                                                    ProtocolRefs.size(),
-                                                   attrList);
+                                                   attrs.getList());
   }
 
   // Last, and definitely not least, parse a protocol declaration.
@@ -1253,7 +1261,7 @@ Decl *Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc,
                                         ProtocolRefs.data(),
                                         ProtocolRefs.size(),
                                         ProtocolLocs.data(),
-                                        EndProtoLoc, attrList);
+                                        EndProtoLoc, attrs.getList());
   ParseObjCInterfaceDeclList(ProtoType, tok::objc_protocol);
   return ProtoType;
 }
index 437a950cd94a7bf6864007e0e85741a3c54254cb..dafe3737783584cceb5852924cb0728e65bb29f6 100644 (file)
@@ -81,10 +81,8 @@ Parser::ParseStatementOrDeclaration(StmtVector &Stmts, bool OnlyStatement) {
   
   ParenBraceBracketBalancer BalancerRAIIObj(*this);
 
-  CXX0XAttributeList Attr;
-  if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier())
-    Attr = ParseCXX0XAttributes();
-  AttributeList *AttrList = Attr.AttrList;
+  ParsedAttributesWithRange attrs;
+  MaybeParseCXX0XAttributes(attrs);
 
   // Cases in this switch statement should fall through if the parser expects
   // the token to end in a semicolon (in which case SemiError should be set),
@@ -106,7 +104,7 @@ Parser::ParseStatementOrDeclaration(StmtVector &Stmts, bool OnlyStatement) {
   case tok::identifier:
     if (NextToken().is(tok::colon)) { // C99 6.8.1: labeled-statement
       // identifier ':' statement
-      return ParseLabeledStatement(AttrList);
+      return ParseLabeledStatement(attrs);
     }
     // PASS THROUGH.
 
@@ -114,7 +112,7 @@ Parser::ParseStatementOrDeclaration(StmtVector &Stmts, bool OnlyStatement) {
     if ((getLang().CPlusPlus || !OnlyStatement) && isDeclarationStatement()) {
       SourceLocation DeclStart = Tok.getLocation(), DeclEnd;
       DeclGroupPtrTy Decl = ParseDeclaration(Stmts, Declarator::BlockContext,
-                                             DeclEnd, Attr);
+                                             DeclEnd, attrs);
       return Actions.ActOnDeclStmt(Decl, DeclStart, DeclEnd);
     }
 
@@ -141,52 +139,50 @@ Parser::ParseStatementOrDeclaration(StmtVector &Stmts, bool OnlyStatement) {
   }
 
   case tok::kw_case:                // C99 6.8.1: labeled-statement
-    return ParseCaseStatement(AttrList);
+    return ParseCaseStatement(attrs);
   case tok::kw_default:             // C99 6.8.1: labeled-statement
-    return ParseDefaultStatement(AttrList);
+    return ParseDefaultStatement(attrs);
 
   case tok::l_brace:                // C99 6.8.2: compound-statement
-    return ParseCompoundStatement(AttrList);
+    return ParseCompoundStatement(attrs);
   case tok::semi: {                 // C99 6.8.3p3: expression[opt] ';'
     bool LeadingEmptyMacro = Tok.hasLeadingEmptyMacro();
     return Actions.ActOnNullStmt(ConsumeToken(), LeadingEmptyMacro);
   }
 
   case tok::kw_if:                  // C99 6.8.4.1: if-statement
-    return ParseIfStatement(AttrList);
+    return ParseIfStatement(attrs);
   case tok::kw_switch:              // C99 6.8.4.2: switch-statement
-    return ParseSwitchStatement(AttrList);
+    return ParseSwitchStatement(attrs);
 
   case tok::kw_while:               // C99 6.8.5.1: while-statement
-    return ParseWhileStatement(AttrList);
+    return ParseWhileStatement(attrs);
   case tok::kw_do:                  // C99 6.8.5.2: do-statement
-    Res = ParseDoStatement(AttrList);
+    Res = ParseDoStatement(attrs);
     SemiError = "do/while";
     break;
   case tok::kw_for:                 // C99 6.8.5.3: for-statement
-    return ParseForStatement(AttrList);
+    return ParseForStatement(attrs);
 
   case tok::kw_goto:                // C99 6.8.6.1: goto-statement
-    Res = ParseGotoStatement(AttrList);
+    Res = ParseGotoStatement(attrs);
     SemiError = "goto";
     break;
   case tok::kw_continue:            // C99 6.8.6.2: continue-statement
-    Res = ParseContinueStatement(AttrList);
+    Res = ParseContinueStatement(attrs);
     SemiError = "continue";
     break;
   case tok::kw_break:               // C99 6.8.6.3: break-statement
-    Res = ParseBreakStatement(AttrList);
+    Res = ParseBreakStatement(attrs);
     SemiError = "break";
     break;
   case tok::kw_return:              // C99 6.8.6.4: return-statement
-    Res = ParseReturnStatement(AttrList);
+    Res = ParseReturnStatement(attrs);
     SemiError = "return";
     break;
 
   case tok::kw_asm: {
-    if (Attr.HasAttr)
-      Diag(Attr.Range.getBegin(), diag::err_attributes_not_allowed)
-        << Attr.Range;
+    ProhibitAttributes(attrs);
     bool msAsm = false;
     Res = ParseAsmStatement(msAsm);
     Res = Actions.ActOnFinishFullStmt(Res.get());
@@ -196,7 +192,7 @@ Parser::ParseStatementOrDeclaration(StmtVector &Stmts, bool OnlyStatement) {
   }
 
   case tok::kw_try:                 // C++ 15: try-block
-    return ParseCXXTryBlock(AttrList);
+    return ParseCXXTryBlock(attrs);
   }
 
   // If we reached this code, the statement must end in a semicolon.
@@ -220,7 +216,7 @@ Parser::ParseStatementOrDeclaration(StmtVector &Stmts, bool OnlyStatement) {
 ///         identifier ':' statement
 /// [GNU]   identifier ':' attributes[opt] statement
 ///
-StmtResult Parser::ParseLabeledStatement(AttributeList *Attr) {
+StmtResult Parser::ParseLabeledStatement(ParsedAttributes &attrs) {
   assert(Tok.is(tok::identifier) && Tok.getIdentifierInfo() &&
          "Not an identifier!");
 
@@ -233,8 +229,7 @@ StmtResult Parser::ParseLabeledStatement(AttributeList *Attr) {
   SourceLocation ColonLoc = ConsumeToken();
 
   // Read label attributes, if present.
-  if (Tok.is(tok::kw___attribute))
-    Attr = addAttributeLists(Attr, ParseGNUAttributes());
+  MaybeParseGNUAttributes(attrs);
 
   StmtResult SubStmt(ParseStatement());
 
@@ -244,7 +239,7 @@ StmtResult Parser::ParseLabeledStatement(AttributeList *Attr) {
 
   return Actions.ActOnLabelStmt(IdentTok.getLocation(),
                                 IdentTok.getIdentifierInfo(),
-                                ColonLoc, SubStmt.get(), Attr);
+                                ColonLoc, SubStmt.get(), attrs.getList());
 }
 
 /// ParseCaseStatement
@@ -252,7 +247,7 @@ StmtResult Parser::ParseLabeledStatement(AttributeList *Attr) {
 ///         'case' constant-expression ':' statement
 /// [GNU]   'case' constant-expression '...' constant-expression ':' statement
 ///
-StmtResult Parser::ParseCaseStatement(AttributeList *Attr) {
+StmtResult Parser::ParseCaseStatement(ParsedAttributes &attrs) {
   assert(Tok.is(tok::kw_case) && "Not a case stmt!");
   // FIXME: Use attributes?
 
@@ -380,7 +375,7 @@ StmtResult Parser::ParseCaseStatement(AttributeList *Attr) {
 ///         'default' ':' statement
 /// Note that this does not parse the 'statement' at the end.
 ///
-StmtResult Parser::ParseDefaultStatement(AttributeList *Attr) {
+StmtResult Parser::ParseDefaultStatement(ParsedAttributes &attrs) {
   //FIXME: Use attributes?
 
   assert(Tok.is(tok::kw_default) && "Not a default stmt!");
@@ -438,7 +433,7 @@ StmtResult Parser::ParseDefaultStatement(AttributeList *Attr) {
 /// [OMP]   barrier-directive
 /// [OMP]   flush-directive
 ///
-StmtResult Parser::ParseCompoundStatement(AttributeList *Attr,
+StmtResult Parser::ParseCompoundStatement(ParsedAttributes &attrs,
                                                         bool isStmtExpr) {
   //FIXME: Use attributes?
 
@@ -482,9 +477,8 @@ StmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) {
       while (Tok.is(tok::kw___extension__))
         ConsumeToken();
 
-      CXX0XAttributeList Attr;
-      if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier())
-        Attr = ParseCXX0XAttributes();
+      ParsedAttributesWithRange attrs;
+      MaybeParseCXX0XAttributes(attrs);
 
       // If this is the start of a declaration, parse it as such.
       if (isDeclarationStatement()) {
@@ -495,7 +489,7 @@ StmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) {
         SourceLocation DeclStart = Tok.getLocation(), DeclEnd;
         DeclGroupPtrTy Res = ParseDeclaration(Stmts,
                                               Declarator::BlockContext, DeclEnd,
-                                              Attr);
+                                              attrs);
         R = Actions.ActOnDeclStmt(Res, DeclStart, DeclEnd);
       } else {
         // Otherwise this was a unary __extension__ marker.
@@ -585,7 +579,7 @@ bool Parser::ParseParenExprOrCondition(ExprResult &ExprResult,
 /// [C++]   'if' '(' condition ')' statement
 /// [C++]   'if' '(' condition ')' statement 'else' statement
 ///
-StmtResult Parser::ParseIfStatement(AttributeList *Attr) {
+StmtResult Parser::ParseIfStatement(ParsedAttributes &attrs) {
   // FIXME: Use attributes?
 
   assert(Tok.is(tok::kw_if) && "Not an if stmt!");
@@ -707,7 +701,7 @@ StmtResult Parser::ParseIfStatement(AttributeList *Attr) {
 ///       switch-statement:
 ///         'switch' '(' expression ')' statement
 /// [C++]   'switch' '(' condition ')' statement
-StmtResult Parser::ParseSwitchStatement(AttributeList *Attr) {
+StmtResult Parser::ParseSwitchStatement(ParsedAttributes &attrs) {
   // FIXME: Use attributes?
 
   assert(Tok.is(tok::kw_switch) && "Not a switch stmt!");
@@ -792,7 +786,7 @@ StmtResult Parser::ParseSwitchStatement(AttributeList *Attr) {
 ///       while-statement: [C99 6.8.5.1]
 ///         'while' '(' expression ')' statement
 /// [C++]   'while' '(' condition ')' statement
-StmtResult Parser::ParseWhileStatement(AttributeList *Attr) {
+StmtResult Parser::ParseWhileStatement(ParsedAttributes &attrs) {
   // FIXME: Use attributes?
 
   assert(Tok.is(tok::kw_while) && "Not a while stmt!");
@@ -866,7 +860,7 @@ StmtResult Parser::ParseWhileStatement(AttributeList *Attr) {
 ///       do-statement: [C99 6.8.5.2]
 ///         'do' statement 'while' '(' expression ')' ';'
 /// Note: this lets the caller parse the end ';'.
-StmtResult Parser::ParseDoStatement(AttributeList *Attr) {
+StmtResult Parser::ParseDoStatement(ParsedAttributes &attrs) {
   // FIXME: Use attributes?
 
   assert(Tok.is(tok::kw_do) && "Not a do stmt!");
@@ -942,7 +936,7 @@ StmtResult Parser::ParseDoStatement(AttributeList *Attr) {
 /// [C++]   expression-statement
 /// [C++]   simple-declaration
 ///
-StmtResult Parser::ParseForStatement(AttributeList *Attr) {
+StmtResult Parser::ParseForStatement(ParsedAttributes &attrs) {
   // FIXME: Use attributes?
 
   assert(Tok.is(tok::kw_for) && "Not a for stmt!");
@@ -1007,14 +1001,13 @@ StmtResult Parser::ParseForStatement(AttributeList *Attr) {
     if (!C99orCXXorObjC)   // Use of C99-style for loops in C90 mode?
       Diag(Tok, diag::ext_c99_variable_decl_in_for_loop);
 
-    AttributeList *AttrList = 0;
-    if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier())
-      AttrList = ParseCXX0XAttributes().AttrList;
+    ParsedAttributesWithRange attrs;
+    MaybeParseCXX0XAttributes(attrs);
 
     SourceLocation DeclStart = Tok.getLocation(), DeclEnd;
     StmtVector Stmts(Actions);
     DeclGroupPtrTy DG = ParseSimpleDeclaration(Stmts, Declarator::ForContext, 
-                                               DeclEnd, AttrList, false);
+                                               DeclEnd, attrs, false);
     FirstPart = Actions.ActOnDeclStmt(DG, DeclStart, Tok.getLocation());
 
     if (Tok.is(tok::semi)) {  // for (int x = 4;
@@ -1141,7 +1134,7 @@ StmtResult Parser::ParseForStatement(AttributeList *Attr) {
 ///
 /// Note: this lets the caller parse the end ';'.
 ///
-StmtResult Parser::ParseGotoStatement(AttributeList *Attr) {
+StmtResult Parser::ParseGotoStatement(ParsedAttributes &attrs) {
   // FIXME: Use attributes?
 
   assert(Tok.is(tok::kw_goto) && "Not a goto stmt!");
@@ -1176,7 +1169,7 @@ StmtResult Parser::ParseGotoStatement(AttributeList *Attr) {
 ///
 /// Note: this lets the caller parse the end ';'.
 ///
-StmtResult Parser::ParseContinueStatement(AttributeList *Attr) {
+StmtResult Parser::ParseContinueStatement(ParsedAttributes &attrs) {
   // FIXME: Use attributes?
 
   SourceLocation ContinueLoc = ConsumeToken();  // eat the 'continue'.
@@ -1189,7 +1182,7 @@ StmtResult Parser::ParseContinueStatement(AttributeList *Attr) {
 ///
 /// Note: this lets the caller parse the end ';'.
 ///
-StmtResult Parser::ParseBreakStatement(AttributeList *Attr) {
+StmtResult Parser::ParseBreakStatement(ParsedAttributes &attrs) {
   // FIXME: Use attributes?
 
   SourceLocation BreakLoc = ConsumeToken();  // eat the 'break'.
@@ -1199,7 +1192,7 @@ StmtResult Parser::ParseBreakStatement(AttributeList *Attr) {
 /// ParseReturnStatement
 ///       jump-statement:
 ///         'return' expression[opt] ';'
-StmtResult Parser::ParseReturnStatement(AttributeList *Attr) {
+StmtResult Parser::ParseReturnStatement(ParsedAttributes &attrs) {
   // FIXME: Use attributes?
 
   assert(Tok.is(tok::kw_return) && "Not a return stmt!");
@@ -1521,7 +1514,7 @@ Decl *Parser::ParseFunctionTryBlock(Decl *Decl) {
 ///       try-block:
 ///         'try' compound-statement handler-seq
 ///
-StmtResult Parser::ParseCXXTryBlock(AttributeList* Attr) {
+StmtResult Parser::ParseCXXTryBlock(ParsedAttributes &attrs) {
   // FIXME: Add attributes?
 
   assert(Tok.is(tok::kw_try) && "Expected 'try'");
@@ -1546,16 +1539,15 @@ StmtResult Parser::ParseCXXTryBlockCommon(SourceLocation TryLoc) {
   if (Tok.isNot(tok::l_brace))
     return StmtError(Diag(Tok, diag::err_expected_lbrace));
   // FIXME: Possible draft standard bug: attribute-specifier should be allowed?
-  StmtResult TryBlock(ParseCompoundStatement(0));
+  ParsedAttributesWithRange attrs;
+  StmtResult TryBlock(ParseCompoundStatement(attrs));
   if (TryBlock.isInvalid())
     return move(TryBlock);
 
   StmtVector Handlers(Actions);
-  if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier()) {
-    CXX0XAttributeList Attr = ParseCXX0XAttributes();
-    Diag(Attr.Range.getBegin(), diag::err_attributes_not_allowed)
-      << Attr.Range;
-  }
+  MaybeParseCXX0XAttributes(attrs);
+  ProhibitAttributes(attrs);
+
   if (Tok.isNot(tok::kw_catch))
     return StmtError(Diag(Tok, diag::err_expected_catch));
   while (Tok.is(tok::kw_catch)) {
@@ -1616,7 +1608,8 @@ StmtResult Parser::ParseCXXCatchBlock() {
     return StmtError(Diag(Tok, diag::err_expected_lbrace));
 
   // FIXME: Possible draft standard bug: attribute-specifier should be allowed?
-  StmtResult Block(ParseCompoundStatement(0));
+  ParsedAttributes attrs;
+  StmtResult Block(ParseCompoundStatement(attrs));
   if (Block.isInvalid())
     return move(Block);
 
index d38d0599ac253427dca31acddab8c175af27a04b..afa2cc62f9fb879ef7f6a7f85dbcf7f2d894cc63 100644 (file)
@@ -196,20 +196,18 @@ Parser::ParseSingleDeclarationAfterTemplate(
     return 0;
   }
 
-  CXX0XAttributeList PrefixAttrs;
-  if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier())
-    PrefixAttrs = ParseCXX0XAttributes();
+  ParsedAttributesWithRange prefixAttrs;
+  MaybeParseCXX0XAttributes(prefixAttrs);
 
   if (Tok.is(tok::kw_using))
     return ParseUsingDirectiveOrDeclaration(Context, TemplateInfo, DeclEnd,
-                                            PrefixAttrs);
+                                            prefixAttrs);
 
   // Parse the declaration specifiers, stealing the accumulated
   // diagnostics from the template parameters.
   ParsingDeclSpec DS(DiagsFromTParams);
 
-  if (PrefixAttrs.HasAttr)
-    DS.AddAttributes(PrefixAttrs.AttrList);
+  DS.takeAttributesFrom(prefixAttrs);
 
   ParseDeclarationSpecifiers(DS, TemplateInfo, AS,
                              getDeclSpecContextFromDeclaratorContext(Context));
index fc57b4086b0bf3cdd9bf43276b1cc7abf6727fc6..c6e6784f6c20200fe3d76f76b72e85aa9d330437 100644 (file)
@@ -1151,8 +1151,8 @@ Parser::TPResult Parser::TryParseParameterDeclarationClause() {
       return TPResult::True(); // '...' is a sign of a function declarator.
     }
 
-    if (getLang().Microsoft && Tok.is(tok::l_square))
-      ParseMicrosoftAttributes();
+    ParsedAttributes attrs;
+    MaybeParseMicrosoftAttributes(attrs);
 
     // decl-specifier-seq
     TPResult TPR = TryParseDeclarationSpecifier();
index f79a2f68c72758a9c6dc72364c9129acdf09f083..2a569b58d8c42eee027d9ee507be586c9d4c3778 100644 (file)
@@ -402,13 +402,11 @@ bool Parser::ParseTopLevelDecl(DeclGroupPtrTy &Result) {
     return true;
   }
 
-  CXX0XAttributeList Attr;
-  if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier())
-    Attr = ParseCXX0XAttributes();
-  if (getLang().Microsoft && Tok.is(tok::l_square))
-    ParseMicrosoftAttributes();
+  ParsedAttributesWithRange attrs;
+  MaybeParseCXX0XAttributes(attrs);
+  MaybeParseMicrosoftAttributes(attrs);
   
-  Result = ParseExternalDeclaration(Attr);
+  Result = ParseExternalDeclaration(attrs);
   return false;
 }
 
@@ -449,8 +447,9 @@ void Parser::ParseTranslationUnit() {
 ///           ';'
 ///
 /// [C++0x/GNU] 'extern' 'template' declaration
-Parser::DeclGroupPtrTy Parser::ParseExternalDeclaration(CXX0XAttributeList Attr,
-                                                        ParsingDeclSpec *DS) {
+Parser::DeclGroupPtrTy
+Parser::ParseExternalDeclaration(ParsedAttributesWithRange &attrs,
+                                 ParsingDeclSpec *DS) {
   ParenBraceBracketBalancer BalancerRAIIObj(*this);
   
   Decl *SingleDecl = 0;
@@ -474,12 +473,10 @@ Parser::DeclGroupPtrTy Parser::ParseExternalDeclaration(CXX0XAttributeList Attr,
     // __extension__ silences extension warnings in the subexpression.
     ExtensionRAIIObject O(Diags);  // Use RAII to do this.
     ConsumeToken();
-    return ParseExternalDeclaration(Attr);
+    return ParseExternalDeclaration(attrs);
   }
   case tok::kw_asm: {
-    if (Attr.HasAttr)
-      Diag(Attr.Range.getBegin(), diag::err_attributes_not_allowed)
-        << Attr.Range;
+    ProhibitAttributes(attrs);
 
     ExprResult Result(ParseSimpleAsm());
 
@@ -511,7 +508,7 @@ Parser::DeclGroupPtrTy Parser::ParseExternalDeclaration(CXX0XAttributeList Attr,
                                    ObjCImpDecl? Sema::PCC_ObjCImplementation
                                               : Sema::PCC_Namespace);
     ConsumeCodeCompletionToken();
-    return ParseExternalDeclaration(Attr);
+    return ParseExternalDeclaration(attrs);
   case tok::kw_using:
   case tok::kw_namespace:
   case tok::kw_typedef:
@@ -522,7 +519,7 @@ Parser::DeclGroupPtrTy Parser::ParseExternalDeclaration(CXX0XAttributeList Attr,
     {
       SourceLocation DeclEnd;
       StmtVector Stmts(Actions);
-      return ParseDeclaration(Stmts, Declarator::FileContext, DeclEnd, Attr);
+      return ParseDeclaration(Stmts, Declarator::FileContext, DeclEnd, attrs);
     }
 
   case tok::kw_static:
@@ -533,7 +530,7 @@ Parser::DeclGroupPtrTy Parser::ParseExternalDeclaration(CXX0XAttributeList Attr,
         << 0;
       SourceLocation DeclEnd;
       StmtVector Stmts(Actions);
-      return ParseDeclaration(Stmts, Declarator::FileContext, DeclEnd, Attr);  
+      return ParseDeclaration(Stmts, Declarator::FileContext, DeclEnd, attrs);  
     }
     goto dont_know;
       
@@ -545,7 +542,7 @@ Parser::DeclGroupPtrTy Parser::ParseExternalDeclaration(CXX0XAttributeList Attr,
       if (NextKind == tok::kw_namespace) {
         SourceLocation DeclEnd;
         StmtVector Stmts(Actions);
-        return ParseDeclaration(Stmts, Declarator::FileContext, DeclEnd, Attr);
+        return ParseDeclaration(Stmts, Declarator::FileContext, DeclEnd, attrs);
       }
       
       // Parse (then ignore) 'inline' prior to a template instantiation. This is
@@ -555,7 +552,7 @@ Parser::DeclGroupPtrTy Parser::ParseExternalDeclaration(CXX0XAttributeList Attr,
           << 1;
         SourceLocation DeclEnd;
         StmtVector Stmts(Actions);
-        return ParseDeclaration(Stmts, Declarator::FileContext, DeclEnd, Attr);  
+        return ParseDeclaration(Stmts, Declarator::FileContext, DeclEnd, attrs);  
       }
     }
     goto dont_know;
@@ -575,10 +572,12 @@ Parser::DeclGroupPtrTy Parser::ParseExternalDeclaration(CXX0XAttributeList Attr,
   default:
   dont_know:
     // We can't tell whether this is a function-definition or declaration yet.
-    if (DS)
-      return ParseDeclarationOrFunctionDefinition(*DS, Attr.AttrList);
-    else
-      return ParseDeclarationOrFunctionDefinition(Attr.AttrList);
+    if (DS) {
+      DS->takeAttributesFrom(attrs);
+      return ParseDeclarationOrFunctionDefinition(*DS);
+    } else {
+      return ParseDeclarationOrFunctionDefinition(attrs);
+    }
   }
 
   // This routine returns a DeclGroup, if the thing we parsed only contains a
@@ -632,12 +631,8 @@ bool Parser::isStartOfFunctionDefinition(const ParsingDeclarator &Declarator) {
 ///
 Parser::DeclGroupPtrTy
 Parser::ParseDeclarationOrFunctionDefinition(ParsingDeclSpec &DS,
-                                             AttributeList *Attr,
                                              AccessSpecifier AS) {
   // Parse the common declaration-specifiers piece.
-  if (Attr)
-    DS.AddAttributes(Attr);
-
   ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS, DSC_top_level);
 
   // C99 6.7.2.3p6: Handle "struct-or-union identifier;", "enum { X };"
@@ -690,10 +685,11 @@ Parser::ParseDeclarationOrFunctionDefinition(ParsingDeclSpec &DS,
 }
 
 Parser::DeclGroupPtrTy
-Parser::ParseDeclarationOrFunctionDefinition(AttributeList *Attr,
+Parser::ParseDeclarationOrFunctionDefinition(ParsedAttributes &attrs,
                                              AccessSpecifier AS) {
   ParsingDeclSpec DS(*this);
-  return ParseDeclarationOrFunctionDefinition(DS, Attr, AS);
+  DS.takeAttributesFrom(attrs);
+  return ParseDeclarationOrFunctionDefinition(DS, AS);
 }
 
 /// ParseFunctionDefinition - We parsed and verified that the specified
@@ -835,11 +831,7 @@ void Parser::ParseKNRParamDeclarations(Declarator &D) {
     // Handle the full declarator list.
     while (1) {
       // If attributes are present, parse them.
-      if (Tok.is(tok::kw___attribute)) {
-        SourceLocation Loc;
-        AttributeList *AttrList = ParseGNUAttributes(&Loc);
-        ParmDeclarator.AddAttributes(AttrList, Loc);
-      }
+      MaybeParseGNUAttributes(ParmDeclarator);
 
       // Ask the actions module to compute the type for this declarator.
       Decl *Param =
index 6aa9690476aab33d37fbdafa491ba3bcc73086c4..6e0a3321048a9be5005cf284e0464bc8dc8518da 100644 (file)
@@ -21,10 +21,10 @@ AttributeList::AttributeList(llvm::BumpPtrAllocator &Alloc,
                              IdentifierInfo *sName, SourceLocation sLoc,
                              IdentifierInfo *pName, SourceLocation pLoc,
                              Expr **ExprList, unsigned numArgs,
-                             AttributeList *n, bool declspec, bool cxx0x)
+                             bool declspec, bool cxx0x)
   : AttrName(aName), AttrLoc(aLoc), ScopeName(sName),
     ScopeLoc(sLoc),
-    ParmName(pName), ParmLoc(pLoc), NumArgs(numArgs), Next(n),
+    ParmName(pName), ParmLoc(pLoc), NumArgs(numArgs), Next(0),
     DeclspecAttribute(declspec), CXX0XAttribute(cxx0x), Invalid(false) {
 
   if (numArgs == 0)
index 5304193b66463ae2817788222fb2b5bf8be82795..4afdc24275fb248873370c08573d5e2ff0410376 100644 (file)
@@ -46,7 +46,8 @@ void UnqualifiedId::setConstructorTemplateId(TemplateIdAnnotation *TemplateId) {
 
 /// DeclaratorChunk::getFunction - Return a DeclaratorChunk for a function.
 /// "TheDeclarator" is the declarator that this will be added to.
-DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto, bool isVariadic,
+DeclaratorChunk DeclaratorChunk::getFunction(const ParsedAttributes &attrs,
+                                             bool hasProto, bool isVariadic,
                                              SourceLocation EllipsisLoc,
                                              ParamInfo *ArgInfo,
                                              unsigned NumArgs,
@@ -65,6 +66,7 @@ DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto, bool isVariadic,
   I.Kind                 = Function;
   I.Loc                  = LPLoc;
   I.EndLoc               = RPLoc;
+  I.Fun.AttrList         = attrs.getList();
   I.Fun.hasPrototype     = hasProto;
   I.Fun.isVariadic       = isVariadic;
   I.Fun.EllipsisLoc      = EllipsisLoc.getRawEncoding();
@@ -483,7 +485,7 @@ void DeclSpec::SaveWrittenBuiltinSpecs() {
   writtenBS.Type = getTypeSpecType();
   // Search the list of attributes for the presence of a mode attribute.
   writtenBS.ModeAttr = false;
-  AttributeList* attrs = getAttributes();
+  AttributeList* attrs = getAttributes().getList();
   while (attrs) {
     if (attrs->getKind() == AttributeList::AT_mode) {
       writtenBS.ModeAttr = true;
index d596649479011920bb78c414c87a1192e3bdcd57..62262bc60b5361c12ee6c2675eb3ae5be292ff62 100644 (file)
@@ -1642,7 +1642,7 @@ Decl *Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS,
   }
          
   if (RecordDecl *Record = dyn_cast_or_null<RecordDecl>(Tag)) {
-    ProcessDeclAttributeList(S, Record, DS.getAttributes());
+    ProcessDeclAttributeList(S, Record, DS.getAttributes().getList());
     
     if (!Record->getDeclName() && Record->isDefinition() &&
         DS.getStorageClassSpec() != DeclSpec::SCS_typedef) {
@@ -5553,7 +5553,8 @@ NamedDecl *Sema::ImplicitlyDefineFunction(SourceLocation Loc,
   (void)Error; // Silence warning.
   assert(!Error && "Error setting up implicit decl!");
   Declarator D(DS, Declarator::BlockContext);
-  D.AddTypeInfo(DeclaratorChunk::getFunction(false, false, SourceLocation(), 0,
+  D.AddTypeInfo(DeclaratorChunk::getFunction(ParsedAttributes(),
+                                             false, false, SourceLocation(), 0,
                                              0, 0, false, SourceLocation(),
                                              false, 0,0,0, Loc, Loc, D),
                 SourceLocation());
index 06cb42ec0e04e143d0a5fce1f8110f2350f951bf..6977a33ac4aecd3b459562f8b64f19b7e9cd87c4 100644 (file)
@@ -2808,7 +2808,7 @@ void Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD) {
   }
 
   // Apply decl attributes from the DeclSpec if present.
-  if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes())
+  if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes().getList())
     ProcessDeclAttributeList(S, D, Attrs);
 
   // Walk the declarator structure, applying decl attributes that were in a type
index 46ec0fe10914dd004c9bee56b6c852559bfd312a..c70d5befbbf3f3d9dcfacebc8ea7b3e8a808068b 100644 (file)
@@ -402,7 +402,7 @@ static QualType ConvertDeclSpecToType(Sema &TheSema,
 
   // See if there are any attributes on the declspec that apply to the type (as
   // opposed to the decl).
-  if (const AttributeList *AL = DS.getAttributes())
+  if (const AttributeList *AL = DS.getAttributes().getList())
     ProcessTypeAttributeList(TheSema, Result, true, AL, Delayed);
 
   // Apply const/volatile/restrict qualifiers to T.