1
0
Fork 0
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:
Markus Schorn 2011-07-04 16:03:21 +02:00
parent f50bbd1819
commit 58dbe6d738
6 changed files with 81 additions and 47 deletions

View file

@ -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());
}
}

View file

@ -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 {

View file

@ -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);
}

View file

@ -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) {

View file

@ -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;
}
}

View file

@ -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);
}