Skip to content

Use depth and index to lookup type metadata artificial variables #16937

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 13, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/AST/ASTMangler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -889,7 +889,7 @@ void ASTMangler::appendType(Type type) {
case TypeKind::Archetype: {
auto *archetype = cast<ArchetypeType>(tybase);

assert(DWARFMangling && "Cannot mangle free-standing archetypes");
assert(false && DWARFMangling && "Cannot mangle free-standing archetypes");

// Mangle the associated type of a parent archetype.
if (auto parent = archetype->getParent()) {
Expand Down
26 changes: 26 additions & 0 deletions lib/IDE/TypeReconstruction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1005,6 +1005,28 @@ static void VisitNodeDestructor(
}
}

static void VisitNodeDependentMember(ASTContext *ast,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should really add a lldb-moduleimport-test test for this.

Demangle::NodePointer cur_node,
VisitNodeResult &result) {
if (cur_node->getNumChildren() == 2) {
auto dep = cur_node->getChild(0);
auto assoc = cur_node->getChild(1);
VisitNodeResult dependency;
if (dep->getKind() == Demangle::Node::Kind::Type &&
assoc->getKind() == Demangle::Node::Kind::DependentAssociatedTypeRef) {
VisitNode(ast, dep, dependency);
if (dependency._types.size() == 1 && assoc->hasText()) {
Identifier name = ast->getIdentifier(assoc->getText());
result._types.push_back(
DependentMemberType::get(dependency._types[0], name));
return;
}
}
}
result._error = "bad dependent member type";
}


static Demangle::NodePointer DropGenericSignature(
Demangle::NodePointer cur_node) {
if (cur_node->getKind() != Demangle::Node::Kind::DependentGenericType)
Expand Down Expand Up @@ -2285,6 +2307,10 @@ static void VisitNode(
VisitNodeConstructor(ast, node, result);
break;

case Demangle::Node::Kind::DependentMemberType:
VisitNodeDependentMember(ast, node, result);
break;

case Demangle::Node::Kind::Destructor:
VisitNodeDestructor(ast, node, result);
break;
Expand Down
11 changes: 4 additions & 7 deletions lib/IRGen/DebugTypeInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,8 @@ DebugTypeInfo DebugTypeInfo::getLocalVariable(DeclContext *DC,
const TypeInfo &Info,
bool Unwrap) {

auto DeclType = (Decl->hasType()
? Decl->getType()
: Decl->getDeclContext()->mapTypeIntoContext(
Decl->getInterfaceType()));
auto DeclType =
Decl->hasInterfaceType() ? Decl->getInterfaceType() : Decl->getType();
auto RealType = Ty;
if (Unwrap) {
DeclType = DeclType->getInOutObjectType();
Expand Down Expand Up @@ -118,7 +116,7 @@ DebugTypeInfo DebugTypeInfo::getGlobal(SILGlobalVariable *GV,
hasDefaultAlignment(Type));
assert(StorageTy && "StorageType is a nullptr");
assert(!DbgTy.isArchetype() &&
"type of a global var cannot contain an archetype");
"type of global variable cannot be an archetype");
assert(align.getValue() != 0);
return DbgTy;
}
Expand All @@ -129,8 +127,7 @@ DebugTypeInfo DebugTypeInfo::getObjCClass(ClassDecl *theClass,
DebugTypeInfo DbgTy(nullptr, nullptr,
theClass->getInterfaceType().getPointer(), StorageType,
size, align, true);
assert(!DbgTy.isArchetype() &&
"type of an objc class cannot contain an archetype");
assert(!DbgTy.isArchetype() && "type of objc class cannot be an archetype");
return DbgTy;
}

Expand Down
39 changes: 23 additions & 16 deletions lib/IRGen/IRGenDebugInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
bool IsLocalToUnit, bool InFixedBuffer,
Optional<SILLocation> Loc);
void emitTypeMetadata(IRGenFunction &IGF, llvm::Value *Metadata,
StringRef Name);
unsigned Depth, unsigned Index, StringRef AssocType);

/// Return the DIBuilder.
llvm::DIBuilder &getBuilder() { return DBuilder; }
Expand Down Expand Up @@ -616,9 +616,13 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
if (MetadataTypeDecl && DbgTy.getDecl() == MetadataTypeDecl)
return BumpAllocatedString(DbgTy.getDecl()->getName().str());

Type Ty = DbgTy.getType();
if (!Ty->hasTypeParameter())
Ty = Ty->mapTypeOutOfContext();

Mangle::ASTMangler Mangler;
std::string Name = Mangler.mangleTypeForDebugger(
DbgTy.getType(), DbgTy.getDeclContext(), DbgTy.getGenericEnvironment());
Ty, DbgTy.getDeclContext(), DbgTy.getGenericEnvironment());
return BumpAllocatedString(Name);
}

