diff --git a/codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/CxxAstUtils.java b/codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/CxxAstUtils.java index 443b5c3cd93..ff9f1096118 100644 --- a/codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/CxxAstUtils.java +++ b/codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/CxxAstUtils.java @@ -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; } } diff --git a/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/internal/checkers/ReturnCheckerTest.java b/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/internal/checkers/ReturnCheckerTest.java index eb495ea1762..cfe7cc23f09 100644 --- a/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/internal/checkers/ReturnCheckerTest.java +++ b/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/internal/checkers/ReturnCheckerTest.java @@ -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; diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ASTComparer.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ASTComparer.java index 50bb5310f43..2525bebad08 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ASTComparer.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ASTComparer.java @@ -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 methodsToIgnore = new HashSet(Arrays.asList( + private static Set 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 diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPImplicitNameTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPImplicitNameTests.java index 63f2aba83b6..053682f6617 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPImplicitNameTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPImplicitNameTests.java @@ -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()); + } } diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TestBase.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TestBase.java index 02dd5edf204..080384e04d4 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TestBase.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TestBase.java @@ -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); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTVisitor.java index eb7fa4d180d..205e6827e65 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTVisitor.java @@ -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. */ diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTImplicitDestructorName.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTImplicitDestructorName.java new file mode 100644 index 00000000000..e3170b71a08 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTImplicitDestructorName.java @@ -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(); +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTImplicitDestructorNameOwner.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTImplicitDestructorNameOwner.java new file mode 100644 index 00000000000..44c5efacc6d --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTImplicitDestructorNameOwner.java @@ -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(); +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTCatchHandler.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTCatchHandler.java index ffa0dfb24da..c3583cbc381 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTCatchHandler.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTCatchHandler.java @@ -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 = {}; /** diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTCompoundStatement.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTCompoundStatement.java new file mode 100644 index 00000000000..b2539e611f2 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTCompoundStatement.java @@ -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 { +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTExpression.java index 7069813a96b..5514f170530 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTExpression.java @@ -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 { } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTForStatement.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTForStatement.java index 1b81285abbc..a6d4168ea7c 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTForStatement.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTForStatement.java @@ -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$ diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTRangeBasedForStatement.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTRangeBasedForStatement.java index d5b85eb9663..aefdec29952 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTRangeBasedForStatement.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTRangeBasedForStatement.java @@ -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( diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTAmbiguousBinaryVsCastExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTAmbiguousBinaryVsCastExpression.java index a7967717781..455e80c260a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTAmbiguousBinaryVsCastExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTAmbiguousBinaryVsCastExpression.java @@ -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(); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTAmbiguousCastVsFunctionCallExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTAmbiguousCastVsFunctionCallExpression.java index c9254d33de8..30f49cc8d0a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTAmbiguousCastVsFunctionCallExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTAmbiguousCastVsFunctionCallExpression.java @@ -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(); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTAmbiguousExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTAmbiguousExpression.java index 7f9c96c3869..5039e96c23b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTAmbiguousExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTAmbiguousExpression.java @@ -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(); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTArraySubscriptExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTArraySubscriptExpression.java index 63daca65bbf..879a2b0351c 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTArraySubscriptExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTArraySubscriptExpression.java @@ -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; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTBinaryExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTBinaryExpression.java index bb226a7ce1f..36415f58b09 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTBinaryExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTBinaryExpression.java @@ -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; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTBinaryTypeIdExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTBinaryTypeIdExpression.java index 1f2a8c02fd1..d7dbcdc2956 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTBinaryTypeIdExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTBinaryTypeIdExpression.java @@ -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. + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTCastExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTCastExpression.java index a2ca0254cc3..8d3b4bc7dc9 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTCastExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTCastExpression.java @@ -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; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTCatchHandler.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTCatchHandler.java index 92d20c5cbb0..c472a6ab164 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTCatchHandler.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTCatchHandler.java @@ -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; } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTCompoundStatement.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTCompoundStatement.java index 6176191c3d8..a27438a1c6e 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTCompoundStatement.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTCompoundStatement.java @@ -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; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTCompoundStatementExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTCompoundStatementExpression.java index 21bb7c3cf64..2db30020bab 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTCompoundStatementExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTCompoundStatementExpression.java @@ -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; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTConditionalExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTConditionalExpression.java index 807357f373c..b97a1c66864 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTConditionalExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTConditionalExpression.java @@ -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; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTDeleteExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTDeleteExpression.java index d3b09a81467..c99d081058a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTDeleteExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTDeleteExpression.java @@ -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; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTExpressionList.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTExpressionList.java index 5f8c0d4f6d5..3c8042abf14 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTExpressionList.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTExpressionList.java @@ -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) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFieldReference.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFieldReference.java index d5a7bad479e..aca4eab1b79 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFieldReference.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFieldReference.java @@ -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; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTForStatement.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTForStatement.java index 97157aff9ca..22b7dbe2ccb 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTForStatement.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTForStatement.java @@ -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; } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFunctionCallExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFunctionCallExpression.java index 98e2961d8ab..e595be4e4e0 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFunctionCallExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFunctionCallExpression.java @@ -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; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTIdExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTIdExpression.java index b9550206f0b..8e61300bc37 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTIdExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTIdExpression.java @@ -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; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTImplicitDestructorName.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTImplicitDestructorName.java new file mode 100644 index 00000000000..1488f4c707b --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTImplicitDestructorName.java @@ -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; + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTLambdaExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTLambdaExpression.java index 6e4f427ef7e..ccb71dc02d0 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTLambdaExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTLambdaExpression.java @@ -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) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTLiteralExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTLiteralExpression.java index 0d4ee4f8660..2a7f4317047 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTLiteralExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTLiteralExpression.java @@ -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) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTNewExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTNewExpression.java index 1e4e313387d..cf3c547e218 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTNewExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTNewExpression.java @@ -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; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTPackExpansionExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTPackExpansionExpression.java index 8341fed79e9..7424b41b97a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTPackExpansionExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTPackExpansionExpression.java @@ -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) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTProblemExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTProblemExpression.java index e9d02fef7c3..ec34ddbeca2 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTProblemExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTProblemExpression.java @@ -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) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTRangeBasedForStatement.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTRangeBasedForStatement.java index 4285849d705..bb55e2756c6 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTRangeBasedForStatement.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTRangeBasedForStatement.java @@ -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; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTSimpleTypeConstructorExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTSimpleTypeConstructorExpression.java index 0342ce79f08..c7ef0dcae70 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTSimpleTypeConstructorExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTSimpleTypeConstructorExpression.java @@ -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; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTemplateIDAmbiguity.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTemplateIDAmbiguity.java index 973c419f862..6b5931de81b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTemplateIDAmbiguity.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTemplateIDAmbiguity.java @@ -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(); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTypeIdExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTypeIdExpression.java index c2ed57e46e1..c73a0a11ec8 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTypeIdExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTypeIdExpression.java @@ -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) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTypeIdInitializerExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTypeIdInitializerExpression.java index e7869955a1d..ae9c012e465 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTypeIdInitializerExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTypeIdInitializerExpression.java @@ -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; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTUnaryExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTUnaryExpression.java index e83dc9635f8..605aed4dedd 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTUnaryExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTUnaryExpression.java @@ -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; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/DestructorCallCollector.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/DestructorCallCollector.java new file mode 100644 index 00000000000..53f0e6b196a --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/DestructorCallCollector.java @@ -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); + } + } + } + } + } + } + } +}