2013-08-23 13:46:38 -04: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"
2015-07-03 12:57:06 -04:00
# include "clang/AST/ASTConsumer.h"
2013-08-23 13:46:38 -04:00
# include "clang/AST/ASTContext.h"
# include "clang/AST/DeclarationName.h"
# include "clang/AST/Decl.h"
# include "lldb/lldb-private.h"
# include "lldb/Core/Address.h"
# include "lldb/Core/Error.h"
# include "lldb/Core/Log.h"
# include "lldb/Core/Module.h"
2013-11-06 11:48:53 -05:00
# include "lldb/Core/ModuleSpec.h"
2013-08-23 13:46:38 -04:00
# include "lldb/Core/RegisterValue.h"
# include "lldb/Core/ValueObjectConstResult.h"
# include "lldb/Core/ValueObjectVariable.h"
# include "lldb/Expression/ASTDumper.h"
# include "lldb/Expression/ClangASTSource.h"
2015-07-03 12:57:06 -04:00
# include "lldb/Expression/ClangModulesDeclVendor.h"
2013-08-23 13:46:38 -04:00
# include "lldb/Expression/ClangPersistentVariables.h"
# include "lldb/Expression/Materializer.h"
# include "lldb/Host/Endian.h"
# include "lldb/Symbol/ClangASTContext.h"
# include "lldb/Symbol/ClangNamespaceDecl.h"
# include "lldb/Symbol/CompileUnit.h"
# include "lldb/Symbol/Function.h"
# include "lldb/Symbol/ObjectFile.h"
# include "lldb/Symbol/SymbolContext.h"
# include "lldb/Symbol/SymbolVendor.h"
# include "lldb/Symbol/Type.h"
# include "lldb/Symbol/TypeList.h"
# include "lldb/Symbol/Variable.h"
# include "lldb/Symbol/VariableList.h"
2015-02-06 16:38:51 -05:00
# include "lldb/Target/CPPLanguageRuntime.h"
2013-08-23 13:46:38 -04:00
# include "lldb/Target/ExecutionContext.h"
# include "lldb/Target/ObjCLanguageRuntime.h"
# include "lldb/Target/Process.h"
# include "lldb/Target/RegisterContext.h"
# include "lldb/Target/StackFrame.h"
# include "lldb/Target/Target.h"
# include "lldb/Target/Thread.h"
using namespace lldb ;
using namespace lldb_private ;
using namespace clang ;
ClangExpressionDeclMap : : ClangExpressionDeclMap ( bool keep_result_in_memory , ExecutionContext & exe_ctx ) :
ClangASTSource ( exe_ctx . GetTargetSP ( ) ) ,
m_found_entities ( ) ,
m_struct_members ( ) ,
m_keep_result_in_memory ( keep_result_in_memory ) ,
m_parser_vars ( ) ,
m_struct_vars ( )
{
EnableStructVars ( ) ;
}
ClangExpressionDeclMap : : ~ ClangExpressionDeclMap ( )
{
// 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
2014-11-25 16:00:58 -05:00
// that valuable lookup data (like namespaces) doesn't vanish, but
2013-08-23 13:46:38 -04:00
DidParse ( ) ;
DisableStructVars ( ) ;
}
2014-11-25 16:00:58 -05:00
bool
2013-08-23 13:46:38 -04:00
ClangExpressionDeclMap : : WillParse ( ExecutionContext & exe_ctx ,
Materializer * materializer )
{
ClangASTMetrics : : ClearLocalCounters ( ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
EnableParserVars ( ) ;
m_parser_vars - > m_exe_ctx = exe_ctx ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04: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 ( ) & & exe_ctx . GetThreadPtr ( ) - > GetStackFrameAtIndex ( 0 ) )
m_parser_vars - > m_sym_ctx = exe_ctx . GetThreadPtr ( ) - > GetStackFrameAtIndex ( 0 ) - > GetSymbolContext ( lldb : : eSymbolContextEverything ) ;
else if ( exe_ctx . GetProcessPtr ( ) )
{
m_parser_vars - > m_sym_ctx . Clear ( true ) ;
m_parser_vars - > m_sym_ctx . target_sp = exe_ctx . GetTargetSP ( ) ;
}
else if ( target )
{
m_parser_vars - > m_sym_ctx . Clear ( true ) ;
m_parser_vars - > m_sym_ctx . target_sp = exe_ctx . GetTargetSP ( ) ;
}
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( target )
{
m_parser_vars - > m_persistent_vars = & target - > GetPersistentVariables ( ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( ! target - > GetScratchClangASTContext ( ) )
return false ;
}
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
m_parser_vars - > m_target_info = GetTargetInfo ( ) ;
m_parser_vars - > m_materializer = materializer ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
return true ;
}
2015-07-03 12:57:06 -04:00
void
ClangExpressionDeclMap : : InstallCodeGenerator ( clang : : ASTConsumer * code_gen )
{
assert ( m_parser_vars ) ;
m_parser_vars - > m_code_gen = code_gen ;
}
2013-08-23 13:46:38 -04:00
void
ClangExpressionDeclMap : : DidParse ( )
{
Log * log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_EXPRESSIONS ) ) ;
if ( log )
ClangASTMetrics : : DumpCounters ( log ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( m_parser_vars . get ( ) )
{
for ( size_t entity_index = 0 , num_entities = m_found_entities . GetSize ( ) ;
entity_index < num_entities ;
+ + entity_index )
{
ClangExpressionVariableSP var_sp ( m_found_entities . GetVariableAtIndex ( entity_index ) ) ;
if ( var_sp )
var_sp - > DisableParserVars ( GetParserID ( ) ) ;
}
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
for ( size_t pvar_index = 0 , num_pvars = m_parser_vars - > m_persistent_vars - > GetSize ( ) ;
pvar_index < num_pvars ;
+ + pvar_index )
{
ClangExpressionVariableSP pvar_sp ( m_parser_vars - > m_persistent_vars - > GetVariableAtIndex ( pvar_index ) ) ;
if ( pvar_sp )
pvar_sp - > DisableParserVars ( GetParserID ( ) ) ;
}
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
DisableParserVars ( ) ;
}
}
// Interface for IRForTarget
2014-11-25 16:00:58 -05:00
ClangExpressionDeclMap : : TargetInfo
2013-08-23 13:46:38 -04:00
ClangExpressionDeclMap : : GetTargetInfo ( )
{
assert ( m_parser_vars . get ( ) ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
TargetInfo ret ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
ExecutionContext & exe_ctx = m_parser_vars - > m_exe_ctx ;
Process * process = exe_ctx . GetProcessPtr ( ) ;
if ( process )
{
ret . byte_order = process - > GetByteOrder ( ) ;
ret . address_byte_size = process - > GetAddressByteSize ( ) ;
}
2014-11-25 16:00:58 -05:00
else
2013-08-23 13:46:38 -04:00
{
Target * target = exe_ctx . GetTargetPtr ( ) ;
if ( target )
{
ret . byte_order = target - > GetArchitecture ( ) . GetByteOrder ( ) ;
ret . address_byte_size = target - > GetArchitecture ( ) . GetAddressByteSize ( ) ;
}
}
return ret ;
}
2014-11-25 16:00:58 -05:00
bool
ClangExpressionDeclMap : : AddPersistentVariable
2013-08-23 13:46:38 -04:00
(
2014-11-25 16:00:58 -05:00
const NamedDecl * decl ,
const ConstString & name ,
2013-08-23 13:46:38 -04:00
TypeFromParser parser_type ,
bool is_result ,
bool is_lvalue
)
{
assert ( m_parser_vars . get ( ) ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( m_parser_vars - > m_materializer & & is_result )
{
Error err ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
ExecutionContext & exe_ctx = m_parser_vars - > m_exe_ctx ;
Target * target = exe_ctx . GetTargetPtr ( ) ;
if ( target = = NULL )
return false ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
ASTContext * context ( target - > GetScratchClangASTContext ( ) - > getASTContext ( ) ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
TypeFromUser user_type ( m_ast_importer - > DeportType ( context ,
parser_type . GetASTContext ( ) ,
parser_type . GetOpaqueQualType ( ) ) ,
context ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
uint32_t offset = m_parser_vars - > m_materializer - > AddResultVariable ( user_type , is_lvalue , m_keep_result_in_memory , err ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
ClangExpressionVariableSP var_sp = m_found_entities . CreateVariable ( exe_ctx . GetBestExecutionContextScope ( ) ,
name ,
user_type ,
m_parser_vars - > m_target_info . byte_order ,
m_parser_vars - > m_target_info . address_byte_size ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( ! var_sp )
return false ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
var_sp - > EnableParserVars ( GetParserID ( ) ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
ClangExpressionVariable : : ParserVars * parser_vars = var_sp - > GetParserVars ( GetParserID ( ) ) ;
parser_vars - > m_named_decl = decl ;
parser_vars - > m_parser_type = parser_type ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
var_sp - > EnableJITVars ( GetParserID ( ) ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
ClangExpressionVariable : : JITVars * jit_vars = var_sp - > GetJITVars ( GetParserID ( ) ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
jit_vars - > m_offset = offset ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
return true ;
}
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
Log * log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_EXPRESSIONS ) ) ;
ExecutionContext & exe_ctx = m_parser_vars - > m_exe_ctx ;
Target * target = exe_ctx . GetTargetPtr ( ) ;
if ( target = = NULL )
return false ;
ASTContext * context ( target - > GetScratchClangASTContext ( ) - > getASTContext ( ) ) ;
2014-11-25 16:00:58 -05:00
TypeFromUser user_type ( m_ast_importer - > DeportType ( context ,
2013-08-23 13:46:38 -04:00
parser_type . GetASTContext ( ) ,
parser_type . GetOpaqueQualType ( ) ) ,
context ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( ! user_type . GetOpaqueQualType ( ) )
{
if ( log )
log - > Printf ( " Persistent variable's type wasn't copied successfully " ) ;
return false ;
}
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( ! m_parser_vars - > m_target_info . IsValid ( ) )
return false ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
ClangExpressionVariableSP var_sp = m_parser_vars - > m_persistent_vars - > CreatePersistentVariable ( exe_ctx . GetBestExecutionContextScope ( ) ,
name ,
user_type ,
m_parser_vars - > m_target_info . byte_order ,
m_parser_vars - > m_target_info . address_byte_size ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( ! var_sp )
return false ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
var_sp - > m_frozen_sp - > SetHasCompleteType ( ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( is_result )
var_sp - > m_flags | = ClangExpressionVariable : : EVNeedsFreezeDry ;
else
var_sp - > m_flags | = ClangExpressionVariable : : EVKeepInTarget ; // explicitly-declared persistent variables should persist
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( is_lvalue )
{
var_sp - > m_flags | = ClangExpressionVariable : : EVIsProgramReference ;
}
else
{
var_sp - > m_flags | = ClangExpressionVariable : : EVIsLLDBAllocated ;
var_sp - > m_flags | = ClangExpressionVariable : : EVNeedsAllocation ;
}
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( m_keep_result_in_memory )
{
var_sp - > m_flags | = ClangExpressionVariable : : EVKeepInTarget ;
}
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( log )
log - > Printf ( " Created persistent variable with flags 0x%hx " , var_sp - > m_flags ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
var_sp - > EnableParserVars ( GetParserID ( ) ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
ClangExpressionVariable : : ParserVars * parser_vars = var_sp - > GetParserVars ( GetParserID ( ) ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
parser_vars - > m_named_decl = decl ;
parser_vars - > m_parser_type = parser_type ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
return true ;
}
2014-11-25 16:00:58 -05:00
bool
ClangExpressionDeclMap : : AddValueToStruct
2013-08-23 13:46:38 -04:00
(
const NamedDecl * decl ,
const ConstString & name ,
llvm : : Value * value ,
size_t size ,
2014-11-25 16:00:58 -05:00
lldb : : offset_t alignment
2013-08-23 13:46:38 -04:00
)
{
assert ( m_struct_vars . get ( ) ) ;
assert ( m_parser_vars . get ( ) ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
bool is_persistent_variable = false ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
Log * log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_EXPRESSIONS ) ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
m_struct_vars - > m_struct_laid_out = false ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( m_struct_members . GetVariable ( decl , GetParserID ( ) ) )
return true ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
ClangExpressionVariableSP var_sp ( m_found_entities . GetVariable ( decl , GetParserID ( ) ) ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( ! var_sp )
{
var_sp = m_parser_vars - > m_persistent_vars - > GetVariable ( decl , GetParserID ( ) ) ;
is_persistent_variable = true ;
}
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( ! var_sp )
return false ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( log )
log - > Printf ( " Adding value for (NamedDecl*)%p [%s - %s] to the structure " ,
2014-11-25 16:00:58 -05:00
static_cast < const void * > ( decl ) , name . GetCString ( ) ,
2013-08-23 13:46:38 -04:00
var_sp - > GetName ( ) . GetCString ( ) ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
// We know entity->m_parser_vars is valid because we used a parser variable
// to find it
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
ClangExpressionVariable : : ParserVars * parser_vars = var_sp - > GetParserVars ( GetParserID ( ) ) ;
parser_vars - > m_llvm_value = value ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( ClangExpressionVariable : : JITVars * jit_vars = var_sp - > GetJITVars ( GetParserID ( ) ) )
{
// We already laid this out; do not touch
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( log )
log - > Printf ( " Already placed at 0x%llx " , ( unsigned long long ) jit_vars - > m_offset ) ;
}
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
var_sp - > EnableJITVars ( GetParserID ( ) ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
ClangExpressionVariable : : JITVars * jit_vars = var_sp - > GetJITVars ( GetParserID ( ) ) ;
jit_vars - > m_alignment = alignment ;
jit_vars - > m_size = size ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
m_struct_members . AddVariable ( var_sp ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( m_parser_vars - > m_materializer )
{
uint32_t offset = 0 ;
Error err ;
if ( is_persistent_variable )
{
offset = m_parser_vars - > m_materializer - > AddPersistentVariable ( var_sp , err ) ;
}
else
{
if ( const lldb_private : : Symbol * sym = parser_vars - > m_lldb_sym )
offset = m_parser_vars - > m_materializer - > AddSymbol ( * sym , err ) ;
else if ( const RegisterInfo * reg_info = var_sp - > GetRegisterInfo ( ) )
offset = m_parser_vars - > m_materializer - > AddRegister ( * reg_info , err ) ;
else if ( parser_vars - > m_lldb_var )
offset = m_parser_vars - > m_materializer - > AddVariable ( parser_vars - > m_lldb_var , err ) ;
}
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( ! err . Success ( ) )
return false ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( log )
log - > Printf ( " Placed at 0x%llx " , ( unsigned long long ) offset ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
jit_vars - > m_offset = offset ; // TODO DoStructLayout() should not change this.
}
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
return true ;
}
bool
ClangExpressionDeclMap : : DoStructLayout ( )
{
assert ( m_struct_vars . get ( ) ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( m_struct_vars - > m_struct_laid_out )
return true ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( ! m_parser_vars - > m_materializer )
return false ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
m_struct_vars - > m_struct_alignment = m_parser_vars - > m_materializer - > GetStructAlignment ( ) ;
m_struct_vars - > m_struct_size = m_parser_vars - > m_materializer - > GetStructByteSize ( ) ;
m_struct_vars - > m_struct_laid_out = true ;
return true ;
}
2014-11-25 16:00:58 -05:00
bool ClangExpressionDeclMap : : GetStructInfo
2013-08-23 13:46:38 -04:00
(
uint32_t & num_elements ,
size_t & size ,
2014-11-25 16:00:58 -05:00
lldb : : offset_t & alignment
2013-08-23 13:46:38 -04:00
)
{
assert ( m_struct_vars . get ( ) ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( ! m_struct_vars - > m_struct_laid_out )
return false ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
num_elements = m_struct_members . GetSize ( ) ;
size = m_struct_vars - > m_struct_size ;
alignment = m_struct_vars - > m_struct_alignment ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
return true ;
}
2014-11-25 16:00:58 -05:00
bool
ClangExpressionDeclMap : : GetStructElement
2013-08-23 13:46:38 -04:00
(
const NamedDecl * & decl ,
llvm : : Value * & value ,
2014-11-25 16:00:58 -05:00
lldb : : offset_t & offset ,
2013-08-23 13:46:38 -04:00
ConstString & name ,
uint32_t index
)
{
assert ( m_struct_vars . get ( ) ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( ! m_struct_vars - > m_struct_laid_out )
return false ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( index > = m_struct_members . GetSize ( ) )
return false ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
ClangExpressionVariableSP member_sp ( m_struct_members . GetVariableAtIndex ( index ) ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( ! member_sp )
return false ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
ClangExpressionVariable : : ParserVars * parser_vars = member_sp - > GetParserVars ( GetParserID ( ) ) ;
ClangExpressionVariable : : JITVars * jit_vars = member_sp - > GetJITVars ( GetParserID ( ) ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( ! parser_vars | |
! jit_vars | |
! member_sp - > GetValueObject ( ) )
return false ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
decl = parser_vars - > m_named_decl ;
value = parser_vars - > m_llvm_value ;
offset = jit_vars - > m_offset ;
name = member_sp - > GetName ( ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
return true ;
}
bool
2014-11-25 16:00:58 -05:00
ClangExpressionDeclMap : : GetFunctionInfo
2013-08-23 13:46:38 -04:00
(
2014-11-25 16:00:58 -05:00
const NamedDecl * decl ,
2013-08-23 13:46:38 -04:00
uint64_t & ptr
)
{
ClangExpressionVariableSP entity_sp ( m_found_entities . GetVariable ( decl , GetParserID ( ) ) ) ;
if ( ! entity_sp )
return false ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
// We know m_parser_vars is valid since we searched for the variable by
// its NamedDecl
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
ClangExpressionVariable : : ParserVars * parser_vars = entity_sp - > GetParserVars ( GetParserID ( ) ) ;
ptr = parser_vars - > m_lldb_value . GetScalar ( ) . ULongLong ( ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
return true ;
}
static void
FindCodeSymbolInContext
(
const ConstString & name ,
SymbolContext & sym_ctx ,
SymbolContextList & sc_list
)
{
2015-07-03 12:57:06 -04:00
sc_list . Clear ( ) ;
2013-08-23 13:46:38 -04:00
SymbolContextList temp_sc_list ;
if ( sym_ctx . module_sp )
2015-07-03 12:57:06 -04:00
sym_ctx . module_sp - > FindFunctions ( name ,
NULL ,
eFunctionNameTypeAuto ,
true , // include_symbols
false , // include_inlines
true , // append
temp_sc_list ) ;
if ( temp_sc_list . GetSize ( ) = = 0 )
{
if ( sym_ctx . target_sp )
sym_ctx . target_sp - > GetImages ( ) . FindFunctions ( name ,
eFunctionNameTypeAuto ,
true , // include_symbols
false , // include_inlines
true , // append
temp_sc_list ) ;
}
2013-08-23 13:46:38 -04:00
2015-07-03 12:57:06 -04:00
SymbolContextList internal_symbol_sc_list ;
2013-08-23 13:46:38 -04:00
unsigned temp_sc_list_size = temp_sc_list . GetSize ( ) ;
for ( unsigned i = 0 ; i < temp_sc_list_size ; i + + )
{
2015-07-03 12:57:06 -04:00
SymbolContext sc ;
temp_sc_list . GetContextAtIndex ( i , sc ) ;
if ( sc . function )
2013-08-23 13:46:38 -04:00
{
2015-07-03 12:57:06 -04:00
sc_list . Append ( sc ) ;
}
else if ( sc . symbol )
{
if ( sc . symbol - > IsExternal ( ) )
{
sc_list . Append ( sc ) ;
}
else
2013-08-23 13:46:38 -04:00
{
2015-07-03 12:57:06 -04:00
internal_symbol_sc_list . Append ( sc ) ;
2013-08-23 13:46:38 -04:00
}
}
}
2015-07-03 12:57:06 -04:00
// If we had internal symbols and we didn't find any external symbols or
// functions in debug info, then fallback to the internal symbols
if ( sc_list . GetSize ( ) = = 0 & & internal_symbol_sc_list . GetSize ( ) )
{
sc_list = internal_symbol_sc_list ;
}
2013-08-23 13:46:38 -04:00
}
bool
2014-11-25 16:00:58 -05:00
ClangExpressionDeclMap : : GetFunctionAddress
2013-08-23 13:46:38 -04:00
(
const ConstString & name ,
uint64_t & func_addr
)
{
assert ( m_parser_vars . get ( ) ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
Log * log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_EXPRESSIONS ) ) ;
ExecutionContext & exe_ctx = m_parser_vars - > m_exe_ctx ;
Target * target = exe_ctx . GetTargetPtr ( ) ;
// Back out in all cases where we're not fully initialized
if ( target = = NULL )
return false ;
if ( ! m_parser_vars - > m_sym_ctx . target_sp )
return false ;
SymbolContextList sc_list ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
FindCodeSymbolInContext ( name , m_parser_vars - > m_sym_ctx , sc_list ) ;
2013-11-06 11:48:53 -05:00
uint32_t sc_list_size = sc_list . GetSize ( ) ;
2015-02-06 16:38:51 -05:00
2013-11-06 11:48:53 -05:00
if ( sc_list_size = = 0 )
2013-08-23 13:46:38 -04:00
{
2014-11-25 16:00:58 -05:00
// We occasionally get debug information in which a const function is reported
2013-08-23 13:46:38 -04:00
// as non-const, so the mangled name is wrong. This is a hack to compensate.
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( ! strncmp ( name . GetCString ( ) , " _ZN " , 3 ) & &
strncmp ( name . GetCString ( ) , " _ZNK " , 4 ) )
{
std : : string fixed_scratch ( " _ZNK " ) ;
fixed_scratch . append ( name . GetCString ( ) + 3 ) ;
ConstString fixed_name ( fixed_scratch . c_str ( ) ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( log )
log - > Printf ( " Failed to find symbols given non-const name %s; trying %s " , name . GetCString ( ) , fixed_name . GetCString ( ) ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
FindCodeSymbolInContext ( fixed_name , m_parser_vars - > m_sym_ctx , sc_list ) ;
2013-11-06 11:48:53 -05:00
sc_list_size = sc_list . GetSize ( ) ;
2013-08-23 13:46:38 -04:00
}
}
2015-07-03 12:57:06 -04:00
lldb : : addr_t intern_callable_load_addr = LLDB_INVALID_ADDRESS ;
2013-08-23 13:46:38 -04:00
2013-11-06 11:48:53 -05:00
for ( uint32_t i = 0 ; i < sc_list_size ; + + i )
{
SymbolContext sym_ctx ;
sc_list . GetContextAtIndex ( i , sym_ctx ) ;
2013-08-23 13:46:38 -04:00
2015-07-03 12:57:06 -04:00
2014-11-25 16:00:58 -05:00
lldb : : addr_t callable_load_addr = LLDB_INVALID_ADDRESS ;
2013-11-06 11:48:53 -05:00
if ( sym_ctx . function )
{
2014-11-25 16:00:58 -05:00
const Address func_so_addr = sym_ctx . function - > GetAddressRange ( ) . GetBaseAddress ( ) ;
if ( func_so_addr . IsValid ( ) )
2013-11-06 11:48:53 -05:00
{
2014-11-25 16:00:58 -05:00
callable_load_addr = func_so_addr . GetCallableLoadAddress ( target , false ) ;
2013-11-06 11:48:53 -05:00
}
}
2014-11-25 16:00:58 -05:00
else if ( sym_ctx . symbol )
{
2015-07-03 12:57:06 -04:00
if ( sym_ctx . symbol - > IsExternal ( ) )
callable_load_addr = sym_ctx . symbol - > ResolveCallableAddress ( * target ) ;
else
{
if ( intern_callable_load_addr = = LLDB_INVALID_ADDRESS )
intern_callable_load_addr = sym_ctx . symbol - > ResolveCallableAddress ( * target ) ;
}
2014-11-25 16:00:58 -05:00
}
2013-08-23 13:46:38 -04:00
2014-11-25 16:00:58 -05:00
if ( callable_load_addr ! = LLDB_INVALID_ADDRESS )
2013-11-06 11:48:53 -05:00
{
2014-11-25 16:00:58 -05:00
func_addr = callable_load_addr ;
return true ;
2013-11-06 11:48:53 -05:00
}
}
2015-07-03 12:57:06 -04:00
// See if we found an internal symbol
if ( intern_callable_load_addr ! = LLDB_INVALID_ADDRESS )
{
func_addr = intern_callable_load_addr ;
return true ;
}
2013-11-06 11:48:53 -05:00
return false ;
2013-08-23 13:46:38 -04:00
}
addr_t
2013-11-06 11:48:53 -05:00
ClangExpressionDeclMap : : GetSymbolAddress ( Target & target ,
Process * process ,
const ConstString & name ,
lldb : : SymbolType symbol_type ,
lldb_private : : Module * module )
2013-08-23 13:46:38 -04:00
{
SymbolContextList sc_list ;
2014-11-25 16:00:58 -05:00
2013-11-06 11:48:53 -05:00
if ( module )
module - > FindSymbolsWithNameAndType ( name , symbol_type , sc_list ) ;
else
target . GetImages ( ) . FindSymbolsWithNameAndType ( name , symbol_type , sc_list ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
const uint32_t num_matches = sc_list . GetSize ( ) ;
addr_t symbol_load_addr = LLDB_INVALID_ADDRESS ;
for ( uint32_t i = 0 ; i < num_matches & & ( symbol_load_addr = = 0 | | symbol_load_addr = = LLDB_INVALID_ADDRESS ) ; i + + )
{
SymbolContext sym_ctx ;
sc_list . GetContextAtIndex ( i , sym_ctx ) ;
2014-11-25 16:00:58 -05:00
2015-07-03 12:57:06 -04:00
const Address sym_address = sym_ctx . symbol - > GetAddress ( ) ;
2014-11-25 16:00:58 -05:00
2015-07-03 12:57:06 -04:00
if ( ! sym_address . IsValid ( ) )
2013-08-23 13:46:38 -04:00
continue ;
2014-11-25 16:00:58 -05:00
2015-07-03 12:57:06 -04:00
switch ( sym_ctx . symbol - > GetType ( ) )
2013-08-23 13:46:38 -04:00
{
2015-07-03 12:57:06 -04:00
case eSymbolTypeCode :
case eSymbolTypeTrampoline :
symbol_load_addr = sym_address . GetCallableLoadAddress ( & target ) ;
break ;
2013-08-23 13:46:38 -04:00
2015-07-03 12:57:06 -04:00
case eSymbolTypeResolver :
symbol_load_addr = sym_address . GetCallableLoadAddress ( & target , true ) ;
break ;
2013-08-23 13:46:38 -04:00
2015-07-03 12:57:06 -04:00
case eSymbolTypeReExported :
{
ConstString reexport_name = sym_ctx . symbol - > GetReExportedSymbolName ( ) ;
if ( reexport_name )
2013-11-06 11:48:53 -05:00
{
2015-07-03 12:57:06 -04:00
ModuleSP reexport_module_sp ;
ModuleSpec reexport_module_spec ;
reexport_module_spec . GetPlatformFileSpec ( ) = sym_ctx . symbol - > GetReExportedSymbolSharedLibrary ( ) ;
if ( reexport_module_spec . GetPlatformFileSpec ( ) )
2013-11-06 11:48:53 -05:00
{
2015-07-03 12:57:06 -04:00
reexport_module_sp = target . GetImages ( ) . FindFirstModule ( reexport_module_spec ) ;
if ( ! reexport_module_sp )
2013-11-06 11:48:53 -05:00
{
2015-07-03 12:57:06 -04:00
reexport_module_spec . GetPlatformFileSpec ( ) . GetDirectory ( ) . Clear ( ) ;
2013-11-06 11:48:53 -05:00
reexport_module_sp = target . GetImages ( ) . FindFirstModule ( reexport_module_spec ) ;
}
}
2015-07-03 12:57:06 -04:00
symbol_load_addr = GetSymbolAddress ( target , process , sym_ctx . symbol - > GetReExportedSymbolName ( ) , symbol_type , reexport_module_sp . get ( ) ) ;
2013-11-06 11:48:53 -05:00
}
2015-07-03 12:57:06 -04:00
}
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 :
case eSymbolTypeObjCClass :
case eSymbolTypeObjCMetaClass :
case eSymbolTypeObjCIVar :
symbol_load_addr = sym_address . GetLoadAddress ( & target ) ;
break ;
2013-08-23 13:46:38 -04:00
}
}
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( symbol_load_addr = = LLDB_INVALID_ADDRESS & & process )
{
ObjCLanguageRuntime * runtime = process - > GetObjCLanguageRuntime ( ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( runtime )
{
symbol_load_addr = runtime - > LookupRuntimeSymbol ( name ) ;
}
}
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
return symbol_load_addr ;
}
addr_t
ClangExpressionDeclMap : : GetSymbolAddress ( const ConstString & name , lldb : : SymbolType symbol_type )
{
assert ( m_parser_vars . get ( ) ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( ! m_parser_vars - > m_exe_ctx . GetTargetPtr ( ) )
return false ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
return GetSymbolAddress ( m_parser_vars - > m_exe_ctx . GetTargetRef ( ) , m_parser_vars - > m_exe_ctx . GetProcessPtr ( ) , name , symbol_type ) ;
}
const Symbol *
ClangExpressionDeclMap : : FindGlobalDataSymbol ( Target & target ,
2013-11-06 11:48:53 -05:00
const ConstString & name ,
lldb_private : : Module * module )
2013-08-23 13:46:38 -04:00
{
SymbolContextList sc_list ;
2014-11-25 16:00:58 -05:00
2013-11-06 11:48:53 -05:00
if ( module )
module - > FindSymbolsWithNameAndType ( name , eSymbolTypeAny , sc_list ) ;
else
target . GetImages ( ) . FindSymbolsWithNameAndType ( name , eSymbolTypeAny , sc_list ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
const uint32_t matches = sc_list . GetSize ( ) ;
for ( uint32_t i = 0 ; i < matches ; + + i )
{
SymbolContext sym_ctx ;
sc_list . GetContextAtIndex ( i , sym_ctx ) ;
if ( sym_ctx . symbol )
{
const Symbol * symbol = sym_ctx . symbol ;
2015-07-03 12:57:06 -04:00
const Address sym_address = symbol - > GetAddress ( ) ;
2014-11-25 16:00:58 -05:00
2015-07-03 12:57:06 -04:00
if ( sym_address . IsValid ( ) )
2013-08-23 13:46:38 -04:00
{
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 ;
2013-11-06 11:48:53 -05:00
case eSymbolTypeReExported :
{
ConstString reexport_name = symbol - > GetReExportedSymbolName ( ) ;
if ( reexport_name )
{
ModuleSP reexport_module_sp ;
ModuleSpec reexport_module_spec ;
reexport_module_spec . GetPlatformFileSpec ( ) = symbol - > GetReExportedSymbolSharedLibrary ( ) ;
if ( reexport_module_spec . GetPlatformFileSpec ( ) )
{
reexport_module_sp = target . GetImages ( ) . FindFirstModule ( reexport_module_spec ) ;
if ( ! reexport_module_sp )
{
reexport_module_spec . GetPlatformFileSpec ( ) . GetDirectory ( ) . Clear ( ) ;
reexport_module_sp = target . GetImages ( ) . FindFirstModule ( reexport_module_spec ) ;
}
}
2015-07-03 12:57:06 -04:00
// Don't allow us to try and resolve a re-exported symbol if it is the same
// as the current symbol
if ( name = = symbol - > GetReExportedSymbolName ( ) & & module = = reexport_module_sp . get ( ) )
return NULL ;
2013-11-06 11:48:53 -05:00
return FindGlobalDataSymbol ( target , symbol - > GetReExportedSymbolName ( ) , reexport_module_sp . get ( ) ) ;
}
}
break ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
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 :
case eSymbolTypeResolver :
break ;
}
}
}
}
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
return NULL ;
}
lldb : : VariableSP
ClangExpressionDeclMap : : FindGlobalVariable
(
Target & target ,
ModuleSP & module ,
const ConstString & name ,
ClangNamespaceDecl * namespace_decl ,
TypeFromUser * type
)
{
VariableList vars ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( module & & namespace_decl )
module - > FindGlobalVariables ( name , namespace_decl , true , - 1 , vars ) ;
else
target . GetImages ( ) . FindGlobalVariables ( name , true , - 1 , vars ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( vars . GetSize ( ) )
{
if ( type )
{
for ( size_t i = 0 ; i < vars . GetSize ( ) ; + + i )
{
VariableSP var_sp = vars . GetVariableAtIndex ( i ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( ClangASTContext : : AreTypesSame ( * type , var_sp - > GetType ( ) - > GetClangFullType ( ) ) )
return var_sp ;
}
}
else
{
return vars . GetVariableAtIndex ( 0 ) ;
}
}
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
return VariableSP ( ) ;
}
// Interface for ClangASTSource
void
ClangExpressionDeclMap : : FindExternalVisibleDecls ( NameSearchContext & context )
{
assert ( m_ast_context ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
ClangASTMetrics : : RegisterVisibleQuery ( ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
const ConstString name ( context . m_decl_name . getAsString ( ) . c_str ( ) ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
Log * log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_EXPRESSIONS ) ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( GetImportInProgress ( ) )
{
if ( log & & log - > GetVerbose ( ) )
log - > Printf ( " Ignoring a query during an import " ) ;
return ;
}
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
static unsigned int invocation_id = 0 ;
unsigned int current_id = invocation_id + + ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( log )
{
if ( ! context . m_decl_context )
log - > Printf ( " ClangExpressionDeclMap::FindExternalVisibleDecls[%u] for '%s' in a NULL DeclContext " , current_id , name . GetCString ( ) ) ;
else if ( const NamedDecl * context_named_decl = dyn_cast < NamedDecl > ( context . m_decl_context ) )
log - > Printf ( " ClangExpressionDeclMap::FindExternalVisibleDecls[%u] for '%s' in '%s' " , current_id , name . GetCString ( ) , context_named_decl - > getNameAsString ( ) . c_str ( ) ) ;
else
log - > Printf ( " ClangExpressionDeclMap::FindExternalVisibleDecls[%u] for '%s' in a '%s' " , current_id , name . GetCString ( ) , context . m_decl_context - > getDeclKindName ( ) ) ;
}
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( const NamespaceDecl * namespace_context = dyn_cast < NamespaceDecl > ( context . m_decl_context ) )
{
ClangASTImporter : : NamespaceMapSP namespace_map = m_ast_importer - > GetNamespaceMap ( namespace_context ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( log & & log - > GetVerbose ( ) )
2014-11-25 16:00:58 -05:00
log - > Printf ( " CEDM::FEVD[%u] Inspecting (NamespaceMap*)%p (%d entries) " ,
current_id , static_cast < void * > ( namespace_map . get ( ) ) ,
2013-08-23 13:46:38 -04:00
( int ) namespace_map - > size ( ) ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( ! namespace_map )
return ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
for ( ClangASTImporter : : NamespaceMap : : iterator i = namespace_map - > begin ( ) , e = namespace_map - > end ( ) ;
i ! = e ;
+ + i )
{
if ( log )
log - > Printf ( " CEDM::FEVD[%u] Searching namespace %s in module %s " ,
current_id ,
i - > second . GetNamespaceDecl ( ) - > getNameAsString ( ) . c_str ( ) ,
i - > first - > GetFileSpec ( ) . GetFilename ( ) . GetCString ( ) ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
FindExternalVisibleDecls ( context ,
i - > first ,
i - > second ,
current_id ) ;
}
}
else if ( isa < TranslationUnitDecl > ( context . m_decl_context ) )
{
ClangNamespaceDecl namespace_decl ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( log )
log - > Printf ( " CEDM::FEVD[%u] Searching the root namespace " , current_id ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
FindExternalVisibleDecls ( context ,
lldb : : ModuleSP ( ) ,
namespace_decl ,
current_id ) ;
}
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( ! context . m_found . variable )
ClangASTSource : : FindExternalVisibleDecls ( context ) ;
}
2014-11-25 16:00:58 -05:00
void
ClangExpressionDeclMap : : FindExternalVisibleDecls ( NameSearchContext & context ,
2013-08-23 13:46:38 -04:00
lldb : : ModuleSP module_sp ,
ClangNamespaceDecl & namespace_decl ,
unsigned int current_id )
{
assert ( m_ast_context ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
Log * log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_EXPRESSIONS ) ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
SymbolContextList sc_list ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
const ConstString name ( context . m_decl_name . getAsString ( ) . c_str ( ) ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
const char * name_unique_cstr = name . GetCString ( ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( name_unique_cstr = = NULL )
return ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
static ConstString id_name ( " id " ) ;
static ConstString Class_name ( " Class " ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( name = = id_name | | name = = Class_name )
return ;
2014-11-25 16:00:58 -05:00
// Only look for functions by name out in our symbols if the function
2013-08-23 13:46:38 -04:00
// doesn't start with our phony prefix of '$'
Target * target = m_parser_vars - > m_exe_ctx . GetTargetPtr ( ) ;
StackFrame * frame = m_parser_vars - > m_exe_ctx . GetFramePtr ( ) ;
if ( name_unique_cstr [ 0 ] = = ' $ ' & & ! namespace_decl )
{
static ConstString g_lldb_class_name ( " $__lldb_class " ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( name = = g_lldb_class_name )
{
// Clang is looking for the type of "this"
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( frame = = NULL )
return ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
SymbolContext sym_ctx = frame - > GetSymbolContext ( lldb : : eSymbolContextFunction ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( ! sym_ctx . function )
return ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04: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 ( ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( ! decl_context )
return ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
clang : : CXXMethodDecl * method_decl = llvm : : dyn_cast < clang : : CXXMethodDecl > ( decl_context ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( method_decl )
{
clang : : CXXRecordDecl * class_decl = method_decl - > getParent ( ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
QualType class_qual_type ( class_decl - > getTypeForDecl ( ) , 0 ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
TypeFromUser class_user_type ( class_qual_type . getAsOpaquePtr ( ) ,
& class_decl - > getASTContext ( ) ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( log )
{
ASTDumper ast_dumper ( class_qual_type ) ;
log - > Printf ( " CEDM::FEVD[%u] Adding type for $__lldb_class: %s " , current_id , ast_dumper . GetCString ( ) ) ;
}
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
TypeFromParser class_type = CopyClassType ( class_user_type , current_id ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( ! class_type . IsValid ( ) )
return ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
TypeSourceInfo * type_source_info = m_ast_context - > getTrivialTypeSourceInfo ( QualType : : getFromOpaquePtr ( class_type . GetOpaqueQualType ( ) ) ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( ! type_source_info )
return ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
TypedefDecl * typedef_decl = TypedefDecl : : Create ( * m_ast_context ,
m_ast_context - > getTranslationUnitDecl ( ) ,
SourceLocation ( ) ,
SourceLocation ( ) ,
context . m_decl_name . getAsIdentifierInfo ( ) ,
type_source_info ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( ! typedef_decl )
return ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
context . AddNamedDecl ( typedef_decl ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( method_decl - > isInstance ( ) )
{
// self is a pointer to the object
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
QualType class_pointer_type = method_decl - > getASTContext ( ) . getPointerType ( class_qual_type ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
TypeFromUser self_user_type ( class_pointer_type . getAsOpaquePtr ( ) ,
& method_decl - > getASTContext ( ) ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
m_struct_vars - > m_object_pointer_type = self_user_type ;
}
}
else
{
// 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
2015-07-03 12:57:06 -04:00
// method of the class. In that case, just look up the "this" variable in the current
2013-08-23 13:46:38 -04:00
// 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.
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
VariableList * vars = frame - > GetVariableList ( false ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
lldb : : VariableSP this_var = vars - > FindVariable ( ConstString ( " this " ) ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( this_var & &
this_var - > IsInScope ( frame ) & &
this_var - > LocationIsValidForFrame ( frame ) )
{
Type * this_type = this_var - > GetType ( ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( ! this_type )
return ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
ClangASTType pointee_type = this_type - > GetClangForwardType ( ) . GetPointeeType ( ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( pointee_type . IsValid ( ) )
{
if ( log )
{
ASTDumper ast_dumper ( this_type - > GetClangFullType ( ) ) ;
log - > Printf ( " FEVD[%u] Adding type for $__lldb_objc_class: %s " , current_id , ast_dumper . GetCString ( ) ) ;
}
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
TypeFromUser class_user_type ( pointee_type ) ;
AddOneType ( context , class_user_type , current_id ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
TypeFromUser this_user_type ( this_type - > GetClangFullType ( ) ) ;
m_struct_vars - > m_object_pointer_type = this_user_type ;
return ;
}
}
}
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
return ;
}
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
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"
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( ! frame )
return ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
SymbolContext sym_ctx = frame - > GetSymbolContext ( lldb : : eSymbolContextFunction ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( ! sym_ctx . function )
return ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
// Get the block that defines the function
Block * function_block = sym_ctx . GetFunctionBlock ( ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( ! function_block )
return ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
clang : : DeclContext * decl_context = function_block - > GetClangDeclContext ( ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( ! decl_context )
return ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
clang : : ObjCMethodDecl * method_decl = llvm : : dyn_cast < clang : : ObjCMethodDecl > ( decl_context ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( method_decl )
{
ObjCInterfaceDecl * self_interface = method_decl - > getClassInterface ( ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( ! self_interface )
return ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
const clang : : Type * interface_type = self_interface - > getTypeForDecl ( ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( ! interface_type )
return ; // This is unlikely, but we have seen crashes where this occurred
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
TypeFromUser class_user_type ( QualType ( interface_type , 0 ) . getAsOpaquePtr ( ) ,
& method_decl - > getASTContext ( ) ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( log )
{
ASTDumper ast_dumper ( interface_type ) ;
log - > Printf ( " FEVD[%u] Adding type for $__lldb_objc_class: %s " , current_id , ast_dumper . GetCString ( ) ) ;
}
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
AddOneType ( context , class_user_type , current_id ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( method_decl - > isInstanceMethod ( ) )
{
// self is a pointer to the object
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
QualType class_pointer_type = method_decl - > getASTContext ( ) . getObjCObjectPointerType ( QualType ( interface_type , 0 ) ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
TypeFromUser self_user_type ( class_pointer_type . getAsOpaquePtr ( ) ,
& method_decl - > getASTContext ( ) ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
m_struct_vars - > m_object_pointer_type = self_user_type ;
}
else
{
// self is a Class pointer
QualType class_type = method_decl - > getASTContext ( ) . getObjCClassType ( ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
TypeFromUser self_user_type ( class_type . getAsOpaquePtr ( ) ,
& method_decl - > getASTContext ( ) ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
m_struct_vars - > m_object_pointer_type = self_user_type ;
}
return ;
}
else
{
// 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
2015-07-03 12:57:06 -04:00
// method of the class. In that case, just look up the "self" variable in the current
2013-08-23 13:46:38 -04:00
// scope and use its type.
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
VariableList * vars = frame - > GetVariableList ( false ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
lldb : : VariableSP self_var = vars - > FindVariable ( ConstString ( " self " ) ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( self_var & &
2014-11-25 16:00:58 -05:00
self_var - > IsInScope ( frame ) & &
2013-08-23 13:46:38 -04:00
self_var - > LocationIsValidForFrame ( frame ) )
{
Type * self_type = self_var - > GetType ( ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( ! self_type )
return ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
ClangASTType self_clang_type = self_type - > GetClangFullType ( ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( self_clang_type . IsObjCClassType ( ) )
{
return ;
}
else if ( self_clang_type . IsObjCObjectPointerType ( ) )
{
self_clang_type = self_clang_type . GetPointeeType ( ) ;
if ( ! self_clang_type )
return ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( log )
{
ASTDumper ast_dumper ( self_type - > GetClangFullType ( ) ) ;
log - > Printf ( " FEVD[%u] Adding type for $__lldb_objc_class: %s " , current_id , ast_dumper . GetCString ( ) ) ;
}
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
TypeFromUser class_user_type ( self_clang_type ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
AddOneType ( context , class_user_type , current_id ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
TypeFromUser self_user_type ( self_type - > GetClangFullType ( ) ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
m_struct_vars - > m_object_pointer_type = self_user_type ;
return ;
}
}
}
return ;
}
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
// any other $__lldb names should be weeded out now
if ( ! : : strncmp ( name_unique_cstr , " $__lldb " , sizeof ( " $__lldb " ) - 1 ) )
return ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
do
{
if ( ! target )
break ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
ClangASTContext * scratch_clang_ast_context = target - > GetScratchClangASTContext ( ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( ! scratch_clang_ast_context )
break ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
ASTContext * scratch_ast_context = scratch_clang_ast_context - > getASTContext ( ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( ! scratch_ast_context )
break ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
TypeDecl * ptype_type_decl = m_parser_vars - > m_persistent_vars - > GetPersistentType ( name ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( ! ptype_type_decl )
break ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
Decl * parser_ptype_decl = m_ast_importer - > CopyDecl ( m_ast_context , scratch_ast_context , ptype_type_decl ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( ! parser_ptype_decl )
break ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
TypeDecl * parser_ptype_type_decl = dyn_cast < TypeDecl > ( parser_ptype_decl ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( ! parser_ptype_type_decl )
break ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( log )
log - > Printf ( " CEDM::FEVD[%u] Found persistent type %s " , current_id , name . GetCString ( ) ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
context . AddNamedDecl ( parser_ptype_type_decl ) ;
} while ( 0 ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
ClangExpressionVariableSP pvar_sp ( m_parser_vars - > m_persistent_vars - > GetVariable ( name ) ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( pvar_sp )
{
AddOneVariable ( context , pvar_sp , current_id ) ;
return ;
}
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
const char * reg_name ( & name . GetCString ( ) [ 1 ] ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( m_parser_vars - > m_exe_ctx . GetRegisterContext ( ) )
{
const RegisterInfo * reg_info ( m_parser_vars - > m_exe_ctx . GetRegisterContext ( ) - > GetRegisterInfoByName ( reg_name ) ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( reg_info )
{
if ( log )
log - > Printf ( " CEDM::FEVD[%u] Found register %s " , current_id , reg_info - > name ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
AddOneRegister ( context , reg_info , current_id ) ;
}
}
}
else
{
ValueObjectSP valobj ;
VariableSP var ;
Error err ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( frame & & ! namespace_decl )
{
2014-11-25 16:00:58 -05:00
valobj = frame - > GetValueForVariableExpressionPath ( name_unique_cstr ,
eNoDynamicValues ,
2015-02-06 16:38:51 -05:00
StackFrame : : eExpressionPathOptionCheckPtrVsMember |
StackFrame : : eExpressionPathOptionsNoFragileObjcIvar |
StackFrame : : eExpressionPathOptionsNoSyntheticChildren |
2013-08-23 13:46:38 -04:00
StackFrame : : eExpressionPathOptionsNoSyntheticArrayRange ,
var ,
err ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
// If we found a variable in scope, no need to pull up function names
if ( err . Success ( ) & & var )
{
AddOneVariable ( context , var , valobj , current_id ) ;
context . m_found . variable = true ;
return ;
}
}
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( target )
{
var = FindGlobalVariable ( * target ,
module_sp ,
name ,
& namespace_decl ,
NULL ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( var )
{
valobj = ValueObjectVariable : : Create ( target , var ) ;
AddOneVariable ( context , var , valobj , current_id ) ;
context . m_found . variable = true ;
return ;
}
}
2015-02-06 16:38:51 -05:00
std : : vector < clang : : NamedDecl * > decls_from_modules ;
if ( target )
{
if ( ClangModulesDeclVendor * decl_vendor = target - > GetClangModulesDeclVendor ( ) )
{
decl_vendor - > FindDecls ( name , false , UINT32_MAX , decls_from_modules ) ;
}
}
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( ! context . m_found . variable )
{
const bool include_inlines = false ;
const bool append = false ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( namespace_decl & & module_sp )
{
const bool include_symbols = false ;
module_sp - > FindFunctions ( name ,
& namespace_decl ,
2014-11-25 16:00:58 -05:00
eFunctionNameTypeBase ,
2013-08-23 13:46:38 -04:00
include_symbols ,
include_inlines ,
append ,
sc_list ) ;
}
else if ( target & & ! namespace_decl )
{
const bool include_symbols = true ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
// TODO Fix FindFunctions so that it doesn't return
// instance methods for eFunctionNameTypeBase.
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
target - > GetImages ( ) . FindFunctions ( name ,
eFunctionNameTypeFull ,
include_symbols ,
include_inlines ,
2014-11-25 16:00:58 -05:00
append ,
2013-08-23 13:46:38 -04:00
sc_list ) ;
}
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( sc_list . GetSize ( ) )
{
2013-11-06 11:48:53 -05:00
Symbol * extern_symbol = NULL ;
2013-08-23 13:46:38 -04:00
Symbol * non_extern_symbol = NULL ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
for ( uint32_t index = 0 , num_indices = sc_list . GetSize ( ) ;
index < num_indices ;
+ + index )
{
SymbolContext sym_ctx ;
sc_list . GetContextAtIndex ( index , sym_ctx ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( sym_ctx . function )
{
clang : : DeclContext * decl_ctx = sym_ctx . function - > GetClangDeclContext ( ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( ! decl_ctx )
continue ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
// Filter out class/instance methods.
if ( dyn_cast < clang : : ObjCMethodDecl > ( decl_ctx ) )
continue ;
if ( dyn_cast < clang : : CXXMethodDecl > ( decl_ctx ) )
continue ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
AddOneFunction ( context , sym_ctx . function , NULL , current_id ) ;
context . m_found . function_with_type_info = true ;
context . m_found . function = true ;
}
else if ( sym_ctx . symbol )
{
2014-11-25 16:00:58 -05:00
if ( sym_ctx . symbol - > GetType ( ) = = eSymbolTypeReExported & & target )
2013-11-06 11:48:53 -05:00
{
sym_ctx . symbol = sym_ctx . symbol - > ResolveReExportedSymbol ( * target ) ;
if ( sym_ctx . symbol = = NULL )
continue ;
}
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( sym_ctx . symbol - > IsExternal ( ) )
2013-11-06 11:48:53 -05:00
extern_symbol = sym_ctx . symbol ;
2013-08-23 13:46:38 -04:00
else
non_extern_symbol = sym_ctx . symbol ;
}
}
2015-02-06 16:38:51 -05:00
if ( ! context . m_found . function_with_type_info )
{
for ( clang : : NamedDecl * decl : decls_from_modules )
{
if ( llvm : : isa < clang : : FunctionDecl > ( decl ) )
{
clang : : NamedDecl * copied_decl = llvm : : cast < FunctionDecl > ( m_ast_importer - > CopyDecl ( m_ast_context , & decl - > getASTContext ( ) , decl ) ) ;
context . AddNamedDecl ( copied_decl ) ;
context . m_found . function_with_type_info = true ;
}
}
}
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( ! context . m_found . function_with_type_info )
{
2013-11-06 11:48:53 -05:00
if ( extern_symbol )
2013-08-23 13:46:38 -04:00
{
2013-11-06 11:48:53 -05:00
AddOneFunction ( context , NULL , extern_symbol , current_id ) ;
2013-08-23 13:46:38 -04:00
context . m_found . function = true ;
}
else if ( non_extern_symbol )
{
AddOneFunction ( context , NULL , non_extern_symbol , current_id ) ;
context . m_found . function = true ;
}
}
}
2015-07-03 12:57:06 -04:00
if ( ! context . m_found . function_with_type_info )
{
// Try the modules next.
do
{
if ( ClangModulesDeclVendor * modules_decl_vendor = m_target - > GetClangModulesDeclVendor ( ) )
{
bool append = false ;
uint32_t max_matches = 1 ;
std : : vector < clang : : NamedDecl * > decls ;
if ( ! modules_decl_vendor - > FindDecls ( name ,
append ,
max_matches ,
decls ) )
break ;
clang : : NamedDecl * const decl_from_modules = decls [ 0 ] ;
if ( llvm : : isa < clang : : FunctionDecl > ( decl_from_modules ) )
{
if ( log )
{
log - > Printf ( " CAS::FEVD[%u] Matching function found for \" %s \" in the modules " ,
current_id ,
name . GetCString ( ) ) ;
}
clang : : Decl * copied_decl = m_ast_importer - > CopyDecl ( m_ast_context , & decl_from_modules - > getASTContext ( ) , decl_from_modules ) ;
clang : : FunctionDecl * copied_function_decl = copied_decl ? dyn_cast < clang : : FunctionDecl > ( copied_decl ) : nullptr ;
if ( ! copied_function_decl )
{
if ( log )
log - > Printf ( " CAS::FEVD[%u] - Couldn't export a function declaration from the modules " ,
current_id ) ;
break ;
}
if ( copied_function_decl - > getBody ( ) & & m_parser_vars - > m_code_gen )
{
DeclGroupRef decl_group_ref ( copied_function_decl ) ;
m_parser_vars - > m_code_gen - > HandleTopLevelDecl ( decl_group_ref ) ;
}
context . AddNamedDecl ( copied_function_decl ) ;
context . m_found . function_with_type_info = true ;
context . m_found . function = true ;
}
2015-09-06 10:32:30 -04:00
else if ( llvm : : isa < clang : : VarDecl > ( decl_from_modules ) )
{
if ( log )
{
log - > Printf ( " CAS::FEVD[%u] Matching variable found for \" %s \" in the modules " ,
current_id ,
name . GetCString ( ) ) ;
}
clang : : Decl * copied_decl = m_ast_importer - > CopyDecl ( m_ast_context , & decl_from_modules - > getASTContext ( ) , decl_from_modules ) ;
clang : : VarDecl * copied_var_decl = copied_decl ? dyn_cast_or_null < clang : : VarDecl > ( copied_decl ) : nullptr ;
if ( ! copied_var_decl )
{
if ( log )
log - > Printf ( " CAS::FEVD[%u] - Couldn't export a variable declaration from the modules " ,
current_id ) ;
break ;
}
context . AddNamedDecl ( copied_var_decl ) ;
context . m_found . variable = true ;
}
2015-07-03 12:57:06 -04:00
}
} while ( 0 ) ;
}
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( target & & ! context . m_found . variable & & ! namespace_decl )
{
2014-11-25 16:00:58 -05:00
// We couldn't find a non-symbol variable for this. Now we'll hunt for a generic
2013-08-23 13:46:38 -04:00
// data symbol, and -- if it is found -- treat it as a variable.
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
const Symbol * data_symbol = FindGlobalDataSymbol ( * target , name ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( data_symbol )
{
2014-02-25 16:42:16 -05:00
std : : string warning ( " got name from symbols: " ) ;
warning . append ( name . AsCString ( ) ) ;
const unsigned diag_id = m_ast_context - > getDiagnostics ( ) . getCustomDiagID ( clang : : DiagnosticsEngine : : Level : : Warning , " %0 " ) ;
m_ast_context - > getDiagnostics ( ) . Report ( diag_id ) < < warning . c_str ( ) ;
2013-08-23 13:46:38 -04:00
AddOneGenericVariable ( context , * data_symbol , current_id ) ;
context . m_found . variable = true ;
}
}
}
}
}
2014-11-25 16:00:58 -05: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();
//}
2013-08-23 13:46:38 -04:00
bool
ClangExpressionDeclMap : : GetVariableValue ( VariableSP & var ,
lldb_private : : Value & var_location ,
TypeFromUser * user_type ,
TypeFromParser * parser_type )
{
Log * log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_EXPRESSIONS ) ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
Type * var_type = var - > GetType ( ) ;
2014-11-25 16:00:58 -05:00
if ( ! var_type )
2013-08-23 13:46:38 -04:00
{
if ( log )
log - > PutCString ( " Skipped a definition because it has no type " ) ;
return false ;
}
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
ClangASTType var_clang_type = var_type - > GetClangFullType ( ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( ! var_clang_type )
{
if ( log )
log - > PutCString ( " Skipped a definition because it has no Clang type " ) ;
return false ;
}
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
ASTContext * ast = var_type - > GetClangASTContext ( ) . getASTContext ( ) ;
if ( ! ast )
{
if ( log )
log - > PutCString ( " There is no AST context for the current execution context " ) ;
return false ;
}
//var_clang_type = MaybePromoteToBlockPointerType (ast, var_clang_type);
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
DWARFExpression & var_location_expr = var - > LocationExpression ( ) ;
2014-11-25 16:00:58 -05:00
Target * target = m_parser_vars - > m_exe_ctx . GetTargetPtr ( ) ;
2013-08-23 13:46:38 -04:00
Error err ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( var - > GetLocationIsConstantValueData ( ) )
{
DataExtractor const_value_extractor ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( var_location_expr . GetExpressionData ( const_value_extractor ) )
{
var_location = Value ( const_value_extractor . GetDataStart ( ) , const_value_extractor . GetByteSize ( ) ) ;
var_location . SetValueType ( Value : : eValueTypeHostAddress ) ;
}
else
{
if ( log )
log - > Printf ( " Error evaluating constant variable: %s " , err . AsCString ( ) ) ;
return false ;
}
}
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
ClangASTType type_to_use = GuardedCopyType ( var_clang_type ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( ! type_to_use )
{
if ( log )
log - > Printf ( " Couldn't copy a variable's type into the parser's AST context " ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
return false ;
}
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( parser_type )
* parser_type = TypeFromParser ( type_to_use ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( var_location . GetContextType ( ) = = Value : : eContextTypeInvalid )
var_location . SetClangType ( type_to_use ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( var_location . GetValueType ( ) = = Value : : eValueTypeFileAddress )
{
SymbolContext var_sc ;
var - > CalculateSymbolContext ( & var_sc ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( ! var_sc . module_sp )
return false ;
Address so_addr ( var_location . GetScalar ( ) . ULongLong ( ) , var_sc . module_sp - > GetSectionList ( ) ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
lldb : : addr_t load_addr = so_addr . GetLoadAddress ( target ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( load_addr ! = LLDB_INVALID_ADDRESS )
{
var_location . GetScalar ( ) = load_addr ;
var_location . SetValueType ( Value : : eValueTypeLoadAddress ) ;
}
}
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( user_type )
* user_type = TypeFromUser ( var_clang_type ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
return true ;
}
void
ClangExpressionDeclMap : : AddOneVariable ( NameSearchContext & context , VariableSP var , ValueObjectSP valobj , unsigned int current_id )
{
assert ( m_parser_vars . get ( ) ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
Log * log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_EXPRESSIONS ) ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
TypeFromUser ut ;
TypeFromParser pt ;
Value var_location ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( ! GetVariableValue ( var , var_location , & ut , & pt ) )
return ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
clang : : QualType parser_opaque_type = QualType : : getFromOpaquePtr ( pt . GetOpaqueQualType ( ) ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( parser_opaque_type . isNull ( ) )
return ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04: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 ( ) ) ;
2014-02-18 11:23:10 -05:00
if ( const ObjCObjectPointerType * objc_object_ptr_type = dyn_cast < ObjCObjectPointerType > ( parser_type ) )
CompleteType ( objc_object_ptr_type - > getInterfaceDecl ( ) ) ;
2013-08-23 13:46:38 -04:00
}
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
bool is_reference = pt . IsReferenceType ( ) ;
NamedDecl * var_decl = NULL ;
if ( is_reference )
var_decl = context . AddVarDecl ( pt ) ;
else
var_decl = context . AddVarDecl ( pt . GetLValueReferenceType ( ) ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
std : : string decl_name ( context . m_decl_name . getAsString ( ) ) ;
ConstString entity_name ( decl_name . c_str ( ) ) ;
ClangExpressionVariableSP entity ( m_found_entities . CreateVariable ( valobj ) ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
assert ( entity . get ( ) ) ;
entity - > EnableParserVars ( GetParserID ( ) ) ;
ClangExpressionVariable : : ParserVars * parser_vars = entity - > GetParserVars ( GetParserID ( ) ) ;
parser_vars - > m_parser_type = pt ;
parser_vars - > m_named_decl = var_decl ;
parser_vars - > m_llvm_value = NULL ;
parser_vars - > m_lldb_value = var_location ;
parser_vars - > m_lldb_var = var ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( is_reference )
entity - > m_flags | = ClangExpressionVariable : : EVTypeIsReference ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( log )
{
ASTDumper orig_dumper ( ut . GetOpaqueQualType ( ) ) ;
2014-11-25 16:00:58 -05:00
ASTDumper ast_dumper ( var_decl ) ;
2013-08-23 13:46:38 -04: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 ( ) ) ;
}
}
void
ClangExpressionDeclMap : : AddOneVariable ( NameSearchContext & context ,
2014-11-25 16:00:58 -05:00
ClangExpressionVariableSP & pvar_sp ,
2013-08-23 13:46:38 -04:00
unsigned int current_id )
{
Log * log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_EXPRESSIONS ) ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
TypeFromUser user_type ( pvar_sp - > GetTypeFromUser ( ) ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
TypeFromParser parser_type ( GuardedCopyType ( user_type ) ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04: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 ;
}
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
NamedDecl * var_decl = context . AddVarDecl ( parser_type . GetLValueReferenceType ( ) ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
pvar_sp - > EnableParserVars ( GetParserID ( ) ) ;
ClangExpressionVariable : : ParserVars * parser_vars = pvar_sp - > GetParserVars ( GetParserID ( ) ) ;
parser_vars - > m_parser_type = parser_type ;
parser_vars - > m_named_decl = var_decl ;
parser_vars - > m_llvm_value = NULL ;
parser_vars - > m_lldb_value . Clear ( ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( log )
{
ASTDumper ast_dumper ( var_decl ) ;
log - > Printf ( " CEDM::FEVD[%u] Added pvar %s, returned %s " , current_id , pvar_sp - > GetName ( ) . GetCString ( ) , ast_dumper . GetCString ( ) ) ;
}
}
void
2014-11-25 16:00:58 -05:00
ClangExpressionDeclMap : : AddOneGenericVariable ( NameSearchContext & context ,
2013-08-23 13:46:38 -04:00
const Symbol & symbol ,
unsigned int current_id )
{
assert ( m_parser_vars . get ( ) ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
Log * log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_EXPRESSIONS ) ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
Target * target = m_parser_vars - > m_exe_ctx . GetTargetPtr ( ) ;
if ( target = = NULL )
return ;
ASTContext * scratch_ast_context = target - > GetScratchClangASTContext ( ) - > getASTContext ( ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
TypeFromUser user_type ( ClangASTContext : : GetBasicType ( scratch_ast_context , eBasicTypeVoid ) . GetPointerType ( ) . GetLValueReferenceType ( ) ) ;
TypeFromParser parser_type ( ClangASTContext : : GetBasicType ( m_ast_context , eBasicTypeVoid ) . GetPointerType ( ) . GetLValueReferenceType ( ) ) ;
NamedDecl * var_decl = context . AddVarDecl ( parser_type ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
std : : string decl_name ( context . m_decl_name . getAsString ( ) ) ;
ConstString entity_name ( decl_name . c_str ( ) ) ;
ClangExpressionVariableSP entity ( m_found_entities . CreateVariable ( m_parser_vars - > m_exe_ctx . GetBestExecutionContextScope ( ) ,
2014-11-25 16:00:58 -05:00
entity_name ,
2013-08-23 13:46:38 -04:00
user_type ,
m_parser_vars - > m_target_info . byte_order ,
m_parser_vars - > m_target_info . address_byte_size ) ) ;
assert ( entity . get ( ) ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
entity - > EnableParserVars ( GetParserID ( ) ) ;
ClangExpressionVariable : : ParserVars * parser_vars = entity - > GetParserVars ( GetParserID ( ) ) ;
2015-07-03 12:57:06 -04:00
const Address symbol_address = symbol . GetAddress ( ) ;
2013-08-23 13:46:38 -04:00
lldb : : addr_t symbol_load_addr = symbol_address . GetLoadAddress ( target ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
//parser_vars->m_lldb_value.SetContext(Value::eContextTypeClangType, user_type.GetOpaqueQualType());
parser_vars - > m_lldb_value . SetClangType ( user_type ) ;
parser_vars - > m_lldb_value . GetScalar ( ) = symbol_load_addr ;
parser_vars - > m_lldb_value . SetValueType ( Value : : eValueTypeLoadAddress ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
parser_vars - > m_parser_type = parser_type ;
parser_vars - > m_named_decl = var_decl ;
parser_vars - > m_llvm_value = NULL ;
parser_vars - > m_lldb_sym = & symbol ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( log )
{
ASTDumper ast_dumper ( var_decl ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
log - > Printf ( " CEDM::FEVD[%u] Found variable %s, returned %s " , current_id , decl_name . c_str ( ) , ast_dumper . GetCString ( ) ) ;
}
}
2014-11-25 16:00:58 -05:00
bool
2013-08-23 13:46:38 -04:00
ClangExpressionDeclMap : : ResolveUnknownTypes ( )
{
Log * log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_EXPRESSIONS ) ) ;
Target * target = m_parser_vars - > m_exe_ctx . GetTargetPtr ( ) ;
ASTContext * scratch_ast_context = target - > GetScratchClangASTContext ( ) - > getASTContext ( ) ;
for ( size_t index = 0 , num_entities = m_found_entities . GetSize ( ) ;
index < num_entities ;
+ + index )
{
ClangExpressionVariableSP entity = m_found_entities . GetVariableAtIndex ( index ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
ClangExpressionVariable : : ParserVars * parser_vars = entity - > GetParserVars ( GetParserID ( ) ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( entity - > m_flags & ClangExpressionVariable : : EVUnknownType )
{
const NamedDecl * named_decl = parser_vars - > m_named_decl ;
const VarDecl * var_decl = dyn_cast < VarDecl > ( named_decl ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( ! var_decl )
{
if ( log )
log - > Printf ( " Entity of unknown type does not have a VarDecl " ) ;
return false ;
}
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( log )
{
ASTDumper ast_dumper ( const_cast < VarDecl * > ( var_decl ) ) ;
log - > Printf ( " Variable of unknown type now has Decl %s " , ast_dumper . GetCString ( ) ) ;
}
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
QualType var_type = var_decl - > getType ( ) ;
TypeFromParser parser_type ( var_type . getAsOpaquePtr ( ) , & var_decl - > getASTContext ( ) ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
lldb : : clang_type_t copied_type = m_ast_importer - > CopyType ( scratch_ast_context , & var_decl - > getASTContext ( ) , var_type . getAsOpaquePtr ( ) ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( ! copied_type )
2014-11-25 16:00:58 -05:00
{
2013-08-23 13:46:38 -04:00
if ( log )
log - > Printf ( " ClangExpressionDeclMap::ResolveUnknownType - Couldn't import the type for a variable " ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
return ( bool ) lldb : : ClangExpressionVariableSP ( ) ;
}
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
TypeFromUser user_type ( copied_type , scratch_ast_context ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
// parser_vars->m_lldb_value.SetContext(Value::eContextTypeClangType, user_type.GetOpaqueQualType());
parser_vars - > m_lldb_value . SetClangType ( user_type ) ;
parser_vars - > m_parser_type = parser_type ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
entity - > SetClangType ( user_type ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
entity - > m_flags & = ~ ( ClangExpressionVariable : : EVUnknownType ) ;
}
}
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
return true ;
}
void
ClangExpressionDeclMap : : AddOneRegister ( NameSearchContext & context ,
2014-11-25 16:00:58 -05:00
const RegisterInfo * reg_info ,
2013-08-23 13:46:38 -04:00
unsigned int current_id )
{
Log * log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_EXPRESSIONS ) ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
ClangASTType clang_type = ClangASTContext : : GetBuiltinTypeForEncodingAndBitSize ( m_ast_context ,
reg_info - > encoding ,
reg_info - > byte_size * 8 ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( ! clang_type )
{
if ( log )
log - > Printf ( " Tried to add a type for %s, but couldn't get one " , context . m_decl_name . getAsString ( ) . c_str ( ) ) ;
return ;
}
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
TypeFromParser parser_clang_type ( clang_type ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
NamedDecl * var_decl = context . AddVarDecl ( parser_clang_type ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
ClangExpressionVariableSP entity ( m_found_entities . CreateVariable ( m_parser_vars - > m_exe_ctx . GetBestExecutionContextScope ( ) ,
m_parser_vars - > m_target_info . byte_order ,
m_parser_vars - > m_target_info . address_byte_size ) ) ;
assert ( entity . get ( ) ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
std : : string decl_name ( context . m_decl_name . getAsString ( ) ) ;
entity - > SetName ( ConstString ( decl_name . c_str ( ) ) ) ;
entity - > SetRegisterInfo ( reg_info ) ;
entity - > EnableParserVars ( GetParserID ( ) ) ;
ClangExpressionVariable : : ParserVars * parser_vars = entity - > GetParserVars ( GetParserID ( ) ) ;
parser_vars - > m_parser_type = parser_clang_type ;
parser_vars - > m_named_decl = var_decl ;
parser_vars - > m_llvm_value = NULL ;
parser_vars - > m_lldb_value . Clear ( ) ;
entity - > m_flags | = ClangExpressionVariable : : EVBareRegister ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( log )
{
ASTDumper ast_dumper ( var_decl ) ;
log - > Printf ( " CEDM::FEVD[%d] Added register %s, returned %s " , current_id , context . m_decl_name . getAsString ( ) . c_str ( ) , ast_dumper . GetCString ( ) ) ;
}
}
void
ClangExpressionDeclMap : : AddOneFunction ( NameSearchContext & context ,
Function * function ,
Symbol * symbol ,
unsigned int current_id )
{
assert ( m_parser_vars . get ( ) ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
Log * log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_EXPRESSIONS ) ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
NamedDecl * function_decl = NULL ;
2015-07-03 12:57:06 -04:00
Address fun_address ;
2013-08-23 13:46:38 -04:00
ClangASTType function_clang_type ;
bool is_indirect_function = false ;
if ( function )
{
Type * function_type = function - > GetType ( ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( ! function_type )
{
if ( log )
log - > PutCString ( " Skipped a function because it has no type " ) ;
return ;
}
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
function_clang_type = function_type - > GetClangFullType ( ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( ! function_clang_type )
{
if ( log )
log - > PutCString ( " Skipped a function because it has no Clang type " ) ;
return ;
}
2014-11-25 16:00:58 -05:00
2015-07-03 12:57:06 -04:00
fun_address = function - > GetAddressRange ( ) . GetBaseAddress ( ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
ClangASTType copied_function_type = GuardedCopyType ( function_clang_type ) ;
if ( copied_function_type )
{
function_decl = context . AddFunDecl ( copied_function_type ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( ! function_decl )
{
if ( log )
{
log - > Printf ( " Failed to create a function decl for '%s' {0x%8.8 " PRIx64 " } " ,
function_type - > GetName ( ) . GetCString ( ) ,
function_type - > GetID ( ) ) ;
}
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
return ;
}
}
else
{
// We failed to copy the type we found
if ( log )
{
log - > Printf ( " Failed to import the function type '%s' {0x%8.8 " PRIx64 " } into the expression parser AST contenxt " ,
function_type - > GetName ( ) . GetCString ( ) ,
function_type - > GetID ( ) ) ;
}
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
return ;
}
}
else if ( symbol )
{
2015-07-03 12:57:06 -04:00
fun_address = symbol - > GetAddress ( ) ;
2013-08-23 13:46:38 -04:00
function_decl = context . AddGenericFunDecl ( ) ;
is_indirect_function = symbol - > IsIndirect ( ) ;
}
else
{
if ( log )
log - > PutCString ( " AddOneFunction called with no function and no symbol " ) ;
return ;
}
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
Target * target = m_parser_vars - > m_exe_ctx . GetTargetPtr ( ) ;
2015-07-03 12:57:06 -04:00
lldb : : addr_t load_addr = fun_address . GetCallableLoadAddress ( target , is_indirect_function ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
ClangExpressionVariableSP entity ( m_found_entities . CreateVariable ( m_parser_vars - > m_exe_ctx . GetBestExecutionContextScope ( ) ,
m_parser_vars - > m_target_info . byte_order ,
m_parser_vars - > m_target_info . address_byte_size ) ) ;
assert ( entity . get ( ) ) ;
std : : string decl_name ( context . m_decl_name . getAsString ( ) ) ;
entity - > SetName ( ConstString ( decl_name . c_str ( ) ) ) ;
entity - > SetClangType ( function_clang_type ) ;
entity - > EnableParserVars ( GetParserID ( ) ) ;
ClangExpressionVariable : : ParserVars * parser_vars = entity - > GetParserVars ( GetParserID ( ) ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( load_addr ! = LLDB_INVALID_ADDRESS )
{
parser_vars - > m_lldb_value . SetValueType ( Value : : eValueTypeLoadAddress ) ;
parser_vars - > m_lldb_value . GetScalar ( ) = load_addr ;
}
else
{
// We have to try finding a file address.
2014-11-25 16:00:58 -05:00
2015-07-03 12:57:06 -04:00
lldb : : addr_t file_addr = fun_address . GetFileAddress ( ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
parser_vars - > m_lldb_value . SetValueType ( Value : : eValueTypeFileAddress ) ;
parser_vars - > m_lldb_value . GetScalar ( ) = file_addr ;
}
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
parser_vars - > m_named_decl = function_decl ;
parser_vars - > m_llvm_value = NULL ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( log )
{
ASTDumper ast_dumper ( function_decl ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
StreamString ss ;
2014-11-25 16:00:58 -05:00
2015-07-03 12:57:06 -04:00
fun_address . Dump ( & ss , m_parser_vars - > m_exe_ctx . GetBestExecutionContextScope ( ) , Address : : DumpStyleResolvedDescription ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
log - > Printf ( " CEDM::FEVD[%u] Found %s function %s (description %s), returned %s " ,
current_id ,
( function ? " specific " : " generic " ) ,
decl_name . c_str ( ) ,
ss . GetData ( ) ,
ast_dumper . GetCString ( ) ) ;
}
}
TypeFromParser
ClangExpressionDeclMap : : CopyClassType ( TypeFromUser & ut ,
unsigned int current_id )
{
ClangASTType copied_clang_type = GuardedCopyType ( ut ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( ! copied_clang_type )
{
Log * log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_EXPRESSIONS ) ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( log )
log - > Printf ( " ClangExpressionDeclMap::CopyClassType - Couldn't import the type " ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
return TypeFromParser ( ) ;
}
if ( copied_clang_type . IsAggregateType ( ) & & copied_clang_type . GetCompleteType ( ) )
{
ClangASTType void_clang_type = ClangASTContext : : GetBasicType ( m_ast_context , eBasicTypeVoid ) ;
ClangASTType void_ptr_clang_type = void_clang_type . GetPointerType ( ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
ClangASTType method_type = ClangASTContext : : CreateFunctionType ( m_ast_context ,
void_clang_type ,
& void_ptr_clang_type ,
1 ,
false ,
copied_clang_type . GetTypeQualifiers ( ) ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
const bool is_virtual = false ;
const bool is_static = false ;
const bool is_inline = false ;
const bool is_explicit = false ;
const bool is_attr_used = true ;
const bool is_artificial = false ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
copied_clang_type . AddMethodToCXXRecordType ( " $__lldb_expr " ,
method_type ,
lldb : : eAccessPublic ,
is_virtual ,
is_static ,
is_inline ,
is_explicit ,
is_attr_used ,
is_artificial ) ;
}
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
return TypeFromParser ( copied_clang_type ) ;
}
2014-11-25 16:00:58 -05:00
void
ClangExpressionDeclMap : : AddOneType ( NameSearchContext & context ,
2013-08-23 13:46:38 -04:00
TypeFromUser & ut ,
unsigned int current_id )
{
ClangASTType copied_clang_type = GuardedCopyType ( ut ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
if ( ! copied_clang_type )
{
Log * log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_EXPRESSIONS ) ) ;
if ( log )
log - > Printf ( " ClangExpressionDeclMap::AddOneType - Couldn't import the type " ) ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
return ;
}
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
context . AddTypeDecl ( copied_clang_type ) ;
}