Expand Down Expand Up @@ -1308,15 +1312,13 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
return getOrCreateDesugaredType(CanTy, DbgTy);
}

case TypeKind::DependentMember:
case TypeKind::GenericTypeParam: {
auto *ParamTy = cast<GenericTypeParamType>(BaseTy);
// FIXME: Provide a more meaningful debug type.
return DBuilder.createUnspecifiedType(ParamTy->getName().str());
}
case TypeKind::DependentMember: {
auto *MemberTy = cast<DependentMemberType>(BaseTy);
// FIXME: Provide a more meaningful debug type.
return DBuilder.createUnspecifiedType(MemberTy->getName().str());
return DBuilder.createStructType(
Scope, MangledName, File, 0, SizeInBits, AlignInBits, Flags,
nullptr, nullptr,
llvm::dwarf::DW_LANG_Swift, nullptr, MangledName);
}

// The following types exist primarily for internal use by the type
Expand Down Expand Up @@ -2028,8 +2030,8 @@ void IRGenDebugInfoImpl::emitGlobalVariableDeclaration(
}

void IRGenDebugInfoImpl::emitTypeMetadata(IRGenFunction &IGF,
llvm::Value *Metadata,
StringRef Name) {
llvm::Value *Metadata, unsigned Depth,
unsigned Index, StringRef AssocType) {
if (Opts.DebugInfoKind <= IRGenDebugInfoKind::LineTables)
return;

Expand All @@ -2038,12 +2040,16 @@ void IRGenDebugInfoImpl::emitTypeMetadata(IRGenFunction &IGF,
if (!DS || DS->getInlinedFunction()->isTransparent())
return;

auto TName = BumpAllocatedString(("$swift.type." + Name).str());
llvm::SmallString<8> Buf;
static const char *Tau = u8"\u03C4_";
llvm::raw_svector_ostream OS(Buf);
OS << '$' << Tau << Depth << '_' << Index << AssocType;
auto DbgTy = DebugTypeInfo::getMetadata(
getMetadataType()->getDeclaredInterfaceType().getPointer(),
Metadata->getType(), Size(CI.getTargetInfo().getPointerWidth(0)),
Alignment(CI.getTargetInfo().getPointerAlign(0)));
emitVariableDeclaration(IGF.Builder, Metadata, DbgTy, DS, nullptr, TName, 0,
emitVariableDeclaration(IGF.Builder, Metadata, DbgTy, IGF.getDebugScope(),
nullptr, OS.str().str(), 0,
// swift.type is already a pointer type,
// having a shadow copy doesn't add another
// layer of indirection.
Expand Down Expand Up @@ -2155,9 +2161,10 @@ void IRGenDebugInfo::emitGlobalVariableDeclaration(
}

void IRGenDebugInfo::emitTypeMetadata(IRGenFunction &IGF, llvm::Value *Metadata,
StringRef Name) {
static_cast<IRGenDebugInfoImpl *>(this)->emitTypeMetadata(IGF, Metadata,
Name);
unsigned Depth, unsigned Index,
StringRef AssocType) {
static_cast<IRGenDebugInfoImpl *>(this)->emitTypeMetadata(
IGF, Metadata, Depth, Index, AssocType);
}

llvm::DIBuilder &IRGenDebugInfo::getBuilder() {
Expand Down
2 changes: 1 addition & 1 deletion lib/IRGen/IRGenDebugInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ class IRGenDebugInfo {

/// Emit debug metadata for type metadata (for generic types). So meta.
void emitTypeMetadata(IRGenFunction &IGF, llvm::Value *Metadata,
StringRef Name);
unsigned Depth, unsigned Index, StringRef AssocType);

/// Return the DIBuilder.
llvm::DIBuilder &getBuilder();
Expand Down
13 changes: 12 additions & 1 deletion lib/IRGen/LocalTypeData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,18 @@ static void maybeEmitDebugInfoForLocalTypeData(IRGenFunction &IGF,
return;

// Emit debug info for the metadata.
IGF.IGM.DebugInfo->emitTypeMetadata(IGF, data, name);
llvm::SmallString<8> AssocType;
auto *oocTy = type->mapTypeOutOfContext().getPointer();
{
llvm::raw_svector_ostream OS(AssocType);
while (auto *dependentMemberType = dyn_cast<DependentMemberType>(oocTy)) {
OS << '.' << dependentMemberType->getName();
oocTy = dependentMemberType->getBase().getPointer();
}
}
auto *typeParam = cast<GenericTypeParamType>(oocTy);
IGF.IGM.DebugInfo->emitTypeMetadata(IGF, data, typeParam->getDepth(),
typeParam->getIndex(), AssocType);
}

void
Expand Down
3 changes: 3 additions & 0 deletions test/DebugInfo/DumpTypeFromMangledName.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ extension Collection where Element: Equatable {
var results = [SubSequence]()
return results
}
func foo(_ x: Iterator.Element) {
print(x)
}
}

class Foo<T> {
Expand Down
1 change: 1 addition & 0 deletions test/DebugInfo/Inputs/type-reconstr-names.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ $S4blah4mainyyF8PatatinoL_VMa ---> Can't resolve type of $S4blah4mainyyF8Patatin
$Ss10CollectionP7Element ---> Can't resolve type of $Ss10CollectionP7Element
$Ss15ContiguousArrayV9formIndex5afterySiz_tFSS_Tg5 ---> (inout Int) -> ()
$S12TypeReconstr8PatatinoaySiGD ---> Patatino<Int>
$S7ElementQzD ---> τ_0_0.Element
$S13EyeCandySwift21_previousUniqueNumber33_ADC08935D64EA4F796440E7335798735LLs6UInt64Vvp -> UInt64
2 changes: 1 addition & 1 deletion test/DebugInfo/archetype.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,5 @@ func ExistentialTuple<T: RandomAccessIndex>(_ x: T, y: T) -> T.Distance {
return _overflowChecked((tmp.0, tmp.1))
}
// CHECK: ![[TT]] = !DICompositeType(tag: DW_TAG_structure_type,
// CHECK-SAME: name: "$S9archetype16ExistentialTuple_1y8Distance
// CHECK-SAME: name: "$S8DistanceQz_SbtD"

9 changes: 4 additions & 5 deletions test/DebugInfo/archetypes2.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,15 @@
func markUsed<T>(_ t: T) {}

class C<A> {
// CHECK: ![[A:.*]] = !DICompositeType(tag: DW_TAG_structure_type,{{.*}}identifier: "$SxD"
// CHECK: !DILocalVariable(name: "x", arg: 1,
// CHECK-SAME: line: [[@LINE+9]],
// CHECK-SAME: type: ![[A:[0-9]+]]
// CHECK: ![[A]] = !DICompositeType(tag: DW_TAG_structure_type,
// CHECK-SAME: identifier: "$S11archetypes21CCQq_D"
// CHECK-SAME: line: [[@LINE+7]],
// CHECK-SAME: type: ![[A]]
// CHECK: !DILocalVariable(name: "y", arg: 2,
// CHECK-SAME: line: [[@LINE+4]],
// CHECK-SAME: type: ![[B:[0-9]+]]
// CHECK: ![[B]] = !DICompositeType(tag: DW_TAG_structure_type,
// CHECK-SAME: identifier: "$S11archetypes21CC3foo
// CHECK-SAME: identifier: "$Sqd__D"
func foo<B>(_ x: A, y :B) {
markUsed("hello world")
}
Expand Down
18 changes: 0 additions & 18 deletions test/DebugInfo/atype.swift

This file was deleted.

12 changes: 10 additions & 2 deletions test/DebugInfo/dynamic_layout.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,16 @@ class Class <T> {

init(_x : T) {x = _x}

// Verify that the mangling of the decl context of the type U is correct.
// CHECK: !DICompositeType({{.*}}name: "{{[^"]*}}$S14dynamic_layout5ClassC3fooyx_qd__tqd__lFQq_{{[^"]*}}"
// Verify that the mangling of the type U is correct.
// CHECK: define {{.*}}3foo
// CHECK: %[[U1:.*]] = alloca %swift.type*
// CHECK: call void @llvm.dbg.declare(metadata %swift.type** %[[U1]],
// CHECK-SAME: metadata ![[U:[0-9]+]]
// CHECK: %[[T2:.*]] = alloca %swift.type*
// CHECK: call void @llvm.dbg.declare(metadata %swift.type** %[[T2]],
// CHECK-SAME: metadata ![[T:[0-9]+]]
// CHECK: ![[U]] = !DILocalVariable(name: "$\CF\84_1_0"
// CHECK: ![[T]] = !DILocalVariable(name: "$\CF\84_0_0"
func foo <U> (_ y : U) -> (T,U) {
var tuple = (x,y)
return tuple
Expand Down
10 changes: 5 additions & 5 deletions test/DebugInfo/enum.swift
Original file line number Diff line number Diff line change
Expand Up @@ -64,24 +64,24 @@ public func foo(_ empty : Nothing) { }
// CHECK-SAME: {{.*}}identifier: "$S4enum4RoseOyxG{{z?}}D")
enum Rose<A> {
case MkRose(() -> A, () -> [Rose<A>])
// DWARF: !DICompositeType({{.*}}name: "Rose",{{.*}}identifier: "$S4enum4RoseOyAA3fooyACyxGAElFQq_GD")
// DWARF: !DICompositeType({{.*}}name: "Rose",{{.*}}identifier: "$S4enum4RoseOyxGD")
case IORose(() -> Rose<A>)
}

func foo<T>(_ x : Rose<T>) -> Rose<T> { return x }

// CHECK: !DICompositeType({{.*}}name: "Tuple", {{.*}}elements: ![[ELTS:[0-9]+]], {{.*}}identifier: "$S4enum5TupleOyAA3baryACyxGAElFQq_GD")
// CHECK: !DICompositeType({{.*}}name: "Tuple", {{.*}}elements: ![[ELTS:[0-9]+]], {{.*}}identifier: "$S4enum5TupleOyxGD")
// DWARF: !DICompositeType({{.*}}name: "Tuple", {{.*}}elements: ![[ELTS:[0-9]+]],
// DWARF-SAME: {{.*}}identifier: "$S4enum5TupleOyxG{{z?}}D")
public enum Tuple<P> {
// DWARF: !DICompositeType({{.*}}name: "Tuple",{{.*}}identifier: "$S4enum5TupleOyAA3baryACyxGAElFQq_GD")
// DWARF: !DICompositeType({{.*}}name: "Tuple",{{.*}}identifier: "$S4enum5TupleOyxGD")
case C(P, () -> Tuple)
}

func bar<T>(_ x : Tuple<T>) -> Tuple<T> { return x }

// CHECK: !DILocalVariable(name: "self", arg: 1, {{.*}} line: [[@LINE+5]], type: ![[LIST:.*]], flags: DIFlagArtificial)
// CHECK: ![[LIST]] = !DICompositeType({{.*}}identifier: "$S4enum4ListOyACQq_GD"
// CHECK: ![[LIST:.*]] = !DICompositeType({{.*}}identifier: "$S4enum4ListOyxGD"
// CHECK: !DILocalVariable(name: "self", arg: 1, {{.*}} line: [[@LINE+4]], type: ![[LIST]], flags: DIFlagArtificial)
public enum List<T> {
indirect case Tail(List, T)
case End
Expand Down
4 changes: 2 additions & 2 deletions test/DebugInfo/generic_arg.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ func foo<T>(_ x: T) -> () {
// CHECK-SAME: metadata ![[X1:.*]], metadata !DIExpression())
// CHECK: store %swift.type* %T, %swift.type** %[[T]],
// CHECK: store %swift.opaque* %0, %swift.opaque** %[[X]],
// CHECK: ![[T1]] = !DILocalVariable(name: "$swift.type.T",
// CHECK: ![[T1]] = !DILocalVariable(name: "$\CF\84_0_0",
// CHECK-SAME: flags: DIFlagArtificial)
// CHECK: ![[X1]] = !DILocalVariable(name: "x", arg: 1,
// CHECK-SAME: line: 3, type: ![[TY:.*]])
// CHECK: ![[TY]] = !DICompositeType({{.*}}identifier: "$S11generic_arg3fooyyxlFQq_D")
// CHECK: ![[TY]] = !DICompositeType({{.*}}identifier: "$SxD")
_blackHole(x)
}

Expand Down
4 changes: 2 additions & 2 deletions test/DebugInfo/generic_arg3.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ public func f<Type>(_ value : Type)
// CHECK: call void @llvm.dbg.declare(metadata %swift.opaque** %[[ALLOCA:[^,]+]],
// CHECK-SAME: metadata ![[ARG:.*]], metadata !DIExpression())
// CHECK: store %swift.opaque* %1, %swift.opaque** %[[ALLOCA]], align
// No deref here: The argument is an Archetype and this implicitly indirect.
// CHECK: ![[TY:.*]] = !DICompositeType({{.*}}identifier: "$S12generic_arg31fyyxlFQq_D"
// No deref here.
// CHECK: ![[TY:.*]] = !DICompositeType({{.*}}identifier: "$SxD"
// CHECK: ![[ARG]] = !DILocalVariable(name: "arg", arg: 1,
// CHECK-SAME: line: [[@LINE+1]], type: ![[TY]])
apply(value) { arg in return arg }
Expand Down
6 changes: 3 additions & 3 deletions test/DebugInfo/generic_arg4.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ public struct Q<T> {
// CHECK-SAME: metadata ![[ARG:.*]], metadata !DIExpression())
// CHECK: store %[[TY]]* %0, %[[TY]]** %[[ALLOCA]], align
// No deref here: the array argument is passed by value.
// CHECK: ![[ARG]] = !DILocalVariable(name: "arg", arg: 1,
// CHECK-SAME: line: [[@LINE+2]], type: ![[TY:.*]])
// CHECK: ![[TY]] = !DICompositeType({{.*}}identifier: "$SSay12generic_arg41QVyAA3fooyySayACyxGGlFQq_GGD")
// CHECK: ![[DITY:.*]] = !DICompositeType({{.*}}identifier: "$SSay12generic_arg41QVyxGGD")
public func foo<T>(_ arg: [Q<T>]) {
// CHECK: ![[ARG]] = !DILocalVariable(name: "arg", arg: 1,
// CHECK-SAME: line: [[@LINE-2]], type: ![[DITY:.*]])
}
5 changes: 3 additions & 2 deletions test/DebugInfo/generic_arg5.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@ public func foo<Type>(_ values : [S<Type>])
// CHECK: store %[[TY]]* %1, %[[TY]]** %[[ALLOCA]], align
// The argument is a by-ref struct and thus needs to be dereferenced.
// CHECK: ![[ARG]] = !DILocalVariable(name: "arg", arg: 1,
// CHECK-SAME: line: [[@LINE+3]],
// CHECK-SAME: line: [[@LINE+4]],
// CHECK-SAME: type: ![[TY:.*]])
// CHECK: ![[TY]] = !DICompositeType({{.*}}identifier: "$S12generic_arg51SVyAA3fooyySayACyxGGlFQq_GD")
// CHECK: ![[TY]] = !DICompositeType(
// CHECK-SAME: identifier: "$S12generic_arg51SVyxGD")
let _ = values.flatMap { arg in
return .some(arg)
}
Expand Down
Loading