summaryrefslogtreecommitdiff
path: root/source/Symbol
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2016-07-23 20:50:09 +0000
committerDimitry Andric <dim@FreeBSD.org>2016-07-23 20:50:09 +0000
commitf3fbd1c0586ff6ec7895991e6c28f61a503c36a8 (patch)
tree48d008fd3df8c0e73271a4b18474e0aac6dbfe33 /source/Symbol
parent2fc5d2d1dfaf623ce4e24cd8590565902f8c557c (diff)
Notes
Diffstat (limited to 'source/Symbol')
-rw-r--r--source/Symbol/ArmUnwindInfo.cpp2
-rw-r--r--source/Symbol/Block.cpp37
-rw-r--r--source/Symbol/CMakeLists.txt2
-rw-r--r--source/Symbol/ClangASTContext.cpp1360
-rw-r--r--source/Symbol/ClangASTImporter.cpp267
-rw-r--r--source/Symbol/ClangExternalASTSourceCommon.cpp6
-rw-r--r--source/Symbol/ClangUtil.cpp58
-rw-r--r--source/Symbol/CompactUnwindInfo.cpp520
-rw-r--r--source/Symbol/CompileUnit.cpp63
-rw-r--r--source/Symbol/CompilerDecl.cpp6
-rw-r--r--source/Symbol/CompilerDeclContext.cpp5
-rw-r--r--source/Symbol/CompilerType.cpp21
-rw-r--r--source/Symbol/DWARFCallFrameInfo.cpp52
-rw-r--r--source/Symbol/FuncUnwinders.cpp142
-rw-r--r--source/Symbol/Function.cpp44
-rw-r--r--source/Symbol/GoASTContext.cpp6
-rw-r--r--source/Symbol/JavaASTContext.cpp1561
-rw-r--r--source/Symbol/LineEntry.cpp16
-rw-r--r--source/Symbol/LineTable.cpp5
-rw-r--r--source/Symbol/Makefile14
-rw-r--r--source/Symbol/ObjectFile.cpp30
-rw-r--r--source/Symbol/Symbol.cpp7
-rw-r--r--source/Symbol/SymbolContext.cpp72
-rw-r--r--source/Symbol/SymbolFile.cpp2
-rw-r--r--source/Symbol/SymbolVendor.cpp70
-rw-r--r--source/Symbol/Symtab.cpp256
-rw-r--r--source/Symbol/Type.cpp8
-rw-r--r--source/Symbol/TypeSystem.cpp59
-rw-r--r--source/Symbol/UnwindPlan.cpp25
-rw-r--r--source/Symbol/UnwindTable.cpp28
-rw-r--r--source/Symbol/Variable.cpp37
31 files changed, 3743 insertions, 1038 deletions
diff --git a/source/Symbol/ArmUnwindInfo.cpp b/source/Symbol/ArmUnwindInfo.cpp
index 0d3e974bebbe..95207cbe320d 100644
--- a/source/Symbol/ArmUnwindInfo.cpp
+++ b/source/Symbol/ArmUnwindInfo.cpp
@@ -103,7 +103,7 @@ ArmUnwindInfo::GetULEB128(const uint32_t* data, uint16_t& offset, uint16_t max_o
while (offset < max_offset)
{
uint8_t byte = GetByteAtOffset(data, offset++);
- result |= (byte & 0x7f) << shift;
+ result |= (uint64_t)(byte & 0x7f) << shift;
if ((byte & 0x80) == 0)
break;
shift += 7;
diff --git a/source/Symbol/Block.cpp b/source/Symbol/Block.cpp
index dfe9217362bd..9d50c5cb7c9a 100644
--- a/source/Symbol/Block.cpp
+++ b/source/Symbol/Block.cpp
@@ -486,16 +486,24 @@ uint32_t
Block::AppendBlockVariables (bool can_create,
bool get_child_block_variables,
bool stop_if_child_block_is_inlined_function,
+ const std::function<bool(Variable*)>& filter,
VariableList *variable_list)
{
uint32_t num_variables_added = 0;
VariableList *block_var_list = GetBlockVariableList (can_create).get();
if (block_var_list)
{
- num_variables_added += block_var_list->GetSize();
- variable_list->AddVariables (block_var_list);
+ for (size_t i = 0; i < block_var_list->GetSize(); ++i)
+ {
+ VariableSP variable = block_var_list->GetVariableAtIndex(i);
+ if (filter(variable.get()))
+ {
+ num_variables_added++;
+ variable_list->AddVariable(variable);
+ }
+ }
}
-
+
if (get_child_block_variables)
{
collection::const_iterator pos, end = m_children.end();
@@ -508,6 +516,7 @@ Block::AppendBlockVariables (bool can_create,
num_variables_added += child_block->AppendBlockVariables (can_create,
get_child_block_variables,
stop_if_child_block_is_inlined_function,
+ filter,
variable_list);
}
}
@@ -521,6 +530,7 @@ Block::AppendVariables
bool can_create,
bool get_parent_variables,
bool stop_if_block_is_inlined_function,
+ const std::function<bool(Variable*)>& filter,
VariableList *variable_list
)
{
@@ -528,12 +538,19 @@ Block::AppendVariables
VariableListSP variable_list_sp(GetBlockVariableList(can_create));
bool is_inlined_function = GetInlinedFunctionInfo() != nullptr;
- if (variable_list_sp.get())
+ if (variable_list_sp)
{
- num_variables_added = variable_list_sp->GetSize();
- variable_list->AddVariables(variable_list_sp.get());
+ for (size_t i = 0; i < variable_list_sp->GetSize(); ++i)
+ {
+ VariableSP variable = variable_list_sp->GetVariableAtIndex(i);
+ if (filter(variable.get()))
+ {
+ num_variables_added++;
+ variable_list->AddVariable(variable);
+ }
+ }
}
-
+
if (get_parent_variables)
{
if (stop_if_block_is_inlined_function && is_inlined_function)
@@ -541,7 +558,11 @@ Block::AppendVariables
Block* parent_block = GetParent();
if (parent_block)
- num_variables_added += parent_block->AppendVariables (can_create, get_parent_variables, stop_if_block_is_inlined_function, variable_list);
+ num_variables_added += parent_block->AppendVariables(can_create,
+ get_parent_variables,
+ stop_if_block_is_inlined_function,
+ filter,
+ variable_list);
}
return num_variables_added;
}
diff --git a/source/Symbol/CMakeLists.txt b/source/Symbol/CMakeLists.txt
index 6372fffde1f1..320a780dc98e 100644
--- a/source/Symbol/CMakeLists.txt
+++ b/source/Symbol/CMakeLists.txt
@@ -5,6 +5,7 @@ add_lldb_library(lldbSymbol
ClangASTImporter.cpp
ClangExternalASTSourceCallbacks.cpp
ClangExternalASTSourceCommon.cpp
+ ClangUtil.cpp
CompilerDecl.cpp
CompilerDeclContext.cpp
CompilerType.cpp
@@ -16,6 +17,7 @@ add_lldb_library(lldbSymbol
Function.cpp
FuncUnwinders.cpp
GoASTContext.cpp
+ JavaASTContext.cpp
LineEntry.cpp
LineTable.cpp
ObjectFile.cpp
diff --git a/source/Symbol/ClangASTContext.cpp b/source/Symbol/ClangASTContext.cpp
index 621bd1615f80..02882ef2ef4d 100644
--- a/source/Symbol/ClangASTContext.cpp
+++ b/source/Symbol/ClangASTContext.cpp
@@ -63,21 +63,24 @@
#include "llvm/Support/Signals.h"
+#include "Plugins/ExpressionParser/Clang/ClangFunctionCaller.h"
+#include "Plugins/ExpressionParser/Clang/ClangUserExpression.h"
+#include "Plugins/ExpressionParser/Clang/ClangUtilityFunction.h"
#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/Flags.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/RegularExpression.h"
+#include "lldb/Core/Scalar.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Core/ThreadSafeDenseMap.h"
#include "lldb/Core/UniqueCStringMap.h"
-#include "Plugins/ExpressionParser/Clang/ClangUserExpression.h"
-#include "Plugins/ExpressionParser/Clang/ClangFunctionCaller.h"
-#include "Plugins/ExpressionParser/Clang/ClangUtilityFunction.h"
#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Symbol/ClangASTImporter.h"
#include "lldb/Symbol/ClangExternalASTSourceCallbacks.h"
#include "lldb/Symbol/ClangExternalASTSourceCommon.h"
+#include "lldb/Symbol/ClangUtil.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Symbol/VerifyDecl.h"
@@ -86,8 +89,10 @@
#include "lldb/Target/ObjCLanguageRuntime.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
+#include "lldb/Utility/LLDBAssert.h"
#include "Plugins/SymbolFile/DWARF/DWARFASTParserClang.h"
+#include "Plugins/SymbolFile/PDB/PDBASTParser.h"
#include <stdio.h>
@@ -105,7 +110,10 @@ namespace
return language == eLanguageTypeUnknown || // Clang is the default type system
Language::LanguageIsC (language) ||
Language::LanguageIsCPlusPlus (language) ||
- Language::LanguageIsObjC (language);
+ Language::LanguageIsObjC (language) ||
+ // Use Clang for Rust until there is a proper language plugin for it
+ language == eLanguageTypeRust ||
+ language == eLanguageTypeExtRenderScript;
}
}
@@ -332,22 +340,7 @@ ClangASTContext::ClangASTContext (const char *target_triple) :
//----------------------------------------------------------------------
ClangASTContext::~ClangASTContext()
{
- if (m_ast_ap.get())
- {
- GetASTMap().Erase(m_ast_ap.get());
- if (!m_ast_owned)
- m_ast_ap.release();
- }
-
- m_builtins_ap.reset();
- m_selector_table_ap.reset();
- m_identifier_table_ap.reset();
- m_target_info_ap.reset();
- m_target_options_rp.reset();
- m_diagnostics_engine_ap.reset();
- m_source_manager_ap.reset();
- m_language_options_ap.reset();
- m_ast_ap.reset();
+ Finalize();
}
ConstString
@@ -471,6 +464,27 @@ ClangASTContext::Terminate()
PluginManager::UnregisterPlugin (CreateInstance);
}
+void
+ClangASTContext::Finalize()
+{
+ if (m_ast_ap.get())
+ {
+ GetASTMap().Erase(m_ast_ap.get());
+ if (!m_ast_owned)
+ m_ast_ap.release();
+ }
+
+ m_builtins_ap.reset();
+ m_selector_table_ap.reset();
+ m_identifier_table_ap.reset();
+ m_target_info_ap.reset();
+ m_target_options_rp.reset();
+ m_diagnostics_engine_ap.reset();
+ m_source_manager_ap.reset();
+ m_language_options_ap.reset();
+ m_ast_ap.reset();
+ m_scratch_ast_source_ap.reset();
+}
void
ClangASTContext::Clear()
@@ -678,8 +692,9 @@ public:
{
m_log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
}
-
- void HandleDiagnostic (DiagnosticsEngine::Level DiagLevel, const Diagnostic &info)
+
+ void
+ HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, const clang::Diagnostic &info)
{
if (m_log)
{
@@ -707,11 +722,11 @@ ClangASTContext::getDiagnosticConsumer()
return m_diagnostic_consumer_ap.get();
}
-std::shared_ptr<TargetOptions> &
+std::shared_ptr<clang::TargetOptions> &
ClangASTContext::getTargetOptions() {
if (m_target_options_rp.get() == nullptr && !m_target_triple.empty())
{
- m_target_options_rp = std::make_shared<TargetOptions>();
+ m_target_options_rp = std::make_shared<clang::TargetOptions>();
if (m_target_options_rp.get() != nullptr)
m_target_options_rp->Triple = m_target_triple;
}
@@ -773,8 +788,8 @@ ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (ASTContext *ast, Encoding
break;
case eEncodingSint:
- if (QualTypeMatchesBitSize (bit_size, ast, ast->CharTy))
- return CompilerType (ast, ast->CharTy);
+ if (QualTypeMatchesBitSize (bit_size, ast, ast->SignedCharTy))
+ return CompilerType (ast, ast->SignedCharTy);
if (QualTypeMatchesBitSize (bit_size, ast, ast->ShortTy))
return CompilerType (ast, ast->ShortTy);
if (QualTypeMatchesBitSize (bit_size, ast, ast->IntTy))
@@ -901,113 +916,12 @@ ClangASTContext::GetBasicType (lldb::BasicType basic_type)
CompilerType
ClangASTContext::GetBasicType (ASTContext *ast, lldb::BasicType basic_type)
{
- if (ast)
- {
- lldb::opaque_compiler_type_t clang_type = nullptr;
-
- switch (basic_type)
- {
- case eBasicTypeInvalid:
- case eBasicTypeOther:
- break;
- case eBasicTypeVoid:
- clang_type = ast->VoidTy.getAsOpaquePtr();
- break;
- case eBasicTypeChar:
- clang_type = ast->CharTy.getAsOpaquePtr();
- break;
- case eBasicTypeSignedChar:
- clang_type = ast->SignedCharTy.getAsOpaquePtr();
- break;
- case eBasicTypeUnsignedChar:
- clang_type = ast->UnsignedCharTy.getAsOpaquePtr();
- break;
- case eBasicTypeWChar:
- clang_type = ast->getWCharType().getAsOpaquePtr();
- break;
- case eBasicTypeSignedWChar:
- clang_type = ast->getSignedWCharType().getAsOpaquePtr();
- break;
- case eBasicTypeUnsignedWChar:
- clang_type = ast->getUnsignedWCharType().getAsOpaquePtr();
- break;
- case eBasicTypeChar16:
- clang_type = ast->Char16Ty.getAsOpaquePtr();
- break;
- case eBasicTypeChar32:
- clang_type = ast->Char32Ty.getAsOpaquePtr();
- break;
- case eBasicTypeShort:
- clang_type = ast->ShortTy.getAsOpaquePtr();
- break;
- case eBasicTypeUnsignedShort:
- clang_type = ast->UnsignedShortTy.getAsOpaquePtr();
- break;
- case eBasicTypeInt:
- clang_type = ast->IntTy.getAsOpaquePtr();
- break;
- case eBasicTypeUnsignedInt:
- clang_type = ast->UnsignedIntTy.getAsOpaquePtr();
- break;
- case eBasicTypeLong:
- clang_type = ast->LongTy.getAsOpaquePtr();
- break;
- case eBasicTypeUnsignedLong:
- clang_type = ast->UnsignedLongTy.getAsOpaquePtr();
- break;
- case eBasicTypeLongLong:
- clang_type = ast->LongLongTy.getAsOpaquePtr();
- break;
- case eBasicTypeUnsignedLongLong:
- clang_type = ast->UnsignedLongLongTy.getAsOpaquePtr();
- break;
- case eBasicTypeInt128:
- clang_type = ast->Int128Ty.getAsOpaquePtr();
- break;
- case eBasicTypeUnsignedInt128:
- clang_type = ast->UnsignedInt128Ty.getAsOpaquePtr();
- break;
- case eBasicTypeBool:
- clang_type = ast->BoolTy.getAsOpaquePtr();
- break;
- case eBasicTypeHalf:
- clang_type = ast->HalfTy.getAsOpaquePtr();
- break;
- case eBasicTypeFloat:
- clang_type = ast->FloatTy.getAsOpaquePtr();
- break;
- case eBasicTypeDouble:
- clang_type = ast->DoubleTy.getAsOpaquePtr();
- break;
- case eBasicTypeLongDouble:
- clang_type = ast->LongDoubleTy.getAsOpaquePtr();
- break;
- case eBasicTypeFloatComplex:
- clang_type = ast->FloatComplexTy.getAsOpaquePtr();
- break;
- case eBasicTypeDoubleComplex:
- clang_type = ast->DoubleComplexTy.getAsOpaquePtr();
- break;
- case eBasicTypeLongDoubleComplex:
- clang_type = ast->LongDoubleComplexTy.getAsOpaquePtr();
- break;
- case eBasicTypeObjCID:
- clang_type = ast->getObjCIdType().getAsOpaquePtr();
- break;
- case eBasicTypeObjCClass:
- clang_type = ast->getObjCClassType().getAsOpaquePtr();
- break;
- case eBasicTypeObjCSel:
- clang_type = ast->getObjCSelType().getAsOpaquePtr();
- break;
- case eBasicTypeNullPtr:
- clang_type = ast->NullPtrTy.getAsOpaquePtr();
- break;
- }
-
- if (clang_type)
- return CompilerType (GetASTContext(ast), clang_type);
- }
+ if (!ast)
+ return CompilerType();
+ lldb::opaque_compiler_type_t clang_type = GetOpaqueCompilerType(ast, basic_type);
+
+ if (clang_type)
+ return CompilerType(GetASTContext(ast), clang_type);
return CompilerType();
}
@@ -1049,7 +963,7 @@ ClangASTContext::GetBuiltinTypeForDWARFEncodingAndBitSize (const char *type_name
if (::strstr(type_name, "complex"))
{
CompilerType complex_int_clang_type = GetBuiltinTypeForDWARFEncodingAndBitSize ("int", DW_ATE_signed, bit_size/2);
- return CompilerType (ast, ast->getComplexType (GetQualType(complex_int_clang_type)));
+ return CompilerType(ast, ast->getComplexType(ClangUtil::GetQualType(complex_int_clang_type)));
}
}
break;
@@ -1064,7 +978,7 @@ ClangASTContext::GetBuiltinTypeForDWARFEncodingAndBitSize (const char *type_name
else
{
CompilerType complex_float_clang_type = GetBuiltinTypeForDWARFEncodingAndBitSize ("float", DW_ATE_float, bit_size/2);
- return CompilerType (ast, ast->getComplexType (GetQualType(complex_float_clang_type)));
+ return CompilerType(ast, ast->getComplexType(ClangUtil::GetQualType(complex_float_clang_type)));
}
break;
@@ -1294,9 +1208,9 @@ ClangASTContext::AreTypesSame (CompilerType type1,
if (type1.GetOpaqueQualType() == type2.GetOpaqueQualType())
return true;
- QualType type1_qual = GetQualType(type1);
- QualType type2_qual = GetQualType(type2);
-
+ QualType type1_qual = ClangUtil::GetQualType(type1);
+ QualType type2_qual = ClangUtil::GetQualType(type2);
+
if (ignore_qualifiers)
{
type1_qual = type1_qual.getUnqualifiedType();
@@ -1488,9 +1402,7 @@ ClangASTContext::CreateFunctionTemplateSpecializationInfo (FunctionDecl *func_de
clang::FunctionTemplateDecl *func_tmpl_decl,
const TemplateParameterInfos &infos)
{
- TemplateArgumentList template_args (TemplateArgumentList::OnStack,
- infos.args.data(),
- infos.args.size());
+ TemplateArgumentList template_args (TemplateArgumentList::OnStack, infos.args);
func_decl->setFunctionTemplateSpecialization (func_tmpl_decl,
&template_args,
@@ -1588,8 +1500,7 @@ ClangASTContext::CreateClassTemplateSpecializationDecl (DeclContext *decl_ctx,
SourceLocation(),
SourceLocation(),
class_template_decl,
- &template_param_infos.args.front(),
- template_param_infos.args.size(),
+ template_param_infos.args,
nullptr);
class_template_specialization_decl->setSpecializationKind(TSK_ExplicitSpecialization);
@@ -1652,25 +1563,14 @@ ClangASTContext::CheckOverloadedOperatorKindParameterCount (uint32_t op_kind, ui
clang::AccessSpecifier
ClangASTContext::UnifyAccessSpecifiers (clang::AccessSpecifier lhs, clang::AccessSpecifier rhs)
{
- clang::AccessSpecifier ret = lhs;
-
// Make the access equal to the stricter of the field and the nested field's access
- switch (ret)
- {
- case clang::AS_none:
- break;
- case clang::AS_private:
- break;
- case clang::AS_protected:
- if (rhs == AS_private)
- ret = AS_private;
- break;
- case clang::AS_public:
- ret = rhs;
- break;
- }
-
- return ret;
+ if (lhs == AS_none || rhs == AS_none)
+ return AS_none;
+ if (lhs == AS_private || rhs == AS_private)
+ return AS_private;
+ if (lhs == AS_protected || rhs == AS_protected)
+ return AS_protected;
+ return AS_public;
}
bool
@@ -1884,6 +1784,17 @@ ClangASTContext::GetUniqueNamespaceDeclaration (const char *name, DeclContext *d
return namespace_decl;
}
+NamespaceDecl *
+ClangASTContext::GetUniqueNamespaceDeclaration (clang::ASTContext *ast,
+ const char *name,
+ clang::DeclContext *decl_ctx)
+{
+ ClangASTContext *ast_ctx = ClangASTContext::GetASTContext(ast);
+ if (ast_ctx == nullptr)
+ return nullptr;
+
+ return ast_ctx->GetUniqueNamespaceDeclaration(name, decl_ctx);
+}
clang::BlockDecl *
ClangASTContext::CreateBlockDeclaration (clang::DeclContext *ctx)
@@ -1977,6 +1888,78 @@ ClangASTContext::CreateVariableDeclaration (clang::DeclContext *decl_context, co
return nullptr;
}
+lldb::opaque_compiler_type_t
+ClangASTContext::GetOpaqueCompilerType(clang::ASTContext *ast, lldb::BasicType basic_type)
+{
+ switch (basic_type)
+ {
+ case eBasicTypeVoid:
+ return ast->VoidTy.getAsOpaquePtr();
+ case eBasicTypeChar:
+ return ast->CharTy.getAsOpaquePtr();
+ case eBasicTypeSignedChar:
+ return ast->SignedCharTy.getAsOpaquePtr();
+ case eBasicTypeUnsignedChar:
+ return ast->UnsignedCharTy.getAsOpaquePtr();
+ case eBasicTypeWChar:
+ return ast->getWCharType().getAsOpaquePtr();
+ case eBasicTypeSignedWChar:
+ return ast->getSignedWCharType().getAsOpaquePtr();
+ case eBasicTypeUnsignedWChar:
+ return ast->getUnsignedWCharType().getAsOpaquePtr();
+ case eBasicTypeChar16:
+ return ast->Char16Ty.getAsOpaquePtr();
+ case eBasicTypeChar32:
+ return ast->Char32Ty.getAsOpaquePtr();
+ case eBasicTypeShort:
+ return ast->ShortTy.getAsOpaquePtr();
+ case eBasicTypeUnsignedShort:
+ return ast->UnsignedShortTy.getAsOpaquePtr();
+ case eBasicTypeInt:
+ return ast->IntTy.getAsOpaquePtr();
+ case eBasicTypeUnsignedInt:
+ return ast->UnsignedIntTy.getAsOpaquePtr();
+ case eBasicTypeLong:
+ return ast->LongTy.getAsOpaquePtr();
+ case eBasicTypeUnsignedLong:
+ return ast->UnsignedLongTy.getAsOpaquePtr();
+ case eBasicTypeLongLong:
+ return ast->LongLongTy.getAsOpaquePtr();
+ case eBasicTypeUnsignedLongLong:
+ return ast->UnsignedLongLongTy.getAsOpaquePtr();
+ case eBasicTypeInt128:
+ return ast->Int128Ty.getAsOpaquePtr();
+ case eBasicTypeUnsignedInt128:
+ return ast->UnsignedInt128Ty.getAsOpaquePtr();
+ case eBasicTypeBool:
+ return ast->BoolTy.getAsOpaquePtr();
+ case eBasicTypeHalf:
+ return ast->HalfTy.getAsOpaquePtr();
+ case eBasicTypeFloat:
+ return ast->FloatTy.getAsOpaquePtr();
+ case eBasicTypeDouble:
+ return ast->DoubleTy.getAsOpaquePtr();
+ case eBasicTypeLongDouble:
+ return ast->LongDoubleTy.getAsOpaquePtr();
+ case eBasicTypeFloatComplex:
+ return ast->FloatComplexTy.getAsOpaquePtr();
+ case eBasicTypeDoubleComplex:
+ return ast->DoubleComplexTy.getAsOpaquePtr();
+ case eBasicTypeLongDoubleComplex:
+ return ast->LongDoubleComplexTy.getAsOpaquePtr();
+ case eBasicTypeObjCID:
+ return ast->getObjCIdType().getAsOpaquePtr();
+ case eBasicTypeObjCClass:
+ return ast->getObjCClassType().getAsOpaquePtr();
+ case eBasicTypeObjCSel:
+ return ast->getObjCSelType().getAsOpaquePtr();
+ case eBasicTypeNullPtr:
+ return ast->NullPtrTy.getAsOpaquePtr();
+ default:
+ return nullptr;
+ }
+}
+
#pragma mark Function Types
FunctionDecl *
@@ -1997,31 +1980,17 @@ ClangASTContext::CreateFunctionDeclaration (DeclContext *decl_ctx,
if (name && name[0])
{
- func_decl = FunctionDecl::Create (*ast,
- decl_ctx,
- SourceLocation(),
- SourceLocation(),
- DeclarationName (&ast->Idents.get(name)),
- GetQualType(function_clang_type),
- nullptr,
- (clang::StorageClass)storage,
- is_inline,
- hasWrittenPrototype,
- isConstexprSpecified);
+ func_decl = FunctionDecl::Create(
+ *ast, decl_ctx, SourceLocation(), SourceLocation(), DeclarationName(&ast->Idents.get(name)),
+ ClangUtil::GetQualType(function_clang_type), nullptr, (clang::StorageClass)storage, is_inline,
+ hasWrittenPrototype, isConstexprSpecified);
}
else
{
- func_decl = FunctionDecl::Create (*ast,
- decl_ctx,
- SourceLocation(),
- SourceLocation(),
- DeclarationName (),
- GetQualType(function_clang_type),
- nullptr,
- (clang::StorageClass)storage,
- is_inline,
- hasWrittenPrototype,
- isConstexprSpecified);
+ func_decl =
+ FunctionDecl::Create(*ast, decl_ctx, SourceLocation(), SourceLocation(), DeclarationName(),
+ ClangUtil::GetQualType(function_clang_type), nullptr, (clang::StorageClass)storage,
+ is_inline, hasWrittenPrototype, isConstexprSpecified);
}
if (func_decl)
decl_ctx->addDecl (func_decl);
@@ -2041,10 +2010,33 @@ ClangASTContext::CreateFunctionType (ASTContext *ast,
bool is_variadic,
unsigned type_quals)
{
- assert (ast != nullptr);
+ if (ast == nullptr)
+ return CompilerType(); // invalid AST
+
+ if (!result_type || !ClangUtil::IsClangType(result_type))
+ return CompilerType(); // invalid return type
+
std::vector<QualType> qual_type_args;
+ if (num_args > 0 && args == nullptr)
+ return CompilerType(); // invalid argument array passed in
+
+ // Verify that all arguments are valid and the right type
for (unsigned i=0; i<num_args; ++i)
- qual_type_args.push_back (GetQualType(args[i]));
+ {
+ if (args[i])
+ {
+ // Make sure we have a clang type in args[i] and not a type from another
+ // language whose name might match
+ const bool is_clang_type = ClangUtil::IsClangType(args[i]);
+ lldbassert(is_clang_type);
+ if (is_clang_type)
+ qual_type_args.push_back(ClangUtil::GetQualType(args[i]));
+ else
+ return CompilerType(); // invalid argument type (must be a clang type)
+ }
+ else
+ return CompilerType(); // invalid argument type (empty)
+ }
// TODO: Detect calling convention in DWARF?
FunctionProtoType::ExtProtoInfo proto_info;
@@ -2053,9 +2045,7 @@ ClangASTContext::CreateFunctionType (ASTContext *ast,
proto_info.TypeQuals = type_quals;
proto_info.RefQualifier = RQ_None;
- return CompilerType (ast, ast->getFunctionType (GetQualType(result_type),
- qual_type_args,
- proto_info));
+ return CompilerType(ast, ast->getFunctionType(ClangUtil::GetQualType(result_type), qual_type_args, proto_info));
}
ParmVarDecl *
@@ -2063,15 +2053,9 @@ ClangASTContext::CreateParameterDeclaration (const char *name, const CompilerTyp
{
ASTContext *ast = getASTContext();
assert (ast != nullptr);
- return ParmVarDecl::Create(*ast,
- ast->getTranslationUnitDecl(),
- SourceLocation(),
- SourceLocation(),
- name && name[0] ? &ast->Idents.get(name) : nullptr,
- GetQualType(param_type),
- nullptr,
- (clang::StorageClass)storage,
- 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);
}
void
@@ -2081,6 +2065,13 @@ ClangASTContext::SetFunctionParameters (FunctionDecl *function_decl, ParmVarDecl
function_decl->setParams (ArrayRef<ParmVarDecl*>(params, num_params));
}
+CompilerType
+ClangASTContext::CreateBlockPointerType (const CompilerType &function_type)
+{
+ QualType block_type = m_ast_ap->getBlockPointerType(clang::QualType::getFromOpaquePtr(function_type.GetOpaqueQualType()));
+
+ return CompilerType (this, block_type.getAsOpaquePtr());
+}
#pragma mark Array Types
@@ -2096,7 +2087,7 @@ ClangASTContext::CreateArrayType (const CompilerType &element_type,
if (is_vector)
{
- return CompilerType (ast, ast->getExtVectorType(GetQualType(element_type), element_count));
+ return CompilerType(ast, ast->getExtVectorType(ClangUtil::GetQualType(element_type), element_count));
}
else
{
@@ -2104,16 +2095,13 @@ ClangASTContext::CreateArrayType (const CompilerType &element_type,
llvm::APInt ap_element_count (64, element_count);
if (element_count == 0)
{
- return CompilerType (ast, ast->getIncompleteArrayType (GetQualType(element_type),
- ArrayType::Normal,
- 0));
+ return CompilerType(ast, ast->getIncompleteArrayType(ClangUtil::GetQualType(element_type),
+ clang::ArrayType::Normal, 0));
}
else
{
- return CompilerType (ast, ast->getConstantArrayType (GetQualType(element_type),
- ap_element_count,
- ArrayType::Normal,
- 0));
+ return CompilerType(ast, ast->getConstantArrayType(ClangUtil::GetQualType(element_type),
+ ap_element_count, clang::ArrayType::Normal, 0));
}
}
}
@@ -2121,13 +2109,17 @@ ClangASTContext::CreateArrayType (const CompilerType &element_type,
}
CompilerType
-ClangASTContext::GetOrCreateStructForIdentifier (const ConstString &type_name,
- const std::initializer_list< std::pair < const char *, CompilerType > >& type_fields,
- bool packed)
+ClangASTContext::CreateStructForIdentifier (const ConstString &type_name,
+ const std::initializer_list< std::pair < const char *, CompilerType > >& type_fields,
+ bool packed)
{
CompilerType type;
- if ((type = GetTypeForIdentifier<clang::CXXRecordDecl>(type_name)).IsValid())
+ if (!type_name.IsEmpty() && (type = GetTypeForIdentifier<clang::CXXRecordDecl>(type_name)).IsValid())
+ {
+ lldbassert("Trying to create a type for an existing name");
return type;
+ }
+
type = CreateRecordType(nullptr, lldb::eAccessPublic, type_name.GetCString(), clang::TTK_Struct, lldb::eLanguageTypeC);
StartTagDeclarationDefinition(type);
for (const auto& field : type_fields)
@@ -2138,6 +2130,20 @@ ClangASTContext::GetOrCreateStructForIdentifier (const ConstString &type_name,
return type;
}
+CompilerType
+ClangASTContext::GetOrCreateStructForIdentifier (const ConstString &type_name,
+ const std::initializer_list< std::pair < const char *, CompilerType > >& type_fields,
+ bool packed)
+{
+ CompilerType type;
+ if ((type = GetTypeForIdentifier<clang::CXXRecordDecl>(type_name)).IsValid())
+ return type;
+
+ return CreateStructForIdentifier (type_name,
+ type_fields,
+ packed);
+}
+
#pragma mark Enumeration Types
CompilerType
@@ -2171,8 +2177,8 @@ ClangASTContext::CreateEnumerationType
if (enum_decl)
{
// TODO: check if we should be setting the promotion type too?
- enum_decl->setIntegerType(GetQualType(integer_clang_type));
-
+ enum_decl->setIntegerType(ClangUtil::GetQualType(integer_clang_type));
+
enum_decl->setAccess(AS_public); // TODO respect what's in the debug info
return CompilerType (ast, ast->getTagDeclType(enum_decl));
@@ -2565,7 +2571,7 @@ ClangASTContext::SetDefaultAccessForRecordFields (clang::RecordDecl* record_decl
clang::DeclContext *
ClangASTContext::GetDeclContextForType (const CompilerType& type)
{
- return GetDeclContextForType(GetQualType(type));
+ return GetDeclContextForType(ClangUtil::GetQualType(type));
}
clang::DeclContext *
@@ -2632,8 +2638,8 @@ GetCompleteQualType (clang::ASTContext *ast, clang::QualType qual_type, bool all
external_ast_source->CompleteType(cxx_record_decl);
if (cxx_record_decl->isCompleteDefinition())
{
- cxx_record_decl->setHasLoadedFieldsFromExternalStorage (true);
cxx_record_decl->field_begin();
+ cxx_record_decl->setHasLoadedFieldsFromExternalStorage (true);
}
}
}
@@ -3082,9 +3088,11 @@ ClangASTContext::IsHomogeneousAggregate (lldb::opaque_compiler_type_t type, Comp
bool is_hva = false;
bool is_hfa = false;
clang::QualType base_qual_type;
+ uint64_t base_bitwidth = 0;
for (field_pos = record_decl->field_begin(); field_pos != field_end; ++field_pos)
{
clang::QualType field_qual_type = field_pos->getType();
+ uint64_t field_bitwidth = getASTContext()->getTypeSize (qual_type);
if (field_qual_type->isFloatingType())
{
if (field_qual_type->isComplexType())
@@ -3105,22 +3113,21 @@ ClangASTContext::IsHomogeneousAggregate (lldb::opaque_compiler_type_t type, Comp
}
else if (field_qual_type->isVectorType() || field_qual_type->isExtVectorType())
{
- const clang::VectorType *array = field_qual_type.getTypePtr()->getAs<clang::VectorType>();
- if (array && array->getNumElements() <= 4)
+ if (num_fields == 0)
{
- if (num_fields == 0)
- base_qual_type = array->getElementType();
- else
- {
- if (is_hfa)
- return 0;
- is_hva = true;
- if (field_qual_type.getTypePtr() != base_qual_type.getTypePtr())
- return 0;
- }
+ base_qual_type = field_qual_type;
+ base_bitwidth = field_bitwidth;
}
else
- return 0;
+ {
+ if (is_hfa)
+ return 0;
+ is_hva = true;
+ if (base_bitwidth != field_bitwidth)
+ return 0;
+ if (field_qual_type.getTypePtr() != base_qual_type.getTypePtr())
+ return 0;
+ }
}
else
return 0;
@@ -3166,7 +3173,7 @@ ClangASTContext::GetFunctionArgumentAtIndex (lldb::opaque_compiler_type_t type,
{
if (type)
{
- clang::QualType qual_type (GetCanonicalQualType(type));
+ clang::QualType qual_type (GetQualType(type));
const clang::FunctionProtoType* func = llvm::dyn_cast<clang::FunctionProtoType>(qual_type.getTypePtr());
if (func)
{
@@ -3216,6 +3223,52 @@ ClangASTContext::IsFunctionPointerType (lldb::opaque_compiler_type_t type)
}
bool
+ClangASTContext::IsBlockPointerType (lldb::opaque_compiler_type_t type, CompilerType *function_pointer_type_ptr)
+{
+ if (type)
+ {
+ clang::QualType qual_type (GetCanonicalQualType(type));
+
+ if (qual_type->isBlockPointerType())
+ {
+ if (function_pointer_type_ptr)
+ {
+ const clang::BlockPointerType *block_pointer_type = qual_type->getAs<clang::BlockPointerType>();
+ QualType pointee_type = block_pointer_type->getPointeeType();
+ QualType function_pointer_type = m_ast_ap->getPointerType(pointee_type);
+ *function_pointer_type_ptr = CompilerType (getASTContext(), function_pointer_type);
+ }
+ return true;
+ }
+
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class)
+ {
+ default:
+ break;
+ case clang::Type::Typedef:
+ return IsBlockPointerType (llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), function_pointer_type_ptr);
+ case clang::Type::Auto:
+ return IsBlockPointerType (llvm::cast<clang::AutoType>(qual_type)->getDeducedType().getAsOpaquePtr(), function_pointer_type_ptr);
+ case clang::Type::Elaborated:
+ return IsBlockPointerType (llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), function_pointer_type_ptr);
+ case clang::Type::Paren:
+ return IsBlockPointerType (llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(), function_pointer_type_ptr);
+
+ case clang::Type::LValueReference:
+ case clang::Type::RValueReference:
+ {
+ const clang::ReferenceType *reference_type = llvm::cast<clang::ReferenceType>(qual_type.getTypePtr());
+ if (reference_type)
+ return IsBlockPointerType(reference_type->getPointeeType().getAsOpaquePtr(), function_pointer_type_ptr);
+ }
+ break;
+ }
+ }
+ return false;
+}
+
+bool
ClangASTContext::IsIntegerType (lldb::opaque_compiler_type_t type, bool &is_signed)
{
if (!type)
@@ -3237,6 +3290,23 @@ ClangASTContext::IsIntegerType (lldb::opaque_compiler_type_t type, bool &is_sign
}
bool
+ClangASTContext::IsEnumerationType(lldb::opaque_compiler_type_t type, bool &is_signed)
+{
+ if (type)
+ {
+ const clang::EnumType *enum_type = llvm::dyn_cast<clang::EnumType>(GetCanonicalQualType(type)->getCanonicalTypeInternal());
+
+ if (enum_type)
+ {
+ IsIntegerType(enum_type->getDecl()->getIntegerType().getAsOpaquePtr(), is_signed);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool
ClangASTContext::IsPointerType (lldb::opaque_compiler_type_t type, CompilerType *pointee_type)
{
if (type)
@@ -3466,8 +3536,8 @@ ClangASTContext::IsObjCClassType (const CompilerType& type)
{
if (type)
{
- clang::QualType qual_type (GetCanonicalQualType(type));
-
+ clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type));
+
const clang::ObjCObjectPointerType *obj_pointer_type = llvm::dyn_cast<clang::ObjCObjectPointerType>(qual_type);
if (obj_pointer_type)
@@ -3479,13 +3549,33 @@ ClangASTContext::IsObjCClassType (const CompilerType& type)
bool
ClangASTContext::IsObjCObjectOrInterfaceType (const CompilerType& type)
{
- if (IsClangType(type))
- return GetCanonicalQualType(type)->isObjCObjectOrInterfaceType();
+ if (ClangUtil::IsClangType(type))
+ return ClangUtil::GetCanonicalQualType(type)->isObjCObjectOrInterfaceType();
return false;
}
bool
-ClangASTContext::IsPolymorphicClass (lldb::opaque_compiler_type_t type)
+ClangASTContext::IsClassType(lldb::opaque_compiler_type_t type)
+{
+ if (!type)
+ return false;
+ clang::QualType qual_type(GetCanonicalQualType(type));
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ return (type_class == clang::Type::Record);
+}
+
+bool
+ClangASTContext::IsEnumType(lldb::opaque_compiler_type_t type)
+{
+ if (!type)
+ return false;
+ clang::QualType qual_type(GetCanonicalQualType(type));
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ return (type_class == clang::Type::Enum);
+}
+
+bool
+ClangASTContext::IsPolymorphicClass(lldb::opaque_compiler_type_t type)
{
if (type)
{
@@ -3539,6 +3629,14 @@ ClangASTContext::IsPossibleDynamicType (lldb::opaque_compiler_type_t type, Compi
case clang::Type::ObjCObjectPointer:
if (check_objc)
{
+ if (auto objc_pointee_type = qual_type->getPointeeType().getTypePtrOrNull())
+ {
+ if (auto objc_object_type = llvm::dyn_cast_or_null<clang::ObjCObjectType>(objc_pointee_type))
+ {
+ if (objc_object_type->isObjCClass())
+ return false;
+ }
+ }
if (dynamic_pointee_type)
dynamic_pointee_type->SetCompilerType(getASTContext(), llvm::cast<clang::ObjCObjectPointerType>(qual_type)->getPointeeType());
return true;
@@ -3696,7 +3794,7 @@ ClangASTContext::GetCXXClassName (const CompilerType& type, std::string &class_n
{
if (type)
{
- clang::QualType qual_type (GetCanonicalQualType(type));
+ clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type));
if (!qual_type.isNull())
{
clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
@@ -3717,8 +3815,8 @@ ClangASTContext::IsCXXClassType (const CompilerType& type)
{
if (!type)
return false;
-
- clang::QualType qual_type (GetCanonicalQualType(type));
+
+ clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type));
if (!qual_type.isNull() && qual_type->getAsCXXRecordDecl() != nullptr)
return true;
return false;
@@ -3742,7 +3840,7 @@ ClangASTContext::IsObjCObjectPointerType (const CompilerType& type, CompilerType
if (!type)
return false;
- clang::QualType qual_type (GetCanonicalQualType(type));
+ clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type));
if (!qual_type.isNull() && qual_type->isObjCObjectPointerType())
{
@@ -3770,9 +3868,9 @@ ClangASTContext::GetObjCClassName (const CompilerType& type, std::string &class_
{
if (!type)
return false;
-
- clang::QualType qual_type (GetCanonicalQualType(type));
-
+
+ clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type));
+
const clang::ObjCObjectType *object_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type);
if (object_type)
{
@@ -3809,7 +3907,6 @@ ClangASTContext::GetTypeName (lldb::opaque_compiler_type_t type)
clang::PrintingPolicy printing_policy (getASTContext()->getPrintingPolicy());
clang::QualType qual_type(GetQualType(type));
printing_policy.SuppressTagKeyword = true;
- printing_policy.LangOpts.WChar = true;
const clang::TypedefType *typedef_type = qual_type->getAs<clang::TypedefType>();
if (typedef_type)
{
@@ -4491,7 +4588,7 @@ ClangASTContext::CreateTypedefType (const CompilerType& type,
if (!ast)
return CompilerType();
clang::ASTContext* clang_ast = ast->getASTContext();
- clang::QualType qual_type (GetQualType(type));
+ clang::QualType qual_type(ClangUtil::GetQualType(type));
clang::DeclContext *decl_ctx = ClangASTContext::DeclContextGetAsDeclContext(compiler_decl_ctx);
if (decl_ctx == nullptr)
@@ -4621,6 +4718,20 @@ ClangASTContext::CreateTypedef (lldb::opaque_compiler_type_t type, const char *t
&clang_ast->Idents.get(typedef_name),
clang_ast->getTrivialTypeSourceInfo(qual_type));
+ clang::TagDecl *tdecl = nullptr;
+ if (!qual_type.isNull())
+ {
+ if (const clang::RecordType *rt = qual_type->getAs<clang::RecordType>())
+ tdecl = rt->getDecl();
+ if (const clang::EnumType *et = qual_type->getAs<clang::EnumType>())
+ tdecl = et->getDecl();
+ }
+
+ // Check whether this declaration is an anonymous struct, union, or enum, hidden behind a typedef. If so, we
+ // try to check whether we have a typedef tag to attach to the original record declaration
+ if (tdecl && !tdecl->getIdentifier() && !tdecl->getTypedefNameForAnonDecl())
+ tdecl->setTypedefNameForAnonDecl(decl);
+
decl->setAccess(clang::AS_public); // TODO respect proper access specifier
// Get a uniqued clang::QualType for the typedef decl type
@@ -4643,18 +4754,6 @@ ClangASTContext::GetTypedefedType (lldb::opaque_compiler_type_t type)
return CompilerType();
}
-CompilerType
-ClangASTContext::RemoveFastQualifiers (const CompilerType& type)
-{
- if (IsClangType(type))
- {
- clang::QualType qual_type(GetQualType(type));
- qual_type.getQualifiers().removeFastQualifiers();
- return CompilerType (type.GetTypeSystem(), qual_type.getAsOpaquePtr());
- }
- return type;
-}
-
//----------------------------------------------------------------------
// Create related types using the current type's AST
@@ -4675,8 +4774,16 @@ ClangASTContext::GetBitSize (lldb::opaque_compiler_type_t type, ExecutionContext
if (GetCompleteType (type))
{
clang::QualType qual_type(GetCanonicalQualType(type));
- switch (qual_type->getTypeClass())
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class)
{
+ case clang::Type::Record:
+ if (GetCompleteType(type))
+ return getASTContext()->getTypeSize(qual_type);
+ else
+ return 0;
+ break;
+
case clang::Type::ObjCInterface:
case clang::Type::ObjCObject:
{
@@ -4710,7 +4817,7 @@ ClangASTContext::GetBitSize (lldb::opaque_compiler_type_t type, ExecutionContext
}
}
}
- // fallthrough
+ LLVM_FALLTHROUGH;
default:
const uint32_t bit_size = getASTContext()->getTypeSize (qual_type);
if (bit_size == 0)
@@ -4740,97 +4847,127 @@ ClangASTContext::GetEncoding (lldb::opaque_compiler_type_t type, uint64_t &count
{
if (!type)
return lldb::eEncodingInvalid;
-
+
count = 1;
clang::QualType qual_type(GetCanonicalQualType(type));
-
+
switch (qual_type->getTypeClass())
{
case clang::Type::UnaryTransform:
break;
-
+
case clang::Type::FunctionNoProto:
case clang::Type::FunctionProto:
break;
-
+
case clang::Type::IncompleteArray:
case clang::Type::VariableArray:
break;
-
+
case clang::Type::ConstantArray:
break;
-
+
case clang::Type::ExtVector:
case clang::Type::Vector:
// TODO: Set this to more than one???
break;
-
+
case clang::Type::Builtin:
switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind())
- {
- case clang::BuiltinType::Void:
- break;
-
- case clang::BuiltinType::Bool:
- case clang::BuiltinType::Char_S:
- case clang::BuiltinType::SChar:
- case clang::BuiltinType::WChar_S:
- case clang::BuiltinType::Char16:
- case clang::BuiltinType::Char32:
- case clang::BuiltinType::Short:
- case clang::BuiltinType::Int:
- case clang::BuiltinType::Long:
- case clang::BuiltinType::LongLong:
- case clang::BuiltinType::Int128: return lldb::eEncodingSint;
-
- case clang::BuiltinType::Char_U:
- case clang::BuiltinType::UChar:
- case clang::BuiltinType::WChar_U:
- case clang::BuiltinType::UShort:
- case clang::BuiltinType::UInt:
- case clang::BuiltinType::ULong:
- case clang::BuiltinType::ULongLong:
- case clang::BuiltinType::UInt128: return lldb::eEncodingUint;
-
- case clang::BuiltinType::Half:
- case clang::BuiltinType::Float:
- case clang::BuiltinType::Double:
- case clang::BuiltinType::LongDouble: return lldb::eEncodingIEEE754;
-
- case clang::BuiltinType::ObjCClass:
- case clang::BuiltinType::ObjCId:
- case clang::BuiltinType::ObjCSel: return lldb::eEncodingUint;
-
- case clang::BuiltinType::NullPtr: return lldb::eEncodingUint;
-
- case clang::BuiltinType::Kind::ARCUnbridgedCast:
- case clang::BuiltinType::Kind::BoundMember:
- case clang::BuiltinType::Kind::BuiltinFn:
- case clang::BuiltinType::Kind::Dependent:
- case clang::BuiltinType::Kind::OCLClkEvent:
- case clang::BuiltinType::Kind::OCLEvent:
- case clang::BuiltinType::Kind::OCLImage1d:
- case clang::BuiltinType::Kind::OCLImage1dArray:
- case clang::BuiltinType::Kind::OCLImage1dBuffer:
- case clang::BuiltinType::Kind::OCLImage2d:
- case clang::BuiltinType::Kind::OCLImage2dArray:
- case clang::BuiltinType::Kind::OCLImage2dArrayDepth:
- case clang::BuiltinType::Kind::OCLImage2dArrayMSAA:
- case clang::BuiltinType::Kind::OCLImage2dArrayMSAADepth:
- case clang::BuiltinType::Kind::OCLImage2dDepth:
- case clang::BuiltinType::Kind::OCLImage2dMSAA:
- case clang::BuiltinType::Kind::OCLImage2dMSAADepth:
- case clang::BuiltinType::Kind::OCLImage3d:
- case clang::BuiltinType::Kind::OCLQueue:
- case clang::BuiltinType::Kind::OCLNDRange:
- case clang::BuiltinType::Kind::OCLReserveID:
- case clang::BuiltinType::Kind::OCLSampler:
- case clang::BuiltinType::Kind::OMPArraySection:
- case clang::BuiltinType::Kind::Overload:
- case clang::BuiltinType::Kind::PseudoObject:
- case clang::BuiltinType::Kind::UnknownAny:
- break;
- }
+ {
+ case clang::BuiltinType::Void:
+ break;
+
+ case clang::BuiltinType::Bool:
+ case clang::BuiltinType::Char_S:
+ case clang::BuiltinType::SChar:
+ case clang::BuiltinType::WChar_S:
+ case clang::BuiltinType::Char16:
+ case clang::BuiltinType::Char32:
+ case clang::BuiltinType::Short:
+ case clang::BuiltinType::Int:
+ case clang::BuiltinType::Long:
+ case clang::BuiltinType::LongLong:
+ case clang::BuiltinType::Int128:
+ return lldb::eEncodingSint;
+
+ case clang::BuiltinType::Char_U:
+ case clang::BuiltinType::UChar:
+ case clang::BuiltinType::WChar_U:
+ case clang::BuiltinType::UShort:
+ case clang::BuiltinType::UInt:
+ case clang::BuiltinType::ULong:
+ case clang::BuiltinType::ULongLong:
+ case clang::BuiltinType::UInt128:
+ return lldb::eEncodingUint;
+
+ case clang::BuiltinType::Half:
+ case clang::BuiltinType::Float:
+ case clang::BuiltinType::Float128:
+ case clang::BuiltinType::Double:
+ case clang::BuiltinType::LongDouble:
+ return lldb::eEncodingIEEE754;
+
+ case clang::BuiltinType::ObjCClass:
+ case clang::BuiltinType::ObjCId:
+ case clang::BuiltinType::ObjCSel:
+ return lldb::eEncodingUint;
+
+ case clang::BuiltinType::NullPtr:
+ return lldb::eEncodingUint;
+
+ case clang::BuiltinType::Kind::ARCUnbridgedCast:
+ case clang::BuiltinType::Kind::BoundMember:
+ case clang::BuiltinType::Kind::BuiltinFn:
+ case clang::BuiltinType::Kind::Dependent:
+ case clang::BuiltinType::Kind::OCLClkEvent:
+ case clang::BuiltinType::Kind::OCLEvent:
+ case clang::BuiltinType::Kind::OCLImage1dRO:
+ case clang::BuiltinType::Kind::OCLImage1dWO:
+ case clang::BuiltinType::Kind::OCLImage1dRW:
+ case clang::BuiltinType::Kind::OCLImage1dArrayRO:
+ case clang::BuiltinType::Kind::OCLImage1dArrayWO:
+ case clang::BuiltinType::Kind::OCLImage1dArrayRW:
+ case clang::BuiltinType::Kind::OCLImage1dBufferRO:
+ case clang::BuiltinType::Kind::OCLImage1dBufferWO:
+ case clang::BuiltinType::Kind::OCLImage1dBufferRW:
+ case clang::BuiltinType::Kind::OCLImage2dRO:
+ case clang::BuiltinType::Kind::OCLImage2dWO:
+ case clang::BuiltinType::Kind::OCLImage2dRW:
+ case clang::BuiltinType::Kind::OCLImage2dArrayRO:
+ case clang::BuiltinType::Kind::OCLImage2dArrayWO:
+ case clang::BuiltinType::Kind::OCLImage2dArrayRW:
+ case clang::BuiltinType::Kind::OCLImage2dArrayDepthRO:
+ case clang::BuiltinType::Kind::OCLImage2dArrayDepthWO:
+ case clang::BuiltinType::Kind::OCLImage2dArrayDepthRW:
+ case clang::BuiltinType::Kind::OCLImage2dArrayMSAARO:
+ case clang::BuiltinType::Kind::OCLImage2dArrayMSAAWO:
+ case clang::BuiltinType::Kind::OCLImage2dArrayMSAARW:
+ case clang::BuiltinType::Kind::OCLImage2dArrayMSAADepthRO:
+ case clang::BuiltinType::Kind::OCLImage2dArrayMSAADepthWO:
+ case clang::BuiltinType::Kind::OCLImage2dArrayMSAADepthRW:
+ case clang::BuiltinType::Kind::OCLImage2dDepthRO:
+ case clang::BuiltinType::Kind::OCLImage2dDepthWO:
+ case clang::BuiltinType::Kind::OCLImage2dDepthRW:
+ case clang::BuiltinType::Kind::OCLImage2dMSAARO:
+ case clang::BuiltinType::Kind::OCLImage2dMSAAWO:
+ case clang::BuiltinType::Kind::OCLImage2dMSAARW:
+ case clang::BuiltinType::Kind::OCLImage2dMSAADepthRO:
+ case clang::BuiltinType::Kind::OCLImage2dMSAADepthWO:
+ case clang::BuiltinType::Kind::OCLImage2dMSAADepthRW:
+ case clang::BuiltinType::Kind::OCLImage3dRO:
+ case clang::BuiltinType::Kind::OCLImage3dWO:
+ case clang::BuiltinType::Kind::OCLImage3dRW:
+ case clang::BuiltinType::Kind::OCLQueue:
+ case clang::BuiltinType::Kind::OCLNDRange:
+ case clang::BuiltinType::Kind::OCLReserveID:
+ case clang::BuiltinType::Kind::OCLSampler:
+ case clang::BuiltinType::Kind::OMPArraySection:
+ case clang::BuiltinType::Kind::Overload:
+ case clang::BuiltinType::Kind::PseudoObject:
+ case clang::BuiltinType::Kind::UnknownAny:
+ break;
+ }
break;
// All pointer types are represented as unsigned integer encodings.
// We may nee to add a eEncodingPointer if we ever need to know the
@@ -4857,7 +4994,7 @@ ClangASTContext::GetEncoding (lldb::opaque_compiler_type_t type, uint64_t &count
count = 2;
return encoding;
}
-
+
case clang::Type::ObjCInterface: break;
case clang::Type::Record: break;
case clang::Type::Enum: return lldb::eEncodingSint;
@@ -4866,13 +5003,13 @@ ClangASTContext::GetEncoding (lldb::opaque_compiler_type_t type, uint64_t &count
case clang::Type::Auto:
return CompilerType(getASTContext(), llvm::cast<clang::AutoType>(qual_type)->getDeducedType()).GetEncoding(count);
-
+
case clang::Type::Elaborated:
return CompilerType(getASTContext(), llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).GetEncoding(count);
-
+
case clang::Type::Paren:
return CompilerType(getASTContext(), llvm::cast<clang::ParenType>(qual_type)->desugar()).GetEncoding(count);
-
+
case clang::Type::DependentSizedArray:
case clang::Type::DependentSizedExtVector:
case clang::Type::UnresolvedUsing:
@@ -4885,7 +5022,7 @@ ClangASTContext::GetEncoding (lldb::opaque_compiler_type_t type, uint64_t &count
case clang::Type::DependentTemplateSpecialization:
case clang::Type::PackExpansion:
case clang::Type::ObjCObject:
-
+
case clang::Type::TypeOfExpr:
case clang::Type::TypeOf:
case clang::Type::Decltype:
@@ -4894,7 +5031,7 @@ ClangASTContext::GetEncoding (lldb::opaque_compiler_type_t type, uint64_t &count
case clang::Type::Adjusted:
case clang::Type::Pipe:
break;
-
+
// pointer type decayed from an array or function type.
case clang::Type::Decayed:
break;
@@ -5213,7 +5350,7 @@ ClangASTContext::GetNumChildren (lldb::opaque_compiler_type_t type, bool omit_em
CompilerType
ClangASTContext::GetBuiltinTypeByName (const ConstString &name)
{
- return GetBasicType (GetBasicTypeEnumeration (name));
+ return GetBasicType(GetBasicTypeEnumeration(name));
}
lldb::BasicType
@@ -5817,7 +5954,8 @@ ClangASTContext::GetVirtualBaseClassAtIndex (lldb::opaque_compiler_type_t type,
return GetVirtualBaseClassAtIndex (llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), idx, bit_offset_ptr);
case clang::Type::Paren:
- return GetVirtualBaseClassAtIndex (llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(), idx, bit_offset_ptr);
+ return GetVirtualBaseClassAtIndex(llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(), idx,
+ bit_offset_ptr);
default:
break;
@@ -5848,12 +5986,24 @@ ClangASTContext::GetNumPointeeChildren (clang::QualType type)
case clang::BuiltinType::Void:
case clang::BuiltinType::NullPtr:
case clang::BuiltinType::OCLEvent:
- case clang::BuiltinType::OCLImage1d:
- case clang::BuiltinType::OCLImage1dArray:
- case clang::BuiltinType::OCLImage1dBuffer:
- case clang::BuiltinType::OCLImage2d:
- case clang::BuiltinType::OCLImage2dArray:
- case clang::BuiltinType::OCLImage3d:
+ case clang::BuiltinType::OCLImage1dRO:
+ case clang::BuiltinType::OCLImage1dWO:
+ case clang::BuiltinType::OCLImage1dRW:
+ case clang::BuiltinType::OCLImage1dArrayRO:
+ case clang::BuiltinType::OCLImage1dArrayWO:
+ case clang::BuiltinType::OCLImage1dArrayRW:
+ case clang::BuiltinType::OCLImage1dBufferRO:
+ case clang::BuiltinType::OCLImage1dBufferWO:
+ case clang::BuiltinType::OCLImage1dBufferRW:
+ case clang::BuiltinType::OCLImage2dRO:
+ case clang::BuiltinType::OCLImage2dWO:
+ case clang::BuiltinType::OCLImage2dRW:
+ case clang::BuiltinType::OCLImage2dArrayRO:
+ case clang::BuiltinType::OCLImage2dArrayWO:
+ case clang::BuiltinType::OCLImage2dArrayRW:
+ case clang::BuiltinType::OCLImage3dRO:
+ case clang::BuiltinType::OCLImage3dWO:
+ case clang::BuiltinType::OCLImage3dRW:
case clang::BuiltinType::OCLSampler:
return 0;
case clang::BuiltinType::Bool:
@@ -6070,8 +6220,9 @@ ClangASTContext::GetChildCompilerTypeAtIndex (lldb::opaque_compiler_type_t type,
{
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 = process->ReadUnsignedIntegerFromMemory(base_offset_addr, 4, UINT32_MAX, err);
- if (base_offset != UINT32_MAX)
+ 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;
@@ -6123,12 +6274,20 @@ ClangASTContext::GetChildCompilerTypeAtIndex (lldb::opaque_compiler_type_t type,
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);
+ const uint32_t child_bit_size = child_byte_size * 8;
// Figure out the field offset within the current struct/union/class type
bit_offset = record_layout.getFieldOffset (field_idx);
- child_byte_offset = bit_offset / 8;
if (ClangASTContext::FieldIsBitfield (getASTContext(), *field, child_bitfield_bit_size))
- child_bitfield_bit_offset = bit_offset % 8;
+ {
+ child_bitfield_bit_offset = bit_offset % child_bit_size;
+ const uint32_t child_bit_offset = bit_offset - child_bitfield_bit_offset;
+ child_byte_offset = child_bit_offset / 8;
+ }
+ else
+ {
+ child_byte_offset = bit_offset / 8;
+ }
return field_clang_type;
}
@@ -7216,7 +7375,7 @@ CompilerType
ClangASTContext::GetTypeForFormatters (void* type)
{
if (type)
- return RemoveFastQualifiers(CompilerType(this, type));
+ return ClangUtil::RemoveFastQualifiers(CompilerType(this, type));
return CompilerType();
}
@@ -7439,7 +7598,7 @@ IsOperator (const char *name, clang::OverloadedOperatorKind &op_kind)
clang::EnumDecl *
ClangASTContext::GetAsEnumDecl (const CompilerType& type)
{
- const clang::EnumType *enutype = llvm::dyn_cast<clang::EnumType>(GetCanonicalQualType(type));
+ const clang::EnumType *enutype = llvm::dyn_cast<clang::EnumType>(ClangUtil::GetCanonicalQualType(type));
if (enutype)
return enutype->getDecl();
return NULL;
@@ -7448,7 +7607,7 @@ ClangASTContext::GetAsEnumDecl (const CompilerType& type)
clang::RecordDecl *
ClangASTContext::GetAsRecordDecl (const CompilerType& type)
{
- const clang::RecordType *record_type = llvm::dyn_cast<clang::RecordType>(GetCanonicalQualType(type));
+ const clang::RecordType *record_type = llvm::dyn_cast<clang::RecordType>(ClangUtil::GetCanonicalQualType(type));
if (record_type)
return record_type->getDecl();
return nullptr;
@@ -7457,7 +7616,7 @@ ClangASTContext::GetAsRecordDecl (const CompilerType& type)
clang::TagDecl *
ClangASTContext::GetAsTagDecl (const CompilerType& type)
{
- clang::QualType qual_type = GetCanonicalQualType(type);
+ clang::QualType qual_type = ClangUtil::GetCanonicalQualType(type);
if (qual_type.isNull())
return nullptr;
else
@@ -7473,7 +7632,8 @@ ClangASTContext::GetAsCXXRecordDecl (lldb::opaque_compiler_type_t type)
clang::ObjCInterfaceDecl *
ClangASTContext::GetAsObjCInterfaceDecl (const CompilerType& type)
{
- const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(GetCanonicalQualType(type));
+ const clang::ObjCObjectType *objc_class_type =
+ llvm::dyn_cast<clang::ObjCObjectType>(ClangUtil::GetCanonicalQualType(type));
if (objc_class_type)
return objc_class_type->getInterface();
return nullptr;
@@ -7504,17 +7664,14 @@ ClangASTContext::AddFieldToRecordType (const CompilerType& type, const char *nam
clang::RecordDecl *record_decl = ast->GetAsRecordDecl (type);
if (record_decl)
{
- field = clang::FieldDecl::Create (*clang_ast,
- record_decl,
- clang::SourceLocation(),
- clang::SourceLocation(),
- name ? &clang_ast->Idents.get(name) : nullptr, // Identifier
- GetQualType(field_clang_type), // Field type
- nullptr, // TInfo *
- bit_width, // BitWidth
- false, // Mutable
- clang::ICIS_NoInit); // HasInit
-
+ 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)
{
// Determine whether this field corresponds to an anonymous
@@ -7549,18 +7706,14 @@ ClangASTContext::AddFieldToRecordType (const CompilerType& type, const char *nam
const bool is_synthesized = false;
field_clang_type.GetCompleteType();
-
- field = clang::ObjCIvarDecl::Create (*clang_ast,
- class_interface_decl,
- clang::SourceLocation(),
- clang::SourceLocation(),
- name ? &clang_ast->Idents.get(name) : nullptr, // Identifier
- GetQualType(field_clang_type), // Field type
- nullptr, // TypeSourceInfo *
- ConvertAccessTypeToObjCIvarAccessControl (access),
- bit_width,
- is_synthesized);
-
+
+ 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 *
+ ConvertAccessTypeToObjCIvarAccessControl(access), bit_width, is_synthesized);
+
if (field)
{
class_interface_decl->addDecl(field);
@@ -7625,8 +7778,7 @@ ClangASTContext::BuildIndirectFields (const CompilerType& type)
clang::SourceLocation(),
nested_field_decl->getIdentifier(),
nested_field_decl->getType(),
- chain,
- 2);
+ {chain, 2});
indirect_field->setImplicit();
@@ -7637,7 +7789,7 @@ ClangASTContext::BuildIndirectFields (const CompilerType& type)
}
else if (clang::IndirectFieldDecl *nested_indirect_field_decl = llvm::dyn_cast<clang::IndirectFieldDecl>(*di))
{
- int nested_chain_size = nested_indirect_field_decl->getChainingSize();
+ size_t nested_chain_size = nested_indirect_field_decl->getChainingSize();
clang::NamedDecl **chain = new (*ast->getASTContext()) clang::NamedDecl*[nested_chain_size + 1];
chain[0] = *field_pos;
@@ -7656,8 +7808,7 @@ ClangASTContext::BuildIndirectFields (const CompilerType& type)
clang::SourceLocation(),
nested_indirect_field_decl->getIdentifier(),
nested_indirect_field_decl->getType(),
- chain,
- nested_chain_size + 1);
+ {chain, nested_chain_size + 1});
indirect_field->setImplicit();
@@ -7720,14 +7871,15 @@ ClangASTContext::AddVariableToRecordType (const CompilerType& type, const char *
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 *
- GetQualType(var_type), // Variable clang::QualType
- nullptr, // TypeSourceInfo *
- clang::SC_Static); // StorageClass
+ 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));
@@ -7762,9 +7914,9 @@ ClangASTContext::AddMethodToCXXRecordType (lldb::opaque_compiler_type_t type, co
if (cxx_record_decl == nullptr)
return nullptr;
-
- clang::QualType method_qual_type (GetQualType(method_clang_type));
-
+
+ clang::QualType method_qual_type(ClangUtil::GetQualType(method_clang_type));
+
clang::CXXMethodDecl *cxx_method_decl = nullptr;
clang::DeclarationName decl_name (&getASTContext()->Idents.get(name));
@@ -8048,17 +8200,16 @@ ClangASTContext::AddObjCClassProperty (const CompilerType& type,
if (ivar_decl)
prop_type_source = clang_ast->getTrivialTypeSourceInfo (ivar_decl->getType());
else
- prop_type_source = clang_ast->getTrivialTypeSourceInfo (GetQualType(property_clang_type));
-
- clang::ObjCPropertyDecl *property_decl = clang::ObjCPropertyDecl::Create (*clang_ast,
- class_interface_decl,
- clang::SourceLocation(), // Source Location
- &clang_ast->Idents.get(property_name),
- clang::SourceLocation(), //Source Location for AT
- clang::SourceLocation(), //Source location for (
- ivar_decl ? ivar_decl->getType() : ClangASTContext::GetQualType(property_clang_type),
- prop_type_source);
-
+ prop_type_source = clang_ast->getTrivialTypeSourceInfo(ClangUtil::GetQualType(property_clang_type));
+
+ clang::ObjCPropertyDecl *property_decl = clang::ObjCPropertyDecl::Create(
+ *clang_ast, class_interface_decl,
+ clang::SourceLocation(), // Source Location
+ &clang_ast->Idents.get(property_name),
+ clang::SourceLocation(), // Source Location for AT
+ clang::SourceLocation(), // Source location for (
+ ivar_decl ? ivar_decl->getType() : ClangUtil::GetQualType(property_clang_type), prop_type_source);
+
if (property_decl)
{
if (metadata)
@@ -8113,32 +8264,32 @@ ClangASTContext::AddObjCClassProperty (const CompilerType& type,
property_decl->setPropertyAttributes (clang::ObjCPropertyDecl::OBJC_PR_copy);
if (property_attributes & DW_APPLE_PROPERTY_nonatomic)
property_decl->setPropertyAttributes (clang::ObjCPropertyDecl::OBJC_PR_nonatomic);
-
- if (!getter_sel.isNull() && !class_interface_decl->lookupInstanceMethod(getter_sel))
+ if (property_attributes & clang::ObjCPropertyDecl::OBJC_PR_nullability)
+ property_decl->setPropertyAttributes(clang::ObjCPropertyDecl::OBJC_PR_nullability);
+ if (property_attributes & clang::ObjCPropertyDecl::OBJC_PR_null_resettable)
+ property_decl->setPropertyAttributes(clang::ObjCPropertyDecl::OBJC_PR_null_resettable);
+ if (property_attributes & clang::ObjCPropertyDecl::OBJC_PR_class)
+ property_decl->setPropertyAttributes(clang::ObjCPropertyDecl::OBJC_PR_class);
+
+ const bool isInstance = (property_attributes & clang::ObjCPropertyDecl::OBJC_PR_class) == 0;
+
+ if (!getter_sel.isNull() &&
+ !(isInstance ? class_interface_decl->lookupInstanceMethod(getter_sel)
+ : class_interface_decl->lookupClassMethod(getter_sel)))
{
- const bool isInstance = true;
const bool isVariadic = false;
const bool isSynthesized = false;
const bool isImplicitlyDeclared = true;
const bool isDefined = false;
const clang::ObjCMethodDecl::ImplementationControl impControl = clang::ObjCMethodDecl::None;
const bool HasRelatedResultType = false;
-
- clang::ObjCMethodDecl *getter = clang::ObjCMethodDecl::Create (*clang_ast,
- clang::SourceLocation(),
- clang::SourceLocation(),
- getter_sel,
- GetQualType(property_clang_type_to_access),
- nullptr,
- class_interface_decl,
- isInstance,
- isVariadic,
- isSynthesized,
- isImplicitlyDeclared,
- isDefined,
- impControl,
- HasRelatedResultType);
-
+
+ clang::ObjCMethodDecl *getter = clang::ObjCMethodDecl::Create(
+ *clang_ast, clang::SourceLocation(), clang::SourceLocation(), getter_sel,
+ ClangUtil::GetQualType(property_clang_type_to_access), nullptr, class_interface_decl,
+ isInstance, isVariadic, isSynthesized, isImplicitlyDeclared, isDefined, impControl,
+ HasRelatedResultType);
+
if (getter && metadata)
ClangASTContext::SetMetadata(clang_ast, getter, *metadata);
@@ -8149,12 +8300,12 @@ ClangASTContext::AddObjCClassProperty (const CompilerType& type,
class_interface_decl->addDecl(getter);
}
}
-
- if (!setter_sel.isNull() && !class_interface_decl->lookupInstanceMethod(setter_sel))
+
+ if (!setter_sel.isNull() &&
+ !(isInstance ? class_interface_decl->lookupInstanceMethod(setter_sel)
+ : class_interface_decl->lookupClassMethod(setter_sel)))
{
clang::QualType result_type = clang_ast->VoidTy;
-
- const bool isInstance = true;
const bool isVariadic = false;
const bool isSynthesized = false;
const bool isImplicitlyDeclared = true;
@@ -8181,17 +8332,12 @@ ClangASTContext::AddObjCClassProperty (const CompilerType& type,
ClangASTContext::SetMetadata(clang_ast, setter, *metadata);
llvm::SmallVector<clang::ParmVarDecl *, 1> params;
-
- params.push_back (clang::ParmVarDecl::Create (*clang_ast,
- setter,
- clang::SourceLocation(),
- clang::SourceLocation(),
- nullptr, // anonymous
- GetQualType(property_clang_type_to_access),
- nullptr,
- clang::SC_Auto,
- nullptr));
-
+
+ params.push_back(clang::ParmVarDecl::Create(
+ *clang_ast, setter, clang::SourceLocation(), clang::SourceLocation(),
+ nullptr, // anonymous
+ ClangUtil::GetQualType(property_clang_type_to_access), nullptr, clang::SC_Auto, nullptr));
+
if (setter)
{
setter->setMethodParams(*clang_ast, llvm::ArrayRef<clang::ParmVarDecl*>(params), llvm::ArrayRef<clang::SourceLocation>());
@@ -8222,7 +8368,8 @@ ClangASTContext::AddMethodToObjCObjectType (const CompilerType& type,
const char *name, // the full symbol name as seen in the symbol table (lldb::opaque_compiler_type_t type, "-[NString stringWithCString:]")
const CompilerType &method_clang_type,
lldb::AccessType access,
- bool is_artificial)
+ bool is_artificial,
+ bool is_variadic)
{
if (!type || !method_clang_type.IsValid())
return nullptr;
@@ -8267,9 +8414,9 @@ ClangASTContext::AddMethodToObjCObjectType (const CompilerType& type,
clang::Selector method_selector = ast->Selectors.getSelector (num_selectors_with_args ? selector_idents.size() : 0,
selector_idents.data());
-
- clang::QualType method_qual_type (GetQualType(method_clang_type));
-
+
+ clang::QualType method_qual_type(ClangUtil::GetQualType(method_clang_type));
+
// Populate the method decl with parameter decls
const clang::Type *method_type(method_qual_type.getTypePtr());
@@ -8282,7 +8429,6 @@ ClangASTContext::AddMethodToObjCObjectType (const CompilerType& type,
return nullptr;
- bool is_variadic = false;
bool is_synthesized = false;
bool is_defined = false;
clang::ObjCMethodDecl::ImplementationControl imp_control = clang::ObjCMethodDecl::None;
@@ -8291,23 +8437,18 @@ ClangASTContext::AddMethodToObjCObjectType (const CompilerType& type,
if (num_args != num_selectors_with_args)
return nullptr; // some debug information is corrupt. We are not going to deal with it.
-
- clang::ObjCMethodDecl *objc_method_decl = clang::ObjCMethodDecl::Create (*ast,
- clang::SourceLocation(), // beginLoc,
- clang::SourceLocation(), // endLoc,
- method_selector,
- method_function_prototype->getReturnType(),
- nullptr, // TypeSourceInfo *ResultTInfo,
- ClangASTContext::GetASTContext(ast)->GetDeclContextForType(GetQualType(type)),
- name[0] == '-',
- is_variadic,
- is_synthesized,
- true, // is_implicitly_declared; we force this to true because we don't have source locations
- is_defined,
- imp_control,
- false /*has_related_result_type*/);
-
-
+
+ clang::ObjCMethodDecl *objc_method_decl = clang::ObjCMethodDecl::Create(
+ *ast,
+ clang::SourceLocation(), // beginLoc,
+ clang::SourceLocation(), // endLoc,
+ method_selector, method_function_prototype->getReturnType(),
+ nullptr, // TypeSourceInfo *ResultTInfo,
+ ClangASTContext::GetASTContext(ast)->GetDeclContextForType(ClangUtil::GetQualType(type)), name[0] == '-',
+ is_variadic, is_synthesized,
+ true, // is_implicitly_declared; we force this to true because we don't have source locations
+ is_defined, imp_control, false /*has_related_result_type*/);
+
if (objc_method_decl == nullptr)
return nullptr;
@@ -8343,10 +8484,10 @@ ClangASTContext::AddMethodToObjCObjectType (const CompilerType& type,
bool
ClangASTContext::GetHasExternalStorage (const CompilerType &type)
{
- if (IsClangType(type))
+ if (ClangUtil::IsClangType(type))
return false;
- clang::QualType qual_type (GetCanonicalQualType(type));
+ clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type));
const clang::Type::TypeClass type_class = qual_type->getTypeClass();
switch (type_class)
@@ -8474,158 +8615,12 @@ ClangASTContext::SetHasExternalStorage (lldb::opaque_compiler_type_t type, bool
}
-bool
-ClangASTContext::CanImport (const CompilerType &type, lldb_private::ClangASTImporter &importer)
-{
- if (IsClangType(type))
- {
- // TODO: remove external completion BOOL
- // CompleteAndFetchChildren should get the Decl out and check for the
-
- clang::QualType qual_type(GetCanonicalQualType(RemoveFastQualifiers(type)));
-
- const clang::Type::TypeClass type_class = qual_type->getTypeClass();
- switch (type_class)
- {
- case clang::Type::Record:
- {
- const clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
- if (cxx_record_decl)
- {
- if (importer.ResolveDeclOrigin (cxx_record_decl, NULL, NULL))
- return true;
- }
- }
- break;
-
- case clang::Type::Enum:
- {
- clang::EnumDecl *enum_decl = llvm::cast<clang::EnumType>(qual_type)->getDecl();
- if (enum_decl)
- {
- if (importer.ResolveDeclOrigin (enum_decl, NULL, NULL))
- return true;
- }
- }
- break;
-
- case clang::Type::ObjCObject:
- case clang::Type::ObjCInterface:
- {
- const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type);
- if (objc_class_type)
- {
- clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
- // We currently can't complete objective C types through the newly added ASTContext
- // because it only supports TagDecl objects right now...
- if (class_interface_decl)
- {
- if (importer.ResolveDeclOrigin (class_interface_decl, NULL, NULL))
- return true;
- }
- }
- }
- break;
-
-
- case clang::Type::Typedef:
- return CanImport(CompilerType (type.GetTypeSystem(), llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr()), importer);
-
- case clang::Type::Auto:
- return CanImport(CompilerType (type.GetTypeSystem(), llvm::cast<clang::AutoType>(qual_type)->getDeducedType().getAsOpaquePtr()), importer);
-
- case clang::Type::Elaborated:
- return CanImport(CompilerType (type.GetTypeSystem(), llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr()), importer);
-
- case clang::Type::Paren:
- return CanImport(CompilerType (type.GetTypeSystem(), llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr()), importer);
-
- default:
- break;
- }
- }
- return false;
-}
-bool
-ClangASTContext::Import (const CompilerType &type, lldb_private::ClangASTImporter &importer)
-{
- if (IsClangType(type))
- {
- // TODO: remove external completion BOOL
- // CompleteAndFetchChildren should get the Decl out and check for the
-
- clang::QualType qual_type(GetCanonicalQualType(RemoveFastQualifiers(type)));
-
- const clang::Type::TypeClass type_class = qual_type->getTypeClass();
- switch (type_class)
- {
- case clang::Type::Record:
- {
- const clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
- if (cxx_record_decl)
- {
- if (importer.ResolveDeclOrigin (cxx_record_decl, NULL, NULL))
- return importer.CompleteAndFetchChildren(qual_type);
- }
- }
- break;
-
- case clang::Type::Enum:
- {
- clang::EnumDecl *enum_decl = llvm::cast<clang::EnumType>(qual_type)->getDecl();
- if (enum_decl)
- {
- if (importer.ResolveDeclOrigin (enum_decl, NULL, NULL))
- return importer.CompleteAndFetchChildren(qual_type);
- }
- }
- break;
-
- case clang::Type::ObjCObject:
- case clang::Type::ObjCInterface:
- {
- const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type);
- if (objc_class_type)
- {
- clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
- // We currently can't complete objective C types through the newly added ASTContext
- // because it only supports TagDecl objects right now...
- if (class_interface_decl)
- {
- if (importer.ResolveDeclOrigin (class_interface_decl, NULL, NULL))
- return importer.CompleteAndFetchChildren(qual_type);
- }
- }
- }
- break;
-
-
- case clang::Type::Typedef:
- return Import (CompilerType(type.GetTypeSystem(), llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr()), importer);
-
- case clang::Type::Auto:
- return Import (CompilerType(type.GetTypeSystem(),llvm::cast<clang::AutoType>(qual_type)->getDeducedType().getAsOpaquePtr()), importer);
-
- case clang::Type::Elaborated:
- return Import (CompilerType(type.GetTypeSystem(),llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr()), importer);
-
- case clang::Type::Paren:
- return Import (CompilerType(type.GetTypeSystem(),llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr()), importer);
-
- default:
- break;
- }
- }
- return false;
-}
-
-
#pragma mark TagDecl
bool
ClangASTContext::StartTagDeclarationDefinition (const CompilerType &type)
{
- clang::QualType qual_type (ClangASTContext::GetQualType(type));
+ clang::QualType qual_type(ClangUtil::GetQualType(type));
if (!qual_type.isNull())
{
const clang::TagType *tag_type = qual_type->getAs<clang::TagType>();
@@ -8656,21 +8651,31 @@ ClangASTContext::StartTagDeclarationDefinition (const CompilerType &type)
bool
ClangASTContext::CompleteTagDeclarationDefinition (const CompilerType& type)
{
- clang::QualType qual_type (ClangASTContext::GetQualType(type));
+ clang::QualType qual_type(ClangUtil::GetQualType(type));
if (!qual_type.isNull())
{
- clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
-
- if (cxx_record_decl)
+ // Make sure we use the same methodology as ClangASTContext::StartTagDeclarationDefinition()
+ // as to how we start/end the definition. Previously we were calling
+ const clang::TagType *tag_type = qual_type->getAs<clang::TagType>();
+ if (tag_type)
{
- if (!cxx_record_decl->isCompleteDefinition())
- cxx_record_decl->completeDefinition();
- cxx_record_decl->setHasLoadedFieldsFromExternalStorage(true);
- cxx_record_decl->setHasExternalLexicalStorage (false);
- cxx_record_decl->setHasExternalVisibleStorage (false);
- return true;
+ clang::TagDecl *tag_decl = tag_type->getDecl();
+ if (tag_decl)
+ {
+ clang::CXXRecordDecl *cxx_record_decl = llvm::dyn_cast_or_null<clang::CXXRecordDecl>(tag_decl);
+
+ if (cxx_record_decl)
+ {
+ if (!cxx_record_decl->isCompleteDefinition())
+ cxx_record_decl->completeDefinition();
+ cxx_record_decl->setHasLoadedFieldsFromExternalStorage(true);
+ cxx_record_decl->setHasExternalLexicalStorage (false);
+ cxx_record_decl->setHasExternalVisibleStorage (false);
+ return true;
+ }
+ }
}
-
+
const clang::EnumType *enutype = qual_type->getAs<clang::EnumType>();
if (enutype)
@@ -8687,24 +8692,28 @@ ClangASTContext::CompleteTagDeclarationDefinition (const CompilerType& type)
clang::ASTContext *ast = lldb_ast->getASTContext();
/// TODO This really needs to be fixed.
-
- unsigned NumPositiveBits = 1;
- unsigned NumNegativeBits = 0;
-
- clang::QualType promotion_qual_type;
- // If the enum integer type is less than an integer in bit width,
- // then we must promote it to an integer size.
- if (ast->getTypeSize(enum_decl->getIntegerType()) < ast->getTypeSize(ast->IntTy))
+
+ QualType integer_type(enum_decl->getIntegerType());
+ if (!integer_type.isNull())
{
- if (enum_decl->getIntegerType()->isSignedIntegerType())
- promotion_qual_type = ast->IntTy;
+ unsigned NumPositiveBits = 1;
+ unsigned NumNegativeBits = 0;
+
+ clang::QualType promotion_qual_type;
+ // If the enum integer type is less than an integer in bit width,
+ // then we must promote it to an integer size.
+ if (ast->getTypeSize(enum_decl->getIntegerType()) < ast->getTypeSize(ast->IntTy))
+ {
+ if (enum_decl->getIntegerType()->isSignedIntegerType())
+ promotion_qual_type = ast->IntTy;
+ else
+ promotion_qual_type = ast->UnsignedIntTy;
+ }
else
- promotion_qual_type = ast->UnsignedIntTy;
+ promotion_qual_type = enum_decl->getIntegerType();
+
+ enum_decl->completeDefinition(enum_decl->getIntegerType(), promotion_qual_type, NumPositiveBits, NumNegativeBits);
}
- else
- promotion_qual_type = enum_decl->getIntegerType();
-
- enum_decl->completeDefinition(enum_decl->getIntegerType(), promotion_qual_type, NumPositiveBits, NumNegativeBits);
}
return true;
}
@@ -8736,15 +8745,11 @@ ClangASTContext::AddEnumerationValueToEnumerationType (lldb::opaque_compiler_typ
{
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
- GetQualType(enumerator_clang_type),
- nullptr,
- enum_llvm_apsint);
-
+ 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);
@@ -8787,9 +8792,9 @@ ClangASTContext::CreateMemberPointerType (const CompilerType& type, const Compil
ClangASTContext *ast = llvm::dyn_cast<ClangASTContext>(type.GetTypeSystem());
if (!ast)
return CompilerType();
- return CompilerType (ast->getASTContext(),
- ast->getASTContext()->getMemberPointerType (GetQualType(pointee_type),
- GetQualType(type).getTypePtr()));
+ return CompilerType(ast->getASTContext(),
+ ast->getASTContext()->getMemberPointerType(ClangUtil::GetQualType(pointee_type),
+ ClangUtil::GetQualType(type).getTypePtr()));
}
return CompilerType();
}
@@ -8816,18 +8821,10 @@ ClangASTContext::ConvertStringToFloatValue (lldb::opaque_compiler_type_t type, c
const uint64_t byte_size = bit_size / 8;
if (dst_size >= byte_size)
{
- if (bit_size == sizeof(float)*8)
- {
- float float32 = ap_float.convertToFloat();
- ::memcpy (dst, &float32, byte_size);
- return byte_size;
- }
- else if (bit_size >= 64)
- {
- llvm::APInt ap_int(ap_float.bitcastToAPInt());
- ::memcpy (dst, ap_int.getRawData(), byte_size);
+ Scalar scalar = ap_float.bitcastToAPInt().zextOrTrunc(llvm::NextPowerOf2(byte_size) * 8);
+ lldb_private::Error get_data_error;
+ if (scalar.GetAsMemoryData(dst, byte_size, lldb_private::endian::InlHostByteOrder(), get_data_error))
return byte_size;
- }
}
}
}
@@ -9281,6 +9278,7 @@ ClangASTContext::DumpTypeValue (lldb::opaque_compiler_type_t type, Stream *s,
return true;
}
// format was not enum, just fall through and dump the value as requested....
+ LLVM_FALLTHROUGH;
default:
// We are down to a scalar type that we just need to display.
@@ -9519,9 +9517,9 @@ ClangASTContext::DumpTypeDescription (lldb::opaque_compiler_type_t type, Stream
void
ClangASTContext::DumpTypeName (const CompilerType &type)
{
- if (IsClangType(type))
+ if (ClangUtil::IsClangType(type))
{
- clang::QualType qual_type(GetCanonicalQualType(RemoveFastQualifiers(type)));
+ clang::QualType qual_type(ClangUtil::GetCanonicalQualType(ClangUtil::RemoveFastQualifiers(type)));
const clang::Type::TypeClass type_class = qual_type->getTypeClass();
switch (type_class)
@@ -9633,15 +9631,21 @@ ClangASTContext::CompleteObjCInterfaceDecl (void *baton, clang::ObjCInterfaceDec
}
}
-
DWARFASTParser *
-ClangASTContext::GetDWARFParser ()
+ClangASTContext::GetDWARFParser()
{
if (!m_dwarf_ast_parser_ap)
m_dwarf_ast_parser_ap.reset(new DWARFASTParserClang(*this));
return m_dwarf_ast_parser_ap.get();
}
+PDBASTParser *
+ClangASTContext::GetPDBParser()
+{
+ if (!m_pdb_ast_parser_ap)
+ m_pdb_ast_parser_ap.reset(new PDBASTParser(*this));
+ return m_pdb_ast_parser_ap.get();
+}
bool
ClangASTContext::LayoutRecordType(void *baton,
@@ -9654,30 +9658,13 @@ ClangASTContext::LayoutRecordType(void *baton,
{
ClangASTContext *ast = (ClangASTContext *)baton;
DWARFASTParserClang *dwarf_ast_parser = (DWARFASTParserClang *)ast->GetDWARFParser();
- return dwarf_ast_parser->LayoutRecordType(record_decl, bit_size, alignment, field_offsets, base_offsets, vbase_offsets);
+ return dwarf_ast_parser->GetClangASTImporter().LayoutRecordType(record_decl, bit_size, alignment, field_offsets,
+ base_offsets, vbase_offsets);
}
//----------------------------------------------------------------------
// CompilerDecl override functions
//----------------------------------------------------------------------
-lldb::VariableSP
-ClangASTContext::DeclGetVariable (void *opaque_decl)
-{
- if (llvm::dyn_cast<clang::VarDecl>((clang::Decl *)opaque_decl))
- {
- auto decl_search_it = m_decl_objects.find(opaque_decl);
- if (decl_search_it != m_decl_objects.end())
- return std::static_pointer_cast<Variable>(decl_search_it->second);
- }
- return VariableSP();
-}
-
-void
-ClangASTContext::DeclLinkToObject (void *opaque_decl, std::shared_ptr<void> object)
-{
- if (m_decl_objects.find(opaque_decl) == m_decl_objects.end())
- m_decl_objects.insert(std::make_pair(opaque_decl, object));
-}
ConstString
ClangASTContext::DeclGetName (void *opaque_decl)
@@ -9750,7 +9737,7 @@ ClangASTContext::DeclGetFunctionNumArguments(void *opaque_decl)
if (clang::FunctionDecl *func_decl = llvm::dyn_cast<clang::FunctionDecl>((clang::Decl*)opaque_decl))
return func_decl->param_size();
if (clang::ObjCMethodDecl *objc_method = llvm::dyn_cast<clang::ObjCMethodDecl>((clang::Decl*)opaque_decl))
- return objc_method->param_size();
+ return objc_method->param_size();
else
return 0;
}
@@ -9764,7 +9751,7 @@ ClangASTContext::DeclGetFunctionArgumentType (void *opaque_decl, size_t idx)
{
ParmVarDecl *var_decl = func_decl->getParamDecl(idx);
if (var_decl)
- return CompilerType(this, var_decl->getOriginalType().getAsOpaquePtr());
+ return CompilerType(this, var_decl->getOriginalType().getAsOpaquePtr());
}
}
else if (clang::ObjCMethodDecl *objc_method = llvm::dyn_cast<clang::ObjCMethodDecl>((clang::Decl*)opaque_decl))
@@ -9780,7 +9767,9 @@ ClangASTContext::DeclGetFunctionArgumentType (void *opaque_decl, size_t idx)
//----------------------------------------------------------------------
std::vector<CompilerDecl>
-ClangASTContext::DeclContextFindDeclByName(void *opaque_decl_ctx, ConstString name)
+ClangASTContext::DeclContextFindDeclByName(void *opaque_decl_ctx,
+ ConstString name,
+ const bool ignore_using_decls)
{
std::vector<CompilerDecl> found_decls;
if (opaque_decl_ctx)
@@ -9804,12 +9793,16 @@ ClangASTContext::DeclContextFindDeclByName(void *opaque_decl_ctx, ConstString na
{
if (clang::UsingDirectiveDecl *ud = llvm::dyn_cast<clang::UsingDirectiveDecl>(child))
{
+ if (ignore_using_decls)
+ continue;
clang::DeclContext *from = ud->getCommonAncestor();
if (searched.find(ud->getNominatedNamespace()) == searched.end())
search_queue.insert(std::make_pair(from, ud->getNominatedNamespace()));
}
else if (clang::UsingDecl *ud = llvm::dyn_cast<clang::UsingDecl>(child))
{
+ if (ignore_using_decls)
+ continue;
for (clang::UsingShadowDecl *usd : ud->shadows())
{
clang::Decl *target = usd->getTargetDecl();
@@ -9902,6 +9895,15 @@ ClangASTContext::CountDeclLevels (clang::DeclContext *frame_decl_ctx,
{
if (searched.find(it->second) != searched.end())
continue;
+
+ // Currently DWARF has one shared translation unit for all Decls at top level, so this
+ // would erroneously find using statements anywhere. So don't look at the top-level
+ // translation unit.
+ // TODO fix this and add a testcase that depends on it.
+
+ if (llvm::isa<clang::TranslationUnitDecl>(it->second))
+ continue;
+
searched.insert(it->second);
symbol_file->ParseDeclsForContext(CompilerDeclContext(this, it->second));
diff --git a/source/Symbol/ClangASTImporter.cpp b/source/Symbol/ClangASTImporter.cpp
index 141937072c73..6be10602d998 100644
--- a/source/Symbol/ClangASTImporter.cpp
+++ b/source/Symbol/ClangASTImporter.cpp
@@ -7,16 +7,17 @@
//
//===----------------------------------------------------------------------===//
-#include "clang/AST/Decl.h"
-#include "clang/AST/DeclCXX.h"
-#include "clang/AST/DeclObjC.h"
-#include "llvm/Support/raw_ostream.h"
+#include "lldb/Symbol/ClangASTImporter.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
#include "lldb/Symbol/ClangASTContext.h"
-#include "lldb/Symbol/ClangASTImporter.h"
#include "lldb/Symbol/ClangExternalASTSourceCommon.h"
+#include "lldb/Symbol/ClangUtil.h"
#include "lldb/Utility/LLDBAssert.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclObjC.h"
+#include "llvm/Support/raw_ostream.h"
using namespace lldb_private;
using namespace clang;
@@ -347,6 +348,211 @@ ClangASTImporter::DeportDecl (clang::ASTContext *dst_ctx,
return result;
}
+bool
+ClangASTImporter::CanImport(const CompilerType &type)
+{
+ if (!ClangUtil::IsClangType(type))
+ return false;
+
+ // TODO: remove external completion BOOL
+ // CompleteAndFetchChildren should get the Decl out and check for the
+
+ clang::QualType qual_type(ClangUtil::GetCanonicalQualType(ClangUtil::RemoveFastQualifiers(type)));
+
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class)
+ {
+ case clang::Type::Record:
+ {
+ const clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
+ if (cxx_record_decl)
+ {
+ if (ResolveDeclOrigin(cxx_record_decl, NULL, NULL))
+ return true;
+ }
+ }
+ break;
+
+ case clang::Type::Enum:
+ {
+ clang::EnumDecl *enum_decl = llvm::cast<clang::EnumType>(qual_type)->getDecl();
+ if (enum_decl)
+ {
+ if (ResolveDeclOrigin(enum_decl, NULL, NULL))
+ return true;
+ }
+ }
+ break;
+
+ case clang::Type::ObjCObject:
+ case clang::Type::ObjCInterface:
+ {
+ const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type);
+ if (objc_class_type)
+ {
+ clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
+ // We currently can't complete objective C types through the newly added ASTContext
+ // because it only supports TagDecl objects right now...
+ if (class_interface_decl)
+ {
+ if (ResolveDeclOrigin(class_interface_decl, NULL, NULL))
+ return true;
+ }
+ }
+ }
+ break;
+
+ case clang::Type::Typedef:
+ return CanImport(CompilerType(
+ type.GetTypeSystem(),
+ llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr()));
+
+ case clang::Type::Auto:
+ return CanImport(CompilerType(type.GetTypeSystem(),
+ llvm::cast<clang::AutoType>(qual_type)->getDeducedType().getAsOpaquePtr()));
+
+ case clang::Type::Elaborated:
+ return CanImport(CompilerType(
+ type.GetTypeSystem(), llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr()));
+
+ case clang::Type::Paren:
+ return CanImport(CompilerType(type.GetTypeSystem(),
+ llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr()));
+
+ default:
+ break;
+ }
+
+ return false;
+}
+
+bool
+ClangASTImporter::Import(const CompilerType &type)
+{
+ if (!ClangUtil::IsClangType(type))
+ return false;
+ // TODO: remove external completion BOOL
+ // CompleteAndFetchChildren should get the Decl out and check for the
+
+ clang::QualType qual_type(ClangUtil::GetCanonicalQualType(ClangUtil::RemoveFastQualifiers(type)));
+
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class)
+ {
+ case clang::Type::Record:
+ {
+ const clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
+ if (cxx_record_decl)
+ {
+ if (ResolveDeclOrigin(cxx_record_decl, NULL, NULL))
+ return CompleteAndFetchChildren(qual_type);
+ }
+ }
+ break;
+
+ case clang::Type::Enum:
+ {
+ clang::EnumDecl *enum_decl = llvm::cast<clang::EnumType>(qual_type)->getDecl();
+ if (enum_decl)
+ {
+ if (ResolveDeclOrigin(enum_decl, NULL, NULL))
+ return CompleteAndFetchChildren(qual_type);
+ }
+ }
+ break;
+
+ case clang::Type::ObjCObject:
+ case clang::Type::ObjCInterface:
+ {
+ const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type);
+ if (objc_class_type)
+ {
+ clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
+ // We currently can't complete objective C types through the newly added ASTContext
+ // because it only supports TagDecl objects right now...
+ if (class_interface_decl)
+ {
+ if (ResolveDeclOrigin(class_interface_decl, NULL, NULL))
+ return CompleteAndFetchChildren(qual_type);
+ }
+ }
+ }
+ break;
+
+ case clang::Type::Typedef:
+ return Import(CompilerType(
+ type.GetTypeSystem(),
+ llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr()));
+
+ case clang::Type::Auto:
+ return Import(CompilerType(type.GetTypeSystem(),
+ llvm::cast<clang::AutoType>(qual_type)->getDeducedType().getAsOpaquePtr()));
+
+ case clang::Type::Elaborated:
+ return Import(CompilerType(type.GetTypeSystem(),
+ llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr()));
+
+ case clang::Type::Paren:
+ return Import(CompilerType(type.GetTypeSystem(),
+ llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr()));
+
+ default:
+ break;
+ }
+ return false;
+}
+
+bool
+ClangASTImporter::CompleteType(const CompilerType &compiler_type)
+{
+ if (!CanImport(compiler_type))
+ return false;
+
+ if (Import(compiler_type))
+ {
+ ClangASTContext::CompleteTagDeclarationDefinition(compiler_type);
+ return true;
+ }
+
+ ClangASTContext::SetHasExternalStorage(compiler_type.GetOpaqueQualType(), false);
+ return false;
+}
+
+bool
+ClangASTImporter::LayoutRecordType(const clang::RecordDecl *record_decl, uint64_t &bit_size, uint64_t &alignment,
+ llvm::DenseMap<const clang::FieldDecl *, uint64_t> &field_offsets,
+ llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &base_offsets,
+ llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &vbase_offsets)
+{
+ RecordDeclToLayoutMap::iterator pos = m_record_decl_to_layout_map.find(record_decl);
+ bool success = false;
+ base_offsets.clear();
+ vbase_offsets.clear();
+ if (pos != m_record_decl_to_layout_map.end())
+ {
+ bit_size = pos->second.bit_size;
+ alignment = pos->second.alignment;
+ field_offsets.swap(pos->second.field_offsets);
+ base_offsets.swap(pos->second.base_offsets);
+ vbase_offsets.swap(pos->second.vbase_offsets);
+ m_record_decl_to_layout_map.erase(pos);
+ success = true;
+ }
+ else
+ {
+ bit_size = 0;
+ alignment = 0;
+ field_offsets.clear();
+ }
+ return success;
+}
+
+void
+ClangASTImporter::InsertRecordDecl(clang::RecordDecl *decl, const LayoutInfo &layout)
+{
+ m_record_decl_to_layout_map.insert(std::make_pair(decl, layout));
+}
+
void
ClangASTImporter::CompleteDecl (clang::Decl *decl)
{
@@ -729,16 +935,21 @@ ClangASTImporter::Minion::ExecuteDeportWorkQueues ()
if (TagDecl *tag_decl = dyn_cast<TagDecl>(decl))
{
if (TagDecl *original_tag_decl = dyn_cast<TagDecl>(original_decl))
+ {
if (original_tag_decl->isCompleteDefinition())
+ {
ImportDefinitionTo(tag_decl, original_tag_decl);
+ tag_decl->setCompleteDefinition(true);
+ }
+ }
tag_decl->setHasExternalLexicalStorage(false);
tag_decl->setHasExternalVisibleStorage(false);
}
- else if (ObjCInterfaceDecl *interface_decl = dyn_cast<ObjCInterfaceDecl>(decl))
+ else if (ObjCContainerDecl *container_decl = dyn_cast<ObjCContainerDecl>(decl))
{
- interface_decl->setHasExternalLexicalStorage(false);
- interface_decl->setHasExternalVisibleStorage(false);
+ container_decl->setHasExternalLexicalStorage(false);
+ container_decl->setHasExternalVisibleStorage(false);
}
to_context_md->m_origins.erase(decl);
@@ -753,8 +964,6 @@ ClangASTImporter::Minion::ImportDefinitionTo (clang::Decl *to, clang::Decl *from
{
ASTImporter::Imported(from, to);
- ObjCInterfaceDecl *to_objc_interface = dyn_cast<ObjCInterfaceDecl>(to);
-
/*
if (to_objc_interface)
to_objc_interface->startDefinition();
@@ -766,12 +975,20 @@ ClangASTImporter::Minion::ImportDefinitionTo (clang::Decl *to, clang::Decl *from
*/
ImportDefinition(from);
+
+ if (clang::TagDecl *to_tag = dyn_cast<clang::TagDecl>(to))
+ {
+ if (clang::TagDecl *from_tag = dyn_cast<clang::TagDecl>(from))
+ {
+ to_tag->setCompleteDefinition(from_tag->isCompleteDefinition());
+ }
+ }
// If we're dealing with an Objective-C class, ensure that the inheritance has
// been set up correctly. The ASTImporter may not do this correctly if the
// class was originally sourced from symbols.
- if (to_objc_interface)
+ if (ObjCInterfaceDecl *to_objc_interface = dyn_cast<ObjCInterfaceDecl>(to))
{
do
{
@@ -949,20 +1166,32 @@ ClangASTImporter::Minion::Imported (clang::Decl *from, clang::Decl *to)
to_namespace_decl->setHasExternalVisibleStorage();
}
- if (isa<ObjCInterfaceDecl>(from))
+ if (isa<ObjCContainerDecl>(from))
{
- ObjCInterfaceDecl *to_interface_decl = dyn_cast<ObjCInterfaceDecl>(to);
+ ObjCContainerDecl *to_container_decl = dyn_cast<ObjCContainerDecl>(to);
- to_interface_decl->setHasExternalLexicalStorage();
- to_interface_decl->setHasExternalVisibleStorage();
+ to_container_decl->setHasExternalLexicalStorage();
+ to_container_decl->setHasExternalVisibleStorage();
/*to_interface_decl->setExternallyCompleted();*/
if (log)
- log->Printf(" [ClangASTImporter] To is an ObjCInterfaceDecl - attributes %s%s%s",
- (to_interface_decl->hasExternalLexicalStorage() ? " Lexical" : ""),
- (to_interface_decl->hasExternalVisibleStorage() ? " Visible" : ""),
- (to_interface_decl->hasDefinition() ? " HasDefinition" : ""));
+ {
+ if (ObjCInterfaceDecl *to_interface_decl = llvm::dyn_cast<ObjCInterfaceDecl>(to_container_decl))
+ {
+ log->Printf(" [ClangASTImporter] To is an ObjCInterfaceDecl - attributes %s%s%s",
+ (to_interface_decl->hasExternalLexicalStorage() ? " Lexical" : ""),
+ (to_interface_decl->hasExternalVisibleStorage() ? " Visible" : ""),
+ (to_interface_decl->hasDefinition() ? " HasDefinition" : ""));
+ }
+ else
+ {
+ log->Printf(" [ClangASTImporter] To is an %sDecl - attributes %s%s",
+ ((Decl*)to_container_decl)->getDeclKindName(),
+ (to_container_decl->hasExternalLexicalStorage() ? " Lexical" : ""),
+ (to_container_decl->hasExternalVisibleStorage() ? " Visible" : ""));
+ }
+ }
}
return clang::ASTImporter::Imported(from, to);
diff --git a/source/Symbol/ClangExternalASTSourceCommon.cpp b/source/Symbol/ClangExternalASTSourceCommon.cpp
index 79cc9a91355a..77aea1eafc4f 100644
--- a/source/Symbol/ClangExternalASTSourceCommon.cpp
+++ b/source/Symbol/ClangExternalASTSourceCommon.cpp
@@ -9,7 +9,6 @@
#include "lldb/Symbol/ClangExternalASTSourceCommon.h"
#include "lldb/Core/Stream.h"
-#include "lldb/Host/Mutex.h"
using namespace lldb_private;
@@ -19,8 +18,9 @@ typedef llvm::DenseMap<clang::ExternalASTSource *, ClangExternalASTSourceCommon
static ASTSourceMap &GetSourceMap()
{
- static ASTSourceMap s_source_map;
- return s_source_map;
+ // Intentionally leaked to avoid problems with global destructors.
+ static ASTSourceMap *s_source_map = new ASTSourceMap;
+ return *s_source_map;
}
ClangExternalASTSourceCommon *
diff --git a/source/Symbol/ClangUtil.cpp b/source/Symbol/ClangUtil.cpp
new file mode 100644
index 000000000000..76d621e9ce44
--- /dev/null
+++ b/source/Symbol/ClangUtil.cpp
@@ -0,0 +1,58 @@
+//===-- ClangUtil.cpp -------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+// A collection of helper methods and data structures for manipulating clang
+// types and decls.
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Symbol/ClangUtil.h"
+#include "lldb/Symbol/ClangASTContext.h"
+
+using namespace clang;
+using namespace lldb_private;
+
+bool
+ClangUtil::IsClangType(const CompilerType &ct)
+{
+ if (llvm::dyn_cast_or_null<ClangASTContext>(ct.GetTypeSystem()) == nullptr)
+ return false;
+
+ if (!ct.GetOpaqueQualType())
+ return false;
+
+ return true;
+}
+
+QualType
+ClangUtil::GetQualType(const CompilerType &ct)
+{
+ // Make sure we have a clang type before making a clang::QualType
+ if (!IsClangType(ct))
+ return QualType();
+
+ return QualType::getFromOpaquePtr(ct.GetOpaqueQualType());
+}
+
+QualType
+ClangUtil::GetCanonicalQualType(const CompilerType &ct)
+{
+ if (!IsClangType(ct))
+ return QualType();
+
+ return GetQualType(ct).getCanonicalType();
+}
+
+CompilerType
+ClangUtil::RemoveFastQualifiers(const CompilerType &ct)
+{
+ if (!IsClangType(ct))
+ return ct;
+
+ QualType qual_type(GetQualType(ct));
+ qual_type.removeLocalFastQualifiers();
+ return CompilerType(ct.GetTypeSystem(), qual_type.getAsOpaquePtr());
+}
diff --git a/source/Symbol/CompactUnwindInfo.cpp b/source/Symbol/CompactUnwindInfo.cpp
index 233ca91ec8d8..105c3c242c0f 100644
--- a/source/Symbol/CompactUnwindInfo.cpp
+++ b/source/Symbol/CompactUnwindInfo.cpp
@@ -101,6 +101,52 @@ namespace lldb_private {
UNWIND_X86_64_REG_R15 = 5,
UNWIND_X86_64_REG_RBP = 6,
};
+
+ FLAGS_ANONYMOUS_ENUM()
+ {
+ UNWIND_ARM64_MODE_MASK = 0x0F000000,
+ UNWIND_ARM64_MODE_FRAMELESS = 0x02000000,
+ UNWIND_ARM64_MODE_DWARF = 0x03000000,
+ UNWIND_ARM64_MODE_FRAME = 0x04000000,
+
+ UNWIND_ARM64_FRAME_X19_X20_PAIR = 0x00000001,
+ UNWIND_ARM64_FRAME_X21_X22_PAIR = 0x00000002,
+ UNWIND_ARM64_FRAME_X23_X24_PAIR = 0x00000004,
+ UNWIND_ARM64_FRAME_X25_X26_PAIR = 0x00000008,
+ UNWIND_ARM64_FRAME_X27_X28_PAIR = 0x00000010,
+ UNWIND_ARM64_FRAME_D8_D9_PAIR = 0x00000100,
+ UNWIND_ARM64_FRAME_D10_D11_PAIR = 0x00000200,
+ UNWIND_ARM64_FRAME_D12_D13_PAIR = 0x00000400,
+ UNWIND_ARM64_FRAME_D14_D15_PAIR = 0x00000800,
+
+ UNWIND_ARM64_FRAMELESS_STACK_SIZE_MASK = 0x00FFF000,
+ UNWIND_ARM64_DWARF_SECTION_OFFSET = 0x00FFFFFF,
+ };
+
+ FLAGS_ANONYMOUS_ENUM()
+ {
+ UNWIND_ARM_MODE_MASK = 0x0F000000,
+ UNWIND_ARM_MODE_FRAME = 0x01000000,
+ UNWIND_ARM_MODE_FRAME_D = 0x02000000,
+ UNWIND_ARM_MODE_DWARF = 0x04000000,
+
+ UNWIND_ARM_FRAME_STACK_ADJUST_MASK = 0x00C00000,
+
+ UNWIND_ARM_FRAME_FIRST_PUSH_R4 = 0x00000001,
+ UNWIND_ARM_FRAME_FIRST_PUSH_R5 = 0x00000002,
+ UNWIND_ARM_FRAME_FIRST_PUSH_R6 = 0x00000004,
+
+ UNWIND_ARM_FRAME_SECOND_PUSH_R8 = 0x00000008,
+ UNWIND_ARM_FRAME_SECOND_PUSH_R9 = 0x00000010,
+ UNWIND_ARM_FRAME_SECOND_PUSH_R10 = 0x00000020,
+ UNWIND_ARM_FRAME_SECOND_PUSH_R11 = 0x00000040,
+ UNWIND_ARM_FRAME_SECOND_PUSH_R12 = 0x00000080,
+
+ UNWIND_ARM_FRAME_D_REG_COUNT_MASK = 0x00000700,
+
+ UNWIND_ARM_DWARF_SECTION_OFFSET = 0x00FFFFFF,
+ };
+
}
@@ -127,22 +173,20 @@ namespace lldb_private {
//----------------------
-// constructor
+// constructor
//----------------------
-
-CompactUnwindInfo::CompactUnwindInfo(ObjectFile& objfile, SectionSP& section_sp) :
- m_objfile (objfile),
- m_section_sp (section_sp),
- m_section_contents_if_encrypted (),
- m_mutex (),
- m_indexes (),
- m_indexes_computed (eLazyBoolCalculate),
- m_unwindinfo_data (),
- m_unwindinfo_data_computed (false),
- m_unwind_header ()
+CompactUnwindInfo::CompactUnwindInfo(ObjectFile &objfile, SectionSP &section_sp)
+ : m_objfile(objfile),
+ m_section_sp(section_sp),
+ m_section_contents_if_encrypted(),
+ m_mutex(),
+ m_indexes(),
+ m_indexes_computed(eLazyBoolCalculate),
+ m_unwindinfo_data(),
+ m_unwindinfo_data_computed(false),
+ m_unwind_header()
{
-
}
//----------------------
@@ -175,7 +219,7 @@ CompactUnwindInfo::GetUnwindPlan (Target &target, Address addr, UnwindPlan& unwi
if (log && log->GetVerbose())
{
StreamString strm;
- addr.Dump (&strm, NULL, Address::DumpStyle::DumpStyleResolvedDescriptionNoFunctionArguments, Address::DumpStyle::DumpStyleFileAddress, arch.GetAddressByteSize());
+ addr.Dump (&strm, NULL, Address::DumpStyle::DumpStyleResolvedDescriptionNoFunctionArguments, Address::DumpStyle::DumpStyleFileAddress, arch.GetAddressByteSize());
log->Printf ("Got compact unwind encoding 0x%x for function %s", function_info.encoding, strm.GetData());
}
@@ -184,7 +228,7 @@ CompactUnwindInfo::GetUnwindPlan (Target &target, Address addr, UnwindPlan& unwi
SectionList *sl = m_objfile.GetSectionList ();
if (sl)
{
- addr_t func_range_start_file_addr =
+ addr_t func_range_start_file_addr =
function_info.valid_range_offset_start + m_objfile.GetHeaderAddress().GetFileAddress();
AddressRange func_range (func_range_start_file_addr,
function_info.valid_range_offset_end - function_info.valid_range_offset_start,
@@ -197,10 +241,18 @@ CompactUnwindInfo::GetUnwindPlan (Target &target, Address addr, UnwindPlan& unwi
{
return CreateUnwindPlan_x86_64 (target, function_info, unwind_plan, addr);
}
+ if (arch.GetTriple().getArch() == llvm::Triple::aarch64)
+ {
+ return CreateUnwindPlan_arm64 (target, function_info, unwind_plan, addr);
+ }
if (arch.GetTriple().getArch() == llvm::Triple::x86)
{
return CreateUnwindPlan_i386 (target, function_info, unwind_plan, addr);
}
+ if (arch.GetTriple().getArch() == llvm::Triple::arm || arch.GetTriple().getArch() == llvm::Triple::thumb)
+ {
+ return CreateUnwindPlan_armv7 (target, function_info, unwind_plan, addr);
+ }
}
}
return false;
@@ -223,7 +275,7 @@ CompactUnwindInfo::IsValid (const ProcessSP &process_sp)
void
CompactUnwindInfo::ScanIndex (const ProcessSP &process_sp)
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::mutex> guard(m_mutex);
if (m_indexes_computed == eLazyBoolYes && m_unwindinfo_data_computed)
return;
@@ -248,8 +300,8 @@ CompactUnwindInfo::ScanIndex (const ProcessSP &process_sp)
m_section_contents_if_encrypted.reset (new DataBufferHeap (m_section_sp->GetByteSize(), 0));
Error error;
if (process_sp->ReadMemory (
- m_section_sp->GetLoadBaseAddress (&process_sp->GetTarget()),
- m_section_contents_if_encrypted->GetBytes(),
+ m_section_sp->GetLoadBaseAddress (&process_sp->GetTarget()),
+ m_section_contents_if_encrypted->GetBytes(),
m_section_sp->GetByteSize(), error) == m_section_sp->GetByteSize() && error.Success())
{
m_unwindinfo_data.SetAddressByteSize (process_sp->GetTarget().GetArchitecture().GetAddressByteSize());
@@ -279,7 +331,7 @@ CompactUnwindInfo::ScanIndex (const ProcessSP &process_sp)
// uint32_t personalityArrayCount;
// uint32_t indexSectionOffset;
// uint32_t indexCount;
-
+
m_unwind_header.version = m_unwindinfo_data.GetU32(&offset);
m_unwind_header.common_encodings_array_offset = m_unwindinfo_data.GetU32(&offset);
m_unwind_header.common_encodings_array_count = m_unwindinfo_data.GetU32(&offset);
@@ -305,13 +357,21 @@ CompactUnwindInfo::ScanIndex (const ProcessSP &process_sp)
// Parse the basic information from the indexes
// We wait to scan the second level page info until it's needed
- // struct unwind_info_section_header_index_entry
+ // struct unwind_info_section_header_index_entry
// {
// uint32_t functionOffset;
// uint32_t secondLevelPagesSectionOffset;
// uint32_t lsdaIndexArraySectionOffset;
// };
+ bool clear_address_zeroth_bit = false;
+ ArchSpec arch;
+ if (m_objfile.GetArchitecture (arch))
+ {
+ if (arch.GetTriple().getArch() == llvm::Triple::arm || arch.GetTriple().getArch() == llvm::Triple::thumb)
+ clear_address_zeroth_bit = true;
+ }
+
offset = indexSectionOffset;
for (uint32_t idx = 0; idx < indexCount; idx++)
{
@@ -324,8 +384,11 @@ CompactUnwindInfo::ScanIndex (const ProcessSP &process_sp)
m_indexes_computed = eLazyBoolNo;
}
+ if (clear_address_zeroth_bit)
+ function_offset &= ~1ull;
+
UnwindIndex this_index;
- this_index.function_offset = function_offset; //
+ this_index.function_offset = function_offset;
this_index.second_level = second_level_offset;
this_index.lsda_array_start = lsda_offset;
@@ -352,7 +415,7 @@ CompactUnwindInfo::ScanIndex (const ProcessSP &process_sp)
uint32_t
CompactUnwindInfo::GetLSDAForFunctionOffset (uint32_t lsda_offset, uint32_t lsda_count, uint32_t function_offset)
{
- // struct unwind_info_section_header_lsda_index_entry
+ // struct unwind_info_section_header_lsda_index_entry
// {
// uint32_t functionOffset;
// uint32_t lsdaOffset;
@@ -387,7 +450,7 @@ lldb::offset_t
CompactUnwindInfo::BinarySearchRegularSecondPage (uint32_t entry_page_offset, uint32_t entry_count, uint32_t function_offset, uint32_t *entry_func_start_offset, uint32_t *entry_func_end_offset)
{
// typedef uint32_t compact_unwind_encoding_t;
- // struct unwind_info_regular_second_level_entry
+ // struct unwind_info_regular_second_level_entry
// {
// uint32_t functionOffset;
// compact_unwind_encoding_t encoding;
@@ -502,10 +565,10 @@ CompactUnwindInfo::GetCompactUnwindInfoForFunction (Target &target, Address addr
return false;
addr_t function_offset = address.GetFileAddress() - m_objfile.GetHeaderAddress().GetFileAddress();
-
+
UnwindIndex key;
key.function_offset = function_offset;
-
+
std::vector<UnwindIndex>::const_iterator it;
it = std::lower_bound (m_indexes.begin(), m_indexes.end(), key);
if (it == m_indexes.end())
@@ -527,7 +590,7 @@ CompactUnwindInfo::GetCompactUnwindInfoForFunction (Target &target, Address addr
auto next_it = it + 1;
if (next_it != m_indexes.end())
{
- // initialize the function offset end range to be the start of the
+ // initialize the function offset end range to be the start of the
// next index offset. If we find an entry which is at the end of
// the index table, this will establish the range end.
unwind_info.valid_range_offset_end = next_it->function_offset;
@@ -549,7 +612,7 @@ CompactUnwindInfo::GetCompactUnwindInfoForFunction (Target &target, Address addr
// uint16_t entryCount;
// typedef uint32_t compact_unwind_encoding_t;
- // struct unwind_info_regular_second_level_entry
+ // struct unwind_info_regular_second_level_entry
// {
// uint32_t functionOffset;
// compact_unwind_encoding_t encoding;
@@ -604,9 +667,9 @@ CompactUnwindInfo::GetCompactUnwindInfoForFunction (Target &target, Address addr
// uint32_t kind; // UNWIND_SECOND_LEVEL_COMPRESSED
// uint16_t entryPageOffset; // offset from this 2nd lvl page idx to array of entries
// // (an entry has a function offset and index into the encodings)
- // // NB function offset from the entry in the compressed page
+ // // NB function offset from the entry in the compressed page
// // must be added to the index's functionOffset value.
- // uint16_t entryCount;
+ // uint16_t entryCount;
// uint16_t encodingsPageOffset; // offset from this 2nd lvl page idx to array of encodings
// uint16_t encodingsCount;
@@ -626,7 +689,7 @@ CompactUnwindInfo::GetCompactUnwindInfoForFunction (Target &target, Address addr
offset = m_unwind_header.common_encodings_array_offset + (encoding_index * sizeof (uint32_t));
encoding = m_unwindinfo_data.GetU32(&offset); // encoding entry from the commonEncodingsArray
}
- else
+ else
{
uint32_t page_specific_entry_index = encoding_index - m_unwind_header.common_encodings_array_count;
offset = second_page_offset + encodings_page_offset + (page_specific_entry_index * sizeof (uint32_t));
@@ -742,7 +805,7 @@ CompactUnwindInfo::CreateUnwindPlan_x86_64 (Target &target, FunctionInfo &functi
row->SetRegisterLocationToAtCFAPlusOffset (x86_64_eh_regnum::rbp, wordsize * -2, true);
row->SetRegisterLocationToAtCFAPlusOffset (x86_64_eh_regnum::rip, wordsize * -1, true);
row->SetRegisterLocationToIsCFAPlusOffset (x86_64_eh_regnum::rsp, 0, true);
-
+
uint32_t saved_registers_offset = EXTRACT_BITS (function_info.encoding, UNWIND_X86_64_RBP_FRAME_OFFSET);
uint32_t saved_registers_locations = EXTRACT_BITS (function_info.encoding, UNWIND_X86_64_RBP_FRAME_REGISTERS);
@@ -775,7 +838,7 @@ CompactUnwindInfo::CreateUnwindPlan_x86_64 (Target &target, FunctionInfo &functi
case UNWIND_X86_64_MODE_STACK_IND:
{
// The clang in Xcode 6 is emitting incorrect compact unwind encodings for this
- // style of unwind. It was fixed in llvm r217020.
+ // style of unwind. It was fixed in llvm r217020.
// The clang in Xcode 7 has this fixed.
return false;
}
@@ -838,7 +901,7 @@ CompactUnwindInfo::CreateUnwindPlan_x86_64 (Target &target, FunctionInfo &functi
// We need to include (up to) 6 registers in 10 bits.
// That would be 18 bits if we just used 3 bits per reg to indicate
- // the order they're saved on the stack.
+ // the order they're saved on the stack.
//
// This is done with Lehmer code permutation, e.g. see
// http://stackoverflow.com/questions/1506078/fast-permutation-number-permutation-mapping-algorithms
@@ -848,7 +911,7 @@ CompactUnwindInfo::CreateUnwindPlan_x86_64 (Target &target, FunctionInfo &functi
// and gives us the Lehmer code sequence which can then
// be decoded.
- switch (register_count)
+ switch (register_count)
{
case 6:
permunreg[0] = permutation/120; // 120 == 5!
@@ -898,7 +961,7 @@ CompactUnwindInfo::CreateUnwindPlan_x86_64 (Target &target, FunctionInfo &functi
permunreg[0] = permutation;
break;
}
-
+
// Decode the Lehmer code for this permutation of
// the registers v. http://en.wikipedia.org/wiki/Lehmer_code
@@ -1025,7 +1088,7 @@ CompactUnwindInfo::CreateUnwindPlan_i386 (Target &target, FunctionInfo &function
row->SetRegisterLocationToAtCFAPlusOffset (i386_eh_regnum::ebp, wordsize * -2, true);
row->SetRegisterLocationToAtCFAPlusOffset (i386_eh_regnum::eip, wordsize * -1, true);
row->SetRegisterLocationToIsCFAPlusOffset (i386_eh_regnum::esp, 0, true);
-
+
uint32_t saved_registers_offset = EXTRACT_BITS (function_info.encoding, UNWIND_X86_EBP_FRAME_OFFSET);
uint32_t saved_registers_locations = EXTRACT_BITS (function_info.encoding, UNWIND_X86_EBP_FRAME_REGISTERS);
@@ -1106,13 +1169,13 @@ CompactUnwindInfo::CreateUnwindPlan_i386 (Target &target, FunctionInfo &function
row->SetOffset (0);
row->SetRegisterLocationToAtCFAPlusOffset (i386_eh_regnum::eip, wordsize * -1, true);
row->SetRegisterLocationToIsCFAPlusOffset (i386_eh_regnum::esp, 0, true);
-
+
if (register_count > 0)
{
// We need to include (up to) 6 registers in 10 bits.
// That would be 18 bits if we just used 3 bits per reg to indicate
- // the order they're saved on the stack.
+ // the order they're saved on the stack.
//
// This is done with Lehmer code permutation, e.g. see
// http://stackoverflow.com/questions/1506078/fast-permutation-number-permutation-mapping-algorithms
@@ -1122,7 +1185,7 @@ CompactUnwindInfo::CreateUnwindPlan_i386 (Target &target, FunctionInfo &function
// and gives us the Lehmer code sequence which can then
// be decoded.
- switch (register_count)
+ switch (register_count)
{
case 6:
permunreg[0] = permutation/120; // 120 == 5!
@@ -1172,7 +1235,7 @@ CompactUnwindInfo::CreateUnwindPlan_i386 (Target &target, FunctionInfo &function
permunreg[0] = permutation;
break;
}
-
+
// Decode the Lehmer code for this permutation of
// the registers v. http://en.wikipedia.org/wiki/Lehmer_code
@@ -1231,3 +1294,380 @@ CompactUnwindInfo::CreateUnwindPlan_i386 (Target &target, FunctionInfo &function
}
return false;
}
+
+
+
+// DWARF register numbers from "DWARF for the ARM 64-bit Architecture (AArch64)" doc by ARM
+
+enum arm64_eh_regnum {
+ x19 = 19,
+ x20 = 20,
+ x21 = 21,
+ x22 = 22,
+ x23 = 23,
+ x24 = 24,
+ x25 = 25,
+ x26 = 26,
+ x27 = 27,
+ x28 = 28,
+
+ fp = 29,
+ ra = 30,
+ sp = 31,
+ pc = 32,
+
+ // Compact unwind encodes d8-d15 but we don't have eh_frame / dwarf reg #'s for the 64-bit
+ // fp regs. Normally in DWARF it's context sensitive - so it knows it is fetching a
+ // 32- or 64-bit quantity from reg v8 to indicate s0 or d0 - but the unwinder is operating
+ // at a lower level and we'd try to fetch 128 bits if we were told that v8 were stored on
+ // the stack...
+ v8 = 72,
+ v9 = 73,
+ v10 = 74,
+ v11 = 75,
+ v12 = 76,
+ v13 = 77,
+ v14 = 78,
+ v15 = 79,
+};
+
+enum arm_eh_regnum {
+ arm_r0 = 0,
+ arm_r1 = 1,
+ arm_r2 = 2,
+ arm_r3 = 3,
+ arm_r4 = 4,
+ arm_r5 = 5,
+ arm_r6 = 6,
+ arm_r7 = 7,
+ arm_r8 = 8,
+ arm_r9 = 9,
+ arm_r10 = 10,
+ arm_r11 = 11,
+ arm_r12 = 12,
+
+ arm_sp = 13,
+ arm_lr = 14,
+ arm_pc = 15,
+
+ arm_d0 = 256,
+ arm_d1 = 257,
+ arm_d2 = 258,
+ arm_d3 = 259,
+ arm_d4 = 260,
+ arm_d5 = 261,
+ arm_d6 = 262,
+ arm_d7 = 263,
+ arm_d8 = 264,
+ arm_d9 = 265,
+ arm_d10 = 266,
+ arm_d11 = 267,
+ arm_d12 = 268,
+ arm_d13 = 269,
+ arm_d14 = 270,
+};
+
+
+
+bool
+CompactUnwindInfo::CreateUnwindPlan_arm64 (Target &target, FunctionInfo &function_info, UnwindPlan &unwind_plan, Address pc_or_function_start)
+{
+ unwind_plan.SetSourceName ("compact unwind info");
+ unwind_plan.SetSourcedFromCompiler (eLazyBoolYes);
+ unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolNo);
+ unwind_plan.SetRegisterKind (eRegisterKindEHFrame);
+
+ unwind_plan.SetLSDAAddress (function_info.lsda_address);
+ unwind_plan.SetPersonalityFunctionPtr (function_info.personality_ptr_address);
+
+ UnwindPlan::RowSP row (new UnwindPlan::Row);
+
+ const int wordsize = 8;
+ int mode = function_info.encoding & UNWIND_ARM64_MODE_MASK;
+
+ if (mode == UNWIND_ARM64_MODE_DWARF)
+ return false;
+
+ if (mode == UNWIND_ARM64_MODE_FRAMELESS)
+ {
+ row->SetOffset (0);
+
+ uint32_t stack_size = (EXTRACT_BITS (function_info.encoding, UNWIND_ARM64_FRAMELESS_STACK_SIZE_MASK)) * 16;
+
+ // Our previous Call Frame Address is the stack pointer plus the stack size
+ row->GetCFAValue().SetIsRegisterPlusOffset (arm64_eh_regnum::sp, stack_size);
+
+ // Our previous PC is in the LR
+ row->SetRegisterLocationToRegister(arm64_eh_regnum::pc, arm64_eh_regnum::ra, true);
+
+ unwind_plan.AppendRow (row);
+ return true;
+ }
+
+ // Should not be possible
+ if (mode != UNWIND_ARM64_MODE_FRAME)
+ return false;
+
+
+ // mode == UNWIND_ARM64_MODE_FRAME
+
+ row->GetCFAValue().SetIsRegisterPlusOffset (arm64_eh_regnum::fp , 2 * wordsize);
+ row->SetOffset (0);
+ row->SetRegisterLocationToAtCFAPlusOffset (arm64_eh_regnum::fp, wordsize * -2, true);
+ row->SetRegisterLocationToAtCFAPlusOffset (arm64_eh_regnum::pc, wordsize * -1, true);
+ row->SetRegisterLocationToIsCFAPlusOffset (arm64_eh_regnum::sp, 0, true);
+
+ int reg_pairs_saved_count = 1;
+
+ uint32_t saved_register_bits = function_info.encoding & 0xfff;
+
+ if (saved_register_bits & UNWIND_ARM64_FRAME_X19_X20_PAIR)
+ {
+ int cfa_offset = reg_pairs_saved_count * -2 * wordsize;
+ cfa_offset -= wordsize;
+ row->SetRegisterLocationToAtCFAPlusOffset (arm64_eh_regnum::x19, cfa_offset, true);
+ cfa_offset -= wordsize;
+ row->SetRegisterLocationToAtCFAPlusOffset (arm64_eh_regnum::x20, cfa_offset, true);
+ reg_pairs_saved_count++;
+ }
+
+ if (saved_register_bits & UNWIND_ARM64_FRAME_X21_X22_PAIR)
+ {
+ int cfa_offset = reg_pairs_saved_count * -2 * wordsize;
+ cfa_offset -= wordsize;
+ row->SetRegisterLocationToAtCFAPlusOffset (arm64_eh_regnum::x21, cfa_offset, true);
+ cfa_offset -= wordsize;
+ row->SetRegisterLocationToAtCFAPlusOffset (arm64_eh_regnum::x22, cfa_offset, true);
+ reg_pairs_saved_count++;
+ }
+
+ if (saved_register_bits & UNWIND_ARM64_FRAME_X23_X24_PAIR)
+ {
+ int cfa_offset = reg_pairs_saved_count * -2 * wordsize;
+ cfa_offset -= wordsize;
+ row->SetRegisterLocationToAtCFAPlusOffset (arm64_eh_regnum::x23, cfa_offset, true);
+ cfa_offset -= wordsize;
+ row->SetRegisterLocationToAtCFAPlusOffset (arm64_eh_regnum::x24, cfa_offset, true);
+ reg_pairs_saved_count++;
+ }
+
+ if (saved_register_bits & UNWIND_ARM64_FRAME_X25_X26_PAIR)
+ {
+ int cfa_offset = reg_pairs_saved_count * -2 * wordsize;
+ cfa_offset -= wordsize;
+ row->SetRegisterLocationToAtCFAPlusOffset (arm64_eh_regnum::x25, cfa_offset, true);
+ cfa_offset -= wordsize;
+ row->SetRegisterLocationToAtCFAPlusOffset (arm64_eh_regnum::x26, cfa_offset, true);
+ reg_pairs_saved_count++;
+ }
+
+ if (saved_register_bits & UNWIND_ARM64_FRAME_X27_X28_PAIR)
+ {
+ int cfa_offset = reg_pairs_saved_count * -2 * wordsize;
+ cfa_offset -= wordsize;
+ row->SetRegisterLocationToAtCFAPlusOffset (arm64_eh_regnum::x27, cfa_offset, true);
+ cfa_offset -= wordsize;
+ row->SetRegisterLocationToAtCFAPlusOffset (arm64_eh_regnum::x28, cfa_offset, true);
+ reg_pairs_saved_count++;
+ }
+
+ // If we use the v8-v15 regnums here, the unwinder will try to grab 128 bits off the stack;
+ // not sure if we have a good way to represent the 64-bitness of these saves.
+
+ if (saved_register_bits & UNWIND_ARM64_FRAME_D8_D9_PAIR)
+ {
+ reg_pairs_saved_count++;
+ }
+ if (saved_register_bits & UNWIND_ARM64_FRAME_D10_D11_PAIR)
+ {
+ reg_pairs_saved_count++;
+ }
+ if (saved_register_bits & UNWIND_ARM64_FRAME_D12_D13_PAIR)
+ {
+ reg_pairs_saved_count++;
+ }
+ if (saved_register_bits & UNWIND_ARM64_FRAME_D14_D15_PAIR)
+ {
+ reg_pairs_saved_count++;
+ }
+
+ unwind_plan.AppendRow (row);
+ return true;
+}
+
+bool
+CompactUnwindInfo::CreateUnwindPlan_armv7 (Target &target, FunctionInfo &function_info, UnwindPlan &unwind_plan, Address pc_or_function_start)
+{
+ unwind_plan.SetSourceName ("compact unwind info");
+ unwind_plan.SetSourcedFromCompiler (eLazyBoolYes);
+ unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolNo);
+ unwind_plan.SetRegisterKind (eRegisterKindEHFrame);
+
+ unwind_plan.SetLSDAAddress (function_info.lsda_address);
+ unwind_plan.SetPersonalityFunctionPtr (function_info.personality_ptr_address);
+
+ UnwindPlan::RowSP row (new UnwindPlan::Row);
+
+ const int wordsize = 4;
+ int mode = function_info.encoding & UNWIND_ARM_MODE_MASK;
+
+ if (mode == UNWIND_ARM_MODE_DWARF)
+ return false;
+
+ uint32_t stack_adjust = (EXTRACT_BITS (function_info.encoding, UNWIND_ARM_FRAME_STACK_ADJUST_MASK)) * wordsize;
+
+ row->GetCFAValue().SetIsRegisterPlusOffset (arm_r7 , (2 * wordsize) + stack_adjust);
+ row->SetOffset (0);
+ row->SetRegisterLocationToAtCFAPlusOffset (arm_r7, (wordsize * -2) - stack_adjust, true);
+ row->SetRegisterLocationToAtCFAPlusOffset (arm_pc, (wordsize * -1) - stack_adjust, true);
+ row->SetRegisterLocationToIsCFAPlusOffset (arm_sp, 0, true);
+
+ int cfa_offset = -stack_adjust - (2 * wordsize);
+
+ uint32_t saved_register_bits = function_info.encoding & 0xff;
+
+ if (saved_register_bits & UNWIND_ARM_FRAME_FIRST_PUSH_R6)
+ {
+ cfa_offset -= wordsize;
+ row->SetRegisterLocationToAtCFAPlusOffset (arm_r6, cfa_offset, true);
+ }
+
+ if (saved_register_bits & UNWIND_ARM_FRAME_FIRST_PUSH_R5)
+ {
+ cfa_offset -= wordsize;
+ row->SetRegisterLocationToAtCFAPlusOffset (arm_r5, cfa_offset, true);
+ }
+
+ if (saved_register_bits & UNWIND_ARM_FRAME_FIRST_PUSH_R4)
+ {
+ cfa_offset -= wordsize;
+ row->SetRegisterLocationToAtCFAPlusOffset (arm_r4, cfa_offset, true);
+ }
+
+ if (saved_register_bits & UNWIND_ARM_FRAME_SECOND_PUSH_R12)
+ {
+ cfa_offset -= wordsize;
+ row->SetRegisterLocationToAtCFAPlusOffset (arm_r12, cfa_offset, true);
+ }
+
+ if (saved_register_bits & UNWIND_ARM_FRAME_SECOND_PUSH_R11)
+ {
+ cfa_offset -= wordsize;
+ row->SetRegisterLocationToAtCFAPlusOffset (arm_r11, cfa_offset, true);
+ }
+
+ if (saved_register_bits & UNWIND_ARM_FRAME_SECOND_PUSH_R10)
+ {
+ cfa_offset -= wordsize;
+ row->SetRegisterLocationToAtCFAPlusOffset (arm_r10, cfa_offset, true);
+ }
+
+ if (saved_register_bits & UNWIND_ARM_FRAME_SECOND_PUSH_R9)
+ {
+ cfa_offset -= wordsize;
+ row->SetRegisterLocationToAtCFAPlusOffset (arm_r9, cfa_offset, true);
+ }
+
+ if (saved_register_bits & UNWIND_ARM_FRAME_SECOND_PUSH_R8)
+ {
+ cfa_offset -= wordsize;
+ row->SetRegisterLocationToAtCFAPlusOffset (arm_r8, cfa_offset, true);
+ }
+
+
+ if (mode == UNWIND_ARM_MODE_FRAME_D)
+ {
+ uint32_t d_reg_bits = EXTRACT_BITS (function_info.encoding, UNWIND_ARM_FRAME_D_REG_COUNT_MASK);
+ switch (d_reg_bits)
+ {
+ case 0:
+ // vpush {d8}
+ cfa_offset -= 8;
+ row->SetRegisterLocationToAtCFAPlusOffset (arm_d8, cfa_offset, true);
+ break;
+ case 1:
+ // vpush {d10}
+ // vpush {d8}
+ cfa_offset -= 8;
+ row->SetRegisterLocationToAtCFAPlusOffset (arm_d10, cfa_offset, true);
+ cfa_offset -= 8;
+ row->SetRegisterLocationToAtCFAPlusOffset (arm_d8, cfa_offset, true);
+ break;
+ case 2:
+ // vpush {d12}
+ // vpush {d10}
+ // vpush {d8}
+ cfa_offset -= 8;
+ row->SetRegisterLocationToAtCFAPlusOffset (arm_d12, cfa_offset, true);
+ cfa_offset -= 8;
+ row->SetRegisterLocationToAtCFAPlusOffset (arm_d10, cfa_offset, true);
+ cfa_offset -= 8;
+ row->SetRegisterLocationToAtCFAPlusOffset (arm_d8, cfa_offset, true);
+ break;
+ case 3:
+ // vpush {d14}
+ // vpush {d12}
+ // vpush {d10}
+ // vpush {d8}
+ cfa_offset -= 8;
+ row->SetRegisterLocationToAtCFAPlusOffset (arm_d14, cfa_offset, true);
+ cfa_offset -= 8;
+ row->SetRegisterLocationToAtCFAPlusOffset (arm_d12, cfa_offset, true);
+ cfa_offset -= 8;
+ row->SetRegisterLocationToAtCFAPlusOffset (arm_d10, cfa_offset, true);
+ cfa_offset -= 8;
+ row->SetRegisterLocationToAtCFAPlusOffset (arm_d8, cfa_offset, true);
+ break;
+ case 4:
+ // vpush {d14}
+ // vpush {d12}
+ // sp = (sp - 24) & (-16);
+ // vst {d8, d9, d10}
+ cfa_offset -= 8;
+ row->SetRegisterLocationToAtCFAPlusOffset (arm_d14, cfa_offset, true);
+ cfa_offset -= 8;
+ row->SetRegisterLocationToAtCFAPlusOffset (arm_d12, cfa_offset, true);
+
+ // FIXME we don't have a way to represent reg saves at an specific alignment short of
+ // coming up with some DWARF location description.
+
+ break;
+ case 5:
+ // vpush {d14}
+ // sp = (sp - 40) & (-16);
+ // vst {d8, d9, d10, d11}
+ // vst {d12}
+
+ cfa_offset -= 8;
+ row->SetRegisterLocationToAtCFAPlusOffset (arm_d14, cfa_offset, true);
+
+ // FIXME we don't have a way to represent reg saves at an specific alignment short of
+ // coming up with some DWARF location description.
+
+ break;
+ case 6:
+ // sp = (sp - 56) & (-16);
+ // vst {d8, d9, d10, d11}
+ // vst {d12, d13, d14}
+
+ // FIXME we don't have a way to represent reg saves at an specific alignment short of
+ // coming up with some DWARF location description.
+
+ break;
+ case 7:
+ // sp = (sp - 64) & (-16);
+ // vst {d8, d9, d10, d11}
+ // vst {d12, d13, d14, d15}
+
+ // FIXME we don't have a way to represent reg saves at an specific alignment short of
+ // coming up with some DWARF location description.
+
+ break;
+ }
+ }
+
+ unwind_plan.AppendRow (row);
+ return true;
+}
+
+
diff --git a/source/Symbol/CompileUnit.cpp b/source/Symbol/CompileUnit.cpp
index 50eda8806375..259a450b7165 100644
--- a/source/Symbol/CompileUnit.cpp
+++ b/source/Symbol/CompileUnit.cpp
@@ -17,36 +17,40 @@
using namespace lldb;
using namespace lldb_private;
-CompileUnit::CompileUnit (const lldb::ModuleSP &module_sp, void *user_data, const char *pathname, const lldb::user_id_t cu_sym_id, lldb::LanguageType language, bool is_optimized) :
- ModuleChild(module_sp),
- FileSpec (pathname, false),
- UserID(cu_sym_id),
- m_user_data (user_data),
- m_language (language),
- m_flags (0),
- m_functions (),
- m_support_files (),
- m_line_table_ap (),
- m_variables(),
- m_is_optimized (is_optimized)
+CompileUnit::CompileUnit(const lldb::ModuleSP &module_sp, void *user_data, const char *pathname,
+ const lldb::user_id_t cu_sym_id, lldb::LanguageType language,
+ lldb_private::LazyBool is_optimized)
+ : ModuleChild(module_sp),
+ FileSpec(pathname, false),
+ UserID(cu_sym_id),
+ m_user_data(user_data),
+ m_language(language),
+ m_flags(0),
+ m_functions(),
+ m_support_files(),
+ m_line_table_ap(),
+ m_variables(),
+ m_is_optimized(is_optimized)
{
if (language != eLanguageTypeUnknown)
m_flags.Set(flagsParsedLanguage);
assert(module_sp);
}
-CompileUnit::CompileUnit (const lldb::ModuleSP &module_sp, void *user_data, const FileSpec &fspec, const lldb::user_id_t cu_sym_id, lldb::LanguageType language, bool is_optimized) :
- ModuleChild(module_sp),
- FileSpec (fspec),
- UserID(cu_sym_id),
- m_user_data (user_data),
- m_language (language),
- m_flags (0),
- m_functions (),
- m_support_files (),
- m_line_table_ap (),
- m_variables(),
- m_is_optimized (is_optimized)
+CompileUnit::CompileUnit(const lldb::ModuleSP &module_sp, void *user_data, const FileSpec &fspec,
+ const lldb::user_id_t cu_sym_id, lldb::LanguageType language,
+ lldb_private::LazyBool is_optimized)
+ : ModuleChild(module_sp),
+ FileSpec(fspec),
+ UserID(cu_sym_id),
+ m_user_data(user_data),
+ m_language(language),
+ m_flags(0),
+ m_functions(),
+ m_support_files(),
+ m_line_table_ap(),
+ m_variables(),
+ m_is_optimized(is_optimized)
{
if (language != eLanguageTypeUnknown)
m_flags.Set(flagsParsedLanguage);
@@ -468,6 +472,17 @@ CompileUnit::ResolveSymbolContext
bool
CompileUnit::GetIsOptimized ()
{
+ if (m_is_optimized == eLazyBoolCalculate)
+ {
+ m_is_optimized = eLazyBoolNo;
+ if (SymbolVendor *symbol_vendor = GetModule()->GetSymbolVendor())
+ {
+ SymbolContext sc;
+ CalculateSymbolContext(&sc);
+ if (symbol_vendor->ParseCompileUnitIsOptimized(sc))
+ m_is_optimized = eLazyBoolYes;
+ }
+ }
return m_is_optimized;
}
diff --git a/source/Symbol/CompilerDecl.cpp b/source/Symbol/CompilerDecl.cpp
index 42e5fb081071..98eef060df0e 100644
--- a/source/Symbol/CompilerDecl.cpp
+++ b/source/Symbol/CompilerDecl.cpp
@@ -31,12 +31,6 @@ CompilerDecl::GetMangledName () const
return m_type_system->DeclGetMangledName(m_opaque_decl);
}
-lldb::VariableSP
-CompilerDecl::GetAsVariable ()
-{
- return m_type_system->DeclGetVariable(m_opaque_decl);
-}
-
CompilerDeclContext
CompilerDecl::GetDeclContext() const
{
diff --git a/source/Symbol/CompilerDeclContext.cpp b/source/Symbol/CompilerDeclContext.cpp
index 8bee1b48753a..10a70d97f231 100644
--- a/source/Symbol/CompilerDeclContext.cpp
+++ b/source/Symbol/CompilerDeclContext.cpp
@@ -15,10 +15,11 @@
using namespace lldb_private;
std::vector<CompilerDecl>
-CompilerDeclContext::FindDeclByName (ConstString name)
+CompilerDeclContext::FindDeclByName (ConstString name, const bool ignore_using_decls)
{
if (IsValid())
- return m_type_system->DeclContextFindDeclByName(m_opaque_decl_ctx, name);
+ return m_type_system->DeclContextFindDeclByName(
+ m_opaque_decl_ctx, name, ignore_using_decls);
else
return std::vector<CompilerDecl>();
}
diff --git a/source/Symbol/CompilerType.cpp b/source/Symbol/CompilerType.cpp
index 000a949626c5..2b06c93c3f0d 100644
--- a/source/Symbol/CompilerType.cpp
+++ b/source/Symbol/CompilerType.cpp
@@ -177,7 +177,14 @@ CompilerType::IsFunctionPointerType () const
if (IsValid())
return m_type_system->IsFunctionPointerType(m_type);
return false;
+}
+bool
+CompilerType::IsBlockPointerType (CompilerType *function_pointer_type_ptr) const
+{
+ if (IsValid())
+ return m_type_system->IsBlockPointerType(m_type, function_pointer_type_ptr);
+ return 0;
}
bool
@@ -189,6 +196,20 @@ CompilerType::IsIntegerType (bool &is_signed) const
}
bool
+CompilerType::IsEnumerationType (bool &is_signed) const
+{
+ if (IsValid())
+ return m_type_system->IsEnumerationType(m_type, is_signed);
+ return false;
+}
+
+bool
+CompilerType::IsIntegerOrEnumerationType (bool &is_signed) const
+{
+ return IsIntegerType(is_signed) || IsEnumerationType(is_signed);
+}
+
+bool
CompilerType::IsPointerType (CompilerType *pointee_type) const
{
if (IsValid())
diff --git a/source/Symbol/DWARFCallFrameInfo.cpp b/source/Symbol/DWARFCallFrameInfo.cpp
index c357a5001690..6a4004bb7902 100644
--- a/source/Symbol/DWARFCallFrameInfo.cpp
+++ b/source/Symbol/DWARFCallFrameInfo.cpp
@@ -308,14 +308,22 @@ DWARFCallFrameInfo::GetFDEIndex ()
if (m_fde_index_initialized)
return;
-
- Mutex::Locker locker(m_fde_index_mutex);
-
+
+ std::lock_guard<std::mutex> guard(m_fde_index_mutex);
+
if (m_fde_index_initialized) // if two threads hit the locker
return;
Timer scoped_timer (__PRETTY_FUNCTION__, "%s - %s", __PRETTY_FUNCTION__, m_objfile.GetFileSpec().GetFilename().AsCString(""));
+ bool clear_address_zeroth_bit = false;
+ ArchSpec arch;
+ if (m_objfile.GetArchitecture (arch))
+ {
+ if (arch.GetTriple().getArch() == llvm::Triple::arm || arch.GetTriple().getArch() == llvm::Triple::thumb)
+ clear_address_zeroth_bit = true;
+ }
+
lldb::offset_t offset = 0;
if (m_cfi_data_initialized == false)
GetCFIData();
@@ -376,6 +384,9 @@ DWARFCallFrameInfo::GetFDEIndex ()
const lldb::addr_t data_addr = LLDB_INVALID_ADDRESS;
lldb::addr_t addr = m_cfi_data.GetGNUEHPointer(&offset, cie->ptr_encoding, pc_rel_addr, text_addr, data_addr);
+ if (clear_address_zeroth_bit)
+ addr &= ~1ull;
+
lldb::addr_t length = m_cfi_data.GetGNUEHPointer(&offset, cie->ptr_encoding & DW_EH_PE_MASK_ENCODING, pc_rel_addr, text_addr, data_addr);
FDEEntryMap::Entry fde (addr, length, current_entry);
m_fde_index.Append(fde);
@@ -397,6 +408,7 @@ DWARFCallFrameInfo::GetFDEIndex ()
bool
DWARFCallFrameInfo::FDEToUnwindPlan (dw_offset_t dwarf_offset, Address startaddr, UnwindPlan& unwind_plan)
{
+ Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND);
lldb::offset_t offset = dwarf_offset;
lldb::offset_t current_entry = offset;
@@ -637,6 +649,15 @@ DWARFCallFrameInfo::FDEToUnwindPlan (dw_offset_t dwarf_offset, Address startaddr
// the stack and place them in the current row. (This operation is
// useful for compilers that move epilogue code into the body of a
// function.)
+ if (stack.empty())
+ {
+ if (log)
+ log->Printf(
+ "DWARFCallFrameInfo::%s(dwarf_offset: %" PRIx32 ", startaddr: %" PRIx64
+ " encountered DW_CFA_restore_state but state stack is empty. Corrupt unwind info?",
+ __FUNCTION__, dwarf_offset, startaddr.GetFileAddress());
+ break;
+ }
lldb::addr_t offset = row->GetOffset ();
row = stack.back ();
stack.pop_back ();
@@ -644,6 +665,17 @@ DWARFCallFrameInfo::FDEToUnwindPlan (dw_offset_t dwarf_offset, Address startaddr
break;
}
+ case DW_CFA_GNU_args_size: // 0x2e
+ {
+ // The DW_CFA_GNU_args_size instruction takes an unsigned LEB128 operand
+ // representing an argument size. This instruction specifies the total of
+ // the size of the arguments which have been pushed onto the stack.
+
+ // TODO: Figure out how we should handle this.
+ m_cfi_data.GetULEB128(&offset);
+ break;
+ }
+
case DW_CFA_val_offset : // 0x14
case DW_CFA_val_offset_sf : // 0x15
default:
@@ -899,3 +931,17 @@ DWARFCallFrameInfo::HandleCommonDwarfOpcode(uint8_t primary_opcode,
}
return false;
}
+
+void
+DWARFCallFrameInfo::ForEachFDEEntries(
+ const std::function<bool(lldb::addr_t, uint32_t, dw_offset_t)>& callback)
+{
+ GetFDEIndex();
+
+ for (size_t i = 0, c = m_fde_index.GetSize(); i < c; ++i)
+ {
+ const FDEEntryMap::Entry& entry = m_fde_index.GetEntryRef(i);
+ if (!callback(entry.base, entry.size, entry.data))
+ break;
+ }
+}
diff --git a/source/Symbol/FuncUnwinders.cpp b/source/Symbol/FuncUnwinders.cpp
index 4c96b1a2bb1b..2fa41b84cb25 100644
--- a/source/Symbol/FuncUnwinders.cpp
+++ b/source/Symbol/FuncUnwinders.cpp
@@ -22,6 +22,7 @@
#include "lldb/Target/Thread.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/UnwindAssembly.h"
+#include "lldb/Utility/RegisterNumber.h"
using namespace lldb;
using namespace lldb_private;
@@ -30,27 +31,27 @@ using namespace lldb_private;
/// constructor
//------------------------------------------------
-FuncUnwinders::FuncUnwinders (UnwindTable& unwind_table, AddressRange range) :
- m_unwind_table (unwind_table),
- m_range (range),
- m_mutex (Mutex::eMutexTypeRecursive),
- m_unwind_plan_assembly_sp (),
- m_unwind_plan_eh_frame_sp (),
- m_unwind_plan_eh_frame_augmented_sp (),
- m_unwind_plan_compact_unwind (),
- m_unwind_plan_arm_unwind_sp (),
- m_unwind_plan_fast_sp (),
- m_unwind_plan_arch_default_sp (),
- m_unwind_plan_arch_default_at_func_entry_sp (),
- m_tried_unwind_plan_assembly (false),
- m_tried_unwind_plan_eh_frame (false),
- m_tried_unwind_plan_eh_frame_augmented (false),
- m_tried_unwind_plan_compact_unwind (false),
- m_tried_unwind_plan_arm_unwind (false),
- m_tried_unwind_fast (false),
- m_tried_unwind_arch_default (false),
- m_tried_unwind_arch_default_at_func_entry (false),
- m_first_non_prologue_insn ()
+FuncUnwinders::FuncUnwinders(UnwindTable &unwind_table, AddressRange range)
+ : m_unwind_table(unwind_table),
+ m_range(range),
+ m_mutex(),
+ m_unwind_plan_assembly_sp(),
+ m_unwind_plan_eh_frame_sp(),
+ m_unwind_plan_eh_frame_augmented_sp(),
+ m_unwind_plan_compact_unwind(),
+ m_unwind_plan_arm_unwind_sp(),
+ m_unwind_plan_fast_sp(),
+ m_unwind_plan_arch_default_sp(),
+ m_unwind_plan_arch_default_at_func_entry_sp(),
+ m_tried_unwind_plan_assembly(false),
+ m_tried_unwind_plan_eh_frame(false),
+ m_tried_unwind_plan_eh_frame_augmented(false),
+ m_tried_unwind_plan_compact_unwind(false),
+ m_tried_unwind_plan_arm_unwind(false),
+ m_tried_unwind_fast(false),
+ m_tried_unwind_arch_default(false),
+ m_tried_unwind_arch_default_at_func_entry(false),
+ m_first_non_prologue_insn()
{
}
@@ -65,7 +66,7 @@ FuncUnwinders::~FuncUnwinders ()
UnwindPlanSP
FuncUnwinders::GetUnwindPlanAtCallSite (Target &target, int current_offset)
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
UnwindPlanSP unwind_plan_sp = GetEHFrameUnwindPlan (target, current_offset);
if (unwind_plan_sp)
@@ -90,7 +91,7 @@ FuncUnwinders::GetCompactUnwindUnwindPlan (Target &target, int current_offset)
if (m_tried_unwind_plan_compact_unwind)
return UnwindPlanSP();
- Mutex::Locker lock (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
m_tried_unwind_plan_compact_unwind = true;
if (m_range.GetBaseAddress().IsValid())
{
@@ -117,7 +118,7 @@ FuncUnwinders::GetEHFrameUnwindPlan (Target &target, int current_offset)
if (m_unwind_plan_eh_frame_sp.get() || m_tried_unwind_plan_eh_frame)
return m_unwind_plan_eh_frame_sp;
- Mutex::Locker lock (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
m_tried_unwind_plan_eh_frame = true;
if (m_range.GetBaseAddress().IsValid())
{
@@ -141,7 +142,7 @@ FuncUnwinders::GetArmUnwindUnwindPlan (Target &target, int current_offset)
if (m_unwind_plan_arm_unwind_sp.get() || m_tried_unwind_plan_arm_unwind)
return m_unwind_plan_arm_unwind_sp;
- Mutex::Locker lock (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
m_tried_unwind_plan_arm_unwind = true;
if (m_range.GetBaseAddress().IsValid())
{
@@ -175,7 +176,7 @@ FuncUnwinders::GetEHFrameAugmentedUnwindPlan (Target &target, Thread &thread, in
return m_unwind_plan_eh_frame_augmented_sp;
}
- Mutex::Locker lock (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
m_tried_unwind_plan_eh_frame_augmented = true;
UnwindPlanSP eh_frame_plan = GetEHFrameUnwindPlan (target, current_offset);
@@ -206,10 +207,14 @@ FuncUnwinders::GetEHFrameAugmentedUnwindPlan (Target &target, Thread &thread, in
UnwindPlanSP
FuncUnwinders::GetAssemblyUnwindPlan (Target &target, Thread &thread, int current_offset)
{
- if (m_unwind_plan_assembly_sp.get() || m_tried_unwind_plan_assembly)
+ if (m_unwind_plan_assembly_sp.get()
+ || m_tried_unwind_plan_assembly
+ || m_unwind_table.GetAllowAssemblyEmulationUnwindPlans () == false)
+ {
return m_unwind_plan_assembly_sp;
+ }
- Mutex::Locker lock (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
m_tried_unwind_plan_assembly = true;
UnwindAssemblySP assembly_profiler_sp (GetUnwindAssemblyProfiler(target));
@@ -224,16 +229,81 @@ FuncUnwinders::GetAssemblyUnwindPlan (Target &target, Thread &thread, int curren
return m_unwind_plan_assembly_sp;
}
+// This method compares the pc unwind rule in the first row of two UnwindPlans.
+// If they have the same way of getting the pc value (e.g. "CFA - 8" + "CFA is sp"),
+// then it will return LazyBoolTrue.
+LazyBool
+FuncUnwinders::CompareUnwindPlansForIdenticalInitialPCLocation (Thread& thread, const UnwindPlanSP &a, const UnwindPlanSP &b)
+{
+ LazyBool plans_are_identical = eLazyBoolCalculate;
+
+ RegisterNumber pc_reg (thread, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
+ uint32_t pc_reg_lldb_regnum = pc_reg.GetAsKind (eRegisterKindLLDB);
+
+ if (a.get() && b.get())
+ {
+ UnwindPlan::RowSP a_first_row = a->GetRowAtIndex (0);
+ UnwindPlan::RowSP b_first_row = b->GetRowAtIndex (0);
+
+ if (a_first_row.get() && b_first_row.get())
+ {
+ UnwindPlan::Row::RegisterLocation a_pc_regloc;
+ UnwindPlan::Row::RegisterLocation b_pc_regloc;
+
+ a_first_row->GetRegisterInfo (pc_reg_lldb_regnum, a_pc_regloc);
+ b_first_row->GetRegisterInfo (pc_reg_lldb_regnum, b_pc_regloc);
+
+ plans_are_identical = eLazyBoolYes;
+
+ if (a_first_row->GetCFAValue() != b_first_row->GetCFAValue())
+ {
+ plans_are_identical = eLazyBoolNo;
+ }
+ if (a_pc_regloc != b_pc_regloc)
+ {
+ plans_are_identical = eLazyBoolNo;
+ }
+ }
+ }
+ return plans_are_identical;
+}
UnwindPlanSP
FuncUnwinders::GetUnwindPlanAtNonCallSite (Target& target, Thread& thread, int current_offset)
{
- UnwindPlanSP non_call_site_unwindplan_sp = GetEHFrameAugmentedUnwindPlan (target, thread, current_offset);
- if (non_call_site_unwindplan_sp.get() == nullptr)
+ UnwindPlanSP eh_frame_sp = GetEHFrameUnwindPlan (target, current_offset);
+ UnwindPlanSP arch_default_at_entry_sp = GetUnwindPlanArchitectureDefaultAtFunctionEntry (thread);
+ UnwindPlanSP arch_default_sp = GetUnwindPlanArchitectureDefault (thread);
+ UnwindPlanSP assembly_sp = GetAssemblyUnwindPlan (target, thread, current_offset);
+
+ // This point of this code is to detect when a function is using a non-standard ABI, and the eh_frame
+ // correctly describes that alternate ABI. This is addressing a specific situation on x86_64 linux
+ // systems where one function in a library pushes a value on the stack and jumps to another function.
+ // So using an assembly instruction based unwind will not work when you're in the second function -
+ // the stack has been modified in a non-ABI way. But we have eh_frame that correctly describes how to
+ // unwind from this location. So we're looking to see if the initial pc register save location from
+ // the eh_frame is different from the assembly unwind, the arch default unwind, and the arch default at
+ // initial function entry.
+ //
+ // We may have eh_frame that describes the entire function -- or we may have eh_frame that only describes
+ // the unwind after the prologue has executed -- so we need to check both the arch default (once the prologue
+ // has executed) and the arch default at initial function entry. And we may be running on a target where
+ // we have only some of the assembly/arch default unwind plans available.
+
+ if (CompareUnwindPlansForIdenticalInitialPCLocation (thread, eh_frame_sp, arch_default_at_entry_sp) == eLazyBoolNo
+ && CompareUnwindPlansForIdenticalInitialPCLocation (thread, eh_frame_sp, arch_default_sp) == eLazyBoolNo
+ && CompareUnwindPlansForIdenticalInitialPCLocation (thread, assembly_sp, arch_default_sp) == eLazyBoolNo)
{
- non_call_site_unwindplan_sp = GetAssemblyUnwindPlan (target, thread, current_offset);
+ return eh_frame_sp;
}
- return non_call_site_unwindplan_sp;
+
+ UnwindPlanSP eh_frame_augmented_sp = GetEHFrameAugmentedUnwindPlan (target, thread, current_offset);
+ if (eh_frame_augmented_sp)
+ {
+ return eh_frame_augmented_sp;
+ }
+
+ return assembly_sp;
}
UnwindPlanSP
@@ -242,7 +312,7 @@ FuncUnwinders::GetUnwindPlanFastUnwind (Target& target, Thread& thread)
if (m_unwind_plan_fast_sp.get() || m_tried_unwind_fast)
return m_unwind_plan_fast_sp;
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
m_tried_unwind_fast = true;
UnwindAssemblySP assembly_profiler_sp (GetUnwindAssemblyProfiler(target));
@@ -263,7 +333,7 @@ FuncUnwinders::GetUnwindPlanArchitectureDefault (Thread& thread)
if (m_unwind_plan_arch_default_sp.get() || m_tried_unwind_arch_default)
return m_unwind_plan_arch_default_sp;
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
m_tried_unwind_arch_default = true;
Address current_pc;
@@ -290,7 +360,7 @@ FuncUnwinders::GetUnwindPlanArchitectureDefaultAtFunctionEntry (Thread& thread)
if (m_unwind_plan_arch_default_at_func_entry_sp.get() || m_tried_unwind_arch_default_at_func_entry)
return m_unwind_plan_arch_default_at_func_entry_sp;
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
m_tried_unwind_arch_default_at_func_entry = true;
Address current_pc;
@@ -318,7 +388,7 @@ FuncUnwinders::GetFirstNonPrologueInsn (Target& target)
if (m_first_non_prologue_insn.IsValid())
return m_first_non_prologue_insn;
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
ExecutionContext exe_ctx (target.shared_from_this(), false);
UnwindAssemblySP assembly_profiler_sp (GetUnwindAssemblyProfiler(target));
if (assembly_profiler_sp)
diff --git a/source/Symbol/Function.cpp b/source/Symbol/Function.cpp
index 33cc0c4e264c..598af270bddf 100644
--- a/source/Symbol/Function.cpp
+++ b/source/Symbol/Function.cpp
@@ -570,6 +570,8 @@ Function::GetPrologueByteSize ()
{
m_flags.Set(flagsCalculatedPrologueSize);
LineTable* line_table = m_comp_unit->GetLineTable ();
+ uint32_t prologue_end_line_idx = 0;
+
if (line_table)
{
LineEntry first_line_entry;
@@ -578,9 +580,12 @@ Function::GetPrologueByteSize ()
{
// Make sure the first line entry isn't already the end of the prologue
addr_t prologue_end_file_addr = LLDB_INVALID_ADDRESS;
+ addr_t line_zero_end_file_addr = LLDB_INVALID_ADDRESS;
+
if (first_line_entry.is_prologue_end)
{
prologue_end_file_addr = first_line_entry.range.GetBaseAddress().GetFileAddress();
+ prologue_end_line_idx = first_line_entry_idx;
}
else
{
@@ -595,6 +600,7 @@ Function::GetPrologueByteSize ()
if (line_entry.is_prologue_end)
{
prologue_end_file_addr = line_entry.range.GetBaseAddress().GetFileAddress();
+ prologue_end_line_idx = idx;
break;
}
}
@@ -607,7 +613,7 @@ Function::GetPrologueByteSize ()
{
// Check the first few instructions and look for one that has
// a line number that's different than the first entry.
- const uint32_t last_line_entry_idx = first_line_entry_idx + 6;
+ uint32_t last_line_entry_idx = first_line_entry_idx + 6;
for (uint32_t idx = first_line_entry_idx + 1; idx < last_line_entry_idx; ++idx)
{
LineEntry line_entry;
@@ -616,6 +622,7 @@ Function::GetPrologueByteSize ()
if (line_entry.line != first_line_entry.line)
{
prologue_end_file_addr = line_entry.range.GetBaseAddress().GetFileAddress();
+ prologue_end_line_idx = idx;
break;
}
}
@@ -624,10 +631,37 @@ Function::GetPrologueByteSize ()
if (prologue_end_file_addr == LLDB_INVALID_ADDRESS)
{
prologue_end_file_addr = first_line_entry.range.GetBaseAddress().GetFileAddress() + first_line_entry.range.GetByteSize();
+ prologue_end_line_idx = first_line_entry_idx;
}
}
+
const addr_t func_start_file_addr = m_range.GetBaseAddress().GetFileAddress();
const addr_t func_end_file_addr = func_start_file_addr + m_range.GetByteSize();
+
+ // Now calculate the offset to pass the subsequent line 0 entries.
+ uint32_t first_non_zero_line = prologue_end_line_idx;
+ while (1)
+ {
+ LineEntry line_entry;
+ if (line_table->GetLineEntryAtIndex(first_non_zero_line, line_entry))
+ {
+ if (line_entry.line != 0)
+ break;
+ }
+ if (line_entry.range.GetBaseAddress().GetFileAddress() >= func_end_file_addr)
+ break;
+
+ first_non_zero_line++;
+ }
+
+ if (first_non_zero_line > prologue_end_line_idx)
+ {
+ LineEntry first_non_zero_entry;
+ if (line_table->GetLineEntryAtIndex(first_non_zero_line, first_non_zero_entry))
+ {
+ line_zero_end_file_addr = first_non_zero_entry.range.GetBaseAddress().GetFileAddress();
+ }
+ }
// Verify that this prologue end file address in the function's
// address range just to be sure
@@ -635,10 +669,16 @@ Function::GetPrologueByteSize ()
{
m_prologue_byte_size = prologue_end_file_addr - func_start_file_addr;
}
+
+ if (prologue_end_file_addr < line_zero_end_file_addr && line_zero_end_file_addr < func_end_file_addr)
+ {
+ m_prologue_byte_size += line_zero_end_file_addr - prologue_end_file_addr;
+ }
}
}
}
- return m_prologue_byte_size;
+
+ return m_prologue_byte_size;
}
lldb::LanguageType
diff --git a/source/Symbol/GoASTContext.cpp b/source/Symbol/GoASTContext.cpp
index 1993f2331058..faca778f069c 100644
--- a/source/Symbol/GoASTContext.cpp
+++ b/source/Symbol/GoASTContext.cpp
@@ -538,6 +538,12 @@ GoASTContext::IsFunctionPointerType(lldb::opaque_compiler_type_t type)
}
bool
+GoASTContext::IsBlockPointerType (lldb::opaque_compiler_type_t type, CompilerType *function_pointer_type_ptr)
+{
+ return false;
+}
+
+bool
GoASTContext::IsIntegerType(lldb::opaque_compiler_type_t type, bool &is_signed)
{
is_signed = false;
diff --git a/source/Symbol/JavaASTContext.cpp b/source/Symbol/JavaASTContext.cpp
new file mode 100644
index 000000000000..45cda8d5112b
--- /dev/null
+++ b/source/Symbol/JavaASTContext.cpp
@@ -0,0 +1,1561 @@
+//===-- JavaASTContext.cpp --------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <sstream>
+
+#include "lldb/Core/ArchSpec.h"
+#include "lldb/Core/DataExtractor.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/Stream.h"
+#include "lldb/Core/StreamFile.h"
+#include "lldb/Core/ValueObject.h"
+#include "lldb/Expression/DWARFExpression.h"
+#include "lldb/Symbol/CompilerType.h"
+#include "lldb/Symbol/JavaASTContext.h"
+#include "lldb/Symbol/SymbolFile.h"
+#include "lldb/Symbol/Type.h"
+#include "lldb/Target/Target.h"
+
+#include "Plugins/SymbolFile/DWARF/DWARFASTParserJava.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+namespace lldb_private
+{
+
+class JavaASTContext::JavaType
+{
+public:
+ enum LLVMCastKind
+ {
+ eKindPrimitive,
+ eKindObject,
+ eKindReference,
+ eKindArray,
+ kNumKinds
+ };
+
+ JavaType(LLVMCastKind kind) : m_kind(kind) {}
+
+ virtual ~JavaType() = default;
+
+ virtual ConstString
+ GetName() = 0;
+
+ virtual void
+ Dump(Stream *s) = 0;
+
+ virtual bool
+ IsCompleteType() = 0;
+
+ LLVMCastKind
+ getKind() const
+ {
+ return m_kind;
+ }
+
+private:
+ LLVMCastKind m_kind;
+};
+
+} // end of namespace lldb_private
+
+namespace
+{
+
+class JavaPrimitiveType : public JavaASTContext::JavaType
+{
+public:
+ enum TypeKind
+ {
+ eTypeByte,
+ eTypeShort,
+ eTypeInt,
+ eTypeLong,
+ eTypeFloat,
+ eTypeDouble,
+ eTypeBoolean,
+ eTypeChar,
+ };
+
+ JavaPrimitiveType(TypeKind type_kind) : JavaType(JavaType::eKindPrimitive), m_type_kind(type_kind) {}
+
+ ConstString
+ GetName() override
+ {
+ switch (m_type_kind)
+ {
+ case eTypeByte:
+ return ConstString("byte");
+ case eTypeShort:
+ return ConstString("short");
+ case eTypeInt:
+ return ConstString("int");
+ case eTypeLong:
+ return ConstString("long");
+ case eTypeFloat:
+ return ConstString("float");
+ case eTypeDouble:
+ return ConstString("double");
+ case eTypeBoolean:
+ return ConstString("boolean");
+ case eTypeChar:
+ return ConstString("char");
+ }
+ return ConstString();
+ }
+
+ TypeKind
+ GetTypeKind()
+ {
+ return m_type_kind;
+ }
+
+ void
+ Dump(Stream *s) override
+ {
+ s->Printf("%s\n", GetName().GetCString());
+ }
+
+ bool
+ IsCompleteType() override
+ {
+ return true;
+ }
+
+ static bool
+ classof(const JavaType *jt)
+ {
+ return jt->getKind() == JavaType::eKindPrimitive;
+ }
+
+private:
+ const TypeKind m_type_kind;
+};
+
+class JavaDynamicType : public JavaASTContext::JavaType
+{
+public:
+ JavaDynamicType(LLVMCastKind kind, const ConstString &linkage_name) :
+ JavaType(kind),
+ m_linkage_name(linkage_name),
+ m_dynamic_type_id(nullptr)
+ {
+ }
+
+ ConstString
+ GetLinkageName() const
+ {
+ return m_linkage_name;
+ }
+
+ void
+ SetDynamicTypeId(const DWARFExpression &type_id)
+ {
+ m_dynamic_type_id = type_id;
+ }
+
+ uint64_t
+ CalculateDynamicTypeId(ExecutionContext *exe_ctx, ValueObject &value_obj)
+ {
+ if (!m_dynamic_type_id.IsValid())
+ return UINT64_MAX;
+
+ Value obj_load_address = value_obj.GetValue();
+ obj_load_address.ResolveValue(exe_ctx);
+ obj_load_address.SetValueType(Value::eValueTypeLoadAddress);
+
+ Value result;
+ if (m_dynamic_type_id.Evaluate(exe_ctx->GetBestExecutionContextScope(), nullptr, nullptr, 0, &obj_load_address,
+ nullptr, result, nullptr))
+ {
+ Error error;
+
+ lldb::addr_t type_id_addr = result.GetScalar().UInt();
+ lldb::ProcessSP process_sp = exe_ctx->GetProcessSP();
+ if (process_sp)
+ return process_sp->ReadUnsignedIntegerFromMemory(type_id_addr, process_sp->GetAddressByteSize(),
+ UINT64_MAX, error);
+ }
+
+ return UINT64_MAX;
+ }
+
+public:
+ ConstString m_linkage_name;
+ DWARFExpression m_dynamic_type_id;
+};
+
+class JavaObjectType : public JavaDynamicType
+{
+public:
+ struct Field
+ {
+ ConstString m_name;
+ CompilerType m_type;
+ uint32_t m_offset;
+ };
+
+ JavaObjectType(const ConstString &name, const ConstString &linkage_name, uint32_t byte_size)
+ : JavaDynamicType(JavaType::eKindObject, linkage_name),
+ m_name(name),
+ m_byte_size(byte_size),
+ m_base_class_offset(0),
+ m_is_complete(false)
+ {
+ }
+
+ ConstString
+ GetName() override
+ {
+ return m_name;
+ }
+
+ uint32_t
+ GetByteSize() const
+ {
+ return m_byte_size;
+ }
+
+ uint32_t
+ GetNumFields()
+ {
+ return m_fields.size();
+ }
+
+ void
+ Dump(Stream *s) override
+ {
+ if (m_base_class.IsValid())
+ s->Printf("%s : %s\n", GetName().GetCString(), m_base_class.GetTypeName().GetCString());
+ else
+ s->Printf("%s\n", GetName().GetCString());
+
+ s->IndentMore();
+ for (const Field &f : m_fields)
+ s->Printf("%s %s\n", f.m_type.GetTypeName().GetCString(), f.m_name.GetCString());
+ s->IndentLess();
+ }
+
+ Field *
+ GetFieldAtIndex(size_t idx)
+ {
+ if (idx < m_fields.size())
+ return &m_fields[idx];
+ return nullptr;
+ }
+
+ CompilerType
+ GetBaseClass()
+ {
+ return m_base_class;
+ }
+
+ uint32_t
+ GetBaseClassOffset()
+ {
+ return m_base_class_offset;
+ }
+
+ uint32_t
+ GetNumInterfaces()
+ {
+ return m_interfaces.size();
+ }
+
+ CompilerType
+ GetInterfaceAtIndex(uint32_t idx)
+ {
+ if (m_interfaces.size() < idx)
+ return m_interfaces[idx];
+ return CompilerType();
+ }
+
+ bool
+ IsCompleteType() override
+ {
+ return m_is_complete;
+ }
+
+ void
+ SetCompleteType(bool is_complete)
+ {
+ m_is_complete = is_complete;
+ if (m_byte_size == 0)
+ {
+ // Try to calcualte the size of the object based on it's values
+ for (const Field &field : m_fields)
+ {
+ uint32_t field_end = field.m_offset + field.m_type.GetByteSize(nullptr);
+ if (field_end > m_byte_size)
+ m_byte_size = field_end;
+ }
+ }
+ }
+
+ void
+ AddBaseClass(const CompilerType &type, uint32_t offset)
+ {
+ // TODO: Check if type is an interface and add it to the interface list in that case
+ m_base_class = type;
+ m_base_class_offset = offset;
+ }
+
+ void
+ AddField(const ConstString &name, const CompilerType &type, uint32_t offset)
+ {
+ m_fields.push_back({name, type, offset});
+ }
+
+ static bool
+ classof(const JavaType *jt)
+ {
+ return jt->getKind() == JavaType::eKindObject;
+ }
+
+private:
+ ConstString m_name;
+ uint32_t m_byte_size;
+ CompilerType m_base_class;
+ uint32_t m_base_class_offset;
+ std::vector<CompilerType> m_interfaces;
+ std::vector<Field> m_fields;
+ bool m_is_complete;
+};
+
+class JavaReferenceType : public JavaASTContext::JavaType
+{
+public:
+ JavaReferenceType(CompilerType pointee_type) : JavaType(JavaType::eKindReference), m_pointee_type(pointee_type) {}
+
+ static bool
+ classof(const JavaType *jt)
+ {
+ return jt->getKind() == JavaType::eKindReference;
+ }
+
+ CompilerType
+ GetPointeeType()
+ {
+ return m_pointee_type;
+ }
+
+ ConstString
+ GetName() override
+ {
+ ConstString pointee_type_name = static_cast<JavaType *>(GetPointeeType().GetOpaqueQualType())->GetName();
+ return ConstString(std::string(pointee_type_name.AsCString()) + "&");
+ }
+
+ void
+ Dump(Stream *s) override
+ {
+ static_cast<JavaType *>(m_pointee_type.GetOpaqueQualType())->Dump(s);
+ }
+
+ bool
+ IsCompleteType() override
+ {
+ return m_pointee_type.IsCompleteType();
+ }
+
+private:
+ CompilerType m_pointee_type;
+};
+
+class JavaArrayType : public JavaDynamicType
+{
+public:
+ JavaArrayType(const ConstString& linkage_name, CompilerType element_type, const DWARFExpression &length_expression,
+ lldb::addr_t data_offset)
+ : JavaDynamicType(JavaType::eKindArray, linkage_name),
+ m_element_type(element_type),
+ m_length_expression(length_expression),
+ m_data_offset(data_offset)
+ {
+ }
+
+ static bool
+ classof(const JavaType *jt)
+ {
+ return jt->getKind() == JavaType::eKindArray;
+ }
+
+ CompilerType
+ GetElementType()
+ {
+ return m_element_type;
+ }
+
+ ConstString
+ GetName() override
+ {
+ ConstString element_type_name = static_cast<JavaType *>(GetElementType().GetOpaqueQualType())->GetName();
+ return ConstString(std::string(element_type_name.AsCString()) + "[]");
+ }
+
+ void
+ Dump(Stream *s) override
+ {
+ s->Printf("%s\n", GetName().GetCString());
+ }
+
+ bool
+ IsCompleteType() override
+ {
+ return m_length_expression.IsValid();
+ }
+
+ uint32_t
+ GetNumElements(ValueObject *value_obj)
+ {
+ if (!m_length_expression.IsValid())
+ return UINT32_MAX;
+
+ Error error;
+ ValueObjectSP address_obj = value_obj->AddressOf(error);
+ if (error.Fail())
+ return UINT32_MAX;
+
+ Value obj_load_address = address_obj->GetValue();
+ obj_load_address.SetValueType(Value::eValueTypeLoadAddress);
+
+ Value result;
+ ExecutionContextScope* exec_ctx_scope = value_obj->GetExecutionContextRef().Lock(true).GetBestExecutionContextScope();
+ if (m_length_expression.Evaluate(exec_ctx_scope, nullptr, nullptr, 0, nullptr, &obj_load_address, result, nullptr))
+ return result.GetScalar().UInt();
+
+ return UINT32_MAX;
+ }
+
+ uint64_t
+ GetElementOffset(size_t idx)
+ {
+ return m_data_offset + idx * m_element_type.GetByteSize(nullptr);
+ }
+
+private:
+ CompilerType m_element_type;
+ DWARFExpression m_length_expression;
+ lldb::addr_t m_data_offset;
+};
+
+} // end of anonymous namespace
+
+ConstString
+JavaASTContext::GetPluginNameStatic()
+{
+ return ConstString("java");
+}
+
+ConstString
+JavaASTContext::GetPluginName()
+{
+ return JavaASTContext::GetPluginNameStatic();
+}
+
+uint32_t
+JavaASTContext::GetPluginVersion()
+{
+ return 1;
+}
+
+lldb::TypeSystemSP
+JavaASTContext::CreateInstance(lldb::LanguageType language, Module *module, Target *target)
+{
+ if (language == eLanguageTypeJava)
+ {
+ if (module)
+ return std::make_shared<JavaASTContext>(module->GetArchitecture());
+ if (target)
+ return std::make_shared<JavaASTContext>(target->GetArchitecture());
+ assert(false && "Either a module or a target has to be specifed to create a JavaASTContext");
+ }
+ return lldb::TypeSystemSP();
+}
+
+void
+JavaASTContext::EnumerateSupportedLanguages(std::set<lldb::LanguageType> &languages_for_types,
+ std::set<lldb::LanguageType> &languages_for_expressions)
+{
+ static std::vector<lldb::LanguageType> s_languages_for_types({lldb::eLanguageTypeJava});
+ static std::vector<lldb::LanguageType> s_languages_for_expressions({});
+
+ languages_for_types.insert(s_languages_for_types.begin(), s_languages_for_types.end());
+ languages_for_expressions.insert(s_languages_for_expressions.begin(), s_languages_for_expressions.end());
+}
+
+void
+JavaASTContext::Initialize()
+{
+ PluginManager::RegisterPlugin(GetPluginNameStatic(), "AST context plug-in", CreateInstance,
+ EnumerateSupportedLanguages);
+}
+
+void
+JavaASTContext::Terminate()
+{
+ PluginManager::UnregisterPlugin(CreateInstance);
+}
+
+JavaASTContext::JavaASTContext(const ArchSpec &arch)
+ : TypeSystem(eKindJava), m_pointer_byte_size(arch.GetAddressByteSize())
+{
+}
+
+JavaASTContext::~JavaASTContext()
+{
+}
+
+uint32_t
+JavaASTContext::GetPointerByteSize()
+{
+ return m_pointer_byte_size;
+}
+
+DWARFASTParser *
+JavaASTContext::GetDWARFParser()
+{
+ if (!m_dwarf_ast_parser_ap)
+ m_dwarf_ast_parser_ap.reset(new DWARFASTParserJava(*this));
+ return m_dwarf_ast_parser_ap.get();
+}
+
+ConstString
+JavaASTContext::DeclGetName(void *opaque_decl)
+{
+ return ConstString();
+}
+
+std::vector<CompilerDecl>
+JavaASTContext::DeclContextFindDeclByName(void *opaque_decl_ctx, ConstString name, const bool ignore_imported_decls)
+{
+ return std::vector<CompilerDecl>();
+}
+
+bool
+JavaASTContext::DeclContextIsStructUnionOrClass(void *opaque_decl_ctx)
+{
+ return false;
+}
+
+ConstString
+JavaASTContext::DeclContextGetName(void *opaque_decl_ctx)
+{
+ return ConstString();
+}
+
+bool
+JavaASTContext::DeclContextIsClassMethod(void *opaque_decl_ctx, lldb::LanguageType *language_ptr,
+ bool *is_instance_method_ptr, ConstString *language_object_name_ptr)
+{
+ return false;
+}
+
+bool
+JavaASTContext::IsArrayType(lldb::opaque_compiler_type_t type, CompilerType *element_type, uint64_t *size,
+ bool *is_incomplete)
+{
+ if (element_type)
+ element_type->Clear();
+ if (size)
+ *size = 0;
+ if (is_incomplete)
+ *is_incomplete = false;
+
+ if (JavaArrayType *array = llvm::dyn_cast<JavaArrayType>(static_cast<JavaType *>(type)))
+ {
+ if (element_type)
+ *element_type = array->GetElementType();
+ return true;
+ }
+ return false;
+}
+
+bool
+JavaASTContext::IsAggregateType(lldb::opaque_compiler_type_t type)
+{
+ return llvm::isa<JavaObjectType>(static_cast<JavaType *>(type));
+}
+
+bool
+JavaASTContext::IsCharType(lldb::opaque_compiler_type_t type)
+{
+ if (JavaPrimitiveType *ptype = llvm::dyn_cast<JavaPrimitiveType>(static_cast<JavaType *>(type)))
+ return ptype->GetTypeKind() == JavaPrimitiveType::eTypeChar;
+ return false;
+}
+
+bool
+JavaASTContext::IsFloatingPointType(lldb::opaque_compiler_type_t type, uint32_t &count, bool &is_complex)
+{
+ is_complex = true;
+
+ if (JavaPrimitiveType *ptype = llvm::dyn_cast<JavaPrimitiveType>(static_cast<JavaType *>(type)))
+ {
+ switch (ptype->GetTypeKind())
+ {
+ case JavaPrimitiveType::eTypeFloat:
+ case JavaPrimitiveType::eTypeDouble:
+ count = 1;
+ return true;
+ default:
+ break;
+ }
+ }
+
+ count = 0;
+ return false;
+}
+
+bool
+JavaASTContext::IsFunctionType(lldb::opaque_compiler_type_t type, bool *is_variadic_ptr)
+{
+ if (is_variadic_ptr)
+ *is_variadic_ptr = false;
+ return false;
+}
+
+size_t
+JavaASTContext::GetNumberOfFunctionArguments(lldb::opaque_compiler_type_t type)
+{
+ return 0;
+}
+
+CompilerType
+JavaASTContext::GetFunctionArgumentAtIndex(lldb::opaque_compiler_type_t type, const size_t index)
+{
+ return CompilerType();
+}
+
+bool
+JavaASTContext::IsFunctionPointerType(lldb::opaque_compiler_type_t type)
+{
+ return false;
+}
+
+bool
+JavaASTContext::IsBlockPointerType (lldb::opaque_compiler_type_t type, CompilerType *function_pointer_type_ptr)
+{
+ return false;
+}
+
+bool
+JavaASTContext::IsIntegerType(lldb::opaque_compiler_type_t type, bool &is_signed)
+{
+ if (JavaPrimitiveType *ptype = llvm::dyn_cast<JavaPrimitiveType>(static_cast<JavaType *>(type)))
+ {
+ switch (ptype->GetTypeKind())
+ {
+ case JavaPrimitiveType::eTypeByte:
+ case JavaPrimitiveType::eTypeShort:
+ case JavaPrimitiveType::eTypeInt:
+ case JavaPrimitiveType::eTypeLong:
+ is_signed = true;
+ return true;
+ default:
+ break;
+ }
+ }
+
+ is_signed = false;
+ return false;
+}
+
+bool
+JavaASTContext::IsPossibleDynamicType(lldb::opaque_compiler_type_t type, CompilerType *target_type,
+ bool check_cplusplus, bool check_objc)
+{
+ return llvm::isa<JavaReferenceType>(static_cast<JavaType *>(type));
+}
+
+bool
+JavaASTContext::IsPointerType(lldb::opaque_compiler_type_t type, CompilerType *pointee_type)
+{
+ if (pointee_type)
+ pointee_type->Clear();
+ return false;
+}
+
+bool
+JavaASTContext::IsReferenceType(lldb::opaque_compiler_type_t type, CompilerType *pointee_type, bool *is_rvalue)
+{
+ if (is_rvalue)
+ *is_rvalue = false;
+
+ if (JavaReferenceType *ref = llvm::dyn_cast<JavaReferenceType>(static_cast<JavaType *>(type)))
+ {
+ if (pointee_type)
+ *pointee_type = ref->GetPointeeType();
+ return true;
+ }
+
+ if (pointee_type)
+ pointee_type->Clear();
+ return false;
+}
+
+bool
+JavaASTContext::IsScalarType(lldb::opaque_compiler_type_t type)
+{
+ return llvm::isa<JavaReferenceType>(static_cast<JavaType *>(type)) ||
+ llvm::isa<JavaPrimitiveType>(static_cast<JavaType *>(type));
+}
+
+bool
+JavaASTContext::IsVoidType(lldb::opaque_compiler_type_t type)
+{
+ return false; // TODO: Implement if we introduce the void type
+}
+
+bool
+JavaASTContext::SupportsLanguage(lldb::LanguageType language)
+{
+ return language == lldb::eLanguageTypeJava;
+}
+
+bool
+JavaASTContext::IsRuntimeGeneratedType(lldb::opaque_compiler_type_t type)
+{
+ return true;
+}
+
+bool
+JavaASTContext::IsPointerOrReferenceType(lldb::opaque_compiler_type_t type, CompilerType *pointee_type)
+{
+ return IsPointerType(type, pointee_type) || IsReferenceType(type, pointee_type);
+}
+
+bool
+JavaASTContext::IsCStringType(lldb::opaque_compiler_type_t type, uint32_t &length)
+{
+ return false; // TODO: Implement it if we need it for string literals
+}
+
+bool
+JavaASTContext::IsTypedefType(lldb::opaque_compiler_type_t type)
+{
+ return false;
+}
+
+bool
+JavaASTContext::IsVectorType(lldb::opaque_compiler_type_t type, CompilerType *element_type, uint64_t *size)
+{
+ if (element_type)
+ element_type->Clear();
+ if (size)
+ *size = 0;
+ return false;
+}
+
+bool
+JavaASTContext::IsPolymorphicClass(lldb::opaque_compiler_type_t type)
+{
+ return llvm::isa<JavaObjectType>(static_cast<JavaType *>(type));
+}
+
+uint32_t
+JavaASTContext::IsHomogeneousAggregate(lldb::opaque_compiler_type_t type, CompilerType *base_type_ptr)
+{
+ return false;
+}
+
+bool
+JavaASTContext::IsCompleteType(lldb::opaque_compiler_type_t type)
+{
+ return static_cast<JavaType *>(type)->IsCompleteType();
+}
+
+bool
+JavaASTContext::IsConst(lldb::opaque_compiler_type_t type)
+{
+ return false;
+}
+
+bool
+JavaASTContext::IsBeingDefined(lldb::opaque_compiler_type_t type)
+{
+ return false;
+}
+
+bool
+JavaASTContext::IsDefined(lldb::opaque_compiler_type_t type)
+{
+ return type != nullptr;
+}
+
+bool
+JavaASTContext::GetCompleteType(lldb::opaque_compiler_type_t type)
+{
+ if (IsCompleteType(type))
+ return true;
+
+ if (JavaArrayType *array = llvm::dyn_cast<JavaArrayType>(static_cast<JavaType *>(type)))
+ return GetCompleteType(array->GetElementType().GetOpaqueQualType());
+
+ if (JavaReferenceType *reference = llvm::dyn_cast<JavaReferenceType>(static_cast<JavaType *>(type)))
+ return GetCompleteType(reference->GetPointeeType().GetOpaqueQualType());
+
+ if (llvm::isa<JavaObjectType>(static_cast<JavaType *>(type)))
+ {
+ SymbolFile *symbol_file = GetSymbolFile();
+ if (!symbol_file)
+ return false;
+
+ CompilerType object_type(this, type);
+ return symbol_file->CompleteType(object_type);
+ }
+ return false;
+}
+
+ConstString
+JavaASTContext::GetTypeName(lldb::opaque_compiler_type_t type)
+{
+ if (type)
+ return static_cast<JavaType *>(type)->GetName();
+ return ConstString();
+}
+
+uint32_t
+JavaASTContext::GetTypeInfo(lldb::opaque_compiler_type_t type, CompilerType *pointee_or_element_compiler_type)
+{
+ if (pointee_or_element_compiler_type)
+ pointee_or_element_compiler_type->Clear();
+ if (!type)
+ return 0;
+
+ if (IsReferenceType(type, pointee_or_element_compiler_type))
+ return eTypeHasChildren | eTypeHasValue | eTypeIsReference;
+ if (IsArrayType(type, pointee_or_element_compiler_type, nullptr, nullptr))
+ return eTypeHasChildren | eTypeIsArray;
+ if (llvm::isa<JavaObjectType>(static_cast<JavaType *>(type)))
+ return eTypeHasChildren | eTypeIsClass;
+
+ if (JavaPrimitiveType *ptype = llvm::dyn_cast<JavaPrimitiveType>(static_cast<JavaType *>(type)))
+ {
+ switch (ptype->GetTypeKind())
+ {
+ case JavaPrimitiveType::eTypeByte:
+ case JavaPrimitiveType::eTypeShort:
+ case JavaPrimitiveType::eTypeInt:
+ case JavaPrimitiveType::eTypeLong:
+ return eTypeHasValue | eTypeIsBuiltIn | eTypeIsScalar | eTypeIsInteger | eTypeIsSigned;
+ case JavaPrimitiveType::eTypeFloat:
+ case JavaPrimitiveType::eTypeDouble:
+ return eTypeHasValue | eTypeIsBuiltIn | eTypeIsScalar | eTypeIsFloat | eTypeIsSigned;
+ case JavaPrimitiveType::eTypeBoolean:
+ return eTypeHasValue | eTypeIsBuiltIn | eTypeIsScalar;
+ case JavaPrimitiveType::eTypeChar:
+ return eTypeHasValue | eTypeIsBuiltIn | eTypeIsScalar;
+ }
+ }
+ return 0;
+}
+
+lldb::TypeClass
+JavaASTContext::GetTypeClass(lldb::opaque_compiler_type_t type)
+{
+ if (!type)
+ return eTypeClassInvalid;
+ if (llvm::isa<JavaReferenceType>(static_cast<JavaType *>(type)))
+ return eTypeClassReference;
+ if (llvm::isa<JavaArrayType>(static_cast<JavaType *>(type)))
+ return eTypeClassArray;
+ if (llvm::isa<JavaObjectType>(static_cast<JavaType *>(type)))
+ return eTypeClassClass;
+ if (llvm::isa<JavaPrimitiveType>(static_cast<JavaType *>(type)))
+ return eTypeClassBuiltin;
+ assert(false && "Java type with unhandled type class");
+ return eTypeClassInvalid;
+}
+
+lldb::LanguageType
+JavaASTContext::GetMinimumLanguage(lldb::opaque_compiler_type_t type)
+{
+ return lldb::eLanguageTypeJava;
+}
+
+CompilerType
+JavaASTContext::GetArrayElementType(lldb::opaque_compiler_type_t type, uint64_t *stride)
+{
+ if (stride)
+ *stride = 0;
+
+ CompilerType element_type;
+ if (IsArrayType(type, &element_type, nullptr, nullptr))
+ return element_type;
+ return CompilerType();
+}
+
+CompilerType
+JavaASTContext::GetPointeeType(lldb::opaque_compiler_type_t type)
+{
+ CompilerType pointee_type;
+ if (IsPointerType(type, &pointee_type))
+ return pointee_type;
+ return CompilerType();
+}
+
+CompilerType
+JavaASTContext::GetPointerType(lldb::opaque_compiler_type_t type)
+{
+ return CompilerType(); // No pointer types in java
+}
+
+CompilerType
+JavaASTContext::GetCanonicalType(lldb::opaque_compiler_type_t type)
+{
+ return CompilerType(this, type);
+}
+
+CompilerType
+JavaASTContext::GetFullyUnqualifiedType(lldb::opaque_compiler_type_t type)
+{
+ return CompilerType(this, type);
+}
+
+CompilerType
+JavaASTContext::GetNonReferenceType(lldb::opaque_compiler_type_t type)
+{
+ CompilerType pointee_type;
+ if (IsReferenceType(type, &pointee_type))
+ return pointee_type;
+ return CompilerType(this, type);
+}
+
+CompilerType
+JavaASTContext::GetTypedefedType(lldb::opaque_compiler_type_t type)
+{
+ return CompilerType();
+}
+
+CompilerType
+JavaASTContext::GetBasicTypeFromAST(lldb::BasicType basic_type)
+{
+ return CompilerType();
+}
+
+CompilerType
+JavaASTContext::GetBuiltinTypeForEncodingAndBitSize(lldb::Encoding encoding, size_t bit_size)
+{
+ return CompilerType();
+}
+
+size_t
+JavaASTContext::GetTypeBitAlign(lldb::opaque_compiler_type_t type)
+{
+ return 0;
+}
+
+lldb::BasicType
+JavaASTContext::GetBasicTypeEnumeration(lldb::opaque_compiler_type_t type)
+{
+ if (JavaPrimitiveType *ptype = llvm::dyn_cast<JavaPrimitiveType>(static_cast<JavaType *>(type)))
+ {
+ switch (ptype->GetTypeKind())
+ {
+ case JavaPrimitiveType::eTypeByte:
+ return eBasicTypeOther;
+ case JavaPrimitiveType::eTypeShort:
+ return eBasicTypeShort;
+ case JavaPrimitiveType::eTypeInt:
+ return eBasicTypeInt;
+ case JavaPrimitiveType::eTypeLong:
+ return eBasicTypeLong;
+ case JavaPrimitiveType::eTypeFloat:
+ return eBasicTypeFloat;
+ case JavaPrimitiveType::eTypeDouble:
+ return eBasicTypeDouble;
+ case JavaPrimitiveType::eTypeBoolean:
+ return eBasicTypeBool;
+ case JavaPrimitiveType::eTypeChar:
+ return eBasicTypeChar;
+ }
+ }
+ return eBasicTypeInvalid;
+}
+
+uint64_t
+JavaASTContext::GetBitSize(lldb::opaque_compiler_type_t type, ExecutionContextScope *exe_scope)
+{
+ if (JavaPrimitiveType *ptype = llvm::dyn_cast<JavaPrimitiveType>(static_cast<JavaType *>(type)))
+ {
+ switch (ptype->GetTypeKind())
+ {
+ case JavaPrimitiveType::eTypeByte:
+ return 8;
+ case JavaPrimitiveType::eTypeShort:
+ return 16;
+ case JavaPrimitiveType::eTypeInt:
+ return 32;
+ case JavaPrimitiveType::eTypeLong:
+ return 64;
+ case JavaPrimitiveType::eTypeFloat:
+ return 32;
+ case JavaPrimitiveType::eTypeDouble:
+ return 64;
+ case JavaPrimitiveType::eTypeBoolean:
+ return 1;
+ case JavaPrimitiveType::eTypeChar:
+ return 16;
+ }
+ }
+ else if (llvm::isa<JavaReferenceType>(static_cast<JavaType *>(type)))
+ {
+ return 32; // References are always 4 byte long in java
+ }
+ else if (llvm::isa<JavaArrayType>(static_cast<JavaType *>(type)))
+ {
+ return 64;
+ }
+ else if (JavaObjectType *obj = llvm::dyn_cast<JavaObjectType>(static_cast<JavaType *>(type)))
+ {
+ return obj->GetByteSize() * 8;
+ }
+ return 0;
+}
+
+lldb::Encoding
+JavaASTContext::GetEncoding(lldb::opaque_compiler_type_t type, uint64_t &count)
+{
+ count = 1;
+
+ if (JavaPrimitiveType *ptype = llvm::dyn_cast<JavaPrimitiveType>(static_cast<JavaType *>(type)))
+ {
+ switch (ptype->GetTypeKind())
+ {
+ case JavaPrimitiveType::eTypeByte:
+ case JavaPrimitiveType::eTypeShort:
+ case JavaPrimitiveType::eTypeInt:
+ case JavaPrimitiveType::eTypeLong:
+ return eEncodingSint;
+ case JavaPrimitiveType::eTypeFloat:
+ case JavaPrimitiveType::eTypeDouble:
+ return eEncodingIEEE754;
+ case JavaPrimitiveType::eTypeBoolean:
+ case JavaPrimitiveType::eTypeChar:
+ return eEncodingUint;
+ }
+ }
+ if (IsReferenceType(type))
+ return eEncodingUint;
+ return eEncodingInvalid;
+}
+
+lldb::Format
+JavaASTContext::GetFormat(lldb::opaque_compiler_type_t type)
+{
+ if (JavaPrimitiveType *ptype = llvm::dyn_cast<JavaPrimitiveType>(static_cast<JavaType *>(type)))
+ {
+ switch (ptype->GetTypeKind())
+ {
+ case JavaPrimitiveType::eTypeByte:
+ case JavaPrimitiveType::eTypeShort:
+ case JavaPrimitiveType::eTypeInt:
+ case JavaPrimitiveType::eTypeLong:
+ return eFormatDecimal;
+ case JavaPrimitiveType::eTypeFloat:
+ case JavaPrimitiveType::eTypeDouble:
+ return eFormatFloat;
+ case JavaPrimitiveType::eTypeBoolean:
+ return eFormatBoolean;
+ case JavaPrimitiveType::eTypeChar:
+ return eFormatUnicode16;
+ }
+ }
+ if (IsReferenceType(type))
+ return eFormatHex;
+ return eFormatDefault;
+}
+
+unsigned
+JavaASTContext::GetTypeQualifiers(lldb::opaque_compiler_type_t type)
+{
+ return 0;
+}
+
+size_t
+JavaASTContext::ConvertStringToFloatValue(lldb::opaque_compiler_type_t type, const char *s, uint8_t *dst,
+ size_t dst_size)
+{
+ assert(false && "Not implemented");
+ return 0;
+}
+
+size_t
+JavaASTContext::GetNumTemplateArguments(lldb::opaque_compiler_type_t type)
+{
+ return 0;
+}
+
+CompilerType
+JavaASTContext::GetTemplateArgument(lldb::opaque_compiler_type_t type, size_t idx, lldb::TemplateArgumentKind &kind)
+{
+ return CompilerType();
+}
+
+uint32_t
+JavaASTContext::GetNumFields(lldb::opaque_compiler_type_t type)
+{
+ if (JavaObjectType *obj = llvm::dyn_cast<JavaObjectType>(static_cast<JavaType *>(type)))
+ {
+ GetCompleteType(type);
+ return obj->GetNumFields();
+ }
+ return 0;
+}
+
+CompilerType
+JavaASTContext::GetFieldAtIndex(lldb::opaque_compiler_type_t type, size_t idx, std::string &name,
+ uint64_t *bit_offset_ptr, uint32_t *bitfield_bit_size_ptr, bool *is_bitfield_ptr)
+{
+ if (bit_offset_ptr)
+ *bit_offset_ptr = 0;
+ if (bitfield_bit_size_ptr)
+ *bitfield_bit_size_ptr = 0;
+ if (is_bitfield_ptr)
+ *is_bitfield_ptr = false;
+
+ if (JavaObjectType *obj = llvm::dyn_cast<JavaObjectType>(static_cast<JavaType *>(type)))
+ {
+ GetCompleteType(type);
+
+ JavaObjectType::Field *field = obj->GetFieldAtIndex(idx);
+ if (!field)
+ return CompilerType();
+ name = field->m_name.AsCString();
+ if (bit_offset_ptr)
+ *bit_offset_ptr = field->m_offset * 8;
+ return field->m_type;
+ }
+ return CompilerType();
+}
+
+uint32_t
+JavaASTContext::GetNumChildren(lldb::opaque_compiler_type_t type, bool omit_empty_base_classes)
+{
+ GetCompleteType(type);
+
+ if (JavaReferenceType *ref = llvm::dyn_cast<JavaReferenceType>(static_cast<JavaType *>(type)))
+ return ref->GetPointeeType().GetNumChildren(omit_empty_base_classes);
+
+ if (llvm::isa<JavaObjectType>(static_cast<JavaType *>(type)))
+ return GetNumFields(type) + GetNumDirectBaseClasses(type);
+
+ return 0;
+}
+
+uint32_t
+JavaASTContext::GetNumDirectBaseClasses(lldb::opaque_compiler_type_t type)
+{
+ if (JavaObjectType *obj = llvm::dyn_cast<JavaObjectType>(static_cast<JavaType *>(type)))
+ {
+ GetCompleteType(type);
+ return obj->GetNumInterfaces() + (obj->GetBaseClass() ? 1 : 0);
+ }
+ return 0;
+}
+
+uint32_t
+JavaASTContext::GetNumVirtualBaseClasses(lldb::opaque_compiler_type_t type)
+{
+ if (JavaObjectType *obj = llvm::dyn_cast<JavaObjectType>(static_cast<JavaType *>(type)))
+ {
+ GetCompleteType(type);
+ return obj->GetNumInterfaces();
+ }
+ return 0;
+}
+
+CompilerType
+JavaASTContext::GetDirectBaseClassAtIndex(lldb::opaque_compiler_type_t type, size_t idx, uint32_t *bit_offset_ptr)
+{
+ if (JavaObjectType *obj = llvm::dyn_cast<JavaObjectType>(static_cast<JavaType *>(type)))
+ {
+ GetCompleteType(type);
+
+ if (CompilerType base_class = obj->GetBaseClass())
+ {
+ if (idx == 0)
+ return base_class;
+ else
+ --idx;
+ }
+ return obj->GetInterfaceAtIndex(idx);
+ }
+ return CompilerType();
+}
+
+CompilerType
+JavaASTContext::GetVirtualBaseClassAtIndex(lldb::opaque_compiler_type_t type, size_t idx, uint32_t *bit_offset_ptr)
+{
+ if (JavaObjectType *obj = llvm::dyn_cast<JavaObjectType>(static_cast<JavaType *>(type)))
+ {
+ GetCompleteType(type);
+ return obj->GetInterfaceAtIndex(idx);
+ }
+ return CompilerType();
+}
+
+void
+JavaASTContext::DumpValue(lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, Stream *s, lldb::Format format,
+ const DataExtractor &data, lldb::offset_t data_offset, size_t data_byte_size,
+ uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset, bool show_types, bool show_summary,
+ bool verbose, uint32_t depth)
+{
+ assert(false && "Not implemented");
+}
+
+bool
+JavaASTContext::DumpTypeValue(lldb::opaque_compiler_type_t type, Stream *s, lldb::Format format,
+ const DataExtractor &data, lldb::offset_t data_offset, size_t data_byte_size,
+ uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset,
+ ExecutionContextScope *exe_scope)
+{
+ if (IsScalarType(type))
+ {
+ return data.Dump(s, data_offset, format, data_byte_size,
+ 1, // count
+ UINT32_MAX, LLDB_INVALID_ADDRESS, bitfield_bit_size, bitfield_bit_offset, exe_scope);
+ }
+ return false;
+}
+
+void
+JavaASTContext::DumpTypeDescription(lldb::opaque_compiler_type_t type)
+{
+ StreamFile s(stdout, false);
+ DumpTypeDescription(type, &s);
+}
+
+void
+JavaASTContext::DumpTypeDescription(lldb::opaque_compiler_type_t type, Stream *s)
+{
+ static_cast<JavaType *>(type)->Dump(s);
+}
+
+void
+JavaASTContext::DumpSummary(lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, Stream *s,
+ const DataExtractor &data, lldb::offset_t data_offset, size_t data_byte_size)
+{
+ assert(false && "Not implemented");
+}
+
+int
+JavaASTContext::GetFunctionArgumentCount(lldb::opaque_compiler_type_t type)
+{
+ return 0;
+}
+
+CompilerType
+JavaASTContext::GetFunctionArgumentTypeAtIndex(lldb::opaque_compiler_type_t type, size_t idx)
+{
+ return CompilerType();
+}
+
+CompilerType
+JavaASTContext::GetFunctionReturnType(lldb::opaque_compiler_type_t type)
+{
+ return CompilerType();
+}
+
+size_t
+JavaASTContext::GetNumMemberFunctions(lldb::opaque_compiler_type_t type)
+{
+ return 0;
+}
+
+TypeMemberFunctionImpl
+JavaASTContext::GetMemberFunctionAtIndex(lldb::opaque_compiler_type_t type, size_t idx)
+{
+ return TypeMemberFunctionImpl();
+}
+
+CompilerType
+JavaASTContext::GetChildCompilerTypeAtIndex(lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, size_t idx,
+ bool transparent_pointers, bool omit_empty_base_classes,
+ bool ignore_array_bounds, std::string &child_name,
+ uint32_t &child_byte_size, int32_t &child_byte_offset,
+ uint32_t &child_bitfield_bit_size, uint32_t &child_bitfield_bit_offset,
+ bool &child_is_base_class, bool &child_is_deref_of_parent,
+ ValueObject *valobj, uint64_t &language_flags)
+{
+ child_name.clear();
+ child_byte_size = 0;
+ child_byte_offset = 0;
+ child_bitfield_bit_size = 0;
+ child_bitfield_bit_offset = 0;
+ child_is_base_class = false;
+ child_is_deref_of_parent = false;
+ language_flags = 0;
+
+ ExecutionContextScope *exec_ctx_scope = exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr;
+
+ if (JavaObjectType *obj = llvm::dyn_cast<JavaObjectType>(static_cast<JavaType *>(type)))
+ {
+ GetCompleteType(type);
+
+ if (CompilerType base_class = obj->GetBaseClass())
+ {
+ if (idx == 0)
+ {
+ JavaType *base_class_type = static_cast<JavaType *>(base_class.GetOpaqueQualType());
+ child_name = base_class_type->GetName().GetCString();
+ child_byte_size = base_class.GetByteSize(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr);
+ child_byte_offset = obj->GetBaseClassOffset();
+ child_is_base_class = true;
+ return base_class;
+ }
+ idx -= 1;
+ }
+
+ JavaObjectType::Field *field = obj->GetFieldAtIndex(idx);
+ if (!field)
+ return CompilerType();
+
+ child_name = field->m_name.AsCString();
+ child_byte_size = field->m_type.GetByteSize(exec_ctx_scope);
+ child_byte_offset = field->m_offset;
+ return field->m_type;
+ }
+ else if (JavaReferenceType *ref = llvm::dyn_cast<JavaReferenceType>(static_cast<JavaType *>(type)))
+ {
+ CompilerType pointee_type = ref->GetPointeeType();
+
+ if (transparent_pointers)
+ return pointee_type.GetChildCompilerTypeAtIndex(
+ exe_ctx, idx, transparent_pointers, omit_empty_base_classes, ignore_array_bounds, child_name,
+ child_byte_size, child_byte_offset, child_bitfield_bit_size, child_bitfield_bit_offset,
+ child_is_base_class, child_is_deref_of_parent, valobj, language_flags);
+
+ if (idx != 0)
+ return CompilerType();
+
+ if (valobj && valobj->GetName())
+ child_name = valobj->GetName().GetCString();
+ child_is_deref_of_parent = true;
+ child_byte_offset = 0;
+ child_byte_size = pointee_type.GetByteSize(exec_ctx_scope);
+ return pointee_type;
+ }
+ return CompilerType();
+}
+
+uint32_t
+JavaASTContext::GetIndexOfChildWithName(lldb::opaque_compiler_type_t type, const char *name,
+ bool omit_empty_base_classes)
+{
+ if (JavaObjectType *obj = llvm::dyn_cast<JavaObjectType>(static_cast<JavaType *>(type)))
+ {
+ GetCompleteType(type);
+
+ uint32_t index_offset = 0;
+ if (CompilerType base_class = obj->GetBaseClass())
+ {
+ if (base_class.GetTypeName() == ConstString(name))
+ return 0;
+ index_offset = 1;
+ }
+ for (uint32_t i = 0; i < obj->GetNumFields(); ++i)
+ {
+ if (obj->GetFieldAtIndex(i)->m_name == ConstString(name))
+ return i + index_offset;
+ }
+ }
+ else if (JavaReferenceType *ref = llvm::dyn_cast<JavaReferenceType>(static_cast<JavaType *>(type)))
+ {
+ return GetIndexOfChildWithName(ref->GetPointeeType().GetOpaqueQualType(), name, omit_empty_base_classes);
+ }
+ return UINT_MAX;
+}
+
+size_t
+JavaASTContext::GetIndexOfChildMemberWithName(lldb::opaque_compiler_type_t type, const char *name,
+ bool omit_empty_base_classes, std::vector<uint32_t> &child_indexes)
+{
+ child_indexes.clear();
+
+ if (JavaObjectType *obj = llvm::dyn_cast<JavaObjectType>(static_cast<JavaType *>(type)))
+ {
+ GetCompleteType(type);
+
+ uint32_t index_offset = 0;
+ if (CompilerType base_class = obj->GetBaseClass())
+ {
+ if (GetIndexOfChildMemberWithName(base_class.GetOpaqueQualType(), name, omit_empty_base_classes,
+ child_indexes) != 0)
+ {
+ child_indexes.insert(child_indexes.begin(), 0);
+ return child_indexes.size();
+ }
+ index_offset = 1;
+ }
+
+ for (uint32_t i = 0; i < obj->GetNumFields(); ++i)
+ {
+ if (obj->GetFieldAtIndex(i)->m_name == ConstString(name))
+ {
+ child_indexes.push_back(i + index_offset);
+ return child_indexes.size();
+ }
+ }
+ }
+ else if (JavaReferenceType *ref = llvm::dyn_cast<JavaReferenceType>(static_cast<JavaType *>(type)))
+ {
+ return GetIndexOfChildMemberWithName(ref->GetPointeeType().GetOpaqueQualType(), name, omit_empty_base_classes,
+ child_indexes);
+ }
+ return 0;
+}
+
+CompilerType
+JavaASTContext::GetLValueReferenceType(lldb::opaque_compiler_type_t type)
+{
+ return CreateReferenceType(CompilerType(this, type));
+}
+
+ConstString
+JavaASTContext::DeclContextGetScopeQualifiedName(lldb::opaque_compiler_type_t opaque_decl_ctx)
+{
+ return GetTypeName(opaque_decl_ctx);
+}
+
+static void
+AddPrimitiveType(JavaASTContext::JavaTypeMap &type_map, JavaPrimitiveType::TypeKind type_kind)
+{
+ JavaPrimitiveType *type = new JavaPrimitiveType(type_kind);
+ type_map.emplace(type->GetName(), std::unique_ptr<JavaASTContext::JavaType>(type));
+}
+
+CompilerType
+JavaASTContext::CreateBaseType(const ConstString &name)
+{
+ if (m_base_type_map.empty())
+ {
+ AddPrimitiveType(m_base_type_map, JavaPrimitiveType::eTypeByte);
+ AddPrimitiveType(m_base_type_map, JavaPrimitiveType::eTypeShort);
+ AddPrimitiveType(m_base_type_map, JavaPrimitiveType::eTypeInt);
+ AddPrimitiveType(m_base_type_map, JavaPrimitiveType::eTypeLong);
+ AddPrimitiveType(m_base_type_map, JavaPrimitiveType::eTypeFloat);
+ AddPrimitiveType(m_base_type_map, JavaPrimitiveType::eTypeDouble);
+ AddPrimitiveType(m_base_type_map, JavaPrimitiveType::eTypeBoolean);
+ AddPrimitiveType(m_base_type_map, JavaPrimitiveType::eTypeChar);
+ }
+ auto it = m_base_type_map.find(name);
+ if (it != m_base_type_map.end())
+ return CompilerType(this, it->second.get());
+ return CompilerType();
+}
+
+CompilerType
+JavaASTContext::CreateObjectType(const ConstString &name, const ConstString &linkage_name, uint32_t byte_size)
+{
+ auto it = m_object_type_map.find(name);
+ if (it == m_object_type_map.end())
+ {
+ std::unique_ptr<JavaType> object_type(new JavaObjectType(name, linkage_name, byte_size));
+ it = m_object_type_map.emplace(name, std::move(object_type)).first;
+ }
+ return CompilerType(this, it->second.get());
+}
+
+CompilerType
+JavaASTContext::CreateArrayType(const ConstString &linkage_name, const CompilerType &element_type,
+ const DWARFExpression &length_expression, const lldb::addr_t data_offset)
+{
+ ConstString name = element_type.GetTypeName();
+ auto it = m_array_type_map.find(name);
+ if (it == m_array_type_map.end())
+ {
+ std::unique_ptr<JavaType> array_type(new JavaArrayType(linkage_name, element_type, length_expression,
+ data_offset));
+ it = m_array_type_map.emplace(name, std::move(array_type)).first;
+ }
+ return CompilerType(this, it->second.get());
+}
+
+CompilerType
+JavaASTContext::CreateReferenceType(const CompilerType &pointee_type)
+{
+ ConstString name = pointee_type.GetTypeName();
+ auto it = m_reference_type_map.find(name);
+ if (it == m_reference_type_map.end())
+ it = m_reference_type_map.emplace(name, std::unique_ptr<JavaType>(new JavaReferenceType(pointee_type))).first;
+ return CompilerType(this, it->second.get());
+}
+
+void
+JavaASTContext::CompleteObjectType(const CompilerType &object_type)
+{
+ JavaObjectType *obj = llvm::dyn_cast<JavaObjectType>(static_cast<JavaType *>(object_type.GetOpaqueQualType()));
+ assert(obj && "JavaASTContext::CompleteObjectType called with not a JavaObjectType");
+ obj->SetCompleteType(true);
+}
+
+void
+JavaASTContext::AddBaseClassToObject(const CompilerType &object_type, const CompilerType &member_type,
+ uint32_t member_offset)
+{
+ JavaObjectType *obj = llvm::dyn_cast<JavaObjectType>(static_cast<JavaType *>(object_type.GetOpaqueQualType()));
+ assert(obj && "JavaASTContext::AddMemberToObject called with not a JavaObjectType");
+ obj->AddBaseClass(member_type, member_offset);
+}
+
+void
+JavaASTContext::AddMemberToObject(const CompilerType &object_type, const ConstString &name,
+ const CompilerType &member_type, uint32_t member_offset)
+{
+ JavaObjectType *obj = llvm::dyn_cast<JavaObjectType>(static_cast<JavaType *>(object_type.GetOpaqueQualType()));
+ assert(obj && "JavaASTContext::AddMemberToObject called with not a JavaObjectType");
+ obj->AddField(name, member_type, member_offset);
+}
+
+void
+JavaASTContext::SetDynamicTypeId(const CompilerType &type, const DWARFExpression &type_id)
+{
+ JavaObjectType *obj = llvm::dyn_cast<JavaObjectType>(static_cast<JavaType *>(type.GetOpaqueQualType()));
+ assert(obj && "JavaASTContext::SetDynamicTypeId called with not a JavaObjectType");
+ obj->SetDynamicTypeId(type_id);
+}
+
+uint64_t
+JavaASTContext::CalculateDynamicTypeId(ExecutionContext *exe_ctx, const CompilerType &type, ValueObject &in_value)
+{
+ if (JavaObjectType *obj = llvm::dyn_cast<JavaObjectType>(static_cast<JavaType *>(type.GetOpaqueQualType())))
+ return obj->CalculateDynamicTypeId(exe_ctx, in_value);
+ if (JavaArrayType *arr = llvm::dyn_cast<JavaArrayType>(static_cast<JavaType *>(type.GetOpaqueQualType())))
+ return arr->CalculateDynamicTypeId(exe_ctx, in_value);
+ return UINT64_MAX;
+}
+
+uint32_t
+JavaASTContext::CalculateArraySize(const CompilerType &type, ValueObject &in_value)
+{
+ if (JavaArrayType *arr = llvm::dyn_cast<JavaArrayType>(static_cast<JavaType *>(type.GetOpaqueQualType())))
+ return arr->GetNumElements(&in_value);
+ return UINT32_MAX;
+}
+
+uint64_t
+JavaASTContext::CalculateArrayElementOffset(const CompilerType &type, size_t index)
+{
+ if (JavaArrayType *arr = llvm::dyn_cast<JavaArrayType>(static_cast<JavaType *>(type.GetOpaqueQualType())))
+ return arr->GetElementOffset(index);
+ return UINT64_MAX;
+}
+
+ConstString
+JavaASTContext::GetLinkageName(const CompilerType &type)
+{
+ if (JavaObjectType *obj = llvm::dyn_cast<JavaObjectType>(static_cast<JavaType *>(type.GetOpaqueQualType())))
+ return obj->GetLinkageName();
+ return ConstString();
+}
diff --git a/source/Symbol/LineEntry.cpp b/source/Symbol/LineEntry.cpp
index 815101368bd1..9b3a043f6cae 100644
--- a/source/Symbol/LineEntry.cpp
+++ b/source/Symbol/LineEntry.cpp
@@ -43,6 +43,7 @@ LineEntry::LineEntry
) :
range(section_sp, section_offset, byte_size),
file(_file),
+ original_file(_file),
line(_line),
column(_column),
is_start_of_statement(_is_start_of_statement),
@@ -58,6 +59,7 @@ LineEntry::Clear()
{
range.Clear();
file.Clear();
+ original_file.Clear();
line = LLDB_INVALID_LINE_NUMBER;
column = 0;
is_start_of_statement = 0;
@@ -260,7 +262,7 @@ LineEntry::GetSameLineContiguousAddressRange () const
if (next_line_sc.line_entry.IsValid()
&& next_line_sc.line_entry.range.GetByteSize() > 0
- && file == next_line_sc.line_entry.file)
+ && original_file == next_line_sc.line_entry.original_file)
{
// Include any line 0 entries - they indicate that this is compiler-generated code
// that does not correspond to user source code.
@@ -283,3 +285,15 @@ LineEntry::GetSameLineContiguousAddressRange () const
}
return complete_line_range;
}
+
+void
+LineEntry::ApplyFileMappings(lldb::TargetSP target_sp)
+{
+ if (target_sp)
+ {
+ // Apply any file remappings to our file
+ FileSpec new_file_spec;
+ if (target_sp->GetSourcePathMap().FindFile(original_file, new_file_spec))
+ file = new_file_spec;
+ }
+}
diff --git a/source/Symbol/LineTable.cpp b/source/Symbol/LineTable.cpp
index f9a42a7d14af..965dd689981b 100644
--- a/source/Symbol/LineTable.cpp
+++ b/source/Symbol/LineTable.cpp
@@ -299,6 +299,7 @@ LineTable::ConvertEntryAtIndexToLineEntry (uint32_t idx, LineEntry &line_entry)
line_entry.range.SetByteSize(0);
line_entry.file = m_comp_unit->GetSupportFiles().GetFileSpecAtIndex (entry.file_idx);
+ line_entry.original_file = m_comp_unit->GetSupportFiles().GetFileSpecAtIndex(entry.file_idx);
line_entry.line = entry.line;
line_entry.column = entry.column;
line_entry.is_start_of_statement = entry.is_start_of_statement;
@@ -462,9 +463,9 @@ LineTable::Dump (Stream *s, Target *target, Address::DumpStyle style, Address::D
for (size_t idx = 0; idx < count; ++idx)
{
ConvertEntryAtIndexToLineEntry (idx, line_entry);
- line_entry.Dump (s, target, prev_file != line_entry.file, style, fallback_style, show_line_ranges);
+ line_entry.Dump (s, target, prev_file != line_entry.original_file, style, fallback_style, show_line_ranges);
s->EOL();
- prev_file = line_entry.file;
+ prev_file = line_entry.original_file;
}
}
diff --git a/source/Symbol/Makefile b/source/Symbol/Makefile
deleted file mode 100644
index ae0cef0e242a..000000000000
--- a/source/Symbol/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- source/Symbol/Makefile ------------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../..
-LIBRARYNAME := lldbSymbol
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Symbol/ObjectFile.cpp b/source/Symbol/ObjectFile.cpp
index 99f9236a2cd9..62cde26c702f 100644
--- a/source/Symbol/ObjectFile.cpp
+++ b/source/Symbol/ObjectFile.cpp
@@ -241,8 +241,7 @@ ObjectFile::ObjectFile (const lldb::ModuleSP &module_sp,
lldb::offset_t file_offset,
lldb::offset_t length,
const lldb::DataBufferSP& data_sp,
- lldb::offset_t data_offset
-) :
+ lldb::offset_t data_offset) :
ModuleChild (module_sp),
m_file (), // This file could be different from the original module's file
m_type (eTypeInvalid),
@@ -254,7 +253,8 @@ ObjectFile::ObjectFile (const lldb::ModuleSP &module_sp,
m_process_wp(),
m_memory_addr (LLDB_INVALID_ADDRESS),
m_sections_ap(),
- m_symtab_ap ()
+ m_symtab_ap (),
+ m_synthetic_symbol_idx (0)
{
if (file_spec_ptr)
m_file = *file_spec_ptr;
@@ -286,7 +286,8 @@ ObjectFile::ObjectFile (const lldb::ModuleSP &module_sp,
m_process_wp (process_sp),
m_memory_addr (header_addr),
m_sections_ap(),
- m_symtab_ap ()
+ m_symtab_ap (),
+ m_synthetic_symbol_idx (0)
{
if (header_data_sp)
m_data.SetData (header_data_sp, 0, header_data_sp->GetByteSize());
@@ -384,6 +385,11 @@ ObjectFile::GetAddressClass (addr_t file_addr)
case eSectionTypeELFDynamicLinkInfo:
case eSectionTypeOther:
return eAddressClassUnknown;
+ case eSectionTypeAbsoluteAddress:
+ // In case of absolute sections decide the address class based on the symbol
+ // type because the section type isn't specify if it is a code or a data
+ // section.
+ break;
}
}
}
@@ -545,8 +551,6 @@ ObjectFile::ReadSectionData (const Section *section, DataExtractor& section_data
// The object file now contains a full mmap'ed copy of the object file data, so just use this
return MemoryMapSectionData (section, section_data);
}
- section_data.Clear();
- return 0;
}
size_t
@@ -596,7 +600,7 @@ ObjectFile::ClearSymtab ()
ModuleSP module_sp(GetModule());
if (module_sp)
{
- lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
if (log)
log->Printf ("%p ObjectFile::ClearSymtab () symtab = %p",
@@ -616,7 +620,7 @@ ObjectFile::GetSectionList(bool update_module_section_list)
ModuleSP module_sp(GetModule());
if (module_sp)
{
- lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
CreateSections(*module_sp->GetUnifiedSectionList());
}
}
@@ -653,3 +657,13 @@ ObjectFile::GetSymbolTypeFromName (llvm::StringRef name,
}
return symbol_type_hint;
}
+
+ConstString
+ObjectFile::GetNextSyntheticSymbolName()
+{
+ StreamString ss;
+ ConstString file_name = GetModule()->GetFileSpec().GetFilename();
+ ss.Printf("___lldb_unnamed_symbol%u$$%s", ++m_synthetic_symbol_idx, file_name.GetCString());
+ return ConstString(ss.GetData());
+}
+
diff --git a/source/Symbol/Symbol.cpp b/source/Symbol/Symbol.cpp
index 5884fcaa551d..1fa792c9729d 100644
--- a/source/Symbol/Symbol.cpp
+++ b/source/Symbol/Symbol.cpp
@@ -737,3 +737,10 @@ Symbol::GetDisassembly (const ExecutionContext &exe_ctx,
}
return false;
}
+
+bool
+Symbol::ContainsFileAddress (lldb::addr_t file_addr) const
+{
+ return m_addr_range.ContainsFileAddress(file_addr);
+}
+
diff --git a/source/Symbol/SymbolContext.cpp b/source/Symbol/SymbolContext.cpp
index 54db5e090b80..1e55ce652e0d 100644
--- a/source/Symbol/SymbolContext.cpp
+++ b/source/Symbol/SymbolContext.cpp
@@ -365,6 +365,10 @@ SymbolContext::GetDescription(Stream *s, lldb::DescriptionLevel level, Target *t
s->PutCString("kind = local, ");
break;
+ case eValueTypeVariableThreadLocal:
+ s->PutCString("kind = thread local, ");
+ break;
+
default:
break;
}
@@ -595,6 +599,7 @@ SymbolContext::GetParentOfInlinedScope (const Address &curr_frame_pc,
next_frame_pc = range.GetBaseAddress();
next_frame_sc.line_entry.range.GetBaseAddress() = next_frame_pc;
next_frame_sc.line_entry.file = curr_inlined_block_inlined_info->GetCallSite().GetFile();
+ next_frame_sc.line_entry.original_file = curr_inlined_block_inlined_info->GetCallSite().GetFile();
next_frame_sc.line_entry.line = curr_inlined_block_inlined_info->GetCallSite().GetLine();
next_frame_sc.line_entry.column = curr_inlined_block_inlined_info->GetCallSite().GetColumn();
return true;
@@ -857,6 +862,73 @@ SymbolContext::GetFunctionStartLineEntry () const
return LineEntry();
}
+bool
+SymbolContext::GetAddressRangeFromHereToEndLine(uint32_t end_line, AddressRange &range, Error &error)
+{
+ if (!line_entry.IsValid())
+ {
+ error.SetErrorString("Symbol context has no line table.");
+ return false;
+ }
+
+ range = line_entry.range;
+ if (line_entry.line > end_line)
+ {
+ error.SetErrorStringWithFormat("end line option %d must be after the current line: %d",
+ end_line,
+ line_entry.line);
+ return false;
+ }
+
+ uint32_t line_index = 0;
+ bool found = false;
+ while (1)
+ {
+ LineEntry this_line;
+ line_index = comp_unit->FindLineEntry(line_index, line_entry.line, nullptr, false, &this_line);
+ if (line_index == UINT32_MAX)
+ break;
+ if (LineEntry::Compare(this_line, line_entry) == 0)
+ {
+ found = true;
+ break;
+ }
+ }
+
+ LineEntry end_entry;
+ if (!found)
+ {
+ // Can't find the index of the SymbolContext's line entry in the SymbolContext's CompUnit.
+ error.SetErrorString("Can't find the current line entry in the CompUnit - can't process "
+ "the end-line option");
+ return false;
+ }
+
+ line_index = comp_unit->FindLineEntry(line_index, end_line, nullptr, false, &end_entry);
+ if (line_index == UINT32_MAX)
+ {
+ error.SetErrorStringWithFormat("could not find a line table entry corresponding "
+ "to end line number %d",
+ end_line);
+ return false;
+ }
+
+ Block *func_block = GetFunctionBlock();
+ if (func_block && func_block->GetRangeIndexContainingAddress(end_entry.range.GetBaseAddress()) == UINT32_MAX)
+ {
+ error.SetErrorStringWithFormat("end line number %d is not contained within the current function.",
+ end_line);
+ return false;
+ }
+
+ lldb::addr_t range_size = end_entry.range.GetBaseAddress().GetFileAddress()
+ - range.GetBaseAddress().GetFileAddress();
+ range.SetByteSize(range_size);
+ return true;
+}
+
+
+
//----------------------------------------------------------------------
//
// SymbolContextSpecifier
diff --git a/source/Symbol/SymbolFile.cpp b/source/Symbol/SymbolFile.cpp
index 82bbceb9610a..808dfd3d06d6 100644
--- a/source/Symbol/SymbolFile.cpp
+++ b/source/Symbol/SymbolFile.cpp
@@ -141,7 +141,7 @@ SymbolFile::GetMangledNamesForFunction(const std::string &scope_qualified_name,
}
uint32_t
-SymbolFile::FindTypes (const SymbolContext& sc, const ConstString &name, const CompilerDeclContext *parent_decl_ctx, bool append, uint32_t max_matches, TypeMap& types)
+SymbolFile::FindTypes (const SymbolContext& sc, const ConstString &name, const CompilerDeclContext *parent_decl_ctx, bool append, uint32_t max_matches, llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files, TypeMap& types)
{
if (!append)
types.Clear();
diff --git a/source/Symbol/SymbolVendor.cpp b/source/Symbol/SymbolVendor.cpp
index b9ec9a1c8a79..c569943b3463 100644
--- a/source/Symbol/SymbolVendor.cpp
+++ b/source/Symbol/SymbolVendor.cpp
@@ -85,7 +85,7 @@ SymbolVendor::AddSymbolFileRepresentation(const ObjectFileSP &objfile_sp)
ModuleSP module_sp(GetModule());
if (module_sp)
{
- lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
if (objfile_sp)
{
m_objfile_sp = objfile_sp;
@@ -100,7 +100,7 @@ SymbolVendor::SetCompileUnitAtIndex (size_t idx, const CompUnitSP &cu_sp)
ModuleSP module_sp(GetModule());
if (module_sp)
{
- lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
const size_t num_compile_units = GetNumCompileUnits();
if (idx < num_compile_units)
{
@@ -129,7 +129,7 @@ SymbolVendor::GetNumCompileUnits()
ModuleSP module_sp(GetModule());
if (module_sp)
{
- lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
if (m_compile_units.empty())
{
if (m_sym_file_ap.get())
@@ -151,7 +151,7 @@ SymbolVendor::ParseCompileUnitLanguage (const SymbolContext& sc)
ModuleSP module_sp(GetModule());
if (module_sp)
{
- lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
if (m_sym_file_ap.get())
return m_sym_file_ap->ParseCompileUnitLanguage(sc);
}
@@ -165,7 +165,7 @@ SymbolVendor::ParseCompileUnitFunctions (const SymbolContext &sc)
ModuleSP module_sp(GetModule());
if (module_sp)
{
- lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
if (m_sym_file_ap.get())
return m_sym_file_ap->ParseCompileUnitFunctions(sc);
}
@@ -178,7 +178,7 @@ SymbolVendor::ParseCompileUnitLineTable (const SymbolContext &sc)
ModuleSP module_sp(GetModule());
if (module_sp)
{
- lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
if (m_sym_file_ap.get())
return m_sym_file_ap->ParseCompileUnitLineTable(sc);
}
@@ -191,7 +191,7 @@ SymbolVendor::ParseCompileUnitDebugMacros (const SymbolContext &sc)
ModuleSP module_sp(GetModule());
if (module_sp)
{
- lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
if (m_sym_file_ap.get())
return m_sym_file_ap->ParseCompileUnitDebugMacros(sc);
}
@@ -203,7 +203,7 @@ SymbolVendor::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecLis
ModuleSP module_sp(GetModule());
if (module_sp)
{
- lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
if (m_sym_file_ap.get())
return m_sym_file_ap->ParseCompileUnitSupportFiles(sc, support_files);
}
@@ -211,13 +211,25 @@ SymbolVendor::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecLis
}
bool
-SymbolVendor::ParseImportedModules (const SymbolContext &sc,
- std::vector<ConstString> &imported_modules)
+SymbolVendor::ParseCompileUnitIsOptimized(const SymbolContext &sc)
{
ModuleSP module_sp(GetModule());
if (module_sp)
{
- lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
+ if (m_sym_file_ap.get())
+ return m_sym_file_ap->ParseCompileUnitIsOptimized(sc);
+ }
+ return false;
+}
+
+bool
+SymbolVendor::ParseImportedModules(const SymbolContext &sc, std::vector<ConstString> &imported_modules)
+{
+ ModuleSP module_sp(GetModule());
+ if (module_sp)
+ {
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
if (m_sym_file_ap.get())
return m_sym_file_ap->ParseImportedModules(sc, imported_modules);
}
@@ -231,7 +243,7 @@ SymbolVendor::ParseFunctionBlocks (const SymbolContext &sc)
ModuleSP module_sp(GetModule());
if (module_sp)
{
- lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
if (m_sym_file_ap.get())
return m_sym_file_ap->ParseFunctionBlocks(sc);
}
@@ -244,7 +256,7 @@ SymbolVendor::ParseTypes (const SymbolContext &sc)
ModuleSP module_sp(GetModule());
if (module_sp)
{
- lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
if (m_sym_file_ap.get())
return m_sym_file_ap->ParseTypes(sc);
}
@@ -257,7 +269,7 @@ SymbolVendor::ParseVariablesForContext (const SymbolContext& sc)
ModuleSP module_sp(GetModule());
if (module_sp)
{
- lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
if (m_sym_file_ap.get())
return m_sym_file_ap->ParseVariablesForContext(sc);
}
@@ -270,7 +282,7 @@ SymbolVendor::ResolveTypeUID(lldb::user_id_t type_uid)
ModuleSP module_sp(GetModule());
if (module_sp)
{
- lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
if (m_sym_file_ap.get())
return m_sym_file_ap->ResolveTypeUID(type_uid);
}
@@ -284,7 +296,7 @@ SymbolVendor::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_sco
ModuleSP module_sp(GetModule());
if (module_sp)
{
- lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
if (m_sym_file_ap.get())
return m_sym_file_ap->ResolveSymbolContext(so_addr, resolve_scope, sc);
}
@@ -297,7 +309,7 @@ SymbolVendor::ResolveSymbolContext (const FileSpec& file_spec, uint32_t line, bo
ModuleSP module_sp(GetModule());
if (module_sp)
{
- lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
if (m_sym_file_ap.get())
return m_sym_file_ap->ResolveSymbolContext(file_spec, line, check_inlines, resolve_scope, sc_list);
}
@@ -310,7 +322,7 @@ SymbolVendor::FindGlobalVariables (const ConstString &name, const CompilerDeclCo
ModuleSP module_sp(GetModule());
if (module_sp)
{
- lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
if (m_sym_file_ap.get())
return m_sym_file_ap->FindGlobalVariables(name, parent_decl_ctx, append, max_matches, variables);
}
@@ -323,7 +335,7 @@ SymbolVendor::FindGlobalVariables (const RegularExpression& regex, bool append,
ModuleSP module_sp(GetModule());
if (module_sp)
{
- lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
if (m_sym_file_ap.get())
return m_sym_file_ap->FindGlobalVariables(regex, append, max_matches, variables);
}
@@ -336,7 +348,7 @@ SymbolVendor::FindFunctions(const ConstString &name, const CompilerDeclContext *
ModuleSP module_sp(GetModule());
if (module_sp)
{
- lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
if (m_sym_file_ap.get())
return m_sym_file_ap->FindFunctions(name, parent_decl_ctx, name_type_mask, include_inlines, append, sc_list);
}
@@ -349,7 +361,7 @@ SymbolVendor::FindFunctions(const RegularExpression& regex, bool include_inlines
ModuleSP module_sp(GetModule());
if (module_sp)
{
- lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
if (m_sym_file_ap.get())
return m_sym_file_ap->FindFunctions(regex, include_inlines, append, sc_list);
}
@@ -358,14 +370,14 @@ SymbolVendor::FindFunctions(const RegularExpression& regex, bool include_inlines
size_t
-SymbolVendor::FindTypes (const SymbolContext& sc, const ConstString &name, const CompilerDeclContext *parent_decl_ctx, bool append, size_t max_matches, TypeMap& types)
+SymbolVendor::FindTypes (const SymbolContext& sc, const ConstString &name, const CompilerDeclContext *parent_decl_ctx, bool append, size_t max_matches, llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files, TypeMap& types)
{
ModuleSP module_sp(GetModule());
if (module_sp)
{
- lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
if (m_sym_file_ap.get())
- return m_sym_file_ap->FindTypes(sc, name, parent_decl_ctx, append, max_matches, types);
+ return m_sym_file_ap->FindTypes(sc, name, parent_decl_ctx, append, max_matches, searched_symbol_files, types);
}
if (!append)
types.Clear();
@@ -378,7 +390,7 @@ SymbolVendor::FindTypes (const std::vector<CompilerContext> &context, bool appen
ModuleSP module_sp(GetModule());
if (module_sp)
{
- lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
if (m_sym_file_ap.get())
return m_sym_file_ap->FindTypes(context, append, types);
}
@@ -395,7 +407,7 @@ SymbolVendor::GetTypes (SymbolContextScope *sc_scope,
ModuleSP module_sp(GetModule());
if (module_sp)
{
- lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
if (m_sym_file_ap.get())
return m_sym_file_ap->GetTypes (sc_scope, type_mask, type_list);
}
@@ -409,7 +421,7 @@ SymbolVendor::FindNamespace(const SymbolContext& sc, const ConstString &name, co
ModuleSP module_sp(GetModule());
if (module_sp)
{
- lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
if (m_sym_file_ap.get())
namespace_decl_ctx = m_sym_file_ap->FindNamespace (sc, name, parent_decl_ctx);
}
@@ -422,7 +434,7 @@ SymbolVendor::Dump(Stream *s)
ModuleSP module_sp(GetModule());
if (module_sp)
{
- lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
bool show_context = false;
@@ -467,7 +479,7 @@ SymbolVendor::GetCompileUnitAtIndex(size_t idx)
ModuleSP module_sp(GetModule());
if (module_sp)
{
- lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
const size_t num_compile_units = GetNumCompileUnits();
if (idx < num_compile_units)
{
diff --git a/source/Symbol/Symtab.cpp b/source/Symbol/Symtab.cpp
index 709d899075a4..b11b731014d8 100644
--- a/source/Symbol/Symtab.cpp
+++ b/source/Symbol/Symtab.cpp
@@ -25,16 +25,14 @@
using namespace lldb;
using namespace lldb_private;
-
-
-Symtab::Symtab(ObjectFile *objfile) :
- m_objfile (objfile),
- m_symbols (),
- m_file_addr_to_index (),
- m_name_to_index (),
- m_mutex (Mutex::eMutexTypeRecursive),
- m_file_addr_to_index_computed (false),
- m_name_indexes_computed (false)
+Symtab::Symtab(ObjectFile *objfile)
+ : m_objfile(objfile),
+ m_symbols(),
+ m_file_addr_to_index(),
+ m_name_to_index(),
+ m_mutex(),
+ m_file_addr_to_index_computed(false),
+ m_name_indexes_computed(false)
{
}
@@ -56,7 +54,7 @@ Symtab::Resize(size_t count)
// Clients should grab the mutex from this symbol table and lock it manually
// when calling this function to avoid performance issues.
m_symbols.resize (count);
- return &m_symbols[0];
+ return m_symbols.empty() ? nullptr : &m_symbols[0];
}
uint32_t
@@ -76,7 +74,7 @@ Symtab::AddSymbol(const Symbol& symbol)
size_t
Symtab::GetNumSymbols() const
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
return m_symbols.size();
}
@@ -90,9 +88,9 @@ Symtab::SectionFileAddressesChanged ()
void
Symtab::Dump (Stream *s, Target *target, SortOrder sort_order)
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
-// s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);
+ // s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);
s->Indent();
const FileSpec &file_spec = m_objfile->GetFileSpec();
const char * object_name = nullptr;
@@ -171,7 +169,7 @@ Symtab::Dump (Stream *s, Target *target, SortOrder sort_order)
void
Symtab::Dump(Stream *s, Target *target, std::vector<uint32_t>& indexes) const
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
const size_t num_symbols = GetNumSymbols();
//s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);
@@ -224,7 +222,7 @@ CompareSymbolID (const void *key, const void *p)
Symbol *
Symtab::FindSymbolByID (lldb::user_id_t symbol_uid) const
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
Symbol *symbol = (Symbol*)::bsearch (&symbol_uid,
&m_symbols[0],
@@ -474,7 +472,7 @@ Symtab::AppendSymbolNamesToMap (const IndexCollection &indexes,
if (add_demangled || add_mangled)
{
Timer scoped_timer (__PRETTY_FUNCTION__, "%s", __PRETTY_FUNCTION__);
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
// Create the name index vector to be able to quickly search by name
NameToIndexMap::Entry entry;
@@ -506,7 +504,7 @@ Symtab::AppendSymbolNamesToMap (const IndexCollection &indexes,
uint32_t
Symtab::AppendSymbolIndexesWithType (SymbolType symbol_type, std::vector<uint32_t>& indexes, uint32_t start_idx, uint32_t end_index) const
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
uint32_t prev_size = indexes.size();
@@ -524,7 +522,7 @@ Symtab::AppendSymbolIndexesWithType (SymbolType symbol_type, std::vector<uint32_
uint32_t
Symtab::AppendSymbolIndexesWithTypeAndFlagsValue (SymbolType symbol_type, uint32_t flags_value, std::vector<uint32_t>& indexes, uint32_t start_idx, uint32_t end_index) const
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
uint32_t prev_size = indexes.size();
@@ -542,7 +540,7 @@ Symtab::AppendSymbolIndexesWithTypeAndFlagsValue (SymbolType symbol_type, uint32
uint32_t
Symtab::AppendSymbolIndexesWithType (SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t>& indexes, uint32_t start_idx, uint32_t end_index) const
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
uint32_t prev_size = indexes.size();
@@ -632,7 +630,7 @@ namespace {
void
Symtab::SortSymbolIndexesByValue (std::vector<uint32_t>& indexes, bool remove_duplicates) const
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
Timer scoped_timer (__PRETTY_FUNCTION__,__PRETTY_FUNCTION__);
// No need to sort if we have zero or one items...
@@ -657,7 +655,7 @@ Symtab::SortSymbolIndexesByValue (std::vector<uint32_t>& indexes, bool remove_du
uint32_t
Symtab::AppendSymbolIndexesWithName (const ConstString& symbol_name, std::vector<uint32_t>& indexes)
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
Timer scoped_timer (__PRETTY_FUNCTION__, "%s", __PRETTY_FUNCTION__);
if (symbol_name)
@@ -674,7 +672,7 @@ Symtab::AppendSymbolIndexesWithName (const ConstString& symbol_name, std::vector
uint32_t
Symtab::AppendSymbolIndexesWithName (const ConstString& symbol_name, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t>& indexes)
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
Timer scoped_timer (__PRETTY_FUNCTION__, "%s", __PRETTY_FUNCTION__);
if (symbol_name)
@@ -700,7 +698,7 @@ Symtab::AppendSymbolIndexesWithName (const ConstString& symbol_name, Debug symbo
uint32_t
Symtab::AppendSymbolIndexesWithNameAndType (const ConstString& symbol_name, SymbolType symbol_type, std::vector<uint32_t>& indexes)
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
if (AppendSymbolIndexesWithName(symbol_name, indexes) > 0)
{
@@ -719,7 +717,7 @@ Symtab::AppendSymbolIndexesWithNameAndType (const ConstString& symbol_name, Symb
uint32_t
Symtab::AppendSymbolIndexesWithNameAndType (const ConstString& symbol_name, SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t>& indexes)
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
if (AppendSymbolIndexesWithName(symbol_name, symbol_debug_type, symbol_visibility, indexes) > 0)
{
@@ -739,7 +737,7 @@ Symtab::AppendSymbolIndexesWithNameAndType (const ConstString& symbol_name, Symb
uint32_t
Symtab::AppendSymbolIndexesMatchingRegExAndType (const RegularExpression &regexp, SymbolType symbol_type, std::vector<uint32_t>& indexes)
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
uint32_t prev_size = indexes.size();
uint32_t sym_end = m_symbols.size();
@@ -763,7 +761,7 @@ Symtab::AppendSymbolIndexesMatchingRegExAndType (const RegularExpression &regexp
uint32_t
Symtab::AppendSymbolIndexesMatchingRegExAndType (const RegularExpression &regexp, SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t>& indexes)
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
uint32_t prev_size = indexes.size();
uint32_t sym_end = m_symbols.size();
@@ -790,7 +788,7 @@ Symtab::AppendSymbolIndexesMatchingRegExAndType (const RegularExpression &regexp
Symbol *
Symtab::FindSymbolWithType (SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, uint32_t& start_idx)
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
const size_t count = m_symbols.size();
for (size_t idx = start_idx; idx < count; ++idx)
@@ -810,7 +808,7 @@ Symtab::FindSymbolWithType (SymbolType symbol_type, Debug symbol_debug_type, Vis
size_t
Symtab::FindAllSymbolsWithNameAndType (const ConstString &name, SymbolType symbol_type, std::vector<uint32_t>& symbol_indexes)
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
Timer scoped_timer (__PRETTY_FUNCTION__, "%s", __PRETTY_FUNCTION__);
// Initialize all of the lookup by name indexes before converting NAME
@@ -830,7 +828,7 @@ Symtab::FindAllSymbolsWithNameAndType (const ConstString &name, SymbolType symbo
size_t
Symtab::FindAllSymbolsWithNameAndType (const ConstString &name, SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t>& symbol_indexes)
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
Timer scoped_timer (__PRETTY_FUNCTION__, "%s", __PRETTY_FUNCTION__);
// Initialize all of the lookup by name indexes before converting NAME
@@ -850,7 +848,7 @@ Symtab::FindAllSymbolsWithNameAndType (const ConstString &name, SymbolType symbo
size_t
Symtab::FindAllSymbolsMatchingRexExAndType (const RegularExpression &regex, SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t>& symbol_indexes)
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
AppendSymbolIndexesMatchingRegExAndType(regex, symbol_type, symbol_debug_type, symbol_visibility, symbol_indexes);
return symbol_indexes.size();
@@ -859,7 +857,7 @@ Symtab::FindAllSymbolsMatchingRexExAndType (const RegularExpression &regex, Symb
Symbol *
Symtab::FindFirstSymbolWithNameAndType (const ConstString &name, SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility)
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
Timer scoped_timer (__PRETTY_FUNCTION__, "%s", __PRETTY_FUNCTION__);
if (!m_name_indexes_computed)
@@ -894,33 +892,39 @@ typedef struct
addr_t match_offset;
} SymbolSearchInfo;
-static int
-SymbolWithClosestFileAddress (SymbolSearchInfo *info, const uint32_t *index_ptr)
+// Add all the section file start address & size to the RangeVector,
+// recusively adding any children sections.
+static void
+AddSectionsToRangeMap (SectionList *sectlist, RangeVector<addr_t, addr_t> &section_ranges)
{
- const Symbol *symbol = info->symtab->SymbolAtIndex (index_ptr[0]);
- if (symbol == nullptr)
- return -1;
-
- const addr_t info_file_addr = info->file_addr;
- if (symbol->ValueIsAddress())
+ const int num_sections = sectlist->GetNumSections (0);
+ for (int i = 0; i < num_sections; i++)
{
- const addr_t curr_file_addr = symbol->GetAddressRef().GetFileAddress();
- if (info_file_addr < curr_file_addr)
- return -1;
-
- // Since we are finding the closest symbol that is greater than or equal
- // to 'info->file_addr' we set the symbol here. This will get set
- // multiple times, but after the search is done it will contain the best
- // symbol match
- info->match_symbol = const_cast<Symbol *>(symbol);
- info->match_index_ptr = index_ptr;
- info->match_offset = info_file_addr - curr_file_addr;
-
- if (info_file_addr > curr_file_addr)
- return +1;
- return 0;
+ SectionSP sect_sp = sectlist->GetSectionAtIndex (i);
+ if (sect_sp)
+ {
+ SectionList &child_sectlist = sect_sp->GetChildren();
+
+ // If this section has children, add the children to the RangeVector.
+ // Else add this section to the RangeVector.
+ if (child_sectlist.GetNumSections (0) > 0)
+ {
+ AddSectionsToRangeMap (&child_sectlist, section_ranges);
+ }
+ else
+ {
+ size_t size = sect_sp->GetByteSize();
+ if (size > 0)
+ {
+ addr_t base_addr = sect_sp->GetFileAddress();
+ RangeVector<addr_t, addr_t>::Entry entry;
+ entry.SetRangeBase (base_addr);
+ entry.SetByteSize (size);
+ section_ranges.Append (entry);
+ }
+ }
+ }
}
- return -1;
}
void
@@ -948,35 +952,69 @@ Symtab::InitAddressIndexes()
if (num_entries > 0)
{
m_file_addr_to_index.Sort();
- m_file_addr_to_index.CalculateSizesOfZeroByteSizeRanges();
-
- // Now our last symbols might not have had sizes because there
- // was no subsequent symbol to calculate the size from. If this is
- // the case, then calculate the size by capping it at the end of the
- // section in which the symbol resides
- for (int i = num_entries - 1; i >= 0; --i)
+
+ // Create a RangeVector with the start & size of all the sections for
+ // this objfile. We'll need to check this for any FileRangeToIndexMap
+ // entries with an uninitialized size, which could potentially be a
+ // large number so reconstituting the weak pointer is busywork when it
+ // is invariant information.
+ SectionList *sectlist = m_objfile->GetSectionList();
+ RangeVector<addr_t, addr_t> section_ranges;
+ if (sectlist)
+ {
+ AddSectionsToRangeMap (sectlist, section_ranges);
+ section_ranges.Sort();
+ }
+
+ // Iterate through the FileRangeToIndexMap and fill in the size for any
+ // entries that didn't already have a size from the Symbol (e.g. if we
+ // have a plain linker symbol with an address only, instead of debug info
+ // where we get an address and a size and a type, etc.)
+ for (size_t i = 0; i < num_entries; i++)
{
- const FileRangeToIndexMap::Entry &entry = m_file_addr_to_index.GetEntryRef(i);
- // As we iterate backwards, as soon as we find a symbol with a valid
- // byte size, we are done
- if (entry.GetByteSize() > 0)
- break;
-
- // Cap the size to the end of the section in which the symbol resides
- SectionSP section_sp (m_objfile->GetSectionList()->FindSectionContainingFileAddress (entry.GetRangeBase()));
- if (section_sp)
+ FileRangeToIndexMap::Entry *entry = m_file_addr_to_index.GetMutableEntryAtIndex (i);
+ if (entry->GetByteSize() == 0)
{
- const lldb::addr_t end_section_file_addr = section_sp->GetFileAddress() + section_sp->GetByteSize();
- const lldb::addr_t symbol_file_addr = entry.GetRangeBase();
- if (end_section_file_addr > symbol_file_addr)
+ addr_t curr_base_addr = entry->GetRangeBase();
+ const RangeVector<addr_t, addr_t>::Entry *containing_section =
+ section_ranges.FindEntryThatContains (curr_base_addr);
+
+ // Use the end of the section as the default max size of the symbol
+ addr_t sym_size = 0;
+ if (containing_section)
{
- Symbol &symbol = m_symbols[entry.data];
+ sym_size = containing_section->GetByteSize() -
+ (entry->GetRangeBase() - containing_section->GetRangeBase());
+ }
+
+ for (size_t j = i; j < num_entries; j++)
+ {
+ FileRangeToIndexMap::Entry *next_entry = m_file_addr_to_index.GetMutableEntryAtIndex (j);
+ addr_t next_base_addr = next_entry->GetRangeBase();
+ if (next_base_addr > curr_base_addr)
+ {
+ addr_t size_to_next_symbol = next_base_addr - curr_base_addr;
- symbol.SetByteSize(end_section_file_addr - symbol_file_addr);
- symbol.SetSizeIsSynthesized(true);
+ // Take the difference between this symbol and the next one as its size,
+ // if it is less than the size of the section.
+ if (sym_size == 0 || size_to_next_symbol < sym_size)
+ {
+ sym_size = size_to_next_symbol;
+ }
+ break;
+ }
+ }
+
+ if (sym_size > 0)
+ {
+ entry->SetByteSize (sym_size);
+ Symbol &symbol = m_symbols[entry->data];
+ symbol.SetByteSize (sym_size);
+ symbol.SetSizeIsSynthesized (true);
}
}
}
+
// Sort again in case the range size changes the ordering
m_file_addr_to_index.Sort();
}
@@ -986,7 +1024,7 @@ Symtab::InitAddressIndexes()
void
Symtab::CalculateSymbolSizes ()
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
if (!m_symbols.empty())
{
@@ -1018,40 +1056,18 @@ Symtab::CalculateSymbolSizes ()
}
Symbol *
-Symtab::FindSymbolContainingFileAddress (addr_t file_addr, const uint32_t* indexes, uint32_t num_indexes)
+Symtab::FindSymbolAtFileAddress (addr_t file_addr)
{
- Mutex::Locker locker (m_mutex);
-
-
- SymbolSearchInfo info = { this, file_addr, nullptr, nullptr, 0 };
-
- ::bsearch (&info,
- indexes,
- num_indexes,
- sizeof(uint32_t),
- (ComparisonFunction)SymbolWithClosestFileAddress);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ if (!m_file_addr_to_index_computed)
+ InitAddressIndexes();
- if (info.match_symbol)
+ const FileRangeToIndexMap::Entry *entry = m_file_addr_to_index.FindEntryStartsAt(file_addr);
+ if (entry)
{
- if (info.match_offset == 0)
- {
- // We found an exact match!
- return info.match_symbol;
- }
-
- const size_t symbol_byte_size = info.match_symbol->GetByteSize();
-
- if (symbol_byte_size == 0)
- {
- // We weren't able to find the size of the symbol so lets just go
- // with that match we found in our search...
- return info.match_symbol;
- }
-
- // We were able to figure out a symbol size so lets make sure our
- // offset puts "file_addr" in the symbol's address range.
- if (info.match_offset < symbol_byte_size)
- return info.match_symbol;
+ Symbol* symbol = SymbolAtIndex(entry->data);
+ if (symbol->GetFileAddress() == file_addr)
+ return symbol;
}
return nullptr;
}
@@ -1059,21 +1075,25 @@ Symtab::FindSymbolContainingFileAddress (addr_t file_addr, const uint32_t* index
Symbol *
Symtab::FindSymbolContainingFileAddress (addr_t file_addr)
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
if (!m_file_addr_to_index_computed)
InitAddressIndexes();
const FileRangeToIndexMap::Entry *entry = m_file_addr_to_index.FindEntryThatContains(file_addr);
if (entry)
- return SymbolAtIndex(entry->data);
+ {
+ Symbol* symbol = SymbolAtIndex(entry->data);
+ if (symbol->ContainsFileAddress(file_addr))
+ return symbol;
+ }
return nullptr;
}
void
Symtab::ForEachSymbolContainingFileAddress(addr_t file_addr, std::function<bool(Symbol *)> const &callback)
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
if (!m_file_addr_to_index_computed)
InitAddressIndexes();
@@ -1085,8 +1105,12 @@ Symtab::ForEachSymbolContainingFileAddress(addr_t file_addr, std::function<bool(
for (size_t i = 0; i < addr_match_count; ++i)
{
- if (!callback(SymbolAtIndex(all_addr_indexes[i])))
- break;
+ Symbol* symbol = SymbolAtIndex(all_addr_indexes[i]);
+ if (symbol->ContainsFileAddress(file_addr))
+ {
+ if (!callback(symbol))
+ break;
+ }
}
}
@@ -1133,7 +1157,7 @@ Symtab::FindFunctionSymbols (const ConstString &name,
unsigned temp_symbol_indexes_size = temp_symbol_indexes.size();
if (temp_symbol_indexes_size > 0)
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
for (unsigned i = 0; i < temp_symbol_indexes_size; i++)
{
SymbolContext sym_ctx;
diff --git a/source/Symbol/Type.cpp b/source/Symbol/Type.cpp
index 8061e016ca59..8b51d99ece38 100644
--- a/source/Symbol/Type.cpp
+++ b/source/Symbol/Type.cpp
@@ -559,8 +559,8 @@ Type::ResolveClangType (ResolveState compiler_type_resolve_state)
break;
case eEncodingIsTypedefUID:
- m_compiler_type = encoding_type->GetForwardCompilerType ().CreateTypedef(GetName().AsCString(),
- GetSymbolFile()->GetDeclContextContainingUID(GetID()));
+ m_compiler_type = encoding_type->GetForwardCompilerType ().CreateTypedef(m_name.AsCString("__lldb_invalid_typedef_name"),
+ GetSymbolFile()->GetDeclContextContainingUID(GetID()));
m_name.Clear();
break;
@@ -605,8 +605,8 @@ Type::ResolveClangType (ResolveState compiler_type_resolve_state)
break;
case eEncodingIsTypedefUID:
- m_compiler_type = void_compiler_type.CreateTypedef(GetName().AsCString(),
- GetSymbolFile()->GetDeclContextContainingUID(GetID()));
+ m_compiler_type = void_compiler_type.CreateTypedef(m_name.AsCString("__lldb_invalid_typedef_name"),
+ GetSymbolFile()->GetDeclContextContainingUID(GetID()));
break;
case eEncodingIsPointerUID:
diff --git a/source/Symbol/TypeSystem.cpp b/source/Symbol/TypeSystem.cpp
index 5c2ab5cceab6..2cd82f221f91 100644
--- a/source/Symbol/TypeSystem.cpp
+++ b/source/Symbol/TypeSystem.cpp
@@ -153,7 +153,9 @@ TypeSystem::DeclGetFunctionArgumentType (void *opaque_decl, size_t arg_idx)
std::vector<CompilerDecl>
-TypeSystem::DeclContextFindDeclByName (void *opaque_decl_ctx, ConstString name)
+TypeSystem::DeclContextFindDeclByName (void *opaque_decl_ctx,
+ ConstString name,
+ bool ignore_imported_decls)
{
return std::vector<CompilerDecl>();
}
@@ -161,9 +163,7 @@ TypeSystem::DeclContextFindDeclByName (void *opaque_decl_ctx, ConstString name)
#pragma mark TypeSystemMap
-TypeSystemMap::TypeSystemMap() :
- m_mutex (),
- m_map ()
+TypeSystemMap::TypeSystemMap() : m_mutex(), m_map(), m_clear_in_progress(false)
{
}
@@ -174,15 +174,35 @@ TypeSystemMap::~TypeSystemMap()
void
TypeSystemMap::Clear ()
{
- Mutex::Locker locker (m_mutex);
- m_map.clear();
+ collection map;
+ {
+ std::lock_guard<std::mutex> guard(m_mutex);
+ map = m_map;
+ m_clear_in_progress = true;
+ }
+ std::set<TypeSystem *> visited;
+ for (auto pair : map)
+ {
+ TypeSystem *type_system = pair.second.get();
+ if (type_system && !visited.count(type_system))
+ {
+ visited.insert(type_system);
+ type_system->Finalize();
+ }
+ }
+ map.clear();
+ {
+ std::lock_guard<std::mutex> guard(m_mutex);
+ m_map.clear();
+ m_clear_in_progress = false;
+ }
}
void
TypeSystemMap::ForEach (std::function <bool(TypeSystem *)> const &callback)
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::mutex> guard(m_mutex);
// Use a std::set so we only call the callback once for each unique
// TypeSystem instance
std::set<TypeSystem *> visited;
@@ -201,7 +221,7 @@ TypeSystemMap::ForEach (std::function <bool(TypeSystem *)> const &callback)
TypeSystem *
TypeSystemMap::GetTypeSystemForLanguage (lldb::LanguageType language, Module *module, bool can_create)
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::mutex> guard(m_mutex);
collection::iterator pos = m_map.find(language);
if (pos != m_map.end())
return pos->second.get();
@@ -212,7 +232,7 @@ TypeSystemMap::GetTypeSystemForLanguage (lldb::LanguageType language, Module *mo
{
// Add a new mapping for "language" to point to an already existing
// TypeSystem that supports this language
- m_map[language] = pair.second;
+ AddToMap(language, pair.second);
return pair.second.get();
}
}
@@ -222,14 +242,14 @@ TypeSystemMap::GetTypeSystemForLanguage (lldb::LanguageType language, Module *mo
// Cache even if we get a shared pointer that contains null type system back
lldb::TypeSystemSP type_system_sp = TypeSystem::CreateInstance (language, module);
- m_map[language] = type_system_sp;
+ AddToMap (language, type_system_sp);
return type_system_sp.get();
}
TypeSystem *
TypeSystemMap::GetTypeSystemForLanguage (lldb::LanguageType language, Target *target, bool can_create)
{
- Mutex::Locker locker (m_mutex);
+ std::lock_guard<std::mutex> guard(m_mutex);
collection::iterator pos = m_map.find(language);
if (pos != m_map.end())
return pos->second.get();
@@ -240,7 +260,8 @@ TypeSystemMap::GetTypeSystemForLanguage (lldb::LanguageType language, Target *ta
{
// Add a new mapping for "language" to point to an already existing
// TypeSystem that supports this language
- m_map[language] = pair.second;
+
+ AddToMap(language, pair.second);
return pair.second.get();
}
}
@@ -249,7 +270,17 @@ TypeSystemMap::GetTypeSystemForLanguage (lldb::LanguageType language, Target *ta
return nullptr;
// Cache even if we get a shared pointer that contains null type system back
- lldb::TypeSystemSP type_system_sp = TypeSystem::CreateInstance (language, target);
- m_map[language] = type_system_sp;
+ lldb::TypeSystemSP type_system_sp;
+ if (!m_clear_in_progress)
+ type_system_sp = TypeSystem::CreateInstance (language, target);
+
+ AddToMap(language, type_system_sp);
return type_system_sp.get();
}
+
+void
+TypeSystemMap::AddToMap (lldb::LanguageType language, lldb::TypeSystemSP const &type_system_sp)
+{
+ if (!m_clear_in_progress)
+ m_map[language] = type_system_sp;
+}
diff --git a/source/Symbol/UnwindPlan.cpp b/source/Symbol/UnwindPlan.cpp
index 80c22c08ee4f..18f0cb7b9dbd 100644
--- a/source/Symbol/UnwindPlan.cpp
+++ b/source/Symbol/UnwindPlan.cpp
@@ -338,7 +338,7 @@ UnwindPlan::AppendRow (const UnwindPlan::RowSP &row_sp)
}
void
-UnwindPlan::InsertRow (const UnwindPlan::RowSP &row_sp)
+UnwindPlan::InsertRow (const UnwindPlan::RowSP &row_sp, bool replace_existing)
{
collection::iterator it = m_row_list.begin();
while (it != m_row_list.end()) {
@@ -349,6 +349,8 @@ UnwindPlan::InsertRow (const UnwindPlan::RowSP &row_sp)
}
if (it == m_row_list.end() || (*it)->GetOffset() != row_sp->GetOffset())
m_row_list.insert(it, row_sp);
+ else if (replace_existing)
+ *it = row_sp;
}
UnwindPlan::RowSP
@@ -383,16 +385,27 @@ UnwindPlan::IsValidRowIndex (uint32_t idx) const
const UnwindPlan::RowSP
UnwindPlan::GetRowAtIndex (uint32_t idx) const
{
- // You must call IsValidRowIndex(idx) first before calling this!!!
- assert (idx < m_row_list.size());
- return m_row_list[idx];
+ if (idx < m_row_list.size())
+ return m_row_list[idx];
+ else
+ {
+ Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
+ if (log)
+ log->Printf ("error: UnwindPlan::GetRowAtIndex(idx = %u) invalid index (number rows is %u)", idx, (uint32_t)m_row_list.size());
+ return UnwindPlan::RowSP();
+ }
}
const UnwindPlan::RowSP
UnwindPlan::GetLastRow () const
{
- // You must call GetRowCount() first to make sure there is at least one row
- assert (!m_row_list.empty());
+ if (m_row_list.empty())
+ {
+ Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
+ if (log)
+ log->Printf ("UnwindPlan::GetLastRow() when rows are empty");
+ return UnwindPlan::RowSP();
+ }
return m_row_list.back();
}
diff --git a/source/Symbol/UnwindTable.cpp b/source/Symbol/UnwindTable.cpp
index ac7a9b0fda87..87c18d94b070 100644
--- a/source/Symbol/UnwindTable.cpp
+++ b/source/Symbol/UnwindTable.cpp
@@ -27,14 +27,14 @@
using namespace lldb;
using namespace lldb_private;
-UnwindTable::UnwindTable (ObjectFile& objfile) :
- m_object_file (objfile),
- m_unwinds (),
- m_initialized (false),
- m_mutex (),
- m_eh_frame_up (),
- m_compact_unwind_up (),
- m_arm_unwind_up ()
+UnwindTable::UnwindTable(ObjectFile &objfile)
+ : m_object_file(objfile),
+ m_unwinds(),
+ m_initialized(false),
+ m_mutex(),
+ m_eh_frame_up(),
+ m_compact_unwind_up(),
+ m_arm_unwind_up()
{
}
@@ -47,7 +47,7 @@ UnwindTable::Initialize ()
if (m_initialized)
return;
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::mutex> guard(m_mutex);
if (m_initialized) // check again once we've acquired the lock
return;
@@ -90,7 +90,7 @@ UnwindTable::GetFuncUnwindersContainingAddress (const Address& addr, SymbolConte
Initialize();
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::mutex> guard(m_mutex);
// There is an UnwindTable per object file, so we can safely use file handles
addr_t file_addr = addr.GetFileAddress();
@@ -152,7 +152,7 @@ UnwindTable::GetUncachedFuncUnwindersContainingAddress (const Address& addr, Sym
void
UnwindTable::Dump (Stream &s)
{
- Mutex::Locker locker(m_mutex);
+ std::lock_guard<std::mutex> guard(m_mutex);
s.Printf("UnwindTable for '%s':\n", m_object_file.GetFileSpec().GetPath().c_str());
const_iterator begin = m_unwinds.begin();
const_iterator end = m_unwinds.end();
@@ -189,3 +189,9 @@ UnwindTable::GetArchitecture (lldb_private::ArchSpec &arch)
{
return m_object_file.GetArchitecture (arch);
}
+
+bool
+UnwindTable::GetAllowAssemblyEmulationUnwindPlans ()
+{
+ return m_object_file.AllowAssemblyEmulationUnwindPlans ();
+}
diff --git a/source/Symbol/Variable.cpp b/source/Symbol/Variable.cpp
index 51d11b7ca8e9..dd27b1b5d802 100644
--- a/source/Symbol/Variable.cpp
+++ b/source/Symbol/Variable.cpp
@@ -43,6 +43,7 @@ Variable::Variable (lldb::user_id_t uid,
const lldb::SymbolFileTypeSP &symfile_type_sp,
ValueType scope,
SymbolContextScope *context,
+ const RangeList& scope_range,
Declaration* decl_ptr,
const DWARFExpression& location,
bool external,
@@ -54,6 +55,7 @@ Variable::Variable (lldb::user_id_t uid,
m_symfile_type_sp(symfile_type_sp),
m_scope(scope),
m_owner_scope(context),
+ m_scope_range(scope_range),
m_declaration(decl_ptr),
m_location(location),
m_external(external),
@@ -155,8 +157,13 @@ Variable::Dump(Stream *s, bool show_context) const
switch (m_scope)
{
case eValueTypeVariableGlobal: s->PutCString(m_external ? "global" : "static"); break;
- case eValueTypeVariableArgument: s->PutCString("parameter"); break;
+ case eValueTypeVariableArgument:
+ s->PutCString("parameter");
+ break;
case eValueTypeVariableLocal: s->PutCString("local"); break;
+ case eValueTypeVariableThreadLocal:
+ s->PutCString("thread local");
+ break;
default: *s << "??? (" << m_scope << ')';
}
}
@@ -242,17 +249,16 @@ CompilerDeclContext
Variable::GetDeclContext ()
{
Type *type = GetType();
- return type->GetSymbolFile()->GetDeclContextContainingUID(GetID());
+ if (type)
+ return type->GetSymbolFile()->GetDeclContextContainingUID(GetID());
+ return CompilerDeclContext();
}
CompilerDecl
Variable::GetDecl ()
{
Type *type = GetType();
- CompilerDecl decl = type->GetSymbolFile()->GetDeclForUID(GetID());
- if (decl)
- decl.GetTypeSystem()->DeclLinkToObject(decl.GetOpaqueDecl(), shared_from_this());
- return decl;
+ return type ? type->GetSymbolFile()->GetDeclForUID(GetID()) : CompilerDecl();
}
void
@@ -343,6 +349,7 @@ Variable::IsInScope (StackFrame *frame)
case eValueTypeConstResult:
case eValueTypeVariableGlobal:
case eValueTypeVariableStatic:
+ case eValueTypeVariableThreadLocal:
return true;
case eValueTypeVariableArgument:
@@ -356,14 +363,24 @@ Variable::IsInScope (StackFrame *frame)
{
SymbolContext variable_sc;
CalculateSymbolContext (&variable_sc);
+
// Check for static or global variable defined at the compile unit
// level that wasn't defined in a block
if (variable_sc.block == nullptr)
- return true;
+ return true;
- if (variable_sc.block == deepest_frame_block)
+ // Check if the variable is valid in the current block
+ if (variable_sc.block != deepest_frame_block &&
+ !variable_sc.block->Contains(deepest_frame_block))
+ return false;
+
+ // If no scope range is specified then it means that the scope is the same as the
+ // scope of the enclosing lexical block.
+ if (m_scope_range.IsEmpty())
return true;
- return variable_sc.block->Contains (deepest_frame_block);
+
+ addr_t file_address = frame->GetFrameCodeAddress().GetFileAddress();
+ return m_scope_range.FindEntryThatContains(file_address) != nullptr;
}
}
break;
@@ -816,6 +833,7 @@ PrivateAutoComplete (StackFrame *frame,
word_complete);
}
}
+ break;
default:
break;
}
@@ -852,6 +870,7 @@ PrivateAutoComplete (StackFrame *frame,
matches,
word_complete);
}
+ break;
default:
break;
}