/// @param SplitName The name of the file that we'll split debug info out
/// into.
/// @param Kind The kind of debug information to generate.
+ /// @param DWOId The DWOId if this is a split skeleton compile unit.
/// @param EmitDebugInfo A boolean flag which indicates whether debug
/// information should be written to the final
/// output or not. When this is false, debug
/// source location information in the back end
/// without actually changing the output (e.g.,
/// when using optimization remarks).
- DICompileUnit *createCompileUnit(unsigned Lang, StringRef File,
- StringRef Dir, StringRef Producer,
- bool isOptimized, StringRef Flags,
- unsigned RV, StringRef SplitName = "",
- DebugEmissionKind Kind = FullDebug,
- bool EmitDebugInfo = true);
+ DICompileUnit *
+ createCompileUnit(unsigned Lang, StringRef File, StringRef Dir,
+ StringRef Producer, bool isOptimized, StringRef Flags,
+ unsigned RV, StringRef SplitName = StringRef(),
+ DebugEmissionKind Kind = FullDebug, uint64_t DWOId = 0,
+ bool EmitDebugInfo = true);
/// createFile - Create a file descriptor to hold debugging information
/// for a file.
bool IsOptimized;
unsigned RuntimeVersion;
unsigned EmissionKind;
+ uint64_t DWOId;
DICompileUnit(LLVMContext &C, StorageType Storage, unsigned SourceLanguage,
bool IsOptimized, unsigned RuntimeVersion,
- unsigned EmissionKind, ArrayRef<Metadata *> Ops)
+ unsigned EmissionKind, uint64_t DWOId, ArrayRef<Metadata *> Ops)
: DIScope(C, DICompileUnitKind, Storage, dwarf::DW_TAG_compile_unit, Ops),
SourceLanguage(SourceLanguage), IsOptimized(IsOptimized),
- RuntimeVersion(RuntimeVersion), EmissionKind(EmissionKind) {}
+ RuntimeVersion(RuntimeVersion), EmissionKind(EmissionKind),
+ DWOId(DWOId) {}
~DICompileUnit() = default;
static DICompileUnit *
unsigned EmissionKind, DICompositeTypeArray EnumTypes,
DITypeArray RetainedTypes, DISubprogramArray Subprograms,
DIGlobalVariableArray GlobalVariables,
- DIImportedEntityArray ImportedEntities, StorageType Storage,
- bool ShouldCreate = true) {
- return getImpl(
- Context, SourceLanguage, File, getCanonicalMDString(Context, Producer),
- IsOptimized, getCanonicalMDString(Context, Flags), RuntimeVersion,
- getCanonicalMDString(Context, SplitDebugFilename), EmissionKind,
- EnumTypes.get(), RetainedTypes.get(), Subprograms.get(),
- GlobalVariables.get(), ImportedEntities.get(), Storage, ShouldCreate);
+ DIImportedEntityArray ImportedEntities, uint64_t DWOId,
+ StorageType Storage, bool ShouldCreate = true) {
+ return getImpl(Context, SourceLanguage, File,
+ getCanonicalMDString(Context, Producer), IsOptimized,
+ getCanonicalMDString(Context, Flags), RuntimeVersion,
+ getCanonicalMDString(Context, SplitDebugFilename),
+ EmissionKind, EnumTypes.get(), RetainedTypes.get(),
+ Subprograms.get(), GlobalVariables.get(),
+ ImportedEntities.get(), DWOId, Storage, ShouldCreate);
}
static DICompileUnit *
getImpl(LLVMContext &Context, unsigned SourceLanguage, Metadata *File,
unsigned RuntimeVersion, MDString *SplitDebugFilename,
unsigned EmissionKind, Metadata *EnumTypes, Metadata *RetainedTypes,
Metadata *Subprograms, Metadata *GlobalVariables,
- Metadata *ImportedEntities, StorageType Storage,
+ Metadata *ImportedEntities, uint64_t DWOId, StorageType Storage,
bool ShouldCreate = true);
TempDICompileUnit cloneImpl() const {
getContext(), getSourceLanguage(), getFile(), getProducer(),
isOptimized(), getFlags(), getRuntimeVersion(), getSplitDebugFilename(),
getEmissionKind(), getEnumTypes(), getRetainedTypes(), getSubprograms(),
- getGlobalVariables(), getImportedEntities());
+ getGlobalVariables(), getImportedEntities(), DWOId);
}
public:
DICompositeTypeArray EnumTypes, DITypeArray RetainedTypes,
DISubprogramArray Subprograms,
DIGlobalVariableArray GlobalVariables,
- DIImportedEntityArray ImportedEntities),
- (SourceLanguage, File, Producer, IsOptimized, Flags,
- RuntimeVersion, SplitDebugFilename, EmissionKind,
- EnumTypes, RetainedTypes, Subprograms, GlobalVariables,
- ImportedEntities))
- DEFINE_MDNODE_GET(DICompileUnit,
- (unsigned SourceLanguage, Metadata *File,
- MDString *Producer, bool IsOptimized, MDString *Flags,
- unsigned RuntimeVersion, MDString *SplitDebugFilename,
- unsigned EmissionKind, Metadata *EnumTypes,
- Metadata *RetainedTypes, Metadata *Subprograms,
- Metadata *GlobalVariables, Metadata *ImportedEntities),
+ DIImportedEntityArray ImportedEntities, uint64_t DWOId),
(SourceLanguage, File, Producer, IsOptimized, Flags,
RuntimeVersion, SplitDebugFilename, EmissionKind,
EnumTypes, RetainedTypes, Subprograms, GlobalVariables,
- ImportedEntities))
+ ImportedEntities, DWOId))
+ DEFINE_MDNODE_GET(
+ DICompileUnit,
+ (unsigned SourceLanguage, Metadata *File, MDString *Producer,
+ bool IsOptimized, MDString *Flags, unsigned RuntimeVersion,
+ MDString *SplitDebugFilename, unsigned EmissionKind, Metadata *EnumTypes,
+ Metadata *RetainedTypes, Metadata *Subprograms,
+ Metadata *GlobalVariables, Metadata *ImportedEntities, uint64_t DWOId),
+ (SourceLanguage, File, Producer, IsOptimized, Flags, RuntimeVersion,
+ SplitDebugFilename, EmissionKind, EnumTypes, RetainedTypes, Subprograms,
+ GlobalVariables, ImportedEntities, DWOId))
TempDICompileUnit clone() const { return cloneImpl(); }
DIImportedEntityArray getImportedEntities() const {
return cast_or_null<MDTuple>(getRawImportedEntities());
}
+ unsigned getDWOId() const { return DWOId; }
MDString *getRawProducer() const { return getOperandAs<MDString>(1); }
MDString *getRawFlags() const { return getOperandAs<MDString>(2); }
/// isOptimized: true, flags: "-O2", runtimeVersion: 1,
/// splitDebugFilename: "abc.debug", emissionKind: 1,
/// enums: !1, retainedTypes: !2, subprograms: !3,
-/// globals: !4, imports: !5)
+/// globals: !4, imports: !5, dwoId: 0x0abcd)
bool LLParser::ParseDICompileUnit(MDNode *&Result, bool IsDistinct) {
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
REQUIRED(language, DwarfLangField, ); \
OPTIONAL(retainedTypes, MDField, ); \
OPTIONAL(subprograms, MDField, ); \
OPTIONAL(globals, MDField, ); \
- OPTIONAL(imports, MDField, );
+ OPTIONAL(imports, MDField, ); \
+ OPTIONAL(dwoId, MDUnsignedField, );
PARSE_MD_FIELDS();
#undef VISIT_MD_FIELDS
isOptimized.Val, flags.Val, runtimeVersion.Val,
splitDebugFilename.Val, emissionKind.Val, enums.Val,
retainedTypes.Val, subprograms.Val, globals.Val,
- imports.Val));
+ imports.Val, dwoId.Val));
return false;
}
break;
}
case bitc::METADATA_COMPILE_UNIT: {
- if (Record.size() != 14)
+ if (Record.size() < 14 || Record.size() > 15)
return Error("Invalid record");
MDValueList.AssignValue(
getMDString(Record[7]), Record[8],
getMDOrNull(Record[9]), getMDOrNull(Record[10]),
getMDOrNull(Record[11]), getMDOrNull(Record[12]),
- getMDOrNull(Record[13]))),
+ getMDOrNull(Record[13]),
+ Record.size() == 14 ? 0 : Record[14])),
NextMDValueNo++);
break;
}
Record.push_back(VE.getMetadataOrNullID(N->getSubprograms().get()));
Record.push_back(VE.getMetadataOrNullID(N->getGlobalVariables().get()));
Record.push_back(VE.getMetadataOrNullID(N->getImportedEntities().get()));
+ Record.push_back(N->getDWOId());
Stream.EmitRecord(bitc::METADATA_COMPILE_UNIT, Record, Abbrev);
Record.clear();
Printer.printMetadata("subprograms", N->getRawSubprograms());
Printer.printMetadata("globals", N->getRawGlobalVariables());
Printer.printMetadata("imports", N->getRawImportedEntities());
+ Printer.printInt("dwoId", N->getDWOId());
Out << ")";
}
DICompileUnit *DIBuilder::createCompileUnit(
unsigned Lang, StringRef Filename, StringRef Directory, StringRef Producer,
bool isOptimized, StringRef Flags, unsigned RunTimeVer, StringRef SplitName,
- DebugEmissionKind Kind, bool EmitDebugInfo) {
+ DebugEmissionKind Kind, uint64_t DWOId, bool EmitDebugInfo) {
assert(((Lang <= dwarf::DW_LANG_Fortran08 && Lang >= dwarf::DW_LANG_C89) ||
(Lang <= dwarf::DW_LANG_hi_user && Lang >= dwarf::DW_LANG_lo_user)) &&
VMContext, Lang, DIFile::get(VMContext, Filename, Directory), Producer,
isOptimized, Flags, RunTimeVer, SplitName, Kind, TempEnumTypes.get(),
TempRetainTypes.get(), TempSubprograms.get(), TempGVs.get(),
- TempImportedModules.get());
+ TempImportedModules.get(), DWOId);
// Create a named metadata so that it is easier to find cu in a module.
// Note that we only generate this when the caller wants to actually
unsigned RuntimeVersion, MDString *SplitDebugFilename,
unsigned EmissionKind, Metadata *EnumTypes, Metadata *RetainedTypes,
Metadata *Subprograms, Metadata *GlobalVariables,
- Metadata *ImportedEntities, StorageType Storage, bool ShouldCreate) {
+ Metadata *ImportedEntities, uint64_t DWOId,
+ StorageType Storage, bool ShouldCreate) {
assert(isCanonical(Producer) && "Expected canonical MDString");
assert(isCanonical(Flags) && "Expected canonical MDString");
assert(isCanonical(SplitDebugFilename) && "Expected canonical MDString");
DICompileUnit,
(SourceLanguage, File, getString(Producer), IsOptimized, getString(Flags),
RuntimeVersion, getString(SplitDebugFilename), EmissionKind, EnumTypes,
- RetainedTypes, Subprograms, GlobalVariables, ImportedEntities));
+ RetainedTypes, Subprograms, GlobalVariables, ImportedEntities, DWOId));
Metadata *Ops[] = {File, Producer, Flags, SplitDebugFilename, EnumTypes,
RetainedTypes, Subprograms, GlobalVariables,
ImportedEntities};
DEFINE_GETIMPL_STORE(
DICompileUnit,
- (SourceLanguage, IsOptimized, RuntimeVersion, EmissionKind), Ops);
+ (SourceLanguage, IsOptimized, RuntimeVersion, EmissionKind, DWOId), Ops);
}
DISubprogram *DILocalScope::getSubprogram() const {
Metadata *Subprograms;
Metadata *GlobalVariables;
Metadata *ImportedEntities;
+ uint64_t DWOId;
MDNodeKeyImpl(unsigned SourceLanguage, Metadata *File, StringRef Producer,
bool IsOptimized, StringRef Flags, unsigned RuntimeVersion,
StringRef SplitDebugFilename, unsigned EmissionKind,
Metadata *EnumTypes, Metadata *RetainedTypes,
Metadata *Subprograms, Metadata *GlobalVariables,
- Metadata *ImportedEntities)
+ Metadata *ImportedEntities, uint64_t DWOId)
: SourceLanguage(SourceLanguage), File(File), Producer(Producer),
IsOptimized(IsOptimized), Flags(Flags), RuntimeVersion(RuntimeVersion),
SplitDebugFilename(SplitDebugFilename), EmissionKind(EmissionKind),
EnumTypes(EnumTypes), RetainedTypes(RetainedTypes),
Subprograms(Subprograms), GlobalVariables(GlobalVariables),
- ImportedEntities(ImportedEntities) {}
+ ImportedEntities(ImportedEntities), DWOId(DWOId) {}
MDNodeKeyImpl(const DICompileUnit *N)
: SourceLanguage(N->getSourceLanguage()), File(N->getRawFile()),
Producer(N->getProducer()), IsOptimized(N->isOptimized()),
RetainedTypes(N->getRawRetainedTypes()),
Subprograms(N->getRawSubprograms()),
GlobalVariables(N->getRawGlobalVariables()),
- ImportedEntities(N->getRawImportedEntities()) {}
+ ImportedEntities(N->getRawImportedEntities()), DWOId(N->getDWOId()) {}
bool isKeyOf(const DICompileUnit *RHS) const {
return SourceLanguage == RHS->getSourceLanguage() &&
RetainedTypes == RHS->getRawRetainedTypes() &&
Subprograms == RHS->getRawSubprograms() &&
GlobalVariables == RHS->getRawGlobalVariables() &&
- ImportedEntities == RHS->getRawImportedEntities();
+ ImportedEntities == RHS->getRawImportedEntities() &&
+ DWOId == RHS->getDWOId();
}
unsigned getHashValue() const {
return hash_combine(SourceLanguage, File, Producer, IsOptimized, Flags,
RuntimeVersion, SplitDebugFilename, EmissionKind,
EnumTypes, RetainedTypes, Subprograms, GlobalVariables,
- ImportedEntities);
+ ImportedEntities, DWOId);
}
};
!5 = distinct !{}
!6 = distinct !{}
-; CHECK: !7 = !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang", isOptimized: true, flags: "-O2", runtimeVersion: 2, splitDebugFilename: "abc.debug", emissionKind: 3, enums: !2, retainedTypes: !3, subprograms: !4, globals: !5, imports: !6)
+; CHECK: !7 = !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang", isOptimized: true, flags: "-O2", runtimeVersion: 2, splitDebugFilename: "abc.debug", emissionKind: 3, enums: !2, retainedTypes: !3, subprograms: !4, globals: !5, imports: !6, dwoId: 42)
!7 = !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang",
isOptimized: true, flags: "-O2", runtimeVersion: 2,
splitDebugFilename: "abc.debug", emissionKind: 3,
enums: !2, retainedTypes: !3, subprograms: !4,
- globals: !5, imports: !6)
+ globals: !5, imports: !6, dwoId: 42)
!8 = !DICompileUnit(language: 12, file: !1, producer: "clang",
isOptimized: true, flags: "-O2", runtimeVersion: 2,
splitDebugFilename: "abc.debug", emissionKind: 3,
enums: !2, retainedTypes: !3, subprograms: !4,
- globals: !5, imports: !6)
+ globals: !5, imports: !6, dwoId: 42)
; CHECK: !8 = !DICompileUnit(language: DW_LANG_C99, file: !1, isOptimized: false, runtimeVersion: 0, emissionKind: 0)
!9 = !DICompileUnit(language: 12, file: !1, producer: "",
--- /dev/null
+; The input uses the older (r236428) form without a dwoId field. This should
+; default to 0, which is not displayed at all in the textual representation.
+;
+; RUN: llvm-dis %s.bc -o - | FileCheck %s
+; CHECK: !DICompileUnit
+; CHECK-NOT: dwoId:
+!named = !{!0}
+!0 = !DICompileUnit(language: 12, file: !1)
+!1 = !DIFile(filename: "path/to/file", directory: "/path/to/dir")
MDTuple *Subprograms = getTuple();
MDTuple *GlobalVariables = getTuple();
MDTuple *ImportedEntities = getTuple();
+ uint64_t DWOId = 0xc0ffee;
auto *N = DICompileUnit::get(
Context, SourceLanguage, File, Producer, IsOptimized, Flags,
RuntimeVersion, SplitDebugFilename, EmissionKind, EnumTypes,
- RetainedTypes, Subprograms, GlobalVariables, ImportedEntities);
+ RetainedTypes, Subprograms, GlobalVariables, ImportedEntities, DWOId);
EXPECT_EQ(dwarf::DW_TAG_compile_unit, N->getTag());
EXPECT_EQ(SourceLanguage, N->getSourceLanguage());
EXPECT_EQ(Subprograms, N->getSubprograms().get());
EXPECT_EQ(GlobalVariables, N->getGlobalVariables().get());
EXPECT_EQ(ImportedEntities, N->getImportedEntities().get());
+ EXPECT_EQ(DWOId, N->getDWOId());
EXPECT_EQ(N, DICompileUnit::get(Context, SourceLanguage, File, Producer,
IsOptimized, Flags, RuntimeVersion,
SplitDebugFilename, EmissionKind, EnumTypes,
RetainedTypes, Subprograms, GlobalVariables,
- ImportedEntities));
+ ImportedEntities, DWOId));
EXPECT_NE(N, DICompileUnit::get(Context, SourceLanguage + 1, File, Producer,
IsOptimized, Flags, RuntimeVersion,
SplitDebugFilename, EmissionKind, EnumTypes,
RetainedTypes, Subprograms, GlobalVariables,
- ImportedEntities));
+ ImportedEntities, DWOId));
EXPECT_NE(N, DICompileUnit::get(Context, SourceLanguage, getFile(), Producer,
IsOptimized, Flags, RuntimeVersion,
SplitDebugFilename, EmissionKind, EnumTypes,
RetainedTypes, Subprograms, GlobalVariables,
- ImportedEntities));
+ ImportedEntities, DWOId));
EXPECT_NE(N, DICompileUnit::get(Context, SourceLanguage, File, "other",
IsOptimized, Flags, RuntimeVersion,
SplitDebugFilename, EmissionKind, EnumTypes,
RetainedTypes, Subprograms, GlobalVariables,
- ImportedEntities));
+ ImportedEntities, DWOId));
EXPECT_NE(N, DICompileUnit::get(Context, SourceLanguage, File, Producer,
!IsOptimized, Flags, RuntimeVersion,
SplitDebugFilename, EmissionKind, EnumTypes,
RetainedTypes, Subprograms, GlobalVariables,
- ImportedEntities));
+ ImportedEntities, DWOId));
EXPECT_NE(N, DICompileUnit::get(Context, SourceLanguage, File, Producer,
IsOptimized, "other", RuntimeVersion,
SplitDebugFilename, EmissionKind, EnumTypes,
RetainedTypes, Subprograms, GlobalVariables,
- ImportedEntities));
+ ImportedEntities, DWOId));
EXPECT_NE(N, DICompileUnit::get(Context, SourceLanguage, File, Producer,
IsOptimized, Flags, RuntimeVersion + 1,
SplitDebugFilename, EmissionKind, EnumTypes,
RetainedTypes, Subprograms, GlobalVariables,
- ImportedEntities));
- EXPECT_NE(N,
- DICompileUnit::get(Context, SourceLanguage, File, Producer,
- IsOptimized, Flags, RuntimeVersion, "other",
- EmissionKind, EnumTypes, RetainedTypes,
- Subprograms, GlobalVariables, ImportedEntities));
+ ImportedEntities, DWOId));
+ EXPECT_NE(N, DICompileUnit::get(Context, SourceLanguage, File, Producer,
+ IsOptimized, Flags, RuntimeVersion, "other",
+ EmissionKind, EnumTypes, RetainedTypes,
+ Subprograms, GlobalVariables,
+ ImportedEntities, DWOId));
EXPECT_NE(N, DICompileUnit::get(Context, SourceLanguage, File, Producer,
IsOptimized, Flags, RuntimeVersion,
SplitDebugFilename, EmissionKind + 1,
EnumTypes, RetainedTypes, Subprograms,
- GlobalVariables, ImportedEntities));
+ GlobalVariables, ImportedEntities, DWOId));
EXPECT_NE(N, DICompileUnit::get(Context, SourceLanguage, File, Producer,
IsOptimized, Flags, RuntimeVersion,
SplitDebugFilename, EmissionKind, getTuple(),
RetainedTypes, Subprograms, GlobalVariables,
- ImportedEntities));
- EXPECT_NE(N, DICompileUnit::get(
- Context, SourceLanguage, File, Producer, IsOptimized, Flags,
- RuntimeVersion, SplitDebugFilename, EmissionKind, EnumTypes,
- getTuple(), Subprograms, GlobalVariables, ImportedEntities));
+ ImportedEntities, DWOId));
+ EXPECT_NE(N, DICompileUnit::get(Context, SourceLanguage, File, Producer,
+ IsOptimized, Flags, RuntimeVersion,
+ SplitDebugFilename, EmissionKind, EnumTypes,
+ getTuple(), Subprograms, GlobalVariables,
+ ImportedEntities, DWOId));
EXPECT_NE(N, DICompileUnit::get(Context, SourceLanguage, File, Producer,
IsOptimized, Flags, RuntimeVersion,
SplitDebugFilename, EmissionKind, EnumTypes,
RetainedTypes, getTuple(), GlobalVariables,
- ImportedEntities));
- EXPECT_NE(N, DICompileUnit::get(
- Context, SourceLanguage, File, Producer, IsOptimized, Flags,
- RuntimeVersion, SplitDebugFilename, EmissionKind, EnumTypes,
- RetainedTypes, Subprograms, getTuple(), ImportedEntities));
- EXPECT_NE(N, DICompileUnit::get(
- Context, SourceLanguage, File, Producer, IsOptimized, Flags,
- RuntimeVersion, SplitDebugFilename, EmissionKind, EnumTypes,
- RetainedTypes, Subprograms, GlobalVariables, getTuple()));
+ ImportedEntities, DWOId));
+ EXPECT_NE(N, DICompileUnit::get(Context, SourceLanguage, File, Producer,
+ IsOptimized, Flags, RuntimeVersion,
+ SplitDebugFilename, EmissionKind, EnumTypes,
+ RetainedTypes, Subprograms, getTuple(),
+ ImportedEntities, DWOId));
+ EXPECT_NE(N, DICompileUnit::get(Context, SourceLanguage, File, Producer,
+ IsOptimized, Flags, RuntimeVersion,
+ SplitDebugFilename, EmissionKind, EnumTypes,
+ RetainedTypes, Subprograms, GlobalVariables,
+ getTuple(), DWOId));
+ EXPECT_NE(N, DICompileUnit::get(Context, SourceLanguage, File, Producer,
+ IsOptimized, Flags, RuntimeVersion,
+ SplitDebugFilename, EmissionKind, EnumTypes,
+ RetainedTypes, Subprograms, GlobalVariables,
+ ImportedEntities, DWOId + 1));
TempDICompileUnit Temp = N->clone();
EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
MDTuple *EnumTypes = MDTuple::getDistinct(Context, None);
MDTuple *RetainedTypes = MDTuple::getDistinct(Context, None);
MDTuple *ImportedEntities = MDTuple::getDistinct(Context, None);
+ uint64_t DWOId = 0xc0ffee;
auto *N = DICompileUnit::get(
Context, SourceLanguage, File, Producer, IsOptimized, Flags,
RuntimeVersion, SplitDebugFilename, EmissionKind, EnumTypes,
- RetainedTypes, nullptr, nullptr, ImportedEntities);
+ RetainedTypes, nullptr, nullptr, ImportedEntities, DWOId);
auto *Subprograms = MDTuple::getDistinct(Context, None);
EXPECT_EQ(nullptr, N->getSubprograms().get());