1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Bug 399394: Include macro expansions yielding the empty token in IASTNode.getNodeLocations()

This commit is contained in:
Markus Schorn 2013-01-31 10:35:40 +01:00
parent 47373b6644
commit b4401b6198
4 changed files with 56 additions and 23 deletions

View file

@ -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.IASTLabelStatement;
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.IASTNamedTypeSpecifier;
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.IASTParameterDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
@ -7426,4 +7428,29 @@ public class AST2Tests extends AST2TestBase {
public void testNoRawStringInPlainC_397127() throws Exception {
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;
}
}

View file

@ -130,7 +130,7 @@ abstract class LocationCtx implements ILocationCtx {
* Returns the sequence of file locations spanning the given range.
* 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.

View file

@ -32,7 +32,7 @@ class LocationCtxContainer extends LocationCtx {
private int fChildSequenceLength;
private ArrayList<LocationCtx> fChildren;
private AbstractCharArray fSource;
private final AbstractCharArray fSource;
private int[] fLineOffsets;
public LocationCtxContainer(LocationCtxContainer parent, AbstractCharArray source,
@ -138,47 +138,55 @@ class LocationCtxContainer extends LocationCtx {
}
@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;
if (fChildren != null) {
int childIdx= Math.max(0, findChildIdxLessOrEqualThan(sequenceNumber, false));
for (; childIdx < fChildren.size(); 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) {
// 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);
// it the child is not affected, we are done.
// Requested range ends before the child.
if (endSequenceNumber <= child.fSequenceNumber) {
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);
sequenceNumber= child.fSequenceNumber;
assert sequenceNumber < endSequenceNumber;
}
// let the child create locations
// Let the child create locations
final int childEndSequenceNumber= child.fSequenceNumber + child.getSequenceLength();
if (sequenceNumber < childEndSequenceNumber) {
if (child.collectLocations(sequenceNumber, endSequenceNumber - sequenceNumber, locations)) {
return true;
}
if (sequenceNumber < childEndSequenceNumber
|| (sequenceNumber == childEndSequenceNumber && !locations.isEmpty())) {
child.collectLocations(sequenceNumber, endSequenceNumber - sequenceNumber, locations);
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 offset= fSource.getLength() - (myEndNumber - sequenceNumber);
if (endSequenceNumber <= myEndNumber) {
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) {

View file

@ -25,7 +25,7 @@ class LocationCtxMacroExpansion extends LocationCtx {
private final LocationMap fLocationMap;
private final int fLength;
private final ImageLocationInfo[] fLocationInfos;
private ASTMacroReferenceName fExpansionName;
private final ASTMacroReferenceName fExpansionName;
public LocationCtxMacroExpansion(LocationMap map, LocationCtxContainer parent, int parentOffset, int parentEndOffset,
int sequenceNumber, int length, ImageLocationInfo[] imageLocations, ASTMacroReferenceName expansionName) {
@ -45,17 +45,15 @@ class LocationCtxMacroExpansion extends LocationCtx {
}
@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;
assert offset >= 0 && length >= 0;
if (offset + length <= fLength) {
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() {