diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMLocationInclusionTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMLocationInclusionTests.java index 50891171ea7..c73ab8fb4a5 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMLocationInclusionTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMLocationInclusionTests.java @@ -22,6 +22,7 @@ import org.eclipse.cdt.core.dom.IParserConfiguration; import org.eclipse.cdt.core.dom.ast.IASTDeclaration; import org.eclipse.cdt.core.dom.ast.IASTFileLocation; import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition; +import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTNodeLocation; import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement; @@ -192,6 +193,14 @@ public class DOMLocationInclusionTests extends AST2FileBasePluginTest { assertEquals(length, nodeLocation.getNodeLength()); } + private void assertFileLocation(IASTNode n, String pathEndsWith, + int offset, int length) { + IASTFileLocation location = n.getFileLocation(); + assertTrue(location.getFileName().endsWith(pathEndsWith)); + assertEquals(offset, location.getNodeOffset()); + assertEquals(length, location.getNodeLength()); + } + public void testSimpleInclusion() throws Exception { String foo = "int FOO;"; //$NON-NLS-1$ String code = "int bar;\n#include \"foo.h\"\n"; //$NON-NLS-1$ @@ -216,10 +225,21 @@ public class DOMLocationInclusionTests extends AST2FileBasePluginTest { assertNotNull(incs); assertEquals(incs.length, 1); assertSoleFileLocation(incs[0], filename, code.indexOf("#inc"), "#include \"foo.h\"".length()); + + checkInclude(incs[0], filename, code, "foo.h", false); } } - public void testSimpleInclusion2() throws Exception { + private void checkInclude(IASTPreprocessorIncludeStatement inc, String file, String code, String name, boolean system) { + IASTName incName= inc.getName(); + + assertEquals(system, inc.isSystemInclude()); + assertEquals(name, incName.toString()); + assertSoleFileLocation(incName, file, code.indexOf(name), name.length()); + + } + + public void testSimpleInclusion2() throws Exception { String foo = "int FOO;"; //$NON-NLS-1$ String code = "int bar;\n#include \"foo.h\"\nfloat byob;\n"; //$NON-NLS-1$ @@ -531,7 +551,7 @@ public class DOMLocationInclusionTests extends AST2FileBasePluginTest { IFile code = importFile(filename, "int main() { return BEAST * sizeof( Include ); } "); //$NON-NLS-1$ //$NON-NLS-2$ - IASTTranslationUnit tu = parse(code, scannerInfo); //$NON-NLS-1$ + IASTTranslationUnit tu = parse(code, scannerInfo); IASTPreprocessorMacroDefinition[] macro_defs = tu .getMacroDefinitions(); assertEquals(macro_defs.length, 4); @@ -554,4 +574,39 @@ public class DOMLocationInclusionTests extends AST2FileBasePluginTest { } } + + public void testSystemInclude() throws Exception { + IFile incsh= importFile("incs.h", ""); + StringBuffer buffer = new StringBuffer(); + buffer.append("#include \n"); + buffer.append("#include <../AST2BasedProjectMofo/incs.h>\n"); + buffer.append("#define TARG \n"); + buffer.append("#include TARG\n"); + String code= buffer.toString(); + IExtendedScannerInfo scannerInfo = new ExtendedScannerInfo( + Collections.EMPTY_MAP, new String[] {incsh.getLocation().removeLastSegments(1).toOSString()}, null, null); + for (ParserLanguage p = ParserLanguage.C; p != null; p = (p == ParserLanguage.C) ? ParserLanguage.CPP + : null) { + String filename = (p == ParserLanguage.CPP) ? "main.cc" : "main.c"; + IFile sfile = importFile(filename, code); + IASTTranslationUnit tu = parse(sfile, scannerInfo); + + IASTPreprocessorIncludeStatement[] incs = tu.getIncludeDirectives(); + assertNotNull(incs); + assertEquals(3, incs.length); + + assertSoleFileLocation(incs[0], filename, code.indexOf("#include "), "#include ".length()); + checkInclude(incs[0], filename, code, "incs.h", true); + + assertSoleFileLocation(incs[1], filename, code.indexOf("#include <../AST2BasedProjectMofo/incs.h>"), "#include <../AST2BasedProjectMofo/incs.h>".length()); + checkInclude(incs[1], filename, code, "../AST2BasedProjectMofo/incs.h", true); + + assertFileLocation(incs[2], filename, code.indexOf("#include TARG"), "#include TARG".length()); + IASTName incName= incs[2].getName(); + + assertEquals(true, incs[2].isSystemInclude()); + assertEquals("incs.h", incName.toString()); + assertFileLocation(incName, filename, code.lastIndexOf("TARG"), "TARG".length()); + } + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTPreprocessorIncludeStatement.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTPreprocessorIncludeStatement.java index 72e627f03ce..804b30a0264 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTPreprocessorIncludeStatement.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTPreprocessorIncludeStatement.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2005 IBM Corporation and others. + * Copyright (c) 2004, 2006 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -7,6 +7,7 @@ * * Contributors: * IBM - Initial API and implementation + * Markus Schorn (Wind River Systems) *******************************************************************************/ package org.eclipse.cdt.core.dom.ast; @@ -19,10 +20,28 @@ public interface IASTPreprocessorIncludeStatement extends IASTPreprocessorStatement { /** - * Get the full path filename of the file found through #include. - * - * @return + * INCLUDE_NAME describes the relationship between an include directive and + * it's name. + */ + public static final ASTNodeProperty INCLUDE_NAME = new ASTNodeProperty( + "IASTPreprocessorMacroDefinition.INCLUDE_NAME - Include Name"); //$NON-NLS-1$ + + + /** + * Returns the absolute location of the file found through #include. */ public String getPath(); - + + /** + * Returns the name of the file as specified in the directive. Does not include quotes or + * angle brackets. + * @since 4.0 + */ + public IASTName getName(); + + /** + * Returns whether this is a system include (one specified with angle brackets). + * @since 4.0 + */ + public boolean isSystemInclude(); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/CharArrayUtils.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/CharArrayUtils.java index 84169d77a75..7027185bae7 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/CharArrayUtils.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/CharArrayUtils.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2005 IBM Corporation and others. + * Copyright (c) 2004, 2006 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -8,6 +8,7 @@ * Contributors: * IBM Corporation - initial API and implementation * Andrew Ferguson (Symbian) + * Markus Schorn (Wind River Systems) *******************************************************************************/ /* * Created on May 28, 2004 @@ -20,6 +21,8 @@ package org.eclipse.cdt.core.parser.util; * */ public class CharArrayUtils { + public static final char[] EMPTY = new char[0]; + private CharArrayUtils() {} public static final int hash(char[] str, int start, int length) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/BaseScanner.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/BaseScanner.java index 2471a3d28a5..9037daef24e 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/BaseScanner.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/BaseScanner.java @@ -2828,11 +2828,12 @@ abstract class BaseScanner implements IScanner { } break; } - int startPos= pos; - int len= bufferPos[bufferStackPos] - startPos; + nameOffset= pos; + int len= bufferPos[bufferStackPos] - nameOffset; + nameEndOffset= nameOffset + len; bufferPos[bufferStackPos]--; - Object expObject = definitions.get(buffer, startPos, len); + Object expObject = definitions.get(buffer, nameOffset, len); if (expObject != null) { char[] t = null; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/DOMScanner.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/DOMScanner.java index 21d5349d138..fc3b3c3b48e 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/DOMScanner.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/DOMScanner.java @@ -7,6 +7,7 @@ * * Contributors: * IBM - Initial API and implementation + * Markus Schorn (Wind River Systems) *******************************************************************************/ package org.eclipse.cdt.internal.core.parser.scanner2; @@ -40,15 +41,22 @@ public class DOMScanner extends BaseScanner { private static class DOMInclusion { public final char[] pt; - public final int o; + public final int nameOffset; + public final int nameEndoffset; + public final char[] name; + public boolean systemInclude; /** * */ - public DOMInclusion(char[] path, int offset) { + public DOMInclusion(char[] path, int offset, int nameOffset, int nameEndoffset, char[] name, boolean systemInclude) { this.pt = path; this.o = offset; + this.nameOffset= nameOffset; + this.nameEndoffset= nameEndoffset; + this.name= name; + this.systemInclude= systemInclude; } } @@ -133,7 +141,7 @@ public class DOMScanner extends BaseScanner { char[] filenamePath, boolean local, int startOffset, int startingLineNumber, int nameOffset, int nameEndOffset, int nameLine, int endOffset, int endLine, boolean isForced) { - return new DOMInclusion(filenamePath, getGlobalOffset(startOffset)); + return new DOMInclusion(filenamePath, getGlobalOffset(startOffset), nameOffset, nameEndOffset, fileName, !local); } /* @@ -194,7 +202,8 @@ public class DOMScanner extends BaseScanner { if( ! isCircularInclusion( (InclusionData) data )) { DOMInclusion inc = ((DOMInclusion) ((InclusionData) data).inclusion); - locationMap.startInclusion(((InclusionData) data).reader, inc.o, getGlobalOffset(getCurrentOffset())+1); + locationMap.startInclusion(((InclusionData) data).reader, inc.o, getGlobalOffset(getCurrentOffset())+1, + inc.nameOffset, inc.nameEndoffset, inc.name, inc.systemInclude); bufferDelta[bufferStackPos + 1] = 0; } } @@ -220,7 +229,8 @@ public class DOMScanner extends BaseScanner { else if( data instanceof CodeReader && !macroFilesInitialized ) { int resolved = getGlobalOffset(0, 0); - locationMap.startInclusion( (CodeReader) data, resolved, resolved ); + CodeReader codeReader = (CodeReader) data; + locationMap.startInclusion( codeReader, resolved, resolved, resolved, resolved, CharArrayUtils.EMPTY, false); } super.pushContext(buffer, data); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/IScannerPreprocessorLog.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/IScannerPreprocessorLog.java index 75ed7e7801a..81639c104c7 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/IScannerPreprocessorLog.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/IScannerPreprocessorLog.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2005 IBM Corporation and others. + * Copyright (c) 2004, 2006 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -7,6 +7,7 @@ * * Contributors: * IBM - Initial API and implementation + * Markus Schorn (Wind River Systems) *******************************************************************************/ package org.eclipse.cdt.internal.core.parser.scanner2; @@ -23,7 +24,7 @@ public interface IScannerPreprocessorLog { public void endTranslationUnit(int offset); - public void startInclusion(CodeReader reader, int offset, int endOffset); + public void startInclusion(CodeReader reader, int offset, int endOffset, int nameOffset, int nameEndoffset, char[] name, boolean systemInclude); public void endInclusion(CodeReader reader, int offset); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/LocationMap.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/LocationMap.java index 01af7463591..dd456751f2d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/LocationMap.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/LocationMap.java @@ -445,10 +445,12 @@ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog { IASTPreprocessorIncludeStatement { private final char[] path; + private IASTName fName; public int startOffset; - public int endOffset; + private boolean fSystemInclude; + /** * @param cs @@ -469,8 +471,22 @@ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog { public String toString() { return getPath(); } - + public IASTName getName() { + return fName; + } + + public void setName(IASTName name) { + fName= name; + } + + public boolean isSystemInclude() { + return fSystemInclude; + } + + public void setSystemInclude(boolean val) { + fSystemInclude= val; + } } /** @@ -717,6 +733,52 @@ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog { } } + public class ASTIncludeName extends ASTNode implements IASTName { + private final char[] name; + + public ASTIncludeName(char[] n) { + this.name = n; + } + + public IBinding resolveBinding() { + return null; + } + public IBinding[] resolvePrefix() { + return null; + } + + public char[] toCharArray() { + return name; + } + + public String toString() { + return new String(name); + } + + public boolean isDeclaration() { + return false; + } + + public boolean isDefinition() { + return false; + } + + public boolean isReference() { + return false; + } + + public IBinding getBinding() { + return null; + } + + public void setBinding(IBinding binding) { + } + + public ILinkage getLinkage() { + return Linkage.NO_LINKAGE; + } + } + /** * @author jcamelon */ @@ -1111,9 +1173,18 @@ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog { protected static class _Inclusion extends _CompositeFileContext implements _IPreprocessorDirective { - public _Inclusion(_CompositeContext parent, CodeReader reader, - int startOffset, int endOffset) { + public final int fNameOffset; + public final int fNameEndOffset; + public final char[] fName; + public boolean fSystemInclude; + + public _Inclusion(_CompositeContext parent, CodeReader reader, + int startOffset, int endOffset, int nameOffset, int nameEndoffset, char[] name, boolean systemInclude) { super(parent, startOffset, endOffset, reader); + fNameOffset= nameOffset; + fNameEndOffset= nameEndoffset; + fName= name; + fSystemInclude= systemInclude; } } @@ -1143,13 +1214,6 @@ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog { protected static class _MacroDefinition extends _Context implements IMacroDefinition { - /** - * @param parent - * @param startOffset - * @param endOffset - * @param nameOffset - * TODO - */ public _MacroDefinition(_CompositeContext parent, int startOffset, int endOffset, char[] name, int nameOffset, char[] expansion) { super(parent, startOffset, endOffset); @@ -1425,15 +1489,18 @@ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog { * @return */ private IASTPreprocessorIncludeStatement createASTInclusion(_Inclusion inc) { - IASTPreprocessorIncludeStatement result = new ASTInclusionStatement( - inc.reader.filename); - ((ASTNode) result).setOffsetAndLength(inc.context_directive_start, inc.getDirectiveLength()); - ((ASTInclusionStatement) result).startOffset = inc.getContextStart(); - ((ASTInclusionStatement) result).endOffset = inc.context_directive_end; - ((ASTInclusionStatement) result).setParent(rootNode); - ((ASTInclusionStatement) result).setPropertyInParent(IASTTranslationUnit.PREPROCESSOR_STATEMENT); + ASTInclusionStatement result = new ASTInclusionStatement(inc.reader.filename); + result.setOffsetAndLength(inc.context_directive_start, inc.getDirectiveLength()); + result.startOffset = inc.getContextStart(); + result.endOffset = inc.context_directive_end; + ASTIncludeName name= new ASTIncludeName(inc.fName); + name.setPropertyInParent(IASTPreprocessorIncludeStatement.INCLUDE_NAME); + name.setParent(result); + name.setOffsetAndLength(inc.fNameOffset, inc.fNameEndOffset-inc.fNameOffset); + result.setName(name); result.setParent(rootNode); result.setPropertyInParent(IASTTranslationUnit.PREPROCESSOR_STATEMENT); + result.setSystemInclude(inc.fSystemInclude); return result; } @@ -1787,8 +1854,8 @@ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog { * @see org.eclipse.cdt.internal.core.parser.scanner2.IScannerPreprocessorLog#startInclusion(char[], * int) */ - public void startInclusion(CodeReader reader, int offset, int endOffset) { - _Inclusion i = new _Inclusion(currentContext, reader, offset, endOffset); + public void startInclusion(CodeReader reader, int offset, int endOffset, int nameOffset, int nameEndoffset, char[] name, boolean systemInclude) { + _Inclusion i = new _Inclusion(currentContext, reader, offset, endOffset, nameOffset, nameEndoffset, name, systemInclude); currentContext.addSubContext(i); currentContext = i; }