|
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,77 @@ 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 | + LangVersion = LO.getCPlusPlusLangStd().value_or(0); |
| 700 | + } |
| 701 | + } else if (LO.ObjC) { |
| 702 | + LangTag = llvm::dwarf::DW_LNAME_ObjC; |
| 703 | + } else if (LO.OpenCL) { |
| 704 | + LangTag = llvm::dwarf::DW_LNAME_OpenCL_C; |
| 705 | + } else { |
| 706 | + LangTag = llvm::dwarf::DW_LNAME_C; |
| 707 | + LangVersion = LO.getCLangStd().value_or(0); |
| 708 | + } |
| 709 | + |
| 710 | + return {LangTag, LangVersion}; |
| 711 | +} |
| 712 | + |
| 713 | +static llvm::DISourceLanguageName |
| 714 | +GetDISourceLanguageName(const CodeGenModule &CGM) { |
| 715 | + // Emit pre-DWARFv6 language codes. |
| 716 | + if (CGM.getCodeGenOpts().DwarfVersion < 6) |
| 717 | + return llvm::DISourceLanguageName(GetSourceLanguage(CGM)); |
| 718 | + |
| 719 | + auto [LName, LVersion] = GetSourceLanguageName(CGM); |
| 720 | + return llvm::DISourceLanguageName(LName, LVersion); |
| 721 | +} |
| 722 | + |
650 | 723 | void CGDebugInfo::CreateCompileUnit() { |
651 | 724 | SmallString<64> Checksum; |
652 | 725 | std::optional<llvm::DIFile::ChecksumKind> CSKind; |
@@ -702,31 +775,6 @@ void CGDebugInfo::CreateCompileUnit() { |
702 | 775 | } |
703 | 776 | } |
704 | 777 |
|
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 | 778 | std::string Producer = getClangFullVersion(); |
731 | 779 |
|
732 | 780 | // Figure out which version of the ObjC runtime we have. |
@@ -787,7 +835,7 @@ void CGDebugInfo::CreateCompileUnit() { |
787 | 835 |
|
788 | 836 | // Create new compile unit. |
789 | 837 | TheCU = DBuilder.createCompileUnit( |
790 | | - llvm::DISourceLanguageName(LangTag), CUFile, |
| 838 | + GetDISourceLanguageName(CGM), CUFile, |
791 | 839 | CGOpts.EmitVersionIdentMetadata ? Producer : "", |
792 | 840 | CGOpts.OptimizationLevel != 0 || CGOpts.PrepareForLTO || |
793 | 841 | CGOpts.PrepareForThinLTO, |
@@ -1234,20 +1282,46 @@ llvm::DIType *CGDebugInfo::CreateType(const PointerType *Ty, |
1234 | 1282 | Ty->getPointeeType(), Unit); |
1235 | 1283 | } |
1236 | 1284 |
|
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()) { |
| 1285 | +static bool hasCXXMangling(llvm::dwarf::SourceLanguage Lang, bool IsTagDecl) { |
| 1286 | + switch (Lang) { |
1240 | 1287 | case llvm::dwarf::DW_LANG_C_plus_plus: |
1241 | 1288 | case llvm::dwarf::DW_LANG_C_plus_plus_11: |
1242 | 1289 | case llvm::dwarf::DW_LANG_C_plus_plus_14: |
1243 | 1290 | return true; |
1244 | 1291 | case llvm::dwarf::DW_LANG_ObjC_plus_plus: |
1245 | | - return isa<CXXRecordDecl>(TD) || isa<EnumDecl>(TD); |
| 1292 | + return IsTagDecl; |
1246 | 1293 | default: |
1247 | 1294 | return false; |
1248 | 1295 | } |
1249 | 1296 | } |
1250 | 1297 |
|
| 1298 | +static bool hasCXXMangling(llvm::dwarf::SourceLanguageName Lang, |
| 1299 | + bool IsTagDecl) { |
| 1300 | + switch (Lang) { |
| 1301 | + case llvm::dwarf::DW_LNAME_C_plus_plus: |
| 1302 | + return true; |
| 1303 | + case llvm::dwarf::DW_LNAME_ObjC_plus_plus: |
| 1304 | + return IsTagDecl; |
| 1305 | + default: |
| 1306 | + return false; |
| 1307 | + } |
| 1308 | +} |
| 1309 | + |
| 1310 | +/// \return whether a C++ mangling exists for the type defined by TD. |
| 1311 | +static bool hasCXXMangling(const TagDecl *TD, llvm::DICompileUnit *TheCU) { |
| 1312 | + const bool IsTagDecl = isa<CXXRecordDecl>(TD) || isa<EnumDecl>(TD); |
| 1313 | + |
| 1314 | + if (llvm::DISourceLanguageName SourceLang = TheCU->getSourceLanguage(); |
| 1315 | + SourceLang.hasVersionedName()) |
| 1316 | + return hasCXXMangling( |
| 1317 | + static_cast<llvm::dwarf::SourceLanguageName>(SourceLang.getName()), |
| 1318 | + IsTagDecl); |
| 1319 | + else |
| 1320 | + return hasCXXMangling( |
| 1321 | + static_cast<llvm::dwarf::SourceLanguage>(SourceLang.getName()), |
| 1322 | + IsTagDecl); |
| 1323 | +} |
| 1324 | + |
1251 | 1325 | // Determines if the debug info for this tag declaration needs a type |
1252 | 1326 | // identifier. The purpose of the unique identifier is to deduplicate type |
1253 | 1327 | // information for identical types across TUs. Because of the C++ one definition |
|
0 commit comments