diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java index f82112495b3..0f18f070973 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java @@ -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()); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ASTPreprocessorNode.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ASTPreprocessorNode.java index 985304997a6..23ca3939424 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ASTPreprocessorNode.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ASTPreprocessorNode.java @@ -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 { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/CPreprocessor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/CPreprocessor.java index 8cb705ff165..4687ae8fa83 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/CPreprocessor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/CPreprocessor.java @@ -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); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/LocationMap.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/LocationMap.java index 0436a19b413..09d5104e5ca 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/LocationMap.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/LocationMap.java @@ -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) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ScannerContext.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ScannerContext.java index b83fff9b4a9..63d82f34602 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ScannerContext.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ScannerContext.java @@ -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; } } diff --git a/core/org.eclipse.cdt.ui.tests/src/org/eclipse/cdt/ui/tests/DOMAST/DOMASTNodeLeaf.java b/core/org.eclipse.cdt.ui.tests/src/org/eclipse/cdt/ui/tests/DOMAST/DOMASTNodeLeaf.java index 168fe96cc1f..c892d5affae 100644 --- a/core/org.eclipse.cdt.ui.tests/src/org/eclipse/cdt/ui/tests/DOMAST/DOMASTNodeLeaf.java +++ b/core/org.eclipse.cdt.ui.tests/src/org/eclipse/cdt/ui/tests/DOMAST/DOMASTNodeLeaf.java @@ -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); }