1
0
Fork 0
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:
Markus Schorn 2010-09-09 10:01:16 +00:00
parent e0657555f3
commit 737591823b
6 changed files with 125 additions and 9 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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