PDBSymbol.cpp revision 344779
10SN/A//===- PDBSymbol.cpp - base class for user-facing symbol types --*- C++ -*-===//
22362SN/A//
30SN/A//                     The LLVM Compiler Infrastructure
40SN/A//
50SN/A// This file is distributed under the University of Illinois Open Source
60SN/A// License. See LICENSE.TXT for details.
72362SN/A//
80SN/A//===----------------------------------------------------------------------===//
92362SN/A
100SN/A#include "llvm/DebugInfo/PDB/PDBSymbol.h"
110SN/A#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
120SN/A#include "llvm/DebugInfo/PDB/IPDBRawSymbol.h"
130SN/A#include "llvm/DebugInfo/PDB/IPDBSession.h"
140SN/A#include "llvm/DebugInfo/PDB/PDBExtras.h"
150SN/A#include "llvm/DebugInfo/PDB/PDBSymbolAnnotation.h"
160SN/A#include "llvm/DebugInfo/PDB/PDBSymbolBlock.h"
170SN/A#include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h"
180SN/A#include "llvm/DebugInfo/PDB/PDBSymbolCompilandDetails.h"
190SN/A#include "llvm/DebugInfo/PDB/PDBSymbolCompilandEnv.h"
200SN/A#include "llvm/DebugInfo/PDB/PDBSymbolCustom.h"
212362SN/A#include "llvm/DebugInfo/PDB/PDBSymbolData.h"
222362SN/A#include "llvm/DebugInfo/PDB/PDBSymbolExe.h"
232362SN/A#include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"
240SN/A#include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugEnd.h"
250SN/A#include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugStart.h"
260SN/A#include "llvm/DebugInfo/PDB/PDBSymbolLabel.h"
270SN/A#include "llvm/DebugInfo/PDB/PDBSymbolPublicSymbol.h"
280SN/A#include "llvm/DebugInfo/PDB/PDBSymbolThunk.h"
290SN/A#include "llvm/DebugInfo/PDB/PDBSymbolTypeArray.h"
300SN/A#include "llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h"
310SN/A#include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h"
320SN/A#include "llvm/DebugInfo/PDB/PDBSymbolTypeCustom.h"
330SN/A#include "llvm/DebugInfo/PDB/PDBSymbolTypeDimension.h"
340SN/A#include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h"
3513629Savstepan#include "llvm/DebugInfo/PDB/PDBSymbolTypeFriend.h"
3613629Savstepan#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionArg.h"
3713629Savstepan#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h"
380SN/A#include "llvm/DebugInfo/PDB/PDBSymbolTypeManaged.h"
390SN/A#include "llvm/DebugInfo/PDB/PDBSymbolTypePointer.h"
400SN/A#include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h"
4113629Savstepan#include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"
420SN/A#include "llvm/DebugInfo/PDB/PDBSymbolTypeVTable.h"
430SN/A#include "llvm/DebugInfo/PDB/PDBSymbolTypeVTableShape.h"
440SN/A#include "llvm/DebugInfo/PDB/PDBSymbolUnknown.h"
450SN/A#include "llvm/DebugInfo/PDB/PDBSymbolUsingNamespace.h"
460SN/A#include "llvm/DebugInfo/PDB/PDBTypes.h"
470SN/A#include <algorithm>
480SN/A#include <memory>
4913629Savstepan
500SN/Ausing namespace llvm;
510SN/Ausing namespace llvm::pdb;
520SN/A
530SN/APDBSymbol::PDBSymbol(const IPDBSession &PDBSession) : Session(PDBSession) {}
5413629Savstepan
5513629SavstepanPDBSymbol::PDBSymbol(PDBSymbol &&Other)
560SN/A    : Session(Other.Session), RawSymbol(std::move(Other.RawSymbol)) {}
570SN/A
580SN/APDBSymbol::~PDBSymbol() = default;
590SN/A
600SN/A#define FACTORY_SYMTAG_CASE(Tag, Type)                                         \
619458SN/A  case PDB_SymType::Tag:                                                       \
620SN/A    return std::unique_ptr<PDBSymbol>(new Type(PDBSession));
630SN/A
640SN/Astd::unique_ptr<PDBSymbol>
650SN/APDBSymbol::createSymbol(const IPDBSession &PDBSession, PDB_SymType Tag) {
660SN/A  switch (Tag) {
670SN/A    FACTORY_SYMTAG_CASE(Exe, PDBSymbolExe)
680SN/A    FACTORY_SYMTAG_CASE(Compiland, PDBSymbolCompiland)
690SN/A    FACTORY_SYMTAG_CASE(CompilandDetails, PDBSymbolCompilandDetails)
700SN/A    FACTORY_SYMTAG_CASE(CompilandEnv, PDBSymbolCompilandEnv)
710SN/A    FACTORY_SYMTAG_CASE(Function, PDBSymbolFunc)
720SN/A    FACTORY_SYMTAG_CASE(Block, PDBSymbolBlock)
730SN/A    FACTORY_SYMTAG_CASE(Data, PDBSymbolData)
740SN/A    FACTORY_SYMTAG_CASE(Annotation, PDBSymbolAnnotation)
750SN/A    FACTORY_SYMTAG_CASE(Label, PDBSymbolLabel)
760SN/A    FACTORY_SYMTAG_CASE(PublicSymbol, PDBSymbolPublicSymbol)
779458SN/A    FACTORY_SYMTAG_CASE(UDT, PDBSymbolTypeUDT)
780SN/A    FACTORY_SYMTAG_CASE(Enum, PDBSymbolTypeEnum)
790SN/A    FACTORY_SYMTAG_CASE(FunctionSig, PDBSymbolTypeFunctionSig)
800SN/A    FACTORY_SYMTAG_CASE(PointerType, PDBSymbolTypePointer)
8113629Savstepan    FACTORY_SYMTAG_CASE(ArrayType, PDBSymbolTypeArray)
820SN/A    FACTORY_SYMTAG_CASE(BuiltinType, PDBSymbolTypeBuiltin)
8313629Savstepan    FACTORY_SYMTAG_CASE(Typedef, PDBSymbolTypeTypedef)
840SN/A    FACTORY_SYMTAG_CASE(BaseClass, PDBSymbolTypeBaseClass)
8510735Syan    FACTORY_SYMTAG_CASE(Friend, PDBSymbolTypeFriend)
8610735Syan    FACTORY_SYMTAG_CASE(FunctionArg, PDBSymbolTypeFunctionArg)
870SN/A    FACTORY_SYMTAG_CASE(FuncDebugStart, PDBSymbolFuncDebugStart)
880SN/A    FACTORY_SYMTAG_CASE(FuncDebugEnd, PDBSymbolFuncDebugEnd)
890SN/A    FACTORY_SYMTAG_CASE(UsingNamespace, PDBSymbolUsingNamespace)
900SN/A    FACTORY_SYMTAG_CASE(VTableShape, PDBSymbolTypeVTableShape)
910SN/A    FACTORY_SYMTAG_CASE(VTable, PDBSymbolTypeVTable)
920SN/A    FACTORY_SYMTAG_CASE(Custom, PDBSymbolCustom)
930SN/A    FACTORY_SYMTAG_CASE(Thunk, PDBSymbolThunk)
940SN/A    FACTORY_SYMTAG_CASE(CustomType, PDBSymbolTypeCustom)
950SN/A    FACTORY_SYMTAG_CASE(ManagedType, PDBSymbolTypeManaged)
960SN/A    FACTORY_SYMTAG_CASE(Dimension, PDBSymbolTypeDimension)
970SN/A  default:
980SN/A    return std::unique_ptr<PDBSymbol>(new PDBSymbolUnknown(PDBSession));
990SN/A  }
1000SN/A}
1010SN/A
1020SN/Astd::unique_ptr<PDBSymbol>
1030SN/APDBSymbol::create(const IPDBSession &PDBSession,
1040SN/A                  std::unique_ptr<IPDBRawSymbol> RawSymbol) {
1050SN/A  auto SymbolPtr = createSymbol(PDBSession, RawSymbol->getSymTag());
1060SN/A  SymbolPtr->RawSymbol = RawSymbol.get();
1070SN/A  SymbolPtr->OwnedRawSymbol = std::move(RawSymbol);
1080SN/A  return SymbolPtr;
1090SN/A}
1100SN/A
1110SN/Astd::unique_ptr<PDBSymbol> PDBSymbol::create(const IPDBSession &PDBSession,
1120SN/A                                             IPDBRawSymbol &RawSymbol) {
1130SN/A  auto SymbolPtr = createSymbol(PDBSession, RawSymbol.getSymTag());
1140SN/A  SymbolPtr->RawSymbol = &RawSymbol;
1150SN/A  return SymbolPtr;
1160SN/A}
1170SN/A
1180SN/Avoid PDBSymbol::defaultDump(raw_ostream &OS, int Indent,
1190SN/A                            PdbSymbolIdField ShowFlags,
1200SN/A                            PdbSymbolIdField RecurseFlags) const {
1210SN/A  RawSymbol->dump(OS, Indent, ShowFlags, RecurseFlags);
1220SN/A}
1230SN/A
1240SN/Avoid PDBSymbol::dumpProperties() const {
1250SN/A  outs() << "\n";
1260SN/A  defaultDump(outs(), 0, PdbSymbolIdField::All, PdbSymbolIdField::None);
1270SN/A  outs().flush();
1280SN/A}
1290SN/A
1300SN/Avoid PDBSymbol::dumpChildStats() const {
1310SN/A  TagStats Stats;
1320SN/A  getChildStats(Stats);
1330SN/A  outs() << "\n";
1340SN/A  for (auto &Stat : Stats) {
1350SN/A    outs() << Stat.first << ": " << Stat.second << "\n";
1360SN/A  }
1370SN/A  outs().flush();
1380SN/A}
13913629Savstepan
1400SN/APDB_SymType PDBSymbol::getSymTag() const { return RawSymbol->getSymTag(); }
1410SN/Auint32_t PDBSymbol::getSymIndexId() const { return RawSymbol->getSymIndexId(); }
14213629Savstepan
1430SN/Astd::unique_ptr<IPDBEnumSymbols> PDBSymbol::findAllChildren() const {
1440SN/A  return findAllChildren(PDB_SymType::None);
14513629Savstepan}
14613629Savstepan
14713629Savstepanstd::unique_ptr<IPDBEnumSymbols>
14810735SyanPDBSymbol::findAllChildren(PDB_SymType Type) const {
14910735Syan  return RawSymbol->findChildren(Type);
1500SN/A}
1510SN/A
1520SN/Astd::unique_ptr<IPDBEnumSymbols>
1530SN/APDBSymbol::findChildren(PDB_SymType Type, StringRef Name,
1540SN/A                        PDB_NameSearchFlags Flags) const {
1550SN/A  return RawSymbol->findChildren(Type, Name, Flags);
1560SN/A}
1570SN/A
1580SN/Astd::unique_ptr<IPDBEnumSymbols>
1590SN/APDBSymbol::findChildrenByRVA(PDB_SymType Type, StringRef Name,
1600SN/A                             PDB_NameSearchFlags Flags, uint32_t RVA) const {
1610SN/A  return RawSymbol->findChildrenByRVA(Type, Name, Flags, RVA);
1620SN/A}
1630SN/A
1640SN/Astd::unique_ptr<IPDBEnumSymbols>
1650SN/APDBSymbol::findInlineFramesByRVA(uint32_t RVA) const {
1660SN/A  return RawSymbol->findInlineFramesByRVA(RVA);
1670SN/A}
1680SN/A
1690SN/Astd::unique_ptr<IPDBEnumSymbols>
1700SN/APDBSymbol::getChildStats(TagStats &Stats) const {
1710SN/A  std::unique_ptr<IPDBEnumSymbols> Result(findAllChildren());
1720SN/A  if (!Result)
1730SN/A    return nullptr;
1740SN/A  Stats.clear();
1750SN/A  while (auto Child = Result->getNext()) {
1760SN/A    ++Stats[Child->getSymTag()];
1770SN/A  }
1780SN/A  Result->reset();
1790SN/A  return Result;
1800SN/A}
1810SN/A
1820SN/Astd::unique_ptr<PDBSymbol> PDBSymbol::getSymbolByIdHelper(uint32_t Id) const {
1830SN/A  return Session.getSymbolById(Id);
18410735Syan}
18510735Syan
1860SN/Avoid llvm::pdb::dumpSymbolIdField(raw_ostream &OS, StringRef Name,
1870SN/A                                  SymIndexId Value, int Indent,
1880SN/A                                  const IPDBSession &Session,
1890SN/A                                  PdbSymbolIdField FieldId,
1900SN/A                                  PdbSymbolIdField ShowFlags,
1910SN/A                                  PdbSymbolIdField RecurseFlags) {
1920SN/A  if ((FieldId & ShowFlags) == PdbSymbolIdField::None)
1930SN/A    return;
1940SN/A
1950SN/A  OS << "\n";
1960SN/A  OS.indent(Indent);
1970SN/A  OS << Name << ": " << Value;
1980SN/A  // Don't recurse unless the user requested it.
1990SN/A  if ((FieldId & RecurseFlags) == PdbSymbolIdField::None)
2000SN/A    return;
2010SN/A  // And obviously don't recurse on the symbol itself.
2020SN/A  if (FieldId == PdbSymbolIdField::SymIndexId)
2030SN/A    return;
2040SN/A
2050SN/A  auto Child = Session.getSymbolById(Value);
20610735Syan
2070SN/A  // It could have been a placeholder symbol for a type we don't yet support,
2080SN/A  // so just exit in that case.
2090SN/A  if (!Child)
21013629Savstepan    return;
21113629Savstepan
21213629Savstepan  // Don't recurse more than once, so pass PdbSymbolIdField::None) for the
21313629Savstepan  // recurse flags.
21410735Syan  Child->defaultDump(OS, Indent + 2, ShowFlags, PdbSymbolIdField::None);
2150SN/A}
2160SN/A