summaryrefslogtreecommitdiffstats
path: root/clang/lib/Parse
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2010-12-24 02:08:15 +0000
committerJohn McCall <rjmccall@apple.com>2010-12-24 02:08:15 +0000
commit53fa71476d0539b031a8f91232607f5ca8f182e5 (patch)
tree9e6d370da16c00a54a4b7f8ad66553458cedf899 /clang/lib/Parse
parentb4d271ef46bde4815c3ca3363779645ce3513811 (diff)
downloadbcm5719-llvm-53fa71476d0539b031a8f91232607f5ca8f182e5.tar.gz
bcm5719-llvm-53fa71476d0539b031a8f91232607f5ca8f182e5.zip
Refactor how we collect attributes during parsing, and add slots for attributes
on array and function declarators. This is pretty far from complete, and I'll revisit it later if someone doesn't beat me to it. llvm-svn: 122535
Diffstat (limited to 'clang/lib/Parse')
-rw-r--r--clang/lib/Parse/ParseDecl.cpp297
-rw-r--r--clang/lib/Parse/ParseDeclCXX.cpp147
-rw-r--r--clang/lib/Parse/ParseExpr.cpp27
-rw-r--r--clang/lib/Parse/ParseExprCXX.cpp11
-rw-r--r--clang/lib/Parse/ParseObjc.cpp56
-rw-r--r--clang/lib/Parse/ParseStmt.cpp101
-rw-r--r--clang/lib/Parse/ParseTemplate.cpp10
-rw-r--r--clang/lib/Parse/ParseTentative.cpp4
-rw-r--r--clang/lib/Parse/Parser.cpp56
9 files changed, 308 insertions, 401 deletions
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index f627b2c9f42..ab9173ffab0 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -82,21 +82,20 @@ TypeResult Parser::ParseTypeName(SourceRange *Range) {
/// attributes are very simple in practice. Until we find a bug, I don't see
/// a pressing need to implement the 2 token lookahead.
-AttributeList *Parser::ParseGNUAttributes(SourceLocation *EndLoc) {
+void Parser::ParseGNUAttributes(ParsedAttributes &attrs,
+ SourceLocation *endLoc) {
assert(Tok.is(tok::kw___attribute) && "Not a GNU attribute list!");
- AttributeList *CurrAttr = 0;
-
while (Tok.is(tok::kw___attribute)) {
ConsumeToken();
if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
"attribute")) {
SkipUntil(tok::r_paren, true); // skip until ) or ;
- return CurrAttr;
+ return;
}
if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after, "(")) {
SkipUntil(tok::r_paren, true); // skip until ) or ;
- return CurrAttr;
+ return;
}
// Parse the attribute-list. e.g. __attribute__(( weak, alias("__f") ))
while (Tok.is(tok::identifier) || isDeclarationSpecifier() ||
@@ -122,8 +121,8 @@ AttributeList *Parser::ParseGNUAttributes(SourceLocation *EndLoc) {
if (Tok.is(tok::r_paren)) {
// __attribute__(( mode(byte) ))
ConsumeParen(); // ignore the right paren loc for now
- CurrAttr = AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc,
- ParmName, ParmLoc, 0, 0, CurrAttr);
+ attrs.add(AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc,
+ ParmName, ParmLoc, 0, 0));
} else if (Tok.is(tok::comma)) {
ConsumeToken();
// __attribute__(( format(printf, 1, 2) ))
@@ -146,10 +145,9 @@ AttributeList *Parser::ParseGNUAttributes(SourceLocation *EndLoc) {
}
if (ArgExprsOk && Tok.is(tok::r_paren)) {
ConsumeParen(); // ignore the right paren loc for now
- CurrAttr = AttrFactory.Create(AttrName, AttrNameLoc, 0,
- AttrNameLoc, ParmName, ParmLoc,
- ArgExprs.take(), ArgExprs.size(),
- CurrAttr);
+ attrs.add(AttrFactory.Create(AttrName, AttrNameLoc, 0,
+ AttrNameLoc, ParmName, ParmLoc,
+ ArgExprs.take(), ArgExprs.size()));
}
}
} else { // not an identifier
@@ -158,8 +156,8 @@ AttributeList *Parser::ParseGNUAttributes(SourceLocation *EndLoc) {
// parse a possibly empty comma separated list of expressions
// __attribute__(( nonnull() ))
ConsumeParen(); // ignore the right paren loc for now
- CurrAttr = AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc,
- 0, SourceLocation(), 0, 0, CurrAttr);
+ attrs.add(AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc,
+ 0, SourceLocation(), 0, 0));
break;
case tok::kw_char:
case tok::kw_wchar_t:
@@ -174,10 +172,12 @@ AttributeList *Parser::ParseGNUAttributes(SourceLocation *EndLoc) {
case tok::kw_float:
case tok::kw_double:
case tok::kw_void:
- case tok::kw_typeof:
- CurrAttr = AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc,
- 0, SourceLocation(), 0, 0, CurrAttr);
- if (CurrAttr->getKind() == AttributeList::AT_IBOutletCollection)
+ case tok::kw_typeof: {
+ AttributeList *attr
+ = AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc,
+ 0, SourceLocation(), 0, 0);
+ attrs.add(attr);
+ if (attr->getKind() == AttributeList::AT_IBOutletCollection)
Diag(Tok, diag::err_iboutletcollection_builtintype);
// If it's a builtin type name, eat it and expect a rparen
// __attribute__(( vec_type_hint(char) ))
@@ -185,6 +185,7 @@ AttributeList *Parser::ParseGNUAttributes(SourceLocation *EndLoc) {
if (Tok.is(tok::r_paren))
ConsumeParen();
break;
+ }
default:
// __attribute__(( aligned(16) ))
ExprVector ArgExprs(Actions);
@@ -207,17 +208,16 @@ AttributeList *Parser::ParseGNUAttributes(SourceLocation *EndLoc) {
// Match the ')'.
if (ArgExprsOk && Tok.is(tok::r_paren)) {
ConsumeParen(); // ignore the right paren loc for now
- CurrAttr = AttrFactory.Create(AttrName, AttrNameLoc, 0,
- AttrNameLoc, 0, SourceLocation(), ArgExprs.take(),
- ArgExprs.size(),
- CurrAttr);
+ attrs.add(AttrFactory.Create(AttrName, AttrNameLoc, 0,
+ AttrNameLoc, 0, SourceLocation(),
+ ArgExprs.take(), ArgExprs.size()));
}
break;
}
}
} else {
- CurrAttr = AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc,
- 0, SourceLocation(), 0, 0, CurrAttr);
+ attrs.add(AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc,
+ 0, SourceLocation(), 0, 0));
}
}
if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen))
@@ -226,10 +226,9 @@ AttributeList *Parser::ParseGNUAttributes(SourceLocation *EndLoc) {
if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen)) {
SkipUntil(tok::r_paren, false);
}
- if (EndLoc)
- *EndLoc = Loc;
+ if (endLoc)
+ *endLoc = Loc;
}
- return CurrAttr;
}
/// ParseMicrosoftDeclSpec - Parse an __declspec construct
@@ -241,14 +240,14 @@ AttributeList *Parser::ParseGNUAttributes(SourceLocation *EndLoc) {
/// extended-decl-modifier[opt]
/// extended-decl-modifier extended-decl-modifier-seq
-AttributeList* Parser::ParseMicrosoftDeclSpec(AttributeList *CurrAttr) {
+void Parser::ParseMicrosoftDeclSpec(ParsedAttributes &attrs) {
assert(Tok.is(tok::kw___declspec) && "Not a declspec!");
ConsumeToken();
if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
"declspec")) {
SkipUntil(tok::r_paren, true); // skip until ) or ;
- return CurrAttr;
+ return;
}
while (Tok.getIdentifierInfo()) {
IdentifierInfo *AttrName = Tok.getIdentifierInfo();
@@ -260,23 +259,22 @@ AttributeList* Parser::ParseMicrosoftDeclSpec(AttributeList *CurrAttr) {
ExprResult ArgExpr(ParseAssignmentExpression());
if (!ArgExpr.isInvalid()) {
Expr *ExprList = ArgExpr.take();
- CurrAttr = AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc, 0,
- SourceLocation(), &ExprList, 1,
- CurrAttr, true);
+ attrs.add(AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc, 0,
+ SourceLocation(), &ExprList, 1, true));
}
if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen))
SkipUntil(tok::r_paren, false);
} else {
- CurrAttr = AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc,
- 0, SourceLocation(), 0, 0, CurrAttr, true);
+ attrs.add(AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc,
+ 0, SourceLocation(), 0, 0, true));
}
}
if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen))
SkipUntil(tok::r_paren, false);
- return CurrAttr;
+ return;
}
-AttributeList* Parser::ParseMicrosoftTypeAttributes(AttributeList *CurrAttr) {
+void Parser::ParseMicrosoftTypeAttributes(ParsedAttributes &attrs) {
// Treat these like attributes
// FIXME: Allow Sema to distinguish between these and real attributes!
while (Tok.is(tok::kw___fastcall) || Tok.is(tok::kw___stdcall) ||
@@ -287,21 +285,24 @@ AttributeList* Parser::ParseMicrosoftTypeAttributes(AttributeList *CurrAttr) {
if (Tok.is(tok::kw___ptr64) || Tok.is(tok::kw___w64))
// FIXME: Support these properly!
continue;
- CurrAttr = AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc, 0,
- SourceLocation(), 0, 0, CurrAttr, true);
+ attrs.add(AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc, 0,
+ SourceLocation(), 0, 0, true));
}
- return CurrAttr;
}
-AttributeList* Parser::ParseBorlandTypeAttributes(AttributeList *CurrAttr) {
+void Parser::ParseBorlandTypeAttributes(ParsedAttributes &attrs) {
// Treat these like attributes
while (Tok.is(tok::kw___pascal)) {
IdentifierInfo *AttrName = Tok.getIdentifierInfo();
SourceLocation AttrNameLoc = ConsumeToken();
- CurrAttr = AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc, 0,
- SourceLocation(), 0, 0, CurrAttr, true);
+ attrs.add(AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc, 0,
+ SourceLocation(), 0, 0, true));
}
- return CurrAttr;
+}
+
+void Parser::DiagnoseProhibitedAttributes(ParsedAttributesWithRange &attrs) {
+ Diag(attrs.Range.getBegin(), diag::err_attributes_not_allowed)
+ << attrs.Range;
}
/// ParseDeclaration - Parse a full 'declaration', which consists of
@@ -323,49 +324,40 @@ AttributeList* Parser::ParseBorlandTypeAttributes(AttributeList *CurrAttr) {
Parser::DeclGroupPtrTy Parser::ParseDeclaration(StmtVector &Stmts,
unsigned Context,
SourceLocation &DeclEnd,
- CXX0XAttributeList Attr) {
+ ParsedAttributesWithRange &attrs) {
ParenBraceBracketBalancer BalancerRAIIObj(*this);
Decl *SingleDecl = 0;
switch (Tok.getKind()) {
case tok::kw_template:
case tok::kw_export:
- if (Attr.HasAttr)
- Diag(Attr.Range.getBegin(), diag::err_attributes_not_allowed)
- << Attr.Range;
+ ProhibitAttributes(attrs);
SingleDecl = ParseDeclarationStartingWithTemplate(Context, DeclEnd);
break;
case tok::kw_inline:
// Could be the start of an inline namespace. Allowed as an ext in C++03.
if (getLang().CPlusPlus && NextToken().is(tok::kw_namespace)) {
- if (Attr.HasAttr)
- Diag(Attr.Range.getBegin(), diag::err_attributes_not_allowed)
- << Attr.Range;
+ ProhibitAttributes(attrs);
SourceLocation InlineLoc = ConsumeToken();
SingleDecl = ParseNamespace(Context, DeclEnd, InlineLoc);
break;
}
- return ParseSimpleDeclaration(Stmts, Context, DeclEnd, Attr.AttrList,
+ return ParseSimpleDeclaration(Stmts, Context, DeclEnd, attrs,
true);
case tok::kw_namespace:
- if (Attr.HasAttr)
- Diag(Attr.Range.getBegin(), diag::err_attributes_not_allowed)
- << Attr.Range;
+ ProhibitAttributes(attrs);
SingleDecl = ParseNamespace(Context, DeclEnd);
break;
case tok::kw_using:
SingleDecl = ParseUsingDirectiveOrDeclaration(Context, ParsedTemplateInfo(),
- DeclEnd, Attr);
+ DeclEnd, attrs);
break;
case tok::kw_static_assert:
- if (Attr.HasAttr)
- Diag(Attr.Range.getBegin(), diag::err_attributes_not_allowed)
- << Attr.Range;
+ ProhibitAttributes(attrs);
SingleDecl = ParseStaticAssertDeclaration(DeclEnd);
break;
default:
- return ParseSimpleDeclaration(Stmts, Context, DeclEnd, Attr.AttrList,
- true);
+ return ParseSimpleDeclaration(Stmts, Context, DeclEnd, attrs, true);
}
// This routine returns a DeclGroup, if the thing we parsed only contains a
@@ -383,12 +375,11 @@ Parser::DeclGroupPtrTy Parser::ParseDeclaration(StmtVector &Stmts,
Parser::DeclGroupPtrTy Parser::ParseSimpleDeclaration(StmtVector &Stmts,
unsigned Context,
SourceLocation &DeclEnd,
- AttributeList *Attr,
+ ParsedAttributes &attrs,
bool RequireSemi) {
// Parse the common declaration-specifiers piece.
ParsingDeclSpec DS(*this);
- if (Attr)
- DS.AddAttributes(Attr);
+ DS.takeAttributesFrom(attrs);
ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS_none,
getDeclSpecContextFromDeclaratorContext(Context));
StmtResult R = Actions.ActOnVlaStmt(DS);
@@ -482,11 +473,7 @@ Parser::DeclGroupPtrTy Parser::ParseDeclGroup(ParsingDeclSpec &DS,
// short __attribute__((common)) var; -> declspec
// short var __attribute__((common)); -> declarator
// short x, __attribute__((common)) var; -> declarator
- if (Tok.is(tok::kw___attribute)) {
- SourceLocation Loc;
- AttributeList *AttrList = ParseGNUAttributes(&Loc);
- D.AddAttributes(AttrList, Loc);
- }
+ MaybeParseGNUAttributes(D);
ParseDeclarator(D);
@@ -555,12 +542,7 @@ Decl *Parser::ParseDeclarationAfterDeclarator(Declarator &D,
D.SetRangeEnd(Loc);
}
- // If attributes are present, parse them.
- if (Tok.is(tok::kw___attribute)) {
- SourceLocation Loc;
- AttributeList *AttrList = ParseGNUAttributes(&Loc);
- D.AddAttributes(AttrList, Loc);
- }
+ MaybeParseGNUAttributes(D);
// Inform the current actions module that we just parsed this declarator.
Decl *ThisDecl = 0;
@@ -688,7 +670,7 @@ void Parser::ParseSpecifierQualifierList(DeclSpec &DS) {
// Validate declspec for type-name.
unsigned Specs = DS.getParsedSpecifiers();
if (Specs == DeclSpec::PQ_None && !DS.getNumProtocolQualifiers() &&
- !DS.getAttributes())
+ !DS.hasAttributes())
Diag(Tok, diag::err_typename_requires_specqual);
// Issue diagnostic and remove storage class if present.
@@ -1191,12 +1173,12 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
// GNU attributes support.
case tok::kw___attribute:
- DS.AddAttributes(ParseGNUAttributes());
+ ParseGNUAttributes(DS.getAttributes());
continue;
// Microsoft declspec support.
case tok::kw___declspec:
- DS.AddAttributes(ParseMicrosoftDeclSpec());
+ ParseMicrosoftDeclSpec(DS.getAttributes());
continue;
// Microsoft single token adornments.
@@ -1210,12 +1192,12 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
case tok::kw___stdcall:
case tok::kw___fastcall:
case tok::kw___thiscall:
- DS.AddAttributes(ParseMicrosoftTypeAttributes());
+ ParseMicrosoftTypeAttributes(DS.getAttributes());
continue;
// Borland single token adornments.
case tok::kw___pascal:
- DS.AddAttributes(ParseBorlandTypeAttributes());
+ ParseBorlandTypeAttributes(DS.getAttributes());
continue;
// storage-class-specifier
@@ -1692,11 +1674,11 @@ bool Parser::ParseOptionalTypeSpecifier(DeclSpec &DS, bool& isInvalid,
case tok::kw___stdcall:
case tok::kw___fastcall:
case tok::kw___thiscall:
- DS.AddAttributes(ParseMicrosoftTypeAttributes());
+ ParseMicrosoftTypeAttributes(DS.getAttributes());
return true;
case tok::kw___pascal:
- DS.AddAttributes(ParseBorlandTypeAttributes());
+ ParseBorlandTypeAttributes(DS.getAttributes());
return true;
default:
@@ -1759,11 +1741,8 @@ ParseStructDeclaration(DeclSpec &DS, FieldCallback &Fields) {
FieldDeclarator DeclaratorInfo(DS);
// Attributes are only allowed here on successive declarators.
- if (!FirstDeclarator && Tok.is(tok::kw___attribute)) {
- SourceLocation Loc;
- AttributeList *AttrList = ParseGNUAttributes(&Loc);
- DeclaratorInfo.D.AddAttributes(AttrList, Loc);
- }
+ if (!FirstDeclarator)
+ MaybeParseGNUAttributes(DeclaratorInfo.D);
/// struct-declarator: declarator
/// struct-declarator: declarator[opt] ':' constant-expression
@@ -1783,11 +1762,7 @@ ParseStructDeclaration(DeclSpec &DS, FieldCallback &Fields) {
}
// If attributes exist after the declarator, parse them.
- if (Tok.is(tok::kw___attribute)) {
- SourceLocation Loc;
- AttributeList *AttrList = ParseGNUAttributes(&Loc);
- DeclaratorInfo.D.AddAttributes(AttrList, Loc);
- }
+ MaybeParseGNUAttributes(DeclaratorInfo.D);
// We're done with this declarator; invoke the callback.
Decl *D = Fields.invoke(DeclaratorInfo);
@@ -1908,15 +1883,14 @@ void Parser::ParseStructUnionBody(SourceLocation RecordLoc,
SourceLocation RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBraceLoc);
- AttributeList *AttrList = 0;
+ ParsedAttributes attrs;
// If attributes exist after struct contents, parse them.
- if (Tok.is(tok::kw___attribute))
- AttrList = ParseGNUAttributes();
+ MaybeParseGNUAttributes(attrs);
Actions.ActOnFields(getCurScope(),
RecordLoc, TagDecl, FieldDecls.data(), FieldDecls.size(),
LBraceLoc, RBraceLoc,
- AttrList);
+ attrs.getList());
StructScope.Exit();
Actions.ActOnTagFinishDefinition(getCurScope(), TagDecl, RBraceLoc);
}
@@ -1958,10 +1932,9 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
ConsumeCodeCompletionToken();
}
- AttributeList *Attr = 0;
// If attributes exist after tag, parse them.
- if (Tok.is(tok::kw___attribute))
- Attr = ParseGNUAttributes();
+ ParsedAttributes attrs;
+ MaybeParseGNUAttributes(attrs);
CXXScopeSpec &SS = DS.getTypeSpecScope();
if (getLang().CPlusPlus) {
@@ -2102,7 +2075,7 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
const char *PrevSpec = 0;
unsigned DiagID;
Decl *TagDecl = Actions.ActOnTag(getCurScope(), DeclSpec::TST_enum, TUK,
- StartLoc, SS, Name, NameLoc, Attr,
+ StartLoc, SS, Name, NameLoc, attrs.getList(),
AS,
MultiTemplateParamsArg(Actions),
Owned, IsDependent, IsScopedEnum,
@@ -2185,9 +2158,8 @@ void Parser::ParseEnumBody(SourceLocation StartLoc, Decl *EnumDecl) {
SourceLocation IdentLoc = ConsumeToken();
// If attributes exist after the enumerator, parse them.
- AttributeList *Attr = 0;
- if (Tok.is(tok::kw___attribute))
- Attr = ParseGNUAttributes();
+ ParsedAttributes attrs;
+ MaybeParseGNUAttributes(attrs);
SourceLocation EqualLoc;
ExprResult AssignedVal;
@@ -2202,7 +2174,7 @@ void Parser::ParseEnumBody(SourceLocation StartLoc, Decl *EnumDecl) {
Decl *EnumConstDecl = Actions.ActOnEnumConstant(getCurScope(), EnumDecl,
LastEnumConstDecl,
IdentLoc, Ident,
- Attr, EqualLoc,
+ attrs.getList(), EqualLoc,
AssignedVal.release());
EnumConstantDecls.push_back(EnumConstDecl);
LastEnumConstDecl = EnumConstDecl;
@@ -2229,14 +2201,13 @@ void Parser::ParseEnumBody(SourceLocation StartLoc, Decl *EnumDecl) {
// Eat the }.
SourceLocation RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBraceLoc);
- AttributeList *Attr = 0;
// If attributes exist after the identifier list, parse them.
- if (Tok.is(tok::kw___attribute))
- Attr = ParseGNUAttributes(); // FIXME: where do they do?
+ ParsedAttributes attrs;
+ MaybeParseGNUAttributes(attrs);
Actions.ActOnEnumBody(StartLoc, LBraceLoc, RBraceLoc, EnumDecl,
EnumConstantDecls.data(), EnumConstantDecls.size(),
- getCurScope(), Attr);
+ getCurScope(), attrs.getList());
EnumScope.Exit();
Actions.ActOnTagFinishDefinition(getCurScope(), EnumDecl, RBraceLoc);
@@ -2567,9 +2538,10 @@ void Parser::ParseTypeQualifierListOpt(DeclSpec &DS,
bool CXX0XAttributesAllowed) {
if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier()) {
SourceLocation Loc = Tok.getLocation();
- CXX0XAttributeList Attr = ParseCXX0XAttributes();
+ ParsedAttributesWithRange attrs;
+ ParseCXX0XAttributes(attrs);
if (CXX0XAttributesAllowed)
- DS.AddAttributes(Attr.AttrList);
+ DS.takeAttributesFrom(attrs);
else
Diag(Loc, diag::err_attributes_not_allowed);
}
@@ -2605,19 +2577,19 @@ void Parser::ParseTypeQualifierListOpt(DeclSpec &DS,
case tok::kw___fastcall:
case tok::kw___thiscall:
if (VendorAttributesAllowed) {
- DS.AddAttributes(ParseMicrosoftTypeAttributes());
+ ParseMicrosoftTypeAttributes(DS.getAttributes());
continue;
}
goto DoneWithTypeQuals;
case tok::kw___pascal:
if (VendorAttributesAllowed) {
- DS.AddAttributes(ParseBorlandTypeAttributes());
+ ParseBorlandTypeAttributes(DS.getAttributes());
continue;
}
goto DoneWithTypeQuals;
case tok::kw___attribute:
if (VendorAttributesAllowed) {
- DS.AddAttributes(ParseGNUAttributes());
+ ParseGNUAttributes(DS.getAttributes());
continue; // do *not* consume the next token!
}
// otherwise, FALL THROUGH!
@@ -2703,7 +2675,7 @@ void Parser::ParseDeclaratorInternal(Declarator &D,
// Sema will have to catch (syntactically invalid) pointers into global
// scope. It has to catch pointers into namespace scope anyway.
D.AddTypeInfo(DeclaratorChunk::getMemberPointer(SS,DS.getTypeQualifiers(),
- Loc, DS.TakeAttributes()),
+ Loc, DS.takeAttributes()),
/* Don't replace range end. */SourceLocation());
return;
}
@@ -2737,12 +2709,12 @@ void Parser::ParseDeclaratorInternal(Declarator &D,
if (Kind == tok::star)
// Remember that we parsed a pointer type, and remember the type-quals.
D.AddTypeInfo(DeclaratorChunk::getPointer(DS.getTypeQualifiers(), Loc,
- DS.TakeAttributes()),
+ DS.takeAttributes()),
SourceLocation());
else
// Remember that we parsed a Block type, and remember the type-quals.
D.AddTypeInfo(DeclaratorChunk::getBlockPointer(DS.getTypeQualifiers(),
- Loc, DS.TakeAttributes()),
+ Loc, DS.takeAttributes()),
SourceLocation());
} else {
// Is a reference
@@ -2794,7 +2766,7 @@ void Parser::ParseDeclaratorInternal(Declarator &D,
// Remember that we parsed a reference type. It doesn't have type-quals.
D.AddTypeInfo(DeclaratorChunk::getReference(DS.getTypeQualifiers(), Loc,
- DS.TakeAttributes(),
+ DS.takeAttributes(),
Kind == tok::amp),
SourceLocation());
}
@@ -2946,12 +2918,8 @@ void Parser::ParseDirectDeclarator(Declarator &D) {
"Haven't past the location of the identifier yet?");
// Don't parse attributes unless we have an identifier.
- if (D.getIdentifier() && getLang().CPlusPlus0x
- && isCXX0XAttributeSpecifier(true)) {
- SourceLocation AttrEndLoc;
- CXX0XAttributeList Attr = ParseCXX0XAttributes();
- D.AddAttributes(Attr.AttrList, AttrEndLoc);
- }
+ if (D.getIdentifier())
+ MaybeParseCXX0XAttributes(D);
while (1) {
if (Tok.is(tok::l_paren)) {
@@ -2965,7 +2933,8 @@ void Parser::ParseDirectDeclarator(Declarator &D) {
if (!isCXXFunctionDeclarator(warnIfAmbiguous))
break;
}
- ParseFunctionDeclarator(ConsumeParen(), D);
+ ParsedAttributes attrs;
+ ParseFunctionDeclarator(ConsumeParen(), D, attrs);
} else if (Tok.is(tok::l_square)) {
ParseBracketDeclarator(D);
} else {
@@ -3001,10 +2970,10 @@ void Parser::ParseParenDeclarator(Declarator &D) {
// In either case, we need to eat any attributes to be able to determine what
// sort of paren this is.
//
- AttributeList *AttrList = 0;
+ ParsedAttributes attrs;
bool RequiresArg = false;
if (Tok.is(tok::kw___attribute)) {
- AttrList = ParseGNUAttributes();
+ ParseGNUAttributes(attrs);
// We require that the argument list (if this is a non-grouping paren) be
// present even if the attribute list was empty.
@@ -3014,11 +2983,11 @@ void Parser::ParseParenDeclarator(Declarator &D) {
if (Tok.is(tok::kw___cdecl) || Tok.is(tok::kw___stdcall) ||
Tok.is(tok::kw___thiscall) || Tok.is(tok::kw___fastcall) ||
Tok.is(tok::kw___w64) || Tok.is(tok::kw___ptr64)) {
- AttrList = ParseMicrosoftTypeAttributes(AttrList);
+ ParseMicrosoftTypeAttributes(attrs);
}
// Eat any Borland extensions.
if (Tok.is(tok::kw___pascal))
- AttrList = ParseBorlandTypeAttributes(AttrList);
+ ParseBorlandTypeAttributes(attrs);
// If we haven't past the identifier yet (or where the identifier would be
// stored, if this is an abstract declarator), then this is probably just
@@ -3047,8 +3016,8 @@ void Parser::ParseParenDeclarator(Declarator &D) {
if (isGrouping) {
bool hadGroupingParens = D.hasGroupingParens();
D.setGroupingParens(true);
- if (AttrList)
- D.AddAttributes(AttrList, SourceLocation());
+ if (!attrs.empty())
+ D.addAttributes(attrs.getList(), SourceLocation());
ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
// Match the ')'.
@@ -3065,7 +3034,7 @@ void Parser::ParseParenDeclarator(Declarator &D) {
// ParseFunctionDeclarator to handle of argument list.
D.SetIdentifier(0, Tok.getLocation());
- ParseFunctionDeclarator(StartLoc, D, AttrList, RequiresArg);
+ ParseFunctionDeclarator(StartLoc, D, attrs, RequiresArg);
}
/// ParseFunctionDeclarator - We are after the identifier and have parsed the
@@ -3101,7 +3070,7 @@ void Parser::ParseParenDeclarator(Declarator &D) {
/// and "exception-specification[opt]".
///
void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
- AttributeList *AttrList,
+ ParsedAttributes &attrs,
bool RequiresArg) {
// lparen is already consumed!
assert(D.isPastIdentifier() && "Should not call before identifier!");
@@ -3124,6 +3093,8 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
llvm::SmallVector<ParsedType, 2> Exceptions;
llvm::SmallVector<SourceRange, 2> ExceptionRanges;
if (getLang().CPlusPlus) {
+ MaybeParseCXX0XAttributes(attrs);
+
ParseTypeQualifierListOpt(DS, false /*no attributes*/);
if (!DS.getSourceRange().getEnd().isInvalid())
EndLoc = DS.getSourceRange().getEnd();
@@ -3146,7 +3117,8 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
// Remember that we parsed a function type, and remember the attributes.
// int() -> no prototype, no '...'.
- D.AddTypeInfo(DeclaratorChunk::getFunction(/*prototype*/getLang().CPlusPlus,
+ D.AddTypeInfo(DeclaratorChunk::getFunction(attrs,
+ /*prototype*/getLang().CPlusPlus,
/*variadic*/ false,
SourceLocation(),
/*arglist*/ 0, 0,
@@ -3219,22 +3191,21 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
EllipsisLoc = ConsumeToken(); // Consume the ellipsis.
break;
}
+
+ // Parse the declaration-specifiers.
+ // Just use the ParsingDeclaration "scope" of the declarator.
+ DeclSpec DS;
// Skip any Microsoft attributes before a param.
if (getLang().Microsoft && Tok.is(tok::l_square))
- ParseMicrosoftAttributes();
+ ParseMicrosoftAttributes(DS.getAttributes());
SourceLocation DSStart = Tok.getLocation();
- // Parse the declaration-specifiers.
- // Just use the ParsingDeclaration "scope" of the declarator.
- DeclSpec DS;
-
// If the caller parsed attributes for the first argument, add them now.
- if (AttrList) {
- DS.AddAttributes(AttrList);
- AttrList = 0; // Only apply the attributes to the first parameter.
- }
+ // Take them so that we only apply the attributes to the first parameter.
+ DS.takeAttributesFrom(attrs);
+
ParseDeclarationSpecifiers(DS);
// Parse the declarator. This is "PrototypeContext", because we must
@@ -3243,11 +3214,7 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
ParseDeclarator(ParmDecl);
// Parse GNU attributes, if present.
- if (Tok.is(tok::kw___attribute)) {
- SourceLocation Loc;
- AttributeList *AttrList = ParseGNUAttributes(&Loc);
- ParmDecl.AddAttributes(AttrList, Loc);
- }
+ MaybeParseGNUAttributes(ParmDecl);
// Remember this parsed parameter in ParamInfo.
IdentifierInfo *ParmII = ParmDecl.getIdentifier();
@@ -3362,6 +3329,8 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
llvm::SmallVector<SourceRange, 2> ExceptionRanges;
if (getLang().CPlusPlus) {
+ MaybeParseCXX0XAttributes(attrs);
+
// Parse cv-qualifier-seq[opt].
ParseTypeQualifierListOpt(DS, false /*no attributes*/);
if (!DS.getSourceRange().getEnd().isInvalid())
@@ -3390,7 +3359,8 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
PrototypeScope.Exit();
// Remember that we parsed a function type, and remember the attributes.
- D.AddTypeInfo(DeclaratorChunk::getFunction(/*proto*/true, IsVariadic,
+ D.AddTypeInfo(DeclaratorChunk::getFunction(attrs,
+ /*proto*/true, IsVariadic,
EllipsisLoc,
ParamInfo.data(), ParamInfo.size(),
DS.getTypeQualifiers(),
@@ -3470,7 +3440,8 @@ void Parser::ParseFunctionDeclaratorIdentifierList(SourceLocation LParenLoc,
// Remember that we parsed a function type, and remember the attributes. This
// function type is always a K&R style function type, which is not varargs and
// has no prototype.
- D.AddTypeInfo(DeclaratorChunk::getFunction(/*proto*/false, /*varargs*/false,
+ D.AddTypeInfo(DeclaratorChunk::getFunction(ParsedAttributes(),
+ /*proto*/false, /*varargs*/false,
SourceLocation(),
&ParamInfo[0], ParamInfo.size(),
/*TypeQuals*/0,
@@ -3492,15 +3463,12 @@ void Parser::ParseBracketDeclarator(Declarator &D) {
// This code does a fast path to handle some of the most obvious cases.
if (Tok.getKind() == tok::r_square) {
SourceLocation EndLoc = MatchRHSPunctuation(tok::r_square, StartLoc);
- //FIXME: Use these
- CXX0XAttributeList Attr;
- if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier(true)) {
- Attr = ParseCXX0XAttributes();
- }
+ ParsedAttributes attrs;
+ MaybeParseCXX0XAttributes(attrs);
// Remember that we parsed the empty array type.
ExprResult NumElements;
- D.AddTypeInfo(DeclaratorChunk::getArray(0, false, false, 0,
+ D.AddTypeInfo(DeclaratorChunk::getArray(0, attrs, false, false, 0,
StartLoc, EndLoc),
EndLoc);
return;
@@ -3511,18 +3479,12 @@ void Parser::ParseBracketDeclarator(Declarator &D) {
ConsumeToken();
SourceLocation EndLoc = MatchRHSPunctuation(tok::r_square, StartLoc);
- //FIXME: Use these
- CXX0XAttributeList Attr;
- if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier()) {
- Attr = ParseCXX0XAttributes();
- }
-
- // If there was an error parsing the assignment-expression, recover.
- if (ExprRes.isInvalid())
- ExprRes.release(); // Deallocate expr, just use [].
+ ParsedAttributes attrs;
+ MaybeParseCXX0XAttributes(attrs);
// Remember that we parsed a array type, and remember its features.
- D.AddTypeInfo(DeclaratorChunk::getArray(0, false, 0, ExprRes.release(),
+ D.AddTypeInfo(DeclaratorChunk::getArray(0, attrs, false, 0,
+ ExprRes.release(),
StartLoc, EndLoc),
EndLoc);
return;
@@ -3583,14 +3545,11 @@ void Parser::ParseBracketDeclarator(Declarator &D) {
SourceLocation EndLoc = MatchRHSPunctuation(tok::r_square, StartLoc);
- //FIXME: Use these
- CXX0XAttributeList Attr;
- if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier()) {
- Attr = ParseCXX0XAttributes();
- }
+ ParsedAttributes attrs;
+ MaybeParseCXX0XAttributes(attrs);
// Remember that we parsed a array type, and remember its features.
- D.AddTypeInfo(DeclaratorChunk::getArray(DS.getTypeQualifiers(),
+ D.AddTypeInfo(DeclaratorChunk::getArray(DS.getTypeQualifiers(), attrs,
StaticLoc.isValid(), isStar,
NumElements.release(),
StartLoc, EndLoc),
diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp
index e1f7f7bdc58..fe2390f1aa0 100644
--- a/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/clang/lib/Parse/ParseDeclCXX.cpp
@@ -69,16 +69,16 @@ Decl *Parser::ParseNamespace(unsigned Context,
}
// Read label attributes, if present.
- AttributeList *AttrList = 0;
+ ParsedAttributes attrs;
if (Tok.is(tok::kw___attribute)) {
attrTok = Tok;
// FIXME: save these somewhere.
- AttrList = ParseGNUAttributes();
+ ParseGNUAttributes(attrs);
}
if (Tok.is(tok::equal)) {
- if (AttrList)
+ if (!attrs.empty())
Diag(attrTok, diag::err_unexpected_namespace_attributes_alias);
if (InlineLoc.isValid())
Diag(InlineLoc, diag::err_inline_namespace_alias)
@@ -112,18 +112,16 @@ Decl *Parser::ParseNamespace(unsigned Context,
Decl *NamespcDecl =
Actions.ActOnStartNamespaceDef(getCurScope(), InlineLoc, IdentLoc, Ident,
- LBrace, AttrList);
+ LBrace, attrs.getList());
PrettyDeclStackTraceEntry CrashInfo(Actions, NamespcDecl, NamespaceLoc,
"parsing namespace");
while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
- CXX0XAttributeList Attr;
- if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier())
- Attr = ParseCXX0XAttributes();
- if (getLang().Microsoft && Tok.is(tok::l_square))
- ParseMicrosoftAttributes();
- ParseExternalDeclaration(Attr);
+ ParsedAttributesWithRange attrs;
+ MaybeParseCXX0XAttributes(attrs);
+ MaybeParseMicrosoftAttributes(attrs);
+ ParseExternalDeclaration(attrs);
}
// Leave the namespace scope.
@@ -201,34 +199,27 @@ Decl *Parser::ParseLinkage(ParsingDeclSpec &DS, unsigned Context) {
Tok.is(tok::l_brace)? Tok.getLocation()
: SourceLocation());
- CXX0XAttributeList Attr;
- if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier())
- Attr = ParseCXX0XAttributes();
-
- if (getLang().Microsoft && Tok.is(tok::l_square))
- ParseMicrosoftAttributes();
+ ParsedAttributesWithRange attrs;
+ MaybeParseCXX0XAttributes(attrs);
+ MaybeParseMicrosoftAttributes(attrs);
if (Tok.isNot(tok::l_brace)) {
DS.setExternInLinkageSpec(true);
- ParseExternalDeclaration(Attr, &DS);
+ ParseExternalDeclaration(attrs, &DS);
return Actions.ActOnFinishLinkageSpecification(getCurScope(), LinkageSpec,
SourceLocation());
}
DS.abort();
- if (Attr.HasAttr)
- Diag(Attr.Range.getBegin(), diag::err_attributes_not_allowed)
- << Attr.Range;
+ ProhibitAttributes(attrs);
SourceLocation LBrace = ConsumeBrace();
while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
- CXX0XAttributeList Attr;
- if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier())
- Attr = ParseCXX0XAttributes();
- if (getLang().Microsoft && Tok.is(tok::l_square))
- ParseMicrosoftAttributes();
- ParseExternalDeclaration(Attr);
+ ParsedAttributesWithRange attrs;
+ MaybeParseCXX0XAttributes(attrs);
+ MaybeParseMicrosoftAttributes(attrs);
+ ParseExternalDeclaration(attrs);
}
SourceLocation RBrace = MatchRHSPunctuation(tok::r_brace, LBrace);
@@ -241,7 +232,7 @@ Decl *Parser::ParseLinkage(ParsingDeclSpec &DS, unsigned Context) {
Decl *Parser::ParseUsingDirectiveOrDeclaration(unsigned Context,
const ParsedTemplateInfo &TemplateInfo,
SourceLocation &DeclEnd,
- CXX0XAttributeList Attr) {
+ ParsedAttributesWithRange &attrs) {
assert(Tok.is(tok::kw_using) && "Not using token");
// Eat 'using'.
@@ -261,15 +252,13 @@ Decl *Parser::ParseUsingDirectiveOrDeclaration(unsigned Context,
<< R << FixItHint::CreateRemoval(R);
}
- return ParseUsingDirective(Context, UsingLoc, DeclEnd, Attr.AttrList);
+ return ParseUsingDirective(Context, UsingLoc, DeclEnd, attrs);
}
// Otherwise, it must be a using-declaration.
// Using declarations can't have attributes.
- if (Attr.HasAttr)
- Diag(Attr.Range.getBegin(), diag::err_attributes_not_allowed)
- << Attr.Range;
+ ProhibitAttributes(attrs);
return ParseUsingDeclaration(Context, TemplateInfo, UsingLoc, DeclEnd);
}
@@ -287,7 +276,7 @@ Decl *Parser::ParseUsingDirectiveOrDeclaration(unsigned Context,
Decl *Parser::ParseUsingDirective(unsigned Context,
SourceLocation UsingLoc,
SourceLocation &DeclEnd,
- AttributeList *Attr) {
+ ParsedAttributes &attrs) {
assert(Tok.is(tok::kw_namespace) && "Not 'namespace' token");
// Eat 'namespace'.
@@ -322,7 +311,7 @@ Decl *Parser::ParseUsingDirective(unsigned Context,
bool GNUAttr = false;
if (Tok.is(tok::kw___attribute)) {
GNUAttr = true;
- Attr = addAttributeLists(Attr, ParseGNUAttributes());
+ ParseGNUAttributes(attrs);
}
// Eat ';'.
@@ -333,7 +322,7 @@ Decl *Parser::ParseUsingDirective(unsigned Context,
"", tok::semi);
return Actions.ActOnUsingDirective(getCurScope(), UsingLoc, NamespcLoc, SS,
- IdentLoc, NamespcName, Attr);
+ IdentLoc, NamespcName, attrs.getList());
}
/// ParseUsingDeclaration - Parse C++ using-declaration. Assumes that
@@ -391,14 +380,13 @@ Decl *Parser::ParseUsingDeclaration(unsigned Context,
}
// Parse (optional) attributes (most likely GNU strong-using extension).
- AttributeList *AttrList = 0;
- if (Tok.is(tok::kw___attribute))
- AttrList = ParseGNUAttributes();
+ ParsedAttributes attrs;
+ MaybeParseGNUAttributes(attrs);
// Eat ';'.
DeclEnd = Tok.getLocation();
ExpectAndConsume(tok::semi, diag::err_expected_semi_after,
- AttrList ? "attributes list" : "using declaration",
+ !attrs.empty() ? "attributes list" : "using declaration",
tok::semi);
// Diagnose an attempt to declare a templated using-declaration.
@@ -414,7 +402,8 @@ Decl *Parser::ParseUsingDeclaration(unsigned Context,
}
return Actions.ActOnUsingDeclaration(getCurScope(), AS, true, UsingLoc, SS,
- Name, AttrList, IsTypeName, TypenameLoc);
+ Name, attrs.getList(),
+ IsTypeName, TypenameLoc);
}
/// ParseStaticAssertDeclaration - Parse C++0x static_assert-declaratoion.
@@ -685,20 +674,19 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
SuppressingAccessChecks = true;
}
- AttributeList *AttrList = 0;
+ ParsedAttributes attrs;
// If attributes exist after tag, parse them.
if (Tok.is(tok::kw___attribute))
- AttrList = ParseGNUAttributes();
+ ParseGNUAttributes(attrs);
// If declspecs exist after tag, parse them.
while (Tok.is(tok::kw___declspec))
- AttrList = ParseMicrosoftDeclSpec(AttrList);
+ ParseMicrosoftDeclSpec(attrs);
// If C++0x attributes exist here, parse them.
// FIXME: Are we consistent with the ordering of parsing of different
// styles of attributes?
- if (isCXX0XAttributeSpecifier())
- AttrList = addAttributeLists(AttrList, ParseCXX0XAttributes().AttrList);
+ MaybeParseCXX0XAttributes(attrs);
if (TagType == DeclSpec::TST_struct && Tok.is(tok::kw___is_pod)) {
// GNU libstdc++ 4.2 uses __is_pod as the name of a struct template, but
@@ -892,7 +880,7 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
TemplateId->LAngleLoc,
TemplateArgsPtr,
TemplateId->RAngleLoc,
- AttrList);
+ attrs.getList());
// Friend template-ids are treated as references unless
// they have template headers, in which case they're ill-formed
@@ -954,7 +942,7 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
TemplateId->LAngleLoc,
TemplateArgsPtr,
TemplateId->RAngleLoc,
- AttrList,
+ attrs.getList(),
MultiTemplateParamsArg(Actions,
TemplateParams? &(*TemplateParams)[0] : 0,
TemplateParams? TemplateParams->size() : 0));
@@ -972,13 +960,13 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
TemplateInfo.ExternLoc,
TemplateInfo.TemplateLoc,
TagType, StartLoc, SS, Name,
- NameLoc, AttrList);
+ NameLoc, attrs.getList());
} else if (TUK == Sema::TUK_Friend &&
TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate) {
TagOrTempResult =
Actions.ActOnTemplatedFriendTag(getCurScope(), DS.getFriendSpecLoc(),
TagType, StartLoc, SS,
- Name, NameLoc, AttrList,
+ Name, NameLoc, attrs.getList(),
MultiTemplateParamsArg(Actions,
TemplateParams? &(*TemplateParams)[0] : 0,
TemplateParams? TemplateParams->size() : 0));
@@ -1000,7 +988,7 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
// Declaration or definition of a class type
TagOrTempResult = Actions.ActOnTag(getCurScope(), TagType, TUK, StartLoc,
- SS, Name, NameLoc, AttrList, AS,
+ SS, Name, NameLoc, attrs.getList(), AS,
TParams, Owned, IsDependent, false,
false, clang::TypeResult());
@@ -1364,19 +1352,15 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
// is a bitfield.
ColonProtectionRAIIObject X(*this);
- CXX0XAttributeList AttrList;
+ ParsedAttributesWithRange attrs;
// Optional C++0x attribute-specifier
- if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier())
- AttrList = ParseCXX0XAttributes();
- if (getLang().Microsoft && Tok.is(tok::l_square))
- ParseMicrosoftAttributes();
+ MaybeParseCXX0XAttributes(attrs);
+ MaybeParseMicrosoftAttributes(attrs);
if (Tok.is(tok::kw_using)) {
// FIXME: Check for template aliases
- if (AttrList.HasAttr)
- Diag(AttrList.Range.getBegin(), diag::err_attributes_not_allowed)
- << AttrList.Range;
+ ProhibitAttributes(attrs);
// Eat 'using'.
SourceLocation UsingLoc = ConsumeToken();
@@ -1397,7 +1381,7 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
// decl-specifier-seq:
// Parse the common declaration-specifiers piece.
ParsingDeclSpec DS(*this, TemplateDiags);
- DS.AddAttributes(AttrList.AttrList);
+ DS.takeAttributesFrom(attrs);
ParseDeclarationSpecifiers(DS, TemplateInfo, AS, DSC_class);
MultiTemplateParamsArg TemplateParams(Actions,
@@ -1430,11 +1414,7 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
}
// If attributes exist after the declarator, but before an '{', parse them.
- if (Tok.is(tok::kw___attribute)) {
- SourceLocation Loc;
- AttributeList *AttrList = ParseGNUAttributes(&Loc);
- DeclaratorInfo.AddAttributes(AttrList, Loc);
- }
+ MaybeParseGNUAttributes(DeclaratorInfo);
// function-definition:
if (Tok.is(tok::l_brace)
@@ -1518,11 +1498,7 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
}
// If attributes exist after the declarator, parse them.
- if (Tok.is(tok::kw___attribute)) {
- SourceLocation Loc;
- AttributeList *AttrList = ParseGNUAttributes(&Loc);
- DeclaratorInfo.AddAttributes(AttrList, Loc);
- }
+ MaybeParseGNUAttributes(DeclaratorInfo);
// NOTE: If Sema is the Action module and declarator is an instance field,
// this call will *not* return the created decl; It will return null.
@@ -1569,11 +1545,7 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
Deleted = false;
// Attributes are only allowed on the second declarator.
- if (Tok.is(tok::kw___attribute)) {
- SourceLocation Loc;
- AttributeList *AttrList = ParseGNUAttributes(&Loc);
- DeclaratorInfo.AddAttributes(AttrList, Loc);
- }
+ MaybeParseGNUAttributes(DeclaratorInfo);
if (Tok.isNot(tok::colon))
ParseDeclarator(DeclaratorInfo);
@@ -1708,14 +1680,13 @@ void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc,
}
// If attributes exist after class contents, parse them.
- AttributeList *AttrList = 0;
- if (Tok.is(tok::kw___attribute))
- AttrList = ParseGNUAttributes();
+ ParsedAttributes attrs;
+ MaybeParseGNUAttributes(attrs);
if (TagDecl)
Actions.ActOnFinishCXXMemberSpecification(getCurScope(), RecordLoc, TagDecl,
LBraceLoc, RBraceLoc,
- AttrList);
+ attrs.getList());
// C++ 9.2p2: Within the class member-specification, the class is regarded as
// complete within function bodies, default arguments,
@@ -2043,12 +2014,12 @@ void Parser::PopParsingClass() {
/// '[' balanced-token-seq ']'
/// '{' balanced-token-seq '}'
/// any token but '(', ')', '[', ']', '{', or '}'
-CXX0XAttributeList Parser::ParseCXX0XAttributes(SourceLocation *EndLoc) {
+void Parser::ParseCXX0XAttributes(ParsedAttributesWithRange &attrs,
+ SourceLocation *endLoc) {
assert(Tok.is(tok::l_square) && NextToken().is(tok::l_square)
&& "Not a C++0x attribute list");
SourceLocation StartLoc = Tok.getLocation(), Loc;
- AttributeList *CurrAttr = 0;
ConsumeBracket();
ConsumeBracket();
@@ -2104,9 +2075,8 @@ CXX0XAttributeList Parser::ParseCXX0XAttributes(SourceLocation *EndLoc) {
break;
}
- CurrAttr = AttrFactory.Create(AttrName, AttrLoc, 0, AttrLoc, 0,
- SourceLocation(), 0, 0, CurrAttr, false,
- true);
+ attrs.add(AttrFactory.Create(AttrName, AttrLoc, 0, AttrLoc, 0,
+ SourceLocation(), 0, 0, false, true));
AttrParsed = true;
break;
}
@@ -2126,9 +2096,9 @@ CXX0XAttributeList Parser::ParseCXX0XAttributes(SourceLocation *EndLoc) {
ExprVector ArgExprs(Actions);
ArgExprs.push_back(ArgExpr.release());
- CurrAttr = AttrFactory.Create(AttrName, AttrLoc, 0, AttrLoc,
- 0, ParamLoc, ArgExprs.take(), 1, CurrAttr,
- false, true);
+ attrs.add(AttrFactory.Create(AttrName, AttrLoc, 0, AttrLoc,
+ 0, ParamLoc, ArgExprs.take(), 1,
+ false, true));
AttrParsed = true;
break;
@@ -2153,8 +2123,7 @@ CXX0XAttributeList Parser::ParseCXX0XAttributes(SourceLocation *EndLoc) {
if (ExpectAndConsume(tok::r_square, diag::err_expected_rsquare))
SkipUntil(tok::r_square, false);
- CXX0XAttributeList Attr (CurrAttr, SourceRange(StartLoc, Loc), true);
- return Attr;
+ attrs.Range = SourceRange(StartLoc, Loc);
}
/// ParseCXX0XAlignArgument - Parse the argument to C++0x's [[align]]
@@ -2185,12 +2154,14 @@ ExprResult Parser::ParseCXX0XAlignArgument(SourceLocation Start) {
/// [MS] ms-attribute-seq:
/// ms-attribute[opt]
/// ms-attribute ms-attribute-seq
-void Parser::ParseMicrosoftAttributes() {
+void Parser::ParseMicrosoftAttributes(ParsedAttributes &attrs,
+ SourceLocation *endLoc) {
assert(Tok.is(tok::l_square) && "Not a Microsoft attribute list");
while (Tok.is(tok::l_square)) {
ConsumeBracket();
SkipUntil(tok::r_square, true, true);
+ if (endLoc) *endLoc = Tok.getLocation();
ExpectAndConsume(tok::r_square, diag::err_expected_rsquare);
}
}
diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp
index 47b60b5f477..92bbbd7bf9a 100644
--- a/clang/lib/Parse/ParseExpr.cpp
+++ b/clang/lib/Parse/ParseExpr.cpp
@@ -1522,7 +1522,8 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr,
if (ExprType >= CompoundStmt && Tok.is(tok::l_brace)) {
Diag(Tok, diag::ext_gnu_statement_expr);
- StmtResult Stmt(ParseCompoundStatement(0, true));
+ ParsedAttributes attrs;
+ StmtResult Stmt(ParseCompoundStatement(attrs, true));
ExprType = CompoundStmt;
// If the substmt parsed correctly, build the AST node.
@@ -1741,14 +1742,9 @@ void Parser::ParseBlockId() {
ParseDeclarator(DeclaratorInfo);
// We do this for: ^ __attribute__((noreturn)) {, as DS has the attributes.
- DeclaratorInfo.AddAttributes(DS.TakeAttributes(),
- SourceLocation());
+ DeclaratorInfo.addAttributes(DS.takeAttributes());
- if (Tok.is(tok::kw___attribute)) {
- SourceLocation Loc;
- AttributeList *AttrList = ParseGNUAttributes(&Loc);
- DeclaratorInfo.AddAttributes(AttrList, Loc);
- }
+ MaybeParseGNUAttributes(DeclaratorInfo);
// Inform sema that we are starting a block.
Actions.ActOnBlockArguments(DeclaratorInfo, getCurScope());
@@ -1806,11 +1802,7 @@ ExprResult Parser::ParseBlockLiteralExpression() {
return ExprError();
}
- if (Tok.is(tok::kw___attribute)) {
- SourceLocation Loc;
- AttributeList *AttrList = ParseGNUAttributes(&Loc);
- ParamInfo.AddAttributes(AttrList, Loc);
- }
+ MaybeParseGNUAttributes(ParamInfo);
// Inform sema that we are starting a block.
Actions.ActOnBlockArguments(ParamInfo, getCurScope());
@@ -1818,7 +1810,8 @@ ExprResult Parser::ParseBlockLiteralExpression() {
ParseBlockId();
} else {
// Otherwise, pretend we saw (void).
- ParamInfo.AddTypeInfo(DeclaratorChunk::getFunction(true, false,
+ ParamInfo.AddTypeInfo(DeclaratorChunk::getFunction(ParsedAttributes(),
+ true, false,
SourceLocation(),
0, 0, 0,
false, SourceLocation(),
@@ -1827,11 +1820,7 @@ ExprResult Parser::ParseBlockLiteralExpression() {
ParamInfo),
CaretLoc);
- if (Tok.is(tok::kw___attribute)) {
- SourceLocation Loc;
- AttributeList *AttrList = ParseGNUAttributes(&Loc);
- ParamInfo.AddAttributes(AttrList, Loc);
- }
+ MaybeParseGNUAttributes(ParamInfo);
// Inform sema that we are starting a block.
Actions.ActOnBlockArguments(ParamInfo, getCurScope());
diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp
index 8014dbd50e0..bf4b5f4b166 100644
--- a/clang/lib/Parse/ParseExprCXX.cpp
+++ b/clang/lib/Parse/ParseExprCXX.cpp
@@ -810,15 +810,11 @@ bool Parser::ParseCXXCondition(ExprResult &ExprOut,
}
// If attributes are present, parse them.
- if (Tok.is(tok::kw___attribute)) {
- SourceLocation Loc;
- AttributeList *AttrList = ParseGNUAttributes(&Loc);
- DeclaratorInfo.AddAttributes(AttrList, Loc);
- }
+ MaybeParseGNUAttributes(DeclaratorInfo);
// Type-check the declaration itself.
DeclResult Dcl = Actions.ActOnCXXConditionDeclaration(getCurScope(),
- DeclaratorInfo);
+ DeclaratorInfo);
DeclOut = Dcl.get();
ExprOut = ExprError();
@@ -1729,7 +1725,8 @@ void Parser::ParseDirectNewDeclarator(Declarator &D) {
first = false;
SourceLocation RLoc = MatchRHSPunctuation(tok::r_square, LLoc);
- D.AddTypeInfo(DeclaratorChunk::getArray(0, /*static=*/false, /*star=*/false,
+ D.AddTypeInfo(DeclaratorChunk::getArray(0, ParsedAttributes(),
+ /*static=*/false, /*star=*/false,
Size.release(), LLoc, RLoc),
RLoc);
diff --git a/clang/lib/Parse/ParseObjc.cpp b/clang/lib/Parse/ParseObjc.cpp
index cd1321ed832..c48f6803b01 100644
--- a/clang/lib/Parse/ParseObjc.cpp
+++ b/clang/lib/Parse/ParseObjc.cpp
@@ -40,10 +40,14 @@ Decl *Parser::ParseObjCAtDirectives() {
switch (Tok.getObjCKeywordID()) {
case tok::objc_class:
return ParseObjCAtClassDeclaration(AtLoc);
- case tok::objc_interface:
- return ParseObjCAtInterfaceDeclaration(AtLoc);
- case tok::objc_protocol:
- return ParseObjCAtProtocolDeclaration(AtLoc);
+ case tok::objc_interface: {
+ ParsedAttributes attrs;
+ return ParseObjCAtInterfaceDeclaration(AtLoc, attrs);
+ }
+ case tok::objc_protocol: {
+ ParsedAttributes attrs;
+ return ParseObjCAtProtocolDeclaration(AtLoc, attrs);
+ }
case tok::objc_implementation:
return ParseObjCAtImplementationDeclaration(AtLoc);
case tok::objc_end:
@@ -124,8 +128,8 @@ Decl *Parser::ParseObjCAtClassDeclaration(SourceLocation atLoc) {
/// __attribute__((unavailable))
/// __attribute__((objc_exception)) - used by NSException on 64-bit
///
-Decl *Parser::ParseObjCAtInterfaceDeclaration(
- SourceLocation atLoc, AttributeList *attrList) {
+Decl *Parser::ParseObjCAtInterfaceDeclaration(SourceLocation atLoc,
+ ParsedAttributes &attrs) {
assert(Tok.isObjCAtKeyword(tok::objc_interface) &&
"ParseObjCAtInterfaceDeclaration(): Expected @interface");
ConsumeToken(); // the "interface" identifier
@@ -178,7 +182,7 @@ Decl *Parser::ParseObjCAtInterfaceDeclaration(
LAngleLoc, EndProtoLoc))
return 0;
- if (attrList) // categories don't support attributes.
+ if (!attrs.empty()) // categories don't support attributes.
Diag(Tok, diag::err_objc_no_attributes_on_category);
Decl *CategoryType =
@@ -230,7 +234,7 @@ Decl *Parser::ParseObjCAtInterfaceDeclaration(
superClassId, superClassLoc,
ProtocolRefs.data(), ProtocolRefs.size(),
ProtocolLocs.data(),
- EndProtoLoc, attrList);
+ EndProtoLoc, attrs.getList());
if (Tok.is(tok::l_brace))
ParseObjCClassInstanceVariables(ClsType, tok::objc_protected, atLoc);
@@ -365,7 +369,8 @@ void Parser::ParseObjCInterfaceDeclList(Decl *interfaceDecl,
// FIXME: as the name implies, this rule allows function definitions.
// We could pass a flag or check for functions during semantic analysis.
- allTUVariables.push_back(ParseDeclarationOrFunctionDefinition(0));
+ ParsedAttributes attrs;
+ allTUVariables.push_back(ParseDeclarationOrFunctionDefinition(attrs));
continue;
}
@@ -830,9 +835,9 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
ReturnType = ParseObjCTypeName(DSRet, false);
// If attributes exist before the method, parse them.
- AttributeList *MethodAttrs = 0;
- if (getLang().ObjC2 && Tok.is(tok::kw___attribute))
- MethodAttrs = ParseGNUAttributes();
+ ParsedAttributes attrs;
+ if (getLang().ObjC2)
+ MaybeParseGNUAttributes(attrs);
if (Tok.is(tok::code_completion)) {
Actions.CodeCompleteObjCMethodDecl(getCurScope(), mType == tok::minus,
@@ -856,8 +861,8 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
llvm::SmallVector<DeclaratorChunk::ParamInfo, 8> CParamInfo;
if (Tok.isNot(tok::colon)) {
// If attributes exist after the method, parse them.
- if (getLang().ObjC2 && Tok.is(tok::kw___attribute))
- MethodAttrs = addAttributeLists(MethodAttrs, ParseGNUAttributes());
+ if (getLang().ObjC2)
+ MaybeParseGNUAttributes(attrs);
Selector Sel = PP.getSelectorTable().getNullarySelector(SelIdent);
Decl *Result
@@ -865,7 +870,7 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
mType, IDecl, DSRet, ReturnType, Sel,
0,
CParamInfo.data(), CParamInfo.size(),
- MethodAttrs, MethodImplKind);
+ attrs.getList(), MethodImplKind);
PD.complete(Result);
return Result;
}
@@ -889,8 +894,11 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
// If attributes exist before the argument name, parse them.
ArgInfo.ArgAttrs = 0;
- if (getLang().ObjC2 && Tok.is(tok::kw___attribute))
- ArgInfo.ArgAttrs = ParseGNUAttributes();
+ if (getLang().ObjC2) {
+ ParsedAttributes attrs;
+ MaybeParseGNUAttributes(attrs);
+ ArgInfo.ArgAttrs = attrs.getList();
+ }
// Code completion for the next piece of the selector.
if (Tok.is(tok::code_completion)) {
@@ -964,8 +972,8 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
// FIXME: Add support for optional parameter list...
// If attributes exist after the method, parse them.
- if (getLang().ObjC2 && Tok.is(tok::kw___attribute))
- MethodAttrs = addAttributeLists(MethodAttrs, ParseGNUAttributes());
+ if (getLang().ObjC2)
+ MaybeParseGNUAttributes(attrs);
if (KeyIdents.size() == 0)
return 0;
@@ -976,7 +984,7 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
mType, IDecl, DSRet, ReturnType, Sel,
&ArgInfos[0],
CParamInfo.data(), CParamInfo.size(),
- MethodAttrs,
+ attrs.getList(),
MethodImplKind, isVariadic);
PD.complete(Result);
return Result;
@@ -1184,7 +1192,7 @@ void Parser::ParseObjCClassInstanceVariables(Decl *interfaceDecl,
/// identifier-list ;": objc-interface-decl-list may not start with a
/// semicolon in the first alternative if objc-protocol-refs are omitted.
Decl *Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc,
- AttributeList *attrList) {
+ ParsedAttributes &attrs) {
assert(Tok.isObjCAtKeyword(tok::objc_protocol) &&
"ParseObjCAtProtocolDeclaration(): Expected @protocol");
ConsumeToken(); // the "protocol" identifier
@@ -1206,7 +1214,7 @@ Decl *Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc,
IdentifierLocPair ProtoInfo(protocolName, nameLoc);
ConsumeToken();
return Actions.ActOnForwardProtocolDeclaration(AtLoc, &ProtoInfo, 1,
- attrList);
+ attrs.getList());
}
if (Tok.is(tok::comma)) { // list of forward declarations.
@@ -1235,7 +1243,7 @@ Decl *Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc,
return Actions.ActOnForwardProtocolDeclaration(AtLoc,
&ProtocolRefs[0],
ProtocolRefs.size(),
- attrList);
+ attrs.getList());
}
// Last, and definitely not least, parse a protocol declaration.
@@ -1253,7 +1261,7 @@ Decl *Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc,
ProtocolRefs.data(),
ProtocolRefs.size(),
ProtocolLocs.data(),
- EndProtoLoc, attrList);
+ EndProtoLoc, attrs.getList());
ParseObjCInterfaceDeclList(ProtoType, tok::objc_protocol);
return ProtoType;
}
diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp
index 437a950cd94..dafe3737783 100644
--- a/clang/lib/Parse/ParseStmt.cpp
+++ b/clang/lib/Parse/ParseStmt.cpp
@@ -81,10 +81,8 @@ Parser::ParseStatementOrDeclaration(StmtVector &Stmts, bool OnlyStatement) {
ParenBraceBracketBalancer BalancerRAIIObj(*this);
- CXX0XAttributeList Attr;
- if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier())
- Attr = ParseCXX0XAttributes();
- AttributeList *AttrList = Attr.AttrList;
+ ParsedAttributesWithRange attrs;
+ MaybeParseCXX0XAttributes(attrs);
// Cases in this switch statement should fall through if the parser expects
// the token to end in a semicolon (in which case SemiError should be set),
@@ -106,7 +104,7 @@ Parser::ParseStatementOrDeclaration(StmtVector &Stmts, bool OnlyStatement) {
case tok::identifier:
if (NextToken().is(tok::colon)) { // C99 6.8.1: labeled-statement
// identifier ':' statement
- return ParseLabeledStatement(AttrList);
+ return ParseLabeledStatement(attrs);
}
// PASS THROUGH.
@@ -114,7 +112,7 @@ Parser::ParseStatementOrDeclaration(StmtVector &Stmts, bool OnlyStatement) {
if ((getLang().CPlusPlus || !OnlyStatement) && isDeclarationStatement()) {
SourceLocation DeclStart = Tok.getLocation(), DeclEnd;
DeclGroupPtrTy Decl = ParseDeclaration(Stmts, Declarator::BlockContext,
- DeclEnd, Attr);
+ DeclEnd, attrs);
return Actions.ActOnDeclStmt(Decl, DeclStart, DeclEnd);
}
@@ -141,52 +139,50 @@ Parser::ParseStatementOrDeclaration(StmtVector &Stmts, bool OnlyStatement) {
}
case tok::kw_case: // C99 6.8.1: labeled-statement
- return ParseCaseStatement(AttrList);
+ return ParseCaseStatement(attrs);
case tok::kw_default: // C99 6.8.1: labeled-statement
- return ParseDefaultStatement(AttrList);
+ return ParseDefaultStatement(attrs);
case tok::l_brace: // C99 6.8.2: compound-statement
- return ParseCompoundStatement(AttrList);
+ return ParseCompoundStatement(attrs);
case tok::semi: { // C99 6.8.3p3: expression[opt] ';'
bool LeadingEmptyMacro = Tok.hasLeadingEmptyMacro();
return Actions.ActOnNullStmt(ConsumeToken(), LeadingEmptyMacro);
}
case tok::kw_if: // C99 6.8.4.1: if-statement
- return ParseIfStatement(AttrList);
+ return ParseIfStatement(attrs);
case tok::kw_switch: // C99 6.8.4.2: switch-statement
- return ParseSwitchStatement(AttrList);
+ return ParseSwitchStatement(attrs);
case tok::kw_while: // C99 6.8.5.1: while-statement
- return ParseWhileStatement(AttrList);
+ return ParseWhileStatement(attrs);
case tok::kw_do: // C99 6.8.5.2: do-statement
- Res = ParseDoStatement(AttrList);
+ Res = ParseDoStatement(attrs);
SemiError = "do/while";
break;
case tok::kw_for: // C99 6.8.5.3: for-statement
- return ParseForStatement(AttrList);
+ return ParseForStatement(attrs);
case tok::kw_goto: // C99 6.8.6.1: goto-statement
- Res = ParseGotoStatement(AttrList);
+ Res = ParseGotoStatement(attrs);
SemiError = "goto";
break;
case tok::kw_continue: // C99 6.8.6.2: continue-statement
- Res = ParseContinueStatement(AttrList);
+ Res = ParseContinueStatement(attrs);
SemiError = "continue";
break;
case tok::kw_break: // C99 6.8.6.3: break-statement
- Res = ParseBreakStatement(AttrList);
+ Res = ParseBreakStatement(attrs);
SemiError = "break";
break;
case tok::kw_return: // C99 6.8.6.4: return-statement
- Res = ParseReturnStatement(AttrList);
+ Res = ParseReturnStatement(attrs);
SemiError = "return";
break;
case tok::kw_asm: {
- if (Attr.HasAttr)
- Diag(Attr.Range.getBegin(), diag::err_attributes_not_allowed)
- << Attr.Range;
+ ProhibitAttributes(attrs);
bool msAsm = false;
Res = ParseAsmStatement(msAsm);
Res = Actions.ActOnFinishFullStmt(Res.get());
@@ -196,7 +192,7 @@ Parser::ParseStatementOrDeclaration(StmtVector &Stmts, bool OnlyStatement) {
}
case tok::kw_try: // C++ 15: try-block
- return ParseCXXTryBlock(AttrList);
+ return ParseCXXTryBlock(attrs);
}
// If we reached this code, the statement must end in a semicolon.
@@ -220,7 +216,7 @@ Parser::ParseStatementOrDeclaration(StmtVector &Stmts, bool OnlyStatement) {
/// identifier ':' statement
/// [GNU] identifier ':' attributes[opt] statement
///
-StmtResult Parser::ParseLabeledStatement(AttributeList *Attr) {
+StmtResult Parser::ParseLabeledStatement(ParsedAttributes &attrs) {
assert(Tok.is(tok::identifier) && Tok.getIdentifierInfo() &&
"Not an identifier!");
@@ -233,8 +229,7 @@ StmtResult Parser::ParseLabeledStatement(AttributeList *Attr) {
SourceLocation ColonLoc = ConsumeToken();
// Read label attributes, if present.
- if (Tok.is(tok::kw___attribute))
- Attr = addAttributeLists(Attr, ParseGNUAttributes());
+ MaybeParseGNUAttributes(attrs);
StmtResult SubStmt(ParseStatement());
@@ -244,7 +239,7 @@ StmtResult Parser::ParseLabeledStatement(AttributeList *Attr) {
return Actions.ActOnLabelStmt(IdentTok.getLocation(),
IdentTok.getIdentifierInfo(),
- ColonLoc, SubStmt.get(), Attr);
+ ColonLoc, SubStmt.get(), attrs.getList());
}
/// ParseCaseStatement
@@ -252,7 +247,7 @@ StmtResult Parser::ParseLabeledStatement(AttributeList *Attr) {
/// 'case' constant-expression ':' statement
/// [GNU] 'case' constant-expression '...' constant-expression ':' statement
///
-StmtResult Parser::ParseCaseStatement(AttributeList *Attr) {
+StmtResult Parser::ParseCaseStatement(ParsedAttributes &attrs) {
assert(Tok.is(tok::kw_case) && "Not a case stmt!");
// FIXME: Use attributes?
@@ -380,7 +375,7 @@ StmtResult Parser::ParseCaseStatement(AttributeList *Attr) {
/// 'default' ':' statement
/// Note that this does not parse the 'statement' at the end.
///
-StmtResult Parser::ParseDefaultStatement(AttributeList *Attr) {
+StmtResult Parser::ParseDefaultStatement(ParsedAttributes &attrs) {
//FIXME: Use attributes?
assert(Tok.is(tok::kw_default) && "Not a default stmt!");
@@ -438,7 +433,7 @@ StmtResult Parser::ParseDefaultStatement(AttributeList *Attr) {
/// [OMP] barrier-directive
/// [OMP] flush-directive
///
-StmtResult Parser::ParseCompoundStatement(AttributeList *Attr,
+StmtResult Parser::ParseCompoundStatement(ParsedAttributes &attrs,
bool isStmtExpr) {
//FIXME: Use attributes?
@@ -482,9 +477,8 @@ StmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) {
while (Tok.is(tok::kw___extension__))
ConsumeToken();
- CXX0XAttributeList Attr;
- if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier())
- Attr = ParseCXX0XAttributes();
+ ParsedAttributesWithRange attrs;
+ MaybeParseCXX0XAttributes(attrs);
// If this is the start of a declaration, parse it as such.
if (isDeclarationStatement()) {
@@ -495,7 +489,7 @@ StmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) {
SourceLocation DeclStart = Tok.getLocation(), DeclEnd;
DeclGroupPtrTy Res = ParseDeclaration(Stmts,
Declarator::BlockContext, DeclEnd,
- Attr);
+ attrs);
R = Actions.ActOnDeclStmt(Res, DeclStart, DeclEnd);
} else {
// Otherwise this was a unary __extension__ marker.
@@ -585,7 +579,7 @@ bool Parser::ParseParenExprOrCondition(ExprResult &ExprResult,
/// [C++] 'if' '(' condition ')' statement
/// [C++] 'if' '(' condition ')' statement 'else' statement
///
-StmtResult Parser::ParseIfStatement(AttributeList *Attr) {
+StmtResult Parser::ParseIfStatement(ParsedAttributes &attrs) {
// FIXME: Use attributes?
assert(Tok.is(tok::kw_if) && "Not an if stmt!");
@@ -707,7 +701,7 @@ StmtResult Parser::ParseIfStatement(AttributeList *Attr) {
/// switch-statement:
/// 'switch' '(' expression ')' statement
/// [C++] 'switch' '(' condition ')' statement
-StmtResult Parser::ParseSwitchStatement(AttributeList *Attr) {
+StmtResult Parser::ParseSwitchStatement(ParsedAttributes &attrs) {
// FIXME: Use attributes?
assert(Tok.is(tok::kw_switch) && "Not a switch stmt!");
@@ -792,7 +786,7 @@ StmtResult Parser::ParseSwitchStatement(AttributeList *Attr) {
/// while-statement: [C99 6.8.5.1]
/// 'while' '(' expression ')' statement
/// [C++] 'while' '(' condition ')' statement
-StmtResult Parser::ParseWhileStatement(AttributeList *Attr) {
+StmtResult Parser::ParseWhileStatement(ParsedAttributes &attrs) {
// FIXME: Use attributes?
assert(Tok.is(tok::kw_while) && "Not a while stmt!");
@@ -866,7 +860,7 @@ StmtResult Parser::ParseWhileStatement(AttributeList *Attr) {
/// do-statement: [C99 6.8.5.2]
/// 'do' statement 'while' '(' expression ')' ';'
/// Note: this lets the caller parse the end ';'.
-StmtResult Parser::ParseDoStatement(AttributeList *Attr) {
+StmtResult Parser::ParseDoStatement(ParsedAttributes &attrs) {
// FIXME: Use attributes?
assert(Tok.is(tok::kw_do) && "Not a do stmt!");
@@ -942,7 +936,7 @@ StmtResult Parser::ParseDoStatement(AttributeList *Attr) {
/// [C++] expression-statement
/// [C++] simple-declaration
///
-StmtResult Parser::ParseForStatement(AttributeList *Attr) {
+StmtResult Parser::ParseForStatement(ParsedAttributes &attrs) {
// FIXME: Use attributes?
assert(Tok.is(tok::kw_for) && "Not a for stmt!");
@@ -1007,14 +1001,13 @@ StmtResult Parser::ParseForStatement(AttributeList *Attr) {
if (!C99orCXXorObjC) // Use of C99-style for loops in C90 mode?
Diag(Tok, diag::ext_c99_variable_decl_in_for_loop);
- AttributeList *AttrList = 0;
- if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier())
- AttrList = ParseCXX0XAttributes().AttrList;
+ ParsedAttributesWithRange attrs;
+ MaybeParseCXX0XAttributes(attrs);
SourceLocation DeclStart = Tok.getLocation(), DeclEnd;
StmtVector Stmts(Actions);
DeclGroupPtrTy DG = ParseSimpleDeclaration(Stmts, Declarator::ForContext,
- DeclEnd, AttrList, false);
+ DeclEnd, attrs, false);
FirstPart = Actions.ActOnDeclStmt(DG, DeclStart, Tok.getLocation());
if (Tok.is(tok::semi)) { // for (int x = 4;
@@ -1141,7 +1134,7 @@ StmtResult Parser::ParseForStatement(AttributeList *Attr) {
///
/// Note: this lets the caller parse the end ';'.
///
-StmtResult Parser::ParseGotoStatement(AttributeList *Attr) {
+StmtResult Parser::ParseGotoStatement(ParsedAttributes &attrs) {
// FIXME: Use attributes?
assert(Tok.is(tok::kw_goto) && "Not a goto stmt!");
@@ -1176,7 +1169,7 @@ StmtResult Parser::ParseGotoStatement(AttributeList *Attr) {
///
/// Note: this lets the caller parse the end ';'.
///
-StmtResult Parser::ParseContinueStatement(AttributeList *Attr) {
+StmtResult Parser::ParseContinueStatement(ParsedAttributes &attrs) {
// FIXME: Use attributes?
SourceLocation ContinueLoc = ConsumeToken(); // eat the 'continue'.
@@ -1189,7 +1182,7 @@ StmtResult Parser::ParseContinueStatement(AttributeList *Attr) {
///
/// Note: this lets the caller parse the end ';'.
///
-StmtResult Parser::ParseBreakStatement(AttributeList *Attr) {
+StmtResult Parser::ParseBreakStatement(ParsedAttributes &attrs) {
// FIXME: Use attributes?
SourceLocation BreakLoc = ConsumeToken(); // eat the 'break'.
@@ -1199,7 +1192,7 @@ StmtResult Parser::ParseBreakStatement(AttributeList *Attr) {
/// ParseReturnStatement
/// jump-statement:
/// 'return' expression[opt] ';'
-StmtResult Parser::ParseReturnStatement(AttributeList *Attr) {
+StmtResult Parser::ParseReturnStatement(ParsedAttributes &attrs) {
// FIXME: Use attributes?
assert(Tok.is(tok::kw_return) && "Not a return stmt!");
@@ -1521,7 +1514,7 @@ Decl *Parser::ParseFunctionTryBlock(Decl *Decl) {
/// try-block:
/// 'try' compound-statement handler-seq
///
-StmtResult Parser::ParseCXXTryBlock(AttributeList* Attr) {
+StmtResult Parser::ParseCXXTryBlock(ParsedAttributes &attrs) {
// FIXME: Add attributes?
assert(Tok.is(tok::kw_try) && "Expected 'try'");
@@ -1546,16 +1539,15 @@ StmtResult Parser::ParseCXXTryBlockCommon(SourceLocation TryLoc) {
if (Tok.isNot(tok::l_brace))
return StmtError(Diag(Tok, diag::err_expected_lbrace));
// FIXME: Possible draft standard bug: attribute-specifier should be allowed?
- StmtResult TryBlock(ParseCompoundStatement(0));
+ ParsedAttributesWithRange attrs;
+ StmtResult TryBlock(ParseCompoundStatement(attrs));
if (TryBlock.isInvalid())
return move(TryBlock);
StmtVector Handlers(Actions);
- if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier()) {
- CXX0XAttributeList Attr = ParseCXX0XAttributes();
- Diag(Attr.Range.getBegin(), diag::err_attributes_not_allowed)
- << Attr.Range;
- }
+ MaybeParseCXX0XAttributes(attrs);
+ ProhibitAttributes(attrs);
+
if (Tok.isNot(tok::kw_catch))
return StmtError(Diag(Tok, diag::err_expected_catch));
while (Tok.is(tok::kw_catch)) {
@@ -1616,7 +1608,8 @@ StmtResult Parser::ParseCXXCatchBlock() {
return StmtError(Diag(Tok, diag::err_expected_lbrace));
// FIXME: Possible draft standard bug: attribute-specifier should be allowed?
- StmtResult Block(ParseCompoundStatement(0));
+ ParsedAttributes attrs;
+ StmtResult Block(ParseCompoundStatement(attrs));
if (Block.isInvalid())
return move(Block);
diff --git a/clang/lib/Parse/ParseTemplate.cpp b/clang/lib/Parse/ParseTemplate.cpp
index d38d0599ac2..afa2cc62f9f 100644
--- a/clang/lib/Parse/ParseTemplate.cpp
+++ b/clang/lib/Parse/ParseTemplate.cpp
@@ -196,20 +196,18 @@ Parser::ParseSingleDeclarationAfterTemplate(
return 0;
}
- CXX0XAttributeList PrefixAttrs;
- if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier())
- PrefixAttrs = ParseCXX0XAttributes();
+ ParsedAttributesWithRange prefixAttrs;
+ MaybeParseCXX0XAttributes(prefixAttrs);
if (Tok.is(tok::kw_using))
return ParseUsingDirectiveOrDeclaration(Context, TemplateInfo, DeclEnd,
- PrefixAttrs);
+ prefixAttrs);
// Parse the declaration specifiers, stealing the accumulated
// diagnostics from the template parameters.
ParsingDeclSpec DS(DiagsFromTParams);
- if (PrefixAttrs.HasAttr)
- DS.AddAttributes(PrefixAttrs.AttrList);
+ DS.takeAttributesFrom(prefixAttrs);
ParseDeclarationSpecifiers(DS, TemplateInfo, AS,
getDeclSpecContextFromDeclaratorContext(Context));
diff --git a/clang/lib/Parse/ParseTentative.cpp b/clang/lib/Parse/ParseTentative.cpp
index fc57b4086b0..c6e6784f6c2 100644
--- a/clang/lib/Parse/ParseTentative.cpp
+++ b/clang/lib/Parse/ParseTentative.cpp
@@ -1151,8 +1151,8 @@ Parser::TPResult Parser::TryParseParameterDeclarationClause() {
return TPResult::True(); // '...' is a sign of a function declarator.
}
- if (getLang().Microsoft && Tok.is(tok::l_square))
- ParseMicrosoftAttributes();
+ ParsedAttributes attrs;
+ MaybeParseMicrosoftAttributes(attrs);
// decl-specifier-seq
TPResult TPR = TryParseDeclarationSpecifier();
diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp
index f79a2f68c72..2a569b58d8c 100644
--- a/clang/lib/Parse/Parser.cpp
+++ b/clang/lib/Parse/Parser.cpp
@@ -402,13 +402,11 @@ bool Parser::ParseTopLevelDecl(DeclGroupPtrTy &Result) {
return true;
}
- CXX0XAttributeList Attr;
- if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier())
- Attr = ParseCXX0XAttributes();
- if (getLang().Microsoft && Tok.is(tok::l_square))
- ParseMicrosoftAttributes();
+ ParsedAttributesWithRange attrs;
+ MaybeParseCXX0XAttributes(attrs);
+ MaybeParseMicrosoftAttributes(attrs);
- Result = ParseExternalDeclaration(Attr);
+ Result = ParseExternalDeclaration(attrs);
return false;
}
@@ -449,8 +447,9 @@ void Parser::ParseTranslationUnit() {
/// ';'
///
/// [C++0x/GNU] 'extern' 'template' declaration
-Parser::DeclGroupPtrTy Parser::ParseExternalDeclaration(CXX0XAttributeList Attr,
- ParsingDeclSpec *DS) {
+Parser::DeclGroupPtrTy
+Parser::ParseExternalDeclaration(ParsedAttributesWithRange &attrs,
+ ParsingDeclSpec *DS) {
ParenBraceBracketBalancer BalancerRAIIObj(*this);
Decl *SingleDecl = 0;
@@ -474,12 +473,10 @@ Parser::DeclGroupPtrTy Parser::ParseExternalDeclaration(CXX0XAttributeList Attr,
// __extension__ silences extension warnings in the subexpression.
ExtensionRAIIObject O(Diags); // Use RAII to do this.
ConsumeToken();
- return ParseExternalDeclaration(Attr);
+ return ParseExternalDeclaration(attrs);
}
case tok::kw_asm: {
- if (Attr.HasAttr)
- Diag(Attr.Range.getBegin(), diag::err_attributes_not_allowed)
- << Attr.Range;
+ ProhibitAttributes(attrs);
ExprResult Result(ParseSimpleAsm());
@@ -511,7 +508,7 @@ Parser::DeclGroupPtrTy Parser::ParseExternalDeclaration(CXX0XAttributeList Attr,
ObjCImpDecl? Sema::PCC_ObjCImplementation
: Sema::PCC_Namespace);
ConsumeCodeCompletionToken();
- return ParseExternalDeclaration(Attr);
+ return ParseExternalDeclaration(attrs);
case tok::kw_using:
case tok::kw_namespace:
case tok::kw_typedef:
@@ -522,7 +519,7 @@ Parser::DeclGroupPtrTy Parser::ParseExternalDeclaration(CXX0XAttributeList Attr,
{
SourceLocation DeclEnd;
StmtVector Stmts(Actions);
- return ParseDeclaration(Stmts, Declarator::FileContext, DeclEnd, Attr);
+ return ParseDeclaration(Stmts, Declarator::FileContext, DeclEnd, attrs);
}
case tok::kw_static:
@@ -533,7 +530,7 @@ Parser::DeclGroupPtrTy Parser::ParseExternalDeclaration(CXX0XAttributeList Attr,
<< 0;
SourceLocation DeclEnd;
StmtVector Stmts(Actions);
- return ParseDeclaration(Stmts, Declarator::FileContext, DeclEnd, Attr);
+ return ParseDeclaration(Stmts, Declarator::FileContext, DeclEnd, attrs);
}
goto dont_know;
@@ -545,7 +542,7 @@ Parser::DeclGroupPtrTy Parser::ParseExternalDeclaration(CXX0XAttributeList Attr,
if (NextKind == tok::kw_namespace) {
SourceLocation DeclEnd;
StmtVector Stmts(Actions);
- return ParseDeclaration(Stmts, Declarator::FileContext, DeclEnd, Attr);
+ return ParseDeclaration(Stmts, Declarator::FileContext, DeclEnd, attrs);
}
// Parse (then ignore) 'inline' prior to a template instantiation. This is
@@ -555,7 +552,7 @@ Parser::DeclGroupPtrTy Parser::ParseExternalDeclaration(CXX0XAttributeList Attr,
<< 1;
SourceLocation DeclEnd;
StmtVector Stmts(Actions);
- return ParseDeclaration(Stmts, Declarator::FileContext, DeclEnd, Attr);
+ return ParseDeclaration(Stmts, Declarator::FileContext, DeclEnd, attrs);
}
}
goto dont_know;
@@ -575,10 +572,12 @@ Parser::DeclGroupPtrTy Parser::ParseExternalDeclaration(CXX0XAttributeList Attr,
default:
dont_know:
// We can't tell whether this is a function-definition or declaration yet.
- if (DS)
- return ParseDeclarationOrFunctionDefinition(*DS, Attr.AttrList);
- else
- return ParseDeclarationOrFunctionDefinition(Attr.AttrList);
+ if (DS) {
+ DS->takeAttributesFrom(attrs);
+ return ParseDeclarationOrFunctionDefinition(*DS);
+ } else {
+ return ParseDeclarationOrFunctionDefinition(attrs);
+ }
}
// This routine returns a DeclGroup, if the thing we parsed only contains a
@@ -632,12 +631,8 @@ bool Parser::isStartOfFunctionDefinition(const ParsingDeclarator &Declarator) {
///
Parser::DeclGroupPtrTy
Parser::ParseDeclarationOrFunctionDefinition(ParsingDeclSpec &DS,
- AttributeList *Attr,
AccessSpecifier AS) {
// Parse the common declaration-specifiers piece.
- if (Attr)
- DS.AddAttributes(Attr);
-
ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS, DSC_top_level);
// C99 6.7.2.3p6: Handle "struct-or-union identifier;", "enum { X };"
@@ -690,10 +685,11 @@ Parser::ParseDeclarationOrFunctionDefinition(ParsingDeclSpec &DS,
}
Parser::DeclGroupPtrTy
-Parser::ParseDeclarationOrFunctionDefinition(AttributeList *Attr,
+Parser::ParseDeclarationOrFunctionDefinition(ParsedAttributes &attrs,
AccessSpecifier AS) {
ParsingDeclSpec DS(*this);
- return ParseDeclarationOrFunctionDefinition(DS, Attr, AS);
+ DS.takeAttributesFrom(attrs);
+ return ParseDeclarationOrFunctionDefinition(DS, AS);
}
/// ParseFunctionDefinition - We parsed and verified that the specified
@@ -835,11 +831,7 @@ void Parser::ParseKNRParamDeclarations(Declarator &D) {
// Handle the full declarator list.
while (1) {
// If attributes are present, parse them.
- if (Tok.is(tok::kw___attribute)) {
- SourceLocation Loc;
- AttributeList *AttrList = ParseGNUAttributes(&Loc);
- ParmDeclarator.AddAttributes(AttrList, Loc);
- }
+ MaybeParseGNUAttributes(ParmDeclarator);
// Ask the actions module to compute the type for this declarator.
Decl *Param =
OpenPOWER on IntegriCloud