From 4e91bb54ab7237c04102517236b80178a83f8899 Mon Sep 17 00:00:00 2001
From: Markus Schorn
Date: Mon, 3 Mar 2008 15:05:11 +0000
Subject: Navigating an argument of a macro-expansion, bug 208300.
---
.../cdt/core/index/IndexLocationFactory.java | 13 +-
.../internal/core/dom/parser/ASTNodeMatchKind.java | 20 ++-
.../eclipse/cdt/internal/core/index/CIndex.java | 3 +
.../core/parser/scanner/ASTPreprocessorNode.java | 2 +-
.../parser/scanner/FindNodeByImageLocation.java | 191 +++++++++++++++++++++
.../parser/scanner/LocationCtxMacroExpansion.java | 3 +-
.../internal/core/parser/scanner/LocationMap.java | 35 +++-
.../internal/core/pdom/AbstractIndexerTask.java | 7 +
8 files changed, 254 insertions(+), 20 deletions(-)
create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/FindNodeByImageLocation.java
(limited to 'core/org.eclipse.cdt.core/parser')
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IndexLocationFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IndexLocationFactory.java
index a47f2301d21..a8bdaed3f8e 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IndexLocationFactory.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IndexLocationFactory.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2006, 2007 Symbian Software Ltd. and others.
+ * Copyright (c) 2006, 2008 Symbian Software Ltd. 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
@@ -10,6 +10,8 @@
*******************************************************************************/
package org.eclipse.cdt.core.index;
+import java.net.URI;
+
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.internal.core.index.IndexFileLocation;
@@ -120,12 +122,17 @@ public class IndexLocationFactory {
}
/**
- * Returns an IIndexFileLocation for the specified workspace file
+ * Returns an IIndexFileLocation for the specified workspace file, or null
if it does not
+ * have a location.
* @param file
* @return an IIndexFileLocation for the specified workspace file
*/
public static IIndexFileLocation getWorkspaceIFL(IFile file) {
- return new IndexFileLocation(file.getLocationURI(), file.getFullPath().toString());
+ final URI locationURI = file.getLocationURI();
+ if (locationURI != null) {
+ return new IndexFileLocation(locationURI, file.getFullPath().toString());
+ }
+ return null;
}
/**
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTNodeMatchKind.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTNodeMatchKind.java
index ff4a186f9d3..20acf3266c5 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTNodeMatchKind.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTNodeMatchKind.java
@@ -48,12 +48,18 @@ public class ASTNodeMatchKind {
* Returns whether the node matches the selection.
*/
public boolean matches(ASTNode node, int selOffset, int selLength) {
- if (fNamesOnly && node instanceof IASTName == false) {
- return false;
- }
-
- final int nodeOffset= node.getOffset();
- final int nodeLength= node.getLength();
+ return isAcceptableNode(node) && rangeMatches(node.getOffset(), node.getLength(), selOffset, selLength);
+ }
+
+ public boolean isAcceptableNode(ASTNode astNode) {
+ return !fNamesOnly || astNode instanceof IASTName;
+ }
+
+ /**
+ * Returns whether the node range matches the selection.
+ */
+ public boolean rangeMatches(final int nodeOffset, final int nodeLength, int selOffset,
+ int selLength) {
switch(fRelation) {
case EXACT:
return selOffset == nodeOffset && selLength == nodeLength;
@@ -63,7 +69,7 @@ public class ASTNodeMatchKind {
return nodeOffset <= selOffset && selOffset+selLength <= nodeOffset+nodeLength;
default:
assert false;
- return false;
+ return false;
}
}
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 d799499567d..f9784997b44 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
@@ -187,6 +187,9 @@ public class CIndex implements IIndex {
}
public IIndexFile[] getFiles(IIndexFileLocation location) throws CoreException {
+ if (location == null) {
+ return IIndexFile.EMPTY_FILE_ARRAY;
+ }
ArrayList result= new ArrayList();
BitSet linkages= new BitSet();
for (int i = 0; i < fPrimaryFragmentCount; i++) {
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ASTPreprocessorNode.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ASTPreprocessorNode.java
index 3563065d0c8..fa8f7cbdae1 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ASTPreprocessorNode.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ASTPreprocessorNode.java
@@ -413,7 +413,7 @@ class ASTUndef extends ASTPreprocessorNode implements IASTPreprocessorUndefState
fName= new ASTPreprocessorName(this, IASTPreprocessorUndefStatement.MACRO_NAME, nameNumber, nameEndNumber, name, binding);
}
- public IASTName getMacroName() {
+ public ASTPreprocessorName getMacroName() {
return fName;
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/FindNodeByImageLocation.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/FindNodeByImageLocation.java
new file mode 100644
index 00000000000..189b092f6aa
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/FindNodeByImageLocation.java
@@ -0,0 +1,191 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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.parser.scanner;
+
+import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
+import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
+import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
+import org.eclipse.cdt.core.dom.ast.IASTExpression;
+import org.eclipse.cdt.core.dom.ast.IASTImageLocation;
+import org.eclipse.cdt.core.dom.ast.IASTInitializer;
+import org.eclipse.cdt.core.dom.ast.IASTName;
+import org.eclipse.cdt.core.dom.ast.IASTNode;
+import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
+import org.eclipse.cdt.core.dom.ast.IASTProblem;
+import org.eclipse.cdt.core.dom.ast.IASTStatement;
+import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
+import org.eclipse.cdt.core.dom.ast.IASTTypeId;
+import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator;
+import org.eclipse.cdt.core.dom.ast.c.ICASTDesignator;
+import org.eclipse.cdt.core.dom.ast.c.ICASTVisitor;
+import org.eclipse.cdt.core.dom.ast.cpp.CPPASTVisitor;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateParameter;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTVisitor;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
+import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
+import org.eclipse.cdt.internal.core.dom.parser.ASTNodeMatchKind;
+
+public class FindNodeByImageLocation extends CPPASTVisitor implements ICASTVisitor, ICPPASTVisitor {
+ private ASTNode fCandidate= null;
+ private final int fOffset;
+ private final int fLength;
+ private final ASTNodeMatchKind fMatchKind;
+ private int fImageOffset;
+ private int fImageLength;
+
+ public FindNodeByImageLocation(int offset, int length, int imgOffset, int imgLength, ASTNodeMatchKind matchKind) {
+ fMatchKind= matchKind;
+ fOffset = offset;
+ fLength = length;
+ fImageOffset= imgOffset;
+ fImageLength= imgLength;
+
+ shouldVisitNames = true;
+ shouldVisitDeclarations= true;
+
+ shouldVisitInitializers=
+ shouldVisitParameterDeclarations=
+ shouldVisitDeclarators=
+ shouldVisitDeclSpecifiers=
+ shouldVisitDesignators=
+ shouldVisitEnumerators=
+ shouldVisitExpressions=
+ shouldVisitStatements=
+ shouldVisitTypeIds=
+ shouldVisitEnumerators=
+ shouldVisitBaseSpecifiers=
+ shouldVisitNamespaces=
+ shouldVisitTemplateParameters=
+ shouldVisitTranslationUnit= !matchKind.matchNamesOnly();
+ }
+
+ public int processNode(IASTNode node) {
+ if (node instanceof ASTNode) {
+ final ASTNode astNode = (ASTNode) node;
+ if (astNode.getOffset() > fOffset+fLength || astNode.getOffset() + astNode.getLength() < fOffset) {
+ return PROCESS_SKIP;
+ }
+
+ if (fMatchKind.isAcceptableNode(astNode)) {
+ IASTImageLocation imageLocation= astNode.getImageLocation();
+ if (imageLocation != null && imageLocation.getLocationKind() == IASTImageLocation.ARGUMENT_TO_MACRO_EXPANSION) {
+ if (fMatchKind.rangeMatches(imageLocation.getNodeOffset(), imageLocation.getNodeLength(), fImageOffset, fImageLength)) {
+ if (fCandidate == null || !fMatchKind.isBetterMatch(fCandidate, astNode)) {
+ fCandidate= astNode;
+ }
+ }
+ }
+ }
+ }
+ return PROCESS_CONTINUE;
+ }
+
+ @Override
+ public int visit(IASTDeclaration declaration) {
+ // use declarations to determine if the search has gone past the
+ // offset (i.e. don't know the order the visitor visits the nodes)
+ if (declaration instanceof ASTNode && ((ASTNode) declaration).getOffset() > fOffset + fLength)
+ return PROCESS_ABORT;
+
+ return processNode(declaration);
+ }
+
+ @Override
+ public int visit(IASTDeclarator declarator) {
+ return processNode(declarator);
+ }
+
+ @Override
+ public int visit(IASTDeclSpecifier declSpec) {
+ return processNode(declSpec);
+ }
+
+ @Override
+ public int visit(IASTEnumerator enumerator) {
+ return processNode(enumerator);
+ }
+
+ @Override
+ public int visit(IASTExpression expression) {
+ return processNode(expression);
+ }
+
+ @Override
+ public int visit(IASTInitializer initializer) {
+ return processNode(initializer);
+ }
+
+ @Override
+ public int visit(IASTName name) {
+ if (name.toString() != null)
+ return processNode(name);
+ return PROCESS_CONTINUE;
+ }
+
+ @Override
+ public int visit(IASTParameterDeclaration parameterDeclaration) {
+ return processNode(parameterDeclaration);
+ }
+
+ @Override
+ public int visit(IASTStatement statement) {
+ return processNode(statement);
+ }
+
+ @Override
+ public int visit(IASTTypeId typeId) {
+ return processNode(typeId);
+ }
+
+ @Override
+ public int visit(ICPPASTBaseSpecifier baseSpecifier) {
+ return processNode(baseSpecifier);
+ }
+
+ @Override
+ public int visit(ICPPASTNamespaceDefinition namespaceDefinition) {
+ return processNode(namespaceDefinition);
+ }
+
+ @Override
+ public int visit(ICPPASTTemplateParameter templateParameter) {
+ return processNode(templateParameter);
+ }
+
+ @Override
+ public int visit(IASTProblem problem) {
+ return processNode(problem);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.internal.core.dom.parser.c.CVisitor.CBaseVisitorAction#processDesignator(org.eclipse.cdt.core.dom.ast.c.ICASTDesignator)
+ */
+ public int visit(ICASTDesignator designator) {
+ return processNode(designator);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.dom.ast.c.ICASTVisitor#leave(org.eclipse.cdt.core.dom.ast.c.ICASTDesignator)
+ */
+ public int leave(ICASTDesignator designator) {
+ return PROCESS_CONTINUE;
+ }
+
+ @Override
+ public int visit(IASTTranslationUnit tu) {
+ return processNode(tu);
+ }
+
+ public ASTNode getNode() {
+ return fCandidate;
+ }
+}
\ No newline at end of file
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/LocationCtxMacroExpansion.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/LocationCtxMacroExpansion.java
index 0dc39f5a8c0..753203b6b44 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/LocationCtxMacroExpansion.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/LocationCtxMacroExpansion.java
@@ -13,7 +13,6 @@ package org.eclipse.cdt.internal.core.parser.scanner;
import java.util.ArrayList;
import org.eclipse.cdt.core.dom.ast.IASTImageLocation;
-import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNodeLocation;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroDefinition;
import org.eclipse.cdt.core.dom.ast.IMacroBinding;
@@ -130,7 +129,7 @@ class LocationCtxMacroExpansion extends LocationCtx {
return null;
}
- public IASTName[] getNestedMacroReferences() {
+ public ASTPreprocessorName[] getNestedMacroReferences() {
return fLocationMap.getNestedMacroReferences((ASTMacroExpansion) fExpansionName.getParent());
}
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/LocationMap.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/LocationMap.java
index b0b54f63ce2..9b300aa3e09 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/LocationMap.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/LocationMap.java
@@ -51,7 +51,7 @@ public class LocationMap implements ILocationResolver {
private ArrayList fProblems= new ArrayList();
private ArrayList fComments= new ArrayList();
private ArrayList fBuiltinMacros= new ArrayList();
- private ArrayList fMacroReferences= new ArrayList();
+ private ArrayList fMacroReferences= new ArrayList();
private LocationCtxFile fRootContext= null;
private LocationCtx fCurrentContext= null;
@@ -176,7 +176,7 @@ public class LocationMap implements ILocationResolver {
return fCurrentContext;
}
- private void addMacroReference(IASTName name) {
+ private void addMacroReference(ASTPreprocessorName name) {
fMacroReferences.add(name);
}
@@ -460,7 +460,28 @@ public class LocationMap implements ILocationResolver {
// search for a macro-expansion
LocationCtxMacroExpansion ctx= fRootContext.findSurroundingMacroExpansion(sequenceNumber, length);
if (ctx != null) {
- return ctx.findNode(sequenceNumber, length, matchKind);
+ ASTNode candidate= ctx.findNode(sequenceNumber, length, matchKind);
+ int imageOffset= ctx.fEndOffsetInParent + sequenceNumber - ctx.fSequenceNumber;
+ if (fTranslationUnit != null) {
+ FindNodeByImageLocation visitor= new FindNodeByImageLocation(ctx.fSequenceNumber, ctx.getSequenceLength(), imageOffset, length, matchKind);
+ fTranslationUnit.accept(visitor);
+ ASTNode candidate2= visitor.getNode();
+ if (matchKind.isBetterMatch(candidate2, candidate)) {
+ candidate= candidate2;
+ }
+ }
+ ASTPreprocessorName[] nested= ctx.getNestedMacroReferences();
+ for (ASTPreprocessorName name : nested) {
+ IASTImageLocation imageLoc= name.getImageLocation();
+ if (imageLoc != null && imageLoc.getLocationKind() == IASTImageLocation.ARGUMENT_TO_MACRO_EXPANSION) {
+ if (matchKind.rangeMatches(imageLoc.getNodeOffset(), imageLoc.getNodeLength(), imageOffset, length)) {
+ if (matchKind.isBetterMatch(name, candidate)) {
+ candidate= name;
+ }
+ }
+ }
+ }
+ return candidate;
}
return null;
@@ -590,15 +611,15 @@ public class LocationMap implements ILocationResolver {
return result.toArray(new IASTName[result.size()]);
}
- public IASTName[] getNestedMacroReferences(ASTMacroExpansion expansion) {
+ public ASTPreprocessorName[] getNestedMacroReferences(ASTMacroExpansion expansion) {
final IASTName explicitRef= expansion.getMacroReference();
- List result= new ArrayList();
- for (IASTName name : fMacroReferences) {
+ List result= new ArrayList();
+ for (ASTPreprocessorName name : fMacroReferences) {
if (name.getParent() == expansion && name != explicitRef) {
result.add(name);
}
}
- return result.toArray(new IASTName[result.size()]);
+ return result.toArray(new ASTPreprocessorName[result.size()]);
}
public IDependencyTree getDependencyTree() {
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/AbstractIndexerTask.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/AbstractIndexerTask.java
index a38c15f5111..3974161d378 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/AbstractIndexerTask.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/AbstractIndexerTask.java
@@ -249,6 +249,9 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
final Object tu= fFilesToUpdate[i];
final IIndexFileLocation ifl= fResolver.resolveFile(tu);
+ if (ifl == null)
+ continue;
+
final boolean isSourceUnit= fResolver.isSourceUnit(tu);
final boolean isExcludedSource= isSourceUnit && !fIndexFilesWithoutConfiguration && !fResolver.isFileBuildConfigured(tu);
final IIndexFragmentFile[] indexFiles= fIndex.getWritableFiles(ifl);
@@ -393,6 +396,8 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
}
final Object tu = iterator.next();
IIndexFileLocation ifl= fResolver.resolveFile(tu);
+ if (ifl == null)
+ continue;
IIndexFragmentFile[] ifiles= fIndex.getWritableFiles(ifl);
for (int i = 0; i < ifiles.length; i++) {
IIndexFragmentFile ifile = ifiles[i];
@@ -470,6 +475,8 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
return;
final Object tu= iter.next();
final IIndexFileLocation ifl = fResolver.resolveFile(tu);
+ if (ifl == null)
+ continue;
final FileContent info= getFileInfo(linkageID, ifl);
if (info != null && info.fRequestUpdate && !info.fIsUpdated) {
info.fRequestIsCounted= false;
--
cgit v1.2.3