1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-04 14:55:41 +02:00

Bug 360541: Ambiguity resolution for declaration statements.

This commit is contained in:
Markus Schorn 2011-10-31 17:05:55 +01:00
parent b7224bd864
commit 939ab1508d
13 changed files with 297 additions and 58 deletions

View file

@ -138,7 +138,13 @@ public class AST2Tests extends AST2BaseTest {
public AST2Tests(String name) { public AST2Tests(String name) {
super(name); super(name);
} }
private void parseAndCheckBindings() throws Exception {
String code= getAboveComment();
parseAndCheckBindings(code, ParserLanguage.C);
parseAndCheckBindings(code, ParserLanguage.CPP);
}
protected IASTTranslationUnit parseAndCheckBindings(String code) throws Exception { protected IASTTranslationUnit parseAndCheckBindings(String code) throws Exception {
return parseAndCheckBindings(code, ParserLanguage.C); return parseAndCheckBindings(code, ParserLanguage.C);
} }
@ -7360,4 +7366,13 @@ public class AST2Tests extends AST2BaseTest {
es= getStatement(a, 2); es= getStatement(a, 2);
assertEquals("unsigned long int", ASTTypeUtil.getType(es.getExpression().getExpressionType())); assertEquals("unsigned long int", ASTTypeUtil.getType(es.getExpression().getExpressionType()));
} }
// void foo(){
// typedef int foobar_t;
// foobar_t *a = 0, *b = a;
// }
public void testAmbiguousStatement_Bug360541() throws Exception {
parseAndCheckBindings();
}
} }

View file

@ -83,12 +83,12 @@ public abstract class ASTAmbiguousNode extends ASTNode {
int minIssues = Integer.MAX_VALUE; int minIssues = Integer.MAX_VALUE;
for (IASTNode alternative : alternatives) { for (IASTNode alternative : alternatives) {
beforeAlternative(alternative); // Setup the ast to use the alternative
// setup the ast to use the alternative
owner.replace(nodeToReplace, alternative); owner.replace(nodeToReplace, alternative);
nodeToReplace= alternative; nodeToReplace= alternative;
beforeAlternative(alternative);
// handle nested ambiguities first, otherwise we cannot visit the alternative // handle nested ambiguities first, otherwise we cannot visit the alternative
alternative.accept(resolver); alternative.accept(resolver);

View file

@ -41,4 +41,11 @@ public interface IASTInternalScope extends IScope {
* the ambiguities have been resolved. * the ambiguities have been resolved.
*/ */
public void populateCache(); public void populateCache();
/**
* Can be called during ambiguity resolution to remove the names within the given
* node from the cache.
*/
public void removeNestedFromCache(IASTNode container);
} }

View file

@ -68,14 +68,17 @@ public class ProblemBinding extends PlatformObject implements IProblemBinding, I
this.candidateBindings = candidateBindings; this.candidateBindings = candidateBindings;
} }
@Override
public EScopeKind getKind() { public EScopeKind getKind() {
return EScopeKind.eLocal; return EScopeKind.eLocal;
} }
public IASTNode getASTNode() { @Override
public IASTNode getASTNode() {
return node; return node;
} }
@Override
public IBinding[] getCandidateBindings() { public IBinding[] getCandidateBindings() {
return candidateBindings != null ? candidateBindings : IBinding.EMPTY_BINDING_ARRAY; return candidateBindings != null ? candidateBindings : IBinding.EMPTY_BINDING_ARRAY;
} }
@ -87,14 +90,16 @@ public class ProblemBinding extends PlatformObject implements IProblemBinding, I
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IProblemBinding#getID() * @see org.eclipse.cdt.core.dom.ast.IProblemBinding#getID()
*/ */
public int getID() { @Override
public int getID() {
return id; return id;
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IProblemBinding#getMessage() * @see org.eclipse.cdt.core.dom.ast.IProblemBinding#getMessage()
*/ */
public String getMessage() { @Override
public String getMessage() {
if (message != null) if (message != null)
return message; return message;
@ -115,28 +120,32 @@ public class ProblemBinding extends PlatformObject implements IProblemBinding, I
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IBinding#getName() * @see org.eclipse.cdt.core.dom.ast.IBinding#getName()
*/ */
public String getName() { @Override
public String getName() {
return node instanceof IASTName ? new String(((IASTName) node).getSimpleID()) : CPPSemantics.EMPTY_NAME; return node instanceof IASTName ? new String(((IASTName) node).getSimpleID()) : CPPSemantics.EMPTY_NAME;
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IBinding#getNameCharArray() * @see org.eclipse.cdt.core.dom.ast.IBinding#getNameCharArray()
*/ */
public char[] getNameCharArray() { @Override
public char[] getNameCharArray() {
return node instanceof IASTName ? ((IASTName) node).getSimpleID() : CharArrayUtils.EMPTY; return node instanceof IASTName ? ((IASTName) node).getSimpleID() : CharArrayUtils.EMPTY;
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IBinding#getScope() * @see org.eclipse.cdt.core.dom.ast.IBinding#getScope()
*/ */
public IScope getScope() throws DOMException { @Override
public IScope getScope() throws DOMException {
throw new DOMException(this); throw new DOMException(this);
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IBinding#getPhysicalNode() * @see org.eclipse.cdt.core.dom.ast.IBinding#getPhysicalNode()
*/ */
public IASTNode getPhysicalNode() { @Override
public IASTNode getPhysicalNode() {
return getASTNode(); return getASTNode();
} }
@ -150,20 +159,23 @@ public class ProblemBinding extends PlatformObject implements IProblemBinding, I
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IScope#getParent() * @see org.eclipse.cdt.core.dom.ast.IScope#getParent()
*/ */
public IScope getParent() throws DOMException { @Override
public IScope getParent() throws DOMException {
throw new DOMException(this); throw new DOMException(this);
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IScope#find(java.lang.String) * @see org.eclipse.cdt.core.dom.ast.IScope#find(java.lang.String)
*/ */
public IBinding[] find(String name) { @Override
public IBinding[] find(String name) {
return IBinding.EMPTY_BINDING_ARRAY; return IBinding.EMPTY_BINDING_ARRAY;
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IScope#getScopeName() * @see org.eclipse.cdt.core.dom.ast.IScope#getScopeName()
*/ */
@Override
public IName getScopeName() { public IName getScopeName() {
return null; return null;
} }
@ -171,16 +183,19 @@ public class ProblemBinding extends PlatformObject implements IProblemBinding, I
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IScope#addName(org.eclipse.cdt.core.dom.ast.IASTName) * @see org.eclipse.cdt.core.dom.ast.IScope#addName(org.eclipse.cdt.core.dom.ast.IASTName)
*/ */
public void addName(IASTName name) { @Override
public void addName(IASTName name) {
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IScope#getBinding(org.eclipse.cdt.core.dom.ast.IASTName, boolean) * @see org.eclipse.cdt.core.dom.ast.IScope#getBinding(org.eclipse.cdt.core.dom.ast.IASTName, boolean)
*/ */
public IBinding getBinding(IASTName name, boolean resolve) { @Override
public IBinding getBinding(IASTName name, boolean resolve) {
return null; return null;
} }
@Override
public final IBinding[] getBindings(IASTName name, boolean resolve, boolean prefix) { public final IBinding[] getBindings(IASTName name, boolean resolve, boolean prefix) {
return IBinding.EMPTY_BINDING_ARRAY; return IBinding.EMPTY_BINDING_ARRAY;
} }
@ -188,24 +203,28 @@ public class ProblemBinding extends PlatformObject implements IProblemBinding, I
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IScope#getBinding(org.eclipse.cdt.core.dom.ast.IASTName, boolean) * @see org.eclipse.cdt.core.dom.ast.IScope#getBinding(org.eclipse.cdt.core.dom.ast.IASTName, boolean)
*/ */
public IBinding getBinding(IASTName name, boolean resolve, IIndexFileSet fileSet) { @Override
public IBinding getBinding(IASTName name, boolean resolve, IIndexFileSet fileSet) {
return null; return null;
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IScope#getBinding(org.eclipse.cdt.core.dom.ast.IASTName, boolean) * @see org.eclipse.cdt.core.dom.ast.IScope#getBinding(org.eclipse.cdt.core.dom.ast.IASTName, boolean)
*/ */
public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup, IIndexFileSet fileSet) { @Override
public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup, IIndexFileSet fileSet) {
return IBinding.EMPTY_BINDING_ARRAY; return IBinding.EMPTY_BINDING_ARRAY;
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IType#isSameType(org.eclipse.cdt.core.dom.ast.IType) * @see org.eclipse.cdt.core.dom.ast.IType#isSameType(org.eclipse.cdt.core.dom.ast.IType)
*/ */
public boolean isSameType(IType type) { @Override
public boolean isSameType(IType type) {
return type == this; return type == this;
} }
@Override
public String getFileName() { public String getFileName() {
if (node != null) if (node != null)
return node.getContainingFilename(); return node.getContainingFilename();
@ -213,6 +232,7 @@ public class ProblemBinding extends PlatformObject implements IProblemBinding, I
return ""; //$NON-NLS-1$ return ""; //$NON-NLS-1$
} }
@Override
public int getLineNumber() { public int getLineNumber() {
if (node != null) { if (node != null) {
IASTFileLocation fileLoc = node.getFileLocation(); IASTFileLocation fileLoc = node.getFileLocation();
@ -222,9 +242,11 @@ public class ProblemBinding extends PlatformObject implements IProblemBinding, I
return -1; return -1;
} }
@Override
public void addBinding(IBinding binding) { public void addBinding(IBinding binding) {
} }
@Override
public ILinkage getLinkage() { public ILinkage getLinkage() {
return Linkage.NO_LINKAGE; return Linkage.NO_LINKAGE;
} }
@ -234,6 +256,7 @@ public class ProblemBinding extends PlatformObject implements IProblemBinding, I
return getMessage(); return getMessage();
} }
@Override
public IBinding getOwner() { public IBinding getOwner() {
if (node instanceof IASTName) { if (node instanceof IASTName) {
IASTTranslationUnit tu= node.getTranslationUnit(); IASTTranslationUnit tu= node.getTranslationUnit();
@ -251,10 +274,13 @@ public class ProblemBinding extends PlatformObject implements IProblemBinding, I
} }
} }
@Override
public void populateCache() { public void populateCache() {
} }
@Override
public void removeNestedFromCache(IASTNode container) {}
// Dummy methods for derived classes // Dummy methods for derived classes
public IType getType() { public IType getType() {
return new ProblemType(getID()); return new ProblemType(getID());

View file

@ -12,7 +12,6 @@ package org.eclipse.cdt.internal.core.dom.parser.c;
import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration; import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTDeclarationStatement;
import org.eclipse.cdt.core.dom.ast.IASTDeclarator; import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTNode;
@ -47,8 +46,6 @@ public final class CASTAmbiguityResolver extends ASTVisitor {
} }
node= node.getParent(); node= node.getParent();
} }
} else if (node instanceof IASTDeclarationStatement) {
repopulateScope(((IASTDeclarationStatement) node).getDeclaration());
} }
return PROCESS_SKIP; return PROCESS_SKIP;
} }

View file

@ -11,6 +11,9 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.c; package org.eclipse.cdt.internal.core.dom.parser.c;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTDeclarationStatement;
import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTStatement; import org.eclipse.cdt.core.dom.ast.IASTStatement;
import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IScope;
@ -18,11 +21,14 @@ import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.dom.parser.ASTAmbiguousNode; import org.eclipse.cdt.internal.core.dom.parser.ASTAmbiguousNode;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguousStatement; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguousStatement;
import org.eclipse.cdt.internal.core.dom.parser.IASTInternalScope; import org.eclipse.cdt.internal.core.dom.parser.IASTInternalScope;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPASTInternalScope;
public class CASTAmbiguousStatement extends ASTAmbiguousNode implements IASTAmbiguousStatement { public class CASTAmbiguousStatement extends ASTAmbiguousNode implements IASTAmbiguousStatement {
private IASTStatement [] stmts = new IASTStatement[2]; private IASTStatement [] stmts = new IASTStatement[2];
private int stmtsPos=-1; private int stmtsPos=-1;
private IScope fScope;
private IASTDeclaration fDeclaration;
public CASTAmbiguousStatement(IASTStatement... statements) { public CASTAmbiguousStatement(IASTStatement... statements) {
for(IASTStatement s : statements) for(IASTStatement s : statements)
@ -31,13 +37,39 @@ public class CASTAmbiguousStatement extends ASTAmbiguousNode implements IASTAmbi
@Override @Override
protected void beforeResolution() { protected void beforeResolution() {
// populate containing scope, so that it will not be affected by the alternative branches. // Populate containing scope, so that it will not be affected by the alternative
IScope scope= CVisitor.getContainingScope(this); // branches.
if (scope instanceof IASTInternalScope) { fScope= CVisitor.getContainingScope(this);
((IASTInternalScope) scope).populateCache(); if (fScope instanceof ICPPASTInternalScope) {
((ICPPASTInternalScope) fScope).populateCache();
}
}
@Override
protected void beforeAlternative(IASTNode alternative) {
cleanupScope();
if (alternative instanceof IASTDeclarationStatement) {
if (fScope instanceof CScope) {
fDeclaration = ((IASTDeclarationStatement) alternative).getDeclaration();
((CScope) fScope).collectNames(fDeclaration);
}
}
}
private void cleanupScope() {
if (fScope instanceof IASTInternalScope && fDeclaration != null) {
((IASTInternalScope) fScope).removeNestedFromCache(fDeclaration);
} }
} }
@Override
protected void afterResolution(ASTVisitor resolver, IASTNode best) {
beforeAlternative(best);
fDeclaration= null;
fScope= null;
}
@Override
public void addStatement(IASTStatement s) { public void addStatement(IASTStatement s) {
assertNotFrozen(); assertNotFrozen();
if (s != null) { if (s != null) {
@ -47,7 +79,8 @@ public class CASTAmbiguousStatement extends ASTAmbiguousNode implements IASTAmbi
} }
} }
public IASTStatement[] getStatements() { @Override
public IASTStatement[] getStatements() {
stmts = (IASTStatement[]) ArrayUtil.removeNullsAfter( IASTStatement.class, stmts, stmtsPos ); stmts = (IASTStatement[]) ArrayUtil.removeNullsAfter( IASTStatement.class, stmts, stmtsPos );
return stmts; return stmts;
} }
@ -58,10 +91,12 @@ public class CASTAmbiguousStatement extends ASTAmbiguousNode implements IASTAmbi
} }
@Override
public IASTStatement copy() { public IASTStatement copy() {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@Override
public IASTStatement copy(CopyStyle style) { public IASTStatement copy(CopyStyle style) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }

View file

@ -112,7 +112,7 @@ public class CScope implements ICScope, IASTInternalScope {
private IASTNode physicalNode = null; private IASTNode physicalNode = null;
private boolean isCached = false; private boolean isCached = false;
private CharArrayObjectMap[] mapsToNameOrBinding = { CharArrayObjectMap.EMPTY_MAP, CharArrayObjectMap.EMPTY_MAP }; private CharArrayObjectMap<?> mapsToNameOrBinding[] = { CharArrayObjectMap.EMPTY_MAP, CharArrayObjectMap.EMPTY_MAP };
private final EScopeKind kind; private final EScopeKind kind;
public CScope(IASTNode physical, EScopeKind eKind) { public CScope(IASTNode physical, EScopeKind eKind) {
@ -120,6 +120,7 @@ public class CScope implements ICScope, IASTInternalScope {
kind= eKind; kind= eKind;
} }
@Override
public EScopeKind getKind() { public EScopeKind getKind() {
return kind; return kind;
} }
@ -127,7 +128,8 @@ public class CScope implements ICScope, IASTInternalScope {
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IScope#getParent() * @see org.eclipse.cdt.core.dom.ast.IScope#getParent()
*/ */
public IScope getParent() { @Override
public IScope getParent() {
return CVisitor.getContainingScope(physicalNode); return CVisitor.getContainingScope(physicalNode);
} }
@ -167,6 +169,7 @@ public class CScope implements ICScope, IASTInternalScope {
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IScope#find(java.lang.String) * @see org.eclipse.cdt.core.dom.ast.IScope#find(java.lang.String)
*/ */
@Override
public IBinding[] find(String name) { public IBinding[] find(String name) {
return CVisitor.findBindings(this, name); return CVisitor.findBindings(this, name);
} }
@ -188,19 +191,22 @@ public class CScope implements ICScope, IASTInternalScope {
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IScope#getPhysicalNode() * @see org.eclipse.cdt.core.dom.ast.IScope#getPhysicalNode()
*/ */
public IASTNode getPhysicalNode() { @Override
public IASTNode getPhysicalNode() {
return physicalNode; return physicalNode;
} }
@Override
public void addName(IASTName name) { public void addName(IASTName name) {
final char[] nchars = name.toCharArray(); final char[] nchars = name.toCharArray();
if (nchars.length == 0) if (nchars.length == 0)
return; return;
int type = getNamespaceType(name); int type = getNamespaceType(name);
CharArrayObjectMap map = mapsToNameOrBinding[type]; @SuppressWarnings("unchecked")
CharArrayObjectMap<Object> map = (CharArrayObjectMap<Object>) mapsToNameOrBinding[type];
if (map == CharArrayObjectMap.EMPTY_MAP) if (map == CharArrayObjectMap.EMPTY_MAP)
map = mapsToNameOrBinding[type] = new CharArrayObjectMap(1); mapsToNameOrBinding[type] = map = new CharArrayObjectMap<Object>(1);
Object o= map.get(nchars); Object o= map.get(nchars);
if (o instanceof IASTName) { if (o instanceof IASTName) {
@ -234,14 +240,17 @@ public class CScope implements ICScope, IASTInternalScope {
return NAMESPACE_TYPE_OTHER; return NAMESPACE_TYPE_OTHER;
} }
public final IBinding getBinding(IASTName name, boolean resolve) { @Override
public final IBinding getBinding(IASTName name, boolean resolve) {
return getBinding(name, resolve, IIndexFileSet.EMPTY); return getBinding(name, resolve, IIndexFileSet.EMPTY);
} }
@Override
public final IBinding[] getBindings(IASTName name, boolean resolve, boolean prefix) { public final IBinding[] getBindings(IASTName name, boolean resolve, boolean prefix) {
return getBindings(name, resolve, prefix, IIndexFileSet.EMPTY); return getBindings(name, resolve, prefix, IIndexFileSet.EMPTY);
} }
@Override
public final IBinding getBinding(IASTName name, boolean resolve, IIndexFileSet fileSet) { public final IBinding getBinding(IASTName name, boolean resolve, IIndexFileSet fileSet) {
char[] c = name.toCharArray(); char[] c = name.toCharArray();
if (c.length == 0) { if (c.length == 0) {
@ -323,12 +332,13 @@ public class CScope implements ICScope, IASTInternalScope {
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.c.ICScope#getBinding(org.eclipse.cdt.core.dom.ast.IASTName, boolean) * @see org.eclipse.cdt.core.dom.ast.c.ICScope#getBinding(org.eclipse.cdt.core.dom.ast.IASTName, boolean)
*/ */
@Override
public final IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup, IIndexFileSet fileSet) { public final IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup, IIndexFileSet fileSet) {
char[] c = name.toCharArray(); char[] c = name.toCharArray();
Object[] obj = null; Object[] obj = null;
populateCache(); populateCache();
for (CharArrayObjectMap map : mapsToNameOrBinding) { for (CharArrayObjectMap<?> map : mapsToNameOrBinding) {
if (prefixLookup) { if (prefixLookup) {
IContentAssistMatcher matcher = ContentAssistMatcherFactory.getInstance().createMatcher(c); IContentAssistMatcher matcher = ContentAssistMatcherFactory.getInstance().createMatcher(c);
Object[] keys = map.keyArray(); Object[] keys = map.keyArray();
@ -405,7 +415,8 @@ public class CScope implements ICScope, IASTInternalScope {
return bindings[0]; return bindings[0];
} }
public void populateCache() { @Override
public void populateCache() {
if (isCached) if (isCached)
return; return;
@ -413,6 +424,45 @@ public class CScope implements ICScope, IASTInternalScope {
isCached= true; isCached= true;
} }
@Override
public void removeNestedFromCache(IASTNode container) {
if (mapsToNameOrBinding != null) {
removeFromMap(mapsToNameOrBinding[0], container);
removeFromMap(mapsToNameOrBinding[1], container);
}
}
private void removeFromMap(CharArrayObjectMap<?> map, IASTNode container) {
for (int i = 0; i < map.size(); i++) {
Object o= map.getAt(i);
if (o instanceof IASTName) {
if (container.contains((IASTNode) o)) {
final char[] key = map.keyAt(i);
map.remove(key, 0, key.length);
i--;
}
} else if (o instanceof IASTName[]) {
final IASTName[] set = (IASTName[]) o;
removeFromSet(set, container);
}
}
}
private void removeFromSet(IASTName[] set, IASTNode container) {
int j= 0;
for (int i = 0; i < set.length; i++) {
IASTName n= set[i];
if (n == null)
break;
if (container.contains(n)) {
set[i]= null;
} else if (i != j) {
set[j++]= n;
set[i]= null;
}
}
}
protected void doPopulateCache() { protected void doPopulateCache() {
final IASTNode scopeNode = physicalNode; final IASTNode scopeNode = physicalNode;
IASTNode[] nodes = null; IASTNode[] nodes = null;
@ -569,6 +619,7 @@ public class CScope implements ICScope, IASTInternalScope {
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IScope#getScopeName() * @see org.eclipse.cdt.core.dom.ast.IScope#getScopeName()
*/ */
@Override
public IName getScopeName() { public IName getScopeName() {
if (physicalNode instanceof IASTCompositeTypeSpecifier) { if (physicalNode instanceof IASTCompositeTypeSpecifier) {
return ((IASTCompositeTypeSpecifier) physicalNode).getName(); return ((IASTCompositeTypeSpecifier) physicalNode).getName();
@ -576,15 +627,17 @@ public class CScope implements ICScope, IASTInternalScope {
return null; return null;
} }
@Override
public void addBinding(IBinding binding) { public void addBinding(IBinding binding) {
int type = NAMESPACE_TYPE_OTHER; int type = NAMESPACE_TYPE_OTHER;
if (binding instanceof ICompositeType || binding instanceof IEnumeration) { if (binding instanceof ICompositeType || binding instanceof IEnumeration) {
type = NAMESPACE_TYPE_TAG; type = NAMESPACE_TYPE_TAG;
} }
CharArrayObjectMap map = mapsToNameOrBinding[type]; @SuppressWarnings("unchecked")
CharArrayObjectMap<Object> map = (CharArrayObjectMap<Object>) mapsToNameOrBinding[type];
if (map == CharArrayObjectMap.EMPTY_MAP) if (map == CharArrayObjectMap.EMPTY_MAP)
map = mapsToNameOrBinding[type] = new CharArrayObjectMap(2); mapsToNameOrBinding[type] = map= new CharArrayObjectMap<Object>(2);
map.put(binding.getNameCharArray(), binding); map.put(binding.getNameCharArray(), binding);
} }

View file

@ -18,7 +18,6 @@ import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTCompositeTypeSpecifier; import org.eclipse.cdt.core.dom.ast.IASTCompositeTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier; import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration; import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTDeclarationStatement;
import org.eclipse.cdt.core.dom.ast.IASTDeclarator; import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition; import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
@ -85,8 +84,6 @@ final class CPPASTAmbiguityResolver extends ASTVisitor {
} }
node= node.getParent(); node= node.getParent();
} }
} else if (node instanceof IASTDeclarationStatement) {
repopulateScope(((IASTDeclarationStatement) node).getDeclaration());
} else if (node instanceof IASTDeclaration) { } else if (node instanceof IASTDeclaration) {
repopulateScope((IASTDeclaration) node); repopulateScope((IASTDeclaration) node);
} }

View file

@ -11,12 +11,16 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTDeclarationStatement;
import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTStatement; import org.eclipse.cdt.core.dom.ast.IASTStatement;
import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.dom.parser.ASTAmbiguousNode; import org.eclipse.cdt.internal.core.dom.parser.ASTAmbiguousNode;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguousStatement; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguousStatement;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
public class CPPASTAmbiguousStatement extends ASTAmbiguousNode implements public class CPPASTAmbiguousStatement extends ASTAmbiguousNode implements
@ -24,6 +28,8 @@ public class CPPASTAmbiguousStatement extends ASTAmbiguousNode implements
private IASTStatement [] stmts = new IASTStatement[2]; private IASTStatement [] stmts = new IASTStatement[2];
private int stmtsPos=-1; private int stmtsPos=-1;
private IScope fScope;
private IASTDeclaration fDeclaration;
public CPPASTAmbiguousStatement(IASTStatement... statements) { public CPPASTAmbiguousStatement(IASTStatement... statements) {
for(IASTStatement s : statements) for(IASTStatement s : statements)
@ -32,21 +38,49 @@ public class CPPASTAmbiguousStatement extends ASTAmbiguousNode implements
@Override @Override
protected void beforeResolution() { protected void beforeResolution() {
// populate containing scope, so that it will not be affected by the alternative branches. // Populate containing scope, so that it will not be affected by the alternative
IScope scope= CPPVisitor.getContainingScope(this); // branches.
if (scope instanceof ICPPASTInternalScope) { fScope= CPPVisitor.getContainingScope(this);
((ICPPASTInternalScope) scope).populateCache(); if (fScope instanceof ICPPASTInternalScope) {
((ICPPASTInternalScope) fScope).populateCache();
}
}
@Override
protected void beforeAlternative(IASTNode alternative) {
cleanupScope();
if (alternative instanceof IASTDeclarationStatement) {
if (fScope instanceof ICPPASTInternalScope) {
fDeclaration = ((IASTDeclarationStatement) alternative).getDeclaration();
CPPSemantics.populateCache((ICPPASTInternalScope) fScope, fDeclaration);
}
}
}
private void cleanupScope() {
if (fScope instanceof ICPPASTInternalScope && fDeclaration != null) {
((ICPPASTInternalScope) fScope).removeNestedFromCache(fDeclaration);
} }
} }
public IASTStatement copy() { @Override
protected void afterResolution(ASTVisitor resolver, IASTNode best) {
beforeAlternative(best);
fDeclaration= null;
fScope= null;
}
@Override
public IASTStatement copy() {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@Override
public IASTStatement copy(CopyStyle style) { public IASTStatement copy(CopyStyle style) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@Override
public void addStatement(IASTStatement s) { public void addStatement(IASTStatement s) {
assertNotFrozen(); assertNotFrozen();
if (s != null) { if (s != null) {
@ -56,7 +90,8 @@ public class CPPASTAmbiguousStatement extends ASTAmbiguousNode implements
} }
} }
public IASTStatement[] getStatements() { @Override
public IASTStatement[] getStatements() {
stmts = (IASTStatement[]) ArrayUtil.removeNullsAfter( IASTStatement.class, stmts, stmtsPos ); stmts = (IASTStatement[]) ArrayUtil.removeNullsAfter( IASTStatement.class, stmts, stmtsPos );
return stmts; return stmts;
} }

View file

@ -28,8 +28,14 @@ public class CPPClassSpecializationScope extends AbstractCPPClassSpecializationS
} }
// This scope does not cache its own names // This scope does not cache its own names
@Override
public void addName(IASTName name) {} public void addName(IASTName name) {}
@Override
public IASTNode getPhysicalNode() { return null; } public IASTNode getPhysicalNode() { return null; }
@Override
public void addBinding(IBinding binding) {} public void addBinding(IBinding binding) {}
@Override
public void populateCache() {} public void populateCache() {}
@Override
public void removeNestedFromCache(IASTNode container) {}
} }

View file

@ -60,7 +60,7 @@ abstract public class CPPScope implements ICPPASTInternalScope {
private IASTNode physicalNode; private IASTNode physicalNode;
private boolean isCached = false; private boolean isCached = false;
protected CharArrayObjectMap bindings = null; protected CharArrayObjectMap<Object> bindings = null;
private ICPPNamespace fIndexNamespace= UNINITIALIZED; private ICPPNamespace fIndexNamespace= UNINITIALIZED;
public static class CPPScopeProblem extends ProblemBinding implements ICPPScope { public static class CPPScopeProblem extends ProblemBinding implements ICPPScope {
@ -76,14 +76,17 @@ abstract public class CPPScope implements ICPPASTInternalScope {
this.physicalNode = physicalNode; this.physicalNode = physicalNode;
} }
@Override
public IScope getParent() throws DOMException { public IScope getParent() throws DOMException {
return CPPVisitor.getContainingNonTemplateScope(physicalNode); return CPPVisitor.getContainingNonTemplateScope(physicalNode);
} }
@Override
public IASTNode getPhysicalNode() { public IASTNode getPhysicalNode() {
return physicalNode; return physicalNode;
} }
@Override
@SuppressWarnings({ "unchecked" }) @SuppressWarnings({ "unchecked" })
public void addName(IASTName name) { public void addName(IASTName name) {
// don't add inactive names to the scope // don't add inactive names to the scope
@ -91,7 +94,7 @@ abstract public class CPPScope implements ICPPASTInternalScope {
return; return;
if (bindings == null) if (bindings == null)
bindings = new CharArrayObjectMap(1); bindings = new CharArrayObjectMap<Object>(1);
if (name instanceof ICPPASTQualifiedName) { if (name instanceof ICPPASTQualifiedName) {
if (!(physicalNode instanceof ICPPASTCompositeTypeSpecifier) && if (!(physicalNode instanceof ICPPASTCompositeTypeSpecifier) &&
!(physicalNode instanceof ICPPASTNamespaceDefinition)) { !(physicalNode instanceof ICPPASTNamespaceDefinition)) {
@ -144,6 +147,7 @@ abstract public class CPPScope implements ICPPASTInternalScope {
} }
} }
@Override
public IBinding getBinding(IASTName name, boolean forceResolve, IIndexFileSet fileSet) { public IBinding getBinding(IASTName name, boolean forceResolve, IIndexFileSet fileSet) {
IBinding binding= getBindingInAST(name, forceResolve); IBinding binding= getBindingInAST(name, forceResolve);
if (binding == null && forceResolve) { if (binding == null && forceResolve) {
@ -198,10 +202,12 @@ abstract public class CPPScope implements ICPPASTInternalScope {
return CPPSemantics.resolveAmbiguities(name, bs); return CPPSemantics.resolveAmbiguities(name, bs);
} }
@Override
public final IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup, IIndexFileSet fileSet) { public final IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup, IIndexFileSet fileSet) {
return getBindings(name, resolve, prefixLookup, fileSet, true); return getBindings(name, resolve, prefixLookup, fileSet, true);
} }
@Override
public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup, IIndexFileSet fileSet, public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup, IIndexFileSet fileSet,
boolean checkPointOfDecl) { boolean checkPointOfDecl) {
IBinding[] result = getBindingsInAST(name, resolve, prefixLookup, checkPointOfDecl); IBinding[] result = getBindingsInAST(name, resolve, prefixLookup, checkPointOfDecl);
@ -316,24 +322,63 @@ abstract public class CPPScope implements ICPPASTInternalScope {
return (IBinding[]) ArrayUtil.append(IBinding.class, result, binding); return (IBinding[]) ArrayUtil.append(IBinding.class, result, binding);
} }
@Override
public final void populateCache() { public final void populateCache() {
if (!isCached) { if (!isCached) {
CPPSemantics.populateCache(this); CPPSemantics.populateCache(this);
isCached= true; isCached= true;
} }
} }
@Override
public void removeNestedFromCache(IASTNode container) {
if (bindings != null) {
removeFromMap(bindings, container);
}
}
private void removeFromMap(CharArrayObjectMap<Object> map, IASTNode container) {
for (int i = 0; i < map.size(); i++) {
Object o= map.getAt(i);
if (o instanceof IASTName) {
if (container.contains((IASTNode) o)) {
final char[] key = map.keyAt(i);
map.remove(key, 0, key.length);
i--;
}
} else if (o instanceof ObjectSet) {
@SuppressWarnings("unchecked")
final ObjectSet<Object> set = (ObjectSet<Object>) o;
removeFromSet(set, container);
}
}
}
private void removeFromSet(ObjectSet<Object> set, IASTNode container) {
for (int i = 0; i < set.size(); i++) {
Object o= set.keyAt(i);
if (o instanceof IASTName) {
if (container.contains((IASTNode) o)) {
set.remove(o);
i--;
}
}
}
}
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IScope#find(java.lang.String) * @see org.eclipse.cdt.core.dom.ast.IScope#find(java.lang.String)
*/ */
@Override
public IBinding[] find(String name) { public IBinding[] find(String name) {
return CPPSemantics.findBindings(this, name, false); return CPPSemantics.findBindings(this, name, false);
} }
@Override
@SuppressWarnings({ "unchecked" }) @SuppressWarnings({ "unchecked" })
public void addBinding(IBinding binding) { public void addBinding(IBinding binding) {
if (bindings == null) if (bindings == null)
bindings = new CharArrayObjectMap(1); bindings = new CharArrayObjectMap<Object>(1);
char[] c = binding.getNameCharArray(); char[] c = binding.getNameCharArray();
if (c.length == 0) { if (c.length == 0) {
return; return;
@ -353,14 +398,17 @@ abstract public class CPPScope implements ICPPASTInternalScope {
} }
} }
@Override
public final IBinding getBinding(IASTName name, boolean resolve) { public final IBinding getBinding(IASTName name, boolean resolve) {
return getBinding(name, resolve, IIndexFileSet.EMPTY); return getBinding(name, resolve, IIndexFileSet.EMPTY);
} }
@Override
public final IBinding[] getBindings(IASTName name, boolean resolve, boolean prefix) { public final IBinding[] getBindings(IASTName name, boolean resolve, boolean prefix) {
return getBindings(name, resolve, prefix, IIndexFileSet.EMPTY, true); return getBindings(name, resolve, prefix, IIndexFileSet.EMPTY, true);
} }
@Override
public IName getScopeName() { public IName getScopeName() {
return null; return null;
} }

View file

@ -52,6 +52,7 @@ public class CPPUnknownScope implements ICPPInternalUnknownScope {
this.binding = binding; this.binding = binding;
} }
@Override
public EScopeKind getKind() { public EScopeKind getKind() {
return EScopeKind.eClassType; return EScopeKind.eClassType;
} }
@ -59,37 +60,43 @@ public class CPPUnknownScope implements ICPPInternalUnknownScope {
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IScope#getScopeName() * @see org.eclipse.cdt.core.dom.ast.IScope#getScopeName()
*/ */
public IName getScopeName() { @Override
public IName getScopeName() {
return scopeName; return scopeName;
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IScope#getParent() * @see org.eclipse.cdt.core.dom.ast.IScope#getParent()
*/ */
public IScope getParent() throws DOMException { @Override
public IScope getParent() throws DOMException {
return binding.getScope(); return binding.getScope();
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IScope#find(java.lang.String) * @see org.eclipse.cdt.core.dom.ast.IScope#find(java.lang.String)
*/ */
public IBinding[] find(String name) { @Override
public IBinding[] find(String name) {
return null; return null;
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IScope#getPhysicalNode() * @see org.eclipse.cdt.core.dom.ast.IScope#getPhysicalNode()
*/ */
public IASTNode getPhysicalNode() { @Override
public IASTNode getPhysicalNode() {
return scopeName; return scopeName;
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IScope#addName(org.eclipse.cdt.core.dom.ast.IASTName) * @see org.eclipse.cdt.core.dom.ast.IScope#addName(org.eclipse.cdt.core.dom.ast.IASTName)
*/ */
public void addName(IASTName name) { @Override
public void addName(IASTName name) {
} }
@Override
public final IBinding getBinding(IASTName name, boolean resolve) { public final IBinding getBinding(IASTName name, boolean resolve) {
return getBinding(name, resolve, IIndexFileSet.EMPTY); return getBinding(name, resolve, IIndexFileSet.EMPTY);
} }
@ -97,7 +104,8 @@ public class CPPUnknownScope implements ICPPInternalUnknownScope {
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IScope#getBinding(org.eclipse.cdt.core.dom.ast.IASTName, boolean) * @see org.eclipse.cdt.core.dom.ast.IScope#getBinding(org.eclipse.cdt.core.dom.ast.IASTName, boolean)
*/ */
public IBinding getBinding(final IASTName name, boolean resolve, IIndexFileSet fileSet) { @Override
public IBinding getBinding(final IASTName name, boolean resolve, IIndexFileSet fileSet) {
boolean type= false; boolean type= false;
boolean function= false; boolean function= false;
@ -171,15 +179,18 @@ public class CPPUnknownScope implements ICPPInternalUnknownScope {
return result; return result;
} }
@Override
public final IBinding[] getBindings(IASTName name, boolean resolve, boolean prefix) { public final IBinding[] getBindings(IASTName name, boolean resolve, boolean prefix) {
return getBindings(name, resolve, prefix, IIndexFileSet.EMPTY); return getBindings(name, resolve, prefix, IIndexFileSet.EMPTY);
} }
public final IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup, IIndexFileSet fileSet) { @Override
public final IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup, IIndexFileSet fileSet) {
return getBindings(name, resolve, prefixLookup, fileSet, true); return getBindings(name, resolve, prefixLookup, fileSet, true);
} }
public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup, IIndexFileSet acceptLocalBindings, boolean checkPointOfDecl) { @Override
public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup, IIndexFileSet acceptLocalBindings, boolean checkPointOfDecl) {
if (prefixLookup) { if (prefixLookup) {
if (binding instanceof ICPPDeferredClassInstance) { if (binding instanceof ICPPDeferredClassInstance) {
ICPPDeferredClassInstance instance = (ICPPDeferredClassInstance) binding; ICPPDeferredClassInstance instance = (ICPPDeferredClassInstance) binding;
@ -194,6 +205,7 @@ public class CPPUnknownScope implements ICPPInternalUnknownScope {
return new IBinding[] {getBinding(name, resolve, acceptLocalBindings)}; return new IBinding[] {getBinding(name, resolve, acceptLocalBindings)};
} }
@Override
public void addBinding(IBinding binding) { public void addBinding(IBinding binding) {
// do nothing, this is part of template magic and not a normal scope // do nothing, this is part of template magic and not a normal scope
} }
@ -201,6 +213,7 @@ public class CPPUnknownScope implements ICPPInternalUnknownScope {
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalUnknownScope#getUnknownBinding() * @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalUnknownScope#getUnknownBinding()
*/ */
@Override
public ICPPBinding getScopeBinding() { public ICPPBinding getScopeBinding() {
return binding; return binding;
} }
@ -213,5 +226,9 @@ public class CPPUnknownScope implements ICPPInternalUnknownScope {
return scopeName.toString(); return scopeName.toString();
} }
@Override
public void populateCache() {} public void populateCache() {}
@Override
public void removeNestedFromCache(IASTNode container) {}
} }

View file

@ -92,6 +92,9 @@ public class C99Scope implements IC99Scope, IASTInternalScope {
public void populateCache() { public void populateCache() {
} }
public void removeNestedFromCache(IASTNode container) {
}
public IBinding getBinding(IASTName name, boolean resolve, public IBinding getBinding(IASTName name, boolean resolve,
IIndexFileSet acceptLocalBindings) { IIndexFileSet acceptLocalBindings) {
// TODO Auto-generated method stub // TODO Auto-generated method stub