1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-23 06:32:10 +02:00

Reverted "Bug 393717 - Have constructor definitions reference implicitly

called base constructors via implicit names"

Change-Id: Icb3614727b2da9ed8d0e97ee08c7d4ba7e6eef8d
This commit is contained in:
Sergey Prigogin 2015-08-04 18:40:21 -07:00
parent ad52facf4e
commit f6828f8daf
4 changed files with 14 additions and 214 deletions

View file

@ -24,11 +24,7 @@ import static org.eclipse.cdt.core.parser.ParserLanguage.CPP;
import static org.eclipse.cdt.core.parser.tests.VisibilityAsserts.assertVisibility;
import static org.junit.Assert.assertNotEquals;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import java.util.Arrays;
import java.util.HashSet;
import junit.framework.TestSuite;
import org.eclipse.cdt.core.dom.IName;
import org.eclipse.cdt.core.dom.ast.ASTTypeUtil;
@ -155,7 +151,11 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.cdt.internal.core.index.IndexCPPSignatureUtil;
import org.eclipse.cdt.internal.core.parser.ParserException;
import junit.framework.TestSuite;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import java.util.Arrays;
import java.util.HashSet;
public class AST2CPPTests extends AST2TestBase {
@ -11602,73 +11602,4 @@ public class AST2CPPTests extends AST2TestBase {
// this test will need to be updated.
helper.assertVariableValue("generic_lambdas_supported", 0);
}
// struct A {
// A() {}
// };
//
// struct B {
// B() {}
// };
//
// struct C : A {
// C() {}
// };
//
// struct D : virtual A, virtual B {
// D() {}
// };
//
// struct E {
// E() {}
// };
//
// struct F : D, virtual E {
// F() {}
// };
public void testImplicitlyCalledBaseConstructor_393717() throws Exception {
BindingAssertionHelper helper = getAssertionHelper();
ICPPConstructor aCtor = helper.assertNonProblem("A()", "A");
ICPPConstructor bCtor = helper.assertNonProblem("B()", "B");
ICPPConstructor dCtor = helper.assertNonProblem("D()", "D");
ICPPConstructor eCtor = helper.assertNonProblem("E()", "E");
ICPPASTFunctionDefinition ctorDef = helper.assertNode("C() {}");
IASTImplicitName[] implicitNames = ((IASTImplicitNameOwner) ctorDef).getImplicitNames();
assertEquals(1, implicitNames.length);
assertEquals(aCtor, implicitNames[0].resolveBinding());
ctorDef = helper.assertNode("D() {}");
implicitNames = ((IASTImplicitNameOwner) ctorDef).getImplicitNames();
sortNames(implicitNames);
assertEquals(2, implicitNames.length);
assertEquals(aCtor, implicitNames[0].resolveBinding());
assertEquals(bCtor, implicitNames[1].resolveBinding());
ctorDef = helper.assertNode("F() {}");
implicitNames = ((IASTImplicitNameOwner) ctorDef).getImplicitNames();
sortNames(implicitNames);
assertEquals(4, implicitNames.length);
assertEquals(aCtor, implicitNames[0].resolveBinding());
assertEquals(bCtor, implicitNames[1].resolveBinding());
assertEquals(dCtor, implicitNames[2].resolveBinding());
assertEquals(eCtor, implicitNames[3].resolveBinding());
}
// struct A {
// A(int, int);
// };
// void a(A);
// int main() {
// a(A{3, 4});
// }
public void testImplicitConstructorNameInTypeConstructorExpression_447431() throws Exception {
BindingAssertionHelper helper = getAssertionHelper();
ICPPConstructor ctor = helper.assertNonProblem("A(int, int)", "A");
ICPPASTSimpleTypeConstructorExpression typeConstructorExpr = helper.assertNode("A{3, 4}");
IASTImplicitName[] implicitNames = ((IASTImplicitNameOwner) typeConstructorExpr).getImplicitNames();
assertEquals(1, implicitNames.length);
assertEquals(ctor, implicitNames[0].resolveBinding());
}
}

View file

@ -20,8 +20,6 @@ import static org.eclipse.cdt.core.parser.ParserLanguage.CPP;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -915,15 +913,4 @@ public class AST2TestBase extends BaseTestCase {
assertInstance(stmt, IASTExpressionStatement.class);
return (T) ((IASTExpressionStatement) stmt).getExpression();
}
/**
* Sort the given array of AST names lexicographically.
*/
protected static <T extends IASTName> void sortNames(T[] names) {
Arrays.sort(names, new Comparator<IASTName>() {
@Override
public int compare(IASTName a, IASTName b) {
return a.toString().compareTo(b.toString());
}});
}
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2004, 2015 IBM Corporation and others.
* Copyright (c) 2004, 2014 IBM Corporation 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
@ -12,30 +12,18 @@
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
import java.util.HashSet;
import java.util.Set;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTImplicitName;
import org.eclipse.cdt.core.dom.ast.IASTImplicitNameOwner;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTStatement;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorChainInitializer;
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.ICPPBase;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.dom.parser.ASTAttributeOwner;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.ASTQueries;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
@ -44,12 +32,11 @@ import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
* it may contain member initializers.
*/
public class CPPASTFunctionDefinition extends ASTAttributeOwner
implements ICPPASTFunctionDefinition, IASTAmbiguityParent, IASTImplicitNameOwner {
implements ICPPASTFunctionDefinition, IASTAmbiguityParent {
private IASTDeclSpecifier declSpecifier;
private IASTFunctionDeclarator declarator;
private IASTStatement bodyStatement;
private ICPPASTConstructorChainInitializer[] memInits;
private IASTImplicitName[] implicitNames; // for constructors: base constructors called implicitly
private int memInitPos= -1;
private boolean fDeleted;
private boolean fDefaulted;
@ -212,14 +199,6 @@ public class CPPASTFunctionDefinition extends ASTAttributeOwner
return false;
}
if (action.shouldVisitImplicitNames) {
for (IASTImplicitName implicitName : getImplicitNames()) {
if (!implicitName.accept(action)) {
return false;
}
}
}
if (bodyStatement != null && !bodyStatement.accept(action))
return false;
@ -247,67 +226,4 @@ public class CPPASTFunctionDefinition extends ASTAttributeOwner
bodyStatement = (IASTStatement) other;
}
}
@Override
public IASTImplicitName[] getImplicitNames() {
if (implicitNames == null) {
implicitNames = IASTImplicitName.EMPTY_NAME_ARRAY;
IASTName functionName = ASTQueries.findInnermostDeclarator(declarator).getName();
IBinding function = functionName.resolveBinding();
if (function instanceof ICPPConstructor) {
ICPPClassType classOwner = ((ICPPConstructor) function).getClassOwner();
// Determine the bases of 'classOwner' that need to be initialized by this constructor.
Set<ICPPClassType> basesThatNeedInitialization = new HashSet<>();
for (ICPPBase base : ClassTypeHelper.getBases(classOwner, this)) {
IType baseType = base.getBaseClassType();
if (baseType instanceof ICPPClassType) {
basesThatNeedInitialization.add((ICPPClassType) baseType);
}
}
for (ICPPClassType virtualBase : ClassTypeHelper.getVirtualBases(classOwner, this)) {
basesThatNeedInitialization.add(virtualBase);
}
// Go through the bases determined above, and see which ones aren't initialized
// explicitly in the mem-initializer list.
for (ICPPClassType base : basesThatNeedInitialization) {
if (!isInitializedExplicitly(base)) {
// Try to find a default constructor to create an implicit name for.
for (ICPPConstructor constructor : ClassTypeHelper.getConstructors(base, this)) {
if (constructor.getRequiredArgumentCount() == 0) { // default constructor
CPPASTImplicitName ctorName = new CPPASTImplicitName(
constructor.getNameCharArray(), this);
ctorName.setBinding(constructor);
ctorName.setOffsetAndLength((ASTNode) functionName);
implicitNames = ArrayUtil.append(implicitNames, ctorName);
break;
}
}
}
}
}
implicitNames = ArrayUtil.trim(implicitNames);
}
return implicitNames;
}
// Returns whether the base type 'base' is explicitly initialized by one of the mem-initializers
// of this constructor.
private boolean isInitializedExplicitly(ICPPClassType base) {
for (ICPPASTConstructorChainInitializer memInitializer : getMemberInitializers()) {
IBinding binding = memInitializer.getMemberInitializerId().resolveBinding();
if (binding instanceof IType) {
if (((IType) binding).isSameType(base)) {
return true;
}
}
if (binding instanceof ICPPConstructor) {
if (((ICPPConstructor) binding).getClassOwner().isSameType(base)) {
return true;
}
}
}
return false;
}
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2004, 2015 IBM Corporation and others.
* Copyright (c) 2004, 2014 IBM Corporation 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
@ -24,7 +24,6 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.cdt.core.dom.ast.ASTTypeUtil;
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
@ -285,15 +284,15 @@ public class ClassTypeHelper {
* @return An array of base classes in arbitrary order.
*/
public static ICPPClassType[] getAllBases(ICPPClassType classType, IASTNode point) {
Set<ICPPClassType> result= new HashSet<>();
HashSet<ICPPClassType> result= new HashSet<>();
result.add(classType);
getAllBases(classType, result, point);
result.remove(classType);
return result.toArray(new ICPPClassType[result.size()]);
}
private static void getAllBases(ICPPClassType classType, Set<ICPPClassType> result, IASTNode point) {
ICPPBase[] bases= getBases(classType, point);
private static void getAllBases(ICPPClassType classType, HashSet<ICPPClassType> result, IASTNode point) {
ICPPBase[] bases= ClassTypeHelper.getBases(classType, point);
for (ICPPBase base : bases) {
IBinding b= base.getBaseClass();
if (b instanceof ICPPClassType) {
@ -305,39 +304,6 @@ public class ClassTypeHelper {
}
}
/**
* Returns all (direct or indirect) virtual base classes of 'classType'.
* @param point the point of instantiation for name lookups
*/
public static ICPPClassType[] getVirtualBases(ICPPClassType classType, IASTNode point) {
Set<ICPPClassType> result = new HashSet<>();
result.add(classType);
getVirtualBases(classType, result, point);
result.remove(classType);
return result.toArray(new ICPPClassType[result.size()]);
}
// Helper function for getVirtualBases(classType, point).
private static void getVirtualBases(ICPPClassType classType, Set<ICPPClassType> result, IASTNode point) {
ICPPBase[] bases = getBases(classType, point);
for (ICPPBase base : bases) {
IBinding b = base.getBaseClass();
if (b instanceof ICPPClassType) {
final ICPPClassType baseClass = (ICPPClassType) b;
if (base.isVirtual()) {
if (result.add(baseClass)) {
getVirtualBases(baseClass, result, point);
}
} else {
// A non-virtual base could have virtual bases in its hierarchy.
if (!result.contains(baseClass)) {
getVirtualBases(baseClass, result, point);
}
}
}
}
}
/**
* Checks inheritance relationship between two classes.
* @return {@code true} if {@code subclass} is a subclass of {@code superclass}.