mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-09 02:36:01 +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:
parent
952c64a0bc
commit
751b2e3e1d
2 changed files with 46 additions and 56 deletions
|
@ -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>
|
||||||
|
|
|
@ -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,19 +232,21 @@ 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();
|
||||||
if (deferredNode == node) {
|
while (iterator.hasNext()) {
|
||||||
// Temporarily set the class nesting level to 0,
|
Deque<IASTNode> deferred = iterator.next();
|
||||||
// to prevent the node just being deferred again.
|
for (IASTNode deferredNode : deferred) {
|
||||||
int classNestingLevel = fClassNestingLevel;
|
if (deferredNode == node) {
|
||||||
fClassNestingLevel = 0;
|
int deferFunctions = fDeferFunctions;
|
||||||
try {
|
fDeferFunctions = 0;
|
||||||
deferredNode.accept(this);
|
try {
|
||||||
} finally {
|
deferredNode.accept(this);
|
||||||
fClassNestingLevel = classNestingLevel;
|
} finally {
|
||||||
|
fDeferFunctions = deferFunctions;
|
||||||
|
}
|
||||||
|
deferred.remove(deferredNode);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
fDeferredNodes.remove(deferredNode);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue