@@ -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,32 +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
- assert ((Dim.SizeInBits != 0 || StorageSize != 0 ) &&
1036
- " zero-sized variable with nonzero storage size" );
1037
-
1038
- // FIXME: Occasionally we miss out that the Storage is actually a
1039
- // refcount wrapper. Silently skip these for now.
1040
- if (OffsetInBits+Dim.SizeInBits > VarSizeInBits)
1041
- break ;
1042
- if (OffsetInBits == 0 && Dim.SizeInBits == VarSizeInBits)
1043
- break ;
1044
- if (Dim.SizeInBits == 0 )
1045
- break ;
1046
-
1047
- assert (Dim.SizeInBits < VarSizeInBits
1048
- && " piece covers entire var" );
1049
- 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.
1050
981
Operands.push_back (llvm::dwarf::DW_OP_bit_piece);
1051
982
Operands.push_back (OffsetInBits);
1052
- Operands.push_back (Dim.SizeInBits );
1053
-
1054
- auto Size = Dim.SizeInBits ;
1055
- Dim = EltSizes.getNext ();
1056
- OffsetInBits +=
1057
- llvm::alignTo (Size, Dim.AlignInBits ? Dim.AlignInBits
1058
- : SizeOfByte);
983
+ Operands.push_back (SizeInBits);
1059
984
}
1060
985
emitDbgIntrinsic (BB, Piece, Var, DBuilder.createExpression (Operands), Line,
1061
986
Loc.Column , Scope, DS);
@@ -1334,14 +1259,46 @@ llvm::DIType *IRGenDebugInfo::createPointerSizedStruct(
1334
1259
unsigned PtrAlign = CI.getTargetInfo ().getPointerAlign (0 );
1335
1260
auto PtrTy = DBuilder.createPointerType (PointeeTy, PtrSize, PtrAlign);
1336
1261
llvm::Metadata *Elements[] = {
1337
- DBuilder.createMemberType (Scope, " pointer " , File, 0 ,
1262
+ DBuilder.createMemberType (Scope, " ptr " , File, 0 ,
1338
1263
PtrSize, PtrAlign, 0 , Flags, PtrTy)
1339
1264
};
1340
1265
return DBuilder.createStructType (
1341
1266
Scope, Name, File, Line, PtrSize, PtrAlign, Flags,
1342
- nullptr , // DerivedFrom
1343
- DBuilder.getOrCreateArray (Elements), llvm::dwarf::DW_LANG_Swift,
1344
- nullptr , MangledName);
1267
+ /* DerivedFrom */ nullptr , DBuilder.getOrCreateArray (Elements),
1268
+ llvm::dwarf::DW_LANG_Swift, nullptr , MangledName);
1269
+ }
1270
+
1271
+ // / Create a 2*pointer-sized struct with a mangled name and a single
1272
+ // / member of PointeeTy.
1273
+ llvm::DIType *IRGenDebugInfo::createDoublePointerSizedStruct (
1274
+ llvm::DIScope *Scope, StringRef Name, llvm::DIType *PointeeTy,
1275
+ llvm::DIFile *File, unsigned Line, unsigned Flags, StringRef MangledName) {
1276
+ unsigned PtrSize = CI.getTargetInfo ().getPointerWidth (0 );
1277
+ unsigned PtrAlign = CI.getTargetInfo ().getPointerAlign (0 );
1278
+ llvm::Metadata *Elements[] = {
1279
+ DBuilder.createMemberType (
1280
+ Scope, " ptr" , File, 0 , PtrSize, PtrAlign, 0 , Flags,
1281
+ DBuilder.createPointerType (PointeeTy, PtrSize, PtrAlign)),
1282
+ DBuilder.createMemberType (
1283
+ Scope, " _" , File, 0 , PtrSize, PtrAlign, 0 , Flags,
1284
+ DBuilder.createPointerType (nullptr , PtrSize, PtrAlign))};
1285
+ return DBuilder.createStructType (
1286
+ Scope, Name, File, Line, 2 *PtrSize, PtrAlign, Flags,
1287
+ /* DerivedFrom */ nullptr , DBuilder.getOrCreateArray (Elements),
1288
+ llvm::dwarf::DW_LANG_Swift, nullptr , MangledName);
1289
+ }
1290
+
1291
+ // / Create an opaque struct with a mangled name.
1292
+ llvm::DIType *
1293
+ IRGenDebugInfo::createOpaqueStruct (llvm::DIScope *Scope, StringRef Name,
1294
+ llvm::DIFile *File, unsigned Line,
1295
+ unsigned SizeInBits, unsigned AlignInBits,
1296
+ unsigned Flags, StringRef MangledName) {
1297
+ return DBuilder.createStructType (
1298
+ Scope, Name, File, Line, SizeInBits, AlignInBits, Flags,
1299
+ /* DerivedFrom */ nullptr ,
1300
+ DBuilder.getOrCreateArray (ArrayRef<llvm::Metadata *>()),
1301
+ llvm::dwarf::DW_LANG_Swift, nullptr , MangledName);
1345
1302
}
1346
1303
1347
1304
// / Construct a DIType from a DebugTypeInfo object.
@@ -1497,6 +1454,7 @@ llvm::DIType *IRGenDebugInfo::createType(DebugTypeInfo DbgTy,
1497
1454
}
1498
1455
Scope = getOrCreateModule (ModuleName, TheCU, ModuleName, ModulePath);
1499
1456
}
1457
+ assert (SizeInBits == CI.getTargetInfo ().getPointerWidth (0 ));
1500
1458
return createPointerSizedStruct (Scope, Decl->getNameStr (),
1501
1459
getOrCreateFile (L.Filename ), L.Line , Flags,
1502
1460
MangledName);
@@ -1508,9 +1466,9 @@ llvm::DIType *IRGenDebugInfo::createType(DebugTypeInfo DbgTy,
1508
1466
// FIXME: (LLVM branch) This should probably be a DW_TAG_interface_type.
1509
1467
auto L = getDebugLoc (SM, Decl);
1510
1468
auto File = getOrCreateFile (L.Filename );
1511
- return createPointerSizedStruct (Scope,
1512
- Decl ? Decl-> getNameStr () : MangledName ,
1513
- File, L. Line , Flags, MangledName);
1469
+ return createOpaqueStruct (Scope, Decl ? Decl-> getNameStr () : MangledName ,
1470
+ File, L. Line , SizeInBits, AlignInBits, Flags ,
1471
+ MangledName);
1514
1472
}
1515
1473
1516
1474
case TypeKind::ProtocolComposition: {
@@ -1520,15 +1478,16 @@ llvm::DIType *IRGenDebugInfo::createType(DebugTypeInfo DbgTy,
1520
1478
1521
1479
// FIXME: emit types
1522
1480
// auto ProtocolCompositionTy = BaseTy->castTo<ProtocolCompositionType>();
1523
- return createPointerSizedStruct (Scope,
1524
- Decl ? Decl-> getNameStr () : MangledName ,
1525
- File, L. Line , Flags, MangledName);
1481
+ return createOpaqueStruct (Scope, Decl ? Decl-> getNameStr () : MangledName ,
1482
+ File, L. Line , SizeInBits, AlignInBits, Flags ,
1483
+ MangledName);
1526
1484
}
1527
1485
1528
1486
case TypeKind::UnboundGeneric: {
1529
1487
auto *UnboundTy = BaseTy->castTo <UnboundGenericType>();
1530
1488
auto *Decl = UnboundTy->getDecl ();
1531
1489
auto L = getDebugLoc (SM, Decl);
1490
+ assert (SizeInBits == CI.getTargetInfo ().getPointerWidth (0 ));
1532
1491
return createPointerSizedStruct (Scope,
1533
1492
Decl ? Decl->getNameStr () : MangledName,
1534
1493
File, L.Line , Flags, MangledName);
@@ -1538,9 +1497,9 @@ llvm::DIType *IRGenDebugInfo::createType(DebugTypeInfo DbgTy,
1538
1497
auto *StructTy = BaseTy->castTo <BoundGenericStructType>();
1539
1498
auto *Decl = StructTy->getDecl ();
1540
1499
auto L = getDebugLoc (SM, Decl);
1541
- return createPointerSizedStruct (Scope,
1542
- Decl ? Decl-> getNameStr () : MangledName ,
1543
- File, L. Line , Flags, MangledName);
1500
+ return createOpaqueStruct (Scope, Decl ? Decl-> getNameStr () : MangledName ,
1501
+ File, L. Line , SizeInBits, AlignInBits, Flags ,
1502
+ MangledName);
1544
1503
}
1545
1504
1546
1505
case TypeKind::BoundGenericClass: {
@@ -1549,6 +1508,7 @@ llvm::DIType *IRGenDebugInfo::createType(DebugTypeInfo DbgTy,
1549
1508
auto L = getDebugLoc (SM, Decl);
1550
1509
// TODO: We may want to peek at Decl->isObjC() and set this
1551
1510
// attribute accordingly.
1511
+ assert (SizeInBits == CI.getTargetInfo ().getPointerWidth (0 ));
1552
1512
return createPointerSizedStruct (Scope,
1553
1513
Decl ? Decl->getNameStr () : MangledName,
1554
1514
File, L.Line , Flags, MangledName);
@@ -1640,39 +1600,49 @@ llvm::DIType *IRGenDebugInfo::createType(DebugTypeInfo DbgTy,
1640
1600
case TypeKind::Function:
1641
1601
case TypeKind::PolymorphicFunction:
1642
1602
case TypeKind::GenericFunction: {
1643
- auto FwdDecl = llvm::TempDINode (
1644
- DBuilder.createReplaceableCompositeType (
1603
+ auto FwdDecl = llvm::TempDINode (DBuilder.createReplaceableCompositeType (
1645
1604
llvm::dwarf::DW_TAG_subroutine_type, MangledName, Scope, File, 0 ,
1646
- llvm::dwarf::DW_LANG_Swift, SizeInBits, AlignInBits, Flags,
1647
- MangledName));
1648
-
1605
+ llvm::dwarf::DW_LANG_Swift, SizeInBits, AlignInBits, Flags,
1606
+ MangledName));
1607
+
1649
1608
auto TH = llvm::TrackingMDNodeRef (FwdDecl.get ());
1650
1609
DITypeCache[DbgTy.getType ()] = TH;
1651
1610
1652
- CanSILFunctionType FunctionTy ;
1611
+ CanSILFunctionType FunTy ;
1653
1612
if (auto *SILFnTy = dyn_cast<SILFunctionType>(BaseTy))
1654
- FunctionTy = CanSILFunctionType (SILFnTy);
1613
+ FunTy = CanSILFunctionType (SILFnTy);
1655
1614
// FIXME: Handling of generic parameters in SIL type lowering is in flux.
1656
1615
// DebugInfo doesn't appear to care about the generic context, so just
1657
1616
// throw it away before lowering.
1658
1617
else if (isa<GenericFunctionType>(BaseTy) ||
1659
1618
isa<PolymorphicFunctionType>(BaseTy)) {
1660
1619
auto *fTy = cast<AnyFunctionType>(BaseTy);
1661
1620
auto *nongenericTy = FunctionType::get (fTy ->getInput (), fTy ->getResult (),
1662
- fTy ->getExtInfo ());
1621
+ fTy ->getExtInfo ());
1663
1622
1664
- FunctionTy = IGM.SILMod ->Types .getLoweredType (nongenericTy)
1665
- .castTo <SILFunctionType>();
1623
+ FunTy = IGM.SILMod ->Types .getLoweredType (nongenericTy)
1624
+ .castTo <SILFunctionType>();
1666
1625
} else
1667
- FunctionTy =
1626
+ FunTy =
1668
1627
IGM.SILMod ->Types .getLoweredType (BaseTy).castTo <SILFunctionType>();
1669
- auto Params = createParameterTypes (FunctionTy , DbgTy.getDeclContext ());
1628
+ auto Params = createParameterTypes (FunTy , DbgTy.getDeclContext ());
1670
1629
1671
- // Functions are actually stored as a Pointer or a FunctionPairTy:
1672
- // { i8*, %swift.refcounted* }
1673
1630
auto FnTy = DBuilder.createSubroutineType (Params, Flags);
1674
- auto DITy = createPointerSizedStruct (Scope, MangledName, FnTy,
1675
- MainFile, 0 , Flags, MangledName);
1631
+ llvm::DIType *DITy;
1632
+ if (FunTy->getRepresentation () == SILFunctionType::Representation::Thick) {
1633
+ if (SizeInBits == 2 * CI.getTargetInfo ().getPointerWidth (0 ))
1634
+ // This is a FunctionPairTy: { i8*, %swift.refcounted* }.
1635
+ DITy = createDoublePointerSizedStruct (Scope, MangledName, FnTy,
1636
+ MainFile, 0 , Flags, MangledName);
1637
+ else
1638
+ // This is a generic function as noted above.
1639
+ DITy = createOpaqueStruct (Scope, MangledName, MainFile, 0 , SizeInBits,
1640
+ AlignInBits, Flags, MangledName);
1641
+ } else {
1642
+ assert (SizeInBits == CI.getTargetInfo ().getPointerWidth (0 ));
1643
+ DITy = createPointerSizedStruct (Scope, MangledName, FnTy, MainFile, 0 ,
1644
+ Flags, MangledName);
1645
+ }
1676
1646
DBuilder.replaceTemporary (std::move (FwdDecl), DITy);
1677
1647
return DITy;
1678
1648
}
0 commit comments