|
41 | 41 | #include "llvm/ADT/DenseSet.h" |
42 | 42 | #include "llvm/ADT/SmallVector.h" |
43 | 43 | #include "llvm/ADT/StringExtras.h" |
| 44 | +#include "llvm/BinaryFormat/Dwarf.h" |
44 | 45 | #include "llvm/IR/Constants.h" |
45 | 46 | #include "llvm/IR/DataLayout.h" |
| 47 | +#include "llvm/IR/DebugInfoMetadata.h" |
46 | 48 | #include "llvm/IR/DerivedTypes.h" |
47 | 49 | #include "llvm/IR/Instruction.h" |
48 | 50 | #include "llvm/IR/Instructions.h" |
@@ -647,6 +649,97 @@ StringRef CGDebugInfo::getCurrentDirname() { |
647 | 649 | return CGM.getCodeGenOpts().DebugCompilationDir; |
648 | 650 | } |
649 | 651 |
|
| 652 | +static llvm::dwarf::SourceLanguage GetSourceLanguage(const CodeGenModule &CGM) { |
| 653 | + const CodeGenOptions &CGO = CGM.getCodeGenOpts(); |
| 654 | + const LangOptions &LO = CGM.getLangOpts(); |
| 655 | + |
| 656 | + assert(CGO.DwarfVersion <= 5); |
| 657 | + |
| 658 | + llvm::dwarf::SourceLanguage LangTag; |
| 659 | + if (LO.CPlusPlus) { |
| 660 | + if (LO.ObjC) |
| 661 | + LangTag = llvm::dwarf::DW_LANG_ObjC_plus_plus; |
| 662 | + else if (CGO.DebugStrictDwarf && CGO.DwarfVersion < 5) |
| 663 | + LangTag = llvm::dwarf::DW_LANG_C_plus_plus; |
| 664 | + else if (LO.CPlusPlus14) |
| 665 | + LangTag = llvm::dwarf::DW_LANG_C_plus_plus_14; |
| 666 | + else if (LO.CPlusPlus11) |
| 667 | + LangTag = llvm::dwarf::DW_LANG_C_plus_plus_11; |
| 668 | + else |
| 669 | + LangTag = llvm::dwarf::DW_LANG_C_plus_plus; |
| 670 | + } else if (LO.ObjC) { |
| 671 | + LangTag = llvm::dwarf::DW_LANG_ObjC; |
| 672 | + } else if (LO.OpenCL && (!CGO.DebugStrictDwarf || CGO.DwarfVersion >= 5)) { |
| 673 | + LangTag = llvm::dwarf::DW_LANG_OpenCL; |
| 674 | + } else if (LO.C11 && !(CGO.DebugStrictDwarf && CGO.DwarfVersion < 5)) { |
| 675 | + LangTag = llvm::dwarf::DW_LANG_C11; |
| 676 | + } else if (LO.C99) { |
| 677 | + LangTag = llvm::dwarf::DW_LANG_C99; |
| 678 | + } else { |
| 679 | + LangTag = llvm::dwarf::DW_LANG_C89; |
| 680 | + } |
| 681 | + |
| 682 | + return LangTag; |
| 683 | +} |
| 684 | + |
| 685 | +static std::pair<llvm::dwarf::SourceLanguageName, uint32_t> |
| 686 | +GetSourceLanguageName(const CodeGenModule &CGM) { |
| 687 | + const CodeGenOptions &CGO = CGM.getCodeGenOpts(); |
| 688 | + const LangOptions &LO = CGM.getLangOpts(); |
| 689 | + |
| 690 | + assert(CGO.DwarfVersion >= 6); |
| 691 | + |
| 692 | + uint32_t LangVersion = 0; |
| 693 | + llvm::dwarf::SourceLanguageName LangTag; |
| 694 | + if (LO.CPlusPlus) { |
| 695 | + if (LO.ObjC) { |
| 696 | + LangTag = llvm::dwarf::DW_LNAME_ObjC_plus_plus; |
| 697 | + } else { |
| 698 | + LangTag = llvm::dwarf::DW_LNAME_C_plus_plus; |
| 699 | + if (LO.CPlusPlus26) |
| 700 | + LangVersion = 202400; // No official language code yet. |
| 701 | + else if (LO.CPlusPlus23) |
| 702 | + LangVersion = llvm::dwarf::DW_LANG_VERSION_C_plus_plus_23; |
| 703 | + else if (LO.CPlusPlus20) |
| 704 | + LangVersion = llvm::dwarf::DW_LANG_VERSION_C_plus_plus_20; |
| 705 | + else if (LO.CPlusPlus17) |
| 706 | + LangVersion = llvm::dwarf::DW_LANG_VERSION_C_plus_plus_17; |
| 707 | + else if (LO.CPlusPlus14) |
| 708 | + LangVersion = llvm::dwarf::DW_LANG_VERSION_C_plus_plus_14; |
| 709 | + else if (LO.CPlusPlus11) |
| 710 | + LangVersion = llvm::dwarf::DW_LANG_VERSION_C_plus_plus_11; |
| 711 | + } |
| 712 | + } else if (LO.ObjC) { |
| 713 | + LangTag = llvm::dwarf::DW_LNAME_ObjC; |
| 714 | + } else if (LO.OpenCL) { |
| 715 | + LangTag = llvm::dwarf::DW_LNAME_OpenCL_C; |
| 716 | + } else { |
| 717 | + LangTag = llvm::dwarf::DW_LNAME_C; |
| 718 | + if (LO.C2y) |
| 719 | + LangVersion = 202500; // No official language code yet. |
| 720 | + else if (LO.C23) |
| 721 | + LangVersion = llvm::dwarf::DW_LANG_VERSION_C23; |
| 722 | + else if (LO.C17) |
| 723 | + LangVersion = llvm::dwarf::DW_LANG_VERSION_C17; |
| 724 | + else if (LO.C11) |
| 725 | + LangVersion = llvm::dwarf::DW_LANG_VERSION_C11; |
| 726 | + else if (LO.C99) |
| 727 | + LangVersion = llvm::dwarf::DW_LANG_VERSION_C99; |
| 728 | + } |
| 729 | + |
| 730 | + return {LangTag, LangVersion}; |
| 731 | +} |
| 732 | + |
| 733 | +static llvm::DISourceLanguageName |
| 734 | +GetDISourceLanguageName(const CodeGenModule &CGM) { |
| 735 | + // Emit pre-DWARFv6 language codes. |
| 736 | + if (CGM.getCodeGenOpts().DwarfVersion < 6) |
| 737 | + return llvm::DISourceLanguageName(GetSourceLanguage(CGM)); |
| 738 | + |
| 739 | + auto [LName, LVersion] = GetSourceLanguageName(CGM); |
| 740 | + return llvm::DISourceLanguageName(LName, LVersion); |
| 741 | +} |
| 742 | + |
650 | 743 | void CGDebugInfo::CreateCompileUnit() { |
651 | 744 | SmallString<64> Checksum; |
652 | 745 | std::optional<llvm::DIFile::ChecksumKind> CSKind; |
@@ -702,31 +795,6 @@ void CGDebugInfo::CreateCompileUnit() { |
702 | 795 | } |
703 | 796 | } |
704 | 797 |
|
705 | | - llvm::dwarf::SourceLanguage LangTag; |
706 | | - if (LO.CPlusPlus) { |
707 | | - if (LO.ObjC) |
708 | | - LangTag = llvm::dwarf::DW_LANG_ObjC_plus_plus; |
709 | | - else if (CGO.DebugStrictDwarf && CGO.DwarfVersion < 5) |
710 | | - LangTag = llvm::dwarf::DW_LANG_C_plus_plus; |
711 | | - else if (LO.CPlusPlus14) |
712 | | - LangTag = llvm::dwarf::DW_LANG_C_plus_plus_14; |
713 | | - else if (LO.CPlusPlus11) |
714 | | - LangTag = llvm::dwarf::DW_LANG_C_plus_plus_11; |
715 | | - else |
716 | | - LangTag = llvm::dwarf::DW_LANG_C_plus_plus; |
717 | | - } else if (LO.ObjC) { |
718 | | - LangTag = llvm::dwarf::DW_LANG_ObjC; |
719 | | - } else if (LO.OpenCL && (!CGM.getCodeGenOpts().DebugStrictDwarf || |
720 | | - CGM.getCodeGenOpts().DwarfVersion >= 5)) { |
721 | | - LangTag = llvm::dwarf::DW_LANG_OpenCL; |
722 | | - } else if (LO.C11 && !(CGO.DebugStrictDwarf && CGO.DwarfVersion < 5)) { |
723 | | - LangTag = llvm::dwarf::DW_LANG_C11; |
724 | | - } else if (LO.C99) { |
725 | | - LangTag = llvm::dwarf::DW_LANG_C99; |
726 | | - } else { |
727 | | - LangTag = llvm::dwarf::DW_LANG_C89; |
728 | | - } |
729 | | - |
730 | 798 | std::string Producer = getClangFullVersion(); |
731 | 799 |
|
732 | 800 | // Figure out which version of the ObjC runtime we have. |
@@ -787,7 +855,7 @@ void CGDebugInfo::CreateCompileUnit() { |
787 | 855 |
|
788 | 856 | // Create new compile unit. |
789 | 857 | TheCU = DBuilder.createCompileUnit( |
790 | | - llvm::DISourceLanguageName(LangTag), CUFile, |
| 858 | + GetDISourceLanguageName(CGM), CUFile, |
791 | 859 | CGOpts.EmitVersionIdentMetadata ? Producer : "", |
792 | 860 | CGOpts.OptimizationLevel != 0 || CGOpts.PrepareForLTO || |
793 | 861 | CGOpts.PrepareForThinLTO, |
@@ -1234,20 +1302,46 @@ llvm::DIType *CGDebugInfo::CreateType(const PointerType *Ty, |
1234 | 1302 | Ty->getPointeeType(), Unit); |
1235 | 1303 | } |
1236 | 1304 |
|
1237 | | -/// \return whether a C++ mangling exists for the type defined by TD. |
1238 | | -static bool hasCXXMangling(const TagDecl *TD, llvm::DICompileUnit *TheCU) { |
1239 | | - switch (TheCU->getSourceLanguage().getUnversionedName()) { |
| 1305 | +static bool hasCXXMangling(llvm::dwarf::SourceLanguage Lang, bool IsTagDecl) { |
| 1306 | + switch (Lang) { |
1240 | 1307 | case llvm::dwarf::DW_LANG_C_plus_plus: |
1241 | 1308 | case llvm::dwarf::DW_LANG_C_plus_plus_11: |
1242 | 1309 | case llvm::dwarf::DW_LANG_C_plus_plus_14: |
1243 | 1310 | return true; |
1244 | 1311 | case llvm::dwarf::DW_LANG_ObjC_plus_plus: |
1245 | | - return isa<CXXRecordDecl>(TD) || isa<EnumDecl>(TD); |
| 1312 | + return IsTagDecl; |
1246 | 1313 | default: |
1247 | 1314 | return false; |
1248 | 1315 | } |
1249 | 1316 | } |
1250 | 1317 |
|
| 1318 | +static bool hasCXXMangling(llvm::dwarf::SourceLanguageName Lang, |
| 1319 | + bool IsTagDecl) { |
| 1320 | + switch (Lang) { |
| 1321 | + case llvm::dwarf::DW_LNAME_C_plus_plus: |
| 1322 | + return true; |
| 1323 | + case llvm::dwarf::DW_LNAME_ObjC_plus_plus: |
| 1324 | + return IsTagDecl; |
| 1325 | + default: |
| 1326 | + return false; |
| 1327 | + } |
| 1328 | +} |
| 1329 | + |
| 1330 | +/// \return whether a C++ mangling exists for the type defined by TD. |
| 1331 | +static bool hasCXXMangling(const TagDecl *TD, llvm::DICompileUnit *TheCU) { |
| 1332 | + const bool IsTagDecl = isa<CXXRecordDecl>(TD) || isa<EnumDecl>(TD); |
| 1333 | + |
| 1334 | + if (llvm::DISourceLanguageName SourceLang = TheCU->getSourceLanguage(); |
| 1335 | + SourceLang.hasVersionedName()) |
| 1336 | + return hasCXXMangling( |
| 1337 | + static_cast<llvm::dwarf::SourceLanguageName>(SourceLang.getName()), |
| 1338 | + IsTagDecl); |
| 1339 | + else |
| 1340 | + return hasCXXMangling( |
| 1341 | + static_cast<llvm::dwarf::SourceLanguage>(SourceLang.getName()), |
| 1342 | + IsTagDecl); |
| 1343 | +} |
| 1344 | + |
1251 | 1345 | // Determines if the debug info for this tag declaration needs a type |
1252 | 1346 | // identifier. The purpose of the unique identifier is to deduplicate type |
1253 | 1347 | // information for identical types across TUs. Because of the C++ one definition |
|
0 commit comments