1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-23 08:55:25 +02:00

Bug 304479: Disambiguation of types and objects from index.

This commit is contained in:
Markus Schorn 2010-03-04 08:22:17 +00:00
parent 6a8a4ece8f
commit 96c2033d9f
2 changed files with 102 additions and 16 deletions

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2006, 2009 Wind River Systems, Inc. and others.
* Copyright (c) 2006, 2010 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -2169,4 +2169,44 @@ public class IndexBugsTests extends BaseTestCase {
}
}
// // a.h
// struct Error{};
// // b.h
// void Error(int errCode) {}
// // source1.cpp
// #include "a.h"
// Error d;
// // source2.cpp
// Error d; // Problem, without inclusion we need to prefer the function.
public void testDisambiguateObjectVsType_304479() throws Exception {
waitForIndexer();
String[] testData = getContentsForTest(4);
TestSourceReader.createFile(fCProject.getProject(), "a.h", testData[0]);
TestSourceReader.createFile(fCProject.getProject(), "b.h", testData[1]);
IFile s1= TestSourceReader.createFile(fCProject.getProject(), "s1.cpp", testData[2]);
IFile s2= TestSourceReader.createFile(fCProject.getProject(), "s2.cpp", testData[3]);
final IIndexManager indexManager = CCorePlugin.getIndexManager();
indexManager.reindex(fCProject);
waitForIndexer();
IIndex index= indexManager.getIndex(fCProject);
index.acquireReadLock();
try {
IASTTranslationUnit tu = TestSourceReader.createIndexBasedAST(index, fCProject, s1);
IASTSimpleDeclaration sdecl= (IASTSimpleDeclaration) tu.getDeclarations()[0];
IVariable var= (IVariable) sdecl.getDeclarators()[0].getName().resolveBinding();
assertFalse(var.getType() instanceof IProblemBinding);
assertTrue(var.getType() instanceof ICPPClassType);
tu = TestSourceReader.createIndexBasedAST(index, fCProject, s2);
sdecl= (IASTSimpleDeclaration) tu.getDeclarations()[0];
var= (IVariable) sdecl.getDeclarators()[0].getName().resolveBinding();
assertTrue(var.getType() instanceof IProblemBinding);
} finally {
index.releaseReadLock();
}
}
}

View file

@ -1765,40 +1765,45 @@ public class CPPSemantics {
ICPPUsingDeclaration composite = new CPPUsingDeclaration(data.astName, bindings);
return composite;
}
if (data.typesOnly) {
if (type != null) {
if (obj instanceof ICPPNamespace && compareByRelevance(data, type, obj) < 0) {
return obj;
}
return type;
if (obj != null && type != null) {
if (obj instanceof ICPPNamespace) {
if (compareByRelevance(data, type, obj) >= 0) {
obj= null;
}
} else if (!data.typesOnly && overrulesByRelevance(data, type, obj)) {
obj= null;
}
}
if (data.typesOnly) {
if (obj instanceof ICPPNamespace)
return obj;
return null;
return type;
}
if (fns.size() > 0) {
final IFunction[] fnArray = fns.keyArray(IFunction.class);
if (type != null && overrulesByRelevance(data, type, fnArray)) {
return type;
}
if (obj != null) {
int cmp= compareByRelevance(data, obj, fnArray);
if (cmp == 0) {
return new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP,
data.getFoundBindings());
}
if (cmp > 0)
if (cmp > 0) {
return obj;
}
}
return resolveFunction(data, fnArray, true);
}
if (obj != null) {
if (type != null && obj instanceof ICPPNamespace) {
if (compareByRelevance(data, type, obj) >= 0) {
return type;
}
}
return obj;
}
return type;
@ -1834,6 +1839,47 @@ public class CPPSemantics {
return 0;
}
/**
* Compares two bindings for relevance in the context of an AST. Type bindings are
* considered to overrule object bindings when the former is reachable but the
* latter is not.
*/
static boolean overrulesByRelevance(LookupData data, IBinding type, IBinding b2) {
if (data != null && data.tu != null) {
return !isReachableFromAst(data.tu, b2) && isReachableFromAst(data.tu, type);
}
return false;
}
/**
* Compares a binding with a list of function candidates for relevance in the
* context of an AST. Types are considered to overrule object bindings when
* the former is reachable but none of the functions are.
*/
static boolean overrulesByRelevance(LookupData data, IBinding type, IFunction[] fns) {
if (data == null || data.tu == null) {
return false;
}
for (int i = 0; i < fns.length; i++) {
if (!isFromIndex(fns[i])) {
return false; // function from ast
}
}
if (!isReachableFromAst(data.tu, type)) {
return false;
}
for (IFunction fn : fns) {
if (isReachableFromAst(data.tu, fn)) {
return false; // function from ast
}
}
return true;
}
/**
* Compares two bindings for relevance in the context of an AST. AST bindings are
* considered more relevant than index ones since the index may be out of date,
@ -1901,7 +1947,7 @@ public class CPPSemantics {
}
return 1; // only obj is from ast.
}
private static boolean isFromIndex(IBinding binding) {
if (binding instanceof IIndexBinding) {
return true;