diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTTypeComparator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTTypeComparator.java
new file mode 100644
index 00000000000..94e16895e28
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTTypeComparator.java
@@ -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 true
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);
+ }
+}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IType.java
index a743ce9828a..53ca22eaef3 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IType.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IType.java
@@ -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);
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/IObjectComparator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/IObjectComparator.java
new file mode 100644
index 00000000000..ebb2fe09b98
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/IObjectComparator.java
@@ -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);
+}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/ObjectMap.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/ObjectMap.java
index 5a8a1d31532..4f33592fc2d 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/ObjectMap.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/ObjectMap.java
@@ -144,7 +144,21 @@ public class ObjectMap extends ObjectTable {
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$
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/ObjectTable.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/ObjectTable.java
index 404e3cad3fc..7a8ae42ffa5 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/ObjectTable.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/ObjectTable.java
@@ -34,7 +34,7 @@ public abstract class ObjectTable extends HashTable {
@Override
@SuppressWarnings("unchecked")
- public Object clone(){
+ public Object clone() {
ObjectTable newTable = (ObjectTable) super.clone();
int size = capacity();
@@ -44,10 +44,10 @@ public abstract class ObjectTable extends HashTable {
return newTable;
}
- public List toList(){
+ public List toList() {
List list = new ArrayList(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 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 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 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 extends HashTable {
System.arraycopy(keyTable, 0, keys, 0, keys.length);
return keys;
}
+
+ public boolean isSame(ObjectTable 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;
+ }
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFunctionDeclarator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFunctionDeclarator.java
index 620b1d2947e..2aad0b00be8 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFunctionDeclarator.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFunctionDeclarator.java
@@ -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;
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTypedefSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTypedefSpecialization.java
index 151cdd73cfb..2a4b9714ca7 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTypedefSpecialization.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTypedefSpecialization.java
@@ -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());
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassTemplate.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassTemplate.java
index 9fdcb720c7c..8a2a9a92fb6 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassTemplate.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassTemplate.java
@@ -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);