From 4064c8158511d73d08deeb7ee5867a19628e6c70 Mon Sep 17 00:00:00 2001
From: Jason Newton <jason@utopiacompression.com>
Date: Thu, 9 May 2013 17:21:03 -0700
Subject: [PATCH] first try for c++11 alignas keyword support

---
 src/libs/3rdparty/cplusplus/AST.cpp        | 27 +++++++++++++++
 src/libs/3rdparty/cplusplus/AST.h          | 29 ++++++++++++++++
 src/libs/3rdparty/cplusplus/ASTClone.cpp   | 33 +++++++++++++-----
 src/libs/3rdparty/cplusplus/ASTMatch0.cpp  |  9 ++++-
 src/libs/3rdparty/cplusplus/ASTMatcher.cpp | 24 +++++++++++++
 src/libs/3rdparty/cplusplus/ASTMatcher.h   |  1 +
 src/libs/3rdparty/cplusplus/ASTVisit.cpp   |  9 +++++
 src/libs/3rdparty/cplusplus/ASTVisitor.h   |  2 ++
 src/libs/3rdparty/cplusplus/ASTfwd.h       |  1 +
 src/libs/3rdparty/cplusplus/Bind.cpp       |  9 +++++
 src/libs/3rdparty/cplusplus/Bind.h         |  2 ++
 src/libs/3rdparty/cplusplus/Parser.cpp     | 54 +++++++++++++++++++-----------
 12 files changed, 171 insertions(+), 29 deletions(-)

diff --git a/src/libs/3rdparty/cplusplus/AST.cpp b/src/libs/3rdparty/cplusplus/AST.cpp
index 13c4568..3b62798 100644
--- a/src/libs/3rdparty/cplusplus/AST.cpp
+++ b/src/libs/3rdparty/cplusplus/AST.cpp
@@ -67,8 +67,16 @@ bool AST::match(AST *pattern, ASTMatcher *matcher)
     return match0(pattern, matcher);
 }
 
+unsigned AlignmentSpecifierAST::firstToken() const
+{
+    return alignas_token;
+}
+
 unsigned AttributeSpecifierAST::firstToken() const
 {
+    if(alignment){
+        return alignment->firstToken();
+    }
     return attribute_token;
 }
 
@@ -4193,8 +4201,27 @@ unsigned WhileStatementAST::lastToken() const
 }
 
 /** \generated */
+unsigned AlignmentSpecifierAST::lastToken() const
+{
+    if (rparen_token)
+        return rparen_token + 1;
+    if (expression)
+        if (unsigned candidate = expression->lastToken())
+            return candidate;
+    if (lparen_token)
+        return lparen_token + 1;
+    if (alignas_token)
+        return alignas_token + 1;
+    return 1;
+}
+
+/** \generated */
 unsigned AttributeSpecifierAST::lastToken() const
 {
+    if(alignment){
+        return alignment->lastToken();
+    }
+
     if (second_rparen_token)
         return second_rparen_token + 1;
     if (first_rparen_token)
diff --git a/src/libs/3rdparty/cplusplus/AST.h b/src/libs/3rdparty/cplusplus/AST.h
index 961bc2e..d935991 100644
--- a/src/libs/3rdparty/cplusplus/AST.h
+++ b/src/libs/3rdparty/cplusplus/AST.h
@@ -126,6 +126,7 @@ public:
 
     virtual AccessDeclarationAST *asAccessDeclaration() { return 0; }
     virtual AliasDeclarationAST *asAliasDeclaration() { return 0; }
+    virtual AlignmentSpecifierAST *asAlignmentSpecifier() { return 0; }
     virtual AlignofExpressionAST *asAlignofExpression() { return 0; }
     virtual ArrayAccessAST *asArrayAccess() { return 0; }
     virtual ArrayDeclaratorAST *asArrayDeclarator() { return 0; }
@@ -455,6 +456,32 @@ protected:
     virtual bool match0(AST *, ASTMatcher *);
 };
 
+class CPLUSPLUS_EXPORT AlignmentSpecifierAST: public SpecifierAST
+{
+public:
+    unsigned alignas_token;
+    unsigned lparen_token;
+    ExpressionAST *expression;
+    unsigned rparen_token;
+
+public:
+    AlignmentSpecifierAST()
+        : alignas_token(0)
+        , lparen_token(0)
+        , expression(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 AttributeSpecifierAST: public SpecifierAST
 {
 public:
@@ -464,6 +491,7 @@ public:
     AttributeListAST *attribute_list;
     unsigned first_rparen_token;
     unsigned second_rparen_token;
+    AlignmentSpecifierAST *alignment;
 
 public:
     AttributeSpecifierAST()
@@ -473,6 +501,7 @@ public:
         , attribute_list(0)
         , first_rparen_token(0)
         , second_rparen_token(0)
+        , alignment(0)
     {}
 
     virtual AttributeSpecifierAST *asAttributeSpecifier() { return this; }
diff --git a/src/libs/3rdparty/cplusplus/ASTClone.cpp b/src/libs/3rdparty/cplusplus/ASTClone.cpp
index 73565b8..63666d5 100644
--- a/src/libs/3rdparty/cplusplus/ASTClone.cpp
+++ b/src/libs/3rdparty/cplusplus/ASTClone.cpp
@@ -58,14 +58,19 @@ SimpleSpecifierAST *SimpleSpecifierAST::clone(MemoryPool *pool) const
 AttributeSpecifierAST *AttributeSpecifierAST::clone(MemoryPool *pool) const
 {
     AttributeSpecifierAST *ast = new (pool) AttributeSpecifierAST;
-    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;
-         iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
-        *ast_iter = new (pool) AttributeListAST((iter->value) ? iter->value->clone(pool) : 0);
-    ast->first_rparen_token = first_rparen_token;
-    ast->second_rparen_token = second_rparen_token;
+    if(alignment){
+        ast->alignment = alignment->clone(pool);
+    }else{
+        ast->alignment = 0;
+        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;
+             iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
+            *ast_iter = new (pool) AttributeListAST((iter->value) ? iter->value->clone(pool) : 0);
+        ast->first_rparen_token = first_rparen_token;
+        ast->second_rparen_token = second_rparen_token;
+    }
     return ast;
 }
 
@@ -1136,6 +1141,18 @@ SizeofExpressionAST *SizeofExpressionAST::clone(MemoryPool *pool) const
     return ast;
 }
 
+AlignmentSpecifierAST *AlignmentSpecifierAST::clone(MemoryPool *pool) const
+{
+    AlignmentSpecifierAST *ast = new (pool) AlignmentSpecifierAST;
+    ast->alignas_token = alignas_token;
+    ast->lparen_token = lparen_token;
+    if (expression)
+        ast->expression = expression->clone(pool);
+    ast->rparen_token = rparen_token;
+    return ast;
+}
+
+
 AlignofExpressionAST *AlignofExpressionAST::clone(MemoryPool *pool) const
 {
     AlignofExpressionAST *ast = new (pool) AlignofExpressionAST;
diff --git a/src/libs/3rdparty/cplusplus/ASTMatch0.cpp b/src/libs/3rdparty/cplusplus/ASTMatch0.cpp
index c49b5da..4f2f994 100644
--- a/src/libs/3rdparty/cplusplus/ASTMatch0.cpp
+++ b/src/libs/3rdparty/cplusplus/ASTMatch0.cpp
@@ -776,6 +776,14 @@ bool SizeofExpressionAST::match0(AST *pattern, ASTMatcher *matcher)
     return false;
 }
 
+bool AlignmentSpecifierAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (AlignmentSpecifierAST *_other = pattern->asAlignmentSpecifier())
+        return matcher->match(this, _other);
+
+    return false;
+}
+
 bool AlignofExpressionAST::match0(AST *pattern, ASTMatcher *matcher)
 {
     if (AlignofExpressionAST *_other = pattern->asAlignofExpression())
@@ -783,7 +791,6 @@ bool AlignofExpressionAST::match0(AST *pattern, ASTMatcher *matcher)
 
     return false;
 }
-
 bool PointerLiteralAST::match0(AST *pattern, ASTMatcher *matcher)
 {
     if (PointerLiteralAST *_other = pattern->asPointerLiteral())
diff --git a/src/libs/3rdparty/cplusplus/ASTMatcher.cpp b/src/libs/3rdparty/cplusplus/ASTMatcher.cpp
index 4fbb9d6..40fa347 100644
--- a/src/libs/3rdparty/cplusplus/ASTMatcher.cpp
+++ b/src/libs/3rdparty/cplusplus/ASTMatcher.cpp
@@ -93,6 +93,11 @@ bool ASTMatcher::match(AttributeSpecifierAST *node, AttributeSpecifierAST *patte
 
     pattern->second_rparen_token = node->second_rparen_token;
 
+    if (! pattern->alignment)
+        pattern->alignment = node->alignment;
+    else if (! AST::match(node->alignment, pattern->alignment, this))
+        return false;
+
     return true;
 }
 
@@ -1925,6 +1930,25 @@ bool ASTMatcher::match(SizeofExpressionAST *node, SizeofExpressionAST *pattern)
     return true;
 }
 
+bool ASTMatcher::match(AlignmentSpecifierAST *node, AlignmentSpecifierAST *pattern)
+{
+    (void) node;
+    (void) pattern;
+
+    pattern->alignas_token = node->alignas_token;
+
+    pattern->lparen_token = node->lparen_token;
+
+    if (! pattern->expression)
+        pattern->expression = node->expression;
+    else if (! AST::match(node->expression, pattern->expression, this))
+        return false;
+
+    pattern->rparen_token = node->rparen_token;
+
+    return true;
+}
+
 bool ASTMatcher::match(AlignofExpressionAST *node, AlignofExpressionAST *pattern)
 {
     (void) node;
diff --git a/src/libs/3rdparty/cplusplus/ASTMatcher.h b/src/libs/3rdparty/cplusplus/ASTMatcher.h
index 2984225..c04bc16 100644
--- a/src/libs/3rdparty/cplusplus/ASTMatcher.h
+++ b/src/libs/3rdparty/cplusplus/ASTMatcher.h
@@ -33,6 +33,7 @@ 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(ArrayAccessAST *node, ArrayAccessAST *pattern);
     virtual bool match(ArrayDeclaratorAST *node, ArrayDeclaratorAST *pattern);
diff --git a/src/libs/3rdparty/cplusplus/ASTVisit.cpp b/src/libs/3rdparty/cplusplus/ASTVisit.cpp
index 76adc01..0437007 100644
--- a/src/libs/3rdparty/cplusplus/ASTVisit.cpp
+++ b/src/libs/3rdparty/cplusplus/ASTVisit.cpp
@@ -54,10 +54,19 @@ void SimpleSpecifierAST::accept0(ASTVisitor *visitor)
     visitor->endVisit(this);
 }
 
+void AlignmentSpecifierAST::accept0(ASTVisitor *visitor)
+{
+    if (visitor->visit(this)) {
+        accept(expression, visitor);
+    }
+    visitor->endVisit(this);
+}
+
 void AttributeSpecifierAST::accept0(ASTVisitor *visitor)
 {
     if (visitor->visit(this)) {
         accept(attribute_list, visitor);
+        accept(alignment, visitor);
     }
     visitor->endVisit(this);
 }
diff --git a/src/libs/3rdparty/cplusplus/ASTVisitor.h b/src/libs/3rdparty/cplusplus/ASTVisitor.h
index a7d3f72..f9d924f 100644
--- a/src/libs/3rdparty/cplusplus/ASTVisitor.h
+++ b/src/libs/3rdparty/cplusplus/ASTVisitor.h
@@ -75,6 +75,7 @@ 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(ArrayAccessAST *) { return true; }
     virtual bool visit(ArrayDeclaratorAST *) { return true; }
@@ -220,6 +221,7 @@ public:
 
     virtual void endVisit(AccessDeclarationAST *) {}
     virtual void endVisit(AliasDeclarationAST *) {}
+    virtual void endVisit(AlignmentSpecifierAST *) {}
     virtual void endVisit(AlignofExpressionAST *) {}
     virtual void endVisit(ArrayAccessAST *) {}
     virtual void endVisit(ArrayDeclaratorAST *) {}
diff --git a/src/libs/3rdparty/cplusplus/ASTfwd.h b/src/libs/3rdparty/cplusplus/ASTfwd.h
index 722a5b0..b20382a 100644
--- a/src/libs/3rdparty/cplusplus/ASTfwd.h
+++ b/src/libs/3rdparty/cplusplus/ASTfwd.h
@@ -33,6 +33,7 @@ class ASTMatcher;
 
 class AccessDeclarationAST;
 class AliasDeclarationAST;
+class AlignmentSpecifierAST;
 class AlignofExpressionAST;
 class ArrayAccessAST;
 class ArrayDeclaratorAST;
diff --git a/src/libs/3rdparty/cplusplus/Bind.cpp b/src/libs/3rdparty/cplusplus/Bind.cpp
index b21b167..f5e6d89 100644
--- a/src/libs/3rdparty/cplusplus/Bind.cpp
+++ b/src/libs/3rdparty/cplusplus/Bind.cpp
@@ -2858,6 +2858,12 @@ bool Bind::visit(SimpleSpecifierAST *ast)
     return false;
 }
 
+bool Bind::visit(AlignmentSpecifierAST *ast)
+{
+    this->expression(ast->expression);
+    return false;
+}
+
 bool Bind::visit(AttributeSpecifierAST *ast)
 {
     // unsigned attribute_token = ast->attribute_token;
@@ -2868,6 +2874,9 @@ bool Bind::visit(AttributeSpecifierAST *ast)
     }
     // unsigned first_rparen_token = ast->first_rparen_token;
     // unsigned second_rparen_token = ast->second_rparen_token;
+    if(ast->alignment){
+        this->visit(ast->alignment);
+    }
     return false;
 }
 
diff --git a/src/libs/3rdparty/cplusplus/Bind.h b/src/libs/3rdparty/cplusplus/Bind.h
index ca2c608..cb02675 100644
--- a/src/libs/3rdparty/cplusplus/Bind.h
+++ b/src/libs/3rdparty/cplusplus/Bind.h
@@ -78,6 +78,7 @@ protected:
 
     const Name *objCSelectorArgument(ObjCSelectorArgumentAST *ast, bool *hasArg);
     void attribute(AttributeAST *ast);
+    void alignas(AlignmentSpecifierAST *ast);
     FullySpecifiedType declarator(DeclaratorAST *ast, const FullySpecifiedType &init, DeclaratorIdAST **declaratorId);
     void qtInterfaceName(QtInterfaceNameAST *ast);
     void baseSpecifier(BaseSpecifierAST *ast, unsigned colon_token, Class *klass);
@@ -244,6 +245,7 @@ protected:
     // SpecifierAST
     virtual bool visit(SimpleSpecifierAST *ast);
     virtual bool visit(AttributeSpecifierAST *ast);
+    virtual bool visit(AlignmentSpecifierAST *ast);
     virtual bool visit(TypeofSpecifierAST *ast);
     virtual bool visit(DecltypeSpecifierAST *ast);
     virtual bool visit(ClassSpecifierAST *ast);
diff --git a/src/libs/3rdparty/cplusplus/Parser.cpp b/src/libs/3rdparty/cplusplus/Parser.cpp
index 71f0fad..b2b4a35 100644
--- a/src/libs/3rdparty/cplusplus/Parser.cpp
+++ b/src/libs/3rdparty/cplusplus/Parser.cpp
@@ -783,7 +783,7 @@ bool Parser::parseNamespace(DeclarationAST *&node)
     if (LA() == T_IDENTIFIER)
         ast->identifier_token = consumeToken();
     SpecifierListAST **attr_ptr = &ast->attribute_list;
-    while (LA() == T___ATTRIBUTE__) {
+    while (LA() == T___ATTRIBUTE__ || LA() == T_ALIGNAS) {
         parseAttributeSpecifier(*attr_ptr);
         attr_ptr = &(*attr_ptr)->next;
     }
@@ -796,6 +796,7 @@ bool Parser::parseNamespace(DeclarationAST *&node)
             case T_IDENTIFIER:
             case T_POUND:
             case T_POUND_POUND:
+            case T_ALIGNAS:
             case T___ATTRIBUTE__:
             case T_LPAREN:
             case T_RPAREN:
@@ -1214,7 +1215,7 @@ bool Parser::parseCvQualifiers(SpecifierListAST *&node)
             spec->specifier_token = consumeToken();
             *ast = new (_pool) SpecifierListAST(spec);
             ast = &(*ast)->next;
-        } else if (LA() == T___ATTRIBUTE__) {
+        } else if (LA() == T___ATTRIBUTE__ || LA() == T_ALIGNAS) {
             parseAttributeSpecifier(*ast);
             ast = &(*ast)->next;
         } else {
@@ -1402,7 +1403,7 @@ bool Parser::parseCoreDeclarator(DeclaratorAST *&node, SpecifierListAST *decl_sp
     unsigned start = cursor();
     SpecifierListAST *attributes = 0;
     SpecifierListAST **attribute_ptr = &attributes;
-    while (LA() == T___ATTRIBUTE__) {
+    while (LA() == T___ATTRIBUTE__ || LA() == T_ALIGNAS) {
         parseAttributeSpecifier(*attribute_ptr);
         attribute_ptr = &(*attribute_ptr)->next;
     }
@@ -1581,7 +1582,7 @@ bool Parser::parseDeclarator(DeclaratorAST *&node, SpecifierListAST *decl_specif
     }
 
     SpecifierListAST **spec_ptr = &node->post_attribute_list;
-    while (LA() == T___ATTRIBUTE__) {
+    while (LA() == T___ATTRIBUTE__ || LA() == T_ALIGNAS) {
         parseAttributeSpecifier(*spec_ptr);
         spec_ptr = &(*spec_ptr)->next;
     }
@@ -1989,7 +1990,7 @@ bool Parser::parseClassSpecifier(SpecifierListAST *&node)
     unsigned classkey_token = consumeToken();
 
     SpecifierListAST *attributes = 0, **attr_ptr = &attributes;
-    while (LA() == T___ATTRIBUTE__) {
+    while (LA() == T___ATTRIBUTE__ || LA() == T_ALIGNAS) {
         parseAttributeSpecifier(*attr_ptr);
         attr_ptr = &(*attr_ptr)->next;
     }
@@ -2481,7 +2482,7 @@ bool Parser::parseElaboratedTypeSpecifier(SpecifierListAST *&node)
         unsigned classkey_token = consumeToken();
 
         SpecifierListAST *attributes = 0, **attr_ptr = &attributes;
-        while (LA() == T___ATTRIBUTE__) {
+        while (LA() == T___ATTRIBUTE__ || LA() == T_ALIGNAS) {
             parseAttributeSpecifier(*attr_ptr);
             attr_ptr = &(*attr_ptr)->next;
         }
@@ -3756,6 +3757,7 @@ bool Parser::lookAtBuiltinTypeSpecifier() const
     case T_VOID:
     case T_AUTO:
     case T_DECLTYPE:
+    case T_ALIGNAS:
         return true;
     // [gcc] extensions
     case T___TYPEOF__:
@@ -3781,18 +3783,30 @@ bool Parser::lookAtClassKey() const
 bool Parser::parseAttributeSpecifier(SpecifierListAST *&node)
 {
     DEBUG_THIS_RULE();
-    if (LA() != T___ATTRIBUTE__)
-        return false;
+    if (LA() == T___ATTRIBUTE__){
+        AttributeSpecifierAST *ast = new (_pool) AttributeSpecifierAST;
+        ast->attribute_token = consumeToken();
+        match(T_LPAREN, &ast->first_lparen_token);
+        match(T_LPAREN, &ast->second_lparen_token);
+        parseAttributeList(ast->attribute_list);
+        match(T_RPAREN, &ast->first_rparen_token);
+        match(T_RPAREN, &ast->second_rparen_token);
+        ast->alignment = 0;
+        node = new (_pool) SpecifierListAST(ast);
+        return true;
+    }
 
-    AttributeSpecifierAST *ast = new (_pool) AttributeSpecifierAST;
-    ast->attribute_token = consumeToken();
-    match(T_LPAREN, &ast->first_lparen_token);
-    match(T_LPAREN, &ast->second_lparen_token);
-    parseAttributeList(ast->attribute_list);
-    match(T_RPAREN, &ast->first_rparen_token);
-    match(T_RPAREN, &ast->second_rparen_token);
-    node = new (_pool) SpecifierListAST(ast);
-    return true;
+    if(LA() == T_ALIGNAS){
+        AttributeSpecifierAST *ast = new (_pool) AttributeSpecifierAST;
+        ast->alignment = new (_pool) AlignmentSpecifierAST;
+        match(T_LPAREN, &ast->alignment->lparen_token);
+        parseExpression(ast->alignment->expression);
+        match(T_RPAREN, &ast->alignment->rparen_token);
+        ast->attribute_list = 0;
+        node = new (_pool) SpecifierListAST(ast);
+        return true;
+    }
+    return false;
 }
 
 bool Parser::parseAttributeList(AttributeListAST *&node)
@@ -3834,7 +3848,7 @@ bool Parser::parseAttributeList(AttributeListAST *&node)
 bool Parser::parseBuiltinTypeSpecifier(SpecifierListAST *&node)
 {
     DEBUG_THIS_RULE();
-    if (LA() == T___ATTRIBUTE__) {
+    if (LA() == T___ATTRIBUTE__ || LA() == T_ALIGNAS) {
         return parseAttributeSpecifier(node);
     } else if (LA() == T___TYPEOF__) {
         TypeofSpecifierAST *ast = new (_pool) TypeofSpecifierAST;
@@ -3891,7 +3905,7 @@ bool Parser::parseSimpleDeclaration(DeclarationAST *&node, ClassSpecifierAST *de
             spec->specifier_token = consumeToken();
             *decl_specifier_seq_ptr = new (_pool) SpecifierListAST(spec);
             decl_specifier_seq_ptr = &(*decl_specifier_seq_ptr)->next;
-        } else if (LA() == T___ATTRIBUTE__) {
+        } else if (LA() == T___ATTRIBUTE__ || LA() == T_ALIGNAS) {
             parseAttributeSpecifier(*decl_specifier_seq_ptr);
             decl_specifier_seq_ptr = &(*decl_specifier_seq_ptr)->next;
         } else if (! named_type_specifier && ! has_complex_type_specifier && lookAtBuiltinTypeSpecifier()) {
@@ -5450,7 +5464,7 @@ bool Parser::parseObjCInterface(DeclarationAST *&node,
                                 SpecifierListAST *attributes)
 {
     DEBUG_THIS_RULE();
-    if (! attributes && LA() == T___ATTRIBUTE__) {
+    if (! attributes && (LA() == T___ATTRIBUTE__ || LA() == T_ALIGNAS)) {
         SpecifierListAST **attr = &attributes;
         while (parseAttributeSpecifier(*attr))
             attr = &(*attr)->next;
-- 
1.8.1.4

