aboutsummaryrefslogtreecommitdiff
path: root/lib/Parse/ParseDecl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Parse/ParseDecl.cpp')
-rw-r--r--lib/Parse/ParseDecl.cpp175
1 files changed, 86 insertions, 89 deletions
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index 6928d0d6d0..976e60f0c9 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -33,7 +33,7 @@ using namespace clang;
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 @@ void Parser::ParseGNUAttributes(ParsedAttributes &attrs,
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 @@ void Parser::ParseGNUAttributes(ParsedAttributes &attrs,
}
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 @@ void Parser::ParseGNUAttributes(ParsedAttributes &attrs,
// 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 @@ void Parser::ParseGNUAttributes(ParsedAttributes &attrs,
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 @@ void Parser::ParseGNUAttributes(ParsedAttributes &attrs,
// 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 @@ void Parser::ParseMicrosoftDeclSpec(ParsedAttributes &attrs) {
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 @@ void Parser::ParseMicrosoftTypeAttributes(ParsedAttributes &attrs) {
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 @@ void Parser::ParseBorlandTypeAttributes(ParsedAttributes &attrs) {
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 @@ void Parser::ParseOpenCLAttributes(ParsedAttributes &attrs) {
// 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 @@ void Parser::ParseOpenCLQualifiers(DeclSpec &DS) {
// 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 @@ void Parser::ParseAvailabilityAttribute(IdentifierInfo &Availability,
*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 @@ void Parser::ParseStructUnionBody(SourceLocation RecordLoc,
}
// Parse all the comma separated declarators.
- DeclSpec DS;
+ DeclSpec DS(AttrFactory);
if (!Tok.is(tok::at)) {
struct CFieldCallback : FieldCallback {
@@ -2236,7 +2234,7 @@ void Parser::ParseStructUnionBody(SourceLocation RecordLoc,
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 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
}
// If attributes exist after tag, parse them.
- ParsedAttributes attrs;
+ ParsedAttributes attrs(AttrFactory);
MaybeParseGNUAttributes(attrs);
CXXScopeSpec &SS = DS.getTypeSpecScope();
@@ -2526,7 +2524,7 @@ void Parser::ParseEnumBody(SourceLocation StartLoc, Decl *EnumDecl) {
SourceLocation IdentLoc = ConsumeToken();
// If attributes exist after the enumerator, parse them.
- ParsedAttributes attrs;
+ ParsedAttributes attrs(AttrFactory);
MaybeParseGNUAttributes(attrs);
SourceLocation EqualLoc;
@@ -2570,7 +2568,7 @@ void Parser::ParseEnumBody(SourceLocation StartLoc, Decl *EnumDecl) {
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 @@ bool Parser::isConstructorDeclarator() {
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 @@ void Parser::ParseTypeQualifierListOpt(DeclSpec &DS,
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 @@ void Parser::ParseDeclaratorInternal(Declarator &D,
SourceLocation Loc = ConsumeToken();
D.SetRangeEnd(Loc);
- DeclSpec DS;
+ DeclSpec DS(AttrFactory);
ParseTypeQualifierListOpt(DS);
D.ExtendWithDeclSpec(DS);
@@ -3102,7 +3100,8 @@ 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.getAttributes(),
/* Don't replace range end. */SourceLocation());
return;
}
@@ -3126,7 +3125,7 @@ void Parser::ParseDeclaratorInternal(Declarator &D,
if (Kind == tok::star || Kind == tok::caret) {
// Is a pointer.
- DeclSpec DS;
+ DeclSpec DS(AttrFactory);
ParseTypeQualifierListOpt(DS);
D.ExtendWithDeclSpec(DS);
@@ -3138,17 +3137,18 @@ void Parser::ParseDeclaratorInternal(Declarator &D,
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 @@ 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(),
Kind == tok::amp),
+ DS.getAttributes(),
SourceLocation());
}
}
@@ -3362,7 +3362,7 @@ void Parser::ParseDirectDeclarator(Declarator &D) {
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 @@ 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.
//
- ParsedAttributes attrs;
+ ParsedAttributes attrs(AttrFactory);
bool RequiresArg = false;
if (Tok.is(tok::kw___attribute)) {
ParseGNUAttributes(attrs);
@@ -3445,13 +3445,12 @@ void Parser::ParseParenDeclarator(Declarator &D) {
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 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
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 @@ 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(attrs,
- /*prototype*/getLang().CPlusPlus,
+ D.AddTypeInfo(DeclaratorChunk::getFunction(/*prototype*/getLang().CPlusPlus,
/*variadic*/ false,
SourceLocation(),
/*arglist*/ 0, 0,
@@ -3575,7 +3573,7 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
NoexceptExpr.get() : 0,
LParenLoc, EndLoc, D,
TrailingReturnType),
- EndLoc);
+ attrs, EndLoc);
return;
}
@@ -3639,7 +3637,7 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
// 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 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
// 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 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
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 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
NoexceptExpr.get() : 0,
LParenLoc, EndLoc, D,
TrailingReturnType),
- EndLoc);
+ attrs, EndLoc);
}
/// ParseFunctionDeclaratorIdentifierList - While parsing a function declarator
@@ -3898,15 +3895,15 @@ 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(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 @@ 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);
- 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 @@ void Parser::ParseBracketDeclarator(Declarator &D) {
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 @@ void Parser::ParseBracketDeclarator(Declarator &D) {
// 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 @@ void Parser::ParseBracketDeclarator(Declarator &D) {
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: