LLDB  mainline
UdtRecordCompleter.cpp
Go to the documentation of this file.
1 #include "UdtRecordCompleter.h"
2 
3 #include "PdbAstBuilder.h"
4 #include "PdbIndex.h"
5 #include "PdbSymUid.h"
6 #include "PdbUtil.h"
7 
12 #include "SymbolFileNativePDB.h"
13 #include "lldb/Core/Address.h"
14 #include "lldb/Symbol/Type.h"
16 #include "lldb/Utility/LLDBLog.h"
17 #include "lldb/lldb-enumerations.h"
18 #include "lldb/lldb-forward.h"
19 
20 #include "llvm/ADT/STLExtras.h"
21 #include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
22 #include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
23 #include "llvm/DebugInfo/CodeView/TypeIndex.h"
24 #include "llvm/DebugInfo/PDB/Native/GlobalsStream.h"
25 #include "llvm/DebugInfo/PDB/Native/TpiStream.h"
26 #include "llvm/DebugInfo/PDB/PDBTypes.h"
27 
28 using namespace llvm::codeview;
29 using namespace llvm::pdb;
30 using namespace lldb;
31 using namespace lldb_private;
32 using namespace lldb_private::npdb;
33 
35 
36 UdtRecordCompleter::UdtRecordCompleter(
37  PdbTypeSymId id, CompilerType &derived_ct, clang::TagDecl &tag_decl,
38  PdbAstBuilder &ast_builder, PdbIndex &index,
39  llvm::DenseMap<clang::Decl *, DeclStatus> &decl_to_status,
40  llvm::DenseMap<lldb::opaque_compiler_type_t,
41  llvm::SmallSet<std::pair<llvm::StringRef, CompilerType>, 8>>
42  &cxx_record_map)
43  : m_id(id), m_derived_ct(derived_ct), m_tag_decl(tag_decl),
44  m_ast_builder(ast_builder), m_index(index),
45  m_decl_to_status(decl_to_status), m_cxx_record_map(cxx_record_map) {
46  CVType cvt = m_index.tpi().getType(m_id.index);
47  switch (cvt.kind()) {
48  case LF_ENUM:
49  llvm::cantFail(TypeDeserializer::deserializeAs<EnumRecord>(cvt, m_cvr.er));
50  break;
51  case LF_UNION:
52  llvm::cantFail(TypeDeserializer::deserializeAs<UnionRecord>(cvt, m_cvr.ur));
53  m_layout.bit_size = m_cvr.ur.getSize() * 8;
55  break;
56  case LF_CLASS:
57  case LF_STRUCTURE:
58  llvm::cantFail(TypeDeserializer::deserializeAs<ClassRecord>(cvt, m_cvr.cr));
59  m_layout.bit_size = m_cvr.cr.getSize() * 8;
61  break;
62  default:
63  llvm_unreachable("unreachable!");
64  }
65 }
66 
68  llvm::codeview::TypeIndex ti, llvm::codeview::MemberAccess access,
69  llvm::Optional<uint64_t> vtable_idx) {
70  PdbTypeSymId type_id(ti);
71  clang::QualType qt = m_ast_builder.GetOrCreateType(type_id);
72 
73  CVType udt_cvt = m_index.tpi().getType(ti);
74 
75  std::unique_ptr<clang::CXXBaseSpecifier> base_spec =
77  qt.getAsOpaquePtr(), TranslateMemberAccess(access),
78  vtable_idx.has_value(), udt_cvt.kind() == LF_CLASS);
79  if (!base_spec)
80  return {};
81 
82  m_bases.push_back(
83  std::make_pair(vtable_idx.value_or(0), std::move(base_spec)));
84 
85  return qt;
86 }
87 
88 void UdtRecordCompleter::AddMethod(llvm::StringRef name, TypeIndex type_idx,
89  MemberAccess access, MethodOptions options,
90  MemberAttributes attrs) {
91  clang::QualType method_qt =
93  if (method_qt.isNull())
94  return;
95  CompilerType method_ct = m_ast_builder.ToCompilerType(method_qt);
97  lldb::opaque_compiler_type_t derived_opaque_ty =
99  auto iter = m_cxx_record_map.find(derived_opaque_ty);
100  if (iter != m_cxx_record_map.end()) {
101  if (iter->getSecond().contains({name, method_ct})) {
102  return;
103  }
104  }
105 
106  lldb::AccessType access_type = TranslateMemberAccess(access);
107  bool is_artificial = (options & MethodOptions::CompilerGenerated) ==
108  MethodOptions::CompilerGenerated;
110  derived_opaque_ty, name.data(), nullptr, method_ct,
111  access_type, attrs.isVirtual(), attrs.isStatic(), false, false, false,
112  is_artificial);
113 
114  m_cxx_record_map[derived_opaque_ty].insert({name, method_ct});
115 }
116 
117 Error UdtRecordCompleter::visitKnownMember(CVMemberRecord &cvr,
118  BaseClassRecord &base) {
119  clang::QualType base_qt =
120  AddBaseClassForTypeIndex(base.Type, base.getAccess());
121 
122  if (base_qt.isNull())
123  return llvm::Error::success();
124  auto decl =
125  m_ast_builder.clang().GetAsCXXRecordDecl(base_qt.getAsOpaquePtr());
126  lldbassert(decl);
127 
128  auto offset = clang::CharUnits::fromQuantity(base.getBaseOffset());
129  m_layout.base_offsets.insert(std::make_pair(decl, offset));
130 
131  return llvm::Error::success();
132 }
133 
134 Error UdtRecordCompleter::visitKnownMember(CVMemberRecord &cvr,
135  VirtualBaseClassRecord &base) {
136  AddBaseClassForTypeIndex(base.BaseType, base.getAccess(), base.VTableIndex);
137 
138  return Error::success();
139 }
140 
141 Error UdtRecordCompleter::visitKnownMember(CVMemberRecord &cvr,
142  ListContinuationRecord &cont) {
143  return Error::success();
144 }
145 
146 Error UdtRecordCompleter::visitKnownMember(CVMemberRecord &cvr,
147  VFPtrRecord &vfptr) {
148  return Error::success();
149 }
150 
151 Error UdtRecordCompleter::visitKnownMember(
152  CVMemberRecord &cvr, StaticDataMemberRecord &static_data_member) {
153  clang::QualType member_type =
154  m_ast_builder.GetOrCreateType(PdbTypeSymId(static_data_member.Type));
155  if (member_type.isNull())
156  return llvm::Error::success();
157 
158  CompilerType member_ct = m_ast_builder.ToCompilerType(member_type);
159 
160  lldb::AccessType access =
161  TranslateMemberAccess(static_data_member.getAccess());
163  m_derived_ct, static_data_member.Name, member_ct, access);
164 
165  // Static constant members may be a const[expr] declaration.
166  // Query the symbol's value as the variable initializer if valid.
167  if (member_ct.IsConst() && member_ct.IsCompleteType()) {
168  std::string qual_name = decl->getQualifiedNameAsString();
169 
170  auto results =
171  m_index.globals().findRecordsByName(qual_name, m_index.symrecords());
172 
173  for (const auto &result : results) {
174  if (result.second.kind() == SymbolKind::S_CONSTANT) {
175  ConstantSym constant(SymbolRecordKind::ConstantSym);
176  cantFail(SymbolDeserializer::deserializeAs<ConstantSym>(result.second,
177  constant));
178 
179  clang::QualType qual_type = decl->getType();
180  unsigned type_width = decl->getASTContext().getIntWidth(qual_type);
181  unsigned constant_width = constant.Value.getBitWidth();
182 
183  if (qual_type->isIntegralOrEnumerationType()) {
184  if (type_width >= constant_width) {
186  decl, constant.Value.extOrTrunc(type_width));
187  } else {
189  "Class '{0}' has a member '{1}' of type '{2}' ({3} bits) "
190  "which resolves to a wider constant value ({4} bits). "
191  "Ignoring constant.",
192  m_derived_ct.GetTypeName(), static_data_member.Name,
193  member_ct.GetTypeName(), type_width, constant_width);
194  }
195  } else {
196  lldb::BasicType basic_type_enum = member_ct.GetBasicTypeEnumeration();
197  switch (basic_type_enum) {
201  if (type_width == constant_width) {
203  decl, basic_type_enum == lldb::eBasicTypeFloat
204  ? llvm::APFloat(constant.Value.bitsToFloat())
205  : llvm::APFloat(constant.Value.bitsToDouble()));
206  decl->setConstexpr(true);
207  } else {
208  LLDB_LOG(
210  "Class '{0}' has a member '{1}' of type '{2}' ({3} bits) "
211  "which resolves to a constant value of mismatched width "
212  "({4} bits). Ignoring constant.",
213  m_derived_ct.GetTypeName(), static_data_member.Name,
214  member_ct.GetTypeName(), type_width, constant_width);
215  }
216  break;
217  default:
218  break;
219  }
220  }
221  break;
222  }
223  }
224  }
225 
226  // FIXME: Add a PdbSymUid namespace for field list members and update
227  // the m_uid_to_decl map with this decl.
228  return Error::success();
229 }
230 
231 Error UdtRecordCompleter::visitKnownMember(CVMemberRecord &cvr,
232  NestedTypeRecord &nested) {
233  return Error::success();
234 }
235 
236 Error UdtRecordCompleter::visitKnownMember(CVMemberRecord &cvr,
237  DataMemberRecord &data_member) {
238 
239  uint64_t offset = data_member.FieldOffset * 8;
240  uint32_t bitfield_width = 0;
241 
242  TypeIndex ti(data_member.Type);
243  if (!ti.isSimple()) {
244  CVType cvt = m_index.tpi().getType(ti);
245  if (cvt.kind() == LF_BITFIELD) {
246  BitFieldRecord bfr;
247  llvm::cantFail(TypeDeserializer::deserializeAs<BitFieldRecord>(cvt, bfr));
248  offset += bfr.BitOffset;
249  bitfield_width = bfr.BitSize;
250  ti = bfr.Type;
251  }
252  }
253 
254  clang::QualType member_qt = m_ast_builder.GetOrCreateType(PdbTypeSymId(ti));
255  if (member_qt.isNull())
256  return Error::success();
258  lldb::AccessType access = TranslateMemberAccess(data_member.getAccess());
259  size_t field_size =
260  bitfield_width ? bitfield_width : GetSizeOfType(ti, m_index.tpi()) * 8;
261  if (field_size == 0)
262  return Error::success();
263  m_record.CollectMember(data_member.Name, offset, field_size, member_qt, access,
264  bitfield_width);
265  return Error::success();
266 }
267 
268 Error UdtRecordCompleter::visitKnownMember(CVMemberRecord &cvr,
269  OneMethodRecord &one_method) {
270  AddMethod(one_method.Name, one_method.Type, one_method.getAccess(),
271  one_method.getOptions(), one_method.Attrs);
272 
273  return Error::success();
274 }
275 
276 Error UdtRecordCompleter::visitKnownMember(CVMemberRecord &cvr,
277  OverloadedMethodRecord &overloaded) {
278  TypeIndex method_list_idx = overloaded.MethodList;
279 
280  CVType method_list_type = m_index.tpi().getType(method_list_idx);
281  assert(method_list_type.kind() == LF_METHODLIST);
282 
283  MethodOverloadListRecord method_list;
284  llvm::cantFail(TypeDeserializer::deserializeAs<MethodOverloadListRecord>(
285  method_list_type, method_list));
286 
287  for (const OneMethodRecord &method : method_list.Methods)
288  AddMethod(overloaded.Name, method.Type, method.getAccess(),
289  method.getOptions(), method.Attrs);
290 
291  return Error::success();
292 }
293 
294 Error UdtRecordCompleter::visitKnownMember(CVMemberRecord &cvr,
295  EnumeratorRecord &enumerator) {
296  Declaration decl;
297  llvm::StringRef name = DropNameScope(enumerator.getName());
298 
300  m_derived_ct, decl, name.str().c_str(), enumerator.Value);
301  return Error::success();
302 }
303 
305  // Ensure the correct order for virtual bases.
306  llvm::stable_sort(m_bases, llvm::less_first());
307 
308  std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> bases;
309  bases.reserve(m_bases.size());
310  for (auto &ib : m_bases)
311  bases.push_back(std::move(ib.second));
312 
314  // Make sure all base classes refer to complete types and not forward
315  // declarations. If we don't do this, clang will crash with an
316  // assertion in the call to clang_type.TransferBaseClasses()
317  for (const auto &base_class : bases) {
318  clang::TypeSourceInfo *type_source_info =
319  base_class->getTypeSourceInfo();
320  if (type_source_info) {
322  clang.GetType(type_source_info->getType()));
323  }
324  }
325 
326  clang.TransferBaseClasses(m_derived_ct.GetOpaqueQualType(), std::move(bases));
327 
328  clang.AddMethodOverridesForCXXRecordType(m_derived_ct.GetOpaqueQualType());
329  FinishRecord();
332 
333  if (auto *record_decl = llvm::dyn_cast<clang::CXXRecordDecl>(&m_tag_decl)) {
335  }
336 }
337 
338 uint64_t
340  uint64_t bit_offset, CompilerType parent_ct,
341  ClangASTImporter::LayoutInfo &parent_layout,
342  clang::DeclContext *parent_decl_ctx) {
343  SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(
344  clang.GetSymbolFile()->GetBackingSymbolFile());
345  clang::FieldDecl *field_decl = nullptr;
346  uint64_t bit_size = 0;
347  switch (field->kind) {
348  case Member::Field: {
350  parent_ct, field->name, m_ast_builder.ToCompilerType(field->qt),
351  field->access, field->bitfield_width);
352  bit_size = field->bit_size;
353  break;
354  };
355  case Member::Struct:
356  case Member::Union: {
357  clang::TagTypeKind kind = field->kind == Member::Struct
358  ? clang::TagTypeKind::TTK_Struct
359  : clang::TagTypeKind::TTK_Union;
360  ClangASTMetadata metadata;
361  metadata.SetUserID(pdb->anonymous_id);
362  metadata.SetIsDynamicCXXType(false);
363  CompilerType record_ct = clang.CreateRecordType(
364  parent_decl_ctx, OptionalClangModuleID(), lldb::eAccessPublic, "", kind,
365  lldb::eLanguageTypeC_plus_plus, &metadata);
368  clang::DeclContext *decl_ctx = clang.GetDeclContextForType(record_ct);
369  for (const auto &member : field->fields) {
370  uint64_t member_offset = field->kind == Member::Struct
371  ? member->bit_offset - field->base_offset
372  : 0;
373  uint64_t member_bit_size = AddMember(clang, member.get(), member_offset,
374  record_ct, layout, decl_ctx);
375  if (field->kind == Member::Struct)
376  bit_size = std::max(bit_size, member_offset + member_bit_size);
377  else
378  bit_size = std::max(bit_size, member_bit_size);
379  }
380  layout.bit_size = bit_size;
382  clang::RecordDecl *record_decl = clang.GetAsRecordDecl(record_ct);
383  m_ast_builder.GetClangASTImporter().SetRecordLayout(record_decl, layout);
385  parent_ct, "", record_ct, lldb::eAccessPublic, 0);
386  // Mark this record decl as completed.
387  DeclStatus status;
388  status.resolved = true;
389  status.uid = pdb->anonymous_id--;
390  m_decl_to_status.insert({record_decl, status});
391  break;
392  };
393  }
394  // FIXME: Add a PdbSymUid namespace for field list members and update
395  // the m_uid_to_decl map with this decl.
396  parent_layout.field_offsets.insert({field_decl, bit_offset});
397  return bit_size;
398 }
399 
402  clang::DeclContext *decl_ctx =
405  // Maybe we should check the construsted record size with the size in pdb. If
406  // they mismatch, it might be pdb has fields info missing.
407  for (const auto &field : m_record.record.fields) {
408  AddMember(clang, field.get(), field->bit_offset, m_derived_ct, m_layout,
409  decl_ctx);
410  }
411 }
412 
414  llvm::StringRef name, uint64_t offset, uint64_t field_size,
415  clang::QualType qt, lldb::AccessType access, uint64_t bitfield_width) {
416  fields_map[offset].push_back(std::make_unique<Member>(
417  name, offset, field_size, qt, access, bitfield_width));
418  if (start_offset > offset)
419  start_offset = offset;
420 }
421 
423  // For anonymous unions in a struct, msvc generated pdb doesn't have the
424  // entity for that union. So, we need to construct anonymous union and struct
425  // based on field offsets. The final AST is likely not matching the exact
426  // original AST, but the memory layout is preseved.
427  // After we collecting all fields in visitKnownMember, we have all fields in
428  // increasing offset order in m_fields. Since we are iterating in increase
429  // offset order, if the current offset is equal to m_start_offset, we insert
430  // it as direct field of top level record. If the current offset is greater
431  // than m_start_offset, we should be able to find a field in end_offset_map
432  // whose end offset is less than or equal to current offset. (if not, it might
433  // be missing field info. We will ignore the field in this case. e.g. Field A
434  // starts at 0 with size 4 bytes, and Field B starts at 2 with size 4 bytes.
435  // Normally, there must be something which ends at/before 2.) Then we will
436  // append current field to the end of parent record. If parent is struct, we
437  // can just grow it. If parent is a field, it's a field inside an union. We
438  // convert it into an anonymous struct containing old field and new field.
439 
440  // The end offset to a vector of field/struct that ends at the offset.
441  std::map<uint64_t, std::vector<Member *>> end_offset_map;
442  for (auto &pair : fields_map) {
443  uint64_t offset = pair.first;
444  auto &fields = pair.second;
445  lldbassert(offset >= start_offset);
446  Member *parent = &record;
447  if (offset > start_offset) {
448  // Find the field with largest end offset that is <= offset. If it's less
449  // than offset, it indicates there are padding bytes between end offset
450  // and offset.
451  lldbassert(!end_offset_map.empty());
452  auto iter = end_offset_map.lower_bound(offset);
453  if (iter == end_offset_map.end())
454  --iter;
455  else if (iter->first > offset) {
456  if (iter == end_offset_map.begin())
457  continue;
458  --iter;
459  }
460  if (iter->second.empty())
461  continue;
462  parent = iter->second.back();
463  iter->second.pop_back();
464  }
465  // If it's a field, then the field is inside a union, so we can safely
466  // increase its size by converting it to a struct to hold multiple fields.
467  if (parent->kind == Member::Field)
468  parent->ConvertToStruct();
469 
470  if (fields.size() == 1) {
471  uint64_t end_offset = offset + fields.back()->bit_size;
472  parent->fields.push_back(std::move(fields.back()));
473  if (parent->kind == Member::Struct) {
474  end_offset_map[end_offset].push_back(parent);
475  } else {
476  lldbassert(parent == &record &&
477  "If parent is union, it must be the top level record.");
478  end_offset_map[end_offset].push_back(parent->fields.back().get());
479  }
480  } else {
481  if (parent->kind == Member::Struct) {
482  parent->fields.push_back(std::make_unique<Member>(Member::Union));
483  parent = parent->fields.back().get();
484  parent->bit_offset = offset;
485  } else {
486  lldbassert(parent == &record &&
487  "If parent is union, it must be the top level record.");
488  }
489  for (auto &field : fields) {
490  int64_t bit_size = field->bit_size;
491  parent->fields.push_back(std::move(field));
492  end_offset_map[offset + bit_size].push_back(
493  parent->fields.back().get());
494  }
495  }
496  }
497 }
lldb_private::ClangASTImporter::LayoutInfo::field_offsets
llvm::DenseMap< const clang::FieldDecl *, uint64_t > field_offsets
Definition: ClangASTImporter.h:73
lldb_private::npdb::UdtRecordCompleter::Record::fields_map
std::map< uint64_t, llvm::SmallVector< MemberUP, 1 > > fields_map
Definition: UdtRecordCompleter.h:118
lldb_private::npdb::UdtRecordCompleter::UdtTagRecord::er
llvm::codeview::EnumRecord er
Definition: UdtRecordCompleter.h:47
lldb_private::npdb::UdtRecordCompleter::Member
Definition: UdtRecordCompleter.h:80
lldb_private::npdb::PdbAstBuilder::ToCompilerType
CompilerType ToCompilerType(clang::QualType qt)
Definition: PdbAstBuilder.cpp:1430
lldb_private::TypeSystemClang::SetFloatingInitializerForVariable
static void SetFloatingInitializerForVariable(clang::VarDecl *var, const llvm::APFloat &init_value)
Initializes a variable with a floating point value.
Definition: TypeSystemClang.cpp:7636
lldb_private::LLDBLog::AST
@ AST
lldb_private::npdb::SymbolFileNativePDB
Definition: SymbolFileNativePDB.h:42
lldb_private::npdb::PdbIndex
PdbIndex - Lazy access to the important parts of a PDB file.
Definition: PdbIndex.h:47
lldb_private::npdb::PdbTypeSymId::index
llvm::codeview::TypeIndex index
Definition: PdbSymUid.h:76
lldb_private::ClangASTMetadata::SetUserID
void SetUserID(lldb::user_id_t user_id)
Definition: ClangASTMetadata.h:29
lldb_private::CompilerType::GetTypeName
ConstString GetTypeName(bool BaseOnly=false) const
Definition: CompilerType.cpp:314
lldb_private::npdb::UdtRecordCompleter::UdtTagRecord::cr
llvm::codeview::ClassRecord cr
Definition: UdtRecordCompleter.h:46
lldb_private::CompilerType::IsCompleteType
bool IsCompleteType() const
Definition: CompilerType.cpp:90
lldb_private::npdb::TranslateMemberAccess
lldb::AccessType TranslateMemberAccess(llvm::codeview::MemberAccess access)
lldb_private::npdb
Definition: TypeSystem.h:35
lldb_private::npdb::DropNameScope
llvm::StringRef DropNameScope(llvm::StringRef name)
Definition: PdbUtil.cpp:599
lldb_private::npdb::PdbAstBuilder::clang
TypeSystemClang & clang()
Definition: PdbAstBuilder.h:86
lldb_private::npdb::UdtRecordCompleter::AddBaseClassForTypeIndex
clang::QualType AddBaseClassForTypeIndex(llvm::codeview::TypeIndex ti, llvm::codeview::MemberAccess access, llvm::Optional< uint64_t > vtable_idx=llvm::Optional< uint64_t >())
Definition: UdtRecordCompleter.cpp:67
lldb_private::ClangASTImporter::LayoutInfo
Definition: ClangASTImporter.h:66
lldb_private::npdb::UdtRecordCompleter::Member::Union
@ Union
Definition: UdtRecordCompleter.h:81
lldb_private::CompilerType::GetOpaqueQualType
lldb::opaque_compiler_type_t GetOpaqueQualType() const
Definition: CompilerType.h:229
lldb_private::npdb::UdtRecordCompleter::Member::Field
@ Field
Definition: UdtRecordCompleter.h:81
lldb_private::TypeSystemClang::AddVariableToRecordType
static clang::VarDecl * AddVariableToRecordType(const CompilerType &type, llvm::StringRef name, const CompilerType &var_type, lldb::AccessType access)
Definition: TypeSystemClang.cpp:7573
lldb_private::npdb::UdtRecordCompleter::Member::Struct
@ Struct
Definition: UdtRecordCompleter.h:81
lldb_private::npdb::UdtRecordCompleter::Member::name
llvm::StringRef name
Definition: UdtRecordCompleter.h:83
lldb::BasicType
BasicType
Basic types enumeration for the public API SBType::GetBasicType().
Definition: lldb-enumerations.h:748
lldb_private::npdb::UdtRecordCompleter::Member::qt
clang::QualType qt
Definition: UdtRecordCompleter.h:86
lldb_private::npdb::UdtRecordCompleter::Record::start_offset
uint64_t start_offset
Definition: UdtRecordCompleter.h:117
PdbIndex.h
lldb_private::npdb::DeclStatus
Definition: PdbAstBuilder.h:44
ClangUtil.h
lldb_private::CompilerType::IsConst
bool IsConst() const
Definition: CompilerType.cpp:104
lldb_private::npdb::UdtRecordCompleter::complete
void complete()
Definition: UdtRecordCompleter.cpp:304
lldb::eBasicTypeFloat
@ eBasicTypeFloat
Definition: lldb-enumerations.h:772
lldb_private::npdb::SymbolFileNativePDB::anonymous_id
lldb::user_id_t anonymous_id
Definition: SymbolFileNativePDB.h:272
lldb_private::ClangASTImporter::LayoutInfo::base_offsets
OffsetMap base_offsets
Definition: ClangASTImporter.h:74
lldb_private::npdb::PdbAstBuilder::GetClangASTImporter
ClangASTImporter & GetClangASTImporter()
Definition: PdbAstBuilder.h:87
lldb_private::npdb::GetSizeOfType
size_t GetSizeOfType(PdbTypeSymId id, llvm::pdb::TpiStream &tpi)
Definition: PdbUtil.cpp:1065
LLDBAssert.h
ClangASTMetadata.h
lldb_private::TypeSystemClang::GetAsCXXRecordDecl
static clang::CXXRecordDecl * GetAsCXXRecordDecl(lldb::opaque_compiler_type_t type)
Definition: TypeSystemClang.cpp:7338
lldb_private::npdb::UdtRecordCompleter::Member::kind
enum lldb_private::npdb::UdtRecordCompleter::Member::Kind kind
lldb_private::CompilerType::GetBasicTypeEnumeration
lldb::BasicType GetBasicTypeEnumeration() const
Definition: CompilerType.cpp:588
TypeSystemClang.h
lldb_private::TypeSystemClang::AddFieldToRecordType
static clang::FieldDecl * AddFieldToRecordType(const CompilerType &type, llvm::StringRef name, const CompilerType &field_type, lldb::AccessType access, uint32_t bitfield_bit_size)
Definition: TypeSystemClang.cpp:7352
lldb_private::npdb::DeclStatus::resolved
bool resolved
Definition: PdbAstBuilder.h:49
lldb_private::npdb::PdbIndex::tpi
llvm::pdb::TpiStream & tpi()
Definition: PdbIndex.h:124
lldb_private::npdb::UdtRecordCompleter::Member::ConvertToStruct
void ConvertToStruct()
Definition: UdtRecordCompleter.h:102
lldb_private::npdb::UdtRecordCompleter::m_ast_builder
PdbAstBuilder & m_ast_builder
Definition: UdtRecordCompleter.h:53
Type.h
llvm::pdb
Definition: DWARFLocationExpression.h:23
lldb::eBasicTypeDouble
@ eBasicTypeDouble
Definition: lldb-enumerations.h:773
lldb_private::npdb::PdbTypeSymId
Definition: PdbSymUid.h:70
lldb::eLanguageTypeC_plus_plus
@ eLanguageTypeC_plus_plus
ISO C++:1998.
Definition: lldb-enumerations.h:442
lldb-enumerations.h
lldb_private::ClangASTMetadata::SetIsDynamicCXXType
void SetIsDynamicCXXType(bool b)
Definition: ClangASTMetadata.h:27
lldb_private::npdb::UdtRecordCompleter::Member::fields
llvm::SmallVector< MemberUP, 1 > fields
Definition: UdtRecordCompleter.h:91
PdbAstBuilder.h
lldb_private::TypeSystemClang::RequireCompleteType
static void RequireCompleteType(CompilerType type)
Complete a type from debug info, or mark it as forcefully completed if there is no definition of the ...
Definition: TypeSystemClang.cpp:9841
string
string(SUBSTRING ${p} 10 -1 pStripped) if($
Definition: Plugins/CMakeLists.txt:40
lldb_private::ClangASTMetadata
Definition: ClangASTMetadata.h:18
lldb_private::npdb::UdtRecordCompleter::m_cvr
union lldb_private::npdb::UdtRecordCompleter::UdtTagRecord m_cvr
Address.h
PdbUtil.h
lldb_private::ClangASTImporter::SetRecordLayout
void SetRecordLayout(clang::RecordDecl *decl, const LayoutInfo &layout)
Sets the layout for the given RecordDecl.
Definition: ClangASTImporter.cpp:548
lldb::eAccessPublic
@ eAccessPublic
Definition: lldb-enumerations.h:510
lldb_private::npdb::UdtRecordCompleter::Member::bitfield_width
uint32_t bitfield_width
Definition: UdtRecordCompleter.h:88
lldbassert
#define lldbassert(x)
Definition: LLDBAssert.h:15
lldb_private::npdb::UdtRecordCompleter::FinishRecord
void FinishRecord()
Definition: UdtRecordCompleter.cpp:400
lldb_private::npdb::UdtRecordCompleter::Member::bit_offset
uint64_t bit_offset
Definition: UdtRecordCompleter.h:84
lldb::eBasicTypeLongDouble
@ eBasicTypeLongDouble
Definition: lldb-enumerations.h:774
lldb_private::OptionalClangModuleID
A Clang module ID.
Definition: TypeSystemClang.h:56
uint32_t
UdtRecordCompleter.h
PdbSymUid.h
lldb_private::npdb::UdtRecordCompleter::Member::bit_size
uint64_t bit_size
Definition: UdtRecordCompleter.h:85
id
void * id
Definition: PlatformiOSSimulatorCoreSimulatorSupport.h:20
lldb_private::npdb::PdbAstBuilder::GetOrCreateDeclContextForUid
clang::DeclContext * GetOrCreateDeclContextForUid(PdbSymUid uid)
Definition: PdbAstBuilder.cpp:304
lldb_private::TypeSystemClang::BuildIndirectFields
static void BuildIndirectFields(const CompilerType &type)
Definition: TypeSystemClang.cpp:7448
lldb_private::npdb::UdtRecordCompleter::m_cxx_record_map
llvm::DenseMap< lldb::opaque_compiler_type_t, llvm::SmallSet< std::pair< llvm::StringRef, CompilerType >, 8 > > & m_cxx_record_map
Definition: UdtRecordCompleter.h:60
lldb_private::npdb::UdtRecordCompleter::m_record
Record m_record
Definition: UdtRecordCompleter.h:127
LLDB_LOG
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
Definition: Log.h:337
SymbolFileNativePDB.h
clang
Definition: ASTResultSynthesizer.h:15
lldb_private::npdb::UdtRecordCompleter::m_derived_ct
CompilerType & m_derived_ct
Definition: UdtRecordCompleter.h:51
lldb_private::npdb::PdbAstBuilder::GetOrCreateType
clang::QualType GetOrCreateType(PdbTypeSymId type)
Definition: PdbAstBuilder.cpp:804
lldb_private::CompilerType
Generic representation of a type in a programming language.
Definition: CompilerType.h:35
lldb-forward.h
lldb_private::npdb::UdtRecordCompleter::m_id
PdbTypeSymId m_id
Definition: UdtRecordCompleter.h:50
lldb_private::TypeSystemClang::StartTagDeclarationDefinition
static bool StartTagDeclarationDefinition(const CompilerType &type)
Definition: TypeSystemClang.cpp:8309
lldb_private::npdb::PdbIndex::symrecords
llvm::pdb::SymbolStream & symrecords()
Definition: PdbIndex.h:139
lldb_private
A class that represents a running process on the host machine.
Definition: SBCommandInterpreterRunOptions.h:16
llvm::codeview
Definition: DWARFLocationExpression.h:20
lldb_private::npdb::UdtRecordCompleter::AddMember
uint64_t AddMember(TypeSystemClang &clang, Member *field, uint64_t bit_offset, CompilerType parent_ct, ClangASTImporter::LayoutInfo &parent_layout, clang::DeclContext *decl_ctx)
Definition: UdtRecordCompleter.cpp:339
lldb_private::npdb::UdtRecordCompleter::Record::CollectMember
void CollectMember(llvm::StringRef name, uint64_t offset, uint64_t field_size, clang::QualType qt, lldb::AccessType access, uint64_t bitfield_width)
Definition: UdtRecordCompleter.cpp:413
Error
llvm::Error Error
Definition: UdtRecordCompleter.cpp:34
lldb_private::TypeSystemClang::SetIntegerInitializerForVariable
static void SetIntegerInitializerForVariable(clang::VarDecl *var, const llvm::APInt &init_value)
Initializes a variable with an integer value.
Definition: TypeSystemClang.cpp:7611
lldb_private::npdb::UdtRecordCompleter::m_tag_decl
clang::TagDecl & m_tag_decl
Definition: UdtRecordCompleter.h:52
lldb_private::npdb::UdtRecordCompleter::Member::access
lldb::AccessType access
Definition: UdtRecordCompleter.h:87
lldb_private::TypeSystemClang
A TypeSystem implementation based on Clang.
Definition: TypeSystemClang.h:105
lldb_private::npdb::DeclStatus::uid
lldb::user_id_t uid
Definition: PdbAstBuilder.h:48
ClangASTImporter.h
lldb_private::TypeSystemClang::AddEnumerationValueToEnumerationType
clang::EnumConstantDecl * AddEnumerationValueToEnumerationType(const CompilerType &enum_type, const Declaration &decl, const char *name, int64_t enum_value, uint32_t enum_value_bit_size)
Definition: TypeSystemClang.cpp:8465
lldb_private::npdb::UdtRecordCompleter::m_decl_to_status
llvm::DenseMap< clang::Decl *, DeclStatus > & m_decl_to_status
Definition: UdtRecordCompleter.h:57
lldb_private::npdb::UdtRecordCompleter::Record::record
Member record
Definition: UdtRecordCompleter.h:116
lldb_private::npdb::UdtRecordCompleter::Member::base_offset
uint64_t base_offset
Definition: UdtRecordCompleter.h:90
lldb_private::TypeSystemClang::AddMethodToCXXRecordType
clang::CXXMethodDecl * AddMethodToCXXRecordType(lldb::opaque_compiler_type_t type, llvm::StringRef name, const char *mangled_name, const CompilerType &method_type, lldb::AccessType access, bool is_virtual, bool is_static, bool is_inline, bool is_explicit, bool is_attr_used, bool is_artificial)
Definition: TypeSystemClang.cpp:7647
lldb_private::npdb::PdbIndex::globals
llvm::pdb::GlobalsStream & globals()
Definition: PdbIndex.h:136
lldb_private::npdb::UdtRecordCompleter::m_layout
ClangASTImporter::LayoutInfo m_layout
Definition: UdtRecordCompleter.h:56
lldb_private::GetLog
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
Definition: Log.h:309
lldb_private::Declaration
Definition: Declaration.h:24
lldb_private::npdb::UdtRecordCompleter::UdtTagRecord::ur
llvm::codeview::UnionRecord ur
Definition: UdtRecordCompleter.h:45
lldb_private::TypeSystemClang::CompleteTagDeclarationDefinition
static bool CompleteTagDeclarationDefinition(const CompilerType &type)
Definition: TypeSystemClang.cpp:8334
lldb
Definition: SBAddress.h:15
LLDBLog.h
lldb_private::npdb::UdtRecordCompleter::Record::ConstructRecord
void ConstructRecord()
Definition: UdtRecordCompleter.cpp:422
lldb::AccessType
AccessType
Definition: lldb-enumerations.h:508
lldb_private::TypeSystemClang::CreateBaseClassSpecifier
std::unique_ptr< clang::CXXBaseSpecifier > CreateBaseClassSpecifier(lldb::opaque_compiler_type_t type, lldb::AccessType access, bool is_virtual, bool base_of_class)
Definition: TypeSystemClang.cpp:7853
lldb::opaque_compiler_type_t
void * opaque_compiler_type_t
Definition: lldb-types.h:90
lldb_private::ClangASTImporter::LayoutInfo::bit_size
uint64_t bit_size
Definition: ClangASTImporter.h:71
lldb_private::npdb::UdtRecordCompleter::AddMethod
void AddMethod(llvm::StringRef name, llvm::codeview::TypeIndex type_idx, llvm::codeview::MemberAccess access, llvm::codeview::MethodOptions options, llvm::codeview::MemberAttributes attrs)
Definition: UdtRecordCompleter.cpp:88
lldb_private::npdb::PdbAstBuilder
Definition: PdbAstBuilder.h:52
lldb_private::npdb::UdtRecordCompleter::m_index
PdbIndex & m_index
Definition: UdtRecordCompleter.h:54
lldb_private::npdb::UdtRecordCompleter::m_bases
std::vector< IndexedBase > m_bases
Definition: UdtRecordCompleter.h:55