From 751b2e3e1d058dac0a69ce3e31f9e25f36a75df6 Mon Sep 17 00:00:00 2001 From: Sergey Prigogin Date: Thu, 14 Jan 2016 19:26:16 -0500 Subject: [PATCH] Revert "Bug 485388 - Ambiguity resolution of method bodies of nested classes" This reverts commit 3d814869df99977c7664e648a3ea5ca859b29b16. Change-Id: Ia9ee55575d7bd7f8fe4a6b67dbc0d7659cedcfe8 --- .../parser/tests/ast2/AST2TemplateTests.java | 17 ---- .../parser/cpp/CPPASTAmbiguityResolver.java | 85 ++++++++++--------- 2 files changed, 46 insertions(+), 56 deletions(-) diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java index 7e084fe3f48..ca38084592a 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java @@ -8955,23 +8955,6 @@ public class AST2TemplateTests extends AST2TestBase { parseAndCheckBindings(); } - // template struct S {}; - // struct U {}; - // - // struct outer { - // struct inner { - // S foo() { - // return waldo<42>(0); - // } - // }; - // - // template - // static S waldo(int); - // }; - public void testAmbiguityResolutionInNestedClassMethodBody_485388() throws Exception { - parseAndCheckBindings(); - } - // template // struct Base { // template diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTAmbiguityResolver.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTAmbiguityResolver.java index 3177d21a511..8052ab07d03 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTAmbiguityResolver.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTAmbiguityResolver.java @@ -14,6 +14,7 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp; import java.util.ArrayDeque; import java.util.Deque; import java.util.HashSet; +import java.util.Iterator; import org.eclipse.cdt.core.dom.ast.ASTNodeProperty; import org.eclipse.cdt.core.dom.ast.ASTVisitor; @@ -47,18 +48,9 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; */ final class CPPASTAmbiguityResolver extends ASTVisitor { private int fSkipInitializers= 0; - /* - * The current nesting level of class definitions. - * Used to handle processing of method bodies, which are deferred - * until the end of the outermost class definition. - */ - private int fClassNestingLevel= 0; + private int fDeferFunctions= 1; private HashSet fRepopulate= new HashSet<>(); - /* - * Nodes that have been deferred for later processing. - * Currently used only for method bodies. - */ - private Deque fDeferredNodes = new ArrayDeque<>(); + private Deque> fDeferredNodes= new ArrayDeque<>(); public CPPASTAmbiguityResolver() { super(false); @@ -106,7 +98,8 @@ final class CPPASTAmbiguityResolver extends ASTVisitor { @Override public int visit(IASTDeclSpecifier declSpec) { if (declSpec instanceof ICPPASTCompositeTypeSpecifier) { - fClassNestingLevel++; + fDeferFunctions++; + fDeferredNodes.add(new ArrayDeque()); } return PROCESS_CONTINUE; } @@ -114,7 +107,7 @@ final class CPPASTAmbiguityResolver extends ASTVisitor { @Override public int leave(IASTDeclSpecifier declSpec) { if (declSpec instanceof ICPPASTCompositeTypeSpecifier) { - fClassNestingLevel--; + fDeferFunctions--; // Resolve class type definitions, such that the scope is available // during ambiguity resolution. @@ -124,20 +117,14 @@ final class CPPASTAmbiguityResolver extends ASTVisitor { if (declSpec instanceof CPPASTCompositeTypeSpecifier) ((CPPASTCompositeTypeSpecifier) declSpec).setAmbiguitiesResolved(); - // If we are leaving the outermost class, process the bodies of - // methods of the class and its nested classes. - if (fClassNestingLevel == 0) { - while (!fDeferredNodes.isEmpty()) { - fDeferredNodes.removeFirst().accept(this); - } - } + processDeferredNodes(fDeferredNodes.removeLast()); } return PROCESS_CONTINUE; } @Override public int visit(IASTDeclaration decl) { - if (fClassNestingLevel > 0 && decl instanceof IASTFunctionDefinition) { + if (fDeferFunctions > 0 && decl instanceof IASTFunctionDefinition) { final IASTFunctionDefinition fdef= (IASTFunctionDefinition) decl; // Visit the declarator first, it may contain ambiguous template arguments needed @@ -153,7 +140,7 @@ final class CPPASTAmbiguityResolver extends ASTVisitor { trailingReturnType.accept(this); } // Defer visiting the body of the function until the class body has been visited. - fDeferredNodes.add(decl); + fDeferredNodes.getLast().add(decl); return PROCESS_SKIP; } return PROCESS_CONTINUE; @@ -201,14 +188,32 @@ final class CPPASTAmbiguityResolver extends ASTVisitor { } @Override - public int leave(IASTTranslationUnit tu) { - // As deferred method bodies are processed at the end of outermost - // class definitions, there should be none left when the end of - // the translation unit is reached. - assert fDeferredNodes.isEmpty(); + public int visit(IASTTranslationUnit tu) { + fDeferredNodes.add(new ArrayDeque()); return PROCESS_CONTINUE; } + @Override + public int leave(IASTTranslationUnit tu) { + fDeferFunctions= 0; + while (!fDeferredNodes.isEmpty()) { + processDeferredNodes(fDeferredNodes.removeLast()); + } + return PROCESS_CONTINUE; + } + + private void processDeferredNodes(Deque deferredNodes) { + int deferFunctions = fDeferFunctions; + fDeferFunctions = 0; + try { + while (!deferredNodes.isEmpty()) { + deferredNodes.removeFirst().accept(this); + } + } finally { + fDeferFunctions = deferFunctions; + } + } + private void repopulateScope(IASTDeclaration declaration) { IScope scope= CPPVisitor.getContainingNonTemplateScope(declaration); if (scope instanceof ICPPASTInternalScope) { @@ -227,19 +232,21 @@ final class CPPASTAmbiguityResolver extends ASTVisitor { * If 'node' has been deferred for later processing, process it now. */ public void resolvePendingAmbiguities(IASTNode node) { - for (IASTNode deferredNode : fDeferredNodes) { - if (deferredNode == node) { - // Temporarily set the class nesting level to 0, - // to prevent the node just being deferred again. - int classNestingLevel = fClassNestingLevel; - fClassNestingLevel = 0; - try { - deferredNode.accept(this); - } finally { - fClassNestingLevel = classNestingLevel; + Iterator> iterator = fDeferredNodes.descendingIterator(); + while (iterator.hasNext()) { + Deque deferred = iterator.next(); + for (IASTNode deferredNode : deferred) { + if (deferredNode == node) { + int deferFunctions = fDeferFunctions; + fDeferFunctions = 0; + try { + deferredNode.accept(this); + } finally { + fDeferFunctions = deferFunctions; + } + deferred.remove(deferredNode); + break; } - fDeferredNodes.remove(deferredNode); - break; } } }