1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-10 17:55:39 +02:00

Added support for MacroExpansions as IASTNodeLocation.

Fixed Bug 88108 - Add support for Macro bindings.
This commit is contained in:
John Camelon 2005-04-05 17:06:22 +00:00
parent e4e566f433
commit 1e8393f7a2
28 changed files with 1834 additions and 710 deletions

View file

@ -0,0 +1,302 @@
/**********************************************************************
* Copyright (c) 2004 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM - Initial API and implementation
**********************************************************************/
package org.eclipse.cdt.core.parser.tests.ast2;
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
import org.eclipse.cdt.core.dom.ast.IASTMacroExpansion;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNodeLocation;
import org.eclipse.cdt.core.dom.ast.IASTPointer;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorFunctionStyleMacroDefinition;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroDefinition;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorObjectStyleMacroDefinition;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorUndefStatement;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IMacroBinding;
import org.eclipse.cdt.core.parser.ParserLanguage;
import org.eclipse.cdt.internal.core.parser.ParserException;
public class DOMLocationMacroTests extends AST2BaseTest {
public void testObjectStyleMacroExpansionSimpleDeclarator() throws Exception
{
StringBuffer buffer = new StringBuffer( "#define ABC D\n" ); //$NON-NLS-1$
buffer.append( "int ABC;"); //$NON-NLS-1$
String code = buffer.toString();
for (ParserLanguage p = ParserLanguage.C; p != null; p = (p == ParserLanguage.C) ? ParserLanguage.CPP
: null) {
IASTTranslationUnit tu = parse(code, p);
IASTPreprocessorObjectStyleMacroDefinition ABC = (IASTPreprocessorObjectStyleMacroDefinition) tu.getMacroDefinitions()[0];
IASTSimpleDeclaration var = (IASTSimpleDeclaration) tu.getDeclarations()[0];
IASTDeclarator d = var.getDeclarators()[0];
assertEquals( d.getName().toString(), "D"); //$NON-NLS-1$
IASTNodeLocation [] declaratorLocations = d.getNodeLocations();
assertEquals( declaratorLocations.length, 1 );
IASTMacroExpansion expansion = (IASTMacroExpansion) declaratorLocations[0];
IASTPreprocessorObjectStyleMacroDefinition fromExpansion = (IASTPreprocessorObjectStyleMacroDefinition) expansion.getMacroDefinition();
assertEqualsMacros( fromExpansion, ABC );
assertEquals( expansion.getNodeOffset(), 0 );
assertEquals( expansion.getNodeLength(), 1 );
IASTNodeLocation [] macroLocation = expansion.getExpansionLocations();
assertEquals( macroLocation.length, 1 );
assertTrue( macroLocation[0] instanceof IASTFileLocation );
assertEquals( macroLocation[0].getNodeOffset(), code.indexOf( "int ABC;") + "int ".length() ); //$NON-NLS-1$ //$NON-NLS-2$
assertEquals( macroLocation[0].getNodeLength(), "ABC".length() ); //$NON-NLS-1$
}
}
public void testObjectMacroExpansionModestDeclarator() throws Exception
{
StringBuffer buffer = new StringBuffer( "#define ABC * D\n" ); //$NON-NLS-1$
buffer.append( "int ABC;"); //$NON-NLS-1$
String code = buffer.toString();
for (ParserLanguage p = ParserLanguage.C; p != null; p = (p == ParserLanguage.C) ? ParserLanguage.CPP
: null) {
IASTTranslationUnit tu = parse(code, p);
IASTPreprocessorObjectStyleMacroDefinition ABC = (IASTPreprocessorObjectStyleMacroDefinition) tu.getMacroDefinitions()[0];
IASTSimpleDeclaration var = (IASTSimpleDeclaration) tu.getDeclarations()[0];
IASTDeclarator d = var.getDeclarators()[0];
assertEquals( d.getName().toString(), "D"); //$NON-NLS-1$
assertEquals( d.getPointerOperators().length, 1 );
IASTNodeLocation [] declaratorLocations = d.getNodeLocations();
assertEquals( declaratorLocations.length, 1 );
IASTMacroExpansion expansion = (IASTMacroExpansion) declaratorLocations[0];
IASTPreprocessorObjectStyleMacroDefinition fromExpansion = (IASTPreprocessorObjectStyleMacroDefinition) expansion.getMacroDefinition();
assertEqualsMacros( fromExpansion, ABC );
assertEquals( expansion.getNodeOffset(), 0 );
assertEquals( expansion.getNodeLength(), 3 );
IASTNodeLocation [] macroLocation = expansion.getExpansionLocations();
assertEquals( macroLocation.length, 1 );
assertTrue( macroLocation[0] instanceof IASTFileLocation );
assertEquals( macroLocation[0].getNodeOffset(), code.indexOf( "int ABC;") + "int ".length() ); //$NON-NLS-1$ //$NON-NLS-2$
assertEquals( macroLocation[0].getNodeLength(), "ABC".length() ); //$NON-NLS-1$
IASTName n = d.getName();
IASTNodeLocation [] nameLocations = n.getNodeLocations();
assertEquals( nameLocations.length, 1 );
final IASTMacroExpansion nodeLocation = (IASTMacroExpansion) nameLocations[0];
assertEquals( nodeLocation.getNodeOffset(), 2 );
assertEquals( nodeLocation.getNodeLength(), 1 );
assertEquals( nodeLocation.getExpansionLocations()[0].getNodeOffset(), macroLocation[0].getNodeOffset() );
assertEquals( nodeLocation.getExpansionLocations()[0].getNodeLength(), macroLocation[0].getNodeLength() );
IASTPointer po = (IASTPointer) d.getPointerOperators()[0];
assertFalse( po.isConst() );
assertFalse( po.isVolatile() );
IASTMacroExpansion pointerLocation = (IASTMacroExpansion) po.getNodeLocations()[0];
assertEquals( pointerLocation.getNodeOffset(), 0 );
assertEquals( pointerLocation.getNodeLength(), 1 );
assertEquals( pointerLocation.getExpansionLocations()[0].getNodeOffset(), macroLocation[0].getNodeOffset() );
assertEquals( pointerLocation.getExpansionLocations()[0].getNodeLength(), macroLocation[0].getNodeLength() );
assertEqualsMacros( pointerLocation.getMacroDefinition(), nodeLocation.getMacroDefinition() );
}
}
public void testObjectMacroExpansionPartialDeclSpec() throws Exception
{
StringBuffer buffer = new StringBuffer( "#define XYZ const\n"); //$NON-NLS-1$
buffer.append( "XYZ int var;"); //$NON-NLS-1$
String code = buffer.toString();
for (ParserLanguage p = ParserLanguage.C; p != null; p = (p == ParserLanguage.C) ? ParserLanguage.CPP
: null) {
IASTTranslationUnit tu = parse(code, p);
IASTPreprocessorObjectStyleMacroDefinition XYZ = (IASTPreprocessorObjectStyleMacroDefinition) tu.getMacroDefinitions()[0];
IASTSimpleDeclaration var = (IASTSimpleDeclaration) tu.getDeclarations()[0];
IASTSimpleDeclSpecifier declSpec = (IASTSimpleDeclSpecifier) var.getDeclSpecifier();
IASTNodeLocation [] declSpecLocations = declSpec.getNodeLocations();
assertEquals( declSpecLocations.length, 2 );
IASTMacroExpansion expansion = (IASTMacroExpansion) declSpecLocations[0];
assertEqualsMacros( XYZ, expansion.getMacroDefinition() );
assertEquals( expansion.getNodeOffset(), 0 );
assertEquals( expansion.getNodeLength(), 6 );
IASTNodeLocation [] expansionLocations = expansion.getExpansionLocations();
assertEquals( expansionLocations.length, 1 );
assertTrue( expansionLocations[0] instanceof IASTFileLocation );
assertEquals( expansionLocations[0].getNodeOffset(), code.indexOf( "XYZ int")); //$NON-NLS-1$
assertEquals( expansionLocations[0].getNodeLength(), "XYZ".length()); //$NON-NLS-1$
IASTFileLocation second = (IASTFileLocation) declSpecLocations[1];
assertEquals( second.getNodeOffset(), code.indexOf( " int") ); //$NON-NLS-1$
assertEquals( second.getNodeLength(), " int".length() ); //$NON-NLS-1$
}
}
public void testObjectMacroExpansionNested() throws Exception
{
StringBuffer buffer = new StringBuffer( "#define XYZ const\n"); //$NON-NLS-1$
buffer.append( "#define PO *\n"); //$NON-NLS-1$
buffer.append( "#define C_PO PO XYZ\n"); //$NON-NLS-1$
buffer.append( "int C_PO var;"); //$NON-NLS-1$
String code = buffer.toString();
for (ParserLanguage p = ParserLanguage.C; p != null; p = (p == ParserLanguage.C) ? ParserLanguage.CPP
: null) {
IASTTranslationUnit tu = parse(code, p);
final IASTPreprocessorMacroDefinition[] macroDefinitions = tu.getMacroDefinitions();
IASTPreprocessorMacroDefinition XYZ = macroDefinitions[0];
IASTPreprocessorMacroDefinition PO = macroDefinitions[1];
IASTPreprocessorMacroDefinition C_PO = macroDefinitions[2];
IASTSimpleDeclaration var = (IASTSimpleDeclaration) tu.getDeclarations()[0];
assertTrue( var.getDeclarators()[0].getPointerOperators().length > 0 );
IASTNodeLocation [] locations = var.getNodeLocations();
assertEquals( 3, locations.length);
IASTFileLocation start_loc = (IASTFileLocation) locations[0];
assertEquals( start_loc.getNodeOffset(), code.indexOf( "int") ); //$NON-NLS-1$
assertEquals( start_loc.getNodeLength(), "int ".length()); //$NON-NLS-1$
IASTMacroExpansion mac_loc = (IASTMacroExpansion) locations[1];
final IASTPreprocessorMacroDefinition C_PO2 = mac_loc.getMacroDefinition();
assertEqualsMacros( C_PO, C_PO2 );
assertEquals( 0, mac_loc.getNodeOffset());
assertEquals( 4+ C_PO.getExpansion().length() + XYZ.getExpansion().length() + PO.getExpansion().length(), mac_loc.getNodeLength() );
IASTFileLocation end_loc = (IASTFileLocation) locations[2];
assertEquals( code.indexOf( " var"), end_loc.getNodeOffset() ); //$NON-NLS-1$
assertEquals( " var;".length(), end_loc.getNodeLength() ); //$NON-NLS-1$
}
}
public void testObjectMacroExpansionComplex() throws Exception
{
StringBuffer buffer = new StringBuffer( "#define XYZ const\n"); //$NON-NLS-1$
buffer.append( "#define PO *\n"); //$NON-NLS-1$
buffer.append( "#define C_PO PO XYZ\n"); //$NON-NLS-1$
buffer.append( "#define IT int\n"); //$NON-NLS-1$
buffer.append( "#define V var\n"); //$NON-NLS-1$
buffer.append( "XYZ IT C_PO C_PO V;"); //$NON-NLS-1$
String code = buffer.toString();
for (ParserLanguage p = ParserLanguage.C; p != null; p = (p == ParserLanguage.C) ? ParserLanguage.CPP
: null) {
IASTTranslationUnit tu = parse(code, p);
IASTPreprocessorObjectStyleMacroDefinition XYZ = (IASTPreprocessorObjectStyleMacroDefinition) tu.getMacroDefinitions()[0];
// IASTPreprocessorObjectStyleMacroDefinition PO = (IASTPreprocessorObjectStyleMacroDefinition) tu.getMacroDefinitions()[1];
IASTPreprocessorObjectStyleMacroDefinition C_PO = (IASTPreprocessorObjectStyleMacroDefinition) tu.getMacroDefinitions()[2];
IASTPreprocessorObjectStyleMacroDefinition IT = (IASTPreprocessorObjectStyleMacroDefinition) tu.getMacroDefinitions()[3];
IASTPreprocessorObjectStyleMacroDefinition V = (IASTPreprocessorObjectStyleMacroDefinition) tu.getMacroDefinitions()[4];
IASTSimpleDeclaration var = (IASTSimpleDeclaration) tu.getDeclarations()[0];
final IASTNodeLocation[] nodeLocations = var.getNodeLocations();
assertEquals( 10, nodeLocations.length );
IASTMacroExpansion first_loc = (IASTMacroExpansion) nodeLocations[0];
assertEqualsMacros( first_loc.getMacroDefinition(), XYZ );
IASTFileLocation second_loc = (IASTFileLocation) nodeLocations[1];
assertEquals( 1, second_loc.getNodeLength() );
IASTMacroExpansion third_loc = (IASTMacroExpansion) nodeLocations[2];
assertEqualsMacros( third_loc.getMacroDefinition(), IT );
IASTFileLocation fourth_loc = (IASTFileLocation) nodeLocations[3];
assertEquals( 1, fourth_loc.getNodeLength() );
IASTMacroExpansion fifth_loc = (IASTMacroExpansion) nodeLocations[4];
assertEqualsMacros( fifth_loc.getMacroDefinition(), C_PO );
IASTFileLocation sixth_loc = (IASTFileLocation) nodeLocations[5];
assertEquals( 1, sixth_loc.getNodeLength() );
IASTMacroExpansion seventh_loc = (IASTMacroExpansion) nodeLocations[6];
assertEqualsMacros( seventh_loc.getMacroDefinition(), C_PO );
IASTFileLocation eighth_loc = (IASTFileLocation) nodeLocations[7];
assertEquals( 1, eighth_loc.getNodeLength() );
IASTMacroExpansion ninth_loc = (IASTMacroExpansion) nodeLocations[8];
assertEqualsMacros( ninth_loc.getMacroDefinition(), V );
IASTFileLocation tenth_loc = (IASTFileLocation) nodeLocations[9];
assertEquals( 1, tenth_loc.getNodeLength() );
final IASTFileLocation flatLocation = tu.flattenLocationsToFile(nodeLocations);
assertNotNull( flatLocation);
assertEquals( code.indexOf("XYZ IT C_PO C_PO V;"), flatLocation.getNodeOffset() ); //$NON-NLS-1$
assertEquals( "XYZ IT C_PO C_PO V;".length(), flatLocation.getNodeLength() ); //$NON-NLS-1$
}
}
public void testStdioBug() throws ParserException
{
StringBuffer buffer = new StringBuffer( "#define _PTR void *\n"); //$NON-NLS-1$
buffer.append( "#define _EXFUN(name, proto) __cdecl name proto\n"); //$NON-NLS-1$
buffer.append( "_PTR _EXFUN(memchr,(const _PTR, int, size_t));\n"); //$NON-NLS-1$
String code = buffer.toString();
for (ParserLanguage p = ParserLanguage.C; p != null; p = (p == ParserLanguage.C) ? ParserLanguage.CPP
: null) {
IASTTranslationUnit tu = parse(code, p);
final IASTPreprocessorMacroDefinition[] macroDefinitions = tu.getMacroDefinitions();
IASTPreprocessorObjectStyleMacroDefinition _PTR = (IASTPreprocessorObjectStyleMacroDefinition) macroDefinitions[0];
IASTPreprocessorFunctionStyleMacroDefinition _EXFUN = (IASTPreprocessorFunctionStyleMacroDefinition) macroDefinitions[1];
IASTSimpleDeclaration memchr = (IASTSimpleDeclaration) tu.getDeclarations()[0];
IASTNodeLocation [] locations = memchr.getNodeLocations();
assertEquals( locations.length, 4 );
IASTMacroExpansion loc_1 = (IASTMacroExpansion) locations[0];
assertEqualsMacros( _PTR, loc_1.getMacroDefinition() );
IASTFileLocation loc_2 = (IASTFileLocation) locations[1];
assertEquals( loc_2.getNodeOffset(), code.indexOf( " _EXFUN(")); //$NON-NLS-1$
assertEquals( loc_2.getNodeLength(), " ".length() ); //$NON-NLS-1$
IASTMacroExpansion loc_3 = (IASTMacroExpansion) locations[2];
assertEqualsMacros( _EXFUN, loc_3.getMacroDefinition() );
IASTFileLocation loc_4 = (IASTFileLocation) locations[3];
assertEquals( loc_4.getNodeOffset(), code.indexOf( ";")); //$NON-NLS-1$
assertEquals( loc_4.getNodeLength(), 1 );
IASTFileLocation flat = tu.flattenLocationsToFile(locations);
assertEquals( flat.getNodeOffset() , code.indexOf( "_PTR _EXFUN(memchr,(const _PTR, int, size_t));")); //$NON-NLS-1$
assertEquals( flat.getNodeLength(), "_PTR _EXFUN(memchr,(const _PTR, int, size_t));".length() ); //$NON-NLS-1$
IASTNodeLocation [] fullyMonty = tu.getNodeLocations();
IASTFileLocation flatMonty = tu.flattenLocationsToFile( fullyMonty );
assertEquals( flatMonty.getNodeOffset(), 0 );
// assertEquals( flatMonty.getNodeLength(), code.length() );
}
}
private void assertEqualsMacros(IASTPreprocessorMacroDefinition fromExpansion, IASTPreprocessorMacroDefinition source) {
assertEquals( fromExpansion.getExpansion(), source.getExpansion() );
assertEquals( fromExpansion.getName().toString(), source.getName().toString() );
}
public void testMacroBindings() throws Exception
{
StringBuffer buffer = new StringBuffer( "#define ABC def\n"); //$NON-NLS-1$
buffer.append( "int ABC;\n"); //$NON-NLS-1$
buffer.append( "#undef ABC\n"); //$NON-NLS-1$
buffer.append( "#define ABC ghi\n"); //$NON-NLS-1$
buffer.append( "int ABC;\n"); //$NON-NLS-1$
String code = buffer.toString();
for (ParserLanguage p = ParserLanguage.C; p != null; p = (p == ParserLanguage.C) ? ParserLanguage.CPP
: null) {
IASTTranslationUnit tu = parse(code, p);
IASTPreprocessorMacroDefinition [] macros = tu.getMacroDefinitions();
assertEquals( macros.length, 2 );
IASTPreprocessorObjectStyleMacroDefinition ABC1 = (IASTPreprocessorObjectStyleMacroDefinition) macros[0];
IASTPreprocessorObjectStyleMacroDefinition ABC2 = (IASTPreprocessorObjectStyleMacroDefinition) macros[1];
IMacroBinding binding1 = (IMacroBinding) ABC1.getName().resolveBinding();
assertNotNull( binding1 );
IMacroBinding binding2 = (IMacroBinding) ABC2.getName().resolveBinding();
assertNotNull( binding2 );
assertNotSame( binding1, binding2 );
IASTName [] firstReferences = tu.getReferences( binding1 );
IASTName [] firstDeclarations = tu.getDeclarations( binding1 );
assertEquals( firstReferences.length, 2 );
assertEquals( firstReferences[0].getPropertyInParent(), IASTTranslationUnit.EXPANSION_NAME );
assertEquals( firstReferences[0].getParent(), tu );
assertEquals( firstReferences[1].getPropertyInParent(), IASTPreprocessorUndefStatement.MACRO_NAME );
assertTrue( firstReferences[1].getParent() instanceof IASTPreprocessorUndefStatement );
assertEquals( firstDeclarations.length, 1 );
assertSame( ABC1.getName(), firstDeclarations[0] );
IASTName [] secondReferences = tu.getReferences(binding2);
IASTName [] secondDeclarations = tu.getDeclarations( binding2 );
assertEquals( 1, secondReferences.length );
assertEquals( secondReferences[0].getPropertyInParent(), IASTTranslationUnit.EXPANSION_NAME );
assertEquals( secondReferences[0].getParent(), tu );
assertSame( ABC2.getName(), secondDeclarations[0]);
}
}
}

