mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
Bug 350345: Resolving explicit type conversions
This commit is contained in:
parent
8382397625
commit
794aaa995e
9 changed files with 167 additions and 80 deletions
|
@ -87,6 +87,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCastExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConversionName;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConversionName;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionCallExpression;
|
||||||
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.ICPPASTLinkageSpecification;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLinkageSpecification;
|
||||||
|
@ -2551,9 +2552,12 @@ public class AST2CPPTests extends AST2BaseTest {
|
||||||
ICPPConstructor T1_ctor = (ICPPConstructor) col.getName(6)
|
ICPPConstructor T1_ctor = (ICPPConstructor) col.getName(6)
|
||||||
.resolveBinding();
|
.resolveBinding();
|
||||||
ICPPClassType T1 = (ICPPClassType) col.getName(0).resolveBinding();
|
ICPPClassType T1 = (ICPPClassType) col.getName(0).resolveBinding();
|
||||||
|
assertInstances(col, T1_ctor, 1);
|
||||||
|
assertInstances(col, T1, 3);
|
||||||
|
|
||||||
assertInstances(col, T1_ctor, 2);
|
ICPPASTFunctionCallExpression fc= (ICPPASTFunctionCallExpression) col.getName(4).getParent().getParent();
|
||||||
assertInstances(col, T1, 2);
|
IBinding ctor2 = fc.getImplicitNames()[0].resolveBinding();
|
||||||
|
assertSame(T1_ctor, ctor2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// struct S { int i; };
|
// struct S { int i; };
|
||||||
|
|
|
@ -49,6 +49,7 @@ import org.eclipse.cdt.core.dom.ast.IType;
|
||||||
import org.eclipse.cdt.core.dom.ast.ITypedef;
|
import org.eclipse.cdt.core.dom.ast.ITypedef;
|
||||||
import org.eclipse.cdt.core.dom.ast.IVariable;
|
import org.eclipse.cdt.core.dom.ast.IVariable;
|
||||||
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.ICPPASTFunctionCallExpression;
|
||||||
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.ICPPASTQualifiedName;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
|
||||||
|
@ -1725,8 +1726,13 @@ public class AST2TemplateTests extends AST2BaseTest {
|
||||||
ICPPConstructor ctor = (ICPPConstructor) col.getName(2).resolveBinding();
|
ICPPConstructor ctor = (ICPPConstructor) col.getName(2).resolveBinding();
|
||||||
ICPPFunction f = (ICPPFunction) col.getName(5).resolveBinding();
|
ICPPFunction f = (ICPPFunction) col.getName(5).resolveBinding();
|
||||||
|
|
||||||
ICPPSpecialization spec = (ICPPSpecialization) col.getName(11).resolveBinding();
|
final IASTName typeConversion = col.getName(11);
|
||||||
assertSame(spec.getSpecializedBinding(), ctor);
|
ICPPSpecialization spec = (ICPPSpecialization) typeConversion.resolveBinding();
|
||||||
|
assertSame(ctor.getOwner(), spec.getSpecializedBinding());
|
||||||
|
|
||||||
|
final ICPPASTFunctionCallExpression fcall = (ICPPASTFunctionCallExpression) typeConversion.getParent().getParent();
|
||||||
|
final IBinding ctorSpec = fcall.getImplicitNames()[0].resolveBinding();
|
||||||
|
assertSame(ctor, (((ICPPSpecialization) ctorSpec).getSpecializedBinding()));
|
||||||
|
|
||||||
assertSame(f, col.getName(10).resolveBinding());
|
assertSame(f, col.getName(10).resolveBinding());
|
||||||
}
|
}
|
||||||
|
@ -1750,8 +1756,13 @@ public class AST2TemplateTests extends AST2BaseTest {
|
||||||
ICPPConstructor ctor = (ICPPConstructor) col.getName(3).resolveBinding();
|
ICPPConstructor ctor = (ICPPConstructor) col.getName(3).resolveBinding();
|
||||||
ICPPMethod add = (ICPPMethod) col.getName(9).resolveBinding();
|
ICPPMethod add = (ICPPMethod) col.getName(9).resolveBinding();
|
||||||
|
|
||||||
ICPPSpecialization spec = (ICPPSpecialization) col.getName(20).resolveBinding();
|
final IASTName typeConversion = col.getName(20);
|
||||||
assertSame(spec.getSpecializedBinding(), ctor);
|
ICPPSpecialization spec = (ICPPSpecialization) typeConversion.resolveBinding();
|
||||||
|
assertSame(ctor.getOwner(), spec.getSpecializedBinding());
|
||||||
|
|
||||||
|
final ICPPASTFunctionCallExpression fcall = (ICPPASTFunctionCallExpression) typeConversion.getParent().getParent();
|
||||||
|
final IBinding ctorSpec = fcall.getImplicitNames()[0].resolveBinding();
|
||||||
|
assertSame(ctor, (((ICPPSpecialization) ctorSpec).getSpecializedBinding()));
|
||||||
|
|
||||||
assertSame(add, col.getName(19).resolveBinding());
|
assertSame(add, col.getName(19).resolveBinding());
|
||||||
}
|
}
|
||||||
|
@ -1772,8 +1783,13 @@ public class AST2TemplateTests extends AST2BaseTest {
|
||||||
ICPPConstructor ctor = (ICPPConstructor) col.getName(2).resolveBinding();
|
ICPPConstructor ctor = (ICPPConstructor) col.getName(2).resolveBinding();
|
||||||
ICPPMethod add = (ICPPMethod) col.getName(7).resolveBinding();
|
ICPPMethod add = (ICPPMethod) col.getName(7).resolveBinding();
|
||||||
|
|
||||||
ICPPSpecialization spec = (ICPPSpecialization) col.getName(17).resolveBinding();
|
final IASTName typeConversion = col.getName(17);
|
||||||
assertSame(spec.getSpecializedBinding(), ctor);
|
ICPPSpecialization spec = (ICPPSpecialization) typeConversion.resolveBinding();
|
||||||
|
assertSame(ctor.getOwner(), spec.getSpecializedBinding());
|
||||||
|
|
||||||
|
final ICPPASTFunctionCallExpression fcall = (ICPPASTFunctionCallExpression) typeConversion.getParent().getParent();
|
||||||
|
final IBinding ctorSpec = fcall.getImplicitNames()[0].resolveBinding();
|
||||||
|
assertSame(ctor, (((ICPPSpecialization) ctorSpec).getSpecializedBinding()));
|
||||||
|
|
||||||
assertSame(add, col.getName(16).resolveBinding());
|
assertSame(add, col.getName(16).resolveBinding());
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,8 @@ import org.eclipse.core.runtime.CoreException;
|
||||||
* Implementation of problem types.
|
* Implementation of problem types.
|
||||||
*/
|
*/
|
||||||
public class ProblemType implements IProblemType, ISerializableType {
|
public class ProblemType implements IProblemType, ISerializableType {
|
||||||
|
public static final IType UNRESOLVED_NAME = new ProblemType(TYPE_UNRESOLVED_NAME);
|
||||||
|
|
||||||
private final int fID;
|
private final int fID;
|
||||||
|
|
||||||
public ProblemType(int id) {
|
public ProblemType(int id) {
|
||||||
|
|
|
@ -13,21 +13,18 @@
|
||||||
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
||||||
|
|
||||||
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE;
|
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE;
|
||||||
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.prvalueType;
|
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE;
|
||||||
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.typeFromFunctionCall;
|
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.*;
|
||||||
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.typeFromReturnType;
|
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.*;
|
||||||
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.valueCategoryFromFunctionCall;
|
|
||||||
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.valueCategoryFromReturnType;
|
|
||||||
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.CVTYPE;
|
|
||||||
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.REF;
|
|
||||||
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.TDEF;
|
|
||||||
|
|
||||||
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
||||||
|
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.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.IASTInitializerClause;
|
||||||
|
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.IBinding;
|
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||||
import org.eclipse.cdt.core.dom.ast.IFunctionType;
|
import org.eclipse.cdt.core.dom.ast.IFunctionType;
|
||||||
|
@ -38,7 +35,6 @@ import org.eclipse.cdt.core.dom.ast.IType;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpressionList;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpressionList;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionCallExpression;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionCallExpression;
|
||||||
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.ICPPFunction;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
|
||||||
import org.eclipse.cdt.core.parser.IToken;
|
import org.eclipse.cdt.core.parser.IToken;
|
||||||
|
@ -47,6 +43,7 @@ import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.ProblemType;
|
import org.eclipse.cdt.internal.core.dom.parser.ProblemType;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.LookupData;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
|
||||||
|
|
||||||
|
|
||||||
|
@ -124,7 +121,17 @@ public class CPPASTFunctionCallExpression extends ASTNode implements
|
||||||
public IASTImplicitName[] getImplicitNames() {
|
public IASTImplicitName[] getImplicitNames() {
|
||||||
if (implicitNames == null) {
|
if (implicitNames == null) {
|
||||||
ICPPFunction overload = getOperator();
|
ICPPFunction overload = getOperator();
|
||||||
if (overload == null || overload instanceof CPPImplicitFunction) {
|
if (overload == null)
|
||||||
|
return implicitNames = IASTImplicitName.EMPTY_NAME_ARRAY;
|
||||||
|
|
||||||
|
if (isExplicitTypeConversion() != null) {
|
||||||
|
CPPASTImplicitName n1 = new CPPASTImplicitName(overload.getNameCharArray(), this);
|
||||||
|
n1.setOffsetAndLength((ASTNode) functionName);
|
||||||
|
n1.setBinding(overload);
|
||||||
|
return implicitNames= new IASTImplicitName[] {n1};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (overload instanceof CPPImplicitFunction) {
|
||||||
if (!(overload instanceof ICPPMethod) || ((ICPPMethod) overload).isImplicit()) {
|
if (!(overload instanceof ICPPMethod) || ((ICPPMethod) overload).isImplicit()) {
|
||||||
return implicitNames = IASTImplicitName.EMPTY_NAME_ARRAY;
|
return implicitNames = IASTImplicitName.EMPTY_NAME_ARRAY;
|
||||||
}
|
}
|
||||||
|
@ -190,7 +197,7 @@ public class CPPASTFunctionCallExpression extends ASTNode implements
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (implicits != null && implicits.length > 0 && !implicits[1].accept(action))
|
if (implicits != null && implicits.length > 1 && !implicits[1].accept(action))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (action.shouldVisitExpressions && action.leave(this) == ASTVisitor.PROCESS_ABORT)
|
if (action.shouldVisitExpressions && action.leave(this) == ASTVisitor.PROCESS_ABORT)
|
||||||
|
@ -217,35 +224,40 @@ public class CPPASTFunctionCallExpression extends ASTNode implements
|
||||||
public ICPPFunction getOperator() {
|
public ICPPFunction getOperator() {
|
||||||
if (overload == UNINITIALIZED_FUNCTION) {
|
if (overload == UNINITIALIZED_FUNCTION) {
|
||||||
overload= null;
|
overload= null;
|
||||||
IType t= functionName.getExpressionType();
|
IType t= isExplicitTypeConversion();
|
||||||
t= SemanticUtil.getNestedType(t, TDEF | REF | CVTYPE);
|
if (t != null) {
|
||||||
|
t = getNestedType(t, TDEF|CVTYPE|REF);
|
||||||
|
if (t instanceof ICPPClassType && !(t instanceof ICPPUnknownBinding)) {
|
||||||
|
ICPPClassType cls= (ICPPClassType) t;
|
||||||
|
LookupData data= CPPSemantics.createLookupData(((IASTIdExpression) functionName).getName());
|
||||||
|
try {
|
||||||
|
IBinding b= CPPSemantics.resolveFunction(data, cls.getConstructors(), true);
|
||||||
|
if (b instanceof ICPPFunction)
|
||||||
|
overload= (ICPPFunction) b;
|
||||||
|
} catch (DOMException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
t= SemanticUtil.getNestedType(functionName.getExpressionType(), TDEF|REF|CVTYPE);
|
||||||
if (t instanceof ICPPClassType) {
|
if (t instanceof ICPPClassType) {
|
||||||
overload = CPPSemantics.findOverloadedOperator(this, (ICPPClassType)t);
|
overload = CPPSemantics.findOverloadedOperator(this, (ICPPClassType)t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return overload;
|
return overload;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IType getExpressionType() {
|
public IType getExpressionType() {
|
||||||
if (functionName instanceof IASTIdExpression) {
|
// Handle explicit type conversion in functional notation.
|
||||||
// Handle misused id-expression in functional type conversions or simple type initializers.
|
IType t= isExplicitTypeConversion();
|
||||||
final IBinding binding= ((IASTIdExpression) functionName).getName().resolvePreBinding();
|
if (t != null) {
|
||||||
if (binding instanceof ICPPConstructor) {
|
if (t instanceof IProblemBinding) {
|
||||||
IBinding owner= binding.getOwner();
|
return ProblemType.UNRESOLVED_NAME;
|
||||||
if (owner instanceof ICPPClassType) {
|
|
||||||
return (ICPPClassType) owner;
|
|
||||||
}
|
|
||||||
return new ProblemType(ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION);
|
|
||||||
}
|
|
||||||
if (binding instanceof IProblemBinding) {
|
|
||||||
return new ProblemType(ISemanticProblem.TYPE_UNRESOLVED_NAME);
|
|
||||||
}
|
|
||||||
if (binding instanceof IType) {
|
|
||||||
return prvalueType((IType) binding);
|
|
||||||
}
|
}
|
||||||
|
return prvalueType(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
IType t= SemanticUtil.getNestedType(functionName.getExpressionType(), TDEF|REF|CVTYPE);
|
t= SemanticUtil.getNestedType(functionName.getExpressionType(), TDEF|REF|CVTYPE);
|
||||||
if (t instanceof ICPPClassType) {
|
if (t instanceof ICPPClassType) {
|
||||||
if (overload == UNINITIALIZED_FUNCTION) {
|
if (overload == UNINITIALIZED_FUNCTION) {
|
||||||
overload = CPPSemantics.findOverloadedOperator(this, (ICPPClassType)t);
|
overload = CPPSemantics.findOverloadedOperator(this, (ICPPClassType)t);
|
||||||
|
@ -268,11 +280,24 @@ public class CPPASTFunctionCallExpression extends ASTNode implements
|
||||||
return new ProblemType(ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION);
|
return new ProblemType(ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private IType isExplicitTypeConversion() {
|
||||||
|
if (functionName instanceof IASTIdExpression) {
|
||||||
|
final IASTName name = ((IASTIdExpression) functionName).getName();
|
||||||
|
IBinding b= name.resolvePreBinding();
|
||||||
|
if (b instanceof IType)
|
||||||
|
return (IType) b;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isLValue() {
|
public boolean isLValue() {
|
||||||
return getValueCategory() == LVALUE;
|
return getValueCategory() == LVALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ValueCategory getValueCategory() {
|
public ValueCategory getValueCategory() {
|
||||||
|
if (isExplicitTypeConversion() != null)
|
||||||
|
return PRVALUE;
|
||||||
|
|
||||||
IType t= functionName.getExpressionType();
|
IType t= functionName.getExpressionType();
|
||||||
if (t instanceof ICPPClassType) {
|
if (t instanceof ICPPClassType) {
|
||||||
if (overload == UNINITIALIZED_FUNCTION) {
|
if (overload == UNINITIALIZED_FUNCTION) {
|
||||||
|
|
|
@ -308,6 +308,15 @@ public class CPPSemantics {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Explicit type conversion in functional notation
|
||||||
|
if (binding instanceof ICPPClassTemplate && data.astName instanceof ICPPASTTemplateId) {
|
||||||
|
final IASTNode parent = data.astName.getParent();
|
||||||
|
if (parent instanceof IASTIdExpression &&
|
||||||
|
parent.getPropertyInParent() == IASTFunctionCallExpression.FUNCTION_NAME) {
|
||||||
|
return binding;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* 14.6.1-1:
|
/* 14.6.1-1:
|
||||||
* Within the scope of a class template, when the name of the template is neither qualified nor
|
* Within the scope of a class template, when the name of the template is neither qualified nor
|
||||||
* followed by <, it is equivalent to the name followed by the template parameters enclosed in <>.
|
* followed by <, it is equivalent to the name followed by the template parameters enclosed in <>.
|
||||||
|
@ -441,15 +450,15 @@ public class CPPSemantics {
|
||||||
}
|
}
|
||||||
} else if (namePropertyInParent == IASTIdExpression.ID_NAME) {
|
} else if (namePropertyInParent == IASTIdExpression.ID_NAME) {
|
||||||
if (binding instanceof IType) {
|
if (binding instanceof IType) {
|
||||||
IASTNode parent= name.getParent().getParent();
|
final IASTNode idExpr = name.getParent();
|
||||||
if (parent instanceof ICPPASTTemplatedTypeTemplateParameter) {
|
ASTNodeProperty pip = idExpr.getPropertyInParent();
|
||||||
// default for template template parameter is an id-expression, which is a type.
|
if (pip == ICPPASTTemplatedTypeTemplateParameter.DEFAULT_VALUE) {
|
||||||
} else if (parent instanceof ICPPASTUnaryExpression
|
// Default for template template parameter is a type.
|
||||||
&& ((ICPPASTUnaryExpression) parent).getOperator() == IASTUnaryExpression.op_sizeofParameterPack) {
|
} else if (pip == IASTFunctionCallExpression.FUNCTION_NAME) {
|
||||||
// argument of sizeof... can be a type
|
// Explicit type conversion in functional notation.
|
||||||
} else if ((binding instanceof ICPPUnknownType || binding instanceof ITypedef || binding instanceof IEnumeration)
|
} else if (pip == IASTUnaryExpression.OPERAND
|
||||||
&& convertClassToConstructor(data.astName)) {
|
&& ((ICPPASTUnaryExpression) idExpr.getParent()).getOperator() == IASTUnaryExpression.op_sizeofParameterPack) {
|
||||||
// constructor or simple-type constructor
|
// Argument of sizeof... can be a type
|
||||||
} else {
|
} else {
|
||||||
binding= new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_INVALID_TYPE,
|
binding= new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_INVALID_TYPE,
|
||||||
data.getFoundBindings());
|
data.getFoundBindings());
|
||||||
|
@ -511,20 +520,7 @@ public class CPPSemantics {
|
||||||
if (parent instanceof ICPPASTConstructorChainInitializer) {
|
if (parent instanceof ICPPASTConstructorChainInitializer) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (parent instanceof IASTExpression) {
|
if (parent instanceof ICPPASTNamedTypeSpecifier) {
|
||||||
ASTNodeProperty propInParent= parent.getPropertyInParent();
|
|
||||||
if (parent instanceof IASTIdExpression) {
|
|
||||||
parent= parent.getParent();
|
|
||||||
}
|
|
||||||
while (parent instanceof IASTUnaryExpression
|
|
||||||
&& ((IASTUnaryExpression) parent).getOperator() == IASTUnaryExpression.op_bracketedPrimary) {
|
|
||||||
propInParent = parent.getPropertyInParent();
|
|
||||||
parent= parent.getParent();
|
|
||||||
}
|
|
||||||
if (parent instanceof IASTFunctionCallExpression && propInParent == IASTFunctionCallExpression.FUNCTION_NAME) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} else if (parent instanceof ICPPASTNamedTypeSpecifier) {
|
|
||||||
parent= parent.getParent();
|
parent= parent.getParent();
|
||||||
if (parent instanceof IASTTypeId && parent.getParent() instanceof ICPPASTNewExpression) {
|
if (parent instanceof IASTTypeId && parent.getParent() instanceof ICPPASTNewExpression) {
|
||||||
IASTDeclarator dtor = ((IASTTypeId) parent).getAbstractDeclarator();
|
IASTDeclarator dtor = ((IASTTypeId) parent).getAbstractDeclarator();
|
||||||
|
@ -2324,7 +2320,7 @@ public class CPPSemantics {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static IBinding resolveFunction(LookupData data, ICPPFunction[] fns, boolean allowUDC) throws DOMException {
|
public static IBinding resolveFunction(LookupData data, ICPPFunction[] fns, boolean allowUDC) throws DOMException {
|
||||||
fns= (ICPPFunction[]) ArrayUtil.trim(ICPPFunction.class, fns);
|
fns= (ICPPFunction[]) ArrayUtil.trim(ICPPFunction.class, fns);
|
||||||
if (fns == null || fns.length == 0)
|
if (fns == null || fns.length == 0)
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -605,6 +605,10 @@ public class CPPTemplates {
|
||||||
//functions are instantiated as part of the resolution process
|
//functions are instantiated as part of the resolution process
|
||||||
IBinding result= CPPVisitor.createBinding(id);
|
IBinding result= CPPVisitor.createBinding(id);
|
||||||
IASTName templateName = id.getTemplateName();
|
IASTName templateName = id.getTemplateName();
|
||||||
|
if (result instanceof ICPPClassTemplate) {
|
||||||
|
templateName.setBinding(result);
|
||||||
|
id.setBinding(null);
|
||||||
|
} else {
|
||||||
if (result instanceof ICPPTemplateInstance) {
|
if (result instanceof ICPPTemplateInstance) {
|
||||||
templateName.setBinding(((ICPPTemplateInstance) result).getTemplateDefinition());
|
templateName.setBinding(((ICPPTemplateInstance) result).getTemplateDefinition());
|
||||||
} else {
|
} else {
|
||||||
|
@ -612,6 +616,7 @@ public class CPPTemplates {
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
IASTNode parentOfName = id.getParent();
|
IASTNode parentOfName = id.getParent();
|
||||||
boolean isLastName= true;
|
boolean isLastName= true;
|
||||||
|
|
|
@ -2189,7 +2189,7 @@ public:
|
||||||
virtual ~Test();
|
virtual ~Test();
|
||||||
private:
|
private:
|
||||||
void test();
|
void test();
|
||||||
RetValueType exp();
|
RetType exp();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* TEST_H_ */
|
#endif /* TEST_H_ */
|
||||||
|
@ -2218,7 +2218,7 @@ Test::Test() {
|
||||||
Test::~Test() {
|
Test::~Test() {
|
||||||
}
|
}
|
||||||
|
|
||||||
RetValueType Test::exp()
|
RetType Test::exp()
|
||||||
{
|
{
|
||||||
return RetType();
|
return RetType();
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,12 +23,18 @@ import org.eclipse.ui.IWorkbenchWindow;
|
||||||
import org.eclipse.ui.texteditor.ITextEditor;
|
import org.eclipse.ui.texteditor.ITextEditor;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.CCorePlugin;
|
import org.eclipse.cdt.core.CCorePlugin;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.DOMException;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.EScopeKind;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTImplicitName;
|
||||||
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.IBinding;
|
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||||
import org.eclipse.cdt.core.dom.ast.IEnumerator;
|
import org.eclipse.cdt.core.dom.ast.IEnumerator;
|
||||||
import org.eclipse.cdt.core.dom.ast.IFunction;
|
import org.eclipse.cdt.core.dom.ast.IFunction;
|
||||||
import org.eclipse.cdt.core.dom.ast.IVariable;
|
import org.eclipse.cdt.core.dom.ast.IVariable;
|
||||||
import org.eclipse.cdt.core.dom.ast.c.ICExternalBinding;
|
import org.eclipse.cdt.core.dom.ast.c.ICExternalBinding;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionCallExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization;
|
||||||
import org.eclipse.cdt.core.index.IIndex;
|
import org.eclipse.cdt.core.index.IIndex;
|
||||||
import org.eclipse.cdt.core.index.IIndexManager;
|
import org.eclipse.cdt.core.index.IIndexManager;
|
||||||
|
@ -36,7 +42,6 @@ import org.eclipse.cdt.core.index.IIndexName;
|
||||||
import org.eclipse.cdt.core.model.ICElement;
|
import org.eclipse.cdt.core.model.ICElement;
|
||||||
import org.eclipse.cdt.core.model.ICProject;
|
import org.eclipse.cdt.core.model.ICProject;
|
||||||
import org.eclipse.cdt.core.model.ITranslationUnit;
|
import org.eclipse.cdt.core.model.ITranslationUnit;
|
||||||
import org.eclipse.cdt.internal.ui.viewsupport.CElementLabels;
|
|
||||||
import org.eclipse.cdt.ui.CUIPlugin;
|
import org.eclipse.cdt.ui.CUIPlugin;
|
||||||
|
|
||||||
import org.eclipse.cdt.internal.core.model.ext.ICElementHandle;
|
import org.eclipse.cdt.internal.core.model.ext.ICElementHandle;
|
||||||
|
@ -45,6 +50,7 @@ import org.eclipse.cdt.internal.corext.util.CModelUtil;
|
||||||
import org.eclipse.cdt.internal.ui.actions.OpenActionUtil;
|
import org.eclipse.cdt.internal.ui.actions.OpenActionUtil;
|
||||||
import org.eclipse.cdt.internal.ui.util.ExceptionHandler;
|
import org.eclipse.cdt.internal.ui.util.ExceptionHandler;
|
||||||
import org.eclipse.cdt.internal.ui.util.StatusLineHandler;
|
import org.eclipse.cdt.internal.ui.util.StatusLineHandler;
|
||||||
|
import org.eclipse.cdt.internal.ui.viewsupport.CElementLabels;
|
||||||
import org.eclipse.cdt.internal.ui.viewsupport.IndexUI;
|
import org.eclipse.cdt.internal.ui.viewsupport.IndexUI;
|
||||||
|
|
||||||
public class CallHierarchyUI {
|
public class CallHierarchyUI {
|
||||||
|
@ -158,6 +164,19 @@ public class CallHierarchyUI {
|
||||||
IASTName name= IndexUI.getSelectedName(editorInput, sel);
|
IASTName name= IndexUI.getSelectedName(editorInput, sel);
|
||||||
if (name != null) {
|
if (name != null) {
|
||||||
IBinding binding= name.resolveBinding();
|
IBinding binding= name.resolveBinding();
|
||||||
|
if (!CallHierarchyUI.isRelevantForCallHierarchy(binding)) {
|
||||||
|
for (IASTNode parent= name; parent != null; parent= parent.getParent()) {
|
||||||
|
if (parent.getPropertyInParent() == IASTFunctionCallExpression.FUNCTION_NAME) {
|
||||||
|
ICPPASTFunctionCallExpression fcall= (ICPPASTFunctionCallExpression) parent.getParent();
|
||||||
|
if (fcall != null) {
|
||||||
|
IASTImplicitName[] implicit = fcall.getImplicitNames();
|
||||||
|
if (implicit.length > 0)
|
||||||
|
binding= implicit[0].resolveBinding();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if (CallHierarchyUI.isRelevantForCallHierarchy(binding)) {
|
if (CallHierarchyUI.isRelevantForCallHierarchy(binding)) {
|
||||||
if (name.isDefinition()) {
|
if (name.isDefinition()) {
|
||||||
ICElement elem= IndexUI.getCElementForName(project, index, name);
|
ICElement elem= IndexUI.getCElementForName(project, index, name);
|
||||||
|
@ -270,8 +289,15 @@ public class CallHierarchyUI {
|
||||||
public static boolean isRelevantForCallHierarchy(IBinding binding) {
|
public static boolean isRelevantForCallHierarchy(IBinding binding) {
|
||||||
if (binding instanceof ICExternalBinding ||
|
if (binding instanceof ICExternalBinding ||
|
||||||
binding instanceof IEnumerator ||
|
binding instanceof IEnumerator ||
|
||||||
binding instanceof IFunction ||
|
binding instanceof IFunction)
|
||||||
binding instanceof IVariable) {
|
return true;
|
||||||
|
|
||||||
|
if (binding instanceof IVariable) {
|
||||||
|
try {
|
||||||
|
if (binding.getScope().getKind() == EScopeKind.eLocal)
|
||||||
|
return false;
|
||||||
|
} catch (DOMException e) {
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -71,8 +71,10 @@ import org.eclipse.cdt.core.index.IndexFilter;
|
||||||
import org.eclipse.cdt.core.model.ICElement;
|
import org.eclipse.cdt.core.model.ICElement;
|
||||||
import org.eclipse.cdt.core.model.ICProject;
|
import org.eclipse.cdt.core.model.ICProject;
|
||||||
import org.eclipse.cdt.core.model.ILanguage;
|
import org.eclipse.cdt.core.model.ILanguage;
|
||||||
|
import org.eclipse.cdt.core.model.IMethodDeclaration;
|
||||||
import org.eclipse.cdt.core.model.ISourceRange;
|
import org.eclipse.cdt.core.model.ISourceRange;
|
||||||
import org.eclipse.cdt.core.model.ISourceReference;
|
import org.eclipse.cdt.core.model.ISourceReference;
|
||||||
|
import org.eclipse.cdt.core.model.IStructureDeclaration;
|
||||||
import org.eclipse.cdt.core.model.ITranslationUnit;
|
import org.eclipse.cdt.core.model.ITranslationUnit;
|
||||||
import org.eclipse.cdt.core.parser.util.ArrayUtil;
|
import org.eclipse.cdt.core.parser.util.ArrayUtil;
|
||||||
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
|
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
|
||||||
|
@ -487,6 +489,16 @@ class OpenDeclarationsJob extends Job implements ASTRunnable {
|
||||||
if (uniqueElements.size() == 1) {
|
if (uniqueElements.size() == 1) {
|
||||||
target= (ISourceReference) uniqueElements.get(0);
|
target= (ISourceReference) uniqueElements.get(0);
|
||||||
} else {
|
} else {
|
||||||
|
if (uniqueElements.size() == 2) {
|
||||||
|
final ICElement e0 = uniqueElements.get(0);
|
||||||
|
final ICElement e1 = uniqueElements.get(1);
|
||||||
|
if (e0 instanceof IStructureDeclaration && e1 instanceof IMethodDeclaration) {
|
||||||
|
target= (ISourceReference) e1;
|
||||||
|
} else if (e1 instanceof IStructureDeclaration && e0 instanceof IMethodDeclaration) {
|
||||||
|
target= (ISourceReference) e0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (target == null) {
|
||||||
if (OpenDeclarationsAction.sIsJUnitTest) {
|
if (OpenDeclarationsAction.sIsJUnitTest) {
|
||||||
throw new RuntimeException("ambiguous input: " + uniqueElements.size()); //$NON-NLS-1$
|
throw new RuntimeException("ambiguous input: " + uniqueElements.size()); //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
|
@ -495,6 +507,7 @@ class OpenDeclarationsJob extends Job implements ASTRunnable {
|
||||||
CEditorMessages.OpenDeclarationsAction_dialog_title, CEditorMessages.OpenDeclarationsAction_selectMessage,
|
CEditorMessages.OpenDeclarationsAction_dialog_title, CEditorMessages.OpenDeclarationsAction_selectMessage,
|
||||||
CElementLabels.ALL_DEFAULT | CElementLabels.ALL_FULLY_QUALIFIED | CElementLabels.MF_POST_FILE_QUALIFIED, 0);
|
CElementLabels.ALL_DEFAULT | CElementLabels.ALL_FULLY_QUALIFIED | CElementLabels.MF_POST_FILE_QUALIFIED, 0);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (target != null) {
|
if (target != null) {
|
||||||
ITranslationUnit tu= target.getTranslationUnit();
|
ITranslationUnit tu= target.getTranslationUnit();
|
||||||
ISourceRange sourceRange;
|
ISourceRange sourceRange;
|
||||||
|
|
Loading…
Add table
Reference in a new issue