1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-24 09:25:31 +02:00

fix 84250, 84705, 84710,

expression type for ICPPASTLiteralExpression.lk_this
This commit is contained in:
Andrew Niefer 2005-02-09 21:28:05 +00:00
parent 753fe63759
commit 675667f94d
8 changed files with 241 additions and 24 deletions

View file

@ -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$
}
}

View file

@ -17,5 +17,5 @@ package org.eclipse.cdt.core.dom.ast.cpp;
* @author aniefer
*/
public interface ICPPClassScope extends ICPPScope {
ICPPClassType getClassType();
}

View file

@ -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);
}
/*

View file

@ -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();
}
}

View file

@ -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)

View file

@ -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;
}
}

View file

@ -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;
}

View file

@ -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;
}