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 2049fc6a01d..09d327becd9 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 @@ -8762,4 +8762,16 @@ public class AST2TemplateTests extends AST2TestBase { public void testClassSpecializationInEnumerator_457511() throws Exception { parseAndCheckBindings(); } + + // template struct TypeTemplate {}; + // template struct Size_tTemplate {}; + // + // template struct Test { + // static constexpr int packSize() { return sizeof...(ParameterPack); } + // + // using type = TypeTemplate>; + // }; + public void testAmbiguityResolutionOrder_462348() throws Exception { + parseAndCheckBindings(); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTNode.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTNode.java index c1a5ad2c70c..a00915cd414 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTNode.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTNode.java @@ -394,4 +394,12 @@ public abstract class ASTNode implements IASTNode { } return node; } + + /** + * If ambiguity resolution is in progress, and procesing of this node has been deferred, + * process it now. Has no effect if ambiguity resolution is not in progress. + */ + public void resolvePendingAmbiguities() { + ((ASTTranslationUnit) getTranslationUnit()).resolvePendingAmbiguities(this); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTTranslationUnit.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTTranslationUnit.java index 11860d8dbb3..b865ef690e2 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTTranslationUnit.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTTranslationUnit.java @@ -522,4 +522,10 @@ public abstract class ASTTranslationUnit extends ASTNode implements IASTTranslat assertNotFrozen(); fNodesOmitted = hasNodesOmitted; } + + /** + * If ambiguity resolution is in progress, and processing of 'node' has been deferred, + * process it now. Has no effect if ambiguity resolution is not in progress. + */ + public void resolvePendingAmbiguities(IASTNode node) {} } 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 4f794e4c74a..de6041762a2 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 @@ -218,4 +218,26 @@ final class CPPASTAmbiguityResolver extends ASTVisitor { CPPSemantics.populateCache((ICPPASTInternalScope) scope, declaration); } } + + /** + * If 'node' has been deferred for later processing, process it now. + */ + public void resolvePendingAmbiguities(IASTNode node) { + if (!fDeferredNodes.isEmpty()) { + Deque deferred = fDeferredNodes.getLast(); + for (IASTNode deferredNode : deferred) { + if (deferredNode == node) { + int deferFunctions = fDeferFunctions; + fDeferFunctions = 0; + try { + deferredNode.accept(this); + } finally { + fDeferFunctions = deferFunctions; + } + deferred.remove(deferredNode); + break; + } + } + } + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTranslationUnit.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTranslationUnit.java index 05b442da82b..720a9db4148 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTranslationUnit.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTranslationUnit.java @@ -44,6 +44,7 @@ public class CPPASTTranslationUnit extends ASTTranslationUnit implements ICPPAST private CPPNamespaceScope fScope; private ICPPNamespace fBinding; private final CPPScopeMapper fScopeMapper= new CPPScopeMapper(this); + private CPPASTAmbiguityResolver fAmbiguityResolver; public CPPASTTranslationUnit() { } @@ -190,11 +191,20 @@ public class CPPASTTranslationUnit extends ASTTranslationUnit implements ICPPAST @Override public void resolveAmbiguities() { - accept(new CPPASTAmbiguityResolver()); + fAmbiguityResolver = new CPPASTAmbiguityResolver(); + accept(fAmbiguityResolver); + fAmbiguityResolver = null; } @Override protected IType createType(IASTTypeId typeid) { return CPPVisitor.createType(typeid); } + + @Override + public void resolvePendingAmbiguities(IASTNode node) { + if (fAmbiguityResolver != null) { + fAmbiguityResolver.resolvePendingAmbiguities(node); + } + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunction.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunction.java index 0ad6f654d7d..3319836ad37 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunction.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunction.java @@ -680,6 +680,9 @@ public class CPPFunction extends PlatformObject implements ICPPFunction, ICPPInt static ICPPEvaluation getReturnExpression(IASTFunctionDefinition functionDefinition) { IASTReturnStatement returnStatement = null; + // Make sure ambiguity resolution has been performed on the function body, even + // if it's a class method and we're still processing the class declaration. + ((ASTNode) functionDefinition).resolvePendingAmbiguities(); IASTStatement body = functionDefinition.getBody(); if (body instanceof IASTReturnStatement) { returnStatement = (IASTReturnStatement) body;