summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
Diffstat (limited to 'llvm')
-rw-r--r--llvm/include/llvm/Bitcode/BitcodeReader.h30
-rw-r--r--llvm/lib/Bitcode/Reader/BitcodeReader.cpp37
-rw-r--r--llvm/lib/Bitcode/Reader/MetadataLoader.cpp49
-rw-r--r--llvm/lib/Bitcode/Reader/MetadataLoader.h4
-rw-r--r--llvm/lib/LTO/LTO.cpp6
-rw-r--r--llvm/lib/LTO/LTOBackend.cpp3
-rw-r--r--llvm/lib/LTO/ThinLTOCodeGenerator.cpp17
-rw-r--r--llvm/lib/Object/IRObjectFile.cpp3
-rw-r--r--llvm/test/ThinLTO/X86/Inputs/debuginfo-compositetype-import.ll13
-rw-r--r--llvm/test/ThinLTO/X86/debuginfo-compositetype-import.ll62
10 files changed, 173 insertions, 51 deletions
diff --git a/llvm/include/llvm/Bitcode/BitcodeReader.h b/llvm/include/llvm/Bitcode/BitcodeReader.h
index ab2f25186d7..9e042b17241 100644
--- a/llvm/include/llvm/Bitcode/BitcodeReader.h
+++ b/llvm/include/llvm/Bitcode/BitcodeReader.h
@@ -61,9 +61,10 @@ namespace llvm {
friend Expected<std::vector<BitcodeModule>>
getBitcodeModuleList(MemoryBufferRef Buffer);
- Expected<std::unique_ptr<Module>>
- getModuleImpl(LLVMContext &Context, bool MaterializeAll,
- bool ShouldLazyLoadMetadata);
+ Expected<std::unique_ptr<Module>> getModuleImpl(LLVMContext &Context,
+ bool MaterializeAll,
+ bool ShouldLazyLoadMetadata,
+ bool IsImporting);
public:
StringRef getBuffer() const {
@@ -74,8 +75,11 @@ namespace llvm {
/// Read the bitcode module and prepare for lazy deserialization of function
/// bodies. If ShouldLazyLoadMetadata is true, lazily load metadata as well.
- Expected<std::unique_ptr<Module>>
- getLazyModule(LLVMContext &Context, bool ShouldLazyLoadMetadata);
+ /// If IsImporting is true, this module is being parsed for ThinLTO
+ /// importing into another module.
+ Expected<std::unique_ptr<Module>> getLazyModule(LLVMContext &Context,
+ bool ShouldLazyLoadMetadata,
+ bool IsImporting);
/// Read the entire bitcode module and return it.
Expected<std::unique_ptr<Module>> parseModule(LLVMContext &Context);
@@ -93,18 +97,20 @@ namespace llvm {
/// Read the header of the specified bitcode buffer and prepare for lazy
/// deserialization of function bodies. If ShouldLazyLoadMetadata is true,
- /// lazily load metadata as well.
+ /// lazily load metadata as well. If IsImporting is true, this module is
+ /// being parsed for ThinLTO importing into another module.
Expected<std::unique_ptr<Module>>
getLazyBitcodeModule(MemoryBufferRef Buffer, LLVMContext &Context,
- bool ShouldLazyLoadMetadata = false);
+ bool ShouldLazyLoadMetadata = false,
+ bool IsImporting = false);
/// Like getLazyBitcodeModule, except that the module takes ownership of
/// the memory buffer if successful. If successful, this moves Buffer. On
- /// error, this *does not* move Buffer.
- Expected<std::unique_ptr<Module>>
- getOwningLazyBitcodeModule(std::unique_ptr<MemoryBuffer> &&Buffer,
- LLVMContext &Context,
- bool ShouldLazyLoadMetadata = false);
+ /// error, this *does not* move Buffer. If IsImporting is true, this module is
+ /// being parsed for ThinLTO importing into another module.
+ Expected<std::unique_ptr<Module>> getOwningLazyBitcodeModule(
+ std::unique_ptr<MemoryBuffer> &&Buffer, LLVMContext &Context,
+ bool ShouldLazyLoadMetadata = false, bool IsImporting = false);
/// Read the header of the specified bitcode buffer and extract just the
/// triple information. If successful, this returns a string. On error, this
diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
index ad4d9cec717..4812b2cfe8e 100644
--- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -488,7 +488,8 @@ public:
/// \brief Main interface to parsing a bitcode buffer.
/// \returns true if an error occurred.
- Error parseBitcodeInto(Module *M, bool ShouldLazyLoadMetadata = false);
+ Error parseBitcodeInto(Module *M, bool ShouldLazyLoadMetadata = false,
+ bool IsImporting = false);
static uint64_t decodeSignRotatedValue(uint64_t V);
@@ -3084,9 +3085,10 @@ Error BitcodeReader::parseModule(uint64_t ResumeBit,
}
}
-Error BitcodeReader::parseBitcodeInto(Module *M, bool ShouldLazyLoadMetadata) {
+Error BitcodeReader::parseBitcodeInto(Module *M, bool ShouldLazyLoadMetadata,
+ bool IsImporting) {
TheModule = M;
- MDLoader = MetadataLoader(Stream, *M, ValueList,
+ MDLoader = MetadataLoader(Stream, *M, ValueList, IsImporting,
[&](unsigned ID) { return getTypeByID(ID); });
return parseModule(0, ShouldLazyLoadMetadata);
}
@@ -5220,7 +5222,7 @@ llvm::getBitcodeModuleList(MemoryBufferRef Buffer) {
/// everything.
Expected<std::unique_ptr<Module>>
BitcodeModule::getModuleImpl(LLVMContext &Context, bool MaterializeAll,
- bool ShouldLazyLoadMetadata) {
+ bool ShouldLazyLoadMetadata, bool IsImporting) {
BitstreamCursor Stream(Buffer);
std::string ProducerIdentification;
@@ -5243,7 +5245,8 @@ BitcodeModule::getModuleImpl(LLVMContext &Context, bool MaterializeAll,
M->setMaterializer(R);
// Delay parsing Metadata if ShouldLazyLoadMetadata is true.
- if (Error Err = R->parseBitcodeInto(M.get(), ShouldLazyLoadMetadata))
+ if (Error Err =
+ R->parseBitcodeInto(M.get(), ShouldLazyLoadMetadata, IsImporting))
return std::move(Err);
if (MaterializeAll) {
@@ -5259,9 +5262,9 @@ BitcodeModule::getModuleImpl(LLVMContext &Context, bool MaterializeAll,
}
Expected<std::unique_ptr<Module>>
-BitcodeModule::getLazyModule(LLVMContext &Context,
- bool ShouldLazyLoadMetadata) {
- return getModuleImpl(Context, false, ShouldLazyLoadMetadata);
+BitcodeModule::getLazyModule(LLVMContext &Context, bool ShouldLazyLoadMetadata,
+ bool IsImporting) {
+ return getModuleImpl(Context, false, ShouldLazyLoadMetadata, IsImporting);
}
// Parse the specified bitcode buffer, returning the function info index.
@@ -5323,20 +5326,20 @@ static Expected<BitcodeModule> getSingleModule(MemoryBufferRef Buffer) {
}
Expected<std::unique_ptr<Module>>
-llvm::getLazyBitcodeModule(MemoryBufferRef Buffer,
- LLVMContext &Context, bool ShouldLazyLoadMetadata) {
+llvm::getLazyBitcodeModule(MemoryBufferRef Buffer, LLVMContext &Context,
+ bool ShouldLazyLoadMetadata, bool IsImporting) {
Expected<BitcodeModule> BM = getSingleModule(Buffer);
if (!BM)
return BM.takeError();
- return BM->getLazyModule(Context, ShouldLazyLoadMetadata);
+ return BM->getLazyModule(Context, ShouldLazyLoadMetadata, IsImporting);
}
-Expected<std::unique_ptr<Module>>
-llvm::getOwningLazyBitcodeModule(std::unique_ptr<MemoryBuffer> &&Buffer,
- LLVMContext &Context,
- bool ShouldLazyLoadMetadata) {
- auto MOrErr = getLazyBitcodeModule(*Buffer, Context, ShouldLazyLoadMetadata);
+Expected<std::unique_ptr<Module>> llvm::getOwningLazyBitcodeModule(
+ std::unique_ptr<MemoryBuffer> &&Buffer, LLVMContext &Context,
+ bool ShouldLazyLoadMetadata, bool IsImporting) {
+ auto MOrErr = getLazyBitcodeModule(*Buffer, Context, ShouldLazyLoadMetadata,
+ IsImporting);
if (MOrErr)
(*MOrErr)->setOwnedMemoryBuffer(std::move(Buffer));
return MOrErr;
@@ -5344,7 +5347,7 @@ llvm::getOwningLazyBitcodeModule(std::unique_ptr<MemoryBuffer> &&Buffer,
Expected<std::unique_ptr<Module>>
BitcodeModule::parseModule(LLVMContext &Context) {
- return getModuleImpl(Context, true, false);
+ return getModuleImpl(Context, true, false, false);
// TODO: Restore the use-lists to the in-memory state when the bitcode was
// written. We must defer until the Module has been fully materialized.
}
diff --git a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp
index 1e28411d01e..eb24ac6def1 100644
--- a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp
+++ b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp
@@ -86,6 +86,12 @@
using namespace llvm;
+/// Flag whether we need to import full type definitions for ThinLTO.
+/// Currently needed for Darwin and LLDB.
+static cl::opt<bool> ImportFullTypeDefinitions(
+ "import-full-type-definitions", cl::init(false), cl::Hidden,
+ cl::desc("Import full type definitions for ThinLTO."));
+
namespace {
static int64_t unrotateSign(uint64_t U) { return U & 1 ? ~(U >> 1) : U >> 1; }
@@ -399,7 +405,7 @@ public:
Stream(Stream), Context(TheModule.getContext()), TheModule(TheModule),
getTypeByID(getTypeByID) {}
- Error parseMetadata(bool ModuleLevel);
+ Error parseMetadata(bool ModuleLevel, bool IsImporting);
bool hasFwdRefs() const { return MetadataList.hasFwdRefs(); }
Metadata *getMetadataFwdRef(unsigned Idx) {
@@ -435,7 +441,8 @@ Error error(const Twine &Message) {
/// Parse a METADATA_BLOCK. If ModuleLevel is true then we are parsing
/// module level metadata.
-Error MetadataLoader::MetadataLoaderImpl::parseMetadata(bool ModuleLevel) {
+Error MetadataLoader::MetadataLoaderImpl::parseMetadata(bool ModuleLevel,
+ bool IsImporting) {
if (!ModuleLevel && MetadataList.hasFwdRefs())
return error("Invalid metadata: fwd refs into function blocks");
@@ -709,18 +716,38 @@ Error MetadataLoader::MetadataLoaderImpl::parseMetadata(bool ModuleLevel) {
Metadata *File = getMDOrNull(Record[3]);
unsigned Line = Record[4];
Metadata *Scope = getDITypeRefOrNull(Record[5]);
- Metadata *BaseType = getDITypeRefOrNull(Record[6]);
+ Metadata *BaseType = nullptr;
uint64_t SizeInBits = Record[7];
if (Record[8] > (uint64_t)std::numeric_limits<uint32_t>::max())
return error("Alignment value is too large");
uint32_t AlignInBits = Record[8];
- uint64_t OffsetInBits = Record[9];
+ uint64_t OffsetInBits = 0;
DINode::DIFlags Flags = static_cast<DINode::DIFlags>(Record[10]);
- Metadata *Elements = getMDOrNull(Record[11]);
+ Metadata *Elements = nullptr;
unsigned RuntimeLang = Record[12];
- Metadata *VTableHolder = getDITypeRefOrNull(Record[13]);
- Metadata *TemplateParams = getMDOrNull(Record[14]);
+ Metadata *VTableHolder = nullptr;
+ Metadata *TemplateParams = nullptr;
auto *Identifier = getMDString(Record[15]);
+ // If this module is being parsed so that it can be ThinLTO imported
+ // into another module, composite types only need to be imported
+ // as type declarations (unless full type definitions requested).
+ // Create type declarations up front to save memory. Also, buildODRType
+ // handles the case where this is type ODRed with a definition needed
+ // by the importing module, in which case the existing definition is
+ // used.
+ if (IsImporting && !ImportFullTypeDefinitions &&
+ (Tag == dwarf::DW_TAG_enumeration_type ||
+ Tag == dwarf::DW_TAG_class_type ||
+ Tag == dwarf::DW_TAG_structure_type ||
+ Tag == dwarf::DW_TAG_union_type)) {
+ Flags = Flags | DINode::FlagFwdDecl;
+ } else {
+ BaseType = getDITypeRefOrNull(Record[6]);
+ OffsetInBits = Record[9];
+ Elements = getMDOrNull(Record[11]);
+ VTableHolder = getDITypeRefOrNull(Record[13]);
+ TemplateParams = getMDOrNull(Record[14]);
+ }
DICompositeType *CT = nullptr;
if (Identifier)
CT = DICompositeType::buildODRType(
@@ -1281,17 +1308,19 @@ MetadataLoader &MetadataLoader::operator=(MetadataLoader &&RHS) {
return *this;
}
MetadataLoader::MetadataLoader(MetadataLoader &&RHS)
- : Pimpl(std::move(RHS.Pimpl)) {}
+ : Pimpl(std::move(RHS.Pimpl)), IsImporting(RHS.IsImporting) {}
MetadataLoader::~MetadataLoader() = default;
MetadataLoader::MetadataLoader(BitstreamCursor &Stream, Module &TheModule,
BitcodeReaderValueList &ValueList,
+ bool IsImporting,
std::function<Type *(unsigned)> getTypeByID)
: Pimpl(llvm::make_unique<MetadataLoaderImpl>(Stream, TheModule, ValueList,
- getTypeByID)) {}
+ getTypeByID)),
+ IsImporting(IsImporting) {}
Error MetadataLoader::parseMetadata(bool ModuleLevel) {
- return Pimpl->parseMetadata(ModuleLevel);
+ return Pimpl->parseMetadata(ModuleLevel, IsImporting);
}
bool MetadataLoader::hasFwdRefs() const { return Pimpl->hasFwdRefs(); }
diff --git a/llvm/lib/Bitcode/Reader/MetadataLoader.h b/llvm/lib/Bitcode/Reader/MetadataLoader.h
index 7d1027e9d52..351857e342c 100644
--- a/llvm/lib/Bitcode/Reader/MetadataLoader.h
+++ b/llvm/lib/Bitcode/Reader/MetadataLoader.h
@@ -36,12 +36,14 @@ class Type;
class MetadataLoader {
class MetadataLoaderImpl;
std::unique_ptr<MetadataLoaderImpl> Pimpl;
+ /// True if metadata is being parsed for a module being ThinLTO imported.
+ bool IsImporting = false;
Error parseMetadata(bool ModuleLevel);
public:
~MetadataLoader();
MetadataLoader(BitstreamCursor &Stream, Module &TheModule,
- BitcodeReaderValueList &ValueList,
+ BitcodeReaderValueList &ValueList, bool IsImporting,
std::function<Type *(unsigned)> getTypeByID);
MetadataLoader &operator=(MetadataLoader &&);
MetadataLoader(MetadataLoader &&);
diff --git a/llvm/lib/LTO/LTO.cpp b/llvm/lib/LTO/LTO.cpp
index 09198591da9..7364f0e0cd3 100644
--- a/llvm/lib/LTO/LTO.cpp
+++ b/llvm/lib/LTO/LTO.cpp
@@ -252,7 +252,8 @@ Expected<std::unique_ptr<InputFile>> InputFile::create(MemoryBufferRef Object) {
// ModuleSymbolTable.
for (auto BM : *BMsOrErr) {
Expected<std::unique_ptr<Module>> MOrErr =
- BM.getLazyModule(File->Ctx, /*ShouldLazyLoadMetadata*/ true);
+ BM.getLazyModule(File->Ctx, /*ShouldLazyLoadMetadata*/ true,
+ /*IsImporting*/ false);
if (!MOrErr)
return MOrErr.takeError();
@@ -415,7 +416,8 @@ Error LTO::addRegularLTO(BitcodeModule BM, const SymbolResolution *&ResI,
RegularLTO.Mover = llvm::make_unique<IRMover>(*RegularLTO.CombinedModule);
}
Expected<std::unique_ptr<Module>> MOrErr =
- BM.getLazyModule(RegularLTO.Ctx, /*ShouldLazyLoadMetadata*/ true);
+ BM.getLazyModule(RegularLTO.Ctx, /*ShouldLazyLoadMetadata*/ true,
+ /*IsImporting*/ false);
if (!MOrErr)
return MOrErr.takeError();
diff --git a/llvm/lib/LTO/LTOBackend.cpp b/llvm/lib/LTO/LTOBackend.cpp
index dbb54f34565..6342cbe4fd9 100644
--- a/llvm/lib/LTO/LTOBackend.cpp
+++ b/llvm/lib/LTO/LTOBackend.cpp
@@ -356,7 +356,8 @@ Error lto::thinBackend(Config &Conf, unsigned Task, AddStreamFn AddStream,
auto I = ModuleMap.find(Identifier);
assert(I != ModuleMap.end());
return I->second.getLazyModule(Mod.getContext(),
- /*ShouldLazyLoadMetadata=*/true);
+ /*ShouldLazyLoadMetadata=*/true,
+ /*IsImporting*/ true);
};
FunctionImporter Importer(CombinedIndex, ModuleLoader);
diff --git a/llvm/lib/LTO/ThinLTOCodeGenerator.cpp b/llvm/lib/LTO/ThinLTOCodeGenerator.cpp
index 950930176c0..2791efc69cd 100644
--- a/llvm/lib/LTO/ThinLTOCodeGenerator.cpp
+++ b/llvm/lib/LTO/ThinLTOCodeGenerator.cpp
@@ -168,12 +168,13 @@ static void promoteModule(Module &TheModule, const ModuleSummaryIndex &Index) {
static std::unique_ptr<Module>
loadModuleFromBuffer(const MemoryBufferRef &Buffer, LLVMContext &Context,
- bool Lazy) {
+ bool Lazy, bool IsImporting) {
SMDiagnostic Err;
Expected<std::unique_ptr<Module>> ModuleOrErr =
- Lazy ? getLazyBitcodeModule(Buffer, Context,
- /* ShouldLazyLoadMetadata */ true)
- : parseBitcodeFile(Buffer, Context);
+ Lazy
+ ? getLazyBitcodeModule(Buffer, Context,
+ /* ShouldLazyLoadMetadata */ true, IsImporting)
+ : parseBitcodeFile(Buffer, Context);
if (!ModuleOrErr) {
handleAllErrors(ModuleOrErr.takeError(), [&](ErrorInfoBase &EIB) {
SMDiagnostic Err = SMDiagnostic(Buffer.getBufferIdentifier(),
@@ -191,7 +192,7 @@ crossImportIntoModule(Module &TheModule, const ModuleSummaryIndex &Index,
const FunctionImporter::ImportMapTy &ImportList) {
auto Loader = [&](StringRef Identifier) {
return loadModuleFromBuffer(ModuleMap[Identifier], TheModule.getContext(),
- /*Lazy=*/true);
+ /*Lazy=*/true, /*IsImporting*/ true);
};
FunctionImporter Importer(Index, Loader);
@@ -787,7 +788,8 @@ void ThinLTOCodeGenerator::run() {
Context.setDiscardValueNames(LTODiscardValueNames);
// Parse module now
- auto TheModule = loadModuleFromBuffer(ModuleBuffer, Context, false);
+ auto TheModule = loadModuleFromBuffer(ModuleBuffer, Context, false,
+ /*IsImporting*/ false);
// CodeGen
ProducedBinaries[count] = codegen(*TheModule);
@@ -933,7 +935,8 @@ void ThinLTOCodeGenerator::run() {
}
// Parse module now
- auto TheModule = loadModuleFromBuffer(ModuleBuffer, Context, false);
+ auto TheModule = loadModuleFromBuffer(ModuleBuffer, Context, false,
+ /*IsImporting*/ false);
// Save temps: original file.
saveTempBitcode(*TheModule, SaveTempsDir, count, ".0.original.bc");
diff --git a/llvm/lib/Object/IRObjectFile.cpp b/llvm/lib/Object/IRObjectFile.cpp
index 2d055e14470..adbf0de6d1b 100644
--- a/llvm/lib/Object/IRObjectFile.cpp
+++ b/llvm/lib/Object/IRObjectFile.cpp
@@ -127,7 +127,8 @@ IRObjectFile::create(MemoryBufferRef Object, LLVMContext &Context) {
std::vector<std::unique_ptr<Module>> Mods;
for (auto BM : *BMsOrErr) {
Expected<std::unique_ptr<Module>> MOrErr =
- BM.getLazyModule(Context, /*ShouldLazyLoadMetadata*/ true);
+ BM.getLazyModule(Context, /*ShouldLazyLoadMetadata*/ true,
+ /*IsImporting*/ false);
if (!MOrErr)
return MOrErr.takeError();
diff --git a/llvm/test/ThinLTO/X86/Inputs/debuginfo-compositetype-import.ll b/llvm/test/ThinLTO/X86/Inputs/debuginfo-compositetype-import.ll
new file mode 100644
index 00000000000..7e80c4d7c44
--- /dev/null
+++ b/llvm/test/ThinLTO/X86/Inputs/debuginfo-compositetype-import.ll
@@ -0,0 +1,13 @@
+; ModuleID = 'debuginfo-compositetype-import2.c'
+source_filename = "debuginfo-compositetype-import2.c"
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+; Function Attrs: nounwind uwtable
+define i32 @main() {
+entry:
+ call void (...) @foo()
+ ret i32 0
+}
+
+declare void @foo(...) #1
diff --git a/llvm/test/ThinLTO/X86/debuginfo-compositetype-import.ll b/llvm/test/ThinLTO/X86/debuginfo-compositetype-import.ll
new file mode 100644
index 00000000000..0b3a7a45224
--- /dev/null
+++ b/llvm/test/ThinLTO/X86/debuginfo-compositetype-import.ll
@@ -0,0 +1,62 @@
+; Test to ensure DICompositeType are imported as type declarations
+; for ThinLTO
+
+; RUN: opt -module-summary %s -o %t1.bc
+; RUN: opt -module-summary %p/Inputs/debuginfo-compositetype-import.ll -o %t2.bc
+; RUN: llvm-lto -thinlto-action=thinlink -o %t.index.bc %t1.bc %t2.bc
+
+; By default, composite types are imported as type declarations
+; RUN: llvm-lto -thinlto-action=import %t2.bc -thinlto-index=%t.index.bc -o - | llvm-dis -o - | FileCheck %s
+; RUN: llvm-lto2 %t1.bc %t2.bc -o %t.out -save-temps \
+; RUN: -r %t2.bc,main,plx \
+; RUN: -r %t2.bc,foo,l \
+; RUN: -r %t1.bc,foo,pl
+; RUN: llvm-dis < %t.out.1.3.import.bc | FileCheck %s
+
+; CHECK: distinct !DICompositeType(tag: DW_TAG_enumeration_type, name: "enum", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: 50, size: 32, flags: DIFlagFwdDecl, identifier: "enum")
+; CHECK: distinct !DICompositeType(tag: DW_TAG_class_type, name: "class", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: 728, size: 448, flags: DIFlagFwdDecl, identifier: "class")
+; CHECK: distinct !DICompositeType(tag: DW_TAG_structure_type, name: "struct", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: 309, size: 128, flags: DIFlagFwdDecl, identifier: "list")
+; CHECK: distinct !DICompositeType(tag: DW_TAG_union_type, file: !{{[0-9]+}}, line: 115, size: 384, flags: DIFlagFwdDecl, identifier: "union")
+
+; Ensure that full type definitions of composite types are imported if requested
+; RUN: llvm-lto -import-full-type-definitions -thinlto-action=import %t2.bc -thinlto-index=%t.index.bc -o - | llvm-dis -o - | FileCheck %s --check-prefix=FULL
+; RUN: llvm-lto2 %t1.bc %t2.bc -o %t.out -save-temps \
+; RUN: -import-full-type-definitions \
+; RUN: -r %t2.bc,main,plx \
+; RUN: -r %t2.bc,foo,l \
+; RUN: -r %t1.bc,foo,pl
+; RUN: llvm-dis < %t.out.1.3.import.bc | FileCheck %s --check-prefix=FULL
+
+; FULL: distinct !DICompositeType(tag: DW_TAG_enumeration_type, name: "enum", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: 50, size: 32, elements: !{{[0-9]+}}, identifier: "enum")
+; FULL: distinct !DICompositeType(tag: DW_TAG_class_type, name: "class", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: 728, size: 448, elements: !{{[0-9]+}}, identifier: "class")
+; FULL: distinct !DICompositeType(tag: DW_TAG_structure_type, name: "struct", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: 309, baseType: !{{[0-9]+}}, size: 128, offset: 64, elements: !{{[0-9]+}}, vtableHolder: !{{[0-9]+}}, templateParams: !{{[0-9]+}}, identifier: "list")
+; FULL: distinct !DICompositeType(tag: DW_TAG_union_type, file: !{{[0-9]+}}, line: 115, size: 384, elements: !{{[0-9]+}}, identifier: "union")
+
+; ModuleID = 'debuginfo-compositetype-import.c'
+source_filename = "debuginfo-compositetype-import.c"
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+; Function Attrs: nounwind uwtable
+define void @foo() #0 !dbg !6 {
+entry:
+ ret void
+}
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!2, !3}
+!llvm.ident = !{!4}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 4.0.0 (trunk 286863) (llvm/trunk 286875)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug)
+!1 = !DIFile(filename: "debuginfo-compositetype-import.c", directory: "")
+!2 = !{i32 2, !"Dwarf Version", i32 4}
+!3 = !{i32 2, !"Debug Info Version", i32 3}
+!4 = !{!"clang version 4.0.0 (trunk 286863) (llvm/trunk 286875)"}
+!5 = !{}
+!6 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 1, type: !7, isLocal: false, isDefinition: true, scopeLine: 2, isOptimized: false, unit: !0, variables: !5)
+!7 = !DISubroutineType(types: !8)
+!8 = !{!9, !10, !11, !12}
+!9 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "enum", scope: !1, file: !1, line: 50, size: 32, elements: !5, identifier: "enum")
+!10 = !DICompositeType(tag: DW_TAG_class_type, name: "class", scope: !1, file: !1, line: 728, size: 448, elements: !5, identifier: "class")
+!11 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "struct", scope: !1, file: !1, line: 309, baseType: !10, size: 128, offset: 64, elements: !5, vtableHolder: !10, templateParams: !5, identifier: "list")
+!12 = distinct !DICompositeType(tag: DW_TAG_union_type, file: !1, line: 115, size: 384, elements: !5, identifier: "union")
OpenPOWER on IntegriCloud