Provide DIA implementation of DebugInfoPDB.
[oota-llvm.git] / lib / DebugInfo / PDB / DIA / DIASession.cpp
1 //===- DIASession.cpp - DIA implementation of IPDBSession -------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "llvm/DebugInfo/PDB/DIA/DIAEnumDebugStreams.h"
11 #include "llvm/DebugInfo/PDB/DIA/DIARawSymbol.h"
12 #include "llvm/DebugInfo/PDB/DIA/DIASession.h"
13 #include "llvm/DebugInfo/PDB/DIA/DIASourceFile.h"
14 #include "llvm/DebugInfo/PDB/PDBSymbolExe.h"
15 #include "llvm/Support/ConvertUTF.h"
16
17 using namespace llvm;
18
19 namespace {}
20
21 DIASession::DIASession(CComPtr<IDiaSession> DiaSession) : Session(DiaSession) {}
22
23 DIASession *DIASession::createFromPdb(StringRef Path) {
24   CComPtr<IDiaDataSource> DataSource;
25   CComPtr<IDiaSession> Session;
26
27   // We assume that CoInitializeEx has already been called by the executable.
28   HRESULT Result = ::CoCreateInstance(CLSID_DiaSource, nullptr,
29                                       CLSCTX_INPROC_SERVER, IID_IDiaDataSource,
30                                       reinterpret_cast<LPVOID *>(&DataSource));
31   if (FAILED(Result))
32     return nullptr;
33
34   llvm::SmallVector<UTF16, 128> Path16;
35   if (!llvm::convertUTF8ToUTF16String(Path, Path16))
36     return nullptr;
37
38   const wchar_t *Path16Str = reinterpret_cast<const wchar_t*>(Path16.data());
39   if (FAILED(DataSource->loadDataFromPdb(Path16Str)))
40     return nullptr;
41
42   if (FAILED(DataSource->openSession(&Session)))
43     return nullptr;
44   return new DIASession(Session);
45 }
46
47 uint64_t DIASession::getLoadAddress() const {
48   uint64_t LoadAddress;
49   bool success = (S_OK == Session->get_loadAddress(&LoadAddress));
50   return (success) ? LoadAddress : 0;
51 }
52
53 void DIASession::setLoadAddress(uint64_t Address) {
54   Session->put_loadAddress(Address);
55 }
56
57 std::unique_ptr<PDBSymbolExe> DIASession::getGlobalScope() const {
58   CComPtr<IDiaSymbol> GlobalScope;
59   if (S_OK != Session->get_globalScope(&GlobalScope))
60     return nullptr;
61
62   auto RawSymbol = std::make_unique<DIARawSymbol>(*this, GlobalScope);
63   auto PdbSymbol(PDBSymbol::create(*this, std::move(RawSymbol)));
64   std::unique_ptr<PDBSymbolExe> ExeSymbol(
65       static_cast<PDBSymbolExe *>(PdbSymbol.release()));
66   return ExeSymbol;
67 }
68
69 std::unique_ptr<PDBSymbol> DIASession::getSymbolById(uint32_t SymbolId) const {
70   CComPtr<IDiaSymbol> LocatedSymbol;
71   if (S_OK != Session->symbolById(SymbolId, &LocatedSymbol))
72     return nullptr;
73
74   auto RawSymbol = std::make_unique<DIARawSymbol>(*this, LocatedSymbol);
75   return PDBSymbol::create(*this, std::move(RawSymbol));
76 }
77
78 std::unique_ptr<IPDBSourceFile>
79 DIASession::getSourceFileById(uint32_t FileId) const {
80   CComPtr<IDiaSourceFile> LocatedFile;
81   if (S_OK != Session->findFileById(FileId, &LocatedFile))
82     return nullptr;
83
84   return std::make_unique<DIASourceFile>(*this, LocatedFile);
85 }
86
87 std::unique_ptr<IPDBEnumDataStreams> DIASession::getDebugStreams() const {
88   CComPtr<IDiaEnumDebugStreams> DiaEnumerator;
89   if (S_OK != Session->getEnumDebugStreams(&DiaEnumerator))
90     return nullptr;
91
92   return std::unique_ptr<IPDBEnumDataStreams>(
93       new DIAEnumDebugStreams(DiaEnumerator));
94 }