llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp

2352 lines
86 KiB
C++
Raw Normal View History

//===-- 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 "ClangExpressionDeclMap.h"
#include "ASTDumper.h"
#include "ClangASTSource.h"
#include "ClangModulesDeclVendor.h"
#include "ClangPersistentVariables.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclarationName.h"
#include "clang/AST/Decl.h"
#include "lldb/lldb-private.h"
#include "lldb/Core/Address.h"
#include "lldb/Core/Error.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
2011-05-09 20:18:18 +00:00
#include "lldb/Core/RegisterValue.h"
#include "lldb/Core/ValueObjectConstResult.h"
#include "lldb/Core/ValueObjectVariable.h"
#include "lldb/Expression/Materializer.h"
#include "lldb/Host/Endian.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/CompilerDecl.h"
Final bit of type system cleanup that abstracts declaration contexts into lldb_private::CompilerDeclContext and renames ClangType to CompilerType in many accessors and functions. Create a new "lldb_private::CompilerDeclContext" class that will replace all direct uses of "clang::DeclContext" when used in compiler agnostic code, yet still allow for conversion to clang::DeclContext subclasses by clang specific code. This completes the abstraction of type parsing by removing all "clang::" references from the SymbolFileDWARF. The new "lldb_private::CompilerDeclContext" class abstracts decl contexts found in compiler type systems so they can be used in internal API calls. The TypeSystem is required to support CompilerDeclContexts with new pure virtual functions that start with "DeclContext" in the member function names. Converted all code that used lldb_private::ClangNamespaceDecl over to use the new CompilerDeclContext class and removed the ClangNamespaceDecl.cpp and ClangNamespaceDecl.h files. Removed direct use of clang APIs from SBType and now use the abstract type systems to correctly explore types. Bulk renames for things that used to return a ClangASTType which is now CompilerType: "Type::GetClangFullType()" to "Type::GetFullCompilerType()" "Type::GetClangLayoutType()" to "Type::GetLayoutCompilerType()" "Type::GetClangForwardType()" to "Type::GetForwardCompilerType()" "Value::GetClangType()" to "Value::GetCompilerType()" "Value::SetClangType (const CompilerType &)" to "Value::SetCompilerType (const CompilerType &)" "ValueObject::GetClangType ()" to "ValueObject::GetCompilerType()" many more renames that are similar. llvm-svn: 245905
2015-08-24 23:46:31 +00:00
#include "lldb/Symbol/CompilerDeclContext.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Symbol/SymbolVendor.h"
#include "lldb/Symbol/Type.h"
#include "lldb/Symbol/TypeList.h"
#include "lldb/Symbol/Variable.h"
#include "lldb/Symbol/VariableList.h"
#include "lldb/Target/CPPLanguageRuntime.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/ObjCLanguageRuntime.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
using namespace lldb;
using namespace lldb_private;
using namespace clang;
ClangExpressionDeclMap::ClangExpressionDeclMap (bool keep_result_in_memory,
Materializer::PersistentVariableDelegate *result_delegate,
ExecutionContext &exe_ctx) :
ClangASTSource (exe_ctx.GetTargetSP()),
m_found_entities (),
m_struct_members (),
m_keep_result_in_memory (keep_result_in_memory),
m_result_delegate (result_delegate),
m_parser_vars (),
m_struct_vars ()
{
EnableStructVars();
}
ClangExpressionDeclMap::~ClangExpressionDeclMap()
{
// Note: The model is now that the parser's AST context and all associated
// data does not vanish until the expression has been executed. This means
// that valuable lookup data (like namespaces) doesn't vanish, but
DidParse();
DisableStructVars();
}
bool
ClangExpressionDeclMap::WillParse(ExecutionContext &exe_ctx,
Materializer *materializer)
{
ClangASTMetrics::ClearLocalCounters();
EnableParserVars();
m_parser_vars->m_exe_ctx = exe_ctx;
Target *target = exe_ctx.GetTargetPtr();
if (exe_ctx.GetFramePtr())
m_parser_vars->m_sym_ctx = exe_ctx.GetFramePtr()->GetSymbolContext(lldb::eSymbolContextEverything);
else if (exe_ctx.GetThreadPtr() && exe_ctx.GetThreadPtr()->GetStackFrameAtIndex(0))
m_parser_vars->m_sym_ctx = exe_ctx.GetThreadPtr()->GetStackFrameAtIndex(0)->GetSymbolContext(lldb::eSymbolContextEverything);
else if (exe_ctx.GetProcessPtr())
{
m_parser_vars->m_sym_ctx.Clear(true);
m_parser_vars->m_sym_ctx.target_sp = exe_ctx.GetTargetSP();
}
else if (target)
{
m_parser_vars->m_sym_ctx.Clear(true);
m_parser_vars->m_sym_ctx.target_sp = exe_ctx.GetTargetSP();
}
if (target)
{
m_parser_vars->m_persistent_vars = llvm::cast<ClangPersistentVariables>(target->GetPersistentExpressionStateForLanguage(eLanguageTypeC));
if (!target->GetScratchClangASTContext())
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 02:13:07 +00:00
m_parser_vars->m_target_info = GetTargetInfo();
m_parser_vars->m_materializer = materializer;
return true;
}
void
ClangExpressionDeclMap::InstallCodeGenerator (clang::ASTConsumer *code_gen)
{
assert(m_parser_vars);
m_parser_vars->m_code_gen = code_gen;
}
void
Modified LLDB expressions to not have to JIT and run code just to see variable values or persistent expression variables. Now if an expression consists of a value that is a child of a variable, or of a persistent variable only, we will create a value object for it and make a ValueObjectConstResult from it to freeze the value (for program variables only, not persistent variables) and avoid running JITed code. For everything else we still parse up and JIT code and run it in the inferior. There was also a lot of clean up in the expression code. I made the ClangExpressionVariables be stored in collections of shared pointers instead of in collections of objects. This will help stop a lot of copy constructors on these large objects and also cleans up the code considerably. The persistent clang expression variables were moved over to the Target to ensure they persist across process executions. Added the ability for lldb_private::Target objects to evaluate expressions. We want to evaluate expressions at the target level in case we aren't running yet, or we have just completed running. We still want to be able to access the persistent expression variables between runs, and also evaluate constant expressions. Added extra logging to the dynamic loader plug-in for MacOSX. ModuleList objects can now dump their contents with the UUID, arch and full paths being logged with appropriate prefix values. Thread hardened the Communication class a bit by making the connection auto_ptr member into a shared pointer member and then making a local copy of the shared pointer in each method that uses it to make sure another thread can't nuke the connection object while it is being used by another thread. Added a new file to the lldb/test/load_unload test that causes the test a.out file to link to the libd.dylib file all the time. This will allow us to test using the DYLD_LIBRARY_PATH environment variable after moving libd.dylib somewhere else. llvm-svn: 121745
2010-12-14 02:59:59 +00:00
ClangExpressionDeclMap::DidParse()
{
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
if (log)
ClangASTMetrics::DumpCounters(log);
if (m_parser_vars.get())
{
Modified LLDB expressions to not have to JIT and run code just to see variable values or persistent expression variables. Now if an expression consists of a value that is a child of a variable, or of a persistent variable only, we will create a value object for it and make a ValueObjectConstResult from it to freeze the value (for program variables only, not persistent variables) and avoid running JITed code. For everything else we still parse up and JIT code and run it in the inferior. There was also a lot of clean up in the expression code. I made the ClangExpressionVariables be stored in collections of shared pointers instead of in collections of objects. This will help stop a lot of copy constructors on these large objects and also cleans up the code considerably. The persistent clang expression variables were moved over to the Target to ensure they persist across process executions. Added the ability for lldb_private::Target objects to evaluate expressions. We want to evaluate expressions at the target level in case we aren't running yet, or we have just completed running. We still want to be able to access the persistent expression variables between runs, and also evaluate constant expressions. Added extra logging to the dynamic loader plug-in for MacOSX. ModuleList objects can now dump their contents with the UUID, arch and full paths being logged with appropriate prefix values. Thread hardened the Communication class a bit by making the connection auto_ptr member into a shared pointer member and then making a local copy of the shared pointer in each method that uses it to make sure another thread can't nuke the connection object while it is being used by another thread. Added a new file to the lldb/test/load_unload test that causes the test a.out file to link to the libd.dylib file all the time. This will allow us to test using the DYLD_LIBRARY_PATH environment variable after moving libd.dylib somewhere else. llvm-svn: 121745
2010-12-14 02:59:59 +00:00
for (size_t entity_index = 0, num_entities = m_found_entities.GetSize();
entity_index < num_entities;
++entity_index)
{
ExpressionVariableSP var_sp(m_found_entities.GetVariableAtIndex(entity_index));
if (var_sp)
llvm::cast<ClangExpressionVariable>(var_sp.get())->DisableParserVars(GetParserID());
}
Modified LLDB expressions to not have to JIT and run code just to see variable values or persistent expression variables. Now if an expression consists of a value that is a child of a variable, or of a persistent variable only, we will create a value object for it and make a ValueObjectConstResult from it to freeze the value (for program variables only, not persistent variables) and avoid running JITed code. For everything else we still parse up and JIT code and run it in the inferior. There was also a lot of clean up in the expression code. I made the ClangExpressionVariables be stored in collections of shared pointers instead of in collections of objects. This will help stop a lot of copy constructors on these large objects and also cleans up the code considerably. The persistent clang expression variables were moved over to the Target to ensure they persist across process executions. Added the ability for lldb_private::Target objects to evaluate expressions. We want to evaluate expressions at the target level in case we aren't running yet, or we have just completed running. We still want to be able to access the persistent expression variables between runs, and also evaluate constant expressions. Added extra logging to the dynamic loader plug-in for MacOSX. ModuleList objects can now dump their contents with the UUID, arch and full paths being logged with appropriate prefix values. Thread hardened the Communication class a bit by making the connection auto_ptr member into a shared pointer member and then making a local copy of the shared pointer in each method that uses it to make sure another thread can't nuke the connection object while it is being used by another thread. Added a new file to the lldb/test/load_unload test that causes the test a.out file to link to the libd.dylib file all the time. This will allow us to test using the DYLD_LIBRARY_PATH environment variable after moving libd.dylib somewhere else. llvm-svn: 121745
2010-12-14 02:59:59 +00:00
for (size_t pvar_index = 0, num_pvars = m_parser_vars->m_persistent_vars->GetSize();
pvar_index < num_pvars;
++pvar_index)
{
ExpressionVariableSP pvar_sp(m_parser_vars->m_persistent_vars->GetVariableAtIndex(pvar_index));
if (ClangExpressionVariable *clang_var = llvm::dyn_cast<ClangExpressionVariable>(pvar_sp.get()))
clang_var->DisableParserVars(GetParserID());
}
DisableParserVars();
}
}
// Interface for IRForTarget
ClangExpressionDeclMap::TargetInfo
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 02:13:07 +00:00
ClangExpressionDeclMap::GetTargetInfo()
{
assert (m_parser_vars.get());
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 02:13:07 +00:00
TargetInfo ret;
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 02:13:07 +00:00
{
ret.byte_order = process->GetByteOrder();
ret.address_byte_size = process->GetAddressByteSize();
}
else
{
Target *target = exe_ctx.GetTargetPtr();
if (target)
{
ret.byte_order = target->GetArchitecture().GetByteOrder();
ret.address_byte_size = target->GetArchitecture().GetAddressByteSize();
}
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 02:13:07 +00: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 02:13:07 +00:00
return ret;
}
bool
ClangExpressionDeclMap::AddPersistentVariable
(
const NamedDecl *decl,
const ConstString &name,
TypeFromParser parser_type,
bool is_result,
bool is_lvalue
)
{
assert (m_parser_vars.get());
ClangASTContext *ast = llvm::dyn_cast_or_null<ClangASTContext>(parser_type.GetTypeSystem());
if (ast == nullptr)
return false;
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-18 22:06:33 +00:00
if (m_parser_vars->m_materializer && is_result)
{
Error err;
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-18 22:06:33 +00:00
ExecutionContext &exe_ctx = m_parser_vars->m_exe_ctx;
Target *target = exe_ctx.GetTargetPtr();
if (target == nullptr)
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-18 22:06:33 +00:00
return false;
ClangASTContext *context(target->GetScratchClangASTContext());
TypeFromUser user_type(m_ast_importer_sp->DeportType(context->getASTContext(),
ast->getASTContext(),
parser_type.GetOpaqueQualType()),
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-18 22:06:33 +00:00
context);
uint32_t offset = m_parser_vars->m_materializer->AddResultVariable(user_type,
is_lvalue,
m_keep_result_in_memory,
m_result_delegate,
err);
ClangExpressionVariable *var = new ClangExpressionVariable(exe_ctx.GetBestExecutionContextScope(),
name,
user_type,
m_parser_vars->m_target_info.byte_order,
m_parser_vars->m_target_info.address_byte_size);
m_found_entities.AddNewlyConstructedVariable(var);
var->EnableParserVars(GetParserID());
ClangExpressionVariable::ParserVars *parser_vars = var->GetParserVars(GetParserID());
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-18 22:06:33 +00:00
parser_vars->m_named_decl = decl;
parser_vars->m_parser_type = parser_type;
var->EnableJITVars(GetParserID());
ClangExpressionVariable::JITVars *jit_vars = var->GetJITVars(GetParserID());
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-18 22:06:33 +00:00
jit_vars->m_offset = offset;
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-18 22:06:33 +00:00
return true;
}
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
ExecutionContext &exe_ctx = m_parser_vars->m_exe_ctx;
Target *target = exe_ctx.GetTargetPtr();
if (target == NULL)
return false;
ClangASTContext *context(target->GetScratchClangASTContext());
TypeFromUser user_type(m_ast_importer_sp->DeportType(context->getASTContext(),
ast->getASTContext(),
parser_type.GetOpaqueQualType()),
context);
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 02:13:07 +00:00
if (!m_parser_vars->m_target_info.IsValid())
return false;
ClangExpressionVariable *var = llvm::cast<ClangExpressionVariable>(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).get());
if (!var)
return false;
var->m_frozen_sp->SetHasCompleteType();
if (is_result)
var->m_flags |= ClangExpressionVariable::EVNeedsFreezeDry;
else
var->m_flags |= ClangExpressionVariable::EVKeepInTarget; // explicitly-declared persistent variables should persist
if (is_lvalue)
{
var->m_flags |= ClangExpressionVariable::EVIsProgramReference;
}
else
{
var->m_flags |= ClangExpressionVariable::EVIsLLDBAllocated;
var->m_flags |= ClangExpressionVariable::EVNeedsAllocation;
}
if (m_keep_result_in_memory)
{
var->m_flags |= ClangExpressionVariable::EVKeepInTarget;
}
if (log)
log->Printf("Created persistent variable with flags 0x%hx", var->m_flags);
var->EnableParserVars(GetParserID());
ClangExpressionVariable::ParserVars *parser_vars = var->GetParserVars(GetParserID());
parser_vars->m_named_decl = decl;
parser_vars->m_parser_type = parser_type;
return true;
}
bool
ClangExpressionDeclMap::AddValueToStruct
(
const NamedDecl *decl,
const ConstString &name,
llvm::Value *value,
size_t size,
lldb::offset_t alignment
)
{
assert (m_struct_vars.get());
assert (m_parser_vars.get());
bool is_persistent_variable = false;
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
m_struct_vars->m_struct_laid_out = false;
if (ClangExpressionVariable::FindVariableInList(m_struct_members, decl, GetParserID()))
return true;
ClangExpressionVariable *var(ClangExpressionVariable::FindVariableInList(m_found_entities, decl, GetParserID()));
if (!var)
{
var = ClangExpressionVariable::FindVariableInList(*m_parser_vars->m_persistent_vars, decl, GetParserID());
is_persistent_variable = true;
}
if (!var)
return false;
if (log)
log->Printf("Adding value for (NamedDecl*)%p [%s - %s] to the structure",
static_cast<const void*>(decl), name.GetCString(),
var->GetName().GetCString());
// We know entity->m_parser_vars is valid because we used a parser variable
// to find it
ClangExpressionVariable::ParserVars *parser_vars = llvm::cast<ClangExpressionVariable>(var)->GetParserVars(GetParserID());
parser_vars->m_llvm_value = value;
if (ClangExpressionVariable::JITVars *jit_vars = llvm::cast<ClangExpressionVariable>(var)->GetJITVars(GetParserID()))
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-18 22:06:33 +00:00
{
// We already laid this out; do not touch
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-18 22:06:33 +00:00
if (log)
log->Printf("Already placed at 0x%llx", (unsigned long long)jit_vars->m_offset);
}
llvm::cast<ClangExpressionVariable>(var)->EnableJITVars(GetParserID());
ClangExpressionVariable::JITVars *jit_vars = llvm::cast<ClangExpressionVariable>(var)->GetJITVars(GetParserID());
jit_vars->m_alignment = alignment;
jit_vars->m_size = size;
m_struct_members.AddVariable(var->shared_from_this());
if (m_parser_vars->m_materializer)
{
uint32_t offset = 0;
Error err;
if (is_persistent_variable)
{
ExpressionVariableSP var_sp(var->shared_from_this());
offset = m_parser_vars->m_materializer->AddPersistentVariable(var_sp, nullptr, err);
}
else
{
if (const lldb_private::Symbol *sym = parser_vars->m_lldb_sym)
offset = m_parser_vars->m_materializer->AddSymbol(*sym, err);
else if (const RegisterInfo *reg_info = var->GetRegisterInfo())
offset = m_parser_vars->m_materializer->AddRegister(*reg_info, err);
else if (parser_vars->m_lldb_var)
offset = m_parser_vars->m_materializer->AddVariable(parser_vars->m_lldb_var, err);
}
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.
}
return true;
}
bool
ClangExpressionDeclMap::DoStructLayout ()
{
assert (m_struct_vars.get());
if (m_struct_vars->m_struct_laid_out)
return true;
if (!m_parser_vars->m_materializer)
return false;
m_struct_vars->m_struct_alignment = m_parser_vars->m_materializer->GetStructAlignment();
m_struct_vars->m_struct_size = m_parser_vars->m_materializer->GetStructByteSize();
m_struct_vars->m_struct_laid_out = true;
return true;
}
bool ClangExpressionDeclMap::GetStructInfo
(
uint32_t &num_elements,
size_t &size,
lldb::offset_t &alignment
)
{
assert (m_struct_vars.get());
if (!m_struct_vars->m_struct_laid_out)
return false;
Modified LLDB expressions to not have to JIT and run code just to see variable values or persistent expression variables. Now if an expression consists of a value that is a child of a variable, or of a persistent variable only, we will create a value object for it and make a ValueObjectConstResult from it to freeze the value (for program variables only, not persistent variables) and avoid running JITed code. For everything else we still parse up and JIT code and run it in the inferior. There was also a lot of clean up in the expression code. I made the ClangExpressionVariables be stored in collections of shared pointers instead of in collections of objects. This will help stop a lot of copy constructors on these large objects and also cleans up the code considerably. The persistent clang expression variables were moved over to the Target to ensure they persist across process executions. Added the ability for lldb_private::Target objects to evaluate expressions. We want to evaluate expressions at the target level in case we aren't running yet, or we have just completed running. We still want to be able to access the persistent expression variables between runs, and also evaluate constant expressions. Added extra logging to the dynamic loader plug-in for MacOSX. ModuleList objects can now dump their contents with the UUID, arch and full paths being logged with appropriate prefix values. Thread hardened the Communication class a bit by making the connection auto_ptr member into a shared pointer member and then making a local copy of the shared pointer in each method that uses it to make sure another thread can't nuke the connection object while it is being used by another thread. Added a new file to the lldb/test/load_unload test that causes the test a.out file to link to the libd.dylib file all the time. This will allow us to test using the DYLD_LIBRARY_PATH environment variable after moving libd.dylib somewhere else. llvm-svn: 121745
2010-12-14 02:59:59 +00:00
num_elements = m_struct_members.GetSize();
size = m_struct_vars->m_struct_size;
alignment = m_struct_vars->m_struct_alignment;
return true;
}
bool
ClangExpressionDeclMap::GetStructElement
(
const NamedDecl *&decl,
llvm::Value *&value,
lldb::offset_t &offset,
ConstString &name,
uint32_t index
)
{
assert (m_struct_vars.get());
if (!m_struct_vars->m_struct_laid_out)
return false;
Modified LLDB expressions to not have to JIT and run code just to see variable values or persistent expression variables. Now if an expression consists of a value that is a child of a variable, or of a persistent variable only, we will create a value object for it and make a ValueObjectConstResult from it to freeze the value (for program variables only, not persistent variables) and avoid running JITed code. For everything else we still parse up and JIT code and run it in the inferior. There was also a lot of clean up in the expression code. I made the ClangExpressionVariables be stored in collections of shared pointers instead of in collections of objects. This will help stop a lot of copy constructors on these large objects and also cleans up the code considerably. The persistent clang expression variables were moved over to the Target to ensure they persist across process executions. Added the ability for lldb_private::Target objects to evaluate expressions. We want to evaluate expressions at the target level in case we aren't running yet, or we have just completed running. We still want to be able to access the persistent expression variables between runs, and also evaluate constant expressions. Added extra logging to the dynamic loader plug-in for MacOSX. ModuleList objects can now dump their contents with the UUID, arch and full paths being logged with appropriate prefix values. Thread hardened the Communication class a bit by making the connection auto_ptr member into a shared pointer member and then making a local copy of the shared pointer in each method that uses it to make sure another thread can't nuke the connection object while it is being used by another thread. Added a new file to the lldb/test/load_unload test that causes the test a.out file to link to the libd.dylib file all the time. This will allow us to test using the DYLD_LIBRARY_PATH environment variable after moving libd.dylib somewhere else. llvm-svn: 121745
2010-12-14 02:59:59 +00:00
if (index >= m_struct_members.GetSize())
return false;
ExpressionVariableSP member_sp(m_struct_members.GetVariableAtIndex(index));
if (!member_sp)
return false;
ClangExpressionVariable::ParserVars *parser_vars = llvm::cast<ClangExpressionVariable>(member_sp.get())->GetParserVars(GetParserID());
ClangExpressionVariable::JITVars *jit_vars = llvm::cast<ClangExpressionVariable>(member_sp.get())->GetJITVars(GetParserID());
if (!parser_vars ||
!jit_vars ||
!member_sp->GetValueObject())
return false;
decl = parser_vars->m_named_decl;
value = parser_vars->m_llvm_value;
offset = jit_vars->m_offset;
Modified LLDB expressions to not have to JIT and run code just to see variable values or persistent expression variables. Now if an expression consists of a value that is a child of a variable, or of a persistent variable only, we will create a value object for it and make a ValueObjectConstResult from it to freeze the value (for program variables only, not persistent variables) and avoid running JITed code. For everything else we still parse up and JIT code and run it in the inferior. There was also a lot of clean up in the expression code. I made the ClangExpressionVariables be stored in collections of shared pointers instead of in collections of objects. This will help stop a lot of copy constructors on these large objects and also cleans up the code considerably. The persistent clang expression variables were moved over to the Target to ensure they persist across process executions. Added the ability for lldb_private::Target objects to evaluate expressions. We want to evaluate expressions at the target level in case we aren't running yet, or we have just completed running. We still want to be able to access the persistent expression variables between runs, and also evaluate constant expressions. Added extra logging to the dynamic loader plug-in for MacOSX. ModuleList objects can now dump their contents with the UUID, arch and full paths being logged with appropriate prefix values. Thread hardened the Communication class a bit by making the connection auto_ptr member into a shared pointer member and then making a local copy of the shared pointer in each method that uses it to make sure another thread can't nuke the connection object while it is being used by another thread. Added a new file to the lldb/test/load_unload test that causes the test a.out file to link to the libd.dylib file all the time. This will allow us to test using the DYLD_LIBRARY_PATH environment variable after moving libd.dylib somewhere else. llvm-svn: 121745
2010-12-14 02:59:59 +00:00
name = member_sp->GetName();
return true;
}
bool
ClangExpressionDeclMap::GetFunctionInfo
(
const NamedDecl *decl,
uint64_t &ptr
)
{
ClangExpressionVariable *entity(ClangExpressionVariable::FindVariableInList(m_found_entities, decl, GetParserID()));
if (!entity)
return false;
// We know m_parser_vars is valid since we searched for the variable by
// its NamedDecl
ClangExpressionVariable::ParserVars *parser_vars = entity->GetParserVars(GetParserID());
ptr = parser_vars->m_lldb_value.GetScalar().ULongLong();
return true;
}
static void
FindCodeSymbolInContext
(
const ConstString &name,
SymbolContext &sym_ctx,
uint32_t name_type_mask,
SymbolContextList &sc_list
)
{
sc_list.Clear();
SymbolContextList temp_sc_list;
if (sym_ctx.module_sp)
sym_ctx.module_sp->FindFunctions(name,
NULL,
name_type_mask,
true, // include_symbols
false, // include_inlines
true, // append
temp_sc_list);
if (temp_sc_list.GetSize() == 0)
{
if (sym_ctx.target_sp)
sym_ctx.target_sp->GetImages().FindFunctions(name,
name_type_mask,
true, // include_symbols
false, // include_inlines
true, // append
temp_sc_list);
}
SymbolContextList internal_symbol_sc_list;
unsigned temp_sc_list_size = temp_sc_list.GetSize();
for (unsigned i = 0; i < temp_sc_list_size; i++)
{
SymbolContext sc;
temp_sc_list.GetContextAtIndex(i, sc);
if (sc.function)
{
sc_list.Append(sc);
}
else if (sc.symbol)
{
if (sc.symbol->IsExternal())
{
sc_list.Append(sc);
}
else
{
internal_symbol_sc_list.Append(sc);
}
}
}
// If we had internal symbols and we didn't find any external symbols or
// functions in debug info, then fallback to the internal symbols
if (sc_list.GetSize() == 0 && internal_symbol_sc_list.GetSize())
{
sc_list = internal_symbol_sc_list;
}
}
bool
ClangExpressionDeclMap::GetFunctionAddress
(
const ConstString &name,
uint64_t &func_addr
)
{
assert (m_parser_vars.get());
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
ExecutionContext &exe_ctx = m_parser_vars->m_exe_ctx;
Target *target = exe_ctx.GetTargetPtr();
// Back out in all cases where we're not fully initialized
if (target == NULL)
return false;
if (!m_parser_vars->m_sym_ctx.target_sp)
return false;
SymbolContextList sc_list;
FindCodeSymbolInContext(name, m_parser_vars->m_sym_ctx, eFunctionNameTypeAuto, sc_list);
uint32_t sc_list_size = sc_list.GetSize();
if (sc_list_size == 0)
{
SymbolContext &sc = m_parser_vars->m_sym_ctx;
if (sc.comp_unit)
{
LanguageType lang_type = sc.comp_unit->GetLanguage();
if (Language::LanguageIsCPlusPlus(lang_type) &&
CPlusPlusLanguage::IsCPPMangledName(name.AsCString()))
{
// 1. Demangle the name
Mangled mangled(name, true);
ConstString demangled = mangled.GetDemangledName(lang_type);
if (demangled)
{
FindCodeSymbolInContext(
demangled, m_parser_vars->m_sym_ctx, eFunctionNameTypeFull, sc_list);
sc_list_size = sc_list.GetSize();
}
}
}
}
if (sc_list_size == 0)
{
// 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.
if (!strncmp(name.GetCString(), "_ZN", 3) &&
strncmp(name.GetCString(), "_ZNK", 4))
{
std::string fixed_scratch("_ZNK");
fixed_scratch.append(name.GetCString() + 3);
ConstString fixed_name(fixed_scratch.c_str());
if (log)
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, eFunctionNameTypeAuto, sc_list);
sc_list_size = sc_list.GetSize();
}
}
When we have a symbol, like "NSLog" that we try to call in an expression, make sure we prioritize the external symbols over the internal one. This is a temporary fix until a more comprehensive fix can be made for finding functions that we call in expressions. We find "NSLog" in ClangExpressionDeclMap::FindExternalVisibleDecls() in after a call to target->GetImages().FindFunctions(...). Note that there are two symbols: NSLog from CFNetwork which is not external, and NSLog from Foundation which _is_ external. We do something with the external symbol with: if (extern_symbol) { AddOneFunction (context, NULL, extern_symbol, current_id); context.m_found.function = true; } Then later we try to lookup the _Z5NSLogP8NSStringz name and we don't find it so we call ClangExpressionDeclMap::GetFunctionAddress() with "_Z5NSLogP8NSStringz" as the name and the sc_list_size is zero at the "if" statement at line 568 because we don't find the mangled name and we extract the basename "NSLog" and call: FindCodeSymbolInContext(ConstString(basename), m_parser_vars->m_sym_ctx, sc_list); sc_list_size = sc_list.GetSize(); and we get a list size of two again, and we proceed to search for the symbol again, this time ignoring the external vs non-external-ness of the symbols that we find. This fix ensures we prioritize the external symbol until we get a real fix from Sean Callanan when he gets back to make sure we don't do multiple lookups for the same symbol we already resolved. <rdar://problem/19879282> llvm-svn: 231420
2015-03-05 23:12:02 +00:00
lldb::addr_t intern_callable_load_addr = LLDB_INVALID_ADDRESS;
for (uint32_t i=0; i<sc_list_size; ++i)
{
SymbolContext sym_ctx;
sc_list.GetContextAtIndex(i, sym_ctx);
When we have a symbol, like "NSLog" that we try to call in an expression, make sure we prioritize the external symbols over the internal one. This is a temporary fix until a more comprehensive fix can be made for finding functions that we call in expressions. We find "NSLog" in ClangExpressionDeclMap::FindExternalVisibleDecls() in after a call to target->GetImages().FindFunctions(...). Note that there are two symbols: NSLog from CFNetwork which is not external, and NSLog from Foundation which _is_ external. We do something with the external symbol with: if (extern_symbol) { AddOneFunction (context, NULL, extern_symbol, current_id); context.m_found.function = true; } Then later we try to lookup the _Z5NSLogP8NSStringz name and we don't find it so we call ClangExpressionDeclMap::GetFunctionAddress() with "_Z5NSLogP8NSStringz" as the name and the sc_list_size is zero at the "if" statement at line 568 because we don't find the mangled name and we extract the basename "NSLog" and call: FindCodeSymbolInContext(ConstString(basename), m_parser_vars->m_sym_ctx, sc_list); sc_list_size = sc_list.GetSize(); and we get a list size of two again, and we proceed to search for the symbol again, this time ignoring the external vs non-external-ness of the symbols that we find. This fix ensures we prioritize the external symbol until we get a real fix from Sean Callanan when he gets back to make sure we don't do multiple lookups for the same symbol we already resolved. <rdar://problem/19879282> llvm-svn: 231420
2015-03-05 23:12:02 +00:00
lldb::addr_t callable_load_addr = LLDB_INVALID_ADDRESS;
if (sym_ctx.function)
{
const Address func_so_addr = sym_ctx.function->GetAddressRange().GetBaseAddress();
if (func_so_addr.IsValid())
{
callable_load_addr = func_so_addr.GetCallableLoadAddress(target, false);
}
}
else if (sym_ctx.symbol)
{
When we have a symbol, like "NSLog" that we try to call in an expression, make sure we prioritize the external symbols over the internal one. This is a temporary fix until a more comprehensive fix can be made for finding functions that we call in expressions. We find "NSLog" in ClangExpressionDeclMap::FindExternalVisibleDecls() in after a call to target->GetImages().FindFunctions(...). Note that there are two symbols: NSLog from CFNetwork which is not external, and NSLog from Foundation which _is_ external. We do something with the external symbol with: if (extern_symbol) { AddOneFunction (context, NULL, extern_symbol, current_id); context.m_found.function = true; } Then later we try to lookup the _Z5NSLogP8NSStringz name and we don't find it so we call ClangExpressionDeclMap::GetFunctionAddress() with "_Z5NSLogP8NSStringz" as the name and the sc_list_size is zero at the "if" statement at line 568 because we don't find the mangled name and we extract the basename "NSLog" and call: FindCodeSymbolInContext(ConstString(basename), m_parser_vars->m_sym_ctx, sc_list); sc_list_size = sc_list.GetSize(); and we get a list size of two again, and we proceed to search for the symbol again, this time ignoring the external vs non-external-ness of the symbols that we find. This fix ensures we prioritize the external symbol until we get a real fix from Sean Callanan when he gets back to make sure we don't do multiple lookups for the same symbol we already resolved. <rdar://problem/19879282> llvm-svn: 231420
2015-03-05 23:12:02 +00:00
if (sym_ctx.symbol->IsExternal())
callable_load_addr = sym_ctx.symbol->ResolveCallableAddress(*target);
else
{
if (intern_callable_load_addr == LLDB_INVALID_ADDRESS)
intern_callable_load_addr = sym_ctx.symbol->ResolveCallableAddress(*target);
}
}
if (callable_load_addr != LLDB_INVALID_ADDRESS)
{
func_addr = callable_load_addr;
return true;
}
}
When we have a symbol, like "NSLog" that we try to call in an expression, make sure we prioritize the external symbols over the internal one. This is a temporary fix until a more comprehensive fix can be made for finding functions that we call in expressions. We find "NSLog" in ClangExpressionDeclMap::FindExternalVisibleDecls() in after a call to target->GetImages().FindFunctions(...). Note that there are two symbols: NSLog from CFNetwork which is not external, and NSLog from Foundation which _is_ external. We do something with the external symbol with: if (extern_symbol) { AddOneFunction (context, NULL, extern_symbol, current_id); context.m_found.function = true; } Then later we try to lookup the _Z5NSLogP8NSStringz name and we don't find it so we call ClangExpressionDeclMap::GetFunctionAddress() with "_Z5NSLogP8NSStringz" as the name and the sc_list_size is zero at the "if" statement at line 568 because we don't find the mangled name and we extract the basename "NSLog" and call: FindCodeSymbolInContext(ConstString(basename), m_parser_vars->m_sym_ctx, sc_list); sc_list_size = sc_list.GetSize(); and we get a list size of two again, and we proceed to search for the symbol again, this time ignoring the external vs non-external-ness of the symbols that we find. This fix ensures we prioritize the external symbol until we get a real fix from Sean Callanan when he gets back to make sure we don't do multiple lookups for the same symbol we already resolved. <rdar://problem/19879282> llvm-svn: 231420
2015-03-05 23:12:02 +00:00
// See if we found an internal symbol
if (intern_callable_load_addr != LLDB_INVALID_ADDRESS)
{
func_addr = intern_callable_load_addr;
return true;
}
return false;
}
addr_t
ClangExpressionDeclMap::GetSymbolAddress (Target &target,
Process *process,
const ConstString &name,
lldb::SymbolType symbol_type,
lldb_private::Module *module)
{
SymbolContextList sc_list;
if (module)
module->FindSymbolsWithNameAndType(name, symbol_type, sc_list);
else
target.GetImages().FindSymbolsWithNameAndType(name, symbol_type, sc_list);
const uint32_t num_matches = sc_list.GetSize();
addr_t symbol_load_addr = LLDB_INVALID_ADDRESS;
for (uint32_t i=0; i<num_matches && (symbol_load_addr == 0 || symbol_load_addr == LLDB_INVALID_ADDRESS); i++)
{
SymbolContext sym_ctx;
sc_list.GetContextAtIndex(i, sym_ctx);
const Address sym_address = sym_ctx.symbol->GetAddress();
if (!sym_address.IsValid())
continue;
switch (sym_ctx.symbol->GetType())
{
case eSymbolTypeCode:
case eSymbolTypeTrampoline:
symbol_load_addr = sym_address.GetCallableLoadAddress (&target);
break;
case eSymbolTypeResolver:
symbol_load_addr = sym_address.GetCallableLoadAddress (&target, true);
break;
case eSymbolTypeReExported:
{
ConstString reexport_name = sym_ctx.symbol->GetReExportedSymbolName();
if (reexport_name)
{
ModuleSP reexport_module_sp;
ModuleSpec reexport_module_spec;
reexport_module_spec.GetPlatformFileSpec() = sym_ctx.symbol->GetReExportedSymbolSharedLibrary();
if (reexport_module_spec.GetPlatformFileSpec())
{
reexport_module_sp = target.GetImages().FindFirstModule(reexport_module_spec);
if (!reexport_module_sp)
{
reexport_module_spec.GetPlatformFileSpec().GetDirectory().Clear();
reexport_module_sp = target.GetImages().FindFirstModule(reexport_module_spec);
}
}
symbol_load_addr = GetSymbolAddress(target, process, sym_ctx.symbol->GetReExportedSymbolName(), symbol_type, reexport_module_sp.get());
}
}
break;
case eSymbolTypeData:
case eSymbolTypeRuntime:
case eSymbolTypeVariable:
case eSymbolTypeLocal:
case eSymbolTypeParam:
case eSymbolTypeInvalid:
case eSymbolTypeAbsolute:
case eSymbolTypeException:
case eSymbolTypeSourceFile:
case eSymbolTypeHeaderFile:
case eSymbolTypeObjectFile:
case eSymbolTypeCommonBlock:
case eSymbolTypeBlock:
case eSymbolTypeVariableType:
case eSymbolTypeLineEntry:
case eSymbolTypeLineHeader:
case eSymbolTypeScopeBegin:
case eSymbolTypeScopeEnd:
case eSymbolTypeAdditional:
case eSymbolTypeCompiler:
case eSymbolTypeInstrumentation:
case eSymbolTypeUndefined:
case eSymbolTypeObjCClass:
case eSymbolTypeObjCMetaClass:
case eSymbolTypeObjCIVar:
symbol_load_addr = sym_address.GetLoadAddress (&target);
break;
}
}
if (symbol_load_addr == LLDB_INVALID_ADDRESS && process)
{
ObjCLanguageRuntime *runtime = process->GetObjCLanguageRuntime();
if (runtime)
{
symbol_load_addr = runtime->LookupRuntimeSymbol(name);
}
}
return symbol_load_addr;
}
addr_t
ClangExpressionDeclMap::GetSymbolAddress (const ConstString &name, lldb::SymbolType symbol_type)
{
assert (m_parser_vars.get());
if (!m_parser_vars->m_exe_ctx.GetTargetPtr())
return false;
return GetSymbolAddress(m_parser_vars->m_exe_ctx.GetTargetRef(), m_parser_vars->m_exe_ctx.GetProcessPtr(), name, symbol_type);
}
const Symbol *
ClangExpressionDeclMap::FindGlobalDataSymbol (Target &target,
const ConstString &name,
lldb_private::Module *module)
{
SymbolContextList sc_list;
if (module)
module->FindSymbolsWithNameAndType(name, eSymbolTypeAny, sc_list);
else
target.GetImages().FindSymbolsWithNameAndType(name, eSymbolTypeAny, sc_list);
const uint32_t matches = sc_list.GetSize();
for (uint32_t i=0; i<matches; ++i)
{
SymbolContext sym_ctx;
sc_list.GetContextAtIndex(i, sym_ctx);
if (sym_ctx.symbol)
{
const Symbol *symbol = sym_ctx.symbol;
const Address sym_address = symbol->GetAddress();
if (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 eSymbolTypeReExported:
{
ConstString reexport_name = symbol->GetReExportedSymbolName();
if (reexport_name)
{
ModuleSP reexport_module_sp;
ModuleSpec reexport_module_spec;
reexport_module_spec.GetPlatformFileSpec() = symbol->GetReExportedSymbolSharedLibrary();
if (reexport_module_spec.GetPlatformFileSpec())
{
reexport_module_sp = target.GetImages().FindFirstModule(reexport_module_spec);
if (!reexport_module_sp)
{
reexport_module_spec.GetPlatformFileSpec().GetDirectory().Clear();
reexport_module_sp = target.GetImages().FindFirstModule(reexport_module_spec);
}
}
// Don't allow us to try and resolve a re-exported symbol if it is the same
// as the current symbol
if (name == symbol->GetReExportedSymbolName() && module == reexport_module_sp.get())
return NULL;
return FindGlobalDataSymbol(target, symbol->GetReExportedSymbolName(), reexport_module_sp.get());
}
}
break;
case eSymbolTypeCode: // We already lookup functions elsewhere
case eSymbolTypeVariable:
case eSymbolTypeLocal:
case eSymbolTypeParam:
case eSymbolTypeTrampoline:
case eSymbolTypeInvalid:
case eSymbolTypeException:
case eSymbolTypeSourceFile:
case eSymbolTypeHeaderFile:
case eSymbolTypeObjectFile:
case eSymbolTypeCommonBlock:
case eSymbolTypeBlock:
case eSymbolTypeVariableType:
case eSymbolTypeLineEntry:
case eSymbolTypeLineHeader:
case eSymbolTypeScopeBegin:
case eSymbolTypeScopeEnd:
case eSymbolTypeAdditional:
case eSymbolTypeCompiler:
case eSymbolTypeInstrumentation:
case eSymbolTypeUndefined:
case eSymbolTypeResolver:
break;
}
}
}
}
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 02:13:07 +00:00
lldb::VariableSP
ClangExpressionDeclMap::FindGlobalVariable
(
Target &target,
ModuleSP &module,
const ConstString &name,
Final bit of type system cleanup that abstracts declaration contexts into lldb_private::CompilerDeclContext and renames ClangType to CompilerType in many accessors and functions. Create a new "lldb_private::CompilerDeclContext" class that will replace all direct uses of "clang::DeclContext" when used in compiler agnostic code, yet still allow for conversion to clang::DeclContext subclasses by clang specific code. This completes the abstraction of type parsing by removing all "clang::" references from the SymbolFileDWARF. The new "lldb_private::CompilerDeclContext" class abstracts decl contexts found in compiler type systems so they can be used in internal API calls. The TypeSystem is required to support CompilerDeclContexts with new pure virtual functions that start with "DeclContext" in the member function names. Converted all code that used lldb_private::ClangNamespaceDecl over to use the new CompilerDeclContext class and removed the ClangNamespaceDecl.cpp and ClangNamespaceDecl.h files. Removed direct use of clang APIs from SBType and now use the abstract type systems to correctly explore types. Bulk renames for things that used to return a ClangASTType which is now CompilerType: "Type::GetClangFullType()" to "Type::GetFullCompilerType()" "Type::GetClangLayoutType()" to "Type::GetLayoutCompilerType()" "Type::GetClangForwardType()" to "Type::GetForwardCompilerType()" "Value::GetClangType()" to "Value::GetCompilerType()" "Value::SetClangType (const CompilerType &)" to "Value::SetCompilerType (const CompilerType &)" "ValueObject::GetClangType ()" to "ValueObject::GetCompilerType()" many more renames that are similar. llvm-svn: 245905
2015-08-24 23:46:31 +00:00
CompilerDeclContext *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 02:13:07 +00:00
TypeFromUser *type
)
{
VariableList vars;
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 02:13:07 +00:00
if (vars.GetSize())
{
if (type)
{
for (size_t i = 0; i < vars.GetSize(); ++i)
{
VariableSP var_sp = vars.GetVariableAtIndex(i);
Final bit of type system cleanup that abstracts declaration contexts into lldb_private::CompilerDeclContext and renames ClangType to CompilerType in many accessors and functions. Create a new "lldb_private::CompilerDeclContext" class that will replace all direct uses of "clang::DeclContext" when used in compiler agnostic code, yet still allow for conversion to clang::DeclContext subclasses by clang specific code. This completes the abstraction of type parsing by removing all "clang::" references from the SymbolFileDWARF. The new "lldb_private::CompilerDeclContext" class abstracts decl contexts found in compiler type systems so they can be used in internal API calls. The TypeSystem is required to support CompilerDeclContexts with new pure virtual functions that start with "DeclContext" in the member function names. Converted all code that used lldb_private::ClangNamespaceDecl over to use the new CompilerDeclContext class and removed the ClangNamespaceDecl.cpp and ClangNamespaceDecl.h files. Removed direct use of clang APIs from SBType and now use the abstract type systems to correctly explore types. Bulk renames for things that used to return a ClangASTType which is now CompilerType: "Type::GetClangFullType()" to "Type::GetFullCompilerType()" "Type::GetClangLayoutType()" to "Type::GetLayoutCompilerType()" "Type::GetClangForwardType()" to "Type::GetForwardCompilerType()" "Value::GetClangType()" to "Value::GetCompilerType()" "Value::SetClangType (const CompilerType &)" to "Value::SetCompilerType (const CompilerType &)" "ValueObject::GetClangType ()" to "ValueObject::GetCompilerType()" many more renames that are similar. llvm-svn: 245905
2015-08-24 23:46:31 +00:00
if (ClangASTContext::AreTypesSame(*type, var_sp->GetType()->GetFullCompilerType ()))
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 02:13:07 +00:00
}
}
else
{
return vars.GetVariableAtIndex(0);
}
}
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 02:13:07 +00:00
return VariableSP();
}
// 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 02:13:07 +00:00
void
ClangExpressionDeclMap::FindExternalVisibleDecls (NameSearchContext &context)
{
assert (m_ast_context);
ClangASTMetrics::RegisterVisibleQuery();
const ConstString name(context.m_decl_name.getAsString().c_str());
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
if (GetImportInProgress())
{
if (log && log->GetVerbose())
log->Printf("Ignoring a query during an import");
return;
}
static unsigned int invocation_id = 0;
unsigned int current_id = invocation_id++;
if (log)
{
if (!context.m_decl_context)
log->Printf("ClangExpressionDeclMap::FindExternalVisibleDecls[%u] for '%s' in a NULL DeclContext", current_id, name.GetCString());
else if (const NamedDecl *context_named_decl = dyn_cast<NamedDecl>(context.m_decl_context))
log->Printf("ClangExpressionDeclMap::FindExternalVisibleDecls[%u] for '%s' in '%s'", current_id, name.GetCString(), context_named_decl->getNameAsString().c_str());
else
log->Printf("ClangExpressionDeclMap::FindExternalVisibleDecls[%u] for '%s' in a '%s'", current_id, name.GetCString(), context.m_decl_context->getDeclKindName());
}
if (const NamespaceDecl *namespace_context = dyn_cast<NamespaceDecl>(context.m_decl_context))
{
ClangASTImporter::NamespaceMapSP namespace_map = m_ast_importer_sp->GetNamespaceMap(namespace_context);
if (log && log->GetVerbose())
log->Printf(" CEDM::FEVD[%u] Inspecting (NamespaceMap*)%p (%d entries)",
current_id, static_cast<void*>(namespace_map.get()),
(int)namespace_map->size());
if (!namespace_map)
return;
for (ClangASTImporter::NamespaceMap::iterator i = namespace_map->begin(), e = namespace_map->end();
i != e;
++i)
{
if (log)
log->Printf(" CEDM::FEVD[%u] Searching namespace %s in module %s",
current_id,
Final bit of type system cleanup that abstracts declaration contexts into lldb_private::CompilerDeclContext and renames ClangType to CompilerType in many accessors and functions. Create a new "lldb_private::CompilerDeclContext" class that will replace all direct uses of "clang::DeclContext" when used in compiler agnostic code, yet still allow for conversion to clang::DeclContext subclasses by clang specific code. This completes the abstraction of type parsing by removing all "clang::" references from the SymbolFileDWARF. The new "lldb_private::CompilerDeclContext" class abstracts decl contexts found in compiler type systems so they can be used in internal API calls. The TypeSystem is required to support CompilerDeclContexts with new pure virtual functions that start with "DeclContext" in the member function names. Converted all code that used lldb_private::ClangNamespaceDecl over to use the new CompilerDeclContext class and removed the ClangNamespaceDecl.cpp and ClangNamespaceDecl.h files. Removed direct use of clang APIs from SBType and now use the abstract type systems to correctly explore types. Bulk renames for things that used to return a ClangASTType which is now CompilerType: "Type::GetClangFullType()" to "Type::GetFullCompilerType()" "Type::GetClangLayoutType()" to "Type::GetLayoutCompilerType()" "Type::GetClangForwardType()" to "Type::GetForwardCompilerType()" "Value::GetClangType()" to "Value::GetCompilerType()" "Value::SetClangType (const CompilerType &)" to "Value::SetCompilerType (const CompilerType &)" "ValueObject::GetClangType ()" to "ValueObject::GetCompilerType()" many more renames that are similar. llvm-svn: 245905
2015-08-24 23:46:31 +00:00
i->second.GetName().AsCString(),
i->first->GetFileSpec().GetFilename().GetCString());
FindExternalVisibleDecls(context,
i->first,
i->second,
current_id);
}
}
else if (isa<TranslationUnitDecl>(context.m_decl_context))
{
Final bit of type system cleanup that abstracts declaration contexts into lldb_private::CompilerDeclContext and renames ClangType to CompilerType in many accessors and functions. Create a new "lldb_private::CompilerDeclContext" class that will replace all direct uses of "clang::DeclContext" when used in compiler agnostic code, yet still allow for conversion to clang::DeclContext subclasses by clang specific code. This completes the abstraction of type parsing by removing all "clang::" references from the SymbolFileDWARF. The new "lldb_private::CompilerDeclContext" class abstracts decl contexts found in compiler type systems so they can be used in internal API calls. The TypeSystem is required to support CompilerDeclContexts with new pure virtual functions that start with "DeclContext" in the member function names. Converted all code that used lldb_private::ClangNamespaceDecl over to use the new CompilerDeclContext class and removed the ClangNamespaceDecl.cpp and ClangNamespaceDecl.h files. Removed direct use of clang APIs from SBType and now use the abstract type systems to correctly explore types. Bulk renames for things that used to return a ClangASTType which is now CompilerType: "Type::GetClangFullType()" to "Type::GetFullCompilerType()" "Type::GetClangLayoutType()" to "Type::GetLayoutCompilerType()" "Type::GetClangForwardType()" to "Type::GetForwardCompilerType()" "Value::GetClangType()" to "Value::GetCompilerType()" "Value::SetClangType (const CompilerType &)" to "Value::SetCompilerType (const CompilerType &)" "ValueObject::GetClangType ()" to "ValueObject::GetCompilerType()" many more renames that are similar. llvm-svn: 245905
2015-08-24 23:46:31 +00:00
CompilerDeclContext namespace_decl;
if (log)
log->Printf(" CEDM::FEVD[%u] Searching the root namespace", current_id);
FindExternalVisibleDecls(context,
lldb::ModuleSP(),
namespace_decl,
current_id);
}
if (!context.m_found.variable)
ClangASTSource::FindExternalVisibleDecls(context);
}
void
ClangExpressionDeclMap::FindExternalVisibleDecls (NameSearchContext &context,
lldb::ModuleSP module_sp,
Final bit of type system cleanup that abstracts declaration contexts into lldb_private::CompilerDeclContext and renames ClangType to CompilerType in many accessors and functions. Create a new "lldb_private::CompilerDeclContext" class that will replace all direct uses of "clang::DeclContext" when used in compiler agnostic code, yet still allow for conversion to clang::DeclContext subclasses by clang specific code. This completes the abstraction of type parsing by removing all "clang::" references from the SymbolFileDWARF. The new "lldb_private::CompilerDeclContext" class abstracts decl contexts found in compiler type systems so they can be used in internal API calls. The TypeSystem is required to support CompilerDeclContexts with new pure virtual functions that start with "DeclContext" in the member function names. Converted all code that used lldb_private::ClangNamespaceDecl over to use the new CompilerDeclContext class and removed the ClangNamespaceDecl.cpp and ClangNamespaceDecl.h files. Removed direct use of clang APIs from SBType and now use the abstract type systems to correctly explore types. Bulk renames for things that used to return a ClangASTType which is now CompilerType: "Type::GetClangFullType()" to "Type::GetFullCompilerType()" "Type::GetClangLayoutType()" to "Type::GetLayoutCompilerType()" "Type::GetClangForwardType()" to "Type::GetForwardCompilerType()" "Value::GetClangType()" to "Value::GetCompilerType()" "Value::SetClangType (const CompilerType &)" to "Value::SetCompilerType (const CompilerType &)" "ValueObject::GetClangType ()" to "ValueObject::GetCompilerType()" many more renames that are similar. llvm-svn: 245905
2015-08-24 23:46:31 +00:00
CompilerDeclContext &namespace_decl,
unsigned int current_id)
{
assert (m_ast_context);
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
SymbolContextList sc_list;
const ConstString name(context.m_decl_name.getAsString().c_str());
const char *name_unique_cstr = name.GetCString();
if (name_unique_cstr == NULL)
return;
static ConstString id_name("id");
static ConstString Class_name("Class");
if (name == id_name || name == Class_name)
return;
// Only look for functions by name out in our symbols if the function
// doesn't start with our phony prefix of '$'
Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr();
SymbolContext sym_ctx;
if (frame != nullptr)
sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction|lldb::eSymbolContextBlock);
if (name_unique_cstr[0] == '$' && !namespace_decl)
{
static ConstString g_lldb_class_name ("$__lldb_class");
if (name == g_lldb_class_name)
{
// Clang is looking for the type of "this"
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 02:13:07 +00:00
return;
Final bit of type system cleanup that abstracts declaration contexts into lldb_private::CompilerDeclContext and renames ClangType to CompilerType in many accessors and functions. Create a new "lldb_private::CompilerDeclContext" class that will replace all direct uses of "clang::DeclContext" when used in compiler agnostic code, yet still allow for conversion to clang::DeclContext subclasses by clang specific code. This completes the abstraction of type parsing by removing all "clang::" references from the SymbolFileDWARF. The new "lldb_private::CompilerDeclContext" class abstracts decl contexts found in compiler type systems so they can be used in internal API calls. The TypeSystem is required to support CompilerDeclContexts with new pure virtual functions that start with "DeclContext" in the member function names. Converted all code that used lldb_private::ClangNamespaceDecl over to use the new CompilerDeclContext class and removed the ClangNamespaceDecl.cpp and ClangNamespaceDecl.h files. Removed direct use of clang APIs from SBType and now use the abstract type systems to correctly explore types. Bulk renames for things that used to return a ClangASTType which is now CompilerType: "Type::GetClangFullType()" to "Type::GetFullCompilerType()" "Type::GetClangLayoutType()" to "Type::GetLayoutCompilerType()" "Type::GetClangForwardType()" to "Type::GetForwardCompilerType()" "Value::GetClangType()" to "Value::GetCompilerType()" "Value::SetClangType (const CompilerType &)" to "Value::SetCompilerType (const CompilerType &)" "ValueObject::GetClangType ()" to "ValueObject::GetCompilerType()" many more renames that are similar. llvm-svn: 245905
2015-08-24 23:46:31 +00:00
// Find the block that defines the function represented by "sym_ctx"
Block *function_block = sym_ctx.GetFunctionBlock();
if (!function_block)
return;
Final bit of type system cleanup that abstracts declaration contexts into lldb_private::CompilerDeclContext and renames ClangType to CompilerType in many accessors and functions. Create a new "lldb_private::CompilerDeclContext" class that will replace all direct uses of "clang::DeclContext" when used in compiler agnostic code, yet still allow for conversion to clang::DeclContext subclasses by clang specific code. This completes the abstraction of type parsing by removing all "clang::" references from the SymbolFileDWARF. The new "lldb_private::CompilerDeclContext" class abstracts decl contexts found in compiler type systems so they can be used in internal API calls. The TypeSystem is required to support CompilerDeclContexts with new pure virtual functions that start with "DeclContext" in the member function names. Converted all code that used lldb_private::ClangNamespaceDecl over to use the new CompilerDeclContext class and removed the ClangNamespaceDecl.cpp and ClangNamespaceDecl.h files. Removed direct use of clang APIs from SBType and now use the abstract type systems to correctly explore types. Bulk renames for things that used to return a ClangASTType which is now CompilerType: "Type::GetClangFullType()" to "Type::GetFullCompilerType()" "Type::GetClangLayoutType()" to "Type::GetLayoutCompilerType()" "Type::GetClangForwardType()" to "Type::GetForwardCompilerType()" "Value::GetClangType()" to "Value::GetCompilerType()" "Value::SetClangType (const CompilerType &)" to "Value::SetCompilerType (const CompilerType &)" "ValueObject::GetClangType ()" to "ValueObject::GetCompilerType()" many more renames that are similar. llvm-svn: 245905
2015-08-24 23:46:31 +00:00
CompilerDeclContext function_decl_ctx = function_block->GetDeclContext();
Final bit of type system cleanup that abstracts declaration contexts into lldb_private::CompilerDeclContext and renames ClangType to CompilerType in many accessors and functions. Create a new "lldb_private::CompilerDeclContext" class that will replace all direct uses of "clang::DeclContext" when used in compiler agnostic code, yet still allow for conversion to clang::DeclContext subclasses by clang specific code. This completes the abstraction of type parsing by removing all "clang::" references from the SymbolFileDWARF. The new "lldb_private::CompilerDeclContext" class abstracts decl contexts found in compiler type systems so they can be used in internal API calls. The TypeSystem is required to support CompilerDeclContexts with new pure virtual functions that start with "DeclContext" in the member function names. Converted all code that used lldb_private::ClangNamespaceDecl over to use the new CompilerDeclContext class and removed the ClangNamespaceDecl.cpp and ClangNamespaceDecl.h files. Removed direct use of clang APIs from SBType and now use the abstract type systems to correctly explore types. Bulk renames for things that used to return a ClangASTType which is now CompilerType: "Type::GetClangFullType()" to "Type::GetFullCompilerType()" "Type::GetClangLayoutType()" to "Type::GetLayoutCompilerType()" "Type::GetClangForwardType()" to "Type::GetForwardCompilerType()" "Value::GetClangType()" to "Value::GetCompilerType()" "Value::SetClangType (const CompilerType &)" to "Value::SetCompilerType (const CompilerType &)" "ValueObject::GetClangType ()" to "ValueObject::GetCompilerType()" many more renames that are similar. llvm-svn: 245905
2015-08-24 23:46:31 +00:00
if (!function_decl_ctx)
return;
Final bit of type system cleanup that abstracts declaration contexts into lldb_private::CompilerDeclContext and renames ClangType to CompilerType in many accessors and functions. Create a new "lldb_private::CompilerDeclContext" class that will replace all direct uses of "clang::DeclContext" when used in compiler agnostic code, yet still allow for conversion to clang::DeclContext subclasses by clang specific code. This completes the abstraction of type parsing by removing all "clang::" references from the SymbolFileDWARF. The new "lldb_private::CompilerDeclContext" class abstracts decl contexts found in compiler type systems so they can be used in internal API calls. The TypeSystem is required to support CompilerDeclContexts with new pure virtual functions that start with "DeclContext" in the member function names. Converted all code that used lldb_private::ClangNamespaceDecl over to use the new CompilerDeclContext class and removed the ClangNamespaceDecl.cpp and ClangNamespaceDecl.h files. Removed direct use of clang APIs from SBType and now use the abstract type systems to correctly explore types. Bulk renames for things that used to return a ClangASTType which is now CompilerType: "Type::GetClangFullType()" to "Type::GetFullCompilerType()" "Type::GetClangLayoutType()" to "Type::GetLayoutCompilerType()" "Type::GetClangForwardType()" to "Type::GetForwardCompilerType()" "Value::GetClangType()" to "Value::GetCompilerType()" "Value::SetClangType (const CompilerType &)" to "Value::SetCompilerType (const CompilerType &)" "ValueObject::GetClangType ()" to "ValueObject::GetCompilerType()" many more renames that are similar. llvm-svn: 245905
2015-08-24 23:46:31 +00:00
clang::CXXMethodDecl *method_decl = ClangASTContext::DeclContextGetAsCXXMethodDecl(function_decl_ctx);
if (method_decl)
{
clang::CXXRecordDecl *class_decl = method_decl->getParent();
QualType class_qual_type(class_decl->getTypeForDecl(), 0);
TypeFromUser class_user_type (class_qual_type.getAsOpaquePtr(),
ClangASTContext::GetASTContext(&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());
}
AddThisType(context, class_user_type, current_id);
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(),
ClangASTContext::GetASTContext(&method_decl->getASTContext()));
m_struct_vars->m_object_pointer_type = self_user_type;
}
}
else
{
// This branch will get hit if we are executing code in the context of a function that
// claims to have an object pointer (through DW_AT_object_pointer?) but is not formally a
// method of the class. In that case, just look up the "this" variable in 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.
VariableList *vars = frame->GetVariableList(false);
lldb::VariableSP this_var = vars->FindVariable(ConstString("this"));
if (this_var &&
this_var->IsInScope(frame) &&
this_var->LocationIsValidForFrame (frame))
{
Type *this_type = this_var->GetType();
if (!this_type)
return;
TypeFromUser pointee_type = this_type->GetForwardCompilerType ().GetPointeeType();
if (pointee_type.IsValid())
{
if (log)
{
ASTDumper ast_dumper(pointee_type);
log->Printf(" FEVD[%u] Adding type for $__lldb_class: %s", current_id, ast_dumper.GetCString());
}
AddThisType(context, pointee_type, current_id);
Final bit of type system cleanup that abstracts declaration contexts into lldb_private::CompilerDeclContext and renames ClangType to CompilerType in many accessors and functions. Create a new "lldb_private::CompilerDeclContext" class that will replace all direct uses of "clang::DeclContext" when used in compiler agnostic code, yet still allow for conversion to clang::DeclContext subclasses by clang specific code. This completes the abstraction of type parsing by removing all "clang::" references from the SymbolFileDWARF. The new "lldb_private::CompilerDeclContext" class abstracts decl contexts found in compiler type systems so they can be used in internal API calls. The TypeSystem is required to support CompilerDeclContexts with new pure virtual functions that start with "DeclContext" in the member function names. Converted all code that used lldb_private::ClangNamespaceDecl over to use the new CompilerDeclContext class and removed the ClangNamespaceDecl.cpp and ClangNamespaceDecl.h files. Removed direct use of clang APIs from SBType and now use the abstract type systems to correctly explore types. Bulk renames for things that used to return a ClangASTType which is now CompilerType: "Type::GetClangFullType()" to "Type::GetFullCompilerType()" "Type::GetClangLayoutType()" to "Type::GetLayoutCompilerType()" "Type::GetClangForwardType()" to "Type::GetForwardCompilerType()" "Value::GetClangType()" to "Value::GetCompilerType()" "Value::SetClangType (const CompilerType &)" to "Value::SetCompilerType (const CompilerType &)" "ValueObject::GetClangType ()" to "ValueObject::GetCompilerType()" many more renames that are similar. llvm-svn: 245905
2015-08-24 23:46:31 +00:00
TypeFromUser this_user_type(this_type->GetFullCompilerType ());
m_struct_vars->m_object_pointer_type = this_user_type;
return;
}
}
}
return;
}
static ConstString g_lldb_objc_class_name ("$__lldb_objc_class");
if (name == g_lldb_objc_class_name)
{
// Clang is looking for the type of "*self"
if (!frame)
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 02:13:07 +00:00
return;
Final bit of type system cleanup that abstracts declaration contexts into lldb_private::CompilerDeclContext and renames ClangType to CompilerType in many accessors and functions. Create a new "lldb_private::CompilerDeclContext" class that will replace all direct uses of "clang::DeclContext" when used in compiler agnostic code, yet still allow for conversion to clang::DeclContext subclasses by clang specific code. This completes the abstraction of type parsing by removing all "clang::" references from the SymbolFileDWARF. The new "lldb_private::CompilerDeclContext" class abstracts decl contexts found in compiler type systems so they can be used in internal API calls. The TypeSystem is required to support CompilerDeclContexts with new pure virtual functions that start with "DeclContext" in the member function names. Converted all code that used lldb_private::ClangNamespaceDecl over to use the new CompilerDeclContext class and removed the ClangNamespaceDecl.cpp and ClangNamespaceDecl.h files. Removed direct use of clang APIs from SBType and now use the abstract type systems to correctly explore types. Bulk renames for things that used to return a ClangASTType which is now CompilerType: "Type::GetClangFullType()" to "Type::GetFullCompilerType()" "Type::GetClangLayoutType()" to "Type::GetLayoutCompilerType()" "Type::GetClangForwardType()" to "Type::GetForwardCompilerType()" "Value::GetClangType()" to "Value::GetCompilerType()" "Value::SetClangType (const CompilerType &)" to "Value::SetCompilerType (const CompilerType &)" "ValueObject::GetClangType ()" to "ValueObject::GetCompilerType()" many more renames that are similar. llvm-svn: 245905
2015-08-24 23:46:31 +00:00
SymbolContext sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction|lldb::eSymbolContextBlock);
Final bit of type system cleanup that abstracts declaration contexts into lldb_private::CompilerDeclContext and renames ClangType to CompilerType in many accessors and functions. Create a new "lldb_private::CompilerDeclContext" class that will replace all direct uses of "clang::DeclContext" when used in compiler agnostic code, yet still allow for conversion to clang::DeclContext subclasses by clang specific code. This completes the abstraction of type parsing by removing all "clang::" references from the SymbolFileDWARF. The new "lldb_private::CompilerDeclContext" class abstracts decl contexts found in compiler type systems so they can be used in internal API calls. The TypeSystem is required to support CompilerDeclContexts with new pure virtual functions that start with "DeclContext" in the member function names. Converted all code that used lldb_private::ClangNamespaceDecl over to use the new CompilerDeclContext class and removed the ClangNamespaceDecl.cpp and ClangNamespaceDecl.h files. Removed direct use of clang APIs from SBType and now use the abstract type systems to correctly explore types. Bulk renames for things that used to return a ClangASTType which is now CompilerType: "Type::GetClangFullType()" to "Type::GetFullCompilerType()" "Type::GetClangLayoutType()" to "Type::GetLayoutCompilerType()" "Type::GetClangForwardType()" to "Type::GetForwardCompilerType()" "Value::GetClangType()" to "Value::GetCompilerType()" "Value::SetClangType (const CompilerType &)" to "Value::SetCompilerType (const CompilerType &)" "ValueObject::GetClangType ()" to "ValueObject::GetCompilerType()" many more renames that are similar. llvm-svn: 245905
2015-08-24 23:46:31 +00:00
// Find the block that defines the function represented by "sym_ctx"
Block *function_block = sym_ctx.GetFunctionBlock();
if (!function_block)
return;
Final bit of type system cleanup that abstracts declaration contexts into lldb_private::CompilerDeclContext and renames ClangType to CompilerType in many accessors and functions. Create a new "lldb_private::CompilerDeclContext" class that will replace all direct uses of "clang::DeclContext" when used in compiler agnostic code, yet still allow for conversion to clang::DeclContext subclasses by clang specific code. This completes the abstraction of type parsing by removing all "clang::" references from the SymbolFileDWARF. The new "lldb_private::CompilerDeclContext" class abstracts decl contexts found in compiler type systems so they can be used in internal API calls. The TypeSystem is required to support CompilerDeclContexts with new pure virtual functions that start with "DeclContext" in the member function names. Converted all code that used lldb_private::ClangNamespaceDecl over to use the new CompilerDeclContext class and removed the ClangNamespaceDecl.cpp and ClangNamespaceDecl.h files. Removed direct use of clang APIs from SBType and now use the abstract type systems to correctly explore types. Bulk renames for things that used to return a ClangASTType which is now CompilerType: "Type::GetClangFullType()" to "Type::GetFullCompilerType()" "Type::GetClangLayoutType()" to "Type::GetLayoutCompilerType()" "Type::GetClangForwardType()" to "Type::GetForwardCompilerType()" "Value::GetClangType()" to "Value::GetCompilerType()" "Value::SetClangType (const CompilerType &)" to "Value::SetCompilerType (const CompilerType &)" "ValueObject::GetClangType ()" to "ValueObject::GetCompilerType()" many more renames that are similar. llvm-svn: 245905
2015-08-24 23:46:31 +00:00
CompilerDeclContext function_decl_ctx = function_block->GetDeclContext();
Final bit of type system cleanup that abstracts declaration contexts into lldb_private::CompilerDeclContext and renames ClangType to CompilerType in many accessors and functions. Create a new "lldb_private::CompilerDeclContext" class that will replace all direct uses of "clang::DeclContext" when used in compiler agnostic code, yet still allow for conversion to clang::DeclContext subclasses by clang specific code. This completes the abstraction of type parsing by removing all "clang::" references from the SymbolFileDWARF. The new "lldb_private::CompilerDeclContext" class abstracts decl contexts found in compiler type systems so they can be used in internal API calls. The TypeSystem is required to support CompilerDeclContexts with new pure virtual functions that start with "DeclContext" in the member function names. Converted all code that used lldb_private::ClangNamespaceDecl over to use the new CompilerDeclContext class and removed the ClangNamespaceDecl.cpp and ClangNamespaceDecl.h files. Removed direct use of clang APIs from SBType and now use the abstract type systems to correctly explore types. Bulk renames for things that used to return a ClangASTType which is now CompilerType: "Type::GetClangFullType()" to "Type::GetFullCompilerType()" "Type::GetClangLayoutType()" to "Type::GetLayoutCompilerType()" "Type::GetClangForwardType()" to "Type::GetForwardCompilerType()" "Value::GetClangType()" to "Value::GetCompilerType()" "Value::SetClangType (const CompilerType &)" to "Value::SetCompilerType (const CompilerType &)" "ValueObject::GetClangType ()" to "ValueObject::GetCompilerType()" many more renames that are similar. llvm-svn: 245905
2015-08-24 23:46:31 +00:00
if (!function_decl_ctx)
return;
Final bit of type system cleanup that abstracts declaration contexts into lldb_private::CompilerDeclContext and renames ClangType to CompilerType in many accessors and functions. Create a new "lldb_private::CompilerDeclContext" class that will replace all direct uses of "clang::DeclContext" when used in compiler agnostic code, yet still allow for conversion to clang::DeclContext subclasses by clang specific code. This completes the abstraction of type parsing by removing all "clang::" references from the SymbolFileDWARF. The new "lldb_private::CompilerDeclContext" class abstracts decl contexts found in compiler type systems so they can be used in internal API calls. The TypeSystem is required to support CompilerDeclContexts with new pure virtual functions that start with "DeclContext" in the member function names. Converted all code that used lldb_private::ClangNamespaceDecl over to use the new CompilerDeclContext class and removed the ClangNamespaceDecl.cpp and ClangNamespaceDecl.h files. Removed direct use of clang APIs from SBType and now use the abstract type systems to correctly explore types. Bulk renames for things that used to return a ClangASTType which is now CompilerType: "Type::GetClangFullType()" to "Type::GetFullCompilerType()" "Type::GetClangLayoutType()" to "Type::GetLayoutCompilerType()" "Type::GetClangForwardType()" to "Type::GetForwardCompilerType()" "Value::GetClangType()" to "Value::GetCompilerType()" "Value::SetClangType (const CompilerType &)" to "Value::SetCompilerType (const CompilerType &)" "ValueObject::GetClangType ()" to "ValueObject::GetCompilerType()" many more renames that are similar. llvm-svn: 245905
2015-08-24 23:46:31 +00:00
clang::ObjCMethodDecl *method_decl = ClangASTContext::DeclContextGetAsObjCMethodDecl(function_decl_ctx);
if (method_decl)
{
ObjCInterfaceDecl* self_interface = method_decl->getClassInterface();
if (!self_interface)
return;
const clang::Type *interface_type = self_interface->getTypeForDecl();
if (!interface_type)
return; // This is unlikely, but we have seen crashes where this occurred
TypeFromUser class_user_type(QualType(interface_type, 0).getAsOpaquePtr(),
ClangASTContext::GetASTContext(&method_decl->getASTContext()));
if (log)
{
ASTDumper ast_dumper(interface_type);
log->Printf(" FEVD[%u] Adding type for $__lldb_objc_class: %s", current_id, ast_dumper.GetCString());
}
AddOneType(context, class_user_type, current_id);
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(),
ClangASTContext::GetASTContext(&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(),
ClangASTContext::GetASTContext(&method_decl->getASTContext()));
m_struct_vars->m_object_pointer_type = self_user_type;
}
return;
}
else
{
// This branch will get hit if we are executing code in the context of a function that
// claims to have an object pointer (through DW_AT_object_pointer?) but is not formally a
// method of the class. In that case, just look up the "self" variable in the current
// scope and use its type.
VariableList *vars = frame->GetVariableList(false);
lldb::VariableSP self_var = vars->FindVariable(ConstString("self"));
if (self_var &&
self_var->IsInScope(frame) &&
self_var->LocationIsValidForFrame (frame))
{
Type *self_type = self_var->GetType();
if (!self_type)
return;
Final bit of type system cleanup that abstracts declaration contexts into lldb_private::CompilerDeclContext and renames ClangType to CompilerType in many accessors and functions. Create a new "lldb_private::CompilerDeclContext" class that will replace all direct uses of "clang::DeclContext" when used in compiler agnostic code, yet still allow for conversion to clang::DeclContext subclasses by clang specific code. This completes the abstraction of type parsing by removing all "clang::" references from the SymbolFileDWARF. The new "lldb_private::CompilerDeclContext" class abstracts decl contexts found in compiler type systems so they can be used in internal API calls. The TypeSystem is required to support CompilerDeclContexts with new pure virtual functions that start with "DeclContext" in the member function names. Converted all code that used lldb_private::ClangNamespaceDecl over to use the new CompilerDeclContext class and removed the ClangNamespaceDecl.cpp and ClangNamespaceDecl.h files. Removed direct use of clang APIs from SBType and now use the abstract type systems to correctly explore types. Bulk renames for things that used to return a ClangASTType which is now CompilerType: "Type::GetClangFullType()" to "Type::GetFullCompilerType()" "Type::GetClangLayoutType()" to "Type::GetLayoutCompilerType()" "Type::GetClangForwardType()" to "Type::GetForwardCompilerType()" "Value::GetClangType()" to "Value::GetCompilerType()" "Value::SetClangType (const CompilerType &)" to "Value::SetCompilerType (const CompilerType &)" "ValueObject::GetClangType ()" to "ValueObject::GetCompilerType()" many more renames that are similar. llvm-svn: 245905
2015-08-24 23:46:31 +00:00
CompilerType self_clang_type = self_type->GetFullCompilerType ();
if (ClangASTContext::IsObjCClassType(self_clang_type))
{
return;
}
else if (ClangASTContext::IsObjCObjectPointerType(self_clang_type))
{
self_clang_type = self_clang_type.GetPointeeType();
if (!self_clang_type)
return;
if (log)
{
Final bit of type system cleanup that abstracts declaration contexts into lldb_private::CompilerDeclContext and renames ClangType to CompilerType in many accessors and functions. Create a new "lldb_private::CompilerDeclContext" class that will replace all direct uses of "clang::DeclContext" when used in compiler agnostic code, yet still allow for conversion to clang::DeclContext subclasses by clang specific code. This completes the abstraction of type parsing by removing all "clang::" references from the SymbolFileDWARF. The new "lldb_private::CompilerDeclContext" class abstracts decl contexts found in compiler type systems so they can be used in internal API calls. The TypeSystem is required to support CompilerDeclContexts with new pure virtual functions that start with "DeclContext" in the member function names. Converted all code that used lldb_private::ClangNamespaceDecl over to use the new CompilerDeclContext class and removed the ClangNamespaceDecl.cpp and ClangNamespaceDecl.h files. Removed direct use of clang APIs from SBType and now use the abstract type systems to correctly explore types. Bulk renames for things that used to return a ClangASTType which is now CompilerType: "Type::GetClangFullType()" to "Type::GetFullCompilerType()" "Type::GetClangLayoutType()" to "Type::GetLayoutCompilerType()" "Type::GetClangForwardType()" to "Type::GetForwardCompilerType()" "Value::GetClangType()" to "Value::GetCompilerType()" "Value::SetClangType (const CompilerType &)" to "Value::SetCompilerType (const CompilerType &)" "ValueObject::GetClangType ()" to "ValueObject::GetCompilerType()" many more renames that are similar. llvm-svn: 245905
2015-08-24 23:46:31 +00:00
ASTDumper ast_dumper(self_type->GetFullCompilerType ());
log->Printf(" FEVD[%u] Adding type for $__lldb_objc_class: %s", current_id, ast_dumper.GetCString());
}
TypeFromUser class_user_type (self_clang_type);
AddOneType(context, class_user_type, current_id);
Final bit of type system cleanup that abstracts declaration contexts into lldb_private::CompilerDeclContext and renames ClangType to CompilerType in many accessors and functions. Create a new "lldb_private::CompilerDeclContext" class that will replace all direct uses of "clang::DeclContext" when used in compiler agnostic code, yet still allow for conversion to clang::DeclContext subclasses by clang specific code. This completes the abstraction of type parsing by removing all "clang::" references from the SymbolFileDWARF. The new "lldb_private::CompilerDeclContext" class abstracts decl contexts found in compiler type systems so they can be used in internal API calls. The TypeSystem is required to support CompilerDeclContexts with new pure virtual functions that start with "DeclContext" in the member function names. Converted all code that used lldb_private::ClangNamespaceDecl over to use the new CompilerDeclContext class and removed the ClangNamespaceDecl.cpp and ClangNamespaceDecl.h files. Removed direct use of clang APIs from SBType and now use the abstract type systems to correctly explore types. Bulk renames for things that used to return a ClangASTType which is now CompilerType: "Type::GetClangFullType()" to "Type::GetFullCompilerType()" "Type::GetClangLayoutType()" to "Type::GetLayoutCompilerType()" "Type::GetClangForwardType()" to "Type::GetForwardCompilerType()" "Value::GetClangType()" to "Value::GetCompilerType()" "Value::SetClangType (const CompilerType &)" to "Value::SetCompilerType (const CompilerType &)" "ValueObject::GetClangType ()" to "ValueObject::GetCompilerType()" many more renames that are similar. llvm-svn: 245905
2015-08-24 23:46:31 +00:00
TypeFromUser self_user_type(self_type->GetFullCompilerType ());
m_struct_vars->m_object_pointer_type = self_user_type;
return;
}
}
}
return;
}
// any other $__lldb names should be weeded out now
if (!::strncmp(name_unique_cstr, "$__lldb", sizeof("$__lldb") - 1))
return;
do
{
if (!target)
break;
ClangASTContext *scratch_clang_ast_context = target->GetScratchClangASTContext();
if (!scratch_clang_ast_context)
break;
ASTContext *scratch_ast_context = scratch_clang_ast_context->getASTContext();
if (!scratch_ast_context)
break;
TypeDecl *ptype_type_decl = m_parser_vars->m_persistent_vars->GetPersistentType(name);
if (!ptype_type_decl)
break;
Decl *parser_ptype_decl = m_ast_importer_sp->CopyDecl(m_ast_context, scratch_ast_context, ptype_type_decl);
if (!parser_ptype_decl)
break;
TypeDecl *parser_ptype_type_decl = dyn_cast<TypeDecl>(parser_ptype_decl);
if (!parser_ptype_type_decl)
break;
if (log)
log->Printf(" CEDM::FEVD[%u] Found persistent type %s", current_id, name.GetCString());
context.AddNamedDecl(parser_ptype_type_decl);
} while (0);
ExpressionVariableSP pvar_sp(m_parser_vars->m_persistent_vars->GetVariable(name));
Modified LLDB expressions to not have to JIT and run code just to see variable values or persistent expression variables. Now if an expression consists of a value that is a child of a variable, or of a persistent variable only, we will create a value object for it and make a ValueObjectConstResult from it to freeze the value (for program variables only, not persistent variables) and avoid running JITed code. For everything else we still parse up and JIT code and run it in the inferior. There was also a lot of clean up in the expression code. I made the ClangExpressionVariables be stored in collections of shared pointers instead of in collections of objects. This will help stop a lot of copy constructors on these large objects and also cleans up the code considerably. The persistent clang expression variables were moved over to the Target to ensure they persist across process executions. Added the ability for lldb_private::Target objects to evaluate expressions. We want to evaluate expressions at the target level in case we aren't running yet, or we have just completed running. We still want to be able to access the persistent expression variables between runs, and also evaluate constant expressions. Added extra logging to the dynamic loader plug-in for MacOSX. ModuleList objects can now dump their contents with the UUID, arch and full paths being logged with appropriate prefix values. Thread hardened the Communication class a bit by making the connection auto_ptr member into a shared pointer member and then making a local copy of the shared pointer in each method that uses it to make sure another thread can't nuke the connection object while it is being used by another thread. Added a new file to the lldb/test/load_unload test that causes the test a.out file to link to the libd.dylib file all the time. This will allow us to test using the DYLD_LIBRARY_PATH environment variable after moving libd.dylib somewhere else. llvm-svn: 121745
2010-12-14 02:59:59 +00:00
if (pvar_sp)
{
AddOneVariable(context, pvar_sp, current_id);
return;
}
const char *reg_name(&name.GetCString()[1]);
if (m_parser_vars->m_exe_ctx.GetRegisterContext())
{
const RegisterInfo *reg_info(m_parser_vars->m_exe_ctx.GetRegisterContext()->GetRegisterInfoByName(reg_name));
if (reg_info)
{
if (log)
log->Printf(" CEDM::FEVD[%u] Found register %s", current_id, reg_info->name);
AddOneRegister(context, reg_info, current_id);
}
}
}
else
{
ValueObjectSP valobj;
VariableSP var;
if (frame && !namespace_decl)
{
CompilerDeclContext compiler_decl_context = sym_ctx.block != nullptr ? sym_ctx.block->GetDeclContext() : CompilerDeclContext();
if (compiler_decl_context)
{
// Make sure that the variables are parsed so that we have the declarations
VariableListSP vars = frame->GetInScopeVariableList(true);
for (size_t i = 0; i < vars->GetSize(); i++)
vars->GetVariableAtIndex(i)->GetDecl();
// Search for declarations matching the name
std::vector<CompilerDecl> found_decls = compiler_decl_context.FindDeclByName(name);
bool variable_found = false;
for (CompilerDecl decl : found_decls)
{
var = decl.GetAsVariable();
if (var)
{
variable_found = true;
valobj = ValueObjectVariable::Create(frame, var);
AddOneVariable(context, var, valobj, current_id);
context.m_found.variable = true;
}
}
if (variable_found)
return;
}
}
if (target)
{
var = FindGlobalVariable (*target,
module_sp,
name,
&namespace_decl,
NULL);
if (var)
{
valobj = ValueObjectVariable::Create(target, var);
AddOneVariable(context, var, valobj, current_id);
context.m_found.variable = true;
return;
}
}
std::vector<clang::NamedDecl *> decls_from_modules;
if (target)
{
if (ClangModulesDeclVendor *decl_vendor = target->GetClangModulesDeclVendor())
{
decl_vendor->FindDecls(name, false, UINT32_MAX, decls_from_modules);
}
}
if (!context.m_found.variable)
{
const bool include_inlines = false;
const bool append = false;
if (namespace_decl && module_sp)
{
const bool include_symbols = false;
module_sp->FindFunctions(name,
&namespace_decl,
eFunctionNameTypeBase,
include_symbols,
include_inlines,
append,
sc_list);
}
else if (target && !namespace_decl)
{
const bool include_symbols = true;
// TODO Fix FindFunctions so that it doesn't return
// instance methods for eFunctionNameTypeBase.
target->GetImages().FindFunctions(name,
eFunctionNameTypeFull,
include_symbols,
include_inlines,
append,
sc_list);
}
// If we found more than one function, see if we can use the
// frame's decl context to remove functions that are shadowed
// by other functions which match in type but are nearer in scope.
//
// AddOneFunction will not add a function whose type has already been
// added, so if there's another function in the list with a matching
// type, check to see if their decl context is a parent of the current
// frame's or was imported via a and using statement, and pick the
// best match according to lookup rules.
if (sc_list.GetSize() > 1)
{
// Collect some info about our frame's context.
StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr();
SymbolContext frame_sym_ctx;
if (frame != nullptr)
frame_sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction|lldb::eSymbolContextBlock);
CompilerDeclContext frame_decl_context = frame_sym_ctx.block != nullptr ? frame_sym_ctx.block->GetDeclContext() : CompilerDeclContext();
// We can't do this without a compiler decl context for our frame.
if (frame_decl_context)
{
clang::DeclContext *frame_decl_ctx = (clang::DeclContext *)frame_decl_context.GetOpaqueDeclContext();
ClangASTContext *ast = llvm::dyn_cast_or_null<ClangASTContext>(frame_decl_context.GetTypeSystem());
// Structure to hold the info needed when comparing function
// declarations.
struct FuncDeclInfo
{
ConstString m_name;
CompilerType m_copied_type;
uint32_t m_decl_lvl;
SymbolContext m_sym_ctx;
};
// First, symplify things by looping through the symbol contexts
// to remove unwanted functions and separate out the functions we
// want to compare and prune into a separate list.
// Cache the info needed about the function declarations in a
// vector for efficiency.
SymbolContextList sc_sym_list;
uint32_t num_indices = sc_list.GetSize();
std::vector<FuncDeclInfo> fdi_cache;
fdi_cache.reserve(num_indices);
for (uint32_t index = 0; index < num_indices; ++index)
{
FuncDeclInfo fdi;
SymbolContext sym_ctx;
sc_list.GetContextAtIndex(index, sym_ctx);
// We don't know enough about symbols to compare them,
// but we should keep them in the list.
Function *function = sym_ctx.function;
if (!function)
{
sc_sym_list.Append(sym_ctx);
continue;
}
// Filter out functions without declaration contexts, as well as
// class/instance methods, since they'll be skipped in the
// code that follows anyway.
CompilerDeclContext func_decl_context = function->GetDeclContext();
if (!func_decl_context || func_decl_context.IsClassMethod(nullptr, nullptr, nullptr))
continue;
// We can only prune functions for which we can copy the type.
CompilerType func_clang_type = function->GetType()->GetFullCompilerType();
CompilerType copied_func_type = GuardedCopyType(func_clang_type);
if (!copied_func_type)
{
sc_sym_list.Append(sym_ctx);
continue;
}
fdi.m_sym_ctx = sym_ctx;
fdi.m_name = function->GetName();
fdi.m_copied_type = copied_func_type;
fdi.m_decl_lvl = LLDB_INVALID_DECL_LEVEL;
if (fdi.m_copied_type && func_decl_context)
{
// Call CountDeclLevels to get the number of parent scopes we
// have to look through before we find the function declaration.
// When comparing functions of the same type, the one with a
// lower count will be closer to us in the lookup scope and
// shadows the other.
clang::DeclContext *func_decl_ctx = (clang::DeclContext *)func_decl_context.GetOpaqueDeclContext();
fdi.m_decl_lvl = ast->CountDeclLevels(frame_decl_ctx,
func_decl_ctx,
&fdi.m_name,
&fdi.m_copied_type);
}
fdi_cache.emplace_back(fdi);
}
// Loop through the functions in our cache looking for matching types,
// then compare their scope levels to see which is closer.
std::multimap<CompilerType, const FuncDeclInfo*> matches;
for (const FuncDeclInfo &fdi : fdi_cache)
{
const CompilerType t = fdi.m_copied_type;
auto q = matches.find(t);
if (q != matches.end())
{
if (q->second->m_decl_lvl > fdi.m_decl_lvl)
// This function is closer; remove the old set.
matches.erase(t);
else if (q->second->m_decl_lvl < fdi.m_decl_lvl)
// The functions in our set are closer - skip this one.
continue;
}
matches.insert(std::make_pair(t, &fdi));
}
// Loop through our matches and add their symbol contexts to our list.
SymbolContextList sc_func_list;
for (const auto &q : matches)
sc_func_list.Append(q.second->m_sym_ctx);
// Rejoin the lists with the functions in front.
sc_list = sc_func_list;
sc_list.Append(sc_sym_list);
}
}
if (sc_list.GetSize())
{
Symbol *extern_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)
{
Final bit of type system cleanup that abstracts declaration contexts into lldb_private::CompilerDeclContext and renames ClangType to CompilerType in many accessors and functions. Create a new "lldb_private::CompilerDeclContext" class that will replace all direct uses of "clang::DeclContext" when used in compiler agnostic code, yet still allow for conversion to clang::DeclContext subclasses by clang specific code. This completes the abstraction of type parsing by removing all "clang::" references from the SymbolFileDWARF. The new "lldb_private::CompilerDeclContext" class abstracts decl contexts found in compiler type systems so they can be used in internal API calls. The TypeSystem is required to support CompilerDeclContexts with new pure virtual functions that start with "DeclContext" in the member function names. Converted all code that used lldb_private::ClangNamespaceDecl over to use the new CompilerDeclContext class and removed the ClangNamespaceDecl.cpp and ClangNamespaceDecl.h files. Removed direct use of clang APIs from SBType and now use the abstract type systems to correctly explore types. Bulk renames for things that used to return a ClangASTType which is now CompilerType: "Type::GetClangFullType()" to "Type::GetFullCompilerType()" "Type::GetClangLayoutType()" to "Type::GetLayoutCompilerType()" "Type::GetClangForwardType()" to "Type::GetForwardCompilerType()" "Value::GetClangType()" to "Value::GetCompilerType()" "Value::SetClangType (const CompilerType &)" to "Value::SetCompilerType (const CompilerType &)" "ValueObject::GetClangType ()" to "ValueObject::GetCompilerType()" many more renames that are similar. llvm-svn: 245905
2015-08-24 23:46:31 +00:00
CompilerDeclContext decl_ctx = sym_ctx.function->GetDeclContext();
if (!decl_ctx)
continue;
// Filter out class/instance methods.
Final bit of type system cleanup that abstracts declaration contexts into lldb_private::CompilerDeclContext and renames ClangType to CompilerType in many accessors and functions. Create a new "lldb_private::CompilerDeclContext" class that will replace all direct uses of "clang::DeclContext" when used in compiler agnostic code, yet still allow for conversion to clang::DeclContext subclasses by clang specific code. This completes the abstraction of type parsing by removing all "clang::" references from the SymbolFileDWARF. The new "lldb_private::CompilerDeclContext" class abstracts decl contexts found in compiler type systems so they can be used in internal API calls. The TypeSystem is required to support CompilerDeclContexts with new pure virtual functions that start with "DeclContext" in the member function names. Converted all code that used lldb_private::ClangNamespaceDecl over to use the new CompilerDeclContext class and removed the ClangNamespaceDecl.cpp and ClangNamespaceDecl.h files. Removed direct use of clang APIs from SBType and now use the abstract type systems to correctly explore types. Bulk renames for things that used to return a ClangASTType which is now CompilerType: "Type::GetClangFullType()" to "Type::GetFullCompilerType()" "Type::GetClangLayoutType()" to "Type::GetLayoutCompilerType()" "Type::GetClangForwardType()" to "Type::GetForwardCompilerType()" "Value::GetClangType()" to "Value::GetCompilerType()" "Value::SetClangType (const CompilerType &)" to "Value::SetCompilerType (const CompilerType &)" "ValueObject::GetClangType ()" to "ValueObject::GetCompilerType()" many more renames that are similar. llvm-svn: 245905
2015-08-24 23:46:31 +00:00
if (decl_ctx.IsClassMethod(nullptr, nullptr, nullptr))
continue;
AddOneFunction(context, sym_ctx.function, NULL, current_id);
context.m_found.function_with_type_info = true;
context.m_found.function = true;
}
else if (sym_ctx.symbol)
{
if (sym_ctx.symbol->GetType() == eSymbolTypeReExported && target)
{
sym_ctx.symbol = sym_ctx.symbol->ResolveReExportedSymbol(*target);
if (sym_ctx.symbol == NULL)
continue;
}
if (sym_ctx.symbol->IsExternal())
extern_symbol = sym_ctx.symbol;
else
non_extern_symbol = sym_ctx.symbol;
}
}
if (!context.m_found.function_with_type_info)
{
for (clang::NamedDecl *decl : decls_from_modules)
{
if (llvm::isa<clang::FunctionDecl>(decl))
{
clang::NamedDecl *copied_decl = llvm::cast<FunctionDecl>(m_ast_importer_sp->CopyDecl(m_ast_context, &decl->getASTContext(), decl));
context.AddNamedDecl(copied_decl);
context.m_found.function_with_type_info = true;
}
}
}
if (!context.m_found.function_with_type_info)
{
if (extern_symbol)
{
AddOneFunction (context, NULL, extern_symbol, current_id);
context.m_found.function = true;
}
else if (non_extern_symbol)
{
AddOneFunction (context, NULL, non_extern_symbol, current_id);
context.m_found.function = true;
}
}
}
if (!context.m_found.function_with_type_info)
{
// Try the modules next.
do
{
if (ClangModulesDeclVendor *modules_decl_vendor = m_target->GetClangModulesDeclVendor())
{
bool append = false;
uint32_t max_matches = 1;
std::vector <clang::NamedDecl *> decls;
if (!modules_decl_vendor->FindDecls(name,
append,
max_matches,
decls))
break;
clang::NamedDecl *const decl_from_modules = decls[0];
if (llvm::isa<clang::FunctionDecl>(decl_from_modules))
{
if (log)
{
log->Printf(" CAS::FEVD[%u] Matching function found for \"%s\" in the modules",
current_id,
name.GetCString());
}
clang::Decl *copied_decl = m_ast_importer_sp->CopyDecl(m_ast_context, &decl_from_modules->getASTContext(), decl_from_modules);
clang::FunctionDecl *copied_function_decl = copied_decl ? dyn_cast<clang::FunctionDecl>(copied_decl) : nullptr;
if (!copied_function_decl)
{
if (log)
log->Printf(" CAS::FEVD[%u] - Couldn't export a function declaration from the modules",
current_id);
break;
}
if (copied_function_decl->getBody() && m_parser_vars->m_code_gen)
{
DeclGroupRef decl_group_ref(copied_function_decl);
m_parser_vars->m_code_gen->HandleTopLevelDecl(decl_group_ref);
}
context.AddNamedDecl(copied_function_decl);
context.m_found.function_with_type_info = true;
context.m_found.function = true;
}
else if (llvm::isa<clang::VarDecl>(decl_from_modules))
{
if (log)
{
log->Printf(" CAS::FEVD[%u] Matching variable found for \"%s\" in the modules",
current_id,
name.GetCString());
}
clang::Decl *copied_decl = m_ast_importer_sp->CopyDecl(m_ast_context, &decl_from_modules->getASTContext(), decl_from_modules);
clang::VarDecl *copied_var_decl = copied_decl ? dyn_cast_or_null<clang::VarDecl>(copied_decl) : nullptr;
if (!copied_var_decl)
{
if (log)
log->Printf(" CAS::FEVD[%u] - Couldn't export a variable declaration from the modules",
current_id);
break;
}
context.AddNamedDecl(copied_var_decl);
context.m_found.variable = true;
}
}
} while (0);
}
if (target && !context.m_found.variable && !namespace_decl)
{
// We couldn't find a non-symbol variable for this. Now we'll hunt for a generic
// data symbol, and -- if it is found -- treat it as a variable.
const Symbol *data_symbol = FindGlobalDataSymbol(*target, name);
if (data_symbol)
{
std::string warning("got name from symbols: ");
warning.append(name.AsCString());
const unsigned diag_id = m_ast_context->getDiagnostics().getCustomDiagID(clang::DiagnosticsEngine::Level::Warning, "%0");
m_ast_context->getDiagnostics().Report(diag_id) << warning.c_str();
AddOneGenericVariable(context, *data_symbol, current_id);
context.m_found.variable = true;
}
}
}
}
}
//static opaque_compiler_type_t
//MaybePromoteToBlockPointerType
//(
// ASTContext *ast_context,
// opaque_compiler_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();
//}
bool
ClangExpressionDeclMap::GetVariableValue (VariableSP &var,
lldb_private::Value &var_location,
TypeFromUser *user_type,
TypeFromParser *parser_type)
{
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Type *var_type = var->GetType();
if (!var_type)
{
if (log)
log->PutCString("Skipped a definition because it has no type");
return false;
}
Final bit of type system cleanup that abstracts declaration contexts into lldb_private::CompilerDeclContext and renames ClangType to CompilerType in many accessors and functions. Create a new "lldb_private::CompilerDeclContext" class that will replace all direct uses of "clang::DeclContext" when used in compiler agnostic code, yet still allow for conversion to clang::DeclContext subclasses by clang specific code. This completes the abstraction of type parsing by removing all "clang::" references from the SymbolFileDWARF. The new "lldb_private::CompilerDeclContext" class abstracts decl contexts found in compiler type systems so they can be used in internal API calls. The TypeSystem is required to support CompilerDeclContexts with new pure virtual functions that start with "DeclContext" in the member function names. Converted all code that used lldb_private::ClangNamespaceDecl over to use the new CompilerDeclContext class and removed the ClangNamespaceDecl.cpp and ClangNamespaceDecl.h files. Removed direct use of clang APIs from SBType and now use the abstract type systems to correctly explore types. Bulk renames for things that used to return a ClangASTType which is now CompilerType: "Type::GetClangFullType()" to "Type::GetFullCompilerType()" "Type::GetClangLayoutType()" to "Type::GetLayoutCompilerType()" "Type::GetClangForwardType()" to "Type::GetForwardCompilerType()" "Value::GetClangType()" to "Value::GetCompilerType()" "Value::SetClangType (const CompilerType &)" to "Value::SetCompilerType (const CompilerType &)" "ValueObject::GetClangType ()" to "ValueObject::GetCompilerType()" many more renames that are similar. llvm-svn: 245905
2015-08-24 23:46:31 +00:00
CompilerType var_clang_type = var_type->GetFullCompilerType ();
if (!var_clang_type)
{
if (log)
log->PutCString("Skipped a definition because it has no Clang type");
return false;
}
TypeSystem is now a plugin interface and removed any "ClangASTContext &Class::GetClangASTContext()" functions. This cleans up type systems to be more pluggable. Prior to this we had issues: - Module, SymbolFile, and many others has "ClangASTContext &GetClangASTContext()" functions. All have been switched over to use "TypeSystem *GetTypeSystemForLanguage()" - Cleaned up any places that were using the GetClangASTContext() functions to use TypeSystem - Cleaned up Module so that it no longer has dedicated type system member variables: lldb::ClangASTContextUP m_ast; ///< The Clang AST context for this module. lldb::GoASTContextUP m_go_ast; ///< The Go AST context for this module. Now we have a type system map: typedef std::map<lldb::LanguageType, lldb::TypeSystemSP> TypeSystemMap; TypeSystemMap m_type_system_map; ///< A map of any type systems associated with this module - Many places in code were using ClangASTContext static functions to place with CompilerType objects and add modifiers (const, volatile, restrict) and to make typedefs, L and R value references and more. These have been made into CompilerType functions that are abstract: class CompilerType { ... //---------------------------------------------------------------------- // Return a new CompilerType that is a L value reference to this type if // this type is valid and the type system supports L value references, // else return an invalid type. //---------------------------------------------------------------------- CompilerType GetLValueReferenceType () const; //---------------------------------------------------------------------- // Return a new CompilerType that is a R value reference to this type if // this type is valid and the type system supports R value references, // else return an invalid type. //---------------------------------------------------------------------- CompilerType GetRValueReferenceType () const; //---------------------------------------------------------------------- // Return a new CompilerType adds a const modifier to this type if // this type is valid and the type system supports const modifiers, // else return an invalid type. //---------------------------------------------------------------------- CompilerType AddConstModifier () const; //---------------------------------------------------------------------- // Return a new CompilerType adds a volatile modifier to this type if // this type is valid and the type system supports volatile modifiers, // else return an invalid type. //---------------------------------------------------------------------- CompilerType AddVolatileModifier () const; //---------------------------------------------------------------------- // Return a new CompilerType adds a restrict modifier to this type if // this type is valid and the type system supports restrict modifiers, // else return an invalid type. //---------------------------------------------------------------------- CompilerType AddRestrictModifier () const; //---------------------------------------------------------------------- // Create a typedef to this type using "name" as the name of the typedef // this type is valid and the type system supports typedefs, else return // an invalid type. //---------------------------------------------------------------------- CompilerType CreateTypedef (const char *name, const CompilerDeclContext &decl_ctx) const; }; Other changes include: - Removed "CompilerType TypeSystem::GetIntTypeFromBitSize(...)" and CompilerType TypeSystem::GetFloatTypeFromBitSize(...) and replaced it with "CompilerType TypeSystem::GetBuiltinTypeForEncodingAndBitSize(lldb::Encoding encoding, size_t bit_size);" - Fixed code in Type.h to not request the full type for a type for no good reason, just request the forward type and let the type expand as needed llvm-svn: 247953
2015-09-17 22:23:34 +00:00
ClangASTContext *clang_ast = llvm::dyn_cast_or_null<ClangASTContext>(var_type->GetForwardCompilerType().GetTypeSystem());
if (!clang_ast)
{
if (log)
log->PutCString("Skipped a definition because it has no Clang AST");
return false;
}
ASTContext *ast = clang_ast->getASTContext();
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 03:46:26 +00:00
if (!ast)
{
if (log)
log->PutCString("There is no AST context for the current execution context");
return false;
}
//var_clang_type = MaybePromoteToBlockPointerType (ast, var_clang_type);
DWARFExpression &var_location_expr = var->LocationExpression();
Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
Error err;
if (var->GetLocationIsConstantValueData())
{
DataExtractor const_value_extractor;
if (var_location_expr.GetExpressionData(const_value_extractor))
{
var_location = Value(const_value_extractor.GetDataStart(), const_value_extractor.GetByteSize());
var_location.SetValueType(Value::eValueTypeHostAddress);
}
else
{
if (log)
log->Printf("Error evaluating constant variable: %s", err.AsCString());
return false;
}
}
CompilerType type_to_use = GuardedCopyType(var_clang_type);
if (!type_to_use)
{
if (log)
log->Printf("Couldn't copy a variable's type into the parser's AST context");
return false;
}
if (parser_type)
*parser_type = TypeFromParser(type_to_use);
if (var_location.GetContextType() == Value::eContextTypeInvalid)
Final bit of type system cleanup that abstracts declaration contexts into lldb_private::CompilerDeclContext and renames ClangType to CompilerType in many accessors and functions. Create a new "lldb_private::CompilerDeclContext" class that will replace all direct uses of "clang::DeclContext" when used in compiler agnostic code, yet still allow for conversion to clang::DeclContext subclasses by clang specific code. This completes the abstraction of type parsing by removing all "clang::" references from the SymbolFileDWARF. The new "lldb_private::CompilerDeclContext" class abstracts decl contexts found in compiler type systems so they can be used in internal API calls. The TypeSystem is required to support CompilerDeclContexts with new pure virtual functions that start with "DeclContext" in the member function names. Converted all code that used lldb_private::ClangNamespaceDecl over to use the new CompilerDeclContext class and removed the ClangNamespaceDecl.cpp and ClangNamespaceDecl.h files. Removed direct use of clang APIs from SBType and now use the abstract type systems to correctly explore types. Bulk renames for things that used to return a ClangASTType which is now CompilerType: "Type::GetClangFullType()" to "Type::GetFullCompilerType()" "Type::GetClangLayoutType()" to "Type::GetLayoutCompilerType()" "Type::GetClangForwardType()" to "Type::GetForwardCompilerType()" "Value::GetClangType()" to "Value::GetCompilerType()" "Value::SetClangType (const CompilerType &)" to "Value::SetCompilerType (const CompilerType &)" "ValueObject::GetClangType ()" to "ValueObject::GetCompilerType()" many more renames that are similar. llvm-svn: 245905
2015-08-24 23:46:31 +00:00
var_location.SetCompilerType(type_to_use);
if (var_location.GetValueType() == Value::eValueTypeFileAddress)
{
SymbolContext var_sc;
var->CalculateSymbolContext(&var_sc);
if (!var_sc.module_sp)
return false;
Address so_addr(var_location.GetScalar().ULongLong(), var_sc.module_sp->GetSectionList());
lldb::addr_t load_addr = so_addr.GetLoadAddress(target);
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 02:13:07 +00:00
if (load_addr != LLDB_INVALID_ADDRESS)
{
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 02:13:07 +00:00
}
}
if (user_type)
*user_type = TypeFromUser(var_clang_type);
return true;
}
void
ClangExpressionDeclMap::AddOneVariable (NameSearchContext &context, VariableSP var, ValueObjectSP valobj, unsigned int current_id)
{
assert (m_parser_vars.get());
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
TypeFromUser ut;
TypeFromParser pt;
Value var_location;
if (!GetVariableValue (var, var_location, &ut, &pt))
return;
clang::QualType parser_opaque_type = QualType::getFromOpaquePtr(pt.GetOpaqueQualType());
if (parser_opaque_type.isNull())
return;
if (const clang::Type *parser_type = parser_opaque_type.getTypePtr())
{
if (const TagType *tag_type = dyn_cast<TagType>(parser_type))
CompleteType(tag_type->getDecl());
if (const ObjCObjectPointerType *objc_object_ptr_type = dyn_cast<ObjCObjectPointerType>(parser_type))
CompleteType(objc_object_ptr_type->getInterfaceDecl());
}
bool is_reference = pt.IsReferenceType();
NamedDecl *var_decl = NULL;
if (is_reference)
var_decl = context.AddVarDecl(pt);
else
TypeSystem is now a plugin interface and removed any "ClangASTContext &Class::GetClangASTContext()" functions. This cleans up type systems to be more pluggable. Prior to this we had issues: - Module, SymbolFile, and many others has "ClangASTContext &GetClangASTContext()" functions. All have been switched over to use "TypeSystem *GetTypeSystemForLanguage()" - Cleaned up any places that were using the GetClangASTContext() functions to use TypeSystem - Cleaned up Module so that it no longer has dedicated type system member variables: lldb::ClangASTContextUP m_ast; ///< The Clang AST context for this module. lldb::GoASTContextUP m_go_ast; ///< The Go AST context for this module. Now we have a type system map: typedef std::map<lldb::LanguageType, lldb::TypeSystemSP> TypeSystemMap; TypeSystemMap m_type_system_map; ///< A map of any type systems associated with this module - Many places in code were using ClangASTContext static functions to place with CompilerType objects and add modifiers (const, volatile, restrict) and to make typedefs, L and R value references and more. These have been made into CompilerType functions that are abstract: class CompilerType { ... //---------------------------------------------------------------------- // Return a new CompilerType that is a L value reference to this type if // this type is valid and the type system supports L value references, // else return an invalid type. //---------------------------------------------------------------------- CompilerType GetLValueReferenceType () const; //---------------------------------------------------------------------- // Return a new CompilerType that is a R value reference to this type if // this type is valid and the type system supports R value references, // else return an invalid type. //---------------------------------------------------------------------- CompilerType GetRValueReferenceType () const; //---------------------------------------------------------------------- // Return a new CompilerType adds a const modifier to this type if // this type is valid and the type system supports const modifiers, // else return an invalid type. //---------------------------------------------------------------------- CompilerType AddConstModifier () const; //---------------------------------------------------------------------- // Return a new CompilerType adds a volatile modifier to this type if // this type is valid and the type system supports volatile modifiers, // else return an invalid type. //---------------------------------------------------------------------- CompilerType AddVolatileModifier () const; //---------------------------------------------------------------------- // Return a new CompilerType adds a restrict modifier to this type if // this type is valid and the type system supports restrict modifiers, // else return an invalid type. //---------------------------------------------------------------------- CompilerType AddRestrictModifier () const; //---------------------------------------------------------------------- // Create a typedef to this type using "name" as the name of the typedef // this type is valid and the type system supports typedefs, else return // an invalid type. //---------------------------------------------------------------------- CompilerType CreateTypedef (const char *name, const CompilerDeclContext &decl_ctx) const; }; Other changes include: - Removed "CompilerType TypeSystem::GetIntTypeFromBitSize(...)" and CompilerType TypeSystem::GetFloatTypeFromBitSize(...) and replaced it with "CompilerType TypeSystem::GetBuiltinTypeForEncodingAndBitSize(lldb::Encoding encoding, size_t bit_size);" - Fixed code in Type.h to not request the full type for a type for no good reason, just request the forward type and let the type expand as needed llvm-svn: 247953
2015-09-17 22:23:34 +00:00
var_decl = context.AddVarDecl(pt.GetLValueReferenceType());
std::string decl_name(context.m_decl_name.getAsString());
Modified LLDB expressions to not have to JIT and run code just to see variable values or persistent expression variables. Now if an expression consists of a value that is a child of a variable, or of a persistent variable only, we will create a value object for it and make a ValueObjectConstResult from it to freeze the value (for program variables only, not persistent variables) and avoid running JITed code. For everything else we still parse up and JIT code and run it in the inferior. There was also a lot of clean up in the expression code. I made the ClangExpressionVariables be stored in collections of shared pointers instead of in collections of objects. This will help stop a lot of copy constructors on these large objects and also cleans up the code considerably. The persistent clang expression variables were moved over to the Target to ensure they persist across process executions. Added the ability for lldb_private::Target objects to evaluate expressions. We want to evaluate expressions at the target level in case we aren't running yet, or we have just completed running. We still want to be able to access the persistent expression variables between runs, and also evaluate constant expressions. Added extra logging to the dynamic loader plug-in for MacOSX. ModuleList objects can now dump their contents with the UUID, arch and full paths being logged with appropriate prefix values. Thread hardened the Communication class a bit by making the connection auto_ptr member into a shared pointer member and then making a local copy of the shared pointer in each method that uses it to make sure another thread can't nuke the connection object while it is being used by another thread. Added a new file to the lldb/test/load_unload test that causes the test a.out file to link to the libd.dylib file all the time. This will allow us to test using the DYLD_LIBRARY_PATH environment variable after moving libd.dylib somewhere else. llvm-svn: 121745
2010-12-14 02:59:59 +00:00
ConstString entity_name(decl_name.c_str());
ClangExpressionVariable *entity(new ClangExpressionVariable(valobj));
m_found_entities.AddNewlyConstructedVariable(entity);
assert (entity);
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;
if (is_reference)
entity->m_flags |= ClangExpressionVariable::EVTypeIsReference;
if (log)
{
ASTDumper orig_dumper(ut.GetOpaqueQualType());
ASTDumper ast_dumper(var_decl);
log->Printf(" CEDM::FEVD[%u] Found variable %s, returned %s (original %s)", current_id, decl_name.c_str(), ast_dumper.GetCString(), orig_dumper.GetCString());
}
}
void
ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
ExpressionVariableSP &pvar_sp,
unsigned int current_id)
{
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
TypeFromUser user_type (llvm::cast<ClangExpressionVariable>(pvar_sp.get())->GetTypeFromUser());
TypeFromParser parser_type (GuardedCopyType(user_type));
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;
}
TypeSystem is now a plugin interface and removed any "ClangASTContext &Class::GetClangASTContext()" functions. This cleans up type systems to be more pluggable. Prior to this we had issues: - Module, SymbolFile, and many others has "ClangASTContext &GetClangASTContext()" functions. All have been switched over to use "TypeSystem *GetTypeSystemForLanguage()" - Cleaned up any places that were using the GetClangASTContext() functions to use TypeSystem - Cleaned up Module so that it no longer has dedicated type system member variables: lldb::ClangASTContextUP m_ast; ///< The Clang AST context for this module. lldb::GoASTContextUP m_go_ast; ///< The Go AST context for this module. Now we have a type system map: typedef std::map<lldb::LanguageType, lldb::TypeSystemSP> TypeSystemMap; TypeSystemMap m_type_system_map; ///< A map of any type systems associated with this module - Many places in code were using ClangASTContext static functions to place with CompilerType objects and add modifiers (const, volatile, restrict) and to make typedefs, L and R value references and more. These have been made into CompilerType functions that are abstract: class CompilerType { ... //---------------------------------------------------------------------- // Return a new CompilerType that is a L value reference to this type if // this type is valid and the type system supports L value references, // else return an invalid type. //---------------------------------------------------------------------- CompilerType GetLValueReferenceType () const; //---------------------------------------------------------------------- // Return a new CompilerType that is a R value reference to this type if // this type is valid and the type system supports R value references, // else return an invalid type. //---------------------------------------------------------------------- CompilerType GetRValueReferenceType () const; //---------------------------------------------------------------------- // Return a new CompilerType adds a const modifier to this type if // this type is valid and the type system supports const modifiers, // else return an invalid type. //---------------------------------------------------------------------- CompilerType AddConstModifier () const; //---------------------------------------------------------------------- // Return a new CompilerType adds a volatile modifier to this type if // this type is valid and the type system supports volatile modifiers, // else return an invalid type. //---------------------------------------------------------------------- CompilerType AddVolatileModifier () const; //---------------------------------------------------------------------- // Return a new CompilerType adds a restrict modifier to this type if // this type is valid and the type system supports restrict modifiers, // else return an invalid type. //---------------------------------------------------------------------- CompilerType AddRestrictModifier () const; //---------------------------------------------------------------------- // Create a typedef to this type using "name" as the name of the typedef // this type is valid and the type system supports typedefs, else return // an invalid type. //---------------------------------------------------------------------- CompilerType CreateTypedef (const char *name, const CompilerDeclContext &decl_ctx) const; }; Other changes include: - Removed "CompilerType TypeSystem::GetIntTypeFromBitSize(...)" and CompilerType TypeSystem::GetFloatTypeFromBitSize(...) and replaced it with "CompilerType TypeSystem::GetBuiltinTypeForEncodingAndBitSize(lldb::Encoding encoding, size_t bit_size);" - Fixed code in Type.h to not request the full type for a type for no good reason, just request the forward type and let the type expand as needed llvm-svn: 247953
2015-09-17 22:23:34 +00:00
NamedDecl *var_decl = context.AddVarDecl(parser_type.GetLValueReferenceType());
llvm::cast<ClangExpressionVariable>(pvar_sp.get())->EnableParserVars(GetParserID());
ClangExpressionVariable::ParserVars *parser_vars = llvm::cast<ClangExpressionVariable>(pvar_sp.get())->GetParserVars(GetParserID());
parser_vars->m_parser_type = parser_type;
parser_vars->m_named_decl = var_decl;
parser_vars->m_llvm_value = NULL;
parser_vars->m_lldb_value.Clear();
if (log)
{
ASTDumper ast_dumper(var_decl);
log->Printf(" CEDM::FEVD[%u] Added pvar %s, returned %s", current_id, pvar_sp->GetName().GetCString(), ast_dumper.GetCString());
}
}
void
ClangExpressionDeclMap::AddOneGenericVariable(NameSearchContext &context,
const Symbol &symbol,
unsigned int current_id)
{
assert(m_parser_vars.get());
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
if (target == NULL)
return;
ASTContext *scratch_ast_context = target->GetScratchClangASTContext()->getASTContext();
TypeSystem is now a plugin interface and removed any "ClangASTContext &Class::GetClangASTContext()" functions. This cleans up type systems to be more pluggable. Prior to this we had issues: - Module, SymbolFile, and many others has "ClangASTContext &GetClangASTContext()" functions. All have been switched over to use "TypeSystem *GetTypeSystemForLanguage()" - Cleaned up any places that were using the GetClangASTContext() functions to use TypeSystem - Cleaned up Module so that it no longer has dedicated type system member variables: lldb::ClangASTContextUP m_ast; ///< The Clang AST context for this module. lldb::GoASTContextUP m_go_ast; ///< The Go AST context for this module. Now we have a type system map: typedef std::map<lldb::LanguageType, lldb::TypeSystemSP> TypeSystemMap; TypeSystemMap m_type_system_map; ///< A map of any type systems associated with this module - Many places in code were using ClangASTContext static functions to place with CompilerType objects and add modifiers (const, volatile, restrict) and to make typedefs, L and R value references and more. These have been made into CompilerType functions that are abstract: class CompilerType { ... //---------------------------------------------------------------------- // Return a new CompilerType that is a L value reference to this type if // this type is valid and the type system supports L value references, // else return an invalid type. //---------------------------------------------------------------------- CompilerType GetLValueReferenceType () const; //---------------------------------------------------------------------- // Return a new CompilerType that is a R value reference to this type if // this type is valid and the type system supports R value references, // else return an invalid type. //---------------------------------------------------------------------- CompilerType GetRValueReferenceType () const; //---------------------------------------------------------------------- // Return a new CompilerType adds a const modifier to this type if // this type is valid and the type system supports const modifiers, // else return an invalid type. //---------------------------------------------------------------------- CompilerType AddConstModifier () const; //---------------------------------------------------------------------- // Return a new CompilerType adds a volatile modifier to this type if // this type is valid and the type system supports volatile modifiers, // else return an invalid type. //---------------------------------------------------------------------- CompilerType AddVolatileModifier () const; //---------------------------------------------------------------------- // Return a new CompilerType adds a restrict modifier to this type if // this type is valid and the type system supports restrict modifiers, // else return an invalid type. //---------------------------------------------------------------------- CompilerType AddRestrictModifier () const; //---------------------------------------------------------------------- // Create a typedef to this type using "name" as the name of the typedef // this type is valid and the type system supports typedefs, else return // an invalid type. //---------------------------------------------------------------------- CompilerType CreateTypedef (const char *name, const CompilerDeclContext &decl_ctx) const; }; Other changes include: - Removed "CompilerType TypeSystem::GetIntTypeFromBitSize(...)" and CompilerType TypeSystem::GetFloatTypeFromBitSize(...) and replaced it with "CompilerType TypeSystem::GetBuiltinTypeForEncodingAndBitSize(lldb::Encoding encoding, size_t bit_size);" - Fixed code in Type.h to not request the full type for a type for no good reason, just request the forward type and let the type expand as needed llvm-svn: 247953
2015-09-17 22:23:34 +00:00
TypeFromUser user_type (ClangASTContext::GetBasicType(scratch_ast_context, eBasicTypeVoid).GetPointerType().GetLValueReferenceType());
TypeFromParser parser_type (ClangASTContext::GetBasicType(m_ast_context, eBasicTypeVoid).GetPointerType().GetLValueReferenceType());
NamedDecl *var_decl = context.AddVarDecl(parser_type);
std::string decl_name(context.m_decl_name.getAsString());
ConstString entity_name(decl_name.c_str());
ClangExpressionVariable *entity(new ClangExpressionVariable(m_parser_vars->m_exe_ctx.GetBestExecutionContextScope (),
entity_name,
user_type,
m_parser_vars->m_target_info.byte_order,
m_parser_vars->m_target_info.address_byte_size));
m_found_entities.AddNewlyConstructedVariable(entity);
entity->EnableParserVars(GetParserID());
ClangExpressionVariable::ParserVars *parser_vars = entity->GetParserVars(GetParserID());
const Address symbol_address = symbol.GetAddress();
lldb::addr_t symbol_load_addr = symbol_address.GetLoadAddress(target);
//parser_vars->m_lldb_value.SetContext(Value::eContextTypeClangType, user_type.GetOpaqueQualType());
Final bit of type system cleanup that abstracts declaration contexts into lldb_private::CompilerDeclContext and renames ClangType to CompilerType in many accessors and functions. Create a new "lldb_private::CompilerDeclContext" class that will replace all direct uses of "clang::DeclContext" when used in compiler agnostic code, yet still allow for conversion to clang::DeclContext subclasses by clang specific code. This completes the abstraction of type parsing by removing all "clang::" references from the SymbolFileDWARF. The new "lldb_private::CompilerDeclContext" class abstracts decl contexts found in compiler type systems so they can be used in internal API calls. The TypeSystem is required to support CompilerDeclContexts with new pure virtual functions that start with "DeclContext" in the member function names. Converted all code that used lldb_private::ClangNamespaceDecl over to use the new CompilerDeclContext class and removed the ClangNamespaceDecl.cpp and ClangNamespaceDecl.h files. Removed direct use of clang APIs from SBType and now use the abstract type systems to correctly explore types. Bulk renames for things that used to return a ClangASTType which is now CompilerType: "Type::GetClangFullType()" to "Type::GetFullCompilerType()" "Type::GetClangLayoutType()" to "Type::GetLayoutCompilerType()" "Type::GetClangForwardType()" to "Type::GetForwardCompilerType()" "Value::GetClangType()" to "Value::GetCompilerType()" "Value::SetClangType (const CompilerType &)" to "Value::SetCompilerType (const CompilerType &)" "ValueObject::GetClangType ()" to "ValueObject::GetCompilerType()" many more renames that are similar. llvm-svn: 245905
2015-08-24 23:46:31 +00:00
parser_vars->m_lldb_value.SetCompilerType(user_type);
parser_vars->m_lldb_value.GetScalar() = symbol_load_addr;
parser_vars->m_lldb_value.SetValueType(Value::eValueTypeLoadAddress);
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;
if (log)
{
ASTDumper ast_dumper(var_decl);
log->Printf(" CEDM::FEVD[%u] Found variable %s, returned %s", current_id, decl_name.c_str(), ast_dumper.GetCString());
}
}
bool
ClangExpressionDeclMap::ResolveUnknownTypes()
{
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
ClangASTContext *scratch_ast_context = target->GetScratchClangASTContext();
for (size_t index = 0, num_entities = m_found_entities.GetSize();
index < num_entities;
++index)
{
ExpressionVariableSP entity = m_found_entities.GetVariableAtIndex(index);
ClangExpressionVariable::ParserVars *parser_vars = llvm::cast<ClangExpressionVariable>(entity.get())->GetParserVars(GetParserID());
if (entity->m_flags & ClangExpressionVariable::EVUnknownType)
{
const NamedDecl *named_decl = parser_vars->m_named_decl;
const VarDecl *var_decl = dyn_cast<VarDecl>(named_decl);
if (!var_decl)
{
if (log)
log->Printf("Entity of unknown type does not have a VarDecl");
return false;
}
if (log)
{
ASTDumper ast_dumper(const_cast<VarDecl*>(var_decl));
log->Printf("Variable of unknown type now has Decl %s", ast_dumper.GetCString());
}
QualType var_type = var_decl->getType();
TypeFromParser parser_type(var_type.getAsOpaquePtr(), ClangASTContext::GetASTContext(&var_decl->getASTContext()));
lldb::opaque_compiler_type_t copied_type = m_ast_importer_sp->CopyType(scratch_ast_context->getASTContext(), &var_decl->getASTContext(), var_type.getAsOpaquePtr());
if (!copied_type)
{
if (log)
log->Printf("ClangExpressionDeclMap::ResolveUnknownType - Couldn't import the type for a variable");
return (bool) lldb::ExpressionVariableSP();
}
TypeFromUser user_type(copied_type, scratch_ast_context);
// parser_vars->m_lldb_value.SetContext(Value::eContextTypeClangType, user_type.GetOpaqueQualType());
Final bit of type system cleanup that abstracts declaration contexts into lldb_private::CompilerDeclContext and renames ClangType to CompilerType in many accessors and functions. Create a new "lldb_private::CompilerDeclContext" class that will replace all direct uses of "clang::DeclContext" when used in compiler agnostic code, yet still allow for conversion to clang::DeclContext subclasses by clang specific code. This completes the abstraction of type parsing by removing all "clang::" references from the SymbolFileDWARF. The new "lldb_private::CompilerDeclContext" class abstracts decl contexts found in compiler type systems so they can be used in internal API calls. The TypeSystem is required to support CompilerDeclContexts with new pure virtual functions that start with "DeclContext" in the member function names. Converted all code that used lldb_private::ClangNamespaceDecl over to use the new CompilerDeclContext class and removed the ClangNamespaceDecl.cpp and ClangNamespaceDecl.h files. Removed direct use of clang APIs from SBType and now use the abstract type systems to correctly explore types. Bulk renames for things that used to return a ClangASTType which is now CompilerType: "Type::GetClangFullType()" to "Type::GetFullCompilerType()" "Type::GetClangLayoutType()" to "Type::GetLayoutCompilerType()" "Type::GetClangForwardType()" to "Type::GetForwardCompilerType()" "Value::GetClangType()" to "Value::GetCompilerType()" "Value::SetClangType (const CompilerType &)" to "Value::SetCompilerType (const CompilerType &)" "ValueObject::GetClangType ()" to "ValueObject::GetCompilerType()" many more renames that are similar. llvm-svn: 245905
2015-08-24 23:46:31 +00:00
parser_vars->m_lldb_value.SetCompilerType(user_type);
parser_vars->m_parser_type = parser_type;
Final bit of type system cleanup that abstracts declaration contexts into lldb_private::CompilerDeclContext and renames ClangType to CompilerType in many accessors and functions. Create a new "lldb_private::CompilerDeclContext" class that will replace all direct uses of "clang::DeclContext" when used in compiler agnostic code, yet still allow for conversion to clang::DeclContext subclasses by clang specific code. This completes the abstraction of type parsing by removing all "clang::" references from the SymbolFileDWARF. The new "lldb_private::CompilerDeclContext" class abstracts decl contexts found in compiler type systems so they can be used in internal API calls. The TypeSystem is required to support CompilerDeclContexts with new pure virtual functions that start with "DeclContext" in the member function names. Converted all code that used lldb_private::ClangNamespaceDecl over to use the new CompilerDeclContext class and removed the ClangNamespaceDecl.cpp and ClangNamespaceDecl.h files. Removed direct use of clang APIs from SBType and now use the abstract type systems to correctly explore types. Bulk renames for things that used to return a ClangASTType which is now CompilerType: "Type::GetClangFullType()" to "Type::GetFullCompilerType()" "Type::GetClangLayoutType()" to "Type::GetLayoutCompilerType()" "Type::GetClangForwardType()" to "Type::GetForwardCompilerType()" "Value::GetClangType()" to "Value::GetCompilerType()" "Value::SetClangType (const CompilerType &)" to "Value::SetCompilerType (const CompilerType &)" "ValueObject::GetClangType ()" to "ValueObject::GetCompilerType()" many more renames that are similar. llvm-svn: 245905
2015-08-24 23:46:31 +00:00
entity->SetCompilerType(user_type);
entity->m_flags &= ~(ClangExpressionVariable::EVUnknownType);
}
}
return true;
}
void
Modified LLDB expressions to not have to JIT and run code just to see variable values or persistent expression variables. Now if an expression consists of a value that is a child of a variable, or of a persistent variable only, we will create a value object for it and make a ValueObjectConstResult from it to freeze the value (for program variables only, not persistent variables) and avoid running JITed code. For everything else we still parse up and JIT code and run it in the inferior. There was also a lot of clean up in the expression code. I made the ClangExpressionVariables be stored in collections of shared pointers instead of in collections of objects. This will help stop a lot of copy constructors on these large objects and also cleans up the code considerably. The persistent clang expression variables were moved over to the Target to ensure they persist across process executions. Added the ability for lldb_private::Target objects to evaluate expressions. We want to evaluate expressions at the target level in case we aren't running yet, or we have just completed running. We still want to be able to access the persistent expression variables between runs, and also evaluate constant expressions. Added extra logging to the dynamic loader plug-in for MacOSX. ModuleList objects can now dump their contents with the UUID, arch and full paths being logged with appropriate prefix values. Thread hardened the Communication class a bit by making the connection auto_ptr member into a shared pointer member and then making a local copy of the shared pointer in each method that uses it to make sure another thread can't nuke the connection object while it is being used by another thread. Added a new file to the lldb/test/load_unload test that causes the test a.out file to link to the libd.dylib file all the time. This will allow us to test using the DYLD_LIBRARY_PATH environment variable after moving libd.dylib somewhere else. llvm-svn: 121745
2010-12-14 02:59:59 +00:00
ClangExpressionDeclMap::AddOneRegister (NameSearchContext &context,
const RegisterInfo *reg_info,
unsigned int current_id)
{
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
CompilerType clang_type = ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (m_ast_context,
reg_info->encoding,
reg_info->byte_size * 8);
if (!clang_type)
{
if (log)
log->Printf(" Tried to add a type for %s, but couldn't get one", context.m_decl_name.getAsString().c_str());
return;
}
TypeFromParser parser_clang_type (clang_type);
NamedDecl *var_decl = context.AddVarDecl(parser_clang_type);
ClangExpressionVariable *entity(new ClangExpressionVariable(m_parser_vars->m_exe_ctx.GetBestExecutionContextScope(),
m_parser_vars->m_target_info.byte_order,
m_parser_vars->m_target_info.address_byte_size));
m_found_entities.AddNewlyConstructedVariable(entity);
std::string decl_name(context.m_decl_name.getAsString());
Modified LLDB expressions to not have to JIT and run code just to see variable values or persistent expression variables. Now if an expression consists of a value that is a child of a variable, or of a persistent variable only, we will create a value object for it and make a ValueObjectConstResult from it to freeze the value (for program variables only, not persistent variables) and avoid running JITed code. For everything else we still parse up and JIT code and run it in the inferior. There was also a lot of clean up in the expression code. I made the ClangExpressionVariables be stored in collections of shared pointers instead of in collections of objects. This will help stop a lot of copy constructors on these large objects and also cleans up the code considerably. The persistent clang expression variables were moved over to the Target to ensure they persist across process executions. Added the ability for lldb_private::Target objects to evaluate expressions. We want to evaluate expressions at the target level in case we aren't running yet, or we have just completed running. We still want to be able to access the persistent expression variables between runs, and also evaluate constant expressions. Added extra logging to the dynamic loader plug-in for MacOSX. ModuleList objects can now dump their contents with the UUID, arch and full paths being logged with appropriate prefix values. Thread hardened the Communication class a bit by making the connection auto_ptr member into a shared pointer member and then making a local copy of the shared pointer in each method that uses it to make sure another thread can't nuke the connection object while it is being used by another thread. Added a new file to the lldb/test/load_unload test that causes the test a.out file to link to the libd.dylib file all the time. This will allow us to test using the DYLD_LIBRARY_PATH environment variable after moving libd.dylib somewhere else. llvm-svn: 121745
2010-12-14 02:59:59 +00:00
entity->SetName (ConstString (decl_name.c_str()));
entity->SetRegisterInfo (reg_info);
entity->EnableParserVars(GetParserID());
ClangExpressionVariable::ParserVars *parser_vars = entity->GetParserVars(GetParserID());
parser_vars->m_parser_type = parser_clang_type;
parser_vars->m_named_decl = var_decl;
parser_vars->m_llvm_value = NULL;
parser_vars->m_lldb_value.Clear();
entity->m_flags |= ClangExpressionVariable::EVBareRegister;
if (log)
{
ASTDumper ast_dumper(var_decl);
log->Printf(" CEDM::FEVD[%d] Added register %s, returned %s", current_id, context.m_decl_name.getAsString().c_str(), ast_dumper.GetCString());
}
}
void
ClangExpressionDeclMap::AddOneFunction (NameSearchContext &context,
Function* function,
Symbol* symbol,
unsigned int current_id)
{
assert (m_parser_vars.get());
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
NamedDecl *function_decl = NULL;
Address fun_address;
CompilerType function_clang_type;
bool is_indirect_function = false;
if (function)
{
Type *function_type = function->GetType();
if (!function_type)
{
if (log)
log->PutCString(" Skipped a function because it has no type");
return;
}
Final bit of type system cleanup that abstracts declaration contexts into lldb_private::CompilerDeclContext and renames ClangType to CompilerType in many accessors and functions. Create a new "lldb_private::CompilerDeclContext" class that will replace all direct uses of "clang::DeclContext" when used in compiler agnostic code, yet still allow for conversion to clang::DeclContext subclasses by clang specific code. This completes the abstraction of type parsing by removing all "clang::" references from the SymbolFileDWARF. The new "lldb_private::CompilerDeclContext" class abstracts decl contexts found in compiler type systems so they can be used in internal API calls. The TypeSystem is required to support CompilerDeclContexts with new pure virtual functions that start with "DeclContext" in the member function names. Converted all code that used lldb_private::ClangNamespaceDecl over to use the new CompilerDeclContext class and removed the ClangNamespaceDecl.cpp and ClangNamespaceDecl.h files. Removed direct use of clang APIs from SBType and now use the abstract type systems to correctly explore types. Bulk renames for things that used to return a ClangASTType which is now CompilerType: "Type::GetClangFullType()" to "Type::GetFullCompilerType()" "Type::GetClangLayoutType()" to "Type::GetLayoutCompilerType()" "Type::GetClangForwardType()" to "Type::GetForwardCompilerType()" "Value::GetClangType()" to "Value::GetCompilerType()" "Value::SetClangType (const CompilerType &)" to "Value::SetCompilerType (const CompilerType &)" "ValueObject::GetClangType ()" to "ValueObject::GetCompilerType()" many more renames that are similar. llvm-svn: 245905
2015-08-24 23:46:31 +00:00
function_clang_type = function_type->GetFullCompilerType ();
if (!function_clang_type)
{
if (log)
log->PutCString(" Skipped a function because it has no Clang type");
return;
}
fun_address = function->GetAddressRange().GetBaseAddress();
CompilerType copied_function_type = GuardedCopyType(function_clang_type);
if (copied_function_type)
{
function_decl = context.AddFunDecl(copied_function_type);
if (!function_decl)
{
if (log)
{
log->Printf (" Failed to create a function decl for '%s' {0x%8.8" PRIx64 "}",
function_type->GetName().GetCString(),
function_type->GetID());
}
return;
}
}
else
{
// We failed to copy the type we found
if (log)
{
log->Printf (" Failed to import the function type '%s' {0x%8.8" PRIx64 "} into the expression parser AST contenxt",
function_type->GetName().GetCString(),
function_type->GetID());
}
return;
}
}
else if (symbol)
{
fun_address = symbol->GetAddress();
function_decl = context.AddGenericFunDecl();
is_indirect_function = symbol->IsIndirect();
}
else
{
if (log)
log->PutCString(" AddOneFunction called with no function and no symbol");
return;
}
Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
lldb::addr_t load_addr = fun_address.GetCallableLoadAddress(target, is_indirect_function);
ClangExpressionVariable *entity(new ClangExpressionVariable (m_parser_vars->m_exe_ctx.GetBestExecutionContextScope (),
m_parser_vars->m_target_info.byte_order,
m_parser_vars->m_target_info.address_byte_size));
m_found_entities.AddNewlyConstructedVariable(entity);
std::string decl_name(context.m_decl_name.getAsString());
entity->SetName(ConstString(decl_name.c_str()));
Final bit of type system cleanup that abstracts declaration contexts into lldb_private::CompilerDeclContext and renames ClangType to CompilerType in many accessors and functions. Create a new "lldb_private::CompilerDeclContext" class that will replace all direct uses of "clang::DeclContext" when used in compiler agnostic code, yet still allow for conversion to clang::DeclContext subclasses by clang specific code. This completes the abstraction of type parsing by removing all "clang::" references from the SymbolFileDWARF. The new "lldb_private::CompilerDeclContext" class abstracts decl contexts found in compiler type systems so they can be used in internal API calls. The TypeSystem is required to support CompilerDeclContexts with new pure virtual functions that start with "DeclContext" in the member function names. Converted all code that used lldb_private::ClangNamespaceDecl over to use the new CompilerDeclContext class and removed the ClangNamespaceDecl.cpp and ClangNamespaceDecl.h files. Removed direct use of clang APIs from SBType and now use the abstract type systems to correctly explore types. Bulk renames for things that used to return a ClangASTType which is now CompilerType: "Type::GetClangFullType()" to "Type::GetFullCompilerType()" "Type::GetClangLayoutType()" to "Type::GetLayoutCompilerType()" "Type::GetClangForwardType()" to "Type::GetForwardCompilerType()" "Value::GetClangType()" to "Value::GetCompilerType()" "Value::SetClangType (const CompilerType &)" to "Value::SetCompilerType (const CompilerType &)" "ValueObject::GetClangType ()" to "ValueObject::GetCompilerType()" many more renames that are similar. llvm-svn: 245905
2015-08-24 23:46:31 +00:00
entity->SetCompilerType (function_clang_type);
entity->EnableParserVars(GetParserID());
ClangExpressionVariable::ParserVars *parser_vars = entity->GetParserVars(GetParserID());
if (load_addr != LLDB_INVALID_ADDRESS)
{
parser_vars->m_lldb_value.SetValueType(Value::eValueTypeLoadAddress);
parser_vars->m_lldb_value.GetScalar() = load_addr;
}
else
{
// We have to try finding a file address.
lldb::addr_t file_addr = fun_address.GetFileAddress();
parser_vars->m_lldb_value.SetValueType(Value::eValueTypeFileAddress);
parser_vars->m_lldb_value.GetScalar() = file_addr;
}
parser_vars->m_named_decl = function_decl;
parser_vars->m_llvm_value = NULL;
if (log)
{
ASTDumper ast_dumper(function_decl);
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",
current_id,
(function ? "specific" : "generic"),
decl_name.c_str(),
ss.GetData(),
ast_dumper.GetCString());
}
}
void
ClangExpressionDeclMap::AddThisType(NameSearchContext &context,
TypeFromUser &ut,
unsigned int current_id)
{
CompilerType copied_clang_type = GuardedCopyType(ut);
if (!copied_clang_type)
{
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
if (log)
log->Printf("ClangExpressionDeclMap::AddThisType - Couldn't import the type");
return;
}
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 00:44:12 +00:00
{
CompilerType void_clang_type = ClangASTContext::GetBasicType(m_ast_context, eBasicTypeVoid);
CompilerType void_ptr_clang_type = void_clang_type.GetPointerType();
CompilerType method_type = ClangASTContext::CreateFunctionType (m_ast_context,
void_clang_type,
&void_ptr_clang_type,
1,
false,
copied_clang_type.GetTypeQualifiers());
const bool is_virtual = false;
const bool is_static = false;
const bool is_inline = false;
const bool is_explicit = false;
const bool is_attr_used = true;
const bool is_artificial = false;
ClangASTContext::GetASTContext(m_ast_context)->
AddMethodToCXXRecordType (copied_clang_type.GetOpaqueQualType(),
"$__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 00:44:12 +00:00
}
if (!copied_clang_type.IsValid())
return;
TypeSourceInfo *type_source_info = m_ast_context->getTrivialTypeSourceInfo(QualType::getFromOpaquePtr(copied_clang_type.GetOpaqueQualType()));
if (!type_source_info)
return;
// Construct a typedef type because if "*this" is a templated type we can't just return ClassTemplateSpecializationDecls in response to name queries.
// Using a typedef makes this much more robust.
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);
return;
}
void
ClangExpressionDeclMap::AddOneType(NameSearchContext &context,
TypeFromUser &ut,
unsigned int current_id)
{
CompilerType copied_clang_type = GuardedCopyType(ut);
if (!copied_clang_type)
{
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
if (log)
log->Printf("ClangExpressionDeclMap::AddOneType - Couldn't import the type");
return;
}
context.AddTypeDecl(copied_clang_type);
}