diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMLocationMacroTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMLocationMacroTests.java new file mode 100644 index 00000000000..0f01e58778d --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMLocationMacroTests.java @@ -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]); + + } + } + +} diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMLocationTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMLocationTests.java index 324c00491b0..cb9b42e8ecc 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMLocationTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMLocationTests.java @@ -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.IASTUnaryExpression; 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.ICPPASTFunctionTryBlockDeclarator; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLinkageSpecification; @@ -454,7 +453,7 @@ public class DOMLocationTests extends AST2BaseTest { } 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 : null) { IASTTranslationUnit tu = parse(code, p); diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMParserTestSuite.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMParserTestSuite.java index fb98c813117..69a96cd86f5 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMParserTestSuite.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMParserTestSuite.java @@ -31,6 +31,7 @@ public class DOMParserTestSuite extends TestCase { suite.addTestSuite( CompleteParser2Tests.class ); // suite.addTestSuite( DOMScannerTests.class ); suite.addTestSuite( DOMLocationTests.class ); + suite.addTestSuite( DOMLocationMacroTests.class ); suite.addTest( DOMLocationInclusionTests.suite() ); suite.addTestSuite( AST2KnRTests.class ); suite.addTestSuite( AST2UtilTests.class ); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTMacroExpansion.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTMacroExpansion.java index 3f5a45913ad..8376651f09d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTMacroExpansion.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTMacroExpansion.java @@ -33,5 +33,7 @@ public interface IASTMacroExpansion extends IASTNodeLocation { * @return */ public IASTNodeLocation[] getExpansionLocations(); + + } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTNodeLocation.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTNodeLocation.java index 2c471aa68f4..d02ca4d0be1 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTNodeLocation.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTNodeLocation.java @@ -33,4 +33,11 @@ public interface IASTNodeLocation { */ public int getNodeLength(); + /** + * Return a file location that best maps into this location. + * + * @return + */ + public IASTFileLocation asFileLocation(); + } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTPreprocessorFunctionStyleMacroDefinition.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTPreprocessorFunctionStyleMacroDefinition.java index 30551675060..b6f7ba662bb 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTPreprocessorFunctionStyleMacroDefinition.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTPreprocessorFunctionStyleMacroDefinition.java @@ -14,6 +14,8 @@ package org.eclipse.cdt.core.dom.ast; * This interface represent a preprocessor function-style macro definition. e.g. * #define ABC( def ) GHI * + * Note: macros that are expanded as parameters to function style macros are not captured in this abstraction. + * * @author jcamelon */ public interface IASTPreprocessorFunctionStyleMacroDefinition extends diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTPreprocessorUndefStatement.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTPreprocessorUndefStatement.java index 2442cfae821..739516f804c 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTPreprocessorUndefStatement.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTPreprocessorUndefStatement.java @@ -18,4 +18,7 @@ package org.eclipse.cdt.core.dom.ast; public interface IASTPreprocessorUndefStatement extends 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(); + } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTTranslationUnit.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTTranslationUnit.java index 148ff70bc5b..85acd26372d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTTranslationUnit.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTTranslationUnit.java @@ -37,7 +37,7 @@ public interface IASTTranslationUnit extends IASTNode { */ public static final ASTNodeProperty PREPROCESSOR_STATEMENT = new ASTNodeProperty( "IASTTranslationUnit.PREPROCESSOR_STATEMENT - IASTPreprocessorStatement for IASTTranslationUnit"); //$NON-NLS-1$ - + /** * A translation unit contains an ordered sequence of declarations. * @@ -134,4 +134,34 @@ public interface IASTTranslationUnit extends IASTNode { * @return String representation of path. */ public String getFilePath(); + + /** + * Flatten the node locations provided into a single file location. + * + * @param nodeLocations IASTNodeLocations 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(); + + + } \ No newline at end of file diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IBinding.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IBinding.java index 2bace021525..8edeced39b7 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IBinding.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IBinding.java @@ -21,6 +21,12 @@ public interface IBinding { * @return name */ public String getName(); + + /** + * The name of the binding. + * + * @return name + */ public char[] getNameCharArray(); /** diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IMacroBinding.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IMacroBinding.java new file mode 100644 index 00000000000..e91481e9d65 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IMacroBinding.java @@ -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 { + +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/CodeReader.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/CodeReader.java index dd8e913dc2f..b1205fd4acc 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/CodeReader.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/CodeReader.java @@ -127,5 +127,9 @@ public class CodeReader { public boolean isFile() { return !CharArrayUtils.equals( filename, NOFILE ); } + + public String toString() { + return new String( filename ); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/IExtendedScannerInfo.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/IExtendedScannerInfo.java index 2d22b9fe5c0..627329e5dec 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/IExtendedScannerInfo.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/IExtendedScannerInfo.java @@ -26,5 +26,10 @@ public interface IExtendedScannerInfo extends IScannerInfo { */ public String [] getIncludeFiles(); + /** + * Get local inclusions? + * + * @return + */ public String [] getLocalIncludePath(); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTFileLocation.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTFileLocation.java deleted file mode 100644 index d448711eaf2..00000000000 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTFileLocation.java +++ /dev/null @@ -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; - } - -} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTProblem.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTProblem.java index bff63ad244a..d9334e2aaba 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTProblem.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTProblem.java @@ -273,12 +273,21 @@ public class CASTProblem extends CASTNode implements IASTProblem { IASTNodeLocation [] locs = getNodeLocations(); String file = null; int offset = 0; - if( locs != null && locs.length > 0 ){ + if( locs != null && locs.length == 1 && locs[0] instanceof IASTFileLocation ){ file = ((IASTFileLocation) locs[0]).getFileName(); offset = locs[0].getNodeOffset(); } else { - file = ""; //$NON-NLS-1$ - offset = 0; + IASTFileLocation f = getTranslationUnit().flattenLocationsToFile(locs); + 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$ diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTTranslationUnit.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTTranslationUnit.java index 4e16677473f..993bf3ba4ae 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTTranslationUnit.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTTranslationUnit.java @@ -9,7 +9,6 @@ * IBM Rational Software - Initial API and implementation */ 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.IASTArrayDeclarator; 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.IASTDeclarator; 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.IASTName; 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.IASTTypeId; 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.c.CASTVisitor; 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 IASTName[] EMPTY_NAME_ARRAY = new IASTName[0]; + public void addDeclaration(IASTDeclaration d) { if (decls == null) { 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) */ 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); } @@ -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) */ 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); } @@ -375,8 +388,6 @@ public class CASTTranslationUnit extends CASTNode implements return EMPTY_PREPROCESSOR_MACRODEF_ARRAY; IASTPreprocessorMacroDefinition[] result = resolver .getMacroDefinitions(); - setParentRelationship(result, - IASTTranslationUnit.PREPROCESSOR_STATEMENT); return result; } @@ -390,24 +401,10 @@ public class CASTTranslationUnit extends CASTNode implements return EMPTY_PREPROCESSOR_INCLUSION_ARRAY; IASTPreprocessorIncludeStatement[] result = resolver .getIncludeDirectives(); - setParentRelationship(result, - IASTTranslationUnit.PREPROCESSOR_STATEMENT); 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) * * @see org.eclipse.cdt.core.dom.ast.IASTTranslationUnit#getAllPreprocessorStatements() @@ -417,8 +414,6 @@ public class CASTTranslationUnit extends CASTNode implements return EMPTY_PREPROCESSOR_STATEMENT_ARRAY; IASTPreprocessorStatement[] result = resolver .getAllPreprocessorStatements(); - setParentRelationship(result, - IASTTranslationUnit.PREPROCESSOR_STATEMENT); return result; } @@ -429,6 +424,7 @@ public class CASTTranslationUnit extends CASTNode implements */ public void setLocationResolver(ILocationResolver resolver) { this.resolver = resolver; + resolver.setRootNode( this ); } /* @@ -495,4 +491,22 @@ public class CASTTranslationUnit extends CASTNode implements } 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(); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTranslationUnit.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTranslationUnit.java index ea53ebfea22..6d331d90d7c 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTranslationUnit.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTranslationUnit.java @@ -10,7 +10,6 @@ **********************************************************************/ 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.IASTArrayDeclarator; 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.IASTDeclarator; 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.IASTName; 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.IASTTypeId; 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.c.ICASTDesignator; 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 IASTProblem[] EMPTY_PROBLEM_ARRAY = new IASTProblem[0]; + private static final IASTName[] EMPTY_NAME_ARRAY = new IASTName[0]; + public void addDeclaration(IASTDeclaration d) { if (decls == null) { 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) */ 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 ); } @@ -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) */ 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); } @@ -366,7 +381,6 @@ public class CPPASTTranslationUnit extends CPPASTNode implements public IASTPreprocessorMacroDefinition[] getMacroDefinitions() { if( resolver == null ) return EMPTY_PREPROCESSOR_MACRODEF_ARRAY; IASTPreprocessorMacroDefinition [] result = resolver.getMacroDefinitions(); - setParentRelationship( result, IASTTranslationUnit.PREPROCESSOR_STATEMENT ); return result; } @@ -378,22 +392,9 @@ public class CPPASTTranslationUnit extends CPPASTNode implements public IASTPreprocessorIncludeStatement[] getIncludeDirectives() { if( resolver == null ) return EMPTY_PREPROCESSOR_INCLUSION_ARRAY; IASTPreprocessorIncludeStatement [] result = resolver.getIncludeDirectives(); - setParentRelationship( result, IASTTranslationUnit.PREPROCESSOR_STATEMENT ); 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) * @@ -403,7 +404,6 @@ public class CPPASTTranslationUnit extends CPPASTNode implements if (resolver == null) return EMPTY_PREPROCESSOR_STATEMENT_ARRAY; IASTPreprocessorStatement [] result = resolver.getAllPreprocessorStatements(); - setParentRelationship( result, IASTTranslationUnit.PREPROCESSOR_STATEMENT ); return result; } @@ -414,6 +414,7 @@ public class CPPASTTranslationUnit extends CPPASTNode implements */ public void setLocationResolver(ILocationResolver resolver) { this.resolver = resolver; + resolver.setRootNode( this ); } /* @@ -477,4 +478,24 @@ public class CPPASTTranslationUnit extends CPPASTNode implements } 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(); + } + + } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/BaseScanner.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/BaseScanner.java index e2237608d87..04b516e0ff1 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/BaseScanner.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/BaseScanner.java @@ -55,8 +55,6 @@ abstract class BaseScanner implements IScanner { 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); /** @@ -77,6 +75,10 @@ abstract class BaseScanner implements IScanner { this.reader = reader; this.inclusion = inclusion; } + + public String toString() { + return reader.toString(); + } } protected static class MacroData { @@ -91,6 +93,10 @@ abstract class BaseScanner implements IScanner { public final int endOffset; public final IMacro macro; + + public String toString() { + return macro.toString(); + } } protected ParserLanguage language; @@ -3236,16 +3242,20 @@ abstract class BaseScanner implements IScanner { handleCompletionOnDefinition(new String(buffer, idstart, idlen)); 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 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) throws EndOfFileException { @@ -3988,8 +3998,10 @@ abstract class BaseScanner implements IScanner { result); } if (pushContext) + { pushContext(result, new MacroData(start, bufferPos[bufferStackPos], macro)); + } return result; } @@ -4030,7 +4042,10 @@ abstract class BaseScanner implements IScanner { } if (expObject == null) + { return arg; + } + char[] expansion = null; if (expObject instanceof FunctionStyleMacro) { @@ -4060,6 +4075,8 @@ abstract class BaseScanner implements IScanner { System.arraycopy(arg, end + 1, result, start + expansion.length, limit - end - 1); + + beforeReplaceAllMacros(); //we need to put the macro on the context stack in order to detect // recursive macros pushContext(EMPTY_CHAR_ARRAY, @@ -4068,10 +4085,29 @@ abstract class BaseScanner implements IScanner { (IMacro) expObject)); arg = replaceArgumentMacros(result); //rescan for more macros popContext(); + afterReplaceAllMacros(); } + 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, CharArrayObjectMap argmap, CharArrayObjectMap replacedArgs, char[] result) { @@ -4161,6 +4197,7 @@ abstract class BaseScanner implements IScanner { char[] rep = (char[]) ((replacedArgs != null) ? replacedArgs .get(repObject) : null); + if (rep != null) repObject = rep; else { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/DOMScanner.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/DOMScanner.java index 5066852707f..6e38c1a476b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/DOMScanner.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/DOMScanner.java @@ -20,9 +20,7 @@ import org.eclipse.cdt.core.parser.IToken; import org.eclipse.cdt.core.parser.ParserLanguage; import org.eclipse.cdt.core.parser.ParserMode; 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.SimpleExpansionToken; import org.eclipse.cdt.internal.core.parser.token.SimpleToken; /** @@ -69,6 +67,36 @@ public class DOMScanner extends BaseScanner { 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) * @@ -113,14 +141,18 @@ public class DOMScanner extends BaseScanner { protected void processMacro(char[] name, int startingOffset, int startingLineNumber, int idstart, int idend, int nameLine, int textEnd, int endingLine, IMacro macro) { + IScannerPreprocessorLog.IMacroDefinition m = null; if (macro instanceof FunctionStyleMacro) - locationMap.defineFunctionStyleMacro((FunctionStyleMacro) macro, - resolveOffset(startingOffset), resolveOffset(idstart), - resolveOffset(idend), resolveOffset(textEnd)); + m = locationMap.defineFunctionStyleMacro( + (FunctionStyleMacro) macro, resolveOffset(startingOffset), + resolveOffset(idstart), resolveOffset(idend), + resolveOffset(textEnd)); else if (macro instanceof ObjectStyleMacro) - locationMap.defineObjectStyleMacro((ObjectStyleMacro) macro, + m = locationMap.defineObjectStyleMacro((ObjectStyleMacro) macro, resolveOffset(startingOffset), resolveOffset(idstart), 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())); 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); } + protected int fsmCount = 0; + /* * (non-Javadoc) * * @see org.eclipse.cdt.internal.core.parser.scanner2.BaseScanner#popContext() */ protected Object popContext() { - //TODO calibrate offsets + // TODO calibrate offsets Object result = super.popContext(); if (result instanceof CodeReader) { locationMap.endTranslationUnit(bufferDelta[0] + ((CodeReader) result).buffer.length); - } - if (result instanceof InclusionData) { + } else if (result instanceof InclusionData) { CodeReader codeReader = ((InclusionData) result).reader; if (log.isTracing()) { StringBuffer buffer = new StringBuffer("Exiting inclusion "); //$NON-NLS-1$ @@ -188,6 +239,25 @@ public class DOMScanner extends BaseScanner { + bufferPos[bufferStackPos + 1]); bufferDelta[bufferStackPos] += bufferDelta[bufferStackPos + 1] + 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; } @@ -211,18 +281,6 @@ public class DOMScanner extends BaseScanner { * @return */ 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, resolveOffset(bufferPos[bufferStackPos] + 1), getCurrentFilename(), @@ -230,24 +288,12 @@ public class DOMScanner extends BaseScanner { } 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, resolveOffset(bufferPos[bufferStackPos] + 1), EMPTY_CHAR_ARRAY, getLineNumber(bufferPos[bufferStackPos] + 1)); if (buffer != null && buffer.length == 0 && signal != IToken.tSTRING && signal != IToken.tLSTRING) - bufferPos[bufferStackPos] += 1; //TODO - remove this hack at some + bufferPos[bufferStackPos] += 1; // TODO - remove this hack at some // point return i; @@ -259,7 +305,7 @@ public class DOMScanner extends BaseScanner { * @see org.eclipse.cdt.internal.core.parser.scanner2.BaseScanner#quickParsePushPopInclusion(java.lang.Object) */ 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) { super.postConstructorSetup(reader, info); locationMap.startTranslationUnit(getMainReader()); + registerMacros(); } /* @@ -351,9 +398,12 @@ public class DOMScanner extends BaseScanner { * @see org.eclipse.cdt.internal.core.parser.scanner2.BaseScanner#processUndef(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), - resolveOffset(endPos)); + resolveOffset(endPos), symbol, namePos, macroDefinition); } /* @@ -389,4 +439,11 @@ public class DOMScanner extends BaseScanner { resolveOffset(endPos)); } + protected void beforeReplaceAllMacros() { + ++fsmCount; + } + + protected void afterReplaceAllMacros() { + --fsmCount; + } } \ No newline at end of file diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/DynamicStyleMacro.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/DynamicStyleMacro.java index 55eb1560022..a555aa53aef 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/DynamicStyleMacro.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/DynamicStyleMacro.java @@ -11,6 +11,7 @@ package org.eclipse.cdt.internal.core.parser.scanner2; import org.eclipse.cdt.core.parser.IMacro; +import org.eclipse.cdt.internal.core.parser.scanner2.IScannerPreprocessorLog.IMacroDefinition; /** * @author jcamelon @@ -24,7 +25,8 @@ public abstract class DynamicStyleMacro implements IMacro{ { name = n; } - public final char [] name; + public final char [] name; + public IMacroDefinition attachment; public char[] getSignature() { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/ILocationResolver.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/ILocationResolver.java index 2696493b19c..044435a1862 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/ILocationResolver.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/ILocationResolver.java @@ -10,11 +10,16 @@ **********************************************************************/ 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.IASTPreprocessorIncludeStatement; import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroDefinition; import org.eclipse.cdt.core.dom.ast.IASTPreprocessorStatement; 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; /** @@ -38,4 +43,11 @@ public interface ILocationResolver { 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(); + } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/IScannerPreprocessorLog.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/IScannerPreprocessorLog.java index b2cd4a15b3e..13a409a955f 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/IScannerPreprocessorLog.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/IScannerPreprocessorLog.java @@ -11,6 +11,7 @@ package org.eclipse.cdt.internal.core.parser.scanner2; import org.eclipse.cdt.core.dom.ast.IASTProblem; +import org.eclipse.cdt.core.dom.ast.IMacroBinding; import org.eclipse.cdt.core.parser.CodeReader; /** @@ -26,21 +27,30 @@ public interface IScannerPreprocessorLog { public void endInclusion(int offset); - public void enterObjectStyleMacroExpansion(char[] name, char[] expansion, - int offset); + public void startObjectStyleMacroExpansion(IMacroDefinition macro, + 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, - int nameOffset, int nameEndOffset, int endOffset); + public interface IMacroDefinition { + public char[] getName(); + public char[] getExpansion(); + + public IMacroBinding getBinding(); + public void setBinding( IMacroBinding b ); + } - public void defineFunctionStyleMacro(FunctionStyleMacro m, int startOffset, - int nameOffset, int nameEndOffset, int endOffset); + public IMacroDefinition defineObjectStyleMacro(ObjectStyleMacro m, + 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); @@ -60,7 +70,17 @@ public interface IScannerPreprocessorLog { 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 IMacroDefinition registerBuiltinObjectStyleMacro(ObjectStyleMacro macro); + + public IMacroDefinition registerBuiltinFunctionStyleMacro(FunctionStyleMacro macro); + + public IMacroDefinition registerBuiltinDynamicFunctionStyleMacro(DynamicFunctionStyleMacro macro); + + public IMacroDefinition registerBuiltinDynamicStyleMacro(DynamicStyleMacro macro); + } \ No newline at end of file diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/LocationMap.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/LocationMap.java index 2ed5d76330a..2a24815d5a8 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/LocationMap.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/LocationMap.java @@ -10,14 +10,11 @@ **********************************************************************/ package org.eclipse.cdt.internal.core.parser.scanner2; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - import org.eclipse.cdt.core.dom.ast.ASTNodeProperty; import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.IASTFileLocation; import org.eclipse.cdt.core.dom.ast.IASTFunctionStyleMacroParameter; +import org.eclipse.cdt.core.dom.ast.IASTMacroExpansion; import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTNodeLocation; @@ -38,7 +35,10 @@ import org.eclipse.cdt.core.dom.ast.IASTPreprocessorUndefStatement; import org.eclipse.cdt.core.dom.ast.IASTProblem; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.dom.ast.IMacroBinding; +import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit.IDependencyTree; import org.eclipse.cdt.core.parser.CodeReader; +import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ASTPreprocessorSelectionResult; @@ -48,12 +48,55 @@ import org.eclipse.cdt.internal.core.dom.parser.ASTPreprocessorSelectionResult; */ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog { + public class MacroExpansionLocation implements IASTMacroExpansion { + + public MacroExpansionLocation( + IASTPreprocessorMacroDefinition macroDefinition, + IASTNodeLocation[] locations, int offset, int length) { + this.definition = macroDefinition; + this.locations = locations; + this.offset = offset; + this.length = length; + } + + private final int length; + + private final int offset; + + private final IASTNodeLocation[] locations; + + private final IASTPreprocessorMacroDefinition definition; + + public IASTPreprocessorMacroDefinition getMacroDefinition() { + return definition; + } + + public IASTNodeLocation[] getExpansionLocations() { + return locations; + } + + public int getNodeOffset() { + return offset; + } + + public int getNodeLength() { + return length; + } + + public IASTFileLocation asFileLocation() { + return rootNode.flattenLocationsToFile(getExpansionLocations()); + } + + } + private static final String NOT_VALID_MACRO = "Not a valid macro selection"; //$NON-NLS-1$ - private static final String TU_INCLUDE_NOT_FOUND = "File searching does not match TU or #includes."; //$NON-NLS-1$ - /** + + private static final String TU_INCLUDE_NOT_FOUND = "File searching does not match TU or #includes."; //$NON-NLS-1$ + + /** * @author jcamelon */ - static class ASTEndif extends ScannerASTNode implements + public static class ASTEndif extends ScannerASTNode implements IASTPreprocessorEndifStatement { } @@ -61,7 +104,7 @@ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog { /** * @author jcamelon */ - static class ASTElif extends ScannerASTNode implements + public static class ASTElif extends ScannerASTNode implements IASTPreprocessorElifStatement { private final boolean taken; @@ -87,7 +130,7 @@ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog { /** * @author jcamelon */ - static class ASTElse extends ScannerASTNode implements + public static class ASTElse extends ScannerASTNode implements IASTPreprocessorElseStatement { private final boolean taken; @@ -112,7 +155,7 @@ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog { /** * @author jcamelon */ - static class ASTIfndef extends ScannerASTNode implements + public static class ASTIfndef extends ScannerASTNode implements IASTPreprocessorIfndefStatement { private final boolean taken; @@ -138,7 +181,7 @@ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog { /** * @author jcamelon */ - static class ASTIfdef extends ScannerASTNode implements + public static class ASTIfdef extends ScannerASTNode implements IASTPreprocessorIfdefStatement { private final boolean taken; @@ -164,7 +207,7 @@ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog { /** * @author jcamelon */ - static class ASTIf extends ScannerASTNode implements + public static class ASTIf extends ScannerASTNode implements IASTPreprocessorIfStatement { private final boolean taken; @@ -190,7 +233,7 @@ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog { /** * @author jcamelon */ - static class ASTError extends ScannerASTNode implements + public static class ASTError extends ScannerASTNode implements IASTPreprocessorErrorStatement { } @@ -198,7 +241,7 @@ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog { /** * @author jcamelon */ - static class ASTPragma extends ScannerASTNode implements + public static class ASTPragma extends ScannerASTNode implements IASTPreprocessorPragmaStatement { } @@ -206,9 +249,22 @@ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog { /** * @author jcamelon */ - static class ASTUndef extends ScannerASTNode implements + public static class ASTUndef extends ScannerASTNode implements IASTPreprocessorUndefStatement { + public ASTUndef( IASTName n ) + { + this.n = n; + n.setPropertyInParent( IASTPreprocessorUndefStatement.MACRO_NAME ); + n.setParent(this); + } + + private final IASTName n; + + public IASTName getMacroName() { + return n; + } + } /** @@ -405,7 +461,6 @@ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog { IASTPreprocessorFunctionStyleMacroDefinition { private IASTName name; - private String expansion; /* @@ -495,33 +550,58 @@ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog { public void setExpansion(String exp) { this.expansion = exp; } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.dom.ast.IASTNameOwner#getRoleForName(org.eclipse.cdt.core.dom.ast.IASTName) - */ - public int getRoleForName(IASTName n) { - if( name == n ) return r_declaration; - return r_unclear; - } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.core.dom.ast.IASTNameOwner#getRoleForName(org.eclipse.cdt.core.dom.ast.IASTName) + */ + public int getRoleForName(IASTName n) { + if (name == n) + return r_declaration; + return r_unclear; + } } public static interface _IPreprocessorDirective { } - protected static class _Undef extends _Context implements + protected class _Undef extends _Context implements _IPreprocessorDirective { + public final char[] name; + public final int nameOffset; + private IASTName expansionName; + public final IMacroDefinition macroDefn; + + public IASTName getName() + { + if( expansionName == null ) + { + expansionName = new ASTMacroName( name ); + ((ScannerASTNode)expansionName).setParent( rootNode ); + ((ScannerASTNode)expansionName).setPropertyInParent( IASTPreprocessorUndefStatement.MACRO_NAME ); + ((ScannerASTNode)expansionName).setOffsetAndLength( context_directive_start, name.length ); + } + return expansionName; + } + /** * @param parent * @param startOffset * @param endOffset */ - public _Undef(_CompositeContext parent, int startOffset, int endOffset) { + public _Undef(_CompositeContext parent, int startOffset, int endOffset, + char[] name, int nameOffset, IMacroDefinition macro ) { super(parent, startOffset, endOffset); + this.name = name; + this.nameOffset = nameOffset; + this.macroDefn = macro; } } - static class ScannerASTNode extends ASTNode { + public static class ScannerASTNode extends ASTNode { private IASTNode parent; private ASTNodeProperty property; @@ -572,10 +652,12 @@ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog { return (IASTTranslationUnit) node; } - /* (non-Javadoc) + /* + * (non-Javadoc) + * * @see org.eclipse.cdt.core.dom.ast.IASTNode#accept(org.eclipse.cdt.core.dom.ast.IASTVisitor.BaseVisitorAction) */ - public boolean accept( ASTVisitor visitor ) { + public boolean accept(ASTVisitor visitor) { return true; } @@ -584,11 +666,12 @@ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog { /** * @author jcamelon */ - public static class ScannerASTName extends ScannerASTNode implements - IASTName { + public class ASTMacroName extends ScannerASTNode implements IASTName { private final char[] name; + private IMacroBinding binding = null; + - public ScannerASTName(char[] n) { + public ASTMacroName(char[] n) { this.name = n; } @@ -598,15 +681,19 @@ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog { * @see org.eclipse.cdt.core.dom.ast.IASTName#resolveBinding() */ public IBinding resolveBinding() { + if( binding == null ) + { + binding = resolveBindingForMacro( name, getOffset() ); + } + return binding; + } + + + public IBinding[] resolvePrefix() { // TODO Auto-generated method stub return null; } - public IBinding[] resolvePrefix() { - // TODO Auto-generated method stub - return null; - } - /* * (non-Javadoc) * @@ -625,37 +712,44 @@ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog { return new String(name); } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.dom.ast.IASTName#isDeclaration() - */ - public boolean isDeclaration() { - if (getParent() instanceof IASTPreprocessorMacroDefinition && getPropertyInParent() == IASTPreprocessorMacroDefinition.MACRO_NAME ) - return true; - return false; - } + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.core.dom.ast.IASTName#isDeclaration() + */ + public boolean isDeclaration() { + if (getParent() instanceof IASTPreprocessorMacroDefinition + && getPropertyInParent() == IASTPreprocessorMacroDefinition.MACRO_NAME) + return true; + return false; + } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.dom.ast.IASTName#isReference() - */ - public boolean isReference() { - return !isDeclaration(); - } + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.core.dom.ast.IASTName#isReference() + */ + public boolean isReference() { + return !isDeclaration(); + } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.dom.ast.IASTName#getBinding() - */ - public IBinding getBinding() { - // TODO Auto-generated method stub - return null; - } + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.core.dom.ast.IASTName#getBinding() + */ + public IBinding getBinding() { + return binding; + } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.dom.ast.IASTName#setBinding(org.eclipse.cdt.core.dom.ast.IBinding) - */ - public void setBinding(IBinding binding) { - // TODO Auto-generated method stub - - } + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.core.dom.ast.IASTName#setBinding(org.eclipse.cdt.core.dom.ast.IBinding) + */ + public void setBinding(IBinding binding) { + //do nothing + } } /** @@ -665,13 +759,17 @@ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog { IASTPreprocessorObjectStyleMacroDefinition { private IASTName name; - /* (non-Javadoc) - * @see org.eclipse.cdt.core.dom.ast.IASTNameOwner#getRoleForName(org.eclipse.cdt.core.dom.ast.IASTName) - */ - public int getRoleForName(IASTName n) { - if( name == n ) return r_declaration; - return r_unclear; - } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.core.dom.ast.IASTNameOwner#getRoleForName(org.eclipse.cdt.core.dom.ast.IASTName) + */ + public int getRoleForName(IASTName n) { + if (name == n) + return r_declaration; + return r_unclear; + } private String expansion; @@ -714,7 +812,7 @@ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog { } - public static class Location implements IASTNodeLocation { + public abstract static class Location implements IASTNodeLocation { private final int nodeOffset; private final int nodeLength; @@ -781,7 +879,7 @@ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog { * @param length * @param offset * @param tu_filename - * + * */ public FileLocation(char[] tu_filename, int offset, int length) { super(offset, length); @@ -797,6 +895,10 @@ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog { return fileName; } + public IASTFileLocation asFileLocation() { + return this; + } + } protected static class _Context { @@ -811,17 +913,37 @@ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog { this.parent = parent; } - public final int context_directive_start; - - public final int context_directive_end; - + public int context_directive_start; + public int context_directive_end; public int context_ends; - - final _CompositeContext parent; + public _CompositeContext parent; public _CompositeContext getParent() { return parent; } + + public boolean contains(int offset) { + if (offset >= context_directive_start && offset <= context_ends) + return true; + return false; + } + + public boolean containsInDirective(int offset, int length) { + if (offset >= context_directive_start + && offset + length - 1<= context_directive_end) + return true; + return false; + } + + public boolean hasAncestor(_Context cc) { + _Context p = parent; + while (p != null) { + if (p == cc) + return true; + p = p.parent; + } + return false; + } } protected static class _CompositeContext extends _Context { @@ -833,23 +955,87 @@ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog { private static final int DEFAULT_SUBCONTEXT_ARRAY_SIZE = 8; - protected List subContexts = Collections.EMPTY_LIST; + private _Context[] subContexts = null; - public List getSubContexts() { + private static final _Context[] EMPTY_CONTEXT_ARRAY = new _Context[0]; + + public _Context[] getSubContexts() { + if (subContexts == null) + return EMPTY_CONTEXT_ARRAY; + trimSubContexts(); return subContexts; } + /** + * + */ + private void trimSubContexts() { + subContexts = (_Context[]) ArrayUtil.trim(_Context.class, + subContexts); + } + public void addSubContext(_Context c) { - if (subContexts == Collections.EMPTY_LIST) - subContexts = new ArrayList(DEFAULT_SUBCONTEXT_ARRAY_SIZE); - subContexts.add(c); + if (subContexts == null) + subContexts = new _Context[DEFAULT_SUBCONTEXT_ARRAY_SIZE]; + subContexts = (_Context[]) ArrayUtil.append(_Context.class, + subContexts, c); + } + + public void removeSubContext(_Context c) { + _Context[] sub = getSubContexts(); + for (int i = 0; i < sub.length; ++i) + if (sub[i] == c) { + sub[i] = null; + trimSubContexts(); + return; + } } /** * @return */ public boolean hasSubContexts() { - return subContexts != Collections.EMPTY_LIST; + if (subContexts == null) + return false; + for (int i = 0; i < subContexts.length; ++i) + if (subContexts[i] != null) + return true; + return false; + } + + public _Context findContextContainingOffset(int offset) { + if (!hasSubContexts()) { + if (contains(offset)) + return this; + return null; + } + _Context[] l = getSubContexts(); + for (int i = 0; i < l.length; ++i) { + _Context c = l[i]; + if (c.contains(offset)) { + if (c instanceof _CompositeContext) { + _Context trial = ((_CompositeContext) c) + .findContextContainingOffset(offset); + if (trial == null) + return c; + return trial; + } + return c; + } + } + if (contains(offset)) + return this; + return null; + } + + public int getNumberOfContexts() { + final _Context[] contextz = getSubContexts(); + int result = contextz.length; + for (int i = 0; i < contextz.length; ++i) + if (contextz[i] instanceof _CompositeContext) + result += ((_CompositeContext) contextz[i]) + .getNumberOfContexts(); + return result; } } @@ -862,6 +1048,7 @@ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog { super(parent, startOffset, endOffset); this.reader = reader; } + } protected static class _Inclusion extends _CompositeFileContext implements @@ -882,9 +1069,23 @@ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog { public _TranslationUnit(CodeReader reader) { super(null, 0, 0, reader); } + + IMacroDefinition [] builtins = new IMacroDefinition[2]; + + public void addBuiltinMacro(IMacroDefinition def) { + builtins = (IMacroDefinition[]) ArrayUtil.append( IMacroDefinition.class, builtins, def ); + } + + public IMacroDefinition [] getBuiltinMacroDefinitions() + { + builtins = (IMacroDefinition[]) ArrayUtil.removeNulls( IMacroDefinition.class, builtins ); + return builtins; + } + } - protected static class _MacroDefinition extends _Context { + protected static class _MacroDefinition extends _Context implements + IMacroDefinition { /** * @param parent @@ -902,10 +1103,28 @@ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog { } public final char[] name; - public final char[] expansion; - public final int nameOffset; + public IASTPreprocessorMacroDefinition astNode; + + private IMacroBinding bind; + + public char[] getName() { + return name; + } + + public char[] getExpansion() { + return expansion; + } + + public IMacroBinding getBinding() { + return bind; + } + + public void setBinding(IMacroBinding b) { + this.bind = b; + } + } protected static class _ObjectMacroDefinition extends _MacroDefinition @@ -962,16 +1181,55 @@ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog { } + protected class _MacroExpansion extends _CompositeContext { + public final IMacroDefinition definition; + private IASTName expansionName; + + public _MacroExpansion(_CompositeContext parent, int startOffset, + int endOffset, IMacroDefinition definition) { + super(parent, startOffset, endOffset); + this.definition = definition; + } + + public IASTName getName() + { + if( expansionName == null ) + { + expansionName = new ASTMacroName( definition.getName() ); + ((ScannerASTNode)expansionName).setParent( rootNode ); + ((ScannerASTNode)expansionName).setPropertyInParent( IASTTranslationUnit.EXPANSION_NAME ); + ((ScannerASTNode)expansionName).setOffsetAndLength( context_directive_start, context_directive_end - context_directive_start); + } + return expansionName; + } + } + + protected class _ObjectMacroExpansion extends _MacroExpansion { + + public _ObjectMacroExpansion(_CompositeContext parent, int startOffset, + int endOffset, IMacroDefinition definition) { + super(parent, startOffset, endOffset, definition); + } + + } + + protected class _FunctionMacroExpansion extends _MacroExpansion { + public final char[][] args; + + + public _FunctionMacroExpansion(_CompositeContext parent, + int startOffset, int endOffset, IMacroDefinition definition, + char[][] args) { + super(parent, startOffset, endOffset, definition); + this.args = args; + } + + } + protected _TranslationUnit tu; protected _CompositeContext currentContext; - /** - * - */ - public LocationMap() { - } - private static final IASTProblem[] EMPTY_PROBLEMS_ARRAY = new IASTProblem[0]; private static final IASTNodeLocation[] EMPTY_LOCATION_ARRAY = new IASTNodeLocation[0]; @@ -995,12 +1253,35 @@ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog { collectContexts(V_MACRODEFS, tu, contexts, 0); IASTPreprocessorMacroDefinition[] result = new IASTPreprocessorMacroDefinition[contexts.length]; - for (int i = 0; i < contexts.length; ++i) + for (int i = 0; i < contexts.length; ++i) { result[i] = createASTMacroDefinition((_MacroDefinition) contexts[i]); + result[i].setParent(rootNode); + result[i] + .setPropertyInParent(IASTTranslationUnit.PREPROCESSOR_STATEMENT); + } return result; } + public IMacroBinding resolveBindingForMacro(char[] name, int offset ) { + _Context search = findContextForOffset( offset ); + IMacroDefinition macroDefinition = null; + if (search instanceof _MacroDefinition) { + _MacroDefinition macroDef = (_MacroDefinition) search; + if( CharArrayUtils.equals( name, macroDef.name) && offset == macroDef.nameOffset ) + macroDefinition = macroDef; + } + else if (search instanceof _MacroExpansion ) { + _MacroExpansion expansion = (_MacroExpansion) search; + macroDefinition = expansion.definition; + } + if( macroDefinition == null ) + return null; + if( macroDefinition.getBinding() == null ) + macroDefinition.setBinding( new MacroBinding( name, rootNode.getScope(), macroDefinition ) ); + return macroDefinition.getBinding(); + } + /** * @param d * @return @@ -1024,7 +1305,7 @@ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog { r = f; } - IASTName name = new ScannerASTName(d.name); + IASTName name = new ASTMacroName(d.name); name.setPropertyInParent(IASTPreprocessorMacroDefinition.MACRO_NAME); name.setParent(r); ((ScannerASTNode) name).setOffsetAndLength(d.nameOffset, d.name.length); @@ -1032,6 +1313,7 @@ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog { r.setExpansion(new String(d.expansion)); ((ScannerASTNode) r).setOffsetAndLength(d.context_directive_start, d.context_directive_end - d.context_directive_start); + d.astNode = r; return r; } @@ -1047,8 +1329,12 @@ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog { _Context[] contexts = new _Context[size]; collectContexts(V_INCLUSIONS, tu, contexts, 0); IASTPreprocessorIncludeStatement[] result = new IASTPreprocessorIncludeStatement[size]; - for (int i = 0; i < size; ++i) + for (int i = 0; i < size; ++i) { result[i] = createASTInclusion(((_Inclusion) contexts[i])); + result[i].setParent(rootNode); + result[i] + .setPropertyInParent(IASTTranslationUnit.PREPROCESSOR_STATEMENT); + } return result; } @@ -1081,15 +1367,19 @@ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog { collectContexts(V_PREPROCESSOR, tu, contexts, 0); IASTPreprocessorStatement[] result = new IASTPreprocessorStatement[size]; for (int i = 0; i < size; ++i) { - result[i] = createPreprocessorStatement(contexts[i]); + result[i] = createPreprocessorStatement(contexts[i]); + result[i].setParent(rootNode); + result[i] + .setPropertyInParent(IASTTranslationUnit.PREPROCESSOR_STATEMENT); } return result; } - - private IASTPreprocessorStatement createPreprocessorStatement(_Context context) { - IASTPreprocessorStatement result = null; - if (context instanceof _Inclusion) + + private IASTPreprocessorStatement createPreprocessorStatement( + _Context context) { + IASTPreprocessorStatement result = null; + if (context instanceof _Inclusion) result = createASTInclusion(((_Inclusion) context)); else if (context instanceof _MacroDefinition) result = createASTMacroDefinition((_MacroDefinition) context); @@ -1111,8 +1401,8 @@ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog { result = createASTElif((_Elif) context); else if (context instanceof _Endif) result = createASTEndif((_Endif) context); - - return result; + + return result; } /** @@ -1206,7 +1496,7 @@ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog { * @return */ private IASTPreprocessorStatement createASTUndef(_Undef undef) { - IASTPreprocessorUndefStatement result = new ASTUndef(); + IASTPreprocessorUndefStatement result = new ASTUndef(undef.getName()); ((ASTNode) result).setOffsetAndLength(undef.context_directive_start, undef.context_directive_end - undef.context_directive_start); return result; @@ -1222,39 +1512,141 @@ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog { if (tu == null) return EMPTY_LOCATION_ARRAY; _Context c = findContextForOffset(offset); - if (c == null) + if (c.contains(offset + length)) { + if (c instanceof _CompositeContext) { + _Context[] subz = ((_CompositeContext) c).getSubContexts(); + boolean foundNested = false; + for (int i = 0; i < subz.length; ++i) { + _Context sub = subz[i]; + if (sub.context_directive_start > offset + && sub.context_ends <= offset + length) { + foundNested = true; + break; + } + } + if (!foundNested) + return createSoleLocationArray(c, offset, length); + } else + return createSoleLocationArray(c, offset, length); + } + // check to see if we spill over into other + _WeightedContext[] extraContexts = findAllContextsForLength(offset, + length); + if (extraContexts.length == 0) return EMPTY_LOCATION_ARRAY; - if (c.context_ends >= offset + length) - return createSoleLocation(c, offset, length); + if (extraContexts.length == 1) + return createSoleLocationArray(extraContexts[0].context, offset, + length); - return EMPTY_LOCATION_ARRAY; + return createMegaLocationArray(offset, length, extraContexts); } + private IASTNodeLocation[] createMegaLocationArray(int offset, int length, + _WeightedContext[] contexts) { + IASTNodeLocation[] result = new IASTNodeLocation[contexts.length]; + int currentOffset = offset; + for (int i = 0; i < contexts.length; ++i) { + final IASTNodeLocation location = createSoleLocation( + contexts[i].context, currentOffset, contexts[i].count); + result[i] = location; + currentOffset += contexts[i].count; + } + return (IASTNodeLocation[]) ArrayUtil.removeNulls( IASTNodeLocation.class, result ); + } + + protected static final class _WeightedContext { + public final _Context context; + + public final int count; + + public _WeightedContext(_Context c, int currentCount) { + context = c; + count = currentCount; + } + + } + + protected _WeightedContext[] findAllContextsForLength(int offset, int length) { + _WeightedContext[] result = new _WeightedContext[2]; + _Context cc = null; + int currentCount = 0; + for (int i = offset; i < offset + length; ++i) { + _Context r = tu.findContextContainingOffset(i); + if (cc == null) { + cc = r; + currentCount = 1; + } else if (cc == r) + ++currentCount; + else if (cc instanceof _MacroExpansion && r.hasAncestor(cc)) + ++currentCount; + else { + result = (_WeightedContext[]) ArrayUtil.append( + _WeightedContext.class, result, new _WeightedContext( + cc, currentCount)); + cc = r; + currentCount = 1; + } + } + result = (_WeightedContext[]) ArrayUtil.append(_WeightedContext.class, + result, new _WeightedContext(cc, currentCount)); + return (_WeightedContext[]) ArrayUtil.removeNulls( + _WeightedContext.class, result); + } + + protected IASTNodeLocation createSoleLocation(_Context c, int offset, + int length) { + if (c instanceof _IPreprocessorDirective) { + if (c.containsInDirective(offset, length)) { + _CompositeContext parent = c.parent; + while (!(parent instanceof _CompositeFileContext)) + parent = c.parent; + _CompositeFileContext fc = (_CompositeFileContext) parent; + return new FileLocation(fc.reader.filename, reconcileOffset(fc, + c, offset), length); + } + + } + if (c instanceof _CompositeFileContext) { + return new FileLocation( + ((_CompositeFileContext) c).reader.filename, + reconcileOffset(c, offset), length); + } + if (c instanceof _MacroExpansion) { + _MacroExpansion expansion = (_MacroExpansion) c; + IASTNodeLocation[] locations = createSoleLocationArray(c.parent, + c.context_directive_start, c.context_directive_end + - c.context_directive_start + 1); + IASTPreprocessorMacroDefinition definition = null; + _MacroDefinition d = (_MacroDefinition) expansion.definition; + if (d.astNode != null) + definition = d.astNode; + else { + IASTPreprocessorMacroDefinition astNode = createASTMacroDefinition(d); + d.astNode = astNode; + definition = astNode; + } + + return new MacroExpansionLocation(definition, locations, + reconcileOffset(c, offset), length); + } + return null; + } + + /** * @param c * @param offset * @param length * @return */ - protected IASTNodeLocation[] createSoleLocation(_Context c, int offset, - int length) { + protected IASTNodeLocation[] createSoleLocationArray(_Context c, + int offset, int length) { + IASTNodeLocation value = createSoleLocation(c, offset, length); + if (value == null) + return EMPTY_LOCATION_ARRAY; IASTNodeLocation[] result = new IASTNodeLocation[1]; - if (c instanceof _CompositeFileContext) { - result[0] = new FileLocation( - ((_CompositeFileContext) c).reader.filename, - reconcileOffset(c, offset), length); - return result; - } - if (c instanceof _IPreprocessorDirective) { - _CompositeContext parent = c.parent; - while (!(parent instanceof _CompositeFileContext)) - parent = c.parent; - _CompositeFileContext fc = (_CompositeFileContext) parent; - result[0] = new FileLocation(fc.reader.filename, reconcileOffset( - fc, c, offset), length); - return result; - } - return EMPTY_LOCATION_ARRAY; + result[0] = value; + return result; } /** @@ -1267,9 +1659,9 @@ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog { int offset) { int subtractOff = 0; if (c.parent == fc) { - List subs = fc.getSubContexts(); - for (int i = 0; i < subs.size(); ++i) { - _Context sample = (_Context) subs.get(i); + _Context[] subs = fc.getSubContexts(); + for (int i = 0; i < subs.length; ++i) { + _Context sample = subs[i]; if (sample == c) break; if (!(sample instanceof _CompositeContext)) @@ -1288,10 +1680,10 @@ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog { */ protected static int reconcileOffset(_Context c, int offset) { int subtractOff = 0; - if (c instanceof _CompositeContext) { - List subs = ((_CompositeContext) c).getSubContexts(); - for (int i = 0; i < subs.size(); ++i) { - _Context subC = (_Context) subs.get(i); + if (c instanceof _CompositeFileContext) { + _Context[] subs = ((_CompositeFileContext) c).getSubContexts(); + for (int i = 0; i < subs.length; ++i) { + _Context subC = subs[i]; if (subC.context_ends > offset) break; if (!(subC instanceof _CompositeContext)) @@ -1301,7 +1693,8 @@ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog { } } - return offset - c.context_directive_end - subtractOff; + final int result = offset - c.context_directive_end - subtractOff; + return ((result < 0) ? 0 : result); } /** @@ -1309,39 +1702,7 @@ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog { * @return */ protected _Context findContextForOffset(int offset) { - return findContextForOffset(tu, offset); - } - - protected static _Context findContextForOffset(_CompositeContext context, - int offset) { - if (!context.hasSubContexts()) { - if (context.context_ends >= offset) - return context; - return null; - } - List subContexts = context.getSubContexts(); - //check first - _Context bestContext = (_Context) subContexts.get(0); - if (bestContext.context_directive_end > offset) - return context; - - for (int i = 1; i < subContexts.size(); ++i) { - _Context nextContext = (_Context) subContexts.get(i); - if (nextContext.context_directive_end < offset) - bestContext = nextContext; - else if (nextContext.context_directive_start < offset - && nextContext.context_ends > offset) - bestContext = nextContext; - else - break; - } - - if (bestContext.context_ends < offset) - return context; - - if (bestContext instanceof _CompositeContext) - return findContextForOffset((_CompositeContext) bestContext, offset); - return bestContext; + return tu.findContextContainingOffset(offset); } /* @@ -1392,10 +1753,12 @@ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog { * @see org.eclipse.cdt.internal.core.parser.scanner2.IScannerPreprocessorLog#enterObjectStyleMacroExpansion(char[], * char[], int) */ - public void enterObjectStyleMacroExpansion(char[] name, char[] expansion, - int offset) { - // TODO Auto-generated method stub - + public void startObjectStyleMacroExpansion(IMacroDefinition macro, + int startOffset, int endOffset) { + _ObjectMacroExpansion context = new _ObjectMacroExpansion( + currentContext, startOffset, endOffset, macro); + currentContext.addSubContext(context); + currentContext = context; } /* @@ -1404,9 +1767,9 @@ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog { * @see org.eclipse.cdt.internal.core.parser.scanner2.IScannerPreprocessorLog#exitObjectStyleMacroExpansion(char[], * int) */ - public void exitObjectStyleMacroExpansion(char[] name, int offset) { - // TODO Auto-generated method stub - + public void endObjectStyleMacroExpansion(int offset) { + ((_ObjectMacroExpansion) currentContext).context_ends = offset; + currentContext = currentContext.getParent(); } /* @@ -1415,10 +1778,12 @@ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog { * @see org.eclipse.cdt.internal.core.parser.scanner2.IScannerPreprocessorLog#enterFunctionStyleExpansion(char[], * char[][], char[], int) */ - public void enterFunctionStyleExpansion(char[] name, char[][] parameters, - char[] expansion, int offset) { - // TODO Auto-generated method stub - + public void startFunctionStyleExpansion(IMacroDefinition macro, + char[][] parameters, int startOffset, int endOffset) { + _FunctionMacroExpansion context = new _FunctionMacroExpansion( + currentContext, startOffset, endOffset, macro, parameters); + currentContext.addSubContext(context); + currentContext = context; } /* @@ -1427,9 +1792,9 @@ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog { * @see org.eclipse.cdt.internal.core.parser.scanner2.IScannerPreprocessorLog#exitFunctionStyleExpansion(char[], * int) */ - public void exitFunctionStyleExpansion(char[] name, int offset) { - // TODO Auto-generated method stub - + public void endFunctionStyleExpansion(int offset) { + ((_FunctionMacroExpansion) currentContext).context_ends = offset; + currentContext = currentContext.getParent(); } /* @@ -1438,10 +1803,13 @@ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog { * @see org.eclipse.cdt.internal.core.parser.scanner2.IScannerPreprocessorLog#defineObjectStyleMacro(org.eclipse.cdt.internal.core.parser.scanner2.ObjectStyleMacro, * int, int, int, int) */ - public void defineObjectStyleMacro(ObjectStyleMacro m, int startOffset, - int nameOffset, int nameEndOffset, int endOffset) { - currentContext.addSubContext(new _ObjectMacroDefinition(currentContext, - startOffset, endOffset, m.name, nameOffset, m.expansion)); + public IMacroDefinition defineObjectStyleMacro(ObjectStyleMacro m, + int startOffset, int nameOffset, int nameEndOffset, int endOffset) { + final _ObjectMacroDefinition objectMacroDefinition = new _ObjectMacroDefinition( + currentContext, startOffset, endOffset, m.name, nameOffset, + m.expansion); + currentContext.addSubContext(objectMacroDefinition); + return objectMacroDefinition; } /* @@ -1450,11 +1818,13 @@ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog { * @see org.eclipse.cdt.internal.core.parser.scanner2.IScannerPreprocessorLog#defineFunctionStyleMacro(org.eclipse.cdt.internal.core.parser.scanner2.FunctionStyleMacro, * int, int, int, int) */ - public void defineFunctionStyleMacro(FunctionStyleMacro m, int startOffset, - int nameOffset, int nameEndOffset, int endOffset) { - currentContext.addSubContext(new _FunctionMacroDefinition( + public IMacroDefinition defineFunctionStyleMacro(FunctionStyleMacro m, + int startOffset, int nameOffset, int nameEndOffset, int endOffset) { + final _FunctionMacroDefinition functionMacroDefinition = new _FunctionMacroDefinition( currentContext, startOffset, endOffset, m.name, nameOffset, - m.expansion, removeNullArguments(m.arglist))); + m.expansion, removeNullArguments(m.arglist)); + currentContext.addSubContext(functionMacroDefinition); + return functionMacroDefinition; } /** @@ -1528,9 +1898,10 @@ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog { * @see org.eclipse.cdt.internal.core.parser.scanner2.IScannerPreprocessorLog#encounterPoundUndef(int, * int) */ - public void encounterPoundUndef(int startOffset, int endOffset) { + public void encounterPoundUndef(int startOffset, int endOffset, + char[] symbol, int nameOffset, IMacroDefinition macroDefinition) { currentContext.addSubContext(new _Undef(currentContext, startOffset, - endOffset)); + endOffset, symbol, nameOffset, macroDefinition)); } /* @@ -1581,7 +1952,7 @@ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog { * @see org.eclipse.cdt.internal.core.parser.scanner2.ILocationResolver#cleanup() */ public void cleanup() { - // TODO Auto-generated method stub + tu = null; } /* @@ -1596,8 +1967,11 @@ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog { _Context[] contexts = new _Context[size]; LocationMap.collectContexts(V_PROBLEMS, tu, contexts, 0); IASTProblem[] result = new IASTProblem[size]; - for (int i = 0; i < size; ++i) + for (int i = 0; i < size; ++i) { result[i] = ((_Problem) contexts[i]).problem; + result[i].setParent(rootNode); + result[i].setPropertyInParent(IASTTranslationUnit.SCANNER_PROBLEM); + } return result; } @@ -1625,7 +1999,15 @@ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog { protected static final int V_PREPROCESSOR = 5; + protected static final int V_MACRODEFSUNDEFS = 6; + private static final char[] EMPTY_CHAR_ARRAY = "".toCharArray(); //$NON-NLS-1$ + private static final IASTName[] EMPTY_NAME_ARRAY = new IASTName[0]; + + + protected IASTTranslationUnit rootNode; + + protected static int collectContexts(int key, _Context source, _Context[] result, int s) { @@ -1666,12 +2048,18 @@ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog { ++count; } break; + case V_MACRODEFSUNDEFS: + if (source instanceof _MacroDefinition || source instanceof _Undef) { + if (result != null) + result[startAt++] = source; + ++count; + } + break; } if (source instanceof _CompositeContext) { - List l = ((_CompositeContext) source).getSubContexts(); - for (int i = 0; i < l.size(); ++i) { - int value = collectContexts(key, (_Context) l.get(i), result, - startAt); + _Context[] l = ((_CompositeContext) source).getSubContexts(); + for (int i = 0; i < l.length; ++i) { + int value = collectContexts(key, l[i], result, startAt); count += value; startAt += value; } @@ -1714,7 +2102,7 @@ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog { case 0: return EMPTY_CHAR_ARRAY; default: - //TODO + // TODO return EMPTY_CHAR_ARRAY; } } @@ -1747,89 +2135,259 @@ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog { currentContext.addSubContext(new _Ifndef(currentContext, startOffset, endOffset, taken)); } - + private _Context findInclusion(_CompositeContext context, String path) { - _Context foundContext = null; - List contexts = context.getSubContexts(); - - for (int i=0; foundContext == null && i context.context_directive_end) { - globalOffset += context.context_ends - context.context_directive_end; - } - - // check if the _Context is the selection - if (globalOffset == context.context_directive_start && - length == context.context_directive_end - context.context_directive_start) { - result = createPreprocessorStatement(context); - } - - // check if a sub node of the macro is the selection // TODO determine how this can be kept in sync with logic in getAllPreprocessorStatements (i.e. 1:1 mapping) - if (context instanceof _MacroDefinition) { - if (globalOffset == ((_MacroDefinition)context).nameOffset - && length == ((_MacroDefinition)context).name.length) - result = createASTMacroDefinition((_MacroDefinition)context).getName(); - } + private ASTPreprocessorSelectionResult getPreprocessorNode( + int globalOffset, int length, _Context startContext) + throws InvalidPreprocessorNodeException { + IASTNode result = null; + if (!(startContext instanceof _CompositeContext)) + throw new InvalidPreprocessorNodeException(NOT_VALID_MACRO, + globalOffset); + _Context[] contexts = ((_CompositeContext) startContext) + .getSubContexts(); - // stop searching the _Contexts if they've gone past the selection - if (globalOffset < context.context_directive_end) - break; - } - } - - return new ASTPreprocessorSelectionResult(result, globalOffset); + // check if a macro in the location map is the selection + for (int i = 0; result == null && i < contexts.length; i++) { + _Context context = contexts[i]; + + // if offset is past the _Context then increment globalOffset + if (globalOffset > context.context_directive_end) { + globalOffset += context.context_ends + - context.context_directive_end; + } + + // check if the _Context is the selection + if (globalOffset == context.context_directive_start + && length == context.context_directive_end + - context.context_directive_start) { + result = createPreprocessorStatement(context); + } + + // check if a sub node of the macro is the selection // TODO + // determine how this can be kept in sync with logic in + // getAllPreprocessorStatements (i.e. 1:1 mapping) + if (context instanceof _MacroDefinition) { + if (globalOffset == ((_MacroDefinition) context).nameOffset + && length == ((_MacroDefinition) context).name.length) + result = createASTMacroDefinition( + (_MacroDefinition) context).getName(); + } + + // stop searching the _Contexts if they've gone past the selection + if (globalOffset < context.context_directive_end) + break; + + } + + return new ASTPreprocessorSelectionResult(result, globalOffset); } - - /* (non-Javadoc) - * @see org.eclipse.cdt.internal.core.parser.scanner2.ILocationResolver#getPreprocessorNode(int, int) - */ - public ASTPreprocessorSelectionResult getPreprocessorNode(String path, int offset, int length) throws InvalidPreprocessorNodeException { - ASTPreprocessorSelectionResult result = null; - - int globalOffset = 0; - _Context foundContext = tu; - - // is the selection in TU or an #include else it's an exception - if (CharArrayUtils.equals(tu.reader.filename, path.toCharArray())) { - globalOffset = offset; // in TU so start at the real offset - } else { - foundContext = findInclusion(tu, path); - - if (foundContext == null) { - throw new InvalidPreprocessorNodeException(TU_INCLUDE_NOT_FOUND, globalOffset); - } else if (foundContext instanceof _Inclusion){ - globalOffset = foundContext.context_directive_end + offset; // start at #include's directive_end + real offset - } - } - - result = getPreprocessorNode(globalOffset, length, foundContext); - - return result; - } + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.internal.core.parser.scanner2.ILocationResolver#getPreprocessorNode(int, + * int) + */ + public ASTPreprocessorSelectionResult getPreprocessorNode(String path, + int offset, int length) throws InvalidPreprocessorNodeException { + ASTPreprocessorSelectionResult result = null; + + int globalOffset = 0; + _Context foundContext = tu; + + // is the selection in TU or an #include else it's an exception + if (CharArrayUtils.equals(tu.reader.filename, path.toCharArray())) { + globalOffset = offset; // in TU so start at the real offset + } else { + foundContext = findInclusion(tu, path); + + if (foundContext == null) { + throw new InvalidPreprocessorNodeException( + TU_INCLUDE_NOT_FOUND, globalOffset); + } else if (foundContext instanceof _Inclusion) { + globalOffset = foundContext.context_directive_end + offset; // start + // at + // #include's + // directive_end + // + + // real + // offset + } + } + + result = getPreprocessorNode(globalOffset, length, foundContext); + + return result; + } + + public void setRootNode(IASTTranslationUnit root) { + this.rootNode = root; + } + + public IASTFileLocation flattenLocations(IASTNodeLocation[] nodeLocations) { + if (nodeLocations == null) + return null; + if (nodeLocations.length == 0) + return null; + if (nodeLocations.length == 1 + && nodeLocations[0] instanceof IASTFileLocation) + return (IASTFileLocation) nodeLocations[0]; + IASTFileLocation[] result = new IASTFileLocation[nodeLocations.length]; + for (int i = 0; i < nodeLocations.length; ++i) { + if (nodeLocations[i] != null) + result[i] = nodeLocations[i].asFileLocation(); + } + return flatten(result); + } + + private IASTFileLocation flatten(IASTFileLocation[] result) { + String filename = null; + int offset = 0, length = 0; + for (int i = 0; i < result.length; ++i) { + if (i == 0) { + offset = result[0].getNodeOffset(); + filename = result[0].getFileName(); + length = result[0].getNodeLength(); + } else { + if (result[i] != null + && result[i].getNodeOffset() != (offset + length)) + return null; + if (result[i] != null) + length += result[i].getNodeLength(); + } + } + return new FileLocation(filename.toCharArray(), offset, length); + } + + public IASTName[] getReferences(IMacroBinding binding) { + if( binding instanceof MacroBinding ) + { + IMacroDefinition d = ((MacroBinding)binding).getDefinition(); + _Context [] r = findReferences( tu, d ); + return createNameArray( r ); + } + return EMPTY_NAME_ARRAY; + } + + private IASTName[] createNameArray(_Context[] r) { + IASTName [] result = new IASTName[ r.length ]; + for( int i = 0; i < r.length; ++i ) + { + IASTName n = null; + if( r[i] instanceof _MacroExpansion ) + { + n = ((_MacroExpansion)r[i]).getName(); + } + else if( r[i] instanceof _Undef ) + { + n = ((_Undef)r[i]).getName(); + createASTUndef( (_Undef) r[i] ); + } + result[i] = n; + } + return result; + } + + protected _Context [] findReferences(_CompositeContext c, IMacroDefinition d) { + _Context [] results = new _Context[2]; + _Context [] subs = c.getSubContexts(); + for( int i = 0; i < subs.length; ++i ) + { + if( subs[i] instanceof _MacroExpansion ) + { + if( ((_MacroExpansion)subs[i]).definition == d ) + results = (_Context[]) ArrayUtil.append( _Context.class, results, subs[i] ); + } + else if( subs[i] instanceof _Undef ) + { + if( ((_Undef)subs[i]).macroDefn == d ) + results = (_Context[]) ArrayUtil.append( _Context.class, results, subs[i] ); + } + + if( subs[i] instanceof _CompositeContext ) + { + _Context [] s = findReferences( (_CompositeContext) subs[i], d ); + if( s.length > 0 ) + results = (_Context[]) ArrayUtil.addAll( _Context.class, results, s ); + } + } + return (_Context[]) ArrayUtil.removeNulls( _Context.class, results ); + } + + public IASTName[] getDeclarations(IMacroBinding binding) { + if( binding instanceof MacroBinding ) + { + IMacroDefinition d = ((MacroBinding)binding).getDefinition(); + if( d instanceof _MacroDefinition ) + return createNameArray( ((_MacroDefinition)d) ); + } + return EMPTY_NAME_ARRAY; + } + + private IASTName[] createNameArray(_MacroDefinition definition) { + IASTName [] result = new IASTName[1]; + if( definition.astNode == null ) + { + IASTPreprocessorMacroDefinition astNode = createASTMacroDefinition(definition); + definition.astNode = astNode; + } + result[0] = definition.astNode.getName(); + return result; + } + + public IASTName[] getMacroExpansions() { + // TODO Auto-generated method stub + return null; + } + + public IDependencyTree getDependencyTree() { + // TODO Auto-generated method stub + return null; + } + + public IMacroDefinition registerBuiltinObjectStyleMacro(ObjectStyleMacro macro) { + IMacroDefinition result = new _ObjectMacroDefinition( tu, -1, -1, macro.name, -1, macro.expansion ); + tu.addBuiltinMacro( result ); + return result; + } + + public IMacroDefinition registerBuiltinFunctionStyleMacro(FunctionStyleMacro macro) { + IMacroDefinition result = new _FunctionMacroDefinition( tu, -1, -1, macro.name, -1, macro.expansion, macro.arglist ); + tu.addBuiltinMacro( result ); + return result; + } + + public IMacroDefinition registerBuiltinDynamicFunctionStyleMacro(DynamicFunctionStyleMacro macro) { + IMacroDefinition result = new _MacroDefinition( tu, -1, -1, macro.name, -1, macro.expansion ); + tu.addBuiltinMacro( result ); + return result; + } + + public IMacroDefinition registerBuiltinDynamicStyleMacro(DynamicStyleMacro macro) { + IMacroDefinition result = new _MacroDefinition( tu, -1, -1, macro.name, -1, macro.execute() ); + tu.addBuiltinMacro( result ); + return result; + } } \ No newline at end of file diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/MacroBinding.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/MacroBinding.java new file mode 100644 index 00000000000..b55a4aa155c --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/MacroBinding.java @@ -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; + } + + +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/ObjectStyleMacro.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/ObjectStyleMacro.java index 74873dda98f..589c8bf453b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/ObjectStyleMacro.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/ObjectStyleMacro.java @@ -11,6 +11,7 @@ package org.eclipse.cdt.internal.core.parser.scanner2; import org.eclipse.cdt.core.parser.IMacro; +import org.eclipse.cdt.internal.core.parser.scanner2.IScannerPreprocessorLog.IMacroDefinition; /** * @author Doug Schaefer @@ -19,6 +20,7 @@ public class ObjectStyleMacro implements IMacro{ public char[] name; public char[] expansion; + public IMacroDefinition attachment; public ObjectStyleMacro(char[] name, char[] expansion) { this.name = name; @@ -32,4 +34,8 @@ public class ObjectStyleMacro implements IMacro{ public char[] getName(){ return name; } + + public String toString() { + return new String( name ); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/Scanner2.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/Scanner2.java index 0beaf15d25f..6adf368a311 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/Scanner2.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/Scanner2.java @@ -34,272 +34,302 @@ import org.eclipse.cdt.internal.core.parser.token.SimpleToken; */ public class Scanner2 extends BaseScanner { - /** - * @param reader - * @param info - * @param requestor - * @param parserMode - * @param language - * @param log - * @param workingCopies - * @param configuration - */ - public Scanner2(CodeReader reader, IScannerInfo info, - ISourceElementRequestor requestor, ParserMode parserMode, - ParserLanguage language, IParserLogService log, List workingCopies, - IScannerExtensionConfiguration configuration) { - super(reader, info, parserMode, language, log, configuration); - this.requestor = requestor; - this.callbackManager = new ScannerCallbackManager(requestor); - this.expressionEvaluator = new ExpressionEvaluator(callbackManager, spf); - this.workingCopies = workingCopies; - postConstructorSetup(reader, info); - } + /** + * @param reader + * @param info + * @param requestor + * @param parserMode + * @param language + * @param log + * @param workingCopies + * @param configuration + */ + public Scanner2(CodeReader reader, IScannerInfo info, + ISourceElementRequestor requestor, ParserMode parserMode, + ParserLanguage language, IParserLogService log, List workingCopies, + IScannerExtensionConfiguration configuration) { + super(reader, info, parserMode, language, log, configuration); + this.requestor = requestor; + this.callbackManager = new ScannerCallbackManager(requestor); + this.expressionEvaluator = new ExpressionEvaluator(callbackManager, spf); + this.workingCopies = workingCopies; + postConstructorSetup(reader, info); + } - /* - * (non-Javadoc) - * - * @see org.eclipse.cdt.internal.core.parser.scanner.IScannerData#getASTFactory() - */ - protected IASTFactory getASTFactory() { - if (astFactory == null) - astFactory = ParserFactory.createASTFactory(parserMode, language); - return astFactory; - } + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.internal.core.parser.scanner.IScannerData#getASTFactory() + */ + protected IASTFactory getASTFactory() { + if (astFactory == null) + astFactory = ParserFactory.createASTFactory(parserMode, language); + return astFactory; + } - protected IASTFactory astFactory; + protected IASTFactory astFactory; - // callbacks - protected ScannerCallbackManager callbackManager; + // callbacks + protected ScannerCallbackManager callbackManager; - protected ISourceElementRequestor requestor; + protected ISourceElementRequestor requestor; - protected List workingCopies; + protected List workingCopies; - public final void setASTFactory(IASTFactory f) { - astFactory = f; - } + public final void setASTFactory(IASTFactory f) { + astFactory = f; + } - /* - * (non-Javadoc) - * - * @see org.eclipse.cdt.internal.core.parser.scanner2.BaseScanner#createInclusionConstruct(char[], - * char[], boolean, int, int, int, int, int, int, int, boolean) - */ - protected Object createInclusionConstruct(char[] fileName, - char[] filenamePath, boolean local, int startOffset, - int startingLineNumber, int nameOffset, int nameEndOffset, - int nameLine, int endOffset, int endLine, boolean isForced) { - return getASTFactory().createInclusion(fileName, filenamePath, local, - startOffset, startingLineNumber, nameOffset, nameEndOffset, - nameLine, endOffset, endLine, getCurrentFilename(), isForced); - } + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.internal.core.parser.scanner2.BaseScanner#createInclusionConstruct(char[], + * char[], boolean, int, int, int, int, int, int, int, boolean) + */ + protected Object createInclusionConstruct(char[] fileName, + char[] filenamePath, boolean local, int startOffset, + int startingLineNumber, int nameOffset, int nameEndOffset, + int nameLine, int endOffset, int endLine, boolean isForced) { + return getASTFactory().createInclusion(fileName, filenamePath, local, + startOffset, startingLineNumber, nameOffset, nameEndOffset, + nameLine, endOffset, endLine, getCurrentFilename(), isForced); + } - /* - * (non-Javadoc) - * - * @see org.eclipse.cdt.internal.core.parser.scanner2.BaseScanner#processMacro(char[], - * int, int, int, int, int, int, int) - */ - protected void processMacro(char[] name, int startingOffset, - int startingLineNumber, int idstart, int idend, int nameLine, - int textEnd, int endingLine, org.eclipse.cdt.core.parser.IMacro macro) { - callbackManager.pushCallback(getASTFactory().createMacro(name, - startingOffset, startingLineNumber, idstart, idend, nameLine, - textEnd, endingLine, getCurrentFilename(), !isInitialized)); - } + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.internal.core.parser.scanner2.BaseScanner#processMacro(char[], + * int, int, int, int, int, int, int) + */ + protected void processMacro(char[] name, int startingOffset, + int startingLineNumber, int idstart, int idend, int nameLine, + int textEnd, int endingLine, + org.eclipse.cdt.core.parser.IMacro macro) { + callbackManager.pushCallback(getASTFactory().createMacro(name, + startingOffset, startingLineNumber, idstart, idend, nameLine, + textEnd, endingLine, getCurrentFilename(), !isInitialized)); + } - /* - * (non-Javadoc) - * - * @see org.eclipse.cdt.internal.core.parser.scanner2.BaseScanner#pushContext(char[], - * java.lang.Object) - */ - protected void pushContext(char[] buffer, Object data) { - super.pushContext(buffer, data); - if (data instanceof InclusionData) { - callbackManager.pushCallback(data); - if (log.isTracing()) { - StringBuffer b = new StringBuffer("Entering inclusion "); //$NON-NLS-1$ - b.append(((InclusionData) data).reader.filename); - log.traceLog(b.toString()); - } - } - } + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.internal.core.parser.scanner2.BaseScanner#pushContext(char[], + * java.lang.Object) + */ + protected void pushContext(char[] buffer, Object data) { + super.pushContext(buffer, data); + if (data instanceof InclusionData) { + callbackManager.pushCallback(data); + if (log.isTracing()) { + StringBuffer b = new StringBuffer("Entering inclusion "); //$NON-NLS-1$ + b.append(((InclusionData) data).reader.filename); + log.traceLog(b.toString()); + } + } + } - /* - * (non-Javadoc) - * - * @see org.eclipse.cdt.internal.core.parser.scanner2.BaseScanner#beforeSecondFetchToken() - */ - protected void beforeSecondFetchToken() { - if (callbackManager.hasCallbacks()) - callbackManager.popCallbacks(); - } + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.internal.core.parser.scanner2.BaseScanner#beforeSecondFetchToken() + */ + protected void beforeSecondFetchToken() { + if (callbackManager.hasCallbacks()) + callbackManager.popCallbacks(); + } - /* - * (non-Javadoc) - * - * @see org.eclipse.cdt.internal.core.parser.scanner2.BaseScanner#quickParsePushPopInclusion(java.lang.Object) - */ - protected void quickParsePushPopInclusion(Object inclusion) { - callbackManager.pushCallback(new InclusionData(null, inclusion)); - callbackManager.pushCallback(inclusion); - } + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.internal.core.parser.scanner2.BaseScanner#quickParsePushPopInclusion(java.lang.Object) + */ + protected void quickParsePushPopInclusion(Object inclusion) { + callbackManager.pushCallback(new InclusionData(null, inclusion)); + callbackManager.pushCallback(inclusion); + } - /* - * (non-Javadoc) - * - * @see org.eclipse.cdt.internal.core.parser.scanner2.BaseScanner#createReaderDuple(java.lang.String) - */ - protected CodeReader createReaderDuple(String finalPath) { - return ScannerUtility.createReaderDuple(finalPath, requestor, - getWorkingCopies()); - } + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.internal.core.parser.scanner2.BaseScanner#createReaderDuple(java.lang.String) + */ + protected CodeReader createReaderDuple(String finalPath) { + return ScannerUtility.createReaderDuple(finalPath, requestor, + getWorkingCopies()); + } - /* - * (non-Javadoc) - * - * @see org.eclipse.cdt.core.parser.IScanner#getLocationResolver() - */ - public ILocationResolver getLocationResolver() { - return null; - } + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.core.parser.IScanner#getLocationResolver() + */ + public ILocationResolver getLocationResolver() { + return null; + } - /* - * (non-Javadoc) - * - * @see org.eclipse.cdt.internal.core.parser.scanner.IScannerData#getWorkingCopies() - */ - protected Iterator getWorkingCopies() { - if (workingCopies == null) - return EmptyIterator.EMPTY_ITERATOR; - return workingCopies.iterator(); - } + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.internal.core.parser.scanner.IScannerData#getWorkingCopies() + */ + protected Iterator getWorkingCopies() { + if (workingCopies == null) + return EmptyIterator.EMPTY_ITERATOR; + return workingCopies.iterator(); + } - /** - * @return - */ - 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, data.startOffset, - data.endOffset - data.startOffset + 1, getCurrentFilename(), - getLineNumber(bufferPos[mostRelevant] + 1)); - } - return new SimpleToken(signal, bufferPos[bufferStackPos] + 1, - getCurrentFilename(), getLineNumber(bufferPos[bufferStackPos] + 1)); - } + /** + * @return + */ + 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, data.startOffset, + data.endOffset - data.startOffset + 1, + getCurrentFilename(), + getLineNumber(bufferPos[mostRelevant] + 1)); + } + return new SimpleToken(signal, bufferPos[bufferStackPos] + 1, + getCurrentFilename(), + getLineNumber(bufferPos[bufferStackPos] + 1)); + } - 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, data.startOffset, - data.endOffset - data.startOffset + 1, getCurrentFilename(), - getLineNumber(bufferPos[mostRelevant] + 1)); - } - IToken i = new ImagedToken(signal, buffer, bufferPos[bufferStackPos] + 1, - getCurrentFilename(), getLineNumber(bufferPos[bufferStackPos] + 1)); - if (buffer != null && buffer.length == 0 && signal != IToken.tSTRING - && signal != IToken.tLSTRING) - bufferPos[bufferStackPos] += 1; // TODO - remove this hack at some - // point + 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, data.startOffset, + data.endOffset - data.startOffset + 1, + getCurrentFilename(), + getLineNumber(bufferPos[mostRelevant] + 1)); + } + IToken i = new ImagedToken(signal, buffer, + bufferPos[bufferStackPos] + 1, getCurrentFilename(), + getLineNumber(bufferPos[bufferStackPos] + 1)); + if (buffer != null && buffer.length == 0 && signal != IToken.tSTRING + && 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) - * - * @see org.eclipse.cdt.internal.core.parser.scanner2.BaseScanner#handleProblem(int, - * int, char[]) - */ - protected void handleProblem(int id, int offset, char[] arg) { - if (parserMode == ParserMode.COMPLETION_PARSE) - return; - IProblem p = spf.createProblem(id, offset, bufferPos[bufferStackPos], - getLineNumber(bufferPos[bufferStackPos]), getCurrentFilename(), - arg != null ? arg : EMPTY_CHAR_ARRAY, false, true); - callbackManager.pushCallback(p); - } + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.internal.core.parser.scanner2.BaseScanner#handleProblem(int, + * int, char[]) + */ + protected void handleProblem(int id, int offset, char[] arg) { + if (parserMode == ParserMode.COMPLETION_PARSE) + return; + IProblem p = spf.createProblem(id, offset, bufferPos[bufferStackPos], + getLineNumber(bufferPos[bufferStackPos]), getCurrentFilename(), + arg != null ? arg : EMPTY_CHAR_ARRAY, false, true); + callbackManager.pushCallback(p); + } - /* - * (non-Javadoc) - * - * @see org.eclipse.cdt.internal.core.parser.scanner2.BaseScanner#popContext() - */ - protected Object popContext() { - if (bufferData[bufferStackPos] instanceof InclusionData) { - if (log.isTracing()) { - StringBuffer buffer = new StringBuffer("Exiting inclusion "); //$NON-NLS-1$ - buffer - .append(((InclusionData) bufferData[bufferStackPos]).reader.filename); - log.traceLog(buffer.toString()); - } - callbackManager - .pushCallback(((InclusionData) bufferData[bufferStackPos]).inclusion); - } - return super.popContext(); - } + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.internal.core.parser.scanner2.BaseScanner#popContext() + */ + protected Object popContext() { + if (bufferData[bufferStackPos] instanceof InclusionData) { + if (log.isTracing()) { + StringBuffer buffer = new StringBuffer("Exiting inclusion "); //$NON-NLS-1$ + buffer + .append(((InclusionData) bufferData[bufferStackPos]).reader.filename); + log.traceLog(buffer.toString()); + } + callbackManager + .pushCallback(((InclusionData) bufferData[bufferStackPos]).inclusion); + } + return super.popContext(); + } - /* (non-Javadoc) - * @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#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) - */ - protected void processIf(int startPos, int endPos, boolean taken) { - } + /* + * (non-Javadoc) + * + * @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) - */ - protected void processElsif(int startPos, int endPos, boolean taken) { - } + /* + * (non-Javadoc) + * + * @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) - */ - protected void processElse(int startPos, int endPos, boolean taken) { - } + /* + * (non-Javadoc) + * + * @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) - */ - protected void processUndef(int pos, int endPos) { - } + /* + * (non-Javadoc) + * + * @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) - */ - protected void processError(int startPos, int endPos) { - } + /* + * (non-Javadoc) + * + * @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) - */ - protected void processEndif(int pos, int i) { - } + /* + * (non-Javadoc) + * + * @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) - */ - protected void processPragma(int startPos, int endPos) { - } + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.internal.core.parser.scanner2.BaseScanner#processPragma(int, + * int) + */ + protected void processPragma(int startPos, int endPos) { + } } \ No newline at end of file diff --git a/core/org.eclipse.cdt.ui.tests/src/org/eclipse/cdt/ui/tests/DOMAST/CPopulateASTViewAction.java b/core/org.eclipse.cdt.ui.tests/src/org/eclipse/cdt/ui/tests/DOMAST/CPopulateASTViewAction.java index efd0765eb39..268e885f207 100644 --- a/core/org.eclipse.cdt.ui.tests/src/org/eclipse/cdt/ui/tests/DOMAST/CPopulateASTViewAction.java +++ b/core/org.eclipse.cdt.ui.tests/src/org/eclipse/cdt/ui/tests/DOMAST/CPopulateASTViewAction.java @@ -72,9 +72,7 @@ public class CPopulateASTViewAction extends CASTVisitor implements IPopulateDOMA if (node == null) return PROCESS_CONTINUE; IASTNodeLocation[] nodeLocations = node.getNodeLocations(); - if (!(nodeLocations.length > 0 && - nodeLocations[0].getNodeOffset() >= 0 && - nodeLocations[0].getNodeLength() > 0)) + if (!(nodeLocations.length > 0 ) ) return PROCESS_CONTINUE; DOMASTNodeParent parent = root.findTreeParentForNode(node); diff --git a/core/org.eclipse.cdt.ui.tests/src/org/eclipse/cdt/ui/tests/DOMAST/DOMASTNodeLeaf.java b/core/org.eclipse.cdt.ui.tests/src/org/eclipse/cdt/ui/tests/DOMAST/DOMASTNodeLeaf.java index 62d7f5f2fe2..6b20f4aec50 100644 --- a/core/org.eclipse.cdt.ui.tests/src/org/eclipse/cdt/ui/tests/DOMAST/DOMASTNodeLeaf.java +++ b/core/org.eclipse.cdt.ui.tests/src/org/eclipse/cdt/ui/tests/DOMAST/DOMASTNodeLeaf.java @@ -279,21 +279,30 @@ public class DOMASTNodeLeaf implements IAdaptable { IASTNodeLocation [] location = node.getNodeLocations(); if( location.length > 0 && location[0] instanceof IASTFileLocation ) 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() { IASTNodeLocation [] location = node.getNodeLocations(); - if( location.length == 1 ) + if( location.length == 1 && location[0] instanceof IASTFileLocation ) 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() { IASTNodeLocation [] location = node.getNodeLocations(); - if( location.length == 1 ) + if( location.length == 1 && location[0] instanceof IASTFileLocation ) 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) { @@ -447,9 +456,13 @@ public class DOMASTNodeLeaf implements IAdaptable { } else if (obj instanceof ASTNodeProperty) { buffer.append(((ASTNodeProperty)obj).getName()); } else if (obj instanceof IASTName) { - buffer.append( trimObjectToString(((IASTName)obj).toString()) ); - buffer.append(COLON_SEPARATOR); - buffer.append( getType(((IASTName)obj).resolveBinding()) ); + final String toString = ((IASTName)obj).toString(); + if( toString != null ) + { + buffer.append( trimObjectToString(toString) ); + buffer.append(COLON_SEPARATOR); + buffer.append( getType(((IASTName)obj).resolveBinding()) ); + } } else if (obj instanceof IType) { buffer.append(getType(obj)); } else if (obj instanceof IBinding) { diff --git a/core/org.eclipse.cdt.ui.tests/src/org/eclipse/cdt/ui/tests/DOMAST/DOMQuery.java b/core/org.eclipse.cdt.ui.tests/src/org/eclipse/cdt/ui/tests/DOMAST/DOMQuery.java index 604afb7377f..794e96c32d4 100644 --- a/core/org.eclipse.cdt.ui.tests/src/org/eclipse/cdt/ui/tests/DOMAST/DOMQuery.java +++ b/core/org.eclipse.cdt.ui.tests/src/org/eclipse/cdt/ui/tests/DOMAST/DOMQuery.java @@ -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.IASTName; 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.model.ICElement; import org.eclipse.cdt.core.search.BasicSearchMatch; 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.CSearchResult; 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.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; @@ -71,26 +68,16 @@ public class DOMQuery extends CSearchQuery implements ISearchQuery { for (int i=0; i 0 && location[0] instanceof IASTFileLocation ) - 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; - + IASTFileLocation location = nodes[i].getTranslationUnit().flattenLocationsToFile( nodes[i].getNodeLocations() ); + fileName = location.getFileName(); path = new Path(fileName); - file = ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(path); - - if (nodes[i].getNodeLocations().length > 0) { // fix for 84223 - 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 ) ); - } + start = location.getNodeOffset(); + end = location.getNodeOffset() + location.getNodeLength(); + collector.acceptMatch( createMatch(path, start, end, nodes[i], path ) ); } } catch (CoreException ce) {} }