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:
parent
d065bc268e
commit
5558b7e7a1
9 changed files with 165 additions and 107 deletions
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -103,9 +103,6 @@ class ASTBuiltinName extends ASTPreprocessorDefinition {
|
|||
}
|
||||
|
||||
public IASTFileLocation getFileLocation() {
|
||||
if (fFileLocation == null) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
return fFileLocation;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
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();
|
||||
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;
|
||||
}
|
||||
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();
|
||||
|
|
|
@ -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,49 +170,48 @@ public class OpenDeclarationsAction extends SelectionParseAction {
|
|||
if (!found) {
|
||||
reportSymbolLookupFailure(new String(searchName.toCharArray()));
|
||||
}
|
||||
|
||||
} 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();
|
||||
}
|
||||
return Status.OK_STATUS;
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
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) {
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Add table
Reference in a new issue