mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-09 18:56:02 +02:00
Bug 156668: Implicit ctors for automatic variables.
This commit is contained in:
parent
ca68f6bb04
commit
200c531f33
7 changed files with 146 additions and 57 deletions
|
@ -9118,4 +9118,40 @@ public class AST2CPPTests extends AST2BaseTest {
|
||||||
assertSame(fc, ref);
|
assertSame(fc, ref);
|
||||||
bh.assertNonProblem("g(0 ? p : \"\")", 1); //
|
bh.assertNonProblem("g(0 ? p : \"\")", 1); //
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// struct C {
|
||||||
|
// C();
|
||||||
|
// C(int a, int b);
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// C c1; // C()
|
||||||
|
// C c2(1,2); // C(int, int)
|
||||||
|
// C c3 ({1,2}); // C(C(int, int)) // copy ctor is elided
|
||||||
|
// C c4 ={1,2}; // C(C(int, int)) // copy ctor is elided
|
||||||
|
// C c5 {1,2}; // C(int, int)
|
||||||
|
public void testCtorForAutomaticVariables_156668() throws Exception {
|
||||||
|
String code= getAboveComment();
|
||||||
|
BindingAssertionHelper bh= new BindingAssertionHelper(code, true);
|
||||||
|
IFunction ctor1= bh.assertNonProblem("C();", 1);
|
||||||
|
IFunction ctor2= bh.assertNonProblem("C(int a, int b);", 1);
|
||||||
|
|
||||||
|
IASTName name;
|
||||||
|
IASTImplicitNameOwner dtor;
|
||||||
|
name= bh.findName("c1", 2);
|
||||||
|
dtor= (IASTImplicitNameOwner) name.getParent();
|
||||||
|
assertSame(ctor1, dtor.getImplicitNames()[0].resolveBinding());
|
||||||
|
name= bh.findName("c2", 2);
|
||||||
|
dtor= (IASTImplicitNameOwner) name.getParent();
|
||||||
|
assertSame(ctor2, dtor.getImplicitNames()[0].resolveBinding());
|
||||||
|
name= bh.findName("c3", 2);
|
||||||
|
dtor= (IASTImplicitNameOwner) name.getParent();
|
||||||
|
assertSame(ctor2, dtor.getImplicitNames()[0].resolveBinding());
|
||||||
|
name= bh.findName("c4", 2);
|
||||||
|
dtor= (IASTImplicitNameOwner) name.getParent();
|
||||||
|
assertSame(ctor2, dtor.getImplicitNames()[0].resolveBinding());
|
||||||
|
name= bh.findName("c5", 2);
|
||||||
|
dtor= (IASTImplicitNameOwner) name.getParent();
|
||||||
|
assertSame(ctor2, dtor.getImplicitNames()[0].resolveBinding());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -196,6 +196,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalNamespaceScope;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalNamespaceScope;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownClassType;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownType;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownType;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.OverloadableOperator;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.OverloadableOperator;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Conversions.Context;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Conversions.Context;
|
||||||
|
@ -2399,7 +2400,14 @@ public class CPPSemantics {
|
||||||
((FunctionSetType) iType).applySelectedFunction(bestFnCost.getCost(i).getSelectedFunction());
|
((FunctionSetType) iType).applySelectedFunction(bestFnCost.getCost(i).getSelectedFunction());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return bestFnCost.getFunction();
|
IFunction result= bestFnCost.getFunction();
|
||||||
|
if (bestFnCost.isDirectInitWithCopyCtor()) {
|
||||||
|
Cost c0= bestFnCost.getCost(0);
|
||||||
|
IFunction firstConversion= c0.getUserDefinedConversion();
|
||||||
|
if (firstConversion instanceof ICPPConstructor)
|
||||||
|
return firstConversion;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void setTargetedFunctionsToUnknown(IType[] argTypes) {
|
private static void setTargetedFunctionsToUnknown(IType[] argTypes) {
|
||||||
|
@ -2450,8 +2458,8 @@ public class CPPSemantics {
|
||||||
if (iast != i) {
|
if (iast != i) {
|
||||||
fns[i]= fns[iast];
|
fns[i]= fns[iast];
|
||||||
fns[iast]= fn;
|
fns[iast]= fn;
|
||||||
iast++;
|
|
||||||
}
|
}
|
||||||
|
iast++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2545,9 +2553,10 @@ public class CPPSemantics {
|
||||||
|
|
||||||
Context ctx= Context.ORDINARY;
|
Context ctx= Context.ORDINARY;
|
||||||
if (j==0 && sourceLen == 1 && fn instanceof ICPPConstructor) {
|
if (j==0 && sourceLen == 1 && fn instanceof ICPPConstructor) {
|
||||||
if (paramType instanceof ICPPReferenceType && !((ICPPReferenceType) paramType).isRValueReference()) {
|
if (paramType instanceof ICPPReferenceType) {
|
||||||
if (((ICPPConstructor) fn).getClassOwner().isSameType(getNestedType(paramType, TDEF|REF|CVTYPE))) {
|
if (((ICPPConstructor) fn).getClassOwner().isSameType(getNestedType(paramType, TDEF|REF|CVTYPE))) {
|
||||||
ctx= Context.FIRST_PARAM_OF_DIRECT_COPY_CTOR;
|
ctx= Context.FIRST_PARAM_OF_DIRECT_COPY_CTOR;
|
||||||
|
result.setIsDirectInitWithCopyCtor(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2940,7 +2949,8 @@ public class CPPSemantics {
|
||||||
IASTDeclarator dtor= ASTQueries.findOutermostDeclarator(declarator);
|
IASTDeclarator dtor= ASTQueries.findOutermostDeclarator(declarator);
|
||||||
IASTNode parent = dtor.getParent();
|
IASTNode parent = dtor.getParent();
|
||||||
if (parent instanceof IASTSimpleDeclaration) {
|
if (parent instanceof IASTSimpleDeclaration) {
|
||||||
if (dtor.getInitializer() == null) {
|
final IASTInitializer initializer = dtor.getInitializer();
|
||||||
|
if (initializer == null) {
|
||||||
IASTDeclSpecifier declSpec = ((IASTSimpleDeclaration) parent).getDeclSpecifier();
|
IASTDeclSpecifier declSpec = ((IASTSimpleDeclaration) parent).getDeclSpecifier();
|
||||||
parent = parent.getParent();
|
parent = parent.getParent();
|
||||||
if (parent instanceof IASTCompositeTypeSpecifier ||
|
if (parent instanceof IASTCompositeTypeSpecifier ||
|
||||||
|
@ -2950,7 +2960,7 @@ public class CPPSemantics {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return findImplicitlyCalledConstructor(declarator.getName(), dtor.getInitializer());
|
return findImplicitlyCalledConstructor(declarator.getName(), initializer);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -2976,10 +2986,12 @@ public class CPPSemantics {
|
||||||
type = SemanticUtil.getNestedType(((ICPPVariable) binding).getType(), TDEF | CVTYPE);
|
type = SemanticUtil.getNestedType(((ICPPVariable) binding).getType(), TDEF | CVTYPE);
|
||||||
if (!(type instanceof ICPPClassType))
|
if (!(type instanceof ICPPClassType))
|
||||||
return null;
|
return null;
|
||||||
final ICPPClassType classType = (ICPPClassType) type;
|
if (type instanceof ICPPClassTemplate || type instanceof ICPPUnknownClassType || type instanceof IProblemBinding)
|
||||||
|
return null;
|
||||||
|
|
||||||
// Copy initialization
|
final ICPPClassType classType = (ICPPClassType) type;
|
||||||
if (initializer instanceof IASTEqualsInitializer) {
|
if (initializer instanceof IASTEqualsInitializer) {
|
||||||
|
// Copy initialization
|
||||||
IASTEqualsInitializer eqInit= (IASTEqualsInitializer) initializer;
|
IASTEqualsInitializer eqInit= (IASTEqualsInitializer) initializer;
|
||||||
IASTInitializerClause initClause = eqInit.getInitializerClause();
|
IASTInitializerClause initClause = eqInit.getInitializerClause();
|
||||||
IType sourceType= null;
|
IType sourceType= null;
|
||||||
|
@ -2994,15 +3006,24 @@ public class CPPSemantics {
|
||||||
if (sourceType != null) {
|
if (sourceType != null) {
|
||||||
Cost c= Conversions.checkImplicitConversionSequence(type, sourceType, isLValue, UDCMode.ALLOWED, Context.ORDINARY);
|
Cost c= Conversions.checkImplicitConversionSequence(type, sourceType, isLValue, UDCMode.ALLOWED, Context.ORDINARY);
|
||||||
if (c.converts()) {
|
if (c.converts()) {
|
||||||
IFunction f= c.getUserDefinedConversion();
|
ICPPFunction f = c.getUserDefinedConversion();
|
||||||
|
if (f instanceof ICPPConstructor)
|
||||||
|
return (ICPPConstructor) f;
|
||||||
|
// If a conversion is used, the constructor is elided.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (initializer instanceof ICPPASTInitializerList) {
|
||||||
|
// List initialization
|
||||||
|
final InitializerListType listType = new InitializerListType((ICPPASTInitializerList) initializer);
|
||||||
|
Cost c= Conversions.listInitializationSequence(listType, type, UDCMode.ALLOWED, true);
|
||||||
|
if (c.converts()) {
|
||||||
|
ICPPFunction f = c.getUserDefinedConversion();
|
||||||
if (f instanceof ICPPConstructor)
|
if (f instanceof ICPPConstructor)
|
||||||
return (ICPPConstructor) f;
|
return (ICPPConstructor) f;
|
||||||
}
|
}
|
||||||
return null;
|
} else if (initializer instanceof ICPPASTConstructorInitializer) {
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Direct Initialization
|
// Direct Initialization
|
||||||
|
final IASTInitializerClause[] arguments = ((ICPPASTConstructorInitializer) initializer).getArguments();
|
||||||
CPPASTName astName = new CPPASTName();
|
CPPASTName astName = new CPPASTName();
|
||||||
astName.setName(classType.getNameCharArray());
|
astName.setName(classType.getNameCharArray());
|
||||||
astName.setOffsetAndLength((ASTNode) name);
|
astName.setOffsetAndLength((ASTNode) name);
|
||||||
|
@ -3011,18 +3032,21 @@ public class CPPSemantics {
|
||||||
idExp.setPropertyInParent(IASTFunctionCallExpression.FUNCTION_NAME);
|
idExp.setPropertyInParent(IASTFunctionCallExpression.FUNCTION_NAME);
|
||||||
|
|
||||||
LookupData data = new LookupData(astName);
|
LookupData data = new LookupData(astName);
|
||||||
if (initializer == null) {
|
data.setFunctionArguments(false, arguments);
|
||||||
data.setFunctionArguments(false);
|
|
||||||
} else if (initializer instanceof ICPPASTConstructorInitializer) {
|
|
||||||
data.setFunctionArguments(false, ((ICPPASTConstructorInitializer) initializer).getArguments());
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
data.forceQualified = true;
|
data.forceQualified = true;
|
||||||
data.foundItems = classType.getConstructors();
|
data.foundItems = classType.getConstructors();
|
||||||
binding = resolveAmbiguities(data, astName);
|
binding = resolveAmbiguities(data, astName);
|
||||||
if (binding instanceof ICPPConstructor)
|
if (binding instanceof ICPPConstructor)
|
||||||
return (ICPPConstructor) binding;
|
return (ICPPConstructor) binding;
|
||||||
|
} else if (initializer == null) {
|
||||||
|
// Default initialization
|
||||||
|
ICPPConstructor[] ctors = classType.getConstructors();
|
||||||
|
for (ICPPConstructor ctor : ctors) {
|
||||||
|
if (ctor.getRequiredArgumentCount() == 0)
|
||||||
|
return ctor;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
} catch (DOMException e) {
|
} catch (DOMException e) {
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -85,32 +85,42 @@ public class Conversions {
|
||||||
public static Cost checkImplicitConversionSequence(IType target, IType exprType,
|
public static Cost checkImplicitConversionSequence(IType target, IType exprType,
|
||||||
ValueCategory valueCat, UDCMode udc, Context ctx) throws DOMException {
|
ValueCategory valueCat, UDCMode udc, Context ctx) throws DOMException {
|
||||||
final boolean isImpliedObject= ctx == Context.IMPLICIT_OBJECT;
|
final boolean isImpliedObject= ctx == Context.IMPLICIT_OBJECT;
|
||||||
if (isImpliedObject) {
|
if (isImpliedObject)
|
||||||
udc= UDCMode.FORBIDDEN;
|
udc= UDCMode.FORBIDDEN;
|
||||||
}
|
|
||||||
|
|
||||||
target= getNestedType(target, TDEF);
|
target= getNestedType(target, TDEF);
|
||||||
exprType= getNestedType(exprType, TDEF | REF);
|
exprType= getNestedType(exprType, TDEF | REF);
|
||||||
|
final IType cv1T1= getNestedType(target, TDEF | REF);
|
||||||
|
final IType T1= getNestedType(cv1T1, TDEF | REF | ALLCVQ);
|
||||||
|
|
||||||
|
ReferenceBinding refBindingType= ReferenceBinding.OTHER;
|
||||||
if (target instanceof ICPPReferenceType) {
|
if (target instanceof ICPPReferenceType) {
|
||||||
// [8.5.3-5] initialization of a reference
|
// [8.5.3-5] initialization of a reference
|
||||||
final boolean isLValueRef= !((ICPPReferenceType) target).isRValueReference();
|
final boolean isLValueRef= !((ICPPReferenceType) target).isRValueReference();
|
||||||
final IType cv1T1= getNestedType(target, TDEF | REF);
|
|
||||||
final IType T1= getNestedType(cv1T1, TDEF | REF | ALLCVQ);
|
|
||||||
final IType cv2T2= exprType;
|
final IType cv2T2= exprType;
|
||||||
final IType T2= getNestedType(cv2T2, TDEF | REF | ALLCVQ);
|
final IType T2= getNestedType(cv2T2, TDEF | REF | ALLCVQ);
|
||||||
|
|
||||||
// mstodo: will change when implementing rvalue references on this pointer
|
// mstodo: will change when implementing rvalue references on this pointer
|
||||||
final boolean isImplicitWithoutRefQualifier = isImpliedObject;
|
final boolean isImplicitWithoutRefQualifier = isImpliedObject;
|
||||||
ReferenceBinding refBindingType= ReferenceBinding.OTHER;
|
|
||||||
if (!isImplicitWithoutRefQualifier) {
|
if (!isImplicitWithoutRefQualifier) {
|
||||||
if (isLValueRef) {
|
if (isLValueRef) {
|
||||||
refBindingType= ReferenceBinding.LVALUE_REF;
|
refBindingType= ReferenceBinding.LVALUE_REF;
|
||||||
} else if (valueCat == LVALUE) {
|
} else {
|
||||||
refBindingType= ReferenceBinding.RVALUE_REF_BINDS_RVALUE;
|
refBindingType= ReferenceBinding.RVALUE_REF_BINDS_RVALUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (exprType instanceof InitializerListType) {
|
||||||
|
if (isLValueRef && getCVQualifier(cv1T1) != CVQualifier.c)
|
||||||
|
return Cost.NO_CONVERSION;
|
||||||
|
|
||||||
|
Cost cost= listInitializationSequence(((InitializerListType) exprType), T1, udc, false);
|
||||||
|
if (cost.converts()) {
|
||||||
|
cost.setReferenceBinding(refBindingType);
|
||||||
|
}
|
||||||
|
return cost;
|
||||||
|
}
|
||||||
|
|
||||||
// If the reference is an lvalue reference and ...
|
// If the reference is an lvalue reference and ...
|
||||||
if (isLValueRef) {
|
if (isLValueRef) {
|
||||||
// ... the initializer expression is an lvalue (but is not a bit field)
|
// ... the initializer expression is an lvalue (but is not a bit field)
|
||||||
|
@ -237,24 +247,12 @@ public class Conversions {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Non-reference binding
|
// Non-reference binding
|
||||||
IType uqsource= getNestedType(exprType, TDEF | REF | ALLCVQ);
|
Cost cost= nonReferenceConversion(valueCat, exprType, T1, udc, isImpliedObject);
|
||||||
IType uqtarget= getNestedType(target, TDEF | REF | ALLCVQ);
|
if (cost.converts()) {
|
||||||
|
cost.setReferenceBinding(refBindingType);
|
||||||
// [13.3.3.1-6] Derived to base conversion
|
|
||||||
if (uqsource instanceof ICPPClassType && uqtarget instanceof ICPPClassType) {
|
|
||||||
int depth= SemanticUtil.calculateInheritanceDepth(uqsource, uqtarget);
|
|
||||||
if (depth > -1) {
|
|
||||||
if (depth == 0) {
|
|
||||||
return new Cost(uqsource, uqtarget, Rank.IDENTITY);
|
|
||||||
}
|
}
|
||||||
Cost cost= new Cost(uqsource, uqtarget, Rank.CONVERSION);
|
|
||||||
cost.setInheritanceDistance(depth);
|
|
||||||
return cost;
|
return cost;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return nonReferenceConversion(valueCat, exprType, uqtarget, udc, isImpliedObject);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* C++0x: 13.3.1.6 Initialization by conversion function for direct reference binding
|
* C++0x: 13.3.1.6 Initialization by conversion function for direct reference binding
|
||||||
|
@ -314,7 +312,7 @@ public class Conversions {
|
||||||
if (uqTarget instanceof ICPPClassType) {
|
if (uqTarget instanceof ICPPClassType) {
|
||||||
if (uqSource instanceof ICPPClassType) {
|
if (uqSource instanceof ICPPClassType) {
|
||||||
// 13.3.3.1-6 Conceptual derived to base conversion
|
// 13.3.3.1-6 Conceptual derived to base conversion
|
||||||
int depth= calculateInheritanceDepth(uqTarget, uqSource);
|
int depth= calculateInheritanceDepth(uqSource, uqTarget);
|
||||||
if (depth >= 0) {
|
if (depth >= 0) {
|
||||||
if (depth == 0) {
|
if (depth == 0) {
|
||||||
return new Cost(source, target, Rank.IDENTITY);
|
return new Cost(source, target, Rank.IDENTITY);
|
||||||
|
|
|
@ -74,6 +74,10 @@ public class Cost {
|
||||||
public void setCouldNarrow() {
|
public void setCouldNarrow() {
|
||||||
assert false;
|
assert false;
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
|
public void setSelectedFunction(ICPPFunction function) {
|
||||||
|
assert false;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
IType source;
|
IType source;
|
||||||
|
@ -110,6 +114,11 @@ public class Cost {
|
||||||
fRank= rank;
|
fRank= rank;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public ReferenceBinding getReferenceBinding() {
|
||||||
|
return fReferenceBinding;
|
||||||
|
}
|
||||||
|
|
||||||
public void setReferenceBinding(ReferenceBinding binding) {
|
public void setReferenceBinding(ReferenceBinding binding) {
|
||||||
fReferenceBinding= binding;
|
fReferenceBinding= binding;
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@ class FunctionCost {
|
||||||
private final IFunction fFunction;
|
private final IFunction fFunction;
|
||||||
private final Cost[] fCosts;
|
private final Cost[] fCosts;
|
||||||
private final ValueCategory[] fValueCategories;
|
private final ValueCategory[] fValueCategories;
|
||||||
|
private boolean fIsDirectCopyCtor;
|
||||||
|
|
||||||
public FunctionCost(IFunction fn, int paramCount) {
|
public FunctionCost(IFunction fn, int paramCount) {
|
||||||
fFunction= fn;
|
fFunction= fn;
|
||||||
|
@ -109,6 +110,7 @@ class FunctionCost {
|
||||||
if (!udcCost.converts()) {
|
if (!udcCost.converts()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
udcCost.setReferenceBinding(cost.getReferenceBinding());
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -212,4 +214,12 @@ class FunctionCost {
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setIsDirectInitWithCopyCtor(boolean val) {
|
||||||
|
fIsDirectCopyCtor= val;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isDirectInitWithCopyCtor() {
|
||||||
|
return fIsDirectCopyCtor;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2006, 2009 Wind River Systems, Inc. and others.
|
* Copyright (c) 2006, 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
|
||||||
|
@ -293,7 +293,7 @@ public class BasicCppCallHierarchyTest extends CallHierarchyBaseTest {
|
||||||
// void automatic() {
|
// void automatic() {
|
||||||
// MyClass m;
|
// MyClass m;
|
||||||
// }
|
// }
|
||||||
public void _testAutomaticConstructor_156668() throws Exception {
|
public void testAutomaticConstructor_156668() throws Exception {
|
||||||
String content = readTaggedComment("testAutomaticConstructor");
|
String content = readTaggedComment("testAutomaticConstructor");
|
||||||
IFile file= createFile(getProject(), "testConstructor.cpp", content);
|
IFile file= createFile(getProject(), "testConstructor.cpp", content);
|
||||||
waitForIndexer(fIndex, file, CallHierarchyBaseTest.INDEXER_WAIT_TIME);
|
waitForIndexer(fIndex, file, CallHierarchyBaseTest.INDEXER_WAIT_TIME);
|
||||||
|
@ -304,6 +304,15 @@ public class BasicCppCallHierarchyTest extends CallHierarchyBaseTest {
|
||||||
Tree tree = getCHTreeViewer().getTree();
|
Tree tree = getCHTreeViewer().getTree();
|
||||||
checkTreeNode(tree, 0, "MyClass::MyClass()");
|
checkTreeNode(tree, 0, "MyClass::MyClass()");
|
||||||
checkTreeNode(tree, 0, 0, "automatic()");
|
checkTreeNode(tree, 0, 0, "automatic()");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void _testAutomaticDestructor_156668() throws Exception {
|
||||||
|
String content = readTaggedComment("testAutomaticConstructor");
|
||||||
|
IFile file= createFile(getProject(), "testConstructor.cpp", content);
|
||||||
|
waitForIndexer(fIndex, file, CallHierarchyBaseTest.INDEXER_WAIT_TIME);
|
||||||
|
CEditor editor = openEditor(file);
|
||||||
|
openCallHierarchy(editor);
|
||||||
|
Tree tree = getCHTreeViewer().getTree();
|
||||||
|
|
||||||
editor.selectAndReveal(content.indexOf("~MyClass"), 2);
|
editor.selectAndReveal(content.indexOf("~MyClass"), 2);
|
||||||
openCallHierarchy(editor);
|
openCallHierarchy(editor);
|
||||||
|
|
|
@ -58,6 +58,7 @@ import org.eclipse.cdt.core.index.IIndexName;
|
||||||
import org.eclipse.cdt.ui.CUIPlugin;
|
import org.eclipse.cdt.ui.CUIPlugin;
|
||||||
import org.eclipse.cdt.ui.PreferenceConstants;
|
import org.eclipse.cdt.ui.PreferenceConstants;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.OverloadableOperator;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.OverloadableOperator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1991,6 +1992,8 @@ public class SemanticHighlightings {
|
||||||
&& ((ICPPMethod) binding).isImplicit()) {
|
&& ((ICPPMethod) binding).isImplicit()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (binding instanceof ICPPUnknownBinding)
|
||||||
|
return false;
|
||||||
char[] chars = name.toCharArray();
|
char[] chars = name.toCharArray();
|
||||||
if (chars[0] == '~' || OverloadableOperator.isNew(chars)
|
if (chars[0] == '~' || OverloadableOperator.isNew(chars)
|
||||||
|| OverloadableOperator.isDelete(chars)) {
|
|| OverloadableOperator.isDelete(chars)) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue