aboutsummaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/llc/llc.cpp4
-rw-r--r--tools/llvm-cvtres/CMakeLists.txt1
-rw-r--r--tools/llvm-cvtres/llvm-cvtres.cpp100
-rw-r--r--tools/llvm-cvtres/llvm-cvtres.h6
-rw-r--r--tools/llvm-dwp/llvm-dwp.cpp2
-rw-r--r--tools/llvm-lto/llvm-lto.cpp24
-rw-r--r--tools/llvm-pdbdump/Analyze.cpp1
-rw-r--r--tools/llvm-pdbdump/CompactTypeDumpVisitor.cpp10
-rw-r--r--tools/llvm-pdbdump/CompactTypeDumpVisitor.h8
-rw-r--r--tools/llvm-pdbdump/LLVMOutputStyle.cpp119
-rw-r--r--tools/llvm-pdbdump/LLVMOutputStyle.h12
-rw-r--r--tools/llvm-pdbdump/PdbYaml.cpp2
-rw-r--r--tools/llvm-pdbdump/YAMLOutputStyle.h1
-rw-r--r--tools/llvm-pdbdump/YamlTypeDumper.cpp1
-rw-r--r--tools/llvm-pdbdump/llvm-pdbdump.cpp86
-rw-r--r--tools/llvm-readobj/COFFDumper.cpp99
-rw-r--r--tools/opt/opt.cpp12
17 files changed, 323 insertions, 165 deletions
diff --git a/tools/llc/llc.cpp b/tools/llc/llc.cpp
index 8c786950036f..589005943045 100644
--- a/tools/llc/llc.cpp
+++ b/tools/llc/llc.cpp
@@ -356,9 +356,7 @@ static bool addPass(PassManagerBase &PM, const char *argv0,
}
Pass *P;
- if (PI->getTargetMachineCtor())
- P = PI->getTargetMachineCtor()(&TPC.getTM<TargetMachine>());
- else if (PI->getNormalCtor())
+ if (PI->getNormalCtor())
P = PI->getNormalCtor()();
else {
errs() << argv0 << ": cannot create pass: " << PI->getPassName() << "\n";
diff --git a/tools/llvm-cvtres/CMakeLists.txt b/tools/llvm-cvtres/CMakeLists.txt
index 52edccac8165..e912030e205e 100644
--- a/tools/llvm-cvtres/CMakeLists.txt
+++ b/tools/llvm-cvtres/CMakeLists.txt
@@ -1,4 +1,5 @@
set(LLVM_LINK_COMPONENTS
+ Object
Option
Support
)
diff --git a/tools/llvm-cvtres/llvm-cvtres.cpp b/tools/llvm-cvtres/llvm-cvtres.cpp
index f03e0b772e1b..96f7437ab5f6 100644
--- a/tools/llvm-cvtres/llvm-cvtres.cpp
+++ b/tools/llvm-cvtres/llvm-cvtres.cpp
@@ -14,17 +14,23 @@
#include "llvm-cvtres.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/Object/Binary.h"
+#include "llvm/Object/WindowsResource.h"
#include "llvm/Option/Arg.h"
#include "llvm/Option/ArgList.h"
#include "llvm/Option/Option.h"
+#include "llvm/Support/BinaryStreamError.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/Path.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/Process.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
+using namespace object;
namespace {
@@ -61,6 +67,28 @@ public:
static ExitOnError ExitOnErr;
}
+LLVM_ATTRIBUTE_NORETURN void reportError(Twine Msg) {
+ errs() << Msg;
+ exit(1);
+}
+
+static void reportError(StringRef Input, std::error_code EC) {
+ reportError(Twine(Input) + ": " + EC.message() + ".\n");
+}
+
+void error(std::error_code EC) {
+ if (!EC)
+ return;
+ reportError(EC.message() + ".\n");
+}
+
+void error(Error EC) {
+ if (!EC)
+ return;
+ handleAllErrors(std::move(EC),
+ [&](const ErrorInfoBase &EI) { reportError(EI.message()); });
+}
+
int main(int argc_, const char *argv_[]) {
sys::PrintStackTraceOnErrorSignal(argv_[0]);
PrettyStackTraceProgram X(argc_, argv_);
@@ -76,11 +104,79 @@ int main(int argc_, const char *argv_[]) {
CvtResOptTable T;
unsigned MAI, MAC;
- ArrayRef<const char *> ArgsArr = makeArrayRef(argv_, argc_);
+ ArrayRef<const char *> ArgsArr = makeArrayRef(argv_ + 1, argc_);
opt::InputArgList InputArgs = T.ParseArgs(ArgsArr, MAI, MAC);
- if (InputArgs.hasArg(OPT_HELP))
+ if (InputArgs.hasArg(OPT_HELP)) {
T.PrintHelp(outs(), "cvtres", "Resource Converter", false);
+ return 0;
+ }
+
+ machine Machine;
+
+ if (InputArgs.hasArg(OPT_MACHINE)) {
+ std::string MachineString = InputArgs.getLastArgValue(OPT_MACHINE).upper();
+ Machine = StringSwitch<machine>(MachineString)
+ .Case("ARM", machine::ARM)
+ .Case("X64", machine::X64)
+ .Case("X86", machine::X86)
+ .Default(machine::UNKNOWN);
+ if (Machine == machine::UNKNOWN)
+ reportError("Unsupported machine architecture");
+ } else {
+ outs() << "Machine architecture not specified; assumed X64.\n";
+ Machine = machine::X64;
+ }
+
+ std::vector<std::string> InputFiles = InputArgs.getAllArgValues(OPT_INPUT);
+
+ if (InputFiles.size() == 0) {
+ reportError("No input file specified");
+ }
+
+ SmallString<128> OutputFile;
+
+ if (InputArgs.hasArg(OPT_OUT)) {
+ OutputFile = InputArgs.getLastArgValue(OPT_OUT);
+ } else {
+ OutputFile = StringRef(InputFiles[0]);
+ llvm::sys::path::replace_extension(OutputFile, ".obj");
+ }
+
+ for (const auto &File : InputFiles) {
+ Expected<object::OwningBinary<object::Binary>> BinaryOrErr =
+ object::createBinary(File);
+ if (!BinaryOrErr)
+ reportError(File, errorToErrorCode(BinaryOrErr.takeError()));
+
+ Binary &Binary = *BinaryOrErr.get().getBinary();
+
+ WindowsResource *RF = dyn_cast<WindowsResource>(&Binary);
+ if (!RF)
+ reportError(File + ": unrecognized file format.\n");
+ int EntryNumber = 0;
+ Expected<ResourceEntryRef> EntryOrErr = RF->getHeadEntry();
+ if (!EntryOrErr)
+ error(EntryOrErr.takeError());
+ ResourceEntryRef Entry = EntryOrErr.get();
+ bool End = false;
+ while (!End) {
+ error(Entry.moveNext(End));
+ EntryNumber++;
+ }
+ outs() << "Number of resources: " << EntryNumber << "\n";
+ }
+ outs() << "Machine: ";
+ switch (Machine) {
+ case machine::ARM:
+ outs() << "ARM\n";
+ break;
+ case machine::X86:
+ outs() << "X86\n";
+ break;
+ default:
+ outs() << "X64\n";
+ }
return 0;
}
diff --git a/tools/llvm-cvtres/llvm-cvtres.h b/tools/llvm-cvtres/llvm-cvtres.h
index eeaba1969036..2e45b66461f0 100644
--- a/tools/llvm-cvtres/llvm-cvtres.h
+++ b/tools/llvm-cvtres/llvm-cvtres.h
@@ -10,4 +10,10 @@
#ifndef LLVM_TOOLS_LLVMCVTRES_LLVMCVTRES_H
#define LLVM_TOOLS_LLVMCVTRES_LLVMCVTRES_H
+#include <system_error>
+
+void error(std::error_code EC);
+
+enum class machine { UNKNOWN = 0, ARM, X64, X86 };
+
#endif
diff --git a/tools/llvm-dwp/llvm-dwp.cpp b/tools/llvm-dwp/llvm-dwp.cpp
index 0c4af7576608..f8d00b3b5534 100644
--- a/tools/llvm-dwp/llvm-dwp.cpp
+++ b/tools/llvm-dwp/llvm-dwp.cpp
@@ -373,7 +373,7 @@ handleCompressedSection(std::deque<SmallString<32>> &UncompressedSections,
return createError(Name, Dec.takeError());
UncompressedSections.emplace_back();
- if (Error E = Dec->decompress(UncompressedSections.back()))
+ if (Error E = Dec->resizeAndDecompress(UncompressedSections.back()))
return createError(Name, std::move(E));
Name = Name.substr(2); // Drop ".z"
diff --git a/tools/llvm-lto/llvm-lto.cpp b/tools/llvm-lto/llvm-lto.cpp
index 2458d3d123ca..ccc673be4570 100644
--- a/tools/llvm-lto/llvm-lto.cpp
+++ b/tools/llvm-lto/llvm-lto.cpp
@@ -669,24 +669,30 @@ private:
if (!ThinLTOIndex.empty())
errs() << "Warning: -thinlto-index ignored for codegen stage";
+ std::vector<std::unique_ptr<MemoryBuffer>> InputBuffers;
for (auto &Filename : InputFilenames) {
LLVMContext Ctx;
- auto TheModule = loadModule(Filename, Ctx);
-
- auto Buffer = ThinGenerator.codegen(*TheModule);
+ auto InputOrErr = MemoryBuffer::getFile(Filename);
+ error(InputOrErr, "error " + CurrentActivity);
+ InputBuffers.push_back(std::move(*InputOrErr));
+ ThinGenerator.addModule(Filename, InputBuffers.back()->getBuffer());
+ }
+ ThinGenerator.setCodeGenOnly(true);
+ ThinGenerator.run();
+ for (auto BinName :
+ zip(ThinGenerator.getProducedBinaries(), InputFilenames)) {
std::string OutputName = OutputFilename;
- if (OutputName.empty()) {
- OutputName = Filename + ".thinlto.o";
- }
- if (OutputName == "-") {
- outs() << Buffer->getBuffer();
+ if (OutputName.empty())
+ OutputName = std::get<1>(BinName) + ".thinlto.o";
+ else if (OutputName == "-") {
+ outs() << std::get<0>(BinName)->getBuffer();
return;
}
std::error_code EC;
raw_fd_ostream OS(OutputName, EC, sys::fs::OpenFlags::F_None);
error(EC, "error opening the file '" + OutputName + "'");
- OS << Buffer->getBuffer();
+ OS << std::get<0>(BinName)->getBuffer();
}
}
diff --git a/tools/llvm-pdbdump/Analyze.cpp b/tools/llvm-pdbdump/Analyze.cpp
index ab4477ed7bad..3a026e5d2451 100644
--- a/tools/llvm-pdbdump/Analyze.cpp
+++ b/tools/llvm-pdbdump/Analyze.cpp
@@ -14,7 +14,6 @@
#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
#include "llvm/DebugInfo/CodeView/TypeDatabase.h"
#include "llvm/DebugInfo/CodeView/TypeDatabaseVisitor.h"
-#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
#include "llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h"
#include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
diff --git a/tools/llvm-pdbdump/CompactTypeDumpVisitor.cpp b/tools/llvm-pdbdump/CompactTypeDumpVisitor.cpp
index 5ad0bfad26c1..3b609ae50c1c 100644
--- a/tools/llvm-pdbdump/CompactTypeDumpVisitor.cpp
+++ b/tools/llvm-pdbdump/CompactTypeDumpVisitor.cpp
@@ -29,15 +29,15 @@ static StringRef getLeafName(TypeLeafKind K) {
return StringRef();
}
-CompactTypeDumpVisitor::CompactTypeDumpVisitor(TypeDatabase &TypeDB,
+CompactTypeDumpVisitor::CompactTypeDumpVisitor(TypeCollection &Types,
ScopedPrinter *W)
- : CompactTypeDumpVisitor(TypeDB, TypeIndex(TypeIndex::FirstNonSimpleIndex),
+ : CompactTypeDumpVisitor(Types, TypeIndex(TypeIndex::FirstNonSimpleIndex),
W) {}
-CompactTypeDumpVisitor::CompactTypeDumpVisitor(TypeDatabase &TypeDB,
+CompactTypeDumpVisitor::CompactTypeDumpVisitor(TypeCollection &Types,
TypeIndex FirstTI,
ScopedPrinter *W)
- : W(W), TI(FirstTI), Offset(0), TypeDB(TypeDB) {}
+ : W(W), TI(FirstTI), Offset(0), Types(Types) {}
Error CompactTypeDumpVisitor::visitTypeBegin(CVType &Record) {
return Error::success();
@@ -46,7 +46,7 @@ Error CompactTypeDumpVisitor::visitTypeBegin(CVType &Record) {
Error CompactTypeDumpVisitor::visitTypeEnd(CVType &Record) {
uint32_t I = TI.getIndex();
StringRef Leaf = getLeafName(Record.Type);
- StringRef Name = TypeDB.getTypeName(TI);
+ StringRef Name = Types.getTypeName(TI);
W->printString(
llvm::formatv("Index: {0:x} ({1:N} bytes, offset {2:N}) {3} \"{4}\"", I,
Record.length(), Offset, Leaf, Name)
diff --git a/tools/llvm-pdbdump/CompactTypeDumpVisitor.h b/tools/llvm-pdbdump/CompactTypeDumpVisitor.h
index 76fafc93e030..41ccea0c2e90 100644
--- a/tools/llvm-pdbdump/CompactTypeDumpVisitor.h
+++ b/tools/llvm-pdbdump/CompactTypeDumpVisitor.h
@@ -17,7 +17,7 @@
namespace llvm {
class ScopedPrinter;
namespace codeview {
-class TypeDatabase;
+class TypeCollection;
}
namespace pdb {
@@ -26,8 +26,8 @@ namespace pdb {
/// Dumps records on a single line, and ignores member records.
class CompactTypeDumpVisitor : public codeview::TypeVisitorCallbacks {
public:
- CompactTypeDumpVisitor(codeview::TypeDatabase &TypeDB, ScopedPrinter *W);
- CompactTypeDumpVisitor(codeview::TypeDatabase &TypeDB,
+ CompactTypeDumpVisitor(codeview::TypeCollection &Types, ScopedPrinter *W);
+ CompactTypeDumpVisitor(codeview::TypeCollection &Types,
codeview::TypeIndex FirstTI, ScopedPrinter *W);
/// Paired begin/end actions for all types. Receives all record data,
@@ -40,7 +40,7 @@ private:
codeview::TypeIndex TI;
uint32_t Offset;
- codeview::TypeDatabase &TypeDB;
+ codeview::TypeCollection &Types;
};
} // end namespace pdb
diff --git a/tools/llvm-pdbdump/LLVMOutputStyle.cpp b/tools/llvm-pdbdump/LLVMOutputStyle.cpp
index c4fecb80ea5a..07d3b226d7c6 100644
--- a/tools/llvm-pdbdump/LLVMOutputStyle.cpp
+++ b/tools/llvm-pdbdump/LLVMOutputStyle.cpp
@@ -14,9 +14,9 @@
#include "StreamUtil.h"
#include "llvm-pdbdump.h"
-#include "llvm/DebugInfo/CodeView/CVTypeDumper.h"
#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
#include "llvm/DebugInfo/CodeView/EnumTables.h"
+#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
#include "llvm/DebugInfo/CodeView/Line.h"
#include "llvm/DebugInfo/CodeView/ModuleDebugFileChecksumFragment.h"
#include "llvm/DebugInfo/CodeView/ModuleDebugFragmentVisitor.h"
@@ -25,7 +25,6 @@
#include "llvm/DebugInfo/CodeView/ModuleDebugUnknownFragment.h"
#include "llvm/DebugInfo/CodeView/SymbolDumper.h"
#include "llvm/DebugInfo/CodeView/TypeDatabaseVisitor.h"
-#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
#include "llvm/DebugInfo/CodeView/TypeDumpVisitor.h"
#include "llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h"
#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
@@ -84,7 +83,7 @@ struct PageStats {
class C13RawVisitor : public C13DebugFragmentVisitor {
public:
- C13RawVisitor(ScopedPrinter &P, PDBFile &F, TypeDatabase &IPI)
+ C13RawVisitor(ScopedPrinter &P, PDBFile &F, LazyRandomTypeCollection &IPI)
: C13DebugFragmentVisitor(F), P(P), IPI(IPI) {}
Error handleLines() override {
@@ -160,7 +159,7 @@ public:
if (auto EC = printFileName("FileName", L.Header->FileID))
return EC;
- if (auto EC = dumpTypeRecord("Function", IPI, L.Header->Inlinee))
+ if (auto EC = dumpTypeRecord("Function", L.Header->Inlinee))
return EC;
P.printNumber("SourceLine", L.Header->SourceLineNum);
if (IL.hasExtraFiles()) {
@@ -176,11 +175,11 @@ public:
}
private:
- Error dumpTypeRecord(StringRef Label, TypeDatabase &DB, TypeIndex Index) {
- CompactTypeDumpVisitor CTDV(DB, Index, &P);
+ Error dumpTypeRecord(StringRef Label, TypeIndex Index) {
+ CompactTypeDumpVisitor CTDV(IPI, Index, &P);
DictScope D(P, Label);
- if (DB.contains(Index)) {
- CVType &Type = DB.getTypeRecord(Index);
+ if (IPI.contains(Index)) {
+ CVType Type = IPI.getType(Index);
if (auto EC = codeview::visitTypeRecord(Type, CTDV))
return EC;
} else {
@@ -199,7 +198,7 @@ private:
}
ScopedPrinter &P;
- TypeDatabase &IPI;
+ LazyRandomTypeCollection &IPI;
};
}
@@ -609,14 +608,19 @@ Error LLVMOutputStyle::dumpTpiStream(uint32_t StreamIdx) {
VerLabel = "IPI Version";
}
- if (!DumpRecordBytes && !DumpRecords && !DumpTpiHash)
- return Error::success();
-
auto Tpi = (StreamIdx == StreamTPI) ? File.getPDBTpiStream()
: File.getPDBIpiStream();
if (!Tpi)
return Tpi.takeError();
+ auto ExpectedTypes = initializeTypeDatabase(StreamIdx);
+ if (!ExpectedTypes)
+ return ExpectedTypes.takeError();
+ auto &Types = *ExpectedTypes;
+
+ if (!DumpRecordBytes && !DumpRecords && !DumpTpiHash)
+ return Error::success();
+
std::unique_ptr<DictScope> StreamScope;
std::unique_ptr<ListScope> RecordScope;
@@ -624,25 +628,19 @@ Error LLVMOutputStyle::dumpTpiStream(uint32_t StreamIdx) {
P.printNumber(VerLabel, Tpi->getTpiVersion());
P.printNumber("Record count", Tpi->getNumTypeRecords());
- Optional<TypeDatabase> &StreamDB = (StreamIdx == StreamTPI) ? TypeDB : ItemDB;
-
std::vector<std::unique_ptr<TypeVisitorCallbacks>> Visitors;
- if (!StreamDB.hasValue()) {
- StreamDB.emplace(Tpi->getNumTypeRecords());
- Visitors.push_back(make_unique<TypeDatabaseVisitor>(*StreamDB));
- }
// If we're in dump mode, add a dumper with the appropriate detail level.
if (DumpRecords) {
std::unique_ptr<TypeVisitorCallbacks> Dumper;
if (opts::raw::CompactRecords)
- Dumper = make_unique<CompactTypeDumpVisitor>(*StreamDB, &P);
+ Dumper = make_unique<CompactTypeDumpVisitor>(Types, &P);
else {
- assert(TypeDB.hasValue());
+ assert(TpiTypes);
- auto X = make_unique<TypeDumpVisitor>(*TypeDB, &P, false);
+ auto X = make_unique<TypeDumpVisitor>(*TpiTypes, &P, false);
if (StreamIdx == StreamIPI)
- X->setItemDB(*ItemDB);
+ X->setIpiTypes(*IpiTypes);
Dumper = std::move(X);
}
Visitors.push_back(std::move(Dumper));
@@ -660,23 +658,18 @@ Error LLVMOutputStyle::dumpTpiStream(uint32_t StreamIdx) {
if (DumpRecords || DumpRecordBytes)
RecordScope = llvm::make_unique<ListScope>(P, "Records");
- bool HadError = false;
-
- TypeIndex T(TypeIndex::FirstNonSimpleIndex);
- for (auto Type : Tpi->types(&HadError)) {
+ Optional<TypeIndex> I = Types.getFirst();
+ while (I) {
std::unique_ptr<DictScope> OneRecordScope;
if ((DumpRecords || DumpRecordBytes) && !opts::raw::CompactRecords)
OneRecordScope = llvm::make_unique<DictScope>(P, "");
- if (auto EC = codeview::visitTypeRecord(Type, Pipeline))
+ auto T = Types.getType(*I);
+ if (auto EC = codeview::visitTypeRecord(T, *I, Pipeline))
return EC;
-
- ++T;
+ I = Types.getNext(*I);
}
- if (HadError)
- return make_error<RawError>(raw_error_code::corrupt_file,
- "TPI stream contained corrupt record");
if (DumpTpiHash) {
DictScope DD(P, "Hash");
@@ -711,35 +704,26 @@ Error LLVMOutputStyle::dumpTpiStream(uint32_t StreamIdx) {
return Error::success();
}
-Error LLVMOutputStyle::buildTypeDatabase(uint32_t SN) {
- assert(SN == StreamIPI || SN == StreamTPI);
-
- auto &DB = (SN == StreamIPI) ? ItemDB : TypeDB;
-
- if (DB.hasValue())
- return Error::success();
-
+Expected<codeview::LazyRandomTypeCollection &>
+LLVMOutputStyle::initializeTypeDatabase(uint32_t SN) {
+ auto &TypeCollection = (SN == StreamTPI) ? TpiTypes : IpiTypes;
auto Tpi =
(SN == StreamTPI) ? File.getPDBTpiStream() : File.getPDBIpiStream();
-
if (!Tpi)
return Tpi.takeError();
- DB.emplace(Tpi->getNumTypeRecords());
-
- TypeDatabaseVisitor DBV(*DB);
-
- auto HashValues = Tpi->getHashValues();
- if (HashValues.empty())
- return codeview::visitTypeStream(Tpi->typeArray(), DBV);
-
- TypeVisitorCallbackPipeline Pipeline;
- Pipeline.addCallbackToPipeline(DBV);
-
- TpiHashVerifier HashVerifier(HashValues, Tpi->getNumHashBuckets());
- Pipeline.addCallbackToPipeline(HashVerifier);
+ if (!TypeCollection) {
+ // Initialize the type collection, even if we're not going to dump it. This
+ // way if some other part of the dumper decides it wants to use some or all
+ // of the records for whatever purposes, it can still access them lazily.
+ auto &Types = Tpi->typeArray();
+ uint32_t Count = Tpi->getNumTypeRecords();
+ auto Offsets = Tpi->getTypeIndexOffsets();
+ TypeCollection =
+ llvm::make_unique<LazyRandomTypeCollection>(Types, Count, Offsets);
+ }
- return codeview::visitTypeStream(Tpi->typeArray(), Pipeline);
+ return *TypeCollection;
}
Error LLVMOutputStyle::dumpDbiStream() {
@@ -814,11 +798,13 @@ Error LLVMOutputStyle::dumpDbiStream() {
return EC;
if (ShouldDumpSymbols) {
- if (auto EC = buildTypeDatabase(StreamTPI))
- return EC;
+ auto ExpectedTypes = initializeTypeDatabase(StreamTPI);
+ if (!ExpectedTypes)
+ return ExpectedTypes.takeError();
+ auto &Types = *ExpectedTypes;
ListScope SS(P, "Symbols");
- codeview::CVSymbolDumper SD(P, *TypeDB, nullptr, false);
+ codeview::CVSymbolDumper SD(P, Types, nullptr, false);
bool HadError = false;
for (auto S : ModS.symbols(&HadError)) {
DictScope LL(P, "");
@@ -839,10 +825,11 @@ Error LLVMOutputStyle::dumpDbiStream() {
}
if (opts::raw::DumpLineInfo) {
ListScope SS(P, "LineInfo");
- if (auto EC = buildTypeDatabase(StreamIPI))
- return EC;
-
- C13RawVisitor V(P, File, *ItemDB);
+ auto ExpectedTypes = initializeTypeDatabase(StreamIPI);
+ if (!ExpectedTypes)
+ return ExpectedTypes.takeError();
+ auto &IpiItems = *ExpectedTypes;
+ C13RawVisitor V(P, File, IpiItems);
if (auto EC = codeview::visitModuleDebugFragments(
ModS.linesAndChecksums(), V))
return EC;
@@ -960,10 +947,12 @@ Error LLVMOutputStyle::dumpPublicsStream() {
P.printList("Section Offsets", Publics->getSectionOffsets(),
printSectionOffset);
ListScope L(P, "Symbols");
- if (auto EC = buildTypeDatabase(StreamTPI))
- return EC;
+ auto ExpectedTypes = initializeTypeDatabase(StreamTPI);
+ if (!ExpectedTypes)
+ return ExpectedTypes.takeError();
+ auto &Tpi = *ExpectedTypes;
- codeview::CVSymbolDumper SD(P, *TypeDB, nullptr, false);
+ codeview::CVSymbolDumper SD(P, Tpi, nullptr, false);
bool HadError = false;
for (auto S : Publics->getSymbols(&HadError)) {
DictScope DD(P, "");
diff --git a/tools/llvm-pdbdump/LLVMOutputStyle.h b/tools/llvm-pdbdump/LLVMOutputStyle.h
index b0e7e3406b36..184dc4e1f44d 100644
--- a/tools/llvm-pdbdump/LLVMOutputStyle.h
+++ b/tools/llvm-pdbdump/LLVMOutputStyle.h
@@ -21,6 +21,11 @@
namespace llvm {
class BitVector;
+
+namespace codeview {
+class LazyRandomTypeCollection;
+}
+
namespace pdb {
class LLVMOutputStyle : public OutputStyle {
public:
@@ -29,7 +34,8 @@ public:
Error dump() override;
private:
- Error buildTypeDatabase(uint32_t SN);
+ Expected<codeview::LazyRandomTypeCollection &>
+ initializeTypeDatabase(uint32_t SN);
Error dumpFileHeaders();
Error dumpStreamSummary();
@@ -54,8 +60,8 @@ private:
PDBFile &File;
ScopedPrinter P;
- Optional<codeview::TypeDatabase> TypeDB;
- Optional<codeview::TypeDatabase> ItemDB;
+ std::unique_ptr<codeview::LazyRandomTypeCollection> TpiTypes;
+ std::unique_ptr<codeview::LazyRandomTypeCollection> IpiTypes;
SmallVector<std::string, 32> StreamPurposes;
};
}
diff --git a/tools/llvm-pdbdump/PdbYaml.cpp b/tools/llvm-pdbdump/PdbYaml.cpp
index 6527bec31a77..dd32eca14c1d 100644
--- a/tools/llvm-pdbdump/PdbYaml.cpp
+++ b/tools/llvm-pdbdump/PdbYaml.cpp
@@ -19,7 +19,6 @@
#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
#include "llvm/DebugInfo/CodeView/SymbolSerializer.h"
#include "llvm/DebugInfo/CodeView/SymbolVisitorCallbackPipeline.h"
-#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
#include "llvm/DebugInfo/CodeView/TypeSerializer.h"
#include "llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h"
#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
@@ -371,7 +370,6 @@ void MappingContextTraits<PdbInlineeInfo, SerializationContext>::mapping(
void MappingContextTraits<PdbTpiRecord, pdb::yaml::SerializationContext>::
mapping(IO &IO, pdb::yaml::PdbTpiRecord &Obj,
pdb::yaml::SerializationContext &Context) {
-
if (IO.outputting()) {
// For PDB to Yaml, deserialize into a high level record type, then dump it.
consumeError(codeview::visitTypeRecord(Obj.Record, Context.Dumper));
diff --git a/tools/llvm-pdbdump/YAMLOutputStyle.h b/tools/llvm-pdbdump/YAMLOutputStyle.h
index 517c7d86d7ab..068312aec450 100644
--- a/tools/llvm-pdbdump/YAMLOutputStyle.h
+++ b/tools/llvm-pdbdump/YAMLOutputStyle.h
@@ -13,7 +13,6 @@
#include "OutputStyle.h"
#include "PdbYaml.h"
-#include "llvm/DebugInfo/CodeView/CVTypeDumper.h"
#include "llvm/Support/ScopedPrinter.h"
#include "llvm/Support/YAMLTraits.h"
diff --git a/tools/llvm-pdbdump/YamlTypeDumper.cpp b/tools/llvm-pdbdump/YamlTypeDumper.cpp
index 3e447ca60b61..beb700720954 100644
--- a/tools/llvm-pdbdump/YamlTypeDumper.cpp
+++ b/tools/llvm-pdbdump/YamlTypeDumper.cpp
@@ -13,7 +13,6 @@
#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
#include "llvm/DebugInfo/CodeView/EnumTables.h"
-#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
#include "llvm/DebugInfo/CodeView/TypeSerializer.h"
#include "llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h"
diff --git a/tools/llvm-pdbdump/llvm-pdbdump.cpp b/tools/llvm-pdbdump/llvm-pdbdump.cpp
index 0e5913fa3c93..1767c3cfda85 100644
--- a/tools/llvm-pdbdump/llvm-pdbdump.cpp
+++ b/tools/llvm-pdbdump/llvm-pdbdump.cpp
@@ -31,9 +31,12 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Config/config.h"
+#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
#include "llvm/DebugInfo/CodeView/ModuleDebugFileChecksumFragment.h"
#include "llvm/DebugInfo/CodeView/ModuleDebugInlineeLinesFragment.h"
#include "llvm/DebugInfo/CodeView/ModuleDebugLineFragment.h"
+#include "llvm/DebugInfo/CodeView/TypeStreamMerger.h"
+#include "llvm/DebugInfo/CodeView/TypeTableBuilder.h"
#include "llvm/DebugInfo/MSF/MSFBuilder.h"
#include "llvm/DebugInfo/PDB/GenericError.h"
#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
@@ -67,6 +70,7 @@
#include "llvm/Support/Format.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Path.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/Process.h"
#include "llvm/Support/Regex.h"
@@ -99,6 +103,9 @@ cl::SubCommand
AnalyzeSubcommand("analyze",
"Analyze various aspects of a PDB's structure");
+cl::SubCommand MergeSubcommand("merge",
+ "Merge multiple PDBs into a single PDB");
+
cl::OptionCategory TypeCategory("Symbol Type Options");
cl::OptionCategory FilterCategory("Filtering and Sorting Options");
cl::OptionCategory OtherOptions("Other Options");
@@ -365,9 +372,9 @@ cl::opt<std::string>
YamlPdbOutputFile("pdb", cl::desc("the name of the PDB file to write"),
cl::sub(YamlToPdbSubcommand));
-cl::list<std::string> InputFilename(cl::Positional,
- cl::desc("<input YAML file>"), cl::Required,
- cl::sub(YamlToPdbSubcommand));
+cl::opt<std::string> InputFilename(cl::Positional,
+ cl::desc("<input YAML file>"), cl::Required,
+ cl::sub(YamlToPdbSubcommand));
}
namespace pdb2yaml {
@@ -440,6 +447,15 @@ cl::list<std::string> InputFilename(cl::Positional,
cl::desc("<input PDB file>"), cl::Required,
cl::sub(AnalyzeSubcommand));
}
+
+namespace merge {
+cl::list<std::string> InputFilenames(cl::Positional,
+ cl::desc("<input PDB files>"),
+ cl::OneOrMore, cl::sub(MergeSubcommand));
+cl::opt<std::string>
+ PdbOutputFile("pdb", cl::desc("the name of the PDB file to write"),
+ cl::sub(MergeSubcommand));
+}
}
static ExitOnError ExitOnErr;
@@ -827,6 +843,57 @@ static void dumpPretty(StringRef Path) {
outs().flush();
}
+static void mergePdbs() {
+ BumpPtrAllocator Allocator;
+ TypeTableBuilder MergedTpi(Allocator);
+ TypeTableBuilder MergedIpi(Allocator);
+
+ // Create a Tpi and Ipi type table with all types from all input files.
+ for (const auto &Path : opts::merge::InputFilenames) {
+ std::unique_ptr<IPDBSession> Session;
+ auto &File = loadPDB(Path, Session);
+ SmallVector<TypeIndex, 128> SourceToDest;
+ if (File.hasPDBTpiStream()) {
+ SourceToDest.clear();
+ auto &Tpi = ExitOnErr(File.getPDBTpiStream());
+ ExitOnErr(codeview::mergeTypeStreams(MergedIpi, MergedTpi, SourceToDest,
+ nullptr, Tpi.typeArray()));
+ }
+ if (File.hasPDBIpiStream()) {
+ SourceToDest.clear();
+ auto &Ipi = ExitOnErr(File.getPDBIpiStream());
+ ExitOnErr(codeview::mergeTypeStreams(MergedIpi, MergedTpi, SourceToDest,
+ nullptr, Ipi.typeArray()));
+ }
+ }
+
+ // Then write the PDB.
+ PDBFileBuilder Builder(Allocator);
+ ExitOnErr(Builder.initialize(4096));
+ // Add each of the reserved streams. We might not put any data in them,
+ // but at least they have to be present.
+ for (uint32_t I = 0; I < kSpecialStreamCount; ++I)
+ ExitOnErr(Builder.getMsfBuilder().addStream(0));
+
+ auto &DestTpi = Builder.getTpiBuilder();
+ auto &DestIpi = Builder.getIpiBuilder();
+ MergedTpi.ForEachRecord(
+ [&DestTpi](TypeIndex TI, MutableArrayRef<uint8_t> Data) {
+ DestTpi.addTypeRecord(Data, None);
+ });
+ MergedIpi.ForEachRecord(
+ [&DestIpi](TypeIndex TI, MutableArrayRef<uint8_t> Data) {
+ DestIpi.addTypeRecord(Data, None);
+ });
+
+ SmallString<64> OutFile(opts::merge::PdbOutputFile);
+ if (OutFile.empty()) {
+ OutFile = opts::merge::InputFilenames[0];
+ llvm::sys::path::replace_extension(OutFile, "merged.pdb");
+ }
+ ExitOnErr(Builder.commit(OutFile));
+}
+
int main(int argc_, const char *argv_[]) {
// Print a stack trace if we signal out.
sys::PrintStackTraceOnErrorSignal(argv_[0]);
@@ -894,7 +961,12 @@ int main(int argc_, const char *argv_[]) {
if (opts::PdbToYamlSubcommand) {
pdb2Yaml(opts::pdb2yaml::InputFilename.front());
} else if (opts::YamlToPdbSubcommand) {
- yamlToPdb(opts::yaml2pdb::InputFilename.front());
+ if (opts::yaml2pdb::YamlPdbOutputFile.empty()) {
+ SmallString<16> OutputFilename(opts::yaml2pdb::InputFilename.getValue());
+ sys::path::replace_extension(OutputFilename, ".pdb");
+ opts::yaml2pdb::YamlPdbOutputFile = OutputFilename.str();
+ }
+ yamlToPdb(opts::yaml2pdb::InputFilename);
} else if (opts::AnalyzeSubcommand) {
dumpAnalysis(opts::analyze::InputFilename.front());
} else if (opts::PrettySubcommand) {
@@ -943,6 +1015,12 @@ int main(int argc_, const char *argv_[]) {
exit(1);
}
diff(opts::diff::InputFilenames[0], opts::diff::InputFilenames[1]);
+ } else if (opts::MergeSubcommand) {
+ if (opts::merge::InputFilenames.size() < 2) {
+ errs() << "merge subcommand requires at least 2 input files.\n";
+ exit(1);
+ }
+ mergePdbs();
}
outs().flush();
diff --git a/tools/llvm-readobj/COFFDumper.cpp b/tools/llvm-readobj/COFFDumper.cpp
index aca7de840d80..78bfa558e4a3 100644
--- a/tools/llvm-readobj/COFFDumper.cpp
+++ b/tools/llvm-readobj/COFFDumper.cpp
@@ -22,8 +22,9 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
-#include "llvm/DebugInfo/CodeView/CVTypeDumper.h"
+#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
#include "llvm/DebugInfo/CodeView/Line.h"
#include "llvm/DebugInfo/CodeView/ModuleDebugFileChecksumFragment.h"
#include "llvm/DebugInfo/CodeView/ModuleDebugInlineeLinesFragment.h"
@@ -34,19 +35,20 @@
#include "llvm/DebugInfo/CodeView/SymbolDumpDelegate.h"
#include "llvm/DebugInfo/CodeView/SymbolDumper.h"
#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
+#include "llvm/DebugInfo/CodeView/TypeDatabase.h"
#include "llvm/DebugInfo/CodeView/TypeDumpVisitor.h"
#include "llvm/DebugInfo/CodeView/TypeIndex.h"
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
#include "llvm/DebugInfo/CodeView/TypeStreamMerger.h"
#include "llvm/DebugInfo/CodeView/TypeTableBuilder.h"
+#include "llvm/DebugInfo/CodeView/TypeTableCollection.h"
#include "llvm/Object/COFF.h"
#include "llvm/Object/ObjectFile.h"
-#include "llvm/Support/BinaryByteStream.h"
#include "llvm/Support/BinaryStreamReader.h"
#include "llvm/Support/COFF.h"
-#include "llvm/Support/ConvertUTF.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h"
+#include "llvm/Support/ConvertUTF.h"
#include "llvm/Support/DataExtractor.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/Path.h"
@@ -71,7 +73,7 @@ class COFFDumper : public ObjDumper {
public:
friend class COFFObjectDumpDelegate;
COFFDumper(const llvm::object::COFFObjectFile *Obj, ScopedPrinter &Writer)
- : ObjDumper(Writer), Obj(Obj), Writer(Writer), TypeDB(100) {}
+ : ObjDumper(Writer), Obj(Obj), Writer(Writer), Types(100) {}
void printFileHeaders() override;
void printSections() override;
@@ -107,7 +109,7 @@ private:
void printFileNameForOffset(StringRef Label, uint32_t FileOffset);
void printTypeIndex(StringRef FieldName, TypeIndex TI) {
// Forward to CVTypeDumper for simplicity.
- CVTypeDumper::printTypeIndex(Writer, FieldName, TI, TypeDB);
+ codeview::printTypeIndex(Writer, FieldName, TI, Types);
}
void printCodeViewSymbolsSubsection(StringRef Subsection,
@@ -155,14 +157,13 @@ private:
bool RelocCached = false;
RelocMapTy RelocMap;
- BinaryByteStream ChecksumContents;
VarStreamArray<FileChecksumEntry> CVFileChecksumTable;
- BinaryByteStream StringTableContents;
StringTableRef CVStringTable;
ScopedPrinter &Writer;
- TypeDatabase TypeDB;
+ BinaryByteStream TypeContents;
+ LazyRandomTypeCollection Types;
};
class COFFObjectDumpDelegate : public SymbolDumpDelegate {
@@ -775,14 +776,13 @@ void COFFDumper::initializeFileAndStringTables(BinaryStreamReader &Reader) {
switch (ModuleDebugFragmentKind(SubType)) {
case ModuleDebugFragmentKind::FileChecksums: {
- ChecksumContents = BinaryByteStream(Contents, support::little);
- BinaryStreamReader CSR(ChecksumContents);
+ BinaryStreamReader CSR(Contents, support::little);
error(CSR.readArray(CVFileChecksumTable, CSR.getLength()));
break;
}
case ModuleDebugFragmentKind::StringTable: {
- StringTableContents = BinaryByteStream(Contents, support::little);
- error(CVStringTable.initialize(StringTableContents));
+ BinaryStreamRef ST(Contents, support::little);
+ error(CVStringTable.initialize(ST));
} break;
default:
break;
@@ -812,8 +812,7 @@ void COFFDumper::printCodeViewSymbolSection(StringRef SectionName,
if (Magic != COFF::DEBUG_SECTION_MAGIC)
return error(object_error::parse_failed);
- BinaryByteStream FileAndStrings(Data, support::little);
- BinaryStreamReader FSReader(FileAndStrings);
+ BinaryStreamReader FSReader(Data, support::little);
initializeFileAndStringTables(FSReader);
// TODO: Convert this over to using ModuleSubstreamVisitor.
@@ -889,8 +888,7 @@ void COFFDumper::printCodeViewSymbolSection(StringRef SectionName,
}
case ModuleDebugFragmentKind::FrameData: {
// First four bytes is a relocation against the function.
- BinaryByteStream S(Contents, llvm::support::little);
- BinaryStreamReader SR(S);
+ BinaryStreamReader SR(Contents, llvm::support::little);
const uint32_t *CodePtr;
error(SR.readObject(CodePtr));
StringRef LinkageName;
@@ -934,8 +932,7 @@ void COFFDumper::printCodeViewSymbolSection(StringRef SectionName,
ListScope S(W, "FunctionLineTable");
W.printString("LinkageName", Name);
- BinaryByteStream LineTableInfo(FunctionLineTables[Name], support::little);
- BinaryStreamReader Reader(LineTableInfo);
+ BinaryStreamReader Reader(FunctionLineTables[Name], support::little);
ModuleDebugLineFragmentRef LineInfo;
error(LineInfo.initialize(Reader));
@@ -982,12 +979,9 @@ void COFFDumper::printCodeViewSymbolsSubsection(StringRef Subsection,
Subsection.bytes_end());
auto CODD = llvm::make_unique<COFFObjectDumpDelegate>(*this, Section, Obj,
SectionContents);
-
- CVSymbolDumper CVSD(W, TypeDB, std::move(CODD),
- opts::CodeViewSubsectionBytes);
- BinaryByteStream Stream(BinaryData, llvm::support::little);
+ CVSymbolDumper CVSD(W, Types, std::move(CODD), opts::CodeViewSubsectionBytes);
CVSymbolArray Symbols;
- BinaryStreamReader Reader(Stream);
+ BinaryStreamReader Reader(BinaryData, llvm::support::little);
if (auto EC = Reader.readArray(Symbols, Reader.getLength())) {
consumeError(std::move(EC));
W.flush();
@@ -1002,8 +996,7 @@ void COFFDumper::printCodeViewSymbolsSubsection(StringRef Subsection,
}
void COFFDumper::printCodeViewFileChecksums(StringRef Subsection) {
- BinaryByteStream S(Subsection, llvm::support::little);
- BinaryStreamReader SR(S);
+ BinaryStreamReader SR(Subsection, llvm::support::little);
ModuleDebugFileChecksumFragmentRef Checksums;
error(Checksums.initialize(SR));
@@ -1021,8 +1014,7 @@ void COFFDumper::printCodeViewFileChecksums(StringRef Subsection) {
}
void COFFDumper::printCodeViewInlineeLines(StringRef Subsection) {
- BinaryByteStream S(Subsection, llvm::support::little);
- BinaryStreamReader SR(S);
+ BinaryStreamReader SR(Subsection, llvm::support::little);
ModuleDebugInlineeLineFragmentRef Lines;
error(Lines.initialize(SR));
@@ -1072,18 +1064,17 @@ void COFFDumper::mergeCodeViewTypes(TypeTableBuilder &CVIDs,
error(consume(Data, Magic));
if (Magic != 4)
error(object_error::parse_failed);
- ArrayRef<uint8_t> Bytes(reinterpret_cast<const uint8_t *>(Data.data()),
- Data.size());
- BinaryByteStream Stream(Bytes, llvm::support::little);
+
CVTypeArray Types;
- BinaryStreamReader Reader(Stream);
+ BinaryStreamReader Reader(Data, llvm::support::little);
if (auto EC = Reader.readArray(Types, Reader.getLength())) {
consumeError(std::move(EC));
W.flush();
error(object_error::parse_failed);
}
-
- if (auto EC = mergeTypeStreams(CVIDs, CVTypes, nullptr, Types))
+ SmallVector<TypeIndex, 128> SourceToDest;
+ if (auto EC =
+ mergeTypeStreams(CVIDs, CVTypes, SourceToDest, nullptr, Types))
return error(std::move(EC));
}
}
@@ -1105,12 +1096,11 @@ void COFFDumper::printCodeViewTypeSection(StringRef SectionName,
if (Magic != COFF::DEBUG_SECTION_MAGIC)
return error(object_error::parse_failed);
- CVTypeDumper CVTD(TypeDB);
- TypeDumpVisitor TDV(TypeDB, &W, opts::CodeViewSubsectionBytes);
- if (auto EC = CVTD.dump({Data.bytes_begin(), Data.bytes_end()}, TDV)) {
- W.flush();
- error(llvm::errorToErrorCode(std::move(EC)));
- }
+ Types.reset(Data);
+
+ TypeDumpVisitor TDV(Types, &W, opts::CodeViewSubsectionBytes);
+ error(codeview::visitTypeStream(Types, TDV));
+ W.flush();
}
void COFFDumper::printSections() {
@@ -1650,35 +1640,22 @@ void llvm::dumpCodeViewMergedTypes(ScopedPrinter &Writer,
TypeBuf.append(Record.begin(), Record.end());
});
- TypeDatabase TypeDB(CVTypes.records().size());
+ TypeTableCollection TpiTypes(CVTypes.records());
{
ListScope S(Writer, "MergedTypeStream");
- CVTypeDumper CVTD(TypeDB);
- TypeDumpVisitor TDV(TypeDB, &Writer, opts::CodeViewSubsectionBytes);
- if (auto EC = CVTD.dump(
- {TypeBuf.str().bytes_begin(), TypeBuf.str().bytes_end()}, TDV)) {
- Writer.flush();
- error(std::move(EC));
- }
+ TypeDumpVisitor TDV(TpiTypes, &Writer, opts::CodeViewSubsectionBytes);
+ error(codeview::visitTypeStream(TpiTypes, TDV));
+ Writer.flush();
}
// Flatten the id stream and print it next. The ID stream refers to names from
// the type stream.
- SmallString<0> IDBuf;
- IDTable.ForEachRecord([&](TypeIndex TI, ArrayRef<uint8_t> Record) {
- IDBuf.append(Record.begin(), Record.end());
- });
-
+ TypeTableCollection IpiTypes(IDTable.records());
{
ListScope S(Writer, "MergedIDStream");
- TypeDatabase IDDB(IDTable.records().size());
- CVTypeDumper CVTD(IDDB);
- TypeDumpVisitor TDV(TypeDB, &Writer, opts::CodeViewSubsectionBytes);
- TDV.setItemDB(IDDB);
- if (auto EC = CVTD.dump(
- {IDBuf.str().bytes_begin(), IDBuf.str().bytes_end()}, TDV)) {
- Writer.flush();
- error(std::move(EC));
- }
+ TypeDumpVisitor TDV(TpiTypes, &Writer, opts::CodeViewSubsectionBytes);
+ TDV.setIpiTypes(IpiTypes);
+ error(codeview::visitTypeStream(IpiTypes, TDV));
+ Writer.flush();
}
}
diff --git a/tools/opt/opt.cpp b/tools/opt/opt.cpp
index c362dff3a3e0..bef197d603ca 100644
--- a/tools/opt/opt.cpp
+++ b/tools/opt/opt.cpp
@@ -24,6 +24,7 @@
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/Bitcode/BitcodeWriterPass.h"
#include "llvm/CodeGen/CommandFlags.h"
+#include "llvm/CodeGen/TargetPassConfig.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/IRPrintingPasses.h"
@@ -579,6 +580,13 @@ int main(int argc, char **argv) {
NoOutput = true;
}
+ if (TM) {
+ // FIXME: We should dyn_cast this when supported.
+ auto &LTM = static_cast<LLVMTargetMachine &>(*TM);
+ Pass *TPC = LTM.createPassConfig(Passes);
+ Passes.add(TPC);
+ }
+
// Create a new optimization pass for each one specified on the command line
for (unsigned i = 0; i < PassList.size(); ++i) {
if (StandardLinkOpts &&
@@ -619,9 +627,7 @@ int main(int argc, char **argv) {
const PassInfo *PassInf = PassList[i];
Pass *P = nullptr;
- if (PassInf->getTargetMachineCtor())
- P = PassInf->getTargetMachineCtor()(TM.get());
- else if (PassInf->getNormalCtor())
+ if (PassInf->getNormalCtor())
P = PassInf->getNormalCtor()();
else
errs() << argv[0] << ": cannot create pass: "