1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-08 10:16:03 +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.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;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIfdefStatement;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroDefinition; import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroDefinition;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroExpansion; import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroExpansion;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorPragmaStatement; import org.eclipse.cdt.core.dom.ast.IASTPreprocessorPragmaStatement;
@ -7321,4 +7322,19 @@ public class AST2Tests extends AST2BaseTest {
bh.assertNonProblem("a;", 1); 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 { abstract class ASTDirectiveWithCondition extends ASTPreprocessorNode {
protected final int fConditionOffset; protected final int fConditionOffset;
private final boolean fActive; private final boolean fTaken;
public ASTDirectiveWithCondition(IASTTranslationUnit parent, int startNumber, int condNumber, int endNumber, boolean active) { public ASTDirectiveWithCondition(IASTTranslationUnit parent, int startNumber, int condNumber, int endNumber, boolean taken) {
super(parent, IASTTranslationUnit.PREPROCESSOR_STATEMENT, startNumber, endNumber); super(parent, IASTTranslationUnit.PREPROCESSOR_STATEMENT, startNumber, endNumber);
fConditionOffset= condNumber; fConditionOffset= condNumber;
fActive= active; fTaken= taken;
} }
public boolean taken() { public boolean taken() {
return fActive; return fTaken;
} }
public String getConditionString() { public String getConditionString() {
@ -154,19 +154,19 @@ class ASTEndif extends ASTPreprocessorNode implements IASTPreprocessorEndifState
} }
class ASTElif extends ASTDirectiveWithCondition implements IASTPreprocessorElifStatement { class ASTElif extends ASTDirectiveWithCondition implements IASTPreprocessorElifStatement {
public ASTElif(IASTTranslationUnit parent, int startNumber, int condNumber, int condEndNumber, boolean active) { public ASTElif(IASTTranslationUnit parent, int startNumber, int condNumber, int condEndNumber, boolean taken) {
super(parent, startNumber, condNumber, condEndNumber, active); super(parent, startNumber, condNumber, condEndNumber, taken);
} }
} }
class ASTElse extends ASTPreprocessorNode implements IASTPreprocessorElseStatement { class ASTElse extends ASTPreprocessorNode implements IASTPreprocessorElseStatement {
private final boolean fActive; private final boolean fTaken;
public ASTElse(IASTTranslationUnit parent, int startNumber, int endNumber, boolean active) { public ASTElse(IASTTranslationUnit parent, int startNumber, int endNumber, boolean taken) {
super(parent, IASTTranslationUnit.PREPROCESSOR_STATEMENT, startNumber, endNumber); super(parent, IASTTranslationUnit.PREPROCESSOR_STATEMENT, startNumber, endNumber);
fActive= active; fTaken= taken;
} }
public boolean taken() { public boolean taken() {
return fActive; return fTaken;
} }
} }
@ -204,8 +204,8 @@ class ASTIfdef extends ASTDirectiveWithCondition implements IASTPreprocessorIfde
} }
class ASTIf extends ASTDirectiveWithCondition implements IASTPreprocessorIfStatement { class ASTIf extends ASTDirectiveWithCondition implements IASTPreprocessorIfStatement {
public ASTIf(IASTTranslationUnit parent, int startNumber, int condNumber, int condEndNumber, boolean active) { public ASTIf(IASTTranslationUnit parent, int startNumber, int condNumber, int condEndNumber, boolean taken) {
super(parent, startNumber, condNumber, condEndNumber, active); super(parent, startNumber, condNumber, condEndNumber, taken);
} }
} }
@ -304,7 +304,6 @@ class ASTMacroDefinition extends ASTPreprocessorNode implements IASTPreprocessor
private final ASTPreprocessorName fName; private final ASTPreprocessorName fName;
protected final int fExpansionNumber; protected final int fExpansionNumber;
private final int fExpansionOffset; private final int fExpansionOffset;
private final boolean fActive;
/** /**
* Regular constructor. * Regular constructor.
@ -314,8 +313,9 @@ class ASTMacroDefinition extends ASTPreprocessorNode implements IASTPreprocessor
super(parent, IASTTranslationUnit.PREPROCESSOR_STATEMENT, startNumber, endNumber); super(parent, IASTTranslationUnit.PREPROCESSOR_STATEMENT, startNumber, endNumber);
fExpansionNumber= expansionNumber; fExpansionNumber= expansionNumber;
fExpansionOffset= -1; fExpansionOffset= -1;
fActive= active;
fName= new ASTPreprocessorDefinition(this, IASTPreprocessorMacroDefinition.MACRO_NAME, nameNumber, nameEndNumber, macro.getNameCharArray(), macro); 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); fName= new ASTBuiltinName(this, IASTPreprocessorMacroDefinition.MACRO_NAME, floc, macro.getNameCharArray(), macro);
fExpansionNumber= -1; fExpansionNumber= -1;
fExpansionOffset= expansionOffset; fExpansionOffset= expansionOffset;
fActive= true;
} }
@ -388,11 +387,6 @@ class ASTMacroDefinition extends ASTPreprocessorNode implements IASTPreprocessor
public String toString() { public String toString() {
return getName().toString() + '=' + getExpansion(); return getName().toString() + '=' + getExpansion();
} }
@Override
final public boolean isActive() {
return fActive;
}
} }
class ASTMacroParameter extends ASTPreprocessorNode implements IASTFunctionStyleMacroParameter { 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 nameEndOffset = name.getEndOffset();
final int endOffset= lexer.currentToken().getEndOffset(); final int endOffset= lexer.currentToken().getEndOffset();
boolean isActive= false; boolean isTaken= false;
PreprocessorMacro macro= null; PreprocessorMacro macro= null;
final Conditional conditional= fCurrentContext.newBranch(BranchKind.eIf, withinExpansion); final Conditional conditional= fCurrentContext.newBranch(BranchKind.eIf, withinExpansion);
if (conditional.canHaveActiveBranch(withinExpansion)) { if (conditional.canHaveActiveBranch(withinExpansion)) {
@ -1394,19 +1394,23 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
} else { } else {
final char[] namechars= name.getCharImage(); final char[] namechars= name.getCharImage();
macro= fMacroDictionary.get(namechars); macro= fMacroDictionary.get(namechars);
isActive= (macro == null) == isIfndef; isTaken= (macro == null) == isIfndef;
if (macro == null) { if (macro == null) {
macro = new UndefinedMacro(namechars); macro = new UndefinedMacro(namechars);
} }
} }
} }
ASTPreprocessorNode stmt;
if (isIfndef) { if (isIfndef) {
fLocationMap.encounterPoundIfndef(offset, nameOffset, nameEndOffset, endOffset, isActive, macro); stmt= fLocationMap.encounterPoundIfndef(offset, nameOffset, nameEndOffset, endOffset, isTaken, macro);
} else { } 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 { 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(); return fCurrentContext.getCodeState();
} }
boolean isActive= false; boolean isTaken= false;
IASTName[] refs= IASTName.EMPTY_NAME_ARRAY; IASTName[] refs= IASTName.EMPTY_NAME_ARRAY;
int condOffset= lexer.nextToken().getOffset(); int condOffset= lexer.nextToken().getOffset();
int condEndOffset, endOffset; int condEndOffset, endOffset;
@ -1433,7 +1437,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
} else { } else {
try { try {
fExpressionEvaluator.clearMacrosInDefinedExpression(); fExpressionEvaluator.clearMacrosInDefinedExpression();
isActive= fExpressionEvaluator.evaluate(condition, fMacroDictionary, fLocationMap); isTaken= fExpressionEvaluator.evaluate(condition, fMacroDictionary, fLocationMap);
refs = fExpressionEvaluator.clearMacrosInDefinedExpression(); refs = fExpressionEvaluator.clearMacrosInDefinedExpression();
} catch (EvalException e) { } catch (EvalException e) {
handleProblem(e.getProblemID(), e.getProblemArg(), condOffset, endOffset); handleProblem(e.getProblemID(), e.getProblemArg(), condOffset, endOffset);
@ -1444,12 +1448,16 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
endOffset= lexer.currentToken().getEndOffset(); endOffset= lexer.currentToken().getEndOffset();
} }
ASTPreprocessorNode stmt;
if (isElif) { if (isElif) {
fLocationMap.encounterPoundElif(startOffset, condOffset, condEndOffset, endOffset, isActive, refs); stmt= fLocationMap.encounterPoundElif(startOffset, condOffset, condEndOffset, endOffset, isTaken, refs);
} else { } 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) 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(); return fCurrentContext.getCodeState();
} }
final boolean isActive= cond.canHaveActiveBranch(withinExpansion); final boolean isTaken= cond.canHaveActiveBranch(withinExpansion);
fLocationMap.encounterPoundElse(startOffset, endOffset, isActive); ASTElse stmt = fLocationMap.encounterPoundElse(startOffset, endOffset, isTaken);
return fCurrentContext.setBranchState(cond, isActive, withinExpansion, startOffset); if (!cond.isActive(withinExpansion))
stmt.setInactive();
return fCurrentContext.setBranchState(cond, isTaken, withinExpansion, startOffset);
} }
private CodeState executeEndif(Lexer lexer, int startOffset, boolean withinExpansion) throws OffsetLimitReachedException { 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) { if (cond == null) {
handleProblem(IProblem.PREPROCESSOR_UNBALANCE_CONDITION, Keywords.cENDIF, startOffset, endOffset); handleProblem(IProblem.PREPROCESSOR_UNBALANCE_CONDITION, Keywords.cENDIF, startOffset, endOffset);
} else { } else {
fLocationMap.encounterPoundEndIf(startOffset, endOffset); ASTEndif stmt = fLocationMap.encounterPoundEndIf(startOffset, endOffset);
if (!cond.isActive(withinExpansion))
stmt.setInactive();
} }
return fCurrentContext.setBranchEndState(cond, withinExpansion, startOffset); return fCurrentContext.setBranchEndState(cond, withinExpansion, startOffset);
} }

View file

@ -248,19 +248,21 @@ public class LocationMap implements ILocationResolver {
fProblems.add(problem); fProblems.add(problem);
} }
public void encounterPoundElse(int startOffset, int endOffset, boolean isActive) { public ASTElse encounterPoundElse(int startOffset, int endOffset, boolean isActive) {
startOffset= getSequenceNumberForOffset(startOffset); startOffset= getSequenceNumberForOffset(startOffset);
endOffset= getSequenceNumberForOffset(endOffset); 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) { IASTName[] macrosInDefinedExpression) {
startOffset= getSequenceNumberForOffset(startOffset); startOffset= getSequenceNumberForOffset(startOffset);
condOffset= getSequenceNumberForOffset(condOffset); condOffset= getSequenceNumberForOffset(condOffset);
condEndOffset= getSequenceNumberForOffset(condEndOffset); condEndOffset= getSequenceNumberForOffset(condEndOffset);
// compatible with 4.0: endOffset= getSequenceNumberForOffset(endOffset); // 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); fDirectives.add(elif);
for (IASTName element : macrosInDefinedExpression) { for (IASTName element : macrosInDefinedExpression) {
@ -269,13 +271,15 @@ public class LocationMap implements ILocationResolver {
name.setPropertyInParent(IASTPreprocessorStatement.MACRO_NAME); name.setPropertyInParent(IASTPreprocessorStatement.MACRO_NAME);
addMacroReference(name); addMacroReference(name);
} }
return elif;
} }
public void encounterPoundEndIf(int startOffset, int endOffset) { public ASTEndif encounterPoundEndIf(int startOffset, int endOffset) {
startOffset= getSequenceNumberForOffset(startOffset); startOffset= getSequenceNumberForOffset(startOffset);
endOffset= getSequenceNumberForOffset(endOffset); 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) { 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)); 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); startOffset= getSequenceNumberForOffset(startOffset);
condOffset= getSequenceNumberForOffset(condOffset); condOffset= getSequenceNumberForOffset(condOffset);
condEndOffset= getSequenceNumberForOffset(condEndOffset); condEndOffset= getSequenceNumberForOffset(condEndOffset);
@ -306,9 +310,10 @@ public class LocationMap implements ILocationResolver {
final ASTIfdef ifdef = new ASTIfdef(fTranslationUnit, startOffset, condOffset, condEndOffset, taken, macro); final ASTIfdef ifdef = new ASTIfdef(fTranslationUnit, startOffset, condOffset, condEndOffset, taken, macro);
fDirectives.add(ifdef); fDirectives.add(ifdef);
addMacroReference(ifdef.getMacroReference()); 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); startOffset= getSequenceNumberForOffset(startOffset);
condOffset= getSequenceNumberForOffset(condOffset); condOffset= getSequenceNumberForOffset(condOffset);
condEndOffset= getSequenceNumberForOffset(condEndOffset); condEndOffset= getSequenceNumberForOffset(condEndOffset);
@ -316,15 +321,16 @@ public class LocationMap implements ILocationResolver {
final ASTIfndef ifndef = new ASTIfndef(fTranslationUnit, startOffset, condOffset, condEndOffset, taken, macro); final ASTIfndef ifndef = new ASTIfndef(fTranslationUnit, startOffset, condOffset, condEndOffset, taken, macro);
fDirectives.add(ifndef); fDirectives.add(ifndef);
addMacroReference(ifndef.getMacroReference()); 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) { IASTName[] macrosInDefinedExpression) {
startOffset= getSequenceNumberForOffset(startOffset); startOffset= getSequenceNumberForOffset(startOffset);
condOffset= getSequenceNumberForOffset(condOffset); condOffset= getSequenceNumberForOffset(condOffset);
condEndOffset= getSequenceNumberForOffset(condEndOffset); condEndOffset= getSequenceNumberForOffset(condEndOffset);
// not using endOffset, compatible with 4.0: endOffset= getSequenceNumberForOffset(endOffset); // 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); fDirectives.add(astif);
for (IASTName element : macrosInDefinedExpression) { for (IASTName element : macrosInDefinedExpression) {
ASTMacroReferenceName name = (ASTMacroReferenceName) element; ASTMacroReferenceName name = (ASTMacroReferenceName) element;
@ -332,6 +338,7 @@ public class LocationMap implements ILocationResolver {
name.setPropertyInParent(IASTPreprocessorStatement.MACRO_NAME); name.setPropertyInParent(IASTPreprocessorStatement.MACRO_NAME);
addMacroReference(name); addMacroReference(name);
} }
return astif;
} }
public void encounterPoundDefine(int startOffset, int nameOffset, int nameEndOffset, int expansionOffset, int endOffset, boolean isActive, IMacroBinding macrodef) { 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 BranchKind {eIf, eElif, eElse, eEnd}
enum CodeState {eActive, eParseInactive, eSkipInactive} enum CodeState {eActive, eParseInactive, eSkipInactive}
final static class Conditional { final static class Conditional {
private CodeState fInitialState; private final CodeState fInitialState;
private BranchKind fLast; private BranchKind fLast;
private boolean fTakeElse= true; private boolean fTakeElse= true;
Conditional(CodeState state) { Conditional(CodeState state) {
@ -31,7 +31,11 @@ final class ScannerContext {
fLast= BranchKind.eIf; fLast= BranchKind.eIf;
} }
boolean canHaveActiveBranch(boolean withinExpansion) { 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(); String methodName = id.toString();
methodName = methodName.replaceAll(NODE_PREFIX, BLANK_STRING); methodName = methodName.replaceAll(NODE_PREFIX, BLANK_STRING);
Method method = nodeClass.getMethod(methodName, new Class[0]); // only going to be getter methods... Method method = nodeClass.getMethod(methodName, new Class[0]); // only going to be getter methods...
method.setAccessible(true);
result = method.invoke(node); result = method.invoke(node);
} }