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

Modeling array sizes, bug 269926.

This commit is contained in:
Markus Schorn 2009-07-17 17:30:36 +00:00
parent 8bef66b111
commit b358f1f6d0
27 changed files with 565 additions and 409 deletions

View file

@ -675,21 +675,21 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest {
// typedef int UNKA[]; // UNKA is an incomplete type
// UNKA* arrp; // arrp is a pointer to an incomplete type
// UNKA** arrpp;
// void foo()
// {
// xp++; //illformed: X is incomplete
// arrp++; //illformed: incomplete type
// void foo() {
// xp++; //ill-formed: X is incomplete
// arrp++; //ill-formed: incomplete type
// arrpp++; //OK: sizeof UNKA* is known
// }
// struct X { int i; }; // now X is a complete type
// struct X {
// int i;
// }; // now X is a complete type
// int arr[10]; // now the type of arr is complete
// X x;
// void bar()
// {
// void bar() {
// xp = &x; // OK; type is ''pointer to X''
// arrp = &arr; // illformed: different types
// arrp = &arr; // ill-formed: different types
// xp++; //OK: X is complete
// arrp++; //illformed: UNKA can't be completed
// arrp++; //ill-formed: UNKA can't be completed
// }
public void test3_9s7() throws Exception {
parse(getAboveComment(), ParserLanguage.CPP, true, 0);
@ -797,7 +797,7 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest {
assertNull(newExpr.getNewPlacement());
assertNull(newExpr.getNewInitializer());
IASTTypeId typeid= newExpr.getTypeId();
isTypeEqual(CPPVisitor.createType(typeid), "int (* [])()");
isTypeEqual(CPPVisitor.createType(typeid), "int (* [10])()");
}
// typedef int T;
@ -835,7 +835,7 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest {
newExpr= (ICPPASTNewExpression) expr;
assertNull(newExpr.getNewPlacement());
assertNull(newExpr.getNewInitializer());
isTypeEqual(CPPVisitor.createType(newExpr.getTypeId()), "int []");
isTypeEqual(CPPVisitor.createType(newExpr.getTypeId()), "int [5]");
// new (2,f) T[5];
expr= getExpressionOfStatement(fdef, 3);
@ -843,7 +843,7 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest {
newExpr= (ICPPASTNewExpression) expr;
assertInstance(newExpr.getNewPlacement(), IASTExpressionList.class);
assertNull(newExpr.getNewInitializer());
isTypeEqual(CPPVisitor.createType(newExpr.getTypeId()), "int []");
isTypeEqual(CPPVisitor.createType(newExpr.getTypeId()), "int [5]");
}
// int n=2;

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
@ -1203,8 +1203,10 @@ public class AST2CSpecTest extends AST2SpecBaseTest {
buffer.append("for (int j = 0, k = n*m+300; j < k; j++)\n"); //$NON-NLS-1$
buffer.append("// a is a pointer to a VLA with n*m+300 elements\n"); //$NON-NLS-1$
buffer.append("a[i][j] += x;\n"); //$NON-NLS-1$
buffer.append("}\n"); //$NON-NLS-1$
parseCandCPP(buffer.toString(), true, 0);
buffer.append("}\n");
String code = buffer.toString(); //$NON-NLS-1$
// no valid c++ code
parse(code, ParserLanguage.C, true, 0);
}
/**

View file

@ -1971,8 +1971,7 @@ public class AST2TemplateTests extends AST2BaseTest {
ICPPSpecialization spec = (ICPPSpecialization) col.getName(9).resolveBinding();
assertSame(spec.getSpecializedBinding(), ctor);
ICPPSpecialization c = (ICPPSpecialization) col.getName(10).resolveBinding();
assertSame(c.getSpecializedBinding(), g);
ICPPParameter c = (ICPPParameter) col.getName(10).resolveBinding();
assertSame(blah, col.getName(11).resolveBinding());
assertSame(c, col.getName(12).resolveBinding());
@ -1980,8 +1979,7 @@ public class AST2TemplateTests extends AST2BaseTest {
ICPPSpecialization spec2 = (ICPPSpecialization) col.getName(13).resolveBinding();
assertSame(spec.getSpecializedBinding(), ctor);
ICPPSpecialization c2 = (ICPPSpecialization) col.getName(14).resolveBinding();
assertSame(c2.getSpecializedBinding(), g);
ICPPParameter c2 = (ICPPParameter) col.getName(14).resolveBinding();
assertSame(blah, col.getName(15).resolveBinding());
assertSame(c2, col.getName(16).resolveBinding());
@ -4056,7 +4054,7 @@ public class AST2TemplateTests extends AST2BaseTest {
// void test() {
// S(a);
// }
public void _testFunctionTemplateWithArrayReferenceParameter_269926() throws Exception {
public void testFunctionTemplateWithArrayReferenceParameter_269926() throws Exception {
final String code = getAboveComment();
parseAndCheckBindings(code, ParserLanguage.CPP);
}
@ -4106,4 +4104,14 @@ public class AST2TemplateTests extends AST2BaseTest {
final String code = getAboveComment();
parseAndCheckBindings(code, ParserLanguage.CPP);
}
// template <int N> void T(int (&array)[N]) {};
// void test() {
// int a[2];
// T<2>(a);
// }
public void testInstantiationOfArraySize_269926() throws Exception {
final String code= getAboveComment();
parseAndCheckBindings(code, ParserLanguage.CPP);
}
}

View file

@ -5157,10 +5157,10 @@ public class AST2Tests extends AST2BaseTest {
BindingAssertionHelper ba= new BindingAssertionHelper(getAboveComment(), isCpp);
IFunction f= ba.assertNonProblem("f1", 2, IFunction.class);
isTypeEqual(f.getType(), "int (* (int))[]");
isTypeEqual(f.getType(), "int (* (int))[5]");
f= ba.assertNonProblem("f1 ", 2, IFunction.class);
isTypeEqual(f.getType(), "int (* (int))[]");
isTypeEqual(f.getType(), "int (* (int))[5]");
}
}

View file

@ -24,6 +24,7 @@ import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.ICompositeType;
import org.eclipse.cdt.core.dom.ast.IEnumeration;
import org.eclipse.cdt.core.dom.ast.IEnumerator;
import org.eclipse.cdt.core.dom.ast.IFunction;
import org.eclipse.cdt.core.dom.ast.IPointerType;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.IValue;
@ -1364,6 +1365,19 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
assertEquals(i, numericalValue.intValue());
}
// void f(int (&v)[1]);
// void f(int (&v)[2]);
// void test() {
// int a[1], b[2];
// f(a); f(b);
// }
public void testArrayTypeWithSize_269926() throws Exception {
IFunction f1= getBindingFromASTName("f(a)", 1, IFunction.class);
IFunction f2= getBindingFromASTName("f(b)", 1, IFunction.class);
assertFalse(f1.equals(f2));
}
/* CPP assertion helpers */
/* ##################################################################### */

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2005, 2008 QNX Software Systems
* Copyright (c) 2005, 2009 QNX Software Systems
* 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
@ -33,6 +33,7 @@ import org.eclipse.core.runtime.IPath;
public class DBTest extends BaseTestCase {
protected Database db;
@Override
protected void setUp() throws Exception {
super.setUp();
db = new Database(getTestDir().append(getName()+System.currentTimeMillis()+".dat").toFile(),
@ -52,6 +53,7 @@ public class DBTest extends BaseTestCase {
return path;
}
@Override
protected void tearDown() throws Exception {
db.close();
if(!db.getLocation().delete()) {
@ -72,8 +74,8 @@ public class DBTest extends BaseTestCase {
assertEquals(-blocksize, db.getShort(mem - Database.BLOCK_HEADER_SIZE));
db.free(mem);
assertEquals(blocksize, db.getShort(mem - Database.BLOCK_HEADER_SIZE));
assertEquals(mem - Database.BLOCK_HEADER_SIZE, db.getRecPtr((deltas-Database.MIN_BLOCK_DELTAS+1) * Database.INT_SIZE));
assertEquals(mem - Database.BLOCK_HEADER_SIZE + blocksize, db.getRecPtr((freeDeltas-Database.MIN_BLOCK_DELTAS+1) * Database.INT_SIZE));
assertEquals(mem, db.getRecPtr((deltas-Database.MIN_BLOCK_DELTAS+1) * Database.INT_SIZE));
assertEquals(mem + blocksize, db.getRecPtr((freeDeltas-Database.MIN_BLOCK_DELTAS+1) * Database.INT_SIZE));
}
public void testBug192437() throws IOException {
@ -110,10 +112,10 @@ public class DBTest extends BaseTestCase {
long mem2 = db.malloc(realsize);
db.free(mem1);
db.free(mem2);
assertEquals(mem2 - Database.BLOCK_HEADER_SIZE, db.getRecPtr((deltas-Database.MIN_BLOCK_DELTAS+1) * Database.INT_SIZE));
assertEquals(mem2, db.getRecPtr((deltas-Database.MIN_BLOCK_DELTAS+1) * Database.INT_SIZE));
assertEquals(0, db.getRecPtr(mem2));
assertEquals(mem1 - Database.BLOCK_HEADER_SIZE, db.getRecPtr(mem2 + Database.INT_SIZE));
assertEquals(mem2 - Database.BLOCK_HEADER_SIZE, db.getRecPtr(mem1));
assertEquals(mem1, db.getRecPtr(mem2 + Database.INT_SIZE));
assertEquals(mem2, db.getRecPtr(mem1));
assertEquals(0, db.getRecPtr(mem1 + Database.INT_SIZE));
}

View file

@ -39,6 +39,7 @@ import org.eclipse.cdt.core.parser.GCCKeywords;
import org.eclipse.cdt.core.parser.Keywords;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer;
import org.eclipse.cdt.internal.core.dom.parser.Value;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTTypeId;
import org.eclipse.cdt.internal.core.dom.parser.c.CVisitor;
import org.eclipse.cdt.internal.core.dom.parser.c.ICInternalBinding;
@ -202,22 +203,23 @@ public class ASTTypeUtil {
result.append(Keywords.cpLBRACKET);
if (type instanceof ICArrayType) {
try {
if (((ICArrayType) type).isConst()) {
final ICArrayType catype = (ICArrayType) type;
if (catype.isConst()) {
result.append(Keywords.CONST); needSpace = true;
}
if (((ICArrayType) type).isRestrict()) {
if (catype.isRestrict()) {
if (needSpace) {
result.append(SPACE); needSpace = false;
}
result.append(Keywords.RESTRICT); needSpace = true;
}
if (((ICArrayType) type).isStatic()) {
if (catype.isStatic()) {
if (needSpace) {
result.append(SPACE); needSpace = false;
}
result.append(Keywords.STATIC); needSpace = true;
}
if (((ICArrayType) type).isVolatile()) {
if (catype.isVolatile()) {
if (needSpace) {
result.append(SPACE); needSpace = false;
}
@ -226,6 +228,23 @@ public class ASTTypeUtil {
} catch (DOMException e) {
}
}
IValue val= ((IArrayType) type).getSize();
if (val != null && val != Value.UNKNOWN) {
if (normalize) {
if (needSpace) {
result.append(SPACE); needSpace = false;
}
result.append(val.getSignature());
} else {
Long v= val.numericalValue();
if (v != null) {
if (needSpace) {
result.append(SPACE); needSpace = false;
}
result.append(v.longValue());
}
}
}
result.append(Keywords.cpRBRACKET);
} else if (type instanceof IBasicType) {
IBasicType basicType= (IBasicType) type;

View file

@ -7,6 +7,7 @@
*
* Contributors:
* Andrew Niefer (IBM Corporation) - initial API and implementation
* Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.core.dom.ast;
@ -20,6 +21,12 @@ public interface IArrayType extends IType {
*/
IType getType();
/**
* Returns the value for the size of the array type, or <code>null</code> if it is unspecified.
* @since 5.2
*/
IValue getSize();
/**
* get the expression that represents the size of this array
* @throws DOMException

View file

@ -19,6 +19,7 @@ import org.eclipse.cdt.core.dom.ast.IASTFieldDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.dom.parser.c.CVisitor;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
@ -136,4 +137,12 @@ public class ASTQueries {
}
return active;
}
public static boolean isSameType(IType type1, IType type2) {
if (type1 == type2)
return true;
if (type1 == null || type2 == null)
return false;
return type1.isSameType(type2);
}
}

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
@ -45,6 +45,7 @@ import org.eclipse.cdt.internal.core.parser.scanner.ExpressionEvaluator.EvalExce
public class Value implements IValue {
public static final int MAX_RECURSION_DEPTH = 25;
public final static IValue UNKNOWN= new Value("<unknown>".toCharArray(), ICPPUnknownBinding.EMPTY_UNKNOWN_BINDING_ARRAY); //$NON-NLS-1$
public final static IValue NOT_INITIALIZED= new Value("<__>".toCharArray(), ICPPUnknownBinding.EMPTY_UNKNOWN_BINDING_ARRAY); //$NON-NLS-1$
private static final String SCOPE_OP = "::"; //$NON-NLS-1$
private static final char UNIQUE_CHAR = '_';
@ -225,8 +226,8 @@ public class Value implements IValue {
*/
public static boolean referencesTemplateParameter(IValue tval) {
final char[] rep= tval.getInternalExpression();
for (int i = 0; i < rep.length; i++) {
if (rep[i] == TEMPLATE_PARAM_CHAR)
for (char element : rep) {
if (element == TEMPLATE_PARAM_CHAR)
return true;
}
return false;
@ -237,8 +238,7 @@ public class Value implements IValue {
*/
public static boolean isDependentValue(IValue nonTypeValue) {
final char[] rep= nonTypeValue.getInternalExpression();
for (int i = 0; i < rep.length; i++) {
final char c = rep[i];
for (final char c : rep) {
if (c == REFERENCE_CHAR || c == TEMPLATE_PARAM_CHAR)
return true;
}

View file

@ -6,7 +6,7 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
* Devin Steffler (IBM Corporation) - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.c;
@ -16,14 +16,14 @@ import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IArrayType;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.ITypedef;
import org.eclipse.cdt.core.dom.ast.IValue;
import org.eclipse.cdt.core.dom.ast.c.ICASTArrayModifier;
import org.eclipse.cdt.core.dom.ast.c.ICArrayType;
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.Value;
import org.eclipse.cdt.internal.core.index.IIndexType;
/**
* @author dsteffle
*/
public class CArrayType implements ICArrayType, ITypeContainer {
IType type;
ICASTArrayModifier mod;
@ -35,7 +35,7 @@ public class CArrayType implements ICArrayType, ITypeContainer {
public boolean isSameType(IType obj) {
if (obj == this)
return true;
if (obj instanceof ITypedef)
if (obj instanceof ITypedef || obj instanceof IIndexType)
return obj.isSameType(this);
if (obj instanceof ICArrayType) {
ICArrayType at = (ICArrayType) obj;
@ -46,18 +46,24 @@ public class CArrayType implements ICArrayType, ITypeContainer {
if (isVolatile() != at.isVolatile()) return false;
if (isVariableLength() != at.isVariableLength()) return false;
return at.getType().isSameType(type);
return at.getType().isSameType(type) && hasSameSize(at);
} catch (DOMException e) {
return false;
}
}
// Workaround for bug 182976, no PDOMCArrayType.
else if (obj instanceof IArrayType && obj instanceof IIndexType) {
return obj.isSameType(this);
}
return false;
}
private boolean hasSameSize(IArrayType rhs) {
IValue s1 = getSize();
IValue s2 = rhs.getSize();
if (s1 == s2)
return true;
if (s1 == null || s2 == null)
return false;
return CharArrayUtils.equals(s1.getSignature(), s2.getSignature());
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IArrayType#getType()
*/
@ -117,9 +123,17 @@ public class CArrayType implements ICArrayType, ITypeContainer {
return mod;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IArrayType#getArraySizeExpression()
*/
public IValue getSize() {
if (mod != null) {
IASTExpression sizeExpression = mod.getConstantExpression();
if (sizeExpression != null) {
return Value.create(sizeExpression, Value.MAX_RECURSION_DEPTH);
}
}
return null;
}
@Deprecated
public IASTExpression getArraySizeExpression() {
if (mod != null)
return mod.getConstantExpression();

View file

@ -16,16 +16,25 @@ import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IArrayType;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.ITypedef;
import org.eclipse.cdt.core.dom.ast.IValue;
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.Value;
public class CPPArrayType implements IArrayType, ITypeContainer {
private IType type;
private IASTExpression sizeExpression;
private IValue value= Value.NOT_INITIALIZED;
public CPPArrayType(IType type) {
this.type = type;
}
public CPPArrayType(IType type, IValue value) {
this.type= type;
this.value= value;
}
public CPPArrayType(IType type, IASTExpression sizeExp) {
this.type = type;
this.sizeExpression = sizeExp;
@ -46,16 +55,34 @@ public class CPPArrayType implements IArrayType, ITypeContainer {
return ((ITypedef) obj).isSameType(this);
if (obj instanceof IArrayType) {
IType objType = ((IArrayType) obj).getType();
if (objType != null)
return objType.isSameType(type);
final IArrayType rhs = (IArrayType) obj;
IType objType = rhs.getType();
if (objType != null) {
if (objType.isSameType(type)) {
IValue s1= getSize();
IValue s2= rhs.getSize();
if (s1 == s2)
return true;
if (s1 == null || s2 == null)
return false;
return CharArrayUtils.equals(s1.getSignature(), s2.getSignature());
}
}
}
return false;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IArrayType#getArraySizeExpression()
*/
public IValue getSize() {
if (value != Value.NOT_INITIALIZED)
return value;
if (sizeExpression == null)
return value= null;
return value= Value.create(sizeExpression, Value.MAX_RECURSION_DEPTH);
}
@Deprecated
public IASTExpression getArraySizeExpression() {
return sizeExpression;
}

View file

@ -99,9 +99,9 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope {
}
char[] className = name.getLookupKey();
IParameter[] voidPs = new IParameter[] { new CPPParameter(CPPSemantics.VOID_TYPE) };
IParameter[] voidPs = new IParameter[] { new CPPParameter(CPPSemantics.VOID_TYPE, 0) };
IType pType = new CPPReferenceType(SemanticUtil.addQualifiers(clsType, true, false));
IParameter[] ps = new IParameter[] { new CPPParameter(pType) };
IParameter[] ps = new IParameter[] { new CPPParameter(pType, 0) };
int i= 0;
ImplicitsAnalysis ia= new ImplicitsAnalysis(compTypeSpec);

View file

@ -164,18 +164,18 @@ public class CPPFunction extends PlatformObject implements ICPPFunction, ICPPInt
return definition;
}
public void addDefinition(IASTNode node) {
public final void addDefinition(IASTNode node) {
ICPPASTFunctionDeclarator dtor = extractFunctionDtor(node);
if (dtor != null) {
updateParameterBindings(dtor);
updateFunctionParameterBindings(dtor);
definition = dtor;
}
}
public void addDeclaration(IASTNode node) {
public final void addDeclaration(IASTNode node) {
ICPPASTFunctionDeclarator dtor = extractFunctionDtor(node);
if (dtor != null) {
updateParameterBindings(dtor);
updateFunctionParameterBindings(dtor);
if (declarations == null) {
declarations = new ICPPASTFunctionDeclarator[] { dtor };
@ -213,7 +213,7 @@ public class CPPFunction extends PlatformObject implements ICPPFunction, ICPPInt
if (size > 0) {
for (int i = 0; i < size; i++) {
IASTParameterDeclaration p = params[i];
final IASTName name = ASTQueries.findInnermostDeclarator(p.getDeclarator()).getName();
final IASTName name = getParamName(p);
final IBinding binding= name.resolveBinding();
if (binding instanceof IParameter) {
result[i]= (IParameter) binding;
@ -287,67 +287,60 @@ public class CPPFunction extends PlatformObject implements ICPPFunction, ICPPInt
return type;
}
public IBinding resolveParameter(IASTParameterDeclaration param) {
IASTDeclarator dtor = param.getDeclarator();
while (dtor.getNestedDeclarator() != null)
dtor = dtor.getNestedDeclarator();
IASTName name = dtor.getName();
IBinding binding = name.getBinding();
if (binding != null)
return binding;
public IBinding resolveParameter(CPPParameter param) {
int pos= param.getParameterPosition();
IASTStandardFunctionDeclarator fdtor = (IASTStandardFunctionDeclarator) param.getParent();
IASTParameterDeclaration[] ps = fdtor.getParameters();
int i = 0;
for (; i < ps.length; i++) {
if (param == ps[i])
int tdeclLen= declarations == null ? 0 : declarations.length;
for (int i= -1; i < tdeclLen; i++) {
ICPPASTFunctionDeclarator tdecl;
if (i == -1) {
tdecl= definition;
if (tdecl == null)
continue;
} else {
tdecl= declarations[i];
if (tdecl == null)
break;
}
//create a new binding and set it for the corresponding parameter in all known defns and decls
binding = new CPPParameter(name);
IASTParameterDeclaration temp = null;
if (definition != null) {
IASTParameterDeclaration[] paramDecls = definition.getParameters();
if (paramDecls.length > i) { // This will be less than i if we have a void parameter
temp = paramDecls[i];
IASTName n = ASTQueries.findInnermostDeclarator(temp.getDeclarator()).getName();
if (n != name) {
n.setBinding(binding);
ASTInternal.addDeclaration(binding, n);
IASTParameterDeclaration[] params = tdecl.getParameters();
if (pos < params.length) {
final IASTName oName = getParamName(params[pos]);
return oName.resolvePreBinding();
}
}
}
if (declarations != null) {
for (int j = 0; j < declarations.length && declarations[j] != null; j++) {
IASTParameterDeclaration[] paramDecls = declarations[j].getParameters();
if (paramDecls.length > i) {
temp = paramDecls[i];
IASTName n = ASTQueries.findInnermostDeclarator(temp.getDeclarator()).getName();
if (n != name) {
n.setBinding(binding);
ASTInternal.addDeclaration(binding, n);
}
}
}
}
return binding;
return param;
}
protected void updateParameterBindings(ICPPASTFunctionDeclarator fdtor) {
ICPPASTFunctionDeclarator orig = definition != null ? definition : declarations[0];
IASTParameterDeclaration[] ops = orig.getParameters();
IASTParameterDeclaration[] nps = fdtor.getParameters();
CPPParameter temp = null;
for (int i = 0; i < ops.length; i++) {
temp = (CPPParameter) ASTQueries.findInnermostDeclarator(ops[i].getDeclarator()).getName().getBinding();
if (temp != null && nps.length > i) { //length could be different, ie 0 or 1 with void
IASTDeclarator dtor = nps[i].getDeclarator();
while (dtor.getNestedDeclarator() != null)
dtor = dtor.getNestedDeclarator();
IASTName name = dtor.getName();
name.setBinding(temp);
ASTInternal.addDeclaration(temp, name);
private IASTName getParamName(final IASTParameterDeclaration paramDecl) {
return ASTQueries.findInnermostDeclarator(paramDecl.getDeclarator()).getName();
}
protected final void updateFunctionParameterBindings(ICPPASTFunctionDeclarator fdtor) {
IASTParameterDeclaration[] updateParams = fdtor.getParameters();
int k= 0;
int tdeclLen= declarations == null ? 0 : declarations.length;
for (int i= -1; i < tdeclLen && k < updateParams.length; i++) {
ICPPASTFunctionDeclarator tdecl;
if (i == -1) {
tdecl= definition;
if (tdecl == null)
continue;
} else {
tdecl= declarations[i];
if (tdecl == null)
break;
}
IASTParameterDeclaration[] params = tdecl.getParameters();
int end= Math.min(params.length, updateParams.length);
for (; k < end; k++) {
final IASTName oName = getParamName(params[k]);
IBinding b= oName.resolvePreBinding();
IASTName n = getParamName(updateParams[k]);
n.setBinding(b);
ASTInternal.addDeclaration(b, n);
}
}
}

View file

@ -158,39 +158,68 @@ public class CPPFunctionSpecialization extends CPPSpecialization implements ICPP
return false;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalFunction#resolveParameter(org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration)
*/
public IBinding resolveParameter(IASTParameterDeclaration param) {
IASTDeclarator dtor = param.getDeclarator();
while (dtor.getNestedDeclarator() != null)
dtor = dtor.getNestedDeclarator();
IASTName name = dtor.getName();
IBinding binding = name.getBinding();
if (binding != null)
return binding;
public IBinding resolveParameter(CPPParameter param) {
int pos= param.getParameterPosition();
ICPPASTFunctionDeclarator fdtor = (ICPPASTFunctionDeclarator) param.getParent();
IASTParameterDeclaration[] ps = fdtor.getParameters();
int i = 0;
for (; i < ps.length; i++) {
if (param == ps[i])
final IASTNode[] decls= getDeclarations();
int tdeclLen= decls == null ? 0 : decls.length;
for (int i= -1; i < tdeclLen; i++) {
ICPPASTFunctionDeclarator tdecl;
if (i == -1) {
tdecl= (ICPPASTFunctionDeclarator) getDefinition();
if (tdecl == null)
continue;
} else if (decls != null){
tdecl= (ICPPASTFunctionDeclarator) decls[i];
if (tdecl == null)
break;
} else {
break;
}
try {
IParameter[] params = getParameters();
if (i < params.length) {
final IParameter myParam = params[i];
name.setBinding(myParam);
ASTInternal.addDeclaration(myParam, name);
return myParam;
IASTParameterDeclaration[] params = tdecl.getParameters();
if (pos < params.length) {
final IASTName oName = getParamName(params[pos]);
return oName.resolvePreBinding();
}
}
return param;
}
} catch (DOMException e) {
return e.getProblem();
protected void updateFunctionParameterBindings(ICPPASTFunctionDeclarator fdtor) {
IASTParameterDeclaration[] updateParams = fdtor.getParameters();
int k= 0;
final IASTNode[] decls= getDeclarations();
int tdeclLen= decls == null ? 0 : decls.length;
for (int i= -1; i < tdeclLen && k < updateParams.length; i++) {
ICPPASTFunctionDeclarator tdecl;
if (i == -1) {
tdecl= (ICPPASTFunctionDeclarator) getDefinition();
if (tdecl == null)
continue;
} else if (decls != null) {
tdecl= (ICPPASTFunctionDeclarator) decls[i];
if (tdecl == null)
break;
} else {
break;
}
return null;
IASTParameterDeclaration[] params = tdecl.getParameters();
int end= Math.min(params.length, updateParams.length);
for (; k < end; k++) {
final IASTName oName = getParamName(params[k]);
IBinding b= oName.resolvePreBinding();
IASTName n = getParamName(updateParams[k]);
n.setBinding(b);
ASTInternal.addDeclaration(b, n);
}
}
}
private IASTName getParamName(final IASTParameterDeclaration paramDecl) {
return ASTQueries.findInnermostDeclarator(paramDecl.getDeclarator()).getName();
}
private ICPPASTFunctionDeclarator extractFunctionDtor(IASTNode node) {
@ -209,7 +238,7 @@ public class CPPFunctionSpecialization extends CPPSpecialization implements ICPP
public void addDefinition(IASTNode node) {
ICPPASTFunctionDeclarator dtor = extractFunctionDtor(node);
if (dtor != null) {
updateParameterBindings(dtor);
updateFunctionParameterBindings(dtor);
super.addDefinition(dtor);
}
}
@ -218,32 +247,11 @@ public class CPPFunctionSpecialization extends CPPSpecialization implements ICPP
public void addDeclaration(IASTNode node) {
ICPPASTFunctionDeclarator dtor = extractFunctionDtor(node);
if (dtor != null) {
updateParameterBindings(dtor);
updateFunctionParameterBindings(dtor);
super.addDeclaration(dtor);
}
}
protected void updateParameterBindings(ICPPASTFunctionDeclarator fdtor) {
IParameter[] params = null;
try {
params = getParameters();
} catch (DOMException e) {
return;
}
IASTParameterDeclaration[] nps = fdtor.getParameters();
for (int i = 0; i < nps.length; i++) {
final IParameter param = params[i];
if (param != null) {
IASTDeclarator dtor = nps[i].getDeclarator();
while (dtor.getNestedDeclarator() != null)
dtor = dtor.getNestedDeclarator();
IASTName name = dtor.getName();
name.setBinding(param);
ASTInternal.addDeclaration(param, name);
}
}
}
@Override
public String toString() {
StringBuilder result = new StringBuilder();

View file

@ -113,7 +113,11 @@ public class CPPFunctionTemplate extends CPPTemplateDefinition
public void addDefinition(IASTNode node) {
if (!(node instanceof IASTName))
return;
updateFunctionParameterBindings((IASTName) node);
ICPPASTFunctionDeclarator fdecl= getDeclaratorByName(node);
if (fdecl == null)
return;
updateFunctionParameterBindings(fdecl);
super.addDefinition(node);
}
@ -121,24 +125,12 @@ public class CPPFunctionTemplate extends CPPTemplateDefinition
public void addDeclaration(IASTNode node) {
if (!(node instanceof IASTName))
return;
updateFunctionParameterBindings((IASTName) node);
super.addDeclaration(node);
}
ICPPASTFunctionDeclarator fdecl= getDeclaratorByName(node);
if (fdecl == null)
return;
private void updateFunctionParameterBindings(IASTName declName) {
IASTName defName = definition != null ? definition : declarations[0];
ICPPASTFunctionDeclarator orig = getDeclaratorByName(defName);
IASTParameterDeclaration[] ops = orig.getParameters();
IASTParameterDeclaration[] nps = getDeclaratorByName(declName).getParameters();
CPPParameter temp = null;
for(int i = 0; i < nps.length; i++) {
temp = (CPPParameter) ASTQueries.findInnermostDeclarator(ops[i].getDeclarator()).getName().getBinding();
if (temp != null) {
IASTName name = ASTQueries.findInnermostDeclarator(nps[i].getDeclarator()).getName();
name.setBinding(temp);
ASTInternal.addDeclaration(temp, name);
}
}
updateFunctionParameterBindings(fdecl);
super.addDeclaration(node);
}
public IParameter[] getParameters() {
@ -212,48 +204,68 @@ public class CPPFunctionTemplate extends CPPTemplateDefinition
return false;
}
public IBinding resolveParameter(IASTParameterDeclaration param) {
IASTName name = ASTQueries.findInnermostDeclarator(param.getDeclarator()).getName();
IBinding binding = name.getBinding();
if (binding != null)
return binding;
public IBinding resolveParameter(CPPParameter param) {
int pos= param.getParameterPosition();
ICPPASTFunctionDeclarator fdtor = (ICPPASTFunctionDeclarator) param.getParent();
IASTParameterDeclaration[] ps = fdtor.getParameters();
int i = 0;
for (; i < ps.length; i++) {
if (param == ps[i])
final IASTNode[] decls= getDeclarations();
int tdeclLen= decls == null ? 0 : decls.length;
for (int i= -1; i < tdeclLen; i++) {
ICPPASTFunctionDeclarator tdecl;
if (i == -1) {
tdecl= getDeclaratorByName(getDefinition());
if (tdecl == null)
continue;
} else if (decls != null){
tdecl= getDeclaratorByName(decls[i]);
if (tdecl == null)
break;
} else {
break;
}
//create a new binding and set it for the corresponding parameter in all known defns and decls
binding = new CPPParameter(name);
IASTParameterDeclaration temp = null;
if (definition != null) {
ICPPASTFunctionDeclarator fdecl= getDeclaratorByName(definition);
if (fdecl != null) {
temp = fdecl.getParameters()[i];
IASTName n = ASTQueries.findInnermostDeclarator(temp.getDeclarator()).getName();
if (n != name) {
n.setBinding(binding);
ASTInternal.addDeclaration(binding, n);
IASTParameterDeclaration[] params = tdecl.getParameters();
if (pos < params.length) {
final IASTName oName = getParamName(params[pos]);
return oName.resolvePreBinding();
}
}
return param;
}
protected void updateFunctionParameterBindings(ICPPASTFunctionDeclarator fdtor) {
IASTParameterDeclaration[] updateParams = fdtor.getParameters();
int k= 0;
final IASTNode[] decls= getDeclarations();
int tdeclLen= decls == null ? 0 : decls.length;
for (int i= -1; i < tdeclLen && k < updateParams.length; i++) {
ICPPASTFunctionDeclarator tdecl;
if (i == -1) {
tdecl= getDeclaratorByName(getDefinition());
if (tdecl == null)
continue;
} else if (decls != null) {
tdecl= getDeclaratorByName(decls[i]);
if (tdecl == null)
break;
} else {
break;
}
IASTParameterDeclaration[] params = tdecl.getParameters();
int end= Math.min(params.length, updateParams.length);
for (; k < end; k++) {
final IASTName oName = getParamName(params[k]);
IBinding b= oName.resolvePreBinding();
IASTName n = getParamName(updateParams[k]);
n.setBinding(b);
ASTInternal.addDeclaration(b, n);
}
}
}
if (declarations != null) {
for(int j = 0; j < declarations.length && declarations[j] != null; j++) {
ICPPASTFunctionDeclarator fdecl= getDeclaratorByName(declarations[j]);
if (fdecl != null) {
temp = fdecl.getParameters()[i];
IASTName n = ASTQueries.findInnermostDeclarator(temp.getDeclarator()).getName();
if (n != name) {
n.setBinding(binding);
ASTInternal.addDeclaration(binding, n);
}
}
}
}
return binding;
private IASTName getParamName(final IASTParameterDeclaration paramDecl) {
return ASTQueries.findInnermostDeclarator(paramDecl.getDeclarator()).getName();
}
public boolean isStatic() {

View file

@ -11,15 +11,10 @@
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IParameter;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
import org.eclipse.cdt.internal.core.dom.parser.ASTInternal;
import org.eclipse.cdt.internal.core.dom.parser.ASTQueries;
/**
* The CPPImplicitFunction is used to represent implicit functions that exist on the translation
@ -82,58 +77,6 @@ public class CPPImplicitFunction extends CPPFunction {
return null;
}
@Override
public IBinding resolveParameter(IASTParameterDeclaration param) {
IASTName aName = ASTQueries.findInnermostDeclarator(param.getDeclarator()).getName();
IParameter binding = (IParameter) aName.getBinding();
if (binding != null)
return binding;
// get the index in the parameter list
ICPPASTFunctionDeclarator fdtor = (ICPPASTFunctionDeclarator) param.getParent();
IASTParameterDeclaration[] ps = fdtor.getParameters();
int i = 0;
for (; i < ps.length; i++) {
if (param == ps[i])
break;
}
// set the binding for the corresponding parameter in all known defns and decls
binding = parms[i];
IASTParameterDeclaration temp = null;
if (definition != null) {
temp = definition.getParameters()[i];
IASTName n = ASTQueries.findInnermostDeclarator(temp.getDeclarator()).getName();
n.setBinding(binding);
ASTInternal.addDeclaration(binding, n);
}
if (declarations != null) {
for (int j = 0; j < declarations.length && declarations[j] != null; j++) {
temp = declarations[j].getParameters()[i];
IASTName n = ASTQueries.findInnermostDeclarator(temp.getDeclarator()).getName();
n.setBinding(binding);
ASTInternal.addDeclaration(binding, n);
}
}
return binding;
}
@Override
protected void updateParameterBindings(ICPPASTFunctionDeclarator fdtor) {
if (parms != null) {
IASTParameterDeclaration[] nps = fdtor.getParameters();
if (nps.length != parms.length)
return;
for (int i = 0; i < nps.length; i++) {
IASTName aName = ASTQueries.findInnermostDeclarator(nps[i].getDeclarator()).getName();
final IParameter param = parms[i];
aName.setBinding(param);
ASTInternal.addDeclaration(param, aName);
}
}
}
@Override
public boolean takesVarArgs() {
return takesVarArgs;

View file

@ -16,6 +16,7 @@ import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.IASTInitializer;
import org.eclipse.cdt.core.dom.ast.IASTName;
@ -30,6 +31,7 @@ import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.internal.core.dom.Linkage;
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.ProblemBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
@ -38,7 +40,7 @@ import org.eclipse.core.runtime.PlatformObject;
/**
* Binding for a c++ function parameter
*/
public class CPPParameter extends PlatformObject implements ICPPParameter, ICPPInternalBinding {
public class CPPParameter extends PlatformObject implements ICPPParameter, ICPPInternalBinding, ICPPTwoPhaseBinding {
public static class CPPParameterProblem extends ProblemBinding implements ICPPParameter {
public CPPParameterProblem(IASTNode node, int id, char[] arg) {
super(node, id, arg);
@ -83,14 +85,17 @@ public class CPPParameter extends PlatformObject implements ICPPParameter, ICPPI
private IType type = null;
private IASTName[] declarations = null;
private int fPosition;
public CPPParameter(IASTName name) {
public CPPParameter(IASTName name, int pos) {
this.declarations = new IASTName[] { name };
fPosition= pos;
}
public CPPParameter(IType type) {
public CPPParameter(IType type, int pos) {
this.type = type;
fPosition= pos;
}
/* (non-Javadoc)
@ -301,4 +306,28 @@ public class CPPParameter extends PlatformObject implements ICPPParameter, ICPPI
public IValue getInitialValue() {
return null;
}
public IBinding resolveFinalBinding(CPPASTNameBase name) {
// check if the binding has been updated.
IBinding current= name.getPreBinding();
if (current != this)
return current;
IASTNode node= getPrimaryDeclaration();
while (node != null && !(node instanceof IASTFunctionDeclarator)) {
node= node.getParent();
}
if (node instanceof IASTFunctionDeclarator) {
IASTName funcName= ASTQueries.findInnermostDeclarator((IASTFunctionDeclarator) node).getName();
IBinding b= funcName.resolvePreBinding();
if (b instanceof ICPPInternalFunction) {
return ((ICPPInternalFunction) b).resolveParameter(this);
}
}
return this;
}
public int getParameterPosition() {
return fPosition;
}
}

View file

@ -12,7 +12,6 @@
package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
import org.eclipse.cdt.core.dom.ast.IBinding;
/**
@ -20,7 +19,10 @@ import org.eclipse.cdt.core.dom.ast.IBinding;
*/
public interface ICPPInternalFunction extends ICPPInternalBinding {
public IBinding resolveParameter( IASTParameterDeclaration param );
/**
* Called to resolve the parameter in the second phase.
*/
public IBinding resolveParameter(CPPParameter parameter);
/**
* Returns whether there is a static declaration for this function.

View file

@ -96,6 +96,7 @@ 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.Value;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTName;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPArrayType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClassInstance;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClassSpecialization;
@ -842,11 +843,11 @@ public class CPPTemplates {
}
if (type instanceof ITypeContainer) {
final ITypeContainer tc = (ITypeContainer) type;
IType nestedType = tc.getType();
final ITypeContainer typeContainer = (ITypeContainer) type;
IType nestedType = typeContainer.getType();
IType newNestedType = instantiateType(nestedType, tpMap, within);
if (type instanceof ICPPPointerToMemberType) {
ICPPPointerToMemberType ptm = (ICPPPointerToMemberType) type;
if (typeContainer instanceof ICPPPointerToMemberType) {
ICPPPointerToMemberType ptm = (ICPPPointerToMemberType) typeContainer;
IType memberOfClass = ptm.getMemberOfClass();
IType newMemberOfClass = instantiateType(memberOfClass, tpMap, within);
if (newNestedType != nestedType || newMemberOfClass != memberOfClass) {
@ -854,13 +855,22 @@ public class CPPTemplates {
return new CPPPointerToMemberType(newNestedType, newMemberOfClass,
ptm.isConst(), ptm.isVolatile());
}
return type;
return typeContainer;
}
} else if (typeContainer instanceof IArrayType) {
IArrayType at= (IArrayType) typeContainer;
IValue asize= at.getSize();
if (asize != null) {
IValue newSize= instantiateValue(asize, tpMap, within, Value.MAX_RECURSION_DEPTH);
if (newSize != asize) {
return new CPPArrayType(newNestedType, newSize);
}
}
}
if (newNestedType != nestedType) {
return SemanticUtil.replaceNestedType(tc, newNestedType);
return SemanticUtil.replaceNestedType(typeContainer, newNestedType);
}
return type;
return typeContainer;
}
return type;
@ -1595,6 +1605,32 @@ public class CPPTemplates {
}
p = ((ICPPReferenceType) p).getType();
a = ((ICPPReferenceType) a).getType();
} else if (p instanceof IArrayType) {
if (!(a instanceof IArrayType)) {
return false;
}
IArrayType aa= (IArrayType) a;
IArrayType pa= (IArrayType) p;
IValue as= aa.getSize();
IValue ps= pa.getSize();
if (as != ps) {
if (as == null || ps == null)
return false;
int parPos= Value.isTemplateParameter(ps);
if (parPos >= 0) {
ICPPTemplateArgument old= map.getArgument(parPos);
if (old == null) {
map.put(parPos, new CPPTemplateArgument(ps, new CPPBasicType(IBasicType.t_int, 0)));
} else if (!ps.equals(old.getNonTypeValue())) {
return false;
}
} else if (!ps.equals(as)) {
return false;
}
}
p = pa.getType();
a = aa.getType();
} else if (p instanceof IQualifierType) {
if (a instanceof IQualifierType) {
a = ((IQualifierType) a).getType(); //TODO a = strip qualifiers from p out of a
@ -1915,7 +1951,7 @@ public class CPPTemplates {
if (!(paramType instanceof IType))
return null;
IParameter[] functionParameters = new IParameter[] { new CPPParameter((IType) paramType) };
IParameter[] functionParameters = new IParameter[] { new CPPParameter((IType) paramType, 0) };
return new CPPImplicitFunctionTemplate(specialization.getTemplateParameters(), functionParameters);
} catch (DOMException e) {
@ -2085,6 +2121,11 @@ public class CPPTemplates {
return true;
t= ptmt.getType();
} else if (t instanceof ITypeContainer) {
if (t instanceof IArrayType) {
IValue asize= ((IArrayType) t).getSize();
if (asize != null && Value.isDependentValue(asize))
return true;
}
t= ((ITypeContainer) t).getType();
} else {
return false;

View file

@ -166,7 +166,6 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.GPPBasicType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.GPPPointerToMemberType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.GPPPointerType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalFunction;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding;
import org.eclipse.cdt.internal.core.index.IIndexScope;
@ -454,6 +453,7 @@ public class CPPVisitor extends ASTQueries {
}
return binding;
}
private static IBinding createBinding(IASTDeclaration declaration) {
if (declaration instanceof ICPPASTNamespaceDefinition) {
ICPPASTNamespaceDefinition namespaceDef = (ICPPASTNamespaceDefinition) declaration;
@ -499,6 +499,7 @@ public class CPPVisitor extends ASTQueries {
return null;
}
private static IBinding createBinding(IASTDeclarator declarator) {
IASTNode parent = findOutermostDeclarator(declarator).getParent();
declarator= findInnermostDeclarator(declarator);
@ -556,16 +557,13 @@ public class CPPVisitor extends ASTQueries {
if (!(findOutermostDeclarator(fdtor).getParent() instanceof IASTDeclaration) ||
findTypeRelevantDeclarator(fdtor) != fdtor)
return null;
IBinding temp = findInnermostDeclarator(fdtor).getName().resolveBinding();
if (temp instanceof ICPPInternalFunction) {
return ((ICPPInternalFunction) temp).resolveParameter(param);
} else if (temp instanceof IProblemBinding) {
//problems with the function, still create binding for the parameter
return new CPPParameter(name);
} else if (temp instanceof IIndexBinding) {
return new CPPParameter(name);
IASTParameterDeclaration[] params = fdtor.getParameters();
int i=0;
for(;i<params.length; i++) {
if (params[i] == param)
break;
}
return null;
return new CPPParameter(name, i);
} else if (parent instanceof ICPPASTTemplateDeclaration) {
return CPPTemplates.createBinding(param);
}
@ -600,28 +598,7 @@ public class CPPVisitor extends ASTQueries {
IASTSimpleDeclaration simpleDecl = (parent instanceof IASTSimpleDeclaration) ?
(IASTSimpleDeclaration) parent : null;
if (parent instanceof ICPPASTParameterDeclaration) {
ICPPASTParameterDeclaration param = (ICPPASTParameterDeclaration) parent;
parent = param.getParent();
if (parent instanceof IASTStandardFunctionDeclarator) {
IASTStandardFunctionDeclarator fdtor = (IASTStandardFunctionDeclarator) param.getParent();
// if the fdtor does not declare a function we don't create a binding for the parameter.
if (!(findOutermostDeclarator(fdtor).getParent() instanceof IASTDeclaration) ||
findTypeRelevantDeclarator(fdtor) != fdtor)
return null;
IBinding temp = findInnermostDeclarator(fdtor).getName().resolveBinding();
if (temp instanceof ICPPInternalFunction) {
binding = ((ICPPInternalFunction) temp).resolveParameter(param);
} else if (temp instanceof IProblemBinding) {
//problems with the function, still create binding for the parameter
binding = new CPPParameter(name);
} else if (temp instanceof IIndexBinding) {
binding= new CPPParameter(name);
}
} else if (parent instanceof ICPPASTTemplateDeclaration) {
return CPPTemplates.createBinding(param);
}
} else if (simpleDecl != null &&
if (simpleDecl != null &&
simpleDecl.getDeclSpecifier().getStorageClass() == IASTDeclSpecifier.sc_typedef) {
if (binding instanceof ICPPInternalBinding && binding instanceof ITypedef && name.isActive()) {
IType t1 = ((ITypedef) binding).getType();
@ -687,7 +664,7 @@ public class CPPVisitor extends ASTQueries {
}
}
if (t1 != null && t2 != null) {
if (t1.isSameType(t2)) {
if (t1.isSameType(t2) || isCompatibleArray(t1, t2) != null) {
ASTInternal.addDeclaration(binding, name);
} else {
binding = new ProblemBinding(name, IProblemBinding.SEMANTIC_INVALID_REDECLARATION);
@ -702,6 +679,24 @@ public class CPPVisitor extends ASTQueries {
return binding;
}
private static IType isCompatibleArray(IType t1, IType t2) {
if (t1 instanceof IArrayType && t2 instanceof IArrayType) {
IArrayType a1 = (IArrayType) t1;
IArrayType a2 = (IArrayType) t2;
if (!isSameType(a1.getType(), a2.getType())) {
return null;
}
if (a1.getSize() == null) {
if (a2.getSize() != null) {
return a2;
}
} else if (a2.getSize() == null) {
return a1;
}
}
return null;
}
public static boolean isConstructor(IScope containingScope, IASTDeclarator declarator) {
if (containingScope == null || !(containingScope instanceof ICPPClassScope))
return false;

View file

@ -15,6 +15,8 @@ import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IArrayType;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.ITypedef;
import org.eclipse.cdt.core.dom.ast.IValue;
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer;
public class ArrayTypeClone implements IIndexType, IArrayType, ITypeContainer {
@ -37,9 +39,23 @@ public class ArrayTypeClone implements IIndexType, IArrayType, ITypeContainer {
return false;
IArrayType rhs = (IArrayType) type;
return type1.isSameType(rhs.getType());
if (type1.isSameType(rhs.getType())) {
IValue s1= getSize();
IValue s2= rhs.getSize();
if (s1 == s2)
return true;
if (s1 == null || s2 == null)
return false;
return CharArrayUtils.equals(s1.getSignature(), s2.getSignature());
}
return false;
}
public IValue getSize() {
return delegate.getSize();
}
@Deprecated
public IASTExpression getArraySizeExpression() throws DOMException {
return delegate.getArraySizeExpression();
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2007 Symbian Software Systems and others.
* Copyright (c) 2007, 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
@ -10,9 +10,9 @@
*******************************************************************************/
package org.eclipse.cdt.internal.core.index.composite;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IArrayType;
import org.eclipse.cdt.core.dom.ast.IValue;
import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer;
import org.eclipse.cdt.internal.core.index.ArrayTypeClone;
@ -21,12 +21,17 @@ public class CompositeArrayType extends CompositeTypeContainer implements IArray
super((ITypeContainer) arrayType, cf);
}
public IASTExpression getArraySizeExpression() throws DOMException {
fail(); return null;
}
@Override
public Object clone() {
return new ArrayTypeClone(this);
}
public IValue getSize() {
return ((IArrayType) type).getSize();
}
@Deprecated
public IASTExpression getArraySizeExpression() {
return null;
}
}

View file

@ -181,18 +181,11 @@ public class PDOM extends PlatformObject implements IPDOM {
* 84.0 - storing free record pointers as (ptr>>3) and allocated pointers as (ptr-2)>>3 RECPTR_DENSE_VERSION
*
* CDT 7.0 development (versions not supported on the 6.0.x branch)
* next: 90.0
* 90.0 - support for array sizes, bug 269926
*/
private static final int MIN_SUPPORTED_VERSION= version(83, 0);
private static final int MAX_SUPPORTED_VERSION= version(84, Short.MAX_VALUE);
private static int DEFAULT_VERSION = version(84, 0);
public static final int DENSE_RECPTR_VERSION = version(84, 0);
static {
if (System.getProperty("org.eclipse.cdt.core.parser.pdom.useDensePointers", "false").equals("true")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
DEFAULT_VERSION= DENSE_RECPTR_VERSION;
}
}
private static final int MIN_SUPPORTED_VERSION= version(90, 0);
private static final int MAX_SUPPORTED_VERSION= version(90, Short.MAX_VALUE);
private static final int DEFAULT_VERSION = version(90, 0);
private static int version(int major, int minor) {
return (major << 16) + minor;

View file

@ -106,19 +106,10 @@ final class Chunk {
* pointer is not moved past the BLOCK_HEADER_SIZE.
*/
public void putRecPtr(final long offset, final long value) {
if (!fDatabase.usesDensePointers()) {
putFreeRecPtr(offset, value);
} else {
putFreeRecPtr(offset, value == 0 ? value : value - Database.BLOCK_HEADER_SIZE);
}
return;
}
public void putFreeRecPtr(final long offset, final long value) {
if (!fDatabase.usesDensePointers()) {
putInt(offset, (int) value);
return;
}
/*
* This assert verifies the alignment. We expect the low bits to be clear.
*/
@ -127,9 +118,6 @@ final class Chunk {
}
public long getRecPtr(final long offset) {
if (!fDatabase.usesDensePointers()) {
return getInt(offset);
}
long address = getFreeRecPtr(offset);
return address != 0 ? (address + Database.BLOCK_HEADER_SIZE) : address;
}
@ -137,9 +125,6 @@ final class Chunk {
public long getFreeRecPtr(final long offset) {
int value = getInt(offset);
if (!fDatabase.usesDensePointers()) {
return value;
}
/*
* We need to properly manage the integer that was read. The value will be sign-extended
* so if the most significant bit is set, the resulting long will look negative. By

View file

@ -24,7 +24,6 @@ import java.nio.channels.FileChannel;
import java.util.ArrayList;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.internal.core.pdom.PDOM;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
@ -74,6 +73,9 @@ public class Database {
public static final int MIN_BLOCK_DELTAS = 2; // a block must at least be 2 + 2*4 bytes to link the free blocks.
public static final int MAX_BLOCK_DELTAS = CHUNK_SIZE/BLOCK_SIZE_DELTA;
public static final int MAX_MALLOC_SIZE = MAX_BLOCK_DELTAS*BLOCK_SIZE_DELTA - BLOCK_HEADER_SIZE;
public static final int PTR_SIZE = 4; // size of a pointer in the database in bytes
public static final long MAX_DB_SIZE= ((long) 1 << (Integer.SIZE + BLOCK_SIZE_DELTA_BITS));
public static final int VERSION_OFFSET = 0;
public static final int DATA_AREA = (CHUNK_SIZE / BLOCK_SIZE_DELTA - MIN_BLOCK_DELTAS + 2) * INT_SIZE;
@ -360,14 +362,8 @@ public class Database {
* special status, the indexing operation should be stopped. This is desired since generally, once
* the max size is exceeded, there are lots of errors.
*/
long max_size;
if (usesDensePointers()) {
max_size = ((long) 1 << (Integer.SIZE + BLOCK_SIZE_DELTA_BITS));
} else {
max_size = ((long) 1 << (Integer.SIZE - 1));
}
if (address >= max_size) {
Object bindings[] = { this.getLocation().getAbsolutePath(), max_size };
if (address >= MAX_DB_SIZE) {
Object bindings[] = { this.getLocation().getAbsolutePath(), MAX_DB_SIZE };
throw new CoreException(new Status(IStatus.ERROR, CCorePlugin.PLUGIN_ID,
CCorePlugin.STATUS_PDOM_TOO_LARGE, NLS.bind(CCorePlugin
.getResourceString("pdom.DatabaseTooLarge"), bindings), null)); //$NON-NLS-1$
@ -376,13 +372,6 @@ public class Database {
}
}
/**
* Returns whether this database uses dense pointers.
*/
boolean usesDensePointers() {
return getVersion() >= PDOM.DENSE_RECPTR_VERSION;
}
/**
* for testing purposes, only.
*/

View file

@ -17,17 +17,25 @@ import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IArrayType;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.ITypedef;
import org.eclipse.cdt.core.dom.ast.IValue;
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.Value;
import org.eclipse.cdt.internal.core.index.ArrayTypeClone;
import org.eclipse.cdt.internal.core.index.IIndexBindingConstants;
import org.eclipse.cdt.internal.core.index.IIndexType;
import org.eclipse.cdt.internal.core.pdom.db.Database;
import org.eclipse.core.runtime.CoreException;
public class PDOMArrayType extends PDOMNode implements IIndexType, IArrayType, ITypeContainer {
private static final int TYPE = PDOMNode.RECORD_SIZE;
private static final int ARRAYSIZE= TYPE + Database.PTR_SIZE;
@SuppressWarnings("hiding")
private static final int RECORD_SIZE= TYPE+4;
private static final int RECORD_SIZE= ARRAYSIZE + Database.PTR_SIZE;
private IType fCachedType= null;
private IValue fCachedValue= Value.NOT_INITIALIZED;
public PDOMArrayType(PDOMLinkage linkage, long record) {
super(linkage, record);
@ -38,7 +46,13 @@ public class PDOMArrayType extends PDOMNode implements IIndexType, IArrayType, I
PDOMNode targetTypeNode = getLinkage().addType(this, type.getType());
if (targetTypeNode != null) {
long typeRec = targetTypeNode.getRecord();
getDB().putRecPtr(record + TYPE, typeRec);
final Database db = getDB();
db.putRecPtr(record + TYPE, typeRec);
IValue val= type.getSize();
if (val != null) {
long ptr= PDOMValue.store(db, linkage, val);
db.putRecPtr(record + ARRAYSIZE, ptr);
}
}
}
@ -52,19 +66,34 @@ public class PDOMArrayType extends PDOMNode implements IIndexType, IArrayType, I
return IIndexBindingConstants.ARRAY_TYPE;
}
public IASTExpression getArraySizeExpression() throws DOMException {
return null;
}
public IType getType() {
if (fCachedType == null) {
try {
PDOMNode node = getLinkage().getNode(getDB().getRecPtr(record + TYPE));
return node instanceof IType ? (IType)node : null;
if (node instanceof IType) {
return fCachedType= (IType) node;
}
} catch (CoreException e) {
CCorePlugin.log(e);
return null;
}
}
return fCachedType;
}
public IValue getSize() {
if (fCachedValue == Value.NOT_INITIALIZED) {
try {
final Database db = getDB();
long ptr= db.getRecPtr(record + ARRAYSIZE);
return fCachedValue= PDOMValue.restore(db, getLinkage(), ptr);
} catch (CoreException e) {
CCorePlugin.log(e);
}
return fCachedValue= null;
}
return fCachedValue;
}
public boolean isSameType(IType type) {
if( type instanceof ITypedef )
@ -78,7 +107,16 @@ public class PDOMArrayType extends PDOMNode implements IIndexType, IArrayType, I
return false;
IArrayType rhs = (IArrayType) type;
return type1.isSameType( rhs.getType() );
if (type1.isSameType(rhs.getType())) {
IValue s1 = getSize();
IValue s2 = rhs.getSize();
if (s1 == s2)
return true;
if (s1 == null || s2 == null)
return false;
return CharArrayUtils.equals(s1.getSignature(), s2.getSignature());
}
return false;
}
public void setType(IType type) {
@ -95,4 +133,9 @@ public class PDOMArrayType extends PDOMNode implements IIndexType, IArrayType, I
linkage.deleteType(getType(), record);
super.delete(linkage);
}
@Deprecated
public IASTExpression getArraySizeExpression() throws DOMException {
return null;
}
}