Commit e2a727c4 authored by Erik Verbruggen's avatar Erik Verbruggen Committed by Nikolai Kosjar

C++: add semantic support for C++11 alias decls.

Task-number: QTCREATORBUG-9386

Change-Id: Ia68f3866c122ca5261dd73b2c740b47fb15744fc
Reviewed-by: default avatarNikolai Kosjar <nikolai.kosjar@digia.com>
parent c2d6081a
......@@ -4419,8 +4419,9 @@ unsigned AliasDeclarationAST::firstToken() const
{
if (using_token)
return using_token;
if (identifier_token)
return identifier_token;
if (name)
if (unsigned candidate = name->firstToken())
return candidate;
if (equal_token)
return equal_token;
if (typeId)
......@@ -4441,8 +4442,9 @@ unsigned AliasDeclarationAST::lastToken() const
return candidate;
if (equal_token)
return equal_token + 1;
if (identifier_token)
return identifier_token + 1;
if (name)
if (unsigned candidate = name->lastToken())
return candidate;
if (using_token)
return using_token + 1;
return 1;
......
......@@ -2432,18 +2432,22 @@ class CPLUSPLUS_EXPORT AliasDeclarationAST: public DeclarationAST
{
public:
unsigned using_token;
unsigned identifier_token;
NameAST *name;
unsigned equal_token;
TypeIdAST *typeId;
unsigned semicolon_token;
public: // annotations
Declaration *symbol;
public:
AliasDeclarationAST()
: using_token(0)
, identifier_token(0)
, name(0)
, equal_token(0)
, typeId(0)
, semicolon_token(0)
, symbol(0)
{}
virtual AliasDeclarationAST *asAliasDeclaration() { return this; }
......
......@@ -890,7 +890,8 @@ AliasDeclarationAST *AliasDeclarationAST::clone(MemoryPool *pool) const
{
AliasDeclarationAST *ast = new (pool) AliasDeclarationAST;
ast->using_token = using_token;
ast->identifier_token = identifier_token;
if (name)
ast->name = name->clone(pool);
ast->equal_token = equal_token;
if (typeId)
ast->typeId = typeId->clone(pool);
......
......@@ -1511,7 +1511,10 @@ bool ASTMatcher::match(AliasDeclarationAST *node, AliasDeclarationAST *pattern)
pattern->using_token = node->using_token;
pattern->identifier_token = node->identifier_token;
if (! pattern->name)
pattern->name = node->name;
else if (! AST::match(node->name, pattern->name, this))
return false;
pattern->equal_token = node->equal_token;
......
......@@ -584,9 +584,10 @@ public:
return __ast;
}
AliasDeclarationAST *AliasDeclaration(TypeIdAST *typeId = 0)
AliasDeclarationAST *AliasDeclaration(NameAST *name = 0, TypeIdAST *typeId = 0)
{
AliasDeclarationAST *__ast = new (&pool) AliasDeclarationAST;
__ast->name = name;
__ast->typeId = typeId;
return __ast;
}
......
......@@ -646,6 +646,7 @@ void NamespaceAliasDefinitionAST::accept0(ASTVisitor *visitor)
void AliasDeclarationAST::accept0(ASTVisitor *visitor)
{
if (visitor->visit(this)) {
accept(name, visitor);
accept(typeId, visitor);
}
visitor->endVisit(this);
......
......@@ -2066,6 +2066,27 @@ bool Bind::visit(QtInterfacesDeclarationAST *ast)
return false;
}
bool Bind::visit(AliasDeclarationAST *ast)
{
if (!ast->name)
return false;
const Name *name = this->name(ast->name);
FullySpecifiedType ty = expression(ast->typeId);
ty.setTypedef(true);
Declaration *decl = control()->newDeclaration(ast->name->firstToken(), name);
decl->setType(ty);
decl->setStorage(Symbol::Typedef);
ast->symbol = decl;
if (_scope->isClass())
decl->setVisibility(_visibility);
_scope->addMember(decl);
return false;
}
bool Bind::visit(AsmDefinitionAST *ast)
{
(void) ast;
......
......@@ -209,6 +209,7 @@ protected:
virtual bool visit(QtEnumDeclarationAST *ast);
virtual bool visit(QtFlagsDeclarationAST *ast);
virtual bool visit(QtInterfacesDeclarationAST *ast);
virtual bool visit(AliasDeclarationAST *ast);
virtual bool visit(AsmDefinitionAST *ast);
virtual bool visit(ExceptionDeclarationAST *ast);
virtual bool visit(FunctionDefinitionAST *ast);
......
......@@ -868,7 +868,9 @@ bool Parser::parseAliasDeclaration(DeclarationAST *&node)
AliasDeclarationAST *alias = new (_pool) AliasDeclarationAST;
alias->using_token = consumeToken();
alias->identifier_token = consumeToken();
SimpleNameAST *name = new (_pool) SimpleNameAST;
name->identifier_token = consumeToken();
alias->name = name;
// ### attributes!
while (LA() != T_EQUAL)
......
......@@ -198,6 +198,7 @@ private slots:
void test_checksymbols_highlightingUsedTemplateFunctionParameter_QTCREATORBUG6861();
void test_checksymbols_crashWhenUsingNamespaceClass_QTCREATORBUG9323_namespace();
void test_checksymbols_crashWhenUsingNamespaceClass_QTCREATORBUG9323_insideFunction();
void test_alias_decl_QTCREATORBUG9386();
};
void tst_CheckSymbols::test_checksymbols_TypeUse()
......@@ -1727,6 +1728,21 @@ void tst_CheckSymbols::test_checksymbols_crashWhenUsingNamespaceClass_QTCREATORB
TestData::check(source, expectedUses);
}
void tst_CheckSymbols::test_alias_decl_QTCREATORBUG9386()
{
const QByteArray source =
"using wobble = int;\n"
"wobble cobble = 1;\n"
;
const QList<Use> expectedUses = QList<Use>()
<< Use(1, 7, 6, CppHighlightingSupport::TypeUse)
<< Use(2, 1, 6, CppHighlightingSupport::TypeUse)
;
TestData::check(source, expectedUses);
}
void tst_CheckSymbols::test_checksymbols_highlightingUsedTemplateFunctionParameter_QTCREATORBUG6861()
{
const QByteArray source =
......
......@@ -154,6 +154,7 @@ private slots:
void function_declaration_2();
void function_definition_1();
void nested_class_1();
void alias_declaration_1();
void typedef_1();
void typedef_2();
void typedef_3();
......@@ -320,6 +321,25 @@ void tst_Semantic::nested_class_1()
QCOMPARE(namedTy->name()->asNameId()->identifier(), objectId);
}
void tst_Semantic::alias_declaration_1()
{
QSharedPointer<Document> doc = document(
"using wobble = int;\n"
, false, false, true);
QCOMPARE(doc->errorCount, 0U);
QCOMPARE(doc->globals->memberCount(), 1U);
Declaration *decl = doc->globals->memberAt(0)->asDeclaration();
QVERIFY(decl->name());
QVERIFY(decl->name()->identifier());
QCOMPARE(decl->name()->identifier()->chars(), "wobble");
QVERIFY(decl->isTypedef());
QVERIFY(decl->type().isTypedef());
QVERIFY(decl->type()->isIntegerType());
}
void tst_Semantic::typedef_1()
{
QSharedPointer<Document> doc = document(
......
......@@ -865,8 +865,7 @@ virtual bool visit(AliasDeclarationAST *ast)
{
if (ast->using_token)
terminal(ast->using_token, ast);
if (ast->identifier_token)
terminal(ast->identifier_token, ast);
nonterminal(ast->name);
if (ast->equal_token)
terminal(ast->equal_token, ast);
nonterminal(ast->typeId);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment