Skip to content

Commit c8daec6

Browse files
committed
Index distinct typedef from header file
GDB sources contain private portable regex implementation which provides own regmatch_t typedef. If another project file references system regex.h which provides regmatch_t typedef too, indexer would not adapt that binding and instead reuse first one it encountered. Later when that other file is parsed, attempt to resolve binding for ASTName referring to regmatch_t would fail because found PDOM binding is reachable only via private implementation header which is not included. Fix this by adapting unique typedef name to make both typedefs availabe to lookup procedure which will then filter by reachable index fragment.
1 parent 48d8d26 commit c8daec6

File tree

6 files changed

+128
-19
lines changed

6 files changed

+128
-19
lines changed

core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTInternal.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,8 +202,12 @@ private static boolean isPartOfSource(IASTNode decl) {
202202
}
203203

204204
private static IASTNode resolveConflict(IASTNode n1, IASTNode n2) {
205-
if (n1 == null)
205+
if (n1 == n2) {
206+
// No need to dig deeper
207+
return n1;
208+
} else if (n1 == null) {
206209
return n2;
210+
}
207211

208212
IASTFileLocation loc1 = n1.getFileLocation();
209213
if (loc1 == null)

core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/CIndex.java

Lines changed: 95 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,12 @@
2323
import java.util.Arrays;
2424
import java.util.Collection;
2525
import java.util.Collections;
26+
import java.util.Comparator;
2627
import java.util.HashMap;
2728
import java.util.HashSet;
2829
import java.util.List;
2930
import java.util.Set;
31+
import java.util.TreeSet;
3032
import java.util.regex.Pattern;
3133

3234
import org.eclipse.cdt.core.CCorePlugin;
@@ -46,11 +48,13 @@
4648
import org.eclipse.cdt.core.index.IIndexName;
4749
import org.eclipse.cdt.core.index.IndexFilter;
4850
import org.eclipse.cdt.core.parser.ISignificantMacros;
51+
import org.eclipse.cdt.core.parser.util.ArrayUtil;
4952
import org.eclipse.cdt.internal.core.dom.Linkage;
5053
import org.eclipse.cdt.internal.core.index.composite.CompositingNotImplementedError;
5154
import org.eclipse.cdt.internal.core.index.composite.ICompositesFactory;
5255
import org.eclipse.cdt.internal.core.index.composite.c.CCompositesFactory;
5356
import org.eclipse.cdt.internal.core.index.composite.cpp.CPPCompositesFactory;
57+
import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode;
5458
import org.eclipse.core.runtime.CoreException;
5559
import org.eclipse.core.runtime.IProgressMonitor;
5660
import org.eclipse.core.runtime.NullProgressMonitor;
@@ -162,8 +166,65 @@ public IIndexBinding[] findMacroContainers(Pattern pattern, IndexFilter filter,
162166
}
163167
}
164168

169+
private static class BindingAndLocationComparator implements Comparator<IIndexName> {
170+
@Override
171+
public int compare(IIndexName f1, IIndexName f2) {
172+
if (f1.equals(f2)) {
173+
return 0;
174+
}
175+
try {
176+
IIndexFile file1 = f1.getFile();
177+
IIndexFile file2 = f2.getFile();
178+
if (file1 != null && file2 != null) {
179+
return file1.getLocation().getURI().compareTo(file2.getLocation().getURI());
180+
}
181+
} catch (CoreException e) {
182+
}
183+
return -1;
184+
}
185+
}
186+
165187
@Override
166188
public IIndexName[] findNames(IBinding binding, int flags) throws CoreException {
189+
ArrayList<IIndexName> result = new ArrayList<>();
190+
PDOMNode pdomNode = binding.getAdapter(PDOMNode.class);
191+
if (pdomNode instanceof final IIndexFragmentBinding foreignIndexFragmeintBinding
192+
&& foreignIndexFragmeintBinding.isFileLocal()) {
193+
// same name in header file included from multiple projects will have multiple
194+
// distinct fragment bindings private to index fragments belonging to projects
195+
196+
// 1. extract all fragment bindings with same name from all index fragments
197+
198+
ILinkage linkage = foreignIndexFragmeintBinding.getLinkage();
199+
IIndexFragmentBinding[][] allBindings = findAllBindingsForLinkage(linkage, binding.getNameCharArray(),
200+
false, IndexFilter.ALL, new NullProgressMonitor());
201+
202+
// 2. pick ones comparing equal to search argument and get names for each
203+
204+
ICompositesFactory factory = getCompositesFactory(linkage.getLinkageID());
205+
for (IIndexFragmentBinding[] parts : allBindings) {
206+
if (parts == null) {
207+
continue;
208+
}
209+
for (IIndexFragmentBinding part : parts) {
210+
if (part == null) {
211+
continue;
212+
}
213+
if (factory.compareCompositeBindings(foreignIndexFragmeintBinding, part) == 0) {
214+
// found another fragment binding which looks like search argument
215+
ArrayUtil.addAll(result, findNamesForBinding(part, flags));
216+
}
217+
}
218+
}
219+
} else {
220+
ArrayUtil.addAll(result, findNamesForBinding(binding, flags));
221+
}
222+
223+
// return all found names
224+
return result.toArray(new IIndexName[result.size()]);
225+
}
226+
227+
private IIndexName[] findNamesForBinding(IBinding binding, int flags) throws CoreException {
167228
ArrayList<IIndexFragmentName> result = new ArrayList<>();
168229
if (binding instanceof ICPPUsingDeclaration) {
169230
IBinding[] bindings = ((ICPPUsingDeclaration) binding).getDelegates();
@@ -212,7 +273,16 @@ public IIndexName[] findNames(IBinding binding, int flags) throws CoreException
212273

213274
@Override
214275
public IIndexName[] findDeclarations(IBinding binding) throws CoreException {
215-
return findNames(binding, FIND_DECLARATIONS_DEFINITIONS);
276+
IIndexName[] names = findNames(binding, FIND_DECLARATIONS_DEFINITIONS);
277+
278+
// callers expect single entry per file if it is included multiple times, deduplicate by file location
279+
280+
TreeSet<IIndexName> ts = new TreeSet<>(new BindingAndLocationComparator());
281+
for (IIndexName name : names) {
282+
ts.add(name);
283+
}
284+
285+
return ts.toArray(new IIndexName[ts.size()]);
216286
}
217287

218288
@Override
@@ -652,27 +722,35 @@ public IIndexBinding[] findBindings(char[] name, boolean filescope, IndexFilter
652722
List<IIndexBinding[]> result = new ArrayList<>();
653723
ILinkage[] linkages = Linkage.getIndexerLinkages();
654724
for (ILinkage linkage : linkages) {
655-
if (filter.acceptLinkage(linkage)) {
656-
IIndexFragmentBinding[][] fragmentBindings = new IIndexFragmentBinding[fFragments.length][];
657-
for (int i = 0; i < fFragments.length; i++) {
658-
try {
659-
IBinding[] part = fFragments[i].findBindings(name, filescope,
660-
retargetFilter(linkage, filter), monitor);
661-
fragmentBindings[i] = new IIndexFragmentBinding[part.length];
662-
System.arraycopy(part, 0, fragmentBindings[i], 0, part.length);
663-
} catch (CoreException e) {
664-
CCorePlugin.log(e);
665-
fragmentBindings[i] = IIndexFragmentBinding.EMPTY_INDEX_BINDING_ARRAY;
666-
}
667-
}
668-
ICompositesFactory factory = getCompositesFactory(linkage.getLinkageID());
669-
result.add(factory.getCompositeBindings(fragmentBindings));
670-
}
725+
IIndexFragmentBinding[][] fragmentBindings = findAllBindingsForLinkage(linkage, name, filescope, filter,
726+
monitor);
727+
ICompositesFactory factory = getCompositesFactory(linkage.getLinkageID());
728+
result.add(factory.getCompositeBindings(fragmentBindings));
671729
}
672730
return flatten(result);
673731
}
674732
}
675733

734+
private IIndexFragmentBinding[][] findAllBindingsForLinkage(ILinkage linkage, char[] name, boolean filescope,
735+
IndexFilter filter, IProgressMonitor monitor) throws CoreException {
736+
if (!filter.acceptLinkage(linkage)) {
737+
return new IIndexFragmentBinding[0][];
738+
}
739+
740+
IIndexFragmentBinding[][] fragmentBindings = new IIndexFragmentBinding[fFragments.length][];
741+
for (int i = 0; i < fFragments.length; i++) {
742+
try {
743+
IBinding[] part = fFragments[i].findBindings(name, filescope, retargetFilter(linkage, filter), monitor);
744+
fragmentBindings[i] = new IIndexFragmentBinding[part.length];
745+
System.arraycopy(part, 0, fragmentBindings[i], 0, part.length);
746+
} catch (CoreException e) {
747+
CCorePlugin.log(e);
748+
fragmentBindings[i] = IIndexFragmentBinding.EMPTY_INDEX_BINDING_ARRAY;
749+
}
750+
}
751+
return fragmentBindings;
752+
}
753+
676754
@Override
677755
public IIndexMacro[] findMacros(char[] name, IndexFilter filter, IProgressMonitor monitor) throws CoreException {
678756
return findMacros(name, false, true, filter, monitor);

core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/AbstractCompositeFactory.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,11 @@ protected IIndexFragmentBinding[] mergeBindingArrays(IIndexFragmentBinding[][] f
104104
return ts.toArray(new IIndexFragmentBinding[ts.size()]);
105105
}
106106

107+
@Override
108+
public int compareCompositeBindings(IIndexFragmentBinding lhs, IIndexFragmentBinding rhs) {
109+
return fragmentComparator.compare(lhs, rhs);
110+
}
111+
107112
/**
108113
* Convenience method for finding a binding with a definition (in the specified index
109114
* context) which is equivalent to the specified binding. If no definition is found,

core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/ICompositesFactory.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,4 +54,12 @@ public interface ICompositesFactory {
5454
* Converts values.
5555
*/
5656
public IValue getCompositeValue(IValue v);
57+
58+
/**
59+
* Compares bindings
60+
* @param lhs
61+
* @param rhs
62+
* @return
63+
*/
64+
public int compareCompositeBindings(IIndexFragmentBinding lhs, IIndexFragmentBinding rhs);
5765
}

core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1343,6 +1343,11 @@ public IIndexFragmentInclude[] findIncludedBy(IIndexFragmentFile file) throws Co
13431343
return new PDOMInclude[0];
13441344
}
13451345

1346+
public boolean hasFileForLocation(int linkageId, IIndexFileLocation location) throws CoreException {
1347+
PDOMFile pdomFile = getFile(linkageId, location, null);
1348+
return pdomFile != null;
1349+
}
1350+
13461351
private PDOMFile adaptFile(IIndexFragmentFile file) throws CoreException {
13471352
if (file.getIndexFragment() == this && file instanceof PDOMFile) {
13481353
return (PDOMFile) file;

core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1300,7 +1300,10 @@ private final PDOMNode adaptOrAddParent(boolean add, IBinding binding) throws Co
13001300
IIndexBinding ib = (IIndexBinding) binding;
13011301
// Don't adapt file local bindings from other fragments to this one.
13021302
if (ib.isFileLocal()) {
1303-
return null;
1303+
if (!getPDOM().hasFileForLocation(ib.getLinkage().getLinkageID(), ib.getLocalToFile().getLocation())) {
1304+
// location not indexed here
1305+
return null;
1306+
}
13041307
}
13051308
}
13061309

@@ -1602,6 +1605,11 @@ protected PDOMFile getLocalToFile(IBinding binding, PDOMBinding glob) throws Cor
16021605
if (node != null) {
16031606
file = wpdom.getFileForASTNode(getLinkageID(), node);
16041607
}
1608+
} else if (binding instanceof ITypedef) {
1609+
IASTNode node = ASTInternal.getDeclaredInOneFileOnly(binding);
1610+
if (node != null) {
1611+
file = wpdom.getFileForASTNode(getLinkageID(), node);
1612+
}
16051613
} else if (binding instanceof ICPPNamespaceAlias) {
16061614
IASTNode node = ASTInternal.getDeclaredInSourceFileOnly(getPDOM(), binding, false, glob);
16071615
if (node != null) {
@@ -1610,6 +1618,7 @@ protected PDOMFile getLocalToFile(IBinding binding, PDOMBinding glob) throws Cor
16101618
}
16111619
if (file == null && !(binding instanceof IIndexBinding)) {
16121620
IBinding owner = binding.getOwner();
1621+
// TODO: maybe do the same for anonymous class type?
16131622
if (owner instanceof ICPPNamespace && owner.getNameCharArray().length == 0) {
16141623
IASTNode node = ASTInternal.getDefinitionOfBinding(binding);
16151624
if (node != null) {

0 commit comments

Comments
 (0)