From 5558b7e7a199ca21674184510de1e7a51efadb8c Mon Sep 17 00:00:00 2001 From: Markus Schorn Date: Tue, 13 Nov 2007 09:55:43 +0000 Subject: [PATCH] Handling of PDOMMacros in CPreprocessor. --- .../eclipse/cdt/core/index/IIndexMacro.java | 9 ++ .../parser/scanner/ASTPreprocessorName.java | 3 - .../parser/scanner/ASTPreprocessorNode.java | 9 ++ .../core/parser/scanner/CPreprocessor.java | 30 ++++--- .../core/parser/scanner/LocationMap.java | 7 ++ .../parser/scanner/MacroDefinitionParser.java | 48 +++++----- .../cdt/internal/core/pdom/dom/PDOMMacro.java | 64 +++++++++----- .../actions/OpenDeclarationsAction.java | 87 ++++++++++--------- .../cdt/internal/ui/viewsupport/IndexUI.java | 15 ++-- 9 files changed, 165 insertions(+), 107 deletions(-) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexMacro.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexMacro.java index d762d594720..8c4ab511273 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexMacro.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexMacro.java @@ -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 null if this is not a function style macro + * @since 5.0 + */ + char[][] getParameterList(); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ASTPreprocessorName.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ASTPreprocessorName.java index b8e981ee2da..89183879a89 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ASTPreprocessorName.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ASTPreprocessorName.java @@ -103,9 +103,6 @@ class ASTBuiltinName extends ASTPreprocessorDefinition { } public IASTFileLocation getFileLocation() { - if (fFileLocation == null) { - throw new UnsupportedOperationException(); - } return fFileLocation; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ASTPreprocessorNode.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ASTPreprocessorNode.java index 0c1b028f196..b412796ebf4 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ASTPreprocessorNode.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ASTPreprocessorNode.java @@ -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; } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/CPreprocessor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/CPreprocessor.java index 5959fd8d3c3..e7109add0e4 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/CPreprocessor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/CPreprocessor.java @@ -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(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/LocationMap.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/LocationMap.java index 559528ed80a..c3f4f3ae928 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/LocationMap.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/LocationMap.java @@ -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]; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/MacroDefinitionParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/MacroDefinitionParser.java index 32915dfdf3a..793462f989c 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/MacroDefinitionParser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/MacroDefinitionParser.java @@ -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; } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMMacro.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMMacro.java index 6b08789c642..0a98eebfd1b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMMacro.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMMacro.java @@ -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(); diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/actions/OpenDeclarationsAction.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/actions/OpenDeclarationsAction.java index 13467b81460..65000bd199c 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/actions/OpenDeclarationsAction.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/actions/OpenDeclarationsAction.java @@ -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) { diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/viewsupport/IndexUI.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/viewsupport/IndexUI.java index 01b837fd21c..880c16a90fc 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/viewsupport/IndexUI.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/viewsupport/IndexUI.java @@ -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)