1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-09 10:46:02 +02:00

Revert "Bug 485388 - Ambiguity resolution of method bodies of nested classes"

This reverts commit 3d814869df.

Change-Id: Ia9ee55575d7bd7f8fe4a6b67dbc0d7659cedcfe8
This commit is contained in:
Sergey Prigogin 2016-01-14 19:26:16 -05:00 committed by Gerrit Code Review @ Eclipse.org
parent 952c64a0bc
commit 751b2e3e1d
2 changed files with 46 additions and 56 deletions

View file

@ -8955,23 +8955,6 @@ public class AST2TemplateTests extends AST2TestBase {
parseAndCheckBindings(); parseAndCheckBindings();
} }
// template <typename> struct S {};
// struct U {};
//
// struct outer {
// struct inner {
// S<U> foo() {
// return waldo<42>(0);
// }
// };
//
// template <int>
// static S<U> waldo(int);
// };
public void testAmbiguityResolutionInNestedClassMethodBody_485388() throws Exception {
parseAndCheckBindings();
}
// template <typename> // template <typename>
// struct Base { // struct Base {
// template <typename> // template <typename>

View file

@ -14,6 +14,7 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp;
import java.util.ArrayDeque; import java.util.ArrayDeque;
import java.util.Deque; import java.util.Deque;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator;
import org.eclipse.cdt.core.dom.ast.ASTNodeProperty; import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
import org.eclipse.cdt.core.dom.ast.ASTVisitor; 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 { final class CPPASTAmbiguityResolver extends ASTVisitor {
private int fSkipInitializers= 0; private int fSkipInitializers= 0;
/* private int fDeferFunctions= 1;
* 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 HashSet<IASTDeclaration> fRepopulate= new HashSet<>(); private HashSet<IASTDeclaration> fRepopulate= new HashSet<>();
/* private Deque<Deque<IASTNode>> fDeferredNodes= new ArrayDeque<>();
* Nodes that have been deferred for later processing.
* Currently used only for method bodies.
*/
private Deque<IASTNode> fDeferredNodes = new ArrayDeque<>();
public CPPASTAmbiguityResolver() { public CPPASTAmbiguityResolver() {
super(false); super(false);
@ -106,7 +98,8 @@ final class CPPASTAmbiguityResolver extends ASTVisitor {
@Override @Override
public int visit(IASTDeclSpecifier declSpec) { public int visit(IASTDeclSpecifier declSpec) {
if (declSpec instanceof ICPPASTCompositeTypeSpecifier) { if (declSpec instanceof ICPPASTCompositeTypeSpecifier) {
fClassNestingLevel++; fDeferFunctions++;
fDeferredNodes.add(new ArrayDeque<IASTNode>());
} }
return PROCESS_CONTINUE; return PROCESS_CONTINUE;
} }
@ -114,7 +107,7 @@ final class CPPASTAmbiguityResolver extends ASTVisitor {
@Override @Override
public int leave(IASTDeclSpecifier declSpec) { public int leave(IASTDeclSpecifier declSpec) {
if (declSpec instanceof ICPPASTCompositeTypeSpecifier) { if (declSpec instanceof ICPPASTCompositeTypeSpecifier) {
fClassNestingLevel--; fDeferFunctions--;
// Resolve class type definitions, such that the scope is available // Resolve class type definitions, such that the scope is available
// during ambiguity resolution. // during ambiguity resolution.
@ -124,20 +117,14 @@ final class CPPASTAmbiguityResolver extends ASTVisitor {
if (declSpec instanceof CPPASTCompositeTypeSpecifier) if (declSpec instanceof CPPASTCompositeTypeSpecifier)
((CPPASTCompositeTypeSpecifier) declSpec).setAmbiguitiesResolved(); ((CPPASTCompositeTypeSpecifier) declSpec).setAmbiguitiesResolved();
// If we are leaving the outermost class, process the bodies of processDeferredNodes(fDeferredNodes.removeLast());
// methods of the class and its nested classes.
if (fClassNestingLevel == 0) {
while (!fDeferredNodes.isEmpty()) {
fDeferredNodes.removeFirst().accept(this);
}
}
} }
return PROCESS_CONTINUE; return PROCESS_CONTINUE;
} }
@Override @Override
public int visit(IASTDeclaration decl) { public int visit(IASTDeclaration decl) {
if (fClassNestingLevel > 0 && decl instanceof IASTFunctionDefinition) { if (fDeferFunctions > 0 && decl instanceof IASTFunctionDefinition) {
final IASTFunctionDefinition fdef= (IASTFunctionDefinition) decl; final IASTFunctionDefinition fdef= (IASTFunctionDefinition) decl;
// Visit the declarator first, it may contain ambiguous template arguments needed // Visit the declarator first, it may contain ambiguous template arguments needed
@ -153,7 +140,7 @@ final class CPPASTAmbiguityResolver extends ASTVisitor {
trailingReturnType.accept(this); trailingReturnType.accept(this);
} }
// Defer visiting the body of the function until the class body has been visited. // 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_SKIP;
} }
return PROCESS_CONTINUE; return PROCESS_CONTINUE;
@ -201,14 +188,32 @@ final class CPPASTAmbiguityResolver extends ASTVisitor {
} }
@Override @Override
public int leave(IASTTranslationUnit tu) { public int visit(IASTTranslationUnit tu) {
// As deferred method bodies are processed at the end of outermost fDeferredNodes.add(new ArrayDeque<IASTNode>());
// class definitions, there should be none left when the end of
// the translation unit is reached.
assert fDeferredNodes.isEmpty();
return PROCESS_CONTINUE; return PROCESS_CONTINUE;
} }
@Override
public int leave(IASTTranslationUnit tu) {
fDeferFunctions= 0;
while (!fDeferredNodes.isEmpty()) {
processDeferredNodes(fDeferredNodes.removeLast());
}
return PROCESS_CONTINUE;
}
private void processDeferredNodes(Deque<IASTNode> deferredNodes) {
int deferFunctions = fDeferFunctions;
fDeferFunctions = 0;
try {
while (!deferredNodes.isEmpty()) {
deferredNodes.removeFirst().accept(this);
}
} finally {
fDeferFunctions = deferFunctions;
}
}
private void repopulateScope(IASTDeclaration declaration) { private void repopulateScope(IASTDeclaration declaration) {
IScope scope= CPPVisitor.getContainingNonTemplateScope(declaration); IScope scope= CPPVisitor.getContainingNonTemplateScope(declaration);
if (scope instanceof ICPPASTInternalScope) { if (scope instanceof ICPPASTInternalScope) {
@ -227,20 +232,22 @@ final class CPPASTAmbiguityResolver extends ASTVisitor {
* If 'node' has been deferred for later processing, process it now. * If 'node' has been deferred for later processing, process it now.
*/ */
public void resolvePendingAmbiguities(IASTNode node) { public void resolvePendingAmbiguities(IASTNode node) {
for (IASTNode deferredNode : fDeferredNodes) { Iterator<Deque<IASTNode>> iterator = fDeferredNodes.descendingIterator();
while (iterator.hasNext()) {
Deque<IASTNode> deferred = iterator.next();
for (IASTNode deferredNode : deferred) {
if (deferredNode == node) { if (deferredNode == node) {
// Temporarily set the class nesting level to 0, int deferFunctions = fDeferFunctions;
// to prevent the node just being deferred again. fDeferFunctions = 0;
int classNestingLevel = fClassNestingLevel;
fClassNestingLevel = 0;
try { try {
deferredNode.accept(this); deferredNode.accept(this);
} finally { } finally {
fClassNestingLevel = classNestingLevel; fDeferFunctions = deferFunctions;
} }
fDeferredNodes.remove(deferredNode); deferred.remove(deferredNode);
break; break;
} }
} }
} }
}
} }