mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
Testcase and fix for 106275, IASTPreprocessorIncludeStatement incomplete.
This commit is contained in:
parent
f60b2f1bb1
commit
df871fe06b
7 changed files with 194 additions and 38 deletions
|
@ -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 <incs.h>\n");
|
||||
buffer.append("#include <../AST2BasedProjectMofo/incs.h>\n");
|
||||
buffer.append("#define TARG <incs.h>\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 <incs.h>"), "#include <incs.h>".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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
* <code>INCLUDE_NAME</code> 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();
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue