1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Handling of PDOMMacros in CPreprocessor.

This commit is contained in:
Markus Schorn 2007-11-13 09:55:43 +00:00
parent d065bc268e
commit 5558b7e7a1
9 changed files with 165 additions and 107 deletions

View file

@ -29,6 +29,9 @@ import org.eclipse.core.runtime.CoreException;
* *
* @since 4.0 * @since 4.0
*/ */
// mstodo scanner removal: IIndexMacro should extend IMacroBinding. However, the DOMScanner requires
// the delivery of some internal representation of macros. That's what this interface seems to be
// trimmed to.
public interface IIndexMacro extends IMacro { public interface IIndexMacro extends IMacro {
IIndexMacro[] EMPTY_INDEX_MACRO_ARRAY = new IIndexMacro[0]; IIndexMacro[] EMPTY_INDEX_MACRO_ARRAY = new IIndexMacro[0];
@ -55,4 +58,10 @@ public interface IIndexMacro extends IMacro {
* Returns the length of the name. * Returns the length of the name.
*/ */
public int getNodeLength(); public int getNodeLength();
/**
* Returns the parameter names or <code>null</code> if this is not a function style macro
* @since 5.0
*/
char[][] getParameterList();
} }

View file

@ -103,9 +103,6 @@ class ASTBuiltinName extends ASTPreprocessorDefinition {
} }
public IASTFileLocation getFileLocation() { public IASTFileLocation getFileLocation() {
if (fFileLocation == null) {
throw new UnsupportedOperationException();
}
return fFileLocation; return fFileLocation;
} }

View file

