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 5ce1c9e2d9f..cf23d8328ef 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 @@ -36,7 +36,7 @@ public class CPPTypedefSpecialization extends CPPSpecialization implements IType } } - static final int MAX_RESOLUTION_DEPTH = 5; + public static final int MAX_RESOLUTION_DEPTH = 5; private IType type; private int fResolutionDepth; @@ -59,22 +59,31 @@ public class CPPTypedefSpecialization extends CPPSpecialization implements IType */ public IType getType() throws DOMException { if (type == null) { - if (++fResolutionDepth > MAX_RESOLUTION_DEPTH) { - type = new RecursionResolvingBinding(getDefinition(), getNameCharArray()); - } else { - type = CPPTemplates.instantiateType(getTypedef().getType(), argumentMap, getScope()); - // 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().isEquivalent(argumentMap, IType.TYPE_MATCHER)) { + try { + if (++fResolutionDepth > MAX_RESOLUTION_DEPTH) { type = new RecursionResolvingBinding(getDefinition(), getNameCharArray()); - } + } else { + type = CPPTemplates.instantiateType(getTypedef().getType(), argumentMap, getScope()); + // 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().isEquivalent(argumentMap, IType.TYPE_MATCHER)) { + type = new RecursionResolvingBinding(getDefinition(), getNameCharArray()); + } + } + } finally { + --fResolutionDepth; } } return type; } + public int incResolutionDepth(int increment) { + fResolutionDepth += increment; + return fResolutionDepth; + } + /* (non-Javadoc) * @see java.lang.Object#clone() */ diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPTypedefSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPTypedefSpecialization.java index 726f114bcca..d42e124ccd1 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPTypedefSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPTypedefSpecialization.java @@ -18,6 +18,7 @@ import org.eclipse.cdt.core.dom.ast.ITypedef; import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization; import org.eclipse.cdt.internal.core.Util; import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTypedefSpecialization; import org.eclipse.cdt.internal.core.index.CPPTypedefClone; import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants; import org.eclipse.cdt.internal.core.index.IIndexType; @@ -28,12 +29,10 @@ import org.eclipse.core.runtime.CoreException; /** * @author Bryan Wilkinson - * */ class PDOMCPPTypedefSpecialization extends PDOMCPPSpecialization implements ITypedef, ITypeContainer, IIndexType { - private static final int TYPE = PDOMCPPSpecialization.RECORD_SIZE + 0; @SuppressWarnings("hiding") @@ -44,12 +43,24 @@ class PDOMCPPTypedefSpecialization extends PDOMCPPSpecialization super(pdom, parent, (ICPPSpecialization) typedef, specialized); try { + if (typedef instanceof CPPTypedefSpecialization) { + if (((CPPTypedefSpecialization) typedef).incResolutionDepth(1) > + CPPTypedefSpecialization.MAX_RESOLUTION_DEPTH) { + return; + } + } IType type = typedef.getType(); + // The following may try to add the same typedef specialization to the index again. + // We protect against infinite recursion using a counter inside typedef. PDOMNode typeNode = parent.getLinkageImpl().addType(this, type); if (typeNode != null) pdom.getDB().putInt(record + TYPE, typeNode.getRecord()); } catch (DOMException e) { throw new CoreException(Util.createStatus(e)); + } finally { + if (typedef instanceof CPPTypedefSpecialization) { + ((CPPTypedefSpecialization) typedef).incResolutionDepth(-1); + } } }