diff --git a/src/plugins/cppeditor/cppchecksymbols.cpp b/src/plugins/cppeditor/cppchecksymbols.cpp index 635ddb6285c5da6971667e7b6f979d6b435a1f54..f33c6bdf4677e8d2cc56cbd941a93b0144780219 100644 --- a/src/plugins/cppeditor/cppchecksymbols.cpp +++ b/src/plugins/cppeditor/cppchecksymbols.cpp @@ -28,6 +28,8 @@ **************************************************************************/ #include "cppchecksymbols.h" +#include "cpplocalsymbols.h" + #include <cplusplus/Overview.h> #include <Names.h> @@ -45,6 +47,7 @@ #include <qtconcurrent/runextensions.h> using namespace CPlusPlus; +using namespace CppEditor::Internal; namespace { @@ -53,6 +56,7 @@ class CollectTypes: protected SymbolVisitor Document::Ptr _doc; Snapshot _snapshot; QSet<QByteArray> _types; + QSet<QByteArray> _members; QList<ScopedSymbol *> _scopes; QList<NameAST *> _names; bool _mainDocument; @@ -70,6 +74,11 @@ public: return _types; } + const QSet<QByteArray> &members() const + { + return _members; + } + const QList<ScopedSymbol *> &scopes() const { return _scopes; @@ -126,6 +135,18 @@ protected: } } + void addMember(const Name *name) + { + if (! name) { + return; + + } else if (name->isNameId()) { + const Identifier *id = name->identifier(); + _members.insert(QByteArray::fromRawData(id->chars(), id->size())); + + } + } + void addScope(ScopedSymbol *symbol) { if (_mainDocument) @@ -166,6 +187,8 @@ protected: { if (symbol->isTypedef()) addType(symbol->name()); + else if (! symbol->type()->isFunctionType() && symbol->enclosingSymbol()->isClass()) + addMember(symbol->name()); return true; } @@ -267,6 +290,7 @@ CheckSymbols::CheckSymbols(Document::Ptr doc, const LookupContext &context) _fileName = doc->fileName(); CollectTypes collectTypes(doc, context.snapshot()); _potentialTypes = collectTypes.types(); + _potentialMembers = collectTypes.members(); _scopes = collectTypes.scopes(); _flushRequested = false; _flushLine = 0; @@ -351,6 +375,12 @@ bool CheckSymbols::visit(NamedTypeSpecifierAST *) return true; } +bool CheckSymbols::visit(MemberAccessAST *ast) +{ + accept(ast->base_expression); + return false; +} + void CheckSymbols::checkNamespace(NameAST *name) { if (! name) @@ -380,6 +410,28 @@ void CheckSymbols::checkName(NameAST *ast) Scope *scope = findScope(ast); const QList<Symbol *> candidates = _context.lookup(ast->name, scope); addTypeUsage(candidates, ast); + } else if (_potentialMembers.contains(id)) { + Scope *scope = findScope(ast); + const QList<Symbol *> candidates = _context.lookup(ast->name, scope); + addMemberUsage(candidates, ast); + } + } + } +} + +void CheckSymbols::checkMemberName(NameAST *ast) +{ + if (ast && ast->name) { + if (const Identifier *ident = ast->name->identifier()) { + const QByteArray id = QByteArray::fromRawData(ident->chars(), ident->size()); + if (_potentialMembers.contains(id)) { + Scope *scope = findScope(ast); + const QList<Symbol *> candidates = _context.lookup(ast->name, scope); + addMemberUsage(candidates, ast); + } else if (_potentialMembers.contains(id)) { + Scope *scope = findScope(ast); + const QList<Symbol *> candidates = _context.lookup(ast->name, scope); + addMemberUsage(candidates, ast); } } } @@ -473,14 +525,35 @@ void CheckSymbols::endVisit(TemplateDeclarationAST *) _templateDeclarationStack.takeFirst(); } +bool CheckSymbols::visit(FunctionDefinitionAST *ast) +{ + _functionDefinitionStack.append(ast); + const LocalSymbols locals(_doc, ast); + QList<SemanticInfo::Use> uses; + foreach (uses, locals.uses) { + foreach (const SemanticInfo::Use &u, uses) + addTypeUsage(u); + } + + accept(ast->decl_specifier_list); + accept(ast->declarator); + accept(ast->ctor_initializer); + accept(ast->function_body); + + _functionDefinitionStack.removeLast(); + return false; +} + void CheckSymbols::addTypeUsage(const Use &use) { - if (_typeUsages.size() >= 50) { - if (_flushRequested && use.line != _flushLine) - flush(); - else if (! _flushRequested) { - _flushRequested = true; - _flushLine = use.line; + if (_functionDefinitionStack.isEmpty()) { + if (_typeUsages.size() >= 50) { + if (_flushRequested && use.line != _flushLine) + flush(); + else if (! _flushRequested) { + _flushRequested = true; + _flushLine = use.line; + } } } @@ -538,6 +611,36 @@ void CheckSymbols::addTypeUsage(const QList<Symbol *> &candidates, NameAST *ast) } } +void CheckSymbols::addMemberUsage(const QList<Symbol *> &candidates, NameAST *ast) +{ + unsigned startToken = ast->firstToken(); + if (DestructorNameAST *dtor = ast->asDestructorName()) + startToken = dtor->identifier_token; + + const Token &tok = tokenAt(startToken); + if (tok.generated()) + return; + + unsigned line, column; + getTokenStartPosition(startToken, &line, &column); + const unsigned length = tok.length(); + + foreach (Symbol *c, candidates) { + if (! c->isDeclaration()) + continue; + else if (c->isTypedef()) + continue; + else if (c->type()->isFunctionType()) + continue; + else if (! c->enclosingSymbol()->isClass()) + continue; + + const Use use(line, column, length, Use::Field); + addTypeUsage(use); + //qDebug() << "added use" << oo(ast->name) << line << column << length; + } +} + unsigned CheckSymbols::startOfTemplateDeclaration(TemplateDeclarationAST *ast) const { if (ast->declaration) { diff --git a/src/plugins/cppeditor/cppchecksymbols.h b/src/plugins/cppeditor/cppchecksymbols.h index 876132ab3f42adb5357b0799269602cdf36ff0d1..bb996fb691d9cc2ee0f7e5347e3a215e865cac7a 100644 --- a/src/plugins/cppeditor/cppchecksymbols.h +++ b/src/plugins/cppeditor/cppchecksymbols.h @@ -87,6 +87,9 @@ protected: void addTypeUsage(const QList<Symbol *> &candidates, NameAST *ast); void addTypeUsage(const Use &use); + void checkMemberName(NameAST *ast); + void addMemberUsage(const QList<Symbol *> &candidates, NameAST *ast); + virtual bool preVisit(AST *); virtual bool visit(NamespaceAST *); @@ -105,6 +108,9 @@ protected: virtual bool visit(TypenameTypeParameterAST *ast); virtual bool visit(TemplateTypeParameterAST *ast); + virtual bool visit(FunctionDefinitionAST *ast); + virtual bool visit(MemberAccessAST *ast); + unsigned startOfTemplateDeclaration(TemplateDeclarationAST *ast) const; Scope *findScope(AST *ast) const; @@ -116,8 +122,10 @@ private: QString _fileName; QList<Document::DiagnosticMessage> _diagnosticMessages; QSet<QByteArray> _potentialTypes; + QSet<QByteArray> _potentialMembers; QList<ScopedSymbol *> _scopes; QList<TemplateDeclarationAST *> _templateDeclarationStack; + QList<FunctionDefinitionAST *> _functionDefinitionStack; QVector<Use> _typeUsages; bool _flushRequested; unsigned _flushLine; diff --git a/src/plugins/cppeditor/cppeditor.cpp b/src/plugins/cppeditor/cppeditor.cpp index adef080f35ffa6e0f388c33f00abf06010479956..034e17831237f8cac77b40c1d60cab01279b7a0a 100644 --- a/src/plugins/cppeditor/cppeditor.cpp +++ b/src/plugins/cppeditor/cppeditor.cpp @@ -33,6 +33,7 @@ #include "cpphighlighter.h" #include "cppchecksymbols.h" #include "cppquickfix.h" +#include "cpplocalsymbols.h" #include <AST.h> #include <Control.h> @@ -172,240 +173,6 @@ private: CPlusPlus::OverviewModel *m_sourceModel; }; - -class FindLocalUses: protected ASTVisitor -{ - Scope *_functionScope; - Document::Ptr _doc; - -public: - FindLocalUses(Document::Ptr doc) - : ASTVisitor(doc->translationUnit()), _doc(doc), hasD(false), hasQ(false) - { } - - // local and external uses. - SemanticInfo::LocalUseMap localUses; - bool hasD; - bool hasQ; - - void operator()(DeclarationAST *ast) - { - localUses.clear(); - - if (!ast) - return; - - if (FunctionDefinitionAST *def = ast->asFunctionDefinition()) { - if (def->symbol) { - _functionScope = def->symbol->members(); - accept(ast); - } - } else if (ObjCMethodDeclarationAST *decl = ast->asObjCMethodDeclaration()) { - if (decl->method_prototype->symbol) { - _functionScope = decl->method_prototype->symbol->members(); - accept(ast); - } - } - } - -protected: - using ASTVisitor::visit; - - bool findMember(Scope *scope, NameAST *ast, unsigned line, unsigned column) - { - if (! (ast && ast->name)) - return false; - - const Identifier *id = ast->name->identifier(); - - if (scope) { - for (Symbol *member = scope->lookat(id); member; member = member->next()) { - if (member->identifier() != id) - continue; - else if (member->line() < line || (member->line() == line && member->column() <= column)) { - localUses[member].append(SemanticInfo::Use(line, column, id->size())); - return true; - } - } - } - - return false; - } - - void searchUsesInTemplateArguments(NameAST *name) - { - if (! name) - return; - - else if (TemplateIdAST *template_id = name->asTemplateId()) { - for (TemplateArgumentListAST *it = template_id->template_argument_list; it; it = it->next) { - accept(it->value); - } - } - } - - virtual bool visit(SimpleNameAST *ast) - { return findMemberForToken(ast->firstToken(), ast); } - - bool findMemberForToken(unsigned tokenIdx, NameAST *ast) - { - const Token &tok = tokenAt(tokenIdx); - if (tok.generated()) - return false; - - unsigned line, column; - getTokenStartPosition(tokenIdx, &line, &column); - - Scope *scope = _doc->scopeAt(line, column); - - while (scope) { - if (scope->isFunctionScope()) { - Function *fun = scope->owner()->asFunction(); - if (findMember(fun->members(), ast, line, column)) - return false; - else if (findMember(fun->arguments(), ast, line, column)) - return false; - } else if (scope->isObjCMethodScope()) { - ObjCMethod *method = scope->owner()->asObjCMethod(); - if (findMember(method->members(), ast, line, column)) - return false; - else if (findMember(method->arguments(), ast, line, column)) - return false; - } else if (scope->isBlockScope()) { - if (findMember(scope, ast, line, column)) - return false; - } else { - break; - } - - scope = scope->enclosingScope(); - } - - return false; - } - - virtual bool visit(TemplateIdAST *ast) - { - for (TemplateArgumentListAST *arg = ast->template_argument_list; arg; arg = arg->next) - accept(arg->value); - - const Token &tok = tokenAt(ast->identifier_token); - if (tok.generated()) - return false; - - unsigned line, column; - getTokenStartPosition(ast->firstToken(), &line, &column); - - Scope *scope = _doc->scopeAt(line, column); - - while (scope) { - if (scope->isFunctionScope()) { - Function *fun = scope->owner()->asFunction(); - if (findMember(fun->members(), ast, line, column)) - return false; - else if (findMember(fun->arguments(), ast, line, column)) - return false; - } else if (scope->isBlockScope()) { - if (findMember(scope, ast, line, column)) - return false; - } else { - break; - } - - scope = scope->enclosingScope(); - } - - return false; - } - - virtual bool visit(QualifiedNameAST *ast) - { - for (NestedNameSpecifierListAST *it = ast->nested_name_specifier_list; it; it = it->next) - searchUsesInTemplateArguments(it->value->class_or_namespace_name); - - searchUsesInTemplateArguments(ast->unqualified_name); - return false; - } - - virtual bool visit(MemberAccessAST *ast) - { - // accept only the base expression - accept(ast->base_expression); - // and ignore the member name. - return false; - } - - virtual bool visit(ElaboratedTypeSpecifierAST *) - { - // ### template args - return false; - } - - virtual bool visit(ClassSpecifierAST *) - { - // ### template args - return false; - } - - virtual bool visit(EnumSpecifierAST *) - { - // ### template args - return false; - } - - virtual bool visit(UsingDirectiveAST *) - { - return false; - } - - virtual bool visit(UsingAST *ast) - { - accept(ast->name); - return false; - } - - virtual bool visit(QtMemberDeclarationAST *ast) - { - if (tokenKind(ast->q_token) == T_Q_D) - hasD = true; - else - hasQ = true; - - return true; - } - - virtual bool visit(ExpressionOrDeclarationStatementAST *ast) - { - accept(ast->declaration); - return false; - } - - virtual bool visit(FunctionDeclaratorAST *ast) - { - accept(ast->parameters); - - for (SpecifierListAST *it = ast->cv_qualifier_list; it; it = it->next) - accept(it->value); - - accept(ast->exception_specification); - - return false; - } - - virtual bool visit(ObjCMethodPrototypeAST *ast) - { - accept(ast->argument_list); - return false; - } - - virtual bool visit(ObjCMessageArgumentDeclarationAST *ast) - { - accept(ast->param_name); - return false; - } -}; - - class FunctionDefinitionUnderCursor: protected ASTVisitor { unsigned _line; @@ -1131,6 +898,12 @@ void CPPEditor::highlightTypeUsages(int from, int to) Q_ASSERT(!chunks.isEmpty()); QTextBlock b = doc->findBlockByNumber(m_nextHighlightBlockNumber); + QTextCharFormat localUseFormat; + localUseFormat.setForeground(Qt::darkBlue); // ### hardcoded + + QTextCharFormat memberUseFormat; + memberUseFormat.setForeground(Qt::darkRed); // ### hardcoded + QMapIterator<int, QVector<SemanticInfo::Use> > it(chunks); while (b.isValid() && it.hasNext()) { it.next(); @@ -1146,7 +919,24 @@ void CPPEditor::highlightTypeUsages(int from, int to) QList<QTextLayout::FormatRange> formats; foreach (const SemanticInfo::Use &use, it.value()) { QTextLayout::FormatRange formatRange; - formatRange.format = m_typeFormat; + + switch (use.kind) { + case SemanticInfo::Use::Type: + formatRange.format = m_typeFormat; + break; + + case SemanticInfo::Use::Field: + formatRange.format = memberUseFormat; + break; + + case SemanticInfo::Use::Local: + formatRange.format = localUseFormat; + break; + + default: + continue; + } + formatRange.start = use.column - 1; formatRange.length = use.length; formats.append(formatRange); @@ -2187,8 +1977,7 @@ SemanticInfo SemanticHighlighter::semanticInfo(const Source &source) Snapshot snapshot; Document::Ptr doc; QList<Document::DiagnosticMessage> diagnosticMessages; - QList<SemanticInfo::Use> typeUsages, objcKeywords; - LookupContext context; + QList<SemanticInfo::Use> objcKeywords; if (! source.force && revision == source.revision) { m_mutex.lock(); @@ -2207,13 +1996,7 @@ SemanticInfo SemanticHighlighter::semanticInfo(const Source &source) doc->check(); #if 0 - context = LookupContext(doc, snapshot); - if (TranslationUnit *unit = doc->translationUnit()) { - CheckUndefinedSymbols checkUndefinedSymbols(unit, context); - diagnosticMessages = checkUndefinedSymbols(unit->ast()); - typeUsages = checkUndefinedSymbols.typeUsages(); - FindObjCKeywords findObjCKeywords(unit); // ### remove me objcKeywords = findObjCKeywords(); } @@ -2226,14 +2009,13 @@ SemanticInfo SemanticHighlighter::semanticInfo(const Source &source) FunctionDefinitionUnderCursor functionDefinitionUnderCursor(translationUnit); DeclarationAST *currentFunctionDefinition = functionDefinitionUnderCursor(ast, source.line, source.column); - FindLocalUses useTable(doc); - useTable(currentFunctionDefinition); + const LocalSymbols useTable(doc, currentFunctionDefinition); SemanticInfo semanticInfo; semanticInfo.revision = source.revision; semanticInfo.snapshot = snapshot; semanticInfo.doc = doc; - semanticInfo.localUses = useTable.localUses; + semanticInfo.localUses = useTable.uses; semanticInfo.hasQ = useTable.hasQ; semanticInfo.hasD = useTable.hasD; semanticInfo.forced = source.force; diff --git a/src/plugins/cppeditor/cppeditor.pro b/src/plugins/cppeditor/cppeditor.pro index 4b017f64fee12ef67cab8aca3d73cf7d550932ea..274639f4141756b2bc76a6c263f93b6a736f0079 100644 --- a/src/plugins/cppeditor/cppeditor.pro +++ b/src/plugins/cppeditor/cppeditor.pro @@ -20,7 +20,8 @@ HEADERS += cppplugin.h \ cppchecksymbols.h \ cppsemanticinfo.h \ cppoutline.h \ - cppdeclfromdef.h + cppdeclfromdef.h \ + cpplocalsymbols.h SOURCES += cppplugin.cpp \ cppeditor.cpp \ @@ -33,7 +34,8 @@ SOURCES += cppplugin.cpp \ cppchecksymbols.cpp \ cppsemanticinfo.cpp \ cppoutline.cpp \ - cppdeclfromdef.cpp + cppdeclfromdef.cpp \ + cpplocalsymbols.cpp RESOURCES += cppeditor.qrc diff --git a/src/plugins/cppeditor/cpplocalsymbols.cpp b/src/plugins/cppeditor/cpplocalsymbols.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1f5e9f4300b2f5ce0716df4208bd6ca93b7fc74d --- /dev/null +++ b/src/plugins/cppeditor/cpplocalsymbols.cpp @@ -0,0 +1,289 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#include "cpplocalsymbols.h" +#include "cppsemanticinfo.h" + +#include <cplusplus/CppDocument.h> +#include <ASTVisitor.h> +#include <AST.h> +#include <Scope.h> +#include <Symbols.h> +#include <CoreTypes.h> +#include <Names.h> +#include <Literals.h> + +using namespace CPlusPlus; +using namespace CppEditor::Internal; + +namespace { + +class FindLocalSymbols: protected ASTVisitor +{ + Scope *_functionScope; + Document::Ptr _doc; + +public: + FindLocalSymbols(Document::Ptr doc) + : ASTVisitor(doc->translationUnit()), _doc(doc), hasD(false), hasQ(false) + { } + + // local and external uses. + SemanticInfo::LocalUseMap localUses; + bool hasD; + bool hasQ; + + void operator()(DeclarationAST *ast) + { + localUses.clear(); + + if (!ast) + return; + + if (FunctionDefinitionAST *def = ast->asFunctionDefinition()) { + if (def->symbol) { + _functionScope = def->symbol->members(); + accept(ast); + } + } else if (ObjCMethodDeclarationAST *decl = ast->asObjCMethodDeclaration()) { + if (decl->method_prototype->symbol) { + _functionScope = decl->method_prototype->symbol->members(); + accept(ast); + } + } + } + +protected: + using ASTVisitor::visit; + + bool findMember(Scope *scope, NameAST *ast, unsigned line, unsigned column) + { + if (! (ast && ast->name)) + return false; + + const Identifier *id = ast->name->identifier(); + + if (scope) { + for (Symbol *member = scope->lookat(id); member; member = member->next()) { + if (member->identifier() != id) + continue; + else if (member->line() < line || (member->line() == line && member->column() <= column)) { + localUses[member].append(SemanticInfo::Use(line, column, id->size(), SemanticInfo::Use::Local)); + return true; + } + } + } + + return false; + } + + void searchUsesInTemplateArguments(NameAST *name) + { + if (! name) + return; + + else if (TemplateIdAST *template_id = name->asTemplateId()) { + for (TemplateArgumentListAST *it = template_id->template_argument_list; it; it = it->next) { + accept(it->value); + } + } + } + + virtual bool visit(SimpleNameAST *ast) + { return findMemberForToken(ast->firstToken(), ast); } + + bool findMemberForToken(unsigned tokenIdx, NameAST *ast) + { + const Token &tok = tokenAt(tokenIdx); + if (tok.generated()) + return false; + + unsigned line, column; + getTokenStartPosition(tokenIdx, &line, &column); + + Scope *scope = _doc->scopeAt(line, column); + + while (scope) { + if (scope->isFunctionScope()) { + Function *fun = scope->owner()->asFunction(); + if (findMember(fun->members(), ast, line, column)) + return false; + else if (findMember(fun->arguments(), ast, line, column)) + return false; + } else if (scope->isObjCMethodScope()) { + ObjCMethod *method = scope->owner()->asObjCMethod(); + if (findMember(method->members(), ast, line, column)) + return false; + else if (findMember(method->arguments(), ast, line, column)) + return false; + } else if (scope->isBlockScope()) { + if (findMember(scope, ast, line, column)) + return false; + } else { + break; + } + + scope = scope->enclosingScope(); + } + + return false; + } + + virtual bool visit(TemplateIdAST *ast) + { + for (TemplateArgumentListAST *arg = ast->template_argument_list; arg; arg = arg->next) + accept(arg->value); + + const Token &tok = tokenAt(ast->identifier_token); + if (tok.generated()) + return false; + + unsigned line, column; + getTokenStartPosition(ast->firstToken(), &line, &column); + + Scope *scope = _doc->scopeAt(line, column); + + while (scope) { + if (scope->isFunctionScope()) { + Function *fun = scope->owner()->asFunction(); + if (findMember(fun->members(), ast, line, column)) + return false; + else if (findMember(fun->arguments(), ast, line, column)) + return false; + } else if (scope->isBlockScope()) { + if (findMember(scope, ast, line, column)) + return false; + } else { + break; + } + + scope = scope->enclosingScope(); + } + + return false; + } + + virtual bool visit(QualifiedNameAST *ast) + { + for (NestedNameSpecifierListAST *it = ast->nested_name_specifier_list; it; it = it->next) + searchUsesInTemplateArguments(it->value->class_or_namespace_name); + + searchUsesInTemplateArguments(ast->unqualified_name); + return false; + } + + virtual bool visit(MemberAccessAST *ast) + { + // accept only the base expression + accept(ast->base_expression); + // and ignore the member name. + return false; + } + + virtual bool visit(ElaboratedTypeSpecifierAST *) + { + // ### template args + return false; + } + + virtual bool visit(ClassSpecifierAST *) + { + // ### template args + return false; + } + + virtual bool visit(EnumSpecifierAST *) + { + // ### template args + return false; + } + + virtual bool visit(UsingDirectiveAST *) + { + return false; + } + + virtual bool visit(UsingAST *ast) + { + accept(ast->name); + return false; + } + + virtual bool visit(QtMemberDeclarationAST *ast) + { + if (tokenKind(ast->q_token) == T_Q_D) + hasD = true; + else + hasQ = true; + + return true; + } + + virtual bool visit(ExpressionOrDeclarationStatementAST *ast) + { + accept(ast->declaration); + return false; + } + + virtual bool visit(FunctionDeclaratorAST *ast) + { + accept(ast->parameters); + + for (SpecifierListAST *it = ast->cv_qualifier_list; it; it = it->next) + accept(it->value); + + accept(ast->exception_specification); + + return false; + } + + virtual bool visit(ObjCMethodPrototypeAST *ast) + { + accept(ast->argument_list); + return false; + } + + virtual bool visit(ObjCMessageArgumentDeclarationAST *ast) + { + accept(ast->param_name); + return false; + } +}; + +} // end of anonymous namespace + + +LocalSymbols::LocalSymbols(CPlusPlus::Document::Ptr doc, CPlusPlus::DeclarationAST *ast) +{ + FindLocalSymbols FindLocalSymbols(doc); + FindLocalSymbols(ast); + hasD = FindLocalSymbols.hasD; + hasQ = FindLocalSymbols.hasQ; + uses = FindLocalSymbols.localUses; +} diff --git a/src/plugins/cppeditor/cpplocalsymbols.h b/src/plugins/cppeditor/cpplocalsymbols.h new file mode 100644 index 0000000000000000000000000000000000000000..42f3a2fb0a428d1bc2bfcb5b068d240ed0975b16 --- /dev/null +++ b/src/plugins/cppeditor/cpplocalsymbols.h @@ -0,0 +1,56 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#ifndef CPPLOCALSYMBOLS_H +#define CPPLOCALSYMBOLS_H + +#include "cppsemanticinfo.h" +#include <cplusplus/CppDocument.h> +#include <ASTfwd.h> + +namespace CppEditor { +namespace Internal { + +class LocalSymbols +{ + Q_DISABLE_COPY(LocalSymbols) + +public: + LocalSymbols(CPlusPlus::Document::Ptr doc, CPlusPlus::DeclarationAST *ast); + + bool hasD; + bool hasQ; + SemanticInfo::LocalUseMap uses; +}; + +} + +} + +#endif // CPPLOCALSYMBOLS_H diff --git a/src/plugins/cppeditor/cppsemanticinfo.h b/src/plugins/cppeditor/cppsemanticinfo.h index 7f374c8ffd703c3731977cdf787269df36e8829b..3ea662bdbbe3049a054e864bc61aa4729574bf0c 100644 --- a/src/plugins/cppeditor/cppsemanticinfo.h +++ b/src/plugins/cppeditor/cppsemanticinfo.h @@ -46,9 +46,16 @@ public: unsigned line; unsigned column; unsigned length; + unsigned kind; - Use(unsigned line = 0, unsigned column = 0, unsigned length = 0) - : line(line), column(column), length(length) {} + enum { + Type = 0, + Local, + Field + }; + + Use(unsigned line = 0, unsigned column = 0, unsigned length = 0, unsigned kind = Type) + : line(line), column(column), length(length), kind(kind) {} }; typedef QHash<CPlusPlus::Symbol *, QList<Use> > LocalUseMap;