Commit 3c51faa2 authored by Bernd Buschinski's avatar Bernd Buschinski

FunctionDefinition: only look for (new/other) function definition if we don't have one

Summary:
FunctionDefinition::definition always looks for FunctionDefinition based on the DeclarationId, but we don't need to do that if we already have a FunctionDefinition.
This could cause problems if we have multiple (same) definitions.

Test Plan:
- create a small cmake (or whatever) project with 3 targets
-- util1.c / util2.c / util3.c (same content):

```
#include <stdio.h>
#include <stdlib.h>

void configure()
{
    printf("do stuff in %s\n", __FILE__);
}

int main(int argc, char *argv[])
{
    configure();
    puts("Hello, UTIL!");
    exit(EXIT_SUCCESS);
}
```

-- CMakeLists.txt:
```
add_executable(util1 util1.c)
add_executable(util2 util2.c)
add_executable(util3 util3.c)
```

- open util1.c
- open the outline and select "configure"
- EXPECTED: it should open the configure in util1.c (or the currently opened file)
- repeat with util2 and util3
- ACTUAL: only one of them works, the other two point to the wrong file.

Reviewers: #kdevelop, mwolff

Reviewed By: #kdevelop, mwolff

Subscribers: mwolff, kdevelop-devel

Tags: #kdevelop

Differential Revision: https://phabricator.kde.org/D16356
parent c3c30113
......@@ -85,6 +85,10 @@ FunctionDefinition* FunctionDefinition::definition(const Declaration* decl)
return nullptr;
}
if (decl->isFunctionDeclaration() && decl->isDefinition()) {
return const_cast<FunctionDefinition *>(static_cast<const FunctionDefinition *> (decl));
}
const KDevVarLengthArray<IndexedDeclaration> allDefinitions = DUChain::definitions()->definitions(decl->id());
for (const IndexedDeclaration decl : allDefinitions) {
if(decl.data()) ///@todo Find better ways of deciding which definition to use
......
......@@ -2086,3 +2086,45 @@ void TestDUChain::testHasInclude()
}
}
}
void TestDUChain::testSameFunctionDefinition()
{
QString source(QStringLiteral(R"(
#include <stdio.h>
#include <stdlib.h>
void configure()
{
printf("do stuff\n");
}
)"));
QTemporaryDir dir;
auto project = new TestProject(Path(dir.path()), this);
m_projectController->addProject(project);
TestFile file1(source, QStringLiteral("c"), project);
TestFile file2(source, QStringLiteral("c"), project);
TestFile file3(source, QStringLiteral("c"), project);
file1.parse(TopDUContext::AllDeclarationsContextsAndUses);
file2.parse(TopDUContext::AllDeclarationsContextsAndUses);
file3.parse(TopDUContext::AllDeclarationsContextsAndUses);
QVERIFY(file1.waitForParsed(1000));
QVERIFY(file2.waitForParsed(1000));
QVERIFY(file3.waitForParsed(1000));
auto checkFunctionDefinition = [] (TestFile & file) {
DUChainReadLocker lock;
QCOMPARE(file.topContext()->localDeclarations().count(), 1);
auto configureFunc = file.topContext()->localDeclarations().first();
QCOMPARE(FunctionDefinition::definition(configureFunc), configureFunc);
};
checkFunctionDefinition(file1);
checkFunctionDefinition(file2);
checkFunctionDefinition(file3);
m_projectController->closeAllProjects();
}
......@@ -102,6 +102,8 @@ private Q_SLOTS:
void testQtIntegration();
void testHasInclude();
void testSameFunctionDefinition();
private:
QScopedPointer<TestEnvironmentProvider> m_provider;
KDevelop::TestProjectController* m_projectController;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment