1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-16 20:55:44 +02:00

Bug 461538 - "noreturn" attribute in destructor is not accounted for

Change-Id: Ia3c3bdfdb26ff18092fd20be02f178ebb71848bb
Signed-off-by: Sergey Prigogin <eclipse.sprigogin@gmail.com>
This commit is contained in:
Sergey Prigogin 2015-04-03 14:12:28 -07:00
parent d702a8f947
commit 711ec8df95
43 changed files with 980 additions and 128 deletions

View file

@ -1,14 +1,15 @@
/*******************************************************************************
* Copyright (c) 2009, 2012 Alena Laskavaia, Tomasz Wesolowski
* Copyright (c) 2009, 2015 Alena Laskavaia, Tomasz Wesolowski
* 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Alena Laskavaia - initial API and implementation
* Tomasz Wesolowski - extension
* Marc-Andre Laperle
* Alena Laskavaia - initial API and implementation
* Tomasz Wesolowski - extension
* Marc-Andre Laperle
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.codan.core.cxx;
@ -31,6 +32,7 @@ import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
import org.eclipse.cdt.core.dom.ast.IASTImplicitName;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTNode.CopyStyle;
@ -90,6 +92,27 @@ public final class CxxAstUtils {
}
}
private static class NoReturnImplicitCallFinder extends ASTVisitor {
boolean noReturn;
NoReturnImplicitCallFinder() {
shouldVisitImplicitNames = true;
shouldVisitImplicitDestructorNames = true;
}
@Override
public int visit(IASTName name) {
if (name instanceof IASTImplicitName) {
IBinding binding = name.resolveBinding();
if (binding instanceof IFunction && ((IFunction) binding).isNoReturn()) {
noReturn = true;
return PROCESS_ABORT;
}
}
return PROCESS_CONTINUE;
}
}
// Not instantiatable. All methods are static.
private CxxAstUtils() {
}
@ -378,6 +401,11 @@ public final class CxxAstUtils {
}
public static boolean isExitStatement(IASTNode statement) {
NoReturnImplicitCallFinder noReturnFinder = new NoReturnImplicitCallFinder();
statement.accept(noReturnFinder);
if (noReturnFinder.noReturn)
return true;
if (!(statement instanceof IASTExpressionStatement))
return false;
IASTExpression expression = ((IASTExpressionStatement) statement).getExpression();
@ -388,7 +416,7 @@ public final class CxxAstUtils {
IASTName name = ((IASTIdExpression) functionNameExpression).getName();
IBinding binding = name.resolveBinding();
if (binding != null && binding instanceof IFunction && ((IFunction) binding).isNoReturn()) {
if (binding instanceof IFunction && ((IFunction) binding).isNoReturn()) {
return true;
}
}

View file

@ -303,17 +303,27 @@ public class ReturnCheckerTest extends CheckerTestCase {
checkSampleAbove();
}
//void f() __attribute__((noreturn));
//
//int test() {
// f();
//}
// void f() __attribute__((noreturn));
//
// int test() {
// f();
// }
public void testNoReturn() {
checkSampleAbove();
}
// struct A {
// A();
// ~A() __attribute__((noreturn));
// };
//
// int test() {
// A();
// }
public void testNoReturnInDestructor_461538() throws Exception {
checkSampleAboveCpp();
}
// int try1() {
// try {
// return 5;

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2009, 2010 IBM Corporation and others.
* Copyright (c) 2009, 2015 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
@ -7,6 +7,7 @@
*
* Contributors:
* Mike Kucera (IBM) - Initial API and implementation
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.core.parser.tests;
@ -26,7 +27,7 @@ import org.junit.Assert;
public class ASTComparer extends Assert {
private static Set<String> methodsToIgnore = new HashSet<String>(Arrays.asList(
private static Set<String> methodsToIgnore = new HashSet<>(Arrays.asList(
// Prevent infinite recursion
"getParent",
"getTranslationUnit",
@ -61,6 +62,7 @@ public class ASTComparer extends Assert {
"isAssociatedWithLastName",
"getNestingLevel",
"getImplicitNames",
"getImplicitDestructorNames",
"isLValue",
// These methods can return a special constant value, such as

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2009, 2013 IBM Corporation and others.
* Copyright (c) 2009, 2015 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
@ -15,6 +15,8 @@ package org.eclipse.cdt.core.parser.tests.ast2;
import java.io.IOException;
import org.eclipse.cdt.core.dom.ast.IASTImplicitDestructorName;
import org.eclipse.cdt.core.dom.ast.IASTImplicitDestructorNameOwner;
import org.eclipse.cdt.core.dom.ast.IASTImplicitName;
import org.eclipse.cdt.core.dom.ast.IASTImplicitNameOwner;
import org.eclipse.cdt.core.dom.ast.IASTNodeSelector;
@ -61,6 +63,25 @@ public class AST2CPPImplicitNameTests extends AST2TestBase {
return implicits;
}
protected IASTImplicitDestructorName[] getImplicitDestructorNames(IASTTranslationUnit tu, String contents,
String section) {
return getImplicitDestructorNames(tu, contents, section, section.length());
}
protected IASTImplicitDestructorName[] getImplicitDestructorNames(IASTTranslationUnit tu, String contents,
String section, int len) {
final int offset = contents.indexOf(section);
assertTrue(offset >= 0);
IASTNodeSelector selector = tu.getNodeSelector(null);
IASTImplicitName firstImplicit = selector.findImplicitName(offset, len);
if (firstImplicit instanceof IASTImplicitDestructorName) {
IASTImplicitDestructorNameOwner owner = (IASTImplicitDestructorNameOwner) firstImplicit.getParent();
IASTImplicitDestructorName[] implicits = owner.getImplicitDestructorNames();
return implicits;
}
return IASTImplicitDestructorName.EMPTY_NAME_ARRAY;
}
// class point {
// int x, y;
// public:
@ -578,4 +599,82 @@ public class AST2CPPImplicitNameTests extends AST2TestBase {
IASTImplicitName a = ba.assertImplicitName("==b", 2, ICPPFunction.class);
assertSame(op, a.resolveBinding());
}
// struct A {
// ~A();
// int a;
// };
// void test() {
// int x;
// x = A().a;
// }
public void testTemporaryDestruction() throws Exception {
BindingAssertionHelper ba= getAssertionHelper();
IASTImplicitDestructorName[] names = ba.getImplicitDestructorNames("x = A().a");
assertEquals(1, names.length);
assertEquals("~A", names[0].resolveBinding().getName());
}
// struct A {
// ~A();
// int a;
// };
// void test() {
// A x;
// x = A();
// }
public void testTemporaryNotCreatedWhenBoundToVariable() throws Exception {
BindingAssertionHelper ba= getAssertionHelper();
IASTImplicitDestructorName[] names = ba.getImplicitDestructorNames("x = A()");
assertEquals(0, names.length);
}
// struct A {
// ~A();
// int a;
// };
// int test() {
// return (new A())->a;
// }
public void testTemporaryNotCreatesInNewExpression() throws Exception {
BindingAssertionHelper ba= getAssertionHelper();
IASTImplicitDestructorName[] names = ba.getImplicitDestructorNames("(new A())->a");
assertEquals(0, names.length);
}
// struct A {
// ~A();
// int a;
// };
// void test() {
// A& x = A();
// }
public void testTemporaryBoundToReference() throws Exception {
BindingAssertionHelper ba= getAssertionHelper();
IASTImplicitDestructorName[] names = ba.getImplicitDestructorNames("A()");
assertEquals(0, names.length);
}
// struct S {
// S();
// S(int);
// ~S();
// };
//
// void test() {
// S s1;
// const S& s2 = S(1);
// S s3;
// }//1
public void testOrderOfDestruction() throws Exception {
BindingAssertionHelper ba= getAssertionHelper();
IASTImplicitDestructorName[] names = ba.getImplicitDestructorNames("}//1", 1);
assertEquals(3, names.length);
assertEquals("~S", names[0].resolveBinding().getName());
assertEquals("s3", names[0].getConstructionPoint().getParent().getRawSignature());
assertEquals("~S", names[1].resolveBinding().getName());
assertEquals("S(1)", names[1].getConstructionPoint().getParent().getRawSignature());
assertEquals("~S", names[2].resolveBinding().getName());
assertEquals("s1", names[2].getConstructionPoint().getParent().getRawSignature());
}
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2004, 2013 IBM Corporation and others.
* Copyright (c) 2004, 2015 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
@ -39,6 +39,8 @@ import org.eclipse.cdt.core.dom.ast.IASTExpressionStatement;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
import org.eclipse.cdt.core.dom.ast.IASTImplicitDestructorName;
import org.eclipse.cdt.core.dom.ast.IASTImplicitDestructorNameOwner;
import org.eclipse.cdt.core.dom.ast.IASTImplicitName;
import org.eclipse.cdt.core.dom.ast.IASTImplicitNameOwner;
import org.eclipse.cdt.core.dom.ast.IASTInitializerClause;
@ -666,6 +668,10 @@ public class AST2TestBase extends BaseTestCase {
assertNull("found name \"" + selection + "\"", name);
}
public IASTImplicitName[] getImplicitNames(String section) {
return getImplicitNames(section, section.length());
}
public IASTImplicitName[] getImplicitNames(String section, int len) {
IASTName name = findImplicitName(section, len);
IASTImplicitNameOwner owner = (IASTImplicitNameOwner) name.getParent();
@ -673,6 +679,20 @@ public class AST2TestBase extends BaseTestCase {
return implicits;
}
public IASTImplicitDestructorName[] getImplicitDestructorNames(String section) {
return getImplicitDestructorNames(section, section.length());
}
public IASTImplicitDestructorName[] getImplicitDestructorNames(String section, int len) {
final int offset = contents.indexOf(section);
assertTrue(offset >= 0);
IASTNodeSelector selector = tu.getNodeSelector(null);
IASTNode enclosingNode = selector.findEnclosingNode(offset, len);
if (!(enclosingNode instanceof IASTImplicitDestructorNameOwner))
return IASTImplicitDestructorName.EMPTY_NAME_ARRAY;
return ((IASTImplicitDestructorNameOwner) enclosingNode).getImplicitDestructorNames();
}
public IASTName findName(String section, int len) {
final int offset = contents.indexOf(section);
assertTrue("Section \"" + section + "\" not found", offset >= 0);

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2004, 2012 IBM Corporation and others.
* Copyright (c) 2004, 2015 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
@ -186,6 +186,16 @@ public abstract class ASTVisitor {
*/
public boolean shouldVisitImplicitNameAlternates = false;
/**
* Implicit destructor names are created to mark code locations where destructors of temporaries and
* variables going out of scope are called, normally they are not visited, set this flag to true to visit
* them.
* @since 5.10
* @see #visit(IASTName)
* @see IASTImplicitDestructorName
*/
public boolean shouldVisitImplicitDestructorNames = false;
/**
* Creates a visitor that does not visit any kind of node per default.
*/

View file

@ -0,0 +1,27 @@
/*******************************************************************************
* Copyright (c) 2015 Google, Inc 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Sergey Prigogin (Google) - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.core.dom.ast;
/**
* An implicit name corresponding to a destructor call for a temporary or a variable going out of scope.
*
* @since 5.10
* @noextend This interface is not intended to be extended by clients.
* @noimplement This interface is not intended to be implemented by clients.
*/
public interface IASTImplicitDestructorName extends IASTImplicitName {
public static final IASTImplicitDestructorName[] EMPTY_NAME_ARRAY = {};
/**
* Returns the name corresponding to the constructor call.
*/
IASTName getConstructionPoint();
}

View file

@ -0,0 +1,26 @@
/*******************************************************************************
* Copyright (c) 2015 Google, Inc 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Sergey Prigogin (Google) - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.core.dom.ast;
/**
* An AST node that may have implicit destructor names.
* @see IASTImplicitDestructorName
*
* @since 5.10
* @noextend This interface is not intended to be extended by clients.
* @noimplement This interface is not intended to be implemented by clients.
*/
public interface IASTImplicitDestructorNameOwner extends IASTNode {
public static final ASTNodeProperty IMPLICIT_DESTRUCTOR_NAME =
new ASTNodeProperty("IASTImplicitDestructorNameOwner.IMPLICIT_DESTRUCTOR_NAME"); //$NON-NLS-1$
public IASTImplicitDestructorName[] getImplicitDestructorNames();
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2004, 2011 IBM Corporation and others.
* Copyright (c) 2004, 2015 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,6 +12,7 @@ package org.eclipse.cdt.core.dom.ast.cpp;
import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTImplicitDestructorNameOwner;
import org.eclipse.cdt.core.dom.ast.IASTStatement;
import org.eclipse.cdt.core.dom.ast.IScope;
@ -23,7 +24,7 @@ import org.eclipse.cdt.core.dom.ast.IScope;
* @noextend This interface is not intended to be extended by clients.
* @noimplement This interface is not intended to be implemented by clients.
*/
public interface ICPPASTCatchHandler extends IASTStatement {
public interface ICPPASTCatchHandler extends IASTStatement, IASTImplicitDestructorNameOwner {
public static final ICPPASTCatchHandler[] EMPTY_CATCHHANDLER_ARRAY = {};
/**

View file

@ -0,0 +1,24 @@
/*******************************************************************************
* Copyright (c) 2015 Google, Inc 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Sergey Prigogin (Google) - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.core.dom.ast.cpp;
import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement;
import org.eclipse.cdt.core.dom.ast.IASTImplicitDestructorNameOwner;
/**
* Represents a block of statements in C++.
*
* @noextend This interface is not intended to be extended by clients.
* @noimplement This interface is not intended to be implemented by clients.
* @since 5.10
*/
public interface ICPPASTCompoundStatement extends IASTCompoundStatement, IASTImplicitDestructorNameOwner {
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2012 Wind River Systems, Inc. and others.
* Copyright (c) 2012, 2015 Wind River Systems, Inc. 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
@ -7,17 +7,23 @@
*
* Contributors:
* Markus Schorn - initial API and implementation
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.core.dom.ast.cpp;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTImplicitDestructorName;
import org.eclipse.cdt.core.dom.ast.IASTImplicitDestructorNameOwner;
/**
* Interface for C++ expressions.
* Interface for C++ expressions. Any full-expressions may contain {@link IASTImplicitDestructorName}s of
* destructors called at the end of the expression to destroy temporaries created by the expression.
* A full-expression is an expression that is not a subexpression of another expression.
*
* @since 5.10
* @noextend This interface is not intended to be extended by clients.
* @noimplement This interface is not intended to be implemented by clients.
*/
public interface ICPPASTExpression extends IASTExpression, ICPPASTInitializerClause {
public interface ICPPASTExpression
extends IASTExpression, ICPPASTInitializerClause, IASTImplicitDestructorNameOwner {
}

View file

@ -1,5 +1,5 @@
/**********************************************************************
* Copyright (c) 2004, 2011 IBM Corporation and others.
* Copyright (c) 2004, 2015 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
@ -13,6 +13,7 @@ package org.eclipse.cdt.core.dom.ast.cpp;
import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTForStatement;
import org.eclipse.cdt.core.dom.ast.IASTImplicitDestructorNameOwner;
/**
* The C++ 'for' statement.
@ -20,7 +21,7 @@ import org.eclipse.cdt.core.dom.ast.IASTForStatement;
* @noextend This interface is not intended to be extended by clients.
* @noimplement This interface is not intended to be implemented by clients.
*/
public interface ICPPASTForStatement extends IASTForStatement {
public interface ICPPASTForStatement extends IASTForStatement, IASTImplicitDestructorNameOwner {
public static final ASTNodeProperty CONDITION_DECLARATION =
new ASTNodeProperty("org.eclipse.cdt.core.dom.ast.cpp.ICPPASTForStatement"); //$NON-NLS-1$

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2010, 2011 Wind River Systems, Inc. and others.
* Copyright (c) 2010, 2015 Wind River Systems, Inc. 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,19 +12,21 @@ package org.eclipse.cdt.core.dom.ast.cpp;
import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTImplicitDestructorNameOwner;
import org.eclipse.cdt.core.dom.ast.IASTImplicitNameOwner;
import org.eclipse.cdt.core.dom.ast.IASTInitializerClause;
import org.eclipse.cdt.core.dom.ast.IASTStatement;
import org.eclipse.cdt.core.dom.ast.IScope;
/**
* Represents a range-based for loop.
* Represents a range-based 'for' loop.
*
* @noextend This interface is not intended to be extended by clients.
* @noimplement This interface is not intended to be implemented by clients.
* @since 5.3
*/
public interface ICPPASTRangeBasedForStatement extends IASTStatement, IASTImplicitNameOwner {
public interface ICPPASTRangeBasedForStatement
extends IASTStatement, IASTImplicitNameOwner, IASTImplicitDestructorNameOwner {
public static final ASTNodeProperty DECLARATION = new ASTNodeProperty(
"ICPPASTRangeBasedForStatement.DECLARATION [IASTDeclaration]"); //$NON-NLS-1$
public static final ASTNodeProperty INITIALIZER = new ASTNodeProperty(

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2008, 2009 Wind River Systems, Inc. and others.
* Copyright (c) 2008, 2015 Wind River Systems, Inc. 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
@ -7,11 +7,13 @@
*
* Contributors:
* Markus Schorn - Initial API and implementation
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression;
import org.eclipse.cdt.core.dom.ast.IASTCastExpression;
import org.eclipse.cdt.core.dom.ast.IASTImplicitDestructorName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression;
import org.eclipse.cdt.internal.core.dom.parser.ASTAmbiguousBinaryVsCastExpression;
@ -20,4 +22,9 @@ public class CPPASTAmbiguousBinaryVsCastExpression extends ASTAmbiguousBinaryVsC
public CPPASTAmbiguousBinaryVsCastExpression(IASTBinaryExpression bexp, IASTCastExpression castExpr) {
super(bexp, castExpr);
}
@Override
public IASTImplicitDestructorName[] getImplicitDestructorNames() {
throw new UnsupportedOperationException();
}
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2008 Wind River Systems, Inc. and others.
* Copyright (c) 2008, 2015 Wind River Systems, Inc. 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
@ -7,11 +7,13 @@
*
* Contributors:
* Markus Schorn - Initial API and implementation
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.IASTCastExpression;
import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression;
import org.eclipse.cdt.core.dom.ast.IASTImplicitDestructorName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression;
import org.eclipse.cdt.internal.core.dom.parser.ASTAmbiguousCastVsFunctionCallExpression;
@ -21,4 +23,9 @@ public class CPPASTAmbiguousCastVsFunctionCallExpression
public CPPASTAmbiguousCastVsFunctionCallExpression(IASTCastExpression castExpr, IASTFunctionCallExpression funcCall) {
super(castExpr, funcCall);
}
@Override
public IASTImplicitDestructorName[] getImplicitDestructorNames() {
throw new UnsupportedOperationException();
}
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2004, 2011 IBM Corporation and others.
* Copyright (c) 2004, 2015 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,10 +8,12 @@
* Contributors:
* IBM - Initial API and implementation
* Markus Schorn (Wind River Systems)
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTImplicitDestructorName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
@ -59,4 +61,9 @@ public class CPPASTAmbiguousExpression extends ASTAmbiguousNode
public IASTNode[] getNodes() {
return getExpressions();
}
@Override
public IASTImplicitDestructorName[] getImplicitDestructorNames() {
throw new UnsupportedOperationException();
}
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2004, 2012 IBM Corporation and others.
* Copyright (c) 2004, 2015 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
@ -9,6 +9,7 @@
* John Camelon (IBM) - Initial API and implementation
* Mike Kucera (IBM)
* Markus Schorn (Wind River Systems)
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
@ -16,6 +17,7 @@ import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTImplicitDestructorName;
import org.eclipse.cdt.core.dom.ast.IASTImplicitName;
import org.eclipse.cdt.core.dom.ast.IASTInitializerClause;
import org.eclipse.cdt.core.dom.ast.IASTNode;
@ -210,4 +212,9 @@ public class CPPASTArraySubscriptExpression extends ASTNode
public boolean isLValue() {
return getValueCategory() == LVALUE;
}
@Override
public IASTImplicitDestructorName[] getImplicitDestructorNames() {
return IASTImplicitDestructorName.EMPTY_NAME_ARRAY;
}
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2004, 2011 IBM Corporation and others.
* Copyright (c) 2004, 2015 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
@ -18,6 +18,7 @@ import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTImplicitDestructorName;
import org.eclipse.cdt.core.dom.ast.IASTImplicitName;
import org.eclipse.cdt.core.dom.ast.IASTImplicitNameOwner;
import org.eclipse.cdt.core.dom.ast.IASTInitializerClause;
@ -30,6 +31,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.DestructorCallCollector;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalBinary;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed;
@ -41,6 +43,7 @@ public class CPPASTBinaryExpression extends ASTNode implements ICPPASTBinaryExpr
private ICPPEvaluation fEvaluation;
private IASTImplicitName[] fImplicitNames;
private IASTImplicitDestructorName[] fImplicitDestructorNames;
public CPPASTBinaryExpression() {
}
@ -139,6 +142,15 @@ public class CPPASTBinaryExpression extends ASTNode implements ICPPASTBinaryExpr
return fImplicitNames;
}
@Override
public IASTImplicitDestructorName[] getImplicitDestructorNames() {
if (fImplicitDestructorNames == null) {
fImplicitDestructorNames = DestructorCallCollector.getTemporariesDestructorCalls(this);
}
return fImplicitDestructorNames;
}
@Override
public boolean accept(ASTVisitor action) {
if (fOperand1 instanceof IASTBinaryExpression || fOperand2 instanceof IASTBinaryExpression) {
@ -162,6 +174,9 @@ public class CPPASTBinaryExpression extends ASTNode implements ICPPASTBinaryExpr
if (fOperand2 != null && !fOperand2.accept(action))
return false;
if (action.shouldVisitImplicitDestructorNames && !acceptByNodes(getImplicitDestructorNames(), action))
return false;
if (action.shouldVisitExpressions && action.leave(this) == ASTVisitor.PROCESS_ABORT)
return false;

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2004, 2013 IBM Corporation and others.
* Copyright (c) 2004, 2015 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;
@ -15,6 +16,7 @@ import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTBinaryTypeIdExpression;
import org.eclipse.cdt.core.dom.ast.IASTImplicitDestructorName;
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression;
@ -145,4 +147,9 @@ public class CPPASTBinaryTypeIdExpression extends ASTNode implements ICPPASTExpr
public ValueCategory getValueCategory() {
return PRVALUE;
}
@Override
public IASTImplicitDestructorName[] getImplicitDestructorNames() {
return IASTImplicitDestructorName.EMPTY_NAME_ARRAY; // Binary type-id expressions don't call destructors.
}
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2004, 2011 IBM Corporation and others.
* Copyright (c) 2004, 2015 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;
@ -15,6 +16,7 @@ import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTImplicitDestructorName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
import org.eclipse.cdt.core.dom.ast.IProblemType;
@ -24,6 +26,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.DestructorCallCollector;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalTypeId;
@ -35,6 +38,7 @@ public class CPPASTCastExpression extends ASTNode implements ICPPASTCastExpressi
private ICPPASTExpression fOperand;
private IASTTypeId fTypeId;
private ICPPEvaluation fEvaluation;
private IASTImplicitDestructorName[] fImplicitDestructorNames;
public CPPASTCastExpression() {
}
@ -101,6 +105,15 @@ public class CPPASTCastExpression extends ASTNode implements ICPPASTCastExpressi
}
}
@Override
public IASTImplicitDestructorName[] getImplicitDestructorNames() {
if (fImplicitDestructorNames == null) {
fImplicitDestructorNames = DestructorCallCollector.getTemporariesDestructorCalls(this);
}
return fImplicitDestructorNames;
}
@Override
public boolean accept(ASTVisitor action) {
if (action.shouldVisitExpressions) {
@ -115,6 +128,9 @@ public class CPPASTCastExpression extends ASTNode implements ICPPASTCastExpressi
IASTExpression op = getOperand();
if (op != null && !op.accept(action)) return false;
if (action.shouldVisitImplicitDestructorNames && !acceptByNodes(getImplicitDestructorNames(), action))
return false;
if (action.shouldVisitExpressions) {
switch (action.leave(this)) {
case ASTVisitor.PROCESS_ABORT: return false;

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2004, 2014 IBM Corporation and others.
* Copyright (c) 2004, 2015 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
@ -14,22 +14,25 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTImplicitDestructorName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTStatement;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCatchHandler;
import org.eclipse.cdt.internal.core.dom.parser.ASTAttributeOwner;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.DestructorCallCollector;
/**
* @author jcamelon
*/
public class CPPASTCatchHandler extends ASTAttributeOwner
implements ICPPASTCatchHandler, IASTAmbiguityParent {
private boolean isCatchAll;
private IASTStatement body;
private IASTDeclaration declaration;
private IScope scope;
private boolean fIsCatchAll;
private IASTStatement fBody;
private IASTDeclaration fDeclaration;
private IScope fScope;
private IASTImplicitDestructorName[] fImplicitDestructorNames;
public CPPASTCatchHandler() {
}
@ -47,27 +50,27 @@ public class CPPASTCatchHandler extends ASTAttributeOwner
@Override
public CPPASTCatchHandler copy(CopyStyle style) {
CPPASTCatchHandler copy = new CPPASTCatchHandler();
copy.setDeclaration(declaration == null ? null : declaration.copy(style));
copy.setCatchBody(body == null ? null : body.copy(style));
copy.setIsCatchAll(isCatchAll);
copy.setDeclaration(fDeclaration == null ? null : fDeclaration.copy(style));
copy.setCatchBody(fBody == null ? null : fBody.copy(style));
copy.setIsCatchAll(fIsCatchAll);
return copy(copy, style);
}
@Override
public void setIsCatchAll(boolean isEllipsis) {
assertNotFrozen();
isCatchAll = isEllipsis;
fIsCatchAll = isEllipsis;
}
@Override
public boolean isCatchAll() {
return isCatchAll;
return fIsCatchAll;
}
@Override
public void setCatchBody(IASTStatement compoundStatement) {
assertNotFrozen();
body = compoundStatement;
fBody = compoundStatement;
if (compoundStatement != null) {
compoundStatement.setParent(this);
compoundStatement.setPropertyInParent(CATCH_BODY);
@ -76,13 +79,13 @@ public class CPPASTCatchHandler extends ASTAttributeOwner
@Override
public IASTStatement getCatchBody() {
return body;
return fBody;
}
@Override
public void setDeclaration(IASTDeclaration decl) {
assertNotFrozen();
declaration = decl;
fDeclaration = decl;
if (decl != null) {
decl.setParent(this);
decl.setPropertyInParent(DECLARATION);
@ -91,9 +94,18 @@ public class CPPASTCatchHandler extends ASTAttributeOwner
@Override
public IASTDeclaration getDeclaration() {
return declaration;
return fDeclaration;
}
@Override
public IASTImplicitDestructorName[] getImplicitDestructorNames() {
if (fImplicitDestructorNames == null) {
fImplicitDestructorNames = DestructorCallCollector.getLocalVariablesDestructorCalls(this);
}
return fImplicitDestructorNames;
}
@Override
public boolean accept(ASTVisitor action) {
if (action.shouldVisitStatements) {
@ -105,9 +117,12 @@ public class CPPASTCatchHandler extends ASTAttributeOwner
}
if (!acceptByAttributeSpecifiers(action)) return false;
if (declaration != null && !declaration.accept(action)) return false;
if (body != null && !body.accept(action)) return false;
if (fDeclaration != null && !fDeclaration.accept(action)) return false;
if (fBody != null && !fBody.accept(action)) return false;
if (action.shouldVisitImplicitDestructorNames && !acceptByNodes(getImplicitDestructorNames(), action))
return false;
if (action.shouldVisitStatements) {
switch (action.leave(this)) {
case ASTVisitor.PROCESS_ABORT: return false;
@ -120,23 +135,23 @@ public class CPPASTCatchHandler extends ASTAttributeOwner
@Override
public void replace(IASTNode child, IASTNode other) {
if (body == child) {
if (fBody == child) {
other.setPropertyInParent(child.getPropertyInParent());
other.setParent(child.getParent());
body = (IASTStatement) other;
fBody = (IASTStatement) other;
}
if (declaration == child) {
if (fDeclaration == child) {
other.setParent(child.getParent());
other.setPropertyInParent(child.getPropertyInParent());
declaration = (IASTDeclaration) other;
fDeclaration = (IASTDeclaration) other;
}
}
@Override
public IScope getScope() {
if (scope == null) {
scope = new CPPBlockScope(this);
if (fScope == null) {
fScope = new CPPBlockScope(this);
}
return scope;
return fScope;
}
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2004, 2014 IBM Corporation and others.
* Copyright (c) 2004, 2015 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,22 +12,25 @@
package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement;
import org.eclipse.cdt.core.dom.ast.IASTImplicitDestructorName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTStatement;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompoundStatement;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope;
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.IASTAmbiguityParent;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.DestructorCallCollector;
/**
* @author jcamelon
*/
public class CPPASTCompoundStatement extends ASTAttributeOwner
implements IASTCompoundStatement, IASTAmbiguityParent {
implements ICPPASTCompoundStatement, IASTAmbiguityParent {
private IASTStatement[] statements = new IASTStatement[2];
private ICPPScope scope;
private IASTImplicitDestructorName[] fImplicitDestructorNames;
@Override
public CPPASTCompoundStatement copy() {
@ -68,6 +71,15 @@ public class CPPASTCompoundStatement extends ASTAttributeOwner
return scope;
}
@Override
public IASTImplicitDestructorName[] getImplicitDestructorNames() {
if (fImplicitDestructorNames == null) {
fImplicitDestructorNames = DestructorCallCollector.getLocalVariablesDestructorCalls(this);
}
return fImplicitDestructorNames;
}
@Override
public boolean accept(ASTVisitor action) {
if (action.shouldVisitStatements) {
@ -86,6 +98,9 @@ public class CPPASTCompoundStatement extends ASTAttributeOwner
return false;
}
if (action.shouldVisitImplicitDestructorNames && !acceptByNodes(getImplicitDestructorNames(), action))
return false;
if (action.shouldVisitStatements) {
switch (action.leave(this)) {
case ASTVisitor.PROCESS_ABORT: return false;

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2004, 2011 IBM Corporation and others.
* Copyright (c) 2004, 2015 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;
@ -16,11 +17,13 @@ import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement;
import org.eclipse.cdt.core.dom.ast.IASTExpressionStatement;
import org.eclipse.cdt.core.dom.ast.IASTImplicitDestructorName;
import org.eclipse.cdt.core.dom.ast.IASTStatement;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression;
import org.eclipse.cdt.core.dom.ast.gnu.IGNUASTCompoundStatementExpression;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.DestructorCallCollector;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalCompound;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed;
@ -30,6 +33,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed;
public class CPPASTCompoundStatementExpression extends ASTNode implements IGNUASTCompoundStatementExpression, ICPPASTExpression {
private IASTCompoundStatement fStatement;
private ICPPEvaluation fEval;
private IASTImplicitDestructorName[] fImplicitDestructorNames;
public CPPASTCompoundStatementExpression() {
}
@ -82,6 +86,15 @@ public class CPPASTCompoundStatementExpression extends ASTNode implements IGNUAS
}
}
@Override
public IASTImplicitDestructorName[] getImplicitDestructorNames() {
if (fImplicitDestructorNames == null) {
fImplicitDestructorNames = DestructorCallCollector.getTemporariesDestructorCalls(this);
}
return fImplicitDestructorNames;
}
@Override
public boolean accept(ASTVisitor action) {
if (action.shouldVisitExpressions) {
@ -94,6 +107,9 @@ public class CPPASTCompoundStatementExpression extends ASTNode implements IGNUAS
if (fStatement != null && !fStatement.accept(action)) return false;
if (action.shouldVisitImplicitDestructorNames && !acceptByNodes(getImplicitDestructorNames(), action))
return false;
if (action.shouldVisitExpressions) {
switch (action.leave(this)) {
case ASTVisitor.PROCESS_ABORT: return false;

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2004, 2012 IBM Corporation and others.
* Copyright (c) 2004, 2015 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;
@ -16,12 +17,14 @@ import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTConditionalExpression;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTImplicitDestructorName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.DestructorCallCollector;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalConditional;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed;
@ -31,6 +34,7 @@ public class CPPASTConditionalExpression extends ASTNode
private ICPPASTExpression fPositive;
private ICPPASTExpression fNegative;
private ICPPEvaluation fEval;
private IASTImplicitDestructorName[] fImplicitDestructorNames;
public CPPASTConditionalExpression() {
}
@ -100,6 +104,15 @@ public class CPPASTConditionalExpression extends ASTNode
}
}
@Override
public IASTImplicitDestructorName[] getImplicitDestructorNames() {
if (fImplicitDestructorNames == null) {
fImplicitDestructorNames = DestructorCallCollector.getTemporariesDestructorCalls(this);
}
return fImplicitDestructorNames;
}
@Override
public boolean accept(ASTVisitor action) {
if (action.shouldVisitExpressions) {
@ -117,6 +130,9 @@ public class CPPASTConditionalExpression extends ASTNode
if (fNegative != null && !fNegative.accept(action))
return false;
if (action.shouldVisitImplicitDestructorNames && !acceptByNodes(getImplicitDestructorNames(), action))
return false;
if (action.shouldVisitExpressions && action.leave(this) == ASTVisitor.PROCESS_ABORT)
return false;

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2004, 2011 IBM Corporation and others.
* Copyright (c) 2004, 2015 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;
@ -18,6 +19,7 @@ import java.util.List;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTImplicitDestructorName;
import org.eclipse.cdt.core.dom.ast.IASTImplicitName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IType;
@ -27,6 +29,7 @@ import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
import org.eclipse.cdt.internal.core.dom.parser.Value;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.DestructorCallCollector;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed;
@ -38,6 +41,7 @@ public class CPPASTDeleteExpression extends ASTNode implements ICPPASTDeleteExpr
private boolean isVectored;
private IASTImplicitName[] implicitNames;
private IASTImplicitDestructorName[] fImplicitDestructorNames;
public CPPASTDeleteExpression() {
}
@ -140,6 +144,15 @@ public class CPPASTDeleteExpression extends ASTNode implements ICPPASTDeleteExpr
return implicitNames;
}
@Override
public IASTImplicitDestructorName[] getImplicitDestructorNames() {
if (fImplicitDestructorNames == null) {
fImplicitDestructorNames = DestructorCallCollector.getTemporariesDestructorCalls(this);
}
return fImplicitDestructorNames;
}
@Override
public boolean accept(ASTVisitor action) {
if (action.shouldVisitExpressions) {
@ -150,16 +163,15 @@ public class CPPASTDeleteExpression extends ASTNode implements ICPPASTDeleteExpr
}
}
if (action.shouldVisitImplicitNames) {
for (IASTImplicitName name : getImplicitNames()) {
if (!name.accept(action))
return false;
}
}
if (action.shouldVisitImplicitNames && !acceptByNodes(getImplicitNames(), action))
return false;
if (operand != null && !operand.accept(action))
return false;
if (action.shouldVisitImplicitDestructorNames && !acceptByNodes(getImplicitDestructorNames(), action))
return false;
if (action.shouldVisitExpressions) {
switch (action.leave(this)) {
case ASTVisitor.PROCESS_ABORT: return false;

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2004, 2011 IBM Corporation and others.
* Copyright (c) 2004, 2015 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
@ -9,6 +9,7 @@
* John Camelon (IBM) - Initial API and implementation
* Mike Kucera (IBM) - implicit names
* Markus Schorn (Wind River Systems)
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
@ -16,6 +17,7 @@ import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTImplicitDestructorName;
import org.eclipse.cdt.core.dom.ast.IASTImplicitName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IType;
@ -25,6 +27,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
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.IASTAmbiguityParent;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.DestructorCallCollector;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalComma;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed;
@ -37,6 +40,8 @@ public class CPPASTExpressionList extends ASTNode implements ICPPASTExpressionLi
*/
private IASTImplicitName[] fImplicitNames;
private IASTImplicitDestructorName[] fImplicitDestructorNames;
private ICPPEvaluation fEvaluation;
@Override
@ -93,6 +98,9 @@ public class CPPASTExpressionList extends ASTNode implements ICPPASTExpressionLi
}
}
if (action.shouldVisitImplicitDestructorNames && !acceptByNodes(getImplicitDestructorNames(), action))
return false;
if (action.shouldVisitExpressions) {
switch (action.leave(this)) {
case ASTVisitor.PROCESS_ABORT: return false;
@ -136,6 +144,15 @@ public class CPPASTExpressionList extends ASTNode implements ICPPASTExpressionLi
return ArrayUtil.removeNulls(IASTImplicitName.class, computeImplicitNames());
}
@Override
public IASTImplicitDestructorName[] getImplicitDestructorNames() {
if (fImplicitDestructorNames == null) {
fImplicitDestructorNames = DestructorCallCollector.getTemporariesDestructorCalls(this);
}
return fImplicitDestructorNames;
}
private ICPPFunction[] getOverloads() {
ICPPEvaluation eval = getEvaluation();
if (eval instanceof EvalComma) {

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2004, 2011 IBM Corporation and others.
* Copyright (c) 2004, 2015 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
@ -10,6 +10,7 @@
* Bryan Wilkinson (QNX)
* Mike Kucera (IBM)
* Markus Schorn (Wind River Systems)
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
@ -21,6 +22,7 @@ import java.util.List;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTImplicitDestructorName;
import org.eclipse.cdt.core.dom.ast.IASTImplicitName;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
@ -43,6 +45,7 @@ import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPFunctionSet;
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.DestructorCallCollector;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalID;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalMemberAccess;
@ -55,6 +58,7 @@ public class CPPASTFieldReference extends ASTNode
private IASTName fName;
private IASTImplicitName[] fImplicitNames;
private ICPPEvaluation fEvaluation;
private IASTImplicitDestructorName[] fImplicitDestructorNames;
public CPPASTFieldReference() {
}
@ -160,6 +164,15 @@ public class CPPASTFieldReference extends ASTNode
return fImplicitNames;
}
@Override
public IASTImplicitDestructorName[] getImplicitDestructorNames() {
if (fImplicitDestructorNames == null) {
fImplicitDestructorNames = DestructorCallCollector.getTemporariesDestructorCalls(this);
}
return fImplicitDestructorNames;
}
@Override
public boolean accept(ASTVisitor action) {
if (action.shouldVisitExpressions) {
@ -183,6 +196,9 @@ public class CPPASTFieldReference extends ASTNode
if (fName != null && !fName.accept(action))
return false;
if (action.shouldVisitImplicitDestructorNames && !acceptByNodes(getImplicitDestructorNames(), action))
return false;
if (action.shouldVisitExpressions) {
switch (action.leave(this)) {
case ASTVisitor.PROCESS_ABORT: return false;

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2004, 2014 IBM Corporation and others.
* Copyright (c) 2004, 2015 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
@ -16,25 +16,28 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTImplicitDestructorName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTStatement;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTForStatement;
import org.eclipse.cdt.internal.core.dom.parser.ASTAttributeOwner;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.DestructorCallCollector;
/**
* For statement in C++
*/
public class CPPASTForStatement extends ASTAttributeOwner
implements ICPPASTForStatement, IASTAmbiguityParent {
private IScope scope;
private IScope fScope;
private IASTStatement init;
private IASTExpression condition;
private IASTDeclaration condDeclaration;
private IASTExpression iterationExpression;
private IASTStatement body;
private IASTStatement fInit;
private IASTExpression fCondition;
private IASTDeclaration fCondDeclaration;
private IASTExpression fIterationExpression;
private IASTStatement fBody;
private IASTImplicitDestructorName[] fImplicitDestructorNames;
public CPPASTForStatement() {
}
@ -63,40 +66,40 @@ public class CPPASTForStatement extends ASTAttributeOwner
@Override
public CPPASTForStatement copy(CopyStyle style) {
CPPASTForStatement copy = new CPPASTForStatement();
copy.setInitializerStatement(init == null ? null : init.copy(style));
copy.setConditionDeclaration(condDeclaration == null ? null : condDeclaration.copy(style));
copy.setConditionExpression(condition == null ? null : condition.copy(style));
copy.setIterationExpression(iterationExpression == null ?
null : iterationExpression.copy(style));
copy.setBody(body == null ? null : body.copy(style));
copy.setInitializerStatement(fInit == null ? null : fInit.copy(style));
copy.setConditionDeclaration(fCondDeclaration == null ? null : fCondDeclaration.copy(style));
copy.setConditionExpression(fCondition == null ? null : fCondition.copy(style));
copy.setIterationExpression(fIterationExpression == null ?
null : fIterationExpression.copy(style));
copy.setBody(fBody == null ? null : fBody.copy(style));
return copy(copy, style);
}
@Override
public IASTExpression getConditionExpression() {
return condition;
return fCondition;
}
@Override
public void setConditionExpression(IASTExpression condition) {
assertNotFrozen();
this.condition = condition;
this.fCondition = condition;
if (condition != null) {
condition.setParent(this);
condition.setPropertyInParent(CONDITION);
condDeclaration= null;
fCondDeclaration= null;
}
}
@Override
public IASTExpression getIterationExpression() {
return iterationExpression;
return fIterationExpression;
}
@Override
public void setIterationExpression(IASTExpression iterator) {
assertNotFrozen();
this.iterationExpression = iterator;
this.fIterationExpression = iterator;
if (iterator != null) {
iterator.setParent(this);
iterator.setPropertyInParent(ITERATION);
@ -105,13 +108,13 @@ public class CPPASTForStatement extends ASTAttributeOwner
@Override
public IASTStatement getBody() {
return body;
return fBody;
}
@Override
public void setBody(IASTStatement statement) {
assertNotFrozen();
body = statement;
fBody = statement;
if (statement != null) {
statement.setParent(this);
statement.setPropertyInParent(BODY);
@ -120,11 +123,20 @@ public class CPPASTForStatement extends ASTAttributeOwner
@Override
public IScope getScope() {
if (scope == null)
scope = new CPPBlockScope(this);
return scope;
if (fScope == null)
fScope = new CPPBlockScope(this);
return fScope;
}
@Override
public IASTImplicitDestructorName[] getImplicitDestructorNames() {
if (fImplicitDestructorNames == null) {
fImplicitDestructorNames = DestructorCallCollector.getLocalVariablesDestructorCalls(this);
}
return fImplicitDestructorNames;
}
@Override
public boolean accept(ASTVisitor action) {
if (action.shouldVisitStatements) {
@ -136,12 +148,15 @@ public class CPPASTForStatement extends ASTAttributeOwner
}
if (!acceptByAttributeSpecifiers(action)) return false;
if (init != null && !init.accept(action)) return false;
if (condition != null && !condition.accept(action)) return false;
if (condDeclaration != null && !condDeclaration.accept(action)) return false;
if (iterationExpression != null && !iterationExpression.accept(action)) return false;
if (body != null && !body.accept(action)) return false;
if (fInit != null && !fInit.accept(action)) return false;
if (fCondition != null && !fCondition.accept(action)) return false;
if (fCondDeclaration != null && !fCondDeclaration.accept(action)) return false;
if (fIterationExpression != null && !fIterationExpression.accept(action)) return false;
if (fBody != null && !fBody.accept(action)) return false;
if (action.shouldVisitImplicitDestructorNames && !acceptByNodes(getImplicitDestructorNames(), action))
return false;
if (action.shouldVisitStatements) {
switch (action.leave(this)) {
case ASTVisitor.PROCESS_ABORT: return false;
@ -154,36 +169,36 @@ public class CPPASTForStatement extends ASTAttributeOwner
@Override
public void replace(IASTNode child, IASTNode other) {
if (body == child) {
if (fBody == child) {
other.setPropertyInParent(child.getPropertyInParent());
other.setParent(child.getParent());
body = (IASTStatement) other;
} else if (child == condition || child == condDeclaration) {
fBody = (IASTStatement) other;
} else if (child == fCondition || child == fCondDeclaration) {
if (other instanceof IASTExpression) {
setConditionExpression((IASTExpression) other);
} else if (other instanceof IASTDeclaration) {
setConditionDeclaration((IASTDeclaration) other);
}
} else if (child == iterationExpression) {
} else if (child == fIterationExpression) {
other.setPropertyInParent(child.getPropertyInParent());
other.setParent(child.getParent());
iterationExpression = (IASTExpression) other;
} else if (child == init) {
fIterationExpression = (IASTExpression) other;
} else if (child == fInit) {
other.setPropertyInParent(child.getPropertyInParent());
other.setParent(child.getParent());
init = (IASTStatement) other;
fInit = (IASTStatement) other;
}
}
@Override
public IASTStatement getInitializerStatement() {
return init;
return fInit;
}
@Override
public void setInitializerStatement(IASTStatement statement) {
assertNotFrozen();
init = statement;
fInit = statement;
if (statement != null) {
statement.setParent(this);
statement.setPropertyInParent(INITIALIZER);
@ -193,16 +208,16 @@ public class CPPASTForStatement extends ASTAttributeOwner
@Override
public void setConditionDeclaration(IASTDeclaration d) {
assertNotFrozen();
condDeclaration = d;
fCondDeclaration = d;
if (d != null) {
d.setParent(this);
d.setPropertyInParent(CONDITION_DECLARATION);
condition= null;
fCondition= null;
}
}
@Override
public IASTDeclaration getConditionDeclaration() {
return condDeclaration;
return fCondDeclaration;
}
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2004, 2012 IBM Corporation and others.
* Copyright (c) 2004, 2015 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
@ -9,6 +9,7 @@
* John Camelon (IBM) - Initial API and implementation
* Mike Kucera (IBM) - implicit names
* Markus Schorn (Wind River Systems)
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
@ -23,6 +24,7 @@ import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.ExpansionOverlapsBoundaryException;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
import org.eclipse.cdt.core.dom.ast.IASTImplicitDestructorName;
import org.eclipse.cdt.core.dom.ast.IASTImplicitName;
import org.eclipse.cdt.core.dom.ast.IASTInitializerClause;
import org.eclipse.cdt.core.dom.ast.IASTName;
@ -41,6 +43,7 @@ import org.eclipse.cdt.core.parser.IToken;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.DestructorCallCollector;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFunctionCall;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalTypeId;
@ -53,6 +56,7 @@ public class CPPASTFunctionCallExpression extends ASTNode
private IASTImplicitName[] fImplicitNames;
private ICPPEvaluation fEvaluation;
private IASTImplicitDestructorName[] fImplicitDestructorNames;
public CPPASTFunctionCallExpression() {
setArguments(null);
@ -176,6 +180,15 @@ public class CPPASTFunctionCallExpression extends ASTNode
return fImplicitNames;
}
@Override
public IASTImplicitDestructorName[] getImplicitDestructorNames() {
if (fImplicitDestructorNames == null) {
fImplicitDestructorNames = DestructorCallCollector.getTemporariesDestructorCalls(this);
}
return fImplicitDestructorNames;
}
@Override
public boolean accept(ASTVisitor action) {
if (action.shouldVisitExpressions) {
@ -202,6 +215,9 @@ public class CPPASTFunctionCallExpression extends ASTNode
if (implicits != null && implicits.length > 1 && !implicits[1].accept(action))
return false;
if (action.shouldVisitImplicitDestructorNames && !acceptByNodes(getImplicitDestructorNames(), action))
return false;
if (action.shouldVisitExpressions && action.leave(this) == ASTVisitor.PROCESS_ABORT)
return false;

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2004, 2011 IBM Corporation and others.
* Copyright (c) 2004, 2015 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
@ -9,6 +9,7 @@
* John Camelon (IBM) - Initial API and implementation
* Bryan Wilkinson (QNX)
* Markus Schorn (Wind River Systems)
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
@ -16,6 +17,7 @@ import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
import org.eclipse.cdt.core.dom.ast.IASTImplicitDestructorName;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.ICPPASTCompletionContext;
@ -25,6 +27,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
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.DestructorCallCollector;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalID;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.FunctionSetType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
@ -33,6 +36,7 @@ public class CPPASTIdExpression extends ASTNode
implements IASTIdExpression, ICPPASTExpression, ICPPASTCompletionContext {
private IASTName fName;
private ICPPEvaluation fEvaluation;
private IASTImplicitDestructorName[] fImplicitDestructorNames;
public CPPASTIdExpression() {
}
@ -67,6 +71,15 @@ public class CPPASTIdExpression extends ASTNode
}
}
@Override
public IASTImplicitDestructorName[] getImplicitDestructorNames() {
if (fImplicitDestructorNames == null) {
fImplicitDestructorNames = DestructorCallCollector.getTemporariesDestructorCalls(this);
}
return fImplicitDestructorNames;
}
@Override
public boolean accept(ASTVisitor action) {
if (action.shouldVisitExpressions) {
@ -79,6 +92,9 @@ public class CPPASTIdExpression extends ASTNode
if (fName != null && !fName.accept(action)) return false;
if (action.shouldVisitImplicitDestructorNames && !acceptByNodes(getImplicitDestructorNames(), action))
return false;
if (action.shouldVisitExpressions) {
switch (action.leave(this)) {
case ASTVisitor.PROCESS_ABORT: return false;

View file

@ -0,0 +1,32 @@
/*******************************************************************************
* Copyright (c) 2015 Google, Inc 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Sergey Prigogin (Google) - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.IASTImplicitDestructorName;
import org.eclipse.cdt.core.dom.ast.IASTImplicitDestructorNameOwner;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
public class CPPASTImplicitDestructorName extends CPPASTImplicitName implements IASTImplicitDestructorName {
private final IASTName constructionPoint;
public CPPASTImplicitDestructorName(char[] name, IASTNode parent, IASTName constructionPoint) {
super(name, parent);
this.constructionPoint = constructionPoint;
setPropertyInParent(IASTImplicitDestructorNameOwner.IMPLICIT_DESTRUCTOR_NAME);
}
@Override
public IASTName getConstructionPoint() {
return constructionPoint;
}
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2010, 2011 Wind River Systems, Inc. and others.
* Copyright (c) 2010, 2015 Wind River Systems, Inc. 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
@ -7,6 +7,7 @@
*
* Contributors:
* Markus Schorn - initial API and implementation
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
@ -14,6 +15,7 @@ import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement;
import org.eclipse.cdt.core.dom.ast.IASTImplicitDestructorName;
import org.eclipse.cdt.core.dom.ast.IASTImplicitName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCapture;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
@ -109,6 +111,11 @@ public class CPPASTLambdaExpression extends ASTNode implements ICPPASTLambdaExpr
return new IASTImplicitName[] {getFunctionCallOperatorName()};
}
@Override
public IASTImplicitDestructorName[] getImplicitDestructorNames() {
return IASTImplicitDestructorName.EMPTY_NAME_ARRAY; // Lambda expression is never a full-expression.
}
@Override
public boolean accept(ASTVisitor visitor) {
if (visitor.shouldVisitExpressions) {

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2004, 2011 IBM Corporation and others.
* Copyright (c) 2004, 2015 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;
@ -15,6 +16,7 @@ import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTImplicitDestructorName;
import org.eclipse.cdt.core.dom.ast.IBasicType;
import org.eclipse.cdt.core.dom.ast.IBasicType.Kind;
import org.eclipse.cdt.core.dom.ast.IScope;
@ -92,6 +94,11 @@ public class CPPASTLiteralExpression extends ASTNode implements ICPPASTLiteralEx
return new String(fValue);
}
@Override
public IASTImplicitDestructorName[] getImplicitDestructorNames() {
return IASTImplicitDestructorName.EMPTY_NAME_ARRAY; // Literal expression does not call destructors.
}
@Override
public boolean accept(ASTVisitor action) {
if (action.shouldVisitExpressions) {

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2004, 2014 IBM Corporation and others.
* Copyright (c) 2004, 2015 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
@ -21,6 +21,7 @@ import org.eclipse.cdt.core.dom.ast.IASTArrayModifier;
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTExpressionList;
import org.eclipse.cdt.core.dom.ast.IASTImplicitDestructorName;
import org.eclipse.cdt.core.dom.ast.IASTImplicitName;
import org.eclipse.cdt.core.dom.ast.IASTInitializer;
import org.eclipse.cdt.core.dom.ast.IASTInitializerClause;
@ -41,6 +42,7 @@ import org.eclipse.cdt.internal.core.dom.parser.ProblemType;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTExpressionList;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.DestructorCallCollector;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalTypeId;
import org.eclipse.core.runtime.Assert;
@ -57,6 +59,7 @@ public class CPPASTNewExpression extends ASTNode implements ICPPASTNewExpression
private IASTExpression[] fCachedArraySizes;
private ICPPEvaluation fEvaluation;
private IASTImplicitName[] fImplicitNames;
private IASTImplicitDestructorName[] fImplicitDestructorNames;
public CPPASTNewExpression() {
}
@ -199,6 +202,15 @@ public class CPPASTNewExpression extends ASTNode implements ICPPASTNewExpression
return fImplicitNames;
}
@Override
public IASTImplicitDestructorName[] getImplicitDestructorNames() {
if (fImplicitDestructorNames == null) {
fImplicitDestructorNames = DestructorCallCollector.getTemporariesDestructorCalls(this);
}
return fImplicitDestructorNames;
}
/**
* Returns true if this expression is allocating an array.
* @since 5.1
@ -244,6 +256,9 @@ public class CPPASTNewExpression extends ASTNode implements ICPPASTNewExpression
if (fInitializer != null && !fInitializer.accept(action))
return false;
if (action.shouldVisitImplicitDestructorNames && !acceptByNodes(getImplicitDestructorNames(), action))
return false;
if (action.shouldVisitExpressions) {
switch (action.leave(this)) {
case ASTVisitor.PROCESS_ABORT: return false;

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2009, 2013 Wind River Systems, Inc. and others.
* Copyright (c) 2009, 2015 Wind River Systems, Inc. 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,11 +8,13 @@
* Contributors:
* Markus Schorn - initial API and implementation
* Natan Ridge
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTImplicitDestructorName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression;
@ -82,6 +84,11 @@ public class CPPASTPackExpansionExpression extends ASTNode implements ICPPASTPac
return fPattern.getValueCategory();
}
@Override
public IASTImplicitDestructorName[] getImplicitDestructorNames() {
return IASTImplicitDestructorName.EMPTY_NAME_ARRAY; // Pack expression is never a full-expression.
}
@Override
public boolean accept(ASTVisitor visitor) {
if (visitor.shouldVisitExpressions) {

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2004, 2011 IBM Corporation and others.
* Copyright (c) 2004, 2015 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,12 +8,14 @@
* 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;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTImplicitDestructorName;
import org.eclipse.cdt.core.dom.ast.IASTProblem;
import org.eclipse.cdt.core.dom.ast.IASTProblemExpression;
import org.eclipse.cdt.core.dom.ast.IType;
@ -41,6 +43,11 @@ public class CPPASTProblemExpression extends CPPASTProblemOwner implements IASTP
return copy(copy, style);
}
@Override
public IASTImplicitDestructorName[] getImplicitDestructorNames() {
return IASTImplicitDestructorName.EMPTY_NAME_ARRAY;
}
@Override
public boolean accept(ASTVisitor action) {
if (action.shouldVisitExpressions) {

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2010, 2014 Wind River Systems, Inc. and others.
* Copyright (c) 2010, 2015 Wind River Systems, Inc. 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
@ -17,6 +17,7 @@ import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUti
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTImplicitDestructorName;
import org.eclipse.cdt.core.dom.ast.IASTImplicitName;
import org.eclipse.cdt.core.dom.ast.IASTInitializerClause;
import org.eclipse.cdt.core.dom.ast.IASTNode;
@ -31,10 +32,11 @@ import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.DestructorCallCollector;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
/**
* Range based for loop in c++.
* Range based 'for' loop in C++.
*/
public class CPPASTRangeBasedForStatement extends ASTAttributeOwner
implements ICPPASTRangeBasedForStatement, IASTAmbiguityParent {
@ -43,6 +45,7 @@ public class CPPASTRangeBasedForStatement extends ASTAttributeOwner
private IASTInitializerClause fInitClause;
private IASTStatement fBody;
private IASTImplicitName[] fImplicitNames;
private IASTImplicitDestructorName[] fImplicitDestructorNames;
public CPPASTRangeBasedForStatement() {
}
@ -173,6 +176,15 @@ public class CPPASTRangeBasedForStatement extends ASTAttributeOwner
return fImplicitNames;
}
@Override
public IASTImplicitDestructorName[] getImplicitDestructorNames() {
if (fImplicitDestructorNames == null) {
fImplicitDestructorNames = DestructorCallCollector.getLocalVariablesDestructorCalls(this);
}
return fImplicitDestructorNames;
}
@Override
public boolean accept( ASTVisitor action ){
if (action.shouldVisitStatements) {
@ -199,6 +211,9 @@ public class CPPASTRangeBasedForStatement extends ASTAttributeOwner
if (fBody != null && !fBody.accept(action))
return false;
if (action.shouldVisitImplicitDestructorNames && !acceptByNodes(getImplicitDestructorNames(), action))
return false;
if (action.shouldVisitStatements && action.leave(this) == ASTVisitor.PROCESS_ABORT)
return false;
return true;

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2004, 2011 IBM Corporation and others.
* Copyright (c) 2004, 2015 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,11 +8,13 @@
* 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;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTImplicitDestructorName;
import org.eclipse.cdt.core.dom.ast.IASTInitializer;
import org.eclipse.cdt.core.dom.ast.IASTInitializerClause;
import org.eclipse.cdt.core.dom.ast.IBasicType.Kind;
@ -25,6 +27,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSimpleTypeConstructorExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.DestructorCallCollector;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalTypeId;
@ -33,6 +36,7 @@ public class CPPASTSimpleTypeConstructorExpression extends ASTNode
private ICPPASTDeclSpecifier fDeclSpec;
private IASTInitializer fInitializer;
private ICPPEvaluation fEvaluation;
private IASTImplicitDestructorName[] fImplicitDestructorNames;
public CPPASTSimpleTypeConstructorExpression() {
}
@ -122,6 +126,15 @@ public class CPPASTSimpleTypeConstructorExpression extends ASTNode
return false;
}
@Override
public IASTImplicitDestructorName[] getImplicitDestructorNames() {
if (fImplicitDestructorNames == null) {
fImplicitDestructorNames = DestructorCallCollector.getTemporariesDestructorCalls(this);
}
return fImplicitDestructorNames;
}
@Override
public boolean accept(ASTVisitor action) {
if (action.shouldVisitExpressions) {
@ -138,6 +151,9 @@ public class CPPASTSimpleTypeConstructorExpression extends ASTNode
if (fInitializer != null && !fInitializer.accept(action))
return false;
if (action.shouldVisitImplicitDestructorNames && !acceptByNodes(getImplicitDestructorNames(), action))
return false;
if (action.shouldVisitExpressions) {
switch (action.leave(this)) {
case ASTVisitor.PROCESS_ABORT: return false;

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2011, 2014 Wind River Systems, Inc. and others.
* Copyright (c) 2011, 2015 Wind River Systems, Inc. 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
@ -17,6 +17,7 @@ import java.util.List;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTImplicitDestructorName;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IBinding;
@ -174,4 +175,9 @@ public class CPPASTTemplateIDAmbiguity extends ASTAmbiguousNode
public IASTExpression[] getExpressions() {
throw new UnsupportedOperationException();
}
@Override
public IASTImplicitDestructorName[] getImplicitDestructorNames() {
throw new UnsupportedOperationException();
}
}

View file

@ -14,6 +14,7 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTImplicitDestructorName;
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
import org.eclipse.cdt.core.dom.ast.IProblemType;
import org.eclipse.cdt.core.dom.ast.IType;
@ -74,6 +75,11 @@ public class CPPASTTypeIdExpression extends ASTNode implements ICPPASTTypeIdExpr
return fTypeId;
}
@Override
public IASTImplicitDestructorName[] getImplicitDestructorNames() {
return IASTImplicitDestructorName.EMPTY_NAME_ARRAY; // Type-id expression does not call destructors.
}
@Override
public boolean accept(ASTVisitor action) {
if (action.shouldVisitExpressions) {

View file

@ -1,16 +1,20 @@
/*******************************************************************************
* Copyright (c) 2009, 2011 Wind River Systems, Inc. and others.
* Copyright (c) 2005, 2015 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Markus Schorn - initial API and implementation
*******************************************************************************/
* John Camelon (IBM Rational Software) - Initial API and implementation
* Yuan Zhang / Beth Tibbitts (IBM Research)
* Markus Schorn (Wind River Systems)
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTImplicitDestructorName;
import org.eclipse.cdt.core.dom.ast.IASTInitializer;
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
import org.eclipse.cdt.core.dom.ast.IASTTypeIdInitializerExpression;
@ -20,6 +24,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerClause;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.DestructorCallCollector;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalTypeId;
@ -31,6 +36,7 @@ public class CPPASTTypeIdInitializerExpression extends ASTNode
private IASTTypeId fTypeId;
private IASTInitializer fInitializer;
private ICPPEvaluation fEvaluation;
private IASTImplicitDestructorName[] fImplicitDestructorNames;
public CPPASTTypeIdInitializerExpression() {
}
@ -70,6 +76,15 @@ public class CPPASTTypeIdInitializerExpression extends ASTNode
}
}
@Override
public IASTImplicitDestructorName[] getImplicitDestructorNames() {
if (fImplicitDestructorNames == null) {
fImplicitDestructorNames = DestructorCallCollector.getTemporariesDestructorCalls(this);
}
return fImplicitDestructorNames;
}
@Override
public boolean accept(ASTVisitor action) {
if (action.shouldVisitExpressions) {
@ -83,6 +98,9 @@ public class CPPASTTypeIdInitializerExpression extends ASTNode
if (fTypeId != null && !fTypeId.accept(action)) return false;
if (fInitializer != null && !fInitializer.accept(action)) return false;
if (action.shouldVisitImplicitDestructorNames && !acceptByNodes(getImplicitDestructorNames(), action))
return false;
if (action.shouldVisitExpressions) {
switch (action.leave(this)) {
case ASTVisitor.PROCESS_ABORT: return false;

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2004, 2012 IBM Corporation and others.
* Copyright (c) 2004, 2015 IBM Corporation and others.
* All rights reserved. This program and the accompanying masterials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -10,6 +10,7 @@
* Sergey Prigogin (Google)
* Mike Kucera (IBM)
* Markus Schorn (Wind River Systems)
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
@ -18,6 +19,7 @@ import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
import org.eclipse.cdt.core.dom.ast.IASTImplicitDestructorName;
import org.eclipse.cdt.core.dom.ast.IASTImplicitName;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
@ -31,6 +33,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.DestructorCallCollector;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalUnary;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.FunctionSetType;
@ -43,6 +46,7 @@ public class CPPASTUnaryExpression extends ASTNode implements ICPPASTUnaryExpres
private ICPPASTExpression fOperand;
private ICPPEvaluation fEvaluation;
private IASTImplicitName[] fImplicitNames;
private IASTImplicitDestructorName[] fImplicitDestructorNames;
public CPPASTUnaryExpression() {
}
@ -112,6 +116,15 @@ public class CPPASTUnaryExpression extends ASTNode implements ICPPASTUnaryExpres
return fImplicitNames;
}
@Override
public IASTImplicitDestructorName[] getImplicitDestructorNames() {
if (fImplicitDestructorNames == null) {
fImplicitDestructorNames = DestructorCallCollector.getTemporariesDestructorCalls(this);
}
return fImplicitDestructorNames;
}
@Override
public boolean accept(ASTVisitor action) {
if (action.shouldVisitExpressions) {
@ -141,6 +154,9 @@ public class CPPASTUnaryExpression extends ASTNode implements ICPPASTUnaryExpres
}
}
if (action.shouldVisitImplicitDestructorNames && !acceptByNodes(getImplicitDestructorNames(), action))
return false;
if (action.shouldVisitExpressions) {
switch (action.leave(this)) {
case ASTVisitor.PROCESS_ABORT: return false;

View file

@ -0,0 +1,224 @@
/*******************************************************************************
* Copyright (c) 2015 Google, Inc 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Sergey Prigogin (Google) - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
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.TDEF;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.EScopeKind;
import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression;
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTEqualsInitializer;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
import org.eclipse.cdt.core.dom.ast.IASTImplicitDestructorName;
import org.eclipse.cdt.core.dom.ast.IASTImplicitDestructorNameOwner;
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.IASTInitializerClause;
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.ICPPASTExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNewExpression;
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.ICPPMethod;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariable;
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.cpp.CPPASTImplicitDestructorName;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper.MethodKind;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPASTInternalScope;
/**
* Finds destructor calls for temporaries and local variables.
*/
public class DestructorCallCollector {
/**
* Returns the implicit names corresponding to the destructor calls for temporaries destroyed at the end
* of the expression. Only expression that is not a subexpression of another expression may contain
* implicit destructor calls.
*
* @param expression the expression to get the destructor calls for
* @return an array of destructor names
*/
public static IASTImplicitDestructorName[] getTemporariesDestructorCalls(ICPPASTExpression expression) {
if (expression.getParent() instanceof ICPPASTExpression)
return IASTImplicitDestructorName.EMPTY_NAME_ARRAY; // Not a full-expression
TemporariesDestructorCollector collector = new TemporariesDestructorCollector(expression);
expression.accept(collector);
return collector.getDestructorCalls();
}
/**
* Returns the implicit names corresponding to the destructor calls for the local variables destroyed at
* the end of the statement.
*
* @param statement the expression to get the destructor calls for
* @return an array of destructor names
*/
public static IASTImplicitDestructorName[] getLocalVariablesDestructorCalls(IASTStatement statement) {
if (!(statement instanceof IASTImplicitDestructorNameOwner))
return IASTImplicitDestructorName.EMPTY_NAME_ARRAY;
LocalVariablesDestructorCollector collector =
new LocalVariablesDestructorCollector((IASTImplicitDestructorNameOwner) statement);
statement.accept(collector);
return collector.getDestructorCalls();
}
// Not instantiatable. All methods are static.
private DestructorCallCollector() {
}
private abstract static class DestructorCollector extends ASTVisitor {
protected final IASTImplicitDestructorNameOwner owner;
private IASTImplicitDestructorName[] destructorNames = IASTImplicitDestructorName.EMPTY_NAME_ARRAY;
DestructorCollector(IASTImplicitDestructorNameOwner owner) {
this.owner = owner;
}
IASTImplicitDestructorName[] getDestructorCalls() {
destructorNames = ArrayUtil.trim(destructorNames);
return destructorNames;
}
static ICPPMethod findDestructor(ICPPClassType classType, IASTNode point) {
return ClassTypeHelper.getMethodInClass(classType, MethodKind.DTOR, point);
}
protected void addDestructorCall(IASTName name, ICPPMethod destructor) {
CPPASTImplicitDestructorName destructorName =
new CPPASTImplicitDestructorName(destructor.getNameCharArray(), owner, name);
destructorName.setBinding(destructor);
ASTNode parentNode = (ASTNode) owner;
int offset = parentNode.getOffset() + parentNode.getLength();
if (!(owner instanceof ICPPASTExpression))
offset--; // Before the closing brace.
destructorName.setOffsetAndLength(offset, 0);
destructorNames = ArrayUtil.prepend(destructorNames, destructorName);
}
}
private static class TemporariesDestructorCollector extends DestructorCollector {
private TemporariesDestructorCollector(ICPPASTExpression owner) {
super(owner);
shouldVisitImplicitNames = true;
}
@Override
public int visit(IASTName name) {
if (name instanceof IASTImplicitName && !(name.getParent() instanceof ICPPASTNewExpression)) {
IBinding binding = name.resolveBinding();
if (binding instanceof ICPPConstructor) {
ICPPClassType classType = ((ICPPConstructor) binding).getClassOwner();
ICPPMethod destructor = findDestructor(classType, name);
if (destructor != null && !isBoundToVariable(name)) {
addDestructorCall(name, destructor);
}
}
}
return PROCESS_CONTINUE;
}
private boolean isBoundToVariable(IASTName name) {
IASTNode parent = name.getParent();
if (!(parent instanceof IASTExpression))
return false;
parent = parent.getParent();
if (!(parent instanceof IASTBinaryExpression))
return false;
IASTBinaryExpression binExpr = (IASTBinaryExpression) parent;
if (binExpr.getOperator() != IASTBinaryExpression.op_assign)
return false;
IASTExpression left = binExpr.getOperand1();
if (left instanceof IASTIdExpression) {
IASTName name2 = ((IASTIdExpression) left).getName();
IBinding binding = name2.resolveBinding();
if (binding instanceof ICPPVariable) {
return true;
}
}
return false;
}
}
private static class LocalVariablesDestructorCollector extends DestructorCollector {
private LocalVariablesDestructorCollector(IASTImplicitDestructorNameOwner owner) {
super(owner);
shouldVisitNames = true;
shouldVisitImplicitNames = true;
}
@Override
public int visit(IASTName name) {
if (name.getPropertyInParent() == IASTDeclarator.DECLARATOR_NAME) {
IBinding binding = name.resolveBinding();
if (binding instanceof ICPPVariable) {
ICPPVariable var = (ICPPVariable) binding;
try {
IScope scope = var.getScope();
if (scope.getKind() == EScopeKind.eLocal && scope instanceof ICPPASTInternalScope) {
IASTNode scopeNode = ((ICPPASTInternalScope) scope).getPhysicalNode();
if (scopeNode.equals(owner)) {
IType type = SemanticUtil.getNestedType(var.getType(), TDEF | CVTYPE);
if (type instanceof ICPPClassType) {
ICPPMethod destructor = findDestructor((ICPPClassType) type, name);
addDestructorCall(name, destructor);
} else if (type instanceof ICPPReferenceType) {
IASTDeclarator decl = (IASTDeclarator) name.getParent();
addDestructorCallForTemporaryBoundToReference(decl);
}
}
}
} catch (DOMException e) {
CCorePlugin.log(e);
}
}
}
return PROCESS_CONTINUE;
}
private void addDestructorCallForTemporaryBoundToReference(IASTDeclarator decl) {
IASTInitializer initializer = decl.getInitializer();
if (initializer instanceof IASTEqualsInitializer) {
IASTInitializerClause clause = ((IASTEqualsInitializer) initializer).getInitializerClause();
if (clause instanceof IASTImplicitNameOwner) {
IASTImplicitName[] implicitNames = ((IASTImplicitNameOwner) clause).getImplicitNames();
if (implicitNames.length != 0) {
IASTImplicitName name = implicitNames[0];
IBinding binding = name.resolveBinding();
if (binding instanceof ICPPConstructor) {
ICPPClassType classType = ((ICPPConstructor) binding).getClassOwner();
ICPPMethod destructor = findDestructor(classType, name);
if (destructor != null) {
addDestructorCall(name, destructor);
}
}
}
}
}
}
}
}