forked from qt-creator/qt-creator
C++: Support noexcept operator
The code model failed to parse the noexcept operator which is often used in noexcept specifiers, e.g.: "void f() noexcept(noexcept(g()));" Consequently some c++11 headers such as unordered_map, array and unordered_set could not be parsed and no code completition was available. I have created the NoExceptOperatorExpressionAST class which is created whenever a noexcept token is found in an expression with operator precedence. The noExcept test case in the cplusplus/cxx11 test now contains a function that uses the noexcept operator. Fixed noexcept operator parsing Added the test requested by Sergey Shambir, which then revealed that i had not implemeneted the noexpect operator parsing according to the c++ specification. As stated here http://cpp0x.centaur.ath.cx/expr.unary.noexcept.html the noexcept operator is a unary-expression that contains an expression (and not a constant-expression). This should now be fixed. Change-Id: Id4a99a43b660bd83e7680274491d99a698b57094 Reviewed-by: Nikolai Kosjar <nikolai.kosjar@theqtcompany.com>
This commit is contained in:
22
src/libs/3rdparty/cplusplus/AST.cpp
vendored
22
src/libs/3rdparty/cplusplus/AST.cpp
vendored
@@ -4560,3 +4560,25 @@ unsigned AlignmentSpecifierAST::lastToken() const
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** \generated */
|
||||||
|
unsigned NoExceptOperatorExpressionAST::firstToken() const
|
||||||
|
{
|
||||||
|
if (noexcept_token)
|
||||||
|
return noexcept_token;
|
||||||
|
if (expression)
|
||||||
|
if (unsigned candidate = expression->firstToken())
|
||||||
|
return candidate;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \generated */
|
||||||
|
unsigned NoExceptOperatorExpressionAST::lastToken() const
|
||||||
|
{
|
||||||
|
if (expression)
|
||||||
|
if (unsigned candidate = expression->lastToken())
|
||||||
|
return candidate;
|
||||||
|
if (noexcept_token)
|
||||||
|
return noexcept_token + 1;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
25
src/libs/3rdparty/cplusplus/AST.h
vendored
25
src/libs/3rdparty/cplusplus/AST.h
vendored
@@ -206,6 +206,7 @@ public:
|
|||||||
virtual NewArrayDeclaratorAST *asNewArrayDeclarator() { return 0; }
|
virtual NewArrayDeclaratorAST *asNewArrayDeclarator() { return 0; }
|
||||||
virtual NewExpressionAST *asNewExpression() { return 0; }
|
virtual NewExpressionAST *asNewExpression() { return 0; }
|
||||||
virtual NewTypeIdAST *asNewTypeId() { return 0; }
|
virtual NewTypeIdAST *asNewTypeId() { return 0; }
|
||||||
|
virtual NoExceptOperatorExpressionAST *asNoExceptOperatorExpression() { return 0; }
|
||||||
virtual NoExceptSpecificationAST *asNoExceptSpecification() { return 0; }
|
virtual NoExceptSpecificationAST *asNoExceptSpecification() { return 0; }
|
||||||
virtual NumericLiteralAST *asNumericLiteral() { return 0; }
|
virtual NumericLiteralAST *asNumericLiteral() { return 0; }
|
||||||
virtual ObjCClassDeclarationAST *asObjCClassDeclaration() { return 0; }
|
virtual ObjCClassDeclarationAST *asObjCClassDeclaration() { return 0; }
|
||||||
@@ -3397,6 +3398,30 @@ protected:
|
|||||||
virtual bool match0(AST *, ASTMatcher *);
|
virtual bool match0(AST *, ASTMatcher *);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class CPLUSPLUS_EXPORT NoExceptOperatorExpressionAST: public ExpressionAST
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
unsigned noexcept_token;
|
||||||
|
ExpressionAST *expression;
|
||||||
|
|
||||||
|
public:
|
||||||
|
NoExceptOperatorExpressionAST()
|
||||||
|
: noexcept_token(0)
|
||||||
|
, expression(0)
|
||||||
|
{}
|
||||||
|
|
||||||
|
virtual NoExceptOperatorExpressionAST *asNoExceptOperatorExpression() { return this; }
|
||||||
|
|
||||||
|
virtual unsigned firstToken() const;
|
||||||
|
virtual unsigned lastToken() const;
|
||||||
|
|
||||||
|
virtual NoExceptOperatorExpressionAST *clone(MemoryPool *pool) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void accept0(ASTVisitor *visitor);
|
||||||
|
virtual bool match0(AST *, ASTMatcher *);
|
||||||
|
};
|
||||||
|
|
||||||
class CPLUSPLUS_EXPORT TranslationUnitAST: public AST
|
class CPLUSPLUS_EXPORT TranslationUnitAST: public AST
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|||||||
9
src/libs/3rdparty/cplusplus/ASTClone.cpp
vendored
9
src/libs/3rdparty/cplusplus/ASTClone.cpp
vendored
@@ -1267,6 +1267,15 @@ ThrowExpressionAST *ThrowExpressionAST::clone(MemoryPool *pool) const
|
|||||||
return ast;
|
return ast;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NoExceptOperatorExpressionAST *NoExceptOperatorExpressionAST::clone(MemoryPool *pool) const
|
||||||
|
{
|
||||||
|
NoExceptOperatorExpressionAST *ast = new (pool) NoExceptOperatorExpressionAST;
|
||||||
|
ast->noexcept_token = noexcept_token;
|
||||||
|
if (expression)
|
||||||
|
ast->expression = expression->clone(pool);
|
||||||
|
return ast;
|
||||||
|
}
|
||||||
|
|
||||||
TranslationUnitAST *TranslationUnitAST::clone(MemoryPool *pool) const
|
TranslationUnitAST *TranslationUnitAST::clone(MemoryPool *pool) const
|
||||||
{
|
{
|
||||||
TranslationUnitAST *ast = new (pool) TranslationUnitAST;
|
TranslationUnitAST *ast = new (pool) TranslationUnitAST;
|
||||||
|
|||||||
8
src/libs/3rdparty/cplusplus/ASTMatch0.cpp
vendored
8
src/libs/3rdparty/cplusplus/ASTMatch0.cpp
vendored
@@ -880,6 +880,14 @@ bool ThrowExpressionAST::match0(AST *pattern, ASTMatcher *matcher)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool NoExceptOperatorExpressionAST::match0(AST *pattern, ASTMatcher *matcher)
|
||||||
|
{
|
||||||
|
if (NoExceptOperatorExpressionAST *_other = pattern->asNoExceptOperatorExpression())
|
||||||
|
return matcher->match(this, _other);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool TranslationUnitAST::match0(AST *pattern, ASTMatcher *matcher)
|
bool TranslationUnitAST::match0(AST *pattern, ASTMatcher *matcher)
|
||||||
{
|
{
|
||||||
if (TranslationUnitAST *_other = pattern->asTranslationUnit())
|
if (TranslationUnitAST *_other = pattern->asTranslationUnit())
|
||||||
|
|||||||
15
src/libs/3rdparty/cplusplus/ASTMatcher.cpp
vendored
15
src/libs/3rdparty/cplusplus/ASTMatcher.cpp
vendored
@@ -2145,6 +2145,21 @@ bool ASTMatcher::match(ThrowExpressionAST *node, ThrowExpressionAST *pattern)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ASTMatcher::match(NoExceptOperatorExpressionAST *node, NoExceptOperatorExpressionAST *pattern)
|
||||||
|
{
|
||||||
|
(void) node;
|
||||||
|
(void) pattern;
|
||||||
|
|
||||||
|
pattern->noexcept_token = node->noexcept_token;
|
||||||
|
|
||||||
|
if (! pattern->expression)
|
||||||
|
pattern->expression = node->expression;
|
||||||
|
else if (! AST::match(node->expression, pattern->expression, this))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool ASTMatcher::match(TranslationUnitAST *node, TranslationUnitAST *pattern)
|
bool ASTMatcher::match(TranslationUnitAST *node, TranslationUnitAST *pattern)
|
||||||
{
|
{
|
||||||
(void) node;
|
(void) node;
|
||||||
|
|||||||
1
src/libs/3rdparty/cplusplus/ASTMatcher.h
vendored
1
src/libs/3rdparty/cplusplus/ASTMatcher.h
vendored
@@ -106,6 +106,7 @@ public:
|
|||||||
virtual bool match(NewArrayDeclaratorAST *node, NewArrayDeclaratorAST *pattern);
|
virtual bool match(NewArrayDeclaratorAST *node, NewArrayDeclaratorAST *pattern);
|
||||||
virtual bool match(NewExpressionAST *node, NewExpressionAST *pattern);
|
virtual bool match(NewExpressionAST *node, NewExpressionAST *pattern);
|
||||||
virtual bool match(NewTypeIdAST *node, NewTypeIdAST *pattern);
|
virtual bool match(NewTypeIdAST *node, NewTypeIdAST *pattern);
|
||||||
|
virtual bool match(NoExceptOperatorExpressionAST *node, NoExceptOperatorExpressionAST *pattern);
|
||||||
virtual bool match(NoExceptSpecificationAST *node, NoExceptSpecificationAST *pattern);
|
virtual bool match(NoExceptSpecificationAST *node, NoExceptSpecificationAST *pattern);
|
||||||
virtual bool match(NumericLiteralAST *node, NumericLiteralAST *pattern);
|
virtual bool match(NumericLiteralAST *node, NumericLiteralAST *pattern);
|
||||||
virtual bool match(ObjCClassDeclarationAST *node, ObjCClassDeclarationAST *pattern);
|
virtual bool match(ObjCClassDeclarationAST *node, ObjCClassDeclarationAST *pattern);
|
||||||
|
|||||||
@@ -837,6 +837,13 @@ public:
|
|||||||
return ast;
|
return ast;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NoExceptOperatorExpressionAST *NoExceptOperatorExpression(ExpressionAST *expression = 0)
|
||||||
|
{
|
||||||
|
NoExceptOperatorExpressionAST *ast = new (&pool) NoExceptOperatorExpressionAST;
|
||||||
|
ast->expression = expression;
|
||||||
|
return ast;
|
||||||
|
}
|
||||||
|
|
||||||
TranslationUnitAST *TranslationUnit(DeclarationListAST *declaration_list = 0)
|
TranslationUnitAST *TranslationUnit(DeclarationListAST *declaration_list = 0)
|
||||||
{
|
{
|
||||||
TranslationUnitAST *ast = new (&pool) TranslationUnitAST;
|
TranslationUnitAST *ast = new (&pool) TranslationUnitAST;
|
||||||
|
|||||||
8
src/libs/3rdparty/cplusplus/ASTVisit.cpp
vendored
8
src/libs/3rdparty/cplusplus/ASTVisit.cpp
vendored
@@ -930,6 +930,14 @@ void ThrowExpressionAST::accept0(ASTVisitor *visitor)
|
|||||||
visitor->endVisit(this);
|
visitor->endVisit(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NoExceptOperatorExpressionAST::accept0(ASTVisitor *visitor)
|
||||||
|
{
|
||||||
|
if (visitor->visit(this)) {
|
||||||
|
accept(expression, visitor);
|
||||||
|
}
|
||||||
|
visitor->endVisit(this);
|
||||||
|
}
|
||||||
|
|
||||||
void TranslationUnitAST::accept0(ASTVisitor *visitor)
|
void TranslationUnitAST::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
@@ -148,6 +148,7 @@ public:
|
|||||||
virtual bool visit(NewArrayDeclaratorAST *) { return true; }
|
virtual bool visit(NewArrayDeclaratorAST *) { return true; }
|
||||||
virtual bool visit(NewExpressionAST *) { return true; }
|
virtual bool visit(NewExpressionAST *) { return true; }
|
||||||
virtual bool visit(NewTypeIdAST *) { return true; }
|
virtual bool visit(NewTypeIdAST *) { return true; }
|
||||||
|
virtual bool visit(NoExceptOperatorExpressionAST *) { return true; }
|
||||||
virtual bool visit(NoExceptSpecificationAST *) { return true; }
|
virtual bool visit(NoExceptSpecificationAST *) { return true; }
|
||||||
virtual bool visit(NumericLiteralAST *) { return true; }
|
virtual bool visit(NumericLiteralAST *) { return true; }
|
||||||
virtual bool visit(ObjCClassDeclarationAST *) { return true; }
|
virtual bool visit(ObjCClassDeclarationAST *) { return true; }
|
||||||
@@ -298,6 +299,7 @@ public:
|
|||||||
virtual void endVisit(NewArrayDeclaratorAST *) {}
|
virtual void endVisit(NewArrayDeclaratorAST *) {}
|
||||||
virtual void endVisit(NewExpressionAST *) {}
|
virtual void endVisit(NewExpressionAST *) {}
|
||||||
virtual void endVisit(NewTypeIdAST *) {}
|
virtual void endVisit(NewTypeIdAST *) {}
|
||||||
|
virtual void endVisit(NoExceptOperatorExpressionAST *) {}
|
||||||
virtual void endVisit(NoExceptSpecificationAST *) {}
|
virtual void endVisit(NoExceptSpecificationAST *) {}
|
||||||
virtual void endVisit(NumericLiteralAST *) {}
|
virtual void endVisit(NumericLiteralAST *) {}
|
||||||
virtual void endVisit(ObjCClassDeclarationAST *) {}
|
virtual void endVisit(ObjCClassDeclarationAST *) {}
|
||||||
|
|||||||
1
src/libs/3rdparty/cplusplus/ASTfwd.h
vendored
1
src/libs/3rdparty/cplusplus/ASTfwd.h
vendored
@@ -113,6 +113,7 @@ class NestedNameSpecifierAST;
|
|||||||
class NewArrayDeclaratorAST;
|
class NewArrayDeclaratorAST;
|
||||||
class NewExpressionAST;
|
class NewExpressionAST;
|
||||||
class NewTypeIdAST;
|
class NewTypeIdAST;
|
||||||
|
class NoExceptOperatorExpressionAST;
|
||||||
class NoExceptSpecificationAST;
|
class NoExceptSpecificationAST;
|
||||||
class NumericLiteralAST;
|
class NumericLiteralAST;
|
||||||
class ObjCClassDeclarationAST;
|
class ObjCClassDeclarationAST;
|
||||||
|
|||||||
21
src/libs/3rdparty/cplusplus/Parser.cpp
vendored
21
src/libs/3rdparty/cplusplus/Parser.cpp
vendored
@@ -5238,6 +5238,14 @@ bool Parser::parseUnaryExpression(ExpressionAST *&node)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
case T_NOEXCEPT: {
|
||||||
|
if (!_languageFeatures.cxx11Enabled)
|
||||||
|
break;
|
||||||
|
|
||||||
|
return parseNoExceptOperatorExpression(node);
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
} // switch
|
} // switch
|
||||||
@@ -5674,6 +5682,19 @@ bool Parser::parseThrowExpression(ExpressionAST *&node)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Parser::parseNoExceptOperatorExpression(ExpressionAST *&node)
|
||||||
|
{
|
||||||
|
DEBUG_THIS_RULE();
|
||||||
|
if (_languageFeatures.cxx11Enabled && LA() == T_NOEXCEPT) {
|
||||||
|
NoExceptOperatorExpressionAST *ast = new (_pool) NoExceptOperatorExpressionAST;
|
||||||
|
ast->noexcept_token = consumeToken();
|
||||||
|
parseExpression(ast->expression);
|
||||||
|
node = ast;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool Parser::lookAtObjCSelector() const
|
bool Parser::lookAtObjCSelector() const
|
||||||
{
|
{
|
||||||
switch (LA()) {
|
switch (LA()) {
|
||||||
|
|||||||
1
src/libs/3rdparty/cplusplus/Parser.h
vendored
1
src/libs/3rdparty/cplusplus/Parser.h
vendored
@@ -155,6 +155,7 @@ public:
|
|||||||
bool parseTemplateParameter(DeclarationAST *&node);
|
bool parseTemplateParameter(DeclarationAST *&node);
|
||||||
bool parseTemplateParameterList(DeclarationListAST *&node);
|
bool parseTemplateParameterList(DeclarationListAST *&node);
|
||||||
bool parseThrowExpression(ExpressionAST *&node);
|
bool parseThrowExpression(ExpressionAST *&node);
|
||||||
|
bool parseNoExceptOperatorExpression(ExpressionAST *&node);
|
||||||
bool parseTryBlockStatement(StatementAST *&node, CtorInitializerAST **placeholder);
|
bool parseTryBlockStatement(StatementAST *&node, CtorInitializerAST **placeholder);
|
||||||
bool parseCatchClause(CatchClauseListAST *&node);
|
bool parseCatchClause(CatchClauseListAST *&node);
|
||||||
bool parseTypeId(ExpressionAST *&node);
|
bool parseTypeId(ExpressionAST *&node);
|
||||||
|
|||||||
@@ -1381,6 +1381,12 @@ bool FindUsages::visit(ThrowExpressionAST *ast)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool FindUsages::visit(NoExceptOperatorExpressionAST* ast)
|
||||||
|
{
|
||||||
|
this->expression(ast->expression);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool FindUsages::visit(TypeIdAST *ast)
|
bool FindUsages::visit(TypeIdAST *ast)
|
||||||
{
|
{
|
||||||
for (SpecifierListAST *it = ast->type_specifier_list; it; it = it->next) {
|
for (SpecifierListAST *it = ast->type_specifier_list; it; it = it->next) {
|
||||||
|
|||||||
@@ -205,6 +205,7 @@ protected:
|
|||||||
virtual bool visit(NestedExpressionAST *ast);
|
virtual bool visit(NestedExpressionAST *ast);
|
||||||
virtual bool visit(StringLiteralAST *ast);
|
virtual bool visit(StringLiteralAST *ast);
|
||||||
virtual bool visit(ThrowExpressionAST *ast);
|
virtual bool visit(ThrowExpressionAST *ast);
|
||||||
|
virtual bool visit(NoExceptOperatorExpressionAST *ast);
|
||||||
virtual bool visit(TypeIdAST *ast);
|
virtual bool visit(TypeIdAST *ast);
|
||||||
virtual bool visit(UnaryExpressionAST *ast);
|
virtual bool visit(UnaryExpressionAST *ast);
|
||||||
virtual bool visit(ObjCMessageExpressionAST *ast);
|
virtual bool visit(ObjCMessageExpressionAST *ast);
|
||||||
|
|||||||
@@ -1237,6 +1237,14 @@ virtual bool visit(ThrowExpressionAST *ast)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual bool visit(NoExceptOperatorExpressionAST *ast)
|
||||||
|
{
|
||||||
|
if (ast->noexcept_token)
|
||||||
|
terminal(ast->noexcept_token, ast);
|
||||||
|
nonterminal(ast->expression);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
virtual bool visit(TranslationUnitAST *ast)
|
virtual bool visit(TranslationUnitAST *ast)
|
||||||
{
|
{
|
||||||
for (DeclarationListAST *iter = ast->declaration_list; iter; iter = iter->next)
|
for (DeclarationListAST *iter = ast->declaration_list; iter; iter = iter->next)
|
||||||
|
|||||||
@@ -3,3 +3,11 @@ void f() noexcept {
|
|||||||
|
|
||||||
void g() noexcept(1) {
|
void g() noexcept(1) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void h() noexcept(noexcept(f())) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
bool noExcept_hf = noexcept(h()) && noexcept(f());
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user