mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-08-10 09:45:39 +02:00
Mapping types of variables back to ast-types, if possible; bug 292749.
This commit is contained in:
parent
24ce8e3659
commit
353d1d0875
10 changed files with 256 additions and 14 deletions
|
@ -233,6 +233,72 @@ public abstract class IndexBindingResolutionTestBase extends BaseTestCase {
|
||||||
assertQNEquals(expContainedTypeQN, (IBinding) containedType);
|
assertQNEquals(expContainedTypeQN, (IBinding) containedType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class SinglePDOMTestFirstASTStrategy implements ITestStrategy {
|
||||||
|
private IIndex index;
|
||||||
|
private ICProject cproject;
|
||||||
|
private StringBuffer[] testData;
|
||||||
|
private IASTTranslationUnit ast;
|
||||||
|
private boolean cpp;
|
||||||
|
|
||||||
|
public SinglePDOMTestFirstASTStrategy(boolean cpp) {
|
||||||
|
this.cpp = cpp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ICProject getCProject() {
|
||||||
|
return cproject;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StringBuffer[] getTestData() {
|
||||||
|
return testData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IASTTranslationUnit getAst() {
|
||||||
|
return ast;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUp() throws Exception {
|
||||||
|
cproject = cpp ? CProjectHelper.createCCProject(getName()+System.currentTimeMillis(), "bin", IPDOMManager.ID_NO_INDEXER)
|
||||||
|
: CProjectHelper.createCProject(getName()+System.currentTimeMillis(), "bin", IPDOMManager.ID_NO_INDEXER);
|
||||||
|
Bundle b = CTestPlugin.getDefault().getBundle();
|
||||||
|
testData = TestSourceReader.getContentsForTest(b, "parser", IndexBindingResolutionTestBase.this.getClass(), getName(), 2);
|
||||||
|
|
||||||
|
if (testData.length < 2)
|
||||||
|
return;
|
||||||
|
IFile file = TestSourceReader.createFile(cproject.getProject(), new Path("header.h"), testData[0].toString());
|
||||||
|
CCorePlugin.getIndexManager().setIndexerId(cproject, IPDOMManager.ID_FAST_INDEXER);
|
||||||
|
assertTrue(CCorePlugin.getIndexManager().joinIndexer(360000, new NullProgressMonitor()));
|
||||||
|
|
||||||
|
if (DEBUG) {
|
||||||
|
System.out.println("Project PDOM: "+getName());
|
||||||
|
((PDOM)CCoreInternals.getPDOMManager().getPDOM(cproject)).accept(new PDOMPrettyPrinter());
|
||||||
|
}
|
||||||
|
|
||||||
|
index= CCorePlugin.getIndexManager().getIndex(cproject);
|
||||||
|
|
||||||
|
index.acquireReadLock();
|
||||||
|
IFile cppfile= TestSourceReader.createFile(cproject.getProject(), new Path("references.c" + (cpp ? "pp" : "")), testData[1].toString());
|
||||||
|
ast = TestSourceReader.createIndexBasedAST(index, cproject, cppfile);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void tearDown() throws Exception {
|
||||||
|
if (index != null) {
|
||||||
|
index.releaseReadLock();
|
||||||
|
}
|
||||||
|
if (cproject != null) {
|
||||||
|
cproject.getProject().delete(IResource.FORCE | IResource.ALWAYS_DELETE_PROJECT_CONTENT, new NullProgressMonitor());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public IIndex getIndex() {
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isCompositeIndex() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class SinglePDOMTestStrategy implements ITestStrategy {
|
class SinglePDOMTestStrategy implements ITestStrategy {
|
||||||
private IIndex index;
|
private IIndex index;
|
||||||
|
|
|
@ -64,13 +64,14 @@ public class IndexCPPBindingResolutionBugs extends IndexBindingResolutionTestBas
|
||||||
public SingleProject() {setStrategy(new SinglePDOMTestStrategy(true));}
|
public SingleProject() {setStrategy(new SinglePDOMTestStrategy(true));}
|
||||||
public static TestSuite suite() {return suite(SingleProject.class);}
|
public static TestSuite suite() {return suite(SingleProject.class);}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class ProjectWithDepProj extends IndexCPPBindingResolutionBugs {
|
public static class ProjectWithDepProj extends IndexCPPBindingResolutionBugs {
|
||||||
public ProjectWithDepProj() {setStrategy(new ReferencedProject(true));}
|
public ProjectWithDepProj() {setStrategy(new ReferencedProject(true));}
|
||||||
public static TestSuite suite() {return suite(ProjectWithDepProj.class);}
|
public static TestSuite suite() {return suite(ProjectWithDepProj.class);}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void addTests(TestSuite suite) {
|
public static void addTests(TestSuite suite) {
|
||||||
|
suite.addTest(IndexCPPBindingResolutionBugsSingleProjectFirstAST.suite());
|
||||||
suite.addTest(SingleProject.suite());
|
suite.addTest(SingleProject.suite());
|
||||||
suite.addTest(ProjectWithDepProj.suite());
|
suite.addTest(ProjectWithDepProj.suite());
|
||||||
}
|
}
|
||||||
|
@ -87,6 +88,7 @@ public class IndexCPPBindingResolutionBugs extends IndexBindingResolutionTestBas
|
||||||
// #define FUNC() void bar()
|
// #define FUNC() void bar()
|
||||||
// #define FUNC2(A) void baz()
|
// #define FUNC2(A) void baz()
|
||||||
|
|
||||||
|
|
||||||
// #include "header.h"
|
// #include "header.h"
|
||||||
//
|
//
|
||||||
// OBJ {}
|
// OBJ {}
|
||||||
|
@ -1136,4 +1138,20 @@ public class IndexCPPBindingResolutionBugs extends IndexBindingResolutionTestBas
|
||||||
buf.append('}');
|
buf.append('}');
|
||||||
return buf.toString();
|
return buf.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// class Derived;
|
||||||
|
// class X {
|
||||||
|
// Derived* d;
|
||||||
|
// };
|
||||||
|
// class Base {};
|
||||||
|
// void useBase(Base* b);
|
||||||
|
|
||||||
|
// class Derived: Base {};
|
||||||
|
// void test() {
|
||||||
|
// X x;
|
||||||
|
// useBase(x.d);
|
||||||
|
// }
|
||||||
|
public void testLateDefinitionOfInheritance_Bug292749() throws Exception {
|
||||||
|
getBindingFromASTName("useBase(x.d", 7, ICPPFunction.class);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2009 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
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* Markus Schorn - initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.internal.index.tests;
|
||||||
|
|
||||||
|
import junit.framework.TestSuite;
|
||||||
|
|
||||||
|
public class IndexCPPBindingResolutionBugsSingleProjectFirstAST extends IndexCPPBindingResolutionBugs {
|
||||||
|
public IndexCPPBindingResolutionBugsSingleProjectFirstAST() {
|
||||||
|
setStrategy(new SinglePDOMTestFirstASTStrategy(true));
|
||||||
|
}
|
||||||
|
public static TestSuite suite() {return suite(IndexCPPBindingResolutionBugsSingleProjectFirstAST.class);}
|
||||||
|
// invalid tests for this strategy, they assume that the second file is already indexed.
|
||||||
|
@Override public void testBug208558() {}
|
||||||
|
@Override public void testBug176708_CCE() {}
|
||||||
|
@Override public void testIsSameAnonymousType_Bug193962() {}
|
||||||
|
@Override public void testIsSameNestedAnonymousType_Bug193962() {}
|
||||||
|
}
|
|
@ -35,6 +35,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
|
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
|
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author jcamelon
|
* @author jcamelon
|
||||||
|
@ -188,11 +189,11 @@ public class CPPASTFieldReference extends ASTNode implements
|
||||||
IBinding binding = name.resolvePreBinding();
|
IBinding binding = name.resolvePreBinding();
|
||||||
try {
|
try {
|
||||||
if (binding instanceof IVariable) {
|
if (binding instanceof IVariable) {
|
||||||
return ((IVariable) binding).getType();
|
return SemanticUtil.mapToAST(((IVariable) binding).getType(), this);
|
||||||
} else if (binding instanceof IEnumerator) {
|
} else if (binding instanceof IEnumerator) {
|
||||||
return ((IEnumerator) binding).getType();
|
return ((IEnumerator) binding).getType();
|
||||||
} else if (binding instanceof IFunction) {
|
} else if (binding instanceof IFunction) {
|
||||||
return ((IFunction) binding).getType();
|
return SemanticUtil.mapToAST(((IFunction) binding).getType(), this);
|
||||||
} else if (binding instanceof ICPPUnknownBinding) {
|
} else if (binding instanceof ICPPUnknownBinding) {
|
||||||
return CPPUnknownClass.createUnnamedInstance();
|
return CPPUnknownClass.createUnnamedInstance();
|
||||||
} else if (binding instanceof IProblemBinding) {
|
} else if (binding instanceof IProblemBinding) {
|
||||||
|
|
|
@ -213,9 +213,9 @@ public class CPPASTFunctionCallExpression extends ASTNode implements
|
||||||
return new ProblemBinding(this, IProblemBinding.SEMANTIC_BAD_SCOPE,
|
return new ProblemBinding(this, IProblemBinding.SEMANTIC_BAD_SCOPE,
|
||||||
binding.getName().toCharArray());
|
binding.getName().toCharArray());
|
||||||
} else if (binding instanceof IFunction) {
|
} else if (binding instanceof IFunction) {
|
||||||
t = ((IFunction) binding).getType();
|
t = SemanticUtil.mapToAST(((IFunction) binding).getType(), this);
|
||||||
} else if (binding instanceof IVariable) {
|
} else if (binding instanceof IVariable) {
|
||||||
t = ((IVariable) binding).getType();
|
t = SemanticUtil.mapToAST(((IVariable) binding).getType(), this);
|
||||||
} else if (binding instanceof IType) {
|
} else if (binding instanceof IType) {
|
||||||
return (IType) binding; // constructor or simple type initializer
|
return (IType) binding; // constructor or simple type initializer
|
||||||
} else if (binding instanceof IProblemBinding) {
|
} else if (binding instanceof IProblemBinding) {
|
||||||
|
|
|
@ -26,6 +26,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateNonTypeParameter;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateNonTypeParameter;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
|
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author jcamelon
|
* @author jcamelon
|
||||||
|
@ -91,13 +92,13 @@ public class CPPASTIdExpression extends ASTNode implements IASTIdExpression, IAS
|
||||||
IBinding binding = name.resolvePreBinding();
|
IBinding binding = name.resolvePreBinding();
|
||||||
try {
|
try {
|
||||||
if (binding instanceof IVariable) {
|
if (binding instanceof IVariable) {
|
||||||
return ((IVariable) binding).getType();
|
return SemanticUtil.mapToAST(((IVariable) binding).getType(), this);
|
||||||
} else if (binding instanceof IEnumerator) {
|
} else if (binding instanceof IEnumerator) {
|
||||||
return ((IEnumerator) binding).getType();
|
return ((IEnumerator) binding).getType();
|
||||||
} else if (binding instanceof IProblemBinding) {
|
} else if (binding instanceof IProblemBinding) {
|
||||||
return (IType) binding;
|
return (IType) binding;
|
||||||
} else if (binding instanceof IFunction) {
|
} else if (binding instanceof IFunction) {
|
||||||
return ((IFunction) binding).getType();
|
return SemanticUtil.mapToAST(((IFunction) binding).getType(), this);
|
||||||
} else if (binding instanceof ICPPTemplateNonTypeParameter) {
|
} else if (binding instanceof ICPPTemplateNonTypeParameter) {
|
||||||
return ((ICPPTemplateNonTypeParameter) binding).getType();
|
return ((ICPPTemplateNonTypeParameter) binding).getType();
|
||||||
} else if (binding instanceof ICPPClassType) {
|
} else if (binding instanceof ICPPClassType) {
|
||||||
|
|
|
@ -17,6 +17,7 @@ import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.dom.IName;
|
||||||
import org.eclipse.cdt.core.dom.ast.DOMException;
|
import org.eclipse.cdt.core.dom.ast.DOMException;
|
||||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||||
import org.eclipse.cdt.core.dom.ast.IProblemBinding;
|
import org.eclipse.cdt.core.dom.ast.IProblemBinding;
|
||||||
|
@ -194,10 +195,20 @@ class BaseClassLookup {
|
||||||
// assume that there are no bases
|
// assume that there are no bases
|
||||||
}
|
}
|
||||||
if (grandBases != null && grandBases.length > 0) {
|
if (grandBases != null && grandBases.length > 0) {
|
||||||
HashSet<IBinding> grandBaseBindings= grandBases.length > 1 ? new HashSet<IBinding>() : null;
|
HashSet<IBinding> grandBaseBindings= null;
|
||||||
for (ICPPBase grandBase : grandBases) {
|
BitSet selectedBases= null;
|
||||||
|
if (grandBases.length > 1) {
|
||||||
|
grandBaseBindings= new HashSet<IBinding>();
|
||||||
|
|
||||||
|
// if we have reachable bases, then ignore the others
|
||||||
|
selectedBases = selectPreferredBases(data, grandBases);
|
||||||
|
}
|
||||||
|
for (int i = 0; i < grandBases.length; i++) {
|
||||||
|
ICPPBase grandBase = grandBases[i];
|
||||||
if (grandBase instanceof IProblemBinding)
|
if (grandBase instanceof IProblemBinding)
|
||||||
continue;
|
continue;
|
||||||
|
if (selectedBases != null && !selectedBases.get(i))
|
||||||
|
continue;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
IBinding grandBaseBinding = grandBase.getBaseClass();
|
IBinding grandBaseBinding = grandBase.getBaseClass();
|
||||||
|
@ -238,6 +249,31 @@ class BaseClassLookup {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static BitSet selectPreferredBases(LookupData data, ICPPBase[] grandBases) {
|
||||||
|
if (data.contentAssist)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
BitSet selectedBases;
|
||||||
|
selectedBases= new BitSet(grandBases.length);
|
||||||
|
IName baseName= null;
|
||||||
|
for (int i = 0; i < grandBases.length; i++) {
|
||||||
|
ICPPBase nbase = grandBases[i];
|
||||||
|
if (nbase instanceof IProblemBinding)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
final IName nbaseName = nbase.getBaseClassSpecifierName();
|
||||||
|
int cmp= baseName == null ? -1 : CPPSemantics.compareByRelevance(data, baseName, nbaseName);
|
||||||
|
if (cmp <= 0) {
|
||||||
|
if (cmp < 0) {
|
||||||
|
selectedBases.clear();
|
||||||
|
baseName= nbaseName;
|
||||||
|
}
|
||||||
|
selectedBases.set(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return selectedBases;
|
||||||
|
}
|
||||||
|
|
||||||
static void hideVirtualBases(BaseClassLookup rootInfo, HashMap<IScope, BaseClassLookup> infoMap) {
|
static void hideVirtualBases(BaseClassLookup rootInfo, HashMap<IScope, BaseClassLookup> infoMap) {
|
||||||
boolean containsVirtualBase= false;
|
boolean containsVirtualBase= false;
|
||||||
final BaseClassLookup[] allInfos = infoMap.values().toArray(new BaseClassLookup[infoMap.size()]);
|
final BaseClassLookup[] allInfos = infoMap.values().toArray(new BaseClassLookup[infoMap.size()]);
|
||||||
|
|
|
@ -24,6 +24,7 @@ import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.dom.IName;
|
||||||
import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
|
import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
|
||||||
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
||||||
import org.eclipse.cdt.core.dom.ast.DOMException;
|
import org.eclipse.cdt.core.dom.ast.DOMException;
|
||||||
|
@ -136,7 +137,9 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDirective;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariable;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariable;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
|
||||||
import org.eclipse.cdt.core.index.IIndexBinding;
|
import org.eclipse.cdt.core.index.IIndexBinding;
|
||||||
|
import org.eclipse.cdt.core.index.IIndexFile;
|
||||||
import org.eclipse.cdt.core.index.IIndexFileSet;
|
import org.eclipse.cdt.core.index.IIndexFileSet;
|
||||||
|
import org.eclipse.cdt.core.index.IIndexName;
|
||||||
import org.eclipse.cdt.core.parser.IProblem;
|
import org.eclipse.cdt.core.parser.IProblem;
|
||||||
import org.eclipse.cdt.core.parser.util.ArrayUtil;
|
import org.eclipse.cdt.core.parser.util.ArrayUtil;
|
||||||
import org.eclipse.cdt.core.parser.util.CharArrayObjectMap;
|
import org.eclipse.cdt.core.parser.util.CharArrayObjectMap;
|
||||||
|
@ -183,6 +186,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.OverloadableOperator;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Conversions.UDCMode;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Conversions.UDCMode;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Cost.Rank;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Cost.Rank;
|
||||||
import org.eclipse.cdt.internal.core.index.IIndexScope;
|
import org.eclipse.cdt.internal.core.index.IIndexScope;
|
||||||
|
import org.eclipse.core.runtime.CoreException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Name resolution
|
* Name resolution
|
||||||
|
@ -1788,6 +1792,36 @@ public class CPPSemantics {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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,
|
||||||
|
* built for a different configuration, etc. Index bindings reachable through includes
|
||||||
|
* are more relevant than unreachable ones.
|
||||||
|
* @param ast
|
||||||
|
* @param b1
|
||||||
|
* @param b2
|
||||||
|
* @return 1 if binding <code>b1</code> is more relevant than <code>b2</code>; 0 if
|
||||||
|
* the two bindings have the same relevance; -1 if <code>b1</code> is less relevant than
|
||||||
|
* <code>b2</code>.
|
||||||
|
*/
|
||||||
|
static int compareByRelevance(LookupData data, IName b1, IName b2) {
|
||||||
|
boolean b1FromIndex= (b1 instanceof IIndexName);
|
||||||
|
boolean b2FromIndex= (b2 instanceof IIndexName);
|
||||||
|
if (b1FromIndex != b2FromIndex) {
|
||||||
|
return !b1FromIndex ? 1 : -1;
|
||||||
|
} else if (b1FromIndex) {
|
||||||
|
// Both are from index.
|
||||||
|
if (data.tu != null) {
|
||||||
|
boolean b1Reachable= isReachableFromAst(data.tu, b1);
|
||||||
|
boolean b2Reachable= isReachableFromAst(data.tu, b2);
|
||||||
|
if (b1Reachable != b2Reachable) {
|
||||||
|
return b1Reachable ? 1 : -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compares a binding with a list of function candidates for relevance in the context of an AST. AST bindings are
|
* Compares a binding with a list of function candidates 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,
|
* considered more relevant than index ones since the index may be out of date,
|
||||||
|
@ -1864,6 +1898,28 @@ public class CPPSemantics {
|
||||||
return indexFileSet != null && indexFileSet.containsDeclaration(indexBinding);
|
return indexFileSet != null && indexFileSet.containsDeclaration(indexBinding);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if a binding is an AST binding, or is reachable from the AST through includes.
|
||||||
|
* The binding is assumed to belong to the AST, if it is not an IIndexBinding and not
|
||||||
|
* a specialization of an IIndexBinding.
|
||||||
|
* @param ast
|
||||||
|
* @param binding
|
||||||
|
* @return <code>true</code> if the <code>binding</code> is reachable from <code>ast</code>.
|
||||||
|
*/
|
||||||
|
private static boolean isReachableFromAst(IASTTranslationUnit ast, IName name) {
|
||||||
|
if (!(name instanceof IIndexName)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
IIndexName indexName = (IIndexName) name;
|
||||||
|
try {
|
||||||
|
IIndexFile file= indexName.getFile();
|
||||||
|
IIndexFileSet indexFileSet = ast.getIndexFileSet();
|
||||||
|
return indexFileSet != null && indexFileSet.contains(file);
|
||||||
|
} catch (CoreException e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static private void reduceToViable(LookupData data, IBinding[] functions) throws DOMException {
|
static private void reduceToViable(LookupData data, IBinding[] functions) throws DOMException {
|
||||||
if (functions == null || functions.length == 0)
|
if (functions == null || functions.length == 0)
|
||||||
return;
|
return;
|
||||||
|
@ -2452,7 +2508,7 @@ public class CPPSemantics {
|
||||||
* Also collections the function bindings if requested.
|
* Also collections the function bindings if requested.
|
||||||
*/
|
*/
|
||||||
public static IType getChainedMemberAccessOperatorReturnType(ICPPASTFieldReference fieldReference, Collection<ICPPFunction> functionBindings) throws DOMException {
|
public static IType getChainedMemberAccessOperatorReturnType(ICPPASTFieldReference fieldReference, Collection<ICPPFunction> functionBindings) throws DOMException {
|
||||||
IASTExpression owner = fieldReference.getFieldOwner();
|
final IASTExpression owner = fieldReference.getFieldOwner();
|
||||||
if (owner == null)
|
if (owner == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
|
@ -2505,7 +2561,7 @@ public class CPPSemantics {
|
||||||
if (functionBindings != null)
|
if (functionBindings != null)
|
||||||
functionBindings.add(op);
|
functionBindings.add(op);
|
||||||
|
|
||||||
type= op.getType().getReturnType();
|
type= SemanticUtil.mapToAST(op.getType().getReturnType(), owner);
|
||||||
foundOperator= true;
|
foundOperator= true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -594,9 +594,8 @@ public class Conversions {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This should actually be done in 'checkImplicitConversionSequence', see 13.3.3.1-6 and 8.5.14
|
// This should actually be done before the conversion is attempted, see for instance 13.3.3.1-6 and 8.5.14.
|
||||||
// 8.5.14 cv-qualifiers can be ignored for non-class types
|
// However, it does not hurt to do it here either.
|
||||||
// mstodo
|
|
||||||
IType unqualifiedTarget= getNestedType(target, CVQ | PTR_CVQ | TDEF | REF);
|
IType unqualifiedTarget= getNestedType(target, CVQ | PTR_CVQ | TDEF | REF);
|
||||||
if (!(unqualifiedTarget instanceof ICPPClassType)) {
|
if (!(unqualifiedTarget instanceof ICPPClassType)) {
|
||||||
IType unqualifiedSource= getNestedType(source, CVQ | PTR_CVQ | TDEF | REF);
|
IType unqualifiedSource= getNestedType(source, CVQ | PTR_CVQ | TDEF | REF);
|
||||||
|
|
|
@ -15,6 +15,8 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.CCorePlugin;
|
import org.eclipse.cdt.core.CCorePlugin;
|
||||||
import org.eclipse.cdt.core.dom.ast.DOMException;
|
import org.eclipse.cdt.core.dom.ast.DOMException;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
||||||
import org.eclipse.cdt.core.dom.ast.IArrayType;
|
import org.eclipse.cdt.core.dom.ast.IArrayType;
|
||||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||||
import org.eclipse.cdt.core.dom.ast.IFunctionType;
|
import org.eclipse.cdt.core.dom.ast.IFunctionType;
|
||||||
|
@ -37,6 +39,7 @@ import org.eclipse.cdt.core.parser.util.CharArraySet;
|
||||||
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
|
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
|
||||||
import org.eclipse.cdt.core.parser.util.ObjectSet;
|
import org.eclipse.cdt.core.parser.util.ObjectSet;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer;
|
import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTTranslationUnit;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunctionType;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunctionType;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerToMemberType;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerToMemberType;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerType;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerType;
|
||||||
|
@ -44,6 +47,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPQualifierType;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateArgument;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateArgument;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.OverloadableOperator;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.OverloadableOperator;
|
||||||
|
import org.eclipse.cdt.internal.core.index.IIndexType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -290,6 +294,42 @@ public class SemanticUtil {
|
||||||
type.setType(newNestedType);
|
type.setType(newNestedType);
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static IType mapToAST(IType type, IASTNode node) {
|
||||||
|
if (!(type instanceof IIndexType))
|
||||||
|
return type;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (type instanceof IFunctionType) {
|
||||||
|
final ICPPFunctionType ft = (ICPPFunctionType) type;
|
||||||
|
final IType r = ft.getReturnType();
|
||||||
|
final IType ret = mapToAST(r, node);
|
||||||
|
if (ret == r) {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
return new CPPFunctionType(ret, ft.getParameterTypes(), ft.isConst(), ft.isVolatile());
|
||||||
|
}
|
||||||
|
if (type instanceof ITypeContainer) {
|
||||||
|
final ITypeContainer tc = (ITypeContainer) type;
|
||||||
|
final IType nestedType= tc.getType();
|
||||||
|
if (nestedType == null)
|
||||||
|
return type;
|
||||||
|
|
||||||
|
IType newType= mapToAST(nestedType, node);
|
||||||
|
if (newType != nestedType) {
|
||||||
|
return replaceNestedType(tc, newType);
|
||||||
|
}
|
||||||
|
return type;
|
||||||
|
} else if (type instanceof ICPPClassType && type instanceof IIndexType) {
|
||||||
|
IASTTranslationUnit tu = node.getTranslationUnit();
|
||||||
|
if (tu instanceof CPPASTTranslationUnit) {
|
||||||
|
return ((CPPASTTranslationUnit) tu).mapToAST((ICPPClassType) type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (DOMException e) {
|
||||||
|
}
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
public static IType[] getSimplifiedTypes(IType[] types) {
|
public static IType[] getSimplifiedTypes(IType[] types) {
|
||||||
// Don't create a new array until it's really needed.
|
// Don't create a new array until it's really needed.
|
||||||
|
|
Loading…
Add table
Reference in a new issue