From 7c6a5a00948ba39ee2c2407d2493685b0d8068d0 Mon Sep 17 00:00:00 2001 From: Andrew Niefer Date: Wed, 15 Dec 2004 17:09:04 +0000 Subject: [PATCH] C++: enumerations, enumerators and pointers to functions --- .../core/parser/tests/ast2/AST2CPPTests.java | 143 +++++++++++++++ .../core/dom/parser/cpp/CPPEnumeration.java | 62 +++++++ .../core/dom/parser/cpp/CPPEnumerator.java | 61 +++++++ .../core/dom/parser/cpp/CPPFunction.java | 4 +- .../core/dom/parser/cpp/CPPVariable.java | 20 +-- .../core/dom/parser/cpp/CPPVisitor.java | 166 ++++++++++++------ 6 files changed, 381 insertions(+), 75 deletions(-) create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPEnumeration.java create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPEnumerator.java diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java index 87251c3a45d..6bab529958f 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java @@ -25,10 +25,16 @@ import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTNamedTypeSpecifier; import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; +import org.eclipse.cdt.core.dom.ast.IBasicType; import org.eclipse.cdt.core.dom.ast.ICompositeType; +import org.eclipse.cdt.core.dom.ast.IEnumeration; +import org.eclipse.cdt.core.dom.ast.IEnumerator; import org.eclipse.cdt.core.dom.ast.IField; import org.eclipse.cdt.core.dom.ast.IFunction; +import org.eclipse.cdt.core.dom.ast.IFunctionType; import org.eclipse.cdt.core.dom.ast.IParameter; +import org.eclipse.cdt.core.dom.ast.IPointerType; +import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.ITypedef; import org.eclipse.cdt.core.dom.ast.IVariable; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier; @@ -594,5 +600,142 @@ public class AST2CPPTests extends AST2BaseTest { assertInstances( collector, A, 2 ); assertInstances( collector, x, 2 ); } + + public void testEnumerations() throws Exception { + StringBuffer buffer = new StringBuffer(); + buffer.append( "enum hue { red, blue, green }; \n" ); //$NON-NLS-1$ + buffer.append( "enum hue col, *cp; \n" ); //$NON-NLS-1$ + buffer.append( "void f() { \n" ); //$NON-NLS-1$ + buffer.append( " col = blue; \n" ); //$NON-NLS-1$ + buffer.append( " cp = &col; \n" ); //$NON-NLS-1$ + buffer.append( " if( *cp != red ) \n" ); //$NON-NLS-1$ + buffer.append( " return; \n" ); //$NON-NLS-1$ + buffer.append( "} \n" ); //$NON-NLS-1$ + + IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.CPP ); + CPPNameCollector collector = new CPPNameCollector(); + CPPVisitor.visitTranslationUnit( tu, collector ); + + IEnumeration hue = (IEnumeration) collector.getName(0).resolveBinding(); + IEnumerator red = (IEnumerator) collector.getName(1).resolveBinding(); + IEnumerator blue = (IEnumerator) collector.getName(2).resolveBinding(); + IEnumerator green = (IEnumerator) collector.getName(3).resolveBinding(); + IVariable col = (IVariable) collector.getName(5).resolveBinding(); + IVariable cp = (IVariable) collector.getName(6).resolveBinding(); + + assertInstances( collector, hue, 2 ); + assertInstances( collector, red, 2 ); + assertInstances( collector, blue, 2 ); + assertInstances( collector, green, 1 ); + assertInstances( collector, col, 3 ); + assertInstances( collector, cp, 3 ); + + assertTrue( cp.getType() instanceof IPointerType ); + IPointerType pt = (IPointerType) cp.getType(); + assertSame( pt.getType(), hue ); + } + + public void testPointerToFunction() throws Exception{ + IASTTranslationUnit tu = parse( "int (*pfi)();", ParserLanguage.CPP ); //$NON-NLS-1$ + CPPNameCollector collector = new CPPNameCollector(); + CPPVisitor.visitTranslationUnit( tu, collector ); + IVariable pf = (IVariable) collector.getName(0).resolveBinding(); + IPointerType pt = (IPointerType) pf.getType(); + assertTrue( pt.getType() instanceof IFunctionType ); + + tu = parse( "struct A; int (*pfi)( int, struct A * );", ParserLanguage.CPP ); //$NON-NLS-1$ + collector = new CPPNameCollector(); + CPPVisitor.visitTranslationUnit( tu, collector ); + ICPPClassType A = (ICPPClassType) collector.getName(0).resolveBinding(); + pf = (IVariable) collector.getName(1).resolveBinding(); + pt = (IPointerType) pf.getType(); + assertTrue( pt.getType() instanceof IFunctionType ); + IFunctionType ft = (IFunctionType) pt.getType(); + IType [] params = ft.getParameterTypes(); + assertTrue( params[0] instanceof IBasicType ); + assertTrue( params[1] instanceof IPointerType ); + pt = (IPointerType) params[1]; + assertSame( pt.getType(), A ); + } + + public void testFunctionTypes() throws Exception{ + StringBuffer buffer = new StringBuffer(); + buffer.append( "struct A; \n"); //$NON-NLS-1$ + buffer.append( "int * f( int i, char c ); \n"); //$NON-NLS-1$ + buffer.append( "void ( *g ) ( A * ); \n"); //$NON-NLS-1$ + buffer.append( "void (* (*h)(A**) ) ( int ); \n"); //$NON-NLS-1$ + + IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.CPP ); + + IASTSimpleDeclaration decl = (IASTSimpleDeclaration) tu.getDeclarations()[0]; + IASTElaboratedTypeSpecifier elabSpec = (IASTElaboratedTypeSpecifier) decl.getDeclSpecifier(); + ICompositeType A = (ICompositeType) elabSpec.getName().resolveBinding(); + + decl = (IASTSimpleDeclaration) tu.getDeclarations()[1]; + IFunction f = (IFunction) decl.getDeclarators()[0].getName().resolveBinding(); + + decl = (IASTSimpleDeclaration) tu.getDeclarations()[2]; + IVariable g = (IVariable) decl.getDeclarators()[0].getNestedDeclarator().getName().resolveBinding(); + + decl = (IASTSimpleDeclaration) tu.getDeclarations()[3]; + IVariable h = (IVariable) decl.getDeclarators()[0].getNestedDeclarator().getNestedDeclarator().getName().resolveBinding(); + + IFunctionType t_f = f.getType(); + IType t_f_return = t_f.getReturnType(); + assertTrue( t_f_return instanceof IPointerType ); + assertTrue( ((IPointerType) t_f_return).getType() instanceof IBasicType ); + IType [] t_f_params = t_f.getParameterTypes(); + assertEquals( t_f_params.length, 2 ); + assertTrue( t_f_params[0] instanceof IBasicType ); + assertTrue( t_f_params[1] instanceof IBasicType ); + + //g is a pointer to a function that returns void and has 1 parameter struct A * + IType t_g = g.getType(); + assertTrue( t_g instanceof IPointerType ); + assertTrue( ((IPointerType) t_g).getType() instanceof IFunctionType ); + IFunctionType t_g_func = (IFunctionType) ((IPointerType) t_g).getType(); + IType t_g_func_return = t_g_func.getReturnType(); + assertTrue( t_g_func_return instanceof IBasicType ); + IType [] t_g_func_params = t_g_func.getParameterTypes(); + assertEquals( t_g_func_params.length, 1 ); + IType t_g_func_p1 = t_g_func_params[0]; + assertTrue( t_g_func_p1 instanceof IPointerType ); + assertSame( ((IPointerType)t_g_func_p1).getType(), A ); + + //h is a pointer to a function that returns a pointer to a function + //the returned pointer to function returns void and takes 1 parameter int + // the *h function takes 1 parameter struct A** + IType t_h = h.getType(); + assertTrue( t_h instanceof IPointerType ); + assertTrue( ((IPointerType) t_h).getType() instanceof IFunctionType ); + IFunctionType t_h_func = (IFunctionType) ((IPointerType) t_h).getType(); + IType t_h_func_return = t_h_func.getReturnType(); + IType [] t_h_func_params = t_h_func.getParameterTypes(); + assertEquals( t_h_func_params.length, 1 ); + IType t_h_func_p1 = t_h_func_params[0]; + assertTrue( t_h_func_p1 instanceof IPointerType ); + assertTrue( ((IPointerType)t_h_func_p1).getType() instanceof IPointerType ); + assertSame( ((IPointerType) ((IPointerType)t_h_func_p1).getType() ).getType(), A ); + + assertTrue( t_h_func_return instanceof IPointerType ); + IFunctionType h_return = (IFunctionType) ((IPointerType) t_h_func_return).getType(); + IType h_r = h_return.getReturnType(); + IType [] h_ps = h_return.getParameterTypes(); + assertTrue( h_r instanceof IBasicType ); + assertEquals( h_ps.length, 1 ); + assertTrue( h_ps[0] instanceof IBasicType ); + } + + public void testFnReturningPtrToFn() throws Exception { + IASTTranslationUnit tu = parse( "void ( * f( int ) )(){}", ParserLanguage.CPP ); //$NON-NLS-1$ + + IASTFunctionDefinition def = (IASTFunctionDefinition) tu.getDeclarations()[0]; + IFunction f = (IFunction) def.getDeclarator().getNestedDeclarator().getName().resolveBinding(); + + IFunctionType ft = f.getType(); + assertTrue( ft.getReturnType() instanceof IPointerType ); + assertTrue( ((IPointerType) ft.getReturnType()).getType() instanceof IFunctionType ); + assertEquals( ft.getParameterTypes().length, 1 ); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPEnumeration.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPEnumeration.java new file mode 100644 index 00000000000..154a371a2fc --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPEnumeration.java @@ -0,0 +1,62 @@ +/******************************************************************************* + * 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 Corporation - initial API and implementation + *******************************************************************************/ + +/* + * Created on Dec 14, 2004 + */ +package org.eclipse.cdt.internal.core.dom.parser.cpp; + +import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier; +import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.IEnumeration; +import org.eclipse.cdt.core.dom.ast.IScope; + +/** + * @author aniefer + */ +public class CPPEnumeration implements IEnumeration { + private IASTEnumerationSpecifier enumSpecifier; + /** + * @param specifier + */ + public CPPEnumeration( IASTEnumerationSpecifier specifier ) { + this.enumSpecifier = specifier; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.IBinding#getName() + */ + public String getName() { + return enumSpecifier.getName().toString(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.IBinding#getNameCharArray() + */ + public char[] getNameCharArray() { + return enumSpecifier.getName().toCharArray(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.IBinding#getScope() + */ + public IScope getScope() { + return CPPVisitor.getContainingScope( enumSpecifier ); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.IBinding#getPhysicalNode() + */ + public IASTNode getPhysicalNode() { + return enumSpecifier; + } + +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPEnumerator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPEnumerator.java new file mode 100644 index 00000000000..56a407a6b2f --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPEnumerator.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * 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 Corporation - initial API and implementation + *******************************************************************************/ + +/* + * Created on Dec 14, 2004 + */ +package org.eclipse.cdt.internal.core.dom.parser.cpp; + +import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.IEnumerator; +import org.eclipse.cdt.core.dom.ast.IScope; +import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator; + +/** + * @author aniefer + */ +public class CPPEnumerator implements IEnumerator { + private IASTEnumerator enumerator; + /** + * @param enumerator + */ + public CPPEnumerator( IASTEnumerator enumerator ) { + this.enumerator = enumerator; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.IBinding#getName() + */ + public String getName() { + return enumerator.getName().toString(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.IBinding#getNameCharArray() + */ + public char[] getNameCharArray() { + return enumerator.getName().toCharArray(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.IBinding#getScope() + */ + public IScope getScope() { + return CPPVisitor.getContainingScope( enumerator ); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.IBinding#getPhysicalNode() + */ + public IASTNode getPhysicalNode() { + return enumerator; + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunction.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunction.java index 4ddca342d25..a934e33fde4 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunction.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunction.java @@ -124,8 +124,8 @@ public class CPPFunction implements IFunction { * @see org.eclipse.cdt.core.dom.ast.IFunction#getType() */ public IFunctionType getType() { - if( type == null ) - type = CPPVisitor.createType( ( definition != null ) ? definition : declarations[0] ); + if( type == null ) + type = (IFunctionType) CPPVisitor.createType( ( definition != null ) ? definition : declarations[0] ); return type; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVariable.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVariable.java index f33e9ad041e..15c09b5320f 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVariable.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVariable.java @@ -13,13 +13,8 @@ */ package org.eclipse.cdt.internal.core.dom.parser.cpp; -import org.eclipse.cdt.core.dom.ast.IASTCompositeTypeSpecifier; -import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier; import org.eclipse.cdt.core.dom.ast.IASTDeclarator; -import org.eclipse.cdt.core.dom.ast.IASTElaboratedTypeSpecifier; -import org.eclipse.cdt.core.dom.ast.IASTNamedTypeSpecifier; import org.eclipse.cdt.core.dom.ast.IASTNode; -import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IVariable; @@ -29,6 +24,7 @@ import org.eclipse.cdt.core.dom.ast.IVariable; */ public class CPPVariable implements IVariable { private IASTDeclarator declarator = null; + private IType type = null; public CPPVariable( IASTDeclarator dtor ){ declarator = dtor; @@ -38,17 +34,9 @@ public class CPPVariable implements IVariable { * @see org.eclipse.cdt.core.dom.ast.IVariable#getType() */ public IType getType() { - IASTSimpleDeclaration decl = (IASTSimpleDeclaration) declarator.getParent(); - IASTDeclSpecifier declSpec = decl.getDeclSpecifier(); - - if( declSpec instanceof IASTNamedTypeSpecifier ) - return (IType) ((IASTNamedTypeSpecifier)declSpec).getName().resolveBinding(); - else if( declSpec instanceof IASTCompositeTypeSpecifier ) - return (IType) ((IASTCompositeTypeSpecifier)declSpec).getName().resolveBinding(); - else if( declSpec instanceof IASTElaboratedTypeSpecifier ) - return (IType) ((IASTElaboratedTypeSpecifier)declSpec).getName().resolveBinding(); - - return null; + if( type == null ) + type = CPPVisitor.createType( declarator ); + return type; } /* (non-Javadoc) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java index 98c2bfe87c9..72bb59f527f 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java @@ -133,20 +133,46 @@ public class CPPVisitor { return createBinding( (IASTDeclarator) parent ); } else if( parent instanceof ICPPASTElaboratedTypeSpecifier ){ return createBinding( (ICPPASTElaboratedTypeSpecifier) parent ); - } else if( parent instanceof IASTDeclaration ) + } else if( parent instanceof IASTDeclaration ){ return createBinding( (IASTDeclaration) parent ); + } else if( parent instanceof IASTEnumerationSpecifier ){ + return createBinding( (IASTEnumerationSpecifier) parent ); + } else if( parent instanceof IASTEnumerator ){ + return createBinding( (IASTEnumerator) parent ); + } return null; } - private static IBinding createBinding( ICPPASTElaboratedTypeSpecifier elabType ){ + private static IBinding createBinding( IASTEnumerator enumerator ) { + ICPPScope scope = (ICPPScope) getContainingScope( enumerator ); + IBinding enum = scope.getBinding( enumerator.getName() ); + if( enum == null ){ + enum = new CPPEnumerator( enumerator ); + scope.addBinding( enum ); + } + return enum; + } + + + private static IBinding createBinding( IASTEnumerationSpecifier specifier ) { + ICPPScope scope = (ICPPScope) getContainingScope( specifier ); + IBinding enum = scope.getBinding( specifier.getName() ); + if( enum == null ){ + enum = new CPPEnumeration( specifier ); + scope.addBinding( enum ); + } + return enum; + } + + private static IBinding createBinding( ICPPASTElaboratedTypeSpecifier elabType ){ IASTNode parent = elabType.getParent(); if( parent instanceof IASTSimpleDeclaration ){ IASTDeclarator [] dtors = ((IASTSimpleDeclaration)parent).getDeclarators(); if( dtors.length > 0 ){ - IBinding binding = CPPSemantics.resolveBinding( elabType.getName() ); - if( binding != null ) - return binding; + return CPPSemantics.resolveBinding( elabType.getName() ); } + } else if( parent instanceof IASTParameterDeclaration ){ + return CPPSemantics.resolveBinding( elabType.getName() ); } else if( parent instanceof IASTTypeId ){ return CPPSemantics.resolveBinding( elabType.getName() ); } @@ -191,20 +217,27 @@ public class CPPVisitor { return null; } private static IBinding createBinding( IASTDeclarator declarator ){ - IASTNode parent = declarator.getParent(); - + if( parent instanceof IASTTypeId ) return CPPSemantics.resolveBinding( declarator.getName() ); + + if( declarator.getNestedDeclarator() != null ) + return createBinding( declarator.getNestedDeclarator() ); + + + while( parent instanceof IASTDeclarator ){ + parent = parent.getParent(); + } ICPPScope scope = (ICPPScope) getContainingScope( parent ); IBinding binding = ( scope != null ) ? scope.getBinding( declarator.getName() ) : null; - + if( declarator instanceof ICPPASTFunctionDeclarator ){ if( binding != null && binding instanceof IFunction ){ IFunction function = (IFunction) binding; IFunctionType ftype = function.getType(); - IType type = createType( (ICPPASTFunctionDeclarator) declarator ); + IType type = createType( declarator ); if( ftype.equals( type ) ){ if( parent instanceof IASTSimpleDeclaration ) ((CPPFunction)function).addDeclaration( (ICPPASTFunctionDeclarator) declarator ); @@ -216,28 +249,26 @@ public class CPPVisitor { } if( scope instanceof ICPPClassScope ) binding = new CPPMethod( (ICPPASTFunctionDeclarator) declarator ); - else + else { binding = new CPPFunction( (ICPPASTFunctionDeclarator) declarator ); - } else { - if( parent instanceof IASTSimpleDeclaration ){ - IASTSimpleDeclaration simpleDecl = (IASTSimpleDeclaration) parent; - if( simpleDecl.getDeclSpecifier().getStorageClass() == IASTDeclSpecifier.sc_typedef ){ - binding = new CPPTypedef( declarator ); - } else if( simpleDecl.getParent() instanceof ICPPASTCompositeTypeSpecifier ){ - binding = new CPPField( declarator ); - } else { - binding = new CPPVariable( declarator ); - } - } else if( parent instanceof IASTParameterDeclaration ){ - IASTParameterDeclaration param = (IASTParameterDeclaration) parent; - IASTFunctionDeclarator fDtor = (IASTFunctionDeclarator) param.getParent(); - IFunction function = (IFunction) fDtor.getName().resolveBinding(); - binding = ((CPPFunction) function).resolveParameter( param ); - } else if( parent instanceof IASTFunctionDefinition ){ - } - } - if( scope != null ) + } else if( parent instanceof IASTParameterDeclaration ){ + IASTParameterDeclaration param = (IASTParameterDeclaration) parent; + IASTFunctionDeclarator fDtor = (IASTFunctionDeclarator) param.getParent(); + IFunction function = (IFunction) fDtor.getName().resolveBinding(); + binding = ((CPPFunction) function).resolveParameter( param ); + } else if( parent instanceof IASTSimpleDeclaration ){ + IASTSimpleDeclaration simpleDecl = (IASTSimpleDeclaration) parent; + if( simpleDecl.getDeclSpecifier().getStorageClass() == IASTDeclSpecifier.sc_typedef ){ + binding = new CPPTypedef( declarator ); + } else if( simpleDecl.getParent() instanceof ICPPASTCompositeTypeSpecifier ){ + binding = new CPPField( declarator ); + } else { + binding = new CPPVariable( declarator ); + } + } + + if( scope != null && binding != null ) scope.addBinding( binding ); return binding; } @@ -350,7 +381,7 @@ public class CPPVisitor { return getContainingScope( (IASTSimpleDeclaration) parent ); else if( parent instanceof IASTTypeId ) return getContainingScope( parent.getParent() ); - return null; + return getContainingScope( parent ); } /** @@ -361,9 +392,14 @@ public class CPPVisitor { IASTNode parent = parameterDeclaration.getParent(); if( parent instanceof IASTFunctionDeclarator ){ IASTFunctionDeclarator functionDeclarator = (IASTFunctionDeclarator) parent; + if( functionDeclarator.getNestedDeclarator() != null ){ + return getContainingScope( functionDeclarator ); + } IASTName fnName = functionDeclarator.getName(); - IFunction function = (IFunction) fnName.resolveBinding(); - return function.getFunctionScope(); + IBinding binding = fnName.resolveBinding(); + if( binding instanceof IFunction ) + return ((IFunction)binding).getFunctionScope(); + return binding.getScope(); } return null; @@ -793,7 +829,7 @@ public class CPPVisitor { return true; } - public static IFunctionType createType( ICPPASTFunctionDeclarator fnDtor ){ + private static IType createType( IType returnType, ICPPASTFunctionDeclarator fnDtor ){ List pTypes = Collections.EMPTY_LIST; IASTParameterDeclaration [] params = fnDtor.getParameters(); IType pt = null; @@ -830,39 +866,26 @@ public class CPPVisitor { pTypes.add( pt ); } - IASTNode node = fnDtor.getParent(); - IASTDeclSpecifier declSpec = null; - if( node instanceof IASTSimpleDeclaration ) - declSpec = ((IASTSimpleDeclaration)node).getDeclSpecifier(); - else if ( node instanceof IASTFunctionDefinition ) - declSpec = ((IASTFunctionDefinition)node).getDeclSpecifier(); - - IType returnType = createType( declSpec ); returnType = getPointerTypes( returnType, fnDtor ); IType [] array = new IType [ pTypes.size() ]; - return new CPPFunctionType( returnType, (IType[]) pTypes.toArray( array ) ); + IType type = new CPPFunctionType( returnType, (IType[]) pTypes.toArray( array ) ); + IASTDeclarator nested = fnDtor.getNestedDeclarator(); + if( nested != null ) { + return createType( type, nested ); + } + return type; } /** * @param declarator * @return */ - public static IType createType(IASTDeclarator declarator) { + private static IType createType(IType baseType, IASTDeclarator declarator) { if( declarator instanceof ICPPASTFunctionDeclarator ) - return createType( (ICPPASTFunctionDeclarator)declarator ); - - IASTNode parent = declarator.getParent(); - IASTDeclSpecifier declSpec = null; - if( parent instanceof IASTParameterDeclaration ) - declSpec = ((IASTParameterDeclaration) parent).getDeclSpecifier(); - else if( parent instanceof IASTSimpleDeclaration ) - declSpec = ((IASTSimpleDeclaration)parent).getDeclSpecifier(); - else if( parent instanceof IASTTypeId ) - declSpec = ((IASTTypeId)parent).getDeclSpecifier(); - - IType type = createType( declSpec ); + return createType( baseType, (ICPPASTFunctionDeclarator)declarator ); + IType type = baseType; type = getPointerTypes( type, declarator ); if( declarator instanceof IASTArrayDeclarator ) type = getArrayTypes( type, (IASTArrayDeclarator) declarator ); @@ -884,11 +907,35 @@ public class CPPVisitor { return type; } + /** + * @param declarator + * @return + */ + public static IType createType(IASTDeclarator declarator) { + IASTDeclSpecifier declSpec = null; + + IASTNode node = declarator.getParent(); + while( node instanceof IASTDeclarator ){ + declarator = (IASTDeclarator) node; + node = node.getParent(); + } + + if( node instanceof IASTParameterDeclaration ) + declSpec = ((IASTParameterDeclaration) node).getDeclSpecifier(); + else if( node instanceof IASTSimpleDeclaration ) + declSpec = ((IASTSimpleDeclaration)node).getDeclSpecifier(); + else if( node instanceof IASTFunctionDefinition ) + declSpec = ((IASTFunctionDefinition)node).getDeclSpecifier(); + + IType type = createType( declSpec ); + type = createType( type, declarator ); + return type; + } /** * @param declSpec * @return */ - protected static IType createType(IASTDeclSpecifier declSpec ) { + public static IType createType(IASTDeclSpecifier declSpec ) { IType type = getBaseType( declSpec ); if( type != null && ( declSpec.isConst() || declSpec.isVolatile() ) ){ @@ -903,6 +950,10 @@ public class CPPVisitor { IBinding binding = ((ICPPASTCompositeTypeSpecifier) declSpec).getName().resolveBinding(); if( binding instanceof IType) type = (IType) binding; + } else if( declSpec instanceof ICPPASTNamedTypeSpecifier ){ + IBinding binding = ((ICPPASTNamedTypeSpecifier)declSpec).getName().resolveBinding(); + if( binding instanceof IType ) + type = (IType) binding; } else if( declSpec instanceof ICPPASTElaboratedTypeSpecifier ){ IBinding binding = ((ICPPASTElaboratedTypeSpecifier)declSpec).getName().resolveBinding(); if( binding instanceof IType ) @@ -937,7 +988,8 @@ public class CPPVisitor { } } else if( expression instanceof IASTCastExpression ){ IASTTypeId id = ((IASTCastExpression)expression).getTypeId(); - return createType( id.getAbstractDeclarator() ); + IType type = createType( id.getDeclSpecifier() ); + return createType( type, id.getAbstractDeclarator() ); } else if( expression instanceof ICPPASTLiteralExpression ){ switch( ((ICPPASTLiteralExpression) expression).getKind() ){ case ICPPASTLiteralExpression.lk_this : break;