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:
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.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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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() {
|
||||
|
|
Loading…
Add table
Reference in a new issue