Adding debug metadata – Advanced IR Generation-2
The file is a module in tinylang, which makes it the compilation unit for LLVM. This carries a lot of information:
bool IsOptimized = false;
llvm::StringRef CUFlags;
unsigned ObjCRunTimeVersion = 0;
llvm::StringRef SplitName;
llvm::DICompileUnit::DebugEmissionKind EmissionKind =
llvm::DICompileUnit::DebugEmissionKind::FullDebug;
llvm::DICompileUnit *DbgCU = DBuilder.createCompileUnit(
llvm::dwarf::DW_LANG_Modula2, DbgFile, „tinylang”,
IsOptimized, CUFlags, ObjCRunTimeVersion, SplitName,
EmissionKind);
Furthermore, the debugger needs to know the source language. The DWARF standard defines an enumeration with all the common values. One disadvantage of this is that you cannot simply add a new source language. To do that, you have to create a request at the DWARF committee. Be aware that the debugger and other debug tools also need support for a new language – just adding a new member to the enumeration is not enough.
In many cases, it is sufficient to choose a language that is close to your source language. In the case of tinylang, this is Modula-2, and we use DW_LANG_Modula2 as the language identifier. A compilation unit resides in a file, which is identified by the DbgFile variable we created previously. Additionally, the debug information can carry information about the producer, which can be the name of the compiler and version information. Here, we just pass the tinylang string. If you do not want to add this information, then you can simply use an empty string as a parameter.
The next set of information includes the IsOptimized flag, which should indicate if the compiler has turned optimization on or not. Usually, this flag is derived from the –O command-line switch. You can pass additional parameter settings to the debugger with the CUFlags parameter. This is not used here, and we pass an empty string. We also do not use Objective-C, so we pass 0 as the Objective-C runtime version.
Normally, debug information is embedded in the object file we are creating. If we want to write the debug information into a separate file, then the SplitName parameter must contain the name of this file. Otherwise, simply passing an empty string is sufficient. Finally, you can define the level of debug information that should be emitted. The default is full debug information, as indicated by the use of the FullDebug enum value, but you can also choose the LineTablesOnly value if you want to emit only line numbers, or the NoDebug value for no debug information at all. For the latter, it is better to not create debug information in the first place.
Our minimalistic source only uses the INTEGER data type, which is a signed 32-bit value. Creating the metadata for this type is straightforward:
llvm::DIBasicType *DbgIntTy =
DBuilder.createBasicType(“INTEGER”, 32,
llvm::dwarf::DW_ATE_signed);