forked from qt-creator/qt-creator
C++11: Parse alias declarations.
The parser no longer fails declarations like: using Foo = std::vector<int>::iterator; Change-Id: Ib3a552ebbe0147fa138db6448a52cdba8f9b9207 Reviewed-by: hjk <qthjk@ovi.com>
This commit is contained in:
34
src/libs/3rdparty/cplusplus/AST.cpp
vendored
34
src/libs/3rdparty/cplusplus/AST.cpp
vendored
@@ -4431,3 +4431,37 @@ unsigned AlignofExpressionAST::lastToken() const
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** \generated */
|
||||||
|
unsigned AliasDeclarationAST::firstToken() const
|
||||||
|
{
|
||||||
|
if (using_token)
|
||||||
|
return using_token;
|
||||||
|
if (identifier_token)
|
||||||
|
return identifier_token;
|
||||||
|
if (equal_token)
|
||||||
|
return equal_token;
|
||||||
|
if (typeId)
|
||||||
|
if (unsigned candidate = typeId->firstToken())
|
||||||
|
return candidate;
|
||||||
|
if (semicolon_token)
|
||||||
|
return semicolon_token;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \generated */
|
||||||
|
unsigned AliasDeclarationAST::lastToken() const
|
||||||
|
{
|
||||||
|
if (semicolon_token)
|
||||||
|
return semicolon_token + 1;
|
||||||
|
if (typeId)
|
||||||
|
if (unsigned candidate = typeId->lastToken())
|
||||||
|
return candidate;
|
||||||
|
if (equal_token)
|
||||||
|
return equal_token + 1;
|
||||||
|
if (identifier_token)
|
||||||
|
return identifier_token + 1;
|
||||||
|
if (using_token)
|
||||||
|
return using_token + 1;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
31
src/libs/3rdparty/cplusplus/AST.h
vendored
31
src/libs/3rdparty/cplusplus/AST.h
vendored
@@ -125,6 +125,7 @@ public:
|
|||||||
virtual AST *clone(MemoryPool *pool) const = 0;
|
virtual AST *clone(MemoryPool *pool) const = 0;
|
||||||
|
|
||||||
virtual AccessDeclarationAST *asAccessDeclaration() { return 0; }
|
virtual AccessDeclarationAST *asAccessDeclaration() { return 0; }
|
||||||
|
virtual AliasDeclarationAST *asAliasDeclaration() { return 0; }
|
||||||
virtual AlignofExpressionAST *asAlignofExpression() { return 0; }
|
virtual AlignofExpressionAST *asAlignofExpression() { return 0; }
|
||||||
virtual ArrayAccessAST *asArrayAccess() { return 0; }
|
virtual ArrayAccessAST *asArrayAccess() { return 0; }
|
||||||
virtual ArrayDeclaratorAST *asArrayDeclarator() { return 0; }
|
virtual ArrayDeclaratorAST *asArrayDeclarator() { return 0; }
|
||||||
@@ -2400,6 +2401,36 @@ protected:
|
|||||||
virtual bool match0(AST *, ASTMatcher *);
|
virtual bool match0(AST *, ASTMatcher *);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class CPLUSPLUS_EXPORT AliasDeclarationAST: public DeclarationAST
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
unsigned using_token;
|
||||||
|
unsigned identifier_token;
|
||||||
|
unsigned equal_token;
|
||||||
|
TypeIdAST *typeId;
|
||||||
|
unsigned semicolon_token;
|
||||||
|
|
||||||
|
public:
|
||||||
|
AliasDeclarationAST()
|
||||||
|
: using_token(0)
|
||||||
|
, identifier_token(0)
|
||||||
|
, equal_token(0)
|
||||||
|
, typeId(0)
|
||||||
|
, semicolon_token(0)
|
||||||
|
{}
|
||||||
|
|
||||||
|
virtual AliasDeclarationAST *asAliasDeclaration() { return this; }
|
||||||
|
|
||||||
|
virtual unsigned firstToken() const;
|
||||||
|
virtual unsigned lastToken() const;
|
||||||
|
|
||||||
|
virtual AliasDeclarationAST *clone(MemoryPool *pool) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void accept0(ASTVisitor *visitor);
|
||||||
|
virtual bool match0(AST *, ASTMatcher *);
|
||||||
|
};
|
||||||
|
|
||||||
class CPLUSPLUS_EXPORT ExpressionListParenAST: public ExpressionAST
|
class CPLUSPLUS_EXPORT ExpressionListParenAST: public ExpressionAST
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|||||||
12
src/libs/3rdparty/cplusplus/ASTClone.cpp
vendored
12
src/libs/3rdparty/cplusplus/ASTClone.cpp
vendored
@@ -874,6 +874,18 @@ NamespaceAliasDefinitionAST *NamespaceAliasDefinitionAST::clone(MemoryPool *pool
|
|||||||
return ast;
|
return ast;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AliasDeclarationAST *AliasDeclarationAST::clone(MemoryPool *pool) const
|
||||||
|
{
|
||||||
|
AliasDeclarationAST *ast = new (pool) AliasDeclarationAST;
|
||||||
|
ast->using_token = using_token;
|
||||||
|
ast->identifier_token = identifier_token;
|
||||||
|
ast->equal_token = equal_token;
|
||||||
|
if (typeId)
|
||||||
|
ast->typeId = typeId->clone(pool);
|
||||||
|
ast->semicolon_token = semicolon_token;
|
||||||
|
return ast;
|
||||||
|
}
|
||||||
|
|
||||||
ExpressionListParenAST *ExpressionListParenAST::clone(MemoryPool *pool) const
|
ExpressionListParenAST *ExpressionListParenAST::clone(MemoryPool *pool) const
|
||||||
{
|
{
|
||||||
ExpressionListParenAST *ast = new (pool) ExpressionListParenAST;
|
ExpressionListParenAST *ast = new (pool) ExpressionListParenAST;
|
||||||
|
|||||||
8
src/libs/3rdparty/cplusplus/ASTMatch0.cpp
vendored
8
src/libs/3rdparty/cplusplus/ASTMatch0.cpp
vendored
@@ -592,6 +592,14 @@ bool NamespaceAliasDefinitionAST::match0(AST *pattern, ASTMatcher *matcher)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AliasDeclarationAST::match0(AST *pattern, ASTMatcher *matcher)
|
||||||
|
{
|
||||||
|
if (AliasDeclarationAST *_other = pattern->asAliasDeclaration())
|
||||||
|
return matcher->match(this, _other);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool ExpressionListParenAST::match0(AST *pattern, ASTMatcher *matcher)
|
bool ExpressionListParenAST::match0(AST *pattern, ASTMatcher *matcher)
|
||||||
{
|
{
|
||||||
if (ExpressionListParenAST *_other = pattern->asExpressionListParen())
|
if (ExpressionListParenAST *_other = pattern->asExpressionListParen())
|
||||||
|
|||||||
21
src/libs/3rdparty/cplusplus/ASTMatcher.cpp
vendored
21
src/libs/3rdparty/cplusplus/ASTMatcher.cpp
vendored
@@ -1485,6 +1485,27 @@ bool ASTMatcher::match(NamespaceAliasDefinitionAST *node, NamespaceAliasDefiniti
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ASTMatcher::match(AliasDeclarationAST *node, AliasDeclarationAST *pattern)
|
||||||
|
{
|
||||||
|
(void) node;
|
||||||
|
(void) pattern;
|
||||||
|
|
||||||
|
pattern->using_token = node->using_token;
|
||||||
|
|
||||||
|
pattern->identifier_token = node->identifier_token;
|
||||||
|
|
||||||
|
pattern->equal_token = node->equal_token;
|
||||||
|
|
||||||
|
if (! pattern->typeId)
|
||||||
|
pattern->typeId = node->typeId;
|
||||||
|
else if (! AST::match(node->typeId, pattern->typeId, this))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
pattern->semicolon_token = node->semicolon_token;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool ASTMatcher::match(ExpressionListParenAST *node, ExpressionListParenAST *pattern)
|
bool ASTMatcher::match(ExpressionListParenAST *node, ExpressionListParenAST *pattern)
|
||||||
{
|
{
|
||||||
(void) node;
|
(void) node;
|
||||||
|
|||||||
1
src/libs/3rdparty/cplusplus/ASTMatcher.h
vendored
1
src/libs/3rdparty/cplusplus/ASTMatcher.h
vendored
@@ -32,6 +32,7 @@ public:
|
|||||||
virtual ~ASTMatcher();
|
virtual ~ASTMatcher();
|
||||||
|
|
||||||
virtual bool match(AccessDeclarationAST *node, AccessDeclarationAST *pattern);
|
virtual bool match(AccessDeclarationAST *node, AccessDeclarationAST *pattern);
|
||||||
|
virtual bool match(AliasDeclarationAST *node, AliasDeclarationAST *pattern);
|
||||||
virtual bool match(AlignofExpressionAST *node, AlignofExpressionAST *pattern);
|
virtual bool match(AlignofExpressionAST *node, AlignofExpressionAST *pattern);
|
||||||
virtual bool match(ArrayAccessAST *node, ArrayAccessAST *pattern);
|
virtual bool match(ArrayAccessAST *node, ArrayAccessAST *pattern);
|
||||||
virtual bool match(ArrayDeclaratorAST *node, ArrayDeclaratorAST *pattern);
|
virtual bool match(ArrayDeclaratorAST *node, ArrayDeclaratorAST *pattern);
|
||||||
|
|||||||
@@ -577,6 +577,13 @@ public:
|
|||||||
return __ast;
|
return __ast;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AliasDeclarationAST *AliasDeclaration(TypeIdAST *typeId = 0)
|
||||||
|
{
|
||||||
|
AliasDeclarationAST *__ast = new (&pool) AliasDeclarationAST;
|
||||||
|
__ast->typeId = typeId;
|
||||||
|
return __ast;
|
||||||
|
}
|
||||||
|
|
||||||
ExpressionListParenAST *ExpressionListParen(ExpressionListAST *expression_list = 0)
|
ExpressionListParenAST *ExpressionListParen(ExpressionListAST *expression_list = 0)
|
||||||
{
|
{
|
||||||
ExpressionListParenAST *__ast = new (&pool) ExpressionListParenAST;
|
ExpressionListParenAST *__ast = new (&pool) ExpressionListParenAST;
|
||||||
|
|||||||
8
src/libs/3rdparty/cplusplus/ASTVisit.cpp
vendored
8
src/libs/3rdparty/cplusplus/ASTVisit.cpp
vendored
@@ -635,6 +635,14 @@ void NamespaceAliasDefinitionAST::accept0(ASTVisitor *visitor)
|
|||||||
visitor->endVisit(this);
|
visitor->endVisit(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AliasDeclarationAST::accept0(ASTVisitor *visitor)
|
||||||
|
{
|
||||||
|
if (visitor->visit(this)) {
|
||||||
|
accept(typeId, visitor);
|
||||||
|
}
|
||||||
|
visitor->endVisit(this);
|
||||||
|
}
|
||||||
|
|
||||||
void ExpressionListParenAST::accept0(ASTVisitor *visitor)
|
void ExpressionListParenAST::accept0(ASTVisitor *visitor)
|
||||||
{
|
{
|
||||||
if (visitor->visit(this)) {
|
if (visitor->visit(this)) {
|
||||||
|
|||||||
2
src/libs/3rdparty/cplusplus/ASTVisitor.h
vendored
2
src/libs/3rdparty/cplusplus/ASTVisitor.h
vendored
@@ -74,6 +74,7 @@ public:
|
|||||||
virtual void postVisit(AST *) {}
|
virtual void postVisit(AST *) {}
|
||||||
|
|
||||||
virtual bool visit(AccessDeclarationAST *) { return true; }
|
virtual bool visit(AccessDeclarationAST *) { return true; }
|
||||||
|
virtual bool visit(AliasDeclarationAST *) { return true; }
|
||||||
virtual bool visit(AlignofExpressionAST *) { return true; }
|
virtual bool visit(AlignofExpressionAST *) { return true; }
|
||||||
virtual bool visit(ArrayAccessAST *) { return true; }
|
virtual bool visit(ArrayAccessAST *) { return true; }
|
||||||
virtual bool visit(ArrayDeclaratorAST *) { return true; }
|
virtual bool visit(ArrayDeclaratorAST *) { return true; }
|
||||||
@@ -219,6 +220,7 @@ public:
|
|||||||
virtual bool visit(WhileStatementAST *) { return true; }
|
virtual bool visit(WhileStatementAST *) { return true; }
|
||||||
|
|
||||||
virtual void endVisit(AccessDeclarationAST *) {}
|
virtual void endVisit(AccessDeclarationAST *) {}
|
||||||
|
virtual void endVisit(AliasDeclarationAST *) {}
|
||||||
virtual void endVisit(AlignofExpressionAST *) {}
|
virtual void endVisit(AlignofExpressionAST *) {}
|
||||||
virtual void endVisit(ArrayAccessAST *) {}
|
virtual void endVisit(ArrayAccessAST *) {}
|
||||||
virtual void endVisit(ArrayDeclaratorAST *) {}
|
virtual void endVisit(ArrayDeclaratorAST *) {}
|
||||||
|
|||||||
1
src/libs/3rdparty/cplusplus/ASTfwd.h
vendored
1
src/libs/3rdparty/cplusplus/ASTfwd.h
vendored
@@ -32,6 +32,7 @@ class ASTVisitor;
|
|||||||
class ASTMatcher;
|
class ASTMatcher;
|
||||||
|
|
||||||
class AccessDeclarationAST;
|
class AccessDeclarationAST;
|
||||||
|
class AliasDeclarationAST;
|
||||||
class AlignofExpressionAST;
|
class AlignofExpressionAST;
|
||||||
class ArrayAccessAST;
|
class ArrayAccessAST;
|
||||||
class ArrayDeclaratorAST;
|
class ArrayDeclaratorAST;
|
||||||
|
|||||||
46
src/libs/3rdparty/cplusplus/Parser.cpp
vendored
46
src/libs/3rdparty/cplusplus/Parser.cpp
vendored
@@ -367,6 +367,18 @@ bool Parser::skip(int l, int r)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Parser::find(int token, int stopAt)
|
||||||
|
{
|
||||||
|
for (int i = 1; ; ++i) {
|
||||||
|
const int tk = LA(i);
|
||||||
|
if (!tk || tk == stopAt)
|
||||||
|
return 0;
|
||||||
|
if (tk == token)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void Parser::match(int kind, unsigned *token)
|
void Parser::match(int kind, unsigned *token)
|
||||||
{
|
{
|
||||||
if (LA() == kind)
|
if (LA() == kind)
|
||||||
@@ -811,6 +823,9 @@ bool Parser::parseUsing(DeclarationAST *&node)
|
|||||||
if (LA(2) == T_NAMESPACE)
|
if (LA(2) == T_NAMESPACE)
|
||||||
return parseUsingDirective(node);
|
return parseUsingDirective(node);
|
||||||
|
|
||||||
|
if (_cxx0xEnabled && LA(2) == T_IDENTIFIER && parseAliasDeclaration(node))
|
||||||
|
return true;
|
||||||
|
|
||||||
UsingAST *ast = new (_pool) UsingAST;
|
UsingAST *ast = new (_pool) UsingAST;
|
||||||
ast->using_token = consumeToken();
|
ast->using_token = consumeToken();
|
||||||
|
|
||||||
@@ -840,6 +855,37 @@ bool Parser::parseUsingDirective(DeclarationAST *&node)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// alias-declaration = 'using' identifier attribute-specifier-seq(opt) '=' type-id ';'
|
||||||
|
bool Parser::parseAliasDeclaration(DeclarationAST *&node)
|
||||||
|
{
|
||||||
|
DEBUG_THIS_RULE();
|
||||||
|
if (LA() != T_USING || LA(2) != T_IDENTIFIER)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!find(T_EQUAL, T_SEMICOLON))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
AliasDeclarationAST *alias = new (_pool) AliasDeclarationAST;
|
||||||
|
alias->using_token = consumeToken();
|
||||||
|
alias->identifier_token = consumeToken();
|
||||||
|
|
||||||
|
// ### attributes!
|
||||||
|
while (LA() != T_EQUAL)
|
||||||
|
consumeToken();
|
||||||
|
|
||||||
|
alias->equal_token = consumeToken();
|
||||||
|
|
||||||
|
ExpressionAST *expr = 0;
|
||||||
|
parseTypeId(expr);
|
||||||
|
if (expr)
|
||||||
|
alias->typeId = expr->asTypeId();
|
||||||
|
|
||||||
|
match(T_SEMICOLON, &alias->semicolon_token);
|
||||||
|
|
||||||
|
node = alias;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool Parser::parseConversionFunctionId(NameAST *&node)
|
bool Parser::parseConversionFunctionId(NameAST *&node)
|
||||||
{
|
{
|
||||||
DEBUG_THIS_RULE();
|
DEBUG_THIS_RULE();
|
||||||
|
|||||||
2
src/libs/3rdparty/cplusplus/Parser.h
vendored
2
src/libs/3rdparty/cplusplus/Parser.h
vendored
@@ -191,6 +191,7 @@ public:
|
|||||||
bool parseUnqualifiedName(NameAST *&node, bool acceptTemplateId = true);
|
bool parseUnqualifiedName(NameAST *&node, bool acceptTemplateId = true);
|
||||||
bool parseUsing(DeclarationAST *&node);
|
bool parseUsing(DeclarationAST *&node);
|
||||||
bool parseUsingDirective(DeclarationAST *&node);
|
bool parseUsingDirective(DeclarationAST *&node);
|
||||||
|
bool parseAliasDeclaration(DeclarationAST *&node);
|
||||||
bool parseWhileStatement(StatementAST *&node);
|
bool parseWhileStatement(StatementAST *&node);
|
||||||
|
|
||||||
void parseExpressionWithOperatorPrecedence(ExpressionAST *&lhs, int minPrecedence);
|
void parseExpressionWithOperatorPrecedence(ExpressionAST *&lhs, int minPrecedence);
|
||||||
@@ -256,6 +257,7 @@ public:
|
|||||||
void skipUntilDeclaration();
|
void skipUntilDeclaration();
|
||||||
bool skipUntilStatement();
|
bool skipUntilStatement();
|
||||||
bool skip(int l, int r);
|
bool skip(int l, int r);
|
||||||
|
int find(int token, int stopAt);
|
||||||
|
|
||||||
bool lookAtTypeParameter() const;
|
bool lookAtTypeParameter() const;
|
||||||
bool lookAtCVQualifier() const;
|
bool lookAtCVQualifier() const;
|
||||||
|
|||||||
4
tests/auto/cplusplus/cxx11/data/aliasDecl.1.cpp
Normal file
4
tests/auto/cplusplus/cxx11/data/aliasDecl.1.cpp
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
using Foo = int;
|
||||||
|
using Bar = std::vector<int>::value_type;
|
||||||
|
using A [[foo]] = const float;
|
||||||
|
using B alignas(void*) = C *;
|
||||||
@@ -142,6 +142,7 @@ void tst_cxx11::parse_data()
|
|||||||
QTest::newRow("refQualifier.1") << "refQualifier.1.cpp" << "";
|
QTest::newRow("refQualifier.1") << "refQualifier.1.cpp" << "";
|
||||||
QTest::newRow("alignofAlignas.1") << "alignofAlignas.1.cpp" << "";
|
QTest::newRow("alignofAlignas.1") << "alignofAlignas.1.cpp" << "";
|
||||||
QTest::newRow("rangeFor.1") << "rangeFor.1.cpp" << "";
|
QTest::newRow("rangeFor.1") << "rangeFor.1.cpp" << "";
|
||||||
|
QTest::newRow("aliasDecl.1") << "aliasDecl.1.cpp" << "";
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_cxx11::parse()
|
void tst_cxx11::parse()
|
||||||
|
|||||||
@@ -848,6 +848,20 @@ virtual bool visit(NamespaceAliasDefinitionAST *ast)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual bool visit(AliasDeclarationAST *ast)
|
||||||
|
{
|
||||||
|
if (ast->using_token)
|
||||||
|
terminal(ast->using_token, ast);
|
||||||
|
if (ast->identifier_token)
|
||||||
|
terminal(ast->identifier_token, ast);
|
||||||
|
if (ast->equal_token)
|
||||||
|
terminal(ast->equal_token, ast);
|
||||||
|
nonterminal(ast->typeId);
|
||||||
|
if (ast->semicolon_token)
|
||||||
|
terminal(ast->semicolon_token, ast);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
virtual bool visit(ExpressionListParenAST *ast)
|
virtual bool visit(ExpressionListParenAST *ast)
|
||||||
{
|
{
|
||||||
if (ast->lparen_token)
|
if (ast->lparen_token)
|
||||||
|
|||||||
Reference in New Issue
Block a user