mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-24 09:25:31 +02:00
Bug 324096: Update for initializer lists, c++ issue 990.
This commit is contained in:
parent
e0657555f3
commit
737591823b
6 changed files with 125 additions and 9 deletions
|
@ -14,6 +14,9 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.cdt.core.parser.tests.ast2;
|
||||
|
||||
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE;
|
||||
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.XVALUE;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.StringReader;
|
||||
import java.util.Arrays;
|
||||
|
@ -8135,11 +8138,13 @@ public class AST2CPPTests extends AST2BaseTest {
|
|||
// struct S {
|
||||
// S(std::initializer_list<double>) {}
|
||||
// S(std::initializer_list<int>) {}
|
||||
// S() {}
|
||||
// };
|
||||
// void fs(S){}
|
||||
// void tests() {
|
||||
// fs({1,2,3});
|
||||
// fs({1.0,2.0,3.0});
|
||||
// fs({});
|
||||
// }
|
||||
public void testListInitialization_302412a() throws Exception {
|
||||
String code= getAboveComment();
|
||||
|
@ -8956,4 +8961,102 @@ public class AST2CPPTests extends AST2BaseTest {
|
|||
ref= bh.assertNonProblem("g(\"abc\")", 1);
|
||||
assertSame(g, ref);
|
||||
}
|
||||
|
||||
// struct A {
|
||||
// int m;
|
||||
// };
|
||||
// A&& operator+(A, A);
|
||||
// A&& f();
|
||||
// A a;
|
||||
// A&& ar = static_cast<A&&>(a);
|
||||
// void test() {
|
||||
// f(); // xvalue
|
||||
// f().m; // xvalue
|
||||
// static_cast<A&&>(a); // xvalue
|
||||
// a+a; // xvalue
|
||||
// ar; // rvalue
|
||||
// }
|
||||
public void testXValueCategories() throws Exception {
|
||||
String code= getAboveComment();
|
||||
IASTTranslationUnit tu= parseAndCheckBindings(code);
|
||||
ICPPASTFunctionDefinition fdef= getDeclaration(tu, 5);
|
||||
IASTExpression expr;
|
||||
|
||||
expr= getExpressionOfStatement(fdef, 0);
|
||||
assertEquals(XVALUE, expr.getValueCategory());
|
||||
assertEquals("A", ASTTypeUtil.getType(expr.getExpressionType()));
|
||||
|
||||
expr= getExpressionOfStatement(fdef, 1);
|
||||
assertEquals(XVALUE, expr.getValueCategory());
|
||||
assertEquals("int", ASTTypeUtil.getType(expr.getExpressionType()));
|
||||
|
||||
expr= getExpressionOfStatement(fdef, 2);
|
||||
assertEquals(XVALUE, expr.getValueCategory());
|
||||
assertEquals("A", ASTTypeUtil.getType(expr.getExpressionType()));
|
||||
|
||||
expr= getExpressionOfStatement(fdef, 3);
|
||||
assertEquals(XVALUE, expr.getValueCategory());
|
||||
assertEquals("A", ASTTypeUtil.getType(expr.getExpressionType()));
|
||||
|
||||
// ar;
|
||||
expr= getExpressionOfStatement(fdef, 4);
|
||||
assertEquals(LVALUE, expr.getValueCategory());
|
||||
assertEquals("A", ASTTypeUtil.getType(expr.getExpressionType()));
|
||||
}
|
||||
|
||||
// void f() {
|
||||
// int i;
|
||||
// int f1();
|
||||
// int&& f2();
|
||||
// int g(const int&);
|
||||
// int g(const int&&);
|
||||
// int j = g(i); // calls g(const int&)
|
||||
// int k = g(f1()); // calls g(const int&&)
|
||||
// int l = g(f2()); // calls g(const int&&)
|
||||
// }
|
||||
public void testRankingOfReferenceBindings() throws Exception {
|
||||
String code= getAboveComment();
|
||||
BindingAssertionHelper bh= new BindingAssertionHelper(code, true);
|
||||
IFunction g1= bh.assertNonProblem("g(const int&)", 1);
|
||||
IFunction g2= bh.assertNonProblem("g(const int&&)", 1);
|
||||
|
||||
IFunction ref;
|
||||
ref= bh.assertNonProblem("g(i);", 1);
|
||||
assertSame(g1, ref);
|
||||
ref= bh.assertNonProblem("g(f1());", 1);
|
||||
assertSame(g2, ref);
|
||||
ref= bh.assertNonProblem("g(f2());", 1);
|
||||
assertSame(g2, ref);
|
||||
}
|
||||
|
||||
// namespace std {
|
||||
// template<typename T> class initializer_list;
|
||||
// }
|
||||
// struct S {
|
||||
// S(std::initializer_list<double>); // #1
|
||||
// S(std::initializer_list<int>); // #2
|
||||
// S(); // #3
|
||||
// };
|
||||
// S s1 = { 1.0, 2.0, 3.0 }; // invoke #1
|
||||
// S s2 = { 1, 2, 3 }; // invoke #2
|
||||
// S s3 = { }; // invoke #3
|
||||
public void testEmptyInitializerList_324096() throws Exception {
|
||||
String code= getAboveComment();
|
||||
BindingAssertionHelper bh= new BindingAssertionHelper(code, true);
|
||||
IFunction ctor1= bh.assertNonProblem("S(std::initializer_list<double>);", 1);
|
||||
IFunction ctor2= bh.assertNonProblem("S(std::initializer_list<int>);", 1);
|
||||
IFunction ctor3= bh.assertNonProblem("S();", 1);
|
||||
|
||||
IASTName name;
|
||||
IASTImplicitNameOwner dtor;
|
||||
name= bh.findName("s1", 2);
|
||||
dtor= (IASTImplicitNameOwner) name.getParent();
|
||||
assertSame(ctor1, dtor.getImplicitNames()[0].resolveBinding());
|
||||
name= bh.findName("s2", 2);
|
||||
dtor= (IASTImplicitNameOwner) name.getParent();
|
||||
assertSame(ctor2, dtor.getImplicitNames()[0].resolveBinding());
|
||||
name= bh.findName("s3", 2);
|
||||
dtor= (IASTImplicitNameOwner) name.getParent();
|
||||
assertSame(ctor3, dtor.getImplicitNames()[0].resolveBinding());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1758,13 +1758,13 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
|
|||
return funcDefinition;
|
||||
}
|
||||
|
||||
protected abstract IASTInitializer optionalInitializer(DeclarationOptions options)
|
||||
protected abstract IASTInitializer optionalInitializer(IASTDeclarator dtor, DeclarationOptions options)
|
||||
throws EndOfFileException, BacktrackException;
|
||||
|
||||
protected IASTDeclarator addInitializer(FoundAggregateInitializer e, DeclarationOptions options)
|
||||
throws EndOfFileException, BacktrackException {
|
||||
final IASTDeclarator d = e.fDeclarator;
|
||||
IASTInitializer i = optionalInitializer(options);
|
||||
IASTInitializer i = optionalInitializer(d, options);
|
||||
if (i != null) {
|
||||
d.setInitializer(i);
|
||||
((ASTNode) d).setLength(calculateEndOffset(i) - ((ASTNode) d).getOffset());
|
||||
|
|
|
@ -134,7 +134,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected IASTInitializer optionalInitializer(DeclarationOptions options) throws EndOfFileException, BacktrackException {
|
||||
protected IASTInitializer optionalInitializer(IASTDeclarator dtor, DeclarationOptions options) throws EndOfFileException, BacktrackException {
|
||||
if (LTcatchEOF(1) == IToken.tASSIGN) {
|
||||
final int offset= consume().getOffset();
|
||||
IASTInitializerClause initClause = initClause(false);
|
||||
|
@ -1315,7 +1315,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
|
|||
if (lt1 == IToken.tASSIGN && LT(2) == IToken.tLBRACE)
|
||||
throw new FoundAggregateInitializer(declspec, d);
|
||||
|
||||
IASTInitializer i = optionalInitializer(option);
|
||||
IASTInitializer i = optionalInitializer(d, option);
|
||||
if (i != null) {
|
||||
d.setInitializer(i);
|
||||
((ASTNode) d).setLength(calculateEndOffset(i) - ((ASTNode) d).getOffset());
|
||||
|
|
|
@ -2975,7 +2975,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
|||
if (LTcatchEOF(1) == IToken.tASSIGN && LTcatchEOF(2) == IToken.tLBRACE)
|
||||
throw new FoundAggregateInitializer(declspec, dtor);
|
||||
|
||||
IASTInitializer initializer= optionalInitializer(option);
|
||||
IASTInitializer initializer= optionalInitializer(dtor, option);
|
||||
if (initializer != null) {
|
||||
if (initializer instanceof IASTInitializerList
|
||||
&& ((IASTInitializerList) initializer).getSize() == 0) {
|
||||
|
@ -3009,7 +3009,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
|||
* braced-init-list
|
||||
*/
|
||||
@Override
|
||||
protected IASTInitializer optionalInitializer(DeclarationOptions option) throws EndOfFileException, BacktrackException {
|
||||
protected IASTInitializer optionalInitializer(IASTDeclarator dtor, DeclarationOptions option) throws EndOfFileException, BacktrackException {
|
||||
final int lt1= LTcatchEOF(1);
|
||||
|
||||
// = initializer-clause
|
||||
|
@ -3020,7 +3020,8 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
|||
return null;
|
||||
|
||||
int offset= consume().getOffset();
|
||||
IASTInitializerClause initClause = initClause(LT(1) == IToken.tLBRACE);
|
||||
final boolean allowSkipping = LT(1) == IToken.tLBRACE && specifiesArray(dtor);
|
||||
IASTInitializerClause initClause = initClause(allowSkipping);
|
||||
IASTEqualsInitializer initExpr= nodeFactory.newEqualsInitializer(initClause);
|
||||
return setRange(initExpr, offset, calculateEndOffset(initClause));
|
||||
}
|
||||
|
@ -3037,6 +3038,11 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
|||
return null;
|
||||
}
|
||||
|
||||
private boolean specifiesArray(IASTDeclarator dtor) {
|
||||
dtor = ASTQueries.findTypeRelevantDeclarator(dtor);
|
||||
return dtor instanceof IASTArrayDeclarator;
|
||||
}
|
||||
|
||||
private IASTInitializer bracedOrCtorStyleInitializer() throws EndOfFileException, BacktrackException {
|
||||
final int lt1= LT(1);
|
||||
if (lt1 == IToken.tLPAREN) {
|
||||
|
|
|
@ -2970,7 +2970,7 @@ public class CPPSemantics {
|
|||
sourceType= new InitializerListType((ICPPASTInitializerList) initClause);
|
||||
}
|
||||
if (sourceType != null) {
|
||||
Cost c= Conversions.copyInitializationOfClass(isLValue, sourceType, classType, false);
|
||||
Cost c= Conversions.checkImplicitConversionSequence(type, sourceType, isLValue, UDCMode.ALLOWED, Context.ORDINARY);
|
||||
if (c.converts()) {
|
||||
IFunction f= c.getUserDefinedConversion();
|
||||
if (f instanceof ICPPConstructor)
|
||||
|
|
|
@ -571,7 +571,14 @@ public class Conversions {
|
|||
final ICPPConstructor[] constructors = t.getConstructors();
|
||||
ICPPConstructor[] ctors= constructors;
|
||||
for (ICPPConstructor ctor : ctors) {
|
||||
if (ctor.getRequiredArgumentCount() <= 1) {
|
||||
final int minArgCount = ctor.getRequiredArgumentCount();
|
||||
if (minArgCount == 0) {
|
||||
if (arg.getExpressionTypes().length == 0) {
|
||||
Cost c= new Cost(arg, t, Rank.IDENTITY);
|
||||
c.setUserDefinedConversion(ctor);
|
||||
return c;
|
||||
}
|
||||
} else if (minArgCount <= 1) {
|
||||
IType[] parTypes= ctor.getType().getParameterTypes();
|
||||
if (parTypes.length > 0) {
|
||||
final IType target = parTypes[0];
|
||||
|
|
Loading…
Add table
Reference in a new issue