[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: KDE/kdevelop/languages/cpp/cppduchain
From: David Nolden <david.nolden.kde () art-master ! de>
Date: 2008-05-31 19:10:54
Message-ID: 1212261054.064914.12961.nullmailer () svn ! kde ! org
[Download RAW message or body]
SVN commit 814956 by zwabel:
- Also give function bodies a scope identifier, and adjust the tests.
- When searching from within function definitions that have namespaces as part of their scope \
identifiers, also search for the items within those namespaces, as specified in iso c++.
- Add a test to verify.
M +10 -7 contextbuilder.cpp
M +3 -1 contextbuilder.h
M +5 -0 cppduchain.cpp
M +4 -1 cppduchain.h
M +33 -0 cppducontext.h
M +1 -1 dumpchain.cpp
M +37 -5 tests/test_duchain.cpp
M +1 -0 tests/test_duchain.h
--- trunk/KDE/kdevelop/languages/cpp/cppduchain/contextbuilder.cpp #814955:814956
@@ -148,7 +148,7 @@
DUContext* ctx = 0;
if( first && last )
- ctx = openContext(first, last, DUContext::Template, 0); //Open anonymous context for the \
template-parameters + ctx = openContext(first, last, DUContext::Template); //Open anonymous context \
for the template-parameters else
ctx = openContextEmpty(ast, DUContext::Template); //Open an empty context, because there are no \
template-parameters
@@ -462,8 +462,9 @@
{
PushValue<bool> push(m_inFunctionDefinition, (bool)node->function_body);
+ QualifiedIdentifier functionName;
if (m_compilingContexts && node->init_declarator && node->init_declarator->declarator && \
node->init_declarator->declarator->id) {
- QualifiedIdentifier functionName = identifierForName(node->init_declarator->declarator->id);
+ functionName = identifierForName(node->init_declarator->declarator->id);
if (functionName.count() >= 2) {
// This is a class function definition
DUChainReadLocker lock(DUChain::lock());
@@ -483,17 +484,18 @@
}
}
}
-
visitFunctionDeclaration(node);
if (node->constructor_initializers && node->function_body) {
- openContext(node->constructor_initializers, node->function_body, DUContext::Other);
+ openContext(node->constructor_initializers, node->function_body, DUContext::Other); //The \
constructor initializer context addImportedContexts();
}
// Otherwise, the context is created in the function body visit
visit(node->constructor_initializers);
+ m_openingFunctionBody = functionName;
visit(node->function_body);
+ m_openingFunctionBody = QualifiedIdentifier();
if (node->constructor_initializers)
closeContext();
@@ -563,13 +565,13 @@
}
}
-DUContext* ContextBuilder::openContext(AST* fromRange, AST* toRange, DUContext::ContextType type, \
NameAST* identifier) +DUContext* ContextBuilder::openContext(AST* fromRange, AST* toRange, \
DUContext::ContextType type, const KDevelop::QualifiedIdentifier& identifier) {
if (m_compilingContexts) {
#ifdef DEBUG_UPDATE_MATCHING
kDebug() << "opening context with text" << m_editor->tokensToStrings( fromRange->start_token, \
toRange->end_token ); #endif
- DUContext* ret = openContextInternal(m_editor->findRangeForContext(fromRange->start_token, \
toRange->end_token), type, identifier ? identifierForName(identifier) : QualifiedIdentifier()); + \
DUContext* ret = openContextInternal(m_editor->findRangeForContext(fromRange->start_token, \
toRange->end_token), type, identifier); fromRange->ducontext = ret;
return ret;
} else {
@@ -723,7 +725,8 @@
void ContextBuilder::visitCompoundStatement(CompoundStatementAST * node)
{
- openContext(node, DUContext::Other);
+ openContext(node, DUContext::Other, m_openingFunctionBody);
+ m_openingFunctionBody.clear();
addImportedContexts();
--- trunk/KDE/kdevelop/languages/cpp/cppduchain/contextbuilder.h #814955:814956
@@ -190,7 +190,7 @@
KDevelop::DUContext* openContext(AST* range, KDevelop::DUContext::ContextType type, const \
KDevelop::QualifiedIdentifier& identifier); KDevelop::DUContext* openContext(AST* range, \
KDevelop::DUContext::ContextType type, NameAST* identifier = 0);
- KDevelop::DUContext* openContext(AST* fromRange, AST* toRange, KDevelop::DUContext::ContextType type, \
NameAST* identifier = 0); + KDevelop::DUContext* openContext(AST* fromRange, AST* toRange, \
KDevelop::DUContext::ContextType type, const KDevelop::QualifiedIdentifier& identifier = \
KDevelop::QualifiedIdentifier()); //Opens a context of size 0, starting at the given node
KDevelop::DUContext* openContextEmpty(AST* range, KDevelop::DUContext::ContextType type);
@@ -224,6 +224,8 @@
QStack<KDevelop::DUContext*> m_contextStack;
QStack<int> m_nextContextStack;
+ QualifiedIdentifier m_openingFunctionBody; //Identifier of the currently opened function body, or \
empty. +
KDevelop::DUContext* m_lastContext; //Last context that was opened
inline int& nextContextIndex() { return m_nextContextStack.top(); }
--- trunk/KDE/kdevelop/languages/cpp/cppduchain/cppduchain.cpp #814955:814956
@@ -111,6 +111,11 @@
{ //Move context to the top context of type "Other". This is needed because every compound-statement \
creates a new sub-context. context = context->parentContext();
}
+
+ //Since declarations are assigned to the bodies, not to the argument contexts, go to the body context \
to make the step to the function + if(context->type() == DUContext::Function)
+ if(!context->importedChildContexts().isEmpty())
+ context = context->importedChildContexts().first();
///Step 1: Find the function-declaration for the function we are in
Declaration* functionDeclaration = 0;
--- trunk/KDE/kdevelop/languages/cpp/cppduchain/cppduchain.h #814955:814956
@@ -61,7 +61,10 @@
* */
KDEVCPPDUCHAIN_EXPORT QList< QPair<KDevelop::Declaration*, int> > hideOverloadedDeclarations( const \
QList< QPair<KDevelop::Declaration*, int> >& declarations );
- /**Tries determining the local class that the given code-context belongs to.*/
+ /**Tries determining the local class that the given code-context belongs to.
+ *
+ * This works within contexts of type DUContext::Other, as well as in argument contexts of type \
DUContext::Function(also within function definitions). + */
KDEVCPPDUCHAIN_EXPORT KDevelop::Declaration* localClassFromCodeContext(KDevelop::DUContext* context);
/**
--- trunk/KDE/kdevelop/languages/cpp/cppduchain/cppducontext.h #814955:814956
@@ -68,6 +68,7 @@
#include <duchain/namespacealiasdeclaration.h>
#include "typeutils.h"
#include "cpptypes.h"
+#include "cppduchain.h"
#include "templatedeclaration.h"
#include "expressionparser.h"
@@ -569,6 +570,38 @@
m_instantiatedFrom->m_instatiations.insert( this );
}
+ virtual void applyUpwardsAliases(QList<QualifiedIdentifier>& identifiers) const
+ {
+ BaseContext::applyUpwardsAliases(identifiers);
+ ///@see Iso C++ 3.4.1 : Unqualified name lookup:
+ ///We need to make sure that when leaving a function definition, the namespace components are \
searched + QualifiedIdentifier prefix = BaseContext::localScopeIdentifier();
+ if(prefix.count() > 1) {
+ //This must be a function-definition, like void A::B::test() {}
+ KDevelop::Declaration* classDeclaration = \
Cpp::localClassFromCodeContext(const_cast<BaseContext*>((const BaseContext*)this)); + \
if(classDeclaration && classDeclaration->internalContext()) { + //If this is a definition of a \
class member, only add aliases for the namespace elements(The class scope will be + //searched \
using then normal import logic) + prefix = \
classDeclaration->internalContext()->scopeIdentifier(false); + }else{
+ prefix.pop();
+ }
+ prefix.setExplicitlyGlobal(true);
+
+ QList<QualifiedIdentifier> addIdentifiers;
+
+ while(!prefix.isEmpty()) {
+ for(QList<QualifiedIdentifier>::const_iterator it = identifiers.begin(); it != \
identifiers.end(); ++it) { + addIdentifiers.append(prefix + *it);
+ }
+ prefix.pop();
+ }
+
+ if(!addIdentifiers.isEmpty())
+ identifiers = addIdentifiers + identifiers;
+ }
+ }
+
/**
* If this returns nonzero value, this context is a instatiation of some other context, and that \
other context will be returned here.
* */
--- trunk/KDE/kdevelop/languages/cpp/cppduchain/dumpchain.cpp #814955:814956
@@ -186,7 +186,7 @@
//IdentifiedType* idType = dynamic_cast<IdentifiedType*>(dec->abstractType().data());
- kDebug(9007) << QString((indent+1) * 2, ' ') << "Declaration: " << dec->toString() << /*(idType ? \
(" (type-identity: " + idType->identifier().toString() + ")") : QString()) <<*/ " [" << \
dec->qualifiedIdentifier() << "]" << dec << "(internal ctx" << dec->internalContext() << ")" << \
dec->range().textRange() << "," << (dec->isDefinition() ? "defined, " : (dec->definition() ? "" : "no \
definition, ")) << dec->uses().count() << "use(s)."; + kDebug(9007) << QString((indent+1) * 2, ' ') \
<< "Declaration: " << dec->toString() << /*(idType ? (" (type-identity: " + \
idType->identifier().toString() + ")") : QString()) <<*/ " [" << dec->qualifiedIdentifier() << "]" << dec \
<< "(internal ctx" << dec->internalContext() << ")" << dec->range().textRange() << "smart range:" << \
dec->smartRange() << "," << (dec->isDefinition() ? "defined, " : (dec->definition() ? "" : "no \
definition, ")) << dec->uses().count() << "use(s)."; if (dec->definition())
kDebug(9007) << QString((indent+1) * 2 + 1, ' ') << "Definition:" << \
dec->definition()->range().textRange(); QMap<HashedString, QList<SimpleRange> > uses = dec->uses();
--- trunk/KDE/kdevelop/languages/cpp/cppduchain/tests/test_duchain.cpp #814955:814956
@@ -29,6 +29,7 @@
#include "usebuilder.h"
#include <declaration.h>
#include <dumpdotgraph.h>
+#include <typeinfo>
#include <time.h>
#include <set>
#include <algorithm>
@@ -448,7 +449,7 @@
QCOMPARE(main->importedParentContexts().count(), 1);
QCOMPARE(main->childContexts().count(), 2);
QCOMPARE(main->localDeclarations().count(), 0);
- QVERIFY(main->localScopeIdentifier().isEmpty());
+ QCOMPARE(main->localScopeIdentifier(), QualifiedIdentifier("main"));
QCOMPARE(findDeclaration(main, Identifier("i")), noDef);
@@ -827,8 +828,8 @@
DUContext* testCtx = top->childContexts()[2];
QCOMPARE(testCtx->childContexts().count(), 0);
QCOMPARE(testCtx->localDeclarations().count(), 0);
- QCOMPARE(testCtx->localScopeIdentifier(), QualifiedIdentifier());
- QCOMPARE(testCtx->scopeIdentifier(), QualifiedIdentifier());
+ QCOMPARE(testCtx->localScopeIdentifier(), QualifiedIdentifier("test"));
+ QCOMPARE(testCtx->scopeIdentifier(), QualifiedIdentifier("test"));
Declaration* bar2 = top->localDeclarations().first();
QCOMPARE(bar2->identifier(), Identifier("bar"));
@@ -875,6 +876,37 @@
release(top);
}
+void TestDUChain::testSearchAcrossNamespace2()
+{
+ TEST_FILE_PARSE_ONLY
+
+ // 0 1 2 3 4 5 6 7
+ // \
0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012 + \
QByteArray method("namespace A {class B{}; } namespace A { class C{ void member(B);}; } void \
A::C::member(B b) {B c;}"); +
+ DUContext* top = parse(method, DumpNone);
+
+ DUChainWriteLocker lock(DUChain::lock());
+
+ QVERIFY(!top->parentContext());
+ QCOMPARE(top->childContexts().count(), 4);
+ QCOMPARE(top->childContexts()[0]->localDeclarations().count(), 1);
+ QCOMPARE(top->childContexts()[1]->localDeclarations().count(), 1);
+ QCOMPARE(top->childContexts()[2]->localDeclarations().count(), 1);
+ QCOMPARE(top->childContexts()[2]->type(), DUContext::Function);
+ QCOMPARE(top->childContexts()[2]->localDeclarations().count(), 1);
+ QCOMPARE(top->childContexts()[2]->localScopeIdentifier(), QualifiedIdentifier("A::C::member"));
+ QVERIFY(top->childContexts()[2]->localDeclarations()[0]->abstractType()); //B should be found from \
that position + QVERIFY(!dynamic_cast<DelayedType*>(top->childContexts()[2]->localDeclarations()[0]->abstractType().data()));
+ QCOMPARE(top->childContexts()[3]->type(), DUContext::Other);
+ QCOMPARE(top->childContexts()[3]->localDeclarations().count(), 1);
+ QVERIFY(top->childContexts()[3]->localDeclarations()[0]->abstractType()); //B should be found from \
that position + QCOMPARE(top->childContexts()[3]->localScopeIdentifier(), \
QualifiedIdentifier("A::C::member")); + \
QVERIFY(!dynamic_cast<DelayedType*>(top->childContexts()[3]->localDeclarations()[0]->abstractType().data()));
+
+ release(top);
+}
+
void TestDUChain::testDeclareUsingNamespace2()
{
TEST_FILE_PARSE_ONLY
@@ -978,8 +1010,8 @@
QCOMPARE(testCtx->importedParentContexts().count(), 1);
QCOMPARE(testCtx->childContexts().count(), 0);
QCOMPARE(testCtx->localDeclarations().count(), 0);
- QCOMPARE(testCtx->localScopeIdentifier(), QualifiedIdentifier());
- QCOMPARE(testCtx->scopeIdentifier(), QualifiedIdentifier());
+ QCOMPARE(testCtx->localScopeIdentifier(), QualifiedIdentifier("test"));
+ QCOMPARE(testCtx->scopeIdentifier(), QualifiedIdentifier("test"));
release(top);
}
--- trunk/KDE/kdevelop/languages/cpp/cppduchain/tests/test_duchain.h #814955:814956
@@ -71,6 +71,7 @@
void testDeclareUsingNamespace();
void testDeclareUsingNamespace2();
void testSearchAcrossNamespace();
+ void testSearchAcrossNamespace2();
void testTemplateEnums();
void testIntegralTemplates();
void testTypedef();
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic