@@ -885,74 +885,6 @@ llvm::DIFile *IRGenDebugInfo::getFile(llvm::DIScope *Scope) {
885
885
return cast<llvm::DIFile>(Scope);
886
886
}
887
887
888
- // / Return the storage size of an explosion value.
889
- static uint64_t getSizeFromExplosionValue (const clang::TargetInfo &TI,
890
- llvm::Value *V) {
891
- llvm::Type *Ty = V->getType ();
892
- if (unsigned PrimitiveSize = Ty->getPrimitiveSizeInBits ())
893
- return PrimitiveSize;
894
- else if (Ty->isPointerTy ())
895
- return TI.getPointerWidth (0 );
896
- else
897
- llvm_unreachable (" unhandled type of explosion value" );
898
- }
899
-
900
- // / A generator that recursively returns the size of each element of a
901
- // / composite type.
902
- class ElementSizes {
903
- const TrackingDIRefMap &DIRefMap;
904
- llvm::SmallPtrSetImpl<const llvm::DIType *> &IndirectEnums;
905
- llvm::SmallVector<const llvm::DIType *, 12 > Stack;
906
- public:
907
- ElementSizes (const llvm::DIType *DITy, const TrackingDIRefMap &DIRefMap,
908
- llvm::SmallPtrSetImpl<const llvm::DIType *> &IndirectEnums)
909
- : DIRefMap(DIRefMap), IndirectEnums(IndirectEnums), Stack(1 , DITy) {}
910
-
911
- struct SizeAlign {
912
- uint64_t SizeInBits, AlignInBits;
913
- };
914
-
915
- struct SizeAlign getNext () {
916
- if (Stack.empty ())
917
- return {0 , 0 };
918
-
919
- auto *Cur = Stack.pop_back_val ();
920
- if (isa<llvm::DICompositeType>(Cur) &&
921
- Cur->getTag () != llvm::dwarf::DW_TAG_subroutine_type) {
922
- auto *CTy = cast<llvm::DICompositeType>(Cur);
923
- auto Elts = CTy->getElements ();
924
- unsigned N = Cur->getTag () == llvm::dwarf::DW_TAG_union_type
925
- ? std::min (1U , Elts.size ()) // For unions, pick any one.
926
- : Elts.size ();
927
-
928
- if (N) {
929
- // Push all elements in reverse order.
930
- // FIXME: With a little more state we don't need to actually
931
- // store them on the Stack.
932
- for (unsigned I = N; I > 0 ; --I)
933
- Stack.push_back (cast<llvm::DIType>(Elts[I - 1 ]));
934
- return getNext ();
935
- }
936
- }
937
- switch (Cur->getTag ()) {
938
- case llvm::dwarf::DW_TAG_member:
939
- // FIXME: Correctly handle the explosion value for enum types
940
- // with indirect members.
941
- if (IndirectEnums.count (Cur))
942
- return {0 , 0 };
943
- [[clang::fallthrough]];
944
- case llvm::dwarf::DW_TAG_typedef: {
945
- // Replace top of stack.
946
- auto *DTy = cast<llvm::DIDerivedType>(Cur);
947
- Stack.push_back (DTy->getBaseType ().resolve (DIRefMap));
948
- return getNext ();
949
- }
950
- default :
951
- return {Cur->getSizeInBits (), Cur->getAlignInBits ()};
952
- }
953
- }
954
- };
955
-
956
888
static Size
957
889
getStorageSize (const llvm::DataLayout &DL, ArrayRef<llvm::Value *> Storage) {
958
890
unsigned size = 0 ;
@@ -1012,13 +944,16 @@ void IRGenDebugInfo::emitVariableDeclaration(
1012
944
Optimized, Flags);
1013
945
1014
946
// Insert a debug intrinsic into the current block.
1015
- unsigned OffsetInBits = 0 ;
1016
947
auto *BB = Builder.GetInsertBlock ();
1017
948
bool IsPiece = Storage.size () > 1 ;
1018
949
uint64_t SizeOfByte = CI.getTargetInfo ().getCharWidth ();
1019
950
unsigned VarSizeInBits = getSizeInBits (Var, DIRefMap);
1020
- ElementSizes EltSizes (DITy, DIRefMap, IndirectEnumCases);
1021
- auto Dim = EltSizes.getNext ();
951
+
952
+ // Running variables for the current/previous piece.
953
+ unsigned SizeInBits = 0 ;
954
+ unsigned AlignInBits = SizeOfByte;
955
+ unsigned OffsetInBits = 0 ;
956
+
1022
957
for (llvm::Value *Piece : Storage) {
1023
958
SmallVector<uint64_t , 3 > Operands;
1024
959
if (Indirection)
@@ -1030,35 +965,22 @@ void IRGenDebugInfo::emitVariableDeclaration(
1030
965
Piece = llvm::ConstantInt::get (llvm::Type::getInt64Ty (M.getContext ()), 0 );
1031
966
1032
967
if (IsPiece) {
1033
- // Try to get the size from the type if possible.
1034
- auto StorageSize = getSizeFromExplosionValue (CI.getTargetInfo (), Piece);
1035
- // FIXME: The TypeInfo for bound generic enum types reports a
1036
- // type <{}> (with size 0) but a concrete instance may still
1037
- // have storage allocated for it. rdar://problem/21470869
1038
- if (!Dim.SizeInBits || (StorageSize && Dim.SizeInBits > StorageSize))
1039
- Dim.SizeInBits = StorageSize;
1040
-
1041
- // FIXME: Occasionally we miss out that the Storage is actually a
1042
- // refcount wrapper. Silently skip these for now.
1043
- if (OffsetInBits+Dim.SizeInBits > VarSizeInBits)
1044
- break ;
1045
- if (OffsetInBits == 0 && Dim.SizeInBits == VarSizeInBits)
1046
- break ;
1047
- if (Dim.SizeInBits == 0 )
1048
- break ;
1049
-
1050
- assert (Dim.SizeInBits < VarSizeInBits
1051
- && " piece covers entire var" );
1052
- assert (OffsetInBits+Dim.SizeInBits <= VarSizeInBits && " pars > totum" );
968
+ // Advance the offset and align it for the next piece.
969
+ OffsetInBits += llvm::alignTo (SizeInBits, AlignInBits);
970
+ SizeInBits = IGM.DataLayout .getTypeSizeInBits (Piece->getType ());
971
+ AlignInBits = IGM.DataLayout .getABITypeAlignment (Piece->getType ());
972
+ if (!AlignInBits)
973
+ AlignInBits = SizeOfByte;
974
+
975
+ // Sanity checks.
976
+ assert (SizeInBits && " zero-sized piece" );
977
+ assert (SizeInBits < VarSizeInBits && " piece covers entire var" );
978
+ assert (OffsetInBits+SizeInBits <= VarSizeInBits && " pars > totum" );
979
+
980
+ // Add the piece DWARF expression.
1053
981
Operands.push_back (llvm::dwarf::DW_OP_bit_piece);
1054
982
Operands.push_back (OffsetInBits);
1055
- Operands.push_back (Dim.SizeInBits );
1056
-
1057
- auto Size = Dim.SizeInBits ;
1058
- Dim = EltSizes.getNext ();
1059
- OffsetInBits +=
1060
- llvm::alignTo (Size, Dim.AlignInBits ? Dim.AlignInBits
1061
- : SizeOfByte);
983
+ Operands.push_back (SizeInBits);
1062
984
}
1063
985
emitDbgIntrinsic (BB, Piece, Var, DBuilder.createExpression (Operands), Line,
1064
986
Loc.Column , Scope, DS);
@@ -1343,14 +1265,46 @@ llvm::DIType *IRGenDebugInfo::createPointerSizedStruct(
1343
1265
unsigned PtrAlign = CI.getTargetInfo ().getPointerAlign (0 );
1344
1266
auto PtrTy = DBuilder.createPointerType (PointeeTy, PtrSize, PtrAlign);
1345
1267
llvm::Metadata *Elements[] = {
1346
- DBuilder.createMemberType (Scope, " pointer " , File, 0 ,
1268
+ DBuilder.createMemberType (Scope, " ptr " , File, 0 ,
1347
1269
PtrSize, PtrAlign, 0 , Flags, PtrTy)
1348
1270
};
1349
1271
return DBuilder.createStructType (
1350
1272
Scope, Name, File, Line, PtrSize, PtrAlign, Flags,
1351
- nullptr , // DerivedFrom
1352
- DBuilder.getOrCreateArray (Elements), llvm::dwarf::DW_LANG_Swift,
1353
- nullptr , MangledName);
1273
+ /* DerivedFrom */ nullptr , DBuilder.getOrCreateArray (Elements),
1274
+ llvm::dwarf::DW_LANG_Swift, nullptr , MangledName);
1275
+ }
1276
+
1277
+ // / Create a 2*pointer-sized struct with a mangled name and a single
1278
+ // / member of PointeeTy.
1279
+ llvm::DIType *IRGenDebugInfo::createDoublePointerSizedStruct (
1280
+ llvm::DIScope *Scope, StringRef Name, llvm::DIType *PointeeTy,
1281
+ llvm::DIFile *File, unsigned Line, unsigned Flags, StringRef MangledName) {
1282
+ unsigned PtrSize = CI.getTargetInfo ().getPointerWidth (0 );
1283
+ unsigned PtrAlign = CI.getTargetInfo ().getPointerAlign (0 );
1284
+ llvm::Metadata *Elements[] = {
1285
+ DBuilder.createMemberType (
1286
+ Scope, " ptr" , File, 0 , PtrSize, PtrAlign, 0 , Flags,
1287
+ DBuilder.createPointerType (PointeeTy, PtrSize, PtrAlign)),
1288
+ DBuilder.createMemberType (
1289
+ Scope, " _" , File, 0 , PtrSize, PtrAlign, 0 , Flags,
1290
+ DBuilder.createPointerType (nullptr , PtrSize, PtrAlign))};
1291
+ return DBuilder.createStructType (
1292
+ Scope, Name, File, Line, 2 *PtrSize, PtrAlign, Flags,
1293
+ /* DerivedFrom */ nullptr , DBuilder.getOrCreateArray (Elements),
1294
+ llvm::dwarf::DW_LANG_Swift, nullptr , MangledName);
1295
+ }
1296
+
1297
+ // / Create an opaque struct with a mangled name.
1298
+ llvm::DIType *
1299
+ IRGenDebugInfo::createOpaqueStruct (llvm::DIScope *Scope, StringRef Name,
1300
+ llvm::DIFile *File, unsigned Line,
1301
+ unsigned SizeInBits, unsigned AlignInBits,
1302
+ unsigned Flags, StringRef MangledName) {
1303
+ return DBuilder.createStructType (
1304
+ Scope, Name, File, Line, SizeInBits, AlignInBits, Flags,
1305
+ /* DerivedFrom */ nullptr ,
1306
+ DBuilder.getOrCreateArray (ArrayRef<llvm::Metadata *>()),
1307
+ llvm::dwarf::DW_LANG_Swift, nullptr , MangledName);
1354
1308
}
1355
1309
1356
1310
// / Construct a DIType from a DebugTypeInfo object.
@@ -1506,6 +1460,7 @@ llvm::DIType *IRGenDebugInfo::createType(DebugTypeInfo DbgTy,
1506
1460
}
1507
1461
Scope = getOrCreateModule (ModuleName, TheCU, ModuleName, ModulePath);
1508
1462
}
1463
+ assert (SizeInBits == CI.getTargetInfo ().getPointerWidth (0 ));
1509
1464
return createPointerSizedStruct (Scope, Decl->getNameStr (),
1510
1465
getOrCreateFile (L.Filename ), L.Line , Flags,
1511
1466
MangledName);
@@ -1517,9 +1472,9 @@ llvm::DIType *IRGenDebugInfo::createType(DebugTypeInfo DbgTy,
1517
1472
// FIXME: (LLVM branch) This should probably be a DW_TAG_interface_type.
1518
1473
auto L = getDebugLoc (SM, Decl);
1519
1474
auto File = getOrCreateFile (L.Filename );
1520
- return createPointerSizedStruct (Scope,
1521
- Decl ? Decl-> getNameStr () : MangledName ,
1522
- File, L. Line , Flags, MangledName);
1475
+ return createOpaqueStruct (Scope, Decl ? Decl-> getNameStr () : MangledName ,
1476
+ File, L. Line , SizeInBits, AlignInBits, Flags ,
1477
+ MangledName);
1523
1478
}
1524
1479
1525
1480
case TypeKind::ProtocolComposition: {
@@ -1529,15 +1484,16 @@ llvm::DIType *IRGenDebugInfo::createType(DebugTypeInfo DbgTy,
1529
1484
1530
1485
// FIXME: emit types
1531
1486
// auto ProtocolCompositionTy = BaseTy->castTo<ProtocolCompositionType>();
1532
- return createPointerSizedStruct (Scope,
1533
- Decl ? Decl-> getNameStr () : MangledName ,
1534
- File, L. Line , Flags, MangledName);
1487
+ return createOpaqueStruct (Scope, Decl ? Decl-> getNameStr () : MangledName ,
1488
+ File, L. Line , SizeInBits, AlignInBits, Flags ,
1489
+ MangledName);
1535
1490
}
1536
1491
1537
1492
case TypeKind::UnboundGeneric: {
1538
1493
auto *UnboundTy = BaseTy->castTo <UnboundGenericType>();
1539
1494
auto *Decl = UnboundTy->getDecl ();
1540
1495
auto L = getDebugLoc (SM, Decl);
1496
+ assert (SizeInBits == CI.getTargetInfo ().getPointerWidth (0 ));
1541
1497
return createPointerSizedStruct (Scope,
1542
1498
Decl ? Decl->getNameStr () : MangledName,
1543
1499
File, L.Line , Flags, MangledName);
@@ -1547,9 +1503,9 @@ llvm::DIType *IRGenDebugInfo::createType(DebugTypeInfo DbgTy,
1547
1503
auto *StructTy = BaseTy->castTo <BoundGenericStructType>();
1548
1504
auto *Decl = StructTy->getDecl ();
1549
1505
auto L = getDebugLoc (SM, Decl);
1550
- return createPointerSizedStruct (Scope,
1551
- Decl ? Decl-> getNameStr () : MangledName ,
1552
- File, L. Line , Flags, MangledName);
1506
+ return createOpaqueStruct (Scope, Decl ? Decl-> getNameStr () : MangledName ,
1507
+ File, L. Line , SizeInBits, AlignInBits, Flags ,
1508
+ MangledName);
1553
1509
}
1554
1510
1555
1511
case TypeKind::BoundGenericClass: {
@@ -1558,6 +1514,7 @@ llvm::DIType *IRGenDebugInfo::createType(DebugTypeInfo DbgTy,
1558
1514
auto L = getDebugLoc (SM, Decl);
1559
1515
// TODO: We may want to peek at Decl->isObjC() and set this
1560
1516
// attribute accordingly.
1517
+ assert (SizeInBits == CI.getTargetInfo ().getPointerWidth (0 ));
1561
1518
return createPointerSizedStruct (Scope,
1562
1519
Decl ? Decl->getNameStr () : MangledName,
1563
1520
File, L.Line , Flags, MangledName);
@@ -1649,39 +1606,49 @@ llvm::DIType *IRGenDebugInfo::createType(DebugTypeInfo DbgTy,
1649
1606
case TypeKind::Function:
1650
1607
case TypeKind::PolymorphicFunction:
1651
1608
case TypeKind::GenericFunction: {
1652
- auto FwdDecl = llvm::TempDINode (
1653
- DBuilder.createReplaceableCompositeType (
1609
+ auto FwdDecl = llvm::TempDINode (DBuilder.createReplaceableCompositeType (
1654
1610
llvm::dwarf::DW_TAG_subroutine_type, MangledName, Scope, File, 0 ,
1655
- llvm::dwarf::DW_LANG_Swift, SizeInBits, AlignInBits, Flags,
1656
- MangledName));
1657
-
1611
+ llvm::dwarf::DW_LANG_Swift, SizeInBits, AlignInBits, Flags,
1612
+ MangledName));
1613
+
1658
1614
auto TH = llvm::TrackingMDNodeRef (FwdDecl.get ());
1659
1615
DITypeCache[DbgTy.getType ()] = TH;
1660
1616
1661
- CanSILFunctionType FunctionTy ;
1617
+ CanSILFunctionType FunTy ;
1662
1618
if (auto *SILFnTy = dyn_cast<SILFunctionType>(BaseTy))
1663
- FunctionTy = CanSILFunctionType (SILFnTy);
1619
+ FunTy = CanSILFunctionType (SILFnTy);
1664
1620
// FIXME: Handling of generic parameters in SIL type lowering is in flux.
1665
1621
// DebugInfo doesn't appear to care about the generic context, so just
1666
1622
// throw it away before lowering.
1667
1623
else if (isa<GenericFunctionType>(BaseTy) ||
1668
1624
isa<PolymorphicFunctionType>(BaseTy)) {
1669
1625
auto *fTy = cast<AnyFunctionType>(BaseTy);
1670
1626
auto *nongenericTy = FunctionType::get (fTy ->getInput (), fTy ->getResult (),
1671
- fTy ->getExtInfo ());
1627
+ fTy ->getExtInfo ());
1672
1628
1673
- FunctionTy = IGM.SILMod ->Types .getLoweredType (nongenericTy)
1674
- .castTo <SILFunctionType>();
1629
+ FunTy = IGM.SILMod ->Types .getLoweredType (nongenericTy)
1630
+ .castTo <SILFunctionType>();
1675
1631
} else
1676
- FunctionTy =
1632
+ FunTy =
1677
1633
IGM.SILMod ->Types .getLoweredType (BaseTy).castTo <SILFunctionType>();
1678
- auto Params = createParameterTypes (FunctionTy , DbgTy.getDeclContext ());
1634
+ auto Params = createParameterTypes (FunTy , DbgTy.getDeclContext ());
1679
1635
1680
- // Functions are actually stored as a Pointer or a FunctionPairTy:
1681
- // { i8*, %swift.refcounted* }
1682
1636
auto FnTy = DBuilder.createSubroutineType (Params, Flags);
1683
- auto DITy = createPointerSizedStruct (Scope, MangledName, FnTy,
1684
- MainFile, 0 , Flags, MangledName);
1637
+ llvm::DIType *DITy;
1638
+ if (FunTy->getRepresentation () == SILFunctionType::Representation::Thick) {
1639
+ if (SizeInBits == 2 * CI.getTargetInfo ().getPointerWidth (0 ))
1640
+ // This is a FunctionPairTy: { i8*, %swift.refcounted* }.
1641
+ DITy = createDoublePointerSizedStruct (Scope, MangledName, FnTy,
1642
+ MainFile, 0 , Flags, MangledName);
1643
+ else
1644
+ // This is a generic function as noted above.
1645
+ DITy = createOpaqueStruct (Scope, MangledName, MainFile, 0 , SizeInBits,
1646
+ AlignInBits, Flags, MangledName);
1647
+ } else {
1648
+ assert (SizeInBits == CI.getTargetInfo ().getPointerWidth (0 ));
1649
+ DITy = createPointerSizedStruct (Scope, MangledName, FnTy, MainFile, 0 ,
1650
+ Flags, MangledName);
1651
+ }
1685
1652
DBuilder.replaceTemporary (std::move (FwdDecl), DITy);
1686
1653
return DITy;
1687
1654
}
0 commit comments