@ -269,6 +269,7 @@ class ASTInclusionStatement extends ASTPreprocessorNode implements IASTPreproces
class ASTMacro extends ASTPreprocessorNode implements IASTPreprocessorObjectStyleMacroDefinition { class ASTMacro extends ASTPreprocessorNode implements IASTPreprocessorObjectStyleMacroDefinition {
private final ASTPreprocessorName fName; private final ASTPreprocessorName fName;
private final int fExpansionNumber; private final int fExpansionNumber;
private final int fExpansionOffset;
/** /**
* Regular constructor. * Regular constructor.
@ -277,6 +278,7 @@ class ASTMacro extends ASTPreprocessorNode implements IASTPreprocessorObjectStyl
int startNumber, int nameNumber, int nameEndNumber, int expansionNumber, int endNumber) { int startNumber, int nameNumber, int nameEndNumber, int expansionNumber, int endNumber) {
super(parent, IASTTranslationUnit.PREPROCESSOR_STATEMENT, startNumber, endNumber); super(parent, IASTTranslationUnit.PREPROCESSOR_STATEMENT, startNumber, endNumber);
fExpansionNumber= expansionNumber; fExpansionNumber= expansionNumber;
fExpansionOffset= -1;
fName= new ASTPreprocessorDefinition(this, IASTPreprocessorMacroDefinition.MACRO_NAME, nameNumber, nameEndNumber, macro.getNameCharArray(), macro); fName= new ASTPreprocessorDefinition(this, IASTPreprocessorMacroDefinition.MACRO_NAME, nameNumber, nameEndNumber, macro.getNameCharArray(), macro);
} }
@ -288,6 +290,7 @@ class ASTMacro extends ASTPreprocessorNode implements IASTPreprocessorObjectStyl
super(parent, IASTTranslationUnit.PREPROCESSOR_STATEMENT, -1, -1); super(parent, IASTTranslationUnit.PREPROCESSOR_STATEMENT, -1, -1);
fName= new ASTBuiltinName(this, IASTPreprocessorMacroDefinition.MACRO_NAME, filename, nameOffset, nameEndOffset, macro.getNameCharArray(), macro); fName= new ASTBuiltinName(this, IASTPreprocessorMacroDefinition.MACRO_NAME, filename, nameOffset, nameEndOffset, macro.getNameCharArray(), macro);
fExpansionNumber= -1; fExpansionNumber= -1;
fExpansionOffset= expansionOffset;
} }
protected IMacroBinding getMacro() { protected IMacroBinding getMacro() {
@ -328,6 +331,12 @@ class ASTMacro extends ASTPreprocessorNode implements IASTPreprocessorObjectStyl
} }
} }
} }
if (fExpansionOffset >= 0) {
String fileName= fName.getContainingFilename();
if (fileName != null) {
return new ASTFileLocationForBuiltins(fileName, fExpansionOffset, getMacro().getExpansionImage().length);
}
}
return null; return null;
} }
} }

View file

@ -21,8 +21,10 @@ import java.util.Iterator;
import java.util.Map; import java.util.Map;
import org.eclipse.cdt.core.dom.ICodeReaderFactory; import org.eclipse.cdt.core.dom.ICodeReaderFactory;
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.parser.IScannerExtensionConfiguration; import org.eclipse.cdt.core.dom.parser.IScannerExtensionConfiguration;
import org.eclipse.cdt.core.index.IIndexMacro;
import org.eclipse.cdt.core.parser.CodeReader; import org.eclipse.cdt.core.parser.CodeReader;
import org.eclipse.cdt.core.parser.EndOfFileException; import org.eclipse.cdt.core.parser.EndOfFileException;
import org.eclipse.cdt.core.parser.IExtendedScannerInfo; import org.eclipse.cdt.core.parser.IExtendedScannerInfo;
@ -811,17 +813,18 @@ public class CPreprocessor implements ILexerLog, IScanner {
} }
public Object createMacro(char[] name, char[][] parameters, char[] expansion) { public void addMacroDefinition(IIndexMacro macro) {
return fMacroDefinitionParser.parseMacroDefinition(name, parameters, expansion); try {
} PreprocessorMacro result= fMacroDefinitionParser.parseMacroDefinition(macro.getName(), macro.getParameterList(), macro.getExpansion());
final IASTFileLocation loc= macro.getFileLocation();
public void addMacroDefinition(Object macro, String filename, int nameOffset, int nameEndOffset, int expansionOffset) { int offset= loc.getNodeOffset();
if (!(macro instanceof PreprocessorMacro)) { int endOffset= offset + loc.getNodeLength();
throw new IllegalArgumentException(); fLocationMap.registerMacroFromIndex(result, loc.getFileName(), offset, endOffset, -1);
fMacroDictionary.put(result.getNameCharArray(), result);
}
catch (Exception e) {
fLog.traceLog("Invalid macro definition: '" + String.valueOf(macro.getName()) + "'"); //$NON-NLS-1$//$NON-NLS-2$
} }
PreprocessorMacro pm= (PreprocessorMacro) macro;
fLocationMap.registerMacroFromIndex(pm, filename, nameOffset, nameEndOffset, expansionOffset);
fMacroDictionary.put(pm.getNameCharArray(), pm);
} }
public ILocationResolver getLocationMap() { public ILocationResolver getLocationMap() {
@ -1397,7 +1400,12 @@ public class CPreprocessor implements ILexerLog, IScanner {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
public void addDefinition(IMacro macro) { public void addDefinition(IMacro macro) {
addMacroDefinition(macro.getSignature(), macro.getExpansion()); if (macro instanceof IIndexMacro) {
addMacroDefinition((IIndexMacro) macro);
}
else {
addMacroDefinition(macro.getSignature(), macro.getExpansion());
}
} }
public IMacro addDefinition(char[] key, char[] value) { public IMacro addDefinition(char[] key, char[] value) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();

View file

@ -498,6 +498,13 @@ public class LocationMap implements ILocationResolver {
IASTPreprocessorMacroDefinition getMacroDefinition(IMacroBinding binding) { IASTPreprocessorMacroDefinition getMacroDefinition(IMacroBinding binding) {
if (fMacroDefinitionMap == null) { if (fMacroDefinitionMap == null) {
fMacroDefinitionMap= new IdentityHashMap(); fMacroDefinitionMap= new IdentityHashMap();
for (int i = 0; i < fBuiltinMacros.size(); i++) {
final IASTPreprocessorMacroDefinition def = (IASTPreprocessorMacroDefinition) fBuiltinMacros.get(i);
final IASTName name = def.getName();
if (name != null) {
fMacroDefinitionMap.put(name.getBinding(), def);
}
}
IASTPreprocessorMacroDefinition[] defs= getMacroDefinitions(); IASTPreprocessorMacroDefinition[] defs= getMacroDefinitions();
for (int i = 0; i < defs.length; i++) { for (int i = 0; i < defs.length; i++) {
final IASTPreprocessorMacroDefinition def = defs[i]; final IASTPreprocessorMacroDefinition def = defs[i];

View file

@ -113,32 +113,34 @@ class MacroDefinitionParser {
* Parses a macro definition basically checking for var-args. * Parses a macro definition basically checking for var-args.
*/ */
public PreprocessorMacro parseMacroDefinition(final char[] name, char[][] paramList, final char[] replacement) { public PreprocessorMacro parseMacroDefinition(final char[] name, char[][] paramList, final char[] replacement) {
final int length = paramList.length;
fHasVarArgs= 0; fHasVarArgs= 0;
if (paramList != null && length > 0) { if (paramList != null) {
char[] lastParam= paramList[length-1]; final int length = paramList.length;
final int lpl = lastParam.length; if (length > 0) {
switch(lpl) { char[] lastParam= paramList[length-1];
case 0: case 1: case 2: final int lpl = lastParam.length;
switch(lpl) {
case 0: case 1: case 2:
break;
case 3:
if (CharArrayUtils.equals(lastParam, Keywords.cpELLIPSIS)) {
fHasVarArgs= FunctionStyleMacro.VAARGS;
char[][] copy= new char[length][];
System.arraycopy(paramList, 0, copy, 0, length-1);
copy[length-1]= Keywords.cVA_ARGS;
paramList= copy;
}
break;
default:
if (CharArrayUtils.equals(lastParam, lpl-3, 3, Keywords.cpELLIPSIS)) {
fHasVarArgs= FunctionStyleMacro.NAMED_VAARGS;
char[][] copy= new char[length][];
System.arraycopy(paramList, 0, copy, 0, length-1);
copy[length-1]= CharArrayUtils.subarray(lastParam, 0, lpl-3);
paramList= copy;
}
break; break;
case 3:
if (CharArrayUtils.equals(lastParam, Keywords.cpELLIPSIS)) {
fHasVarArgs= FunctionStyleMacro.VAARGS;
char[][] copy= new char[length][];
System.arraycopy(paramList, 0, copy, 0, length-1);
copy[length-1]= Keywords.cVA_ARGS;
paramList= copy;
} }
break;
default:
if (CharArrayUtils.equals(lastParam, lpl-3, 3, Keywords.cpELLIPSIS)) {
fHasVarArgs= FunctionStyleMacro.NAMED_VAARGS;
char[][] copy= new char[length][];
System.arraycopy(paramList, 0, copy, 0, length-1);
copy[length-1]= CharArrayUtils.subarray(lastParam, 0, lpl-3);
paramList= copy;
}
break;
} }
} }

View file

@ -42,7 +42,7 @@ public class PDOMMacro implements IIndexMacro, IASTFileLocation {
private final PDOM pdom; private final PDOM pdom;
private final int record; private final int record;
private IMacro macro; private IIndexMacro macro;
private static final byte MACROSTYLE_UNKNOWN = 0; // for reading versions of PDOM <39 private static final byte MACROSTYLE_UNKNOWN = 0; // for reading versions of PDOM <39
private static final byte MACROSTYLE_OBJECT = 1; private static final byte MACROSTYLE_OBJECT = 1;
@ -158,6 +158,9 @@ public class PDOMMacro implements IIndexMacro, IASTFileLocation {
public int getNodeLength() { public int getNodeLength() {
return PDOMMacro.this.getNodeLength(); return PDOMMacro.this.getNodeLength();
} }
public char[][] getParameterList() {
return null;
}
} }
private class FunctionStylePDOMMacro extends FunctionStyleMacro implements IIndexMacro { private class FunctionStylePDOMMacro extends FunctionStyleMacro implements IIndexMacro {
@ -179,6 +182,9 @@ public class PDOMMacro implements IIndexMacro, IASTFileLocation {
public int getNodeLength() { public int getNodeLength() {
return PDOMMacro.this.getNodeLength(); return PDOMMacro.this.getNodeLength();
} }
public char[][] getParameterList() {
return getOriginalParameters();
}
} }
private char[] getMacroExpansion() { private char[] getMacroExpansion() {
@ -196,33 +202,45 @@ public class PDOMMacro implements IIndexMacro, IASTFileLocation {
} }
private void rebuildMacro() throws CoreException { private void rebuildMacro() throws CoreException {
char[] name = getNameInDB(pdom, record).getChars(); if (macro == null) {
PDOMMacroParameter param= getFirstParameter(); char[] name = getNameInDB(pdom, record).getChars();
PDOMMacroParameter param= getFirstParameter();
byte style= pdom.getDB().getByte(record + MACRO_STYLE);
if(style == MACROSTYLE_UNKNOWN) { byte style= pdom.getDB().getByte(record + MACRO_STYLE);
/* PDOM formats < 39 do not store MACRO_STYLE (208558) */ if(style == MACROSTYLE_UNKNOWN) {
style= param != null ? MACROSTYLE_FUNCTION : MACROSTYLE_OBJECT; /* PDOM formats < 39 do not store MACRO_STYLE (208558) */
} style= param != null ? MACROSTYLE_FUNCTION : MACROSTYLE_OBJECT;
switch(style) {
case MACROSTYLE_OBJECT:
macro= new ObjectStylePDOMMacro(name);
break;
case MACROSTYLE_FUNCTION:
List paramList = new ArrayList();
while (param != null) {
paramList.add(param.getName().getChars());
param = param.getNextParameter();
} }
char[][] params = (char[][])paramList.toArray(new char[paramList.size()][]);
macro= new FunctionStylePDOMMacro(name, params); switch(style) {
break; case MACROSTYLE_OBJECT:
default: macro= new ObjectStylePDOMMacro(name);
break;
case MACROSTYLE_FUNCTION:
List paramList = new ArrayList();
while (param != null) {
paramList.add(param.getName().getChars());
param = param.getNextParameter();
}
char[][] params = (char[][])paramList.toArray(new char[paramList.size()][]);
macro= new FunctionStylePDOMMacro(name, params);
break;
default:
throw new PDOMNotImplementedError(); throw new PDOMNotImplementedError();
}
} }
} }
public char[][] getParameterList() {
try {
rebuildMacro();
} catch (CoreException e) {
CCorePlugin.log(e);
return new char[][]{};
}
return macro.getParameterList();
}
public char[] getSignature() { public char[] getSignature() {
try { try {
rebuildMacro(); rebuildMacro();

View file

@ -33,6 +33,7 @@ import org.eclipse.cdt.core.dom.IName;
import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTFileLocation; 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.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement; import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorStatement; import org.eclipse.cdt.core.dom.ast.IASTPreprocessorStatement;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
@ -126,6 +127,11 @@ public class OpenDeclarationsAction extends SelectionParseAction {
if (selectedNames.length > 0 && selectedNames[0] != null) { // just right, only one name selected if (selectedNames.length > 0 && selectedNames[0] != null) { // just right, only one name selected
boolean found = false; boolean found = false;
IASTName searchName = selectedNames[0]; IASTName searchName = selectedNames[0];
final IASTNode parent = searchName.getParent();
if (parent instanceof IASTPreprocessorIncludeStatement) {
openInclude(((IASTPreprocessorIncludeStatement) parent));
return Status.OK_STATUS;
}
boolean isDefinition= searchName.isDefinition(); boolean isDefinition= searchName.isDefinition();
IBinding binding = searchName.resolveBinding(); IBinding binding = searchName.resolveBinding();
if (binding != null && !(binding instanceof IProblemBinding)) { if (binding != null && !(binding instanceof IProblemBinding)) {
@ -164,49 +170,48 @@ public class OpenDeclarationsAction extends SelectionParseAction {
if (!found) { if (!found) {
reportSymbolLookupFailure(new String(searchName.toCharArray())); reportSymbolLookupFailure(new String(searchName.toCharArray()));
} }
return Status.OK_STATUS;
} else { }
// Check if we're in an include statement
IASTPreprocessorStatement[] preprocs = ast.getAllPreprocessorStatements(); // Check if we're in an include statement
boolean foundInInclude = false; IASTPreprocessorStatement[] preprocs = ast.getAllPreprocessorStatements();
for (int i = 0; i < preprocs.length; ++i) { for (int i = 0; i < preprocs.length; ++i) {
if (!(preprocs[i] instanceof IASTPreprocessorIncludeStatement)) if (!(preprocs[i] instanceof IASTPreprocessorIncludeStatement))
continue; continue;
IASTPreprocessorIncludeStatement incStmt = (IASTPreprocessorIncludeStatement)preprocs[i]; IASTPreprocessorIncludeStatement incStmt = (IASTPreprocessorIncludeStatement)preprocs[i];
IASTFileLocation loc = preprocs[i].getFileLocation(); IASTFileLocation loc = preprocs[i].getFileLocation();
if (loc != null if (loc != null
&& loc.getFileName().equals(ast.getFilePath()) && loc.getFileName().equals(ast.getFilePath())
&& loc.getNodeOffset() < selectionStart && loc.getNodeOffset() < selectionStart
&& loc.getNodeOffset() + loc.getNodeLength() > selectionStart) { && loc.getNodeOffset() + loc.getNodeLength() > selectionStart) {
// Got it // Got it
foundInInclude = true; openInclude(incStmt);
String name = null; return Status.OK_STATUS;
if (incStmt.isResolved())
name = incStmt.getPath();
if (name != null) {
final IPath path = new Path(name);
runInUIThread(new Runnable() {
public void run() {
try {
open(path, 0, 0);
} catch (CoreException e) {
CUIPlugin.getDefault().log(e);
}
}
});
} else {
reportIncludeLookupFailure(new String(incStmt.getName().toCharArray()));
}
break;
}
if (!foundInInclude) {
reportSelectionMatchFailure();
}
} }
} }
return Status.OK_STATUS; reportSelectionMatchFailure();
return Status.OK_STATUS;
}
private void openInclude(IASTPreprocessorIncludeStatement incStmt) {
String name = null;
if (incStmt.isResolved())
name = incStmt.getPath();
if (name != null) {
final IPath path = new Path(name);
runInUIThread(new Runnable() {
public void run() {
try {
open(path, 0, 0);
} catch (CoreException e) {
CUIPlugin.getDefault().log(e);
}
}
});
} else {
reportIncludeLookupFailure(new String(incStmt.getName().toCharArray()));
}
} }
private boolean navigateOneLocation(IName[] declNames) { private boolean navigateOneLocation(IName[] declNames) {

View file

@ -307,13 +307,16 @@ public class IndexUI {
} }
public static ITranslationUnit getTranslationUnit(ICProject cproject, IName name) { public static ITranslationUnit getTranslationUnit(ICProject cproject, IName name) {
IPath path= Path.fromOSString(name.getFileLocation().getFileName()); final IASTFileLocation fileLocation = name.getFileLocation();
try { if (fileLocation != null) {
return CoreModelUtil.findTranslationUnitForLocation(path, cproject); IPath path= Path.fromOSString(fileLocation.getFileName());
} catch (CModelException e) { try {
CUIPlugin.getDefault().log(e); return CoreModelUtil.findTranslationUnitForLocation(path, cproject);
return null; } catch (CModelException e) {
CUIPlugin.getDefault().log(e);
}
} }
return null;
} }
public static ICElementHandle getCElementForName(ICProject preferProject, IIndex index, IIndexName declName) public static ICElementHandle getCElementForName(ICProject preferProject, IIndex index, IIndexName declName)