forked from qt-creator/qt-creator
C++: Support ellipsis on variadic inheritance parsing
Change-Id: I571aefdb1f2aba88ba0c7710f16b6d8ad2e8f5a8 Reviewed-by: André Hartmann <aha_1980@gmx.de> Reviewed-by: Orgad Shaneh <orgads@gmail.com> Reviewed-by: Nikolai Kosjar <nikolai.kosjar@theqtcompany.com>
This commit is contained in:
committed by
Orgad Shaneh
parent
697479572f
commit
2a966a8917
4
src/libs/3rdparty/cplusplus/AST.cpp
vendored
4
src/libs/3rdparty/cplusplus/AST.cpp
vendored
@@ -89,7 +89,9 @@ unsigned BaseSpecifierAST::firstToken() const
|
|||||||
|
|
||||||
unsigned BaseSpecifierAST::lastToken() const
|
unsigned BaseSpecifierAST::lastToken() const
|
||||||
{
|
{
|
||||||
if (name)
|
if (ellipsis_token)
|
||||||
|
return ellipsis_token;
|
||||||
|
else if (name)
|
||||||
return name->lastToken();
|
return name->lastToken();
|
||||||
else if (virtual_token && access_specifier_token)
|
else if (virtual_token && access_specifier_token)
|
||||||
return std::max(virtual_token, access_specifier_token) + 1;
|
return std::max(virtual_token, access_specifier_token) + 1;
|
||||||
|
|||||||
2
src/libs/3rdparty/cplusplus/AST.h
vendored
2
src/libs/3rdparty/cplusplus/AST.h
vendored
@@ -1002,6 +1002,7 @@ public:
|
|||||||
unsigned virtual_token;
|
unsigned virtual_token;
|
||||||
unsigned access_specifier_token;
|
unsigned access_specifier_token;
|
||||||
NameAST *name;
|
NameAST *name;
|
||||||
|
unsigned ellipsis_token;
|
||||||
|
|
||||||
public: // annotations
|
public: // annotations
|
||||||
BaseClass *symbol;
|
BaseClass *symbol;
|
||||||
@@ -1011,6 +1012,7 @@ public:
|
|||||||
: virtual_token(0)
|
: virtual_token(0)
|
||||||
, access_specifier_token(0)
|
, access_specifier_token(0)
|
||||||
, name(0)
|
, name(0)
|
||||||
|
, ellipsis_token(0)
|
||||||
, symbol(0)
|
, symbol(0)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|||||||
1
src/libs/3rdparty/cplusplus/ASTClone.cpp
vendored
1
src/libs/3rdparty/cplusplus/ASTClone.cpp
vendored
@@ -287,6 +287,7 @@ BaseSpecifierAST *BaseSpecifierAST::clone(MemoryPool *pool) const
|
|||||||
ast->access_specifier_token = access_specifier_token;
|
ast->access_specifier_token = access_specifier_token;
|
||||||
if (name)
|
if (name)
|
||||||
ast->name = name->clone(pool);
|
ast->name = name->clone(pool);
|
||||||
|
ast->ellipsis_token = ellipsis_token;
|
||||||
return ast;
|
return ast;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
2
src/libs/3rdparty/cplusplus/ASTMatcher.cpp
vendored
2
src/libs/3rdparty/cplusplus/ASTMatcher.cpp
vendored
@@ -462,6 +462,8 @@ bool ASTMatcher::match(BaseSpecifierAST *node, BaseSpecifierAST *pattern)
|
|||||||
else if (! AST::match(node->name, pattern->name, this))
|
else if (! AST::match(node->name, pattern->name, this))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
pattern->ellipsis_token = node->ellipsis_token;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
2
src/libs/3rdparty/cplusplus/Bind.cpp
vendored
2
src/libs/3rdparty/cplusplus/Bind.cpp
vendored
@@ -429,6 +429,8 @@ void Bind::baseSpecifier(BaseSpecifierAST *ast, unsigned colon_token, Class *kla
|
|||||||
const int visibility = visibilityForAccessSpecifier(tokenKind(ast->access_specifier_token));
|
const int visibility = visibilityForAccessSpecifier(tokenKind(ast->access_specifier_token));
|
||||||
baseClass->setVisibility(visibility); // ### well, not exactly.
|
baseClass->setVisibility(visibility); // ### well, not exactly.
|
||||||
}
|
}
|
||||||
|
if (ast->ellipsis_token)
|
||||||
|
baseClass->setVariadic(true);
|
||||||
klass->addBaseClass(baseClass);
|
klass->addBaseClass(baseClass);
|
||||||
ast->symbol = baseClass;
|
ast->symbol = baseClass;
|
||||||
}
|
}
|
||||||
|
|||||||
5
src/libs/3rdparty/cplusplus/Parser.cpp
vendored
5
src/libs/3rdparty/cplusplus/Parser.cpp
vendored
@@ -3006,6 +3006,11 @@ bool Parser::parseBaseSpecifier(BaseSpecifierListAST *&node)
|
|||||||
if (! ast->name)
|
if (! ast->name)
|
||||||
error(cursor(), "expected class-name");
|
error(cursor(), "expected class-name");
|
||||||
|
|
||||||
|
// a name can have ellipsis in case of C++11
|
||||||
|
// note: the id must be unqualified then - TODO
|
||||||
|
if (_languageFeatures.cxx11Enabled && LA() == T_DOT_DOT_DOT)
|
||||||
|
ast->ellipsis_token = consumeToken();
|
||||||
|
|
||||||
node = new (_pool) BaseSpecifierListAST;
|
node = new (_pool) BaseSpecifierListAST;
|
||||||
node->value = ast;
|
node->value = ast;
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
6
src/libs/3rdparty/cplusplus/Symbols.cpp
vendored
6
src/libs/3rdparty/cplusplus/Symbols.cpp
vendored
@@ -599,6 +599,12 @@ bool BaseClass::isVirtual() const
|
|||||||
void BaseClass::setVirtual(bool isVirtual)
|
void BaseClass::setVirtual(bool isVirtual)
|
||||||
{ _isVirtual = isVirtual; }
|
{ _isVirtual = isVirtual; }
|
||||||
|
|
||||||
|
bool BaseClass::isVariadic() const
|
||||||
|
{ return _isVariadic; }
|
||||||
|
|
||||||
|
void BaseClass::setVariadic(bool isVariadic)
|
||||||
|
{ _isVariadic = isVariadic; }
|
||||||
|
|
||||||
void BaseClass::visitSymbol0(SymbolVisitor *visitor)
|
void BaseClass::visitSymbol0(SymbolVisitor *visitor)
|
||||||
{ visitor->visit(this); }
|
{ visitor->visit(this); }
|
||||||
|
|
||||||
|
|||||||
4
src/libs/3rdparty/cplusplus/Symbols.h
vendored
4
src/libs/3rdparty/cplusplus/Symbols.h
vendored
@@ -474,6 +474,9 @@ public:
|
|||||||
bool isVirtual() const;
|
bool isVirtual() const;
|
||||||
void setVirtual(bool isVirtual);
|
void setVirtual(bool isVirtual);
|
||||||
|
|
||||||
|
bool isVariadic() const;
|
||||||
|
void setVariadic(bool isVariadic);
|
||||||
|
|
||||||
// Symbol's interface
|
// Symbol's interface
|
||||||
virtual FullySpecifiedType type() const;
|
virtual FullySpecifiedType type() const;
|
||||||
void setType(const FullySpecifiedType &type);
|
void setType(const FullySpecifiedType &type);
|
||||||
@@ -488,6 +491,7 @@ protected:
|
|||||||
virtual void visitSymbol0(SymbolVisitor *visitor);
|
virtual void visitSymbol0(SymbolVisitor *visitor);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool _isVariadic;
|
||||||
bool _isVirtual;
|
bool _isVirtual;
|
||||||
FullySpecifiedType _type;
|
FullySpecifiedType _type;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -292,6 +292,8 @@ virtual bool visit(BaseSpecifierAST *ast)
|
|||||||
if (ast->access_specifier_token)
|
if (ast->access_specifier_token)
|
||||||
terminal(ast->access_specifier_token, ast);
|
terminal(ast->access_specifier_token, ast);
|
||||||
nonterminal(ast->name);
|
nonterminal(ast->name);
|
||||||
|
if (ast->ellipsis_token)
|
||||||
|
terminal(ast->ellipsis_token, ast);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -75,8 +75,10 @@ public:
|
|||||||
return unit;
|
return unit;
|
||||||
}
|
}
|
||||||
|
|
||||||
TranslationUnit *parseDeclaration(const QByteArray &source, bool blockErrors = false, bool qtMocRun = false)
|
TranslationUnit *parseDeclaration(const QByteArray &source, bool blockErrors = false,
|
||||||
{ return parse(source, TranslationUnit::ParseDeclaration, blockErrors, qtMocRun); }
|
bool qtMocRun = false, bool cxx11Enabled = false)
|
||||||
|
{ return parse(source, TranslationUnit::ParseDeclaration,
|
||||||
|
blockErrors, qtMocRun, cxx11Enabled); }
|
||||||
|
|
||||||
TranslationUnit *parseExpression(const QByteArray &source)
|
TranslationUnit *parseExpression(const QByteArray &source)
|
||||||
{ return parse(source, TranslationUnit::ParseExpression); }
|
{ return parse(source, TranslationUnit::ParseExpression); }
|
||||||
@@ -167,6 +169,11 @@ private slots:
|
|||||||
void cpp_constructor_multiple_args();
|
void cpp_constructor_multiple_args();
|
||||||
void cpp_constructor_function_try_catch();
|
void cpp_constructor_function_try_catch();
|
||||||
|
|
||||||
|
// c++11 ast
|
||||||
|
//! checks for both correct ellipsis tokens in
|
||||||
|
//! "template<class ...Args> class T : Args... {};"
|
||||||
|
void cpp11_variadic_inheritance();
|
||||||
|
|
||||||
// Q_PROPERTY
|
// Q_PROPERTY
|
||||||
void cpp_qproperty();
|
void cpp_qproperty();
|
||||||
void cpp_qproperty_data();
|
void cpp_qproperty_data();
|
||||||
@@ -1273,6 +1280,49 @@ void tst_AST::cpp_constructor_function_try_catch()
|
|||||||
QVERIFY(funDecl->parameter_declaration_clause->parameter_declaration_list != 0);
|
QVERIFY(funDecl->parameter_declaration_clause->parameter_declaration_list != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tst_AST::cpp11_variadic_inheritance()
|
||||||
|
{
|
||||||
|
QSharedPointer<TranslationUnit> unit(parseDeclaration(
|
||||||
|
"template<class ...Args> class C : public Args... {};",
|
||||||
|
false, false, true));
|
||||||
|
AST *ast = unit->ast();
|
||||||
|
QVERIFY(ast != 0);
|
||||||
|
|
||||||
|
DeclarationAST *d = ast->asDeclaration();
|
||||||
|
QVERIFY(d != 0);
|
||||||
|
|
||||||
|
TemplateDeclarationAST *t = d->asTemplateDeclaration();
|
||||||
|
QVERIFY(t != 0);
|
||||||
|
|
||||||
|
DeclarationListAST *tp = t->template_parameter_list;
|
||||||
|
QVERIFY(tp != 0);
|
||||||
|
QVERIFY(tp->next == 0);
|
||||||
|
|
||||||
|
DeclarationAST *d3 = tp->value;
|
||||||
|
QVERIFY(d3 != 0);
|
||||||
|
|
||||||
|
TypenameTypeParameterAST *ttp = d3->asTypenameTypeParameter();
|
||||||
|
QVERIFY(ttp != 0);
|
||||||
|
QVERIFY(ttp->dot_dot_dot_token != 0); // important
|
||||||
|
|
||||||
|
DeclarationAST *d2 = t->declaration;
|
||||||
|
QVERIFY(d2 != 0);
|
||||||
|
|
||||||
|
SimpleDeclarationAST *sd = d2->asSimpleDeclaration();
|
||||||
|
QVERIFY(sd != 0);
|
||||||
|
|
||||||
|
ClassSpecifierAST *cl = sd->decl_specifier_list->value->asClassSpecifier();
|
||||||
|
QVERIFY(cl != 0);
|
||||||
|
|
||||||
|
BaseSpecifierListAST *bl = cl->base_clause_list;
|
||||||
|
QVERIFY(bl != 0);
|
||||||
|
QVERIFY(bl->next == 0);
|
||||||
|
|
||||||
|
BaseSpecifierAST *ba = bl->value;
|
||||||
|
QVERIFY(ba != 0);
|
||||||
|
QVERIFY(ba->ellipsis_token != 0); // important
|
||||||
|
}
|
||||||
|
|
||||||
void tst_AST::cpp_qproperty()
|
void tst_AST::cpp_qproperty()
|
||||||
{
|
{
|
||||||
QFETCH(QByteArray, source);
|
QFETCH(QByteArray, source);
|
||||||
|
|||||||
Reference in New Issue
Block a user