From 1d3dc3015343a9ec55d58115390f5dcf9ba92297 Mon Sep 17 00:00:00 2001 From: Erik Verbruggen <erik.verbruggen@nokia.com> Date: Thu, 2 Feb 2012 13:39:24 +0100 Subject: [PATCH] C++11: add support for static_assert. Change-Id: I82d8d60acaa9265fd25e0a3734855b19bdef9c06 Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com> --- src/libs/3rdparty/cplusplus/AST.cpp | 44 +++++++++++++++++++ src/libs/3rdparty/cplusplus/AST.h | 35 +++++++++++++++ src/libs/3rdparty/cplusplus/ASTClone.cpp | 15 +++++++ src/libs/3rdparty/cplusplus/ASTMatch0.cpp | 8 ++++ src/libs/3rdparty/cplusplus/ASTMatcher.cpp | 28 ++++++++++++ src/libs/3rdparty/cplusplus/ASTMatcher.h | 1 + .../3rdparty/cplusplus/ASTPatternBuilder.h | 8 ++++ src/libs/3rdparty/cplusplus/ASTVisit.cpp | 9 ++++ src/libs/3rdparty/cplusplus/ASTVisitor.h | 2 + src/libs/3rdparty/cplusplus/ASTfwd.h | 1 + src/libs/3rdparty/cplusplus/Keywords.cpp | 28 +++++++++++- src/libs/3rdparty/cplusplus/Parser.cpp | 26 +++++++++++ src/libs/3rdparty/cplusplus/Parser.h | 1 + src/libs/3rdparty/cplusplus/Token.cpp | 2 +- src/libs/3rdparty/cplusplus/Token.h | 1 + src/libs/cplusplus/FindUsages.cpp | 6 +++ src/libs/cplusplus/FindUsages.h | 1 + tests/manual/plain-cplusplus/main.cpp | 1 + 18 files changed, 215 insertions(+), 2 deletions(-) diff --git a/src/libs/3rdparty/cplusplus/AST.cpp b/src/libs/3rdparty/cplusplus/AST.cpp index 139a856106d..109cc63455a 100644 --- a/src/libs/3rdparty/cplusplus/AST.cpp +++ b/src/libs/3rdparty/cplusplus/AST.cpp @@ -4269,3 +4269,47 @@ unsigned NoExceptSpecificationAST::lastToken() const return 1; } +/** \generated */ +unsigned StaticAssertDeclarationAST::firstToken() const +{ + if (static_assert_token) + return static_assert_token; + if (lparen_token) + return lparen_token; + if (expression) + if (unsigned candidate = expression->firstToken()) + return candidate; + if (comma_token) + return comma_token; + if (string_literal) + if (unsigned candidate = string_literal->firstToken()) + return candidate; + if (rparen_token) + return rparen_token; + if (semicolon_token) + return semicolon_token; + return 0; +} + +/** \generated */ +unsigned StaticAssertDeclarationAST::lastToken() const +{ + if (semicolon_token) + return semicolon_token + 1; + if (rparen_token) + return rparen_token + 1; + if (string_literal) + if (unsigned candidate = string_literal->lastToken()) + return candidate; + if (comma_token) + return comma_token + 1; + if (expression) + if (unsigned candidate = expression->lastToken()) + return candidate; + if (lparen_token) + return lparen_token + 1; + if (static_assert_token) + return static_assert_token + 1; + return 1; +} + diff --git a/src/libs/3rdparty/cplusplus/AST.h b/src/libs/3rdparty/cplusplus/AST.h index b02f771ab43..c6939876e6c 100644 --- a/src/libs/3rdparty/cplusplus/AST.h +++ b/src/libs/3rdparty/cplusplus/AST.h @@ -254,6 +254,7 @@ public: virtual SizeofExpressionAST *asSizeofExpression() { return 0; } virtual SpecifierAST *asSpecifier() { return 0; } virtual StatementAST *asStatement() { return 0; } + virtual StaticAssertDeclarationAST *asStaticAssertDeclaration() { return 0; } virtual StringLiteralAST *asStringLiteral() { return 0; } virtual SwitchStatementAST *asSwitchStatement() { return 0; } virtual TemplateDeclarationAST *asTemplateDeclaration() { return 0; } @@ -3062,6 +3063,40 @@ protected: virtual bool match0(AST *, ASTMatcher *); }; +class CPLUSPLUS_EXPORT StaticAssertDeclarationAST: public DeclarationAST +{ +public: + unsigned static_assert_token; + unsigned lparen_token; + ExpressionAST *expression; + unsigned comma_token; + ExpressionAST *string_literal; + unsigned rparen_token; + unsigned semicolon_token; + +public: + StaticAssertDeclarationAST() + : static_assert_token(0) + , lparen_token(0) + , expression(0) + , comma_token(0) + , string_literal(0) + , rparen_token(0) + , semicolon_token(0) + {} + + virtual StaticAssertDeclarationAST *asStaticAssertDeclaration() { return this; } + + virtual unsigned firstToken() const; + virtual unsigned lastToken() const; + + virtual StaticAssertDeclarationAST *clone(MemoryPool *pool) const; + +protected: + virtual void accept0(ASTVisitor *visitor); + virtual bool match0(AST *, ASTMatcher *); +}; + class CPLUSPLUS_EXPORT StringLiteralAST: public ExpressionAST { public: diff --git a/src/libs/3rdparty/cplusplus/ASTClone.cpp b/src/libs/3rdparty/cplusplus/ASTClone.cpp index 6cca878c193..e65be49c38e 100644 --- a/src/libs/3rdparty/cplusplus/ASTClone.cpp +++ b/src/libs/3rdparty/cplusplus/ASTClone.cpp @@ -1142,6 +1142,21 @@ NestedExpressionAST *NestedExpressionAST::clone(MemoryPool *pool) const return ast; } +StaticAssertDeclarationAST *StaticAssertDeclarationAST::clone(MemoryPool *pool) const +{ + StaticAssertDeclarationAST *ast = new (pool) StaticAssertDeclarationAST; + ast->static_assert_token = static_assert_token; + ast->lparen_token = lparen_token; + if (expression) + ast->expression = expression->clone(pool); + ast->comma_token = comma_token; + if (string_literal) + ast->string_literal = string_literal->clone(pool); + ast->rparen_token = rparen_token; + ast->semicolon_token = semicolon_token; + return ast; +} + StringLiteralAST *StringLiteralAST::clone(MemoryPool *pool) const { StringLiteralAST *ast = new (pool) StringLiteralAST; diff --git a/src/libs/3rdparty/cplusplus/ASTMatch0.cpp b/src/libs/3rdparty/cplusplus/ASTMatch0.cpp index 9694be4b4d5..127993ea2a6 100644 --- a/src/libs/3rdparty/cplusplus/ASTMatch0.cpp +++ b/src/libs/3rdparty/cplusplus/ASTMatch0.cpp @@ -800,6 +800,14 @@ bool NestedExpressionAST::match0(AST *pattern, ASTMatcher *matcher) return false; } +bool StaticAssertDeclarationAST::match0(AST *pattern, ASTMatcher *matcher) +{ + if (StaticAssertDeclarationAST *_other = pattern->asStaticAssertDeclaration()) + return matcher->match(this, _other); + + return false; +} + bool StringLiteralAST::match0(AST *pattern, ASTMatcher *matcher) { if (StringLiteralAST *_other = pattern->asStringLiteral()) diff --git a/src/libs/3rdparty/cplusplus/ASTMatcher.cpp b/src/libs/3rdparty/cplusplus/ASTMatcher.cpp index 0f7d7056e02..daafb070b19 100644 --- a/src/libs/3rdparty/cplusplus/ASTMatcher.cpp +++ b/src/libs/3rdparty/cplusplus/ASTMatcher.cpp @@ -1917,6 +1917,34 @@ bool ASTMatcher::match(NestedExpressionAST *node, NestedExpressionAST *pattern) return true; } +bool ASTMatcher::match(StaticAssertDeclarationAST *node, StaticAssertDeclarationAST *pattern) +{ + (void) node; + (void) pattern; + + pattern->static_assert_token = node->static_assert_token; + + pattern->lparen_token = node->lparen_token; + + if (! pattern->expression) + pattern->expression = node->expression; + else if (! AST::match(node->expression, pattern->expression, this)) + return false; + + pattern->comma_token = node->comma_token; + + if (! pattern->string_literal) + pattern->string_literal = node->string_literal; + else if (! AST::match(node->string_literal, pattern->string_literal, this)) + return false; + + pattern->rparen_token = node->rparen_token; + + pattern->semicolon_token = node->semicolon_token; + + return true; +} + bool ASTMatcher::match(StringLiteralAST *node, StringLiteralAST *pattern) { (void) node; diff --git a/src/libs/3rdparty/cplusplus/ASTMatcher.h b/src/libs/3rdparty/cplusplus/ASTMatcher.h index 84ec77c84d4..4c8612ccdc6 100644 --- a/src/libs/3rdparty/cplusplus/ASTMatcher.h +++ b/src/libs/3rdparty/cplusplus/ASTMatcher.h @@ -151,6 +151,7 @@ public: virtual bool match(SimpleNameAST *node, SimpleNameAST *pattern); virtual bool match(SimpleSpecifierAST *node, SimpleSpecifierAST *pattern); virtual bool match(SizeofExpressionAST *node, SizeofExpressionAST *pattern); + virtual bool match(StaticAssertDeclarationAST *node, StaticAssertDeclarationAST *pattern); virtual bool match(StringLiteralAST *node, StringLiteralAST *pattern); virtual bool match(SwitchStatementAST *node, SwitchStatementAST *pattern); virtual bool match(TemplateDeclarationAST *node, TemplateDeclarationAST *pattern); diff --git a/src/libs/3rdparty/cplusplus/ASTPatternBuilder.h b/src/libs/3rdparty/cplusplus/ASTPatternBuilder.h index f9ab027c79b..cbc2ccdaf8d 100644 --- a/src/libs/3rdparty/cplusplus/ASTPatternBuilder.h +++ b/src/libs/3rdparty/cplusplus/ASTPatternBuilder.h @@ -759,6 +759,14 @@ public: return __ast; } + StaticAssertDeclarationAST *StaticAssertDeclaration(ExpressionAST *expression = 0, ExpressionAST *string_literal = 0) + { + StaticAssertDeclarationAST *__ast = new (&pool) StaticAssertDeclarationAST; + __ast->expression = expression; + __ast->string_literal = string_literal; + return __ast; + } + StringLiteralAST *StringLiteral(StringLiteralAST *next = 0) { StringLiteralAST *__ast = new (&pool) StringLiteralAST; diff --git a/src/libs/3rdparty/cplusplus/ASTVisit.cpp b/src/libs/3rdparty/cplusplus/ASTVisit.cpp index af0ef827ca3..2e99c3155a1 100644 --- a/src/libs/3rdparty/cplusplus/ASTVisit.cpp +++ b/src/libs/3rdparty/cplusplus/ASTVisit.cpp @@ -843,6 +843,15 @@ void NestedExpressionAST::accept0(ASTVisitor *visitor) visitor->endVisit(this); } +void StaticAssertDeclarationAST::accept0(ASTVisitor *visitor) +{ + if (visitor->visit(this)) { + accept(expression, visitor); + accept(string_literal, visitor); + } + visitor->endVisit(this); +} + void StringLiteralAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { diff --git a/src/libs/3rdparty/cplusplus/ASTVisitor.h b/src/libs/3rdparty/cplusplus/ASTVisitor.h index 16f7ebbe682..9ca6cf57f6d 100644 --- a/src/libs/3rdparty/cplusplus/ASTVisitor.h +++ b/src/libs/3rdparty/cplusplus/ASTVisitor.h @@ -193,6 +193,7 @@ public: virtual bool visit(SimpleNameAST *) { return true; } virtual bool visit(SimpleSpecifierAST *) { return true; } virtual bool visit(SizeofExpressionAST *) { return true; } + virtual bool visit(StaticAssertDeclarationAST *) { return true; } virtual bool visit(StringLiteralAST *) { return true; } virtual bool visit(SwitchStatementAST *) { return true; } virtual bool visit(TemplateDeclarationAST *) { return true; } @@ -334,6 +335,7 @@ public: virtual void endVisit(SimpleNameAST *) {} virtual void endVisit(SimpleSpecifierAST *) {} virtual void endVisit(SizeofExpressionAST *) {} + virtual void endVisit(StaticAssertDeclarationAST *) {} virtual void endVisit(StringLiteralAST *) {} virtual void endVisit(SwitchStatementAST *) {} virtual void endVisit(TemplateDeclarationAST *) {} diff --git a/src/libs/3rdparty/cplusplus/ASTfwd.h b/src/libs/3rdparty/cplusplus/ASTfwd.h index 7df129cbd82..9858a42ab21 100644 --- a/src/libs/3rdparty/cplusplus/ASTfwd.h +++ b/src/libs/3rdparty/cplusplus/ASTfwd.h @@ -161,6 +161,7 @@ class SimpleSpecifierAST; class SizeofExpressionAST; class SpecifierAST; class StatementAST; +class StaticAssertDeclarationAST; class StringLiteralAST; class SwitchStatementAST; class TemplateDeclarationAST; diff --git a/src/libs/3rdparty/cplusplus/Keywords.cpp b/src/libs/3rdparty/cplusplus/Keywords.cpp index a09e0f05205..49c7e442d0e 100644 --- a/src/libs/3rdparty/cplusplus/Keywords.cpp +++ b/src/libs/3rdparty/cplusplus/Keywords.cpp @@ -1360,7 +1360,7 @@ static inline int classify12(const char *s, bool q, bool) { return T_IDENTIFIER; } -static inline int classify13(const char *s, bool, bool) { +static inline int classify13(const char *s, bool, bool x) { if (s[0] == '_') { if (s[1] == '_') { if (s[2] == 'a') { @@ -1387,6 +1387,32 @@ static inline int classify13(const char *s, bool, bool) { } } } + } else if (x && s[0] == 's') { + if (s[1] == 't') { + if (s[2] == 'a') { + if (s[3] == 't') { + if (s[4] == 'i') { + if (s[5] == 'c') { + if (s[6] == '_') { + if (s[7] == 'a') { + if (s[8] == 's') { + if (s[9] == 's') { + if (s[10] == 'e') { + if (s[11] == 'r') { + if (s[12] == 't') { + return T_STATIC_ASSERT; + } + } + } + } + } + } + } + } + } + } + } + } } return T_IDENTIFIER; } diff --git a/src/libs/3rdparty/cplusplus/Parser.cpp b/src/libs/3rdparty/cplusplus/Parser.cpp index 1ad7996f40d..a8c8be79797 100644 --- a/src/libs/3rdparty/cplusplus/Parser.cpp +++ b/src/libs/3rdparty/cplusplus/Parser.cpp @@ -269,6 +269,8 @@ void Parser::skipUntilDeclaration() // declarations case T_ENUM: case T_NAMESPACE: + case T_INLINE: + case T_STATIC_ASSERT: case T_ASM: case T_EXPORT: case T_AT_CLASS: @@ -621,6 +623,7 @@ bool Parser::parseDeclaration(DeclarationAST *&node) consumeToken(); break; + // C++11 case T_INLINE: if (_cxx0xEnabled && LA(2) == T_NAMESPACE) return parseNamespace(node); @@ -707,6 +710,25 @@ bool Parser::parseLinkageBody(DeclarationAST *&node) return false; } +bool Parser::parseStaticAssertDeclaration(DeclarationAST *&node) +{ + DEBUG_THIS_RULE(); + if (LA() != T_STATIC_ASSERT) + return false; + + StaticAssertDeclarationAST *ast = new (_pool) StaticAssertDeclarationAST; + ast->static_assert_token = consumeToken(); + match(T_LPAREN, &ast->lparen_token); + parseConstantExpression(ast->expression); + match(T_COMMA, &ast->comma_token); + parseStringLiteral(ast->string_literal); + match(T_RPAREN, &ast->rparen_token); + match(T_SEMICOLON, &ast->semicolon_token); + + node = ast; + return true; +} + // ### rename parseNamespaceAliarOrDeclaration? bool Parser::parseNamespace(DeclarationAST *&node) { @@ -2259,6 +2281,10 @@ bool Parser::parseMemberSpecification(DeclarationAST *&node, ClassSpecifierAST * case T_Q_INTERFACES: return parseQtInterfaces(node); + // C++11 + case T_STATIC_ASSERT: + return parseStaticAssertDeclaration(node); + default: return parseSimpleDeclaration(node, declaringClass); } // switch diff --git a/src/libs/3rdparty/cplusplus/Parser.h b/src/libs/3rdparty/cplusplus/Parser.h index de2acfcb547..24a1b3f0128 100644 --- a/src/libs/3rdparty/cplusplus/Parser.h +++ b/src/libs/3rdparty/cplusplus/Parser.h @@ -125,6 +125,7 @@ public: bool parseName(NameAST *&node, bool acceptTemplateId = true); bool parseNestedNameSpecifier(NestedNameSpecifierListAST *&node, bool acceptTemplateId); bool parseNestedNameSpecifierOpt(NestedNameSpecifierListAST *&name, bool acceptTemplateId); + bool parseStaticAssertDeclaration(DeclarationAST *&node); bool parseNamespace(DeclarationAST *&node); bool parseNamespaceAliasDefinition(DeclarationAST *&node); bool parseNewArrayDeclarator(NewArrayDeclaratorListAST *&node); diff --git a/src/libs/3rdparty/cplusplus/Token.cpp b/src/libs/3rdparty/cplusplus/Token.cpp index 4b40707cbfe..1ebb54070a7 100644 --- a/src/libs/3rdparty/cplusplus/Token.cpp +++ b/src/libs/3rdparty/cplusplus/Token.cpp @@ -48,7 +48,7 @@ static const char *token_names[] = { ("mutable"), ("namespace"), ("new"), ("noexcept"), ("nullptr"), ("operator"), ("private"), ("protected"), ("public"), ("register"), ("reinterpret_cast"), - ("return"), ("short"), ("signed"), ("sizeof"), ("static"), + ("return"), ("short"), ("signed"), ("sizeof"), ("static"),("static_assert"), ("static_cast"), ("struct"), ("switch"), ("template"), ("this"), ("throw"), ("true"), ("try"), ("typedef"), ("typeid"), ("typename"), ("union"), ("unsigned"), ("using"), ("virtual"), ("void"), diff --git a/src/libs/3rdparty/cplusplus/Token.h b/src/libs/3rdparty/cplusplus/Token.h index bc98176b6ee..7a2d13264e7 100644 --- a/src/libs/3rdparty/cplusplus/Token.h +++ b/src/libs/3rdparty/cplusplus/Token.h @@ -148,6 +148,7 @@ enum Kind { T_SIGNED, T_SIZEOF, T_STATIC, + T_STATIC_ASSERT, T_STATIC_CAST, T_STRUCT, T_SWITCH, diff --git a/src/libs/cplusplus/FindUsages.cpp b/src/libs/cplusplus/FindUsages.cpp index 6e9c5257635..cbd3e8a27ea 100644 --- a/src/libs/cplusplus/FindUsages.cpp +++ b/src/libs/cplusplus/FindUsages.cpp @@ -1674,6 +1674,12 @@ bool FindUsages::visit(ParameterDeclarationAST *ast) return false; } +bool FindUsages::visit(StaticAssertDeclarationAST *ast) +{ + this->expression(ast->expression); + return false; +} + bool FindUsages::visit(TemplateDeclarationAST *ast) { // unsigned export_token = ast->export_token; diff --git a/src/libs/cplusplus/FindUsages.h b/src/libs/cplusplus/FindUsages.h index e4df7e82243..389c670ff56 100644 --- a/src/libs/cplusplus/FindUsages.h +++ b/src/libs/cplusplus/FindUsages.h @@ -236,6 +236,7 @@ protected: virtual bool visit(NamespaceAST *ast); virtual bool visit(NamespaceAliasDefinitionAST *ast); virtual bool visit(ParameterDeclarationAST *ast); + virtual bool visit(StaticAssertDeclarationAST *ast); virtual bool visit(TemplateDeclarationAST *ast); virtual bool visit(TypenameTypeParameterAST *ast); virtual bool visit(TemplateTypeParameterAST *ast); diff --git a/tests/manual/plain-cplusplus/main.cpp b/tests/manual/plain-cplusplus/main.cpp index dfd51ca5b9f..49d2f8bef70 100644 --- a/tests/manual/plain-cplusplus/main.cpp +++ b/tests/manual/plain-cplusplus/main.cpp @@ -145,6 +145,7 @@ void parse(const char *fileName, const char *source, unsigned size) Control control; TranslationUnit unit(&control, control.stringLiteral(fileName)); unit.setSource(source, size); + unit.setCxxOxEnabled(true); unit.parse(); #if 1 -- GitLab