1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

fix up CPPSemantics.declaredBefore & resolving typedefs

also:
90654 - conversion operators
90653 - overloaded operators
86618 - conversion of string literal (const char *) to char *
This commit is contained in:
Andrew Niefer 2005-04-15 14:43:29 +00:00
parent 81d46bfbf6
commit 21c09e5d0f
16 changed files with 453 additions and 260 deletions

View file

@ -581,47 +581,6 @@ public class AST2CPPSpecFailingTest extends AST2SpecBaseTest {
}
}
/**
[--Start Example(CPP 12.3-4):
class X {
// ...
public:
operator int();
};
class Y {
// ...
public:
operator X();
};
Y a;
int b = a; // error:
// a.operator X().operator int() not tried
int c = X(a); // OK: a.operator X().operator int()
--End Example]
*/
public void test12_3s4() { // TODO raised bug 90654
StringBuffer buffer = new StringBuffer();
buffer.append("class X {\n"); //$NON-NLS-1$
buffer.append("// ...\n"); //$NON-NLS-1$
buffer.append("public:\n"); //$NON-NLS-1$
buffer.append("operator int();\n"); //$NON-NLS-1$
buffer.append("};\n"); //$NON-NLS-1$
buffer.append("class Y {\n"); //$NON-NLS-1$
buffer.append("// ...\n"); //$NON-NLS-1$
buffer.append("public:\n"); //$NON-NLS-1$
buffer.append("operator X();\n"); //$NON-NLS-1$
buffer.append("};\n"); //$NON-NLS-1$
buffer.append("Y a;\n"); //$NON-NLS-1$
buffer.append("int b = a; // error:\n"); //$NON-NLS-1$
buffer.append("// a.operator X().operator int() not tried\n"); //$NON-NLS-1$
buffer.append("int c = X(a); // OK: a.operator X().operator int()\n"); //$NON-NLS-1$
try {
parse(buffer.toString(), ParserLanguage.CPP, false, true);
assertTrue(false);
} catch (Exception e) {
}
}
/**
[--Start Example(CPP 12.7-2):
struct A { };
@ -669,33 +628,6 @@ public class AST2CPPSpecFailingTest extends AST2SpecBaseTest {
}
}
/**
[--Start Example(CPP 13.3.3.2-3c):
struct A {
operator short();
} a;
int f(int);
int f(float);
int i = f(a); // Calls f(int), because short ® int is
// better than short ® float.
--End Example]
*/
public void test13_3_3_2s3c() { // TODO raised bug 90667
StringBuffer buffer = new StringBuffer();
buffer.append("struct A {\n"); //$NON-NLS-1$
buffer.append("operator short();\n"); //$NON-NLS-1$
buffer.append("} a;\n"); //$NON-NLS-1$
buffer.append("int f(int);\n"); //$NON-NLS-1$
buffer.append("int f(float);\n"); //$NON-NLS-1$
buffer.append("int i = f(a); // Calls f(int), because short ® int is\n"); //$NON-NLS-1$
buffer.append("// better than short ® float.\n"); //$NON-NLS-1$
try {
parse(buffer.toString(), ParserLanguage.CPP, true, true);
assertTrue(false);
} catch (Exception e) {
}
}
/**
[--Start Example(CPP 13.4-5a):
int f(double);
@ -1264,53 +1196,6 @@ public class AST2CPPSpecFailingTest extends AST2SpecBaseTest {
}
}
/**
[--Start Example(CPP 14.7.1-10):
namespace N {
template<class T> class List {
public:
T* get();
// ...
};
}
template<class K, class V> class Map {
N::List<V> lt;
V get(K);
// ...
};
void g(Map<char*,int>& m)
{
int i = m.get("Nicholas");
// ...
}
--End Example]
*/
public void test14_7_1s10() { // TODO already have similar bug
StringBuffer buffer = new StringBuffer();
buffer.append("namespace N {\n"); //$NON-NLS-1$
buffer.append("template<class T> class List {\n"); //$NON-NLS-1$
buffer.append("public:\n"); //$NON-NLS-1$
buffer.append("T* get();\n"); //$NON-NLS-1$
buffer.append("// ...\n"); //$NON-NLS-1$
buffer.append("};\n"); //$NON-NLS-1$
buffer.append("}\n"); //$NON-NLS-1$
buffer.append("template<class K, class V> class Map {\n"); //$NON-NLS-1$
buffer.append("N::List<V> lt;\n"); //$NON-NLS-1$
buffer.append("V get(K);\n"); //$NON-NLS-1$
buffer.append("// ...\n"); //$NON-NLS-1$
buffer.append("};\n"); //$NON-NLS-1$
buffer.append("void g(Map<char*,int>& m)\n"); //$NON-NLS-1$
buffer.append("{\n"); //$NON-NLS-1$
buffer.append("int i = m.get(\"Nicholas\");\n"); //$NON-NLS-1$
buffer.append("// ...\n"); //$NON-NLS-1$
buffer.append("}\n"); //$NON-NLS-1$
try {
parse(buffer.toString(), ParserLanguage.CPP, true, true);
assertTrue(false);
} catch (Exception e) {
}
}
/**
[--Start Example(CPP 14.7.1-14):
template<class T> class X {

View file

@ -6519,6 +6519,44 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest {
parse(buffer.toString(), ParserLanguage.CPP, true, true);
}
/**
[--Start Example(CPP 12.3-4):
class X {
// ...
public:
operator int();
};
class Y {
// ...
public:
operator X();
};
Y a;
int b = a; // error:
// a.operator X().operator int() not tried
int c = X(a); // OK: a.operator X().operator int()
--End Example]
*/
public void test12_3s4() throws Exception {
StringBuffer buffer = new StringBuffer();
buffer.append("class X {\n"); //$NON-NLS-1$
buffer.append("// ...\n"); //$NON-NLS-1$
buffer.append("public:\n"); //$NON-NLS-1$
buffer.append("operator int();\n"); //$NON-NLS-1$
buffer.append("};\n"); //$NON-NLS-1$
buffer.append("class Y {\n"); //$NON-NLS-1$
buffer.append("// ...\n"); //$NON-NLS-1$
buffer.append("public:\n"); //$NON-NLS-1$
buffer.append("operator X();\n"); //$NON-NLS-1$
buffer.append("};\n"); //$NON-NLS-1$
buffer.append("Y a;\n"); //$NON-NLS-1$
buffer.append("int b = a; // error:\n"); //$NON-NLS-1$
buffer.append("// a.operator X().operator int() not tried\n"); //$NON-NLS-1$
buffer.append("int c = X(a); // OK: a.operator X().operator int()\n"); //$NON-NLS-1$
parse(buffer.toString(), ParserLanguage.CPP, false, true);
}
/**
[--Start Example(CPP 12.3-5):
class X {
@ -8140,6 +8178,30 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest {
parse(buffer.toString(), ParserLanguage.CPP, false, true);
}
/**
[--Start Example(CPP 13.3.3.2-3c):
struct A {
operator short();
} a;
int f(int);
int f(float);
int i = f(a); // Calls f(int), because short ® int is
// better than short ® float.
--End Example]
*/
public void test13_3_3_2s3c() throws Exception {
StringBuffer buffer = new StringBuffer();
buffer.append("struct A {\n"); //$NON-NLS-1$
buffer.append("operator short();\n"); //$NON-NLS-1$
buffer.append("} a;\n"); //$NON-NLS-1$
buffer.append("int f(int);\n"); //$NON-NLS-1$
buffer.append("int f(float);\n"); //$NON-NLS-1$
buffer.append("int i = f(a); // Calls f(int), because short -> int is\n"); //$NON-NLS-1$
buffer.append("// better than short -> float.\n"); //$NON-NLS-1$
parse(buffer.toString(), ParserLanguage.CPP, true, true);
}
/**
[--Start Example(CPP 13.3.3.2-4):
struct A {};
@ -9828,6 +9890,50 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest {
parse(buffer.toString(), ParserLanguage.CPP, true, true);
}
/**
[--Start Example(CPP 14.7.1-10):
namespace N {
template<class T> class List {
public:
T* get();
// ...
};
}
template<class K, class V> class Map {
N::List<V> lt;
V get(K);
// ...
};
void g(Map<char*,int>& m)
{
int i = m.get("Nicholas");
// ...
}
--End Example]
*/
public void test14_7_1s10() throws Exception {
StringBuffer buffer = new StringBuffer();
buffer.append("namespace N {\n"); //$NON-NLS-1$
buffer.append("template<class T> class List {\n"); //$NON-NLS-1$
buffer.append("public:\n"); //$NON-NLS-1$
buffer.append("T* get();\n"); //$NON-NLS-1$
buffer.append("// ...\n"); //$NON-NLS-1$
buffer.append("};\n"); //$NON-NLS-1$
buffer.append("}\n"); //$NON-NLS-1$
buffer.append("template<class K, class V> class Map {\n"); //$NON-NLS-1$
buffer.append("N::List<V> lt;\n"); //$NON-NLS-1$
buffer.append("V get(K);\n"); //$NON-NLS-1$
buffer.append("// ...\n"); //$NON-NLS-1$
buffer.append("};\n"); //$NON-NLS-1$
buffer.append("void g(Map<char*,int>& m)\n"); //$NON-NLS-1$
buffer.append("{\n"); //$NON-NLS-1$
buffer.append("int i = m.get(\"Nicholas\");\n"); //$NON-NLS-1$
buffer.append("// ...\n"); //$NON-NLS-1$
buffer.append("}\n"); //$NON-NLS-1$
parse(buffer.toString(), ParserLanguage.CPP, true, true);
}
/**
[--Start Example(CPP 14.7.1-12):
template<class T> void f(T x, T y = ydef(T()), T z = zdef(T()));

View file

@ -3549,7 +3549,7 @@ public class AST2CPPTests extends AST2BaseTest {
assertTrue( I8.getType() instanceof IBasicType );
assertEquals( ((IBasicType)I8.getType()).getType(), IBasicType.t_char );
}
public void testBug90623_2() throws Exception {
StringBuffer buffer = new StringBuffer();
buffer.append( "typedef int I; \n"); //$NON-NLS-1$
@ -3563,5 +3563,84 @@ public class AST2CPPTests extends AST2BaseTest {
IASTName f = col.getName( 5 );
f.resolvePrefix();
}
public void testBug90654_1() throws Exception {
StringBuffer buffer = new StringBuffer();
buffer.append("class X { \n"); //$NON-NLS-1$
buffer.append(" X( const X & ); \n"); //$NON-NLS-1$
buffer.append("}; \n"); //$NON-NLS-1$
buffer.append("class Y { \n"); //$NON-NLS-1$
buffer.append(" operator X (); \n"); //$NON-NLS-1$
buffer.append("}; \n"); //$NON-NLS-1$
buffer.append("Y y; \n"); //$NON-NLS-1$
buffer.append("X x = new X( y ); \n"); //$NON-NLS-1$
IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.CPP ); //$NON-NLS-1$
CPPNameCollector col = new CPPNameCollector();
tu.accept( col );
ICPPConstructor ctor1 = (ICPPConstructor) col.getName(1).resolveBinding();
ICPPConstructor ctor = (ICPPConstructor) col.getName(11).resolveBinding();
assertSame( ctor, ctor1 );
}
public void testBug90654_2() throws Exception {
StringBuffer buffer = new StringBuffer();
buffer.append("struct A { \n"); //$NON-NLS-1$
buffer.append(" operator short(); \n"); //$NON-NLS-1$
buffer.append("} a; \n"); //$NON-NLS-1$
buffer.append("int f( int ); \n"); //$NON-NLS-1$
buffer.append("int f( float ); \n"); //$NON-NLS-1$
buffer.append("int x = f(a); \n"); //$NON-NLS-1$
IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.CPP ); //$NON-NLS-1$
CPPNameCollector col = new CPPNameCollector();
tu.accept( col );
IFunction f1 = (IFunction) col.getName(3).resolveBinding();
IFunction f2 = (IFunction) col.getName(8).resolveBinding();
assertSame( f1, f2 );
}
public void testBug90653() throws Exception {
StringBuffer buffer = new StringBuffer();
buffer.append("struct A {}; \n"); //$NON-NLS-1$
buffer.append("struct B : public A { \n"); //$NON-NLS-1$
buffer.append(" B& operator = (const B & ); \n"); //$NON-NLS-1$
buffer.append("}; \n"); //$NON-NLS-1$
buffer.append("B& B::operator = (const B & s){ \n"); //$NON-NLS-1$
buffer.append(" this->A::operator=(s); \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 ); //$NON-NLS-1$
CPPNameCollector col = new CPPNameCollector();
tu.accept( col );
ICPPClassType A = (ICPPClassType) col.getName(0).resolveBinding();
ICPPMethod implicit = A.getMethods()[2];
ICPPMethod op1 = (ICPPMethod) col.getName(4).resolveBinding();
ICPPMethod op2 = (ICPPMethod) col.getName(10).resolveBinding();
ICPPMethod op = (ICPPMethod) col.getName(15).resolveBinding();
assertSame( op1, op2 );
assertSame( op, implicit );
}
public void testBug86618() throws Exception {
StringBuffer buffer = new StringBuffer();
buffer.append("void f( char * ); \n"); //$NON-NLS-1$
buffer.append("void foo() { \n"); //$NON-NLS-1$
buffer.append(" f( \"test\" ); \n"); //$NON-NLS-1$
buffer.append("} \n"); //$NON-NLS-1$
IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.CPP ); //$NON-NLS-1$
CPPNameCollector col = new CPPNameCollector();
tu.accept( col );
IFunction f = (IFunction) col.getName(0).resolveBinding();
assertInstances( col, f, 2 );
}
}

View file

@ -1,5 +1,5 @@
/**********************************************************************
* Copyright (c) 2004 IBM Corporation and others.
* Copyright (c) 2004, 2005 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
@ -15,5 +15,5 @@ package org.eclipse.cdt.core.dom.ast.cpp;
* @author Doug Schaefer
*/
public interface ICPPMethod extends ICPPFunction, ICPPMember {
public static final ICPPMethod [] EMPTY_CPPMETHOD_ARRAY = new ICPPMethod[0];
}

