mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-23 22:52:11 +02:00
Detection of implicit constructor calls in declarators and initializers. Bug 248854.
This commit is contained in:
parent
28ffaab1ff
commit
d596dcb716
6 changed files with 226 additions and 26 deletions
|
@ -7,6 +7,7 @@
|
|||
*
|
||||
* Contributors:
|
||||
* Mike Kucera (IBM)
|
||||
* Sergey Prigogin (Google)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.core.parser.tests.ast2;
|
||||
|
||||
|
@ -16,8 +17,10 @@ import org.eclipse.cdt.core.dom.ast.IASTImplicitName;
|
|||
import org.eclipse.cdt.core.dom.ast.IASTImplicitNameOwner;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTNodeSelector;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
||||
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.ICPPMethod;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance;
|
||||
import org.eclipse.cdt.core.parser.ParserLanguage;
|
||||
|
||||
/**
|
||||
|
@ -277,7 +280,7 @@ public class AST2CPPImplicitNameTests extends AST2BaseTest {
|
|||
// bool b = true;
|
||||
// x(b); // 1
|
||||
// x(); // 2
|
||||
// x(1,2); // 3
|
||||
// x(1, 2); // 3
|
||||
// }
|
||||
public void testFunctionCallOperator() throws Exception {
|
||||
BindingAssertionHelper ba= new BindingAssertionHelper(getAboveComment(), true);
|
||||
|
@ -301,7 +304,7 @@ public class AST2CPPImplicitNameTests extends AST2BaseTest {
|
|||
assertTrue(n2.isAlternate());
|
||||
assertSame(col.getName(3).resolveBinding(), n1.resolveBinding());
|
||||
|
||||
n1 = ba.assertImplicitName("(1,2); // 3", 1, ICPPMethod.class);
|
||||
n1 = ba.assertImplicitName("(1, 2); // 3", 1, ICPPMethod.class);
|
||||
n2 = ba.assertImplicitName("); // 3", 1, ICPPMethod.class);
|
||||
assertSame(n1.resolveBinding(), n2.resolveBinding());
|
||||
assertFalse(n1.isAlternate());
|
||||
|
@ -416,18 +419,18 @@ public class AST2CPPImplicitNameTests extends AST2BaseTest {
|
|||
// int test() {
|
||||
// X* fp = new (nothrow) X;
|
||||
// int* p = new (nothrow) int[5];
|
||||
// int* p2 = new (5,6) int[5];
|
||||
// int* p2 = new (5, 6) int[5];
|
||||
// }
|
||||
public void testNew() throws Exception {
|
||||
BindingAssertionHelper ba= new BindingAssertionHelper(getAboveComment(), true);
|
||||
IASTImplicitName n1 = ba.assertImplicitName("new (nothrow) X", 3, ICPPFunction.class);
|
||||
IASTImplicitName n2 = ba.assertImplicitName("new (nothrow) int", 3, ICPPFunction.class);
|
||||
IASTImplicitName n3 = ba.assertImplicitName("new (5,6) int", 3, ICPPFunction.class);
|
||||
|
||||
IASTImplicitName n3 = ba.assertImplicitName("new (5, 6) int", 3, ICPPFunction.class);
|
||||
|
||||
IASTTranslationUnit tu = ba.getTranslationUnit();
|
||||
CPPNameCollector col = new CPPNameCollector();
|
||||
tu.accept(col);
|
||||
|
||||
|
||||
assertSame(col.getName(4).resolveBinding(), n1.resolveBinding());
|
||||
assertSame(col.getName(9).resolveBinding(), n2.resolveBinding());
|
||||
assertSame(col.getName(14).resolveBinding(), n3.resolveBinding());
|
||||
|
@ -440,4 +443,56 @@ public class AST2CPPImplicitNameTests extends AST2BaseTest {
|
|||
BindingAssertionHelper ba= new BindingAssertionHelper(getAboveComment(), true);
|
||||
ba.assertNoImplicitName("throw;", 5);
|
||||
}
|
||||
|
||||
// struct A {
|
||||
// A() {}
|
||||
// A(int) {}
|
||||
// template <typename T>
|
||||
// A(T, int) {}
|
||||
// };
|
||||
// typedef A B;
|
||||
//
|
||||
// void test() {
|
||||
// B a;
|
||||
// B b(1);
|
||||
// B c = 1;
|
||||
// B d("", 1);
|
||||
// extern B e;
|
||||
// }
|
||||
//
|
||||
// struct C {
|
||||
// static B s = 1;
|
||||
// static B t;
|
||||
// B u;
|
||||
// B v;
|
||||
// C(int p) : u(), v(p) {}
|
||||
// };
|
||||
// B C::t = 1;
|
||||
public void testConstructorCall() throws Exception {
|
||||
BindingAssertionHelper ba= new BindingAssertionHelper(getAboveComment(), true);
|
||||
IASTTranslationUnit tu = ba.getTranslationUnit();
|
||||
ICPPConstructor ctor0 = ba.assertNonProblem("A()", 1, ICPPConstructor.class);
|
||||
ICPPConstructor ctor1 = ba.assertNonProblem("A(int)", 1, ICPPConstructor.class);
|
||||
ICPPConstructor ctor2 = ba.assertNonProblem("A(T, int)", 1, ICPPConstructor.class);
|
||||
|
||||
IASTImplicitName a = ba.assertImplicitName("a;", 1, ICPPConstructor.class);
|
||||
assertSame(ctor0, a.resolveBinding());
|
||||
IASTImplicitName b = ba.assertImplicitName("b(", 1, ICPPConstructor.class);
|
||||
assertSame(ctor1, b.resolveBinding());
|
||||
IASTImplicitName c = ba.assertImplicitName("c =", 1, ICPPConstructor.class);
|
||||
assertSame(ctor1, c.resolveBinding());
|
||||
IASTImplicitName d = ba.assertImplicitName("d(", 1, ICPPConstructor.class);
|
||||
assertSame(ctor2, ((ICPPTemplateInstance) d.resolveBinding()).getTemplateDefinition());
|
||||
ba.assertNoImplicitName("e;", 1);
|
||||
IASTImplicitName s = ba.assertImplicitName("s =", 1, ICPPConstructor.class);
|
||||
assertSame(ctor1, s.resolveBinding());
|
||||
ba.assertNoImplicitName("t;", 1);
|
||||
IASTImplicitName t = ba.assertImplicitName("t =", 1, ICPPConstructor.class);
|
||||
assertSame(ctor1, t.resolveBinding());
|
||||
ba.assertNoImplicitName("u;", 1);
|
||||
IASTImplicitName u = ba.assertImplicitName("u()", 1, ICPPConstructor.class);
|
||||
assertSame(ctor0, u.resolveBinding());
|
||||
IASTImplicitName v = ba.assertImplicitName("v(p)", 1, ICPPConstructor.class);
|
||||
assertSame(ctor1, v.resolveBinding());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -174,10 +174,11 @@ public class IndexNamesTests extends BaseTestCase {
|
|||
|
||||
assertNull(main.getEnclosingDefinition());
|
||||
IIndexName[] enclosed= main.getEnclosedNames();
|
||||
assertLength(3, enclosed);
|
||||
assertName("C", enclosed[0]);
|
||||
assertName("func", enclosed[1]);
|
||||
assertName("var", enclosed[2]);
|
||||
assertLength(4, enclosed);
|
||||
assertName("C", enclosed[0]); // Class reference
|
||||
assertName("C", enclosed[1]); // Implicit ctor call
|
||||
assertName("func", enclosed[2]);
|
||||
assertName("var", enclosed[3]);
|
||||
|
||||
IIndexName enclosing= enclosed[0].getEnclosingDefinition();
|
||||
assertNotNull(enclosing);
|
||||
|
@ -189,9 +190,13 @@ public class IndexNamesTests extends BaseTestCase {
|
|||
|
||||
enclosing= enclosed[2].getEnclosingDefinition();
|
||||
assertNotNull(enclosing);
|
||||
assertName("main", enclosing);
|
||||
|
||||
enclosing= enclosed[3].getEnclosingDefinition();
|
||||
assertNotNull(enclosing);
|
||||
assertName("main", enclosing);
|
||||
|
||||
IIndexBinding funcB= fIndex.findBinding(enclosed[1]);
|
||||
IIndexBinding funcB= fIndex.findBinding(enclosed[2]);
|
||||
assertNotNull(funcB);
|
||||
names= fIndex.findDefinitions(funcB);
|
||||
assertLength(1, names);
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
* Contributors:
|
||||
* John Camelon (IBM) - Initial API and implementation
|
||||
* Markus Schorn (Wind River Systems)
|
||||
* Sergey Prigogin (Google)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
||||
|
||||
|
@ -16,6 +17,8 @@ import java.util.Arrays;
|
|||
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTCompletionContext;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTImplicitName;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTImplicitNameOwner;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTInitializer;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||
|
@ -23,6 +26,7 @@ import org.eclipse.cdt.core.dom.ast.IBinding;
|
|||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorChainInitializer;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorInitializer;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPField;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace;
|
||||
|
@ -40,8 +44,9 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
|
|||
* {@code Base()} and {@code field()} are the constructor chain initializers.<br>
|
||||
*/
|
||||
public class CPPASTConstructorChainInitializer extends ASTNode implements
|
||||
ICPPASTConstructorChainInitializer, IASTCompletionContext {
|
||||
ICPPASTConstructorChainInitializer, IASTImplicitNameOwner, IASTCompletionContext {
|
||||
private IASTName name;
|
||||
private IASTImplicitName[] implicitNames;
|
||||
private IASTInitializer initializer;
|
||||
private boolean fIsPackExpansion;
|
||||
|
||||
|
@ -101,6 +106,13 @@ public class CPPASTConstructorChainInitializer extends ASTNode implements
|
|||
if (name != null && !name.accept(action))
|
||||
return false;
|
||||
|
||||
if (action.shouldVisitImplicitNames) {
|
||||
for (IASTImplicitName implicitName : getImplicitNames()) {
|
||||
if (!implicitName.accept(action))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (initializer != null && !initializer.accept(action))
|
||||
return false;
|
||||
|
||||
|
@ -154,7 +166,6 @@ public class CPPASTConstructorChainInitializer extends ASTNode implements
|
|||
for (IASTNode parent = name.getParent(); parent != null; parent = parent.getParent()) {
|
||||
if (parent instanceof ICPPASTCompositeTypeSpecifier) {
|
||||
ICPPASTCompositeTypeSpecifier specifier = (ICPPASTCompositeTypeSpecifier) parent;
|
||||
|
||||
return specifier.getBaseSpecifiers();
|
||||
}
|
||||
}
|
||||
|
@ -201,4 +212,27 @@ public class CPPASTConstructorChainInitializer extends ASTNode implements
|
|||
setInitializer(ctorInit);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see IASTImplicitNameOwner#getImplicitNames()
|
||||
*/
|
||||
public IASTImplicitName[] getImplicitNames() {
|
||||
if (implicitNames == null) {
|
||||
ICPPConstructor ctor = CPPSemantics.findImplicitlyCalledConstructor(this);
|
||||
if (ctor == null) {
|
||||
implicitNames = IASTImplicitName.EMPTY_NAME_ARRAY;
|
||||
} else {
|
||||
CPPASTImplicitName ctorName = new CPPASTImplicitName(ctor.getNameCharArray(), this);
|
||||
ctorName.setBinding(ctor);
|
||||
IASTName id = name;
|
||||
if (id instanceof ICPPASTQualifiedName) {
|
||||
id = ((ICPPASTQualifiedName) id).getLastName();
|
||||
}
|
||||
ctorName.setOffsetAndLength((ASTNode) id);
|
||||
implicitNames = new IASTImplicitName[] { ctorName };
|
||||
}
|
||||
}
|
||||
|
||||
return implicitNames;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2004, 2009 IBM Corporation and others.
|
||||
* Copyright (c) 2004, 2010 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
|
||||
|
@ -8,6 +8,7 @@
|
|||
* Contributors:
|
||||
* John Camelon (IBM) - Initial API and implementation
|
||||
* Markus Schorn (Wind River Systems)
|
||||
* Sergey Prigogin (Google)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
||||
|
||||
|
@ -17,6 +18,8 @@ import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
|
|||
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTImplicitName;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTImplicitNameOwner;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTInitializer;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||
|
@ -26,22 +29,26 @@ import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
|
|||
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclarator;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLinkageSpecification;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope;
|
||||
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.ASTNode;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.ASTQueries;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
|
||||
|
||||
/**
|
||||
* C++ specific declarator.
|
||||
*/
|
||||
public class CPPASTDeclarator extends ASTNode implements ICPPASTDeclarator {
|
||||
public class CPPASTDeclarator extends ASTNode implements ICPPASTDeclarator, IASTImplicitNameOwner {
|
||||
private IASTInitializer initializer;
|
||||
private IASTName name;
|
||||
private IASTImplicitName[] implicitNames;
|
||||
private IASTDeclarator nested;
|
||||
private IASTPointerOperator[] pointerOps = null;
|
||||
private IASTPointerOperator[] pointerOps;
|
||||
private boolean isPackExpansion;
|
||||
|
||||
|
||||
public CPPASTDeclarator() {
|
||||
}
|
||||
|
||||
|
@ -139,7 +146,7 @@ public class CPPASTDeclarator extends ASTNode implements ICPPASTDeclarator {
|
|||
switch (action.visit(this)) {
|
||||
case ASTVisitor.PROCESS_ABORT: return false;
|
||||
case ASTVisitor.PROCESS_SKIP: return true;
|
||||
default : break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -155,13 +162,19 @@ public class CPPASTDeclarator extends ASTNode implements ICPPASTDeclarator {
|
|||
if (nested == null && name != null) {
|
||||
IASTDeclarator outermost= ASTQueries.findOutermostDeclarator(this);
|
||||
if (outermost.getPropertyInParent() != IASTTypeId.ABSTRACT_DECLARATOR) {
|
||||
if (!name.accept(action)) return false;
|
||||
if (!name.accept(action))
|
||||
return false;
|
||||
if (action.shouldVisitImplicitNames) {
|
||||
for (IASTImplicitName implicitName : getImplicitNames()) {
|
||||
if (!implicitName.accept(action))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (nested != null) {
|
||||
if (!nested.accept(action)) return false;
|
||||
}
|
||||
if (nested != null && !nested.accept(action))
|
||||
return false;
|
||||
|
||||
if (!postAccept(action))
|
||||
return false;
|
||||
|
@ -233,4 +246,27 @@ public class CPPASTDeclarator extends ASTNode implements ICPPASTDeclarator {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see IASTImplicitNameOwner#getImplicitNames()
|
||||
*/
|
||||
public IASTImplicitName[] getImplicitNames() {
|
||||
if (implicitNames == null) {
|
||||
ICPPConstructor ctor = CPPSemantics.findImplicitlyCalledConstructor(this);
|
||||
if (ctor == null) {
|
||||
implicitNames = IASTImplicitName.EMPTY_NAME_ARRAY;
|
||||
} else {
|
||||
CPPASTImplicitName ctorName = new CPPASTImplicitName(ctor.getNameCharArray(), this);
|
||||
ctorName.setBinding(ctor);
|
||||
IASTName id = name;
|
||||
if (id instanceof ICPPASTQualifiedName) {
|
||||
id = ((ICPPASTQualifiedName) id).getLastName();
|
||||
}
|
||||
ctorName.setOffsetAndLength((ASTNode) id);
|
||||
implicitNames = new IASTImplicitName[] { ctorName };
|
||||
}
|
||||
}
|
||||
|
||||
return implicitNames;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -89,7 +89,7 @@ public class CPPASTDeleteExpression extends ASTNode implements ICPPASTDeleteExpr
|
|||
List<IASTImplicitName> names = new ArrayList<IASTImplicitName>();
|
||||
|
||||
if (!isVectored) {
|
||||
ICPPFunction destructor = CPPSemantics.findDestructor(this);
|
||||
ICPPFunction destructor = CPPSemantics.findImplicitlyCalledDestructor(this);
|
||||
if (destructor != null) {
|
||||
CPPASTImplicitName destructorName = new CPPASTImplicitName(destructor.getNameCharArray(), this);
|
||||
destructorName.setBinding(destructor);
|
||||
|
@ -121,7 +121,7 @@ public class CPPASTDeleteExpression extends ASTNode implements ICPPASTDeleteExpr
|
|||
@Override
|
||||
public boolean accept(ASTVisitor action) {
|
||||
if (action.shouldVisitExpressions) {
|
||||
switch(action.visit(this)) {
|
||||
switch (action.visit(this)) {
|
||||
case ASTVisitor.PROCESS_ABORT: return false;
|
||||
case ASTVisitor.PROCESS_SKIP: return true;
|
||||
default: break;
|
||||
|
@ -129,7 +129,7 @@ public class CPPASTDeleteExpression extends ASTNode implements ICPPASTDeleteExpr
|
|||
}
|
||||
|
||||
if (action.shouldVisitImplicitNames) {
|
||||
for(IASTImplicitName name : getImplicitNames()) {
|
||||
for (IASTImplicitName name : getImplicitNames()) {
|
||||
if (!name.accept(action))
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -158,6 +158,7 @@ import org.eclipse.cdt.internal.core.dom.parser.ASTQueries;
|
|||
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguousDeclarator;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.IASTInternalScope;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTDeclarator;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTFieldReference;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTIdExpression;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTLiteralExpression;
|
||||
|
@ -2762,7 +2763,76 @@ public class CPPSemantics {
|
|||
return null;
|
||||
}
|
||||
|
||||
public static ICPPFunction findDestructor(ICPPASTDeleteExpression expr) {
|
||||
/**
|
||||
* Returns constructor called by a declarator, or <code>null</code> if no constructor is called.
|
||||
*/
|
||||
public static ICPPConstructor findImplicitlyCalledConstructor(CPPASTDeclarator declarator) {
|
||||
if (declarator.getInitializer() == null) {
|
||||
IASTNode parent = declarator.getParent();
|
||||
if (parent instanceof IASTSimpleDeclaration) {
|
||||
IASTDeclSpecifier declSpec = ((IASTSimpleDeclaration) parent).getDeclSpecifier();
|
||||
parent = parent.getParent();
|
||||
if (parent instanceof IASTCompositeTypeSpecifier ||
|
||||
declSpec.getStorageClass() == IASTDeclSpecifier.sc_extern) {
|
||||
// No initialization is performed for class members and extern declarations
|
||||
// without an initializer.
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
return findImplicitlyCalledConstructor(declarator.getName(), declarator.getInitializer());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns constructor called by a class member initializer in a constructor initializer chain.
|
||||
* Returns <code>null</code> if no constructor is called.
|
||||
*/
|
||||
public static ICPPConstructor findImplicitlyCalledConstructor(ICPPASTConstructorChainInitializer initializer) {
|
||||
return findImplicitlyCalledConstructor(initializer.getMemberInitializerId(), initializer.getInitializer());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns constructor called by a variable declarator or an initializer in a constructor initializer
|
||||
* chain. Returns <code>null</code> if no constructor is called.
|
||||
*/
|
||||
private static ICPPConstructor findImplicitlyCalledConstructor(IASTName name, IASTInitializer initializer) {
|
||||
IBinding binding = name.resolveBinding();
|
||||
if (!(binding instanceof ICPPVariable))
|
||||
return null;
|
||||
IType type;
|
||||
try {
|
||||
type = SemanticUtil.getSimplifiedType(((ICPPVariable) binding).getType());
|
||||
if (!(type instanceof ICPPClassType))
|
||||
return null;
|
||||
ICPPClassType classType = (ICPPClassType) type;
|
||||
CPPASTName astName = new CPPASTName();
|
||||
astName.setName(classType.getNameCharArray());
|
||||
astName.setOffsetAndLength((ASTNode) name);
|
||||
CPPASTIdExpression idExp = new CPPASTIdExpression(astName);
|
||||
idExp.setParent(name.getParent());
|
||||
idExp.setPropertyInParent(IASTFunctionCallExpression.FUNCTION_NAME);
|
||||
|
||||
LookupData data = new LookupData(astName);
|
||||
if (initializer == null) {
|
||||
data.setFunctionArguments(IASTExpression.EMPTY_EXPRESSION_ARRAY);
|
||||
} else if (initializer instanceof IASTEqualsInitializer) {
|
||||
data.setFunctionArguments(((IASTEqualsInitializer) initializer).getInitializerClause());
|
||||
} else if (initializer instanceof ICPPASTConstructorInitializer) {
|
||||
data.setFunctionArguments(((ICPPASTConstructorInitializer) initializer).getArguments());
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
data.forceQualified = true;
|
||||
data.foundItems = classType.getConstructors();
|
||||
binding = resolveAmbiguities(data, astName);
|
||||
if (binding instanceof ICPPConstructor)
|
||||
return (ICPPConstructor) binding;
|
||||
} catch (DOMException e) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static ICPPFunction findImplicitlyCalledDestructor(ICPPASTDeleteExpression expr) {
|
||||
ICPPClassType cls = getNestedClassType(expr);
|
||||
if (cls == null)
|
||||
return null;
|
||||
|
|
Loading…
Add table
Reference in a new issue