AttributeList de-listifying:

Basically, "AttributeList" loses all list-like mechanisms, ParsedAttributes is
switched to use a TinyPtrVector (and a ParsedAttributesView is created to
have a non-allocating attributes list). DeclaratorChunk gets the later kind,
Declarator/DeclSpec keep ParsedAttributes.

Iterators are added to the ParsedAttribute types so that for-loops work.

llvm-svn: 336945
diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp
index a969a0f..166f7a8 100644
--- a/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/clang/lib/Parse/ParseDeclCXX.cpp
@@ -183,10 +183,9 @@
   ParseScope NamespaceScope(this, Scope::DeclScope);
 
   UsingDirectiveDecl *ImplicitUsingDirectiveDecl = nullptr;
-  Decl *NamespcDecl =
-    Actions.ActOnStartNamespaceDef(getCurScope(), InlineLoc, NamespaceLoc,
-                                   IdentLoc, Ident, T.getOpenLocation(), 
-                                   attrs.getList(), ImplicitUsingDirectiveDecl);
+  Decl *NamespcDecl = Actions.ActOnStartNamespaceDef(
+      getCurScope(), InlineLoc, NamespaceLoc, IdentLoc, Ident,
+      T.getOpenLocation(), attrs, ImplicitUsingDirectiveDecl);
 
   PrettyDeclStackTraceEntry CrashInfo(Actions.Context, NamespcDecl,
                                       NamespaceLoc, "parsing namespace");
@@ -233,11 +232,10 @@
   // desugaring it here.
   ParseScope NamespaceScope(this, Scope::DeclScope);
   UsingDirectiveDecl *ImplicitUsingDirectiveDecl = nullptr;
-  Decl *NamespcDecl =
-    Actions.ActOnStartNamespaceDef(getCurScope(), SourceLocation(),
-                                   NamespaceLoc[index], IdentLoc[index],
-                                   Ident[index], Tracker.getOpenLocation(), 
-                                   attrs.getList(), ImplicitUsingDirectiveDecl);
+  Decl *NamespcDecl = Actions.ActOnStartNamespaceDef(
+      getCurScope(), SourceLocation(), NamespaceLoc[index], IdentLoc[index],
+      Ident[index], Tracker.getOpenLocation(), attrs,
+      ImplicitUsingDirectiveDecl);
   assert(!ImplicitUsingDirectiveDecl && 
          "nested namespace definition cannot define anonymous namespace");
 
@@ -543,7 +541,7 @@
     SkipUntil(tok::semi);
 
   return Actions.ActOnUsingDirective(getCurScope(), UsingLoc, NamespcLoc, SS,
-                                     IdentLoc, NamespcName, attrs.getList());
+                                     IdentLoc, NamespcName, attrs);
 }
 
 /// Parse a using-declarator (or the identifier in a C++11 alias-declaration).
@@ -711,7 +709,7 @@
 
       Decl *UD = Actions.ActOnUsingDeclaration(getCurScope(), AS, UsingLoc,
                                                D.TypenameLoc, D.SS, D.Name,
-                                               D.EllipsisLoc, Attrs.getList());
+                                               D.EllipsisLoc, Attrs);
       if (UD)
         DeclsInGroup.push_back(UD);
     }
@@ -813,8 +811,8 @@
     TemplateParams ? TemplateParams->data() : nullptr,
     TemplateParams ? TemplateParams->size() : 0);
   return Actions.ActOnAliasDeclaration(getCurScope(), AS, TemplateParamsArg,
-                                       UsingLoc, D.Name, Attrs.getList(),
-                                       TypeAlias, DeclFromDeclSpec);
+                                       UsingLoc, D.Name, Attrs, TypeAlias,
+                                       DeclFromDeclSpec);
 }
 
 /// ParseStaticAssertDeclaration - Parse C++0x or C11 static_assert-declaration.
@@ -1752,24 +1750,16 @@
       // This is an explicit instantiation of a class template.
       ProhibitAttributes(attrs);
 
