mizvekov updated this revision to Diff 360645. mizvekov added a comment. - Really `git add` the test case this time.
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,52 @@ +// 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; } + +// LL-LABEL: !DICompositeType(tag: DW_TAG_enumeration_type, name: "uns", {{.*}}) +// LL: !DIEnumerator(name: "unsval", value: 18446744073709551615, isUnsigned: true) + +// 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 + + +enum class sig : __int128 { sigval = -(__int128(1) << 64) }; +sig t2() { return sig::sigval; } + +// LL-LABEL: !DICompositeType(tag: DW_TAG_enumeration_type, name: "sig", {{.*}}) +// LL: !DIEnumerator(name: "sigval", value: -9223372036854775808) + +// 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 + + +struct test { + static const __uint128_t u128 = __uint128_t(1) << 64; + static const __int128 s128 = -(__int128(1) << 64); +}; +test t3() { return test(); } + +// 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: .short 0x1203 # Record kind: LF_FIELDLIST + +// ASM-LABEL: .short 0x150e # Member kind: StaticDataMember ( LF_STMEMBER ) +// ASM-NEXT: .short 0x3 # Attrs: Public +// ASM-NEXT: .long 0x100e # Type: const <unknown simple type> +// ASM-NEXT: .asciz "u128" # Name + +// ASM-LABEL: .short 0x150e # Member kind: StaticDataMember ( LF_STMEMBER ) +// ASM-NEXT: .short 0x3 # Attrs: Public +// ASM-NEXT: .long 0x100f # Type: const <unknown simple type> +// ASM-NEXT: .asciz "s128" # 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