mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
Fixed another case of an infinite loop. This time accompanied by a memory leak.
This commit is contained in:
parent
973c77a635
commit
12cc9fcc6a
8 changed files with 144 additions and 67 deletions
|
@ -0,0 +1,29 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2008 Google, 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Sergey Prigogin (Google) - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.core.dom.ast;
|
||||
|
||||
import org.eclipse.cdt.core.parser.util.IObjectComparator;
|
||||
|
||||
public class ASTTypeComparator implements IObjectComparator {
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if the two objects are equal or represent the same type.
|
||||
*/
|
||||
public boolean isSame(Object o1, Object o2) {
|
||||
if (o1 == o2) {
|
||||
return true;
|
||||
}
|
||||
if (o1 instanceof IType && o2 instanceof IType) {
|
||||
return ((IType) o1).isSameType((IType) o2);
|
||||
}
|
||||
return o1.equals(o2);
|
||||
}
|
||||
}
|
|
@ -6,7 +6,8 @@
|
|||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM - Initial API and implementation
|
||||
* IBM - Initial API and implementation
|
||||
* Sergey Prigogin (Google)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.core.dom.ast;
|
||||
|
||||
|
@ -14,12 +15,14 @@ package org.eclipse.cdt.core.dom.ast;
|
|||
* @author Doug Schaefer
|
||||
*/
|
||||
public interface IType extends Cloneable {
|
||||
public static final IType [] EMPTY_TYPE_ARRAY = new IType[0];
|
||||
public static final IType[] EMPTY_TYPE_ARRAY = new IType[0];
|
||||
public static final ASTTypeComparator TYPE_COMPARATOR = new ASTTypeComparator();
|
||||
|
||||
public Object clone();
|
||||
|
||||
/**
|
||||
* is the given type the same as this type?
|
||||
* @param type
|
||||
*/
|
||||
public boolean isSameType( IType type );
|
||||
public boolean isSameType(IType type);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2008 Google, 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Sergey Prigogin (Google) - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.core.parser.util;
|
||||
|
||||
public interface IObjectComparator {
|
||||
boolean isSame(Object o1, Object o2);
|
||||
}
|
|
@ -144,7 +144,21 @@ public class ObjectMap extends ObjectTable<Object> {
|
|||
System.arraycopy(valueTable, 0, vals, 0, vals.length);
|
||||
return vals;
|
||||
}
|
||||
|
||||
|
||||
public boolean isSame(ObjectMap other, IObjectComparator comparator) {
|
||||
if (!super.isSame(other, comparator)) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < keyTable.length; i++) {
|
||||
Object val1 = valueTable[i];
|
||||
Object val2 = other.valueTable[i];
|
||||
if (val1 != val2 && !comparator.isSame(val1, val2)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder("{"); //$NON-NLS-1$
|
||||
|
|
|
@ -34,7 +34,7 @@ public abstract class ObjectTable<T> extends HashTable {
|
|||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public Object clone(){
|
||||
public Object clone() {
|
||||
ObjectTable<T> newTable = (ObjectTable<T>) super.clone();
|
||||
|
||||
int size = capacity();
|
||||
|
@ -44,10 +44,10 @@ public abstract class ObjectTable<T> extends HashTable {
|
|||
return newTable;
|
||||
}
|
||||
|
||||
public List<T> toList(){
|
||||
public List<T> toList() {
|
||||
List<T> list = new ArrayList<T>(size());
|
||||
int size = size();
|
||||
for (int i = 0; i < size; i++){
|
||||
for (int i = 0; i < size; i++) {
|
||||
list.add(keyAt(i));
|
||||
}
|
||||
return list;
|
||||
|
@ -61,14 +61,14 @@ public abstract class ObjectTable<T> extends HashTable {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void clear(){
|
||||
public void clear() {
|
||||
super.clear();
|
||||
for (int i = 0; i < keyTable.length; i++)
|
||||
keyTable[i] = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final int hash(int pos){
|
||||
protected final int hash(int pos) {
|
||||
return hash(keyTable[pos]);
|
||||
}
|
||||
|
||||
|
@ -111,7 +111,7 @@ public abstract class ObjectTable<T> extends HashTable {
|
|||
removeEntry(i, hash);
|
||||
}
|
||||
|
||||
protected final int lookup(Object buffer){
|
||||
protected final int lookup(Object buffer) {
|
||||
if (hashTable != null) {
|
||||
int hash = hash(buffer);
|
||||
|
||||
|
@ -137,11 +137,11 @@ public abstract class ObjectTable<T> extends HashTable {
|
|||
return -1;
|
||||
}
|
||||
|
||||
public boolean containsKey(T key){
|
||||
public boolean containsKey(T key) {
|
||||
return lookup(key) != -1;
|
||||
}
|
||||
|
||||
public Object[] keyArray(){
|
||||
public Object[] keyArray() {
|
||||
Object[] keys = new Object[size()];
|
||||
System.arraycopy(keyTable, 0, keys, 0, keys.length);
|
||||
return keys;
|
||||
|
@ -153,4 +153,19 @@ public abstract class ObjectTable<T> extends HashTable {
|
|||
System.arraycopy(keyTable, 0, keys, 0, keys.length);
|
||||
return keys;
|
||||
}
|
||||
|
||||
public boolean isSame(ObjectTable<T> other, IObjectComparator comparator) {
|
||||
if (size() != other.size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < keyTable.length; i++) {
|
||||
T key1 = keyTable[i];
|
||||
T key2 = other.keyTable[i];
|
||||
if (key1 != key2 && !comparator.isSame(key1, key2)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,16 +27,18 @@ import org.eclipse.cdt.core.parser.util.ArrayUtil;
|
|||
* @author jcamelon
|
||||
*/
|
||||
public class CPPASTFunctionDeclarator extends CPPASTDeclarator implements ICPPASTFunctionDeclarator {
|
||||
|
||||
private IASTParameterDeclaration [] parameters = null;
|
||||
private int parametersPos=-1;
|
||||
private IASTParameterDeclaration[] parameters = null;
|
||||
private int parametersPos = -1;
|
||||
private ICPPFunctionScope scope = null;
|
||||
private boolean varArgs;
|
||||
private boolean pureVirtual;
|
||||
private boolean isVolatile;
|
||||
private boolean isConst;
|
||||
|
||||
|
||||
private IASTTypeId[] typeIds = null;
|
||||
private int typeIdsPos = -1;
|
||||
private ICPPASTConstructorChainInitializer[] constructorChain = null;
|
||||
private int constructorChainPos = -1;
|
||||
|
||||
public CPPASTFunctionDeclarator() {
|
||||
}
|
||||
|
||||
|
@ -44,9 +46,9 @@ public class CPPASTFunctionDeclarator extends CPPASTDeclarator implements ICPPAS
|
|||
super(name);
|
||||
}
|
||||
|
||||
public IASTParameterDeclaration [] getParameters() {
|
||||
if( parameters == null ) return IASTParameterDeclaration.EMPTY_PARAMETERDECLARATION_ARRAY;
|
||||
parameters = (IASTParameterDeclaration[]) ArrayUtil.removeNullsAfter( IASTParameterDeclaration.class, parameters, parametersPos );
|
||||
public IASTParameterDeclaration[] getParameters() {
|
||||
if (parameters == null) return IASTParameterDeclaration.EMPTY_PARAMETERDECLARATION_ARRAY;
|
||||
parameters = (IASTParameterDeclaration[]) ArrayUtil.removeNullsAfter(IASTParameterDeclaration.class, parameters, parametersPos);
|
||||
return parameters;
|
||||
}
|
||||
|
||||
|
@ -54,7 +56,7 @@ public class CPPASTFunctionDeclarator extends CPPASTDeclarator implements ICPPAS
|
|||
if (parameter != null) {
|
||||
parameter.setParent(this);
|
||||
parameter.setPropertyInParent(FUNCTION_PARAMETER);
|
||||
parameters = (IASTParameterDeclaration []) ArrayUtil.append( IASTParameterDeclaration.class, parameters, ++parametersPos, parameter );
|
||||
parameters = (IASTParameterDeclaration[]) ArrayUtil.append(IASTParameterDeclaration.class, parameters, ++parametersPos, parameter);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -66,12 +68,10 @@ public class CPPASTFunctionDeclarator extends CPPASTDeclarator implements ICPPAS
|
|||
varArgs = value;
|
||||
}
|
||||
|
||||
|
||||
public boolean isConst() {
|
||||
return isConst;
|
||||
}
|
||||
|
||||
|
||||
public void setConst(boolean value) {
|
||||
this.isConst = value;
|
||||
}
|
||||
|
@ -84,82 +84,73 @@ public class CPPASTFunctionDeclarator extends CPPASTDeclarator implements ICPPAS
|
|||
this.isVolatile = value;
|
||||
}
|
||||
|
||||
private IASTTypeId [] typeIds = null;
|
||||
private int typeIdsPos=-1;
|
||||
|
||||
public IASTTypeId[] getExceptionSpecification() {
|
||||
if( typeIds == null ) return IASTTypeId.EMPTY_TYPEID_ARRAY;
|
||||
typeIds = (IASTTypeId[]) ArrayUtil.removeNullsAfter( IASTTypeId.class, typeIds, typeIdsPos );
|
||||
if (typeIds == null) return IASTTypeId.EMPTY_TYPEID_ARRAY;
|
||||
typeIds = (IASTTypeId[]) ArrayUtil.removeNullsAfter(IASTTypeId.class, typeIds, typeIdsPos);
|
||||
return typeIds;
|
||||
}
|
||||
|
||||
|
||||
public void addExceptionSpecificationTypeId(IASTTypeId typeId) {
|
||||
if (typeId != null) {
|
||||
typeIds = (IASTTypeId[]) ArrayUtil.append( IASTTypeId.class, typeIds, ++typeIdsPos, typeId );
|
||||
typeIds = (IASTTypeId[]) ArrayUtil.append(IASTTypeId.class, typeIds, ++typeIdsPos, typeId);
|
||||
typeId.setParent(this);
|
||||
typeId.setPropertyInParent(EXCEPTION_TYPEID);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public boolean isPureVirtual() {
|
||||
return pureVirtual;
|
||||
}
|
||||
|
||||
|
||||
public void setPureVirtual(boolean isPureVirtual) {
|
||||
this.pureVirtual = isPureVirtual;
|
||||
}
|
||||
|
||||
|
||||
private ICPPASTConstructorChainInitializer [] constructorChain = null;
|
||||
private int constructorChainPos=-1;
|
||||
|
||||
|
||||
public ICPPASTConstructorChainInitializer[] getConstructorChain() {
|
||||
if( constructorChain == null ) return ICPPASTConstructorChainInitializer.EMPTY_CONSTRUCTORCHAININITIALIZER_ARRAY;
|
||||
constructorChain = (ICPPASTConstructorChainInitializer[]) ArrayUtil.removeNullsAfter( ICPPASTConstructorChainInitializer.class, constructorChain, constructorChainPos );
|
||||
if (constructorChain == null) return ICPPASTConstructorChainInitializer.EMPTY_CONSTRUCTORCHAININITIALIZER_ARRAY;
|
||||
constructorChain = (ICPPASTConstructorChainInitializer[]) ArrayUtil.removeNullsAfter(
|
||||
ICPPASTConstructorChainInitializer.class, constructorChain, constructorChainPos);
|
||||
return constructorChain;
|
||||
}
|
||||
|
||||
|
||||
public void addConstructorToChain(ICPPASTConstructorChainInitializer initializer) {
|
||||
if (initializer != null) {
|
||||
constructorChain = (ICPPASTConstructorChainInitializer[]) ArrayUtil.append(ICPPASTConstructorChainInitializer.class, constructorChain, ++constructorChainPos, initializer );
|
||||
constructorChain = (ICPPASTConstructorChainInitializer[]) ArrayUtil.append(
|
||||
ICPPASTConstructorChainInitializer.class, constructorChain, ++constructorChainPos, initializer);
|
||||
initializer.setParent(this);
|
||||
initializer.setPropertyInParent(CONSTRUCTOR_CHAIN_MEMBER);
|
||||
}
|
||||
}
|
||||
|
||||
public ICPPFunctionScope getFunctionScope(){
|
||||
if( scope != null )
|
||||
public ICPPFunctionScope getFunctionScope() {
|
||||
if (scope != null)
|
||||
return scope;
|
||||
|
||||
ASTNodeProperty prop = getPropertyInParent();
|
||||
if( prop == IASTSimpleDeclaration.DECLARATOR || prop == IASTFunctionDefinition.DECLARATOR )
|
||||
scope = new CPPFunctionScope( this );
|
||||
if (prop == IASTSimpleDeclaration.DECLARATOR || prop == IASTFunctionDefinition.DECLARATOR) {
|
||||
scope = new CPPFunctionScope(this);
|
||||
}
|
||||
return scope;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean postAccept( ASTVisitor action ){
|
||||
IASTParameterDeclaration [] params = getParameters();
|
||||
for ( int i = 0; i < params.length; i++ ) {
|
||||
if( !params[i].accept( action ) ) return false;
|
||||
protected boolean postAccept(ASTVisitor action) {
|
||||
IASTParameterDeclaration[] params = getParameters();
|
||||
for (int i = 0; i < params.length; i++) {
|
||||
if (!params[i].accept(action)) return false;
|
||||
}
|
||||
|
||||
ICPPASTConstructorChainInitializer [] chain = getConstructorChain();
|
||||
for ( int i = 0; i < chain.length; i++ ) {
|
||||
if( !chain[i].accept( action ) ) return false;
|
||||
ICPPASTConstructorChainInitializer[] chain = getConstructorChain();
|
||||
for (int i = 0; i < chain.length; i++) {
|
||||
if (!chain[i].accept(action)) return false;
|
||||
}
|
||||
|
||||
IASTInitializer initializer = getInitializer();
|
||||
if( initializer != null ) if( !initializer.accept( action ) ) return false;
|
||||
if (initializer != null && !initializer.accept(action)) return false;
|
||||
|
||||
IASTTypeId[] ids = getExceptionSpecification();
|
||||
for ( int i = 0; i < ids.length; i++ ) {
|
||||
if( !ids[i].accept( action ) ) return false;
|
||||
for (int i = 0; i < ids.length; i++) {
|
||||
if (!ids[i].accept(action)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -48,8 +48,11 @@ public class CPPTypedefSpecialization extends CPPSpecialization implements IType
|
|||
public IType getType() throws DOMException {
|
||||
if (type == null) {
|
||||
type = CPPTemplates.instantiateType(getTypedef().getType(), argumentMap, getScope());
|
||||
if (type == this) {
|
||||
// A typedef pointing to itself is a sure recipe for an infinite loop.
|
||||
// A typedef pointing to itself is a sure recipe for an infinite loop -- replace with
|
||||
// a problem binding.
|
||||
if (type instanceof CPPTypedefSpecialization &&
|
||||
((CPPTypedefSpecialization) type).getSpecializedBinding().equals(getSpecializedBinding()) &&
|
||||
((CPPTypedefSpecialization) type).getArgumentMap().isSame(argumentMap, IType.TYPE_COMPARATOR)) {
|
||||
type = new ProblemBinding(getDefinition(), IProblemBinding.SEMANTIC_INVALID_TYPE,
|
||||
getNameCharArray());
|
||||
}
|
||||
|
|
|
@ -67,6 +67,8 @@ class PDOMCPPClassTemplate extends PDOMCPPClassType
|
|||
@SuppressWarnings("hiding")
|
||||
protected static final int RECORD_SIZE = PDOMCPPClassType.RECORD_SIZE + 16;
|
||||
|
||||
private ICPPTemplateParameter[] params; // Cached template parameters.
|
||||
|
||||
public PDOMCPPClassTemplate(PDOM pdom, PDOMNode parent, ICPPClassTemplate template) throws CoreException {
|
||||
super(pdom, parent, template);
|
||||
}
|
||||
|
@ -100,16 +102,21 @@ class PDOMCPPClassTemplate extends PDOMCPPClassType
|
|||
}
|
||||
|
||||
public ICPPTemplateParameter[] getTemplateParameters() {
|
||||
try {
|
||||
PDOMNodeLinkedList list = new PDOMNodeLinkedList(pdom, record + PARAMETERS, getLinkageImpl());
|
||||
TemplateParameterCollector visitor = new TemplateParameterCollector();
|
||||
list.accept(visitor);
|
||||
|
||||
return visitor.getTemplateParameters();
|
||||
} catch (CoreException e) {
|
||||
CCorePlugin.log(e);
|
||||
return new ICPPTemplateParameter[0];
|
||||
if (params == null) {
|
||||
try {
|
||||
PDOMNodeLinkedList list = new PDOMNodeLinkedList(pdom, record + PARAMETERS, getLinkageImpl());
|
||||
TemplateParameterCollector visitor = new TemplateParameterCollector();
|
||||
list.accept(visitor);
|
||||
params = visitor.getTemplateParameters();
|
||||
} catch (CoreException e) {
|
||||
CCorePlugin.log(e);
|
||||
params = ICPPTemplateParameter.EMPTY_TEMPLATE_PARAMETER_ARRAY;
|
||||
}
|
||||
}
|
||||
// Copy to a new array for safety.
|
||||
ICPPTemplateParameter[] result = new ICPPTemplateParameter[params.length];
|
||||
System.arraycopy(params, 0, result, 0, params.length);
|
||||
return result;
|
||||
}
|
||||
|
||||
private PDOMCPPClassTemplatePartialSpecialization getFirstPartial() throws CoreException {
|
||||
|
@ -310,7 +317,7 @@ class PDOMCPPClassTemplate extends PDOMCPPClassType
|
|||
if (template instanceof IProblemBinding)
|
||||
return template;
|
||||
if (template != null && template instanceof ICPPClassTemplatePartialSpecialization) {
|
||||
return ((PDOMCPPClassTemplate)template).instantiate(arguments);
|
||||
return ((PDOMCPPClassTemplate) template).instantiate(arguments);
|
||||
}
|
||||
|
||||
return CPPTemplates.instantiateTemplate(this, arguments, null);
|
||||
|
|
Loading…
Add table
Reference in a new issue