Author: vvassilev Date: Wed Mar 30 17:18:29 2016 New Revision: 264937 URL: http://llvm.org/viewvc/llvm-project?rev=264937&view=rev Log: Canonicalize UnaryTransformType types when they don't have a known underlying type.
Fixes https://llvm.org/bugs/show_bug.cgi?id=26014 Reviewed by Richard Smith. Added: cfe/trunk/test/Modules/Inputs/PR26014/ cfe/trunk/test/Modules/Inputs/PR26014/A.h cfe/trunk/test/Modules/Inputs/PR26014/B.h cfe/trunk/test/Modules/Inputs/PR26014/module.modulemap cfe/trunk/test/Modules/pr26014.cpp Modified: cfe/trunk/include/clang/AST/ASTContext.h cfe/trunk/include/clang/AST/Type.h cfe/trunk/lib/AST/ASTContext.cpp cfe/trunk/lib/AST/Type.cpp cfe/trunk/test/SemaCXX/underlying_type.cpp Modified: cfe/trunk/include/clang/AST/ASTContext.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=264937&r1=264936&r2=264937&view=diff ============================================================================== --- cfe/trunk/include/clang/AST/ASTContext.h (original) +++ cfe/trunk/include/clang/AST/ASTContext.h Wed Mar 30 17:18:29 2016 @@ -129,6 +129,8 @@ class ASTContext : public RefCountedBase llvm::FoldingSet<PackExpansionType> PackExpansionTypes; mutable llvm::FoldingSet<ObjCObjectTypeImpl> ObjCObjectTypes; mutable llvm::FoldingSet<ObjCObjectPointerType> ObjCObjectPointerTypes; + mutable llvm::FoldingSet<DependentUnaryTransformType> + DependentUnaryTransformTypes; mutable llvm::FoldingSet<AutoType> AutoTypes; mutable llvm::FoldingSet<AtomicType> AtomicTypes; llvm::FoldingSet<AttributedType> AttributedTypes; Modified: cfe/trunk/include/clang/AST/Type.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=264937&r1=264936&r2=264937&view=diff ============================================================================== --- cfe/trunk/include/clang/AST/Type.h (original) +++ cfe/trunk/include/clang/AST/Type.h Wed Mar 30 17:18:29 2016 @@ -3633,6 +3633,28 @@ public: } }; +/// \brief Internal representation of canonical, dependent +/// __underlying_type(type) types. +/// +/// This class is used internally by the ASTContext to manage +/// canonical, dependent types, only. Clients will only see instances +/// of this class via UnaryTransformType nodes. +class DependentUnaryTransformType : public UnaryTransformType, + public llvm::FoldingSetNode { +public: + DependentUnaryTransformType(const ASTContext &C, QualType BaseType, + UTTKind UKind); + void Profile(llvm::FoldingSetNodeID &ID) { + Profile(ID, getBaseType(), getUTTKind()); + } + + static void Profile(llvm::FoldingSetNodeID &ID, QualType BaseType, + UTTKind UKind) { + ID.AddPointer(BaseType.getAsOpaquePtr()); + ID.AddInteger((unsigned)UKind); + } +}; + class TagType : public Type { /// Stores the TagDecl associated with this type. The decl may point to any /// TagDecl that declares the entity. Modified: cfe/trunk/lib/AST/ASTContext.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=264937&r1=264936&r2=264937&view=diff ============================================================================== --- cfe/trunk/lib/AST/ASTContext.cpp (original) +++ cfe/trunk/lib/AST/ASTContext.cpp Wed Mar 30 17:18:29 2016 @@ -4020,13 +4020,35 @@ QualType ASTContext::getUnaryTransformTy QualType UnderlyingType, UnaryTransformType::UTTKind Kind) const { - UnaryTransformType *Ty = - new (*this, TypeAlignment) UnaryTransformType (BaseType, UnderlyingType, - Kind, - UnderlyingType->isDependentType() ? - QualType() : getCanonicalType(UnderlyingType)); - Types.push_back(Ty); - return QualType(Ty, 0); + UnaryTransformType *ut = nullptr; + + if (BaseType->isDependentType()) { + // Look in the folding set for an existing type. + llvm::FoldingSetNodeID ID; + DependentUnaryTransformType::Profile(ID, getCanonicalType(BaseType), Kind); + + void *InsertPos = nullptr; + DependentUnaryTransformType *Canon + = DependentUnaryTransformTypes.FindNodeOrInsertPos(ID, InsertPos); + + if (!Canon) { + // Build a new, canonical __underlying_type(type) type. + Canon = new (*this, TypeAlignment) + DependentUnaryTransformType(*this, getCanonicalType(BaseType), + Kind); + DependentUnaryTransformTypes.InsertNode(Canon, InsertPos); + } + ut = new (*this, TypeAlignment) UnaryTransformType (BaseType, + QualType(), Kind, + QualType(Canon, 0)); + } else { + QualType CanonType = getCanonicalType(UnderlyingType); + ut = new (*this, TypeAlignment) UnaryTransformType (BaseType, + UnderlyingType, Kind, + CanonType); + } + Types.push_back(ut); + return QualType(ut, 0); } /// getAutoType - Return the uniqued reference to the 'auto' type which has been Modified: cfe/trunk/lib/AST/Type.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=264937&r1=264936&r2=264937&view=diff ============================================================================== --- cfe/trunk/lib/AST/Type.cpp (original) +++ cfe/trunk/lib/AST/Type.cpp Wed Mar 30 17:18:29 2016 @@ -2935,6 +2935,24 @@ void DependentDecltypeType::Profile(llvm E->Profile(ID, Context, true); } +UnaryTransformType::UnaryTransformType(QualType BaseType, + QualType UnderlyingType, + UTTKind UKind, + QualType CanonicalType) + : Type(UnaryTransform, CanonicalType, BaseType->isDependentType(), + BaseType->isInstantiationDependentType(), + BaseType->isVariablyModifiedType(), + BaseType->containsUnexpandedParameterPack()) + , BaseType(BaseType), UnderlyingType(UnderlyingType), UKind(UKind) +{} + +DependentUnaryTransformType::DependentUnaryTransformType(const ASTContext &C, + QualType BaseType, + UTTKind UKind) + : UnaryTransformType(BaseType, C.DependentTy, UKind, QualType()) +{} + + TagType::TagType(TypeClass TC, const TagDecl *D, QualType can) : Type(TC, can, D->isDependentType(), /*InstantiationDependent=*/D->isDependentType(), @@ -2951,17 +2969,6 @@ static TagDecl *getInterestingTagDecl(Ta return decl; } -UnaryTransformType::UnaryTransformType(QualType BaseType, - QualType UnderlyingType, - UTTKind UKind, - QualType CanonicalType) - : Type(UnaryTransform, CanonicalType, UnderlyingType->isDependentType(), - UnderlyingType->isInstantiationDependentType(), - UnderlyingType->isVariablyModifiedType(), - BaseType->containsUnexpandedParameterPack()) - , BaseType(BaseType), UnderlyingType(UnderlyingType), UKind(UKind) -{} - TagDecl *TagType::getDecl() const { return getInterestingTagDecl(decl); } Added: cfe/trunk/test/Modules/Inputs/PR26014/A.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/PR26014/A.h?rev=264937&view=auto ============================================================================== --- cfe/trunk/test/Modules/Inputs/PR26014/A.h (added) +++ cfe/trunk/test/Modules/Inputs/PR26014/A.h Wed Mar 30 17:18:29 2016 @@ -0,0 +1,13 @@ +#ifndef _LIBCPP_TYPE_TRAITS +#define _LIBCPP_TYPE_TRAITS + + +template <class _Tp> +struct underlying_type +{ + typedef __underlying_type(_Tp) type; +}; + +#endif // _LIBCPP_TYPE_TRAITS + +#include "B.h" Added: cfe/trunk/test/Modules/Inputs/PR26014/B.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/PR26014/B.h?rev=264937&view=auto ============================================================================== --- cfe/trunk/test/Modules/Inputs/PR26014/B.h (added) +++ cfe/trunk/test/Modules/Inputs/PR26014/B.h Wed Mar 30 17:18:29 2016 @@ -0,0 +1,10 @@ +#ifndef _LIBCPP_TYPE_TRAITS +#define _LIBCPP_TYPE_TRAITS + +template <class _Tp> +struct underlying_type +{ + typedef __underlying_type(_Tp) type; +}; + +#endif // _LIBCPP_TYPE_TRAITS Added: cfe/trunk/test/Modules/Inputs/PR26014/module.modulemap URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/PR26014/module.modulemap?rev=264937&view=auto ============================================================================== --- cfe/trunk/test/Modules/Inputs/PR26014/module.modulemap (added) +++ cfe/trunk/test/Modules/Inputs/PR26014/module.modulemap Wed Mar 30 17:18:29 2016 @@ -0,0 +1,9 @@ +module A { + header "A.h" + export * +} + +module B { + header "B.h" + export * +} Added: cfe/trunk/test/Modules/pr26014.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/pr26014.cpp?rev=264937&view=auto ============================================================================== --- cfe/trunk/test/Modules/pr26014.cpp (added) +++ cfe/trunk/test/Modules/pr26014.cpp Wed Mar 30 17:18:29 2016 @@ -0,0 +1,7 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -I%S/Inputs/PR26014 -verify %s +// RUN: %clang_cc1 -fmodules -fmodule-map-file=%S/Inputs/PR26014/module.modulemap -fmodules-cache-path=%t -I%S/Inputs/PR26014 -verify %s + +#include "A.h" + +// expected-no-diagnostics Modified: cfe/trunk/test/SemaCXX/underlying_type.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/underlying_type.cpp?rev=264937&r1=264936&r2=264937&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/underlying_type.cpp (original) +++ cfe/trunk/test/SemaCXX/underlying_type.cpp Wed Mar 30 17:18:29 2016 @@ -55,3 +55,10 @@ namespace PR19966 { // expected-error@-2 {{constant expression}} }; } + +template<typename T> void f(__underlying_type(T)); +template<typename T> void f(__underlying_type(T)); +enum E {}; +void PR26014() { f<E>(0); } // should not yield an ambiguity error. + +template<typename ...T> void f(__underlying_type(T) v); // expected-error {{declaration type contains unexpanded parameter pack 'T'}} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits