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"
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"
2013-10-21 18:40:51 +00:00
# include "lldb/Core/ModuleSpec.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"
2013-04-11 00:09:05 +00:00
# include "lldb/Expression/Materializer.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"
2013-11-04 09:33:30 +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
2014-07-06 17:54:58 +00:00
// that valuable lookup data (like namespaces) doesn't vanish, but
2011-10-12 22:20:02 +00:00
DidParse ( ) ;
2010-12-03 01:38:59 +00:00
DisableStructVars ( ) ;
}
2010-10-26 00:31:56 +00:00
2014-07-06 17:54:58 +00:00
bool
2013-04-11 00:09:05 +00:00
ClangExpressionDeclMap : : WillParse ( ExecutionContext & exe_ctx ,
Materializer * materializer )
2013-03-08 20:04:57 +00:00
{
ClangASTMetrics : : ClearLocalCounters ( ) ;
2014-07-06 17:54:58 +00:00
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 ;
2014-07-06 17:54:58 +00:00
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 ) ;
2013-02-21 22:01:43 +00:00
else if ( exe_ctx . GetThreadPtr ( ) & & exe_ctx . GetThreadPtr ( ) - > GetStackFrameAtIndex ( 0 ) )
2011-09-22 04:58:26 +00:00
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
{
2013-02-23 04:12:47 +00:00
m_parser_vars - > m_sym_ctx . Clear ( true ) ;
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
{
2013-02-23 04:12:47 +00:00
m_parser_vars - > m_sym_ctx . Clear ( true ) ;
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
}
2014-07-06 17:54:58 +00:00
2011-09-22 04:58:26 +00:00
if ( target )
{
m_parser_vars - > m_persistent_vars = & target - > GetPersistentVariables ( ) ;
2014-07-06 17:54:58 +00:00
2011-09-22 04:58:26 +00:00
if ( ! target - > GetScratchClangASTContext ( ) )
return false ;
}
2014-07-06 17:54:58 +00:00
2011-09-15 02:13:07 +00:00
m_parser_vars - > m_target_info = GetTargetInfo ( ) ;
2013-04-11 00:09:05 +00:00
m_parser_vars - > m_materializer = materializer ;
2014-07-06 17:54:58 +00:00
2011-08-01 18:18:33 +00:00
return true ;
2010-12-03 01:38:59 +00:00
}
2013-04-11 00:09:05 +00:00
void
2010-12-14 02:59:59 +00:00
ClangExpressionDeclMap : : DidParse ( )
2010-12-03 01:38:59 +00:00
{
2013-03-27 23:08:40 +00:00
Log * log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_EXPRESSIONS ) ) ;
2013-03-08 20:04:57 +00:00
if ( log )
ClangASTMetrics : : DumpCounters ( log ) ;
2014-07-06 17:54:58 +00:00
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 )
2013-01-15 23:29:36 +00:00
var_sp - > DisableParserVars ( GetParserID ( ) ) ;
2010-12-03 01:38:59 +00:00
}
2014-07-06 17:54:58 +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 )
2013-01-15 23:29:36 +00:00
pvar_sp - > DisableParserVars ( GetParserID ( ) ) ;
2010-12-03 01:38:59 +00:00
}
2014-07-06 17:54:58 +00:00
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
2014-07-06 17:54:58 +00:00
ClangExpressionDeclMap : : TargetInfo
2011-09-15 02:13:07 +00:00
ClangExpressionDeclMap : : GetTargetInfo ( )
{
assert ( m_parser_vars . get ( ) ) ;
2014-07-06 17:54:58 +00:00
2011-09-15 02:13:07 +00:00
TargetInfo ret ;
2014-07-06 17:54:58 +00:00
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 ( ) ;
}
2014-07-06 17:54:58 +00:00
else
2012-02-10 01:22:05 +00:00
{
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 ;
}
2014-07-06 17:54:58 +00:00
bool
ClangExpressionDeclMap : : AddPersistentVariable
2010-10-15 22:48:33 +00:00
(
2014-07-06 17:54:58 +00:00
const NamedDecl * decl ,
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 ( ) ) ;
2014-07-06 17:54:58 +00:00
2013-04-18 22:06:33 +00:00
if ( m_parser_vars - > m_materializer & & is_result )
{
Error err ;
2014-07-06 17:54:58 +00:00
2013-04-18 22:06:33 +00:00
ExecutionContext & exe_ctx = m_parser_vars - > m_exe_ctx ;
Target * target = exe_ctx . GetTargetPtr ( ) ;
if ( target = = NULL )
return false ;
2014-07-06 17:54:58 +00:00
2013-04-18 22:06:33 +00:00
ASTContext * context ( target - > GetScratchClangASTContext ( ) - > getASTContext ( ) ) ;
2014-07-06 17:54:58 +00:00
2013-04-18 22:06:33 +00:00
TypeFromUser user_type ( m_ast_importer - > DeportType ( context ,
parser_type . GetASTContext ( ) ,
parser_type . GetOpaqueQualType ( ) ) ,
context ) ;
2014-07-06 17:54:58 +00:00
2013-04-18 22:06:33 +00:00
uint32_t offset = m_parser_vars - > m_materializer - > AddResultVariable ( user_type , is_lvalue , m_keep_result_in_memory , err ) ;
2014-07-06 17:54:58 +00:00
2013-07-15 18:43:36 +00: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-07-06 17:54:58 +00:00
2013-04-18 22:06:33 +00:00
if ( ! var_sp )
return false ;
2014-07-06 17:54:58 +00:00
2013-04-18 22:06:33 +00:00
var_sp - > EnableParserVars ( GetParserID ( ) ) ;
2014-07-06 17:54:58 +00:00
2013-04-18 22:06:33 +00:00
ClangExpressionVariable : : ParserVars * parser_vars = var_sp - > GetParserVars ( GetParserID ( ) ) ;
parser_vars - > m_named_decl = decl ;
parser_vars - > m_parser_type = parser_type ;
2014-07-06 17:54:58 +00:00
2013-04-18 22:06:33 +00:00
var_sp - > EnableJITVars ( GetParserID ( ) ) ;
2014-07-06 17:54:58 +00:00
2013-04-18 22:06:33 +00:00
ClangExpressionVariable : : JITVars * jit_vars = var_sp - > GetJITVars ( GetParserID ( ) ) ;
2014-07-06 17:54:58 +00:00
2013-04-18 22:06:33 +00:00
jit_vars - > m_offset = offset ;
2014-07-06 17:54:58 +00:00
2013-04-18 22:06:33 +00:00
return true ;
}
2014-07-06 17:54:58 +00:00
2013-03-27 23:08:40 +00:00
Log * 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 ( ) ) ;
2014-07-06 17:54:58 +00:00
TypeFromUser user_type ( m_ast_importer - > DeportType ( context ,
2011-12-16 21:06:35 +00:00
parser_type . GetASTContext ( ) ,
parser_type . GetOpaqueQualType ( ) ) ,
2011-01-13 21:23:32 +00:00
context ) ;
2014-07-06 17:54:58 +00:00
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 ;
}
2014-07-06 17:54:58 +00:00
2011-09-15 02:13:07 +00:00
if ( ! m_parser_vars - > m_target_info . IsValid ( ) )
return false ;
2014-07-06 17:54:58 +00:00
2013-07-15 18:43:36 +00: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-07-06 17:54:58 +00:00
2010-12-14 02:59:59 +00:00
if ( ! var_sp )
2010-08-23 23:09:38 +00:00
return false ;
2014-07-06 17:54:58 +00:00
2012-09-20 23:21:16 +00:00
var_sp - > m_frozen_sp - > SetHasCompleteType ( ) ;
2014-07-06 17:54:58 +00:00
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
2014-07-06 17:54:58 +00:00
2011-01-13 08:53:35 +00:00
if ( is_lvalue )
{
var_sp - > m_flags | = ClangExpressionVariable : : EVIsProgramReference ;
}
else
{
var_sp - > m_flags | = ClangExpressionVariable : : EVIsLLDBAllocated ;
var_sp - > m_flags | = ClangExpressionVariable : : EVNeedsAllocation ;
}
2014-07-06 17:54:58 +00:00
2013-04-12 18:10:34 +00:00
if ( m_keep_result_in_memory )
{
var_sp - > m_flags | = ClangExpressionVariable : : EVKeepInTarget ;
}
2014-07-06 17:54:58 +00:00
2011-01-13 08:53:35 +00:00
if ( log )
log - > Printf ( " Created persistent variable with flags 0x%hx " , var_sp - > m_flags ) ;
2014-07-06 17:54:58 +00:00
2013-01-15 23:29:36 +00:00
var_sp - > EnableParserVars ( GetParserID ( ) ) ;
2014-07-06 17:54:58 +00:00
2013-01-15 23:29:36 +00:00
ClangExpressionVariable : : ParserVars * parser_vars = var_sp - > GetParserVars ( GetParserID ( ) ) ;
2014-07-06 17:54:58 +00:00
2013-01-15 23:29:36 +00:00
parser_vars - > m_named_decl = decl ;
parser_vars - > m_parser_type = parser_type ;
2014-07-06 17:54:58 +00:00
2010-08-23 23:09:38 +00:00
return true ;
2010-08-11 03:57:18 +00:00
}
2014-07-06 17:54:58 +00:00
bool
ClangExpressionDeclMap : : AddValueToStruct
2010-10-15 22:48:33 +00:00
(
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 ,
2014-07-02 17:24:07 +00:00
lldb : : offset_t alignment
2010-10-15 22:48:33 +00:00
)
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 ( ) ) ;
2014-04-04 04:06:10 +00:00
2013-04-11 02:05:11 +00:00
bool is_persistent_variable = false ;
2014-04-04 04:06:10 +00:00
2013-03-27 23:08:40 +00:00
Log * log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_EXPRESSIONS ) ) ;
2014-04-04 04:06:10 +00:00
2010-12-03 01:38:59 +00:00
m_struct_vars - > m_struct_laid_out = false ;
2014-04-04 04:06:10 +00:00
2013-01-15 23:29:36 +00:00
if ( m_struct_members . GetVariable ( decl , GetParserID ( ) ) )
2010-08-23 23:09:38 +00:00
return true ;
2014-04-04 04:06:10 +00:00
2013-01-15 23:29:36 +00:00
ClangExpressionVariableSP var_sp ( m_found_entities . GetVariable ( decl , GetParserID ( ) ) ) ;
2014-04-04 04:06:10 +00:00
2010-12-14 02:59:59 +00:00
if ( ! var_sp )
2013-04-11 02:05:11 +00:00
{
2013-01-15 23:29:36 +00:00
var_sp = m_parser_vars - > m_persistent_vars - > GetVariable ( decl , GetParserID ( ) ) ;
2013-04-11 02:05:11 +00:00
is_persistent_variable = true ;
}
2014-04-04 04:06:10 +00:00
2010-12-14 02:59:59 +00:00
if ( ! var_sp )
2010-08-23 23:09:38 +00:00
return false ;
2014-04-04 04:06:10 +00:00
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 " ,
2014-04-04 04:06:10 +00:00
static_cast < const void * > ( decl ) , name . GetCString ( ) ,
2010-12-14 02:59:59 +00:00
var_sp - > GetName ( ) . GetCString ( ) ) ;
2014-04-04 04:06:10 +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
2014-04-04 04:06:10 +00:00
2013-01-15 23:29:36 +00:00
ClangExpressionVariable : : ParserVars * parser_vars = var_sp - > GetParserVars ( GetParserID ( ) ) ;
parser_vars - > m_llvm_value = value ;
2014-04-04 04:06:10 +00:00
2013-04-18 22:06:33 +00:00
if ( ClangExpressionVariable : : JITVars * jit_vars = var_sp - > GetJITVars ( GetParserID ( ) ) )
{
// We already laid this out; do not touch
2014-04-04 04:06:10 +00:00
2013-04-18 22:06:33 +00:00
if ( log )
log - > Printf ( " Already placed at 0x%llx " , ( unsigned long long ) jit_vars - > m_offset ) ;
}
2014-04-04 04:06:10 +00:00
2013-01-15 23:29:36 +00:00
var_sp - > EnableJITVars ( GetParserID ( ) ) ;
2014-04-04 04:06:10 +00:00
2013-01-15 23:29:36 +00:00
ClangExpressionVariable : : JITVars * jit_vars = var_sp - > GetJITVars ( GetParserID ( ) ) ;
jit_vars - > m_alignment = alignment ;
jit_vars - > m_size = size ;
2014-04-04 04:06:10 +00:00
2010-12-14 02:59:59 +00:00
m_struct_members . AddVariable ( var_sp ) ;
2014-04-04 04:06:10 +00:00
2013-04-11 02:05:11 +00:00
if ( m_parser_vars - > m_materializer )
{
2013-04-11 21:16:36 +00:00
uint32_t offset = 0 ;
2013-04-11 02:05:11 +00:00
Error err ;
if ( is_persistent_variable )
{
2013-04-11 21:16:36 +00:00
offset = m_parser_vars - > m_materializer - > AddPersistentVariable ( var_sp , err ) ;
2013-04-11 02:05:11 +00:00
}
else
{
if ( const lldb_private : : Symbol * sym = parser_vars - > m_lldb_sym )
2013-04-11 21:16:36 +00:00
offset = m_parser_vars - > m_materializer - > AddSymbol ( * sym , err ) ;
2013-04-11 02:05:11 +00:00
else if ( const RegisterInfo * reg_info = var_sp - > GetRegisterInfo ( ) )
2013-04-11 21:16:36 +00:00
offset = m_parser_vars - > m_materializer - > AddRegister ( * reg_info , err ) ;
2013-04-11 02:05:11 +00:00
else if ( parser_vars - > m_lldb_var )
2013-04-11 21:16:36 +00:00
offset = m_parser_vars - > m_materializer - > AddVariable ( parser_vars - > m_lldb_var , err ) ;
2013-04-11 02:05:11 +00:00
}
2014-04-04 04:06:10 +00:00
2013-04-11 21:16:36 +00:00
if ( ! err . Success ( ) )
return false ;
2014-04-04 04:06:10 +00:00
2013-04-11 21:16:36 +00:00
if ( log )
log - > Printf ( " Placed at 0x%llx " , ( unsigned long long ) offset ) ;
2014-04-04 04:06:10 +00:00
2013-04-11 21:16:36 +00:00
jit_vars - > m_offset = offset ; // TODO DoStructLayout() should not change this.
2013-04-11 02:05:11 +00:00
}
2014-04-04 04:06:10 +00:00
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 ( ) ) ;
2014-07-06 17:54:58 +00:00
2010-12-03 01:38:59 +00:00
if ( m_struct_vars - > m_struct_laid_out )
2010-07-13 21:41:46 +00:00
return true ;
2014-07-06 17:54:58 +00:00
2013-04-16 23:25:35 +00:00
if ( ! m_parser_vars - > m_materializer )
return false ;
2014-07-06 17:54:58 +00:00
2013-04-16 23:25:35 +00: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 ( ) ;
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 ;
}
2014-07-06 17:54:58 +00:00
bool ClangExpressionDeclMap : : GetStructInfo
2010-10-15 22:48:33 +00:00
(
uint32_t & num_elements ,
size_t & size ,
2014-07-02 17:24:07 +00:00
lldb : : offset_t & alignment
2010-10-15 22:48:33 +00:00
)
2010-07-13 21:41:46 +00:00
{
2010-12-03 01:38:59 +00:00
assert ( m_struct_vars . get ( ) ) ;
2014-07-06 17:54:58 +00:00
2010-12-03 01:38:59 +00:00
if ( ! m_struct_vars - > m_struct_laid_out )
2010-07-13 21:41:46 +00:00
return false ;
2014-07-06 17:54:58 +00:00
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 ;
2014-07-06 17:54:58 +00:00
2010-07-13 21:41:46 +00:00
return true ;
}
2014-07-06 17:54:58 +00:00
bool
ClangExpressionDeclMap : : GetStructElement
2010-10-15 22:48:33 +00:00
(
2011-07-30 02:42:06 +00:00
const NamedDecl * & decl ,
2010-10-15 22:48:33 +00:00
llvm : : Value * & value ,
2014-07-02 17:24:07 +00:00
lldb : : offset_t & offset ,
2010-10-15 22:48:33 +00:00
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 ( ) ) ;
2014-07-06 17:54:58 +00:00
2010-12-03 01:38:59 +00:00
if ( ! m_struct_vars - > m_struct_laid_out )
2010-07-13 21:41:46 +00:00
return false ;
2014-07-06 17:54:58 +00:00
2010-12-14 02:59:59 +00:00
if ( index > = m_struct_members . GetSize ( ) )
2010-07-13 21:41:46 +00:00
return false ;
2014-07-06 17:54:58 +00:00
2010-12-14 02:59:59 +00:00
ClangExpressionVariableSP member_sp ( m_struct_members . GetVariableAtIndex ( index ) ) ;
2014-07-06 17:54:58 +00:00
2013-01-15 23:29:36 +00:00
if ( ! member_sp )
return false ;
2014-07-06 17:54:58 +00:00
2013-01-15 23:29:36 +00:00
ClangExpressionVariable : : ParserVars * parser_vars = member_sp - > GetParserVars ( GetParserID ( ) ) ;
ClangExpressionVariable : : JITVars * jit_vars = member_sp - > GetJITVars ( GetParserID ( ) ) ;
2014-07-06 17:54:58 +00:00
2013-01-15 23:29:36 +00:00
if ( ! parser_vars | |
! jit_vars | |
2012-04-12 16:58:26 +00:00
! member_sp - > GetValueObject ( ) )
2010-08-23 23:09:38 +00:00
return false ;
2014-07-06 17:54:58 +00:00
2013-01-15 23:29:36 +00:00
decl = parser_vars - > m_named_decl ;
value = parser_vars - > m_llvm_value ;
offset = jit_vars - > m_offset ;
2010-12-14 02:59:59 +00:00
name = member_sp - > GetName ( ) ;
2014-07-06 17:54:58 +00:00
2010-07-13 21:41:46 +00:00
return true ;
}
2010-07-27 21:39:39 +00:00
bool
2014-07-06 17:54:58 +00:00
ClangExpressionDeclMap : : GetFunctionInfo
2010-10-15 22:48:33 +00:00
(
2014-07-06 17:54:58 +00:00
const NamedDecl * decl ,
2010-10-15 22:48:33 +00:00
uint64_t & ptr
)
2010-07-27 02:07:53 +00:00
{
2013-01-15 23:29:36 +00:00
ClangExpressionVariableSP entity_sp ( m_found_entities . GetVariable ( decl , GetParserID ( ) ) ) ;
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 ;
2014-07-06 17:54:58 +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
2014-07-06 17:54:58 +00:00
2013-01-15 23:29:36 +00:00
ClangExpressionVariable : : ParserVars * parser_vars = entity_sp - > GetParserVars ( GetParserID ( ) ) ;
2013-07-11 22:46:58 +00:00
ptr = parser_vars - > m_lldb_value . GetScalar ( ) . ULongLong ( ) ;
2014-07-06 17:54:58 +00:00
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
)
{
2013-02-27 20:13:38 +00:00
SymbolContextList temp_sc_list ;
2011-08-16 18:09:29 +00:00
if ( sym_ctx . module_sp )
2013-02-27 20:13:38 +00:00
sym_ctx . module_sp - > FindSymbolsWithNameAndType ( name , eSymbolTypeAny , temp_sc_list ) ;
2014-07-06 17:54:58 +00:00
2013-02-27 20:13:38 +00:00
if ( ! sc_list . GetSize ( ) & & sym_ctx . target_sp )
sym_ctx . target_sp - > GetImages ( ) . FindSymbolsWithNameAndType ( name , eSymbolTypeAny , temp_sc_list ) ;
unsigned temp_sc_list_size = temp_sc_list . GetSize ( ) ;
for ( unsigned i = 0 ; i < temp_sc_list_size ; i + + )
{
SymbolContext sym_ctx ;
temp_sc_list . GetContextAtIndex ( i , sym_ctx ) ;
if ( sym_ctx . symbol )
{
switch ( sym_ctx . symbol - > GetType ( ) )
{
case eSymbolTypeCode :
case eSymbolTypeResolver :
2013-10-30 21:37:46 +00:00
case eSymbolTypeReExported :
2013-02-27 20:13:38 +00:00
sc_list . Append ( sym_ctx ) ;
break ;
default :
break ;
}
}
}
2011-08-16 18:09:29 +00:00
}
2010-07-31 01:32:05 +00:00
bool
2014-07-06 17:54:58 +00:00
ClangExpressionDeclMap : : GetFunctionAddress
2010-10-15 22:48:33 +00:00
(
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 ( ) ) ;
2014-07-06 17:54:58 +00:00
2013-03-27 23:08:40 +00:00
Log * 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 ;
2014-07-06 17:54:58 +00:00
2011-08-16 18:09:29 +00:00
FindCodeSymbolInContext ( name , m_parser_vars - > m_sym_ctx , sc_list ) ;
2013-02-27 20:13:38 +00:00
2013-10-30 21:37:46 +00:00
uint32_t sc_list_size = sc_list . GetSize ( ) ;
if ( sc_list_size = = 0 )
2011-05-13 18:27:02 +00:00
{
2014-07-06 17:54:58 +00:00
// We occasionally get debug information in which a const function is reported
2011-05-13 18:27:02 +00:00
// as non-const, so the mangled name is wrong. This is a hack to compensate.
2014-07-06 17:54:58 +00:00
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 ( ) ) ;
2014-07-06 17:54:58 +00:00
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 ( ) ) ;
2014-07-06 17:54:58 +00:00
2011-10-25 18:02:05 +00:00
FindCodeSymbolInContext ( fixed_name , m_parser_vars - > m_sym_ctx , sc_list ) ;
2013-10-30 21:37:46 +00:00
sc_list_size = sc_list . GetSize ( ) ;
2011-05-13 18:27:02 +00:00
}
}
2013-02-27 20:13:38 +00:00
2013-10-30 21:37:46 +00:00
for ( uint32_t i = 0 ; i < sc_list_size ; + + i )
{
SymbolContext sym_ctx ;
sc_list . GetContextAtIndex ( i , sym_ctx ) ;
2013-02-27 20:13:38 +00:00
2014-05-23 02:30:48 +00:00
lldb : : addr_t callable_load_addr = LLDB_INVALID_ADDRESS ;
2014-07-06 17:54:58 +00:00
2013-10-30 21:37:46 +00:00
if ( sym_ctx . function )
{
2014-05-23 02:30:48 +00:00
const Address func_so_addr = sym_ctx . function - > GetAddressRange ( ) . GetBaseAddress ( ) ;
if ( func_so_addr . IsValid ( ) )
2013-10-30 21:37:46 +00:00
{
2014-05-23 02:30:48 +00:00
callable_load_addr = func_so_addr . GetCallableLoadAddress ( target , false ) ;
2013-10-30 21:37:46 +00:00
}
}
2014-05-23 02:30:48 +00:00
else if ( sym_ctx . symbol )
2013-10-30 21:37:46 +00:00
{
2014-05-23 02:30:48 +00:00
callable_load_addr = sym_ctx . symbol - > ResolveCallableAddress ( * target ) ;
}
if ( callable_load_addr ! = LLDB_INVALID_ADDRESS )
{
func_addr = callable_load_addr ;
return true ;
2013-10-30 21:37:46 +00:00
}
}
return false ;
2010-07-31 01:32:05 +00:00
}
2011-06-23 04:25:29 +00:00
addr_t
2013-10-21 18:40:51 +00:00
ClangExpressionDeclMap : : GetSymbolAddress ( Target & target ,
Process * process ,
const ConstString & name ,
lldb : : SymbolType symbol_type ,
2013-10-22 12:27:43 +00:00
lldb_private : : Module * module )
2011-01-17 23:42:46 +00:00
{
SymbolContextList sc_list ;
2014-07-06 17:54:58 +00:00
2013-10-21 18:40:51 +00:00
if ( module )
module - > FindSymbolsWithNameAndType ( name , symbol_type , sc_list ) ;
else
target . GetImages ( ) . FindSymbolsWithNameAndType ( name , symbol_type , sc_list ) ;
2014-07-06 17:54:58 +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 ) ;
2014-07-06 17:54:58 +00:00
2012-03-07 21:03:09 +00:00
const Address * sym_address = & sym_ctx . symbol - > GetAddress ( ) ;
2014-07-06 17:54:58 +00:00
2011-07-07 23:05:43 +00:00
if ( ! sym_address | | ! sym_address - > IsValid ( ) )
2013-04-30 00:21:42 +00:00
continue ;
2014-07-06 17:54:58 +00:00
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 ;
2013-02-27 20:13:38 +00:00
case eSymbolTypeResolver :
symbol_load_addr = sym_address - > GetCallableLoadAddress ( & target , true ) ;
break ;
2013-10-21 18:40:51 +00:00
case eSymbolTypeReExported :
{
ConstString reexport_name = sym_ctx . symbol - > GetReExportedSymbolName ( ) ;
if ( reexport_name )
{
ModuleSP reexport_module_sp ;
ModuleSpec reexport_module_spec ;
reexport_module_spec . GetPlatformFileSpec ( ) = sym_ctx . 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 ) ;
}
}
symbol_load_addr = GetSymbolAddress ( target , process , sym_ctx . symbol - > GetReExportedSymbolName ( ) , symbol_type , reexport_module_sp . get ( ) ) ;
}
}
break ;
2011-06-23 04:25:29 +00:00
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 ;
}
}
}
2014-07-06 17:54:58 +00:00
2012-11-15 02:02:04 +00:00
if ( symbol_load_addr = = LLDB_INVALID_ADDRESS & & process )
{
ObjCLanguageRuntime * runtime = process - > GetObjCLanguageRuntime ( ) ;
2014-07-06 17:54:58 +00:00
2012-11-15 02:02:04 +00:00
if ( runtime )
{
symbol_load_addr = runtime - > LookupRuntimeSymbol ( name ) ;
}
}
2014-07-06 17:54:58 +00:00
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 ( ) ) ;
2014-07-06 17:54:58 +00:00
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 ;
2014-07-06 17:54:58 +00:00
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
}
2012-11-27 01:52:16 +00:00
const Symbol *
ClangExpressionDeclMap : : FindGlobalDataSymbol ( Target & target ,
2013-10-21 18:40:51 +00:00
const ConstString & name ,
2013-10-22 12:27:43 +00:00
lldb_private : : Module * module )
2011-05-08 02:21:26 +00:00
{
SymbolContextList sc_list ;
2014-07-06 17:54:58 +00:00
2013-10-21 18:40:51 +00:00
if ( module )
module - > FindSymbolsWithNameAndType ( name , eSymbolTypeAny , sc_list ) ;
else
target . GetImages ( ) . FindSymbolsWithNameAndType ( name , eSymbolTypeAny , sc_list ) ;
2014-07-06 17:54:58 +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 ( ) ;
2014-07-06 17:54:58 +00:00
2012-11-27 01:52:16 +00:00
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 ;
2013-10-21 18:40:51 +00: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 ) ;
}
}
return FindGlobalDataSymbol ( target , symbol - > GetReExportedSymbolName ( ) , reexport_module_sp . get ( ) ) ;
}
}
break ;
2014-07-06 17:54:58 +00:00
2012-11-27 01:52:16 +00: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 :
2013-02-27 20:13:38 +00:00
case eSymbolTypeResolver :
2012-11-27 01:52:16 +00:00
break ;
}
}
}
2011-05-08 02:21:26 +00:00
}
2014-07-06 17:54:58 +00:00
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 ;
2014-07-06 17:54:58 +00:00
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 ) ;
2014-07-06 17:54:58 +00:00
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 ) ;
2014-07-06 17:54:58 +00:00
2013-07-11 22:46:58 +00:00
if ( ClangASTContext : : AreTypesSame ( * type , var_sp - > GetType ( ) - > GetClangFullType ( ) ) )
return var_sp ;
2011-09-15 02:13:07 +00:00
}
}
else
{
return vars . GetVariableAtIndex ( 0 ) ;
}
}
2014-07-06 17:54:58 +00:00
2011-09-15 02:13:07 +00:00
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 ) ;
2014-04-04 04:06:10 +00:00
2013-03-08 20:04:57 +00:00
ClangASTMetrics : : RegisterVisibleQuery ( ) ;
2014-04-04 04:06:10 +00:00
2011-10-28 23:38:38 +00:00
const ConstString name ( context . m_decl_name . getAsString ( ) . c_str ( ) ) ;
2014-04-04 04:06:10 +00:00
2013-03-27 23:08:40 +00:00
Log * log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_EXPRESSIONS ) ) ;
2014-04-04 04:06:10 +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 ;
}
2014-04-04 04:06:10 +00:00
2011-10-14 20:34:21 +00:00
static unsigned int invocation_id = 0 ;
unsigned int current_id = invocation_id + + ;
2014-04-04 04:06:10 +00:00
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
}
2014-04-04 04:06:10 +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 ) ;
2014-04-04 04:06:10 +00:00
2011-10-14 20:34:21 +00:00
if ( log & & log - > GetVerbose ( ) )
2014-07-06 17:54:58 +00:00
log - > Printf ( " CEDM::FEVD[%u] Inspecting (NamespaceMap*)%p (%d entries) " ,
2014-04-04 04:06:10 +00:00
current_id , static_cast < void * > ( namespace_map . get ( ) ) ,
2011-10-14 20:34:21 +00:00
( int ) namespace_map - > size ( ) ) ;
2014-04-04 04:06:10 +00:00
2011-10-21 22:18:07 +00:00
if ( ! namespace_map )
return ;
2014-04-04 04:06:10 +00:00
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 ( ) ) ;
2014-04-04 04:06:10 +00:00
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 ;
2014-04-04 04:06:10 +00:00
2011-10-12 00:12:34 +00:00
if ( log )
2011-10-29 19:50:43 +00:00
log - > Printf ( " CEDM::FEVD[%u] Searching the root namespace " , current_id ) ;
2014-04-04 04:06:10 +00:00
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
}
2014-04-04 04:06:10 +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
}
2014-07-06 17:54:58 +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 ) ;
2014-07-06 17:54:58 +00:00
2013-03-27 23:08:40 +00:00
Log * log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_EXPRESSIONS ) ) ;
2014-07-06 17:54:58 +00:00
2010-11-09 23:46:37 +00:00
SymbolContextList sc_list ;
2014-07-06 17:54:58 +00:00
2011-10-29 19:50:43 +00:00
const ConstString name ( context . m_decl_name . getAsString ( ) . c_str ( ) ) ;
2014-07-06 17:54:58 +00:00
2010-11-14 22:13:40 +00:00
const char * name_unique_cstr = name . GetCString ( ) ;
2014-07-06 17:54:58 +00:00
2010-11-14 22:13:40 +00:00
if ( name_unique_cstr = = NULL )
return ;
2014-07-06 17:54:58 +00:00
2012-02-04 08:49:35 +00:00
static ConstString id_name ( " id " ) ;
static ConstString Class_name ( " Class " ) ;
2014-07-06 17:54:58 +00:00
2012-02-04 08:49:35 +00:00
if ( name = = id_name | | name = = Class_name )
return ;
2014-07-06 17:54:58 +00:00
// Only look for functions by name out in our symbols if the function
2010-10-15 22:48:33 +00:00
// 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 ( ) ;
2013-11-04 09:33:30 +00:00
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 " ) ;
2014-07-06 17:54:58 +00:00
2011-10-12 01:39:28 +00:00
if ( name = = g_lldb_class_name )
{
// Clang is looking for the type of "this"
2014-07-06 17:54:58 +00:00
2012-02-08 03:45:08 +00:00
if ( frame = = NULL )
2011-10-12 01:39:28 +00:00
return ;
2014-07-06 17:54:58 +00:00
2012-02-08 03:45:08 +00:00
SymbolContext sym_ctx = frame - > GetSymbolContext ( lldb : : eSymbolContextFunction ) ;
2014-07-06 17:54:58 +00:00
2012-02-08 03:45:08 +00:00
if ( ! sym_ctx . function )
2011-10-12 01:39:28 +00:00
return ;
2014-07-06 17:54:58 +00:00
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 ( ) ;
2014-07-06 17:54:58 +00:00
2012-02-08 03:45:08 +00:00
if ( ! decl_context )
2011-10-12 01:39:28 +00:00
return ;
2014-07-06 17:54:58 +00:00
2012-02-08 03:45:08 +00:00
clang : : CXXMethodDecl * method_decl = llvm : : dyn_cast < clang : : CXXMethodDecl > ( decl_context ) ;
2014-07-06 17:54:58 +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 ( ) ;
2014-07-06 17:54:58 +00:00
2012-10-30 23:35:54 +00:00
QualType class_qual_type ( class_decl - > getTypeForDecl ( ) , 0 ) ;
2014-07-06 17:54:58 +00:00
2012-10-30 23:35:54 +00:00
TypeFromUser class_user_type ( class_qual_type . getAsOpaquePtr ( ) ,
& class_decl - > getASTContext ( ) ) ;
2014-07-06 17:54:58 +00:00
2012-10-30 23:35:54 +00: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-07-06 17:54:58 +00:00
2013-02-01 06:55:48 +00:00
TypeFromParser class_type = CopyClassType ( class_user_type , current_id ) ;
2014-07-06 17:54:58 +00:00
2013-02-01 06:55:48 +00:00
if ( ! class_type . IsValid ( ) )
return ;
2014-07-06 17:54:58 +00:00
2013-03-12 21:22:00 +00:00
TypeSourceInfo * type_source_info = m_ast_context - > getTrivialTypeSourceInfo ( QualType : : getFromOpaquePtr ( class_type . GetOpaqueQualType ( ) ) ) ;
2014-07-06 17:54:58 +00:00
2013-02-01 06:55:48 +00:00
if ( ! type_source_info )
return ;
2014-07-06 17:54:58 +00:00
2013-02-01 06:55:48 +00:00
TypedefDecl * typedef_decl = TypedefDecl : : Create ( * m_ast_context ,
m_ast_context - > getTranslationUnitDecl ( ) ,
SourceLocation ( ) ,
SourceLocation ( ) ,
context . m_decl_name . getAsIdentifierInfo ( ) ,
type_source_info ) ;
2014-07-06 17:54:58 +00:00
2013-02-01 06:55:48 +00:00
if ( ! typedef_decl )
return ;
2014-07-06 17:54:58 +00:00
2013-02-01 06:55:48 +00:00
context . AddNamedDecl ( typedef_decl ) ;
2014-07-06 17:54:58 +00:00
2012-10-30 23:35:54 +00:00
if ( method_decl - > isInstance ( ) )
{
// self is a pointer to the object
2014-07-06 17:54:58 +00:00
2012-10-30 23:35:54 +00:00
QualType class_pointer_type = method_decl - > getASTContext ( ) . getPointerType ( class_qual_type ) ;
2014-07-06 17:54:58 +00:00
2012-10-30 23:35:54 +00:00
TypeFromUser self_user_type ( class_pointer_type . getAsOpaquePtr ( ) ,
& method_decl - > getASTContext ( ) ) ;
2014-07-06 17:54:58 +00:00
2012-10-30 23:35:54 +00:00
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.
2014-07-06 17:54:58 +00:00
2012-10-30 23:35:54 +00:00
VariableList * vars = frame - > GetVariableList ( false ) ;
2014-07-06 17:54:58 +00:00
2012-10-30 23:35:54 +00:00
lldb : : VariableSP this_var = vars - > FindVariable ( ConstString ( " this " ) ) ;
2014-07-06 17:54:58 +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 ( ) ;
2014-07-06 17:54:58 +00:00
2012-10-30 23:35:54 +00:00
if ( ! this_type )
return ;
2014-07-06 17:54:58 +00:00
2013-07-11 22:46:58 +00:00
ClangASTType pointee_type = this_type - > GetClangForwardType ( ) . GetPointeeType ( ) ;
2014-07-06 17:54:58 +00:00
2013-07-11 22:46:58 +00:00
if ( pointee_type . IsValid ( ) )
2012-10-30 23:35:54 +00:00
{
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-07-06 17:54:58 +00:00
2013-07-11 22:46:58 +00:00
TypeFromUser class_user_type ( pointee_type ) ;
2013-02-01 06:55:48 +00:00
AddOneType ( context , class_user_type , current_id ) ;
2014-07-06 17:54:58 +00:00
2013-07-11 22:46:58 +00:00
TypeFromUser this_user_type ( this_type - > GetClangFullType ( ) ) ;
2012-10-30 23:35:54 +00:00
m_struct_vars - > m_object_pointer_type = this_user_type ;
return ;
}
}
2012-03-05 22:08:20 +00:00
}
2014-07-06 17:54:58 +00:00
2011-10-12 01:39:28 +00:00
return ;
}
2014-07-06 17:54:58 +00:00
2011-10-12 01:39:28 +00: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-07-06 17:54:58 +00:00
2011-10-12 01:39:28 +00:00
if ( ! frame )
return ;
2014-07-06 17:54:58 +00:00
2011-11-15 02:11:17 +00:00
SymbolContext sym_ctx = frame - > GetSymbolContext ( lldb : : eSymbolContextFunction ) ;
2014-07-06 17:54:58 +00:00
2011-11-15 02:11:17 +00:00
if ( ! sym_ctx . function )
return ;
2014-07-06 17:54:58 +00:00
2012-07-14 00:53:55 +00:00
// Get the block that defines the function
Block * function_block = sym_ctx . GetFunctionBlock ( ) ;
2014-07-06 17:54:58 +00:00
2012-07-14 00:53:55 +00:00
if ( ! function_block )
return ;
2014-07-06 17:54:58 +00:00
2012-07-14 00:53:55 +00:00
clang : : DeclContext * decl_context = function_block - > GetClangDeclContext ( ) ;
2014-07-06 17:54:58 +00:00
2011-11-15 02:11:17 +00:00
if ( ! decl_context )
return ;
2014-07-06 17:54:58 +00:00
2011-11-15 02:11:17 +00:00
clang : : ObjCMethodDecl * method_decl = llvm : : dyn_cast < clang : : ObjCMethodDecl > ( decl_context ) ;
2014-07-06 17:54:58 +00:00
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 ( ) ;
2014-07-06 17:54:58 +00:00
2012-10-30 23:35:54 +00:00
if ( ! self_interface )
2012-02-08 03:45:08 +00:00
return ;
2014-07-06 17:54:58 +00:00
2012-10-30 23:35:54 +00:00
const clang : : Type * interface_type = self_interface - > getTypeForDecl ( ) ;
2014-07-06 17:54:58 +00:00
2013-04-09 21:30:48 +00:00
if ( ! interface_type )
return ; // This is unlikely, but we have seen crashes where this occurred
2014-07-06 17:54:58 +00:00
2012-10-30 23:35:54 +00:00
TypeFromUser class_user_type ( QualType ( interface_type , 0 ) . getAsOpaquePtr ( ) ,
& method_decl - > getASTContext ( ) ) ;
2014-07-06 17:54:58 +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 ( ) ) ;
}
2014-07-06 17:54:58 +00:00
2013-02-01 06:55:48 +00:00
AddOneType ( context , class_user_type , current_id ) ;
2014-07-06 17:54:58 +00:00
2012-10-30 23:35:54 +00:00
if ( method_decl - > isInstanceMethod ( ) )
{
// self is a pointer to the object
2014-07-06 17:54:58 +00:00
2012-10-30 23:35:54 +00:00
QualType class_pointer_type = method_decl - > getASTContext ( ) . getObjCObjectPointerType ( QualType ( interface_type , 0 ) ) ;
2014-07-06 17:54:58 +00:00
2012-10-30 23:35:54 +00:00
TypeFromUser self_user_type ( class_pointer_type . getAsOpaquePtr ( ) ,
& method_decl - > getASTContext ( ) ) ;
2014-07-06 17:54:58 +00:00
2012-10-30 23:35:54 +00: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-07-06 17:54:58 +00:00
2012-10-30 23:35:54 +00:00
TypeFromUser self_user_type ( class_type . getAsOpaquePtr ( ) ,
& method_decl - > getASTContext ( ) ) ;
2014-07-06 17:54:58 +00:00
2012-10-30 23:35:54 +00:00
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.
2014-07-06 17:54:58 +00:00
2012-10-30 23:35:54 +00:00
VariableList * vars = frame - > GetVariableList ( false ) ;
2014-07-06 17:54:58 +00:00
2012-10-30 23:35:54 +00:00
lldb : : VariableSP self_var = vars - > FindVariable ( ConstString ( " self " ) ) ;
2014-07-06 17:54:58 +00:00
2012-10-30 23:35:54 +00:00
if ( self_var & &
2014-07-06 17:54:58 +00:00
self_var - > IsInScope ( frame ) & &
2012-10-30 23:35:54 +00:00
self_var - > LocationIsValidForFrame ( frame ) )
{
Type * self_type = self_var - > GetType ( ) ;
2014-07-06 17:54:58 +00:00
2012-10-30 23:35:54 +00:00
if ( ! self_type )
return ;
2014-07-06 17:54:58 +00:00
2013-07-11 22:46:58 +00:00
ClangASTType self_clang_type = self_type - > GetClangFullType ( ) ;
2014-07-06 17:54:58 +00:00
2013-07-11 22:46:58 +00:00
if ( self_clang_type . IsObjCClassType ( ) )
2012-10-30 23:35:54 +00:00
{
2013-01-19 01:49:02 +00:00
return ;
}
2013-07-11 22:46:58 +00:00
else if ( self_clang_type . IsObjCObjectPointerType ( ) )
2013-01-19 01:49:02 +00:00
{
2013-07-11 22:46:58 +00:00
self_clang_type = self_clang_type . GetPointeeType ( ) ;
if ( ! self_clang_type )
2013-04-26 22:54:19 +00:00
return ;
2014-07-06 17:54:58 +00:00
2012-10-30 23:35:54 +00: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-07-06 17:54:58 +00:00
2013-07-11 22:46:58 +00:00
TypeFromUser class_user_type ( self_clang_type ) ;
2014-07-06 17:54:58 +00:00
2013-02-01 06:55:48 +00:00
AddOneType ( context , class_user_type , current_id ) ;
2014-07-06 17:54:58 +00:00
2013-07-11 22:46:58 +00:00
TypeFromUser self_user_type ( self_type - > GetClangFullType ( ) ) ;
2014-07-06 17:54:58 +00:00
2012-10-30 23:35:54 +00:00
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 ;
}
2014-07-06 17:54:58 +00:00
2011-10-12 01:39:28 +00:00
// any other $__lldb names should be weeded out now
if ( ! : : strncmp ( name_unique_cstr , " $__lldb " , sizeof ( " $__lldb " ) - 1 ) )
return ;
2014-07-06 17:54:58 +00:00
2011-10-12 01:39:28 +00:00
do
{
if ( ! target )
break ;
2014-07-06 17:54:58 +00:00
2011-10-12 01:39:28 +00:00
ClangASTContext * scratch_clang_ast_context = target - > GetScratchClangASTContext ( ) ;
2014-07-06 17:54:58 +00:00
2011-10-12 01:39:28 +00:00
if ( ! scratch_clang_ast_context )
break ;
2014-07-06 17:54:58 +00:00
2011-10-12 01:39:28 +00:00
ASTContext * scratch_ast_context = scratch_clang_ast_context - > getASTContext ( ) ;
2014-07-06 17:54:58 +00:00
2011-10-12 01:39:28 +00:00
if ( ! scratch_ast_context )
break ;
2014-07-06 17:54:58 +00:00
2011-10-12 01:39:28 +00:00
TypeDecl * ptype_type_decl = m_parser_vars - > m_persistent_vars - > GetPersistentType ( name ) ;
2014-07-06 17:54:58 +00:00
2011-10-12 01:39:28 +00:00
if ( ! ptype_type_decl )
break ;
2014-07-06 17:54:58 +00:00
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 ) ;
2014-07-06 17:54:58 +00:00
2011-10-12 01:39:28 +00:00
if ( ! parser_ptype_decl )
break ;
2014-07-06 17:54:58 +00:00
2011-10-12 01:39:28 +00:00
TypeDecl * parser_ptype_type_decl = dyn_cast < TypeDecl > ( parser_ptype_decl ) ;
2014-07-06 17:54:58 +00:00
2011-10-12 01:39:28 +00:00
if ( ! parser_ptype_type_decl )
break ;
2014-07-06 17:54:58 +00:00
2011-10-12 01:39:28 +00:00
if ( log )
2011-10-29 19:50:43 +00:00
log - > Printf ( " CEDM::FEVD[%u] Found persistent type %s " , current_id , name . GetCString ( ) ) ;
2014-07-06 17:54:58 +00:00
2011-10-12 01:39:28 +00:00
context . AddNamedDecl ( parser_ptype_type_decl ) ;
} while ( 0 ) ;
2014-07-06 17:54:58 +00:00
2011-10-12 01:39:28 +00:00
ClangExpressionVariableSP pvar_sp ( m_parser_vars - > m_persistent_vars - > GetVariable ( name ) ) ;
2014-07-06 17:54:58 +00:00
2011-10-12 01:39:28 +00:00
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 ;
}
2014-07-06 17:54:58 +00:00
2011-10-12 01:39:28 +00:00
const char * reg_name ( & name . GetCString ( ) [ 1 ] ) ;
2014-07-06 17:54:58 +00:00
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 ) ) ;
2014-07-06 17:54:58 +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 ) ;
2014-07-06 17:54:58 +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 ;
2014-07-06 17:54:58 +00:00
2011-10-12 01:39:28 +00:00
if ( frame & & ! namespace_decl )
2010-10-15 22:48:33 +00:00
{
2014-07-06 17:54:58 +00:00
valobj = frame - > GetValueForVariableExpressionPath ( name_unique_cstr ,
eNoDynamicValues ,
2013-11-04 09:33:30 +00:00
StackFrame : : eExpressionPathOptionCheckPtrVsMember | |
StackFrame : : eExpressionPathOptionsAllowDirectIVarAccess | |
StackFrame : : eExpressionPathOptionsNoFragileObjcIvar | |
StackFrame : : eExpressionPathOptionsNoSyntheticChildren | |
StackFrame : : eExpressionPathOptionsNoSyntheticArrayRange ,
2011-10-12 00:12:34 +00:00
var ,
err ) ;
2014-07-06 17:54:58 +00:00
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
}
2014-07-06 17:54:58 +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 ) ;
2014-07-06 17:54:58 +00:00
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
}
}
2014-07-06 17:54:58 +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 ;
2014-07-06 17:54:58 +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 ,
2014-07-06 17:54:58 +00:00
eFunctionNameTypeBase ,
2011-10-12 18:44:30 +00:00
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 ;
2014-07-06 17:54:58 +00:00
2012-07-28 00:21:01 +00:00
// TODO Fix FindFunctions so that it doesn't return
// instance methods for eFunctionNameTypeBase.
2014-07-06 17:54:58 +00:00
2011-10-12 17:38:09 +00:00
target - > GetImages ( ) . FindFunctions ( name ,
2013-04-03 02:00:15 +00:00
eFunctionNameTypeFull ,
2011-10-12 17:38:09 +00:00
include_symbols ,
2012-02-10 22:52:19 +00:00
include_inlines ,
2014-07-06 17:54:58 +00:00
append ,
2011-10-12 17:38:09 +00:00
sc_list ) ;
}
2014-07-06 17:54:58 +00:00
2011-05-08 02:21:26 +00:00
if ( sc_list . GetSize ( ) )
2010-10-15 22:48:33 +00:00
{
2013-10-31 16:59:47 +00:00
Symbol * extern_symbol = NULL ;
Symbol * non_extern_symbol = NULL ;
2014-07-06 17:54:58 +00:00
2011-05-08 02:21:26 +00:00
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 ) ;
2014-07-06 17:54:58 +00:00
2011-05-08 02:21:26 +00:00
if ( sym_ctx . function )
{
2012-07-28 00:21:01 +00:00
clang : : DeclContext * decl_ctx = sym_ctx . function - > GetClangDeclContext ( ) ;
2014-07-06 17:54:58 +00:00
2013-04-27 01:57:44 +00:00
if ( ! decl_ctx )
continue ;
2014-07-06 17:54:58 +00:00
2012-07-28 00:21:01 +00:00
// Filter out class/instance methods.
if ( dyn_cast < clang : : ObjCMethodDecl > ( decl_ctx ) )
continue ;
if ( dyn_cast < clang : : CXXMethodDecl > ( decl_ctx ) )
continue ;
2014-07-06 17:54:58 +00:00
2013-04-24 00:34:41 +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 )
{
2014-06-13 21:57:58 +00:00
if ( sym_ctx . symbol - > GetType ( ) = = eSymbolTypeReExported & & target )
2013-10-31 16:59:47 +00:00
{
sym_ctx . symbol = sym_ctx . symbol - > ResolveReExportedSymbol ( * target ) ;
if ( sym_ctx . symbol = = NULL )
continue ;
}
2014-07-06 17:54:58 +00:00
2013-10-31 16:59:47 +00:00
if ( sym_ctx . symbol - > IsExternal ( ) )
extern_symbol = sym_ctx . symbol ;
2011-05-08 02:21:26 +00:00
else
2013-10-31 16:59:47 +00:00
non_extern_symbol = sym_ctx . symbol ;
2011-05-08 02:21:26 +00:00
}
2010-10-15 22:48:33 +00:00
}
2014-07-06 17:54:58 +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
{
2013-10-31 16:59:47 +00:00
if ( extern_symbol )
2011-09-15 02:13:07 +00:00
{
2013-10-31 16:59:47 +00:00
AddOneFunction ( context , NULL , extern_symbol , current_id ) ;
context . m_found . function = true ;
}
else if ( non_extern_symbol )
{
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
}
2014-07-06 17:54:58 +00:00
2013-05-15 18:27:08 +00:00
if ( target & & ! context . m_found . variable & & ! namespace_decl )
2010-10-15 22:48:33 +00:00
{
2014-07-06 17:54:58 +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.
2014-07-06 17:54:58 +00:00
2012-11-27 01:52:16 +00:00
const Symbol * data_symbol = FindGlobalDataSymbol ( * target , name ) ;
2014-07-06 17:54:58 +00:00
2011-05-08 02:21:26 +00:00
if ( data_symbol )
2011-09-15 02:13:07 +00:00
{
2014-02-19 23:37:25 +00: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 ( ) ;
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
2014-03-20 06:08:36 +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();
//}
2012-03-06 21:56:33 +00:00
2013-07-11 22:46:58 +00:00
bool
ClangExpressionDeclMap : : GetVariableValue ( VariableSP & var ,
lldb_private : : Value & var_location ,
TypeFromUser * user_type ,
TypeFromParser * parser_type )
2010-06-08 16:52:24 +00:00
{
2013-03-27 23:08:40 +00:00
Log * log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_EXPRESSIONS ) ) ;
2014-07-06 17:54:58 +00:00
2010-06-08 16:52:24 +00:00
Type * var_type = var - > GetType ( ) ;
2014-07-06 17:54:58 +00:00
if ( ! var_type )
2010-06-08 16:52:24 +00:00
{
2010-07-16 00:09:46 +00:00
if ( log )
log - > PutCString ( " Skipped a definition because it has no type " ) ;
2013-07-11 22:46:58 +00:00
return false ;
2010-06-08 16:52:24 +00:00
}
2014-07-06 17:54:58 +00:00
2013-07-11 22:46:58 +00:00
ClangASTType var_clang_type = var_type - > GetClangFullType ( ) ;
2014-07-06 17:54:58 +00:00
2013-07-11 22:46:58 +00:00
if ( ! var_clang_type )
2010-06-08 16:52:24 +00:00
{
2010-07-16 00:09:46 +00:00
if ( log )
log - > PutCString ( " Skipped a definition because it has no Clang type " ) ;
2013-07-11 22:46:58 +00:00
return false ;
2010-06-08 16:52:24 +00:00
}
2014-07-06 17:54:58 +00:00
2011-07-30 02:42:06 +00:00
ASTContext * ast = var_type - > GetClangASTContext ( ) . getASTContext ( ) ;
2013-07-11 22:46:58 +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 " ) ;
2013-07-11 22:46:58 +00:00
return false ;
2010-06-08 16:52:24 +00:00
}
2013-07-11 22:46:58 +00:00
//var_clang_type = MaybePromoteToBlockPointerType (ast, var_clang_type);
2014-07-06 17:54:58 +00:00
2010-07-17 00:43:37 +00:00
DWARFExpression & var_location_expr = var - > LocationExpression ( ) ;
2014-07-06 17:54:58 +00:00
2012-02-10 01:22:05 +00:00
Target * target = m_parser_vars - > m_exe_ctx . GetTargetPtr ( ) ;
2010-06-08 16:52:24 +00:00
Error err ;
2014-07-06 17:54:58 +00:00
2013-01-18 21:20:51 +00:00
if ( var - > GetLocationIsConstantValueData ( ) )
{
DataExtractor const_value_extractor ;
2014-07-06 17:54:58 +00:00
2013-01-18 21:20:51 +00:00
if ( var_location_expr . GetExpressionData ( const_value_extractor ) )
{
2013-07-11 22:46:58 +00:00
var_location = Value ( const_value_extractor . GetDataStart ( ) , const_value_extractor . GetByteSize ( ) ) ;
var_location . SetValueType ( Value : : eValueTypeHostAddress ) ;
2013-01-18 21:20:51 +00:00
}
else
{
if ( log )
log - > Printf ( " Error evaluating constant variable: %s " , err . AsCString ( ) ) ;
2013-07-11 22:46:58 +00:00
return false ;
2013-01-18 21:20:51 +00:00
}
}
2014-07-06 17:54:58 +00:00
2013-07-11 22:46:58 +00:00
ClangASTType type_to_use = GuardedCopyType ( var_clang_type ) ;
2014-07-06 17:54:58 +00:00
2013-07-11 22:46:58 +00:00
if ( ! type_to_use )
2010-07-20 23:31:16 +00:00
{
2013-07-11 22:46:58 +00:00
if ( log )
log - > Printf ( " Couldn't copy a variable's type into the parser's AST context " ) ;
2014-07-06 17:54:58 +00:00
2013-07-11 22:46:58 +00:00
return false ;
2010-07-20 23:31:16 +00:00
}
2014-07-06 17:54:58 +00:00
2013-07-11 22:46:58 +00:00
if ( parser_type )
* parser_type = TypeFromParser ( type_to_use ) ;
2014-07-06 17:54:58 +00:00
2013-07-11 22:46:58 +00:00
if ( var_location . GetContextType ( ) = = Value : : eContextTypeInvalid )
var_location . SetClangType ( type_to_use ) ;
2014-07-06 17:54:58 +00:00
2013-07-11 22:46:58 +00:00
if ( var_location . GetValueType ( ) = = Value : : eValueTypeFileAddress )
2010-06-08 16:52:24 +00:00
{
SymbolContext var_sc ;
var - > CalculateSymbolContext ( & var_sc ) ;
2014-07-06 17:54:58 +00:00
2010-06-08 16:52:24 +00:00
if ( ! var_sc . module_sp )
2013-08-07 19:05:15 +00:00
return false ;
2013-07-10 01:23:25 +00:00
2013-07-11 22:46:58 +00:00
Address so_addr ( var_location . GetScalar ( ) . ULongLong ( ) , var_sc . module_sp - > GetSectionList ( ) ) ;
2014-07-06 17:54:58 +00:00
2011-09-22 04:58:26 +00:00
lldb : : addr_t load_addr = so_addr . GetLoadAddress ( target ) ;
2014-07-06 17:54:58 +00:00
2011-09-15 02:13:07 +00:00
if ( load_addr ! = LLDB_INVALID_ADDRESS )
{
2013-07-11 22:46:58 +00:00
var_location . GetScalar ( ) = load_addr ;
var_location . SetValueType ( Value : : eValueTypeLoadAddress ) ;
2011-09-15 02:13:07 +00:00
}
2010-06-08 16:52:24 +00:00
}
2014-07-06 17:54:58 +00:00
2010-07-20 23:31:16 +00:00
if ( user_type )
2013-07-11 22:46:58 +00:00
* user_type = TypeFromUser ( var_clang_type ) ;
2014-07-06 17:54:58 +00:00
2013-07-11 22:46:58 +00:00
return true ;
2010-07-17 00:43:37 +00:00
}
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 ( ) ) ;
2014-07-06 17:54:58 +00:00
2013-03-27 23:08:40 +00:00
Log * log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_EXPRESSIONS ) ) ;
2014-07-06 17:54:58 +00:00
2010-07-20 23:31:16 +00:00
TypeFromUser ut ;
TypeFromParser pt ;
2013-07-11 22:46:58 +00:00
Value var_location ;
2014-07-06 17:54:58 +00:00
2013-07-11 22:46:58 +00:00
if ( ! GetVariableValue ( var , var_location , & ut , & pt ) )
return ;
2014-07-06 17:54:58 +00:00
2012-03-15 01:53:17 +00:00
clang : : QualType parser_opaque_type = QualType : : getFromOpaquePtr ( pt . GetOpaqueQualType ( ) ) ;
2014-07-06 17:54:58 +00:00
2012-03-21 17:13:20 +00:00
if ( parser_opaque_type . isNull ( ) )
return ;
2014-07-06 17:54:58 +00:00
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 ( ) ) ;
2013-12-20 04:09:05 +00:00
if ( const ObjCObjectPointerType * objc_object_ptr_type = dyn_cast < ObjCObjectPointerType > ( parser_type ) )
CompleteType ( objc_object_ptr_type - > getInterfaceDecl ( ) ) ;
2012-03-15 01:53:17 +00:00
}
2014-07-06 17:54:58 +00:00
2013-07-11 22:46:58 +00:00
bool is_reference = pt . IsReferenceType ( ) ;
2011-10-27 19:41:13 +00:00
2013-07-11 22:46:58 +00:00
NamedDecl * var_decl = NULL ;
2011-10-27 19:41:13 +00:00
if ( is_reference )
2013-07-11 22:46:58 +00:00
var_decl = context . AddVarDecl ( pt ) ;
2011-10-27 19:41:13 +00:00
else
2013-07-11 22:46:58 +00:00
var_decl = context . AddVarDecl ( pt . GetLValueReferenceType ( ) ) ;
2014-07-06 17:54:58 +00:00
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 ) ) ;
2014-07-06 17:54:58 +00:00
2010-12-14 02:59:59 +00:00
assert ( entity . get ( ) ) ;
2013-01-15 23:29:36 +00:00
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-07-06 17:54:58 +00:00
2011-10-27 19:41:13 +00:00
if ( is_reference )
entity - > m_flags | = ClangExpressionVariable : : EVTypeIsReference ;
2014-07-06 17:54:58 +00:00
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 ( ) ) ;
2014-07-06 17:54:58 +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 ,
2014-07-06 17:54:58 +00:00
ClangExpressionVariableSP & pvar_sp ,
2011-10-14 20:34:21 +00:00
unsigned int current_id )
2010-08-11 03:57:18 +00:00
{
2013-03-27 23:08:40 +00:00
Log * log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_EXPRESSIONS ) ) ;
2014-07-06 17:54:58 +00:00
2010-12-14 02:59:59 +00:00
TypeFromUser user_type ( pvar_sp - > GetTypeFromUser ( ) ) ;
2014-07-06 17:54:58 +00:00
2013-07-11 22:46:58 +00:00
TypeFromParser parser_type ( GuardedCopyType ( user_type ) ) ;
2014-07-06 17:54:58 +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 ;
}
2014-07-06 17:54:58 +00:00
2013-07-11 22:46:58 +00:00
NamedDecl * var_decl = context . AddVarDecl ( parser_type . GetLValueReferenceType ( ) ) ;
2014-07-06 17:54:58 +00:00
2013-01-15 23:29:36 +00:00
pvar_sp - > EnableParserVars ( GetParserID ( ) ) ;
ClangExpressionVariable : : ParserVars * parser_vars = pvar_sp - > GetParserVars ( GetParserID ( ) ) ;
parser_vars - > m_parser_type = parser_type ;
2013-07-11 22:46:58 +00:00
parser_vars - > m_named_decl = var_decl ;
parser_vars - > m_llvm_value = NULL ;
parser_vars - > m_lldb_value . Clear ( ) ;
2014-07-06 17:54:58 +00:00
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
2014-07-06 17:54:58 +00:00
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 ( ) ) ;
2014-07-06 17:54:58 +00:00
2013-03-27 23:08:40 +00:00
Log * log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_EXPRESSIONS ) ) ;
2014-07-06 17:54:58 +00:00
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 ( ) ;
2014-07-06 17:54:58 +00:00
2013-07-11 22:46:58 +00: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-07-06 17:54:58 +00:00
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 ( ) ,
2014-07-06 17:54:58 +00:00
entity_name ,
2011-05-08 02:21:26 +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-05-08 02:21:26 +00:00
assert ( entity . get ( ) ) ;
2014-07-06 17:54:58 +00:00
2013-07-11 22:46:58 +00:00
entity - > EnableParserVars ( GetParserID ( ) ) ;
ClangExpressionVariable : : ParserVars * parser_vars = entity - > GetParserVars ( GetParserID ( ) ) ;
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 ) ;
2014-07-06 17:54:58 +00:00
2013-07-11 22:46:58 +00: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-07-06 17:54:58 +00:00
2013-01-15 23:29:36 +00: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-07-06 17:54:58 +00:00
2011-05-08 02:21:26 +00:00
if ( log )
{
2011-10-20 00:47:21 +00:00
ASTDumper ast_dumper ( var_decl ) ;
2014-07-06 17:54:58 +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
}
}
2014-07-06 17:54:58 +00:00
bool
2011-05-12 23:54:16 +00:00
ClangExpressionDeclMap : : ResolveUnknownTypes ( )
{
2013-03-27 23:08:40 +00:00
Log * 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 ) ;
2014-07-06 17:54:58 +00:00
2013-01-15 23:29:36 +00:00
ClangExpressionVariable : : ParserVars * parser_vars = entity - > GetParserVars ( GetParserID ( ) ) ;
2014-07-06 17:54:58 +00:00
2011-05-12 23:54:16 +00:00
if ( entity - > m_flags & ClangExpressionVariable : : EVUnknownType )
{
2013-01-15 23:29:36 +00:00
const NamedDecl * named_decl = parser_vars - > m_named_decl ;
2011-05-12 23:54:16 +00:00
const VarDecl * var_decl = dyn_cast < VarDecl > ( named_decl ) ;
2014-07-06 17:54:58 +00:00
2011-05-12 23:54:16 +00:00
if ( ! var_decl )
{
if ( log )
log - > Printf ( " Entity of unknown type does not have a VarDecl " ) ;
return false ;
}
2014-07-06 17:54:58 +00:00
2011-05-12 23:54:16 +00:00
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
}
2014-07-06 17:54:58 +00:00
2011-05-12 23:54:16 +00:00
QualType var_type = var_decl - > getType ( ) ;
TypeFromParser parser_type ( var_type . getAsOpaquePtr ( ) , & var_decl - > getASTContext ( ) ) ;
2014-07-06 17:54:58 +00:00
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 ( ) ) ;
2014-07-06 17:54:58 +00:00
2011-12-01 21:04:37 +00:00
if ( ! copied_type )
2014-07-06 17:54:58 +00:00
{
2011-12-01 21:04:37 +00:00
if ( log )
log - > Printf ( " ClangExpressionDeclMap::ResolveUnknownType - Couldn't import the type for a variable " ) ;
2014-07-06 17:54:58 +00:00
2012-08-11 00:35:26 +00:00
return ( bool ) lldb : : ClangExpressionVariableSP ( ) ;
2011-12-01 21:04:37 +00:00
}
2014-07-06 17:54:58 +00:00
2011-05-12 23:54:16 +00:00
TypeFromUser user_type ( copied_type , scratch_ast_context ) ;
2014-07-06 17:54:58 +00:00
2013-07-11 22:46:58 +00:00
// parser_vars->m_lldb_value.SetContext(Value::eContextTypeClangType, user_type.GetOpaqueQualType());
parser_vars - > m_lldb_value . SetClangType ( user_type ) ;
2013-01-15 23:29:36 +00:00
parser_vars - > m_parser_type = parser_type ;
2014-07-06 17:54:58 +00:00
2013-07-11 22:46:58 +00:00
entity - > SetClangType ( user_type ) ;
2014-07-06 17:54:58 +00:00
2011-05-12 23:54:16 +00:00
entity - > m_flags & = ~ ( ClangExpressionVariable : : EVUnknownType ) ;
}
}
2014-07-06 17:54:58 +00:00
2011-05-12 23:54:16 +00:00
return true ;
}
2010-11-30 00:27:43 +00:00
void
2010-12-14 02:59:59 +00:00
ClangExpressionDeclMap : : AddOneRegister ( NameSearchContext & context ,
2014-07-06 17:54:58 +00:00
const RegisterInfo * reg_info ,
2011-10-14 20:34:21 +00:00
unsigned int current_id )
2010-11-30 00:27:43 +00:00
{
2013-03-27 23:08:40 +00:00
Log * log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_EXPRESSIONS ) ) ;
2014-07-06 17:54:58 +00:00
2013-07-11 22:46:58 +00:00
ClangASTType clang_type = ClangASTContext : : GetBuiltinTypeForEncodingAndBitSize ( m_ast_context ,
reg_info - > encoding ,
reg_info - > byte_size * 8 ) ;
2014-07-06 17:54:58 +00:00
2013-07-11 22:46:58 +00:00
if ( ! clang_type )
2010-11-30 00:27:43 +00:00
{
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 ;
}
2014-07-06 17:54:58 +00:00
2013-07-11 22:46:58 +00:00
TypeFromParser parser_clang_type ( clang_type ) ;
2014-07-06 17:54:58 +00:00
2013-07-11 22:46:58 +00:00
NamedDecl * var_decl = context . AddVarDecl ( parser_clang_type ) ;
2014-07-06 17:54:58 +00:00
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 ( ) ) ;
2014-07-06 17:54:58 +00:00
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 ) ;
2013-01-15 23:29:36 +00:00
entity - > EnableParserVars ( GetParserID ( ) ) ;
ClangExpressionVariable : : ParserVars * parser_vars = entity - > GetParserVars ( GetParserID ( ) ) ;
2013-07-11 22:46:58 +00:00
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 ( ) ;
2012-02-15 01:40:39 +00:00
entity - > m_flags | = ClangExpressionVariable : : EVBareRegister ;
2014-07-06 17:54:58 +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 ,
2013-07-11 22:46:58 +00:00
Function * function ,
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 ( ) ) ;
2014-07-06 17:54:58 +00:00
2013-03-27 23:08:40 +00:00
Log * log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_EXPRESSIONS ) ) ;
2014-07-06 17:54:58 +00:00
2013-07-11 22:46:58 +00:00
NamedDecl * function_decl = NULL ;
2011-07-08 00:39:14 +00:00
const Address * fun_address = NULL ;
2013-07-11 22:46:58 +00:00
ClangASTType function_clang_type ;
2013-02-27 20:13:38 +00:00
bool is_indirect_function = false ;
2013-07-11 22:46:58 +00:00
if ( function )
2010-07-27 00:55:47 +00:00
{
2013-07-11 22:46:58 +00:00
Type * function_type = function - > GetType ( ) ;
2014-07-06 17:54:58 +00:00
2013-07-11 22:46:58 +00:00
if ( ! function_type )
2010-07-27 00:55:47 +00:00
{
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 ;
}
2014-07-06 17:54:58 +00:00
2013-07-11 22:46:58 +00:00
function_clang_type = function_type - > GetClangFullType ( ) ;
2014-07-06 17:54:58 +00:00
2013-07-11 22:46:58 +00:00
if ( ! function_clang_type )
2010-07-27 00:55:47 +00:00
{
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 ;
}
2014-07-06 17:54:58 +00:00
2013-07-11 22:46:58 +00:00
fun_address = & function - > GetAddressRange ( ) . GetBaseAddress ( ) ;
2014-07-06 17:54:58 +00:00
2013-07-11 22:46:58 +00:00
ClangASTType copied_function_type = GuardedCopyType ( function_clang_type ) ;
if ( copied_function_type )
2011-10-20 00:47:21 +00:00
{
2013-07-11 22:46:58 +00:00
function_decl = context . AddFunDecl ( copied_function_type ) ;
2014-07-06 17:54:58 +00:00
2013-07-11 22:46:58 +00:00
if ( ! function_decl )
2013-04-24 00:34:41 +00:00
{
if ( log )
{
log - > Printf ( " Failed to create a function decl for '%s' {0x%8.8 " PRIx64 " } " ,
2013-07-11 22:46:58 +00:00
function_type - > GetName ( ) . GetCString ( ) ,
function_type - > GetID ( ) ) ;
2013-04-24 00:34:41 +00:00
}
2014-07-06 17:54:58 +00:00
2013-04-24 00:34:41 +00:00
return ;
}
2011-10-20 00:47:21 +00:00
}
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 " ,
2013-07-11 22:46:58 +00:00
function_type - > GetName ( ) . GetCString ( ) ,
function_type - > GetID ( ) ) ;
2011-10-20 00:47:21 +00:00
}
2014-07-06 17:54:58 +00:00
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 ( ) ;
2013-07-11 22:46:58 +00:00
function_decl = context . AddGenericFunDecl ( ) ;
2013-02-27 20:13:38 +00:00
is_indirect_function = symbol - > IsIndirect ( ) ;
2010-07-27 00:55:47 +00:00
}
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 ;
}
2014-07-06 17:54:58 +00:00
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
2013-02-27 20:13:38 +00:00
lldb : : addr_t load_addr = fun_address - > GetCallableLoadAddress ( target , is_indirect_function ) ;
2014-07-06 17:54:58 +00:00
2013-07-11 22:46:58 +00: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-07-06 17:54:58 +00:00
2013-03-19 01:45:02 +00:00
if ( load_addr ! = LLDB_INVALID_ADDRESS )
{
2013-07-11 22:46:58 +00:00
parser_vars - > m_lldb_value . SetValueType ( Value : : eValueTypeLoadAddress ) ;
parser_vars - > m_lldb_value . GetScalar ( ) = load_addr ;
2013-03-19 01:45:02 +00:00
}
else
{
// We have to try finding a file address.
2014-07-06 17:54:58 +00:00
2013-03-19 01:45:02 +00:00
lldb : : addr_t file_addr = fun_address - > GetFileAddress ( ) ;
2014-07-06 17:54:58 +00:00
2013-07-11 22:46:58 +00:00
parser_vars - > m_lldb_value . SetValueType ( Value : : eValueTypeFileAddress ) ;
parser_vars - > m_lldb_value . GetScalar ( ) = file_addr ;
2013-03-19 01:45:02 +00:00
}
2014-07-06 17:54:58 +00:00
2013-07-11 22:46:58 +00:00
parser_vars - > m_named_decl = function_decl ;
2013-01-15 23:29:36 +00:00
parser_vars - > m_llvm_value = NULL ;
2014-07-06 17:54:58 +00:00
2010-07-16 00:09:46 +00:00
if ( log )
2010-10-15 22:48:33 +00:00
{
2013-07-11 22:46:58 +00:00
ASTDumper ast_dumper ( function_decl ) ;
2014-07-06 17:54:58 +00:00
2012-07-28 00:21:01 +00:00
StreamString ss ;
2014-07-06 17:54:58 +00:00
2012-07-28 00:21:01 +00:00
fun_address - > Dump ( & ss , m_parser_vars - > m_exe_ctx . GetBestExecutionContextScope ( ) , Address : : DumpStyleResolvedDescription ) ;
2014-07-06 17:54:58 +00:00
2012-07-28 00:21:01 +00:00
log - > Printf ( " CEDM::FEVD[%u] Found %s function %s (description %s), returned %s " ,
2011-10-14 20:34:21 +00:00
current_id ,
2013-07-11 22:46:58 +00:00
( function ? " 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
2013-02-01 06:55:48 +00:00
TypeFromParser
ClangExpressionDeclMap : : CopyClassType ( TypeFromUser & ut ,
unsigned int current_id )
2010-08-04 01:02:13 +00:00
{
2013-07-11 22:46:58 +00:00
ClangASTType copied_clang_type = GuardedCopyType ( ut ) ;
2014-07-06 17:54:58 +00:00
2013-07-11 22:46:58 +00:00
if ( ! copied_clang_type )
2011-12-01 21:04:37 +00:00
{
2013-03-27 23:08:40 +00:00
Log * log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_EXPRESSIONS ) ) ;
2014-07-06 17:54:58 +00:00
2013-02-01 06:55:48 +00:00
if ( log )
log - > Printf ( " ClangExpressionDeclMap::CopyClassType - Couldn't import the type " ) ;
2014-07-06 17:54:58 +00:00
2013-02-01 06:55:48 +00:00
return TypeFromParser ( ) ;
2011-12-01 21:04:37 +00:00
}
2013-02-01 06:55:48 +00:00
2013-07-11 22:46:58 +00:00
if ( copied_clang_type . IsAggregateType ( ) & & copied_clang_type . GetCompleteType ( ) )
2010-09-21 00:44:12 +00:00
{
2013-07-11 22:46:58 +00:00
ClangASTType void_clang_type = ClangASTContext : : GetBasicType ( m_ast_context , eBasicTypeVoid ) ;
ClangASTType void_ptr_clang_type = void_clang_type . GetPointerType ( ) ;
2014-07-06 17:54:58 +00:00
2013-07-11 22:46:58 +00:00
ClangASTType method_type = ClangASTContext : : CreateFunctionType ( m_ast_context ,
void_clang_type ,
& void_ptr_clang_type ,
2011-11-01 18:07:13 +00:00
1 ,
false ,
2013-07-11 22:46:58 +00:00
copied_clang_type . GetTypeQualifiers ( ) ) ;
2014-07-06 17:54:58 +00:00
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 ;
2014-07-06 17:54:58 +00:00
2013-07-11 22:46:58 +00:00
copied_clang_type . AddMethodToCXXRecordType ( " $__lldb_expr " ,
method_type ,
lldb : : eAccessPublic ,
is_virtual ,
is_static ,
is_inline ,
is_explicit ,
is_attr_used ,
is_artificial ) ;
2010-09-21 00:44:12 +00:00
}
2014-07-06 17:54:58 +00:00
2013-07-11 22:46:58 +00:00
return TypeFromParser ( copied_clang_type ) ;
2013-02-01 06:55:48 +00:00
}
2014-07-06 17:54:58 +00:00
void
ClangExpressionDeclMap : : AddOneType ( NameSearchContext & context ,
2013-02-01 06:55:48 +00:00
TypeFromUser & ut ,
unsigned int current_id )
{
2013-07-11 22:46:58 +00:00
ClangASTType copied_clang_type = GuardedCopyType ( ut ) ;
2014-07-06 17:54:58 +00:00
2013-07-11 22:46:58 +00:00
if ( ! copied_clang_type )
2013-02-01 06:55:48 +00:00
{
2013-03-27 23:08:40 +00:00
Log * log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_EXPRESSIONS ) ) ;
2013-02-01 06:55:48 +00:00
if ( log )
log - > Printf ( " ClangExpressionDeclMap::AddOneType - Couldn't import the type " ) ;
2014-07-06 17:54:58 +00:00
2013-02-01 06:55:48 +00:00
return ;
}
2014-07-06 17:54:58 +00:00
2013-07-11 22:46:58 +00:00
context . AddTypeDecl ( copied_clang_type ) ;
2010-08-04 01:02:13 +00:00
}