1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-24 09:25:31 +02:00

Cleaning up bindings after resolving ambiguities, bug 232811.

This commit is contained in:
Markus Schorn 2008-05-20 13:06:23 +00:00
parent 4177ecd4aa
commit da0b0d3b57
12 changed files with 309 additions and 319 deletions

View file

@ -0,0 +1,129 @@
/*******************************************************************************
* Copyright (c) 2004, 2008 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM - Initial API and implementation
* Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IProblemBinding;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
/**
* Base implementation for all ambiguous nodes.
*/
public abstract class ASTAmbiguousNode extends ASTNode {
public static class NameCollector extends ASTVisitor {
private IASTName[] names = new IASTName[2];
private int namesPos = -1;
public NameCollector() {
shouldVisitNames = true;
}
@Override
public int visit(IASTName name) {
if (name != null) {
namesPos++;
names = (IASTName[]) ArrayUtil.append(IASTName.class, names, name);
}
return PROCESS_CONTINUE;
}
public IASTName[] getNames() {
names = (IASTName[]) ArrayUtil.removeNullsAfter(IASTName.class, names, namesPos);
return names;
}
}
/**
* Return the alternative nodes for this ambiguity.
*/
protected abstract IASTNode [] getNodes();
/**
* Returns the scope that may get polluted by alternatives of this ambiguity.
*/
protected abstract IScope getAffectedScope();
@Override
public boolean accept(ASTVisitor visitor) {
final IScope scope= getAffectedScope();
final IASTAmbiguityParent owner= (IASTAmbiguityParent) getParent();
IASTNode nodeToReplace= this;
final IASTNode[] alternatives= getNodes();
IASTNode bestAlternative= null;
int minIssues = Integer.MAX_VALUE;
for (IASTNode alternative : alternatives) {
// flush scope, if this is not the first alternative
if (nodeToReplace != this && scope instanceof IASTInternalScope) {
try {
((IASTInternalScope) scope).flushCache();
} catch (DOMException e) {
}
}
// setup the ast to use the alternative
owner.replace(nodeToReplace, alternative);
nodeToReplace= alternative;
// handle nested ambiguities first, otherwise we cannot visit the alternative
alternative.accept(visitor);
// find nested names
final NameCollector nameCollector= new NameCollector();
alternative.accept(nameCollector);
final IASTName[] names= nameCollector.getNames();
// resolve names and count issues
int issues= 0;
for (IASTName name : names) {
try {
IBinding b = name.resolveBinding();
if (b instanceof IProblemBinding) {
issues++;
}
} catch (Exception t) {
issues++;
}
if (issues == minIssues) {
break;
}
}
if (issues < minIssues) {
minIssues= issues;
bestAlternative= alternative;
if (issues == 0) {
break;
}
}
}
// switch back to the best alternative, if necessary.
if (nodeToReplace != bestAlternative) {
if (scope instanceof IASTInternalScope) {
try {
((IASTInternalScope) scope).flushCache();
} catch (DOMException e) {
}
}
owner.replace(nodeToReplace, bestAlternative);
}
return true;
}
}

View file

@ -333,4 +333,19 @@ public abstract class ASTTranslationUnit extends ASTNode implements IASTTranslat
public final IASTNodeSelector getNodeSelector(String filePath) {
return new ASTNodeSelector(this, fLocationResolver, filePath);
}
/**
* @since 5.0
*/
public void cleanupAfterAmbiguityResolution() {
// clear bindings (see bug 232811)
accept(new ASTVisitor(){
{shouldVisitNames= true;}
@Override
public int visit(IASTName name) {
name.setBinding(null);
return PROCESS_CONTINUE;
}
});
}
}

View file

@ -416,20 +416,20 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
}
protected void resolveAmbiguities() {
getTranslationUnit().accept(createVisitor());
final IASTTranslationUnit translationUnit = getTranslationUnit();
translationUnit.accept(createAmbiguityNodeVisitor());
if (translationUnit instanceof ASTTranslationUnit) {
((ASTTranslationUnit)translationUnit).cleanupAfterAmbiguityResolution();
}
}
protected abstract ASTVisitor createVisitor();
protected abstract ASTVisitor createAmbiguityNodeVisitor();
/**
*
*/
protected abstract void nullifyTranslationUnit();
protected IToken skipOverCompoundStatement() throws BacktrackException,
EndOfFileException {
// speed up the parser by skiping the body
// simply look for matching brace and return
// speed up the parser by skipping the body, simply look for matching brace and return
consume(IToken.tLBRACE);
IToken result = null;
int depth = 1;

View file

@ -11,110 +11,13 @@
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.c;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IProblemBinding;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.c.CASTVisitor;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
import org.eclipse.cdt.internal.core.dom.parser.IASTInternalScope;
import org.eclipse.cdt.internal.core.dom.parser.ASTAmbiguousNode;
public abstract class CASTAmbiguity extends CASTNode {
public abstract class CASTAmbiguity extends ASTAmbiguousNode {
protected static class CASTNameCollector extends CASTVisitor
{
private IASTName[] names = new IASTName[ 2 ];
private int namesPos=-1;
{
shouldVisitNames = true;
}
@Override
public int visit(IASTName name) {
if (name != null) {
namesPos++;
names = (IASTName[]) ArrayUtil.append( IASTName.class, names, name );
}
return PROCESS_CONTINUE;
}
public IASTName [] getNames()
{
names = (IASTName[]) ArrayUtil.removeNullsAfter( IASTName.class, names, namesPos );
return names;
}
}
protected abstract IASTNode [] getNodes();
@Override
public boolean accept(ASTVisitor visitor) {
IScope scope= CVisitor.getContainingScope(this);
IASTNode[] nodez = getNodes();
int bestIndex = 0;
int bestValue = Integer.MAX_VALUE;
for (int i = 0; i < nodez.length; ++i) {
final IASTNode s = nodez[i];
s.accept(visitor);
int issues= 0;
final CASTNameCollector resolver = new CASTNameCollector();
s.accept(resolver);
final IASTName[] names= resolver.getNames();
for (IASTName name : names) {
try {
IBinding b = name.resolveBinding();
if (b instanceof IProblemBinding) {
issues++;
}
} catch (Exception t) {
issues++;
}
if (issues == bestValue) {
break;
}
}
if (scope instanceof IASTInternalScope) {
final IASTInternalScope internalScope = (IASTInternalScope) scope;
try {
internalScope.flushCache();
} catch (DOMException e) {
}
}
if (issues < bestValue) {
bestValue= issues;
bestIndex= i;
if (issues == 0) {
break;
}
}
}
IASTAmbiguityParent owner = (IASTAmbiguityParent) getParent();
owner.replace(this, nodez[bestIndex]);
if (scope instanceof IASTInternalScope) {
try {
IASTNode node= ((IASTInternalScope) scope).getPhysicalNode();
if (node != null) {
CASTNameCollector nc = new CASTNameCollector();
node.accept(nc);
final IASTName[] names= nc.getNames();
for (IASTName name : names) {
name.setBinding(null);
}
}
} catch (DOMException e) {
}
}
return true;
}
protected IScope getAffectedScope() {
return CVisitor.getContainingScope(this);
}
}

View file

@ -13,12 +13,12 @@ package org.eclipse.cdt.internal.core.dom.parser.c;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguousExpression;
public class CASTAmbiguousExpression extends CASTAmbiguity implements
IASTAmbiguousExpression {
public class CASTAmbiguousExpression extends CASTAmbiguity implements IASTAmbiguousExpression {
private IASTExpression [] expressions = new IASTExpression[2];
private int expressionsPos=-1;
@ -29,6 +29,12 @@ public class CASTAmbiguousExpression extends CASTAmbiguity implements
addExpression(e);
}
@Override
protected IScope getAffectedScope() {
// an expression cannot pollute a parent scope
return null;
}
public void addExpression(IASTExpression e) {
if (e != null) {
expressions = (IASTExpression[]) ArrayUtil.append( IASTExpression.class, expressions, ++expressionsPos, e );

View file

@ -79,7 +79,6 @@ import org.eclipse.cdt.core.dom.ast.IASTWhileStatement;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator;
import org.eclipse.cdt.core.dom.ast.c.CASTVisitor;
import org.eclipse.cdt.core.dom.ast.c.ICASTArrayDesignator;
import org.eclipse.cdt.core.dom.ast.c.ICASTArrayModifier;
import org.eclipse.cdt.core.dom.ast.c.ICASTCompositeTypeSpecifier;
@ -119,13 +118,8 @@ import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguousStatement;
*/
public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
private static class EmptyVisitor extends CASTVisitor {
{
shouldVisitStatements = true;
}
}
private static final EmptyVisitor EMPTY_VISITOR = new EmptyVisitor();
private static final ASTVisitor EMPTY_VISITOR = new ASTVisitor() {
};
private final boolean supportGCCStyleDesignators;
@ -2275,7 +2269,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
}
@Override
protected ASTVisitor createVisitor() {
protected ASTVisitor createAmbiguityNodeVisitor() {
return EMPTY_VISITOR;
}

View file

@ -10,89 +10,15 @@
* Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
//no change for leave()
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IProblemBinding;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.cpp.CPPASTVisitor;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.dom.parser.ASTInternal;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
import org.eclipse.cdt.internal.core.dom.parser.ASTAmbiguousNode;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
public abstract class CPPASTAmbiguity extends CPPASTNode {
// private static final boolean debugging = false;
protected static class CPPASTNameCollector extends CPPASTVisitor {
private IASTName[] names = new IASTName[2];
private int namesPos=-1;
public CPPASTNameCollector() {
shouldVisitNames = true;
}
@Override
public int visit(IASTName name) {
if (name != null) {
namesPos++;
names = (IASTName[]) ArrayUtil.append(IASTName.class, names, name);
}
return PROCESS_CONTINUE;
}
public IASTName[] getNames() {
names = (IASTName[]) ArrayUtil.removeNullsAfter(IASTName.class, names, namesPos);
return names;
}
}
protected abstract IASTNode[] getNodes();
public abstract class CPPASTAmbiguity extends ASTAmbiguousNode {
@Override
public boolean accept(ASTVisitor visitor) {
IASTNode[] nodez = getNodes();
int[] problems = new int[nodez.length];
for(int i = 0; i < nodez.length; ++i) {
IASTNode node = nodez[i];
node.accept(visitor);
CPPASTNameCollector nameCollector = new CPPASTNameCollector();
node.accept(nameCollector);
IASTName[] names = nameCollector.getNames();
for(IASTName name : names) {
try {
IBinding b = name.resolveBinding();
if(b == null || b instanceof IProblemBinding)
++problems[i];
} catch (Exception t) {
++problems[i];
}
}
if(names.length > 0) {
IScope scope = CPPVisitor.getContainingScope(names[0]);
if( scope != null ) {
try {
ASTInternal.flushCache(scope);
} catch (DOMException de) {}
}
}
}
int bestIndex = 0;
int bestValue = problems[0];
for (int i = 1; i < problems.length; ++i) {
if (problems[i] < bestValue) {
bestIndex = i;
bestValue = problems[i];
}
}
IASTAmbiguityParent owner = (IASTAmbiguityParent) getParent();
owner.replace(this, nodez[bestIndex]);
return true;
protected IScope getAffectedScope() {
return CPPVisitor.getContainingScope(this);
}
}

View file

@ -12,6 +12,7 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguousExpression;
@ -23,6 +24,12 @@ public class CPPASTAmbiguousExpression extends CPPASTAmbiguity implements
private IASTExpression [] exp = new IASTExpression[2];
private int expPos=-1;
@Override
public IScope getAffectedScope() {
// an expression does not introduce names to a parent scope.
return null;
}
public CPPASTAmbiguousExpression(IASTExpression... expressions) {
for(IASTExpression e : expressions)
addExpression(e);

View file

@ -184,10 +184,6 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope {
if (bindings == null)
bindings = new CharArrayObjectMap(1);
if (constructor instanceof IASTName && ((IASTName)constructor).getBinding() != null) {
constructor = ((IASTName)constructor).getBinding();
}
Object o = bindings.get(CONSTRUCTOR_KEY);
if (o != null) {
if (o instanceof ObjectSet) {
@ -284,11 +280,8 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope {
if (obj instanceof IASTName) {
IASTName n = (IASTName) obj;
binding = shouldResolve(forceResolve, n, forName) ? n.resolveBinding() : n.getBinding();
if (binding != null) {
set.remove(n);
set.put(binding);
i--;
continue;
if (binding instanceof ICPPConstructor) {
bs = (IBinding[]) ArrayUtil.append(ICPPConstructor.class, bs, binding);
}
} else if (obj instanceof ICPPConstructor) {
bs = (IBinding[]) ArrayUtil.append(ICPPConstructor.class, bs, obj);
@ -297,8 +290,9 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope {
return (ICPPConstructor[]) ArrayUtil.trim(ICPPConstructor.class, bs);
} else if (o instanceof IASTName) {
if (shouldResolve(forceResolve, (IASTName) o, forName) || ((IASTName)o).getBinding() != null) {
// always store the name, rather than the binding, such that we can properly flush the scope.
bindings.put(CONSTRUCTOR_KEY, o);
binding = ((IASTName)o).resolveBinding();
bindings.put(CONSTRUCTOR_KEY, binding);
}
} else if (o instanceof IBinding) {
binding = (IBinding) o;
@ -450,16 +444,16 @@ class ImplicitsAnalysis {
char[] name = compSpec.getName().toCharArray();
IASTDeclarator dcltor = null;
IASTDeclSpecifier spec = null;
for (int i = 0; i < members.length; i++) {
if (members[i] instanceof IASTSimpleDeclaration) {
IASTDeclarator[] dtors = ((IASTSimpleDeclaration)members[i]).getDeclarators();
for (IASTDeclaration member : members) {
if (member instanceof IASTSimpleDeclaration) {
IASTDeclarator[] dtors = ((IASTSimpleDeclaration)member).getDeclarators();
if (dtors.length == 0 || dtors.length > 1)
continue;
dcltor = dtors[0];
spec = ((IASTSimpleDeclaration)members[i]).getDeclSpecifier();
} else if (members[i] instanceof IASTFunctionDefinition) {
dcltor = ((IASTFunctionDefinition)members[i]).getDeclarator();
spec = ((IASTFunctionDefinition)members[i]).getDeclSpecifier();
spec = ((IASTSimpleDeclaration)member).getDeclSpecifier();
} else if (member instanceof IASTFunctionDefinition) {
dcltor = ((IASTFunctionDefinition)member).getDeclarator();
spec = ((IASTFunctionDefinition)member).getDeclSpecifier();
}
@ -490,14 +484,14 @@ class ImplicitsAnalysis {
List<ICPPASTFunctionDeclarator> result= new ArrayList<ICPPASTFunctionDeclarator>();
IASTDeclaration[] members = compSpec.getMembers();
IASTDeclarator dcltor = null;
for (int i = 0; i < members.length; i++) {
if (members[i] instanceof IASTSimpleDeclaration) {
IASTDeclarator[] dtors = ((IASTSimpleDeclaration)members[i]).getDeclarators();
for (IASTDeclaration member : members) {
if (member instanceof IASTSimpleDeclaration) {
IASTDeclarator[] dtors = ((IASTSimpleDeclaration)member).getDeclarators();
if (dtors.length == 0 || dtors.length > 1)
continue;
dcltor = dtors[0];
} else if (members[i] instanceof IASTFunctionDefinition) {
dcltor = ((IASTFunctionDefinition)members[i]).getDeclarator();
} else if (member instanceof IASTFunctionDefinition) {
dcltor = ((IASTFunctionDefinition)member).getDeclarator();
}
if (!(dcltor instanceof ICPPASTFunctionDeclarator) ||
!CharArrayUtils.equals(dcltor.getName().toCharArray(), OverloadableOperator.ASSIGN.toCharArray()))

View file

@ -11,9 +11,6 @@
* Bryan Wilkinson (QNX)
* Andrew Ferguson (Symbian)
*******************************************************************************/
/*
* Created on Nov 29, 2004
*/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.CCorePlugin;
@ -282,8 +279,8 @@ abstract public class CPPScope implements ICPPScope, IASTInternalScope {
Object[] obj = null;
if (prefixLookup) {
Object[] keys = bindings != null ? bindings.keyArray() : new Object[0];
for (int i = 0; i < keys.length; i++) {
char[] key = (char[]) keys[i];
for (Object key2 : keys) {
char[] key = (char[]) key2;
if (CharArrayUtils.equals(key, 0, c.length, c, true)) {
obj = ArrayUtil.append(obj, bindings.get(key));
}
@ -293,10 +290,10 @@ abstract public class CPPScope implements ICPPScope, IASTInternalScope {
}
obj = ArrayUtil.trim(Object.class, obj);
for (int i = 0; i < obj.length; i++) {
if (obj[i] instanceof ObjectSet) {
for (Object element : obj) {
if (element instanceof ObjectSet) {
@SuppressWarnings("unchecked")
ObjectSet<Object> os= (ObjectSet<Object>) obj[i];
ObjectSet<Object> os= (ObjectSet<Object>) element;
for (int j = 0; j < os.size(); j++) {
Object o = os.keyAt(j);
if (o instanceof IASTName) {
@ -311,12 +308,12 @@ abstract public class CPPScope implements ICPPScope, IASTInternalScope {
result = (IBinding[]) ArrayUtil.append(IBinding.class, result, o);
}
}
} else if (obj[i] instanceof IASTName) {
} else if (element instanceof IASTName) {
IBinding binding = null;
if (forceResolve && obj[i] != name && obj[i] != name.getParent()) {
binding = ((IASTName) obj[i]).resolveBinding();
if (forceResolve && element != name && element != name.getParent()) {
binding = ((IASTName) element).resolveBinding();
} else {
IASTName n = (IASTName) obj[i];
IASTName n = (IASTName) element;
if (n instanceof ICPPASTQualifiedName) {
IASTName[] ns = ((ICPPASTQualifiedName)n).getNames();
n = ns[ns.length - 1];
@ -329,7 +326,7 @@ abstract public class CPPScope implements ICPPScope, IASTInternalScope {
}
result = (IBinding[]) ArrayUtil.append(IBinding.class, result, binding);
} else {
result = (IBinding[]) ArrayUtil.append(IBinding.class, result, obj[i]);
result = (IBinding[]) ArrayUtil.append(IBinding.class, result, element);
}
}
return (IBinding[]) ArrayUtil.trim(IBinding.class, result);
@ -351,15 +348,15 @@ abstract public class CPPScope implements ICPPScope, IASTInternalScope {
removeBinding(key, binding);
}
@SuppressWarnings("unchecked")
protected void removeBinding(char[] key, IBinding binding) {
if (bindings == null || ! bindings.containsKey(key))
return;
Object obj = bindings.get(key);
if (obj instanceof ObjectSet) {
@SuppressWarnings("unchecked")
ObjectSet<Object> set = (ObjectSet<Object>) obj;
for (int i = set.size() - 1; i > 0; i--) {
for (int i = set.size() - 1; i >= 0; i--) {
Object o = set.keyAt(i);
if ((o instanceof IBinding && o == binding) ||
(o instanceof IASTName && ((IASTName)o).getBinding() == binding)) {
@ -384,9 +381,46 @@ abstract public class CPPScope implements ICPPScope, IASTInternalScope {
}
public void flushCache() {
final CharArrayObjectMap map= bindings;
if (map != null) {
CharArrayObjectMap allBuiltins= null;
for (int i = 0; i < map.size(); i++) {
Object o= map.getAt(i);
if (o instanceof IASTName) {
((IASTName) o).setBinding(null);
} else if (o instanceof IBinding) {
if (allBuiltins == null) {
allBuiltins= new CharArrayObjectMap(1);
}
allBuiltins.put(map.keyAt(i), o);
} else if (o instanceof ObjectSet) {
@SuppressWarnings("unchecked")
final ObjectSet<Object> set= (ObjectSet<Object>) map.getAt(i);
if (set != null) {
ObjectSet<Object> builtins= null;
for (int j= set.size()-1; j >= 0; j--) {
Object p= set.keyAt(j);
if (p instanceof IASTName) {
((IASTName) p).setBinding(null);
} else if (p instanceof IBinding) {
if (builtins == null) {
builtins= new ObjectSet<Object>(1);
}
builtins.put(p);
}
}
if (builtins != null) {
if (allBuiltins == null) {
allBuiltins= new CharArrayObjectMap(1);
}
allBuiltins.put(map.keyAt(i), builtins);
}
}
}
}
bindings= allBuiltins;
}
isfull = false;
if (bindings != null)
bindings.clear();
}
@SuppressWarnings("unchecked")

View file

@ -77,7 +77,6 @@ import org.eclipse.cdt.core.dom.ast.IASTWhileStatement;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator;
import org.eclipse.cdt.core.dom.ast.cpp.CPPASTVisitor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTBinaryExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCastExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCatchHandler;
@ -4620,16 +4619,11 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
return null;
}
private static class EmptyVisitor extends CPPASTVisitor {
{
shouldVisitStatements = true;
}
}
private static final EmptyVisitor EMPTY_VISITOR = new EmptyVisitor();
private static final ASTVisitor EMPTY_VISITOR = new ASTVisitor() {
};
@Override
protected ASTVisitor createVisitor() {
protected ASTVisitor createAmbiguityNodeVisitor() {
return EMPTY_VISITOR;
}

View file

@ -3,20 +3,12 @@ package org.eclipse.cdt.core.dom.lrparser.action.cpp;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTInitializer;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IProblemBinding;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.internal.core.dom.parser.ASTInternal;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTAmbiguity;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
@SuppressWarnings("restriction")
@ -37,68 +29,66 @@ public class CPPASTAmbiguousDeclarator extends CPPASTAmbiguity implements IASTDe
return declarators.toArray(new IASTDeclarator[declarators.size()]);
}
@Override
public boolean accept(ASTVisitor visitor) {
// this code was copied from CPPASTAmbiguity.accept() and slightly modified.
IASTNode nodeToReplace = this;
IASTAmbiguityParent owner = (IASTAmbiguityParent) getParent();
IASTNode[] nodez = getNodes();
int[] problems = new int[nodez.length];
for(int i = 0; i < nodez.length; ++i) {
defaultDeclarator = i;
IASTNode node = nodez[i];
owner.replace(nodeToReplace, node);
nodeToReplace = node;
node.accept(visitor);
CPPASTNameCollector nameCollector = new CPPASTNameCollector();
node.accept(nameCollector);
IASTName[] names = nameCollector.getNames();
for(IASTName name : names) {
if(name.toCharArray().length > 0) { // don't count dummy name nodes
try {
IBinding b = name.resolveBinding();
if(b == null || b instanceof IProblemBinding) {
++problems[i];
}
} catch (Exception t) {
t.printStackTrace();
++problems[i];
}
}
}
if(names.length > 0) {
IScope scope = CPPVisitor.getContainingScope(names[0]);
if( scope != null ) {
try {
IScope parentScope = scope;
do {
ASTInternal.flushCache(parentScope);
} while((parentScope = parentScope.getParent()) != null);
} catch (DOMException de) {}
}
}
}
int bestIndex = 0;
int bestValue = problems[0];
for (int i = 1; i < problems.length; ++i) {
if (problems[i] < bestValue) {
bestIndex = i;
bestValue = problems[i];
}
}
//IASTAmbiguityParent owner = (IASTAmbiguityParent) getParent();
owner.replace(nodeToReplace, nodez[bestIndex]);
defaultDeclarator = 0;
return true;
}
// @Override
// public boolean accept(ASTVisitor visitor) {
// // this code was copied from CPPASTAmbiguity.accept() and slightly modified.
// IASTNode nodeToReplace = this;
// IASTAmbiguityParent owner = (IASTAmbiguityParent) getParent();
//
// IASTNode[] nodez = getNodes();
// int[] problems = new int[nodez.length];
//
// for(int i = 0; i < nodez.length; ++i) {
// defaultDeclarator = i;
// IASTNode node = nodez[i];
// owner.replace(nodeToReplace, node);
// nodeToReplace = node;
//
// node.accept(visitor);
// NameCollector nameCollector = new NameCollector();
// node.accept(nameCollector);
// IASTName[] names = nameCollector.getNames();
// for(IASTName name : names) {
// if(name.toCharArray().length > 0) { // don't count dummy name nodes
// try {
// IBinding b = name.resolveBinding();
// if(b == null || b instanceof IProblemBinding) {
// ++problems[i];
// }
// } catch (Exception t) {
// t.printStackTrace();
// ++problems[i];
// }
// }
// }
// if(names.length > 0) {
// IScope scope = CPPVisitor.getContainingScope(names[0]);
//
// if( scope != null ) {
// try {
// IScope parentScope = scope;
// do {
// ASTInternal.flushCache(parentScope);
// } while((parentScope = parentScope.getParent()) != null);
// } catch (DOMException de) {}
// }
// }
// }
//
// int bestIndex = 0;
// int bestValue = problems[0];
// for (int i = 1; i < problems.length; ++i) {
// if (problems[i] < bestValue) {
// bestIndex = i;
// bestValue = problems[i];
// }
// }
//
// //IASTAmbiguityParent owner = (IASTAmbiguityParent) getParent();
// owner.replace(nodeToReplace, nodez[bestIndex]);
// defaultDeclarator = 0;
// return true;
// }
public void addDeclarator(IASTDeclarator declarator) {
if(declarator != null) {
@ -147,6 +137,4 @@ public class CPPASTAmbiguousDeclarator extends CPPASTAmbiguity implements IASTDe
public int getRoleForName(IASTName n) {
return getDefaultDeclarator().getRoleForName(n);
}
}