1
0
Fork 0
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:
Markus Schorn 2008-04-03 18:08:07 +00:00
parent fa6684b982
commit 8d500e6332
5 changed files with 73 additions and 16 deletions

View file

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

View file

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

View file

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

View file

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

View file

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