|
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,45 @@ StringRef CGDebugInfo::getCurrentDirname() { |
647 | 649 | return CGM.getCodeGenOpts().DebugCompilationDir; |
648 | 650 | } |
649 | 651 |
|
| 652 | +static llvm::DISourceLanguageName |
| 653 | +GetDISourceLanguageName(const CodeGenModule &CGM) { |
| 654 | + const CodeGenOptions &CGO = CGM.getCodeGenOpts(); |
| 655 | + const LangOptions &LO = CGM.getLangOpts(); |
| 656 | + |
| 657 | + llvm::dwarf::SourceLanguage LangTag; |
| 658 | + if (LO.CPlusPlus) { |
| 659 | + if (LO.ObjC) |
| 660 | + LangTag = llvm::dwarf::DW_LANG_ObjC_plus_plus; |
| 661 | + else if (CGO.DebugStrictDwarf && CGO.DwarfVersion < 5) |
| 662 | + LangTag = llvm::dwarf::DW_LANG_C_plus_plus; |
| 663 | + else if (LO.CPlusPlus14) |
| 664 | + LangTag = llvm::dwarf::DW_LANG_C_plus_plus_14; |
| 665 | + else if (LO.CPlusPlus11) |
| 666 | + LangTag = llvm::dwarf::DW_LANG_C_plus_plus_11; |
| 667 | + else |
| 668 | + LangTag = llvm::dwarf::DW_LANG_C_plus_plus; |
| 669 | + } else if (LO.ObjC) { |
| 670 | + LangTag = llvm::dwarf::DW_LANG_ObjC; |
| 671 | + } else if (LO.OpenCL && (!CGO.DebugStrictDwarf || CGO.DwarfVersion >= 5)) { |
| 672 | + LangTag = llvm::dwarf::DW_LANG_OpenCL; |
| 673 | + } else if (LO.C11 && !(CGO.DebugStrictDwarf && CGO.DwarfVersion < 5)) { |
| 674 | + LangTag = llvm::dwarf::DW_LANG_C11; |
| 675 | + } else if (LO.C99) { |
| 676 | + LangTag = llvm::dwarf::DW_LANG_C99; |
| 677 | + } else { |
| 678 | + LangTag = llvm::dwarf::DW_LANG_C89; |
| 679 | + } |
| 680 | + |
| 681 | + // FIXME: for some languages that don't have a DW_LNAME_* we would fall back |
| 682 | + // to emitting a DW_LANG_. Which is technically obsolete starting with |
| 683 | + // DWARFv6. |
| 684 | + if (CGO.DwarfVersion >= 6) |
| 685 | + if (auto LName = llvm::dwarf::toDW_LNAME(LangTag)) |
| 686 | + return llvm::DISourceLanguageName(LName->first, LName->second); |
| 687 | + |
| 688 | + return llvm::DISourceLanguageName(LangTag); |
| 689 | +} |
| 690 | + |
650 | 691 | void CGDebugInfo::CreateCompileUnit() { |
651 | 692 | SmallString<64> Checksum; |
652 | 693 | std::optional<llvm::DIFile::ChecksumKind> CSKind; |
@@ -702,31 +743,6 @@ void CGDebugInfo::CreateCompileUnit() { |
702 | 743 | } |
703 | 744 | } |
704 | 745 |
|
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 | 746 | std::string Producer = getClangFullVersion(); |
731 | 747 |
|
732 | 748 | // Figure out which version of the ObjC runtime we have. |
@@ -787,7 +803,7 @@ void CGDebugInfo::CreateCompileUnit() { |
787 | 803 |
|
788 | 804 | // Create new compile unit. |
789 | 805 | TheCU = DBuilder.createCompileUnit( |
790 | | - llvm::DISourceLanguageName(LangTag), CUFile, |
| 806 | + GetDISourceLanguageName(CGM), CUFile, |
791 | 807 | CGOpts.EmitVersionIdentMetadata ? Producer : "", |
792 | 808 | CGOpts.OptimizationLevel != 0 || CGOpts.PrepareForLTO || |
793 | 809 | CGOpts.PrepareForThinLTO, |
@@ -1231,20 +1247,46 @@ llvm::DIType *CGDebugInfo::CreateType(const PointerType *Ty, |
1231 | 1247 | Ty->getPointeeType(), Unit); |
1232 | 1248 | } |
1233 | 1249 |
|
1234 | | -/// \return whether a C++ mangling exists for the type defined by TD. |
1235 | | -static bool hasCXXMangling(const TagDecl *TD, llvm::DICompileUnit *TheCU) { |
1236 | | - switch (TheCU->getSourceLanguage().getUnversionedName()) { |
| 1250 | +static bool hasCXXMangling(llvm::dwarf::SourceLanguage Lang, bool IsTagDecl) { |
| 1251 | + switch (Lang) { |
1237 | 1252 | case llvm::dwarf::DW_LANG_C_plus_plus: |
1238 | 1253 | case llvm::dwarf::DW_LANG_C_plus_plus_11: |
1239 | 1254 | case llvm::dwarf::DW_LANG_C_plus_plus_14: |
1240 | 1255 | return true; |
1241 | 1256 | case llvm::dwarf::DW_LANG_ObjC_plus_plus: |
1242 | | - return isa<CXXRecordDecl>(TD) || isa<EnumDecl>(TD); |
| 1257 | + return IsTagDecl; |
1243 | 1258 | default: |
1244 | 1259 | return false; |
1245 | 1260 | } |
1246 | 1261 | } |
1247 | 1262 |
|
| 1263 | +static bool hasCXXMangling(llvm::dwarf::SourceLanguageName Lang, |
| 1264 | + bool IsTagDecl) { |
| 1265 | + switch (Lang) { |
| 1266 | + case llvm::dwarf::DW_LNAME_C_plus_plus: |
| 1267 | + return true; |
| 1268 | + case llvm::dwarf::DW_LNAME_ObjC_plus_plus: |
| 1269 | + return IsTagDecl; |
| 1270 | + default: |
| 1271 | + return false; |
| 1272 | + } |
| 1273 | +} |
| 1274 | + |
| 1275 | +/// \return whether a C++ mangling exists for the type defined by TD. |
| 1276 | +static bool hasCXXMangling(const TagDecl *TD, llvm::DICompileUnit *TheCU) { |
| 1277 | + const bool IsTagDecl = isa<CXXRecordDecl>(TD) || isa<EnumDecl>(TD); |
| 1278 | + |
| 1279 | + if (llvm::DISourceLanguageName SourceLang = TheCU->getSourceLanguage(); |
| 1280 | + SourceLang.hasVersionedName()) |
| 1281 | + return hasCXXMangling( |
| 1282 | + static_cast<llvm::dwarf::SourceLanguageName>(SourceLang.getName()), |
| 1283 | + IsTagDecl); |
| 1284 | + else |
| 1285 | + return hasCXXMangling( |
| 1286 | + static_cast<llvm::dwarf::SourceLanguage>(SourceLang.getName()), |
| 1287 | + IsTagDecl); |
| 1288 | +} |
| 1289 | + |
1248 | 1290 | // Determines if the debug info for this tag declaration needs a type |
1249 | 1291 | // identifier. The purpose of the unique identifier is to deduplicate type |
1250 | 1292 | // information for identical types across TUs. Because of the C++ one definition |
|
0 commit comments