From 8d500e6332dace97cb8531b14d518b9bd38108dc Mon Sep 17 00:00:00 2001 From: Markus Schorn Date: Thu, 3 Apr 2008 18:08:07 +0000 Subject: defined-constructs in macro bodies, bug 225562 --- .../core/parser/scanner/MacroExpander.java | 33 ++++++++++++++++------ .../scanner/MultiMacroExpansionExplorer.java | 10 ++++++- .../scanner/SingleMacroExpansionExplorer.java | 13 +++++---- 3 files changed, 42 insertions(+), 14 deletions(-) (limited to 'core/org.eclipse.cdt.core') diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/MacroExpander.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/MacroExpander.java index afe9e45c284..f933cf0123d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/MacroExpander.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/MacroExpander.java @@ -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 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,9 +325,15 @@ 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())) { @@ -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; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/MultiMacroExpansionExplorer.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/MultiMacroExpansionExplorer.java index 45fa127d5eb..2d6a9393d6d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/MultiMacroExpansionExplorer.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/MultiMacroExpansionExplorer.java @@ -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; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/SingleMacroExpansionExplorer.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/SingleMacroExpansionExplorer.java index 9771f5dacc9..492d930fd71 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/SingleMacroExpansionExplorer.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/SingleMacroExpansionExplorer.java @@ -36,17 +36,20 @@ public class SingleMacroExpansionExplorer extends MacroExpansionExplorer { private final CharArrayMap fDictionary; private MacroExpansionStep fFullExpansion; private int fExpansionCount; - private String fFilePath; - private int fLineNumber; + private final String fFilePath; + private final int fLineNumber; private final Map fMacroLocationMap; + private final boolean fIsPPCondition; public SingleMacroExpansionExplorer(String input, IASTName[] refs, - Map macroDefinitionLocationMap, String filePath, int lineNumber) { + Map macroDefinitionLocationMap, + String filePath, int lineNumber, boolean isPPCondition) { fInput= input; fDictionary= createDictionary(refs); fMacroLocationMap= macroDefinitionLocationMap; fFilePath= filePath; fLineNumber= lineNumber; + fIsPPCondition= isPPCondition; } private CharArrayMap 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(); -- cgit v1.2.3