diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/EmptyIndexFragment.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/EmptyIndexFragment.java
index a2e41c70274..1c0ce140708 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/EmptyIndexFragment.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/EmptyIndexFragment.java
@@ -7,6 +7,7 @@
*
* Contributors:
* Andrew Ferguson (Symbian) - initial API and implementation
+ * Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.index.tests;
@@ -16,6 +17,7 @@ import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.index.IIndexFileLocation;
import org.eclipse.cdt.core.index.IIndexLinkage;
+import org.eclipse.cdt.core.index.IIndexMacro;
import org.eclipse.cdt.core.index.IndexFilter;
import org.eclipse.cdt.internal.core.index.IIndexFragment;
import org.eclipse.cdt.internal.core.index.IIndexFragmentBinding;
@@ -63,6 +65,10 @@ public class EmptyIndexFragment implements IIndexFragment {
return IIndexFragmentBinding.EMPTY_INDEX_BINDING_ARRAY;
}
+ public IIndexMacro[] findMacros(char[] name, boolean isPrefix, boolean caseSensitive, IndexFilter filter, IProgressMonitor monitor) {
+ return IIndexMacro.EMPTY_INDEX_MACRO_ARRAY;
+ }
+
public IIndexFragmentInclude[] findIncludedBy(IIndexFragmentFile file)
throws CoreException {
return IIndexFragmentInclude.EMPTY_FRAGMENT_INCLUDES_ARRAY;
diff --git a/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/IndexTypeInfo.java b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/IndexTypeInfo.java
index 2185abf19e8..3564fe548e9 100644
--- a/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/IndexTypeInfo.java
+++ b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/IndexTypeInfo.java
@@ -16,6 +16,7 @@ package org.eclipse.cdt.core.browser;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.HashMap;
import java.util.List;
import org.eclipse.cdt.core.CCorePlugin;
@@ -27,9 +28,12 @@ import org.eclipse.cdt.core.dom.ast.IFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBinding;
import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.index.IIndexBinding;
+import org.eclipse.cdt.core.index.IIndexFile;
import org.eclipse.cdt.core.index.IIndexFileLocation;
+import org.eclipse.cdt.core.index.IIndexMacro;
import org.eclipse.cdt.core.index.IIndexName;
import org.eclipse.cdt.core.index.IndexFilter;
+import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.parser.ast.ASTAccessVisibility;
import org.eclipse.cdt.internal.core.browser.IndexTypeReference;
@@ -50,6 +54,17 @@ import org.eclipse.core.runtime.Path;
*
*/
public class IndexTypeInfo implements ITypeInfo, IFunctionInfo {
+ private static int hashCode(String[] array) {
+ int prime = 31;
+ if (array == null)
+ return 0;
+ int result = 1;
+ for (int index = 0; index < array.length; index++) {
+ result = prime * result + (array[index] == null ? 0 : array[index].hashCode());
+ }
+ return result;
+ }
+
private final String[] fqn;
private final int elementType;
private final IIndex index;
@@ -58,7 +73,7 @@ public class IndexTypeInfo implements ITypeInfo, IFunctionInfo {
private ITypeReference reference; // lazily constructed
/**
- * Creates a typeinfo suitable for the binding.
+ * Creates a type info suitable for the binding.
* @param index a non-null index in which to locate references
* @param binding
* @since 4.0.1
@@ -93,6 +108,17 @@ public class IndexTypeInfo implements ITypeInfo, IFunctionInfo {
return new IndexTypeInfo(fqn, elementType, index);
}
+ /**
+ * Creates a type info object suitable for a macro.
+ * @param index a non-null index in which to locate references
+ * @param binding
+ * @since 4.0.1
+ */
+ public static IndexTypeInfo create(IIndex index, IIndexMacro macro) {
+ final char[] name= macro.getName();
+ return new IndexTypeInfo(new String[] {new String(name)}, ICElement.C_MACRO, index);
+ }
+
private IndexTypeInfo(String[] fqn, int elementType, IIndex index, String[] params, String returnType, ITypeReference reference) {
Assert.isTrue(index != null);
this.fqn= fqn;
@@ -190,6 +216,9 @@ public class IndexTypeInfo implements ITypeInfo, IFunctionInfo {
public ITypeReference getResolvedReference() {
if(reference==null) {
+ if (elementType == ICElement.C_MACRO) {
+ return createMacroReference();
+ }
try {
index.acquireReadLock();
@@ -235,6 +264,29 @@ public class IndexTypeInfo implements ITypeInfo, IFunctionInfo {
return reference;
}
+ private ITypeReference createMacroReference() {
+ try {
+ index.acquireReadLock();
+
+ IIndexMacro[] macros = index.findMacros(fqn[0].toCharArray(), IndexFilter.ALL_DECLARED, new NullProgressMonitor());
+ if(macros.length>0) {
+ for (int i = 0; i < macros.length; i++) {
+ reference= createReference(macros[i]);
+ if (reference != null) {
+ break;
+ }
+ }
+ }
+ } catch(CoreException ce) {
+ CCorePlugin.log(ce);
+ } catch (InterruptedException ie) {
+ Thread.currentThread().interrupt();
+ } finally {
+ index.releaseReadLock();
+ }
+ return reference;
+ }
+
private IndexTypeReference createReference(IIndexBinding binding, IIndexName indexName) throws CoreException {
IIndexFileLocation ifl = indexName.getFile().getLocation();
String fullPath = ifl.getFullPath();
@@ -256,7 +308,32 @@ public class IndexTypeInfo implements ITypeInfo, IFunctionInfo {
return null;
}
+ private IndexTypeReference createReference(IIndexMacro macro) throws CoreException {
+ IIndexFileLocation ifl = macro.getFile().getLocation();
+ String fullPath = ifl.getFullPath();
+ if (fullPath != null) {
+ IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(fullPath));
+ if(file!=null) {
+ return new IndexTypeReference(
+ macro, file, file.getProject(), macro.getNodeOffset(), macro.getNodeLength()
+ );
+ }
+ } else {
+ IPath path = URIUtil.toPath(ifl.getURI());
+ if(path!=null) {
+ return new IndexTypeReference(
+ macro, path, null, macro.getNodeOffset(), macro.getNodeLength()
+ );
+ }
+ }
+ return null;
+ }
+
public ITypeReference[] getReferences() {
+ if (elementType == ICElement.C_MACRO) {
+ return getMacroReferences();
+ }
+
List references= new ArrayList();
try {
index.acquireReadLock();
@@ -279,16 +356,51 @@ public class IndexTypeInfo implements ITypeInfo, IFunctionInfo {
return sameType;
}
}, new NullProgressMonitor());
+ // in case a file is represented multiple times in the index then we take references from
+ // one of those, only.
+ HashMap iflMap= new HashMap();
for (int i = 0; i < ibs.length; i++) {
IIndexBinding binding = ibs[i];
IIndexName[] names;
names= index.findNames(binding, IIndex.FIND_DEFINITIONS);
if (names.length == 0) {
- names= index.findNames(ibs[0], IIndex.FIND_DECLARATIONS);
+ names= index.findNames(binding, IIndex.FIND_DECLARATIONS);
}
for (int j = 0; j < names.length; j++) {
IIndexName indexName = names[j];
- IndexTypeReference ref= createReference(binding, indexName);
+ if (checkFile(iflMap, indexName.getFile())) {
+ IndexTypeReference ref= createReference(binding, indexName);
+ if (ref != null) {
+ references.add(ref);
+ }
+ }
+ }
+ }
+ } catch(CoreException ce) {
+ CCorePlugin.log(ce);
+ } catch (InterruptedException ie) {
+ CCorePlugin.log(ie);
+ } finally {
+ index.releaseReadLock();
+ }
+ return (IndexTypeReference[]) references.toArray(new IndexTypeReference[references.size()]);
+ }
+
+
+ private ITypeReference[] getMacroReferences() {
+ List references= new ArrayList();
+ try {
+ index.acquireReadLock();
+
+ char[] cfn= fqn[0].toCharArray();
+ IIndexMacro[] ibs = index.findMacros(cfn, IndexFilter.ALL_DECLARED, new NullProgressMonitor());
+ // in case a file is represented multiple times in the index then we take references from
+ // one of those, only.
+ HashMap iflMap= new HashMap();
+ for (int i = 0; i < ibs.length; i++) {
+ IIndexMacro macro= ibs[i];
+ if (checkFile(iflMap, macro.getFile())) {
+ IndexTypeReference ref= createReference(macro);
if (ref != null) {
references.add(ref);
}
@@ -304,6 +416,18 @@ public class IndexTypeInfo implements ITypeInfo, IFunctionInfo {
return (IndexTypeReference[]) references.toArray(new IndexTypeReference[references.size()]);
}
+ /**
+ * Makes sure that per file only refs from one IIndexFile object are taken.
+ */
+ private boolean checkFile(HashMap iflMap, IIndexFile file) throws CoreException {
+ IIndexFileLocation ifl= file.getLocation();
+ IIndexFile otherFile= (IIndexFile) iflMap.get(ifl);
+ if (otherFile == null) {
+ iflMap.put(ifl, file);
+ return true;
+ }
+ return otherFile.equals(file);
+ }
public ITypeInfo getRootNamespace(boolean includeGlobalNamespace) {
throw new PDOMNotImplementedError();
@@ -383,4 +507,32 @@ public class IndexTypeInfo implements ITypeInfo, IFunctionInfo {
return returnType;
}
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + elementType;
+ result = prime * result + IndexTypeInfo.hashCode(fqn);
+ result = prime * result + IndexTypeInfo.hashCode(params);
+ return result;
+ }
+
+ /**
+ * Type info objects are equal if they compute the same references.
+ */
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ IndexTypeInfo other = (IndexTypeInfo) obj;
+ if (elementType != other.elementType)
+ return false;
+ if (!Arrays.equals(fqn, other.fqn))
+ return false;
+ if (!Arrays.equals(params, other.params))
+ return false;
+ return true;
+ }
}
diff --git a/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/IndexTypeReference.java b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/IndexTypeReference.java
index 6d78125c484..b950740a020 100644
--- a/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/IndexTypeReference.java
+++ b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/IndexTypeReference.java
@@ -15,6 +15,7 @@ package org.eclipse.cdt.internal.core.browser;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.browser.TypeReference;
import org.eclipse.cdt.core.dom.ast.IBinding;
+import org.eclipse.cdt.core.index.IIndexMacro;
import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.internal.core.model.ext.CElementHandleFactory;
@@ -43,7 +44,17 @@ public class IndexTypeReference extends TypeReference {
super(resource, project, offset, length);
fCElement= createCElement(binding);
}
+
+ public IndexTypeReference(IIndexMacro macro, IPath path, IProject project, int offset, int length) {
+ super(path, project, offset, length);
+ fCElement= createCElement(macro);
+ }
+ public IndexTypeReference(IIndexMacro macro, IResource resource, IProject project, int offset, int length) {
+ super(resource, project, offset, length);
+ fCElement= createCElement(macro);
+ }
+
/**
* Compute the C element handle for the given binding.
* @param binding
@@ -62,6 +73,23 @@ public class IndexTypeReference extends TypeReference {
return null;
}
+ /**
+ * Compute the C element handle for the given macro.
+ */
+ private ICElement createCElement(IIndexMacro macro) {
+ ITranslationUnit tu= getTranslationUnit();
+ if (tu != null) {
+ long timestamp= tu.getResource() != null ? tu.getResource().getLocalTimeStamp() : 0;
+ IRegion region= new Region(getOffset(), getLength());
+ try {
+ return CElementHandleFactory.create(tu, macro, region, timestamp);
+ } catch (CoreException e) {
+ CCorePlugin.log(e);
+ }
+ }
+ return null;
+ }
+
/*
* @see org.eclipse.cdt.core.browser.ITypeReference#getCElements()
*/
diff --git a/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/util/IndexModelUtil.java b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/util/IndexModelUtil.java
index faed1859837..fb7b880d10f 100644
--- a/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/util/IndexModelUtil.java
+++ b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/util/IndexModelUtil.java
@@ -10,6 +10,7 @@
* IBM Corporation
* Andrew Ferguson (Symbian)
* Anton Leherbauer (Wind River Systems)
+ * Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.core.browser.util;
@@ -100,12 +101,16 @@ public class IndexModelUtil {
if (binding instanceof ICompositeType) {
ICompositeType classType = (ICompositeType) binding;
try {
- if(classType.getKey() == ICPPClassType.k_class) {
+ switch(classType.getKey()) {
+ case ICPPClassType.k_class:
elementType = ICElement.C_CLASS;
- } else if(classType.getKey() == ICPPClassType.k_struct) {
+ break;
+ case ICompositeType.k_struct:
elementType = ICElement.C_STRUCT;
- } else if(classType.getKey() == ICPPClassType.k_union) {
+ break;
+ case ICompositeType.k_union:
elementType = ICElement.C_UNION;
+ break;
}
} catch(DOMException de) {
CCorePlugin.log(de);
diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/ext/CElementHandleFactory.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/ext/CElementHandleFactory.java
index d54e6d818a9..7794c5e6afe 100644
--- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/ext/CElementHandleFactory.java
+++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/ext/CElementHandleFactory.java
@@ -32,6 +32,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateScope;
+import org.eclipse.cdt.core.index.IIndexMacro;
import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.core.runtime.CoreException;
@@ -55,7 +56,16 @@ public class CElementHandleFactory {
return null;
}
}
-
+
+ public static ICElementHandle create(ITranslationUnit tu, IIndexMacro macro,
+ IRegion region, long timestamp) throws CoreException {
+ CElementHandle element= new MacroHandle(tu, macro);
+ if (element != null && region != null) {
+ element.setRangeOfID(region, timestamp);
+ }
+ return element;
+ }
+
public static ICElementHandle internalCreate(ITranslationUnit tu, IBinding binding, boolean definition,
IRegion region, long timestamp) throws CoreException, DOMException {
diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/ext/MacroHandle.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/ext/MacroHandle.java
new file mode 100644
index 00000000000..acf1f45f39a
--- /dev/null
+++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/ext/MacroHandle.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2007 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.core.model.ext;
+
+import org.eclipse.cdt.core.index.IIndexMacro;
+import org.eclipse.cdt.core.model.ICElement;
+import org.eclipse.cdt.core.model.IMacro;
+import org.eclipse.cdt.core.model.ITranslationUnit;
+
+public class MacroHandle extends CElementHandle implements IMacro {
+
+ public MacroHandle(ITranslationUnit tu, IIndexMacro macro) {
+ super(tu, ICElement.C_MACRO, new String(macro.getName()));
+ }
+
+ public String getIdentifierList() {
+ return ""; //$NON-NLS-1$
+ }
+
+ public String getTokenSequence() {
+ return ""; //$NON-NLS-1$
+ }
+}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndex.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndex.java
index 67c7d62bcc0..1f41022f51b 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndex.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndex.java
@@ -59,7 +59,7 @@ public interface IIndex {
*/
final int FIND_DEFINITIONS = 0x2;
/**
- * Constant to search for all declarations including definitons.
+ * Constant to search for all declarations including definitions.
*/
final int FIND_REFERENCES = 0x4;
/**
@@ -67,7 +67,7 @@ public interface IIndex {
*/
final int FIND_DECLARATIONS_DEFINITIONS = FIND_DECLARATIONS | FIND_DEFINITIONS;
/**
- * Constant to search for all occurrences of a binding. This includes declarations, definitons and references.
+ * Constant to search for all occurrences of a binding. This includes declarations, definitions and references.
*/
final int FIND_ALL_OCCURENCES = FIND_DECLARATIONS | FIND_DEFINITIONS | FIND_REFERENCES;
@@ -185,6 +185,30 @@ public interface IIndex {
*/
public IIndexFile resolveInclude(IIndexInclude include) throws CoreException;
+ /**
+ * Searches for all macros with a given name.
+ *
+ * @param name a name, that has to be matched by the macros.
+ * @param filter a filter that allows for skipping parts of the index
+ * @param monitor a monitor to report progress, may be null
.
+ * @return an array of macros matching the name.
+ * @throws CoreException
+ * @since 4.0.2
+ */
+ public IIndexMacro[] findMacros(char[] name, IndexFilter filter, IProgressMonitor monitor) throws CoreException;
+
+ /**
+ * Searches for all macros with names that start with the given prefix.
+ *
+ * @param prefix the prefix with which all returned macros must start
+ * @param filter a filter that allows for skipping parts of the index
+ * @param monitor a monitor for progress reporting and cancellation, may be null
+ * @return an array of bindings with the prefix
+ * @throws CoreException
+ * @since 4.0.2
+ */
+ public IIndexMacro[] findMacrosForPrefix(char[] prefix, IndexFilter filter, IProgressMonitor monitor) throws CoreException;
+
/**
* Searches for the binding of a name. The name may be originated by
* an AST or by a search in an index. May return null
.
@@ -243,7 +267,7 @@ public interface IIndex {
*
* findBindings(new char[][]{name}, filter, monitor); *- * @param names an array of names, which has to be matched by the qualified name of the bindings. + * @param name a name, which has to be matched by the qualified name of the bindings. * @param filter a filter that allows for skipping parts of the index * @param monitor a monitor to report progress, may be
null
.
* @return an array of bindings matching the pattern
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexMacro.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexMacro.java
index bba86032949..d762d594720 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexMacro.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexMacro.java
@@ -13,6 +13,7 @@ package org.eclipse.cdt.core.index;
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
import org.eclipse.cdt.core.parser.IMacro;
+import org.eclipse.core.runtime.CoreException;
/**
* Represents a macro stored in the index.
@@ -30,11 +31,28 @@ import org.eclipse.cdt.core.parser.IMacro;
*/
public interface IIndexMacro extends IMacro {
+ IIndexMacro[] EMPTY_INDEX_MACRO_ARRAY = new IIndexMacro[0];
+
/**
* If available, return the file location for this macro definition
* otherwise return null
* @return
*/
IASTFileLocation getFileLocation();
+
+ /**
+ * Returns the file this macro belongs to.
+ * @throws CoreException
+ */
+ IIndexFile getFile() throws CoreException;
+
+ /**
+ * Returns the character offset of the location of the name.
+ */
+ public int getNodeOffset();
+ /**
+ * Returns the length of the name.
+ */
+ public int getNodeLength();
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/CIndex.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/CIndex.java
index 37880f0dc44..33ce7860361 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/CIndex.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/CIndex.java
@@ -34,6 +34,7 @@ import org.eclipse.cdt.core.index.IIndexBinding;
import org.eclipse.cdt.core.index.IIndexFile;
import org.eclipse.cdt.core.index.IIndexFileLocation;
import org.eclipse.cdt.core.index.IIndexInclude;
+import org.eclipse.cdt.core.index.IIndexMacro;
import org.eclipse.cdt.core.index.IIndexName;
import org.eclipse.cdt.core.index.IndexFilter;
import org.eclipse.cdt.internal.core.dom.Linkage;
@@ -486,7 +487,56 @@ public class CIndex implements IIndex {
return flatten(result);
}
}
+
+ public IIndexMacro[] findMacros(char[] name, IndexFilter filter, IProgressMonitor monitor) throws CoreException {
+ return findMacros(name, false, true, filter, monitor);
+ }
+ public IIndexMacro[] findMacrosForPrefix(char[] name, IndexFilter filter, IProgressMonitor monitor) throws CoreException {
+ return findMacros(name, true, false, filter, monitor);
+ }
+
+ private IIndexMacro[] findMacros(char[] name, boolean isPrefix, boolean caseSensitive, IndexFilter filter, IProgressMonitor monitor) throws CoreException {
+ if (SPECIALCASE_SINGLES && fFragments.length==1) {
+ try {
+ return fFragments[0].findMacros(name, isPrefix, caseSensitive, filter, monitor);
+ } catch (CoreException e) {
+ CCorePlugin.log(e);
+ return IIndexMacro.EMPTY_INDEX_MACRO_ARRAY;
+ }
+ } else {
+ if (monitor == null) {
+ monitor= new NullProgressMonitor();
+ }
+ List result = new ArrayList();
+ HashSet handledIFLs= new HashSet();
+ monitor.beginTask(Messages.CIndex_FindBindingsTask_label, fFragments.length);
+ for (int i = 0; i < fPrimaryFragmentCount; i++) {
+ HashSet allowedFiles= new HashSet();
+ try {
+ IIndexMacro[] macros= fFragments[i].findMacros(name, isPrefix, caseSensitive, filter, new SubProgressMonitor(monitor, 1));
+ for (int k = 0; k < macros.length; k++) {
+ IIndexMacro indexMacro = macros[k];
+ IIndexFile file= indexMacro.getFile();
+ if (!allowedFiles.contains(file)) {
+ if (handledIFLs.add(file.getLocation())) {
+ allowedFiles.add(file);
+ }
+ else {
+ continue;
+ }
+ }
+ result.add(indexMacro);
+ }
+ } catch (CoreException e) {
+ CCorePlugin.log(e);
+ }
+ }
+ monitor.done();
+ return (IIndexMacro[]) result.toArray(new IIndexMacro[result.size()]);
+ }
+ }
+
public long getCacheHits() {
long result= 0;
for (int i = 0; i < fFragments.length; i++) {
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/EmptyCIndex.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/EmptyCIndex.java
index 2e6205aa743..cc4d17df512 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/EmptyCIndex.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/EmptyCIndex.java
@@ -22,6 +22,7 @@ import org.eclipse.cdt.core.index.IIndexBinding;
import org.eclipse.cdt.core.index.IIndexFile;
import org.eclipse.cdt.core.index.IIndexFileLocation;
import org.eclipse.cdt.core.index.IIndexInclude;
+import org.eclipse.cdt.core.index.IIndexMacro;
import org.eclipse.cdt.core.index.IIndexName;
import org.eclipse.cdt.core.index.IndexFilter;
import org.eclipse.core.runtime.CoreException;
@@ -112,4 +113,12 @@ final public class EmptyCIndex implements IIndex {
IProgressMonitor monitor) {
return IIndexBinding.EMPTY_INDEX_BINDING_ARRAY;
}
+
+ public IIndexMacro[] findMacros(char[] name, IndexFilter filter, IProgressMonitor monitor) {
+ return IIndexMacro.EMPTY_INDEX_MACRO_ARRAY;
+ }
+
+ public IIndexMacro[] findMacrosForPrefix(char[] prefix, IndexFilter filter, IProgressMonitor monitor) {
+ return IIndexMacro.EMPTY_INDEX_MACRO_ARRAY;
+ }
}
\ No newline at end of file
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragment.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragment.java
index c79d3bf8407..6270560cfaa 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragment.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragment.java
@@ -20,6 +20,7 @@ import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.index.IIndexFileLocation;
import org.eclipse.cdt.core.index.IIndexLinkage;
+import org.eclipse.cdt.core.index.IIndexMacro;
import org.eclipse.cdt.core.index.IndexFilter;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
@@ -176,6 +177,12 @@ public interface IIndexFragment {
*/
IIndexFragmentBinding[] findBindingsForPrefix(char[] prefix, boolean filescope, IndexFilter filter, IProgressMonitor monitor) throws CoreException;
+ /**
+ * Returns all macros with the given prefix or name, accepted by the given filter
+ * @param monitor to report progress, may be null
+ */
+ IIndexMacro[] findMacros(char[] name, boolean isPrefix, boolean caseSensitive, IndexFilter filter, IProgressMonitor monitor) throws CoreException;
+
/**
* Returns the linkages that are contained in this fragment
* @return
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java
index 65df7b909e0..dc90c237ee2 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java
@@ -37,6 +37,7 @@ import org.eclipse.cdt.core.index.IIndexBinding;
import org.eclipse.cdt.core.index.IIndexFileLocation;
import org.eclipse.cdt.core.index.IIndexLinkage;
import org.eclipse.cdt.core.index.IIndexLocationConverter;
+import org.eclipse.cdt.core.index.IIndexMacro;
import org.eclipse.cdt.core.index.IIndexName;
import org.eclipse.cdt.core.index.IndexFilter;
import org.eclipse.cdt.internal.core.index.IIndexFragment;
@@ -51,11 +52,14 @@ import org.eclipse.cdt.internal.core.pdom.db.Database;
import org.eclipse.cdt.internal.core.pdom.db.IBTreeVisitor;
import org.eclipse.cdt.internal.core.pdom.dom.ApplyVisitor;
import org.eclipse.cdt.internal.core.pdom.dom.BindingCollector;
+import org.eclipse.cdt.internal.core.pdom.dom.FindBinding;
import org.eclipse.cdt.internal.core.pdom.dom.IPDOMLinkageFactory;
+import org.eclipse.cdt.internal.core.pdom.dom.MacroCollector;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMFile;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMInclude;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage;
+import org.eclipse.cdt.internal.core.pdom.dom.PDOMMacro;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMName;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode;
import org.eclipse.core.runtime.CoreException;
@@ -71,17 +75,16 @@ import org.eclipse.core.runtime.Status;
* @author Doug Schaefer
*/
public class PDOM extends PlatformObject implements IIndexFragment, IPDOM {
- protected Database db;
-
/**
* Identifier for PDOM format
* @see IIndexFragment#PROPERTY_FRAGMENT_FORMAT_ID
*/
public static final String FRAGMENT_PROPERTY_VALUE_FORMAT_ID= "org.eclipse.cdt.internal.core.pdom.PDOM"; //$NON-NLS-1$
- public static final int CURRENT_VERSION = 37;
+ public static final int CURRENT_VERSION = 38;
public static final int MIN_SUPPORTED_VERSION= 36;
public static final int MIN_VERSION_TO_WRITE_NESTED_BINDINGS_INDEX= 37; // to be removed in 4.1
+ public static final int MIN_VERSION_TO_WRITE_MACROS_INDEX= 38; // to be removed in 4.1
/*
* PDOM internal format history
@@ -126,24 +129,33 @@ public class PDOM extends PlatformObject implements IIndexFragment, IPDOM {
* 35 - add scanner configuration hash-code (62366)
* #36#- changed chunk size back to 4K (184892) - <true
a binding is considered if its name starts with the given prefix.
+ */
+ public MacroCollector(PDOM pdom, char[] name, boolean prefixLookup, boolean caseSensitive) {
+ this.name= name;
+ this.pdom= pdom;
+ this.prefixLookup= prefixLookup;
+ this.caseSensitive= caseSensitive;
+ }
+
+ /**
+ * Allows to cancel a visit. If set a visit may throw an OperationCancelledException.
+ * @since 4.0
+ */
+ public void setMonitor(IProgressMonitor pm) {
+ monitor= pm;
+ }
+
+ final public int compare(int record) throws CoreException {
+ if (monitor != null)
+ checkCancelled();
+ IString name= PDOMMacro.getNameInDB(pdom, record);
+ return compare(name);
+ }
+
+ private int compare(IString rhsName) throws CoreException {
+ int cmp;
+ if (prefixLookup) {
+ cmp= rhsName.comparePrefix(name, false);
+ if(caseSensitive) {
+ cmp= cmp==0 ? rhsName.comparePrefix(name, true) : cmp;
+ }
+ return cmp;
+ } else {
+ if(caseSensitive) {
+ cmp= rhsName.compareCompatibleWithIgnoreCase(name);
+ }
+ else {
+ cmp= rhsName.compare(name, false);
+ }
+ }
+ return cmp;
+ }
+
+ final public boolean visit(int record) throws CoreException {
+ if (monitor != null)
+ checkCancelled();
+
+ if (record == 0)
+ return true;
+
+ macros.add(new PDOMMacro(pdom, record));
+ return true; // look for more
+ }
+
+ final public List getMacroList() {
+ return macros;
+ }
+
+ private void checkCancelled() {
+ if (++monitorCheckCounter % 0x1000 == 0 && monitor.isCanceled()) {
+ throw new OperationCanceledException();
+ }
+ }
+}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMFile.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMFile.java
index 551287fa8a4..9bc83bba622 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMFile.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMFile.java
@@ -203,6 +203,7 @@ public class PDOMFile implements IIndexFragmentFile {
lastMacro.setNextMacro(pdomMacro);
}
lastMacro= pdomMacro;
+ pdom.afterAddMacro(pdomMacro);
}
}
@@ -259,6 +260,7 @@ public class PDOMFile implements IIndexFragmentFile {
// Delete all the macros in this file
PDOMMacro macro = getFirstMacro();
while (macro != null) {
+ pdom.beforeRemoveMacro(macro);
PDOMMacro nextMacro = macro.getNextMacro();
macro.delete();
macro = nextMacro;
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMMacro.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMMacro.java
index e16c070667a..976830b49cb 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMMacro.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMMacro.java
@@ -92,7 +92,7 @@ public class PDOMMacro implements IIndexMacro, IASTFileLocation {
}
public void delete() throws CoreException {
- getNameInDB().delete();
+ getNameInDB(pdom, record).delete();
getExpansionInDB().delete();
PDOMMacroParameter param = getFirstParameter();
if (param != null)
@@ -100,7 +100,7 @@ public class PDOMMacro implements IIndexMacro, IASTFileLocation {
pdom.getDB().free(record);
}
- public IString getNameInDB() throws CoreException {
+ public static IString getNameInDB(PDOM pdom, int record) throws CoreException {
Database db = pdom.getDB();
int rec = db.getInt(record + NAME);
return db.getString(rec);
@@ -140,6 +140,15 @@ public class PDOMMacro implements IIndexMacro, IASTFileLocation {
public IASTFileLocation getFileLocation() {
return PDOMMacro.this;
}
+ public IIndexFile getFile() throws CoreException {
+ return PDOMMacro.this.getFile();
+ }
+ public int getNodeOffset() {
+ return PDOMMacro.this.getNodeOffset();
+ }
+ public int getNodeLength() {
+ return PDOMMacro.this.getNodeLength();
+ }
}
private class FunctionStylePDOMMacro extends FunctionStyleMacro implements IIndexMacro {
@@ -152,6 +161,15 @@ public class PDOMMacro implements IIndexMacro, IASTFileLocation {
public IASTFileLocation getFileLocation() {
return PDOMMacro.this;
}
+ public IIndexFile getFile() throws CoreException {
+ return PDOMMacro.this.getFile();
+ }
+ public int getNodeOffset() {
+ return PDOMMacro.this.getNodeOffset();
+ }
+ public int getNodeLength() {
+ return PDOMMacro.this.getNodeLength();
+ }
}
private char[] getMacroExpansion() {
@@ -169,7 +187,7 @@ public class PDOMMacro implements IIndexMacro, IASTFileLocation {
}
private void rebuildMacro() throws CoreException {
- char[] name = getNameInDB().getChars();
+ char[] name = getNameInDB(pdom, record).getChars();
PDOMMacroParameter param = getFirstParameter();
if (param != null) {
List paramList = new ArrayList();
@@ -205,12 +223,11 @@ public class PDOMMacro implements IIndexMacro, IASTFileLocation {
public char[] getName() {
try {
- rebuildMacro();
+ return getNameInDB(pdom, record).getChars();
} catch (CoreException e) {
CCorePlugin.log(e);
return new char[] { ' ' };
}
- return macro.getName();
}
public IIndexFile getFile() throws CoreException {
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/export/GeneratePDOM.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/export/GeneratePDOM.java
index a6c8981ba70..df5e2811f87 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/export/GeneratePDOM.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/export/GeneratePDOM.java
@@ -80,9 +80,10 @@ public class GeneratePDOM implements ISafeRunnable {
exportedPDOM.setProperty((String) entry.getKey(), (String) entry.getValue());
}
}
- // fake version of pdom, such that it works with CDT 4.0.0, also.
- if (PDOM.CURRENT_VERSION == PDOM.MIN_VERSION_TO_WRITE_NESTED_BINDINGS_INDEX) {
- exportedPDOM.getDB().setVersion(PDOM.CURRENT_VERSION-1);
+ // fake version of pdom, such that it works with CDT 4.0.0 and CDT 4.0.1, also.
+ // can be removed in CDT 5.0
+ if (PDOM.CURRENT_VERSION == PDOM.MIN_VERSION_TO_WRITE_MACROS_INDEX) {
+ exportedPDOM.getDB().setVersion(PDOM.CURRENT_VERSION-2);
}
exportedPDOM.close();
}
diff --git a/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/opentype/ElementSelectionDialog.java b/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/opentype/ElementSelectionDialog.java
index 9b673734650..dc2e36b715a 100644
--- a/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/opentype/ElementSelectionDialog.java
+++ b/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/opentype/ElementSelectionDialog.java
@@ -12,9 +12,8 @@
package org.eclipse.cdt.internal.ui.browser.opentype;
-import java.util.ArrayList;
import java.util.Arrays;
-import java.util.List;
+import java.util.HashSet;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
@@ -40,10 +39,13 @@ import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.browser.ITypeInfo;
import org.eclipse.cdt.core.browser.IndexTypeInfo;
import org.eclipse.cdt.core.browser.QualifiedTypeName;
+import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.index.IIndexBinding;
+import org.eclipse.cdt.core.index.IIndexMacro;
import org.eclipse.cdt.core.index.IndexFilter;
import org.eclipse.cdt.core.model.CoreModel;
+import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.ui.browser.typeinfo.TypeSelectionDialog;
import org.eclipse.cdt.internal.core.browser.util.IndexModelUtil;
@@ -232,24 +234,40 @@ public class ElementSelectionDialog extends TypeSelectionDialog {
if (monitor.isCanceled()) {
return null;
}
- List types = new ArrayList();
+ HashSet types = new HashSet();
if(prefix.length > 0 || fAllowEmptyPrefix) {
+ final IndexFilter filter= new IndexFilter() {
+ public boolean acceptBinding(IBinding binding) throws CoreException {
+ if (isVisibleType(IndexModelUtil.getElementType(binding))) {
+ if (IndexFilter.ALL_DECLARED.acceptBinding(binding)) {
+ // until we have correctly modeled file-local variables and functions, don't show them.
+ return !((IIndexBinding) binding).isFileLocal();
+ }
+ }
+ return false;
+ }
+ };
try {
IIndex index = CCorePlugin.getIndexManager().getIndex(CoreModel.getDefault().getCModel().getCProjects());
try {
index.acquireReadLock();
- IIndexBinding[] bindings= index.findBindingsForPrefix(prefix, false, IndexFilter.ALL_DECLARED, monitor);
+ IIndexBinding[] bindings= index.findBindingsForPrefix(prefix, false, filter, monitor);
for(int i=0; i