aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/CodeGen/CGDebugInfo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/CodeGen/CGDebugInfo.cpp')
-rw-r--r--clang/lib/CodeGen/CGDebugInfo.cpp123
1 files changed, 93 insertions, 30 deletions
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index 85c70de..12e2813ef 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -647,6 +647,68 @@ StringRef CGDebugInfo::getCurrentDirname() {
return CGM.getCodeGenOpts().DebugCompilationDir;
}
+static llvm::dwarf::SourceLanguage GetSourceLanguage(const CodeGenModule &CGM) {
+ const CodeGenOptions &CGO = CGM.getCodeGenOpts();
+ const LangOptions &LO = CGM.getLangOpts();
+
+ assert(CGO.DwarfVersion <= 5);
+
+ llvm::dwarf::SourceLanguage LangTag;
+ if (LO.CPlusPlus) {
+ if (LO.ObjC)
+ LangTag = llvm::dwarf::DW_LANG_ObjC_plus_plus;
+ else if (CGO.DebugStrictDwarf && CGO.DwarfVersion < 5)
+ LangTag = llvm::dwarf::DW_LANG_C_plus_plus;
+ else if (LO.CPlusPlus14)
+ LangTag = llvm::dwarf::DW_LANG_C_plus_plus_14;
+ else if (LO.CPlusPlus11)
+ LangTag = llvm::dwarf::DW_LANG_C_plus_plus_11;
+ else
+ LangTag = llvm::dwarf::DW_LANG_C_plus_plus;
+ } else if (LO.ObjC) {
+ LangTag = llvm::dwarf::DW_LANG_ObjC;
+ } else if (LO.OpenCL && (!CGO.DebugStrictDwarf || CGO.DwarfVersion >= 5)) {
+ LangTag = llvm::dwarf::DW_LANG_OpenCL;
+ } else if (LO.C11 && !(CGO.DebugStrictDwarf && CGO.DwarfVersion < 5)) {
+ LangTag = llvm::dwarf::DW_LANG_C11;
+ } else if (LO.C99) {
+ LangTag = llvm::dwarf::DW_LANG_C99;
+ } else {
+ LangTag = llvm::dwarf::DW_LANG_C89;
+ }
+
+ return LangTag;
+}
+
+static llvm::DISourceLanguageName
+GetDISourceLanguageName(const CodeGenModule &CGM) {
+ // Emit pre-DWARFv6 language codes.
+ if (CGM.getCodeGenOpts().DwarfVersion < 6)
+ return llvm::DISourceLanguageName(GetSourceLanguage(CGM));
+
+ const LangOptions &LO = CGM.getLangOpts();
+
+ uint32_t LangVersion = 0;
+ llvm::dwarf::SourceLanguageName LangTag;
+ if (LO.CPlusPlus) {
+ if (LO.ObjC) {
+ LangTag = llvm::dwarf::DW_LNAME_ObjC_plus_plus;
+ } else {
+ LangTag = llvm::dwarf::DW_LNAME_C_plus_plus;
+ LangVersion = LO.getCPlusPlusLangStd().value_or(0);
+ }
+ } else if (LO.ObjC) {
+ LangTag = llvm::dwarf::DW_LNAME_ObjC;
+ } else if (LO.OpenCL) {
+ LangTag = llvm::dwarf::DW_LNAME_OpenCL_C;
+ } else {
+ LangTag = llvm::dwarf::DW_LNAME_C;
+ LangVersion = LO.getCLangStd().value_or(0);
+ }
+
+ return llvm::DISourceLanguageName(LangTag, LangVersion);
+}
+
void CGDebugInfo::CreateCompileUnit() {
SmallString<64> Checksum;
std::optional<llvm::DIFile::ChecksumKind> CSKind;
@@ -702,31 +764,6 @@ void CGDebugInfo::CreateCompileUnit() {
}
}
- llvm::dwarf::SourceLanguage LangTag;
- if (LO.CPlusPlus) {
- if (LO.ObjC)
- LangTag = llvm::dwarf::DW_LANG_ObjC_plus_plus;
- else if (CGO.DebugStrictDwarf && CGO.DwarfVersion < 5)
- LangTag = llvm::dwarf::DW_LANG_C_plus_plus;
- else if (LO.CPlusPlus14)
- LangTag = llvm::dwarf::DW_LANG_C_plus_plus_14;
- else if (LO.CPlusPlus11)
- LangTag = llvm::dwarf::DW_LANG_C_plus_plus_11;
- else
- LangTag = llvm::dwarf::DW_LANG_C_plus_plus;
- } else if (LO.ObjC) {
- LangTag = llvm::dwarf::DW_LANG_ObjC;
- } else if (LO.OpenCL && (!CGM.getCodeGenOpts().DebugStrictDwarf ||
- CGM.getCodeGenOpts().DwarfVersion >= 5)) {
- LangTag = llvm::dwarf::DW_LANG_OpenCL;
- } else if (LO.C11 && !(CGO.DebugStrictDwarf && CGO.DwarfVersion < 5)) {
- LangTag = llvm::dwarf::DW_LANG_C11;
- } else if (LO.C99) {
- LangTag = llvm::dwarf::DW_LANG_C99;
- } else {
- LangTag = llvm::dwarf::DW_LANG_C89;
- }
-
std::string Producer = getClangFullVersion();
// Figure out which version of the ObjC runtime we have.
@@ -787,7 +824,7 @@ void CGDebugInfo::CreateCompileUnit() {
// Create new compile unit.
TheCU = DBuilder.createCompileUnit(
- llvm::DISourceLanguageName(LangTag), CUFile,
+ GetDISourceLanguageName(CGM), CUFile,
CGOpts.EmitVersionIdentMetadata ? Producer : "",
CGOpts.OptimizationLevel != 0 || CGOpts.PrepareForLTO ||
CGOpts.PrepareForThinLTO,
@@ -1234,20 +1271,46 @@ llvm::DIType *CGDebugInfo::CreateType(const PointerType *Ty,
Ty->getPointeeType(), Unit);
}
-/// \return whether a C++ mangling exists for the type defined by TD.
-static bool hasCXXMangling(const TagDecl *TD, llvm::DICompileUnit *TheCU) {
- switch (TheCU->getSourceLanguage().getUnversionedName()) {
+static bool hasCXXMangling(llvm::dwarf::SourceLanguage Lang, bool IsTagDecl) {
+ switch (Lang) {
case llvm::dwarf::DW_LANG_C_plus_plus:
case llvm::dwarf::DW_LANG_C_plus_plus_11:
case llvm::dwarf::DW_LANG_C_plus_plus_14:
return true;
case llvm::dwarf::DW_LANG_ObjC_plus_plus:
- return isa<CXXRecordDecl>(TD) || isa<EnumDecl>(TD);
+ return IsTagDecl;
+ default:
+ return false;
+ }
+}
+
+static bool hasCXXMangling(llvm::dwarf::SourceLanguageName Lang,
+ bool IsTagDecl) {
+ switch (Lang) {
+ case llvm::dwarf::DW_LNAME_C_plus_plus:
+ return true;
+ case llvm::dwarf::DW_LNAME_ObjC_plus_plus:
+ return IsTagDecl;
default:
return false;
}
}
+/// \return whether a C++ mangling exists for the type defined by TD.
+static bool hasCXXMangling(const TagDecl *TD, llvm::DICompileUnit *TheCU) {
+ const bool IsTagDecl = isa<CXXRecordDecl>(TD) || isa<EnumDecl>(TD);
+
+ if (llvm::DISourceLanguageName SourceLang = TheCU->getSourceLanguage();
+ SourceLang.hasVersionedName())
+ return hasCXXMangling(
+ static_cast<llvm::dwarf::SourceLanguageName>(SourceLang.getName()),
+ IsTagDecl);
+ else
+ return hasCXXMangling(
+ static_cast<llvm::dwarf::SourceLanguage>(SourceLang.getName()),
+ IsTagDecl);
+}
+
// Determines if the debug info for this tag declaration needs a type
// identifier. The purpose of the unique identifier is to deduplicate type
// information for identical types across TUs. Because of the C++ one definition