Commit 45b1169d authored by Erik Verbruggen's avatar Erik Verbruggen Committed by Nikolai Kosjar
Browse files

C++: Support alignas in C++11 mode.



Change-Id: Ifa81a481bf92b5b71495a105ae292f3e9895f704
Task-number: QTCREATORBUG-9279
Reviewed-by: default avatarNikolai Kosjar <nikolai.kosjar@digia.com>
parent d2db54b4
......@@ -68,7 +68,7 @@ bool AST::match(AST *pattern, ASTMatcher *matcher)
return match0(pattern, matcher);
}
unsigned AttributeSpecifierAST::firstToken() const
unsigned GnuAttributeSpecifierAST::firstToken() const
{
return attribute_token;
}
......@@ -242,7 +242,7 @@ unsigned AsmDefinitionAST::lastToken() const
}
/** \generated */
unsigned AttributeAST::firstToken() const
unsigned GnuAttributeAST::firstToken() const
{
if (identifier_token)
return identifier_token;
......@@ -259,7 +259,7 @@ unsigned AttributeAST::firstToken() const
}
/** \generated */
unsigned AttributeAST::lastToken() const
unsigned GnuAttributeAST::lastToken() const
{
if (rparen_token)
return rparen_token + 1;
......@@ -4194,7 +4194,7 @@ unsigned WhileStatementAST::lastToken() const
}
/** \generated */
unsigned AttributeSpecifierAST::lastToken() const
unsigned GnuAttributeSpecifierAST::lastToken() const
{
if (second_rparen_token)
return second_rparen_token + 1;
......@@ -4524,3 +4524,37 @@ unsigned DotDesignatorAST::lastToken() const
return 1;
}
/** \generated */
unsigned AlignmentSpecifierAST::firstToken() const
{
if (align_token)
return align_token;
if (lparen_token)
return lparen_token;
if (typeIdExprOrAlignmentExpr)
if (unsigned candidate = typeIdExprOrAlignmentExpr->firstToken())
return candidate;
if (ellipses_token)
return ellipses_token;
if (rparen_token)
return rparen_token;
return 0;
}
/** \generated */
unsigned AlignmentSpecifierAST::lastToken() const
{
if (rparen_token)
return rparen_token + 1;
if (ellipses_token)
return ellipses_token + 1;
if (typeIdExprOrAlignmentExpr)
if (unsigned candidate = typeIdExprOrAlignmentExpr->lastToken())
return candidate;
if (lparen_token)
return lparen_token + 1;
if (align_token)
return align_token + 1;
return 1;
}
......@@ -126,13 +126,13 @@ public:
virtual AccessDeclarationAST *asAccessDeclaration() { return 0; }
virtual AliasDeclarationAST *asAliasDeclaration() { return 0; }
virtual AlignmentSpecifierAST *asAlignmentSpecifier() { return 0; }
virtual AlignofExpressionAST *asAlignofExpression() { return 0; }
virtual AnonymousNameAST *asAnonymousName() { return 0; }
virtual ArrayAccessAST *asArrayAccess() { return 0; }
virtual ArrayDeclaratorAST *asArrayDeclarator() { return 0; }
virtual ArrayInitializerAST *asArrayInitializer() { return 0; }
virtual AsmDefinitionAST *asAsmDefinition() { return 0; }
virtual AttributeAST *asAttribute() { return 0; }
virtual AttributeSpecifierAST *asAttributeSpecifier() { return 0; }
virtual BaseSpecifierAST *asBaseSpecifier() { return 0; }
virtual BinaryExpressionAST *asBinaryExpression() { return 0; }
......@@ -182,6 +182,8 @@ public:
virtual ForeachStatementAST *asForeachStatement() { return 0; }
virtual FunctionDeclaratorAST *asFunctionDeclarator() { return 0; }
virtual FunctionDefinitionAST *asFunctionDefinition() { return 0; }
virtual GnuAttributeAST *asGnuAttribute() { return 0; }
virtual GnuAttributeSpecifierAST *asGnuAttributeSpecifier() { return 0; }
virtual GotoStatementAST *asGotoStatement() { return 0; }
virtual IdExpressionAST *asIdExpression() { return 0; }
virtual IfStatementAST *asIfStatement() { return 0; }
......@@ -462,16 +464,58 @@ protected:
class CPLUSPLUS_EXPORT AttributeSpecifierAST: public SpecifierAST
{
public:
AttributeSpecifierAST()
{}
virtual AttributeSpecifierAST *asAttributeSpecifier() { return this; }
virtual AttributeSpecifierAST *clone(MemoryPool *pool) const = 0;
};
class CPLUSPLUS_EXPORT AlignmentSpecifierAST: public AttributeSpecifierAST
{
public:
unsigned align_token;
unsigned lparen_token;
ExpressionAST *typeIdExprOrAlignmentExpr;
unsigned ellipses_token;
unsigned rparen_token;
public:
AlignmentSpecifierAST()
: align_token(0)
, lparen_token(0)
, typeIdExprOrAlignmentExpr(0)
, ellipses_token(0)
, rparen_token(0)
{}
virtual AlignmentSpecifierAST *asAlignmentSpecifier() { return this; }
virtual unsigned firstToken() const;
virtual unsigned lastToken() const;
virtual AlignmentSpecifierAST *clone(MemoryPool *pool) const;
protected:
virtual void accept0(ASTVisitor *visitor);
virtual bool match0(AST *, ASTMatcher *);
};
class CPLUSPLUS_EXPORT GnuAttributeSpecifierAST: public AttributeSpecifierAST
{
public:
unsigned attribute_token;
unsigned first_lparen_token;
unsigned second_lparen_token;
AttributeListAST *attribute_list;
GnuAttributeListAST *attribute_list;
unsigned first_rparen_token;
unsigned second_rparen_token;
public:
AttributeSpecifierAST()
GnuAttributeSpecifierAST()
: attribute_token(0)
, first_lparen_token(0)
, second_lparen_token(0)
......@@ -480,19 +524,19 @@ public:
, second_rparen_token(0)
{}
virtual AttributeSpecifierAST *asAttributeSpecifier() { return this; }
virtual GnuAttributeSpecifierAST *asGnuAttributeSpecifier() { return this; }
virtual unsigned firstToken() const;
virtual unsigned lastToken() const;
virtual AttributeSpecifierAST *clone(MemoryPool *pool) const;
virtual GnuAttributeSpecifierAST *clone(MemoryPool *pool) const;
protected:
virtual void accept0(ASTVisitor *visitor);
virtual bool match0(AST *, ASTMatcher *);
};
class CPLUSPLUS_EXPORT AttributeAST: public AST
class CPLUSPLUS_EXPORT GnuAttributeAST: public AST
{
public:
unsigned identifier_token;
......@@ -502,7 +546,7 @@ public:
unsigned rparen_token;
public:
AttributeAST()
GnuAttributeAST()
: identifier_token(0)
, lparen_token(0)
, tag_token(0)
......@@ -510,12 +554,12 @@ public:
, rparen_token(0)
{}
virtual AttributeAST *asAttribute() { return this; }
virtual GnuAttributeAST *asGnuAttribute() { return this; }
virtual unsigned firstToken() const;
virtual unsigned lastToken() const;
virtual AttributeAST *clone(MemoryPool *pool) const;
virtual GnuAttributeAST *clone(MemoryPool *pool) const;
protected:
virtual void accept0(ASTVisitor *visitor);
......
......@@ -55,23 +55,35 @@ SimpleSpecifierAST *SimpleSpecifierAST::clone(MemoryPool *pool) const
return ast;
}
AttributeSpecifierAST *AttributeSpecifierAST::clone(MemoryPool *pool) const
AlignmentSpecifierAST *AlignmentSpecifierAST::clone(MemoryPool *pool) const
{
AttributeSpecifierAST *ast = new (pool) AttributeSpecifierAST;
AlignmentSpecifierAST *ast = new (pool) AlignmentSpecifierAST;
ast->align_token = align_token;
ast->lparen_token = lparen_token;
if (typeIdExprOrAlignmentExpr)
ast->typeIdExprOrAlignmentExpr = typeIdExprOrAlignmentExpr->clone(pool);
ast->ellipses_token = ellipses_token;
ast->rparen_token = rparen_token;
return ast;
}
GnuAttributeSpecifierAST *GnuAttributeSpecifierAST::clone(MemoryPool *pool) const
{
GnuAttributeSpecifierAST *ast = new (pool) GnuAttributeSpecifierAST;
ast->attribute_token = attribute_token;
ast->first_lparen_token = first_lparen_token;
ast->second_lparen_token = second_lparen_token;
for (AttributeListAST *iter = attribute_list, **ast_iter = &ast->attribute_list;
for (GnuAttributeListAST *iter = attribute_list, **ast_iter = &ast->attribute_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
*ast_iter = new (pool) AttributeListAST((iter->value) ? iter->value->clone(pool) : 0);
*ast_iter = new (pool) GnuAttributeListAST((iter->value) ? iter->value->clone(pool) : 0);
ast->first_rparen_token = first_rparen_token;
ast->second_rparen_token = second_rparen_token;
return ast;
}
AttributeAST *AttributeAST::clone(MemoryPool *pool) const
GnuAttributeAST *GnuAttributeAST::clone(MemoryPool *pool) const
{
AttributeAST *ast = new (pool) AttributeAST;
GnuAttributeAST *ast = new (pool) GnuAttributeAST;
ast->identifier_token = identifier_token;
ast->lparen_token = lparen_token;
ast->tag_token = tag_token;
......
......@@ -56,17 +56,25 @@ bool SimpleSpecifierAST::match0(AST *pattern, ASTMatcher *matcher)
return false;
}
bool AttributeSpecifierAST::match0(AST *pattern, ASTMatcher *matcher)
bool AlignmentSpecifierAST::match0(AST *pattern, ASTMatcher *matcher)
{
if (AttributeSpecifierAST *_other = pattern->asAttributeSpecifier())
if (AlignmentSpecifierAST *_other = pattern->asAlignmentSpecifier())
return matcher->match(this, _other);
return false;
}
bool AttributeAST::match0(AST *pattern, ASTMatcher *matcher)
bool GnuAttributeSpecifierAST::match0(AST *pattern, ASTMatcher *matcher)
{
if (AttributeAST *_other = pattern->asAttribute())
if (GnuAttributeSpecifierAST *_other = pattern->asGnuAttributeSpecifier())
return matcher->match(this, _other);
return false;
}
bool GnuAttributeAST::match0(AST *pattern, ASTMatcher *matcher)
{
if (GnuAttributeAST *_other = pattern->asGnuAttribute())
return matcher->match(this, _other);
return false;
......
......@@ -73,7 +73,28 @@ bool ASTMatcher::match(SimpleSpecifierAST *node, SimpleSpecifierAST *pattern)
return true;
}
bool ASTMatcher::match(AttributeSpecifierAST *node, AttributeSpecifierAST *pattern)
bool ASTMatcher::match(AlignmentSpecifierAST *node, AlignmentSpecifierAST *pattern)
{
(void) node;
(void) pattern;
pattern->align_token = node->align_token;
pattern->lparen_token = node->lparen_token;
if (! pattern->typeIdExprOrAlignmentExpr)
pattern->typeIdExprOrAlignmentExpr = node->typeIdExprOrAlignmentExpr;
else if (! AST::match(node->typeIdExprOrAlignmentExpr, pattern->typeIdExprOrAlignmentExpr, this))
return false;
pattern->ellipses_token = node->ellipses_token;
pattern->rparen_token = node->rparen_token;
return true;
}
bool ASTMatcher::match(GnuAttributeSpecifierAST *node, GnuAttributeSpecifierAST *pattern)
{
(void) node;
(void) pattern;
......@@ -96,7 +117,7 @@ bool ASTMatcher::match(AttributeSpecifierAST *node, AttributeSpecifierAST *patte
return true;
}
bool ASTMatcher::match(AttributeAST *node, AttributeAST *pattern)
bool ASTMatcher::match(GnuAttributeAST *node, GnuAttributeAST *pattern)
{
(void) node;
(void) pattern;
......
......@@ -33,14 +33,13 @@ public:
virtual bool match(AccessDeclarationAST *node, AccessDeclarationAST *pattern);
virtual bool match(AliasDeclarationAST *node, AliasDeclarationAST *pattern);
virtual bool match(AlignmentSpecifierAST *node, AlignmentSpecifierAST *pattern);
virtual bool match(AlignofExpressionAST *node, AlignofExpressionAST *pattern);
virtual bool match(AnonymousNameAST *node, AnonymousNameAST *pattern);
virtual bool match(ArrayAccessAST *node, ArrayAccessAST *pattern);
virtual bool match(ArrayDeclaratorAST *node, ArrayDeclaratorAST *pattern);
virtual bool match(ArrayInitializerAST *node, ArrayInitializerAST *pattern);
virtual bool match(AsmDefinitionAST *node, AsmDefinitionAST *pattern);
virtual bool match(AttributeAST *node, AttributeAST *pattern);
virtual bool match(AttributeSpecifierAST *node, AttributeSpecifierAST *pattern);
virtual bool match(BaseSpecifierAST *node, BaseSpecifierAST *pattern);
virtual bool match(BinaryExpressionAST *node, BinaryExpressionAST *pattern);
virtual bool match(BoolLiteralAST *node, BoolLiteralAST *pattern);
......@@ -84,6 +83,8 @@ public:
virtual bool match(ForeachStatementAST *node, ForeachStatementAST *pattern);
virtual bool match(FunctionDeclaratorAST *node, FunctionDeclaratorAST *pattern);
virtual bool match(FunctionDefinitionAST *node, FunctionDefinitionAST *pattern);
virtual bool match(GnuAttributeAST *node, GnuAttributeAST *pattern);
virtual bool match(GnuAttributeSpecifierAST *node, GnuAttributeSpecifierAST *pattern);
virtual bool match(GotoStatementAST *node, GotoStatementAST *pattern);
virtual bool match(IdExpressionAST *node, IdExpressionAST *pattern);
virtual bool match(IfStatementAST *node, IfStatementAST *pattern);
......
......@@ -63,16 +63,23 @@ public:
return __ast;
}
AttributeSpecifierAST *AttributeSpecifier(AttributeListAST *attribute_list = 0)
AlignmentSpecifierAST *AlignmentSpecifier(ExpressionAST *typeIdExprOrAlignmentExpr = 0)
{
AttributeSpecifierAST *__ast = new (&pool) AttributeSpecifierAST;
AlignmentSpecifierAST *__ast = new (&pool) AlignmentSpecifierAST;
__ast->typeIdExprOrAlignmentExpr = typeIdExprOrAlignmentExpr;
return __ast;
}
GnuAttributeSpecifierAST *GnuAttributeSpecifier(GnuAttributeListAST *attribute_list = 0)
{
GnuAttributeSpecifierAST *__ast = new (&pool) GnuAttributeSpecifierAST;
__ast->attribute_list = attribute_list;
return __ast;
}
AttributeAST *Attribute(ExpressionListAST *expression_list = 0)
GnuAttributeAST *GnuAttribute(ExpressionListAST *expression_list = 0)
{
AttributeAST *__ast = new (&pool) AttributeAST;
GnuAttributeAST *__ast = new (&pool) GnuAttributeAST;
__ast->expression_list = expression_list;
return __ast;
}
......@@ -1168,14 +1175,6 @@ public:
return __ast;
}
AttributeListAST *AttributeList(AttributeAST *value, AttributeListAST *next = 0)
{
AttributeListAST *__list = new (&pool) AttributeListAST;
__list->next = next;
__list->value = value;
return __list;
}
BaseSpecifierListAST *BaseSpecifierList(BaseSpecifierAST *value, BaseSpecifierListAST *next = 0)
{
BaseSpecifierListAST *__list = new (&pool) BaseSpecifierListAST;
......@@ -1240,6 +1239,14 @@ public:
return __list;
}
GnuAttributeListAST *GnuAttributeList(GnuAttributeAST *value, GnuAttributeListAST *next = 0)
{
GnuAttributeListAST *__list = new (&pool) GnuAttributeListAST;
__list->next = next;
__list->value = value;
return __list;
}
MemInitializerListAST *MemInitializerList(MemInitializerAST *value, MemInitializerListAST *next = 0)
{
MemInitializerListAST *__list = new (&pool) MemInitializerListAST;
......
......@@ -54,7 +54,15 @@ void SimpleSpecifierAST::accept0(ASTVisitor *visitor)
visitor->endVisit(this);
}
void AttributeSpecifierAST::accept0(ASTVisitor *visitor)
void AlignmentSpecifierAST::accept0(ASTVisitor *visitor)
{
if (visitor->visit(this)) {
accept(typeIdExprOrAlignmentExpr, visitor);
}
visitor->endVisit(this);
}
void GnuAttributeSpecifierAST::accept0(ASTVisitor *visitor)
{
if (visitor->visit(this)) {
accept(attribute_list, visitor);
......@@ -62,7 +70,7 @@ void AttributeSpecifierAST::accept0(ASTVisitor *visitor)
visitor->endVisit(this);
}
void AttributeAST::accept0(ASTVisitor *visitor)
void GnuAttributeAST::accept0(ASTVisitor *visitor)
{
if (visitor->visit(this)) {
accept(expression_list, visitor);
......
......@@ -75,14 +75,13 @@ public:
virtual bool visit(AccessDeclarationAST *) { return true; }
virtual bool visit(AliasDeclarationAST *) { return true; }
virtual bool visit(AlignmentSpecifierAST *) { return true; }
virtual bool visit(AlignofExpressionAST *) { return true; }
virtual bool visit(AnonymousNameAST *) { return true; }
virtual bool visit(ArrayAccessAST *) { return true; }
virtual bool visit(ArrayDeclaratorAST *) { return true; }
virtual bool visit(ArrayInitializerAST *) { return true; }
virtual bool visit(AsmDefinitionAST *) { return true; }
virtual bool visit(AttributeAST *) { return true; }
virtual bool visit(AttributeSpecifierAST *) { return true; }
virtual bool visit(BaseSpecifierAST *) { return true; }
virtual bool visit(BinaryExpressionAST *) { return true; }
virtual bool visit(BoolLiteralAST *) { return true; }
......@@ -126,6 +125,8 @@ public:
virtual bool visit(ForeachStatementAST *) { return true; }
virtual bool visit(FunctionDeclaratorAST *) { return true; }
virtual bool visit(FunctionDefinitionAST *) { return true; }
virtual bool visit(GnuAttributeAST *) { return true; }
virtual bool visit(GnuAttributeSpecifierAST *) { return true; }
virtual bool visit(GotoStatementAST *) { return true; }
virtual bool visit(IdExpressionAST *) { return true; }
virtual bool visit(IfStatementAST *) { return true; }
......@@ -224,14 +225,13 @@ public:
virtual void endVisit(AccessDeclarationAST *) {}
virtual void endVisit(AliasDeclarationAST *) {}
virtual void endVisit(AlignmentSpecifierAST *) {}
virtual void endVisit(AlignofExpressionAST *) {}
virtual void endVisit(AnonymousNameAST *) {}
virtual void endVisit(ArrayAccessAST *) {}
virtual void endVisit(ArrayDeclaratorAST *) {}
virtual void endVisit(ArrayInitializerAST *) {}
virtual void endVisit(AsmDefinitionAST *) {}
virtual void endVisit(AttributeAST *) {}
virtual void endVisit(AttributeSpecifierAST *) {}
virtual void endVisit(BaseSpecifierAST *) {}
virtual void endVisit(BinaryExpressionAST *) {}
virtual void endVisit(BoolLiteralAST *) {}
......@@ -275,6 +275,8 @@ public:
virtual void endVisit(ForeachStatementAST *) {}
virtual void endVisit(FunctionDeclaratorAST *) {}
virtual void endVisit(FunctionDefinitionAST *) {}
virtual void endVisit(GnuAttributeAST *) {}
virtual void endVisit(GnuAttributeSpecifierAST *) {}
virtual void endVisit(GotoStatementAST *) {}
virtual void endVisit(IdExpressionAST *) {}
virtual void endVisit(IfStatementAST *) {}
......
......@@ -33,13 +33,13 @@ class ASTMatcher;
class AccessDeclarationAST;
class AliasDeclarationAST;
class AlignmentSpecifierAST;
class AlignofExpressionAST;
class AnonymousNameAST;
class ArrayAccessAST;
class ArrayDeclaratorAST;
class ArrayInitializerAST;
class AsmDefinitionAST;
class AttributeAST;
class AttributeSpecifierAST;
class BaseSpecifierAST;
class BinaryExpressionAST;
......@@ -89,6 +89,8 @@ class ForStatementAST;
class ForeachStatementAST;
class FunctionDeclaratorAST;
class FunctionDefinitionAST;
class GnuAttributeAST;
class GnuAttributeSpecifierAST;
class GotoStatementAST;
class IdExpressionAST;
class IfStatementAST;
......@@ -201,7 +203,7 @@ typedef List<MemInitializerAST *> MemInitializerListAST;
typedef List<NewArrayDeclaratorAST *> NewArrayDeclaratorListAST;
typedef List<PostfixAST *> PostfixListAST;
typedef List<PostfixDeclaratorAST *> PostfixDeclaratorListAST;
typedef List<AttributeAST *> AttributeListAST;
typedef List<GnuAttributeAST *> GnuAttributeListAST;
typedef List<NestedNameSpecifierAST *> NestedNameSpecifierListAST;
typedef List<CatchClauseAST *> CatchClauseListAST;
typedef List<PtrOperatorAST *> PtrOperatorListAST;
......
......@@ -303,14 +303,14 @@ const Name *Bind::objCSelectorArgument(ObjCSelectorArgumentAST *ast, bool *hasAr
return identifier(ast->name_token);
}
bool Bind::visit(AttributeAST *ast)
bool Bind::visit(GnuAttributeAST *ast)
{
(void) ast;
CPP_CHECK(!"unreachable");
return false;
}
void Bind::attribute(AttributeAST *ast)
void Bind::attribute(GnuAttributeAST *ast)
{
if (! ast)
return;
......@@ -2902,12 +2902,20 @@ bool Bind::visit(SimpleSpecifierAST *ast)
return false;
}
bool Bind::visit(AttributeSpecifierAST *ast)
bool Bind::visit(AlignmentSpecifierAST *ast)
{
// Prevent visiting the type-id or alignment expression from changing the currently
// calculated type:
expression(ast->typeIdExprOrAlignmentExpr);
return false;
}
bool Bind::visit(GnuAttributeSpecifierAST *ast)
{
// unsigned attribute_token = ast->attribute_token;
// unsigned first_lparen_token = ast->first_lparen_token;
// unsigned second_lparen_token = ast->second_lparen_token;
for (AttributeListAST *it = ast->attribute_list; it; it = it->next) {
for (GnuAttributeListAST *it = ast->attribute_list; it; it = it->next) {
this->attribute(it->value);
}
// unsigned first_rparen_token = ast->first_rparen_token;
......
......@@ -77,7 +77,7 @@ protected:
unsigned calculateScopeStart(ObjCProtocolDeclarationAST *ast) const;
const Name *objCSelectorArgument(ObjCSelectorArgumentAST *ast, bool *hasArg);
void attribute(AttributeAST *ast);
void attribute(GnuAttributeAST *ast);
FullySpecifiedType declarator(DeclaratorAST *ast, const FullySpecifiedType &init, DeclaratorIdAST **declaratorId);
void qtInterfaceName(QtInterfaceNameAST *ast);
void baseSpecifier(BaseSpecifierAST *ast, unsigned colon_token, Class *klass);
......@@ -112,7 +112,7 @@ protected:
// AST
virtual bool visit(ObjCSelectorArgumentAST *ast);
virtual bool visit(AttributeAST *ast);
virtual bool visit(GnuAttributeAST *ast);
virtual bool visit(DeclaratorAST *ast);
virtual bool visit(QtPropertyDeclarationItemAST *ast);
virtual bool visit(QtInterfaceNameAST *ast);
......@@ -245,7 +245,8 @@ protected:
// SpecifierAST
virtual bool visit(SimpleSpecifierAST *ast);
virtual bool visit(AttributeSpecifierAST *ast);
virtual bool visit(AlignmentSpecifierAST *ast);
virtual bool visit(GnuAttributeSpecifierAST *ast);
virtual bool visit(TypeofSpecifierAST *ast);
virtual bool visit(DecltypeSpecifierAST *ast);
virtual bool visit(ClassSpecifierAST *ast);
......
......@@ -633,7 +633,7 @@ bool Parser::parseDeclaration(DeclarationAST *&node)
if (_languageFeatures.objCEnabled && LA() == T___ATTRIBUTE__) {
const unsigned start = cursor();
SpecifierListAST *attributes = 0, **attr = &attributes;
while (parseAttributeSpecifier(*attr))
while (parseGnuAttributeSpecifier(*attr))
attr = &(*attr)->next;
if (LA() == T_AT_INTERFACE)
return parseObjCInterface(node, attributes);
......@@ -761,11 +761,7 @@ bool Parser::parseNamespace(DeclarationAST *&node)
ast->namespace_token = namespace_token;
if (LA() == T_IDENTIFIER)
ast->identifier_token = consumeToken();
SpecifierListAST **attr_ptr = &ast->attribute_list;
while (LA() == T___ATTRIBUTE__) {
parseAttributeSpecifier(*attr_ptr);
attr_ptr = &(*attr_ptr)->next;