View file

@ -39,7 +39,7 @@ import org.eclipse.cdt.core.parser.util.ObjectMap;
* @author aniefer
*/
public class CPPClassTemplate extends CPPTemplateDefinition implements
ICPPClassTemplate, ICPPClassType, ICPPInternalBinding {
ICPPClassTemplate, ICPPClassType, ICPPInternalClassType {
/**
* @param decl
@ -228,4 +228,11 @@ public class CPPClassTemplate extends CPPTemplateDefinition implements
}
return null;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalClassType#getConversionOperators()
*/
public ICPPMethod[] getConversionOperators() {
return ICPPMethod.EMPTY_CPPMETHOD_ARRAY;
}
}

View file

@ -31,6 +31,7 @@ import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.CPPASTVisitor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConversionName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTElaboratedTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
@ -50,13 +51,14 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBas
import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.core.parser.util.ObjectSet;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
/**
* @author aniefer
*/
public class CPPClassType implements ICPPClassType, ICPPInternalBinding {
public static class CPPClassTypeDelegate extends CPPDelegate implements ICPPClassType {
public class CPPClassType implements ICPPClassType, ICPPInternalClassType {
public static class CPPClassTypeDelegate extends CPPDelegate implements ICPPClassType, ICPPInternalClassType {
public CPPClassTypeDelegate( IASTName name, ICPPClassType cls ){
super( name, cls );
}
@ -96,6 +98,15 @@ public class CPPClassType implements ICPPClassType, ICPPInternalBinding {
public Object clone() {
return ((ICPPClassType)getBinding()).clone();
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalClassType#getConversionOperators()
*/
public ICPPMethod[] getConversionOperators() {
IBinding binding = getBinding();
if( binding instanceof ICPPInternalClassType )
return ((ICPPInternalClassType)binding).getConversionOperators();
return ICPPMethod.EMPTY_CPPMETHOD_ARRAY;
}
}
public static class CPPClassTypeProblem extends ProblemBinding implements ICPPClassType{
public CPPClassTypeProblem( IASTNode node, int id, char[] arg ) {
@ -351,22 +362,22 @@ public class CPPClassType implements ICPPClassType, ICPPInternalBinding {
public void addDeclaration( IASTNode node ) {
if( !(node instanceof ICPPASTElaboratedTypeSpecifier) )
return;
ICPPASTElaboratedTypeSpecifier elabSpec = (ICPPASTElaboratedTypeSpecifier) node;
IASTName name = ((ICPPASTElaboratedTypeSpecifier) node).getName();
if( declarations == null ){
declarations = new IASTName[] { elabSpec.getName() };
declarations = new IASTName[] { name };
return;
}
for( int i = 0; i < declarations.length; i++ ){
if( declarations[i] == null ){
declarations[i] = elabSpec.getName();
return;
}
}
IASTName tmp [] = new IASTName[ declarations.length * 2 ];
System.arraycopy( declarations, 0, tmp, 0, declarations.length );
tmp[ declarations.length ] = elabSpec.getName();
declarations = tmp;
//keep the lowest offset declaration in [0]
if( declarations.length > 0 && ((ASTNode)node).getOffset() < ((ASTNode)declarations[0]).getOffset() ){
IASTName temp = declarations[0];
declarations[0] = name;
node = temp;
}
declarations = (IASTName[]) ArrayUtil.append( IASTName.class, declarations, name );
}
/* (non-Javadoc)
@ -431,6 +442,56 @@ public class CPPClassType implements ICPPClassType, ICPPInternalBinding {
}
return (ICPPField[]) ArrayUtil.trim( ICPPField.class, result );
}
public ICPPMethod[] getConversionOperators() {
if( definition == null ){
checkForDefinition();
if( definition == null ){
IASTNode node = (declarations != null && declarations.length > 0) ? declarations[0] : null;
return new ICPPMethod[] { new CPPMethod.CPPMethodProblem( node, IProblemBinding.SEMANTIC_DEFINITION_NOT_FOUND, getNameCharArray() ) };
}
}
IBinding binding = null;
ICPPMethod [] result = null;
IASTDeclaration [] decls = getCompositeTypeSpecifier().getMembers();
IASTName name = null;
for ( int i = 0; i < decls.length; i++ ) {
if( decls[i] instanceof IASTSimpleDeclaration ){
IASTDeclarator [] dtors = ((IASTSimpleDeclaration)decls[i]).getDeclarators();
for ( int j = 0; j < dtors.length; j++ ) {
name = CPPVisitor.getMostNestedDeclarator( dtors[j] ).getName();
if( name instanceof ICPPASTConversionName ){
binding = name.resolveBinding();
if( binding instanceof ICPPMethod)
result = (ICPPMethod[]) ArrayUtil.append( ICPPMethod.class, result, binding );
}
}
} else if( decls[i] instanceof IASTFunctionDefinition ){
IASTDeclarator dtor = ((IASTFunctionDefinition)decls[i]).getDeclarator();
name = CPPVisitor.getMostNestedDeclarator( dtor ).getName();
if( name instanceof ICPPASTConversionName ){
binding = name.resolveBinding();
if( binding instanceof ICPPMethod ){
result = (ICPPMethod[]) ArrayUtil.append( ICPPMethod.class, result, binding );
}
}
}
}
ICPPBase [] bases = getBases();
for ( int i = 0; i < bases.length; i++ ) {
ICPPClassType cls;
try {
cls = bases[i].getBaseClass();
} catch (DOMException e) {
continue;
}
if( cls instanceof CPPClassType )
result = (ICPPMethod[]) ArrayUtil.addAll( ICPPMethod.class, result, ((CPPClassType)cls).getConversionOperators() );
}
return (ICPPMethod[]) ArrayUtil.trim( ICPPMethod.class, result );
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType#getMethods()

View file

@ -36,6 +36,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPDelegate;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
/**
@ -174,26 +175,23 @@ public class CPPFunction implements ICPPFunction, ICPPInternalBinding {
node = node.getParent();
if( !(node instanceof ICPPASTFunctionDeclarator) )
return;
ICPPASTFunctionDeclarator dtor = (ICPPASTFunctionDeclarator) node;
updateParameterBindings( dtor );
if( declarations == null ){
declarations = new ICPPASTFunctionDeclarator [] { dtor };
return;
}
for( int i = 0; i < declarations.length; i++ ){
if( declarations[i] == dtor ){
//already in
return;
} else if( declarations[i] == null ){
declarations[i] = dtor;
updateParameterBindings( dtor );
return;
}
//keep the lowest offset declaration in [0]
if( declarations.length > 0 && ((ASTNode)node).getOffset() < ((ASTNode)declarations[0]).getOffset() ){
ICPPASTFunctionDeclarator temp = declarations[0];
declarations[0] = dtor;
dtor = temp;
}
ICPPASTFunctionDeclarator [] tmp = new ICPPASTFunctionDeclarator[ declarations.length * 2 ];
System.arraycopy( declarations, 0, tmp, 0, declarations.length );
tmp[ declarations.length ] = dtor;
declarations = tmp;
declarations = (ICPPASTFunctionDeclarator[]) ArrayUtil.append( ICPPASTFunctionDeclarator.class, declarations, dtor );
}
/* (non-Javadoc)

View file

@ -32,6 +32,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceScope;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
/**
* @author aniefer
@ -221,8 +222,22 @@ public class CPPNamespace implements ICPPNamespace, ICPPInternalBinding {
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding#addDefinition(org.eclipse.cdt.core.dom.ast.IASTNode)
*/
public void addDefinition(IASTNode node) {
if( node instanceof IASTName )
namespaceDefinitions = (IASTName[]) ArrayUtil.append( IASTName.class, namespaceDefinitions, node );
if( !(node instanceof IASTName) )
return;
IASTName name = (IASTName) node;
if( namespaceDefinitions == null ){
namespaceDefinitions = new IASTName[] { name };
return;
}
if( namespaceDefinitions.length > 0 && ((ASTNode)name).getOffset() < ((ASTNode)namespaceDefinitions[0]).getOffset() ){
IASTName temp = namespaceDefinitions[0];
namespaceDefinitions[0] = name;
name = temp;
}
namespaceDefinitions = (IASTName[]) ArrayUtil.append( IASTName.class, namespaceDefinitions, name );
}
/* (non-Javadoc)

View file

@ -24,6 +24,7 @@ import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPDelegate;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariable;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
/**
* @author aniefer
@ -75,16 +76,8 @@ public class CPPParameter implements IParameter, ICPPInternalBinding, ICPPVariab
declarations = new IASTName [] { name };
return;
}
for( int i = 0; i < declarations.length; i++ ){
if( declarations[i] == null ){
declarations[i] = name;
return;
}
}
IASTName [] tmp = new IASTName[ declarations.length * 2 ];
System.arraycopy( declarations, 0, tmp, 0, declarations.length );
tmp[ declarations.length ] = name;
declarations = tmp;
declarations = (IASTName[]) ArrayUtil.append( IASTName.class, declarations, name );
}
private IASTName getPrimaryDeclaration(){
@ -186,7 +179,6 @@ public class CPPParameter implements IParameter, ICPPInternalBinding, ICPPVariab
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding#addDefinition(org.eclipse.cdt.core.dom.ast.IASTNode)
*/
public void addDefinition(IASTNode node) {
// TODO Auto-generated method stub
addDeclaration( node );
}
}

View file

@ -25,6 +25,7 @@ import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer;
public class CPPQualifierType implements IQualifierType, ITypeContainer {
private boolean isConst = false;
private boolean isVolatile = false;
private boolean fromStringLiteral = false;
private IType type = null;
public CPPQualifierType( IType type, boolean isConst, boolean isVolatile ){
@ -79,4 +80,15 @@ public class CPPQualifierType implements IQualifierType, ITypeContainer {
}
return t;
}
/**
* @return
*/
public boolean fromStringLiteral() {
return fromStringLiteral;
}
public void setFromStringLiteral( boolean fromString ){
fromStringLiteral = fromString;
}
}

View file

@ -33,6 +33,7 @@ import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression;
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.IASTInitializer;
import org.eclipse.cdt.core.dom.ast.IASTInitializerExpression;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNamedTypeSpecifier;
@ -1363,20 +1364,13 @@ public class CPPSemantics {
if( obj instanceof ICPPInternalBinding ){
ICPPInternalBinding cpp = (ICPPInternalBinding) obj;
IASTNode[] n = cpp.getDeclarations();
int o, offset = -1;
if( n != null && n.length > 0 ) {
nd = (ASTNode) n[0];
offset = ((ASTNode) n[0]).getOffset();
for (int i = 1; i < n.length && n[i] != null; i++) {
o = ((ASTNode) n[i]).getOffset();
if( o < offset )
nd = (ASTNode) n[i];
}
}
if( cpp.getDefinition() != null ){
if( nd == null || ((ASTNode)cpp.getDefinition()).getOffset() < nd.getOffset() )
nd = (ASTNode) cpp.getDefinition();
}
ASTNode def = (ASTNode) cpp.getDefinition();
if( def != null ){
if( nd == null || def.getOffset() < nd.getOffset() )
nd = def;
}
if( nd == null )
return true;
@ -1384,21 +1378,22 @@ public class CPPSemantics {
nd = (ASTNode) obj;
}
//avoid recursive loops in case of a malformed AST by requiring the decl of the type of a function parameter
//to occur before the start of that function's declarator.
if( node instanceof IASTName && node.getPropertyInParent() == IASTNamedTypeSpecifier.NAME ) {
IASTNode n = node.getParent();
if( n.getPropertyInParent() == IASTParameterDeclaration.DECL_SPECIFIER ){
node = (ASTNode) n.getParent().getParent(); //parent is param, parent.parent is fnDtor
}
}
if( nd != null ){
int pointOfDecl = 0;
ASTNodeProperty prop = nd.getPropertyInParent();
if( prop == IASTDeclarator.DECLARATOR_NAME ){
pointOfDecl = nd.getOffset() + nd.getLength();
} else if( prop == IASTEnumerator.ENUMERATOR_NAME) {
//point of declaration for a name is immediately after its complete declarator and before its initializer
if( prop == IASTDeclarator.DECLARATOR_NAME || nd instanceof IASTDeclarator ){
IASTDeclarator dtor = (IASTDeclarator)((nd instanceof IASTDeclarator) ? nd : nd.getParent());
while( dtor.getParent() instanceof IASTDeclarator )
dtor = (IASTDeclarator) dtor.getParent();
IASTInitializer init = dtor.getInitializer();
if( init != null )
pointOfDecl = ((ASTNode)init).getOffset() - 1;
else
pointOfDecl = ((ASTNode)dtor).getOffset() + ((ASTNode)dtor).getLength();
}
//point of declaration for an enumerator is immediately after it enumerator-definition
else if( prop == IASTEnumerator.ENUMERATOR_NAME) {
IASTEnumerator enumtor = (IASTEnumerator) nd.getParent();
if( enumtor.getValue() != null ){
ASTNode exp = (ASTNode) enumtor.getValue();
@ -1410,7 +1405,7 @@ public class CPPSemantics {
nd = (ASTNode) nd.getParent();
pointOfDecl = nd.getOffset() + nd.getLength();
} else
pointOfDecl = nd.getOffset();
pointOfDecl = nd.getOffset() + nd.getLength();
return ( pointOfDecl < ((ASTNode)node).getOffset() );
@ -2128,32 +2123,38 @@ public class CPPSemantics {
constructor = (ICPPConstructor) binding;
}
}
if( constructor != null && constructor.isExplicit() ){
constructor = null;
if( constructor != null && !constructor.isExplicit() ){
constructorCost = checkStandardConversionSequence( t, target );
}
}
//conversion operators
if( s instanceof ICPPClassType ){
char[] name = EMPTY_NAME_ARRAY;//TODO target.toCharArray();
if( !CharArrayUtils.equals( name, EMPTY_NAME_ARRAY) ){
LookupData data = new LookupData( CharArrayUtils.concat( OPERATOR_, name ));
data.functionParameters = IASTExpression.EMPTY_EXPRESSION_ARRAY;
data.forUserDefinedConversion = true;
ICPPScope scope = (ICPPScope) ((ICPPClassType) s).getCompositeScope();
data.foundItems = lookupInScope( data, scope, null );
IBinding [] fns = (IBinding[]) ArrayUtil.append( IBinding.class, null, data.foundItems );
conversion = (ICPPMethod) ( (data.foundItems != null ) ? resolveFunction( data, fns ) : null );
if( s instanceof ICPPInternalClassType ){
ICPPMethod [] ops = ((ICPPInternalClassType)s).getConversionOperators();
Cost [] costs = null;
for (int i = 0; i < ops.length; i++) {
cost = checkStandardConversionSequence( ops[i].getType().getReturnType(), target );
if( cost.rank != Cost.NO_MATCH_RANK )
costs = (Cost[]) ArrayUtil.append( Cost.class, costs, cost );
}
if( costs != null ){
Cost best = costs[0];
boolean bestIsBest = true;
int bestIdx = 0;
for (int i = 1; i < costs.length && costs[i] != null; i++) {
int comp = best.compare( costs[i] );
if( comp == 0 )
bestIsBest = false;
else if( comp > 0 ){
best = costs[ bestIdx = i ];
bestIsBest = true;
}
}
if( bestIsBest ){
conversion = ops[ bestIdx ];
conversionCost = best;
}
}
}
if( constructor != null ){
constructorCost = checkStandardConversionSequence( t, target );
}
if( conversion != null ){
conversionCost = checkStandardConversionSequence( conversion.getType().getReturnType(), target );
}
//if both are valid, then the conversion is ambiguous
@ -2284,8 +2285,14 @@ public class CPPSemantics {
if( s instanceof IQualifierType ^ t instanceof IQualifierType ){
if( t instanceof IQualifierType )
canConvert = true;
else
canConvert = false;
else {
//4.2-2 a string literal can be converted to pointer to char
if( t instanceof IBasicType && ((IBasicType)t).getType() == IBasicType.t_char &&
s instanceof CPPQualifierType && ((CPPQualifierType)s).fromStringLiteral() )
canConvert = true;
else
canConvert = false;
}
} else if( s instanceof IQualifierType && t instanceof IQualifierType ){
IQualifierType qs = (IQualifierType) s, qt = (IQualifierType) t;
if( qs.isConst() && !qt.isConst() || qs.isVolatile() && !qt.isVolatile() )
@ -2327,13 +2334,15 @@ public class CPPSemantics {
int tType = ((IBasicType)trg).getType();
if( ( tType == IBasicType.t_int && ( sType == IBasicType.t_char ||
sType == ICPPBasicType.t_bool ||
sType == ICPPBasicType.t_wchar_t ) ) ||
sType == ICPPBasicType.t_wchar_t ||
sType == IBasicType.t_unspecified ) ) || //treat unspecified as int
( tType == IBasicType.t_double && sType == IBasicType.t_float ) )
{
cost.promotion = 1;
}
} else if( src instanceof IEnumeration && trg instanceof IBasicType &&
((IBasicType) trg).getType() == IBasicType.t_int )
( ((IBasicType)trg).getType() == IBasicType.t_int ||
((IBasicType)trg).getType() == IBasicType.t_unspecified ) )
{
cost.promotion = 1;
}
@ -2453,8 +2462,11 @@ public class CPPSemantics {
}
public static IBinding[] findBindings( IScope scope, String name, boolean qualified ) throws DOMException{
return findBindings( scope, name.toCharArray(), qualified );
}
public static IBinding[] findBindings( IScope scope, char []name, boolean qualified ) throws DOMException{
CPPASTName astName = new CPPASTName();
astName.setName( name.toCharArray() );
astName.setName( name );
astName.setParent( scope.getPhysicalNode() );
astName.setPropertyInParent( STRING_LOOKUP_PROPERTY );

View file

@ -23,6 +23,8 @@ import org.eclipse.cdt.core.dom.ast.ITypedef;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBinding;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBlockScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPDelegate;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer;
/**
@ -44,31 +46,29 @@ public class CPPTypedef implements ITypedef, ITypeContainer, ICPPInternalBinding
return null;
}
}
private IASTName typedefName = null;
private IASTName [] declarations = null;
private IType type = null;
/**
* @param declarator
*/
public CPPTypedef(IASTName name) {
this.typedefName = name;
this.declarations = new IASTName[] { name };
name.setBinding( this );
// TODO Auto-generated constructor stub
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPBinding#getDeclarations()
*/
public IASTNode[] getDeclarations() {
return null;
return declarations;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPBinding#getDefinition()
*/
public IASTNode getDefinition() {
return typedefName;
return declarations[0];
}
public boolean equals( Object o ){
@ -98,13 +98,7 @@ public class CPPTypedef implements ITypedef, ITypeContainer, ICPPInternalBinding
*/
public IType getType() {
if( type == null ){
type = CPPVisitor.createType( (IASTDeclarator) typedefName.getParent() );
// if( type instanceof ITypedef ){
// try {
// type = ((ITypedef)type).getType();
// } catch ( DOMException e ) {
// }
// }
type = CPPVisitor.createType( (IASTDeclarator) declarations[0].getParent() );
}
return type;
}
@ -117,30 +111,23 @@ public class CPPTypedef implements ITypedef, ITypeContainer, ICPPInternalBinding
* @see org.eclipse.cdt.core.dom.ast.IBinding#getName()
*/
public String getName() {
return typedefName.toString();
return declarations[0].toString();
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IBinding#getNameCharArray()
*/
public char[] getNameCharArray() {
return typedefName.toCharArray();
return declarations[0].toCharArray();
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IBinding#getScope()
*/
public IScope getScope() {
return CPPVisitor.getContainingScope( typedefName.getParent() );
return CPPVisitor.getContainingScope( declarations[0].getParent() );
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IBinding#getPhysicalNode()
*/
public IASTNode getPhysicalNode() {
return typedefName;
}
public Object clone(){
IType t = null;
try {
@ -188,16 +175,27 @@ public class CPPTypedef implements ITypedef, ITypeContainer, ICPPInternalBinding
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding#addDefinition(org.eclipse.cdt.core.dom.ast.IASTNode)
*/
public void addDefinition(IASTNode node) {
// TODO Auto-generated method stub
addDeclaration( node );
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding#addDeclaration(org.eclipse.cdt.core.dom.ast.IASTNode)
*/
public void addDeclaration(IASTNode node) {
// TODO Auto-generated method stub
}
if( !(node instanceof IASTName) )
return;
IASTName name = (IASTName) node;
if( declarations == null )
declarations = new IASTName[] { name };
else {
//keep the lowest offset declaration in [0]
if( declarations.length > 0 && ((ASTNode)node).getOffset() < ((ASTNode)declarations[0]).getOffset() ){
IASTName temp = declarations[0];
declarations[0] = name;
name = temp;
}
declarations = (IASTName[]) ArrayUtil.append( IASTName.class, declarations, name );
}
}
}

View file

@ -27,6 +27,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPBlockScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPDelegate;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariable;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
/**
@ -119,8 +120,17 @@ public class CPPVariable implements ICPPVariable, ICPPInternalBinding {
IASTName name = (IASTName) node;
if( isDefinition( name ) )
definition = name;
else
else if( declarations == null )
declarations = new IASTName[] { name };
else {
//keep the lowest offset declaration in [0]
if( declarations.length > 0 && ((ASTNode)node).getOffset() < ((ASTNode)declarations[0]).getOffset() ){
IASTName temp = declarations[0];
declarations[0] = name;
name = temp;
}
declarations = (IASTName[]) ArrayUtil.append( IASTName.class, declarations, name );
}
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPBinding#getDeclarations()
@ -249,8 +259,7 @@ public class CPPVariable implements ICPPVariable, ICPPInternalBinding {
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding#addDefinition(org.eclipse.cdt.core.dom.ast.IASTNode)
*/
public void addDefinition(IASTNode node) {
// TODO Auto-generated method stub
addDeclaration( node );
}
}

View file

@ -77,6 +77,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.CPPASTVisitor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTBinaryExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorChainInitializer;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConversionName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTElaboratedTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFieldReference;
@ -480,18 +481,6 @@ public class CPPVisitor {
return CPPTemplates.createBinding( param );
}
} else if( simpleDecl != null && simpleDecl.getDeclSpecifier().getStorageClass() == IASTDeclSpecifier.sc_typedef ){
if( binding == null ){
binding = CPPSemantics.resolveBinding( name );
try {
if( (binding instanceof IProblemBinding && ((IProblemBinding)binding).getID() == IProblemBinding.SEMANTIC_NAME_NOT_FOUND) ||
binding.getScope() != scope )
{
binding = null;
}
} catch ( DOMException e ){
binding = null;
}
}
if( binding != null && binding instanceof ITypedef ){
try {
IType t1 = ((ITypedef)binding).getType();
@ -1293,8 +1282,13 @@ public class CPPVisitor {
pTypes[i] = pt;
}
returnType = getPointerTypes( returnType, fnDtor );
IASTName name = fnDtor.getName();
if( name instanceof ICPPASTConversionName ){
returnType = createType( ((ICPPASTConversionName)name).getTypeId() );
} else {
returnType = getPointerTypes( returnType, fnDtor );
}
IType type = new CPPFunctionType( returnType, pTypes );
IASTDeclarator nested = fnDtor.getNestedDeclarator();
@ -1407,13 +1401,13 @@ public class CPPVisitor {
name = ((IASTEnumerationSpecifier)declSpec).getName();
} else if( declSpec instanceof ICPPASTSimpleDeclSpecifier ){
ICPPASTSimpleDeclSpecifier spec = (ICPPASTSimpleDeclSpecifier) declSpec;
int bits = ( spec.isLong() ? CPPBasicType.IS_LONG : 0 ) &
( spec.isShort() ? CPPBasicType.IS_SHORT : 0 ) &
( spec.isSigned() ? CPPBasicType.IS_SIGNED: 0 ) &
int bits = ( spec.isLong() ? CPPBasicType.IS_LONG : 0 ) |
( spec.isShort() ? CPPBasicType.IS_SHORT : 0 ) |
( spec.isSigned() ? CPPBasicType.IS_SIGNED: 0 ) |
( spec.isUnsigned() ? CPPBasicType.IS_SHORT : 0 );
if( spec instanceof IGPPASTSimpleDeclSpecifier ){
IGPPASTSimpleDeclSpecifier gspec = (IGPPASTSimpleDeclSpecifier) spec;
bits &= ( gspec.isLongLong() ? GPPBasicType.IS_LONGLONG : 0 );
bits |= ( gspec.isLongLong() ? GPPBasicType.IS_LONGLONG : 0 );
type = new GPPBasicType( spec.getType(), bits, getExpressionType(gspec.getTypeofExpression()) );
} else {
type = new CPPBasicType( spec.getType(), bits );
@ -1503,6 +1497,7 @@ public class CPPVisitor {
case IASTLiteralExpression.lk_string_literal:
IType type = new CPPBasicType( IBasicType.t_char, 0 );
type = new CPPQualifierType( type, true, false );
((CPPQualifierType)type).setFromStringLiteral( true );
return new CPPPointerType( type );
}

View file

@ -25,6 +25,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPDelegate;
public interface ICPPInternalBinding extends IBinding {
//methods required by the CPPVisitor but not meant for the public interface
//implementors should keep the node with the lowest offset in declarations[0]
IASTNode [] getDeclarations();
IASTNode getDefinition();

View file

@ -0,0 +1,23 @@
/**********************************************************************
* Copyright (c) 2005 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
**********************************************************************/
/*
* Created on Apr 12, 2005
*/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
/**
* @author aniefer
*/
public interface ICPPInternalClassType extends ICPPInternalBinding {
public ICPPMethod [] getConversionOperators();
}