2010-06-09 00:52:24 +08:00
//===-- ClangExpressionDeclMap.cpp -----------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
# include "lldb/Expression/ClangExpressionDeclMap.h"
// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
2012-09-25 06:25:51 +08:00
# include "clang/AST/ASTContext.h"
2010-09-23 11:01:22 +08:00
# include "clang/AST/DeclarationName.h"
2010-11-02 07:22:47 +08:00
# include "clang/AST/Decl.h"
2010-06-09 00:52:24 +08:00
# include "lldb/lldb-private.h"
# include "lldb/Core/Address.h"
2010-07-16 08:09:46 +08:00
# include "lldb/Core/Error.h"
2010-06-23 08:47:48 +08:00
# include "lldb/Core/Log.h"
2010-06-09 00:52:24 +08:00
# include "lldb/Core/Module.h"
2011-05-10 04:18:18 +08:00
# include "lldb/Core/RegisterValue.h"
2010-12-16 11:17:46 +08:00
# include "lldb/Core/ValueObjectConstResult.h"
2011-12-10 11:12:34 +08:00
# include "lldb/Core/ValueObjectVariable.h"
2011-02-02 07:43:26 +08:00
# include "lldb/Expression/ASTDumper.h"
2010-06-09 00:52:24 +08:00
# include "lldb/Expression/ClangASTSource.h"
2010-08-11 11:57:18 +08:00
# include "lldb/Expression/ClangPersistentVariables.h"
2013-04-11 08:09:05 +08:00
# include "lldb/Expression/Materializer.h"
2011-02-01 09:31:41 +08:00
# include "lldb/Host/Endian.h"
2010-06-09 00:52:24 +08:00
# include "lldb/Symbol/ClangASTContext.h"
2010-11-13 11:52:47 +08:00
# include "lldb/Symbol/ClangNamespaceDecl.h"
2010-06-09 00:52:24 +08:00
# include "lldb/Symbol/CompileUnit.h"
# include "lldb/Symbol/Function.h"
# include "lldb/Symbol/ObjectFile.h"
# include "lldb/Symbol/SymbolContext.h"
2011-10-12 08:12:34 +08:00
# include "lldb/Symbol/SymbolVendor.h"
2010-06-09 00:52:24 +08:00
# include "lldb/Symbol/Type.h"
# include "lldb/Symbol/TypeList.h"
# include "lldb/Symbol/Variable.h"
# include "lldb/Symbol/VariableList.h"
2010-07-21 07:31:16 +08:00
# include "lldb/Target/ExecutionContext.h"
2012-11-15 10:02:04 +08:00
# include "lldb/Target/ObjCLanguageRuntime.h"
2010-07-16 08:09:46 +08:00
# include "lldb/Target/Process.h"
2010-10-06 04:18:48 +08:00
# include "lldb/Target/RegisterContext.h"
2010-06-09 00:52:24 +08:00
# include "lldb/Target/StackFrame.h"
2010-07-21 07:31:16 +08:00
# include "lldb/Target/Target.h"
2010-12-07 09:56:02 +08:00
# include "lldb/Target/Thread.h"
2010-06-09 00:52:24 +08:00
Just like functions can have a basename and a mangled/demangled name, variable
can too. So now the lldb_private::Variable class has support for this.
Variables now have support for having a basename ("i"), and a mangled name
("_ZN12_GLOBAL__N_11iE"), and a demangled name ("(anonymous namespace)::i").
Nowwhen searching for a variable by name, users might enter the fully qualified
name, or just the basename. So new test functions were added to the Variable
and Mangled classes as:
bool NameMatches (const ConstString &name);
bool NameMatches (const RegularExpression ®ex);
I also modified "ClangExpressionDeclMap::FindVariableInScope" to also search
for global variables that are not in the current file scope by first starting
with the current module, then moving on to all modules.
Fixed an issue in the DWARF parser that could cause a varaible to get parsed
more than once. Now, once we have parsed a VariableSP for a DIE, we cache
the result even if a variable wasn't made so we don't do any re-parsing. Some
DW_TAG_variable DIEs don't have locations, or are missing vital info that
stops a debugger from being able to display anything for it, we parse a NULL
variable shared pointer for these DIEs so we don't keep trying to reparse it.
llvm-svn: 119085
2010-11-15 06:13:40 +08:00
using namespace lldb ;
2010-06-09 00:52:24 +08:00
using namespace lldb_private ;
using namespace clang ;
2011-10-29 09:58:46 +08:00
ClangExpressionDeclMap : : ClangExpressionDeclMap ( bool keep_result_in_memory , ExecutionContext & exe_ctx ) :
ClangASTSource ( exe_ctx . GetTargetSP ( ) ) ,
2010-10-16 06:48:33 +08:00
m_found_entities ( ) ,
m_struct_members ( ) ,
2011-04-12 03:41:40 +08:00
m_keep_result_in_memory ( keep_result_in_memory ) ,
2010-12-03 09:38:59 +08:00
m_parser_vars ( ) ,
2011-04-12 03:41:40 +08:00
m_struct_vars ( )
2010-06-09 00:52:24 +08:00
{
2010-12-03 09:38:59 +08:00
EnableStructVars ( ) ;
2010-06-09 00:52:24 +08:00
}
ClangExpressionDeclMap : : ~ ClangExpressionDeclMap ( )
2010-12-03 09:38:59 +08:00
{
2011-10-13 06:20:02 +08:00
// Note: The model is now that the parser's AST context and all associated
// data does not vanish until the expression has been executed. This means
// that valuable lookup data (like namespaces) doesn't vanish, but
DidParse ( ) ;
2010-12-03 09:38:59 +08:00
DisableStructVars ( ) ;
}
2011-08-02 02:18:33 +08:00
bool
2013-04-11 08:09:05 +08:00
ClangExpressionDeclMap : : WillParse ( ExecutionContext & exe_ctx ,
Materializer * materializer )
2013-03-09 04:04:57 +08:00
{
ClangASTMetrics : : ClearLocalCounters ( ) ;
2010-12-03 09:38:59 +08:00
EnableParserVars ( ) ;
2012-02-10 09:22:05 +08:00
m_parser_vars - > m_exe_ctx = exe_ctx ;
2011-09-22 12:58:26 +08:00
Target * target = exe_ctx . GetTargetPtr ( ) ;
if ( exe_ctx . GetFramePtr ( ) )
m_parser_vars - > m_sym_ctx = exe_ctx . GetFramePtr ( ) - > GetSymbolContext ( lldb : : eSymbolContextEverything ) ;
2013-02-22 06:01:43 +08:00
else if ( exe_ctx . GetThreadPtr ( ) & & exe_ctx . GetThreadPtr ( ) - > GetStackFrameAtIndex ( 0 ) )
2011-09-22 12:58:26 +08:00
m_parser_vars - > m_sym_ctx = exe_ctx . GetThreadPtr ( ) - > GetStackFrameAtIndex ( 0 ) - > GetSymbolContext ( lldb : : eSymbolContextEverything ) ;
else if ( exe_ctx . GetProcessPtr ( ) )
2011-09-17 16:33:22 +08:00
{
2013-02-23 12:12:47 +08:00
m_parser_vars - > m_sym_ctx . Clear ( true ) ;
2011-09-22 12:58:26 +08:00
m_parser_vars - > m_sym_ctx . target_sp = exe_ctx . GetTargetSP ( ) ;
2011-09-17 16:33:22 +08:00
}
2011-09-22 12:58:26 +08:00
else if ( target )
2011-09-17 16:33:22 +08:00
{
2013-02-23 12:12:47 +08:00
m_parser_vars - > m_sym_ctx . Clear ( true ) ;
2011-09-22 12:58:26 +08:00
m_parser_vars - > m_sym_ctx . target_sp = exe_ctx . GetTargetSP ( ) ;
2011-09-17 16:33:22 +08:00
}
2011-09-16 02:41:04 +08:00
2011-09-22 12:58:26 +08:00
if ( target )
{
m_parser_vars - > m_persistent_vars = & target - > GetPersistentVariables ( ) ;
2011-08-02 02:18:33 +08:00
2011-09-22 12:58:26 +08:00
if ( ! target - > GetScratchClangASTContext ( ) )
return false ;
}
2011-08-02 02:18:33 +08:00
This patch modifies the expression parser to allow it
to execute expressions even in the absence of a process.
This allows expressions to run in situations where the
target cannot run -- e.g., to perform calculations based
on type information, or to inspect a binary's static
data.
This modification touches the following files:
lldb-private-enumerations.h
Introduce a new enum specifying the policy for
processing an expression. Some expressions should
always be JITted, for example if they are functions
that will be used over and over again. Some
expressions should always be interpreted, for
example if the target is unsafe to run. For most,
it is acceptable to JIT them, but interpretation
is preferable when possible.
Target.[h,cpp]
Have EvaluateExpression now accept the new enum.
ClangExpressionDeclMap.[cpp,h]
Add support for the IR interpreter and also make
the ClangExpressionDeclMap more robust in the
absence of a process.
ClangFunction.[cpp,h]
Add support for the new enum.
IRInterpreter.[cpp,h]
New implementation.
ClangUserExpression.[cpp,h]
Add support for the new enum, and for running
expressions in the absence of a process.
ClangExpression.h
Remove references to the old DWARF-based method
of evaluating expressions, because it has been
superseded for now.
ClangUtilityFunction.[cpp,h]
Add support for the new enum.
ClangExpressionParser.[cpp,h]
Add support for the new enum, remove references
to DWARF, and add support for checking whether
the expression could be evaluated statically.
IRForTarget.[h,cpp]
Add support for the new enum, and add utility
functions to support the interpreter.
IRToDWARF.cpp
Removed
CommandObjectExpression.cpp
Remove references to the obsolete -i option.
Process.cpp
Modify calls to ClangUserExpression::Evaluate
to pass the correct enum (for dlopen/dlclose)
SBValue.cpp
Add support for the new enum.
SBFrame.cpp
Add support for he new enum.
BreakpointOptions.cpp
Add support for the new enum.
llvm-svn: 139772
2011-09-15 10:13:07 +08:00
m_parser_vars - > m_target_info = GetTargetInfo ( ) ;
2013-04-11 08:09:05 +08:00
m_parser_vars - > m_materializer = materializer ;
This patch modifies the expression parser to allow it
to execute expressions even in the absence of a process.
This allows expressions to run in situations where the
target cannot run -- e.g., to perform calculations based
on type information, or to inspect a binary's static
data.
This modification touches the following files:
lldb-private-enumerations.h
Introduce a new enum specifying the policy for
processing an expression. Some expressions should
always be JITted, for example if they are functions
that will be used over and over again. Some
expressions should always be interpreted, for
example if the target is unsafe to run. For most,
it is acceptable to JIT them, but interpretation
is preferable when possible.
Target.[h,cpp]
Have EvaluateExpression now accept the new enum.
ClangExpressionDeclMap.[cpp,h]
Add support for the IR interpreter and also make
the ClangExpressionDeclMap more robust in the
absence of a process.
ClangFunction.[cpp,h]
Add support for the new enum.
IRInterpreter.[cpp,h]
New implementation.
ClangUserExpression.[cpp,h]
Add support for the new enum, and for running
expressions in the absence of a process.
ClangExpression.h
Remove references to the old DWARF-based method
of evaluating expressions, because it has been
superseded for now.
ClangUtilityFunction.[cpp,h]
Add support for the new enum.
ClangExpressionParser.[cpp,h]
Add support for the new enum, remove references
to DWARF, and add support for checking whether
the expression could be evaluated statically.
IRForTarget.[h,cpp]
Add support for the new enum, and add utility
functions to support the interpreter.
IRToDWARF.cpp
Removed
CommandObjectExpression.cpp
Remove references to the obsolete -i option.
Process.cpp
Modify calls to ClangUserExpression::Evaluate
to pass the correct enum (for dlopen/dlclose)
SBValue.cpp
Add support for the new enum.
SBFrame.cpp
Add support for he new enum.
BreakpointOptions.cpp
Add support for the new enum.
llvm-svn: 139772
2011-09-15 10:13:07 +08:00
2011-08-02 02:18:33 +08:00
return true ;
2010-12-03 09:38:59 +08:00
}
2010-10-26 08:31:56 +08:00
2013-04-11 08:09:05 +08:00
void
2010-12-14 10:59:59 +08:00
ClangExpressionDeclMap : : DidParse ( )
2010-12-03 09:38:59 +08:00
{
2013-03-28 07:08:40 +08:00
Log * log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_EXPRESSIONS ) ) ;
2013-03-09 04:04:57 +08:00
if ( log )
ClangASTMetrics : : DumpCounters ( log ) ;
2010-12-03 09:38:59 +08:00
if ( m_parser_vars . get ( ) )
{
2010-12-14 10:59:59 +08:00
for ( size_t entity_index = 0 , num_entities = m_found_entities . GetSize ( ) ;
2010-12-03 09:38:59 +08:00
entity_index < num_entities ;
+ + entity_index )
{
2010-12-14 10:59:59 +08:00
ClangExpressionVariableSP var_sp ( m_found_entities . GetVariableAtIndex ( entity_index ) ) ;
2012-10-13 01:34:26 +08:00
if ( var_sp )
2013-01-16 07:29:36 +08:00
var_sp - > DisableParserVars ( GetParserID ( ) ) ;
2010-12-03 09:38:59 +08:00
}
2010-12-14 10:59:59 +08:00
for ( size_t pvar_index = 0 , num_pvars = m_parser_vars - > m_persistent_vars - > GetSize ( ) ;
2010-12-03 09:38:59 +08:00
pvar_index < num_pvars ;
+ + pvar_index )
{
2010-12-14 10:59:59 +08:00
ClangExpressionVariableSP pvar_sp ( m_parser_vars - > m_persistent_vars - > GetVariableAtIndex ( pvar_index ) ) ;
if ( pvar_sp )
2013-01-16 07:29:36 +08:00
pvar_sp - > DisableParserVars ( GetParserID ( ) ) ;
2010-12-03 09:38:59 +08:00
}
DisableParserVars ( ) ;
2010-10-08 09:58:41 +08:00
}
2010-06-09 00:52:24 +08:00
}
2010-07-14 05:41:46 +08:00
// Interface for IRForTarget
This patch modifies the expression parser to allow it
to execute expressions even in the absence of a process.
This allows expressions to run in situations where the
target cannot run -- e.g., to perform calculations based
on type information, or to inspect a binary's static
data.
This modification touches the following files:
lldb-private-enumerations.h
Introduce a new enum specifying the policy for
processing an expression. Some expressions should
always be JITted, for example if they are functions
that will be used over and over again. Some
expressions should always be interpreted, for
example if the target is unsafe to run. For most,
it is acceptable to JIT them, but interpretation
is preferable when possible.
Target.[h,cpp]
Have EvaluateExpression now accept the new enum.
ClangExpressionDeclMap.[cpp,h]
Add support for the IR interpreter and also make
the ClangExpressionDeclMap more robust in the
absence of a process.
ClangFunction.[cpp,h]
Add support for the new enum.
IRInterpreter.[cpp,h]
New implementation.
ClangUserExpression.[cpp,h]
Add support for the new enum, and for running
expressions in the absence of a process.
ClangExpression.h
Remove references to the old DWARF-based method
of evaluating expressions, because it has been
superseded for now.
ClangUtilityFunction.[cpp,h]
Add support for the new enum.
ClangExpressionParser.[cpp,h]
Add support for the new enum, remove references
to DWARF, and add support for checking whether
the expression could be evaluated statically.
IRForTarget.[h,cpp]
Add support for the new enum, and add utility
functions to support the interpreter.
IRToDWARF.cpp
Removed
CommandObjectExpression.cpp
Remove references to the obsolete -i option.
Process.cpp
Modify calls to ClangUserExpression::Evaluate
to pass the correct enum (for dlopen/dlclose)
SBValue.cpp
Add support for the new enum.
SBFrame.cpp
Add support for he new enum.
BreakpointOptions.cpp
Add support for the new enum.
llvm-svn: 139772
2011-09-15 10:13:07 +08:00
ClangExpressionDeclMap : : TargetInfo
ClangExpressionDeclMap : : GetTargetInfo ( )
{
assert ( m_parser_vars . get ( ) ) ;
TargetInfo ret ;
2012-02-10 09:22:05 +08:00
ExecutionContext & exe_ctx = m_parser_vars - > m_exe_ctx ;
Process * process = exe_ctx . GetProcessPtr ( ) ;
if ( process )
This patch modifies the expression parser to allow it
to execute expressions even in the absence of a process.
This allows expressions to run in situations where the
target cannot run -- e.g., to perform calculations based
on type information, or to inspect a binary's static
data.
This modification touches the following files:
lldb-private-enumerations.h
Introduce a new enum specifying the policy for
processing an expression. Some expressions should
always be JITted, for example if they are functions
that will be used over and over again. Some
expressions should always be interpreted, for
example if the target is unsafe to run. For most,
it is acceptable to JIT them, but interpretation
is preferable when possible.
Target.[h,cpp]
Have EvaluateExpression now accept the new enum.
ClangExpressionDeclMap.[cpp,h]
Add support for the IR interpreter and also make
the ClangExpressionDeclMap more robust in the
absence of a process.
ClangFunction.[cpp,h]
Add support for the new enum.
IRInterpreter.[cpp,h]
New implementation.
ClangUserExpression.[cpp,h]
Add support for the new enum, and for running
expressions in the absence of a process.
ClangExpression.h
Remove references to the old DWARF-based method
of evaluating expressions, because it has been
superseded for now.
ClangUtilityFunction.[cpp,h]
Add support for the new enum.
ClangExpressionParser.[cpp,h]
Add support for the new enum, remove references
to DWARF, and add support for checking whether
the expression could be evaluated statically.
IRForTarget.[h,cpp]
Add support for the new enum, and add utility
functions to support the interpreter.
IRToDWARF.cpp
Removed
CommandObjectExpression.cpp
Remove references to the obsolete -i option.
Process.cpp
Modify calls to ClangUserExpression::Evaluate
to pass the correct enum (for dlopen/dlclose)
SBValue.cpp
Add support for the new enum.
SBFrame.cpp
Add support for he new enum.
BreakpointOptions.cpp
Add support for the new enum.
llvm-svn: 139772
2011-09-15 10:13:07 +08:00
{
2012-02-10 09:22:05 +08:00
ret . byte_order = process - > GetByteOrder ( ) ;
ret . address_byte_size = process - > GetAddressByteSize ( ) ;
}
else
{
Target * target = exe_ctx . GetTargetPtr ( ) ;
if ( target )
2011-09-22 12:58:26 +08:00
{
2012-02-10 09:22:05 +08:00
ret . byte_order = target - > GetArchitecture ( ) . GetByteOrder ( ) ;
ret . address_byte_size = target - > GetArchitecture ( ) . GetAddressByteSize ( ) ;
2011-09-22 12:58:26 +08:00
}
This patch modifies the expression parser to allow it
to execute expressions even in the absence of a process.
This allows expressions to run in situations where the
target cannot run -- e.g., to perform calculations based
on type information, or to inspect a binary's static
data.
This modification touches the following files:
lldb-private-enumerations.h
Introduce a new enum specifying the policy for
processing an expression. Some expressions should
always be JITted, for example if they are functions
that will be used over and over again. Some
expressions should always be interpreted, for
example if the target is unsafe to run. For most,
it is acceptable to JIT them, but interpretation
is preferable when possible.
Target.[h,cpp]
Have EvaluateExpression now accept the new enum.
ClangExpressionDeclMap.[cpp,h]
Add support for the IR interpreter and also make
the ClangExpressionDeclMap more robust in the
absence of a process.
ClangFunction.[cpp,h]
Add support for the new enum.
IRInterpreter.[cpp,h]
New implementation.
ClangUserExpression.[cpp,h]
Add support for the new enum, and for running
expressions in the absence of a process.
ClangExpression.h
Remove references to the old DWARF-based method
of evaluating expressions, because it has been
superseded for now.
ClangUtilityFunction.[cpp,h]
Add support for the new enum.
ClangExpressionParser.[cpp,h]
Add support for the new enum, remove references
to DWARF, and add support for checking whether
the expression could be evaluated statically.
IRForTarget.[h,cpp]
Add support for the new enum, and add utility
functions to support the interpreter.
IRToDWARF.cpp
Removed
CommandObjectExpression.cpp
Remove references to the obsolete -i option.
Process.cpp
Modify calls to ClangUserExpression::Evaluate
to pass the correct enum (for dlopen/dlclose)
SBValue.cpp
Add support for the new enum.
SBFrame.cpp
Add support for he new enum.
BreakpointOptions.cpp
Add support for the new enum.
llvm-svn: 139772
2011-09-15 10:13:07 +08:00
}
2012-02-10 09:22:05 +08:00
This patch modifies the expression parser to allow it
to execute expressions even in the absence of a process.
This allows expressions to run in situations where the
target cannot run -- e.g., to perform calculations based
on type information, or to inspect a binary's static
data.
This modification touches the following files:
lldb-private-enumerations.h
Introduce a new enum specifying the policy for
processing an expression. Some expressions should
always be JITted, for example if they are functions
that will be used over and over again. Some
expressions should always be interpreted, for
example if the target is unsafe to run. For most,
it is acceptable to JIT them, but interpretation
is preferable when possible.
Target.[h,cpp]
Have EvaluateExpression now accept the new enum.
ClangExpressionDeclMap.[cpp,h]
Add support for the IR interpreter and also make
the ClangExpressionDeclMap more robust in the
absence of a process.
ClangFunction.[cpp,h]
Add support for the new enum.
IRInterpreter.[cpp,h]
New implementation.
ClangUserExpression.[cpp,h]
Add support for the new enum, and for running
expressions in the absence of a process.
ClangExpression.h
Remove references to the old DWARF-based method
of evaluating expressions, because it has been
superseded for now.
ClangUtilityFunction.[cpp,h]
Add support for the new enum.
ClangExpressionParser.[cpp,h]
Add support for the new enum, remove references
to DWARF, and add support for checking whether
the expression could be evaluated statically.
IRForTarget.[h,cpp]
Add support for the new enum, and add utility
functions to support the interpreter.
IRToDWARF.cpp
Removed
CommandObjectExpression.cpp
Remove references to the obsolete -i option.
Process.cpp
Modify calls to ClangUserExpression::Evaluate
to pass the correct enum (for dlopen/dlclose)
SBValue.cpp
Add support for the new enum.
SBFrame.cpp
Add support for he new enum.
BreakpointOptions.cpp
Add support for the new enum.
llvm-svn: 139772
2011-09-15 10:13:07 +08:00
return ret ;
}
2010-08-11 11:57:18 +08:00
bool
2010-10-16 06:48:33 +08:00
ClangExpressionDeclMap : : AddPersistentVariable
(
2011-07-30 10:42:06 +08:00
const NamedDecl * decl ,
2010-10-16 06:48:33 +08:00
const ConstString & name ,
2011-01-13 16:53:35 +08:00
TypeFromParser parser_type ,
bool is_result ,
bool is_lvalue
2010-10-16 06:48:33 +08:00
)
2010-08-11 11:57:18 +08:00
{
2010-12-03 09:38:59 +08:00
assert ( m_parser_vars . get ( ) ) ;
This commit changes the way LLDB executes user
expressions.
Previously, ClangUserExpression assumed that if
there was a constant result for an expression
then it could be determined during parsing. In
particular, the IRInterpreter ran while parser
state (in particular, ClangExpressionDeclMap)
was present. This approach is flawed, because
the IRInterpreter actually is capable of using
external variables, and hence the result might
be different each run. Until now, we papered
over this flaw by re-parsing the expression each
time we ran it.
I have rewritten the IRInterpreter to be
completely independent of the ClangExpressionDeclMap.
Instead of special-casing external variable lookup,
which ties the IRInterpreter closely to LLDB,
we now interpret the exact same IR that the JIT
would see. This IR assumes that materialization
has occurred; hence the recent implementation of the
Materializer, which does not require parser state
(in the form of ClangExpressionDeclMap) to be
present.
Materialization, interpretation, and dematerialization
are now all independent of parsing. This means that
in theory we can parse expressions once and run them
many times. I have three outstanding tasks before
shutting this down:
- First, I will ensure that all of this works with
core files. Core files have a Process but do not
allow allocating memory, which currently confuses
materialization.
- Second, I will make expression breakpoint
conditions remember their ClangUserExpression and
re-use it.
- Third, I will tear out all the redundant code
(for example, materialization logic in
ClangExpressionDeclMap) that is no longer used.
While implementing this fix, I also found a bug in
IRForTarget's handling of floating-point constants.
This should be fixed.
llvm-svn: 179801
2013-04-19 06:06:33 +08:00
if ( m_parser_vars - > m_materializer & & is_result )
{
Error err ;
ExecutionContext & exe_ctx = m_parser_vars - > m_exe_ctx ;
Target * target = exe_ctx . GetTargetPtr ( ) ;
if ( target = = NULL )
return false ;
ASTContext * context ( target - > GetScratchClangASTContext ( ) - > getASTContext ( ) ) ;
TypeFromUser user_type ( m_ast_importer - > DeportType ( context ,
parser_type . GetASTContext ( ) ,
parser_type . GetOpaqueQualType ( ) ) ,
context ) ;
uint32_t offset = m_parser_vars - > m_materializer - > AddResultVariable ( user_type , is_lvalue , m_keep_result_in_memory , err ) ;
2013-07-16 02:43:36 +08: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 ) ;
This commit changes the way LLDB executes user
expressions.
Previously, ClangUserExpression assumed that if
there was a constant result for an expression
then it could be determined during parsing. In
particular, the IRInterpreter ran while parser
state (in particular, ClangExpressionDeclMap)
was present. This approach is flawed, because
the IRInterpreter actually is capable of using
external variables, and hence the result might
be different each run. Until now, we papered
over this flaw by re-parsing the expression each
time we ran it.
I have rewritten the IRInterpreter to be
completely independent of the ClangExpressionDeclMap.
Instead of special-casing external variable lookup,
which ties the IRInterpreter closely to LLDB,
we now interpret the exact same IR that the JIT
would see. This IR assumes that materialization
has occurred; hence the recent implementation of the
Materializer, which does not require parser state
(in the form of ClangExpressionDeclMap) to be
present.
Materialization, interpretation, and dematerialization
are now all independent of parsing. This means that
in theory we can parse expressions once and run them
many times. I have three outstanding tasks before
shutting this down:
- First, I will ensure that all of this works with
core files. Core files have a Process but do not
allow allocating memory, which currently confuses
materialization.
- Second, I will make expression breakpoint
conditions remember their ClangUserExpression and
re-use it.
- Third, I will tear out all the redundant code
(for example, materialization logic in
ClangExpressionDeclMap) that is no longer used.
While implementing this fix, I also found a bug in
IRForTarget's handling of floating-point constants.
This should be fixed.
llvm-svn: 179801
2013-04-19 06:06:33 +08:00
if ( ! var_sp )
return false ;
var_sp - > EnableParserVars ( GetParserID ( ) ) ;
ClangExpressionVariable : : ParserVars * parser_vars = var_sp - > GetParserVars ( GetParserID ( ) ) ;
parser_vars - > m_named_decl = decl ;
parser_vars - > m_parser_type = parser_type ;
var_sp - > EnableJITVars ( GetParserID ( ) ) ;
ClangExpressionVariable : : JITVars * jit_vars = var_sp - > GetJITVars ( GetParserID ( ) ) ;
jit_vars - > m_offset = offset ;
return true ;
}
2013-03-28 07:08:40 +08:00
Log * log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_EXPRESSIONS ) ) ;
2012-02-10 09:22:05 +08:00
ExecutionContext & exe_ctx = m_parser_vars - > m_exe_ctx ;
Target * target = exe_ctx . GetTargetPtr ( ) ;
2011-09-22 12:58:26 +08:00
if ( target = = NULL )
return false ;
ASTContext * context ( target - > GetScratchClangASTContext ( ) - > getASTContext ( ) ) ;
2010-08-11 11:57:18 +08:00
2011-12-17 05:06:35 +08:00
TypeFromUser user_type ( m_ast_importer - > DeportType ( context ,
parser_type . GetASTContext ( ) ,
parser_type . GetOpaqueQualType ( ) ) ,
2011-01-14 05:23:32 +08:00
context ) ;
2011-11-18 11:28:09 +08:00
if ( ! user_type . GetOpaqueQualType ( ) )
{
if ( log )
log - > Printf ( " Persistent variable's type wasn't copied successfully " ) ;
return false ;
}
This patch modifies the expression parser to allow it
to execute expressions even in the absence of a process.
This allows expressions to run in situations where the
target cannot run -- e.g., to perform calculations based
on type information, or to inspect a binary's static
data.
This modification touches the following files:
lldb-private-enumerations.h
Introduce a new enum specifying the policy for
processing an expression. Some expressions should
always be JITted, for example if they are functions
that will be used over and over again. Some
expressions should always be interpreted, for
example if the target is unsafe to run. For most,
it is acceptable to JIT them, but interpretation
is preferable when possible.
Target.[h,cpp]
Have EvaluateExpression now accept the new enum.
ClangExpressionDeclMap.[cpp,h]
Add support for the IR interpreter and also make
the ClangExpressionDeclMap more robust in the
absence of a process.
ClangFunction.[cpp,h]
Add support for the new enum.
IRInterpreter.[cpp,h]
New implementation.
ClangUserExpression.[cpp,h]
Add support for the new enum, and for running
expressions in the absence of a process.
ClangExpression.h
Remove references to the old DWARF-based method
of evaluating expressions, because it has been
superseded for now.
ClangUtilityFunction.[cpp,h]
Add support for the new enum.
ClangExpressionParser.[cpp,h]
Add support for the new enum, remove references
to DWARF, and add support for checking whether
the expression could be evaluated statically.
IRForTarget.[h,cpp]
Add support for the new enum, and add utility
functions to support the interpreter.
IRToDWARF.cpp
Removed
CommandObjectExpression.cpp
Remove references to the obsolete -i option.
Process.cpp
Modify calls to ClangUserExpression::Evaluate
to pass the correct enum (for dlopen/dlclose)
SBValue.cpp
Add support for the new enum.
SBFrame.cpp
Add support for he new enum.
BreakpointOptions.cpp
Add support for the new enum.
llvm-svn: 139772
2011-09-15 10:13:07 +08:00
if ( ! m_parser_vars - > m_target_info . IsValid ( ) )
return false ;
2010-08-11 11:57:18 +08:00
2013-07-16 02:43:36 +08: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 ) ;
2010-08-24 07:09:38 +08:00
2010-12-14 10:59:59 +08:00
if ( ! var_sp )
2010-08-24 07:09:38 +08:00
return false ;
2012-09-21 07:21:16 +08:00
var_sp - > m_frozen_sp - > SetHasCompleteType ( ) ;
2011-01-13 16:53:35 +08:00
if ( is_result )
var_sp - > m_flags | = ClangExpressionVariable : : EVNeedsFreezeDry ;
else
var_sp - > m_flags | = ClangExpressionVariable : : EVKeepInTarget ; // explicitly-declared persistent variables should persist
if ( is_lvalue )
{
var_sp - > m_flags | = ClangExpressionVariable : : EVIsProgramReference ;
}
else
{
var_sp - > m_flags | = ClangExpressionVariable : : EVIsLLDBAllocated ;
var_sp - > m_flags | = ClangExpressionVariable : : EVNeedsAllocation ;
}
2013-04-13 02:10:34 +08:00
if ( m_keep_result_in_memory )
{
var_sp - > m_flags | = ClangExpressionVariable : : EVKeepInTarget ;
}
2011-01-13 16:53:35 +08:00
if ( log )
log - > Printf ( " Created persistent variable with flags 0x%hx " , var_sp - > m_flags ) ;
2013-01-16 07:29:36 +08:00
var_sp - > EnableParserVars ( GetParserID ( ) ) ;
ClangExpressionVariable : : ParserVars * parser_vars = var_sp - > GetParserVars ( GetParserID ( ) ) ;
2010-08-24 07:09:38 +08:00
2013-01-16 07:29:36 +08:00
parser_vars - > m_named_decl = decl ;
parser_vars - > m_parser_type = parser_type ;
2010-08-24 07:09:38 +08:00
return true ;
2010-08-11 11:57:18 +08:00
}
2010-07-14 05:41:46 +08:00
bool
2010-10-16 06:48:33 +08:00
ClangExpressionDeclMap : : AddValueToStruct
(
2011-07-30 10:42:06 +08:00
const NamedDecl * decl ,
2010-10-16 06:48:33 +08:00
const ConstString & name ,
llvm : : Value * value ,
size_t size ,
off_t alignment
)
2010-07-14 05:41:46 +08:00
{
2010-12-03 09:38:59 +08:00
assert ( m_struct_vars . get ( ) ) ;
assert ( m_parser_vars . get ( ) ) ;
2013-04-11 10:05:11 +08:00
bool is_persistent_variable = false ;
2013-03-28 07:08:40 +08:00
Log * log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_EXPRESSIONS ) ) ;
2010-08-31 06:17:16 +08:00
2010-12-03 09:38:59 +08:00
m_struct_vars - > m_struct_laid_out = false ;
2010-07-14 05:41:46 +08:00
2013-01-16 07:29:36 +08:00
if ( m_struct_members . GetVariable ( decl , GetParserID ( ) ) )
2010-08-24 07:09:38 +08:00
return true ;
2010-07-14 05:41:46 +08:00
2013-01-16 07:29:36 +08:00
ClangExpressionVariableSP var_sp ( m_found_entities . GetVariable ( decl , GetParserID ( ) ) ) ;
2010-08-24 07:09:38 +08:00
2010-12-14 10:59:59 +08:00
if ( ! var_sp )
2013-04-11 10:05:11 +08:00
{
2013-01-16 07:29:36 +08:00
var_sp = m_parser_vars - > m_persistent_vars - > GetVariable ( decl , GetParserID ( ) ) ;
2013-04-11 10:05:11 +08:00
is_persistent_variable = true ;
}
2010-08-24 07:09:38 +08:00
2010-12-14 10:59:59 +08:00
if ( ! var_sp )
2010-08-24 07:09:38 +08:00
return false ;
2010-08-31 06:17:16 +08:00
if ( log )
2011-11-18 11:28:09 +08:00
log - > Printf ( " Adding value for (NamedDecl*)%p [%s - %s] to the structure " ,
2010-08-31 06:17:16 +08:00
decl ,
2010-10-16 06:48:33 +08:00
name . GetCString ( ) ,
2010-12-14 10:59:59 +08:00
var_sp - > GetName ( ) . GetCString ( ) ) ;
2010-08-31 06:17:16 +08:00
2010-08-24 07:09:38 +08:00
// We know entity->m_parser_vars is valid because we used a parser variable
// to find it
2010-07-14 05:41:46 +08:00
2013-01-16 07:29:36 +08:00
ClangExpressionVariable : : ParserVars * parser_vars = var_sp - > GetParserVars ( GetParserID ( ) ) ;
parser_vars - > m_llvm_value = value ;
This commit changes the way LLDB executes user
expressions.
Previously, ClangUserExpression assumed that if
there was a constant result for an expression
then it could be determined during parsing. In
particular, the IRInterpreter ran while parser
state (in particular, ClangExpressionDeclMap)
was present. This approach is flawed, because
the IRInterpreter actually is capable of using
external variables, and hence the result might
be different each run. Until now, we papered
over this flaw by re-parsing the expression each
time we ran it.
I have rewritten the IRInterpreter to be
completely independent of the ClangExpressionDeclMap.
Instead of special-casing external variable lookup,
which ties the IRInterpreter closely to LLDB,
we now interpret the exact same IR that the JIT
would see. This IR assumes that materialization
has occurred; hence the recent implementation of the
Materializer, which does not require parser state
(in the form of ClangExpressionDeclMap) to be
present.
Materialization, interpretation, and dematerialization
are now all independent of parsing. This means that
in theory we can parse expressions once and run them
many times. I have three outstanding tasks before
shutting this down:
- First, I will ensure that all of this works with
core files. Core files have a Process but do not
allow allocating memory, which currently confuses
materialization.
- Second, I will make expression breakpoint
conditions remember their ClangUserExpression and
re-use it.
- Third, I will tear out all the redundant code
(for example, materialization logic in
ClangExpressionDeclMap) that is no longer used.
While implementing this fix, I also found a bug in
IRForTarget's handling of floating-point constants.
This should be fixed.
llvm-svn: 179801
2013-04-19 06:06:33 +08:00
if ( ClangExpressionVariable : : JITVars * jit_vars = var_sp - > GetJITVars ( GetParserID ( ) ) )
{
// We already laid this out; do not touch
if ( log )
log - > Printf ( " Already placed at 0x%llx " , ( unsigned long long ) jit_vars - > m_offset ) ;
}
2013-01-16 07:29:36 +08:00
var_sp - > EnableJITVars ( GetParserID ( ) ) ;
ClangExpressionVariable : : JITVars * jit_vars = var_sp - > GetJITVars ( GetParserID ( ) ) ;
jit_vars - > m_alignment = alignment ;
jit_vars - > m_size = size ;
2010-07-14 05:41:46 +08:00
2010-12-14 10:59:59 +08:00
m_struct_members . AddVariable ( var_sp ) ;
2010-07-14 05:41:46 +08:00
2013-04-11 10:05:11 +08:00
if ( m_parser_vars - > m_materializer )
{
2013-04-12 05:16:36 +08:00
uint32_t offset = 0 ;
2013-04-11 10:05:11 +08:00
Error err ;
if ( is_persistent_variable )
{
2013-04-12 05:16:36 +08:00
offset = m_parser_vars - > m_materializer - > AddPersistentVariable ( var_sp , err ) ;
2013-04-11 10:05:11 +08:00
}
else
{
if ( const lldb_private : : Symbol * sym = parser_vars - > m_lldb_sym )
2013-04-12 05:16:36 +08:00
offset = m_parser_vars - > m_materializer - > AddSymbol ( * sym , err ) ;
2013-04-11 10:05:11 +08:00
else if ( const RegisterInfo * reg_info = var_sp - > GetRegisterInfo ( ) )
2013-04-12 05:16:36 +08:00
offset = m_parser_vars - > m_materializer - > AddRegister ( * reg_info , err ) ;
2013-04-11 10:05:11 +08:00
else if ( parser_vars - > m_lldb_var )
2013-04-12 05:16:36 +08:00
offset = m_parser_vars - > m_materializer - > AddVariable ( parser_vars - > m_lldb_var , err ) ;
2013-04-11 10:05:11 +08:00
}
2013-04-12 05:16:36 +08:00
if ( ! err . Success ( ) )
return false ;
if ( log )
log - > Printf ( " Placed at 0x%llx " , ( unsigned long long ) offset ) ;
jit_vars - > m_offset = offset ; // TODO DoStructLayout() should not change this.
2013-04-11 10:05:11 +08:00
}
2010-07-14 05:41:46 +08:00
return true ;
}
bool
ClangExpressionDeclMap : : DoStructLayout ( )
{
2010-12-03 09:38:59 +08:00
assert ( m_struct_vars . get ( ) ) ;
if ( m_struct_vars - > m_struct_laid_out )
2010-07-14 05:41:46 +08:00
return true ;
2013-04-17 07:25:35 +08:00
if ( ! m_parser_vars - > m_materializer )
return false ;
2010-07-14 05:41:46 +08:00
2013-04-17 07:25:35 +08: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 09:38:59 +08:00
m_struct_vars - > m_struct_laid_out = true ;
2010-07-14 05:41:46 +08:00
return true ;
}
2010-10-16 06:48:33 +08:00
bool ClangExpressionDeclMap : : GetStructInfo
(
uint32_t & num_elements ,
size_t & size ,
off_t & alignment
)
2010-07-14 05:41:46 +08:00
{
2010-12-03 09:38:59 +08:00
assert ( m_struct_vars . get ( ) ) ;
if ( ! m_struct_vars - > m_struct_laid_out )
2010-07-14 05:41:46 +08:00
return false ;
2010-12-14 10:59:59 +08:00
num_elements = m_struct_members . GetSize ( ) ;
2010-12-03 09:38:59 +08:00
size = m_struct_vars - > m_struct_size ;
alignment = m_struct_vars - > m_struct_alignment ;
2010-07-14 05:41:46 +08:00
return true ;
}
bool
2010-10-16 06:48:33 +08:00
ClangExpressionDeclMap : : GetStructElement
(
2011-07-30 10:42:06 +08:00
const NamedDecl * & decl ,
2010-10-16 06:48:33 +08:00
llvm : : Value * & value ,
off_t & offset ,
ConstString & name ,
uint32_t index
)
2010-07-14 05:41:46 +08:00
{
2010-12-03 09:38:59 +08:00
assert ( m_struct_vars . get ( ) ) ;
if ( ! m_struct_vars - > m_struct_laid_out )
2010-07-14 05:41:46 +08:00
return false ;
2010-12-14 10:59:59 +08:00
if ( index > = m_struct_members . GetSize ( ) )
2010-07-14 05:41:46 +08:00
return false ;
2010-12-14 10:59:59 +08:00
ClangExpressionVariableSP member_sp ( m_struct_members . GetVariableAtIndex ( index ) ) ;
2010-08-24 07:09:38 +08:00
2013-01-16 07:29:36 +08:00
if ( ! member_sp )
return false ;
ClangExpressionVariable : : ParserVars * parser_vars = member_sp - > GetParserVars ( GetParserID ( ) ) ;
ClangExpressionVariable : : JITVars * jit_vars = member_sp - > GetJITVars ( GetParserID ( ) ) ;
if ( ! parser_vars | |
! jit_vars | |
2012-04-13 00:58:26 +08:00
! member_sp - > GetValueObject ( ) )
2010-08-24 07:09:38 +08:00
return false ;
2010-07-14 05:41:46 +08:00
2013-01-16 07:29:36 +08:00
decl = parser_vars - > m_named_decl ;
value = parser_vars - > m_llvm_value ;
offset = jit_vars - > m_offset ;
2010-12-14 10:59:59 +08:00
name = member_sp - > GetName ( ) ;
2010-08-24 07:09:38 +08:00
2010-07-14 05:41:46 +08:00
return true ;
}
2010-07-28 05:39:39 +08:00
bool
2010-10-16 06:48:33 +08:00
ClangExpressionDeclMap : : GetFunctionInfo
(
2011-07-30 10:42:06 +08:00
const NamedDecl * decl ,
2010-10-16 06:48:33 +08:00
uint64_t & ptr
)
2010-07-27 10:07:53 +08:00
{
2013-01-16 07:29:36 +08:00
ClangExpressionVariableSP entity_sp ( m_found_entities . GetVariable ( decl , GetParserID ( ) ) ) ;
2010-08-24 07:09:38 +08:00
2010-12-14 10:59:59 +08:00
if ( ! entity_sp )
2010-08-24 07:09:38 +08:00
return false ;
2010-07-27 10:07:53 +08:00
2010-08-24 07:09:38 +08:00
// We know m_parser_vars is valid since we searched for the variable by
// its NamedDecl
2010-07-27 10:07:53 +08:00
2013-01-16 07:29:36 +08:00
ClangExpressionVariable : : ParserVars * parser_vars = entity_sp - > GetParserVars ( GetParserID ( ) ) ;
2013-07-12 06:46:58 +08:00
ptr = parser_vars - > m_lldb_value . GetScalar ( ) . ULongLong ( ) ;
2010-08-24 07:09:38 +08:00
return true ;
2010-07-27 10:07:53 +08:00
}
2011-08-17 02:09:29 +08:00
static void
FindCodeSymbolInContext
(
const ConstString & name ,
SymbolContext & sym_ctx ,
SymbolContextList & sc_list
)
{
2013-02-28 04:13:38 +08:00
SymbolContextList temp_sc_list ;
2011-08-17 02:09:29 +08:00
if ( sym_ctx . module_sp )
2013-02-28 04:13:38 +08:00
sym_ctx . module_sp - > FindSymbolsWithNameAndType ( name , eSymbolTypeAny , temp_sc_list ) ;
2011-08-17 02:09:29 +08:00
2013-02-28 04:13:38 +08: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 :
sc_list . Append ( sym_ctx ) ;
break ;
default :
break ;
}
}
}
2011-08-17 02:09:29 +08:00
}
2010-07-31 09:32:05 +08:00
bool
2010-10-16 06:48:33 +08:00
ClangExpressionDeclMap : : GetFunctionAddress
(
const ConstString & name ,
2011-05-19 06:01:49 +08:00
uint64_t & func_addr
2010-10-16 06:48:33 +08:00
)
2010-07-31 09:32:05 +08:00
{
2010-12-03 09:38:59 +08:00
assert ( m_parser_vars . get ( ) ) ;
2013-03-28 07:08:40 +08:00
Log * log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_EXPRESSIONS ) ) ;
2012-02-10 09:22:05 +08:00
ExecutionContext & exe_ctx = m_parser_vars - > m_exe_ctx ;
Target * target = exe_ctx . GetTargetPtr ( ) ;
2010-07-31 09:32:05 +08:00
// Back out in all cases where we're not fully initialized
2011-09-22 12:58:26 +08:00
if ( target = = NULL )
2010-12-07 09:56:02 +08:00
return false ;
if ( ! m_parser_vars - > m_sym_ctx . target_sp )
2010-07-31 09:32:05 +08:00
return false ;
2010-11-10 07:46:37 +08:00
SymbolContextList sc_list ;
2010-07-31 09:32:05 +08:00
2011-08-17 02:09:29 +08:00
FindCodeSymbolInContext ( name , m_parser_vars - > m_sym_ctx , sc_list ) ;
2013-02-28 04:13:38 +08:00
2010-11-10 07:46:37 +08:00
if ( ! sc_list . GetSize ( ) )
2011-05-14 02:27:02 +08:00
{
// We occasionally get debug information in which a const function is reported
// as non-const, so the mangled name is wrong. This is a hack to compensate.
2011-10-26 02:02:05 +08:00
if ( ! strncmp ( name . GetCString ( ) , " _ZN " , 3 ) & &
strncmp ( name . GetCString ( ) , " _ZNK " , 4 ) )
2011-05-14 02:27:02 +08:00
{
2011-10-26 02:02:05 +08:00
std : : string fixed_scratch ( " _ZNK " ) ;
fixed_scratch . append ( name . GetCString ( ) + 3 ) ;
ConstString fixed_name ( fixed_scratch . c_str ( ) ) ;
2011-05-14 02:27:02 +08:00
if ( log )
2011-10-26 02:02:05 +08:00
log - > Printf ( " Failed to find symbols given non-const name %s; trying %s " , name . GetCString ( ) , fixed_name . GetCString ( ) ) ;
FindCodeSymbolInContext ( fixed_name , m_parser_vars - > m_sym_ctx , sc_list ) ;
2011-05-14 02:27:02 +08:00
}
}
if ( ! sc_list . GetSize ( ) )
2010-07-31 09:32:05 +08:00
return false ;
2013-02-28 04:13:38 +08:00
2010-07-31 09:32:05 +08:00
SymbolContext sym_ctx ;
2010-11-10 07:46:37 +08:00
sc_list . GetContextAtIndex ( 0 , sym_ctx ) ;
2013-02-28 04:13:38 +08:00
2011-05-19 06:01:49 +08:00
const Address * func_so_addr = NULL ;
2013-02-28 04:13:38 +08:00
bool is_indirect_function = false ;
2010-07-31 09:32:05 +08:00
if ( sym_ctx . function )
2011-05-19 06:01:49 +08:00
func_so_addr = & sym_ctx . function - > GetAddressRange ( ) . GetBaseAddress ( ) ;
2013-02-28 04:13:38 +08:00
else if ( sym_ctx . symbol ) {
2012-03-08 05:03:09 +08:00
func_so_addr = & sym_ctx . symbol - > GetAddress ( ) ;
2013-02-28 04:13:38 +08:00
is_indirect_function = sym_ctx . symbol - > IsIndirect ( ) ;
} else
2010-07-31 09:32:05 +08:00
return false ;
2013-02-28 04:13:38 +08:00
2011-07-08 07:05:43 +08:00
if ( ! func_so_addr | | ! func_so_addr - > IsValid ( ) )
return false ;
2013-02-28 04:13:38 +08:00
func_addr = func_so_addr - > GetCallableLoadAddress ( target , is_indirect_function ) ;
2011-05-19 06:01:49 +08:00
2010-07-31 09:32:05 +08:00
return true ;
}
2011-06-23 12:25:29 +08:00
addr_t
2012-11-15 10:02:04 +08:00
ClangExpressionDeclMap : : GetSymbolAddress ( Target & target , Process * process , const ConstString & name , lldb : : SymbolType symbol_type )
2011-01-18 07:42:46 +08:00
{
SymbolContextList sc_list ;
2011-12-01 10:04:16 +08:00
target . GetImages ( ) . FindSymbolsWithNameAndType ( name , symbol_type , sc_list ) ;
2011-01-18 07:42:46 +08:00
2011-06-23 12:25:29 +08:00
const uint32_t num_matches = sc_list . GetSize ( ) ;
addr_t symbol_load_addr = LLDB_INVALID_ADDRESS ;
2011-12-01 10:04:16 +08:00
for ( uint32_t i = 0 ; i < num_matches & & ( symbol_load_addr = = 0 | | symbol_load_addr = = LLDB_INVALID_ADDRESS ) ; i + + )
2011-06-23 12:25:29 +08:00
{
SymbolContext sym_ctx ;
sc_list . GetContextAtIndex ( i , sym_ctx ) ;
2011-01-18 07:42:46 +08:00
2012-03-08 05:03:09 +08:00
const Address * sym_address = & sym_ctx . symbol - > GetAddress ( ) ;
2011-07-08 07:05:43 +08:00
if ( ! sym_address | | ! sym_address - > IsValid ( ) )
2013-04-30 08:21:42 +08:00
continue ;
2011-07-08 07:05:43 +08:00
2011-06-23 12:25:29 +08:00
if ( sym_address )
{
switch ( sym_ctx . symbol - > GetType ( ) )
{
case eSymbolTypeCode :
case eSymbolTypeTrampoline :
symbol_load_addr = sym_address - > GetCallableLoadAddress ( & target ) ;
break ;
2013-02-28 04:13:38 +08:00
case eSymbolTypeResolver :
symbol_load_addr = sym_address - > GetCallableLoadAddress ( & target , true ) ;
break ;
2011-06-23 12:25:29 +08: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 10:30:59 +08:00
case eSymbolTypeObjCClass :
case eSymbolTypeObjCMetaClass :
case eSymbolTypeObjCIVar :
2011-06-23 12:25:29 +08:00
symbol_load_addr = sym_address - > GetLoadAddress ( & target ) ;
break ;
}
}
}
2011-01-18 07:42:46 +08:00
2012-11-15 10:02:04 +08:00
if ( symbol_load_addr = = LLDB_INVALID_ADDRESS & & process )
{
ObjCLanguageRuntime * runtime = process - > GetObjCLanguageRuntime ( ) ;
if ( runtime )
{
symbol_load_addr = runtime - > LookupRuntimeSymbol ( name ) ;
}
}
2011-06-23 12:25:29 +08:00
return symbol_load_addr ;
2011-01-18 07:42:46 +08:00
}
2011-06-23 12:25:29 +08:00
addr_t
2011-12-01 10:04:16 +08:00
ClangExpressionDeclMap : : GetSymbolAddress ( const ConstString & name , lldb : : SymbolType symbol_type )
2011-05-08 10:21:26 +08:00
{
assert ( m_parser_vars . get ( ) ) ;
2012-02-10 09:22:05 +08:00
if ( ! m_parser_vars - > m_exe_ctx . GetTargetPtr ( ) )
2011-05-08 10:21:26 +08:00
return false ;
2012-11-15 10:02:04 +08:00
return GetSymbolAddress ( m_parser_vars - > m_exe_ctx . GetTargetRef ( ) , m_parser_vars - > m_exe_ctx . GetProcessPtr ( ) , name , symbol_type ) ;
2011-05-08 10:21:26 +08:00
}
2012-11-27 09:52:16 +08:00
const Symbol *
ClangExpressionDeclMap : : FindGlobalDataSymbol ( Target & target ,
const ConstString & name )
2011-05-08 10:21:26 +08:00
{
SymbolContextList sc_list ;
2012-11-27 09:52:16 +08:00
target . GetImages ( ) . FindSymbolsWithNameAndType ( name , eSymbolTypeAny , sc_list ) ;
2011-05-08 10:21:26 +08:00
2012-11-27 09:52:16 +08:00
const uint32_t matches = sc_list . GetSize ( ) ;
for ( uint32_t i = 0 ; i < matches ; + + i )
2011-05-08 10:21:26 +08:00
{
SymbolContext sym_ctx ;
2012-11-27 09:52:16 +08:00
sc_list . GetContextAtIndex ( i , sym_ctx ) ;
if ( sym_ctx . symbol )
{
const Symbol * symbol = sym_ctx . symbol ;
const Address * sym_address = & symbol - > GetAddress ( ) ;
if ( sym_address & & sym_address - > IsValid ( ) )
{
switch ( symbol - > GetType ( ) )
{
case eSymbolTypeData :
case eSymbolTypeRuntime :
case eSymbolTypeAbsolute :
case eSymbolTypeObjCClass :
case eSymbolTypeObjCMetaClass :
case eSymbolTypeObjCIVar :
if ( symbol - > GetDemangledNameIsSynthesized ( ) )
{
// If the demangled name was synthesized, then don't use it
// for expressions. Only let the symbol match if the mangled
// named matches for these symbols.
if ( symbol - > GetMangled ( ) . GetMangledName ( ) ! = name )
break ;
}
return symbol ;
case eSymbolTypeCode : // We already lookup functions elsewhere
case eSymbolTypeVariable :
case eSymbolTypeLocal :
case eSymbolTypeParam :
case eSymbolTypeTrampoline :
case eSymbolTypeInvalid :
case eSymbolTypeException :
case eSymbolTypeSourceFile :
case eSymbolTypeHeaderFile :
case eSymbolTypeObjectFile :
case eSymbolTypeCommonBlock :
case eSymbolTypeBlock :
case eSymbolTypeVariableType :
case eSymbolTypeLineEntry :
case eSymbolTypeLineHeader :
case eSymbolTypeScopeBegin :
case eSymbolTypeScopeEnd :
case eSymbolTypeAdditional :
case eSymbolTypeCompiler :
case eSymbolTypeInstrumentation :
case eSymbolTypeUndefined :
2013-02-28 04:13:38 +08:00
case eSymbolTypeResolver :
2012-11-27 09:52:16 +08:00
break ;
}
}
}
2011-05-08 10:21:26 +08:00
}
return NULL ;
}
This patch modifies the expression parser to allow it
to execute expressions even in the absence of a process.
This allows expressions to run in situations where the
target cannot run -- e.g., to perform calculations based
on type information, or to inspect a binary's static
data.
This modification touches the following files:
lldb-private-enumerations.h
Introduce a new enum specifying the policy for
processing an expression. Some expressions should
always be JITted, for example if they are functions
that will be used over and over again. Some
expressions should always be interpreted, for
example if the target is unsafe to run. For most,
it is acceptable to JIT them, but interpretation
is preferable when possible.
Target.[h,cpp]
Have EvaluateExpression now accept the new enum.
ClangExpressionDeclMap.[cpp,h]
Add support for the IR interpreter and also make
the ClangExpressionDeclMap more robust in the
absence of a process.
ClangFunction.[cpp,h]
Add support for the new enum.
IRInterpreter.[cpp,h]
New implementation.
ClangUserExpression.[cpp,h]
Add support for the new enum, and for running
expressions in the absence of a process.
ClangExpression.h
Remove references to the old DWARF-based method
of evaluating expressions, because it has been
superseded for now.
ClangUtilityFunction.[cpp,h]
Add support for the new enum.
ClangExpressionParser.[cpp,h]
Add support for the new enum, remove references
to DWARF, and add support for checking whether
the expression could be evaluated statically.
IRForTarget.[h,cpp]
Add support for the new enum, and add utility
functions to support the interpreter.
IRToDWARF.cpp
Removed
CommandObjectExpression.cpp
Remove references to the obsolete -i option.
Process.cpp
Modify calls to ClangUserExpression::Evaluate
to pass the correct enum (for dlopen/dlclose)
SBValue.cpp
Add support for the new enum.
SBFrame.cpp
Add support for he new enum.
BreakpointOptions.cpp
Add support for the new enum.
llvm-svn: 139772
2011-09-15 10:13:07 +08:00
lldb : : VariableSP
ClangExpressionDeclMap : : FindGlobalVariable
(
Target & target ,
2011-10-13 00:59:31 +08:00
ModuleSP & module ,
const ConstString & name ,
ClangNamespaceDecl * namespace_decl ,
This patch modifies the expression parser to allow it
to execute expressions even in the absence of a process.
This allows expressions to run in situations where the
target cannot run -- e.g., to perform calculations based
on type information, or to inspect a binary's static
data.
This modification touches the following files:
lldb-private-enumerations.h
Introduce a new enum specifying the policy for
processing an expression. Some expressions should
always be JITted, for example if they are functions
that will be used over and over again. Some
expressions should always be interpreted, for
example if the target is unsafe to run. For most,
it is acceptable to JIT them, but interpretation
is preferable when possible.
Target.[h,cpp]
Have EvaluateExpression now accept the new enum.
ClangExpressionDeclMap.[cpp,h]
Add support for the IR interpreter and also make
the ClangExpressionDeclMap more robust in the
absence of a process.
ClangFunction.[cpp,h]
Add support for the new enum.
IRInterpreter.[cpp,h]
New implementation.
ClangUserExpression.[cpp,h]
Add support for the new enum, and for running
expressions in the absence of a process.
ClangExpression.h
Remove references to the old DWARF-based method
of evaluating expressions, because it has been
superseded for now.
ClangUtilityFunction.[cpp,h]
Add support for the new enum.
ClangExpressionParser.[cpp,h]
Add support for the new enum, remove references
to DWARF, and add support for checking whether
the expression could be evaluated statically.
IRForTarget.[h,cpp]
Add support for the new enum, and add utility
functions to support the interpreter.
IRToDWARF.cpp
Removed
CommandObjectExpression.cpp
Remove references to the obsolete -i option.
Process.cpp
Modify calls to ClangUserExpression::Evaluate
to pass the correct enum (for dlopen/dlclose)
SBValue.cpp
Add support for the new enum.
SBFrame.cpp
Add support for he new enum.
BreakpointOptions.cpp
Add support for the new enum.
llvm-svn: 139772
2011-09-15 10:13:07 +08:00
TypeFromUser * type
)
{
VariableList vars ;
2011-10-13 00:59:31 +08:00
if ( module & & namespace_decl )
module - > FindGlobalVariables ( name , namespace_decl , true , - 1 , vars ) ;
else
target . GetImages ( ) . FindGlobalVariables ( name , true , - 1 , vars ) ;
This patch modifies the expression parser to allow it
to execute expressions even in the absence of a process.
This allows expressions to run in situations where the
target cannot run -- e.g., to perform calculations based
on type information, or to inspect a binary's static
data.
This modification touches the following files:
lldb-private-enumerations.h
Introduce a new enum specifying the policy for
processing an expression. Some expressions should
always be JITted, for example if they are functions
that will be used over and over again. Some
expressions should always be interpreted, for
example if the target is unsafe to run. For most,
it is acceptable to JIT them, but interpretation
is preferable when possible.
Target.[h,cpp]
Have EvaluateExpression now accept the new enum.
ClangExpressionDeclMap.[cpp,h]
Add support for the IR interpreter and also make
the ClangExpressionDeclMap more robust in the
absence of a process.
ClangFunction.[cpp,h]
Add support for the new enum.
IRInterpreter.[cpp,h]
New implementation.
ClangUserExpression.[cpp,h]
Add support for the new enum, and for running
expressions in the absence of a process.
ClangExpression.h
Remove references to the old DWARF-based method
of evaluating expressions, because it has been
superseded for now.
ClangUtilityFunction.[cpp,h]
Add support for the new enum.
ClangExpressionParser.[cpp,h]
Add support for the new enum, remove references
to DWARF, and add support for checking whether
the expression could be evaluated statically.
IRForTarget.[h,cpp]
Add support for the new enum, and add utility
functions to support the interpreter.
IRToDWARF.cpp
Removed
CommandObjectExpression.cpp
Remove references to the obsolete -i option.
Process.cpp
Modify calls to ClangUserExpression::Evaluate
to pass the correct enum (for dlopen/dlclose)
SBValue.cpp
Add support for the new enum.
SBFrame.cpp
Add support for he new enum.
BreakpointOptions.cpp
Add support for the new enum.
llvm-svn: 139772
2011-09-15 10:13:07 +08:00
if ( vars . GetSize ( ) )
{
if ( type )
{
for ( size_t i = 0 ; i < vars . GetSize ( ) ; + + i )
{
VariableSP var_sp = vars . GetVariableAtIndex ( i ) ;
2013-07-12 06:46:58 +08:00
if ( ClangASTContext : : AreTypesSame ( * type , var_sp - > GetType ( ) - > GetClangFullType ( ) ) )
return var_sp ;
This patch modifies the expression parser to allow it
to execute expressions even in the absence of a process.
This allows expressions to run in situations where the
target cannot run -- e.g., to perform calculations based
on type information, or to inspect a binary's static
data.
This modification touches the following files:
lldb-private-enumerations.h
Introduce a new enum specifying the policy for
processing an expression. Some expressions should
always be JITted, for example if they are functions
that will be used over and over again. Some
expressions should always be interpreted, for
example if the target is unsafe to run. For most,
it is acceptable to JIT them, but interpretation
is preferable when possible.
Target.[h,cpp]
Have EvaluateExpression now accept the new enum.
ClangExpressionDeclMap.[cpp,h]
Add support for the IR interpreter and also make
the ClangExpressionDeclMap more robust in the
absence of a process.
ClangFunction.[cpp,h]
Add support for the new enum.
IRInterpreter.[cpp,h]
New implementation.
ClangUserExpression.[cpp,h]
Add support for the new enum, and for running
expressions in the absence of a process.
ClangExpression.h
Remove references to the old DWARF-based method
of evaluating expressions, because it has been
superseded for now.
ClangUtilityFunction.[cpp,h]
Add support for the new enum.
ClangExpressionParser.[cpp,h]
Add support for the new enum, remove references
to DWARF, and add support for checking whether
the expression could be evaluated statically.
IRForTarget.[h,cpp]
Add support for the new enum, and add utility
functions to support the interpreter.
IRToDWARF.cpp
Removed
CommandObjectExpression.cpp
Remove references to the obsolete -i option.
Process.cpp
Modify calls to ClangUserExpression::Evaluate
to pass the correct enum (for dlopen/dlclose)
SBValue.cpp
Add support for the new enum.
SBFrame.cpp
Add support for he new enum.
BreakpointOptions.cpp
Add support for the new enum.
llvm-svn: 139772
2011-09-15 10:13:07 +08:00
}
}
else
{
return vars . GetVariableAtIndex ( 0 ) ;
}
}
return VariableSP ( ) ;
}
2010-06-09 00:52:24 +08:00
// Interface for ClangASTSource
This patch modifies the expression parser to allow it
to execute expressions even in the absence of a process.
This allows expressions to run in situations where the
target cannot run -- e.g., to perform calculations based
on type information, or to inspect a binary's static
data.
This modification touches the following files:
lldb-private-enumerations.h
Introduce a new enum specifying the policy for
processing an expression. Some expressions should
always be JITted, for example if they are functions
that will be used over and over again. Some
expressions should always be interpreted, for
example if the target is unsafe to run. For most,
it is acceptable to JIT them, but interpretation
is preferable when possible.
Target.[h,cpp]
Have EvaluateExpression now accept the new enum.
ClangExpressionDeclMap.[cpp,h]
Add support for the IR interpreter and also make
the ClangExpressionDeclMap more robust in the
absence of a process.
ClangFunction.[cpp,h]
Add support for the new enum.
IRInterpreter.[cpp,h]
New implementation.
ClangUserExpression.[cpp,h]
Add support for the new enum, and for running
expressions in the absence of a process.
ClangExpression.h
Remove references to the old DWARF-based method
of evaluating expressions, because it has been
superseded for now.
ClangUtilityFunction.[cpp,h]
Add support for the new enum.
ClangExpressionParser.[cpp,h]
Add support for the new enum, remove references
to DWARF, and add support for checking whether
the expression could be evaluated statically.
IRForTarget.[h,cpp]
Add support for the new enum, and add utility
functions to support the interpreter.
IRToDWARF.cpp
Removed
CommandObjectExpression.cpp
Remove references to the obsolete -i option.
Process.cpp
Modify calls to ClangUserExpression::Evaluate
to pass the correct enum (for dlopen/dlclose)
SBValue.cpp
Add support for the new enum.
SBFrame.cpp
Add support for he new enum.
BreakpointOptions.cpp
Add support for the new enum.
llvm-svn: 139772
2011-09-15 10:13:07 +08:00
2011-10-12 08:12:34 +08:00
void
2011-10-29 07:38:38 +08:00
ClangExpressionDeclMap : : FindExternalVisibleDecls ( NameSearchContext & context )
2010-06-09 00:52:24 +08:00
{
2011-10-29 07:38:38 +08:00
assert ( m_ast_context ) ;
2013-03-09 04:04:57 +08:00
ClangASTMetrics : : RegisterVisibleQuery ( ) ;
2011-10-29 07:38:38 +08:00
const ConstString name ( context . m_decl_name . getAsString ( ) . c_str ( ) ) ;
2013-03-28 07:08:40 +08:00
Log * log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_EXPRESSIONS ) ) ;
2010-06-09 00:52:24 +08:00
2011-10-30 03:50:43 +08:00
if ( GetImportInProgress ( ) )
2010-11-20 04:20:02 +08:00
{
2011-10-15 04:34:21 +08:00
if ( log & & log - > GetVerbose ( ) )
2010-11-20 04:20:02 +08:00
log - > Printf ( " Ignoring a query during an import " ) ;
return ;
}
2011-06-25 08:44:06 +08:00
2011-10-15 04:34:21 +08:00
static unsigned int invocation_id = 0 ;
unsigned int current_id = invocation_id + + ;
2011-10-12 08:12:34 +08:00
if ( log )
{
if ( ! context . m_decl_context )
2011-10-30 03:50:43 +08:00
log - > Printf ( " ClangExpressionDeclMap::FindExternalVisibleDecls[%u] for '%s' in a NULL DeclContext " , current_id , name . GetCString ( ) ) ;
2011-10-12 08:12:34 +08:00
else if ( const NamedDecl * context_named_decl = dyn_cast < NamedDecl > ( context . m_decl_context ) )
2011-10-30 03:50:43 +08:00
log - > Printf ( " ClangExpressionDeclMap::FindExternalVisibleDecls[%u] for '%s' in '%s' " , current_id , name . GetCString ( ) , context_named_decl - > getNameAsString ( ) . c_str ( ) ) ;
2011-10-12 08:12:34 +08:00
else
2011-10-30 03:50:43 +08:00
log - > Printf ( " ClangExpressionDeclMap::FindExternalVisibleDecls[%u] for '%s' in a '%s' " , current_id , name . GetCString ( ) , context . m_decl_context - > getDeclKindName ( ) ) ;
2011-10-12 08:12:34 +08:00
}
2011-10-30 03:50:43 +08:00
2011-10-12 08:12:34 +08:00
if ( const NamespaceDecl * namespace_context = dyn_cast < NamespaceDecl > ( context . m_decl_context ) )
{
2011-10-29 09:58:46 +08:00
ClangASTImporter : : NamespaceMapSP namespace_map = m_ast_importer - > GetNamespaceMap ( namespace_context ) ;
2011-10-14 05:08:11 +08:00
2011-10-15 04:34:21 +08:00
if ( log & & log - > GetVerbose ( ) )
2011-11-18 11:28:09 +08:00
log - > Printf ( " CEDM::FEVD[%u] Inspecting (NamespaceMap*)%p (%d entries) " ,
2011-10-15 04:34:21 +08:00
current_id ,
namespace_map . get ( ) ,
( int ) namespace_map - > size ( ) ) ;
2011-10-14 05:08:11 +08:00
2011-10-22 06:18:07 +08:00
if ( ! namespace_map )
return ;
2011-10-12 08:12:34 +08:00
for ( ClangASTImporter : : NamespaceMap : : iterator i = namespace_map - > begin ( ) , e = namespace_map - > end ( ) ;
i ! = e ;
+ + i )
{
if ( log )
2011-10-30 03:50:43 +08:00
log - > Printf ( " CEDM::FEVD[%u] Searching namespace %s in module %s " ,
2011-10-15 04:34:21 +08:00
current_id ,
2011-10-12 08:12:34 +08:00
i - > second . GetNamespaceDecl ( ) - > getNameAsString ( ) . c_str ( ) ,
i - > first - > GetFileSpec ( ) . GetFilename ( ) . GetCString ( ) ) ;
2011-10-14 05:50:33 +08:00
FindExternalVisibleDecls ( context ,
i - > first ,
i - > second ,
2011-10-15 04:34:21 +08:00
current_id ) ;
2011-10-12 08:12:34 +08:00
}
}
2011-11-15 10:11:17 +08:00
else if ( isa < TranslationUnitDecl > ( context . m_decl_context ) )
2011-10-12 08:12:34 +08:00
{
ClangNamespaceDecl namespace_decl ;
if ( log )
2011-10-30 03:50:43 +08:00
log - > Printf ( " CEDM::FEVD[%u] Searching the root namespace " , current_id ) ;
2011-10-12 08:12:34 +08:00
FindExternalVisibleDecls ( context ,
lldb : : ModuleSP ( ) ,
namespace_decl ,
2011-10-15 04:34:21 +08:00
current_id ) ;
2011-10-12 08:12:34 +08:00
}
2011-10-14 05:08:11 +08:00
2011-10-30 03:50:43 +08:00
if ( ! context . m_found . variable )
ClangASTSource : : FindExternalVisibleDecls ( context ) ;
2011-10-12 08:12:34 +08:00
}
void
ClangExpressionDeclMap : : FindExternalVisibleDecls ( NameSearchContext & context ,
2011-10-13 02:44:30 +08:00
lldb : : ModuleSP module_sp ,
2011-10-12 09:39:28 +08:00
ClangNamespaceDecl & namespace_decl ,
2011-10-15 04:34:21 +08:00
unsigned int current_id )
2011-10-12 08:12:34 +08:00
{
2011-10-29 07:38:38 +08:00
assert ( m_ast_context ) ;
2011-10-12 08:12:34 +08:00
2013-03-28 07:08:40 +08:00
Log * log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_EXPRESSIONS ) ) ;
2011-10-30 03:50:43 +08:00
2010-11-10 07:46:37 +08:00
SymbolContextList sc_list ;
2010-06-09 00:52:24 +08:00
2011-10-30 03:50:43 +08:00
const ConstString name ( context . m_decl_name . getAsString ( ) . c_str ( ) ) ;
Just like functions can have a basename and a mangled/demangled name, variable
can too. So now the lldb_private::Variable class has support for this.
Variables now have support for having a basename ("i"), and a mangled name
("_ZN12_GLOBAL__N_11iE"), and a demangled name ("(anonymous namespace)::i").
Nowwhen searching for a variable by name, users might enter the fully qualified
name, or just the basename. So new test functions were added to the Variable
and Mangled classes as:
bool NameMatches (const ConstString &name);
bool NameMatches (const RegularExpression ®ex);
I also modified "ClangExpressionDeclMap::FindVariableInScope" to also search
for global variables that are not in the current file scope by first starting
with the current module, then moving on to all modules.
Fixed an issue in the DWARF parser that could cause a varaible to get parsed
more than once. Now, once we have parsed a VariableSP for a DIE, we cache
the result even if a variable wasn't made so we don't do any re-parsing. Some
DW_TAG_variable DIEs don't have locations, or are missing vital info that
stops a debugger from being able to display anything for it, we parse a NULL
variable shared pointer for these DIEs so we don't keep trying to reparse it.
llvm-svn: 119085
2010-11-15 06:13:40 +08:00
const char * name_unique_cstr = name . GetCString ( ) ;
if ( name_unique_cstr = = NULL )
return ;
2011-10-30 03:50:43 +08:00
2012-02-04 16:49:35 +08:00
static ConstString id_name ( " id " ) ;
static ConstString Class_name ( " Class " ) ;
if ( name = = id_name | | name = = Class_name )
return ;
2010-10-16 06:48:33 +08:00
// Only look for functions by name out in our symbols if the function
// doesn't start with our phony prefix of '$'
2012-02-10 09:22:05 +08:00
Target * target = m_parser_vars - > m_exe_ctx . GetTargetPtr ( ) ;
StackFrame * frame = m_parser_vars - > m_exe_ctx . GetFramePtr ( ) ;
2011-10-12 09:39:28 +08:00
if ( name_unique_cstr [ 0 ] = = ' $ ' & & ! namespace_decl )
2010-10-06 08:10:07 +08:00
{
2010-11-09 12:42:43 +08:00
static ConstString g_lldb_class_name ( " $__lldb_class " ) ;
This patch modifies the expression parser to allow it
to execute expressions even in the absence of a process.
This allows expressions to run in situations where the
target cannot run -- e.g., to perform calculations based
on type information, or to inspect a binary's static
data.
This modification touches the following files:
lldb-private-enumerations.h
Introduce a new enum specifying the policy for
processing an expression. Some expressions should
always be JITted, for example if they are functions
that will be used over and over again. Some
expressions should always be interpreted, for
example if the target is unsafe to run. For most,
it is acceptable to JIT them, but interpretation
is preferable when possible.
Target.[h,cpp]
Have EvaluateExpression now accept the new enum.
ClangExpressionDeclMap.[cpp,h]
Add support for the IR interpreter and also make
the ClangExpressionDeclMap more robust in the
absence of a process.
ClangFunction.[cpp,h]
Add support for the new enum.
IRInterpreter.[cpp,h]
New implementation.
ClangUserExpression.[cpp,h]
Add support for the new enum, and for running
expressions in the absence of a process.
ClangExpression.h
Remove references to the old DWARF-based method
of evaluating expressions, because it has been
superseded for now.
ClangUtilityFunction.[cpp,h]
Add support for the new enum.
ClangExpressionParser.[cpp,h]
Add support for the new enum, remove references
to DWARF, and add support for checking whether
the expression could be evaluated statically.
IRForTarget.[h,cpp]
Add support for the new enum, and add utility
functions to support the interpreter.
IRToDWARF.cpp
Removed
CommandObjectExpression.cpp
Remove references to the obsolete -i option.
Process.cpp
Modify calls to ClangUserExpression::Evaluate
to pass the correct enum (for dlopen/dlclose)
SBValue.cpp
Add support for the new enum.
SBFrame.cpp
Add support for he new enum.
BreakpointOptions.cpp
Add support for the new enum.
llvm-svn: 139772
2011-09-15 10:13:07 +08:00
2010-11-09 12:42:43 +08:00
if ( name = = g_lldb_class_name )
{
// Clang is looking for the type of "this"
2012-02-08 11:45:08 +08:00
if ( frame = = NULL )
This patch modifies the expression parser to allow it
to execute expressions even in the absence of a process.
This allows expressions to run in situations where the
target cannot run -- e.g., to perform calculations based
on type information, or to inspect a binary's static
data.
This modification touches the following files:
lldb-private-enumerations.h
Introduce a new enum specifying the policy for
processing an expression. Some expressions should
always be JITted, for example if they are functions
that will be used over and over again. Some
expressions should always be interpreted, for
example if the target is unsafe to run. For most,
it is acceptable to JIT them, but interpretation
is preferable when possible.
Target.[h,cpp]
Have EvaluateExpression now accept the new enum.
ClangExpressionDeclMap.[cpp,h]
Add support for the IR interpreter and also make
the ClangExpressionDeclMap more robust in the
absence of a process.
ClangFunction.[cpp,h]
Add support for the new enum.
IRInterpreter.[cpp,h]
New implementation.
ClangUserExpression.[cpp,h]
Add support for the new enum, and for running
expressions in the absence of a process.
ClangExpression.h
Remove references to the old DWARF-based method
of evaluating expressions, because it has been
superseded for now.
ClangUtilityFunction.[cpp,h]
Add support for the new enum.
ClangExpressionParser.[cpp,h]
Add support for the new enum, remove references
to DWARF, and add support for checking whether
the expression could be evaluated statically.
IRForTarget.[h,cpp]
Add support for the new enum, and add utility
functions to support the interpreter.
IRToDWARF.cpp
Removed
CommandObjectExpression.cpp
Remove references to the obsolete -i option.
Process.cpp
Modify calls to ClangUserExpression::Evaluate
to pass the correct enum (for dlopen/dlclose)
SBValue.cpp
Add support for the new enum.
SBFrame.cpp
Add support for he new enum.
BreakpointOptions.cpp
Add support for the new enum.
llvm-svn: 139772
2011-09-15 10:13:07 +08:00
return ;
2012-02-08 11:45:08 +08:00
SymbolContext sym_ctx = frame - > GetSymbolContext ( lldb : : eSymbolContextFunction ) ;
2010-11-09 12:42:43 +08:00
2012-02-08 11:45:08 +08:00
if ( ! sym_ctx . function )
2010-11-09 12:42:43 +08:00
return ;
2012-07-14 08:53:55 +08: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 ( ) ;
2010-11-09 12:42:43 +08:00
2012-02-08 11:45:08 +08:00
if ( ! decl_context )
2010-11-09 12:42:43 +08:00
return ;
2012-02-08 11:45:08 +08:00
clang : : CXXMethodDecl * method_decl = llvm : : dyn_cast < clang : : CXXMethodDecl > ( decl_context ) ;
2010-11-09 12:42:43 +08:00
2012-10-31 07:35:54 +08:00
if ( method_decl )
2010-12-14 06:46:15 +08:00
{
2012-10-31 07:35:54 +08:00
clang : : CXXRecordDecl * class_decl = method_decl - > getParent ( ) ;
QualType class_qual_type ( class_decl - > getTypeForDecl ( ) , 0 ) ;
TypeFromUser class_user_type ( class_qual_type . getAsOpaquePtr ( ) ,
& class_decl - > getASTContext ( ) ) ;
if ( log )
{
ASTDumper ast_dumper ( class_qual_type ) ;
log - > Printf ( " CEDM::FEVD[%u] Adding type for $__lldb_class: %s " , current_id , ast_dumper . GetCString ( ) ) ;
}
2013-02-01 14:55:48 +08:00
TypeFromParser class_type = CopyClassType ( class_user_type , current_id ) ;
if ( ! class_type . IsValid ( ) )
return ;
2013-03-13 05:22:00 +08:00
TypeSourceInfo * type_source_info = m_ast_context - > getTrivialTypeSourceInfo ( QualType : : getFromOpaquePtr ( class_type . GetOpaqueQualType ( ) ) ) ;
2013-02-01 14:55:48 +08:00
if ( ! type_source_info )
return ;
TypedefDecl * typedef_decl = TypedefDecl : : Create ( * m_ast_context ,
m_ast_context - > getTranslationUnitDecl ( ) ,
SourceLocation ( ) ,
SourceLocation ( ) ,
context . m_decl_name . getAsIdentifierInfo ( ) ,
type_source_info ) ;
if ( ! typedef_decl )
return ;
context . AddNamedDecl ( typedef_decl ) ;
2012-10-31 07:35:54 +08:00
if ( method_decl - > isInstance ( ) )
{
// self is a pointer to the object
QualType class_pointer_type = method_decl - > getASTContext ( ) . getPointerType ( class_qual_type ) ;
TypeFromUser self_user_type ( class_pointer_type . getAsOpaquePtr ( ) ,
& method_decl - > getASTContext ( ) ) ;
m_struct_vars - > m_object_pointer_type = self_user_type ;
}
}
else
2012-03-06 06:08:20 +08:00
{
2012-10-31 07:35:54 +08:00
// This branch will get hit if we are executing code in the context of a function that
// claims to have an object pointer (through DW_AT_object_pointer?) but is not formally a
// method of the class. In that case, just look up the "this" variable in the the current
// scope and use its type.
// FIXME: This code is formally correct, but clang doesn't currently emit DW_AT_object_pointer
// for C++ so it hasn't actually been tested.
2012-03-06 06:08:20 +08:00
2012-10-31 07:35:54 +08:00
VariableList * vars = frame - > GetVariableList ( false ) ;
2012-03-06 06:08:20 +08:00
2012-10-31 07:35:54 +08:00
lldb : : VariableSP this_var = vars - > FindVariable ( ConstString ( " this " ) ) ;
2012-03-06 06:08:20 +08:00
2012-10-31 07:35:54 +08:00
if ( this_var & &
this_var - > IsInScope ( frame ) & &
this_var - > LocationIsValidForFrame ( frame ) )
{
Type * this_type = this_var - > GetType ( ) ;
if ( ! this_type )
return ;
2013-07-12 06:46:58 +08:00
ClangASTType pointee_type = this_type - > GetClangForwardType ( ) . GetPointeeType ( ) ;
2012-10-31 07:35:54 +08:00
2013-07-12 06:46:58 +08:00
if ( pointee_type . IsValid ( ) )
2012-10-31 07:35:54 +08: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 ( ) ) ;
}
2013-07-12 06:46:58 +08:00
TypeFromUser class_user_type ( pointee_type ) ;
2013-02-01 14:55:48 +08:00
AddOneType ( context , class_user_type , current_id ) ;
2012-10-31 07:35:54 +08:00
2013-07-12 06:46:58 +08:00
TypeFromUser this_user_type ( this_type - > GetClangFullType ( ) ) ;
2012-10-31 07:35:54 +08:00
m_struct_vars - > m_object_pointer_type = this_user_type ;
return ;
}
}
2012-03-06 06:08:20 +08:00
}
2010-11-09 12:42:43 +08:00
return ;
}
2010-12-14 06:46:15 +08: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"
2011-09-22 12:58:26 +08:00
if ( ! frame )
This patch modifies the expression parser to allow it
to execute expressions even in the absence of a process.
This allows expressions to run in situations where the
target cannot run -- e.g., to perform calculations based
on type information, or to inspect a binary's static
data.
This modification touches the following files:
lldb-private-enumerations.h
Introduce a new enum specifying the policy for
processing an expression. Some expressions should
always be JITted, for example if they are functions
that will be used over and over again. Some
expressions should always be interpreted, for
example if the target is unsafe to run. For most,
it is acceptable to JIT them, but interpretation
is preferable when possible.
Target.[h,cpp]
Have EvaluateExpression now accept the new enum.
ClangExpressionDeclMap.[cpp,h]
Add support for the IR interpreter and also make
the ClangExpressionDeclMap more robust in the
absence of a process.
ClangFunction.[cpp,h]
Add support for the new enum.
IRInterpreter.[cpp,h]
New implementation.
ClangUserExpression.[cpp,h]
Add support for the new enum, and for running
expressions in the absence of a process.
ClangExpression.h
Remove references to the old DWARF-based method
of evaluating expressions, because it has been
superseded for now.
ClangUtilityFunction.[cpp,h]
Add support for the new enum.
ClangExpressionParser.[cpp,h]
Add support for the new enum, remove references
to DWARF, and add support for checking whether
the expression could be evaluated statically.
IRForTarget.[h,cpp]
Add support for the new enum, and add utility
functions to support the interpreter.
IRToDWARF.cpp
Removed
CommandObjectExpression.cpp
Remove references to the obsolete -i option.
Process.cpp
Modify calls to ClangUserExpression::Evaluate
to pass the correct enum (for dlopen/dlclose)
SBValue.cpp
Add support for the new enum.
SBFrame.cpp
Add support for he new enum.
BreakpointOptions.cpp
Add support for the new enum.
llvm-svn: 139772
2011-09-15 10:13:07 +08:00
return ;
2011-11-15 10:11:17 +08:00
SymbolContext sym_ctx = frame - > GetSymbolContext ( lldb : : eSymbolContextFunction ) ;
This patch modifies the expression parser to allow it
to execute expressions even in the absence of a process.
This allows expressions to run in situations where the
target cannot run -- e.g., to perform calculations based
on type information, or to inspect a binary's static
data.
This modification touches the following files:
lldb-private-enumerations.h
Introduce a new enum specifying the policy for
processing an expression. Some expressions should
always be JITted, for example if they are functions
that will be used over and over again. Some
expressions should always be interpreted, for
example if the target is unsafe to run. For most,
it is acceptable to JIT them, but interpretation
is preferable when possible.
Target.[h,cpp]
Have EvaluateExpression now accept the new enum.
ClangExpressionDeclMap.[cpp,h]
Add support for the IR interpreter and also make
the ClangExpressionDeclMap more robust in the
absence of a process.
ClangFunction.[cpp,h]
Add support for the new enum.
IRInterpreter.[cpp,h]
New implementation.
ClangUserExpression.[cpp,h]
Add support for the new enum, and for running
expressions in the absence of a process.
ClangExpression.h
Remove references to the old DWARF-based method
of evaluating expressions, because it has been
superseded for now.
ClangUtilityFunction.[cpp,h]
Add support for the new enum.
ClangExpressionParser.[cpp,h]
Add support for the new enum, remove references
to DWARF, and add support for checking whether
the expression could be evaluated statically.
IRForTarget.[h,cpp]
Add support for the new enum, and add utility
functions to support the interpreter.
IRToDWARF.cpp
Removed
CommandObjectExpression.cpp
Remove references to the obsolete -i option.
Process.cpp
Modify calls to ClangUserExpression::Evaluate
to pass the correct enum (for dlopen/dlclose)
SBValue.cpp
Add support for the new enum.
SBFrame.cpp
Add support for he new enum.
BreakpointOptions.cpp
Add support for the new enum.
llvm-svn: 139772
2011-09-15 10:13:07 +08:00
2011-11-15 10:11:17 +08:00
if ( ! sym_ctx . function )
return ;
2011-10-12 09:39:28 +08:00
2012-07-14 08:53:55 +08:00
// Get the block that defines the function
Block * function_block = sym_ctx . GetFunctionBlock ( ) ;
2011-11-15 10:11:17 +08:00
2012-07-14 08:53:55 +08:00
if ( ! function_block )
return ;
clang : : DeclContext * decl_context = function_block - > GetClangDeclContext ( ) ;
2011-11-15 10:11:17 +08:00
if ( ! decl_context )
2010-12-14 06:46:15 +08:00
return ;
2011-10-12 09:39:28 +08:00
2011-11-15 10:11:17 +08:00
clang : : ObjCMethodDecl * method_decl = llvm : : dyn_cast < clang : : ObjCMethodDecl > ( decl_context ) ;
2012-10-31 07:35:54 +08:00
if ( method_decl )
2011-11-15 10:11:17 +08:00
{
2012-10-31 07:35:54 +08:00
ObjCInterfaceDecl * self_interface = method_decl - > getClassInterface ( ) ;
2012-02-08 11:45:08 +08:00
2012-10-31 07:35:54 +08:00
if ( ! self_interface )
2012-02-08 11:45:08 +08:00
return ;
2012-10-31 07:35:54 +08:00
const clang : : Type * interface_type = self_interface - > getTypeForDecl ( ) ;
2013-04-10 05:30:48 +08:00
if ( ! interface_type )
return ; // This is unlikely, but we have seen crashes where this occurred
2012-10-31 07:35:54 +08:00
TypeFromUser class_user_type ( QualType ( interface_type , 0 ) . getAsOpaquePtr ( ) ,
& method_decl - > getASTContext ( ) ) ;
2012-02-08 11:45:08 +08:00
2012-10-31 07:35:54 +08:00
if ( log )
{
ASTDumper ast_dumper ( interface_type ) ;
log - > Printf ( " FEVD[%u] Adding type for $__lldb_objc_class: %s " , current_id , ast_dumper . GetCString ( ) ) ;
}
2013-02-01 14:55:48 +08:00
AddOneType ( context , class_user_type , current_id ) ;
2012-10-31 07:35:54 +08:00
if ( method_decl - > isInstanceMethod ( ) )
{
// self is a pointer to the object
QualType class_pointer_type = method_decl - > getASTContext ( ) . getObjCObjectPointerType ( QualType ( interface_type , 0 ) ) ;
TypeFromUser self_user_type ( class_pointer_type . getAsOpaquePtr ( ) ,
& method_decl - > getASTContext ( ) ) ;
m_struct_vars - > m_object_pointer_type = self_user_type ;
}
else
{
// self is a Class pointer
QualType class_type = method_decl - > getASTContext ( ) . getObjCClassType ( ) ;
TypeFromUser self_user_type ( class_type . getAsOpaquePtr ( ) ,
& method_decl - > getASTContext ( ) ) ;
m_struct_vars - > m_object_pointer_type = self_user_type ;
}
return ;
2012-02-08 11:45:08 +08:00
}
else
{
2012-10-31 07:35:54 +08: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.
VariableList * vars = frame - > GetVariableList ( false ) ;
2012-02-08 11:45:08 +08:00
2012-10-31 07:35:54 +08:00
lldb : : VariableSP self_var = vars - > FindVariable ( ConstString ( " self " ) ) ;
2012-02-08 11:45:08 +08:00
2012-10-31 07:35:54 +08:00
if ( self_var & &
self_var - > IsInScope ( frame ) & &
self_var - > LocationIsValidForFrame ( frame ) )
{
Type * self_type = self_var - > GetType ( ) ;
if ( ! self_type )
return ;
2013-07-12 06:46:58 +08:00
ClangASTType self_clang_type = self_type - > GetClangFullType ( ) ;
2012-10-31 07:35:54 +08:00
2013-07-12 06:46:58 +08:00
if ( self_clang_type . IsObjCClassType ( ) )
2013-01-19 09:49:02 +08:00
{
return ;
}
2013-07-12 06:46:58 +08:00
else if ( self_clang_type . IsObjCObjectPointerType ( ) )
2012-10-31 07:35:54 +08:00
{
2013-07-12 06:46:58 +08:00
self_clang_type = self_clang_type . GetPointeeType ( ) ;
if ( ! self_clang_type )
2013-04-27 06:54:19 +08:00
return ;
2012-10-31 07:35:54 +08: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 ( ) ) ;
}
2013-07-12 06:46:58 +08:00
TypeFromUser class_user_type ( self_clang_type ) ;
2013-01-19 09:49:02 +08:00
2013-02-01 14:55:48 +08:00
AddOneType ( context , class_user_type , current_id ) ;
2012-10-31 07:35:54 +08:00
2013-07-12 06:46:58 +08:00
TypeFromUser self_user_type ( self_type - > GetClangFullType ( ) ) ;
2012-10-31 07:35:54 +08:00
m_struct_vars - > m_object_pointer_type = self_user_type ;
return ;
}
}
2012-02-08 11:45:08 +08:00
}
2010-12-14 06:46:15 +08:00
return ;
}
2011-10-08 07:18:13 +08:00
// any other $__lldb names should be weeded out now
if ( ! : : strncmp ( name_unique_cstr , " $__lldb " , sizeof ( " $__lldb " ) - 1 ) )
return ;
2011-10-12 09:39:28 +08:00
2011-08-24 05:20:51 +08:00
do
{
2011-09-22 12:58:26 +08:00
if ( ! target )
2011-08-24 05:20:51 +08:00
break ;
2011-09-22 12:58:26 +08:00
ClangASTContext * scratch_clang_ast_context = target - > GetScratchClangASTContext ( ) ;
2011-08-24 05:20:51 +08:00
if ( ! scratch_clang_ast_context )
break ;
ASTContext * scratch_ast_context = scratch_clang_ast_context - > getASTContext ( ) ;
if ( ! scratch_ast_context )
break ;
TypeDecl * ptype_type_decl = m_parser_vars - > m_persistent_vars - > GetPersistentType ( name ) ;
2011-10-12 09:39:28 +08:00
2011-08-24 05:20:51 +08:00
if ( ! ptype_type_decl )
break ;
2011-12-06 11:41:14 +08:00
Decl * parser_ptype_decl = m_ast_importer - > CopyDecl ( m_ast_context , scratch_ast_context , ptype_type_decl ) ;
2011-08-24 05:20:51 +08:00
if ( ! parser_ptype_decl )
break ;
TypeDecl * parser_ptype_type_decl = dyn_cast < TypeDecl > ( parser_ptype_decl ) ;
if ( ! parser_ptype_type_decl )
break ;
if ( log )
2011-10-30 03:50:43 +08:00
log - > Printf ( " CEDM::FEVD[%u] Found persistent type %s " , current_id , name . GetCString ( ) ) ;
2011-08-24 05:20:51 +08:00
context . AddNamedDecl ( parser_ptype_type_decl ) ;
} while ( 0 ) ;
2010-12-14 10:59:59 +08:00
ClangExpressionVariableSP pvar_sp ( m_parser_vars - > m_persistent_vars - > GetVariable ( name ) ) ;
2011-10-12 09:39:28 +08:00
2010-12-14 10:59:59 +08:00
if ( pvar_sp )
2010-11-30 08:27:43 +08:00
{
2011-10-15 04:34:21 +08:00
AddOneVariable ( context , pvar_sp , current_id ) ;
2010-11-30 08:27:43 +08:00
return ;
}
const char * reg_name ( & name . GetCString ( ) [ 1 ] ) ;
2012-02-10 09:22:05 +08:00
if ( m_parser_vars - > m_exe_ctx . GetRegisterContext ( ) )
2010-11-30 08:27:43 +08:00
{
2012-02-10 09:22:05 +08:00
const RegisterInfo * reg_info ( m_parser_vars - > m_exe_ctx . GetRegisterContext ( ) - > GetRegisterInfoByName ( reg_name ) ) ;
2011-10-30 03:50:43 +08:00
2010-11-30 08:27:43 +08:00
if ( reg_info )
2011-10-19 00:46:55 +08:00
{
if ( log )
2011-10-30 03:50:43 +08:00
log - > Printf ( " CEDM::FEVD[%u] Found register %s " , current_id , reg_info - > name ) ;
2011-10-19 00:46:55 +08:00
2011-10-15 04:34:21 +08:00
AddOneRegister ( context , reg_info , current_id ) ;
2011-10-19 00:46:55 +08:00
}
2010-11-30 08:27:43 +08:00
}
2010-10-16 06:48:33 +08:00
}
2011-10-12 09:39:28 +08:00
else
{
ValueObjectSP valobj ;
VariableSP var ;
Error err ;
if ( frame & & ! namespace_decl )
{
valobj = frame - > GetValueForVariableExpressionPath ( name_unique_cstr ,
eNoDynamicValues ,
2013-02-12 15:56:36 +08:00
StackFrame : : eExpressionPathOptionCheckPtrVsMember | |
StackFrame : : eExpressionPathOptionsAllowDirectIVarAccess | |
StackFrame : : eExpressionPathOptionsNoFragileObjcIvar | |
StackFrame : : eExpressionPathOptionsNoSyntheticChildren | |
StackFrame : : eExpressionPathOptionsNoSyntheticArrayRange ,
2011-10-12 09:39:28 +08:00
var ,
err ) ;
// If we found a variable in scope, no need to pull up function names
2012-08-09 08:50:26 +08:00
if ( err . Success ( ) & & var )
2011-10-12 09:39:28 +08:00
{
2011-11-30 06:03:21 +08:00
AddOneVariable ( context , var , valobj , current_id ) ;
2011-10-13 04:29:25 +08:00
context . m_found . variable = true ;
2011-10-26 04:36:57 +08:00
return ;
2011-10-12 09:39:28 +08:00
}
}
2011-12-10 12:03:38 +08:00
if ( target )
2011-10-12 09:39:28 +08:00
{
2011-10-13 00:59:31 +08:00
var = FindGlobalVariable ( * target ,
2011-10-13 02:44:30 +08:00
module_sp ,
2011-10-13 00:59:31 +08:00
name ,
& namespace_decl ,
2011-10-12 09:39:28 +08:00
NULL ) ;
if ( var )
{
2011-12-10 11:12:34 +08:00
valobj = ValueObjectVariable : : Create ( target , var ) ;
2011-11-30 06:03:21 +08:00
AddOneVariable ( context , var , valobj , current_id ) ;
2011-10-13 04:29:25 +08:00
context . m_found . variable = true ;
2011-12-10 12:03:38 +08:00
return ;
2011-10-12 09:39:28 +08:00
}
}
2011-10-13 04:29:25 +08:00
if ( ! context . m_found . variable )
2011-10-12 09:39:28 +08:00
{
2012-02-11 06:52:19 +08:00
const bool include_inlines = false ;
2011-10-12 09:39:28 +08:00
const bool append = false ;
2011-10-13 01:38:09 +08:00
2011-10-13 02:44:30 +08:00
if ( namespace_decl & & module_sp )
2011-10-13 01:38:09 +08:00
{
2012-02-16 01:14:49 +08:00
const bool include_symbols = false ;
2011-10-13 02:44:30 +08:00
module_sp - > FindFunctions ( name ,
& namespace_decl ,
eFunctionNameTypeBase ,
include_symbols ,
2012-02-11 06:52:19 +08:00
include_inlines ,
2011-10-13 02:44:30 +08:00
append ,
sc_list ) ;
2011-10-13 01:38:09 +08:00
}
2012-10-13 01:34:26 +08:00
else if ( target & & ! namespace_decl )
2011-10-13 01:38:09 +08:00
{
2012-02-16 01:14:49 +08:00
const bool include_symbols = true ;
2012-07-28 08:21:01 +08:00
// TODO Fix FindFunctions so that it doesn't return
// instance methods for eFunctionNameTypeBase.
2011-10-13 01:38:09 +08:00
target - > GetImages ( ) . FindFunctions ( name ,
2013-04-03 10:00:15 +08:00
eFunctionNameTypeFull ,
2011-10-13 01:38:09 +08:00
include_symbols ,
2012-02-11 06:52:19 +08:00
include_inlines ,
2011-10-13 01:38:09 +08:00
append ,
sc_list ) ;
}
2011-10-12 09:39:28 +08:00
if ( sc_list . GetSize ( ) )
{
Symbol * generic_symbol = NULL ;
Symbol * non_extern_symbol = NULL ;
for ( uint32_t index = 0 , num_indices = sc_list . GetSize ( ) ;
index < num_indices ;
+ + index )
{
SymbolContext sym_ctx ;
sc_list . GetContextAtIndex ( index , sym_ctx ) ;
if ( sym_ctx . function )
{
2012-07-28 08:21:01 +08:00
clang : : DeclContext * decl_ctx = sym_ctx . function - > GetClangDeclContext ( ) ;
2013-04-27 09:57:44 +08:00
if ( ! decl_ctx )
continue ;
2012-07-28 08:21:01 +08:00
// Filter out class/instance methods.
if ( dyn_cast < clang : : ObjCMethodDecl > ( decl_ctx ) )
continue ;
if ( dyn_cast < clang : : CXXMethodDecl > ( decl_ctx ) )
continue ;
2013-04-24 08:34:41 +08:00
AddOneFunction ( context , sym_ctx . function , NULL , current_id ) ;
2011-10-13 04:29:25 +08:00
context . m_found . function_with_type_info = true ;
context . m_found . function = true ;
2011-10-12 09:39:28 +08:00
}
else if ( sym_ctx . symbol )
{
if ( sym_ctx . symbol - > IsExternal ( ) )
generic_symbol = sym_ctx . symbol ;
else
non_extern_symbol = sym_ctx . symbol ;
}
}
2011-10-13 04:29:25 +08:00
if ( ! context . m_found . function_with_type_info )
2011-10-12 09:39:28 +08:00
{
if ( generic_symbol )
{
2011-10-15 04:34:21 +08:00
AddOneFunction ( context , NULL , generic_symbol , current_id ) ;
2011-10-13 04:29:25 +08:00
context . m_found . function = true ;
2011-10-12 09:39:28 +08:00
}
else if ( non_extern_symbol )
{
2011-10-15 04:34:21 +08:00
AddOneFunction ( context , NULL , non_extern_symbol , current_id ) ;
2011-10-13 04:29:25 +08:00
context . m_found . function = true ;
2011-10-12 09:39:28 +08:00
}
}
}
2013-05-16 02:27:08 +08:00
if ( target & & ! context . m_found . variable & & ! namespace_decl )
2011-10-12 09:39:28 +08:00
{
2011-10-13 04:29:25 +08:00
// We couldn't find a non-symbol variable for this. Now we'll hunt for a generic
2011-10-12 09:39:28 +08:00
// data symbol, and -- if it is found -- treat it as a variable.
2012-11-27 09:52:16 +08:00
const Symbol * data_symbol = FindGlobalDataSymbol ( * target , name ) ;
2011-10-12 09:39:28 +08:00
if ( data_symbol )
{
2011-10-15 04:34:21 +08:00
AddOneGenericVariable ( context , * data_symbol , current_id ) ;
2011-10-13 04:29:25 +08:00
context . m_found . variable = true ;
2011-10-12 09:39:28 +08:00
}
}
}
2011-10-27 10:06:03 +08:00
}
2010-06-09 00:52:24 +08:00
}
2011-06-25 08:44:06 +08:00
2012-03-07 05:56:33 +08: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-07-12 06:46:58 +08:00
bool
ClangExpressionDeclMap : : GetVariableValue ( VariableSP & var ,
lldb_private : : Value & var_location ,
TypeFromUser * user_type ,
TypeFromParser * parser_type )
2010-06-09 00:52:24 +08:00
{
2013-03-28 07:08:40 +08:00
Log * log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_EXPRESSIONS ) ) ;
2010-06-23 08:47:48 +08:00
2010-06-09 00:52:24 +08:00
Type * var_type = var - > GetType ( ) ;
if ( ! var_type )
{
2010-07-16 08:09:46 +08:00
if ( log )
log - > PutCString ( " Skipped a definition because it has no type " ) ;
2013-07-12 06:46:58 +08:00
return false ;
2010-06-09 00:52:24 +08:00
}
2013-07-12 06:46:58 +08:00
ClangASTType var_clang_type = var_type - > GetClangFullType ( ) ;
2010-06-09 00:52:24 +08:00
2013-07-12 06:46:58 +08:00
if ( ! var_clang_type )
2010-06-09 00:52:24 +08:00
{
2010-07-16 08:09:46 +08:00
if ( log )
log - > PutCString ( " Skipped a definition because it has no Clang type " ) ;
2013-07-12 06:46:58 +08:00
return false ;
2010-06-09 00:52:24 +08:00
}
2011-07-30 10:42:06 +08:00
ASTContext * ast = var_type - > GetClangASTContext ( ) . getASTContext ( ) ;
2013-07-12 06:46:58 +08:00
A few of the issue I have been trying to track down and fix have been due to
the way LLDB lazily gets complete definitions for types within the debug info.
When we run across a class/struct/union definition in the DWARF, we will only
parse the full definition if we need to. This works fine for top level types
that are assigned directly to variables and arguments, but when we have a
variable with a class, lets say "A" for this example, that has a member:
"B *m_b". Initially we don't need to hunt down a definition for this class
unless we are ever asked to do something with it ("expr m_b->getDecl()" for
example). With my previous approach to lazy type completion, we would be able
to take a "A *a" and get a complete type for it, but we wouldn't be able to
then do an "a->m_b->getDecl()" unless we always expanded all types within a
class prior to handing out the type. Expanding everything is very costly and
it would be great if there were a better way.
A few months ago I worked with the llvm/clang folks to have the
ExternalASTSource class be able to complete classes if there weren't completed
yet:
class ExternalASTSource {
....
virtual void
CompleteType (clang::TagDecl *Tag);
virtual void
CompleteType (clang::ObjCInterfaceDecl *Class);
};
This was great, because we can now have the class that is producing the AST
(SymbolFileDWARF and SymbolFileDWARFDebugMap) sign up as external AST sources
and the object that creates the forward declaration types can now also
complete them anywhere within the clang type system.
This patch makes a few major changes:
- lldb_private::Module classes now own the AST context. Previously the TypeList
objects did.
- The DWARF parsers now sign up as an external AST sources so they can complete
types.
- All of the pure clang type system wrapper code we have in LLDB (ClangASTContext,
ClangASTType, and more) can now be iterating through children of any type,
and if a class/union/struct type (clang::RecordType or ObjC interface)
is found that is incomplete, we can ask the AST to get the definition.
- The SymbolFileDWARFDebugMap class now will create and use a single AST that
all child SymbolFileDWARF classes will share (much like what happens when
we have a complete linked DWARF for an executable).
We will need to modify some of the ClangUserExpression code to take more
advantage of this completion ability in the near future. Meanwhile we should
be better off now that we can be accessing any children of variables through
pointers and always be able to resolve the clang type if needed.
llvm-svn: 123613
2011-01-17 11:46:26 +08:00
if ( ! ast )
2010-06-09 00:52:24 +08:00
{
2010-07-16 08:09:46 +08:00
if ( log )
log - > PutCString ( " There is no AST context for the current execution context " ) ;
2013-07-12 06:46:58 +08:00
return false ;
2010-06-09 00:52:24 +08:00
}
2013-07-12 06:46:58 +08:00
//var_clang_type = MaybePromoteToBlockPointerType (ast, var_clang_type);
2010-06-09 00:52:24 +08:00
2010-07-17 08:43:37 +08:00
DWARFExpression & var_location_expr = var - > LocationExpression ( ) ;
2010-09-14 10:20:48 +08:00
lldb : : addr_t loclist_base_load_addr = LLDB_INVALID_ADDRESS ;
2012-02-10 09:22:05 +08:00
Target * target = m_parser_vars - > m_exe_ctx . GetTargetPtr ( ) ;
2011-09-22 12:58:26 +08:00
2010-09-14 10:20:48 +08:00
if ( var_location_expr . IsLocationList ( ) )
{
SymbolContext var_sc ;
var - > CalculateSymbolContext ( & var_sc ) ;
2011-09-22 12:58:26 +08:00
loclist_base_load_addr = var_sc . function - > GetAddressRange ( ) . GetBaseAddress ( ) . GetLoadAddress ( target ) ;
2010-09-14 10:20:48 +08:00
}
2010-06-09 00:52:24 +08:00
Error err ;
2013-01-19 05:20:51 +08:00
if ( var - > GetLocationIsConstantValueData ( ) )
{
DataExtractor const_value_extractor ;
if ( var_location_expr . GetExpressionData ( const_value_extractor ) )
{
2013-07-12 06:46:58 +08:00
var_location = Value ( const_value_extractor . GetDataStart ( ) , const_value_extractor . GetByteSize ( ) ) ;
var_location . SetValueType ( Value : : eValueTypeHostAddress ) ;
2013-01-19 05:20:51 +08:00
}
else
{
if ( log )
log - > Printf ( " Error evaluating constant variable: %s " , err . AsCString ( ) ) ;
2013-07-12 06:46:58 +08:00
return false ;
2013-01-19 05:20:51 +08:00
}
}
2013-05-17 08:55:28 +08:00
2013-07-12 06:46:58 +08:00
ClangASTType type_to_use = GuardedCopyType ( var_clang_type ) ;
2010-07-17 08:43:37 +08:00
2013-07-12 06:46:58 +08:00
if ( ! type_to_use )
2010-07-21 07:31:16 +08:00
{
2013-07-12 06:46:58 +08:00
if ( log )
log - > Printf ( " Couldn't copy a variable's type into the parser's AST context " ) ;
2010-11-20 10:19:29 +08:00
2013-07-12 06:46:58 +08:00
return false ;
2010-07-21 07:31:16 +08:00
}
2010-06-09 00:52:24 +08:00
2013-07-12 06:46:58 +08:00
if ( parser_type )
* parser_type = TypeFromParser ( type_to_use ) ;
2010-06-09 00:52:24 +08:00
2013-07-12 06:46:58 +08:00
if ( var_location . GetContextType ( ) = = Value : : eContextTypeInvalid )
var_location . SetClangType ( type_to_use ) ;
if ( var_location . GetValueType ( ) = = Value : : eValueTypeFileAddress )
2010-06-09 00:52:24 +08:00
{
SymbolContext var_sc ;
var - > CalculateSymbolContext ( & var_sc ) ;
2010-07-17 08:43:37 +08:00
2010-06-09 00:52:24 +08:00
if ( ! var_sc . module_sp )
2013-08-08 03:05:15 +08:00
return false ;
2013-07-10 09:23:25 +08:00
2013-07-12 06:46:58 +08:00
Address so_addr ( var_location . GetScalar ( ) . ULongLong ( ) , var_sc . module_sp - > GetSectionList ( ) ) ;
2010-06-09 00:52:24 +08:00
2011-09-22 12:58:26 +08:00
lldb : : addr_t load_addr = so_addr . GetLoadAddress ( target ) ;
2010-06-09 00:52:24 +08:00
This patch modifies the expression parser to allow it
to execute expressions even in the absence of a process.
This allows expressions to run in situations where the
target cannot run -- e.g., to perform calculations based
on type information, or to inspect a binary's static
data.
This modification touches the following files:
lldb-private-enumerations.h
Introduce a new enum specifying the policy for
processing an expression. Some expressions should
always be JITted, for example if they are functions
that will be used over and over again. Some
expressions should always be interpreted, for
example if the target is unsafe to run. For most,
it is acceptable to JIT them, but interpretation
is preferable when possible.
Target.[h,cpp]
Have EvaluateExpression now accept the new enum.
ClangExpressionDeclMap.[cpp,h]
Add support for the IR interpreter and also make
the ClangExpressionDeclMap more robust in the
absence of a process.
ClangFunction.[cpp,h]
Add support for the new enum.
IRInterpreter.[cpp,h]
New implementation.
ClangUserExpression.[cpp,h]
Add support for the new enum, and for running
expressions in the absence of a process.
ClangExpression.h
Remove references to the old DWARF-based method
of evaluating expressions, because it has been
superseded for now.
ClangUtilityFunction.[cpp,h]
Add support for the new enum.
ClangExpressionParser.[cpp,h]
Add support for the new enum, remove references
to DWARF, and add support for checking whether
the expression could be evaluated statically.
IRForTarget.[h,cpp]
Add support for the new enum, and add utility
functions to support the interpreter.
IRToDWARF.cpp
Removed
CommandObjectExpression.cpp
Remove references to the obsolete -i option.
Process.cpp
Modify calls to ClangUserExpression::Evaluate
to pass the correct enum (for dlopen/dlclose)
SBValue.cpp
Add support for the new enum.
SBFrame.cpp
Add support for he new enum.
BreakpointOptions.cpp
Add support for the new enum.
llvm-svn: 139772
2011-09-15 10:13:07 +08:00
if ( load_addr ! = LLDB_INVALID_ADDRESS )
{
2013-07-12 06:46:58 +08:00
var_location . GetScalar ( ) = load_addr ;
var_location . SetValueType ( Value : : eValueTypeLoadAddress ) ;
This patch modifies the expression parser to allow it
to execute expressions even in the absence of a process.
This allows expressions to run in situations where the
target cannot run -- e.g., to perform calculations based
on type information, or to inspect a binary's static
data.
This modification touches the following files:
lldb-private-enumerations.h
Introduce a new enum specifying the policy for
processing an expression. Some expressions should
always be JITted, for example if they are functions
that will be used over and over again. Some
expressions should always be interpreted, for
example if the target is unsafe to run. For most,
it is acceptable to JIT them, but interpretation
is preferable when possible.
Target.[h,cpp]
Have EvaluateExpression now accept the new enum.
ClangExpressionDeclMap.[cpp,h]
Add support for the IR interpreter and also make
the ClangExpressionDeclMap more robust in the
absence of a process.
ClangFunction.[cpp,h]
Add support for the new enum.
IRInterpreter.[cpp,h]
New implementation.
ClangUserExpression.[cpp,h]
Add support for the new enum, and for running
expressions in the absence of a process.
ClangExpression.h
Remove references to the old DWARF-based method
of evaluating expressions, because it has been
superseded for now.
ClangUtilityFunction.[cpp,h]
Add support for the new enum.
ClangExpressionParser.[cpp,h]
Add support for the new enum, remove references
to DWARF, and add support for checking whether
the expression could be evaluated statically.
IRForTarget.[h,cpp]
Add support for the new enum, and add utility
functions to support the interpreter.
IRToDWARF.cpp
Removed
CommandObjectExpression.cpp
Remove references to the obsolete -i option.
Process.cpp
Modify calls to ClangUserExpression::Evaluate
to pass the correct enum (for dlopen/dlclose)
SBValue.cpp
Add support for the new enum.
SBFrame.cpp
Add support for he new enum.
BreakpointOptions.cpp
Add support for the new enum.
llvm-svn: 139772
2011-09-15 10:13:07 +08:00
}
2010-06-09 00:52:24 +08:00
}
2010-07-21 07:31:16 +08:00
if ( user_type )
2013-07-12 06:46:58 +08:00
* user_type = TypeFromUser ( var_clang_type ) ;
2010-07-17 08:43:37 +08:00
2013-07-12 06:46:58 +08:00
return true ;
2010-07-17 08:43:37 +08:00
}
void
2011-11-30 06:03:21 +08:00
ClangExpressionDeclMap : : AddOneVariable ( NameSearchContext & context , VariableSP var , ValueObjectSP valobj , unsigned int current_id )
2010-07-17 08:43:37 +08:00
{
2010-12-03 09:38:59 +08:00
assert ( m_parser_vars . get ( ) ) ;
2013-03-28 07:08:40 +08:00
Log * log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_EXPRESSIONS ) ) ;
This patch modifies the expression parser to allow it
to execute expressions even in the absence of a process.
This allows expressions to run in situations where the
target cannot run -- e.g., to perform calculations based
on type information, or to inspect a binary's static
data.
This modification touches the following files:
lldb-private-enumerations.h
Introduce a new enum specifying the policy for
processing an expression. Some expressions should
always be JITted, for example if they are functions
that will be used over and over again. Some
expressions should always be interpreted, for
example if the target is unsafe to run. For most,
it is acceptable to JIT them, but interpretation
is preferable when possible.
Target.[h,cpp]
Have EvaluateExpression now accept the new enum.
ClangExpressionDeclMap.[cpp,h]
Add support for the IR interpreter and also make
the ClangExpressionDeclMap more robust in the
absence of a process.
ClangFunction.[cpp,h]
Add support for the new enum.
IRInterpreter.[cpp,h]
New implementation.
ClangUserExpression.[cpp,h]
Add support for the new enum, and for running
expressions in the absence of a process.
ClangExpression.h
Remove references to the old DWARF-based method
of evaluating expressions, because it has been
superseded for now.
ClangUtilityFunction.[cpp,h]
Add support for the new enum.
ClangExpressionParser.[cpp,h]
Add support for the new enum, remove references
to DWARF, and add support for checking whether
the expression could be evaluated statically.
IRForTarget.[h,cpp]
Add support for the new enum, and add utility
functions to support the interpreter.
IRToDWARF.cpp
Removed
CommandObjectExpression.cpp
Remove references to the obsolete -i option.
Process.cpp
Modify calls to ClangUserExpression::Evaluate
to pass the correct enum (for dlopen/dlclose)
SBValue.cpp
Add support for the new enum.
SBFrame.cpp
Add support for he new enum.
BreakpointOptions.cpp
Add support for the new enum.
llvm-svn: 139772
2011-09-15 10:13:07 +08:00
2010-07-21 07:31:16 +08:00
TypeFromUser ut ;
TypeFromParser pt ;
2013-07-12 06:46:58 +08:00
Value var_location ;
2010-07-17 08:43:37 +08:00
2013-07-12 06:46:58 +08:00
if ( ! GetVariableValue ( var , var_location , & ut , & pt ) )
return ;
2010-07-17 08:43:37 +08:00
2012-03-15 09:53:17 +08:00
clang : : QualType parser_opaque_type = QualType : : getFromOpaquePtr ( pt . GetOpaqueQualType ( ) ) ;
2012-03-22 01:13:20 +08:00
if ( parser_opaque_type . isNull ( ) )
return ;
2012-03-15 09:53:17 +08: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 ( ) ) ;
}
2011-10-28 03:41:13 +08:00
2013-07-12 06:46:58 +08:00
bool is_reference = pt . IsReferenceType ( ) ;
2011-10-28 03:41:13 +08:00
2013-07-12 06:46:58 +08:00
NamedDecl * var_decl = NULL ;
2011-10-28 03:41:13 +08:00
if ( is_reference )
2013-07-12 06:46:58 +08:00
var_decl = context . AddVarDecl ( pt ) ;
2011-10-28 03:41:13 +08:00
else
2013-07-12 06:46:58 +08:00
var_decl = context . AddVarDecl ( pt . GetLValueReferenceType ( ) ) ;
2011-10-28 03:41:13 +08:00
2010-10-16 06:48:33 +08:00
std : : string decl_name ( context . m_decl_name . getAsString ( ) ) ;
2010-12-14 10:59:59 +08:00
ConstString entity_name ( decl_name . c_str ( ) ) ;
2011-11-30 06:03:21 +08:00
ClangExpressionVariableSP entity ( m_found_entities . CreateVariable ( valobj ) ) ;
2010-12-14 10:59:59 +08:00
assert ( entity . get ( ) ) ;
2013-01-16 07:29:36 +08: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 ;
2010-06-09 00:52:24 +08:00
2011-10-28 03:41:13 +08:00
if ( is_reference )
entity - > m_flags | = ClangExpressionVariable : : EVTypeIsReference ;
2010-07-16 08:09:46 +08:00
if ( log )
2010-10-16 06:48:33 +08:00
{
2011-11-08 07:32:52 +08:00
ASTDumper orig_dumper ( ut . GetOpaqueQualType ( ) ) ;
2011-10-20 08:47:21 +08:00
ASTDumper ast_dumper ( var_decl ) ;
2011-11-08 07:32:52 +08: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-16 06:48:33 +08:00
}
2010-06-23 07:46:24 +08:00
}
2010-08-11 11:57:18 +08:00
void
ClangExpressionDeclMap : : AddOneVariable ( NameSearchContext & context ,
2011-10-15 04:34:21 +08:00
ClangExpressionVariableSP & pvar_sp ,
unsigned int current_id )
2010-08-11 11:57:18 +08:00
{
2013-03-28 07:08:40 +08:00
Log * log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_EXPRESSIONS ) ) ;
2010-08-31 06:17:16 +08:00
2010-12-14 10:59:59 +08:00
TypeFromUser user_type ( pvar_sp - > GetTypeFromUser ( ) ) ;
2010-08-11 11:57:18 +08:00
2013-07-12 06:46:58 +08:00
TypeFromParser parser_type ( GuardedCopyType ( user_type ) ) ;
2010-08-11 11:57:18 +08:00
2011-12-02 05:04:37 +08: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 ;
}
2013-07-12 06:46:58 +08:00
NamedDecl * var_decl = context . AddVarDecl ( parser_type . GetLValueReferenceType ( ) ) ;
2010-08-24 07:09:38 +08:00
2013-01-16 07:29:36 +08:00
pvar_sp - > EnableParserVars ( GetParserID ( ) ) ;
ClangExpressionVariable : : ParserVars * parser_vars = pvar_sp - > GetParserVars ( GetParserID ( ) ) ;
parser_vars - > m_parser_type = parser_type ;
2013-07-12 06:46:58 +08:00
parser_vars - > m_named_decl = var_decl ;
parser_vars - > m_llvm_value = NULL ;
parser_vars - > m_lldb_value . Clear ( ) ;
2010-08-31 06:17:16 +08:00
if ( log )
2010-11-02 07:22:47 +08:00
{
2011-10-20 08:47:21 +08:00
ASTDumper ast_dumper ( var_decl ) ;
2011-10-30 03:50:43 +08:00
log - > Printf ( " CEDM::FEVD[%u] Added pvar %s, returned %s " , current_id , pvar_sp - > GetName ( ) . GetCString ( ) , ast_dumper . GetCString ( ) ) ;
2010-11-02 07:22:47 +08:00
}
2010-08-11 11:57:18 +08:00
}
2011-05-08 10:21:26 +08:00
void
ClangExpressionDeclMap : : AddOneGenericVariable ( NameSearchContext & context ,
2012-11-27 09:52:16 +08:00
const Symbol & symbol ,
2011-10-15 04:34:21 +08:00
unsigned int current_id )
2011-05-08 10:21:26 +08:00
{
assert ( m_parser_vars . get ( ) ) ;
2013-03-28 07:08:40 +08:00
Log * log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_EXPRESSIONS ) ) ;
2011-05-08 10:21:26 +08:00
2012-02-10 09:22:05 +08:00
Target * target = m_parser_vars - > m_exe_ctx . GetTargetPtr ( ) ;
2011-09-22 12:58:26 +08:00
if ( target = = NULL )
return ;
ASTContext * scratch_ast_context = target - > GetScratchClangASTContext ( ) - > getASTContext ( ) ;
2011-05-08 10:21:26 +08:00
2013-07-12 06:46:58 +08: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 ) ;
2011-05-08 10:21:26 +08:00
std : : string decl_name ( context . m_decl_name . getAsString ( ) ) ;
ConstString entity_name ( decl_name . c_str ( ) ) ;
2012-02-10 09:22:05 +08:00
ClangExpressionVariableSP entity ( m_found_entities . CreateVariable ( m_parser_vars - > m_exe_ctx . GetBestExecutionContextScope ( ) ,
2011-05-08 10:21:26 +08:00
entity_name ,
user_type ,
This patch modifies the expression parser to allow it
to execute expressions even in the absence of a process.
This allows expressions to run in situations where the
target cannot run -- e.g., to perform calculations based
on type information, or to inspect a binary's static
data.
This modification touches the following files:
lldb-private-enumerations.h
Introduce a new enum specifying the policy for
processing an expression. Some expressions should
always be JITted, for example if they are functions
that will be used over and over again. Some
expressions should always be interpreted, for
example if the target is unsafe to run. For most,
it is acceptable to JIT them, but interpretation
is preferable when possible.
Target.[h,cpp]
Have EvaluateExpression now accept the new enum.
ClangExpressionDeclMap.[cpp,h]
Add support for the IR interpreter and also make
the ClangExpressionDeclMap more robust in the
absence of a process.
ClangFunction.[cpp,h]
Add support for the new enum.
IRInterpreter.[cpp,h]
New implementation.
ClangUserExpression.[cpp,h]
Add support for the new enum, and for running
expressions in the absence of a process.
ClangExpression.h
Remove references to the old DWARF-based method
of evaluating expressions, because it has been
superseded for now.
ClangUtilityFunction.[cpp,h]
Add support for the new enum.
ClangExpressionParser.[cpp,h]
Add support for the new enum, remove references
to DWARF, and add support for checking whether
the expression could be evaluated statically.
IRForTarget.[h,cpp]
Add support for the new enum, and add utility
functions to support the interpreter.
IRToDWARF.cpp
Removed
CommandObjectExpression.cpp
Remove references to the obsolete -i option.
Process.cpp
Modify calls to ClangUserExpression::Evaluate
to pass the correct enum (for dlopen/dlclose)
SBValue.cpp
Add support for the new enum.
SBFrame.cpp
Add support for he new enum.
BreakpointOptions.cpp
Add support for the new enum.
llvm-svn: 139772
2011-09-15 10:13:07 +08:00
m_parser_vars - > m_target_info . byte_order ,
m_parser_vars - > m_target_info . address_byte_size ) ) ;
2011-05-08 10:21:26 +08:00
assert ( entity . get ( ) ) ;
2013-07-12 06:46:58 +08:00
entity - > EnableParserVars ( GetParserID ( ) ) ;
ClangExpressionVariable : : ParserVars * parser_vars = entity - > GetParserVars ( GetParserID ( ) ) ;
2012-11-27 09:52:16 +08:00
const Address & symbol_address = symbol . GetAddress ( ) ;
2011-09-22 12:58:26 +08:00
lldb : : addr_t symbol_load_addr = symbol_address . GetLoadAddress ( target ) ;
2011-05-08 10:21:26 +08:00
2013-07-12 06:46:58 +08: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 ) ;
2011-05-08 10:21:26 +08:00
2013-01-16 07:29:36 +08: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 ;
2011-05-08 10:21:26 +08:00
if ( log )
{
2011-10-20 08:47:21 +08:00
ASTDumper ast_dumper ( var_decl ) ;
2011-05-08 10:21:26 +08:00
2011-10-30 03:50:43 +08:00
log - > Printf ( " CEDM::FEVD[%u] Found variable %s, returned %s " , current_id , decl_name . c_str ( ) , ast_dumper . GetCString ( ) ) ;
2011-05-08 10:21:26 +08:00
}
}
2011-05-13 07:54:16 +08:00
bool
ClangExpressionDeclMap : : ResolveUnknownTypes ( )
{
2013-03-28 07:08:40 +08:00
Log * log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_EXPRESSIONS ) ) ;
2012-02-10 09:22:05 +08:00
Target * target = m_parser_vars - > m_exe_ctx . GetTargetPtr ( ) ;
2011-09-22 12:58:26 +08:00
ASTContext * scratch_ast_context = target - > GetScratchClangASTContext ( ) - > getASTContext ( ) ;
2011-05-13 07:54:16 +08:00
for ( size_t index = 0 , num_entities = m_found_entities . GetSize ( ) ;
index < num_entities ;
+ + index )
{
ClangExpressionVariableSP entity = m_found_entities . GetVariableAtIndex ( index ) ;
2013-01-16 07:29:36 +08:00
ClangExpressionVariable : : ParserVars * parser_vars = entity - > GetParserVars ( GetParserID ( ) ) ;
2011-05-13 07:54:16 +08:00
if ( entity - > m_flags & ClangExpressionVariable : : EVUnknownType )
{
2013-01-16 07:29:36 +08:00
const NamedDecl * named_decl = parser_vars - > m_named_decl ;
2011-05-13 07:54:16 +08:00
const VarDecl * var_decl = dyn_cast < VarDecl > ( named_decl ) ;
if ( ! var_decl )
{
if ( log )
log - > Printf ( " Entity of unknown type does not have a VarDecl " ) ;
return false ;
}
if ( log )
{
2011-10-20 08:47:21 +08:00
ASTDumper ast_dumper ( const_cast < VarDecl * > ( var_decl ) ) ;
log - > Printf ( " Variable of unknown type now has Decl %s " , ast_dumper . GetCString ( ) ) ;
2011-05-13 07:54:16 +08:00
}
QualType var_type = var_decl - > getType ( ) ;
TypeFromParser parser_type ( var_type . getAsOpaquePtr ( ) , & var_decl - > getASTContext ( ) ) ;
2011-11-18 11:28:09 +08:00
lldb : : clang_type_t copied_type = m_ast_importer - > CopyType ( scratch_ast_context , & var_decl - > getASTContext ( ) , var_type . getAsOpaquePtr ( ) ) ;
2011-05-13 07:54:16 +08:00
2011-12-02 05:04:37 +08:00
if ( ! copied_type )
{
if ( log )
log - > Printf ( " ClangExpressionDeclMap::ResolveUnknownType - Couldn't import the type for a variable " ) ;
2012-08-11 08:35:26 +08:00
return ( bool ) lldb : : ClangExpressionVariableSP ( ) ;
2011-12-02 05:04:37 +08:00
}
2011-05-13 07:54:16 +08:00
TypeFromUser user_type ( copied_type , scratch_ast_context ) ;
2013-07-12 06:46:58 +08:00
// parser_vars->m_lldb_value.SetContext(Value::eContextTypeClangType, user_type.GetOpaqueQualType());
parser_vars - > m_lldb_value . SetClangType ( user_type ) ;
2013-01-16 07:29:36 +08:00
parser_vars - > m_parser_type = parser_type ;
2011-05-13 07:54:16 +08:00
2013-07-12 06:46:58 +08:00
entity - > SetClangType ( user_type ) ;
2011-05-13 07:54:16 +08:00
entity - > m_flags & = ~ ( ClangExpressionVariable : : EVUnknownType ) ;
}
}
return true ;
}
2010-11-30 08:27:43 +08:00
void
2010-12-14 10:59:59 +08:00
ClangExpressionDeclMap : : AddOneRegister ( NameSearchContext & context ,
2011-10-15 04:34:21 +08:00
const RegisterInfo * reg_info ,
unsigned int current_id )
2010-11-30 08:27:43 +08:00
{
2013-03-28 07:08:40 +08:00
Log * log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_EXPRESSIONS ) ) ;
2010-11-30 08:27:43 +08:00
2013-07-12 06:46:58 +08:00
ClangASTType clang_type = ClangASTContext : : GetBuiltinTypeForEncodingAndBitSize ( m_ast_context ,
reg_info - > encoding ,
reg_info - > byte_size * 8 ) ;
2010-11-30 08:27:43 +08:00
2013-07-12 06:46:58 +08:00
if ( ! clang_type )
2010-11-30 08:27:43 +08:00
{
2011-08-10 06:52:27 +08:00
if ( log )
2011-10-15 04:34:21 +08: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 08:27:43 +08:00
return ;
}
2013-07-12 06:46:58 +08:00
TypeFromParser parser_clang_type ( clang_type ) ;
2010-11-30 08:27:43 +08:00
2013-07-12 06:46:58 +08:00
NamedDecl * var_decl = context . AddVarDecl ( parser_clang_type ) ;
2010-11-30 08:27:43 +08:00
2012-02-10 09:22:05 +08:00
ClangExpressionVariableSP entity ( m_found_entities . CreateVariable ( m_parser_vars - > m_exe_ctx . GetBestExecutionContextScope ( ) ,
This patch modifies the expression parser to allow it
to execute expressions even in the absence of a process.
This allows expressions to run in situations where the
target cannot run -- e.g., to perform calculations based
on type information, or to inspect a binary's static
data.
This modification touches the following files:
lldb-private-enumerations.h
Introduce a new enum specifying the policy for
processing an expression. Some expressions should
always be JITted, for example if they are functions
that will be used over and over again. Some
expressions should always be interpreted, for
example if the target is unsafe to run. For most,
it is acceptable to JIT them, but interpretation
is preferable when possible.
Target.[h,cpp]
Have EvaluateExpression now accept the new enum.
ClangExpressionDeclMap.[cpp,h]
Add support for the IR interpreter and also make
the ClangExpressionDeclMap more robust in the
absence of a process.
ClangFunction.[cpp,h]
Add support for the new enum.
IRInterpreter.[cpp,h]
New implementation.
ClangUserExpression.[cpp,h]
Add support for the new enum, and for running
expressions in the absence of a process.
ClangExpression.h
Remove references to the old DWARF-based method
of evaluating expressions, because it has been
superseded for now.
ClangUtilityFunction.[cpp,h]
Add support for the new enum.
ClangExpressionParser.[cpp,h]
Add support for the new enum, remove references
to DWARF, and add support for checking whether
the expression could be evaluated statically.
IRForTarget.[h,cpp]
Add support for the new enum, and add utility
functions to support the interpreter.
IRToDWARF.cpp
Removed
CommandObjectExpression.cpp
Remove references to the obsolete -i option.
Process.cpp
Modify calls to ClangUserExpression::Evaluate
to pass the correct enum (for dlopen/dlclose)
SBValue.cpp
Add support for the new enum.
SBFrame.cpp
Add support for he new enum.
BreakpointOptions.cpp
Add support for the new enum.
llvm-svn: 139772
2011-09-15 10:13:07 +08:00
m_parser_vars - > m_target_info . byte_order ,
m_parser_vars - > m_target_info . address_byte_size ) ) ;
2010-12-14 10:59:59 +08:00
assert ( entity . get ( ) ) ;
2013-04-11 08:09:05 +08:00
2010-11-30 08:27:43 +08:00
std : : string decl_name ( context . m_decl_name . getAsString ( ) ) ;
2010-12-14 10:59:59 +08:00
entity - > SetName ( ConstString ( decl_name . c_str ( ) ) ) ;
entity - > SetRegisterInfo ( reg_info ) ;
2013-01-16 07:29:36 +08:00
entity - > EnableParserVars ( GetParserID ( ) ) ;
ClangExpressionVariable : : ParserVars * parser_vars = entity - > GetParserVars ( GetParserID ( ) ) ;
2013-07-12 06:46:58 +08: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 09:40:39 +08:00
entity - > m_flags | = ClangExpressionVariable : : EVBareRegister ;
2010-11-30 08:27:43 +08:00
2012-02-15 09:40:39 +08:00
if ( log )
2010-11-30 08:27:43 +08:00
{
2011-10-20 08:47:21 +08:00
ASTDumper ast_dumper ( var_decl ) ;
2011-10-30 03:50:43 +08: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 08:27:43 +08:00
}
}
2010-06-23 07:46:24 +08:00
void
2011-05-19 06:01:49 +08:00
ClangExpressionDeclMap : : AddOneFunction ( NameSearchContext & context ,
2013-07-12 06:46:58 +08:00
Function * function ,
2011-10-15 04:34:21 +08:00
Symbol * symbol ,
unsigned int current_id )
2010-06-23 07:46:24 +08:00
{
2010-12-03 09:38:59 +08:00
assert ( m_parser_vars . get ( ) ) ;
2013-03-28 07:08:40 +08:00
Log * log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_EXPRESSIONS ) ) ;
2010-06-23 07:46:24 +08:00
2013-07-12 06:46:58 +08:00
NamedDecl * function_decl = NULL ;
2011-07-08 08:39:14 +08:00
const Address * fun_address = NULL ;
2013-07-12 06:46:58 +08:00
ClangASTType function_clang_type ;
2013-02-28 04:13:38 +08:00
bool is_indirect_function = false ;
2013-07-12 06:46:58 +08:00
if ( function )
2010-07-27 08:55:47 +08:00
{
2013-07-12 06:46:58 +08:00
Type * function_type = function - > GetType ( ) ;
2010-07-27 08:55:47 +08:00
2013-07-12 06:46:58 +08:00
if ( ! function_type )
2010-07-27 08:55:47 +08:00
{
if ( log )
2011-10-15 04:34:21 +08:00
log - > PutCString ( " Skipped a function because it has no type " ) ;
2010-07-27 08:55:47 +08:00
return ;
}
2013-07-12 06:46:58 +08:00
function_clang_type = function_type - > GetClangFullType ( ) ;
2010-07-27 08:55:47 +08:00
2013-07-12 06:46:58 +08:00
if ( ! function_clang_type )
2010-07-27 08:55:47 +08:00
{
if ( log )
2011-10-15 04:34:21 +08:00
log - > PutCString ( " Skipped a function because it has no Clang type " ) ;
2010-07-27 08:55:47 +08:00
return ;
}
2013-07-12 06:46:58 +08:00
fun_address = & function - > GetAddressRange ( ) . GetBaseAddress ( ) ;
2010-07-27 08:55:47 +08:00
2013-07-12 06:46:58 +08:00
ClangASTType copied_function_type = GuardedCopyType ( function_clang_type ) ;
if ( copied_function_type )
2011-10-20 08:47:21 +08:00
{
2013-07-12 06:46:58 +08:00
function_decl = context . AddFunDecl ( copied_function_type ) ;
2013-04-24 08:34:41 +08:00
2013-07-12 06:46:58 +08:00
if ( ! function_decl )
2013-04-24 08:34:41 +08:00
{
if ( log )
{
log - > Printf ( " Failed to create a function decl for '%s' {0x%8.8 " PRIx64 " } " ,
2013-07-12 06:46:58 +08:00
function_type - > GetName ( ) . GetCString ( ) ,
function_type - > GetID ( ) ) ;
2013-04-24 08:34:41 +08:00
}
return ;
}
2011-10-20 08:47:21 +08:00
}
else
{
// We failed to copy the type we found
if ( log )
{
2012-11-30 05:49:15 +08:00
log - > Printf ( " Failed to import the function type '%s' {0x%8.8 " PRIx64 " } into the expression parser AST contenxt " ,
2013-07-12 06:46:58 +08:00
function_type - > GetName ( ) . GetCString ( ) ,
function_type - > GetID ( ) ) ;
2011-10-20 08:47:21 +08:00
}
2011-11-16 08:40:13 +08:00
return ;
2011-10-20 08:47:21 +08:00
}
2010-07-27 08:55:47 +08:00
}
else if ( symbol )
{
2012-03-08 05:03:09 +08:00
fun_address = & symbol - > GetAddress ( ) ;
2013-07-12 06:46:58 +08:00
function_decl = context . AddGenericFunDecl ( ) ;
2013-02-28 04:13:38 +08:00
is_indirect_function = symbol - > IsIndirect ( ) ;
2010-07-27 08:55:47 +08:00
}
else
2010-06-23 07:46:24 +08:00
{
2010-07-16 08:09:46 +08:00
if ( log )
2011-10-15 04:34:21 +08:00
log - > PutCString ( " AddOneFunction called with no function and no symbol " ) ;
2010-06-23 07:46:24 +08:00
return ;
}
2012-02-10 09:22:05 +08:00
Target * target = m_parser_vars - > m_exe_ctx . GetTargetPtr ( ) ;
2011-09-22 12:58:26 +08:00
2013-02-28 04:13:38 +08:00
lldb : : addr_t load_addr = fun_address - > GetCallableLoadAddress ( target , is_indirect_function ) ;
2013-03-19 09:45:02 +08:00
2013-07-12 06:46:58 +08: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 ( ) ) ;
2013-03-19 09:45:02 +08:00
if ( load_addr ! = LLDB_INVALID_ADDRESS )
{
2013-07-12 06:46:58 +08:00
parser_vars - > m_lldb_value . SetValueType ( Value : : eValueTypeLoadAddress ) ;
parser_vars - > m_lldb_value . GetScalar ( ) = load_addr ;
2013-03-19 09:45:02 +08:00
}
else
{
// We have to try finding a file address.
lldb : : addr_t file_addr = fun_address - > GetFileAddress ( ) ;
2013-07-12 06:46:58 +08:00
parser_vars - > m_lldb_value . SetValueType ( Value : : eValueTypeFileAddress ) ;
parser_vars - > m_lldb_value . GetScalar ( ) = file_addr ;
2013-03-19 09:45:02 +08:00
}
2010-06-23 07:46:24 +08:00
2013-07-12 06:46:58 +08:00
parser_vars - > m_named_decl = function_decl ;
2013-01-16 07:29:36 +08:00
parser_vars - > m_llvm_value = NULL ;
2013-07-12 06:46:58 +08:00
2010-07-16 08:09:46 +08:00
if ( log )
2010-10-16 06:48:33 +08:00
{
2013-07-12 06:46:58 +08:00
ASTDumper ast_dumper ( function_decl ) ;
2010-11-02 07:22:47 +08:00
2012-07-28 08:21:01 +08:00
StreamString ss ;
fun_address - > Dump ( & ss , m_parser_vars - > m_exe_ctx . GetBestExecutionContextScope ( ) , Address : : DumpStyleResolvedDescription ) ;
log - > Printf ( " CEDM::FEVD[%u] Found %s function %s (description %s), returned %s " ,
2011-10-15 04:34:21 +08:00
current_id ,
2013-07-12 06:46:58 +08:00
( function ? " specific " : " generic " ) ,
2012-07-28 08:21:01 +08:00
decl_name . c_str ( ) ,
ss . GetData ( ) ,
2011-10-20 08:47:21 +08:00
ast_dumper . GetCString ( ) ) ;
2010-10-16 06:48:33 +08:00
}
2010-06-09 00:52:24 +08:00
}
2010-08-04 09:02:13 +08:00
2013-02-01 14:55:48 +08:00
TypeFromParser
ClangExpressionDeclMap : : CopyClassType ( TypeFromUser & ut ,
unsigned int current_id )
2010-08-04 09:02:13 +08:00
{
2013-07-12 06:46:58 +08:00
ClangASTType copied_clang_type = GuardedCopyType ( ut ) ;
2011-12-02 05:04:37 +08:00
2013-07-12 06:46:58 +08:00
if ( ! copied_clang_type )
2011-12-02 05:04:37 +08:00
{
2013-03-28 07:08:40 +08:00
Log * log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_EXPRESSIONS ) ) ;
2013-02-01 14:55:48 +08:00
2011-12-02 05:04:37 +08:00
if ( log )
2013-02-01 14:55:48 +08:00
log - > Printf ( " ClangExpressionDeclMap::CopyClassType - Couldn't import the type " ) ;
2011-12-02 05:04:37 +08:00
2013-02-01 14:55:48 +08:00
return TypeFromParser ( ) ;
2011-12-02 05:04:37 +08:00
}
2013-02-01 14:55:48 +08:00
2013-07-12 06:46:58 +08:00
if ( copied_clang_type . IsAggregateType ( ) & & copied_clang_type . GetCompleteType ( ) )
Removed the hacky "#define this ___clang_this" handler
for C++ classes. Replaced it with a less hacky approach:
- If an expression is defined in the context of a
method of class A, then that expression is wrapped as
___clang_class::___clang_expr(void*) { ... }
instead of ___clang_expr(void*) { ... }.
- ___clang_class is resolved as the type of the target
of the "this" pointer in the method the expression
is defined in.
- When reporting the type of ___clang_class, a method
with the signature ___clang_expr(void*) is added to
that class, so that Clang doesn't complain about a
method being defined without a corresponding
declaration.
- Whenever the expression gets called, "this" gets
looked up, type-checked, and then passed in as the
first argument.
This required the following changes:
- The ABIs were changed to support passing of the "this"
pointer as part of trivial calls.
- ThreadPlanCallFunction and ClangFunction were changed
to support passing of an optional "this" pointer.
- ClangUserExpression was extended to perform the
wrapping described above.
- ClangASTSource was changed to revert the changes
required by the hack.
- ClangExpressionParser, IRForTarget, and
ClangExpressionDeclMap were changed to handle
different manglings of ___clang_expr flexibly. This
meant no longer searching for a function called
___clang_expr, but rather looking for a function whose
name *contains* ___clang_expr.
- ClangExpressionParser and ClangExpressionDeclMap now
remember whether "this" is required, and know how to
look it up as necessary.
A few inheritance bugs remain, and I'm trying to resolve
these. But it is now possible to use "this" as well as
refer implicitly to member variables, when in the proper
context.
llvm-svn: 114384
2010-09-21 08:44:12 +08:00
{
2013-07-12 06:46:58 +08:00
ClangASTType void_clang_type = ClangASTContext : : GetBasicType ( m_ast_context , eBasicTypeVoid ) ;
ClangASTType void_ptr_clang_type = void_clang_type . GetPointerType ( ) ;
Removed the hacky "#define this ___clang_this" handler
for C++ classes. Replaced it with a less hacky approach:
- If an expression is defined in the context of a
method of class A, then that expression is wrapped as
___clang_class::___clang_expr(void*) { ... }
instead of ___clang_expr(void*) { ... }.
- ___clang_class is resolved as the type of the target
of the "this" pointer in the method the expression
is defined in.
- When reporting the type of ___clang_class, a method
with the signature ___clang_expr(void*) is added to
that class, so that Clang doesn't complain about a
method being defined without a corresponding
declaration.
- Whenever the expression gets called, "this" gets
looked up, type-checked, and then passed in as the
first argument.
This required the following changes:
- The ABIs were changed to support passing of the "this"
pointer as part of trivial calls.
- ThreadPlanCallFunction and ClangFunction were changed
to support passing of an optional "this" pointer.
- ClangUserExpression was extended to perform the
wrapping described above.
- ClangASTSource was changed to revert the changes
required by the hack.
- ClangExpressionParser, IRForTarget, and
ClangExpressionDeclMap were changed to handle
different manglings of ___clang_expr flexibly. This
meant no longer searching for a function called
___clang_expr, but rather looking for a function whose
name *contains* ___clang_expr.
- ClangExpressionParser and ClangExpressionDeclMap now
remember whether "this" is required, and know how to
look it up as necessary.
A few inheritance bugs remain, and I'm trying to resolve
these. But it is now possible to use "this" as well as
refer implicitly to member variables, when in the proper
context.
llvm-svn: 114384
2010-09-21 08:44:12 +08:00
2013-07-12 06:46:58 +08:00
ClangASTType method_type = ClangASTContext : : CreateFunctionType ( m_ast_context ,
void_clang_type ,
& void_ptr_clang_type ,
2011-11-02 02:07:13 +08:00
1 ,
false ,
2013-07-12 06:46:58 +08:00
copied_clang_type . GetTypeQualifiers ( ) ) ;
2011-11-02 02:07:13 +08:00
2010-09-24 13:15:53 +08:00
const bool is_virtual = false ;
const bool is_static = false ;
const bool is_inline = false ;
2010-10-01 10:31:07 +08:00
const bool is_explicit = false ;
2011-11-03 02:09:01 +08:00
const bool is_attr_used = true ;
2011-11-02 09:38:59 +08:00
const bool is_artificial = false ;
2010-10-01 10:31:07 +08:00
2013-07-12 06:46:58 +08:00
copied_clang_type . AddMethodToCXXRecordType ( " $__lldb_expr " ,
method_type ,
lldb : : eAccessPublic ,
is_virtual ,
is_static ,
is_inline ,
is_explicit ,
is_attr_used ,
is_artificial ) ;
Removed the hacky "#define this ___clang_this" handler
for C++ classes. Replaced it with a less hacky approach:
- If an expression is defined in the context of a
method of class A, then that expression is wrapped as
___clang_class::___clang_expr(void*) { ... }
instead of ___clang_expr(void*) { ... }.
- ___clang_class is resolved as the type of the target
of the "this" pointer in the method the expression
is defined in.
- When reporting the type of ___clang_class, a method
with the signature ___clang_expr(void*) is added to
that class, so that Clang doesn't complain about a
method being defined without a corresponding
declaration.
- Whenever the expression gets called, "this" gets
looked up, type-checked, and then passed in as the
first argument.
This required the following changes:
- The ABIs were changed to support passing of the "this"
pointer as part of trivial calls.
- ThreadPlanCallFunction and ClangFunction were changed
to support passing of an optional "this" pointer.
- ClangUserExpression was extended to perform the
wrapping described above.
- ClangASTSource was changed to revert the changes
required by the hack.
- ClangExpressionParser, IRForTarget, and
ClangExpressionDeclMap were changed to handle
different manglings of ___clang_expr flexibly. This
meant no longer searching for a function called
___clang_expr, but rather looking for a function whose
name *contains* ___clang_expr.
- ClangExpressionParser and ClangExpressionDeclMap now
remember whether "this" is required, and know how to
look it up as necessary.
A few inheritance bugs remain, and I'm trying to resolve
these. But it is now possible to use "this" as well as
refer implicitly to member variables, when in the proper
context.
llvm-svn: 114384
2010-09-21 08:44:12 +08:00
}
2010-08-04 09:02:13 +08:00
2013-07-12 06:46:58 +08:00
return TypeFromParser ( copied_clang_type ) ;
2013-02-01 14:55:48 +08:00
}
void
ClangExpressionDeclMap : : AddOneType ( NameSearchContext & context ,
TypeFromUser & ut ,
unsigned int current_id )
{
2013-07-12 06:46:58 +08:00
ClangASTType copied_clang_type = GuardedCopyType ( ut ) ;
2013-02-01 14:55:48 +08:00
2013-07-12 06:46:58 +08:00
if ( ! copied_clang_type )
2013-02-01 14:55:48 +08:00
{
2013-03-28 07:08:40 +08:00
Log * log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_EXPRESSIONS ) ) ;
2013-02-01 14:55:48 +08:00
if ( log )
log - > Printf ( " ClangExpressionDeclMap::AddOneType - Couldn't import the type " ) ;
return ;
}
2013-07-12 06:46:58 +08:00
context . AddTypeDecl ( copied_clang_type ) ;
2010-08-04 09:02:13 +08:00
}