1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-29 11:55:40 +02:00

Bug 302412: Overload resolution for list-initializers.

This commit is contained in:
Markus Schorn 2010-03-11 17:58:45 +00:00
parent 4deee6b218
commit d5c5ba8f02
13 changed files with 545 additions and 159 deletions

View file

@ -8077,5 +8077,68 @@ public class AST2CPPTests extends AST2BaseTest {
String code= getAboveComment(); String code= getAboveComment();
parseAndCheckBindings(code, ParserLanguage.CPP); parseAndCheckBindings(code, ParserLanguage.CPP);
} }
// namespace std {
// template<typename T> class initializer_list;
// }
// template<typename T> struct complex {
// complex(const T& r, const T& i);
// };
// template<typename T> struct vector {
// vector(std::initializer_list<T>);
// };
// struct str {
// str(const char*);
// };
// template<typename T> void f(std::initializer_list<T>);
// std::initializer_list<const char*> test() {
// int a = {1};
// complex<double> z{1,2};
// new vector<str>{"a", "b", "c", "d"}; // 4 string elements
// f( {"a","b"} ); // pass list of two elements
// int* e {}; // initialization to zero / null pointer
// a = double{1}; // explicitly construct a double
// return { "a" }; // return list of one element
// }
//
// struct S {
// S(std::initializer_list<double>) {}
// S(std::initializer_list<int>) {}
// };
// void fs(S){}
// void tests() {
// fs({1,2,3});
// fs({1.0,2.0,3.0});
// }
public void _testListInitialization_302412a() throws Exception {
String code= getAboveComment();
parseAndCheckBindings(code, ParserLanguage.CPP);
}
// namespace std {
// template<typename T> class initializer_list;
// }
// void f(std::initializer_list<int>);
// //void ff(std::initializer_list<str>);
// struct A {
// A(std::initializer_list<double>); // #1
// A(std::initializer_list<const char*>); // #3
// };
// void g(A);
// void test() {
// f( {1,2,3} ); // OK: f(initializer_list<int>) identity conversion
// f( {'a','b'} ); // OK: f(initializer_list<int>) integral promotion
// f( {1.0} ); // error: narrowing
// A a{ 1.0,2.0 }; // OK, uses #1
// g({ "foo", "bar" }); // OK, uses #3
// }
public void testListInitialization_302412b() throws Exception {
String code= getAboveComment();
BindingAssertionHelper bh= new BindingAssertionHelper(code, true);
bh.assertNonProblem("f( {1,2,3} )", 1);
bh.assertNonProblem("f( {'a','b'} )", 1);
bh.assertProblem("f( {1.0} )", 1);
bh.assertNonProblem("g({ \"foo\", \"bar\" })", 1);
}
} }

View file

@ -16,9 +16,9 @@ import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.ExpansionOverlapsBoundaryException; import org.eclipse.cdt.core.dom.ast.ExpansionOverlapsBoundaryException;
import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTInitializerClause;
import org.eclipse.cdt.core.dom.ast.IASTIdExpression; import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
import org.eclipse.cdt.core.dom.ast.IASTImplicitName; import org.eclipse.cdt.core.dom.ast.IASTImplicitName;
import org.eclipse.cdt.core.dom.ast.IASTInitializerClause;
import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IFunction; import org.eclipse.cdt.core.dom.ast.IFunction;
@ -64,7 +64,7 @@ public class CPPASTFunctionCallExpression extends ASTNode implements
public CPPASTFunctionCallExpression copy() { public CPPASTFunctionCallExpression copy() {
IASTInitializerClause[] args = null; IASTInitializerClause[] args = null;
if (fArguments.length > 0) { if (fArguments.length > 0) {
args= new IASTExpression[fArguments.length]; args= new IASTInitializerClause[fArguments.length];
for (int i=0; i<fArguments.length; i++) { for (int i=0; i<fArguments.length; i++) {
args[i]= fArguments[i].copy(); args[i]= fArguments[i].copy();
} }

View file

@ -17,11 +17,11 @@ import org.eclipse.cdt.core.dom.ast.IASTEqualsInitializer;
import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTInitializer; import org.eclipse.cdt.core.dom.ast.IASTInitializer;
import org.eclipse.cdt.core.dom.ast.IASTInitializerClause; import org.eclipse.cdt.core.dom.ast.IASTInitializerClause;
import org.eclipse.cdt.core.dom.ast.IASTInitializerList;
import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.IValue; import org.eclipse.cdt.core.dom.ast.IValue;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerList;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTParameterDeclaration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTParameterDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameterPackType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameterPackType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument;
@ -42,6 +42,15 @@ public class CPPTemplateNonTypeParameter extends CPPTemplateParameter implements
} }
public IASTExpression getDefault() { public IASTExpression getDefault() {
IASTInitializerClause def= getDefaultClause();
if (def instanceof IASTExpression) {
return (IASTExpression) def;
}
return null;
}
public IASTInitializerClause getDefaultClause() {
IASTName[] nds = getDeclarations(); IASTName[] nds = getDeclarations();
if (nds == null || nds.length == 0) if (nds == null || nds.length == 0)
return null; return null;
@ -54,12 +63,7 @@ public class CPPTemplateNonTypeParameter extends CPPTemplateParameter implements
IASTDeclarator dtor = (IASTDeclarator) parent; IASTDeclarator dtor = (IASTDeclarator) parent;
IASTInitializer initializer = dtor.getInitializer(); IASTInitializer initializer = dtor.getInitializer();
if (initializer instanceof IASTEqualsInitializer) { if (initializer instanceof IASTEqualsInitializer) {
IASTInitializerClause clause= ((IASTEqualsInitializer) initializer).getInitializerClause(); return ((IASTEqualsInitializer) initializer).getInitializerClause();
if (clause instanceof IASTExpression)
return (IASTExpression) clause;
if (clause instanceof IASTInitializerList) {
// mstodo handle braced init list
}
} }
} }
} }
@ -68,7 +72,23 @@ public class CPPTemplateNonTypeParameter extends CPPTemplateParameter implements
} }
public ICPPTemplateArgument getDefaultValue() { public ICPPTemplateArgument getDefaultValue() {
IASTExpression d= getDefault(); IASTInitializerClause dc= getDefault();
IASTExpression d= null;
if (dc instanceof IASTExpression) {
d= (IASTExpression) dc;
} else if (dc instanceof ICPPASTInitializerList) {
ICPPASTInitializerList list= (ICPPASTInitializerList) dc;
switch(list.getSize()) {
case 0:
return new CPPTemplateArgument(Value.create(0), getType());
case 1:
dc= list.getClauses()[0];
if (dc instanceof IASTExpression) {
d= (IASTExpression) dc;
}
}
}
if (d == null) if (d == null)
return null; return null;

View file

@ -33,6 +33,7 @@ import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.IValue; import org.eclipse.cdt.core.dom.ast.IValue;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorInitializer; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorInitializer;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerList;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBlockScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPBlockScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariable; import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariable;
@ -409,11 +410,18 @@ public class CPPVariable extends PlatformObject implements ICPPVariable, ICPPInt
clause= args[0]; clause= args[0];
} }
} }
} else if (init instanceof ICPPASTInitializerList) {
ICPPASTInitializerList list= (ICPPASTInitializerList) init;
switch (list.getSize()) {
case 0:
return Value.create(0);
case 1:
clause= list.getClauses()[0];
}
} }
if (clause instanceof IASTExpression) { if (clause instanceof IASTExpression) {
return Value.create((IASTExpression) clause, maxDepth); return Value.create((IASTExpression) clause, maxDepth);
} }
// mstodo handle braced init list
return Value.UNKNOWN; return Value.UNKNOWN;
} }
} }

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2004, 2009 IBM Corporation and others. * Copyright (c) 2004, 2010 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -49,6 +49,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPField; import org.eclipse.cdt.core.dom.ast.cpp.ICPPField;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMember;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration;
@ -735,4 +736,30 @@ public class ClassTypeHelper {
} }
return null; return null;
} }
/**
* 8.5.1 Aggregates [dcl.init.aggr]
* An aggregate is an array or a class (Clause 9) with no user-provided constructors (12.1),
* no private or protected non-static data members (Clause 11),
* no base classes (Clause 10), and no virtual functions (10.3).
*/
public static boolean isAggregateClass(ICPPClassType classTarget) throws DOMException {
if (classTarget.getBases().length > 0)
return false;
ICPPMethod[] methods = classTarget.getDeclaredMethods();
for (ICPPMethod m : methods) {
if (m instanceof ICPPConstructor)
return false;
if (m.isVirtual()) {
return false;
}
}
ICPPField[] fields = classTarget.getDeclaredFields();
for (ICPPField field : fields) {
if (!(field.getVisibility() == ICPPMember.v_public || field.isStatic())) {
return false;
}
}
return true;
}
} }

View file

@ -830,7 +830,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
if (allowThrow && LT(1) == IToken.t_throw) { if (allowThrow && LT(1) == IToken.t_throw) {
expr= throwExpression(); expr= throwExpression();
} else if (allowBraceInitializer && LT(1) == IToken.tLBRACE) { } else if (allowBraceInitializer && LT(1) == IToken.tLBRACE) {
expr= bracedInitList(); expr= bracedInitList(true);
} else { } else {
expr= castExpression(castCtx); // next cast expression expr= castExpression(castCtx); // next cast expression
continue loop; continue loop;
@ -1162,7 +1162,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
if (t != null) { if (t != null) {
consume(IToken.tRPAREN); consume(IToken.tRPAREN);
if (LT(1) == IToken.tLBRACE) { if (LT(1) == IToken.tLBRACE) {
IASTInitializer i = bracedInitList(); IASTInitializer i = bracedInitList(false);
firstExpression= nodeFactory.newTypeIdInitializerExpression(t, i); firstExpression= nodeFactory.newTypeIdInitializerExpression(t, i);
setRange(firstExpression, offset, calculateEndOffset(i)); setRange(firstExpression, offset, calculateEndOffset(i));
break; break;
@ -1212,7 +1212,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
consume(IToken.tLBRACKET); consume(IToken.tLBRACKET);
IASTInitializerClause expression; IASTInitializerClause expression;
if (LT(1) == IToken.tLBRACE) { if (LT(1) == IToken.tLBRACE) {
expression= bracedInitList(); expression= bracedInitList(false);
} else { } else {
expression= expression(); expression= expression();
} }
@ -2795,14 +2795,14 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
// = initializer-clause // = initializer-clause
if (lt1 == IToken.tASSIGN) { if (lt1 == IToken.tASSIGN) {
int offset= consume().getOffset(); int offset= consume().getOffset();
IASTInitializerClause initClause = initClause(false); IASTInitializerClause initClause = initClause(LT(1) == IToken.tLBRACE);
IASTEqualsInitializer initExpr= nodeFactory.newEqualsInitializer(initClause); IASTEqualsInitializer initExpr= nodeFactory.newEqualsInitializer(initClause);
return setRange(initExpr, offset, calculateEndOffset(initClause)); return setRange(initExpr, offset, calculateEndOffset(initClause));
} }
// braced-init-list // braced-init-list
if (option.fAllowBracedInitializer && lt1 == IToken.tLBRACE) { if (option.fAllowBracedInitializer && lt1 == IToken.tLBRACE) {
return bracedInitList(); return bracedInitList(false);
} }
// ( expression-list ) // ( expression-list )
@ -2817,7 +2817,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
if (lt1 == IToken.tLPAREN) { if (lt1 == IToken.tLPAREN) {
return ctorStyleInitializer(true); return ctorStyleInitializer(true);
} }
return bracedInitList(); return bracedInitList(false);
} }
/** /**
@ -2848,17 +2848,17 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
* assignment-expression * assignment-expression
* braced-init-list * braced-init-list
*/ */
private IASTInitializerClause initClause(boolean inBraces) throws EndOfFileException, private IASTInitializerClause initClause(boolean allowSkipping) throws EndOfFileException,
BacktrackException { BacktrackException {
// braced-init-list // braced-init-list
if (LT(1) == IToken.tLBRACE) { if (LT(1) == IToken.tLBRACE) {
return bracedInitList(); return bracedInitList(allowSkipping);
} }
// assignment expression // assignment expression
final BinaryExprCtx ctx = fInTemplateParameterList ? BinaryExprCtx.eTmplID : BinaryExprCtx.eNoTmplID; final BinaryExprCtx ctx = fInTemplateParameterList ? BinaryExprCtx.eTmplID : BinaryExprCtx.eNoTmplID;
IASTExpression assignmentExpression = expression(ExprKind.eAssignment, ctx); IASTExpression assignmentExpression = expression(ExprKind.eAssignment, ctx);
if (inBraces && skipTrivialExpressionsInAggregateInitializers) { if (allowSkipping && skipTrivialExpressionsInAggregateInitializers) {
if (!ASTQueries.canContainName(assignmentExpression)) if (!ASTQueries.canContainName(assignmentExpression))
return null; return null;
} }
@ -2870,7 +2870,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
* { initializer-list ,opt } * { initializer-list ,opt }
* { } * { }
*/ */
private ICPPASTInitializerList bracedInitList() throws EndOfFileException, BacktrackException { private ICPPASTInitializerList bracedInitList(boolean allowSkipping) throws EndOfFileException, BacktrackException {
int offset = consume(IToken.tLBRACE).getOffset(); int offset = consume(IToken.tLBRACE).getOffset();
// { } // { }
@ -2879,7 +2879,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
} }
// { initializer-list ,opt } // { initializer-list ,opt }
List<IASTInitializerClause> initList= initializerList(true); List<IASTInitializerClause> initList= initializerList(allowSkipping);
if (LT(1) == IToken.tCOMMA) if (LT(1) == IToken.tCOMMA)
consume(); consume();
@ -2896,14 +2896,14 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
* initializer-clause ...opt * initializer-clause ...opt
* initializer-list , initializer-clause ...opt * initializer-list , initializer-clause ...opt
*/ */
private List<IASTInitializerClause> initializerList(boolean inAggregateInit) throws EndOfFileException, private List<IASTInitializerClause> initializerList(boolean allowSkipping) throws EndOfFileException,
BacktrackException { BacktrackException {
List<IASTInitializerClause> result= null; List<IASTInitializerClause> result= null;
// List of initializer clauses // List of initializer clauses
loop: for(;;) { loop: for(;;) {
// Clause may be null, add to initializer anyways, such that the size can be computed. // Clause may be null, add to initializer anyways, such that the size can be computed.
IASTInitializerClause clause = initClause(inAggregateInit); IASTInitializerClause clause = initClause(allowSkipping);
if (LT(1) == IToken.tELLIPSIS) { if (LT(1) == IToken.tELLIPSIS) {
final int endOffset = consume(IToken.tELLIPSIS).getEndOffset(); final int endOffset = consume(IToken.tELLIPSIS).getEndOffset();
if (clause instanceof ICPPASTPackExpandable) { if (clause instanceof ICPPASTPackExpandable) {
@ -4073,7 +4073,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
IASTInitializerClause expr = null; IASTInitializerClause expr = null;
final int lt1 = LT(1); final int lt1 = LT(1);
if (lt1 == IToken.tLBRACE) { if (lt1 == IToken.tLBRACE) {
expr= bracedInitList(); expr= bracedInitList(true);
} else if (lt1 != IToken.tSEMI) { } else if (lt1 != IToken.tSEMI) {
expr = expression(); expr = expression();
} }

View file

@ -93,6 +93,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTForStatement;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDefinition; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTIfStatement; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTIfStatement;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerList;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLinkageSpecification; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLinkageSpecification;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamedTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamedTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceAlias; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceAlias;
@ -393,7 +394,7 @@ public class CPPSemantics {
// if the lookup in base-classes ran into a deferred instance, use the computed unknown binding. // if the lookup in base-classes ran into a deferred instance, use the computed unknown binding.
final ASTNodeProperty namePropertyInParent = name.getPropertyInParent(); final ASTNodeProperty namePropertyInParent = name.getPropertyInParent();
if (binding == null && data.skippedScope != null) { if (binding == null && data.skippedScope != null) {
if (data.hasArgumentTypes()) { if (data.hasFunctionArguments()) {
binding= new CPPUnknownFunction(data.skippedScope, name.getSimpleID()); binding= new CPPUnknownFunction(data.skippedScope, name.getSimpleID());
} else { } else {
if (namePropertyInParent == IASTNamedTypeSpecifier.NAME) { if (namePropertyInParent == IASTNamedTypeSpecifier.NAME) {
@ -527,11 +528,25 @@ public class CPPSemantics {
return false; return false;
} }
public static IBinding selectConstructor(ICPPClassType classTarget, ICPPASTInitializerList initializerList) {
LookupData data= new LookupData();
IASTName name = new CPPASTName(classTarget.getNameCharArray());
name.setParent(initializerList);
name.setPropertyInParent(CPPSemantics.STRING_LOOKUP_PROPERTY);
data.setFunctionArguments(initializerList);
try {
return CPPSemantics.selectConstructor(classTarget, data);
} catch (DOMException e) {
return e.getProblem();
}
}
private static IBinding selectConstructor(ICPPClassType cls, LookupData data) throws DOMException { private static IBinding selectConstructor(ICPPClassType cls, LookupData data) throws DOMException {
// Force resolution of constructor bindings // Force resolution of constructor bindings
final ICPPConstructor[] constructors= cls.getConstructors(); final ICPPConstructor[] constructors= cls.getConstructors();
if (constructors.length > 0) { if (constructors.length > 0) {
return CPPSemantics.resolveAmbiguities(data.astName, constructors); data.foundItems= constructors;
return CPPSemantics.resolveAmbiguities(data, data.astName);
} }
return cls; return cls;
} }
@ -626,8 +641,8 @@ public class CPPSemantics {
data.setFunctionArguments(); data.setFunctionArguments();
} else if (init instanceof ICPPASTConstructorInitializer) { } else if (init instanceof ICPPASTConstructorInitializer) {
data.setFunctionArguments(((ICPPASTConstructorInitializer) init).getArguments()); data.setFunctionArguments(((ICPPASTConstructorInitializer) init).getArguments());
} else { } else if (init instanceof ICPPASTInitializerList) {
// mstodo handle braced init list data.setFunctionArguments(new IASTInitializerClause[] {(ICPPASTInitializerList) init});
} }
} }
} else if (parent instanceof ICPPASTConstructorChainInitializer) { } else if (parent instanceof ICPPASTConstructorChainInitializer) {
@ -635,8 +650,8 @@ public class CPPSemantics {
IASTInitializer init = ctorinit.getInitializer(); IASTInitializer init = ctorinit.getInitializer();
if (init instanceof ICPPASTConstructorInitializer) { if (init instanceof ICPPASTConstructorInitializer) {
data.setFunctionArguments(((ICPPASTConstructorInitializer) init).getArguments()); data.setFunctionArguments(((ICPPASTConstructorInitializer) init).getArguments());
} else { } else if (init instanceof ICPPASTInitializerList) {
// mstodo handle braced init list data.setFunctionArguments(new IASTInitializerClause[] {(ICPPASTInitializerList) init});
} }
} }
@ -644,7 +659,7 @@ public class CPPSemantics {
} }
static private ObjectSet<ICPPScope> getAssociatedScopes(LookupData data) { static private ObjectSet<ICPPScope> getAssociatedScopes(LookupData data) {
if (!data.hasArgumentTypes()) if (!data.hasFunctionArguments())
return ObjectSet.emptySet(); return ObjectSet.emptySet();
IType[] ps = data.getFunctionArgumentTypes(); IType[] ps = data.getFunctionArgumentTypes();
@ -2138,7 +2153,8 @@ public class CPPSemantics {
} }
// We don't have any arguments with which to resolve the function // We don't have any arguments with which to resolve the function
if (!data.hasArgumentTypes()) { final boolean isFuncDecl = data.forFunctionDeclaration();
if (!data.hasFunctionArguments()) {
return resolveTargetedFunction(data, fns); return resolveTargetedFunction(data, fns);
} }
@ -2146,7 +2162,7 @@ public class CPPSemantics {
return resolveUserDefinedConversion(data, fns); return resolveUserDefinedConversion(data, fns);
} }
if (!data.forFunctionDeclaration() || data.forExplicitFunctionSpecialization()) { if (!isFuncDecl || data.forExplicitFunctionSpecialization()) {
CPPTemplates.instantiateFunctionTemplates(fns, data.getFunctionArgumentTypes(), data.getFunctionArgumentLValues(), data.astName); CPPTemplates.instantiateFunctionTemplates(fns, data.getFunctionArgumentTypes(), data.getFunctionArgumentLValues(), data.astName);
} }
@ -2165,7 +2181,7 @@ public class CPPSemantics {
} }
} }
} }
if (firstViable == null || data.forFunctionDeclaration()) if (firstViable == null || isFuncDecl)
return firstViable; return firstViable;
// The arguments the function is being called with // The arguments the function is being called with

View file

@ -30,6 +30,7 @@ import org.eclipse.cdt.core.dom.ast.IASTElaboratedTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition; import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.IASTIdExpression; import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
import org.eclipse.cdt.core.dom.ast.IASTInitializerClause;
import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
@ -50,6 +51,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTElaboratedTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTElaboratedTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExplicitTemplateInstantiation; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExplicitTemplateInstantiation;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDefinition; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerList;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamedTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamedTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTParameterDeclaration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTParameterDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
@ -1542,6 +1544,8 @@ public class CPPTemplates {
} }
static protected void instantiateFunctionTemplates(IFunction[] functions, IType[] fnArgs, BitSet argIsLValue, IASTName name) { static protected void instantiateFunctionTemplates(IFunction[] functions, IType[] fnArgs, BitSet argIsLValue, IASTName name) {
// mstodo handle list initialization
boolean requireTemplate= false; boolean requireTemplate= false;
if (name != null) { if (name != null) {
if (name.getPropertyInParent() == ICPPASTTemplateId.TEMPLATE_NAME) { if (name.getPropertyInParent() == ICPPASTTemplateId.TEMPLATE_NAME) {
@ -2045,12 +2049,29 @@ public class CPPTemplates {
return true; return true;
} }
t= ((ITypeContainer) t).getType(); t= ((ITypeContainer) t).getType();
} else if (t instanceof InitializerListType) {
return isDependentInitializerList(((InitializerListType) t).getInitializerList());
} else { } else {
return false; return false;
} }
} }
} }
private static boolean isDependentInitializerList(ICPPASTInitializerList initializerList) {
IASTInitializerClause[] clauses= initializerList.getClauses();
for (IASTInitializerClause clause : clauses) {
if (clause instanceof IASTExpression) {
IType t= ((IASTExpression) clause).getExpressionType();
if (isDependentType(t))
return true;
} else if (clause instanceof ICPPASTInitializerList) {
if (isDependentInitializerList((ICPPASTInitializerList) clause))
return true;
}
}
return false;
}
public static boolean containsDependentArg(ObjectMap tpMap) { public static boolean containsDependentArg(ObjectMap tpMap) {
for (Object arg : tpMap.valueArray()) { for (Object arg : tpMap.valueArray()) {
if (isDependentType((IType)arg)) if (isDependentType((IType)arg))

View file

@ -24,6 +24,7 @@ import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTLiteralExpression; import org.eclipse.cdt.core.dom.ast.IASTLiteralExpression;
import org.eclipse.cdt.core.dom.ast.IArrayType; import org.eclipse.cdt.core.dom.ast.IArrayType;
import org.eclipse.cdt.core.dom.ast.IBasicType; import org.eclipse.cdt.core.dom.ast.IBasicType;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IEnumeration; import org.eclipse.cdt.core.dom.ast.IEnumeration;
import org.eclipse.cdt.core.dom.ast.IFunctionType; import org.eclipse.cdt.core.dom.ast.IFunctionType;
import org.eclipse.cdt.core.dom.ast.IPointerType; import org.eclipse.cdt.core.dom.ast.IPointerType;
@ -33,17 +34,23 @@ import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.IValue; import org.eclipse.cdt.core.dom.ast.IValue;
import org.eclipse.cdt.core.dom.ast.IBasicType.Kind; import org.eclipse.cdt.core.dom.ast.IBasicType.Kind;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; 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.ICPPPointerToMemberType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPPointerToMemberType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance;
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.internal.core.dom.parser.ArithmeticConversion; import org.eclipse.cdt.internal.core.dom.parser.ArithmeticConversion;
import org.eclipse.cdt.internal.core.dom.parser.Value; import org.eclipse.cdt.internal.core.dom.parser.Value;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerToMemberType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerToMemberType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Cost.Rank; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Cost.Rank;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Cost.ReferenceBinding; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Cost.ReferenceBinding;
@ -58,6 +65,9 @@ public class Conversions {
static { static {
LVBITSET.set(0, true); LVBITSET.set(0, true);
} }
private static final char[] INITIALIZER_LIST_NAME = "initializer_list".toCharArray(); //$NON-NLS-1$
private static final char[] STD_NAME = "std".toCharArray(); //$NON-NLS-1$
/** /**
* Computes the cost of an implicit conversion sequence * Computes the cost of an implicit conversion sequence
* [over.best.ics] 13.3.3.1 * [over.best.ics] 13.3.3.1
@ -85,7 +95,7 @@ public class Conversions {
final IType cv2T2= exprType; final IType cv2T2= exprType;
final IType T2= getNestedType(cv2T2, TDEF | REF | ALLCVQ); final IType T2= getNestedType(cv2T2, TDEF | REF | ALLCVQ);
final boolean isImplicitWithoutRefQualifier = isImpliedObjectType; // mstodo need to pass this information to here final boolean isImplicitWithoutRefQualifier = isImpliedObjectType;
ReferenceBinding refBindingType= ReferenceBinding.OTHER; ReferenceBinding refBindingType= ReferenceBinding.OTHER;
if (!isImplicitWithoutRefQualifier) { if (!isImplicitWithoutRefQualifier) {
if (isLValueRef) { if (isLValueRef) {
@ -258,6 +268,9 @@ public class Conversions {
} }
private static Cost nonReferenceConversion(boolean sourceIsLValue, IType source, IType target, UDCMode udc, boolean isImpliedObject) throws DOMException { private static Cost nonReferenceConversion(boolean sourceIsLValue, IType source, IType target, UDCMode udc, boolean isImpliedObject) throws DOMException {
if (source instanceof InitializerListType) {
return listInitializationSequence(((InitializerListType) source), target, udc);
}
// [13.3.3.1-6] Subsume cv-qualifications // [13.3.3.1-6] Subsume cv-qualifications
IType uqSource= SemanticUtil.getNestedType(source, TDEF | ALLCVQ); IType uqSource= SemanticUtil.getNestedType(source, TDEF | ALLCVQ);
Cost cost= checkStandardConversionSequence(uqSource, sourceIsLValue, target, isImpliedObject); Cost cost= checkStandardConversionSequence(uqSource, sourceIsLValue, target, isImpliedObject);
@ -271,6 +284,68 @@ public class Conversions {
return cost; return cost;
} }
/**
* 13.3.3.1.5 List-initialization sequence [over.ics.list]
*/
private static Cost listInitializationSequence(InitializerListType arg, IType target, UDCMode udc) throws DOMException {
IType listType= getInitListType(target);
if (listType != null) {
IType[] exprTypes= arg.getExpressionTypes();
BitSet isLValue= arg.getIsLValue();
Cost worstCost= new Cost(arg, target, Rank.IDENTITY);
for (int i = 0; i < exprTypes.length; i++) {
IType exprType = exprTypes[i];
Cost cost= checkImplicitConversionSequence(listType, exprType, isLValue.get(i), UDCMode.allowUDC, false);
if (cost.getRank() == Rank.NO_MATCH)
return cost;
if (cost.isNarrowingConversion()) {
cost.setRank(Rank.NO_MATCH);
return cost;
}
if (cost.compareTo(worstCost) > 0) {
worstCost= cost;
}
}
return worstCost;
}
IType noCVTarget= getNestedType(target, CVTYPE | TDEF);
if (noCVTarget instanceof ICPPClassType) {
if (udc == UDCMode.noUDC)
return new Cost(arg, target, Rank.NO_MATCH);
ICPPClassType classTarget= (ICPPClassType) noCVTarget;
if (ClassTypeHelper.isAggregateClass(classTarget)) {
return new Cost(arg, target, Rank.USER_DEFINED_CONVERSION);
}
Cost cost= checkUserDefinedConversionSequence(false, arg, target, udc == UDCMode.deferUDC);
if (cost != null)
return cost;
}
return new Cost(arg, target, Rank.NO_MATCH);
}
private static IType getInitListType(IType target) throws DOMException {
if (target instanceof ICPPClassSpecialization && target instanceof ICPPTemplateInstance) {
ICPPTemplateInstance inst = (ICPPTemplateInstance) target;
if (CharArrayUtils.equals(INITIALIZER_LIST_NAME, inst.getNameCharArray())) {
IBinding owner = inst.getOwner();
if (owner instanceof ICPPNamespace
&& CharArrayUtils.equals(STD_NAME, owner.getNameCharArray())
&& owner.getOwner() == null) {
ICPPTemplateArgument[] args = inst.getTemplateArguments();
if (args.length == 1) {
ICPPTemplateArgument arg = args[0];
if (arg.isTypeValue()) {
return arg.getTypeValue();
}
}
}
}
}
return null;
}
/** /**
* [3.9.3-4] Implements cv-ness (partial) comparison. There is a (partial) * [3.9.3-4] Implements cv-ness (partial) comparison. There is a (partial)
* ordering on cv-qualifiers, so that a type can be said to be more * ordering on cv-qualifiers, so that a type can be said to be more
@ -423,6 +498,7 @@ public class Conversions {
* @throws DOMException * @throws DOMException
*/ */
static final Cost checkUserDefinedConversionSequence(boolean sourceIsLValue, IType source, IType target, boolean deferUDC) throws DOMException { static final Cost checkUserDefinedConversionSequence(boolean sourceIsLValue, IType source, IType target, boolean deferUDC) throws DOMException {
// mstodo don't return null
IType s= getNestedType(source, TDEF | CVTYPE | REF); IType s= getNestedType(source, TDEF | CVTYPE | REF);
IType t= getNestedType(target, TDEF | CVTYPE | REF); IType t= getNestedType(target, TDEF | CVTYPE | REF);
@ -436,11 +512,74 @@ public class Conversions {
return c; return c;
} }
// 13.3.1.4 Copy initialization of class by user-defined conversion
if (t instanceof ICPPClassType) { if (t instanceof ICPPClassType) {
if (s instanceof InitializerListType) {
// 13.3.1.7 Initialization by list-initialization
return listInitializationOfClass((InitializerListType) s, (ICPPClassType) t, false);
}
// 13.3.1.4 Copy initialization of class by user-defined conversion
return copyInitalizationOfClass(sourceIsLValue, source, s, target, (ICPPClassType) t);
}
if (s instanceof ICPPClassType) {
// 13.3.1.5 Initialization by conversion function
return initializationByConversion(source, (ICPPClassType) s, target);
}
return null;
}
private static Cost listInitializationOfClass(InitializerListType s, ICPPClassType t, boolean isDirect) throws DOMException {
// If T has an initializer-list constructor
ICPPConstructor usedCtor= null;
Cost bestCost= null;
ICPPConstructor[] ctors= t.getConstructors();
for (ICPPConstructor ctor : ctors) {
if (ctor.getRequiredArgumentCount() <= 1) {
IType[] parTypes= ctor.getType().getParameterTypes();
if (parTypes.length > 0) {
final IType target = parTypes[0];
if (getInitListType(target) != null) {
Cost cost= listInitializationSequence(s, target, UDCMode.noUDC);
if (cost.getRank() == Rank.NO_MATCH) {
if (bestCost == null) {
bestCost= cost;
}
} else {
int cmp= cost.compareTo(bestCost);
if (bestCost == null || cmp < 0) {
usedCtor= ctor;
cost.setUserDefinedConversion(ctor);
bestCost= cost;
} else if (cmp == 0) {
bestCost.setAmbiguousUDC(true);
}
}
}
}
}
}
if (bestCost != null) {
if (!bestCost.isAmbiguousUDC() && !isDirect) {
if (usedCtor != null && usedCtor.isExplicit()) {
bestCost.setRank(Rank.NO_MATCH);
}
}
return bestCost;
}
// mstodo expanding the list for selecting the ctor.
return new Cost(s, t, Rank.NO_MATCH);
}
/**
* 13.3.1.4 Copy-initialization of class by user-defined conversion [over.match.copy]
*/
private static Cost copyInitalizationOfClass(boolean sourceIsLValue, IType source, IType s, IType target,
ICPPClassType t) throws DOMException {
FunctionCost cost1= null; FunctionCost cost1= null;
Cost cost2= null; Cost cost2= null;
ICPPConstructor[] ctors= ((ICPPClassType) t).getConstructors(); ICPPConstructor[] ctors= t.getConstructors();
CPPTemplates.instantiateFunctionTemplates(ctors, new IType[]{source}, sourceIsLValue ? LVBITSET : RVBITSET, null); CPPTemplates.instantiateFunctionTemplates(ctors, new IType[]{source}, sourceIsLValue ? LVBITSET : RVBITSET, null);
for (ICPPConstructor ctor : ctors) { for (ICPPConstructor ctor : ctors) {
@ -513,9 +652,11 @@ public class Conversions {
return cost2; return cost2;
} }
// 13.3.1.5 Initialization by conversion function /**
if (s instanceof ICPPClassType) { * 13.3.1.5 Initialization by conversion function [over.match.conv]
ICPPMethod[] ops = SemanticUtil.getConversionOperators((ICPPClassType) s); */
private static Cost initializationByConversion(IType source, ICPPClassType s, IType target) throws DOMException {
ICPPMethod[] ops = SemanticUtil.getConversionOperators(s);
CPPTemplates.instantiateConversionTemplates(ops, target); CPPTemplates.instantiateConversionTemplates(ops, target);
FunctionCost cost1= null; FunctionCost cost1= null;
Cost cost2= null; Cost cost2= null;
@ -550,8 +691,6 @@ public class Conversions {
return cost2; return cost2;
} }
return null;
}
/** /**
* Attempts the conversions below and returns whether this completely converts the source to * Attempts the conversions below and returns whether this completely converts the source to
@ -779,6 +918,7 @@ public class Conversions {
// 4.7 An rvalue of an integer type can be converted to an rvalue of another integer type. // 4.7 An rvalue of an integer type can be converted to an rvalue of another integer type.
// An rvalue of an enumeration type can be converted to an rvalue of an integer type. // An rvalue of an enumeration type can be converted to an rvalue of an integer type.
cost.setRank(Rank.CONVERSION); cost.setRank(Rank.CONVERSION);
cost.setCouldNarrow();
return true; return true;
} }
// 4.12 pointer or pointer to member type can be converted to an rvalue of type bool // 4.12 pointer or pointer to member type can be converted to an rvalue of type bool
@ -812,7 +952,7 @@ public class Conversions {
IType tgtPtrTgt= getNestedType(tgtPtr.getType(), TDEF | CVTYPE | REF); IType tgtPtrTgt= getNestedType(tgtPtr.getType(), TDEF | CVTYPE | REF);
if (SemanticUtil.isVoidType(tgtPtrTgt)) { if (SemanticUtil.isVoidType(tgtPtrTgt)) {
cost.setRank(Rank.CONVERSION); cost.setRank(Rank.CONVERSION);
cost.setInheritanceDistance(Short.MAX_VALUE); // mstodo add distance to last base class cost.setInheritanceDistance(Short.MAX_VALUE);
CVQualifier cv= getCVQualifier(srcPtr.getType()); CVQualifier cv= getCVQualifier(srcPtr.getType());
cost.source= new CPPPointerType(addQualifiers(CPPSemantics.VOID_TYPE, cv.isConst(), cv.isVolatile())); cost.source= new CPPPointerType(addQualifiers(CPPSemantics.VOID_TYPE, cv.isConst(), cv.isVolatile()));
return false; return false;

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2004, 2009 IBM Corporation and others. * Copyright (c) 2004, 2010 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -43,6 +43,8 @@ final class Cost {
private ICPPFunction fUserDefinedConversion; private ICPPFunction fUserDefinedConversion;
private ReferenceBinding fReferenceBinding; private ReferenceBinding fReferenceBinding;
private boolean fCouldNarrow;
public Cost(IType s, IType t, Rank rank) { public Cost(IType s, IType t, Rank rank) {
source = s; source = s;
target = t; target = t;
@ -125,9 +127,11 @@ final class Cost {
if (isAmbiguousUDC() || other.isAmbiguousUDC()) if (isAmbiguousUDC() || other.isAmbiguousUDC())
return 0; return 0;
if (!fUserDefinedConversion.equals(other.fUserDefinedConversion)) if (fUserDefinedConversion != other.fUserDefinedConversion) {
if (fUserDefinedConversion == null ||
!fUserDefinedConversion.equals(other.fUserDefinedConversion))
return 0; return 0;
}
cmp= fSecondStandardConversionRank.compareTo(other.fSecondStandardConversionRank); cmp= fSecondStandardConversionRank.compareTo(other.fSecondStandardConversionRank);
if (cmp != 0) if (cmp != 0)
return cmp; return cmp;
@ -183,4 +187,12 @@ final class Cost {
buf.append(']'); buf.append(']');
return buf.toString(); return buf.toString();
} }
public boolean isNarrowingConversion() {
return fCouldNarrow;
}
public void setCouldNarrow() {
fCouldNarrow= true;
}
} }

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2009 Wind River Systems, Inc. and others. * Copyright (c) 2009, 2010 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -77,7 +77,7 @@ class FunctionCost {
Cost cost = fCosts[i]; Cost cost = fCosts[i];
if (cost.isDeferredUDC()) { if (cost.isDeferredUDC()) {
Cost udcCost= Conversions.checkUserDefinedConversionSequence(fSourceIsLValue.get(i), cost.source, cost.target, false); Cost udcCost= Conversions.checkUserDefinedConversionSequence(fSourceIsLValue.get(i), cost.source, cost.target, false);
if (udcCost == null) { if (udcCost == null || udcCost.getRank() == Rank.NO_MATCH) {
return false; return false;
} }
fCosts[i]= udcCost; fCosts[i]= udcCost;

View file

@ -0,0 +1,84 @@
/*******************************************************************************
* Copyright (c) 2010 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
import java.util.BitSet;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTInitializerClause;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerList;
/**
* Wrapper for initializer lists to allow for participation in the overload resolution.
*/
class InitializerListType implements IType {
private final ICPPASTInitializerList fInitializerList;
private IType[] fExpressionTypes;
private BitSet fLValues;
public InitializerListType(ICPPASTInitializerList list) {
fInitializerList= list;
}
public boolean isSameType(IType type) {
return false;
}
@Override
public Object clone() {
try {
return super.clone();
} catch (CloneNotSupportedException e) {
// Will not happen, we IType extends Clonable.
return null;
}
}
public ICPPASTInitializerList getInitializerList() {
return fInitializerList;
}
public IType[] getExpressionTypes() {
if (fExpressionTypes == null) {
final IASTInitializerClause[] clauses = fInitializerList.getClauses();
fExpressionTypes= new IType[clauses.length];
for (int i = 0; i < clauses.length; i++) {
IASTInitializerClause clause = clauses[i];
if (clause instanceof IASTExpression) {
fExpressionTypes[i]= ((IASTExpression) clause).getExpressionType();
} else if (clause instanceof ICPPASTInitializerList) {
fExpressionTypes[i]= new InitializerListType((ICPPASTInitializerList) clause);
} else {
assert false;
}
}
}
return fExpressionTypes;
}
public BitSet getIsLValue() {
if (fLValues == null) {
final IASTInitializerClause[] clauses = fInitializerList.getClauses();
fLValues= new BitSet(clauses.length);
for (int i = 0; i < clauses.length; i++) {
IASTInitializerClause clause = clauses[i];
if (clause instanceof IASTExpression) {
if (((IASTExpression) clause).isLValue()) {
fLValues.set(i);
}
}
}
}
return fLValues;
}
}

View file

@ -49,6 +49,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeleteExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTElaboratedTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTElaboratedTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExplicitTemplateInstantiation; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExplicitTemplateInstantiation;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFieldReference; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFieldReference;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerList;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTParameterDeclaration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTParameterDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
@ -101,12 +102,14 @@ public class LookupData {
public boolean firstArgIsImpliedMethodArg = false; public boolean firstArgIsImpliedMethodArg = false;
public boolean ignoreMembers = false; public boolean ignoreMembers = false;
private ICPPASTParameterDeclaration[] functionParameters;
private IASTInitializerClause[] functionArgs;
private IType[] functionArgTypes;
private BitSet functionArgLValues;
public ICPPClassType skippedScope; public ICPPClassType skippedScope;
public Object foundItems = null; public Object foundItems = null;
private Object[] functionArgs;
private IType[] functionArgTypes;
public ProblemBinding problem; public ProblemBinding problem;
private BitSet functionArgLValues;
public LookupData(IASTName n) { public LookupData(IASTName n) {
astName = n; astName = n;
@ -529,26 +532,26 @@ public class LookupData {
} }
public IType[] getFunctionArgumentTypes() { public IType[] getFunctionArgumentTypes() {
if (functionArgTypes == null && functionArgs != null) { if (functionArgTypes == null) {
if (functionArgs instanceof ICPPASTParameterDeclaration[]) { if (functionArgs != null) {
ICPPASTParameterDeclaration[] pdecls= (ICPPASTParameterDeclaration[]) functionArgs; IASTInitializerClause[] exprs= functionArgs;
functionArgTypes= new IType[pdecls.length];
for (int i = 0; i < pdecls.length; i++) {
functionArgTypes[i] = SemanticUtil.getSimplifiedType(CPPVisitor.createParameterType(
pdecls[i], true));
}
} else if (functionArgs instanceof IASTInitializerClause[]) {
IASTInitializerClause[] exprs= (IASTInitializerClause[]) functionArgs;
functionArgTypes= new IType[exprs.length]; functionArgTypes= new IType[exprs.length];
for (int i = 0; i < exprs.length; i++) { for (int i = 0; i < exprs.length; i++) {
IASTInitializerClause e = exprs[i]; IASTInitializerClause e = exprs[i];
if (e instanceof IASTExpression) { if (e instanceof IASTExpression) {
IType etype= ((IASTExpression) e).getExpressionType(); IType etype= ((IASTExpression) e).getExpressionType();
functionArgTypes[i]= SemanticUtil.getSimplifiedType(etype); functionArgTypes[i]= SemanticUtil.getSimplifiedType(etype);
} else { } else if (e instanceof ICPPASTInitializerList) {
// mstodo handle braced init list functionArgTypes[i]= new InitializerListType((ICPPASTInitializerList) e);
} }
} }
} else if (functionParameters != null) {
ICPPASTParameterDeclaration[] pdecls= functionParameters;
functionArgTypes= new IType[pdecls.length];
for (int i = 0; i < pdecls.length; i++) {
functionArgTypes[i] = SemanticUtil.getSimplifiedType(CPPVisitor.createParameterType(
pdecls[i], true));
}
} }
} }
return functionArgTypes; return functionArgTypes;
@ -564,7 +567,7 @@ public class LookupData {
if (arg instanceof IASTExpression) { if (arg instanceof IASTExpression) {
functionArgLValues.set(i, ((IASTExpression) arg).isLValue()); functionArgLValues.set(i, ((IASTExpression) arg).isLValue());
} else { } else {
// mstodo handle braced init list functionArgLValues.set(i, false);
} }
} }
} else { } else {
@ -580,32 +583,24 @@ public class LookupData {
return functionArgLValues; return functionArgLValues;
} }
public void setFunctionArgumentTypes(IType[] paramTypes) {
functionArgTypes= paramTypes;
}
public void setFunctionParameters(ICPPASTParameterDeclaration[] parameters) { public void setFunctionParameters(ICPPASTParameterDeclaration[] parameters) {
functionArgs= parameters; functionParameters= parameters;
} }
public IASTInitializerClause[] getFunctionArguments() { public IASTInitializerClause[] getFunctionArguments() {
if (functionArgs instanceof IASTInitializerClause[]) return functionArgs;
return (IASTInitializerClause[]) functionArgs;
return null;
} }
public int getFunctionArgumentCount() { public int getFunctionArgumentCount() {
if (functionArgs != null) if (functionArgs != null)
return functionArgs.length; return functionArgs.length;
if (functionArgTypes != null) if (functionParameters != null)
return functionArgTypes.length; return functionParameters.length;
return 0; return 0;
} }
public boolean hasArgumentTypes() { public boolean hasFunctionArguments() {
return functionArgTypes != null || functionArgs != null; return functionArgs != null || functionParameters != null;
} }
public IBinding[] getFoundBindings() { public IBinding[] getFoundBindings() {