This revision was not accepted when it landed; it landed in state "Needs
Review".
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rGef4bbfe338bd: [clang] AST: SubstTemplateTypeParmType support
for non-canonical underlying type (authored by mizvekov).
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D132816/new/
https://reviews.llvm.org/D132816
Files:
clang/include/clang/AST/Type.h
clang/include/clang/AST/TypeProperties.td
clang/lib/AST/ASTContext.cpp
clang/lib/AST/ASTImporter.cpp
clang/lib/AST/Type.cpp
clang/lib/Sema/SemaTemplate.cpp
clang/lib/Sema/TreeTransform.h
clang/test/AST/ast-dump-template-decls.cpp
Index: clang/test/AST/ast-dump-template-decls.cpp
===================================================================
--- clang/test/AST/ast-dump-template-decls.cpp
+++ clang/test/AST/ast-dump-template-decls.cpp
@@ -162,3 +162,22 @@
// CHECK: SubstTemplateTypeParmType 0x{{[^ ]*}} 'short' sugar pack_index 0
// CHECK-NEXT: TemplateTypeParmType 0x{{[^ ]*}} 'U' dependent contains_unexpanded_pack depth 0 index 0 pack
} // namespace PR56099
+
+namespace subst_default_argument {
+template<class A1> class A {};
+template<template<class C1, class C2 = A<C1>> class D1, class D2> using D = D1<D2>;
+
+template<class E1, class E2> class E {};
+using test1 = D<E, int>;
+// CHECK: TypeAliasDecl 0x{{[^ ]*}} <line:{{[1-9]+}}:1, col:23> col:7 test1 'D<subst_default_argument::E, int>':'subst_default_argument::E<int, subst_default_argument::A<int>>'
+// CHECK: TemplateSpecializationType 0x{{[^ ]*}} 'A<int>' sugar A
+// CHECK-NEXT: |-TemplateArgument type 'int':'int'
+// CHECK-NEXT: | `-SubstTemplateTypeParmType 0x{{[^ ]*}} 'int' sugar
+// CHECK-NEXT: | |-TemplateTypeParmType 0x{{[^ ]*}} 'C1' dependent depth 1 index 0
+// CHECK-NEXT: | | `-TemplateTypeParm 0x{{[^ ]*}} 'C1'
+// CHECK-NEXT: | `-SubstTemplateTypeParmType 0x{{[^ ]*}} 'int' sugar
+// CHECK-NEXT: | |-TemplateTypeParmType 0x{{[^ ]*}} 'type-parameter-0-1' dependent depth 0 index 1
+// CHECK-NEXT: | `-BuiltinType 0x{{[^ ]*}} 'int'
+// CHECK-NEXT: `-RecordType 0x{{[^ ]*}} 'subst_default_argument::A<int>'
+// CHECK-NEXT: `-ClassTemplateSpecialization 0x{{[^ ]*}} 'A'
+} // namespace subst_default_argument
Index: clang/lib/Sema/TreeTransform.h
===================================================================
--- clang/lib/Sema/TreeTransform.h
+++ clang/lib/Sema/TreeTransform.h
@@ -6408,8 +6408,6 @@
if (Replacement.isNull())
return QualType();
- // Always canonicalize the replacement type.
- Replacement = SemaRef.Context.getCanonicalType(Replacement);
QualType Result = SemaRef.Context.getSubstTemplateTypeParmType(
T->getReplacedParameter(), Replacement, T->getPackIndex());
Index: clang/lib/Sema/SemaTemplate.cpp
===================================================================
--- clang/lib/Sema/SemaTemplate.cpp
+++ clang/lib/Sema/SemaTemplate.cpp
@@ -3513,8 +3513,7 @@
0, IndexReplaced, false,
cast<TemplateTypeParmDecl>(TPL->getParam(IndexReplaced)));
return SemaRef.Context.getSubstTemplateTypeParmType(
- cast<TemplateTypeParmType>(TTP), Replacement.getCanonicalType(),
- PackIndexReplaced);
+ cast<TemplateTypeParmType>(TTP), Replacement, PackIndexReplaced);
};
switch (BTD->getBuiltinTemplateKind()) {
Index: clang/lib/AST/Type.cpp
===================================================================
--- clang/lib/AST/Type.cpp
+++ clang/lib/AST/Type.cpp
@@ -3650,10 +3650,16 @@
}
SubstTemplateTypeParmType::SubstTemplateTypeParmType(
- const TemplateTypeParmType *Param, QualType Canon,
+ const TemplateTypeParmType *Param, QualType Replacement,
Optional<unsigned> PackIndex)
- : Type(SubstTemplateTypeParm, Canon, Canon->getDependence()),
+ : Type(SubstTemplateTypeParm, Replacement.getCanonicalType(),
+ Replacement->getDependence()),
Replaced(Param) {
+ SubstTemplateTypeParmTypeBits.HasNonCanonicalUnderlyingType =
+ Replacement != getCanonicalTypeInternal();
+ if (SubstTemplateTypeParmTypeBits.HasNonCanonicalUnderlyingType)
+ *getTrailingObjects<QualType>() = Replacement;
+
SubstTemplateTypeParmTypeBits.PackIndex = PackIndex ? *PackIndex + 1 : 0;
}
Index: clang/lib/AST/ASTImporter.cpp
===================================================================
--- clang/lib/AST/ASTImporter.cpp
+++ clang/lib/AST/ASTImporter.cpp
@@ -1530,8 +1530,7 @@
return ToReplacementTypeOrErr.takeError();
return Importer.getToContext().getSubstTemplateTypeParmType(
- *ReplacedOrErr, ToReplacementTypeOrErr->getCanonicalType(),
- T->getPackIndex());
+ *ReplacedOrErr, *ToReplacementTypeOrErr, T->getPackIndex());
}
ExpectedType ASTNodeImporter::VisitSubstTemplateTypeParmPackType(
Index: clang/lib/AST/ASTContext.cpp
===================================================================
--- clang/lib/AST/ASTContext.cpp
+++ clang/lib/AST/ASTContext.cpp
@@ -4764,9 +4764,6 @@
ASTContext::getSubstTemplateTypeParmType(const TemplateTypeParmType *Parm,
QualType Replacement,
Optional<unsigned> PackIndex) const {
- assert(Replacement.isCanonical()
- && "replacement types must always be canonical");
-
llvm::FoldingSetNodeID ID;
SubstTemplateTypeParmType::Profile(ID, Parm, Replacement, PackIndex);
void *InsertPos = nullptr;
@@ -4774,8 +4771,11 @@
= SubstTemplateTypeParmTypes.FindNodeOrInsertPos(ID, InsertPos);
if (!SubstParm) {
- SubstParm = new (*this, TypeAlignment)
- SubstTemplateTypeParmType(Parm, Replacement, PackIndex);
+ void *Mem = Allocate(SubstTemplateTypeParmType::totalSizeToAlloc<QualType>(
+ !Replacement.isCanonical()),
+ TypeAlignment);
+ SubstParm =
+ new (Mem) SubstTemplateTypeParmType(Parm, Replacement, PackIndex);
Types.push_back(SubstParm);
SubstTemplateTypeParmTypes.InsertNode(SubstParm, InsertPos);
}
Index: clang/include/clang/AST/TypeProperties.td
===================================================================
--- clang/include/clang/AST/TypeProperties.td
+++ clang/include/clang/AST/TypeProperties.td
@@ -739,10 +739,9 @@
}
def : Creator<[{
- // The call to getCanonicalType here existed in ASTReader.cpp, too.
return ctx.getSubstTemplateTypeParmType(
cast<TemplateTypeParmType>(replacedParameter),
- ctx.getCanonicalType(replacementType), PackIndex);
+ replacementType, PackIndex);
}]>;
}
Index: clang/include/clang/AST/Type.h
===================================================================
--- clang/include/clang/AST/Type.h
+++ clang/include/clang/AST/Type.h
@@ -1798,6 +1798,8 @@
unsigned : NumTypeBits;
+ unsigned HasNonCanonicalUnderlyingType : 1;
+
/// Represents the index within a pack if this represents a substitution
/// from a pack expansion. This index starts at the end of the pack and
/// increments towards the beginning.
@@ -4985,8 +4987,12 @@
/// been replaced with these. They are used solely to record that a
/// type was originally written as a template type parameter;
/// therefore they are never canonical.
-class SubstTemplateTypeParmType : public Type, public llvm::FoldingSetNode {
+class SubstTemplateTypeParmType final
+ : public Type,
+ public llvm::FoldingSetNode,
+ private llvm::TrailingObjects<SubstTemplateTypeParmType, QualType> {
friend class ASTContext;
+ friend class llvm::TrailingObjects<SubstTemplateTypeParmType, QualType>;
// The original type parameter.
const TemplateTypeParmType *Replaced;
@@ -5003,7 +5009,9 @@
/// Gets the type that was substituted for the template
/// parameter.
QualType getReplacementType() const {
- return getCanonicalTypeInternal();
+ return SubstTemplateTypeParmTypeBits.HasNonCanonicalUnderlyingType
+ ? *getTrailingObjects<QualType>()
+ : getCanonicalTypeInternal();
}
Optional<unsigned> getPackIndex() const {
@@ -5023,7 +5031,7 @@
const TemplateTypeParmType *Replaced,
QualType Replacement, Optional<unsigned> PackIndex) {
ID.AddPointer(Replaced);
- ID.AddPointer(Replacement.getAsOpaquePtr());
+ Replacement.Profile(ID);
ID.AddInteger(PackIndex ? *PackIndex - 1 : 0);
}
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits