Insomniac refactoring:  change how the parser allocates attributes so that
AttributeLists do not accumulate over the lifetime of parsing, but are
instead reused.  Also make the arguments array not require a separate
allocation, and make availability attributes store their stuff in
augmented memory, too.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@128209 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index 6928d0d..976e60f 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -33,7 +33,7 @@
 TypeResult Parser::ParseTypeName(SourceRange *Range,
                                  Declarator::TheContext Context) {
   // Parse the common declaration-specifiers piece.
-  DeclSpec DS;
+  DeclSpec DS(AttrFactory);
   ParseSpecifierQualifierList(DS);
 
   // Parse the abstract-declarator, if present.
@@ -126,8 +126,8 @@
           if (Tok.is(tok::r_paren)) {
             // __attribute__(( mode(byte) ))
             ConsumeParen(); // ignore the right paren loc for now
-            attrs.add(AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc,
-                                         ParmName, ParmLoc, 0, 0));
+            attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc,
+                         ParmName, ParmLoc, 0, 0);
           } else if (Tok.is(tok::comma)) {
             ConsumeToken();
             // __attribute__(( format(printf, 1, 2) ))
@@ -150,9 +150,8 @@
             }
             if (ArgExprsOk && Tok.is(tok::r_paren)) {
               ConsumeParen(); // ignore the right paren loc for now
-              attrs.add(AttrFactory.Create(AttrName, AttrNameLoc, 0,
-                                           AttrNameLoc, ParmName, ParmLoc,
-                                           ArgExprs.take(), ArgExprs.size()));
+              attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc,
+                           ParmName, ParmLoc, ArgExprs.take(), ArgExprs.size());
             }
           }
         } else { // not an identifier
@@ -161,8 +160,8 @@
           // parse a possibly empty comma separated list of expressions
             // __attribute__(( nonnull() ))
             ConsumeParen(); // ignore the right paren loc for now
-            attrs.add(AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc,
-                                         0, SourceLocation(), 0, 0));
+            attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc,
+                         0, SourceLocation(), 0, 0);
             break;
           case tok::kw_char:
           case tok::kw_wchar_t:
@@ -179,9 +178,8 @@
           case tok::kw_void:
           case tok::kw_typeof: {
             AttributeList *attr
-                     = AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc,
-                                          0, SourceLocation(), 0, 0);
-            attrs.add(attr);
+              = attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc,
+                             0, SourceLocation(), 0, 0);
             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
@@ -213,16 +211,16 @@
             // Match the ')'.
             if (ArgExprsOk && Tok.is(tok::r_paren)) {
               ConsumeParen(); // ignore the right paren loc for now
-              attrs.add(AttrFactory.Create(AttrName, AttrNameLoc, 0,
-                                           AttrNameLoc, 0, SourceLocation(),
-                                           ArgExprs.take(), ArgExprs.size()));
+              attrs.addNew(AttrName, AttrNameLoc, 0,
+                           AttrNameLoc, 0, SourceLocation(),
+                           ArgExprs.take(), ArgExprs.size());
             }
             break;
           }
         }
       } else {
-        attrs.add(AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc,
-                                     0, SourceLocation(), 0, 0));
+        attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc,
+                     0, SourceLocation(), 0, 0);
       }
     }
     if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen))
@@ -264,14 +262,14 @@
       ExprResult ArgExpr(ParseAssignmentExpression());
       if (!ArgExpr.isInvalid()) {
         Expr *ExprList = ArgExpr.take();
-        attrs.add(AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc, 0,
-                                     SourceLocation(), &ExprList, 1, true));
+        attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0,
+                     SourceLocation(), &ExprList, 1, true);
       }
       if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen))
         SkipUntil(tok::r_paren, false);
     } else {
-      attrs.add(AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc,
-                                   0, SourceLocation(), 0, 0, true));
+      attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc,
+                   0, SourceLocation(), 0, 0, true);
     }
   }
   if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen))
@@ -290,8 +288,8 @@
     if (Tok.is(tok::kw___ptr64) || Tok.is(tok::kw___w64))
       // FIXME: Support these properly!
       continue;
-    attrs.add(AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc, 0,
-                                 SourceLocation(), 0, 0, true));
+    attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0,
+                 SourceLocation(), 0, 0, true);
   }
 }
 
@@ -300,8 +298,8 @@
   while (Tok.is(tok::kw___pascal)) {
     IdentifierInfo *AttrName = Tok.getIdentifierInfo();
     SourceLocation AttrNameLoc = ConsumeToken();
-    attrs.add(AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc, 0,
-                                 SourceLocation(), 0, 0, true));
+    attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0,
+                 SourceLocation(), 0, 0, true);
   }
 }
 
@@ -309,9 +307,9 @@
   // Treat these like attributes
   while (Tok.is(tok::kw___kernel)) {
     SourceLocation AttrNameLoc = ConsumeToken();
-    attrs.add(AttrFactory.Create(PP.getIdentifierInfo("opencl_kernel_function"),
-                                 AttrNameLoc, 0, AttrNameLoc, 0,
-                                 SourceLocation(), 0, 0, false));
+    attrs.addNew(PP.getIdentifierInfo("opencl_kernel_function"),
+                 AttrNameLoc, 0, AttrNameLoc, 0,
+                 SourceLocation(), 0, 0, false);
   }
 }
 
@@ -321,45 +319,45 @@
     // OpenCL qualifiers:
     case tok::kw___private:
     case tok::kw_private: 
-      DS.addAttributes(AttrFactory.CreateIntegerAttribute( 
+      DS.getAttributes().addNewInteger(
           Actions.getASTContext(), 
-          PP.getIdentifierInfo("address_space"), Loc, 0));
+          PP.getIdentifierInfo("address_space"), Loc, 0);
       break;
       
     case tok::kw___global:
-      DS.addAttributes(AttrFactory.CreateIntegerAttribute(
+      DS.getAttributes().addNewInteger(
           Actions.getASTContext(),
-          PP.getIdentifierInfo("address_space"), Loc, LangAS::opencl_global));
+          PP.getIdentifierInfo("address_space"), Loc, LangAS::opencl_global);
       break;
       
     case tok::kw___local:
-      DS.addAttributes(AttrFactory.CreateIntegerAttribute(
+      DS.getAttributes().addNewInteger(
           Actions.getASTContext(),
-          PP.getIdentifierInfo("address_space"), Loc, LangAS::opencl_local));
+          PP.getIdentifierInfo("address_space"), Loc, LangAS::opencl_local);
       break;
       
     case tok::kw___constant:
-      DS.addAttributes(AttrFactory.CreateIntegerAttribute(
+      DS.getAttributes().addNewInteger(
           Actions.getASTContext(),
-          PP.getIdentifierInfo("address_space"), Loc, LangAS::opencl_constant));
+          PP.getIdentifierInfo("address_space"), Loc, LangAS::opencl_constant);
       break;
       
     case tok::kw___read_only:
-      DS.addAttributes(AttrFactory.CreateIntegerAttribute(
+      DS.getAttributes().addNewInteger(
           Actions.getASTContext(), 
-          PP.getIdentifierInfo("opencl_image_access"), Loc, CLIA_read_only));
+          PP.getIdentifierInfo("opencl_image_access"), Loc, CLIA_read_only);
       break;
       
     case tok::kw___write_only:
-      DS.addAttributes(AttrFactory.CreateIntegerAttribute(
+      DS.getAttributes().addNewInteger(
           Actions.getASTContext(), 
-          PP.getIdentifierInfo("opencl_image_access"), Loc, CLIA_write_only));
+          PP.getIdentifierInfo("opencl_image_access"), Loc, CLIA_write_only);
       break;
       
     case tok::kw___read_write:
-      DS.addAttributes(AttrFactory.CreateIntegerAttribute(
+      DS.getAttributes().addNewInteger(
           Actions.getASTContext(),
-          PP.getIdentifierInfo("opencl_image_access"), Loc, CLIA_read_write));
+          PP.getIdentifierInfo("opencl_image_access"), Loc, CLIA_read_write);
       break;
     default: break;
   }
@@ -592,12 +590,12 @@
     *endLoc = RParenLoc;
 
   // Record this attribute
-  attrs.add(AttrFactory.Create(&Availability, AvailabilityLoc,
-                               0, SourceLocation(),
-                               Platform, PlatformLoc,
-                               Changes[Introduced],
-                               Changes[Deprecated],
-                               Changes[Obsoleted], false, false));
+  attrs.addNew(&Availability, AvailabilityLoc,
+               0, SourceLocation(),
+               Platform, PlatformLoc,
+               Changes[Introduced],
+               Changes[Deprecated],
+               Changes[Obsoleted], false, false);
 }
 
 void Parser::DiagnoseProhibitedAttributes(ParsedAttributesWithRange &attrs) {
@@ -2175,7 +2173,7 @@
     }
 
     // Parse all the comma separated declarators.
-    DeclSpec DS;
+    DeclSpec DS(AttrFactory);
 
     if (!Tok.is(tok::at)) {
       struct CFieldCallback : FieldCallback {
@@ -2236,7 +2234,7 @@
 
   SourceLocation RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBraceLoc);
 
-  ParsedAttributes attrs;
+  ParsedAttributes attrs(AttrFactory);
   // If attributes exist after struct contents, parse them.
   MaybeParseGNUAttributes(attrs);
 
@@ -2286,7 +2284,7 @@
   }
   
   // If attributes exist after tag, parse them.
-  ParsedAttributes attrs;
+  ParsedAttributes attrs(AttrFactory);
   MaybeParseGNUAttributes(attrs);
 
   CXXScopeSpec &SS = DS.getTypeSpecScope();
@@ -2526,7 +2524,7 @@
     SourceLocation IdentLoc = ConsumeToken();
 
     // If attributes exist after the enumerator, parse them.
-    ParsedAttributes attrs;
+    ParsedAttributes attrs(AttrFactory);
     MaybeParseGNUAttributes(attrs);
 
     SourceLocation EqualLoc;
@@ -2570,7 +2568,7 @@
   SourceLocation RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBraceLoc);
 
   // If attributes exist after the identifier list, parse them.
-  ParsedAttributes attrs;
+  ParsedAttributes attrs(AttrFactory);
   MaybeParseGNUAttributes(attrs);
 
   Actions.ActOnEnumBody(StartLoc, LBraceLoc, RBraceLoc, EnumDecl,
@@ -2918,7 +2916,7 @@
     DeclScopeObj.EnterDeclaratorScope();
 
   // Optionally skip Microsoft attributes.
-  ParsedAttributes Attrs;
+  ParsedAttributes Attrs(AttrFactory);
   MaybeParseMicrosoftAttributes(Attrs);
 
   // Check whether the next token(s) are part of a declaration
@@ -2946,7 +2944,7 @@
                                        bool CXX0XAttributesAllowed) {
   if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier()) {
     SourceLocation Loc = Tok.getLocation();
-    ParsedAttributesWithRange attrs;
+    ParsedAttributesWithRange attrs(AttrFactory);
     ParseCXX0XAttributes(attrs);
     if (CXX0XAttributesAllowed)
       DS.takeAttributesFrom(attrs);
@@ -3092,7 +3090,7 @@
 
       SourceLocation Loc = ConsumeToken();
       D.SetRangeEnd(Loc);
-      DeclSpec DS;
+      DeclSpec DS(AttrFactory);
       ParseTypeQualifierListOpt(DS);
       D.ExtendWithDeclSpec(DS);
 
@@ -3102,7 +3100,8 @@
       // 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.getAttributes(),
                     /* Don't replace range end. */SourceLocation());
       return;
     }
