mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-08-07 16:26:11 +02:00
Bug 399394: Include macro expansions yielding the empty token in IASTNode.getNodeLocations()
This commit is contained in:
parent
47373b6644
commit
b4401b6198
4 changed files with 56 additions and 23 deletions
|
@ -57,9 +57,11 @@ import org.eclipse.cdt.core.dom.ast.IASTInitializer;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTInitializerList;
|
import org.eclipse.cdt.core.dom.ast.IASTInitializerList;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTLabelStatement;
|
import org.eclipse.cdt.core.dom.ast.IASTLabelStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTLiteralExpression;
|
import org.eclipse.cdt.core.dom.ast.IASTLiteralExpression;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTMacroExpansionLocation;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTNamedTypeSpecifier;
|
import org.eclipse.cdt.core.dom.ast.IASTNamedTypeSpecifier;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTNodeLocation;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTNullStatement;
|
import org.eclipse.cdt.core.dom.ast.IASTNullStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
|
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
|
import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
|
||||||
|
@ -7426,4 +7428,29 @@ public class AST2Tests extends AST2TestBase {
|
||||||
public void testNoRawStringInPlainC_397127() throws Exception {
|
public void testNoRawStringInPlainC_397127() throws Exception {
|
||||||
parseAndCheckBindings(getAboveComment(), C, true);
|
parseAndCheckBindings(getAboveComment(), C, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// #define X
|
||||||
|
// int a=X-1;X
|
||||||
|
public void testMacroReferences_399394() throws Exception {
|
||||||
|
IASTTranslationUnit tu= parseAndCheckBindings(getAboveComment());
|
||||||
|
assertEquals(2, countMacroRefs(tu));
|
||||||
|
|
||||||
|
IASTSimpleDeclaration decl= getDeclaration(tu, 0);
|
||||||
|
assertEquals(1, countMacroRefs(decl));
|
||||||
|
|
||||||
|
IASTEqualsInitializer init= (IASTEqualsInitializer) decl.getDeclarators()[0].getInitializer();
|
||||||
|
assertEquals(1, countMacroRefs(init));
|
||||||
|
|
||||||
|
IASTUnaryExpression expr= (IASTUnaryExpression) init.getInitializerClause();
|
||||||
|
assertEquals(0, countMacroRefs(expr));
|
||||||
|
}
|
||||||
|
|
||||||
|
private int countMacroRefs(IASTNode node) {
|
||||||
|
int count = 0;
|
||||||
|
for (IASTNodeLocation loc : node.getNodeLocations()) {
|
||||||
|
if (loc instanceof IASTMacroExpansionLocation)
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -130,7 +130,7 @@ abstract class LocationCtx implements ILocationCtx {
|
||||||
* Returns the sequence of file locations spanning the given range.
|
* Returns the sequence of file locations spanning the given range.
|
||||||
* Assumes that the range starts within this context.
|
* Assumes that the range starts within this context.
|
||||||
*/
|
*/
|
||||||
public abstract boolean collectLocations(int sequenceNumber, int length, ArrayList<IASTNodeLocation> sofar);
|
public abstract void collectLocations(int sequenceNumber, int length, ArrayList<IASTNodeLocation> sofar);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Support for the dependency tree, add inclusion statements found in this context.
|
* Support for the dependency tree, add inclusion statements found in this context.
|
||||||
|
|
|
@ -32,7 +32,7 @@ class LocationCtxContainer extends LocationCtx {
|
||||||
private int fChildSequenceLength;
|
private int fChildSequenceLength;
|
||||||
|
|
||||||
private ArrayList<LocationCtx> fChildren;
|
private ArrayList<LocationCtx> fChildren;
|
||||||
private AbstractCharArray fSource;
|
private final AbstractCharArray fSource;
|
||||||
private int[] fLineOffsets;
|
private int[] fLineOffsets;
|
||||||
|
|
||||||
public LocationCtxContainer(LocationCtxContainer parent, AbstractCharArray source,
|
public LocationCtxContainer(LocationCtxContainer parent, AbstractCharArray source,
|
||||||
|
@ -138,47 +138,55 @@ class LocationCtxContainer extends LocationCtx {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean collectLocations(int sequenceNumber, final int length, ArrayList<IASTNodeLocation> locations) {
|
public void collectLocations(int sequenceNumber, final int length, ArrayList<IASTNodeLocation> locations) {
|
||||||
|
if (length < 1)
|
||||||
|
return;
|
||||||
|
|
||||||
final int endSequenceNumber= sequenceNumber + length;
|
final int endSequenceNumber= sequenceNumber + length;
|
||||||
if (fChildren != null) {
|
if (fChildren != null) {
|
||||||
int childIdx= Math.max(0, findChildIdxLessOrEqualThan(sequenceNumber, false));
|
int childIdx= Math.max(0, findChildIdxLessOrEqualThan(sequenceNumber, false));
|
||||||
for (; childIdx < fChildren.size(); childIdx++) {
|
for (; childIdx < fChildren.size(); childIdx++) {
|
||||||
final LocationCtx child= fChildren.get(childIdx);
|
final LocationCtx child= fChildren.get(childIdx);
|
||||||
|
|
||||||
// create the location between start and the child
|
// Create the location between start and the child
|
||||||
if (sequenceNumber < child.fSequenceNumber) {
|
if (sequenceNumber < child.fSequenceNumber) {
|
||||||
// compute offset backwards from the child's offset
|
// Compute offset backwards from the child's offset in this location
|
||||||
final int offset= child.fEndOffsetInParent - (child.fSequenceNumber - sequenceNumber);
|
final int offset= child.fEndOffsetInParent - (child.fSequenceNumber - sequenceNumber);
|
||||||
// it the child is not affected, we are done.
|
|
||||||
|
// Requested range ends before the child.
|
||||||
if (endSequenceNumber <= child.fSequenceNumber) {
|
if (endSequenceNumber <= child.fSequenceNumber) {
|
||||||
addFileLocation(offset, endSequenceNumber - sequenceNumber, locations);
|
addFileLocation(offset, endSequenceNumber - sequenceNumber, locations);
|
||||||
return true;
|
return;
|
||||||
}
|
}
|
||||||
if (offset < child.fOffsetInParent)
|
|
||||||
|
final int gapLen = child.fOffsetInParent - offset;
|
||||||
|
if (gapLen > 0)
|
||||||
addFileLocation(offset, child.fOffsetInParent - offset, locations);
|
addFileLocation(offset, child.fOffsetInParent - offset, locations);
|
||||||
|
|
||||||
sequenceNumber= child.fSequenceNumber;
|
sequenceNumber= child.fSequenceNumber;
|
||||||
|
assert sequenceNumber < endSequenceNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
// let the child create locations
|
// Let the child create locations
|
||||||
final int childEndSequenceNumber= child.fSequenceNumber + child.getSequenceLength();
|
final int childEndSequenceNumber= child.fSequenceNumber + child.getSequenceLength();
|
||||||
if (sequenceNumber < childEndSequenceNumber) {
|
if (sequenceNumber < childEndSequenceNumber
|
||||||
if (child.collectLocations(sequenceNumber, endSequenceNumber - sequenceNumber, locations)) {
|
|| (sequenceNumber == childEndSequenceNumber && !locations.isEmpty())) {
|
||||||
return true;
|
child.collectLocations(sequenceNumber, endSequenceNumber - sequenceNumber, locations);
|
||||||
}
|
|
||||||
sequenceNumber= childEndSequenceNumber;
|
sequenceNumber= childEndSequenceNumber;
|
||||||
|
if (sequenceNumber >= endSequenceNumber)
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// create the location after the last child.
|
// Create the location after the last child.
|
||||||
final int myEndNumber = fSequenceNumber + getSequenceLength();
|
final int myEndNumber = fSequenceNumber + getSequenceLength();
|
||||||
final int offset= fSource.getLength() - (myEndNumber - sequenceNumber);
|
final int offset= fSource.getLength() - (myEndNumber - sequenceNumber);
|
||||||
if (endSequenceNumber <= myEndNumber) {
|
if (endSequenceNumber <= myEndNumber) {
|
||||||
addFileLocation(offset, endSequenceNumber - sequenceNumber, locations);
|
addFileLocation(offset, endSequenceNumber - sequenceNumber, locations);
|
||||||
return true;
|
} else {
|
||||||
}
|
|
||||||
addFileLocation(offset, fSource.getLength() - offset, locations);
|
addFileLocation(offset, fSource.getLength() - offset, locations);
|
||||||
return false;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private ArrayList<IASTNodeLocation> addFileLocation(int offset, int length, ArrayList<IASTNodeLocation> sofar) {
|
private ArrayList<IASTNodeLocation> addFileLocation(int offset, int length, ArrayList<IASTNodeLocation> sofar) {
|
||||||
|
|
|
@ -25,7 +25,7 @@ class LocationCtxMacroExpansion extends LocationCtx {
|
||||||
private final LocationMap fLocationMap;
|
private final LocationMap fLocationMap;
|
||||||
private final int fLength;
|
private final int fLength;
|
||||||
private final ImageLocationInfo[] fLocationInfos;
|
private final ImageLocationInfo[] fLocationInfos;
|
||||||
private ASTMacroReferenceName fExpansionName;
|
private final ASTMacroReferenceName fExpansionName;
|
||||||
|
|
||||||
public LocationCtxMacroExpansion(LocationMap map, LocationCtxContainer parent, int parentOffset, int parentEndOffset,
|
public LocationCtxMacroExpansion(LocationMap map, LocationCtxContainer parent, int parentOffset, int parentEndOffset,
|
||||||
int sequenceNumber, int length, ImageLocationInfo[] imageLocations, ASTMacroReferenceName expansionName) {
|
int sequenceNumber, int length, ImageLocationInfo[] imageLocations, ASTMacroReferenceName expansionName) {
|
||||||
|
@ -45,17 +45,15 @@ class LocationCtxMacroExpansion extends LocationCtx {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean collectLocations(int start, int length, ArrayList<IASTNodeLocation> locations) {
|
public void collectLocations(int start, int length, ArrayList<IASTNodeLocation> locations) {
|
||||||
final int offset= start - fSequenceNumber;
|
final int offset= start - fSequenceNumber;
|
||||||
assert offset >= 0 && length >= 0;
|
assert offset >= 0 && length >= 0;
|
||||||
|
|
||||||
if (offset + length <= fLength) {
|
if (offset + length <= fLength) {
|
||||||
locations.add(new ASTMacroExpansionLocation(this, offset, length));
|
locations.add(new ASTMacroExpansionLocation(this, offset, length));
|
||||||
return true;
|
} else {
|
||||||
}
|
|
||||||
|
|
||||||
locations.add(new ASTMacroExpansionLocation(this, offset, fLength-offset));
|
locations.add(new ASTMacroExpansionLocation(this, offset, fLength-offset));
|
||||||
return false;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ASTMacroExpansion getExpansion() {
|
public ASTMacroExpansion getExpansion() {
|
||||||
|
|
Loading…
Add table
Reference in a new issue