mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-08 18:26:01 +02:00
fix bug 84267
This commit is contained in:
parent
cb63ddc65b
commit
993bdc690d
6 changed files with 196 additions and 229 deletions
|
@ -2741,4 +2741,33 @@ public class AST2Tests extends AST2BaseTest {
|
||||||
|
|
||||||
assertSame( s_ref, s_decl );
|
assertSame( s_ref, s_decl );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testBug84267() throws Exception {
|
||||||
|
StringBuffer buffer = new StringBuffer();
|
||||||
|
buffer.append( "typedef struct { int a; } S; \n"); //$NON-NLS-1$
|
||||||
|
buffer.append( "void g( S* (*funcp) (void) ) { \n"); //$NON-NLS-1$
|
||||||
|
buffer.append( " (*funcp)()->a; \n"); //$NON-NLS-1$
|
||||||
|
buffer.append( " funcp()->a; \n"); //$NON-NLS-1$
|
||||||
|
buffer.append( "} \n"); //$NON-NLS-1$
|
||||||
|
|
||||||
|
IASTTranslationUnit tu = parse(buffer.toString(), ParserLanguage.C);
|
||||||
|
CNameCollector col = new CNameCollector();
|
||||||
|
CVisitor.visitTranslationUnit(tu, col);
|
||||||
|
|
||||||
|
assertEquals(col.size(), 11);
|
||||||
|
|
||||||
|
ITypedef S = (ITypedef) col.getName(2).resolveBinding();
|
||||||
|
IField a = (IField) col.getName( 10 ).resolveBinding();
|
||||||
|
IParameter funcp = (IParameter) col.getName(7).resolveBinding();
|
||||||
|
assertNotNull( funcp );
|
||||||
|
assertInstances( col, funcp, 3 );
|
||||||
|
assertInstances( col, a, 3 );
|
||||||
|
|
||||||
|
assertTrue( funcp.getType() instanceof IPointerType );
|
||||||
|
IType t = ((IPointerType) funcp.getType()).getType();
|
||||||
|
assertTrue( t instanceof IFunctionType );
|
||||||
|
IFunctionType ft = (IFunctionType) t;
|
||||||
|
assertTrue( ft.getReturnType() instanceof IPointerType );
|
||||||
|
assertSame( ((IPointerType)ft.getReturnType()).getType(), S );
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -91,4 +91,11 @@ public class CArrayType implements ICArrayType, ITypeContainer {
|
||||||
}
|
}
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public ICASTArrayModifier getModifier() {
|
||||||
|
return mod;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -94,7 +94,7 @@ public class CFunction implements IFunction, ICBinding {
|
||||||
if( names.length > 0 ){
|
if( names.length > 0 ){
|
||||||
// ensures that the List of parameters is created in the same order as the K&R C parameter names
|
// ensures that the List of parameters is created in the same order as the K&R C parameter names
|
||||||
for( int i=0; i<names.length; i++ ) {
|
for( int i=0; i<names.length; i++ ) {
|
||||||
IASTDeclarator decl = getKnRParameterDeclarator( (ICASTKnRFunctionDeclarator) dtor, names[i] );
|
IASTDeclarator decl = CVisitor.getKnRParameterDeclarator( (ICASTKnRFunctionDeclarator) dtor, names[i] );
|
||||||
if( decl != null ) {
|
if( decl != null ) {
|
||||||
result[i] = (IParameter) decl.getName().resolveBinding();
|
result[i] = (IParameter) decl.getName().resolveBinding();
|
||||||
} else {
|
} else {
|
||||||
|
@ -145,7 +145,7 @@ public class CFunction implements IFunction, ICBinding {
|
||||||
if( type == null ) {
|
if( type == null ) {
|
||||||
IASTDeclarator functionName = ( definition != null ) ? definition : declarators[0];
|
IASTDeclarator functionName = ( definition != null ) ? definition : declarators[0];
|
||||||
|
|
||||||
while (functionName.getName().toString() == null)
|
while (functionName.getNestedDeclarator() != null)
|
||||||
functionName = functionName.getNestedDeclarator();
|
functionName = functionName.getNestedDeclarator();
|
||||||
|
|
||||||
IType tempType = CVisitor.createType( functionName.getName() );
|
IType tempType = CVisitor.createType( functionName.getName() );
|
||||||
|
@ -163,7 +163,7 @@ public class CFunction implements IFunction, ICBinding {
|
||||||
IBinding binding = null;
|
IBinding binding = null;
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
IASTNode parent = paramName.getParent();
|
IASTNode parent = paramName.getParent();
|
||||||
if( !(parent instanceof ICASTKnRFunctionDeclarator ) )
|
while( parent instanceof IASTDeclarator && !(parent instanceof ICASTKnRFunctionDeclarator ) )
|
||||||
parent = parent.getParent();
|
parent = parent.getParent();
|
||||||
|
|
||||||
ICASTKnRFunctionDeclarator fKnRDtor = null;
|
ICASTKnRFunctionDeclarator fKnRDtor = null;
|
||||||
|
@ -192,7 +192,7 @@ public class CFunction implements IFunction, ICBinding {
|
||||||
if( ps[idx] == paramName)
|
if( ps[idx] == paramName)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
knrParamDtor = getKnRParameterDeclarator( fKnRDtor, paramName );
|
knrParamDtor = CVisitor.getKnRParameterDeclarator( fKnRDtor, paramName );
|
||||||
paramName = knrParamDtor.getName();
|
paramName = knrParamDtor.getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -206,7 +206,7 @@ public class CFunction implements IFunction, ICBinding {
|
||||||
} else if( definition instanceof ICASTKnRFunctionDeclarator ){
|
} else if( definition instanceof ICASTKnRFunctionDeclarator ){
|
||||||
IASTName n = fKnRDtor.getParameterNames()[idx];
|
IASTName n = fKnRDtor.getParameterNames()[idx];
|
||||||
((CASTName)n).setBinding( binding );
|
((CASTName)n).setBinding( binding );
|
||||||
IASTDeclarator dtor = getKnRParameterDeclarator( fKnRDtor, n );
|
IASTDeclarator dtor = CVisitor.getKnRParameterDeclarator( fKnRDtor, n );
|
||||||
if( dtor != null ){
|
if( dtor != null ){
|
||||||
((CASTName)dtor.getName()).setBinding( binding );
|
((CASTName)dtor.getName()).setBinding( binding );
|
||||||
}
|
}
|
||||||
|
@ -223,22 +223,7 @@ public class CFunction implements IFunction, ICBinding {
|
||||||
return binding;
|
return binding;
|
||||||
}
|
}
|
||||||
|
|
||||||
private IASTDeclarator getKnRParameterDeclarator( ICASTKnRFunctionDeclarator fKnRDtor, IASTName name ){
|
|
||||||
IASTDeclaration [] decls = fKnRDtor.getParameterDeclarations();
|
|
||||||
char [] n = name.toCharArray();
|
|
||||||
for( int i = 0; i < decls.length; i++ ){
|
|
||||||
if( !( decls[i] instanceof IASTSimpleDeclaration ) )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
IASTDeclarator [] dtors = ((IASTSimpleDeclaration)decls[i]).getDeclarators();
|
|
||||||
for( int j = 0; j < dtors.length; j++ ){
|
|
||||||
if( CharArrayUtils.equals( dtors[j].getName().toCharArray(), n ) ){
|
|
||||||
return dtors[j];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void updateParameterBindings( IASTFunctionDeclarator fdtor ){
|
protected void updateParameterBindings( IASTFunctionDeclarator fdtor ){
|
||||||
CParameter temp = null;
|
CParameter temp = null;
|
||||||
|
@ -273,7 +258,7 @@ public class CFunction implements IFunction, ICBinding {
|
||||||
CASTName name = (CASTName) ns[i];
|
CASTName name = (CASTName) ns[i];
|
||||||
name.setBinding( temp );
|
name.setBinding( temp );
|
||||||
|
|
||||||
IASTDeclarator dtor = getKnRParameterDeclarator( (ICASTKnRFunctionDeclarator) fdtor, name );
|
IASTDeclarator dtor = CVisitor.getKnRParameterDeclarator( (ICASTKnRFunctionDeclarator) fdtor, name );
|
||||||
if( dtor != null ){
|
if( dtor != null ){
|
||||||
((CASTName) dtor.getName()).setBinding( temp );
|
((CASTName) dtor.getName()).setBinding( temp );
|
||||||
temp.addDeclaration( (CASTName) dtor.getName() );
|
temp.addDeclaration( (CASTName) dtor.getName() );
|
||||||
|
|
|
@ -49,7 +49,7 @@ public class CParameter implements IParameter {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public IType getType() {
|
public IType getType() {
|
||||||
return CVisitor.createType( declarations[0], true );
|
return CVisitor.createType( declarations[0] );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
|
|
|
@ -65,6 +65,7 @@ import org.eclipse.cdt.core.dom.ast.IASTTypeId;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression;
|
import org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression;
|
import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTWhileStatement;
|
import org.eclipse.cdt.core.dom.ast.IASTWhileStatement;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IArrayType;
|
||||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||||
import org.eclipse.cdt.core.dom.ast.ICompositeType;
|
import org.eclipse.cdt.core.dom.ast.ICompositeType;
|
||||||
import org.eclipse.cdt.core.dom.ast.IEnumeration;
|
import org.eclipse.cdt.core.dom.ast.IEnumeration;
|
||||||
|
@ -72,7 +73,7 @@ import org.eclipse.cdt.core.dom.ast.IEnumerator;
|
||||||
import org.eclipse.cdt.core.dom.ast.IFunction;
|
import org.eclipse.cdt.core.dom.ast.IFunction;
|
||||||
import org.eclipse.cdt.core.dom.ast.IFunctionType;
|
import org.eclipse.cdt.core.dom.ast.IFunctionType;
|
||||||
import org.eclipse.cdt.core.dom.ast.ILabel;
|
import org.eclipse.cdt.core.dom.ast.ILabel;
|
||||||
import org.eclipse.cdt.core.dom.ast.IParameter;
|
import org.eclipse.cdt.core.dom.ast.IPointerType;
|
||||||
import org.eclipse.cdt.core.dom.ast.IProblemBinding;
|
import org.eclipse.cdt.core.dom.ast.IProblemBinding;
|
||||||
import org.eclipse.cdt.core.dom.ast.IScope;
|
import org.eclipse.cdt.core.dom.ast.IScope;
|
||||||
import org.eclipse.cdt.core.dom.ast.IType;
|
import org.eclipse.cdt.core.dom.ast.IType;
|
||||||
|
@ -101,6 +102,7 @@ import org.eclipse.cdt.core.dom.ast.gnu.c.IGCCASTArrayRangeDesignator;
|
||||||
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
|
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer;
|
import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
|
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunctionType;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVisitor.CPPBaseVisitorAction;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVisitor.CPPBaseVisitorAction;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -623,27 +625,33 @@ public class CVisitor {
|
||||||
private static IType getExpressionType( IASTExpression expression ) {
|
private static IType getExpressionType( IASTExpression expression ) {
|
||||||
try{
|
try{
|
||||||
if( expression instanceof IASTIdExpression ){
|
if( expression instanceof IASTIdExpression ){
|
||||||
IBinding binding = resolveBinding( expression );
|
IBinding binding = ((IASTIdExpression)expression).getName().resolveBinding();
|
||||||
if( binding instanceof IVariable ){
|
if( binding instanceof IVariable ){
|
||||||
return ((IVariable)binding).getType();
|
return ((IVariable)binding).getType();
|
||||||
}
|
}
|
||||||
} else if( expression instanceof IASTCastExpression ){
|
} else if( expression instanceof IASTCastExpression ){
|
||||||
IASTTypeId id = ((IASTCastExpression)expression).getTypeId();
|
IASTTypeId id = ((IASTCastExpression)expression).getTypeId();
|
||||||
IBinding binding = resolveBinding( id );
|
return createType( id.getAbstractDeclarator().getName() );
|
||||||
if( binding != null && binding instanceof IType ){
|
|
||||||
return (IType) binding;
|
|
||||||
}
|
|
||||||
} else if( expression instanceof IASTFieldReference ){
|
} else if( expression instanceof IASTFieldReference ){
|
||||||
IBinding binding = ((IASTFieldReference)expression).getFieldName().resolveBinding();
|
IBinding binding = ((IASTFieldReference)expression).getFieldName().resolveBinding();
|
||||||
|
|
||||||
if( binding instanceof IVariable ){
|
if( binding instanceof IVariable ){
|
||||||
return ((IVariable)binding).getType();
|
return ((IVariable)binding).getType();
|
||||||
}
|
}
|
||||||
|
} else if( expression instanceof IASTFunctionCallExpression ){
|
||||||
|
IType type = getExpressionType( ((IASTFunctionCallExpression)expression).getFunctionNameExpression() );
|
||||||
|
while( type instanceof ITypeContainer )
|
||||||
|
type = ((ITypeContainer)type).getType();
|
||||||
|
if( type instanceof IFunctionType )
|
||||||
|
return ((IFunctionType)type).getReturnType();
|
||||||
|
} else if( expression instanceof IASTUnaryExpression ) {
|
||||||
|
IType type = getExpressionType(((IASTUnaryExpression)expression).getOperand() );
|
||||||
|
int op = ((IASTUnaryExpression)expression).getOperator();
|
||||||
|
if( op == IASTUnaryExpression.op_star && (type instanceof IPointerType || type instanceof IArrayType) ){
|
||||||
|
return ((ITypeContainer)type).getType();
|
||||||
|
} else if( op == IASTUnaryExpression.op_amper ){
|
||||||
|
return new CPointerType( type );
|
||||||
}
|
}
|
||||||
else if( expression instanceof IASTUnaryExpression )
|
return type;
|
||||||
{
|
|
||||||
if( ((IASTUnaryExpression)expression).getOperator() == IASTUnaryExpression.op_bracketedPrimary )
|
|
||||||
return getExpressionType(((IASTUnaryExpression)expression).getOperand() );
|
|
||||||
}
|
}
|
||||||
} catch( DOMException e ){
|
} catch( DOMException e ){
|
||||||
return e.getProblem();
|
return e.getProblem();
|
||||||
|
@ -759,6 +767,12 @@ public class CVisitor {
|
||||||
} else {
|
} else {
|
||||||
binding = new CVariable( declarator.getName() );
|
binding = new CVariable( declarator.getName() );
|
||||||
}
|
}
|
||||||
|
} else if( parent instanceof IASTParameterDeclaration ){
|
||||||
|
IASTFunctionDeclarator fdtor = (IASTFunctionDeclarator) parent.getParent();
|
||||||
|
IBinding temp = fdtor.getName().resolveBinding();
|
||||||
|
if( temp != null && temp instanceof IFunction ){
|
||||||
|
binding = ((CFunction) temp).resolveParameter( declarator.getName() );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( scope != null && binding != null )
|
if( scope != null && binding != null )
|
||||||
|
@ -1202,7 +1216,11 @@ public class CVisitor {
|
||||||
for( int i = 0; i < parameters.length; i++ ){
|
for( int i = 0; i < parameters.length; i++ ){
|
||||||
IASTParameterDeclaration parameterDeclaration = parameters[i];
|
IASTParameterDeclaration parameterDeclaration = parameters[i];
|
||||||
if( parameterDeclaration == null ) break;
|
if( parameterDeclaration == null ) break;
|
||||||
declName = parameterDeclaration.getDeclarator().getName();
|
IASTDeclarator dtor = parameterDeclaration.getDeclarator();
|
||||||
|
while( dtor.getNestedDeclarator() != null ){
|
||||||
|
dtor = dtor.getNestedDeclarator();
|
||||||
|
}
|
||||||
|
declName = dtor.getName();
|
||||||
if( CharArrayUtils.equals( declName.toCharArray(), name.toCharArray() ) ){
|
if( CharArrayUtils.equals( declName.toCharArray(), name.toCharArray() ) ){
|
||||||
return declName.resolveBinding();
|
return declName.resolveBinding();
|
||||||
}
|
}
|
||||||
|
@ -1669,98 +1687,83 @@ public class CVisitor {
|
||||||
* @return the IType of the IASTName parameter
|
* @return the IType of the IASTName parameter
|
||||||
*/
|
*/
|
||||||
public static IType createType(IASTName name) {
|
public static IType createType(IASTName name) {
|
||||||
return createType(name, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method is used to create the structure of ITypes based on the structure of the IASTDeclarator for the IASTName pased in.
|
|
||||||
*
|
|
||||||
* This method has recursive behaviour if the IASTDeclarator's parent is found to be an IASTFunctionDeclarator.
|
|
||||||
* Recursion is used to get the IType of the IASTDeclarator's parent.
|
|
||||||
*
|
|
||||||
* If the IASTDeclarator's parent is an IASTSimpleDeclaration, an IASTFunctionDefinition, or an IASTParameterDeclaration then
|
|
||||||
* any recurisve behaviour to that point is stopped and the proper IType is returned at that point.
|
|
||||||
*
|
|
||||||
* @param name the IASTName to create an IType for
|
|
||||||
* @param isParm whether the IASTName is a parameter in a declaration or not
|
|
||||||
* @return the IType corresponding to the IASTName
|
|
||||||
*/
|
|
||||||
public static IType createType(IASTName name, boolean isParm) {
|
|
||||||
// if it's not a declarator then return null, otherwise work with its parent
|
|
||||||
if (!(name.getParent() instanceof IASTDeclarator)) return null;
|
if (!(name.getParent() instanceof IASTDeclarator)) return null;
|
||||||
|
|
||||||
|
IASTDeclSpecifier declSpec = null;
|
||||||
IASTDeclarator declarator = (IASTDeclarator) name.getParent();
|
IASTDeclarator declarator = (IASTDeclarator) name.getParent();
|
||||||
|
|
||||||
// if it's a simple declaration then create a base type and a function type if necessary and return it
|
IASTNode node = declarator.getParent();
|
||||||
if (declarator.getParent() instanceof IASTSimpleDeclaration) {
|
while( node instanceof IASTDeclarator ){
|
||||||
IType lastType = createBaseType( declarator, ((IASTSimpleDeclaration)declarator.getParent()).getDeclSpecifier(), isParm );
|
declarator = (IASTDeclarator) node;
|
||||||
|
node = node.getParent();
|
||||||
|
}
|
||||||
|
|
||||||
if (declarator instanceof IASTFunctionDeclarator)
|
if( node instanceof IASTParameterDeclaration )
|
||||||
lastType = new CFunctionType(lastType, getParmTypes((IASTFunctionDeclarator)declarator));
|
declSpec = ((IASTParameterDeclaration) node).getDeclSpecifier();
|
||||||
|
else if( node instanceof IASTSimpleDeclaration )
|
||||||
|
declSpec = ((IASTSimpleDeclaration)node).getDeclSpecifier();
|
||||||
|
else if( node instanceof IASTFunctionDefinition )
|
||||||
|
declSpec = ((IASTFunctionDefinition)node).getDeclSpecifier();
|
||||||
|
else if( node instanceof IASTTypeId )
|
||||||
|
declSpec = ((IASTTypeId)node).getDeclSpecifier();
|
||||||
|
|
||||||
return lastType;
|
boolean isParameter = ( node instanceof IASTParameterDeclaration || node.getParent() instanceof ICASTKnRFunctionDeclarator );
|
||||||
|
|
||||||
// if it's a declarator then use recursion to get the parent's type
|
IType type = null;
|
||||||
} else if (declarator.getParent() instanceof IASTDeclarator) {
|
|
||||||
IASTDeclarator origDecltor = (IASTDeclarator)declarator.getParent();
|
|
||||||
IType lastType = createType(origDecltor.getName(), isParm); // use recursion to get the type of the IASTDeclarator's parent
|
|
||||||
|
|
||||||
// if it was a function declarator and its parent is a function definition then do cleanup from the recursion here (setup pointers/arrays/and get functiontype)
|
//C99 6.7.5.3-12 The storage class specifier for a parameter declaration is ignored unless the declared parameter is one of the
|
||||||
if (declarator.getParent().getParent() instanceof IASTFunctionDefinition) {
|
//members of the parameter type list for a function definition.
|
||||||
if (declarator.getPointerOperators() != IASTDeclarator.EMPTY_DECLARATOR_ARRAY)
|
if( isParameter && node.getParent().getParent() instanceof IASTFunctionDefinition ){
|
||||||
lastType = setupPointerChain(declarator.getPointerOperators(), lastType);
|
type = createBaseType( declSpec );
|
||||||
|
|
||||||
IType arrayChain = setupArrayChain(declarator, lastType);
|
|
||||||
if (arrayChain != null) lastType = arrayChain;
|
|
||||||
|
|
||||||
lastType = new CFunctionType(lastType, getParmTypes((IASTFunctionDeclarator)declarator));
|
|
||||||
|
|
||||||
// if it was a declarator and its parent is not a function definition then do cleanup from the recursion here (setup pointers/arrays/ and check if need function type)
|
|
||||||
} else {
|
} else {
|
||||||
if (declarator.getPointerOperators() != IASTDeclarator.EMPTY_DECLARATOR_ARRAY)
|
type = createType( declSpec );
|
||||||
lastType = setupPointerChain(declarator.getPointerOperators(), lastType);
|
}
|
||||||
|
|
||||||
IType arrayChain = setupArrayChain(declarator, lastType);
|
type = createType( type, declarator );
|
||||||
if (arrayChain != null) lastType = arrayChain;
|
|
||||||
|
|
||||||
|
|
||||||
|
if( isParameter ) {
|
||||||
|
//C99: 6.7.5.3-7 a declaration of a parameter as "array of type" shall be adjusted to "qualified pointer to type", where the
|
||||||
|
//type qualifiers (if any) are those specified within the [ and ] of the array type derivation
|
||||||
|
if( type instanceof IArrayType ){
|
||||||
|
CArrayType at = (CArrayType) type;
|
||||||
|
type = new CQualifiedPointerType( at.getType(), at.getModifier() );
|
||||||
|
} else if( type instanceof IFunctionType ) {
|
||||||
|
//-8 A declaration of a parameter as "function returning type" shall be adjusted to "pointer to function returning type"
|
||||||
|
type = new CPointerType( type );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IType createType( IType baseType, IASTDeclarator declarator ) {
|
||||||
if( declarator instanceof IASTFunctionDeclarator )
|
if( declarator instanceof IASTFunctionDeclarator )
|
||||||
lastType = new CFunctionType(lastType, getParmTypes((IASTFunctionDeclarator)declarator));
|
return createType( baseType, (IASTFunctionDeclarator)declarator );
|
||||||
|
|
||||||
|
IType type = baseType;
|
||||||
|
type = setupPointerChain( declarator.getPointerOperators(), type );
|
||||||
|
type = setupArrayChain( declarator, type );
|
||||||
|
|
||||||
|
IASTDeclarator nested = declarator.getNestedDeclarator();
|
||||||
|
if( nested != null ) {
|
||||||
|
return createType( type, nested );
|
||||||
|
}
|
||||||
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
return lastType;
|
public static IType createType( IType returnType, IASTFunctionDeclarator declarator){
|
||||||
|
|
||||||
// if it's a function definition then create the base type and setup a function type if necessary
|
IType [] pTypes = getParmTypes( declarator );
|
||||||
} else if (declarator.getParent() instanceof IASTFunctionDefinition) {
|
returnType = setupPointerChain( declarator.getPointerOperators(), returnType );
|
||||||
IASTFunctionDefinition functionDef = (IASTFunctionDefinition)declarator.getParent();
|
|
||||||
|
|
||||||
IType lastType = createBaseType(functionDef.getDeclarator(), functionDef.getDeclSpecifier(), isParm);
|
IType type = new CPPFunctionType( returnType, pTypes );
|
||||||
|
|
||||||
if (declarator instanceof IASTFunctionDeclarator)
|
IASTDeclarator nested = declarator.getNestedDeclarator();
|
||||||
lastType = new CFunctionType(lastType, getParmTypes((IASTFunctionDeclarator)declarator));
|
if( nested != null ) {
|
||||||
|
return createType( type, nested );
|
||||||
return lastType;
|
|
||||||
|
|
||||||
// if it's a parameter declaration then setup the base type, if necessary setup a function type and change it's return type to pointer to function returning T
|
|
||||||
} else if (declarator.getParent() instanceof IASTParameterDeclaration) {
|
|
||||||
if (declarator instanceof IASTFunctionDeclarator) {
|
|
||||||
IType returnType = createBaseType(declarator, ((IASTParameterDeclaration)declarator.getParent()).getDeclSpecifier(), isParm);
|
|
||||||
IType lastType = new CFunctionType(returnType, getParmTypes((IASTFunctionDeclarator)declarator));
|
|
||||||
|
|
||||||
if (declarator.getPointerOperators() != IASTPointerOperator.EMPTY_ARRAY)
|
|
||||||
lastType = setupPointerChain(declarator.getPointerOperators(), lastType);
|
|
||||||
|
|
||||||
IType arrayChain = setupArrayChain(declarator, lastType);
|
|
||||||
if (arrayChain != null) lastType = arrayChain;
|
|
||||||
|
|
||||||
// any parameter to type function returning T is adjusted to be pointer to function returning T
|
|
||||||
lastType = new CPointerType( lastType );
|
|
||||||
|
|
||||||
return lastType;
|
|
||||||
}
|
}
|
||||||
|
return type;
|
||||||
return createBaseType( declarator, ((IASTParameterDeclaration)(declarator).getParent()).getDeclSpecifier(), isParm );
|
|
||||||
}
|
|
||||||
|
|
||||||
return null; // if anything else isn't supported yet return null for now
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1773,84 +1776,35 @@ public class CVisitor {
|
||||||
* @param isParm is used to specify whether the IASTDeclarator is a parameter of a declaration
|
* @param isParm is used to specify whether the IASTDeclarator is a parameter of a declaration
|
||||||
* @return the base IType
|
* @return the base IType
|
||||||
*/
|
*/
|
||||||
public static IType createBaseType(IASTDeclarator declarator, IASTDeclSpecifier declSpec, boolean isParm) {
|
public static IType createBaseType( IASTDeclSpecifier declSpec ) {
|
||||||
IType lastType = null;
|
if (declSpec instanceof ICASTSimpleDeclSpecifier) {
|
||||||
|
return new CBasicType((ICASTSimpleDeclSpecifier)declSpec);
|
||||||
|
}
|
||||||
|
IBinding binding = null;
|
||||||
if( declSpec instanceof ICASTTypedefNameSpecifier ){
|
if( declSpec instanceof ICASTTypedefNameSpecifier ){
|
||||||
if (declSpec.isConst() || declSpec.isVolatile() || (declSpec instanceof ICASTDeclSpecifier && ((ICASTDeclSpecifier)declSpec).isRestrict()))
|
|
||||||
return new CQualifierType(declSpec);
|
|
||||||
|
|
||||||
ICASTTypedefNameSpecifier nameSpec = (ICASTTypedefNameSpecifier) declSpec;
|
ICASTTypedefNameSpecifier nameSpec = (ICASTTypedefNameSpecifier) declSpec;
|
||||||
|
binding = nameSpec.getName().resolveBinding();
|
||||||
if (!(nameSpec.getName().resolveBinding() instanceof IType)) return null;
|
|
||||||
|
|
||||||
lastType = (IType) nameSpec.getName().resolveBinding();
|
|
||||||
|
|
||||||
IType pointerChain = setupPointerChain(declarator.getPointerOperators(), lastType);
|
|
||||||
if (pointerChain != null) lastType = pointerChain;
|
|
||||||
|
|
||||||
IType arrayChain = null;
|
|
||||||
if (isParm)
|
|
||||||
arrayChain = setupArrayParmChain(declarator, lastType);
|
|
||||||
else
|
|
||||||
arrayChain = setupArrayChain(declarator, lastType);
|
|
||||||
if (arrayChain != null) lastType = arrayChain;
|
|
||||||
|
|
||||||
} else if( declSpec instanceof IASTElaboratedTypeSpecifier ){
|
} else if( declSpec instanceof IASTElaboratedTypeSpecifier ){
|
||||||
if (declSpec.isConst() || declSpec.isVolatile() || (declSpec instanceof ICASTDeclSpecifier && ((ICASTDeclSpecifier)declSpec).isRestrict()))
|
|
||||||
return new CQualifierType(declSpec);
|
|
||||||
|
|
||||||
IASTElaboratedTypeSpecifier elabTypeSpec = (IASTElaboratedTypeSpecifier) declSpec;
|
IASTElaboratedTypeSpecifier elabTypeSpec = (IASTElaboratedTypeSpecifier) declSpec;
|
||||||
lastType = (IType) elabTypeSpec.getName().resolveBinding();
|
binding = elabTypeSpec.getName().resolveBinding();
|
||||||
|
|
||||||
IType pointerChain = setupPointerChain(declarator.getPointerOperators(), lastType);
|
|
||||||
if (pointerChain != null) lastType = pointerChain;
|
|
||||||
|
|
||||||
IType arrayChain = null;
|
|
||||||
if (isParm)
|
|
||||||
arrayChain = setupArrayParmChain(declarator, lastType);
|
|
||||||
else
|
|
||||||
arrayChain = setupArrayChain(declarator, lastType);
|
|
||||||
if (arrayChain != null) lastType = arrayChain;
|
|
||||||
|
|
||||||
} else if( declSpec instanceof IASTCompositeTypeSpecifier ){
|
} else if( declSpec instanceof IASTCompositeTypeSpecifier ){
|
||||||
|
IASTCompositeTypeSpecifier compTypeSpec = (IASTCompositeTypeSpecifier) declSpec;
|
||||||
|
binding = compTypeSpec.getName().resolveBinding();
|
||||||
|
}
|
||||||
|
|
||||||
|
if( binding instanceof IType )
|
||||||
|
return (IType) binding;
|
||||||
|
|
||||||
|
//TODO IProblem
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IType createType( IASTDeclSpecifier declSpec ) {
|
||||||
if (declSpec.isConst() || declSpec.isVolatile() || (declSpec instanceof ICASTDeclSpecifier && ((ICASTDeclSpecifier)declSpec).isRestrict()))
|
if (declSpec.isConst() || declSpec.isVolatile() || (declSpec instanceof ICASTDeclSpecifier && ((ICASTDeclSpecifier)declSpec).isRestrict()))
|
||||||
return new CQualifierType(declSpec);
|
return new CQualifierType(declSpec);
|
||||||
|
|
||||||
IASTCompositeTypeSpecifier compTypeSpec = (IASTCompositeTypeSpecifier) declSpec;
|
return createBaseType( declSpec );
|
||||||
lastType = (IType) compTypeSpec.getName().resolveBinding();
|
|
||||||
|
|
||||||
IType pointerChain = setupPointerChain(declarator.getPointerOperators(), lastType);
|
|
||||||
if (pointerChain != null) lastType = pointerChain;
|
|
||||||
|
|
||||||
IType arrayChain = null;
|
|
||||||
if (isParm)
|
|
||||||
arrayChain = setupArrayParmChain(declarator, lastType);
|
|
||||||
else
|
|
||||||
arrayChain = setupArrayChain(declarator, lastType);
|
|
||||||
if (arrayChain != null) lastType = arrayChain;
|
|
||||||
|
|
||||||
} else if (declSpec instanceof ICASTSimpleDeclSpecifier) {
|
|
||||||
if (declSpec.isConst() || declSpec.isVolatile() || (declSpec instanceof ICASTDeclSpecifier && ((ICASTDeclSpecifier)declSpec).isRestrict()))
|
|
||||||
lastType = new CQualifierType(declSpec);
|
|
||||||
else
|
|
||||||
lastType = new CBasicType((ICASTSimpleDeclSpecifier)declSpec);
|
|
||||||
|
|
||||||
IType pointerChain = setupPointerChain(declarator.getPointerOperators(), lastType);
|
|
||||||
if (pointerChain != null) lastType = pointerChain;
|
|
||||||
|
|
||||||
IType arrayChain = null;
|
|
||||||
if (isParm)
|
|
||||||
arrayChain = setupArrayParmChain(declarator, lastType);
|
|
||||||
else
|
|
||||||
arrayChain = setupArrayChain(declarator, lastType);
|
|
||||||
if (arrayChain != null) lastType = arrayChain;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return lastType;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an IType[] corresponding to the parameter types of the IASTFunctionDeclarator parameter.
|
* Returns an IType[] corresponding to the parameter types of the IASTFunctionDeclarator parameter.
|
||||||
*
|
*
|
||||||
|
@ -1863,20 +1817,16 @@ public class CVisitor {
|
||||||
IType parmTypes[] = new IType[parms.length];
|
IType parmTypes[] = new IType[parms.length];
|
||||||
|
|
||||||
for( int i = 0; i < parms.length; i++ ){
|
for( int i = 0; i < parms.length; i++ ){
|
||||||
parmTypes[i] = createType(parms[i].getDeclarator().getName(), true);
|
parmTypes[i] = createType( parms[i].getDeclarator().getName() );
|
||||||
}
|
}
|
||||||
return parmTypes;
|
return parmTypes;
|
||||||
} else if ( decltor instanceof ICASTKnRFunctionDeclarator ) {
|
} else if ( decltor instanceof ICASTKnRFunctionDeclarator ) {
|
||||||
IASTDeclaration parms[] = ((ICASTKnRFunctionDeclarator)decltor).getParameterDeclarations();
|
IASTName parms[] = ((ICASTKnRFunctionDeclarator)decltor).getParameterNames();
|
||||||
IType parmTypes[] = new IType[parms.length];
|
IType parmTypes[] = new IType[parms.length];
|
||||||
|
|
||||||
for( int i = 0; i < parms.length; i++ ){
|
for( int i = 0; i < parms.length; i++ ){
|
||||||
if ( parms[i] instanceof IASTSimpleDeclaration ) {
|
IASTDeclarator dtor = getKnRParameterDeclarator( (ICASTKnRFunctionDeclarator) decltor, parms[i] );
|
||||||
IASTDeclarator[] decltors = ((IASTSimpleDeclaration)parms[i]).getDeclarators();
|
parmTypes[i] = createType( dtor.getName() );
|
||||||
for ( int j = 0; j < decltors.length; j++ ) {
|
|
||||||
parmTypes[i] = createType(decltors[j].getName(), true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return parmTypes;
|
return parmTypes;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1884,29 +1834,20 @@ public class CVisitor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
protected static IASTDeclarator getKnRParameterDeclarator( ICASTKnRFunctionDeclarator fKnRDtor, IASTName name ){
|
||||||
* Setup a chain of CQualifiedPointerType for the IASTArrayModifier[] of an IASTArrayDeclarator.
|
IASTDeclaration [] decls = fKnRDtor.getParameterDeclarations();
|
||||||
* The CQualifiedType is an IPointerType that is qualified with the IASTArrayModifier.
|
char [] n = name.toCharArray();
|
||||||
* i.e. the modifiers within the [ and ] of the array type
|
for( int i = 0; i < decls.length; i++ ){
|
||||||
*
|
if( !( decls[i] instanceof IASTSimpleDeclaration ) )
|
||||||
* @param decl the IASTDeclarator that is a parameter and has the IASTArrayModifier[]
|
continue;
|
||||||
* @param lastType the IType that the end of the CQualifiedPointerType chain points to
|
|
||||||
* @return the starting CQualifiedPointerType at the beginning of the CQualifiedPointerType chain
|
|
||||||
*/
|
|
||||||
private static IType setupArrayParmChain(IASTDeclarator decl, IType lastType) {
|
|
||||||
if (decl instanceof IASTArrayDeclarator) {
|
|
||||||
int i=0;
|
|
||||||
IASTArrayModifier[] mods = ((IASTArrayDeclarator)decl).getArrayModifiers();
|
|
||||||
|
|
||||||
// C99: 6.7.5.3-7 "array of type" shall be adjusted to "qualified pointer to type", where the type qualifiers (if any)
|
IASTDeclarator [] dtors = ((IASTSimpleDeclaration)decls[i]).getDeclarators();
|
||||||
// are those specified within the [ and ] of the array type derivation
|
for( int j = 0; j < dtors.length; j++ ){
|
||||||
IType pType = new CQualifiedPointerType(lastType, mods[i++]);
|
if( CharArrayUtils.equals( dtors[j].getName().toCharArray(), n ) ){
|
||||||
for (; i < ((IASTArrayDeclarator)decl).getArrayModifiers().length - 1; i++) {
|
return dtors[j];
|
||||||
pType = new CQualifiedPointerType(lastType, mods[i]);
|
}
|
||||||
}
|
}
|
||||||
return pType;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1938,7 +1879,7 @@ public class CVisitor {
|
||||||
return arrayType;
|
return arrayType;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return lastType;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1975,7 +1916,7 @@ public class CVisitor {
|
||||||
return pointerType;
|
return pointerType;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return lastType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IASTProblem[] getProblems(IASTTranslationUnit tu) {
|
public static IASTProblem[] getProblems(IASTTranslationUnit tu) {
|
||||||
|
|
|
@ -1361,6 +1361,11 @@ public class CPPVisitor {
|
||||||
type = getPointerTypes( type, declarator );
|
type = getPointerTypes( type, declarator );
|
||||||
if( declarator instanceof IASTArrayDeclarator )
|
if( declarator instanceof IASTArrayDeclarator )
|
||||||
type = getArrayTypes( type, (IASTArrayDeclarator) declarator );
|
type = getArrayTypes( type, (IASTArrayDeclarator) declarator );
|
||||||
|
|
||||||
|
IASTDeclarator nested = declarator.getNestedDeclarator();
|
||||||
|
if( nested != null ) {
|
||||||
|
return createType( type, nested );
|
||||||
|
}
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue