mizvekov updated this revision to Diff 360648.
mizvekov added a comment.

.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D105320/new/

https://reviews.llvm.org/D105320

Files:
  clang/lib/CodeGen/CGDebugInfo.cpp
  clang/test/CodeGenCXX/debug-info-codeview-int128.cpp
  llvm/include/llvm/IR/DIBuilder.h
  llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
  llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h
  llvm/lib/DebugInfo/CodeView/CodeViewRecordIO.cpp
  llvm/lib/IR/DIBuilder.cpp

Index: llvm/lib/IR/DIBuilder.cpp
===================================================================
--- llvm/lib/IR/DIBuilder.cpp
+++ llvm/lib/IR/DIBuilder.cpp
@@ -243,7 +243,7 @@
   return MF;
 }
 
-DIEnumerator *DIBuilder::createEnumerator(StringRef Name, int64_t Val,
+DIEnumerator *DIBuilder::createEnumerator(StringRef Name, uint64_t Val,
                                           bool IsUnsigned) {
   assert(!Name.empty() && "Unable to create enumerator without name");
   return DIEnumerator::get(VMContext, APInt(64, Val, !IsUnsigned), IsUnsigned,
Index: llvm/lib/DebugInfo/CodeView/CodeViewRecordIO.cpp
===================================================================
--- llvm/lib/DebugInfo/CodeView/CodeViewRecordIO.cpp
+++ llvm/lib/DebugInfo/CodeView/CodeViewRecordIO.cpp
@@ -188,14 +188,21 @@
 
 Error CodeViewRecordIO::mapEncodedInteger(APSInt &Value, const Twine &Comment) {
   if (isStreaming()) {
+    // FIXME: We also need to handle big values here, but it's
+    //        not clear how we can excercise this code path yet.
     if (Value.isSigned())
       emitEncodedSignedInteger(Value.getSExtValue(), Comment);
     else
       emitEncodedUnsignedInteger(Value.getZExtValue(), Comment);
   } else if (isWriting()) {
-    if (Value.isSigned())
-      return writeEncodedSignedInteger(Value.getSExtValue());
-    return writeEncodedUnsignedInteger(Value.getZExtValue());
+    if (Value.isSigned()) {
+      int64_t Val =
+          Value.getNumWords() <= 1U ? Value.getSExtValue() : INT64_MIN;
+      return writeEncodedSignedInteger(Val);
+    }
+    uint64_t Val =
+        Value.getNumWords() <= 1U ? Value.getZExtValue() : UINT64_MAX;
+    return writeEncodedUnsignedInteger(Val);
   } else
     return consume(*Reader, Value);
   return Error::success();
@@ -273,6 +280,7 @@
 
 void CodeViewRecordIO::emitEncodedSignedInteger(const int64_t &Value,
                                                 const Twine &Comment) {
+  // FIXME: There are no test cases covering this function.
   if (Value >= std::numeric_limits<int8_t>::min()) {
     Streamer->emitIntValue(LF_CHAR, 2);
     emitComment(Comment);
@@ -291,8 +299,8 @@
   } else {
     Streamer->emitIntValue(LF_QUADWORD, 2);
     emitComment(Comment);
-    Streamer->emitIntValue(Value, 4);
-    incrStreamedLen(6);
+    Streamer->emitIntValue(Value, 4); // FIXME: Why not 8 (size of quadword)?
+    incrStreamedLen(6);               // FIXME: Why not 10 (8 + 2)?
   }
 }
 
@@ -313,10 +321,11 @@
     Streamer->emitIntValue(Value, 4);
     incrStreamedLen(6);
   } else {
+    // FIXME: There are no test cases covering this block.
     Streamer->emitIntValue(LF_UQUADWORD, 2);
     emitComment(Comment);
     Streamer->emitIntValue(Value, 8);
-    incrStreamedLen(6);
+    incrStreamedLen(6); // FIXME: Why not 10 (8 + 2)?
   }
 }
 
Index: llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h
===================================================================
--- llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h
+++ llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h
@@ -315,6 +315,8 @@
   void collectDebugInfoForGlobals();
   void emitDebugInfoForGlobals();
   void emitGlobalVariableList(ArrayRef<CVGlobalVariable> Globals);
+  void emitConstantSymbolRecord(const DIType *DTy, APSInt &Value,
+                                const std::string &QualifiedName);
   void emitDebugInfoForGlobal(const CVGlobalVariable &CVGV);
   void emitStaticConstMemberList();
 
Index: llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
===================================================================
--- llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
+++ llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
@@ -3157,6 +3157,28 @@
   }
 }
 
+void CodeViewDebug::emitConstantSymbolRecord(const DIType *DTy, APSInt &Value,
+                                             const std::string &QualifiedName) {
+  MCSymbol *SConstantEnd = beginSymbolRecord(SymbolKind::S_CONSTANT);
+  OS.AddComment("Type");
+  OS.emitInt32(getTypeIndex(DTy).getIndex());
+
+  // TODO: Need to support bigger ints like __int128.
+  OS.AddComment("Value");
+
+  // Encoded integers shouldn't need more than 10 bytes.
+  uint8_t Data[10];
+  BinaryStreamWriter Writer(Data, llvm::support::endianness::little);
+  CodeViewRecordIO IO(Writer);
+  cantFail(IO.mapEncodedInteger(Value));
+  StringRef SRef((char *)Data, Writer.getOffset());
+  OS.emitBinaryData(SRef);
+
+  OS.AddComment("Name");
+  emitNullTerminatedSymbolName(OS, QualifiedName);
+  endSymbolRecord(SConstantEnd);
+}
+
 void CodeViewDebug::emitStaticConstMemberList() {
   for (const DIDerivedType *DTy : StaticConstMembers) {
     const DIScope *Scope = DTy->getScope();
@@ -3172,24 +3194,8 @@
     else
       llvm_unreachable("cannot emit a constant without a value");
 
-    std::string QualifiedName = getFullyQualifiedName(Scope, DTy->getName());
-
-    MCSymbol *SConstantEnd = beginSymbolRecord(SymbolKind::S_CONSTANT);
-    OS.AddComment("Type");
-    OS.emitInt32(getTypeIndex(DTy->getBaseType()).getIndex());
-    OS.AddComment("Value");
-
-    // Encoded integers shouldn't need more than 10 bytes.
-    uint8_t Data[10];
-    BinaryStreamWriter Writer(Data, llvm::support::endianness::little);
-    CodeViewRecordIO IO(Writer);
-    cantFail(IO.mapEncodedInteger(Value));
-    StringRef SRef((char *)Data, Writer.getOffset());
-    OS.emitBinaryData(SRef);
-
-    OS.AddComment("Name");
-    emitNullTerminatedSymbolName(OS, QualifiedName);
-    endSymbolRecord(SConstantEnd);
+    emitConstantSymbolRecord(DTy->getBaseType(), Value,
+                             getFullyQualifiedName(Scope, DTy->getName()));
   }
 }
 
@@ -3253,22 +3259,6 @@
                           ? true
                           : DebugHandlerBase::isUnsignedDIType(DIGV->getType());
     APSInt Value(APInt(/*BitWidth=*/64, DIE->getElement(1)), isUnsigned);
-
-    MCSymbol *SConstantEnd = beginSymbolRecord(SymbolKind::S_CONSTANT);
-    OS.AddComment("Type");
-    OS.emitInt32(getTypeIndex(DIGV->getType()).getIndex());
-    OS.AddComment("Value");
-
-    // Encoded integers shouldn't need more than 10 bytes.
-    uint8_t data[10];
-    BinaryStreamWriter Writer(data, llvm::support::endianness::little);
-    CodeViewRecordIO IO(Writer);
-    cantFail(IO.mapEncodedInteger(Value));
-    StringRef SRef((char *)data, Writer.getOffset());
-    OS.emitBinaryData(SRef);
-
-    OS.AddComment("Name");
-    emitNullTerminatedSymbolName(OS, QualifiedName);
-    endSymbolRecord(SConstantEnd);
+    emitConstantSymbolRecord(DIGV->getType(), Value, QualifiedName);
   }
 }
Index: llvm/include/llvm/IR/DIBuilder.h
===================================================================
--- llvm/include/llvm/IR/DIBuilder.h
+++ llvm/include/llvm/IR/DIBuilder.h
@@ -181,7 +181,8 @@
                                      DIFile *File);
 
     /// Create a single enumerator value.
-    DIEnumerator *createEnumerator(StringRef Name, int64_t Val, bool IsUnsigned = false);
+    DIEnumerator *createEnumerator(StringRef Name, uint64_t Val,
+                                   bool IsUnsigned = false);
 
     /// Create a DWARF unspecified type.
     DIBasicType *createUnspecifiedType(StringRef Name);
Index: clang/test/CodeGenCXX/debug-info-codeview-int128.cpp
===================================================================
--- /dev/null
+++ clang/test/CodeGenCXX/debug-info-codeview-int128.cpp
@@ -0,0 +1,56 @@
+// RUN: %clang_cc1 -triple x86_64-windows-gnu -debug-info-kind=limited -gcodeview -S -emit-llvm %s -o - | FileCheck %s --check-prefix=LL
+// RUN: %clang_cc1 -triple x86_64-windows-gnu -debug-info-kind=limited -gcodeview -S %s -o - | FileCheck %s --check-prefix=ASM
+
+enum class uns : __uint128_t { unsval = __uint128_t(1) << 64 };
+uns t1() { return uns::unsval; }
+
+enum class sig : __int128 { sigval = -(__int128(1) << 64) };
+sig t2() { return sig::sigval; }
+
+struct test {
+  static const __uint128_t u128 = __uint128_t(1) << 64;
+  static const __int128    s128 = -(__int128(1) << 64);
+};
+test t3() { return test(); }
+
+// LL-LABEL: !DICompositeType(tag: DW_TAG_enumeration_type, name: "uns", {{.*}})
+// LL: !DIEnumerator(name: "unsval", value: 18446744073709551615, isUnsigned: true)
+
+// LL-LABEL: !DICompositeType(tag: DW_TAG_enumeration_type, name: "sig", {{.*}})
+// LL: !DIEnumerator(name: "sigval", value: -9223372036854775808)
+
+// LL-LABEL: distinct !DICompositeType(tag: DW_TAG_structure_type, name: "test", {{.*}})
+// LL: !DIDerivedType(tag: DW_TAG_member, name: "u128", {{.*}}, flags: DIFlagStaticMember, extraData: i128 18446744073709551616)
+// LL: !DIDerivedType(tag: DW_TAG_member, name: "s128", {{.*}}, flags: DIFlagStaticMember, extraData: i128 -18446744073709551616)
+
+// ASM-LABEL: .long   241                             # Symbol subsection for globals
+
+// ASM-LABEL: .short	4359                            # Record kind: S_CONSTANT
+// ASM-NEXT:  .long	4110                            # Type
+// ASM-NEXT:  .byte	0x0a, 0x80, 0xff, 0xff          # Value
+// ASM-NEXT:  .byte	0xff, 0xff, 0xff, 0xff
+// ASM-NEXT:  .byte	0xff, 0xff
+// ASM-NEXT:  .asciz	"test::u128"                    # Name
+// ASM-NEXT:  .p2align	2
+
+// ASM-LABEL: .short	4359                            # Record kind: S_CONSTANT
+// ASM-NEXT:  .long	4111                            # Type
+// ASM-NEXT:  .byte	0x09, 0x80, 0x00, 0x00          # Value
+// ASM-NEXT:  .byte	0x00, 0x00, 0x00, 0x00
+// ASM-NEXT:  .byte	0x00, 0x80
+// ASM-NEXT:  .asciz	"test::s128"                    # Name
+// ASM-NEXT:  .p2align	2
+
+// ASM-LABEL: .short	0x1203                          # Record kind: LF_FIELDLIST
+// ASM-NEXT:  .short	0x1502                          # Member kind: Enumerator ( LF_ENUMERATE )
+// ASM-NEXT:  .short	0x3                             # Attrs: Public
+// ASM-NEXT:  .short	0x800a
+// ASM-NEXT:  .quad	0xffffffffffffffff              # EnumValue
+// ASM-NEXT:  .asciz	"unsval"                        # Name
+
+// ASM-LABEL: .short	0x1203                          # Record kind: LF_FIELDLIST
+// ASM-NEXT:  .short	0x1502                          # Member kind: Enumerator ( LF_ENUMERATE )
+// ASM-NEXT:  .short	0x3                             # Attrs: Public
+// ASM-NEXT:  .short	0x800a
+// ASM-NEXT:  .quad	0x8000000000000000              # EnumValue
+// ASM-NEXT:  .asciz	"sigval"                        # Name
Index: clang/lib/CodeGen/CGDebugInfo.cpp
===================================================================
--- clang/lib/CodeGen/CGDebugInfo.cpp
+++ clang/lib/CodeGen/CGDebugInfo.cpp
@@ -3090,7 +3090,11 @@
   bool IsSigned = ED->getIntegerType()->isSignedIntegerType();
   for (const auto *Enum : ED->enumerators()) {
     const auto &InitVal = Enum->getInitVal();
-    auto Value = IsSigned ? InitVal.getSExtValue() : InitVal.getZExtValue();
+    uint64_t Value =
+        IsSigned
+            ? (InitVal.getNumWords() <= 1U ? InitVal.getSExtValue() : INT64_MIN)
+            : (InitVal.getNumWords() <= 1U ? InitVal.getZExtValue()
+                                           : UINT64_MAX);
     Enumerators.push_back(
         DBuilder.createEnumerator(Enum->getName(), Value, !IsSigned));
   }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to