/******************************************************************************* * Copyright (c) 2004, 2010 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM - Initial API and implementation * Markus Schorn (Wind River Systems) * Anton Leherbauer (Wind River Systems) *******************************************************************************/ package org.eclipse.cdt.core.parser.tests.ast2; import org.eclipse.cdt.core.dom.ast.IASTDeclaration; import org.eclipse.cdt.core.dom.ast.IASTDeclarator; import org.eclipse.cdt.core.dom.ast.IASTEqualsInitializer; import org.eclipse.cdt.core.dom.ast.IASTFileLocation; import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition; import org.eclipse.cdt.core.dom.ast.IASTInitializerClause; import org.eclipse.cdt.core.dom.ast.IASTMacroExpansionLocation; 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.IASTPreprocessorMacroExpansion; import org.eclipse.cdt.core.dom.ast.IASTPreprocessorObjectStyleMacroDefinition; import org.eclipse.cdt.core.dom.ast.IASTPreprocessorStatement; 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 { final ParserLanguage[] languages = new ParserLanguage[] { ParserLanguage.C, ParserLanguage.CPP }; public DOMLocationMacroTests() { } public DOMLocationMacroTests(String name) { super(name); } 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 language : languages) { IASTTranslationUnit tu = parse(code, language); 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 ); IASTMacroExpansionLocation expansion = (IASTMacroExpansionLocation) declaratorLocations[0]; IASTPreprocessorObjectStyleMacroDefinition fromExpansion = (IASTPreprocessorObjectStyleMacroDefinition) expansion.getExpansion().getMacroDefinition(); assertEqualsMacros( fromExpansion, ABC ); assertEquals( expansion.getNodeOffset(), 0 ); assertEquals( expansion.getNodeLength(), 1 ); IASTNodeLocation [] macroLocation = expansion.getExpansion().getNodeLocations(); 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 language : languages) { IASTTranslationUnit tu = parse(code, language); 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 ); IASTMacroExpansionLocation expansion = (IASTMacroExpansionLocation) declaratorLocations[0]; IASTPreprocessorObjectStyleMacroDefinition fromExpansion = (IASTPreprocessorObjectStyleMacroDefinition) expansion.getExpansion().getMacroDefinition(); assertEqualsMacros( fromExpansion, ABC ); assertEquals( expansion.getNodeOffset(), 0 ); assertEquals( 2, expansion.getNodeLength() ); IASTNodeLocation [] macroLocation = expansion.getExpansion().getNodeLocations(); 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 IASTMacroExpansionLocation nodeLocation = (IASTMacroExpansionLocation) nameLocations[0]; assertEquals( nodeLocation.getNodeOffset(), 1 ); assertEquals( nodeLocation.getNodeLength(), 1 ); assertEquals( nodeLocation.getExpansion().getNodeLocations()[0].getNodeOffset(), macroLocation[0].getNodeOffset() ); assertEquals( nodeLocation.getExpansion().getNodeLocations()[0].getNodeLength(), macroLocation[0].getNodeLength() ); IASTPointer po = (IASTPointer) d.getPointerOperators()[0]; assertFalse( po.isConst() ); assertFalse( po.isVolatile() ); IASTMacroExpansionLocation pointerLocation = (IASTMacroExpansionLocation) po.getNodeLocations()[0]; assertEquals( pointerLocation.getNodeOffset(), 0 ); assertEquals( pointerLocation.getNodeLength(), 1 ); assertEquals( pointerLocation.getExpansion().getNodeLocations()[0].getNodeOffset(), macroLocation[0].getNodeOffset() ); assertEquals( pointerLocation.getExpansion().getNodeLocations()[0].getNodeLength(), macroLocation[0].getNodeLength() ); assertEqualsMacros( pointerLocation.getExpansion().getMacroDefinition(), nodeLocation.getExpansion().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 language : languages) { IASTTranslationUnit tu = parse(code, language); IASTPreprocessorObjectStyleMacroDefinition defXYZ = (IASTPreprocessorObjectStyleMacroDefinition) tu.getMacroDefinitions()[0]; IASTSimpleDeclaration var = (IASTSimpleDeclaration) tu.getDeclarations()[0]; IASTSimpleDeclSpecifier declSpec = (IASTSimpleDeclSpecifier) var.getDeclSpecifier(); IASTNodeLocation [] declSpecLocations = declSpec.getNodeLocations(); assertEquals( declSpecLocations.length, 2 ); IASTMacroExpansionLocation expansion = (IASTMacroExpansionLocation) declSpecLocations[0]; assertEqualsMacros( defXYZ, expansion.getExpansion().getMacroDefinition() ); assertEquals( expansion.getNodeOffset(), 0 ); assertEquals( expansion.getNodeLength(), 1 ); IASTNodeLocation [] expansionLocations = expansion.getExpansion().getNodeLocations(); 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 language : languages) { IASTTranslationUnit tu = parse(code, language); 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$ IASTMacroExpansionLocation mac_loc = (IASTMacroExpansionLocation) locations[1]; final IASTPreprocessorMacroDefinition C_PO2 = mac_loc.getExpansion().getMacroDefinition(); assertEqualsMacros( C_PO, C_PO2 ); assertEquals( 0, mac_loc.getNodeOffset()); assertEquals( 2, 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 language : languages) { IASTTranslationUnit tu = parse(code, language); 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 ); IASTMacroExpansionLocation first_loc = (IASTMacroExpansionLocation) nodeLocations[0]; assertEqualsMacros( first_loc.getExpansion().getMacroDefinition(), XYZ ); IASTFileLocation second_loc = (IASTFileLocation) nodeLocations[1]; assertEquals( 1, second_loc.getNodeLength() ); IASTMacroExpansionLocation third_loc = (IASTMacroExpansionLocation) nodeLocations[2]; assertEqualsMacros( third_loc.getExpansion().getMacroDefinition(), IT ); IASTFileLocation fourth_loc = (IASTFileLocation) nodeLocations[3]; assertEquals( 1, fourth_loc.getNodeLength() ); IASTMacroExpansionLocation fifth_loc = (IASTMacroExpansionLocation) nodeLocations[4]; assertEqualsMacros( fifth_loc.getExpansion().getMacroDefinition(), C_PO ); IASTFileLocation sixth_loc = (IASTFileLocation) nodeLocations[5]; assertEquals( 1, sixth_loc.getNodeLength() ); IASTMacroExpansionLocation seventh_loc = (IASTMacroExpansionLocation) nodeLocations[6]; assertEqualsMacros( seventh_loc.getExpansion().getMacroDefinition(), C_PO ); IASTFileLocation eighth_loc = (IASTFileLocation) nodeLocations[7]; assertEquals( 1, eighth_loc.getNodeLength() ); IASTMacroExpansionLocation ninth_loc = (IASTMacroExpansionLocation) nodeLocations[8]; assertEqualsMacros( ninth_loc.getExpansion().getMacroDefinition(), V ); IASTFileLocation tenth_loc = (IASTFileLocation) nodeLocations[9]; assertEquals( 1, tenth_loc.getNodeLength() ); final IASTFileLocation flatLocation = var.getFileLocation(); 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 __cdecl __attribute__ ((__cdecl__))\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 language : languages) { IASTTranslationUnit tu = parse(code, language, true, true); final IASTPreprocessorMacroDefinition[] macroDefinitions = tu.getMacroDefinitions(); IASTPreprocessorObjectStyleMacroDefinition _PTR = (IASTPreprocessorObjectStyleMacroDefinition) macroDefinitions[0]; IASTPreprocessorFunctionStyleMacroDefinition _EXFUN = (IASTPreprocessorFunctionStyleMacroDefinition) macroDefinitions[2]; IASTSimpleDeclaration memchr = (IASTSimpleDeclaration) tu.getDeclarations()[0]; IASTNodeLocation [] locations = memchr.getNodeLocations(); assertEquals( locations.length, 4 ); IASTMacroExpansionLocation loc_1 = (IASTMacroExpansionLocation) locations[0]; assertEqualsMacros( _PTR, loc_1.getExpansion().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$ IASTMacroExpansionLocation loc_3 = (IASTMacroExpansionLocation) locations[2]; assertEqualsMacros( _EXFUN, loc_3.getExpansion().getMacroDefinition() ); IASTFileLocation loc_4 = (IASTFileLocation) locations[3]; assertEquals( loc_4.getNodeOffset(), code.indexOf( ";")); //$NON-NLS-1$ assertEquals( loc_4.getNodeLength(), 1 ); IASTFileLocation flat = memchr.getFileLocation(); 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$ IASTDeclarator d = memchr.getDeclarators()[0]; IASTFileLocation f = d.getFileLocation(); assertEquals( code.indexOf( "_PTR _EXFUN(memchr,(const _PTR, int, size_t))"), f.getNodeOffset() ); //$NON-NLS-1$ assertEquals( "_PTR _EXFUN(memchr,(const _PTR, int, size_t))".length(), f.getNodeLength() ); //$NON-NLS-1$ } } 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 language : languages) { IASTTranslationUnit tu = parse(code, language); 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.getDeclarationsInAST( binding1 ); assertEquals( firstReferences.length, 2 ); assertEquals( firstReferences[0].getPropertyInParent(), IASTPreprocessorMacroExpansion.EXPANSION_NAME ); assertEquals( firstReferences[0].getParent().getParent(), tu ); assertEquals( firstReferences[1].getPropertyInParent(), IASTPreprocessorStatement.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.getDeclarationsInAST( binding2 ); assertEquals( 1, secondReferences.length ); assertEquals( secondReferences[0].getPropertyInParent(), IASTPreprocessorMacroExpansion.EXPANSION_NAME ); assertEquals( secondReferences[0].getParent().getParent(), tu ); assertSame( ABC2.getName(), secondDeclarations[0]); } } public void testBug90978() throws Exception { StringBuffer buffer = new StringBuffer( "#define MACRO mm\n"); //$NON-NLS-1$ buffer.append( "int MACRO;\n"); //$NON-NLS-1$ String code = buffer.toString(); for (ParserLanguage language : languages) { IASTTranslationUnit tu = parse(code, language); IASTPreprocessorObjectStyleMacroDefinition MACRO = (IASTPreprocessorObjectStyleMacroDefinition) tu.getMacroDefinitions()[0]; IASTName macro_name = MACRO.getName(); IMacroBinding binding = (IMacroBinding) macro_name.resolveBinding(); IASTName [] references = tu.getReferences( binding ); assertEquals( references.length, 1 ); IASTName reference = references[0]; IASTNodeLocation [] nodeLocations = reference.getNodeLocations(); assertEquals( nodeLocations.length, 1 ); assertTrue( nodeLocations[0] instanceof IASTFileLocation ); IASTFileLocation loc = (IASTFileLocation) nodeLocations[0]; assertEquals( code.indexOf( "int MACRO") + "int ".length(), loc.getNodeOffset() ); //$NON-NLS-1$ //$NON-NLS-2$ assertEquals( "MACRO".length(), loc.getNodeLength() ); //$NON-NLS-1$ } } public void testBug94933() throws Exception { StringBuffer buffer = new StringBuffer( "#define API extern\n" ); //$NON-NLS-1$ buffer.append( "#define MYAPI API\n"); //$NON-NLS-1$ buffer.append( "MYAPI void func() {}" ); //$NON-NLS-1$ String code = buffer.toString(); for (ParserLanguage language : languages) { IASTTranslationUnit tu = parse(code, language); IASTFunctionDefinition f = (IASTFunctionDefinition) tu.getDeclarations()[0]; assertNotNull( f.getFileLocation() ); } } public void testFunctionMacroExpansionWithNameSubstitution_Bug173637() throws Exception { StringBuffer buffer = new StringBuffer( "#define PLUS5(x) (x+5)\n"); //$NON-NLS-1$ buffer.append( "#define FUNCTION PLUS5 \n"); //$NON-NLS-1$ buffer.append( "int var= FUNCTION(1);"); //$NON-NLS-1$ String code = buffer.toString(); for (ParserLanguage language : languages) { IASTTranslationUnit tu = parse(code, language); IASTSimpleDeclaration var = (IASTSimpleDeclaration) tu.getDeclarations()[0]; IASTEqualsInitializer initializer= (IASTEqualsInitializer)var.getDeclarators()[0].getInitializer(); IASTInitializerClause expr= initializer.getInitializerClause(); assertNotNull(expr.getFileLocation()); IASTNodeLocation [] locations = expr.getNodeLocations(); assertEquals(1, locations.length); IASTMacroExpansionLocation macroExpansion = (IASTMacroExpansionLocation) locations[0]; IASTNodeLocation[] expLocations= macroExpansion.getExpansion().getNodeLocations(); assertEquals(1, expLocations.length); assertEquals(code.indexOf("FUNCTION(1)"), expLocations[0].getNodeOffset()); assertEquals("FUNCTION(1)".length(), expLocations[0].getNodeLength()); } } private void assertMacroLocation(IASTDeclaration decl, int index, int length) { IASTSimpleDeclaration var = (IASTSimpleDeclaration) decl; IASTEqualsInitializer initializer= (IASTEqualsInitializer)var.getDeclarators()[0].getInitializer(); IASTInitializerClause expr= initializer.getInitializerClause(); assertNotNull(expr.getFileLocation()); IASTNodeLocation [] locations = expr.getNodeLocations(); assertEquals(1, locations.length); IASTMacroExpansionLocation macroExpansion = (IASTMacroExpansionLocation) locations[0]; IASTNodeLocation[] expLocations= macroExpansion.getExpansion().getNodeLocations(); assertEquals(1, expLocations.length); IASTFileLocation fileLocation = expLocations[0].asFileLocation(); assertEquals(index, fileLocation.getNodeOffset()); assertEquals(length, fileLocation.getNodeLength()); } private void assertExpressionLocation(IASTDeclaration decl, int index, int length) { IASTSimpleDeclaration var = (IASTSimpleDeclaration) decl; IASTEqualsInitializer initializer= (IASTEqualsInitializer)var.getDeclarators()[0].getInitializer(); IASTInitializerClause expr= initializer.getInitializerClause(); IASTFileLocation fileLocation = expr.getFileLocation(); assertNotNull(fileLocation); assertEquals(index, fileLocation.getNodeOffset()); assertEquals(length, fileLocation.getNodeLength()); } public void testBug186257() throws Exception { StringBuffer sb = new StringBuffer(); sb.append("typedef char STR; \n"); //$NON-NLS-1$ sb.append("#define Nullstr Null(STR*) \n"); //$NON-NLS-1$ sb.append("#define Null(x) ((x)NULL) \n"); //$NON-NLS-1$ sb.append("int x = Nullstr; \n"); //$NON-NLS-1$ sb.append("int y = whatever; \n"); //$NON-NLS-1$ String code = sb.toString(); for (ParserLanguage language : languages) { IASTTranslationUnit tu = parse(code, language); IASTDeclaration[] decls = tu.getDeclarations(); assertMacroLocation(decls[1], code.indexOf("Nullstr;"), "Nullstr".length()); //$NON-NLS-1$ //$NON-NLS-2$ assertExpressionLocation(decls[2], code.indexOf("whatever;"), "whatever".length()); //$NON-NLS-1$ //$NON-NLS-2$ } } public void testArgumentExpansion() throws Exception { StringBuffer sb = new StringBuffer(); sb.append("#define ADD(a,b, c) (a) + (b) + (c) \n"); //$NON-NLS-1$ sb.append("#define ONEYONENOE 111111 \n"); //$NON-NLS-1$ sb.append("#define TWO 2 \n"); //$NON-NLS-1$ sb.append("#define THREE 3 \n"); //$NON-NLS-1$ sb.append("int x = ADD(ONEYONENOE,TWO, THREE); \n"); //$NON-NLS-1$ sb.append("int y = whatever; \n"); //$NON-NLS-1$ String code = sb.toString(); for (ParserLanguage language : languages) { IASTTranslationUnit tu = parse(code, language); IASTDeclaration[] decls = tu.getDeclarations(); assertMacroLocation(decls[0], code.indexOf("ADD(ONEYONENOE,TWO, THREE)"), "ADD(ONEYONENOE,TWO, THREE)".length()); //$NON-NLS-1$ //$NON-NLS-2$ assertExpressionLocation(decls[1], code.indexOf("whatever;"), "whatever".length()); //$NON-NLS-1$ //$NON-NLS-2$ } } public void testArgumentCapture() throws Exception { StringBuffer sb = new StringBuffer(); sb.append("#define add(x,y) x + y \n"); //$NON-NLS-1$ sb.append("#define add2 add(x, \n"); //$NON-NLS-1$ sb.append("int x = add2 z); \n"); //$NON-NLS-1$ sb.append("int y = whatever; \n"); //$NON-NLS-1$ String code = sb.toString(); for (ParserLanguage language : languages) { IASTTranslationUnit tu = parse(code, language); IASTDeclaration[] decls = tu.getDeclarations(); assertMacroLocation(decls[0], code.indexOf("add2 z);"), "add2 z)".length()); //$NON-NLS-1$ //$NON-NLS-2$ assertExpressionLocation(decls[1], code.indexOf("whatever;"), "whatever".length()); //$NON-NLS-1$ //$NON-NLS-2$ } } public void testFunctionMacroNotCalled() throws Exception { StringBuffer sb = new StringBuffer(); sb.append("#define FUNCTION(x) x \n"); //$NON-NLS-1$ sb.append("#define YO FUNCTION \n"); //$NON-NLS-1$ sb.append("int x = YO; \n"); //$NON-NLS-1$ sb.append("int y = whatever; \n"); //$NON-NLS-1$ String code = sb.toString(); for (ParserLanguage language : languages) { IASTTranslationUnit tu = parse(code, language); IASTDeclaration[] decls = tu.getDeclarations(); assertMacroLocation(decls[0], code.indexOf("YO;"), "YO".length()); //$NON-NLS-1$ //$NON-NLS-2$ assertExpressionLocation(decls[1], code.indexOf("whatever;"), "whatever".length()); //$NON-NLS-1$ //$NON-NLS-2$ } } public void testBuildFunctionMacroName() throws Exception { StringBuffer sb = new StringBuffer(); sb.append("#define FUN1(x) x \n"); //$NON-NLS-1$ sb.append("#define FUN1(x) x \n"); //$NON-NLS-1$ sb.append("#define MAKEFUN(num) FUN ## num \n"); //$NON-NLS-1$ sb.append("int x = MAKEFUN(1)(z); \n"); //$NON-NLS-1$ sb.append("int y = whatever; \n"); //$NON-NLS-1$ String code = sb.toString(); for (ParserLanguage language : languages) { IASTTranslationUnit tu = parse(code, language); IASTDeclaration[] decls = tu.getDeclarations(); assertMacroLocation(decls[0], code.indexOf("MAKEFUN(1)(z);"), "MAKEFUN(1)(z)".length()); //$NON-NLS-1$ //$NON-NLS-2$ assertExpressionLocation(decls[1], code.indexOf("whatever;"), "whatever".length()); //$NON-NLS-1$ //$NON-NLS-2$ } } }