mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-25 18:05:33 +02:00
Bug 360541: Ambiguity resolution for declaration statements.
This commit is contained in:
parent
b7224bd864
commit
939ab1508d
13 changed files with 297 additions and 58 deletions
|
@ -138,7 +138,13 @@ public class AST2Tests extends AST2BaseTest {
|
|||
public AST2Tests(String 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 {
|
||||
return parseAndCheckBindings(code, ParserLanguage.C);
|
||||
}
|
||||
|
@ -7360,4 +7366,13 @@ public class AST2Tests extends AST2BaseTest {
|
|||
es= getStatement(a, 2);
|
||||
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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -83,12 +83,12 @@ public abstract class ASTAmbiguousNode extends ASTNode {
|
|||
|
||||
int minIssues = Integer.MAX_VALUE;
|
||||
for (IASTNode alternative : alternatives) {
|
||||
beforeAlternative(alternative);
|
||||
|
||||
// setup the ast to use the alternative
|
||||
// Setup the ast to use the alternative
|
||||
owner.replace(nodeToReplace, alternative);
|
||||
nodeToReplace= alternative;
|
||||
|
||||
beforeAlternative(alternative);
|
||||
|
||||
// handle nested ambiguities first, otherwise we cannot visit the alternative
|
||||
alternative.accept(resolver);
|
||||
|
||||
|
|
|
@ -41,4 +41,11 @@ public interface IASTInternalScope extends IScope {
|
|||
* the ambiguities have been resolved.
|
||||
*/
|
||||
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);
|
||||
|
||||
}
|
||||
|
|
|
@ -68,14 +68,17 @@ public class ProblemBinding extends PlatformObject implements IProblemBinding, I
|
|||
this.candidateBindings = candidateBindings;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EScopeKind getKind() {
|
||||
return EScopeKind.eLocal;
|
||||
}
|
||||
|
||||
public IASTNode getASTNode() {
|
||||
@Override
|
||||
public IASTNode getASTNode() {
|
||||
return node;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBinding[] getCandidateBindings() {
|
||||
return candidateBindings != null ? candidateBindings : IBinding.EMPTY_BINDING_ARRAY;
|
||||
}
|
||||
|
@ -87,14 +90,16 @@ public class ProblemBinding extends PlatformObject implements IProblemBinding, I
|
|||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.dom.ast.IProblemBinding#getID()
|
||||
*/
|
||||
public int getID() {
|
||||
@Override
|
||||
public int getID() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.dom.ast.IProblemBinding#getMessage()
|
||||
*/
|
||||
public String getMessage() {
|
||||
@Override
|
||||
public String getMessage() {
|
||||
if (message != null)
|
||||
return message;
|
||||
|
||||
|
@ -115,28 +120,32 @@ public class ProblemBinding extends PlatformObject implements IProblemBinding, I
|
|||
/* (non-Javadoc)
|
||||
* @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;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @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;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.dom.ast.IBinding#getScope()
|
||||
*/
|
||||
public IScope getScope() throws DOMException {
|
||||
@Override
|
||||
public IScope getScope() throws DOMException {
|
||||
throw new DOMException(this);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.dom.ast.IBinding#getPhysicalNode()
|
||||
*/
|
||||
public IASTNode getPhysicalNode() {
|
||||
@Override
|
||||
public IASTNode getPhysicalNode() {
|
||||
return getASTNode();
|
||||
}
|
||||
|
||||
|
@ -150,20 +159,23 @@ public class ProblemBinding extends PlatformObject implements IProblemBinding, I
|
|||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.dom.ast.IScope#getParent()
|
||||
*/
|
||||
public IScope getParent() throws DOMException {
|
||||
@Override
|
||||
public IScope getParent() throws DOMException {
|
||||
throw new DOMException(this);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @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;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.dom.ast.IScope#getScopeName()
|
||||
*/
|
||||
@Override
|
||||
public IName getScopeName() {
|
||||
return null;
|
||||
}
|
||||
|
@ -171,16 +183,19 @@ public class ProblemBinding extends PlatformObject implements IProblemBinding, I
|
|||
/* (non-Javadoc)
|
||||
* @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)
|
||||
* @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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final IBinding[] getBindings(IASTName name, boolean resolve, boolean prefix) {
|
||||
return IBinding.EMPTY_BINDING_ARRAY;
|
||||
}
|
||||
|
@ -188,24 +203,28 @@ public class ProblemBinding extends PlatformObject implements IProblemBinding, I
|
|||
/* (non-Javadoc)
|
||||
* @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;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @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;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFileName() {
|
||||
if (node != null)
|
||||
return node.getContainingFilename();
|
||||
|
@ -213,6 +232,7 @@ public class ProblemBinding extends PlatformObject implements IProblemBinding, I
|
|||
return ""; //$NON-NLS-1$
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLineNumber() {
|
||||
if (node != null) {
|
||||
IASTFileLocation fileLoc = node.getFileLocation();
|
||||
|
@ -222,9 +242,11 @@ public class ProblemBinding extends PlatformObject implements IProblemBinding, I
|
|||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addBinding(IBinding binding) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ILinkage getLinkage() {
|
||||
return Linkage.NO_LINKAGE;
|
||||
}
|
||||
|
@ -234,6 +256,7 @@ public class ProblemBinding extends PlatformObject implements IProblemBinding, I
|
|||
return getMessage();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBinding getOwner() {
|
||||
if (node instanceof IASTName) {
|
||||
IASTTranslationUnit tu= node.getTranslationUnit();
|
||||
|
@ -251,10 +274,13 @@ public class ProblemBinding extends PlatformObject implements IProblemBinding, I
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void populateCache() {
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void removeNestedFromCache(IASTNode container) {}
|
||||
|
||||
// Dummy methods for derived classes
|
||||
public IType getType() {
|
||||
return new ProblemType(getID());
|
||||
|
|
|
@ -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.IASTDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTDeclarationStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||
|
@ -47,8 +46,6 @@ public final class CASTAmbiguityResolver extends ASTVisitor {
|
|||
}
|
||||
node= node.getParent();
|
||||
}
|
||||
} else if (node instanceof IASTDeclarationStatement) {
|
||||
repopulateScope(((IASTDeclarationStatement) node).getDeclaration());
|
||||
}
|
||||
return PROCESS_SKIP;
|
||||
}
|
||||
|
|
|
@ -11,6 +11,9 @@
|
|||
*******************************************************************************/
|
||||
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.IASTStatement;
|
||||
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.IASTAmbiguousStatement;
|
||||
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 {
|
||||
|
||||
private IASTStatement [] stmts = new IASTStatement[2];
|
||||
private int stmtsPos=-1;
|
||||
private IScope fScope;
|
||||
private IASTDeclaration fDeclaration;
|
||||
|
||||
public CASTAmbiguousStatement(IASTStatement... statements) {
|
||||
for(IASTStatement s : statements)
|
||||
|
@ -31,13 +37,39 @@ public class CASTAmbiguousStatement extends ASTAmbiguousNode implements IASTAmbi
|
|||
|
||||
@Override
|
||||
protected void beforeResolution() {
|
||||
// populate containing scope, so that it will not be affected by the alternative branches.
|
||||
IScope scope= CVisitor.getContainingScope(this);
|
||||
if (scope instanceof IASTInternalScope) {
|
||||
((IASTInternalScope) scope).populateCache();
|
||||
// Populate containing scope, so that it will not be affected by the alternative
|
||||
// branches.
|
||||
fScope= CVisitor.getContainingScope(this);
|
||||
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) {
|
||||
assertNotFrozen();
|
||||
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 );
|
||||
return stmts;
|
||||
}
|
||||
|
@ -58,10 +91,12 @@ public class CASTAmbiguousStatement extends ASTAmbiguousNode implements IASTAmbi
|
|||
}
|
||||
|
||||
|
||||
@Override
|
||||
public IASTStatement copy() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IASTStatement copy(CopyStyle style) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
|
|
@ -112,7 +112,7 @@ public class CScope implements ICScope, IASTInternalScope {
|
|||
private IASTNode physicalNode = null;
|
||||
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;
|
||||
|
||||
public CScope(IASTNode physical, EScopeKind eKind) {
|
||||
|
@ -120,6 +120,7 @@ public class CScope implements ICScope, IASTInternalScope {
|
|||
kind= eKind;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EScopeKind getKind() {
|
||||
return kind;
|
||||
}
|
||||
|
@ -127,7 +128,8 @@ public class CScope implements ICScope, IASTInternalScope {
|
|||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.dom.ast.IScope#getParent()
|
||||
*/
|
||||
public IScope getParent() {
|
||||
@Override
|
||||
public IScope getParent() {
|
||||
return CVisitor.getContainingScope(physicalNode);
|
||||
}
|
||||
|
||||
|
@ -167,6 +169,7 @@ public class CScope implements ICScope, IASTInternalScope {
|
|||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.dom.ast.IScope#find(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public IBinding[] find(String name) {
|
||||
return CVisitor.findBindings(this, name);
|
||||
}
|
||||
|
@ -188,19 +191,22 @@ public class CScope implements ICScope, IASTInternalScope {
|
|||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.dom.ast.IScope#getPhysicalNode()
|
||||
*/
|
||||
public IASTNode getPhysicalNode() {
|
||||
@Override
|
||||
public IASTNode getPhysicalNode() {
|
||||
return physicalNode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addName(IASTName name) {
|
||||
final char[] nchars = name.toCharArray();
|
||||
if (nchars.length == 0)
|
||||
return;
|
||||
|
||||
int type = getNamespaceType(name);
|
||||
CharArrayObjectMap map = mapsToNameOrBinding[type];
|
||||
@SuppressWarnings("unchecked")
|
||||
CharArrayObjectMap<Object> map = (CharArrayObjectMap<Object>) mapsToNameOrBinding[type];
|
||||
if (map == CharArrayObjectMap.EMPTY_MAP)
|
||||
map = mapsToNameOrBinding[type] = new CharArrayObjectMap(1);
|
||||
mapsToNameOrBinding[type] = map = new CharArrayObjectMap<Object>(1);
|
||||
|
||||
Object o= map.get(nchars);
|
||||
if (o instanceof IASTName) {
|
||||
|
@ -234,14 +240,17 @@ public class CScope implements ICScope, IASTInternalScope {
|
|||
|
||||
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);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final IBinding[] getBindings(IASTName name, boolean resolve, boolean prefix) {
|
||||
return getBindings(name, resolve, prefix, IIndexFileSet.EMPTY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final IBinding getBinding(IASTName name, boolean resolve, IIndexFileSet fileSet) {
|
||||
char[] c = name.toCharArray();
|
||||
if (c.length == 0) {
|
||||
|
@ -323,12 +332,13 @@ public class CScope implements ICScope, IASTInternalScope {
|
|||
/* (non-Javadoc)
|
||||
* @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) {
|
||||
char[] c = name.toCharArray();
|
||||
Object[] obj = null;
|
||||
|
||||
populateCache();
|
||||
for (CharArrayObjectMap map : mapsToNameOrBinding) {
|
||||
for (CharArrayObjectMap<?> map : mapsToNameOrBinding) {
|
||||
if (prefixLookup) {
|
||||
IContentAssistMatcher matcher = ContentAssistMatcherFactory.getInstance().createMatcher(c);
|
||||
Object[] keys = map.keyArray();
|
||||
|
@ -405,7 +415,8 @@ public class CScope implements ICScope, IASTInternalScope {
|
|||
return bindings[0];
|
||||
}
|
||||
|
||||
public void populateCache() {
|
||||
@Override
|
||||
public void populateCache() {
|
||||
if (isCached)
|
||||
return;
|
||||
|
||||
|
@ -413,6 +424,45 @@ public class CScope implements ICScope, IASTInternalScope {
|
|||
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() {
|
||||
final IASTNode scopeNode = physicalNode;
|
||||
IASTNode[] nodes = null;
|
||||
|
@ -569,6 +619,7 @@ public class CScope implements ICScope, IASTInternalScope {
|
|||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.dom.ast.IScope#getScopeName()
|
||||
*/
|
||||
@Override
|
||||
public IName getScopeName() {
|
||||
if (physicalNode instanceof IASTCompositeTypeSpecifier) {
|
||||
return ((IASTCompositeTypeSpecifier) physicalNode).getName();
|
||||
|
@ -576,15 +627,17 @@ public class CScope implements ICScope, IASTInternalScope {
|
|||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addBinding(IBinding binding) {
|
||||
int type = NAMESPACE_TYPE_OTHER;
|
||||
if (binding instanceof ICompositeType || binding instanceof IEnumeration) {
|
||||
type = NAMESPACE_TYPE_TAG;
|
||||
}
|
||||
|
||||
CharArrayObjectMap map = mapsToNameOrBinding[type];
|
||||
@SuppressWarnings("unchecked")
|
||||
CharArrayObjectMap<Object> map = (CharArrayObjectMap<Object>) mapsToNameOrBinding[type];
|
||||
if (map == CharArrayObjectMap.EMPTY_MAP)
|
||||
map = mapsToNameOrBinding[type] = new CharArrayObjectMap(2);
|
||||
mapsToNameOrBinding[type] = map= new CharArrayObjectMap<Object>(2);
|
||||
|
||||
map.put(binding.getNameCharArray(), binding);
|
||||
}
|
||||
|
|
|
@ -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.IASTDeclSpecifier;
|
||||
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.IASTExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
|
||||
|
@ -85,8 +84,6 @@ final class CPPASTAmbiguityResolver extends ASTVisitor {
|
|||
}
|
||||
node= node.getParent();
|
||||
}
|
||||
} else if (node instanceof IASTDeclarationStatement) {
|
||||
repopulateScope(((IASTDeclarationStatement) node).getDeclaration());
|
||||
} else if (node instanceof IASTDeclaration) {
|
||||
repopulateScope((IASTDeclaration) node);
|
||||
}
|
||||
|
|
|
@ -11,12 +11,16 @@
|
|||
*******************************************************************************/
|
||||
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.IASTStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.IScope;
|
||||
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.IASTAmbiguousStatement;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
|
||||
|
||||
public class CPPASTAmbiguousStatement extends ASTAmbiguousNode implements
|
||||
|
@ -24,6 +28,8 @@ public class CPPASTAmbiguousStatement extends ASTAmbiguousNode implements
|
|||
|
||||
private IASTStatement [] stmts = new IASTStatement[2];
|
||||
private int stmtsPos=-1;
|
||||
private IScope fScope;
|
||||
private IASTDeclaration fDeclaration;
|
||||
|
||||
public CPPASTAmbiguousStatement(IASTStatement... statements) {
|
||||
for(IASTStatement s : statements)
|
||||
|
@ -32,21 +38,49 @@ public class CPPASTAmbiguousStatement extends ASTAmbiguousNode implements
|
|||
|
||||
@Override
|
||||
protected void beforeResolution() {
|
||||
// populate containing scope, so that it will not be affected by the alternative branches.
|
||||
IScope scope= CPPVisitor.getContainingScope(this);
|
||||
if (scope instanceof ICPPASTInternalScope) {
|
||||
((ICPPASTInternalScope) scope).populateCache();
|
||||
// Populate containing scope, so that it will not be affected by the alternative
|
||||
// branches.
|
||||
fScope= CPPVisitor.getContainingScope(this);
|
||||
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();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IASTStatement copy(CopyStyle style) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addStatement(IASTStatement s) {
|
||||
assertNotFrozen();
|
||||
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 );
|
||||
return stmts;
|
||||
}
|
||||
|
|
|
@ -28,8 +28,14 @@ public class CPPClassSpecializationScope extends AbstractCPPClassSpecializationS
|
|||
}
|
||||
|
||||
// This scope does not cache its own names
|
||||
@Override
|
||||
public void addName(IASTName name) {}
|
||||
@Override
|
||||
public IASTNode getPhysicalNode() { return null; }
|
||||
@Override
|
||||
public void addBinding(IBinding binding) {}
|
||||
@Override
|
||||
public void populateCache() {}
|
||||
@Override
|
||||
public void removeNestedFromCache(IASTNode container) {}
|
||||
}
|
||||
|
|
|
@ -60,7 +60,7 @@ abstract public class CPPScope implements ICPPASTInternalScope {
|
|||
|
||||
private IASTNode physicalNode;
|
||||
private boolean isCached = false;
|
||||
protected CharArrayObjectMap bindings = null;
|
||||
protected CharArrayObjectMap<Object> bindings = null;
|
||||
private ICPPNamespace fIndexNamespace= UNINITIALIZED;
|
||||
|
||||
public static class CPPScopeProblem extends ProblemBinding implements ICPPScope {
|
||||
|
@ -76,14 +76,17 @@ abstract public class CPPScope implements ICPPASTInternalScope {
|
|||
this.physicalNode = physicalNode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IScope getParent() throws DOMException {
|
||||
return CPPVisitor.getContainingNonTemplateScope(physicalNode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IASTNode getPhysicalNode() {
|
||||
return physicalNode;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings({ "unchecked" })
|
||||
public void addName(IASTName name) {
|
||||
// don't add inactive names to the scope
|
||||
|
@ -91,7 +94,7 @@ abstract public class CPPScope implements ICPPASTInternalScope {
|
|||
return;
|
||||
|
||||
if (bindings == null)
|
||||
bindings = new CharArrayObjectMap(1);
|
||||
bindings = new CharArrayObjectMap<Object>(1);
|
||||
if (name instanceof ICPPASTQualifiedName) {
|
||||
if (!(physicalNode instanceof ICPPASTCompositeTypeSpecifier) &&
|
||||
!(physicalNode instanceof ICPPASTNamespaceDefinition)) {
|
||||
|
@ -144,6 +147,7 @@ abstract public class CPPScope implements ICPPASTInternalScope {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBinding getBinding(IASTName name, boolean forceResolve, IIndexFileSet fileSet) {
|
||||
IBinding binding= getBindingInAST(name, forceResolve);
|
||||
if (binding == null && forceResolve) {
|
||||
|
@ -198,10 +202,12 @@ abstract public class CPPScope implements ICPPASTInternalScope {
|
|||
return CPPSemantics.resolveAmbiguities(name, bs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup, IIndexFileSet fileSet) {
|
||||
return getBindings(name, resolve, prefixLookup, fileSet, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup, IIndexFileSet fileSet,
|
||||
boolean 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);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void populateCache() {
|
||||
if (!isCached) {
|
||||
CPPSemantics.populateCache(this);
|
||||
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)
|
||||
* @see org.eclipse.cdt.core.dom.ast.IScope#find(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public IBinding[] find(String name) {
|
||||
return CPPSemantics.findBindings(this, name, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings({ "unchecked" })
|
||||
public void addBinding(IBinding binding) {
|
||||
if (bindings == null)
|
||||
bindings = new CharArrayObjectMap(1);
|
||||
bindings = new CharArrayObjectMap<Object>(1);
|
||||
char[] c = binding.getNameCharArray();
|
||||
if (c.length == 0) {
|
||||
return;
|
||||
|
@ -353,14 +398,17 @@ abstract public class CPPScope implements ICPPASTInternalScope {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final IBinding getBinding(IASTName name, boolean resolve) {
|
||||
return getBinding(name, resolve, IIndexFileSet.EMPTY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final IBinding[] getBindings(IASTName name, boolean resolve, boolean prefix) {
|
||||
return getBindings(name, resolve, prefix, IIndexFileSet.EMPTY, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IName getScopeName() {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -52,6 +52,7 @@ public class CPPUnknownScope implements ICPPInternalUnknownScope {
|
|||
this.binding = binding;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EScopeKind getKind() {
|
||||
return EScopeKind.eClassType;
|
||||
}
|
||||
|
@ -59,37 +60,43 @@ public class CPPUnknownScope implements ICPPInternalUnknownScope {
|
|||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.dom.ast.IScope#getScopeName()
|
||||
*/
|
||||
public IName getScopeName() {
|
||||
@Override
|
||||
public IName getScopeName() {
|
||||
return scopeName;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.dom.ast.IScope#getParent()
|
||||
*/
|
||||
public IScope getParent() throws DOMException {
|
||||
@Override
|
||||
public IScope getParent() throws DOMException {
|
||||
return binding.getScope();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @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;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.dom.ast.IScope#getPhysicalNode()
|
||||
*/
|
||||
public IASTNode getPhysicalNode() {
|
||||
@Override
|
||||
public IASTNode getPhysicalNode() {
|
||||
return scopeName;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @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) {
|
||||
return getBinding(name, resolve, IIndexFileSet.EMPTY);
|
||||
}
|
||||
|
@ -97,7 +104,8 @@ public class CPPUnknownScope implements ICPPInternalUnknownScope {
|
|||
/* (non-Javadoc)
|
||||
* @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 function= false;
|
||||
|
||||
|
@ -171,15 +179,18 @@ public class CPPUnknownScope implements ICPPInternalUnknownScope {
|
|||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final IBinding[] getBindings(IASTName name, boolean resolve, boolean prefix) {
|
||||
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);
|
||||
}
|
||||
|
||||
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 (binding instanceof ICPPDeferredClassInstance) {
|
||||
ICPPDeferredClassInstance instance = (ICPPDeferredClassInstance) binding;
|
||||
|
@ -194,6 +205,7 @@ public class CPPUnknownScope implements ICPPInternalUnknownScope {
|
|||
return new IBinding[] {getBinding(name, resolve, acceptLocalBindings)};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addBinding(IBinding binding) {
|
||||
// do nothing, this is part of template magic and not a normal scope
|
||||
}
|
||||
|
@ -201,6 +213,7 @@ public class CPPUnknownScope implements ICPPInternalUnknownScope {
|
|||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalUnknownScope#getUnknownBinding()
|
||||
*/
|
||||
@Override
|
||||
public ICPPBinding getScopeBinding() {
|
||||
return binding;
|
||||
}
|
||||
|
@ -213,5 +226,9 @@ public class CPPUnknownScope implements ICPPInternalUnknownScope {
|
|||
return scopeName.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void populateCache() {}
|
||||
|
||||
@Override
|
||||
public void removeNestedFromCache(IASTNode container) {}
|
||||
}
|
||||
|
|
|
@ -92,6 +92,9 @@ public class C99Scope implements IC99Scope, IASTInternalScope {
|
|||
public void populateCache() {
|
||||
}
|
||||
|
||||
public void removeNestedFromCache(IASTNode container) {
|
||||
}
|
||||
|
||||
public IBinding getBinding(IASTName name, boolean resolve,
|
||||
IIndexFileSet acceptLocalBindings) {
|
||||
// TODO Auto-generated method stub
|
||||
|
|
Loading…
Add table
Reference in a new issue