mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
defined-constructs in macro bodies, bug 225562
This commit is contained in:
parent
fa6684b982
commit
8d500e6332
5 changed files with 73 additions and 16 deletions
|
@ -56,14 +56,14 @@ public class ExpansionExplorerTests extends BaseTestCase {
|
|||
|
||||
private void verifyStepCount(MacroExpander expander, String original, int steps) {
|
||||
MacroExpansionTracker tracker= new MacroExpansionTracker(Integer.MAX_VALUE);
|
||||
expander.expand(original, tracker, "", 1);
|
||||
expander.expand(original, tracker, "", 1, false);
|
||||
assertEquals(steps, tracker.getStepCount());
|
||||
}
|
||||
|
||||
private void verifyStep(MacroExpander expander, String original, int step, String expectedPre,
|
||||
String expectedPost) {
|
||||
MacroExpansionTracker tracker= new MacroExpansionTracker(step);
|
||||
expander.expand(original, tracker, "", 1);
|
||||
expander.expand(original, tracker, "", 1, false);
|
||||
String pre = tracker.getCodeBeforeStep();
|
||||
ReplaceEdit replacement = tracker.getReplacement();
|
||||
assertNotNull(pre);
|
||||
|
|
|
@ -92,4 +92,33 @@ public class PreprocessorBugsTests extends PreprocessorTestsBase {
|
|||
validateEOF();
|
||||
validateProblemCount(0);
|
||||
}
|
||||
|
||||
// #define FOO(ARG) defined(ARG##_BAZ)
|
||||
// #define BAR_BAZ UNDEFINED
|
||||
// #if FOO(BAR)
|
||||
// juhuu
|
||||
// #else
|
||||
// ojeh
|
||||
// #endif
|
||||
// FOO(BAR) // here expansion has to take place
|
||||
//
|
||||
// #define PLATFORM(WTF_FEATURE) (defined( WTF_PLATFORM_##WTF_FEATURE ) && WTF_PLATFORM_##WTF_FEATURE)
|
||||
// #define WTF_PLATFORM_FOO 1
|
||||
// #if PLATFORM(FOO)
|
||||
// ok
|
||||
// #endif
|
||||
|
||||
|
||||
public void testIndirectDefined_Bug225562() throws Exception {
|
||||
initializeScanner();
|
||||
validateIdentifier("juhuu");
|
||||
validateIdentifier("defined");
|
||||
validateToken(IToken.tLPAREN);
|
||||
validateIdentifier("UNDEFINED"); // here the expansion has to take place
|
||||
validateToken(IToken.tRPAREN);
|
||||
|
||||
validateIdentifier("ok");
|
||||
validateEOF();
|
||||
validateProblemCount(0);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,12 +11,14 @@
|
|||
package org.eclipse.cdt.internal.core.parser.scanner;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.BitSet;
|
||||
import java.util.IdentityHashMap;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||
import org.eclipse.cdt.core.parser.IProblem;
|
||||
import org.eclipse.cdt.core.parser.IToken;
|
||||
import org.eclipse.cdt.core.parser.Keywords;
|
||||
import org.eclipse.cdt.core.parser.OffsetLimitReachedException;
|
||||
import org.eclipse.cdt.core.parser.util.CharArrayMap;
|
||||
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
|
||||
|
@ -49,10 +51,12 @@ public class MacroExpander {
|
|||
fIsStart= isStart;
|
||||
}
|
||||
|
||||
@Override
|
||||
public char[] getCharImage() {
|
||||
return CharArrayUtils.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "{" + (fIsStart ? '+' : '-') + fMacro.getName() + '}'; //$NON-NLS-1$
|
||||
}
|
||||
|
@ -152,7 +156,7 @@ public class MacroExpander {
|
|||
/**
|
||||
* Expects that the identifier has been consumed, stores the result in the list provided.
|
||||
*/
|
||||
public TokenList expand(Lexer lexer, boolean stopAtNewline, PreprocessorMacro macro, Token identifier, boolean completionMode) throws OffsetLimitReachedException {
|
||||
public TokenList expand(Lexer lexer, boolean stopAtNewline, final boolean isPPCondition, PreprocessorMacro macro, Token identifier, boolean completionMode) throws OffsetLimitReachedException {
|
||||
fImplicitMacroExpansions.clear();
|
||||
fImageLocationInfos.clear();
|
||||
|
||||
|
@ -172,7 +176,7 @@ public class MacroExpander {
|
|||
|
||||
input.prepend(firstExpansion);
|
||||
|
||||
TokenList result= expandAll(input, forbidden, null);
|
||||
TokenList result= expandAll(input, forbidden, isPPCondition, null);
|
||||
postProcessTokens(result);
|
||||
|
||||
return result;
|
||||
|
@ -182,7 +186,7 @@ public class MacroExpander {
|
|||
* Method for tracking macro expansions.
|
||||
* @since 5.0
|
||||
*/
|
||||
public void expand(String beforeExpansion, MacroExpansionTracker tracker, String filePath, int lineNumber) {
|
||||
public void expand(String beforeExpansion, MacroExpansionTracker tracker, String filePath, int lineNumber, boolean protectDefinedConstructs) {
|
||||
fImplicitMacroExpansions.clear();
|
||||
fImageLocationInfos.clear();
|
||||
fFixedInput= beforeExpansion.toCharArray();
|
||||
|
@ -218,7 +222,7 @@ public class MacroExpander {
|
|||
firstExpansion.append(new ExpansionBoundary(macro, false));
|
||||
input.prepend(firstExpansion);
|
||||
|
||||
TokenList result= expandAll(input, forbidden, tracker);
|
||||
TokenList result= expandAll(input, forbidden, protectDefinedConstructs, tracker);
|
||||
tracker.finish(result, fEndOffset);
|
||||
} catch (OffsetLimitReachedException e) {
|
||||
}
|
||||
|
@ -249,7 +253,7 @@ public class MacroExpander {
|
|||
final boolean needCopy= paramUsage.get(2*i);
|
||||
final boolean needExpansion = paramUsage.get(2*i+1);
|
||||
clonedArgs[i]= needCopy ? argInput.cloneTokens() : EMPTY_TOKEN_LIST;
|
||||
expandedArgs[i]= needExpansion ? expandAll(argInput, forbidden, tracker) : EMPTY_TOKEN_LIST;
|
||||
expandedArgs[i]= needExpansion ? expandAll(argInput, forbidden, false, tracker) : EMPTY_TOKEN_LIST;
|
||||
if (!needExpansion) {
|
||||
executeScopeMarkers(argInput, forbidden);
|
||||
}
|
||||
|
@ -310,8 +314,9 @@ public class MacroExpander {
|
|||
}
|
||||
|
||||
private TokenList expandAll(TokenSource input, IdentityHashMap<PreprocessorMacro, PreprocessorMacro> forbidden,
|
||||
MacroExpansionTracker tracker) throws OffsetLimitReachedException {
|
||||
boolean protectDefinedConstructs, MacroExpansionTracker tracker) throws OffsetLimitReachedException {
|
||||
final TokenList result= new TokenList();
|
||||
boolean protect= false;
|
||||
Token l= null;
|
||||
Token t= input.removeFirst();
|
||||
while(t != null) {
|
||||
|
@ -320,10 +325,16 @@ public class MacroExpander {
|
|||
((ExpansionBoundary) t).execute(forbidden);
|
||||
break;
|
||||
case IToken.tIDENTIFIER:
|
||||
PreprocessorMacro macro= fDictionary.get(t.getCharImage());
|
||||
if (tracker != null && tracker.isDone()) {
|
||||
final char[] image = t.getCharImage();
|
||||
PreprocessorMacro macro= fDictionary.get(image);
|
||||
if (protect || (tracker != null && tracker.isDone())) {
|
||||
result.append(t);
|
||||
}
|
||||
else if (protectDefinedConstructs && Arrays.equals(image, Keywords.cDEFINED)) {
|
||||
t.setType(CPreprocessor.tDEFINED);
|
||||
result.append(t);
|
||||
protect= true;
|
||||
}
|
||||
// tricky: don't mark function-style macros if you don't find the left parenthesis
|
||||
else if (macro == null || (macro.isFunctionStyle() && !input.findLParenthesis())) {
|
||||
result.append(t);
|
||||
|
@ -351,7 +362,13 @@ public class MacroExpander {
|
|||
input.prepend(replacement);
|
||||
}
|
||||
break;
|
||||
case IToken.tLPAREN:
|
||||
case CPreprocessor.tNOSPACE:
|
||||
case CPreprocessor.tSPACE:
|
||||
result.append(t);
|
||||
break;
|
||||
default:
|
||||
protect= false;
|
||||
result.append(t);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -18,6 +18,10 @@ import java.util.Map;
|
|||
|
||||
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTNodeSelector;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorElifStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIfStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroDefinition;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroExpansion;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
||||
|
@ -65,6 +69,7 @@ public class MultiMacroExpansionExplorer extends MacroExpansionExplorer {
|
|||
throw new IllegalArgumentException();
|
||||
}
|
||||
final ILocationResolver resolver = getResolver(tu);
|
||||
final IASTNodeSelector nodeLocator= tu.getNodeSelector(null);
|
||||
final IASTPreprocessorMacroExpansion[] expansions= resolver.getMacroExpansions(loc);
|
||||
final int count= expansions.length;
|
||||
|
||||
|
@ -87,11 +92,14 @@ public class MultiMacroExpansionExplorer extends MacroExpansionExplorer {
|
|||
IASTFileLocation refLoc= expansion.getFileLocation();
|
||||
int from= refLoc.getNodeOffset()-firstOffset;
|
||||
int to= from+refLoc.getNodeLength();
|
||||
IASTNode enclosing= nodeLocator.findEnclosingNode(from+firstOffset-1, 2);
|
||||
boolean isPPCond= enclosing instanceof IASTPreprocessorIfStatement ||
|
||||
enclosing instanceof IASTPreprocessorElifStatement;
|
||||
fBoundaries[++bidx]= from;
|
||||
fBoundaries[++bidx]= to;
|
||||
fDelegates[++didx]= new SingleMacroExpansionExplorer(new String(fSource, from, to-from),
|
||||
refs.toArray(new IASTName[refs.size()]), fMacroLocations,
|
||||
fFilePath, refLoc.getStartingLineNumber());
|
||||
fFilePath, refLoc.getStartingLineNumber(), isPPCond);
|
||||
}
|
||||
}
|
||||
fBoundaries[++bidx]= fSource.length;
|
||||
|
|
|
@ -36,17 +36,20 @@ public class SingleMacroExpansionExplorer extends MacroExpansionExplorer {
|
|||
private final CharArrayMap<PreprocessorMacro> fDictionary;
|
||||
private MacroExpansionStep fFullExpansion;
|
||||
private int fExpansionCount;
|
||||
private String fFilePath;
|
||||
private int fLineNumber;
|
||||
private final String fFilePath;
|
||||
private final int fLineNumber;
|
||||
private final Map<IMacroBinding, IASTFileLocation> fMacroLocationMap;
|
||||
private final boolean fIsPPCondition;
|
||||
|
||||
public SingleMacroExpansionExplorer(String input, IASTName[] refs,
|
||||
Map<IMacroBinding, IASTFileLocation> macroDefinitionLocationMap, String filePath, int lineNumber) {
|
||||
Map<IMacroBinding, IASTFileLocation> macroDefinitionLocationMap,
|
||||
String filePath, int lineNumber, boolean isPPCondition) {
|
||||
fInput= input;
|
||||
fDictionary= createDictionary(refs);
|
||||
fMacroLocationMap= macroDefinitionLocationMap;
|
||||
fFilePath= filePath;
|
||||
fLineNumber= lineNumber;
|
||||
fIsPPCondition= isPPCondition;
|
||||
}
|
||||
|
||||
private CharArrayMap<PreprocessorMacro> createDictionary(IASTName[] refs) {
|
||||
|
@ -79,7 +82,7 @@ public class SingleMacroExpansionExplorer extends MacroExpansionExplorer {
|
|||
private void computeExpansion() {
|
||||
MacroExpander expander= new MacroExpander(ILexerLog.NULL, fDictionary, null, LEX_OPTIONS);
|
||||
MacroExpansionTracker tracker= new MacroExpansionTracker(Integer.MAX_VALUE);
|
||||
expander.expand(fInput, tracker, fFilePath, fLineNumber);
|
||||
expander.expand(fInput, tracker, fFilePath, fLineNumber, fIsPPCondition);
|
||||
|
||||
fExpansionCount= tracker.getStepCount();
|
||||
ReplaceEdit r= tracker.getReplacement();
|
||||
|
@ -95,7 +98,7 @@ public class SingleMacroExpansionExplorer extends MacroExpansionExplorer {
|
|||
}
|
||||
MacroExpander expander= new MacroExpander(ILexerLog.NULL, fDictionary, null, LEX_OPTIONS);
|
||||
MacroExpansionTracker tracker= new MacroExpansionTracker(step);
|
||||
expander.expand(fInput, tracker, fFilePath, fLineNumber);
|
||||
expander.expand(fInput, tracker, fFilePath, fLineNumber, fIsPPCondition);
|
||||
|
||||
fExpansionCount= tracker.getStepCount();
|
||||
ReplaceEdit r= tracker.getReplacement();
|
||||
|
|
Loading…
Add table
Reference in a new issue