summaryrefslogtreecommitdiff
path: root/contrib/llvm/tools/lldb/source/Symbol/ClangASTContext.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/tools/lldb/source/Symbol/ClangASTContext.cpp')
-rw-r--r--contrib/llvm/tools/lldb/source/Symbol/ClangASTContext.cpp751
1 files changed, 491 insertions, 260 deletions
diff --git a/contrib/llvm/tools/lldb/source/Symbol/ClangASTContext.cpp b/contrib/llvm/tools/lldb/source/Symbol/ClangASTContext.cpp
index a7578de0dcac..15596cbebd14 100644
--- a/contrib/llvm/tools/lldb/source/Symbol/ClangASTContext.cpp
+++ b/contrib/llvm/tools/lldb/source/Symbol/ClangASTContext.cpp
@@ -12,13 +12,10 @@
#include "llvm/Support/FormatAdapters.h"
#include "llvm/Support/FormatVariadic.h"
-// C Includes
-// C++ Includes
#include <mutex>
#include <string>
#include <vector>
-// Other libraries and framework includes
// Clang headers like to use NDEBUG inside of them to enable/disable debug
// related features using "#ifndef NDEBUG" preprocessor blocks to do one thing
@@ -76,7 +73,6 @@
#include "lldb/Core/DumpDataExtractor.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
-#include "lldb/Core/Scalar.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Core/ThreadSafeDenseMap.h"
#include "lldb/Core/UniqueCStringMap.h"
@@ -97,6 +93,7 @@
#include "lldb/Utility/LLDBAssert.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/RegularExpression.h"
+#include "lldb/Utility/Scalar.h"
#include "Plugins/SymbolFile/DWARF/DWARFASTParserClang.h"
#ifdef LLDB_ENABLE_ALL
@@ -124,8 +121,204 @@ ClangASTContextSupportsLanguage(lldb::LanguageType language) {
language == eLanguageTypeRust ||
language == eLanguageTypeExtRenderScript ||
// Use Clang for D until there is a proper language plugin for it
- language == eLanguageTypeD;
-}
+ language == eLanguageTypeD ||
+ // Open Dylan compiler debug info is designed to be Clang-compatible
+ language == eLanguageTypeDylan;
+}
+
+// Checks whether m1 is an overload of m2 (as opposed to an override). This is
+// called by addOverridesForMethod to distinguish overrides (which share a
+// vtable entry) from overloads (which require distinct entries).
+bool isOverload(clang::CXXMethodDecl *m1, clang::CXXMethodDecl *m2) {
+ // FIXME: This should detect covariant return types, but currently doesn't.
+ lldbassert(&m1->getASTContext() == &m2->getASTContext() &&
+ "Methods should have the same AST context");
+ clang::ASTContext &context = m1->getASTContext();
+
+ const auto *m1Type = llvm::cast<clang::FunctionProtoType>(
+ context.getCanonicalType(m1->getType()));
+
+ const auto *m2Type = llvm::cast<clang::FunctionProtoType>(
+ context.getCanonicalType(m2->getType()));
+
+ auto compareArgTypes = [&context](const clang::QualType &m1p,
+ const clang::QualType &m2p) {
+ return context.hasSameType(m1p.getUnqualifiedType(),
+ m2p.getUnqualifiedType());
+ };
+
+ // FIXME: In C++14 and later, we can just pass m2Type->param_type_end()
+ // as a fourth parameter to std::equal().
+ return (m1->getNumParams() != m2->getNumParams()) ||
+ !std::equal(m1Type->param_type_begin(), m1Type->param_type_end(),
+ m2Type->param_type_begin(), compareArgTypes);
+}
+
+// If decl is a virtual method, walk the base classes looking for methods that
+// decl overrides. This table of overridden methods is used by IRGen to
+// determine the vtable layout for decl's parent class.
+void addOverridesForMethod(clang::CXXMethodDecl *decl) {
+ if (!decl->isVirtual())
+ return;
+
+ clang::CXXBasePaths paths;
+
+ auto find_overridden_methods =
+ [decl](const clang::CXXBaseSpecifier *specifier,
+ clang::CXXBasePath &path) {
+ if (auto *base_record = llvm::dyn_cast<clang::CXXRecordDecl>(
+ specifier->getType()->getAs<clang::RecordType>()->getDecl())) {
+
+ clang::DeclarationName name = decl->getDeclName();
+
+ // If this is a destructor, check whether the base class destructor is
+ // virtual.
+ if (name.getNameKind() == clang::DeclarationName::CXXDestructorName)
+ if (auto *baseDtorDecl = base_record->getDestructor()) {
+ if (baseDtorDecl->isVirtual()) {
+ path.Decls = baseDtorDecl;
+ return true;
+ } else
+ return false;
+ }
+
+ // Otherwise, search for name in the base class.
+ for (path.Decls = base_record->lookup(name); !path.Decls.empty();
+ path.Decls = path.Decls.slice(1)) {
+ if (auto *method_decl =
+ llvm::dyn_cast<clang::CXXMethodDecl>(path.Decls.front()))
+ if (method_decl->isVirtual() && !isOverload(decl, method_decl)) {
+ path.Decls = method_decl;
+ return true;
+ }
+ }
+ }
+
+ return false;
+ };
+
+ if (decl->getParent()->lookupInBases(find_overridden_methods, paths)) {
+ for (auto *overridden_decl : paths.found_decls())
+ decl->addOverriddenMethod(
+ llvm::cast<clang::CXXMethodDecl>(overridden_decl));
+ }
+}
+}
+
+static lldb::addr_t GetVTableAddress(Process &process,
+ VTableContextBase &vtable_ctx,
+ ValueObject &valobj,
+ const ASTRecordLayout &record_layout) {
+ // Retrieve type info
+ CompilerType pointee_type;
+ CompilerType this_type(valobj.GetCompilerType());
+ uint32_t type_info = this_type.GetTypeInfo(&pointee_type);
+ if (!type_info)
+ return LLDB_INVALID_ADDRESS;
+
+ // Check if it's a pointer or reference
+ bool ptr_or_ref = false;
+ if (type_info & (eTypeIsPointer | eTypeIsReference)) {
+ ptr_or_ref = true;
+ type_info = pointee_type.GetTypeInfo();
+ }
+
+ // We process only C++ classes
+ const uint32_t cpp_class = eTypeIsClass | eTypeIsCPlusPlus;
+ if ((type_info & cpp_class) != cpp_class)
+ return LLDB_INVALID_ADDRESS;
+
+ // Calculate offset to VTable pointer
+ lldb::offset_t vbtable_ptr_offset =
+ vtable_ctx.isMicrosoft() ? record_layout.getVBPtrOffset().getQuantity()
+ : 0;
+
+ if (ptr_or_ref) {
+ // We have a pointer / ref to object, so read
+ // VTable pointer from process memory
+
+ if (valobj.GetAddressTypeOfChildren() != eAddressTypeLoad)
+ return LLDB_INVALID_ADDRESS;
+
+ auto vbtable_ptr_addr = valobj.GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
+ if (vbtable_ptr_addr == LLDB_INVALID_ADDRESS)
+ return LLDB_INVALID_ADDRESS;
+
+ vbtable_ptr_addr += vbtable_ptr_offset;
+
+ Status err;
+ return process.ReadPointerFromMemory(vbtable_ptr_addr, err);
+ }
+
+ // We have an object already read from process memory,
+ // so just extract VTable pointer from it
+
+ DataExtractor data;
+ Status err;
+ auto size = valobj.GetData(data, err);
+ if (err.Fail() || vbtable_ptr_offset + data.GetAddressByteSize() > size)
+ return LLDB_INVALID_ADDRESS;
+
+ return data.GetPointer(&vbtable_ptr_offset);
+}
+
+static int64_t ReadVBaseOffsetFromVTable(Process &process,
+ VTableContextBase &vtable_ctx,
+ lldb::addr_t vtable_ptr,
+ const CXXRecordDecl *cxx_record_decl,
+ const CXXRecordDecl *base_class_decl) {
+ if (vtable_ctx.isMicrosoft()) {
+ clang::MicrosoftVTableContext &msoft_vtable_ctx =
+ static_cast<clang::MicrosoftVTableContext &>(vtable_ctx);
+
+ // Get the index into the virtual base table. The
+ // index is the index in uint32_t from vbtable_ptr
+ const unsigned vbtable_index =
+ msoft_vtable_ctx.getVBTableIndex(cxx_record_decl, base_class_decl);
+ const lldb::addr_t base_offset_addr = vtable_ptr + vbtable_index * 4;
+ Status err;
+ return process.ReadSignedIntegerFromMemory(base_offset_addr, 4, INT64_MAX,
+ err);
+ }
+
+ clang::ItaniumVTableContext &itanium_vtable_ctx =
+ static_cast<clang::ItaniumVTableContext &>(vtable_ctx);
+
+ clang::CharUnits base_offset_offset =
+ itanium_vtable_ctx.getVirtualBaseOffsetOffset(cxx_record_decl,
+ base_class_decl);
+ const lldb::addr_t base_offset_addr =
+ vtable_ptr + base_offset_offset.getQuantity();
+ const uint32_t base_offset_size = process.GetAddressByteSize();
+ Status err;
+ return process.ReadSignedIntegerFromMemory(base_offset_addr, base_offset_size,
+ INT64_MAX, err);
+}
+
+static bool GetVBaseBitOffset(VTableContextBase &vtable_ctx,
+ ValueObject &valobj,
+ const ASTRecordLayout &record_layout,
+ const CXXRecordDecl *cxx_record_decl,
+ const CXXRecordDecl *base_class_decl,
+ int32_t &bit_offset) {
+ ExecutionContext exe_ctx(valobj.GetExecutionContextRef());
+ Process *process = exe_ctx.GetProcessPtr();
+ if (!process)
+ return false;
+
+ lldb::addr_t vtable_ptr =
+ GetVTableAddress(*process, vtable_ctx, valobj, record_layout);
+ if (vtable_ptr == LLDB_INVALID_ADDRESS)
+ return false;
+
+ auto base_offset = ReadVBaseOffsetFromVTable(
+ *process, vtable_ctx, vtable_ptr, cxx_record_decl, base_class_decl);
+ if (base_offset == INT64_MAX)
+ return false;
+
+ bit_offset = base_offset * 8;
+
+ return true;
}
typedef lldb_private::ThreadSafeDenseMap<clang::ASTContext *, ClangASTContext *>
@@ -383,7 +576,7 @@ static void ParseLangArgs(LangOptions &Opts, InputKind IK, const char *triple) {
if (IK.getLanguage() == InputKind::Asm) {
Opts.AsmPreprocessor = 1;
} else if (IK.isObjectiveC()) {
- Opts.ObjC1 = Opts.ObjC2 = 1;
+ Opts.ObjC = 1;
}
LangStandard::Kind LangStd = LangStandard::lang_unspecified;
@@ -630,7 +823,6 @@ void ClangASTContext::SetExternalSource(
if (ast) {
ast->setExternalSource(ast_source_ap);
ast->getTranslationUnitDecl()->setHasExternalLexicalStorage(true);
- // ast->getTranslationUnitDecl()->setHasExternalVisibleStorage(true);
}
}
@@ -641,7 +833,6 @@ void ClangASTContext::RemoveExternalSource() {
llvm::IntrusiveRefCntPtr<ExternalASTSource> empty_ast_source_ap;
ast->setExternalSource(empty_ast_source_ap);
ast->getTranslationUnitDecl()->setHasExternalLexicalStorage(false);
- // ast->getTranslationUnitDecl()->setHasExternalVisibleStorage(false);
}
}
@@ -803,9 +994,7 @@ TargetInfo *ClangASTContext::getTargetInfo() {
static inline bool QualTypeMatchesBitSize(const uint64_t bit_size,
ASTContext *ast, QualType qual_type) {
uint64_t qual_type_bit_size = ast->getTypeSize(qual_type);
- if (qual_type_bit_size == bit_size)
- return true;
- return false;
+ return qual_type_bit_size == bit_size;
}
CompilerType
@@ -954,9 +1143,10 @@ CompilerType ClangASTContext::GetBasicType(ASTContext *ast,
uint32_t ClangASTContext::GetPointerByteSize() {
if (m_pointer_byte_size == 0)
- m_pointer_byte_size = GetBasicType(lldb::eBasicTypeVoid)
- .GetPointerType()
- .GetByteSize(nullptr);
+ if (auto size = GetBasicType(lldb::eBasicTypeVoid)
+ .GetPointerType()
+ .GetByteSize(nullptr))
+ m_pointer_byte_size = *size;
return m_pointer_byte_size;
}
@@ -1677,8 +1867,7 @@ CompilerType ClangASTContext::CreateObjCClass(const char *name,
}
static inline bool BaseSpecifierIsEmpty(const CXXBaseSpecifier *b) {
- return ClangASTContext::RecordHasFields(b->getType()->getAsCXXRecordDecl()) ==
- false;
+ return !ClangASTContext::RecordHasFields(b->getType()->getAsCXXRecordDecl());
}
uint32_t
@@ -1984,7 +2173,8 @@ FunctionDecl *ClangASTContext::CreateFunctionDeclaration(
CompilerType ClangASTContext::CreateFunctionType(
ASTContext *ast, const CompilerType &result_type, const CompilerType *args,
- unsigned num_args, bool is_variadic, unsigned type_quals) {
+ unsigned num_args, bool is_variadic, unsigned type_quals,
+ clang::CallingConv cc) {
if (ast == nullptr)
return CompilerType(); // invalid AST
@@ -2012,9 +2202,10 @@ CompilerType ClangASTContext::CreateFunctionType(
// TODO: Detect calling convention in DWARF?
FunctionProtoType::ExtProtoInfo proto_info;
+ proto_info.ExtInfo = cc;
proto_info.Variadic = is_variadic;
proto_info.ExceptionSpec = EST_None;
- proto_info.TypeQuals = type_quals;
+ proto_info.TypeQuals = clang::Qualifiers::fromFastMask(type_quals);
proto_info.RefQualifier = RQ_None;
return CompilerType(ast,
@@ -2023,14 +2214,17 @@ CompilerType ClangASTContext::CreateFunctionType(
}
ParmVarDecl *ClangASTContext::CreateParameterDeclaration(
- const char *name, const CompilerType &param_type, int storage) {
+ clang::DeclContext *decl_ctx, const char *name,
+ const CompilerType &param_type, int storage) {
ASTContext *ast = getASTContext();
assert(ast != nullptr);
- return ParmVarDecl::Create(*ast, ast->getTranslationUnitDecl(),
- SourceLocation(), SourceLocation(),
- name && name[0] ? &ast->Idents.get(name) : nullptr,
- ClangUtil::GetQualType(param_type), nullptr,
- (clang::StorageClass)storage, nullptr);
+ auto *decl =
+ ParmVarDecl::Create(*ast, decl_ctx, SourceLocation(), SourceLocation(),
+ name && name[0] ? &ast->Idents.get(name) : nullptr,
+ ClangUtil::GetQualType(param_type), nullptr,
+ (clang::StorageClass)storage, nullptr);
+ decl_ctx->addDecl(decl);
+ return decl;
}
void ClangASTContext::SetFunctionParameters(FunctionDecl *function_decl,
@@ -2138,6 +2332,9 @@ ClangASTContext::CreateEnumerationType(const char *name, DeclContext *decl_ctx,
false); // IsFixed
if (enum_decl) {
+ if (decl_ctx)
+ decl_ctx->addDecl(enum_decl);
+
// TODO: check if we should be setting the promotion type too?
enum_decl->setIntegerType(ClangUtil::GetQualType(integer_clang_type));
@@ -3739,9 +3936,7 @@ bool ClangASTContext::IsCXXClassType(const CompilerType &type) {
return false;
clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type));
- if (!qual_type.isNull() && qual_type->getAsCXXRecordDecl() != nullptr)
- return true;
- return false;
+ return !qual_type.isNull() && qual_type->getAsCXXRecordDecl() != nullptr;
}
bool ClangASTContext::IsBeingDefined(lldb::opaque_compiler_type_t type) {
@@ -4313,7 +4508,8 @@ ClangASTContext::GetArrayElementType(lldb::opaque_compiler_type_t type,
// TODO: the real stride will be >= this value.. find the real one!
if (stride)
- *stride = element_type.GetByteSize(nullptr);
+ if (Optional<uint64_t> size = element_type.GetByteSize(nullptr))
+ *stride = *size;
return element_type;
}
@@ -4665,6 +4861,8 @@ CompilerType ClangASTContext::CreateTypedefType(
decl->setAccess(clang::AS_public); // TODO respect proper access specifier
+ decl_ctx->addDecl(decl);
+
// Get a uniqued clang::QualType for the typedef decl type
return CompilerType(clang_ast, clang_ast->getTypedefType(decl));
}
@@ -5032,6 +5230,20 @@ lldb::Encoding ClangASTContext::GetEncoding(lldb::opaque_compiler_type_t type,
case clang::BuiltinType::Kind::PseudoObject:
case clang::BuiltinType::Kind::UnknownAny:
break;
+
+ case clang::BuiltinType::OCLIntelSubgroupAVCMcePayload:
+ case clang::BuiltinType::OCLIntelSubgroupAVCImePayload:
+ case clang::BuiltinType::OCLIntelSubgroupAVCRefPayload:
+ case clang::BuiltinType::OCLIntelSubgroupAVCSicPayload:
+ case clang::BuiltinType::OCLIntelSubgroupAVCMceResult:
+ case clang::BuiltinType::OCLIntelSubgroupAVCImeResult:
+ case clang::BuiltinType::OCLIntelSubgroupAVCRefResult:
+ case clang::BuiltinType::OCLIntelSubgroupAVCSicResult:
+ case clang::BuiltinType::OCLIntelSubgroupAVCImeResultSingleRefStreamout:
+ case clang::BuiltinType::OCLIntelSubgroupAVCImeResultDualRefStreamout:
+ case clang::BuiltinType::OCLIntelSubgroupAVCImeSingleRefStreamin:
+ case clang::BuiltinType::OCLIntelSubgroupAVCImeDualRefStreamin:
+ break;
}
break;
// All pointer types are represented as unsigned integer encodings. We may
@@ -5319,8 +5531,20 @@ static bool ObjCDeclHasIVars(clang::ObjCInterfaceDecl *class_interface_decl,
return false;
}
+static Optional<SymbolFile::ArrayInfo>
+GetDynamicArrayInfo(ClangASTContext &ast, SymbolFile *sym_file,
+ clang::QualType qual_type,
+ const ExecutionContext *exe_ctx) {
+ if (qual_type->isIncompleteArrayType())
+ if (auto *metadata = ast.GetMetadata(qual_type.getAsOpaquePtr()))
+ return sym_file->GetDynamicArrayInfoForUID(metadata->GetUserID(),
+ exe_ctx);
+ return llvm::None;
+}
+
uint32_t ClangASTContext::GetNumChildren(lldb::opaque_compiler_type_t type,
- bool omit_empty_base_classes) {
+ bool omit_empty_base_classes,
+ const ExecutionContext *exe_ctx) {
if (!type)
return 0;
@@ -5342,7 +5566,6 @@ uint32_t ClangASTContext::GetNumChildren(lldb::opaque_compiler_type_t type,
case clang::Type::Complex:
return 0;
-
case clang::Type::Record:
if (GetCompleteQualType(getASTContext(), qual_type)) {
const clang::RecordType *record_type =
@@ -5368,7 +5591,7 @@ uint32_t ClangASTContext::GetNumChildren(lldb::opaque_compiler_type_t type,
->getDecl());
// Skip empty base classes
- if (ClangASTContext::RecordHasFields(base_class_decl) == false)
+ if (!ClangASTContext::RecordHasFields(base_class_decl))
continue;
num_children++;
@@ -5420,7 +5643,7 @@ uint32_t ClangASTContext::GetNumChildren(lldb::opaque_compiler_type_t type,
clang::QualType pointee_type = pointer_type->getPointeeType();
uint32_t num_pointee_children =
CompilerType(getASTContext(), pointee_type)
- .GetNumChildren(omit_empty_base_classes);
+ .GetNumChildren(omit_empty_base_classes, exe_ctx);
// If this type points to a simple type, then it has 1 child
if (num_pointee_children == 0)
num_children = 1;
@@ -5439,6 +5662,14 @@ uint32_t ClangASTContext::GetNumChildren(lldb::opaque_compiler_type_t type,
->getSize()
.getLimitedValue();
break;
+ case clang::Type::IncompleteArray:
+ if (auto array_info =
+ GetDynamicArrayInfo(*this, GetSymbolFile(), qual_type, exe_ctx))
+ // Only 1-dimensional arrays are supported.
+ num_children = array_info->element_orders.size()
+ ? array_info->element_orders.back()
+ : 0;
+ break;
case clang::Type::Pointer: {
const clang::PointerType *pointer_type =
@@ -5446,7 +5677,7 @@ uint32_t ClangASTContext::GetNumChildren(lldb::opaque_compiler_type_t type,
clang::QualType pointee_type(pointer_type->getPointeeType());
uint32_t num_pointee_children =
CompilerType(getASTContext(), pointee_type)
- .GetNumChildren(omit_empty_base_classes);
+ .GetNumChildren(omit_empty_base_classes, exe_ctx);
if (num_pointee_children == 0) {
// We have a pointer to a pointee type that claims it has no children. We
// will want to look at
@@ -5462,7 +5693,7 @@ uint32_t ClangASTContext::GetNumChildren(lldb::opaque_compiler_type_t type,
clang::QualType pointee_type = reference_type->getPointeeType();
uint32_t num_pointee_children =
CompilerType(getASTContext(), pointee_type)
- .GetNumChildren(omit_empty_base_classes);
+ .GetNumChildren(omit_empty_base_classes, exe_ctx);
// If this type points to a simple type, then it has 1 child
if (num_pointee_children == 0)
num_children = 1;
@@ -5475,14 +5706,14 @@ uint32_t ClangASTContext::GetNumChildren(lldb::opaque_compiler_type_t type,
CompilerType(getASTContext(), llvm::cast<clang::TypedefType>(qual_type)
->getDecl()
->getUnderlyingType())
- .GetNumChildren(omit_empty_base_classes);
+ .GetNumChildren(omit_empty_base_classes, exe_ctx);
break;
case clang::Type::Auto:
num_children =
CompilerType(getASTContext(),
llvm::cast<clang::AutoType>(qual_type)->getDeducedType())
- .GetNumChildren(omit_empty_base_classes);
+ .GetNumChildren(omit_empty_base_classes, exe_ctx);
break;
case clang::Type::Elaborated:
@@ -5490,14 +5721,14 @@ uint32_t ClangASTContext::GetNumChildren(lldb::opaque_compiler_type_t type,
CompilerType(
getASTContext(),
llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType())
- .GetNumChildren(omit_empty_base_classes);
+ .GetNumChildren(omit_empty_base_classes, exe_ctx);
break;
case clang::Type::Paren:
num_children =
CompilerType(getASTContext(),
llvm::cast<clang::ParenType>(qual_type)->desugar())
- .GetNumChildren(omit_empty_base_classes);
+ .GetNumChildren(omit_empty_base_classes, exe_ctx);
break;
default:
break;
@@ -5735,10 +5966,10 @@ GetObjCFieldAtIndex(clang::ASTContext *ast,
if (is_bitfield && ast) {
clang::Expr *bitfield_bit_size_expr = ivar_pos->getBitWidth();
- llvm::APSInt bitfield_apsint;
+ clang::Expr::EvalResult result;
if (bitfield_bit_size_expr &&
- bitfield_bit_size_expr->EvaluateAsInt(bitfield_apsint,
- *ast)) {
+ bitfield_bit_size_expr->EvaluateAsInt(result, *ast)) {
+ llvm::APSInt bitfield_apsint = result.Val.getInt();
*bitfield_bit_size_ptr = bitfield_apsint.getLimitedValue();
}
}
@@ -5795,10 +6026,11 @@ CompilerType ClangASTContext::GetFieldAtIndex(lldb::opaque_compiler_type_t type,
if (is_bitfield) {
clang::Expr *bitfield_bit_size_expr = field->getBitWidth();
- llvm::APSInt bitfield_apsint;
+ clang::Expr::EvalResult result;
if (bitfield_bit_size_expr &&
- bitfield_bit_size_expr->EvaluateAsInt(bitfield_apsint,
+ bitfield_bit_size_expr->EvaluateAsInt(result,
*getASTContext())) {
+ llvm::APSInt bitfield_apsint = result.Val.getInt();
*bitfield_bit_size_ptr = bitfield_apsint.getLimitedValue();
}
}
@@ -6366,6 +6598,10 @@ CompilerType ClangASTContext::GetChildCompilerTypeAtIndex(
if (!type)
return CompilerType();
+ auto get_exe_scope = [&exe_ctx]() {
+ return exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr;
+ };
+
clang::QualType parent_qual_type(GetCanonicalQualType(type));
const clang::Type::TypeClass parent_type_class =
parent_qual_type->getTypeClass();
@@ -6374,8 +6610,9 @@ CompilerType ClangASTContext::GetChildCompilerTypeAtIndex(
child_is_base_class = false;
language_flags = 0;
- const bool idx_is_valid = idx < GetNumChildren(type, omit_empty_base_classes);
- uint32_t bit_offset;
+ const bool idx_is_valid =
+ idx < GetNumChildren(type, omit_empty_base_classes, exe_ctx);
+ int32_t bit_offset;
switch (parent_type_class) {
case clang::Type::Builtin:
if (idx_is_valid) {
@@ -6420,7 +6657,7 @@ CompilerType ClangASTContext::GetChildCompilerTypeAtIndex(
if (omit_empty_base_classes) {
base_class_decl = llvm::cast<clang::CXXRecordDecl>(
base_class->getType()->getAs<clang::RecordType>()->getDecl());
- if (ClangASTContext::RecordHasFields(base_class_decl) == false)
+ if (!ClangASTContext::RecordHasFields(base_class_decl))
continue;
}
@@ -6432,80 +6669,12 @@ CompilerType ClangASTContext::GetChildCompilerTypeAtIndex(
if (base_class->isVirtual()) {
bool handled = false;
if (valobj) {
- Status err;
- AddressType addr_type = eAddressTypeInvalid;
- lldb::addr_t vtable_ptr_addr =
- valobj->GetCPPVTableAddress(addr_type);
-
- if (vtable_ptr_addr != LLDB_INVALID_ADDRESS &&
- addr_type == eAddressTypeLoad) {
-
- ExecutionContext exe_ctx(valobj->GetExecutionContextRef());
- Process *process = exe_ctx.GetProcessPtr();
- if (process) {
- clang::VTableContextBase *vtable_ctx =
- getASTContext()->getVTableContext();
- if (vtable_ctx) {
- if (vtable_ctx->isMicrosoft()) {
- clang::MicrosoftVTableContext *msoft_vtable_ctx =
- static_cast<clang::MicrosoftVTableContext *>(
- vtable_ctx);
-
- if (vtable_ptr_addr) {
- const lldb::addr_t vbtable_ptr_addr =
- vtable_ptr_addr +
- record_layout.getVBPtrOffset().getQuantity();
-
- const lldb::addr_t vbtable_ptr =
- process->ReadPointerFromMemory(vbtable_ptr_addr,
- err);
- if (vbtable_ptr != LLDB_INVALID_ADDRESS) {
- // Get the index into the virtual base table. The
- // index is the index in uint32_t from vbtable_ptr
- const unsigned vbtable_index =
- msoft_vtable_ctx->getVBTableIndex(
- cxx_record_decl, base_class_decl);
- const lldb::addr_t base_offset_addr =
- vbtable_ptr + vbtable_index * 4;
- const uint32_t base_offset =
- process->ReadUnsignedIntegerFromMemory(
- base_offset_addr, 4, UINT32_MAX, err);
- if (base_offset != UINT32_MAX) {
- handled = true;
- bit_offset = base_offset * 8;
- }
- }
- }
- } else {
- clang::ItaniumVTableContext *itanium_vtable_ctx =
- static_cast<clang::ItaniumVTableContext *>(
- vtable_ctx);
- if (vtable_ptr_addr) {
- const lldb::addr_t vtable_ptr =
- process->ReadPointerFromMemory(vtable_ptr_addr,
- err);
- if (vtable_ptr != LLDB_INVALID_ADDRESS) {
- clang::CharUnits base_offset_offset =
- itanium_vtable_ctx->getVirtualBaseOffsetOffset(
- cxx_record_decl, base_class_decl);
- const lldb::addr_t base_offset_addr =
- vtable_ptr + base_offset_offset.getQuantity();
- const uint32_t base_offset_size =
- process->GetAddressByteSize();
- const uint64_t base_offset =
- process->ReadUnsignedIntegerFromMemory(
- base_offset_addr, base_offset_size,
- UINT32_MAX, err);
- if (base_offset < UINT32_MAX) {
- handled = true;
- bit_offset = base_offset * 8;
- }
- }
- }
- }
- }
- }
- }
+ clang::VTableContextBase *vtable_ctx =
+ getASTContext()->getVTableContext();
+ if (vtable_ctx)
+ handled = GetVBaseBitOffset(*vtable_ctx, *valobj,
+ record_layout, cxx_record_decl,
+ base_class_decl, bit_offset);
}
if (!handled)
bit_offset = record_layout.getVBaseClassOffset(base_class_decl)
@@ -6521,9 +6690,11 @@ CompilerType ClangASTContext::GetChildCompilerTypeAtIndex(
CompilerType base_class_clang_type(getASTContext(),
base_class->getType());
child_name = base_class_clang_type.GetTypeName().AsCString("");
- uint64_t base_class_clang_type_bit_size =
- base_class_clang_type.GetBitSize(
- exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL);
+ Optional<uint64_t> size =
+ base_class_clang_type.GetBitSize(get_exe_scope());
+ if (!size)
+ return {};
+ uint64_t base_class_clang_type_bit_size = *size;
// Base classes bit sizes should be a multiple of 8 bits in size
assert(base_class_clang_type_bit_size % 8 == 0);
@@ -6551,8 +6722,11 @@ CompilerType ClangASTContext::GetChildCompilerTypeAtIndex(
// alignment (field_type_info.second) from the AST context.
CompilerType field_clang_type(getASTContext(), field->getType());
assert(field_idx < record_layout.getFieldCount());
- child_byte_size = field_clang_type.GetByteSize(
- exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL);
+ Optional<uint64_t> size =
+ field_clang_type.GetByteSize(get_exe_scope());
+ if (!size)
+ return {};
+ child_byte_size = *size;
const uint32_t child_bit_size = child_byte_size * 8;
// Figure out the field offset within the current struct/union/class
@@ -6596,8 +6770,8 @@ CompilerType ClangASTContext::GetChildCompilerTypeAtIndex(
CompilerType base_class_clang_type(
getASTContext(), getASTContext()->getObjCInterfaceType(
superclass_interface_decl));
- if (base_class_clang_type.GetNumChildren(
- omit_empty_base_classes) > 0) {
+ if (base_class_clang_type.GetNumChildren(omit_empty_base_classes,
+ exe_ctx) > 0) {
if (idx == 0) {
clang::QualType ivar_qual_type(
getASTContext()->getObjCInterfaceType(
@@ -6664,9 +6838,9 @@ CompilerType ClangASTContext::GetChildCompilerTypeAtIndex(
}
}
- // Setting this to UINT32_MAX to make sure we don't compute it
+ // Setting this to INT32_MAX to make sure we don't compute it
// twice...
- bit_offset = UINT32_MAX;
+ bit_offset = INT32_MAX;
if (child_byte_offset ==
static_cast<int32_t>(LLDB_INVALID_IVAR_OFFSET)) {
@@ -6683,7 +6857,7 @@ CompilerType ClangASTContext::GetChildCompilerTypeAtIndex(
if (ClangASTContext::FieldIsBitfield(getASTContext(), ivar_decl,
child_bitfield_bit_size)) {
- if (bit_offset == UINT32_MAX)
+ if (bit_offset == INT32_MAX)
bit_offset = interface_layout.getFieldOffset(
child_idx - superclass_idx);
@@ -6723,10 +6897,12 @@ CompilerType ClangASTContext::GetChildCompilerTypeAtIndex(
// We have a pointer to an simple type
if (idx == 0 && pointee_clang_type.GetCompleteType()) {
- child_byte_size = pointee_clang_type.GetByteSize(
- exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL);
- child_byte_offset = 0;
- return pointee_clang_type;
+ if (Optional<uint64_t> size =
+ pointee_clang_type.GetByteSize(get_exe_scope())) {
+ child_byte_size = *size;
+ child_byte_offset = 0;
+ return pointee_clang_type;
+ }
}
}
}
@@ -6744,10 +6920,12 @@ CompilerType ClangASTContext::GetChildCompilerTypeAtIndex(
::snprintf(element_name, sizeof(element_name), "[%" PRIu64 "]",
static_cast<uint64_t>(idx));
child_name.assign(element_name);
- child_byte_size = element_type.GetByteSize(
- exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL);
- child_byte_offset = (int32_t)idx * (int32_t)child_byte_size;
- return element_type;
+ if (Optional<uint64_t> size =
+ element_type.GetByteSize(get_exe_scope())) {
+ child_byte_size = *size;
+ child_byte_offset = (int32_t)idx * (int32_t)child_byte_size;
+ return element_type;
+ }
}
}
}
@@ -6761,10 +6939,12 @@ CompilerType ClangASTContext::GetChildCompilerTypeAtIndex(
CompilerType element_type(getASTContext(), array->getElementType());
if (element_type.GetCompleteType()) {
child_name = llvm::formatv("[{0}]", idx);
- child_byte_size = element_type.GetByteSize(
- exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL);
- child_byte_offset = (int32_t)idx * (int32_t)child_byte_size;
- return element_type;
+ if (Optional<uint64_t> size =
+ element_type.GetByteSize(get_exe_scope())) {
+ child_byte_size = *size;
+ child_byte_offset = (int32_t)idx * (int32_t)child_byte_size;
+ return element_type;
+ }
}
}
}
@@ -6798,10 +6978,12 @@ CompilerType ClangASTContext::GetChildCompilerTypeAtIndex(
// We have a pointer to an simple type
if (idx == 0) {
- child_byte_size = pointee_clang_type.GetByteSize(
- exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL);
- child_byte_offset = 0;
- return pointee_clang_type;
+ if (Optional<uint64_t> size =
+ pointee_clang_type.GetByteSize(get_exe_scope())) {
+ child_byte_size = *size;
+ child_byte_offset = 0;
+ return pointee_clang_type;
+ }
}
}
break;
@@ -6833,10 +7015,12 @@ CompilerType ClangASTContext::GetChildCompilerTypeAtIndex(
// We have a pointer to an simple type
if (idx == 0) {
- child_byte_size = pointee_clang_type.GetByteSize(
- exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL);
- child_byte_offset = 0;
- return pointee_clang_type;
+ if (Optional<uint64_t> size =
+ pointee_clang_type.GetByteSize(get_exe_scope())) {
+ child_byte_size = *size;
+ child_byte_offset = 0;
+ return pointee_clang_type;
+ }
}
}
}
@@ -7283,14 +7467,14 @@ ClangASTContext::GetIndexOfChildWithName(lldb::opaque_compiler_type_t type,
->getAs<clang::RecordType>()
->getDecl());
if (omit_empty_base_classes &&
- ClangASTContext::RecordHasFields(base_class_decl) == false)
+ !ClangASTContext::RecordHasFields(base_class_decl))
continue;
CompilerType base_class_clang_type(getASTContext(),
base_class->getType());
std::string base_class_type_name(
base_class_clang_type.GetTypeName().AsCString(""));
- if (base_class_type_name.compare(name) == 0)
+ if (base_class_type_name == name)
return child_idx;
++child_idx;
}
@@ -7625,7 +7809,7 @@ ClangASTContext::GetTypeTemplateArgument(lldb::opaque_compiler_type_t type,
return CompilerType(getASTContext(), template_arg.getAsType());
}
-llvm::Optional<CompilerType::IntegralTemplateArgument>
+Optional<CompilerType::IntegralTemplateArgument>
ClangASTContext::GetIntegralTemplateArgument(lldb::opaque_compiler_type_t type,
size_t idx) {
const clang::ClassTemplateSpecializationDecl *template_decl =
@@ -7665,11 +7849,16 @@ clang::RecordDecl *ClangASTContext::GetAsRecordDecl(const CompilerType &type) {
}
clang::TagDecl *ClangASTContext::GetAsTagDecl(const CompilerType &type) {
- clang::QualType qual_type = ClangUtil::GetCanonicalQualType(type);
- if (qual_type.isNull())
- return nullptr;
- else
- return qual_type->getAsTagDecl();
+ return ClangUtil::GetAsTagDecl(type);
+}
+
+clang::TypedefNameDecl *
+ClangASTContext::GetAsTypedefDecl(const CompilerType &type) {
+ const clang::TypedefType *typedef_type =
+ llvm::dyn_cast<clang::TypedefType>(ClangUtil::GetQualType(type));
+ if (typedef_type)
+ return typedef_type->getDecl();
+ return nullptr;
}
clang::CXXRecordDecl *
@@ -7688,7 +7877,7 @@ ClangASTContext::GetAsObjCInterfaceDecl(const CompilerType &type) {
}
clang::FieldDecl *ClangASTContext::AddFieldToRecordType(
- const CompilerType &type, const char *name,
+ const CompilerType &type, llvm::StringRef name,
const CompilerType &field_clang_type, AccessType access,
uint32_t bitfield_bit_size) {
if (!type.IsValid() || !field_clang_type.IsValid())
@@ -7698,6 +7887,9 @@ clang::FieldDecl *ClangASTContext::AddFieldToRecordType(
if (!ast)
return nullptr;
clang::ASTContext *clang_ast = ast->getASTContext();
+ clang::IdentifierInfo *ident = nullptr;
+ if (!name.empty())
+ ident = &clang_ast->Idents.get(name);
clang::FieldDecl *field = nullptr;
@@ -7715,14 +7907,14 @@ clang::FieldDecl *ClangASTContext::AddFieldToRecordType(
field = clang::FieldDecl::Create(
*clang_ast, record_decl, clang::SourceLocation(),
clang::SourceLocation(),
- name ? &clang_ast->Idents.get(name) : nullptr, // Identifier
- ClangUtil::GetQualType(field_clang_type), // Field type
- nullptr, // TInfo *
- bit_width, // BitWidth
- false, // Mutable
- clang::ICIS_NoInit); // HasInit
-
- if (!name) {
+ ident, // Identifier
+ ClangUtil::GetQualType(field_clang_type), // Field type
+ nullptr, // TInfo *
+ bit_width, // BitWidth
+ false, // Mutable
+ clang::ICIS_NoInit); // HasInit
+
+ if (name.empty()) {
// Determine whether this field corresponds to an anonymous struct or
// union.
if (const clang::TagType *TagT =
@@ -7758,9 +7950,9 @@ clang::FieldDecl *ClangASTContext::AddFieldToRecordType(
field = clang::ObjCIvarDecl::Create(
*clang_ast, class_interface_decl, clang::SourceLocation(),
clang::SourceLocation(),
- name ? &clang_ast->Idents.get(name) : nullptr, // Identifier
- ClangUtil::GetQualType(field_clang_type), // Field type
- nullptr, // TypeSourceInfo *
+ ident, // Identifier
+ ClangUtil::GetQualType(field_clang_type), // Field type
+ nullptr, // TypeSourceInfo *
ConvertAccessTypeToObjCIvarAccessControl(access), bit_width,
is_synthesized);
@@ -7899,38 +8091,44 @@ void ClangASTContext::SetIsPacked(const CompilerType &type) {
}
clang::VarDecl *ClangASTContext::AddVariableToRecordType(
- const CompilerType &type, const char *name, const CompilerType &var_type,
- AccessType access) {
- clang::VarDecl *var_decl = nullptr;
-
+ const CompilerType &type, llvm::StringRef name,
+ const CompilerType &var_type, AccessType access) {
if (!type.IsValid() || !var_type.IsValid())
return nullptr;
+
ClangASTContext *ast = llvm::dyn_cast<ClangASTContext>(type.GetTypeSystem());
if (!ast)
return nullptr;
clang::RecordDecl *record_decl = ast->GetAsRecordDecl(type);
- if (record_decl) {
- var_decl = clang::VarDecl::Create(
- *ast->getASTContext(), // ASTContext &
- record_decl, // DeclContext *
- clang::SourceLocation(), // clang::SourceLocation StartLoc
- clang::SourceLocation(), // clang::SourceLocation IdLoc
- name ? &ast->getASTContext()->Idents.get(name)
- : nullptr, // clang::IdentifierInfo *
- ClangUtil::GetQualType(var_type), // Variable clang::QualType
- nullptr, // TypeSourceInfo *
- clang::SC_Static); // StorageClass
- if (var_decl) {
- var_decl->setAccess(
- ClangASTContext::ConvertAccessTypeToAccessSpecifier(access));
- record_decl->addDecl(var_decl);
+ if (!record_decl)
+ return nullptr;
+
+ clang::VarDecl *var_decl = nullptr;
+ clang::IdentifierInfo *ident = nullptr;
+ if (!name.empty())
+ ident = &ast->getASTContext()->Idents.get(name);
+
+ var_decl = clang::VarDecl::Create(
+ *ast->getASTContext(), // ASTContext &
+ record_decl, // DeclContext *
+ clang::SourceLocation(), // clang::SourceLocation StartLoc
+ clang::SourceLocation(), // clang::SourceLocation IdLoc
+ ident, // clang::IdentifierInfo *
+ ClangUtil::GetQualType(var_type), // Variable clang::QualType
+ nullptr, // TypeSourceInfo *
+ clang::SC_Static); // StorageClass
+ if (!var_decl)
+ return nullptr;
+
+ var_decl->setAccess(
+ ClangASTContext::ConvertAccessTypeToAccessSpecifier(access));
+ record_decl->addDecl(var_decl);
#ifdef LLDB_CONFIGURATION_DEBUG
- VerifyDecl(var_decl);
+ VerifyDecl(var_decl);
#endif
- }
- }
+
return var_decl;
}
@@ -8131,41 +8329,46 @@ clang::CXXMethodDecl *ClangASTContext::AddMethodToCXXRecordType(
return cxx_method_decl;
}
+void ClangASTContext::AddMethodOverridesForCXXRecordType(
+ lldb::opaque_compiler_type_t type) {
+ if (auto *record = GetAsCXXRecordDecl(type))
+ for (auto *method : record->methods())
+ addOverridesForMethod(method);
+}
+
#pragma mark C++ Base Classes
-clang::CXXBaseSpecifier *
+std::unique_ptr<clang::CXXBaseSpecifier>
ClangASTContext::CreateBaseClassSpecifier(lldb::opaque_compiler_type_t type,
AccessType access, bool is_virtual,
bool base_of_class) {
- if (type)
- return new clang::CXXBaseSpecifier(
- clang::SourceRange(), is_virtual, base_of_class,
- ClangASTContext::ConvertAccessTypeToAccessSpecifier(access),
- getASTContext()->getTrivialTypeSourceInfo(GetQualType(type)),
- clang::SourceLocation());
- return nullptr;
-}
+ if (!type)
+ return nullptr;
-void ClangASTContext::DeleteBaseClassSpecifiers(
- clang::CXXBaseSpecifier **base_classes, unsigned num_base_classes) {
- for (unsigned i = 0; i < num_base_classes; ++i) {
- delete base_classes[i];
- base_classes[i] = nullptr;
- }
+ return llvm::make_unique<clang::CXXBaseSpecifier>(
+ clang::SourceRange(), is_virtual, base_of_class,
+ ClangASTContext::ConvertAccessTypeToAccessSpecifier(access),
+ getASTContext()->getTrivialTypeSourceInfo(GetQualType(type)),
+ clang::SourceLocation());
}
-bool ClangASTContext::SetBaseClassesForClassType(
+bool ClangASTContext::TransferBaseClasses(
lldb::opaque_compiler_type_t type,
- clang::CXXBaseSpecifier const *const *base_classes,
- unsigned num_base_classes) {
- if (type) {
- clang::CXXRecordDecl *cxx_record_decl = GetAsCXXRecordDecl(type);
- if (cxx_record_decl) {
- cxx_record_decl->setBases(base_classes, num_base_classes);
- return true;
- }
- }
- return false;
+ std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> bases) {
+ if (!type)
+ return false;
+ clang::CXXRecordDecl *cxx_record_decl = GetAsCXXRecordDecl(type);
+ if (!cxx_record_decl)
+ return false;
+ std::vector<clang::CXXBaseSpecifier *> raw_bases;
+ raw_bases.reserve(bases.size());
+
+ // Clang will make a copy of them, so it's ok that we pass pointers that we're
+ // about to destroy.
+ for (auto &b : bases)
+ raw_bases.push_back(b.get());
+ cxx_record_decl->setBases(raw_bases.data(), raw_bases.size());
+ return true;
}
bool ClangASTContext::SetObjCSuperClass(
@@ -8750,44 +8953,63 @@ bool ClangASTContext::CompleteTagDeclarationDefinition(
return false;
}
-bool ClangASTContext::AddEnumerationValueToEnumerationType(
- lldb::opaque_compiler_type_t type,
- const CompilerType &enumerator_clang_type, const Declaration &decl,
- const char *name, int64_t enum_value, uint32_t enum_value_bit_size) {
- if (type && enumerator_clang_type.IsValid() && name && name[0]) {
- clang::QualType enum_qual_type(GetCanonicalQualType(type));
-
- bool is_signed = false;
- enumerator_clang_type.IsIntegerType(is_signed);
- const clang::Type *clang_type = enum_qual_type.getTypePtr();
- if (clang_type) {
- const clang::EnumType *enutype =
- llvm::dyn_cast<clang::EnumType>(clang_type);
-
- if (enutype) {
- llvm::APSInt enum_llvm_apsint(enum_value_bit_size, is_signed);
- enum_llvm_apsint = enum_value;
- clang::EnumConstantDecl *enumerator_decl =
- clang::EnumConstantDecl::Create(
- *getASTContext(), enutype->getDecl(), clang::SourceLocation(),
- name ? &getASTContext()->Idents.get(name)
- : nullptr, // Identifier
- ClangUtil::GetQualType(enumerator_clang_type),
- nullptr, enum_llvm_apsint);
-
- if (enumerator_decl) {
- enutype->getDecl()->addDecl(enumerator_decl);
+clang::EnumConstantDecl *ClangASTContext::AddEnumerationValueToEnumerationType(
+ const CompilerType &enum_type, const Declaration &decl, const char *name,
+ const llvm::APSInt &value) {
+
+ if (!enum_type || ConstString(name).IsEmpty())
+ return nullptr;
+
+ lldbassert(enum_type.GetTypeSystem() == static_cast<TypeSystem *>(this));
+
+ lldb::opaque_compiler_type_t enum_opaque_compiler_type =
+ enum_type.GetOpaqueQualType();
+
+ if (!enum_opaque_compiler_type)
+ return nullptr;
+
+ clang::QualType enum_qual_type(
+ GetCanonicalQualType(enum_opaque_compiler_type));
+
+ const clang::Type *clang_type = enum_qual_type.getTypePtr();
+
+ if (!clang_type)
+ return nullptr;
+
+ const clang::EnumType *enutype = llvm::dyn_cast<clang::EnumType>(clang_type);
+
+ if (!enutype)
+ return nullptr;
+
+ clang::EnumConstantDecl *enumerator_decl = clang::EnumConstantDecl::Create(
+ *getASTContext(), enutype->getDecl(), clang::SourceLocation(),
+ name ? &getASTContext()->Idents.get(name) : nullptr, // Identifier
+ clang::QualType(enutype, 0), nullptr, value);
+
+ if (!enumerator_decl)
+ return nullptr;
+
+ enutype->getDecl()->addDecl(enumerator_decl);
#ifdef LLDB_CONFIGURATION_DEBUG
- VerifyDecl(enumerator_decl);
+ VerifyDecl(enumerator_decl);
#endif
- return true;
- }
- }
- }
- }
- return false;
+ return enumerator_decl;
+}
+
+clang::EnumConstantDecl *ClangASTContext::AddEnumerationValueToEnumerationType(
+ const CompilerType &enum_type, const Declaration &decl, const char *name,
+ int64_t enum_value, uint32_t enum_value_bit_size) {
+ CompilerType underlying_type =
+ GetEnumerationIntegerType(enum_type.GetOpaqueQualType());
+ bool is_signed = false;
+ underlying_type.IsIntegerType(is_signed);
+
+ llvm::APSInt value(enum_value_bit_size, is_signed);
+ value = enum_value;
+
+ return AddEnumerationValueToEnumerationType(enum_type, decl, name, value);
}
CompilerType
@@ -8861,6 +9083,11 @@ ClangASTContext::ConvertStringToFloatValue(lldb::opaque_compiler_type_t type,
//----------------------------------------------------------------------
#define DEPTH_INCREMENT 2
+void ClangASTContext::Dump(Stream &s) {
+ Decl *tu = Decl::castFromDeclContext(GetTranslationUnitDecl());
+ tu->dump(s.AsRawOstream());
+}
+
void ClangASTContext::DumpValue(
lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, Stream *s,
lldb::Format format, const DataExtractor &data,
@@ -8898,8 +9125,7 @@ void ClangASTContext::DumpValue(
base_class->getType()->getAs<clang::RecordType>()->getDecl());
// Skip empty base classes
- if (verbose == false &&
- ClangASTContext::RecordHasFields(base_class_decl) == false)
+ if (!verbose && !ClangASTContext::RecordHasFields(base_class_decl))
continue;
if (base_class->isVirtual())
@@ -9672,11 +9898,16 @@ bool ClangASTContext::LayoutRecordType(
llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
&vbase_offsets) {
ClangASTContext *ast = (ClangASTContext *)baton;
- DWARFASTParserClang *dwarf_ast_parser =
- (DWARFASTParserClang *)ast->GetDWARFParser();
- return dwarf_ast_parser->GetClangASTImporter().LayoutRecordType(
- record_decl, bit_size, alignment, field_offsets, base_offsets,
- vbase_offsets);
+ lldb_private::ClangASTImporter *importer = nullptr;
+ if (ast->m_dwarf_ast_parser_ap)
+ importer = &ast->m_dwarf_ast_parser_ap->GetClangASTImporter();
+ if (!importer && ast->m_pdb_ast_parser_ap)
+ importer = &ast->m_pdb_ast_parser_ap->GetClangASTImporter();
+ if (!importer)
+ return false;
+
+ return importer->LayoutRecordType(record_decl, bit_size, alignment,
+ field_offsets, base_offsets, vbase_offsets);
}
//----------------------------------------------------------------------