@@ -3126,7 +3125,7 @@
 
   if (Kind == tok::star || Kind == tok::caret) {
     // Is a pointer.
-    DeclSpec DS;
+    DeclSpec DS(AttrFactory);
 
     ParseTypeQualifierListOpt(DS);
     D.ExtendWithDeclSpec(DS);
@@ -3138,17 +3137,18 @@
       D.AddTypeInfo(DeclaratorChunk::getPointer(DS.getTypeQualifiers(), Loc,
                                                 DS.getConstSpecLoc(),
                                                 DS.getVolatileSpecLoc(),
-                                                DS.getRestrictSpecLoc(),
-                                                DS.takeAttributes()),
+                                                DS.getRestrictSpecLoc()),
+                    DS.getAttributes(),
                     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.getAttributes(),
                     SourceLocation());
   } else {
     // Is a reference
-    DeclSpec DS;
+    DeclSpec DS(AttrFactory);
 
     // Complain about rvalue references in C++03, but then go on and build
     // the declarator.
@@ -3196,8 +3196,8 @@
 
     // Remember that we parsed a reference type. It doesn't have type-quals.
     D.AddTypeInfo(DeclaratorChunk::getReference(DS.getTypeQualifiers(), Loc,
-                                                DS.takeAttributes(),
                                                 Kind == tok::amp),
+                  DS.getAttributes(),
                   SourceLocation());
   }
 }
@@ -3362,7 +3362,7 @@
         if (!isCXXFunctionDeclarator(warnIfAmbiguous))
           break;
       }
-      ParsedAttributes attrs;
+      ParsedAttributes attrs(AttrFactory);
       ParseFunctionDeclarator(ConsumeParen(), D, attrs);
     } else if (Tok.is(tok::l_square)) {
       ParseBracketDeclarator(D);
@@ -3399,7 +3399,7 @@
   // In either case, we need to eat any attributes to be able to determine what
   // sort of paren this is.
   //
-  ParsedAttributes attrs;
+  ParsedAttributes attrs(AttrFactory);
   bool RequiresArg = false;
   if (Tok.is(tok::kw___attribute)) {
     ParseGNUAttributes(attrs);
@@ -3445,13 +3445,12 @@
   if (isGrouping) {
     bool hadGroupingParens = D.hasGroupingParens();
     D.setGroupingParens(true);
-    if (!attrs.empty())
-      D.addAttributes(attrs.getList(), SourceLocation());
 
     ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
     // Match the ')'.
     SourceLocation EndLoc = MatchRHSPunctuation(tok::r_paren, StartLoc);
-    D.AddTypeInfo(DeclaratorChunk::getParen(StartLoc, EndLoc), EndLoc);
+    D.AddTypeInfo(DeclaratorChunk::getParen(StartLoc, EndLoc),
+                  attrs, EndLoc);
 
     D.setGroupingParens(hadGroupingParens);
     return;
@@ -3518,7 +3517,7 @@
     SourceLocation EndLoc = ConsumeParen();  // Eat the closing ')'.
 
     // cv-qualifier-seq[opt].
-    DeclSpec DS;
+    DeclSpec DS(AttrFactory);
     SourceLocation RefQualifierLoc;
     bool RefQualifierIsLValueRef = true;
     ExceptionSpecificationType ESpecType = EST_None;
@@ -3559,8 +3558,7 @@
 
     // Remember that we parsed a function type, and remember the attributes.
     // int() -> no prototype, no '...'.
-    D.AddTypeInfo(DeclaratorChunk::getFunction(attrs,
-                                               /*prototype*/getLang().CPlusPlus,
+    D.AddTypeInfo(DeclaratorChunk::getFunction(/*prototype*/getLang().CPlusPlus,
                                                /*variadic*/ false,
                                                SourceLocation(),
                                                /*arglist*/ 0, 0,
@@ -3575,7 +3573,7 @@
                                                  NoexceptExpr.get() : 0,
                                                LParenLoc, EndLoc, D,
                                                TrailingReturnType),
-                  EndLoc);
+                  attrs, EndLoc);
     return;
   }
 
@@ -3639,7 +3637,7 @@
 
     // Parse the declaration-specifiers.
     // Just use the ParsingDeclaration "scope" of the declarator.
-    DeclSpec DS;
+    DeclSpec DS(AttrFactory);
 	
     // Skip any Microsoft attributes before a param.
     if (getLang().Microsoft && Tok.is(tok::l_square))
@@ -3765,7 +3763,7 @@
   // If we have the closing ')', eat it.
   SourceLocation EndLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
 
-  DeclSpec DS;
+  DeclSpec DS(AttrFactory);
   SourceLocation RefQualifierLoc;
   bool RefQualifierIsLValueRef = true;
   ExceptionSpecificationType ESpecType = EST_None;
@@ -3814,8 +3812,7 @@
   PrototypeScope.Exit();
 
   // Remember that we parsed a function type, and remember the attributes.
-  D.AddTypeInfo(DeclaratorChunk::getFunction(attrs,
-                                             /*proto*/true, IsVariadic,
+  D.AddTypeInfo(DeclaratorChunk::getFunction(/*proto*/true, IsVariadic,
                                              EllipsisLoc,
                                              ParamInfo.data(), ParamInfo.size(),
                                              DS.getTypeQualifiers(),
@@ -3829,7 +3826,7 @@
                                                NoexceptExpr.get() : 0,
                                              LParenLoc, EndLoc, D,
                                              TrailingReturnType),
-                EndLoc);
+                attrs, EndLoc);
 }
 
 /// ParseFunctionDeclaratorIdentifierList - While parsing a function declarator
@@ -3898,15 +3895,15 @@
   // 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(ParsedAttributes(),
-                                             /*proto*/false, /*varargs*/false,
+  ParsedAttributes attrs(AttrFactory);
+  D.AddTypeInfo(DeclaratorChunk::getFunction(/*proto*/false, /*varargs*/false,
                                              SourceLocation(),
                                              &ParamInfo[0], ParamInfo.size(),
                                              /*TypeQuals*/0,
                                              true, SourceLocation(),
                                              EST_None, SourceLocation(), 0, 0,
                                              0, 0, LParenLoc, RLoc, D),
-                RLoc);
+                attrs, RLoc);
 }
 
 /// [C90]   direct-declarator '[' constant-expression[opt] ']'
@@ -3921,14 +3918,14 @@
   // 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);
-    ParsedAttributes attrs;
+    ParsedAttributes attrs(AttrFactory);
     MaybeParseCXX0XAttributes(attrs);
     
     // Remember that we parsed the empty array type.
     ExprResult NumElements;
-    D.AddTypeInfo(DeclaratorChunk::getArray(0, attrs, false, false, 0,
+    D.AddTypeInfo(DeclaratorChunk::getArray(0, false, false, 0,
                                             StartLoc, EndLoc),
-                  EndLoc);
+                  attrs, EndLoc);
     return;
   } else if (Tok.getKind() == tok::numeric_constant &&
              GetLookAheadToken(1).is(tok::r_square)) {
@@ -3937,14 +3934,14 @@
     ConsumeToken();
 
     SourceLocation EndLoc = MatchRHSPunctuation(tok::r_square, StartLoc);
-    ParsedAttributes attrs;
+    ParsedAttributes attrs(AttrFactory);
     MaybeParseCXX0XAttributes(attrs);
 
     // Remember that we parsed a array type, and remember its features.
-    D.AddTypeInfo(DeclaratorChunk::getArray(0, attrs, false, 0,
+    D.AddTypeInfo(DeclaratorChunk::getArray(0, false, 0,
                                             ExprRes.release(),
                                             StartLoc, EndLoc),
-                  EndLoc);
+                  attrs, EndLoc);
     return;
   }
 
@@ -3955,7 +3952,7 @@
 
   // If there is a type-qualifier-list, read it now.
   // Type qualifiers in an array subscript are a C99 feature.
-  DeclSpec DS;
+  DeclSpec DS(AttrFactory);
   ParseTypeQualifierListOpt(DS, false /*no attributes*/);
 
   // If we haven't already read 'static', check to see if there is one after the
@@ -4003,15 +4000,15 @@
 
   SourceLocation EndLoc = MatchRHSPunctuation(tok::r_square, StartLoc);
 
-  ParsedAttributes attrs;
+  ParsedAttributes attrs(AttrFactory);
   MaybeParseCXX0XAttributes(attrs);
 
   // Remember that we parsed a array type, and remember its features.
-  D.AddTypeInfo(DeclaratorChunk::getArray(DS.getTypeQualifiers(), attrs,
+  D.AddTypeInfo(DeclaratorChunk::getArray(DS.getTypeQualifiers(),
                                           StaticLoc.isValid(), isStar,
                                           NumElements.release(),
                                           StartLoc, EndLoc),
-                EndLoc);
+                attrs, EndLoc);
 }
 
 /// [GNU]   typeof-specifier: