From 008d8cf1d33ac10338cf7fb8ad5ba41539d5c2eb Mon Sep 17 00:00:00 2001 From: Markus Schorn Date: Mon, 21 Jan 2008 10:32:47 +0000 Subject: [PATCH] Reporting locations of macro-definitions in macro-explorer, bug 23540. --- .../tests/scanner/ExpansionExplorerTests.java | 50 +++++++++++ .../dom/rewrite/MacroExpansionExplorer.java | 6 ++ .../parser/scanner/MacroExpansionStep.java | 8 +- .../scanner/MultiMacroExpansionExplorer.java | 90 ++++++++++++++----- .../scanner/SingleMacroExpansionExplorer.java | 23 +++-- 5 files changed, 145 insertions(+), 32 deletions(-) diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/scanner/ExpansionExplorerTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/scanner/ExpansionExplorerTests.java index 75c4736750d..07070144faf 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/scanner/ExpansionExplorerTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/scanner/ExpansionExplorerTests.java @@ -294,4 +294,54 @@ public class ExpansionExplorerTests extends BaseTestCase { public void testStringify() throws Exception { performTest(3); } + + // #define vararg(x, y...) bla(x, y) + // #define _p p + + // vararg( _p ); + + // vararg( p ); + + // bla(p, ); + public void testVararg1() throws Exception { + performTest(2); + } + + // #define vararg(x, y...) bla(x, ##y) + // #define _p p + + // vararg( _p ); + + // vararg( p ); + + // bla(p); + public void testVararg1x() throws Exception { + performTest(2); + } + + // #define vararg(x, y...) bla(x, y) + // #define _p p + + // vararg( _p , _p ); + + // vararg( p , _p ); + + // vararg( p , p ); + + // bla(p, p); + public void testVararg2() throws Exception { + performTest(3); + } + + // #define func2(x,y) (x,y) + // #define _p p + + // func2(_p); + + // func2(p); + + // (p,); + public void testTooFewArgs() throws Exception { + performTest(2); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/rewrite/MacroExpansionExplorer.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/rewrite/MacroExpansionExplorer.java index fa07e1b34a8..d0f29625647 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/rewrite/MacroExpansionExplorer.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/rewrite/MacroExpansionExplorer.java @@ -47,6 +47,12 @@ public abstract class MacroExpansionExplorer { * a step representing a full expansion. */ IMacroBinding getExpandedMacro(); + + /** + * Returns the location of the macro-definition that gets expanded in this step, + * or null for built-in macros or for a step representing a full expansion. + */ + IASTFileLocation getLocationOfExpandedMacroDefinition(); } /** diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/MacroExpansionStep.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/MacroExpansionStep.java index 9796d2e10be..4617031d704 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/MacroExpansionStep.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/MacroExpansionStep.java @@ -10,6 +10,7 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.parser.scanner; +import org.eclipse.cdt.core.dom.ast.IASTFileLocation; import org.eclipse.cdt.core.dom.ast.IMacroBinding; import org.eclipse.cdt.core.dom.rewrite.MacroExpansionExplorer.IMacroExpansionStep; import org.eclipse.text.edits.ReplaceEdit; @@ -21,11 +22,13 @@ public class MacroExpansionStep implements IMacroExpansionStep { private final String fBefore; private final IMacroBinding fMacroDefinition; private final ReplaceEdit[] fReplacements; + private final IASTFileLocation fMacroLocation; - public MacroExpansionStep(String before, IMacroBinding def, ReplaceEdit[] replacements) { + public MacroExpansionStep(String before, IMacroBinding def, IASTFileLocation macroLoc, ReplaceEdit[] replacements) { fBefore= before; fReplacements= replacements; fMacroDefinition= def; + fMacroLocation= macroLoc; } public String getCodeBeforeStep() { @@ -51,4 +54,7 @@ public class MacroExpansionStep implements IMacroExpansionStep { public ReplaceEdit[] getReplacements() { return fReplacements; } + public IASTFileLocation getLocationOfExpandedMacroDefinition() { + return fMacroLocation; + } } 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 eaafaad710f..05264b33c24 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 @@ -11,12 +11,18 @@ package org.eclipse.cdt.internal.core.parser.scanner; import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; import java.util.List; +import java.util.Map; import org.eclipse.cdt.core.dom.ast.IASTFileLocation; import org.eclipse.cdt.core.dom.ast.IASTMacroExpansion; import org.eclipse.cdt.core.dom.ast.IASTName; +import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroDefinition; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; +import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.dom.ast.IMacroBinding; import org.eclipse.cdt.core.dom.rewrite.MacroExpansionExplorer; import org.eclipse.jface.text.IRegion; import org.eclipse.text.edits.ReplaceEdit; @@ -49,17 +55,55 @@ public class MultiMacroExpansionExplorer extends MacroExpansionExplorer { private final char[] fSource; private final int[] fBoundaries; private final SingleMacroExpansionExplorer[] fDelegates; - private String fFilePath; + private final String fFilePath; + private final Map fMacroLocations; public MultiMacroExpansionExplorer(IASTTranslationUnit tu, IASTFileLocation loc) { if (tu == null || loc == null || loc.getNodeLength() == 0) { throw new IllegalArgumentException(); } + final ILocationResolver resolver = getResolver(tu); + final IASTMacroExpansion[] expansions= resolver.getMacroExpansions(loc); + final int count= expansions.length; + + loc = extendLocation(loc, expansions); + fMacroLocations= getMacroLocations(resolver); + fFilePath= tu.getFilePath(); + fSource= resolver.getUnpreprocessedSignature(loc); + fBoundaries= new int[count*2+1]; + fDelegates= new SingleMacroExpansionExplorer[count]; + + final int firstOffset= loc.getNodeOffset(); + int bidx= -1; + int didx= -1; + for (IASTMacroExpansion expansion : expansions) { + IASTName ref= expansion.getMacroReference(); + if (ref != null) { + ArrayList refs= new ArrayList(); + refs.add(ref); + refs.addAll(Arrays.asList(resolver.getImplicitMacroReferences(ref))); + IASTFileLocation refLoc= expansion.asFileLocation(); + int from= refLoc.getNodeOffset()-firstOffset; + int to= from+refLoc.getNodeLength(); + 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()); + } + } + fBoundaries[++bidx]= fSource.length; + } + + private ILocationResolver getResolver(IASTTranslationUnit tu) { final ILocationResolver resolver = (ILocationResolver) tu.getAdapter(ILocationResolver.class); if (resolver == null) { throw new IllegalArgumentException(); } - final IASTMacroExpansion[] expansions = resolver.getMacroExpansions(loc); + return resolver; + } + + private IASTFileLocation extendLocation(IASTFileLocation loc, final IASTMacroExpansion[] expansions) { final int count= expansions.length; if (count > 0) { int from= loc.getNodeOffset(); @@ -75,28 +119,28 @@ public class MultiMacroExpansionExplorer extends MacroExpansionExplorer { loc= new ASTFileLocation(loc.getFileName(), from, to-from); } } - - fFilePath= tu.getFilePath(); - fSource= resolver.getUnpreprocessedSignature(loc); - fBoundaries= new int[count*2+1]; - fDelegates= new SingleMacroExpansionExplorer[count]; + return loc; + } - final int firstOffset= loc.getNodeOffset(); - int bidx= -1; - int didx= -1; - for (IASTMacroExpansion expansion : expansions) { - IASTName ref= expansion.getMacroReference(); - if (ref != null) { - IASTFileLocation refLoc= expansion.asFileLocation(); - int from= refLoc.getNodeOffset()-firstOffset; - int to= from+refLoc.getNodeLength(); - fBoundaries[++bidx]= from; - fBoundaries[++bidx]= to; - fDelegates[++didx]= new SingleMacroExpansionExplorer(new String(fSource, from, to-from), ref, - resolver.getImplicitMacroReferences(ref), fFilePath, refLoc.getStartingLineNumber()); + private Map getMacroLocations(final ILocationResolver resolver) { + final Map result= new HashMap(); + addLocations(resolver.getBuiltinMacroDefinitions(), result); + addLocations(resolver.getMacroDefinitions(), result); + return result; + } + + private void addLocations(IASTPreprocessorMacroDefinition[] defs, + final Map result) { + for (IASTPreprocessorMacroDefinition def : defs) { + IASTFileLocation loc= def.getFileLocation(); + if (loc != null) { + final IBinding binding= def.getName().getBinding(); + if (binding instanceof IMacroBinding) { + loc= new ASTFileLocation(loc.getFileName(), loc.getNodeOffset(), loc.getNodeLength()); + result.put((IMacroBinding) binding, loc); + } } } - fBoundaries[++bidx]= fSource.length; } public MultiMacroExpansionExplorer(final IASTTranslationUnit tu, final IRegion loc) { @@ -106,7 +150,7 @@ public class MultiMacroExpansionExplorer extends MacroExpansionExplorer { @Override public IMacroExpansionStep getFullExpansion() { List edits = combineReplaceEdits(fDelegates.length); - return new MacroExpansionStep(new String(fSource), null, edits.toArray(new ReplaceEdit[edits.size()])); + return new MacroExpansionStep(new String(fSource), null, null, edits.toArray(new ReplaceEdit[edits.size()])); } /** @@ -174,7 +218,7 @@ public class MultiMacroExpansionExplorer extends MacroExpansionExplorer { List replacements= new ArrayList(); shiftAndAddEdits(shift, dresult.getReplacements(), replacements); - return new MacroExpansionStep(before.toString(), dresult.getExpandedMacro(), replacements.toArray(new ReplaceEdit[replacements.size()])); + return new MacroExpansionStep(before.toString(), dresult.getExpandedMacro(), dresult.getLocationOfExpandedMacroDefinition(), replacements.toArray(new ReplaceEdit[replacements.size()])); } private void appendGap(StringBuilder result, int i) { 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 eae46069d0f..9771f5dacc9 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 @@ -10,8 +10,12 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.parser.scanner; +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.IBinding; +import org.eclipse.cdt.core.dom.ast.IMacroBinding; import org.eclipse.cdt.core.dom.rewrite.MacroExpansionExplorer; import org.eclipse.cdt.core.parser.util.CharArrayMap; import org.eclipse.cdt.internal.core.parser.scanner.Lexer.LexerOptions; @@ -34,18 +38,20 @@ public class SingleMacroExpansionExplorer extends MacroExpansionExplorer { private int fExpansionCount; private String fFilePath; private int fLineNumber; + private final Map fMacroLocationMap; - public SingleMacroExpansionExplorer(String input, IASTName ref, IASTName[] implicitRefs, String filePath, int lineNumber) { + public SingleMacroExpansionExplorer(String input, IASTName[] refs, + Map macroDefinitionLocationMap, String filePath, int lineNumber) { fInput= input; - fDictionary= createDictionary(ref, implicitRefs); + fDictionary= createDictionary(refs); + fMacroLocationMap= macroDefinitionLocationMap; fFilePath= filePath; fLineNumber= lineNumber; } - private CharArrayMap createDictionary(IASTName ref, IASTName[] implicitRefs) { - CharArrayMap map= new CharArrayMap(implicitRefs.length+1); - addMacroDefinition(map, ref); - for (IASTName name : implicitRefs) { + private CharArrayMap createDictionary(IASTName[] refs) { + CharArrayMap map= new CharArrayMap(refs.length); + for (IASTName name : refs) { addMacroDefinition(map, name); } return map; @@ -78,7 +84,7 @@ public class SingleMacroExpansionExplorer extends MacroExpansionExplorer { fExpansionCount= tracker.getStepCount(); ReplaceEdit r= tracker.getReplacement(); ReplaceEdit[] replacements= r==null ? new ReplaceEdit[0] : new ReplaceEdit[]{r}; - fFullExpansion= new MacroExpansionStep(fInput, null, replacements); + fFullExpansion= new MacroExpansionStep(fInput, null, null, replacements); } @Override @@ -94,6 +100,7 @@ public class SingleMacroExpansionExplorer extends MacroExpansionExplorer { fExpansionCount= tracker.getStepCount(); ReplaceEdit r= tracker.getReplacement(); ReplaceEdit[] replacements= r==null ? new ReplaceEdit[0] : new ReplaceEdit[]{r}; - return new MacroExpansionStep(tracker.getCodeBeforeStep(), tracker.getExpandedMacro(), replacements); + final IMacroBinding macro = tracker.getExpandedMacro(); + return new MacroExpansionStep(tracker.getCodeBeforeStep(), macro, fMacroLocationMap.get(macro), replacements); } }