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:
parent
4177ecd4aa
commit
da0b0d3b57
12 changed files with 309 additions and 319 deletions
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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()))
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue