From 8ec3ab2f9413729cf1878fe639f2556affd5c8d3 Mon Sep 17 00:00:00 2001 From: Sergey Prigogin Date: Sun, 28 Oct 2012 10:41:48 +0100 Subject: [PATCH] Preservation of typedefs in template arguments. --- .../core/parser/tests/ast2/AST2CPPTests.java | 61 ++++++++++++++++--- .../eclipse/cdt/core/dom/ast/ASTTypeUtil.java | 3 +- .../dom/ast/cpp/ICPPTemplateArgument.java | 17 ++++-- .../cpp/CPPTemplateNonTypeArgument.java | 5 ++ .../parser/cpp/CPPTemplateTypeArgument.java | 16 ++++- .../parser/cpp/semantics/CPPTemplates.java | 2 +- .../core/dom/parser/cpp/semantics/EvalID.java | 4 +- .../parser/cpp/semantics/SemanticUtil.java | 2 +- .../semantics/TemplateArgumentDeduction.java | 5 +- .../eclipse/cdt/internal/core/pdom/PDOM.java | 7 ++- .../core/pdom/db/TypeMarshalBuffer.java | 5 +- .../text/contentassist2/CompletionTests.java | 4 +- 12 files changed, 104 insertions(+), 27 deletions(-) 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 506f6a13c0f..be7905597ef 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 @@ -4741,20 +4741,63 @@ public class AST2CPPTests extends AST2BaseTest { assertEquals("string", ((ITypedef) s3.getType()).getName()); } - // template - // struct vector { - // typedef T* const_iterator; - // const_iterator begin() const; - // }; - // - // void test(const vector& v) { + // template + // struct vector { + // typedef T* const_iterator; + // const_iterator begin() const; + // }; + // + // typedef int Element; + // + // void test(const vector& v) { // auto it = v.begin(); // } - public void testTypedefPreservation_380498_2() throws Exception { + public void testTypedefPreservation_380498_2() throws Exception { BindingAssertionHelper ba= getAssertionHelper(); ICPPVariable it = ba.assertNonProblem("it =", "it", ICPPVariable.class); assertTrue(it.getType() instanceof ITypedef); - assertEquals("vector::const_iterator", ASTTypeUtil.getType(it.getType(), false)); + assertEquals("vector::const_iterator", ASTTypeUtil.getType(it.getType(), false)); + } + + // template class char_traits {}; + // template > class basic_string {}; + // + // template + // struct iterator_traits { + // typedef typename _Iterator::reference reference; + // }; + // + // template + // struct iterator_traits<_Tp*> { + // typedef _Tp& reference; + // }; + // + // template + // struct normal_iterator { + // typedef iterator_traits<_Iterator> traits_type; + // typedef typename traits_type::reference reference; + // reference operator*() const; + // }; + // + // template struct vector { + // typedef T* pointer; + // typedef normal_iterator iterator; + // iterator begin(); + // iterator end(); + // }; + // + // typedef basic_string string; + // + // void test() { + // vector v; + // for (auto s : v) { + // } + // } + public void testTypedefPreservation_380498_3() throws Exception { + BindingAssertionHelper ba= getAssertionHelper(); + ICPPVariable s = ba.assertNonProblem("s :", "s", ICPPVariable.class); + assertTrue(s.getType() instanceof ITypedef); + assertEquals("string", ASTTypeUtil.getType(s.getType(), false)); } // int f() { 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 325295bd82d..3f62ddf6e3d 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 @@ -183,7 +183,8 @@ public class ASTTypeUtil { if (val != null) { buf.append(val.getSignature()); } else { - appendType(arg.getTypeValue(), normalize, buf); + IType type = normalize ? arg.getTypeValue() : arg.getOriginalTypeValue(); + appendType(type, normalize, buf); } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPTemplateArgument.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPTemplateArgument.java index a4aa4fb9c77..0f8fb9acff5 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPTemplateArgument.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPTemplateArgument.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2008, 2009 Wind River Systems, Inc. and others. + * Copyright (c) 2008, 2012 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 @@ -7,6 +7,7 @@ * * Contributors: * Markus Schorn - initial API and implementation + * Sergey Prigogin (Google) *******************************************************************************/ package org.eclipse.cdt.core.dom.ast.cpp; @@ -36,11 +37,19 @@ public interface ICPPTemplateArgument { boolean isTypeValue(); /** - * If this is a type value (suitable for a template type and template template parameters), - * the type used as a value is returned. - * For non-type values, null is returned. + * If this is a type value (suitable for a template type and template template parameters), + * the type used as a value is returned. + * For non-type values, null is returned. + * The returned type has all typedefs resolved. */ IType getTypeValue(); + + /** + * Similar to {@link #getTypeValue()} but returns the original type value before typedef + * resolution. + * @noreference This method is not intended to be referenced by clients. + */ + IType getOriginalTypeValue(); /** * If this is a non-type value (suitable for a template non-type parameters), diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateNonTypeArgument.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateNonTypeArgument.java index 3c095d5db00..9e6e6e080c7 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateNonTypeArgument.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateNonTypeArgument.java @@ -41,6 +41,11 @@ public class CPPTemplateNonTypeArgument implements ICPPTemplateArgument { return false; } + @Override + public IType getOriginalTypeValue() { + return null; + } + @Override public boolean isNonTypeValue() { return true; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateTypeArgument.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateTypeArgument.java index 7ec0f62f798..f5d5cd74919 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateTypeArgument.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateTypeArgument.java @@ -22,10 +22,17 @@ import org.eclipse.core.runtime.Assert; */ public class CPPTemplateTypeArgument implements ICPPTemplateArgument { private final IType fType; + private final IType fOriginalType; public CPPTemplateTypeArgument(IType type) { - Assert.isNotNull(type); - fType= type; + this(type, type); + } + + public CPPTemplateTypeArgument(IType simplifiedType, IType originalType) { + Assert.isNotNull(simplifiedType); + Assert.isNotNull(originalType); + fType= simplifiedType; + fOriginalType= originalType; } @Override @@ -43,6 +50,11 @@ public class CPPTemplateTypeArgument implements ICPPTemplateArgument { return fType; } + @Override + public IType getOriginalTypeValue() { + return fOriginalType; + } + @Override public IValue getNonTypeValue() { return null; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java index 122590d4731..6272376d8cb 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java @@ -1162,7 +1162,7 @@ public class CPPTemplates { } if (arg != null) { - IType t= arg.getTypeValue(); + IType t= arg.getOriginalTypeValue(); if (t != null) return t; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalID.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalID.java index 9d1cf787526..f16254948db 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalID.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalID.java @@ -13,6 +13,8 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics; import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE; import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE; +import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.TDEF; +import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.getNestedType; import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.IASTExpression; @@ -294,7 +296,7 @@ public class EvalID extends CPPEvaluation { } else if (nameOwner instanceof IType) { IType type = CPPTemplates.instantiateType((IType) nameOwner, tpMap, packOffset, within, point); if (type instanceof IBinding) - nameOwner = (IBinding) type; + nameOwner = (IBinding) getNestedType(type, TDEF); } if (fieldOwner instanceof IProblemBinding || nameOwner instanceof IProblemBinding) 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 3d9dadf4b01..706a45dcb25 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 @@ -512,7 +512,7 @@ public class SemanticUtil { final IType type= arg.getTypeValue(); final IType newType= getSimplifiedType(type); if (newType != type) { - return new CPPTemplateTypeArgument(newType); + return new CPPTemplateTypeArgument(newType, arg.getOriginalTypeValue()); } } return arg; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TemplateArgumentDeduction.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TemplateArgumentDeduction.java index 14d895b84ae..c494e701305 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TemplateArgumentDeduction.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TemplateArgumentDeduction.java @@ -665,11 +665,12 @@ public class TemplateArgumentDeduction { return tval.equals(sval); } - return fromType(p.getTypeValue(), a.getTypeValue(), false, point); + return fromType(p.getTypeValue(), a.getOriginalTypeValue(), false, point); } private boolean fromType(IType p, IType a, boolean allowCVQConversion, IASTNode point) throws DOMException { while (p != null) { + IType argumentTypeBeforeTypedefResolution = a; while (a instanceof ITypedef) a = ((ITypedef) a).getType(); if (p instanceof IBasicType) { @@ -762,7 +763,7 @@ public class TemplateArgumentDeduction { } if (a == null) return false; - return deduce(((ICPPTemplateParameter)p).getParameterID(), new CPPTemplateTypeArgument(a)); + return deduce(((ICPPTemplateParameter) p).getParameterID(), new CPPTemplateTypeArgument(a, argumentTypeBeforeTypedefResolution)); } else if (p instanceof ICPPTemplateInstance) { if (!(a instanceof ICPPTemplateInstance)) return false; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java index ba33a50e978..ad62367afd9 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java @@ -219,10 +219,11 @@ public class PDOM extends PlatformObject implements IPDOM { * #125.0# - Indexes for unresolved includes and files indexed with I/O errors. <> * 126.0 - Dependent expressions, bug 299911. * 127.0 - Explicit virtual overrides, bug 380623. + * 128.0 - Extended CPPTemplateTypeArgument to include the original type, bug 392278. */ - private static final int MIN_SUPPORTED_VERSION= version(127, 0); - private static final int MAX_SUPPORTED_VERSION= version(127, Short.MAX_VALUE); - private static final int DEFAULT_VERSION = version(127, 0); + private static final int MIN_SUPPORTED_VERSION= version(128, 0); + private static final int MAX_SUPPORTED_VERSION= version(128, Short.MAX_VALUE); + private static final int DEFAULT_VERSION = version(128, 0); private static int version(int major, int minor) { return (major << 16) + minor; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/TypeMarshalBuffer.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/TypeMarshalBuffer.java index b3e7656fca4..0a1b22fba04 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/TypeMarshalBuffer.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/TypeMarshalBuffer.java @@ -194,6 +194,7 @@ public class TypeMarshalBuffer implements ITypeMarshalBuffer { ((CPPTemplateNonTypeArgument) arg).getEvaluation().marshal(this, true); } else { marshalType(arg.getTypeValue()); + marshalType(arg.getOriginalTypeValue()); } } @@ -204,7 +205,9 @@ public class TypeMarshalBuffer implements ITypeMarshalBuffer { return new CPPTemplateNonTypeArgument((ICPPEvaluation) unmarshalEvaluation()); } else { fPos--; - return new CPPTemplateTypeArgument(unmarshalType()); + IType type = unmarshalType(); + IType originalType = unmarshalType(); + return new CPPTemplateTypeArgument(type, originalType); } } diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/CompletionTests.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/CompletionTests.java index bc27e46dee4..f41331227f9 100644 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/CompletionTests.java +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/CompletionTests.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006, 2011 Wind River Systems, Inc. and others. + * Copyright (c) 2006, 2012 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 @@ -1329,7 +1329,7 @@ public class CompletionTests extends AbstractContentAssistTest { // v.push_back(/*cursor*/); // } public void testTypedefSpecialization_Bug307818() throws Exception { - final String[] expected= { "push_back(const vector::value_type & value) : void" }; + final String[] expected= { "push_back(const vector::value_type & value) : void" }; assertParameterHint(expected); }