mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-08 02:06:01 +02:00
Bug 349534: Mark inactive preprocessor statements as such.
This commit is contained in:
parent
f50bbd1819
commit
58dbe6d738
6 changed files with 81 additions and 47 deletions
|
@ -58,6 +58,7 @@ import org.eclipse.cdt.core.dom.ast.IASTNode;
|
|||
import org.eclipse.cdt.core.dom.ast.IASTNullStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIfdefStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroDefinition;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroExpansion;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorPragmaStatement;
|
||||
|
@ -7321,4 +7322,19 @@ public class AST2Tests extends AST2BaseTest {
|
|||
bh.assertNonProblem("a;", 1);
|
||||
}
|
||||
|
||||
// #ifdef A // active, not taken.
|
||||
// #ifdef B // inactive, not taken.
|
||||
// #endif // inactive
|
||||
// #endif // active
|
||||
public void testInactivePreprocessingStatements() throws Exception {
|
||||
IASTTranslationUnit tu= parseAndCheckBindings(getAboveComment());
|
||||
IASTPreprocessorStatement[] stmts= tu.getAllPreprocessorStatements();
|
||||
assertTrue(stmts[0].isActive());
|
||||
assertFalse(stmts[1].isActive());
|
||||
assertFalse(stmts[2].isActive());
|
||||
assertTrue(stmts[3].isActive());
|
||||
|
||||
assertFalse(((IASTPreprocessorIfdefStatement) stmts[0]).taken());
|
||||
assertFalse(((IASTPreprocessorIfdefStatement) stmts[1]).taken());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -127,15 +127,15 @@ class ASTComment extends ASTPreprocessorNode implements IASTComment {
|
|||
|
||||
abstract class ASTDirectiveWithCondition extends ASTPreprocessorNode {
|
||||
protected final int fConditionOffset;
|
||||
private final boolean fActive;
|
||||
public ASTDirectiveWithCondition(IASTTranslationUnit parent, int startNumber, int condNumber, int endNumber, boolean active) {
|
||||
private final boolean fTaken;
|
||||
public ASTDirectiveWithCondition(IASTTranslationUnit parent, int startNumber, int condNumber, int endNumber, boolean taken) {
|
||||
super(parent, IASTTranslationUnit.PREPROCESSOR_STATEMENT, startNumber, endNumber);
|
||||
fConditionOffset= condNumber;
|
||||
fActive= active;
|
||||
fTaken= taken;
|
||||
}
|
||||
|
||||
public boolean taken() {
|
||||
return fActive;
|
||||
return fTaken;
|
||||
}
|
||||
|
||||
public String getConditionString() {
|
||||
|
@ -154,19 +154,19 @@ class ASTEndif extends ASTPreprocessorNode implements IASTPreprocessorEndifState
|
|||
}
|
||||
|
||||
class ASTElif extends ASTDirectiveWithCondition implements IASTPreprocessorElifStatement {
|
||||
public ASTElif(IASTTranslationUnit parent, int startNumber, int condNumber, int condEndNumber, boolean active) {
|
||||
super(parent, startNumber, condNumber, condEndNumber, active);
|
||||
public ASTElif(IASTTranslationUnit parent, int startNumber, int condNumber, int condEndNumber, boolean taken) {
|
||||
super(parent, startNumber, condNumber, condEndNumber, taken);
|
||||
}
|
||||
}
|
||||
|
||||
class ASTElse extends ASTPreprocessorNode implements IASTPreprocessorElseStatement {
|
||||
private final boolean fActive;
|
||||
public ASTElse(IASTTranslationUnit parent, int startNumber, int endNumber, boolean active) {
|
||||
private final boolean fTaken;
|
||||
public ASTElse(IASTTranslationUnit parent, int startNumber, int endNumber, boolean taken) {
|
||||
super(parent, IASTTranslationUnit.PREPROCESSOR_STATEMENT, startNumber, endNumber);
|
||||
fActive= active;
|
||||
fTaken= taken;
|
||||
}
|
||||
public boolean taken() {
|
||||
return fActive;
|
||||
return fTaken;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -204,8 +204,8 @@ class ASTIfdef extends ASTDirectiveWithCondition implements IASTPreprocessorIfde
|
|||
}
|
||||
|
||||
class ASTIf extends ASTDirectiveWithCondition implements IASTPreprocessorIfStatement {
|
||||
public ASTIf(IASTTranslationUnit parent, int startNumber, int condNumber, int condEndNumber, boolean active) {
|
||||
super(parent, startNumber, condNumber, condEndNumber, active);
|
||||
public ASTIf(IASTTranslationUnit parent, int startNumber, int condNumber, int condEndNumber, boolean taken) {
|
||||
super(parent, startNumber, condNumber, condEndNumber, taken);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -304,7 +304,6 @@ class ASTMacroDefinition extends ASTPreprocessorNode implements IASTPreprocessor
|
|||
private final ASTPreprocessorName fName;
|
||||
protected final int fExpansionNumber;
|
||||
private final int fExpansionOffset;
|
||||
private final boolean fActive;
|
||||
|
||||
/**
|
||||
* Regular constructor.
|
||||
|
@ -314,8 +313,9 @@ class ASTMacroDefinition extends ASTPreprocessorNode implements IASTPreprocessor
|
|||
super(parent, IASTTranslationUnit.PREPROCESSOR_STATEMENT, startNumber, endNumber);
|
||||
fExpansionNumber= expansionNumber;
|
||||
fExpansionOffset= -1;
|
||||
fActive= active;
|
||||
fName= new ASTPreprocessorDefinition(this, IASTPreprocessorMacroDefinition.MACRO_NAME, nameNumber, nameEndNumber, macro.getNameCharArray(), macro);
|
||||
if (!active)
|
||||
setInactive();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -327,7 +327,6 @@ class ASTMacroDefinition extends ASTPreprocessorNode implements IASTPreprocessor
|
|||
fName= new ASTBuiltinName(this, IASTPreprocessorMacroDefinition.MACRO_NAME, floc, macro.getNameCharArray(), macro);
|
||||
fExpansionNumber= -1;
|
||||
fExpansionOffset= expansionOffset;
|
||||
fActive= true;
|
||||
}
|
||||
|
||||
|
||||
|
@ -388,11 +387,6 @@ class ASTMacroDefinition extends ASTPreprocessorNode implements IASTPreprocessor
|
|||
public String toString() {
|
||||
return getName().toString() + '=' + getExpansion();
|
||||
}
|
||||
|
||||
@Override
|
||||
final public boolean isActive() {
|
||||
return fActive;
|
||||
}
|
||||
}
|
||||
|
||||
class ASTMacroParameter extends ASTPreprocessorNode implements IASTFunctionStyleMacroParameter {
|
||||
|
|
|
@ -1380,7 +1380,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
|||
final int nameEndOffset = name.getEndOffset();
|
||||
final int endOffset= lexer.currentToken().getEndOffset();
|
||||
|
||||
boolean isActive= false;
|
||||
boolean isTaken= false;
|
||||
PreprocessorMacro macro= null;
|
||||
final Conditional conditional= fCurrentContext.newBranch(BranchKind.eIf, withinExpansion);
|
||||
if (conditional.canHaveActiveBranch(withinExpansion)) {
|
||||
|
@ -1394,19 +1394,23 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
|||
} else {
|
||||
final char[] namechars= name.getCharImage();
|
||||
macro= fMacroDictionary.get(namechars);
|
||||
isActive= (macro == null) == isIfndef;
|
||||
isTaken= (macro == null) == isIfndef;
|
||||
if (macro == null) {
|
||||
macro = new UndefinedMacro(namechars);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ASTPreprocessorNode stmt;
|
||||
if (isIfndef) {
|
||||
fLocationMap.encounterPoundIfndef(offset, nameOffset, nameEndOffset, endOffset, isActive, macro);
|
||||
stmt= fLocationMap.encounterPoundIfndef(offset, nameOffset, nameEndOffset, endOffset, isTaken, macro);
|
||||
} else {
|
||||
fLocationMap.encounterPoundIfdef(offset, nameOffset, nameEndOffset, endOffset, isActive, macro);
|
||||
stmt= fLocationMap.encounterPoundIfdef(offset, nameOffset, nameEndOffset, endOffset, isTaken, macro);
|
||||
}
|
||||
return fCurrentContext.setBranchState(conditional, isActive, withinExpansion, offset);
|
||||
if (!conditional.isActive(withinExpansion))
|
||||
stmt.setInactive();
|
||||
|
||||
return fCurrentContext.setBranchState(conditional, isTaken, withinExpansion, offset);
|
||||
}
|
||||
|
||||
private CodeState executeIf(Lexer lexer, int startOffset, boolean isElif, boolean withinExpansion) throws OffsetLimitReachedException {
|
||||
|
@ -1418,7 +1422,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
|||
return fCurrentContext.getCodeState();
|
||||
}
|
||||
|
||||
boolean isActive= false;
|
||||
boolean isTaken= false;
|
||||
IASTName[] refs= IASTName.EMPTY_NAME_ARRAY;
|
||||
int condOffset= lexer.nextToken().getOffset();
|
||||
int condEndOffset, endOffset;
|
||||
|
@ -1433,7 +1437,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
|||
} else {
|
||||
try {
|
||||
fExpressionEvaluator.clearMacrosInDefinedExpression();
|
||||
isActive= fExpressionEvaluator.evaluate(condition, fMacroDictionary, fLocationMap);
|
||||
isTaken= fExpressionEvaluator.evaluate(condition, fMacroDictionary, fLocationMap);
|
||||
refs = fExpressionEvaluator.clearMacrosInDefinedExpression();
|
||||
} catch (EvalException e) {
|
||||
handleProblem(e.getProblemID(), e.getProblemArg(), condOffset, endOffset);
|
||||
|
@ -1444,12 +1448,16 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
|||
endOffset= lexer.currentToken().getEndOffset();
|
||||
}
|
||||
|
||||
ASTPreprocessorNode stmt;
|
||||
if (isElif) {
|
||||
fLocationMap.encounterPoundElif(startOffset, condOffset, condEndOffset, endOffset, isActive, refs);
|
||||
stmt= fLocationMap.encounterPoundElif(startOffset, condOffset, condEndOffset, endOffset, isTaken, refs);
|
||||
} else {
|
||||
fLocationMap.encounterPoundIf(startOffset, condOffset, condEndOffset, endOffset, isActive, refs);
|
||||
stmt= fLocationMap.encounterPoundIf(startOffset, condOffset, condEndOffset, endOffset, isTaken, refs);
|
||||
}
|
||||
return fCurrentContext.setBranchState(cond, isActive, withinExpansion, startOffset);
|
||||
if (!cond.isActive(withinExpansion))
|
||||
stmt.setInactive();
|
||||
|
||||
return fCurrentContext.setBranchState(cond, isTaken, withinExpansion, startOffset);
|
||||
}
|
||||
|
||||
private CodeState executeElse(final Lexer lexer, final int startOffset,boolean withinExpansion)
|
||||
|
@ -1461,9 +1469,11 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
|||
return fCurrentContext.getCodeState();
|
||||
}
|
||||
|
||||
final boolean isActive= cond.canHaveActiveBranch(withinExpansion);
|
||||
fLocationMap.encounterPoundElse(startOffset, endOffset, isActive);
|
||||
return fCurrentContext.setBranchState(cond, isActive, withinExpansion, startOffset);
|
||||
final boolean isTaken= cond.canHaveActiveBranch(withinExpansion);
|
||||
ASTElse stmt = fLocationMap.encounterPoundElse(startOffset, endOffset, isTaken);
|
||||
if (!cond.isActive(withinExpansion))
|
||||
stmt.setInactive();
|
||||
return fCurrentContext.setBranchState(cond, isTaken, withinExpansion, startOffset);
|
||||
}
|
||||
|
||||
private CodeState executeEndif(Lexer lexer, int startOffset, boolean withinExpansion) throws OffsetLimitReachedException {
|
||||
|
@ -1472,7 +1482,9 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
|||
if (cond == null) {
|
||||
handleProblem(IProblem.PREPROCESSOR_UNBALANCE_CONDITION, Keywords.cENDIF, startOffset, endOffset);
|
||||
} else {
|
||||
fLocationMap.encounterPoundEndIf(startOffset, endOffset);
|
||||
ASTEndif stmt = fLocationMap.encounterPoundEndIf(startOffset, endOffset);
|
||||
if (!cond.isActive(withinExpansion))
|
||||
stmt.setInactive();
|
||||
}
|
||||
return fCurrentContext.setBranchEndState(cond, withinExpansion, startOffset);
|
||||
}
|
||||
|
|
|
@ -248,19 +248,21 @@ public class LocationMap implements ILocationResolver {
|
|||
fProblems.add(problem);
|
||||
}
|
||||
|
||||
public void encounterPoundElse(int startOffset, int endOffset, boolean isActive) {
|
||||
public ASTElse encounterPoundElse(int startOffset, int endOffset, boolean isActive) {
|
||||
startOffset= getSequenceNumberForOffset(startOffset);
|
||||
endOffset= getSequenceNumberForOffset(endOffset);
|
||||
fDirectives.add(new ASTElse(fTranslationUnit, startOffset, endOffset, isActive));
|
||||
final ASTElse astElse = new ASTElse(fTranslationUnit, startOffset, endOffset, isActive);
|
||||
fDirectives.add(astElse);
|
||||
return astElse;
|
||||
}
|
||||
|
||||
public void encounterPoundElif(int startOffset, int condOffset, int condEndOffset, int endOffset, boolean isActive,
|
||||
public ASTElif encounterPoundElif(int startOffset, int condOffset, int condEndOffset, int endOffset, boolean taken,
|
||||
IASTName[] macrosInDefinedExpression) {
|
||||
startOffset= getSequenceNumberForOffset(startOffset);
|
||||
condOffset= getSequenceNumberForOffset(condOffset);
|
||||
condEndOffset= getSequenceNumberForOffset(condEndOffset);
|
||||
// compatible with 4.0: endOffset= getSequenceNumberForOffset(endOffset);
|
||||
final ASTElif elif = new ASTElif(fTranslationUnit, startOffset, condOffset, condEndOffset, isActive);
|
||||
final ASTElif elif = new ASTElif(fTranslationUnit, startOffset, condOffset, condEndOffset, taken);
|
||||
fDirectives.add(elif);
|
||||
|
||||
for (IASTName element : macrosInDefinedExpression) {
|
||||
|
@ -269,13 +271,15 @@ public class LocationMap implements ILocationResolver {
|
|||
name.setPropertyInParent(IASTPreprocessorStatement.MACRO_NAME);
|
||||
addMacroReference(name);
|
||||
}
|
||||
|
||||
return elif;
|
||||
}
|
||||
|
||||
public void encounterPoundEndIf(int startOffset, int endOffset) {
|
||||
public ASTEndif encounterPoundEndIf(int startOffset, int endOffset) {
|
||||
startOffset= getSequenceNumberForOffset(startOffset);
|
||||
endOffset= getSequenceNumberForOffset(endOffset);
|
||||
fDirectives.add(new ASTEndif(fTranslationUnit, startOffset, endOffset));
|
||||
final ASTEndif stmt = new ASTEndif(fTranslationUnit, startOffset, endOffset);
|
||||
fDirectives.add(stmt);
|
||||
return stmt;
|
||||
}
|
||||
|
||||
public void encounterPoundError(int startOffset, int condOffset, int condEndOffset, int endOffset) {
|
||||
|
@ -298,7 +302,7 @@ public class LocationMap implements ILocationResolver {
|
|||
fDirectives.add(new ASTPragmaOperator(fTranslationUnit, startNumber, condNumber, condEndNumber, endNumber));
|
||||
}
|
||||
|
||||
public void encounterPoundIfdef(int startOffset, int condOffset, int condEndOffset, int endOffset, boolean taken, IMacroBinding macro) {
|
||||
public ASTIfdef encounterPoundIfdef(int startOffset, int condOffset, int condEndOffset, int endOffset, boolean taken, IMacroBinding macro) {
|
||||
startOffset= getSequenceNumberForOffset(startOffset);
|
||||
condOffset= getSequenceNumberForOffset(condOffset);
|
||||
condEndOffset= getSequenceNumberForOffset(condEndOffset);
|
||||
|
@ -306,9 +310,10 @@ public class LocationMap implements ILocationResolver {
|
|||
final ASTIfdef ifdef = new ASTIfdef(fTranslationUnit, startOffset, condOffset, condEndOffset, taken, macro);
|
||||
fDirectives.add(ifdef);
|
||||
addMacroReference(ifdef.getMacroReference());
|
||||
return ifdef;
|
||||
}
|
||||
|
||||
public void encounterPoundIfndef(int startOffset, int condOffset, int condEndOffset, int endOffset, boolean taken, IMacroBinding macro) {
|
||||
public ASTIfndef encounterPoundIfndef(int startOffset, int condOffset, int condEndOffset, int endOffset, boolean taken, IMacroBinding macro) {
|
||||
startOffset= getSequenceNumberForOffset(startOffset);
|
||||
condOffset= getSequenceNumberForOffset(condOffset);
|
||||
condEndOffset= getSequenceNumberForOffset(condEndOffset);
|
||||
|
@ -316,15 +321,16 @@ public class LocationMap implements ILocationResolver {
|
|||
final ASTIfndef ifndef = new ASTIfndef(fTranslationUnit, startOffset, condOffset, condEndOffset, taken, macro);
|
||||
fDirectives.add(ifndef);
|
||||
addMacroReference(ifndef.getMacroReference());
|
||||
return ifndef;
|
||||
}
|
||||
|
||||
public void encounterPoundIf(int startOffset, int condOffset, int condEndOffset, int endOffset, boolean isActive,
|
||||
public ASTIf encounterPoundIf(int startOffset, int condOffset, int condEndOffset, int endOffset, boolean taken,
|
||||
IASTName[] macrosInDefinedExpression) {
|
||||
startOffset= getSequenceNumberForOffset(startOffset);
|
||||
condOffset= getSequenceNumberForOffset(condOffset);
|
||||
condEndOffset= getSequenceNumberForOffset(condEndOffset);
|
||||
// not using endOffset, compatible with 4.0: endOffset= getSequenceNumberForOffset(endOffset);
|
||||
final ASTIf astif = new ASTIf(fTranslationUnit, startOffset, condOffset, condEndOffset, isActive);
|
||||
final ASTIf astif = new ASTIf(fTranslationUnit, startOffset, condOffset, condEndOffset, taken);
|
||||
fDirectives.add(astif);
|
||||
for (IASTName element : macrosInDefinedExpression) {
|
||||
ASTMacroReferenceName name = (ASTMacroReferenceName) element;
|
||||
|
@ -332,6 +338,7 @@ public class LocationMap implements ILocationResolver {
|
|||
name.setPropertyInParent(IASTPreprocessorStatement.MACRO_NAME);
|
||||
addMacroReference(name);
|
||||
}
|
||||
return astif;
|
||||
}
|
||||
|
||||
public void encounterPoundDefine(int startOffset, int nameOffset, int nameEndOffset, int expansionOffset, int endOffset, boolean isActive, IMacroBinding macrodef) {
|
||||
|
|
|
@ -23,7 +23,7 @@ final class ScannerContext {
|
|||
enum BranchKind {eIf, eElif, eElse, eEnd}
|
||||
enum CodeState {eActive, eParseInactive, eSkipInactive}
|
||||
final static class Conditional {
|
||||
private CodeState fInitialState;
|
||||
private final CodeState fInitialState;
|
||||
private BranchKind fLast;
|
||||
private boolean fTakeElse= true;
|
||||
Conditional(CodeState state) {
|
||||
|
@ -31,7 +31,11 @@ final class ScannerContext {
|
|||
fLast= BranchKind.eIf;
|
||||
}
|
||||
boolean canHaveActiveBranch(boolean withinExpansion) {
|
||||
return fTakeElse && (fInitialState == CodeState.eActive || withinExpansion);
|
||||
return fTakeElse && isActive(withinExpansion);
|
||||
}
|
||||
|
||||
public boolean isActive(boolean withinExpansion) {
|
||||
return withinExpansion || fInitialState == CodeState.eActive;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -503,6 +503,7 @@ public class DOMASTNodeLeaf implements IAdaptable {
|
|||
String methodName = id.toString();
|
||||
methodName = methodName.replaceAll(NODE_PREFIX, BLANK_STRING);
|
||||
Method method = nodeClass.getMethod(methodName, new Class[0]); // only going to be getter methods...
|
||||
method.setAccessible(true);
|
||||
result = method.invoke(node);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue