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
*/
// 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 {
IIndexMacro[] EMPTY_INDEX_MACRO_ARRAY = new IIndexMacro[0];
@ -55,4 +58,10 @@ public interface IIndexMacro extends IMacro {
* Returns the length of the name.
*/
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() {
if (fFileLocation == null) {
throw new UnsupportedOperationException();
}
return fFileLocation;
}

View file

@ -269,6 +269,7 @@ class ASTInclusionStatement extends ASTPreprocessorNode implements IASTPreproces
class ASTMacro extends ASTPreprocessorNode implements IASTPreprocessorObjectStyleMacroDefinition {
private final ASTPreprocessorName fName;
private final int fExpansionNumber;
private final int fExpansionOffset;
/**
* Regular constructor.
@ -277,6 +278,7 @@ class ASTMacro extends ASTPreprocessorNode implements IASTPreprocessorObjectStyl
int startNumber, int nameNumber, int nameEndNumber, int expansionNumber, int endNumber) {
super(parent, IASTTranslationUnit.PREPROCESSOR_STATEMENT, startNumber, endNumber);
fExpansionNumber= expansionNumber;
fExpansionOffset= -1;
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);
fName= new ASTBuiltinName(this, IASTPreprocessorMacroDefinition.MACRO_NAME, filename, nameOffset, nameEndOffset, macro.getNameCharArray(), macro);
fExpansionNumber= -1;
fExpansionOffset= expansionOffset;
}
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;
}
}

View file

@ -21,8 +21,10 @@ import java.util.Iterator;
import java.util.Map;
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.parser.IScannerExtensionConfiguration;
import org.eclipse.cdt.core.index.IIndexMacro;
import org.eclipse.cdt.core.parser.CodeReader;
import org.eclipse.cdt.core.parser.EndOfFileException;
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) {
return fMacroDefinitionParser.parseMacroDefinition(name, parameters, expansion);
}
public void addMacroDefinition(Object macro, String filename, int nameOffset, int nameEndOffset, int expansionOffset) {
if (!(macro instanceof PreprocessorMacro)) {
throw new IllegalArgumentException();
public void addMacroDefinition(IIndexMacro macro) {
try {
PreprocessorMacro result= fMacroDefinitionParser.parseMacroDefinition(macro.getName(), macro.getParameterList(), macro.getExpansion());
final IASTFileLocation loc= macro.getFileLocation();
int offset= loc.getNodeOffset();
int endOffset= offset + loc.getNodeLength();
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() {
@ -1397,7 +1400,12 @@ public class CPreprocessor implements ILexerLog, IScanner {
throw new UnsupportedOperationException();
}
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) {
throw new UnsupportedOperationException();

View file

@ -498,6 +498,13 @@ public class LocationMap implements ILocationResolver {
IASTPreprocessorMacroDefinition getMacroDefinition(IMacroBinding binding) {
if (fMacroDefinitionMap == null) {
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();
for (int i = 0; i < defs.length; i++) {
final IASTPreprocessorMacroDefinition def = defs[i];

View file

@ -113,32 +113,34 @@ class MacroDefinitionParser {
* Parses a macro definition basically checking for var-args.
*/
public PreprocessorMacro parseMacroDefinition(final char[] name, char[][] paramList, final char[] replacement) {
final int length = paramList.length;
fHasVarArgs= 0;
if (paramList != null && length > 0) {
char[] lastParam= paramList[length-1];
final int lpl = lastParam.length;
switch(lpl) {
case 0: case 1: case 2:
if (paramList != null) {
final int length = paramList.length;
if (length > 0) {
char[] lastParam= paramList[length-1];
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;
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 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_OBJECT = 1;
@ -158,6 +158,9 @@ public class PDOMMacro implements IIndexMacro, IASTFileLocation {
public int getNodeLength() {
return PDOMMacro.this.getNodeLength();
}
public char[][] getParameterList() {
return null;
}
}
private class FunctionStylePDOMMacro extends FunctionStyleMacro implements IIndexMacro {
@ -179,6 +182,9 @@ public class PDOMMacro implements IIndexMacro, IASTFileLocation {
public int getNodeLength() {
return PDOMMacro.this.getNodeLength();
}
public char[][] getParameterList() {
return getOriginalParameters();
}
}
private char[] getMacroExpansion() {
@ -196,33 +202,45 @@ public class PDOMMacro implements IIndexMacro, IASTFileLocation {
}
private void rebuildMacro() throws CoreException {
char[] name = getNameInDB(pdom, record).getChars();
PDOMMacroParameter param= getFirstParameter();
if (macro == null) {
char[] name = getNameInDB(pdom, record).getChars();
PDOMMacroParameter param= getFirstParameter();
byte style= pdom.getDB().getByte(record + MACRO_STYLE);
if(style == MACROSTYLE_UNKNOWN) {
/* 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();
byte style= pdom.getDB().getByte(record + MACRO_STYLE);
if(style == MACROSTYLE_UNKNOWN) {
/* PDOM formats < 39 do not store MACRO_STYLE (208558) */
style= param != null ? MACROSTYLE_FUNCTION : MACROSTYLE_OBJECT;
}
char[][] params = (char[][])paramList.toArray(new char[paramList.size()][]);
macro= new FunctionStylePDOMMacro(name, params);
break;
default:
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);
break;
default:
throw new PDOMNotImplementedError();
}
}
}
public char[][] getParameterList() {
try {
rebuildMacro();
} catch (CoreException e) {
CCorePlugin.log(e);
return new char[][]{};
}
return macro.getParameterList();
}
public char[] getSignature() {
try {
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.IASTFileLocation;
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.IASTPreprocessorStatement;
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
boolean found = false;
IASTName searchName = selectedNames[0];
final IASTNode parent = searchName.getParent();
if (parent instanceof IASTPreprocessorIncludeStatement) {
openInclude(((IASTPreprocessorIncludeStatement) parent));
return Status.OK_STATUS;
}
boolean isDefinition= searchName.isDefinition();
IBinding binding = searchName.resolveBinding();
if (binding != null && !(binding instanceof IProblemBinding)) {
@ -164,51 +170,50 @@ public class OpenDeclarationsAction extends SelectionParseAction {
if (!found) {
reportSymbolLookupFailure(new String(searchName.toCharArray()));
}
return Status.OK_STATUS;
}
} else {
// Check if we're in an include statement
IASTPreprocessorStatement[] preprocs = ast.getAllPreprocessorStatements();
boolean foundInInclude = false;
for (int i = 0; i < preprocs.length; ++i) {
if (!(preprocs[i] instanceof IASTPreprocessorIncludeStatement))
continue;
IASTPreprocessorIncludeStatement incStmt = (IASTPreprocessorIncludeStatement)preprocs[i];
IASTFileLocation loc = preprocs[i].getFileLocation();
if (loc != null
&& loc.getFileName().equals(ast.getFilePath())
&& loc.getNodeOffset() < selectionStart
&& loc.getNodeOffset() + loc.getNodeLength() > selectionStart) {
// Got it
foundInInclude = true;
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()));
}
break;
}
if (!foundInInclude) {
reportSelectionMatchFailure();
}
// Check if we're in an include statement
IASTPreprocessorStatement[] preprocs = ast.getAllPreprocessorStatements();
for (int i = 0; i < preprocs.length; ++i) {
if (!(preprocs[i] instanceof IASTPreprocessorIncludeStatement))
continue;
IASTPreprocessorIncludeStatement incStmt = (IASTPreprocessorIncludeStatement)preprocs[i];
IASTFileLocation loc = preprocs[i].getFileLocation();
if (loc != null
&& loc.getFileName().equals(ast.getFilePath())
&& loc.getNodeOffset() < selectionStart
&& loc.getNodeOffset() + loc.getNodeLength() > selectionStart) {
// Got it
openInclude(incStmt);
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) {
for (int i = 0; i < declNames.length; i++) {
IASTFileLocation fileloc = declNames[i].getFileLocation();

View file

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