diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java index 13b75d8e90e..470b5fc1bab 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java @@ -9602,6 +9602,26 @@ public class AST2CPPTests extends AST2TestBase { parseAndCheckBindings(); } + // template + // struct A { + // typedef char c; + // static constexpr int method() { + // return sizeof(c); + // } + // + // static const int x = method(); + // }; + // + // template::x> + // struct B; + // + // template<> + // struct B { + // }; + public void testAmbiguityResolution_427854() throws Exception { + parseAndCheckBindings(); + } + // template struct C { // C(const C& c) {} // }; 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 ed0729a032b..f1e645b515f 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 @@ -7,10 +7,12 @@ * * Contributors: * Markus Schorn - initial API and implementation + * Sergey Prigogin (Google) *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; import java.util.ArrayDeque; +import java.util.Deque; import java.util.HashSet; import org.eclipse.cdt.core.dom.ast.ASTNodeProperty; @@ -45,7 +47,7 @@ final class CPPASTAmbiguityResolver extends ASTVisitor { private int fSkipInitializers= 0; private int fDeferFunctions= 1; private HashSet fRepopulate= new HashSet<>(); - private ArrayDeque fDeferredNodes= new ArrayDeque<>(); + private Deque> fDeferredNodes= new ArrayDeque<>(); public CPPASTAmbiguityResolver() { super(false); @@ -94,6 +96,7 @@ final class CPPASTAmbiguityResolver extends ASTVisitor { public int visit(IASTDeclSpecifier declSpec) { if (declSpec instanceof ICPPASTCompositeTypeSpecifier) { fDeferFunctions++; + fDeferredNodes.add(new ArrayDeque()); } return PROCESS_CONTINUE; } @@ -110,6 +113,8 @@ final class CPPASTAmbiguityResolver extends ASTVisitor { // Trigger computation of implicit members. if (declSpec instanceof CPPASTCompositeTypeSpecifier) ((CPPASTCompositeTypeSpecifier) declSpec).setAmbiguitiesResolved(); + + processDeferredNodes(fDeferredNodes.removeLast()); } return PROCESS_CONTINUE; } @@ -126,7 +131,7 @@ final class CPPASTAmbiguityResolver extends ASTVisitor { fSkipInitializers--; fdef.getDeclSpecifier().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; @@ -173,15 +178,27 @@ final class CPPASTAmbiguityResolver extends ASTVisitor { return PROCESS_CONTINUE; } + @Override + public int visit(IASTTranslationUnit tu) { + fDeferredNodes.add(new ArrayDeque()); + return PROCESS_CONTINUE; + } + @Override public int leave(IASTTranslationUnit tu) { while (!fDeferredNodes.isEmpty()) { - fDeferFunctions= 0; - fDeferredNodes.removeFirst().accept(this); + processDeferredNodes(fDeferredNodes.removeLast()); } return PROCESS_CONTINUE; } + private void processDeferredNodes(Deque deferredNodes) { + while (!deferredNodes.isEmpty()) { + fDeferFunctions= 0; + deferredNodes.removeFirst().accept(this); + } + } + private void repopulateScope(IASTDeclaration declaration) { IScope scope= CPPVisitor.getContainingNonTemplateScope(declaration); if (scope instanceof ICPPASTInternalScope) {