mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
Reporting locations of macro-definitions in macro-explorer, bug 23540.
This commit is contained in:
parent
5a4a75db93
commit
008d8cf1d3
5 changed files with 145 additions and 32 deletions
|
@ -294,4 +294,54 @@ public class ExpansionExplorerTests extends BaseTestCase {
|
||||||
public void testStringify() throws Exception {
|
public void testStringify() throws Exception {
|
||||||
performTest(3);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,6 +47,12 @@ public abstract class MacroExpansionExplorer {
|
||||||
* a step representing a full expansion.
|
* a step representing a full expansion.
|
||||||
*/
|
*/
|
||||||
IMacroBinding getExpandedMacro();
|
IMacroBinding getExpandedMacro();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the location of the macro-definition that gets expanded in this step,
|
||||||
|
* or <code>null</code> for built-in macros or for a step representing a full expansion.
|
||||||
|
*/
|
||||||
|
IASTFileLocation getLocationOfExpandedMacroDefinition();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.core.parser.scanner;
|
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.ast.IMacroBinding;
|
||||||
import org.eclipse.cdt.core.dom.rewrite.MacroExpansionExplorer.IMacroExpansionStep;
|
import org.eclipse.cdt.core.dom.rewrite.MacroExpansionExplorer.IMacroExpansionStep;
|
||||||
import org.eclipse.text.edits.ReplaceEdit;
|
import org.eclipse.text.edits.ReplaceEdit;
|
||||||
|
@ -21,11 +22,13 @@ public class MacroExpansionStep implements IMacroExpansionStep {
|
||||||
private final String fBefore;
|
private final String fBefore;
|
||||||
private final IMacroBinding fMacroDefinition;
|
private final IMacroBinding fMacroDefinition;
|
||||||
private final ReplaceEdit[] fReplacements;
|
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;
|
fBefore= before;
|
||||||
fReplacements= replacements;
|
fReplacements= replacements;
|
||||||
fMacroDefinition= def;
|
fMacroDefinition= def;
|
||||||
|
fMacroLocation= macroLoc;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getCodeBeforeStep() {
|
public String getCodeBeforeStep() {
|
||||||
|
@ -51,4 +54,7 @@ public class MacroExpansionStep implements IMacroExpansionStep {
|
||||||
public ReplaceEdit[] getReplacements() {
|
public ReplaceEdit[] getReplacements() {
|
||||||
return fReplacements;
|
return fReplacements;
|
||||||
}
|
}
|
||||||
|
public IASTFileLocation getLocationOfExpandedMacroDefinition() {
|
||||||
|
return fMacroLocation;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,12 +11,18 @@
|
||||||
package org.eclipse.cdt.internal.core.parser.scanner;
|
package org.eclipse.cdt.internal.core.parser.scanner;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
|
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTMacroExpansion;
|
import org.eclipse.cdt.core.dom.ast.IASTMacroExpansion;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
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.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.cdt.core.dom.rewrite.MacroExpansionExplorer;
|
||||||
import org.eclipse.jface.text.IRegion;
|
import org.eclipse.jface.text.IRegion;
|
||||||
import org.eclipse.text.edits.ReplaceEdit;
|
import org.eclipse.text.edits.ReplaceEdit;
|
||||||
|
@ -49,17 +55,55 @@ public class MultiMacroExpansionExplorer extends MacroExpansionExplorer {
|
||||||
private final char[] fSource;
|
private final char[] fSource;
|
||||||
private final int[] fBoundaries;
|
private final int[] fBoundaries;
|
||||||
private final SingleMacroExpansionExplorer[] fDelegates;
|
private final SingleMacroExpansionExplorer[] fDelegates;
|
||||||
private String fFilePath;
|
private final String fFilePath;
|
||||||
|
private final Map<IMacroBinding, IASTFileLocation> fMacroLocations;
|
||||||
|
|
||||||
public MultiMacroExpansionExplorer(IASTTranslationUnit tu, IASTFileLocation loc) {
|
public MultiMacroExpansionExplorer(IASTTranslationUnit tu, IASTFileLocation loc) {
|
||||||
if (tu == null || loc == null || loc.getNodeLength() == 0) {
|
if (tu == null || loc == null || loc.getNodeLength() == 0) {
|
||||||
throw new IllegalArgumentException();
|
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<IASTName> refs= new ArrayList<IASTName>();
|
||||||
|
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);
|
final ILocationResolver resolver = (ILocationResolver) tu.getAdapter(ILocationResolver.class);
|
||||||
if (resolver == null) {
|
if (resolver == null) {
|
||||||
throw new IllegalArgumentException();
|
throw new IllegalArgumentException();
|
||||||
}
|
}
|
||||||
final IASTMacroExpansion[] expansions = resolver.getMacroExpansions(loc);
|
return resolver;
|
||||||
|
}
|
||||||
|
|
||||||
|
private IASTFileLocation extendLocation(IASTFileLocation loc, final IASTMacroExpansion[] expansions) {
|
||||||
final int count= expansions.length;
|
final int count= expansions.length;
|
||||||
if (count > 0) {
|
if (count > 0) {
|
||||||
int from= loc.getNodeOffset();
|
int from= loc.getNodeOffset();
|
||||||
|
@ -75,28 +119,28 @@ public class MultiMacroExpansionExplorer extends MacroExpansionExplorer {
|
||||||
loc= new ASTFileLocation(loc.getFileName(), from, to-from);
|
loc= new ASTFileLocation(loc.getFileName(), from, to-from);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return loc;
|
||||||
|
}
|
||||||
|
|
||||||
fFilePath= tu.getFilePath();
|
private Map<IMacroBinding, IASTFileLocation> getMacroLocations(final ILocationResolver resolver) {
|
||||||
fSource= resolver.getUnpreprocessedSignature(loc);
|
final Map<IMacroBinding, IASTFileLocation> result= new HashMap<IMacroBinding, IASTFileLocation>();
|
||||||
fBoundaries= new int[count*2+1];
|
addLocations(resolver.getBuiltinMacroDefinitions(), result);
|
||||||
fDelegates= new SingleMacroExpansionExplorer[count];
|
addLocations(resolver.getMacroDefinitions(), result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
final int firstOffset= loc.getNodeOffset();
|
private void addLocations(IASTPreprocessorMacroDefinition[] defs,
|
||||||
int bidx= -1;
|
final Map<IMacroBinding, IASTFileLocation> result) {
|
||||||
int didx= -1;
|
for (IASTPreprocessorMacroDefinition def : defs) {
|
||||||
for (IASTMacroExpansion expansion : expansions) {
|
IASTFileLocation loc= def.getFileLocation();
|
||||||
IASTName ref= expansion.getMacroReference();
|
if (loc != null) {
|
||||||
if (ref != null) {
|
final IBinding binding= def.getName().getBinding();
|
||||||
IASTFileLocation refLoc= expansion.asFileLocation();
|
if (binding instanceof IMacroBinding) {
|
||||||
int from= refLoc.getNodeOffset()-firstOffset;
|
loc= new ASTFileLocation(loc.getFileName(), loc.getNodeOffset(), loc.getNodeLength());
|
||||||
int to= from+refLoc.getNodeLength();
|
result.put((IMacroBinding) binding, loc);
|
||||||
fBoundaries[++bidx]= from;
|
}
|
||||||
fBoundaries[++bidx]= to;
|
|
||||||
fDelegates[++didx]= new SingleMacroExpansionExplorer(new String(fSource, from, to-from), ref,
|
|
||||||
resolver.getImplicitMacroReferences(ref), fFilePath, refLoc.getStartingLineNumber());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fBoundaries[++bidx]= fSource.length;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public MultiMacroExpansionExplorer(final IASTTranslationUnit tu, final IRegion loc) {
|
public MultiMacroExpansionExplorer(final IASTTranslationUnit tu, final IRegion loc) {
|
||||||
|
@ -106,7 +150,7 @@ public class MultiMacroExpansionExplorer extends MacroExpansionExplorer {
|
||||||
@Override
|
@Override
|
||||||
public IMacroExpansionStep getFullExpansion() {
|
public IMacroExpansionStep getFullExpansion() {
|
||||||
List<ReplaceEdit> edits = combineReplaceEdits(fDelegates.length);
|
List<ReplaceEdit> 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<ReplaceEdit> replacements= new ArrayList<ReplaceEdit>();
|
List<ReplaceEdit> replacements= new ArrayList<ReplaceEdit>();
|
||||||
shiftAndAddEdits(shift, dresult.getReplacements(), replacements);
|
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) {
|
private void appendGap(StringBuilder result, int i) {
|
||||||
|
|
|
@ -10,8 +10,12 @@
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.core.parser.scanner;
|
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.IASTName;
|
||||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
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.dom.rewrite.MacroExpansionExplorer;
|
||||||
import org.eclipse.cdt.core.parser.util.CharArrayMap;
|
import org.eclipse.cdt.core.parser.util.CharArrayMap;
|
||||||
import org.eclipse.cdt.internal.core.parser.scanner.Lexer.LexerOptions;
|
import org.eclipse.cdt.internal.core.parser.scanner.Lexer.LexerOptions;
|
||||||
|
@ -34,18 +38,20 @@ public class SingleMacroExpansionExplorer extends MacroExpansionExplorer {
|
||||||
private int fExpansionCount;
|
private int fExpansionCount;
|
||||||
private String fFilePath;
|
private String fFilePath;
|
||||||
private int fLineNumber;
|
private int fLineNumber;
|
||||||
|
private final Map<IMacroBinding, IASTFileLocation> fMacroLocationMap;
|
||||||
|
|
||||||
public SingleMacroExpansionExplorer(String input, IASTName ref, IASTName[] implicitRefs, String filePath, int lineNumber) {
|
public SingleMacroExpansionExplorer(String input, IASTName[] refs,
|
||||||
|
Map<IMacroBinding, IASTFileLocation> macroDefinitionLocationMap, String filePath, int lineNumber) {
|
||||||
fInput= input;
|
fInput= input;
|
||||||
fDictionary= createDictionary(ref, implicitRefs);
|
fDictionary= createDictionary(refs);
|
||||||
|
fMacroLocationMap= macroDefinitionLocationMap;
|
||||||
fFilePath= filePath;
|
fFilePath= filePath;
|
||||||
fLineNumber= lineNumber;
|
fLineNumber= lineNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
private CharArrayMap<PreprocessorMacro> createDictionary(IASTName ref, IASTName[] implicitRefs) {
|
private CharArrayMap<PreprocessorMacro> createDictionary(IASTName[] refs) {
|
||||||
CharArrayMap<PreprocessorMacro> map= new CharArrayMap<PreprocessorMacro>(implicitRefs.length+1);
|
CharArrayMap<PreprocessorMacro> map= new CharArrayMap<PreprocessorMacro>(refs.length);
|
||||||
addMacroDefinition(map, ref);
|
for (IASTName name : refs) {
|
||||||
for (IASTName name : implicitRefs) {
|
|
||||||
addMacroDefinition(map, name);
|
addMacroDefinition(map, name);
|
||||||
}
|
}
|
||||||
return map;
|
return map;
|
||||||
|
@ -78,7 +84,7 @@ public class SingleMacroExpansionExplorer extends MacroExpansionExplorer {
|
||||||
fExpansionCount= tracker.getStepCount();
|
fExpansionCount= tracker.getStepCount();
|
||||||
ReplaceEdit r= tracker.getReplacement();
|
ReplaceEdit r= tracker.getReplacement();
|
||||||
ReplaceEdit[] replacements= r==null ? new ReplaceEdit[0] : new ReplaceEdit[]{r};
|
ReplaceEdit[] replacements= r==null ? new ReplaceEdit[0] : new ReplaceEdit[]{r};
|
||||||
fFullExpansion= new MacroExpansionStep(fInput, null, replacements);
|
fFullExpansion= new MacroExpansionStep(fInput, null, null, replacements);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -94,6 +100,7 @@ public class SingleMacroExpansionExplorer extends MacroExpansionExplorer {
|
||||||
fExpansionCount= tracker.getStepCount();
|
fExpansionCount= tracker.getStepCount();
|
||||||
ReplaceEdit r= tracker.getReplacement();
|
ReplaceEdit r= tracker.getReplacement();
|
||||||
ReplaceEdit[] replacements= r==null ? new ReplaceEdit[0] : new ReplaceEdit[]{r};
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue