diff options
Diffstat (limited to 'lldb')
-rw-r--r-- | lldb/include/lldb/Expression/ClangExpressionDeclMap.h | 23 | ||||
-rw-r--r-- | lldb/include/lldb/Expression/ClangPersistentVariables.h | 89 | ||||
-rw-r--r-- | lldb/include/lldb/Expression/IRForTarget.h | 7 | ||||
-rw-r--r-- | lldb/include/lldb/Symbol/TaggedASTType.h | 4 | ||||
-rw-r--r-- | lldb/include/lldb/Target/Process.h | 5 | ||||
-rw-r--r-- | lldb/lldb.xcodeproj/project.pbxproj | 8 | ||||
-rw-r--r-- | lldb/source/Commands/CommandObjectExpression.cpp | 4 | ||||
-rw-r--r-- | lldb/source/Expression/ClangExpression.cpp | 1 | ||||
-rw-r--r-- | lldb/source/Expression/ClangExpressionDeclMap.cpp | 148 | ||||
-rw-r--r-- | lldb/source/Expression/ClangPersistentVariables.cpp | 59 | ||||
-rw-r--r-- | lldb/source/Expression/IRForTarget.cpp | 151 | ||||
-rw-r--r-- | lldb/source/Target/Process.cpp | 9 |
12 files changed, 444 insertions, 64 deletions
diff --git a/lldb/include/lldb/Expression/ClangExpressionDeclMap.h b/lldb/include/lldb/Expression/ClangExpressionDeclMap.h index 7dec92d623f..3e7f4ce2108 100644 --- a/lldb/include/lldb/Expression/ClangExpressionDeclMap.h +++ b/lldb/include/lldb/Expression/ClangExpressionDeclMap.h @@ -30,6 +30,7 @@ namespace llvm { namespace lldb_private { +class ClangPersistentVariable; class ClangPersistentVariables; class Error; class Function; @@ -39,8 +40,7 @@ class Variable; class ClangExpressionDeclMap { public: - ClangExpressionDeclMap(ExecutionContext *exe_ctx, - ClangPersistentVariables &persistent_vars); + ClangExpressionDeclMap(ExecutionContext *exe_ctx); ~ClangExpressionDeclMap(); // Interface for ClangStmtVisitor @@ -48,6 +48,7 @@ public: const clang::Decl *decl); // Interface for IRForTarget + bool AddPersistentVariable (const clang::NamedDecl *decl); bool AddValueToStruct (llvm::Value *value, const clang::NamedDecl *decl, std::string &name, @@ -67,7 +68,6 @@ public: bool GetFunctionInfo (const clang::NamedDecl *decl, llvm::Value**& value, uint64_t &ptr); - bool GetFunctionAddress (const char *name, uint64_t &ptr); @@ -90,9 +90,6 @@ public: // Interface for ClangASTSource void GetDecls (NameSearchContext &context, const char *name); - - typedef TaggedASTType<0> TypeFromParser; - typedef TaggedASTType<1> TypeFromUser; private: struct Tuple { @@ -124,7 +121,7 @@ private: StructMemberVector m_members; ExecutionContext *m_exe_ctx; SymbolContext *m_sym_ctx; /* owned by ClangExpressionDeclMap */ - ClangPersistentVariables &m_persistent_vars; + ClangPersistentVariables *m_persistent_vars; off_t m_struct_alignment; size_t m_struct_size; bool m_struct_laid_out; @@ -142,6 +139,7 @@ private: TypeFromParser *parser_type = NULL); void AddOneVariable(NameSearchContext &context, Variable *var); + void AddOneVariable(NameSearchContext &context, ClangPersistentVariable *pvar); void AddOneFunction(NameSearchContext &context, Function *fun, Symbol *sym); void AddOneType(NameSearchContext &context, Type *type); @@ -150,6 +148,12 @@ private: lldb_private::Value *result_value, /* must be non-NULL if D is set */ Error &err); + bool DoMaterializeOnePersistentVariable(bool dematerialize, + ExecutionContext &exe_ctx, + const char *name, + lldb::addr_t addr, + Error &err); + bool DoMaterializeOneVariable(bool dematerialize, ExecutionContext &exe_ctx, const SymbolContext &sym_ctx, @@ -159,11 +163,6 @@ private: Error &err); }; -class ClangPersistentVariables -{ - -}; - } // namespace lldb_private #endif // liblldb_ClangExpressionDeclMap_h_ diff --git a/lldb/include/lldb/Expression/ClangPersistentVariables.h b/lldb/include/lldb/Expression/ClangPersistentVariables.h new file mode 100644 index 00000000000..b60c256d585 --- /dev/null +++ b/lldb/include/lldb/Expression/ClangPersistentVariables.h @@ -0,0 +1,89 @@ +//===-- ClangPersistentVariables.h ------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_ClangPersistentVariables_h_ +#define liblldb_ClangPersistentVariables_h_ + +#include "lldb-forward-rtti.h" +#include "lldb/Core/ConstString.h" +#include "lldb/Core/DataBufferHeap.h" +#include "lldb/Symbol/TaggedASTType.h" + +#include <map> +#include <string> + +namespace lldb_private +{ + +class ClangPersistentVariable +{ + friend class ClangPersistentVariables; +public: + ClangPersistentVariable () : + m_user_type(), + m_data() + { + } + + ClangPersistentVariable (const ClangPersistentVariable &pv) : + m_user_type(pv.m_user_type), + m_data(pv.m_data) + { + } + + ClangPersistentVariable &operator=(const ClangPersistentVariable &pv) + { + m_user_type = pv.m_user_type; + m_data = pv.m_data; + return *this; + } + + size_t Size () + { + return (m_user_type.GetClangTypeBitWidth () + 7) / 8; + } + + uint8_t *Data () + { + return m_data->GetBytes(); + } + + TypeFromUser Type () + { + return m_user_type; + } +private: + ClangPersistentVariable (TypeFromUser user_type) + { + m_user_type = user_type; + m_data = lldb::DataBufferSP(new DataBufferHeap(Size(), 0)); + } + TypeFromUser m_user_type; + lldb::DataBufferSP m_data; +}; + +class ClangPersistentVariables +{ +public: + ClangPersistentVariable *CreateVariable (ConstString name, TypeFromUser user_type); + ClangPersistentVariable *CreateResultVariable (TypeFromUser user_type); + ClangPersistentVariable *GetVariable (ConstString name); + + ClangPersistentVariables (); +private: + typedef std::map <ConstString, ClangPersistentVariable> PVarMap; + typedef PVarMap::iterator PVarIterator; + + PVarMap m_variables; + uint64_t m_result_counter; +}; + +} + +#endif
\ No newline at end of file diff --git a/lldb/include/lldb/Expression/IRForTarget.h b/lldb/include/lldb/Expression/IRForTarget.h index 2b55e49c8af..e9dbc94151d 100644 --- a/lldb/include/lldb/Expression/IRForTarget.h +++ b/lldb/include/lldb/Expression/IRForTarget.h @@ -46,6 +46,13 @@ private: bool rewriteObjCSelectors(llvm::Module &M, llvm::BasicBlock &BB); + // pass to find declarations of, and references to, persistent variables and + // register them for (de)materialization + bool RewritePersistentAlloc(llvm::Instruction *persistent_alloc, + llvm::Module &M); + bool rewritePersistentAllocs(llvm::Module &M, + llvm::BasicBlock &BB); + // pass to register referenced variables and redirect functions at their // targets in the debugged process bool MaybeHandleVariable(llvm::Module &M, diff --git a/lldb/include/lldb/Symbol/TaggedASTType.h b/lldb/include/lldb/Symbol/TaggedASTType.h index 6a5061dbf05..e85bee95ac0 100644 --- a/lldb/include/lldb/Symbol/TaggedASTType.h +++ b/lldb/include/lldb/Symbol/TaggedASTType.h @@ -38,6 +38,10 @@ public: } }; +// Commonly-used tagged types, so code using them is interoperable +typedef TaggedASTType<0> TypeFromParser; +typedef TaggedASTType<1> TypeFromUser; + } #endif diff --git a/lldb/include/lldb/Target/Process.h b/lldb/include/lldb/Target/Process.h index d44a00c8c9d..f4961e90fff 100644 --- a/lldb/include/lldb/Target/Process.h +++ b/lldb/include/lldb/Target/Process.h @@ -25,6 +25,7 @@ #include "lldb/Core/ThreadSafeSTLMap.h" #include "lldb/Core/PluginInterface.h" #include "lldb/Breakpoint/BreakpointSiteList.h" +#include "lldb/Expression/ClangPersistentVariables.h" #include "lldb/Target/ExecutionContextScope.h" #include "lldb/Target/ObjCObjectPrinter.h" #include "lldb/Target/ThreadList.h" @@ -1366,6 +1367,9 @@ public: lldb::ProcessSP GetSP (); + ClangPersistentVariables & + GetPersistentVariables(); + ObjCObjectPrinter & GetObjCObjectPrinter(); @@ -1392,6 +1396,7 @@ protected: Listener &m_listener; BreakpointSiteList m_breakpoint_site_list; ///< This is the list of breakpoint locations we intend ///< to insert in the target. + ClangPersistentVariables m_persistent_vars; ///< These are the persistent variables associated with this process for the expression parser. UnixSignals m_unix_signals; /// This is the current signal set for this process. ConstString m_target_triple; lldb::ABISP m_abi_sp; diff --git a/lldb/lldb.xcodeproj/project.pbxproj b/lldb/lldb.xcodeproj/project.pbxproj index 8471b0ca9f3..563199e2a5d 100644 --- a/lldb/lldb.xcodeproj/project.pbxproj +++ b/lldb/lldb.xcodeproj/project.pbxproj @@ -337,6 +337,8 @@ 49A8A3A011D568A300AD3B68 /* ClangResultSynthesizer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49A8A39F11D568A300AD3B68 /* ClangResultSynthesizer.cpp */; }; 49A8A3A411D568BF00AD3B68 /* ClangResultSynthesizer.h in Headers */ = {isa = PBXBuildFile; fileRef = 49A8A3A311D568BF00AD3B68 /* ClangResultSynthesizer.h */; }; 49BB309611F79450001A4197 /* TaggedASTType.h in Headers */ = {isa = PBXBuildFile; fileRef = 49BB309511F79450001A4197 /* TaggedASTType.h */; }; + 49D4FE831210B5FB00CDB854 /* ClangPersistentVariables.h in Headers */ = {isa = PBXBuildFile; fileRef = 49D4FE821210B5FB00CDB854 /* ClangPersistentVariables.h */; }; + 49D4FE891210B61C00CDB854 /* ClangPersistentVariables.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49D4FE871210B61C00CDB854 /* ClangPersistentVariables.cpp */; }; 49D7072711B5AD03001AD875 /* ClangASTSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 49D7072611B5AD03001AD875 /* ClangASTSource.h */; }; 49D7072911B5AD11001AD875 /* ClangASTSource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49D7072811B5AD11001AD875 /* ClangASTSource.cpp */; settings = {COMPILER_FLAGS = "-fno-rtti"; }; }; 49DA743011DE6A5A006AEF7E /* IRToDWARF.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49DA742F11DE6A5A006AEF7E /* IRToDWARF.cpp */; }; @@ -920,6 +922,8 @@ 49BB309511F79450001A4197 /* TaggedASTType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TaggedASTType.h; path = include/lldb/Symbol/TaggedASTType.h; sourceTree = "<group>"; }; 49BF48DC11ADF356008863BD /* ObjCObjectPrinter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ObjCObjectPrinter.cpp; path = source/Target/ObjCObjectPrinter.cpp; sourceTree = "<group>"; }; 49BF48E011ADF37D008863BD /* ObjCObjectPrinter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ObjCObjectPrinter.h; path = include/lldb/Target/ObjCObjectPrinter.h; sourceTree = "<group>"; }; + 49D4FE821210B5FB00CDB854 /* ClangPersistentVariables.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ClangPersistentVariables.h; path = include/lldb/Expression/ClangPersistentVariables.h; sourceTree = "<group>"; }; + 49D4FE871210B61C00CDB854 /* ClangPersistentVariables.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ClangPersistentVariables.cpp; path = source/Expression/ClangPersistentVariables.cpp; sourceTree = "<group>"; }; 49D7072611B5AD03001AD875 /* ClangASTSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ClangASTSource.h; path = include/lldb/Expression/ClangASTSource.h; sourceTree = "<group>"; }; 49D7072811B5AD11001AD875 /* ClangASTSource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ClangASTSource.cpp; path = source/Expression/ClangASTSource.cpp; sourceTree = "<group>"; }; 49DA742F11DE6A5A006AEF7E /* IRToDWARF.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = IRToDWARF.cpp; path = source/Expression/IRToDWARF.cpp; sourceTree = "<group>"; }; @@ -1851,6 +1855,8 @@ 49F1A74511B3388F003ED505 /* ClangExpressionDeclMap.cpp */, 26BC7DC110F1B79500F91463 /* ClangExpressionVariable.h */, 26BC7ED610F1B86700F91463 /* ClangExpressionVariable.cpp */, + 49D4FE821210B5FB00CDB854 /* ClangPersistentVariables.h */, + 49D4FE871210B61C00CDB854 /* ClangPersistentVariables.cpp */, 49A8A3A311D568BF00AD3B68 /* ClangResultSynthesizer.h */, 49A8A39F11D568A300AD3B68 /* ClangResultSynthesizer.cpp */, 26BC7DC210F1B79500F91463 /* ClangStmtVisitor.h */, @@ -2224,6 +2230,7 @@ 264723A611FA076E00DE380C /* CleanUp.h in Headers */, 2615DB851208A9C90021781D /* StopInfo.h in Headers */, 2615DBCB1208B5FC0021781D /* StopInfoMachException.h in Headers */, + 49D4FE831210B5FB00CDB854 /* ClangPersistentVariables.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2680,6 +2687,7 @@ 49E45FAF11F660FE008F7B28 /* ClangASTType.cpp in Sources */, 2615DB871208A9E40021781D /* StopInfo.cpp in Sources */, 2615DBCA1208B5FC0021781D /* StopInfoMachException.cpp in Sources */, + 49D4FE891210B61C00CDB854 /* ClangPersistentVariables.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/lldb/source/Commands/CommandObjectExpression.cpp b/lldb/source/Commands/CommandObjectExpression.cpp index 404dc2a2606..7d83b2c722b 100644 --- a/lldb/source/Commands/CommandObjectExpression.cpp +++ b/lldb/source/Commands/CommandObjectExpression.cpp @@ -19,6 +19,7 @@ #include "lldb/Expression/ClangExpression.h" #include "lldb/Expression/ClangExpressionDeclMap.h" #include "lldb/Expression/ClangExpressionVariable.h" +#include "lldb/Expression/ClangPersistentVariables.h" #include "lldb/Expression/ClangFunction.h" #include "lldb/Expression/DWARFExpression.h" #include "lldb/Host/Host.h" @@ -217,8 +218,7 @@ CommandObjectExpression::EvaluateExpression (const char *expr, bool bare, Stream return false; } - ClangPersistentVariables persistent_vars; /* TODO store this somewhere sensible */ - ClangExpressionDeclMap expr_decl_map (&m_exe_ctx, persistent_vars); + ClangExpressionDeclMap expr_decl_map (&m_exe_ctx); ClangExpression clang_expr (target_triple.AsCString (), &expr_decl_map); ////////////////////////// diff --git a/lldb/source/Expression/ClangExpression.cpp b/lldb/source/Expression/ClangExpression.cpp index 0e103b65efb..467acbd3f8d 100644 --- a/lldb/source/Expression/ClangExpression.cpp +++ b/lldb/source/Expression/ClangExpression.cpp @@ -239,6 +239,7 @@ ClangExpression::CreateCompilerInstance (bool &IsAST) m_clang_ap->getLangOpts().ObjC1 = true; m_clang_ap->getLangOpts().ThreadsafeStatics = false; m_clang_ap->getLangOpts().AccessControl = false; // Debuggers get universal access + m_clang_ap->getLangOpts().DollarIdents = true; // $ indicates a persistent variable name // Set CodeGen options m_clang_ap->getCodeGenOpts().EmitDeclMetadata = true; diff --git a/lldb/source/Expression/ClangExpressionDeclMap.cpp b/lldb/source/Expression/ClangExpressionDeclMap.cpp index b50d68ef64a..da4333c49c7 100644 --- a/lldb/source/Expression/ClangExpressionDeclMap.cpp +++ b/lldb/source/Expression/ClangExpressionDeclMap.cpp @@ -19,6 +19,7 @@ #include "lldb/Core/Log.h" #include "lldb/Core/Module.h" #include "lldb/Expression/ClangASTSource.h" +#include "lldb/Expression/ClangPersistentVariables.h" #include "lldb/Symbol/ClangASTContext.h" #include "lldb/Symbol/CompileUnit.h" #include "lldb/Symbol/Function.h" @@ -36,17 +37,17 @@ using namespace lldb_private; using namespace clang; -ClangExpressionDeclMap::ClangExpressionDeclMap(ExecutionContext *exe_ctx, - ClangPersistentVariables &persistent_vars) : - m_exe_ctx(exe_ctx), - m_persistent_vars(persistent_vars), - m_struct_laid_out(false), +ClangExpressionDeclMap::ClangExpressionDeclMap(ExecutionContext *exe_ctx) : + m_exe_ctx(exe_ctx), m_struct_laid_out(false), m_materialized_location(0) { if (exe_ctx && exe_ctx->frame) m_sym_ctx = new SymbolContext(exe_ctx->frame->GetSymbolContext(lldb::eSymbolContextEverything)); else m_sym_ctx = NULL; + + if (exe_ctx && exe_ctx->process) + m_persistent_vars = &exe_ctx->process->GetPersistentVariables(); } ClangExpressionDeclMap::~ClangExpressionDeclMap() @@ -83,6 +84,31 @@ ClangExpressionDeclMap::GetIndexForDecl (uint32_t &index, // Interface for IRForTarget bool +ClangExpressionDeclMap::AddPersistentVariable (const clang::NamedDecl *decl) +{ + clang::ASTContext *context(m_exe_ctx->target->GetScratchClangASTContext()->getASTContext()); + + const clang::VarDecl *var(dyn_cast<clang::VarDecl>(decl)); + + if (!var) + return false; + + TypeFromUser user_type(ClangASTContext::CopyType(context, + &var->getASTContext(), + var->getType().getAsOpaquePtr()), + context); + + ConstString const_name(decl->getName().str().c_str()); + + ClangPersistentVariable *pvar = m_persistent_vars->CreateVariable(const_name, user_type); + + if (!pvar) + return false; + + return true; +} + +bool ClangExpressionDeclMap::AddValueToStruct (llvm::Value *value, const clang::NamedDecl *decl, std::string &name, @@ -400,33 +426,40 @@ ClangExpressionDeclMap::DoMaterialize (bool dematerialize, if (!GetIndexForDecl(tuple_index, iter->m_decl)) { - if (iter->m_name.find("___clang_expr_result") == std::string::npos) + if (iter->m_name[0] == '$') { - err.SetErrorStringWithFormat("Unexpected variable %s", iter->m_name.c_str()); - return false; + if (!DoMaterializeOnePersistentVariable(dematerialize, *exe_ctx, iter->m_name.c_str(), m_materialized_location + iter->m_offset, err)) + return false; } - - if (log) - log->Printf("Found special result variable %s", iter->m_name.c_str()); - - if (dematerialize) + else if (iter->m_name.find("___clang_expr_result") != std::string::npos) { - clang::ASTContext *context(exe_ctx->target->GetScratchClangASTContext()->getASTContext()); + if (log) + log->Printf("Found special result variable %s", iter->m_name.c_str()); - if (!context) + if (dematerialize) { - err.SetErrorString("Couldn't find a scratch AST context to put the result type into"); + clang::ASTContext *context(exe_ctx->target->GetScratchClangASTContext()->getASTContext()); + + if (!context) + { + err.SetErrorString("Couldn't find a scratch AST context to put the result type into"); + } + + TypeFromUser copied_type(ClangASTContext::CopyType(context, + iter->m_parser_type.GetASTContext(), + iter->m_parser_type.GetOpaqueQualType()), + context); + + result_value->SetContext(Value::eContextTypeOpaqueClangQualType, copied_type.GetOpaqueQualType()); + + result_value->SetValueType(Value::eValueTypeLoadAddress); + result_value->GetScalar() = (uintptr_t)m_materialized_location + iter->m_offset; } - - TypeFromUser copied_type(ClangASTContext::CopyType(context, - iter->m_parser_type.GetASTContext(), - iter->m_parser_type.GetOpaqueQualType()), - context); - - result_value->SetContext(Value::eContextTypeOpaqueClangQualType, copied_type.GetOpaqueQualType()); - - result_value->SetValueType(Value::eValueTypeLoadAddress); - result_value->GetScalar() = (uintptr_t)m_materialized_location + iter->m_offset; + } + else + { + err.SetErrorStringWithFormat("Unexpected variable %s", iter->m_name.c_str()); + return false; } continue; @@ -441,6 +474,50 @@ ClangExpressionDeclMap::DoMaterialize (bool dematerialize, return true; } +bool +ClangExpressionDeclMap::DoMaterializeOnePersistentVariable(bool dematerialize, + ExecutionContext &exe_ctx, + const char *name, + lldb::addr_t addr, + Error &err) +{ + Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS); + + if (log) + log->Printf("Found persistent variable %s", name); + + ClangPersistentVariable *pvar(m_persistent_vars->GetVariable(ConstString(name))); + + if (!pvar) + { + err.SetErrorStringWithFormat("Undefined persistent variable %s", name); + return LLDB_INVALID_ADDRESS; + } + + size_t pvar_size = pvar->Size(); + uint8_t *pvar_data = pvar->Data(); + Error error; + + if (dematerialize) + { + if (exe_ctx.process->ReadMemory (addr, pvar_data, pvar_size, error) != pvar_size) + { + err.SetErrorStringWithFormat ("Couldn't read a composite type from the target: %s", error.AsCString()); + return false; + } + } + else + { + if (exe_ctx.process->WriteMemory (addr, pvar_data, pvar_size, error) != pvar_size) + { + err.SetErrorStringWithFormat ("Couldn't write a composite type to the target: %s", error.AsCString()); + return false; + } + } + + return true; +} + bool ClangExpressionDeclMap::DoMaterializeOneVariable(bool dematerialize, ExecutionContext &exe_ctx, @@ -682,6 +759,11 @@ ClangExpressionDeclMap::GetDecls(NameSearchContext &context, if (var) AddOneVariable(context, var); + ClangPersistentVariable *pvar(m_persistent_vars->GetVariable(ConstString(name))); + + if (pvar) + AddOneVariable(context, pvar); + /* Commented out pending resolution of a loop when the TagType is imported lldb::TypeSP type = m_sym_ctx->FindTypeByName(name_cs); @@ -824,6 +906,20 @@ ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context, } void +ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context, + ClangPersistentVariable *pvar) +{ + TypeFromUser user_type = pvar->Type(); + + TypeFromParser parser_type(ClangASTContext::CopyType(context.GetASTContext(), + user_type.GetASTContext(), + user_type.GetOpaqueQualType()), + context.GetASTContext()); + + (void)context.AddVarDecl(parser_type.GetOpaqueQualType()); +} + +void ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context, Function* fun, Symbol* symbol) diff --git a/lldb/source/Expression/ClangPersistentVariables.cpp b/lldb/source/Expression/ClangPersistentVariables.cpp new file mode 100644 index 00000000000..dbeac006250 --- /dev/null +++ b/lldb/source/Expression/ClangPersistentVariables.cpp @@ -0,0 +1,59 @@ +//===-- ClangPersistentVariables.cpp ----------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "ClangPersistentVariables.h" +#include "lldb/Core/Log.h" +#include "lldb/Core/StreamString.h" + +using namespace lldb_private; +using namespace clang; + +ClangPersistentVariables::ClangPersistentVariables () : + m_variables(), + m_result_counter(0) +{ +} + +ClangPersistentVariable * +ClangPersistentVariables::CreateVariable (ConstString name, + TypeFromUser user_type) +{ + ClangPersistentVariable new_var(user_type); + + if (m_variables.find(name) != m_variables.end()) + return NULL; + + m_variables[name] = new_var; + + return &m_variables[name]; +} + +ClangPersistentVariable * +ClangPersistentVariables::CreateResultVariable (TypeFromUser user_type) +{ + StreamString s; + s.Printf("$%llu", m_result_counter); + ConstString name(s.GetString().c_str()); + + ClangPersistentVariable *ret = CreateVariable (name, user_type); + + if (ret != NULL) + ++m_result_counter; + + return ret; +} + +ClangPersistentVariable * +ClangPersistentVariables::GetVariable (ConstString name) +{ + if (m_variables.find(name) == m_variables.end()) + return NULL; + + return &m_variables[name]; +} diff --git a/lldb/source/Expression/IRForTarget.cpp b/lldb/source/Expression/IRForTarget.cpp index 4f3a740e0bb..9541945eebc 100644 --- a/lldb/source/Expression/IRForTarget.cpp +++ b/lldb/source/Expression/IRForTarget.cpp @@ -37,6 +37,20 @@ IRForTarget::IRForTarget(const void *pid, { } +/* A handy utility function used at several places in the code */ + +static std::string +PrintValue(Value *V, bool truncate = false) +{ + std::string s; + raw_string_ostream rso(s); + V->print(rso); + rso.flush(); + if (truncate) + s.resize(s.length() - 1); + return s; +} + IRForTarget::~IRForTarget() { } @@ -200,6 +214,97 @@ IRForTarget::rewriteObjCSelectors(Module &M, return true; } +bool +IRForTarget::RewritePersistentAlloc(llvm::Instruction *persistent_alloc, + llvm::Module &M) +{ + AllocaInst *alloc = dyn_cast<AllocaInst>(persistent_alloc); + + MDNode *alloc_md = alloc->getMetadata("clang.decl.ptr"); + + if (!alloc_md || !alloc_md->getNumOperands()) + return false; + + ConstantInt *constant_int = dyn_cast<ConstantInt>(alloc_md->getOperand(0)); + + if (!constant_int) + return false; + + // We attempt to register this as a new persistent variable with the DeclMap. + + uintptr_t ptr = constant_int->getZExtValue(); + + clang::NamedDecl *decl = reinterpret_cast<clang::NamedDecl *>(ptr); + + if (!m_decl_map->AddPersistentVariable(decl)) + return false; + + GlobalVariable *persistent_global = new GlobalVariable(M, + alloc->getType()->getElementType(), + false, /* not constant */ + GlobalValue::ExternalLinkage, + NULL, /* no initializer */ + alloc->getName().str().c_str()); + + // What we're going to do here is make believe this was a regular old external + // variable. That means we need to make the metadata valid. + + NamedMDNode *named_metadata = M.getNamedMetadata("clang.global.decl.ptrs"); + + llvm::Value* values[2]; + values[0] = persistent_global; + values[1] = constant_int; + + MDNode *persistent_global_md = MDNode::get(M.getContext(), values, 2); + named_metadata->addOperand(persistent_global_md); + + alloc->replaceAllUsesWith(persistent_global); + alloc->eraseFromParent(); + + return true; +} + +bool +IRForTarget::rewritePersistentAllocs(llvm::Module &M, + llvm::BasicBlock &BB) +{ + lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS); + + BasicBlock::iterator ii; + + typedef SmallVector <Instruction*, 2> InstrList; + typedef InstrList::iterator InstrIterator; + + InstrList pvar_allocs; + + for (ii = BB.begin(); + ii != BB.end(); + ++ii) + { + Instruction &inst = *ii; + + if (AllocaInst *alloc = dyn_cast<AllocaInst>(&inst)) + if (alloc->getName().startswith("$")) + pvar_allocs.push_back(alloc); + } + + InstrIterator iter; + + for (iter = pvar_allocs.begin(); + iter != pvar_allocs.end(); + ++iter) + { + if (!RewritePersistentAlloc(*iter, M)) + { + if(log) + log->PutCString("Couldn't rewrite the creation of a persistent variable"); + return false; + } + } + + return true; +} + static clang::NamedDecl * DeclForGlobalValue(Module &module, GlobalValue *global_value) @@ -222,7 +327,7 @@ DeclForGlobalValue(Module &module, return NULL; if (metadata_node->getNumOperands() != 2) - return NULL; + continue; if (metadata_node->getOperand(0) != global_value) continue; @@ -400,18 +505,6 @@ IRForTarget::resolveExternals(Module &M, BasicBlock &BB) return true; } -static std::string -PrintValue(Value *V, bool truncate = false) -{ - std::string s; - raw_string_ostream rso(s); - V->print(rso); - rso.flush(); - if (truncate) - s.resize(s.length() - 1); - return s; -} - static bool isGuardVariableRef(Value *V) { ConstantExpr *C = dyn_cast<ConstantExpr>(V); @@ -518,12 +611,21 @@ UnfoldConstant(Constant *C, Value *new_value, Instruction *first_entry_instructi Value::use_iterator ui; + SmallVector<User*, 16> users; + + // We do this because the use list might change, invalidating our iterator. + // Much better to keep a work list ourselves. for (ui = C->use_begin(); ui != C->use_end(); ++ui) - { - User *user = *ui; + users.push_back(*ui); + for (int i = 0; + i < users.size(); + ++i) + { + User *user = users[i]; + if (Constant *constant = dyn_cast<Constant>(user)) { // synthesize a new non-constant equivalent of the constant @@ -703,9 +805,12 @@ IRForTarget::runOnModule(Module &M) bbi != function->end(); ++bbi) { - if (!rewriteObjCSelectors(M, *bbi)) + if (!rewritePersistentAllocs(M, *bbi)) return false; + if (!rewriteObjCSelectors(M, *bbi)) + return false; + if (!resolveExternals(M, *bbi)) return false; @@ -713,13 +818,6 @@ IRForTarget::runOnModule(Module &M) return false; } - /////////////////////////////// - // Run function-level passes - // - - if (!replaceVariables(M, *function)) - return false; - if (log) { std::string s; @@ -732,6 +830,13 @@ IRForTarget::runOnModule(Module &M) log->Printf("Module after preparing for execution: \n%s", s.c_str()); } + /////////////////////////////// + // Run function-level passes + // + + if (!replaceVariables(M, *function)) + return false; + return true; } diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp index 1a1f93c2ada..3171c94652f 100644 --- a/lldb/source/Target/Process.cpp +++ b/lldb/source/Target/Process.cpp @@ -80,7 +80,8 @@ Process::Process(Target &target, Listener &listener) : m_notifications (), m_listener(listener), m_unix_signals (), - m_objc_object_printer(*this) + m_objc_object_printer(*this), + m_persistent_vars() { Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT); if (log) @@ -1882,6 +1883,12 @@ Process::GetSP () return GetTarget().GetProcessSP(); } +ClangPersistentVariables & +Process::GetPersistentVariables() +{ + return m_persistent_vars; +} + ObjCObjectPrinter & Process::GetObjCObjectPrinter() { |