From 21c09e5d0f501c384e1fcbe6dc4bf983b44e5bbe Mon Sep 17 00:00:00 2001 From: Andrew Niefer Date: Fri, 15 Apr 2005 14:43:29 +0000 Subject: [PATCH] fix up CPPSemantics.declaredBefore & resolving typedefs also: 90654 - conversion operators 90653 - overloaded operators 86618 - conversion of string literal (const char *) to char * --- .../tests/ast2/AST2CPPSpecFailingTest.java | 115 ------------------ .../parser/tests/ast2/AST2CPPSpecTest.java | 106 ++++++++++++++++ .../core/parser/tests/ast2/AST2CPPTests.java | 81 +++++++++++- .../cdt/core/dom/ast/cpp/ICPPMethod.java | 4 +- .../core/dom/parser/cpp/CPPClassTemplate.java | 9 +- .../core/dom/parser/cpp/CPPClassType.java | 89 +++++++++++--- .../core/dom/parser/cpp/CPPFunction.java | 24 ++-- .../core/dom/parser/cpp/CPPNamespace.java | 19 ++- .../core/dom/parser/cpp/CPPParameter.java | 16 +-- .../core/dom/parser/cpp/CPPQualifierType.java | 12 ++ .../core/dom/parser/cpp/CPPSemantics.java | 114 +++++++++-------- .../core/dom/parser/cpp/CPPTypedef.java | 54 ++++---- .../core/dom/parser/cpp/CPPVariable.java | 15 ++- .../core/dom/parser/cpp/CPPVisitor.java | 31 ++--- .../dom/parser/cpp/ICPPInternalBinding.java | 1 + .../dom/parser/cpp/ICPPInternalClassType.java | 23 ++++ 16 files changed, 453 insertions(+), 260 deletions(-) create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPInternalClassType.java diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecFailingTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecFailingTest.java index 158972cdae9..704c035a557 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecFailingTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecFailingTest.java @@ -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 List { - public: - T* get(); - // ... - }; - } - template class Map { - N::List lt; - V get(K); - // ... - }; - void g(Map& 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 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 Map {\n"); //$NON-NLS-1$ - buffer.append("N::List 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& 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 X { diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecTest.java index a34074c07d3..a0b949d83d9 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecTest.java @@ -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 List { + public: + T* get(); + // ... + }; + } + template class Map { + N::List lt; + V get(K); + // ... + }; + void g(Map& 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 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 Map {\n"); //$NON-NLS-1$ + buffer.append("N::List 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& 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 void f(T x, T y = ydef(T()), T z = zdef(T())); 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 aae2bea0a5c..834899235c2 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 @@ -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 ); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPMethod.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPMethod.java index da756647fde..9b901195928 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPMethod.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPMethod.java @@ -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]; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplate.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplate.java index b20a3c791fc..2c2d9c77449 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplate.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplate.java @@ -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; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassType.java index ba47016a809..ce8fef3cda2 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassType.java @@ -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() 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 734caee2e25..736589525e8 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 @@ -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) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNamespace.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNamespace.java index 4a318af7131..c1b92e2f1ea 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNamespace.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNamespace.java @@ -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) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPParameter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPParameter.java index 8234861e9cc..46334f2fcc6 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPParameter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPParameter.java @@ -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 ); } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPQualifierType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPQualifierType.java index 0657df472e0..113dbe806db 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPQualifierType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPQualifierType.java @@ -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; + } } 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 9d4fc96d2e4..ed739a30869 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 @@ -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 ); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTypedef.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTypedef.java index 076ea4023be..4b9b9ad2359 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTypedef.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTypedef.java @@ -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 ); + } + } } 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 df114c0639b..03b76063cf6 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 @@ -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 ); } } 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 0e45f8c55b3..ebf68ca7a32 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 @@ -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 ); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPInternalBinding.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPInternalBinding.java index a0b0397d838..72d35689c7b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPInternalBinding.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPInternalBinding.java @@ -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(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPInternalClassType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPInternalClassType.java new file mode 100644 index 00000000000..ac6a7a01814 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPInternalClassType.java @@ -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(); +}