summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/ASTContext.cpp4
-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
-rw-r--r--clang/lib/Sema/AttributeList.cpp4
-rw-r--r--clang/lib/Sema/DeclSpec.cpp6
-rw-r--r--clang/lib/Sema/SemaDecl.cpp5
-rw-r--r--clang/lib/Sema/SemaDeclAttr.cpp2
-rw-r--r--clang/lib/Sema/SemaType.cpp2
15 files changed, 321 insertions, 411 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index eaf222cafad..b145683ce5e 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -1119,8 +1119,8 @@ QualType ASTContext::getObjCGCQualType(QualType T,
if (CanT.getObjCGCAttr() == GCAttr)
return T;
- if (T->isPointerType()) {
- QualType Pointee = T->getAs<PointerType>()->getPointeeType();
+ if (const PointerType *ptr = T->getAs<PointerType>()) {
+ QualType Pointee = ptr->getPointeeType();
if (Pointee->isAnyPointerType()) {
QualType ResultType = getObjCGCQualType(Pointee, GCAttr);
return getPointerType(ResultType);
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 =
diff --git a/clang/lib/Sema/AttributeList.cpp b/clang/lib/Sema/AttributeList.cpp
index 6aa9690476a..6e0a3321048 100644
--- a/clang/lib/Sema/AttributeList.cpp
+++ b/clang/lib/Sema/AttributeList.cpp
@@ -21,10 +21,10 @@ AttributeList::AttributeList(llvm::BumpPtrAllocator &Alloc,
IdentifierInfo *sName, SourceLocation sLoc,
IdentifierInfo *pName, SourceLocation pLoc,
Expr **ExprList, unsigned numArgs,
- AttributeList *n, bool declspec, bool cxx0x)
+ bool declspec, bool cxx0x)
: AttrName(aName), AttrLoc(aLoc), ScopeName(sName),
ScopeLoc(sLoc),
- ParmName(pName), ParmLoc(pLoc), NumArgs(numArgs), Next(n),
+ ParmName(pName), ParmLoc(pLoc), NumArgs(numArgs), Next(0),
DeclspecAttribute(declspec), CXX0XAttribute(cxx0x), Invalid(false) {
if (numArgs == 0)
diff --git a/clang/lib/Sema/DeclSpec.cpp b/clang/lib/Sema/DeclSpec.cpp
index 5304193b664..4afdc24275f 100644
--- a/clang/lib/Sema/DeclSpec.cpp
+++ b/clang/lib/Sema/DeclSpec.cpp
@@ -46,7 +46,8 @@ void UnqualifiedId::setConstructorTemplateId(TemplateIdAnnotation *TemplateId) {
/// DeclaratorChunk::getFunction - Return a DeclaratorChunk for a function.
/// "TheDeclarator" is the declarator that this will be added to.
-DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto, bool isVariadic,
+DeclaratorChunk DeclaratorChunk::getFunction(const ParsedAttributes &attrs,
+ bool hasProto, bool isVariadic,
SourceLocation EllipsisLoc,
ParamInfo *ArgInfo,
unsigned NumArgs,
@@ -65,6 +66,7 @@ DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto, bool isVariadic,
I.Kind = Function;
I.Loc = LPLoc;
I.EndLoc = RPLoc;
+ I.Fun.AttrList = attrs.getList();
I.Fun.hasPrototype = hasProto;
I.Fun.isVariadic = isVariadic;
I.Fun.EllipsisLoc = EllipsisLoc.getRawEncoding();
@@ -483,7 +485,7 @@ void DeclSpec::SaveWrittenBuiltinSpecs() {
writtenBS.Type = getTypeSpecType();
// Search the list of attributes for the presence of a mode attribute.
writtenBS.ModeAttr = false;
- AttributeList* attrs = getAttributes();
+ AttributeList* attrs = getAttributes().getList();
while (attrs) {
if (attrs->getKind() == AttributeList::AT_mode) {
writtenBS.ModeAttr = true;
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index d5966494790..62262bc60b5 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -1642,7 +1642,7 @@ Decl *Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS,
}
if (RecordDecl *Record = dyn_cast_or_null<RecordDecl>(Tag)) {
- ProcessDeclAttributeList(S, Record, DS.getAttributes());
+ ProcessDeclAttributeList(S, Record, DS.getAttributes().getList());
if (!Record->getDeclName() && Record->isDefinition() &&
DS.getStorageClassSpec() != DeclSpec::SCS_typedef) {
@@ -5553,7 +5553,8 @@ NamedDecl *Sema::ImplicitlyDefineFunction(SourceLocation Loc,
(void)Error; // Silence warning.
assert(!Error && "Error setting up implicit decl!");
Declarator D(DS, Declarator::BlockContext);
- D.AddTypeInfo(DeclaratorChunk::getFunction(false, false, SourceLocation(), 0,
+ D.AddTypeInfo(DeclaratorChunk::getFunction(ParsedAttributes(),
+ false, false, SourceLocation(), 0,
0, 0, false, SourceLocation(),
false, 0,0,0, Loc, Loc, D),
SourceLocation());
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 06cb42ec0e0..6977a33ac4a 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -2808,7 +2808,7 @@ void Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD) {
}
// Apply decl attributes from the DeclSpec if present.
- if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes())
+ if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes().getList())
ProcessDeclAttributeList(S, D, Attrs);
// Walk the declarator structure, applying decl attributes that were in a type
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 46ec0fe1091..c70d5befbbf 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -402,7 +402,7 @@ static QualType ConvertDeclSpecToType(Sema &TheSema,
// See if there are any attributes on the declspec that apply to the type (as
// opposed to the decl).
- if (const AttributeList *AL = DS.getAttributes())
+ if (const AttributeList *AL = DS.getAttributes().getList())
ProcessTypeAttributeList(TheSema, Result, true, AL, Delayed);
// Apply const/volatile/restrict qualifiers to T.
OpenPOWER on IntegriCloud