1
0
Fork 0
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:
Markus Schorn 2008-01-21 10:32:47 +00:00
parent 5a4a75db93
commit 008d8cf1d3
5 changed files with 145 additions and 32 deletions

View file

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

View file

@ -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 <code>null</code> for built-in macros or for a step representing a full expansion.
*/
IASTFileLocation getLocationOfExpandedMacroDefinition();
}
/**

View file

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

View file

@ -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<IMacroBinding, IASTFileLocation> 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<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);
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);
}
}
return loc;
}
fFilePath= tu.getFilePath();
fSource= resolver.getUnpreprocessedSignature(loc);
fBoundaries= new int[count*2+1];
fDelegates= new SingleMacroExpansionExplorer[count];
private Map<IMacroBinding, IASTFileLocation> getMacroLocations(final ILocationResolver resolver) {
final Map<IMacroBinding, IASTFileLocation> result= new HashMap<IMacroBinding, IASTFileLocation>();
addLocations(resolver.getBuiltinMacroDefinitions(), result);
addLocations(resolver.getMacroDefinitions(), result);
return result;
}
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 void addLocations(IASTPreprocessorMacroDefinition[] defs,
final Map<IMacroBinding, IASTFileLocation> 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<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>();
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) {

View file

@ -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<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;
fDictionary= createDictionary(ref, implicitRefs);
fDictionary= createDictionary(refs);
fMacroLocationMap= macroDefinitionLocationMap;
fFilePath= filePath;
fLineNumber= lineNumber;
}
private CharArrayMap<PreprocessorMacro> createDictionary(IASTName ref, IASTName[] implicitRefs) {
CharArrayMap<PreprocessorMacro> map= new CharArrayMap<PreprocessorMacro>(implicitRefs.length+1);
addMacroDefinition(map, ref);
for (IASTName name : implicitRefs) {
private CharArrayMap<PreprocessorMacro> createDictionary(IASTName[] refs) {
CharArrayMap<PreprocessorMacro> map= new CharArrayMap<PreprocessorMacro>(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);
}
}