mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-23 17:05:26 +02:00
- add isStatic to IVariable
- fix bug 85824 - fix problems with implicit scopes
This commit is contained in:
parent
7a4aed4b37
commit
5cafbaec9b
11 changed files with 227 additions and 56 deletions
|
@ -1884,5 +1884,19 @@ public class AST2CPPTests extends AST2BaseTest {
|
|||
assertInstances( col, f1, 2 );
|
||||
assertInstances( col, f2, 1 );
|
||||
}
|
||||
|
||||
public void testBug85824() throws Exception {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.append( "extern int g; \n "); //$NON-NLS-1$
|
||||
buffer.append( "int g; \n "); //$NON-NLS-1$
|
||||
buffer.append( "void f() { g = 1; }\n "); //$NON-NLS-1$
|
||||
|
||||
IASTTranslationUnit tu = parse(buffer.toString(), ParserLanguage.CPP);
|
||||
CPPNameCollector col = new CPPNameCollector();
|
||||
CPPVisitor.visitTranslationUnit(tu, col);
|
||||
|
||||
IVariable g = (IVariable) col.getName(3).resolveBinding();
|
||||
assertInstances( col, g, 3 );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -19,4 +19,7 @@ public interface IVariable extends IBinding {
|
|||
* @return the type of the variable
|
||||
*/
|
||||
public IType getType() throws DOMException;
|
||||
|
||||
|
||||
public boolean isStatic() throws DOMException;
|
||||
}
|
||||
|
|
|
@ -62,4 +62,11 @@ public class CExternalVariable implements ICExternalBinding, IVariable {
|
|||
public IType getType() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.dom.ast.IVariable#isStatic()
|
||||
*/
|
||||
public boolean isStatic() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -82,4 +82,11 @@ public class CKnRParameter implements IParameter {
|
|||
return declaration;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.dom.ast.IVariable#isStatic()
|
||||
*/
|
||||
public boolean isStatic() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -36,6 +36,10 @@ public class CParameter implements IParameter {
|
|||
public IType getType() throws DOMException {
|
||||
throw new DOMException( this );
|
||||
}
|
||||
|
||||
public boolean isStatic() throws DOMException {
|
||||
throw new DOMException( this );
|
||||
}
|
||||
}
|
||||
|
||||
private IASTName [] declarations;
|
||||
|
@ -100,4 +104,11 @@ public class CParameter implements IParameter {
|
|||
declarations = tmp;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.dom.ast.IVariable#isStatic()
|
||||
*/
|
||||
public boolean isStatic(){
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -12,12 +12,15 @@
|
|||
package org.eclipse.cdt.internal.core.dom.parser.c;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.DOMException;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.IScope;
|
||||
import org.eclipse.cdt.core.dom.ast.IType;
|
||||
import org.eclipse.cdt.core.dom.ast.IVariable;
|
||||
import org.eclipse.cdt.core.parser.util.ArrayUtil;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
|
||||
|
||||
/**
|
||||
|
@ -33,24 +36,30 @@ public class CVariable implements IVariable, ICBinding {
|
|||
public IType getType() throws DOMException {
|
||||
throw new DOMException( this );
|
||||
}
|
||||
public boolean isStatic() throws DOMException {
|
||||
throw new DOMException( this );
|
||||
}
|
||||
|
||||
}
|
||||
final IASTName name;
|
||||
private IASTName [] declarations = null;
|
||||
private IType type = null;
|
||||
|
||||
public CVariable( IASTName name ){
|
||||
this.name = name;
|
||||
declarations = new IASTName [] { name };
|
||||
}
|
||||
public IASTNode getPhysicalNode(){
|
||||
return name;
|
||||
return declarations[0];
|
||||
}
|
||||
|
||||
public void addDeclaration( IASTName name ){
|
||||
declarations = (IASTName[]) ArrayUtil.append( IASTName.class, declarations, name );
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.dom.ast.IVariable#getType()
|
||||
*/
|
||||
public IType getType() {
|
||||
if (type == null)
|
||||
type = CVisitor.createType(name);
|
||||
type = CVisitor.createType(declarations[0]);
|
||||
return type;
|
||||
}
|
||||
|
||||
|
@ -58,17 +67,29 @@ public class CVariable implements IVariable, ICBinding {
|
|||
* @see org.eclipse.cdt.core.dom.ast.IBinding#getName()
|
||||
*/
|
||||
public String getName() {
|
||||
return name.toString();
|
||||
return declarations[0].toString();
|
||||
}
|
||||
public char[]getNameCharArray(){
|
||||
return ((CASTName)name).toCharArray();
|
||||
return declarations[0].toCharArray();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.dom.ast.IBinding#getScope()
|
||||
*/
|
||||
public IScope getScope() {
|
||||
IASTDeclarator declarator = (IASTDeclarator) name.getParent();
|
||||
IASTDeclarator declarator = (IASTDeclarator) declarations[0].getParent();
|
||||
return CVisitor.getContainingScope( declarator.getParent() );
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.dom.ast.IVariable#isStatic()
|
||||
*/
|
||||
public boolean isStatic() {
|
||||
IASTDeclarator dtor = (IASTDeclarator) declarations[0].getParent();
|
||||
while( dtor.getParent() instanceof IASTDeclarator )
|
||||
dtor = (IASTDeclarator) dtor.getParent();
|
||||
|
||||
IASTSimpleDeclaration simple = (IASTSimpleDeclaration) dtor.getParent();
|
||||
IASTDeclSpecifier declSpec = simple.getDeclSpecifier();
|
||||
return ( declSpec.getStorageClass() == IASTDeclSpecifier.sc_static );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -736,6 +736,15 @@ public class CVisitor {
|
|||
}
|
||||
|
||||
ICScope scope = (ICScope) getContainingScope( parent );
|
||||
|
||||
ASTNodeProperty prop = parent.getPropertyInParent();
|
||||
if( prop == IASTDeclarationStatement.DECLARATION ){
|
||||
//implicit scope, see 6.8.4-3
|
||||
prop = parent.getParent().getPropertyInParent();
|
||||
if( prop != IASTCompoundStatement.NESTED_STATEMENT )
|
||||
scope = null;
|
||||
}
|
||||
|
||||
IBinding binding = null;
|
||||
try {
|
||||
binding = ( scope != null ) ? scope.getBinding( ICScope.NAMESPACE_TYPE_OTHER, declarator.getName().toCharArray() ) : null;
|
||||
|
@ -767,10 +776,22 @@ public class CVisitor {
|
|||
IASTSimpleDeclaration simpleDecl = (IASTSimpleDeclaration) parent;
|
||||
if( simpleDecl.getDeclSpecifier().getStorageClass() == IASTDeclSpecifier.sc_typedef ){
|
||||
binding = new CTypeDef( declarator.getName() );
|
||||
} else if( simpleDecl.getParent() instanceof ICASTCompositeTypeSpecifier ){
|
||||
binding = new CField( declarator.getName() );
|
||||
} else {
|
||||
binding = new CVariable( declarator.getName() );
|
||||
IType t1 = null, t2 = null;
|
||||
if( binding != null && binding instanceof IVariable ){
|
||||
t1 = createType( declarator.getName() );
|
||||
try {
|
||||
t2 = ((IVariable)binding).getType();
|
||||
} catch ( DOMException e1 ) {
|
||||
}
|
||||
}
|
||||
if( t1 != null && t2 != null && t1.equals( t2 ) ){
|
||||
((CVariable)binding).addDeclaration( declarator.getName() );
|
||||
} else if( simpleDecl.getParent() instanceof ICASTCompositeTypeSpecifier ){
|
||||
binding = new CField( declarator.getName() );
|
||||
} else {
|
||||
binding = new CVariable( declarator.getName() );
|
||||
}
|
||||
}
|
||||
} else if( parent instanceof IASTParameterDeclaration ){
|
||||
IASTFunctionDeclarator fdtor = (IASTFunctionDeclarator) parent.getParent();
|
||||
|
|
|
@ -14,11 +14,7 @@
|
|||
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.DOMException;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPField;
|
||||
|
||||
/**
|
||||
|
@ -42,8 +38,8 @@ public class CPPField extends CPPVariable implements ICPPField, ICPPBinding {
|
|||
}
|
||||
}
|
||||
|
||||
public CPPField( IASTDeclarator declarator ){
|
||||
super( declarator );
|
||||
public CPPField( IASTName name ){
|
||||
super( name );
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
|
@ -53,20 +49,4 @@ public class CPPField extends CPPVariable implements ICPPField, ICPPBinding {
|
|||
// TODO Auto-generated method stub
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPMember#isStatic()
|
||||
*/
|
||||
public boolean isStatic() {
|
||||
IASTDeclarator dtor = (IASTDeclarator) getPhysicalNode();
|
||||
while( dtor.getPropertyInParent() == IASTDeclarator.NESTED_DECLARATOR )
|
||||
dtor = (IASTDeclarator) dtor.getParent();
|
||||
|
||||
IASTNode node = dtor.getParent();
|
||||
if( node instanceof IASTSimpleDeclaration ){
|
||||
ICPPASTDeclSpecifier declSpec = (ICPPASTDeclSpecifier) ((IASTSimpleDeclaration)node).getDeclSpecifier();
|
||||
return (declSpec.getStorageClass() == IASTDeclSpecifier.sc_static );
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -111,4 +111,11 @@ public class CPPParameter implements IParameter, ICPPBinding {
|
|||
return type;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.dom.ast.IVariable#isStatic()
|
||||
*/
|
||||
public boolean isStatic() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -14,11 +14,17 @@
|
|||
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.DOMException;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.IScope;
|
||||
import org.eclipse.cdt.core.dom.ast.IType;
|
||||
import org.eclipse.cdt.core.dom.ast.IVariable;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
|
||||
import org.eclipse.cdt.core.parser.util.ArrayUtil;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
|
||||
|
||||
/**
|
||||
|
@ -34,34 +40,71 @@ public class CPPVariable implements IVariable, ICPPBinding {
|
|||
throw new DOMException( this );
|
||||
}
|
||||
|
||||
public boolean isStatic() throws DOMException {
|
||||
throw new DOMException( this );
|
||||
}
|
||||
}
|
||||
private IASTDeclarator declarator = null;
|
||||
private IASTName declarations[] = null;
|
||||
private IASTName definition = null;
|
||||
private IType type = null;
|
||||
|
||||
public CPPVariable( IASTDeclarator dtor ){
|
||||
declarator = dtor;
|
||||
public CPPVariable( IASTName name ){
|
||||
if( isDefinition( name ) )
|
||||
definition = name;
|
||||
else
|
||||
declarations = new IASTName [] { name };
|
||||
}
|
||||
|
||||
protected boolean isDefinition( IASTName name ){
|
||||
IASTDeclarator dtor = (IASTDeclarator) name.getParent();
|
||||
while( dtor.getParent() instanceof IASTDeclarator )
|
||||
dtor = (IASTDeclarator) dtor.getParent();
|
||||
|
||||
IASTSimpleDeclaration simpleDecl = (IASTSimpleDeclaration) dtor.getParent();
|
||||
IASTDeclSpecifier declSpec = simpleDecl.getDeclSpecifier();
|
||||
|
||||
//(3.1-1) A declaration is a definition unless ...
|
||||
//it contains the extern specifier or a linkage-spec and does not contain an initializer
|
||||
if( dtor.getInitializer() == null && declSpec.getStorageClass() == IASTDeclSpecifier.sc_extern )
|
||||
return false;
|
||||
//or it declares a static data member in a class declaration
|
||||
if( simpleDecl.getParent() instanceof ICPPASTCompositeTypeSpecifier &&
|
||||
declSpec.getStorageClass() == IASTDeclSpecifier.sc_static )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void addDeclaration( IASTName name ) {
|
||||
if( isDefinition( name ) )
|
||||
definition = name;
|
||||
else
|
||||
declarations = (IASTName[]) ArrayUtil.append( IASTName.class, declarations, name );
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPBinding#getDeclarations()
|
||||
*/
|
||||
public IASTNode[] getDeclarations() {
|
||||
return null;
|
||||
return declarations;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPBinding#getDefinition()
|
||||
*/
|
||||
public IASTNode getDefinition() {
|
||||
return declarator;
|
||||
return definition;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.dom.ast.IVariable#getType()
|
||||
*/
|
||||
public IType getType() {
|
||||
if( type == null )
|
||||
type = CPPVisitor.createType( declarator );
|
||||
if( type == null ){
|
||||
IASTDeclarator dtor = (IASTDeclarator) ( (definition != null) ? definition.getParent() : declarations[0].getParent() );
|
||||
type = CPPVisitor.createType( dtor );
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
|
@ -69,28 +112,63 @@ public class CPPVariable implements IVariable, ICPPBinding {
|
|||
* @see org.eclipse.cdt.core.dom.ast.IBinding#getName()
|
||||
*/
|
||||
public String getName() {
|
||||
return declarator.getName().toString();
|
||||
if( declarations != null ){
|
||||
return declarations[0].toString();
|
||||
}
|
||||
IASTName name = definition;
|
||||
if( name instanceof ICPPASTQualifiedName ){
|
||||
IASTName [] ns = ((ICPPASTQualifiedName)name).getNames();
|
||||
name = ns[ ns.length - 1 ];
|
||||
}
|
||||
|
||||
return name.toString();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.dom.ast.IBinding#getNameCharArray()
|
||||
*/
|
||||
public char[] getNameCharArray() {
|
||||
return declarator.getName().toCharArray();
|
||||
if( declarations != null ){
|
||||
return declarations[0].toCharArray();
|
||||
}
|
||||
IASTName name = definition;
|
||||
if( name instanceof ICPPASTQualifiedName ){
|
||||
IASTName [] ns = ((ICPPASTQualifiedName)name).getNames();
|
||||
name = ns[ ns.length - 1 ];
|
||||
}
|
||||
|
||||
return name.toCharArray();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.dom.ast.IBinding#getScope()
|
||||
*/
|
||||
public IScope getScope() {
|
||||
return CPPVisitor.getContainingScope( declarator );
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.dom.ast.IBinding#getPhysicalNode()
|
||||
*/
|
||||
public IASTNode getPhysicalNode() {
|
||||
return declarator;
|
||||
return CPPVisitor.getContainingScope( definition != null ? definition : declarations[0] );
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPMember#isStatic()
|
||||
*/
|
||||
public boolean isStatic() {
|
||||
IASTDeclarator dtor = null;
|
||||
if( declarations != null )
|
||||
dtor = (IASTDeclarator) declarations[0].getParent();
|
||||
else {
|
||||
//definition of a static field doesn't necessarily say static
|
||||
if( definition instanceof ICPPASTQualifiedName )
|
||||
return true;
|
||||
dtor = (IASTDeclarator) definition.getParent();
|
||||
}
|
||||
|
||||
while( dtor.getPropertyInParent() == IASTDeclarator.NESTED_DECLARATOR )
|
||||
dtor = (IASTDeclarator) dtor.getParent();
|
||||
|
||||
IASTNode node = dtor.getParent();
|
||||
if( node instanceof IASTSimpleDeclaration ){
|
||||
IASTDeclSpecifier declSpec = ((IASTSimpleDeclaration)node).getDeclSpecifier();
|
||||
return (declSpec.getStorageClass() == IASTDeclSpecifier.sc_static );
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -371,10 +371,9 @@ public class CPPVisitor {
|
|||
if( parent instanceof IASTTypeId )
|
||||
return CPPSemantics.resolveBinding( declarator.getName() );
|
||||
|
||||
if( declarator.getNestedDeclarator() != null )
|
||||
return createBinding( declarator.getNestedDeclarator() );
|
||||
while( declarator.getNestedDeclarator() != null )
|
||||
declarator = declarator.getNestedDeclarator();
|
||||
|
||||
|
||||
while( parent instanceof IASTDeclarator ){
|
||||
parent = parent.getParent();
|
||||
}
|
||||
|
@ -389,6 +388,15 @@ public class CPPVisitor {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
ASTNodeProperty prop = parent.getPropertyInParent();
|
||||
if( prop == IASTDeclarationStatement.DECLARATION ){
|
||||
//implicit scope, see 6.4-1
|
||||
prop = parent.getParent().getPropertyInParent();
|
||||
if( prop != IASTCompoundStatement.NESTED_STATEMENT )
|
||||
scope = null;
|
||||
}
|
||||
|
||||
IBinding binding;
|
||||
try {
|
||||
binding = ( scope != null ) ? scope.getBinding( declarator.getName() ) : null;
|
||||
|
@ -433,13 +441,27 @@ public class CPPVisitor {
|
|||
binding = function.resolveParameter( param );
|
||||
}
|
||||
} else if( parent instanceof IASTSimpleDeclaration ){
|
||||
|
||||
IASTSimpleDeclaration simpleDecl = (IASTSimpleDeclaration) parent;
|
||||
if( simpleDecl.getDeclSpecifier().getStorageClass() == IASTDeclSpecifier.sc_typedef ){
|
||||
binding = new CPPTypedef( declarator );
|
||||
} else if( simpleDecl.getParent() instanceof ICPPASTCompositeTypeSpecifier ){
|
||||
binding = new CPPField( declarator );
|
||||
} else {
|
||||
binding = new CPPVariable( declarator );
|
||||
IType t1 = null, t2 = null;
|
||||
|
||||
if( binding != null && binding instanceof IVariable ){
|
||||
t1 = createType( declarator );
|
||||
try {
|
||||
t2 = ((IVariable)binding).getType();
|
||||
} catch ( DOMException e1 ) {
|
||||
}
|
||||
}
|
||||
if( t1 != null && t2 != null && t1.equals( t2 ) ){
|
||||
((CPPVariable)binding).addDeclaration( declarator.getName() );
|
||||
} else if( simpleDecl.getParent() instanceof ICPPASTCompositeTypeSpecifier ){
|
||||
binding = new CPPField( declarator.getName() );
|
||||
} else {
|
||||
binding = new CPPVariable( declarator.getName() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue