2010-06-08 16:52:24 +00:00
//===-- ClangExpressionDeclMap.cpp -----------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
# include "lldb/Expression/ClangExpressionDeclMap.h"
// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
2012-09-24 22:25:51 +00:00
# include "clang/AST/ASTContext.h"
2010-09-23 03:01:22 +00:00
# include "clang/AST/DeclarationName.h"
2010-11-01 23:22:47 +00:00
# include "clang/AST/Decl.h"
2010-06-08 16:52:24 +00:00
# include "lldb/lldb-private.h"
# include "lldb/Core/Address.h"
2010-07-16 00:09:46 +00:00
# include "lldb/Core/Error.h"
2010-06-23 00:47:48 +00:00
# include "lldb/Core/Log.h"
2010-06-08 16:52:24 +00:00
# include "lldb/Core/Module.h"
2011-05-09 20:18:18 +00:00
# include "lldb/Core/RegisterValue.h"
2010-12-16 03:17:46 +00:00
# include "lldb/Core/ValueObjectConstResult.h"
2011-12-10 03:12:34 +00:00
# include "lldb/Core/ValueObjectVariable.h"
2011-02-01 23:43:26 +00:00
# include "lldb/Expression/ASTDumper.h"
2010-06-08 16:52:24 +00:00
# include "lldb/Expression/ClangASTSource.h"
2010-08-11 03:57:18 +00:00
# include "lldb/Expression/ClangPersistentVariables.h"
2011-02-01 01:31:41 +00:00
# include "lldb/Host/Endian.h"
2010-06-08 16:52:24 +00:00
# include "lldb/Symbol/ClangASTContext.h"
2010-11-13 03:52:47 +00:00
# include "lldb/Symbol/ClangNamespaceDecl.h"
2010-06-08 16:52:24 +00:00
# include "lldb/Symbol/CompileUnit.h"
# include "lldb/Symbol/Function.h"
# include "lldb/Symbol/ObjectFile.h"
# include "lldb/Symbol/SymbolContext.h"
2011-10-12 00:12:34 +00:00
# include "lldb/Symbol/SymbolVendor.h"
2010-06-08 16:52:24 +00:00
# include "lldb/Symbol/Type.h"
# include "lldb/Symbol/TypeList.h"
# include "lldb/Symbol/Variable.h"
# include "lldb/Symbol/VariableList.h"
2010-07-20 23:31:16 +00:00
# include "lldb/Target/ExecutionContext.h"
2012-11-15 02:02:04 +00:00
# include "lldb/Target/ObjCLanguageRuntime.h"
2010-07-16 00:09:46 +00:00
# include "lldb/Target/Process.h"
2010-10-05 20:18:48 +00:00
# include "lldb/Target/RegisterContext.h"
2010-06-08 16:52:24 +00:00
# include "lldb/Target/StackFrame.h"
2010-07-20 23:31:16 +00:00
# include "lldb/Target/Target.h"
2010-12-07 01:56:02 +00:00
# include "lldb/Target/Thread.h"
2010-06-08 16:52:24 +00:00
2010-11-14 22:13:40 +00:00
using namespace lldb ;
2010-06-08 16:52:24 +00:00
using namespace lldb_private ;
using namespace clang ;
2011-10-29 01:58:46 +00:00
ClangExpressionDeclMap : : ClangExpressionDeclMap ( bool keep_result_in_memory , ExecutionContext & exe_ctx ) :
ClangASTSource ( exe_ctx . GetTargetSP ( ) ) ,
2010-10-15 22:48:33 +00:00
m_found_entities ( ) ,
m_struct_members ( ) ,
2011-04-11 19:41:40 +00:00
m_keep_result_in_memory ( keep_result_in_memory ) ,
2010-12-03 01:38:59 +00:00
m_parser_vars ( ) ,
2011-04-11 19:41:40 +00:00
m_struct_vars ( )
2010-06-08 16:52:24 +00:00
{
2010-12-03 01:38:59 +00:00
EnableStructVars ( ) ;
2010-06-08 16:52:24 +00:00
}
ClangExpressionDeclMap : : ~ ClangExpressionDeclMap ( )
2010-12-03 01:38:59 +00:00
{
2011-10-12 22:20:02 +00:00
// Note: The model is now that the parser's AST context and all associated
// data does not vanish until the expression has been executed. This means
// that valuable lookup data (like namespaces) doesn't vanish, but
DidParse ( ) ;
2010-12-03 01:38:59 +00:00
DidDematerialize ( ) ;
DisableStructVars ( ) ;
}
2010-10-26 00:31:56 +00:00
2011-08-01 18:18:33 +00:00
bool
2010-12-14 02:59:59 +00:00
ClangExpressionDeclMap : : WillParse ( ExecutionContext & exe_ctx )
2010-12-03 01:38:59 +00:00
{
EnableParserVars ( ) ;
2012-02-10 01:22:05 +00:00
m_parser_vars - > m_exe_ctx = exe_ctx ;
2011-09-22 04:58:26 +00:00
Target * target = exe_ctx . GetTargetPtr ( ) ;
if ( exe_ctx . GetFramePtr ( ) )
m_parser_vars - > m_sym_ctx = exe_ctx . GetFramePtr ( ) - > GetSymbolContext ( lldb : : eSymbolContextEverything ) ;
else if ( exe_ctx . GetThreadPtr ( ) )
m_parser_vars - > m_sym_ctx = exe_ctx . GetThreadPtr ( ) - > GetStackFrameAtIndex ( 0 ) - > GetSymbolContext ( lldb : : eSymbolContextEverything ) ;
else if ( exe_ctx . GetProcessPtr ( ) )
2011-09-17 08:33:22 +00:00
{
m_parser_vars - > m_sym_ctx . Clear ( ) ;
2011-09-22 04:58:26 +00:00
m_parser_vars - > m_sym_ctx . target_sp = exe_ctx . GetTargetSP ( ) ;
2011-09-17 08:33:22 +00:00
}
2011-09-22 04:58:26 +00:00
else if ( target )
2011-09-17 08:33:22 +00:00
{
m_parser_vars - > m_sym_ctx . Clear ( ) ;
2011-09-22 04:58:26 +00:00
m_parser_vars - > m_sym_ctx . target_sp = exe_ctx . GetTargetSP ( ) ;
2011-09-17 08:33:22 +00:00
}
2011-09-15 18:41:04 +00:00
2011-09-22 04:58:26 +00:00
if ( target )
{
m_parser_vars - > m_persistent_vars = & target - > GetPersistentVariables ( ) ;
2011-08-01 18:18:33 +00:00
2011-09-22 04:58:26 +00:00
if ( ! target - > GetScratchClangASTContext ( ) )
return false ;
}
2011-08-01 18:18:33 +00:00
2011-09-15 02:13:07 +00:00
m_parser_vars - > m_target_info = GetTargetInfo ( ) ;
2011-08-01 18:18:33 +00:00
return true ;
2010-12-03 01:38:59 +00:00
}
2010-12-14 02:59:59 +00:00
void
ClangExpressionDeclMap : : DidParse ( )
2010-12-03 01:38:59 +00:00
{
if ( m_parser_vars . get ( ) )
{
2010-12-14 02:59:59 +00:00
for ( size_t entity_index = 0 , num_entities = m_found_entities . GetSize ( ) ;
2010-12-03 01:38:59 +00:00
entity_index < num_entities ;
+ + entity_index )
{
2010-12-14 02:59:59 +00:00
ClangExpressionVariableSP var_sp ( m_found_entities . GetVariableAtIndex ( entity_index ) ) ;
2012-10-12 17:34:26 +00:00
if ( var_sp )
{
if ( var_sp - > m_parser_vars . get ( ) & &
var_sp - > m_parser_vars - > m_lldb_value )
2010-12-14 02:59:59 +00:00
delete var_sp - > m_parser_vars - > m_lldb_value ;
2010-12-03 01:38:59 +00:00
2012-10-12 17:34:26 +00:00
var_sp - > DisableParserVars ( ) ;
}
2010-12-03 01:38:59 +00:00
}
2010-12-14 02:59:59 +00:00
for ( size_t pvar_index = 0 , num_pvars = m_parser_vars - > m_persistent_vars - > GetSize ( ) ;
2010-12-03 01:38:59 +00:00
pvar_index < num_pvars ;
+ + pvar_index )
{
2010-12-14 02:59:59 +00:00
ClangExpressionVariableSP pvar_sp ( m_parser_vars - > m_persistent_vars - > GetVariableAtIndex ( pvar_index ) ) ;
if ( pvar_sp )
pvar_sp - > DisableParserVars ( ) ;
2010-12-03 01:38:59 +00:00
}
DisableParserVars ( ) ;
2010-10-08 01:58:41 +00:00
}
2010-06-08 16:52:24 +00:00
}
2010-07-13 21:41:46 +00:00
// Interface for IRForTarget
2011-09-15 02:13:07 +00:00
ClangExpressionDeclMap : : TargetInfo
ClangExpressionDeclMap : : GetTargetInfo ( )
{
assert ( m_parser_vars . get ( ) ) ;
TargetInfo ret ;
2012-02-10 01:22:05 +00:00
ExecutionContext & exe_ctx = m_parser_vars - > m_exe_ctx ;
Process * process = exe_ctx . GetProcessPtr ( ) ;
if ( process )
2011-09-15 02:13:07 +00:00
{
2012-02-10 01:22:05 +00:00
ret . byte_order = process - > GetByteOrder ( ) ;
ret . address_byte_size = process - > GetAddressByteSize ( ) ;
}
else
{
Target * target = exe_ctx . GetTargetPtr ( ) ;
if ( target )
2011-09-22 04:58:26 +00:00
{
2012-02-10 01:22:05 +00:00
ret . byte_order = target - > GetArchitecture ( ) . GetByteOrder ( ) ;
ret . address_byte_size = target - > GetArchitecture ( ) . GetAddressByteSize ( ) ;
2011-09-22 04:58:26 +00:00
}
2011-09-15 02:13:07 +00:00
}
2012-02-10 01:22:05 +00:00
2011-09-15 02:13:07 +00:00
return ret ;
}
2010-10-15 22:48:33 +00:00
const ConstString &
ClangExpressionDeclMap : : GetPersistentResultName ( )
2010-08-12 01:56:52 +00:00
{
2010-12-03 01:38:59 +00:00
assert ( m_struct_vars . get ( ) ) ;
assert ( m_parser_vars . get ( ) ) ;
if ( ! m_struct_vars - > m_result_name )
2010-12-14 02:59:59 +00:00
{
Target * target = m_parser_vars - > GetTarget ( ) ;
assert ( target ) ;
m_struct_vars - > m_result_name = target - > GetPersistentVariables ( ) . GetNextPersistentVariableName ( ) ;
}
2010-12-03 01:38:59 +00:00
return m_struct_vars - > m_result_name ;
2010-08-12 01:56:52 +00:00
}
2010-12-16 03:17:46 +00:00
lldb : : ClangExpressionVariableSP
ClangExpressionDeclMap : : BuildIntegerVariable ( const ConstString & name ,
lldb_private : : TypeFromParser type ,
const llvm : : APInt & value )
{
assert ( m_parser_vars . get ( ) ) ;
2011-08-01 18:18:33 +00:00
2012-02-10 01:22:05 +00:00
ExecutionContext & exe_ctx = m_parser_vars - > m_exe_ctx ;
Target * target = exe_ctx . GetTargetPtr ( ) ;
if ( ! target )
return ClangExpressionVariableSP ( ) ;
2011-09-22 04:58:26 +00:00
ASTContext * context ( target - > GetScratchClangASTContext ( ) - > getASTContext ( ) ) ;
2010-12-16 03:17:46 +00:00
2011-11-18 03:28:09 +00:00
TypeFromUser user_type ( m_ast_importer - > CopyType ( context ,
type . GetASTContext ( ) ,
type . GetOpaqueQualType ( ) ) ,
2010-12-16 03:17:46 +00:00
context ) ;
2011-09-15 02:13:07 +00:00
2011-12-01 21:04:37 +00:00
if ( ! user_type . GetOpaqueQualType ( ) )
{
lldb : : LogSP log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_EXPRESSIONS ) ) ;
if ( log )
log - > Printf ( " ClangExpressionDeclMap::BuildIntegerVariable - Couldn't export the type for a constant integer result " ) ;
return lldb : : ClangExpressionVariableSP ( ) ;
}
2012-02-10 01:22:05 +00:00
if ( ! m_parser_vars - > m_persistent_vars - > CreatePersistentVariable ( exe_ctx . GetBestExecutionContextScope ( ) ,
2011-03-31 00:19:25 +00:00
name ,
2011-01-04 02:41:41 +00:00
user_type ,
2011-09-15 02:13:07 +00:00
m_parser_vars - > m_target_info . byte_order ,
m_parser_vars - > m_target_info . address_byte_size ) )
2011-01-04 02:41:41 +00:00
return lldb : : ClangExpressionVariableSP ( ) ;
2010-12-16 03:17:46 +00:00
2011-01-04 02:41:41 +00:00
ClangExpressionVariableSP pvar_sp ( m_parser_vars - > m_persistent_vars - > GetVariable ( name ) ) ;
if ( ! pvar_sp )
return lldb : : ClangExpressionVariableSP ( ) ;
uint8_t * pvar_data = pvar_sp - > GetValueBytes ( ) ;
if ( pvar_data = = NULL )
return lldb : : ClangExpressionVariableSP ( ) ;
2010-12-16 03:17:46 +00:00
uint64_t value64 = value . getLimitedValue ( ) ;
2011-09-15 02:13:07 +00:00
2010-12-16 03:17:46 +00:00
size_t num_val_bytes = sizeof ( value64 ) ;
2011-01-04 02:41:41 +00:00
size_t num_data_bytes = pvar_sp - > GetByteSize ( ) ;
2010-12-16 03:17:46 +00:00
size_t num_bytes = num_val_bytes ;
if ( num_bytes > num_data_bytes )
num_bytes = num_data_bytes ;
2011-07-19 19:48:13 +00:00
for ( size_t byte_idx = 0 ;
2010-12-16 03:17:46 +00:00
byte_idx < num_bytes ;
+ + byte_idx )
{
uint64_t shift = byte_idx * 8 ;
uint64_t mask = 0xffll < < shift ;
uint8_t cur_byte = ( uint8_t ) ( ( value64 & mask ) > > shift ) ;
2011-09-15 02:13:07 +00:00
switch ( m_parser_vars - > m_target_info . byte_order )
2010-12-16 03:17:46 +00:00
{
2011-01-04 02:41:41 +00:00
case eByteOrderBig :
// High Low
// Original: |AABBCCDDEEFFGGHH|
// Target: |EEFFGGHH|
pvar_data [ num_data_bytes - ( 1 + byte_idx ) ] = cur_byte ;
break ;
case eByteOrderLittle :
// Target: |HHGGFFEE|
pvar_data [ byte_idx ] = cur_byte ;
break ;
default :
return lldb : : ClangExpressionVariableSP ( ) ;
2010-12-16 03:17:46 +00:00
}
}
2011-01-13 08:53:35 +00:00
pvar_sp - > m_flags | = ClangExpressionVariable : : EVIsFreezeDried ;
2011-05-07 01:06:41 +00:00
pvar_sp - > m_flags | = ClangExpressionVariable : : EVIsLLDBAllocated ;
pvar_sp - > m_flags | = ClangExpressionVariable : : EVNeedsAllocation ;
2011-01-04 02:41:41 +00:00
return pvar_sp ;
2010-12-16 03:17:46 +00:00
}
2011-05-07 01:06:41 +00:00
lldb : : ClangExpressionVariableSP
ClangExpressionDeclMap : : BuildCastVariable ( const ConstString & name ,
2011-07-30 02:42:06 +00:00
VarDecl * decl ,
2011-05-07 01:06:41 +00:00
lldb_private : : TypeFromParser type )
{
assert ( m_parser_vars . get ( ) ) ;
lldb : : LogSP log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_EXPRESSIONS ) ) ;
2012-02-10 01:22:05 +00:00
ExecutionContext & exe_ctx = m_parser_vars - > m_exe_ctx ;
Target * target = exe_ctx . GetTargetPtr ( ) ;
2011-09-22 04:58:26 +00:00
if ( target = = NULL )
return lldb : : ClangExpressionVariableSP ( ) ;
ASTContext * context ( target - > GetScratchClangASTContext ( ) - > getASTContext ( ) ) ;
2011-05-07 01:06:41 +00:00
ClangExpressionVariableSP var_sp ( m_found_entities . GetVariable ( decl ) ) ;
if ( ! var_sp )
var_sp = m_parser_vars - > m_persistent_vars - > GetVariable ( decl ) ;
if ( ! var_sp )
return ClangExpressionVariableSP ( ) ;
2011-11-18 03:28:09 +00:00
TypeFromUser user_type ( m_ast_importer - > CopyType ( context ,
type . GetASTContext ( ) ,
type . GetOpaqueQualType ( ) ) ,
2011-05-07 01:06:41 +00:00
context ) ;
2011-12-01 21:04:37 +00:00
if ( ! user_type . GetOpaqueQualType ( ) )
2012-10-04 22:47:07 +00:00
{
2011-12-01 21:04:37 +00:00
if ( log )
log - > Printf ( " ClangExpressionDeclMap::BuildCastVariable - Couldn't export the type for a constant cast result " ) ;
return lldb : : ClangExpressionVariableSP ( ) ;
}
2011-05-07 01:06:41 +00:00
TypeFromUser var_type = var_sp - > GetTypeFromUser ( ) ;
2012-02-10 01:22:05 +00:00
StackFrame * frame = exe_ctx . GetFramePtr ( ) ;
2011-09-22 04:58:26 +00:00
if ( frame = = NULL )
return lldb : : ClangExpressionVariableSP ( ) ;
VariableSP var = FindVariableInScope ( * frame , var_sp - > GetName ( ) , & var_type ) ;
2011-05-07 01:06:41 +00:00
if ( ! var )
return lldb : : ClangExpressionVariableSP ( ) ; // but we should handle this; it may be a persistent variable
2011-09-22 04:58:26 +00:00
ValueObjectSP var_valobj = frame - > GetValueObjectForFrameVariable ( var , lldb : : eNoDynamicValues ) ;
2011-05-07 01:06:41 +00:00
if ( ! var_valobj )
return lldb : : ClangExpressionVariableSP ( ) ;
ValueObjectSP var_casted_valobj = var_valobj - > CastPointerType ( name . GetCString ( ) , user_type ) ;
if ( ! var_casted_valobj )
return lldb : : ClangExpressionVariableSP ( ) ;
if ( log )
{
StreamString my_stream_string ;
ClangASTType : : DumpTypeDescription ( var_type . GetASTContext ( ) ,
var_type . GetOpaqueQualType ( ) ,
& my_stream_string ) ;
log - > Printf ( " Building cast variable to type: %s " , my_stream_string . GetString ( ) . c_str ( ) ) ;
}
ClangExpressionVariableSP pvar_sp = m_parser_vars - > m_persistent_vars - > CreatePersistentVariable ( var_casted_valobj ) ;
if ( ! pvar_sp )
return lldb : : ClangExpressionVariableSP ( ) ;
if ( pvar_sp ! = m_parser_vars - > m_persistent_vars - > GetVariable ( name ) )
return lldb : : ClangExpressionVariableSP ( ) ;
pvar_sp - > m_flags | = ClangExpressionVariable : : EVIsFreezeDried ;
pvar_sp - > m_flags | = ClangExpressionVariable : : EVIsLLDBAllocated ;
pvar_sp - > m_flags | = ClangExpressionVariable : : EVNeedsAllocation ;
return pvar_sp ;
}
2011-09-15 02:13:07 +00:00
bool
ClangExpressionDeclMap : : ResultIsReference ( const ConstString & name )
{
ClangExpressionVariableSP pvar_sp = m_parser_vars - > m_persistent_vars - > GetVariable ( name ) ;
return ( pvar_sp - > m_flags & ClangExpressionVariable : : EVIsProgramReference ) ;
}
bool
ClangExpressionDeclMap : : CompleteResultVariable ( lldb : : ClangExpressionVariableSP & valobj ,
lldb_private : : Value & value ,
const ConstString & name ,
2011-09-22 00:41:11 +00:00
lldb_private : : TypeFromParser type ,
2011-10-21 05:18:02 +00:00
bool transient ,
bool maybe_make_load )
2011-09-15 02:13:07 +00:00
{
assert ( m_parser_vars . get ( ) ) ;
ClangExpressionVariableSP pvar_sp = m_parser_vars - > m_persistent_vars - > GetVariable ( name ) ;
if ( ! pvar_sp )
return false ;
2011-10-21 05:18:02 +00:00
if ( maybe_make_load & &
value . GetValueType ( ) = = Value : : eValueTypeFileAddress & &
2012-02-10 01:22:05 +00:00
m_parser_vars - > m_exe_ctx . GetProcessPtr ( ) )
2011-10-21 05:18:02 +00:00
{
value . SetValueType ( Value : : eValueTypeLoadAddress ) ;
}
2011-09-15 02:13:07 +00:00
if ( pvar_sp - > m_flags & ClangExpressionVariable : : EVIsProgramReference & &
2011-09-22 00:41:11 +00:00
! pvar_sp - > m_live_sp & &
! transient )
2011-09-15 02:13:07 +00:00
{
// The reference comes from the program. We need to set up a live SP for it.
2011-12-16 23:04:52 +00:00
unsigned long long address = value . GetScalar ( ) . ULongLong ( ) ;
AddressType address_type = value . GetValueAddressType ( ) ;
2012-02-10 01:22:05 +00:00
pvar_sp - > m_live_sp = ValueObjectConstResult : : Create ( m_parser_vars - > m_exe_ctx . GetBestExecutionContextScope ( ) ,
2011-09-15 02:13:07 +00:00
pvar_sp - > GetTypeFromUser ( ) . GetASTContext ( ) ,
pvar_sp - > GetTypeFromUser ( ) . GetOpaqueQualType ( ) ,
pvar_sp - > GetName ( ) ,
2011-12-16 23:04:52 +00:00
address ,
address_type ,
2011-09-15 02:13:07 +00:00
pvar_sp - > GetByteSize ( ) ) ;
}
if ( pvar_sp - > m_flags & ClangExpressionVariable : : EVNeedsFreezeDry )
{
pvar_sp - > ValueUpdated ( ) ;
const size_t pvar_byte_size = pvar_sp - > GetByteSize ( ) ;
uint8_t * pvar_data = pvar_sp - > GetValueBytes ( ) ;
2012-02-04 08:49:35 +00:00
if ( ! ReadTarget ( pvar_data , value , pvar_byte_size ) )
return false ;
2011-09-15 02:13:07 +00:00
pvar_sp - > m_flags & = ~ ( ClangExpressionVariable : : EVNeedsFreezeDry ) ;
}
valobj = pvar_sp ;
return true ;
}
2012-02-04 08:49:35 +00:00
void
ClangExpressionDeclMap : : RemoveResultVariable
(
const ConstString & name
)
{
ClangExpressionVariableSP pvar_sp = m_parser_vars - > m_persistent_vars - > GetVariable ( name ) ;
m_parser_vars - > m_persistent_vars - > RemovePersistentVariable ( pvar_sp ) ;
}
2010-08-11 03:57:18 +00:00
bool
2010-10-15 22:48:33 +00:00
ClangExpressionDeclMap : : AddPersistentVariable
(
2011-07-30 02:42:06 +00:00
const NamedDecl * decl ,
2010-10-15 22:48:33 +00:00
const ConstString & name ,
2011-01-13 08:53:35 +00:00
TypeFromParser parser_type ,
bool is_result ,
bool is_lvalue
2010-10-15 22:48:33 +00:00
)
2010-08-11 03:57:18 +00:00
{
2010-12-03 01:38:59 +00:00
assert ( m_parser_vars . get ( ) ) ;
2011-01-13 08:53:35 +00:00
lldb : : LogSP log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_EXPRESSIONS ) ) ;
2012-02-10 01:22:05 +00:00
ExecutionContext & exe_ctx = m_parser_vars - > m_exe_ctx ;
Target * target = exe_ctx . GetTargetPtr ( ) ;
2011-09-22 04:58:26 +00:00
if ( target = = NULL )
return false ;
ASTContext * context ( target - > GetScratchClangASTContext ( ) - > getASTContext ( ) ) ;
2010-08-11 03:57:18 +00:00
2011-12-16 21:06:35 +00:00
TypeFromUser user_type ( m_ast_importer - > DeportType ( context ,
parser_type . GetASTContext ( ) ,
parser_type . GetOpaqueQualType ( ) ) ,
2011-01-13 21:23:32 +00:00
context ) ;
2011-11-18 03:28:09 +00:00
if ( ! user_type . GetOpaqueQualType ( ) )
{
if ( log )
log - > Printf ( " Persistent variable's type wasn't copied successfully " ) ;
return false ;
}
2011-09-15 02:13:07 +00:00
if ( ! m_parser_vars - > m_target_info . IsValid ( ) )
return false ;
2010-08-11 03:57:18 +00:00
2012-02-10 01:22:05 +00:00
if ( ! m_parser_vars - > m_persistent_vars - > CreatePersistentVariable ( exe_ctx . GetBestExecutionContextScope ( ) ,
2011-03-31 00:19:25 +00:00
name ,
2010-12-14 02:59:59 +00:00
user_type ,
2011-09-15 02:13:07 +00:00
m_parser_vars - > m_target_info . byte_order ,
m_parser_vars - > m_target_info . address_byte_size ) )
2010-08-23 23:09:38 +00:00
return false ;
2010-12-14 02:59:59 +00:00
ClangExpressionVariableSP var_sp ( m_parser_vars - > m_persistent_vars - > GetVariable ( name ) ) ;
2010-08-23 23:09:38 +00:00
2010-12-14 02:59:59 +00:00
if ( ! var_sp )
2010-08-23 23:09:38 +00:00
return false ;
2012-09-20 23:21:16 +00:00
var_sp - > m_frozen_sp - > SetHasCompleteType ( ) ;
2011-01-13 08:53:35 +00:00
if ( is_result )
var_sp - > m_flags | = ClangExpressionVariable : : EVNeedsFreezeDry ;
else
var_sp - > m_flags | = ClangExpressionVariable : : EVKeepInTarget ; // explicitly-declared persistent variables should persist
if ( is_lvalue )
{
var_sp - > m_flags | = ClangExpressionVariable : : EVIsProgramReference ;
}
else
{
var_sp - > m_flags | = ClangExpressionVariable : : EVIsLLDBAllocated ;
var_sp - > m_flags | = ClangExpressionVariable : : EVNeedsAllocation ;
}
if ( log )
log - > Printf ( " Created persistent variable with flags 0x%hx " , var_sp - > m_flags ) ;
2010-12-14 02:59:59 +00:00
var_sp - > EnableParserVars ( ) ;
2010-08-23 23:09:38 +00:00
2010-12-14 02:59:59 +00:00
var_sp - > m_parser_vars - > m_named_decl = decl ;
var_sp - > m_parser_vars - > m_parser_type = parser_type ;
2010-08-23 23:09:38 +00:00
return true ;
2010-08-11 03:57:18 +00:00
}
2010-07-13 21:41:46 +00:00
bool
2010-10-15 22:48:33 +00:00
ClangExpressionDeclMap : : AddValueToStruct
(
2011-07-30 02:42:06 +00:00
const NamedDecl * decl ,
2010-10-15 22:48:33 +00:00
const ConstString & name ,
llvm : : Value * value ,
size_t size ,
off_t alignment
)
2010-07-13 21:41:46 +00:00
{
2010-12-03 01:38:59 +00:00
assert ( m_struct_vars . get ( ) ) ;
assert ( m_parser_vars . get ( ) ) ;
2010-11-06 01:53:30 +00:00
lldb : : LogSP log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_EXPRESSIONS ) ) ;
2010-08-30 22:17:16 +00:00
2010-12-03 01:38:59 +00:00
m_struct_vars - > m_struct_laid_out = false ;
2010-07-13 21:41:46 +00:00
2010-08-23 23:09:38 +00:00
if ( m_struct_members . GetVariable ( decl ) )
return true ;
2010-07-13 21:41:46 +00:00
2010-12-14 02:59:59 +00:00
ClangExpressionVariableSP var_sp ( m_found_entities . GetVariable ( decl ) ) ;
2010-07-13 21:41:46 +00:00
2010-12-14 02:59:59 +00:00
if ( ! var_sp )
var_sp = m_parser_vars - > m_persistent_vars - > GetVariable ( decl ) ;
2010-07-13 21:41:46 +00:00
2010-12-14 02:59:59 +00:00
if ( ! var_sp )
2010-08-23 23:09:38 +00:00
return false ;
2010-08-30 22:17:16 +00:00
if ( log )
2011-11-18 03:28:09 +00:00
log - > Printf ( " Adding value for (NamedDecl*)%p [%s - %s] to the structure " ,
2010-08-30 22:17:16 +00:00
decl ,
2010-10-15 22:48:33 +00:00
name . GetCString ( ) ,
2010-12-14 02:59:59 +00:00
var_sp - > GetName ( ) . GetCString ( ) ) ;
2010-08-30 22:17:16 +00:00
2010-08-23 23:09:38 +00:00
// We know entity->m_parser_vars is valid because we used a parser variable
// to find it
2010-12-14 02:59:59 +00:00
var_sp - > m_parser_vars - > m_llvm_value = value ;
2010-08-23 23:09:38 +00:00
2010-12-14 02:59:59 +00:00
var_sp - > EnableJITVars ( ) ;
var_sp - > m_jit_vars - > m_alignment = alignment ;
var_sp - > m_jit_vars - > m_size = size ;
2010-08-23 23:09:38 +00:00
2010-12-14 02:59:59 +00:00
m_struct_members . AddVariable ( var_sp ) ;
2010-07-13 21:41:46 +00:00
return true ;
}
bool
ClangExpressionDeclMap : : DoStructLayout ( )
{
2010-12-03 01:38:59 +00:00
assert ( m_struct_vars . get ( ) ) ;
if ( m_struct_vars - > m_struct_laid_out )
2010-07-13 21:41:46 +00:00
return true ;
off_t cursor = 0 ;
2010-12-03 01:38:59 +00:00
m_struct_vars - > m_struct_alignment = 0 ;
m_struct_vars - > m_struct_size = 0 ;
2010-07-13 21:41:46 +00:00
2010-12-14 02:59:59 +00:00
for ( size_t member_index = 0 , num_members = m_struct_members . GetSize ( ) ;
2010-08-23 23:09:38 +00:00
member_index < num_members ;
+ + member_index )
2010-07-13 21:41:46 +00:00
{
2010-12-14 02:59:59 +00:00
ClangExpressionVariableSP member_sp ( m_struct_members . GetVariableAtIndex ( member_index ) ) ;
if ( ! member_sp )
return false ;
if ( ! member_sp - > m_jit_vars . get ( ) )
2010-08-23 23:09:38 +00:00
return false ;
2010-07-13 21:41:46 +00:00
2010-08-23 23:09:38 +00:00
if ( member_index = = 0 )
2010-12-14 02:59:59 +00:00
m_struct_vars - > m_struct_alignment = member_sp - > m_jit_vars - > m_alignment ;
2010-08-23 23:09:38 +00:00
2010-12-14 02:59:59 +00:00
if ( cursor % member_sp - > m_jit_vars - > m_alignment )
cursor + = ( member_sp - > m_jit_vars - > m_alignment - ( cursor % member_sp - > m_jit_vars - > m_alignment ) ) ;
2010-08-23 23:09:38 +00:00
2010-12-14 02:59:59 +00:00
member_sp - > m_jit_vars - > m_offset = cursor ;
cursor + = member_sp - > m_jit_vars - > m_size ;
2010-07-13 21:41:46 +00:00
}
2010-12-03 01:38:59 +00:00
m_struct_vars - > m_struct_size = cursor ;
2010-07-13 21:41:46 +00:00
2010-12-03 01:38:59 +00:00
m_struct_vars - > m_struct_laid_out = true ;
2010-07-13 21:41:46 +00:00
return true ;
}
2010-10-15 22:48:33 +00:00
bool ClangExpressionDeclMap : : GetStructInfo
(
uint32_t & num_elements ,
size_t & size ,
off_t & alignment
)
2010-07-13 21:41:46 +00:00
{
2010-12-03 01:38:59 +00:00
assert ( m_struct_vars . get ( ) ) ;
if ( ! m_struct_vars - > m_struct_laid_out )
2010-07-13 21:41:46 +00:00
return false ;
2010-12-14 02:59:59 +00:00
num_elements = m_struct_members . GetSize ( ) ;
2010-12-03 01:38:59 +00:00
size = m_struct_vars - > m_struct_size ;
alignment = m_struct_vars - > m_struct_alignment ;
2010-07-13 21:41:46 +00:00
return true ;
}
bool
2010-10-15 22:48:33 +00:00
ClangExpressionDeclMap : : GetStructElement
(
2011-07-30 02:42:06 +00:00
const NamedDecl * & decl ,
2010-10-15 22:48:33 +00:00
llvm : : Value * & value ,
off_t & offset ,
ConstString & name ,
uint32_t index
)
2010-07-13 21:41:46 +00:00
{
2010-12-03 01:38:59 +00:00
assert ( m_struct_vars . get ( ) ) ;
if ( ! m_struct_vars - > m_struct_laid_out )
2010-07-13 21:41:46 +00:00
return false ;
2010-12-14 02:59:59 +00:00
if ( index > = m_struct_members . GetSize ( ) )
2010-07-13 21:41:46 +00:00
return false ;
2010-12-14 02:59:59 +00:00
ClangExpressionVariableSP member_sp ( m_struct_members . GetVariableAtIndex ( index ) ) ;
2010-07-13 21:41:46 +00:00
2010-12-14 02:59:59 +00:00
if ( ! member_sp | |
! member_sp - > m_parser_vars . get ( ) | |
2012-04-12 16:58:26 +00:00
! member_sp - > m_jit_vars . get ( ) | |
! member_sp - > GetValueObject ( ) )
2010-08-23 23:09:38 +00:00
return false ;
2010-12-14 02:59:59 +00:00
decl = member_sp - > m_parser_vars - > m_named_decl ;
value = member_sp - > m_parser_vars - > m_llvm_value ;
offset = member_sp - > m_jit_vars - > m_offset ;
name = member_sp - > GetName ( ) ;
2010-08-23 23:09:38 +00:00
2010-07-13 21:41:46 +00:00
return true ;
}
2010-07-27 21:39:39 +00:00
bool
2010-10-15 22:48:33 +00:00
ClangExpressionDeclMap : : GetFunctionInfo
(
2011-07-30 02:42:06 +00:00
const NamedDecl * decl ,
2010-10-15 22:48:33 +00:00
uint64_t & ptr
)
2010-07-27 02:07:53 +00:00
{
2010-12-14 02:59:59 +00:00
ClangExpressionVariableSP entity_sp ( m_found_entities . GetVariable ( decl ) ) ;
2010-08-23 23:09:38 +00:00
2010-12-14 02:59:59 +00:00
if ( ! entity_sp )
2010-08-23 23:09:38 +00:00
return false ;
2010-07-27 02:07:53 +00:00
2010-08-23 23:09:38 +00:00
// We know m_parser_vars is valid since we searched for the variable by
// its NamedDecl
2010-07-27 02:07:53 +00:00
2010-12-14 02:59:59 +00:00
ptr = entity_sp - > m_parser_vars - > m_lldb_value - > GetScalar ( ) . ULongLong ( ) ;
2010-08-23 23:09:38 +00:00
return true ;
2010-07-27 02:07:53 +00:00
}
2011-08-16 18:09:29 +00:00
static void
FindCodeSymbolInContext
(
const ConstString & name ,
SymbolContext & sym_ctx ,
SymbolContextList & sc_list
)
{
if ( sym_ctx . module_sp )
2011-10-13 16:49:47 +00:00
sym_ctx . module_sp - > FindSymbolsWithNameAndType ( name , eSymbolTypeCode , sc_list ) ;
2011-08-16 18:09:29 +00:00
if ( ! sc_list . GetSize ( ) )
sym_ctx . target_sp - > GetImages ( ) . FindSymbolsWithNameAndType ( name , eSymbolTypeCode , sc_list ) ;
}
2010-07-31 01:32:05 +00:00
bool
2010-10-15 22:48:33 +00:00
ClangExpressionDeclMap : : GetFunctionAddress
(
const ConstString & name ,
2011-05-18 22:01:49 +00:00
uint64_t & func_addr
2010-10-15 22:48:33 +00:00
)
2010-07-31 01:32:05 +00:00
{
2010-12-03 01:38:59 +00:00
assert ( m_parser_vars . get ( ) ) ;
2011-05-13 18:27:02 +00:00
lldb : : LogSP log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_EXPRESSIONS ) ) ;
2012-02-10 01:22:05 +00:00
ExecutionContext & exe_ctx = m_parser_vars - > m_exe_ctx ;
Target * target = exe_ctx . GetTargetPtr ( ) ;
2010-07-31 01:32:05 +00:00
// Back out in all cases where we're not fully initialized
2011-09-22 04:58:26 +00:00
if ( target = = NULL )
2010-12-07 01:56:02 +00:00
return false ;
if ( ! m_parser_vars - > m_sym_ctx . target_sp )
2010-07-31 01:32:05 +00:00
return false ;
2010-11-09 23:46:37 +00:00
SymbolContextList sc_list ;
2010-07-31 01:32:05 +00:00
2011-08-16 18:09:29 +00:00
FindCodeSymbolInContext ( name , m_parser_vars - > m_sym_ctx , sc_list ) ;
2010-11-09 23:46:37 +00:00
if ( ! sc_list . GetSize ( ) )
2011-05-13 18:27:02 +00:00
{
// We occasionally get debug information in which a const function is reported
// as non-const, so the mangled name is wrong. This is a hack to compensate.
2011-10-25 18:02:05 +00:00
if ( ! strncmp ( name . GetCString ( ) , " _ZN " , 3 ) & &
strncmp ( name . GetCString ( ) , " _ZNK " , 4 ) )
2011-05-13 18:27:02 +00:00
{
2011-10-25 18:02:05 +00:00
std : : string fixed_scratch ( " _ZNK " ) ;
fixed_scratch . append ( name . GetCString ( ) + 3 ) ;
ConstString fixed_name ( fixed_scratch . c_str ( ) ) ;
2011-05-13 18:27:02 +00:00
if ( log )
2011-10-25 18:02:05 +00:00
log - > Printf ( " Failed to find symbols given non-const name %s; trying %s " , name . GetCString ( ) , fixed_name . GetCString ( ) ) ;
FindCodeSymbolInContext ( fixed_name , m_parser_vars - > m_sym_ctx , sc_list ) ;
2011-05-13 18:27:02 +00:00
}
}
if ( ! sc_list . GetSize ( ) )
2010-07-31 01:32:05 +00:00
return false ;
SymbolContext sym_ctx ;
2010-11-09 23:46:37 +00:00
sc_list . GetContextAtIndex ( 0 , sym_ctx ) ;
2010-07-31 01:32:05 +00:00
2011-05-18 22:01:49 +00:00
const Address * func_so_addr = NULL ;
2010-07-31 01:32:05 +00:00
if ( sym_ctx . function )
2011-05-18 22:01:49 +00:00
func_so_addr = & sym_ctx . function - > GetAddressRange ( ) . GetBaseAddress ( ) ;
2010-07-31 01:32:05 +00:00
else if ( sym_ctx . symbol )
2012-03-07 21:03:09 +00:00
func_so_addr = & sym_ctx . symbol - > GetAddress ( ) ;
2010-07-31 01:32:05 +00:00
else
return false ;
2011-07-07 23:05:43 +00:00
if ( ! func_so_addr | | ! func_so_addr - > IsValid ( ) )
return false ;
2011-09-22 04:58:26 +00:00
func_addr = func_so_addr - > GetCallableLoadAddress ( target ) ;
2011-05-18 22:01:49 +00:00
2010-07-31 01:32:05 +00:00
return true ;
}
2011-06-23 04:25:29 +00:00
addr_t
2012-11-15 02:02:04 +00:00
ClangExpressionDeclMap : : GetSymbolAddress ( Target & target , Process * process , const ConstString & name , lldb : : SymbolType symbol_type )
2011-01-17 23:42:46 +00:00
{
SymbolContextList sc_list ;
2011-12-01 02:04:16 +00:00
target . GetImages ( ) . FindSymbolsWithNameAndType ( name , symbol_type , sc_list ) ;
2011-01-17 23:42:46 +00:00
2011-06-23 04:25:29 +00:00
const uint32_t num_matches = sc_list . GetSize ( ) ;
addr_t symbol_load_addr = LLDB_INVALID_ADDRESS ;
2011-12-01 02:04:16 +00:00
for ( uint32_t i = 0 ; i < num_matches & & ( symbol_load_addr = = 0 | | symbol_load_addr = = LLDB_INVALID_ADDRESS ) ; i + + )
2011-06-23 04:25:29 +00:00
{
SymbolContext sym_ctx ;
sc_list . GetContextAtIndex ( i , sym_ctx ) ;
2011-01-17 23:42:46 +00:00
2012-03-07 21:03:09 +00:00
const Address * sym_address = & sym_ctx . symbol - > GetAddress ( ) ;
2011-07-07 23:05:43 +00:00
if ( ! sym_address | | ! sym_address - > IsValid ( ) )
return LLDB_INVALID_ADDRESS ;
2011-06-23 04:25:29 +00:00
if ( sym_address )
{
switch ( sym_ctx . symbol - > GetType ( ) )
{
case eSymbolTypeCode :
case eSymbolTypeTrampoline :
symbol_load_addr = sym_address - > GetCallableLoadAddress ( & target ) ;
break ;
case eSymbolTypeData :
case eSymbolTypeRuntime :
case eSymbolTypeVariable :
case eSymbolTypeLocal :
case eSymbolTypeParam :
case eSymbolTypeInvalid :
case eSymbolTypeAbsolute :
case eSymbolTypeException :
case eSymbolTypeSourceFile :
case eSymbolTypeHeaderFile :
case eSymbolTypeObjectFile :
case eSymbolTypeCommonBlock :
case eSymbolTypeBlock :
case eSymbolTypeVariableType :
case eSymbolTypeLineEntry :
case eSymbolTypeLineHeader :
case eSymbolTypeScopeBegin :
case eSymbolTypeScopeEnd :
case eSymbolTypeAdditional :
case eSymbolTypeCompiler :
case eSymbolTypeInstrumentation :
case eSymbolTypeUndefined :
2011-12-03 02:30:59 +00:00
case eSymbolTypeObjCClass :
case eSymbolTypeObjCMetaClass :
case eSymbolTypeObjCIVar :
2011-06-23 04:25:29 +00:00
symbol_load_addr = sym_address - > GetLoadAddress ( & target ) ;
break ;
}
}
}
2011-01-17 23:42:46 +00:00
2012-11-15 02:02:04 +00:00
if ( symbol_load_addr = = LLDB_INVALID_ADDRESS & & process )
{
ObjCLanguageRuntime * runtime = process - > GetObjCLanguageRuntime ( ) ;
if ( runtime )
{
symbol_load_addr = runtime - > LookupRuntimeSymbol ( name ) ;
}
}
2011-06-23 04:25:29 +00:00
return symbol_load_addr ;
2011-01-17 23:42:46 +00:00
}
2011-06-23 04:25:29 +00:00
addr_t
2011-12-01 02:04:16 +00:00
ClangExpressionDeclMap : : GetSymbolAddress ( const ConstString & name , lldb : : SymbolType symbol_type )
2011-05-08 02:21:26 +00:00
{
assert ( m_parser_vars . get ( ) ) ;
2012-02-10 01:22:05 +00:00
if ( ! m_parser_vars - > m_exe_ctx . GetTargetPtr ( ) )
2011-05-08 02:21:26 +00:00
return false ;
2012-11-15 02:02:04 +00:00
return GetSymbolAddress ( m_parser_vars - > m_exe_ctx . GetTargetRef ( ) , m_parser_vars - > m_exe_ctx . GetProcessPtr ( ) , name , symbol_type ) ;
2011-05-08 02:21:26 +00:00
}
2011-09-15 02:13:07 +00:00
// Interface for IRInterpreter
2011-10-21 05:18:02 +00:00
Value
ClangExpressionDeclMap : : WrapBareAddress ( lldb : : addr_t addr )
{
Value ret ;
ret . SetContext ( Value : : eContextTypeInvalid , NULL ) ;
2012-02-10 01:22:05 +00:00
if ( m_parser_vars - > m_exe_ctx . GetProcessPtr ( ) )
2011-10-21 05:18:02 +00:00
ret . SetValueType ( Value : : eValueTypeLoadAddress ) ;
else
ret . SetValueType ( Value : : eValueTypeFileAddress ) ;
ret . GetScalar ( ) = ( unsigned long long ) addr ;
return ret ;
}
2011-09-15 02:13:07 +00:00
bool
ClangExpressionDeclMap : : WriteTarget ( lldb_private : : Value & value ,
const uint8_t * data ,
size_t length )
{
assert ( m_parser_vars . get ( ) ) ;
2012-02-10 01:22:05 +00:00
ExecutionContext & exe_ctx = m_parser_vars - > m_exe_ctx ;
2011-09-15 02:13:07 +00:00
2012-02-10 01:22:05 +00:00
Process * process = exe_ctx . GetProcessPtr ( ) ;
2011-09-15 02:13:07 +00:00
if ( value . GetContextType ( ) = = Value : : eContextTypeRegisterInfo )
{
2011-09-22 04:58:26 +00:00
if ( ! process )
2011-09-15 02:13:07 +00:00
return false ;
2012-02-10 01:22:05 +00:00
RegisterContext * reg_ctx = exe_ctx . GetRegisterContext ( ) ;
2011-09-15 02:13:07 +00:00
RegisterInfo * reg_info = value . GetRegisterInfo ( ) ;
if ( ! reg_ctx )
return false ;
lldb_private : : RegisterValue reg_value ;
Error err ;
2011-09-22 04:58:26 +00:00
if ( ! reg_value . SetFromMemoryData ( reg_info , data , length , process - > GetByteOrder ( ) , err ) )
2011-09-15 02:13:07 +00:00
return false ;
return reg_ctx - > WriteRegister ( reg_info , reg_value ) ;
}
else
{
switch ( value . GetValueType ( ) )
{
default :
return false ;
case Value : : eValueTypeFileAddress :
{
2011-09-22 04:58:26 +00:00
if ( ! process )
2011-09-15 02:13:07 +00:00
return false ;
2012-02-10 01:22:05 +00:00
Target * target = exe_ctx . GetTargetPtr ( ) ;
2011-09-15 02:13:07 +00:00
Address file_addr ;
2011-09-22 04:58:26 +00:00
if ( ! target - > GetImages ( ) . ResolveFileAddress ( ( lldb : : addr_t ) value . GetScalar ( ) . ULongLong ( ) , file_addr ) )
2011-09-15 02:13:07 +00:00
return false ;
2011-09-22 04:58:26 +00:00
lldb : : addr_t load_addr = file_addr . GetLoadAddress ( target ) ;
2011-09-15 02:13:07 +00:00
Error err ;
2011-09-22 04:58:26 +00:00
process - > WriteMemory ( load_addr , data , length , err ) ;
2011-09-15 02:13:07 +00:00
return err . Success ( ) ;
}
case Value : : eValueTypeLoadAddress :
{
2011-09-22 04:58:26 +00:00
if ( ! process )
2011-09-15 02:13:07 +00:00
return false ;
Error err ;
2011-09-22 04:58:26 +00:00
process - > WriteMemory ( ( lldb : : addr_t ) value . GetScalar ( ) . ULongLong ( ) , data , length , err ) ;
2011-09-15 02:13:07 +00:00
return err . Success ( ) ;
}
case Value : : eValueTypeHostAddress :
2011-12-06 03:41:14 +00:00
{
if ( value . GetScalar ( ) . ULongLong ( ) = = 0 | | data = = NULL )
return false ;
memcpy ( ( void * ) value . GetScalar ( ) . ULongLong ( ) , data , length ) ;
return true ;
}
2011-09-15 02:13:07 +00:00
case Value : : eValueTypeScalar :
return false ;
}
}
}
bool
ClangExpressionDeclMap : : ReadTarget ( uint8_t * data ,
lldb_private : : Value & value ,
size_t length )
{
assert ( m_parser_vars . get ( ) ) ;
2012-02-10 01:22:05 +00:00
ExecutionContext & exe_ctx = m_parser_vars - > m_exe_ctx ;
2011-09-22 04:58:26 +00:00
2012-02-10 01:22:05 +00:00
Process * process = exe_ctx . GetProcessPtr ( ) ;
2011-09-22 04:58:26 +00:00
2011-09-15 02:13:07 +00:00
if ( value . GetContextType ( ) = = Value : : eContextTypeRegisterInfo )
{
2011-09-22 04:58:26 +00:00
if ( ! process )
2011-09-15 02:13:07 +00:00
return false ;
2012-02-10 01:22:05 +00:00
RegisterContext * reg_ctx = exe_ctx . GetRegisterContext ( ) ;
2011-09-15 02:13:07 +00:00
RegisterInfo * reg_info = value . GetRegisterInfo ( ) ;
if ( ! reg_ctx )
return false ;
lldb_private : : RegisterValue reg_value ;
Error err ;
if ( ! reg_ctx - > ReadRegister ( reg_info , reg_value ) )
return false ;
2011-09-22 04:58:26 +00:00
return reg_value . GetAsMemoryData ( reg_info , data , length , process - > GetByteOrder ( ) , err ) ;
2011-09-15 02:13:07 +00:00
}
else
{
switch ( value . GetValueType ( ) )
{
default :
return false ;
case Value : : eValueTypeFileAddress :
{
2012-02-10 01:22:05 +00:00
Target * target = exe_ctx . GetTargetPtr ( ) ;
2011-09-22 04:58:26 +00:00
if ( target = = NULL )
2011-09-15 02:13:07 +00:00
return false ;
Address file_addr ;
2011-09-22 04:58:26 +00:00
if ( ! target - > GetImages ( ) . ResolveFileAddress ( ( lldb : : addr_t ) value . GetScalar ( ) . ULongLong ( ) , file_addr ) )
2011-09-15 02:13:07 +00:00
return false ;
Error err ;
2012-02-08 21:55:14 +00:00
target - > ReadMemory ( file_addr , false , data , length , err ) ;
2011-09-15 02:13:07 +00:00
return err . Success ( ) ;
}
case Value : : eValueTypeLoadAddress :
{
2011-09-22 04:58:26 +00:00
if ( ! process )
2011-09-15 02:13:07 +00:00
return false ;
Error err ;
2011-09-22 04:58:26 +00:00
process - > ReadMemory ( ( lldb : : addr_t ) value . GetScalar ( ) . ULongLong ( ) , data , length , err ) ;
2011-09-15 02:13:07 +00:00
return err . Success ( ) ;
}
case Value : : eValueTypeHostAddress :
2011-11-18 03:28:09 +00:00
{
void * host_addr = ( void * ) value . GetScalar ( ) . ULongLong ( ) ;
if ( ! host_addr )
return false ;
memcpy ( data , host_addr , length ) ;
2011-09-15 02:13:07 +00:00
return true ;
2011-11-18 03:28:09 +00:00
}
2011-09-15 02:13:07 +00:00
case Value : : eValueTypeScalar :
return false ;
}
}
}
lldb_private : : Value
2012-02-15 01:40:39 +00:00
ClangExpressionDeclMap : : LookupDecl ( clang : : NamedDecl * decl , ClangExpressionVariable : : FlagType & flags )
2011-09-15 02:13:07 +00:00
{
assert ( m_parser_vars . get ( ) ) ;
2012-02-10 01:22:05 +00:00
2011-09-15 02:13:07 +00:00
ClangExpressionVariableSP expr_var_sp ( m_found_entities . GetVariable ( decl ) ) ;
ClangExpressionVariableSP persistent_var_sp ( m_parser_vars - > m_persistent_vars - > GetVariable ( decl ) ) ;
2011-11-02 23:24:30 +00:00
2011-09-15 02:13:07 +00:00
if ( expr_var_sp )
{
2012-02-15 01:40:39 +00:00
flags = expr_var_sp - > m_flags ;
2012-02-08 21:55:14 +00:00
if ( ! expr_var_sp - > m_parser_vars . get ( ) )
2011-10-12 22:20:02 +00:00
return Value ( ) ;
2011-11-02 23:24:30 +00:00
bool is_reference = expr_var_sp - > m_flags & ClangExpressionVariable : : EVTypeIsReference ;
2012-02-08 21:55:14 +00:00
if ( expr_var_sp - > m_parser_vars - > m_lldb_var )
2011-11-02 23:24:30 +00:00
{
2012-02-10 01:22:05 +00:00
std : : auto_ptr < Value > value ( GetVariableValue ( expr_var_sp - > m_parser_vars - > m_lldb_var , NULL ) ) ;
2011-11-02 23:24:30 +00:00
2012-02-08 21:55:14 +00:00
if ( is_reference & & value . get ( ) & & value - > GetValueType ( ) = = Value : : eValueTypeLoadAddress )
{
2012-02-10 01:22:05 +00:00
Process * process = m_parser_vars - > m_exe_ctx . GetProcessPtr ( ) ;
2012-02-08 21:55:14 +00:00
if ( ! process )
return Value ( ) ;
lldb : : addr_t value_addr = value - > GetScalar ( ) . ULongLong ( ) ;
Error read_error ;
addr_t ref_value = process - > ReadPointerFromMemory ( value_addr , read_error ) ;
if ( ! read_error . Success ( ) )
return Value ( ) ;
value - > GetScalar ( ) = ( unsigned long long ) ref_value ;
}
2011-11-02 23:24:30 +00:00
2012-02-08 21:55:14 +00:00
if ( value . get ( ) )
return * value ;
else
return Value ( ) ;
}
else if ( expr_var_sp - > m_parser_vars - > m_lldb_sym )
{
2012-03-07 21:03:09 +00:00
const Address sym_address = expr_var_sp - > m_parser_vars - > m_lldb_sym - > GetAddress ( ) ;
2012-02-08 21:55:14 +00:00
if ( ! sym_address . IsValid ( ) )
return Value ( ) ;
Value ret ;
2012-02-28 17:55:31 +00:00
ProcessSP process_sp ( m_parser_vars - > m_exe_ctx . GetProcessSP ( ) ) ;
if ( process_sp )
{
uint64_t symbol_load_addr = sym_address . GetLoadAddress ( & process_sp - > GetTarget ( ) ) ;
ret . GetScalar ( ) = symbol_load_addr ;
ret . SetValueType ( Value : : eValueTypeLoadAddress ) ;
}
else
{
uint64_t symbol_file_addr = sym_address . GetFileAddress ( ) ;
ret . GetScalar ( ) = symbol_file_addr ;
ret . SetValueType ( Value : : eValueTypeFileAddress ) ;
}
2012-02-08 21:55:14 +00:00
return ret ;
}
2012-02-15 01:40:39 +00:00
else if ( RegisterInfo * reg_info = expr_var_sp - > GetRegisterInfo ( ) )
{
StackFrame * frame = m_parser_vars - > m_exe_ctx . GetFramePtr ( ) ;
if ( ! frame )
return Value ( ) ;
RegisterContextSP reg_context_sp ( frame - > GetRegisterContextSP ( ) ) ;
RegisterValue reg_value ;
if ( ! reg_context_sp - > ReadRegister ( reg_info , reg_value ) )
return Value ( ) ;
Value ret ;
ret . SetContext ( Value : : eContextTypeRegisterInfo , reg_info ) ;
2012-10-30 18:18:43 +00:00
if ( reg_info - > encoding = = eEncodingVector )
{
if ( ret . SetVectorBytes ( ( uint8_t * ) reg_value . GetBytes ( ) , reg_value . GetByteSize ( ) , reg_value . GetByteOrder ( ) ) )
ret . SetScalarFromVector ( ) ;
}
else if ( ! reg_value . GetScalarValue ( ret . GetScalar ( ) ) )
return Value ( ) ;
2012-02-15 01:40:39 +00:00
return ret ;
}
2011-10-26 21:20:00 +00:00
else
2012-02-08 21:55:14 +00:00
{
2011-10-26 21:20:00 +00:00
return Value ( ) ;
2012-02-08 21:55:14 +00:00
}
2011-09-15 02:13:07 +00:00
}
else if ( persistent_var_sp )
{
2012-02-15 01:40:39 +00:00
flags = persistent_var_sp - > m_flags ;
2011-09-22 00:41:11 +00:00
if ( ( persistent_var_sp - > m_flags & ClangExpressionVariable : : EVIsProgramReference | |
persistent_var_sp - > m_flags & ClangExpressionVariable : : EVIsLLDBAllocated ) & &
2011-10-22 01:58:08 +00:00
persistent_var_sp - > m_live_sp & &
2011-12-10 03:12:34 +00:00
( ( persistent_var_sp - > m_live_sp - > GetValue ( ) . GetValueType ( ) = = Value : : eValueTypeLoadAddress & &
2012-02-10 01:22:05 +00:00
m_parser_vars - > m_exe_ctx . GetProcessSP ( ) & &
m_parser_vars - > m_exe_ctx . GetProcessSP ( ) - > IsAlive ( ) ) | |
2011-12-10 03:12:34 +00:00
( persistent_var_sp - > m_live_sp - > GetValue ( ) . GetValueType ( ) = = Value : : eValueTypeFileAddress ) ) )
2011-09-22 00:41:11 +00:00
{
2011-10-26 21:20:00 +00:00
return persistent_var_sp - > m_live_sp - > GetValue ( ) ;
2011-09-22 00:41:11 +00:00
}
else
{
lldb_private : : Value ret ;
ret . SetValueType ( Value : : eValueTypeHostAddress ) ;
ret . SetContext ( Value : : eContextTypeInvalid , NULL ) ;
ret . GetScalar ( ) = ( lldb : : addr_t ) persistent_var_sp - > GetValueBytes ( ) ;
return ret ;
}
2011-09-15 02:13:07 +00:00
}
else
{
return Value ( ) ;
}
}
2011-10-26 21:20:00 +00:00
Value
ClangExpressionDeclMap : : GetSpecialValue ( const ConstString & name )
{
assert ( m_parser_vars . get ( ) ) ;
2012-02-10 01:22:05 +00:00
StackFrame * frame = m_parser_vars - > m_exe_ctx . GetFramePtr ( ) ;
2011-10-26 21:20:00 +00:00
if ( ! frame )
return Value ( ) ;
VariableList * vars = frame - > GetVariableList ( false ) ;
if ( ! vars )
return Value ( ) ;
lldb : : VariableSP var = vars - > FindVariable ( name ) ;
if ( ! var | |
! var - > IsInScope ( frame ) | |
! var - > LocationIsValidForFrame ( frame ) )
return Value ( ) ;
2012-02-10 01:22:05 +00:00
std : : auto_ptr < Value > value ( GetVariableValue ( var , NULL ) ) ;
2011-10-26 21:20:00 +00:00
2011-11-03 22:48:37 +00:00
if ( value . get ( ) & & value - > GetValueType ( ) = = Value : : eValueTypeLoadAddress )
{
2012-02-10 01:22:05 +00:00
Process * process = m_parser_vars - > m_exe_ctx . GetProcessPtr ( ) ;
2011-11-03 22:48:37 +00:00
if ( ! process )
return Value ( ) ;
lldb : : addr_t value_addr = value - > GetScalar ( ) . ULongLong ( ) ;
Error read_error ;
addr_t ptr_value = process - > ReadPointerFromMemory ( value_addr , read_error ) ;
if ( ! read_error . Success ( ) )
return Value ( ) ;
value - > GetScalar ( ) = ( unsigned long long ) ptr_value ;
}
2011-10-26 21:20:00 +00:00
if ( value . get ( ) )
return * value ;
else
return Value ( ) ;
}
2010-07-16 00:09:46 +00:00
// Interface for CommandObjectExpression
2010-07-20 23:31:16 +00:00
bool
2010-10-15 22:48:33 +00:00
ClangExpressionDeclMap : : Materialize
(
lldb : : addr_t & struct_address ,
Error & err
)
2010-07-20 23:31:16 +00:00
{
2012-02-10 01:22:05 +00:00
if ( ! m_parser_vars . get ( ) )
return false ;
2010-12-03 01:38:59 +00:00
EnableMaterialVars ( ) ;
2012-02-10 01:22:05 +00:00
m_material_vars - > m_process = m_parser_vars - > m_exe_ctx . GetProcessPtr ( ) ;
2010-12-03 01:38:59 +00:00
2011-05-09 22:04:36 +00:00
bool result = DoMaterialize ( false /* dematerialize */ ,
LLDB_INVALID_ADDRESS /* top of stack frame */ ,
LLDB_INVALID_ADDRESS /* bottom of stack frame */ ,
NULL , /* result SP */
err ) ;
2010-07-20 23:31:16 +00:00
if ( result )
2010-12-03 01:38:59 +00:00
struct_address = m_material_vars - > m_materialized_location ;
2010-07-20 23:31:16 +00:00
return result ;
}
2010-09-21 00:44:12 +00:00
bool
2010-10-15 22:48:33 +00:00
ClangExpressionDeclMap : : GetObjectPointer
(
lldb : : addr_t & object_ptr ,
2010-12-13 22:46:15 +00:00
ConstString & object_name ,
2010-12-14 00:42:36 +00:00
Error & err ,
bool suppress_type_check
2010-10-15 22:48:33 +00:00
)
2010-09-21 00:44:12 +00:00
{
2010-12-03 01:38:59 +00:00
assert ( m_struct_vars . get ( ) ) ;
2012-02-10 01:22:05 +00:00
Target * target = m_parser_vars - > m_exe_ctx . GetTargetPtr ( ) ;
Process * process = m_parser_vars - > m_exe_ctx . GetProcessPtr ( ) ;
StackFrame * frame = m_parser_vars - > m_exe_ctx . GetFramePtr ( ) ;
2011-09-22 04:58:26 +00:00
if ( frame = = NULL | | process = = NULL | | target = = NULL )
2010-09-21 00:44:12 +00:00
{
2011-11-15 02:11:17 +00:00
err . SetErrorStringWithFormat ( " Couldn't load '%s' because the context is incomplete " , object_name . AsCString ( ) ) ;
2010-09-21 00:44:12 +00:00
return false ;
}
2010-12-03 01:38:59 +00:00
if ( ! m_struct_vars - > m_object_pointer_type . GetOpaqueQualType ( ) )
2010-09-21 00:44:12 +00:00
{
2011-11-15 02:11:17 +00:00
err . SetErrorStringWithFormat ( " Couldn't load '%s' because its type is unknown " , object_name . AsCString ( ) ) ;
2010-09-21 00:44:12 +00:00
return false ;
}
2012-05-21 21:29:52 +00:00
const bool object_pointer = true ;
2012-02-18 02:01:03 +00:00
2011-09-22 04:58:26 +00:00
VariableSP object_ptr_var = FindVariableInScope ( * frame ,
2011-05-07 01:06:41 +00:00
object_name ,
2012-02-18 02:01:03 +00:00
( suppress_type_check ? NULL : & m_struct_vars - > m_object_pointer_type ) ,
2012-05-21 21:29:52 +00:00
object_pointer ) ;
2010-09-21 00:44:12 +00:00
if ( ! object_ptr_var )
{
2011-11-15 02:11:17 +00:00
err . SetErrorStringWithFormat ( " Couldn't find '%s' with appropriate type in scope " , object_name . AsCString ( ) ) ;
2010-09-21 00:44:12 +00:00
return false ;
}
2012-02-10 01:22:05 +00:00
std : : auto_ptr < lldb_private : : Value > location_value ( GetVariableValue ( object_ptr_var ,
2010-12-03 01:38:59 +00:00
NULL ) ) ;
2010-09-21 00:44:12 +00:00
if ( ! location_value . get ( ) )
{
2010-12-13 22:46:15 +00:00
err . SetErrorStringWithFormat ( " Couldn't get the location for '%s' " , object_name . GetCString ( ) ) ;
2010-09-21 00:44:12 +00:00
return false ;
}
2011-03-04 00:23:47 +00:00
switch ( location_value - > GetValueType ( ) )
2010-09-21 00:44:12 +00:00
{
2011-03-04 00:23:47 +00:00
default :
2010-12-13 22:46:15 +00:00
err . SetErrorStringWithFormat ( " '%s' is not in memory; LLDB must be extended to handle registers " , object_name . GetCString ( ) ) ;
2010-09-21 00:44:12 +00:00
return false ;
2011-03-04 00:23:47 +00:00
case Value : : eValueTypeLoadAddress :
{
lldb : : addr_t value_addr = location_value - > GetScalar ( ) . ULongLong ( ) ;
2011-09-22 04:58:26 +00:00
uint32_t address_byte_size = target - > GetArchitecture ( ) . GetAddressByteSize ( ) ;
2011-03-04 00:23:47 +00:00
if ( ClangASTType : : GetClangTypeBitWidth ( m_struct_vars - > m_object_pointer_type . GetASTContext ( ) ,
m_struct_vars - > m_object_pointer_type . GetOpaqueQualType ( ) ) ! = address_byte_size * 8 )
{
err . SetErrorStringWithFormat ( " '%s' is not of an expected pointer size " , object_name . GetCString ( ) ) ;
return false ;
}
Error read_error ;
2011-09-22 04:58:26 +00:00
object_ptr = process - > ReadPointerFromMemory ( value_addr , read_error ) ;
2011-05-22 22:46:53 +00:00
if ( read_error . Fail ( ) | | object_ptr = = LLDB_INVALID_ADDRESS )
2011-03-04 00:23:47 +00:00
{
err . SetErrorStringWithFormat ( " Coldn't read '%s' from the target: %s " , object_name . GetCString ( ) , read_error . AsCString ( ) ) ;
return false ;
2011-05-22 22:46:53 +00:00
}
2011-03-04 00:23:47 +00:00
return true ;
}
case Value : : eValueTypeScalar :
{
if ( location_value - > GetContextType ( ) ! = Value : : eContextTypeRegisterInfo )
{
StreamString ss ;
location_value - > Dump ( & ss ) ;
err . SetErrorStringWithFormat ( " %s is a scalar of unhandled type: %s " , object_name . GetCString ( ) , ss . GetString ( ) . c_str ( ) ) ;
return false ;
}
2011-05-09 20:18:18 +00:00
RegisterInfo * reg_info = location_value - > GetRegisterInfo ( ) ;
2011-03-04 00:23:47 +00:00
2011-05-09 20:18:18 +00:00
if ( ! reg_info )
2011-03-04 00:23:47 +00:00
{
err . SetErrorStringWithFormat ( " Couldn't get the register information for %s " , object_name . GetCString ( ) ) ;
return false ;
}
2012-02-10 01:22:05 +00:00
RegisterContext * reg_ctx = m_parser_vars - > m_exe_ctx . GetRegisterContext ( ) ;
2011-03-04 00:23:47 +00:00
2011-05-09 20:18:18 +00:00
if ( ! reg_ctx )
2011-03-04 00:23:47 +00:00
{
2011-05-09 20:18:18 +00:00
err . SetErrorStringWithFormat ( " Couldn't read register context to read %s from %s " , object_name . GetCString ( ) , reg_info - > name ) ;
2011-03-04 00:23:47 +00:00
return false ;
}
2011-05-09 20:18:18 +00:00
uint32_t register_number = reg_info - > kinds [ lldb : : eRegisterKindLLDB ] ;
2011-03-04 00:23:47 +00:00
2011-05-09 20:18:18 +00:00
object_ptr = reg_ctx - > ReadRegisterAsUnsigned ( register_number , 0x0 ) ;
2011-03-04 00:23:47 +00:00
return true ;
}
2010-09-21 00:44:12 +00:00
}
}
2010-07-20 23:31:16 +00:00
bool
2010-10-15 22:48:33 +00:00
ClangExpressionDeclMap : : Dematerialize
(
2010-12-14 02:59:59 +00:00
ClangExpressionVariableSP & result_sp ,
2011-05-09 22:04:36 +00:00
lldb : : addr_t stack_frame_top ,
lldb : : addr_t stack_frame_bottom ,
2010-10-15 22:48:33 +00:00
Error & err
)
2010-07-20 23:31:16 +00:00
{
2012-02-10 01:22:05 +00:00
return DoMaterialize ( true , stack_frame_top , stack_frame_bottom , & result_sp , err ) ;
2010-12-03 01:38:59 +00:00
DidDematerialize ( ) ;
}
void
ClangExpressionDeclMap : : DidDematerialize ( )
{
if ( m_material_vars . get ( ) )
{
if ( m_material_vars - > m_materialized_location )
{
//#define SINGLE_STEP_EXPRESSIONS
# ifndef SINGLE_STEP_EXPRESSIONS
m_material_vars - > m_process - > DeallocateMemory ( m_material_vars - > m_materialized_location ) ;
# endif
m_material_vars - > m_materialized_location = 0 ;
}
DisableMaterialVars ( ) ;
}
2010-07-20 23:31:16 +00:00
}
2010-07-23 22:19:18 +00:00
bool
2010-10-15 22:48:33 +00:00
ClangExpressionDeclMap : : DumpMaterializedStruct
(
Stream & s ,
Error & err
)
2010-07-23 22:19:18 +00:00
{
2010-12-03 01:38:59 +00:00
assert ( m_struct_vars . get ( ) ) ;
assert ( m_material_vars . get ( ) ) ;
if ( ! m_struct_vars - > m_struct_laid_out )
2010-07-23 22:19:18 +00:00
{
err . SetErrorString ( " Structure hasn't been laid out yet " ) ;
return false ;
}
2012-02-10 01:22:05 +00:00
Process * process = m_parser_vars - > m_exe_ctx . GetProcessPtr ( ) ;
2011-09-22 04:58:26 +00:00
if ( ! process )
2010-07-23 22:19:18 +00:00
{
err . SetErrorString ( " Couldn't find the process " ) ;
return false ;
}
2012-02-10 01:22:05 +00:00
Target * target = m_parser_vars - > m_exe_ctx . GetTargetPtr ( ) ;
2011-09-22 04:58:26 +00:00
if ( ! target )
2010-07-23 22:19:18 +00:00
{
err . SetErrorString ( " Couldn't find the target " ) ;
return false ;
}
2010-12-07 10:00:20 +00:00
if ( ! m_material_vars - > m_materialized_location )
{
err . SetErrorString ( " No materialized location " ) ;
return false ;
}
2011-05-22 22:46:53 +00:00
lldb : : DataBufferSP data_sp ( new DataBufferHeap ( m_struct_vars - > m_struct_size , 0 ) ) ;
2010-07-23 22:19:18 +00:00
Error error ;
2011-09-22 04:58:26 +00:00
if ( process - > ReadMemory ( m_material_vars - > m_materialized_location ,
2011-05-22 22:46:53 +00:00
data_sp - > GetBytes ( ) ,
data_sp - > GetByteSize ( ) , error ) ! = data_sp - > GetByteSize ( ) )
2010-07-23 22:19:18 +00:00
{
err . SetErrorStringWithFormat ( " Couldn't read struct from the target: %s " , error . AsCString ( ) ) ;
return false ;
}
2011-09-22 04:58:26 +00:00
DataExtractor extractor ( data_sp , process - > GetByteOrder ( ) , target - > GetArchitecture ( ) . GetAddressByteSize ( ) ) ;
2010-07-23 22:19:18 +00:00
2010-12-14 02:59:59 +00:00
for ( size_t member_idx = 0 , num_members = m_struct_members . GetSize ( ) ;
member_idx < num_members ;
+ + member_idx )
2010-07-23 22:19:18 +00:00
{
2010-12-14 02:59:59 +00:00
ClangExpressionVariableSP member_sp ( m_struct_members . GetVariableAtIndex ( member_idx ) ) ;
2010-07-23 22:19:18 +00:00
2010-12-14 02:59:59 +00:00
if ( ! member_sp )
return false ;
s . Printf ( " [%s] \n " , member_sp - > GetName ( ) . GetCString ( ) ) ;
2010-08-23 23:09:38 +00:00
2010-12-14 02:59:59 +00:00
if ( ! member_sp - > m_jit_vars . get ( ) )
2010-08-23 23:09:38 +00:00
return false ;
2010-12-14 02:59:59 +00:00
extractor . Dump ( & s , // stream
member_sp - > m_jit_vars - > m_offset , // offset
lldb : : eFormatBytesWithASCII , // format
1 , // byte size of individual entries
member_sp - > m_jit_vars - > m_size , // number of entries
16 , // entries per line
m_material_vars - > m_materialized_location + member_sp - > m_jit_vars - > m_offset , // address to print
0 , // bit size (bitfields only; 0 means ignore)
0 ) ; // bit alignment (bitfields only; 0 means ignore)
2010-07-23 22:19:18 +00:00
s . PutChar ( ' \n ' ) ;
}
return true ;
}
2010-07-20 23:31:16 +00:00
bool
2010-10-15 22:48:33 +00:00
ClangExpressionDeclMap : : DoMaterialize
(
bool dematerialize ,
2011-05-09 22:04:36 +00:00
lldb : : addr_t stack_frame_top ,
lldb : : addr_t stack_frame_bottom ,
2010-12-14 02:59:59 +00:00
lldb : : ClangExpressionVariableSP * result_sp_ptr ,
2010-10-15 22:48:33 +00:00
Error & err
)
2010-07-16 00:09:46 +00:00
{
2010-12-14 02:59:59 +00:00
if ( result_sp_ptr )
result_sp_ptr - > reset ( ) ;
2010-12-03 01:38:59 +00:00
assert ( m_struct_vars . get ( ) ) ;
2010-11-06 01:53:30 +00:00
lldb : : LogSP log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_EXPRESSIONS ) ) ;
2010-08-12 01:56:52 +00:00
2010-12-03 01:38:59 +00:00
if ( ! m_struct_vars - > m_struct_laid_out )
2010-07-16 00:09:46 +00:00
{
err . SetErrorString ( " Structure hasn't been laid out yet " ) ;
2011-09-13 04:03:52 +00:00
return false ;
2010-07-16 00:09:46 +00:00
}
2012-02-10 01:22:05 +00:00
StackFrame * frame = m_parser_vars - > m_exe_ctx . GetFramePtr ( ) ;
2011-09-22 04:58:26 +00:00
if ( ! frame )
2010-07-24 01:37:44 +00:00
{
err . SetErrorString ( " Received null execution frame " ) ;
2011-09-13 04:03:52 +00:00
return false ;
2010-07-24 01:37:44 +00:00
}
2012-02-10 01:22:05 +00:00
Target * target = m_parser_vars - > m_exe_ctx . GetTargetPtr ( ) ;
2010-07-24 01:37:44 +00:00
2011-09-22 04:58:26 +00:00
ClangPersistentVariables & persistent_vars = target - > GetPersistentVariables ( ) ;
2010-12-03 01:38:59 +00:00
if ( ! m_struct_vars - > m_struct_size )
2010-09-13 21:34:21 +00:00
{
if ( log )
log - > PutCString ( " Not bothering to allocate a struct because no arguments are needed " ) ;
2012-09-11 18:11:16 +00:00
m_material_vars - > m_allocated_area = 0UL ;
2010-09-13 21:34:21 +00:00
return true ;
}
2011-09-22 04:58:26 +00:00
const SymbolContext & sym_ctx ( frame - > GetSymbolContext ( lldb : : eSymbolContextEverything ) ) ;
2010-07-16 00:09:46 +00:00
2010-07-20 23:31:16 +00:00
if ( ! dematerialize )
2010-07-16 00:09:46 +00:00
{
2012-02-10 01:22:05 +00:00
Process * process = m_parser_vars - > m_exe_ctx . GetProcessPtr ( ) ;
2010-12-03 01:38:59 +00:00
if ( m_material_vars - > m_materialized_location )
2010-07-20 23:31:16 +00:00
{
2011-09-22 04:58:26 +00:00
process - > DeallocateMemory ( m_material_vars - > m_materialized_location ) ;
2010-12-03 01:38:59 +00:00
m_material_vars - > m_materialized_location = 0 ;
2010-07-20 23:31:16 +00:00
}
2010-10-08 01:58:41 +00:00
if ( log )
log - > PutCString ( " Allocating memory for materialized argument struct " ) ;
2011-09-22 04:58:26 +00:00
lldb : : addr_t mem = process - > AllocateMemory ( m_struct_vars - > m_struct_alignment + m_struct_vars - > m_struct_size ,
2011-11-18 03:28:09 +00:00
lldb : : ePermissionsReadable | lldb : : ePermissionsWritable ,
err ) ;
2010-07-20 23:31:16 +00:00
if ( mem = = LLDB_INVALID_ADDRESS )
2011-11-18 03:28:09 +00:00
{
2012-11-29 21:49:15 +00:00
err . SetErrorStringWithFormat ( " Couldn't allocate 0x%llx bytes for materialized argument struct " ,
2011-11-18 03:28:09 +00:00
( unsigned long long ) ( m_struct_vars - > m_struct_alignment + m_struct_vars - > m_struct_size ) ) ;
2010-07-20 23:31:16 +00:00
return false ;
2011-11-18 03:28:09 +00:00
}
2010-12-03 01:38:59 +00:00
m_material_vars - > m_allocated_area = mem ;
2010-07-16 00:09:46 +00:00
}
2010-12-03 01:38:59 +00:00
m_material_vars - > m_materialized_location = m_material_vars - > m_allocated_area ;
2010-07-20 23:31:16 +00:00
2010-12-03 01:38:59 +00:00
if ( m_material_vars - > m_materialized_location % m_struct_vars - > m_struct_alignment )
m_material_vars - > m_materialized_location + = ( m_struct_vars - > m_struct_alignment - ( m_material_vars - > m_materialized_location % m_struct_vars - > m_struct_alignment ) ) ;
2010-07-20 23:31:16 +00:00
2010-12-14 02:59:59 +00:00
for ( uint64_t member_index = 0 , num_members = m_struct_members . GetSize ( ) ;
2010-08-23 23:09:38 +00:00
member_index < num_members ;
+ + member_index )
2010-07-16 00:09:46 +00:00
{
2010-12-14 02:59:59 +00:00
ClangExpressionVariableSP member_sp ( m_struct_members . GetVariableAtIndex ( member_index ) ) ;
2010-07-16 00:09:46 +00:00
2011-01-09 21:07:35 +00:00
if ( m_found_entities . ContainsVariable ( member_sp ) )
2010-08-23 23:09:38 +00:00
{
2012-08-16 21:34:44 +00:00
if ( ! member_sp - > GetValueObject ( ) )
{
err . SetErrorString ( " Variable being materialized doesn't have a frozen version " ) ;
return false ;
}
2011-01-09 21:07:35 +00:00
RegisterInfo * reg_info = member_sp - > GetRegisterInfo ( ) ;
2010-12-14 02:59:59 +00:00
if ( reg_info )
2010-11-30 00:27:43 +00:00
{
// This is a register variable
2012-02-10 01:22:05 +00:00
RegisterContext * reg_ctx = m_parser_vars - > m_exe_ctx . GetRegisterContext ( ) ;
2010-11-30 00:27:43 +00:00
if ( ! reg_ctx )
2011-11-18 03:28:09 +00:00
{
err . SetErrorString ( " Couldn't get register context " ) ;
2010-11-30 00:27:43 +00:00
return false ;
2011-11-18 03:28:09 +00:00
}
2010-12-14 02:59:59 +00:00
if ( ! DoMaterializeOneRegister ( dematerialize ,
* reg_ctx ,
* reg_info ,
m_material_vars - > m_materialized_location + member_sp - > m_jit_vars - > m_offset ,
err ) )
2010-11-30 00:27:43 +00:00
return false ;
}
else
{
2010-12-14 02:59:59 +00:00
if ( ! member_sp - > m_jit_vars . get ( ) )
2011-11-18 03:28:09 +00:00
{
err . SetErrorString ( " Variable being materialized doesn't have necessary state " ) ;
2010-11-30 00:27:43 +00:00
return false ;
2011-11-18 03:28:09 +00:00
}
2010-11-30 00:27:43 +00:00
2010-12-14 02:59:59 +00:00
if ( ! DoMaterializeOneVariable ( dematerialize ,
2011-01-13 08:53:35 +00:00
sym_ctx ,
member_sp ,
2010-12-14 02:59:59 +00:00
m_material_vars - > m_materialized_location + member_sp - > m_jit_vars - > m_offset ,
err ) )
2010-11-30 00:27:43 +00:00
return false ;
}
2010-08-23 23:09:38 +00:00
}
else
{
2011-01-09 21:07:35 +00:00
// No need to look for presistent variables if the name doesn't start
// with with a '$' character...
if ( member_sp - > GetName ( ) . AsCString ( " ! " ) [ 0 ] = = ' $ ' & & persistent_vars . ContainsVariable ( member_sp ) )
{
2011-01-13 08:53:35 +00:00
2011-01-09 21:07:35 +00:00
if ( member_sp - > GetName ( ) = = m_struct_vars - > m_result_name )
{
if ( log )
log - > PutCString ( " Found result member in the struct " ) ;
2011-01-13 08:53:35 +00:00
2011-01-09 21:07:35 +00:00
if ( result_sp_ptr )
* result_sp_ptr = member_sp ;
2011-01-13 08:53:35 +00:00
2011-01-09 21:07:35 +00:00
}
if ( ! DoMaterializeOnePersistentVariable ( dematerialize ,
member_sp ,
2011-05-09 22:04:36 +00:00
m_material_vars - > m_materialized_location + member_sp - > m_jit_vars - > m_offset ,
stack_frame_top ,
stack_frame_bottom ,
2011-01-09 21:07:35 +00:00
err ) )
return false ;
}
else
{
err . SetErrorStringWithFormat ( " Unexpected variable %s " , member_sp - > GetName ( ) . GetCString ( ) ) ;
return false ;
}
2010-08-23 23:09:38 +00:00
}
2010-07-16 00:09:46 +00:00
}
2010-07-20 23:31:16 +00:00
return true ;
}
2010-08-11 03:57:18 +00:00
bool
2010-10-15 22:48:33 +00:00
ClangExpressionDeclMap : : DoMaterializeOnePersistentVariable
(
bool dematerialize ,
2010-12-14 02:59:59 +00:00
ClangExpressionVariableSP & var_sp ,
2010-10-15 22:48:33 +00:00
lldb : : addr_t addr ,
2011-05-09 22:04:36 +00:00
lldb : : addr_t stack_frame_top ,
lldb : : addr_t stack_frame_bottom ,
2010-10-15 22:48:33 +00:00
Error & err
)
2010-12-03 01:38:59 +00:00
{
2011-01-13 08:53:35 +00:00
lldb : : LogSP log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_EXPRESSIONS ) ) ;
2010-12-14 02:59:59 +00:00
if ( ! var_sp )
2010-08-11 03:57:18 +00:00
{
2010-12-14 02:59:59 +00:00
err . SetErrorString ( " Invalid persistent variable " ) ;
2010-08-11 03:57:18 +00:00
return LLDB_INVALID_ADDRESS ;
}
2010-12-14 02:59:59 +00:00
const size_t pvar_byte_size = var_sp - > GetByteSize ( ) ;
2010-08-20 01:02:30 +00:00
2010-12-14 02:59:59 +00:00
uint8_t * pvar_data = var_sp - > GetValueBytes ( ) ;
if ( pvar_data = = NULL )
2011-11-18 03:28:09 +00:00
{
err . SetErrorString ( " Persistent variable being materialized contains no data " ) ;
2010-08-20 01:02:30 +00:00
return false ;
2011-11-18 03:28:09 +00:00
}
2010-08-20 01:02:30 +00:00
2010-08-11 03:57:18 +00:00
Error error ;
2012-02-10 01:22:05 +00:00
Process * process = m_parser_vars - > m_exe_ctx . GetProcessPtr ( ) ;
2011-09-22 04:58:26 +00:00
2011-01-13 08:53:35 +00:00
lldb : : addr_t mem ; // The address of a spare memory area used to hold the persistent variable.
2010-08-11 03:57:18 +00:00
if ( dematerialize )
{
2011-01-13 08:53:35 +00:00
if ( log )
log - > Printf ( " Dematerializing persistent variable with flags 0x%hx " , var_sp - > m_flags ) ;
if ( ( var_sp - > m_flags & ClangExpressionVariable : : EVIsLLDBAllocated ) | |
( var_sp - > m_flags & ClangExpressionVariable : : EVIsProgramReference ) )
2010-08-11 03:57:18 +00:00
{
2011-01-13 08:53:35 +00:00
// Get the location of the target out of the struct.
Error read_error ;
2011-09-22 04:58:26 +00:00
mem = process - > ReadPointerFromMemory ( addr , read_error ) ;
2011-01-13 08:53:35 +00:00
if ( mem = = LLDB_INVALID_ADDRESS )
{
err . SetErrorStringWithFormat ( " Couldn't read address of %s from struct: %s " , var_sp - > GetName ( ) . GetCString ( ) , error . AsCString ( ) ) ;
return false ;
}
if ( var_sp - > m_flags & ClangExpressionVariable : : EVIsProgramReference & &
! var_sp - > m_live_sp )
{
// If the reference comes from the program, then the ClangExpressionVariable's
// live variable data hasn't been set up yet. Do this now.
2012-02-10 01:22:05 +00:00
var_sp - > m_live_sp = ValueObjectConstResult : : Create ( m_parser_vars - > m_exe_ctx . GetBestExecutionContextScope ( ) ,
2011-04-22 23:53:53 +00:00
var_sp - > GetTypeFromUser ( ) . GetASTContext ( ) ,
var_sp - > GetTypeFromUser ( ) . GetOpaqueQualType ( ) ,
var_sp - > GetName ( ) ,
mem ,
eAddressTypeLoad ,
pvar_byte_size ) ;
2011-01-13 08:53:35 +00:00
}
if ( ! var_sp - > m_live_sp )
{
err . SetErrorStringWithFormat ( " Couldn't find the memory area used to store %s " , var_sp - > GetName ( ) . GetCString ( ) ) ;
return false ;
}
2011-03-24 21:19:54 +00:00
if ( var_sp - > m_live_sp - > GetValue ( ) . GetValueAddressType ( ) ! = eAddressTypeLoad )
2011-01-13 08:53:35 +00:00
{
err . SetErrorStringWithFormat ( " The address of the memory area for %s is in an incorrect format " , var_sp - > GetName ( ) . GetCString ( ) ) ;
return false ;
}
2011-01-13 21:23:32 +00:00
if ( var_sp - > m_flags & ClangExpressionVariable : : EVNeedsFreezeDry | |
var_sp - > m_flags & ClangExpressionVariable : : EVKeepInTarget )
2011-01-13 08:53:35 +00:00
{
mem = var_sp - > m_live_sp - > GetValue ( ) . GetScalar ( ) . ULongLong ( ) ;
if ( log )
2012-11-29 21:49:15 +00:00
log - > Printf ( " Dematerializing %s from 0x% " PRIx64 " (size = %u) " , var_sp - > GetName ( ) . GetCString ( ) , ( uint64_t ) mem , ( unsigned ) pvar_byte_size ) ;
2011-01-13 08:53:35 +00:00
// Read the contents of the spare memory area
2011-05-09 22:04:36 +00:00
2011-01-13 08:53:35 +00:00
var_sp - > ValueUpdated ( ) ;
2011-09-22 04:58:26 +00:00
if ( process - > ReadMemory ( mem , pvar_data , pvar_byte_size , error ) ! = pvar_byte_size )
2011-01-13 08:53:35 +00:00
{
err . SetErrorStringWithFormat ( " Couldn't read a composite type from the target: %s " , error . AsCString ( ) ) ;
return false ;
}
2011-05-09 22:04:36 +00:00
if ( stack_frame_top ! = LLDB_INVALID_ADDRESS & &
stack_frame_bottom ! = LLDB_INVALID_ADDRESS & &
mem > = stack_frame_bottom & &
mem < = stack_frame_top )
{
// If the variable is resident in the stack frame created by the expression,
// then it cannot be relied upon to stay around. We treat it as needing
// reallocation.
var_sp - > m_flags | = ClangExpressionVariable : : EVIsLLDBAllocated ;
var_sp - > m_flags | = ClangExpressionVariable : : EVNeedsAllocation ;
var_sp - > m_flags & = ~ ClangExpressionVariable : : EVIsProgramReference ;
}
2011-01-13 08:53:35 +00:00
var_sp - > m_flags & = ~ ClangExpressionVariable : : EVNeedsFreezeDry ;
}
if ( var_sp - > m_flags & ClangExpressionVariable : : EVNeedsAllocation & &
! ( var_sp - > m_flags & ClangExpressionVariable : : EVKeepInTarget ) )
{
if ( m_keep_result_in_memory )
{
var_sp - > m_flags | = ClangExpressionVariable : : EVKeepInTarget ;
}
else
{
2011-09-22 04:58:26 +00:00
Error deallocate_error = process - > DeallocateMemory ( mem ) ;
2011-01-13 08:53:35 +00:00
if ( ! err . Success ( ) )
{
err . SetErrorStringWithFormat ( " Couldn't deallocate memory for %s: %s " , var_sp - > GetName ( ) . GetCString ( ) , deallocate_error . AsCString ( ) ) ;
return false ;
}
}
}
}
else
{
err . SetErrorStringWithFormat ( " Persistent variables without separate allocations are not currently supported. " ) ;
2010-08-11 03:57:18 +00:00
return false ;
}
}
else
{
2011-01-13 08:53:35 +00:00
if ( log )
log - > Printf ( " Materializing persistent variable with flags 0x%hx " , var_sp - > m_flags ) ;
if ( var_sp - > m_flags & ClangExpressionVariable : : EVNeedsAllocation )
2010-08-11 03:57:18 +00:00
{
2011-01-13 08:53:35 +00:00
// Allocate a spare memory area to store the persistent variable's contents.
Error allocate_error ;
2011-09-22 04:58:26 +00:00
mem = process - > AllocateMemory ( pvar_byte_size ,
2011-10-26 21:20:00 +00:00
lldb : : ePermissionsReadable | lldb : : ePermissionsWritable ,
allocate_error ) ;
2011-01-13 08:53:35 +00:00
if ( mem = = LLDB_INVALID_ADDRESS )
{
err . SetErrorStringWithFormat ( " Couldn't allocate a memory area to store %s: %s " , var_sp - > GetName ( ) . GetCString ( ) , allocate_error . AsCString ( ) ) ;
return false ;
}
if ( log )
2012-11-29 21:49:15 +00:00
log - > Printf ( " Allocated %s (0x% " PRIx64 " ) sucessfully " , var_sp - > GetName ( ) . GetCString ( ) , mem ) ;
2011-01-13 08:53:35 +00:00
// Put the location of the spare memory into the live data of the ValueObject.
2012-02-10 01:22:05 +00:00
var_sp - > m_live_sp = ValueObjectConstResult : : Create ( m_parser_vars - > m_exe_ctx . GetBestExecutionContextScope ( ) ,
2011-04-22 23:53:53 +00:00
var_sp - > GetTypeFromUser ( ) . GetASTContext ( ) ,
var_sp - > GetTypeFromUser ( ) . GetOpaqueQualType ( ) ,
var_sp - > GetName ( ) ,
mem ,
eAddressTypeLoad ,
pvar_byte_size ) ;
2011-01-13 08:53:35 +00:00
// Clear the flag if the variable will never be deallocated.
if ( var_sp - > m_flags & ClangExpressionVariable : : EVKeepInTarget )
var_sp - > m_flags & = ~ ClangExpressionVariable : : EVNeedsAllocation ;
// Write the contents of the variable to the area.
2011-09-22 04:58:26 +00:00
if ( process - > WriteMemory ( mem , pvar_data , pvar_byte_size , error ) ! = pvar_byte_size )
2011-01-13 08:53:35 +00:00
{
err . SetErrorStringWithFormat ( " Couldn't write a composite type to the target: %s " , error . AsCString ( ) ) ;
return false ;
}
}
if ( ( var_sp - > m_flags & ClangExpressionVariable : : EVIsProgramReference & & var_sp - > m_live_sp ) | |
var_sp - > m_flags & ClangExpressionVariable : : EVIsLLDBAllocated )
{
// Now write the location of the area into the struct.
Error write_error ;
2011-09-22 04:58:26 +00:00
if ( ! process - > WriteScalarToMemory ( addr ,
2011-10-26 21:20:00 +00:00
var_sp - > m_live_sp - > GetValue ( ) . GetScalar ( ) ,
process - > GetAddressByteSize ( ) ,
write_error ) )
2011-01-13 08:53:35 +00:00
{
err . SetErrorStringWithFormat ( " Couldn't write %s to the target: %s " , var_sp - > GetName ( ) . GetCString ( ) , write_error . AsCString ( ) ) ;
return false ;
}
if ( log )
2011-05-22 22:46:53 +00:00
log - > Printf ( " Materialized %s into 0x%llx " , var_sp - > GetName ( ) . GetCString ( ) , var_sp - > m_live_sp - > GetValue ( ) . GetScalar ( ) . ULongLong ( ) ) ;
2011-01-13 08:53:35 +00:00
}
2011-05-07 01:06:41 +00:00
else if ( ! ( var_sp - > m_flags & ClangExpressionVariable : : EVIsProgramReference ) )
2011-01-13 08:53:35 +00:00
{
err . SetErrorStringWithFormat ( " Persistent variables without separate allocations are not currently supported. " ) ;
2010-08-11 03:57:18 +00:00
return false ;
}
}
return true ;
}
2010-07-20 23:31:16 +00:00
bool
2010-10-15 22:48:33 +00:00
ClangExpressionDeclMap : : DoMaterializeOneVariable
(
bool dematerialize ,
const SymbolContext & sym_ctx ,
2011-01-13 08:53:35 +00:00
ClangExpressionVariableSP & expr_var ,
2010-10-15 22:48:33 +00:00
lldb : : addr_t addr ,
Error & err
)
2010-07-20 23:31:16 +00:00
{
2010-11-06 01:53:30 +00:00
lldb : : LogSP log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_EXPRESSIONS ) ) ;
2012-02-10 01:22:05 +00:00
Target * target = m_parser_vars - > m_exe_ctx . GetTargetPtr ( ) ;
Process * process = m_parser_vars - > m_exe_ctx . GetProcessPtr ( ) ;
StackFrame * frame = m_parser_vars - > m_exe_ctx . GetFramePtr ( ) ;
2011-09-22 04:58:26 +00:00
2011-10-12 22:20:02 +00:00
if ( ! frame | | ! process | | ! target | | ! m_parser_vars . get ( ) | | ! expr_var - > m_parser_vars . get ( ) )
2011-11-18 03:28:09 +00:00
{
err . SetErrorString ( " Necessary state for variable materialization isn't present " ) ;
2010-09-14 21:59:34 +00:00
return false ;
2011-11-18 03:28:09 +00:00
}
2010-09-14 21:59:34 +00:00
2011-01-13 08:53:35 +00:00
// Vital information about the value
const ConstString & name ( expr_var - > GetName ( ) ) ;
TypeFromUser type ( expr_var - > GetTypeFromUser ( ) ) ;
2011-10-13 00:09:20 +00:00
VariableSP & var ( expr_var - > m_parser_vars - > m_lldb_var ) ;
2012-11-27 01:52:16 +00:00
const lldb_private : : Symbol * symbol = expr_var - > m_parser_vars - > m_lldb_sym ;
2010-07-20 23:31:16 +00:00
2011-10-27 19:41:13 +00:00
bool is_reference ( expr_var - > m_flags & ClangExpressionVariable : : EVTypeIsReference ) ;
2011-05-08 02:21:26 +00:00
std : : auto_ptr < lldb_private : : Value > location_value ;
2011-10-13 00:09:20 +00:00
2011-05-08 02:21:26 +00:00
if ( var )
{
2012-02-10 01:22:05 +00:00
location_value . reset ( GetVariableValue ( var ,
2011-05-08 02:21:26 +00:00
NULL ) ) ;
}
2012-11-27 01:52:16 +00:00
else if ( symbol )
2011-10-13 00:09:20 +00:00
{
2012-11-15 02:02:04 +00:00
addr_t location_load_addr = GetSymbolAddress ( * target , process , name , lldb : : eSymbolTypeAny ) ;
2011-05-08 02:21:26 +00:00
2011-06-23 04:25:29 +00:00
if ( location_load_addr = = LLDB_INVALID_ADDRESS )
2011-05-08 02:21:26 +00:00
{
if ( log )
2011-05-22 22:46:53 +00:00
err . SetErrorStringWithFormat ( " Couldn't find value for global symbol %s " ,
name . GetCString ( ) ) ;
2011-05-08 02:21:26 +00:00
}
2011-10-13 00:09:20 +00:00
location_value . reset ( new Value ) ;
2011-05-08 02:21:26 +00:00
location_value - > SetValueType ( Value : : eValueTypeLoadAddress ) ;
location_value - > GetScalar ( ) = location_load_addr ;
}
else
2010-07-20 23:31:16 +00:00
{
2011-05-22 22:46:53 +00:00
err . SetErrorStringWithFormat ( " Couldn't find %s with appropriate type " ,
name . GetCString ( ) ) ;
2010-07-20 23:31:16 +00:00
return false ;
}
2010-07-23 00:16:21 +00:00
if ( log )
2011-05-12 23:54:16 +00:00
{
StreamString my_stream_string ;
ClangASTType : : DumpTypeDescription ( type . GetASTContext ( ) ,
type . GetOpaqueQualType ( ) ,
& my_stream_string ) ;
2011-05-22 22:46:53 +00:00
log - > Printf ( " %s %s with type %s " ,
dematerialize ? " Dematerializing " : " Materializing " ,
name . GetCString ( ) ,
my_stream_string . GetString ( ) . c_str ( ) ) ;
2011-05-12 23:54:16 +00:00
}
2010-07-20 23:31:16 +00:00
if ( ! location_value . get ( ) )
{
2010-10-15 22:48:33 +00:00
err . SetErrorStringWithFormat ( " Couldn't get value for %s " , name . GetCString ( ) ) ;
2010-07-20 23:31:16 +00:00
return false ;
}
2010-10-05 20:18:48 +00:00
// The size of the type contained in addr
2010-07-20 23:31:16 +00:00
2011-01-13 08:53:35 +00:00
size_t value_bit_size = ClangASTType : : GetClangTypeBitWidth ( type . GetASTContext ( ) , type . GetOpaqueQualType ( ) ) ;
size_t value_byte_size = value_bit_size % 8 ? ( ( value_bit_size + 8 ) / 8 ) : ( value_bit_size / 8 ) ;
2010-10-05 20:18:48 +00:00
Value : : ValueType value_type = location_value - > GetValueType ( ) ;
switch ( value_type )
2010-07-20 23:31:16 +00:00
{
2010-10-05 20:18:48 +00:00
default :
2010-07-20 23:31:16 +00:00
{
2010-10-05 20:18:48 +00:00
StreamString ss ;
location_value - > Dump ( & ss ) ;
2011-05-22 22:46:53 +00:00
err . SetErrorStringWithFormat ( " %s has a value of unhandled type: %s " ,
name . GetCString ( ) ,
ss . GetString ( ) . c_str ( ) ) ;
2010-07-20 23:31:16 +00:00
return false ;
}
2010-10-05 20:18:48 +00:00
break ;
case Value : : eValueTypeLoadAddress :
2010-07-20 23:31:16 +00:00
{
2011-01-13 08:53:35 +00:00
if ( ! dematerialize )
2010-10-05 20:18:48 +00:00
{
2011-05-22 22:46:53 +00:00
Error write_error ;
2011-01-13 08:53:35 +00:00
2011-10-27 19:41:13 +00:00
if ( is_reference )
2011-01-13 08:53:35 +00:00
{
2011-10-27 19:41:13 +00:00
Error read_error ;
addr_t ref_value = process - > ReadPointerFromMemory ( location_value - > GetScalar ( ) . ULongLong ( ) , read_error ) ;
if ( ! read_error . Success ( ) )
{
err . SetErrorStringWithFormat ( " Couldn't read reference to %s from the target: %s " ,
name . GetCString ( ) ,
read_error . AsCString ( ) ) ;
return false ;
}
if ( ! process - > WritePointerToMemory ( addr ,
ref_value ,
write_error ) )
{
err . SetErrorStringWithFormat ( " Couldn't write %s to the target: %s " ,
name . GetCString ( ) ,
write_error . AsCString ( ) ) ;
return false ;
}
}
else
{
if ( ! process - > WriteScalarToMemory ( addr ,
location_value - > GetScalar ( ) ,
process - > GetAddressByteSize ( ) ,
write_error ) )
{
err . SetErrorStringWithFormat ( " Couldn't write %s to the target: %s " ,
name . GetCString ( ) ,
write_error . AsCString ( ) ) ;
return false ;
}
2011-01-13 08:53:35 +00:00
}
2010-10-05 20:18:48 +00:00
}
}
break ;
case Value : : eValueTypeScalar :
{
2010-11-13 03:52:47 +00:00
if ( location_value - > GetContextType ( ) ! = Value : : eContextTypeRegisterInfo )
2010-10-05 20:18:48 +00:00
{
StreamString ss ;
location_value - > Dump ( & ss ) ;
2011-05-22 22:46:53 +00:00
err . SetErrorStringWithFormat ( " %s is a scalar of unhandled type: %s " ,
name . GetCString ( ) ,
ss . GetString ( ) . c_str ( ) ) ;
2010-10-05 20:18:48 +00:00
return false ;
}
2011-05-09 20:18:18 +00:00
RegisterInfo * reg_info = location_value - > GetRegisterInfo ( ) ;
2010-10-05 20:18:48 +00:00
2011-05-09 20:18:18 +00:00
if ( ! reg_info )
2010-10-05 20:18:48 +00:00
{
2011-05-22 22:46:53 +00:00
err . SetErrorStringWithFormat ( " Couldn't get the register information for %s " ,
name . GetCString ( ) ) ;
2010-10-05 20:18:48 +00:00
return false ;
}
2011-05-09 20:18:18 +00:00
RegisterValue reg_value ;
2012-02-10 01:22:05 +00:00
RegisterContext * reg_ctx = m_parser_vars - > m_exe_ctx . GetRegisterContext ( ) ;
2011-05-09 20:18:18 +00:00
if ( ! reg_ctx )
2010-10-05 20:18:48 +00:00
{
2011-05-22 22:46:53 +00:00
err . SetErrorStringWithFormat ( " Couldn't read register context to read %s from %s " ,
name . GetCString ( ) ,
reg_info - > name ) ;
2010-10-05 20:18:48 +00:00
return false ;
}
2011-05-09 20:18:18 +00:00
uint32_t register_byte_size = reg_info - > byte_size ;
2010-10-05 20:18:48 +00:00
if ( dematerialize )
{
2011-10-27 19:41:13 +00:00
if ( is_reference )
return true ; // reference types don't need demateralizing
2011-01-13 08:53:35 +00:00
// Get the location of the spare memory area out of the variable's live data.
if ( ! expr_var - > m_live_sp )
{
err . SetErrorStringWithFormat ( " Couldn't find the memory area used to store %s " , name . GetCString ( ) ) ;
return false ;
}
2011-03-24 21:19:54 +00:00
if ( expr_var - > m_live_sp - > GetValue ( ) . GetValueAddressType ( ) ! = eAddressTypeLoad )
2011-01-13 08:53:35 +00:00
{
err . SetErrorStringWithFormat ( " The address of the memory area for %s is in an incorrect format " , name . GetCString ( ) ) ;
return false ;
}
2011-05-22 22:46:53 +00:00
Scalar & reg_addr = expr_var - > m_live_sp - > GetValue ( ) . GetScalar ( ) ;
2011-01-13 08:53:35 +00:00
2011-05-22 22:46:53 +00:00
err = reg_ctx - > ReadRegisterValueFromMemory ( reg_info ,
reg_addr . ULongLong ( ) ,
value_byte_size ,
reg_value ) ;
2011-05-09 20:18:18 +00:00
if ( err . Fail ( ) )
2010-10-05 20:18:48 +00:00
return false ;
2011-05-09 20:18:18 +00:00
if ( ! reg_ctx - > WriteRegister ( reg_info , reg_value ) )
2010-10-05 20:18:48 +00:00
{
2011-05-22 22:46:53 +00:00
err . SetErrorStringWithFormat ( " Couldn't write %s to register %s " ,
name . GetCString ( ) ,
reg_info - > name ) ;
2010-10-05 20:18:48 +00:00
return false ;
}
2011-01-13 08:53:35 +00:00
// Deallocate the spare area and clear the variable's live data.
2011-09-22 04:58:26 +00:00
Error deallocate_error = process - > DeallocateMemory ( reg_addr . ULongLong ( ) ) ;
2011-01-13 08:53:35 +00:00
if ( ! deallocate_error . Success ( ) )
{
2011-05-22 22:46:53 +00:00
err . SetErrorStringWithFormat ( " Couldn't deallocate spare memory area for %s: %s " ,
name . GetCString ( ) ,
deallocate_error . AsCString ( ) ) ;
2011-01-13 08:53:35 +00:00
return false ;
}
expr_var - > m_live_sp . reset ( ) ;
2010-10-05 20:18:48 +00:00
}
else
{
2011-10-27 19:41:13 +00:00
Error write_error ;
RegisterValue reg_value ;
if ( ! reg_ctx - > ReadRegister ( reg_info , reg_value ) )
{
err . SetErrorStringWithFormat ( " Couldn't read %s from %s " ,
name . GetCString ( ) ,
reg_info - > name ) ;
return false ;
}
if ( is_reference )
{
write_error = reg_ctx - > WriteRegisterValueToMemory ( reg_info ,
addr ,
process - > GetAddressByteSize ( ) ,
reg_value ) ;
if ( ! write_error . Success ( ) )
{
err . SetErrorStringWithFormat ( " Couldn't write %s from register %s to the target: %s " ,
name . GetCString ( ) ,
reg_info - > name ,
write_error . AsCString ( ) ) ;
return false ;
}
return true ;
}
2011-01-13 08:53:35 +00:00
// Allocate a spare memory area to place the register's contents into. This memory area will be pointed to by the slot in the
// struct.
Error allocate_error ;
2011-09-22 04:58:26 +00:00
Scalar reg_addr ( process - > AllocateMemory ( value_byte_size ,
2011-10-27 19:41:13 +00:00
lldb : : ePermissionsReadable | lldb : : ePermissionsWritable ,
allocate_error ) ) ;
2011-01-13 08:53:35 +00:00
2011-05-22 22:46:53 +00:00
if ( reg_addr . ULongLong ( ) = = LLDB_INVALID_ADDRESS )
2011-01-13 08:53:35 +00:00
{
2011-05-22 22:46:53 +00:00
err . SetErrorStringWithFormat ( " Couldn't allocate a memory area to store %s: %s " ,
name . GetCString ( ) ,
allocate_error . AsCString ( ) ) ;
2011-01-13 08:53:35 +00:00
return false ;
}
// Put the location of the spare memory into the live data of the ValueObject.
2012-02-10 01:22:05 +00:00
expr_var - > m_live_sp = ValueObjectConstResult : : Create ( m_parser_vars - > m_exe_ctx . GetBestExecutionContextScope ( ) ,
2011-04-22 23:53:53 +00:00
type . GetASTContext ( ) ,
type . GetOpaqueQualType ( ) ,
name ,
2011-05-22 22:46:53 +00:00
reg_addr . ULongLong ( ) ,
2011-04-22 23:53:53 +00:00
eAddressTypeLoad ,
value_byte_size ) ;
2011-01-13 08:53:35 +00:00
// Now write the location of the area into the struct.
2011-10-27 19:41:13 +00:00
2011-09-22 04:58:26 +00:00
if ( ! process - > WriteScalarToMemory ( addr ,
2011-10-27 19:41:13 +00:00
reg_addr ,
process - > GetAddressByteSize ( ) ,
write_error ) )
2011-01-13 08:53:35 +00:00
{
2011-05-22 22:46:53 +00:00
err . SetErrorStringWithFormat ( " Couldn't write %s to the target: %s " ,
name . GetCString ( ) ,
write_error . AsCString ( ) ) ;
2011-01-13 08:53:35 +00:00
return false ;
}
if ( value_byte_size > register_byte_size )
2010-10-05 20:18:48 +00:00
{
2011-05-22 22:46:53 +00:00
err . SetErrorStringWithFormat ( " %s is too big to store in %s " ,
name . GetCString ( ) ,
reg_info - > name ) ;
2010-10-05 20:18:48 +00:00
return false ;
}
2011-05-09 20:18:18 +00:00
if ( ! reg_ctx - > ReadRegister ( reg_info , reg_value ) )
2010-10-05 20:18:48 +00:00
{
2011-05-22 22:46:53 +00:00
err . SetErrorStringWithFormat ( " Couldn't read %s from %s " ,
name . GetCString ( ) ,
reg_info - > name ) ;
2010-10-05 20:18:48 +00:00
return false ;
}
2011-05-22 22:46:53 +00:00
err = reg_ctx - > WriteRegisterValueToMemory ( reg_info ,
reg_addr . ULongLong ( ) ,
value_byte_size ,
reg_value ) ;
2011-05-09 20:18:18 +00:00
if ( err . Fail ( ) )
2010-10-05 20:18:48 +00:00
return false ;
}
2010-07-20 23:31:16 +00:00
}
}
return true ;
2010-07-16 00:09:46 +00:00
}
2010-11-30 00:27:43 +00:00
bool
ClangExpressionDeclMap : : DoMaterializeOneRegister
(
bool dematerialize ,
RegisterContext & reg_ctx ,
2011-03-24 21:19:54 +00:00
const RegisterInfo & reg_info ,
2010-11-30 00:27:43 +00:00
lldb : : addr_t addr ,
Error & err
)
{
uint32_t register_byte_size = reg_info . byte_size ;
2011-05-09 20:18:18 +00:00
RegisterValue reg_value ;
2010-11-30 00:27:43 +00:00
if ( dematerialize )
{
2011-05-09 20:18:18 +00:00
Error read_error ( reg_ctx . ReadRegisterValueFromMemory ( & reg_info , addr , register_byte_size , reg_value ) ) ;
if ( read_error . Fail ( ) )
2010-11-30 00:27:43 +00:00
{
2011-01-25 23:55:37 +00:00
err . SetErrorStringWithFormat ( " Couldn't read %s from the target: %s " , reg_info . name , read_error . AsCString ( ) ) ;
2010-11-30 00:27:43 +00:00
return false ;
}
2011-05-09 20:18:18 +00:00
if ( ! reg_ctx . WriteRegister ( & reg_info , reg_value ) )
2010-11-30 00:27:43 +00:00
{
2011-05-09 20:18:18 +00:00
err . SetErrorStringWithFormat ( " Couldn't write register %s (dematerialize) " , reg_info . name ) ;
2010-11-30 00:27:43 +00:00
return false ;
}
}
else
{
2011-05-09 20:18:18 +00:00
if ( ! reg_ctx . ReadRegister ( & reg_info , reg_value ) )
2010-11-30 00:27:43 +00:00
{
2011-05-09 20:18:18 +00:00
err . SetErrorStringWithFormat ( " Couldn't read %s (materialize) " , reg_info . name ) ;
2010-11-30 00:27:43 +00:00
return false ;
}
2011-05-09 20:18:18 +00:00
Error write_error ( reg_ctx . WriteRegisterValueToMemory ( & reg_info , addr , register_byte_size , reg_value ) ) ;
if ( write_error . Fail ( ) )
2010-11-30 00:27:43 +00:00
{
2011-09-20 00:26:08 +00:00
err . SetErrorStringWithFormat ( " Couldn't write %s to the target: %s " , reg_info . name , write_error . AsCString ( ) ) ;
2010-11-30 00:27:43 +00:00
return false ;
}
}
return true ;
}
2011-05-07 01:06:41 +00:00
lldb : : VariableSP
2010-10-15 22:48:33 +00:00
ClangExpressionDeclMap : : FindVariableInScope
(
StackFrame & frame ,
const ConstString & name ,
2012-02-18 02:01:03 +00:00
TypeFromUser * type ,
2012-05-21 21:29:52 +00:00
bool object_pointer
2010-10-15 22:48:33 +00:00
)
2010-12-03 01:38:59 +00:00
{
2010-11-06 01:53:30 +00:00
lldb : : LogSP log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_EXPRESSIONS ) ) ;
2010-09-14 21:59:34 +00:00
2011-08-06 00:28:14 +00:00
ValueObjectSP valobj ;
VariableSP var_sp ;
Error err ;
2010-09-14 21:59:34 +00:00
2011-08-06 00:28:14 +00:00
valobj = frame . GetValueForVariableExpressionPath ( name . GetCString ( ) ,
eNoDynamicValues ,
StackFrame : : eExpressionPathOptionCheckPtrVsMember ,
var_sp ,
err ) ;
2010-11-14 22:13:40 +00:00
2011-08-06 00:28:14 +00:00
if ( ! err . Success ( ) | |
! var_sp | |
2011-07-07 23:05:43 +00:00
! var_sp - > IsInScope ( & frame ) | |
! var_sp - > LocationIsValidForFrame ( & frame ) )
return lldb : : VariableSP ( ) ;
2010-11-14 22:13:40 +00:00
2012-05-21 22:25:52 +00:00
if ( var_sp )
2010-11-14 22:13:40 +00:00
{
2012-05-21 22:25:52 +00:00
if ( ! type )
return var_sp ;
2012-05-21 21:29:52 +00:00
TypeFromUser candidate_type ( var_sp - > GetType ( ) - > GetClangFullType ( ) ,
var_sp - > GetType ( ) - > GetClangAST ( ) ) ;
if ( candidate_type . GetASTContext ( ) ! = type - > GetASTContext ( ) )
2010-11-14 22:13:40 +00:00
{
if ( log )
log - > PutCString ( " Skipping a candidate variable because of different AST contexts " ) ;
2011-05-07 01:06:41 +00:00
return lldb : : VariableSP ( ) ;
2010-11-14 22:13:40 +00:00
}
2012-05-21 21:29:52 +00:00
if ( object_pointer )
{
clang : : QualType desired_qual_type = clang : : QualType : : getFromOpaquePtr ( type - > GetOpaqueQualType ( ) ) ;
clang : : QualType candidate_qual_type = clang : : QualType : : getFromOpaquePtr ( candidate_type . GetOpaqueQualType ( ) ) ;
2012-05-21 22:25:52 +00:00
const clang : : ObjCObjectPointerType * desired_objc_ptr_type = desired_qual_type - > getAs < clang : : ObjCObjectPointerType > ( ) ;
const clang : : ObjCObjectPointerType * candidate_objc_ptr_type = desired_qual_type - > getAs < clang : : ObjCObjectPointerType > ( ) ;
if ( desired_objc_ptr_type & & candidate_objc_ptr_type ) {
clang : : QualType desired_target_type = desired_objc_ptr_type - > getPointeeType ( ) . getUnqualifiedType ( ) ;
clang : : QualType candidate_target_type = candidate_objc_ptr_type - > getPointeeType ( ) . getUnqualifiedType ( ) ;
if ( ClangASTContext : : AreTypesSame ( type - > GetASTContext ( ) ,
desired_target_type . getAsOpaquePtr ( ) ,
candidate_target_type . getAsOpaquePtr ( ) ) )
return var_sp ;
}
2012-05-21 21:29:52 +00:00
const clang : : PointerType * desired_ptr_type = desired_qual_type - > getAs < clang : : PointerType > ( ) ;
const clang : : PointerType * candidate_ptr_type = candidate_qual_type - > getAs < clang : : PointerType > ( ) ;
2012-05-21 22:25:52 +00:00
if ( desired_ptr_type & & candidate_ptr_type ) {
clang : : QualType desired_target_type = desired_ptr_type - > getPointeeType ( ) . getUnqualifiedType ( ) ;
clang : : QualType candidate_target_type = candidate_ptr_type - > getPointeeType ( ) . getUnqualifiedType ( ) ;
if ( ClangASTContext : : AreTypesSame ( type - > GetASTContext ( ) ,
desired_target_type . getAsOpaquePtr ( ) ,
candidate_target_type . getAsOpaquePtr ( ) ) )
return var_sp ;
}
2012-05-21 21:29:52 +00:00
2012-05-21 22:25:52 +00:00
return lldb : : VariableSP ( ) ;
2012-05-21 21:29:52 +00:00
}
else
{
2012-05-21 22:25:52 +00:00
if ( ClangASTContext : : AreTypesSame ( type - > GetASTContext ( ) ,
2012-05-21 21:29:52 +00:00
type - > GetOpaqueQualType ( ) ,
var_sp - > GetType ( ) - > GetClangFullType ( ) ) )
2012-05-21 22:25:52 +00:00
return var_sp ;
2012-05-21 21:29:52 +00:00
}
2010-09-14 21:59:34 +00:00
}
2010-11-14 22:13:40 +00:00
2012-05-21 22:25:52 +00:00
return lldb : : VariableSP ( ) ;
2010-09-14 21:59:34 +00:00
}
2010-07-17 00:43:37 +00:00
2012-11-27 01:52:16 +00:00
const Symbol *
ClangExpressionDeclMap : : FindGlobalDataSymbol ( Target & target ,
const ConstString & name )
2011-05-08 02:21:26 +00:00
{
SymbolContextList sc_list ;
2012-11-27 01:52:16 +00:00
target . GetImages ( ) . FindSymbolsWithNameAndType ( name , eSymbolTypeAny , sc_list ) ;
2011-05-08 02:21:26 +00:00
2012-11-27 01:52:16 +00:00
const uint32_t matches = sc_list . GetSize ( ) ;
for ( uint32_t i = 0 ; i < matches ; + + i )
2011-05-08 02:21:26 +00:00
{
SymbolContext sym_ctx ;
2012-11-27 01:52:16 +00:00
sc_list . GetContextAtIndex ( i , sym_ctx ) ;
if ( sym_ctx . symbol )
{
const Symbol * symbol = sym_ctx . symbol ;
const Address * sym_address = & symbol - > GetAddress ( ) ;
if ( sym_address & & sym_address - > IsValid ( ) )
{
switch ( symbol - > GetType ( ) )
{
case eSymbolTypeData :
case eSymbolTypeRuntime :
case eSymbolTypeAbsolute :
case eSymbolTypeObjCClass :
case eSymbolTypeObjCMetaClass :
case eSymbolTypeObjCIVar :
if ( symbol - > GetDemangledNameIsSynthesized ( ) )
{
// If the demangled name was synthesized, then don't use it
// for expressions. Only let the symbol match if the mangled
// named matches for these symbols.
if ( symbol - > GetMangled ( ) . GetMangledName ( ) ! = name )
break ;
}
return symbol ;
case eSymbolTypeCode : // We already lookup functions elsewhere
case eSymbolTypeVariable :
case eSymbolTypeLocal :
case eSymbolTypeParam :
case eSymbolTypeTrampoline :
case eSymbolTypeInvalid :
case eSymbolTypeException :
case eSymbolTypeSourceFile :
case eSymbolTypeHeaderFile :
case eSymbolTypeObjectFile :
case eSymbolTypeCommonBlock :
case eSymbolTypeBlock :
case eSymbolTypeVariableType :
case eSymbolTypeLineEntry :
case eSymbolTypeLineHeader :
case eSymbolTypeScopeBegin :
case eSymbolTypeScopeEnd :
case eSymbolTypeAdditional :
case eSymbolTypeCompiler :
case eSymbolTypeInstrumentation :
case eSymbolTypeUndefined :
break ;
}
}
}
2011-05-08 02:21:26 +00:00
}
return NULL ;
}
2011-09-15 02:13:07 +00:00
lldb : : VariableSP
ClangExpressionDeclMap : : FindGlobalVariable
(
Target & target ,
2011-10-12 16:59:31 +00:00
ModuleSP & module ,
const ConstString & name ,
ClangNamespaceDecl * namespace_decl ,
2011-09-15 02:13:07 +00:00
TypeFromUser * type
)
{
VariableList vars ;
2011-10-12 16:59:31 +00:00
if ( module & & namespace_decl )
module - > FindGlobalVariables ( name , namespace_decl , true , - 1 , vars ) ;
else
target . GetImages ( ) . FindGlobalVariables ( name , true , - 1 , vars ) ;
2011-09-15 02:13:07 +00:00
if ( vars . GetSize ( ) )
{
if ( type )
{
for ( size_t i = 0 ; i < vars . GetSize ( ) ; + + i )
{
VariableSP var_sp = vars . GetVariableAtIndex ( i ) ;
if ( type - > GetASTContext ( ) = = var_sp - > GetType ( ) - > GetClangAST ( ) )
{
if ( ClangASTContext : : AreTypesSame ( type - > GetASTContext ( ) , type - > GetOpaqueQualType ( ) , var_sp - > GetType ( ) - > GetClangFullType ( ) ) )
return var_sp ;
}
}
}
else
{
return vars . GetVariableAtIndex ( 0 ) ;
}
}
return VariableSP ( ) ;
}
2010-06-08 16:52:24 +00:00
// Interface for ClangASTSource
2011-09-15 02:13:07 +00:00
2011-10-12 00:12:34 +00:00
void
2011-10-28 23:38:38 +00:00
ClangExpressionDeclMap : : FindExternalVisibleDecls ( NameSearchContext & context )
2010-06-08 16:52:24 +00:00
{
2011-10-28 23:38:38 +00:00
assert ( m_ast_context ) ;
const ConstString name ( context . m_decl_name . getAsString ( ) . c_str ( ) ) ;
2010-11-06 01:53:30 +00:00
lldb : : LogSP log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_EXPRESSIONS ) ) ;
2010-06-08 16:52:24 +00:00
2011-10-29 19:50:43 +00:00
if ( GetImportInProgress ( ) )
2010-11-19 20:20:02 +00:00
{
2011-10-14 20:34:21 +00:00
if ( log & & log - > GetVerbose ( ) )
2010-11-19 20:20:02 +00:00
log - > Printf ( " Ignoring a query during an import " ) ;
return ;
}
2011-06-25 00:44:06 +00:00
2011-10-14 20:34:21 +00:00
static unsigned int invocation_id = 0 ;
unsigned int current_id = invocation_id + + ;
2011-10-12 00:12:34 +00:00
if ( log )
{
if ( ! context . m_decl_context )
2011-10-29 19:50:43 +00:00
log - > Printf ( " ClangExpressionDeclMap::FindExternalVisibleDecls[%u] for '%s' in a NULL DeclContext " , current_id , name . GetCString ( ) ) ;
2011-10-12 00:12:34 +00:00
else if ( const NamedDecl * context_named_decl = dyn_cast < NamedDecl > ( context . m_decl_context ) )
2011-10-29 19:50:43 +00:00
log - > Printf ( " ClangExpressionDeclMap::FindExternalVisibleDecls[%u] for '%s' in '%s' " , current_id , name . GetCString ( ) , context_named_decl - > getNameAsString ( ) . c_str ( ) ) ;
2011-10-12 00:12:34 +00:00
else
2011-10-29 19:50:43 +00:00
log - > Printf ( " ClangExpressionDeclMap::FindExternalVisibleDecls[%u] for '%s' in a '%s' " , current_id , name . GetCString ( ) , context . m_decl_context - > getDeclKindName ( ) ) ;
2011-10-12 00:12:34 +00:00
}
2011-10-29 19:50:43 +00:00
2011-10-12 00:12:34 +00:00
if ( const NamespaceDecl * namespace_context = dyn_cast < NamespaceDecl > ( context . m_decl_context ) )
{
2011-10-29 01:58:46 +00:00
ClangASTImporter : : NamespaceMapSP namespace_map = m_ast_importer - > GetNamespaceMap ( namespace_context ) ;
2011-10-13 21:08:11 +00:00
2011-10-14 20:34:21 +00:00
if ( log & & log - > GetVerbose ( ) )
2011-11-18 03:28:09 +00:00
log - > Printf ( " CEDM::FEVD[%u] Inspecting (NamespaceMap*)%p (%d entries) " ,
2011-10-14 20:34:21 +00:00
current_id ,
namespace_map . get ( ) ,
( int ) namespace_map - > size ( ) ) ;
2011-10-13 21:08:11 +00:00
2011-10-21 22:18:07 +00:00
if ( ! namespace_map )
return ;
2011-10-12 00:12:34 +00:00
for ( ClangASTImporter : : NamespaceMap : : iterator i = namespace_map - > begin ( ) , e = namespace_map - > end ( ) ;
i ! = e ;
+ + i )
{
if ( log )
2011-10-29 19:50:43 +00:00
log - > Printf ( " CEDM::FEVD[%u] Searching namespace %s in module %s " ,
2011-10-14 20:34:21 +00:00
current_id ,
2011-10-12 00:12:34 +00:00
i - > second . GetNamespaceDecl ( ) - > getNameAsString ( ) . c_str ( ) ,
i - > first - > GetFileSpec ( ) . GetFilename ( ) . GetCString ( ) ) ;
2011-10-13 21:50:33 +00:00
FindExternalVisibleDecls ( context ,
i - > first ,
i - > second ,
2011-10-14 20:34:21 +00:00
current_id ) ;
2011-10-12 00:12:34 +00:00
}
}
2011-11-15 02:11:17 +00:00
else if ( isa < TranslationUnitDecl > ( context . m_decl_context ) )
2011-10-12 00:12:34 +00:00
{
ClangNamespaceDecl namespace_decl ;
if ( log )
2011-10-29 19:50:43 +00:00
log - > Printf ( " CEDM::FEVD[%u] Searching the root namespace " , current_id ) ;
2011-10-12 00:12:34 +00:00
FindExternalVisibleDecls ( context ,
lldb : : ModuleSP ( ) ,
namespace_decl ,
2011-10-14 20:34:21 +00:00
current_id ) ;
2011-10-12 00:12:34 +00:00
}
2011-10-13 21:08:11 +00:00
2011-10-29 19:50:43 +00:00
if ( ! context . m_found . variable )
ClangASTSource : : FindExternalVisibleDecls ( context ) ;
2011-10-12 00:12:34 +00:00
}
void
ClangExpressionDeclMap : : FindExternalVisibleDecls ( NameSearchContext & context ,
2011-10-12 18:44:30 +00:00
lldb : : ModuleSP module_sp ,
2011-10-12 01:39:28 +00:00
ClangNamespaceDecl & namespace_decl ,
2011-10-14 20:34:21 +00:00
unsigned int current_id )
2011-10-12 00:12:34 +00:00
{
2011-10-28 23:38:38 +00:00
assert ( m_ast_context ) ;
2011-10-12 00:12:34 +00:00
lldb : : LogSP log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_EXPRESSIONS ) ) ;
2011-10-29 19:50:43 +00:00
2010-11-09 23:46:37 +00:00
SymbolContextList sc_list ;
2010-06-08 16:52:24 +00:00
2011-10-29 19:50:43 +00:00
const ConstString name ( context . m_decl_name . getAsString ( ) . c_str ( ) ) ;
2010-11-14 22:13:40 +00:00
const char * name_unique_cstr = name . GetCString ( ) ;
if ( name_unique_cstr = = NULL )
return ;
2011-10-29 19:50:43 +00:00
2012-02-04 08:49:35 +00:00
static ConstString id_name ( " id " ) ;
static ConstString Class_name ( " Class " ) ;
if ( name = = id_name | | name = = Class_name )
return ;
2010-10-15 22:48:33 +00:00
// Only look for functions by name out in our symbols if the function
// doesn't start with our phony prefix of '$'
2012-02-10 01:22:05 +00:00
Target * target = m_parser_vars - > m_exe_ctx . GetTargetPtr ( ) ;
StackFrame * frame = m_parser_vars - > m_exe_ctx . GetFramePtr ( ) ;
2011-10-12 01:39:28 +00:00
if ( name_unique_cstr [ 0 ] = = ' $ ' & & ! namespace_decl )
{
static ConstString g_lldb_class_name ( " $__lldb_class " ) ;
if ( name = = g_lldb_class_name )
{
// Clang is looking for the type of "this"
2012-02-08 03:45:08 +00:00
if ( frame = = NULL )
2011-10-12 01:39:28 +00:00
return ;
2012-02-08 03:45:08 +00:00
SymbolContext sym_ctx = frame - > GetSymbolContext ( lldb : : eSymbolContextFunction ) ;
2011-10-12 01:39:28 +00:00
2012-02-08 03:45:08 +00:00
if ( ! sym_ctx . function )
2011-10-12 01:39:28 +00:00
return ;
2012-07-14 00:53:55 +00:00
// Get the block that defines the function
Block * function_block = sym_ctx . GetFunctionBlock ( ) ;
if ( ! function_block )
return ;
clang : : DeclContext * decl_context = function_block - > GetClangDeclContext ( ) ;
2012-02-08 03:45:08 +00:00
if ( ! decl_context )
2011-10-12 01:39:28 +00:00
return ;
2012-02-08 03:45:08 +00:00
clang : : CXXMethodDecl * method_decl = llvm : : dyn_cast < clang : : CXXMethodDecl > ( decl_context ) ;
2011-10-12 01:39:28 +00:00
2012-10-30 23:35:54 +00:00
if ( method_decl )
2011-10-12 01:39:28 +00:00
{
2012-10-30 23:35:54 +00:00
clang : : CXXRecordDecl * class_decl = method_decl - > getParent ( ) ;
QualType class_qual_type ( class_decl - > getTypeForDecl ( ) , 0 ) ;
TypeFromUser class_user_type ( class_qual_type . getAsOpaquePtr ( ) ,
& class_decl - > getASTContext ( ) ) ;
if ( log )
{
ASTDumper ast_dumper ( class_qual_type ) ;
log - > Printf ( " CEDM::FEVD[%u] Adding type for $__lldb_class: %s " , current_id , ast_dumper . GetCString ( ) ) ;
}
AddOneType ( context , class_user_type , current_id , true ) ;
if ( method_decl - > isInstance ( ) )
{
// self is a pointer to the object
QualType class_pointer_type = method_decl - > getASTContext ( ) . getPointerType ( class_qual_type ) ;
TypeFromUser self_user_type ( class_pointer_type . getAsOpaquePtr ( ) ,
& method_decl - > getASTContext ( ) ) ;
m_struct_vars - > m_object_pointer_type = self_user_type ;
}
2011-10-12 01:39:28 +00:00
}
2012-10-30 23:35:54 +00:00
else
2012-03-05 22:08:20 +00:00
{
2012-10-30 23:35:54 +00:00
// This branch will get hit if we are executing code in the context of a function that
// claims to have an object pointer (through DW_AT_object_pointer?) but is not formally a
// method of the class. In that case, just look up the "this" variable in the the current
// scope and use its type.
// FIXME: This code is formally correct, but clang doesn't currently emit DW_AT_object_pointer
// for C++ so it hasn't actually been tested.
2012-03-05 22:08:20 +00:00
2012-10-30 23:35:54 +00:00
VariableList * vars = frame - > GetVariableList ( false ) ;
2012-03-05 22:08:20 +00:00
2012-10-30 23:35:54 +00:00
lldb : : VariableSP this_var = vars - > FindVariable ( ConstString ( " this " ) ) ;
2012-03-05 22:08:20 +00:00
2012-10-30 23:35:54 +00:00
if ( this_var & &
this_var - > IsInScope ( frame ) & &
this_var - > LocationIsValidForFrame ( frame ) )
{
Type * this_type = this_var - > GetType ( ) ;
if ( ! this_type )
return ;
QualType this_qual_type = QualType : : getFromOpaquePtr ( this_type - > GetClangFullType ( ) ) ;
const PointerType * class_pointer_type = this_qual_type - > getAs < PointerType > ( ) ;
if ( class_pointer_type )
{
QualType class_type = class_pointer_type - > getPointeeType ( ) ;
if ( log )
{
ASTDumper ast_dumper ( this_type - > GetClangFullType ( ) ) ;
log - > Printf ( " FEVD[%u] Adding type for $__lldb_objc_class: %s " , current_id , ast_dumper . GetCString ( ) ) ;
}
TypeFromUser class_user_type ( class_type . getAsOpaquePtr ( ) ,
this_type - > GetClangAST ( ) ) ;
AddOneType ( context , class_user_type , current_id , false ) ;
TypeFromUser this_user_type ( this_type - > GetClangFullType ( ) ,
this_type - > GetClangAST ( ) ) ;
m_struct_vars - > m_object_pointer_type = this_user_type ;
return ;
}
}
2012-03-05 22:08:20 +00:00
}
2011-10-12 01:39:28 +00:00
return ;
}
static ConstString g_lldb_objc_class_name ( " $__lldb_objc_class " ) ;
if ( name = = g_lldb_objc_class_name )
{
// Clang is looking for the type of "*self"
if ( ! frame )
return ;
2011-11-15 02:11:17 +00:00
SymbolContext sym_ctx = frame - > GetSymbolContext ( lldb : : eSymbolContextFunction ) ;
if ( ! sym_ctx . function )
return ;
2012-07-14 00:53:55 +00:00
// Get the block that defines the function
Block * function_block = sym_ctx . GetFunctionBlock ( ) ;
2011-11-15 02:11:17 +00:00
2012-07-14 00:53:55 +00:00
if ( ! function_block )
return ;
clang : : DeclContext * decl_context = function_block - > GetClangDeclContext ( ) ;
2011-11-15 02:11:17 +00:00
if ( ! decl_context )
return ;
clang : : ObjCMethodDecl * method_decl = llvm : : dyn_cast < clang : : ObjCMethodDecl > ( decl_context ) ;
2012-10-30 23:35:54 +00:00
if ( method_decl )
2011-11-15 02:11:17 +00:00
{
2012-10-30 23:35:54 +00:00
ObjCInterfaceDecl * self_interface = method_decl - > getClassInterface ( ) ;
2011-11-15 02:11:17 +00:00
2012-10-30 23:35:54 +00:00
if ( ! self_interface )
2012-02-08 03:45:08 +00:00
return ;
2012-10-30 23:35:54 +00:00
const clang : : Type * interface_type = self_interface - > getTypeForDecl ( ) ;
TypeFromUser class_user_type ( QualType ( interface_type , 0 ) . getAsOpaquePtr ( ) ,
& method_decl - > getASTContext ( ) ) ;
2012-02-08 03:45:08 +00:00
2012-10-30 23:35:54 +00:00
if ( log )
{
ASTDumper ast_dumper ( interface_type ) ;
log - > Printf ( " FEVD[%u] Adding type for $__lldb_objc_class: %s " , current_id , ast_dumper . GetCString ( ) ) ;
}
AddOneType ( context , class_user_type , current_id , false ) ;
if ( method_decl - > isInstanceMethod ( ) )
{
// self is a pointer to the object
QualType class_pointer_type = method_decl - > getASTContext ( ) . getObjCObjectPointerType ( QualType ( interface_type , 0 ) ) ;
TypeFromUser self_user_type ( class_pointer_type . getAsOpaquePtr ( ) ,
& method_decl - > getASTContext ( ) ) ;
m_struct_vars - > m_object_pointer_type = self_user_type ;
}
else
{
// self is a Class pointer
QualType class_type = method_decl - > getASTContext ( ) . getObjCClassType ( ) ;
TypeFromUser self_user_type ( class_type . getAsOpaquePtr ( ) ,
& method_decl - > getASTContext ( ) ) ;
m_struct_vars - > m_object_pointer_type = self_user_type ;
}
return ;
2012-02-08 03:45:08 +00:00
}
else
{
2012-10-30 23:35:54 +00:00
// This branch will get hit if we are executing code in the context of a function that
// claims to have an object pointer (through DW_AT_object_pointer?) but is not formally a
// method of the class. In that case, just look up the "self" variable in the the current
// scope and use its type.
2012-02-08 03:45:08 +00:00
2012-10-30 23:35:54 +00:00
VariableList * vars = frame - > GetVariableList ( false ) ;
2012-02-08 03:45:08 +00:00
2012-10-30 23:35:54 +00:00
lldb : : VariableSP self_var = vars - > FindVariable ( ConstString ( " self " ) ) ;
if ( self_var & &
self_var - > IsInScope ( frame ) & &
self_var - > LocationIsValidForFrame ( frame ) )
{
Type * self_type = self_var - > GetType ( ) ;
if ( ! self_type )
return ;
QualType self_qual_type = QualType : : getFromOpaquePtr ( self_type - > GetClangFullType ( ) ) ;
const ObjCObjectPointerType * class_pointer_type = self_qual_type - > getAs < ObjCObjectPointerType > ( ) ;
if ( class_pointer_type )
{
QualType class_type = class_pointer_type - > getPointeeType ( ) ;
if ( log )
{
ASTDumper ast_dumper ( self_type - > GetClangFullType ( ) ) ;
log - > Printf ( " FEVD[%u] Adding type for $__lldb_objc_class: %s " , current_id , ast_dumper . GetCString ( ) ) ;
}
TypeFromUser class_user_type ( class_type . getAsOpaquePtr ( ) ,
self_type - > GetClangAST ( ) ) ;
AddOneType ( context , class_user_type , current_id , false ) ;
TypeFromUser self_user_type ( self_type - > GetClangFullType ( ) ,
self_type - > GetClangAST ( ) ) ;
m_struct_vars - > m_object_pointer_type = self_user_type ;
return ;
}
}
2012-02-08 03:45:08 +00:00
}
2011-10-12 01:39:28 +00:00
return ;
}
// any other $__lldb names should be weeded out now
if ( ! : : strncmp ( name_unique_cstr , " $__lldb " , sizeof ( " $__lldb " ) - 1 ) )
return ;
do
{
if ( ! target )
break ;
ClangASTContext * scratch_clang_ast_context = target - > GetScratchClangASTContext ( ) ;
if ( ! scratch_clang_ast_context )
break ;
ASTContext * scratch_ast_context = scratch_clang_ast_context - > getASTContext ( ) ;
if ( ! scratch_ast_context )
break ;
TypeDecl * ptype_type_decl = m_parser_vars - > m_persistent_vars - > GetPersistentType ( name ) ;
if ( ! ptype_type_decl )
break ;
2011-12-06 03:41:14 +00:00
Decl * parser_ptype_decl = m_ast_importer - > CopyDecl ( m_ast_context , scratch_ast_context , ptype_type_decl ) ;
2011-10-12 01:39:28 +00:00
if ( ! parser_ptype_decl )
break ;
TypeDecl * parser_ptype_type_decl = dyn_cast < TypeDecl > ( parser_ptype_decl ) ;
if ( ! parser_ptype_type_decl )
break ;
if ( log )
2011-10-29 19:50:43 +00:00
log - > Printf ( " CEDM::FEVD[%u] Found persistent type %s " , current_id , name . GetCString ( ) ) ;
2011-10-12 01:39:28 +00:00
context . AddNamedDecl ( parser_ptype_type_decl ) ;
} while ( 0 ) ;
ClangExpressionVariableSP pvar_sp ( m_parser_vars - > m_persistent_vars - > GetVariable ( name ) ) ;
if ( pvar_sp )
{
2011-10-14 20:34:21 +00:00
AddOneVariable ( context , pvar_sp , current_id ) ;
2011-10-12 01:39:28 +00:00
return ;
}
const char * reg_name ( & name . GetCString ( ) [ 1 ] ) ;
2012-02-10 01:22:05 +00:00
if ( m_parser_vars - > m_exe_ctx . GetRegisterContext ( ) )
2011-10-12 01:39:28 +00:00
{
2012-02-10 01:22:05 +00:00
const RegisterInfo * reg_info ( m_parser_vars - > m_exe_ctx . GetRegisterContext ( ) - > GetRegisterInfoByName ( reg_name ) ) ;
2011-10-29 19:50:43 +00:00
2011-10-12 01:39:28 +00:00
if ( reg_info )
2011-10-18 16:46:55 +00:00
{
if ( log )
2011-10-29 19:50:43 +00:00
log - > Printf ( " CEDM::FEVD[%u] Found register %s " , current_id , reg_info - > name ) ;
2011-10-18 16:46:55 +00:00
2011-10-14 20:34:21 +00:00
AddOneRegister ( context , reg_info , current_id ) ;
2011-10-18 16:46:55 +00:00
}
2011-10-12 01:39:28 +00:00
}
}
else
2010-07-27 00:55:47 +00:00
{
2011-08-06 00:28:14 +00:00
ValueObjectSP valobj ;
VariableSP var ;
Error err ;
2011-10-12 01:39:28 +00:00
if ( frame & & ! namespace_decl )
2010-10-15 22:48:33 +00:00
{
2011-09-22 04:58:26 +00:00
valobj = frame - > GetValueForVariableExpressionPath ( name_unique_cstr ,
2011-10-12 00:12:34 +00:00
eNoDynamicValues ,
2012-10-27 02:54:13 +00:00
StackFrame : : eExpressionPathOptionCheckPtrVsMember
| StackFrame : : eExpressionPathOptionsAllowDirectIVarAccess ,
2011-10-12 00:12:34 +00:00
var ,
err ) ;
2011-09-15 02:13:07 +00:00
// If we found a variable in scope, no need to pull up function names
2012-08-09 00:50:26 +00:00
if ( err . Success ( ) & & var )
2011-09-15 02:13:07 +00:00
{
2011-11-29 22:03:21 +00:00
AddOneVariable ( context , var , valobj , current_id ) ;
2011-10-12 20:29:25 +00:00
context . m_found . variable = true ;
2011-10-25 20:36:57 +00:00
return ;
2011-09-15 02:13:07 +00:00
}
2010-10-15 22:48:33 +00:00
}
2011-12-10 04:03:38 +00:00
if ( target )
2011-09-15 02:13:07 +00:00
{
2011-10-12 16:59:31 +00:00
var = FindGlobalVariable ( * target ,
2011-10-12 18:44:30 +00:00
module_sp ,
2011-10-12 16:59:31 +00:00
name ,
& namespace_decl ,
2011-09-22 04:58:26 +00:00
NULL ) ;
2011-09-15 02:13:07 +00:00
if ( var )
{
2011-12-10 03:12:34 +00:00
valobj = ValueObjectVariable : : Create ( target , var ) ;
2011-11-29 22:03:21 +00:00
AddOneVariable ( context , var , valobj , current_id ) ;
2011-10-12 20:29:25 +00:00
context . m_found . variable = true ;
2011-12-10 04:03:38 +00:00
return ;
2011-09-15 02:13:07 +00:00
}
}
2011-10-12 20:29:25 +00:00
if ( ! context . m_found . variable )
2010-10-15 22:48:33 +00:00
{
2012-02-10 22:52:19 +00:00
const bool include_inlines = false ;
2011-01-27 06:44:37 +00:00
const bool append = false ;
2011-10-12 17:38:09 +00:00
2011-10-12 18:44:30 +00:00
if ( namespace_decl & & module_sp )
2011-10-12 17:38:09 +00:00
{
2012-02-15 17:14:49 +00:00
const bool include_symbols = false ;
2011-10-12 18:44:30 +00:00
module_sp - > FindFunctions ( name ,
& namespace_decl ,
eFunctionNameTypeBase ,
include_symbols ,
2012-02-10 22:52:19 +00:00
include_inlines ,
2011-10-12 18:44:30 +00:00
append ,
sc_list ) ;
2011-10-12 17:38:09 +00:00
}
2012-10-12 17:34:26 +00:00
else if ( target & & ! namespace_decl )
2011-10-12 17:38:09 +00:00
{
2012-02-15 17:14:49 +00:00
const bool include_symbols = true ;
2012-07-28 00:21:01 +00:00
// TODO Fix FindFunctions so that it doesn't return
// instance methods for eFunctionNameTypeBase.
2011-10-12 17:38:09 +00:00
target - > GetImages ( ) . FindFunctions ( name ,
eFunctionNameTypeBase ,
include_symbols ,
2012-02-10 22:52:19 +00:00
include_inlines ,
2011-10-12 17:38:09 +00:00
append ,
sc_list ) ;
}
2011-05-08 02:21:26 +00:00
if ( sc_list . GetSize ( ) )
2010-10-15 22:48:33 +00:00
{
2011-05-08 02:21:26 +00:00
Symbol * generic_symbol = NULL ;
Symbol * non_extern_symbol = NULL ;
for ( uint32_t index = 0 , num_indices = sc_list . GetSize ( ) ;
index < num_indices ;
+ + index )
2010-10-15 22:48:33 +00:00
{
2011-05-08 02:21:26 +00:00
SymbolContext sym_ctx ;
sc_list . GetContextAtIndex ( index , sym_ctx ) ;
if ( sym_ctx . function )
{
2012-07-28 00:21:01 +00:00
clang : : DeclContext * decl_ctx = sym_ctx . function - > GetClangDeclContext ( ) ;
// Filter out class/instance methods.
if ( dyn_cast < clang : : ObjCMethodDecl > ( decl_ctx ) )
continue ;
if ( dyn_cast < clang : : CXXMethodDecl > ( decl_ctx ) )
continue ;
2011-05-08 02:21:26 +00:00
// TODO only do this if it's a C function; C++ functions may be
// overloaded
2011-10-12 20:29:25 +00:00
if ( ! context . m_found . function_with_type_info )
2011-10-14 20:34:21 +00:00
AddOneFunction ( context , sym_ctx . function , NULL , current_id ) ;
2011-10-12 20:29:25 +00:00
context . m_found . function_with_type_info = true ;
context . m_found . function = true ;
2011-05-08 02:21:26 +00:00
}
else if ( sym_ctx . symbol )
{
if ( sym_ctx . symbol - > IsExternal ( ) )
generic_symbol = sym_ctx . symbol ;
else
non_extern_symbol = sym_ctx . symbol ;
}
2010-10-15 22:48:33 +00:00
}
2011-05-08 02:21:26 +00:00
2011-10-12 20:29:25 +00:00
if ( ! context . m_found . function_with_type_info )
2010-10-15 22:48:33 +00:00
{
2011-05-08 02:21:26 +00:00
if ( generic_symbol )
2011-09-15 02:13:07 +00:00
{
2011-10-14 20:34:21 +00:00
AddOneFunction ( context , NULL , generic_symbol , current_id ) ;
2011-10-12 20:29:25 +00:00
context . m_found . function = true ;
2011-09-15 02:13:07 +00:00
}
2011-05-08 02:21:26 +00:00
else if ( non_extern_symbol )
2011-09-15 02:13:07 +00:00
{
2011-10-14 20:34:21 +00:00
AddOneFunction ( context , NULL , non_extern_symbol , current_id ) ;
2011-10-12 20:29:25 +00:00
context . m_found . function = true ;
2011-09-15 02:13:07 +00:00
}
2011-05-08 02:21:26 +00:00
}
2010-10-15 22:48:33 +00:00
}
2011-09-15 02:13:07 +00:00
2012-03-06 20:53:06 +00:00
if ( ! context . m_found . variable & & ! namespace_decl )
2010-10-15 22:48:33 +00:00
{
2011-10-12 20:29:25 +00:00
// We couldn't find a non-symbol variable for this. Now we'll hunt for a generic
2011-05-08 02:21:26 +00:00
// data symbol, and -- if it is found -- treat it as a variable.
2012-11-27 01:52:16 +00:00
const Symbol * data_symbol = FindGlobalDataSymbol ( * target , name ) ;
2011-05-08 02:21:26 +00:00
if ( data_symbol )
2011-09-15 02:13:07 +00:00
{
2011-10-14 20:34:21 +00:00
AddOneGenericVariable ( context , * data_symbol , current_id ) ;
2011-10-12 20:29:25 +00:00
context . m_found . variable = true ;
2011-09-15 02:13:07 +00:00
}
2010-11-13 03:52:47 +00:00
}
2010-09-07 21:49:41 +00:00
}
2011-10-27 02:06:03 +00:00
}
2010-07-17 00:43:37 +00:00
}
2011-06-25 00:44:06 +00:00
2012-03-06 21:56:33 +00:00
static clang_type_t
MaybePromoteToBlockPointerType
(
ASTContext * ast_context ,
clang_type_t candidate_type
)
{
if ( ! candidate_type )
return candidate_type ;
QualType candidate_qual_type = QualType : : getFromOpaquePtr ( candidate_type ) ;
const PointerType * candidate_pointer_type = dyn_cast < PointerType > ( candidate_qual_type ) ;
if ( ! candidate_pointer_type )
return candidate_type ;
QualType pointee_qual_type = candidate_pointer_type - > getPointeeType ( ) ;
const RecordType * pointee_record_type = dyn_cast < RecordType > ( pointee_qual_type ) ;
if ( ! pointee_record_type )
return candidate_type ;
RecordDecl * pointee_record_decl = pointee_record_type - > getDecl ( ) ;
if ( ! pointee_record_decl - > isRecord ( ) )
return candidate_type ;
if ( ! pointee_record_decl - > getName ( ) . startswith ( llvm : : StringRef ( " __block_literal_ " ) ) )
return candidate_type ;
QualType generic_function_type = ast_context - > getFunctionNoProtoType ( ast_context - > UnknownAnyTy ) ;
QualType block_pointer_type = ast_context - > getBlockPointerType ( generic_function_type ) ;
return block_pointer_type . getAsOpaquePtr ( ) ;
}
2010-07-17 00:43:37 +00:00
Value *
2010-10-15 22:48:33 +00:00
ClangExpressionDeclMap : : GetVariableValue
(
2011-10-13 00:09:20 +00:00
VariableSP & var ,
2011-07-30 02:42:06 +00:00
ASTContext * parser_ast_context ,
2010-10-15 22:48:33 +00:00
TypeFromUser * user_type ,
TypeFromParser * parser_type
)
2010-06-08 16:52:24 +00:00
{
2010-11-06 01:53:30 +00:00
lldb : : LogSP log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_EXPRESSIONS ) ) ;
2010-06-23 00:47:48 +00:00
2010-06-08 16:52:24 +00:00
Type * var_type = var - > GetType ( ) ;
if ( ! var_type )
{
2010-07-16 00:09:46 +00:00
if ( log )
log - > PutCString ( " Skipped a definition because it has no type " ) ;
2010-07-17 00:43:37 +00:00
return NULL ;
2010-06-08 16:52:24 +00:00
}
2011-02-16 23:00:21 +00:00
clang_type_t var_opaque_type = var_type - > GetClangFullType ( ) ;
2010-06-08 16:52:24 +00:00
if ( ! var_opaque_type )
{
2010-07-16 00:09:46 +00:00
if ( log )
log - > PutCString ( " Skipped a definition because it has no Clang type " ) ;
2010-07-17 00:43:37 +00:00
return NULL ;
2010-06-08 16:52:24 +00:00
}
2011-07-30 02:42:06 +00:00
ASTContext * ast = var_type - > GetClangASTContext ( ) . getASTContext ( ) ;
2010-06-08 16:52:24 +00:00
2011-01-17 03:46:26 +00:00
if ( ! ast )
2010-06-08 16:52:24 +00:00
{
2010-07-16 00:09:46 +00:00
if ( log )
log - > PutCString ( " There is no AST context for the current execution context " ) ;
2010-07-17 00:43:37 +00:00
return NULL ;
2010-06-08 16:52:24 +00:00
}
2012-03-06 21:56:33 +00:00
2012-03-30 16:58:37 +00:00
// commented out because of <rdar://problem/11024417>
//var_opaque_type = MaybePromoteToBlockPointerType (ast, var_opaque_type);
2010-06-08 16:52:24 +00:00
2010-07-17 00:43:37 +00:00
DWARFExpression & var_location_expr = var - > LocationExpression ( ) ;
2010-06-08 16:52:24 +00:00
std : : auto_ptr < Value > var_location ( new Value ) ;
2010-09-14 02:20:48 +00:00
lldb : : addr_t loclist_base_load_addr = LLDB_INVALID_ADDRESS ;
2012-02-10 01:22:05 +00:00
Target * target = m_parser_vars - > m_exe_ctx . GetTargetPtr ( ) ;
2011-09-22 04:58:26 +00:00
2010-09-14 02:20:48 +00:00
if ( var_location_expr . IsLocationList ( ) )
{
SymbolContext var_sc ;
var - > CalculateSymbolContext ( & var_sc ) ;
2011-09-22 04:58:26 +00:00
loclist_base_load_addr = var_sc . function - > GetAddressRange ( ) . GetBaseAddress ( ) . GetLoadAddress ( target ) ;
2010-09-14 02:20:48 +00:00
}
2010-06-08 16:52:24 +00:00
Error err ;
2012-02-10 01:22:05 +00:00
if ( ! var_location_expr . Evaluate ( & m_parser_vars - > m_exe_ctx , ast , NULL , NULL , NULL , loclist_base_load_addr , NULL , * var_location . get ( ) , & err ) )
2010-06-08 16:52:24 +00:00
{
2010-07-16 00:09:46 +00:00
if ( log )
log - > Printf ( " Error evaluating location: %s " , err . AsCString ( ) ) ;
2010-07-17 00:43:37 +00:00
return NULL ;
2010-06-08 16:52:24 +00:00
}
2011-01-17 03:46:26 +00:00
2011-07-08 00:39:14 +00:00
void * type_to_use = NULL ;
2010-07-17 00:43:37 +00:00
2010-07-20 23:31:16 +00:00
if ( parser_ast_context )
{
2011-01-17 03:46:26 +00:00
type_to_use = GuardedCopyType ( parser_ast_context , ast , var_opaque_type ) ;
2010-07-20 23:31:16 +00:00
2010-11-20 02:19:29 +00:00
if ( ! type_to_use )
{
if ( log )
log - > Printf ( " Couldn't copy a variable's type into the parser's AST context " ) ;
return NULL ;
}
2010-07-20 23:31:16 +00:00
if ( parser_type )
* parser_type = TypeFromParser ( type_to_use , parser_ast_context ) ;
}
2010-07-17 00:43:37 +00:00
else
type_to_use = var_opaque_type ;
2010-06-08 16:52:24 +00:00
if ( var_location . get ( ) - > GetContextType ( ) = = Value : : eContextTypeInvalid )
2010-11-13 03:52:47 +00:00
var_location . get ( ) - > SetContext ( Value : : eContextTypeClangType , type_to_use ) ;
2010-06-08 16:52:24 +00:00
if ( var_location . get ( ) - > GetValueType ( ) = = Value : : eValueTypeFileAddress )
{
SymbolContext var_sc ;
var - > CalculateSymbolContext ( & var_sc ) ;
2010-07-17 00:43:37 +00:00
2010-06-08 16:52:24 +00:00
if ( ! var_sc . module_sp )
2010-07-17 00:43:37 +00:00
return NULL ;
2010-06-08 16:52:24 +00:00
ObjectFile * object_file = var_sc . module_sp - > GetObjectFile ( ) ;
if ( ! object_file )
2010-07-17 00:43:37 +00:00
return NULL ;
2010-06-08 16:52:24 +00:00
Address so_addr ( var_location - > GetScalar ( ) . ULongLong ( ) , object_file - > GetSectionList ( ) ) ;
2011-09-22 04:58:26 +00:00
lldb : : addr_t load_addr = so_addr . GetLoadAddress ( target ) ;
2010-06-08 16:52:24 +00:00
2011-09-15 02:13:07 +00:00
if ( load_addr ! = LLDB_INVALID_ADDRESS )
{
var_location - > GetScalar ( ) = load_addr ;
var_location - > SetValueType ( Value : : eValueTypeLoadAddress ) ;
}
2010-06-08 16:52:24 +00:00
}
2010-07-20 23:31:16 +00:00
if ( user_type )
2011-01-17 03:46:26 +00:00
* user_type = TypeFromUser ( var_opaque_type , ast ) ;
2010-07-17 00:43:37 +00:00
return var_location . release ( ) ;
}
void
2011-11-29 22:03:21 +00:00
ClangExpressionDeclMap : : AddOneVariable ( NameSearchContext & context , VariableSP var , ValueObjectSP valobj , unsigned int current_id )
2010-07-17 00:43:37 +00:00
{
2010-12-03 01:38:59 +00:00
assert ( m_parser_vars . get ( ) ) ;
2010-11-06 01:53:30 +00:00
lldb : : LogSP log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_EXPRESSIONS ) ) ;
2011-09-15 02:13:07 +00:00
2010-07-20 23:31:16 +00:00
TypeFromUser ut ;
TypeFromParser pt ;
2010-07-17 00:43:37 +00:00
2012-02-10 01:22:05 +00:00
Value * var_location = GetVariableValue ( var ,
2011-10-28 23:38:38 +00:00
m_ast_context ,
2010-10-15 22:48:33 +00:00
& ut ,
& pt ) ;
2010-07-17 00:43:37 +00:00
2012-03-15 01:53:17 +00:00
clang : : QualType parser_opaque_type = QualType : : getFromOpaquePtr ( pt . GetOpaqueQualType ( ) ) ;
2012-03-21 17:13:20 +00:00
if ( parser_opaque_type . isNull ( ) )
return ;
2012-03-15 01:53:17 +00:00
if ( const clang : : Type * parser_type = parser_opaque_type . getTypePtr ( ) )
{
if ( const TagType * tag_type = dyn_cast < TagType > ( parser_type ) )
CompleteType ( tag_type - > getDecl ( ) ) ;
}
2010-11-20 02:19:29 +00:00
if ( ! var_location )
return ;
2011-10-27 19:41:13 +00:00
NamedDecl * var_decl ;
bool is_reference = ClangASTContext : : IsReferenceType ( pt . GetOpaqueQualType ( ) ) ;
if ( is_reference )
var_decl = context . AddVarDecl ( pt . GetOpaqueQualType ( ) ) ;
else
var_decl = context . AddVarDecl ( ClangASTContext : : CreateLValueReferenceType ( pt . GetASTContext ( ) , pt . GetOpaqueQualType ( ) ) ) ;
2010-10-15 22:48:33 +00:00
std : : string decl_name ( context . m_decl_name . getAsString ( ) ) ;
2010-12-14 02:59:59 +00:00
ConstString entity_name ( decl_name . c_str ( ) ) ;
2011-11-29 22:03:21 +00:00
ClangExpressionVariableSP entity ( m_found_entities . CreateVariable ( valobj ) ) ;
2010-12-14 02:59:59 +00:00
assert ( entity . get ( ) ) ;
entity - > EnableParserVars ( ) ;
entity - > m_parser_vars - > m_parser_type = pt ;
entity - > m_parser_vars - > m_named_decl = var_decl ;
entity - > m_parser_vars - > m_llvm_value = NULL ;
entity - > m_parser_vars - > m_lldb_value = var_location ;
2011-05-07 01:06:41 +00:00
entity - > m_parser_vars - > m_lldb_var = var ;
2010-06-08 16:52:24 +00:00
2011-10-27 19:41:13 +00:00
if ( is_reference )
entity - > m_flags | = ClangExpressionVariable : : EVTypeIsReference ;
2010-07-16 00:09:46 +00:00
if ( log )
2010-10-15 22:48:33 +00:00
{
2011-11-07 23:32:52 +00:00
ASTDumper orig_dumper ( ut . GetOpaqueQualType ( ) ) ;
2011-10-20 00:47:21 +00:00
ASTDumper ast_dumper ( var_decl ) ;
2011-11-07 23:32:52 +00:00
log - > Printf ( " CEDM::FEVD[%u] Found variable %s, returned %s (original %s) " , current_id , decl_name . c_str ( ) , ast_dumper . GetCString ( ) , orig_dumper . GetCString ( ) ) ;
2010-10-15 22:48:33 +00:00
}
2010-06-22 23:46:24 +00:00
}
2010-08-11 03:57:18 +00:00
void
ClangExpressionDeclMap : : AddOneVariable ( NameSearchContext & context ,
2011-10-14 20:34:21 +00:00
ClangExpressionVariableSP & pvar_sp ,
unsigned int current_id )
2010-08-11 03:57:18 +00:00
{
2010-11-06 01:53:30 +00:00
lldb : : LogSP log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_EXPRESSIONS ) ) ;
2010-08-30 22:17:16 +00:00
2010-12-14 02:59:59 +00:00
TypeFromUser user_type ( pvar_sp - > GetTypeFromUser ( ) ) ;
2010-08-11 03:57:18 +00:00
2011-10-28 23:38:38 +00:00
TypeFromParser parser_type ( GuardedCopyType ( m_ast_context ,
2010-12-14 02:59:59 +00:00
user_type . GetASTContext ( ) ,
user_type . GetOpaqueQualType ( ) ) ,
2011-10-28 23:38:38 +00:00
m_ast_context ) ;
2010-08-11 03:57:18 +00:00
2011-12-01 21:04:37 +00:00
if ( ! parser_type . GetOpaqueQualType ( ) )
{
if ( log )
log - > Printf ( " CEDM::FEVD[%u] Couldn't import type for pvar %s " , current_id , pvar_sp - > GetName ( ) . GetCString ( ) ) ;
return ;
}
2011-01-13 08:53:35 +00:00
NamedDecl * var_decl = context . AddVarDecl ( ClangASTContext : : CreateLValueReferenceType ( parser_type . GetASTContext ( ) , parser_type . GetOpaqueQualType ( ) ) ) ;
2010-08-23 23:09:38 +00:00
2010-12-14 02:59:59 +00:00
pvar_sp - > EnableParserVars ( ) ;
pvar_sp - > m_parser_vars - > m_parser_type = parser_type ;
pvar_sp - > m_parser_vars - > m_named_decl = var_decl ;
pvar_sp - > m_parser_vars - > m_llvm_value = NULL ;
pvar_sp - > m_parser_vars - > m_lldb_value = NULL ;
2010-08-30 22:17:16 +00:00
if ( log )
2010-11-01 23:22:47 +00:00
{
2011-10-20 00:47:21 +00:00
ASTDumper ast_dumper ( var_decl ) ;
2011-10-29 19:50:43 +00:00
log - > Printf ( " CEDM::FEVD[%u] Added pvar %s, returned %s " , current_id , pvar_sp - > GetName ( ) . GetCString ( ) , ast_dumper . GetCString ( ) ) ;
2010-11-01 23:22:47 +00:00
}
2010-08-11 03:57:18 +00:00
}
2011-05-08 02:21:26 +00:00
void
ClangExpressionDeclMap : : AddOneGenericVariable ( NameSearchContext & context ,
2012-11-27 01:52:16 +00:00
const Symbol & symbol ,
2011-10-14 20:34:21 +00:00
unsigned int current_id )
2011-05-08 02:21:26 +00:00
{
assert ( m_parser_vars . get ( ) ) ;
lldb : : LogSP log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_EXPRESSIONS ) ) ;
2012-02-10 01:22:05 +00:00
Target * target = m_parser_vars - > m_exe_ctx . GetTargetPtr ( ) ;
2011-09-22 04:58:26 +00:00
if ( target = = NULL )
return ;
ASTContext * scratch_ast_context = target - > GetScratchClangASTContext ( ) - > getASTContext ( ) ;
2011-05-08 02:21:26 +00:00
2012-12-14 00:26:21 +00:00
TypeFromUser user_type ( ClangASTContext : : CreateLValueReferenceType ( scratch_ast_context , ClangASTContext : : GetVoidPtrType ( scratch_ast_context , false ) ) ,
2011-05-08 02:21:26 +00:00
scratch_ast_context ) ;
2012-12-14 00:26:21 +00:00
TypeFromParser parser_type ( ClangASTContext : : CreateLValueReferenceType ( m_ast_context , ClangASTContext : : GetVoidPtrType ( m_ast_context , false ) ) ,
2011-10-28 23:38:38 +00:00
m_ast_context ) ;
2011-05-08 02:21:26 +00:00
2011-05-12 23:54:16 +00:00
NamedDecl * var_decl = context . AddVarDecl ( parser_type . GetOpaqueQualType ( ) ) ;
2011-05-08 02:21:26 +00:00
std : : string decl_name ( context . m_decl_name . getAsString ( ) ) ;
ConstString entity_name ( decl_name . c_str ( ) ) ;
2012-02-10 01:22:05 +00:00
ClangExpressionVariableSP entity ( m_found_entities . CreateVariable ( m_parser_vars - > m_exe_ctx . GetBestExecutionContextScope ( ) ,
2011-05-08 02:21:26 +00:00
entity_name ,
user_type ,
2011-09-15 02:13:07 +00:00
m_parser_vars - > m_target_info . byte_order ,
m_parser_vars - > m_target_info . address_byte_size ) ) ;
2011-05-08 02:21:26 +00:00
assert ( entity . get ( ) ) ;
std : : auto_ptr < Value > symbol_location ( new Value ) ;
2012-11-27 01:52:16 +00:00
const Address & symbol_address = symbol . GetAddress ( ) ;
2011-09-22 04:58:26 +00:00
lldb : : addr_t symbol_load_addr = symbol_address . GetLoadAddress ( target ) ;
2011-05-08 02:21:26 +00:00
symbol_location - > SetContext ( Value : : eContextTypeClangType , user_type . GetOpaqueQualType ( ) ) ;
symbol_location - > GetScalar ( ) = symbol_load_addr ;
symbol_location - > SetValueType ( Value : : eValueTypeLoadAddress ) ;
2011-05-12 23:54:16 +00:00
entity - > EnableParserVars ( ) ;
2011-05-08 02:21:26 +00:00
entity - > m_parser_vars - > m_parser_type = parser_type ;
entity - > m_parser_vars - > m_named_decl = var_decl ;
entity - > m_parser_vars - > m_llvm_value = NULL ;
entity - > m_parser_vars - > m_lldb_value = symbol_location . release ( ) ;
entity - > m_parser_vars - > m_lldb_sym = & symbol ;
if ( log )
{
2011-10-20 00:47:21 +00:00
ASTDumper ast_dumper ( var_decl ) ;
2011-05-08 02:21:26 +00:00
2011-10-29 19:50:43 +00:00
log - > Printf ( " CEDM::FEVD[%u] Found variable %s, returned %s " , current_id , decl_name . c_str ( ) , ast_dumper . GetCString ( ) ) ;
2011-05-08 02:21:26 +00:00
}
}
2011-05-12 23:54:16 +00:00
bool
ClangExpressionDeclMap : : ResolveUnknownTypes ( )
{
lldb : : LogSP log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_EXPRESSIONS ) ) ;
2012-02-10 01:22:05 +00:00
Target * target = m_parser_vars - > m_exe_ctx . GetTargetPtr ( ) ;
2011-09-22 04:58:26 +00:00
ASTContext * scratch_ast_context = target - > GetScratchClangASTContext ( ) - > getASTContext ( ) ;
2011-05-12 23:54:16 +00:00
for ( size_t index = 0 , num_entities = m_found_entities . GetSize ( ) ;
index < num_entities ;
+ + index )
{
ClangExpressionVariableSP entity = m_found_entities . GetVariableAtIndex ( index ) ;
if ( entity - > m_flags & ClangExpressionVariable : : EVUnknownType )
{
const NamedDecl * named_decl = entity - > m_parser_vars - > m_named_decl ;
const VarDecl * var_decl = dyn_cast < VarDecl > ( named_decl ) ;
if ( ! var_decl )
{
if ( log )
log - > Printf ( " Entity of unknown type does not have a VarDecl " ) ;
return false ;
}
if ( log )
{
2011-10-20 00:47:21 +00:00
ASTDumper ast_dumper ( const_cast < VarDecl * > ( var_decl ) ) ;
log - > Printf ( " Variable of unknown type now has Decl %s " , ast_dumper . GetCString ( ) ) ;
2011-05-12 23:54:16 +00:00
}
QualType var_type = var_decl - > getType ( ) ;
TypeFromParser parser_type ( var_type . getAsOpaquePtr ( ) , & var_decl - > getASTContext ( ) ) ;
2011-11-18 03:28:09 +00:00
lldb : : clang_type_t copied_type = m_ast_importer - > CopyType ( scratch_ast_context , & var_decl - > getASTContext ( ) , var_type . getAsOpaquePtr ( ) ) ;
2011-05-12 23:54:16 +00:00
2011-12-01 21:04:37 +00:00
if ( ! copied_type )
{
if ( log )
log - > Printf ( " ClangExpressionDeclMap::ResolveUnknownType - Couldn't import the type for a variable " ) ;
2012-08-11 00:35:26 +00:00
return ( bool ) lldb : : ClangExpressionVariableSP ( ) ;
2011-12-01 21:04:37 +00:00
}
2011-05-12 23:54:16 +00:00
TypeFromUser user_type ( copied_type , scratch_ast_context ) ;
entity - > m_parser_vars - > m_lldb_value - > SetContext ( Value : : eContextTypeClangType , user_type . GetOpaqueQualType ( ) ) ;
entity - > m_parser_vars - > m_parser_type = parser_type ;
entity - > SetClangAST ( user_type . GetASTContext ( ) ) ;
entity - > SetClangType ( user_type . GetOpaqueQualType ( ) ) ;
entity - > m_flags & = ~ ( ClangExpressionVariable : : EVUnknownType ) ;
}
}
return true ;
}
2010-11-30 00:27:43 +00:00
void
2010-12-14 02:59:59 +00:00
ClangExpressionDeclMap : : AddOneRegister ( NameSearchContext & context ,
2011-10-14 20:34:21 +00:00
const RegisterInfo * reg_info ,
unsigned int current_id )
2010-11-30 00:27:43 +00:00
{
lldb : : LogSP log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_EXPRESSIONS ) ) ;
2011-10-28 23:38:38 +00:00
void * ast_type = ClangASTContext : : GetBuiltinTypeForEncodingAndBitSize ( m_ast_context ,
2010-11-30 00:27:43 +00:00
reg_info - > encoding ,
reg_info - > byte_size * 8 ) ;
if ( ! ast_type )
{
2011-08-09 22:52:27 +00:00
if ( log )
2011-10-14 20:34:21 +00:00
log - > Printf ( " Tried to add a type for %s, but couldn't get one " , context . m_decl_name . getAsString ( ) . c_str ( ) ) ;
2010-11-30 00:27:43 +00:00
return ;
}
2010-12-14 02:59:59 +00:00
TypeFromParser parser_type ( ast_type ,
2011-10-28 23:38:38 +00:00
m_ast_context ) ;
2010-11-30 00:27:43 +00:00
NamedDecl * var_decl = context . AddVarDecl ( parser_type . GetOpaqueQualType ( ) ) ;
2012-02-10 01:22:05 +00:00
ClangExpressionVariableSP entity ( m_found_entities . CreateVariable ( m_parser_vars - > m_exe_ctx . GetBestExecutionContextScope ( ) ,
2011-09-15 02:13:07 +00:00
m_parser_vars - > m_target_info . byte_order ,
m_parser_vars - > m_target_info . address_byte_size ) ) ;
2010-12-14 02:59:59 +00:00
assert ( entity . get ( ) ) ;
2010-11-30 00:27:43 +00:00
std : : string decl_name ( context . m_decl_name . getAsString ( ) ) ;
2010-12-14 02:59:59 +00:00
entity - > SetName ( ConstString ( decl_name . c_str ( ) ) ) ;
entity - > SetRegisterInfo ( reg_info ) ;
entity - > EnableParserVars ( ) ;
entity - > m_parser_vars - > m_parser_type = parser_type ;
entity - > m_parser_vars - > m_named_decl = var_decl ;
entity - > m_parser_vars - > m_llvm_value = NULL ;
entity - > m_parser_vars - > m_lldb_value = NULL ;
2012-02-15 01:40:39 +00:00
entity - > m_flags | = ClangExpressionVariable : : EVBareRegister ;
2010-11-30 00:27:43 +00:00
2012-02-15 01:40:39 +00:00
if ( log )
2010-11-30 00:27:43 +00:00
{
2011-10-20 00:47:21 +00:00
ASTDumper ast_dumper ( var_decl ) ;
2011-10-29 19:50:43 +00:00
log - > Printf ( " CEDM::FEVD[%d] Added register %s, returned %s " , current_id , context . m_decl_name . getAsString ( ) . c_str ( ) , ast_dumper . GetCString ( ) ) ;
2010-11-30 00:27:43 +00:00
}
}
2010-06-22 23:46:24 +00:00
void
2011-05-18 22:01:49 +00:00
ClangExpressionDeclMap : : AddOneFunction ( NameSearchContext & context ,
Function * fun ,
2011-10-14 20:34:21 +00:00
Symbol * symbol ,
unsigned int current_id )
2010-06-22 23:46:24 +00:00
{
2010-12-03 01:38:59 +00:00
assert ( m_parser_vars . get ( ) ) ;
2010-11-06 01:53:30 +00:00
lldb : : LogSP log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_EXPRESSIONS ) ) ;
2010-06-22 23:46:24 +00:00
2011-07-08 00:39:14 +00:00
NamedDecl * fun_decl = NULL ;
2010-06-22 23:46:24 +00:00
std : : auto_ptr < Value > fun_location ( new Value ) ;
2011-07-08 00:39:14 +00:00
const Address * fun_address = NULL ;
2010-06-22 23:46:24 +00:00
2010-07-27 00:55:47 +00:00
// only valid for Functions, not for Symbols
void * fun_opaque_type = NULL ;
2011-07-30 02:42:06 +00:00
ASTContext * fun_ast_context = NULL ;
2010-07-27 00:55:47 +00:00
if ( fun )
{
Type * fun_type = fun - > GetType ( ) ;
if ( ! fun_type )
{
if ( log )
2011-10-14 20:34:21 +00:00
log - > PutCString ( " Skipped a function because it has no type " ) ;
2010-07-27 00:55:47 +00:00
return ;
}
2011-02-16 23:00:21 +00:00
fun_opaque_type = fun_type - > GetClangFullType ( ) ;
2010-07-27 00:55:47 +00:00
if ( ! fun_opaque_type )
{
if ( log )
2011-10-14 20:34:21 +00:00
log - > PutCString ( " Skipped a function because it has no Clang type " ) ;
2010-07-27 00:55:47 +00:00
return ;
}
fun_address = & fun - > GetAddressRange ( ) . GetBaseAddress ( ) ;
2011-01-17 03:46:26 +00:00
fun_ast_context = fun_type - > GetClangASTContext ( ) . getASTContext ( ) ;
2011-10-28 23:38:38 +00:00
void * copied_type = GuardedCopyType ( m_ast_context , fun_ast_context , fun_opaque_type ) ;
2011-10-20 00:47:21 +00:00
if ( copied_type )
{
fun_decl = context . AddFunDecl ( copied_type ) ;
}
else
{
// We failed to copy the type we found
if ( log )
{
2012-11-29 21:49:15 +00:00
log - > Printf ( " Failed to import the function type '%s' {0x%8.8 " PRIx64 " } into the expression parser AST contenxt " ,
2011-10-20 00:47:21 +00:00
fun_type - > GetName ( ) . GetCString ( ) ,
fun_type - > GetID ( ) ) ;
}
2011-11-16 00:40:13 +00:00
return ;
2011-10-20 00:47:21 +00:00
}
2010-07-27 00:55:47 +00:00
}
else if ( symbol )
{
2012-03-07 21:03:09 +00:00
fun_address = & symbol - > GetAddress ( ) ;
2010-07-27 00:55:47 +00:00
fun_decl = context . AddGenericFunDecl ( ) ;
}
else
{
if ( log )
2011-10-14 20:34:21 +00:00
log - > PutCString ( " AddOneFunction called with no function and no symbol " ) ;
2010-07-27 00:55:47 +00:00
return ;
}
2012-02-10 01:22:05 +00:00
Target * target = m_parser_vars - > m_exe_ctx . GetTargetPtr ( ) ;
2011-09-22 04:58:26 +00:00
lldb : : addr_t load_addr = fun_address - > GetCallableLoadAddress ( target ) ;
2010-06-22 23:46:24 +00:00
fun_location - > SetValueType ( Value : : eValueTypeLoadAddress ) ;
fun_location - > GetScalar ( ) = load_addr ;
2012-02-10 01:22:05 +00:00
ClangExpressionVariableSP entity ( m_found_entities . CreateVariable ( m_parser_vars - > m_exe_ctx . GetBestExecutionContextScope ( ) ,
2011-09-15 02:13:07 +00:00
m_parser_vars - > m_target_info . byte_order ,
m_parser_vars - > m_target_info . address_byte_size ) ) ;
2010-12-14 02:59:59 +00:00
assert ( entity . get ( ) ) ;
2010-10-15 22:48:33 +00:00
std : : string decl_name ( context . m_decl_name . getAsString ( ) ) ;
2010-12-14 02:59:59 +00:00
entity - > SetName ( ConstString ( decl_name . c_str ( ) ) ) ;
entity - > SetClangType ( fun_opaque_type ) ;
entity - > SetClangAST ( fun_ast_context ) ;
2010-06-22 23:46:24 +00:00
2010-12-14 02:59:59 +00:00
entity - > EnableParserVars ( ) ;
entity - > m_parser_vars - > m_named_decl = fun_decl ;
entity - > m_parser_vars - > m_llvm_value = NULL ;
entity - > m_parser_vars - > m_lldb_value = fun_location . release ( ) ;
2010-08-23 23:09:38 +00:00
2010-07-16 00:09:46 +00:00
if ( log )
2010-10-15 22:48:33 +00:00
{
2011-10-20 00:47:21 +00:00
ASTDumper ast_dumper ( fun_decl ) ;
2010-11-01 23:22:47 +00:00
2012-07-28 00:21:01 +00:00
StreamString ss ;
fun_address - > Dump ( & ss , m_parser_vars - > m_exe_ctx . GetBestExecutionContextScope ( ) , Address : : DumpStyleResolvedDescription ) ;
log - > Printf ( " CEDM::FEVD[%u] Found %s function %s (description %s), returned %s " ,
2011-10-14 20:34:21 +00:00
current_id ,
( fun ? " specific " : " generic " ) ,
2012-07-28 00:21:01 +00:00
decl_name . c_str ( ) ,
ss . GetData ( ) ,
2011-10-20 00:47:21 +00:00
ast_dumper . GetCString ( ) ) ;
2010-10-15 22:48:33 +00:00
}
2010-06-08 16:52:24 +00:00
}
2010-08-04 01:02:13 +00:00
void
ClangExpressionDeclMap : : AddOneType ( NameSearchContext & context ,
2010-09-21 00:44:12 +00:00
TypeFromUser & ut ,
2011-10-14 20:34:21 +00:00
unsigned int current_id ,
2010-09-21 00:44:12 +00:00
bool add_method )
2010-08-04 01:02:13 +00:00
{
2011-10-28 23:38:38 +00:00
ASTContext * parser_ast_context = m_ast_context ;
2011-07-30 02:42:06 +00:00
ASTContext * user_ast_context = ut . GetASTContext ( ) ;
2010-08-04 01:02:13 +00:00
2010-11-19 20:20:02 +00:00
void * copied_type = GuardedCopyType ( parser_ast_context , user_ast_context , ut . GetOpaqueQualType ( ) ) ;
2011-12-01 21:04:37 +00:00
if ( ! copied_type )
{
lldb : : LogSP log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_EXPRESSIONS ) ) ;
if ( log )
log - > Printf ( " ClangExpressionDeclMap::AddOneType - Couldn't import the type " ) ;
return ;
}
2011-10-29 19:50:43 +00:00
2012-03-30 00:51:13 +00:00
if ( add_method & & ClangASTContext : : IsAggregateType ( copied_type ) & & ClangASTContext : : GetCompleteType ( parser_ast_context , copied_type ) )
2010-09-21 00:44:12 +00:00
{
void * args [ 1 ] ;
args [ 0 ] = ClangASTContext : : GetVoidPtrType ( parser_ast_context , false ) ;
2011-11-01 18:07:13 +00:00
clang_type_t method_type = ClangASTContext : : CreateFunctionType ( parser_ast_context ,
ClangASTContext : : GetBuiltInType_void ( parser_ast_context ) ,
args ,
1 ,
false ,
ClangASTContext : : GetTypeQualifiers ( copied_type ) ) ;
2010-09-24 05:15:53 +00:00
const bool is_virtual = false ;
const bool is_static = false ;
const bool is_inline = false ;
2010-10-01 02:31:07 +00:00
const bool is_explicit = false ;
2011-11-02 18:09:01 +00:00
const bool is_attr_used = true ;
2011-11-02 01:38:59 +00:00
const bool is_artificial = false ;
2010-10-01 02:31:07 +00:00
2010-09-24 05:15:53 +00:00
ClangASTContext : : AddMethodToCXXRecordType ( parser_ast_context ,
copied_type ,
2010-10-15 22:48:33 +00:00
" $__lldb_expr " ,
2010-09-24 05:15:53 +00:00
method_type ,
lldb : : eAccessPublic ,
is_virtual ,
is_static ,
2010-10-01 02:31:07 +00:00
is_inline ,
2011-11-01 18:07:13 +00:00
is_explicit ,
2011-11-02 01:38:59 +00:00
is_attr_used ,
is_artificial ) ;
2010-09-21 00:44:12 +00:00
}
2010-08-04 01:02:13 +00:00
context . AddTypeDecl ( copied_type ) ;
}