View file

@ -47,7 +47,6 @@ import org.eclipse.cdt.core.dom.ast.IASTTypeId;
import org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression; import org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression;
import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression; import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionTryBlockDeclarator; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionTryBlockDeclarator;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLinkageSpecification; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLinkageSpecification;
@ -454,7 +453,7 @@ public class DOMLocationTests extends AST2BaseTest {
} }
public void testBug86323() throws Exception { public void testBug86323() throws Exception {
String code = "void f() { int i=0; for (; i<10; i++) { } }"; String code = "void f() { int i=0; for (; i<10; i++) { } }"; //$NON-NLS-1$
for (ParserLanguage p = ParserLanguage.C; p != null; p = (p == ParserLanguage.C) ? ParserLanguage.CPP for (ParserLanguage p = ParserLanguage.C; p != null; p = (p == ParserLanguage.C) ? ParserLanguage.CPP
: null) { : null) {
IASTTranslationUnit tu = parse(code, p); IASTTranslationUnit tu = parse(code, p);

View file

@ -31,6 +31,7 @@ public class DOMParserTestSuite extends TestCase {
suite.addTestSuite( CompleteParser2Tests.class ); suite.addTestSuite( CompleteParser2Tests.class );
// suite.addTestSuite( DOMScannerTests.class ); // suite.addTestSuite( DOMScannerTests.class );
suite.addTestSuite( DOMLocationTests.class ); suite.addTestSuite( DOMLocationTests.class );
suite.addTestSuite( DOMLocationMacroTests.class );
suite.addTest( DOMLocationInclusionTests.suite() ); suite.addTest( DOMLocationInclusionTests.suite() );
suite.addTestSuite( AST2KnRTests.class ); suite.addTestSuite( AST2KnRTests.class );
suite.addTestSuite( AST2UtilTests.class ); suite.addTestSuite( AST2UtilTests.class );

View file

@ -33,5 +33,7 @@ public interface IASTMacroExpansion extends IASTNodeLocation {
* @return * @return
*/ */
public IASTNodeLocation[] getExpansionLocations(); public IASTNodeLocation[] getExpansionLocations();
} }

View file

@ -33,4 +33,11 @@ public interface IASTNodeLocation {
*/ */
public int getNodeLength(); public int getNodeLength();
/**
* Return a file location that best maps into this location.
*
* @return
*/
public IASTFileLocation asFileLocation();
} }

View file

@ -14,6 +14,8 @@ package org.eclipse.cdt.core.dom.ast;
* This interface represent a preprocessor function-style macro definition. e.g. * This interface represent a preprocessor function-style macro definition. e.g.
* #define ABC( def ) GHI * #define ABC( def ) GHI
* *
* Note: macros that are expanded as parameters to function style macros are not captured in this abstraction.
*
* @author jcamelon * @author jcamelon
*/ */
public interface IASTPreprocessorFunctionStyleMacroDefinition extends public interface IASTPreprocessorFunctionStyleMacroDefinition extends

View file

@ -18,4 +18,7 @@ package org.eclipse.cdt.core.dom.ast;
public interface IASTPreprocessorUndefStatement extends public interface IASTPreprocessorUndefStatement extends
IASTPreprocessorStatement { IASTPreprocessorStatement {
public static final ASTNodeProperty MACRO_NAME = new ASTNodeProperty( "IASTPreprocessorUndefStatement.MACRO_NAME - the name of the macro being undefined"); //$NON-NLS-1$
public IASTName getMacroName();
} }

View file

@ -37,7 +37,7 @@ public interface IASTTranslationUnit extends IASTNode {
*/ */
public static final ASTNodeProperty PREPROCESSOR_STATEMENT = new ASTNodeProperty( public static final ASTNodeProperty PREPROCESSOR_STATEMENT = new ASTNodeProperty(
"IASTTranslationUnit.PREPROCESSOR_STATEMENT - IASTPreprocessorStatement for IASTTranslationUnit"); //$NON-NLS-1$ "IASTTranslationUnit.PREPROCESSOR_STATEMENT - IASTPreprocessorStatement for IASTTranslationUnit"); //$NON-NLS-1$
/** /**
* A translation unit contains an ordered sequence of declarations. * A translation unit contains an ordered sequence of declarations.
* *
@ -134,4 +134,34 @@ public interface IASTTranslationUnit extends IASTNode {
* @return String representation of path. * @return String representation of path.
*/ */
public String getFilePath(); public String getFilePath();
/**
* Flatten the node locations provided into a single file location.
*
* @param nodeLocations <code>IASTNodeLocation</code>s to flatten
* @return null if not possible, otherwise, a file location representing where the macros are.
*/
public IASTFileLocation flattenLocationsToFile( IASTNodeLocation [] nodeLocations );
public static final ASTNodeProperty EXPANSION_NAME = new ASTNodeProperty(
"IASTTranslationUnit.EXPANSION_NAME - IASTName generated for macro expansions."); //$NON-NLS-1$
public static interface IDependencyTree
{
public String getTranslationUnitPath();
public static interface IASTInclusionNode
{
public IASTPreprocessorIncludeStatement getIncludeDirective();
public IASTInclusionNode [] getNestedInclusions();
}
public IASTInclusionNode [] getInclusions();
}
public IDependencyTree getDependencyTree();
} }

View file

@ -21,6 +21,12 @@ public interface IBinding {
* @return name * @return name
*/ */
public String getName(); public String getName();
/**
* The name of the binding.
*
* @return name
*/
public char[] getNameCharArray(); public char[] getNameCharArray();
/** /**

View file

@ -0,0 +1,15 @@
/**********************************************************************
* Copyright (c) 2004 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM - Initial API and implementation
**********************************************************************/
package org.eclipse.cdt.core.dom.ast;
public interface IMacroBinding extends IBinding {
}

View file

@ -127,5 +127,9 @@ public class CodeReader {
public boolean isFile() { public boolean isFile() {
return !CharArrayUtils.equals( filename, NOFILE ); return !CharArrayUtils.equals( filename, NOFILE );
} }
public String toString() {
return new String( filename );
}
} }

View file

@ -26,5 +26,10 @@ public interface IExtendedScannerInfo extends IScannerInfo {
*/ */
public String [] getIncludeFiles(); public String [] getIncludeFiles();
/**
* Get local inclusions?
*
* @return
*/
public String [] getLocalIncludePath(); public String [] getLocalIncludePath();
} }

View file

@ -1,66 +0,0 @@
/**********************************************************************
* Copyright (c) 2004 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM - Initial API and implementation
**********************************************************************/
package org.eclipse.cdt.internal.core.dom.parser;
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
/**
* @author jcamelon
*/
public class ASTFileLocation implements IASTFileLocation {
private String fn;
private int o;
private int l;
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IASTFileLocation#getFileName()
*/
public String getFileName() {
return fn;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IASTFileLocation#setFileName(java.lang.String)
*/
public void setFileName(String fileName) {
fn = fileName;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IASTNodeLocation#getNodeOffset()
*/
public int getNodeOffset() {
return o;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IASTNodeLocation#setNodeOffset(int)
*/
public void setNodeOffset(int offset) {
o = offset;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IASTNodeLocation#getNodeLength()
*/
public int getNodeLength() {
return l;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IASTNodeLocation#setNodeLength(int)
*/
public void setNodeLength(int length) {
l = length;
}
}

View file

@ -273,12 +273,21 @@ public class CASTProblem extends CASTNode implements IASTProblem {
IASTNodeLocation [] locs = getNodeLocations(); IASTNodeLocation [] locs = getNodeLocations();
String file = null; String file = null;
int offset = 0; int offset = 0;
if( locs != null && locs.length > 0 ){ if( locs != null && locs.length == 1 && locs[0] instanceof IASTFileLocation ){
file = ((IASTFileLocation) locs[0]).getFileName(); file = ((IASTFileLocation) locs[0]).getFileName();
offset = locs[0].getNodeOffset(); offset = locs[0].getNodeOffset();
} else { } else {
file = ""; //$NON-NLS-1$ IASTFileLocation f = getTranslationUnit().flattenLocationsToFile(locs);
offset = 0; if( f == null )
{
file = ""; //$NON-NLS-1$
offset = 0;
}
else
{
file = f.getFileName();
offset = f.getNodeOffset();
}
} }
Object[] args = new Object[] { msg, file, new Integer( offset ) }; //$NON-NLS-1$ Object[] args = new Object[] { msg, file, new Integer( offset ) }; //$NON-NLS-1$

View file

@ -9,7 +9,6 @@
* IBM Rational Software - Initial API and implementation */ * IBM Rational Software - Initial API and implementation */
package org.eclipse.cdt.internal.core.dom.parser.c; package org.eclipse.cdt.internal.core.dom.parser.c;
import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTArrayDeclarator; import org.eclipse.cdt.core.dom.ast.IASTArrayDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTArrayModifier; import org.eclipse.cdt.core.dom.ast.IASTArrayModifier;
@ -17,6 +16,7 @@ import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration; import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTDeclarator; import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
import org.eclipse.cdt.core.dom.ast.IASTInitializer; import org.eclipse.cdt.core.dom.ast.IASTInitializer;
import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTNode;
@ -31,6 +31,7 @@ import org.eclipse.cdt.core.dom.ast.IASTStatement;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IASTTypeId; import org.eclipse.cdt.core.dom.ast.IASTTypeId;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IMacroBinding;
import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.c.CASTVisitor; import org.eclipse.cdt.core.dom.ast.c.CASTVisitor;
import org.eclipse.cdt.core.dom.ast.c.ICASTDesignator; import org.eclipse.cdt.core.dom.ast.c.ICASTDesignator;
@ -70,6 +71,8 @@ public class CASTTranslationUnit extends CASTNode implements
private static final String EMPTY_STRING = ""; //$NON-NLS-1$ private static final String EMPTY_STRING = ""; //$NON-NLS-1$
private static final IASTName[] EMPTY_NAME_ARRAY = new IASTName[0];
public void addDeclaration(IASTDeclaration d) { public void addDeclaration(IASTDeclaration d) {
if (decls == null) { if (decls == null) {
decls = new IASTDeclaration[DEFAULT_CHILDREN_LIST_SIZE]; decls = new IASTDeclaration[DEFAULT_CHILDREN_LIST_SIZE];
@ -131,7 +134,12 @@ public class CASTTranslationUnit extends CASTNode implements
* @see org.eclipse.cdt.core.dom.ast.IASTTranslationUnit#getDeclarations(org.eclipse.cdt.core.dom.ast.IBinding) * @see org.eclipse.cdt.core.dom.ast.IASTTranslationUnit#getDeclarations(org.eclipse.cdt.core.dom.ast.IBinding)
*/ */
public IASTName[] getDeclarations(IBinding binding) { public IASTName[] getDeclarations(IBinding binding) {
// TODO if binding is macro, circumvent the visitor if( binding instanceof IMacroBinding )
{
if( resolver == null )
return EMPTY_NAME_ARRAY;
return resolver.getDeclarations( (IMacroBinding)binding );
}
return CVisitor.getDeclarations(this, binding); return CVisitor.getDeclarations(this, binding);
} }
@ -141,7 +149,12 @@ public class CASTTranslationUnit extends CASTNode implements
* @see org.eclipse.cdt.core.dom.ast.IASTTranslationUnit#getReferences(org.eclipse.cdt.core.dom.ast.IBinding) * @see org.eclipse.cdt.core.dom.ast.IASTTranslationUnit#getReferences(org.eclipse.cdt.core.dom.ast.IBinding)
*/ */
public IASTName[] getReferences(IBinding binding) { public IASTName[] getReferences(IBinding binding) {
// TODO if binding is macro, circumvent the visitor if( binding instanceof IMacroBinding )
{
if( resolver == null )
return EMPTY_NAME_ARRAY;
return resolver.getReferences( (IMacroBinding)binding );
}
return CVisitor.getReferences(this, binding); return CVisitor.getReferences(this, binding);
} }
@ -375,8 +388,6 @@ public class CASTTranslationUnit extends CASTNode implements
return EMPTY_PREPROCESSOR_MACRODEF_ARRAY; return EMPTY_PREPROCESSOR_MACRODEF_ARRAY;
IASTPreprocessorMacroDefinition[] result = resolver IASTPreprocessorMacroDefinition[] result = resolver
.getMacroDefinitions(); .getMacroDefinitions();
setParentRelationship(result,
IASTTranslationUnit.PREPROCESSOR_STATEMENT);
return result; return result;
} }
@ -390,24 +401,10 @@ public class CASTTranslationUnit extends CASTNode implements
return EMPTY_PREPROCESSOR_INCLUSION_ARRAY; return EMPTY_PREPROCESSOR_INCLUSION_ARRAY;
IASTPreprocessorIncludeStatement[] result = resolver IASTPreprocessorIncludeStatement[] result = resolver
.getIncludeDirectives(); .getIncludeDirectives();
setParentRelationship(result,
IASTTranslationUnit.PREPROCESSOR_STATEMENT);
return result; return result;
} }
/** /*
* @param result
* @param preprocessor_statement
*/
protected void setParentRelationship(IASTNode[] result,
ASTNodeProperty property) {
for (int i = 0; i < result.length; ++i) {
result[i].setParent(this);
result[i].setPropertyInParent(property);
}
}
/*
* (non-Javadoc) * (non-Javadoc)
* *
* @see org.eclipse.cdt.core.dom.ast.IASTTranslationUnit#getAllPreprocessorStatements() * @see org.eclipse.cdt.core.dom.ast.IASTTranslationUnit#getAllPreprocessorStatements()
@ -417,8 +414,6 @@ public class CASTTranslationUnit extends CASTNode implements
return EMPTY_PREPROCESSOR_STATEMENT_ARRAY; return EMPTY_PREPROCESSOR_STATEMENT_ARRAY;
IASTPreprocessorStatement[] result = resolver IASTPreprocessorStatement[] result = resolver
.getAllPreprocessorStatements(); .getAllPreprocessorStatements();
setParentRelationship(result,
IASTTranslationUnit.PREPROCESSOR_STATEMENT);
return result; return result;
} }
@ -429,6 +424,7 @@ public class CASTTranslationUnit extends CASTNode implements
*/ */
public void setLocationResolver(ILocationResolver resolver) { public void setLocationResolver(ILocationResolver resolver) {
this.resolver = resolver; this.resolver = resolver;
resolver.setRootNode( this );
} }
/* /*
@ -495,4 +491,22 @@ public class CASTTranslationUnit extends CASTNode implements
} }
return true; return true;
} }
public IASTFileLocation flattenLocationsToFile(IASTNodeLocation[] nodeLocations) {
if( resolver == null )
return null;
return resolver.flattenLocations( nodeLocations );
}
public IASTName[] getMacroExpansions() {
if( resolver == null )
return EMPTY_NAME_ARRAY;
return resolver.getMacroExpansions();
}
public IDependencyTree getDependencyTree() {
if( resolver == null )
return null;
return resolver.getDependencyTree();
}
} }

View file

@ -10,7 +10,6 @@
**********************************************************************/ **********************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTArrayDeclarator; import org.eclipse.cdt.core.dom.ast.IASTArrayDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTArrayModifier; import org.eclipse.cdt.core.dom.ast.IASTArrayModifier;
@ -18,6 +17,7 @@ import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration; import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTDeclarator; import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
import org.eclipse.cdt.core.dom.ast.IASTInitializer; import org.eclipse.cdt.core.dom.ast.IASTInitializer;
import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTNode;
@ -32,6 +32,7 @@ import org.eclipse.cdt.core.dom.ast.IASTStatement;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IASTTypeId; import org.eclipse.cdt.core.dom.ast.IASTTypeId;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IMacroBinding;
import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.c.ICASTDesignator; import org.eclipse.cdt.core.dom.ast.c.ICASTDesignator;
import org.eclipse.cdt.core.dom.ast.cpp.CPPASTVisitor; import org.eclipse.cdt.core.dom.ast.cpp.CPPASTVisitor;
@ -78,6 +79,8 @@ public class CPPASTTranslationUnit extends CPPASTNode implements
private static final String EMPTY_STRING = ""; //$NON-NLS-1$ private static final String EMPTY_STRING = ""; //$NON-NLS-1$
private static final IASTProblem[] EMPTY_PROBLEM_ARRAY = new IASTProblem[0]; private static final IASTProblem[] EMPTY_PROBLEM_ARRAY = new IASTProblem[0];
private static final IASTName[] EMPTY_NAME_ARRAY = new IASTName[0];
public void addDeclaration(IASTDeclaration d) { public void addDeclaration(IASTDeclaration d) {
if (decls == null) { if (decls == null) {
decls = new IASTDeclaration[DEFAULT_CHILDREN_LIST_SIZE]; decls = new IASTDeclaration[DEFAULT_CHILDREN_LIST_SIZE];
@ -139,6 +142,12 @@ public class CPPASTTranslationUnit extends CPPASTNode implements
* @see org.eclipse.cdt.core.dom.ast.IASTTranslationUnit#getDeclarations(org.eclipse.cdt.core.dom.ast.IBinding) * @see org.eclipse.cdt.core.dom.ast.IASTTranslationUnit#getDeclarations(org.eclipse.cdt.core.dom.ast.IBinding)
*/ */
public IASTName[] getDeclarations(IBinding b) { public IASTName[] getDeclarations(IBinding b) {
if( b instanceof IMacroBinding )
{
if( resolver == null )
return EMPTY_NAME_ARRAY;
return resolver.getDeclarations( (IMacroBinding)b );
}
return CPPVisitor.getDeclarations( this, b ); return CPPVisitor.getDeclarations( this, b );
} }
@ -148,6 +157,12 @@ public class CPPASTTranslationUnit extends CPPASTNode implements
* @see org.eclipse.cdt.core.dom.ast.IASTTranslationUnit#getReferences(org.eclipse.cdt.core.dom.ast.IBinding) * @see org.eclipse.cdt.core.dom.ast.IASTTranslationUnit#getReferences(org.eclipse.cdt.core.dom.ast.IBinding)
*/ */
public IASTName[] getReferences(IBinding b) { public IASTName[] getReferences(IBinding b) {
if( b instanceof IMacroBinding )
{
if( resolver == null )
return EMPTY_NAME_ARRAY;
return resolver.getReferences( (IMacroBinding)b );
}
return CPPVisitor.getReferences(this, b); return CPPVisitor.getReferences(this, b);
} }
@ -366,7 +381,6 @@ public class CPPASTTranslationUnit extends CPPASTNode implements
public IASTPreprocessorMacroDefinition[] getMacroDefinitions() { public IASTPreprocessorMacroDefinition[] getMacroDefinitions() {
if( resolver == null ) return EMPTY_PREPROCESSOR_MACRODEF_ARRAY; if( resolver == null ) return EMPTY_PREPROCESSOR_MACRODEF_ARRAY;
IASTPreprocessorMacroDefinition [] result = resolver.getMacroDefinitions(); IASTPreprocessorMacroDefinition [] result = resolver.getMacroDefinitions();
setParentRelationship( result, IASTTranslationUnit.PREPROCESSOR_STATEMENT );
return result; return result;
} }
@ -378,22 +392,9 @@ public class CPPASTTranslationUnit extends CPPASTNode implements
public IASTPreprocessorIncludeStatement[] getIncludeDirectives() { public IASTPreprocessorIncludeStatement[] getIncludeDirectives() {
if( resolver == null ) return EMPTY_PREPROCESSOR_INCLUSION_ARRAY; if( resolver == null ) return EMPTY_PREPROCESSOR_INCLUSION_ARRAY;
IASTPreprocessorIncludeStatement [] result = resolver.getIncludeDirectives(); IASTPreprocessorIncludeStatement [] result = resolver.getIncludeDirectives();
setParentRelationship( result, IASTTranslationUnit.PREPROCESSOR_STATEMENT );
return result; return result;
} }
/**
* @param result
* @param preprocessor_statement
*/
protected void setParentRelationship(IASTNode[] result, ASTNodeProperty property ) {
for( int i = 0; i < result.length; ++i )
{
result[i].setParent( this );
result[i].setPropertyInParent( property );
}
}
/* /*
* (non-Javadoc) * (non-Javadoc)
* *
@ -403,7 +404,6 @@ public class CPPASTTranslationUnit extends CPPASTNode implements
if (resolver == null) if (resolver == null)
return EMPTY_PREPROCESSOR_STATEMENT_ARRAY; return EMPTY_PREPROCESSOR_STATEMENT_ARRAY;
IASTPreprocessorStatement [] result = resolver.getAllPreprocessorStatements(); IASTPreprocessorStatement [] result = resolver.getAllPreprocessorStatements();
setParentRelationship( result, IASTTranslationUnit.PREPROCESSOR_STATEMENT );
return result; return result;
} }
@ -414,6 +414,7 @@ public class CPPASTTranslationUnit extends CPPASTNode implements
*/ */
public void setLocationResolver(ILocationResolver resolver) { public void setLocationResolver(ILocationResolver resolver) {
this.resolver = resolver; this.resolver = resolver;
resolver.setRootNode( this );
} }
/* /*
@ -477,4 +478,24 @@ public class CPPASTTranslationUnit extends CPPASTNode implements
} }
return true; return true;
} }
public IASTFileLocation flattenLocationsToFile(IASTNodeLocation[] nodeLocations) {
if( resolver == null )
return null;
return resolver.flattenLocations( nodeLocations );
}
public IASTName[] getMacroExpansions() {
if( resolver == null )
return EMPTY_NAME_ARRAY;
return resolver.getMacroExpansions();
}
public IDependencyTree getDependencyTree() {
if( resolver == null )
return null;
return resolver.getDependencyTree();
}
} }

View file

@ -55,8 +55,6 @@ abstract class BaseScanner implements IScanner {
protected static final char[] VA_ARGS_CHARARRAY = "__VA_ARGS__".toCharArray(); //$NON-NLS-1$ protected static final char[] VA_ARGS_CHARARRAY = "__VA_ARGS__".toCharArray(); //$NON-NLS-1$
// The eocToken marks the end of a completion parse.
// The offset is set to the max so that it is properly considered at the end of the parse.
protected final IToken eocToken = new SimpleToken(IToken.tEOC, Integer.MAX_VALUE, null, Integer.MAX_VALUE); protected final IToken eocToken = new SimpleToken(IToken.tEOC, Integer.MAX_VALUE, null, Integer.MAX_VALUE);
/** /**
@ -77,6 +75,10 @@ abstract class BaseScanner implements IScanner {
this.reader = reader; this.reader = reader;
this.inclusion = inclusion; this.inclusion = inclusion;
} }
public String toString() {
return reader.toString();
}
} }
protected static class MacroData { protected static class MacroData {
@ -91,6 +93,10 @@ abstract class BaseScanner implements IScanner {
public final int endOffset; public final int endOffset;
public final IMacro macro; public final IMacro macro;
public String toString() {
return macro.toString();
}
} }
protected ParserLanguage language; protected ParserLanguage language;
@ -3236,16 +3242,20 @@ abstract class BaseScanner implements IScanner {
handleCompletionOnDefinition(new String(buffer, idstart, idlen)); handleCompletionOnDefinition(new String(buffer, idstart, idlen));
skipToNewLine(); skipToNewLine();
processUndef(pos, bufferPos[bufferStackPos]);
definitions.remove(buffer, idstart, idlen); Object definition = definitions.remove(buffer, idstart, idlen);
processUndef(pos, bufferPos[bufferStackPos], CharArrayUtils.extract(buffer, idstart, idlen ), idstart, definition);
} }
/** /**
* @param pos * @param pos
* @param endPos * @param endPos
* @param symbol TODO
* @param namePos TODO
* @param definition TODO
*/ */
protected abstract void processUndef(int pos, int endPos); protected abstract void processUndef(int pos, int endPos, char[] symbol, int namePos, Object definition);
protected void handlePPIfdef(int pos, boolean positive) protected void handlePPIfdef(int pos, boolean positive)
throws EndOfFileException { throws EndOfFileException {
@ -3988,8 +3998,10 @@ abstract class BaseScanner implements IScanner {
result); result);
} }
if (pushContext) if (pushContext)
{
pushContext(result, new MacroData(start, bufferPos[bufferStackPos], pushContext(result, new MacroData(start, bufferPos[bufferStackPos],
macro)); macro));
}
return result; return result;
} }
@ -4030,7 +4042,10 @@ abstract class BaseScanner implements IScanner {
} }
if (expObject == null) if (expObject == null)
{
return arg; return arg;
}
char[] expansion = null; char[] expansion = null;
if (expObject instanceof FunctionStyleMacro) { if (expObject instanceof FunctionStyleMacro) {
@ -4060,6 +4075,8 @@ abstract class BaseScanner implements IScanner {
System.arraycopy(arg, end + 1, result, System.arraycopy(arg, end + 1, result,
start + expansion.length, limit - end - 1); start + expansion.length, limit - end - 1);
beforeReplaceAllMacros();
//we need to put the macro on the context stack in order to detect //we need to put the macro on the context stack in order to detect
// recursive macros // recursive macros
pushContext(EMPTY_CHAR_ARRAY, pushContext(EMPTY_CHAR_ARRAY,
@ -4068,10 +4085,29 @@ abstract class BaseScanner implements IScanner {
(IMacro) expObject)); (IMacro) expObject));
arg = replaceArgumentMacros(result); //rescan for more macros arg = replaceArgumentMacros(result); //rescan for more macros
popContext(); popContext();
afterReplaceAllMacros();
} }
return arg; return arg;
} }
/**
* Hook for subclasses.
*/
protected void afterReplaceAllMacros() {
// TODO Auto-generated method stub
}
/**
* Hook for subclasses.
*/
protected void beforeReplaceAllMacros() {
// TODO Auto-generated method stub
}
protected int expandFunctionStyleMacro(char[] expansion, protected int expandFunctionStyleMacro(char[] expansion,
CharArrayObjectMap argmap, CharArrayObjectMap replacedArgs, CharArrayObjectMap argmap, CharArrayObjectMap replacedArgs,
char[] result) { char[] result) {
@ -4161,6 +4197,7 @@ abstract class BaseScanner implements IScanner {
char[] rep = (char[]) ((replacedArgs != null) ? replacedArgs char[] rep = (char[]) ((replacedArgs != null) ? replacedArgs
.get(repObject) .get(repObject)
: null); : null);
if (rep != null) if (rep != null)
repObject = rep; repObject = rep;
else { else {

View file

@ -20,9 +20,7 @@ import org.eclipse.cdt.core.parser.IToken;
import org.eclipse.cdt.core.parser.ParserLanguage; import org.eclipse.cdt.core.parser.ParserLanguage;
import org.eclipse.cdt.core.parser.ParserMode; import org.eclipse.cdt.core.parser.ParserMode;
import org.eclipse.cdt.core.parser.ast.IASTFactory; import org.eclipse.cdt.core.parser.ast.IASTFactory;
import org.eclipse.cdt.internal.core.parser.token.ImagedExpansionToken;
import org.eclipse.cdt.internal.core.parser.token.ImagedToken; import org.eclipse.cdt.internal.core.parser.token.ImagedToken;
import org.eclipse.cdt.internal.core.parser.token.SimpleExpansionToken;
import org.eclipse.cdt.internal.core.parser.token.SimpleToken; import org.eclipse.cdt.internal.core.parser.token.SimpleToken;
/** /**
@ -69,6 +67,36 @@ public class DOMScanner extends BaseScanner {
postConstructorSetup(reader, info); postConstructorSetup(reader, info);
} }
private void registerMacros() {
for( int i = 0; i < definitions.size(); ++i )
{
IMacro m = (IMacro) definitions.get( definitions.keyAt(i) );
if( m instanceof DynamicStyleMacro )
{
DynamicStyleMacro macro = (DynamicStyleMacro) m;
macro.attachment = locationMap.registerBuiltinDynamicStyleMacro( macro );
}
else if( m instanceof DynamicFunctionStyleMacro )
{
DynamicFunctionStyleMacro macro = (DynamicFunctionStyleMacro) m;
macro.attachment = locationMap.registerBuiltinDynamicFunctionStyleMacro( macro );
}
else if( m instanceof FunctionStyleMacro )
{
FunctionStyleMacro macro = (FunctionStyleMacro) m;
macro.attachment = locationMap.registerBuiltinFunctionStyleMacro( macro );
}
else if( m instanceof ObjectStyleMacro )
{
ObjectStyleMacro macro = (ObjectStyleMacro) m;
macro.attachment = locationMap.registerBuiltinObjectStyleMacro( macro );
}
}
}
/* /*
* (non-Javadoc) * (non-Javadoc)
* *
@ -113,14 +141,18 @@ public class DOMScanner extends BaseScanner {
protected void processMacro(char[] name, int startingOffset, protected void processMacro(char[] name, int startingOffset,
int startingLineNumber, int idstart, int idend, int nameLine, int startingLineNumber, int idstart, int idend, int nameLine,
int textEnd, int endingLine, IMacro macro) { int textEnd, int endingLine, IMacro macro) {
IScannerPreprocessorLog.IMacroDefinition m = null;
if (macro instanceof FunctionStyleMacro) if (macro instanceof FunctionStyleMacro)
locationMap.defineFunctionStyleMacro((FunctionStyleMacro) macro, m = locationMap.defineFunctionStyleMacro(
resolveOffset(startingOffset), resolveOffset(idstart), (FunctionStyleMacro) macro, resolveOffset(startingOffset),
resolveOffset(idend), resolveOffset(textEnd)); resolveOffset(idstart), resolveOffset(idend),
resolveOffset(textEnd));
else if (macro instanceof ObjectStyleMacro) else if (macro instanceof ObjectStyleMacro)
locationMap.defineObjectStyleMacro((ObjectStyleMacro) macro, m = locationMap.defineObjectStyleMacro((ObjectStyleMacro) macro,
resolveOffset(startingOffset), resolveOffset(idstart), resolveOffset(startingOffset), resolveOffset(idstart),
resolveOffset(idend), resolveOffset(textEnd)); resolveOffset(idend), resolveOffset(textEnd));
if (m != null && macro instanceof ObjectStyleMacro)
((ObjectStyleMacro) macro).attachment = m;
} }
@ -161,22 +193,41 @@ public class DOMScanner extends BaseScanner {
resolveOffset(getCurrentOffset())); resolveOffset(getCurrentOffset()));
bufferDelta[bufferStackPos + 1] = 0; bufferDelta[bufferStackPos + 1] = 0;
} }
else if (data instanceof MacroData) {
MacroData d = (MacroData) data;
if (d.macro instanceof FunctionStyleMacro && fsmCount == 0) {
FunctionStyleMacro fsm = (FunctionStyleMacro) d.macro;
locationMap.startFunctionStyleExpansion(fsm.attachment,
fsm.arglist, resolveOffset(d.startOffset),
resolveOffset(d.endOffset));
bufferDelta[bufferStackPos + 1] = 0;
} else if (d.macro instanceof ObjectStyleMacro && fsmCount == 0) {
ObjectStyleMacro osm = (ObjectStyleMacro) d.macro;
locationMap.startObjectStyleMacroExpansion(osm.attachment,
resolveOffset(d.startOffset),
resolveOffset(d.endOffset));
bufferDelta[bufferStackPos + 1] = 0;
}
}
super.pushContext(buffer, data); super.pushContext(buffer, data);
} }
protected int fsmCount = 0;
/* /*
* (non-Javadoc) * (non-Javadoc)
* *
* @see org.eclipse.cdt.internal.core.parser.scanner2.BaseScanner#popContext() * @see org.eclipse.cdt.internal.core.parser.scanner2.BaseScanner#popContext()
*/ */
protected Object popContext() { protected Object popContext() {
//TODO calibrate offsets // TODO calibrate offsets
Object result = super.popContext(); Object result = super.popContext();
if (result instanceof CodeReader) { if (result instanceof CodeReader) {
locationMap.endTranslationUnit(bufferDelta[0] locationMap.endTranslationUnit(bufferDelta[0]
+ ((CodeReader) result).buffer.length); + ((CodeReader) result).buffer.length);
} } else if (result instanceof InclusionData) {
if (result instanceof InclusionData) {
CodeReader codeReader = ((InclusionData) result).reader; CodeReader codeReader = ((InclusionData) result).reader;
if (log.isTracing()) { if (log.isTracing()) {
StringBuffer buffer = new StringBuffer("Exiting inclusion "); //$NON-NLS-1$ StringBuffer buffer = new StringBuffer("Exiting inclusion "); //$NON-NLS-1$
@ -188,6 +239,25 @@ public class DOMScanner extends BaseScanner {
+ bufferPos[bufferStackPos + 1]); + bufferPos[bufferStackPos + 1]);
bufferDelta[bufferStackPos] += bufferDelta[bufferStackPos + 1] bufferDelta[bufferStackPos] += bufferDelta[bufferStackPos + 1]
+ codeReader.buffer.length; + codeReader.buffer.length;
} else if (result instanceof MacroData) {
MacroData data = (MacroData) result;
if (data.macro instanceof FunctionStyleMacro && fsmCount == 0) {
locationMap
.endFunctionStyleExpansion(getGlobalCounter(bufferStackPos + 1)
+ bufferPos[bufferStackPos + 1] + 1); // functionstyle
// macro)
// ;
bufferDelta[bufferStackPos] += bufferDelta[bufferStackPos + 1]
+ bufferPos[bufferStackPos + 1] + 1;
} else if (data.macro instanceof ObjectStyleMacro && fsmCount == 0) {
locationMap
.endObjectStyleMacroExpansion(getGlobalCounter(bufferStackPos + 1)
+ bufferPos[bufferStackPos + 1]);
bufferDelta[bufferStackPos] += bufferDelta[bufferStackPos + 1]
+ bufferPos[bufferStackPos + 1];
}
} }
return result; return result;
} }
@ -211,18 +281,6 @@ public class DOMScanner extends BaseScanner {
* @return * @return
*/ */
protected IToken newToken(int signal) { protected IToken newToken(int signal) {
if (bufferData[bufferStackPos] instanceof MacroData) {
int mostRelevant;
for (mostRelevant = bufferStackPos; mostRelevant >= 0; --mostRelevant)
if (bufferData[mostRelevant] instanceof InclusionData
|| bufferData[mostRelevant] instanceof CodeReader)
break;
MacroData data = (MacroData) bufferData[mostRelevant + 1];
return new SimpleExpansionToken(signal,
resolveOffset(data.startOffset), data.endOffset
- data.startOffset + 1, getCurrentFilename(),
getLineNumber(bufferPos[mostRelevant] + 1));
}
return new SimpleToken(signal, return new SimpleToken(signal,
resolveOffset(bufferPos[bufferStackPos] + 1), resolveOffset(bufferPos[bufferStackPos] + 1),
getCurrentFilename(), getCurrentFilename(),
@ -230,24 +288,12 @@ public class DOMScanner extends BaseScanner {
} }
protected IToken newToken(int signal, char[] buffer) { protected IToken newToken(int signal, char[] buffer) {
if (bufferData[bufferStackPos] instanceof MacroData) {
int mostRelevant;
for (mostRelevant = bufferStackPos; mostRelevant >= 0; --mostRelevant)
if (bufferData[mostRelevant] instanceof InclusionData
|| bufferData[mostRelevant] instanceof CodeReader)
break;
MacroData data = (MacroData) bufferData[mostRelevant + 1];
return new ImagedExpansionToken(signal, buffer,
resolveOffset(data.startOffset), data.endOffset
- data.startOffset + 1, getCurrentFilename(),
getLineNumber(bufferPos[mostRelevant] + 1));
}
IToken i = new ImagedToken(signal, buffer, IToken i = new ImagedToken(signal, buffer,
resolveOffset(bufferPos[bufferStackPos] + 1), EMPTY_CHAR_ARRAY, resolveOffset(bufferPos[bufferStackPos] + 1), EMPTY_CHAR_ARRAY,
getLineNumber(bufferPos[bufferStackPos] + 1)); getLineNumber(bufferPos[bufferStackPos] + 1));
if (buffer != null && buffer.length == 0 && signal != IToken.tSTRING if (buffer != null && buffer.length == 0 && signal != IToken.tSTRING
&& signal != IToken.tLSTRING) && signal != IToken.tLSTRING)
bufferPos[bufferStackPos] += 1; //TODO - remove this hack at some bufferPos[bufferStackPos] += 1; // TODO - remove this hack at some
// point // point
return i; return i;
@ -259,7 +305,7 @@ public class DOMScanner extends BaseScanner {
* @see org.eclipse.cdt.internal.core.parser.scanner2.BaseScanner#quickParsePushPopInclusion(java.lang.Object) * @see org.eclipse.cdt.internal.core.parser.scanner2.BaseScanner#quickParsePushPopInclusion(java.lang.Object)
*/ */
protected void quickParsePushPopInclusion(Object inclusion) { protected void quickParsePushPopInclusion(Object inclusion) {
//do nothing // do nothing
} }
/* /*
@ -293,6 +339,7 @@ public class DOMScanner extends BaseScanner {
protected void postConstructorSetup(CodeReader reader, IScannerInfo info) { protected void postConstructorSetup(CodeReader reader, IScannerInfo info) {
super.postConstructorSetup(reader, info); super.postConstructorSetup(reader, info);
locationMap.startTranslationUnit(getMainReader()); locationMap.startTranslationUnit(getMainReader());
registerMacros();
} }
/* /*
@ -351,9 +398,12 @@ public class DOMScanner extends BaseScanner {
* @see org.eclipse.cdt.internal.core.parser.scanner2.BaseScanner#processUndef(int, * @see org.eclipse.cdt.internal.core.parser.scanner2.BaseScanner#processUndef(int,
* int) * int)
*/ */
protected void processUndef(int pos, int endPos) { protected void processUndef(int pos, int endPos, char[] symbol,
int namePos, Object definition) {
final IScannerPreprocessorLog.IMacroDefinition macroDefinition = (definition instanceof ObjectStyleMacro) ? ((ObjectStyleMacro) definition).attachment
: null;
locationMap.encounterPoundUndef(resolveOffset(pos), locationMap.encounterPoundUndef(resolveOffset(pos),
resolveOffset(endPos)); resolveOffset(endPos), symbol, namePos, macroDefinition);
} }
/* /*
@ -389,4 +439,11 @@ public class DOMScanner extends BaseScanner {
resolveOffset(endPos)); resolveOffset(endPos));
} }
protected void beforeReplaceAllMacros() {
++fsmCount;
}
protected void afterReplaceAllMacros() {
--fsmCount;
}
} }

View file

@ -11,6 +11,7 @@
package org.eclipse.cdt.internal.core.parser.scanner2; package org.eclipse.cdt.internal.core.parser.scanner2;
import org.eclipse.cdt.core.parser.IMacro; import org.eclipse.cdt.core.parser.IMacro;
import org.eclipse.cdt.internal.core.parser.scanner2.IScannerPreprocessorLog.IMacroDefinition;
/** /**
* @author jcamelon * @author jcamelon
@ -24,7 +25,8 @@ public abstract class DynamicStyleMacro implements IMacro{
{ {
name = n; name = n;
} }
public final char [] name; public final char [] name;
public IMacroDefinition attachment;
public char[] getSignature() public char[] getSignature()
{ {

View file

@ -10,11 +10,16 @@
**********************************************************************/ **********************************************************************/
package org.eclipse.cdt.internal.core.parser.scanner2; package org.eclipse.cdt.internal.core.parser.scanner2;
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNodeLocation; import org.eclipse.cdt.core.dom.ast.IASTNodeLocation;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement; import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroDefinition; import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroDefinition;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorStatement; import org.eclipse.cdt.core.dom.ast.IASTPreprocessorStatement;
import org.eclipse.cdt.core.dom.ast.IASTProblem; import org.eclipse.cdt.core.dom.ast.IASTProblem;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IMacroBinding;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit.IDependencyTree;
import org.eclipse.cdt.internal.core.dom.parser.ASTPreprocessorSelectionResult; import org.eclipse.cdt.internal.core.dom.parser.ASTPreprocessorSelectionResult;
/** /**
@ -38,4 +43,11 @@ public interface ILocationResolver {
public ASTPreprocessorSelectionResult getPreprocessorNode( String path, int offset, int length ) throws InvalidPreprocessorNodeException; public ASTPreprocessorSelectionResult getPreprocessorNode( String path, int offset, int length ) throws InvalidPreprocessorNodeException;
public void setRootNode(IASTTranslationUnit root );
public IASTFileLocation flattenLocations(IASTNodeLocation[] nodeLocations);
public IASTName[] getReferences(IMacroBinding binding);
public IASTName[] getDeclarations(IMacroBinding binding);
public IASTName[] getMacroExpansions();
public IDependencyTree getDependencyTree();
} }

View file

@ -11,6 +11,7 @@
package org.eclipse.cdt.internal.core.parser.scanner2; package org.eclipse.cdt.internal.core.parser.scanner2;
import org.eclipse.cdt.core.dom.ast.IASTProblem; import org.eclipse.cdt.core.dom.ast.IASTProblem;
import org.eclipse.cdt.core.dom.ast.IMacroBinding;
import org.eclipse.cdt.core.parser.CodeReader; import org.eclipse.cdt.core.parser.CodeReader;
/** /**
@ -26,21 +27,30 @@ public interface IScannerPreprocessorLog {
public void endInclusion(int offset); public void endInclusion(int offset);
public void enterObjectStyleMacroExpansion(char[] name, char[] expansion, public void startObjectStyleMacroExpansion(IMacroDefinition macro,
int offset); int startOffset, int endOffset);
public void exitObjectStyleMacroExpansion(char[] name, int offset); public void endObjectStyleMacroExpansion(int offset);
public void enterFunctionStyleExpansion(char[] name, char[][] parameters,
char[] expansion, int offset); public void startFunctionStyleExpansion(IMacroDefinition macro,
char[][] parameters, int startOffset, int endOffset);
public void exitFunctionStyleExpansion(char[] name, int offset); public void endFunctionStyleExpansion(int offset);
public void defineObjectStyleMacro(ObjectStyleMacro m, int startOffset, public interface IMacroDefinition {
int nameOffset, int nameEndOffset, int endOffset); public char[] getName();
public char[] getExpansion();
public IMacroBinding getBinding();
public void setBinding( IMacroBinding b );
}
public void defineFunctionStyleMacro(FunctionStyleMacro m, int startOffset, public IMacroDefinition defineObjectStyleMacro(ObjectStyleMacro m,
int nameOffset, int nameEndOffset, int endOffset); int startOffset, int nameOffset, int nameEndOffset, int endOffset);
public IMacroDefinition defineFunctionStyleMacro(FunctionStyleMacro m,
int startOffset, int nameOffset, int nameEndOffset, int endOffset);
public void encounterPoundIf(int startOffset, int endOffset, boolean taken); public void encounterPoundIf(int startOffset, int endOffset, boolean taken);
@ -60,7 +70,17 @@ public interface IScannerPreprocessorLog {
public void encounterPoundError(int startOffset, int endOffset); public void encounterPoundError(int startOffset, int endOffset);
public void encounterPoundUndef(int startOffset, int endOffset); public void encounterPoundUndef(int startOffset, int endOffset,
char[] symbol, int nameOffset, IMacroDefinition macroDefinition);
public void encounterProblem(IASTProblem problem); public void encounterProblem(IASTProblem problem);
public IMacroDefinition registerBuiltinObjectStyleMacro(ObjectStyleMacro macro);
public IMacroDefinition registerBuiltinFunctionStyleMacro(FunctionStyleMacro macro);
public IMacroDefinition registerBuiltinDynamicFunctionStyleMacro(DynamicFunctionStyleMacro macro);
public IMacroDefinition registerBuiltinDynamicStyleMacro(DynamicStyleMacro macro);
} }

View file

@ -0,0 +1,50 @@
/**********************************************************************
* Copyright (c) 2004 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM - Initial API and implementation
**********************************************************************/
package org.eclipse.cdt.internal.core.parser.scanner2;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IMacroBinding;
import org.eclipse.cdt.core.dom.ast.IScope;
public class MacroBinding implements IMacroBinding {
private final char[] name;
private final IScope scope;
private final IScannerPreprocessorLog.IMacroDefinition definition;
public MacroBinding( char [] name, IScope scope, IScannerPreprocessorLog.IMacroDefinition definition )
{
this.name = name;
this.scope = scope;
this.definition = definition;
}
public String getName() {
return new String( name );
}
public char[] getNameCharArray() {
return name;
}
public IScope getScope() throws DOMException {
return scope;
}
/**
* @return Returns the definition.
*/
public IScannerPreprocessorLog.IMacroDefinition getDefinition() {
return definition;
}
}

View file

@ -11,6 +11,7 @@
package org.eclipse.cdt.internal.core.parser.scanner2; package org.eclipse.cdt.internal.core.parser.scanner2;
import org.eclipse.cdt.core.parser.IMacro; import org.eclipse.cdt.core.parser.IMacro;
import org.eclipse.cdt.internal.core.parser.scanner2.IScannerPreprocessorLog.IMacroDefinition;
/** /**
* @author Doug Schaefer * @author Doug Schaefer
@ -19,6 +20,7 @@ public class ObjectStyleMacro implements IMacro{
public char[] name; public char[] name;
public char[] expansion; public char[] expansion;
public IMacroDefinition attachment;
public ObjectStyleMacro(char[] name, char[] expansion) { public ObjectStyleMacro(char[] name, char[] expansion) {
this.name = name; this.name = name;
@ -32,4 +34,8 @@ public class ObjectStyleMacro implements IMacro{
public char[] getName(){ public char[] getName(){
return name; return name;
} }
public String toString() {
return new String( name );
}
} }

View file

@ -34,272 +34,302 @@ import org.eclipse.cdt.internal.core.parser.token.SimpleToken;
*/ */
public class Scanner2 extends BaseScanner { public class Scanner2 extends BaseScanner {
/** /**
* @param reader * @param reader
* @param info * @param info
* @param requestor * @param requestor
* @param parserMode * @param parserMode
* @param language * @param language
* @param log * @param log
* @param workingCopies * @param workingCopies
* @param configuration * @param configuration
*/ */
public Scanner2(CodeReader reader, IScannerInfo info, public Scanner2(CodeReader reader, IScannerInfo info,
ISourceElementRequestor requestor, ParserMode parserMode, ISourceElementRequestor requestor, ParserMode parserMode,
ParserLanguage language, IParserLogService log, List workingCopies, ParserLanguage language, IParserLogService log, List workingCopies,
IScannerExtensionConfiguration configuration) { IScannerExtensionConfiguration configuration) {
super(reader, info, parserMode, language, log, configuration); super(reader, info, parserMode, language, log, configuration);
this.requestor = requestor; this.requestor = requestor;
this.callbackManager = new ScannerCallbackManager(requestor); this.callbackManager = new ScannerCallbackManager(requestor);
this.expressionEvaluator = new ExpressionEvaluator(callbackManager, spf); this.expressionEvaluator = new ExpressionEvaluator(callbackManager, spf);
this.workingCopies = workingCopies; this.workingCopies = workingCopies;
postConstructorSetup(reader, info); postConstructorSetup(reader, info);
} }
/* /*
* (non-Javadoc) * (non-Javadoc)
* *
* @see org.eclipse.cdt.internal.core.parser.scanner.IScannerData#getASTFactory() * @see org.eclipse.cdt.internal.core.parser.scanner.IScannerData#getASTFactory()
*/ */
protected IASTFactory getASTFactory() { protected IASTFactory getASTFactory() {
if (astFactory == null) if (astFactory == null)
astFactory = ParserFactory.createASTFactory(parserMode, language); astFactory = ParserFactory.createASTFactory(parserMode, language);
return astFactory; return astFactory;
} }
protected IASTFactory astFactory; protected IASTFactory astFactory;
// callbacks // callbacks
protected ScannerCallbackManager callbackManager; protected ScannerCallbackManager callbackManager;
protected ISourceElementRequestor requestor; protected ISourceElementRequestor requestor;
protected List workingCopies; protected List workingCopies;
public final void setASTFactory(IASTFactory f) { public final void setASTFactory(IASTFactory f) {
astFactory = f; astFactory = f;
} }
/* /*
* (non-Javadoc) * (non-Javadoc)
* *
* @see org.eclipse.cdt.internal.core.parser.scanner2.BaseScanner#createInclusionConstruct(char[], * @see org.eclipse.cdt.internal.core.parser.scanner2.BaseScanner#createInclusionConstruct(char[],
* char[], boolean, int, int, int, int, int, int, int, boolean) * char[], boolean, int, int, int, int, int, int, int, boolean)
*/ */
protected Object createInclusionConstruct(char[] fileName, protected Object createInclusionConstruct(char[] fileName,
char[] filenamePath, boolean local, int startOffset, char[] filenamePath, boolean local, int startOffset,
int startingLineNumber, int nameOffset, int nameEndOffset, int startingLineNumber, int nameOffset, int nameEndOffset,
int nameLine, int endOffset, int endLine, boolean isForced) { int nameLine, int endOffset, int endLine, boolean isForced) {
return getASTFactory().createInclusion(fileName, filenamePath, local, return getASTFactory().createInclusion(fileName, filenamePath, local,
startOffset, startingLineNumber, nameOffset, nameEndOffset, startOffset, startingLineNumber, nameOffset, nameEndOffset,
nameLine, endOffset, endLine, getCurrentFilename(), isForced); nameLine, endOffset, endLine, getCurrentFilename(), isForced);
} }
/* /*
* (non-Javadoc) * (non-Javadoc)
* *
* @see org.eclipse.cdt.internal.core.parser.scanner2.BaseScanner#processMacro(char[], * @see org.eclipse.cdt.internal.core.parser.scanner2.BaseScanner#processMacro(char[],
* int, int, int, int, int, int, int) * int, int, int, int, int, int, int)
*/ */
protected void processMacro(char[] name, int startingOffset, protected void processMacro(char[] name, int startingOffset,
int startingLineNumber, int idstart, int idend, int nameLine, int startingLineNumber, int idstart, int idend, int nameLine,
int textEnd, int endingLine, org.eclipse.cdt.core.parser.IMacro macro) { int textEnd, int endingLine,
callbackManager.pushCallback(getASTFactory().createMacro(name, org.eclipse.cdt.core.parser.IMacro macro) {
startingOffset, startingLineNumber, idstart, idend, nameLine, callbackManager.pushCallback(getASTFactory().createMacro(name,
textEnd, endingLine, getCurrentFilename(), !isInitialized)); startingOffset, startingLineNumber, idstart, idend, nameLine,
} textEnd, endingLine, getCurrentFilename(), !isInitialized));
}
/* /*
* (non-Javadoc) * (non-Javadoc)
* *
* @see org.eclipse.cdt.internal.core.parser.scanner2.BaseScanner#pushContext(char[], * @see org.eclipse.cdt.internal.core.parser.scanner2.BaseScanner#pushContext(char[],
* java.lang.Object) * java.lang.Object)
*/ */
protected void pushContext(char[] buffer, Object data) { protected void pushContext(char[] buffer, Object data) {
super.pushContext(buffer, data); super.pushContext(buffer, data);
if (data instanceof InclusionData) { if (data instanceof InclusionData) {
callbackManager.pushCallback(data); callbackManager.pushCallback(data);
if (log.isTracing()) { if (log.isTracing()) {
StringBuffer b = new StringBuffer("Entering inclusion "); //$NON-NLS-1$ StringBuffer b = new StringBuffer("Entering inclusion "); //$NON-NLS-1$
b.append(((InclusionData) data).reader.filename); b.append(((InclusionData) data).reader.filename);
log.traceLog(b.toString()); log.traceLog(b.toString());
} }
} }
} }
/* /*
* (non-Javadoc) * (non-Javadoc)
* *
* @see org.eclipse.cdt.internal.core.parser.scanner2.BaseScanner#beforeSecondFetchToken() * @see org.eclipse.cdt.internal.core.parser.scanner2.BaseScanner#beforeSecondFetchToken()
*/ */
protected void beforeSecondFetchToken() { protected void beforeSecondFetchToken() {
if (callbackManager.hasCallbacks()) if (callbackManager.hasCallbacks())
callbackManager.popCallbacks(); callbackManager.popCallbacks();
} }
/* /*
* (non-Javadoc) * (non-Javadoc)
* *
* @see org.eclipse.cdt.internal.core.parser.scanner2.BaseScanner#quickParsePushPopInclusion(java.lang.Object) * @see org.eclipse.cdt.internal.core.parser.scanner2.BaseScanner#quickParsePushPopInclusion(java.lang.Object)
*/ */
protected void quickParsePushPopInclusion(Object inclusion) { protected void quickParsePushPopInclusion(Object inclusion) {
callbackManager.pushCallback(new InclusionData(null, inclusion)); callbackManager.pushCallback(new InclusionData(null, inclusion));
callbackManager.pushCallback(inclusion); callbackManager.pushCallback(inclusion);
} }
/* /*
* (non-Javadoc) * (non-Javadoc)
* *
* @see org.eclipse.cdt.internal.core.parser.scanner2.BaseScanner#createReaderDuple(java.lang.String) * @see org.eclipse.cdt.internal.core.parser.scanner2.BaseScanner#createReaderDuple(java.lang.String)
*/ */
protected CodeReader createReaderDuple(String finalPath) { protected CodeReader createReaderDuple(String finalPath) {
return ScannerUtility.createReaderDuple(finalPath, requestor, return ScannerUtility.createReaderDuple(finalPath, requestor,
getWorkingCopies()); getWorkingCopies());
} }
/* /*
* (non-Javadoc) * (non-Javadoc)
* *
* @see org.eclipse.cdt.core.parser.IScanner#getLocationResolver() * @see org.eclipse.cdt.core.parser.IScanner#getLocationResolver()
*/ */
public ILocationResolver getLocationResolver() { public ILocationResolver getLocationResolver() {
return null; return null;
} }
/* /*
* (non-Javadoc) * (non-Javadoc)
* *
* @see org.eclipse.cdt.internal.core.parser.scanner.IScannerData#getWorkingCopies() * @see org.eclipse.cdt.internal.core.parser.scanner.IScannerData#getWorkingCopies()
*/ */
protected Iterator getWorkingCopies() { protected Iterator getWorkingCopies() {
if (workingCopies == null) if (workingCopies == null)
return EmptyIterator.EMPTY_ITERATOR; return EmptyIterator.EMPTY_ITERATOR;
return workingCopies.iterator(); return workingCopies.iterator();
} }
/** /**
* @return * @return
*/ */
protected IToken newToken(int signal) { protected IToken newToken(int signal) {
if (bufferData[bufferStackPos] instanceof MacroData) { if (bufferData[bufferStackPos] instanceof MacroData) {
int mostRelevant; int mostRelevant;
for (mostRelevant = bufferStackPos; mostRelevant >= 0; --mostRelevant) for (mostRelevant = bufferStackPos; mostRelevant >= 0; --mostRelevant)
if (bufferData[mostRelevant] instanceof InclusionData if (bufferData[mostRelevant] instanceof InclusionData
|| bufferData[mostRelevant] instanceof CodeReader) || bufferData[mostRelevant] instanceof CodeReader)
break; break;
MacroData data = (MacroData) bufferData[mostRelevant + 1]; MacroData data = (MacroData) bufferData[mostRelevant + 1];
return new SimpleExpansionToken(signal, data.startOffset, return new SimpleExpansionToken(signal, data.startOffset,
data.endOffset - data.startOffset + 1, getCurrentFilename(), data.endOffset - data.startOffset + 1,
getLineNumber(bufferPos[mostRelevant] + 1)); getCurrentFilename(),
} getLineNumber(bufferPos[mostRelevant] + 1));
return new SimpleToken(signal, bufferPos[bufferStackPos] + 1, }
getCurrentFilename(), getLineNumber(bufferPos[bufferStackPos] + 1)); return new SimpleToken(signal, bufferPos[bufferStackPos] + 1,
} getCurrentFilename(),
getLineNumber(bufferPos[bufferStackPos] + 1));
}
protected IToken newToken(int signal, char[] buffer) { protected IToken newToken(int signal, char[] buffer) {
if (bufferData[bufferStackPos] instanceof MacroData) { if (bufferData[bufferStackPos] instanceof MacroData) {
int mostRelevant; int mostRelevant;
for (mostRelevant = bufferStackPos; mostRelevant >= 0; --mostRelevant) for (mostRelevant = bufferStackPos; mostRelevant >= 0; --mostRelevant)
if (bufferData[mostRelevant] instanceof InclusionData if (bufferData[mostRelevant] instanceof InclusionData
|| bufferData[mostRelevant] instanceof CodeReader) || bufferData[mostRelevant] instanceof CodeReader)
break; break;
MacroData data = (MacroData) bufferData[mostRelevant + 1]; MacroData data = (MacroData) bufferData[mostRelevant + 1];
return new ImagedExpansionToken(signal, buffer, data.startOffset, return new ImagedExpansionToken(signal, buffer, data.startOffset,
data.endOffset - data.startOffset + 1, getCurrentFilename(), data.endOffset - data.startOffset + 1,
getLineNumber(bufferPos[mostRelevant] + 1)); getCurrentFilename(),
} getLineNumber(bufferPos[mostRelevant] + 1));
IToken i = new ImagedToken(signal, buffer, bufferPos[bufferStackPos] + 1, }
getCurrentFilename(), getLineNumber(bufferPos[bufferStackPos] + 1)); IToken i = new ImagedToken(signal, buffer,
if (buffer != null && buffer.length == 0 && signal != IToken.tSTRING bufferPos[bufferStackPos] + 1, getCurrentFilename(),
&& signal != IToken.tLSTRING) getLineNumber(bufferPos[bufferStackPos] + 1));
bufferPos[bufferStackPos] += 1; // TODO - remove this hack at some if (buffer != null && buffer.length == 0 && signal != IToken.tSTRING
// point && signal != IToken.tLSTRING)
bufferPos[bufferStackPos] += 1; // TODO - remove this hack at some
// point
return i; return i;
} }
protected static final ScannerProblemFactory spf = new ScannerProblemFactory(); protected static final ScannerProblemFactory spf = new ScannerProblemFactory();
/* /*
* (non-Javadoc) * (non-Javadoc)
* *
* @see org.eclipse.cdt.internal.core.parser.scanner2.BaseScanner#handleProblem(int, * @see org.eclipse.cdt.internal.core.parser.scanner2.BaseScanner#handleProblem(int,
* int, char[]) * int, char[])
*/ */
protected void handleProblem(int id, int offset, char[] arg) { protected void handleProblem(int id, int offset, char[] arg) {
if (parserMode == ParserMode.COMPLETION_PARSE) if (parserMode == ParserMode.COMPLETION_PARSE)
return; return;
IProblem p = spf.createProblem(id, offset, bufferPos[bufferStackPos], IProblem p = spf.createProblem(id, offset, bufferPos[bufferStackPos],
getLineNumber(bufferPos[bufferStackPos]), getCurrentFilename(), getLineNumber(bufferPos[bufferStackPos]), getCurrentFilename(),
arg != null ? arg : EMPTY_CHAR_ARRAY, false, true); arg != null ? arg : EMPTY_CHAR_ARRAY, false, true);
callbackManager.pushCallback(p); callbackManager.pushCallback(p);
} }
/* /*
* (non-Javadoc) * (non-Javadoc)
* *
* @see org.eclipse.cdt.internal.core.parser.scanner2.BaseScanner#popContext() * @see org.eclipse.cdt.internal.core.parser.scanner2.BaseScanner#popContext()
*/ */
protected Object popContext() { protected Object popContext() {
if (bufferData[bufferStackPos] instanceof InclusionData) { if (bufferData[bufferStackPos] instanceof InclusionData) {
if (log.isTracing()) { if (log.isTracing()) {
StringBuffer buffer = new StringBuffer("Exiting inclusion "); //$NON-NLS-1$ StringBuffer buffer = new StringBuffer("Exiting inclusion "); //$NON-NLS-1$
buffer buffer
.append(((InclusionData) bufferData[bufferStackPos]).reader.filename); .append(((InclusionData) bufferData[bufferStackPos]).reader.filename);
log.traceLog(buffer.toString()); log.traceLog(buffer.toString());
} }
callbackManager callbackManager
.pushCallback(((InclusionData) bufferData[bufferStackPos]).inclusion); .pushCallback(((InclusionData) bufferData[bufferStackPos]).inclusion);
} }
return super.popContext(); return super.popContext();
} }
/* (non-Javadoc) /*
* @see org.eclipse.cdt.internal.core.parser.scanner2.BaseScanner#processIfdef(int, int, boolean, boolean) * (non-Javadoc)
*/ *
protected void processIfdef(int startPos, int endPos, boolean positive, boolean taken) { * @see org.eclipse.cdt.internal.core.parser.scanner2.BaseScanner#processIfdef(int,
} * int, boolean, boolean)
*/
protected void processIfdef(int startPos, int endPos, boolean positive,
boolean taken) {
}
/* (non-Javadoc) /*
* @see org.eclipse.cdt.internal.core.parser.scanner2.BaseScanner#processIf(int, int, boolean) * (non-Javadoc)
*/ *
protected void processIf(int startPos, int endPos, boolean taken) { * @see org.eclipse.cdt.internal.core.parser.scanner2.BaseScanner#processIf(int,
} * int, boolean)
*/
protected void processIf(int startPos, int endPos, boolean taken) {
}
/* (non-Javadoc) /*
* @see org.eclipse.cdt.internal.core.parser.scanner2.BaseScanner#processElsif(int, int, boolean) * (non-Javadoc)
*/ *
protected void processElsif(int startPos, int endPos, boolean taken) { * @see org.eclipse.cdt.internal.core.parser.scanner2.BaseScanner#processElsif(int,
} * int, boolean)
*/
protected void processElsif(int startPos, int endPos, boolean taken) {
}
/* (non-Javadoc) /*
* @see org.eclipse.cdt.internal.core.parser.scanner2.BaseScanner#processElse(int, int, boolean) * (non-Javadoc)
*/ *
protected void processElse(int startPos, int endPos, boolean taken) { * @see org.eclipse.cdt.internal.core.parser.scanner2.BaseScanner#processElse(int,
} * int, boolean)
*/
protected void processElse(int startPos, int endPos, boolean taken) {
}
/* (non-Javadoc) /*
* @see org.eclipse.cdt.internal.core.parser.scanner2.BaseScanner#processUndef(int, int) * (non-Javadoc)
*/ *
protected void processUndef(int pos, int endPos) { * @see org.eclipse.cdt.internal.core.parser.scanner2.BaseScanner#processUndef(int,
} * int)
*/
protected void processUndef(int pos, int endPos, char[] symbol, int namePos, Object definition) {
}
/* (non-Javadoc) /*
* @see org.eclipse.cdt.internal.core.parser.scanner2.BaseScanner#processError(int, int) * (non-Javadoc)
*/ *
protected void processError(int startPos, int endPos) { * @see org.eclipse.cdt.internal.core.parser.scanner2.BaseScanner#processError(int,
} * int)
*/
protected void processError(int startPos, int endPos) {
}
/* (non-Javadoc) /*
* @see org.eclipse.cdt.internal.core.parser.scanner2.BaseScanner#processEndif(int, int) * (non-Javadoc)
*/ *
protected void processEndif(int pos, int i) { * @see org.eclipse.cdt.internal.core.parser.scanner2.BaseScanner#processEndif(int,
} * int)
*/
protected void processEndif(int pos, int i) {
}
/* (non-Javadoc) /*
* @see org.eclipse.cdt.internal.core.parser.scanner2.BaseScanner#processPragma(int, int) * (non-Javadoc)
*/ *
protected void processPragma(int startPos, int endPos) { * @see org.eclipse.cdt.internal.core.parser.scanner2.BaseScanner#processPragma(int,
} * int)
*/
protected void processPragma(int startPos, int endPos) {
}
} }

View file

@ -72,9 +72,7 @@ public class CPopulateASTViewAction extends CASTVisitor implements IPopulateDOMA
if (node == null) return PROCESS_CONTINUE; if (node == null) return PROCESS_CONTINUE;
IASTNodeLocation[] nodeLocations = node.getNodeLocations(); IASTNodeLocation[] nodeLocations = node.getNodeLocations();
if (!(nodeLocations.length > 0 && if (!(nodeLocations.length > 0 ) )
nodeLocations[0].getNodeOffset() >= 0 &&
nodeLocations[0].getNodeLength() > 0))
return PROCESS_CONTINUE; return PROCESS_CONTINUE;
DOMASTNodeParent parent = root.findTreeParentForNode(node); DOMASTNodeParent parent = root.findTreeParentForNode(node);

View file

@ -279,21 +279,30 @@ public class DOMASTNodeLeaf implements IAdaptable {
IASTNodeLocation [] location = node.getNodeLocations(); IASTNodeLocation [] location = node.getNodeLocations();
if( location.length > 0 && location[0] instanceof IASTFileLocation ) if( location.length > 0 && location[0] instanceof IASTFileLocation )
return ((IASTFileLocation)location[0]).getFileName(); return ((IASTFileLocation)location[0]).getFileName();
return BLANK_STRING; //$NON-NLS-1$ IASTFileLocation f = node.getTranslationUnit().flattenLocationsToFile(location);
if( f == null )
return BLANK_STRING; //$NON-NLS-1$
return f.getFileName();
} }
public int getOffset() { public int getOffset() {
IASTNodeLocation [] location = node.getNodeLocations(); IASTNodeLocation [] location = node.getNodeLocations();
if( location.length == 1 ) if( location.length == 1 && location[0] instanceof IASTFileLocation )
return location[0].getNodeOffset(); return location[0].getNodeOffset();
return 0; IASTFileLocation f = node.getTranslationUnit().flattenLocationsToFile(location);
if( f == null )
return 0; //$NON-NLS-1$
return f.getNodeOffset();
} }
public int getLength() { public int getLength() {
IASTNodeLocation [] location = node.getNodeLocations(); IASTNodeLocation [] location = node.getNodeLocations();
if( location.length == 1 ) if( location.length == 1 && location[0] instanceof IASTFileLocation )
return location[0].getNodeLength(); return location[0].getNodeLength();
return 0; IASTFileLocation f = node.getTranslationUnit().flattenLocationsToFile(location);
if( f == null )
return 0; //$NON-NLS-1$
return f.getNodeLength();
} }
public void setFiltersFlag(int flag) { public void setFiltersFlag(int flag) {
@ -447,9 +456,13 @@ public class DOMASTNodeLeaf implements IAdaptable {
} else if (obj instanceof ASTNodeProperty) { } else if (obj instanceof ASTNodeProperty) {
buffer.append(((ASTNodeProperty)obj).getName()); buffer.append(((ASTNodeProperty)obj).getName());
} else if (obj instanceof IASTName) { } else if (obj instanceof IASTName) {
buffer.append( trimObjectToString(((IASTName)obj).toString()) ); final String toString = ((IASTName)obj).toString();
buffer.append(COLON_SEPARATOR); if( toString != null )
buffer.append( getType(((IASTName)obj).resolveBinding()) ); {
buffer.append( trimObjectToString(toString) );
buffer.append(COLON_SEPARATOR);
buffer.append( getType(((IASTName)obj).resolveBinding()) );
}
} else if (obj instanceof IType) { } else if (obj instanceof IType) {
buffer.append(getType(obj)); buffer.append(getType(obj));
} else if (obj instanceof IBinding) { } else if (obj instanceof IBinding) {

View file

@ -13,18 +13,15 @@ package org.eclipse.cdt.ui.tests.DOMAST;
import org.eclipse.cdt.core.dom.ast.IASTFileLocation; import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTNodeLocation;
import org.eclipse.cdt.core.dom.ast.IASTProblem; import org.eclipse.cdt.core.dom.ast.IASTProblem;
import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.search.BasicSearchMatch; import org.eclipse.cdt.core.search.BasicSearchMatch;
import org.eclipse.cdt.core.search.IMatch; import org.eclipse.cdt.core.search.IMatch;
import org.eclipse.cdt.ui.testplugin.CTestPlugin;
import org.eclipse.cdt.internal.ui.search.CSearchQuery; import org.eclipse.cdt.internal.ui.search.CSearchQuery;
import org.eclipse.cdt.internal.ui.search.CSearchResult; import org.eclipse.cdt.internal.ui.search.CSearchResult;
import org.eclipse.cdt.internal.ui.search.NewSearchResultCollector; import org.eclipse.cdt.internal.ui.search.NewSearchResultCollector;
import org.eclipse.core.resources.IFile; import org.eclipse.cdt.ui.testplugin.CTestPlugin;
import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IProgressMonitor;
@ -71,26 +68,16 @@ public class DOMQuery extends CSearchQuery implements ISearchQuery {
for (int i=0; i<nodes.length; i++) { for (int i=0; i<nodes.length; i++) {
try { try {
String fileName = null; String fileName = null;
IFile file = null;
IPath path = null; IPath path = null;
int start = 0; int start = 0;
int end = 0; int end = 0;
if ( nodes[i] != null ) { if ( nodes[i] != null ) {
IASTNodeLocation [] location = nodes[i].getNodeLocations(); IASTFileLocation location = nodes[i].getTranslationUnit().flattenLocationsToFile( nodes[i].getNodeLocations() );
if( location.length > 0 && location[0] instanceof IASTFileLocation ) fileName = location.getFileName();
fileName = ((IASTFileLocation)location[0]).getFileName(); // TODO Devin this is in two places now, put into one, and fix up the location[0] for things like macros
else
fileName = BLANK_STRING;
path = new Path(fileName); path = new Path(fileName);
file = ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(path); start = location.getNodeOffset();
end = location.getNodeOffset() + location.getNodeLength();
if (nodes[i].getNodeLocations().length > 0) { // fix for 84223 collector.acceptMatch( createMatch(path, start, end, nodes[i], path ) );
start = nodes[i].getNodeLocations()[0].getNodeOffset();
end = nodes[i].getNodeLocations()[0].getNodeOffset() + nodes[i].getNodeLocations()[0].getNodeLength();
collector.acceptMatch( createMatch(file, start, end, nodes[i], path ) );
}
} }
} catch (CoreException ce) {} } catch (CoreException ce) {}
} }