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:
diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp
index ee8690f..4d45431 100644
--- a/lib/Parse/ParseDeclCXX.cpp
+++ b/lib/Parse/ParseDeclCXX.cpp
@@ -69,11 +69,9 @@
}
// Read label attributes, if present.
- ParsedAttributes attrs;
+ ParsedAttributes attrs(AttrFactory);
if (Tok.is(tok::kw___attribute)) {
attrTok = Tok;
-
- // FIXME: save these somewhere.
ParseGNUAttributes(attrs);
}
@@ -118,7 +116,7 @@
"parsing namespace");
while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
- ParsedAttributesWithRange attrs;
+ ParsedAttributesWithRange attrs(AttrFactory);
MaybeParseCXX0XAttributes(attrs);
MaybeParseMicrosoftAttributes(attrs);
ParseExternalDeclaration(attrs);
@@ -138,9 +136,9 @@
/// alias definition.
///
Decl *Parser::ParseNamespaceAlias(SourceLocation NamespaceLoc,
- SourceLocation AliasLoc,
- IdentifierInfo *Alias,
- SourceLocation &DeclEnd) {
+ SourceLocation AliasLoc,
+ IdentifierInfo *Alias,
+ SourceLocation &DeclEnd) {
assert(Tok.is(tok::equal) && "Not equal token");
ConsumeToken(); // eat the '='.
@@ -199,7 +197,7 @@
Tok.is(tok::l_brace) ? Tok.getLocation()
: SourceLocation());
- ParsedAttributesWithRange attrs;
+ ParsedAttributesWithRange attrs(AttrFactory);
MaybeParseCXX0XAttributes(attrs);
MaybeParseMicrosoftAttributes(attrs);
@@ -216,7 +214,7 @@
SourceLocation LBrace = ConsumeBrace();
while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
- ParsedAttributesWithRange attrs;
+ ParsedAttributesWithRange attrs(AttrFactory);
MaybeParseCXX0XAttributes(attrs);
MaybeParseMicrosoftAttributes(attrs);
ParseExternalDeclaration(attrs);
@@ -380,7 +378,7 @@
}
// Parse (optional) attributes (most likely GNU strong-using extension).
- ParsedAttributes attrs;
+ ParsedAttributes attrs(AttrFactory);
MaybeParseGNUAttributes(attrs);
// Eat ';'.
@@ -590,7 +588,7 @@
EndLocation = IdLoc;
// Fake up a Declarator to use with ActOnTypeName.
- DeclSpec DS;
+ DeclSpec DS(AttrFactory);
DS.SetRangeStart(IdLoc);
DS.SetRangeEnd(EndLocation);
DS.getTypeSpecScope() = SS;
@@ -677,7 +675,7 @@
SuppressingAccessChecks = true;
}
- ParsedAttributes attrs;
+ ParsedAttributes attrs(AttrFactory);
// If attributes exist after tag, parse them.
if (Tok.is(tok::kw___attribute))
ParseGNUAttributes(attrs);
@@ -1488,7 +1486,7 @@
// is a bitfield.
ColonProtectionRAIIObject X(*this);
- ParsedAttributesWithRange attrs;
+ ParsedAttributesWithRange attrs(AttrFactory);
// Optional C++0x attribute-specifier
MaybeParseCXX0XAttributes(attrs);
MaybeParseMicrosoftAttributes(attrs);
@@ -1837,7 +1835,7 @@
}
// If attributes exist after class contents, parse them.
- ParsedAttributes attrs;
+ ParsedAttributes attrs(AttrFactory);
MaybeParseGNUAttributes(attrs);
if (TagDecl)
@@ -2309,8 +2307,8 @@
break;
}
- attrs.add(AttrFactory.Create(AttrName, AttrLoc, 0, AttrLoc, 0,
- SourceLocation(), 0, 0, false, true));
+ attrs.addNew(AttrName, AttrLoc, 0, AttrLoc, 0,
+ SourceLocation(), 0, 0, false, true);
AttrParsed = true;
break;
}
@@ -2330,9 +2328,9 @@
ExprVector ArgExprs(Actions);
ArgExprs.push_back(ArgExpr.release());
- attrs.add(AttrFactory.Create(AttrName, AttrLoc, 0, AttrLoc,
- 0, ParamLoc, ArgExprs.take(), 1,
- false, true));
+ attrs.addNew(AttrName, AttrLoc, 0, AttrLoc,
+ 0, ParamLoc, ArgExprs.take(), 1,
+ false, true);
AttrParsed = true;
break;
diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp
index ecc02ac..510e2c2 100644
--- a/lib/Parse/ParseExpr.cpp
+++ b/lib/Parse/ParseExpr.cpp
@@ -683,7 +683,7 @@
if (ParsedType Typ = Actions.getTypeName(II, ILoc, getCurScope()))
if (Typ.get()->isObjCObjectOrInterfaceType()) {
// Fake up a Declarator to use with ActOnTypeName.
- DeclSpec DS;
+ DeclSpec DS(AttrFactory);
DS.SetRangeStart(ILoc);
DS.SetRangeEnd(ILoc);
const char *PrevSpec = 0;
@@ -826,7 +826,7 @@
ParsedType Type = getTypeAnnotation(Tok);
// Fake up a Declarator to use with ActOnTypeName.
- DeclSpec DS;
+ DeclSpec DS(AttrFactory);
DS.SetRangeStart(Tok.getLocation());
DS.SetRangeEnd(Tok.getLastLoc());
@@ -876,7 +876,7 @@
// postfix-expression: simple-type-specifier '(' expression-list[opt] ')'
//
- DeclSpec DS;
+ DeclSpec DS(AttrFactory);
ParseCXXSimpleTypeSpecifier(DS);
if (Tok.isNot(tok::l_paren))
return ExprError(Diag(Tok, diag::err_expected_lparen_after_type)
@@ -1634,7 +1634,7 @@
if (ExprType >= CompoundStmt && Tok.is(tok::l_brace)) {
Diag(Tok, diag::ext_gnu_statement_expr);
- ParsedAttributes attrs;
+ ParsedAttributes attrs(AttrFactory);
StmtResult Stmt(ParseCompoundStatement(attrs, true));
ExprType = CompoundStmt;
@@ -1850,7 +1850,7 @@
}
// Parse the specifier-qualifier-list piece.
- DeclSpec DS;
+ DeclSpec DS(AttrFactory);
ParseSpecifierQualifierList(DS);
// Parse the block-declarator.
@@ -1858,7 +1858,7 @@
ParseDeclarator(DeclaratorInfo);
// We do this for: ^ __attribute__((noreturn)) {, as DS has the attributes.
- DeclaratorInfo.addAttributes(DS.takeAttributes());
+ DeclaratorInfo.takeAttributes(DS.getAttributes(), SourceLocation());
MaybeParseGNUAttributes(DeclaratorInfo);
@@ -1894,7 +1894,7 @@
Actions.ActOnBlockStart(CaretLoc, getCurScope());
// Parse the return type if present.
- DeclSpec DS;
+ DeclSpec DS(AttrFactory);
Declarator ParamInfo(DS, Declarator::BlockLiteralContext);
// FIXME: Since the return type isn't actually parsed, it can't be used to
// fill ParamInfo with an initial valid range, so do it manually.
@@ -1926,8 +1926,8 @@
ParseBlockId();
} else {
// Otherwise, pretend we saw (void).
- ParamInfo.AddTypeInfo(DeclaratorChunk::getFunction(ParsedAttributes(),
- true, false,
+ ParsedAttributes attrs(AttrFactory);
+ ParamInfo.AddTypeInfo(DeclaratorChunk::getFunction(true, false,
SourceLocation(),
0, 0, 0,
true, SourceLocation(),
@@ -1936,7 +1936,7 @@
0, 0, 0, 0,
CaretLoc, CaretLoc,
ParamInfo),
- CaretLoc);
+ attrs, CaretLoc);
MaybeParseGNUAttributes(ParamInfo);
diff --git a/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp
index 422b915..1f41f5d 100644
--- a/lib/Parse/ParseExprCXX.cpp
+++ b/lib/Parse/ParseExprCXX.cpp
@@ -800,7 +800,7 @@
}
// type-specifier-seq
- DeclSpec DS;
+ DeclSpec DS(AttrFactory);
ParseSpecifierQualifierList(DS);
// declarator
@@ -1391,7 +1391,7 @@
// ptr-operator conversion-declarator[opt]
// Parse the type-specifier-seq.
- DeclSpec DS;
+ DeclSpec DS(AttrFactory);
if (ParseCXXTypeSpecifierSeq(DS)) // FIXME: ObjectType?
return true;
@@ -1644,7 +1644,7 @@
SourceLocation PlacementLParen, PlacementRParen;
SourceRange TypeIdParens;
- DeclSpec DS;
+ DeclSpec DS(AttrFactory);
Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
if (Tok.is(tok::l_paren)) {
// If it turns out to be a placement, we change the type location.
@@ -1746,10 +1746,12 @@
first = false;
SourceLocation RLoc = MatchRHSPunctuation(tok::r_square, LLoc);
- D.AddTypeInfo(DeclaratorChunk::getArray(0, ParsedAttributes(),
+
+ ParsedAttributes attrs(AttrFactory);
+ D.AddTypeInfo(DeclaratorChunk::getArray(0,
/*static=*/false, /*star=*/false,
Size.release(), LLoc, RLoc),
- RLoc);
+ attrs, RLoc);
if (RLoc.isInvalid())
return;
diff --git a/lib/Parse/ParseObjc.cpp b/lib/Parse/ParseObjc.cpp
index dab6354..14f2bbe 100644
--- a/lib/Parse/ParseObjc.cpp
+++ b/lib/Parse/ParseObjc.cpp
@@ -41,11 +41,11 @@
case tok::objc_class:
return ParseObjCAtClassDeclaration(AtLoc);
case tok::objc_interface: {
- ParsedAttributes attrs;
+ ParsedAttributes attrs(AttrFactory);
return ParseObjCAtInterfaceDeclaration(AtLoc, attrs);
}
case tok::objc_protocol: {
- ParsedAttributes attrs;
+ ParsedAttributes attrs(AttrFactory);
return ParseObjCAtProtocolDeclaration(AtLoc, attrs);
}
case tok::objc_implementation:
@@ -371,7 +371,7 @@
// FIXME: as the name implies, this rule allows function definitions.
// We could pass a flag or check for functions during semantic analysis.
- ParsedAttributes attrs;
+ ParsedAttributes attrs(AttrFactory);
allTUVariables.push_back(ParseDeclarationOrFunctionDefinition(attrs));
continue;
}
@@ -439,7 +439,7 @@
OCDS, AtLoc, MethodImplKind);
// Parse all the comma separated declarators.
- DeclSpec DS;
+ DeclSpec DS(AttrFactory);
ParseStructDeclaration(DS, Callback);
ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list, "",
@@ -843,9 +843,9 @@
ReturnType = ParseObjCTypeName(DSRet, OTN_ResultType);
// If attributes exist before the method, parse them.
- ParsedAttributes attrs;
+ ParsedAttributes methodAttrs(AttrFactory);
if (getLang().ObjC2)
- MaybeParseGNUAttributes(attrs);
+ MaybeParseGNUAttributes(methodAttrs);
if (Tok.is(tok::code_completion)) {
Actions.CodeCompleteObjCMethodDecl(getCurScope(), mType == tok::minus,
@@ -870,7 +870,7 @@
if (Tok.isNot(tok::colon)) {
// If attributes exist after the method, parse them.
if (getLang().ObjC2)
- MaybeParseGNUAttributes(attrs);
+ MaybeParseGNUAttributes(methodAttrs);
Selector Sel = PP.getSelectorTable().getNullarySelector(SelIdent);
Decl *Result
@@ -878,8 +878,8 @@
mType, IDecl, DSRet, ReturnType, Sel,
0,
CParamInfo.data(), CParamInfo.size(),
- attrs.getList(), MethodImplKind, false,
- MethodDefinition);
+ methodAttrs.getList(), MethodImplKind,
+ false, MethodDefinition);
PD.complete(Result);
return Result;
}
@@ -888,8 +888,11 @@
llvm::SmallVector<Sema::ObjCArgInfo, 12> ArgInfos;
ParseScope PrototypeScope(this,
Scope::FunctionPrototypeScope|Scope::DeclScope);
+
+ AttributePool allParamAttrs(AttrFactory);
while (1) {
+ ParsedAttributes paramAttrs(AttrFactory);
Sema::ObjCArgInfo ArgInfo;
// Each iteration parses a single keyword argument.
@@ -906,9 +909,8 @@
// If attributes exist before the argument name, parse them.
ArgInfo.ArgAttrs = 0;
if (getLang().ObjC2) {
- ParsedAttributes attrs;
- MaybeParseGNUAttributes(attrs);
- ArgInfo.ArgAttrs = attrs.getList();
+ MaybeParseGNUAttributes(paramAttrs);
+ ArgInfo.ArgAttrs = paramAttrs.getList();
}
// Code completion for the next piece of the selector.
@@ -937,6 +939,9 @@
ArgInfos.push_back(ArgInfo);
KeyIdents.push_back(SelIdent);
+ // Make sure the attributes persist.
+ allParamAttrs.takeAllFrom(paramAttrs.getPool());
+
// Code completion for the next piece of the selector.
if (Tok.is(tok::code_completion)) {
ConsumeCodeCompletionToken();
@@ -967,7 +972,7 @@
ConsumeToken();
break;
}
- DeclSpec DS;
+ DeclSpec DS(AttrFactory);
ParseDeclarationSpecifiers(DS);
// Parse the declarator.
Declarator ParmDecl(DS, Declarator::PrototypeContext);
@@ -984,7 +989,7 @@
// FIXME: Add support for optional parameter list...
// If attributes exist after the method, parse them.
if (getLang().ObjC2)
- MaybeParseGNUAttributes(attrs);
+ MaybeParseGNUAttributes(methodAttrs);
if (KeyIdents.size() == 0) {
// Leave prototype scope.
@@ -999,7 +1004,7 @@
mType, IDecl, DSRet, ReturnType, Sel,
&ArgInfos[0],
CParamInfo.data(), CParamInfo.size(),
- attrs.getList(),
+ methodAttrs.getList(),
MethodImplKind, isVariadic, MethodDefinition);
// Leave prototype scope.
PrototypeScope.Exit();
@@ -1172,7 +1177,7 @@
} Callback(*this, interfaceDecl, visibility, AllIvarDecls);
// Parse all the comma separated declarators.
- DeclSpec DS;
+ DeclSpec DS(AttrFactory);
ParseStructDeclaration(DS, Callback);
if (Tok.is(tok::semi)) {
@@ -1616,7 +1621,7 @@
ConsumeParen();
ParseScope CatchScope(this, Scope::DeclScope|Scope::AtCatchScope);
if (Tok.isNot(tok::ellipsis)) {
- DeclSpec DS;
+ DeclSpec DS(AttrFactory);
ParseDeclarationSpecifiers(DS);
// For some odd reason, the name of the exception variable is
// optional. As a result, we need to use "PrototypeContext", because
@@ -1848,7 +1853,7 @@
// typename-specifier
// simple-type-specifier
// expression (that starts with one of the above)
- DeclSpec DS;
+ DeclSpec DS(AttrFactory);
ParseCXXSimpleTypeSpecifier(DS);
if (Tok.is(tok::l_paren)) {
diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp
index cd970ca..8ffd6e9 100644
--- a/lib/Parse/ParseStmt.cpp
+++ b/lib/Parse/ParseStmt.cpp
@@ -81,7 +81,7 @@
ParenBraceBracketBalancer BalancerRAIIObj(*this);
- ParsedAttributesWithRange attrs;
+ ParsedAttributesWithRange attrs(AttrFactory);
MaybeParseCXX0XAttributes(attrs);
// Cases in this switch statement should fall through if the parser expects
@@ -500,7 +500,7 @@
ConsumeToken();
}
- DeclSpec DS;
+ DeclSpec DS(AttrFactory);
DeclGroupPtrTy Res = Actions.FinalizeDeclaratorGroup(getCurScope(), DS,
DeclsInGroup.data(), DeclsInGroup.size());
StmtResult R = Actions.ActOnDeclStmt(Res, LabelLoc, Tok.getLocation());
@@ -528,7 +528,7 @@
while (Tok.is(tok::kw___extension__))
ConsumeToken();
- ParsedAttributesWithRange attrs;
+ ParsedAttributesWithRange attrs(AttrFactory);
MaybeParseCXX0XAttributes(attrs);
// If this is the start of a declaration, parse it as such.
@@ -1049,7 +1049,7 @@
if (!C99orCXXorObjC) // Use of C99-style for loops in C90 mode?
Diag(Tok, diag::ext_c99_variable_decl_in_for_loop);
- ParsedAttributesWithRange attrs;
+ ParsedAttributesWithRange attrs(AttrFactory);
MaybeParseCXX0XAttributes(attrs);
SourceLocation DeclStart = Tok.getLocation(), DeclEnd;
@@ -1359,7 +1359,7 @@
msAsm = true;
return FuzzyParseMicrosoftAsmStatement(AsmLoc);
}
- DeclSpec DS;
+ DeclSpec DS(AttrFactory);
SourceLocation Loc = Tok.getLocation();
ParseTypeQualifierListOpt(DS, true, false);
@@ -1643,7 +1643,7 @@
if (Tok.isNot(tok::l_brace))
return StmtError(Diag(Tok, diag::err_expected_lbrace));
// FIXME: Possible draft standard bug: attribute-specifier should be allowed?
- ParsedAttributesWithRange attrs;
+ ParsedAttributesWithRange attrs(AttrFactory);
StmtResult TryBlock(ParseCompoundStatement(attrs));
if (TryBlock.isInvalid())
return move(TryBlock);
@@ -1696,7 +1696,7 @@
// without default arguments.
Decl *ExceptionDecl = 0;
if (Tok.isNot(tok::ellipsis)) {
- DeclSpec DS;
+ DeclSpec DS(AttrFactory);
if (ParseCXXTypeSpecifierSeq(DS))
return StmtError();
Declarator ExDecl(DS, Declarator::CXXCatchContext);
@@ -1712,7 +1712,7 @@
return StmtError(Diag(Tok, diag::err_expected_lbrace));
// FIXME: Possible draft standard bug: attribute-specifier should be allowed?
- ParsedAttributes attrs;
+ ParsedAttributes attrs(AttrFactory);
StmtResult Block(ParseCompoundStatement(attrs));
if (Block.isInvalid())
return move(Block);
diff --git a/lib/Parse/ParseTemplate.cpp b/lib/Parse/ParseTemplate.cpp
index 799c617..84b3788 100644
--- a/lib/Parse/ParseTemplate.cpp
+++ b/lib/Parse/ParseTemplate.cpp
@@ -196,7 +196,7 @@
return 0;
}
- ParsedAttributesWithRange prefixAttrs;
+ ParsedAttributesWithRange prefixAttrs(AttrFactory);
MaybeParseCXX0XAttributes(prefixAttrs);
if (Tok.is(tok::kw_using))
@@ -205,7 +205,7 @@
// Parse the declaration specifiers, stealing the accumulated
// diagnostics from the template parameters.
- ParsingDeclSpec DS(DiagsFromTParams);
+ ParsingDeclSpec DS(*this, &DiagsFromTParams);
DS.takeAttributesFrom(prefixAttrs);
@@ -598,7 +598,7 @@
// Parse the declaration-specifiers (i.e., the type).
// FIXME: The type should probably be restricted in some way... Not all
// declarators (parts of declarators?) are accepted for parameters.
- DeclSpec DS;
+ DeclSpec DS(AttrFactory);
ParseDeclarationSpecifiers(DS);
// Parse this as a typename.
diff --git a/lib/Parse/ParseTentative.cpp b/lib/Parse/ParseTentative.cpp
index 68b599b..775bc93 100644
--- a/lib/Parse/ParseTentative.cpp
+++ b/lib/Parse/ParseTentative.cpp
@@ -1151,7 +1151,7 @@
return TPResult::True(); // '...' is a sign of a function declarator.
}
- ParsedAttributes attrs;
+ ParsedAttributes attrs(AttrFactory);
MaybeParseMicrosoftAttributes(attrs);
// decl-specifier-seq
diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp
index f18531e..4cdf2de 100644
--- a/lib/Parse/Parser.cpp
+++ b/lib/Parse/Parser.cpp
@@ -441,7 +441,7 @@
return true;
}
- ParsedAttributesWithRange attrs;
+ ParsedAttributesWithRange attrs(AttrFactory);
MaybeParseCXX0XAttributes(attrs);
MaybeParseMicrosoftAttributes(attrs);
@@ -839,7 +839,7 @@
SourceLocation DSStart = Tok.getLocation();
// Parse the common declaration-specifiers piece.
- DeclSpec DS;
+ DeclSpec DS(AttrFactory);
ParseDeclarationSpecifiers(DS);
// C99 6.9.1p6: 'each declaration in the declaration list shall have at
diff --git a/lib/Sema/AttributeList.cpp b/lib/Sema/AttributeList.cpp
index ae5ea67..792ab4e 100644
--- a/lib/Sema/AttributeList.cpp
+++ b/lib/Sema/AttributeList.cpp
@@ -12,46 +12,89 @@
//===----------------------------------------------------------------------===//
#include "clang/Sema/AttributeList.h"
+#include "clang/AST/Expr.h"
#include "clang/Basic/IdentifierTable.h"
#include "llvm/ADT/StringSwitch.h"
using namespace clang;
-AttributeList::AttributeList(llvm::BumpPtrAllocator &Alloc,
- IdentifierInfo *aName, SourceLocation aLoc,
- IdentifierInfo *sName, SourceLocation sLoc,
- IdentifierInfo *pName, SourceLocation pLoc,
- Expr **ExprList, unsigned numArgs,
- bool declspec, bool cxx0x)
- : AttrName(aName), AttrLoc(aLoc), ScopeName(sName),
- ScopeLoc(sLoc),
- ParmName(pName), ParmLoc(pLoc), NumArgs(numArgs), Next(0),
- DeclspecAttribute(declspec), CXX0XAttribute(cxx0x), Invalid(false) {
-
- if (numArgs == 0)
- Args = 0;
- else {
- // Allocate the Args array using the BumpPtrAllocator.
- Args = Alloc.Allocate<Expr*>(numArgs);
- memcpy(Args, ExprList, numArgs*sizeof(Args[0]));
- }
+size_t AttributeList::allocated_size() const {
+ if (IsAvailability) return AttributeFactory::AvailabilityAllocSize;
+ return (sizeof(AttributeList) + NumArgs * sizeof(Expr*));
}
-AttributeList::AttributeList(llvm::BumpPtrAllocator &Alloc,
- IdentifierInfo *AttrName, SourceLocation AttrLoc,
- IdentifierInfo *ScopeName, SourceLocation ScopeLoc,
- IdentifierInfo *ParmName, SourceLocation ParmLoc,
- const AvailabilityChange &Introduced,
- const AvailabilityChange &Deprecated,
- const AvailabilityChange &Obsoleted,
- bool declspec, bool cxx0x)
- : AttrName(AttrName), AttrLoc(AttrLoc), ScopeName(ScopeName),
- ScopeLoc(ScopeLoc), ParmName(ParmName), ParmLoc(ParmLoc),
- Args(0), NumArgs(0), Next(0),
- DeclspecAttribute(declspec), CXX0XAttribute(cxx0x),
- AvailabilityIntroduced(Introduced),
- AvailabilityDeprecated(Deprecated),
- AvailabilityObsoleted(Obsoleted),
- Invalid(false) {
+AttributeFactory::AttributeFactory() {
+ // Go ahead and configure all the inline capacity. This is just a memset.
+ FreeLists.resize(InlineFreeListsCapacity);
+}
+AttributeFactory::~AttributeFactory() {}
+
+static size_t getFreeListIndexForSize(size_t size) {
+ assert(size >= sizeof(AttributeList));
+ assert((size % sizeof(void*)) == 0);
+ return ((size - sizeof(AttributeList)) / sizeof(void*));
+}
+
+void *AttributeFactory::allocate(size_t size) {
+ // Check for a previously reclaimed attribute.
+ size_t index = getFreeListIndexForSize(size);
+ if (index < FreeLists.size()) {
+ if (AttributeList *attr = FreeLists[index]) {
+ FreeLists[index] = attr->NextInPool;
+ return attr;
+ }
+ }
+
+ // Otherwise, allocate something new.
+ return Alloc.Allocate(size, llvm::AlignOf<AttributeFactory>::Alignment);
+}
+
+void AttributeFactory::reclaimPool(AttributeList *cur) {
+ assert(cur && "reclaiming empty pool!");
+ do {
+ // Read this here, because we're going to overwrite NextInPool
+ // when we toss 'cur' into the appropriate queue.
+ AttributeList *next = cur->NextInPool;
+
+ size_t size = cur->allocated_size();
+ size_t freeListIndex = getFreeListIndexForSize(size);
+
+ // Expand FreeLists to the appropriate size, if required.
+ if (freeListIndex >= FreeLists.size())
+ FreeLists.resize(freeListIndex+1);
+
+ // Add 'cur' to the appropriate free-list.
+ cur->NextInPool = FreeLists[freeListIndex];
+ FreeLists[freeListIndex] = cur;
+
+ cur = next;
+ } while (cur);
+}
+
+void AttributePool::takePool(AttributeList *pool) {
+ assert(pool);
+
+ // Fast path: this pool is empty.
+ if (!Head) {
+ Head = pool;
+ return;
+ }
+
+ // Reverse the pool onto the current head. This optimizes for the
+ // pattern of pulling a lot of pools into a single pool.
+ do {
+ AttributeList *next = pool->NextInPool;
+ pool->NextInPool = Head;
+ Head = pool;
+ pool = next;
+ } while (pool);
+}
+
+AttributeList *
+AttributePool::createIntegerAttribute(ASTContext &C, IdentifierInfo *Name,
+ SourceLocation TokLoc, int Arg) {
+ Expr *IArg = IntegerLiteral::Create(C, llvm::APInt(32, (uint64_t) Arg),
+ C.IntTy, TokLoc);
+ return create(Name, TokLoc, 0, TokLoc, 0, TokLoc, &IArg, 1, 0);
}
AttributeList::Kind AttributeList::getKind(const IdentifierInfo *Name) {
diff --git a/lib/Sema/DeclSpec.cpp b/lib/Sema/DeclSpec.cpp
index 8cbf9d9..9bbeef7 100644
--- a/lib/Sema/DeclSpec.cpp
+++ b/lib/Sema/DeclSpec.cpp
@@ -134,8 +134,7 @@
/// DeclaratorChunk::getFunction - Return a DeclaratorChunk for a function.
/// "TheDeclarator" is the declarator that this will be added to.
-DeclaratorChunk DeclaratorChunk::getFunction(const ParsedAttributes &attrs,
- bool hasProto, bool isVariadic,
+DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto, bool isVariadic,
SourceLocation EllipsisLoc,
ParamInfo *ArgInfo,
unsigned NumArgs,
@@ -157,7 +156,7 @@
I.Kind = Function;
I.Loc = LocalRangeBegin;
I.EndLoc = LocalRangeEnd;
- I.Fun.AttrList = attrs.getList();
+ I.Fun.AttrList = 0;
I.Fun.hasPrototype = hasProto;
I.Fun.isVariadic = isVariadic;
I.Fun.EllipsisLoc = EllipsisLoc.getRawEncoding();
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 544d1ae..a6c1543 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -5502,7 +5502,8 @@
// Implicitly declare the argument as type 'int' for lack of a better
// type.
- DeclSpec DS;
+ AttributeFactory attrs;
+ DeclSpec DS(attrs);
const char* PrevSpec; // unused
unsigned DiagID; // unused
DS.SetTypeSpecType(DeclSpec::TST_int, FTI.ArgInfo[i].IdentLoc,
@@ -5838,17 +5839,18 @@
// Set a Declarator for the implicit definition: int foo();
const char *Dummy;
- DeclSpec DS;
+ AttributeFactory attrFactory;
+ DeclSpec DS(attrFactory);
unsigned DiagID;
bool Error = DS.SetTypeSpecType(DeclSpec::TST_int, Loc, Dummy, DiagID);
(void)Error; // Silence warning.
assert(!Error && "Error setting up implicit decl!");
Declarator D(DS, Declarator::BlockContext);
- D.AddTypeInfo(DeclaratorChunk::getFunction(ParsedAttributes(),
- false, false, SourceLocation(), 0,
+ D.AddTypeInfo(DeclaratorChunk::getFunction(false, false, SourceLocation(), 0,
0, 0, true, SourceLocation(),
EST_None, SourceLocation(),
0, 0, 0, 0, Loc, Loc, D),
+ DS.getAttributes(),
SourceLocation());
D.SetIdentifier(&II, Loc);
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index b3cdbb2..5324229 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -536,7 +536,6 @@
// ...and *prepend* it to the declarator.
declarator.AddInnermostTypeInfo(DeclaratorChunk::getFunction(
- ParsedAttributes(),
/*proto*/ true,
/*variadic*/ false, SourceLocation(),
/*args*/ 0, 0,