diff options
author | Claus Steuer <claus755@gmail.com> | 2015-07-22 11:08:01 +0200 |
---|---|---|
committer | Claus Steuer <claus755@gmail.com> | 2015-10-03 17:24:45 +0000 |
commit | 158b07c9c84c8bcd77620f36fe6f1e3eb8d7f224 (patch) | |
tree | 843867c4d879e1f4f759661289e584ecd8383148 /src | |
parent | b1f6974954bfb135a4dd6c0747dec896ef7d8102 (diff) |
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>
Diffstat (limited to 'src')
-rw-r--r-- | src/libs/3rdparty/cplusplus/AST.cpp | 22 | ||||
-rw-r--r-- | src/libs/3rdparty/cplusplus/AST.h | 25 | ||||
-rw-r--r-- | src/libs/3rdparty/cplusplus/ASTClone.cpp | 9 | ||||
-rw-r--r-- | src/libs/3rdparty/cplusplus/ASTMatch0.cpp | 8 | ||||
-rw-r--r-- | src/libs/3rdparty/cplusplus/ASTMatcher.cpp | 15 | ||||
-rw-r--r-- | src/libs/3rdparty/cplusplus/ASTMatcher.h | 1 | ||||
-rw-r--r-- | src/libs/3rdparty/cplusplus/ASTPatternBuilder.h | 7 | ||||
-rw-r--r-- | src/libs/3rdparty/cplusplus/ASTVisit.cpp | 8 | ||||
-rw-r--r-- | src/libs/3rdparty/cplusplus/ASTVisitor.h | 2 | ||||
-rw-r--r-- | src/libs/3rdparty/cplusplus/ASTfwd.h | 1 | ||||
-rw-r--r-- | src/libs/3rdparty/cplusplus/Parser.cpp | 21 | ||||
-rw-r--r-- | src/libs/3rdparty/cplusplus/Parser.h | 1 | ||||
-rw-r--r-- | src/libs/cplusplus/FindUsages.cpp | 6 | ||||
-rw-r--r-- | src/libs/cplusplus/FindUsages.h | 1 | ||||
-rw-r--r-- | src/tools/cplusplus-ast2png/dumpers.inc | 8 |
15 files changed, 135 insertions, 0 deletions
diff --git a/src/libs/3rdparty/cplusplus/AST.cpp b/src/libs/3rdparty/cplusplus/AST.cpp index be235a8c41..035c9baf73 100644 --- a/src/libs/3rdparty/cplusplus/AST.cpp +++ b/src/libs/3rdparty/cplusplus/AST.cpp @@ -4560,3 +4560,25 @@ unsigned AlignmentSpecifierAST::lastToken() const 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; +} + diff --git a/src/libs/3rdparty/cplusplus/AST.h b/src/libs/3rdparty/cplusplus/AST.h index c44d9b4a81..8c3ceca968 100644 --- a/src/libs/3rdparty/cplusplus/AST.h +++ b/src/libs/3rdparty/cplusplus/AST.h @@ -206,6 +206,7 @@ public: virtual NewArrayDeclaratorAST *asNewArrayDeclarator() { return 0; } virtual NewExpressionAST *asNewExpression() { return 0; } virtual NewTypeIdAST *asNewTypeId() { return 0; } + virtual NoExceptOperatorExpressionAST *asNoExceptOperatorExpression() { return 0; } virtual NoExceptSpecificationAST *asNoExceptSpecification() { return 0; } virtual NumericLiteralAST *asNumericLiteral() { return 0; } virtual ObjCClassDeclarationAST *asObjCClassDeclaration() { return 0; } @@ -3397,6 +3398,30 @@ protected: 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 { public: diff --git a/src/libs/3rdparty/cplusplus/ASTClone.cpp b/src/libs/3rdparty/cplusplus/ASTClone.cpp index 647929ad31..17a1af18d9 100644 --- a/src/libs/3rdparty/cplusplus/ASTClone.cpp +++ b/src/libs/3rdparty/cplusplus/ASTClone.cpp @@ -1267,6 +1267,15 @@ ThrowExpressionAST *ThrowExpressionAST::clone(MemoryPool *pool) const 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 *ast = new (pool) TranslationUnitAST; diff --git a/src/libs/3rdparty/cplusplus/ASTMatch0.cpp b/src/libs/3rdparty/cplusplus/ASTMatch0.cpp index b0e732b257..66c6a1be4d 100644 --- a/src/libs/3rdparty/cplusplus/ASTMatch0.cpp +++ b/src/libs/3rdparty/cplusplus/ASTMatch0.cpp @@ -880,6 +880,14 @@ bool ThrowExpressionAST::match0(AST *pattern, ASTMatcher *matcher) 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) { if (TranslationUnitAST *_other = pattern->asTranslationUnit()) diff --git a/src/libs/3rdparty/cplusplus/ASTMatcher.cpp b/src/libs/3rdparty/cplusplus/ASTMatcher.cpp index ed8ef6b09f..d76180a8ca 100644 --- a/src/libs/3rdparty/cplusplus/ASTMatcher.cpp +++ b/src/libs/3rdparty/cplusplus/ASTMatcher.cpp @@ -2145,6 +2145,21 @@ bool ASTMatcher::match(ThrowExpressionAST *node, ThrowExpressionAST *pattern) 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) { (void) node; diff --git a/src/libs/3rdparty/cplusplus/ASTMatcher.h b/src/libs/3rdparty/cplusplus/ASTMatcher.h index 888ada0c20..ad622316da 100644 --- a/src/libs/3rdparty/cplusplus/ASTMatcher.h +++ b/src/libs/3rdparty/cplusplus/ASTMatcher.h @@ -106,6 +106,7 @@ public: virtual bool match(NewArrayDeclaratorAST *node, NewArrayDeclaratorAST *pattern); virtual bool match(NewExpressionAST *node, NewExpressionAST *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(NumericLiteralAST *node, NumericLiteralAST *pattern); virtual bool match(ObjCClassDeclarationAST *node, ObjCClassDeclarationAST *pattern); diff --git a/src/libs/3rdparty/cplusplus/ASTPatternBuilder.h b/src/libs/3rdparty/cplusplus/ASTPatternBuilder.h index 15d4142f7d..f3934b7ba1 100644 --- a/src/libs/3rdparty/cplusplus/ASTPatternBuilder.h +++ b/src/libs/3rdparty/cplusplus/ASTPatternBuilder.h @@ -837,6 +837,13 @@ public: return ast; } + NoExceptOperatorExpressionAST *NoExceptOperatorExpression(ExpressionAST *expression = 0) + { + NoExceptOperatorExpressionAST *ast = new (&pool) NoExceptOperatorExpressionAST; + ast->expression = expression; + return ast; + } + TranslationUnitAST *TranslationUnit(DeclarationListAST *declaration_list = 0) { TranslationUnitAST *ast = new (&pool) TranslationUnitAST; diff --git a/src/libs/3rdparty/cplusplus/ASTVisit.cpp b/src/libs/3rdparty/cplusplus/ASTVisit.cpp index 77b7e1b3fd..5ebe6ba3a5 100644 --- a/src/libs/3rdparty/cplusplus/ASTVisit.cpp +++ b/src/libs/3rdparty/cplusplus/ASTVisit.cpp @@ -930,6 +930,14 @@ void ThrowExpressionAST::accept0(ASTVisitor *visitor) visitor->endVisit(this); } +void NoExceptOperatorExpressionAST::accept0(ASTVisitor *visitor) +{ + if (visitor->visit(this)) { + accept(expression, visitor); + } + visitor->endVisit(this); +} + void TranslationUnitAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { diff --git a/src/libs/3rdparty/cplusplus/ASTVisitor.h b/src/libs/3rdparty/cplusplus/ASTVisitor.h index f6428f13b9..699694e9f9 100644 --- a/src/libs/3rdparty/cplusplus/ASTVisitor.h +++ b/src/libs/3rdparty/cplusplus/ASTVisitor.h @@ -148,6 +148,7 @@ public: virtual bool visit(NewArrayDeclaratorAST *) { return true; } virtual bool visit(NewExpressionAST *) { return true; } virtual bool visit(NewTypeIdAST *) { return true; } + virtual bool visit(NoExceptOperatorExpressionAST *) { return true; } virtual bool visit(NoExceptSpecificationAST *) { return true; } virtual bool visit(NumericLiteralAST *) { return true; } virtual bool visit(ObjCClassDeclarationAST *) { return true; } @@ -298,6 +299,7 @@ public: virtual void endVisit(NewArrayDeclaratorAST *) {} virtual void endVisit(NewExpressionAST *) {} virtual void endVisit(NewTypeIdAST *) {} + virtual void endVisit(NoExceptOperatorExpressionAST *) {} virtual void endVisit(NoExceptSpecificationAST *) {} virtual void endVisit(NumericLiteralAST *) {} virtual void endVisit(ObjCClassDeclarationAST *) {} diff --git a/src/libs/3rdparty/cplusplus/ASTfwd.h b/src/libs/3rdparty/cplusplus/ASTfwd.h index 9723366308..0dd8d04037 100644 --- a/src/libs/3rdparty/cplusplus/ASTfwd.h +++ b/src/libs/3rdparty/cplusplus/ASTfwd.h @@ -113,6 +113,7 @@ class NestedNameSpecifierAST; class NewArrayDeclaratorAST; class NewExpressionAST; class NewTypeIdAST; +class NoExceptOperatorExpressionAST; class NoExceptSpecificationAST; class NumericLiteralAST; class ObjCClassDeclarationAST; diff --git a/src/libs/3rdparty/cplusplus/Parser.cpp b/src/libs/3rdparty/cplusplus/Parser.cpp index da67e51b63..6fccebb015 100644 --- a/src/libs/3rdparty/cplusplus/Parser.cpp +++ b/src/libs/3rdparty/cplusplus/Parser.cpp @@ -5238,6 +5238,14 @@ bool Parser::parseUnaryExpression(ExpressionAST *&node) return true; } + + case T_NOEXCEPT: { + if (!_languageFeatures.cxx11Enabled) + break; + + return parseNoExceptOperatorExpression(node); + } + default: break; } // switch @@ -5674,6 +5682,19 @@ bool Parser::parseThrowExpression(ExpressionAST *&node) 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 { switch (LA()) { diff --git a/src/libs/3rdparty/cplusplus/Parser.h b/src/libs/3rdparty/cplusplus/Parser.h index 22d7a2192e..1c69c21896 100644 --- a/src/libs/3rdparty/cplusplus/Parser.h +++ b/src/libs/3rdparty/cplusplus/Parser.h @@ -155,6 +155,7 @@ public: bool parseTemplateParameter(DeclarationAST *&node); bool parseTemplateParameterList(DeclarationListAST *&node); bool parseThrowExpression(ExpressionAST *&node); + bool parseNoExceptOperatorExpression(ExpressionAST *&node); bool parseTryBlockStatement(StatementAST *&node, CtorInitializerAST **placeholder); bool parseCatchClause(CatchClauseListAST *&node); bool parseTypeId(ExpressionAST *&node); diff --git a/src/libs/cplusplus/FindUsages.cpp b/src/libs/cplusplus/FindUsages.cpp index 1b4e0c6e2b..b9d34bd00c 100644 --- a/src/libs/cplusplus/FindUsages.cpp +++ b/src/libs/cplusplus/FindUsages.cpp @@ -1381,6 +1381,12 @@ bool FindUsages::visit(ThrowExpressionAST *ast) return false; } +bool FindUsages::visit(NoExceptOperatorExpressionAST* ast) +{ + this->expression(ast->expression); + return false; +} + bool FindUsages::visit(TypeIdAST *ast) { for (SpecifierListAST *it = ast->type_specifier_list; it; it = it->next) { diff --git a/src/libs/cplusplus/FindUsages.h b/src/libs/cplusplus/FindUsages.h index 8d58054910..99c8abba11 100644 --- a/src/libs/cplusplus/FindUsages.h +++ b/src/libs/cplusplus/FindUsages.h @@ -205,6 +205,7 @@ protected: virtual bool visit(NestedExpressionAST *ast); virtual bool visit(StringLiteralAST *ast); virtual bool visit(ThrowExpressionAST *ast); + virtual bool visit(NoExceptOperatorExpressionAST *ast); virtual bool visit(TypeIdAST *ast); virtual bool visit(UnaryExpressionAST *ast); virtual bool visit(ObjCMessageExpressionAST *ast); diff --git a/src/tools/cplusplus-ast2png/dumpers.inc b/src/tools/cplusplus-ast2png/dumpers.inc index aea2150a71..166c014013 100644 --- a/src/tools/cplusplus-ast2png/dumpers.inc +++ b/src/tools/cplusplus-ast2png/dumpers.inc @@ -1237,6 +1237,14 @@ virtual bool visit(ThrowExpressionAST *ast) 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) { for (DeclarationListAST *iter = ast->declaration_list; iter; iter = iter->next) |