1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-23 22:52:11 +02:00

Removes the need to flush the cache of c++-scopes, bug 259373.

This commit is contained in:
Markus Schorn 2009-01-16 14:55:08 +00:00
parent 9bc3398966
commit c2436fcb02
34 changed files with 448 additions and 690 deletions

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2006, 2008 Wind River Systems, Inc. and others.
* Copyright (c) 2006, 2009 Wind River Systems, Inc. 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
@ -78,7 +78,7 @@ import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.core.parser.Keywords;
import org.eclipse.cdt.core.parser.ParseError;
import org.eclipse.cdt.core.parser.ast.ASTAccessVisibility;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguousDeclaration;
import org.eclipse.cdt.internal.core.dom.parser.ASTQueries;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
@ -322,8 +322,6 @@ public class CModelBuilder2 implements IContributedModelBuilder {
// TODO [cmodel] asm declaration?
} else if (declaration instanceof IASTProblemDeclaration) {
// TODO [cmodel] problem declaration?
} else if (declaration instanceof IASTAmbiguousDeclaration) {
// TODO [cmodel] ambiguous declaration?
} else {
assert false : "TODO: " + declaration.getClass().getName(); //$NON-NLS-1$
}
@ -467,7 +465,7 @@ public class CModelBuilder2 implements IContributedModelBuilder {
if (declSpecifier.getStorageClass() == IASTDeclSpecifier.sc_typedef) {
return createTypeDef(parent, declSpecifier, declarator);
}
IASTDeclarator typeRelevant= CPPVisitor.findTypeRelevantDeclarator(declarator);
IASTDeclarator typeRelevant= ASTQueries.findTypeRelevantDeclarator(declarator);
if (typeRelevant instanceof IASTFunctionDeclarator) {
return createFunctionDeclaration(parent, declSpecifier, (IASTFunctionDeclarator)typeRelevant, isTemplate);
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2008 Wind River Systems, Inc. and others.
* Copyright (c) 2008, 2009 Wind River Systems, Inc. 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
@ -19,8 +19,8 @@ import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression;
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.IType;
import org.eclipse.cdt.internal.core.dom.parser.ASTAmbiguousNode.NameCollector;
import org.eclipse.cdt.internal.core.dom.parser.c.CVisitor;
import org.eclipse.core.runtime.Assert;
@ -28,7 +28,7 @@ import org.eclipse.core.runtime.Assert;
* Handles the ambiguity between a binary- and a cast-expression. (type)+var versus (var)+var.
* It also handles the impact on the grouping of the sub-expressions.
*/
public abstract class ASTAmbiguousBinaryVsCastExpression extends ASTNode implements IASTAmbiguousExpression {
public abstract class ASTAmbiguousBinaryVsCastExpression extends ASTAmbiguousNode implements IASTAmbiguousExpression {
private final IASTBinaryExpression fBinaryExpression;
private final IASTCastExpression fCastExpression;
@ -43,6 +43,10 @@ public abstract class ASTAmbiguousBinaryVsCastExpression extends ASTNode impleme
fBinaryExpression= binaryExpression;
fCastExpression= castExpression;
}
public final IASTExpression copy() {
throw new UnsupportedOperationException();
}
public void addExpression(IASTExpression e) {
Assert.isLegal(false);
@ -52,12 +56,22 @@ public abstract class ASTAmbiguousBinaryVsCastExpression extends ASTNode impleme
return CVisitor.getExpressionType(getExpressions()[0]);
}
@Override
protected final IScope getAffectedScope() {
return null;
}
@Override
public final IASTNode[] getNodes() {
return getExpressions();
}
public IASTExpression[] getExpressions() {
return new IASTExpression[] {fBinaryExpression, fCastExpression};
}
@Override
public boolean accept(ASTVisitor visitor) {
public final IASTNode resolveAmbiguity(ASTVisitor visitor) {
final IASTAmbiguityParent owner= (IASTAmbiguityParent) getParent();
IASTNode nodeToReplace= this;
@ -91,7 +105,7 @@ public abstract class ASTAmbiguousBinaryVsCastExpression extends ASTNode impleme
}
}
if (hasIssue) {
return true;
return nodeToReplace;
}
final IASTExpression left = fBinaryExpression.getOperand1();
@ -109,12 +123,11 @@ public abstract class ASTAmbiguousBinaryVsCastExpression extends ASTNode impleme
setRange(fCastExpression, primaryInParenthesis, leadingCastExpression);
IASTExpression root= joinExpressions(lp, fCastExpression, rp);
if (root != null) {
owner.replace(nodeToReplace, root);
return true;
return root;
}
}
return true;
return nodeToReplace;
}
private void setEnd(IASTNode node, IASTNode end) {

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2008 Wind River Systems, Inc. and others.
* Copyright (c) 2008, 2009 Wind River Systems, Inc. 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
@ -21,8 +21,8 @@ import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression;
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.IType;
import org.eclipse.cdt.internal.core.dom.parser.ASTAmbiguousNode.NameCollector;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.core.runtime.Assert;
@ -30,7 +30,7 @@ import org.eclipse.core.runtime.Assert;
* Handles the ambiguity between cast and function-call expressions: (type)(expr) versus (function)(expr);
* It also handles the impact on the grouping of the sub-expressions.
*/
public abstract class ASTAmbiguousCastVsFunctionCallExpression extends ASTNode implements IASTAmbiguousExpression {
public abstract class ASTAmbiguousCastVsFunctionCallExpression extends ASTAmbiguousNode implements IASTAmbiguousExpression {
private final IASTCastExpression fCastExpression;
private final IASTFunctionCallExpression fFunctionCallExpression;
@ -46,7 +46,17 @@ public abstract class ASTAmbiguousCastVsFunctionCallExpression extends ASTNode i
fFunctionCallExpression= functionCall;
}
public IASTExpression copy() {
@Override
protected final IScope getAffectedScope() {
return null;
}
@Override
public final IASTNode[] getNodes() {
return getExpressions();
}
public final IASTExpression copy() {
throw new UnsupportedOperationException();
}
@ -63,7 +73,7 @@ public abstract class ASTAmbiguousCastVsFunctionCallExpression extends ASTNode i
}
@Override
public boolean accept(ASTVisitor visitor) {
public final IASTNode resolveAmbiguity(ASTVisitor visitor) {
final IASTAmbiguityParent owner= (IASTAmbiguityParent) getParent();
IASTNode nodeToReplace= this;
@ -76,7 +86,7 @@ public abstract class ASTAmbiguousCastVsFunctionCallExpression extends ASTNode i
// if the operand of the cast-expr is not suitable for a function call, we are done.
final IASTUnaryExpression primaryWithParenthesis= findPrimaryExpressionInParenthesis(fCastExpression.getOperand());
if (primaryWithParenthesis == null)
return true;
return nodeToReplace;
// find nested names
@ -99,7 +109,7 @@ public abstract class ASTAmbiguousCastVsFunctionCallExpression extends ASTNode i
}
}
if (!hasIssue)
return true;
return nodeToReplace;
fFunctionCallExpression.setParameterExpression(primaryWithParenthesis.getOperand());
setRange(fFunctionCallExpression, fCastExpression, primaryWithParenthesis);
@ -145,7 +155,7 @@ public abstract class ASTAmbiguousCastVsFunctionCallExpression extends ASTNode i
owner.replace(nodeToReplace, result);
// resolve ambiguities in the function-call expression
fFunctionCallExpression.getFunctionNameExpression().accept(visitor);
return true;
return result;
}
private IASTUnaryExpression findPrimaryExpressionInParenthesis(IASTExpression operand) {

View file

@ -12,10 +12,11 @@
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.IASTDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IProblemBinding;
import org.eclipse.cdt.core.dom.ast.IScope;
@ -54,7 +55,7 @@ public abstract class ASTAmbiguousNode extends ASTNode {
/**
* Return the alternative nodes for this ambiguity.
*/
protected abstract IASTNode[] getNodes();
public abstract IASTNode[] getNodes();
/**
* Returns the scope that may get polluted by alternatives of this ambiguity.
@ -70,7 +71,11 @@ public abstract class ASTAmbiguousNode extends ASTNode {
return true;
}
public void resolveAmbiguity(ASTVisitor resolver) {
protected void beforeResolution() {
}
public IASTNode resolveAmbiguity(ASTVisitor resolver) {
beforeResolution();
final IScope scope= getAffectedScope();
final IASTAmbiguityParent owner= (IASTAmbiguityParent) getParent();
IASTNode nodeToReplace= this;
@ -82,12 +87,7 @@ public abstract class ASTAmbiguousNode extends ASTNode {
for (IASTNode alternative : alternatives) {
// flush scope, even if this is the first alternative. The ambiguous node may have contributed an
// invalid binding to the scope during the resolution of other ambiguous nodes.
if (scope instanceof IASTInternalScope) {
try {
((IASTInternalScope) scope).flushCache();
} catch (DOMException e) {
}
}
ASTInternal.flushCache(scope);
// setup the ast to use the alternative
owner.replace(nodeToReplace, alternative);
@ -105,6 +105,18 @@ public abstract class ASTAmbiguousNode extends ASTNode {
int issues= 0;
for (IASTName name : names) {
try {
// avoid resolution of parameters (can always be resolved),
// it can triggers resolution of declaration it belongs to,
// while the declarator is still ambiguous. Could be solved by introducing an
// intermediate binding for parameters, similar to template parameters.
if (name.getPropertyInParent() == IASTDeclarator.DECLARATOR_NAME) {
IASTNode parent= name.getParent();
if (parent instanceof IASTDeclarator) {
parent= ASTQueries.findOutermostDeclarator((IASTDeclarator) parent);
if (parent.getPropertyInParent() == IASTParameterDeclaration.DECLARATOR)
continue;
}
}
IBinding b= name.resolvePreBinding();
if (b instanceof IProblemBinding) {
issues++;
@ -133,13 +145,9 @@ public abstract class ASTAmbiguousNode extends ASTNode {
// switch back to the best alternative, if necessary.
if (nodeToReplace != bestAlternative) {
if (scope instanceof IASTInternalScope) {
try {
((IASTInternalScope) scope).flushCache();
} catch (DOMException e) {
}
}
ASTInternal.flushCache(scope);
owner.replace(nodeToReplace, bestAlternative);
}
return bestAlternative;
}
}

View file

@ -43,9 +43,9 @@ public class ASTInternal {
return null;
}
public static void flushCache(IScope scope) throws DOMException {
if (scope instanceof IASTInternalScope) {
((IASTInternalScope) scope).flushCache();
public static void flushCache(IScope scope) {
if (scope instanceof CScope) {
((CScope) scope).flushCache();
}
}
@ -74,9 +74,13 @@ public class ASTInternal {
}
}
public static void addName(IScope scope, IASTName name) throws DOMException {
public static void addName(IScope scope, IASTName name) {
if (scope instanceof IASTInternalScope) {
((IASTInternalScope) scope).addName(name);
try {
((IASTInternalScope) scope).addName(name);
} catch (DOMException e) {
// name is not cached in scope
}
}
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2008 Wind River Systems, Inc. and others.
* Copyright (c) 2008, 2009 Wind River Systems, Inc. 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
@ -10,13 +10,18 @@
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser;
import org.eclipse.cdt.core.dom.ast.IASTArrayModifier;
import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression;
import org.eclipse.cdt.core.dom.ast.IASTCastExpression;
import org.eclipse.cdt.core.dom.ast.IASTConditionalExpression;
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTExpressionList;
import org.eclipse.cdt.core.dom.ast.IASTFieldDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
import org.eclipse.cdt.core.dom.ast.IASTLiteralExpression;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression;
import org.eclipse.cdt.internal.core.dom.parser.c.CVisitor;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
@ -63,4 +68,50 @@ public class ASTQueries {
}
return true;
}
/**
* Returns the outermost declarator the given <code>declarator</code> nests within, or
* <code>declarator</code> itself.
*/
public static IASTDeclarator findOutermostDeclarator(IASTDeclarator declarator) {
IASTDeclarator outermost= null;
IASTNode candidate= declarator;
while (candidate instanceof IASTDeclarator) {
outermost= (IASTDeclarator) candidate;
candidate= outermost.getParent();
}
return outermost;
}
/**
* Returns the innermost declarator nested within the given <code>declarator</code>, or
* <code>declarator</code> itself.
*/
public static IASTDeclarator findInnermostDeclarator(IASTDeclarator declarator) {
IASTDeclarator innermost= null;
while (declarator != null) {
innermost= declarator;
declarator= declarator.getNestedDeclarator();
}
return innermost;
}
/**
* Searches for the innermost declarator that contributes the the type declared.
*/
public static IASTDeclarator findTypeRelevantDeclarator(IASTDeclarator declarator) {
IASTDeclarator result= findInnermostDeclarator(declarator);
while (result.getPointerOperators().length == 0
&& !(result instanceof IASTFieldDeclarator)
&& !(result instanceof IASTFunctionDeclarator)
&& !(result instanceof IASTArrayModifier)) {
final IASTNode parent= result.getParent();
if (parent instanceof IASTDeclarator) {
result= (IASTDeclarator) parent;
} else {
return result;
}
}
return result;
}
}

View file

@ -1,22 +0,0 @@
/*******************************************************************************
* Copyright (c) 2004, 2005 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
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser;
import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
public interface IASTAmbiguousDeclaration extends IASTDeclaration {
public static final ASTNodeProperty SUBDECLARATION = new ASTNodeProperty( "IASTAmbiguousDeclaration.SUBDECLARATION"); //$NON-NLS-1$
public void addDeclaration( IASTDeclaration d );
public IASTDeclaration [] getDeclarations();
}

View file

@ -1,27 +0,0 @@
/*******************************************************************************
* 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
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
/**
* @author jcamelon
* @deprecated there is no class that implements this interface. Use {@link IASTAmbiguousDeclaration}, instead.
*/
@Deprecated
public interface IASTDeclarationAmbiguity extends IASTDeclaration
{
public void addDeclaration( IASTDeclaration decl );
public IASTDeclaration [] getDeclarations();
}

View file

@ -24,13 +24,7 @@ public interface IASTInternalScope extends IScope {
* Return the physical IASTNode that this scope was created for
*/
public IASTNode getPhysicalNode() throws DOMException;
/**
* clear the name cache in this scope
* @throws DOMException
*/
public void flushCache() throws DOMException;
/**
* This adds an IBinding to the scope. It is primarily used by the parser to add
* implicit IBindings to the scope (such as GCC built-in functions).

View file

@ -200,9 +200,6 @@ public class ProblemBinding extends PlatformObject implements IProblemBinding, I
return type == this;
}
public void flushCache() {
}
public String getFileName() {
if (node != null)
return node.getContainingFilename();

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2008 Wind River Systems, Inc. and others.
* Copyright (c) 2008, 2009 Wind River Systems, Inc. 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
@ -12,7 +12,6 @@ package org.eclipse.cdt.internal.core.dom.parser.c;
import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression;
import org.eclipse.cdt.core.dom.ast.IASTCastExpression;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.internal.core.dom.parser.ASTAmbiguousBinaryVsCastExpression;
public class CASTAmbiguousBinaryVsCastExpression extends ASTAmbiguousBinaryVsCastExpression {
@ -20,8 +19,4 @@ public class CASTAmbiguousBinaryVsCastExpression extends ASTAmbiguousBinaryVsCas
public CASTAmbiguousBinaryVsCastExpression(IASTBinaryExpression binaryExpr, IASTCastExpression castExpr) {
super(binaryExpr, castExpr);
}
public IASTExpression copy() {
throw new UnsupportedOperationException();
}
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2008 IBM Wind River Systems, Inc. and others.
* Copyright (c) 2008, 2009 IBM Wind River Systems, Inc. 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
@ -54,7 +54,7 @@ public class CASTAmbiguousDeclarator extends CASTAmbiguity implements IASTAmbigu
}
@Override
protected IASTNode[] getNodes() {
public IASTNode[] getNodes() {
return getDeclarators();
}

View file

@ -1,13 +1,13 @@
/*******************************************************************************
* Copyright (c) 2004, 2008 IBM Corporation and others.
* Copyright (c) 2004, 2009 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)
* IBM - Initial API and implementation
* Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.c;
@ -50,7 +50,7 @@ public class CASTAmbiguousExpression extends CASTAmbiguity implements IASTAmbigu
}
@Override
protected IASTNode[] getNodes() {
public IASTNode[] getNodes() {
return getExpressions();
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2008 IBM Wind River Systems, Inc. and others.
* Copyright (c) 2008, 2009 IBM Wind River Systems, Inc. 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
@ -50,7 +50,7 @@ public class CASTAmbiguousParameterDeclaration extends CASTAmbiguity implements
}
@Override
protected IASTNode[] getNodes() {
public IASTNode[] getNodes() {
return getParameterDeclarations();
}

View file

@ -1,13 +1,13 @@
/*******************************************************************************
* Copyright (c) 2004, 2008 IBM Corporation and others.
* Copyright (c) 2004, 2009 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)
* IBM - Initial API and implementation
* Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.c;
@ -44,7 +44,7 @@ public class CASTAmbiguousStatement extends CASTAmbiguity implements IASTAmbiguo
}
@Override
protected IASTNode[] getNodes() {
public IASTNode[] getNodes() {
return getStatements();
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2005, 2008 IBM Corporation and others.
* Copyright (c) 2005, 2009 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
@ -36,7 +36,6 @@ import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTExpressionList;
import org.eclipse.cdt.core.dom.ast.IASTExpressionStatement;
import org.eclipse.cdt.core.dom.ast.IASTFieldDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTFieldReference;
import org.eclipse.cdt.core.dom.ast.IASTForStatement;
import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression;
@ -104,6 +103,7 @@ import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.core.parser.util.ObjectSet;
import org.eclipse.cdt.internal.core.dom.parser.ASTInternal;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.ASTQueries;
import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer;
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
import org.eclipse.core.runtime.CoreException;
@ -111,7 +111,7 @@ import org.eclipse.core.runtime.CoreException;
/**
* Collection of methods to find information in an AST.
*/
public class CVisitor {
public class CVisitor extends ASTQueries {
public static class ClearBindingAction extends CASTVisitor {
{
shouldVisitNames = true;
@ -530,10 +530,7 @@ public class CVisitor {
}
} else {
binding = new CEnumeration(name);
try {
ASTInternal.addName(scope, name);
} catch (DOMException e1) {
}
ASTInternal.addName(scope, name);
}
return binding;
}
@ -870,11 +867,9 @@ public class CVisitor {
if (declarator.getParent() instanceof IASTFunctionDefinition) {
IScope scope = ((IASTCompoundStatement)((IASTFunctionDefinition)declarator.getParent()).getBody()).getScope();
if (scope != null && binding != null)
try {
ASTInternal.addName(scope, name);
} catch (DOMException e) {
}
if (scope != null && binding != null) {
ASTInternal.addName(scope, name);
}
}
}
} else {
@ -889,8 +884,8 @@ public class CVisitor {
parent = parent.getParent();
}
declarator= CVisitor.findInnermostDeclarator(declarator);
IASTDeclarator typeRelevant= CVisitor.findTypeRelevantDeclarator(declarator);
declarator= ASTQueries.findInnermostDeclarator(declarator);
IASTDeclarator typeRelevant= ASTQueries.findTypeRelevantDeclarator(declarator);
IASTFunctionDeclarator funcDeclarator= null;
if (typeRelevant instanceof IASTFunctionDeclarator) {
funcDeclarator= (IASTFunctionDeclarator) typeRelevant;
@ -977,11 +972,9 @@ public class CVisitor {
}
}
if (scope != null && binding != null)
try {
ASTInternal.addName(scope, name);
} catch (DOMException e) {
}
if (scope != null && binding != null) {
ASTInternal.addName(scope, name);
}
return binding;
}
@ -1196,7 +1189,7 @@ public class CVisitor {
scope = getContainingScope((IASTStatement)parent);
} else if (parent instanceof IASTFunctionDefinition) {
IASTFunctionDeclarator fnDeclarator = ((IASTFunctionDefinition) parent).getDeclarator();
IBinding function = CVisitor.findInnermostDeclarator(fnDeclarator).getName().resolveBinding();
IBinding function = ASTQueries.findInnermostDeclarator(fnDeclarator).getName().resolveBinding();
try {
if (function instanceof IFunction) {
scope = ((IFunction)function).getFunctionScope();
@ -1596,7 +1589,7 @@ public class CVisitor {
IASTSimpleDeclaration simpleDeclaration = (IASTSimpleDeclaration) declaration;
IASTDeclarator[] declarators = simpleDeclaration.getDeclarators();
for (IASTDeclarator declarator : declarators) {
declarator= CVisitor.findInnermostDeclarator(declarator);
declarator= ASTQueries.findInnermostDeclarator(declarator);
tempName = declarator.getName();
if (scope != null)
ASTInternal.addName(scope, tempName);
@ -1616,7 +1609,7 @@ public class CVisitor {
} else if (!typesOnly && declaration instanceof IASTFunctionDefinition) {
IASTFunctionDefinition functionDef = (IASTFunctionDefinition) declaration;
IASTDeclarator dtor = CVisitor.findInnermostDeclarator(functionDef.getDeclarator());
IASTDeclarator dtor = ASTQueries.findInnermostDeclarator(functionDef.getDeclarator());
tempName = dtor.getName();
if (scope != null)
ASTInternal.addName(scope, tempName);
@ -1675,7 +1668,7 @@ public class CVisitor {
if (node instanceof IASTFunctionDefinition && decl instanceof IASTFunctionDeclarator) {
IASTFunctionDeclarator dtor = ((IASTFunctionDefinition) node).getDeclarator();
IASTName name = CVisitor.findInnermostDeclarator(dtor).getName();
IASTName name = ASTQueries.findInnermostDeclarator(dtor).getName();
if (name.toString().equals(declName)) {
return dtor;
}
@ -2135,57 +2128,6 @@ public class CVisitor {
return true;
}
/**
* Returns the innermost declarator nested within the given <code>declarator</code>, or
* <code>declarator</code> itself.
* @since 5.0
*/
public static IASTDeclarator findInnermostDeclarator(IASTDeclarator declarator) {
IASTDeclarator innermost= null;
while(declarator != null) {
innermost= declarator;
declarator= declarator.getNestedDeclarator();
}
return innermost;
}
/**
* Returns the outermost declarator the given <code>declarator</code> nests within, or
* <code>declarator</code> itself.
* @since 5.0
*/
public static IASTDeclarator findOutermostDeclarator(IASTDeclarator declarator) {
IASTDeclarator outermost= null;
IASTNode candidate= declarator;
while(candidate instanceof IASTDeclarator) {
outermost= (IASTDeclarator) candidate;
candidate= outermost.getParent();
}
return outermost;
}
/**
* Searches for the innermost declarator that contributes the the type declared.
* @since 5.0
*/
public static IASTDeclarator findTypeRelevantDeclarator(IASTDeclarator declarator) {
IASTDeclarator result= findInnermostDeclarator(declarator);
while (result.getPointerOperators().length == 0
&& result instanceof IASTFieldDeclarator == false
&& result instanceof IASTFunctionDeclarator == false
&& result instanceof IASTArrayModifier == false) {
final IASTNode parent= result.getParent();
if (parent instanceof IASTDeclarator) {
result= (IASTDeclarator) parent;
} else {
return result;
}
}
return result;
}
/**
* Searches for the function enclosing the given node. May return <code>null</code>.
*/

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2004, 2008 IBM Corporation and others.
* Copyright (c) 2004, 2009 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
@ -13,12 +13,10 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.IScope;
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 ASTAmbiguousNode {
@Override
protected IScope getAffectedScope() {
return CPPVisitor.getContainingScope(this);
return null;
}
}

View file

@ -11,17 +11,24 @@
package org.eclipse.cdt.internal.core.dom.parser.cpp;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
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;
import org.eclipse.cdt.core.dom.ast.IASTInitializer;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
import org.eclipse.cdt.internal.core.dom.parser.ASTAmbiguousNode;
import org.eclipse.cdt.internal.core.dom.parser.ASTQueries;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
/**
@ -42,7 +49,8 @@ public final class CPPASTAmbiguityResolver extends ASTVisitor {
}
private LinkedList<ClassContext> fContextStack;
private ClassContext fCurrentContext;
private boolean fSkipInitializers;
private int fSkipInitializers= 0;
private HashSet<IASTDeclaration> fRepopulate= new HashSet<IASTDeclaration>();
public CPPASTAmbiguityResolver() {
super(false);
@ -54,7 +62,21 @@ public final class CPPASTAmbiguityResolver extends ASTVisitor {
@Override
public int visit(ASTAmbiguousNode astAmbiguousNode) {
astAmbiguousNode.resolveAmbiguity(this);
IASTNode node= astAmbiguousNode.resolveAmbiguity(this);
if (node instanceof IASTDeclarator) {
while(node != null) {
if (node instanceof IASTDeclaration) {
fRepopulate.add((IASTDeclaration) node);
break;
}
if (node instanceof IASTExpression) {
break;
}
node= node.getParent();
}
} else if (node instanceof IASTDeclarationStatement) {
repopulateScope(((IASTDeclarationStatement) node).getDeclaration());
}
return PROCESS_SKIP;
}
@ -119,9 +141,9 @@ public final class CPPASTAmbiguityResolver extends ASTVisitor {
// visit the declarator first, it may contain ambiguous template arguments needed
// for associating the template declarations.
fSkipInitializers= true;
CPPVisitor.findOutermostDeclarator(fdef.getDeclarator()).accept(this);
fSkipInitializers= false;
fSkipInitializers++;
ASTQueries.findOutermostDeclarator(fdef.getDeclarator()).accept(this);
fSkipInitializers--;
if (fCurrentContext != null) {
// defer visiting the body of the function until the class body has been visited.
@ -133,9 +155,24 @@ public final class CPPASTAmbiguityResolver extends ASTVisitor {
return PROCESS_CONTINUE;
}
@Override
public int leave(IASTDeclaration declaration) {
if (fRepopulate.remove(declaration)) {
repopulateScope(declaration);
}
return PROCESS_CONTINUE;
}
private void repopulateScope(IASTDeclaration declaration) {
IScope scope= CPPVisitor.getContainingScope(declaration);
if (scope instanceof ICPPASTInternalScope) {
CPPSemantics.populateCache((ICPPASTInternalScope) scope, declaration, false);
}
}
@Override
public int visit(IASTInitializer initializer) {
if (fSkipInitializers)
if (fSkipInitializers > 0)
return PROCESS_SKIP;
return PROCESS_CONTINUE;

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2008 Wind River Systems, Inc. and others.
* Copyright (c) 2008, 2009 Wind River Systems, Inc. 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
@ -12,7 +12,6 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression;
import org.eclipse.cdt.core.dom.ast.IASTCastExpression;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.internal.core.dom.parser.ASTAmbiguousBinaryVsCastExpression;
public class CPPASTAmbiguousBinaryVsCastExpression extends ASTAmbiguousBinaryVsCastExpression {
@ -20,8 +19,4 @@ public class CPPASTAmbiguousBinaryVsCastExpression extends ASTAmbiguousBinaryVsC
public CPPASTAmbiguousBinaryVsCastExpression(IASTBinaryExpression bexp, IASTCastExpression castExpr) {
super(bexp, castExpr);
}
public IASTExpression copy() {
throw new UnsupportedOperationException();
}
}

View file

@ -1,51 +0,0 @@
/*******************************************************************************
* 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
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguousDeclaration;
public class CPPASTAmbiguousDeclaration extends CPPASTAmbiguity implements IASTAmbiguousDeclaration {
@Override
protected IASTNode[] getNodes() {
return getDeclarations();
}
public IASTDeclaration copy() {
throw new UnsupportedOperationException();
}
private IASTDeclaration [] decls = new IASTDeclaration[2];
private int declsPos=-1;
public CPPASTAmbiguousDeclaration(IASTDeclaration... declarations) {
for(IASTDeclaration d : declarations)
addDeclaration(d);
}
public void addDeclaration(IASTDeclaration d) {
assertNotFrozen();
if (d != null) {
decls = (IASTDeclaration[]) ArrayUtil.append(IASTDeclaration.class, decls, ++declsPos, d );
d.setParent(this);
d.setPropertyInParent(SUBDECLARATION);
}
}
public IASTDeclaration[] getDeclarations() {
decls = (IASTDeclaration[]) ArrayUtil.removeNullsAfter( IASTDeclaration.class, decls, declsPos );
return decls;
}
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2008 IBM Wind River Systems, Inc. and others.
* Copyright (c) 2008, 2009 IBM Wind River Systems, Inc. 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
@ -15,15 +15,16 @@ 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.IScope;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguousDeclarator;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.core.runtime.Assert;
/**
* Handles ambiguities when parsing declarators.
* <br>
* Example: void f(int (D)); // is D a type?
* @since 5.0.1
*/
public class CPPASTAmbiguousDeclarator extends CPPASTAmbiguity implements IASTAmbiguousDeclarator {
@ -39,6 +40,15 @@ public class CPPASTAmbiguousDeclarator extends CPPASTAmbiguity implements IASTAm
}
}
@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();
}
}
public IASTDeclarator copy() {
throw new UnsupportedOperationException();
}
@ -58,7 +68,7 @@ public class CPPASTAmbiguousDeclarator extends CPPASTAmbiguity implements IASTAm
}
@Override
protected IASTNode[] getNodes() {
public IASTNode[] getNodes() {
return getDeclarators();
}

View file

@ -1,12 +1,13 @@
/*******************************************************************************
* Copyright (c) 2004, 2008 IBM Corporation and others.
* Copyright (c) 2004, 2009 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
* IBM - Initial API and implementation
* Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
@ -55,7 +56,7 @@ public class CPPASTAmbiguousExpression extends CPPASTAmbiguity implements
}
@Override
protected IASTNode[] getNodes() {
public IASTNode[] getNodes() {
return getExpressions();
}

View file

@ -1,19 +1,22 @@
/*******************************************************************************
* Copyright (c) 2004, 2008 IBM Corporation and others.
* Copyright (c) 2004, 2009 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
* IBM - Initial API and implementation
* Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
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.IASTAmbiguousStatement;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
public class CPPASTAmbiguousStatement extends CPPASTAmbiguity implements
IASTAmbiguousStatement {
@ -26,6 +29,15 @@ public class CPPASTAmbiguousStatement extends CPPASTAmbiguity implements
addStatement(s);
}
@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();
}
}
public IASTStatement copy() {
throw new UnsupportedOperationException();
}
@ -45,7 +57,7 @@ public class CPPASTAmbiguousStatement extends CPPASTAmbiguity implements
}
@Override
protected IASTNode[] getNodes() {
public IASTNode[] getNodes() {
return getStatements();
}
}

View file

@ -1,12 +1,13 @@
/*******************************************************************************
* Copyright (c) 2008 Symbian Software Systems and others.
* Copyright (c) 2008, 2009 Symbian Software Systems 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:
* Andrew Ferguson (Symbian) - Initial Implementation
* Andrew Ferguson (Symbian) - Initial Implementation
* Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
@ -60,7 +61,7 @@ public class CPPASTAmbiguousTemplateArgument extends CPPASTAmbiguity implements
}
@Override
protected IASTNode[] getNodes() {
public IASTNode[] getNodes() {
return fNodes.toArray(new IASTNode[fNodes.size()]);
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2004, 2008 IBM Corporation and others.
* Copyright (c) 2004, 2009 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
@ -55,6 +55,10 @@ public class CPPASTTranslationUnit extends ASTTranslationUnit implements ICPPAST
return copy;
}
@Override
public void cleanupAfterAmbiguityResolution() {
}
public CPPNamespaceScope getScope() {
if (fScope == null) {
fScope = new CPPNamespaceScope(this);

View file

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

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2004, 2008 IBM Corporation and others.
* Copyright (c) 2004, 2009 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
@ -130,10 +130,4 @@ public class CPPFunctionScope extends CPPScope implements ICPPFunctionScope {
}
return null;
}
@Override
public void flushCache() {
labels.clear();
super.flushCache();
}
}

View file

@ -59,6 +59,9 @@ abstract public class CPPScope implements ICPPScope, ICPPASTInternalScope {
public CPPScopeProblem(IASTNode node, int id, char[] arg) {
super(node, id, arg);
}
public CPPScopeProblem(IASTName name, int id) {
super(name, id);
}
}
public CPPScope(IASTNode physicalNode) {
@ -282,13 +285,9 @@ abstract public class CPPScope implements ICPPScope, ICPPASTInternalScope {
return result;
}
protected void populateCache() {
public final void populateCache() {
if (!isCached) {
try {
CPPSemantics.lookupInScope(null, this, null);
} catch (DOMException e) {
CCorePlugin.log(e);
}
CPPSemantics.populateCache(this);
isCached= true;
}
}
@ -300,49 +299,6 @@ abstract public class CPPScope implements ICPPScope, ICPPASTInternalScope {
return CPPSemantics.findBindings(this, name, false);
}
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;
}
isCached = false;
}
@SuppressWarnings("unchecked")
public void addBinding(IBinding binding) {
if (bindings == null)

View file

@ -174,12 +174,6 @@ public class CPPUnknownScope implements ICPPScope, ICPPInternalUnknownScope {
return new IBinding[] {getBinding(name, resolve, acceptLocalBindings)};
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IScope#flushCache()
*/
public void flushCache() {
}
public void addBinding(IBinding binding) {
// do nothing, this is part of template magic and not a normal scope
}
@ -198,4 +192,6 @@ public class CPPUnknownScope implements ICPPScope, ICPPInternalUnknownScope {
public String toString() {
return scopeName.toString();
}
public void populateCache() {}
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2008 Wind River Systems, Inc. and others.
* Copyright (c) 2008, 2009 Wind River Systems, Inc. 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
@ -14,13 +14,14 @@ import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope;
import org.eclipse.cdt.core.index.IIndexFileSet;
import org.eclipse.cdt.internal.core.dom.parser.IASTInternalScope;
/**
* Interface for internal c++ scopes
*/
public interface ICPPASTInternalScope extends IASTInternalScope {
public interface ICPPASTInternalScope extends IASTInternalScope, ICPPScope {
/**
* Same as {@link IScope#getBindings(IASTName, boolean, boolean, IIndexFileSet)} with the
* possibility to disable checking the point of declaration. The method is used to resolve
@ -28,5 +29,11 @@ public interface ICPPASTInternalScope extends IASTInternalScope {
*/
public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup,
IIndexFileSet acceptLocalBindings, boolean checkPointOfDecl) throws DOMException;
/**
* Can be called during ambiguity resolution to populate a scope without considering
* the ambiguous branches. The rest of the names has to be cached one by one after
* the ambiguities have been resolved.
*/
public void populateCache();
}

View file

@ -44,6 +44,7 @@ import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
import org.eclipse.cdt.core.dom.ast.IASTInitializer;
import org.eclipse.cdt.core.dom.ast.IASTInitializerExpression;
import org.eclipse.cdt.core.dom.ast.IASTLabelStatement;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNameOwner;
import org.eclipse.cdt.core.dom.ast.IASTNamedTypeSpecifier;
@ -126,11 +127,12 @@ import org.eclipse.cdt.core.index.IIndexBinding;
import org.eclipse.cdt.core.index.IIndexFileSet;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.core.parser.util.CharArrayObjectMap;
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.core.parser.util.DebugUtil;
import org.eclipse.cdt.core.parser.util.ObjectSet;
import org.eclipse.cdt.internal.core.dom.parser.ASTInternal;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.ASTQueries;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguousDeclarator;
import org.eclipse.cdt.internal.core.dom.parser.IASTInternalScope;
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTFieldReference;
@ -151,6 +153,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownFunction;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUsingDeclaration;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUsingDirective;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVariable;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPASTInternalScope;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalUnknownScope;
@ -583,7 +586,7 @@ public class CPPSemantics {
return new CPPScope.CPPScopeProblem(((IProblemBinding) scope).getASTNode(),
IProblemBinding.SEMANTIC_BAD_SCOPE, ((IProblemBinding)scope).getNameCharArray());
}
return new CPPScope.CPPScopeProblem(name, IProblemBinding.SEMANTIC_BAD_SCOPE, name.toCharArray());
return new CPPScope.CPPScopeProblem(name, IProblemBinding.SEMANTIC_BAD_SCOPE);
}
private static void mergeResults(LookupData data, Object results, boolean scoped) {
@ -1124,27 +1127,18 @@ public class CPPSemantics {
return (ICPPScope) parent;
}
/**
*
* @param data may be null to use a fresh LookupData
* @param scope
* @param blockItem
* @return List of encountered using directives
* @throws DOMException
*/
public static IASTName[] lookupInScope(LookupData data, ICPPScope scope, IASTNode blockItem) throws DOMException {
if (data == null) {
data = new LookupData();
}
final boolean isIndexBased= data.tu != null && data.tu.getIndex() != null;
Object possible = null;
public static void populateCache(ICPPASTInternalScope scope) {
IASTNode[] nodes = null;
IASTNode parent = ASTInternal.getPhysicalNodeOfScope(scope);
IASTNode parent;
try {
parent = ASTInternal.getPhysicalNodeOfScope(scope);
} catch (DOMException e) {
return;
}
IASTName[] namespaceDefs = null;
int namespaceIdx = -1;
IASTName[] found = null;
if (parent instanceof IASTCompoundStatement) {
IASTNode p = parent.getParent();
if (p instanceof IASTFunctionDefinition) {
@ -1163,15 +1157,6 @@ public class CPPSemantics {
} else if (parent instanceof ICPPASTCompositeTypeSpecifier) {
ICPPASTCompositeTypeSpecifier comp = (ICPPASTCompositeTypeSpecifier) parent;
nodes = comp.getMembers();
// 9-2 a class name is also inserted into the scope of the class itself
IASTName n = comp.getName().getLastName();
if (n instanceof ICPPASTTemplateId) {
n= ((ICPPASTTemplateId) n).getTemplateName();
}
if (nameMatches(data, n, scope)) {
found = (IASTName[]) ArrayUtil.append(IASTName.class, found, n);
}
} else if (parent instanceof ICPPASTNamespaceDefinition) {
//need binding because namespaces can be split
CPPNamespace namespace = (CPPNamespace) ((ICPPASTNamespaceDefinition)parent).getName().resolveBinding();
@ -1182,14 +1167,13 @@ public class CPPSemantics {
}
} else if (parent instanceof ICPPASTFunctionDeclarator) {
ICPPASTFunctionDeclarator dtor = (ICPPASTFunctionDeclarator) parent;
nodes = dtor.getParameters();
nodes = dtor.getParameters();
} else if (parent instanceof ICPPASTTemplateDeclaration) {
ICPPASTTemplateDeclaration template = (ICPPASTTemplateDeclaration) parent;
nodes = template.getTemplateParameters();
}
int idx = -1;
boolean checkWholeClassScope = (scope instanceof ICPPClassScope) && data.checkWholeClassScope;
IASTNode item = (nodes != null ? (nodes.length > 0 ? nodes[++idx] : null) : parent);
IASTNode[][] nodeStack = null;
int[] nodeIdxStack = null;
@ -1206,48 +1190,33 @@ public class CPPSemantics {
continue;
}
}
if (item instanceof IASTLabelStatement)
item= ((IASTLabelStatement) item).getNestedStatement();
if (item instanceof IASTDeclarationStatement)
item = ((IASTDeclarationStatement)item).getDeclaration();
if (item instanceof ICPPASTUsingDirective) {
if (scope instanceof ICPPNamespaceScope) {
final ICPPNamespaceScope nsscope = (ICPPNamespaceScope)scope;
final ICPPASTUsingDirective usingDirective = (ICPPASTUsingDirective) item;
nsscope.addUsingDirective(new CPPUsingDirective(usingDirective));
try {
nsscope.addUsingDirective(new CPPUsingDirective(usingDirective));
} catch (DOMException e) {
// directive is not cached.
}
}
} else if (item instanceof ICPPASTNamespaceDefinition &&
((ICPPASTNamespaceDefinition)item).getName().getLookupKey().length == 0) {
if (scope instanceof ICPPNamespaceScope) {
final ICPPNamespaceScope nsscope = (ICPPNamespaceScope)scope;
final ICPPASTNamespaceDefinition nsdef= (ICPPASTNamespaceDefinition) item;
nsscope.addUsingDirective(new CPPUsingDirective(nsdef));
try {
nsscope.addUsingDirective(new CPPUsingDirective(nsdef));
} catch (DOMException e) {
// directive is not cached.
}
}
} else {
// possible is IASTName or IASTName[]
possible = collectResult(data, scope, item, (item == parent));
if (possible != null) {
int jdx = -1;
IASTName temp;
if (possible instanceof IASTName)
temp = (IASTName) possible;
else
temp = ((IASTName[])possible)[++jdx];
while (temp != null) {
if ((checkWholeClassScope || declaredBefore(temp, data.astName, isIndexBased)) &&
(item != blockItem || data.includeBlockItem(item))) {
if (data.considerConstructors ||
!(temp.getParent() instanceof IASTDeclarator &&
CPPVisitor.isConstructor(scope, (IASTDeclarator) temp.getParent()))) {
found = (IASTName[]) ArrayUtil.append(IASTName.class, found, temp);
}
}
if (++jdx > 0 && jdx < ((IASTName[])possible).length)
temp = ((IASTName[])possible)[jdx];
else
temp = null;
}
}
populateCache(scope, item, (item == parent));
}
if (nodes != null && ++idx < nodes.length) {
@ -1298,8 +1267,139 @@ public class CPPSemantics {
}
}
}
}
return found;
public static void populateCache(ICPPASTInternalScope scope, IASTNode node, boolean checkAux) {
IASTDeclaration declaration = null;
if (node instanceof ICPPASTTemplateDeclaration) {
declaration = ((ICPPASTTemplateDeclaration)node).getDeclaration();
} else if (node instanceof IASTDeclaration) {
declaration = (IASTDeclaration) node;
} else if (node instanceof IASTDeclarationStatement) {
declaration = ((IASTDeclarationStatement)node).getDeclaration();
} else if (node instanceof ICPPASTCatchHandler) {
declaration = ((ICPPASTCatchHandler)node).getDeclaration();
} else if (node instanceof ICPPASTForStatement && checkAux) {
ICPPASTForStatement forStatement = (ICPPASTForStatement) node;
if (forStatement.getConditionDeclaration() == null) {
if (forStatement.getInitializerStatement() instanceof IASTDeclarationStatement)
declaration = ((IASTDeclarationStatement)forStatement.getInitializerStatement()).getDeclaration();
} else {
if (forStatement.getInitializerStatement() instanceof IASTDeclarationStatement) {
populateCache(scope, forStatement.getInitializerStatement(), checkAux);
}
declaration = forStatement.getConditionDeclaration();
}
} else if (node instanceof ICPPASTSwitchStatement) {
declaration = ((ICPPASTSwitchStatement)node).getControllerDeclaration();
} else if (node instanceof ICPPASTIfStatement) {
declaration = ((ICPPASTIfStatement)node).getConditionDeclaration();
} else if (node instanceof ICPPASTWhileStatement) {
declaration = ((ICPPASTWhileStatement)node).getConditionDeclaration();
} else if (node instanceof IASTParameterDeclaration) {
IASTParameterDeclaration parameterDeclaration = (IASTParameterDeclaration) node;
IASTDeclarator dtor = parameterDeclaration.getDeclarator();
IASTDeclarator innermost= dtor;
while (dtor != null) {
if (dtor instanceof IASTAmbiguousDeclarator)
return;
innermost= dtor;
dtor= dtor.getNestedDeclarator();
}
if (innermost != null) { // could be null when content assist in the declSpec
IASTName declName = innermost.getName();
ASTInternal.addName(scope, declName);
return;
}
} else if (node instanceof ICPPASTTemplateParameter) {
IASTName name = CPPTemplates.getTemplateParameterName((ICPPASTTemplateParameter) node);
ASTInternal.addName(scope, name);
return;
}
if (declaration == null)
return;
if (declaration instanceof IASTSimpleDeclaration) {
IASTSimpleDeclaration simpleDeclaration = (IASTSimpleDeclaration) declaration;
ICPPASTDeclSpecifier declSpec = (ICPPASTDeclSpecifier) simpleDeclaration.getDeclSpecifier();
IASTDeclarator[] declarators = simpleDeclaration.getDeclarators();
if (!declSpec.isFriend()) {
for (IASTDeclarator declarator : declarators) {
IASTDeclarator innermost= null;
while (declarator != null) {
if (declarator instanceof IASTAmbiguousDeclarator) {
innermost= null;
break;
}
innermost= declarator;
declarator= declarator.getNestedDeclarator();
}
if (innermost != null) {
IASTName declaratorName = innermost.getName();
ASTInternal.addName(scope, declaratorName);
}
}
}
// declSpec
IASTName specName = null;
if (declSpec instanceof IASTElaboratedTypeSpecifier) {
specName = ((IASTElaboratedTypeSpecifier)declSpec).getName();
} else if (declSpec instanceof ICPPASTCompositeTypeSpecifier) {
ICPPASTCompositeTypeSpecifier compSpec = (ICPPASTCompositeTypeSpecifier) declSpec;
specName = compSpec.getName();
// anonymous union? //GCC supports anonymous structs too
if (declarators.length == 0 && /*compSpec.getKey() == IASTCompositeTypeSpecifier.k_union &&*/
specName.getLookupKey().length == 0) {
IASTDeclaration[] decls = compSpec.getMembers();
for (IASTDeclaration decl : decls) {
populateCache(scope, decl, checkAux);
}
}
} else if (declSpec instanceof IASTEnumerationSpecifier) {
IASTEnumerationSpecifier enumeration = (IASTEnumerationSpecifier) declSpec;
specName = enumeration.getName();
// check enumerators too
IASTEnumerator[] list = enumeration.getEnumerators();
IASTName tempName;
for (IASTEnumerator enumerator : list) {
if (enumerator == null)
break;
tempName = enumerator.getName();
ASTInternal.addName(scope, tempName);
}
}
if (specName != null) {
if (!(specName instanceof ICPPASTQualifiedName)) {
ASTInternal.addName(scope, specName);
}
}
} else if (declaration instanceof ICPPASTUsingDeclaration) {
ICPPASTUsingDeclaration using = (ICPPASTUsingDeclaration) declaration;
IASTName name = using.getName();
if (name instanceof ICPPASTQualifiedName) {
name = ((ICPPASTQualifiedName) name).getLastName();
}
ASTInternal.addName(scope, name);
} else if (declaration instanceof ICPPASTNamespaceDefinition) {
IASTName namespaceName = ((ICPPASTNamespaceDefinition) declaration).getName();
ASTInternal.addName(scope, namespaceName);
} else if (declaration instanceof ICPPASTNamespaceAlias) {
IASTName alias = ((ICPPASTNamespaceAlias) declaration).getAlias();
ASTInternal.addName(scope, alias);
} else if (declaration instanceof IASTFunctionDefinition) {
IASTFunctionDefinition functionDef = (IASTFunctionDefinition) declaration;
if (!((ICPPASTDeclSpecifier) functionDef.getDeclSpecifier()).isFriend()) {
IASTFunctionDeclarator declarator = functionDef.getDeclarator();
// check the function itself
IASTName declName = ASTQueries.findInnermostDeclarator(declarator).getName();
ASTInternal.addName(scope, declName);
}
}
}
/**
@ -1346,221 +1446,6 @@ public class CPPSemantics {
}
}
static private Object collectResult(LookupData data, ICPPScope scope, IASTNode node, boolean checkAux) throws DOMException{
IASTName resultName = null;
IASTName[] resultArray = null;
IASTDeclaration declaration = null;
if (node instanceof ICPPASTTemplateDeclaration) {
declaration = ((ICPPASTTemplateDeclaration)node).getDeclaration();
} else if (node instanceof IASTDeclaration) {
declaration = (IASTDeclaration) node;
} else if (node instanceof IASTDeclarationStatement) {
declaration = ((IASTDeclarationStatement)node).getDeclaration();
} else if (node instanceof ICPPASTCatchHandler) {
declaration = ((ICPPASTCatchHandler)node).getDeclaration();
} else if (node instanceof ICPPASTForStatement && checkAux) {
ICPPASTForStatement forStatement = (ICPPASTForStatement) node;
if (forStatement.getConditionDeclaration() == null) {
if (forStatement.getInitializerStatement() instanceof IASTDeclarationStatement)
declaration = ((IASTDeclarationStatement)forStatement.getInitializerStatement()).getDeclaration();
} else {
if (forStatement.getInitializerStatement() instanceof IASTDeclarationStatement) {
Object o = collectResult(data, scope, forStatement.getInitializerStatement(), checkAux);
if (o instanceof IASTName)
resultName = (IASTName) o;
else if (o instanceof IASTName[])
resultArray = (IASTName[]) o;
}
declaration = forStatement.getConditionDeclaration();
}
} else if (node instanceof ICPPASTSwitchStatement) {
declaration = ((ICPPASTSwitchStatement)node).getControllerDeclaration();
} else if (node instanceof ICPPASTIfStatement) {
declaration = ((ICPPASTIfStatement)node).getConditionDeclaration();
} else if (node instanceof ICPPASTWhileStatement) {
declaration = ((ICPPASTWhileStatement)node).getConditionDeclaration();
} else if (node instanceof IASTParameterDeclaration) {
IASTParameterDeclaration parameterDeclaration = (IASTParameterDeclaration) node;
IASTDeclarator dtor = parameterDeclaration.getDeclarator();
if (dtor != null) { // could be null when content assist in the declSpec
while (dtor.getNestedDeclarator() != null)
dtor = dtor.getNestedDeclarator();
IASTName declName = dtor.getName();
ASTInternal.addName(scope, declName);
if (!data.typesOnly && nameMatches(data, declName, scope)) {
return declName;
}
}
} else if (node instanceof ICPPASTTemplateParameter) {
IASTName name = CPPTemplates.getTemplateParameterName((ICPPASTTemplateParameter) node);
ASTInternal.addName(scope, name);
if (nameMatches(data, name, scope)) {
return name;
}
}
if (declaration == null)
return null;
if (declaration instanceof IASTSimpleDeclaration) {
IASTSimpleDeclaration simpleDeclaration = (IASTSimpleDeclaration) declaration;
ICPPASTDeclSpecifier declSpec = (ICPPASTDeclSpecifier) simpleDeclaration.getDeclSpecifier();
IASTDeclarator[] declarators = simpleDeclaration.getDeclarators();
if (!declSpec.isFriend()) {
for (IASTDeclarator declarator : declarators) {
declarator= CPPVisitor.findInnermostDeclarator(declarator);
IASTName declaratorName = declarator.getName();
ASTInternal.addName(scope, declaratorName);
if (!data.typesOnly || simpleDeclaration.getDeclSpecifier().getStorageClass() == IASTDeclSpecifier.sc_typedef) {
if (nameMatches(data, declaratorName, scope)) {
if (resultName == null)
resultName = declaratorName;
else if (resultArray == null)
resultArray = new IASTName[] { resultName, declaratorName };
else
resultArray = (IASTName[]) ArrayUtil.append(IASTName.class, resultArray, declaratorName);
}
}
}
}
//decl spec
IASTName specName = null;
if (declarators.length == 0 && declSpec instanceof IASTElaboratedTypeSpecifier) {
specName = ((IASTElaboratedTypeSpecifier)declSpec).getName();
} else if (declSpec instanceof ICPPASTCompositeTypeSpecifier) {
ICPPASTCompositeTypeSpecifier compSpec = (ICPPASTCompositeTypeSpecifier) declSpec;
specName = compSpec.getName();
// anonymous union? //GCC supports anonymous structs too
if (declarators.length == 0 && /*compSpec.getKey() == IASTCompositeTypeSpecifier.k_union &&*/
specName.getLookupKey().length == 0)
{
Object o = null;
IASTDeclaration[] decls = compSpec.getMembers();
for (IASTDeclaration decl : decls) {
o = collectResult(data, scope, decl, checkAux);
if (o instanceof IASTName) {
if (resultName == null)
resultName = (IASTName) o;
else if (resultArray == null)
resultArray = new IASTName[] { resultName, (IASTName) o };
else
resultArray = (IASTName[]) ArrayUtil.append(IASTName.class, resultArray, o);
} else if (o instanceof IASTName[]) {
IASTName[] oa = (IASTName[]) o;
if (resultName == null) {
resultName = oa[0];
resultArray = oa;
} else if (resultArray == null) {
resultArray = new IASTName[1 + oa.length];
resultArray[0] = resultName;
resultArray = (IASTName[]) ArrayUtil.addAll(IASTName.class, resultArray, oa);
} else {
resultArray = (IASTName[]) ArrayUtil.addAll(IASTName.class, resultArray, oa);
}
}
}
}
} else if (declSpec instanceof IASTEnumerationSpecifier) {
IASTEnumerationSpecifier enumeration = (IASTEnumerationSpecifier) declSpec;
specName = enumeration.getName();
// check enumerators too
IASTEnumerator[] list = enumeration.getEnumerators();
IASTName tempName;
for (IASTEnumerator enumerator : list) {
if (enumerator == null) break;
tempName = enumerator.getName();
ASTInternal.addName(scope, tempName);
if (!data.typesOnly && nameMatches(data, tempName, scope)) {
if (resultName == null)
resultName = tempName;
else if (resultArray == null)
resultArray = new IASTName[] { resultName, tempName };
else
resultArray = (IASTName[]) ArrayUtil.append(IASTName.class, resultArray, tempName);
}
}
}
if (specName != null) {
if (!(specName instanceof ICPPASTQualifiedName) ||
data.astName == ((ICPPASTQualifiedName) specName).getLastName()) {
ASTInternal.addName(scope, specName);
}
if (nameMatches(data, specName, scope)) {
if (resultName == null)
resultName = specName;
else if (resultArray == null)
resultArray = new IASTName[] { resultName, specName };
else
resultArray = (IASTName[]) ArrayUtil.append(IASTName.class, resultArray, specName);
}
}
} else if (declaration instanceof ICPPASTUsingDeclaration) {
ICPPASTUsingDeclaration using = (ICPPASTUsingDeclaration) declaration;
IASTName name = using.getName();
if (name instanceof ICPPASTQualifiedName) {
name = ((ICPPASTQualifiedName) name).getLastName();
}
ASTInternal.addName(scope, name);
if (nameMatches(data, name, scope)) {
return name;
}
} else if (declaration instanceof ICPPASTNamespaceDefinition) {
IASTName namespaceName = ((ICPPASTNamespaceDefinition) declaration).getName();
ASTInternal.addName(scope, namespaceName);
if (nameMatches(data, namespaceName, scope))
return namespaceName;
} else if (declaration instanceof ICPPASTNamespaceAlias) {
IASTName alias = ((ICPPASTNamespaceAlias) declaration).getAlias();
ASTInternal.addName(scope, alias);
if (nameMatches(data, alias, scope))
return alias;
} else if (declaration instanceof IASTFunctionDefinition) {
IASTFunctionDefinition functionDef = (IASTFunctionDefinition) declaration;
if (!((ICPPASTDeclSpecifier) functionDef.getDeclSpecifier()).isFriend()) {
IASTFunctionDeclarator declarator = functionDef.getDeclarator();
// check the function itself
IASTName declName = CPPVisitor.findInnermostDeclarator(declarator).getName();
ASTInternal.addName(scope, declName);
if (!data.typesOnly && nameMatches(data, declName, scope)) {
return declName;
}
}
}
if (resultArray != null)
return resultArray;
return resultName;
}
private static final boolean nameMatches(LookupData data, IASTName potential, IScope scope) throws DOMException{
final IASTName name = data.astName;
if (name == null)
return false;
if (potential instanceof ICPPASTQualifiedName) {
IASTNode phn= ASTInternal.getPhysicalNodeOfScope(scope);
if (phn instanceof ICPPASTCompositeTypeSpecifier == false && phn instanceof ICPPASTNamespaceDefinition == false)
return false;
// A qualified name implies the name actually belongs to a different scope, and should
// not be considered here, except the qualifier names the scope itself
final ICPPASTQualifiedName qname = (ICPPASTQualifiedName) potential;
if (scope instanceof CPPScope == false || ((CPPScope) scope).canDenoteScopeMember(qname))
return false;
potential= qname.getLastName();
}
char[] c = potential.getLookupKey();
char[] n = name.getLookupKey();
return (data.prefixLookup && CharArrayUtils.equals(c, 0, n.length, n, true))
|| (!data.prefixLookup && CharArrayUtils.equals(c, n));
}
private static void addDefinition(IBinding binding, IASTName name) {
if (binding instanceof IFunction) {
IASTNode node = name.getParent();
@ -2440,7 +2325,7 @@ public class CPPSemantics {
node = node.getParent();
}
IASTDeclarator dtor = ((IASTFunctionDefinition)node).getDeclarator();
dtor= CPPVisitor.findInnermostDeclarator(dtor);
dtor= ASTQueries.findInnermostDeclarator(dtor);
IBinding binding = dtor.getName().resolveBinding();
if (binding instanceof IFunction) {
try {
@ -2755,7 +2640,7 @@ public class CPPSemantics {
}
public static boolean isSameFunction(IFunction function, IASTDeclarator declarator) {
IASTName name = CPPVisitor.findInnermostDeclarator(declarator).getName();
IASTName name = ASTQueries.findInnermostDeclarator(declarator).getName();
ICPPASTTemplateDeclaration templateDecl = CPPTemplates.getTemplateDeclaration(name);
if (templateDecl != null) {
if (templateDecl instanceof ICPPASTTemplateSpecialization) {
@ -2767,7 +2652,7 @@ public class CPPSemantics {
}
}
declarator= CPPVisitor.findTypeRelevantDeclarator(declarator);
declarator= ASTQueries.findTypeRelevantDeclarator(declarator);
try {
if (declarator instanceof ICPPASTFunctionDeclarator) {
IType type = function.getType();

View file

@ -86,6 +86,7 @@ import org.eclipse.cdt.core.parser.util.CharArraySet;
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.core.parser.util.ObjectMap;
import org.eclipse.cdt.core.parser.util.ObjectSet;
import org.eclipse.cdt.internal.core.dom.parser.ASTAmbiguousNode;
import org.eclipse.cdt.internal.core.dom.parser.IASTInternalScope;
import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer;
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
@ -1112,7 +1113,7 @@ public class CPPTemplates {
private static boolean usesTemplateParameter(final ICPPASTTemplateId id, final CharArraySet names) {
final boolean[] result= {false};
ASTVisitor v= new ASTVisitor(false) {
{ shouldVisitNames= true;}
{ shouldVisitNames= true; shouldVisitAmbiguousNodes=true;}
@Override
public int visit(IASTName name) {
if (name instanceof ICPPASTTemplateId)
@ -1140,6 +1141,15 @@ public class CPPTemplates {
}
return PROCESS_CONTINUE;
}
@Override
public int visit(ASTAmbiguousNode node) {
IASTNode[] alternatives= node.getNodes();
for (IASTNode alt : alternatives) {
if (!alt.accept(this))
return PROCESS_ABORT;
}
return PROCESS_CONTINUE;
}
};
id.accept(v);
return result[0];

View file

@ -35,7 +35,6 @@ import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTExpressionList;
import org.eclipse.cdt.core.dom.ast.IASTExpressionStatement;
import org.eclipse.cdt.core.dom.ast.IASTFieldDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTFieldReference;
import org.eclipse.cdt.core.dom.ast.IASTForStatement;
import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression;
@ -315,7 +314,6 @@ public class CPPVisitor extends ASTQueries {
enumtor = scope.getBinding(enumerator.getName(), false);
if (enumtor == null || !(enumtor instanceof IEnumerator)) {
enumtor = new CPPEnumerator(enumerator.getName());
ASTInternal.addName(scope, enumerator.getName());
}
} catch (DOMException e) {
enumtor = e.getProblem();
@ -333,7 +331,6 @@ public class CPPVisitor extends ASTQueries {
enumeration = scope.getBinding(name, false);
if (enumeration == null || !(enumeration instanceof IEnumeration)) {
enumeration = new CPPEnumeration(name);
ASTInternal.addName(scope, name);
}
} catch (DOMException e) {
enumeration = e.getProblem();
@ -409,6 +406,7 @@ public class CPPVisitor extends ASTQueries {
binding = new CPPClassTemplate(name);
else
binding = new CPPClassType(name, binding);
// name may live in a different scope, so make sure to add it to the owner scope, as well.
ASTInternal.addName(scope, elabType.getName());
}
} else {
@ -451,9 +449,6 @@ public class CPPVisitor extends ASTQueries {
} else {
binding = new CPPClassType(name, binding);
}
if (scope != null) {
ASTInternal.addName(scope, compType.getName());
}
} else {
ICPPInternalBinding internal = (ICPPInternalBinding) binding;
if (internal.getDefinition() == null &&
@ -478,7 +473,6 @@ public class CPPVisitor extends ASTQueries {
if (!(binding instanceof ICPPInternalBinding) || binding instanceof IProblemBinding
|| !(binding instanceof ICPPNamespace)) {
binding = new CPPNamespace(namespaceDef);
ASTInternal.addName(scope, namespaceDef.getName());
}
} catch (DOMException e) {
binding = e.getProblem();
@ -501,7 +495,6 @@ public class CPPVisitor extends ASTQueries {
}
if (namespace instanceof ICPPNamespace) {
binding = new CPPNamespaceAlias(alias.getAlias(), (ICPPNamespace) namespace);
ASTInternal.addName(scope, alias.getAlias());
} else {
binding = new ProblemBinding(alias.getAlias(), IProblemBinding.SEMANTIC_NAME_NOT_FOUND);
}
@ -630,6 +623,7 @@ public class CPPVisitor extends ASTQueries {
// if we don't resolve the target type first, we get a problem binding in case the typedef
// redeclares the target type:
// typedef struct S S;
// mstodo this is a hack, remove it!
IType targetType= createType(declarator);
CPPTypedef td= new CPPTypedef(name);
td.setType(targetType);
@ -667,6 +661,10 @@ public class CPPVisitor extends ASTQueries {
} else {
binding = template ? (ICPPFunction) new CPPFunctionTemplate(name)
: new CPPFunction((ICPPASTFunctionDeclarator) funcDeclarator);
// friend functions may be declared in a different scope than the owner scope
if (simpleDecl != null && ((ICPPASTDeclSpecifier) simpleDecl.getDeclSpecifier()).isFriend()) {
ASTInternal.addName(scope, name);
}
}
} else if (parent instanceof IASTSimpleDeclaration) {
IType t1 = null, t2 = null;
@ -691,13 +689,6 @@ public class CPPVisitor extends ASTQueries {
}
}
if (scope != null && binding != null) {
try {
ASTInternal.addName(scope, name);
} catch (DOMException e1) {
}
}
return binding;
}
@ -799,7 +790,7 @@ public class CPPVisitor extends ASTQueries {
IASTNode parent = node.getParent();
if (parent instanceof ICPPASTFunctionDeclarator) {
ICPPASTFunctionDeclarator dtor = (ICPPASTFunctionDeclarator) parent;
if (CPPVisitor.findTypeRelevantDeclarator(dtor) == dtor) {
if (ASTQueries.findTypeRelevantDeclarator(dtor) == dtor) {
while (parent.getParent() instanceof IASTDeclarator)
parent = parent.getParent();
ASTNodeProperty prop = parent.getPropertyInParent();
@ -894,8 +885,7 @@ public class CPPVisitor extends ASTQueries {
public static IScope getContainingScope(IASTName name) {
IScope scope= getContainingScopeOrNull(name);
if (scope == null) {
return new CPPScope.CPPScopeProblem(name, IProblemBinding.SEMANTIC_BAD_SCOPE,
name == null ? CharArrayUtils.EMPTY : name.toCharArray());
return new CPPScope.CPPScopeProblem(name, IProblemBinding.SEMANTIC_BAD_SCOPE);
}
return scope;
@ -948,8 +938,7 @@ public class CPPVisitor extends ASTQueries {
}
if (done) {
if (scope == null) {
return new CPPScope.CPPScopeProblem(names[i - 1],
IProblemBinding.SEMANTIC_BAD_SCOPE, names[i-1].toCharArray());
return new CPPScope.CPPScopeProblem(names[i-1], IProblemBinding.SEMANTIC_BAD_SCOPE);
}
return scope;
}
@ -2353,53 +2342,7 @@ public class CPPVisitor extends ASTQueries {
}
return false;
}
/**
* Returns the outermost declarator the given <code>declarator</code> nests within, or
* <code>declarator</code> itself.
*/
public static IASTDeclarator findOutermostDeclarator(IASTDeclarator declarator) {
IASTDeclarator outermost= null;
IASTNode candidate= declarator;
while (candidate instanceof IASTDeclarator) {
outermost= (IASTDeclarator) candidate;
candidate= outermost.getParent();
}
return outermost;
}
/**
* Returns the innermost declarator nested within the given <code>declarator</code>, or
* <code>declarator</code> itself.
*/
public static IASTDeclarator findInnermostDeclarator(IASTDeclarator declarator) {
IASTDeclarator innermost= null;
while (declarator != null) {
innermost= declarator;
declarator= declarator.getNestedDeclarator();
}
return innermost;
}
/**
* Searches for the innermost declarator that contributes the the type declared.
*/
public static IASTDeclarator findTypeRelevantDeclarator(IASTDeclarator declarator) {
IASTDeclarator result= findInnermostDeclarator(declarator);
while (result.getPointerOperators().length == 0
&& !(result instanceof IASTFieldDeclarator)
&& !(result instanceof IASTFunctionDeclarator)
&& !(result instanceof IASTArrayModifier)) {
final IASTNode parent= result.getParent();
if (parent instanceof IASTDeclarator) {
result= (IASTDeclarator) parent;
} else {
return result;
}
}
return result;
}
/**
* Searches for the function enclosing the given node. May return <code>null</code>.
*/

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2008 Institute for Software, HSR Hochschule fuer Technik
* Copyright (c) 2008, 2009 Institute for Software, HSR Hochschule fuer Technik
* Rapperswil, University of applied sciences and others
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
@ -37,8 +37,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDirective;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTVisibilityLabel;
import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTExplicitTemplateInstantiation;
import org.eclipse.cdt.core.parser.Keywords;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguousDeclaration;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.cdt.internal.core.dom.parser.ASTQueries;
import org.eclipse.cdt.internal.core.dom.rewrite.commenthandler.NodeCommentMap;
@ -74,9 +73,7 @@ public class DeclarationWriter extends NodeWriter{
protected void writeDeclaration(IASTDeclaration declaration, boolean writeSemicolon) {
boolean addNewLine = true;
printSemicolon = writeSemicolon;
if (declaration instanceof IASTAmbiguousDeclaration) {
//Not implemented
} else if (declaration instanceof IASTASMDeclaration) {
if (declaration instanceof IASTASMDeclaration) {
writeASMDeclatation((IASTASMDeclaration) declaration);
} else if (declaration instanceof IASTFunctionDefinition) {
writeFunctionDefinition((IASTFunctionDefinition) declaration);
@ -282,7 +279,7 @@ public class DeclarationWriter extends NodeWriter{
}else {
scribe.printSpace();
}
IASTDeclarator declarator = CPPVisitor.findOutermostDeclarator(funcDef.getDeclarator());
IASTDeclarator declarator = ASTQueries.findOutermostDeclarator(funcDef.getDeclarator());
declarator.accept(visitor);
if (funcDef instanceof ICPPASTFunctionWithTryBlock) {