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