diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java index e027262e19e..0866ecbb462 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java @@ -6735,4 +6735,28 @@ public class AST2CPPTests extends AST2BaseTest { ba.assertNonProblem("onRange(ir)", 7); parseAndCheckBindings(code, ParserLanguage.CPP); } + + // typedef int * pi; + // typedef int *const* pcpi; + // typedef const pi* pcpi2; + // void check(pcpi) {}; + // void testxxx() { + // pcpi p1; + // pcpi2 p2; + // check(p1); + // check(p2); + // } + // template class CT {}; + // CT ct1; + // CT ct2; + public void testConstTypedef_264474() throws Exception { + final String code = getAboveComment(); + BindingAssertionHelper ba= new BindingAssertionHelper(code, true); + ba.assertNonProblem("check(p2)", 5); + IBinding ct1= ba.assertNonProblem("CT", 8); + IBinding ct2= ba.assertNonProblem("CT", 9); + assertSame(ct1, ct2); + + parseAndCheckBindings(code, ParserLanguage.CPP); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTTypeUtil.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTTypeUtil.java index 3ae3afc4cd9..1776d7fdb55 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTTypeUtil.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTTypeUtil.java @@ -474,14 +474,33 @@ public class ASTTypeUtil { // push all of the types onto the stack int i = 0; + IQualifierType cvq= null; while (type != null && ++i < 100) { - final boolean isTypedef= type instanceof ITypedef; - if (!normalize || !isTypedef) { + if (!normalize) { types = (IType[]) ArrayUtil.append(IType.class, types, type); + if (type instanceof ITypedef) { + type= null; // stop here + } + } else { + if (type instanceof ITypedef) { + // skip it + } else { + if (cvq != null) { + if (type instanceof IQualifierType || type instanceof IPointerType) { + type= SemanticUtil.addQualifiers(type, cvq.isConst(), cvq.isVolatile()); + cvq= null; + } else { + types = (IType[]) ArrayUtil.append(IType.class, types, cvq); + } + } + if (type instanceof IQualifierType) { + cvq= (IQualifierType) type; + } else { + types = (IType[]) ArrayUtil.append(IType.class, types, type); + } + } } - if (!normalize && isTypedef) { - type= null; // stop here - } else if (type instanceof ITypeContainer) { + if (type instanceof ITypeContainer) { try { type = ((ITypeContainer) type).getType(); } catch (DOMException e) { @@ -490,7 +509,7 @@ public class ASTTypeUtil { } else { type= null; } - } + } // pop all of the types off of the stack, and build the string representation while doing so for (int j = types.length - 1; j >= 0; j--) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java index 1c1fd0accad..d6f39b00e1f 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java @@ -238,8 +238,17 @@ public class SemanticUtil { t= ((ITypedef) type).getType(); } else if (refs && type instanceof ICPPReferenceType) { t= ((ICPPReferenceType) type).getType(); - } else if (qualifiers && type instanceof IQualifierType) { - t= ((IQualifierType) type).getType(); + } else if (type instanceof IQualifierType) { + final IQualifierType qt = (IQualifierType) type; + if (qualifiers) { + t= qt.getType(); + } else if (typedefs) { + IType temp= qt.getType(); + if (temp instanceof ITypedef) { + temp= getNestedType(temp, TYPEDEFS); + return addQualifiers(temp, qt.isConst(), qt.isVolatile()); + } + } } else if (ptrQualifiers && type instanceof IPointerType) { if (type instanceof CPPPointerType) { return ((CPPPointerType) type).stripQualifiers(); @@ -309,15 +318,10 @@ public class SemanticUtil { public static IType replaceNestedType(ITypeContainer type, IType newNestedType) throws DOMException { // bug 249085 make sure not to add unnecessary qualifications if (type instanceof IQualifierType) { - IQualifierType qt1= (IQualifierType) type; - if (newNestedType instanceof IQualifierType) { - IQualifierType qt2= (IQualifierType) newNestedType; - return new CPPQualifierType(qt2.getType(), qt1.isConst() || qt2.isConst(), qt1.isVolatile() || qt2.isVolatile()); - } else if (newNestedType instanceof IPointerType) { - IPointerType pt2= (IPointerType) newNestedType; - return new CPPPointerType(pt2.getType(), qt1.isConst() || pt2.isConst(), qt1.isVolatile() || pt2.isVolatile()); - } + IQualifierType qt= (IQualifierType) type; + return addQualifiers(newNestedType, qt.isConst(), qt.isVolatile()); } + type = (ITypeContainer) type.clone(); type.setType(newNestedType); return type;