-      TagOrTempResult
-        = Actions.ActOnExplicitInstantiation(getCurScope(),
-                                             TemplateInfo.ExternLoc,
-                                             TemplateInfo.TemplateLoc,
-                                             TagType,
-                                             StartLoc,
-                                             SS,
-                                             TemplateId->Template,
-                                             TemplateId->TemplateNameLoc,
-                                             TemplateId->LAngleLoc,
-                                             TemplateArgsPtr,
-                                             TemplateId->RAngleLoc,
-                                             attrs.getList());
+      TagOrTempResult = Actions.ActOnExplicitInstantiation(
+          getCurScope(), TemplateInfo.ExternLoc, TemplateInfo.TemplateLoc,
+          TagType, StartLoc, SS, TemplateId->Template,
+          TemplateId->TemplateNameLoc, TemplateId->LAngleLoc, TemplateArgsPtr,
+          TemplateId->RAngleLoc, attrs);
 
-    // Friend template-ids are treated as references unless
-    // they have template headers, in which case they're ill-formed
-    // (FIXME: "template <class T> friend class A<T>::B<int>;").
-    // We diagnose this error in ActOnClassTemplateSpecialization.
+      // Friend template-ids are treated as references unless
+      // they have template headers, in which case they're ill-formed
+      // (FIXME: "template <class T> friend class A<T>::B<int>;").
+      // We diagnose this error in ActOnClassTemplateSpecialization.
     } else if (TUK == Sema::TUK_Reference ||
                (TUK == Sema::TUK_Friend &&
                 TemplateInfo.Kind == ParsedTemplateInfo::NonTemplate)) {
@@ -1825,7 +1815,7 @@
       // Build the class template specialization.
       TagOrTempResult = Actions.ActOnClassTemplateSpecialization(
           getCurScope(), TagType, TUK, StartLoc, DS.getModulePrivateSpecLoc(),
-          *TemplateId, attrs.getList(),
+          *TemplateId, attrs,
           MultiTemplateParamsArg(TemplateParams ? &(*TemplateParams)[0]
                                                 : nullptr,
                                  TemplateParams ? TemplateParams->size() : 0),
@@ -1840,24 +1830,18 @@
     //
     ProhibitAttributes(attrs);
 
-    TagOrTempResult
-      = Actions.ActOnExplicitInstantiation(getCurScope(),
-                                           TemplateInfo.ExternLoc,
-                                           TemplateInfo.TemplateLoc,
-                                           TagType, StartLoc, SS, Name,
-                                           NameLoc, attrs.getList());
+    TagOrTempResult = Actions.ActOnExplicitInstantiation(
+        getCurScope(), TemplateInfo.ExternLoc, TemplateInfo.TemplateLoc,
+        TagType, StartLoc, SS, Name, NameLoc, attrs);
   } else if (TUK == Sema::TUK_Friend &&
              TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate) {
     ProhibitAttributes(attrs);
 
-    TagOrTempResult =
-      Actions.ActOnTemplatedFriendTag(getCurScope(), DS.getFriendSpecLoc(),
-                                      TagType, StartLoc, SS,
-                                      Name, NameLoc, attrs.getList(),
-                                      MultiTemplateParamsArg(
-                                    TemplateParams? &(*TemplateParams)[0]
-                                                  : nullptr,
-                                 TemplateParams? TemplateParams->size() : 0));
+    TagOrTempResult = Actions.ActOnTemplatedFriendTag(
+        getCurScope(), DS.getFriendSpecLoc(), TagType, StartLoc, SS, Name,
+        NameLoc, attrs,
+        MultiTemplateParamsArg(TemplateParams ? &(*TemplateParams)[0] : nullptr,
+                               TemplateParams ? TemplateParams->size() : 0));
   } else {
     if (TUK != Sema::TUK_Declaration && TUK != Sema::TUK_Definition)
       ProhibitAttributes(attrs);
@@ -1885,9 +1869,9 @@
 
     // Declaration or definition of a class type
     TagOrTempResult = Actions.ActOnTag(
-        getCurScope(), TagType, TUK, StartLoc, SS, Name, NameLoc,
-        attrs.getList(), AS, DS.getModulePrivateSpecLoc(), TParams, Owned,
-        IsDependent, SourceLocation(), false, clang::TypeResult(),
+        getCurScope(), TagType, TUK, StartLoc, SS, Name, NameLoc, attrs, AS,
+        DS.getModulePrivateSpecLoc(), TParams, Owned, IsDependent,
+        SourceLocation(), false, clang::TypeResult(),
         DSC == DeclSpecContext::DSC_type_specifier,
         DSC == DeclSpecContext::DSC_template_param ||
             DSC == DeclSpecContext::DSC_template_type_arg,
@@ -1929,7 +1913,7 @@
 
   if (!TagOrTempResult.isInvalid())
     // Delayed processing of attributes.
-    Actions.ProcessDeclAttributeDelayed(TagOrTempResult.get(), attrs.getList());
+    Actions.ProcessDeclAttributeDelayed(TagOrTempResult.get(), attrs);
 
   const char *PrevSpec = nullptr;
   unsigned DiagID;
@@ -2300,12 +2284,10 @@
     if (!VS.isUnset()) {
       // If we saw any GNU-style attributes that are known to GCC followed by a
       // virt-specifier, issue a GCC-compat warning.
-      const AttributeList *Attr = DeclaratorInfo.getAttributes();
-      while (Attr) {
-        if (Attr->isKnownToGCC() && !Attr->isCXX11Attribute())
-          Diag(Attr->getLoc(), diag::warn_gcc_attribute_location);
-        Attr = Attr->getNext();
-      }
+      for (const AttributeList &AL : DeclaratorInfo.getAttributes())
+        if (AL.isKnownToGCC() && !AL.isCXX11Attribute())
+          Diag(AL.getLoc(), diag::warn_gcc_attribute_location);
+
       MaybeParseAndDiagnoseDeclSpecAfterCXX11VirtSpecifierSeq(DeclaratorInfo, VS);
     }
   }
@@ -2424,7 +2406,7 @@
 ///
 Parser::DeclGroupPtrTy
 Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
-                                       AttributeList *AccessAttrs,
+                                       ParsedAttributes &AccessAttrs,
                                        const ParsedTemplateInfo &TemplateInfo,
                                        ParsingDeclRAIIObject *TemplateDiags) {
   if (Tok.is(tok::at)) {
@@ -2492,7 +2474,8 @@
       return DeclGroupPtrTy::make(DeclGroupRef(Actions.ActOnUsingDeclaration(
           getCurScope(), AS, /*UsingLoc*/ SourceLocation(),
           /*TypenameLoc*/ SourceLocation(), SS, Name,
-          /*EllipsisLoc*/ SourceLocation(), /*AttrList*/ nullptr)));
+          /*EllipsisLoc*/ SourceLocation(),
+          /*AttrList*/ ParsedAttributesView())));
     }
   }
 
@@ -2512,7 +2495,7 @@
     SourceLocation DeclEnd;
     return DeclGroupPtrTy::make(
         DeclGroupRef(ParseTemplateDeclarationOrSpecialization(
-            DeclaratorContext::MemberContext, DeclEnd, AS, AccessAttrs)));
+            DeclaratorContext::MemberContext, DeclEnd, AccessAttrs, AS)));
   }
 
   // Handle:  member-declaration ::= '__extension__' member-declaration
@@ -2525,12 +2508,12 @@
   }
 
   ParsedAttributesWithRange attrs(AttrFactory);
-  ParsedAttributesWithRange FnAttrs(AttrFactory);
+  ParsedAttributesViewWithRange FnAttrs;
   // Optional C++11 attribute-specifier
   MaybeParseCXX11Attributes(attrs);
   // We need to keep these attributes for future diagnostic
   // before they are taken over by declaration specifier.
-  FnAttrs.addAll(attrs.getList());
+  FnAttrs.addAll(attrs.begin(), attrs.end());
   FnAttrs.Range = attrs.Range;
 
   MaybeParseMicrosoftAttributes(attrs);
@@ -2777,7 +2760,7 @@
         // initialize it.
         ThisDecl = VT->getTemplatedDecl();
 
-      if (ThisDecl && AccessAttrs)
+      if (ThisDecl)
         Actions.ProcessDeclAttributeList(getCurScope(), ThisDecl, AccessAttrs);
     }
 
@@ -3014,7 +2997,7 @@
   switch (Tok.getKind()) {
   case tok::kw___if_exists:
   case tok::kw___if_not_exists:
-    ParseMicrosoftIfExistsClassDeclaration(TagType, AS);
+    ParseMicrosoftIfExistsClassDeclaration(TagType, AccessAttrs, AS);
     return nullptr;
 
   case tok::semi:
@@ -3080,8 +3063,7 @@
       Diag(ASLoc, diag::err_access_specifier_interface) << (AS == AS_protected);
     }
 
-    if (Actions.ActOnAccessSpecifier(NewAS, ASLoc, EndLoc,
-                                     AccessAttrs.getList())) {
+    if (Actions.ActOnAccessSpecifier(NewAS, ASLoc, EndLoc, AccessAttrs)) {
       // found another attribute than only annotations
       AccessAttrs.clear();
     }
@@ -3094,7 +3076,7 @@
                                                       TagDecl);
 
   default:
-    return ParseCXXClassMemberDeclaration(AS, AccessAttrs.getList());
+    return ParseCXXClassMemberDeclaration(AS, AccessAttrs);
   }
 }
 
@@ -3282,9 +3264,8 @@
 
   if (TagDecl)
     Actions.ActOnFinishCXXMemberSpecification(getCurScope(), RecordLoc, TagDecl,
-                                              T.getOpenLocation(), 
-                                              T.getCloseLocation(),
-                                              attrs.getList());
+                                              T.getOpenLocation(),
+                                              T.getCloseLocation(), attrs);
 
   // C++11 [class.mem]p2:
   //   Within the class member-specification, the class is regarded as complete
@@ -3893,25 +3874,26 @@
         ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs, EndLoc,
                                  ScopeName, ScopeLoc, Syntax);
 
-  const AttributeList *Attr = Attrs.getList();
-  if (Attr && IsBuiltInOrStandardCXX11Attribute(AttrName, ScopeName)) {
+  if (!Attrs.empty() &&
+      IsBuiltInOrStandardCXX11Attribute(AttrName, ScopeName)) {
+    AttributeList &Attr = *Attrs.begin();
     // If the attribute is a standard or built-in attribute and we are
     // parsing an argument list, we need to determine whether this attribute
     // was allowed to have an argument list (such as [[deprecated]]), and how
     // many arguments were parsed (so we can diagnose on [[deprecated()]]).
-    if (Attr->getMaxArgs() && !NumArgs) {
+    if (Attr.getMaxArgs() && !NumArgs) {
       // The attribute was allowed to have arguments, but none were provided
       // even though the attribute parsed successfully. This is an error.
       Diag(LParenLoc, diag::err_attribute_requires_arguments) << AttrName;
-      Attr->setInvalid(true);
-    } else if (!Attr->getMaxArgs()) {
+      Attr.setInvalid(true);
+    } else if (!Attr.getMaxArgs()) {
       // The attribute parsed successfully, but was not allowed to have any
       // arguments. It doesn't matter whether any were provided -- the
       // presence of the argument list (even if empty) is diagnosed.
       Diag(LParenLoc, diag::err_cxx11_attribute_forbids_arguments)
           << AttrName
           << FixItHint::CreateRemoval(SourceRange(LParenLoc, *EndLoc));
-      Attr->setInvalid(true);
+      Attr.setInvalid(true);
     }
   }
   return true;
@@ -4221,8 +4203,9 @@
   } while (Tok.is(tok::l_square));
 }
 
-void Parser::ParseMicrosoftIfExistsClassDeclaration(DeclSpec::TST TagType,
-                                                    AccessSpecifier& CurAS) {
+void Parser::ParseMicrosoftIfExistsClassDeclaration(
+    DeclSpec::TST TagType, ParsedAttributes &AccessAttrs,
+    AccessSpecifier &CurAS) {
   IfExistsCondition Result;
   if (ParseMicrosoftIfExistsCondition(Result))
     return;
@@ -4252,7 +4235,8 @@
   while (Tok.isNot(tok::r_brace) && !isEofOrEom()) {
     // __if_exists, __if_not_exists can nest.
     if (Tok.isOneOf(tok::kw___if_exists, tok::kw___if_not_exists)) {
-      ParseMicrosoftIfExistsClassDeclaration((DeclSpec::TST)TagType, CurAS);
+      ParseMicrosoftIfExistsClassDeclaration((DeclSpec::TST)TagType,
+                                             AccessAttrs, CurAS);
       continue;
     }
 
@@ -4269,7 +4253,8 @@
       SourceLocation ASLoc = Tok.getLocation();
       ConsumeToken();
       if (Tok.is(tok::colon))
-        Actions.ActOnAccessSpecifier(AS, ASLoc, Tok.getLocation());
+        Actions.ActOnAccessSpecifier(AS, ASLoc, Tok.getLocation(),
+                                     ParsedAttributesView{});
       else
         Diag(Tok, diag::err_expected) << tok::colon;
       ConsumeToken();
@@ -4277,7 +4262,7 @@
     }
 
     // Parse all the comma separated declarators.
-    ParseCXXClassMemberDeclaration(CurAS, nullptr);
+    ParseCXXClassMemberDeclaration(CurAS, AccessAttrs);
   }
   
   Braces.consumeClose();