[llvm-branch-commits] [lldb] r186540 - Merge top of tree.
Greg Clayton
gclayton at apple.com
Wed Jul 17 15:19:37 PDT 2013
Modified: lldb/branches/lldb-platform-work/source/Host/linux/Host.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Host/linux/Host.cpp?rev=186540&r1=186539&r2=186540&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Host/linux/Host.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Host/linux/Host.cpp Wed Jul 17 17:17:41 2013
@@ -14,6 +14,7 @@
#include <sys/stat.h>
#include <dirent.h>
#include <fcntl.h>
+#include <execinfo.h>
// C++ Includes
// Other libraries and framework includes
@@ -104,6 +105,13 @@ ReadProcPseudoFile (lldb::pid_t pid, con
return buf_sp;
}
+lldb::DataBufferSP
+ReadProcPseudoFile (lldb::pid_t pid, lldb::tid_t tid, const char *name)
+{
+ std::string process_thread_pseudo_file = "task/" + std::to_string(tid) + "/" + name;
+ return ReadProcPseudoFile(pid, process_thread_pseudo_file.c_str());
+}
+
} // anonymous namespace
static bool
@@ -334,7 +342,7 @@ GetELFProcessCPUType (const char *exe_pa
ModuleSpecList specs;
FileSpec filespec (exe_path, false);
- const size_t num_specs = ObjectFile::GetModuleSpecifications (filespec, 0, specs);
+ const size_t num_specs = ObjectFile::GetModuleSpecifications (filespec, 0, 0, specs);
// GetModuleSpecifications() could fail if the executable has been deleted or is locked.
// But it shouldn't return more than 1 architecture.
assert(num_specs <= 1 && "Linux plugin supports only a single architecture");
@@ -472,15 +480,58 @@ Host::ThreadCreated (const char *thread_
}
}
+std::string
+Host::GetThreadName (lldb::pid_t pid, lldb::tid_t tid)
+{
+ const size_t thread_name_max_size = 16;
+ char pthread_name[thread_name_max_size];
+ std::string thread_name;
+ // Read the /proc/$PID/stat file.
+ lldb::DataBufferSP buf_sp = ReadProcPseudoFile (pid, tid, "stat");
+
+ // The file/thread name of the executable is stored in parenthesis. Search for the first
+ // '(' and last ')' and copy everything in between.
+ const char *filename_start = ::strchr ((const char *)buf_sp->GetBytes(), '(');
+ const char *filename_end = ::strrchr ((const char *)buf_sp->GetBytes(), ')');
+
+ if (filename_start && filename_end)
+ {
+ ++filename_start;
+ size_t length = filename_end - filename_start;
+ if (length > thread_name_max_size)
+ length = thread_name_max_size;
+ strncpy(pthread_name, filename_start, length);
+ thread_name = std::string(pthread_name, length);
+ }
+
+ return thread_name;
+}
+
void
Host::Backtrace (Stream &strm, uint32_t max_frames)
{
- // TODO: Is there a way to backtrace the current process on linux?
+ if (max_frames > 0)
+ {
+ std::vector<void *> frame_buffer (max_frames, NULL);
+ int num_frames = ::backtrace (&frame_buffer[0], frame_buffer.size());
+ char** strs = ::backtrace_symbols (&frame_buffer[0], num_frames);
+ if (strs)
+ {
+ // Start at 1 to skip the "Host::Backtrace" frame
+ for (int i = 1; i < num_frames; ++i)
+ strm.Printf("%s\n", strs[i]);
+ ::free (strs);
+ }
+ }
}
size_t
Host::GetEnvironment (StringList &env)
{
- // TODO: Is there a way to the host environment for this process on linux?
- return 0;
+ char **host_env = environ;
+ char *env_entry;
+ size_t i;
+ for (i=0; (env_entry = host_env[i]) != NULL; ++i)
+ env.AppendString(env_entry);
+ return i;
}
Modified: lldb/branches/lldb-platform-work/source/Host/macosx/Host.mm
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Host/macosx/Host.mm?rev=186540&r1=186539&r2=186540&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Host/macosx/Host.mm (original)
+++ lldb/branches/lldb-platform-work/source/Host/macosx/Host.mm Wed Jul 17 17:17:41 2013
@@ -148,6 +148,39 @@ Host::ThreadCreated (const char *thread_
}
}
+std::string
+Host::GetThreadName (lldb::pid_t pid, lldb::tid_t tid)
+{
+ std::string thread_name;
+#if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5
+ // We currently can only get the name of a thread in the current process.
+ if (pid == Host::GetCurrentProcessID())
+ {
+ char pthread_name[1024];
+ if (::pthread_getname_np (::pthread_from_mach_thread_np (tid), pthread_name, sizeof(pthread_name)) == 0)
+ {
+ if (pthread_name[0])
+ {
+ thread_name = pthread_name;
+ }
+ }
+ else
+ {
+ dispatch_queue_t current_queue = ::dispatch_get_current_queue ();
+ if (current_queue != NULL)
+ {
+ const char *queue_name = dispatch_queue_get_label (current_queue);
+ if (queue_name && queue_name[0])
+ {
+ thread_name = queue_name;
+ }
+ }
+ }
+ }
+#endif
+ return thread_name;
+}
+
bool
Host::GetBundleDirectory (const FileSpec &file, FileSpec &bundle_directory)
{
Modified: lldb/branches/lldb-platform-work/source/Host/macosx/launcherXPCService/LauncherRootXPCService-Info.plist
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Host/macosx/launcherXPCService/LauncherRootXPCService-Info.plist?rev=186540&r1=186539&r2=186540&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Host/macosx/launcherXPCService/LauncherRootXPCService-Info.plist (original)
+++ lldb/branches/lldb-platform-work/source/Host/macosx/launcherXPCService/LauncherRootXPCService-Info.plist Wed Jul 17 17:17:41 2013
@@ -25,7 +25,7 @@
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
- <string>300.99.0</string>
+ <string>310.99.0</string>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2012 Apple Inc. All rights reserved.</string>
<key>XPCService</key>
Modified: lldb/branches/lldb-platform-work/source/Host/macosx/launcherXPCService/LauncherXPCService-Info.plist
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Host/macosx/launcherXPCService/LauncherXPCService-Info.plist?rev=186540&r1=186539&r2=186540&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Host/macosx/launcherXPCService/LauncherXPCService-Info.plist (original)
+++ lldb/branches/lldb-platform-work/source/Host/macosx/launcherXPCService/LauncherXPCService-Info.plist Wed Jul 17 17:17:41 2013
@@ -25,7 +25,7 @@
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
- <string>300.99.0</string>
+ <string>310.99.0</string>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2012 Apple Inc. All rights reserved.</string>
<key>XPCService</key>
Modified: lldb/branches/lldb-platform-work/source/Interpreter/PythonDataObjects.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Interpreter/PythonDataObjects.cpp?rev=186540&r1=186539&r2=186540&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Interpreter/PythonDataObjects.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Interpreter/PythonDataObjects.cpp Wed Jul 17 17:17:41 2013
@@ -66,6 +66,28 @@ PythonObject::Dump (Stream &strm) const
strm.PutCString ("NULL");
}
+PythonString
+PythonObject::Repr ()
+{
+ if (!m_py_obj)
+ return PythonString ();
+ PyObject *repr = PyObject_Repr(m_py_obj);
+ if (!repr)
+ return PythonString ();
+ return PythonString(repr);
+}
+
+PythonString
+PythonObject::Str ()
+{
+ if (!m_py_obj)
+ return PythonString ();
+ PyObject *str = PyObject_Str(m_py_obj);
+ if (!str)
+ return PythonString ();
+ return PythonString(str);
+}
+
//----------------------------------------------------------------------
// PythonString
//----------------------------------------------------------------------
Modified: lldb/branches/lldb-platform-work/source/Interpreter/ScriptInterpreterPython.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Interpreter/ScriptInterpreterPython.cpp?rev=186540&r1=186539&r2=186540&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Interpreter/ScriptInterpreterPython.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Interpreter/ScriptInterpreterPython.cpp Wed Jul 17 17:17:41 2013
@@ -119,7 +119,7 @@ LLDBSwigPythonCallCommand (const char *p
const char *session_dictionary_name,
lldb::DebuggerSP& debugger,
const char* args,
- lldb_private::CommandReturnObject& cmd_retobj);
+ lldb_private::CommandReturnObject &cmd_retobj);
extern "C" bool
LLDBSwigPythonCallModuleInit (const char *python_module_name,
@@ -2964,7 +2964,7 @@ ScriptInterpreterPython::RunScriptBasedC
}
lldb::DebuggerSP debugger_sp = m_interpreter.GetDebugger().shared_from_this();
-
+
if (!debugger_sp.get())
{
error.SetErrorString("invalid Debugger pointer");
@@ -2974,15 +2974,15 @@ ScriptInterpreterPython::RunScriptBasedC
bool ret_val = false;
std::string err_msg;
-
+
{
Locker py_lock(this,
Locker::AcquireLock | Locker::InitSession,
Locker::FreeLock | Locker::TearDownSession);
-
+
SynchronicityHandler synch_handler(debugger_sp,
synchronicity);
-
+
// we need to save the thread state when we first start the command
// because we might decide to interrupt it while some action is taking
// place outside of Python (e.g. printing to screen, waiting for the network, ...)
@@ -2998,7 +2998,7 @@ ScriptInterpreterPython::RunScriptBasedC
args,
cmd_retobj);
}
-
+
if (!ret_val)
error.SetErrorString("unable to execute script function");
else
Modified: lldb/branches/lldb-platform-work/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp?rev=186540&r1=186539&r2=186540&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp Wed Jul 17 17:17:41 2013
@@ -318,8 +318,6 @@ ABIMacOSX_arm::GetArgumentValues (Thread
// For now, assume that the types in the AST values come from the Target's
// scratch AST.
- clang::ASTContext *ast_context = exe_ctx.GetTargetRef().GetScratchClangASTContext()->getASTContext();
-
// Extract the register context so we can read arguments from registers
RegisterContext *reg_ctx = thread.GetRegisterContext().get();
@@ -338,18 +336,18 @@ ABIMacOSX_arm::GetArgumentValues (Thread
if (!value)
return false;
- void *value_type = value->GetClangType();
- if (value_type)
+ ClangASTType clang_type = value->GetClangType();
+ if (clang_type)
{
bool is_signed = false;
size_t bit_width = 0;
- if (ClangASTContext::IsIntegerType (value_type, is_signed))
+ if (clang_type.IsIntegerType (is_signed))
{
- bit_width = ClangASTType::GetClangTypeBitWidth(ast_context, value_type);
+ bit_width = clang_type.GetBitSize();
}
- else if (ClangASTContext::IsPointerOrReferenceType (value_type))
+ else if (clang_type.IsPointerOrReferenceType ())
{
- bit_width = ClangASTType::GetClangTypeBitWidth(ast_context, value_type);
+ bit_width = clang_type.GetBitSize();
}
else
{
@@ -421,20 +419,20 @@ ABIMacOSX_arm::GetArgumentValues (Thread
ValueObjectSP
ABIMacOSX_arm::GetReturnValueObjectImpl (Thread &thread,
- lldb_private::ClangASTType &ast_type) const
+ lldb_private::ClangASTType &clang_type) const
{
Value value;
ValueObjectSP return_valobj_sp;
- void *value_type = ast_type.GetOpaqueQualType();
- if (!value_type)
+ if (!clang_type)
return return_valobj_sp;
- clang::ASTContext *ast_context = ast_type.GetASTContext();
+ clang::ASTContext *ast_context = clang_type.GetASTContext();
if (!ast_context)
return return_valobj_sp;
- value.SetContext (Value::eContextTypeClangType, value_type);
+ //value.SetContext (Value::eContextTypeClangType, clang_type.GetOpaqueQualType());
+ value.SetClangType (clang_type);
RegisterContext *reg_ctx = thread.GetRegisterContext().get();
if (!reg_ctx)
@@ -446,9 +444,9 @@ ABIMacOSX_arm::GetReturnValueObjectImpl
// when reading data
const RegisterInfo *r0_reg_info = reg_ctx->GetRegisterInfoByName("r0", 0);
- if (ClangASTContext::IsIntegerType (value_type, is_signed))
+ if (clang_type.IsIntegerType (is_signed))
{
- size_t bit_width = ClangASTType::GetClangTypeBitWidth(ast_context, value_type);
+ size_t bit_width = clang_type.GetBitSize();
switch (bit_width)
{
@@ -486,7 +484,7 @@ ABIMacOSX_arm::GetReturnValueObjectImpl
break;
}
}
- else if (ClangASTContext::IsPointerType (value_type))
+ else if (clang_type.IsPointerType ())
{
uint32_t ptr = thread.GetRegisterContext()->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX;
value.GetScalar() = ptr;
@@ -499,11 +497,9 @@ ABIMacOSX_arm::GetReturnValueObjectImpl
// If we get here, we have a valid Value, so make our ValueObject out of it:
- return_valobj_sp = ValueObjectConstResult::Create(
- thread.GetStackFrameAtIndex(0).get(),
- ast_type.GetASTContext(),
- value,
- ConstString(""));
+ return_valobj_sp = ValueObjectConstResult::Create(thread.GetStackFrameAtIndex(0).get(),
+ value,
+ ConstString(""));
return return_valobj_sp;
}
@@ -517,19 +513,13 @@ ABIMacOSX_arm::SetReturnValueObject(lldb
return error;
}
- clang_type_t value_type = new_value_sp->GetClangType();
- if (!value_type)
+ ClangASTType clang_type = new_value_sp->GetClangType();
+ if (!clang_type)
{
error.SetErrorString ("Null clang type for return value.");
return error;
}
- clang::ASTContext *ast_context = new_value_sp->GetClangAST();
- if (!ast_context)
- {
- error.SetErrorString ("Null clang AST for return value.");
- return error;
- }
Thread *thread = frame_sp->GetThread().get();
bool is_signed;
@@ -539,7 +529,7 @@ ABIMacOSX_arm::SetReturnValueObject(lldb
RegisterContext *reg_ctx = thread->GetRegisterContext().get();
bool set_it_simple = false;
- if (ClangASTContext::IsIntegerType (value_type, is_signed) || ClangASTContext::IsPointerType(value_type))
+ if (clang_type.IsIntegerType (is_signed) || clang_type.IsPointerType())
{
DataExtractor data;
size_t num_bytes = new_value_sp->GetData(data);
@@ -573,7 +563,7 @@ ABIMacOSX_arm::SetReturnValueObject(lldb
error.SetErrorString("We don't support returning longer than 64 bit integer values at present.");
}
}
- else if (ClangASTContext::IsFloatingPointType (value_type, count, is_complex))
+ else if (clang_type.IsFloatingPointType (count, is_complex))
{
if (is_complex)
error.SetErrorString ("We don't support returning complex values at present");
Modified: lldb/branches/lldb-platform-work/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp?rev=186540&r1=186539&r2=186540&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp Wed Jul 17 17:17:41 2013
@@ -510,16 +510,12 @@ ABIMacOSX_i386::PrepareNormalCall (Threa
}
break;
case Value::eValueTypeHostAddress:
- switch (val->GetContextType())
{
- default:
- return false;
- case Value::eContextTypeClangType:
+ ClangASTType clang_type (val->GetClangType());
+ if (clang_type)
{
- void *val_type = val->GetClangType();
- uint32_t cstr_length;
-
- if (ClangASTContext::IsCStringType (val_type, cstr_length))
+ uint32_t cstr_length = 0;
+ if (clang_type.IsCStringType (cstr_length))
{
const char *cstr = (const char*)val->GetScalar().ULongLong();
cstr_length = strlen(cstr);
@@ -616,11 +612,6 @@ ABIMacOSX_i386::GetArgumentValues (Threa
unsigned int num_values = values.GetSize();
unsigned int value_index;
- // Extract the Clang AST context from the PC so that we can figure out type
- // sizes
-
- clang::ASTContext *ast_context = thread.CalculateTarget()->GetScratchClangASTContext()->getASTContext();
-
// Get the pointer to the first stack argument so we have a place to start
// when reading data
@@ -647,35 +638,27 @@ ABIMacOSX_i386::GetArgumentValues (Threa
// We currently only support extracting values with Clang QualTypes.
// Do we care about others?
- switch (value->GetContextType())
+ ClangASTType clang_type (value->GetClangType());
+ if (clang_type)
{
- default:
- return false;
- case Value::eContextTypeClangType:
- {
- void *value_type = value->GetClangType();
- bool is_signed;
-
- if (ClangASTContext::IsIntegerType (value_type, is_signed))
- {
- size_t bit_width = ClangASTType::GetClangTypeBitWidth(ast_context, value_type);
-
- ReadIntegerArgument(value->GetScalar(),
- bit_width,
- is_signed,
- thread.GetProcess().get(),
- current_stack_argument);
- }
- else if (ClangASTContext::IsPointerType (value_type))
- {
- ReadIntegerArgument(value->GetScalar(),
- 32,
- false,
- thread.GetProcess().get(),
- current_stack_argument);
- }
- }
- break;
+ bool is_signed;
+
+ if (clang_type.IsIntegerType (is_signed))
+ {
+ ReadIntegerArgument(value->GetScalar(),
+ clang_type.GetBitSize(),
+ is_signed,
+ thread.GetProcess().get(),
+ current_stack_argument);
+ }
+ else if (clang_type.IsPointerType())
+ {
+ ReadIntegerArgument(value->GetScalar(),
+ clang_type.GetBitSize(),
+ false,
+ thread.GetProcess().get(),
+ current_stack_argument);
+ }
}
}
@@ -692,19 +675,13 @@ ABIMacOSX_i386::SetReturnValueObject(lld
return error;
}
- clang_type_t value_type = new_value_sp->GetClangType();
- if (!value_type)
+ ClangASTType clang_type = new_value_sp->GetClangType();
+ if (!clang_type)
{
error.SetErrorString ("Null clang type for return value.");
return error;
}
- clang::ASTContext *ast_context = new_value_sp->GetClangAST();
- if (!ast_context)
- {
- error.SetErrorString ("Null clang AST for return value.");
- return error;
- }
Thread *thread = frame_sp->GetThread().get();
bool is_signed;
@@ -714,7 +691,7 @@ ABIMacOSX_i386::SetReturnValueObject(lld
RegisterContext *reg_ctx = thread->GetRegisterContext().get();
bool set_it_simple = false;
- if (ClangASTContext::IsIntegerType (value_type, is_signed) || ClangASTContext::IsPointerType(value_type))
+ if (clang_type.IsIntegerType (is_signed) || clang_type.IsPointerType())
{
DataExtractor data;
size_t num_bytes = new_value_sp->GetData(data);
@@ -748,7 +725,7 @@ ABIMacOSX_i386::SetReturnValueObject(lld
error.SetErrorString("We don't support returning longer than 64 bit integer values at present.");
}
}
- else if (ClangASTContext::IsFloatingPointType (value_type, count, is_complex))
+ else if (clang_type.IsFloatingPointType (count, is_complex))
{
if (is_complex)
error.SetErrorString ("We don't support returning complex values at present");
@@ -764,20 +741,16 @@ ABIMacOSX_i386::SetReturnValueObject(lld
ValueObjectSP
ABIMacOSX_i386::GetReturnValueObjectImpl (Thread &thread,
- ClangASTType &ast_type) const
+ ClangASTType &clang_type) const
{
Value value;
ValueObjectSP return_valobj_sp;
- void *value_type = ast_type.GetOpaqueQualType();
- if (!value_type)
+ if (!clang_type)
return return_valobj_sp;
- clang::ASTContext *ast_context = ast_type.GetASTContext();
- if (!ast_context)
- return return_valobj_sp;
-
- value.SetContext (Value::eContextTypeClangType, value_type);
+ //value.SetContext (Value::eContextTypeClangType, clang_type.GetOpaqueQualType());
+ value.SetClangType (clang_type);
RegisterContext *reg_ctx = thread.GetRegisterContext().get();
if (!reg_ctx)
@@ -785,9 +758,9 @@ ABIMacOSX_i386::GetReturnValueObjectImpl
bool is_signed;
- if (ClangASTContext::IsIntegerType (value_type, is_signed))
+ if (clang_type.IsIntegerType (is_signed))
{
- size_t bit_width = ClangASTType::GetClangTypeBitWidth(ast_context, value_type);
+ size_t bit_width = clang_type.GetBitSize();
unsigned eax_id = reg_ctx->GetRegisterInfoByName("eax", 0)->kinds[eRegisterKindLLDB];
unsigned edx_id = reg_ctx->GetRegisterInfoByName("edx", 0)->kinds[eRegisterKindLLDB];
@@ -827,7 +800,7 @@ ABIMacOSX_i386::GetReturnValueObjectImpl
break;
}
}
- else if (ClangASTContext::IsPointerType (value_type))
+ else if (clang_type.IsPointerType ())
{
unsigned eax_id = reg_ctx->GetRegisterInfoByName("eax", 0)->kinds[eRegisterKindLLDB];
uint32_t ptr = thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) & 0xffffffff;
@@ -841,11 +814,9 @@ ABIMacOSX_i386::GetReturnValueObjectImpl
// If we get here, we have a valid Value, so make our ValueObject out of it:
- return_valobj_sp = ValueObjectConstResult::Create(
- thread.GetStackFrameAtIndex(0).get(),
- ast_type.GetASTContext(),
- value,
- ConstString(""));
+ return_valobj_sp = ValueObjectConstResult::Create(thread.GetStackFrameAtIndex(0).get(),
+ value,
+ ConstString(""));
return return_valobj_sp;
}
Modified: lldb/branches/lldb-platform-work/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp?rev=186540&r1=186539&r2=186540&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp Wed Jul 17 17:17:41 2013
@@ -313,14 +313,39 @@ ABISysV_x86_64::PrepareTrivialCall (Thre
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
if (log)
- log->Printf("ABISysV_x86_64::PrepareTrivialCall\n(\n thread = %p\n sp = 0x%" PRIx64 "\n func_addr = 0x%" PRIx64 "\n return_addr = 0x%" PRIx64 "\n arg1_ptr = %p (0x%" PRIx64 ")\n arg2_ptr = %p (0x%" PRIx64 ")\n arg3_ptr = %p (0x%" PRIx64 ")\n)",
- (void*)&thread,
+ {
+ StreamString s;
+ s.Printf("ABISysV_x86_64::PrepareTrivialCall (tid = 0x%" PRIx64 ", sp = 0x%" PRIx64 ", func_addr = 0x%" PRIx64 ", return_addr = 0x%" PRIx64,
+ thread.GetID(),
(uint64_t)sp,
(uint64_t)func_addr,
- (uint64_t)return_addr,
- arg1_ptr, arg1_ptr ? (uint64_t)*arg1_ptr : (uint64_t) 0,
- arg2_ptr, arg2_ptr ? (uint64_t)*arg2_ptr : (uint64_t) 0,
- arg3_ptr, arg3_ptr ? (uint64_t)*arg3_ptr : (uint64_t) 0);
+ (uint64_t)return_addr);
+
+ if (arg1_ptr)
+ {
+ s.Printf (", arg1 = 0x%" PRIx64, (uint64_t)*arg1_ptr);
+ if (arg2_ptr)
+ {
+ s.Printf (", arg2 = 0x%" PRIx64, (uint64_t)*arg2_ptr);
+ if (arg3_ptr)
+ {
+ s.Printf (", arg3 = 0x%" PRIx64, (uint64_t)*arg3_ptr);
+ if (arg4_ptr)
+ {
+ s.Printf (", arg4 = 0x%" PRIx64, (uint64_t)*arg4_ptr);
+ if (arg5_ptr)
+ {
+ s.Printf (", arg5 = 0x%" PRIx64, (uint64_t)*arg5_ptr);
+ if (arg6_ptr)
+ s.Printf (", arg6 = 0x%" PRIx64, (uint64_t)*arg6_ptr);
+ }
+ }
+ }
+ }
+ }
+ s.PutCString (")");
+ log->PutCString(s.GetString().c_str());
+ }
RegisterContext *reg_ctx = thread.GetRegisterContext().get();
if (!reg_ctx)
@@ -461,12 +486,7 @@ ABISysV_x86_64::GetArgumentValues (Threa
{
unsigned int num_values = values.GetSize();
unsigned int value_index;
-
- // For now, assume that the types in the AST values come from the Target's
- // scratch AST.
-
- clang::ASTContext *ast = thread.CalculateTarget()->GetScratchClangASTContext()->getASTContext();
-
+
// Extract the register context so we can read arguments from registers
RegisterContext *reg_ctx = thread.GetRegisterContext().get();
@@ -506,39 +526,30 @@ ABISysV_x86_64::GetArgumentValues (Threa
// We currently only support extracting values with Clang QualTypes.
// Do we care about others?
- switch (value->GetContextType())
- {
- default:
+ ClangASTType clang_type = value->GetClangType();
+ if (!clang_type)
return false;
- case Value::eContextTypeClangType:
- {
- void *value_type = value->GetClangType();
- bool is_signed;
-
- if (ClangASTContext::IsIntegerType (value_type, is_signed))
- {
- size_t bit_width = ClangASTType::GetClangTypeBitWidth(ast, value_type);
-
- ReadIntegerArgument(value->GetScalar(),
- bit_width,
- is_signed,
- thread,
- argument_register_ids,
- current_argument_register,
- current_stack_argument);
- }
- else if (ClangASTContext::IsPointerType (value_type))
- {
- ReadIntegerArgument(value->GetScalar(),
- 64,
- false,
- thread,
- argument_register_ids,
- current_argument_register,
- current_stack_argument);
- }
- }
- break;
+ bool is_signed;
+
+ if (clang_type.IsIntegerType (is_signed))
+ {
+ ReadIntegerArgument(value->GetScalar(),
+ clang_type.GetBitSize(),
+ is_signed,
+ thread,
+ argument_register_ids,
+ current_argument_register,
+ current_stack_argument);
+ }
+ else if (clang_type.IsPointerType ())
+ {
+ ReadIntegerArgument(value->GetScalar(),
+ clang_type.GetBitSize(),
+ false,
+ thread,
+ argument_register_ids,
+ current_argument_register,
+ current_stack_argument);
}
}
@@ -555,19 +566,13 @@ ABISysV_x86_64::SetReturnValueObject(lld
return error;
}
- clang_type_t value_type = new_value_sp->GetClangType();
- if (!value_type)
+ ClangASTType clang_type = new_value_sp->GetClangType();
+ if (!clang_type)
{
error.SetErrorString ("Null clang type for return value.");
return error;
}
- clang::ASTContext *ast = new_value_sp->GetClangAST();
- if (!ast)
- {
- error.SetErrorString ("Null clang AST for return value.");
- return error;
- }
Thread *thread = frame_sp->GetThread().get();
bool is_signed;
@@ -577,7 +582,7 @@ ABISysV_x86_64::SetReturnValueObject(lld
RegisterContext *reg_ctx = thread->GetRegisterContext().get();
bool set_it_simple = false;
- if (ClangASTContext::IsIntegerType (value_type, is_signed) || ClangASTContext::IsPointerType(value_type))
+ if (clang_type.IsIntegerType (is_signed) || clang_type.IsPointerType())
{
const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName("rax", 0);
@@ -597,13 +602,13 @@ ABISysV_x86_64::SetReturnValueObject(lld
}
}
- else if (ClangASTContext::IsFloatingPointType (value_type, count, is_complex))
+ else if (clang_type.IsFloatingPointType (count, is_complex))
{
if (is_complex)
error.SetErrorString ("We don't support returning complex values at present");
else
{
- size_t bit_width = ClangASTType::GetClangTypeBitWidth(ast, value_type);
+ size_t bit_width = clang_type.GetBitSize();
if (bit_width <= 64)
{
const RegisterInfo *xmm0_info = reg_ctx->GetRegisterInfoByName("xmm0", 0);
@@ -640,38 +645,34 @@ ABISysV_x86_64::SetReturnValueObject(lld
ValueObjectSP
ABISysV_x86_64::GetReturnValueObjectSimple (Thread &thread,
- ClangASTType &ast_type) const
+ ClangASTType &return_clang_type) const
{
ValueObjectSP return_valobj_sp;
Value value;
- clang_type_t return_value_type = ast_type.GetOpaqueQualType();
- if (!return_value_type)
- return return_valobj_sp;
-
- clang::ASTContext *ast = ast_type.GetASTContext();
- if (!ast)
+ if (!return_clang_type)
return return_valobj_sp;
- value.SetContext (Value::eContextTypeClangType, return_value_type);
+ //value.SetContext (Value::eContextTypeClangType, return_value_type);
+ value.SetClangType (return_clang_type);
RegisterContext *reg_ctx = thread.GetRegisterContext().get();
if (!reg_ctx)
return return_valobj_sp;
- const uint32_t type_flags = ClangASTContext::GetTypeInfo (return_value_type, ast, NULL);
- if (type_flags & ClangASTContext::eTypeIsScalar)
+ const uint32_t type_flags = return_clang_type.GetTypeInfo ();
+ if (type_flags & ClangASTType::eTypeIsScalar)
{
value.SetValueType(Value::eValueTypeScalar);
bool success = false;
- if (type_flags & ClangASTContext::eTypeIsInteger)
+ if (type_flags & ClangASTType::eTypeIsInteger)
{
// Extract the register context so we can read arguments from registers
- const size_t byte_size = ClangASTType::GetClangTypeByteSize(ast, return_value_type);
+ const size_t byte_size = return_clang_type.GetByteSize();
uint64_t raw_value = thread.GetRegisterContext()->ReadRegisterAsUnsigned(reg_ctx->GetRegisterInfoByName("rax", 0), 0);
- const bool is_signed = (type_flags & ClangASTContext::eTypeIsSigned) != 0;
+ const bool is_signed = (type_flags & ClangASTType::eTypeIsSigned) != 0;
switch (byte_size)
{
default:
@@ -710,15 +711,15 @@ ABISysV_x86_64::GetReturnValueObjectSimp
break;
}
}
- else if (type_flags & ClangASTContext::eTypeIsFloat)
+ else if (type_flags & ClangASTType::eTypeIsFloat)
{
- if (type_flags & ClangASTContext::eTypeIsComplex)
+ if (type_flags & ClangASTType::eTypeIsComplex)
{
// Don't handle complex yet.
}
else
{
- const size_t byte_size = ClangASTType::GetClangTypeByteSize(ast, return_value_type);
+ const size_t byte_size = return_clang_type.GetByteSize();
if (byte_size <= sizeof(long double))
{
const RegisterInfo *xmm0_info = reg_ctx->GetRegisterInfoByName("xmm0", 0);
@@ -751,24 +752,22 @@ ABISysV_x86_64::GetReturnValueObjectSimp
if (success)
return_valobj_sp = ValueObjectConstResult::Create (thread.GetStackFrameAtIndex(0).get(),
- ast_type.GetASTContext(),
value,
ConstString(""));
}
- else if (type_flags & ClangASTContext::eTypeIsPointer)
+ else if (type_flags & ClangASTType::eTypeIsPointer)
{
unsigned rax_id = reg_ctx->GetRegisterInfoByName("rax", 0)->kinds[eRegisterKindLLDB];
value.GetScalar() = (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id, 0);
value.SetValueType(Value::eValueTypeScalar);
return_valobj_sp = ValueObjectConstResult::Create (thread.GetStackFrameAtIndex(0).get(),
- ast_type.GetASTContext(),
value,
ConstString(""));
}
- else if (type_flags & ClangASTContext::eTypeIsVector)
+ else if (type_flags & ClangASTType::eTypeIsVector)
{
- const size_t byte_size = ClangASTType::GetClangTypeByteSize(ast, return_value_type);
+ const size_t byte_size = return_clang_type.GetByteSize();
if (byte_size > 0)
{
@@ -803,8 +802,7 @@ ABISysV_x86_64::GetReturnValueObjectSimp
byte_order,
process_sp->GetTarget().GetArchitecture().GetAddressByteSize());
return_valobj_sp = ValueObjectConstResult::Create (&thread,
- ast,
- return_value_type,
+ return_clang_type,
ConstString(""),
data);
}
@@ -819,29 +817,24 @@ ABISysV_x86_64::GetReturnValueObjectSimp
}
ValueObjectSP
-ABISysV_x86_64::GetReturnValueObjectImpl (Thread &thread, ClangASTType &ast_type) const
+ABISysV_x86_64::GetReturnValueObjectImpl (Thread &thread, ClangASTType &return_clang_type) const
{
ValueObjectSP return_valobj_sp;
+
+ if (!return_clang_type)
+ return return_valobj_sp;
ExecutionContext exe_ctx (thread.shared_from_this());
- return_valobj_sp = GetReturnValueObjectSimple(thread, ast_type);
+ return_valobj_sp = GetReturnValueObjectSimple(thread, return_clang_type);
if (return_valobj_sp)
return return_valobj_sp;
- clang_type_t return_value_type = ast_type.GetOpaqueQualType();
- if (!return_value_type)
- return return_valobj_sp;
-
- clang::ASTContext *ast = ast_type.GetASTContext();
- if (!ast)
- return return_valobj_sp;
-
RegisterContextSP reg_ctx_sp = thread.GetRegisterContext();
if (!reg_ctx_sp)
return return_valobj_sp;
- size_t bit_width = ClangASTType::GetClangTypeBitWidth(ast, return_value_type);
- if (ClangASTContext::IsAggregateType(return_value_type))
+ const size_t bit_width = return_clang_type.GetBitSize();
+ if (return_clang_type.IsAggregateType())
{
Target *target = exe_ctx.GetTargetPtr();
bool is_memory = true;
@@ -874,7 +867,7 @@ ABISysV_x86_64::GetReturnValueObjectImpl
uint32_t fp_bytes = 0; // Tracks how much of the xmm registers we've consumed so far
uint32_t integer_bytes = 0; // Tracks how much of the rax/rds registers we've consumed so far
- uint32_t num_children = ClangASTContext::GetNumFields (ast, return_value_type);
+ const uint32_t num_children = return_clang_type.GetNumFields ();
// Since we are in the small struct regime, assume we are not in memory.
is_memory = false;
@@ -887,8 +880,8 @@ ABISysV_x86_64::GetReturnValueObjectImpl
bool is_complex;
uint32_t count;
- clang_type_t field_clang_type = ClangASTContext::GetFieldAtIndex (ast, return_value_type, idx, name, &field_bit_offset, NULL, NULL);
- size_t field_bit_width = ClangASTType::GetClangTypeBitWidth(ast, field_clang_type);
+ ClangASTType field_clang_type = return_clang_type.GetFieldAtIndex (idx, name, &field_bit_offset, NULL, NULL);
+ const size_t field_bit_width = field_clang_type.GetBitSize();
// If there are any unaligned fields, this is stored in memory.
if (field_bit_offset % field_bit_width != 0)
@@ -904,7 +897,7 @@ ABISysV_x86_64::GetReturnValueObjectImpl
DataExtractor *copy_from_extractor = NULL;
uint32_t copy_from_offset = 0;
- if (ClangASTContext::IsIntegerType (field_clang_type, is_signed) || ClangASTContext::IsPointerType (field_clang_type))
+ if (field_clang_type.IsIntegerType (is_signed) || field_clang_type.IsPointerType ())
{
if (integer_bytes < 8)
{
@@ -937,7 +930,7 @@ ABISysV_x86_64::GetReturnValueObjectImpl
return return_valobj_sp;
}
}
- else if (ClangASTContext::IsFloatingPointType (field_clang_type, count, is_complex))
+ else if (field_clang_type.IsFloatingPointType (count, is_complex))
{
// Structs with long doubles are always passed in memory.
if (field_bit_width == 128)
@@ -970,14 +963,12 @@ ABISysV_x86_64::GetReturnValueObjectImpl
else
{
uint64_t next_field_bit_offset = 0;
- clang_type_t next_field_clang_type = ClangASTContext::GetFieldAtIndex (ast,
- return_value_type,
- idx + 1,
- name,
- &next_field_bit_offset,
- NULL,
- NULL);
- if (ClangASTContext::IsIntegerType (next_field_clang_type, is_signed))
+ ClangASTType next_field_clang_type = return_clang_type.GetFieldAtIndex (idx + 1,
+ name,
+ &next_field_bit_offset,
+ NULL,
+ NULL);
+ if (next_field_clang_type.IsIntegerType (is_signed))
in_gpr = true;
else
{
@@ -996,14 +987,12 @@ ABISysV_x86_64::GetReturnValueObjectImpl
else
{
uint64_t prev_field_bit_offset = 0;
- clang_type_t prev_field_clang_type = ClangASTContext::GetFieldAtIndex (ast,
- return_value_type,
- idx - 1,
- name,
- &prev_field_bit_offset,
- NULL,
- NULL);
- if (ClangASTContext::IsIntegerType (prev_field_clang_type, is_signed))
+ ClangASTType prev_field_clang_type = return_clang_type.GetFieldAtIndex (idx - 1,
+ name,
+ &prev_field_bit_offset,
+ NULL,
+ NULL);
+ if (prev_field_clang_type.IsIntegerType (is_signed))
in_gpr = true;
else
{
@@ -1067,8 +1056,7 @@ ABISysV_x86_64::GetReturnValueObjectImpl
{
// The result is in our data buffer. Let's make a variable object out of it:
return_valobj_sp = ValueObjectConstResult::Create (&thread,
- ast,
- return_value_type,
+ return_clang_type,
ConstString(""),
return_ext);
}
@@ -1087,7 +1075,7 @@ ABISysV_x86_64::GetReturnValueObjectImpl
return_valobj_sp = ValueObjectMemory::Create (&thread,
"",
Address (storage_addr, NULL),
- ast_type);
+ return_clang_type);
}
}
Modified: lldb/branches/lldb-platform-work/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp?rev=186540&r1=186539&r2=186540&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp Wed Jul 17 17:17:41 2013
@@ -123,7 +123,7 @@ public:
lldb::offset_t data_offset)
{
// All we have to do is read the opcode which can be easy for some
- // architetures
+ // architectures
bool got_op = false;
DisassemblerLLVMC &llvm_disasm = GetDisassemblerLLVMC();
const ArchSpec &arch = llvm_disasm.GetArchitecture();
Modified: lldb/branches/lldb-platform-work/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp?rev=186540&r1=186539&r2=186540&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp Wed Jul 17 17:17:41 2013
@@ -625,13 +625,15 @@ DynamicLoaderMacOSXDYLD::NotifyBreakpoin
ValueList argument_values;
Value input_value;
- void *clang_void_ptr_type = clang_ast_context->GetVoidPtrType(false);
- void *clang_uint32_type = clang_ast_context->GetBuiltinTypeForEncodingAndBitSize(lldb::eEncodingUint, 32);
+ ClangASTType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
+ ClangASTType clang_uint32_type = clang_ast_context->GetBuiltinTypeForEncodingAndBitSize(lldb::eEncodingUint, 32);
input_value.SetValueType (Value::eValueTypeScalar);
- input_value.SetContext (Value::eContextTypeClangType, clang_uint32_type);
- argument_values.PushValue(input_value);
- argument_values.PushValue(input_value);
- input_value.SetContext (Value::eContextTypeClangType, clang_void_ptr_type);
+ input_value.SetClangType (clang_uint32_type);
+// input_value.SetContext (Value::eContextTypeClangType, clang_uint32_type);
+ argument_values.PushValue (input_value);
+ argument_values.PushValue (input_value);
+ input_value.SetClangType (clang_void_ptr_type);
+ // input_value.SetContext (Value::eContextTypeClangType, clang_void_ptr_type);
argument_values.PushValue (input_value);
if (abi->GetArgumentValues (exe_ctx.GetThreadRef(), argument_values))
Modified: lldb/branches/lldb-platform-work/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.cpp?rev=186540&r1=186539&r2=186540&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.cpp Wed Jul 17 17:17:41 2013
@@ -19,6 +19,10 @@
#include "lldb/Core/Log.h"
#include "lldb/Target/Process.h"
+#if defined(__linux__) or defined(__FreeBSD__)
+#include "Plugins/Process/elf-core/ProcessElfCore.h"
+#endif
+
#include "AuxVector.h"
using namespace lldb;
@@ -53,7 +57,10 @@ ParseAuxvEntry(DataExtractor &data,
DataBufferSP
AuxVector::GetAuxvData()
{
-
+#if defined(__linux__) or defined(__FreeBSD__)
+ if (m_process->GetPluginName() == ProcessElfCore::GetPluginNameStatic())
+ return static_cast<ProcessElfCore *>(m_process)->GetAuxvData();
+#endif
return lldb_private::Host::GetAuxvData(m_process);
}
Modified: lldb/branches/lldb-platform-work/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp?rev=186540&r1=186539&r2=186540&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp Wed Jul 17 17:17:41 2013
@@ -20,6 +20,7 @@
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadPlanRunToAddress.h"
+#include "lldb/Breakpoint/BreakpointLocation.h"
#include "AuxVector.h"
#include "DynamicLoaderPOSIXDYLD.h"
@@ -93,12 +94,18 @@ DynamicLoaderPOSIXDYLD::DynamicLoaderPOS
m_rendezvous(process),
m_load_offset(LLDB_INVALID_ADDRESS),
m_entry_point(LLDB_INVALID_ADDRESS),
- m_auxv()
+ m_auxv(),
+ m_dyld_bid(LLDB_INVALID_BREAK_ID)
{
}
DynamicLoaderPOSIXDYLD::~DynamicLoaderPOSIXDYLD()
{
+ if (m_dyld_bid != LLDB_INVALID_BREAK_ID)
+ {
+ m_process->GetTarget().RemoveBreakpointByID (m_dyld_bid);
+ m_dyld_bid = LLDB_INVALID_BREAK_ID;
+ }
}
void
@@ -263,13 +270,19 @@ DynamicLoaderPOSIXDYLD::EntryBreakpointH
void
DynamicLoaderPOSIXDYLD::SetRendezvousBreakpoint()
{
- Breakpoint *dyld_break;
- addr_t break_addr;
+ addr_t break_addr = m_rendezvous.GetBreakAddress();
+ Target &target = m_process->GetTarget();
+
+ if (m_dyld_bid == LLDB_INVALID_BREAK_ID)
+ {
+ Breakpoint *dyld_break = target.CreateBreakpoint (break_addr, true).get();
+ dyld_break->SetCallback(RendezvousBreakpointHit, this, true);
+ dyld_break->SetBreakpointKind ("shared-library-event");
+ m_dyld_bid = dyld_break->GetID();
+ }
- break_addr = m_rendezvous.GetBreakAddress();
- dyld_break = m_process->GetTarget().CreateBreakpoint(break_addr, true).get();
- dyld_break->SetCallback(RendezvousBreakpointHit, this, true);
- dyld_break->SetBreakpointKind ("shared-library-event");
+ // Make sure our breakpoint is at the right address.
+ assert (target.GetBreakpointByID(m_dyld_bid)->FindLocationByAddress(break_addr)->GetBreakpoint().GetID() == m_dyld_bid);
}
bool
Modified: lldb/branches/lldb-platform-work/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h?rev=186540&r1=186539&r2=186540&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h Wed Jul 17 17:17:41 2013
@@ -92,6 +92,9 @@ protected:
/// Auxiliary vector of the inferior process.
std::unique_ptr<AuxVector> m_auxv;
+ /// Rendezvous breakpoint.
+ lldb::break_id_t m_dyld_bid;
+
/// Enables a breakpoint on a function called by the runtime
/// linker each time a module is loaded or unloaded.
void
Modified: lldb/branches/lldb-platform-work/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp?rev=186540&r1=186539&r2=186540&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp Wed Jul 17 17:17:41 2013
@@ -37,9 +37,9 @@ static const char *vtable_demangled_pref
bool
ItaniumABILanguageRuntime::CouldHaveDynamicValue (ValueObject &in_value)
{
- return ClangASTContext::IsPossibleDynamicType(in_value.GetClangAST(), in_value.GetClangType(), NULL,
- true, // check for C++
- false); // do not check for ObjC
+ const bool check_cxx = true;
+ const bool check_objc = false;
+ return in_value.GetClangType().IsPossibleDynamicType (NULL, check_cxx, check_objc);
}
bool
@@ -188,7 +188,7 @@ ItaniumABILanguageRuntime::GetDynamicTyp
type_sp = class_types.GetTypeAtIndex(i);
if (type_sp)
{
- if (ClangASTContext::IsCXXClassType(type_sp->GetClangFullType()))
+ if (type_sp->GetClangFullType().IsCXXClassType())
{
if (log)
log->Printf ("0x%16.16" PRIx64 ": static-type = '%s' has multiple matching dynamic types, picking this one: uid={0x%" PRIx64 "}, type-name='%s'\n",
@@ -220,18 +220,12 @@ ItaniumABILanguageRuntime::GetDynamicTyp
// the value we were handed.
if (type_sp)
{
- clang::ASTContext *in_ast_ctx = in_value.GetClangAST ();
- clang::ASTContext *this_ast_ctx = type_sp->GetClangAST ();
- if (in_ast_ctx == this_ast_ctx)
+ if (ClangASTContext::AreTypesSame (in_value.GetClangType(),
+ type_sp->GetClangFullType()))
{
- if (ClangASTContext::AreTypesSame (in_ast_ctx,
- in_value.GetClangType(),
- type_sp->GetClangFullType()))
- {
- // The dynamic type we found was the same type,
- // so we don't have a dynamic type here...
- return false;
- }
+ // The dynamic type we found was the same type,
+ // so we don't have a dynamic type here...
+ return false;
}
// The offset_to_top is two pointers above the address.
Modified: lldb/branches/lldb-platform-work/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp?rev=186540&r1=186539&r2=186540&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp Wed Jul 17 17:17:41 2013
@@ -81,10 +81,10 @@ AppleObjCRuntime::GetObjectDescription (
return false;
Target *target = exe_ctx.GetTargetPtr();
- if (value.GetClangType())
+ ClangASTType clang_type = value.GetClangType();
+ if (clang_type)
{
- clang::QualType value_type = clang::QualType::getFromOpaquePtr (value.GetClangType());
- if (!value_type->isObjCObjectPointerType())
+ if (!clang_type.IsObjCObjectPointerType())
{
strm.Printf ("Value doesn't point to an ObjC object.\n");
return false;
@@ -94,10 +94,11 @@ AppleObjCRuntime::GetObjectDescription (
{
// If it is not a pointer, see if we can make it into a pointer.
ClangASTContext *ast_context = target->GetScratchClangASTContext();
- void *opaque_type_ptr = ast_context->GetBuiltInType_objc_id();
- if (opaque_type_ptr == NULL)
- opaque_type_ptr = ast_context->GetVoidPtrType(false);
- value.SetContext(Value::eContextTypeClangType, opaque_type_ptr);
+ ClangASTType opaque_type = ast_context->GetBasicType(eBasicTypeObjCID);
+ if (!opaque_type)
+ opaque_type = ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
+ //value.SetContext(Value::eContextTypeClangType, opaque_type_ptr);
+ value.SetClangType (opaque_type);
}
ValueList arg_value_list;
@@ -106,9 +107,10 @@ AppleObjCRuntime::GetObjectDescription (
// This is the return value:
ClangASTContext *ast_context = target->GetScratchClangASTContext();
- void *return_qualtype = ast_context->GetCStringType(true);
+ ClangASTType return_clang_type = ast_context->GetCStringType(true);
Value ret;
- ret.SetContext(Value::eContextTypeClangType, return_qualtype);
+// ret.SetContext(Value::eContextTypeClangType, return_clang_type);
+ ret.SetClangType (return_clang_type);
if (exe_ctx.GetFramePtr() == NULL)
{
@@ -126,8 +128,7 @@ AppleObjCRuntime::GetObjectDescription (
// Now we're ready to call the function:
ClangFunction func (*exe_ctx.GetBestExecutionContextScope(),
- ast_context,
- return_qualtype,
+ return_clang_type,
*function_address,
arg_value_list);
@@ -221,10 +222,9 @@ AppleObjCRuntime::GetPrintForDebuggerAdd
bool
AppleObjCRuntime::CouldHaveDynamicValue (ValueObject &in_value)
{
- return ClangASTContext::IsPossibleDynamicType(in_value.GetClangAST(), in_value.GetClangType(),
- NULL,
- false, // do not check C++
- true); // check ObjC
+ return in_value.GetClangType().IsPossibleDynamicType (NULL,
+ false, // do not check C++
+ true); // check ObjC
}
bool
@@ -312,7 +312,7 @@ AppleObjCRuntime::GetObjCVersion (Proces
if (!ofile)
return eObjC_VersionUnknown;
- SectionList *sections = ofile->GetSectionList();
+ SectionList *sections = module_sp->GetSectionList();
if (!sections)
return eObjC_VersionUnknown;
SectionSP v1_telltale_section_sp = sections->FindSectionByName(ConstString ("__OBJC"));
Modified: lldb/branches/lldb-platform-work/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp?rev=186540&r1=186539&r2=186540&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp Wed Jul 17 17:17:41 2013
@@ -178,13 +178,14 @@ AppleObjCRuntimeV1::CreateObjectChecker(
//ObjCLanguageRuntime::ObjCISA
//AppleObjCRuntimeV1::GetISA(ValueObject& valobj)
//{
-//// if (ClangASTType::GetMinimumLanguage(valobj.GetClangAST(),valobj.GetClangType()) != eLanguageTypeObjC)
+// ClangASTType valobj_clang_type = valobj.GetClangType();
+//// if (valobj_clang_type.GetMinimumLanguage() != eLanguageTypeObjC)
//// return 0;
//
// // if we get an invalid VO (which might still happen when playing around
// // with pointers returned by the expression parser, don't consider this
// // a valid ObjC object)
-// if (valobj.GetValue().GetContextType() == Value::eContextTypeInvalid)
+// if (!valobj.GetClangType().IsValid())
// return 0;
//
// addr_t isa_pointer = valobj.GetPointerValue();
Modified: lldb/branches/lldb-platform-work/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp?rev=186540&r1=186539&r2=186540&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp Wed Jul 17 17:17:41 2013
@@ -1613,7 +1613,7 @@ AppleObjCRuntimeV2::GetClassDescriptor (
// if we get an invalid VO (which might still happen when playing around
// with pointers returned by the expression parser, don't consider this
// a valid ObjC object)
- if (valobj.GetValue().GetContextType() != Value::eContextTypeInvalid)
+ if (valobj.GetClangType().IsValid())
{
addr_t isa_pointer = valobj.GetPointerValue();
@@ -1719,8 +1719,8 @@ AppleObjCRuntimeV2::UpdateISAToDescripto
}
// Make some types for our arguments
- clang_type_t clang_uint32_t_type = ast->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 32);
- clang_type_t clang_void_pointer_type = ast->CreatePointerType(ast->GetBuiltInType_void());
+ ClangASTType clang_uint32_t_type = ast->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 32);
+ ClangASTType clang_void_pointer_type = ast->GetBasicType(eBasicTypeVoid).GetPointerType();
if (!m_get_class_info_code.get())
{
@@ -1749,19 +1749,17 @@ AppleObjCRuntimeV2::UpdateISAToDescripto
{
Value value;
value.SetValueType (Value::eValueTypeScalar);
- value.SetContext (Value::eContextTypeClangType, clang_void_pointer_type);
+// value.SetContext (Value::eContextTypeClangType, clang_void_pointer_type);
+ value.SetClangType (clang_void_pointer_type);
arguments.PushValue (value);
-
- value.SetValueType (Value::eValueTypeScalar);
- value.SetContext (Value::eContextTypeClangType, clang_void_pointer_type);
arguments.PushValue (value);
value.SetValueType (Value::eValueTypeScalar);
- value.SetContext (Value::eContextTypeClangType, clang_uint32_t_type);
+// value.SetContext (Value::eContextTypeClangType, clang_uint32_t_type);
+ value.SetClangType (clang_uint32_t_type);
arguments.PushValue (value);
m_get_class_info_function.reset(new ClangFunction (*m_process,
- ast,
clang_uint32_t_type,
function_address,
arguments));
@@ -1827,7 +1825,8 @@ AppleObjCRuntimeV2::UpdateISAToDescripto
Value return_value;
return_value.SetValueType (Value::eValueTypeScalar);
- return_value.SetContext (Value::eContextTypeClangType, clang_uint32_t_type);
+ //return_value.SetContext (Value::eContextTypeClangType, clang_uint32_t_type);
+ return_value.SetClangType (clang_uint32_t_type);
return_value.GetScalar() = 0;
errors.Clear();
@@ -1971,8 +1970,8 @@ AppleObjCRuntimeV2::UpdateISAToDescripto
}
// Make some types for our arguments
- clang_type_t clang_uint32_t_type = ast->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 32);
- clang_type_t clang_void_pointer_type = ast->CreatePointerType(ast->GetBuiltInType_void());
+ ClangASTType clang_uint32_t_type = ast->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 32);
+ ClangASTType clang_void_pointer_type = ast->GetBasicType(eBasicTypeVoid).GetPointerType();
if (!m_get_shared_cache_class_info_code.get())
{
@@ -2001,19 +2000,17 @@ AppleObjCRuntimeV2::UpdateISAToDescripto
{
Value value;
value.SetValueType (Value::eValueTypeScalar);
- value.SetContext (Value::eContextTypeClangType, clang_void_pointer_type);
+ //value.SetContext (Value::eContextTypeClangType, clang_void_pointer_type);
+ value.SetClangType (clang_void_pointer_type);
arguments.PushValue (value);
-
- value.SetValueType (Value::eValueTypeScalar);
- value.SetContext (Value::eContextTypeClangType, clang_void_pointer_type);
arguments.PushValue (value);
value.SetValueType (Value::eValueTypeScalar);
- value.SetContext (Value::eContextTypeClangType, clang_uint32_t_type);
+ //value.SetContext (Value::eContextTypeClangType, clang_uint32_t_type);
+ value.SetClangType (clang_uint32_t_type);
arguments.PushValue (value);
m_get_shared_cache_class_info_function.reset(new ClangFunction (*m_process,
- ast,
clang_uint32_t_type,
function_address,
arguments));
@@ -2079,7 +2076,8 @@ AppleObjCRuntimeV2::UpdateISAToDescripto
Value return_value;
return_value.SetValueType (Value::eValueTypeScalar);
- return_value.SetContext (Value::eContextTypeClangType, clang_uint32_t_type);
+ //return_value.SetContext (Value::eContextTypeClangType, clang_uint32_t_type);
+ return_value.SetClangType (clang_uint32_t_type);
return_value.GetScalar() = 0;
errors.Clear();
@@ -2189,7 +2187,7 @@ AppleObjCRuntimeV2::GetSharedCacheReadOn
if (objc_object)
{
- SectionList *section_list = objc_object->GetSectionList();
+ SectionList *section_list = objc_module_sp->GetSectionList();
if (section_list)
{
Modified: lldb/branches/lldb-platform-work/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp?rev=186540&r1=186539&r2=186540&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp Wed Jul 17 17:17:41 2013
@@ -512,9 +512,11 @@ AppleObjCTrampolineHandler::AppleObjCVTa
ClangASTContext *clang_ast_context = process->GetTarget().GetScratchClangASTContext();
ValueList argument_values;
Value input_value;
- void *clang_void_ptr_type = clang_ast_context->GetVoidPtrType(false);
+ ClangASTType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
+
input_value.SetValueType (Value::eValueTypeScalar);
- input_value.SetContext (Value::eContextTypeClangType, clang_void_ptr_type);
+ //input_value.SetContext (Value::eContextTypeClangType, clang_void_ptr_type);
+ input_value.SetClangType (clang_void_ptr_type);
argument_values.PushValue(input_value);
bool success = abi->GetArgumentValues (exe_ctx.GetThreadRef(), argument_values);
@@ -525,7 +527,6 @@ AppleObjCTrampolineHandler::AppleObjCVTa
Error error;
DataExtractor data;
error = argument_values.GetValueAtIndex(0)->GetValueAsData (&exe_ctx,
- clang_ast_context->getASTContext(),
data,
0,
NULL);
@@ -783,13 +784,12 @@ AppleObjCTrampolineHandler::SetupDispatc
// Next make the runner function for our implementation utility function.
if (!m_impl_function.get())
{
- ClangASTContext *clang_ast_context = thread.GetProcess()->GetTarget().GetScratchClangASTContext();
- lldb::clang_type_t clang_void_ptr_type = clang_ast_context->GetVoidPtrType(false);
- m_impl_function.reset(new ClangFunction (thread,
- clang_ast_context,
- clang_void_ptr_type,
- impl_code_address,
- dispatch_values));
+ ClangASTContext *clang_ast_context = thread.GetProcess()->GetTarget().GetScratchClangASTContext();
+ ClangASTType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
+ m_impl_function.reset(new ClangFunction (thread,
+ clang_void_ptr_type,
+ impl_code_address,
+ dispatch_values));
errors.Clear();
unsigned num_errors = m_impl_function->CompileFunction(errors);
@@ -887,9 +887,10 @@ AppleObjCTrampolineHandler::GetStepThrou
ClangASTContext *clang_ast_context = target_sp->GetScratchClangASTContext();
ValueList argument_values;
Value void_ptr_value;
- lldb::clang_type_t clang_void_ptr_type = clang_ast_context->GetVoidPtrType(false);
+ ClangASTType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
void_ptr_value.SetValueType (Value::eValueTypeScalar);
- void_ptr_value.SetContext (Value::eContextTypeClangType, clang_void_ptr_type);
+ //void_ptr_value.SetContext (Value::eContextTypeClangType, clang_void_ptr_type);
+ void_ptr_value.SetClangType (clang_void_ptr_type);
int obj_index;
int sel_index;
@@ -949,14 +950,14 @@ AppleObjCTrampolineHandler::GetStepThrou
Value super_value(*(argument_values.GetValueAtIndex(obj_index)));
super_value.GetScalar() += process->GetAddressByteSize();
- super_value.ResolveValue (&exe_ctx, clang_ast_context->getASTContext());
+ super_value.ResolveValue (&exe_ctx);
if (super_value.GetScalar().IsValid())
{
// isa_value now holds the class pointer. The second word of the class pointer is the super-class pointer:
super_value.GetScalar() += process->GetAddressByteSize();
- super_value.ResolveValue (&exe_ctx, clang_ast_context->getASTContext());
+ super_value.ResolveValue (&exe_ctx);
if (super_value.GetScalar().IsValid())
isa_addr = super_value.GetScalar().ULongLong();
else
@@ -979,7 +980,7 @@ AppleObjCTrampolineHandler::GetStepThrou
Value super_value(*(argument_values.GetValueAtIndex(obj_index)));
super_value.GetScalar() += process->GetAddressByteSize();
- super_value.ResolveValue (&exe_ctx, clang_ast_context->getASTContext());
+ super_value.ResolveValue (&exe_ctx);
if (super_value.GetScalar().IsValid())
{
@@ -1006,7 +1007,7 @@ AppleObjCTrampolineHandler::GetStepThrou
Value isa_value(*(argument_values.GetValueAtIndex(obj_index)));
isa_value.SetValueType(Value::eValueTypeLoadAddress);
- isa_value.ResolveValue(&exe_ctx, clang_ast_context->getASTContext());
+ isa_value.ResolveValue(&exe_ctx);
if (isa_value.GetScalar().IsValid())
{
isa_addr = isa_value.GetScalar().ULongLong();
@@ -1068,10 +1069,10 @@ AppleObjCTrampolineHandler::GetStepThrou
dispatch_values.PushValue (*(argument_values.GetValueAtIndex(sel_index)));
Value flag_value;
- lldb::clang_type_t clang_int_type
- = clang_ast_context->GetBuiltinTypeForEncodingAndBitSize(lldb::eEncodingSint, 32);
+ ClangASTType clang_int_type = clang_ast_context->GetBuiltinTypeForEncodingAndBitSize(lldb::eEncodingSint, 32);
flag_value.SetValueType (Value::eValueTypeScalar);
- flag_value.SetContext (Value::eContextTypeClangType, clang_int_type);
+ //flag_value.SetContext (Value::eContextTypeClangType, clang_int_type);
+ flag_value.SetClangType (clang_int_type);
if (this_dispatch.stret_return)
flag_value.GetScalar() = 1;
Modified: lldb/branches/lldb-platform-work/source/Plugins/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/Makefile?rev=186540&r1=186539&r2=186540&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/Makefile (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/Makefile Wed Jul 17 17:17:41 2013
@@ -35,11 +35,13 @@ ifeq ($(HOST_OS),Linux)
DIRS += DynamicLoader/MacOSX-DYLD
DIRS += Process/Linux Process/POSIX
DIRS += SymbolVendor/ELF
+DIRS += Process/elf-core
endif
ifneq (,$(filter $(HOST_OS), FreeBSD GNU/kFreeBSD))
DIRS += Process/FreeBSD Process/POSIX
DIRS += SymbolVendor/ELF
+DIRS += Process/elf-core
endif
include $(LLDB_LEVEL)/Makefile
Modified: lldb/branches/lldb-platform-work/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp?rev=186540&r1=186539&r2=186540&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp Wed Jul 17 17:17:41 2013
@@ -11,10 +11,12 @@
#include <ar.h>
-#include "lldb/Core/Stream.h"
#include "lldb/Core/ArchSpec.h"
+#include "lldb/Core/DataBuffer.h"
#include "lldb/Core/Module.h"
+#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/Stream.h"
#include "lldb/Core/Timer.h"
#include "lldb/Host/Mutex.h"
#include "lldb/Symbol/ObjectFile.h"
@@ -105,10 +107,12 @@ ObjectContainerBSDArchive::Archive::Arch
(
const lldb_private::ArchSpec &arch,
const lldb_private::TimeValue &time,
+ lldb::offset_t file_offset,
lldb_private::DataExtractor &data
) :
m_arch (arch),
m_time (time),
+ m_file_offset (file_offset),
m_objects(),
m_data (data)
{
@@ -176,7 +180,7 @@ ObjectContainerBSDArchive::Archive::Find
ObjectContainerBSDArchive::Archive::shared_ptr
-ObjectContainerBSDArchive::Archive::FindCachedArchive (const FileSpec &file, const ArchSpec &arch, const TimeValue &time)
+ObjectContainerBSDArchive::Archive::FindCachedArchive (const FileSpec &file, const ArchSpec &arch, const TimeValue &time, lldb::offset_t file_offset)
{
Mutex::Locker locker(Archive::GetArchiveCacheMutex ());
shared_ptr archive_sp;
@@ -186,7 +190,12 @@ ObjectContainerBSDArchive::Archive::Find
// delete an archive entry...
while (pos != archive_map.end() && pos->first == file)
{
- if (pos->second->GetArchitecture().IsCompatibleMatch(arch))
+ bool match = true;
+ if (arch.IsValid() && pos->second->GetArchitecture().IsCompatibleMatch(arch) == false)
+ match = false;
+ else if (file_offset != LLDB_INVALID_OFFSET && pos->second->GetFileOffset() != file_offset)
+ match = false;
+ if (match)
{
if (pos->second->GetModificationTime() == time)
{
@@ -204,7 +213,7 @@ ObjectContainerBSDArchive::Archive::Find
// remove the old and outdated entry.
archive_map.erase (pos);
pos = archive_map.find (file);
- continue;
+ continue; // Continue to next iteration so we don't increment pos below...
}
}
++pos;
@@ -218,13 +227,15 @@ ObjectContainerBSDArchive::Archive::Pars
const FileSpec &file,
const ArchSpec &arch,
const TimeValue &time,
+ lldb::offset_t file_offset,
DataExtractor &data
)
{
- shared_ptr archive_sp(new Archive (arch, time, data));
+ shared_ptr archive_sp(new Archive (arch, time, file_offset, data));
if (archive_sp)
{
- if (archive_sp->ParseObjects () > 0)
+ const size_t num_objects = archive_sp->ParseObjects ();
+ if (num_objects > 0)
{
Mutex::Locker locker(Archive::GetArchiveCacheMutex ());
Archive::GetArchiveCache().insert(std::make_pair(file, archive_sp));
@@ -314,7 +325,10 @@ ObjectContainerBSDArchive::CreateInstanc
DataBufferSP archive_data_sp (file->MemoryMapFileContents(file_offset, length));
lldb::offset_t archive_data_offset = 0;
- Archive::shared_ptr archive_sp (Archive::FindCachedArchive (*file, module_sp->GetArchitecture(), module_sp->GetModificationTime()));
+ Archive::shared_ptr archive_sp (Archive::FindCachedArchive (*file,
+ module_sp->GetArchitecture(),
+ module_sp->GetModificationTime(),
+ file_offset));
std::unique_ptr<ObjectContainerBSDArchive> container_ap(new ObjectContainerBSDArchive (module_sp,
archive_data_sp,
archive_data_offset,
@@ -338,7 +352,10 @@ ObjectContainerBSDArchive::CreateInstanc
else
{
// No data, just check for a cached archive
- Archive::shared_ptr archive_sp (Archive::FindCachedArchive (*file, module_sp->GetArchitecture(), module_sp->GetModificationTime()));
+ Archive::shared_ptr archive_sp (Archive::FindCachedArchive (*file,
+ module_sp->GetArchitecture(),
+ module_sp->GetModificationTime(),
+ file_offset));
if (archive_sp)
{
std::unique_ptr<ObjectContainerBSDArchive> container_ap(new ObjectContainerBSDArchive (module_sp, data_sp, data_offset, file, file_offset, length));
@@ -409,6 +426,7 @@ ObjectContainerBSDArchive::ParseHeader (
m_archive_sp = Archive::ParseAndCacheArchiveForFile (m_file,
module_sp->GetArchitecture(),
module_sp->GetModificationTime(),
+ m_offset,
m_data);
}
// Clear the m_data that contains the entire archive
@@ -492,8 +510,76 @@ ObjectContainerBSDArchive::GetModuleSpec
lldb::DataBufferSP& data_sp,
lldb::offset_t data_offset,
lldb::offset_t file_offset,
- lldb::offset_t length,
+ lldb::offset_t file_size,
lldb_private::ModuleSpecList &specs)
{
+
+ // We have data, which means this is the first 512 bytes of the file
+ // Check to see if the magic bytes match and if they do, read the entire
+ // table of contents for the archive and cache it
+ DataExtractor data;
+ data.SetData (data_sp, data_offset, data_sp->GetByteSize());
+ if (file && data_sp && ObjectContainerBSDArchive::MagicBytesMatch(data))
+ {
+ const size_t initial_count = specs.GetSize();
+ TimeValue file_mod_time = file.GetModificationTime();
+ Archive::shared_ptr archive_sp (Archive::FindCachedArchive (file, ArchSpec(), file_mod_time, file_offset));
+ bool set_archive_arch = false;
+ if (!archive_sp)
+ {
+ set_archive_arch = true;
+ DataBufferSP data_sp (file.MemoryMapFileContents(file_offset, file_size));
+ data.SetData (data_sp, 0, data_sp->GetByteSize());
+ archive_sp = Archive::ParseAndCacheArchiveForFile(file, ArchSpec(), file_mod_time, file_offset, data);
+ }
+
+ if (archive_sp)
+ {
+ const size_t num_objects = archive_sp->GetNumObjects();
+ for (size_t idx = 0; idx < num_objects; ++idx)
+ {
+ const Object *object = archive_sp->GetObjectAtIndex (idx);
+ if (object)
+ {
+ const lldb::offset_t object_file_offset = file_offset + object->ar_file_offset;
+ if (object->ar_file_offset < file_size && file_size > object_file_offset)
+ {
+ if (ObjectFile::GetModuleSpecifications(file,
+ object_file_offset,
+ file_size - object_file_offset,
+ specs))
+ {
+ ModuleSpec &spec = specs.GetModuleSpecRefAtIndex (specs.GetSize() - 1);
+ TimeValue object_mod_time;
+ object_mod_time.OffsetWithSeconds(object->ar_date);
+ spec.GetObjectName () = object->ar_name;
+ spec.SetObjectOffset(object_file_offset);
+ spec.GetObjectModificationTime () = object_mod_time;
+ }
+ }
+ }
+ }
+ }
+ const size_t end_count = specs.GetSize();
+ size_t num_specs_added = end_count - initial_count;
+ if (set_archive_arch && num_specs_added > 0)
+ {
+ // The archive was created but we didn't have an architecture
+ // so we need to set it
+ for (size_t i=initial_count; i<end_count; ++ i)
+ {
+ ModuleSpec module_spec;
+ if (specs.GetModuleSpecAtIndex(i, module_spec))
+ {
+ if (module_spec.GetArchitecture().IsValid())
+ {
+ archive_sp->SetArchitecture (module_spec.GetArchitecture());
+ break;
+ }
+ }
+ }
+ }
+ return num_specs_added;
+ }
return 0;
}
Modified: lldb/branches/lldb-platform-work/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h?rev=186540&r1=186539&r2=186540&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h Wed Jul 17 17:17:41 2013
@@ -136,16 +136,19 @@ protected:
static Archive::shared_ptr
FindCachedArchive (const lldb_private::FileSpec &file,
const lldb_private::ArchSpec &arch,
- const lldb_private::TimeValue &mod_time);
+ const lldb_private::TimeValue &mod_time,
+ lldb::offset_t file_offset);
static Archive::shared_ptr
ParseAndCacheArchiveForFile (const lldb_private::FileSpec &file,
const lldb_private::ArchSpec &arch,
const lldb_private::TimeValue &mod_time,
+ lldb::offset_t file_offset,
lldb_private::DataExtractor &data);
Archive (const lldb_private::ArchSpec &arch,
const lldb_private::TimeValue &mod_time,
+ lldb::offset_t file_offset,
lldb_private::DataExtractor &data);
~Archive ();
@@ -156,6 +159,14 @@ protected:
return m_objects.size();
}
+ const Object *
+ GetObjectAtIndex (size_t idx)
+ {
+ if (idx < m_objects.size())
+ return &m_objects[idx];
+ return NULL;
+ }
+
size_t
ParseObjects ();
@@ -163,6 +174,12 @@ protected:
FindObject (const lldb_private::ConstString &object_name,
const lldb_private::TimeValue &object_mod_time);
+ lldb::offset_t
+ GetFileOffset () const
+ {
+ return m_file_offset;
+ }
+
const lldb_private::TimeValue &
GetModificationTime()
{
@@ -170,11 +187,17 @@ protected:
}
const lldb_private::ArchSpec &
- GetArchitecture ()
+ GetArchitecture () const
{
return m_arch;
}
-
+
+ void
+ SetArchitecture (const lldb_private::ArchSpec &arch)
+ {
+ m_arch = arch;
+ }
+
bool
HasNoExternalReferences() const;
@@ -191,6 +214,7 @@ protected:
//----------------------------------------------------------------------
lldb_private::ArchSpec m_arch;
lldb_private::TimeValue m_time;
+ lldb::offset_t m_file_offset;
Object::collection m_objects;
ObjectNameToIndexMap m_object_name_to_index_map;
lldb_private::DataExtractor m_data; ///< The data for this object container so we don't lose data if the .a files gets modified
Modified: lldb/branches/lldb-platform-work/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.cpp?rev=186540&r1=186539&r2=186540&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.cpp Wed Jul 17 17:17:41 2013
@@ -278,13 +278,13 @@ ObjectContainerUniversalMachO::GetModule
lldb::DataBufferSP& data_sp,
lldb::offset_t data_offset,
lldb::offset_t file_offset,
- lldb::offset_t length,
+ lldb::offset_t file_size,
lldb_private::ModuleSpecList &specs)
{
const size_t initial_count = specs.GetSize();
DataExtractor data;
- data.SetData (data_sp, data_offset, length);
+ data.SetData (data_sp, data_offset, data_sp->GetByteSize());
if (ObjectContainerUniversalMachO::MagicBytesMatch(data))
{
@@ -294,9 +294,14 @@ ObjectContainerUniversalMachO::GetModule
{
for (const llvm::MachO::fat_arch &fat_arch : fat_archs)
{
- ObjectFile::GetModuleSpecifications (file,
- fat_arch.offset + file_offset,
- specs);
+ const lldb::offset_t slice_file_offset = fat_arch.offset + file_offset;
+ if (fat_arch.offset < file_size && file_size > slice_file_offset)
+ {
+ ObjectFile::GetModuleSpecifications (file,
+ slice_file_offset,
+ file_size - slice_file_offset,
+ specs);
+ }
}
}
}
Modified: lldb/branches/lldb-platform-work/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp?rev=186540&r1=186539&r2=186540&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp Wed Jul 17 17:17:41 2013
@@ -235,6 +235,70 @@ ObjectFileELF::MagicBytesMatch (DataBuff
return false;
}
+/*
+ * crc function from http://svnweb.freebsd.org/base/head/sys/libkern/crc32.c
+ *
+ * COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or
+ * code or tables extracted from it, as desired without restriction.
+ */
+static uint32_t
+calc_gnu_debuglink_crc32(const void *buf, size_t size)
+{
+ static const uint32_t g_crc32_tab[] =
+ {
+ 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
+ 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
+ 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
+ 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
+ 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
+ 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
+ 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
+ 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
+ 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
+ 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
+ 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
+ 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
+ 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
+ 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
+ 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
+ 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
+ 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
+ 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
+ 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
+ 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+ 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
+ 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
+ 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
+ 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
+ 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
+ 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
+ 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
+ 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
+ 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
+ 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
+ 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
+ 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
+ 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
+ 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
+ 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
+ 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
+ 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
+ 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
+ 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
+ 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+ 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
+ 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
+ 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
+ };
+ const uint8_t *p = (const uint8_t *)buf;
+ uint32_t crc;
+
+ crc = ~0U;
+ while (size--)
+ crc = g_crc32_tab[(crc ^ *p++) & 0xFF] ^ (crc >> 8);
+ return crc ^ ~0U;
+}
+
size_t
ObjectFileELF::GetModuleSpecifications (const lldb_private::FileSpec& file,
lldb::DataBufferSP& data_sp,
@@ -278,10 +342,28 @@ ObjectFileELF::GetModuleSpecifications (
data.SetData(data_sp);
}
- uint32_t gnu_debuglink_crc;
+ uint32_t gnu_debuglink_crc = 0;
std::string gnu_debuglink_file;
SectionHeaderColl section_headers;
- GetSectionHeaderInfo(section_headers, data, header, spec.GetUUID(), gnu_debuglink_file, gnu_debuglink_crc);
+ lldb_private::UUID &uuid = spec.GetUUID();
+ GetSectionHeaderInfo(section_headers, data, header, uuid, gnu_debuglink_file, gnu_debuglink_crc);
+
+ if (!uuid.IsValid())
+ {
+ if (!gnu_debuglink_crc)
+ {
+ // Need to map entire file into memory to calculate the crc.
+ data_sp = file.MemoryMapFileContents (file_offset, SIZE_MAX);
+ data.SetData(data_sp);
+ gnu_debuglink_crc = calc_gnu_debuglink_crc32 (data.GetDataStart(), data.GetByteSize());
+ }
+ if (gnu_debuglink_crc)
+ {
+ // Use 4 bytes of crc from the .gnu_debuglink section.
+ uint32_t uuidt[4] = { gnu_debuglink_crc, 0, 0, 0 };
+ uuid.SetBytes (uuidt, sizeof(uuidt));
+ }
+ }
specs.Append(spec);
}
@@ -374,70 +456,6 @@ ObjectFileELF::ParseHeader()
return m_header.Parse(m_data, &offset);
}
-/*
- * crc function from http://svnweb.freebsd.org/base/head/sys/libkern/crc32.c
- *
- * COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or
- * code or tables extracted from it, as desired without restriction.
- */
-static uint32_t
-calc_gnu_debuglink_crc32(const void *buf, size_t size)
-{
- static const uint32_t g_crc32_tab[] =
- {
- 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
- 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
- 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
- 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
- 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
- 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
- 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
- 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
- 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
- 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
- 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
- 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
- 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
- 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
- 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
- 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
- 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
- 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
- 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
- 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
- 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
- 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
- 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
- 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
- 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
- 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
- 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
- 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
- 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
- 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
- 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
- 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
- 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
- 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
- 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
- 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
- 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
- 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
- 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
- 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
- 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
- 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
- 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
- };
- const uint8_t *p = (const uint8_t *)buf;
- uint32_t crc;
-
- crc = ~0U;
- while (size--)
- crc = g_crc32_tab[(crc ^ *p++) & 0xFF] ^ (crc >> 8);
- return crc ^ ~0U;
-}
-
bool
ObjectFileELF::GetUUID(lldb_private::UUID* uuid)
{
@@ -453,7 +471,8 @@ ObjectFileELF::GetUUID(lldb_private::UUI
}
else
{
- m_gnu_debuglink_crc = calc_gnu_debuglink_crc32 (m_data.GetDataStart(), m_data.GetByteSize());
+ if (!m_gnu_debuglink_crc)
+ m_gnu_debuglink_crc = calc_gnu_debuglink_crc32 (m_data.GetDataStart(), m_data.GetByteSize());
if (m_gnu_debuglink_crc)
{
// Use 4 bytes of crc from the .gnu_debuglink section.
@@ -494,22 +513,6 @@ ObjectFileELF::GetDependentModules(FileS
return num_specs;
}
-user_id_t
-ObjectFileELF::GetSectionIndexByType(unsigned type)
-{
- if (!ParseSectionHeaders())
- return 0;
-
- for (SectionHeaderCollIter sh_pos = m_section_headers.begin();
- sh_pos != m_section_headers.end(); ++sh_pos)
- {
- if (sh_pos->sh_type == type)
- return SectionIndex(sh_pos);
- }
-
- return 0;
-}
-
Address
ObjectFileELF::GetImageInfoAddress()
{
@@ -520,28 +523,27 @@ ObjectFileELF::GetImageInfoAddress()
if (!section_list)
return Address();
- user_id_t dynsym_id = GetSectionIndexByType(SHT_DYNAMIC);
- if (!dynsym_id)
+ // Find the SHT_DYNAMIC (.dynamic) section.
+ SectionSP dynsym_section_sp (section_list->FindSectionByType (eSectionTypeELFDynamicLinkInfo, true));
+ if (!dynsym_section_sp)
return Address();
+ assert (dynsym_section_sp->GetObjectFile() == this);
+ user_id_t dynsym_id = dynsym_section_sp->GetID();
const ELFSectionHeaderInfo *dynsym_hdr = GetSectionHeaderByIndex(dynsym_id);
if (!dynsym_hdr)
return Address();
- SectionSP dynsym_section_sp (section_list->FindSectionByID(dynsym_id));
- if (dynsym_section_sp)
+ for (size_t i = 0; i < m_dynamic_symbols.size(); ++i)
{
- for (size_t i = 0; i < m_dynamic_symbols.size(); ++i)
- {
- ELFDynamic &symbol = m_dynamic_symbols[i];
+ ELFDynamic &symbol = m_dynamic_symbols[i];
- if (symbol.d_tag == DT_DEBUG)
- {
- // Compute the offset as the number of previous entries plus the
- // size of d_tag.
- addr_t offset = i * dynsym_hdr->sh_entsize + GetAddressByteSize();
- return Address(dynsym_section_sp, offset);
- }
+ if (symbol.d_tag == DT_DEBUG)
+ {
+ // Compute the offset as the number of previous entries plus the
+ // size of d_tag.
+ addr_t offset = i * dynsym_hdr->sh_entsize + GetAddressByteSize();
+ return Address(dynsym_section_sp, offset);
}
}
@@ -551,26 +553,19 @@ ObjectFileELF::GetImageInfoAddress()
lldb_private::Address
ObjectFileELF::GetEntryPointAddress ()
{
- SectionList *sections;
- addr_t offset;
-
if (m_entry_point_address.IsValid())
return m_entry_point_address;
if (!ParseHeader() || !IsExecutable())
return m_entry_point_address;
- sections = GetSectionList();
- offset = m_header.e_entry;
+ SectionList *section_list = GetSectionList();
+ addr_t offset = m_header.e_entry;
- if (!sections)
- {
+ if (!section_list)
m_entry_point_address.SetOffset(offset);
- return m_entry_point_address;
- }
-
- m_entry_point_address.ResolveAddressUsingFileSections(offset, sections);
-
+ else
+ m_entry_point_address.ResolveAddressUsingFileSections(offset, section_list);
return m_entry_point_address;
}
@@ -588,32 +583,22 @@ ObjectFileELF::ParseDependentModules()
if (!ParseSectionHeaders())
return 0;
- // Locate the dynamic table.
- user_id_t dynsym_id = 0;
- user_id_t dynstr_id = 0;
- for (SectionHeaderCollIter sh_pos = m_section_headers.begin();
- sh_pos != m_section_headers.end(); ++sh_pos)
- {
- if (sh_pos->sh_type == SHT_DYNAMIC)
- {
- dynsym_id = SectionIndex(sh_pos);
- dynstr_id = sh_pos->sh_link + 1; // Section ID's are 1 based.
- break;
- }
- }
-
- if (!(dynsym_id && dynstr_id))
- return 0;
-
SectionList *section_list = GetSectionList();
if (!section_list)
return 0;
- // Resolve and load the dynamic table entries and corresponding string
- // table.
- Section *dynsym = section_list->FindSectionByID(dynsym_id).get();
- Section *dynstr = section_list->FindSectionByID(dynstr_id).get();
- if (!(dynsym && dynstr))
+ // Find the SHT_DYNAMIC section.
+ Section *dynsym = section_list->FindSectionByType (eSectionTypeELFDynamicLinkInfo, true).get();
+ if (!dynsym)
+ return 0;
+ assert (dynsym->GetObjectFile() == this);
+
+ const ELFSectionHeaderInfo *header = GetSectionHeaderByIndex (dynsym->GetID());
+ if (!header)
+ return 0;
+ // sh_link: section header index of string table used by entries in the section.
+ Section *dynstr = section_list->FindSectionByID (header->sh_link + 1).get();
+ if (!dynstr)
return 0;
DataExtractor dynsym_data;
@@ -816,43 +801,46 @@ ObjectFileELF::GetSectionHeaderInfo(Sect
return 0;
}
-//----------------------------------------------------------------------
-// ParseSectionHeaders
-//----------------------------------------------------------------------
size_t
-ObjectFileELF::ParseSectionHeaders()
+ObjectFileELF::GetProgramHeaderCount()
{
- return GetSectionHeaderInfo(m_section_headers, m_data, m_header, m_uuid, m_gnu_debuglink_file, m_gnu_debuglink_crc);
+ return ParseProgramHeaders();
}
-lldb::user_id_t
-ObjectFileELF::GetSectionIndexByName(const char *name)
+const elf::ELFProgramHeader *
+ObjectFileELF::GetProgramHeaderByIndex(lldb::user_id_t id)
{
- if (!ParseSectionHeaders())
- return 0;
-
- // Search the collection of section headers for one with a matching name.
- for (SectionHeaderCollIter I = m_section_headers.begin();
- I != m_section_headers.end(); ++I)
- {
- const char *sectionName = I->section_name.AsCString();
+ if (!id || !ParseProgramHeaders())
+ return NULL;
- if (!sectionName)
- return 0;
+ if (--id < m_program_headers.size())
+ return &m_program_headers[id];
- if (strcmp(name, sectionName) != 0)
- continue;
+ return NULL;
+}
- return SectionIndex(I);
- }
+DataExtractor
+ObjectFileELF::GetSegmentDataByIndex(lldb::user_id_t id)
+{
+ const elf::ELFProgramHeader *segment_header = GetProgramHeaderByIndex(id);
+ if (segment_header == NULL)
+ return DataExtractor();
+ return DataExtractor(m_data, segment_header->p_offset, segment_header->p_filesz);
+}
- return 0;
+//----------------------------------------------------------------------
+// ParseSectionHeaders
+//----------------------------------------------------------------------
+size_t
+ObjectFileELF::ParseSectionHeaders()
+{
+ return GetSectionHeaderInfo(m_section_headers, m_data, m_header, m_uuid, m_gnu_debuglink_file, m_gnu_debuglink_crc);
}
const ObjectFileELF::ELFSectionHeaderInfo *
ObjectFileELF::GetSectionHeaderByIndex(lldb::user_id_t id)
{
- if (!ParseSectionHeaders() || !id)
+ if (!id || !ParseSectionHeaders())
return NULL;
if (--id < m_section_headers.size())
@@ -861,14 +849,10 @@ ObjectFileELF::GetSectionHeaderByIndex(l
return NULL;
}
-
-SectionList *
-ObjectFileELF::GetSectionList()
+void
+ObjectFileELF::CreateSections(SectionList &unified_section_list)
{
- if (m_sections_ap.get())
- return m_sections_ap.get();
-
- if (ParseSectionHeaders())
+ if (!m_sections_ap.get() && ParseSectionHeaders())
{
m_sections_ap.reset(new SectionList());
@@ -927,7 +911,8 @@ ObjectFileELF::GetSectionList()
// .debug_pubtypes â Lookup table for mapping type names to compilation units
// .debug_ranges â Address ranges used in DW_AT_ranges attributes
// .debug_str â String table used in .debug_info
- // MISSING? .debug-index http://src.chromium.org/viewvc/chrome/trunk/src/build/gdb-add-index?pathrev=144644
+ // MISSING? .gnu_debugdata - "mini debuginfo / MiniDebugInfo" section, http://sourceware.org/gdb/onlinedocs/gdb/MiniDebugInfo.html
+ // MISSING? .debug-index - http://src.chromium.org/viewvc/chrome/trunk/src/build/gdb-add-index?pathrev=144644
// MISSING? .debug_types - Type descriptions from DWARF 4? See http://gcc.gnu.org/wiki/DwarfSeparateTypeInfo
else if (name == g_sect_name_dwarf_debug_abbrev) sect_type = eSectionTypeDWARFDebugAbbrev;
else if (name == g_sect_name_dwarf_debug_aranges) sect_type = eSectionTypeDWARFDebugAranges;
@@ -963,40 +948,75 @@ ObjectFileELF::GetSectionList()
break;
}
- SectionSP section_sp(new Section(
- GetModule(), // Module to which this section belongs.
- this, // ObjectFile to which this section belongs and should read section data from.
- SectionIndex(I), // Section ID.
- name, // Section name.
- sect_type, // Section type.
- header.sh_addr, // VM address.
- vm_size, // VM size in bytes of this section.
- header.sh_offset, // Offset of this section in the file.
- file_size, // Size of the section as found in the file.
- header.sh_flags)); // Flags for this section.
+ SectionSP section_sp (new Section(GetModule(), // Module to which this section belongs.
+ this, // ObjectFile to which this section belongs and should read section data from.
+ SectionIndex(I), // Section ID.
+ name, // Section name.
+ sect_type, // Section type.
+ header.sh_addr, // VM address.
+ vm_size, // VM size in bytes of this section.
+ header.sh_offset, // Offset of this section in the file.
+ file_size, // Size of the section as found in the file.
+ header.sh_flags)); // Flags for this section.
if (is_thread_specific)
section_sp->SetIsThreadSpecific (is_thread_specific);
m_sections_ap->AddSection(section_sp);
}
-
- m_sections_ap->Finalize(); // Now that we're done adding sections, finalize to build fast-lookup caches
}
- return m_sections_ap.get();
+ if (m_sections_ap.get())
+ {
+ if (GetType() == eTypeDebugInfo)
+ {
+ static const SectionType g_sections[] =
+ {
+ eSectionTypeDWARFDebugAranges,
+ eSectionTypeDWARFDebugInfo,
+ eSectionTypeDWARFDebugAbbrev,
+ eSectionTypeDWARFDebugFrame,
+ eSectionTypeDWARFDebugLine,
+ eSectionTypeDWARFDebugStr,
+ eSectionTypeDWARFDebugLoc,
+ eSectionTypeDWARFDebugMacInfo,
+ eSectionTypeDWARFDebugPubNames,
+ eSectionTypeDWARFDebugPubTypes,
+ eSectionTypeDWARFDebugRanges,
+ eSectionTypeELFSymbolTable,
+ };
+ SectionList *elf_section_list = m_sections_ap.get();
+ for (size_t idx = 0; idx < sizeof(g_sections) / sizeof(g_sections[0]); ++idx)
+ {
+ SectionType section_type = g_sections[idx];
+ SectionSP section_sp (elf_section_list->FindSectionByType (section_type, true));
+ if (section_sp)
+ {
+ SectionSP module_section_sp (unified_section_list.FindSectionByType (section_type, true));
+ if (module_section_sp)
+ unified_section_list.ReplaceSection (module_section_sp->GetID(), section_sp);
+ else
+ unified_section_list.AddSection (section_sp);
+ }
+ }
+ }
+ else
+ {
+ unified_section_list = *m_sections_ap;
+ }
+ }
}
+// private
unsigned
-ObjectFileELF::ParseSymbols(Symtab *symtab,
- user_id_t start_id,
- SectionList *section_list,
- const ELFSectionHeaderInfo *symtab_shdr,
- const DataExtractor &symtab_data,
- const DataExtractor &strtab_data)
+ObjectFileELF::ParseSymbols (Symtab *symtab,
+ user_id_t start_id,
+ SectionList *section_list,
+ const size_t num_symbols,
+ const DataExtractor &symtab_data,
+ const DataExtractor &strtab_data)
{
ELFSymbol symbol;
lldb::offset_t offset = 0;
- const size_t num_symbols = symtab_data.GetByteSize() / symtab_shdr->sh_entsize;
static ConstString text_section_name(".text");
static ConstString init_section_name(".init");
@@ -1109,21 +1129,18 @@ ObjectFileELF::ParseSymbols(Symtab *symt
}
}
- // If the symbol section we've found has no data (SHT_NOBITS), then check the module
- // for the main object file and use the section there if it has data. This can happen
- // if we're parsing the debug file and the it has no .text section, for example.
+ // If the symbol section we've found has no data (SHT_NOBITS), then check the module section
+ // list. This can happen if we're parsing the debug file and it has no .text section, for example.
if (symbol_section_sp && (symbol_section_sp->GetFileSize() == 0))
{
ModuleSP module_sp(GetModule());
if (module_sp)
{
- ObjectFile *obj_file = module_sp->GetObjectFile();
- // Check if we've got a different object file than ourselves.
- if (obj_file && (obj_file != this))
+ SectionList *module_section_list = module_sp->GetSectionList();
+ if (module_section_list && module_section_list != section_list)
{
const ConstString §_name = symbol_section_sp->GetName();
- SectionList *obj_file_section_list = obj_file->GetSectionList();
- lldb::SectionSP section_sp (obj_file_section_list->FindSectionByName (sect_name));
+ lldb::SectionSP section_sp (module_section_list->FindSectionByName (sect_name));
if (section_sp && section_sp->GetFileSize())
{
symbol_section_sp = section_sp;
@@ -1159,32 +1176,46 @@ ObjectFileELF::ParseSymbols(Symtab *symt
}
unsigned
-ObjectFileELF::ParseSymbolTable(Symtab *symbol_table, user_id_t start_id, user_id_t symtab_id)
+ObjectFileELF::ParseSymbolTable(Symtab *symbol_table, user_id_t start_id, lldb_private::Section *symtab)
{
- // Parse in the section list if needed.
- SectionList *section_list = GetSectionList();
+ if (symtab->GetObjectFile() != this)
+ {
+ // If the symbol table section is owned by a different object file, have it do the
+ // parsing.
+ ObjectFileELF *obj_file_elf = static_cast<ObjectFileELF *>(symtab->GetObjectFile());
+ return obj_file_elf->ParseSymbolTable (symbol_table, start_id, symtab);
+ }
+
+ // Get section list for this object file.
+ SectionList *section_list = m_sections_ap.get();
if (!section_list)
return 0;
- const ELFSectionHeaderInfo *symtab_hdr = &m_section_headers[symtab_id - 1];
+ user_id_t symtab_id = symtab->GetID();
+ const ELFSectionHeaderInfo *symtab_hdr = GetSectionHeaderByIndex(symtab_id);
assert(symtab_hdr->sh_type == SHT_SYMTAB ||
symtab_hdr->sh_type == SHT_DYNSYM);
+ // sh_link: section header index of associated string table.
// Section ID's are ones based.
user_id_t strtab_id = symtab_hdr->sh_link + 1;
-
- Section *symtab = section_list->FindSectionByID(symtab_id).get();
Section *strtab = section_list->FindSectionByID(strtab_id).get();
+
unsigned num_symbols = 0;
if (symtab && strtab)
{
+ assert (symtab->GetObjectFile() == this);
+ assert (strtab->GetObjectFile() == this);
+
DataExtractor symtab_data;
DataExtractor strtab_data;
if (ReadSectionData(symtab, symtab_data) &&
ReadSectionData(strtab, strtab_data))
{
+ size_t num_symbols = symtab_data.GetByteSize() / symtab_hdr->sh_entsize;
+
num_symbols = ParseSymbols(symbol_table, start_id,
- section_list, symtab_hdr,
+ section_list, num_symbols,
symtab_data, strtab_data);
}
}
@@ -1198,17 +1229,15 @@ ObjectFileELF::ParseDynamicSymbols()
if (m_dynamic_symbols.size())
return m_dynamic_symbols.size();
- user_id_t dyn_id = GetSectionIndexByType(SHT_DYNAMIC);
- if (!dyn_id)
- return 0;
-
SectionList *section_list = GetSectionList();
if (!section_list)
return 0;
- Section *dynsym = section_list->FindSectionByID(dyn_id).get();
+ // Find the SHT_DYNAMIC section.
+ Section *dynsym = section_list->FindSectionByType (eSectionTypeELFDynamicLinkInfo, true).get();
if (!dynsym)
return 0;
+ assert (dynsym->GetObjectFile() == this);
ELFDynamic symbol;
DataExtractor dynsym_data;
@@ -1341,7 +1370,7 @@ ObjectFileELF::ParseTrampolineSymbols(Sy
{
assert(rel_hdr->sh_type == SHT_RELA || rel_hdr->sh_type == SHT_REL);
- // The link field points to the associated symbol table. The info field
+ // The link field points to the associated symbol table. The info field
// points to the section holding the plt.
user_id_t symtab_id = rel_hdr->sh_link;
user_id_t plt_id = rel_hdr->sh_info;
@@ -1361,7 +1390,7 @@ ObjectFileELF::ParseTrampolineSymbols(Sy
if (!sym_hdr)
return 0;
- SectionList *section_list = GetSectionList();
+ SectionList *section_list = m_sections_ap.get();
if (!section_list)
return 0;
@@ -1377,6 +1406,7 @@ ObjectFileELF::ParseTrampolineSymbols(Sy
if (!symtab)
return 0;
+ // sh_link points to associated string table.
Section *strtab = section_list->FindSectionByID(sym_hdr->sh_link + 1).get();
if (!strtab)
return 0;
@@ -1411,82 +1441,68 @@ ObjectFileELF::ParseTrampolineSymbols(Sy
}
Symtab *
-ObjectFileELF::GetSymtab(uint32_t flags)
+ObjectFileELF::GetSymtab()
{
ModuleSP module_sp(GetModule());
- if (module_sp)
- {
- lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+ if (!module_sp)
+ return NULL;
+
+ // We always want to use the main object file so we (hopefully) only have one cached copy
+ // of our symtab, dynamic sections, etc.
+ ObjectFile *module_obj_file = module_sp->GetObjectFile();
+ if (module_obj_file && module_obj_file != this)
+ return module_obj_file->GetSymtab();
- bool from_unified_section_list = !!(flags & eSymtabFromUnifiedSectionList);
- SectionList *section_list = from_unified_section_list ? module_sp->GetUnifiedSectionList() : GetSectionList();
+ if (m_symtab_ap.get() == NULL)
+ {
+ SectionList *section_list = GetSectionList();
if (!section_list)
return NULL;
- // If we're doing the unified section list and it has been modified, then clear our
- // cache and reload the symbols. If needed, we could check on only the sections that
- // we use to create the symbol table...
- std::unique_ptr<lldb_private::Symtab> &symtab_ap = from_unified_section_list ? m_symtab_unified_ap : m_symtab_ap;
- if (from_unified_section_list && (m_symtab_unified_revisionid != section_list->GetRevisionID()))
- {
- symtab_ap.reset();
- m_symtab_unified_revisionid = section_list->GetRevisionID();
- }
- else if (symtab_ap.get())
- {
- return symtab_ap.get();
- }
+ uint64_t symbol_id = 0;
+ lldb_private::Mutex::Locker locker(module_sp->GetMutex());
- Symtab *symbol_table = new Symtab(this);
- symtab_ap.reset(symbol_table);
+ m_symtab_ap.reset(new Symtab(this));
// Sharable objects and dynamic executables usually have 2 distinct symbol
// tables, one named ".symtab", and the other ".dynsym". The dynsym is a smaller
// version of the symtab that only contains global symbols. The information found
// in the dynsym is therefore also found in the symtab, while the reverse is not
// necessarily true.
- Section *section_sym = section_list->FindSectionByType (eSectionTypeELFSymbolTable, true).get();
- if (!section_sym)
+ Section *symtab = section_list->FindSectionByType (eSectionTypeELFSymbolTable, true).get();
+ if (!symtab)
{
// The symtab section is non-allocable and can be stripped, so if it doesn't exist
// then use the dynsym section which should always be there.
- section_sym = section_list->FindSectionByType (eSectionTypeELFDynamicSymbols, true).get();
+ symtab = section_list->FindSectionByType (eSectionTypeELFDynamicSymbols, true).get();
}
+ if (symtab)
+ symbol_id += ParseSymbolTable (m_symtab_ap.get(), symbol_id, symtab);
- uint64_t symbol_id = 0;
- if (section_sym)
- {
- user_id_t section_id = section_sym->GetID();
- ObjectFileELF *obj_file_elf = static_cast<ObjectFileELF *>(section_sym->GetObjectFile());
-
- symbol_id += obj_file_elf->ParseSymbolTable (symbol_table, symbol_id, section_id);
- }
-
- Section *section = section_list->FindSectionByType (eSectionTypeELFDynamicLinkInfo, true).get();
- if (section)
+ // Synthesize trampoline symbols to help navigate the PLT.
+ const ELFDynamic *symbol = FindDynamicSymbol(DT_JMPREL);
+ if (symbol)
{
- ObjectFileELF *obj_file_elf = static_cast<ObjectFileELF *>(section->GetObjectFile());
-
- // Synthesize trampoline symbols to help navigate the PLT.
- const ELFDynamic *symbol = obj_file_elf->FindDynamicSymbol(DT_JMPREL);
- if (symbol)
+ addr_t addr = symbol->d_ptr;
+ Section *reloc_section = section_list->FindSectionContainingFileAddress(addr).get();
+ if (reloc_section)
{
- addr_t addr = symbol->d_ptr;
- Section *reloc_section = section_list->FindSectionContainingFileAddress(addr).get();
- if (reloc_section)
- {
- user_id_t reloc_id = reloc_section->GetID();
- const ELFSectionHeaderInfo *reloc_header = obj_file_elf->GetSectionHeaderByIndex(reloc_id);
- assert(reloc_header);
+ user_id_t reloc_id = reloc_section->GetID();
+ const ELFSectionHeaderInfo *reloc_header = GetSectionHeaderByIndex(reloc_id);
+ assert(reloc_header);
- obj_file_elf->ParseTrampolineSymbols(symbol_table, symbol_id, reloc_header, reloc_id);
- }
+ ParseTrampolineSymbols (m_symtab_ap.get(), symbol_id, reloc_header, reloc_id);
}
}
-
- return symbol_table;
}
- return NULL;
+ return m_symtab_ap.get();
+}
+
+bool
+ObjectFileELF::IsStripped ()
+{
+ // TODO: determine this for ELF
+ return false;
}
//===----------------------------------------------------------------------===//
Modified: lldb/branches/lldb-platform-work/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/ObjectFile/ELF/ObjectFileELF.h?rev=186540&r1=186539&r2=186540&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/ObjectFile/ELF/ObjectFileELF.h (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/ObjectFile/ELF/ObjectFileELF.h Wed Jul 17 17:17:41 2013
@@ -100,10 +100,13 @@ public:
GetAddressByteSize() const;
virtual lldb_private::Symtab *
- GetSymtab(uint32_t flags = 0);
+ GetSymtab();
- virtual lldb_private::SectionList *
- GetSectionList();
+ virtual bool
+ IsStripped ();
+
+ virtual void
+ CreateSections (lldb_private::SectionList &unified_section_list);
virtual void
Dump(lldb_private::Stream *s);
@@ -132,6 +135,18 @@ public:
virtual ObjectFile::Strata
CalculateStrata();
+ // Returns number of program headers found in the ELF file.
+ size_t
+ GetProgramHeaderCount();
+
+ // Returns the program header with the given index.
+ const elf::ELFProgramHeader *
+ GetProgramHeaderByIndex(lldb::user_id_t id);
+
+ // Returns segment data for the given index.
+ lldb_private::DataExtractor
+ GetSegmentDataByIndex(lldb::user_id_t id);
+
private:
ObjectFileELF(const lldb::ModuleSP &module_sp,
lldb::DataBufferSP& data_sp,
@@ -232,14 +247,14 @@ private:
unsigned
ParseSymbolTable(lldb_private::Symtab *symbol_table,
lldb::user_id_t start_id,
- lldb::user_id_t symtab_id);
+ lldb_private::Section *symtab);
/// Helper routine for ParseSymbolTable().
unsigned
ParseSymbols(lldb_private::Symtab *symbol_table,
lldb::user_id_t start_id,
lldb_private::SectionList *section_list,
- const ELFSectionHeaderInfo *symtab_shdr,
+ const size_t num_symbols,
const lldb_private::DataExtractor &symtab_data,
const lldb_private::DataExtractor &strtab_data);
@@ -252,17 +267,6 @@ private:
const ELFSectionHeaderInfo *rela_hdr,
lldb::user_id_t section_id);
- /// Utility method for looking up a section given its name. Returns the
- /// index of the corresponding section or zero if no section with the given
- /// name can be found (note that section indices are always 1 based, and so
- /// section index 0 is never valid).
- lldb::user_id_t
- GetSectionIndexByName(const char *name);
-
- // Returns the ID of the first section that has the given type.
- lldb::user_id_t
- GetSectionIndexByType(unsigned type);
-
/// Returns the section header with the given id or NULL.
const ELFSectionHeaderInfo *
GetSectionHeaderByIndex(lldb::user_id_t id);
Modified: lldb/branches/lldb-platform-work/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp?rev=186540&r1=186539&r2=186540&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp Wed Jul 17 17:17:41 2013
@@ -513,7 +513,8 @@ ObjectFileMachO::GetModuleSpecifications
if (header.sizeofcmds >= data_sp->GetByteSize())
{
data_sp = file.ReadFileContents(file_offset, header.sizeofcmds);
- data_offset = MachHeaderSizeFromMagic(header.magic) + file_offset;
+ data.SetData(data_sp);
+ data_offset = MachHeaderSizeFromMagic(header.magic);
}
if (data_sp)
{
@@ -895,7 +896,7 @@ ObjectFileMachO::GetAddressClass (lldb::
}
Symtab *
-ObjectFileMachO::GetSymtab(uint32_t flags)
+ObjectFileMachO::GetSymtab()
{
ModuleSP module_sp(GetModule());
if (module_sp)
@@ -905,409 +906,462 @@ ObjectFileMachO::GetSymtab(uint32_t flag
{
m_symtab_ap.reset(new Symtab(this));
Mutex::Locker symtab_locker (m_symtab_ap->GetMutex());
- ParseSymtab (true);
+ ParseSymtab ();
m_symtab_ap->Finalize ();
}
}
return m_symtab_ap.get();
}
-
-SectionList *
-ObjectFileMachO::GetSectionList()
+bool
+ObjectFileMachO::IsStripped ()
{
- ModuleSP module_sp(GetModule());
- if (module_sp)
+ if (m_dysymtab.cmd == 0)
{
- lldb_private::Mutex::Locker locker(module_sp->GetMutex());
- if (m_sections_ap.get() == NULL)
+ ModuleSP module_sp(GetModule());
+ if (module_sp)
{
- m_sections_ap.reset(new SectionList());
- ParseSections();
+ lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
+ for (uint32_t i=0; i<m_header.ncmds; ++i)
+ {
+ const lldb::offset_t load_cmd_offset = offset;
+
+ load_command lc;
+ if (m_data.GetU32(&offset, &lc.cmd, 2) == NULL)
+ break;
+ if (lc.cmd == LoadCommandDynamicSymtabInfo)
+ {
+ m_dysymtab.cmd = lc.cmd;
+ m_dysymtab.cmdsize = lc.cmdsize;
+ if (m_data.GetU32 (&offset, &m_dysymtab.ilocalsym, (sizeof(m_dysymtab) / sizeof(uint32_t)) - 2) == NULL)
+ {
+ // Clear m_dysymtab if we were unable to read all items from the load command
+ ::memset (&m_dysymtab, 0, sizeof(m_dysymtab));
+ }
+ }
+ offset = load_cmd_offset + lc.cmdsize;
+ }
}
}
- return m_sections_ap.get();
+ if (m_dysymtab.cmd)
+ return m_dysymtab.nlocalsym == 0;
+ return false;
}
-
-size_t
-ObjectFileMachO::ParseSections ()
+void
+ObjectFileMachO::CreateSections (SectionList &unified_section_list)
{
- lldb::user_id_t segID = 0;
- lldb::user_id_t sectID = 0;
- lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
- uint32_t i;
- const bool is_core = GetType() == eTypeCoreFile;
- //bool dump_sections = false;
- ModuleSP module_sp (GetModule());
- // First look up any LC_ENCRYPTION_INFO load commands
- typedef RangeArray<uint32_t, uint32_t, 8> EncryptedFileRanges;
- EncryptedFileRanges encrypted_file_ranges;
- encryption_info_command encryption_cmd;
- for (i=0; i<m_header.ncmds; ++i)
+ if (!m_sections_ap.get())
{
- const lldb::offset_t load_cmd_offset = offset;
- if (m_data.GetU32(&offset, &encryption_cmd, 2) == NULL)
- break;
-
- if (encryption_cmd.cmd == LoadCommandEncryptionInfo)
+ m_sections_ap.reset(new SectionList());
+
+ const bool is_dsym = (m_header.filetype == HeaderFileTypeDSYM);
+ lldb::user_id_t segID = 0;
+ lldb::user_id_t sectID = 0;
+ lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
+ uint32_t i;
+ const bool is_core = GetType() == eTypeCoreFile;
+ //bool dump_sections = false;
+ ModuleSP module_sp (GetModule());
+ // First look up any LC_ENCRYPTION_INFO load commands
+ typedef RangeArray<uint32_t, uint32_t, 8> EncryptedFileRanges;
+ EncryptedFileRanges encrypted_file_ranges;
+ encryption_info_command encryption_cmd;
+ for (i=0; i<m_header.ncmds; ++i)
{
- if (m_data.GetU32(&offset, &encryption_cmd.cryptoff, 3))
+ const lldb::offset_t load_cmd_offset = offset;
+ if (m_data.GetU32(&offset, &encryption_cmd, 2) == NULL)
+ break;
+
+ if (encryption_cmd.cmd == LoadCommandEncryptionInfo)
{
- if (encryption_cmd.cryptid != 0)
+ if (m_data.GetU32(&offset, &encryption_cmd.cryptoff, 3))
{
- EncryptedFileRanges::Entry entry;
- entry.SetRangeBase(encryption_cmd.cryptoff);
- entry.SetByteSize(encryption_cmd.cryptsize);
- encrypted_file_ranges.Append(entry);
+ if (encryption_cmd.cryptid != 0)
+ {
+ EncryptedFileRanges::Entry entry;
+ entry.SetRangeBase(encryption_cmd.cryptoff);
+ entry.SetByteSize(encryption_cmd.cryptsize);
+ encrypted_file_ranges.Append(entry);
+ }
}
}
+ offset = load_cmd_offset + encryption_cmd.cmdsize;
}
- offset = load_cmd_offset + encryption_cmd.cmdsize;
- }
-
- offset = MachHeaderSizeFromMagic(m_header.magic);
- struct segment_command_64 load_cmd;
- for (i=0; i<m_header.ncmds; ++i)
- {
- const lldb::offset_t load_cmd_offset = offset;
- if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
- break;
+ offset = MachHeaderSizeFromMagic(m_header.magic);
- if (load_cmd.cmd == LoadCommandSegment32 || load_cmd.cmd == LoadCommandSegment64)
+ struct segment_command_64 load_cmd;
+ for (i=0; i<m_header.ncmds; ++i)
{
- if (m_data.GetU8(&offset, (uint8_t*)load_cmd.segname, 16))
+ const lldb::offset_t load_cmd_offset = offset;
+ if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
+ break;
+
+ if (load_cmd.cmd == LoadCommandSegment32 || load_cmd.cmd == LoadCommandSegment64)
{
- load_cmd.vmaddr = m_data.GetAddress(&offset);
- load_cmd.vmsize = m_data.GetAddress(&offset);
- load_cmd.fileoff = m_data.GetAddress(&offset);
- load_cmd.filesize = m_data.GetAddress(&offset);
- if (m_length != 0 && load_cmd.filesize != 0)
- {
- if (load_cmd.fileoff > m_length)
- {
- // We have a load command that says it extends past the end of hte file. This is likely
- // a corrupt file. We don't have any way to return an error condition here (this method
- // was likely invokved from something like ObjectFile::GetSectionList()) -- all we can do
- // is null out the SectionList vector and if a process has been set up, dump a message
- // to stdout. The most common case here is core file debugging with a truncated file.
- const char *lc_segment_name = load_cmd.cmd == LoadCommandSegment64 ? "LC_SEGMENT_64" : "LC_SEGMENT";
- GetModule()->ReportError("is a corrupt mach-o file: load command %u %s has a fileoff (0x%" PRIx64 ") that extends beyond the end of the file (0x%" PRIx64 ")",
- i,
- lc_segment_name,
- load_cmd.fileoff,
- m_length);
-
- load_cmd.fileoff = 0;
- load_cmd.filesize = 0;
- }
-
- if (load_cmd.fileoff + load_cmd.filesize > m_length)
+ if (m_data.GetU8(&offset, (uint8_t*)load_cmd.segname, 16))
+ {
+ bool add_section = true;
+ bool add_to_unified = true;
+ ConstString const_segname (load_cmd.segname, std::min<size_t>(strlen(load_cmd.segname), sizeof(load_cmd.segname)));
+
+ SectionSP unified_section_sp(unified_section_list.FindSectionByName(const_segname));
+ if (is_dsym && unified_section_sp)
{
- // We have a load command that says it extends past the end of hte file. This is likely
- // a corrupt file. We don't have any way to return an error condition here (this method
- // was likely invokved from something like ObjectFile::GetSectionList()) -- all we can do
- // is null out the SectionList vector and if a process has been set up, dump a message
- // to stdout. The most common case here is core file debugging with a truncated file.
- const char *lc_segment_name = load_cmd.cmd == LoadCommandSegment64 ? "LC_SEGMENT_64" : "LC_SEGMENT";
- GetModule()->ReportError("is a corrupt mach-o file: load command %u %s has a fileoff + filesize (0x%" PRIx64 ") that extends beyond the end of the file (0x%" PRIx64 "), the segment will be truncated",
- i,
- lc_segment_name,
- load_cmd.fileoff + load_cmd.filesize,
- m_length);
+ if (const_segname == GetSegmentNameLINKEDIT())
+ {
+ // We need to keep the __LINKEDIT segment private to this object file only
+ add_to_unified = false;
+ }
+ else
+ {
+ // This is the dSYM file and this section has already been created by
+ // the object file, no need to create it.
+ add_section = false;
+ }
+ }
+ load_cmd.vmaddr = m_data.GetAddress(&offset);
+ load_cmd.vmsize = m_data.GetAddress(&offset);
+ load_cmd.fileoff = m_data.GetAddress(&offset);
+ load_cmd.filesize = m_data.GetAddress(&offset);
+ if (m_length != 0 && load_cmd.filesize != 0)
+ {
+ if (load_cmd.fileoff > m_length)
+ {
+ // We have a load command that says it extends past the end of hte file. This is likely
+ // a corrupt file. We don't have any way to return an error condition here (this method
+ // was likely invokved from something like ObjectFile::GetSectionList()) -- all we can do
+ // is null out the SectionList vector and if a process has been set up, dump a message
+ // to stdout. The most common case here is core file debugging with a truncated file.
+ const char *lc_segment_name = load_cmd.cmd == LoadCommandSegment64 ? "LC_SEGMENT_64" : "LC_SEGMENT";
+ GetModule()->ReportError("is a corrupt mach-o file: load command %u %s has a fileoff (0x%" PRIx64 ") that extends beyond the end of the file (0x%" PRIx64 ")",
+ i,
+ lc_segment_name,
+ load_cmd.fileoff,
+ m_length);
+
+ load_cmd.fileoff = 0;
+ load_cmd.filesize = 0;
+ }
- // Tuncase the length
- load_cmd.filesize = m_length - load_cmd.fileoff;
+ if (load_cmd.fileoff + load_cmd.filesize > m_length)
+ {
+ // We have a load command that says it extends past the end of hte file. This is likely
+ // a corrupt file. We don't have any way to return an error condition here (this method
+ // was likely invokved from something like ObjectFile::GetSectionList()) -- all we can do
+ // is null out the SectionList vector and if a process has been set up, dump a message
+ // to stdout. The most common case here is core file debugging with a truncated file.
+ const char *lc_segment_name = load_cmd.cmd == LoadCommandSegment64 ? "LC_SEGMENT_64" : "LC_SEGMENT";
+ GetModule()->ReportError("is a corrupt mach-o file: load command %u %s has a fileoff + filesize (0x%" PRIx64 ") that extends beyond the end of the file (0x%" PRIx64 "), the segment will be truncated",
+ i,
+ lc_segment_name,
+ load_cmd.fileoff + load_cmd.filesize,
+ m_length);
+
+ // Tuncase the length
+ load_cmd.filesize = m_length - load_cmd.fileoff;
+ }
}
- }
- if (m_data.GetU32(&offset, &load_cmd.maxprot, 4))
- {
-
- const bool segment_is_encrypted = (load_cmd.flags & SegmentCommandFlagBitProtectedVersion1) != 0;
-
- // Keep a list of mach segments around in case we need to
- // get at data that isn't stored in the abstracted Sections.
- m_mach_segments.push_back (load_cmd);
-
- ConstString segment_name (load_cmd.segname, std::min<size_t>(strlen(load_cmd.segname), sizeof(load_cmd.segname)));
- // Use a segment ID of the segment index shifted left by 8 so they
- // never conflict with any of the sections.
- SectionSP segment_sp;
- if (segment_name || is_core)
+ if (m_data.GetU32(&offset, &load_cmd.maxprot, 4))
{
- segment_sp.reset(new Section (module_sp, // Module to which this section belongs
- this, // Object file to which this sections belongs
- ++segID << 8, // Section ID is the 1 based segment index shifted right by 8 bits as not to collide with any of the 256 section IDs that are possible
- segment_name, // Name of this section
- eSectionTypeContainer, // This section is a container of other sections.
- load_cmd.vmaddr, // File VM address == addresses as they are found in the object file
- load_cmd.vmsize, // VM size in bytes of this section
- load_cmd.fileoff, // Offset to the data for this section in the file
- load_cmd.filesize, // Size in bytes of this section as found in the the file
- load_cmd.flags)); // Flags for this section
- segment_sp->SetIsEncrypted (segment_is_encrypted);
- m_sections_ap->AddSection(segment_sp);
- }
+ const bool segment_is_encrypted = (load_cmd.flags & SegmentCommandFlagBitProtectedVersion1) != 0;
- struct section_64 sect64;
- ::memset (§64, 0, sizeof(sect64));
- // Push a section into our mach sections for the section at
- // index zero (NListSectionNoSection) if we don't have any
- // mach sections yet...
- if (m_mach_sections.empty())
- m_mach_sections.push_back(sect64);
- uint32_t segment_sect_idx;
- const lldb::user_id_t first_segment_sectID = sectID + 1;
+ // Keep a list of mach segments around in case we need to
+ // get at data that isn't stored in the abstracted Sections.
+ m_mach_segments.push_back (load_cmd);
+ // Use a segment ID of the segment index shifted left by 8 so they
+ // never conflict with any of the sections.
+ SectionSP segment_sp;
+ if (add_section && (const_segname || is_core))
+ {
+ segment_sp.reset(new Section (module_sp, // Module to which this section belongs
+ this, // Object file to which this sections belongs
+ ++segID << 8, // Section ID is the 1 based segment index shifted right by 8 bits as not to collide with any of the 256 section IDs that are possible
+ const_segname, // Name of this section
+ eSectionTypeContainer, // This section is a container of other sections.
+ load_cmd.vmaddr, // File VM address == addresses as they are found in the object file
+ load_cmd.vmsize, // VM size in bytes of this section
+ load_cmd.fileoff, // Offset to the data for this section in the file
+ load_cmd.filesize, // Size in bytes of this section as found in the the file
+ load_cmd.flags)); // Flags for this section
+
+ segment_sp->SetIsEncrypted (segment_is_encrypted);
+ m_sections_ap->AddSection(segment_sp);
+ if (add_to_unified)
+ unified_section_list.AddSection(segment_sp);
+ }
+ else if (unified_section_sp)
+ {
+ m_sections_ap->AddSection(unified_section_sp);
+ }
+
+ struct section_64 sect64;
+ ::memset (§64, 0, sizeof(sect64));
+ // Push a section into our mach sections for the section at
+ // index zero (NListSectionNoSection) if we don't have any
+ // mach sections yet...
+ if (m_mach_sections.empty())
+ m_mach_sections.push_back(sect64);
+ uint32_t segment_sect_idx;
+ const lldb::user_id_t first_segment_sectID = sectID + 1;
- const uint32_t num_u32s = load_cmd.cmd == LoadCommandSegment32 ? 7 : 8;
- for (segment_sect_idx=0; segment_sect_idx<load_cmd.nsects; ++segment_sect_idx)
- {
- if (m_data.GetU8(&offset, (uint8_t*)sect64.sectname, sizeof(sect64.sectname)) == NULL)
- break;
- if (m_data.GetU8(&offset, (uint8_t*)sect64.segname, sizeof(sect64.segname)) == NULL)
- break;
- sect64.addr = m_data.GetAddress(&offset);
- sect64.size = m_data.GetAddress(&offset);
- if (m_data.GetU32(&offset, §64.offset, num_u32s) == NULL)
- break;
+ const uint32_t num_u32s = load_cmd.cmd == LoadCommandSegment32 ? 7 : 8;
+ for (segment_sect_idx=0; segment_sect_idx<load_cmd.nsects; ++segment_sect_idx)
+ {
+ if (m_data.GetU8(&offset, (uint8_t*)sect64.sectname, sizeof(sect64.sectname)) == NULL)
+ break;
+ if (m_data.GetU8(&offset, (uint8_t*)sect64.segname, sizeof(sect64.segname)) == NULL)
+ break;
+ sect64.addr = m_data.GetAddress(&offset);
+ sect64.size = m_data.GetAddress(&offset);
- // Keep a list of mach sections around in case we need to
- // get at data that isn't stored in the abstracted Sections.
- m_mach_sections.push_back (sect64);
+ if (m_data.GetU32(&offset, §64.offset, num_u32s) == NULL)
+ break;
- ConstString section_name (sect64.sectname, std::min<size_t>(strlen(sect64.sectname), sizeof(sect64.sectname)));
- if (!segment_name)
- {
- // We have a segment with no name so we need to conjure up
- // segments that correspond to the section's segname if there
- // isn't already such a section. If there is such a section,
- // we resize the section so that it spans all sections.
- // We also mark these sections as fake so address matches don't
- // hit if they land in the gaps between the child sections.
- segment_name.SetTrimmedCStringWithLength(sect64.segname, sizeof(sect64.segname));
- segment_sp = m_sections_ap->FindSectionByName (segment_name);
- if (segment_sp.get())
+ // Keep a list of mach sections around in case we need to
+ // get at data that isn't stored in the abstracted Sections.
+ m_mach_sections.push_back (sect64);
+
+ if (add_section)
{
- Section *segment = segment_sp.get();
- // Grow the section size as needed.
- const lldb::addr_t sect64_min_addr = sect64.addr;
- const lldb::addr_t sect64_max_addr = sect64_min_addr + sect64.size;
- const lldb::addr_t curr_seg_byte_size = segment->GetByteSize();
- const lldb::addr_t curr_seg_min_addr = segment->GetFileAddress();
- const lldb::addr_t curr_seg_max_addr = curr_seg_min_addr + curr_seg_byte_size;
- if (sect64_min_addr >= curr_seg_min_addr)
+ ConstString section_name (sect64.sectname, std::min<size_t>(strlen(sect64.sectname), sizeof(sect64.sectname)));
+ if (!const_segname)
{
- const lldb::addr_t new_seg_byte_size = sect64_max_addr - curr_seg_min_addr;
- // Only grow the section size if needed
- if (new_seg_byte_size > curr_seg_byte_size)
- segment->SetByteSize (new_seg_byte_size);
+ // We have a segment with no name so we need to conjure up
+ // segments that correspond to the section's segname if there
+ // isn't already such a section. If there is such a section,
+ // we resize the section so that it spans all sections.
+ // We also mark these sections as fake so address matches don't
+ // hit if they land in the gaps between the child sections.
+ const_segname.SetTrimmedCStringWithLength(sect64.segname, sizeof(sect64.segname));
+ segment_sp = unified_section_list.FindSectionByName (const_segname);
+ if (segment_sp.get())
+ {
+ Section *segment = segment_sp.get();
+ // Grow the section size as needed.
+ const lldb::addr_t sect64_min_addr = sect64.addr;
+ const lldb::addr_t sect64_max_addr = sect64_min_addr + sect64.size;
+ const lldb::addr_t curr_seg_byte_size = segment->GetByteSize();
+ const lldb::addr_t curr_seg_min_addr = segment->GetFileAddress();
+ const lldb::addr_t curr_seg_max_addr = curr_seg_min_addr + curr_seg_byte_size;
+ if (sect64_min_addr >= curr_seg_min_addr)
+ {
+ const lldb::addr_t new_seg_byte_size = sect64_max_addr - curr_seg_min_addr;
+ // Only grow the section size if needed
+ if (new_seg_byte_size > curr_seg_byte_size)
+ segment->SetByteSize (new_seg_byte_size);
+ }
+ else
+ {
+ // We need to change the base address of the segment and
+ // adjust the child section offsets for all existing children.
+ const lldb::addr_t slide_amount = sect64_min_addr - curr_seg_min_addr;
+ segment->Slide(slide_amount, false);
+ segment->GetChildren().Slide(-slide_amount, false);
+ segment->SetByteSize (curr_seg_max_addr - sect64_min_addr);
+ }
+
+ // Grow the section size as needed.
+ if (sect64.offset)
+ {
+ const lldb::addr_t segment_min_file_offset = segment->GetFileOffset();
+ const lldb::addr_t segment_max_file_offset = segment_min_file_offset + segment->GetFileSize();
+
+ const lldb::addr_t section_min_file_offset = sect64.offset;
+ const lldb::addr_t section_max_file_offset = section_min_file_offset + sect64.size;
+ const lldb::addr_t new_file_offset = std::min (section_min_file_offset, segment_min_file_offset);
+ const lldb::addr_t new_file_size = std::max (section_max_file_offset, segment_max_file_offset) - new_file_offset;
+ segment->SetFileOffset (new_file_offset);
+ segment->SetFileSize (new_file_size);
+ }
+ }
+ else
+ {
+ // Create a fake section for the section's named segment
+ segment_sp.reset(new Section (segment_sp, // Parent section
+ module_sp, // Module to which this section belongs
+ this, // Object file to which this section belongs
+ ++segID << 8, // Section ID is the 1 based segment index shifted right by 8 bits as not to collide with any of the 256 section IDs that are possible
+ const_segname, // Name of this section
+ eSectionTypeContainer, // This section is a container of other sections.
+ sect64.addr, // File VM address == addresses as they are found in the object file
+ sect64.size, // VM size in bytes of this section
+ sect64.offset, // Offset to the data for this section in the file
+ sect64.offset ? sect64.size : 0, // Size in bytes of this section as found in the the file
+ load_cmd.flags)); // Flags for this section
+ segment_sp->SetIsFake(true);
+
+ m_sections_ap->AddSection(segment_sp);
+ if (add_to_unified)
+ unified_section_list.AddSection(segment_sp);
+ segment_sp->SetIsEncrypted (segment_is_encrypted);
+ }
}
- else
+ assert (segment_sp.get());
+
+ uint32_t mach_sect_type = sect64.flags & SectionFlagMaskSectionType;
+ static ConstString g_sect_name_objc_data ("__objc_data");
+ static ConstString g_sect_name_objc_msgrefs ("__objc_msgrefs");
+ static ConstString g_sect_name_objc_selrefs ("__objc_selrefs");
+ static ConstString g_sect_name_objc_classrefs ("__objc_classrefs");
+ static ConstString g_sect_name_objc_superrefs ("__objc_superrefs");
+ static ConstString g_sect_name_objc_const ("__objc_const");
+ static ConstString g_sect_name_objc_classlist ("__objc_classlist");
+ static ConstString g_sect_name_cfstring ("__cfstring");
+
+ static ConstString g_sect_name_dwarf_debug_abbrev ("__debug_abbrev");
+ static ConstString g_sect_name_dwarf_debug_aranges ("__debug_aranges");
+ static ConstString g_sect_name_dwarf_debug_frame ("__debug_frame");
+ static ConstString g_sect_name_dwarf_debug_info ("__debug_info");
+ static ConstString g_sect_name_dwarf_debug_line ("__debug_line");
+ static ConstString g_sect_name_dwarf_debug_loc ("__debug_loc");
+ static ConstString g_sect_name_dwarf_debug_macinfo ("__debug_macinfo");
+ static ConstString g_sect_name_dwarf_debug_pubnames ("__debug_pubnames");
+ static ConstString g_sect_name_dwarf_debug_pubtypes ("__debug_pubtypes");
+ static ConstString g_sect_name_dwarf_debug_ranges ("__debug_ranges");
+ static ConstString g_sect_name_dwarf_debug_str ("__debug_str");
+ static ConstString g_sect_name_dwarf_apple_names ("__apple_names");
+ static ConstString g_sect_name_dwarf_apple_types ("__apple_types");
+ static ConstString g_sect_name_dwarf_apple_namespaces ("__apple_namespac");
+ static ConstString g_sect_name_dwarf_apple_objc ("__apple_objc");
+ static ConstString g_sect_name_eh_frame ("__eh_frame");
+ static ConstString g_sect_name_DATA ("__DATA");
+ static ConstString g_sect_name_TEXT ("__TEXT");
+
+ SectionType sect_type = eSectionTypeOther;
+
+ if (section_name == g_sect_name_dwarf_debug_abbrev)
+ sect_type = eSectionTypeDWARFDebugAbbrev;
+ else if (section_name == g_sect_name_dwarf_debug_aranges)
+ sect_type = eSectionTypeDWARFDebugAranges;
+ else if (section_name == g_sect_name_dwarf_debug_frame)
+ sect_type = eSectionTypeDWARFDebugFrame;
+ else if (section_name == g_sect_name_dwarf_debug_info)
+ sect_type = eSectionTypeDWARFDebugInfo;
+ else if (section_name == g_sect_name_dwarf_debug_line)
+ sect_type = eSectionTypeDWARFDebugLine;
+ else if (section_name == g_sect_name_dwarf_debug_loc)
+ sect_type = eSectionTypeDWARFDebugLoc;
+ else if (section_name == g_sect_name_dwarf_debug_macinfo)
+ sect_type = eSectionTypeDWARFDebugMacInfo;
+ else if (section_name == g_sect_name_dwarf_debug_pubnames)
+ sect_type = eSectionTypeDWARFDebugPubNames;
+ else if (section_name == g_sect_name_dwarf_debug_pubtypes)
+ sect_type = eSectionTypeDWARFDebugPubTypes;
+ else if (section_name == g_sect_name_dwarf_debug_ranges)
+ sect_type = eSectionTypeDWARFDebugRanges;
+ else if (section_name == g_sect_name_dwarf_debug_str)
+ sect_type = eSectionTypeDWARFDebugStr;
+ else if (section_name == g_sect_name_dwarf_apple_names)
+ sect_type = eSectionTypeDWARFAppleNames;
+ else if (section_name == g_sect_name_dwarf_apple_types)
+ sect_type = eSectionTypeDWARFAppleTypes;
+ else if (section_name == g_sect_name_dwarf_apple_namespaces)
+ sect_type = eSectionTypeDWARFAppleNamespaces;
+ else if (section_name == g_sect_name_dwarf_apple_objc)
+ sect_type = eSectionTypeDWARFAppleObjC;
+ else if (section_name == g_sect_name_objc_selrefs)
+ sect_type = eSectionTypeDataCStringPointers;
+ else if (section_name == g_sect_name_objc_msgrefs)
+ sect_type = eSectionTypeDataObjCMessageRefs;
+ else if (section_name == g_sect_name_eh_frame)
+ sect_type = eSectionTypeEHFrame;
+ else if (section_name == g_sect_name_cfstring)
+ sect_type = eSectionTypeDataObjCCFStrings;
+ else if (section_name == g_sect_name_objc_data ||
+ section_name == g_sect_name_objc_classrefs ||
+ section_name == g_sect_name_objc_superrefs ||
+ section_name == g_sect_name_objc_const ||
+ section_name == g_sect_name_objc_classlist)
{
- // We need to change the base address of the segment and
- // adjust the child section offsets for all existing children.
- const lldb::addr_t slide_amount = sect64_min_addr - curr_seg_min_addr;
- segment->Slide(slide_amount, false);
- segment->GetChildren().Slide(-slide_amount, false);
- segment->SetByteSize (curr_seg_max_addr - sect64_min_addr);
+ sect_type = eSectionTypeDataPointers;
}
- // Grow the section size as needed.
- if (sect64.offset)
+ if (sect_type == eSectionTypeOther)
{
- const lldb::addr_t segment_min_file_offset = segment->GetFileOffset();
- const lldb::addr_t segment_max_file_offset = segment_min_file_offset + segment->GetFileSize();
-
- const lldb::addr_t section_min_file_offset = sect64.offset;
- const lldb::addr_t section_max_file_offset = section_min_file_offset + sect64.size;
- const lldb::addr_t new_file_offset = std::min (section_min_file_offset, segment_min_file_offset);
- const lldb::addr_t new_file_size = std::max (section_max_file_offset, segment_max_file_offset) - new_file_offset;
- segment->SetFileOffset (new_file_offset);
- segment->SetFileSize (new_file_size);
+ switch (mach_sect_type)
+ {
+ // TODO: categorize sections by other flags for regular sections
+ case SectionTypeRegular:
+ if (segment_sp->GetName() == g_sect_name_TEXT)
+ sect_type = eSectionTypeCode;
+ else if (segment_sp->GetName() == g_sect_name_DATA)
+ sect_type = eSectionTypeData;
+ else
+ sect_type = eSectionTypeOther;
+ break;
+ case SectionTypeZeroFill: sect_type = eSectionTypeZeroFill; break;
+ case SectionTypeCStringLiterals: sect_type = eSectionTypeDataCString; break; // section with only literal C strings
+ case SectionType4ByteLiterals: sect_type = eSectionTypeData4; break; // section with only 4 byte literals
+ case SectionType8ByteLiterals: sect_type = eSectionTypeData8; break; // section with only 8 byte literals
+ case SectionTypeLiteralPointers: sect_type = eSectionTypeDataPointers; break; // section with only pointers to literals
+ case SectionTypeNonLazySymbolPointers: sect_type = eSectionTypeDataPointers; break; // section with only non-lazy symbol pointers
+ case SectionTypeLazySymbolPointers: sect_type = eSectionTypeDataPointers; break; // section with only lazy symbol pointers
+ case SectionTypeSymbolStubs: sect_type = eSectionTypeCode; break; // section with only symbol stubs, byte size of stub in the reserved2 field
+ case SectionTypeModuleInitFunctionPointers: sect_type = eSectionTypeDataPointers; break; // section with only function pointers for initialization
+ case SectionTypeModuleTermFunctionPointers: sect_type = eSectionTypeDataPointers; break; // section with only function pointers for termination
+ case SectionTypeCoalesced: sect_type = eSectionTypeOther; break;
+ case SectionTypeZeroFillLarge: sect_type = eSectionTypeZeroFill; break;
+ case SectionTypeInterposing: sect_type = eSectionTypeCode; break; // section with only pairs of function pointers for interposing
+ case SectionType16ByteLiterals: sect_type = eSectionTypeData16; break; // section with only 16 byte literals
+ case SectionTypeDTraceObjectFormat: sect_type = eSectionTypeDebug; break;
+ case SectionTypeLazyDylibSymbolPointers: sect_type = eSectionTypeDataPointers; break;
+ default: break;
+ }
}
- }
- else
- {
- // Create a fake section for the section's named segment
- segment_sp.reset(new Section (segment_sp, // Parent section
- module_sp, // Module to which this section belongs
- this, // Object file to which this section belongs
- ++segID << 8, // Section ID is the 1 based segment index shifted right by 8 bits as not to collide with any of the 256 section IDs that are possible
- segment_name, // Name of this section
- eSectionTypeContainer, // This section is a container of other sections.
- sect64.addr, // File VM address == addresses as they are found in the object file
- sect64.size, // VM size in bytes of this section
- sect64.offset, // Offset to the data for this section in the file
- sect64.offset ? sect64.size : 0, // Size in bytes of this section as found in the the file
- load_cmd.flags)); // Flags for this section
- segment_sp->SetIsFake(true);
- m_sections_ap->AddSection(segment_sp);
- segment_sp->SetIsEncrypted (segment_is_encrypted);
- }
- }
- assert (segment_sp.get());
- uint32_t mach_sect_type = sect64.flags & SectionFlagMaskSectionType;
- static ConstString g_sect_name_objc_data ("__objc_data");
- static ConstString g_sect_name_objc_msgrefs ("__objc_msgrefs");
- static ConstString g_sect_name_objc_selrefs ("__objc_selrefs");
- static ConstString g_sect_name_objc_classrefs ("__objc_classrefs");
- static ConstString g_sect_name_objc_superrefs ("__objc_superrefs");
- static ConstString g_sect_name_objc_const ("__objc_const");
- static ConstString g_sect_name_objc_classlist ("__objc_classlist");
- static ConstString g_sect_name_cfstring ("__cfstring");
-
- static ConstString g_sect_name_dwarf_debug_abbrev ("__debug_abbrev");
- static ConstString g_sect_name_dwarf_debug_aranges ("__debug_aranges");
- static ConstString g_sect_name_dwarf_debug_frame ("__debug_frame");
- static ConstString g_sect_name_dwarf_debug_info ("__debug_info");
- static ConstString g_sect_name_dwarf_debug_line ("__debug_line");
- static ConstString g_sect_name_dwarf_debug_loc ("__debug_loc");
- static ConstString g_sect_name_dwarf_debug_macinfo ("__debug_macinfo");
- static ConstString g_sect_name_dwarf_debug_pubnames ("__debug_pubnames");
- static ConstString g_sect_name_dwarf_debug_pubtypes ("__debug_pubtypes");
- static ConstString g_sect_name_dwarf_debug_ranges ("__debug_ranges");
- static ConstString g_sect_name_dwarf_debug_str ("__debug_str");
- static ConstString g_sect_name_dwarf_apple_names ("__apple_names");
- static ConstString g_sect_name_dwarf_apple_types ("__apple_types");
- static ConstString g_sect_name_dwarf_apple_namespaces ("__apple_namespac");
- static ConstString g_sect_name_dwarf_apple_objc ("__apple_objc");
- static ConstString g_sect_name_eh_frame ("__eh_frame");
- static ConstString g_sect_name_DATA ("__DATA");
- static ConstString g_sect_name_TEXT ("__TEXT");
-
- SectionType sect_type = eSectionTypeOther;
-
- if (section_name == g_sect_name_dwarf_debug_abbrev)
- sect_type = eSectionTypeDWARFDebugAbbrev;
- else if (section_name == g_sect_name_dwarf_debug_aranges)
- sect_type = eSectionTypeDWARFDebugAranges;
- else if (section_name == g_sect_name_dwarf_debug_frame)
- sect_type = eSectionTypeDWARFDebugFrame;
- else if (section_name == g_sect_name_dwarf_debug_info)
- sect_type = eSectionTypeDWARFDebugInfo;
- else if (section_name == g_sect_name_dwarf_debug_line)
- sect_type = eSectionTypeDWARFDebugLine;
- else if (section_name == g_sect_name_dwarf_debug_loc)
- sect_type = eSectionTypeDWARFDebugLoc;
- else if (section_name == g_sect_name_dwarf_debug_macinfo)
- sect_type = eSectionTypeDWARFDebugMacInfo;
- else if (section_name == g_sect_name_dwarf_debug_pubnames)
- sect_type = eSectionTypeDWARFDebugPubNames;
- else if (section_name == g_sect_name_dwarf_debug_pubtypes)
- sect_type = eSectionTypeDWARFDebugPubTypes;
- else if (section_name == g_sect_name_dwarf_debug_ranges)
- sect_type = eSectionTypeDWARFDebugRanges;
- else if (section_name == g_sect_name_dwarf_debug_str)
- sect_type = eSectionTypeDWARFDebugStr;
- else if (section_name == g_sect_name_dwarf_apple_names)
- sect_type = eSectionTypeDWARFAppleNames;
- else if (section_name == g_sect_name_dwarf_apple_types)
- sect_type = eSectionTypeDWARFAppleTypes;
- else if (section_name == g_sect_name_dwarf_apple_namespaces)
- sect_type = eSectionTypeDWARFAppleNamespaces;
- else if (section_name == g_sect_name_dwarf_apple_objc)
- sect_type = eSectionTypeDWARFAppleObjC;
- else if (section_name == g_sect_name_objc_selrefs)
- sect_type = eSectionTypeDataCStringPointers;
- else if (section_name == g_sect_name_objc_msgrefs)
- sect_type = eSectionTypeDataObjCMessageRefs;
- else if (section_name == g_sect_name_eh_frame)
- sect_type = eSectionTypeEHFrame;
- else if (section_name == g_sect_name_cfstring)
- sect_type = eSectionTypeDataObjCCFStrings;
- else if (section_name == g_sect_name_objc_data ||
- section_name == g_sect_name_objc_classrefs ||
- section_name == g_sect_name_objc_superrefs ||
- section_name == g_sect_name_objc_const ||
- section_name == g_sect_name_objc_classlist)
- {
- sect_type = eSectionTypeDataPointers;
- }
+ SectionSP section_sp(new Section (segment_sp,
+ module_sp,
+ this,
+ ++sectID,
+ section_name,
+ sect_type,
+ sect64.addr - segment_sp->GetFileAddress(),
+ sect64.size,
+ sect64.offset,
+ sect64.offset == 0 ? 0 : sect64.size,
+ sect64.flags));
+ // Set the section to be encrypted to match the segment
+
+ bool section_is_encrypted = false;
+ if (!segment_is_encrypted && load_cmd.filesize != 0)
+ section_is_encrypted = encrypted_file_ranges.FindEntryThatContains(sect64.offset) != NULL;
- if (sect_type == eSectionTypeOther)
- {
- switch (mach_sect_type)
- {
- // TODO: categorize sections by other flags for regular sections
- case SectionTypeRegular:
- if (segment_sp->GetName() == g_sect_name_TEXT)
- sect_type = eSectionTypeCode;
- else if (segment_sp->GetName() == g_sect_name_DATA)
- sect_type = eSectionTypeData;
- else
- sect_type = eSectionTypeOther;
- break;
- case SectionTypeZeroFill: sect_type = eSectionTypeZeroFill; break;
- case SectionTypeCStringLiterals: sect_type = eSectionTypeDataCString; break; // section with only literal C strings
- case SectionType4ByteLiterals: sect_type = eSectionTypeData4; break; // section with only 4 byte literals
- case SectionType8ByteLiterals: sect_type = eSectionTypeData8; break; // section with only 8 byte literals
- case SectionTypeLiteralPointers: sect_type = eSectionTypeDataPointers; break; // section with only pointers to literals
- case SectionTypeNonLazySymbolPointers: sect_type = eSectionTypeDataPointers; break; // section with only non-lazy symbol pointers
- case SectionTypeLazySymbolPointers: sect_type = eSectionTypeDataPointers; break; // section with only lazy symbol pointers
- case SectionTypeSymbolStubs: sect_type = eSectionTypeCode; break; // section with only symbol stubs, byte size of stub in the reserved2 field
- case SectionTypeModuleInitFunctionPointers: sect_type = eSectionTypeDataPointers; break; // section with only function pointers for initialization
- case SectionTypeModuleTermFunctionPointers: sect_type = eSectionTypeDataPointers; break; // section with only function pointers for termination
- case SectionTypeCoalesced: sect_type = eSectionTypeOther; break;
- case SectionTypeZeroFillLarge: sect_type = eSectionTypeZeroFill; break;
- case SectionTypeInterposing: sect_type = eSectionTypeCode; break; // section with only pairs of function pointers for interposing
- case SectionType16ByteLiterals: sect_type = eSectionTypeData16; break; // section with only 16 byte literals
- case SectionTypeDTraceObjectFormat: sect_type = eSectionTypeDebug; break;
- case SectionTypeLazyDylibSymbolPointers: sect_type = eSectionTypeDataPointers; break;
- default: break;
- }
- }
+ section_sp->SetIsEncrypted (segment_is_encrypted || section_is_encrypted);
+ segment_sp->GetChildren().AddSection(section_sp);
- SectionSP section_sp(new Section (segment_sp,
- module_sp,
- this,
- ++sectID,
- section_name,
- sect_type,
- sect64.addr - segment_sp->GetFileAddress(),
- sect64.size,
- sect64.offset,
- sect64.offset == 0 ? 0 : sect64.size,
- sect64.flags));
- // Set the section to be encrypted to match the segment
-
- bool section_is_encrypted = false;
- if (!segment_is_encrypted && load_cmd.filesize != 0)
- section_is_encrypted = encrypted_file_ranges.FindEntryThatContains(sect64.offset) != NULL;
-
- section_sp->SetIsEncrypted (segment_is_encrypted || section_is_encrypted);
- segment_sp->GetChildren().AddSection(section_sp);
-
- if (segment_sp->IsFake())
- {
- segment_sp.reset();
- segment_name.Clear();
+ if (segment_sp->IsFake())
+ {
+ segment_sp.reset();
+ const_segname.Clear();
+ }
+ }
}
- }
- if (segment_sp && m_header.filetype == HeaderFileTypeDSYM)
- {
- if (first_segment_sectID <= sectID)
+ if (segment_sp && is_dsym)
{
- lldb::user_id_t sect_uid;
- for (sect_uid = first_segment_sectID; sect_uid <= sectID; ++sect_uid)
+ if (first_segment_sectID <= sectID)
{
- SectionSP curr_section_sp(segment_sp->GetChildren().FindSectionByID (sect_uid));
- SectionSP next_section_sp;
- if (sect_uid + 1 <= sectID)
- next_section_sp = segment_sp->GetChildren().FindSectionByID (sect_uid+1);
-
- if (curr_section_sp.get())
+ lldb::user_id_t sect_uid;
+ for (sect_uid = first_segment_sectID; sect_uid <= sectID; ++sect_uid)
{
- if (curr_section_sp->GetByteSize() == 0)
+ SectionSP curr_section_sp(segment_sp->GetChildren().FindSectionByID (sect_uid));
+ SectionSP next_section_sp;
+ if (sect_uid + 1 <= sectID)
+ next_section_sp = segment_sp->GetChildren().FindSectionByID (sect_uid+1);
+
+ if (curr_section_sp.get())
{
- if (next_section_sp.get() != NULL)
- curr_section_sp->SetByteSize ( next_section_sp->GetFileAddress() - curr_section_sp->GetFileAddress() );
- else
- curr_section_sp->SetByteSize ( load_cmd.vmsize );
+ if (curr_section_sp->GetByteSize() == 0)
+ {
+ if (next_section_sp.get() != NULL)
+ curr_section_sp->SetByteSize ( next_section_sp->GetFileAddress() - curr_section_sp->GetFileAddress() );
+ else
+ curr_section_sp->SetByteSize ( load_cmd.vmsize );
+ }
}
}
}
@@ -1315,22 +1369,20 @@ ObjectFileMachO::ParseSections ()
}
}
}
- }
- else if (load_cmd.cmd == LoadCommandDynamicSymtabInfo)
- {
- m_dysymtab.cmd = load_cmd.cmd;
- m_dysymtab.cmdsize = load_cmd.cmdsize;
- m_data.GetU32 (&offset, &m_dysymtab.ilocalsym, (sizeof(m_dysymtab) / sizeof(uint32_t)) - 2);
- }
+ else if (load_cmd.cmd == LoadCommandDynamicSymtabInfo)
+ {
+ m_dysymtab.cmd = load_cmd.cmd;
+ m_dysymtab.cmdsize = load_cmd.cmdsize;
+ m_data.GetU32 (&offset, &m_dysymtab.ilocalsym, (sizeof(m_dysymtab) / sizeof(uint32_t)) - 2);
+ }
- offset = load_cmd_offset + load_cmd.cmdsize;
+ offset = load_cmd_offset + load_cmd.cmdsize;
+ }
+
+// StreamFile s(stdout, false); // REMOVE THIS LINE
+// s.Printf ("Sections for %s:\n", m_file.GetPath().c_str());// REMOVE THIS LINE
+// m_sections_ap->Dump(&s, NULL, true, UINT32_MAX);// REMOVE THIS LINE
}
-// if (dump_sections)
-// {
-// StreamFile s(stdout);
-// m_sections_ap->Dump(&s, true);
-// }
- return sectID; // Return the number of sections we registered with the module
}
class MachSymtabSectionInfo
@@ -1403,7 +1455,7 @@ protected:
};
size_t
-ObjectFileMachO::ParseSymtab (bool minimize)
+ObjectFileMachO::ParseSymtab ()
{
Timer scoped_timer(__PRETTY_FUNCTION__,
"ObjectFileMachO::ParseSymtab () module = %s",
@@ -2044,8 +2096,7 @@ ObjectFileMachO::ParseSymtab (bool minim
// We don't really need the end function STAB as it contains the size which
// we already placed with the original symbol, so don't add it if we want a
// minimal symbol table
- if (minimize)
- add_nlist = false;
+ add_nlist = false;
}
}
break;
@@ -2067,17 +2118,8 @@ ObjectFileMachO::ParseSymtab (bool minim
// N_BNSYM
// We use the current number of symbols in the symbol table in lieu of
// using nlist_idx in case we ever start trimming entries out
- if (minimize)
- {
- // Skip these if we want minimal symbol tables
- add_nlist = false;
- }
- else
- {
- symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
- N_NSYM_indexes.push_back(sym_idx);
- type = eSymbolTypeScopeBegin;
- }
+ // Skip these if we want minimal symbol tables
+ add_nlist = false;
break;
case StabEndSymbol:
@@ -2085,22 +2127,8 @@ ObjectFileMachO::ParseSymtab (bool minim
// Set the size of the N_BNSYM to the terminating index of this N_ENSYM
// so that we can always skip the entire symbol if we need to navigate
// more quickly at the source level when parsing STABS
- if (minimize)
- {
- // Skip these if we want minimal symbol tables
- add_nlist = false;
- }
- else
- {
- if ( !N_NSYM_indexes.empty() )
- {
- symbol_ptr = symtab->SymbolAtIndex(N_NSYM_indexes.back());
- symbol_ptr->SetByteSize(sym_idx + 1);
- symbol_ptr->SetSizeIsSibling(true);
- N_NSYM_indexes.pop_back();
- }
- type = eSymbolTypeScopeEnd;
- }
+ // Skip these if we want minimal symbol tables
+ add_nlist = false;
break;
@@ -2130,15 +2158,14 @@ ObjectFileMachO::ParseSymtab (bool minim
type = eSymbolTypeSourceFile;
if (symbol_name == NULL)
{
- if (minimize)
- add_nlist = false;
+ add_nlist = false;
if (N_SO_index != UINT32_MAX)
{
// Set the size of the N_SO to the terminating index of this N_SO
// so that we can always skip the entire N_SO if we need to navigate
// more quickly at the source level when parsing STABS
symbol_ptr = symtab->SymbolAtIndex(N_SO_index);
- symbol_ptr->SetByteSize(sym_idx + (minimize ? 0 : 1));
+ symbol_ptr->SetByteSize(sym_idx);
symbol_ptr->SetSizeIsSibling(true);
}
N_NSYM_indexes.clear();
@@ -2155,7 +2182,7 @@ ObjectFileMachO::ParseSymtab (bool minim
const bool N_SO_has_full_path = symbol_name[0] == '/';
if (N_SO_has_full_path)
{
- if (minimize && (N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms))
+ if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms))
{
// We have two consecutive N_SO entries where the first contains a directory
// and the second contains a full path.
@@ -2170,7 +2197,7 @@ ObjectFileMachO::ParseSymtab (bool minim
N_SO_index = sym_idx;
}
}
- else if (minimize && (N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms))
+ else if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms))
{
// This is usually the second N_SO entry that contains just the filename,
// so here we combine it with the first one if we are minimizing the symbol table
@@ -2253,8 +2280,7 @@ ObjectFileMachO::ParseSymtab (bool minim
type = eSymbolTypeHeaderFile;
// We currently don't use the header files on darwin
- if (minimize)
- add_nlist = false;
+ add_nlist = false;
break;
case StabCompilerParameters:
@@ -2503,8 +2529,6 @@ ObjectFileMachO::ParseSymtab (bool minim
if (add_nlist)
{
uint64_t symbol_value = nlist.n_value;
- bool symbol_name_is_mangled = false;
-
if (symbol_name_non_abi_mangled)
{
sym[sym_idx].GetMangled().SetMangledName (ConstString(symbol_name_non_abi_mangled));
@@ -2512,6 +2536,8 @@ ObjectFileMachO::ParseSymtab (bool minim
}
else
{
+ bool symbol_name_is_mangled = false;
+
if (symbol_name && symbol_name[0] == '_')
{
symbol_name_is_mangled = symbol_name[1] == '_';
@@ -2521,9 +2547,9 @@ ObjectFileMachO::ParseSymtab (bool minim
if (symbol_name)
{
ConstString const_symbol_name(symbol_name);
- if (is_gsym)
- N_GSYM_name_to_sym_idx[const_symbol_name.GetCString()] = sym_idx;
sym[sym_idx].GetMangled().SetValue(const_symbol_name, symbol_name_is_mangled);
+ if (is_gsym && is_debug)
+ N_GSYM_name_to_sym_idx[sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled).GetCString()] = sym_idx;
}
}
if (symbol_section)
@@ -2590,8 +2616,7 @@ ObjectFileMachO::ParseSymtab (bool minim
ValueToSymbolIndexMap::const_iterator pos = N_FUN_addr_to_sym_idx.find (nlist.n_value);
if (pos != N_FUN_addr_to_sym_idx.end())
{
- if ((symbol_name_is_mangled == true && sym[sym_idx].GetMangled().GetMangledName() == sym[pos->second].GetMangled().GetMangledName()) ||
- (symbol_name_is_mangled == false && sym[sym_idx].GetMangled().GetDemangledName() == sym[pos->second].GetMangled().GetDemangledName()))
+ if (sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled) == sym[pos->second].GetMangled().GetName(Mangled::ePreferMangled))
{
m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
// We just need the flags from the linker symbol, so put these flags
@@ -2611,8 +2636,7 @@ ObjectFileMachO::ParseSymtab (bool minim
ValueToSymbolIndexMap::const_iterator pos = N_STSYM_addr_to_sym_idx.find (nlist.n_value);
if (pos != N_STSYM_addr_to_sym_idx.end())
{
- if ((symbol_name_is_mangled == true && sym[sym_idx].GetMangled().GetMangledName() == sym[pos->second].GetMangled().GetMangledName()) ||
- (symbol_name_is_mangled == false && sym[sym_idx].GetMangled().GetDemangledName() == sym[pos->second].GetMangled().GetDemangledName()))
+ if (sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled) == sym[pos->second].GetMangled().GetName(Mangled::ePreferMangled))
{
m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
// We just need the flags from the linker symbol, so put these flags
@@ -2625,7 +2649,7 @@ ObjectFileMachO::ParseSymtab (bool minim
else
{
// Combine N_GSYM stab entries with the non stab symbol
- ConstNameToSymbolIndexMap::const_iterator pos = N_GSYM_name_to_sym_idx.find(sym[sym_idx].GetMangled().GetMangledName().GetCString());
+ ConstNameToSymbolIndexMap::const_iterator pos = N_GSYM_name_to_sym_idx.find(sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled).GetCString());
if (pos != N_GSYM_name_to_sym_idx.end())
{
const uint32_t GSYM_sym_idx = pos->second;
@@ -2811,8 +2835,7 @@ ObjectFileMachO::ParseSymtab (bool minim
// We don't really need the end function STAB as it contains the size which
// we already placed with the original symbol, so don't add it if we want a
// minimal symbol table
- if (minimize)
- add_nlist = false;
+ add_nlist = false;
}
}
break;
@@ -2834,17 +2857,8 @@ ObjectFileMachO::ParseSymtab (bool minim
// N_BNSYM
// We use the current number of symbols in the symbol table in lieu of
// using nlist_idx in case we ever start trimming entries out
- if (minimize)
- {
- // Skip these if we want minimal symbol tables
- add_nlist = false;
- }
- else
- {
- symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
- N_NSYM_indexes.push_back(sym_idx);
- type = eSymbolTypeScopeBegin;
- }
+ // Skip these if we want minimal symbol tables
+ add_nlist = false;
break;
case StabEndSymbol:
@@ -2852,22 +2866,8 @@ ObjectFileMachO::ParseSymtab (bool minim
// Set the size of the N_BNSYM to the terminating index of this N_ENSYM
// so that we can always skip the entire symbol if we need to navigate
// more quickly at the source level when parsing STABS
- if (minimize)
- {
- // Skip these if we want minimal symbol tables
- add_nlist = false;
- }
- else
- {
- if ( !N_NSYM_indexes.empty() )
- {
- symbol_ptr = symtab->SymbolAtIndex(N_NSYM_indexes.back());
- symbol_ptr->SetByteSize(sym_idx + 1);
- symbol_ptr->SetSizeIsSibling(true);
- N_NSYM_indexes.pop_back();
- }
- type = eSymbolTypeScopeEnd;
- }
+ // Skip these if we want minimal symbol tables
+ add_nlist = false;
break;
@@ -2897,15 +2897,14 @@ ObjectFileMachO::ParseSymtab (bool minim
type = eSymbolTypeSourceFile;
if (symbol_name == NULL)
{
- if (minimize)
- add_nlist = false;
+ add_nlist = false;
if (N_SO_index != UINT32_MAX)
{
// Set the size of the N_SO to the terminating index of this N_SO
// so that we can always skip the entire N_SO if we need to navigate
// more quickly at the source level when parsing STABS
symbol_ptr = symtab->SymbolAtIndex(N_SO_index);
- symbol_ptr->SetByteSize(sym_idx + (minimize ? 0 : 1));
+ symbol_ptr->SetByteSize(sym_idx);
symbol_ptr->SetSizeIsSibling(true);
}
N_NSYM_indexes.clear();
@@ -2922,7 +2921,7 @@ ObjectFileMachO::ParseSymtab (bool minim
const bool N_SO_has_full_path = symbol_name[0] == '/';
if (N_SO_has_full_path)
{
- if (minimize && (N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms))
+ if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms))
{
// We have two consecutive N_SO entries where the first contains a directory
// and the second contains a full path.
@@ -2937,7 +2936,7 @@ ObjectFileMachO::ParseSymtab (bool minim
N_SO_index = sym_idx;
}
}
- else if (minimize && (N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms))
+ else if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms))
{
// This is usually the second N_SO entry that contains just the filename,
// so here we combine it with the first one if we are minimizing the symbol table
@@ -3021,8 +3020,7 @@ ObjectFileMachO::ParseSymtab (bool minim
type = eSymbolTypeHeaderFile;
// We currently don't use the header files on darwin
- if (minimize)
- add_nlist = false;
+ add_nlist = false;
break;
case StabCompilerParameters:
@@ -3275,7 +3273,6 @@ ObjectFileMachO::ParseSymtab (bool minim
if (add_nlist)
{
uint64_t symbol_value = nlist.n_value;
- bool symbol_name_is_mangled = false;
if (symbol_name_non_abi_mangled)
{
@@ -3284,6 +3281,8 @@ ObjectFileMachO::ParseSymtab (bool minim
}
else
{
+ bool symbol_name_is_mangled = false;
+
if (symbol_name && symbol_name[0] == '_')
{
symbol_name_is_mangled = symbol_name[1] == '_';
@@ -3293,9 +3292,11 @@ ObjectFileMachO::ParseSymtab (bool minim
if (symbol_name)
{
ConstString const_symbol_name(symbol_name);
- if (is_gsym)
- N_GSYM_name_to_sym_idx[const_symbol_name.GetCString()] = sym_idx;
sym[sym_idx].GetMangled().SetValue(const_symbol_name, symbol_name_is_mangled);
+ if (is_gsym && is_debug)
+ {
+ N_GSYM_name_to_sym_idx[sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled).GetCString()] = sym_idx;
+ }
}
}
if (symbol_section)
@@ -3357,8 +3358,7 @@ ObjectFileMachO::ParseSymtab (bool minim
ValueToSymbolIndexMap::const_iterator pos = N_FUN_addr_to_sym_idx.find (nlist.n_value);
if (pos != N_FUN_addr_to_sym_idx.end())
{
- if ((symbol_name_is_mangled == true && sym[sym_idx].GetMangled().GetMangledName() == sym[pos->second].GetMangled().GetMangledName()) ||
- (symbol_name_is_mangled == false && sym[sym_idx].GetMangled().GetDemangledName() == sym[pos->second].GetMangled().GetDemangledName()))
+ if (sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled) == sym[pos->second].GetMangled().GetName(Mangled::ePreferMangled))
{
m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
// We just need the flags from the linker symbol, so put these flags
@@ -3378,8 +3378,7 @@ ObjectFileMachO::ParseSymtab (bool minim
ValueToSymbolIndexMap::const_iterator pos = N_STSYM_addr_to_sym_idx.find (nlist.n_value);
if (pos != N_STSYM_addr_to_sym_idx.end())
{
- if ((symbol_name_is_mangled == true && sym[sym_idx].GetMangled().GetMangledName() == sym[pos->second].GetMangled().GetMangledName()) ||
- (symbol_name_is_mangled == false && sym[sym_idx].GetMangled().GetDemangledName() == sym[pos->second].GetMangled().GetDemangledName()))
+ if (sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled) == sym[pos->second].GetMangled().GetName(Mangled::ePreferMangled))
{
m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
// We just need the flags from the linker symbol, so put these flags
@@ -3392,7 +3391,7 @@ ObjectFileMachO::ParseSymtab (bool minim
else
{
// Combine N_GSYM stab entries with the non stab symbol
- ConstNameToSymbolIndexMap::const_iterator pos = N_GSYM_name_to_sym_idx.find(sym[sym_idx].GetMangled().GetMangledName().GetCString());
+ ConstNameToSymbolIndexMap::const_iterator pos = N_GSYM_name_to_sym_idx.find(sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled).GetCString());
if (pos != N_GSYM_name_to_sym_idx.end())
{
const uint32_t GSYM_sym_idx = pos->second;
@@ -3639,6 +3638,16 @@ ObjectFileMachO::ParseSymtab (bool minim
}
}
}
+
+// StreamFile s(stdout, false);
+// s.Printf ("Symbol table before CalculateSymbolSizes():\n");
+// symtab->Dump(&s, NULL, eSortOrderNone);
+ // Set symbol byte sizes correctly since mach-o nlist entries don't have sizes
+ symtab->CalculateSymbolSizes();
+
+// s.Printf ("Symbol table after CalculateSymbolSizes():\n");
+// symtab->Dump(&s, NULL, eSortOrderNone);
+
return symtab->GetNumSymbols();
}
return 0;
@@ -3663,8 +3672,9 @@ ObjectFileMachO::Dump (Stream *s)
*s << ", file = '" << m_file << "', arch = " << header_arch.GetArchitectureName() << "\n";
- if (m_sections_ap.get())
- m_sections_ap->Dump(s, NULL, true, UINT32_MAX);
+ SectionList *sections = GetSectionList();
+ if (sections)
+ sections->Dump(s, NULL, true, UINT32_MAX);
if (m_symtab_ap.get())
m_symtab_ap->Dump(s, NULL, eSortOrderNone);
Modified: lldb/branches/lldb-platform-work/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h?rev=186540&r1=186539&r2=186540&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h Wed Jul 17 17:17:41 2013
@@ -102,10 +102,13 @@ public:
GetAddressClass (lldb::addr_t file_addr);
virtual lldb_private::Symtab *
- GetSymtab(uint32_t flags = 0);
+ GetSymtab();
- virtual lldb_private::SectionList *
- GetSectionList();
+ virtual bool
+ IsStripped ();
+
+ virtual void
+ CreateSections (lldb_private::SectionList &unified_section_list);
virtual void
Dump (lldb_private::Stream *s);
@@ -195,10 +198,7 @@ protected:
bool m_thread_context_offsets_valid;
size_t
- ParseSections ();
-
- size_t
- ParseSymtab (bool minimize);
+ ParseSymtab ();
};
Modified: lldb/branches/lldb-platform-work/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp?rev=186540&r1=186539&r2=186540&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp Wed Jul 17 17:17:41 2013
@@ -511,7 +511,7 @@ ObjectFilePECOFF::GetSectionName(std::st
// GetNListSymtab
//----------------------------------------------------------------------
Symtab *
-ObjectFilePECOFF::GetSymtab(uint32_t flags)
+ObjectFilePECOFF::GetSymtab()
{
ModuleSP module_sp(GetModule());
if (module_sp)
@@ -597,16 +597,26 @@ ObjectFilePECOFF::GetSymtab(uint32_t fla
}
-SectionList *
-ObjectFilePECOFF::GetSectionList()
+bool
+ObjectFilePECOFF::IsStripped ()
{
- ModuleSP module_sp(GetModule());
- if (module_sp)
+ // TODO: determine this for COFF
+ return false;
+}
+
+
+
+void
+ObjectFilePECOFF::CreateSections (SectionList &unified_section_list)
+{
+ if (!m_sections_ap.get())
{
- lldb_private::Mutex::Locker locker(module_sp->GetMutex());
- if (m_sections_ap.get() == NULL)
+ m_sections_ap.reset(new SectionList());
+
+ ModuleSP module_sp(GetModule());
+ if (module_sp)
{
- m_sections_ap.reset(new SectionList());
+ lldb_private::Mutex::Locker locker(module_sp->GetMutex());
const uint32_t nsects = m_sect_headers.size();
ModuleSP module_sp (GetModule());
for (uint32_t idx = 0; idx<nsects; ++idx)
@@ -710,13 +720,11 @@ ObjectFilePECOFF::GetSectionList()
//section_sp->SetIsEncrypted (segment_is_encrypted);
- m_sections_ap->AddSection(section_sp);
+ unified_section_list.AddSection(section_sp);
+ m_sections_ap->AddSection (section_sp);
}
-
- m_sections_ap->Finalize(); // Now that we're done adding sections, finalize to build fast-lookup caches
}
}
- return m_sections_ap.get();
}
bool
@@ -754,8 +762,9 @@ ObjectFilePECOFF::Dump(Stream *s)
*s << ", file = '" << m_file << "', arch = " << header_arch.GetArchitectureName() << "\n";
- if (m_sections_ap.get())
- m_sections_ap->Dump(s, NULL, true, UINT32_MAX);
+ SectionList *sections = GetSectionList();
+ if (sections)
+ sections->Dump(s, NULL, true, UINT32_MAX);
if (m_symtab_ap.get())
m_symtab_ap->Dump(s, NULL, eSortOrderNone);
Modified: lldb/branches/lldb-platform-work/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h?rev=186540&r1=186539&r2=186540&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h Wed Jul 17 17:17:41 2013
@@ -86,10 +86,13 @@ public:
// GetAddressClass (lldb::addr_t file_addr);
//
virtual lldb_private::Symtab *
- GetSymtab(uint32_t flags = 0);
+ GetSymtab ();
- virtual lldb_private::SectionList *
- GetSectionList();
+ virtual bool
+ IsStripped ();
+
+ virtual void
+ CreateSections (lldb_private::SectionList &unified_section_list);
virtual void
Dump (lldb_private::Stream *s);
Modified: lldb/branches/lldb-platform-work/source/Plugins/Process/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/Process/CMakeLists.txt?rev=186540&r1=186539&r2=186540&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/Process/CMakeLists.txt (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/Process/CMakeLists.txt Wed Jul 17 17:17:41 2013
@@ -1,13 +1,14 @@
if (CMAKE_SYSTEM_NAME MATCHES "Linux")
add_subdirectory(Linux)
add_subdirectory(POSIX)
+ add_subdirectory(elf-core)
elseif (CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
add_subdirectory(FreeBSD)
add_subdirectory(POSIX)
+ add_subdirectory(elf-core)
elseif (CMAKE_SYSTEM_NAME MATCHES "Darwin")
add_subdirectory(MacOSX-Kernel)
endif()
-
add_subdirectory(gdb-remote)
add_subdirectory(Utility)
add_subdirectory(mach-core)
Modified: lldb/branches/lldb-platform-work/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp?rev=186540&r1=186539&r2=186540&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp Wed Jul 17 17:17:41 2013
@@ -240,7 +240,7 @@ ReadOperation::Execute(ProcessMonitor *m
}
//------------------------------------------------------------------------------
-/// @class ReadOperation
+/// @class WriteOperation
/// @brief Implements ProcessMonitor::WriteMemory.
class WriteOperation : public Operation
{
@@ -275,13 +275,16 @@ WriteOperation::Execute(ProcessMonitor *
class ReadRegOperation : public Operation
{
public:
- ReadRegOperation(unsigned offset, unsigned size, RegisterValue &value, bool &result)
- : m_offset(offset), m_size(size), m_value(value), m_result(result)
+ ReadRegOperation(lldb::tid_t tid, unsigned offset, unsigned size,
+ RegisterValue &value, bool &result)
+ : m_tid(tid), m_offset(offset), m_size(size),
+ m_value(value), m_result(result)
{ }
void Execute(ProcessMonitor *monitor);
private:
+ lldb::tid_t m_tid;
unsigned m_offset;
unsigned m_size;
RegisterValue &m_value;
@@ -291,11 +294,10 @@ private:
void
ReadRegOperation::Execute(ProcessMonitor *monitor)
{
- lldb::pid_t pid = monitor->GetPID();
struct reg regs;
int rc;
- if ((rc = PTRACE(PT_GETREGS, pid, (caddr_t)®s, 0)) < 0) {
+ if ((rc = PTRACE(PT_GETREGS, m_tid, (caddr_t)®s, 0)) < 0) {
m_result = false;
} else {
if (m_size == sizeof(uintptr_t))
@@ -312,13 +314,16 @@ ReadRegOperation::Execute(ProcessMonitor
class WriteRegOperation : public Operation
{
public:
- WriteRegOperation(unsigned offset, const RegisterValue &value, bool &result)
- : m_offset(offset), m_value(value), m_result(result)
+ WriteRegOperation(lldb::tid_t tid, unsigned offset,
+ const RegisterValue &value, bool &result)
+ : m_tid(tid), m_offset(offset),
+ m_value(value), m_result(result)
{ }
void Execute(ProcessMonitor *monitor);
private:
+ lldb::tid_t m_tid;
unsigned m_offset;
const RegisterValue &m_value;
bool &m_result;
@@ -327,15 +332,14 @@ private:
void
WriteRegOperation::Execute(ProcessMonitor *monitor)
{
- lldb::pid_t pid = monitor->GetPID();
struct reg regs;
- if (PTRACE(PT_GETREGS, pid, (caddr_t)®s, 0) < 0) {
+ if (PTRACE(PT_GETREGS, m_tid, (caddr_t)®s, 0) < 0) {
m_result = false;
return;
}
*(uintptr_t *)(((caddr_t)®s) + m_offset) = (uintptr_t)m_value.GetAsUInt64();
- if (PTRACE(PT_SETREGS, pid, (caddr_t)®s, 0) < 0)
+ if (PTRACE(PT_SETREGS, m_tid, (caddr_t)®s, 0) < 0)
m_result = false;
else
m_result = true;
@@ -347,13 +351,14 @@ WriteRegOperation::Execute(ProcessMonito
class ReadGPROperation : public Operation
{
public:
- ReadGPROperation(void *buf, bool &result)
- : m_buf(buf), m_result(result)
+ ReadGPROperation(lldb::tid_t tid, void *buf, bool &result)
+ : m_tid(tid), m_buf(buf), m_result(result)
{ }
void Execute(ProcessMonitor *monitor);
private:
+ lldb::tid_t m_tid;
void *m_buf;
bool &m_result;
};
@@ -364,7 +369,7 @@ ReadGPROperation::Execute(ProcessMonitor
int rc;
errno = 0;
- rc = PTRACE(PT_GETREGS, monitor->GetPID(), (caddr_t)m_buf, 0);
+ rc = PTRACE(PT_GETREGS, m_tid, (caddr_t)m_buf, 0);
if (errno != 0)
m_result = false;
else
@@ -377,13 +382,14 @@ ReadGPROperation::Execute(ProcessMonitor
class ReadFPROperation : public Operation
{
public:
- ReadFPROperation(void *buf, bool &result)
- : m_buf(buf), m_result(result)
+ ReadFPROperation(lldb::tid_t tid, void *buf, bool &result)
+ : m_tid(tid), m_buf(buf), m_result(result)
{ }
void Execute(ProcessMonitor *monitor);
private:
+ lldb::tid_t m_tid;
void *m_buf;
bool &m_result;
};
@@ -391,7 +397,7 @@ private:
void
ReadFPROperation::Execute(ProcessMonitor *monitor)
{
- if (PTRACE(PT_GETFPREGS, monitor->GetPID(), (caddr_t)m_buf, 0) < 0)
+ if (PTRACE(PT_GETFPREGS, m_tid, (caddr_t)m_buf, 0) < 0)
m_result = false;
else
m_result = true;
@@ -403,13 +409,14 @@ ReadFPROperation::Execute(ProcessMonitor
class WriteGPROperation : public Operation
{
public:
- WriteGPROperation(void *buf, bool &result)
- : m_buf(buf), m_result(result)
+ WriteGPROperation(lldb::tid_t tid, void *buf, bool &result)
+ : m_tid(tid), m_buf(buf), m_result(result)
{ }
void Execute(ProcessMonitor *monitor);
private:
+ lldb::tid_t m_tid;
void *m_buf;
bool &m_result;
};
@@ -417,7 +424,7 @@ private:
void
WriteGPROperation::Execute(ProcessMonitor *monitor)
{
- if (PTRACE(PT_SETREGS, monitor->GetPID(), (caddr_t)m_buf, 0) < 0)
+ if (PTRACE(PT_SETREGS, m_tid, (caddr_t)m_buf, 0) < 0)
m_result = false;
else
m_result = true;
@@ -429,13 +436,14 @@ WriteGPROperation::Execute(ProcessMonito
class WriteFPROperation : public Operation
{
public:
- WriteFPROperation(void *buf, bool &result)
- : m_buf(buf), m_result(result)
+ WriteFPROperation(lldb::tid_t tid, void *buf, bool &result)
+ : m_tid(tid), m_buf(buf), m_result(result)
{ }
void Execute(ProcessMonitor *monitor);
private:
+ lldb::tid_t m_tid;
void *m_buf;
bool &m_result;
};
@@ -443,7 +451,7 @@ private:
void
WriteFPROperation::Execute(ProcessMonitor *monitor)
{
- if (PTRACE(PT_SETFPREGS, monitor->GetPID(), (caddr_t)m_buf, 0) < 0)
+ if (PTRACE(PT_SETFPREGS, m_tid, (caddr_t)m_buf, 0) < 0)
m_result = false;
else
m_result = true;
@@ -518,12 +526,12 @@ SingleStepOperation::Execute(ProcessMoni
}
//------------------------------------------------------------------------------
-/// @class SiginfoOperation
-/// @brief Implements ProcessMonitor::GetSignalInfo.
-class SiginfoOperation : public Operation
+/// @class LwpInfoOperation
+/// @brief Implements ProcessMonitor::GetLwpInfo.
+class LwpInfoOperation : public Operation
{
public:
- SiginfoOperation(lldb::tid_t tid, void *info, bool &result, int &ptrace_err)
+ LwpInfoOperation(lldb::tid_t tid, void *info, bool &result, int &ptrace_err)
: m_tid(tid), m_info(info), m_result(result), m_err(ptrace_err) { }
void Execute(ProcessMonitor *monitor);
@@ -536,7 +544,7 @@ private:
};
void
-SiginfoOperation::Execute(ProcessMonitor *monitor)
+LwpInfoOperation::Execute(ProcessMonitor *monitor)
{
struct ptrace_lwpinfo plwp;
@@ -544,7 +552,7 @@ SiginfoOperation::Execute(ProcessMonitor
m_result = false;
m_err = errno;
} else {
- memcpy(m_info, &plwp.pl_siginfo, sizeof(siginfo_t));
+ memcpy(m_info, &plwp, sizeof(plwp));
m_result = true;
}
}
@@ -1097,7 +1105,7 @@ ProcessMonitor::MonitorCallback(void *ca
ProcessFreeBSD *process = monitor->m_process;
assert(process);
bool stop_monitoring;
- siginfo_t info;
+ struct ptrace_lwpinfo plwp;
int ptrace_err;
Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
@@ -1111,17 +1119,17 @@ ProcessMonitor::MonitorCallback(void *ca
return pid == process->GetID();
}
- if (!monitor->GetSignalInfo(pid, &info, ptrace_err))
+ if (!monitor->GetLwpInfo(pid, &plwp, ptrace_err))
stop_monitoring = true; // pid is gone. Bail.
else {
- switch (info.si_signo)
+ switch (plwp.pl_siginfo.si_signo)
{
case SIGTRAP:
- message = MonitorSIGTRAP(monitor, &info, pid);
+ message = MonitorSIGTRAP(monitor, &plwp.pl_siginfo, pid);
break;
default:
- message = MonitorSignal(monitor, &info, pid);
+ message = MonitorSignal(monitor, &plwp.pl_siginfo, pid);
break;
}
@@ -1482,7 +1490,7 @@ ProcessMonitor::ReadRegisterValue(lldb::
unsigned size, RegisterValue &value)
{
bool result;
- ReadRegOperation op(offset, size, value, result);
+ ReadRegOperation op(tid, offset, size, value, result);
DoOperation(&op);
return result;
}
@@ -1492,7 +1500,7 @@ ProcessMonitor::WriteRegisterValue(lldb:
const char* reg_name, const RegisterValue &value)
{
bool result;
- WriteRegOperation op(offset, value, result);
+ WriteRegOperation op(tid, offset, value, result);
DoOperation(&op);
return result;
}
@@ -1501,7 +1509,7 @@ bool
ProcessMonitor::ReadGPR(lldb::tid_t tid, void *buf, size_t buf_size)
{
bool result;
- ReadGPROperation op(buf, result);
+ ReadGPROperation op(tid, buf, result);
DoOperation(&op);
return result;
}
@@ -1510,7 +1518,7 @@ bool
ProcessMonitor::ReadFPR(lldb::tid_t tid, void *buf, size_t buf_size)
{
bool result;
- ReadFPROperation op(buf, result);
+ ReadFPROperation op(tid, buf, result);
DoOperation(&op);
return result;
}
@@ -1525,7 +1533,7 @@ bool
ProcessMonitor::WriteGPR(lldb::tid_t tid, void *buf, size_t buf_size)
{
bool result;
- WriteGPROperation op(buf, result);
+ WriteGPROperation op(tid, buf, result);
DoOperation(&op);
return result;
}
@@ -1534,7 +1542,7 @@ bool
ProcessMonitor::WriteFPR(lldb::tid_t tid, void *buf, size_t buf_size)
{
bool result;
- WriteFPROperation op(buf, result);
+ WriteFPROperation op(tid, buf, result);
DoOperation(&op);
return result;
}
@@ -1580,10 +1588,10 @@ ProcessMonitor::BringProcessIntoLimbo()
}
bool
-ProcessMonitor::GetSignalInfo(lldb::tid_t tid, void *siginfo, int &ptrace_err)
+ProcessMonitor::GetLwpInfo(lldb::tid_t tid, void *lwpinfo, int &ptrace_err)
{
bool result;
- SiginfoOperation op(tid, siginfo, result, ptrace_err);
+ LwpInfoOperation op(tid, lwpinfo, result, ptrace_err);
DoOperation(&op);
return result;
}
Modified: lldb/branches/lldb-platform-work/source/Plugins/Process/FreeBSD/ProcessMonitor.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/Process/FreeBSD/ProcessMonitor.h?rev=186540&r1=186539&r2=186540&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/Process/FreeBSD/ProcessMonitor.h (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/Process/FreeBSD/ProcessMonitor.h Wed Jul 17 17:17:41 2013
@@ -160,10 +160,10 @@ public:
bool
WriteRegisterSet(lldb::tid_t tid, void *buf, size_t buf_size, unsigned int regset);
- /// Writes a siginfo_t structure corresponding to the given thread ID to the
- /// memory region pointed to by @p siginfo.
+ /// Writes a ptrace_lwpinfo structure corresponding to the given thread ID
+ /// to the memory region pointed to by @p lwpinfo.
bool
- GetSignalInfo(lldb::tid_t tid, void *siginfo, int &error_no);
+ GetLwpInfo(lldb::tid_t tid, void *lwpinfo, int &error_no);
/// Writes the raw event message code (vis-a-vis PTRACE_GETEVENTMSG)
/// corresponding to the given thread IDto the memory pointed to by @p
@@ -190,6 +190,8 @@ public:
lldb_private::Error
Detach(lldb::tid_t tid);
+ void
+ StopMonitor();
private:
ProcessFreeBSD *m_process;
@@ -309,9 +311,6 @@ private:
void
StopMonitoringChildProcess();
- void
- StopMonitor();
-
/// Stops the operation thread used to attach/launch a process.
void
StopOpThread();
Removed: lldb/branches/lldb-platform-work/source/Plugins/Process/FreeBSD/RegisterContextFreeBSD_x86_64.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/Process/FreeBSD/RegisterContextFreeBSD_x86_64.h?rev=186539&view=auto
==============================================================================
(empty)
Modified: lldb/branches/lldb-platform-work/source/Plugins/Process/Linux/ProcessLinux.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/Process/Linux/ProcessLinux.cpp?rev=186540&r1=186539&r2=186540&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/Process/Linux/ProcessLinux.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/Process/Linux/ProcessLinux.cpp Wed Jul 17 17:17:41 2013
@@ -32,9 +32,9 @@ using namespace lldb_private;
// Static functions.
ProcessSP
-ProcessLinux::CreateInstance(Target &target, Listener &listener, const FileSpec *)
+ProcessLinux::CreateInstance(Target &target, Listener &listener, const FileSpec *core_file)
{
- return ProcessSP(new ProcessLinux(target, listener));
+ return ProcessSP(new ProcessLinux(target, listener, (FileSpec *)core_file));
}
void
@@ -63,8 +63,8 @@ ProcessLinux::Initialize()
//------------------------------------------------------------------------------
// Constructors and destructors.
-ProcessLinux::ProcessLinux(Target& target, Listener &listener)
- : ProcessPOSIX(target, listener), m_stopping_threads(false)
+ProcessLinux::ProcessLinux(Target& target, Listener &listener, FileSpec *core_file)
+ : ProcessPOSIX(target, listener), m_stopping_threads(false), m_core_file(core_file)
{
#if 0
// FIXME: Putting this code in the ctor and saving the byte order in a
@@ -170,3 +170,17 @@ ProcessLinux::StopAllThreads(lldb::tid_t
if (log)
log->Printf ("ProcessLinux::%s() finished", __FUNCTION__);
}
+
+bool
+ProcessLinux::CanDebug(Target &target, bool plugin_specified_by_name)
+{
+ if (plugin_specified_by_name)
+ return true;
+
+ /* If core file is specified then let elf-core plugin handle it */
+ if (m_core_file)
+ return false;
+
+ return ProcessPOSIX::CanDebug(target, plugin_specified_by_name);
+}
+
Modified: lldb/branches/lldb-platform-work/source/Plugins/Process/Linux/ProcessLinux.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/Process/Linux/ProcessLinux.h?rev=186540&r1=186539&r2=186540&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/Process/Linux/ProcessLinux.h (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/Process/Linux/ProcessLinux.h Wed Jul 17 17:17:41 2013
@@ -51,7 +51,8 @@ public:
// Constructors and destructors
//------------------------------------------------------------------
ProcessLinux(lldb_private::Target& target,
- lldb_private::Listener &listener);
+ lldb_private::Listener &listener,
+ lldb_private::FileSpec *core_file);
virtual bool
UpdateThreadList(lldb_private::ThreadList &old_thread_list, lldb_private::ThreadList &new_thread_list);
@@ -84,6 +85,9 @@ public:
return m_linux_signals;
}
+ virtual bool
+ CanDebug(lldb_private::Target &target, bool plugin_specified_by_name);
+
//------------------------------------------------------------------
// ProcessPOSIX overrides
//------------------------------------------------------------------
@@ -95,6 +99,8 @@ private:
/// Linux-specific signal set.
LinuxSignals m_linux_signals;
+ lldb_private::FileSpec *m_core_file;
+
// Flag to avoid recursion when stopping all threads.
bool m_stopping_threads;
};
Modified: lldb/branches/lldb-platform-work/source/Plugins/Process/Linux/ProcessMonitor.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/Process/Linux/ProcessMonitor.cpp?rev=186540&r1=186539&r2=186540&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/Process/Linux/ProcessMonitor.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/Process/Linux/ProcessMonitor.cpp Wed Jul 17 17:17:41 2013
@@ -419,7 +419,7 @@ ReadOperation::Execute(ProcessMonitor *m
}
//------------------------------------------------------------------------------
-/// @class ReadOperation
+/// @class WriteOperation
/// @brief Implements ProcessMonitor::WriteMemory.
class WriteOperation : public Operation
{
@@ -1098,6 +1098,7 @@ ProcessMonitor::Launch(LaunchArgs *args)
lldb::pid_t pid;
lldb::ThreadSP inferior;
+ POSIXThread *thread;
Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
// Propagate the environment if one is not supplied.
@@ -1232,10 +1233,16 @@ ProcessMonitor::Launch(LaunchArgs *args)
// FIXME: should we be letting UpdateThreadList handle this?
// FIXME: by using pids instead of tids, we can only support one thread.
inferior.reset(new POSIXThread(process, pid));
+
+ thread = static_cast<POSIXThread*>(inferior.get());
+ thread->SetName(Host::GetThreadName(pid, pid).c_str());
+
if (log)
log->Printf ("ProcessMonitor::%s() adding pid = %" PRIu64, __FUNCTION__, pid);
process.GetThreadList().AddThread(inferior);
+ process.AddThreadForInitialStopIfNeeded(pid);
+
// Let our process instance know the thread has stopped.
process.SendMessage(ProcessMessage::Trace(pid));
@@ -1290,11 +1297,11 @@ ProcessMonitor::Attach(AttachArgs *args)
ProcessMonitor *monitor = args->m_monitor;
ProcessLinux &process = monitor->GetProcess();
lldb::ThreadSP inferior;
+ POSIXThread *thread;
Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
// Use a map to keep track of the threads which we have attached/need to attach.
Host::TidMap tids_to_attach;
-
if (pid <= 1)
{
args->m_error.SetErrorToGenericError();
@@ -1356,10 +1363,15 @@ ProcessMonitor::Attach(AttachArgs *args)
// Update the process thread list with the attached thread.
inferior.reset(new POSIXThread(process, tid));
+
+ thread = static_cast<POSIXThread*>(inferior.get());
+ thread->SetName(Host::GetThreadName(pid, tid).c_str());
+
if (log)
log->Printf ("ProcessMonitor::%s() adding tid = %" PRIu64, __FUNCTION__, tid);
process.GetThreadList().AddThread(inferior);
it->second = true;
+ process.AddThreadForInitialStopIfNeeded(tid);
}
}
}
@@ -1513,7 +1525,7 @@ ProcessMonitor::MonitorSIGTRAP(ProcessMo
if (!monitor->GetEventMessage(pid, &data))
data = -1;
if (log)
- log->Printf ("ProcessMonitor::%s() received exit event, data = %lx, pid = %" PRIu64, __FUNCTION__, data, pid);
+ log->Printf ("ProcessMonitor::%s() received limbo event, data = %lx, pid = %" PRIu64, __FUNCTION__, data, pid);
message = ProcessMessage::Limbo(pid, (data >> 8));
break;
}
@@ -1537,6 +1549,13 @@ ProcessMonitor::MonitorSIGTRAP(ProcessMo
log->Printf ("ProcessMonitor::%s() received watchpoint event, pid = %" PRIu64, __FUNCTION__, pid);
message = ProcessMessage::Watch(pid, (lldb::addr_t)info->si_addr);
break;
+
+ case SIGTRAP:
+ case (SIGTRAP | 0x80):
+ if (log)
+ log->Printf ("ProcessMonitor::%s() received system call stop event, pid = %" PRIu64, __FUNCTION__, pid);
+ // Ignore these signals until we know more about them
+ monitor->Resume(pid, eResumeSignalNone);
}
return message;
@@ -1711,6 +1730,27 @@ ProcessMonitor::StopThread(lldb::tid_t t
return true;
break;
+ case ProcessMessage::eSignalMessage:
+ if (log)
+ log->Printf ("ProcessMonitor::%s(bp) handling message", __FUNCTION__);
+ if (WSTOPSIG(status) == SIGSTOP)
+ {
+ m_process->AddThreadForInitialStopIfNeeded(tid);
+ thread->SetState(lldb::eStateStopped);
+ }
+ else
+ {
+ m_process->SendMessage(message);
+ // This isn't the stop we were expecting, but the thread is
+ // stopped. SendMessage will handle processing of this event,
+ // but we need to resume here to get the stop we are waiting
+ // for (otherwise the thread will stop again immediately when
+ // we try to resume).
+ if (wait_pid == tid)
+ Resume(wait_pid, eResumeSignalNone);
+ }
+ break;
+
case ProcessMessage::eSignalDeliveredMessage:
// This is the stop we're expecting.
if (wait_pid == tid && WIFSTOPPED(status) && WSTOPSIG(status) == SIGSTOP && info.si_code == SI_TKILL)
@@ -1721,7 +1761,6 @@ ProcessMonitor::StopThread(lldb::tid_t t
return true;
}
// else fall-through
- case ProcessMessage::eSignalMessage:
case ProcessMessage::eBreakpointMessage:
case ProcessMessage::eTraceMessage:
case ProcessMessage::eWatchpointMessage:
Modified: lldb/branches/lldb-platform-work/source/Plugins/Process/Linux/ProcessMonitor.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/Process/Linux/ProcessMonitor.h?rev=186540&r1=186539&r2=186540&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/Process/Linux/ProcessMonitor.h (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/Process/Linux/ProcessMonitor.h Wed Jul 17 17:17:41 2013
@@ -177,6 +177,10 @@ public:
lldb_private::Error
Detach(lldb::tid_t tid);
+ /// Stops the monitoring the child process thread.
+ void
+ StopMonitor();
+
/// Stops the requested thread and waits for the stop signal.
bool
StopThread(lldb::tid_t tid);
@@ -302,9 +306,6 @@ private:
void
StopMonitoringChildProcess();
- void
- StopMonitor();
-
/// Stops the operation thread used to attach/launch a process.
void
StopOpThread();
Removed: lldb/branches/lldb-platform-work/source/Plugins/Process/Linux/RegisterContextLinux_x86_64.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/Process/Linux/RegisterContextLinux_x86_64.h?rev=186539&view=auto
==============================================================================
(empty)
Modified: lldb/branches/lldb-platform-work/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp?rev=186540&r1=186539&r2=186540&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp Wed Jul 17 17:17:41 2013
@@ -124,19 +124,48 @@ CommunicationKDP::SendRequestAndGetReply
if (SendRequestPacketNoLock(request_packet))
{
const uint8_t request_sequence_id = (uint8_t)request_packet.GetData()[1];
- if (WaitForPacketWithTimeoutMicroSecondsNoLock (reply_packet, GetPacketTimeoutInMicroSeconds ()))
+ while (1)
{
- offset = 0;
- const uint8_t reply_command = reply_packet.GetU8 (&offset);
- const uint8_t reply_sequence_id = reply_packet.GetU8 (&offset);
- if ((reply_command & eCommandTypeMask) == command)
+ if (WaitForPacketWithTimeoutMicroSecondsNoLock (reply_packet, GetPacketTimeoutInMicroSeconds ()))
{
+ offset = 0;
+ const uint8_t reply_command = reply_packet.GetU8 (&offset);
+ const uint8_t reply_sequence_id = reply_packet.GetU8 (&offset);
if (request_sequence_id == reply_sequence_id)
{
- if (command == KDP_RESUMECPUS)
- m_is_running.SetValue(true, eBroadcastAlways);
- return true;
+ // The sequent ID was correct, now verify we got the response we were looking for
+ if ((reply_command & eCommandTypeMask) == command)
+ {
+ // Success
+ if (command == KDP_RESUMECPUS)
+ m_is_running.SetValue(true, eBroadcastAlways);
+ return true;
+ }
+ else
+ {
+ // Failed to get the correct response, bail
+ reply_packet.Clear();
+ return false;
+ }
}
+ else if (reply_sequence_id > request_sequence_id)
+ {
+ // Sequence ID was greater than the sequence ID of the packet we sent, something
+ // is really wrong...
+ reply_packet.Clear();
+ return false;
+ }
+ else
+ {
+ // The reply sequence ID was less than our current packet's sequence ID
+ // so we should keep trying to get a response because this was a response
+ // for a previous packet that we must have retried.
+ }
+ }
+ else
+ {
+ // Break and retry sending the packet as we didn't get a response due to timeout
+ break;
}
}
}
Modified: lldb/branches/lldb-platform-work/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp?rev=186540&r1=186539&r2=186540&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp Wed Jul 17 17:17:41 2013
@@ -44,6 +44,63 @@
using namespace lldb;
using namespace lldb_private;
+namespace {
+
+ static PropertyDefinition
+ g_properties[] =
+ {
+ { "packet-timeout" , OptionValue::eTypeUInt64 , true , 5, NULL, NULL, "Specify the default packet timeout in seconds." },
+ { NULL , OptionValue::eTypeInvalid, false, 0, NULL, NULL, NULL }
+ };
+
+ enum
+ {
+ ePropertyPacketTimeout
+ };
+
+ class PluginProperties : public Properties
+ {
+ public:
+
+ static ConstString
+ GetSettingName ()
+ {
+ return ProcessKDP::GetPluginNameStatic();
+ }
+
+ PluginProperties() :
+ Properties ()
+ {
+ m_collection_sp.reset (new OptionValueProperties(GetSettingName()));
+ m_collection_sp->Initialize(g_properties);
+ }
+
+ virtual
+ ~PluginProperties()
+ {
+ }
+
+ uint64_t
+ GetPacketTimeout()
+ {
+ const uint32_t idx = ePropertyPacketTimeout;
+ return m_collection_sp->GetPropertyAtIndexAsUInt64(NULL, idx, g_properties[idx].default_uint_value);
+ }
+ };
+
+ typedef std::shared_ptr<PluginProperties> ProcessKDPPropertiesSP;
+
+ static const ProcessKDPPropertiesSP &
+ GetGlobalPluginProperties()
+ {
+ static ProcessKDPPropertiesSP g_settings_sp;
+ if (!g_settings_sp)
+ g_settings_sp.reset (new PluginProperties ());
+ return g_settings_sp;
+ }
+
+} // anonymous namespace end
+
static const lldb::tid_t g_kernel_tid = 1;
ConstString
@@ -124,6 +181,9 @@ ProcessKDP::ProcessKDP(Target& target, L
{
m_async_broadcaster.SetEventName (eBroadcastBitAsyncThreadShouldExit, "async thread should exit");
m_async_broadcaster.SetEventName (eBroadcastBitAsyncContinue, "async thread continue");
+ const uint64_t timeout_seconds = GetGlobalPluginProperties()->GetPacketTimeout();
+ if (timeout_seconds > 0)
+ m_comm.SetPacketTimeout(timeout_seconds);
}
//----------------------------------------------------------------------
@@ -716,7 +776,8 @@ ProcessKDP::Initialize()
g_initialized = true;
PluginManager::RegisterPlugin (GetPluginNameStatic(),
GetPluginDescriptionStatic(),
- CreateInstance);
+ CreateInstance,
+ DebuggerInitialize);
Log::Callbacks log_callbacks = {
ProcessKDPLog::DisableLog,
@@ -728,6 +789,19 @@ ProcessKDP::Initialize()
}
}
+void
+ProcessKDP::DebuggerInitialize (lldb_private::Debugger &debugger)
+{
+ if (!PluginManager::GetSettingForProcessPlugin(debugger, PluginProperties::GetSettingName()))
+ {
+ const bool is_global_setting = true;
+ PluginManager::CreateSettingForProcessPlugin (debugger,
+ GetGlobalPluginProperties()->GetValueProperties(),
+ ConstString ("Properties for the kdp-remote process plug-in."),
+ is_global_setting);
+ }
+}
+
bool
ProcessKDP::StartAsyncThread ()
{
Modified: lldb/branches/lldb-platform-work/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h?rev=186540&r1=186539&r2=186540&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h Wed Jul 17 17:17:41 2013
@@ -48,6 +48,9 @@ public:
Initialize();
static void
+ DebuggerInitialize (lldb_private::Debugger &debugger);
+
+ static void
Terminate();
static lldb_private::ConstString
Modified: lldb/branches/lldb-platform-work/source/Plugins/Process/POSIX/POSIXThread.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/Process/POSIX/POSIXThread.cpp?rev=186540&r1=186539&r2=186540&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/Process/POSIX/POSIXThread.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/Process/POSIX/POSIXThread.cpp Wed Jul 17 17:17:41 2013
@@ -16,12 +16,14 @@
// Other libraries and framework includes
// Project includes
#include "lldb/Breakpoint/Watchpoint.h"
+#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/State.h"
#include "lldb/Host/Host.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/StopInfo.h"
#include "lldb/Target/Target.h"
+#include "lldb/Target/ThreadSpec.h"
#include "POSIXStopInfo.h"
#include "POSIXThread.h"
#include "ProcessPOSIX.h"
@@ -41,7 +43,9 @@ using namespace lldb_private;
POSIXThread::POSIXThread(Process &process, lldb::tid_t tid)
: Thread(process, tid),
- m_frame_ap()
+ m_frame_ap (),
+ m_breakpoint (),
+ m_thread_name ()
{
Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
@@ -104,6 +108,23 @@ POSIXThread::GetInfo()
return NULL;
}
+void
+POSIXThread::SetName (const char *name)
+{
+ if (name && name[0])
+ m_thread_name.assign (name);
+ else
+ m_thread_name.clear();
+}
+
+const char *
+POSIXThread::GetName ()
+{
+ if (m_thread_name.empty())
+ return NULL;
+ return m_thread_name.c_str();
+}
+
lldb::RegisterContextSP
POSIXThread::GetRegisterContext()
{
@@ -364,15 +385,33 @@ POSIXThread::BreakNotify(const ProcessMe
if (log)
log->Printf ("POSIXThread::%s () PC=0x%8.8" PRIx64, __FUNCTION__, pc);
lldb::BreakpointSiteSP bp_site(GetProcess()->GetBreakpointSiteList().FindByAddress(pc));
- assert(bp_site);
- lldb::break_id_t bp_id = bp_site->GetID();
- assert(bp_site && bp_site->ValidForThisThread(this));
- // Make this thread the selected thread
- GetProcess()->GetThreadList().SetSelectedThreadByID(GetID());
+ // If the breakpoint is for this thread, then we'll report the hit, but if it is for another thread,
+ // we can just report no reason. We don't need to worry about stepping over the breakpoint here, that
+ // will be taken care of when the thread resumes and notices that there's a breakpoint under the pc.
+ if (bp_site && bp_site->ValidForThisThread(this))
+ {
+ lldb::break_id_t bp_id = bp_site->GetID();
+ if (GetProcess()->GetThreadList().SetSelectedThreadByID(GetID()))
+ SetStopInfo (StopInfo::CreateStopReasonWithBreakpointSiteID(*this, bp_id));
+ else
+ assert(false && "Invalid thread ID during BreakNotify.");
+ }
+ else
+ {
+ const ThreadSpec *spec = bp_site ?
+ bp_site->GetOwnerAtIndex(0)->GetOptionsNoCreate()->GetThreadSpecNoCreate() : 0;
- m_breakpoint = bp_site;
- SetStopInfo (StopInfo::CreateStopReasonWithBreakpointSiteID(*this, bp_id));
+ if (spec && spec->TIDMatches(*this))
+ assert(false && "BreakpointSite is invalid for the current ThreadSpec.");
+ else
+ {
+ if (!m_stop_info_sp) {
+ StopInfoSP invalid_stop_info_sp;
+ SetStopInfo (invalid_stop_info_sp);
+ }
+ }
+ }
}
void
Modified: lldb/branches/lldb-platform-work/source/Plugins/Process/POSIX/POSIXThread.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/Process/POSIX/POSIXThread.h?rev=186540&r1=186539&r2=186540&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/Process/POSIX/POSIXThread.h (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/Process/POSIX/POSIXThread.h Wed Jul 17 17:17:41 2013
@@ -13,6 +13,7 @@
// C Includes
// C++ Includes
#include <memory>
+#include <string>
// Other libraries and framework includes
#include "lldb/Target/Thread.h"
@@ -46,6 +47,12 @@ public:
const char *
GetInfo();
+ void
+ SetName (const char *name);
+
+ const char *
+ GetName ();
+
virtual lldb::RegisterContextSP
GetRegisterContext();
@@ -100,6 +107,8 @@ private:
lldb::BreakpointSiteSP m_breakpoint;
+ std::string m_thread_name;
+
ProcessMonitor &
GetMonitor();
Modified: lldb/branches/lldb-platform-work/source/Plugins/Process/POSIX/ProcessPOSIX.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/Process/POSIX/ProcessPOSIX.cpp?rev=186540&r1=186539&r2=186540&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/Process/POSIX/ProcessPOSIX.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/Process/POSIX/ProcessPOSIX.cpp Wed Jul 17 17:17:41 2013
@@ -76,7 +76,8 @@ ProcessPOSIX::ProcessPOSIX(Target& targe
m_monitor(NULL),
m_module(NULL),
m_message_mutex (Mutex::eMutexTypeRecursive),
- m_exit_now(false)
+ m_exit_now(false),
+ m_seen_initial_stop()
{
// FIXME: Putting this code in the ctor and saving the byte order in a
// member variable is a hack to avoid const qual issues in GetByteOrder.
@@ -92,6 +93,14 @@ ProcessPOSIX::~ProcessPOSIX()
//------------------------------------------------------------------------------
// Process protocol.
+void
+ProcessPOSIX::Finalize()
+{
+ Process::Finalize();
+
+ if (m_monitor)
+ m_monitor->StopMonitor();
+}
bool
ProcessPOSIX::CanDebug(Target &target, bool plugin_specified_by_name)
@@ -135,6 +144,8 @@ ProcessPOSIX::DoAttachToProcessWithID(ll
m_target.GetArchitecture(),
exe_module_sp,
executable_search_paths.GetSize() ? &executable_search_paths : NULL);
+ if (!error.Success())
+ return error;
// Fix the target architecture if necessary
const ArchSpec &module_arch = exe_module_sp->GetArchitecture();
@@ -144,9 +155,6 @@ ProcessPOSIX::DoAttachToProcessWithID(ll
// Initialize the target module list
m_target.SetExecutableModule (exe_module_sp, true);
- if (!error.Success())
- return error;
-
SetSTDIOFileDescriptor(m_monitor->GetTerminalFD());
SetID(pid);
@@ -313,9 +321,9 @@ ProcessPOSIX::DoDetach(bool keep_stopped
Error error;
if (keep_stopped)
{
- // FIXME: If you want to implement keep_stopped on Linux,
+ // FIXME: If you want to implement keep_stopped,
// this would be the place to do it.
- error.SetErrorString("Detaching with keep_stopped true is not currently supported on Linux.");
+ error.SetErrorString("Detaching with keep_stopped true is not currently supported on this platform.");
return error;
}
@@ -413,13 +421,10 @@ ProcessPOSIX::SendMessage(const ProcessM
m_exit_status = message.GetExitStatus();
SetExitStatus(m_exit_status, NULL);
}
+ else if (!IsAThreadRunning())
+ SetPrivateState(eStateStopped);
break;
- case ProcessMessage::eBreakpointMessage:
- case ProcessMessage::eTraceMessage:
- case ProcessMessage::eWatchpointMessage:
- case ProcessMessage::eNewThreadMessage:
- case ProcessMessage::eCrashMessage:
assert(thread);
thread->SetState(eStateStopped);
StopAllThreads(message.GetTID());
@@ -428,21 +433,21 @@ ProcessPOSIX::SendMessage(const ProcessM
case ProcessMessage::eSignalMessage:
case ProcessMessage::eSignalDeliveredMessage:
- {
- lldb::tid_t tid = message.GetTID();
- lldb::tid_t pid = GetID();
- if (tid == pid) {
- assert(thread);
- thread->SetState(eStateStopped);
- StopAllThreads(message.GetTID());
- SetPrivateState(eStateStopped);
- break;
- } else {
- // FIXME: Ignore any signals generated by children.
+ if (message.GetSignal() == SIGSTOP &&
+ AddThreadForInitialStopIfNeeded(message.GetTID()))
return;
- }
- }
+ // Intentional fall-through
+ case ProcessMessage::eBreakpointMessage:
+ case ProcessMessage::eTraceMessage:
+ case ProcessMessage::eWatchpointMessage:
+ case ProcessMessage::eNewThreadMessage:
+ case ProcessMessage::eCrashMessage:
+ assert(thread);
+ thread->SetState(eStateStopped);
+ StopAllThreads(message.GetTID());
+ SetPrivateState(eStateStopped);
+ break;
}
m_message_queue.push(message);
@@ -454,6 +459,19 @@ ProcessPOSIX::StopAllThreads(lldb::tid_t
// FIXME: Will this work the same way on FreeBSD and Linux?
}
+bool
+ProcessPOSIX::AddThreadForInitialStopIfNeeded(lldb::tid_t stop_tid)
+{
+ bool added_to_set = false;
+ ThreadStopSet::iterator it = m_seen_initial_stop.find(stop_tid);
+ if (it == m_seen_initial_stop.end())
+ {
+ m_seen_initial_stop.insert(stop_tid);
+ added_to_set = true;
+ }
+ return added_to_set;
+}
+
void
ProcessPOSIX::RefreshStateAfterStop()
{
@@ -481,8 +499,13 @@ ProcessPOSIX::RefreshStateAfterStop()
{
if (log)
log->Printf ("ProcessPOSIX::%s() adding thread, tid = %" PRIi64, __FUNCTION__, message.GetChildTID());
+ lldb::tid_t child_tid = message.GetChildTID();
ThreadSP thread_sp;
- thread_sp.reset(new POSIXThread(*this, message.GetChildTID()));
+ thread_sp.reset(new POSIXThread(*this, child_tid));
+
+ POSIXThread *thread = static_cast<POSIXThread*>(thread_sp.get());
+ thread->SetName(Host::GetThreadName(GetID(), child_tid).c_str());
+
m_thread_list.AddThread(thread_sp);
}
@@ -498,6 +521,7 @@ ProcessPOSIX::RefreshStateAfterStop()
log->Printf ("ProcessPOSIX::%s() removing thread, tid = %" PRIi64, __FUNCTION__, tid);
ThreadSP thread_sp = m_thread_list.RemoveThreadByID(tid, false);
thread_sp.reset();
+ m_seen_initial_stop.erase(tid);
}
m_message_queue.pop();
@@ -854,3 +878,22 @@ ProcessPOSIX::IsStopped()
return false;
}
+
+bool
+ProcessPOSIX::IsAThreadRunning()
+{
+ bool is_running = false;
+ uint32_t thread_count = m_thread_list.GetSize(false);
+ for (uint32_t i = 0; i < thread_count; ++i)
+ {
+ POSIXThread *thread = static_cast<POSIXThread*>(
+ m_thread_list.GetThreadAtIndex(i, false).get());
+ StateType thread_state = thread->GetState();
+ if (thread_state == eStateRunning || thread_state == eStateStepping)
+ {
+ is_running = true;
+ break;
+ }
+ }
+ return is_running;
+}
Modified: lldb/branches/lldb-platform-work/source/Plugins/Process/POSIX/ProcessPOSIX.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/Process/POSIX/ProcessPOSIX.h?rev=186540&r1=186539&r2=186540&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/Process/POSIX/ProcessPOSIX.h (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/Process/POSIX/ProcessPOSIX.h Wed Jul 17 17:17:41 2013
@@ -14,6 +14,7 @@
// C++ Includes
#include <queue>
+#include <set>
// Other libraries and framework includes
#include "lldb/Target/Process.h"
@@ -39,6 +40,9 @@ public:
//------------------------------------------------------------------
// Process protocol.
//------------------------------------------------------------------
+ virtual void
+ Finalize();
+
virtual bool
CanDebug(lldb_private::Target &target, bool plugin_specified_by_name);
@@ -157,6 +161,11 @@ public:
virtual void
StopAllThreads(lldb::tid_t stop_tid);
+ /// Adds the thread to the list of threads for which we have received the initial stopping signal.
+ /// The \p stop_tid paramter indicates the thread which the stop happened for.
+ bool
+ AddThreadForInitialStopIfNeeded(lldb::tid_t stop_tid);
+
protected:
/// Target byte order.
lldb::ByteOrder m_byte_order;
@@ -183,8 +192,16 @@ protected:
/// Returns true if the process is stopped.
bool IsStopped();
+ /// Returns true if at least one running is currently running
+ bool IsAThreadRunning();
+
typedef std::map<lldb::addr_t, lldb::addr_t> MMapMap;
MMapMap m_addr_to_mmap_size;
+
+ typedef std::set<lldb::tid_t> ThreadStopSet;
+ /// Every thread begins with a stop signal. This keeps track
+ /// of the threads for which we have received the stop signal.
+ ThreadStopSet m_seen_initial_stop;
};
#endif // liblldb_MacOSXProcess_H_
Modified: lldb/branches/lldb-platform-work/source/Plugins/Process/POSIX/RegisterContext_x86_64.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/Process/POSIX/RegisterContext_x86_64.cpp?rev=186540&r1=186539&r2=186540&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/Process/POSIX/RegisterContext_x86_64.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/Process/POSIX/RegisterContext_x86_64.cpp Wed Jul 17 17:17:41 2013
@@ -21,10 +21,13 @@
#include "llvm/Support/Compiler.h"
#include "ProcessPOSIX.h"
+#if defined(__linux__) or defined(__FreeBSD__)
#include "ProcessMonitor.h"
+#endif
#include "RegisterContext_i386.h"
#include "RegisterContext_x86.h"
#include "RegisterContext_x86_64.h"
+#include "Plugins/Process/elf-core/ProcessElfCore.h"
using namespace lldb_private;
using namespace lldb;
@@ -497,6 +500,11 @@ RegisterContext_x86_64::RegisterContext_
::memset(&m_fpr, 0, sizeof(RegisterContext_x86_64::FPR));
+ // elf-core yet to support ReadFPR()
+ ProcessSP base = CalculateProcess();
+ if (base.get()->GetPluginName() == ProcessElfCore::GetPluginNameStatic())
+ return;
+
// TODO: Use assembly to call cpuid on the inferior and query ebx or ecx
m_fpr_type = eXSAVE; // extended floating-point registers, if available
if (false == ReadFPR())
@@ -507,14 +515,6 @@ RegisterContext_x86_64::~RegisterContext
{
}
-ProcessMonitor &
-RegisterContext_x86_64::GetMonitor()
-{
- ProcessSP base = CalculateProcess();
- ProcessPOSIX *process = static_cast<ProcessPOSIX*>(base.get());
- return process->GetMonitor();
-}
-
void
RegisterContext_x86_64::Invalidate()
{
@@ -696,9 +696,7 @@ RegisterContext_x86_64::ReadRegister(con
return false;
}
else {
- ProcessMonitor &monitor = GetMonitor();
- bool success = monitor.ReadRegisterValue(m_thread.GetID(), GetRegisterOffset(reg),
- GetRegisterName(reg), GetRegisterSize(reg), value);
+ bool success = ReadRegister(reg, value);
// If an i386 register should be parsed from an x86_64 register...
if (success && reg >= k_first_i386 && reg <= k_last_i386)
@@ -801,8 +799,7 @@ RegisterContext_x86_64::WriteRegister(co
{
const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
if (IsGPR(reg)) {
- ProcessMonitor &monitor = GetMonitor();
- return monitor.WriteRegisterValue(m_thread.GetID(), GetRegisterOffset(reg), GetRegisterName(reg), value);
+ return WriteRegister(reg, value);
}
if (IsFPR(reg, m_fpr_type)) {
@@ -898,29 +895,6 @@ RegisterContext_x86_64::WriteAllRegister
}
bool
-RegisterContext_x86_64::ReadRegister(const unsigned reg,
- RegisterValue &value)
-{
- ProcessMonitor &monitor = GetMonitor();
- return monitor.ReadRegisterValue(m_thread.GetID(),
- GetRegisterOffset(reg),
- GetRegisterName(reg),
- GetRegisterSize(reg),
- value);
-}
-
-bool
-RegisterContext_x86_64::WriteRegister(const unsigned reg,
- const RegisterValue &value)
-{
- ProcessMonitor &monitor = GetMonitor();
- return monitor.WriteRegisterValue(m_thread.GetID(),
- GetRegisterOffset(reg),
- GetRegisterName(reg),
- value);
-}
-
-bool
RegisterContext_x86_64::UpdateAfterBreakpoint()
{
// PC points one byte past the int3 responsible for the breakpoint.
@@ -1469,6 +1443,16 @@ RegisterContext_x86_64::HardwareSingleSt
return WriteRegisterFromUnsigned(gpr_rflags, rflags);
}
+#if defined(__linux__) or defined(__FreeBSD__)
+
+ProcessMonitor &
+RegisterContext_x86_64::GetMonitor()
+{
+ ProcessSP base = CalculateProcess();
+ ProcessPOSIX *process = static_cast<ProcessPOSIX*>(base.get());
+ return process->GetMonitor();
+}
+
bool
RegisterContext_x86_64::ReadGPR()
{
@@ -1507,3 +1491,73 @@ RegisterContext_x86_64::WriteFPR()
return false;
}
+bool
+RegisterContext_x86_64::ReadRegister(const unsigned reg,
+ RegisterValue &value)
+{
+ ProcessMonitor &monitor = GetMonitor();
+ return monitor.ReadRegisterValue(m_thread.GetID(),
+ GetRegisterOffset(reg),
+ GetRegisterName(reg),
+ GetRegisterSize(reg),
+ value);
+}
+
+bool
+RegisterContext_x86_64::WriteRegister(const unsigned reg,
+ const RegisterValue &value)
+{
+ ProcessMonitor &monitor = GetMonitor();
+ return monitor.WriteRegisterValue(m_thread.GetID(),
+ GetRegisterOffset(reg),
+ GetRegisterName(reg),
+ value);
+}
+
+#else
+
+bool
+RegisterContext_x86_64::ReadGPR()
+{
+ llvm_unreachable("not implemented");
+ return false;
+}
+
+bool
+RegisterContext_x86_64::ReadFPR()
+{
+ llvm_unreachable("not implemented");
+ return false;
+}
+
+bool
+RegisterContext_x86_64::WriteGPR()
+{
+ llvm_unreachable("not implemented");
+ return false;
+}
+
+bool
+RegisterContext_x86_64::WriteFPR()
+{
+ llvm_unreachable("not implemented");
+ return false;
+}
+
+bool
+RegisterContext_x86_64::ReadRegister(const unsigned reg,
+ RegisterValue &value)
+{
+ llvm_unreachable("not implemented");
+ return false;
+}
+
+bool
+RegisterContext_x86_64::WriteRegister(const unsigned reg,
+ const RegisterValue &value)
+{
+ llvm_unreachable("not implemented");
+ return false;
+}
+
+#endif
Modified: lldb/branches/lldb-platform-work/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp?rev=186540&r1=186539&r2=186540&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp Wed Jul 17 17:17:41 2013
@@ -76,11 +76,11 @@ bool lldb_private::InferiorCallMmap(Proc
if (sc.GetAddressRange(range_scope, 0, use_inline_block_range, mmap_range))
{
ClangASTContext *clang_ast_context = process->GetTarget().GetScratchClangASTContext();
- lldb::clang_type_t clang_void_ptr_type = clang_ast_context->GetVoidPtrType(false);
+ ClangASTType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
ThreadPlanCallFunction *call_function_thread_plan
= new ThreadPlanCallFunction (*thread,
mmap_range.GetBaseAddress(),
- ClangASTType (clang_ast_context->getASTContext(), clang_void_ptr_type),
+ clang_void_ptr_type,
stop_other_threads,
unwind_on_error,
ignore_breakpoints,
@@ -222,11 +222,11 @@ bool lldb_private::InferiorCall(Process
const uint32_t timeout_usec = 500000;
ClangASTContext *clang_ast_context = process->GetTarget().GetScratchClangASTContext();
- lldb::clang_type_t clang_void_ptr_type = clang_ast_context->GetVoidPtrType(false);
+ ClangASTType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
ThreadPlanCallFunction *call_function_thread_plan
= new ThreadPlanCallFunction (*thread,
*address,
- ClangASTType (clang_ast_context->getASTContext(), clang_void_ptr_type),
+ clang_void_ptr_type,
stop_other_threads,
unwind_on_error,
ignore_breakpoints);
Modified: lldb/branches/lldb-platform-work/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/Process/Utility/RegisterContextLLDB.cpp?rev=186540&r1=186539&r2=186540&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/Process/Utility/RegisterContextLLDB.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/Process/Utility/RegisterContextLLDB.cpp Wed Jul 17 17:17:41 2013
@@ -1179,7 +1179,7 @@ RegisterContextLLDB::SavedLocationForReg
dwarfexpr.SetRegisterKind (unwindplan_registerkind);
Value result;
Error error;
- if (dwarfexpr.Evaluate (&exe_ctx, NULL, NULL, NULL, this, 0, NULL, result, &error))
+ if (dwarfexpr.Evaluate (&exe_ctx, NULL, NULL, this, 0, NULL, result, &error))
{
addr_t val;
val = result.GetScalar().ULongLong();
Modified: lldb/branches/lldb-platform-work/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h?rev=186540&r1=186539&r2=186540&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h Wed Jul 17 17:17:41 2013
@@ -288,14 +288,6 @@ public:
return GetVContSupported ('a');
}
- uint32_t
- SetPacketTimeout (uint32_t packet_timeout)
- {
- const uint32_t old_packet_timeout = m_packet_timeout;
- m_packet_timeout = packet_timeout;
- return old_packet_timeout;
- }
-
bool
GetStopReply (StringExtractorGDBRemote &response);
Modified: lldb/branches/lldb-platform-work/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp?rev=186540&r1=186539&r2=186540&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp Wed Jul 17 17:17:41 2013
@@ -83,11 +83,68 @@ namespace lldb
}
}
-
#define DEBUGSERVER_BASENAME "debugserver"
using namespace lldb;
using namespace lldb_private;
+
+namespace {
+
+ static PropertyDefinition
+ g_properties[] =
+ {
+ { "packet-timeout" , OptionValue::eTypeUInt64 , true , 1, NULL, NULL, "Specify the default packet timeout in seconds." },
+ { NULL , OptionValue::eTypeInvalid, false, 0, NULL, NULL, NULL }
+ };
+
+ enum
+ {
+ ePropertyPacketTimeout
+ };
+
+ class PluginProperties : public Properties
+ {
+ public:
+
+ static ConstString
+ GetSettingName ()
+ {
+ return ProcessGDBRemote::GetPluginNameStatic();
+ }
+
+ PluginProperties() :
+ Properties ()
+ {
+ m_collection_sp.reset (new OptionValueProperties(GetSettingName()));
+ m_collection_sp->Initialize(g_properties);
+ }
+
+ virtual
+ ~PluginProperties()
+ {
+ }
+
+ uint64_t
+ GetPacketTimeout()
+ {
+ const uint32_t idx = ePropertyPacketTimeout;
+ return m_collection_sp->GetPropertyAtIndexAsUInt64(NULL, idx, g_properties[idx].default_uint_value);
+ }
+ };
+
+ typedef std::shared_ptr<PluginProperties> ProcessKDPPropertiesSP;
+
+ static const ProcessKDPPropertiesSP &
+ GetGlobalPluginProperties()
+ {
+ static ProcessKDPPropertiesSP g_settings_sp;
+ if (!g_settings_sp)
+ g_settings_sp.reset (new PluginProperties ());
+ return g_settings_sp;
+ }
+
+} // anonymous namespace end
+
static bool rand_initialized = false;
// TODO Randomly assigning a port is unsafe. We should get an unused
@@ -208,6 +265,9 @@ ProcessGDBRemote::ProcessGDBRemote(Targe
m_async_broadcaster.SetEventName (eBroadcastBitAsyncThreadShouldExit, "async thread should exit");
m_async_broadcaster.SetEventName (eBroadcastBitAsyncContinue, "async thread continue");
m_async_broadcaster.SetEventName (eBroadcastBitAsyncThreadDidExit, "async thread did exit");
+ const uint64_t timeout_seconds = GetGlobalPluginProperties()->GetPacketTimeout();
+ if (timeout_seconds > 0)
+ m_gdb_comm.SetPacketTimeout(timeout_seconds);
}
//----------------------------------------------------------------------
@@ -2642,7 +2702,8 @@ ProcessGDBRemote::Initialize()
g_initialized = true;
PluginManager::RegisterPlugin (GetPluginNameStatic(),
GetPluginDescriptionStatic(),
- CreateInstance);
+ CreateInstance,
+ DebuggerInitialize);
Log::Callbacks log_callbacks = {
ProcessGDBRemoteLog::DisableLog,
@@ -2654,6 +2715,19 @@ ProcessGDBRemote::Initialize()
}
}
+void
+ProcessGDBRemote::DebuggerInitialize (lldb_private::Debugger &debugger)
+{
+ if (!PluginManager::GetSettingForProcessPlugin(debugger, PluginProperties::GetSettingName()))
+ {
+ const bool is_global_setting = true;
+ PluginManager::CreateSettingForProcessPlugin (debugger,
+ GetGlobalPluginProperties()->GetValueProperties(),
+ ConstString ("Properties for the gdb-remote process plug-in."),
+ is_global_setting);
+ }
+}
+
bool
ProcessGDBRemote::StartAsyncThread ()
{
Modified: lldb/branches/lldb-platform-work/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h?rev=186540&r1=186539&r2=186540&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h Wed Jul 17 17:17:41 2013
@@ -49,6 +49,9 @@ public:
Initialize();
static void
+ DebuggerInitialize (lldb_private::Debugger &debugger);
+
+ static void
Terminate();
static lldb_private::ConstString
Modified: lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp?rev=186540&r1=186539&r2=186540&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp Wed Jul 17 17:17:41 2013
@@ -1475,6 +1475,16 @@ DWARFDebugInfoEntry::GetName
DWARFFormValue form_value;
if (GetAttributeValue(dwarf2Data, cu, DW_AT_name, form_value))
return form_value.AsCString(&dwarf2Data->get_debug_str_data());
+ else
+ {
+ if (GetAttributeValue(dwarf2Data, cu, DW_AT_specification, form_value))
+ {
+ DWARFCompileUnitSP cu_sp_ptr;
+ const DWARFDebugInfoEntry* die = const_cast<SymbolFileDWARF*>(dwarf2Data)->DebugInfo()->GetDIEPtr(form_value.Reference(cu), &cu_sp_ptr);
+ if (die)
+ return die->GetName(dwarf2Data, cu_sp_ptr.get());
+ }
+ }
return NULL;
}
Modified: lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.cpp?rev=186540&r1=186539&r2=186540&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.cpp Wed Jul 17 17:17:41 2013
@@ -82,7 +82,15 @@ DWARFDeclContext::operator==(const DWARF
for (pos = begin, rhs_pos = rhs_begin; pos != end; ++pos, ++rhs_pos)
{
if (pos->tag != rhs_pos->tag)
+ {
+ // Check for DW_TAG_structure_type and DW_TAG_class_type as they are often
+ // used interchangeably in GCC
+ if (pos->tag == DW_TAG_structure_type && rhs_pos->tag == DW_TAG_class_type)
+ continue;
+ if (pos->tag == DW_TAG_class_type && rhs_pos->tag == DW_TAG_structure_type)
+ continue;
return false;
+ }
}
// The tags all match, now compare the names
for (pos = begin, rhs_pos = rhs_begin; pos != end; ++pos, ++rhs_pos)
Modified: lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp?rev=186540&r1=186539&r2=186540&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp Wed Jul 17 17:17:41 2013
@@ -407,11 +407,11 @@ SymbolFileDWARF::GetTypes (SymbolContext
// });
// }
- std::set<clang_type_t> clang_type_set;
+ std::set<ClangASTType> clang_type_set;
size_t num_types_added = 0;
for (Type *type : type_set)
{
- clang_type_t clang_type = type->GetClangForwardType();
+ ClangASTType clang_type = type->GetClangForwardType();
if (clang_type_set.find(clang_type) == clang_type_set.end())
{
clang_type_set.insert(clang_type);
@@ -543,7 +543,7 @@ SymbolFileDWARF::InitializeObject()
ModuleSP module_sp (m_obj_file->GetModule());
if (module_sp)
{
- const SectionList *section_list = module_sp->GetUnifiedSectionList();
+ const SectionList *section_list = module_sp->GetSectionList();
const Section* section = section_list->FindSectionByName(GetDWARFMachOSegmentName ()).get();
@@ -706,7 +706,7 @@ SymbolFileDWARF::GetCachedSectionData (u
{
ModuleSP module_sp (m_obj_file->GetModule());
m_flags.Set (got_flag);
- const SectionList *section_list = module_sp->GetUnifiedSectionList();
+ const SectionList *section_list = module_sp->GetSectionList();
if (section_list)
{
SectionSP section_sp (section_list->FindSectionByType(sect_type, true));
@@ -1056,7 +1056,7 @@ SymbolFileDWARF::ParseCompileUnitFunctio
if (lowest_func_addr != LLDB_INVALID_ADDRESS && lowest_func_addr <= highest_func_addr)
{
ModuleSP module_sp (m_obj_file->GetModule());
- func_range.GetBaseAddress().ResolveAddressUsingFileSections (lowest_func_addr, module_sp->GetUnifiedSectionList());
+ func_range.GetBaseAddress().ResolveAddressUsingFileSections (lowest_func_addr, module_sp->GetSectionList());
if (func_range.GetBaseAddress().IsValid())
func_range.SetByteSize(highest_func_addr - lowest_func_addr);
}
@@ -1424,7 +1424,7 @@ SymbolFileDWARF::ParseTemplateDIE (DWARF
attributes);
const char *name = NULL;
Type *lldb_type = NULL;
- clang_type_t clang_type = NULL;
+ ClangASTType clang_type;
uint64_t uval64 = 0;
bool uval64_valid = false;
if (num_attributes > 0)
@@ -1465,7 +1465,7 @@ SymbolFileDWARF::ParseTemplateDIE (DWARF
clang::ASTContext *ast = GetClangASTContext().getASTContext();
if (!clang_type)
- clang_type = ast->VoidTy.getAsOpaquePtr();
+ clang_type = GetClangASTContext().GetBasicType(eBasicTypeVoid);
if (clang_type)
{
@@ -1475,20 +1475,19 @@ SymbolFileDWARF::ParseTemplateDIE (DWARF
else
template_param_infos.names.push_back(NULL);
- clang::QualType clang_qual_type (clang::QualType::getFromOpaquePtr (clang_type));
if (tag == DW_TAG_template_value_parameter &&
lldb_type != NULL &&
- ClangASTContext::IsIntegerType (clang_type, is_signed) &&
+ clang_type.IsIntegerType (is_signed) &&
uval64_valid)
{
llvm::APInt apint (lldb_type->GetByteSize() * 8, uval64, is_signed);
template_param_infos.args.push_back (clang::TemplateArgument (*ast,
llvm::APSInt(apint),
- clang_qual_type));
+ clang_type.GetQualType()));
}
else
{
- template_param_infos.args.push_back (clang::TemplateArgument (clang_qual_type));
+ template_param_infos.args.push_back (clang::TemplateArgument (clang_type.GetQualType()));
}
}
else
@@ -1565,17 +1564,15 @@ class SymbolFileDWARF::DelayedAddObjCCla
public:
DelayedAddObjCClassProperty
(
- clang::ASTContext *ast,
- lldb::clang_type_t class_opaque_type,
+ const ClangASTType &class_opaque_type,
const char *property_name,
- lldb::clang_type_t property_opaque_type, // The property type is only required if you don't have an ivar decl
+ const ClangASTType &property_opaque_type, // The property type is only required if you don't have an ivar decl
clang::ObjCIvarDecl *ivar_decl,
const char *property_setter_name,
const char *property_getter_name,
uint32_t property_attributes,
const ClangASTMetadata *metadata
) :
- m_ast (ast),
m_class_opaque_type (class_opaque_type),
m_property_name (property_name),
m_property_opaque_type (property_opaque_type),
@@ -1593,12 +1590,11 @@ public:
DelayedAddObjCClassProperty (const DelayedAddObjCClassProperty &rhs)
{
- *this = rhs;
+ *this = rhs;
}
DelayedAddObjCClassProperty& operator= (const DelayedAddObjCClassProperty &rhs)
{
- m_ast = rhs.m_ast;
m_class_opaque_type = rhs.m_class_opaque_type;
m_property_name = rhs.m_property_name;
m_property_opaque_type = rhs.m_property_opaque_type;
@@ -1615,23 +1611,21 @@ public:
return *this;
}
- bool Finalize() const
+ bool
+ Finalize()
{
- return ClangASTContext::AddObjCClassProperty (m_ast,
- m_class_opaque_type,
- m_property_name,
- m_property_opaque_type,
- m_ivar_decl,
- m_property_setter_name,
- m_property_getter_name,
- m_property_attributes,
- m_metadata_ap.get());
+ return m_class_opaque_type.AddObjCClassProperty (m_property_name,
+ m_property_opaque_type,
+ m_ivar_decl,
+ m_property_setter_name,
+ m_property_getter_name,
+ m_property_attributes,
+ m_metadata_ap.get());
}
private:
- clang::ASTContext *m_ast;
- lldb::clang_type_t m_class_opaque_type;
+ ClangASTType m_class_opaque_type;
const char *m_property_name;
- lldb::clang_type_t m_property_opaque_type;
+ ClangASTType m_property_opaque_type;
clang::ObjCIvarDecl *m_ivar_decl;
const char *m_property_setter_name;
const char *m_property_getter_name;
@@ -1693,7 +1687,7 @@ SymbolFileDWARF::ParseChildMembers
const SymbolContext& sc,
DWARFCompileUnit* dwarf_cu,
const DWARFDebugInfoEntry *parent_die,
- clang_type_t class_clang_type,
+ ClangASTType &class_clang_type,
const LanguageType class_language,
std::vector<clang::CXXBaseSpecifier *>& base_classes,
std::vector<int>& member_accessibilities,
@@ -1772,7 +1766,6 @@ SymbolFileDWARF::ParseChildMembers
uint32_t block_length = form_value.Unsigned();
uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
if (DWARFExpression::Evaluate(NULL, // ExecutionContext *
- NULL, // clang::ASTContext *
NULL, // ClangExpressionVariableList *
NULL, // ClangExpressionDeclMap *
NULL, // RegisterContext *
@@ -1784,7 +1777,7 @@ SymbolFileDWARF::ParseChildMembers
memberOffset,
NULL))
{
- member_byte_offset = memberOffset.ResolveValue(NULL, NULL).UInt();
+ member_byte_offset = memberOffset.ResolveValue(NULL).UInt();
}
}
break;
@@ -1884,17 +1877,18 @@ SymbolFileDWARF::ParseChildMembers
is_artificial = true;
}
- // Skip static members
+ // Handle static members
if (is_external && member_byte_offset == UINT32_MAX)
{
Type *var_type = ResolveTypeUID(encoding_uid);
if (var_type)
{
- GetClangASTContext().AddVariableToRecordType (class_clang_type,
- name,
- var_type->GetClangLayoutType(),
- accessibility);
+ if (accessibility == eAccessNone)
+ accessibility = eAccessPublic;
+ class_clang_type.AddVariableToRecordType (name,
+ var_type->GetClangLayoutType(),
+ accessibility);
}
break;
}
@@ -2008,32 +2002,30 @@ SymbolFileDWARF::ParseChildMembers
if (anon_field_info.IsValid())
{
- clang::FieldDecl *unnamed_bitfield_decl = GetClangASTContext().AddFieldToRecordType (class_clang_type,
- NULL,
- GetClangASTContext().GetBuiltinTypeForEncodingAndBitSize(eEncodingSint, word_width),
- accessibility,
- anon_field_info.bit_size);
+ clang::FieldDecl *unnamed_bitfield_decl = class_clang_type.AddFieldToRecordType (NULL,
+ GetClangASTContext().GetBuiltinTypeForEncodingAndBitSize(eEncodingSint, word_width),
+ accessibility,
+ anon_field_info.bit_size);
layout_info.field_offsets.insert(std::make_pair(unnamed_bitfield_decl, anon_field_info.bit_offset));
}
}
}
- clang_type_t member_clang_type = member_type->GetClangLayoutType();
+ ClangASTType member_clang_type = member_type->GetClangLayoutType();
{
// Older versions of clang emit array[0] and array[1] in the same way (<rdar://problem/12566646>).
// If the current field is at the end of the structure, then there is definitely no room for extra
// elements and we override the type to array[0].
- clang_type_t member_array_element_type;
+ ClangASTType member_array_element_type;
uint64_t member_array_size;
bool member_array_is_incomplete;
- if (GetClangASTContext().IsArrayType(member_clang_type,
- &member_array_element_type,
- &member_array_size,
- &member_array_is_incomplete) &&
+ if (member_clang_type.IsArrayType(&member_array_element_type,
+ &member_array_size,
+ &member_array_is_incomplete) &&
!member_array_is_incomplete)
{
uint64_t parent_byte_size = parent_die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_byte_size, UINT64_MAX);
@@ -2054,11 +2046,10 @@ SymbolFileDWARF::ParseChildMembers
}
}
- field_decl = GetClangASTContext().AddFieldToRecordType (class_clang_type,
- name,
- member_clang_type,
- accessibility,
- bit_size);
+ field_decl = class_clang_type.AddFieldToRecordType (name,
+ member_clang_type,
+ accessibility,
+ bit_size);
GetClangASTContext().SetMetadataAsUserID (field_decl, MakeUserID(die->GetOffset()));
@@ -2094,8 +2085,7 @@ SymbolFileDWARF::ParseChildMembers
ClangASTMetadata metadata;
metadata.SetUserID (MakeUserID(die->GetOffset()));
- delayed_properties.push_back(DelayedAddObjCClassProperty(GetClangASTContext().getASTContext(),
- class_clang_type,
+ delayed_properties.push_back(DelayedAddObjCClassProperty(class_clang_type,
prop_name,
member_type->GetClangLayoutType(),
ivar_decl,
@@ -2162,7 +2152,6 @@ SymbolFileDWARF::ParseChildMembers
if (DWARFExpression::Evaluate (NULL,
NULL,
NULL,
- NULL,
NULL,
debug_info_data,
block_offset,
@@ -2172,7 +2161,7 @@ SymbolFileDWARF::ParseChildMembers
memberOffset,
NULL))
{
- member_byte_offset = memberOffset.ResolveValue(NULL, NULL).UInt();
+ member_byte_offset = memberOffset.ResolveValue(NULL).UInt();
}
}
break;
@@ -2192,27 +2181,26 @@ SymbolFileDWARF::ParseChildMembers
Type *base_class_type = ResolveTypeUID(encoding_uid);
assert(base_class_type);
- clang_type_t base_class_clang_type = base_class_type->GetClangFullType();
+ ClangASTType base_class_clang_type = base_class_type->GetClangFullType();
assert (base_class_clang_type);
if (class_language == eLanguageTypeObjC)
{
- GetClangASTContext().SetObjCSuperClass(class_clang_type, base_class_clang_type);
+ class_clang_type.SetObjCSuperClass(base_class_clang_type);
}
else
{
- base_classes.push_back (GetClangASTContext().CreateBaseClassSpecifier (base_class_clang_type,
- accessibility,
+ base_classes.push_back (base_class_clang_type.CreateBaseClassSpecifier (accessibility,
is_virtual,
is_base_of_class));
if (is_virtual)
{
- layout_info.vbase_offsets.insert(std::make_pair(ClangASTType::GetAsCXXRecordDecl(class_clang_type),
+ layout_info.vbase_offsets.insert(std::make_pair(class_clang_type.GetAsCXXRecordDecl(),
clang::CharUnits::fromQuantity(member_byte_offset)));
}
else
{
- layout_info.base_offsets.insert(std::make_pair(ClangASTType::GetAsCXXRecordDecl(class_clang_type),
+ layout_info.base_offsets.insert(std::make_pair(class_clang_type.GetAsCXXRecordDecl(),
clang::CharUnits::fromQuantity(member_byte_offset)));
}
}
@@ -2331,35 +2319,35 @@ SymbolFileDWARF::ResolveTypeUID (DWARFCo
// SymbolFileDWARF objects to detect if this DWARF file is the one that
// can resolve a clang_type.
bool
-SymbolFileDWARF::HasForwardDeclForClangType (lldb::clang_type_t clang_type)
+SymbolFileDWARF::HasForwardDeclForClangType (const ClangASTType &clang_type)
{
- clang_type_t clang_type_no_qualifiers = ClangASTType::RemoveFastQualifiers(clang_type);
- const DWARFDebugInfoEntry* die = m_forward_decl_clang_type_to_die.lookup (clang_type_no_qualifiers);
+ ClangASTType clang_type_no_qualifiers = clang_type.RemoveFastQualifiers();
+ const DWARFDebugInfoEntry* die = m_forward_decl_clang_type_to_die.lookup (clang_type_no_qualifiers.GetOpaqueQualType());
return die != NULL;
}
-lldb::clang_type_t
-SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_type)
+bool
+SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (ClangASTType &clang_type)
{
// We have a struct/union/class/enum that needs to be fully resolved.
- clang_type_t clang_type_no_qualifiers = ClangASTType::RemoveFastQualifiers(clang_type);
- const DWARFDebugInfoEntry* die = m_forward_decl_clang_type_to_die.lookup (clang_type_no_qualifiers);
+ ClangASTType clang_type_no_qualifiers = clang_type.RemoveFastQualifiers();
+ const DWARFDebugInfoEntry* die = m_forward_decl_clang_type_to_die.lookup (clang_type_no_qualifiers.GetOpaqueQualType());
if (die == NULL)
{
// We have already resolved this type...
- return clang_type;
+ return true;
}
// Once we start resolving this type, remove it from the forward declaration
// map in case anyone child members or other types require this type to get resolved.
// The type will get resolved when all of the calls to SymbolFileDWARF::ResolveClangOpaqueTypeDefinition
// are done.
- m_forward_decl_clang_type_to_die.erase (clang_type_no_qualifiers);
+ m_forward_decl_clang_type_to_die.erase (clang_type_no_qualifiers.GetOpaqueQualType());
// Disable external storage for this type so we don't get anymore
// clang::ExternalASTSource queries for this type.
- ClangASTContext::SetHasExternalStorage (clang_type, false);
+ clang_type.SetHasExternalStorage (false);
DWARFDebugInfo* debug_info = DebugInfo();
@@ -2381,8 +2369,6 @@ SymbolFileDWARF::ResolveClangOpaqueTypeD
assert (clang_type);
DWARFDebugInfoEntry::Attributes attributes;
- ClangASTContext &ast = GetClangASTContext();
-
switch (tag)
{
case DW_TAG_structure_type:
@@ -2396,13 +2382,12 @@ SymbolFileDWARF::ResolveClangOpaqueTypeD
{
LanguageType class_language = eLanguageTypeUnknown;
- bool is_objc_class = ClangASTContext::IsObjCClassType (clang_type);
- if (is_objc_class)
+ if (clang_type.IsObjCObjectOrInterfaceType())
{
class_language = eLanguageTypeObjC;
// For objective C we don't start the definition when
// the class is created.
- ast.StartTagDeclarationDefinition (clang_type);
+ clang_type.StartTagDeclarationDefinition ();
}
int tag_decl_kind = -1;
@@ -2456,7 +2441,7 @@ SymbolFileDWARF::ResolveClangOpaqueTypeD
if (class_language == eLanguageTypeObjC)
{
- std::string class_str (ClangASTType::GetTypeNameForOpaqueQualType(ast.getASTContext(), clang_type));
+ std::string class_str (clang_type.GetTypeName());
if (!class_str.empty())
{
@@ -2499,7 +2484,7 @@ SymbolFileDWARF::ResolveClangOpaqueTypeD
}
}
- for (DelayedPropertyList::const_iterator pi = delayed_properties.begin(), pe = delayed_properties.end();
+ for (DelayedPropertyList::iterator pi = delayed_properties.begin(), pe = delayed_properties.end();
pi != pe;
++pi)
pi->Finalize();
@@ -2511,7 +2496,7 @@ SymbolFileDWARF::ResolveClangOpaqueTypeD
if (class_language != eLanguageTypeObjC)
{
if (is_a_class && tag_decl_kind != clang::TTK_Class)
- ast.SetTagTypeKind (clang_type, clang::TTK_Class);
+ clang_type.SetTagTypeKind (clang::TTK_Class);
}
// Since DW_TAG_structure_type gets used for both classes
@@ -2528,29 +2513,26 @@ SymbolFileDWARF::ResolveClangOpaqueTypeD
{
// This is a class and all members that didn't have
// their access specified are private.
- ast.SetDefaultAccessForRecordFields (clang_type,
- eAccessPrivate,
- &member_accessibilities.front(),
- member_accessibilities.size());
+ clang_type.SetDefaultAccessForRecordFields (eAccessPrivate,
+ &member_accessibilities.front(),
+ member_accessibilities.size());
}
if (!base_classes.empty())
{
- ast.SetBaseClassesForClassType (clang_type,
- &base_classes.front(),
- base_classes.size());
+ clang_type.SetBaseClassesForClassType (&base_classes.front(),
+ base_classes.size());
// Clang will copy each CXXBaseSpecifier in "base_classes"
// so we have to free them all.
- ClangASTContext::DeleteBaseClassSpecifiers (&base_classes.front(),
- base_classes.size());
+ ClangASTType::DeleteBaseClassSpecifiers (&base_classes.front(),
+ base_classes.size());
}
}
}
- ast.BuildIndirectFields (clang_type);
-
- ast.CompleteTagDeclarationDefinition (clang_type);
+ clang_type.BuildIndirectFields ();
+ clang_type.CompleteTagDeclarationDefinition ();
if (!layout_info.field_offsets.empty() ||
!layout_info.base_offsets.empty() ||
@@ -2561,14 +2543,14 @@ SymbolFileDWARF::ResolveClangOpaqueTypeD
if (layout_info.bit_size == 0)
layout_info.bit_size = die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_byte_size, 0) * 8;
- clang::CXXRecordDecl *record_decl = ClangASTType::GetAsCXXRecordDecl(clang_type);
+ clang::CXXRecordDecl *record_decl = clang_type.GetAsCXXRecordDecl();
if (record_decl)
{
if (log)
{
GetObjectFile()->GetModule()->LogMessage (log,
"SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (clang_type = %p) caching layout info for record_decl = %p, bit_size = %" PRIu64 ", alignment = %" PRIu64 ", field_offsets[%u], base_offsets[%u], vbase_offsets[%u])",
- clang_type,
+ clang_type.GetOpaqueQualType(),
record_decl,
layout_info.bit_size,
layout_info.alignment,
@@ -2583,7 +2565,7 @@ SymbolFileDWARF::ResolveClangOpaqueTypeD
{
GetObjectFile()->GetModule()->LogMessage (log,
"SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (clang_type = %p) field[%u] = { bit_offset=%u, name='%s' }",
- clang_type,
+ clang_type.GetOpaqueQualType(),
idx,
(uint32_t)pos->second,
pos->first->getNameAsString().c_str());
@@ -2596,7 +2578,7 @@ SymbolFileDWARF::ResolveClangOpaqueTypeD
{
GetObjectFile()->GetModule()->LogMessage (log,
"SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (clang_type = %p) base[%u] = { byte_offset=%u, name='%s' }",
- clang_type,
+ clang_type.GetOpaqueQualType(),
idx,
(uint32_t)base_pos->second.getQuantity(),
base_pos->first->getNameAsString().c_str());
@@ -2608,7 +2590,7 @@ SymbolFileDWARF::ResolveClangOpaqueTypeD
{
GetObjectFile()->GetModule()->LogMessage (log,
"SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (clang_type = %p) vbase[%u] = { byte_offset=%u, name='%s' }",
- clang_type,
+ clang_type.GetOpaqueQualType(),
idx,
(uint32_t)vbase_pos->second.getQuantity(),
vbase_pos->first->getNameAsString().c_str());
@@ -2623,15 +2605,15 @@ SymbolFileDWARF::ResolveClangOpaqueTypeD
return clang_type;
case DW_TAG_enumeration_type:
- ast.StartTagDeclarationDefinition (clang_type);
+ clang_type.StartTagDeclarationDefinition ();
if (die->HasChildren())
{
SymbolContext sc(GetCompUnitForDWARFCompUnit(dwarf_cu));
bool is_signed = false;
- ast.IsIntegerType(clang_type, is_signed);
+ clang_type.IsIntegerType(is_signed);
ParseChildEnumerators(sc, clang_type, is_signed, type->GetByteSize(), dwarf_cu, die);
}
- ast.CompleteTagDeclarationDefinition (clang_type);
+ clang_type.CompleteTagDeclarationDefinition ();
return clang_type;
default:
@@ -4142,7 +4124,7 @@ SymbolFileDWARF::ParseChildParameters (c
bool skip_artificial,
bool &is_static,
TypeList* type_list,
- std::vector<clang_type_t>& function_param_types,
+ std::vector<ClangASTType>& function_param_types,
std::vector<clang::ParmVarDecl*>& function_param_decls,
unsigned &type_quals,
ClangASTContext::TemplateParameterInfos &template_param_infos)
@@ -4308,7 +4290,7 @@ size_t
SymbolFileDWARF::ParseChildEnumerators
(
const SymbolContext& sc,
- clang_type_t enumerator_clang_type,
+ lldb_private::ClangASTType &clang_type,
bool is_signed,
uint32_t enumerator_byte_size,
DWARFCompileUnit* dwarf_cu,
@@ -4370,12 +4352,11 @@ SymbolFileDWARF::ParseChildEnumerators
if (name && name[0] && got_value)
{
- GetClangASTContext().AddEnumerationValueToEnumerationType (enumerator_clang_type,
- enumerator_clang_type,
- decl,
- name,
- enum_value,
- enumerator_byte_size * 8);
+ clang_type.AddEnumerationValueToEnumerationType (clang_type.GetEnumerationIntegerType(),
+ decl,
+ name,
+ enum_value,
+ enumerator_byte_size * 8);
++enumerators_added;
}
}
@@ -4643,7 +4624,7 @@ SymbolFileDWARF::GetClangDeclContextCont
Type* type = ResolveType (cu, decl_ctx_die);
if (type)
{
- clang::DeclContext *decl_ctx = ClangASTContext::GetDeclContextForType (type->GetClangForwardType ());
+ clang::DeclContext *decl_ctx = type->GetClangForwardType().GetDeclContextForType ();
if (decl_ctx)
{
LinkDeclContextToDIE (decl_ctx, decl_ctx_die);
@@ -4723,7 +4704,7 @@ SymbolFileDWARF::GetObjCClassSymbol (con
Symbol *objc_class_symbol = NULL;
if (m_obj_file)
{
- Symtab *symtab = m_obj_file->GetSymtab (ObjectFile::eSymtabFromUnifiedSectionList);
+ Symtab *symtab = m_obj_file->GetSymtab ();
if (symtab)
{
objc_class_symbol = symtab->FindFirstSymbolWithNameAndType (objc_class_name,
@@ -5671,7 +5652,7 @@ SymbolFileDWARF::ParseType (const Symbol
Declaration decl;
Type::EncodingDataType encoding_data_type = Type::eEncodingIsUID;
- clang_type_t clang_type = NULL;
+ ClangASTType clang_type;
dw_attr_t attr;
@@ -5744,7 +5725,7 @@ SymbolFileDWARF::ParseType (const Symbol
strcmp(type_name_cstr, "decltype(nullptr)") == 0 )
{
resolve_state = Type::eResolveStateFull;
- clang_type = ast.getASTContext()->NullPtrTy.getAsOpaquePtr();
+ clang_type = ast.GetBasicType(eBasicTypeNullPtr);
break;
}
// Fall through to base type below in case we can handle the type there...
@@ -5765,7 +5746,7 @@ SymbolFileDWARF::ParseType (const Symbol
case DW_TAG_volatile_type: encoding_data_type = Type::eEncodingIsVolatileUID; break;
}
- if (clang_type == NULL && (encoding_data_type == Type::eEncodingIsPointerUID || encoding_data_type == Type::eEncodingIsTypedefUID) && sc.comp_unit != NULL)
+ if (!clang_type && (encoding_data_type == Type::eEncodingIsPointerUID || encoding_data_type == Type::eEncodingIsTypedefUID) && sc.comp_unit != NULL)
{
bool translation_unit_is_objc = (sc.comp_unit->GetLanguage() == eLanguageTypeObjC || sc.comp_unit->GetLanguage() == eLanguageTypeObjC_plus_plus);
@@ -5784,7 +5765,7 @@ SymbolFileDWARF::ParseType (const Symbol
die->GetOffset(),
DW_TAG_value_to_name(die->Tag()),
die->GetName(this, dwarf_cu));
- clang_type = ast.GetBuiltInType_objc_id();
+ clang_type = ast.GetBasicType(eBasicTypeObjCID);
encoding_data_type = Type::eEncodingIsUID;
encoding_uid = LLDB_INVALID_UID;
resolve_state = Type::eResolveStateFull;
@@ -5797,7 +5778,7 @@ SymbolFileDWARF::ParseType (const Symbol
die->GetOffset(),
DW_TAG_value_to_name(die->Tag()),
die->GetName(this, dwarf_cu));
- clang_type = ast.GetBuiltInType_objc_Class();
+ clang_type = ast.GetBasicType(eBasicTypeObjCClass);
encoding_data_type = Type::eEncodingIsUID;
encoding_uid = LLDB_INVALID_UID;
resolve_state = Type::eResolveStateFull;
@@ -5809,7 +5790,7 @@ SymbolFileDWARF::ParseType (const Symbol
die->GetOffset(),
DW_TAG_value_to_name(die->Tag()),
die->GetName(this, dwarf_cu));
- clang_type = ast.GetBuiltInType_objc_selector();
+ clang_type = ast.GetBasicType(eBasicTypeObjCSel);
encoding_data_type = Type::eEncodingIsUID;
encoding_uid = LLDB_INVALID_UID;
resolve_state = Type::eResolveStateFull;
@@ -5832,7 +5813,7 @@ SymbolFileDWARF::ParseType (const Symbol
die->GetOffset(),
DW_TAG_value_to_name(die->Tag()),
die->GetName(this, dwarf_cu));
- clang_type = ast.GetBuiltInType_objc_id();
+ clang_type = ast.GetBasicType(eBasicTypeObjCID);
encoding_data_type = Type::eEncodingIsUID;
encoding_uid = LLDB_INVALID_UID;
resolve_state = Type::eResolveStateFull;
@@ -6109,8 +6090,8 @@ SymbolFileDWARF::ParseType (const Symbol
}
assert (tag_decl_kind != -1);
bool clang_type_was_created = false;
- clang_type = m_forward_decl_die_to_clang_type.lookup (die);
- if (clang_type == NULL)
+ clang_type.SetClangType(ast.getASTContext(), m_forward_decl_die_to_clang_type.lookup (die));
+ if (!clang_type)
{
const DWARFDebugInfoEntry *decl_ctx_die;
@@ -6166,7 +6147,7 @@ SymbolFileDWARF::ParseType (const Symbol
// Store a forward declaration to this class type in case any
// parameters in any class methods need it for the clang
// types for function prototypes.
- LinkDeclContextToDIE(ClangASTContext::GetDeclContextForType(clang_type), die);
+ LinkDeclContextToDIE(clang_type.GetDeclContextForType(), die);
type_sp.reset (new Type (MakeUserID(die->GetOffset()),
this,
type_name_const_str,
@@ -6202,27 +6183,21 @@ SymbolFileDWARF::ParseType (const Symbol
if (die->HasChildren() == false)
{
// No children for this struct/union/class, lets finish it
- ast.StartTagDeclarationDefinition (clang_type);
- ast.CompleteTagDeclarationDefinition (clang_type);
+ clang_type.StartTagDeclarationDefinition ();
+ clang_type.CompleteTagDeclarationDefinition ();
if (tag == DW_TAG_structure_type) // this only applies in C
{
- clang::QualType qual_type = clang::QualType::getFromOpaquePtr (clang_type);
- const clang::RecordType *record_type = qual_type->getAs<clang::RecordType> ();
+ clang::RecordDecl *record_decl = clang_type.GetAsRecordDecl();
- if (record_type)
+ if (record_decl)
{
- clang::RecordDecl *record_decl = record_type->getDecl();
+ LayoutInfo layout_info;
- if (record_decl)
- {
- LayoutInfo layout_info;
-
- layout_info.alignment = 0;
- layout_info.bit_size = 0;
-
- m_record_decl_to_layout_map.insert(std::make_pair(record_decl, layout_info));
- }
+ layout_info.alignment = 0;
+ layout_info.bit_size = 0;
+
+ m_record_decl_to_layout_map.insert(std::make_pair(record_decl, layout_info));
}
}
}
@@ -6238,16 +6213,16 @@ SymbolFileDWARF::ParseType (const Symbol
if (class_language != eLanguageTypeObjC &&
class_language != eLanguageTypeObjC_plus_plus)
- ast.StartTagDeclarationDefinition (clang_type);
+ clang_type.StartTagDeclarationDefinition ();
// Leave this as a forward declaration until we need
// to know the details of the type. lldb_private::Type
// will automatically call the SymbolFile virtual function
// "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition(Type *)"
// When the definition needs to be defined.
- m_forward_decl_die_to_clang_type[die] = clang_type;
- m_forward_decl_clang_type_to_die[ClangASTType::RemoveFastQualifiers (clang_type)] = die;
- ClangASTContext::SetHasExternalStorage (clang_type, true);
+ m_forward_decl_die_to_clang_type[die] = clang_type.GetOpaqueQualType();
+ m_forward_decl_clang_type_to_die[clang_type.RemoveFastQualifiers().GetOpaqueQualType()] = die;
+ clang_type.SetHasExternalStorage (true);
}
}
@@ -6303,9 +6278,9 @@ SymbolFileDWARF::ParseType (const Symbol
DEBUG_PRINTF ("0x%8.8" PRIx64 ": %s (\"%s\")\n", MakeUserID(die->GetOffset()), DW_TAG_value_to_name(tag), type_name_cstr);
- clang_type_t enumerator_clang_type = NULL;
- clang_type = m_forward_decl_die_to_clang_type.lookup (die);
- if (clang_type == NULL)
+ ClangASTType enumerator_clang_type;
+ clang_type.SetClangType (ast.getASTContext(), m_forward_decl_die_to_clang_type.lookup (die));
+ if (!clang_type)
{
if (encoding_uid != DW_INVALID_OFFSET)
{
@@ -6314,7 +6289,7 @@ SymbolFileDWARF::ParseType (const Symbol
enumerator_clang_type = enumerator_type->GetClangFullType();
}
- if (enumerator_clang_type == NULL)
+ if (!enumerator_clang_type)
enumerator_clang_type = ast.GetBuiltinTypeForDWARFEncodingAndBitSize (NULL,
DW_ATE_signed,
byte_size * 8);
@@ -6326,10 +6301,10 @@ SymbolFileDWARF::ParseType (const Symbol
}
else
{
- enumerator_clang_type = ClangASTContext::GetEnumerationIntegerType (clang_type);
+ enumerator_clang_type = clang_type.GetEnumerationIntegerType ();
}
- LinkDeclContextToDIE(ClangASTContext::GetDeclContextForType(clang_type), die);
+ LinkDeclContextToDIE(clang_type.GetDeclContextForType(), die);
type_sp.reset( new Type (MakeUserID(die->GetOffset()),
this,
@@ -6342,15 +6317,15 @@ SymbolFileDWARF::ParseType (const Symbol
clang_type,
Type::eResolveStateForward));
- ast.StartTagDeclarationDefinition (clang_type);
+ clang_type.StartTagDeclarationDefinition ();
if (die->HasChildren())
{
SymbolContext cu_sc(GetCompUnitForDWARFCompUnit(dwarf_cu));
bool is_signed = false;
- ast.IsIntegerType(enumerator_clang_type, is_signed);
+ enumerator_clang_type.IsIntegerType(is_signed);
ParseChildEnumerators(cu_sc, clang_type, is_signed, type_sp->GetByteSize(), dwarf_cu, die);
}
- ast.CompleteTagDeclarationDefinition (clang_type);
+ clang_type.CompleteTagDeclarationDefinition ();
}
}
break;
@@ -6473,7 +6448,7 @@ SymbolFileDWARF::ParseType (const Symbol
DEBUG_PRINTF ("0x%8.8" PRIx64 ": %s (\"%s\")\n", MakeUserID(die->GetOffset()), DW_TAG_value_to_name(tag), type_name_cstr);
- clang_type_t return_clang_type = NULL;
+ ClangASTType return_clang_type;
Type *func_type = NULL;
if (type_die_offset != DW_INVALID_OFFSET)
@@ -6482,10 +6457,10 @@ SymbolFileDWARF::ParseType (const Symbol
if (func_type)
return_clang_type = func_type->GetClangForwardType();
else
- return_clang_type = ast.GetBuiltInType_void();
+ return_clang_type = ast.GetBasicType(eBasicTypeVoid);
- std::vector<clang_type_t> function_param_types;
+ std::vector<ClangASTType> function_param_types;
std::vector<clang::ParmVarDecl*> function_param_decls;
// Parse the function children for the parameters
@@ -6535,7 +6510,7 @@ SymbolFileDWARF::ParseType (const Symbol
if (objc_method.IsValid(true))
{
SymbolContext empty_sc;
- clang_type_t class_opaque_type = NULL;
+ ClangASTType class_opaque_type;
ConstString class_name(objc_method.GetClassName());
if (class_name)
{
@@ -6544,8 +6519,8 @@ SymbolFileDWARF::ParseType (const Symbol
if (complete_objc_class_type_sp)
{
- clang_type_t type_clang_forward_type = complete_objc_class_type_sp->GetClangForwardType();
- if (ClangASTContext::IsObjCClassType (type_clang_forward_type))
+ ClangASTType type_clang_forward_type = complete_objc_class_type_sp->GetClangForwardType();
+ if (type_clang_forward_type.IsObjCObjectOrInterfaceType ())
class_opaque_type = type_clang_forward_type;
}
}
@@ -6557,11 +6532,10 @@ SymbolFileDWARF::ParseType (const Symbol
if (accessibility == eAccessNone)
accessibility = eAccessPublic;
- clang::ObjCMethodDecl *objc_method_decl = ast.AddMethodToObjCObjectType (class_opaque_type,
- type_name_cstr,
- clang_type,
- accessibility,
- is_artificial);
+ clang::ObjCMethodDecl *objc_method_decl = class_opaque_type.AddMethodToObjCObjectType (type_name_cstr,
+ clang_type,
+ accessibility,
+ is_artificial);
type_handled = objc_method_decl != NULL;
if (type_handled)
{
@@ -6680,10 +6654,10 @@ SymbolFileDWARF::ParseType (const Symbol
}
else
{
- clang_type_t class_opaque_type = class_type->GetClangForwardType();
- if (ClangASTContext::IsCXXClassType (class_opaque_type))
+ ClangASTType class_opaque_type = class_type->GetClangForwardType();
+ if (class_opaque_type.IsCXXClassType ())
{
- if (ClangASTContext::IsBeingDefined (class_opaque_type))
+ if (class_opaque_type.IsBeingDefined ())
{
// Neither GCC 4.2 nor clang++ currently set a valid accessibility
// in the DWARF for C++ methods... Default to public for now...
@@ -6709,16 +6683,15 @@ SymbolFileDWARF::ParseType (const Symbol
const bool is_attr_used = false;
- cxx_method_decl = ast.AddMethodToCXXRecordType (class_opaque_type,
- type_name_cstr,
- clang_type,
- accessibility,
- is_virtual,
- is_static,
- is_inline,
- is_explicit,
- is_attr_used,
- is_artificial);
+ cxx_method_decl = class_opaque_type.AddMethodToCXXRecordType (type_name_cstr,
+ clang_type,
+ accessibility,
+ is_virtual,
+ is_static,
+ is_inline,
+ is_explicit,
+ is_attr_used,
+ is_artificial);
type_handled = cxx_method_decl != NULL;
@@ -6902,7 +6875,7 @@ SymbolFileDWARF::ParseType (const Symbol
ParseChildArrayInfo(sc, dwarf_cu, die, first_index, element_orders, byte_stride, bit_stride);
if (byte_stride == 0 && bit_stride == 0)
byte_stride = element_type->GetByteSize();
- clang_type_t array_element_type = element_type->GetClangForwardType();
+ ClangASTType array_element_type = element_type->GetClangForwardType();
uint64_t array_element_bit_stride = byte_stride * 8 + bit_stride;
uint64_t num_elements = 0;
std::vector<uint64_t>::const_reverse_iterator pos;
@@ -6961,14 +6934,12 @@ SymbolFileDWARF::ParseType (const Symbol
Type *pointee_type = ResolveTypeUID(type_die_offset);
Type *class_type = ResolveTypeUID(containing_type_die_offset);
- clang_type_t pointee_clang_type = pointee_type->GetClangForwardType();
- clang_type_t class_clang_type = class_type->GetClangLayoutType();
+ ClangASTType pointee_clang_type = pointee_type->GetClangForwardType();
+ ClangASTType class_clang_type = class_type->GetClangLayoutType();
- clang_type = ast.CreateMemberPointerType(pointee_clang_type,
- class_clang_type);
+ clang_type = pointee_clang_type.CreateMemberPointerType(class_clang_type);
- byte_size = ClangASTType::GetClangTypeBitWidth (ast.getASTContext(),
- clang_type) / 8;
+ byte_size = clang_type.GetByteSize();
type_sp.reset( new Type (MakeUserID(die->GetOffset()),
this,
@@ -7437,7 +7408,7 @@ SymbolFileDWARF::ParseVariableDIE
ObjectFile *debug_map_objfile = debug_map_symfile->GetObjectFile();
if (debug_map_objfile)
{
- Symtab *debug_map_symtab = debug_map_objfile->GetSymtab(ObjectFile::eSymtabFromUnifiedSectionList);
+ Symtab *debug_map_symtab = debug_map_objfile->GetSymtab();
if (debug_map_symtab)
{
Symbol *exe_symbol = debug_map_symtab->FindFirstSymbolWithNameAndType (const_name,
@@ -7761,7 +7732,7 @@ void
SymbolFileDWARF::CompleteTagDecl (void *baton, clang::TagDecl *decl)
{
SymbolFileDWARF *symbol_file_dwarf = (SymbolFileDWARF *)baton;
- clang_type_t clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl);
+ ClangASTType clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl);
if (clang_type)
symbol_file_dwarf->ResolveClangOpaqueTypeDefinition (clang_type);
}
@@ -7770,7 +7741,7 @@ void
SymbolFileDWARF::CompleteObjCInterfaceDecl (void *baton, clang::ObjCInterfaceDecl *decl)
{
SymbolFileDWARF *symbol_file_dwarf = (SymbolFileDWARF *)baton;
- clang_type_t clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl);
+ ClangASTType clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl);
if (clang_type)
symbol_file_dwarf->ResolveClangOpaqueTypeDefinition (clang_type);
}
@@ -7844,8 +7815,7 @@ SymbolFileDWARF::SearchDeclContext (cons
Type *matching_type = ResolveType (dwarf_cu, die);
- lldb::clang_type_t type = matching_type->GetClangForwardType();
- clang::QualType qual_type = clang::QualType::getFromOpaquePtr(type);
+ clang::QualType qual_type = matching_type->GetClangForwardType().GetQualType();
if (const clang::TagType *tag_type = llvm::dyn_cast<clang::TagType>(qual_type.getTypePtr()))
{
Modified: lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h?rev=186540&r1=186539&r2=186540&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h Wed Jul 17 17:17:41 2013
@@ -107,7 +107,7 @@ public:
virtual size_t ParseVariablesForContext (const lldb_private::SymbolContext& sc);
virtual lldb_private::Type* ResolveTypeUID(lldb::user_id_t type_uid);
- virtual lldb::clang_type_t ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_opaque_type);
+ virtual bool ResolveClangOpaqueTypeDefinition (lldb_private::ClangASTType& clang_type);
virtual lldb_private::Type* ResolveType (DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry* type_die, bool assert_not_being_parsed = true);
virtual clang::DeclContext* GetClangDeclContextContainingTypeUID (lldb::user_id_t type_uid);
@@ -275,7 +275,7 @@ public:
}
bool
- HasForwardDeclForClangType (lldb::clang_type_t clang_type);
+ HasForwardDeclForClangType (const lldb_private::ClangASTType &clang_type);
protected:
@@ -347,7 +347,7 @@ protected:
const lldb_private::SymbolContext& sc,
DWARFCompileUnit* dwarf_cu,
const DWARFDebugInfoEntry *die,
- lldb::clang_type_t class_clang_type,
+ lldb_private::ClangASTType &class_clang_type,
const lldb::LanguageType class_language,
std::vector<clang::CXXBaseSpecifier *>& base_classes,
std::vector<int>& member_accessibilities,
@@ -365,14 +365,14 @@ protected:
bool skip_artificial,
bool &is_static,
lldb_private::TypeList* type_list,
- std::vector<lldb::clang_type_t>& function_args,
+ std::vector<lldb_private::ClangASTType>& function_args,
std::vector<clang::ParmVarDecl*>& function_param_decls,
unsigned &type_quals,
lldb_private::ClangASTContext::TemplateParameterInfos &template_param_infos);
size_t ParseChildEnumerators(
const lldb_private::SymbolContext& sc,
- lldb::clang_type_t enumerator_qual_type,
+ lldb_private::ClangASTType &clang_type,
bool is_signed,
uint32_t enumerator_byte_size,
DWARFCompileUnit* dwarf_cu,
Modified: lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp?rev=186540&r1=186539&r2=186540&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp Wed Jul 17 17:17:41 2013
@@ -75,9 +75,9 @@ SymbolFileDWARFDebugMap::CompileUnitInfo
{
for (auto comp_unit_info : cu_infos)
{
- Symtab *exe_symtab = exe_symfile->GetObjectFile()->GetSymtab(ObjectFile::eSymtabFromUnifiedSectionList);
+ Symtab *exe_symtab = exe_symfile->GetObjectFile()->GetSymtab();
ModuleSP oso_module_sp (oso_objfile->GetModule());
- Symtab *oso_symtab = oso_objfile->GetSymtab(ObjectFile::eSymtabFromUnifiedSectionList);
+ Symtab *oso_symtab = oso_objfile->GetSymtab();
///const uint32_t fun_resolve_flags = SymbolContext::Module | eSymbolContextCompUnit | eSymbolContextFunction;
//SectionList *oso_sections = oso_objfile->Sections();
@@ -169,7 +169,7 @@ SymbolFileDWARFDebugMap::CompileUnitInfo
exe_symfile->FinalizeOSOFileRanges (this);
// We don't need the symbols anymore for the .o files
- oso_objfile->ClearSymtab(ObjectFile::eSymtabFromUnifiedSectionList);
+ oso_objfile->ClearSymtab();
}
}
return file_range_map;
@@ -325,12 +325,36 @@ SymbolFileDWARFDebugMap::InitOSO()
return;
m_flags.set(kHaveInitializedOSOs);
+
+ // If the object file has been stripped, there is no sense in looking further
+ // as all of the debug symbols for the debug map will not be available
+ if (m_obj_file->IsStripped())
+ return;
+
+ // Also make sure the file type is some sort of executable. Core files, debug
+ // info files (dSYM), object files (.o files), and stub libraries all can
+ switch (m_obj_file->GetType())
+ {
+ case ObjectFile::eTypeInvalid:
+ case ObjectFile::eTypeCoreFile:
+ case ObjectFile::eTypeDebugInfo:
+ case ObjectFile::eTypeObjectFile:
+ case ObjectFile::eTypeStubLibrary:
+ case ObjectFile::eTypeUnknown:
+ return;
+
+ case ObjectFile::eTypeExecutable:
+ case ObjectFile::eTypeDynamicLinker:
+ case ObjectFile::eTypeSharedLibrary:
+ break;
+ }
+
// In order to get the abilities of this plug-in, we look at the list of
// N_OSO entries (object files) from the symbol table and make sure that
// these files exist and also contain valid DWARF. If we get any of that
// then we return the abilities of the first N_OSO's DWARF.
- Symtab* symtab = m_obj_file->GetSymtab(ObjectFile::eSymtabFromUnifiedSectionList);
+ Symtab* symtab = m_obj_file->GetSymtab();
if (symtab)
{
Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_MAP));
@@ -593,27 +617,17 @@ SymbolFileDWARFDebugMap::CalculateAbilit
const uint32_t oso_index_count = GetNumCompileUnits();
if (oso_index_count > 0)
{
- const uint32_t dwarf_abilities = SymbolFile::CompileUnits |
- SymbolFile::Functions |
- SymbolFile::Blocks |
- SymbolFile::GlobalVariables |
- SymbolFile::LocalVariables |
- SymbolFile::VariableTypes |
- SymbolFile::LineTables;
-
InitOSO();
if (!m_compile_unit_infos.empty())
- return dwarf_abilities;
-// for (uint32_t oso_idx=0; oso_idx<oso_index_count; ++oso_idx)
-// {
-// SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx);
-// if (oso_dwarf)
-// {
-// uint32_t oso_abilities = oso_dwarf->GetAbilities();
-// if ((oso_abilities & dwarf_abilities) == dwarf_abilities)
-// return oso_abilities;
-// }
-// }
+ {
+ return SymbolFile::CompileUnits |
+ SymbolFile::Functions |
+ SymbolFile::Blocks |
+ SymbolFile::GlobalVariables |
+ SymbolFile::LocalVariables |
+ SymbolFile::VariableTypes |
+ SymbolFile::LineTables ;
+ }
}
return 0;
}
@@ -766,18 +780,18 @@ SymbolFileDWARFDebugMap::ResolveTypeUID(
return NULL;
}
-lldb::clang_type_t
-SymbolFileDWARFDebugMap::ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_type)
+bool
+SymbolFileDWARFDebugMap::ResolveClangOpaqueTypeDefinition (ClangASTType& clang_type)
{
// We have a struct/union/class/enum that needs to be fully resolved.
- return NULL;
+ return false;
}
uint32_t
SymbolFileDWARFDebugMap::ResolveSymbolContext (const Address& exe_so_addr, uint32_t resolve_scope, SymbolContext& sc)
{
uint32_t resolved_flags = 0;
- Symtab* symtab = m_obj_file->GetSymtab(ObjectFile::eSymtabFromUnifiedSectionList);
+ Symtab* symtab = m_obj_file->GetSymtab();
if (symtab)
{
const addr_t exe_file_addr = exe_so_addr.GetFileAddress();
@@ -1371,7 +1385,7 @@ void
SymbolFileDWARFDebugMap::CompleteTagDecl (void *baton, clang::TagDecl *decl)
{
SymbolFileDWARFDebugMap *symbol_file_dwarf = (SymbolFileDWARFDebugMap *)baton;
- clang_type_t clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl);
+ ClangASTType clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl);
if (clang_type)
{
SymbolFileDWARF *oso_dwarf;
@@ -1391,7 +1405,7 @@ void
SymbolFileDWARFDebugMap::CompleteObjCInterfaceDecl (void *baton, clang::ObjCInterfaceDecl *decl)
{
SymbolFileDWARFDebugMap *symbol_file_dwarf = (SymbolFileDWARFDebugMap *)baton;
- clang_type_t clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl);
+ ClangASTType clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl);
if (clang_type)
{
SymbolFileDWARF *oso_dwarf;
@@ -1454,12 +1468,10 @@ SymbolFileDWARFDebugMap::AddOSOFileRange
lldb::addr_t oso_file_addr,
lldb::addr_t oso_byte_size)
{
- assert (cu_info);// REMOVE THIS PRIOR TO CHECKIN
const uint32_t debug_map_idx = m_debug_map.FindEntryIndexThatContains(exe_file_addr);
if (debug_map_idx != UINT32_MAX)
{
DebugMap::Entry *debug_map_entry = m_debug_map.FindEntryThatContains(exe_file_addr);
- assert (debug_map_entry);// REMOVE THIS PRIOR TO CHECKIN
debug_map_entry->data.SetOSOFileAddress(oso_file_addr);
cu_info->file_range_map.Append(FileRangeMap::Entry(oso_file_addr, oso_byte_size, exe_file_addr));
return true;
Modified: lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h?rev=186540&r1=186539&r2=186540&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h Wed Jul 17 17:17:41 2013
@@ -77,7 +77,7 @@ public:
virtual lldb_private::Type* ResolveTypeUID (lldb::user_id_t type_uid);
virtual clang::DeclContext* GetClangDeclContextContainingTypeUID (lldb::user_id_t type_uid);
virtual clang::DeclContext* GetClangDeclContextForTypeUID (const lldb_private::SymbolContext &sc, lldb::user_id_t type_uid);
- virtual lldb::clang_type_t ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_Type);
+ virtual bool ResolveClangOpaqueTypeDefinition (lldb_private::ClangASTType& clang_type);
virtual uint32_t ResolveSymbolContext (const lldb_private::Address& so_addr, uint32_t resolve_scope, lldb_private::SymbolContext& sc);
virtual uint32_t ResolveSymbolContext (const lldb_private::FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, lldb_private::SymbolContextList& sc_list);
virtual uint32_t FindGlobalVariables (const lldb_private::ConstString &name, const lldb_private::ClangNamespaceDecl *namespace_decl, bool append, uint32_t max_matches, lldb_private::VariableList& variables);
Modified: lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp?rev=186540&r1=186539&r2=186540&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp Wed Jul 17 17:17:41 2013
@@ -93,7 +93,7 @@ SymbolFileSymtab::CalculateAbilities ()
uint32_t abilities = 0;
if (m_obj_file)
{
- const Symtab *symtab = m_obj_file->GetSymtab(ObjectFile::eSymtabFromUnifiedSectionList);
+ const Symtab *symtab = m_obj_file->GetSymtab();
if (symtab)
{
//----------------------------------------------------------------------
@@ -159,7 +159,7 @@ SymbolFileSymtab::ParseCompileUnitAtInde
// the entire object file
if (idx < m_source_indexes.size())
{
- const Symbol *cu_symbol = m_obj_file->GetSymtab(ObjectFile::eSymtabFromUnifiedSectionList)->SymbolAtIndex(m_source_indexes[idx]);
+ const Symbol *cu_symbol = m_obj_file->GetSymtab()->SymbolAtIndex(m_source_indexes[idx]);
if (cu_symbol)
cu_sp.reset(new CompileUnit (m_obj_file->GetModule(), NULL, cu_symbol->GetMangled().GetName().AsCString(), 0, eLanguageTypeUnknown));
}
@@ -179,7 +179,7 @@ SymbolFileSymtab::ParseCompileUnitFuncti
size_t num_added = 0;
// We must at least have a valid compile unit
assert (sc.comp_unit != NULL);
- const Symtab *symtab = m_obj_file->GetSymtab(ObjectFile::eSymtabFromUnifiedSectionList);
+ const Symtab *symtab = m_obj_file->GetSymtab();
const Symbol *curr_symbol = NULL;
const Symbol *next_symbol = NULL;
// const char *prefix = m_obj_file->SymbolPrefix();
@@ -292,10 +292,10 @@ SymbolFileSymtab::ResolveTypeUID(lldb::u
return NULL;
}
-lldb::clang_type_t
-SymbolFileSymtab::ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_Type)
+bool
+SymbolFileSymtab::ResolveClangOpaqueTypeDefinition (lldb_private::ClangASTType& clang_opaque_type)
{
- return NULL;
+ return false;
}
ClangNamespaceDecl
@@ -307,13 +307,13 @@ SymbolFileSymtab::FindNamespace (const S
uint32_t
SymbolFileSymtab::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc)
{
- if (m_obj_file->GetSymtab(ObjectFile::eSymtabFromUnifiedSectionList) == NULL)
+ if (m_obj_file->GetSymtab() == NULL)
return 0;
uint32_t resolved_flags = 0;
if (resolve_scope & eSymbolContextSymbol)
{
- sc.symbol = m_obj_file->GetSymtab(ObjectFile::eSymtabFromUnifiedSectionList)->FindSymbolContainingFileAddress(so_addr.GetFileAddress());
+ sc.symbol = m_obj_file->GetSymtab()->FindSymbolContainingFileAddress(so_addr.GetFileAddress());
if (sc.symbol)
resolved_flags |= eSymbolContextSymbol;
}
Modified: lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h?rev=186540&r1=186539&r2=186540&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h Wed Jul 17 17:17:41 2013
@@ -78,8 +78,8 @@ public:
virtual lldb_private::Type*
ResolveTypeUID(lldb::user_id_t type_uid);
- virtual lldb::clang_type_t
- ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_Type);
+ virtual bool
+ ResolveClangOpaqueTypeDefinition (lldb_private::ClangASTType& clang_type);
virtual uint32_t
ResolveSymbolContext (const lldb_private::Address& so_addr, uint32_t resolve_scope, lldb_private::SymbolContext& sc);
Modified: lldb/branches/lldb-platform-work/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp?rev=186540&r1=186539&r2=186540&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp Wed Jul 17 17:17:41 2013
@@ -141,7 +141,7 @@ SymbolVendorELF::CreateInstance (const l
if (symbol_vendor)
{
// Get the module unified section list and add our debug sections to that.
- SectionList *module_section_list = module_sp->GetUnifiedSectionList();
+ SectionList *module_section_list = module_sp->GetSectionList();
SectionList *objfile_section_list = dsym_objfile_sp->GetSectionList();
static const SectionType g_sections[] =
@@ -172,7 +172,6 @@ SymbolVendorELF::CreateInstance (const l
module_section_list->AddSection (section_sp);
}
}
- module_section_list->Finalize();
symbol_vendor->AddSymbolFileRepresentation (dsym_objfile_sp);
return symbol_vendor;
Modified: lldb/branches/lldb-platform-work/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp?rev=186540&r1=186539&r2=186540&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp Wed Jul 17 17:17:41 2013
@@ -83,51 +83,6 @@ UUIDsMatch(Module *module, ObjectFile *o
return false;
}
-static bool
-ReplaceDSYMSectionsWithExecutableSections (ObjectFile *exec_objfile, ObjectFile *dsym_objfile)
-{
- // We need both the executable and the dSYM to live off of the
- // same section lists. So we take all of the sections from the
- // executable, and replace them in the dSYM. This allows section
- // offset addresses that come from the dSYM to automatically
- // get updated as images (shared libraries) get loaded and
- // unloaded.
- SectionList *exec_section_list = exec_objfile->GetSectionList();
- SectionList *dsym_section_list = dsym_objfile->GetSectionList();
- if (exec_section_list && dsym_section_list)
- {
- const uint32_t num_exec_sections = dsym_section_list->GetSize();
- uint32_t exec_sect_idx;
- for (exec_sect_idx = 0; exec_sect_idx < num_exec_sections; ++exec_sect_idx)
- {
- SectionSP exec_sect_sp(exec_section_list->GetSectionAtIndex(exec_sect_idx));
- if (exec_sect_sp.get())
- {
- // Try and replace any sections that exist in both the executable
- // and in the dSYM with those from the executable. If we fail to
- // replace the one in the dSYM, then add the executable section to
- // the dSYM.
- SectionSP dsym_sect_sp(dsym_section_list->FindSectionByID(exec_sect_sp->GetID()));
- if (dsym_sect_sp.get() && dsym_sect_sp->GetName() != exec_sect_sp->GetName())
- {
- // The sections in a dSYM are normally a superset of the sections in an executable.
- // If we find a section # in the exectuable & dSYM that don't have the same name,
- // something has changed since the dSYM was written. The mach_kernel DSTROOT binary
- // has a CTF segment added, for instance, and it's easiest to simply not add that to
- // the dSYM - none of the nlist entries are going to have references to that section.
- continue;
- }
- if (dsym_section_list->ReplaceSection(exec_sect_sp->GetID(), exec_sect_sp, 0) == false)
- dsym_section_list->AddSection(exec_sect_sp);
- }
- }
-
- dsym_section_list->Finalize(); // Now that we're done adding sections, finalize to build fast-lookup caches
- return true;
- }
- return false;
-}
-
void
SymbolVendorMacOSX::Initialize()
{
@@ -277,6 +232,7 @@ SymbolVendorMacOSX::CreateInstance (cons
if (node_content)
{
strncpy(DBGBuildSourcePath, node_content, sizeof(DBGBuildSourcePath));
+ xmlFree((void *) node_content);
}
}
key_node = value_node;
@@ -296,11 +252,14 @@ SymbolVendorMacOSX::CreateInstance (cons
{
FileSpec resolved_source_path(node_content, true);
resolved_source_path.GetPath(DBGSourcePath, sizeof(DBGSourcePath));
+ xmlFree ((void *) node_content);
}
}
key_node = value_node;
}
}
+ if (key_name != NULL)
+ xmlFree((void *) key_name);
}
}
}
@@ -321,16 +280,6 @@ SymbolVendorMacOSX::CreateInstance (cons
}
}
- if (ReplaceDSYMSectionsWithExecutableSections (obj_file, dsym_objfile_sp.get()))
- {
- SectionList *section_list = dsym_objfile_sp.get()->GetSectionList();
- if (section_list)
- {
- section_list->Copy (module_sp->GetUnifiedSectionList());
- section_list->Finalize ();
- }
- }
-
symbol_vendor->AddSymbolFileRepresentation(dsym_objfile_sp);
return symbol_vendor;
}
Modified: lldb/branches/lldb-platform-work/source/Symbol/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Symbol/CMakeLists.txt?rev=186540&r1=186539&r2=186540&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Symbol/CMakeLists.txt (original)
+++ lldb/branches/lldb-platform-work/source/Symbol/CMakeLists.txt Wed Jul 17 17:17:41 2013
@@ -22,7 +22,6 @@ add_lldb_library(lldbSymbol
SymbolVendor.cpp
Symtab.cpp
Type.cpp
- TypeHierarchyNavigator.cpp
TypeList.cpp
UnwindPlan.cpp
UnwindTable.cpp
Modified: lldb/branches/lldb-platform-work/source/Symbol/ClangASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Symbol/ClangASTContext.cpp?rev=186540&r1=186539&r2=186540&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Symbol/ClangASTContext.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Symbol/ClangASTContext.cpp Wed Jul 17 17:17:41 2013
@@ -62,6 +62,7 @@
#include "lldb/Core/Flags.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/RegularExpression.h"
+#include "lldb/Core/UniqueCStringMap.h"
#include "lldb/Expression/ASTDumper.h"
#include "lldb/Symbol/ClangExternalASTSourceCommon.h"
#include "lldb/Symbol/VerifyDecl.h"
@@ -69,119 +70,17 @@
#include "lldb/Target/Process.h"
#include "lldb/Target/ObjCLanguageRuntime.h"
-
#include <stdio.h>
+#include <mutex>
+
using namespace lldb;
using namespace lldb_private;
using namespace llvm;
using namespace clang;
-
-static bool
-GetCompleteQualType (clang::ASTContext *ast, clang::QualType qual_type, bool allow_completion = true)
-{
- const clang::Type::TypeClass type_class = qual_type->getTypeClass();
- switch (type_class)
- {
- case clang::Type::ConstantArray:
- case clang::Type::IncompleteArray:
- case clang::Type::VariableArray:
- {
- const clang::ArrayType *array_type = dyn_cast<clang::ArrayType>(qual_type.getTypePtr());
-
- if (array_type)
- return GetCompleteQualType (ast, array_type->getElementType(), allow_completion);
- }
- break;
-
- case clang::Type::Record:
- case clang::Type::Enum:
- {
- const clang::TagType *tag_type = dyn_cast<clang::TagType>(qual_type.getTypePtr());
- if (tag_type)
- {
- clang::TagDecl *tag_decl = tag_type->getDecl();
- if (tag_decl)
- {
- if (tag_decl->isCompleteDefinition())
- return true;
-
- if (!allow_completion)
- return false;
-
- if (tag_decl->hasExternalLexicalStorage())
- {
- if (ast)
- {
- ExternalASTSource *external_ast_source = ast->getExternalSource();
- if (external_ast_source)
- {
- external_ast_source->CompleteType(tag_decl);
- return !tag_type->isIncompleteType();
- }
- }
- }
- return false;
- }
- }
-
- }
- break;
-
- case clang::Type::ObjCObject:
- case clang::Type::ObjCInterface:
- {
- const clang::ObjCObjectType *objc_class_type = 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 (class_interface_decl->getDefinition())
- return true;
-
- if (!allow_completion)
- return false;
-
- if (class_interface_decl->hasExternalLexicalStorage())
- {
- if (ast)
- {
- ExternalASTSource *external_ast_source = ast->getExternalSource();
- if (external_ast_source)
- {
- external_ast_source->CompleteType (class_interface_decl);
- return !objc_class_type->isIncompleteType();
- }
- }
- }
- return false;
- }
- }
- }
- break;
-
- case clang::Type::Typedef:
- return GetCompleteQualType (ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType(), allow_completion);
-
- case clang::Type::Elaborated:
- return GetCompleteQualType (ast, cast<ElaboratedType>(qual_type)->getNamedType(), allow_completion);
-
- case clang::Type::Paren:
- return GetCompleteQualType (ast, cast<ParenType>(qual_type)->desugar(), allow_completion);
-
- default:
- break;
- }
-
- return true;
-}
-
-static AccessSpecifier
-ConvertAccessTypeToAccessSpecifier (AccessType access)
+clang::AccessSpecifier
+ClangASTContext::ConvertAccessTypeToAccessSpecifier (AccessType access)
{
switch (access)
{
@@ -194,20 +93,6 @@ ConvertAccessTypeToAccessSpecifier (Acce
return AS_none;
}
-static ObjCIvarDecl::AccessControl
-ConvertAccessTypeToObjCIvarAccessControl (AccessType access)
-{
- switch (access)
- {
- case eAccessNone: return ObjCIvarDecl::None;
- case eAccessPublic: return ObjCIvarDecl::Public;
- case eAccessPrivate: return ObjCIvarDecl::Private;
- case eAccessProtected: return ObjCIvarDecl::Protected;
- case eAccessPackage: return ObjCIvarDecl::Package;
- }
- return ObjCIvarDecl::None;
-}
-
static void
ParseLangArgs
@@ -393,7 +278,8 @@ ClangASTContext::ClangASTContext (const
m_builtins_ap(),
m_callback_tag_decl (NULL),
m_callback_objc_decl (NULL),
- m_callback_baton (NULL)
+ m_callback_baton (NULL),
+ m_pointer_byte_size (0)
{
if (target_triple && target_triple[0])
@@ -429,6 +315,7 @@ ClangASTContext::Clear()
m_identifier_table_ap.reset();
m_selector_table_ap.reset();
m_builtins_ap.reset();
+ m_pointer_byte_size = 0;
}
const char *
@@ -646,80 +533,279 @@ QualTypeMatchesBitSize(const uint64_t bi
return true;
return false;
}
-
-clang_type_t
+ClangASTType
ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (Encoding encoding, uint32_t bit_size)
{
- ASTContext *ast = getASTContext();
-
- assert (ast != NULL);
-
- return GetBuiltinTypeForEncodingAndBitSize (ast, encoding, bit_size);
+ return ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (getASTContext(), encoding, bit_size);
}
-clang_type_t
+ClangASTType
ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (ASTContext *ast, Encoding encoding, uint32_t bit_size)
{
if (!ast)
- return NULL;
+ return ClangASTType();
switch (encoding)
{
case eEncodingInvalid:
if (QualTypeMatchesBitSize (bit_size, ast, ast->VoidPtrTy))
- return ast->VoidPtrTy.getAsOpaquePtr();
+ return ClangASTType (ast, ast->VoidPtrTy.getAsOpaquePtr());
break;
case eEncodingUint:
if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy))
- return ast->UnsignedCharTy.getAsOpaquePtr();
+ return ClangASTType (ast, ast->UnsignedCharTy.getAsOpaquePtr());
if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy))
- return ast->UnsignedShortTy.getAsOpaquePtr();
+ return ClangASTType (ast, ast->UnsignedShortTy.getAsOpaquePtr());
if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedIntTy))
- return ast->UnsignedIntTy.getAsOpaquePtr();
+ return ClangASTType (ast, ast->UnsignedIntTy.getAsOpaquePtr());
if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongTy))
- return ast->UnsignedLongTy.getAsOpaquePtr();
+ return ClangASTType (ast, ast->UnsignedLongTy.getAsOpaquePtr());
if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongLongTy))
- return ast->UnsignedLongLongTy.getAsOpaquePtr();
+ return ClangASTType (ast, ast->UnsignedLongLongTy.getAsOpaquePtr());
if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedInt128Ty))
- return ast->UnsignedInt128Ty.getAsOpaquePtr();
+ return ClangASTType (ast, ast->UnsignedInt128Ty.getAsOpaquePtr());
break;
case eEncodingSint:
if (QualTypeMatchesBitSize (bit_size, ast, ast->CharTy))
- return ast->CharTy.getAsOpaquePtr();
+ return ClangASTType (ast, ast->CharTy.getAsOpaquePtr());
if (QualTypeMatchesBitSize (bit_size, ast, ast->ShortTy))
- return ast->ShortTy.getAsOpaquePtr();
+ return ClangASTType (ast, ast->ShortTy.getAsOpaquePtr());
if (QualTypeMatchesBitSize (bit_size, ast, ast->IntTy))
- return ast->IntTy.getAsOpaquePtr();
+ return ClangASTType (ast, ast->IntTy.getAsOpaquePtr());
if (QualTypeMatchesBitSize (bit_size, ast, ast->LongTy))
- return ast->LongTy.getAsOpaquePtr();
+ return ClangASTType (ast, ast->LongTy.getAsOpaquePtr());
if (QualTypeMatchesBitSize (bit_size, ast, ast->LongLongTy))
- return ast->LongLongTy.getAsOpaquePtr();
+ return ClangASTType (ast, ast->LongLongTy.getAsOpaquePtr());
if (QualTypeMatchesBitSize (bit_size, ast, ast->Int128Ty))
- return ast->Int128Ty.getAsOpaquePtr();
+ return ClangASTType (ast, ast->Int128Ty.getAsOpaquePtr());
break;
case eEncodingIEEE754:
if (QualTypeMatchesBitSize (bit_size, ast, ast->FloatTy))
- return ast->FloatTy.getAsOpaquePtr();
+ return ClangASTType (ast, ast->FloatTy.getAsOpaquePtr());
if (QualTypeMatchesBitSize (bit_size, ast, ast->DoubleTy))
- return ast->DoubleTy.getAsOpaquePtr();
+ return ClangASTType (ast, ast->DoubleTy.getAsOpaquePtr());
if (QualTypeMatchesBitSize (bit_size, ast, ast->LongDoubleTy))
- return ast->LongDoubleTy.getAsOpaquePtr();
+ return ClangASTType (ast, ast->LongDoubleTy.getAsOpaquePtr());
break;
case eEncodingVector:
// Sanity check that bit_size is a multiple of 8's.
if (bit_size && !(bit_size & 0x7u))
- return ast->getExtVectorType (ast->UnsignedCharTy, bit_size/8).getAsOpaquePtr();
+ return ClangASTType (ast, ast->getExtVectorType (ast->UnsignedCharTy, bit_size/8).getAsOpaquePtr());
break;
}
- return NULL;
+ return ClangASTType();
+}
+
+
+
+lldb::BasicType
+ClangASTContext::GetBasicTypeEnumeration (const ConstString &name)
+{
+ if (name)
+ {
+ typedef UniqueCStringMap<lldb::BasicType> TypeNameToBasicTypeMap;
+ static TypeNameToBasicTypeMap g_type_map;
+ static std::once_flag g_once_flag;
+ std::call_once(g_once_flag, [](){
+ // "void"
+ g_type_map.Append(ConstString("void").GetCString(), eBasicTypeVoid);
+
+ // "char"
+ g_type_map.Append(ConstString("char").GetCString(), eBasicTypeChar);
+ g_type_map.Append(ConstString("signed char").GetCString(), eBasicTypeSignedChar);
+ g_type_map.Append(ConstString("unsigned char").GetCString(), eBasicTypeUnsignedChar);
+ g_type_map.Append(ConstString("wchar_t").GetCString(), eBasicTypeWChar);
+ g_type_map.Append(ConstString("signed wchar_t").GetCString(), eBasicTypeSignedWChar);
+ g_type_map.Append(ConstString("unsigned wchar_t").GetCString(), eBasicTypeUnsignedWChar);
+ // "short"
+ g_type_map.Append(ConstString("short").GetCString(), eBasicTypeShort);
+ g_type_map.Append(ConstString("short int").GetCString(), eBasicTypeShort);
+ g_type_map.Append(ConstString("unsigned short").GetCString(), eBasicTypeUnsignedShort);
+ g_type_map.Append(ConstString("unsigned short int").GetCString(), eBasicTypeUnsignedShort);
+
+ // "int"
+ g_type_map.Append(ConstString("int").GetCString(), eBasicTypeInt);
+ g_type_map.Append(ConstString("signed int").GetCString(), eBasicTypeInt);
+ g_type_map.Append(ConstString("unsigned int").GetCString(), eBasicTypeUnsignedInt);
+ g_type_map.Append(ConstString("unsigned").GetCString(), eBasicTypeUnsignedInt);
+
+ // "long"
+ g_type_map.Append(ConstString("long").GetCString(), eBasicTypeLong);
+ g_type_map.Append(ConstString("long int").GetCString(), eBasicTypeLong);
+ g_type_map.Append(ConstString("unsigned long").GetCString(), eBasicTypeUnsignedLong);
+ g_type_map.Append(ConstString("unsigned long int").GetCString(), eBasicTypeUnsignedLong);
+
+ // "long long"
+ g_type_map.Append(ConstString("long long").GetCString(), eBasicTypeLongLong);
+ g_type_map.Append(ConstString("long long int").GetCString(), eBasicTypeLongLong);
+ g_type_map.Append(ConstString("unsigned long long").GetCString(), eBasicTypeUnsignedLongLong);
+ g_type_map.Append(ConstString("unsigned long long int").GetCString(), eBasicTypeUnsignedLongLong);
+
+ // "int128"
+ g_type_map.Append(ConstString("__int128_t").GetCString(), eBasicTypeInt128);
+ g_type_map.Append(ConstString("__uint128_t").GetCString(), eBasicTypeUnsignedInt128);
+
+ // Miscelaneous
+ g_type_map.Append(ConstString("bool").GetCString(), eBasicTypeBool);
+ g_type_map.Append(ConstString("float").GetCString(), eBasicTypeFloat);
+ g_type_map.Append(ConstString("double").GetCString(), eBasicTypeDouble);
+ g_type_map.Append(ConstString("long double").GetCString(), eBasicTypeLongDouble);
+ g_type_map.Append(ConstString("id").GetCString(), eBasicTypeObjCID);
+ g_type_map.Append(ConstString("SEL").GetCString(), eBasicTypeObjCSel);
+ g_type_map.Append(ConstString("nullptr").GetCString(), eBasicTypeNullPtr);
+ g_type_map.Sort();
+ });
+
+ return g_type_map.Find(name.GetCString(), eBasicTypeInvalid);
+ }
+ return eBasicTypeInvalid;
+}
+
+ClangASTType
+ClangASTContext::GetBasicType (ASTContext *ast, const ConstString &name)
+{
+ if (ast)
+ {
+ lldb::BasicType basic_type = ClangASTContext::GetBasicTypeEnumeration (name);
+ return ClangASTContext::GetBasicType (ast, basic_type);
+ }
+ return ClangASTType();
+}
+
+uint32_t
+ClangASTContext::GetPointerByteSize ()
+{
+ if (m_pointer_byte_size == 0)
+ m_pointer_byte_size = GetBasicType(lldb::eBasicTypeVoid).GetPointerType().GetByteSize();
+ return m_pointer_byte_size;
+}
+
+ClangASTType
+ClangASTContext::GetBasicType (lldb::BasicType basic_type)
+{
+ return GetBasicType (getASTContext(), basic_type);
+}
+
+ClangASTType
+ClangASTContext::GetBasicType (ASTContext *ast, lldb::BasicType basic_type)
+{
+ if (ast)
+ {
+ clang_type_t clang_type = NULL;
+
+ 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 ClangASTType (ast, clang_type);
+ }
+ return ClangASTType();
}
-clang_type_t
+
+ClangASTType
ClangASTContext::GetBuiltinTypeForDWARFEncodingAndBitSize (const char *type_name, uint32_t dw_ate, uint32_t bit_size)
{
ASTContext *ast = getASTContext();
@@ -735,18 +821,18 @@ ClangASTContext::GetBuiltinTypeForDWARFE
case DW_ATE_address:
if (QualTypeMatchesBitSize (bit_size, ast, ast->VoidPtrTy))
- return ast->VoidPtrTy.getAsOpaquePtr();
+ return ClangASTType (ast, ast->VoidPtrTy.getAsOpaquePtr());
break;
case DW_ATE_boolean:
if (QualTypeMatchesBitSize (bit_size, ast, ast->BoolTy))
- return ast->BoolTy.getAsOpaquePtr();
+ return ClangASTType (ast, ast->BoolTy.getAsOpaquePtr());
if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy))
- return ast->UnsignedCharTy.getAsOpaquePtr();
+ return ClangASTType (ast, ast->UnsignedCharTy.getAsOpaquePtr());
if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy))
- return ast->UnsignedShortTy.getAsOpaquePtr();
+ return ClangASTType (ast, ast->UnsignedShortTy.getAsOpaquePtr());
if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedIntTy))
- return ast->UnsignedIntTy.getAsOpaquePtr();
+ return ClangASTType (ast, ast->UnsignedIntTy.getAsOpaquePtr());
break;
case DW_ATE_lo_user:
@@ -755,33 +841,33 @@ ClangASTContext::GetBuiltinTypeForDWARFE
{
if (::strstr(type_name, "complex"))
{
- clang_type_t complex_int_clang_type = GetBuiltinTypeForDWARFEncodingAndBitSize ("int", DW_ATE_signed, bit_size/2);
- return ast->getComplexType (QualType::getFromOpaquePtr(complex_int_clang_type)).getAsOpaquePtr();
+ ClangASTType complex_int_clang_type = GetBuiltinTypeForDWARFEncodingAndBitSize ("int", DW_ATE_signed, bit_size/2);
+ return ClangASTType (ast, ast->getComplexType (complex_int_clang_type.GetQualType()).getAsOpaquePtr());
}
}
break;
case DW_ATE_complex_float:
if (QualTypeMatchesBitSize (bit_size, ast, ast->FloatComplexTy))
- return ast->FloatComplexTy.getAsOpaquePtr();
+ return ClangASTType (ast, ast->FloatComplexTy.getAsOpaquePtr());
else if (QualTypeMatchesBitSize (bit_size, ast, ast->DoubleComplexTy))
- return ast->DoubleComplexTy.getAsOpaquePtr();
+ return ClangASTType (ast, ast->DoubleComplexTy.getAsOpaquePtr());
else if (QualTypeMatchesBitSize (bit_size, ast, ast->LongDoubleComplexTy))
- return ast->LongDoubleComplexTy.getAsOpaquePtr();
+ return ClangASTType (ast, ast->LongDoubleComplexTy.getAsOpaquePtr());
else
{
- clang_type_t complex_float_clang_type = GetBuiltinTypeForDWARFEncodingAndBitSize ("float", DW_ATE_float, bit_size/2);
- return ast->getComplexType (QualType::getFromOpaquePtr(complex_float_clang_type)).getAsOpaquePtr();
+ ClangASTType complex_float_clang_type = GetBuiltinTypeForDWARFEncodingAndBitSize ("float", DW_ATE_float, bit_size/2);
+ return ClangASTType (ast, ast->getComplexType (complex_float_clang_type.GetQualType()).getAsOpaquePtr());
}
break;
case DW_ATE_float:
if (QualTypeMatchesBitSize (bit_size, ast, ast->FloatTy))
- return ast->FloatTy.getAsOpaquePtr();
+ return ClangASTType (ast, ast->FloatTy.getAsOpaquePtr());
if (QualTypeMatchesBitSize (bit_size, ast, ast->DoubleTy))
- return ast->DoubleTy.getAsOpaquePtr();
+ return ClangASTType (ast, ast->DoubleTy.getAsOpaquePtr());
if (QualTypeMatchesBitSize (bit_size, ast, ast->LongDoubleTy))
- return ast->LongDoubleTy.getAsOpaquePtr();
+ return ClangASTType (ast, ast->LongDoubleTy.getAsOpaquePtr());
break;
case DW_ATE_signed:
@@ -789,47 +875,47 @@ ClangASTContext::GetBuiltinTypeForDWARFE
{
if (streq(type_name, "wchar_t") &&
QualTypeMatchesBitSize (bit_size, ast, ast->WCharTy))
- return ast->WCharTy.getAsOpaquePtr();
+ return ClangASTType (ast, ast->WCharTy.getAsOpaquePtr());
if (streq(type_name, "void") &&
QualTypeMatchesBitSize (bit_size, ast, ast->VoidTy))
- return ast->VoidTy.getAsOpaquePtr();
+ return ClangASTType (ast, ast->VoidTy.getAsOpaquePtr());
if (strstr(type_name, "long long") &&
QualTypeMatchesBitSize (bit_size, ast, ast->LongLongTy))
- return ast->LongLongTy.getAsOpaquePtr();
+ return ClangASTType (ast, ast->LongLongTy.getAsOpaquePtr());
if (strstr(type_name, "long") &&
QualTypeMatchesBitSize (bit_size, ast, ast->LongTy))
- return ast->LongTy.getAsOpaquePtr();
+ return ClangASTType (ast, ast->LongTy.getAsOpaquePtr());
if (strstr(type_name, "short") &&
QualTypeMatchesBitSize (bit_size, ast, ast->ShortTy))
- return ast->ShortTy.getAsOpaquePtr();
+ return ClangASTType (ast, ast->ShortTy.getAsOpaquePtr());
if (strstr(type_name, "char"))
{
if (QualTypeMatchesBitSize (bit_size, ast, ast->CharTy))
- return ast->CharTy.getAsOpaquePtr();
+ return ClangASTType (ast, ast->CharTy.getAsOpaquePtr());
if (QualTypeMatchesBitSize (bit_size, ast, ast->SignedCharTy))
- return ast->SignedCharTy.getAsOpaquePtr();
+ return ClangASTType (ast, ast->SignedCharTy.getAsOpaquePtr());
}
if (strstr(type_name, "int"))
{
if (QualTypeMatchesBitSize (bit_size, ast, ast->IntTy))
- return ast->IntTy.getAsOpaquePtr();
+ return ClangASTType (ast, ast->IntTy.getAsOpaquePtr());
if (QualTypeMatchesBitSize (bit_size, ast, ast->Int128Ty))
- return ast->Int128Ty.getAsOpaquePtr();
+ return ClangASTType (ast, ast->Int128Ty.getAsOpaquePtr());
}
}
// We weren't able to match up a type name, just search by size
if (QualTypeMatchesBitSize (bit_size, ast, ast->CharTy))
- return ast->CharTy.getAsOpaquePtr();
+ return ClangASTType (ast, ast->CharTy.getAsOpaquePtr());
if (QualTypeMatchesBitSize (bit_size, ast, ast->ShortTy))
- return ast->ShortTy.getAsOpaquePtr();
+ return ClangASTType (ast, ast->ShortTy.getAsOpaquePtr());
if (QualTypeMatchesBitSize (bit_size, ast, ast->IntTy))
- return ast->IntTy.getAsOpaquePtr();
+ return ClangASTType (ast, ast->IntTy.getAsOpaquePtr());
if (QualTypeMatchesBitSize (bit_size, ast, ast->LongTy))
- return ast->LongTy.getAsOpaquePtr();
+ return ClangASTType (ast, ast->LongTy.getAsOpaquePtr());
if (QualTypeMatchesBitSize (bit_size, ast, ast->LongLongTy))
- return ast->LongLongTy.getAsOpaquePtr();
+ return ClangASTType (ast, ast->LongLongTy.getAsOpaquePtr());
if (QualTypeMatchesBitSize (bit_size, ast, ast->Int128Ty))
- return ast->Int128Ty.getAsOpaquePtr();
+ return ClangASTType (ast, ast->Int128Ty.getAsOpaquePtr());
break;
case DW_ATE_signed_char:
@@ -838,13 +924,13 @@ ClangASTContext::GetBuiltinTypeForDWARFE
if (streq(type_name, "signed char"))
{
if (QualTypeMatchesBitSize (bit_size, ast, ast->SignedCharTy))
- return ast->SignedCharTy.getAsOpaquePtr();
+ return ClangASTType (ast, ast->SignedCharTy.getAsOpaquePtr());
}
}
if (QualTypeMatchesBitSize (bit_size, ast, ast->CharTy))
- return ast->CharTy.getAsOpaquePtr();
+ return ClangASTType (ast, ast->CharTy.getAsOpaquePtr());
if (QualTypeMatchesBitSize (bit_size, ast, ast->SignedCharTy))
- return ast->SignedCharTy.getAsOpaquePtr();
+ return ClangASTType (ast, ast->SignedCharTy.getAsOpaquePtr());
break;
case DW_ATE_unsigned:
@@ -853,51 +939,51 @@ ClangASTContext::GetBuiltinTypeForDWARFE
if (strstr(type_name, "long long"))
{
if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongLongTy))
- return ast->UnsignedLongLongTy.getAsOpaquePtr();
+ return ClangASTType (ast, ast->UnsignedLongLongTy.getAsOpaquePtr());
}
else if (strstr(type_name, "long"))
{
if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongTy))
- return ast->UnsignedLongTy.getAsOpaquePtr();
+ return ClangASTType (ast, ast->UnsignedLongTy.getAsOpaquePtr());
}
else if (strstr(type_name, "short"))
{
if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy))
- return ast->UnsignedShortTy.getAsOpaquePtr();
+ return ClangASTType (ast, ast->UnsignedShortTy.getAsOpaquePtr());
}
else if (strstr(type_name, "char"))
{
if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy))
- return ast->UnsignedCharTy.getAsOpaquePtr();
+ return ClangASTType (ast, ast->UnsignedCharTy.getAsOpaquePtr());
}
else if (strstr(type_name, "int"))
{
if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedIntTy))
- return ast->UnsignedIntTy.getAsOpaquePtr();
+ return ClangASTType (ast, ast->UnsignedIntTy.getAsOpaquePtr());
if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedInt128Ty))
- return ast->UnsignedInt128Ty.getAsOpaquePtr();
+ return ClangASTType (ast, ast->UnsignedInt128Ty.getAsOpaquePtr());
}
}
// We weren't able to match up a type name, just search by size
if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy))
- return ast->UnsignedCharTy.getAsOpaquePtr();
+ return ClangASTType (ast, ast->UnsignedCharTy.getAsOpaquePtr());
if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy))
- return ast->UnsignedShortTy.getAsOpaquePtr();
+ return ClangASTType (ast, ast->UnsignedShortTy.getAsOpaquePtr());
if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedIntTy))
- return ast->UnsignedIntTy.getAsOpaquePtr();
+ return ClangASTType (ast, ast->UnsignedIntTy.getAsOpaquePtr());
if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongTy))
- return ast->UnsignedLongTy.getAsOpaquePtr();
+ return ClangASTType (ast, ast->UnsignedLongTy.getAsOpaquePtr());
if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongLongTy))
- return ast->UnsignedLongLongTy.getAsOpaquePtr();
+ return ClangASTType (ast, ast->UnsignedLongLongTy.getAsOpaquePtr());
if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedInt128Ty))
- return ast->UnsignedInt128Ty.getAsOpaquePtr();
+ return ClangASTType (ast, ast->UnsignedInt128Ty.getAsOpaquePtr());
break;
case DW_ATE_unsigned_char:
if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy))
- return ast->UnsignedCharTy.getAsOpaquePtr();
+ return ClangASTType (ast, ast->UnsignedCharTy.getAsOpaquePtr());
if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy))
- return ast->UnsignedShortTy.getAsOpaquePtr();
+ return ClangASTType (ast, ast->UnsignedShortTy.getAsOpaquePtr());
break;
case DW_ATE_imaginary_float:
@@ -908,11 +994,11 @@ ClangASTContext::GetBuiltinTypeForDWARFE
{
if (streq(type_name, "char16_t"))
{
- return ast->Char16Ty.getAsOpaquePtr();
+ return ClangASTType (ast, ast->Char16Ty.getAsOpaquePtr());
}
else if (streq(type_name, "char32_t"))
{
- return ast->Char32Ty.getAsOpaquePtr();
+ return ClangASTType (ast, ast->Char32Ty.getAsOpaquePtr());
}
}
break;
@@ -928,89 +1014,27 @@ ClangASTContext::GetBuiltinTypeForDWARFE
{
Host::SystemLog (Host::eSystemLogError, "error: need to add support for DW_TAG_base_type encoded with DW_ATE = 0x%x, bit_size = %u\n", dw_ate, bit_size);
}
- return NULL;
-}
-
-clang_type_t
-ClangASTContext::GetBuiltInType_void(ASTContext *ast)
-{
- return ast->VoidTy.getAsOpaquePtr();
-}
-
-clang_type_t
-ClangASTContext::GetBuiltInType_bool()
-{
- return getASTContext()->BoolTy.getAsOpaquePtr();
-}
-
-clang_type_t
-ClangASTContext::GetBuiltInType_objc_id()
-{
- return getASTContext()->getObjCIdType().getAsOpaquePtr();
-}
-
-lldb::clang_type_t
-ClangASTContext::GetBuiltInType_objc_id(clang::ASTContext *ast)
-{
- return ast->getObjCIdType().getAsOpaquePtr();
-}
-
-clang_type_t
-ClangASTContext::GetBuiltInType_objc_Class()
-{
- return getASTContext()->getObjCClassType().getAsOpaquePtr();
-}
-
-clang_type_t
-ClangASTContext::GetBuiltInType_objc_selector()
-{
- return getASTContext()->getObjCSelType().getAsOpaquePtr();
+ return ClangASTType ();
}
-clang_type_t
+ClangASTType
ClangASTContext::GetUnknownAnyType(clang::ASTContext *ast)
{
- return ast->UnknownAnyTy.getAsOpaquePtr();
+ if (ast)
+ return ClangASTType (ast, ast->UnknownAnyTy.getAsOpaquePtr());
+ return ClangASTType();
}
-clang_type_t
+ClangASTType
ClangASTContext::GetCStringType (bool is_const)
{
- QualType char_type(getASTContext()->CharTy);
+ ASTContext *ast = getASTContext();
+ QualType char_type(ast->CharTy);
if (is_const)
char_type.addConst();
- return getASTContext()->getPointerType(char_type).getAsOpaquePtr();
-}
-
-clang_type_t
-ClangASTContext::GetVoidType()
-{
- return GetVoidType(getASTContext());
-}
-
-clang_type_t
-ClangASTContext::GetVoidType(ASTContext *ast)
-{
- return ast->VoidTy.getAsOpaquePtr();
-}
-
-clang_type_t
-ClangASTContext::GetVoidPtrType (bool is_const)
-{
- return GetVoidPtrType(getASTContext(), is_const);
-}
-
-clang_type_t
-ClangASTContext::GetVoidPtrType (ASTContext *ast, bool is_const)
-{
- QualType void_ptr_type(ast->VoidPtrTy);
-
- if (is_const)
- void_ptr_type.addConst();
-
- return void_ptr_type.getAsOpaquePtr();
+ return ClangASTType (ast, ast->getPointerType(char_type).getAsOpaquePtr());
}
clang::DeclContext *
@@ -1019,21 +1043,20 @@ ClangASTContext::GetTranslationUnitDecl
return ast->getTranslationUnitDecl();
}
-clang_type_t
+ClangASTType
ClangASTContext::CopyType (ASTContext *dst_ast,
- ASTContext *src_ast,
- clang_type_t clang_type)
+ ClangASTType src)
{
FileSystemOptions file_system_options;
+ ASTContext *src_ast = src.GetASTContext();
FileManager file_manager (file_system_options);
ASTImporter importer(*dst_ast, file_manager,
*src_ast, file_manager,
false);
- QualType src (QualType::getFromOpaquePtr(clang_type));
- QualType dst (importer.Import(src));
+ QualType dst (importer.Import(src.GetQualType()));
- return dst.getAsOpaquePtr();
+ return ClangASTType (dst_ast, dst.getAsOpaquePtr());
}
@@ -1052,16 +1075,19 @@ ClangASTContext::CopyDecl (ASTContext *d
}
bool
-ClangASTContext::AreTypesSame (ASTContext *ast,
- clang_type_t type1,
- clang_type_t type2,
+ClangASTContext::AreTypesSame (ClangASTType type1,
+ ClangASTType type2,
bool ignore_qualifiers)
{
- if (type1 == type2)
+ ASTContext *ast = type1.GetASTContext();
+ if (ast != type2.GetASTContext())
+ return false;
+
+ if (type1.GetOpaqueQualType() == type2.GetOpaqueQualType())
return true;
- QualType type1_qual = QualType::getFromOpaquePtr(type1);
- QualType type2_qual = QualType::getFromOpaquePtr(type2);
+ QualType type1_qual = type1.GetQualType();
+ QualType type2_qual = type2.GetQualType();
if (ignore_qualifiers)
{
@@ -1069,74 +1095,37 @@ ClangASTContext::AreTypesSame (ASTContex
type2_qual = type2_qual.getUnqualifiedType();
}
- return ast->hasSameType (type1_qual,
- type2_qual);
-}
-
-#pragma mark CVR modifiers
-
-clang_type_t
-ClangASTContext::AddConstModifier (clang_type_t clang_type)
-{
- if (clang_type)
- {
- QualType result(QualType::getFromOpaquePtr(clang_type));
- result.addConst();
- return result.getAsOpaquePtr();
- }
- return NULL;
-}
-
-clang_type_t
-ClangASTContext::AddRestrictModifier (clang_type_t clang_type)
-{
- if (clang_type)
- {
- QualType result(QualType::getFromOpaquePtr(clang_type));
- result.getQualifiers().setRestrict (true);
- return result.getAsOpaquePtr();
- }
- return NULL;
-}
-
-clang_type_t
-ClangASTContext::AddVolatileModifier (clang_type_t clang_type)
-{
- if (clang_type)
- {
- QualType result(QualType::getFromOpaquePtr(clang_type));
- result.getQualifiers().setVolatile (true);
- return result.getAsOpaquePtr();
- }
- return NULL;
+ return ast->hasSameType (type1_qual, type2_qual);
}
-clang_type_t
+ClangASTType
ClangASTContext::GetTypeForDecl (TagDecl *decl)
{
// No need to call the getASTContext() accessor (which can create the AST
// if it isn't created yet, because we can't have created a decl in this
// AST if our AST didn't already exist...
- if (m_ast_ap.get())
- return m_ast_ap->getTagDeclType(decl).getAsOpaquePtr();
- return NULL;
+ ASTContext *ast = m_ast_ap.get();
+ if (ast)
+ return ClangASTType (ast, ast->getTagDeclType(decl).getAsOpaquePtr());
+ return ClangASTType();
}
-clang_type_t
+ClangASTType
ClangASTContext::GetTypeForDecl (ObjCInterfaceDecl *decl)
{
// No need to call the getASTContext() accessor (which can create the AST
// if it isn't created yet, because we can't have created a decl in this
// AST if our AST didn't already exist...
- if (m_ast_ap.get())
- return m_ast_ap->getObjCInterfaceType(decl).getAsOpaquePtr();
- return NULL;
+ ASTContext *ast = m_ast_ap.get();
+ if (ast)
+ return ClangASTType (ast, ast->getObjCInterfaceType(decl).getAsOpaquePtr());
+ return ClangASTType();
}
#pragma mark Structure, Unions, Classes
-clang_type_t
+ClangASTType
ClangASTContext::CreateRecordType (DeclContext *decl_ctx,
AccessType access_type,
const char *name,
@@ -1181,9 +1170,9 @@ ClangASTContext::CreateRecordType (DeclC
if (decl_ctx)
decl_ctx->addDecl (decl);
- return ast->getTagDeclType(decl).getAsOpaquePtr();
+ return ClangASTType(ast, ast->getTagDeclType(decl).getAsOpaquePtr());
}
- return NULL;
+ return ClangASTType();
}
static TemplateParameterList *
@@ -1385,85 +1374,16 @@ ClangASTContext::CreateClassTemplateSpec
return class_template_specialization_decl;
}
-lldb::clang_type_t
+ClangASTType
ClangASTContext::CreateClassTemplateSpecializationType (ClassTemplateSpecializationDecl *class_template_specialization_decl)
{
if (class_template_specialization_decl)
{
ASTContext *ast = getASTContext();
if (ast)
- return ast->getTagDeclType(class_template_specialization_decl).getAsOpaquePtr();
- }
- return NULL;
-}
-
-bool
-ClangASTContext::SetHasExternalStorage (clang_type_t clang_type, bool has_extern)
-{
- if (clang_type == NULL)
- return false;
-
- QualType qual_type (QualType::getFromOpaquePtr(clang_type));
-
- const clang::Type::TypeClass type_class = qual_type->getTypeClass();
- switch (type_class)
- {
- case clang::Type::Record:
- {
- CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
- if (cxx_record_decl)
- {
- cxx_record_decl->setHasExternalLexicalStorage (has_extern);
- cxx_record_decl->setHasExternalVisibleStorage (has_extern);
- return true;
- }
- }
- break;
-
- case clang::Type::Enum:
- {
- EnumDecl *enum_decl = cast<EnumType>(qual_type)->getDecl();
- if (enum_decl)
- {
- enum_decl->setHasExternalLexicalStorage (has_extern);
- enum_decl->setHasExternalVisibleStorage (has_extern);
- return true;
- }
- }
- break;
-
- case clang::Type::ObjCObject:
- case clang::Type::ObjCInterface:
- {
- const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
- assert (objc_class_type);
- if (objc_class_type)
- {
- ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
-
- if (class_interface_decl)
- {
- class_interface_decl->setHasExternalLexicalStorage (has_extern);
- class_interface_decl->setHasExternalVisibleStorage (has_extern);
- return true;
- }
- }
- }
- break;
-
- case clang::Type::Typedef:
- return ClangASTContext::SetHasExternalStorage (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), has_extern);
-
- case clang::Type::Elaborated:
- return ClangASTContext::SetHasExternalStorage (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), has_extern);
-
- case clang::Type::Paren:
- return ClangASTContext::SetHasExternalStorage (cast<ParenType>(qual_type)->desugar().getAsOpaquePtr(), has_extern);
-
- default:
- break;
+ return ClangASTType(ast, ast->getTagDeclType(class_template_specialization_decl).getAsOpaquePtr());
}
- return false;
+ return ClangASTType();
}
static bool
@@ -1722,500 +1642,35 @@ ClangASTContext::CheckOverloadedOperator
return false;
}
-CXXMethodDecl *
-ClangASTContext::AddMethodToCXXRecordType
-(
- ASTContext *ast,
- clang_type_t record_opaque_type,
- const char *name,
- clang_type_t method_opaque_type,
- lldb::AccessType access,
- bool is_virtual,
- bool is_static,
- bool is_inline,
- bool is_explicit,
- bool is_attr_used,
- bool is_artificial
-)
+clang::AccessSpecifier
+ClangASTContext::UnifyAccessSpecifiers (clang::AccessSpecifier lhs, clang::AccessSpecifier rhs)
{
- if (!record_opaque_type || !method_opaque_type || !name)
- return NULL;
-
- assert(ast);
-
- IdentifierTable *identifier_table = &ast->Idents;
-
- assert(identifier_table);
-
- QualType record_qual_type(QualType::getFromOpaquePtr(record_opaque_type));
-
- CXXRecordDecl *cxx_record_decl = record_qual_type->getAsCXXRecordDecl();
-
- if (cxx_record_decl == NULL)
- return NULL;
-
- QualType method_qual_type (QualType::getFromOpaquePtr (method_opaque_type));
+ clang::AccessSpecifier ret = lhs;
- CXXMethodDecl *cxx_method_decl = NULL;
+ // 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;
+ }
- DeclarationName decl_name (&identifier_table->get(name));
+ return ret;
+}
- const clang::FunctionType *function_Type = dyn_cast<FunctionType>(method_qual_type.getTypePtr());
-
- if (function_Type == NULL)
- return NULL;
-
- const FunctionProtoType *method_function_prototype (dyn_cast<FunctionProtoType>(function_Type));
-
- if (!method_function_prototype)
- return NULL;
-
- unsigned int num_params = method_function_prototype->getNumArgs();
-
- CXXDestructorDecl *cxx_dtor_decl(NULL);
- CXXConstructorDecl *cxx_ctor_decl(NULL);
-
- if (is_artificial)
- return NULL; // skip everything artificial
-
- if (name[0] == '~')
- {
- cxx_dtor_decl = CXXDestructorDecl::Create (*ast,
- cxx_record_decl,
- SourceLocation(),
- DeclarationNameInfo (ast->DeclarationNames.getCXXDestructorName (ast->getCanonicalType (record_qual_type)), SourceLocation()),
- method_qual_type,
- NULL,
- is_inline,
- is_artificial);
- cxx_method_decl = cxx_dtor_decl;
- }
- else if (decl_name == cxx_record_decl->getDeclName())
- {
- cxx_ctor_decl = CXXConstructorDecl::Create (*ast,
- cxx_record_decl,
- SourceLocation(),
- DeclarationNameInfo (ast->DeclarationNames.getCXXConstructorName (ast->getCanonicalType (record_qual_type)), SourceLocation()),
- method_qual_type,
- NULL, // TypeSourceInfo *
- is_explicit,
- is_inline,
- is_artificial,
- false /*is_constexpr*/);
- cxx_method_decl = cxx_ctor_decl;
- }
- else
- {
- clang::StorageClass SC = is_static ? SC_Static : SC_None;
- OverloadedOperatorKind op_kind = NUM_OVERLOADED_OPERATORS;
-
- if (IsOperator (name, op_kind))
- {
- if (op_kind != NUM_OVERLOADED_OPERATORS)
- {
- // Check the number of operator parameters. Sometimes we have
- // seen bad DWARF that doesn't correctly describe operators and
- // if we try to create a methed and add it to the class, clang
- // will assert and crash, so we need to make sure things are
- // acceptable.
- if (!ClangASTContext::CheckOverloadedOperatorKindParameterCount (op_kind, num_params))
- return NULL;
- cxx_method_decl = CXXMethodDecl::Create (*ast,
- cxx_record_decl,
- SourceLocation(),
- DeclarationNameInfo (ast->DeclarationNames.getCXXOperatorName (op_kind), SourceLocation()),
- method_qual_type,
- NULL, // TypeSourceInfo *
- SC,
- is_inline,
- false /*is_constexpr*/,
- SourceLocation());
- }
- else if (num_params == 0)
- {
- // Conversion operators don't take params...
- cxx_method_decl = CXXConversionDecl::Create (*ast,
- cxx_record_decl,
- SourceLocation(),
- DeclarationNameInfo (ast->DeclarationNames.getCXXConversionFunctionName (ast->getCanonicalType (function_Type->getResultType())), SourceLocation()),
- method_qual_type,
- NULL, // TypeSourceInfo *
- is_inline,
- is_explicit,
- false /*is_constexpr*/,
- SourceLocation());
- }
- }
-
- if (cxx_method_decl == NULL)
- {
- cxx_method_decl = CXXMethodDecl::Create (*ast,
- cxx_record_decl,
- SourceLocation(),
- DeclarationNameInfo (decl_name, SourceLocation()),
- method_qual_type,
- NULL, // TypeSourceInfo *
- SC,
- is_inline,
- false /*is_constexpr*/,
- SourceLocation());
- }
- }
-
- AccessSpecifier access_specifier = ConvertAccessTypeToAccessSpecifier (access);
-
- cxx_method_decl->setAccess (access_specifier);
- cxx_method_decl->setVirtualAsWritten (is_virtual);
-
- if (is_attr_used)
- cxx_method_decl->addAttr(::new (*ast) UsedAttr(SourceRange(), *ast));
-
- // Populate the method decl with parameter decls
-
- llvm::SmallVector<ParmVarDecl *, 12> params;
-
- for (unsigned param_index = 0;
- param_index < num_params;
- ++param_index)
- {
- params.push_back (ParmVarDecl::Create (*ast,
- cxx_method_decl,
- SourceLocation(),
- SourceLocation(),
- NULL, // anonymous
- method_function_prototype->getArgType(param_index),
- NULL,
- SC_None,
- NULL));
- }
-
- cxx_method_decl->setParams (ArrayRef<ParmVarDecl*>(params));
-
- cxx_record_decl->addDecl (cxx_method_decl);
-
- // Sometimes the debug info will mention a constructor (default/copy/move),
- // destructor, or assignment operator (copy/move) but there won't be any
- // version of this in the code. So we check if the function was artificially
- // generated and if it is trivial and this lets the compiler/backend know
- // that it can inline the IR for these when it needs to and we can avoid a
- // "missing function" error when running expressions.
-
- if (is_artificial)
- {
- if (cxx_ctor_decl &&
- ((cxx_ctor_decl->isDefaultConstructor() && cxx_record_decl->hasTrivialDefaultConstructor ()) ||
- (cxx_ctor_decl->isCopyConstructor() && cxx_record_decl->hasTrivialCopyConstructor ()) ||
- (cxx_ctor_decl->isMoveConstructor() && cxx_record_decl->hasTrivialMoveConstructor ()) ))
- {
- cxx_ctor_decl->setDefaulted();
- cxx_ctor_decl->setTrivial(true);
- }
- else if (cxx_dtor_decl)
- {
- if (cxx_record_decl->hasTrivialDestructor())
- {
- cxx_dtor_decl->setDefaulted();
- cxx_dtor_decl->setTrivial(true);
- }
- }
- else if ((cxx_method_decl->isCopyAssignmentOperator() && cxx_record_decl->hasTrivialCopyAssignment()) ||
- (cxx_method_decl->isMoveAssignmentOperator() && cxx_record_decl->hasTrivialMoveAssignment()))
- {
- cxx_method_decl->setDefaulted();
- cxx_method_decl->setTrivial(true);
- }
- }
-
-#ifdef LLDB_CONFIGURATION_DEBUG
- VerifyDecl(cxx_method_decl);
-#endif
-
-// printf ("decl->isPolymorphic() = %i\n", cxx_record_decl->isPolymorphic());
-// printf ("decl->isAggregate() = %i\n", cxx_record_decl->isAggregate());
-// printf ("decl->isPOD() = %i\n", cxx_record_decl->isPOD());
-// printf ("decl->isEmpty() = %i\n", cxx_record_decl->isEmpty());
-// printf ("decl->isAbstract() = %i\n", cxx_record_decl->isAbstract());
-// printf ("decl->hasTrivialConstructor() = %i\n", cxx_record_decl->hasTrivialConstructor());
-// printf ("decl->hasTrivialCopyConstructor() = %i\n", cxx_record_decl->hasTrivialCopyConstructor());
-// printf ("decl->hasTrivialCopyAssignment() = %i\n", cxx_record_decl->hasTrivialCopyAssignment());
-// printf ("decl->hasTrivialDestructor() = %i\n", cxx_record_decl->hasTrivialDestructor());
- return cxx_method_decl;
-}
-
-clang::FieldDecl *
-ClangASTContext::AddFieldToRecordType
-(
- ASTContext *ast,
- clang_type_t record_clang_type,
- const char *name,
- clang_type_t field_type,
- AccessType access,
- uint32_t bitfield_bit_size
-)
-{
- if (record_clang_type == NULL || field_type == NULL)
- return NULL;
-
- FieldDecl *field = NULL;
- IdentifierTable *identifier_table = &ast->Idents;
-
- assert (ast != NULL);
- assert (identifier_table != NULL);
-
- QualType record_qual_type(QualType::getFromOpaquePtr(record_clang_type));
-
- const clang::Type *clang_type = record_qual_type.getTypePtr();
- if (clang_type)
- {
- const RecordType *record_type = dyn_cast<RecordType>(clang_type);
-
- if (record_type)
- {
- RecordDecl *record_decl = record_type->getDecl();
-
- clang::Expr *bit_width = NULL;
- if (bitfield_bit_size != 0)
- {
- APInt bitfield_bit_size_apint(ast->getTypeSize(ast->IntTy), bitfield_bit_size);
- bit_width = new (*ast)IntegerLiteral (*ast, bitfield_bit_size_apint, ast->IntTy, SourceLocation());
- }
- field = FieldDecl::Create (*ast,
- record_decl,
- SourceLocation(),
- SourceLocation(),
- name ? &identifier_table->get(name) : NULL, // Identifier
- QualType::getFromOpaquePtr(field_type), // Field type
- NULL, // TInfo *
- bit_width, // BitWidth
- false, // Mutable
- ICIS_NoInit); // HasInit
-
- if (!name) {
- // Determine whether this field corresponds to an anonymous
- // struct or union.
- if (const TagType *TagT = field->getType()->getAs<TagType>()) {
- if (RecordDecl *Rec = dyn_cast<RecordDecl>(TagT->getDecl()))
- if (!Rec->getDeclName()) {
- Rec->setAnonymousStructOrUnion(true);
- field->setImplicit();
-
- }
- }
- }
-
- if (field)
- {
- field->setAccess (ConvertAccessTypeToAccessSpecifier (access));
-
- record_decl->addDecl(field);
-
-#ifdef LLDB_CONFIGURATION_DEBUG
- VerifyDecl(field);
-#endif
- }
- }
- else
- {
- const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(clang_type);
- if (objc_class_type)
- {
- bool is_synthesized = false;
- field = ClangASTContext::AddObjCClassIVar (ast,
- record_clang_type,
- name,
- field_type,
- access,
- bitfield_bit_size,
- is_synthesized);
- }
- }
- }
- return field;
-}
-
-clang::VarDecl *
-ClangASTContext::AddVariableToRecordType (clang::ASTContext *ast,
- lldb::clang_type_t record_opaque_type,
- const char *name,
- lldb::clang_type_t var_type,
- AccessType access)
-{
- clang::VarDecl *var_decl = NULL;
-
- if (record_opaque_type == NULL || var_type == NULL)
- return NULL;
-
- IdentifierTable *identifier_table = &ast->Idents;
-
- assert (ast != NULL);
- assert (identifier_table != NULL);
-
- const RecordType *record_type = dyn_cast<RecordType>(QualType::getFromOpaquePtr(record_opaque_type).getTypePtr());
-
- if (record_type)
- {
- RecordDecl *record_decl = record_type->getDecl();
-
- var_decl = VarDecl::Create (*ast, // ASTContext &
- record_decl, // DeclContext *
- SourceLocation(), // SourceLocation StartLoc
- SourceLocation(), // SourceLocation IdLoc
- name ? &identifier_table->get(name) : NULL, // IdentifierInfo *
- QualType::getFromOpaquePtr(var_type), // Variable QualType
- NULL, // TypeSourceInfo *
- SC_Static); // StorageClass
- if (var_decl)
- {
- var_decl->setAccess(ConvertAccessTypeToAccessSpecifier (access));
- record_decl->addDecl(var_decl);
-
-#ifdef LLDB_CONFIGURATION_DEBUG
- VerifyDecl(var_decl);
-#endif
- }
- }
- return var_decl;
-}
-
-
-static clang::AccessSpecifier 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;
-}
-
-void
-ClangASTContext::BuildIndirectFields (clang::ASTContext *ast,
- lldb::clang_type_t record_clang_type)
-{
- QualType record_qual_type(QualType::getFromOpaquePtr(record_clang_type));
-
- const RecordType *record_type = record_qual_type->getAs<RecordType>();
-
- if (!record_type)
- return;
-
- RecordDecl *record_decl = record_type->getDecl();
-
- if (!record_decl)
- return;
-
- typedef llvm::SmallVector <IndirectFieldDecl *, 1> IndirectFieldVector;
-
- IndirectFieldVector indirect_fields;
- RecordDecl::field_iterator field_pos;
- RecordDecl::field_iterator field_end_pos = record_decl->field_end();
- RecordDecl::field_iterator last_field_pos = field_end_pos;
- for (field_pos = record_decl->field_begin(); field_pos != field_end_pos; last_field_pos = field_pos++)
- {
- if (field_pos->isAnonymousStructOrUnion())
- {
- QualType field_qual_type = field_pos->getType();
-
- const RecordType *field_record_type = field_qual_type->getAs<RecordType>();
-
- if (!field_record_type)
- continue;
-
- RecordDecl *field_record_decl = field_record_type->getDecl();
-
- if (!field_record_decl)
- continue;
-
- for (RecordDecl::decl_iterator di = field_record_decl->decls_begin(), de = field_record_decl->decls_end();
- di != de;
- ++di)
- {
- if (FieldDecl *nested_field_decl = dyn_cast<FieldDecl>(*di))
- {
- NamedDecl **chain = new (*ast) NamedDecl*[2];
- chain[0] = *field_pos;
- chain[1] = nested_field_decl;
- IndirectFieldDecl *indirect_field = IndirectFieldDecl::Create(*ast,
- record_decl,
- SourceLocation(),
- nested_field_decl->getIdentifier(),
- nested_field_decl->getType(),
- chain,
- 2);
-
- indirect_field->setAccess(UnifyAccessSpecifiers(field_pos->getAccess(),
- nested_field_decl->getAccess()));
-
- indirect_fields.push_back(indirect_field);
- }
- else if (IndirectFieldDecl *nested_indirect_field_decl = dyn_cast<IndirectFieldDecl>(*di))
- {
- int nested_chain_size = nested_indirect_field_decl->getChainingSize();
- NamedDecl **chain = new (*ast) NamedDecl*[nested_chain_size + 1];
- chain[0] = *field_pos;
-
- int chain_index = 1;
- for (IndirectFieldDecl::chain_iterator nci = nested_indirect_field_decl->chain_begin(),
- nce = nested_indirect_field_decl->chain_end();
- nci < nce;
- ++nci)
- {
- chain[chain_index] = *nci;
- chain_index++;
- }
-
- IndirectFieldDecl *indirect_field = IndirectFieldDecl::Create(*ast,
- record_decl,
- SourceLocation(),
- nested_indirect_field_decl->getIdentifier(),
- nested_indirect_field_decl->getType(),
- chain,
- nested_chain_size + 1);
-
- indirect_field->setAccess(UnifyAccessSpecifiers(field_pos->getAccess(),
- nested_indirect_field_decl->getAccess()));
-
- indirect_fields.push_back(indirect_field);
- }
- }
- }
- }
-
- // Check the last field to see if it has an incomplete array type as its
- // last member and if it does, the tell the record decl about it
- if (last_field_pos != field_end_pos)
- {
- if (last_field_pos->getType()->isIncompleteArrayType())
- record_decl->hasFlexibleArrayMember();
- }
-
- for (IndirectFieldVector::iterator ifi = indirect_fields.begin(), ife = indirect_fields.end();
- ifi < ife;
- ++ifi)
- {
- record_decl->addDecl(*ifi);
- }
-}
-
-bool
-ClangASTContext::FieldIsBitfield (FieldDecl* field, uint32_t& bitfield_bit_size)
-{
- return FieldIsBitfield(getASTContext(), field, bitfield_bit_size);
-}
+bool
+ClangASTContext::FieldIsBitfield (FieldDecl* field, uint32_t& bitfield_bit_size)
+{
+ return FieldIsBitfield(getASTContext(), field, bitfield_bit_size);
+}
bool
ClangASTContext::FieldIsBitfield
@@ -2270,76 +1725,9 @@ ClangASTContext::RecordHasFields (const
return false;
}
-void
-ClangASTContext::SetDefaultAccessForRecordFields (clang_type_t clang_type, int default_accessibility, int *assigned_accessibilities, size_t num_assigned_accessibilities)
-{
- if (clang_type)
- {
- QualType qual_type(QualType::getFromOpaquePtr(clang_type));
-
- const RecordType *record_type = dyn_cast<RecordType>(qual_type.getTypePtr());
- if (record_type)
- {
- RecordDecl *record_decl = record_type->getDecl();
- if (record_decl)
- {
- uint32_t field_idx;
- RecordDecl::field_iterator field, field_end;
- for (field = record_decl->field_begin(), field_end = record_decl->field_end(), field_idx = 0;
- field != field_end;
- ++field, ++field_idx)
- {
- // If no accessibility was assigned, assign the correct one
- if (field_idx < num_assigned_accessibilities && assigned_accessibilities[field_idx] == clang::AS_none)
- field->setAccess ((AccessSpecifier)default_accessibility);
- }
- }
- }
- }
-}
-
-#pragma mark C++ Base Classes
-
-CXXBaseSpecifier *
-ClangASTContext::CreateBaseClassSpecifier (clang_type_t base_class_type, AccessType access, bool is_virtual, bool base_of_class)
-{
- if (base_class_type)
- return new CXXBaseSpecifier (SourceRange(),
- is_virtual,
- base_of_class,
- ConvertAccessTypeToAccessSpecifier (access),
- getASTContext()->getTrivialTypeSourceInfo (QualType::getFromOpaquePtr(base_class_type)),
- SourceLocation());
- return NULL;
-}
-
-void
-ClangASTContext::DeleteBaseClassSpecifiers (CXXBaseSpecifier **base_classes, unsigned num_base_classes)
-{
- for (unsigned i=0; i<num_base_classes; ++i)
- {
- delete base_classes[i];
- base_classes[i] = NULL;
- }
-}
-
-bool
-ClangASTContext::SetBaseClassesForClassType (clang_type_t class_clang_type, CXXBaseSpecifier const * const *base_classes, unsigned num_base_classes)
-{
- if (class_clang_type)
- {
- CXXRecordDecl *cxx_record_decl = QualType::getFromOpaquePtr(class_clang_type)->getAsCXXRecordDecl();
- if (cxx_record_decl)
- {
- cxx_record_decl->setBases(base_classes, num_base_classes);
- return true;
- }
- }
- return false;
-}
#pragma mark Objective C Classes
-clang_type_t
+ClangASTType
ClangASTContext::CreateObjCClass
(
const char *name,
@@ -2355,11 +1743,6 @@ ClangASTContext::CreateObjCClass
if (decl_ctx == NULL)
decl_ctx = ast->getTranslationUnitDecl();
- // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and
- // we will need to update this code. I was told to currently always use
- // the CXXRecordDecl class since we often don't know from debug information
- // if something is struct or a class, so we default to always use the more
- // complete definition just in case.
ObjCInterfaceDecl *decl = ObjCInterfaceDecl::Create (*ast,
decl_ctx,
SourceLocation(),
@@ -2372,4317 +1755,333 @@ ClangASTContext::CreateObjCClass
if (decl && metadata)
SetMetadata(ast, decl, *metadata);
- return ast->getObjCInterfaceType(decl).getAsOpaquePtr();
+ return ClangASTType (ast, ast->getObjCInterfaceType(decl));
}
-bool
-ClangASTContext::SetObjCSuperClass (clang_type_t class_opaque_type, clang_type_t super_opaque_type)
+static inline bool
+BaseSpecifierIsEmpty (const CXXBaseSpecifier *b)
{
- if (class_opaque_type && super_opaque_type)
- {
- QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
- QualType super_qual_type(QualType::getFromOpaquePtr(super_opaque_type));
- const clang::Type *class_type = class_qual_type.getTypePtr();
- const clang::Type *super_type = super_qual_type.getTypePtr();
- if (class_type && super_type)
- {
- const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
- const ObjCObjectType *objc_super_type = dyn_cast<ObjCObjectType>(super_type);
- if (objc_class_type && objc_super_type)
- {
- ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
- ObjCInterfaceDecl *super_interface_decl = objc_super_type->getInterface();
- if (class_interface_decl && super_interface_decl)
- {
- class_interface_decl->setSuperClass(super_interface_decl);
- return true;
- }
- }
- }
- }
- return false;
+ return ClangASTContext::RecordHasFields(b->getType()->getAsCXXRecordDecl()) == false;
}
-
-FieldDecl *
-ClangASTContext::AddObjCClassIVar
-(
- ASTContext *ast,
- clang_type_t class_opaque_type,
- const char *name,
- clang_type_t ivar_opaque_type,
- AccessType access,
- uint32_t bitfield_bit_size,
- bool is_synthesized
-)
+uint32_t
+ClangASTContext::GetNumBaseClasses (const CXXRecordDecl *cxx_record_decl, bool omit_empty_base_classes)
{
- if (class_opaque_type == NULL || ivar_opaque_type == NULL)
- return NULL;
-
- ObjCIvarDecl *field = NULL;
-
- IdentifierTable *identifier_table = &ast->Idents;
-
- assert (ast != NULL);
- assert (identifier_table != NULL);
-
- QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
-
- const clang::Type *class_type = class_qual_type.getTypePtr();
- if (class_type)
+ uint32_t num_bases = 0;
+ if (cxx_record_decl)
{
- const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
-
- if (objc_class_type)
+ if (omit_empty_base_classes)
{
- ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
-
- if (class_interface_decl)
+ CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
+ for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
+ base_class != base_class_end;
+ ++base_class)
{
- clang::Expr *bit_width = NULL;
- if (bitfield_bit_size != 0)
- {
- APInt bitfield_bit_size_apint(ast->getTypeSize(ast->IntTy), bitfield_bit_size);
- bit_width = new (*ast)IntegerLiteral (*ast, bitfield_bit_size_apint, ast->IntTy, SourceLocation());
- }
-
- field = ObjCIvarDecl::Create (*ast,
- class_interface_decl,
- SourceLocation(),
- SourceLocation(),
- name ? &identifier_table->get(name) : NULL, // Identifier
- QualType::getFromOpaquePtr(ivar_opaque_type), // Field type
- NULL, // TypeSourceInfo *
- ConvertAccessTypeToObjCIvarAccessControl (access),
- bit_width,
- is_synthesized);
-
- if (field)
+ // Skip empty base classes
+ if (omit_empty_base_classes)
{
- class_interface_decl->addDecl(field);
-
-#ifdef LLDB_CONFIGURATION_DEBUG
- VerifyDecl(field);
-#endif
-
- return field;
+ if (BaseSpecifierIsEmpty (base_class))
+ continue;
}
+ ++num_bases;
}
}
+ else
+ num_bases = cxx_record_decl->getNumBases();
}
- return NULL;
+ return num_bases;
}
-bool
-ClangASTContext::AddObjCClassProperty
-(
- ASTContext *ast,
- clang_type_t class_opaque_type,
- const char *property_name,
- clang_type_t property_opaque_type,
- ObjCIvarDecl *ivar_decl,
- const char *property_setter_name,
- const char *property_getter_name,
- uint32_t property_attributes,
- ClangASTMetadata *metadata
-)
-{
- if (class_opaque_type == NULL || property_name == NULL || property_name[0] == '\0')
- return false;
-
- IdentifierTable *identifier_table = &ast->Idents;
- assert (ast != NULL);
- assert (identifier_table != NULL);
+#pragma mark Namespace Declarations
- QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
- const clang::Type *class_type = class_qual_type.getTypePtr();
- if (class_type)
- {
- const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
-
- if (objc_class_type)
- {
- ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
-
- clang_type_t property_opaque_type_to_access = NULL;
-
- if (property_opaque_type)
- property_opaque_type_to_access = property_opaque_type;
- else if (ivar_decl)
- property_opaque_type_to_access = ivar_decl->getType().getAsOpaquePtr();
-
- if (class_interface_decl && property_opaque_type_to_access)
- {
- clang::TypeSourceInfo *prop_type_source;
- if (ivar_decl)
- prop_type_source = ast->getTrivialTypeSourceInfo (ivar_decl->getType());
- else
- prop_type_source = ast->getTrivialTypeSourceInfo (QualType::getFromOpaquePtr(property_opaque_type));
-
- ObjCPropertyDecl *property_decl = ObjCPropertyDecl::Create(*ast,
- class_interface_decl,
- SourceLocation(), // Source Location
- &identifier_table->get(property_name),
- SourceLocation(), //Source Location for AT
- SourceLocation(), //Source location for (
- prop_type_source
- );
-
- if (property_decl)
- {
- if (metadata)
- SetMetadata(ast, property_decl, *metadata);
-
- class_interface_decl->addDecl (property_decl);
-
- Selector setter_sel, getter_sel;
-
- if (property_setter_name != NULL)
- {
- std::string property_setter_no_colon(property_setter_name, strlen(property_setter_name) - 1);
- clang::IdentifierInfo *setter_ident = &identifier_table->get(property_setter_no_colon.c_str());
- setter_sel = ast->Selectors.getSelector(1, &setter_ident);
- }
- else if (!(property_attributes & DW_APPLE_PROPERTY_readonly))
- {
- std::string setter_sel_string("set");
- setter_sel_string.push_back(::toupper(property_name[0]));
- setter_sel_string.append(&property_name[1]);
- clang::IdentifierInfo *setter_ident = &identifier_table->get(setter_sel_string.c_str());
- setter_sel = ast->Selectors.getSelector(1, &setter_ident);
- }
- property_decl->setSetterName(setter_sel);
- property_decl->setPropertyAttributes (clang::ObjCPropertyDecl::OBJC_PR_setter);
-
- if (property_getter_name != NULL)
- {
- clang::IdentifierInfo *getter_ident = &identifier_table->get(property_getter_name);
- getter_sel = ast->Selectors.getSelector(0, &getter_ident);
- }
- else
- {
- clang::IdentifierInfo *getter_ident = &identifier_table->get(property_name);
- getter_sel = ast->Selectors.getSelector(0, &getter_ident);
- }
- property_decl->setGetterName(getter_sel);
- property_decl->setPropertyAttributes (clang::ObjCPropertyDecl::OBJC_PR_getter);
-
- if (ivar_decl)
- property_decl->setPropertyIvarDecl (ivar_decl);
-
- if (property_attributes & DW_APPLE_PROPERTY_readonly)
- property_decl->setPropertyAttributes (clang::ObjCPropertyDecl::OBJC_PR_readonly);
- if (property_attributes & DW_APPLE_PROPERTY_readwrite)
- property_decl->setPropertyAttributes (clang::ObjCPropertyDecl::OBJC_PR_readwrite);
- if (property_attributes & DW_APPLE_PROPERTY_assign)
- property_decl->setPropertyAttributes (clang::ObjCPropertyDecl::OBJC_PR_assign);
- if (property_attributes & DW_APPLE_PROPERTY_retain)
- property_decl->setPropertyAttributes (clang::ObjCPropertyDecl::OBJC_PR_retain);
- if (property_attributes & DW_APPLE_PROPERTY_copy)
- 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))
- {
- QualType result_type = QualType::getFromOpaquePtr(property_opaque_type_to_access);
-
- const bool isInstance = true;
- const bool isVariadic = false;
- const bool isSynthesized = false;
- const bool isImplicitlyDeclared = true;
- const bool isDefined = false;
- const ObjCMethodDecl::ImplementationControl impControl = ObjCMethodDecl::None;
- const bool HasRelatedResultType = false;
-
- ObjCMethodDecl *getter = ObjCMethodDecl::Create(*ast,
- SourceLocation(),
- SourceLocation(),
- getter_sel,
- result_type,
- NULL,
- class_interface_decl,
- isInstance,
- isVariadic,
- isSynthesized,
- isImplicitlyDeclared,
- isDefined,
- impControl,
- HasRelatedResultType);
-
- if (getter && metadata)
- SetMetadata(ast, getter, *metadata);
-
- getter->setMethodParams(*ast, ArrayRef<ParmVarDecl*>(), ArrayRef<SourceLocation>());
-
- class_interface_decl->addDecl(getter);
- }
-
- if (!setter_sel.isNull() && !class_interface_decl->lookupInstanceMethod(setter_sel))
- {
- QualType result_type = ast->VoidTy;
-
- const bool isInstance = true;
- const bool isVariadic = false;
- const bool isSynthesized = false;
- const bool isImplicitlyDeclared = true;
- const bool isDefined = false;
- const ObjCMethodDecl::ImplementationControl impControl = ObjCMethodDecl::None;
- const bool HasRelatedResultType = false;
-
- ObjCMethodDecl *setter = ObjCMethodDecl::Create(*ast,
- SourceLocation(),
- SourceLocation(),
- setter_sel,
- result_type,
- NULL,
- class_interface_decl,
- isInstance,
- isVariadic,
- isSynthesized,
- isImplicitlyDeclared,
- isDefined,
- impControl,
- HasRelatedResultType);
-
- if (setter && metadata)
- SetMetadata(ast, setter, *metadata);
-
- llvm::SmallVector<ParmVarDecl *, 1> params;
-
- params.push_back (ParmVarDecl::Create (*ast,
- setter,
- SourceLocation(),
- SourceLocation(),
- NULL, // anonymous
- QualType::getFromOpaquePtr(property_opaque_type_to_access),
- NULL,
- SC_Auto,
- NULL));
-
- setter->setMethodParams(*ast, ArrayRef<ParmVarDecl*>(params), ArrayRef<SourceLocation>());
-
- class_interface_decl->addDecl(setter);
- }
-
- return true;
- }
- }
- }
- }
- return false;
-}
-
-bool
-ClangASTContext::ObjCTypeHasIVars (clang_type_t class_opaque_type, bool check_superclass)
-{
- QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
-
- const clang::Type *class_type = class_qual_type.getTypePtr();
- if (class_type)
- {
- const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
-
- if (objc_class_type)
- return ObjCDeclHasIVars (objc_class_type->getInterface(), check_superclass);
- }
- return false;
-}
-
-bool
-ClangASTContext::ObjCDeclHasIVars (ObjCInterfaceDecl *class_interface_decl, bool check_superclass)
-{
- while (class_interface_decl)
- {
- if (class_interface_decl->ivar_size() > 0)
- return true;
-
- if (check_superclass)
- class_interface_decl = class_interface_decl->getSuperClass();
- else
- break;
- }
- return false;
-}
-
-ObjCMethodDecl *
-ClangASTContext::AddMethodToObjCObjectType (ASTContext *ast,
- clang_type_t class_opaque_type,
- const char *name, // the full symbol name as seen in the symbol table ("-[NString stringWithCString:]")
- clang_type_t method_opaque_type,
- lldb::AccessType access,
- bool is_artificial)
+NamespaceDecl *
+ClangASTContext::GetUniqueNamespaceDeclaration (const char *name, DeclContext *decl_ctx)
{
- if (class_opaque_type == NULL || method_opaque_type == NULL)
- return NULL;
-
- IdentifierTable *identifier_table = &ast->Idents;
-
- assert (ast != NULL);
- assert (identifier_table != NULL);
-
- QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
-
- const clang::Type *class_type = class_qual_type.getTypePtr();
- if (class_type == NULL)
- return NULL;
-
- const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
-
- if (objc_class_type == NULL)
- return NULL;
-
- ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
-
- if (class_interface_decl == NULL)
- return NULL;
-
- const char *selector_start = ::strchr (name, ' ');
- if (selector_start == NULL)
- return NULL;
-
- selector_start++;
- llvm::SmallVector<IdentifierInfo *, 12> selector_idents;
-
- size_t len = 0;
- const char *start;
- //printf ("name = '%s'\n", name);
-
- unsigned num_selectors_with_args = 0;
- for (start = selector_start;
- start && *start != '\0' && *start != ']';
- start += len)
- {
- len = ::strcspn(start, ":]");
- bool has_arg = (start[len] == ':');
- if (has_arg)
- ++num_selectors_with_args;
- selector_idents.push_back (&identifier_table->get (StringRef (start, len)));
- if (has_arg)
- len += 1;
- }
-
-
- if (selector_idents.size() == 0)
- return 0;
-
- clang::Selector method_selector = ast->Selectors.getSelector (num_selectors_with_args ? selector_idents.size() : 0,
- selector_idents.data());
-
- QualType method_qual_type (QualType::getFromOpaquePtr (method_opaque_type));
-
- // Populate the method decl with parameter decls
- const clang::Type *method_type(method_qual_type.getTypePtr());
-
- if (method_type == NULL)
- return NULL;
-
- const FunctionProtoType *method_function_prototype (dyn_cast<FunctionProtoType>(method_type));
-
- if (!method_function_prototype)
- return NULL;
-
-
- bool is_variadic = false;
- bool is_synthesized = false;
- bool is_defined = false;
- ObjCMethodDecl::ImplementationControl imp_control = ObjCMethodDecl::None;
-
- const unsigned num_args = method_function_prototype->getNumArgs();
-
- if (num_args != num_selectors_with_args)
- return NULL; // some debug information is corrupt. We are not going to deal with it.
-
- ObjCMethodDecl *objc_method_decl = ObjCMethodDecl::Create (*ast,
- SourceLocation(), // beginLoc,
- SourceLocation(), // endLoc,
- method_selector,
- method_function_prototype->getResultType(),
- NULL, // TypeSourceInfo *ResultTInfo,
- GetDeclContextForType (class_opaque_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 == NULL)
- return NULL;
-
- if (num_args > 0)
- {
- llvm::SmallVector<ParmVarDecl *, 12> params;
-
- for (unsigned param_index = 0; param_index < num_args; ++param_index)
- {
- params.push_back (ParmVarDecl::Create (*ast,
- objc_method_decl,
- SourceLocation(),
- SourceLocation(),
- NULL, // anonymous
- method_function_prototype->getArgType(param_index),
- NULL,
- SC_Auto,
- NULL));
- }
-
- objc_method_decl->setMethodParams(*ast, ArrayRef<ParmVarDecl*>(params), ArrayRef<SourceLocation>());
- }
+ NamespaceDecl *namespace_decl = NULL;
+ ASTContext *ast = getASTContext();
+ TranslationUnitDecl *translation_unit_decl = ast->getTranslationUnitDecl ();
+ if (decl_ctx == NULL)
+ decl_ctx = translation_unit_decl;
- class_interface_decl->addDecl (objc_method_decl);
-
-#ifdef LLDB_CONFIGURATION_DEBUG
- VerifyDecl(objc_method_decl);
-#endif
-
- return objc_method_decl;
-}
-
-size_t
-ClangASTContext::GetNumTemplateArguments (clang::ASTContext *ast, clang_type_t clang_type)
-{
- if (clang_type)
+ if (name)
{
- QualType qual_type (QualType::getFromOpaquePtr(clang_type));
-
- const clang::Type::TypeClass type_class = qual_type->getTypeClass();
- switch (type_class)
+ IdentifierInfo &identifier_info = ast->Idents.get(name);
+ DeclarationName decl_name (&identifier_info);
+ clang::DeclContext::lookup_result result = decl_ctx->lookup(decl_name);
+ for (NamedDecl *decl : result)
{
- case clang::Type::Record:
- if (GetCompleteQualType (ast, qual_type))
- {
- const CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
- if (cxx_record_decl)
- {
- const ClassTemplateSpecializationDecl *template_decl = dyn_cast<ClassTemplateSpecializationDecl>(cxx_record_decl);
- if (template_decl)
- return template_decl->getTemplateArgs().size();
- }
- }
- break;
-
- case clang::Type::Typedef:
- return ClangASTContext::GetNumTemplateArguments (ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
-
- case clang::Type::Elaborated:
- return ClangASTContext::GetNumTemplateArguments (ast, cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
-
- case clang::Type::Paren:
- return ClangASTContext::GetNumTemplateArguments(ast, cast<ParenType>(qual_type)->desugar().getAsOpaquePtr());
-
- default:
- break;
+ namespace_decl = dyn_cast<clang::NamespaceDecl>(decl);
+ if (namespace_decl)
+ return namespace_decl;
}
- }
- return 0;
-}
-clang_type_t
-ClangASTContext::GetTemplateArgument (clang::ASTContext *ast, clang_type_t clang_type, size_t arg_idx, lldb::TemplateArgumentKind &kind)
-{
- if (clang_type)
- {
- QualType qual_type (QualType::getFromOpaquePtr(clang_type));
+ namespace_decl = NamespaceDecl::Create(*ast,
+ decl_ctx,
+ false,
+ SourceLocation(),
+ SourceLocation(),
+ &identifier_info,
+ NULL);
- const clang::Type::TypeClass type_class = qual_type->getTypeClass();
- switch (type_class)
- {
- case clang::Type::Record:
- if (GetCompleteQualType (ast, qual_type))
- {
- const CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
- if (cxx_record_decl)
- {
- const ClassTemplateSpecializationDecl *template_decl = dyn_cast<ClassTemplateSpecializationDecl>(cxx_record_decl);
- if (template_decl && arg_idx < template_decl->getTemplateArgs().size())
- {
- const TemplateArgument &template_arg = template_decl->getTemplateArgs()[arg_idx];
- switch (template_arg.getKind())
- {
- case clang::TemplateArgument::Null:
- kind = eTemplateArgumentKindNull;
- return NULL;
-
- case clang::TemplateArgument::Type:
- kind = eTemplateArgumentKindType;
- return template_arg.getAsType().getAsOpaquePtr();
-
- case clang::TemplateArgument::Declaration:
- kind = eTemplateArgumentKindDeclaration;
- return NULL;
-
- case clang::TemplateArgument::Integral:
- kind = eTemplateArgumentKindIntegral;
- return template_arg.getIntegralType().getAsOpaquePtr();
-
- case clang::TemplateArgument::Template:
- kind = eTemplateArgumentKindTemplate;
- return NULL;
-
- case clang::TemplateArgument::TemplateExpansion:
- kind = eTemplateArgumentKindTemplateExpansion;
- return NULL;
-
- case clang::TemplateArgument::Expression:
- kind = eTemplateArgumentKindExpression;
- return NULL;
-
- case clang::TemplateArgument::Pack:
- kind = eTemplateArgumentKindPack;
- return NULL;
-
- default:
- assert (!"Unhandled TemplateArgument::ArgKind");
- kind = eTemplateArgumentKindNull;
- return NULL;
- }
- }
- }
- }
- break;
-
- case clang::Type::Typedef:
- return ClangASTContext::GetTemplateArgument (ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), arg_idx, kind);
-
- case clang::Type::Elaborated:
- return ClangASTContext::GetTemplateArgument (ast, cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), arg_idx, kind);
-
- case clang::Type::Paren:
- return ClangASTContext::GetTemplateArgument(ast, cast<ParenType>(qual_type)->desugar().getAsOpaquePtr(), arg_idx, kind);
-
- default:
- break;
- }
+ decl_ctx->addDecl (namespace_decl);
}
- kind = eTemplateArgumentKindNull;
- return NULL;
-}
-
-uint32_t
-ClangASTContext::GetTypeInfo
-(
- clang_type_t clang_type,
- clang::ASTContext *ast,
- clang_type_t *pointee_or_element_clang_type
-)
-{
- if (clang_type == NULL)
- return 0;
-
- if (pointee_or_element_clang_type)
- *pointee_or_element_clang_type = NULL;
-
- QualType qual_type (QualType::getFromOpaquePtr(clang_type));
-
- const clang::Type::TypeClass type_class = qual_type->getTypeClass();
- switch (type_class)
+ else
{
- case clang::Type::Builtin:
- {
- const BuiltinType *builtin_type = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal());
-
- uint32_t builtin_type_flags = eTypeIsBuiltIn | eTypeHasValue;
- switch (builtin_type->getKind())
- {
- case clang::BuiltinType::ObjCId:
- case clang::BuiltinType::ObjCClass:
- if (ast && pointee_or_element_clang_type)
- *pointee_or_element_clang_type = ast->ObjCBuiltinClassTy.getAsOpaquePtr();
- builtin_type_flags |= eTypeIsPointer | eTypeIsObjC;
- break;
-
- case clang::BuiltinType::ObjCSel:
- if (ast && pointee_or_element_clang_type)
- *pointee_or_element_clang_type = ast->CharTy.getAsOpaquePtr();
- builtin_type_flags |= eTypeIsPointer | eTypeIsObjC;
- break;
-
- case clang::BuiltinType::Bool:
- case clang::BuiltinType::Char_U:
- case clang::BuiltinType::UChar:
- case clang::BuiltinType::WChar_U:
- case clang::BuiltinType::Char16:
- case clang::BuiltinType::Char32:
- case clang::BuiltinType::UShort:
- case clang::BuiltinType::UInt:
- case clang::BuiltinType::ULong:
- case clang::BuiltinType::ULongLong:
- case clang::BuiltinType::UInt128:
- case clang::BuiltinType::Char_S:
- case clang::BuiltinType::SChar:
- case clang::BuiltinType::WChar_S:
- case clang::BuiltinType::Short:
- case clang::BuiltinType::Int:
- case clang::BuiltinType::Long:
- case clang::BuiltinType::LongLong:
- case clang::BuiltinType::Int128:
- case clang::BuiltinType::Float:
- case clang::BuiltinType::Double:
- case clang::BuiltinType::LongDouble:
- builtin_type_flags |= eTypeIsScalar;
- if (builtin_type->isInteger())
- {
- builtin_type_flags |= eTypeIsInteger;
- if (builtin_type->isSignedInteger())
- builtin_type_flags |= eTypeIsSigned;
- }
- else if (builtin_type->isFloatingPoint())
- builtin_type_flags |= eTypeIsFloat;
- break;
- default:
- break;
- }
- return builtin_type_flags;
- }
-
- case clang::Type::BlockPointer:
- if (pointee_or_element_clang_type)
- *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr();
- return eTypeIsPointer | eTypeHasChildren | eTypeIsBlock;
-
- case clang::Type::Complex:
+ if (decl_ctx == translation_unit_decl)
{
- uint32_t complex_type_flags = eTypeIsBuiltIn | eTypeHasValue | eTypeIsComplex;
- const ComplexType *complex_type = dyn_cast<ComplexType>(qual_type->getCanonicalTypeInternal());
- if (complex_type)
- {
- QualType complex_element_type (complex_type->getElementType());
- if (complex_element_type->isIntegerType())
- complex_type_flags |= eTypeIsFloat;
- else if (complex_element_type->isFloatingType())
- complex_type_flags |= eTypeIsInteger;
- }
- return complex_type_flags;
+ namespace_decl = translation_unit_decl->getAnonymousNamespace();
+ if (namespace_decl)
+ return namespace_decl;
+
+ namespace_decl = NamespaceDecl::Create(*ast,
+ decl_ctx,
+ false,
+ SourceLocation(),
+ SourceLocation(),
+ NULL,
+ NULL);
+ translation_unit_decl->setAnonymousNamespace (namespace_decl);
+ translation_unit_decl->addDecl (namespace_decl);
+ assert (namespace_decl == translation_unit_decl->getAnonymousNamespace());
}
- break;
-
- case clang::Type::ConstantArray:
- case clang::Type::DependentSizedArray:
- case clang::Type::IncompleteArray:
- case clang::Type::VariableArray:
- if (pointee_or_element_clang_type)
- *pointee_or_element_clang_type = cast<ArrayType>(qual_type.getTypePtr())->getElementType().getAsOpaquePtr();
- return eTypeHasChildren | eTypeIsArray;
-
- case clang::Type::DependentName: return 0;
- case clang::Type::DependentSizedExtVector: return eTypeHasChildren | eTypeIsVector;
- case clang::Type::DependentTemplateSpecialization: return eTypeIsTemplate;
- case clang::Type::Decltype: return 0;
-
- case clang::Type::Enum:
- if (pointee_or_element_clang_type)
- *pointee_or_element_clang_type = cast<EnumType>(qual_type)->getDecl()->getIntegerType().getAsOpaquePtr();
- return eTypeIsEnumeration | eTypeHasValue;
-
- case clang::Type::Elaborated:
- return ClangASTContext::GetTypeInfo (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(),
- ast,
- pointee_or_element_clang_type);
-
- case clang::Type::Paren:
- return ClangASTContext::GetTypeInfo(llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
- ast,
- pointee_or_element_clang_type);
-
- case clang::Type::FunctionProto: return eTypeIsFuncPrototype | eTypeHasValue;
- case clang::Type::FunctionNoProto: return eTypeIsFuncPrototype | eTypeHasValue;
- case clang::Type::InjectedClassName: return 0;
-
- case clang::Type::LValueReference:
- case clang::Type::RValueReference:
- if (pointee_or_element_clang_type)
- *pointee_or_element_clang_type = cast<ReferenceType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr();
- return eTypeHasChildren | eTypeIsReference | eTypeHasValue;
-
- case clang::Type::MemberPointer: return eTypeIsPointer | eTypeIsMember | eTypeHasValue;
-
- case clang::Type::ObjCObjectPointer:
- if (pointee_or_element_clang_type)
- *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr();
- return eTypeHasChildren | eTypeIsObjC | eTypeIsClass | eTypeIsPointer | eTypeHasValue;
-
- case clang::Type::ObjCObject: return eTypeHasChildren | eTypeIsObjC | eTypeIsClass;
- case clang::Type::ObjCInterface: return eTypeHasChildren | eTypeIsObjC | eTypeIsClass;
-
- case clang::Type::Pointer:
- if (pointee_or_element_clang_type)
- *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr();
- return eTypeHasChildren | eTypeIsPointer | eTypeHasValue;
-
- case clang::Type::Record:
- if (qual_type->getAsCXXRecordDecl())
- return eTypeHasChildren | eTypeIsClass | eTypeIsCPlusPlus;
else
- return eTypeHasChildren | eTypeIsStructUnion;
- break;
- case clang::Type::SubstTemplateTypeParm: return eTypeIsTemplate;
- case clang::Type::TemplateTypeParm: return eTypeIsTemplate;
- case clang::Type::TemplateSpecialization: return eTypeIsTemplate;
-
- case clang::Type::Typedef:
- return eTypeIsTypedef | ClangASTContext::GetTypeInfo (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
- ast,
- pointee_or_element_clang_type);
-
- case clang::Type::TypeOfExpr: return 0;
- case clang::Type::TypeOf: return 0;
- case clang::Type::UnresolvedUsing: return 0;
-
- case clang::Type::ExtVector:
- case clang::Type::Vector:
{
- uint32_t vector_type_flags = eTypeHasChildren | eTypeIsVector;
- const VectorType *vector_type = dyn_cast<VectorType>(qual_type->getCanonicalTypeInternal());
- if (vector_type)
+ NamespaceDecl *parent_namespace_decl = cast<NamespaceDecl>(decl_ctx);
+ if (parent_namespace_decl)
{
- if (vector_type->isIntegerType())
- vector_type_flags |= eTypeIsFloat;
- else if (vector_type->isFloatingType())
- vector_type_flags |= eTypeIsInteger;
+ namespace_decl = parent_namespace_decl->getAnonymousNamespace();
+ if (namespace_decl)
+ return namespace_decl;
+ namespace_decl = NamespaceDecl::Create(*ast,
+ decl_ctx,
+ false,
+ SourceLocation(),
+ SourceLocation(),
+ NULL,
+ NULL);
+ parent_namespace_decl->setAnonymousNamespace (namespace_decl);
+ parent_namespace_decl->addDecl (namespace_decl);
+ assert (namespace_decl == parent_namespace_decl->getAnonymousNamespace());
}
- return vector_type_flags;
- }
- default: return 0;
- }
- return 0;
-}
-
-
-#pragma mark Aggregate Types
-
-bool
-ClangASTContext::IsAggregateType (clang_type_t clang_type)
-{
- if (clang_type == NULL)
- return false;
-
- QualType qual_type (QualType::getFromOpaquePtr(clang_type));
-
- const clang::Type::TypeClass type_class = qual_type->getTypeClass();
- switch (type_class)
- {
- case clang::Type::IncompleteArray:
- case clang::Type::VariableArray:
- case clang::Type::ConstantArray:
- case clang::Type::ExtVector:
- case clang::Type::Vector:
- case clang::Type::Record:
- case clang::Type::ObjCObject:
- case clang::Type::ObjCInterface:
- return true;
- case clang::Type::Elaborated:
- return ClangASTContext::IsAggregateType (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
- case clang::Type::Typedef:
- return ClangASTContext::IsAggregateType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
- case clang::Type::Paren:
- return ClangASTContext::IsAggregateType (cast<ParenType>(qual_type)->desugar().getAsOpaquePtr());
- default:
- break;
- }
- // The clang type does have a value
- return false;
-}
-
-uint32_t
-ClangASTContext::GetNumChildren (clang::ASTContext *ast, clang_type_t clang_type, bool omit_empty_base_classes)
-{
- if (clang_type == NULL)
- return 0;
-
- uint32_t num_children = 0;
- QualType qual_type(QualType::getFromOpaquePtr(clang_type));
- const clang::Type::TypeClass type_class = qual_type->getTypeClass();
- switch (type_class)
- {
- case clang::Type::Builtin:
- switch (cast<clang::BuiltinType>(qual_type)->getKind())
- {
- case clang::BuiltinType::ObjCId: // child is Class
- case clang::BuiltinType::ObjCClass: // child is Class
- num_children = 1;
- break;
-
- default:
- break;
- }
- break;
-
- case clang::Type::Complex: return 0;
-
- case clang::Type::Record:
- if (GetCompleteQualType (ast, qual_type))
- {
- const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
- const RecordDecl *record_decl = record_type->getDecl();
- assert(record_decl);
- const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
- if (cxx_record_decl)
+ else
{
- if (omit_empty_base_classes)
- {
- // Check each base classes to see if it or any of its
- // base classes contain any fields. This can help
- // limit the noise in variable views by not having to
- // show base classes that contain no members.
- CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
- for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
- base_class != base_class_end;
- ++base_class)
- {
- const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
-
- // Skip empty base classes
- if (RecordHasFields(base_class_decl) == false)
- continue;
-
- num_children++;
- }
- }
- else
- {
- // Include all base classes
- num_children += cxx_record_decl->getNumBases();
- }
-
+ // BAD!!!
}
- RecordDecl::field_iterator field, field_end;
- for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field)
- ++num_children;
}
- break;
+
- case clang::Type::ObjCObject:
- case clang::Type::ObjCInterface:
- if (GetCompleteQualType (ast, qual_type))
- {
- const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
- assert (objc_class_type);
- if (objc_class_type)
- {
- ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
-
- if (class_interface_decl)
- {
-
- ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
- if (superclass_interface_decl)
- {
- if (omit_empty_base_classes)
- {
- if (ClangASTContext::ObjCDeclHasIVars (superclass_interface_decl, true))
- ++num_children;
- }
- else
- ++num_children;
- }
-
- num_children += class_interface_decl->ivar_size();
- }
- }
- }
- break;
-
- case clang::Type::ObjCObjectPointer:
- {
- const ObjCObjectPointerType *pointer_type = cast<ObjCObjectPointerType>(qual_type.getTypePtr());
- QualType pointee_type = pointer_type->getPointeeType();
- uint32_t num_pointee_children = ClangASTContext::GetNumChildren (ast,
- pointee_type.getAsOpaquePtr(),
- omit_empty_base_classes);
- // If this type points to a simple type, then it has 1 child
- if (num_pointee_children == 0)
- num_children = 1;
- else
- num_children = num_pointee_children;
- }
- break;
-
- case clang::Type::Vector:
- case clang::Type::ExtVector:
- num_children = cast<VectorType>(qual_type.getTypePtr())->getNumElements();
- break;
-
- case clang::Type::ConstantArray:
- num_children = cast<ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue();
- break;
-
- case clang::Type::Pointer:
- {
- const PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
- QualType pointee_type (pointer_type->getPointeeType());
- uint32_t num_pointee_children = ClangASTContext::GetNumChildren (ast,
- pointee_type.getAsOpaquePtr(),
- omit_empty_base_classes);
- if (num_pointee_children == 0)
- {
- // We have a pointer to a pointee type that claims it has no children.
- // We will want to look at
- num_children = ClangASTContext::GetNumPointeeChildren (pointee_type.getAsOpaquePtr());
- }
- else
- num_children = num_pointee_children;
- }
- break;
-
- case clang::Type::LValueReference:
- case clang::Type::RValueReference:
- {
- const ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
- QualType pointee_type = reference_type->getPointeeType();
- uint32_t num_pointee_children = ClangASTContext::GetNumChildren (ast,
- pointee_type.getAsOpaquePtr(),
- omit_empty_base_classes);
- // If this type points to a simple type, then it has 1 child
- if (num_pointee_children == 0)
- num_children = 1;
- else
- num_children = num_pointee_children;
- }
- break;
-
-
- case clang::Type::Typedef:
- num_children = ClangASTContext::GetNumChildren (ast,
- cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
- omit_empty_base_classes);
- break;
-
- case clang::Type::Elaborated:
- num_children = ClangASTContext::GetNumChildren (ast,
- cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(),
- omit_empty_base_classes);
- break;
-
- case clang::Type::Paren:
- num_children = ClangASTContext::GetNumChildren(ast,
- llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
- omit_empty_base_classes);
-
- break;
- default:
- break;
- }
- return num_children;
-}
-
-uint32_t
-ClangASTContext::GetNumDirectBaseClasses (clang::ASTContext *ast, clang_type_t clang_type)
-{
- if (clang_type == NULL)
- return 0;
-
- uint32_t count = 0;
- QualType qual_type(QualType::getFromOpaquePtr(clang_type));
- const clang::Type::TypeClass type_class = qual_type->getTypeClass();
- switch (type_class)
- {
- case clang::Type::Record:
- if (GetCompleteQualType (ast, qual_type))
- {
- const CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
- if (cxx_record_decl)
- count = cxx_record_decl->getNumBases();
- }
- break;
-
- case clang::Type::ObjCObjectPointer:
- if (GetCompleteQualType (ast, qual_type))
- {
- const ObjCObjectPointerType *objc_class_type = qual_type->getAsObjCInterfacePointerType();
- if (objc_class_type)
- {
- ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterfaceDecl();
- if (class_interface_decl && class_interface_decl->getSuperClass())
- count = 1;
- }
- }
- break;
-
- case clang::Type::ObjCObject:
- case clang::Type::ObjCInterface:
- if (GetCompleteQualType (ast, qual_type))
- {
- const ObjCObjectType *objc_class_type = qual_type->getAsObjCQualifiedInterfaceType();
- if (objc_class_type)
- {
- ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
-
- if (class_interface_decl && class_interface_decl->getSuperClass())
- count = 1;
- }
- }
- break;
-
-
- case clang::Type::Typedef:
- count = ClangASTContext::GetNumDirectBaseClasses (ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
- break;
-
- case clang::Type::Elaborated:
- count = ClangASTContext::GetNumDirectBaseClasses (ast, cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
- break;
-
- case clang::Type::Paren:
- return ClangASTContext::GetNumDirectBaseClasses(ast, cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr());
-
- default:
- break;
- }
- return count;
-}
-
-uint32_t
-ClangASTContext::GetNumVirtualBaseClasses (clang::ASTContext *ast,
- clang_type_t clang_type)
-{
- if (clang_type == NULL)
- return 0;
-
- uint32_t count = 0;
- QualType qual_type(QualType::getFromOpaquePtr(clang_type));
- const clang::Type::TypeClass type_class = qual_type->getTypeClass();
- switch (type_class)
- {
- case clang::Type::Record:
- if (GetCompleteQualType (ast, qual_type))
- {
- const CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
- if (cxx_record_decl)
- count = cxx_record_decl->getNumVBases();
- }
- break;
-
- case clang::Type::Typedef:
- count = ClangASTContext::GetNumVirtualBaseClasses (ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
- break;
-
- case clang::Type::Elaborated:
- count = ClangASTContext::GetNumVirtualBaseClasses (ast, cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
- break;
-
- case clang::Type::Paren:
- count = ClangASTContext::GetNumVirtualBaseClasses(ast, cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr());
- break;
-
- default:
- break;
- }
- return count;
-}
-
-uint32_t
-ClangASTContext::GetNumFields (clang::ASTContext *ast, clang_type_t clang_type)
-{
- if (clang_type == NULL)
- return 0;
-
- uint32_t count = 0;
- QualType qual_type(QualType::getFromOpaquePtr(clang_type));
- const clang::Type::TypeClass type_class = qual_type->getTypeClass();
- switch (type_class)
- {
- case clang::Type::Record:
- if (GetCompleteQualType (ast, qual_type))
- {
- const RecordType *record_type = dyn_cast<RecordType>(qual_type.getTypePtr());
- if (record_type)
- {
- RecordDecl *record_decl = record_type->getDecl();
- if (record_decl)
- {
- uint32_t field_idx = 0;
- RecordDecl::field_iterator field, field_end;
- for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field)
- ++field_idx;
- count = field_idx;
- }
- }
- }
- break;
-
- case clang::Type::Typedef:
- count = ClangASTContext::GetNumFields (ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
- break;
-
- case clang::Type::Elaborated:
- count = ClangASTContext::GetNumFields (ast, cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
- break;
-
- case clang::Type::Paren:
- count = ClangASTContext::GetNumFields(ast, cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr());
- break;
-
- case clang::Type::ObjCObjectPointer:
- if (GetCompleteQualType (ast, qual_type))
- {
- const ObjCObjectPointerType *objc_class_type = qual_type->getAsObjCInterfacePointerType();
- if (objc_class_type)
- {
- ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterfaceDecl();
-
- if (class_interface_decl)
- count = class_interface_decl->ivar_size();
- }
- }
- break;
-
- case clang::Type::ObjCObject:
- case clang::Type::ObjCInterface:
- if (GetCompleteQualType (ast, qual_type))
- {
- const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
- if (objc_class_type)
- {
- ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
-
- if (class_interface_decl)
- count = class_interface_decl->ivar_size();
- }
- }
- break;
-
- default:
- break;
- }
- return count;
-}
-
-clang_type_t
-ClangASTContext::GetDirectBaseClassAtIndex (clang::ASTContext *ast,
- clang_type_t clang_type,
- size_t idx,
- uint32_t *bit_offset_ptr)
-{
- if (clang_type == NULL)
- return 0;
-
- QualType qual_type(QualType::getFromOpaquePtr(clang_type));
- const clang::Type::TypeClass type_class = qual_type->getTypeClass();
- switch (type_class)
- {
- case clang::Type::Record:
- if (GetCompleteQualType (ast, qual_type))
- {
- const CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
- if (cxx_record_decl)
- {
- uint32_t curr_idx = 0;
- CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
- for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
- base_class != base_class_end;
- ++base_class, ++curr_idx)
- {
- if (curr_idx == idx)
- {
- if (bit_offset_ptr)
- {
- const ASTRecordLayout &record_layout = ast->getASTRecordLayout(cxx_record_decl);
- const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
- if (base_class->isVirtual())
- *bit_offset_ptr = record_layout.getVBaseClassOffset(base_class_decl).getQuantity() * 8;
- else
- *bit_offset_ptr = record_layout.getBaseClassOffset(base_class_decl).getQuantity() * 8;
- }
- return base_class->getType().getAsOpaquePtr();
- }
- }
- }
- }
- break;
-
- case clang::Type::ObjCObjectPointer:
- if (idx == 0 && GetCompleteQualType (ast, qual_type))
- {
- const ObjCObjectPointerType *objc_class_type = qual_type->getAsObjCInterfacePointerType();
- if (objc_class_type)
- {
- ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterfaceDecl();
- if (class_interface_decl)
- {
- ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
- if (superclass_interface_decl)
- {
- if (bit_offset_ptr)
- *bit_offset_ptr = 0;
- return ast->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr();
- }
- }
- }
- }
- break;
-
- case clang::Type::ObjCObject:
- case clang::Type::ObjCInterface:
- if (idx == 0 && GetCompleteQualType (ast, qual_type))
- {
- const ObjCObjectType *objc_class_type = qual_type->getAsObjCQualifiedInterfaceType();
- if (objc_class_type)
- {
- ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
-
- if (class_interface_decl)
- {
- ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
- if (superclass_interface_decl)
- {
- if (bit_offset_ptr)
- *bit_offset_ptr = 0;
- return ast->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr();
- }
- }
- }
- }
- break;
-
-
- case clang::Type::Typedef:
- return ClangASTContext::GetDirectBaseClassAtIndex (ast,
- cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
- idx,
- bit_offset_ptr);
-
- case clang::Type::Elaborated:
- return ClangASTContext::GetDirectBaseClassAtIndex (ast,
- cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(),
- idx,
- bit_offset_ptr);
-
- case clang::Type::Paren:
- return ClangASTContext::GetDirectBaseClassAtIndex (ast,
- cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
- idx,
- bit_offset_ptr);
-
- default:
- break;
- }
- return NULL;
-}
-
-clang_type_t
-ClangASTContext::GetVirtualBaseClassAtIndex (clang::ASTContext *ast,
- clang_type_t clang_type,
- size_t idx,
- uint32_t *bit_offset_ptr)
-{
- if (clang_type == NULL)
- return 0;
-
- QualType qual_type(QualType::getFromOpaquePtr(clang_type));
- const clang::Type::TypeClass type_class = qual_type->getTypeClass();
- switch (type_class)
- {
- case clang::Type::Record:
- if (GetCompleteQualType (ast, qual_type))
- {
- const CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
- if (cxx_record_decl)
- {
- uint32_t curr_idx = 0;
- CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
- for (base_class = cxx_record_decl->vbases_begin(), base_class_end = cxx_record_decl->vbases_end();
- base_class != base_class_end;
- ++base_class, ++curr_idx)
- {
- if (curr_idx == idx)
- {
- if (bit_offset_ptr)
- {
- const ASTRecordLayout &record_layout = ast->getASTRecordLayout(cxx_record_decl);
- const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
- *bit_offset_ptr = record_layout.getVBaseClassOffset(base_class_decl).getQuantity() * 8;
-
- }
- return base_class->getType().getAsOpaquePtr();
- }
- }
- }
- }
- break;
-
- case clang::Type::Typedef:
- return ClangASTContext::GetVirtualBaseClassAtIndex (ast,
- cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
- idx,
- bit_offset_ptr);
-
- case clang::Type::Elaborated:
- return ClangASTContext::GetVirtualBaseClassAtIndex (ast,
- cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(),
- idx,
- bit_offset_ptr);
-
- case clang::Type::Paren:
- return ClangASTContext::GetVirtualBaseClassAtIndex (ast,
- cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
- idx,
- bit_offset_ptr);
-
- default:
- break;
- }
- return NULL;
-}
-
-static clang_type_t
-GetObjCFieldAtIndex (clang::ASTContext *ast,
- ObjCInterfaceDecl * class_interface_decl,
- size_t idx,
- std::string& name,
- uint64_t *bit_offset_ptr,
- uint32_t *bitfield_bit_size_ptr,
- bool *is_bitfield_ptr)
-{
- if (class_interface_decl)
- {
- if (idx < (class_interface_decl->ivar_size()))
- {
- ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
- uint32_t ivar_idx = 0;
-
- for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos, ++ivar_idx)
- {
- if (ivar_idx == idx)
- {
- const ObjCIvarDecl* ivar_decl = *ivar_pos;
-
- QualType ivar_qual_type(ivar_decl->getType());
-
- name.assign(ivar_decl->getNameAsString());
-
- if (bit_offset_ptr)
- {
- const ASTRecordLayout &interface_layout = ast->getASTObjCInterfaceLayout(class_interface_decl);
- *bit_offset_ptr = interface_layout.getFieldOffset (ivar_idx);
- }
-
- const bool is_bitfield = ivar_pos->isBitField();
-
- if (bitfield_bit_size_ptr)
- {
- *bitfield_bit_size_ptr = 0;
-
- if (is_bitfield && ast)
- {
- Expr *bitfield_bit_size_expr = ivar_pos->getBitWidth();
- llvm::APSInt bitfield_apsint;
- if (bitfield_bit_size_expr && bitfield_bit_size_expr->EvaluateAsInt(bitfield_apsint, *ast))
- {
- *bitfield_bit_size_ptr = bitfield_apsint.getLimitedValue();
- }
- }
- }
- if (is_bitfield_ptr)
- *is_bitfield_ptr = is_bitfield;
-
- return ivar_qual_type.getAsOpaquePtr();
- }
- }
- }
- }
- return NULL;
-}
-
-clang_type_t
-ClangASTContext::GetFieldAtIndex (clang::ASTContext *ast,
- clang_type_t clang_type,
- size_t idx,
- std::string& name,
- uint64_t *bit_offset_ptr,
- uint32_t *bitfield_bit_size_ptr,
- bool *is_bitfield_ptr)
-{
- if (clang_type == NULL)
- return 0;
-
- QualType qual_type(QualType::getFromOpaquePtr(clang_type));
- const clang::Type::TypeClass type_class = qual_type->getTypeClass();
- switch (type_class)
- {
- case clang::Type::Record:
- if (GetCompleteQualType (ast, qual_type))
- {
- const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
- const RecordDecl *record_decl = record_type->getDecl();
- uint32_t field_idx = 0;
- RecordDecl::field_iterator field, field_end;
- for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field, ++field_idx)
- {
- if (idx == field_idx)
- {
- // Print the member type if requested
- // Print the member name and equal sign
- name.assign(field->getNameAsString());
-
- // Figure out the type byte size (field_type_info.first) and
- // alignment (field_type_info.second) from the AST context.
- if (bit_offset_ptr)
- {
- const ASTRecordLayout &record_layout = ast->getASTRecordLayout(record_decl);
- *bit_offset_ptr = record_layout.getFieldOffset (field_idx);
- }
-
- const bool is_bitfield = field->isBitField();
-
- if (bitfield_bit_size_ptr)
- {
- *bitfield_bit_size_ptr = 0;
-
- if (is_bitfield && ast)
- {
- Expr *bitfield_bit_size_expr = field->getBitWidth();
- llvm::APSInt bitfield_apsint;
- if (bitfield_bit_size_expr && bitfield_bit_size_expr->EvaluateAsInt(bitfield_apsint, *ast))
- {
- *bitfield_bit_size_ptr = bitfield_apsint.getLimitedValue();
- }
- }
- }
- if (is_bitfield_ptr)
- *is_bitfield_ptr = is_bitfield;
-
- return field->getType().getAsOpaquePtr();
- }
- }
- }
- break;
-
- case clang::Type::ObjCObjectPointer:
- if (GetCompleteQualType (ast, qual_type))
- {
- const ObjCObjectPointerType *objc_class_type = qual_type->getAsObjCInterfacePointerType();
- if (objc_class_type)
- {
- ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterfaceDecl();
- return GetObjCFieldAtIndex(ast, class_interface_decl, idx, name, bit_offset_ptr, bitfield_bit_size_ptr, is_bitfield_ptr);
- }
- }
- break;
-
- case clang::Type::ObjCObject:
- case clang::Type::ObjCInterface:
- if (GetCompleteQualType (ast, qual_type))
- {
- const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
- assert (objc_class_type);
- if (objc_class_type)
- {
- ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
- return GetObjCFieldAtIndex(ast, class_interface_decl, idx, name, bit_offset_ptr, bitfield_bit_size_ptr, is_bitfield_ptr);
- }
- }
- break;
-
-
- case clang::Type::Typedef:
- return ClangASTContext::GetFieldAtIndex (ast,
- cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
- idx,
- name,
- bit_offset_ptr,
- bitfield_bit_size_ptr,
- is_bitfield_ptr);
-
- case clang::Type::Elaborated:
- return ClangASTContext::GetFieldAtIndex (ast,
- cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(),
- idx,
- name,
- bit_offset_ptr,
- bitfield_bit_size_ptr,
- is_bitfield_ptr);
-
- case clang::Type::Paren:
- return ClangASTContext::GetFieldAtIndex (ast,
- cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
- idx,
- name,
- bit_offset_ptr,
- bitfield_bit_size_ptr,
- is_bitfield_ptr);
-
- default:
- break;
- }
- return NULL;
-}
-
-size_t
-ClangASTContext::GetIndexOfFieldWithName (clang::ASTContext *ast,
- lldb::clang_type_t clang_type,
- const char* name,
- lldb::clang_type_t* field_clang_type,
- uint64_t *bit_offset_ptr,
- uint32_t *bitfield_bit_size_ptr,
- bool *is_bitfield_ptr)
-{
- unsigned count = ClangASTContext::GetNumFields(ast, clang_type);
- lldb::clang_type_t field_clang_type_internal;
- std::string field_name;
- for (unsigned index = 0; index < count; index++)
- {
- field_clang_type_internal = ClangASTContext::GetFieldAtIndex(ast, clang_type, index, field_name, bit_offset_ptr, bitfield_bit_size_ptr, is_bitfield_ptr);
- if ( strcmp(field_name.c_str(), name) == 0 )
- {
- if (field_clang_type)
- *field_clang_type = field_clang_type_internal;
- return index;
- }
- }
- return UINT32_MAX;
-}
-
-lldb::BasicType
-ClangASTContext::GetLLDBBasicTypeEnumeration (clang_type_t clang_type)
-{
- if (clang_type)
- {
- QualType qual_type(QualType::getFromOpaquePtr(clang_type));
- const clang::Type::TypeClass type_class = qual_type->getTypeClass();
- if (type_class == clang::Type::Builtin)
- {
- switch (cast<clang::BuiltinType>(qual_type)->getKind())
- {
- case clang::BuiltinType::Void: return eBasicTypeVoid;
- case clang::BuiltinType::Bool: return eBasicTypeBool;
- case clang::BuiltinType::Char_S: return eBasicTypeSignedChar;
- case clang::BuiltinType::Char_U: return eBasicTypeUnsignedChar;
- case clang::BuiltinType::Char16: return eBasicTypeChar16;
- case clang::BuiltinType::Char32: return eBasicTypeChar32;
- case clang::BuiltinType::UChar: return eBasicTypeUnsignedChar;
- case clang::BuiltinType::SChar: return eBasicTypeSignedChar;
- case clang::BuiltinType::WChar_S: return eBasicTypeSignedWChar;
- case clang::BuiltinType::WChar_U: return eBasicTypeUnsignedWChar;
- case clang::BuiltinType::Short: return eBasicTypeShort;
- case clang::BuiltinType::UShort: return eBasicTypeUnsignedShort;
- case clang::BuiltinType::Int: return eBasicTypeInt;
- case clang::BuiltinType::UInt: return eBasicTypeUnsignedInt;
- case clang::BuiltinType::Long: return eBasicTypeLong;
- case clang::BuiltinType::ULong: return eBasicTypeUnsignedLong;
- case clang::BuiltinType::LongLong: return eBasicTypeLongLong;
- case clang::BuiltinType::ULongLong: return eBasicTypeUnsignedLongLong;
- case clang::BuiltinType::Int128: return eBasicTypeInt128;
- case clang::BuiltinType::UInt128: return eBasicTypeUnsignedInt128;
-
- case clang::BuiltinType::Half: return eBasicTypeHalf;
- case clang::BuiltinType::Float: return eBasicTypeFloat;
- case clang::BuiltinType::Double: return eBasicTypeDouble;
- case clang::BuiltinType::LongDouble:return eBasicTypeLongDouble;
-
- case clang::BuiltinType::NullPtr: return eBasicTypeNullPtr;
- case clang::BuiltinType::ObjCId: return eBasicTypeObjCID;
- case clang::BuiltinType::ObjCClass: return eBasicTypeObjCClass;
- case clang::BuiltinType::ObjCSel: return eBasicTypeObjCSel;
- case clang::BuiltinType::Dependent:
- case clang::BuiltinType::Overload:
- case clang::BuiltinType::BoundMember:
- case clang::BuiltinType::PseudoObject:
- case clang::BuiltinType::UnknownAny:
- case clang::BuiltinType::BuiltinFn:
- case clang::BuiltinType::ARCUnbridgedCast:
- 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::OCLSampler:
- return eBasicTypeOther;
- }
- }
- }
-
- return eBasicTypeInvalid;
-}
-
-
-
-// If a pointer to a pointee type (the clang_type arg) says that it has no
-// children, then we either need to trust it, or override it and return a
-// different result. For example, an "int *" has one child that is an integer,
-// but a function pointer doesn't have any children. Likewise if a Record type
-// claims it has no children, then there really is nothing to show.
-uint32_t
-ClangASTContext::GetNumPointeeChildren (clang_type_t clang_type)
-{
- if (clang_type == NULL)
- return 0;
-
- QualType qual_type(QualType::getFromOpaquePtr(clang_type));
- const clang::Type::TypeClass type_class = qual_type->getTypeClass();
- switch (type_class)
- {
- case clang::Type::Builtin:
- switch (cast<clang::BuiltinType>(qual_type)->getKind())
- {
- case clang::BuiltinType::UnknownAny:
- 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::OCLSampler:
- return 0;
- case clang::BuiltinType::Bool:
- case clang::BuiltinType::Char_U:
- case clang::BuiltinType::UChar:
- case clang::BuiltinType::WChar_U:
- case clang::BuiltinType::Char16:
- case clang::BuiltinType::Char32:
- case clang::BuiltinType::UShort:
- case clang::BuiltinType::UInt:
- case clang::BuiltinType::ULong:
- case clang::BuiltinType::ULongLong:
- case clang::BuiltinType::UInt128:
- case clang::BuiltinType::Char_S:
- case clang::BuiltinType::SChar:
- case clang::BuiltinType::WChar_S:
- case clang::BuiltinType::Short:
- case clang::BuiltinType::Int:
- case clang::BuiltinType::Long:
- case clang::BuiltinType::LongLong:
- case clang::BuiltinType::Int128:
- case clang::BuiltinType::Float:
- case clang::BuiltinType::Double:
- case clang::BuiltinType::LongDouble:
- case clang::BuiltinType::Dependent:
- case clang::BuiltinType::Overload:
- case clang::BuiltinType::ObjCId:
- case clang::BuiltinType::ObjCClass:
- case clang::BuiltinType::ObjCSel:
- case clang::BuiltinType::BoundMember:
- case clang::BuiltinType::Half:
- case clang::BuiltinType::ARCUnbridgedCast:
- case clang::BuiltinType::PseudoObject:
- case clang::BuiltinType::BuiltinFn:
- return 1;
- }
- break;
-
- case clang::Type::Complex: return 1;
- case clang::Type::Pointer: return 1;
- case clang::Type::BlockPointer: return 0; // If block pointers don't have debug info, then no children for them
- case clang::Type::LValueReference: return 1;
- case clang::Type::RValueReference: return 1;
- case clang::Type::MemberPointer: return 0;
- case clang::Type::ConstantArray: return 0;
- case clang::Type::IncompleteArray: return 0;
- case clang::Type::VariableArray: return 0;
- case clang::Type::DependentSizedArray: return 0;
- case clang::Type::DependentSizedExtVector: return 0;
- case clang::Type::Vector: return 0;
- case clang::Type::ExtVector: return 0;
- case clang::Type::FunctionProto: return 0; // When we function pointers, they have no children...
- case clang::Type::FunctionNoProto: return 0; // When we function pointers, they have no children...
- case clang::Type::UnresolvedUsing: return 0;
- case clang::Type::Paren: return ClangASTContext::GetNumPointeeChildren (cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr());
- case clang::Type::Typedef: return ClangASTContext::GetNumPointeeChildren (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
- case clang::Type::Elaborated: return ClangASTContext::GetNumPointeeChildren (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
- case clang::Type::TypeOfExpr: return 0;
- case clang::Type::TypeOf: return 0;
- case clang::Type::Decltype: return 0;
- case clang::Type::Record: return 0;
- case clang::Type::Enum: return 1;
- case clang::Type::TemplateTypeParm: return 1;
- case clang::Type::SubstTemplateTypeParm: return 1;
- case clang::Type::TemplateSpecialization: return 1;
- case clang::Type::InjectedClassName: return 0;
- case clang::Type::DependentName: return 1;
- case clang::Type::DependentTemplateSpecialization: return 1;
- case clang::Type::ObjCObject: return 0;
- case clang::Type::ObjCInterface: return 0;
- case clang::Type::ObjCObjectPointer: return 1;
- default:
- break;
- }
- return 0;
-}
-
-clang_type_t
-ClangASTContext::GetChildClangTypeAtIndex
-(
- ExecutionContext *exe_ctx,
- const char *parent_name,
- clang_type_t parent_clang_type,
- 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
-)
-{
- if (parent_clang_type)
-
- return GetChildClangTypeAtIndex (exe_ctx,
- getASTContext(),
- parent_name,
- parent_clang_type,
- 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);
- return NULL;
-}
-
-clang_type_t
-ClangASTContext::GetChildClangTypeAtIndex
-(
- ExecutionContext *exe_ctx,
- ASTContext *ast,
- const char *parent_name,
- clang_type_t parent_clang_type,
- 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
-)
-{
- if (parent_clang_type == NULL)
- return NULL;
-
- QualType parent_qual_type(QualType::getFromOpaquePtr(parent_clang_type));
- const clang::Type::TypeClass parent_type_class = parent_qual_type->getTypeClass();
- child_bitfield_bit_size = 0;
- child_bitfield_bit_offset = 0;
- child_is_base_class = false;
-
- const bool idx_is_valid = idx < ClangASTContext::GetNumChildren (ast, parent_clang_type, omit_empty_base_classes);
- uint32_t bit_offset;
- switch (parent_type_class)
- {
- case clang::Type::Builtin:
- if (idx_is_valid)
- {
- switch (cast<clang::BuiltinType>(parent_qual_type)->getKind())
- {
- case clang::BuiltinType::ObjCId:
- case clang::BuiltinType::ObjCClass:
- child_name = "isa";
- child_byte_size = ast->getTypeSize(ast->ObjCBuiltinClassTy) / CHAR_BIT;
- return ast->ObjCBuiltinClassTy.getAsOpaquePtr();
-
- default:
- break;
- }
- }
- break;
-
- case clang::Type::Record:
- if (idx_is_valid && GetCompleteQualType (ast, parent_qual_type))
- {
- const RecordType *record_type = cast<RecordType>(parent_qual_type.getTypePtr());
- const RecordDecl *record_decl = record_type->getDecl();
- assert(record_decl);
- const ASTRecordLayout &record_layout = ast->getASTRecordLayout(record_decl);
- uint32_t child_idx = 0;
-
- const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
- if (cxx_record_decl)
- {
- // We might have base classes to print out first
- CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
- for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
- base_class != base_class_end;
- ++base_class)
- {
- const CXXRecordDecl *base_class_decl = NULL;
-
- // Skip empty base classes
- if (omit_empty_base_classes)
- {
- base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
- if (RecordHasFields(base_class_decl) == false)
- continue;
- }
-
- if (idx == child_idx)
- {
- if (base_class_decl == NULL)
- base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
-
-
- if (base_class->isVirtual())
- bit_offset = record_layout.getVBaseClassOffset(base_class_decl).getQuantity() * 8;
- else
- bit_offset = record_layout.getBaseClassOffset(base_class_decl).getQuantity() * 8;
-
- // Base classes should be a multiple of 8 bits in size
- child_byte_offset = bit_offset/8;
-
- child_name = ClangASTType::GetTypeNameForQualType(ast, base_class->getType());
-
- uint64_t clang_type_info_bit_size = ast->getTypeSize(base_class->getType());
-
- // Base classes bit sizes should be a multiple of 8 bits in size
- assert (clang_type_info_bit_size % 8 == 0);
- child_byte_size = clang_type_info_bit_size / 8;
- child_is_base_class = true;
- return base_class->getType().getAsOpaquePtr();
- }
- // We don't increment the child index in the for loop since we might
- // be skipping empty base classes
- ++child_idx;
- }
- }
- // Make sure index is in range...
- uint32_t field_idx = 0;
- RecordDecl::field_iterator field, field_end;
- for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field, ++field_idx, ++child_idx)
- {
- if (idx == child_idx)
- {
- // Print the member type if requested
- // Print the member name and equal sign
- child_name.assign(field->getNameAsString().c_str());
-
- // Figure out the type byte size (field_type_info.first) and
- // alignment (field_type_info.second) from the AST context.
- std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(field->getType());
- assert(field_idx < record_layout.getFieldCount());
-
- child_byte_size = field_type_info.first / 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 (ast, *field, child_bitfield_bit_size))
- child_bitfield_bit_offset = bit_offset % 8;
-
- return field->getType().getAsOpaquePtr();
- }
- }
- }
- break;
-
- case clang::Type::ObjCObject:
- case clang::Type::ObjCInterface:
- if (idx_is_valid && GetCompleteQualType (ast, parent_qual_type))
- {
- const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(parent_qual_type.getTypePtr());
- assert (objc_class_type);
- if (objc_class_type)
- {
- uint32_t child_idx = 0;
- ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
-
- if (class_interface_decl)
- {
-
- const ASTRecordLayout &interface_layout = ast->getASTObjCInterfaceLayout(class_interface_decl);
- ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
- if (superclass_interface_decl)
- {
- if (omit_empty_base_classes)
- {
- if (ClangASTContext::GetNumChildren(ast, ast->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(), omit_empty_base_classes) > 0)
- {
- if (idx == 0)
- {
- QualType ivar_qual_type(ast->getObjCInterfaceType(superclass_interface_decl));
-
-
- child_name.assign(superclass_interface_decl->getNameAsString().c_str());
-
- std::pair<uint64_t, unsigned> ivar_type_info = ast->getTypeInfo(ivar_qual_type.getTypePtr());
-
- child_byte_size = ivar_type_info.first / 8;
- child_byte_offset = 0;
- child_is_base_class = true;
-
- return ivar_qual_type.getAsOpaquePtr();
- }
-
- ++child_idx;
- }
- }
- else
- ++child_idx;
- }
-
- const uint32_t superclass_idx = child_idx;
-
- if (idx < (child_idx + class_interface_decl->ivar_size()))
- {
- ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
-
- for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos)
- {
- if (child_idx == idx)
- {
- ObjCIvarDecl* ivar_decl = *ivar_pos;
-
- QualType ivar_qual_type(ivar_decl->getType());
-
- child_name.assign(ivar_decl->getNameAsString().c_str());
-
- std::pair<uint64_t, unsigned> ivar_type_info = ast->getTypeInfo(ivar_qual_type.getTypePtr());
-
- child_byte_size = ivar_type_info.first / 8;
-
- // Figure out the field offset within the current struct/union/class type
- // For ObjC objects, we can't trust the bit offset we get from the Clang AST, since
- // that doesn't account for the space taken up by unbacked properties, or from
- // the changing size of base classes that are newer than this class.
- // So if we have a process around that we can ask about this object, do so.
- child_byte_offset = LLDB_INVALID_IVAR_OFFSET;
- Process *process = NULL;
- if (exe_ctx)
- process = exe_ctx->GetProcessPtr();
- if (process)
- {
- ObjCLanguageRuntime *objc_runtime = process->GetObjCLanguageRuntime();
- if (objc_runtime != NULL)
- {
- ClangASTType parent_ast_type (ast, parent_qual_type.getAsOpaquePtr());
- child_byte_offset = objc_runtime->GetByteOffsetForIvar (parent_ast_type, ivar_decl->getNameAsString().c_str());
- }
- }
-
- // Setting this to UINT32_MAX to make sure we don't compute it twice...
- bit_offset = UINT32_MAX;
-
- if (child_byte_offset == LLDB_INVALID_IVAR_OFFSET)
- {
- bit_offset = interface_layout.getFieldOffset (child_idx - superclass_idx);
- child_byte_offset = bit_offset / 8;
- }
-
- // Note, the ObjC Ivar Byte offset is just that, it doesn't account for the bit offset
- // of a bitfield within its containing object. So regardless of where we get the byte
- // offset from, we still need to get the bit offset for bitfields from the layout.
-
- if (ClangASTContext::FieldIsBitfield (ast, ivar_decl, child_bitfield_bit_size))
- {
- if (bit_offset == UINT32_MAX)
- bit_offset = interface_layout.getFieldOffset (child_idx - superclass_idx);
-
- child_bitfield_bit_offset = bit_offset % 8;
- }
- return ivar_qual_type.getAsOpaquePtr();
- }
- ++child_idx;
- }
- }
- }
- }
- }
- break;
-
- case clang::Type::ObjCObjectPointer:
- if (idx_is_valid)
- {
- const ObjCObjectPointerType *pointer_type = cast<ObjCObjectPointerType>(parent_qual_type.getTypePtr());
- QualType pointee_type = pointer_type->getPointeeType();
-
- if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
- {
- child_is_deref_of_parent = false;
- bool tmp_child_is_deref_of_parent = false;
- return GetChildClangTypeAtIndex (exe_ctx,
- ast,
- parent_name,
- pointer_type->getPointeeType().getAsOpaquePtr(),
- 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,
- tmp_child_is_deref_of_parent);
- }
- else
- {
- child_is_deref_of_parent = true;
- if (parent_name)
- {
- child_name.assign(1, '*');
- child_name += parent_name;
- }
-
- // We have a pointer to an simple type
- if (idx == 0 && GetCompleteQualType(ast, pointee_type))
- {
- std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
- assert(clang_type_info.first % 8 == 0);
- child_byte_size = clang_type_info.first / 8;
- child_byte_offset = 0;
- return pointee_type.getAsOpaquePtr();
- }
- }
- }
- break;
-
- case clang::Type::Vector:
- case clang::Type::ExtVector:
- if (idx_is_valid)
- {
- const VectorType *array = cast<VectorType>(parent_qual_type.getTypePtr());
- if (array)
- {
- if (GetCompleteQualType (ast, array->getElementType()))
- {
- std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(array->getElementType());
-
- char element_name[64];
- ::snprintf (element_name, sizeof (element_name), "[%zu]", idx);
-
- child_name.assign(element_name);
- assert(field_type_info.first % 8 == 0);
- child_byte_size = field_type_info.first / 8;
- child_byte_offset = (int32_t)idx * (int32_t)child_byte_size;
- return array->getElementType().getAsOpaquePtr();
- }
- }
- }
- break;
-
- case clang::Type::ConstantArray:
- case clang::Type::IncompleteArray:
- if (ignore_array_bounds || idx_is_valid)
- {
- const ArrayType *array = cast<ArrayType>(parent_qual_type.getTypePtr());
- if (array)
- {
- if (GetCompleteQualType (ast, array->getElementType()))
- {
- std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(array->getElementType());
-
- char element_name[64];
- ::snprintf (element_name, sizeof (element_name), "[%zu]", idx);
-
- child_name.assign(element_name);
- assert(field_type_info.first % 8 == 0);
- child_byte_size = field_type_info.first / 8;
- child_byte_offset = (int32_t)idx * (int32_t)child_byte_size;
- return array->getElementType().getAsOpaquePtr();
- }
- }
- }
- break;
-
-
- case clang::Type::Pointer:
- if (idx_is_valid)
- {
- const PointerType *pointer_type = cast<PointerType>(parent_qual_type.getTypePtr());
- QualType pointee_type = pointer_type->getPointeeType();
-
- // Don't dereference "void *" pointers
- if (pointee_type->isVoidType())
- return NULL;
-
- if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
- {
- child_is_deref_of_parent = false;
- bool tmp_child_is_deref_of_parent = false;
- return GetChildClangTypeAtIndex (exe_ctx,
- ast,
- parent_name,
- pointer_type->getPointeeType().getAsOpaquePtr(),
- 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,
- tmp_child_is_deref_of_parent);
- }
- else
- {
- child_is_deref_of_parent = true;
-
- if (parent_name)
- {
- child_name.assign(1, '*');
- child_name += parent_name;
- }
-
- // We have a pointer to an simple type
- if (idx == 0)
- {
- std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
- assert(clang_type_info.first % 8 == 0);
- child_byte_size = clang_type_info.first / 8;
- child_byte_offset = 0;
- return pointee_type.getAsOpaquePtr();
- }
- }
- }
- break;
-
- case clang::Type::LValueReference:
- case clang::Type::RValueReference:
- if (idx_is_valid)
- {
- const ReferenceType *reference_type = cast<ReferenceType>(parent_qual_type.getTypePtr());
- QualType pointee_type(reference_type->getPointeeType());
- clang_type_t pointee_clang_type = pointee_type.getAsOpaquePtr();
- if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_clang_type))
- {
- child_is_deref_of_parent = false;
- bool tmp_child_is_deref_of_parent = false;
- return GetChildClangTypeAtIndex (exe_ctx,
- ast,
- parent_name,
- pointee_clang_type,
- 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,
- tmp_child_is_deref_of_parent);
- }
- else
- {
- if (parent_name)
- {
- child_name.assign(1, '&');
- child_name += parent_name;
- }
-
- // We have a pointer to an simple type
- if (idx == 0)
- {
- std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
- assert(clang_type_info.first % 8 == 0);
- child_byte_size = clang_type_info.first / 8;
- child_byte_offset = 0;
- return pointee_type.getAsOpaquePtr();
- }
- }
- }
- break;
-
- case clang::Type::Typedef:
- return GetChildClangTypeAtIndex (exe_ctx,
- ast,
- parent_name,
- cast<TypedefType>(parent_qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
- 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);
- break;
-
- case clang::Type::Elaborated:
- return GetChildClangTypeAtIndex (exe_ctx,
- ast,
- parent_name,
- cast<ElaboratedType>(parent_qual_type)->getNamedType().getAsOpaquePtr(),
- 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);
-
- case clang::Type::Paren:
- return GetChildClangTypeAtIndex (exe_ctx,
- ast,
- parent_name,
- llvm::cast<clang::ParenType>(parent_qual_type)->desugar().getAsOpaquePtr(),
- 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);
-
-
- default:
- break;
- }
- return NULL;
-}
-
-static inline bool
-BaseSpecifierIsEmpty (const CXXBaseSpecifier *b)
-{
- return ClangASTContext::RecordHasFields(b->getType()->getAsCXXRecordDecl()) == false;
-}
-
-static uint32_t
-GetNumBaseClasses (const CXXRecordDecl *cxx_record_decl, bool omit_empty_base_classes)
-{
- uint32_t num_bases = 0;
- if (cxx_record_decl)
- {
- if (omit_empty_base_classes)
- {
- CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
- for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
- base_class != base_class_end;
- ++base_class)
- {
- // Skip empty base classes
- if (omit_empty_base_classes)
- {
- if (BaseSpecifierIsEmpty (base_class))
- continue;
- }
- ++num_bases;
- }
- }
- else
- num_bases = cxx_record_decl->getNumBases();
- }
- return num_bases;
-}
-
-
-static uint32_t
-GetIndexForRecordBase
-(
- const RecordDecl *record_decl,
- const CXXBaseSpecifier *base_spec,
- bool omit_empty_base_classes
-)
-{
- uint32_t child_idx = 0;
-
- const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
-
-// const char *super_name = record_decl->getNameAsCString();
-// const char *base_name = base_spec->getType()->getAs<RecordType>()->getDecl()->getNameAsCString();
-// printf ("GetIndexForRecordChild (%s, %s)\n", super_name, base_name);
-//
- if (cxx_record_decl)
- {
- CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
- for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
- base_class != base_class_end;
- ++base_class)
- {
- if (omit_empty_base_classes)
- {
- if (BaseSpecifierIsEmpty (base_class))
- continue;
- }
-
-// printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n", super_name, base_name,
-// child_idx,
-// base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString());
-//
-//
- if (base_class == base_spec)
- return child_idx;
- ++child_idx;
- }
- }
-
- return UINT32_MAX;
-}
-
-
-static uint32_t
-GetIndexForRecordChild
-(
- const RecordDecl *record_decl,
- NamedDecl *canonical_decl,
- bool omit_empty_base_classes
-)
-{
- uint32_t child_idx = GetNumBaseClasses (dyn_cast<CXXRecordDecl>(record_decl), omit_empty_base_classes);
-
-// const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
-//
-//// printf ("GetIndexForRecordChild (%s, %s)\n", record_decl->getNameAsCString(), canonical_decl->getNameAsCString());
-// if (cxx_record_decl)
-// {
-// CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
-// for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
-// base_class != base_class_end;
-// ++base_class)
-// {
-// if (omit_empty_base_classes)
-// {
-// if (BaseSpecifierIsEmpty (base_class))
-// continue;
-// }
-//
-//// printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n",
-//// record_decl->getNameAsCString(),
-//// canonical_decl->getNameAsCString(),
-//// child_idx,
-//// base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString());
-//
-//
-// CXXRecordDecl *curr_base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
-// if (curr_base_class_decl == canonical_decl)
-// {
-// return child_idx;
-// }
-// ++child_idx;
-// }
-// }
-//
-// const uint32_t num_bases = child_idx;
- RecordDecl::field_iterator field, field_end;
- for (field = record_decl->field_begin(), field_end = record_decl->field_end();
- field != field_end;
- ++field, ++child_idx)
- {
-// printf ("GetIndexForRecordChild (%s, %s) field[%u] = %s\n",
-// record_decl->getNameAsCString(),
-// canonical_decl->getNameAsCString(),
-// child_idx - num_bases,
-// field->getNameAsCString());
-
- if (field->getCanonicalDecl() == canonical_decl)
- return child_idx;
- }
-
- return UINT32_MAX;
-}
-
-// Look for a child member (doesn't include base classes, but it does include
-// their members) in the type hierarchy. Returns an index path into "clang_type"
-// on how to reach the appropriate member.
-//
-// class A
-// {
-// public:
-// int m_a;
-// int m_b;
-// };
-//
-// class B
-// {
-// };
-//
-// class C :
-// public B,
-// public A
-// {
-// };
-//
-// If we have a clang type that describes "class C", and we wanted to looked
-// "m_b" in it:
-//
-// With omit_empty_base_classes == false we would get an integer array back with:
-// { 1, 1 }
-// The first index 1 is the child index for "class A" within class C
-// The second index 1 is the child index for "m_b" within class A
-//
-// With omit_empty_base_classes == true we would get an integer array back with:
-// { 0, 1 }
-// The first index 0 is the child index for "class A" within class C (since class B doesn't have any members it doesn't count)
-// The second index 1 is the child index for "m_b" within class A
-
-size_t
-ClangASTContext::GetIndexOfChildMemberWithName
-(
- ASTContext *ast,
- clang_type_t clang_type,
- const char *name,
- bool omit_empty_base_classes,
- std::vector<uint32_t>& child_indexes
-)
-{
- if (clang_type && name && name[0])
- {
- QualType qual_type(QualType::getFromOpaquePtr(clang_type));
- const clang::Type::TypeClass type_class = qual_type->getTypeClass();
- switch (type_class)
- {
- case clang::Type::Record:
- if (GetCompleteQualType (ast, qual_type))
- {
- const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
- const RecordDecl *record_decl = record_type->getDecl();
-
- assert(record_decl);
- uint32_t child_idx = 0;
-
- const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
-
- // Try and find a field that matches NAME
- RecordDecl::field_iterator field, field_end;
- StringRef name_sref(name);
- for (field = record_decl->field_begin(), field_end = record_decl->field_end();
- field != field_end;
- ++field, ++child_idx)
- {
- if (field->getName().equals (name_sref))
- {
- // We have to add on the number of base classes to this index!
- child_indexes.push_back (child_idx + GetNumBaseClasses (cxx_record_decl, omit_empty_base_classes));
- return child_indexes.size();
- }
- }
-
- if (cxx_record_decl)
- {
- const RecordDecl *parent_record_decl = cxx_record_decl;
-
- //printf ("parent = %s\n", parent_record_decl->getNameAsCString());
-
- //const Decl *root_cdecl = cxx_record_decl->getCanonicalDecl();
- // Didn't find things easily, lets let clang do its thang...
- IdentifierInfo & ident_ref = ast->Idents.get(name_sref);
- DeclarationName decl_name(&ident_ref);
-
- CXXBasePaths paths;
- if (cxx_record_decl->lookupInBases(CXXRecordDecl::FindOrdinaryMember,
- decl_name.getAsOpaquePtr(),
- paths))
- {
- CXXBasePaths::const_paths_iterator path, path_end = paths.end();
- for (path = paths.begin(); path != path_end; ++path)
- {
- const size_t num_path_elements = path->size();
- for (size_t e=0; e<num_path_elements; ++e)
- {
- CXXBasePathElement elem = (*path)[e];
-
- child_idx = GetIndexForRecordBase (parent_record_decl, elem.Base, omit_empty_base_classes);
- if (child_idx == UINT32_MAX)
- {
- child_indexes.clear();
- return 0;
- }
- else
- {
- child_indexes.push_back (child_idx);
- parent_record_decl = cast<RecordDecl>(elem.Base->getType()->getAs<RecordType>()->getDecl());
- }
- }
- for (NamedDecl *path_decl : path->Decls)
- {
- child_idx = GetIndexForRecordChild (parent_record_decl, path_decl, omit_empty_base_classes);
- if (child_idx == UINT32_MAX)
- {
- child_indexes.clear();
- return 0;
- }
- else
- {
- child_indexes.push_back (child_idx);
- }
- }
- }
- return child_indexes.size();
- }
- }
-
- }
- break;
-
- case clang::Type::ObjCObject:
- case clang::Type::ObjCInterface:
- if (GetCompleteQualType (ast, qual_type))
- {
- StringRef name_sref(name);
- const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
- assert (objc_class_type);
- if (objc_class_type)
- {
- uint32_t child_idx = 0;
- ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
-
- if (class_interface_decl)
- {
- ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
- ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
-
- for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos, ++child_idx)
- {
- const ObjCIvarDecl* ivar_decl = *ivar_pos;
-
- if (ivar_decl->getName().equals (name_sref))
- {
- if ((!omit_empty_base_classes && superclass_interface_decl) ||
- ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true)))
- ++child_idx;
-
- child_indexes.push_back (child_idx);
- return child_indexes.size();
- }
- }
-
- if (superclass_interface_decl)
- {
- // The super class index is always zero for ObjC classes,
- // so we push it onto the child indexes in case we find
- // an ivar in our superclass...
- child_indexes.push_back (0);
-
- if (GetIndexOfChildMemberWithName (ast,
- ast->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(),
- name,
- omit_empty_base_classes,
- child_indexes))
- {
- // We did find an ivar in a superclass so just
- // return the results!
- return child_indexes.size();
- }
-
- // We didn't find an ivar matching "name" in our
- // superclass, pop the superclass zero index that
- // we pushed on above.
- child_indexes.pop_back();
- }
- }
- }
- }
- break;
-
- case clang::Type::ObjCObjectPointer:
- {
- return GetIndexOfChildMemberWithName (ast,
- cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(),
- name,
- omit_empty_base_classes,
- child_indexes);
- }
- break;
-
-
- case clang::Type::ConstantArray:
- {
-// const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
-// const uint64_t element_count = array->getSize().getLimitedValue();
-//
-// if (idx < element_count)
-// {
-// std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(array->getElementType());
-//
-// char element_name[32];
-// ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
-//
-// child_name.assign(element_name);
-// assert(field_type_info.first % 8 == 0);
-// child_byte_size = field_type_info.first / 8;
-// child_byte_offset = idx * child_byte_size;
-// return array->getElementType().getAsOpaquePtr();
-// }
- }
- break;
-
-// case clang::Type::MemberPointerType:
-// {
-// MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr());
-// QualType pointee_type = mem_ptr_type->getPointeeType();
-//
-// if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
-// {
-// return GetIndexOfChildWithName (ast,
-// mem_ptr_type->getPointeeType().getAsOpaquePtr(),
-// name);
-// }
-// }
-// break;
-//
- case clang::Type::LValueReference:
- case clang::Type::RValueReference:
- {
- const ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
- QualType pointee_type = reference_type->getPointeeType();
-
- if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
- {
- return GetIndexOfChildMemberWithName (ast,
- reference_type->getPointeeType().getAsOpaquePtr(),
- name,
- omit_empty_base_classes,
- child_indexes);
- }
- }
- break;
-
- case clang::Type::Pointer:
- {
- const PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
- QualType pointee_type = pointer_type->getPointeeType();
-
- if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
- {
- return GetIndexOfChildMemberWithName (ast,
- pointer_type->getPointeeType().getAsOpaquePtr(),
- name,
- omit_empty_base_classes,
- child_indexes);
- }
- else
- {
-// if (parent_name)
-// {
-// child_name.assign(1, '*');
-// child_name += parent_name;
-// }
-//
-// // We have a pointer to an simple type
-// if (idx == 0)
-// {
-// std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
-// assert(clang_type_info.first % 8 == 0);
-// child_byte_size = clang_type_info.first / 8;
-// child_byte_offset = 0;
-// return pointee_type.getAsOpaquePtr();
-// }
- }
- }
- break;
-
- case clang::Type::Typedef:
- return GetIndexOfChildMemberWithName (ast,
- cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
- name,
- omit_empty_base_classes,
- child_indexes);
-
- case clang::Type::Elaborated:
- return GetIndexOfChildMemberWithName (ast,
- cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(),
- name,
- omit_empty_base_classes,
- child_indexes);
-
- case clang::Type::Paren:
- return GetIndexOfChildMemberWithName (ast,
- cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
- name,
- omit_empty_base_classes,
- child_indexes);
-
- default:
- break;
- }
- }
- return 0;
-}
-
-
-// Get the index of the child of "clang_type" whose name matches. This function
-// doesn't descend into the children, but only looks one level deep and name
-// matches can include base class names.
-
-uint32_t
-ClangASTContext::GetIndexOfChildWithName
-(
- ASTContext *ast,
- clang_type_t clang_type,
- const char *name,
- bool omit_empty_base_classes
-)
-{
- if (clang_type && name && name[0])
- {
- QualType qual_type(QualType::getFromOpaquePtr(clang_type));
-
- const clang::Type::TypeClass type_class = qual_type->getTypeClass();
-
- switch (type_class)
- {
- case clang::Type::Record:
- if (GetCompleteQualType (ast, qual_type))
- {
- const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
- const RecordDecl *record_decl = record_type->getDecl();
-
- assert(record_decl);
- uint32_t child_idx = 0;
-
- const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
-
- if (cxx_record_decl)
- {
- CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
- for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
- base_class != base_class_end;
- ++base_class)
- {
- // Skip empty base classes
- CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
- if (omit_empty_base_classes && RecordHasFields(base_class_decl) == false)
- continue;
-
- std::string base_class_type_name (ClangASTType::GetTypeNameForQualType(ast, base_class->getType()));
- if (base_class_type_name.compare (name) == 0)
- return child_idx;
- ++child_idx;
- }
- }
-
- // Try and find a field that matches NAME
- RecordDecl::field_iterator field, field_end;
- StringRef name_sref(name);
- for (field = record_decl->field_begin(), field_end = record_decl->field_end();
- field != field_end;
- ++field, ++child_idx)
- {
- if (field->getName().equals (name_sref))
- return child_idx;
- }
-
- }
- break;
-
- case clang::Type::ObjCObject:
- case clang::Type::ObjCInterface:
- if (GetCompleteQualType (ast, qual_type))
- {
- StringRef name_sref(name);
- const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
- assert (objc_class_type);
- if (objc_class_type)
- {
- uint32_t child_idx = 0;
- ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
-
- if (class_interface_decl)
- {
- ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
- ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
-
- for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos, ++child_idx)
- {
- const ObjCIvarDecl* ivar_decl = *ivar_pos;
-
- if (ivar_decl->getName().equals (name_sref))
- {
- if ((!omit_empty_base_classes && superclass_interface_decl) ||
- ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true)))
- ++child_idx;
-
- return child_idx;
- }
- }
-
- if (superclass_interface_decl)
- {
- if (superclass_interface_decl->getName().equals (name_sref))
- return 0;
- }
- }
- }
- }
- break;
-
- case clang::Type::ObjCObjectPointer:
- {
- return GetIndexOfChildWithName (ast,
- cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(),
- name,
- omit_empty_base_classes);
- }
- break;
-
- case clang::Type::ConstantArray:
- {
-// const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
-// const uint64_t element_count = array->getSize().getLimitedValue();
-//
-// if (idx < element_count)
-// {
-// std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(array->getElementType());
-//
-// char element_name[32];
-// ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
-//
-// child_name.assign(element_name);
-// assert(field_type_info.first % 8 == 0);
-// child_byte_size = field_type_info.first / 8;
-// child_byte_offset = idx * child_byte_size;
-// return array->getElementType().getAsOpaquePtr();
-// }
- }
- break;
-
-// case clang::Type::MemberPointerType:
-// {
-// MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr());
-// QualType pointee_type = mem_ptr_type->getPointeeType();
-//
-// if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
-// {
-// return GetIndexOfChildWithName (ast,
-// mem_ptr_type->getPointeeType().getAsOpaquePtr(),
-// name);
-// }
-// }
-// break;
-//
- case clang::Type::LValueReference:
- case clang::Type::RValueReference:
- {
- const ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
- QualType pointee_type = reference_type->getPointeeType();
-
- if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
- {
- return GetIndexOfChildWithName (ast,
- reference_type->getPointeeType().getAsOpaquePtr(),
- name,
- omit_empty_base_classes);
- }
- }
- break;
-
- case clang::Type::Pointer:
- {
- const PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
- QualType pointee_type = pointer_type->getPointeeType();
-
- if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
- {
- return GetIndexOfChildWithName (ast,
- pointer_type->getPointeeType().getAsOpaquePtr(),
- name,
- omit_empty_base_classes);
- }
- else
- {
-// if (parent_name)
-// {
-// child_name.assign(1, '*');
-// child_name += parent_name;
-// }
-//
-// // We have a pointer to an simple type
-// if (idx == 0)
-// {
-// std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
-// assert(clang_type_info.first % 8 == 0);
-// child_byte_size = clang_type_info.first / 8;
-// child_byte_offset = 0;
-// return pointee_type.getAsOpaquePtr();
-// }
- }
- }
- break;
-
- case clang::Type::Elaborated:
- return GetIndexOfChildWithName (ast,
- cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(),
- name,
- omit_empty_base_classes);
-
- case clang::Type::Paren:
- return GetIndexOfChildWithName (ast,
- cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
- name,
- omit_empty_base_classes);
-
- case clang::Type::Typedef:
- return GetIndexOfChildWithName (ast,
- cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
- name,
- omit_empty_base_classes);
-
- default:
- break;
- }
- }
- return UINT32_MAX;
-}
-
-#pragma mark TagType
-
-bool
-ClangASTContext::SetTagTypeKind (clang_type_t tag_clang_type, int kind)
-{
- if (tag_clang_type)
- {
- QualType tag_qual_type(QualType::getFromOpaquePtr(tag_clang_type));
- const clang::Type *clang_type = tag_qual_type.getTypePtr();
- if (clang_type)
- {
- const TagType *tag_type = dyn_cast<TagType>(clang_type);
- if (tag_type)
- {
- TagDecl *tag_decl = dyn_cast<TagDecl>(tag_type->getDecl());
- if (tag_decl)
- {
- tag_decl->setTagKind ((TagDecl::TagKind)kind);
- return true;
- }
- }
- }
- }
- return false;
-}
-
-
-#pragma mark DeclContext Functions
-
-DeclContext *
-ClangASTContext::GetDeclContextForType (clang_type_t clang_type)
-{
- if (clang_type == NULL)
- return NULL;
-
- QualType qual_type(QualType::getFromOpaquePtr(clang_type));
- const clang::Type::TypeClass type_class = qual_type->getTypeClass();
- switch (type_class)
- {
- case clang::Type::UnaryTransform: break;
- case clang::Type::FunctionNoProto: break;
- case clang::Type::FunctionProto: break;
- case clang::Type::IncompleteArray: break;
- case clang::Type::VariableArray: break;
- case clang::Type::ConstantArray: break;
- case clang::Type::DependentSizedArray: break;
- case clang::Type::ExtVector: break;
- case clang::Type::DependentSizedExtVector: break;
- case clang::Type::Vector: break;
- case clang::Type::Builtin: break;
- case clang::Type::BlockPointer: break;
- case clang::Type::Pointer: break;
- case clang::Type::LValueReference: break;
- case clang::Type::RValueReference: break;
- case clang::Type::MemberPointer: break;
- case clang::Type::Complex: break;
- case clang::Type::ObjCObject: break;
- case clang::Type::ObjCInterface: return cast<ObjCObjectType>(qual_type.getTypePtr())->getInterface();
- case clang::Type::ObjCObjectPointer: return ClangASTContext::GetDeclContextForType (cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr());
- case clang::Type::Record: return cast<RecordType>(qual_type)->getDecl();
- case clang::Type::Enum: return cast<EnumType>(qual_type)->getDecl();
- case clang::Type::Typedef: return ClangASTContext::GetDeclContextForType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
- case clang::Type::Elaborated: return ClangASTContext::GetDeclContextForType (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
- case clang::Type::Paren: return ClangASTContext::GetDeclContextForType (cast<ParenType>(qual_type)->desugar().getAsOpaquePtr());
- case clang::Type::TypeOfExpr: break;
- case clang::Type::TypeOf: break;
- case clang::Type::Decltype: break;
- //case clang::Type::QualifiedName: break;
- case clang::Type::TemplateSpecialization: break;
- case clang::Type::DependentTemplateSpecialization: break;
- case clang::Type::TemplateTypeParm: break;
- case clang::Type::SubstTemplateTypeParm: break;
- case clang::Type::SubstTemplateTypeParmPack:break;
- case clang::Type::PackExpansion: break;
- case clang::Type::UnresolvedUsing: break;
- case clang::Type::Attributed: break;
- case clang::Type::Auto: break;
- case clang::Type::InjectedClassName: break;
- case clang::Type::DependentName: break;
- case clang::Type::Atomic: break;
- }
- // No DeclContext in this type...
- return NULL;
-}
-
-#pragma mark Namespace Declarations
-
-NamespaceDecl *
-ClangASTContext::GetUniqueNamespaceDeclaration (const char *name, DeclContext *decl_ctx)
-{
- NamespaceDecl *namespace_decl = NULL;
- ASTContext *ast = getASTContext();
- TranslationUnitDecl *translation_unit_decl = ast->getTranslationUnitDecl ();
- if (decl_ctx == NULL)
- decl_ctx = translation_unit_decl;
-
- if (name)
- {
- IdentifierInfo &identifier_info = ast->Idents.get(name);
- DeclarationName decl_name (&identifier_info);
- clang::DeclContext::lookup_result result = decl_ctx->lookup(decl_name);
- for (NamedDecl *decl : result)
- {
- namespace_decl = dyn_cast<clang::NamespaceDecl>(decl);
- if (namespace_decl)
- return namespace_decl;
- }
-
- namespace_decl = NamespaceDecl::Create(*ast,
- decl_ctx,
- false,
- SourceLocation(),
- SourceLocation(),
- &identifier_info,
- NULL);
-
- decl_ctx->addDecl (namespace_decl);
- }
- else
- {
- if (decl_ctx == translation_unit_decl)
- {
- namespace_decl = translation_unit_decl->getAnonymousNamespace();
- if (namespace_decl)
- return namespace_decl;
-
- namespace_decl = NamespaceDecl::Create(*ast,
- decl_ctx,
- false,
- SourceLocation(),
- SourceLocation(),
- NULL,
- NULL);
- translation_unit_decl->setAnonymousNamespace (namespace_decl);
- translation_unit_decl->addDecl (namespace_decl);
- assert (namespace_decl == translation_unit_decl->getAnonymousNamespace());
- }
- else
- {
- NamespaceDecl *parent_namespace_decl = cast<NamespaceDecl>(decl_ctx);
- if (parent_namespace_decl)
- {
- namespace_decl = parent_namespace_decl->getAnonymousNamespace();
- if (namespace_decl)
- return namespace_decl;
- namespace_decl = NamespaceDecl::Create(*ast,
- decl_ctx,
- false,
- SourceLocation(),
- SourceLocation(),
- NULL,
- NULL);
- parent_namespace_decl->setAnonymousNamespace (namespace_decl);
- parent_namespace_decl->addDecl (namespace_decl);
- assert (namespace_decl == parent_namespace_decl->getAnonymousNamespace());
- }
- else
- {
- // BAD!!!
- }
- }
-
-
- if (namespace_decl)
- {
- // If we make it here, we are creating the anonymous namespace decl
- // for the first time, so we need to do the using directive magic
- // like SEMA does
- UsingDirectiveDecl* using_directive_decl = UsingDirectiveDecl::Create (*ast,
- decl_ctx,
- SourceLocation(),
- SourceLocation(),
- NestedNameSpecifierLoc(),
- SourceLocation(),
- namespace_decl,
- decl_ctx);
- using_directive_decl->setImplicit();
- decl_ctx->addDecl(using_directive_decl);
- }
- }
-#ifdef LLDB_CONFIGURATION_DEBUG
- VerifyDecl(namespace_decl);
-#endif
- return namespace_decl;
-}
-
-
-#pragma mark Function Types
-
-FunctionDecl *
-ClangASTContext::CreateFunctionDeclaration (DeclContext *decl_ctx, const char *name, clang_type_t function_clang_type, int storage, bool is_inline)
-{
- FunctionDecl *func_decl = NULL;
- ASTContext *ast = getASTContext();
- if (decl_ctx == NULL)
- decl_ctx = ast->getTranslationUnitDecl();
-
-
- const bool hasWrittenPrototype = true;
- const bool isConstexprSpecified = false;
-
- if (name && name[0])
- {
- func_decl = FunctionDecl::Create (*ast,
- decl_ctx,
- SourceLocation(),
- SourceLocation(),
- DeclarationName (&ast->Idents.get(name)),
- QualType::getFromOpaquePtr(function_clang_type),
- NULL,
- (FunctionDecl::StorageClass)storage,
- is_inline,
- hasWrittenPrototype,
- isConstexprSpecified);
- }
- else
- {
- func_decl = FunctionDecl::Create (*ast,
- decl_ctx,
- SourceLocation(),
- SourceLocation(),
- DeclarationName (),
- QualType::getFromOpaquePtr(function_clang_type),
- NULL,
- (FunctionDecl::StorageClass)storage,
- is_inline,
- hasWrittenPrototype,
- isConstexprSpecified);
- }
- if (func_decl)
- decl_ctx->addDecl (func_decl);
-
-#ifdef LLDB_CONFIGURATION_DEBUG
- VerifyDecl(func_decl);
-#endif
-
- return func_decl;
-}
-
-clang_type_t
-ClangASTContext::CreateFunctionType (ASTContext *ast,
- clang_type_t result_type,
- clang_type_t *args,
- unsigned num_args,
- bool is_variadic,
- unsigned type_quals)
-{
- assert (ast != NULL);
- std::vector<QualType> qual_type_args;
- for (unsigned i=0; i<num_args; ++i)
- qual_type_args.push_back (QualType::getFromOpaquePtr(args[i]));
-
- // TODO: Detect calling convention in DWARF?
- FunctionProtoType::ExtProtoInfo proto_info;
- proto_info.Variadic = is_variadic;
- proto_info.ExceptionSpecType = EST_None;
- proto_info.TypeQuals = type_quals;
- proto_info.RefQualifier = RQ_None;
- proto_info.NumExceptions = 0;
- proto_info.Exceptions = NULL;
-
- return ast->getFunctionType (QualType::getFromOpaquePtr(result_type),
- qual_type_args,
- proto_info).getAsOpaquePtr();
-}
-
-ParmVarDecl *
-ClangASTContext::CreateParameterDeclaration (const char *name, clang_type_t param_type, int storage)
-{
- ASTContext *ast = getASTContext();
- assert (ast != NULL);
- return ParmVarDecl::Create(*ast,
- ast->getTranslationUnitDecl(),
- SourceLocation(),
- SourceLocation(),
- name && name[0] ? &ast->Idents.get(name) : NULL,
- QualType::getFromOpaquePtr(param_type),
- NULL,
- (VarDecl::StorageClass)storage,
- 0);
-}
-
-void
-ClangASTContext::SetFunctionParameters (FunctionDecl *function_decl, ParmVarDecl **params, unsigned num_params)
-{
- if (function_decl)
- function_decl->setParams (ArrayRef<ParmVarDecl*>(params, num_params));
-}
-
-
-#pragma mark Array Types
-
-clang_type_t
-ClangASTContext::CreateArrayType (clang_type_t element_type,
- size_t element_count,
- bool is_vector)
-{
- if (element_type)
- {
- ASTContext *ast = getASTContext();
- assert (ast != NULL);
-
- QualType element_qual_type(QualType::getFromOpaquePtr(element_type));
-
- if (is_vector)
- {
- return ast->getExtVectorType(element_qual_type, element_count).getAsOpaquePtr();
- }
- else
- {
-
- llvm::APInt ap_element_count (64, element_count);
- if (element_count == 0)
- {
- return ast->getIncompleteArrayType(element_qual_type,
- ArrayType::Normal,
- 0).getAsOpaquePtr();
-
- }
- else
- {
- return ast->getConstantArrayType(element_qual_type,
- ap_element_count,
- ArrayType::Normal,
- 0).getAsOpaquePtr(); // ElemQuals
- }
- }
- }
- return NULL;
-}
-
-
-#pragma mark TagDecl
-
-bool
-ClangASTContext::StartTagDeclarationDefinition (clang_type_t clang_type)
-{
- if (clang_type)
- {
- QualType qual_type (QualType::getFromOpaquePtr(clang_type));
- const clang::Type *t = qual_type.getTypePtr();
- if (t)
- {
- const TagType *tag_type = dyn_cast<TagType>(t);
- if (tag_type)
- {
- TagDecl *tag_decl = tag_type->getDecl();
- if (tag_decl)
- {
- tag_decl->startDefinition();
- return true;
- }
- }
-
- const ObjCObjectType *object_type = dyn_cast<ObjCObjectType>(t);
- if (object_type)
- {
- ObjCInterfaceDecl *interface_decl = object_type->getInterface();
- if (interface_decl)
- {
- interface_decl->startDefinition();
- return true;
- }
- }
- }
- }
- return false;
-}
-
-bool
-ClangASTContext::CompleteTagDeclarationDefinition (clang_type_t clang_type)
-{
- if (clang_type)
- {
- QualType qual_type (QualType::getFromOpaquePtr(clang_type));
-
- CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
-
- if (cxx_record_decl)
- {
- cxx_record_decl->completeDefinition();
-
- return true;
- }
-
- const EnumType *enum_type = dyn_cast<EnumType>(qual_type.getTypePtr());
-
- if (enum_type)
- {
- EnumDecl *enum_decl = enum_type->getDecl();
-
- if (enum_decl)
- {
- /// TODO This really needs to be fixed.
-
- unsigned NumPositiveBits = 1;
- unsigned NumNegativeBits = 0;
-
- ASTContext *ast = getASTContext();
-
- 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 = enum_decl->getIntegerType();
-
- enum_decl->completeDefinition(enum_decl->getIntegerType(), promotion_qual_type, NumPositiveBits, NumNegativeBits);
- return true;
- }
- }
- }
- return false;
-}
-
-
-#pragma mark Enumeration Types
-
-clang_type_t
-ClangASTContext::CreateEnumerationType
-(
- const char *name,
- DeclContext *decl_ctx,
- const Declaration &decl,
- clang_type_t integer_qual_type
-)
-{
- // TODO: Do something intelligent with the Declaration object passed in
- // like maybe filling in the SourceLocation with it...
- ASTContext *ast = getASTContext();
- assert (ast != NULL);
-
- // TODO: ask about these...
-// const bool IsScoped = false;
-// const bool IsFixed = false;
-
- EnumDecl *enum_decl = EnumDecl::Create (*ast,
- decl_ctx,
- SourceLocation(),
- SourceLocation(),
- name && name[0] ? &ast->Idents.get(name) : NULL,
- NULL,
- false, // IsScoped
- false, // IsScopedUsingClassTag
- false); // IsFixed
-
-
- if (enum_decl)
- {
- // TODO: check if we should be setting the promotion type too?
- enum_decl->setIntegerType(QualType::getFromOpaquePtr (integer_qual_type));
-
- enum_decl->setAccess(AS_public); // TODO respect what's in the debug info
-
- return ast->getTagDeclType(enum_decl).getAsOpaquePtr();
- }
- return NULL;
-}
-
-clang_type_t
-ClangASTContext::GetEnumerationIntegerType (clang_type_t enum_clang_type)
-{
- QualType enum_qual_type (QualType::getFromOpaquePtr(enum_clang_type));
-
- const clang::Type *clang_type = enum_qual_type.getTypePtr();
- if (clang_type)
- {
- const EnumType *enum_type = dyn_cast<EnumType>(clang_type);
- if (enum_type)
- {
- EnumDecl *enum_decl = enum_type->getDecl();
- if (enum_decl)
- return enum_decl->getIntegerType().getAsOpaquePtr();
- }
- }
- return NULL;
-}
-bool
-ClangASTContext::AddEnumerationValueToEnumerationType
-(
- clang_type_t enum_clang_type,
- clang_type_t enumerator_clang_type,
- const Declaration &decl,
- const char *name,
- int64_t enum_value,
- uint32_t enum_value_bit_size
-)
-{
- if (enum_clang_type && enumerator_clang_type && name)
- {
- // TODO: Do something intelligent with the Declaration object passed in
- // like maybe filling in the SourceLocation with it...
- ASTContext *ast = getASTContext();
- IdentifierTable *identifier_table = getIdentifierTable();
-
- assert (ast != NULL);
- assert (identifier_table != NULL);
- QualType enum_qual_type (QualType::getFromOpaquePtr(enum_clang_type));
-
- bool is_signed = false;
- IsIntegerType (enumerator_clang_type, is_signed);
- const clang::Type *clang_type = enum_qual_type.getTypePtr();
- if (clang_type)
- {
- const EnumType *enum_type = dyn_cast<EnumType>(clang_type);
-
- if (enum_type)
- {
- llvm::APSInt enum_llvm_apsint(enum_value_bit_size, is_signed);
- enum_llvm_apsint = enum_value;
- EnumConstantDecl *enumerator_decl =
- EnumConstantDecl::Create (*ast,
- enum_type->getDecl(),
- SourceLocation(),
- name ? &identifier_table->get(name) : NULL, // Identifier
- QualType::getFromOpaquePtr(enumerator_clang_type),
- NULL,
- enum_llvm_apsint);
-
- if (enumerator_decl)
- {
- enum_type->getDecl()->addDecl(enumerator_decl);
-
-#ifdef LLDB_CONFIGURATION_DEBUG
- VerifyDecl(enumerator_decl);
-#endif
-
- return true;
- }
- }
- }
- }
- return false;
-}
-
-#pragma mark Pointers & References
-
-clang_type_t
-ClangASTContext::CreatePointerType (clang_type_t clang_type)
-{
- return CreatePointerType (getASTContext(), clang_type);
-}
-
-clang_type_t
-ClangASTContext::CreatePointerType (clang::ASTContext *ast, clang_type_t clang_type)
-{
- if (ast && clang_type)
- {
- QualType qual_type (QualType::getFromOpaquePtr(clang_type));
-
- const clang::Type::TypeClass type_class = qual_type->getTypeClass();
- switch (type_class)
- {
- case clang::Type::ObjCObject:
- case clang::Type::ObjCInterface:
- return ast->getObjCObjectPointerType(qual_type).getAsOpaquePtr();
-
- default:
- return ast->getPointerType(qual_type).getAsOpaquePtr();
- }
- }
- return NULL;
-}
-
-clang_type_t
-ClangASTContext::CreateLValueReferenceType (clang::ASTContext *ast,
- clang_type_t clang_type)
-{
- if (clang_type)
- return ast->getLValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr();
- return NULL;
-}
-
-clang_type_t
-ClangASTContext::CreateRValueReferenceType (clang::ASTContext *ast,
- clang_type_t clang_type)
-{
- if (clang_type)
- return ast->getRValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr();
- return NULL;
-}
-
-clang_type_t
-ClangASTContext::CreateMemberPointerType (clang_type_t clang_pointee_type, clang_type_t clang_class_type)
-{
- if (clang_pointee_type && clang_pointee_type)
- return getASTContext()->getMemberPointerType(QualType::getFromOpaquePtr(clang_pointee_type),
- QualType::getFromOpaquePtr(clang_class_type).getTypePtr()).getAsOpaquePtr();
- return NULL;
-}
-
-uint64_t
-ClangASTContext::GetPointerBitSize ()
-{
- ASTContext *ast = getASTContext();
- return ast->getTypeSize(ast->VoidPtrTy);
-}
-
-bool
-ClangASTContext::IsPossibleDynamicType (clang::ASTContext *ast,
- clang_type_t clang_type,
- clang_type_t *dynamic_pointee_type,
- bool check_cplusplus,
- bool check_objc)
-{
- QualType pointee_qual_type;
- if (clang_type)
- {
- QualType qual_type (QualType::getFromOpaquePtr(clang_type).getCanonicalType());
- const clang::Type::TypeClass type_class = qual_type->getTypeClass();
- bool success = false;
- switch (type_class)
- {
- case clang::Type::Builtin:
- if (check_objc && cast<clang::BuiltinType>(qual_type)->getKind() == clang::BuiltinType::ObjCId)
- {
- if (dynamic_pointee_type)
- *dynamic_pointee_type = clang_type;
- return true;
- }
- break;
-
- case clang::Type::ObjCObjectPointer:
- if (check_objc)
- {
- if (dynamic_pointee_type)
- *dynamic_pointee_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
- return true;
- }
- break;
-
- case clang::Type::Pointer:
- pointee_qual_type = cast<PointerType>(qual_type)->getPointeeType();
- success = true;
- break;
-
- case clang::Type::LValueReference:
- case clang::Type::RValueReference:
- pointee_qual_type = cast<ReferenceType>(qual_type)->getPointeeType();
- success = true;
- break;
-
- case clang::Type::Typedef:
- return ClangASTContext::IsPossibleDynamicType (ast,
- cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
- dynamic_pointee_type,
- check_cplusplus,
- check_objc);
-
- case clang::Type::Elaborated:
- return ClangASTContext::IsPossibleDynamicType (ast,
- cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(),
- dynamic_pointee_type,
- check_cplusplus,
- check_objc);
-
- case clang::Type::Paren:
- return ClangASTContext::IsPossibleDynamicType (ast,
- cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
- dynamic_pointee_type,
- check_cplusplus,
- check_objc);
- default:
- break;
- }
-
- if (success)
- {
- // Check to make sure what we are pointing too is a possible dynamic C++ type
- // We currently accept any "void *" (in case we have a class that has been
- // watered down to an opaque pointer) and virtual C++ classes.
- const clang::Type::TypeClass pointee_type_class = pointee_qual_type.getCanonicalType()->getTypeClass();
- switch (pointee_type_class)
- {
- case clang::Type::Builtin:
- switch (cast<clang::BuiltinType>(pointee_qual_type)->getKind())
- {
- case clang::BuiltinType::UnknownAny:
- case clang::BuiltinType::Void:
- if (dynamic_pointee_type)
- *dynamic_pointee_type = pointee_qual_type.getAsOpaquePtr();
- return true;
-
- case clang::BuiltinType::NullPtr:
- case clang::BuiltinType::Bool:
- case clang::BuiltinType::Char_U:
- case clang::BuiltinType::UChar:
- case clang::BuiltinType::WChar_U:
- case clang::BuiltinType::Char16:
- case clang::BuiltinType::Char32:
- case clang::BuiltinType::UShort:
- case clang::BuiltinType::UInt:
- case clang::BuiltinType::ULong:
- case clang::BuiltinType::ULongLong:
- case clang::BuiltinType::UInt128:
- case clang::BuiltinType::Char_S:
- case clang::BuiltinType::SChar:
- case clang::BuiltinType::WChar_S:
- case clang::BuiltinType::Short:
- case clang::BuiltinType::Int:
- case clang::BuiltinType::Long:
- case clang::BuiltinType::LongLong:
- case clang::BuiltinType::Int128:
- case clang::BuiltinType::Float:
- case clang::BuiltinType::Double:
- case clang::BuiltinType::LongDouble:
- case clang::BuiltinType::Dependent:
- case clang::BuiltinType::Overload:
- case clang::BuiltinType::ObjCId:
- case clang::BuiltinType::ObjCClass:
- case clang::BuiltinType::ObjCSel:
- case clang::BuiltinType::BoundMember:
- case clang::BuiltinType::Half:
- case clang::BuiltinType::ARCUnbridgedCast:
- case clang::BuiltinType::PseudoObject:
- case clang::BuiltinType::BuiltinFn:
- 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::OCLSampler:
- break;
- }
- break;
-
- case clang::Type::Record:
- if (check_cplusplus)
- {
- CXXRecordDecl *cxx_record_decl = pointee_qual_type->getAsCXXRecordDecl();
- if (cxx_record_decl)
- {
- bool is_complete = cxx_record_decl->isCompleteDefinition();
-
- if (is_complete)
- success = cxx_record_decl->isDynamicClass();
- else
- {
- ClangASTMetadata *metadata = GetMetadata (ast, cxx_record_decl);
- if (metadata)
- success = metadata->GetIsDynamicCXXType();
- else
- {
- is_complete = ClangASTContext::GetCompleteType (ast, pointee_qual_type.getAsOpaquePtr());
- if (is_complete)
- success = cxx_record_decl->isDynamicClass();
- else
- success = false;
- }
- }
-
- if (success)
- {
- if (dynamic_pointee_type)
- *dynamic_pointee_type = pointee_qual_type.getAsOpaquePtr();
- return true;
- }
- }
- }
- break;
-
- case clang::Type::ObjCObject:
- case clang::Type::ObjCInterface:
- if (check_objc)
- {
- if (dynamic_pointee_type)
- *dynamic_pointee_type = pointee_qual_type.getAsOpaquePtr();
- return true;
- }
- break;
-
- default:
- break;
- }
- }
- }
- if (dynamic_pointee_type)
- *dynamic_pointee_type = NULL;
- return false;
-}
-
-
-bool
-ClangASTContext::IsPossibleCPlusPlusDynamicType (clang::ASTContext *ast, clang_type_t clang_type, clang_type_t *dynamic_pointee_type)
-{
- return IsPossibleDynamicType (ast,
- clang_type,
- dynamic_pointee_type,
- true, // Check for dynamic C++ types
- false); // Check for dynamic ObjC types
-}
-
-bool
-ClangASTContext::IsReferenceType (clang_type_t clang_type, clang_type_t *target_type)
-{
- if (clang_type == NULL)
- return false;
-
- QualType qual_type (QualType::getFromOpaquePtr(clang_type));
- const clang::Type::TypeClass type_class = qual_type->getTypeClass();
-
- switch (type_class)
- {
- case clang::Type::LValueReference:
- if (target_type)
- *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr();
- return true;
- case clang::Type::RValueReference:
- if (target_type)
- *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr();
- return true;
- case clang::Type::Typedef:
- return ClangASTContext::IsReferenceType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
- case clang::Type::Elaborated:
- return ClangASTContext::IsReferenceType (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
- case clang::Type::Paren:
- return ClangASTContext::IsReferenceType (cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr());
-
- default:
- break;
- }
-
- return false;
-}
-
-bool
-ClangASTContext::IsPointerOrReferenceType (clang_type_t clang_type, clang_type_t*target_type)
-{
- if (clang_type == NULL)
- return false;
-
- QualType qual_type (QualType::getFromOpaquePtr(clang_type));
- const clang::Type::TypeClass type_class = qual_type->getTypeClass();
- switch (type_class)
- {
- case clang::Type::Builtin:
- switch (cast<clang::BuiltinType>(qual_type)->getKind())
- {
- default:
- break;
- case clang::BuiltinType::ObjCId:
- case clang::BuiltinType::ObjCClass:
- return true;
- }
- return false;
- case clang::Type::ObjCObjectPointer:
- if (target_type)
- *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
- return true;
- case clang::Type::BlockPointer:
- if (target_type)
- *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
- return true;
- case clang::Type::Pointer:
- if (target_type)
- *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
- return true;
- case clang::Type::MemberPointer:
- if (target_type)
- *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
- return true;
- case clang::Type::LValueReference:
- if (target_type)
- *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr();
- return true;
- case clang::Type::RValueReference:
- if (target_type)
- *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr();
- return true;
- case clang::Type::Typedef:
- return ClangASTContext::IsPointerOrReferenceType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
- case clang::Type::Elaborated:
- return ClangASTContext::IsPointerOrReferenceType (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
- case clang::Type::Paren:
- return ClangASTContext::IsPointerOrReferenceType (cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr());
- default:
- break;
- }
- return false;
-}
-
-bool
-ClangASTContext::IsIntegerType (clang_type_t clang_type, bool &is_signed)
-{
- if (!clang_type)
- return false;
-
- QualType qual_type (QualType::getFromOpaquePtr(clang_type));
- const BuiltinType *builtin_type = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal());
-
- if (builtin_type)
- {
- if (builtin_type->isInteger())
- {
- is_signed = builtin_type->isSignedInteger();
- return true;
- }
- }
-
- return false;
-}
-
-bool
-ClangASTContext::IsPointerType (clang_type_t clang_type, clang_type_t *target_type)
-{
- if (target_type)
- *target_type = NULL;
-
- if (clang_type)
- {
- QualType qual_type (QualType::getFromOpaquePtr(clang_type));
- const clang::Type::TypeClass type_class = qual_type->getTypeClass();
- switch (type_class)
- {
- case clang::Type::Builtin:
- switch (cast<clang::BuiltinType>(qual_type)->getKind())
- {
- default:
- break;
- case clang::BuiltinType::ObjCId:
- case clang::BuiltinType::ObjCClass:
- return true;
- }
- return false;
- case clang::Type::ObjCObjectPointer:
- if (target_type)
- *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
- return true;
- case clang::Type::BlockPointer:
- if (target_type)
- *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
- return true;
- case clang::Type::Pointer:
- if (target_type)
- *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
- return true;
- case clang::Type::MemberPointer:
- if (target_type)
- *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
- return true;
- case clang::Type::Typedef:
- return ClangASTContext::IsPointerType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), target_type);
- case clang::Type::Elaborated:
- return ClangASTContext::IsPointerType (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), target_type);
- case clang::Type::Paren:
- return ClangASTContext::IsPointerType (cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(), target_type);
- default:
- break;
- }
- }
- return false;
-}
-
-bool
-ClangASTContext::IsFloatingPointType (clang_type_t clang_type, uint32_t &count, bool &is_complex)
-{
- if (clang_type)
- {
- QualType qual_type (QualType::getFromOpaquePtr(clang_type));
-
- if (const BuiltinType *BT = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal()))
- {
- clang::BuiltinType::Kind kind = BT->getKind();
- if (kind >= BuiltinType::Float && kind <= BuiltinType::LongDouble)
- {
- count = 1;
- is_complex = false;
- return true;
- }
- }
- else if (const ComplexType *CT = dyn_cast<ComplexType>(qual_type->getCanonicalTypeInternal()))
- {
- if (IsFloatingPointType(CT->getElementType().getAsOpaquePtr(), count, is_complex))
- {
- count = 2;
- is_complex = true;
- return true;
- }
- }
- else if (const VectorType *VT = dyn_cast<VectorType>(qual_type->getCanonicalTypeInternal()))
- {
- if (IsFloatingPointType(VT->getElementType().getAsOpaquePtr(), count, is_complex))
- {
- count = VT->getNumElements();
- is_complex = false;
- return true;
- }
- }
- }
- return false;
-}
-
-bool
-ClangASTContext::IsScalarType (lldb::clang_type_t clang_type)
-{
- bool is_signed;
- if (ClangASTContext::IsIntegerType(clang_type, is_signed))
- return true;
-
- uint32_t count;
- bool is_complex;
- return ClangASTContext::IsFloatingPointType(clang_type, count, is_complex) && !is_complex;
-}
-
-bool
-ClangASTContext::IsPointerToScalarType (lldb::clang_type_t clang_type)
-{
- if (!IsPointerType(clang_type))
- return false;
-
- QualType qual_type (QualType::getFromOpaquePtr(clang_type));
- lldb::clang_type_t pointee_type = qual_type.getTypePtr()->getPointeeType().getAsOpaquePtr();
- return IsScalarType(pointee_type);
-}
-
-bool
-ClangASTContext::IsArrayOfScalarType (lldb::clang_type_t clang_type)
-{
- clang_type = GetAsArrayType(clang_type, NULL, NULL, NULL);
-
- if (clang_type == 0)
- return false;
-
- QualType qual_type (QualType::getFromOpaquePtr(clang_type));
- lldb::clang_type_t item_type = cast<ArrayType>(qual_type.getTypePtr())->getElementType().getAsOpaquePtr();
- return IsScalarType(item_type);
-}
-
-
-bool
-ClangASTContext::GetCXXClassName (clang_type_t clang_type, std::string &class_name)
-{
- if (clang_type)
- {
- QualType qual_type (QualType::getFromOpaquePtr(clang_type));
-
- CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
- if (cxx_record_decl)
+ if (namespace_decl)
{
- class_name.assign (cxx_record_decl->getIdentifier()->getNameStart());
- return true;
+ // If we make it here, we are creating the anonymous namespace decl
+ // for the first time, so we need to do the using directive magic
+ // like SEMA does
+ UsingDirectiveDecl* using_directive_decl = UsingDirectiveDecl::Create (*ast,
+ decl_ctx,
+ SourceLocation(),
+ SourceLocation(),
+ NestedNameSpecifierLoc(),
+ SourceLocation(),
+ namespace_decl,
+ decl_ctx);
+ using_directive_decl->setImplicit();
+ decl_ctx->addDecl(using_directive_decl);
}
}
- class_name.clear();
- return false;
+#ifdef LLDB_CONFIGURATION_DEBUG
+ VerifyDecl(namespace_decl);
+#endif
+ return namespace_decl;
}
-bool
-ClangASTContext::IsCXXClassType (clang_type_t clang_type)
-{
- if (clang_type)
- {
- QualType qual_type (QualType::getFromOpaquePtr(clang_type));
- if (qual_type->getAsCXXRecordDecl() != NULL)
- return true;
- }
- return false;
-}
+#pragma mark Function Types
-bool
-ClangASTContext::IsBeingDefined (lldb::clang_type_t clang_type)
+FunctionDecl *
+ClangASTContext::CreateFunctionDeclaration (DeclContext *decl_ctx,
+ const char *name,
+ const ClangASTType &function_clang_type,
+ int storage,
+ bool is_inline)
{
- if (clang_type)
- {
- QualType qual_type (QualType::getFromOpaquePtr(clang_type));
- const clang::TagType *tag_type = dyn_cast<clang::TagType>(qual_type);
- if (tag_type)
- return tag_type->isBeingDefined();
- }
- return false;
-}
+ FunctionDecl *func_decl = NULL;
+ ASTContext *ast = getASTContext();
+ if (decl_ctx == NULL)
+ decl_ctx = ast->getTranslationUnitDecl();
-bool
-ClangASTContext::IsObjCClassType (clang_type_t clang_type)
-{
- if (clang_type)
+
+ const bool hasWrittenPrototype = true;
+ const bool isConstexprSpecified = false;
+
+ if (name && name[0])
{
- QualType qual_type (QualType::getFromOpaquePtr(clang_type));
- if (qual_type->isObjCObjectOrInterfaceType())
- return true;
+ func_decl = FunctionDecl::Create (*ast,
+ decl_ctx,
+ SourceLocation(),
+ SourceLocation(),
+ DeclarationName (&ast->Idents.get(name)),
+ function_clang_type.GetQualType(),
+ NULL,
+ (FunctionDecl::StorageClass)storage,
+ is_inline,
+ hasWrittenPrototype,
+ isConstexprSpecified);
}
- return false;
-}
-
-bool
-ClangASTContext::IsObjCObjectPointerType (lldb::clang_type_t clang_type, clang_type_t *class_type)
-{
- if (clang_type)
+ else
{
- QualType qual_type (QualType::getFromOpaquePtr(clang_type));
- if (qual_type->isObjCObjectPointerType())
- {
- if (class_type)
- {
- *class_type = NULL;
-
- if (!qual_type->isObjCClassType() &&
- !qual_type->isObjCIdType())
- {
- const ObjCObjectPointerType *obj_pointer_type = dyn_cast<ObjCObjectPointerType>(qual_type);
- if (!obj_pointer_type)
- *class_type = NULL;
- else
- *class_type = QualType(obj_pointer_type->getInterfaceType(), 0).getAsOpaquePtr();
- }
- }
- return true;
- }
+ func_decl = FunctionDecl::Create (*ast,
+ decl_ctx,
+ SourceLocation(),
+ SourceLocation(),
+ DeclarationName (),
+ function_clang_type.GetQualType(),
+ NULL,
+ (FunctionDecl::StorageClass)storage,
+ is_inline,
+ hasWrittenPrototype,
+ isConstexprSpecified);
}
- return false;
+ if (func_decl)
+ decl_ctx->addDecl (func_decl);
+
+#ifdef LLDB_CONFIGURATION_DEBUG
+ VerifyDecl(func_decl);
+#endif
+
+ return func_decl;
}
-bool
-ClangASTContext::GetObjCClassName (lldb::clang_type_t clang_type,
- std::string &class_name)
+ClangASTType
+ClangASTContext::CreateFunctionType (ASTContext *ast,
+ const ClangASTType& result_type,
+ const ClangASTType *args,
+ unsigned num_args,
+ bool is_variadic,
+ unsigned type_quals)
{
- if (!clang_type)
- return false;
-
- const ObjCObjectType *object_type = dyn_cast<ObjCObjectType>(QualType::getFromOpaquePtr(clang_type));
- if (!object_type)
- return false;
-
- const ObjCInterfaceDecl *interface = object_type->getInterface();
- if (!interface)
- return false;
+ assert (ast != NULL);
+ std::vector<QualType> qual_type_args;
+ for (unsigned i=0; i<num_args; ++i)
+ qual_type_args.push_back (args[i].GetQualType());
+
+ // TODO: Detect calling convention in DWARF?
+ FunctionProtoType::ExtProtoInfo proto_info;
+ proto_info.Variadic = is_variadic;
+ proto_info.ExceptionSpecType = EST_None;
+ proto_info.TypeQuals = type_quals;
+ proto_info.RefQualifier = RQ_None;
+ proto_info.NumExceptions = 0;
+ proto_info.Exceptions = NULL;
- class_name = interface->getNameAsString();
- return true;
+ return ClangASTType (ast, ast->getFunctionType (result_type.GetQualType(),
+ qual_type_args,
+ proto_info).getAsOpaquePtr());
}
-bool
-ClangASTContext::IsCharType (clang_type_t clang_type)
+ParmVarDecl *
+ClangASTContext::CreateParameterDeclaration (const char *name, const ClangASTType ¶m_type, int storage)
{
- if (clang_type)
- return QualType::getFromOpaquePtr(clang_type)->isCharType();
- return false;
+ ASTContext *ast = getASTContext();
+ assert (ast != NULL);
+ return ParmVarDecl::Create(*ast,
+ ast->getTranslationUnitDecl(),
+ SourceLocation(),
+ SourceLocation(),
+ name && name[0] ? &ast->Idents.get(name) : NULL,
+ param_type.GetQualType(),
+ NULL,
+ (VarDecl::StorageClass)storage,
+ 0);
}
-bool
-ClangASTContext::IsCStringType (clang_type_t clang_type, uint32_t &length)
+void
+ClangASTContext::SetFunctionParameters (FunctionDecl *function_decl, ParmVarDecl **params, unsigned num_params)
{
- clang_type_t pointee_or_element_clang_type = NULL;
- Flags type_flags (ClangASTContext::GetTypeInfo (clang_type, NULL, &pointee_or_element_clang_type));
-
- if (pointee_or_element_clang_type == NULL)
- return false;
+ if (function_decl)
+ function_decl->setParams (ArrayRef<ParmVarDecl*>(params, num_params));
+}
+
- if (type_flags.AnySet (eTypeIsArray | eTypeIsPointer))
+#pragma mark Array Types
+
+ClangASTType
+ClangASTContext::CreateArrayType (const ClangASTType &element_type,
+ size_t element_count,
+ bool is_vector)
+{
+ if (element_type.IsValid())
{
- QualType pointee_or_element_qual_type (QualType::getFromOpaquePtr (pointee_or_element_clang_type));
-
- if (pointee_or_element_qual_type.getUnqualifiedType()->isCharType())
+ ASTContext *ast = getASTContext();
+ assert (ast != NULL);
+
+ if (is_vector)
+ {
+ return ClangASTType (ast, ast->getExtVectorType(element_type.GetQualType(), element_count).getAsOpaquePtr());
+ }
+ else
{
- QualType qual_type (QualType::getFromOpaquePtr(clang_type));
- if (type_flags.Test (eTypeIsArray))
+
+ llvm::APInt ap_element_count (64, element_count);
+ if (element_count == 0)
{
- // We know the size of the array and it could be a C string
- // since it is an array of characters
- length = cast<ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue();
- return true;
+ return ClangASTType (ast, ast->getIncompleteArrayType (element_type.GetQualType(),
+ ArrayType::Normal,
+ 0).getAsOpaquePtr());
}
else
{
- length = 0;
- return true;
+ return ClangASTType (ast, ast->getConstantArrayType (element_type.GetQualType(),
+ ap_element_count,
+ ArrayType::Normal,
+ 0).getAsOpaquePtr());
}
-
}
}
- return false;
+ return ClangASTType();
}
-bool
-ClangASTContext::IsFunctionPointerType (clang_type_t clang_type)
-{
- if (clang_type)
- {
- QualType qual_type (QualType::getFromOpaquePtr(clang_type));
-
- if (qual_type->isFunctionPointerType())
- return true;
-
- const clang::Type::TypeClass type_class = qual_type->getTypeClass();
- switch (type_class)
- {
- default:
- break;
- case clang::Type::Typedef:
- return ClangASTContext::IsFunctionPointerType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
- case clang::Type::Elaborated:
- return ClangASTContext::IsFunctionPointerType (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
- case clang::Type::Paren:
- return ClangASTContext::IsFunctionPointerType (cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr());
- case clang::Type::LValueReference:
- case clang::Type::RValueReference:
- {
- const ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
- if (reference_type)
- return ClangASTContext::IsFunctionPointerType (reference_type->getPointeeType().getAsOpaquePtr());
- }
- break;
- }
- }
- return false;
-}
-size_t
-ClangASTContext::GetArraySize (clang_type_t clang_type)
-{
- if (clang_type)
- {
- QualType qual_type(QualType::getFromOpaquePtr(clang_type));
- const clang::Type::TypeClass type_class = qual_type->getTypeClass();
- switch (type_class)
- {
- case clang::Type::ConstantArray:
- {
- const ConstantArrayType *array = cast<ConstantArrayType>(QualType::getFromOpaquePtr(clang_type).getTypePtr());
- if (array)
- return array->getSize().getLimitedValue();
- }
- break;
+#pragma mark Enumeration Types
- case clang::Type::Typedef:
- return ClangASTContext::GetArraySize(cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
-
- case clang::Type::Elaborated:
- return ClangASTContext::GetArraySize(cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
+ClangASTType
+ClangASTContext::CreateEnumerationType
+(
+ const char *name,
+ DeclContext *decl_ctx,
+ const Declaration &decl,
+ const ClangASTType &integer_clang_type
+)
+{
+ // TODO: Do something intelligent with the Declaration object passed in
+ // like maybe filling in the SourceLocation with it...
+ ASTContext *ast = getASTContext();
- case clang::Type::Paren:
- return ClangASTContext::GetArraySize(cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr());
-
- default:
- break;
- }
- }
- return 0;
-}
+ // TODO: ask about these...
+// const bool IsScoped = false;
+// const bool IsFixed = false;
-clang_type_t
-ClangASTContext::GetAsArrayType (clang_type_t clang_type, clang_type_t*member_type, uint64_t *size, bool *is_incomplete)
-{
- if (is_incomplete)
- *is_incomplete = false;
- if (!clang_type)
- return 0;
+ EnumDecl *enum_decl = EnumDecl::Create (*ast,
+ decl_ctx,
+ SourceLocation(),
+ SourceLocation(),
+ name && name[0] ? &ast->Idents.get(name) : NULL,
+ NULL,
+ false, // IsScoped
+ false, // IsScopedUsingClassTag
+ false); // IsFixed
- QualType qual_type (QualType::getFromOpaquePtr(clang_type));
- const clang::Type::TypeClass type_class = qual_type->getTypeClass();
- switch (type_class)
- {
- default:
- break;
-
- case clang::Type::ConstantArray:
- if (member_type)
- *member_type = cast<ConstantArrayType>(qual_type)->getElementType().getAsOpaquePtr();
- if (size)
- *size = cast<ConstantArrayType>(qual_type)->getSize().getLimitedValue(ULLONG_MAX);
- return clang_type;
-
- case clang::Type::IncompleteArray:
- if (member_type)
- *member_type = cast<IncompleteArrayType>(qual_type)->getElementType().getAsOpaquePtr();
- if (size)
- *size = 0;
- if (is_incomplete)
- *is_incomplete = true;
- return clang_type;
-
- case clang::Type::VariableArray:
- if (member_type)
- *member_type = cast<VariableArrayType>(qual_type)->getElementType().getAsOpaquePtr();
- if (size)
- *size = 0;
- return clang_type;
-
- case clang::Type::DependentSizedArray:
- if (member_type)
- *member_type = cast<DependentSizedArrayType>(qual_type)->getElementType().getAsOpaquePtr();
- if (size)
- *size = 0;
- return clang_type;
-
- case clang::Type::Typedef:
- return ClangASTContext::GetAsArrayType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
- member_type,
- size,
- is_incomplete);
-
- case clang::Type::Elaborated:
- return ClangASTContext::GetAsArrayType (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(),
- member_type,
- size,
- is_incomplete);
- case clang::Type::Paren:
- return ClangASTContext::GetAsArrayType (cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
- member_type,
- size,
- is_incomplete);
- }
- return 0;
-}
-
-
-#pragma mark Typedefs
-
-clang_type_t
-ClangASTContext::CreateTypedefType (const char *name, clang_type_t clang_type, DeclContext *decl_ctx)
-{
- if (clang_type)
+ if (enum_decl)
{
- QualType qual_type (QualType::getFromOpaquePtr(clang_type));
- ASTContext *ast = getASTContext();
- IdentifierTable *identifier_table = getIdentifierTable();
- assert (ast != NULL);
- assert (identifier_table != NULL);
- if (decl_ctx == NULL)
- decl_ctx = ast->getTranslationUnitDecl();
- TypedefDecl *decl = TypedefDecl::Create (*ast,
- decl_ctx,
- SourceLocation(),
- SourceLocation(),
- name ? &identifier_table->get(name) : NULL, // Identifier
- ast->getTrivialTypeSourceInfo(qual_type));
+ // TODO: check if we should be setting the promotion type too?
+ enum_decl->setIntegerType(integer_clang_type.GetQualType());
- //decl_ctx->addDecl (decl);
-
- decl->setAccess(AS_public); // TODO respect proper access specifier
-
- // Get a uniqued QualType for the typedef decl type
- return ast->getTypedefType (decl).getAsOpaquePtr();
+ enum_decl->setAccess(AS_public); // TODO respect what's in the debug info
+
+ return ClangASTType (ast, ast->getTagDeclType(enum_decl).getAsOpaquePtr());
}
- return NULL;
+ return ClangASTType();
}
// Disable this for now since I can't seem to get a nicely formatted float
@@ -6726,103 +2125,23 @@ ClangASTContext::CreateTypedefType (cons
// return false;
//}
-size_t
-ClangASTContext::ConvertStringToFloatValue (ASTContext *ast, clang_type_t clang_type, const char *s, uint8_t *dst, size_t dst_size)
-{
- if (clang_type)
- {
- QualType qual_type (QualType::getFromOpaquePtr(clang_type));
- uint32_t count = 0;
- bool is_complex = false;
- if (ClangASTContext::IsFloatingPointType (clang_type, count, is_complex))
- {
- // TODO: handle complex and vector types
- if (count != 1)
- return false;
-
- StringRef s_sref(s);
- APFloat ap_float(ast->getFloatTypeSemantics(qual_type), s_sref);
-
- const uint64_t bit_size = ast->getTypeSize (qual_type);
- 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);
- return byte_size;
- }
- }
- }
- }
- return 0;
-}
-lldb::clang_type_t
+ClangASTType
ClangASTContext::GetFloatTypeFromBitSize (clang::ASTContext *ast,
size_t bit_size)
{
if (ast)
{
if (bit_size == ast->getTypeSize(ast->FloatTy))
- return ast->FloatTy.getAsOpaquePtr();
+ return ClangASTType(ast, ast->FloatTy.getAsOpaquePtr());
else if (bit_size == ast->getTypeSize(ast->DoubleTy))
- return ast->DoubleTy.getAsOpaquePtr();
+ return ClangASTType(ast, ast->DoubleTy.getAsOpaquePtr());
else if (bit_size == ast->getTypeSize(ast->LongDoubleTy))
- return ast->LongDoubleTy.getAsOpaquePtr();
+ return ClangASTType(ast, ast->LongDoubleTy.getAsOpaquePtr());
else if (bit_size == ast->getTypeSize(ast->HalfTy))
- return ast->HalfTy.getAsOpaquePtr();
+ return ClangASTType(ast, ast->HalfTy.getAsOpaquePtr());
}
- return NULL;
-}
-
-unsigned
-ClangASTContext::GetTypeQualifiers(clang_type_t clang_type)
-{
- assert (clang_type);
-
- QualType qual_type (QualType::getFromOpaquePtr(clang_type));
-
- return qual_type.getQualifiers().getCVRQualifiers();
-}
-
-bool
-ClangASTContext::GetCompleteType (clang::ASTContext *ast, lldb::clang_type_t clang_type)
-{
- if (clang_type == NULL)
- return false;
-
- return GetCompleteQualType (ast, clang::QualType::getFromOpaquePtr(clang_type));
-}
-
-
-bool
-ClangASTContext::GetCompleteType (clang_type_t clang_type)
-{
- return ClangASTContext::GetCompleteType (getASTContext(), clang_type);
-}
-
-bool
-ClangASTContext::IsCompleteType (clang::ASTContext *ast, lldb::clang_type_t clang_type)
-{
- if (clang_type == NULL)
- return false;
-
- return GetCompleteQualType (ast, clang::QualType::getFromOpaquePtr(clang_type), false); // just check but don't let it actually complete
-}
-
-
-bool
-ClangASTContext::IsCompleteType (clang_type_t clang_type)
-{
- return ClangASTContext::IsCompleteType (getASTContext(), clang_type);
+ return ClangASTType();
}
bool
Modified: lldb/branches/lldb-platform-work/source/Symbol/ClangASTImporter.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Symbol/ClangASTImporter.cpp?rev=186540&r1=186539&r2=186540&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Symbol/ClangASTImporter.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Symbol/ClangASTImporter.cpp Wed Jul 17 17:17:41 2013
@@ -568,8 +568,8 @@ ClangASTImporter::Minion::ImportDefiniti
}
}
-clang::Decl
-*ClangASTImporter::Minion::Imported (clang::Decl *from, clang::Decl *to)
+clang::Decl *
+ClangASTImporter::Minion::Imported (clang::Decl *from, clang::Decl *to)
{
ClangASTMetrics::RegisterClangImport();
Modified: lldb/branches/lldb-platform-work/source/Symbol/ClangASTType.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Symbol/ClangASTType.cpp?rev=186540&r1=186539&r2=186540&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Symbol/ClangASTType.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Symbol/ClangASTType.cpp Wed Jul 17 17:17:41 2013
@@ -13,10 +13,13 @@
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/ASTContext.h"
+#include "clang/AST/Attr.h"
+#include "clang/AST/CXXInheritance.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclGroup.h"
+#include "clang/AST/DeclTemplate.h"
#include "clang/AST/RecordLayout.h"
#include "clang/AST/Type.h"
@@ -36,9 +39,9 @@
#include "lldb/Core/Scalar.h"
#include "lldb/Core/Stream.h"
#include "lldb/Core/StreamString.h"
-#include "lldb/Core/UniqueCStringMap.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/ClangExternalASTSourceCommon.h"
+#include "lldb/Symbol/VerifyDecl.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Process.h"
@@ -46,233 +49,1325 @@
using namespace lldb;
using namespace lldb_private;
+using namespace clang;
+using namespace llvm;
-
-ClangASTType::~ClangASTType()
+static bool
+GetCompleteQualType (ASTContext *ast, QualType qual_type, bool allow_completion = true)
{
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class)
+ {
+ case clang::Type::ConstantArray:
+ case clang::Type::IncompleteArray:
+ case clang::Type::VariableArray:
+ {
+ const ArrayType *array_type = dyn_cast<ArrayType>(qual_type.getTypePtr());
+
+ if (array_type)
+ return GetCompleteQualType (ast, array_type->getElementType(), allow_completion);
+ }
+ break;
+
+ case clang::Type::Record:
+ case clang::Type::Enum:
+ {
+ const TagType *tag_type = dyn_cast<TagType>(qual_type.getTypePtr());
+ if (tag_type)
+ {
+ TagDecl *tag_decl = tag_type->getDecl();
+ if (tag_decl)
+ {
+ if (tag_decl->isCompleteDefinition())
+ return true;
+
+ if (!allow_completion)
+ return false;
+
+ if (tag_decl->hasExternalLexicalStorage())
+ {
+ if (ast)
+ {
+ ExternalASTSource *external_ast_source = ast->getExternalSource();
+ if (external_ast_source)
+ {
+ external_ast_source->CompleteType(tag_decl);
+ return !tag_type->isIncompleteType();
+ }
+ }
+ }
+ return false;
+ }
+ }
+
+ }
+ break;
+
+ case clang::Type::ObjCObject:
+ case clang::Type::ObjCInterface:
+ {
+ const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type);
+ if (objc_class_type)
+ {
+ 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 (class_interface_decl->getDefinition())
+ return true;
+
+ if (!allow_completion)
+ return false;
+
+ if (class_interface_decl->hasExternalLexicalStorage())
+ {
+ if (ast)
+ {
+ ExternalASTSource *external_ast_source = ast->getExternalSource();
+ if (external_ast_source)
+ {
+ external_ast_source->CompleteType (class_interface_decl);
+ return !objc_class_type->isIncompleteType();
+ }
+ }
+ }
+ return false;
+ }
+ }
+ }
+ break;
+
+ case clang::Type::Typedef:
+ return GetCompleteQualType (ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType(), allow_completion);
+
+ case clang::Type::Elaborated:
+ return GetCompleteQualType (ast, cast<ElaboratedType>(qual_type)->getNamedType(), allow_completion);
+
+ case clang::Type::Paren:
+ return GetCompleteQualType (ast, cast<ParenType>(qual_type)->desugar(), allow_completion);
+
+ default:
+ break;
+ }
+
+ return true;
}
-std::string
-ClangASTType::GetTypeNameForQualType (clang::ASTContext *ast, clang::QualType qual_type)
+static ObjCIvarDecl::AccessControl
+ConvertAccessTypeToObjCIvarAccessControl (AccessType access)
{
- std::string type_name;
-
- clang::PrintingPolicy printing_policy (ast->getPrintingPolicy());
- printing_policy.SuppressTagKeyword = true;
- printing_policy.LangOpts.WChar = true;
- const clang::TypedefType *typedef_type = qual_type->getAs<clang::TypedefType>();
- if (typedef_type)
- {
- const clang::TypedefNameDecl *typedef_decl = typedef_type->getDecl();
- type_name = typedef_decl->getQualifiedNameAsString(printing_policy);
- }
- else
+ switch (access)
{
- type_name = qual_type.getAsString(printing_policy);
+ case eAccessNone: return ObjCIvarDecl::None;
+ case eAccessPublic: return ObjCIvarDecl::Public;
+ case eAccessPrivate: return ObjCIvarDecl::Private;
+ case eAccessProtected: return ObjCIvarDecl::Protected;
+ case eAccessPackage: return ObjCIvarDecl::Package;
}
- return type_name;
+ return ObjCIvarDecl::None;
}
-std::string
-ClangASTType::GetTypeNameForOpaqueQualType (clang::ASTContext *ast, clang_type_t opaque_qual_type)
-{
- return GetTypeNameForQualType (ast, clang::QualType::getFromOpaquePtr(opaque_qual_type));
-}
+//----------------------------------------------------------------------
+// Tests
+//----------------------------------------------------------------------
-ClangASTType
-ClangASTType::GetCanonicalType (clang::ASTContext *ast, lldb::clang_type_t opaque_qual_type)
+ClangASTType::ClangASTType (clang::ASTContext *ast,
+ clang::QualType qual_type) :
+ m_type (qual_type.getAsOpaquePtr()),
+ m_ast (ast)
{
- if (ast && opaque_qual_type)
- return ClangASTType (ast,
- clang::QualType::getFromOpaquePtr(opaque_qual_type).getCanonicalType().getAsOpaquePtr());
- return ClangASTType();
}
-ConstString
-ClangASTType::GetConstTypeName ()
+ClangASTType::~ClangASTType()
{
- // TODO: verify if we actually need to complete a type just to get its type name????
- if (!ClangASTContext::GetCompleteType (this->m_ast, this->m_type))
- return ConstString("<invalid>");
- return GetConstTypeName (m_ast, m_type);
}
-ConstString
-ClangASTType::GetConstQualifiedTypeName ()
+//----------------------------------------------------------------------
+// Tests
+//----------------------------------------------------------------------
+
+bool
+ClangASTType::IsAggregateType () const
{
- // TODO: verify if we actually need to complete a type just to get its fully qualified type name????
- if (!ClangASTContext::GetCompleteType (this->m_ast, this->m_type))
- return ConstString("<invalid>");
- return GetConstQualifiedTypeName (m_ast, m_type);
+ if (!IsValid())
+ return false;
+
+ QualType qual_type (GetCanonicalQualType());
+
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class)
+ {
+ case clang::Type::IncompleteArray:
+ case clang::Type::VariableArray:
+ case clang::Type::ConstantArray:
+ case clang::Type::ExtVector:
+ case clang::Type::Vector:
+ case clang::Type::Record:
+ case clang::Type::ObjCObject:
+ case clang::Type::ObjCInterface:
+ return true;
+ case clang::Type::Elaborated:
+ return ClangASTType(m_ast, cast<ElaboratedType>(qual_type)->getNamedType()).IsAggregateType();
+ case clang::Type::Typedef:
+ return ClangASTType(m_ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()).IsAggregateType();
+ case clang::Type::Paren:
+ return ClangASTType(m_ast, cast<ParenType>(qual_type)->desugar()).IsAggregateType();
+ default:
+ break;
+ }
+ // The clang type does have a value
+ return false;
}
-ConstString
-ClangASTType::GetConstQualifiedTypeName (clang::ASTContext *ast, clang_type_t clang_type)
+bool
+ClangASTType::IsArrayType (ClangASTType *element_type_ptr,
+ uint64_t *size,
+ bool *is_incomplete) const
{
- if (ast == NULL || clang_type == NULL)
- return ConstString("<invalid>");
-
- return ConstString (GetTypeNameForQualType (ast, clang::QualType::getFromOpaquePtr(clang_type)).c_str());
+ if (IsValid())
+ {
+ QualType qual_type (GetCanonicalQualType());
+
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class)
+ {
+ default:
+ break;
+
+ case clang::Type::ConstantArray:
+ if (element_type_ptr)
+ element_type_ptr->SetClangType (m_ast, cast<ConstantArrayType>(qual_type)->getElementType());
+ if (size)
+ *size = cast<ConstantArrayType>(qual_type)->getSize().getLimitedValue(ULLONG_MAX);
+ return true;
+
+ case clang::Type::IncompleteArray:
+ if (element_type_ptr)
+ element_type_ptr->SetClangType (m_ast, cast<IncompleteArrayType>(qual_type)->getElementType());
+ if (size)
+ *size = 0;
+ if (is_incomplete)
+ *is_incomplete = true;
+ return true;
+
+ case clang::Type::VariableArray:
+ if (element_type_ptr)
+ element_type_ptr->SetClangType (m_ast, cast<VariableArrayType>(qual_type)->getElementType());
+ if (size)
+ *size = 0;
+ return true;
+
+ case clang::Type::DependentSizedArray:
+ if (element_type_ptr)
+ element_type_ptr->SetClangType (m_ast, cast<DependentSizedArrayType>(qual_type)->getElementType());
+ if (size)
+ *size = 0;
+ return true;
+
+ case clang::Type::Typedef:
+ return ClangASTType (m_ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()).IsArrayType (element_type_ptr,
+ size,
+ is_incomplete);
+ case clang::Type::Elaborated:
+ return ClangASTType (m_ast, cast<ElaboratedType>(qual_type)->getNamedType()).IsArrayType (element_type_ptr,
+ size,
+ is_incomplete);
+ case clang::Type::Paren:
+ return ClangASTType (m_ast, cast<clang::ParenType>(qual_type)->desugar()).IsArrayType (element_type_ptr,
+ size,
+ is_incomplete);
+ }
+ }
+ if (element_type_ptr)
+ element_type_ptr->Clear();
+ if (size)
+ *size = 0;
+ if (is_incomplete)
+ *is_incomplete = false;
+ return 0;
}
-ConstString
-ClangASTType::GetConstTypeName (clang::ASTContext *ast, clang_type_t clang_type)
+bool
+ClangASTType::IsCharType () const
{
- if (!clang_type)
- return ConstString("<invalid>");
-
- std::string type_name (GetTypeNameForOpaqueQualType(ast, clang_type));
- ConstString const_type_name;
- if (type_name.empty())
- const_type_name.SetCString ("<invalid>");
- else
- const_type_name.SetCString(type_name.c_str());
- return const_type_name;
+ if (!IsValid())
+ return false;
+ return GetQualType().getUnqualifiedType()->isCharType();
}
-clang_type_t
-ClangASTType::GetPointeeType () const
+
+bool
+ClangASTType::IsCompleteType () const
{
- return GetPointeeType (m_type);
+ if (!IsValid())
+ return false;
+ const bool allow_completion = false;
+ return GetCompleteQualType (m_ast, GetQualType(), allow_completion);
}
-clang_type_t
-ClangASTType::GetPointeeType (clang_type_t clang_type)
+bool
+ClangASTType::IsConst() const
{
- if (clang_type)
- {
- clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type));
-
- return qual_type.getTypePtr()->getPointeeType().getAsOpaquePtr();
- }
- return NULL;
+ return GetQualType().isConstQualified();
}
-lldb::clang_type_t
-ClangASTType::GetArrayElementType (uint64_t& stride)
+bool
+ClangASTType::IsCStringType (uint32_t &length) const
{
- return GetArrayElementType(m_ast, m_type, stride);
+ ClangASTType pointee_or_element_clang_type;
+ length = 0;
+ Flags type_flags (GetTypeInfo (&pointee_or_element_clang_type));
+
+ if (!pointee_or_element_clang_type.IsValid())
+ return false;
+
+ if (type_flags.AnySet (eTypeIsArray | eTypeIsPointer))
+ {
+ if (pointee_or_element_clang_type.IsCharType())
+ {
+ if (type_flags.Test (eTypeIsArray))
+ {
+ // We know the size of the array and it could be a C string
+ // since it is an array of characters
+ length = cast<ConstantArrayType>(GetCanonicalQualType().getTypePtr())->getSize().getLimitedValue();
+ }
+ return true;
+
+ }
+ }
+ return false;
}
-lldb::clang_type_t
-ClangASTType::GetArrayElementType (clang::ASTContext* ast,
- lldb::clang_type_t opaque_clang_qual_type,
- uint64_t& stride)
+bool
+ClangASTType::IsFunctionType (bool *is_variadic_ptr) const
{
- if (opaque_clang_qual_type)
+ if (IsValid())
{
- clang::QualType qual_type(clang::QualType::getFromOpaquePtr(opaque_clang_qual_type));
+ QualType qual_type (GetCanonicalQualType());
- lldb::clang_type_t ret_type = qual_type.getTypePtr()->getArrayElementTypeNoTypeQual()->getCanonicalTypeUnqualified().getAsOpaquePtr();
-
- // TODO: the real stride will be >= this value.. find the real one!
- stride = GetTypeByteSize(ast, ret_type);
-
- return ret_type;
+ if (qual_type->isFunctionType())
+ {
+ if (is_variadic_ptr)
+ {
+ const clang::FunctionProtoType *function_proto_type = llvm::dyn_cast<clang::FunctionProtoType>(qual_type.getTypePtr());
+ if (function_proto_type)
+ *is_variadic_ptr = function_proto_type->isVariadic();
+ else
+ *is_variadic_ptr = false;
+ }
+ return true;
+ }
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class)
+ {
+ default:
+ break;
+ case clang::Type::Typedef:
+ return ClangASTType (m_ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()).IsFunctionType();
+ case clang::Type::Elaborated:
+ return ClangASTType (m_ast, cast<ElaboratedType>(qual_type)->getNamedType()).IsFunctionType();
+ case clang::Type::Paren:
+ return ClangASTType (m_ast, cast<clang::ParenType>(qual_type)->desugar()).IsFunctionType();
+
+ case clang::Type::LValueReference:
+ case clang::Type::RValueReference:
+ {
+ const ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
+ if (reference_type)
+ return ClangASTType (m_ast, reference_type->getPointeeType()).IsFunctionType();
+ }
+ break;
+ }
}
- return NULL;
-
+ return false;
}
-lldb::clang_type_t
-ClangASTType::GetPointerType () const
-{
- return GetPointerType (m_ast, m_type);
-}
-lldb::clang_type_t
-ClangASTType::GetPointerType (clang::ASTContext *ast_context,
- lldb::clang_type_t opaque_clang_qual_type)
+bool
+ClangASTType::IsFunctionPointerType () const
{
- if (opaque_clang_qual_type)
+ if (IsValid())
{
- clang::QualType qual_type(clang::QualType::getFromOpaquePtr(opaque_clang_qual_type));
+ QualType qual_type (GetCanonicalQualType());
+
+ if (qual_type->isFunctionPointerType())
+ return true;
- return ast_context->getPointerType(qual_type).getAsOpaquePtr();
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class)
+ {
+ default:
+ break;
+ case clang::Type::Typedef:
+ return ClangASTType (m_ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()).IsFunctionPointerType();
+ case clang::Type::Elaborated:
+ return ClangASTType (m_ast, cast<ElaboratedType>(qual_type)->getNamedType()).IsFunctionPointerType();
+ case clang::Type::Paren:
+ return ClangASTType (m_ast, cast<clang::ParenType>(qual_type)->desugar()).IsFunctionPointerType();
+
+ case clang::Type::LValueReference:
+ case clang::Type::RValueReference:
+ {
+ const ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
+ if (reference_type)
+ return ClangASTType (m_ast, reference_type->getPointeeType()).IsFunctionPointerType();
+ }
+ break;
+ }
}
- return NULL;
-}
-
-ClangASTType
-ClangASTType::GetFullyUnqualifiedType ()
-{
- return GetFullyUnqualifiedType(m_ast, m_type);
-}
+ return false;
-static clang::QualType GetFullyUnqualifiedType_Impl (clang::QualType Ty,
- clang::ASTContext * ctx)
-{
- if (Ty->isPointerType())
- Ty = ctx->getPointerType(GetFullyUnqualifiedType_Impl(Ty->getPointeeType(),ctx));
- else
- Ty = Ty.getUnqualifiedType();
- Ty.removeLocalConst();
- Ty.removeLocalRestrict();
- Ty.removeLocalVolatile();
- return Ty;
}
-ClangASTType
-ClangASTType::GetFullyUnqualifiedType (clang::ASTContext *ast_context, lldb::clang_type_t clang_type)
+bool
+ClangASTType::IsIntegerType (bool &is_signed) const
{
- return ClangASTType(ast_context,GetFullyUnqualifiedType_Impl(clang::QualType::getFromOpaquePtr(clang_type),ast_context).getAsOpaquePtr());
+ if (!IsValid())
+ return false;
+
+ QualType qual_type (GetCanonicalQualType());
+ const BuiltinType *builtin_type = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal());
+
+ if (builtin_type)
+ {
+ if (builtin_type->isInteger())
+ {
+ is_signed = builtin_type->isSignedInteger();
+ return true;
+ }
+ }
+
+ return false;
}
-lldb::Encoding
-ClangASTType::GetEncoding (uint64_t &count)
+bool
+ClangASTType::IsPointerType (ClangASTType *pointee_type) const
{
- return GetEncoding(m_type, count);
+ if (IsValid())
+ {
+ QualType qual_type (GetCanonicalQualType());
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class)
+ {
+ case clang::Type::Builtin:
+ switch (cast<clang::BuiltinType>(qual_type)->getKind())
+ {
+ default:
+ break;
+ case clang::BuiltinType::ObjCId:
+ case clang::BuiltinType::ObjCClass:
+ return true;
+ }
+ return false;
+ case clang::Type::ObjCObjectPointer:
+ if (pointee_type)
+ pointee_type->SetClangType (m_ast, cast<ObjCObjectPointerType>(qual_type)->getPointeeType());
+ return true;
+ case clang::Type::BlockPointer:
+ if (pointee_type)
+ pointee_type->SetClangType (m_ast, cast<BlockPointerType>(qual_type)->getPointeeType());
+ return true;
+ case clang::Type::Pointer:
+ if (pointee_type)
+ pointee_type->SetClangType (m_ast, cast<PointerType>(qual_type)->getPointeeType());
+ return true;
+ case clang::Type::MemberPointer:
+ if (pointee_type)
+ pointee_type->SetClangType (m_ast, cast<MemberPointerType>(qual_type)->getPointeeType());
+ return true;
+ case clang::Type::Typedef:
+ return ClangASTType (m_ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()).IsPointerType(pointee_type);
+ case clang::Type::Elaborated:
+ return ClangASTType (m_ast, cast<ElaboratedType>(qual_type)->getNamedType()).IsPointerType(pointee_type);
+ case clang::Type::Paren:
+ return ClangASTType (m_ast, cast<clang::ParenType>(qual_type)->desugar()).IsPointerType(pointee_type);
+ default:
+ break;
+ }
+ }
+ if (pointee_type)
+ pointee_type->Clear();
+ return false;
}
-lldb::LanguageType
-ClangASTType::GetMinimumLanguage ()
-{
- return ClangASTType::GetMinimumLanguage (m_ast,
- m_type);
-}
-
bool
-ClangASTType::IsPolymorphicClass (clang::ASTContext *ast_context, lldb::clang_type_t clang_type)
+ClangASTType::IsPointerOrReferenceType (ClangASTType *pointee_type) const
{
- if (clang_type)
+ if (IsValid())
{
- clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type).getCanonicalType());
+ QualType qual_type (GetCanonicalQualType());
const clang::Type::TypeClass type_class = qual_type->getTypeClass();
switch (type_class)
{
- case clang::Type::Record:
- if (ClangASTContext::GetCompleteType (ast_context, clang_type))
- {
- const clang::RecordType *record_type = llvm::cast<clang::RecordType>(qual_type.getTypePtr());
- const clang::RecordDecl *record_decl = record_type->getDecl();
- if (record_decl)
- {
- const clang::CXXRecordDecl *cxx_record_decl = llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
- if (cxx_record_decl)
- return cxx_record_decl->isPolymorphic();
- }
- }
- break;
-
+ case clang::Type::Builtin:
+ switch (cast<clang::BuiltinType>(qual_type)->getKind())
+ {
+ default:
+ break;
+ case clang::BuiltinType::ObjCId:
+ case clang::BuiltinType::ObjCClass:
+ return true;
+ }
+ return false;
+ case clang::Type::ObjCObjectPointer:
+ if (pointee_type)
+ pointee_type->SetClangType(m_ast, cast<ObjCObjectPointerType>(qual_type)->getPointeeType());
+ return true;
+ case clang::Type::BlockPointer:
+ if (pointee_type)
+ pointee_type->SetClangType(m_ast, cast<BlockPointerType>(qual_type)->getPointeeType());
+ return true;
+ case clang::Type::Pointer:
+ if (pointee_type)
+ pointee_type->SetClangType(m_ast, cast<PointerType>(qual_type)->getPointeeType());
+ return true;
+ case clang::Type::MemberPointer:
+ if (pointee_type)
+ pointee_type->SetClangType(m_ast, cast<MemberPointerType>(qual_type)->getPointeeType());
+ return true;
+ case clang::Type::LValueReference:
+ if (pointee_type)
+ pointee_type->SetClangType(m_ast, cast<LValueReferenceType>(qual_type)->desugar());
+ return true;
+ case clang::Type::RValueReference:
+ if (pointee_type)
+ pointee_type->SetClangType(m_ast, cast<LValueReferenceType>(qual_type)->desugar());
+ return true;
+ case clang::Type::Typedef:
+ return ClangASTType (m_ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()).IsPointerOrReferenceType(pointee_type);
+ case clang::Type::Elaborated:
+ return ClangASTType (m_ast, cast<ElaboratedType>(qual_type)->getNamedType()).IsPointerOrReferenceType(pointee_type);
+ case clang::Type::Paren:
+ return ClangASTType (m_ast, cast<clang::ParenType>(qual_type)->desugar()).IsPointerOrReferenceType(pointee_type);
default:
break;
}
}
+ if (pointee_type)
+ pointee_type->Clear();
return false;
}
-lldb::TypeClass
-ClangASTType::GetTypeClass (clang::ASTContext *ast_context, lldb::clang_type_t clang_type)
-{
- if (clang_type == NULL)
- return lldb::eTypeClassInvalid;
- clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type));
-
- switch (qual_type->getTypeClass())
+bool
+ClangASTType::IsReferenceType (ClangASTType *pointee_type) const
+{
+ if (IsValid())
+ {
+ QualType qual_type (GetCanonicalQualType());
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+
+ switch (type_class)
+ {
+ case clang::Type::LValueReference:
+ if (pointee_type)
+ pointee_type->SetClangType(m_ast, cast<LValueReferenceType>(qual_type)->desugar());
+ return true;
+ case clang::Type::RValueReference:
+ if (pointee_type)
+ pointee_type->SetClangType(m_ast, cast<LValueReferenceType>(qual_type)->desugar());
+ return true;
+ case clang::Type::Typedef:
+ return ClangASTType(m_ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()).IsReferenceType(pointee_type);
+ case clang::Type::Elaborated:
+ return ClangASTType(m_ast, cast<ElaboratedType>(qual_type)->getNamedType()).IsReferenceType(pointee_type);
+ case clang::Type::Paren:
+ return ClangASTType(m_ast, cast<clang::ParenType>(qual_type)->desugar()).IsReferenceType(pointee_type);
+
+ default:
+ break;
+ }
+ }
+ if (pointee_type)
+ pointee_type->Clear();
+ return false;
+}
+
+bool
+ClangASTType::IsFloatingPointType (uint32_t &count, bool &is_complex) const
+{
+ if (IsValid())
+ {
+ QualType qual_type (GetCanonicalQualType());
+
+ if (const BuiltinType *BT = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal()))
+ {
+ clang::BuiltinType::Kind kind = BT->getKind();
+ if (kind >= BuiltinType::Float && kind <= BuiltinType::LongDouble)
+ {
+ count = 1;
+ is_complex = false;
+ return true;
+ }
+ }
+ else if (const ComplexType *CT = dyn_cast<ComplexType>(qual_type->getCanonicalTypeInternal()))
+ {
+ if (ClangASTType (m_ast, CT->getElementType()).IsFloatingPointType (count, is_complex))
+ {
+ count = 2;
+ is_complex = true;
+ return true;
+ }
+ }
+ else if (const VectorType *VT = dyn_cast<VectorType>(qual_type->getCanonicalTypeInternal()))
+ {
+ if (ClangASTType (m_ast, VT->getElementType()).IsFloatingPointType (count, is_complex))
+ {
+ count = VT->getNumElements();
+ is_complex = false;
+ return true;
+ }
+ }
+ }
+ count = 0;
+ is_complex = false;
+ return false;
+}
+
+
+bool
+ClangASTType::IsDefined() const
+{
+ if (!IsValid())
+ return false;
+
+ QualType qual_type(GetQualType());
+ const TagType *tag_type = dyn_cast<TagType>(qual_type.getTypePtr());
+ if (tag_type)
+ {
+ TagDecl *tag_decl = tag_type->getDecl();
+ if (tag_decl)
+ return tag_decl->isCompleteDefinition();
+ return false;
+ }
+ else
+ {
+ const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type);
+ if (objc_class_type)
+ {
+ ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
+ if (class_interface_decl)
+ return class_interface_decl->getDefinition() != NULL;
+ return false;
+ }
+ }
+ return true;
+}
+
+bool
+ClangASTType::IsObjCClassType () const
+{
+ if (IsValid())
+ {
+ QualType qual_type (GetCanonicalQualType());
+
+ const ObjCObjectPointerType *obj_pointer_type = dyn_cast<ObjCObjectPointerType>(qual_type);
+
+ if (obj_pointer_type)
+ return obj_pointer_type->isObjCClassType();
+ }
+ return false;
+}
+
+bool
+ClangASTType::IsObjCObjectOrInterfaceType () const
+{
+ if (IsValid())
+ return GetCanonicalQualType()->isObjCObjectOrInterfaceType();
+ return false;
+}
+
+bool
+ClangASTType::IsPolymorphicClass () const
+{
+ if (IsValid())
+ {
+ QualType qual_type(GetCanonicalQualType());
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class)
+ {
+ case clang::Type::Record:
+ if (GetCompleteType())
+ {
+ const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
+ const RecordDecl *record_decl = record_type->getDecl();
+ if (record_decl)
+ {
+ const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
+ if (cxx_record_decl)
+ return cxx_record_decl->isPolymorphic();
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ return false;
+}
+
+bool
+ClangASTType::IsPossibleDynamicType (ClangASTType *dynamic_pointee_type,
+ bool check_cplusplus,
+ bool check_objc) const
+{
+ QualType pointee_qual_type;
+ if (m_type)
+ {
+ QualType qual_type (GetCanonicalQualType());
+ bool success = false;
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class)
+ {
+ case clang::Type::Builtin:
+ if (check_objc && cast<BuiltinType>(qual_type)->getKind() == BuiltinType::ObjCId)
+ {
+ if (dynamic_pointee_type)
+ dynamic_pointee_type->SetClangType(m_ast, m_type);
+ return true;
+ }
+ break;
+
+ case clang::Type::ObjCObjectPointer:
+ if (check_objc)
+ {
+ if (dynamic_pointee_type)
+ dynamic_pointee_type->SetClangType(m_ast, cast<ObjCObjectPointerType>(qual_type)->getPointeeType());
+ return true;
+ }
+ break;
+
+ case clang::Type::Pointer:
+ pointee_qual_type = cast<PointerType>(qual_type)->getPointeeType();
+ success = true;
+ break;
+
+ case clang::Type::LValueReference:
+ case clang::Type::RValueReference:
+ pointee_qual_type = cast<ReferenceType>(qual_type)->getPointeeType();
+ success = true;
+ break;
+
+ case clang::Type::Typedef:
+ return ClangASTType (m_ast,
+ cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()).IsPossibleDynamicType (dynamic_pointee_type,
+ check_cplusplus,
+ check_objc);
+
+ case clang::Type::Elaborated:
+ return ClangASTType (m_ast,
+ cast<ElaboratedType>(qual_type)->getNamedType()).IsPossibleDynamicType (dynamic_pointee_type,
+ check_cplusplus,
+ check_objc);
+
+ case clang::Type::Paren:
+ return ClangASTType (m_ast,
+ cast<ParenType>(qual_type)->desugar()).IsPossibleDynamicType (dynamic_pointee_type,
+ check_cplusplus,
+ check_objc);
+ default:
+ break;
+ }
+
+ if (success)
+ {
+ // Check to make sure what we are pointing too is a possible dynamic C++ type
+ // We currently accept any "void *" (in case we have a class that has been
+ // watered down to an opaque pointer) and virtual C++ classes.
+ const clang::Type::TypeClass pointee_type_class = pointee_qual_type.getCanonicalType()->getTypeClass();
+ switch (pointee_type_class)
+ {
+ case clang::Type::Builtin:
+ switch (cast<BuiltinType>(pointee_qual_type)->getKind())
+ {
+ case BuiltinType::UnknownAny:
+ case BuiltinType::Void:
+ if (dynamic_pointee_type)
+ dynamic_pointee_type->SetClangType(m_ast, pointee_qual_type);
+ return true;
+
+ case BuiltinType::NullPtr:
+ case BuiltinType::Bool:
+ case BuiltinType::Char_U:
+ case BuiltinType::UChar:
+ case BuiltinType::WChar_U:
+ case BuiltinType::Char16:
+ case BuiltinType::Char32:
+ case BuiltinType::UShort:
+ case BuiltinType::UInt:
+ case BuiltinType::ULong:
+ case BuiltinType::ULongLong:
+ case BuiltinType::UInt128:
+ case BuiltinType::Char_S:
+ case BuiltinType::SChar:
+ case BuiltinType::WChar_S:
+ case BuiltinType::Short:
+ case BuiltinType::Int:
+ case BuiltinType::Long:
+ case BuiltinType::LongLong:
+ case BuiltinType::Int128:
+ case BuiltinType::Float:
+ case BuiltinType::Double:
+ case BuiltinType::LongDouble:
+ case BuiltinType::Dependent:
+ case BuiltinType::Overload:
+ case BuiltinType::ObjCId:
+ case BuiltinType::ObjCClass:
+ case BuiltinType::ObjCSel:
+ case BuiltinType::BoundMember:
+ case BuiltinType::Half:
+ case BuiltinType::ARCUnbridgedCast:
+ case BuiltinType::PseudoObject:
+ case BuiltinType::BuiltinFn:
+ case BuiltinType::OCLEvent:
+ case BuiltinType::OCLImage1d:
+ case BuiltinType::OCLImage1dArray:
+ case BuiltinType::OCLImage1dBuffer:
+ case BuiltinType::OCLImage2d:
+ case BuiltinType::OCLImage2dArray:
+ case BuiltinType::OCLImage3d:
+ case BuiltinType::OCLSampler:
+ break;
+ }
+ break;
+
+ case clang::Type::Record:
+ if (check_cplusplus)
+ {
+ CXXRecordDecl *cxx_record_decl = pointee_qual_type->getAsCXXRecordDecl();
+ if (cxx_record_decl)
+ {
+ bool is_complete = cxx_record_decl->isCompleteDefinition();
+
+ if (is_complete)
+ success = cxx_record_decl->isDynamicClass();
+ else
+ {
+ ClangASTMetadata *metadata = ClangASTContext::GetMetadata (m_ast, cxx_record_decl);
+ if (metadata)
+ success = metadata->GetIsDynamicCXXType();
+ else
+ {
+ is_complete = ClangASTType(m_ast, pointee_qual_type).GetCompleteType();
+ if (is_complete)
+ success = cxx_record_decl->isDynamicClass();
+ else
+ success = false;
+ }
+ }
+
+ if (success)
+ {
+ if (dynamic_pointee_type)
+ dynamic_pointee_type->SetClangType(m_ast, pointee_qual_type);
+ return true;
+ }
+ }
+ }
+ break;
+
+ case clang::Type::ObjCObject:
+ case clang::Type::ObjCInterface:
+ if (check_objc)
+ {
+ if (dynamic_pointee_type)
+ dynamic_pointee_type->SetClangType(m_ast, pointee_qual_type);
+ return true;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+ if (dynamic_pointee_type)
+ dynamic_pointee_type->Clear();
+ return false;
+}
+
+
+bool
+ClangASTType::IsScalarType () const
+{
+ if (!IsValid())
+ return false;
+
+ return (GetTypeInfo (NULL) & eTypeIsScalar) != 0;
+}
+
+bool
+ClangASTType::IsTypedefType () const
+{
+ if (!IsValid())
+ return false;
+ return GetQualType()->getTypeClass() == clang::Type::Typedef;
+}
+
+bool
+ClangASTType::IsVoidType () const
+{
+ if (!IsValid())
+ return false;
+ return GetCanonicalQualType()->isVoidType();
+}
+
+bool
+ClangASTType::IsPointerToScalarType () const
+{
+ if (!IsValid())
+ return false;
+
+ return IsPointerType() && GetPointeeType().IsScalarType();
+}
+
+bool
+ClangASTType::IsArrayOfScalarType () const
+{
+ ClangASTType element_type;
+ if (IsArrayType(&element_type, NULL, NULL))
+ return element_type.IsScalarType();
+ return false;
+}
+
+
+bool
+ClangASTType::GetCXXClassName (std::string &class_name) const
+{
+ if (IsValid())
+ {
+ QualType qual_type (GetCanonicalQualType());
+
+ CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
+ if (cxx_record_decl)
+ {
+ class_name.assign (cxx_record_decl->getIdentifier()->getNameStart());
+ return true;
+ }
+ }
+ class_name.clear();
+ return false;
+}
+
+
+bool
+ClangASTType::IsCXXClassType () const
+{
+ if (!IsValid())
+ return false;
+
+ QualType qual_type (GetCanonicalQualType());
+ if (qual_type->getAsCXXRecordDecl() != NULL)
+ return true;
+ return false;
+}
+
+bool
+ClangASTType::IsBeingDefined () const
+{
+ if (!IsValid())
+ return false;
+ QualType qual_type (GetCanonicalQualType());
+ const clang::TagType *tag_type = dyn_cast<clang::TagType>(qual_type);
+ if (tag_type)
+ return tag_type->isBeingDefined();
+ return false;
+}
+
+bool
+ClangASTType::IsObjCObjectPointerType (ClangASTType *class_type_ptr)
+{
+ if (!IsValid())
+ return false;
+
+ QualType qual_type (GetCanonicalQualType());
+
+ if (qual_type->isObjCObjectPointerType())
+ {
+ if (class_type_ptr)
+ {
+ if (!qual_type->isObjCClassType() &&
+ !qual_type->isObjCIdType())
+ {
+ const ObjCObjectPointerType *obj_pointer_type = dyn_cast<ObjCObjectPointerType>(qual_type);
+ if (obj_pointer_type == NULL)
+ class_type_ptr->Clear();
+ else
+ class_type_ptr->SetClangType (m_ast, QualType(obj_pointer_type->getInterfaceType(), 0));
+ }
+ }
+ return true;
+ }
+ if (class_type_ptr)
+ class_type_ptr->Clear();
+ return false;
+}
+
+bool
+ClangASTType::GetObjCClassName (std::string &class_name)
+{
+ if (!IsValid())
+ return false;
+
+ QualType qual_type (GetCanonicalQualType());
+
+ const ObjCObjectType *object_type = dyn_cast<ObjCObjectType>(qual_type);
+ if (object_type)
+ {
+ const ObjCInterfaceDecl *interface = object_type->getInterface();
+ if (interface)
+ {
+ class_name = interface->getNameAsString();
+ return true;
+ }
+ }
+ return false;
+}
+
+
+//----------------------------------------------------------------------
+// Type Completion
+//----------------------------------------------------------------------
+
+bool
+ClangASTType::GetCompleteType () const
+{
+ if (!IsValid())
+ return false;
+ const bool allow_completion = true;
+ return GetCompleteQualType (m_ast, GetQualType(), allow_completion);
+}
+
+//----------------------------------------------------------------------
+// AST related queries
+//----------------------------------------------------------------------
+size_t
+ClangASTType::GetPointerByteSize () const
+{
+ if (m_ast)
+ return m_ast->getTypeSize(m_ast->VoidPtrTy) / 8;
+ return 0;
+}
+
+ConstString
+ClangASTType::GetConstQualifiedTypeName () const
+{
+ return GetConstTypeName ();
+}
+
+ConstString
+ClangASTType::GetConstTypeName () const
+{
+ if (IsValid())
+ {
+ std::string type_name (GetTypeName());
+ if (!type_name.empty())
+ return ConstString (type_name.c_str());
+ }
+ return ConstString("<invalid>");
+}
+
+std::string
+ClangASTType::GetTypeName () const
+{
+ std::string type_name;
+ if (IsValid())
+ {
+ PrintingPolicy printing_policy (m_ast->getPrintingPolicy());
+ QualType qual_type(GetQualType());
+ printing_policy.SuppressTagKeyword = true;
+ printing_policy.LangOpts.WChar = true;
+ const TypedefType *typedef_type = qual_type->getAs<TypedefType>();
+ if (typedef_type)
+ {
+ const TypedefNameDecl *typedef_decl = typedef_type->getDecl();
+ type_name = typedef_decl->getQualifiedNameAsString(printing_policy);
+ }
+ else
+ {
+ type_name = qual_type.getAsString(printing_policy);
+ }
+ }
+ return type_name;
+}
+
+
+uint32_t
+ClangASTType::GetTypeInfo (ClangASTType *pointee_or_element_clang_type) const
+{
+ if (!IsValid())
+ return 0;
+
+ if (pointee_or_element_clang_type)
+ pointee_or_element_clang_type->Clear();
+
+ QualType qual_type (GetQualType());
+
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class)
+ {
+ case clang::Type::Builtin:
+ {
+ const BuiltinType *builtin_type = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal());
+
+ uint32_t builtin_type_flags = eTypeIsBuiltIn | eTypeHasValue;
+ switch (builtin_type->getKind())
+ {
+ case clang::BuiltinType::ObjCId:
+ case clang::BuiltinType::ObjCClass:
+ if (pointee_or_element_clang_type)
+ pointee_or_element_clang_type->SetClangType(m_ast, m_ast->ObjCBuiltinClassTy);
+ builtin_type_flags |= eTypeIsPointer | eTypeIsObjC;
+ break;
+
+ case clang::BuiltinType::ObjCSel:
+ if (pointee_or_element_clang_type)
+ pointee_or_element_clang_type->SetClangType(m_ast, m_ast->CharTy);
+ builtin_type_flags |= eTypeIsPointer | eTypeIsObjC;
+ break;
+
+ case clang::BuiltinType::Bool:
+ case clang::BuiltinType::Char_U:
+ case clang::BuiltinType::UChar:
+ case clang::BuiltinType::WChar_U:
+ case clang::BuiltinType::Char16:
+ case clang::BuiltinType::Char32:
+ case clang::BuiltinType::UShort:
+ case clang::BuiltinType::UInt:
+ case clang::BuiltinType::ULong:
+ case clang::BuiltinType::ULongLong:
+ case clang::BuiltinType::UInt128:
+ case clang::BuiltinType::Char_S:
+ case clang::BuiltinType::SChar:
+ case clang::BuiltinType::WChar_S:
+ case clang::BuiltinType::Short:
+ case clang::BuiltinType::Int:
+ case clang::BuiltinType::Long:
+ case clang::BuiltinType::LongLong:
+ case clang::BuiltinType::Int128:
+ case clang::BuiltinType::Float:
+ case clang::BuiltinType::Double:
+ case clang::BuiltinType::LongDouble:
+ builtin_type_flags |= eTypeIsScalar;
+ if (builtin_type->isInteger())
+ {
+ builtin_type_flags |= eTypeIsInteger;
+ if (builtin_type->isSignedInteger())
+ builtin_type_flags |= eTypeIsSigned;
+ }
+ else if (builtin_type->isFloatingPoint())
+ builtin_type_flags |= eTypeIsFloat;
+ break;
+ default:
+ break;
+ }
+ return builtin_type_flags;
+ }
+
+ case clang::Type::BlockPointer:
+ if (pointee_or_element_clang_type)
+ pointee_or_element_clang_type->SetClangType(m_ast, qual_type->getPointeeType());
+ return eTypeIsPointer | eTypeHasChildren | eTypeIsBlock;
+
+ case clang::Type::Complex:
+ {
+ uint32_t complex_type_flags = eTypeIsBuiltIn | eTypeHasValue | eTypeIsComplex;
+ const ComplexType *complex_type = dyn_cast<ComplexType>(qual_type->getCanonicalTypeInternal());
+ if (complex_type)
+ {
+ QualType complex_element_type (complex_type->getElementType());
+ if (complex_element_type->isIntegerType())
+ complex_type_flags |= eTypeIsFloat;
+ else if (complex_element_type->isFloatingType())
+ complex_type_flags |= eTypeIsInteger;
+ }
+ return complex_type_flags;
+ }
+ break;
+
+ case clang::Type::ConstantArray:
+ case clang::Type::DependentSizedArray:
+ case clang::Type::IncompleteArray:
+ case clang::Type::VariableArray:
+ if (pointee_or_element_clang_type)
+ pointee_or_element_clang_type->SetClangType(m_ast, cast<ArrayType>(qual_type.getTypePtr())->getElementType());
+ return eTypeHasChildren | eTypeIsArray;
+
+ case clang::Type::DependentName: return 0;
+ case clang::Type::DependentSizedExtVector: return eTypeHasChildren | eTypeIsVector;
+ case clang::Type::DependentTemplateSpecialization: return eTypeIsTemplate;
+ case clang::Type::Decltype: return 0;
+
+ case clang::Type::Enum:
+ if (pointee_or_element_clang_type)
+ pointee_or_element_clang_type->SetClangType(m_ast, cast<EnumType>(qual_type)->getDecl()->getIntegerType());
+ return eTypeIsEnumeration | eTypeHasValue;
+
+ case clang::Type::Elaborated:
+ return ClangASTType (m_ast, cast<ElaboratedType>(qual_type)->getNamedType()).GetTypeInfo (pointee_or_element_clang_type);
+ case clang::Type::Paren:
+ return ClangASTType (m_ast, cast<clang::ParenType>(qual_type)->desugar()).GetTypeInfo (pointee_or_element_clang_type);
+
+ case clang::Type::FunctionProto: return eTypeIsFuncPrototype | eTypeHasValue;
+ case clang::Type::FunctionNoProto: return eTypeIsFuncPrototype | eTypeHasValue;
+ case clang::Type::InjectedClassName: return 0;
+
+ case clang::Type::LValueReference:
+ case clang::Type::RValueReference:
+ if (pointee_or_element_clang_type)
+ pointee_or_element_clang_type->SetClangType(m_ast, cast<ReferenceType>(qual_type.getTypePtr())->getPointeeType());
+ return eTypeHasChildren | eTypeIsReference | eTypeHasValue;
+
+ case clang::Type::MemberPointer: return eTypeIsPointer | eTypeIsMember | eTypeHasValue;
+
+ case clang::Type::ObjCObjectPointer:
+ if (pointee_or_element_clang_type)
+ pointee_or_element_clang_type->SetClangType(m_ast, qual_type->getPointeeType());
+ return eTypeHasChildren | eTypeIsObjC | eTypeIsClass | eTypeIsPointer | eTypeHasValue;
+
+ case clang::Type::ObjCObject: return eTypeHasChildren | eTypeIsObjC | eTypeIsClass;
+ case clang::Type::ObjCInterface: return eTypeHasChildren | eTypeIsObjC | eTypeIsClass;
+
+ case clang::Type::Pointer:
+ if (pointee_or_element_clang_type)
+ pointee_or_element_clang_type->SetClangType(m_ast, qual_type->getPointeeType());
+ return eTypeHasChildren | eTypeIsPointer | eTypeHasValue;
+
+ case clang::Type::Record:
+ if (qual_type->getAsCXXRecordDecl())
+ return eTypeHasChildren | eTypeIsClass | eTypeIsCPlusPlus;
+ else
+ return eTypeHasChildren | eTypeIsStructUnion;
+ break;
+ case clang::Type::SubstTemplateTypeParm: return eTypeIsTemplate;
+ case clang::Type::TemplateTypeParm: return eTypeIsTemplate;
+ case clang::Type::TemplateSpecialization: return eTypeIsTemplate;
+
+ case clang::Type::Typedef:
+ return eTypeIsTypedef | ClangASTType (m_ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetTypeInfo (pointee_or_element_clang_type);
+ case clang::Type::TypeOfExpr: return 0;
+ case clang::Type::TypeOf: return 0;
+ case clang::Type::UnresolvedUsing: return 0;
+
+ case clang::Type::ExtVector:
+ case clang::Type::Vector:
+ {
+ uint32_t vector_type_flags = eTypeHasChildren | eTypeIsVector;
+ const VectorType *vector_type = dyn_cast<VectorType>(qual_type->getCanonicalTypeInternal());
+ if (vector_type)
+ {
+ if (vector_type->isIntegerType())
+ vector_type_flags |= eTypeIsFloat;
+ else if (vector_type->isFloatingType())
+ vector_type_flags |= eTypeIsInteger;
+ }
+ return vector_type_flags;
+ }
+ default: return 0;
+ }
+ return 0;
+}
+
+
+
+lldb::LanguageType
+ClangASTType::GetMinimumLanguage ()
+{
+ if (!IsValid())
+ return lldb::eLanguageTypeC;
+
+ // If the type is a reference, then resolve it to what it refers to first:
+ QualType qual_type (GetCanonicalQualType().getNonReferenceType());
+ if (qual_type->isAnyPointerType())
+ {
+ if (qual_type->isObjCObjectPointerType())
+ return lldb::eLanguageTypeObjC;
+
+ QualType pointee_type (qual_type->getPointeeType());
+ if (pointee_type->getPointeeCXXRecordDecl() != NULL)
+ return lldb::eLanguageTypeC_plus_plus;
+ if (pointee_type->isObjCObjectOrInterfaceType())
+ return lldb::eLanguageTypeObjC;
+ if (pointee_type->isObjCClassType())
+ return lldb::eLanguageTypeObjC;
+ if (pointee_type.getTypePtr() == m_ast->ObjCBuiltinIdTy.getTypePtr())
+ return lldb::eLanguageTypeObjC;
+ }
+ else
+ {
+ if (qual_type->isObjCObjectOrInterfaceType())
+ return lldb::eLanguageTypeObjC;
+ if (qual_type->getAsCXXRecordDecl())
+ return lldb::eLanguageTypeC_plus_plus;
+ switch (qual_type->getTypeClass())
+ {
+ default:
+ break;
+ case clang::Type::Builtin:
+ switch (cast<BuiltinType>(qual_type)->getKind())
+ {
+ default:
+ case BuiltinType::Void:
+ case BuiltinType::Bool:
+ case BuiltinType::Char_U:
+ case BuiltinType::UChar:
+ case BuiltinType::WChar_U:
+ case BuiltinType::Char16:
+ case BuiltinType::Char32:
+ case BuiltinType::UShort:
+ case BuiltinType::UInt:
+ case BuiltinType::ULong:
+ case BuiltinType::ULongLong:
+ case BuiltinType::UInt128:
+ case BuiltinType::Char_S:
+ case BuiltinType::SChar:
+ case BuiltinType::WChar_S:
+ case BuiltinType::Short:
+ case BuiltinType::Int:
+ case BuiltinType::Long:
+ case BuiltinType::LongLong:
+ case BuiltinType::Int128:
+ case BuiltinType::Float:
+ case BuiltinType::Double:
+ case BuiltinType::LongDouble:
+ break;
+
+ case BuiltinType::NullPtr:
+ return eLanguageTypeC_plus_plus;
+
+ case BuiltinType::ObjCId:
+ case BuiltinType::ObjCClass:
+ case BuiltinType::ObjCSel:
+ return eLanguageTypeObjC;
+
+ case BuiltinType::Dependent:
+ case BuiltinType::Overload:
+ case BuiltinType::BoundMember:
+ case BuiltinType::UnknownAny:
+ break;
+ }
+ break;
+ case clang::Type::Typedef:
+ return ClangASTType(m_ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetMinimumLanguage();
+ }
+ }
+ return lldb::eLanguageTypeC;
+}
+
+lldb::TypeClass
+ClangASTType::GetTypeClass () const
+{
+ if (!IsValid())
+ return lldb::eTypeClassInvalid;
+
+ QualType qual_type(GetQualType());
+
+ switch (qual_type->getTypeClass())
{
case clang::Type::UnaryTransform: break;
case clang::Type::FunctionNoProto: return lldb::eTypeClassFunction;
@@ -293,483 +1388,4163 @@ ClangASTType::GetTypeClass (clang::ASTCo
case clang::Type::MemberPointer: return lldb::eTypeClassMemberPointer;
case clang::Type::Complex:
if (qual_type->isComplexType())
- return lldb::eTypeClassComplexFloat;
+ return lldb::eTypeClassComplexFloat;
+ else
+ return lldb::eTypeClassComplexInteger;
+ case clang::Type::ObjCObject: return lldb::eTypeClassObjCObject;
+ case clang::Type::ObjCInterface: return lldb::eTypeClassObjCInterface;
+ case clang::Type::Record:
+ {
+ const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
+ const RecordDecl *record_decl = record_type->getDecl();
+ if (record_decl->isUnion())
+ return lldb::eTypeClassUnion;
+ else if (record_decl->isStruct())
+ return lldb::eTypeClassStruct;
+ else
+ return lldb::eTypeClassClass;
+ }
+ break;
+ case clang::Type::Enum: return lldb::eTypeClassEnumeration;
+ case clang::Type::Typedef: return lldb::eTypeClassTypedef;
+ case clang::Type::UnresolvedUsing: break;
+ case clang::Type::Paren:
+ return ClangASTType(m_ast, cast<ParenType>(qual_type)->desugar()).GetTypeClass();
+ case clang::Type::Elaborated:
+ return ClangASTType(m_ast, cast<ElaboratedType>(qual_type)->getNamedType()).GetTypeClass();
+
+ case clang::Type::Attributed: break;
+ case clang::Type::TemplateTypeParm: break;
+ case clang::Type::SubstTemplateTypeParm: break;
+ case clang::Type::SubstTemplateTypeParmPack:break;
+ case clang::Type::Auto: break;
+ case clang::Type::InjectedClassName: break;
+ case clang::Type::DependentName: break;
+ case clang::Type::DependentTemplateSpecialization: break;
+ case clang::Type::PackExpansion: break;
+
+ case clang::Type::TypeOfExpr: break;
+ case clang::Type::TypeOf: break;
+ case clang::Type::Decltype: break;
+ case clang::Type::TemplateSpecialization: break;
+ case clang::Type::Atomic: break;
+ }
+ // We don't know hot to display this type...
+ return lldb::eTypeClassOther;
+
+}
+
+void
+ClangASTType::SetClangType (clang::ASTContext *ast, clang::QualType qual_type)
+{
+ m_ast = ast;
+ m_type = qual_type.getAsOpaquePtr();
+}
+
+unsigned
+ClangASTType::GetTypeQualifiers() const
+{
+ if (IsValid())
+ return GetQualType().getQualifiers().getCVRQualifiers();
+ return 0;
+}
+
+//----------------------------------------------------------------------
+// Creating related types
+//----------------------------------------------------------------------
+
+ClangASTType
+ClangASTType::AddConstModifier () const
+{
+ if (m_type)
+ {
+ QualType result(GetQualType());
+ result.addConst();
+ return ClangASTType (m_ast, result);
+ }
+ return ClangASTType();
+}
+
+ClangASTType
+ClangASTType::AddRestrictModifier () const
+{
+ if (m_type)
+ {
+ QualType result(GetQualType());
+ result.getQualifiers().setRestrict (true);
+ return ClangASTType (m_ast, result);
+ }
+ return ClangASTType();
+}
+
+ClangASTType
+ClangASTType::AddVolatileModifier () const
+{
+ if (m_type)
+ {
+ QualType result(GetQualType());
+ result.getQualifiers().setVolatile (true);
+ return ClangASTType (m_ast, result);
+ }
+ return ClangASTType();
+}
+
+ClangASTType
+ClangASTType::GetArrayElementType (uint64_t& stride) const
+{
+ if (IsValid())
+ {
+ QualType qual_type(GetCanonicalQualType());
+
+ ClangASTType element_type (m_ast, qual_type.getTypePtr()->getArrayElementTypeNoTypeQual()->getCanonicalTypeUnqualified());
+
+ // TODO: the real stride will be >= this value.. find the real one!
+ stride = element_type.GetByteSize();
+
+ return element_type;
+
+ }
+ return ClangASTType();
+}
+
+ClangASTType
+ClangASTType::GetCanonicalType () const
+{
+ if (IsValid())
+ return ClangASTType (m_ast, GetCanonicalQualType());
+ return ClangASTType();
+}
+
+static QualType
+GetFullyUnqualifiedType_Impl (ASTContext *ast, QualType qual_type)
+{
+ if (qual_type->isPointerType())
+ qual_type = ast->getPointerType(GetFullyUnqualifiedType_Impl(ast, qual_type->getPointeeType()));
+ else
+ qual_type = qual_type.getUnqualifiedType();
+ qual_type.removeLocalConst();
+ qual_type.removeLocalRestrict();
+ qual_type.removeLocalVolatile();
+ return qual_type;
+}
+
+ClangASTType
+ClangASTType::GetFullyUnqualifiedType () const
+{
+ if (IsValid())
+ return ClangASTType(m_ast, GetFullyUnqualifiedType_Impl(m_ast, GetQualType()));
+ return ClangASTType();
+}
+
+
+int
+ClangASTType::GetFunctionArgumentCount () const
+{
+ if (IsValid())
+ {
+ const FunctionProtoType* func = dyn_cast<FunctionProtoType>(GetCanonicalQualType());
+ if (func)
+ return func->getNumArgs();
+ }
+ return -1;
+}
+
+ClangASTType
+ClangASTType::GetFunctionArgumentTypeAtIndex (size_t idx)
+{
+ if (IsValid())
+ {
+ const FunctionProtoType* func = dyn_cast<FunctionProtoType>(GetCanonicalQualType());
+ if (func)
+ {
+ const uint32_t num_args = func->getNumArgs();
+ if (idx < num_args)
+ return ClangASTType(m_ast, func->getArgType(idx));
+ }
+ }
+ return ClangASTType();
+}
+
+ClangASTType
+ClangASTType::GetFunctionReturnType () const
+{
+ if (IsValid())
+ {
+ QualType qual_type(GetCanonicalQualType());
+ const FunctionProtoType* func = dyn_cast<FunctionProtoType>(qual_type.getTypePtr());
+ if (func)
+ return ClangASTType(m_ast, func->getResultType());
+ }
+ return ClangASTType();
+}
+
+
+ClangASTType
+ClangASTType::GetLValueReferenceType () const
+{
+ if (IsValid())
+ {
+ return ClangASTType(m_ast, m_ast->getLValueReferenceType(GetQualType()));
+ }
+ return ClangASTType();
+}
+
+ClangASTType
+ClangASTType::GetRValueReferenceType () const
+{
+ if (IsValid())
+ {
+ return ClangASTType(m_ast, m_ast->getRValueReferenceType(GetQualType()));
+ }
+ return ClangASTType();
+}
+
+ClangASTType
+ClangASTType::GetNonReferenceType () const
+{
+ if (IsValid())
+ return ClangASTType(m_ast, GetQualType().getNonReferenceType());
+ return ClangASTType();
+}
+
+ClangASTType
+ClangASTType::CreateTypedefType (const char *typedef_name,
+ clang::DeclContext *decl_ctx) const
+{
+ if (IsValid() && typedef_name && typedef_name[0])
+ {
+ QualType qual_type (GetQualType());
+ if (decl_ctx == NULL)
+ decl_ctx = m_ast->getTranslationUnitDecl();
+ TypedefDecl *decl = TypedefDecl::Create (*m_ast,
+ decl_ctx,
+ SourceLocation(),
+ SourceLocation(),
+ &m_ast->Idents.get(typedef_name),
+ m_ast->getTrivialTypeSourceInfo(qual_type));
+
+ decl->setAccess(AS_public); // TODO respect proper access specifier
+
+ // Get a uniqued QualType for the typedef decl type
+ return ClangASTType (m_ast, m_ast->getTypedefType (decl));
+ }
+ return ClangASTType();
+
+}
+
+ClangASTType
+ClangASTType::GetPointeeType () const
+{
+ if (m_type)
+ {
+ QualType qual_type(GetQualType());
+ return ClangASTType (m_ast, qual_type.getTypePtr()->getPointeeType());
+ }
+ return ClangASTType();
+}
+
+ClangASTType
+ClangASTType::GetPointerType () const
+{
+ if (IsValid())
+ {
+ QualType qual_type (GetQualType());
+
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class)
+ {
+ case clang::Type::ObjCObject:
+ case clang::Type::ObjCInterface:
+ return ClangASTType(m_ast, m_ast->getObjCObjectPointerType(qual_type).getAsOpaquePtr());
+
+ default:
+ return ClangASTType(m_ast, m_ast->getPointerType(qual_type).getAsOpaquePtr());
+ }
+ }
+ return ClangASTType();
+}
+
+ClangASTType
+ClangASTType::GetTypedefedType () const
+{
+ if (IsValid())
+ {
+ const TypedefType *typedef_type = dyn_cast<TypedefType>(GetQualType());
+ if (typedef_type)
+ return ClangASTType (m_ast, typedef_type->getDecl()->getUnderlyingType());
+ }
+ return ClangASTType();
+}
+
+ClangASTType
+ClangASTType::RemoveFastQualifiers () const
+{
+ if (m_type)
+ {
+ QualType qual_type(GetQualType());
+ qual_type.getQualifiers().removeFastQualifiers();
+ return ClangASTType (m_ast, qual_type);
+ }
+ return ClangASTType();
+}
+
+
+//----------------------------------------------------------------------
+// Create related types using the current type's AST
+//----------------------------------------------------------------------
+
+ClangASTType
+ClangASTType::GetBasicTypeFromAST (lldb::BasicType basic_type) const
+{
+ if (IsValid())
+ return ClangASTContext::GetBasicType(m_ast, basic_type);
+ return ClangASTType();
+}
+//----------------------------------------------------------------------
+// Exploring the type
+//----------------------------------------------------------------------
+
+uint64_t
+ClangASTType::GetBitSize () const
+{
+ if (GetCompleteType ())
+ {
+ QualType qual_type(GetCanonicalQualType());
+ const uint32_t bit_size = m_ast->getTypeSize (qual_type);
+ if (bit_size == 0)
+ {
+ if (qual_type->isIncompleteArrayType())
+ return m_ast->getTypeSize (qual_type->getArrayElementTypeNoTypeQual()->getCanonicalTypeUnqualified());
+ }
+ if (qual_type->isObjCObjectOrInterfaceType())
+ return bit_size + m_ast->getTypeSize(m_ast->ObjCBuiltinClassTy);
+ return bit_size;
+ }
+ return 0;
+}
+
+uint64_t
+ClangASTType::GetByteSize () const
+{
+ return (GetBitSize () + 7) / 8;
+}
+
+size_t
+ClangASTType::GetTypeBitAlign () const
+{
+ if (GetCompleteType ())
+ return m_ast->getTypeAlign(GetQualType());
+ return 0;
+}
+
+
+lldb::Encoding
+ClangASTType::GetEncoding (uint64_t &count) const
+{
+ if (!IsValid())
+ return lldb::eEncodingInvalid;
+
+ count = 1;
+ QualType qual_type(GetCanonicalQualType());
+
+ 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 (cast<BuiltinType>(qual_type)->getKind())
+ {
+ default: assert(0 && "Unknown builtin type!");
+ case BuiltinType::Void:
+ break;
+
+ case BuiltinType::Bool:
+ case BuiltinType::Char_S:
+ case BuiltinType::SChar:
+ case BuiltinType::WChar_S:
+ case BuiltinType::Char16:
+ case BuiltinType::Char32:
+ case BuiltinType::Short:
+ case BuiltinType::Int:
+ case BuiltinType::Long:
+ case BuiltinType::LongLong:
+ case BuiltinType::Int128: return lldb::eEncodingSint;
+
+ case BuiltinType::Char_U:
+ case BuiltinType::UChar:
+ case BuiltinType::WChar_U:
+ case BuiltinType::UShort:
+ case BuiltinType::UInt:
+ case BuiltinType::ULong:
+ case BuiltinType::ULongLong:
+ case BuiltinType::UInt128: return lldb::eEncodingUint;
+
+ case BuiltinType::Float:
+ case BuiltinType::Double:
+ case BuiltinType::LongDouble: return lldb::eEncodingIEEE754;
+
+ case BuiltinType::ObjCClass:
+ case BuiltinType::ObjCId:
+ case BuiltinType::ObjCSel: return lldb::eEncodingUint;
+
+ case BuiltinType::NullPtr: return lldb::eEncodingUint;
+ }
+ break;
+ // All pointer types are represented as unsigned integer encodings.
+ // We may nee to add a eEncodingPointer if we ever need to know the
+ // difference
+ case clang::Type::ObjCObjectPointer:
+ case clang::Type::BlockPointer:
+ case clang::Type::Pointer:
+ case clang::Type::LValueReference:
+ case clang::Type::RValueReference:
+ case clang::Type::MemberPointer: return lldb::eEncodingUint;
+ case clang::Type::Complex:
+ {
+ lldb::Encoding encoding = lldb::eEncodingIEEE754;
+ if (qual_type->isComplexType())
+ encoding = lldb::eEncodingIEEE754;
+ else
+ {
+ const ComplexType *complex_type = qual_type->getAsComplexIntegerType();
+ if (complex_type)
+ encoding = ClangASTType(m_ast, complex_type->getElementType()).GetEncoding(count);
+ else
+ encoding = lldb::eEncodingSint;
+ }
+ count = 2;
+ return encoding;
+ }
+
+ case clang::Type::ObjCInterface: break;
+ case clang::Type::Record: break;
+ case clang::Type::Enum: return lldb::eEncodingSint;
+ case clang::Type::Typedef:
+ return ClangASTType(m_ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetEncoding(count);
+
+ case clang::Type::Elaborated:
+ return ClangASTType(m_ast, cast<ElaboratedType>(qual_type)->getNamedType()).GetEncoding(count);
+
+ case clang::Type::Paren:
+ return ClangASTType(m_ast, cast<ParenType>(qual_type)->desugar()).GetEncoding(count);
+
+ case clang::Type::DependentSizedArray:
+ case clang::Type::DependentSizedExtVector:
+ case clang::Type::UnresolvedUsing:
+ case clang::Type::Attributed:
+ case clang::Type::TemplateTypeParm:
+ case clang::Type::SubstTemplateTypeParm:
+ case clang::Type::SubstTemplateTypeParmPack:
+ case clang::Type::Auto:
+ case clang::Type::InjectedClassName:
+ case clang::Type::DependentName:
+ case clang::Type::DependentTemplateSpecialization:
+ case clang::Type::PackExpansion:
+ case clang::Type::ObjCObject:
+
+ case clang::Type::TypeOfExpr:
+ case clang::Type::TypeOf:
+ case clang::Type::Decltype:
+ case clang::Type::TemplateSpecialization:
+ case clang::Type::Atomic:
+ break;
+
+ }
+ count = 0;
+ return lldb::eEncodingInvalid;
+}
+
+lldb::Format
+ClangASTType::GetFormat () const
+{
+ if (!IsValid())
+ return lldb::eFormatDefault;
+
+ QualType qual_type(GetCanonicalQualType());
+
+ 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:
+ return lldb::eFormatVoid; // no value
+
+ case clang::Type::ExtVector:
+ case clang::Type::Vector:
+ break;
+
+ case clang::Type::Builtin:
+ switch (cast<BuiltinType>(qual_type)->getKind())
+ {
+ //default: assert(0 && "Unknown builtin type!");
+ case BuiltinType::UnknownAny:
+ case BuiltinType::Void:
+ case BuiltinType::BoundMember:
+ break;
+
+ case BuiltinType::Bool: return lldb::eFormatBoolean;
+ case BuiltinType::Char_S:
+ case BuiltinType::SChar:
+ case BuiltinType::WChar_S:
+ case BuiltinType::Char_U:
+ case BuiltinType::UChar:
+ case BuiltinType::WChar_U: return lldb::eFormatChar;
+ case BuiltinType::Char16: return lldb::eFormatUnicode16;
+ case BuiltinType::Char32: return lldb::eFormatUnicode32;
+ case BuiltinType::UShort: return lldb::eFormatUnsigned;
+ case BuiltinType::Short: return lldb::eFormatDecimal;
+ case BuiltinType::UInt: return lldb::eFormatUnsigned;
+ case BuiltinType::Int: return lldb::eFormatDecimal;
+ case BuiltinType::ULong: return lldb::eFormatUnsigned;
+ case BuiltinType::Long: return lldb::eFormatDecimal;
+ case BuiltinType::ULongLong: return lldb::eFormatUnsigned;
+ case BuiltinType::LongLong: return lldb::eFormatDecimal;
+ case BuiltinType::UInt128: return lldb::eFormatUnsigned;
+ case BuiltinType::Int128: return lldb::eFormatDecimal;
+ case BuiltinType::Float: return lldb::eFormatFloat;
+ case BuiltinType::Double: return lldb::eFormatFloat;
+ case BuiltinType::LongDouble: return lldb::eFormatFloat;
+ case BuiltinType::NullPtr:
+ case BuiltinType::Overload:
+ case BuiltinType::Dependent:
+ case BuiltinType::ObjCId:
+ case BuiltinType::ObjCClass:
+ case BuiltinType::ObjCSel:
+ case BuiltinType::Half:
+ case BuiltinType::ARCUnbridgedCast:
+ case BuiltinType::PseudoObject:
+ case BuiltinType::BuiltinFn:
+ case BuiltinType::OCLEvent:
+ case BuiltinType::OCLImage1d:
+ case BuiltinType::OCLImage1dArray:
+ case BuiltinType::OCLImage1dBuffer:
+ case BuiltinType::OCLImage2d:
+ case BuiltinType::OCLImage2dArray:
+ case BuiltinType::OCLImage3d:
+ case BuiltinType::OCLSampler:
+ return lldb::eFormatHex;
+ }
+ break;
+ case clang::Type::ObjCObjectPointer: return lldb::eFormatHex;
+ case clang::Type::BlockPointer: return lldb::eFormatHex;
+ case clang::Type::Pointer: return lldb::eFormatHex;
+ case clang::Type::LValueReference:
+ case clang::Type::RValueReference: return lldb::eFormatHex;
+ case clang::Type::MemberPointer: break;
+ case clang::Type::Complex:
+ {
+ if (qual_type->isComplexType())
+ return lldb::eFormatComplex;
+ else
+ return lldb::eFormatComplexInteger;
+ }
+ case clang::Type::ObjCInterface: break;
+ case clang::Type::Record: break;
+ case clang::Type::Enum: return lldb::eFormatEnum;
+ case clang::Type::Typedef:
+ return ClangASTType (m_ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetFormat();
+ case clang::Type::Auto:
+ return ClangASTType (m_ast, cast<AutoType>(qual_type)->desugar()).GetFormat();
+ case clang::Type::Paren:
+ return ClangASTType (m_ast, cast<ParenType>(qual_type)->desugar()).GetFormat();
+ case clang::Type::Elaborated:
+ return ClangASTType (m_ast, cast<ElaboratedType>(qual_type)->getNamedType()).GetFormat();
+ case clang::Type::DependentSizedArray:
+ case clang::Type::DependentSizedExtVector:
+ case clang::Type::UnresolvedUsing:
+ case clang::Type::Attributed:
+ case clang::Type::TemplateTypeParm:
+ case clang::Type::SubstTemplateTypeParm:
+ case clang::Type::SubstTemplateTypeParmPack:
+ case clang::Type::InjectedClassName:
+ case clang::Type::DependentName:
+ case clang::Type::DependentTemplateSpecialization:
+ case clang::Type::PackExpansion:
+ case clang::Type::ObjCObject:
+
+ case clang::Type::TypeOfExpr:
+ case clang::Type::TypeOf:
+ case clang::Type::Decltype:
+ case clang::Type::TemplateSpecialization:
+ case clang::Type::Atomic:
+ break;
+ }
+ // We don't know hot to display this type...
+ return lldb::eFormatBytes;
+}
+
+static bool
+ObjCDeclHasIVars (ObjCInterfaceDecl *class_interface_decl, bool check_superclass)
+{
+ while (class_interface_decl)
+ {
+ if (class_interface_decl->ivar_size() > 0)
+ return true;
+
+ if (check_superclass)
+ class_interface_decl = class_interface_decl->getSuperClass();
+ else
+ break;
+ }
+ return false;
+}
+
+uint32_t
+ClangASTType::GetNumChildren (bool omit_empty_base_classes) const
+{
+ if (!IsValid())
+ return 0;
+
+ uint32_t num_children = 0;
+ QualType qual_type(GetQualType());
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class)
+ {
+ case clang::Type::Builtin:
+ switch (cast<BuiltinType>(qual_type)->getKind())
+ {
+ case BuiltinType::ObjCId: // child is Class
+ case BuiltinType::ObjCClass: // child is Class
+ num_children = 1;
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+ case clang::Type::Complex: return 0;
+
+ case clang::Type::Record:
+ if (GetCompleteQualType (m_ast, qual_type))
+ {
+ const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
+ const RecordDecl *record_decl = record_type->getDecl();
+ assert(record_decl);
+ const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
+ if (cxx_record_decl)
+ {
+ if (omit_empty_base_classes)
+ {
+ // Check each base classes to see if it or any of its
+ // base classes contain any fields. This can help
+ // limit the noise in variable views by not having to
+ // show base classes that contain no members.
+ CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
+ for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
+ base_class != base_class_end;
+ ++base_class)
+ {
+ const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
+
+ // Skip empty base classes
+ if (ClangASTContext::RecordHasFields(base_class_decl) == false)
+ continue;
+
+ num_children++;
+ }
+ }
+ else
+ {
+ // Include all base classes
+ num_children += cxx_record_decl->getNumBases();
+ }
+
+ }
+ RecordDecl::field_iterator field, field_end;
+ for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field)
+ ++num_children;
+ }
+ break;
+
+ case clang::Type::ObjCObject:
+ case clang::Type::ObjCInterface:
+ if (GetCompleteQualType (m_ast, qual_type))
+ {
+ const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
+ assert (objc_class_type);
+ if (objc_class_type)
+ {
+ ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
+
+ if (class_interface_decl)
+ {
+
+ ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
+ if (superclass_interface_decl)
+ {
+ if (omit_empty_base_classes)
+ {
+ if (ObjCDeclHasIVars (superclass_interface_decl, true))
+ ++num_children;
+ }
+ else
+ ++num_children;
+ }
+
+ num_children += class_interface_decl->ivar_size();
+ }
+ }
+ }
+ break;
+
+ case clang::Type::ObjCObjectPointer:
+ {
+ const ObjCObjectPointerType *pointer_type = cast<ObjCObjectPointerType>(qual_type.getTypePtr());
+ QualType pointee_type = pointer_type->getPointeeType();
+ uint32_t num_pointee_children = ClangASTType (m_ast,pointee_type).GetNumChildren (omit_empty_base_classes);
+ // If this type points to a simple type, then it has 1 child
+ if (num_pointee_children == 0)
+ num_children = 1;
+ else
+ num_children = num_pointee_children;
+ }
+ break;
+
+ case clang::Type::Vector:
+ case clang::Type::ExtVector:
+ num_children = cast<VectorType>(qual_type.getTypePtr())->getNumElements();
+ break;
+
+ case clang::Type::ConstantArray:
+ num_children = cast<ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue();
+ break;
+
+ case clang::Type::Pointer:
+ {
+ const PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
+ QualType pointee_type (pointer_type->getPointeeType());
+ uint32_t num_pointee_children = ClangASTType (m_ast,pointee_type).GetNumChildren (omit_empty_base_classes);
+ if (num_pointee_children == 0)
+ {
+ // We have a pointer to a pointee type that claims it has no children.
+ // We will want to look at
+ num_children = ClangASTType (m_ast, pointee_type).GetNumPointeeChildren();
+ }
+ else
+ num_children = num_pointee_children;
+ }
+ break;
+
+ case clang::Type::LValueReference:
+ case clang::Type::RValueReference:
+ {
+ const ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
+ QualType pointee_type = reference_type->getPointeeType();
+ uint32_t num_pointee_children = ClangASTType (m_ast, pointee_type).GetNumChildren (omit_empty_base_classes);
+ // If this type points to a simple type, then it has 1 child
+ if (num_pointee_children == 0)
+ num_children = 1;
+ else
+ num_children = num_pointee_children;
+ }
+ break;
+
+
+ case clang::Type::Typedef:
+ num_children = ClangASTType (m_ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetNumChildren (omit_empty_base_classes);
+ break;
+
+ case clang::Type::Elaborated:
+ num_children = ClangASTType (m_ast, cast<ElaboratedType>(qual_type)->getNamedType()).GetNumChildren (omit_empty_base_classes);
+ break;
+
+ case clang::Type::Paren:
+ num_children = ClangASTType (m_ast, cast<ParenType>(qual_type)->desugar()).GetNumChildren (omit_empty_base_classes);
+ break;
+ default:
+ break;
+ }
+ return num_children;
+}
+
+lldb::BasicType
+ClangASTType::GetBasicTypeEnumeration () const
+{
+ if (IsValid())
+ {
+ QualType qual_type(GetQualType());
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ if (type_class == clang::Type::Builtin)
+ {
+ switch (cast<clang::BuiltinType>(qual_type)->getKind())
+ {
+ case clang::BuiltinType::Void: return eBasicTypeVoid;
+ case clang::BuiltinType::Bool: return eBasicTypeBool;
+ case clang::BuiltinType::Char_S: return eBasicTypeSignedChar;
+ case clang::BuiltinType::Char_U: return eBasicTypeUnsignedChar;
+ case clang::BuiltinType::Char16: return eBasicTypeChar16;
+ case clang::BuiltinType::Char32: return eBasicTypeChar32;
+ case clang::BuiltinType::UChar: return eBasicTypeUnsignedChar;
+ case clang::BuiltinType::SChar: return eBasicTypeSignedChar;
+ case clang::BuiltinType::WChar_S: return eBasicTypeSignedWChar;
+ case clang::BuiltinType::WChar_U: return eBasicTypeUnsignedWChar;
+ case clang::BuiltinType::Short: return eBasicTypeShort;
+ case clang::BuiltinType::UShort: return eBasicTypeUnsignedShort;
+ case clang::BuiltinType::Int: return eBasicTypeInt;
+ case clang::BuiltinType::UInt: return eBasicTypeUnsignedInt;
+ case clang::BuiltinType::Long: return eBasicTypeLong;
+ case clang::BuiltinType::ULong: return eBasicTypeUnsignedLong;
+ case clang::BuiltinType::LongLong: return eBasicTypeLongLong;
+ case clang::BuiltinType::ULongLong: return eBasicTypeUnsignedLongLong;
+ case clang::BuiltinType::Int128: return eBasicTypeInt128;
+ case clang::BuiltinType::UInt128: return eBasicTypeUnsignedInt128;
+
+ case clang::BuiltinType::Half: return eBasicTypeHalf;
+ case clang::BuiltinType::Float: return eBasicTypeFloat;
+ case clang::BuiltinType::Double: return eBasicTypeDouble;
+ case clang::BuiltinType::LongDouble:return eBasicTypeLongDouble;
+
+ case clang::BuiltinType::NullPtr: return eBasicTypeNullPtr;
+ case clang::BuiltinType::ObjCId: return eBasicTypeObjCID;
+ case clang::BuiltinType::ObjCClass: return eBasicTypeObjCClass;
+ case clang::BuiltinType::ObjCSel: return eBasicTypeObjCSel;
+ case clang::BuiltinType::Dependent:
+ case clang::BuiltinType::Overload:
+ case clang::BuiltinType::BoundMember:
+ case clang::BuiltinType::PseudoObject:
+ case clang::BuiltinType::UnknownAny:
+ case clang::BuiltinType::BuiltinFn:
+ case clang::BuiltinType::ARCUnbridgedCast:
+ 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::OCLSampler:
+ return eBasicTypeOther;
+ }
+ }
+ }
+ return eBasicTypeInvalid;
+}
+
+
+#pragma mark Aggregate Types
+
+uint32_t
+ClangASTType::GetNumDirectBaseClasses () const
+{
+ if (!IsValid())
+ return 0;
+
+ uint32_t count = 0;
+ QualType qual_type(GetCanonicalQualType());
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class)
+ {
+ case clang::Type::Record:
+ if (GetCompleteType())
+ {
+ const CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
+ if (cxx_record_decl)
+ count = cxx_record_decl->getNumBases();
+ }
+ break;
+
+ case clang::Type::ObjCObjectPointer:
+ if (GetCompleteType())
+ {
+ const ObjCObjectPointerType *objc_class_type = qual_type->getAsObjCInterfacePointerType();
+ if (objc_class_type)
+ {
+ ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterfaceDecl();
+ if (class_interface_decl && class_interface_decl->getSuperClass())
+ count = 1;
+ }
+ }
+ break;
+
+ case clang::Type::ObjCObject:
+ case clang::Type::ObjCInterface:
+ if (GetCompleteType())
+ {
+ const ObjCObjectType *objc_class_type = qual_type->getAsObjCQualifiedInterfaceType();
+ if (objc_class_type)
+ {
+ ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
+
+ if (class_interface_decl && class_interface_decl->getSuperClass())
+ count = 1;
+ }
+ }
+ break;
+
+
+ case clang::Type::Typedef:
+ count = ClangASTType (m_ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetNumDirectBaseClasses ();
+ break;
+
+ case clang::Type::Elaborated:
+ count = ClangASTType (m_ast, cast<ElaboratedType>(qual_type)->getNamedType()).GetNumDirectBaseClasses ();
+ break;
+
+ case clang::Type::Paren:
+ return ClangASTType (m_ast, cast<clang::ParenType>(qual_type)->desugar()).GetNumDirectBaseClasses ();
+
+ default:
+ break;
+ }
+ return count;
+}
+
+uint32_t
+ClangASTType::GetNumVirtualBaseClasses () const
+{
+ if (!IsValid())
+ return 0;
+
+ uint32_t count = 0;
+ QualType qual_type(GetCanonicalQualType());
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class)
+ {
+ case clang::Type::Record:
+ if (GetCompleteType())
+ {
+ const CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
+ if (cxx_record_decl)
+ count = cxx_record_decl->getNumVBases();
+ }
+ break;
+
+ case clang::Type::Typedef:
+ count = ClangASTType (m_ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetNumVirtualBaseClasses();
+ break;
+
+ case clang::Type::Elaborated:
+ count = ClangASTType (m_ast, cast<ElaboratedType>(qual_type)->getNamedType()).GetNumVirtualBaseClasses();
+ break;
+
+ case clang::Type::Paren:
+ count = ClangASTType (m_ast, cast<clang::ParenType>(qual_type)->desugar()).GetNumVirtualBaseClasses();
+ break;
+
+ default:
+ break;
+ }
+ return count;
+}
+
+uint32_t
+ClangASTType::GetNumFields () const
+{
+ if (!IsValid())
+ return 0;
+
+ uint32_t count = 0;
+ QualType qual_type(GetCanonicalQualType());
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class)
+ {
+ case clang::Type::Record:
+ if (GetCompleteType())
+ {
+ const RecordType *record_type = dyn_cast<RecordType>(qual_type.getTypePtr());
+ if (record_type)
+ {
+ RecordDecl *record_decl = record_type->getDecl();
+ if (record_decl)
+ {
+ uint32_t field_idx = 0;
+ RecordDecl::field_iterator field, field_end;
+ for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field)
+ ++field_idx;
+ count = field_idx;
+ }
+ }
+ }
+ break;
+
+ case clang::Type::Typedef:
+ count = ClangASTType (m_ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetNumFields();
+ break;
+
+ case clang::Type::Elaborated:
+ count = ClangASTType (m_ast, cast<ElaboratedType>(qual_type)->getNamedType()).GetNumFields();
+ break;
+
+ case clang::Type::Paren:
+ count = ClangASTType (m_ast, cast<clang::ParenType>(qual_type)->desugar()).GetNumFields();
+ break;
+
+ case clang::Type::ObjCObjectPointer:
+ if (GetCompleteType())
+ {
+ const ObjCObjectPointerType *objc_class_type = qual_type->getAsObjCInterfacePointerType();
+ if (objc_class_type)
+ {
+ ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterfaceDecl();
+
+ if (class_interface_decl)
+ count = class_interface_decl->ivar_size();
+ }
+ }
+ break;
+
+ case clang::Type::ObjCObject:
+ case clang::Type::ObjCInterface:
+ if (GetCompleteType())
+ {
+ const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
+ if (objc_class_type)
+ {
+ ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
+
+ if (class_interface_decl)
+ count = class_interface_decl->ivar_size();
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ return count;
+}
+
+ClangASTType
+ClangASTType::GetDirectBaseClassAtIndex (size_t idx, uint32_t *bit_offset_ptr) const
+{
+ if (!IsValid())
+ return ClangASTType();
+
+ QualType qual_type(GetCanonicalQualType());
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class)
+ {
+ case clang::Type::Record:
+ if (GetCompleteType())
+ {
+ const CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
+ if (cxx_record_decl)
+ {
+ uint32_t curr_idx = 0;
+ CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
+ for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
+ base_class != base_class_end;
+ ++base_class, ++curr_idx)
+ {
+ if (curr_idx == idx)
+ {
+ if (bit_offset_ptr)
+ {
+ const ASTRecordLayout &record_layout = m_ast->getASTRecordLayout(cxx_record_decl);
+ const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
+ if (base_class->isVirtual())
+ *bit_offset_ptr = record_layout.getVBaseClassOffset(base_class_decl).getQuantity() * 8;
+ else
+ *bit_offset_ptr = record_layout.getBaseClassOffset(base_class_decl).getQuantity() * 8;
+ }
+ return ClangASTType (m_ast, base_class->getType());
+ }
+ }
+ }
+ }
+ break;
+
+ case clang::Type::ObjCObjectPointer:
+ if (idx == 0 && GetCompleteType())
+ {
+ const ObjCObjectPointerType *objc_class_type = qual_type->getAsObjCInterfacePointerType();
+ if (objc_class_type)
+ {
+ ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterfaceDecl();
+ if (class_interface_decl)
+ {
+ ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
+ if (superclass_interface_decl)
+ {
+ if (bit_offset_ptr)
+ *bit_offset_ptr = 0;
+ return ClangASTType (m_ast, m_ast->getObjCInterfaceType(superclass_interface_decl));
+ }
+ }
+ }
+ }
+ break;
+
+ case clang::Type::ObjCObject:
+ case clang::Type::ObjCInterface:
+ if (idx == 0 && GetCompleteType())
+ {
+ const ObjCObjectType *objc_class_type = qual_type->getAsObjCQualifiedInterfaceType();
+ if (objc_class_type)
+ {
+ ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
+
+ if (class_interface_decl)
+ {
+ ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
+ if (superclass_interface_decl)
+ {
+ if (bit_offset_ptr)
+ *bit_offset_ptr = 0;
+ return ClangASTType (m_ast, m_ast->getObjCInterfaceType(superclass_interface_decl));
+ }
+ }
+ }
+ }
+ break;
+
+
+ case clang::Type::Typedef:
+ return ClangASTType (m_ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetDirectBaseClassAtIndex (idx, bit_offset_ptr);
+
+ case clang::Type::Elaborated:
+ return ClangASTType (m_ast, cast<ElaboratedType>(qual_type)->getNamedType()).GetDirectBaseClassAtIndex (idx, bit_offset_ptr);
+
+ case clang::Type::Paren:
+ return ClangASTType (m_ast, cast<clang::ParenType>(qual_type)->desugar()).GetDirectBaseClassAtIndex (idx, bit_offset_ptr);
+
+ default:
+ break;
+ }
+ return ClangASTType();
+}
+
+ClangASTType
+ClangASTType::GetVirtualBaseClassAtIndex (size_t idx, uint32_t *bit_offset_ptr) const
+{
+ if (!IsValid())
+ return ClangASTType();
+
+ QualType qual_type(GetCanonicalQualType());
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class)
+ {
+ case clang::Type::Record:
+ if (GetCompleteType())
+ {
+ const CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
+ if (cxx_record_decl)
+ {
+ uint32_t curr_idx = 0;
+ CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
+ for (base_class = cxx_record_decl->vbases_begin(), base_class_end = cxx_record_decl->vbases_end();
+ base_class != base_class_end;
+ ++base_class, ++curr_idx)
+ {
+ if (curr_idx == idx)
+ {
+ if (bit_offset_ptr)
+ {
+ const ASTRecordLayout &record_layout = m_ast->getASTRecordLayout(cxx_record_decl);
+ const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
+ *bit_offset_ptr = record_layout.getVBaseClassOffset(base_class_decl).getQuantity() * 8;
+
+ }
+ return ClangASTType (m_ast, base_class->getType());
+ }
+ }
+ }
+ }
+ break;
+
+ case clang::Type::Typedef:
+ return ClangASTType (m_ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetVirtualBaseClassAtIndex (idx, bit_offset_ptr);
+
+ case clang::Type::Elaborated:
+ return ClangASTType (m_ast, cast<ElaboratedType>(qual_type)->getNamedType()).GetVirtualBaseClassAtIndex (idx, bit_offset_ptr);
+
+ case clang::Type::Paren:
+ return ClangASTType (m_ast, cast<clang::ParenType>(qual_type)->desugar()).GetVirtualBaseClassAtIndex (idx, bit_offset_ptr);
+
+ default:
+ break;
+ }
+ return ClangASTType();
+}
+
+static clang_type_t
+GetObjCFieldAtIndex (clang::ASTContext *ast,
+ ObjCInterfaceDecl *class_interface_decl,
+ size_t idx,
+ std::string& name,
+ uint64_t *bit_offset_ptr,
+ uint32_t *bitfield_bit_size_ptr,
+ bool *is_bitfield_ptr)
+{
+ if (class_interface_decl)
+ {
+ if (idx < (class_interface_decl->ivar_size()))
+ {
+ ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
+ uint32_t ivar_idx = 0;
+
+ for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos, ++ivar_idx)
+ {
+ if (ivar_idx == idx)
+ {
+ const ObjCIvarDecl* ivar_decl = *ivar_pos;
+
+ QualType ivar_qual_type(ivar_decl->getType());
+
+ name.assign(ivar_decl->getNameAsString());
+
+ if (bit_offset_ptr)
+ {
+ const ASTRecordLayout &interface_layout = ast->getASTObjCInterfaceLayout(class_interface_decl);
+ *bit_offset_ptr = interface_layout.getFieldOffset (ivar_idx);
+ }
+
+ const bool is_bitfield = ivar_pos->isBitField();
+
+ if (bitfield_bit_size_ptr)
+ {
+ *bitfield_bit_size_ptr = 0;
+
+ if (is_bitfield && ast)
+ {
+ Expr *bitfield_bit_size_expr = ivar_pos->getBitWidth();
+ llvm::APSInt bitfield_apsint;
+ if (bitfield_bit_size_expr && bitfield_bit_size_expr->EvaluateAsInt(bitfield_apsint, *ast))
+ {
+ *bitfield_bit_size_ptr = bitfield_apsint.getLimitedValue();
+ }
+ }
+ }
+ if (is_bitfield_ptr)
+ *is_bitfield_ptr = is_bitfield;
+
+ return ivar_qual_type.getAsOpaquePtr();
+ }
+ }
+ }
+ }
+ return NULL;
+}
+
+ClangASTType
+ClangASTType::GetFieldAtIndex (size_t idx,
+ std::string& name,
+ uint64_t *bit_offset_ptr,
+ uint32_t *bitfield_bit_size_ptr,
+ bool *is_bitfield_ptr) const
+{
+ if (!IsValid())
+ return ClangASTType();
+
+ QualType qual_type(GetCanonicalQualType());
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class)
+ {
+ case clang::Type::Record:
+ if (GetCompleteType())
+ {
+ const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
+ const RecordDecl *record_decl = record_type->getDecl();
+ uint32_t field_idx = 0;
+ RecordDecl::field_iterator field, field_end;
+ for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field, ++field_idx)
+ {
+ if (idx == field_idx)
+ {
+ // Print the member type if requested
+ // Print the member name and equal sign
+ name.assign(field->getNameAsString());
+
+ // Figure out the type byte size (field_type_info.first) and
+ // alignment (field_type_info.second) from the AST context.
+ if (bit_offset_ptr)
+ {
+ const ASTRecordLayout &record_layout = m_ast->getASTRecordLayout(record_decl);
+ *bit_offset_ptr = record_layout.getFieldOffset (field_idx);
+ }
+
+ const bool is_bitfield = field->isBitField();
+
+ if (bitfield_bit_size_ptr)
+ {
+ *bitfield_bit_size_ptr = 0;
+
+ if (is_bitfield)
+ {
+ Expr *bitfield_bit_size_expr = field->getBitWidth();
+ llvm::APSInt bitfield_apsint;
+ if (bitfield_bit_size_expr && bitfield_bit_size_expr->EvaluateAsInt(bitfield_apsint, *m_ast))
+ {
+ *bitfield_bit_size_ptr = bitfield_apsint.getLimitedValue();
+ }
+ }
+ }
+ if (is_bitfield_ptr)
+ *is_bitfield_ptr = is_bitfield;
+
+ return ClangASTType (m_ast, field->getType());
+ }
+ }
+ }
+ break;
+
+ case clang::Type::ObjCObjectPointer:
+ if (GetCompleteType())
+ {
+ const ObjCObjectPointerType *objc_class_type = qual_type->getAsObjCInterfacePointerType();
+ if (objc_class_type)
+ {
+ ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterfaceDecl();
+ return ClangASTType (m_ast, GetObjCFieldAtIndex(m_ast, class_interface_decl, idx, name, bit_offset_ptr, bitfield_bit_size_ptr, is_bitfield_ptr));
+ }
+ }
+ break;
+
+ case clang::Type::ObjCObject:
+ case clang::Type::ObjCInterface:
+ if (GetCompleteType())
+ {
+ const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
+ assert (objc_class_type);
+ if (objc_class_type)
+ {
+ ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
+ return ClangASTType (m_ast, GetObjCFieldAtIndex(m_ast, class_interface_decl, idx, name, bit_offset_ptr, bitfield_bit_size_ptr, is_bitfield_ptr));
+ }
+ }
+ break;
+
+
+ case clang::Type::Typedef:
+ return ClangASTType (m_ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()).
+ GetFieldAtIndex (idx,
+ name,
+ bit_offset_ptr,
+ bitfield_bit_size_ptr,
+ is_bitfield_ptr);
+
+ case clang::Type::Elaborated:
+ return ClangASTType (m_ast, cast<ElaboratedType>(qual_type)->getNamedType()).
+ GetFieldAtIndex (idx,
+ name,
+ bit_offset_ptr,
+ bitfield_bit_size_ptr,
+ is_bitfield_ptr);
+
+ case clang::Type::Paren:
+ return ClangASTType (m_ast, cast<clang::ParenType>(qual_type)->desugar()).
+ GetFieldAtIndex (idx,
+ name,
+ bit_offset_ptr,
+ bitfield_bit_size_ptr,
+ is_bitfield_ptr);
+
+ default:
+ break;
+ }
+ return ClangASTType();
+}
+
+uint32_t
+ClangASTType::GetIndexOfFieldWithName (const char* name,
+ ClangASTType* field_clang_type_ptr,
+ uint64_t *bit_offset_ptr,
+ uint32_t *bitfield_bit_size_ptr,
+ bool *is_bitfield_ptr) const
+{
+ unsigned count = GetNumFields();
+ std::string field_name;
+ for (unsigned index = 0; index < count; index++)
+ {
+ ClangASTType field_clang_type (GetFieldAtIndex(index, field_name, bit_offset_ptr, bitfield_bit_size_ptr, is_bitfield_ptr));
+ if (strcmp(field_name.c_str(), name) == 0)
+ {
+ if (field_clang_type_ptr)
+ *field_clang_type_ptr = field_clang_type;
+ return index;
+ }
+ }
+ return UINT32_MAX;
+}
+
+// If a pointer to a pointee type (the clang_type arg) says that it has no
+// children, then we either need to trust it, or override it and return a
+// different result. For example, an "int *" has one child that is an integer,
+// but a function pointer doesn't have any children. Likewise if a Record type
+// claims it has no children, then there really is nothing to show.
+uint32_t
+ClangASTType::GetNumPointeeChildren () const
+{
+ if (!IsValid())
+ return 0;
+
+ QualType qual_type(GetCanonicalQualType());
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class)
+ {
+ case clang::Type::Builtin:
+ switch (cast<clang::BuiltinType>(qual_type)->getKind())
+ {
+ case clang::BuiltinType::UnknownAny:
+ 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::OCLSampler:
+ return 0;
+ case clang::BuiltinType::Bool:
+ case clang::BuiltinType::Char_U:
+ case clang::BuiltinType::UChar:
+ case clang::BuiltinType::WChar_U:
+ case clang::BuiltinType::Char16:
+ case clang::BuiltinType::Char32:
+ case clang::BuiltinType::UShort:
+ case clang::BuiltinType::UInt:
+ case clang::BuiltinType::ULong:
+ case clang::BuiltinType::ULongLong:
+ case clang::BuiltinType::UInt128:
+ case clang::BuiltinType::Char_S:
+ case clang::BuiltinType::SChar:
+ case clang::BuiltinType::WChar_S:
+ case clang::BuiltinType::Short:
+ case clang::BuiltinType::Int:
+ case clang::BuiltinType::Long:
+ case clang::BuiltinType::LongLong:
+ case clang::BuiltinType::Int128:
+ case clang::BuiltinType::Float:
+ case clang::BuiltinType::Double:
+ case clang::BuiltinType::LongDouble:
+ case clang::BuiltinType::Dependent:
+ case clang::BuiltinType::Overload:
+ case clang::BuiltinType::ObjCId:
+ case clang::BuiltinType::ObjCClass:
+ case clang::BuiltinType::ObjCSel:
+ case clang::BuiltinType::BoundMember:
+ case clang::BuiltinType::Half:
+ case clang::BuiltinType::ARCUnbridgedCast:
+ case clang::BuiltinType::PseudoObject:
+ case clang::BuiltinType::BuiltinFn:
+ return 1;
+ }
+ break;
+
+ case clang::Type::Complex: return 1;
+ case clang::Type::Pointer: return 1;
+ case clang::Type::BlockPointer: return 0; // If block pointers don't have debug info, then no children for them
+ case clang::Type::LValueReference: return 1;
+ case clang::Type::RValueReference: return 1;
+ case clang::Type::MemberPointer: return 0;
+ case clang::Type::ConstantArray: return 0;
+ case clang::Type::IncompleteArray: return 0;
+ case clang::Type::VariableArray: return 0;
+ case clang::Type::DependentSizedArray: return 0;
+ case clang::Type::DependentSizedExtVector: return 0;
+ case clang::Type::Vector: return 0;
+ case clang::Type::ExtVector: return 0;
+ case clang::Type::FunctionProto: return 0; // When we function pointers, they have no children...
+ case clang::Type::FunctionNoProto: return 0; // When we function pointers, they have no children...
+ case clang::Type::UnresolvedUsing: return 0;
+ case clang::Type::Paren: return ClangASTType (m_ast, cast<clang::ParenType>(qual_type)->desugar()).GetNumPointeeChildren ();
+ case clang::Type::Typedef: return ClangASTType (m_ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetNumPointeeChildren ();
+ case clang::Type::Elaborated: return ClangASTType (m_ast, cast<ElaboratedType>(qual_type)->getNamedType()).GetNumPointeeChildren ();
+ case clang::Type::TypeOfExpr: return 0;
+ case clang::Type::TypeOf: return 0;
+ case clang::Type::Decltype: return 0;
+ case clang::Type::Record: return 0;
+ case clang::Type::Enum: return 1;
+ case clang::Type::TemplateTypeParm: return 1;
+ case clang::Type::SubstTemplateTypeParm: return 1;
+ case clang::Type::TemplateSpecialization: return 1;
+ case clang::Type::InjectedClassName: return 0;
+ case clang::Type::DependentName: return 1;
+ case clang::Type::DependentTemplateSpecialization: return 1;
+ case clang::Type::ObjCObject: return 0;
+ case clang::Type::ObjCInterface: return 0;
+ case clang::Type::ObjCObjectPointer: return 1;
+ default:
+ break;
+ }
+ return 0;
+}
+
+
+ClangASTType
+ClangASTType::GetChildClangTypeAtIndex (ExecutionContext *exe_ctx,
+ const char *parent_name,
+ 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) const
+{
+ if (!IsValid())
+ return ClangASTType();
+
+ QualType parent_qual_type(GetCanonicalQualType());
+ const clang::Type::TypeClass parent_type_class = parent_qual_type->getTypeClass();
+ child_bitfield_bit_size = 0;
+ child_bitfield_bit_offset = 0;
+ child_is_base_class = false;
+
+ const bool idx_is_valid = idx < GetNumChildren (omit_empty_base_classes);
+ uint32_t bit_offset;
+ switch (parent_type_class)
+ {
+ case clang::Type::Builtin:
+ if (idx_is_valid)
+ {
+ switch (cast<clang::BuiltinType>(parent_qual_type)->getKind())
+ {
+ case clang::BuiltinType::ObjCId:
+ case clang::BuiltinType::ObjCClass:
+ child_name = "isa";
+ child_byte_size = m_ast->getTypeSize(m_ast->ObjCBuiltinClassTy) / CHAR_BIT;
+ return ClangASTType (m_ast, m_ast->ObjCBuiltinClassTy);
+
+ default:
+ break;
+ }
+ }
+ break;
+
+ case clang::Type::Record:
+ if (idx_is_valid && GetCompleteType())
+ {
+ const RecordType *record_type = cast<RecordType>(parent_qual_type.getTypePtr());
+ const RecordDecl *record_decl = record_type->getDecl();
+ assert(record_decl);
+ const ASTRecordLayout &record_layout = m_ast->getASTRecordLayout(record_decl);
+ uint32_t child_idx = 0;
+
+ const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
+ if (cxx_record_decl)
+ {
+ // We might have base classes to print out first
+ CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
+ for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
+ base_class != base_class_end;
+ ++base_class)
+ {
+ const CXXRecordDecl *base_class_decl = NULL;
+
+ // Skip empty base classes
+ if (omit_empty_base_classes)
+ {
+ base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
+ if (ClangASTContext::RecordHasFields(base_class_decl) == false)
+ continue;
+ }
+
+ if (idx == child_idx)
+ {
+ if (base_class_decl == NULL)
+ base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
+
+
+ if (base_class->isVirtual())
+ bit_offset = record_layout.getVBaseClassOffset(base_class_decl).getQuantity() * 8;
+ else
+ bit_offset = record_layout.getBaseClassOffset(base_class_decl).getQuantity() * 8;
+
+ // Base classes should be a multiple of 8 bits in size
+ child_byte_offset = bit_offset/8;
+ ClangASTType base_class_clang_type(m_ast, base_class->getType());
+ child_name = base_class_clang_type.GetTypeName();
+ uint64_t base_class_clang_type_bit_size = base_class_clang_type.GetBitSize();
+
+ // Base classes bit sizes should be a multiple of 8 bits in size
+ assert (base_class_clang_type_bit_size % 8 == 0);
+ child_byte_size = base_class_clang_type_bit_size / 8;
+ child_is_base_class = true;
+ return base_class_clang_type;
+ }
+ // We don't increment the child index in the for loop since we might
+ // be skipping empty base classes
+ ++child_idx;
+ }
+ }
+ // Make sure index is in range...
+ uint32_t field_idx = 0;
+ RecordDecl::field_iterator field, field_end;
+ for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field, ++field_idx, ++child_idx)
+ {
+ if (idx == child_idx)
+ {
+ // Print the member type if requested
+ // Print the member name and equal sign
+ child_name.assign(field->getNameAsString().c_str());
+
+ // Figure out the type byte size (field_type_info.first) and
+ // alignment (field_type_info.second) from the AST context.
+ ClangASTType field_clang_type (m_ast, field->getType());
+ assert(field_idx < record_layout.getFieldCount());
+ child_byte_size = field_clang_type.GetByteSize();
+
+ // 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 (m_ast, *field, child_bitfield_bit_size))
+ child_bitfield_bit_offset = bit_offset % 8;
+
+ return field_clang_type;
+ }
+ }
+ }
+ break;
+
+ case clang::Type::ObjCObject:
+ case clang::Type::ObjCInterface:
+ if (idx_is_valid && GetCompleteType())
+ {
+ const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(parent_qual_type.getTypePtr());
+ assert (objc_class_type);
+ if (objc_class_type)
+ {
+ uint32_t child_idx = 0;
+ ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
+
+ if (class_interface_decl)
+ {
+
+ const ASTRecordLayout &interface_layout = m_ast->getASTObjCInterfaceLayout(class_interface_decl);
+ ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
+ if (superclass_interface_decl)
+ {
+ if (omit_empty_base_classes)
+ {
+ ClangASTType base_class_clang_type (m_ast, m_ast->getObjCInterfaceType(superclass_interface_decl));
+ if (base_class_clang_type.GetNumChildren(omit_empty_base_classes) > 0)
+ {
+ if (idx == 0)
+ {
+ QualType ivar_qual_type(m_ast->getObjCInterfaceType(superclass_interface_decl));
+
+
+ child_name.assign(superclass_interface_decl->getNameAsString().c_str());
+
+ std::pair<uint64_t, unsigned> ivar_type_info = m_ast->getTypeInfo(ivar_qual_type.getTypePtr());
+
+ child_byte_size = ivar_type_info.first / 8;
+ child_byte_offset = 0;
+ child_is_base_class = true;
+
+ return ClangASTType (m_ast, ivar_qual_type);
+ }
+
+ ++child_idx;
+ }
+ }
+ else
+ ++child_idx;
+ }
+
+ const uint32_t superclass_idx = child_idx;
+
+ if (idx < (child_idx + class_interface_decl->ivar_size()))
+ {
+ ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
+
+ for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos)
+ {
+ if (child_idx == idx)
+ {
+ ObjCIvarDecl* ivar_decl = *ivar_pos;
+
+ QualType ivar_qual_type(ivar_decl->getType());
+
+ child_name.assign(ivar_decl->getNameAsString().c_str());
+
+ std::pair<uint64_t, unsigned> ivar_type_info = m_ast->getTypeInfo(ivar_qual_type.getTypePtr());
+
+ child_byte_size = ivar_type_info.first / 8;
+
+ // Figure out the field offset within the current struct/union/class type
+ // For ObjC objects, we can't trust the bit offset we get from the Clang AST, since
+ // that doesn't account for the space taken up by unbacked properties, or from
+ // the changing size of base classes that are newer than this class.
+ // So if we have a process around that we can ask about this object, do so.
+ child_byte_offset = LLDB_INVALID_IVAR_OFFSET;
+ Process *process = NULL;
+ if (exe_ctx)
+ process = exe_ctx->GetProcessPtr();
+ if (process)
+ {
+ ObjCLanguageRuntime *objc_runtime = process->GetObjCLanguageRuntime();
+ if (objc_runtime != NULL)
+ {
+ ClangASTType parent_ast_type (m_ast, parent_qual_type);
+ child_byte_offset = objc_runtime->GetByteOffsetForIvar (parent_ast_type, ivar_decl->getNameAsString().c_str());
+ }
+ }
+
+ // Setting this to UINT32_MAX to make sure we don't compute it twice...
+ bit_offset = UINT32_MAX;
+
+ if (child_byte_offset == LLDB_INVALID_IVAR_OFFSET)
+ {
+ bit_offset = interface_layout.getFieldOffset (child_idx - superclass_idx);
+ child_byte_offset = bit_offset / 8;
+ }
+
+ // Note, the ObjC Ivar Byte offset is just that, it doesn't account for the bit offset
+ // of a bitfield within its containing object. So regardless of where we get the byte
+ // offset from, we still need to get the bit offset for bitfields from the layout.
+
+ if (ClangASTContext::FieldIsBitfield (m_ast, ivar_decl, child_bitfield_bit_size))
+ {
+ if (bit_offset == UINT32_MAX)
+ bit_offset = interface_layout.getFieldOffset (child_idx - superclass_idx);
+
+ child_bitfield_bit_offset = bit_offset % 8;
+ }
+ return ClangASTType (m_ast, ivar_qual_type);
+ }
+ ++child_idx;
+ }
+ }
+ }
+ }
+ }
+ break;
+
+ case clang::Type::ObjCObjectPointer:
+ if (idx_is_valid)
+ {
+ ClangASTType pointee_clang_type (GetPointeeType());
+
+ if (transparent_pointers && pointee_clang_type.IsAggregateType())
+ {
+ child_is_deref_of_parent = false;
+ bool tmp_child_is_deref_of_parent = false;
+ return pointee_clang_type.GetChildClangTypeAtIndex (exe_ctx,
+ parent_name,
+ 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,
+ tmp_child_is_deref_of_parent);
+ }
+ else
+ {
+ child_is_deref_of_parent = true;
+ if (parent_name)
+ {
+ child_name.assign(1, '*');
+ child_name += parent_name;
+ }
+
+ // We have a pointer to an simple type
+ if (idx == 0 && pointee_clang_type.GetCompleteType())
+ {
+ child_byte_size = pointee_clang_type.GetByteSize();
+ child_byte_offset = 0;
+ return pointee_clang_type;
+ }
+ }
+ }
+ break;
+
+ case clang::Type::Vector:
+ case clang::Type::ExtVector:
+ if (idx_is_valid)
+ {
+ const VectorType *array = cast<VectorType>(parent_qual_type.getTypePtr());
+ if (array)
+ {
+ ClangASTType element_type (m_ast, array->getElementType());
+ if (element_type.GetCompleteType())
+ {
+ char element_name[64];
+ ::snprintf (element_name, sizeof (element_name), "[%zu]", idx);
+ child_name.assign(element_name);
+ child_byte_size = element_type.GetByteSize();
+ child_byte_offset = (int32_t)idx * (int32_t)child_byte_size;
+ return element_type;
+ }
+ }
+ }
+ break;
+
+ case clang::Type::ConstantArray:
+ case clang::Type::IncompleteArray:
+ if (ignore_array_bounds || idx_is_valid)
+ {
+ const ArrayType *array = cast<ArrayType>(parent_qual_type.getTypePtr());
+ if (array)
+ {
+ ClangASTType element_type (m_ast, array->getElementType());
+ if (element_type.GetCompleteType())
+ {
+ char element_name[64];
+ ::snprintf (element_name, sizeof (element_name), "[%zu]", idx);
+ child_name.assign(element_name);
+ child_byte_size = element_type.GetByteSize();
+ child_byte_offset = (int32_t)idx * (int32_t)child_byte_size;
+ return element_type;
+ }
+ }
+ }
+ break;
+
+
+ case clang::Type::Pointer:
+ if (idx_is_valid)
+ {
+ ClangASTType pointee_clang_type (GetPointeeType());
+
+ // Don't dereference "void *" pointers
+ if (pointee_clang_type.IsVoidType())
+ return ClangASTType();
+
+ if (transparent_pointers && pointee_clang_type.IsAggregateType ())
+ {
+ child_is_deref_of_parent = false;
+ bool tmp_child_is_deref_of_parent = false;
+ return pointee_clang_type.GetChildClangTypeAtIndex (exe_ctx,
+ parent_name,
+ 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,
+ tmp_child_is_deref_of_parent);
+ }
+ else
+ {
+ child_is_deref_of_parent = true;
+
+ if (parent_name)
+ {
+ child_name.assign(1, '*');
+ child_name += parent_name;
+ }
+
+ // We have a pointer to an simple type
+ if (idx == 0)
+ {
+ child_byte_size = pointee_clang_type.GetByteSize();
+ child_byte_offset = 0;
+ return pointee_clang_type;
+ }
+ }
+ }
+ break;
+
+ case clang::Type::LValueReference:
+ case clang::Type::RValueReference:
+ if (idx_is_valid)
+ {
+ const ReferenceType *reference_type = cast<ReferenceType>(parent_qual_type.getTypePtr());
+ ClangASTType pointee_clang_type (m_ast, reference_type->getPointeeType());
+ if (transparent_pointers && pointee_clang_type.IsAggregateType ())
+ {
+ child_is_deref_of_parent = false;
+ bool tmp_child_is_deref_of_parent = false;
+ return pointee_clang_type.GetChildClangTypeAtIndex (exe_ctx,
+ parent_name,
+ 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,
+ tmp_child_is_deref_of_parent);
+ }
+ else
+ {
+ if (parent_name)
+ {
+ child_name.assign(1, '&');
+ child_name += parent_name;
+ }
+
+ // We have a pointer to an simple type
+ if (idx == 0)
+ {
+ child_byte_size = pointee_clang_type.GetByteSize();
+ child_byte_offset = 0;
+ return pointee_clang_type;
+ }
+ }
+ }
+ break;
+
+ case clang::Type::Typedef:
+ {
+ ClangASTType typedefed_clang_type (m_ast, cast<TypedefType>(parent_qual_type)->getDecl()->getUnderlyingType());
+ return typedefed_clang_type.GetChildClangTypeAtIndex (exe_ctx,
+ parent_name,
+ 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);
+ }
+ break;
+
+ case clang::Type::Elaborated:
+ {
+ ClangASTType elaborated_clang_type (m_ast, cast<ElaboratedType>(parent_qual_type)->getNamedType());
+ return elaborated_clang_type.GetChildClangTypeAtIndex (exe_ctx,
+ parent_name,
+ 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);
+ }
+
+ case clang::Type::Paren:
+ {
+ ClangASTType paren_clang_type (m_ast, llvm::cast<clang::ParenType>(parent_qual_type)->desugar());
+ return paren_clang_type.GetChildClangTypeAtIndex (exe_ctx,
+ parent_name,
+ 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);
+ }
+
+
+ default:
+ break;
+ }
+ return ClangASTType();
+}
+
+static inline bool
+BaseSpecifierIsEmpty (const CXXBaseSpecifier *b)
+{
+ return ClangASTContext::RecordHasFields(b->getType()->getAsCXXRecordDecl()) == false;
+}
+
+static uint32_t
+GetIndexForRecordBase
+(
+ const RecordDecl *record_decl,
+ const CXXBaseSpecifier *base_spec,
+ bool omit_empty_base_classes
+ )
+{
+ uint32_t child_idx = 0;
+
+ const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
+
+ // const char *super_name = record_decl->getNameAsCString();
+ // const char *base_name = base_spec->getType()->getAs<RecordType>()->getDecl()->getNameAsCString();
+ // printf ("GetIndexForRecordChild (%s, %s)\n", super_name, base_name);
+ //
+ if (cxx_record_decl)
+ {
+ CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
+ for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
+ base_class != base_class_end;
+ ++base_class)
+ {
+ if (omit_empty_base_classes)
+ {
+ if (BaseSpecifierIsEmpty (base_class))
+ continue;
+ }
+
+ // printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n", super_name, base_name,
+ // child_idx,
+ // base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString());
+ //
+ //
+ if (base_class == base_spec)
+ return child_idx;
+ ++child_idx;
+ }
+ }
+
+ return UINT32_MAX;
+}
+
+
+static uint32_t
+GetIndexForRecordChild (const RecordDecl *record_decl,
+ NamedDecl *canonical_decl,
+ bool omit_empty_base_classes)
+{
+ uint32_t child_idx = ClangASTContext::GetNumBaseClasses (dyn_cast<CXXRecordDecl>(record_decl),
+ omit_empty_base_classes);
+
+ RecordDecl::field_iterator field, field_end;
+ for (field = record_decl->field_begin(), field_end = record_decl->field_end();
+ field != field_end;
+ ++field, ++child_idx)
+ {
+ if (field->getCanonicalDecl() == canonical_decl)
+ return child_idx;
+ }
+
+ return UINT32_MAX;
+}
+
+// Look for a child member (doesn't include base classes, but it does include
+// their members) in the type hierarchy. Returns an index path into "clang_type"
+// on how to reach the appropriate member.
+//
+// class A
+// {
+// public:
+// int m_a;
+// int m_b;
+// };
+//
+// class B
+// {
+// };
+//
+// class C :
+// public B,
+// public A
+// {
+// };
+//
+// If we have a clang type that describes "class C", and we wanted to looked
+// "m_b" in it:
+//
+// With omit_empty_base_classes == false we would get an integer array back with:
+// { 1, 1 }
+// The first index 1 is the child index for "class A" within class C
+// The second index 1 is the child index for "m_b" within class A
+//
+// With omit_empty_base_classes == true we would get an integer array back with:
+// { 0, 1 }
+// The first index 0 is the child index for "class A" within class C (since class B doesn't have any members it doesn't count)
+// The second index 1 is the child index for "m_b" within class A
+
+size_t
+ClangASTType::GetIndexOfChildMemberWithName (const char *name,
+ bool omit_empty_base_classes,
+ std::vector<uint32_t>& child_indexes) const
+{
+ if (IsValid() && name && name[0])
+ {
+ QualType qual_type(GetCanonicalQualType());
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class)
+ {
+ case clang::Type::Record:
+ if (GetCompleteType ())
+ {
+ const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
+ const RecordDecl *record_decl = record_type->getDecl();
+
+ assert(record_decl);
+ uint32_t child_idx = 0;
+
+ const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
+
+ // Try and find a field that matches NAME
+ RecordDecl::field_iterator field, field_end;
+ StringRef name_sref(name);
+ for (field = record_decl->field_begin(), field_end = record_decl->field_end();
+ field != field_end;
+ ++field, ++child_idx)
+ {
+ if (field->getName().equals (name_sref))
+ {
+ // We have to add on the number of base classes to this index!
+ child_indexes.push_back (child_idx + ClangASTContext::GetNumBaseClasses (cxx_record_decl, omit_empty_base_classes));
+ return child_indexes.size();
+ }
+ }
+
+ if (cxx_record_decl)
+ {
+ const RecordDecl *parent_record_decl = cxx_record_decl;
+
+ //printf ("parent = %s\n", parent_record_decl->getNameAsCString());
+
+ //const Decl *root_cdecl = cxx_record_decl->getCanonicalDecl();
+ // Didn't find things easily, lets let clang do its thang...
+ IdentifierInfo & ident_ref = m_ast->Idents.get(name_sref);
+ DeclarationName decl_name(&ident_ref);
+
+ CXXBasePaths paths;
+ if (cxx_record_decl->lookupInBases(CXXRecordDecl::FindOrdinaryMember,
+ decl_name.getAsOpaquePtr(),
+ paths))
+ {
+ CXXBasePaths::const_paths_iterator path, path_end = paths.end();
+ for (path = paths.begin(); path != path_end; ++path)
+ {
+ const size_t num_path_elements = path->size();
+ for (size_t e=0; e<num_path_elements; ++e)
+ {
+ CXXBasePathElement elem = (*path)[e];
+
+ child_idx = GetIndexForRecordBase (parent_record_decl, elem.Base, omit_empty_base_classes);
+ if (child_idx == UINT32_MAX)
+ {
+ child_indexes.clear();
+ return 0;
+ }
+ else
+ {
+ child_indexes.push_back (child_idx);
+ parent_record_decl = cast<RecordDecl>(elem.Base->getType()->getAs<RecordType>()->getDecl());
+ }
+ }
+ for (NamedDecl *path_decl : path->Decls)
+ {
+ child_idx = GetIndexForRecordChild (parent_record_decl, path_decl, omit_empty_base_classes);
+ if (child_idx == UINT32_MAX)
+ {
+ child_indexes.clear();
+ return 0;
+ }
+ else
+ {
+ child_indexes.push_back (child_idx);
+ }
+ }
+ }
+ return child_indexes.size();
+ }
+ }
+
+ }
+ break;
+
+ case clang::Type::ObjCObject:
+ case clang::Type::ObjCInterface:
+ if (GetCompleteType ())
+ {
+ StringRef name_sref(name);
+ const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
+ assert (objc_class_type);
+ if (objc_class_type)
+ {
+ uint32_t child_idx = 0;
+ ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
+
+ if (class_interface_decl)
+ {
+ ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
+ ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
+
+ for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos, ++child_idx)
+ {
+ const ObjCIvarDecl* ivar_decl = *ivar_pos;
+
+ if (ivar_decl->getName().equals (name_sref))
+ {
+ if ((!omit_empty_base_classes && superclass_interface_decl) ||
+ ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true)))
+ ++child_idx;
+
+ child_indexes.push_back (child_idx);
+ return child_indexes.size();
+ }
+ }
+
+ if (superclass_interface_decl)
+ {
+ // The super class index is always zero for ObjC classes,
+ // so we push it onto the child indexes in case we find
+ // an ivar in our superclass...
+ child_indexes.push_back (0);
+
+ ClangASTType superclass_clang_type (m_ast, m_ast->getObjCInterfaceType(superclass_interface_decl));
+ if (superclass_clang_type.GetIndexOfChildMemberWithName (name,
+ omit_empty_base_classes,
+ child_indexes))
+ {
+ // We did find an ivar in a superclass so just
+ // return the results!
+ return child_indexes.size();
+ }
+
+ // We didn't find an ivar matching "name" in our
+ // superclass, pop the superclass zero index that
+ // we pushed on above.
+ child_indexes.pop_back();
+ }
+ }
+ }
+ }
+ break;
+
+ case clang::Type::ObjCObjectPointer:
+ {
+ ClangASTType objc_object_clang_type (m_ast, cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType());
+ return objc_object_clang_type.GetIndexOfChildMemberWithName (name,
+ omit_empty_base_classes,
+ child_indexes);
+ }
+ break;
+
+
+ case clang::Type::ConstantArray:
+ {
+ // const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
+ // const uint64_t element_count = array->getSize().getLimitedValue();
+ //
+ // if (idx < element_count)
+ // {
+ // std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(array->getElementType());
+ //
+ // char element_name[32];
+ // ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
+ //
+ // child_name.assign(element_name);
+ // assert(field_type_info.first % 8 == 0);
+ // child_byte_size = field_type_info.first / 8;
+ // child_byte_offset = idx * child_byte_size;
+ // return array->getElementType().getAsOpaquePtr();
+ // }
+ }
+ break;
+
+ // case clang::Type::MemberPointerType:
+ // {
+ // MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr());
+ // QualType pointee_type = mem_ptr_type->getPointeeType();
+ //
+ // if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
+ // {
+ // return GetIndexOfChildWithName (ast,
+ // mem_ptr_type->getPointeeType().getAsOpaquePtr(),
+ // name);
+ // }
+ // }
+ // break;
+ //
+ case clang::Type::LValueReference:
+ case clang::Type::RValueReference:
+ {
+ const ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
+ QualType pointee_type(reference_type->getPointeeType());
+ ClangASTType pointee_clang_type (m_ast, pointee_type);
+
+ if (pointee_clang_type.IsAggregateType ())
+ {
+ return pointee_clang_type.GetIndexOfChildMemberWithName (name,
+ omit_empty_base_classes,
+ child_indexes);
+ }
+ }
+ break;
+
+ case clang::Type::Pointer:
+ {
+ ClangASTType pointee_clang_type (GetPointeeType());
+
+ if (pointee_clang_type.IsAggregateType ())
+ {
+ return pointee_clang_type.GetIndexOfChildMemberWithName (name,
+ omit_empty_base_classes,
+ child_indexes);
+ }
+ }
+ break;
+
+ case clang::Type::Typedef:
+ return ClangASTType (m_ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetIndexOfChildMemberWithName (name,
+ omit_empty_base_classes,
+ child_indexes);
+
+ case clang::Type::Elaborated:
+ return ClangASTType (m_ast, cast<ElaboratedType>(qual_type)->getNamedType()).GetIndexOfChildMemberWithName (name,
+ omit_empty_base_classes,
+ child_indexes);
+
+ case clang::Type::Paren:
+ return ClangASTType (m_ast, cast<clang::ParenType>(qual_type)->desugar()).GetIndexOfChildMemberWithName (name,
+ omit_empty_base_classes,
+ child_indexes);
+
+ default:
+ break;
+ }
+ }
+ return 0;
+}
+
+
+// Get the index of the child of "clang_type" whose name matches. This function
+// doesn't descend into the children, but only looks one level deep and name
+// matches can include base class names.
+
+uint32_t
+ClangASTType::GetIndexOfChildWithName (const char *name, bool omit_empty_base_classes) const
+{
+ if (IsValid() && name && name[0])
+ {
+ QualType qual_type(GetCanonicalQualType());
+
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+
+ switch (type_class)
+ {
+ case clang::Type::Record:
+ if (GetCompleteType ())
+ {
+ const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
+ const RecordDecl *record_decl = record_type->getDecl();
+
+ assert(record_decl);
+ uint32_t child_idx = 0;
+
+ const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
+
+ if (cxx_record_decl)
+ {
+ CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
+ for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
+ base_class != base_class_end;
+ ++base_class)
+ {
+ // Skip empty base classes
+ CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
+ if (omit_empty_base_classes && ClangASTContext::RecordHasFields(base_class_decl) == false)
+ continue;
+
+ ClangASTType base_class_clang_type (m_ast, base_class->getType());
+ std::string base_class_type_name (base_class_clang_type.GetTypeName());
+ if (base_class_type_name.compare (name) == 0)
+ return child_idx;
+ ++child_idx;
+ }
+ }
+
+ // Try and find a field that matches NAME
+ RecordDecl::field_iterator field, field_end;
+ StringRef name_sref(name);
+ for (field = record_decl->field_begin(), field_end = record_decl->field_end();
+ field != field_end;
+ ++field, ++child_idx)
+ {
+ if (field->getName().equals (name_sref))
+ return child_idx;
+ }
+
+ }
+ break;
+
+ case clang::Type::ObjCObject:
+ case clang::Type::ObjCInterface:
+ if (GetCompleteType())
+ {
+ StringRef name_sref(name);
+ const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
+ assert (objc_class_type);
+ if (objc_class_type)
+ {
+ uint32_t child_idx = 0;
+ ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
+
+ if (class_interface_decl)
+ {
+ ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
+ ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
+
+ for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos, ++child_idx)
+ {
+ const ObjCIvarDecl* ivar_decl = *ivar_pos;
+
+ if (ivar_decl->getName().equals (name_sref))
+ {
+ if ((!omit_empty_base_classes && superclass_interface_decl) ||
+ ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true)))
+ ++child_idx;
+
+ return child_idx;
+ }
+ }
+
+ if (superclass_interface_decl)
+ {
+ if (superclass_interface_decl->getName().equals (name_sref))
+ return 0;
+ }
+ }
+ }
+ }
+ break;
+
+ case clang::Type::ObjCObjectPointer:
+ {
+ ClangASTType pointee_clang_type (m_ast, cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType());
+ return pointee_clang_type.GetIndexOfChildWithName (name, omit_empty_base_classes);
+ }
+ break;
+
+ case clang::Type::ConstantArray:
+ {
+ // const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
+ // const uint64_t element_count = array->getSize().getLimitedValue();
+ //
+ // if (idx < element_count)
+ // {
+ // std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(array->getElementType());
+ //
+ // char element_name[32];
+ // ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
+ //
+ // child_name.assign(element_name);
+ // assert(field_type_info.first % 8 == 0);
+ // child_byte_size = field_type_info.first / 8;
+ // child_byte_offset = idx * child_byte_size;
+ // return array->getElementType().getAsOpaquePtr();
+ // }
+ }
+ break;
+
+ // case clang::Type::MemberPointerType:
+ // {
+ // MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr());
+ // QualType pointee_type = mem_ptr_type->getPointeeType();
+ //
+ // if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
+ // {
+ // return GetIndexOfChildWithName (ast,
+ // mem_ptr_type->getPointeeType().getAsOpaquePtr(),
+ // name);
+ // }
+ // }
+ // break;
+ //
+ case clang::Type::LValueReference:
+ case clang::Type::RValueReference:
+ {
+ const ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
+ ClangASTType pointee_type (m_ast, reference_type->getPointeeType());
+
+ if (pointee_type.IsAggregateType ())
+ {
+ return pointee_type.GetIndexOfChildWithName (name, omit_empty_base_classes);
+ }
+ }
+ break;
+
+ case clang::Type::Pointer:
+ {
+ const PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
+ ClangASTType pointee_type (m_ast, pointer_type->getPointeeType());
+
+ if (pointee_type.IsAggregateType ())
+ {
+ return pointee_type.GetIndexOfChildWithName (name, omit_empty_base_classes);
+ }
+ else
+ {
+ // if (parent_name)
+ // {
+ // child_name.assign(1, '*');
+ // child_name += parent_name;
+ // }
+ //
+ // // We have a pointer to an simple type
+ // if (idx == 0)
+ // {
+ // std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
+ // assert(clang_type_info.first % 8 == 0);
+ // child_byte_size = clang_type_info.first / 8;
+ // child_byte_offset = 0;
+ // return pointee_type.getAsOpaquePtr();
+ // }
+ }
+ }
+ break;
+
+ case clang::Type::Elaborated:
+ return ClangASTType (m_ast, cast<ElaboratedType>(qual_type)->getNamedType()).GetIndexOfChildWithName (name, omit_empty_base_classes);
+
+ case clang::Type::Paren:
+ return ClangASTType (m_ast, cast<clang::ParenType>(qual_type)->desugar()).GetIndexOfChildWithName (name, omit_empty_base_classes);
+
+ case clang::Type::Typedef:
+ return ClangASTType (m_ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetIndexOfChildWithName (name, omit_empty_base_classes);
+
+ default:
+ break;
+ }
+ }
+ return UINT32_MAX;
+}
+
+
+size_t
+ClangASTType::GetNumTemplateArguments () const
+{
+ if (IsValid())
+ {
+ QualType qual_type (GetCanonicalQualType());
+
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class)
+ {
+ case clang::Type::Record:
+ if (GetCompleteType ())
+ {
+ const CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
+ if (cxx_record_decl)
+ {
+ const ClassTemplateSpecializationDecl *template_decl = dyn_cast<ClassTemplateSpecializationDecl>(cxx_record_decl);
+ if (template_decl)
+ return template_decl->getTemplateArgs().size();
+ }
+ }
+ break;
+
+ case clang::Type::Typedef:
+ return ClangASTType (m_ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetNumTemplateArguments();
+
+ case clang::Type::Elaborated:
+ return ClangASTType (m_ast, cast<ElaboratedType>(qual_type)->getNamedType()).GetNumTemplateArguments();
+
+ case clang::Type::Paren:
+ return ClangASTType (m_ast, cast<ParenType>(qual_type)->desugar()).GetNumTemplateArguments();
+
+ default:
+ break;
+ }
+ }
+ return 0;
+}
+
+ClangASTType
+ClangASTType::GetTemplateArgument (size_t arg_idx, lldb::TemplateArgumentKind &kind) const
+{
+ if (IsValid())
+ {
+ QualType qual_type (GetCanonicalQualType());
+
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class)
+ {
+ case clang::Type::Record:
+ if (GetCompleteType ())
+ {
+ const CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
+ if (cxx_record_decl)
+ {
+ const ClassTemplateSpecializationDecl *template_decl = dyn_cast<ClassTemplateSpecializationDecl>(cxx_record_decl);
+ if (template_decl && arg_idx < template_decl->getTemplateArgs().size())
+ {
+ const TemplateArgument &template_arg = template_decl->getTemplateArgs()[arg_idx];
+ switch (template_arg.getKind())
+ {
+ case clang::TemplateArgument::Null:
+ kind = eTemplateArgumentKindNull;
+ return ClangASTType();
+
+ case clang::TemplateArgument::Type:
+ kind = eTemplateArgumentKindType;
+ return ClangASTType(m_ast, template_arg.getAsType());
+
+ case clang::TemplateArgument::Declaration:
+ kind = eTemplateArgumentKindDeclaration;
+ return ClangASTType();
+
+ case clang::TemplateArgument::Integral:
+ kind = eTemplateArgumentKindIntegral;
+ return ClangASTType(m_ast, template_arg.getIntegralType());
+
+ case clang::TemplateArgument::Template:
+ kind = eTemplateArgumentKindTemplate;
+ return ClangASTType();
+
+ case clang::TemplateArgument::TemplateExpansion:
+ kind = eTemplateArgumentKindTemplateExpansion;
+ return ClangASTType();
+
+ case clang::TemplateArgument::Expression:
+ kind = eTemplateArgumentKindExpression;
+ return ClangASTType();
+
+ case clang::TemplateArgument::Pack:
+ kind = eTemplateArgumentKindPack;
+ return ClangASTType();
+
+ default:
+ assert (!"Unhandled TemplateArgument::ArgKind");
+ break;
+ }
+ }
+ }
+ }
+ break;
+
+ case clang::Type::Typedef:
+ return ClangASTType (m_ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetTemplateArgument (arg_idx, kind);
+
+ case clang::Type::Elaborated:
+ return ClangASTType (m_ast, cast<ElaboratedType>(qual_type)->getNamedType()).GetTemplateArgument (arg_idx, kind);
+
+ case clang::Type::Paren:
+ return ClangASTType (m_ast, cast<ParenType>(qual_type)->desugar()).GetTemplateArgument (arg_idx, kind);
+
+ default:
+ break;
+ }
+ }
+ kind = eTemplateArgumentKindNull;
+ return ClangASTType ();
+}
+
+static bool
+IsOperator (const char *name, OverloadedOperatorKind &op_kind)
+{
+ if (name == NULL || name[0] == '\0')
+ return false;
+
+#define OPERATOR_PREFIX "operator"
+#define OPERATOR_PREFIX_LENGTH (sizeof (OPERATOR_PREFIX) - 1)
+
+ const char *post_op_name = NULL;
+
+ bool no_space = true;
+
+ if (::strncmp(name, OPERATOR_PREFIX, OPERATOR_PREFIX_LENGTH))
+ return false;
+
+ post_op_name = name + OPERATOR_PREFIX_LENGTH;
+
+ if (post_op_name[0] == ' ')
+ {
+ post_op_name++;
+ no_space = false;
+ }
+
+#undef OPERATOR_PREFIX
+#undef OPERATOR_PREFIX_LENGTH
+
+ // This is an operator, set the overloaded operator kind to invalid
+ // in case this is a conversion operator...
+ op_kind = NUM_OVERLOADED_OPERATORS;
+
+ switch (post_op_name[0])
+ {
+ default:
+ if (no_space)
+ return false;
+ break;
+ case 'n':
+ if (no_space)
+ return false;
+ if (strcmp (post_op_name, "new") == 0)
+ op_kind = OO_New;
+ else if (strcmp (post_op_name, "new[]") == 0)
+ op_kind = OO_Array_New;
+ break;
+
+ case 'd':
+ if (no_space)
+ return false;
+ if (strcmp (post_op_name, "delete") == 0)
+ op_kind = OO_Delete;
+ else if (strcmp (post_op_name, "delete[]") == 0)
+ op_kind = OO_Array_Delete;
+ break;
+
+ case '+':
+ if (post_op_name[1] == '\0')
+ op_kind = OO_Plus;
+ else if (post_op_name[2] == '\0')
+ {
+ if (post_op_name[1] == '=')
+ op_kind = OO_PlusEqual;
+ else if (post_op_name[1] == '+')
+ op_kind = OO_PlusPlus;
+ }
+ break;
+
+ case '-':
+ if (post_op_name[1] == '\0')
+ op_kind = OO_Minus;
+ else if (post_op_name[2] == '\0')
+ {
+ switch (post_op_name[1])
+ {
+ case '=': op_kind = OO_MinusEqual; break;
+ case '-': op_kind = OO_MinusMinus; break;
+ case '>': op_kind = OO_Arrow; break;
+ }
+ }
+ else if (post_op_name[3] == '\0')
+ {
+ if (post_op_name[2] == '*')
+ op_kind = OO_ArrowStar; break;
+ }
+ break;
+
+ case '*':
+ if (post_op_name[1] == '\0')
+ op_kind = OO_Star;
+ else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
+ op_kind = OO_StarEqual;
+ break;
+
+ case '/':
+ if (post_op_name[1] == '\0')
+ op_kind = OO_Slash;
+ else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
+ op_kind = OO_SlashEqual;
+ break;
+
+ case '%':
+ if (post_op_name[1] == '\0')
+ op_kind = OO_Percent;
+ else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
+ op_kind = OO_PercentEqual;
+ break;
+
+
+ case '^':
+ if (post_op_name[1] == '\0')
+ op_kind = OO_Caret;
+ else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
+ op_kind = OO_CaretEqual;
+ break;
+
+ case '&':
+ if (post_op_name[1] == '\0')
+ op_kind = OO_Amp;
+ else if (post_op_name[2] == '\0')
+ {
+ switch (post_op_name[1])
+ {
+ case '=': op_kind = OO_AmpEqual; break;
+ case '&': op_kind = OO_AmpAmp; break;
+ }
+ }
+ break;
+
+ case '|':
+ if (post_op_name[1] == '\0')
+ op_kind = OO_Pipe;
+ else if (post_op_name[2] == '\0')
+ {
+ switch (post_op_name[1])
+ {
+ case '=': op_kind = OO_PipeEqual; break;
+ case '|': op_kind = OO_PipePipe; break;
+ }
+ }
+ break;
+
+ case '~':
+ if (post_op_name[1] == '\0')
+ op_kind = OO_Tilde;
+ break;
+
+ case '!':
+ if (post_op_name[1] == '\0')
+ op_kind = OO_Exclaim;
+ else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
+ op_kind = OO_ExclaimEqual;
+ break;
+
+ case '=':
+ if (post_op_name[1] == '\0')
+ op_kind = OO_Equal;
+ else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
+ op_kind = OO_EqualEqual;
+ break;
+
+ case '<':
+ if (post_op_name[1] == '\0')
+ op_kind = OO_Less;
+ else if (post_op_name[2] == '\0')
+ {
+ switch (post_op_name[1])
+ {
+ case '<': op_kind = OO_LessLess; break;
+ case '=': op_kind = OO_LessEqual; break;
+ }
+ }
+ else if (post_op_name[3] == '\0')
+ {
+ if (post_op_name[2] == '=')
+ op_kind = OO_LessLessEqual;
+ }
+ break;
+
+ case '>':
+ if (post_op_name[1] == '\0')
+ op_kind = OO_Greater;
+ else if (post_op_name[2] == '\0')
+ {
+ switch (post_op_name[1])
+ {
+ case '>': op_kind = OO_GreaterGreater; break;
+ case '=': op_kind = OO_GreaterEqual; break;
+ }
+ }
+ else if (post_op_name[1] == '>' &&
+ post_op_name[2] == '=' &&
+ post_op_name[3] == '\0')
+ {
+ op_kind = OO_GreaterGreaterEqual;
+ }
+ break;
+
+ case ',':
+ if (post_op_name[1] == '\0')
+ op_kind = OO_Comma;
+ break;
+
+ case '(':
+ if (post_op_name[1] == ')' && post_op_name[2] == '\0')
+ op_kind = OO_Call;
+ break;
+
+ case '[':
+ if (post_op_name[1] == ']' && post_op_name[2] == '\0')
+ op_kind = OO_Subscript;
+ break;
+ }
+
+ return true;
+}
+
+static inline bool
+check_op_param (uint32_t op_kind, bool unary, bool binary, uint32_t num_params)
+{
+ // Special-case call since it can take any number of operands
+ if(op_kind == OO_Call)
+ return true;
+
+ // The parameter count doens't include "this"
+ if (num_params == 0)
+ return unary;
+ if (num_params == 1)
+ return binary;
+ else
+ return false;
+}
+
+clang::RecordDecl *
+ClangASTType::GetAsRecordDecl () const
+{
+ const RecordType *record_type = dyn_cast<RecordType>(GetCanonicalQualType());
+ if (record_type)
+ return record_type->getDecl();
+ return NULL;
+}
+
+clang::CXXRecordDecl *
+ClangASTType::GetAsCXXRecordDecl () const
+{
+ return GetCanonicalQualType()->getAsCXXRecordDecl();
+}
+
+ObjCInterfaceDecl *
+ClangASTType::GetAsObjCInterfaceDecl () const
+{
+ const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(GetCanonicalQualType());
+ if (objc_class_type)
+ return objc_class_type->getInterface();
+ return NULL;
+}
+
+clang::FieldDecl *
+ClangASTType::AddFieldToRecordType (const char *name,
+ const ClangASTType &field_clang_type,
+ AccessType access,
+ uint32_t bitfield_bit_size)
+{
+ if (!IsValid() || !field_clang_type.IsValid())
+ return NULL;
+
+ FieldDecl *field = NULL;
+
+ clang::Expr *bit_width = NULL;
+ if (bitfield_bit_size != 0)
+ {
+ APInt bitfield_bit_size_apint(m_ast->getTypeSize(m_ast->IntTy), bitfield_bit_size);
+ bit_width = new (*m_ast)IntegerLiteral (*m_ast, bitfield_bit_size_apint, m_ast->IntTy, SourceLocation());
+ }
+
+ RecordDecl *record_decl = GetAsRecordDecl ();
+ if (record_decl)
+ {
+ field = FieldDecl::Create (*m_ast,
+ record_decl,
+ SourceLocation(),
+ SourceLocation(),
+ name ? &m_ast->Idents.get(name) : NULL, // Identifier
+ field_clang_type.GetQualType(), // Field type
+ NULL, // TInfo *
+ bit_width, // BitWidth
+ false, // Mutable
+ ICIS_NoInit); // HasInit
+
+ if (!name)
+ {
+ // Determine whether this field corresponds to an anonymous
+ // struct or union.
+ if (const TagType *TagT = field->getType()->getAs<TagType>()) {
+ if (RecordDecl *Rec = dyn_cast<RecordDecl>(TagT->getDecl()))
+ if (!Rec->getDeclName()) {
+ Rec->setAnonymousStructOrUnion(true);
+ field->setImplicit();
+
+ }
+ }
+ }
+
+ if (field)
+ {
+ field->setAccess (ClangASTContext::ConvertAccessTypeToAccessSpecifier (access));
+
+ record_decl->addDecl(field);
+
+#ifdef LLDB_CONFIGURATION_DEBUG
+ VerifyDecl(field);
+#endif
+ }
+ }
+ else
+ {
+ ObjCInterfaceDecl *class_interface_decl = GetAsObjCInterfaceDecl ();
+
+ if (class_interface_decl)
+ {
+ const bool is_synthesized = false;
+
+ field_clang_type.GetCompleteType();
+
+ field = ObjCIvarDecl::Create (*m_ast,
+ class_interface_decl,
+ SourceLocation(),
+ SourceLocation(),
+ name ? &m_ast->Idents.get(name) : NULL, // Identifier
+ field_clang_type.GetQualType(), // Field type
+ NULL, // TypeSourceInfo *
+ ConvertAccessTypeToObjCIvarAccessControl (access),
+ bit_width,
+ is_synthesized);
+
+ if (field)
+ {
+ class_interface_decl->addDecl(field);
+
+#ifdef LLDB_CONFIGURATION_DEBUG
+ VerifyDecl(field);
+#endif
+ }
+ }
+ }
+ return field;
+}
+
+void
+ClangASTType::BuildIndirectFields ()
+{
+ RecordDecl *record_decl = GetAsRecordDecl();
+
+ if (!record_decl)
+ return;
+
+ typedef llvm::SmallVector <IndirectFieldDecl *, 1> IndirectFieldVector;
+
+ IndirectFieldVector indirect_fields;
+ RecordDecl::field_iterator field_pos;
+ RecordDecl::field_iterator field_end_pos = record_decl->field_end();
+ RecordDecl::field_iterator last_field_pos = field_end_pos;
+ for (field_pos = record_decl->field_begin(); field_pos != field_end_pos; last_field_pos = field_pos++)
+ {
+ if (field_pos->isAnonymousStructOrUnion())
+ {
+ QualType field_qual_type = field_pos->getType();
+
+ const RecordType *field_record_type = field_qual_type->getAs<RecordType>();
+
+ if (!field_record_type)
+ continue;
+
+ RecordDecl *field_record_decl = field_record_type->getDecl();
+
+ if (!field_record_decl)
+ continue;
+
+ for (RecordDecl::decl_iterator di = field_record_decl->decls_begin(), de = field_record_decl->decls_end();
+ di != de;
+ ++di)
+ {
+ if (FieldDecl *nested_field_decl = dyn_cast<FieldDecl>(*di))
+ {
+ NamedDecl **chain = new (*m_ast) NamedDecl*[2];
+ chain[0] = *field_pos;
+ chain[1] = nested_field_decl;
+ IndirectFieldDecl *indirect_field = IndirectFieldDecl::Create(*m_ast,
+ record_decl,
+ SourceLocation(),
+ nested_field_decl->getIdentifier(),
+ nested_field_decl->getType(),
+ chain,
+ 2);
+
+ indirect_field->setAccess(ClangASTContext::UnifyAccessSpecifiers(field_pos->getAccess(),
+ nested_field_decl->getAccess()));
+
+ indirect_fields.push_back(indirect_field);
+ }
+ else if (IndirectFieldDecl *nested_indirect_field_decl = dyn_cast<IndirectFieldDecl>(*di))
+ {
+ int nested_chain_size = nested_indirect_field_decl->getChainingSize();
+ NamedDecl **chain = new (*m_ast) NamedDecl*[nested_chain_size + 1];
+ chain[0] = *field_pos;
+
+ int chain_index = 1;
+ for (IndirectFieldDecl::chain_iterator nci = nested_indirect_field_decl->chain_begin(),
+ nce = nested_indirect_field_decl->chain_end();
+ nci < nce;
+ ++nci)
+ {
+ chain[chain_index] = *nci;
+ chain_index++;
+ }
+
+ IndirectFieldDecl *indirect_field = IndirectFieldDecl::Create(*m_ast,
+ record_decl,
+ SourceLocation(),
+ nested_indirect_field_decl->getIdentifier(),
+ nested_indirect_field_decl->getType(),
+ chain,
+ nested_chain_size + 1);
+
+ indirect_field->setAccess(ClangASTContext::UnifyAccessSpecifiers(field_pos->getAccess(),
+ nested_indirect_field_decl->getAccess()));
+
+ indirect_fields.push_back(indirect_field);
+ }
+ }
+ }
+ }
+
+ // Check the last field to see if it has an incomplete array type as its
+ // last member and if it does, the tell the record decl about it
+ if (last_field_pos != field_end_pos)
+ {
+ if (last_field_pos->getType()->isIncompleteArrayType())
+ record_decl->hasFlexibleArrayMember();
+ }
+
+ for (IndirectFieldVector::iterator ifi = indirect_fields.begin(), ife = indirect_fields.end();
+ ifi < ife;
+ ++ifi)
+ {
+ record_decl->addDecl(*ifi);
+ }
+}
+
+clang::VarDecl *
+ClangASTType::AddVariableToRecordType (const char *name,
+ const ClangASTType &var_type,
+ AccessType access)
+{
+ clang::VarDecl *var_decl = NULL;
+
+ if (!IsValid() || !var_type.IsValid())
+ return NULL;
+
+ RecordDecl *record_decl = GetAsRecordDecl ();
+ if (record_decl)
+ {
+ var_decl = VarDecl::Create (*m_ast, // ASTContext &
+ record_decl, // DeclContext *
+ SourceLocation(), // SourceLocation StartLoc
+ SourceLocation(), // SourceLocation IdLoc
+ name ? &m_ast->Idents.get(name) : NULL, // IdentifierInfo *
+ var_type.GetQualType(), // Variable QualType
+ NULL, // TypeSourceInfo *
+ SC_Static); // StorageClass
+ if (var_decl)
+ {
+ var_decl->setAccess(ClangASTContext::ConvertAccessTypeToAccessSpecifier (access));
+ record_decl->addDecl(var_decl);
+
+#ifdef LLDB_CONFIGURATION_DEBUG
+ VerifyDecl(var_decl);
+#endif
+ }
+ }
+ return var_decl;
+}
+
+
+CXXMethodDecl *
+ClangASTType::AddMethodToCXXRecordType (const char *name,
+ const ClangASTType &method_clang_type,
+ lldb::AccessType access,
+ bool is_virtual,
+ bool is_static,
+ bool is_inline,
+ bool is_explicit,
+ bool is_attr_used,
+ bool is_artificial)
+{
+ if (!IsValid() || !method_clang_type.IsValid() || name == NULL || name[0] == '\0')
+ return NULL;
+
+ QualType record_qual_type(GetCanonicalQualType());
+
+ CXXRecordDecl *cxx_record_decl = record_qual_type->getAsCXXRecordDecl();
+
+ if (cxx_record_decl == NULL)
+ return NULL;
+
+ QualType method_qual_type (method_clang_type.GetQualType());
+
+ CXXMethodDecl *cxx_method_decl = NULL;
+
+ DeclarationName decl_name (&m_ast->Idents.get(name));
+
+ const clang::FunctionType *function_type = dyn_cast<FunctionType>(method_qual_type.getTypePtr());
+
+ if (function_type == NULL)
+ return NULL;
+
+ const FunctionProtoType *method_function_prototype (dyn_cast<FunctionProtoType>(function_type));
+
+ if (!method_function_prototype)
+ return NULL;
+
+ unsigned int num_params = method_function_prototype->getNumArgs();
+
+ CXXDestructorDecl *cxx_dtor_decl(NULL);
+ CXXConstructorDecl *cxx_ctor_decl(NULL);
+
+ if (is_artificial)
+ return NULL; // skip everything artificial
+
+ if (name[0] == '~')
+ {
+ cxx_dtor_decl = CXXDestructorDecl::Create (*m_ast,
+ cxx_record_decl,
+ SourceLocation(),
+ DeclarationNameInfo (m_ast->DeclarationNames.getCXXDestructorName (m_ast->getCanonicalType (record_qual_type)), SourceLocation()),
+ method_qual_type,
+ NULL,
+ is_inline,
+ is_artificial);
+ cxx_method_decl = cxx_dtor_decl;
+ }
+ else if (decl_name == cxx_record_decl->getDeclName())
+ {
+ cxx_ctor_decl = CXXConstructorDecl::Create (*m_ast,
+ cxx_record_decl,
+ SourceLocation(),
+ DeclarationNameInfo (m_ast->DeclarationNames.getCXXConstructorName (m_ast->getCanonicalType (record_qual_type)), SourceLocation()),
+ method_qual_type,
+ NULL, // TypeSourceInfo *
+ is_explicit,
+ is_inline,
+ is_artificial,
+ false /*is_constexpr*/);
+ cxx_method_decl = cxx_ctor_decl;
+ }
+ else
+ {
+ clang::StorageClass SC = is_static ? SC_Static : SC_None;
+ OverloadedOperatorKind op_kind = NUM_OVERLOADED_OPERATORS;
+
+ if (IsOperator (name, op_kind))
+ {
+ if (op_kind != NUM_OVERLOADED_OPERATORS)
+ {
+ // Check the number of operator parameters. Sometimes we have
+ // seen bad DWARF that doesn't correctly describe operators and
+ // if we try to create a methed and add it to the class, clang
+ // will assert and crash, so we need to make sure things are
+ // acceptable.
+ if (!ClangASTContext::CheckOverloadedOperatorKindParameterCount (op_kind, num_params))
+ return NULL;
+ cxx_method_decl = CXXMethodDecl::Create (*m_ast,
+ cxx_record_decl,
+ SourceLocation(),
+ DeclarationNameInfo (m_ast->DeclarationNames.getCXXOperatorName (op_kind), SourceLocation()),
+ method_qual_type,
+ NULL, // TypeSourceInfo *
+ SC,
+ is_inline,
+ false /*is_constexpr*/,
+ SourceLocation());
+ }
+ else if (num_params == 0)
+ {
+ // Conversion operators don't take params...
+ cxx_method_decl = CXXConversionDecl::Create (*m_ast,
+ cxx_record_decl,
+ SourceLocation(),
+ DeclarationNameInfo (m_ast->DeclarationNames.getCXXConversionFunctionName (m_ast->getCanonicalType (function_type->getResultType())), SourceLocation()),
+ method_qual_type,
+ NULL, // TypeSourceInfo *
+ is_inline,
+ is_explicit,
+ false /*is_constexpr*/,
+ SourceLocation());
+ }
+ }
+
+ if (cxx_method_decl == NULL)
+ {
+ cxx_method_decl = CXXMethodDecl::Create (*m_ast,
+ cxx_record_decl,
+ SourceLocation(),
+ DeclarationNameInfo (decl_name, SourceLocation()),
+ method_qual_type,
+ NULL, // TypeSourceInfo *
+ SC,
+ is_inline,
+ false /*is_constexpr*/,
+ SourceLocation());
+ }
+ }
+
+ AccessSpecifier access_specifier = ClangASTContext::ConvertAccessTypeToAccessSpecifier (access);
+
+ cxx_method_decl->setAccess (access_specifier);
+ cxx_method_decl->setVirtualAsWritten (is_virtual);
+
+ if (is_attr_used)
+ cxx_method_decl->addAttr(::new (*m_ast) UsedAttr(SourceRange(), *m_ast));
+
+ // Populate the method decl with parameter decls
+
+ llvm::SmallVector<ParmVarDecl *, 12> params;
+
+ for (unsigned param_index = 0;
+ param_index < num_params;
+ ++param_index)
+ {
+ params.push_back (ParmVarDecl::Create (*m_ast,
+ cxx_method_decl,
+ SourceLocation(),
+ SourceLocation(),
+ NULL, // anonymous
+ method_function_prototype->getArgType(param_index),
+ NULL,
+ SC_None,
+ NULL));
+ }
+
+ cxx_method_decl->setParams (ArrayRef<ParmVarDecl*>(params));
+
+ cxx_record_decl->addDecl (cxx_method_decl);
+
+ // Sometimes the debug info will mention a constructor (default/copy/move),
+ // destructor, or assignment operator (copy/move) but there won't be any
+ // version of this in the code. So we check if the function was artificially
+ // generated and if it is trivial and this lets the compiler/backend know
+ // that it can inline the IR for these when it needs to and we can avoid a
+ // "missing function" error when running expressions.
+
+ if (is_artificial)
+ {
+ if (cxx_ctor_decl &&
+ ((cxx_ctor_decl->isDefaultConstructor() && cxx_record_decl->hasTrivialDefaultConstructor ()) ||
+ (cxx_ctor_decl->isCopyConstructor() && cxx_record_decl->hasTrivialCopyConstructor ()) ||
+ (cxx_ctor_decl->isMoveConstructor() && cxx_record_decl->hasTrivialMoveConstructor ()) ))
+ {
+ cxx_ctor_decl->setDefaulted();
+ cxx_ctor_decl->setTrivial(true);
+ }
+ else if (cxx_dtor_decl)
+ {
+ if (cxx_record_decl->hasTrivialDestructor())
+ {
+ cxx_dtor_decl->setDefaulted();
+ cxx_dtor_decl->setTrivial(true);
+ }
+ }
+ else if ((cxx_method_decl->isCopyAssignmentOperator() && cxx_record_decl->hasTrivialCopyAssignment()) ||
+ (cxx_method_decl->isMoveAssignmentOperator() && cxx_record_decl->hasTrivialMoveAssignment()))
+ {
+ cxx_method_decl->setDefaulted();
+ cxx_method_decl->setTrivial(true);
+ }
+ }
+
+#ifdef LLDB_CONFIGURATION_DEBUG
+ VerifyDecl(cxx_method_decl);
+#endif
+
+ // printf ("decl->isPolymorphic() = %i\n", cxx_record_decl->isPolymorphic());
+ // printf ("decl->isAggregate() = %i\n", cxx_record_decl->isAggregate());
+ // printf ("decl->isPOD() = %i\n", cxx_record_decl->isPOD());
+ // printf ("decl->isEmpty() = %i\n", cxx_record_decl->isEmpty());
+ // printf ("decl->isAbstract() = %i\n", cxx_record_decl->isAbstract());
+ // printf ("decl->hasTrivialConstructor() = %i\n", cxx_record_decl->hasTrivialConstructor());
+ // printf ("decl->hasTrivialCopyConstructor() = %i\n", cxx_record_decl->hasTrivialCopyConstructor());
+ // printf ("decl->hasTrivialCopyAssignment() = %i\n", cxx_record_decl->hasTrivialCopyAssignment());
+ // printf ("decl->hasTrivialDestructor() = %i\n", cxx_record_decl->hasTrivialDestructor());
+ return cxx_method_decl;
+}
+
+
+#pragma mark C++ Base Classes
+
+CXXBaseSpecifier *
+ClangASTType::CreateBaseClassSpecifier (AccessType access, bool is_virtual, bool base_of_class)
+{
+ if (IsValid())
+ return new CXXBaseSpecifier (SourceRange(),
+ is_virtual,
+ base_of_class,
+ ClangASTContext::ConvertAccessTypeToAccessSpecifier (access),
+ m_ast->getTrivialTypeSourceInfo (GetQualType()),
+ SourceLocation());
+ return NULL;
+}
+
+void
+ClangASTType::DeleteBaseClassSpecifiers (CXXBaseSpecifier **base_classes, unsigned num_base_classes)
+{
+ for (unsigned i=0; i<num_base_classes; ++i)
+ {
+ delete base_classes[i];
+ base_classes[i] = NULL;
+ }
+}
+
+bool
+ClangASTType::SetBaseClassesForClassType (CXXBaseSpecifier const * const *base_classes,
+ unsigned num_base_classes)
+{
+ if (IsValid())
+ {
+ CXXRecordDecl *cxx_record_decl = GetAsCXXRecordDecl();
+ if (cxx_record_decl)
+ {
+ cxx_record_decl->setBases(base_classes, num_base_classes);
+ return true;
+ }
+ }
+ return false;
+}
+
+bool
+ClangASTType::SetObjCSuperClass (const ClangASTType &superclass_clang_type)
+{
+ if (IsValid() && superclass_clang_type.IsValid())
+ {
+ ObjCInterfaceDecl *class_interface_decl = GetAsObjCInterfaceDecl ();
+ ObjCInterfaceDecl *super_interface_decl = superclass_clang_type.GetAsObjCInterfaceDecl ();
+ if (class_interface_decl && super_interface_decl)
+ {
+ class_interface_decl->setSuperClass(super_interface_decl);
+ return true;
+ }
+ }
+ return false;
+}
+
+bool
+ClangASTType::AddObjCClassProperty (const char *property_name,
+ const ClangASTType &property_clang_type,
+ ObjCIvarDecl *ivar_decl,
+ const char *property_setter_name,
+ const char *property_getter_name,
+ uint32_t property_attributes,
+ ClangASTMetadata *metadata)
+{
+ if (!IsValid() || !property_clang_type.IsValid() || property_name == NULL || property_name[0] == '\0')
+ return false;
+
+ ObjCInterfaceDecl *class_interface_decl = GetAsObjCInterfaceDecl ();
+
+ if (class_interface_decl)
+ {
+ ClangASTType property_clang_type_to_access;
+
+ if (property_clang_type.IsValid())
+ property_clang_type_to_access = property_clang_type;
+ else if (ivar_decl)
+ property_clang_type_to_access = ClangASTType (m_ast, ivar_decl->getType());
+
+ if (class_interface_decl && property_clang_type_to_access.IsValid())
+ {
+ clang::TypeSourceInfo *prop_type_source;
+ if (ivar_decl)
+ prop_type_source = m_ast->getTrivialTypeSourceInfo (ivar_decl->getType());
else
- return lldb::eTypeClassComplexInteger;
- case clang::Type::ObjCObject: return lldb::eTypeClassObjCObject;
- case clang::Type::ObjCInterface: return lldb::eTypeClassObjCInterface;
- case clang::Type::Record:
- if (ClangASTContext::GetCompleteType (ast_context, clang_type))
+ prop_type_source = m_ast->getTrivialTypeSourceInfo (property_clang_type.GetQualType());
+
+ ObjCPropertyDecl *property_decl = ObjCPropertyDecl::Create (*m_ast,
+ class_interface_decl,
+ SourceLocation(), // Source Location
+ &m_ast->Idents.get(property_name),
+ SourceLocation(), //Source Location for AT
+ SourceLocation(), //Source location for (
+ prop_type_source);
+
+ if (property_decl)
{
- const clang::RecordType *record_type = llvm::cast<clang::RecordType>(qual_type.getTypePtr());
- const clang::RecordDecl *record_decl = record_type->getDecl();
- if (record_decl->isUnion())
- return lldb::eTypeClassUnion;
- else if (record_decl->isStruct())
- return lldb::eTypeClassStruct;
+ if (metadata)
+ ClangASTContext::SetMetadata(m_ast, property_decl, *metadata);
+
+ class_interface_decl->addDecl (property_decl);
+
+ Selector setter_sel, getter_sel;
+
+ if (property_setter_name != NULL)
+ {
+ std::string property_setter_no_colon(property_setter_name, strlen(property_setter_name) - 1);
+ clang::IdentifierInfo *setter_ident = &m_ast->Idents.get(property_setter_no_colon.c_str());
+ setter_sel = m_ast->Selectors.getSelector(1, &setter_ident);
+ }
+ else if (!(property_attributes & DW_APPLE_PROPERTY_readonly))
+ {
+ std::string setter_sel_string("set");
+ setter_sel_string.push_back(::toupper(property_name[0]));
+ setter_sel_string.append(&property_name[1]);
+ clang::IdentifierInfo *setter_ident = &m_ast->Idents.get(setter_sel_string.c_str());
+ setter_sel = m_ast->Selectors.getSelector(1, &setter_ident);
+ }
+ property_decl->setSetterName(setter_sel);
+ property_decl->setPropertyAttributes (clang::ObjCPropertyDecl::OBJC_PR_setter);
+
+ if (property_getter_name != NULL)
+ {
+ clang::IdentifierInfo *getter_ident = &m_ast->Idents.get(property_getter_name);
+ getter_sel = m_ast->Selectors.getSelector(0, &getter_ident);
+ }
else
- return lldb::eTypeClassClass;
+ {
+ clang::IdentifierInfo *getter_ident = &m_ast->Idents.get(property_name);
+ getter_sel = m_ast->Selectors.getSelector(0, &getter_ident);
+ }
+ property_decl->setGetterName(getter_sel);
+ property_decl->setPropertyAttributes (clang::ObjCPropertyDecl::OBJC_PR_getter);
+
+ if (ivar_decl)
+ property_decl->setPropertyIvarDecl (ivar_decl);
+
+ if (property_attributes & DW_APPLE_PROPERTY_readonly)
+ property_decl->setPropertyAttributes (clang::ObjCPropertyDecl::OBJC_PR_readonly);
+ if (property_attributes & DW_APPLE_PROPERTY_readwrite)
+ property_decl->setPropertyAttributes (clang::ObjCPropertyDecl::OBJC_PR_readwrite);
+ if (property_attributes & DW_APPLE_PROPERTY_assign)
+ property_decl->setPropertyAttributes (clang::ObjCPropertyDecl::OBJC_PR_assign);
+ if (property_attributes & DW_APPLE_PROPERTY_retain)
+ property_decl->setPropertyAttributes (clang::ObjCPropertyDecl::OBJC_PR_retain);
+ if (property_attributes & DW_APPLE_PROPERTY_copy)
+ 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))
+ {
+ const bool isInstance = true;
+ const bool isVariadic = false;
+ const bool isSynthesized = false;
+ const bool isImplicitlyDeclared = true;
+ const bool isDefined = false;
+ const ObjCMethodDecl::ImplementationControl impControl = ObjCMethodDecl::None;
+ const bool HasRelatedResultType = false;
+
+ ObjCMethodDecl *getter = ObjCMethodDecl::Create (*m_ast,
+ SourceLocation(),
+ SourceLocation(),
+ getter_sel,
+ property_clang_type_to_access.GetQualType(),
+ NULL,
+ class_interface_decl,
+ isInstance,
+ isVariadic,
+ isSynthesized,
+ isImplicitlyDeclared,
+ isDefined,
+ impControl,
+ HasRelatedResultType);
+
+ if (getter && metadata)
+ ClangASTContext::SetMetadata(m_ast, getter, *metadata);
+
+ getter->setMethodParams(*m_ast, ArrayRef<ParmVarDecl*>(), ArrayRef<SourceLocation>());
+
+ class_interface_decl->addDecl(getter);
+ }
+
+ if (!setter_sel.isNull() && !class_interface_decl->lookupInstanceMethod(setter_sel))
+ {
+ QualType result_type = m_ast->VoidTy;
+
+ const bool isInstance = true;
+ const bool isVariadic = false;
+ const bool isSynthesized = false;
+ const bool isImplicitlyDeclared = true;
+ const bool isDefined = false;
+ const ObjCMethodDecl::ImplementationControl impControl = ObjCMethodDecl::None;
+ const bool HasRelatedResultType = false;
+
+ ObjCMethodDecl *setter = ObjCMethodDecl::Create (*m_ast,
+ SourceLocation(),
+ SourceLocation(),
+ setter_sel,
+ result_type,
+ NULL,
+ class_interface_decl,
+ isInstance,
+ isVariadic,
+ isSynthesized,
+ isImplicitlyDeclared,
+ isDefined,
+ impControl,
+ HasRelatedResultType);
+
+ if (setter && metadata)
+ ClangASTContext::SetMetadata(m_ast, setter, *metadata);
+
+ llvm::SmallVector<ParmVarDecl *, 1> params;
+
+ params.push_back (ParmVarDecl::Create (*m_ast,
+ setter,
+ SourceLocation(),
+ SourceLocation(),
+ NULL, // anonymous
+ property_clang_type_to_access.GetQualType(),
+ NULL,
+ SC_Auto,
+ NULL));
+
+ setter->setMethodParams(*m_ast, ArrayRef<ParmVarDecl*>(params), ArrayRef<SourceLocation>());
+
+ class_interface_decl->addDecl(setter);
+ }
+
+ return true;
}
- break;
- case clang::Type::Enum: return lldb::eTypeClassEnumeration;
- case clang::Type::Typedef: return lldb::eTypeClassTypedef;
- case clang::Type::UnresolvedUsing: break;
- case clang::Type::Paren:
- return ClangASTType::GetTypeClass (ast_context, llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr());
- case clang::Type::Elaborated:
- return ClangASTType::GetTypeClass (ast_context, llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
+ }
+ }
+ return false;
+}
- case clang::Type::Attributed: break;
+bool
+ClangASTType::IsObjCClassTypeAndHasIVars (bool check_superclass) const
+{
+ ObjCInterfaceDecl *class_interface_decl = GetAsObjCInterfaceDecl ();
+ if (class_interface_decl)
+ return ObjCDeclHasIVars (class_interface_decl, check_superclass);
+ return false;
+}
+
+
+ObjCMethodDecl *
+ClangASTType::AddMethodToObjCObjectType (const char *name, // the full symbol name as seen in the symbol table ("-[NString stringWithCString:]")
+ const ClangASTType &method_clang_type,
+ lldb::AccessType access,
+ bool is_artificial)
+{
+ if (!IsValid() || !method_clang_type.IsValid())
+ return NULL;
+
+ ObjCInterfaceDecl *class_interface_decl = GetAsObjCInterfaceDecl();
+
+ if (class_interface_decl == NULL)
+ return NULL;
+
+ const char *selector_start = ::strchr (name, ' ');
+ if (selector_start == NULL)
+ return NULL;
+
+ selector_start++;
+ llvm::SmallVector<IdentifierInfo *, 12> selector_idents;
+
+ size_t len = 0;
+ const char *start;
+ //printf ("name = '%s'\n", name);
+
+ unsigned num_selectors_with_args = 0;
+ for (start = selector_start;
+ start && *start != '\0' && *start != ']';
+ start += len)
+ {
+ len = ::strcspn(start, ":]");
+ bool has_arg = (start[len] == ':');
+ if (has_arg)
+ ++num_selectors_with_args;
+ selector_idents.push_back (&m_ast->Idents.get (StringRef (start, len)));
+ if (has_arg)
+ len += 1;
+ }
+
+
+ if (selector_idents.size() == 0)
+ return 0;
+
+ clang::Selector method_selector = m_ast->Selectors.getSelector (num_selectors_with_args ? selector_idents.size() : 0,
+ selector_idents.data());
+
+ QualType method_qual_type (method_clang_type.GetQualType());
+
+ // Populate the method decl with parameter decls
+ const clang::Type *method_type(method_qual_type.getTypePtr());
+
+ if (method_type == NULL)
+ return NULL;
+
+ const FunctionProtoType *method_function_prototype (dyn_cast<FunctionProtoType>(method_type));
+
+ if (!method_function_prototype)
+ return NULL;
+
+
+ bool is_variadic = false;
+ bool is_synthesized = false;
+ bool is_defined = false;
+ ObjCMethodDecl::ImplementationControl imp_control = ObjCMethodDecl::None;
+
+ const unsigned num_args = method_function_prototype->getNumArgs();
+
+ if (num_args != num_selectors_with_args)
+ return NULL; // some debug information is corrupt. We are not going to deal with it.
+
+ ObjCMethodDecl *objc_method_decl = ObjCMethodDecl::Create (*m_ast,
+ SourceLocation(), // beginLoc,
+ SourceLocation(), // endLoc,
+ method_selector,
+ method_function_prototype->getResultType(),
+ NULL, // TypeSourceInfo *ResultTInfo,
+ GetDeclContextForType (),
+ 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 == NULL)
+ return NULL;
+
+ if (num_args > 0)
+ {
+ llvm::SmallVector<ParmVarDecl *, 12> params;
+
+ for (unsigned param_index = 0; param_index < num_args; ++param_index)
+ {
+ params.push_back (ParmVarDecl::Create (*m_ast,
+ objc_method_decl,
+ SourceLocation(),
+ SourceLocation(),
+ NULL, // anonymous
+ method_function_prototype->getArgType(param_index),
+ NULL,
+ SC_Auto,
+ NULL));
+ }
+
+ objc_method_decl->setMethodParams(*m_ast, ArrayRef<ParmVarDecl*>(params), ArrayRef<SourceLocation>());
+ }
+
+ class_interface_decl->addDecl (objc_method_decl);
+
+#ifdef LLDB_CONFIGURATION_DEBUG
+ VerifyDecl(objc_method_decl);
+#endif
+
+ return objc_method_decl;
+}
+
+
+clang::DeclContext *
+ClangASTType::GetDeclContextForType () const
+{
+ if (!IsValid())
+ return NULL;
+
+ QualType qual_type(GetCanonicalQualType());
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class)
+ {
+ case clang::Type::UnaryTransform: break;
+ case clang::Type::FunctionNoProto: break;
+ case clang::Type::FunctionProto: break;
+ case clang::Type::IncompleteArray: break;
+ case clang::Type::VariableArray: break;
+ case clang::Type::ConstantArray: break;
+ case clang::Type::DependentSizedArray: break;
+ case clang::Type::ExtVector: break;
+ case clang::Type::DependentSizedExtVector: break;
+ case clang::Type::Vector: break;
+ case clang::Type::Builtin: break;
+ case clang::Type::BlockPointer: break;
+ case clang::Type::Pointer: break;
+ case clang::Type::LValueReference: break;
+ case clang::Type::RValueReference: break;
+ case clang::Type::MemberPointer: break;
+ case clang::Type::Complex: break;
+ case clang::Type::ObjCObject: break;
+ case clang::Type::ObjCInterface: return cast<ObjCObjectType>(qual_type.getTypePtr())->getInterface();
+ case clang::Type::ObjCObjectPointer: return ClangASTType (m_ast, cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType()).GetDeclContextForType();
+ case clang::Type::Record: return cast<RecordType>(qual_type)->getDecl();
+ case clang::Type::Enum: return cast<EnumType>(qual_type)->getDecl();
+ case clang::Type::Typedef: return ClangASTType (m_ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetDeclContextForType();
+ case clang::Type::Elaborated: return ClangASTType (m_ast, cast<ElaboratedType>(qual_type)->getNamedType()).GetDeclContextForType();
+ case clang::Type::Paren: return ClangASTType (m_ast, cast<ParenType>(qual_type)->desugar()).GetDeclContextForType();
+ case clang::Type::TypeOfExpr: break;
+ case clang::Type::TypeOf: break;
+ case clang::Type::Decltype: break;
+ //case clang::Type::QualifiedName: break;
+ case clang::Type::TemplateSpecialization: break;
+ case clang::Type::DependentTemplateSpecialization: break;
case clang::Type::TemplateTypeParm: break;
case clang::Type::SubstTemplateTypeParm: break;
case clang::Type::SubstTemplateTypeParmPack:break;
+ case clang::Type::PackExpansion: break;
+ case clang::Type::UnresolvedUsing: break;
+ case clang::Type::Attributed: break;
case clang::Type::Auto: break;
case clang::Type::InjectedClassName: break;
case clang::Type::DependentName: break;
- case clang::Type::DependentTemplateSpecialization: break;
- case clang::Type::PackExpansion: break;
-
- case clang::Type::TypeOfExpr: break;
- case clang::Type::TypeOf: break;
- case clang::Type::Decltype: break;
- case clang::Type::TemplateSpecialization: break;
case clang::Type::Atomic: break;
}
- // We don't know hot to display this type...
- return lldb::eTypeClassOther;
-
+ // No DeclContext in this type...
+ return NULL;
}
-
-lldb::LanguageType
-ClangASTType::GetMinimumLanguage (clang::ASTContext *ctx,
- lldb::clang_type_t clang_type)
+bool
+ClangASTType::SetDefaultAccessForRecordFields (int default_accessibility,
+ int *assigned_accessibilities,
+ size_t num_assigned_accessibilities)
{
- if (clang_type == NULL)
- return lldb::eLanguageTypeC;
-
- // If the type is a reference, then resolve it to what it refers to first:
- clang::QualType qual_type (clang::QualType::getFromOpaquePtr(clang_type).getNonReferenceType());
- if (qual_type->isAnyPointerType())
- {
- if (qual_type->isObjCObjectPointerType())
- return lldb::eLanguageTypeObjC;
-
- clang::QualType pointee_type (qual_type->getPointeeType());
- if (pointee_type->getPointeeCXXRecordDecl() != NULL)
- return lldb::eLanguageTypeC_plus_plus;
- if (pointee_type->isObjCObjectOrInterfaceType())
- return lldb::eLanguageTypeObjC;
- if (pointee_type->isObjCClassType())
- return lldb::eLanguageTypeObjC;
- if (pointee_type.getTypePtr() == ctx->ObjCBuiltinIdTy.getTypePtr())
- return lldb::eLanguageTypeObjC;
- }
- else
+ if (IsValid())
{
- if (qual_type->isObjCObjectOrInterfaceType())
- return lldb::eLanguageTypeObjC;
- if (qual_type->getAsCXXRecordDecl())
- return lldb::eLanguageTypeC_plus_plus;
- switch (qual_type->getTypeClass())
+ RecordDecl *record_decl = GetAsRecordDecl();
+ if (record_decl)
{
- default:
- break;
- case clang::Type::Builtin:
- switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind())
+ uint32_t field_idx;
+ RecordDecl::field_iterator field, field_end;
+ for (field = record_decl->field_begin(), field_end = record_decl->field_end(), field_idx = 0;
+ field != field_end;
+ ++field, ++field_idx)
{
- default:
- case clang::BuiltinType::Void:
- case clang::BuiltinType::Bool:
- case clang::BuiltinType::Char_U:
- case clang::BuiltinType::UChar:
- case clang::BuiltinType::WChar_U:
- case clang::BuiltinType::Char16:
- case clang::BuiltinType::Char32:
- case clang::BuiltinType::UShort:
- case clang::BuiltinType::UInt:
- case clang::BuiltinType::ULong:
- case clang::BuiltinType::ULongLong:
- case clang::BuiltinType::UInt128:
- case clang::BuiltinType::Char_S:
- case clang::BuiltinType::SChar:
- case clang::BuiltinType::WChar_S:
- case clang::BuiltinType::Short:
- case clang::BuiltinType::Int:
- case clang::BuiltinType::Long:
- case clang::BuiltinType::LongLong:
- case clang::BuiltinType::Int128:
- case clang::BuiltinType::Float:
- case clang::BuiltinType::Double:
- case clang::BuiltinType::LongDouble:
- break;
+ // If no accessibility was assigned, assign the correct one
+ if (field_idx < num_assigned_accessibilities && assigned_accessibilities[field_idx] == clang::AS_none)
+ field->setAccess ((AccessSpecifier)default_accessibility);
+ }
+ return true;
+ }
+ }
+ return false;
+}
- case clang::BuiltinType::NullPtr:
- return eLanguageTypeC_plus_plus;
-
- case clang::BuiltinType::ObjCId:
- case clang::BuiltinType::ObjCClass:
- case clang::BuiltinType::ObjCSel:
- return eLanguageTypeObjC;
- case clang::BuiltinType::Dependent:
- case clang::BuiltinType::Overload:
- case clang::BuiltinType::BoundMember:
- case clang::BuiltinType::UnknownAny:
- break;
+bool
+ClangASTType::SetHasExternalStorage (bool has_extern)
+{
+ if (!IsValid())
+ return false;
+
+ QualType qual_type (GetCanonicalQualType());
+
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class)
+ {
+ case clang::Type::Record:
+ {
+ CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
+ if (cxx_record_decl)
+ {
+ cxx_record_decl->setHasExternalLexicalStorage (has_extern);
+ cxx_record_decl->setHasExternalVisibleStorage (has_extern);
+ return true;
}
+ }
break;
- case clang::Type::Typedef:
- return GetMinimumLanguage(ctx,
- llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
+
+ case clang::Type::Enum:
+ {
+ EnumDecl *enum_decl = cast<EnumType>(qual_type)->getDecl();
+ if (enum_decl)
+ {
+ enum_decl->setHasExternalLexicalStorage (has_extern);
+ enum_decl->setHasExternalVisibleStorage (has_extern);
+ return true;
+ }
+ }
+ break;
+
+ case clang::Type::ObjCObject:
+ case clang::Type::ObjCInterface:
+ {
+ const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
+ assert (objc_class_type);
+ if (objc_class_type)
+ {
+ ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
+
+ if (class_interface_decl)
+ {
+ class_interface_decl->setHasExternalLexicalStorage (has_extern);
+ class_interface_decl->setHasExternalVisibleStorage (has_extern);
+ return true;
+ }
+ }
}
+ break;
+
+ case clang::Type::Typedef:
+ return ClangASTType (m_ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()).SetHasExternalStorage (has_extern);
+
+ case clang::Type::Elaborated:
+ return ClangASTType (m_ast, cast<ElaboratedType>(qual_type)->getNamedType()).SetHasExternalStorage (has_extern);
+
+ case clang::Type::Paren:
+ return ClangASTType (m_ast, cast<ParenType>(qual_type)->desugar()).SetHasExternalStorage (has_extern);
+
+ default:
+ break;
}
- return lldb::eLanguageTypeC;
+ return false;
}
-lldb::Encoding
-ClangASTType::GetEncoding (clang_type_t clang_type, uint64_t &count)
+bool
+ClangASTType::SetTagTypeKind (int kind) const
{
- count = 1;
- clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type));
-
- switch (qual_type->getTypeClass())
+ if (IsValid())
{
- case clang::Type::UnaryTransform:
- break;
-
- case clang::Type::FunctionNoProto:
- case clang::Type::FunctionProto:
- break;
-
- case clang::Type::IncompleteArray:
- case clang::Type::VariableArray:
- break;
+ QualType tag_qual_type(GetQualType());
+ const clang::Type *clang_type = tag_qual_type.getTypePtr();
+ if (clang_type)
+ {
+ const TagType *tag_type = dyn_cast<TagType>(clang_type);
+ if (tag_type)
+ {
+ TagDecl *tag_decl = dyn_cast<TagDecl>(tag_type->getDecl());
+ if (tag_decl)
+ {
+ tag_decl->setTagKind ((TagDecl::TagKind)kind);
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+}
- case clang::Type::ConstantArray:
- break;
- case clang::Type::ExtVector:
- case clang::Type::Vector:
- // TODO: Set this to more than one???
- break;
+#pragma mark TagDecl
- case clang::Type::Builtin:
- switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind())
+bool
+ClangASTType::StartTagDeclarationDefinition ()
+{
+ if (IsValid())
+ {
+ QualType qual_type (GetQualType());
+ const clang::Type *t = qual_type.getTypePtr();
+ if (t)
{
- default: assert(0 && "Unknown builtin type!");
- 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::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;
+ const TagType *tag_type = dyn_cast<TagType>(t);
+ if (tag_type)
+ {
+ TagDecl *tag_decl = tag_type->getDecl();
+ if (tag_decl)
+ {
+ tag_decl->startDefinition();
+ return true;
+ }
+ }
+
+ const ObjCObjectType *object_type = dyn_cast<ObjCObjectType>(t);
+ if (object_type)
+ {
+ ObjCInterfaceDecl *interface_decl = object_type->getInterface();
+ if (interface_decl)
+ {
+ interface_decl->startDefinition();
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+}
- case clang::BuiltinType::NullPtr: return lldb::eEncodingUint;
+bool
+ClangASTType::CompleteTagDeclarationDefinition ()
+{
+ if (IsValid())
+ {
+ QualType qual_type (GetQualType());
+
+ CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
+
+ if (cxx_record_decl)
+ {
+ cxx_record_decl->completeDefinition();
+
+ return true;
}
- break;
- // All pointer types are represented as unsigned integer encodings.
- // We may nee to add a eEncodingPointer if we ever need to know the
- // difference
- case clang::Type::ObjCObjectPointer:
- case clang::Type::BlockPointer:
- case clang::Type::Pointer:
- case clang::Type::LValueReference:
- case clang::Type::RValueReference:
- case clang::Type::MemberPointer: return lldb::eEncodingUint;
- case clang::Type::Complex:
+
+ const EnumType *enum_type = dyn_cast<EnumType>(qual_type.getTypePtr());
+
+ if (enum_type)
{
- lldb::Encoding encoding = lldb::eEncodingIEEE754;
- if (qual_type->isComplexType())
- encoding = lldb::eEncodingIEEE754;
- else
+ EnumDecl *enum_decl = enum_type->getDecl();
+
+ if (enum_decl)
{
- const clang::ComplexType *complex_type = qual_type->getAsComplexIntegerType();
- if (complex_type)
- encoding = GetEncoding (complex_type->getElementType().getAsOpaquePtr(), count);
- else
- encoding = lldb::eEncodingSint;
+ /// TODO This really needs to be fixed.
+
+ unsigned NumPositiveBits = 1;
+ unsigned NumNegativeBits = 0;
+
+ 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 (m_ast->getTypeSize(enum_decl->getIntegerType()) < m_ast->getTypeSize(m_ast->IntTy))
+ {
+ if (enum_decl->getIntegerType()->isSignedIntegerType())
+ promotion_qual_type = m_ast->IntTy;
+ else
+ promotion_qual_type = m_ast->UnsignedIntTy;
+ }
+ else
+ promotion_qual_type = enum_decl->getIntegerType();
+
+ enum_decl->completeDefinition(enum_decl->getIntegerType(), promotion_qual_type, NumPositiveBits, NumNegativeBits);
+ return true;
}
- count = 2;
- return encoding;
}
+ }
+ return false;
+}
+
+
- case clang::Type::ObjCInterface: break;
- case clang::Type::Record: break;
- case clang::Type::Enum: return lldb::eEncodingSint;
- case clang::Type::Typedef:
- return GetEncoding(llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), count);
- case clang::Type::Elaborated:
- return ClangASTType::GetEncoding (llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), count);
- case clang::Type::Paren:
- return ClangASTType::GetEncoding (llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(), count);
-
- case clang::Type::DependentSizedArray:
- case clang::Type::DependentSizedExtVector:
- case clang::Type::UnresolvedUsing:
- case clang::Type::Attributed:
- case clang::Type::TemplateTypeParm:
- case clang::Type::SubstTemplateTypeParm:
- case clang::Type::SubstTemplateTypeParmPack:
- case clang::Type::Auto:
- case clang::Type::InjectedClassName:
- case clang::Type::DependentName:
- case clang::Type::DependentTemplateSpecialization:
- case clang::Type::PackExpansion:
- case clang::Type::ObjCObject:
-
- case clang::Type::TypeOfExpr:
- case clang::Type::TypeOf:
- case clang::Type::Decltype:
- case clang::Type::TemplateSpecialization:
- case clang::Type::Atomic:
- break;
+
+bool
+ClangASTType::AddEnumerationValueToEnumerationType (const ClangASTType &enumerator_clang_type,
+ const Declaration &decl,
+ const char *name,
+ int64_t enum_value,
+ uint32_t enum_value_bit_size)
+{
+ if (IsValid() && enumerator_clang_type.IsValid() && name && name[0])
+ {
+ QualType enum_qual_type (GetCanonicalQualType());
+
+ bool is_signed = false;
+ enumerator_clang_type.IsIntegerType (is_signed);
+ const clang::Type *clang_type = enum_qual_type.getTypePtr();
+ if (clang_type)
+ {
+ const EnumType *enum_type = dyn_cast<EnumType>(clang_type);
+
+ if (enum_type)
+ {
+ llvm::APSInt enum_llvm_apsint(enum_value_bit_size, is_signed);
+ enum_llvm_apsint = enum_value;
+ EnumConstantDecl *enumerator_decl =
+ EnumConstantDecl::Create (*m_ast,
+ enum_type->getDecl(),
+ SourceLocation(),
+ name ? &m_ast->Idents.get(name) : NULL, // Identifier
+ enumerator_clang_type.GetQualType(),
+ NULL,
+ enum_llvm_apsint);
+
+ if (enumerator_decl)
+ {
+ enum_type->getDecl()->addDecl(enumerator_decl);
+
+#ifdef LLDB_CONFIGURATION_DEBUG
+ VerifyDecl(enumerator_decl);
+#endif
+
+ return true;
+ }
+ }
+ }
}
- count = 0;
- return lldb::eEncodingInvalid;
+ return false;
}
-lldb::Format
-ClangASTType::GetFormat ()
+
+ClangASTType
+ClangASTType::GetEnumerationIntegerType () const
{
- return GetFormat (m_type);
+ QualType enum_qual_type (GetCanonicalQualType());
+ const clang::Type *clang_type = enum_qual_type.getTypePtr();
+ if (clang_type)
+ {
+ const EnumType *enum_type = dyn_cast<EnumType>(clang_type);
+ if (enum_type)
+ {
+ EnumDecl *enum_decl = enum_type->getDecl();
+ if (enum_decl)
+ return ClangASTType (m_ast, enum_decl->getIntegerType());
+ }
+ }
+ return ClangASTType();
}
-lldb::Format
-ClangASTType::GetFormat (clang_type_t clang_type)
+ClangASTType
+ClangASTType::CreateMemberPointerType (const ClangASTType &pointee_type) const
{
- if (clang_type == NULL)
- return lldb::eFormatDefault;
-
- clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type));
-
- switch (qual_type->getTypeClass())
+ if (IsValid() && pointee_type.IsValid())
{
- 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:
- return lldb::eFormatVoid; // no value
+ return ClangASTType (m_ast, m_ast->getMemberPointerType (pointee_type.GetQualType(),
+ GetQualType().getTypePtr()));
+ }
+ return ClangASTType();
+}
- case clang::Type::ExtVector:
- case clang::Type::Vector:
- break;
- case clang::Type::Builtin:
- switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind())
- {
- //default: assert(0 && "Unknown builtin type!");
- case clang::BuiltinType::UnknownAny:
- case clang::BuiltinType::Void:
- case clang::BuiltinType::BoundMember:
- break;
-
- case clang::BuiltinType::Bool: return lldb::eFormatBoolean;
- case clang::BuiltinType::Char_S:
- case clang::BuiltinType::SChar:
- case clang::BuiltinType::WChar_S:
- case clang::BuiltinType::Char_U:
- case clang::BuiltinType::UChar:
- case clang::BuiltinType::WChar_U: return lldb::eFormatChar;
- case clang::BuiltinType::Char16: return lldb::eFormatUnicode16;
- case clang::BuiltinType::Char32: return lldb::eFormatUnicode32;
- case clang::BuiltinType::UShort: return lldb::eFormatUnsigned;
- case clang::BuiltinType::Short: return lldb::eFormatDecimal;
- case clang::BuiltinType::UInt: return lldb::eFormatUnsigned;
- case clang::BuiltinType::Int: return lldb::eFormatDecimal;
- case clang::BuiltinType::ULong: return lldb::eFormatUnsigned;
- case clang::BuiltinType::Long: return lldb::eFormatDecimal;
- case clang::BuiltinType::ULongLong: return lldb::eFormatUnsigned;
- case clang::BuiltinType::LongLong: return lldb::eFormatDecimal;
- case clang::BuiltinType::UInt128: return lldb::eFormatUnsigned;
- case clang::BuiltinType::Int128: return lldb::eFormatDecimal;
- case clang::BuiltinType::Float: return lldb::eFormatFloat;
- case clang::BuiltinType::Double: return lldb::eFormatFloat;
- case clang::BuiltinType::LongDouble: return lldb::eFormatFloat;
- case clang::BuiltinType::NullPtr:
- case clang::BuiltinType::Overload:
- case clang::BuiltinType::Dependent:
- case clang::BuiltinType::ObjCId:
- case clang::BuiltinType::ObjCClass:
- case clang::BuiltinType::ObjCSel:
- case clang::BuiltinType::Half:
- case clang::BuiltinType::ARCUnbridgedCast:
- case clang::BuiltinType::PseudoObject:
- case clang::BuiltinType::BuiltinFn:
- 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::OCLSampler:
- return lldb::eFormatHex;
- }
- break;
- case clang::Type::ObjCObjectPointer: return lldb::eFormatHex;
- case clang::Type::BlockPointer: return lldb::eFormatHex;
- case clang::Type::Pointer: return lldb::eFormatHex;
- case clang::Type::LValueReference:
- case clang::Type::RValueReference: return lldb::eFormatHex;
- case clang::Type::MemberPointer: break;
- case clang::Type::Complex:
+size_t
+ClangASTType::ConvertStringToFloatValue (const char *s, uint8_t *dst, size_t dst_size) const
+{
+ if (IsValid())
+ {
+ QualType qual_type (GetCanonicalQualType());
+ uint32_t count = 0;
+ bool is_complex = false;
+ if (IsFloatingPointType (count, is_complex))
{
- if (qual_type->isComplexType())
- return lldb::eFormatComplex;
- else
- return lldb::eFormatComplexInteger;
+ // TODO: handle complex and vector types
+ if (count != 1)
+ return false;
+
+ StringRef s_sref(s);
+ APFloat ap_float(m_ast->getFloatTypeSemantics(qual_type), s_sref);
+
+ const uint64_t bit_size = m_ast->getTypeSize (qual_type);
+ 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);
+ return byte_size;
+ }
+ }
}
- case clang::Type::ObjCInterface: break;
- case clang::Type::Record: break;
- case clang::Type::Enum: return lldb::eFormatEnum;
- case clang::Type::Typedef:
- return ClangASTType::GetFormat(llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
- case clang::Type::Auto:
- return ClangASTType::GetFormat(llvm::cast<clang::AutoType>(qual_type)->desugar().getAsOpaquePtr());
- case clang::Type::Paren:
- return ClangASTType::GetFormat(llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr());
- case clang::Type::Elaborated:
- return ClangASTType::GetFormat(llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
- case clang::Type::DependentSizedArray:
- case clang::Type::DependentSizedExtVector:
- case clang::Type::UnresolvedUsing:
- case clang::Type::Attributed:
- case clang::Type::TemplateTypeParm:
- case clang::Type::SubstTemplateTypeParm:
- case clang::Type::SubstTemplateTypeParmPack:
- case clang::Type::InjectedClassName:
- case clang::Type::DependentName:
- case clang::Type::DependentTemplateSpecialization:
- case clang::Type::PackExpansion:
- case clang::Type::ObjCObject:
-
- case clang::Type::TypeOfExpr:
- case clang::Type::TypeOf:
- case clang::Type::Decltype:
- case clang::Type::TemplateSpecialization:
- case clang::Type::Atomic:
- break;
}
- // We don't know hot to display this type...
- return lldb::eFormatBytes;
+ return 0;
}
-void
-ClangASTType::DumpValue
-(
- ExecutionContext *exe_ctx,
- Stream *s,
- lldb::Format format,
- const lldb_private::DataExtractor &data,
- lldb::offset_t data_byte_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
-)
-{
- return DumpValue (m_ast,
- m_type,
- exe_ctx,
- s,
- format,
- data,
- data_byte_offset,
- data_byte_size,
- bitfield_bit_size,
- bitfield_bit_offset,
- show_types,
- show_summary,
- verbose,
- depth);
-}
-
+
+//----------------------------------------------------------------------
+// Dumping types
+//----------------------------------------------------------------------
#define DEPTH_INCREMENT 2
+
void
-ClangASTType::DumpValue
-(
- clang::ASTContext *ast_context,
- clang_type_t clang_type,
- ExecutionContext *exe_ctx,
- Stream *s,
- lldb::Format format,
- const lldb_private::DataExtractor &data,
- lldb::offset_t data_byte_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
-)
+ClangASTType::DumpValue (ExecutionContext *exe_ctx,
+ Stream *s,
+ lldb::Format format,
+ const lldb_private::DataExtractor &data,
+ lldb::offset_t data_byte_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)
{
- clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type));
+ if (!IsValid())
+ return;
+
+ QualType qual_type(GetQualType());
switch (qual_type->getTypeClass())
{
case clang::Type::Record:
- if (ClangASTContext::GetCompleteType (ast_context, clang_type))
+ if (GetCompleteType ())
{
- const clang::RecordType *record_type = llvm::cast<clang::RecordType>(qual_type.getTypePtr());
- const clang::RecordDecl *record_decl = record_type->getDecl();
+ const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
+ const RecordDecl *record_decl = record_type->getDecl();
assert(record_decl);
uint32_t field_bit_offset = 0;
uint32_t field_byte_offset = 0;
- const clang::ASTRecordLayout &record_layout = ast_context->getASTRecordLayout(record_decl);
+ const ASTRecordLayout &record_layout = m_ast->getASTRecordLayout(record_decl);
uint32_t child_idx = 0;
-
- const clang::CXXRecordDecl *cxx_record_decl = llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
+ const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
if (cxx_record_decl)
{
// We might have base classes to print out first
- clang::CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
+ CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
base_class != base_class_end;
++base_class)
{
- const clang::CXXRecordDecl *base_class_decl = llvm::cast<clang::CXXRecordDecl>(base_class->getType()->getAs<clang::RecordType>()->getDecl());
+ const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
// Skip empty base classes
if (verbose == false && ClangASTContext::RecordHasFields(base_class_decl) == false)
@@ -786,35 +5561,34 @@ ClangASTType::DumpValue
else
s->PutChar(',');
- clang::QualType base_class_qual_type = base_class->getType();
+ QualType base_class_qual_type = base_class->getType();
std::string base_class_type_name(base_class_qual_type.getAsString());
// Indent and print the base class type name
s->Printf("\n%*s%s ", depth + DEPTH_INCREMENT, "", base_class_type_name.c_str());
- std::pair<uint64_t, unsigned> base_class_type_info = ast_context->getTypeInfo(base_class_qual_type);
+ std::pair<uint64_t, unsigned> base_class_type_info = m_ast->getTypeInfo(base_class_qual_type);
// Dump the value of the member
- DumpValue (ast_context, // The clang AST context for this type
- base_class_qual_type.getAsOpaquePtr(),// The clang type we want to dump
- exe_ctx,
- s, // Stream to dump to
- ClangASTType::GetFormat(base_class_qual_type.getAsOpaquePtr()), // The format with which to display the member
- data, // Data buffer containing all bytes for this type
- data_byte_offset + field_byte_offset,// Offset into "data" where to grab value from
- base_class_type_info.first / 8, // Size of this type in bytes
- 0, // Bitfield bit size
- 0, // Bitfield bit offset
- show_types, // Boolean indicating if we should show the variable types
- show_summary, // Boolean indicating if we should show a summary for the current type
- verbose, // Verbose output?
- depth + DEPTH_INCREMENT); // Scope depth for any types that have children
+ ClangASTType base_clang_type(m_ast, base_class_qual_type);
+ base_clang_type.DumpValue (exe_ctx,
+ s, // Stream to dump to
+ base_clang_type.GetFormat(), // The format with which to display the member
+ data, // Data buffer containing all bytes for this type
+ data_byte_offset + field_byte_offset,// Offset into "data" where to grab value from
+ base_class_type_info.first / 8, // Size of this type in bytes
+ 0, // Bitfield bit size
+ 0, // Bitfield bit offset
+ show_types, // Boolean indicating if we should show the variable types
+ show_summary, // Boolean indicating if we should show a summary for the current type
+ verbose, // Verbose output?
+ depth + DEPTH_INCREMENT); // Scope depth for any types that have children
++child_idx;
}
}
uint32_t field_idx = 0;
- clang::RecordDecl::field_iterator field, field_end;
+ RecordDecl::field_iterator field, field_end;
for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field, ++field_idx, ++child_idx)
{
// Print the starting squiggly bracket (if this is the
@@ -828,18 +5602,18 @@ ClangASTType::DumpValue
// Indent
s->Printf("\n%*s", depth + DEPTH_INCREMENT, "");
- clang::QualType field_type = field->getType();
+ QualType field_type = field->getType();
// Print the member type if requested
// Figure out the type byte size (field_type_info.first) and
// alignment (field_type_info.second) from the AST context.
- std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(field_type);
+ std::pair<uint64_t, unsigned> field_type_info = m_ast->getTypeInfo(field_type);
assert(field_idx < record_layout.getFieldCount());
// Figure out the field offset within the current struct/union/class type
field_bit_offset = record_layout.getFieldOffset (field_idx);
field_byte_offset = field_bit_offset / 8;
uint32_t field_bitfield_bit_size = 0;
uint32_t field_bitfield_bit_offset = 0;
- if (ClangASTContext::FieldIsBitfield (ast_context, *field, field_bitfield_bit_size))
+ if (ClangASTContext::FieldIsBitfield (m_ast, *field, field_bitfield_bit_size))
field_bitfield_bit_offset = field_bit_offset % 8;
if (show_types)
@@ -855,20 +5629,19 @@ ClangASTType::DumpValue
// Dump the value of the member
- DumpValue (ast_context, // The clang AST context for this type
- field_type.getAsOpaquePtr(), // The clang type we want to dump
- exe_ctx,
- s, // Stream to dump to
- ClangASTType::GetFormat(field_type.getAsOpaquePtr()), // The format with which to display the member
- data, // Data buffer containing all bytes for this type
- data_byte_offset + field_byte_offset,// Offset into "data" where to grab value from
- field_type_info.first / 8, // Size of this type in bytes
- field_bitfield_bit_size, // Bitfield bit size
- field_bitfield_bit_offset, // Bitfield bit offset
- show_types, // Boolean indicating if we should show the variable types
- show_summary, // Boolean indicating if we should show a summary for the current type
- verbose, // Verbose output?
- depth + DEPTH_INCREMENT); // Scope depth for any types that have children
+ ClangASTType field_clang_type (m_ast, field_type);
+ field_clang_type.DumpValue (exe_ctx,
+ s, // Stream to dump to
+ field_clang_type.GetFormat(), // The format with which to display the member
+ data, // Data buffer containing all bytes for this type
+ data_byte_offset + field_byte_offset,// Offset into "data" where to grab value from
+ field_type_info.first / 8, // Size of this type in bytes
+ field_bitfield_bit_size, // Bitfield bit size
+ field_bitfield_bit_offset, // Bitfield bit offset
+ show_types, // Boolean indicating if we should show the variable types
+ show_summary, // Boolean indicating if we should show a summary for the current type
+ verbose, // Verbose output?
+ depth + DEPTH_INCREMENT); // Scope depth for any types that have children
}
// Indent the trailing squiggly bracket
@@ -878,12 +5651,12 @@ ClangASTType::DumpValue
return;
case clang::Type::Enum:
- if (ClangASTContext::GetCompleteType (ast_context, clang_type))
+ if (GetCompleteType ())
{
- const clang::EnumType *enum_type = llvm::cast<clang::EnumType>(qual_type.getTypePtr());
- const clang::EnumDecl *enum_decl = enum_type->getDecl();
+ const EnumType *enum_type = cast<EnumType>(qual_type.getTypePtr());
+ const EnumDecl *enum_decl = enum_type->getDecl();
assert(enum_decl);
- clang::EnumDecl::enumerator_iterator enum_pos, enum_end_pos;
+ EnumDecl::enumerator_iterator enum_pos, enum_end_pos;
lldb::offset_t offset = data_byte_offset;
const int64_t enum_value = data.GetMaxU64Bitfield(&offset, data_byte_size, bitfield_bit_size, bitfield_bit_offset);
for (enum_pos = enum_decl->enumerator_begin(), enum_end_pos = enum_decl->enumerator_end(); enum_pos != enum_end_pos; ++enum_pos)
@@ -902,9 +5675,9 @@ ClangASTType::DumpValue
case clang::Type::ConstantArray:
{
- const clang::ConstantArrayType *array = llvm::cast<clang::ConstantArrayType>(qual_type.getTypePtr());
+ const ConstantArrayType *array = cast<ConstantArrayType>(qual_type.getTypePtr());
bool is_array_of_characters = false;
- clang::QualType element_qual_type = array->getElementType();
+ QualType element_qual_type = array->getElementType();
const clang::Type *canonical_type = element_qual_type->getCanonicalTypeInternal().getTypePtr();
if (canonical_type)
@@ -912,7 +5685,7 @@ ClangASTType::DumpValue
const uint64_t element_count = array->getSize().getLimitedValue();
- std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(element_qual_type);
+ std::pair<uint64_t, unsigned> field_type_info = m_ast->getTypeInfo(element_qual_type);
uint32_t element_idx = 0;
uint32_t element_offset = 0;
@@ -928,7 +5701,8 @@ ClangASTType::DumpValue
}
else
{
- lldb::Format element_format = ClangASTType::GetFormat(element_qual_type.getAsOpaquePtr());
+ ClangASTType element_clang_type(m_ast, element_qual_type);
+ lldb::Format element_format = element_clang_type.GetFormat();
for (element_idx = 0; element_idx < element_count; ++element_idx)
{
@@ -947,20 +5721,18 @@ ClangASTType::DumpValue
element_offset = element_idx * element_stride;
// Dump the value of the member
- DumpValue (ast_context, // The clang AST context for this type
- element_qual_type.getAsOpaquePtr(), // The clang type we want to dump
- exe_ctx,
- s, // Stream to dump to
- element_format, // The format with which to display the element
- data, // Data buffer containing all bytes for this type
- data_byte_offset + element_offset,// Offset into "data" where to grab value from
- element_byte_size, // Size of this type in bytes
- 0, // Bitfield bit size
- 0, // Bitfield bit offset
- show_types, // Boolean indicating if we should show the variable types
- show_summary, // Boolean indicating if we should show a summary for the current type
- verbose, // Verbose output?
- depth + DEPTH_INCREMENT); // Scope depth for any types that have children
+ element_clang_type.DumpValue (exe_ctx,
+ s, // Stream to dump to
+ element_format, // The format with which to display the element
+ data, // Data buffer containing all bytes for this type
+ data_byte_offset + element_offset,// Offset into "data" where to grab value from
+ element_byte_size, // Size of this type in bytes
+ 0, // Bitfield bit size
+ 0, // Bitfield bit offset
+ show_types, // Boolean indicating if we should show the variable types
+ show_summary, // Boolean indicating if we should show a summary for the current type
+ verbose, // Verbose output?
+ depth + DEPTH_INCREMENT); // Scope depth for any types that have children
}
// Indent the trailing squiggly bracket
@@ -972,115 +5744,98 @@ ClangASTType::DumpValue
case clang::Type::Typedef:
{
- clang::QualType typedef_qual_type = llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType();
- lldb::Format typedef_format = ClangASTType::GetFormat(typedef_qual_type.getAsOpaquePtr());
- std::pair<uint64_t, unsigned> typedef_type_info = ast_context->getTypeInfo(typedef_qual_type);
+ QualType typedef_qual_type = cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType();
+
+ ClangASTType typedef_clang_type (m_ast, typedef_qual_type);
+ lldb::Format typedef_format = typedef_clang_type.GetFormat();
+ std::pair<uint64_t, unsigned> typedef_type_info = m_ast->getTypeInfo(typedef_qual_type);
uint64_t typedef_byte_size = typedef_type_info.first / 8;
- return DumpValue (ast_context, // The clang AST context for this type
- typedef_qual_type.getAsOpaquePtr(), // The clang type we want to dump
- exe_ctx,
- s, // Stream to dump to
- typedef_format, // The format with which to display the element
- data, // Data buffer containing all bytes for this type
- data_byte_offset, // Offset into "data" where to grab value from
- typedef_byte_size, // Size of this type in bytes
- bitfield_bit_size, // Bitfield bit size
- bitfield_bit_offset,// Bitfield bit offset
- show_types, // Boolean indicating if we should show the variable types
- show_summary, // Boolean indicating if we should show a summary for the current type
- verbose, // Verbose output?
- depth); // Scope depth for any types that have children
+ return typedef_clang_type.DumpValue (exe_ctx,
+ s, // Stream to dump to
+ typedef_format, // The format with which to display the element
+ data, // Data buffer containing all bytes for this type
+ data_byte_offset, // Offset into "data" where to grab value from
+ typedef_byte_size, // Size of this type in bytes
+ bitfield_bit_size, // Bitfield bit size
+ bitfield_bit_offset,// Bitfield bit offset
+ show_types, // Boolean indicating if we should show the variable types
+ show_summary, // Boolean indicating if we should show a summary for the current type
+ verbose, // Verbose output?
+ depth); // Scope depth for any types that have children
}
break;
case clang::Type::Elaborated:
{
- clang::QualType elaborated_qual_type = llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType();
- lldb::Format elaborated_format = ClangASTType::GetFormat(elaborated_qual_type.getAsOpaquePtr());
- std::pair<uint64_t, unsigned> elaborated_type_info = ast_context->getTypeInfo(elaborated_qual_type);
+ QualType elaborated_qual_type = cast<ElaboratedType>(qual_type)->getNamedType();
+ ClangASTType elaborated_clang_type (m_ast, elaborated_qual_type);
+ lldb::Format elaborated_format = elaborated_clang_type.GetFormat();
+ std::pair<uint64_t, unsigned> elaborated_type_info = m_ast->getTypeInfo(elaborated_qual_type);
uint64_t elaborated_byte_size = elaborated_type_info.first / 8;
- return DumpValue (ast_context, // The clang AST context for this type
- elaborated_qual_type.getAsOpaquePtr(), // The clang type we want to dump
- exe_ctx,
- s, // Stream to dump to
- elaborated_format, // The format with which to display the element
- data, // Data buffer containing all bytes for this type
- data_byte_offset, // Offset into "data" where to grab value from
- elaborated_byte_size, // Size of this type in bytes
- bitfield_bit_size, // Bitfield bit size
- bitfield_bit_offset,// Bitfield bit offset
- show_types, // Boolean indicating if we should show the variable types
- show_summary, // Boolean indicating if we should show a summary for the current type
- verbose, // Verbose output?
- depth); // Scope depth for any types that have children
+ return elaborated_clang_type.DumpValue (exe_ctx,
+ s, // Stream to dump to
+ elaborated_format, // The format with which to display the element
+ data, // Data buffer containing all bytes for this type
+ data_byte_offset, // Offset into "data" where to grab value from
+ elaborated_byte_size, // Size of this type in bytes
+ bitfield_bit_size, // Bitfield bit size
+ bitfield_bit_offset,// Bitfield bit offset
+ show_types, // Boolean indicating if we should show the variable types
+ show_summary, // Boolean indicating if we should show a summary for the current type
+ verbose, // Verbose output?
+ depth); // Scope depth for any types that have children
}
break;
case clang::Type::Paren:
- {
- clang::QualType desugar_qual_type = llvm::cast<clang::ParenType>(qual_type)->desugar();
- lldb::Format desugar_format = ClangASTType::GetFormat(desugar_qual_type.getAsOpaquePtr());
- std::pair<uint64_t, unsigned> desugar_type_info = ast_context->getTypeInfo(desugar_qual_type);
- uint64_t desugar_byte_size = desugar_type_info.first / 8;
-
- return DumpValue (ast_context, // The clang AST context for this type
- desugar_qual_type.getAsOpaquePtr(), // The clang type we want to dump
- exe_ctx,
- s, // Stream to dump to
- desugar_format, // The format with which to display the element
- data, // Data buffer containing all bytes for this type
- data_byte_offset, // Offset into "data" where to grab value from
- desugar_byte_size, // Size of this type in bytes
- bitfield_bit_size, // Bitfield bit size
- bitfield_bit_offset,// Bitfield bit offset
- show_types, // Boolean indicating if we should show the variable types
- show_summary, // Boolean indicating if we should show a summary for the current type
- verbose, // Verbose output?
- depth); // Scope depth for any types that have children
- }
+ {
+ QualType desugar_qual_type = cast<ParenType>(qual_type)->desugar();
+ ClangASTType desugar_clang_type (m_ast, desugar_qual_type);
+
+ lldb::Format desugar_format = desugar_clang_type.GetFormat();
+ std::pair<uint64_t, unsigned> desugar_type_info = m_ast->getTypeInfo(desugar_qual_type);
+ uint64_t desugar_byte_size = desugar_type_info.first / 8;
+
+ return desugar_clang_type.DumpValue (exe_ctx,
+ s, // Stream to dump to
+ desugar_format, // The format with which to display the element
+ data, // Data buffer containing all bytes for this type
+ data_byte_offset, // Offset into "data" where to grab value from
+ desugar_byte_size, // Size of this type in bytes
+ bitfield_bit_size, // Bitfield bit size
+ bitfield_bit_offset,// Bitfield bit offset
+ show_types, // Boolean indicating if we should show the variable types
+ show_summary, // Boolean indicating if we should show a summary for the current type
+ verbose, // Verbose output?
+ depth); // Scope depth for any types that have children
+ }
break;
default:
// We are down the a scalar type that we just need to display.
- data.Dump(s, data_byte_offset, format, data_byte_size, 1, UINT32_MAX, LLDB_INVALID_ADDRESS, bitfield_bit_size, bitfield_bit_offset);
+ data.Dump(s,
+ data_byte_offset,
+ format,
+ data_byte_size,
+ 1,
+ UINT32_MAX,
+ LLDB_INVALID_ADDRESS,
+ bitfield_bit_size,
+ bitfield_bit_offset);
if (show_summary)
- DumpSummary (ast_context, clang_type, exe_ctx, s, data, data_byte_offset, data_byte_size);
+ DumpSummary (exe_ctx, s, data, data_byte_offset, data_byte_size);
break;
}
}
-bool
-ClangASTType::DumpTypeValue (Stream *s,
- lldb::Format format,
- const lldb_private::DataExtractor &data,
- lldb::offset_t byte_offset,
- size_t byte_size,
- uint32_t bitfield_bit_size,
- uint32_t bitfield_bit_offset,
- ExecutionContextScope *exe_scope)
-{
- return DumpTypeValue (m_ast,
- m_type,
- s,
- format,
- data,
- byte_offset,
- byte_size,
- bitfield_bit_size,
- bitfield_bit_offset,
- exe_scope);
-}
-
bool
-ClangASTType::DumpTypeValue (clang::ASTContext *ast_context,
- clang_type_t clang_type,
- Stream *s,
+ClangASTType::DumpTypeValue (Stream *s,
lldb::Format format,
const lldb_private::DataExtractor &data,
lldb::offset_t byte_offset,
@@ -1089,47 +5844,48 @@ ClangASTType::DumpTypeValue (clang::ASTC
uint32_t bitfield_bit_offset,
ExecutionContextScope *exe_scope)
{
- clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type));
- if (ClangASTContext::IsAggregateType (clang_type))
+ if (!IsValid())
+ return false;
+ if (IsAggregateType())
{
- return 0;
+ return false;
}
else
{
+ QualType qual_type(GetQualType());
+
const clang::Type::TypeClass type_class = qual_type->getTypeClass();
-
switch (type_class)
{
case clang::Type::Typedef:
{
- clang::QualType typedef_qual_type = llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType();
+ QualType typedef_qual_type = cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType();
+ ClangASTType typedef_clang_type (m_ast, typedef_qual_type);
if (format == eFormatDefault)
- format = ClangASTType::GetFormat(typedef_qual_type.getAsOpaquePtr());
- std::pair<uint64_t, unsigned> typedef_type_info = ast_context->getTypeInfo(typedef_qual_type);
+ format = typedef_clang_type.GetFormat();
+ std::pair<uint64_t, unsigned> typedef_type_info = m_ast->getTypeInfo(typedef_qual_type);
uint64_t typedef_byte_size = typedef_type_info.first / 8;
- return ClangASTType::DumpTypeValue (ast_context, // The clang AST context for this type
- typedef_qual_type.getAsOpaquePtr(), // The clang type we want to dump
- s,
- format, // The format with which to display the element
- data, // Data buffer containing all bytes for this type
- byte_offset, // Offset into "data" where to grab value from
- typedef_byte_size, // Size of this type in bytes
- bitfield_bit_size, // Size in bits of a bitfield value, if zero don't treat as a bitfield
- bitfield_bit_offset, // Offset in bits of a bitfield value if bitfield_bit_size != 0
- exe_scope);
+ return typedef_clang_type.DumpTypeValue (s,
+ format, // The format with which to display the element
+ data, // Data buffer containing all bytes for this type
+ byte_offset, // Offset into "data" where to grab value from
+ typedef_byte_size, // Size of this type in bytes
+ bitfield_bit_size, // Size in bits of a bitfield value, if zero don't treat as a bitfield
+ bitfield_bit_offset, // Offset in bits of a bitfield value if bitfield_bit_size != 0
+ exe_scope);
}
break;
case clang::Type::Enum:
// If our format is enum or default, show the enumeration value as
// its enumeration string value, else just display it as requested.
- if ((format == eFormatEnum || format == eFormatDefault) && ClangASTContext::GetCompleteType (ast_context, clang_type))
+ if ((format == eFormatEnum || format == eFormatDefault) && GetCompleteType ())
{
- const clang::EnumType *enum_type = llvm::cast<clang::EnumType>(qual_type.getTypePtr());
- const clang::EnumDecl *enum_decl = enum_type->getDecl();
+ const EnumType *enum_type = cast<EnumType>(qual_type.getTypePtr());
+ const EnumDecl *enum_decl = enum_type->getDecl();
assert(enum_decl);
- clang::EnumDecl::enumerator_iterator enum_pos, enum_end_pos;
+ EnumDecl::enumerator_iterator enum_pos, enum_end_pos;
const bool is_signed = qual_type->isSignedIntegerOrEnumerationType();
lldb::offset_t offset = byte_offset;
if (is_signed)
@@ -1241,38 +5997,14 @@ ClangASTType::DumpTypeValue (clang::ASTC
void
-ClangASTType::DumpSummary
-(
- ExecutionContext *exe_ctx,
- Stream *s,
- const lldb_private::DataExtractor &data,
- lldb::offset_t data_byte_offset,
- size_t data_byte_size
-)
-{
- return DumpSummary (m_ast,
- m_type,
- exe_ctx,
- s,
- data,
- data_byte_offset,
- data_byte_size);
-}
-
-void
-ClangASTType::DumpSummary
-(
- clang::ASTContext *ast_context,
- clang_type_t clang_type,
- ExecutionContext *exe_ctx,
- Stream *s,
- const lldb_private::DataExtractor &data,
- lldb::offset_t data_byte_offset,
- size_t data_byte_size
-)
+ClangASTType::DumpSummary (ExecutionContext *exe_ctx,
+ Stream *s,
+ const lldb_private::DataExtractor &data,
+ lldb::offset_t data_byte_offset,
+ size_t data_byte_size)
{
uint32_t length = 0;
- if (ClangASTContext::IsCStringType (clang_type, length))
+ if (IsCStringType (length))
{
if (exe_ctx)
{
@@ -1312,104 +6044,8 @@ ClangASTType::DumpSummary
}
}
-uint64_t
-ClangASTType::GetClangTypeByteSize ()
-{
- return (GetClangTypeBitWidth (m_ast, m_type) + 7) / 8;
-}
-
-uint64_t
-ClangASTType::GetClangTypeByteSize (clang::ASTContext *ast_context, clang_type_t clang_type)
-{
- return (GetClangTypeBitWidth (ast_context, clang_type) + 7) / 8;
-}
-
-uint64_t
-ClangASTType::GetClangTypeBitWidth ()
-{
- return GetClangTypeBitWidth (m_ast, m_type);
-}
-
-uint64_t
-ClangASTType::GetClangTypeBitWidth (clang::ASTContext *ast_context, clang_type_t clang_type)
-{
- if (ClangASTContext::GetCompleteType (ast_context, clang_type))
- {
- clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type));
- const uint32_t bit_size = ast_context->getTypeSize (qual_type);
- if (bit_size == 0)
- {
- if (qual_type->isIncompleteArrayType())
- return ast_context->getTypeSize (qual_type->getArrayElementTypeNoTypeQual()->getCanonicalTypeUnqualified());
- }
- return bit_size;
- }
- return 0;
-}
-
-size_t
-ClangASTType::GetTypeBitAlign ()
-{
- return GetTypeBitAlign (m_ast, m_type);
-}
-
-size_t
-ClangASTType::GetTypeBitAlign (clang::ASTContext *ast_context, clang_type_t clang_type)
-{
- if (ClangASTContext::GetCompleteType (ast_context, clang_type))
- return ast_context->getTypeAlign(clang::QualType::getFromOpaquePtr(clang_type));
- return 0;
-}
-
-
-bool
-ClangASTType::IsDefined()
-{
- return ClangASTType::IsDefined (m_type);
-}
-
-bool
-ClangASTType::IsDefined (clang_type_t clang_type)
-{
- clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type));
- const clang::TagType *tag_type = llvm::dyn_cast<clang::TagType>(qual_type.getTypePtr());
- if (tag_type)
- {
- clang::TagDecl *tag_decl = tag_type->getDecl();
- if (tag_decl)
- return tag_decl->isCompleteDefinition();
- return false;
- }
- else
- {
- 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();
- if (class_interface_decl)
- return class_interface_decl->getDefinition() != NULL;
- return false;
- }
- }
- return true;
-}
-
-bool
-ClangASTType::IsConst()
-{
- return ClangASTType::IsConst (m_type);
-}
-
-bool
-ClangASTType::IsConst (lldb::clang_type_t clang_type)
-{
- clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type));
-
- return qual_type.isConstQualified();
-}
-
void
-ClangASTType::DumpTypeDescription ()
+ClangASTType::DumpTypeDescription () const
{
StreamFile s (stdout, false);
DumpTypeDescription (&s);
@@ -1421,22 +6057,14 @@ ClangASTType::DumpTypeDescription ()
}
void
-ClangASTType::DumpTypeDescription (Stream *s)
-{
- return DumpTypeDescription (m_ast, m_type, s);
-}
-
-// Dump the full description of a type. For classes this means all of the
-// ivars and member functions, for structs/unions all of the members.
-void
-ClangASTType::DumpTypeDescription (clang::ASTContext *ast_context, clang_type_t clang_type, Stream *s)
+ClangASTType::DumpTypeDescription (Stream *s) const
{
- if (clang_type)
+ if (IsValid())
{
- clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type));
+ QualType qual_type(GetQualType());
- llvm::SmallVector<char, 1024> buf;
- llvm::raw_svector_ostream llvm_ostrm (buf);
+ SmallVector<char, 1024> buf;
+ raw_svector_ostream llvm_ostrm (buf);
const clang::Type::TypeClass type_class = qual_type->getTypeClass();
switch (type_class)
@@ -1444,16 +6072,16 @@ ClangASTType::DumpTypeDescription (clang
case clang::Type::ObjCObject:
case clang::Type::ObjCInterface:
{
- ClangASTContext::GetCompleteType (ast_context, clang_type);
+ GetCompleteType ();
- const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
+ const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
assert (objc_class_type);
if (objc_class_type)
{
- clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
+ ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
if (class_interface_decl)
{
- clang::PrintingPolicy policy = ast_context->getPrintingPolicy();
+ PrintingPolicy policy = m_ast->getPrintingPolicy();
class_interface_decl->print(llvm_ostrm, policy, s->GetIndentLevel());
}
}
@@ -1462,10 +6090,10 @@ ClangASTType::DumpTypeDescription (clang
case clang::Type::Typedef:
{
- const clang::TypedefType *typedef_type = qual_type->getAs<clang::TypedefType>();
+ const TypedefType *typedef_type = qual_type->getAs<TypedefType>();
if (typedef_type)
{
- const clang::TypedefNameDecl *typedef_decl = typedef_type->getDecl();
+ const TypedefNameDecl *typedef_decl = typedef_type->getDecl();
std::string clang_typedef_name (typedef_decl->getQualifiedNameAsString());
if (!clang_typedef_name.empty())
{
@@ -1477,38 +6105,34 @@ ClangASTType::DumpTypeDescription (clang
break;
case clang::Type::Elaborated:
- DumpTypeDescription (ast_context,
- llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(),
- s);
+ ClangASTType (m_ast, cast<ElaboratedType>(qual_type)->getNamedType()).DumpTypeDescription(s);
return;
case clang::Type::Paren:
- DumpTypeDescription (ast_context,
- llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
- s);
+ ClangASTType (m_ast, cast<ParenType>(qual_type)->desugar()).DumpTypeDescription(s);
return;
case clang::Type::Record:
{
- ClangASTContext::GetCompleteType (ast_context, clang_type);
+ GetCompleteType ();
- const clang::RecordType *record_type = llvm::cast<clang::RecordType>(qual_type.getTypePtr());
- const clang::RecordDecl *record_decl = record_type->getDecl();
- const clang::CXXRecordDecl *cxx_record_decl = llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
+ const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
+ const RecordDecl *record_decl = record_type->getDecl();
+ const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
if (cxx_record_decl)
- cxx_record_decl->print(llvm_ostrm, ast_context->getPrintingPolicy(), s->GetIndentLevel());
+ cxx_record_decl->print(llvm_ostrm, m_ast->getPrintingPolicy(), s->GetIndentLevel());
else
- record_decl->print(llvm_ostrm, ast_context->getPrintingPolicy(), s->GetIndentLevel());
+ record_decl->print(llvm_ostrm, m_ast->getPrintingPolicy(), s->GetIndentLevel());
}
break;
default:
{
- const clang::TagType *tag_type = llvm::dyn_cast<clang::TagType>(qual_type.getTypePtr());
+ const TagType *tag_type = dyn_cast<TagType>(qual_type.getTypePtr());
if (tag_type)
{
- clang::TagDecl *tag_decl = tag_type->getDecl();
+ TagDecl *tag_decl = tag_type->getDecl();
if (tag_decl)
tag_decl->print(llvm_ostrm, 0);
}
@@ -1530,49 +6154,27 @@ ClangASTType::DumpTypeDescription (clang
}
bool
-ClangASTType::GetValueAsScalar
-(
- const lldb_private::DataExtractor &data,
- lldb::offset_t data_byte_offset,
- size_t data_byte_size,
- Scalar &value
-)
-{
- return GetValueAsScalar (m_ast,
- m_type,
- data,
- data_byte_offset,
- data_byte_size,
- value);
-}
-
-bool
-ClangASTType::GetValueAsScalar
-(
- clang::ASTContext *ast_context,
- clang_type_t clang_type,
- const lldb_private::DataExtractor &data,
- lldb::offset_t data_byte_offset,
- size_t data_byte_size,
- Scalar &value
-)
+ClangASTType::GetValueAsScalar (const lldb_private::DataExtractor &data,
+ lldb::offset_t data_byte_offset,
+ size_t data_byte_size,
+ Scalar &value) const
{
- clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type));
+ if (!IsValid())
+ return false;
- if (ClangASTContext::IsAggregateType (clang_type))
+ if (IsAggregateType ())
{
return false; // Aggregate types don't have scalar values
}
else
{
uint64_t count = 0;
- lldb::Encoding encoding = GetEncoding (clang_type, count);
+ lldb::Encoding encoding = GetEncoding (count);
if (encoding == lldb::eEncodingInvalid || count != 1)
return false;
- uint64_t bit_width = ast_context->getTypeSize(qual_type);
- uint64_t byte_size = (bit_width + 7 ) / 8;
+ const uint64_t byte_size = GetByteSize();
lldb::offset_t offset = data_byte_offset;
switch (encoding)
{
@@ -1690,31 +6292,17 @@ ClangASTType::GetValueAsScalar
bool
ClangASTType::SetValueFromScalar (const Scalar &value, Stream &strm)
{
- return SetValueFromScalar (m_ast, m_type, value, strm);
-}
-
-bool
-ClangASTType::SetValueFromScalar
-(
- clang::ASTContext *ast_context,
- clang_type_t clang_type,
- const Scalar &value,
- Stream &strm
-)
-{
- clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type));
-
// Aggregate types don't have scalar values
- if (!ClangASTContext::IsAggregateType (clang_type))
+ if (!IsAggregateType ())
{
strm.GetFlags().Set(Stream::eBinary);
uint64_t count = 0;
- lldb::Encoding encoding = GetEncoding (clang_type, count);
+ lldb::Encoding encoding = GetEncoding (count);
if (encoding == lldb::eEncodingInvalid || count != 1)
return false;
- const uint64_t bit_width = ast_context->getTypeSize(qual_type);
+ const uint64_t bit_width = GetBitSize();
// This function doesn't currently handle non-byte aligned assignments
if ((bit_width % 8) != 0)
return false;
@@ -1783,66 +6371,24 @@ ClangASTType::ReadFromMemory (lldb_priva
AddressType address_type,
lldb_private::DataExtractor &data)
{
- return ReadFromMemory (m_ast,
- m_type,
- exe_ctx,
- addr,
- address_type,
- data);
-}
-
-uint64_t
-ClangASTType::GetTypeByteSize() const
-{
- return GetTypeByteSize (m_ast, m_type);
-}
-
-uint64_t
-ClangASTType::GetTypeByteSize(clang::ASTContext *ast_context, lldb::clang_type_t opaque_clang_qual_type)
-{
-
- if (ClangASTContext::GetCompleteType (ast_context, opaque_clang_qual_type))
- {
- clang::QualType qual_type(clang::QualType::getFromOpaquePtr(opaque_clang_qual_type));
-
- uint64_t byte_size = (ast_context->getTypeSize (qual_type) + (uint64_t)7) / (uint64_t)8;
-
- if (ClangASTContext::IsObjCClassType(opaque_clang_qual_type))
- byte_size += ast_context->getTypeSize(ast_context->ObjCBuiltinClassTy) / 8; // isa
-
- return byte_size;
- }
- return 0;
-}
-
+ if (!IsValid())
+ return false;
-bool
-ClangASTType::ReadFromMemory (clang::ASTContext *ast_context,
- clang_type_t clang_type,
- lldb_private::ExecutionContext *exe_ctx,
- lldb::addr_t addr,
- AddressType address_type,
- lldb_private::DataExtractor &data)
-{
+ // Can't convert a file address to anything valid without more
+ // context (which Module it came from)
if (address_type == eAddressTypeFile)
- {
- // Can't convert a file address to anything valid without more
- // context (which Module it came from)
return false;
- }
- if (!ClangASTContext::GetCompleteType(ast_context, clang_type))
+ if (!GetCompleteType())
return false;
- clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type));
-
- const uint64_t byte_size = (ast_context->getTypeSize (qual_type) + 7) / 8;
+ const uint64_t byte_size = GetByteSize();
if (data.GetByteSize() < byte_size)
{
lldb::DataBufferSP data_sp(new DataBufferHeap (byte_size, '\0'));
data.SetData(data_sp);
}
-
+
uint8_t* dst = (uint8_t*)data.PeekData(0, byte_size);
if (dst != NULL)
{
@@ -1870,41 +6416,23 @@ ClangASTType::ReadFromMemory (clang::AST
}
bool
-ClangASTType::WriteToMemory
-(
- lldb_private::ExecutionContext *exe_ctx,
- lldb::addr_t addr,
- AddressType address_type,
- StreamString &new_value
-)
-{
- return WriteToMemory (m_ast,
- m_type,
- exe_ctx,
- addr,
- address_type,
- new_value);
-}
-
-bool
-ClangASTType::WriteToMemory
-(
- clang::ASTContext *ast_context,
- clang_type_t clang_type,
- lldb_private::ExecutionContext *exe_ctx,
- lldb::addr_t addr,
- AddressType address_type,
- StreamString &new_value
-)
+ClangASTType::WriteToMemory (lldb_private::ExecutionContext *exe_ctx,
+ lldb::addr_t addr,
+ AddressType address_type,
+ StreamString &new_value)
{
+ if (!IsValid())
+ return false;
+
+ // Can't convert a file address to anything valid without more
+ // context (which Module it came from)
if (address_type == eAddressTypeFile)
- {
- // Can't convert a file address to anything valid without more
- // context (which Module it came from)
return false;
- }
- clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type));
- const uint64_t byte_size = (ast_context->getTypeSize (qual_type) + 7) / 8;
+
+ if (!GetCompleteType())
+ return false;
+
+ const uint64_t byte_size = GetByteSize();
if (byte_size > 0)
{
@@ -1930,21 +6458,13 @@ ClangASTType::WriteToMemory
}
-lldb::clang_type_t
-ClangASTType::RemoveFastQualifiers (lldb::clang_type_t clang_type)
-{
- clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type));
- qual_type.getQualifiers().removeFastQualifiers();
- return qual_type.getAsOpaquePtr();
-}
-
-clang::CXXRecordDecl *
-ClangASTType::GetAsCXXRecordDecl (lldb::clang_type_t opaque_clang_qual_type)
-{
- if (opaque_clang_qual_type)
- return clang::QualType::getFromOpaquePtr(opaque_clang_qual_type)->getAsCXXRecordDecl();
- return NULL;
-}
+//CXXRecordDecl *
+//ClangASTType::GetAsCXXRecordDecl (lldb::clang_type_t opaque_clang_qual_type)
+//{
+// if (opaque_clang_qual_type)
+// return QualType::getFromOpaquePtr(opaque_clang_qual_type)->getAsCXXRecordDecl();
+// return NULL;
+//}
bool
lldb_private::operator == (const lldb_private::ClangASTType &lhs, const lldb_private::ClangASTType &rhs)
@@ -1959,190 +6479,4 @@ lldb_private::operator != (const lldb_pr
return lhs.GetASTContext() != rhs.GetASTContext() || lhs.GetOpaqueQualType() != rhs.GetOpaqueQualType();
}
-lldb::BasicType
-ClangASTType::GetBasicTypeEnumeration (const ConstString &name)
-{
- if (name)
- {
- typedef UniqueCStringMap<lldb::BasicType> TypeNameToBasicTypeMap;
- static TypeNameToBasicTypeMap g_type_map;
- static std::once_flag g_once_flag;
- std::call_once(g_once_flag, [](){
- // "void"
- g_type_map.Append(ConstString("void").GetCString(), eBasicTypeVoid);
-
- // "char"
- g_type_map.Append(ConstString("char").GetCString(), eBasicTypeChar);
- g_type_map.Append(ConstString("signed char").GetCString(), eBasicTypeSignedChar);
- g_type_map.Append(ConstString("unsigned char").GetCString(), eBasicTypeUnsignedChar);
- g_type_map.Append(ConstString("wchar_t").GetCString(), eBasicTypeWChar);
- g_type_map.Append(ConstString("signed wchar_t").GetCString(), eBasicTypeSignedWChar);
- g_type_map.Append(ConstString("unsigned wchar_t").GetCString(), eBasicTypeUnsignedWChar);
- // "short"
- g_type_map.Append(ConstString("short").GetCString(), eBasicTypeShort);
- g_type_map.Append(ConstString("short int").GetCString(), eBasicTypeShort);
- g_type_map.Append(ConstString("unsigned short").GetCString(), eBasicTypeUnsignedShort);
- g_type_map.Append(ConstString("unsigned short int").GetCString(), eBasicTypeUnsignedShort);
-
- // "int"
- g_type_map.Append(ConstString("int").GetCString(), eBasicTypeInt);
- g_type_map.Append(ConstString("signed int").GetCString(), eBasicTypeInt);
- g_type_map.Append(ConstString("unsigned int").GetCString(), eBasicTypeUnsignedInt);
- g_type_map.Append(ConstString("unsigned").GetCString(), eBasicTypeUnsignedInt);
-
- // "long"
- g_type_map.Append(ConstString("long").GetCString(), eBasicTypeLong);
- g_type_map.Append(ConstString("long int").GetCString(), eBasicTypeLong);
- g_type_map.Append(ConstString("unsigned long").GetCString(), eBasicTypeUnsignedLong);
- g_type_map.Append(ConstString("unsigned long int").GetCString(), eBasicTypeUnsignedLong);
-
- // "long long"
- g_type_map.Append(ConstString("long long").GetCString(), eBasicTypeLongLong);
- g_type_map.Append(ConstString("long long int").GetCString(), eBasicTypeLongLong);
- g_type_map.Append(ConstString("unsigned long long").GetCString(), eBasicTypeUnsignedLongLong);
- g_type_map.Append(ConstString("unsigned long long int").GetCString(), eBasicTypeUnsignedLongLong);
-
- // "int128"
- g_type_map.Append(ConstString("__int128_t").GetCString(), eBasicTypeInt128);
- g_type_map.Append(ConstString("__uint128_t").GetCString(), eBasicTypeUnsignedInt128);
-
- // Miscelaneous
- g_type_map.Append(ConstString("bool").GetCString(), eBasicTypeBool);
- g_type_map.Append(ConstString("float").GetCString(), eBasicTypeFloat);
- g_type_map.Append(ConstString("double").GetCString(), eBasicTypeDouble);
- g_type_map.Append(ConstString("long double").GetCString(), eBasicTypeLongDouble);
- g_type_map.Append(ConstString("id").GetCString(), eBasicTypeObjCID);
- g_type_map.Append(ConstString("SEL").GetCString(), eBasicTypeObjCSel);
- g_type_map.Append(ConstString("nullptr").GetCString(), eBasicTypeNullPtr);
- g_type_map.Sort();
- });
-
- return g_type_map.Find(name.GetCString(), eBasicTypeInvalid);
- }
- return eBasicTypeInvalid;
-}
-
-ClangASTType
-ClangASTType::GetBasicType (clang::ASTContext *ast, const ConstString &name)
-{
- if (ast)
- {
- lldb::BasicType basic_type = ClangASTType::GetBasicTypeEnumeration (name);
- return ClangASTType::GetBasicType (ast, basic_type);
- }
- return ClangASTType();
-}
-
-ClangASTType
-ClangASTType::GetBasicType (clang::ASTContext *ast, lldb::BasicType type)
-{
- if (ast)
- {
- clang_type_t clang_type = NULL;
-
- switch (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->ObjCBuiltinIdTy.getAsOpaquePtr();
- break;
- case eBasicTypeObjCClass:
- clang_type = ast->ObjCBuiltinClassTy.getAsOpaquePtr();
- break;
- case eBasicTypeObjCSel:
- clang_type = ast->ObjCBuiltinSelTy.getAsOpaquePtr();
- break;
- case eBasicTypeNullPtr:
- clang_type = ast->NullPtrTy.getAsOpaquePtr();
- break;
- }
-
- if (clang_type)
- return ClangASTType (ast, clang_type);
- }
- return ClangASTType();
-}
Modified: lldb/branches/lldb-platform-work/source/Symbol/Function.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Symbol/Function.cpp?rev=186540&r1=186539&r2=186540&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Symbol/Function.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Symbol/Function.cpp Wed Jul 17 17:17:41 2013
@@ -12,13 +12,10 @@
#include "lldb/Core/Section.h"
#include "lldb/Host/Host.h"
#include "lldb/Symbol/ClangASTType.h"
-#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/LineTable.h"
#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Symbol/SymbolVendor.h"
-#include "clang/AST/Type.h"
-#include "clang/AST/CanonicalType.h"
#include "llvm/Support/Casting.h"
using namespace lldb;
@@ -484,64 +481,13 @@ Function::GetType() const
return m_type;
}
-clang_type_t
-Function::GetReturnClangType ()
+ClangASTType
+Function::GetClangType()
{
- Type *type = GetType();
- if (type)
- {
- clang::QualType clang_type (clang::QualType::getFromOpaquePtr(type->GetClangFullType()));
- const clang::FunctionType *function_type = llvm::dyn_cast<clang::FunctionType> (clang_type);
- if (function_type)
- return function_type->getResultType().getAsOpaquePtr();
- }
- return NULL;
-}
-
-int
-Function::GetArgumentCount ()
-{
- clang::QualType clang_type (clang::QualType::getFromOpaquePtr(GetType()->GetClangFullType()));
- assert (clang_type->isFunctionType());
- if (!clang_type->isFunctionProtoType())
- return -1;
-
- const clang::FunctionProtoType *function_proto_type = llvm::dyn_cast<clang::FunctionProtoType>(clang_type);
- if (function_proto_type != NULL)
- return function_proto_type->getNumArgs();
-
- return 0;
-}
-
-clang_type_t
-Function::GetArgumentTypeAtIndex (size_t idx)
-{
- clang::QualType clang_type (clang::QualType::getFromOpaquePtr(GetType()->GetClangFullType()));
- const clang::FunctionProtoType *function_proto_type = llvm::dyn_cast<clang::FunctionProtoType>(clang_type);
- if (function_proto_type)
- {
- unsigned num_args = function_proto_type->getNumArgs();
- if (idx >= num_args)
- return NULL;
-
- return (function_proto_type->arg_type_begin())[idx].getAsOpaquePtr();
- }
- return NULL;
-}
-
-bool
-Function::IsVariadic ()
-{
- const clang::Type *clang_type = static_cast<clang::QualType *>(GetType()->GetClangFullType())->getTypePtr();
- assert (clang_type->isFunctionType());
- if (!clang_type->isFunctionProtoType())
- return false;
-
- const clang::FunctionProtoType *function_proto_type = llvm::dyn_cast<clang::FunctionProtoType>(clang_type);
- if (function_proto_type)
- return function_proto_type->isVariadic();
-
- return false;
+ Type *function_type = GetType();
+ if (function_type)
+ return function_type->GetClangFullType();
+ return ClangASTType();
}
uint32_t
Modified: lldb/branches/lldb-platform-work/source/Symbol/ObjectFile.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Symbol/ObjectFile.cpp?rev=186540&r1=186539&r2=186540&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Symbol/ObjectFile.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Symbol/ObjectFile.cpp Wed Jul 17 17:17:41 2013
@@ -186,16 +186,25 @@ ObjectFile::FindPlugin (const lldb::Modu
size_t
ObjectFile::GetModuleSpecifications (const FileSpec &file,
lldb::offset_t file_offset,
+ lldb::offset_t file_size,
ModuleSpecList &specs)
{
DataBufferSP data_sp (file.ReadFileContents(file_offset, 512));
if (data_sp)
- return ObjectFile::GetModuleSpecifications (file, // file spec
- data_sp, // data bytes
- 0, // data offset
- file_offset, // file offset
- data_sp->GetByteSize(), // data length
+ {
+ if (file_size == 0)
+ {
+ const lldb::offset_t actual_file_size = file.GetByteSize();
+ if (actual_file_size > file_offset)
+ file_size = actual_file_size - file_offset;
+ }
+ return ObjectFile::GetModuleSpecifications (file, // file spec
+ data_sp, // data bytes
+ 0, // data offset
+ file_offset,// file offset
+ file_size, // file length
specs);
+ }
return 0;
}
@@ -204,7 +213,7 @@ ObjectFile::GetModuleSpecifications (con
lldb::DataBufferSP& data_sp,
lldb::offset_t data_offset,
lldb::offset_t file_offset,
- lldb::offset_t length,
+ lldb::offset_t file_size,
lldb_private::ModuleSpecList &specs)
{
const size_t initial_count = specs.GetSize();
@@ -213,14 +222,14 @@ ObjectFile::GetModuleSpecifications (con
// Try the ObjectFile plug-ins
for (i = 0; (callback = PluginManager::GetObjectFileGetModuleSpecificationsCallbackAtIndex(i)) != NULL; ++i)
{
- if (callback (file, data_sp, data_offset, file_offset, length, specs) > 0)
+ if (callback (file, data_sp, data_offset, file_offset, file_size, specs) > 0)
return specs.GetSize() - initial_count;
}
// Try the ObjectContainer plug-ins
for (i = 0; (callback = PluginManager::GetObjectContainerGetModuleSpecificationsCallbackAtIndex(i)) != NULL; ++i)
{
- if (callback (file, data_sp, data_offset, file_offset, length, specs) > 0)
+ if (callback (file, data_sp, data_offset, file_offset, file_size, specs) > 0)
return specs.GetSize() - initial_count;
}
return 0;
@@ -243,10 +252,8 @@ ObjectFile::ObjectFile (const lldb::Modu
m_unwind_table (*this),
m_process_wp(),
m_memory_addr (LLDB_INVALID_ADDRESS),
- m_sections_ap (),
- m_symtab_ap (),
- m_symtab_unified_ap (),
- m_symtab_unified_revisionid (0)
+ m_sections_ap(),
+ m_symtab_ap ()
{
if (file_spec_ptr)
m_file = *file_spec_ptr;
@@ -292,10 +299,8 @@ ObjectFile::ObjectFile (const lldb::Modu
m_unwind_table (*this),
m_process_wp (process_sp),
m_memory_addr (header_addr),
- m_sections_ap (),
- m_symtab_ap (),
- m_symtab_unified_ap (),
- m_symtab_unified_revisionid (0)
+ m_sections_ap(),
+ m_symtab_ap ()
{
if (header_data_sp)
m_data.SetData (header_data_sp, 0, header_data_sp->GetByteSize());
@@ -331,7 +336,7 @@ ObjectFile::SetModulesArchitecture (cons
AddressClass
ObjectFile::GetAddressClass (addr_t file_addr)
{
- Symtab *symtab = GetSymtab(ObjectFile::eSymtabFromUnifiedSectionList);
+ Symtab *symtab = GetSymtab();
if (symtab)
{
Symbol *symbol = symtab->FindSymbolContainingFileAddress(file_addr);
@@ -586,29 +591,31 @@ ObjectFile::SplitArchivePathWithObject (
}
void
-ObjectFile::ClearSymtab (uint32_t flags)
+ObjectFile::ClearSymtab ()
{
ModuleSP module_sp(GetModule());
if (module_sp)
{
lldb_private::Mutex::Locker locker(module_sp->GetMutex());
- bool unified_section_list = !!(flags & ObjectFile::eSymtabFromUnifiedSectionList);
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
if (log)
{
- log->Printf ("%p ObjectFile::ClearSymtab (%s) symtab = %p",
+ log->Printf ("%p ObjectFile::ClearSymtab () symtab = %p",
this,
- unified_section_list ? "unified" : "",
- unified_section_list ? m_symtab_unified_ap.get() : m_symtab_ap.get());
- }
- if (unified_section_list)
- {
- m_symtab_unified_ap.reset();
- m_symtab_unified_revisionid = 0;
- }
- else
- {
- m_symtab_ap.reset();
+ m_symtab_ap.get());
}
+ m_symtab_ap.reset();
+ }
+}
+
+SectionList *
+ObjectFile::GetSectionList()
+{
+ if (m_sections_ap.get() == NULL)
+ {
+ ModuleSP module_sp(GetModule());
+ if (module_sp)
+ CreateSections(*module_sp->GetUnifiedSectionList());
}
+ return m_sections_ap.get();
}
Modified: lldb/branches/lldb-platform-work/source/Symbol/Symbol.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Symbol/Symbol.cpp?rev=186540&r1=186539&r2=186540&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Symbol/Symbol.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Symbol/Symbol.cpp Wed Jul 17 17:17:41 2013
@@ -14,6 +14,7 @@
#include "lldb/Core/Stream.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/Symtab.h"
+#include "lldb/Symbol/Function.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
#include "lldb/Symbol/SymbolVendor.h"
@@ -32,7 +33,7 @@ Symbol::Symbol() :
m_is_external (false),
m_size_is_sibling (false),
m_size_is_synthesized (false),
- m_calculated_size (false),
+ m_size_is_valid (false),
m_demangled_is_synthesized (false),
m_type (eSymbolTypeInvalid),
m_mangled (),
@@ -66,7 +67,7 @@ Symbol::Symbol
m_is_external (external),
m_size_is_sibling (false),
m_size_is_synthesized (false),
- m_calculated_size (size_is_valid || size > 0),
+ m_size_is_valid (size_is_valid || size > 0),
m_demangled_is_synthesized (false),
m_type (type),
m_mangled (ConstString(name), name_is_mangled),
@@ -98,7 +99,7 @@ Symbol::Symbol
m_is_external (external),
m_size_is_sibling (false),
m_size_is_synthesized (false),
- m_calculated_size (size_is_valid || range.GetByteSize() > 0),
+ m_size_is_valid (size_is_valid || range.GetByteSize() > 0),
m_demangled_is_synthesized (false),
m_type (type),
m_mangled (ConstString(name), name_is_mangled),
@@ -117,7 +118,7 @@ Symbol::Symbol(const Symbol& rhs):
m_is_external (rhs.m_is_external),
m_size_is_sibling (rhs.m_size_is_sibling),
m_size_is_synthesized (false),
- m_calculated_size (rhs.m_calculated_size),
+ m_size_is_valid (rhs.m_size_is_valid),
m_demangled_is_synthesized (rhs.m_demangled_is_synthesized),
m_type (rhs.m_type),
m_mangled (rhs.m_mangled),
@@ -140,7 +141,7 @@ Symbol::operator= (const Symbol& rhs)
m_is_external = rhs.m_is_external;
m_size_is_sibling = rhs.m_size_is_sibling;
m_size_is_synthesized = rhs.m_size_is_sibling;
- m_calculated_size = rhs.m_calculated_size;
+ m_size_is_valid = rhs.m_size_is_valid;
m_demangled_is_synthesized = rhs.m_demangled_is_synthesized;
m_type = rhs.m_type;
m_mangled = rhs.m_mangled;
@@ -162,7 +163,7 @@ Symbol::Clear()
m_is_external = false;
m_size_is_sibling = false;
m_size_is_synthesized = false;
- m_calculated_size = false;
+ m_size_is_valid = false;
m_demangled_is_synthesized = false;
m_type = eSymbolTypeInvalid;
m_flags = 0;
@@ -287,60 +288,72 @@ Symbol::GetPrologueByteSize ()
if (!m_type_data_resolved)
{
m_type_data_resolved = true;
- ModuleSP module_sp (m_addr_range.GetBaseAddress().GetModule());
- SymbolContext sc;
- if (module_sp)
+
+ const Address &base_address = m_addr_range.GetBaseAddress();
+ Function *function = base_address.CalculateSymbolContextFunction();
+ if (function)
+ {
+ // Functions have line entries which can also potentially have end of prologue information.
+ // So if this symbol points to a function, use the prologue information from there.
+ m_type_data = function->GetPrologueByteSize();
+ }
+ else
{
- uint32_t resolved_flags = module_sp->ResolveSymbolContextForAddress (m_addr_range.GetBaseAddress(),
- eSymbolContextLineEntry,
- sc);
- if (resolved_flags & eSymbolContextLineEntry)
+ ModuleSP module_sp (base_address.GetModule());
+ SymbolContext sc;
+ if (module_sp)
{
- // Default to the end of the first line entry.
- m_type_data = sc.line_entry.range.GetByteSize();
-
- // Set address for next line.
- Address addr (m_addr_range.GetBaseAddress());
- addr.Slide (m_type_data);
-
- // Check the first few instructions and look for one that has a line number that is
- // different than the first entry. This is also done in Function::GetPrologueByteSize().
- uint16_t total_offset = m_type_data;
- for (int idx = 0; idx < 6; ++idx)
+ uint32_t resolved_flags = module_sp->ResolveSymbolContextForAddress (base_address,
+ eSymbolContextLineEntry,
+ sc);
+ if (resolved_flags & eSymbolContextLineEntry)
{
- SymbolContext sc_temp;
- resolved_flags = module_sp->ResolveSymbolContextForAddress (addr, eSymbolContextLineEntry, sc_temp);
- // Make sure we got line number information...
- if (!(resolved_flags & eSymbolContextLineEntry))
- break;
+ // Default to the end of the first line entry.
+ m_type_data = sc.line_entry.range.GetByteSize();
- // If this line number is different than our first one, use it and we're done.
- if (sc_temp.line_entry.line != sc.line_entry.line)
+ // Set address for next line.
+ Address addr (base_address);
+ addr.Slide (m_type_data);
+
+ // Check the first few instructions and look for one that has a line number that is
+ // different than the first entry. This is also done in Function::GetPrologueByteSize().
+ uint16_t total_offset = m_type_data;
+ for (int idx = 0; idx < 6; ++idx)
{
- m_type_data = total_offset;
- break;
+ SymbolContext sc_temp;
+ resolved_flags = module_sp->ResolveSymbolContextForAddress (addr, eSymbolContextLineEntry, sc_temp);
+ // Make sure we got line number information...
+ if (!(resolved_flags & eSymbolContextLineEntry))
+ break;
+
+ // If this line number is different than our first one, use it and we're done.
+ if (sc_temp.line_entry.line != sc.line_entry.line)
+ {
+ m_type_data = total_offset;
+ break;
+ }
+
+ // Slide addr up to the next line address.
+ addr.Slide (sc_temp.line_entry.range.GetByteSize());
+ total_offset += sc_temp.line_entry.range.GetByteSize();
+ // If we've gone too far, bail out.
+ if (total_offset >= m_addr_range.GetByteSize())
+ break;
}
- // Slide addr up to the next line address.
- addr.Slide (sc_temp.line_entry.range.GetByteSize());
- total_offset += sc_temp.line_entry.range.GetByteSize();
- // If we've gone too far, bail out.
- if (total_offset >= m_addr_range.GetByteSize())
- break;
+ // Sanity check - this may be a function in the middle of code that has debug information, but
+ // not for this symbol. So the line entries surrounding us won't lie inside our function.
+ // In that case, the line entry will be bigger than we are, so we do that quick check and
+ // if that is true, we just return 0.
+ if (m_type_data >= m_addr_range.GetByteSize())
+ m_type_data = 0;
}
-
- // Sanity check - this may be a function in the middle of code that has debug information, but
- // not for this symbol. So the line entries surrounding us won't lie inside our function.
- // In that case, the line entry will be bigger than we are, so we do that quick check and
- // if that is true, we just return 0.
- if (m_type_data >= m_addr_range.GetByteSize())
+ else
+ {
+ // TODO: expose something in Process to figure out the
+ // size of a function prologue.
m_type_data = 0;
- }
- else
- {
- // TODO: expose something in Process to figure out the
- // size of a function prologue.
- m_type_data = 0;
+ }
}
}
}
@@ -397,7 +410,6 @@ Symbol::GetTypeAsString() const
return "<unknown SymbolType>";
}
-
void
Symbol::CalculateSymbolContext (SymbolContext *sc)
{
@@ -423,7 +435,6 @@ Symbol::CalculateSymbolContextSymbol ()
return this;
}
-
void
Symbol::DumpSymbolContext (Stream *s)
{
@@ -443,32 +454,9 @@ Symbol::DumpSymbolContext (Stream *s)
s->Printf("Symbol{0x%8.8x}", GetID());
}
-
lldb::addr_t
Symbol::GetByteSize () const
{
- addr_t byte_size = m_addr_range.GetByteSize();
- if (byte_size == 0 && !m_calculated_size)
- {
- const_cast<Symbol*>(this)->m_calculated_size = true;
- if (ValueIsAddress())
- {
- ModuleSP module_sp (GetAddress().GetModule());
- if (module_sp)
- {
- SymbolVendor *sym_vendor = module_sp->GetSymbolVendor();
- if (sym_vendor)
- {
- Symtab *symtab = sym_vendor->GetSymtab();
- if (symtab)
- {
- const_cast<Symbol*>(this)->SetByteSize (symtab->CalculateSymbolSize (const_cast<Symbol *>(this)));
- byte_size = m_addr_range.GetByteSize();
- }
- }
- }
- }
- }
- return byte_size;
+ return m_addr_range.GetByteSize();
}
Modified: lldb/branches/lldb-platform-work/source/Symbol/SymbolFile.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Symbol/SymbolFile.cpp?rev=186540&r1=186539&r2=186540&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Symbol/SymbolFile.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Symbol/SymbolFile.cpp Wed Jul 17 17:17:41 2013
@@ -24,6 +24,22 @@ SymbolFile::FindPlugin (ObjectFile* obj_
std::unique_ptr<SymbolFile> best_symfile_ap;
if (obj_file != NULL)
{
+
+ // We need to test the abilities of this section list. So create what it would
+ // be with this new obj_file.
+ lldb::ModuleSP module_sp(obj_file->GetModule());
+ if (module_sp)
+ {
+ // Default to the main module section list.
+ ObjectFile *module_obj_file = module_sp->GetObjectFile();
+ if (module_obj_file != obj_file)
+ {
+ // Make sure the main object file's sections are created
+ module_obj_file->GetSectionList();
+ obj_file->CreateSections (*module_sp->GetUnifiedSectionList());
+ }
+ }
+
// TODO: Load any plug-ins in the appropriate plug-in search paths and
// iterate over all of them to find the best one for the job.
Modified: lldb/branches/lldb-platform-work/source/Symbol/SymbolVendor.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Symbol/SymbolVendor.cpp?rev=186540&r1=186539&r2=186540&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Symbol/SymbolVendor.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Symbol/SymbolVendor.cpp Wed Jul 17 17:17:41 2013
@@ -447,7 +447,7 @@ SymbolVendor::GetSymtab ()
if (objfile)
{
// Get symbol table from unified section list.
- return objfile->GetSymtab (ObjectFile::eSymtabFromUnifiedSectionList);
+ return objfile->GetSymtab ();
}
}
return NULL;
@@ -463,7 +463,7 @@ SymbolVendor::ClearSymtab()
if (objfile)
{
// Clear symbol table from unified section list.
- objfile->ClearSymtab (ObjectFile::eSymtabFromUnifiedSectionList);
+ objfile->ClearSymtab ();
}
}
}
Modified: lldb/branches/lldb-platform-work/source/Symbol/Symtab.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Symbol/Symtab.cpp?rev=186540&r1=186539&r2=186540&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Symbol/Symtab.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Symbol/Symtab.cpp Wed Jul 17 17:17:41 2013
@@ -27,10 +27,10 @@ using namespace lldb_private;
Symtab::Symtab(ObjectFile *objfile) :
m_objfile (objfile),
m_symbols (),
- m_addr_indexes (),
+ m_file_addr_to_index (),
m_name_to_index (),
m_mutex (Mutex::eMutexTypeRecursive),
- m_addr_indexes_computed (false),
+ m_file_addr_to_index_computed (false),
m_name_indexes_computed (false)
{
}
@@ -63,9 +63,9 @@ Symtab::AddSymbol(const Symbol& symbol)
// when calling this function to avoid performance issues.
uint32_t symbol_idx = m_symbols.size();
m_name_to_index.Clear();
- m_addr_indexes.clear();
+ m_file_addr_to_index.Clear();
m_symbols.push_back(symbol);
- m_addr_indexes_computed = false;
+ m_file_addr_to_index_computed = false;
m_name_indexes_computed = false;
return symbol_idx;
}
@@ -144,19 +144,14 @@ Symtab::Dump (Stream *s, Target *target,
case eSortOrderByAddress:
s->PutCString (" (sorted by address):\n");
DumpSymbolHeader (s);
- if (!m_addr_indexes_computed)
+ if (!m_file_addr_to_index_computed)
InitAddressIndexes();
- const size_t num_symbols = GetNumSymbols();
- std::vector<uint32_t>::const_iterator pos;
- std::vector<uint32_t>::const_iterator end = m_addr_indexes.end();
- for (pos = m_addr_indexes.begin(); pos != end; ++pos)
+ const size_t num_entries = m_file_addr_to_index.GetSize();
+ for (size_t i=0; i<num_entries; ++i)
{
- size_t idx = *pos;
- if (idx < num_symbols)
- {
- s->Indent();
- m_symbols[idx].Dump(s, target, idx);
- }
+ s->Indent();
+ const uint32_t symbol_idx = m_file_addr_to_index.GetEntryRef(i).data;
+ m_symbols[symbol_idx].Dump(s, target, symbol_idx);
}
break;
}
@@ -943,99 +938,94 @@ void
Symtab::InitAddressIndexes()
{
// Protected function, no need to lock mutex...
- if (!m_addr_indexes_computed && !m_symbols.empty())
+ if (!m_file_addr_to_index_computed && !m_symbols.empty())
{
- m_addr_indexes_computed = true;
+ m_file_addr_to_index_computed = true;
+ FileRangeToIndexMap::Entry entry;
const_iterator begin = m_symbols.begin();
const_iterator end = m_symbols.end();
for (const_iterator pos = m_symbols.begin(); pos != end; ++pos)
{
if (pos->ValueIsAddress())
- m_addr_indexes.push_back (std::distance(begin, pos));
+ {
+ entry.SetRangeBase(pos->GetAddress().GetFileAddress());
+ entry.SetByteSize(pos->GetByteSize());
+ entry.data = std::distance(begin, pos);
+ m_file_addr_to_index.Append(entry);
+ }
}
+ const size_t num_entries = m_file_addr_to_index.GetSize();
+ 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)
+ {
+ 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)
+ {
+ 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)
+ {
+ Symbol &symbol = m_symbols[entry.data];
- SortSymbolIndexesByValue (m_addr_indexes, false);
- m_addr_indexes.push_back (UINT32_MAX); // Terminator for bsearch since we might need to look at the next symbol
+ symbol.SetByteSize(end_section_file_addr - symbol_file_addr);
+ symbol.SetSizeIsSynthesized(true);
+ }
+ }
+ }
+ // Sort again in case the range size changes the ordering
+ m_file_addr_to_index.Sort();
+ }
}
}
-size_t
-Symtab::CalculateSymbolSize (Symbol *symbol)
+void
+Symtab::CalculateSymbolSizes ()
{
Mutex::Locker locker (m_mutex);
- if (m_symbols.empty())
- return 0;
-
- // Make sure this symbol is from this symbol table...
- if (symbol < &m_symbols.front() || symbol > &m_symbols.back())
- return 0;
-
- // See if this symbol already has a byte size?
- size_t byte_size = symbol->GetByteSize();
-
- if (byte_size)
- {
- // It does, just return it
- return byte_size;
- }
-
- // Else if this is an address based symbol, figure out the delta between
- // it and the next address based symbol
- if (symbol->ValueIsAddress())
+ if (!m_symbols.empty())
{
- if (!m_addr_indexes_computed)
+ if (!m_file_addr_to_index_computed)
InitAddressIndexes();
- const size_t num_addr_indexes = m_addr_indexes.size();
- const lldb::addr_t symbol_file_addr = symbol->GetAddress().GetFileAddress();
- SymbolSearchInfo info = FindIndexPtrForSymbolContainingAddress (this,
- symbol_file_addr,
- &m_addr_indexes.front(),
- num_addr_indexes);
- if (info.match_index_ptr != NULL)
+
+ const size_t num_entries = m_file_addr_to_index.GetSize();
+
+ for (size_t i = 0; i < num_entries; ++i)
{
- // We can figure out the address range of all symbols except the
- // last one by taking the delta between the current symbol and
- // the next symbol
-
- for (uint32_t addr_index = info.match_index_ptr - &m_addr_indexes.front() + 1;
- addr_index < num_addr_indexes;
- ++addr_index)
+ // The entries in the m_file_addr_to_index have calculated the sizes already
+ // so we will use this size if we need to.
+ const FileRangeToIndexMap::Entry &entry = m_file_addr_to_index.GetEntryRef(i);
+
+ Symbol &symbol = m_symbols[entry.data];
+
+ // If the symbol size is already valid, no need to do anything
+ if (symbol.GetByteSizeIsValid())
+ continue;
+
+ const addr_t range_size = entry.GetByteSize();
+ if (range_size > 0)
{
- Symbol *next_symbol = SymbolAtIndex(m_addr_indexes[addr_index]);
- if (next_symbol == NULL)
- {
- // No next symbol take the size to be the remaining bytes in the section
- // in which the symbol resides
- SectionSP section_sp (m_objfile->GetSectionList()->FindSectionContainingFileAddress (symbol_file_addr));
- if (section_sp)
- {
- const lldb::addr_t end_section_file_addr = section_sp->GetFileAddress() + section_sp->GetByteSize();
- if (end_section_file_addr > symbol_file_addr)
- {
- byte_size = end_section_file_addr - symbol_file_addr;
- symbol->SetByteSize(byte_size);
- symbol->SetSizeIsSynthesized(true);
- break;
- }
- }
- }
- else
- {
- const lldb::addr_t next_file_addr = next_symbol->GetAddress().GetFileAddress();
- if (next_file_addr > symbol_file_addr)
- {
- byte_size = next_file_addr - symbol_file_addr;
- symbol->SetByteSize(byte_size);
- symbol->SetSizeIsSynthesized(true);
- break;
- }
- }
+ symbol.SetByteSize(range_size);
+ symbol.SetSizeIsSynthesized(true);
}
}
}
- return byte_size;
}
Symbol *
@@ -1043,6 +1033,7 @@ Symtab::FindSymbolContainingFileAddress
{
Mutex::Locker locker (m_mutex);
+
SymbolSearchInfo info = { this, file_addr, NULL, NULL, 0 };
::bsearch (&info,
@@ -1081,10 +1072,13 @@ Symtab::FindSymbolContainingFileAddress
{
Mutex::Locker locker (m_mutex);
- if (!m_addr_indexes_computed)
+ if (!m_file_addr_to_index_computed)
InitAddressIndexes();
- return FindSymbolContainingFileAddress (file_addr, &m_addr_indexes[0], m_addr_indexes.size());
+ const FileRangeToIndexMap::Entry *entry = m_file_addr_to_index.FindEntryThatContains(file_addr);
+ if (entry)
+ return SymbolAtIndex(entry->data);
+ return NULL;
}
void
More information about the llvm-branch-commits
mailing list