mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[Debug info] Emit bound generic class type parameters when emitting AST types
This relands commit 45d4648bdb while ensuring that
sanityCheckCachedType uses the exact same condition (now factored into a helper
function) as createType() to determine whether a type is sized or not.
rdar://143833326
This commit is contained in:
@@ -1197,7 +1197,26 @@ private:
|
|||||||
Scope, Name, File, Line, SizeInBits, AlignInBits, Flags, DerivedFrom,
|
Scope, Name, File, Line, SizeInBits, AlignInBits, Flags, DerivedFrom,
|
||||||
DBuilder.getOrCreateArray(Elements), RuntimeLang, nullptr, UniqueID);
|
DBuilder.getOrCreateArray(Elements), RuntimeLang, nullptr, UniqueID);
|
||||||
DBuilder.replaceTemporary(std::move(FwdDecl), DITy);
|
DBuilder.replaceTemporary(std::move(FwdDecl), DITy);
|
||||||
return DITy;;
|
return DITy;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<bool, Type>
|
||||||
|
getUnsubstituedType(Type Ty, StringRef MangledName) {
|
||||||
|
if (!Ty)
|
||||||
|
return {false,{}};
|
||||||
|
// Go from Pair<Int, Double> to Pair<T, U>.
|
||||||
|
auto *Decl = Ty->getNominalOrBoundGenericNominal();
|
||||||
|
if (!Decl)
|
||||||
|
return {false, {}};
|
||||||
|
// Go from Pair<Int, Double> to Pair<T, U>.
|
||||||
|
Type InterfaceTy = Decl->getDeclaredInterfaceType();
|
||||||
|
Type UnsubstitutedTy = Decl->mapTypeIntoContext(InterfaceTy);
|
||||||
|
|
||||||
|
Mangle::ASTMangler Mangler(IGM.Context);
|
||||||
|
std::string DeclTypeMangledName = Mangler.mangleTypeForDebugger(
|
||||||
|
UnsubstitutedTy->mapTypeOutOfContext(), {});
|
||||||
|
bool IsUnsubstituted = (DeclTypeMangledName == MangledName);
|
||||||
|
return {IsUnsubstituted, UnsubstitutedTy};
|
||||||
}
|
}
|
||||||
|
|
||||||
llvm::DIType *
|
llvm::DIType *
|
||||||
@@ -1206,28 +1225,24 @@ private:
|
|||||||
unsigned SizeInBits, unsigned AlignInBits,
|
unsigned SizeInBits, unsigned AlignInBits,
|
||||||
llvm::DIScope *Scope, llvm::DIFile *File,
|
llvm::DIScope *Scope, llvm::DIFile *File,
|
||||||
unsigned Line, llvm::DINode::DIFlags Flags) {
|
unsigned Line, llvm::DINode::DIFlags Flags) {
|
||||||
auto UnsubstitutedTy = Decl->getDeclaredInterfaceType();
|
auto [IsUnsubstituted, UnsubstitutedTy] =
|
||||||
UnsubstitutedTy = Decl->mapTypeIntoContext(UnsubstitutedTy);
|
getUnsubstituedType(EnumTy, MangledName);
|
||||||
|
auto UnsubstitutedDbgTy = DebugTypeInfo::getFromTypeInfo(
|
||||||
auto DbgTy = DebugTypeInfo::getFromTypeInfo(
|
|
||||||
UnsubstitutedTy, IGM.getTypeInfoForUnlowered(UnsubstitutedTy), IGM);
|
UnsubstitutedTy, IGM.getTypeInfoForUnlowered(UnsubstitutedTy), IGM);
|
||||||
Mangle::ASTMangler Mangler(IGM.Context);
|
if (IsUnsubstituted)
|
||||||
std::string DeclTypeMangledName = Mangler.mangleTypeForDebugger(
|
return createUnsubstitutedVariantType(UnsubstitutedDbgTy, Decl,
|
||||||
UnsubstitutedTy->mapTypeOutOfContext(), {});
|
MangledName, Scope, File, 0, Flags);
|
||||||
if (DeclTypeMangledName == MangledName) {
|
|
||||||
return createUnsubstitutedVariantType(DbgTy, Decl, MangledName, Scope,
|
|
||||||
File, 0, Flags);
|
|
||||||
}
|
|
||||||
StringRef Name = Decl->getName().str();
|
StringRef Name = Decl->getName().str();
|
||||||
auto FwdDecl = createTemporaryReplaceableForwardDecl(
|
auto FwdDecl = createTemporaryReplaceableForwardDecl(
|
||||||
EnumTy, Scope, File, Line, SizeInBits, AlignInBits, Flags, MangledName,
|
EnumTy, Scope, File, Line, SizeInBits, AlignInBits, Flags, MangledName,
|
||||||
Name);
|
Name);
|
||||||
// Force the creation of the unsubstituted type, don't create it
|
// Force the creation of the unsubstituted type, don't create it
|
||||||
// directly so it goes through all the caching/verification logic.
|
// directly so it goes through all the caching/verification logic.
|
||||||
auto unsubstitutedDbgTy = getOrCreateType(DbgTy);
|
auto UnsubstitutedDITy = getOrCreateType(UnsubstitutedDbgTy);
|
||||||
auto DIType = createOpaqueStruct(
|
auto DIType = createOpaqueStruct(
|
||||||
Scope, "", File, 0, SizeInBits, AlignInBits, Flags, MangledName,
|
Scope, "", File, 0, SizeInBits, AlignInBits, Flags, MangledName,
|
||||||
collectGenericParams(EnumTy), unsubstitutedDbgTy);
|
collectGenericParams(EnumTy), UnsubstitutedDITy);
|
||||||
DBuilder.replaceTemporary(std::move(FwdDecl), DIType);
|
DBuilder.replaceTemporary(std::move(FwdDecl), DIType);
|
||||||
return DIType;
|
return DIType;
|
||||||
}
|
}
|
||||||
@@ -1235,7 +1250,7 @@ private:
|
|||||||
/// Create a DICompositeType from a specialized struct. A specialized type
|
/// Create a DICompositeType from a specialized struct. A specialized type
|
||||||
/// is a generic type, or a child type whose parent is generic.
|
/// is a generic type, or a child type whose parent is generic.
|
||||||
llvm::DIType *createSpecializedStructOrClassType(
|
llvm::DIType *createSpecializedStructOrClassType(
|
||||||
NominalOrBoundGenericNominalType *Type, NominalTypeDecl *Decl,
|
NominalOrBoundGenericNominalType *Type,
|
||||||
llvm::DIScope *Scope, llvm::DIFile *File, unsigned Line,
|
llvm::DIScope *Scope, llvm::DIFile *File, unsigned Line,
|
||||||
unsigned SizeInBits, unsigned AlignInBits, llvm::DINode::DIFlags Flags,
|
unsigned SizeInBits, unsigned AlignInBits, llvm::DINode::DIFlags Flags,
|
||||||
StringRef MangledName, bool IsClass = false) {
|
StringRef MangledName, bool IsClass = false) {
|
||||||
@@ -1249,28 +1264,26 @@ private:
|
|||||||
// When emitting debug information for a type such as Pair<Int, Double>,
|
// When emitting debug information for a type such as Pair<Int, Double>,
|
||||||
// emit a description of all the fields for Pair<T, U>, and emit the regular
|
// emit a description of all the fields for Pair<T, U>, and emit the regular
|
||||||
// debug information for Pair<Int, Double>.
|
// debug information for Pair<Int, Double>.
|
||||||
|
auto *Decl = Type->getNominalOrBoundGenericNominal();
|
||||||
|
if (!Decl)
|
||||||
|
return nullptr;
|
||||||
StringRef Name = Decl->getName().str();
|
StringRef Name = Decl->getName().str();
|
||||||
auto FwdDecl = createTemporaryReplaceableForwardDecl(
|
auto FwdDecl = createTemporaryReplaceableForwardDecl(
|
||||||
Type, Scope, File, Line, SizeInBits, AlignInBits, Flags, MangledName,
|
Type, Scope, File, Line, SizeInBits, AlignInBits, Flags, MangledName,
|
||||||
Name);
|
Name);
|
||||||
|
|
||||||
// Go from Pair<Int, Double> to Pair<T, U>.
|
auto [IsUnsubstitued, UnsubstitutedType] =
|
||||||
auto UnsubstitutedTy = Decl->getDeclaredInterfaceType();
|
getUnsubstituedType(Type, MangledName);
|
||||||
UnsubstitutedTy = Decl->mapTypeIntoContext(UnsubstitutedTy);
|
auto UnsubstitutedDbgTy = DebugTypeInfo::getFromTypeInfo(
|
||||||
|
UnsubstitutedType, IGM.getTypeInfoForUnlowered(UnsubstitutedType), IGM);
|
||||||
auto DbgTy = DebugTypeInfo::getFromTypeInfo(
|
if (IsUnsubstitued)
|
||||||
UnsubstitutedTy, IGM.getTypeInfoForUnlowered(UnsubstitutedTy), IGM);
|
|
||||||
Mangle::ASTMangler Mangler(IGM.Context);
|
|
||||||
std::string DeclTypeMangledName = Mangler.mangleTypeForDebugger(
|
|
||||||
UnsubstitutedTy->mapTypeOutOfContext(), {});
|
|
||||||
if (DeclTypeMangledName == MangledName) {
|
|
||||||
return createUnsubstitutedGenericStructOrClassType(
|
return createUnsubstitutedGenericStructOrClassType(
|
||||||
DbgTy, Decl, UnsubstitutedTy, Scope, File, Line, Flags, nullptr,
|
UnsubstitutedDbgTy, Decl, UnsubstitutedType, Scope, File, Line, Flags,
|
||||||
llvm::dwarf::DW_LANG_Swift, DeclTypeMangledName);
|
nullptr, llvm::dwarf::DW_LANG_Swift, MangledName);
|
||||||
}
|
|
||||||
// Force the creation of the unsubstituted type, don't create it
|
// Force the creation of the unsubstituted type, don't create it
|
||||||
// directly so it goes through all the caching/verification logic.
|
// directly so it goes through all the caching/verification logic.
|
||||||
auto UnsubstitutedType = getOrCreateType(DbgTy);
|
auto UnsubstitutedDITy = getOrCreateType(UnsubstitutedDbgTy);
|
||||||
|
|
||||||
if (auto *ClassTy = llvm::dyn_cast<BoundGenericClassType>(Type)) {
|
if (auto *ClassTy = llvm::dyn_cast<BoundGenericClassType>(Type)) {
|
||||||
auto SuperClassTy = ClassTy->getSuperclass();
|
auto SuperClassTy = ClassTy->getSuperclass();
|
||||||
@@ -1280,19 +1293,15 @@ private:
|
|||||||
|
|
||||||
llvm::DIType *SuperClassDITy = getOrCreateType(SuperClassDbgTy);
|
llvm::DIType *SuperClassDITy = getOrCreateType(SuperClassDbgTy);
|
||||||
assert(SuperClassDITy && "getOrCreateType should never return null!");
|
assert(SuperClassDITy && "getOrCreateType should never return null!");
|
||||||
DBuilder.createInheritance(UnsubstitutedType, SuperClassDITy, 0, 0,
|
DBuilder.createInheritance(UnsubstitutedDITy, SuperClassDITy, 0, 0,
|
||||||
llvm::DINode::FlagZero);
|
llvm::DINode::FlagZero);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto *OpaqueType = createPointerSizedStruct(
|
|
||||||
Scope, Decl ? Decl->getNameStr() : MangledName, File, 0, Flags,
|
|
||||||
MangledName, UnsubstitutedType);
|
|
||||||
return OpaqueType;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto *OpaqueType = createOpaqueStruct(
|
auto *OpaqueType =
|
||||||
Scope, "", File, Line, SizeInBits, AlignInBits, Flags, MangledName,
|
createOpaqueStruct(Scope, Decl ? Decl->getNameStr() : "", File, Line,
|
||||||
collectGenericParams(Type), UnsubstitutedType);
|
SizeInBits, AlignInBits, Flags, MangledName,
|
||||||
|
collectGenericParams(Type), UnsubstitutedDITy);
|
||||||
DBuilder.replaceTemporary(std::move(FwdDecl), OpaqueType);
|
DBuilder.replaceTemporary(std::move(FwdDecl), OpaqueType);
|
||||||
return OpaqueType;
|
return OpaqueType;
|
||||||
}
|
}
|
||||||
@@ -1865,7 +1874,7 @@ private:
|
|||||||
if (Opts.DebugInfoLevel > IRGenDebugInfoLevel::ASTTypes) {
|
if (Opts.DebugInfoLevel > IRGenDebugInfoLevel::ASTTypes) {
|
||||||
if (StructTy->isSpecialized())
|
if (StructTy->isSpecialized())
|
||||||
return createSpecializedStructOrClassType(
|
return createSpecializedStructOrClassType(
|
||||||
StructTy, Decl, Scope, L.File, L.Line, SizeInBits, AlignInBits,
|
StructTy, Scope, L.File, L.Line, SizeInBits, AlignInBits,
|
||||||
Flags, MangledName);
|
Flags, MangledName);
|
||||||
return createStructType(DbgTy, Decl, StructTy, Scope, L.File, L.Line,
|
return createStructType(DbgTy, Decl, StructTy, Scope, L.File, L.Line,
|
||||||
SizeInBits, AlignInBits, Flags, nullptr,
|
SizeInBits, AlignInBits, Flags, nullptr,
|
||||||
@@ -1898,7 +1907,7 @@ private:
|
|||||||
if (Opts.DebugInfoLevel > IRGenDebugInfoLevel::ASTTypes) {
|
if (Opts.DebugInfoLevel > IRGenDebugInfoLevel::ASTTypes) {
|
||||||
if (ClassTy->isSpecialized())
|
if (ClassTy->isSpecialized())
|
||||||
return createSpecializedStructOrClassType(
|
return createSpecializedStructOrClassType(
|
||||||
ClassTy, Decl, Scope, L.File, L.Line, SizeInBits, AlignInBits,
|
ClassTy, Scope, L.File, L.Line, SizeInBits, AlignInBits,
|
||||||
Flags, MangledName);
|
Flags, MangledName);
|
||||||
|
|
||||||
auto *DIType = createStructType(
|
auto *DIType = createStructType(
|
||||||
@@ -1964,7 +1973,7 @@ private:
|
|||||||
unsigned FwdDeclLine = 0;
|
unsigned FwdDeclLine = 0;
|
||||||
if (Opts.DebugInfoLevel > IRGenDebugInfoLevel::ASTTypes)
|
if (Opts.DebugInfoLevel > IRGenDebugInfoLevel::ASTTypes)
|
||||||
return createSpecializedStructOrClassType(
|
return createSpecializedStructOrClassType(
|
||||||
StructTy, Decl, Scope, L.File, L.Line, SizeInBits, AlignInBits,
|
StructTy, Scope, L.File, L.Line, SizeInBits, AlignInBits,
|
||||||
Flags, MangledName);
|
Flags, MangledName);
|
||||||
|
|
||||||
return createOpaqueStructWithSizedContainer(
|
return createOpaqueStructWithSizedContainer(
|
||||||
@@ -1977,20 +1986,9 @@ private:
|
|||||||
auto *ClassTy = BaseTy->castTo<BoundGenericClassType>();
|
auto *ClassTy = BaseTy->castTo<BoundGenericClassType>();
|
||||||
auto *Decl = ClassTy->getDecl();
|
auto *Decl = ClassTy->getDecl();
|
||||||
auto L = getFileAndLocation(Decl);
|
auto L = getFileAndLocation(Decl);
|
||||||
unsigned FwdDeclLine = 0;
|
return createSpecializedStructOrClassType(ClassTy, Scope, L.File,
|
||||||
|
L.Line, SizeInBits, AlignInBits,
|
||||||
if (Opts.DebugInfoLevel > IRGenDebugInfoLevel::ASTTypes)
|
Flags, MangledName);
|
||||||
return createSpecializedStructOrClassType(
|
|
||||||
ClassTy, Decl, Scope, L.File, L.Line, SizeInBits, AlignInBits,
|
|
||||||
Flags, MangledName);
|
|
||||||
|
|
||||||
// TODO: We may want to peek at Decl->isObjC() and set this
|
|
||||||
// attribute accordingly.
|
|
||||||
assert(SizeInBits ==
|
|
||||||
CI.getTargetInfo().getPointerWidth(clang::LangAS::Default));
|
|
||||||
return createPointerSizedStruct(
|
|
||||||
Scope, Decl ? Decl->getNameStr() : MangledName, L.File, FwdDeclLine,
|
|
||||||
Flags, MangledName, SpecificationOf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case TypeKind::Pack:
|
case TypeKind::Pack:
|
||||||
@@ -2174,8 +2172,14 @@ private:
|
|||||||
AliasedTy, DbgTy.getAlignment(), DbgTy.hasDefaultAlignment(),
|
AliasedTy, DbgTy.getAlignment(), DbgTy.hasDefaultAlignment(),
|
||||||
/* IsMetadataType = */ false, DbgTy.isFixedBuffer(),
|
/* IsMetadataType = */ false, DbgTy.isFixedBuffer(),
|
||||||
DbgTy.getNumExtraInhabitants());
|
DbgTy.getNumExtraInhabitants());
|
||||||
return DBuilder.createTypedef(getOrCreateType(AliasedDbgTy), MangledName,
|
auto *TypeDef = DBuilder.createTypedef(getOrCreateType(AliasedDbgTy),
|
||||||
L.File, 0, Scope);
|
MangledName, L.File, 0, Scope);
|
||||||
|
// Bound generic types don't reference their type parameters in ASTTypes
|
||||||
|
// mode, so we need to artificially keep typealiases alive, since they can
|
||||||
|
// appear in reflection metadata.
|
||||||
|
if (Opts.DebugInfoLevel < IRGenDebugInfoLevel::DwarfTypes)
|
||||||
|
DBuilder.retainType(TypeDef);
|
||||||
|
return TypeDef;
|
||||||
}
|
}
|
||||||
|
|
||||||
case TypeKind::Locatable: {
|
case TypeKind::Locatable: {
|
||||||
@@ -2269,10 +2273,15 @@ private:
|
|||||||
// so skip the sanity check.
|
// so skip the sanity check.
|
||||||
if (CachedType->isTemporary())
|
if (CachedType->isTemporary())
|
||||||
return true;
|
return true;
|
||||||
|
if (!isa<llvm::DICompositeType>(CachedType))
|
||||||
|
return true;
|
||||||
|
bool IsUnsubstituted =
|
||||||
|
getUnsubstituedType(DbgTy.getType(), getMangledName(DbgTy)).first;
|
||||||
std::optional<uint64_t> SizeInBits;
|
std::optional<uint64_t> SizeInBits;
|
||||||
std::optional<CompletedDebugTypeInfo> CompletedDbgTy = completeType(DbgTy);
|
if (!IsUnsubstituted)
|
||||||
if (CompletedDbgTy)
|
if (auto CompletedDbgTy = completeType(DbgTy))
|
||||||
SizeInBits = CompletedDbgTy->getSizeInBits();
|
SizeInBits = CompletedDbgTy->getSizeInBits();
|
||||||
|
|
||||||
unsigned CachedSizeInBits = getSizeInBits(CachedType);
|
unsigned CachedSizeInBits = getSizeInBits(CachedType);
|
||||||
if (SizeInBits && CachedSizeInBits != *SizeInBits) {
|
if (SizeInBits && CachedSizeInBits != *SizeInBits) {
|
||||||
// Note that CachedSizeInBits && !SizeInBits may happen and is benign,
|
// Note that CachedSizeInBits && !SizeInBits may happen and is benign,
|
||||||
@@ -2511,6 +2520,7 @@ private:
|
|||||||
// winning over a full definition.
|
// winning over a full definition.
|
||||||
auto *FwdDecl = DBuilder.createReplaceableCompositeType(
|
auto *FwdDecl = DBuilder.createReplaceableCompositeType(
|
||||||
llvm::dwarf::DW_TAG_structure_type, MangledName, Scope, 0, 0,
|
llvm::dwarf::DW_TAG_structure_type, MangledName, Scope, 0, 0,
|
||||||
|
|
||||||
llvm::dwarf::DW_LANG_Swift);
|
llvm::dwarf::DW_LANG_Swift);
|
||||||
FwdDeclTypes.emplace_back(
|
FwdDeclTypes.emplace_back(
|
||||||
std::piecewise_construct, std::make_tuple(MangledName),
|
std::piecewise_construct, std::make_tuple(MangledName),
|
||||||
|
|||||||
@@ -351,14 +351,14 @@ func testBlocksWithGenerics(hba: HasBlockArray) -> Any {
|
|||||||
|
|
||||||
// CHECK: attributes [[NOUNWIND]] = { nounwind memory(read) }
|
// CHECK: attributes [[NOUNWIND]] = { nounwind memory(read) }
|
||||||
|
|
||||||
// CHECK: ![[SWIFT_NAME_ALIAS_VAR]] = !DILocalVariable(name: "obj", arg: 1, scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[SWIFT_NAME_ALIAS_TYPE:[0-9]+]])
|
// CHECK-DAG: ![[SWIFT_NAME_ALIAS_VAR]] = !DILocalVariable(name: "obj", arg: 1, scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: 328, type: ![[LET_SWIFT_NAME_ALIAS_TYPE:[0-9]+]])
|
||||||
// CHECK: ![[LET_SWIFT_NAME_ALIAS_TYPE:[0-9]+]] = !DIDerivedType(tag: DW_TAG_const_type, baseType: ![[SWIFT_NAME_ALIAS_TYPE:[0-9]+]])
|
// CHECK-DAG: ![[LET_SWIFT_NAME_ALIAS_TYPE]] = !DIDerivedType(tag: DW_TAG_const_type, baseType: ![[SWIFT_NAME_ALIAS_TYPE:[0-9]+]])
|
||||||
// CHECK: ![[SWIFT_NAME_ALIAS_TYPE]] = !DIDerivedType(tag: DW_TAG_typedef, name: "$sSo14SwiftNameAliasaD", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, baseType: !{{[0-9]+}})
|
// CHECK-DAG: ![[SWIFT_NAME_ALIAS_TYPE]] = !DIDerivedType(tag: DW_TAG_typedef, name: "$sSo14SwiftNameAliasaD", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, baseType: !{{[0-9]+}})
|
||||||
|
|
||||||
// CHECK: ![[SWIFT_GENERIC_NAME_ALIAS_VAR]] = !DILocalVariable(name: "generic_obj", arg: 1, scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[LET_SWIFT_GENERIC_NAME_ALIAS_TYPE:[0-9]+]])
|
// CHECK-DAG: ![[SWIFT_GENERIC_NAME_ALIAS_VAR]] = !DILocalVariable(name: "generic_obj", arg: 1, scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[LET_SWIFT_GENERIC_NAME_ALIAS_TYPE:[0-9]+]])
|
||||||
// CHECK: ![[LET_SWIFT_GENERIC_NAME_ALIAS_TYPE:[0-9]+]] = !DIDerivedType(tag: DW_TAG_const_type, baseType: ![[SWIFT_GENERIC_NAME_ALIAS_TYPE:[0-9]+]])
|
// CHECK-DAG: ![[LET_SWIFT_GENERIC_NAME_ALIAS_TYPE]] = !DIDerivedType(tag: DW_TAG_const_type, baseType: ![[SWIFT_GENERIC_NAME_ALIAS_TYPE:[0-9]+]])
|
||||||
// CHECK: ![[SWIFT_GENERIC_NAME_ALIAS_TYPE]] = !DIDerivedType(tag: DW_TAG_typedef, name: "$sSo21SwiftGenericNameAliasaySo8NSNumberCGD", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, baseType: !{{[0-9]+}})
|
// CHECK-DAG: ![[SWIFT_GENERIC_NAME_ALIAS_TYPE]] = !DIDerivedType(tag: DW_TAG_typedef, name: "$sSo21SwiftGenericNameAliasaySo8NSNumberCGD", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, baseType: !{{[0-9]+}})
|
||||||
|
|
||||||
// CHECK: ![[SWIFT_CONSTR_GENERIC_NAME_ALIAS_VAR]] = !DILocalVariable(name: "constr_generic_obj", arg: 1, scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[LET_SWIFT_CONSTR_GENERIC_NAME_ALIAS_TYPE:[0-9]+]])
|
// CHECK-DAG: ![[SWIFT_CONSTR_GENERIC_NAME_ALIAS_VAR]] = !DILocalVariable(name: "constr_generic_obj", arg: 1, scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[LET_SWIFT_CONSTR_GENERIC_NAME_ALIAS_TYPE:[0-9]+]])
|
||||||
// CHECK: ![[LET_SWIFT_CONSTR_GENERIC_NAME_ALIAS_TYPE:[0-9]+]] = !DIDerivedType(tag: DW_TAG_const_type, baseType: ![[SWIFT_CONSTR_GENERIC_NAME_ALIAS_TYPE:[0-9]+]])
|
// CHECK-DAG: ![[LET_SWIFT_CONSTR_GENERIC_NAME_ALIAS_TYPE]] = !DIDerivedType(tag: DW_TAG_const_type, baseType: ![[SWIFT_CONSTR_GENERIC_NAME_ALIAS_TYPE:[0-9]+]])
|
||||||
// CHECK: ![[SWIFT_CONSTR_GENERIC_NAME_ALIAS_TYPE]] = !DIDerivedType(tag: DW_TAG_typedef, name: "$sSo27SwiftConstrGenericNameAliasaySo8NSNumberCGD", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, baseType: !{{[0-9]+}})
|
// CHECK-DAG: ![[SWIFT_CONSTR_GENERIC_NAME_ALIAS_TYPE]] = !DIDerivedType(tag: DW_TAG_typedef, name: "$sSo27SwiftConstrGenericNameAliasaySo8NSNumberCGD", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, baseType: !{{[0-9]+}})
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ public let s = S<Int>(t: 0)
|
|||||||
// CHECK: ![[INTPARAM]] = !DITemplateTypeParameter(type: ![[INT:[0-9]+]])
|
// CHECK: ![[INTPARAM]] = !DITemplateTypeParameter(type: ![[INT:[0-9]+]])
|
||||||
// CHECK: ![[INT]] = !DICompositeType(tag: DW_TAG_structure_type, {{.*}}identifier: "$sSiD"
|
// CHECK: ![[INT]] = !DICompositeType(tag: DW_TAG_structure_type, {{.*}}identifier: "$sSiD"
|
||||||
|
|
||||||
|
|
||||||
// DWARF: !DICompositeType(tag: DW_TAG_structure_type,
|
// DWARF: !DICompositeType(tag: DW_TAG_structure_type,
|
||||||
// DWARF-SAME: templateParams: ![[PARAMS:[0-9]+]]
|
// DWARF-SAME: templateParams: ![[PARAMS:[0-9]+]]
|
||||||
// DWARF-SAME: identifier: "$s18BoundGenericStruct1SVySiGD"
|
// DWARF-SAME: identifier: "$s18BoundGenericStruct1SVySiGD"
|
||||||
@@ -40,10 +39,7 @@ public let inner = S2<Double>.Inner(t:4.2)
|
|||||||
// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "$s18BoundGenericStruct2S2VyxGD",
|
// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "$s18BoundGenericStruct2S2VyxGD",
|
||||||
// CHECK-SAME: flags: DIFlagFwdDecl, runtimeLang: DW_LANG_Swift)
|
// CHECK-SAME: flags: DIFlagFwdDecl, runtimeLang: DW_LANG_Swift)
|
||||||
|
|
||||||
// DWARF: !DICompositeType(tag: DW_TAG_structure_type, scope: ![[SCOPE1:[0-9]+]],
|
// DWARF: !DICompositeType(tag: DW_TAG_structure_type, name: "Inner", scope: ![[SCOPE1:[0-9]+]],{{.*}} size: 64, {{.*}}, templateParams: ![[PARAMS2:[0-9]+]], identifier: "$s18BoundGenericStruct2S2V5InnerVySd_GD",{{.*}} specification: ![[SPECIFICATION:[0-9]+]]
|
||||||
// DWARF-SAME: size: 64, {{.*}}, templateParams: ![[PARAMS2:[0-9]+]], identifier: "$s18BoundGenericStruct2S2V5InnerVySd_GD"
|
|
||||||
// DWARF-SAME: specification: ![[SPECIFICATION:[0-9]+]]
|
|
||||||
|
|
||||||
// DWARF: ![[SCOPE1]] = !DICompositeType(tag: DW_TAG_structure_type, name: "$s18BoundGenericStruct2S2VyxGD",
|
// DWARF: ![[SCOPE1]] = !DICompositeType(tag: DW_TAG_structure_type, name: "$s18BoundGenericStruct2S2VyxGD",
|
||||||
|
|
||||||
// DWARF: ![[PARAMS2]] = !{![[PARAMS3:[0-9]+]]}
|
// DWARF: ![[PARAMS2]] = !{![[PARAMS3:[0-9]+]]}
|
||||||
|
|||||||
8
test/DebugInfo/typealias_indirect.swift
Normal file
8
test/DebugInfo/typealias_indirect.swift
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
// RUN: %target-swift-frontend %s -emit-ir -parse-as-library -module-name a -g -o - | %FileCheck %s
|
||||||
|
// CHECK: !DIDerivedType(tag: DW_TAG_typedef, name: "$s1a10LocalAliasaD", {{.*}}baseType: ![[BASETY:[0-9]+]]
|
||||||
|
// CHECK: ![[BASETY]]{{.*}}$sSbD
|
||||||
|
public class MyClass<A, B> {}
|
||||||
|
public typealias LocalAlias = Bool
|
||||||
|
public typealias ClassAlias = MyClass<LocalAlias, Bool>
|
||||||
|
public func use(cls: ClassAlias?) {}
|
||||||
|
|
||||||
Reference in New Issue
Block a user