Skip to content

Commit 7c4cba9

Browse files
committed
[llvm][DebugInfo] Abstract DICompileUnit::SourceLanguage to allow alternate DWARF SourceLanguage encoding
1 parent 550b2ef commit 7c4cba9

26 files changed

+214
-121
lines changed

clang/lib/CodeGen/CGDebugInfo.cpp

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -787,7 +787,8 @@ void CGDebugInfo::CreateCompileUnit() {
787787

788788
// Create new compile unit.
789789
TheCU = DBuilder.createCompileUnit(
790-
LangTag, CUFile, CGOpts.EmitVersionIdentMetadata ? Producer : "",
790+
llvm::DISourceLanguageName(LangTag), CUFile,
791+
CGOpts.EmitVersionIdentMetadata ? Producer : "",
791792
CGOpts.OptimizationLevel != 0 || CGOpts.PrepareForLTO ||
792793
CGOpts.PrepareForThinLTO,
793794
CGOpts.DwarfDebugFlags, RuntimeVers, CGOpts.SplitDwarfFile, EmissionKind,
@@ -1232,7 +1233,11 @@ llvm::DIType *CGDebugInfo::CreateType(const PointerType *Ty,
12321233

12331234
/// \return whether a C++ mangling exists for the type defined by TD.
12341235
static bool hasCXXMangling(const TagDecl *TD, llvm::DICompileUnit *TheCU) {
1235-
switch (TheCU->getSourceLanguage()) {
1236+
auto Lang = TheCU->getSourceLanguage();
1237+
// Versioned names (aka DWARFv6 DW_LNAME_) not yet supported.
1238+
assert(!Lang.hasVersionedName());
1239+
1240+
switch (Lang.getName()) {
12361241
case llvm::dwarf::DW_LANG_C_plus_plus:
12371242
case llvm::dwarf::DW_LANG_C_plus_plus_11:
12381243
case llvm::dwarf::DW_LANG_C_plus_plus_14:
@@ -3211,8 +3216,11 @@ llvm::DIType *CGDebugInfo::CreateType(const ObjCInterfaceType *Ty,
32113216
if (!ID)
32123217
return nullptr;
32133218

3214-
auto RuntimeLang =
3215-
static_cast<llvm::dwarf::SourceLanguage>(TheCU->getSourceLanguage());
3219+
auto Lang = TheCU->getSourceLanguage();
3220+
// Versioned names (aka DWARFv6 DW_LNAME_) not yet supported.
3221+
assert(!Lang.hasVersionedName());
3222+
3223+
auto RuntimeLang = static_cast<llvm::dwarf::SourceLanguage>(Lang.getName());
32163224

32173225
// Return a forward declaration if this type was imported from a clang module,
32183226
// and this is not the compile unit with the implementation of the type (which
@@ -3348,7 +3356,11 @@ llvm::DIType *CGDebugInfo::CreateTypeDefinition(const ObjCInterfaceType *Ty,
33483356
ObjCInterfaceDecl *ID = Ty->getDecl();
33493357
llvm::DIFile *DefUnit = getOrCreateFile(ID->getLocation());
33503358
unsigned Line = getLineNumber(ID->getLocation());
3351-
unsigned RuntimeLang = TheCU->getSourceLanguage();
3359+
3360+
auto Lang = TheCU->getSourceLanguage();
3361+
// Versioned names (aka DWARFv6 DW_LNAME_) not yet supported.
3362+
assert(!Lang.hasVersionedName());
3363+
unsigned RuntimeLang = Lang.getName();
33523364

33533365
// Bit size, align and offset of the type.
33543366
uint64_t Size = CGM.getContext().getTypeSize(Ty);

llvm/include/llvm/IR/DIBuilder.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -146,9 +146,9 @@ namespace llvm {
146146
/// \param SDK The SDK name. On Darwin, this is the last component
147147
/// of the sysroot.
148148
LLVM_ABI DICompileUnit *
149-
createCompileUnit(unsigned Lang, DIFile *File, StringRef Producer,
150-
bool isOptimized, StringRef Flags, unsigned RV,
151-
StringRef SplitName = StringRef(),
149+
createCompileUnit(DISourceLanguageName Lang, DIFile *File,
150+
StringRef Producer, bool isOptimized, StringRef Flags,
151+
unsigned RV, StringRef SplitName = StringRef(),
152152
DICompileUnit::DebugEmissionKind Kind =
153153
DICompileUnit::DebugEmissionKind::FullDebug,
154154
uint64_t DWOId = 0, bool SplitDebugInlining = true,

llvm/include/llvm/IR/DebugInfoMetadata.h

Lines changed: 41 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,33 @@ namespace dwarf {
6666
enum Tag : uint16_t;
6767
}
6868

69+
/// Wrapper structure that holds a language name and its version.
70+
///
71+
/// Some debug-info formats, particularly DWARF, distniguish between
72+
/// language codes that include the version name and codes that don't.
73+
/// DISourceLanguageName may hold either of these.
74+
///
75+
class DISourceLanguageName {
76+
/// Language name.
77+
/// If \ref Version is not std::nullopt, then this name
78+
/// is version independent (i.e., doesn't include the language
79+
/// version in its name).
80+
uint16_t Name;
81+
82+
/// Language version. The version scheme is language
83+
/// dependent.
84+
std::optional<uint32_t> Version;
85+
86+
public:
87+
bool hasVersionedName() const { return Version.has_value(); }
88+
89+
uint16_t getName() const { return Name; }
90+
91+
DISourceLanguageName(uint16_t Lang, uint32_t Version)
92+
: Name(Lang), Version(Version) {};
93+
DISourceLanguageName(uint16_t Lang) : Name(Lang), Version(std::nullopt) {};
94+
};
95+
6996
class DbgVariableRecord;
7097

7198
LLVM_ABI extern cl::opt<bool> EnableFSDiscriminator;
@@ -2003,7 +2030,7 @@ class DICompileUnit : public DIScope {
20032030
LLVM_ABI static const char *nameTableKindString(DebugNameTableKind PK);
20042031

20052032
private:
2006-
unsigned SourceLanguage;
2033+
DISourceLanguageName SourceLanguage;
20072034
unsigned RuntimeVersion;
20082035
uint64_t DWOId;
20092036
unsigned EmissionKind;
@@ -2013,16 +2040,17 @@ class DICompileUnit : public DIScope {
20132040
bool DebugInfoForProfiling;
20142041
bool RangesBaseAddress;
20152042

2016-
DICompileUnit(LLVMContext &C, StorageType Storage, unsigned SourceLanguage,
2017-
bool IsOptimized, unsigned RuntimeVersion,
2018-
unsigned EmissionKind, uint64_t DWOId, bool SplitDebugInlining,
2019-
bool DebugInfoForProfiling, unsigned NameTableKind,
2020-
bool RangesBaseAddress, ArrayRef<Metadata *> Ops);
2043+
DICompileUnit(LLVMContext &C, StorageType Storage,
2044+
DISourceLanguageName SourceLanguage, bool IsOptimized,
2045+
unsigned RuntimeVersion, unsigned EmissionKind, uint64_t DWOId,
2046+
bool SplitDebugInlining, bool DebugInfoForProfiling,
2047+
unsigned NameTableKind, bool RangesBaseAddress,
2048+
ArrayRef<Metadata *> Ops);
20212049
~DICompileUnit() = default;
20222050

20232051
static DICompileUnit *
2024-
getImpl(LLVMContext &Context, unsigned SourceLanguage, DIFile *File,
2025-
StringRef Producer, bool IsOptimized, StringRef Flags,
2052+
getImpl(LLVMContext &Context, DISourceLanguageName SourceLanguage,
2053+
DIFile *File, StringRef Producer, bool IsOptimized, StringRef Flags,
20262054
unsigned RuntimeVersion, StringRef SplitDebugFilename,
20272055
unsigned EmissionKind, DICompositeTypeArray EnumTypes,
20282056
DIScopeArray RetainedTypes,
@@ -2042,8 +2070,8 @@ class DICompileUnit : public DIScope {
20422070
getCanonicalMDString(Context, SDK), Storage, ShouldCreate);
20432071
}
20442072
LLVM_ABI static DICompileUnit *
2045-
getImpl(LLVMContext &Context, unsigned SourceLanguage, Metadata *File,
2046-
MDString *Producer, bool IsOptimized, MDString *Flags,
2073+
getImpl(LLVMContext &Context, DISourceLanguageName SourceLanguage,
2074+
Metadata *File, MDString *Producer, bool IsOptimized, MDString *Flags,
20472075
unsigned RuntimeVersion, MDString *SplitDebugFilename,
20482076
unsigned EmissionKind, Metadata *EnumTypes, Metadata *RetainedTypes,
20492077
Metadata *GlobalVariables, Metadata *ImportedEntities,
@@ -2068,7 +2096,7 @@ class DICompileUnit : public DIScope {
20682096

20692097
DEFINE_MDNODE_GET_DISTINCT_TEMPORARY(
20702098
DICompileUnit,
2071-
(unsigned SourceLanguage, DIFile *File, StringRef Producer,
2099+
(DISourceLanguageName SourceLanguage, DIFile *File, StringRef Producer,
20722100
bool IsOptimized, StringRef Flags, unsigned RuntimeVersion,
20732101
StringRef SplitDebugFilename, DebugEmissionKind EmissionKind,
20742102
DICompositeTypeArray EnumTypes, DIScopeArray RetainedTypes,
@@ -2084,7 +2112,7 @@ class DICompileUnit : public DIScope {
20842112
SysRoot, SDK))
20852113
DEFINE_MDNODE_GET_DISTINCT_TEMPORARY(
20862114
DICompileUnit,
2087-
(unsigned SourceLanguage, Metadata *File, MDString *Producer,
2115+
(DISourceLanguageName SourceLanguage, Metadata *File, MDString *Producer,
20882116
bool IsOptimized, MDString *Flags, unsigned RuntimeVersion,
20892117
MDString *SplitDebugFilename, unsigned EmissionKind, Metadata *EnumTypes,
20902118
Metadata *RetainedTypes, Metadata *GlobalVariables,
@@ -2099,7 +2127,7 @@ class DICompileUnit : public DIScope {
20992127

21002128
TempDICompileUnit clone() const { return cloneImpl(); }
21012129

2102-
unsigned getSourceLanguage() const { return SourceLanguage; }
2130+
DISourceLanguageName getSourceLanguage() const { return SourceLanguage; }
21032131
bool isOptimized() const { return IsOptimized; }
21042132
unsigned getRuntimeVersion() const { return RuntimeVersion; }
21052133
DebugEmissionKind getEmissionKind() const {

llvm/lib/Analysis/ModuleDebugInfoPrinter.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,14 @@ static void printModuleDebugInfo(raw_ostream &O, const Module *M,
4343
// filenames), so just print a few useful things.
4444
for (DICompileUnit *CU : Finder.compile_units()) {
4545
O << "Compile unit: ";
46-
auto Lang = dwarf::LanguageString(CU->getSourceLanguage());
46+
auto LangVerPair = CU->getSourceLanguage();
47+
// Versioned names (aka DWARFv6 DW_LNAME_) not yet supported.
48+
assert(!LangVerPair.hasVersionedName());
49+
auto Lang = dwarf::LanguageString(LangVerPair.getName());
4750
if (!Lang.empty())
4851
O << Lang;
4952
else
50-
O << "unknown-language(" << CU->getSourceLanguage() << ")";
53+
O << "unknown-language(" << LangVerPair.getName() << ")";
5154
printFile(O, CU->getFilename(), CU->getDirectory());
5255
O << '\n';
5356
}

llvm/lib/AsmParser/LLParser.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5861,11 +5861,11 @@ bool LLParser::parseDICompileUnit(MDNode *&Result, bool IsDistinct) {
58615861
#undef VISIT_MD_FIELDS
58625862

58635863
Result = DICompileUnit::getDistinct(
5864-
Context, language.Val, file.Val, producer.Val, isOptimized.Val, flags.Val,
5865-
runtimeVersion.Val, splitDebugFilename.Val, emissionKind.Val, enums.Val,
5866-
retainedTypes.Val, globals.Val, imports.Val, macros.Val, dwoId.Val,
5867-
splitDebugInlining.Val, debugInfoForProfiling.Val, nameTableKind.Val,
5868-
rangesBaseAddress.Val, sysroot.Val, sdk.Val);
5864+
Context, DISourceLanguageName(language.Val), file.Val, producer.Val,
5865+
isOptimized.Val, flags.Val, runtimeVersion.Val, splitDebugFilename.Val,
5866+
emissionKind.Val, enums.Val, retainedTypes.Val, globals.Val, imports.Val,
5867+
macros.Val, dwoId.Val, splitDebugInlining.Val, debugInfoForProfiling.Val,
5868+
nameTableKind.Val, rangesBaseAddress.Val, sysroot.Val, sdk.Val);
58695869
return false;
58705870
}
58715871

llvm/lib/Bitcode/Reader/MetadataLoader.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1866,11 +1866,13 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
18661866
// Ignore Record[0], which indicates whether this compile unit is
18671867
// distinct. It's always distinct.
18681868
IsDistinct = true;
1869+
18691870
auto *CU = DICompileUnit::getDistinct(
1870-
Context, Record[1], getMDOrNull(Record[2]), getMDString(Record[3]),
1871-
Record[4], getMDString(Record[5]), Record[6], getMDString(Record[7]),
1872-
Record[8], getMDOrNull(Record[9]), getMDOrNull(Record[10]),
1873-
getMDOrNull(Record[12]), getMDOrNull(Record[13]),
1871+
Context, DISourceLanguageName(Record[1]), getMDOrNull(Record[2]),
1872+
getMDString(Record[3]), Record[4], getMDString(Record[5]), Record[6],
1873+
getMDString(Record[7]), Record[8], getMDOrNull(Record[9]),
1874+
getMDOrNull(Record[10]), getMDOrNull(Record[12]),
1875+
getMDOrNull(Record[13]),
18741876
Record.size() <= 15 ? nullptr : getMDOrNull(Record[15]),
18751877
Record.size() <= 14 ? 0 : Record[14],
18761878
Record.size() <= 16 ? true : Record[16],

llvm/lib/Bitcode/Writer/BitcodeWriter.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2105,7 +2105,12 @@ void ModuleBitcodeWriter::writeDICompileUnit(const DICompileUnit *N,
21052105
unsigned Abbrev) {
21062106
assert(N->isDistinct() && "Expected distinct compile units");
21072107
Record.push_back(/* IsDistinct */ true);
2108-
Record.push_back(N->getSourceLanguage());
2108+
2109+
auto Lang = N->getSourceLanguage();
2110+
// Versioned names (aka DWARFv6 DW_LNAME_) not yet supported.
2111+
assert(!Lang.hasVersionedName());
2112+
Record.push_back(Lang.getName());
2113+
21092114
Record.push_back(VE.getMetadataOrNullID(N->getFile()));
21102115
Record.push_back(VE.getMetadataOrNullID(N->getRawProducer()));
21112116
Record.push_back(N->isOptimized());

llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -633,8 +633,11 @@ void CodeViewDebug::beginModule(Module *M) {
633633
Node = *CUs->operands().begin();
634634
}
635635
const auto *CU = cast<DICompileUnit>(Node);
636+
auto Lang = CU->getSourceLanguage();
637+
// Versioned names (aka DWARFv6 DW_LNAME_) not yet supported.
638+
assert(!Lang.hasVersionedName());
636639

637-
CurrentSourceLanguage = MapDWLangToCVLang(CU->getSourceLanguage());
640+
CurrentSourceLanguage = MapDWLangToCVLang(Lang.getName());
638641
if (!M->getCodeViewFlag() ||
639642
CU->getEmissionKind() == DICompileUnit::NoDebug) {
640643
Asm = nullptr;

llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1039,8 +1039,13 @@ void DwarfDebug::finishUnitAttributes(const DICompileUnit *DIUnit,
10391039
} else
10401040
NewCU.addString(Die, dwarf::DW_AT_producer, Producer);
10411041

1042+
auto Lang = DIUnit->getSourceLanguage();
1043+
// Versioned names (aka DWARFv6 DW_LNAME_) not yet supported.
1044+
assert(!Lang.hasVersionedName());
1045+
10421046
NewCU.addUInt(Die, dwarf::DW_AT_language, dwarf::DW_FORM_data2,
1043-
DIUnit->getSourceLanguage());
1047+
Lang.getName());
1048+
10441049
NewCU.addString(Die, dwarf::DW_AT_name, FN);
10451050
StringRef SysRoot = DIUnit->getSysRoot();
10461051
if (!SysRoot.empty())
@@ -2930,10 +2935,9 @@ static dwarf::PubIndexEntryDescriptor computeIndexValue(DwarfUnit *CU,
29302935
case dwarf::DW_TAG_union_type:
29312936
case dwarf::DW_TAG_enumeration_type:
29322937
return dwarf::PubIndexEntryDescriptor(
2933-
dwarf::GIEK_TYPE,
2934-
dwarf::isCPlusPlus((dwarf::SourceLanguage)CU->getLanguage())
2935-
? dwarf::GIEL_EXTERNAL
2936-
: dwarf::GIEL_STATIC);
2938+
dwarf::GIEK_TYPE, dwarf::isCPlusPlus(CU->getSourceLanguage())
2939+
? dwarf::GIEL_EXTERNAL
2940+
: dwarf::GIEL_STATIC);
29372941
case dwarf::DW_TAG_typedef:
29382942
case dwarf::DW_TAG_base_type:
29392943
case dwarf::DW_TAG_subrange_type:
@@ -3926,7 +3930,7 @@ void DwarfDebug::addDwarfTypeUnitType(DwarfCompileUnit &CU,
39263930
TypeUnitsUnderConstruction.emplace_back(std::move(OwnedUnit), CTy);
39273931

39283932
NewTU.addUInt(UnitDie, dwarf::DW_AT_language, dwarf::DW_FORM_data2,
3929-
CU.getLanguage());
3933+
CU.getSourceLanguage());
39303934

39313935
uint64_t Signature = makeTypeSignature(Identifier);
39323936
NewTU.setTypeSignature(Signature);

llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ DwarfUnit::~DwarfUnit() {
100100
}
101101

102102
int64_t DwarfUnit::getDefaultLowerBound() const {
103-
switch (getLanguage()) {
103+
switch (getSourceLanguage()) {
104104
default:
105105
break;
106106

@@ -704,12 +704,21 @@ void DwarfUnit::addType(DIE &Entity, const DIType *Ty,
704704
addDIEEntry(Entity, Attribute, DIEEntry(*getOrCreateTypeDIE(Ty)));
705705
}
706706

707+
llvm::dwarf::SourceLanguage DwarfUnit::getSourceLanguage() const {
708+
const auto &Lang = getLanguage();
709+
710+
// Versioned names (aka DWARFv6 DW_LNAME_) not yet supported.
711+
assert(!Lang.hasVersionedName());
712+
713+
return static_cast<llvm::dwarf::SourceLanguage>(Lang.getName());
714+
}
715+
707716
std::string DwarfUnit::getParentContextString(const DIScope *Context) const {
708717
if (!Context)
709718
return "";
710719

711720
// FIXME: Decide whether to implement this for non-C++ languages.
712-
if (!dwarf::isCPlusPlus((dwarf::SourceLanguage)getLanguage()))
721+
if (!dwarf::isCPlusPlus(getSourceLanguage()))
713722
return "";
714723

715724
std::string CS;
@@ -940,7 +949,7 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, const DISubroutineType *CTy) {
940949

941950
// Add prototype flag if we're dealing with a C language and the function has
942951
// been prototyped.
943-
if (isPrototyped && dwarf::isC((dwarf::SourceLanguage)getLanguage()))
952+
if (isPrototyped && dwarf::isC(getSourceLanguage()))
944953
addFlag(Buffer, dwarf::DW_AT_prototyped);
945954

946955
// Add a DW_AT_calling_convention if this has an explicit convention.
@@ -1448,7 +1457,7 @@ void DwarfUnit::applySubprogramAttributes(const DISubprogram *SP, DIE &SPDie,
14481457

14491458
// Add the prototype if we have a prototype and we have a C like
14501459
// language.
1451-
if (SP->isPrototyped() && dwarf::isC((dwarf::SourceLanguage)getLanguage()))
1460+
if (SP->isPrototyped() && dwarf::isC(getSourceLanguage()))
14521461
addFlag(SPDie, dwarf::DW_AT_prototyped);
14531462

14541463
if (SP->isObjCDirect())
@@ -1700,8 +1709,7 @@ DIE *DwarfUnit::getIndexTyDie() {
17001709
addString(*IndexTyDie, dwarf::DW_AT_name, Name);
17011710
addUInt(*IndexTyDie, dwarf::DW_AT_byte_size, std::nullopt, sizeof(int64_t));
17021711
addUInt(*IndexTyDie, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1,
1703-
dwarf::getArrayIndexTypeEncoding(
1704-
(dwarf::SourceLanguage)getLanguage()));
1712+
dwarf::getArrayIndexTypeEncoding(getSourceLanguage()));
17051713
DD->addAccelType(*this, CUNode->getNameTableKind(), Name, *IndexTyDie,
17061714
/*Flags*/ 0);
17071715
return IndexTyDie;

0 commit comments

Comments
 (0)