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 0675a6b454b..f68290a53ec 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 @@ -15,7 +15,6 @@ package org.eclipse.cdt.core.parser.tests.ast2; import org.eclipse.cdt.core.dom.ast.IASTCompositeTypeSpecifier; import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement; -import org.eclipse.cdt.core.dom.ast.IASTDeclarationStatement; import org.eclipse.cdt.core.dom.ast.IASTDeclarator; import org.eclipse.cdt.core.dom.ast.IASTElaboratedTypeSpecifier; import org.eclipse.cdt.core.dom.ast.IASTExpressionStatement; @@ -23,10 +22,12 @@ import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator; import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition; import org.eclipse.cdt.core.dom.ast.IASTIdExpression; import org.eclipse.cdt.core.dom.ast.IASTInitializerExpression; +import org.eclipse.cdt.core.dom.ast.IASTLiteralExpression; 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.IASTUnaryExpression; import org.eclipse.cdt.core.dom.ast.IArrayType; import org.eclipse.cdt.core.dom.ast.IBasicType; import org.eclipse.cdt.core.dom.ast.IBinding; @@ -53,6 +54,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace; import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier; import org.eclipse.cdt.core.parser.ParserLanguage; +import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVisitor; /** @@ -1010,12 +1012,12 @@ public class AST2CPPTests extends AST2BaseTest { assertInstances(col, x, 3); } - public void testBug84250() throws Exception { - assertTrue(((IASTDeclarationStatement) ((IASTCompoundStatement) ((IASTFunctionDefinition) parse( - "void f() { int (*p) [2]; }", ParserLanguage.CPP).getDeclarations()[0]).getBody()).getStatements()[0]).getDeclaration() instanceof IASTSimpleDeclaration); //$NON-NLS-1$ - } +// public void testBug84250() throws Exception { +// assertTrue(((IASTDeclarationStatement) ((IASTCompoundStatement) ((IASTFunctionDefinition) parse( +// "void f() { int (*p) [2]; }", ParserLanguage.CPP).getDeclarations()[0]).getBody()).getStatements()[0]).getDeclaration() instanceof IASTSimpleDeclaration); //$NON-NLS-1$ +// } - public void _testBug84250() throws Exception { + public void testBug84250() throws Exception { StringBuffer buffer = new StringBuffer(); buffer.append("void f() { \n"); //$NON-NLS-1$ buffer.append(" int ( *p ) [2]; \n"); //$NON-NLS-1$ @@ -1036,7 +1038,7 @@ public class AST2CPPTests extends AST2BaseTest { assertInstances(col, p, 2); } - public void _testBug84250_2() throws Exception { + public void testBug84250_2() throws Exception { StringBuffer buffer = new StringBuffer(); buffer.append("void f() { \n"); //$NON-NLS-1$ buffer.append(" int ( *p ) [2]; \n"); //$NON-NLS-1$ @@ -1231,6 +1233,82 @@ public class AST2CPPTests extends AST2BaseTest { IVariable a2 = (IVariable) col.getName(10).resolveBinding(); assertSame( a1, a2 ); } + public void testBug84705() throws Exception { + StringBuffer buffer = new StringBuffer(); + buffer.append( "struct C { \n" ); //$NON-NLS-1$ + buffer.append( " void f(); \n" ); //$NON-NLS-1$ + buffer.append( " const C& operator=( const C& ); \n" ); //$NON-NLS-1$ + buffer.append( "}; \n" ); //$NON-NLS-1$ + buffer.append( "const C& C::operator=( const C& other) { \n" ); //$NON-NLS-1$ + buffer.append( " if( this != &other ) { \n" ); //$NON-NLS-1$ + buffer.append( " this->~C(); \n" ); //$NON-NLS-1$ + buffer.append( " new (this) C(other ); \n" ); //$NON-NLS-1$ + buffer.append( " f(); \n" ); //$NON-NLS-1$ + buffer.append( " } \n" ); //$NON-NLS-1$ + buffer.append( " return *this; \n" ); //$NON-NLS-1$ + buffer.append( "} \n" ); //$NON-NLS-1$ + IASTTranslationUnit tu = parse(buffer.toString(), ParserLanguage.CPP); + CPPNameCollector col = new CPPNameCollector(); + CPPVisitor.visitTranslationUnit(tu, col); + + assertEquals(col.size(), 17); + + ICPPMethod f = (ICPPMethod) col.getName(1).resolveBinding(); + IASTName [] refs = tu.getReferences( f ); + assertEquals( 1, refs.length ); + assertSame( f, refs[0].resolveBinding() ); + + ICPPClassType C = (ICPPClassType) col.getName(0).resolveBinding(); + ICPPMethod op = (ICPPMethod) col.getName(3).resolveBinding(); + IParameter other = (IParameter) col.getName(11).resolveBinding(); + ICPPMethod dtor = (ICPPMethod) col.getName(13).resolveBinding(); + assertNotNull( dtor ); + assertEquals( dtor.getName(), "~C" ); //$NON-NLS-1$ + assertInstances( col, C, 6 ); + + assertInstances( col, op, 3 ); + assertInstances( col, other, 4 ); + } + + public void testThis() throws Exception { + StringBuffer buffer = new StringBuffer(); + buffer.append( "class A { void f(); void g() const; }; \n" ); //$NON-NLS-1$ + buffer.append( "void A::f(){ this; } \n" ); //$NON-NLS-1$ + buffer.append( "void A::g() const { *this; } \n" ); //$NON-NLS-1$ + + IASTTranslationUnit tu = parse(buffer.toString(), ParserLanguage.CPP); + + IASTSimpleDeclaration decl = (IASTSimpleDeclaration) tu.getDeclarations()[0]; + ICPPClassType A = (ICPPClassType) ((IASTCompositeTypeSpecifier)decl.getDeclSpecifier()).getName().resolveBinding(); + + IASTFunctionDefinition def = (IASTFunctionDefinition) tu.getDeclarations()[1]; + IASTExpressionStatement expStatement = (IASTExpressionStatement) ((IASTCompoundStatement)def.getBody()).getStatements()[0]; + assertTrue( expStatement.getExpression() instanceof IASTLiteralExpression ); + IType type = CPPVisitor.getExpressionType( expStatement.getExpression() ); + + assertTrue( type instanceof IPointerType ); + assertSame( ((IPointerType) type).getType(), A ); + + def = (IASTFunctionDefinition) tu.getDeclarations()[2]; + expStatement = (IASTExpressionStatement) ((IASTCompoundStatement)def.getBody()).getStatements()[0]; + IASTUnaryExpression ue = (IASTUnaryExpression) expStatement.getExpression(); + type = CPPVisitor.getExpressionType( ue ); + + //when 84749 is fixed, remove this assert and uncomment below. + assertSame( type, A ); +// assertTrue( type instanceof IQualifierType ); +// assertSame( ((IQualifierType) type).getType(), A ); +// assertTrue( ((IQualifierType) type).isConst() ); + } + + public void testBug84710() throws Exception { + IASTTranslationUnit tu = parse( "class T { T(); };", ParserLanguage.CPP ); //$NON-NLS-1$ + CPPNameCollector col = new CPPNameCollector(); + CPPVisitor.visitTranslationUnit(tu, col); + ICPPConstructor T = (ICPPConstructor) col.getName(1).resolveBinding(); + assertTrue( CharArrayUtils.equals( T.getNameCharArray(), "T".toCharArray() ) ) ; //$NON-NLS-1$ + assertEquals( T.getName(), "T" ); //$NON-NLS-1$ + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPClassScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPClassScope.java index 6e12867c6ee..72b620d1fd8 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPClassScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPClassScope.java @@ -17,5 +17,5 @@ package org.eclipse.cdt.core.dom.ast.cpp; * @author aniefer */ public interface ICPPClassScope extends ICPPScope { - + ICPPClassType getClassType(); } 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 bc8bb1d4544..ebee48a0810 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 @@ -12,11 +12,11 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp; import org.eclipse.cdt.core.dom.ast.ASTNodeProperty; import org.eclipse.cdt.core.dom.ast.IASTDeclaration; -import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroDefinition; 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.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; @@ -128,8 +128,7 @@ 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) { - // TODO Auto-generated method stub - return null; + return CPPVisitor.getReferences(this, b); } /* diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java index 04e30ddff27..26a626f65f4 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java @@ -61,22 +61,24 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope { return; } + char [] className = compTypeSpec.getName().toCharArray(); + //default constructor: A() - addBinding( new CPPImplicitConstructor( this, IParameter.EMPTY_PARAMETER_ARRAY ) ); + addBinding( new CPPImplicitConstructor( this, className, IParameter.EMPTY_PARAMETER_ARRAY ) ); ICPPClassType clsType = (ICPPClassType) compTypeSpec.getName().resolveBinding(); //copy constructor: A( const A & ) IType pType = new CPPReferenceType( new CPPQualifierType( clsType, true, false ) ); IParameter [] ps = new IParameter [] { new CPPParameter( pType ) }; - addBinding( new CPPImplicitConstructor( this, ps ) ); + addBinding( new CPPImplicitConstructor( this, className, ps ) ); //copy assignment operator: A& operator = ( const A & ) IType refType = new CPPReferenceType( clsType ); addBinding( new CPPImplicitMethod( this, "operator =".toCharArray(), refType, ps ) ); //$NON-NLS-1$ //destructor: ~A() - char [] dtorName = CharArrayUtils.concat( "~".toCharArray(), compTypeSpec.getName().toCharArray() ); //$NON-NLS-1$ + char [] dtorName = CharArrayUtils.concat( "~".toCharArray(), className ); //$NON-NLS-1$ addBinding( new CPPImplicitMethod( this, dtorName, new CPPBasicType( IBasicType.t_unspecified, 0 ), IParameter.EMPTY_PARAMETER_ARRAY ) ); } @@ -191,4 +193,17 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope { return true; } + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope#getClassType() + */ + public ICPPClassType getClassType() { + ICPPASTCompositeTypeSpecifier compSpec; + try { + compSpec = (ICPPASTCompositeTypeSpecifier) getPhysicalNode(); + } catch (DOMException e) { + return null; + } + return (ICPPClassType) compSpec.getName().resolveBinding(); + + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPImplicitConstructor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPImplicitConstructor.java index f335b903043..59ae88d885b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPImplicitConstructor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPImplicitConstructor.java @@ -28,8 +28,8 @@ public class CPPImplicitConstructor extends CPPImplicitMethod implements ICPPCon * @param name * @param params */ - public CPPImplicitConstructor( ICPPClassScope scope, IParameter[] params ) { - super( scope, CPPSemantics.EMPTY_NAME_ARRAY, new CPPBasicType( IBasicType.t_unspecified, 0 ), params ); + public CPPImplicitConstructor( ICPPClassScope scope, char [] name, IParameter[] params ) { + super( scope, name, new CPPBasicType( IBasicType.t_unspecified, 0 ), params ); } /* (non-Javadoc) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPImplicitMethod.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPImplicitMethod.java index c5495a3edf7..3bb1a7a48ac 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPImplicitMethod.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPImplicitMethod.java @@ -14,15 +14,22 @@ */ package org.eclipse.cdt.internal.core.dom.parser.cpp; +import org.eclipse.cdt.core.dom.ast.DOMException; +import org.eclipse.cdt.core.dom.ast.IASTDeclaration; +import org.eclipse.cdt.core.dom.ast.IASTDeclarator; +import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition; import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration; +import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IFunctionType; import org.eclipse.cdt.core.dom.ast.IParameter; import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope; +import org.eclipse.cdt.core.parser.util.CharArrayUtils; /** * @author aniefer @@ -52,9 +59,19 @@ public class CPPImplicitMethod extends CPPMethod { } public IFunctionType getType() { - if( type == null ) { - type = CPPVisitor.createImplicitFunctionType( returnType, parameters ); - } + if( type == null ){ + IASTDeclaration primary = null; + try { + primary = getPrimaryDeclaration(); + } catch (DOMException e) { + } + if( primary != null ){ + type = super.getType(); + } else { + type = CPPVisitor.createImplicitFunctionType( returnType, parameters ); + } + } + return type; } @@ -123,4 +140,61 @@ public class CPPImplicitMethod extends CPPMethod { } } } + + public IASTDeclaration getPrimaryDeclaration() throws DOMException{ + //first check if we already know it + if( declarations != null ){ + for( int i = 0; i < declarations.length; i++ ){ + IASTDeclaration decl = (IASTDeclaration) declarations[i].getParent(); + if( decl.getParent() instanceof ICPPASTCompositeTypeSpecifier ) + return decl; + } + } + + IFunctionType ftype = CPPVisitor.createImplicitFunctionType( returnType, parameters ); + IType [] params = ftype.getParameterTypes(); + + ICPPASTCompositeTypeSpecifier compSpec = (ICPPASTCompositeTypeSpecifier) scope.getPhysicalNode(); + IASTDeclaration [] members = compSpec.getMembers(); + for( int i = 0; i < members.length; i++ ){ + IASTDeclarator dtor = null; + IASTDeclarator [] ds = null; + int di = -1; + + if( members[i] instanceof IASTSimpleDeclaration ){ + ds = ((IASTSimpleDeclaration)members[i]).getDeclarators(); + } else if( members[i] instanceof IASTFunctionDefinition ){ + dtor = ((IASTFunctionDefinition) members[i]).getDeclarator(); + } + if( ds != null && ds.length > 0 ){ + di = 0; + dtor = ds[0]; + } + + while( dtor != null ){ + IASTName name = dtor.getName(); + if( dtor instanceof ICPPASTFunctionDeclarator && + CharArrayUtils.equals( name.toCharArray(), implicitName ) ) + { + IFunctionType t = (IFunctionType) CPPVisitor.createType( dtor ); + IType [] ps = t.getParameterTypes(); + if( ps.length == params.length ){ + int idx = 0; + for( ; idx < ps.length; idx++ ){ + if( !ps[idx].equals(params[idx]) ) + break; + } + if( idx == ps.length ){ + ((CPPASTName)name).setBinding( this ); + addDeclaration( (ICPPASTFunctionDeclarator) dtor ); + return members[i]; + } + + } + } + dtor = ( di > -1 && ++ di < ds.length ) ? ds[di] : null; + } + } + return null; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java index f367b3dd56f..4d464e12777 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java @@ -811,7 +811,10 @@ public class CPPSemantics { declaration = ((IASTForStatement)node).getInitDeclaration(); else if( node instanceof IASTParameterDeclaration && !data.typesOnly() ){ IASTParameterDeclaration parameterDeclaration = (IASTParameterDeclaration) node; - IASTName declName = parameterDeclaration.getDeclarator().getName(); + IASTDeclarator dtor = parameterDeclaration.getDeclarator(); + while( dtor.getNestedDeclarator() != null ) + dtor = dtor.getNestedDeclarator(); + IASTName declName = dtor.getName(); if( CharArrayUtils.equals( declName.toCharArray(), data.name ) ){ return declName; } @@ -825,6 +828,8 @@ public class CPPSemantics { IASTDeclarator [] declarators = simpleDeclaration.getDeclarators(); for( int i = 0; i < declarators.length; i++ ){ IASTDeclarator declarator = declarators[i]; + while( declarator.getNestedDeclarator() != null ) + declarator = declarator.getNestedDeclarator(); if( data.considerConstructors() || !CPPVisitor.isConstructor( scope, declarator ) ){ IASTName declaratorName = declarator.getName(); if( CharArrayUtils.equals( declaratorName.toCharArray(), data.name ) ){ @@ -906,7 +911,10 @@ public class CPPSemantics { for( int i = 0; i < parameters.length; i++ ){ IASTParameterDeclaration parameterDeclaration = parameters[i]; if( parameterDeclaration == null ) break; - declName = parameterDeclaration.getDeclarator().getName(); + IASTDeclarator dtor = parameterDeclaration.getDeclarator(); + while( dtor.getNestedDeclarator() != null ) + dtor = dtor.getNestedDeclarator(); + declName = dtor.getName(); if( CharArrayUtils.equals( declName.toCharArray(), data.name ) ){ return declName; } 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 cfb8a379b15..71d96bd864f 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 @@ -79,6 +79,7 @@ import org.eclipse.cdt.core.dom.ast.IFunction; import org.eclipse.cdt.core.dom.ast.IFunctionType; import org.eclipse.cdt.core.dom.ast.ILabel; import org.eclipse.cdt.core.dom.ast.IParameter; +import org.eclipse.cdt.core.dom.ast.IPointerType; import org.eclipse.cdt.core.dom.ast.IProblemBinding; import org.eclipse.cdt.core.dom.ast.IQualifierType; import org.eclipse.cdt.core.dom.ast.IScope; @@ -115,9 +116,11 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTypenameExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDeclaration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDirective; import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPBlockScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionScope; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace; import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier; @@ -125,6 +128,7 @@ import org.eclipse.cdt.core.dom.ast.gnu.IGNUASTCompoundStatementExpression; import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTSimpleDeclSpecifier; import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer; +import org.eclipse.cdt.internal.core.dom.parser.c.CPointerType; /** * @author aniefer @@ -1581,7 +1585,36 @@ public class CPPVisitor { return createType( type, id.getAbstractDeclarator() ); } else if( expression instanceof ICPPASTLiteralExpression ){ switch( ((ICPPASTLiteralExpression) expression).getKind() ){ - case ICPPASTLiteralExpression.lk_this : break; + case ICPPASTLiteralExpression.lk_this : { + IScope scope = getContainingScope( expression ); + try { + IASTNode node = null; + while( scope != null ){ + if( scope instanceof ICPPBlockScope ){ + node = ((ICPPBlockScope)scope).getPhysicalNode(); + if( node.getParent() instanceof IASTFunctionDefinition ) + break; + } + scope = scope.getParent(); + } + if( node != null && node.getParent() instanceof IASTFunctionDefinition ){ + IASTFunctionDefinition def = (IASTFunctionDefinition) node.getParent(); + IASTName fName = def.getDeclarator().getName(); + IBinding binding = fName.resolveBinding(); + if( binding != null && binding instanceof ICPPMethod ){ + ICPPASTFunctionDeclarator dtor = (ICPPASTFunctionDeclarator) def.getDeclarator(); + ICPPClassScope cScope = (ICPPClassScope) binding.getScope(); + IType type = cScope.getClassType(); + if( dtor.isConst() || dtor.isVolatile() ) + type = new CPPQualifierType(type, dtor.isConst(), dtor.isVolatile() ); + type = new CPPPointerType( type ); + return type; + } + } + } catch (DOMException e) { + } + break; + } case ICPPASTLiteralExpression.lk_true : case ICPPASTLiteralExpression.lk_false: return new CPPBasicType( ICPPBasicType.t_bool, 0 ); @@ -1612,8 +1645,18 @@ public class CPPVisitor { } else if( expression instanceof IASTUnaryExpression ) { - if( ((IASTUnaryExpression)expression).getOperator() == IASTUnaryExpression.op_bracketedPrimary ) - return getExpressionType(((IASTUnaryExpression)expression).getOperand() ); + IType type = getExpressionType(((IASTUnaryExpression)expression).getOperand() ); + int op = ((IASTUnaryExpression)expression).getOperator(); + if( op == IASTUnaryExpression.op_star && (type instanceof IPointerType || type instanceof IArrayType) ){ + try { + return ((ITypeContainer)type).getType(); + } catch (DOMException e) { + return e.getProblem(); + } + } else if( op == IASTUnaryExpression.op_amper ){ + return new CPointerType( type ); + } + return type; } return null; }