diff --git a/src/libs/3rdparty/cplusplus/AST.cpp b/src/libs/3rdparty/cplusplus/AST.cpp index 445afe812314ebbc54ac452bd92e975ce3f9764b..1b557d2872e54385c06dae1dd2e788a2885c2993 100644 --- a/src/libs/3rdparty/cplusplus/AST.cpp +++ b/src/libs/3rdparty/cplusplus/AST.cpp @@ -4343,3 +4343,61 @@ unsigned DecltypeSpecifierAST::lastToken() const return 1; } +/** \generated */ +unsigned RangeBasedForStatementAST::firstToken() const +{ + if (for_token) + return for_token; + if (lparen_token) + return lparen_token; + if (type_specifier_list) + if (unsigned candidate = type_specifier_list->firstToken()) + return candidate; + if (declarator) + if (unsigned candidate = declarator->firstToken()) + return candidate; + if (initializer) + if (unsigned candidate = initializer->firstToken()) + return candidate; + if (colon_token) + return colon_token; + if (expression) + if (unsigned candidate = expression->firstToken()) + return candidate; + if (rparen_token) + return rparen_token; + if (statement) + if (unsigned candidate = statement->firstToken()) + return candidate; + return 0; +} + +/** \generated */ +unsigned RangeBasedForStatementAST::lastToken() const +{ + if (statement) + if (unsigned candidate = statement->lastToken()) + return candidate; + if (rparen_token) + return rparen_token + 1; + if (expression) + if (unsigned candidate = expression->lastToken()) + return candidate; + if (colon_token) + return colon_token + 1; + if (initializer) + if (unsigned candidate = initializer->lastToken()) + return candidate; + if (declarator) + if (unsigned candidate = declarator->lastToken()) + return candidate; + if (type_specifier_list) + if (unsigned candidate = type_specifier_list->lastToken()) + return candidate; + if (lparen_token) + return lparen_token + 1; + if (for_token) + return for_token + 1; + return 1; +} + diff --git a/src/libs/3rdparty/cplusplus/AST.h b/src/libs/3rdparty/cplusplus/AST.h index f02cce10da40807523ce127e285d3903353c5b43..9dbc2b0320eeaa7fad55c403a245ed84d0cac9d9 100644 --- a/src/libs/3rdparty/cplusplus/AST.h +++ b/src/libs/3rdparty/cplusplus/AST.h @@ -247,6 +247,7 @@ public: virtual QtPropertyDeclarationAST *asQtPropertyDeclaration() { return 0; } virtual QtPropertyDeclarationItemAST *asQtPropertyDeclarationItem() { return 0; } virtual QualifiedNameAST *asQualifiedName() { return 0; } + virtual RangeBasedForStatementAST *asRangeBasedForStatement() { return 0; } virtual ReferenceAST *asReference() { return 0; } virtual ReturnStatementAST *asReturnStatement() { return 0; } virtual SimpleDeclarationAST *asSimpleDeclaration() { return 0; } @@ -1906,6 +1907,50 @@ protected: virtual bool match0(AST *, ASTMatcher *); }; +class CPLUSPLUS_EXPORT RangeBasedForStatementAST : public StatementAST +{ +public: + unsigned for_token; + unsigned lparen_token; + // declaration + SpecifierListAST *type_specifier_list; + DeclaratorAST *declarator; + // or an expression + ExpressionAST *initializer; + unsigned colon_token; + ExpressionAST *expression; + unsigned rparen_token; + StatementAST *statement; + +public: // annotations + Block *symbol; + +public: + RangeBasedForStatementAST() + : for_token(0) + , lparen_token(0) + , type_specifier_list(0) + , declarator(0) + , initializer(0) + , colon_token(0) + , expression(0) + , rparen_token(0) + , statement(0) + , symbol(0) + {} + + virtual RangeBasedForStatementAST *asRangeBasedForStatement() { return this; } + + virtual unsigned firstToken() const; + virtual unsigned lastToken() const; + + virtual RangeBasedForStatementAST *clone(MemoryPool *pool) const; + +protected: + virtual void accept0(ASTVisitor *visitor); + virtual bool match0(AST *, ASTMatcher *); +}; + class CPLUSPLUS_EXPORT ForStatementAST: public StatementAST { public: diff --git a/src/libs/3rdparty/cplusplus/ASTClone.cpp b/src/libs/3rdparty/cplusplus/ASTClone.cpp index 6d77e7e3dab311fcfae8fa25d922412506420021..2478f4f7f29d0eb6d7991e627972e533dd9e98df 100644 --- a/src/libs/3rdparty/cplusplus/ASTClone.cpp +++ b/src/libs/3rdparty/cplusplus/ASTClone.cpp @@ -669,6 +669,27 @@ ForeachStatementAST *ForeachStatementAST::clone(MemoryPool *pool) const return ast; } +RangeBasedForStatementAST *RangeBasedForStatementAST::clone(MemoryPool *pool) const +{ + RangeBasedForStatementAST *ast = new (pool) RangeBasedForStatementAST; + ast->for_token = for_token; + ast->lparen_token = lparen_token; + for (SpecifierListAST *iter = type_specifier_list, **ast_iter = &ast->type_specifier_list; + iter; iter = iter->next, ast_iter = &(*ast_iter)->next) + *ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : 0); + if (declarator) + ast->declarator = declarator->clone(pool); + if (initializer) + ast->initializer = initializer->clone(pool); + ast->colon_token = colon_token; + if (expression) + ast->expression = expression->clone(pool); + ast->rparen_token = rparen_token; + if (statement) + ast->statement = statement->clone(pool); + return ast; +} + ForStatementAST *ForStatementAST::clone(MemoryPool *pool) const { ForStatementAST *ast = new (pool) ForStatementAST; diff --git a/src/libs/3rdparty/cplusplus/ASTMatch0.cpp b/src/libs/3rdparty/cplusplus/ASTMatch0.cpp index e94a5eec60adcb9be98ac2d38ab1de608c8b3d8f..81e74316b6b6793631ce474a01d0a88edda636f5 100644 --- a/src/libs/3rdparty/cplusplus/ASTMatch0.cpp +++ b/src/libs/3rdparty/cplusplus/ASTMatch0.cpp @@ -456,6 +456,14 @@ bool ForeachStatementAST::match0(AST *pattern, ASTMatcher *matcher) return false; } +bool RangeBasedForStatementAST::match0(AST *pattern, ASTMatcher *matcher) +{ + if (RangeBasedForStatementAST *_other = pattern->asRangeBasedForStatement()) + return matcher->match(this, _other); + + return false; +} + bool ForStatementAST::match0(AST *pattern, ASTMatcher *matcher) { if (ForStatementAST *_other = pattern->asForStatement()) diff --git a/src/libs/3rdparty/cplusplus/ASTMatcher.cpp b/src/libs/3rdparty/cplusplus/ASTMatcher.cpp index 15595ac1700a160302d7cdf3de0a6183f4c5ac5f..a7b19ba99fbf7aa63b751c51bfcce072241c6d32 100644 --- a/src/libs/3rdparty/cplusplus/ASTMatcher.cpp +++ b/src/libs/3rdparty/cplusplus/ASTMatcher.cpp @@ -1131,6 +1131,47 @@ bool ASTMatcher::match(ForeachStatementAST *node, ForeachStatementAST *pattern) return true; } +bool ASTMatcher::match(RangeBasedForStatementAST *node, RangeBasedForStatementAST *pattern) +{ + (void) node; + (void) pattern; + + pattern->for_token = node->for_token; + + pattern->lparen_token = node->lparen_token; + + if (! pattern->type_specifier_list) + pattern->type_specifier_list = node->type_specifier_list; + else if (! AST::match(node->type_specifier_list, pattern->type_specifier_list, this)) + return false; + + if (! pattern->declarator) + pattern->declarator = node->declarator; + else if (! AST::match(node->declarator, pattern->declarator, this)) + return false; + + if (! pattern->initializer) + pattern->initializer = node->initializer; + else if (! AST::match(node->initializer, pattern->initializer, this)) + return false; + + pattern->colon_token = node->colon_token; + + if (! pattern->expression) + pattern->expression = node->expression; + else if (! AST::match(node->expression, pattern->expression, this)) + return false; + + pattern->rparen_token = node->rparen_token; + + if (! pattern->statement) + pattern->statement = node->statement; + else if (! AST::match(node->statement, pattern->statement, this)) + return false; + + return true; +} + bool ASTMatcher::match(ForStatementAST *node, ForStatementAST *pattern) { (void) node; diff --git a/src/libs/3rdparty/cplusplus/ASTMatcher.h b/src/libs/3rdparty/cplusplus/ASTMatcher.h index 1e32dababedec3a2c2d1d4ce54f9540d58e1ed39..202a5777414970e9db0ffee9926514bf0d3f5c0a 100644 --- a/src/libs/3rdparty/cplusplus/ASTMatcher.h +++ b/src/libs/3rdparty/cplusplus/ASTMatcher.h @@ -146,6 +146,7 @@ public: virtual bool match(QtPropertyDeclarationAST *node, QtPropertyDeclarationAST *pattern); virtual bool match(QtPropertyDeclarationItemAST *node, QtPropertyDeclarationItemAST *pattern); virtual bool match(QualifiedNameAST *node, QualifiedNameAST *pattern); + virtual bool match(RangeBasedForStatementAST *node, RangeBasedForStatementAST *pattern); virtual bool match(ReferenceAST *node, ReferenceAST *pattern); virtual bool match(ReturnStatementAST *node, ReturnStatementAST *pattern); virtual bool match(SimpleDeclarationAST *node, SimpleDeclarationAST *pattern); diff --git a/src/libs/3rdparty/cplusplus/ASTPatternBuilder.h b/src/libs/3rdparty/cplusplus/ASTPatternBuilder.h index dce4608cde7562631a73ac6e440535e1d4d985fa..e318a32f07850c25d6845fd19d1003cb8bbb2c45 100644 --- a/src/libs/3rdparty/cplusplus/ASTPatternBuilder.h +++ b/src/libs/3rdparty/cplusplus/ASTPatternBuilder.h @@ -447,6 +447,17 @@ public: return __ast; } + RangeBasedForStatementAST *RangeBasedForStatement(SpecifierListAST *type_specifier_list = 0, DeclaratorAST *declarator = 0, ExpressionAST *initializer = 0, ExpressionAST *expression = 0, StatementAST *statement = 0) + { + RangeBasedForStatementAST *__ast = new (&pool) RangeBasedForStatementAST; + __ast->type_specifier_list = type_specifier_list; + __ast->declarator = declarator; + __ast->initializer = initializer; + __ast->expression = expression; + __ast->statement = statement; + return __ast; + } + ForStatementAST *ForStatement(StatementAST *initializer = 0, ExpressionAST *condition = 0, ExpressionAST *expression = 0, StatementAST *statement = 0) { ForStatementAST *__ast = new (&pool) ForStatementAST; diff --git a/src/libs/3rdparty/cplusplus/ASTVisit.cpp b/src/libs/3rdparty/cplusplus/ASTVisit.cpp index 5d7ab2511de46280f2530cd085d7ad12b7385d2d..41cf0cf75594e08848f4682578cf3153b78a39dd 100644 --- a/src/libs/3rdparty/cplusplus/ASTVisit.cpp +++ b/src/libs/3rdparty/cplusplus/ASTVisit.cpp @@ -488,6 +488,18 @@ void ForeachStatementAST::accept0(ASTVisitor *visitor) visitor->endVisit(this); } +void RangeBasedForStatementAST::accept0(ASTVisitor *visitor) +{ + if (visitor->visit(this)) { + accept(type_specifier_list, visitor); + accept(declarator, visitor); + accept(initializer, visitor); + accept(expression, visitor); + accept(statement, visitor); + } + visitor->endVisit(this); +} + void ForStatementAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { diff --git a/src/libs/3rdparty/cplusplus/ASTVisitor.cpp b/src/libs/3rdparty/cplusplus/ASTVisitor.cpp index 63127783af47cf30f8b40ecf002b1a4e2b2b3e61..5aa1f2d52ff57f69d7f7433ed2294f3efd6d7710 100644 --- a/src/libs/3rdparty/cplusplus/ASTVisitor.cpp +++ b/src/libs/3rdparty/cplusplus/ASTVisitor.cpp @@ -90,5 +90,3 @@ void ASTVisitor::getTokenStartPosition(unsigned index, unsigned *line, unsigned void ASTVisitor::getTokenEndPosition(unsigned index, unsigned *line, unsigned *column) const { getPosition(tokenAt(index).end(), line, column); } - - diff --git a/src/libs/3rdparty/cplusplus/ASTVisitor.h b/src/libs/3rdparty/cplusplus/ASTVisitor.h index 599634090c493d7a9dbac9b9f1140d505c26bba6..eab93a20bba3a45c34d58817f8643277627fb32c 100644 --- a/src/libs/3rdparty/cplusplus/ASTVisitor.h +++ b/src/libs/3rdparty/cplusplus/ASTVisitor.h @@ -188,6 +188,7 @@ public: virtual bool visit(QtPropertyDeclarationAST *) { return true; } virtual bool visit(QtPropertyDeclarationItemAST *) { return true; } virtual bool visit(QualifiedNameAST *) { return true; } + virtual bool visit(RangeBasedForStatementAST *) { return true; } virtual bool visit(ReferenceAST *) { return true; } virtual bool visit(ReturnStatementAST *) { return true; } virtual bool visit(SimpleDeclarationAST *) { return true; } @@ -331,6 +332,7 @@ public: virtual void endVisit(QtPropertyDeclarationAST *) {} virtual void endVisit(QtPropertyDeclarationItemAST *) {} virtual void endVisit(QualifiedNameAST *) {} + virtual void endVisit(RangeBasedForStatementAST *) {} virtual void endVisit(ReferenceAST *) {} virtual void endVisit(ReturnStatementAST *) {} virtual void endVisit(SimpleDeclarationAST *) {} diff --git a/src/libs/3rdparty/cplusplus/ASTfwd.h b/src/libs/3rdparty/cplusplus/ASTfwd.h index b2036c0672c90fb48f92a6c7082b2bf791347b81..f429fe7101136ac1ed084c63e72f5dcf5809904c 100644 --- a/src/libs/3rdparty/cplusplus/ASTfwd.h +++ b/src/libs/3rdparty/cplusplus/ASTfwd.h @@ -154,6 +154,7 @@ class QtPrivateSlotAST; class QtPropertyDeclarationAST; class QtPropertyDeclarationItemAST; class QualifiedNameAST; +class RangeBasedForStatementAST; class ReferenceAST; class ReturnStatementAST; class SimpleDeclarationAST; diff --git a/src/libs/3rdparty/cplusplus/Bind.cpp b/src/libs/3rdparty/cplusplus/Bind.cpp index 1d33812d0ee3de4f15abd7b19cd8c5ababdbe4fc..5f37dafc83b1897c347921a63b9d79a50bff903a 100644 --- a/src/libs/3rdparty/cplusplus/Bind.cpp +++ b/src/libs/3rdparty/cplusplus/Bind.cpp @@ -1282,6 +1282,56 @@ bool Bind::visit(ForeachStatementAST *ast) return false; } +bool Bind::visit(RangeBasedForStatementAST *ast) +{ + Block *block = control()->newBlock(ast->firstToken()); + const unsigned startScopeToken = ast->lparen_token ? ast->lparen_token : ast->firstToken(); + block->setStartOffset(tokenAt(startScopeToken).end()); + block->setEndOffset(tokenAt(ast->lastToken()).begin()); + _scope->addMember(block); + ast->symbol = block; + + Scope *previousScope = switchScope(block); + + FullySpecifiedType type; + for (SpecifierListAST *it = ast->type_specifier_list; it; it = it->next) { + type = this->specifier(it->value, type); + } + DeclaratorIdAST *declaratorId = 0; + type = this->declarator(ast->declarator, type, &declaratorId); + const StringLiteral *initializer = 0; + if (type.isAuto() && translationUnit()->cxx0xEnabled()) { + ExpressionTy exprType = this->expression(ast->expression); + + ArrayType* arrayType = 0; + arrayType = exprType->asArrayType(); + + if (arrayType != 0) + type = arrayType->elementType(); + else if (ast->expression != 0) { + unsigned startOfExpression = ast->expression->firstToken(); + unsigned endOfExpression = ast->expression->lastToken(); + const StringLiteral *sl = asStringLiteral(startOfExpression, endOfExpression); + const std::string buff = std::string("*") + sl->chars() + ".begin()"; + initializer = control()->stringLiteral(buff.c_str(), buff.size()); + } + } + + if (declaratorId && declaratorId->name) { + unsigned sourceLocation = location(declaratorId->name, ast->firstToken()); + Declaration *decl = control()->newDeclaration(sourceLocation, declaratorId->name->name); + decl->setType(type); + decl->setInitializer(initializer); + block->addMember(decl); + } + + /*ExpressionTy initializer =*/ this->expression(ast->initializer); + /*ExpressionTy expression =*/ this->expression(ast->expression); + this->statement(ast->statement); + (void) switchScope(previousScope); + return false; +} + bool Bind::visit(ForStatementAST *ast) { Block *block = control()->newBlock(ast->firstToken()); diff --git a/src/libs/3rdparty/cplusplus/Bind.h b/src/libs/3rdparty/cplusplus/Bind.h index 66d8ed2a0dbb5a06856c4694ee67fc701902d7da..d1fff79ea50e10943d21bac9ba922b611e719a48 100644 --- a/src/libs/3rdparty/cplusplus/Bind.h +++ b/src/libs/3rdparty/cplusplus/Bind.h @@ -152,6 +152,7 @@ protected: virtual bool visit(ExpressionOrDeclarationStatementAST *ast); virtual bool visit(ExpressionStatementAST *ast); virtual bool visit(ForeachStatementAST *ast); + virtual bool visit(RangeBasedForStatementAST *ast); virtual bool visit(ForStatementAST *ast); virtual bool visit(IfStatementAST *ast); virtual bool visit(LabeledStatementAST *ast); diff --git a/src/libs/3rdparty/cplusplus/Parser.cpp b/src/libs/3rdparty/cplusplus/Parser.cpp index cf459dbffbbea0ac039bf1b8ae69866e959be986..8d08e39044841a0e994ab1c695bc632c7fa684e6 100644 --- a/src/libs/3rdparty/cplusplus/Parser.cpp +++ b/src/libs/3rdparty/cplusplus/Parser.cpp @@ -3230,6 +3230,32 @@ bool Parser::parseForStatement(StatementAST *&node) rewind(startOfTypeSpecifier); } + if (cxx0xEnabled()) { + RangeBasedForStatementAST *ast = new (_pool) RangeBasedForStatementAST; + ast->for_token = for_token; + ast->lparen_token = lparen_token; + + if (parseTypeSpecifier(ast->type_specifier_list)) + parseDeclarator(ast->declarator, ast->type_specifier_list); + + if ((ast->type_specifier_list || ast->declarator) && LA() == T_COLON) { + ast->colon_token = consumeToken(); + blockErrors(blocked); + + parseExpression(ast->expression); + match(T_RPAREN, &ast->rparen_token); + parseStatement(ast->statement); + + // We need both type specifier and declarator for C++11 range-based for + if (!ast->type_specifier_list || !ast->declarator) + error(for_token, "expected declaration with type specifier"); + + node = ast; + return true; + } + rewind(startOfTypeSpecifier); + } + blockErrors(blocked); // Normal C/C++ for-statement parsing @@ -6108,4 +6134,3 @@ void Parser::fatal(unsigned index, const char *format, ...) va_end(ap); va_end(args); } - diff --git a/src/libs/cplusplus/FindUsages.cpp b/src/libs/cplusplus/FindUsages.cpp index 27d02b2b677c548124ce6860f6264d44c201629f..cd0d93bbaf6b47071cdab4a28b8c828ba9ac5f3a 100644 --- a/src/libs/cplusplus/FindUsages.cpp +++ b/src/libs/cplusplus/FindUsages.cpp @@ -1050,6 +1050,23 @@ bool FindUsages::visit(ForeachStatementAST *ast) return false; } +bool FindUsages::visit(RangeBasedForStatementAST *ast) +{ + Scope *previousScope = switchScope(ast->symbol); + for (SpecifierListAST *it = ast->type_specifier_list; it; it = it->next) { + this->specifier(it->value); + } + this->declarator(ast->declarator); + this->expression(ast->initializer); + // unsigned comma_token = ast->comma_token; + this->expression(ast->expression); + // unsigned rparen_token = ast->rparen_token; + this->statement(ast->statement); + // Block *symbol = ast->symbol; + (void) switchScope(previousScope); + return false; +} + bool FindUsages::visit(ForStatementAST *ast) { // unsigned for_token = ast->for_token; @@ -2215,5 +2232,3 @@ bool FindUsages::visit(ArrayDeclaratorAST *ast) // unsigned rbracket_token = ast->rbracket_token; return false; } - - diff --git a/src/libs/cplusplus/FindUsages.h b/src/libs/cplusplus/FindUsages.h index cdc4b8e7e5daf19710a44186759a5922679c6641..630abe189a324bc6cc0a39a329d39c781f45023c 100644 --- a/src/libs/cplusplus/FindUsages.h +++ b/src/libs/cplusplus/FindUsages.h @@ -171,6 +171,7 @@ protected: virtual bool visit(ExpressionOrDeclarationStatementAST *ast); virtual bool visit(ExpressionStatementAST *ast); virtual bool visit(ForeachStatementAST *ast); + virtual bool visit(RangeBasedForStatementAST *ast); virtual bool visit(ForStatementAST *ast); virtual bool visit(IfStatementAST *ast); virtual bool visit(LabeledStatementAST *ast); diff --git a/src/libs/cplusplus/findcdbbreakpoint.cpp b/src/libs/cplusplus/findcdbbreakpoint.cpp index edfc34be35048162427e4d585db3d6c69cc90b7e..06ef4ae730b71164d27df9f6cca4efb8f9c0e457 100644 --- a/src/libs/cplusplus/findcdbbreakpoint.cpp +++ b/src/libs/cplusplus/findcdbbreakpoint.cpp @@ -144,6 +144,15 @@ bool FindCdbBreakpoint::visit(ForeachStatementAST *ast) return false; } +bool FindCdbBreakpoint::visit(RangeBasedForStatementAST *ast) +{ + if (m_initialLine <= endLine(ast->rparen_token)) + foundLine(ast->rparen_token); + + accept(ast->statement); + return false; +} + bool FindCdbBreakpoint::visit(ForStatementAST *ast) { if (m_initialLine <= endLine(ast->rparen_token)) diff --git a/src/libs/cplusplus/findcdbbreakpoint.h b/src/libs/cplusplus/findcdbbreakpoint.h index eceba4e1631535fb8fe609fadb54e25aae654f99..9894b339cb0f446749826c5c09fa6d595c20defa 100644 --- a/src/libs/cplusplus/findcdbbreakpoint.h +++ b/src/libs/cplusplus/findcdbbreakpoint.h @@ -78,6 +78,7 @@ protected: bool visit(DoStatementAST *ast); bool visit(ExpressionStatementAST *ast); bool visit(ForeachStatementAST *ast); + bool visit(RangeBasedForStatementAST *ast); bool visit(ForStatementAST *ast); bool visit(IfStatementAST *ast); bool visit(LabeledStatementAST *ast); diff --git a/src/plugins/cppeditor/cppinsertdecldef.cpp b/src/plugins/cppeditor/cppinsertdecldef.cpp index 827e8ad5eebd3ea64c867fb192a7c381ebd3ec52..47e4e28a000c9f5bdeadb6617898c00e57cd44e1 100644 --- a/src/plugins/cppeditor/cppinsertdecldef.cpp +++ b/src/plugins/cppeditor/cppinsertdecldef.cpp @@ -639,6 +639,12 @@ public: return false; } + bool visit(RangeBasedForStatementAST *stmt) + { + statement(stmt->statement); + return false; + } + bool visit(ForStatementAST *stmt) { statement(stmt->initializer); diff --git a/src/plugins/cpptools/cppchecksymbols.cpp b/src/plugins/cpptools/cppchecksymbols.cpp index 2a3c9d2289a7808221c73c6f5781376034b5ee22..fc83c054e0ba2afc39c6e031e32b407b02df33c5 100644 --- a/src/plugins/cpptools/cppchecksymbols.cpp +++ b/src/plugins/cpptools/cppchecksymbols.cpp @@ -407,6 +407,10 @@ Scope *CheckSymbols::enclosingScope() const if (foreachStmt->symbol) return foreachStmt->symbol; + } else if (RangeBasedForStatementAST *rangeBasedForStmt = ast->asRangeBasedForStatement()) { + if (rangeBasedForStmt->symbol) + return rangeBasedForStmt->symbol; + } else if (SwitchStatementAST *switchStmt = ast->asSwitchStatement()) { if (switchStmt->symbol) return switchStmt->symbol; diff --git a/src/plugins/cpptools/cpplocalsymbols.cpp b/src/plugins/cpptools/cpplocalsymbols.cpp index fc4933ef171112af6247bbc3290eb335d6c5ca8b..0b62d58c25ba1fbc2621fdf8a142556c4e5f0a97 100644 --- a/src/plugins/cpptools/cpplocalsymbols.cpp +++ b/src/plugins/cpptools/cpplocalsymbols.cpp @@ -253,6 +253,19 @@ protected: _scopeStack.removeLast(); } + virtual bool visit(RangeBasedForStatementAST *ast) + { + if (ast->symbol) + enterScope(ast->symbol); + return true; + } + + virtual void endVisit(RangeBasedForStatementAST *ast) + { + if (ast->symbol) + _scopeStack.removeLast(); + } + virtual bool visit(SwitchStatementAST *ast) { if (ast->symbol)