diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java index 2634bdb12ab..4f6256e48b6 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java @@ -52,6 +52,7 @@ import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator; import org.eclipse.cdt.core.dom.ast.c.ICASTCompositeTypeSpecifier; import org.eclipse.cdt.core.dom.ast.c.ICASTEnumerationSpecifier; import org.eclipse.cdt.core.dom.ast.c.ICASTPointer; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTPointerToMember; import org.eclipse.cdt.core.parser.ParserLanguage; import org.eclipse.cdt.internal.core.parser.ParserException; import org.eclipse.cdt.internal.core.parser2.c.CVisitor; @@ -815,5 +816,44 @@ public class AST2Tests extends AST2BaseTest { assertSame( cp, cp3 ); assertSame( red, red2 ); } + + public void testPointerToFunction() throws Exception + { + IASTTranslationUnit tu = parse( "int (*pfi)();", ParserLanguage.C ); //$NON-NLS-1$ + assertEquals( tu.getDeclarations().size(), 1 ); + IASTSimpleDeclaration d = (IASTSimpleDeclaration) tu.getDeclarations().get(0); + assertEquals( d.getDeclarators().size(), 1 ); + IASTFunctionDeclarator f = (IASTFunctionDeclarator) d.getDeclarators().get(0); + assertNull( f.getName().toString() ); + assertNotNull( f.getNestedDeclarator() ); + assertEquals( f.getNestedDeclarator().getName().toString(), "pfi"); //$NON-NLS-1$ + assertTrue( f.getPointerOperators().isEmpty() ); + assertFalse( f.getNestedDeclarator().getPointerOperators().isEmpty() ); + tu = parse( "int (*pfi)();", ParserLanguage.CPP ); //$NON-NLS-1$ + assertEquals( tu.getDeclarations().size(), 1 ); + d = (IASTSimpleDeclaration) tu.getDeclarations().get(0); + assertEquals( d.getDeclarators().size(), 1 ); + f = (IASTFunctionDeclarator) d.getDeclarators().get(0); + assertNull( f.getName().toString() ); + assertNotNull( f.getNestedDeclarator() ); + assertEquals( f.getNestedDeclarator().getName().toString(), "pfi"); //$NON-NLS-1$ + } + + + public void testBasicPointerToMember() throws Exception + { + StringBuffer buffer = new StringBuffer( "class X {\n"); //$NON-NLS-1$ + buffer.append( " public:\n"); //$NON-NLS-1$ + buffer.append( " void f(int);\n"); //$NON-NLS-1$ + buffer.append( " int a;\n"); //$NON-NLS-1$ + buffer.append( "};\n"); //$NON-NLS-1$ + buffer.append( "int X:: * pmi = &X::a;\n"); //$NON-NLS-1$ + IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.CPP ); + assertEquals( tu.getDeclarations().size(), 2 ); + IASTSimpleDeclaration p2m = (IASTSimpleDeclaration) tu.getDeclarations().get(1); + IASTDeclarator d = (IASTDeclarator) p2m.getDeclarators().get(0); + ICPPASTPointerToMember po = (ICPPASTPointerToMember) d.getPointerOperators().get(0); + assertEquals( po.getName().toString(), "X::"); //$NON-NLS-1$ + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTPointerToMember.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTPointerToMember.java index 37b54fc1e65..21d706bdc65 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTPointerToMember.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTPointerToMember.java @@ -10,16 +10,19 @@ **********************************************************************/ package org.eclipse.cdt.core.dom.ast.cpp; -import org.eclipse.cdt.core.dom.ast.IASTPointerOperator; +import org.eclipse.cdt.core.dom.ast.ASTNodeProperty; +import org.eclipse.cdt.core.dom.ast.IASTName; +import org.eclipse.cdt.core.dom.ast.IASTPointer; /** * This is a pointer to member pointer operator for declarators. * * @author Doug Schaefer */ -public interface ICPPASTPointerToMember extends IASTPointerOperator { +public interface ICPPASTPointerToMember extends IASTPointer { - // TODO fill this in with a qualified name for the class containing - // the member + public static final ASTNodeProperty NAME = new ASTNodeProperty( "Name"); //$NON-NLS-1$ + public void setName( IASTName name ); + public IASTName getName(); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/gnu/cpp/IGPPASTPointerToMember.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/gnu/cpp/IGPPASTPointerToMember.java new file mode 100644 index 00000000000..d0f15d97636 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/gnu/cpp/IGPPASTPointerToMember.java @@ -0,0 +1,21 @@ +/********************************************************************** + * 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.gnu.cpp; + +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTPointerToMember; + +/** + * @author jcamelon + */ +public interface IGPPASTPointerToMember extends IGPPASTPointer, + ICPPASTPointerToMember { + +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/token/BasicTokenDuple.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/token/BasicTokenDuple.java index 2ed5c09afef..beea3a85d26 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/token/BasicTokenDuple.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/token/BasicTokenDuple.java @@ -552,6 +552,7 @@ public class BasicTokenDuple implements ITokenDuple { if( token == last ) break; token = ( token != null ) ? token.getNext() : getFirstToken(); + if( token == null ) break; if( token.getType() == IToken.tLT ) token = TokenFactory.consumeTemplateIdArguments( token, last ); if( token.getType() == IToken.tCOLONCOLON ){ diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/c/GNUCSourceParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/c/GNUCSourceParser.java index ac966c26d70..641a8f878ca 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/c/GNUCSourceParser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/c/GNUCSourceParser.java @@ -84,10 +84,8 @@ import org.eclipse.cdt.core.parser.IGCCToken; import org.eclipse.cdt.core.parser.IParserLogService; import org.eclipse.cdt.core.parser.IScanner; import org.eclipse.cdt.core.parser.IToken; -import org.eclipse.cdt.core.parser.ITokenDuple; import org.eclipse.cdt.core.parser.ParseError; import org.eclipse.cdt.core.parser.ParserMode; -import org.eclipse.cdt.internal.core.parser.token.TokenFactory; import org.eclipse.cdt.internal.core.parser2.ASTNode; import org.eclipse.cdt.internal.core.parser2.AbstractGNUSourceCodeParser; import org.eclipse.cdt.internal.core.parser2.IProblemRequestor; @@ -1084,12 +1082,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser { for (;;) { IToken mark = mark(); - ITokenDuple nameDuple = null; boolean isConst = false, isVolatile = false, isRestrict = false; - if (LT(1) == IToken.tIDENTIFIER) { - IToken t = identifier(); - nameDuple = TokenFactory.createTokenDuple(t, t); - } if( LT(1) != IToken.tSTAR ) { @@ -1120,18 +1113,12 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser { break; } - IASTPointerOperator po = null; - if (nameDuple != null) { - nameDuple.freeReferences(); - } else { - po = createPointer(); - ((ASTNode)po).setOffset( startOffset ); - ((ICASTPointer) po).setConst(isConst); - ((ICASTPointer) po).setVolatile(isVolatile); - ((ICASTPointer) po).setRestrict(isRestrict); - } - if (po != null) - pointerOps.add(po); + IASTPointerOperator po = createPointer(); + ((ASTNode)po).setOffset( startOffset ); + ((ICASTPointer) po).setConst(isConst); + ((ICASTPointer) po).setVolatile(isVolatile); + ((ICASTPointer) po).setRestrict(isRestrict); + pointerOps.add(po); } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/cpp/CPPASTPointerToMember.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/cpp/CPPASTPointerToMember.java new file mode 100644 index 00000000000..578f192ace1 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/cpp/CPPASTPointerToMember.java @@ -0,0 +1,38 @@ +/********************************************************************** + * 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.parser2.cpp; + +import org.eclipse.cdt.core.dom.ast.IASTName; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTPointerToMember; + +/** + * @author jcamelon + */ +public class CPPASTPointerToMember extends CPPASTPointer implements + ICPPASTPointerToMember { + + private IASTName n; + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPASTPointerToMember#setName(org.eclipse.cdt.core.dom.ast.IASTName) + */ + public void setName(IASTName name) { + n = name; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPASTPointerToMember#getName() + */ + public IASTName getName() { + return n; + } + +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/cpp/GNUCPPSourceParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/cpp/GNUCPPSourceParser.java index 47ceefa84d3..ddf1e7d8028 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/cpp/GNUCPPSourceParser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/cpp/GNUCPPSourceParser.java @@ -88,6 +88,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceAlias; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNewExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTParameterDeclaration; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTPointerToMember; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTReferenceOperator; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSimpleDeclSpecifier; @@ -111,6 +112,7 @@ import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTBinaryExpression; import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTDeclSpecifier; import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTExplicitTemplateInstantiation; import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTPointer; +import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTPointerToMember; import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTSimpleDeclSpecifier; import org.eclipse.cdt.core.parser.BacktrackException; import org.eclipse.cdt.core.parser.EndOfFileException; @@ -570,8 +572,22 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { IASTPointerOperator po = null; if (nameDuple != null) { - //TODO - pointer to functions - nameDuple.freeReferences(); + IASTName name = createName( nameDuple ); + ICPPASTPointerToMember p2m = createPointerToMember(isRestrict); + ((ASTNode)p2m).setOffset( starOffset ); + p2m.setConst(isConst); + p2m.setVolatile(isVolatile); + p2m.setName( name ); + name.setParent( p2m ); + name.setPropertyInParent( ICPPASTPointerToMember.NAME ); + if( isRestrict ) + { + IGPPASTPointerToMember newPo = (IGPPASTPointerToMember) p2m; + newPo.setRestrict( isRestrict ); + p2m = newPo; + } + po = p2m; + } else { po = createPointer(isRestrict); ((ASTNode)po).setOffset( starOffset ); @@ -602,7 +618,16 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { * @param isRestrict * @return */ - private IASTPointerOperator createPointer(boolean gnu) { + protected ICPPASTPointerToMember createPointerToMember(boolean gnu) { + if( gnu ) return new GPPASTPointerToMember(); + return new CPPASTPointerToMember(); + } + + /** + * @param isRestrict + * @return + */ + protected IASTPointerOperator createPointer(boolean gnu) { if( gnu ) return new GPPASTPointer(); return new CPPASTPointer(); } @@ -1516,7 +1541,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { /** * @return */ - private IASTFunctionCallExpression createFunctionCallExpression() { + protected IASTFunctionCallExpression createFunctionCallExpression() { return new CPPASTFunctionCallExpression(); } @@ -1650,7 +1675,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { /** * @return */ - private ICPPASTLiteralExpression createLiteralExpression() { + protected ICPPASTLiteralExpression createLiteralExpression() { return new CPPASTLiteralExpression(); } @@ -2696,7 +2721,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { /** * @return */ - private ICPPASTParameterDeclaration createParameterDeclaration() { + protected ICPPASTParameterDeclaration createParameterDeclaration() { return new CPPASTParameterDeclaration(); } @@ -2707,7 +2732,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { * @throws EndOfFileException * we could encounter EOF while looking ahead */ - private boolean lookAheadForConstructorOrConversion(Flags flags) throws EndOfFileException { + protected boolean lookAheadForConstructorOrConversion(Flags flags) throws EndOfFileException { if (flags.isForParameterDeclaration()) return false; if (LT(2) == IToken.tLPAREN @@ -3109,7 +3134,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { /** * @return */ - private ICPPASTSimpleDeclSpecifier createGPPSimpleDeclSpecifier() { + protected ICPPASTSimpleDeclSpecifier createGPPSimpleDeclSpecifier() { return new GPPASTSimpleDeclSpecifier(); } @@ -3302,7 +3327,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { /** * @return */ - private IASTInitializerExpression createInitializerExpression() { + protected IASTInitializerExpression createInitializerExpression() { return new CPPASTInitializerExpresion(); } @@ -3390,14 +3415,9 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { if (LT(2) == IToken.tIDENTIFIER) { IToken newMark = mark(); consume(IToken.tLPAREN); - ITokenDuple queryName = null; try { try { - queryName = name(); - //TODO - when the Visitor is available - //find the IASTName relating to this in the AST - //if this is a type, failed = false - //if this is a value, failed = true + name(); failed = false; } catch (Exception e) { int endOffset = (lastToken != null) ? lastToken @@ -3412,8 +3432,6 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { failed = true; } - if (queryName != null) - queryName.freeReferences(); backup(newMark); } } @@ -3629,14 +3647,14 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { /** * @return */ - private ICPPASTFunctionDeclarator createFunctionDeclarator() { + protected ICPPASTFunctionDeclarator createFunctionDeclarator() { return new CPPASTFunctionDeclarator(); } /** * @return */ - private IASTFieldDeclarator createFieldDeclarator() { + protected IASTFieldDeclarator createFieldDeclarator() { return new CPPASTFieldDeclarator(); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/cpp/GPPASTPointerToMember.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/cpp/GPPASTPointerToMember.java new file mode 100644 index 00000000000..8b814c3d8b8 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/cpp/GPPASTPointerToMember.java @@ -0,0 +1,37 @@ +/********************************************************************** + * 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.parser2.cpp; + +import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTPointerToMember; + +/** + * @author jcamelon + */ +public class GPPASTPointerToMember extends CPPASTPointerToMember implements + IGPPASTPointerToMember { + + private boolean isRestrict; + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTPointer#isRestrict() + */ + public boolean isRestrict() { + return isRestrict; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTPointer#setRestrict(boolean) + */ + public void setRestrict(boolean value) { + isRestrict = value; + } + +}