diff options
Diffstat (limited to 'source/Expression')
-rw-r--r-- | source/Expression/ClangASTSource.cpp | 239 | ||||
-rw-r--r-- | source/Expression/ClangExpressionDeclMap.cpp | 51 | ||||
-rw-r--r-- | source/Expression/ClangExpressionParser.cpp | 83 | ||||
-rw-r--r-- | source/Expression/ClangExpressionVariable.cpp | 11 | ||||
-rw-r--r-- | source/Expression/ClangFunction.cpp | 22 | ||||
-rw-r--r-- | source/Expression/ClangModulesDeclVendor.cpp | 372 | ||||
-rw-r--r-- | source/Expression/ClangUserExpression.cpp | 25 | ||||
-rw-r--r-- | source/Expression/DWARFExpression.cpp | 7 | ||||
-rw-r--r-- | source/Expression/IRExecutionUnit.cpp | 128 | ||||
-rw-r--r-- | source/Expression/IRForTarget.cpp | 54 |
10 files changed, 748 insertions, 244 deletions
diff --git a/source/Expression/ClangASTSource.cpp b/source/Expression/ClangASTSource.cpp index d488993b90d7..9a6d6e532255 100644 --- a/source/Expression/ClangASTSource.cpp +++ b/source/Expression/ClangASTSource.cpp @@ -708,6 +708,8 @@ ClangASTSource::FindExternalVisibleDecls (NameSearchContext &context, else m_target->GetImages().FindTypes(null_sc, name, exact_match, 1, types); + bool found_a_type = false; + if (types.GetSize()) { lldb::TypeSP type_sp = types.GetTypeAtIndex(0); @@ -736,8 +738,62 @@ ClangASTSource::FindExternalVisibleDecls (NameSearchContext &context, } context.AddTypeDecl(copied_clang_type); + + found_a_type = true; } - else + + if (!found_a_type) + { + // 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; + + if (log) + { + log->Printf(" CAS::FEVD[%u] Matching entity found for \"%s\" in the modules", + current_id, + name.GetCString()); + } + + clang::NamedDecl *const decl_from_modules = decls[0]; + + if (llvm::isa<clang::TypeDecl>(decl_from_modules) || + llvm::isa<clang::ObjCContainerDecl>(decl_from_modules) || + llvm::isa<clang::EnumConstantDecl>(decl_from_modules)) + { + clang::Decl *copied_decl = m_ast_importer->CopyDecl(m_ast_context, &decl_from_modules->getASTContext(), decl_from_modules); + clang::NamedDecl *copied_named_decl = copied_decl ? dyn_cast<clang::NamedDecl>(copied_decl) : nullptr; + + if (!copied_named_decl) + { + if (log) + log->Printf(" CAS::FEVD[%u] - Couldn't export a type from the modules", + current_id); + + break; + } + + context.AddNamedDecl(copied_named_decl); + + found_a_type = true; + } + } + } while (0); + } + + if (!found_a_type) { do { @@ -753,19 +809,19 @@ ClangASTSource::FindExternalVisibleDecls (NameSearchContext &context, if (!language_runtime) break; - TypeVendor *type_vendor = language_runtime->GetTypeVendor(); + DeclVendor *decl_vendor = language_runtime->GetDeclVendor(); - if (!type_vendor) + if (!decl_vendor) break; bool append = false; uint32_t max_matches = 1; - std::vector <ClangASTType> types; + std::vector <clang::NamedDecl *> decls; - if (!type_vendor->FindTypes(name, + if (!decl_vendor->FindDecls(name, append, max_matches, - types)) + decls)) break; if (log) @@ -774,10 +830,11 @@ ClangASTSource::FindExternalVisibleDecls (NameSearchContext &context, current_id, name.GetCString()); } - - ClangASTType copied_clang_type (GuardedCopyType(types[0])); - - if (!copied_clang_type) + + clang::Decl *copied_decl = m_ast_importer->CopyDecl(m_ast_context, &decls[0]->getASTContext(), decls[0]); + clang::NamedDecl *copied_named_decl = copied_decl ? dyn_cast<clang::NamedDecl>(copied_decl) : nullptr; + + if (!copied_named_decl) { if (log) log->Printf(" CAS::FEVD[%u] - Couldn't export a type from the runtime", @@ -786,7 +843,7 @@ ClangASTSource::FindExternalVisibleDecls (NameSearchContext &context, break; } - context.AddTypeDecl(copied_clang_type); + context.AddNamedDecl(copied_named_decl); } while(0); } @@ -895,31 +952,44 @@ FindObjCMethodDeclsWithOrigin (unsigned int current_id, } DeclarationName original_decl_name(original_selector); - - ObjCInterfaceDecl::lookup_result result = original_interface_decl->lookup(original_decl_name); - - if (result.empty()) - return false; - - if (!result[0]) + + llvm::SmallVector<NamedDecl *, 1> methods; + + ClangASTContext::GetCompleteDecl(original_ctx, original_interface_decl); + + if (ObjCMethodDecl *instance_method_decl = original_interface_decl->lookupInstanceMethod(original_selector)) + { + methods.push_back(instance_method_decl); + } + else if (ObjCMethodDecl *class_method_decl = original_interface_decl->lookupClassMethod(original_selector)) + { + methods.push_back(class_method_decl); + } + + if (methods.empty()) + { return false; - - for (NamedDecl *named_decl : result) + } + + for (NamedDecl *named_decl : methods) { + if (!named_decl) + continue; + ObjCMethodDecl *result_method = dyn_cast<ObjCMethodDecl>(named_decl); if (!result_method) - return false; + continue; Decl *copied_decl = ast_importer->CopyDecl(ast_context, &result_method->getASTContext(), result_method); if (!copied_decl) - return false; + continue; ObjCMethodDecl *copied_method_decl = dyn_cast<ObjCMethodDecl>(copied_decl); if (!copied_method_decl) - return false; + continue; Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); @@ -1169,10 +1239,43 @@ ClangASTSource::FindObjCMethodDecls (NameSearchContext &context) return; } while (0); + + do + { + // Check the modules only if the debug information didn't have a complete interface. + + if (ClangModulesDeclVendor *modules_decl_vendor = m_target->GetClangModulesDeclVendor()) + { + ConstString interface_name(interface_decl->getNameAsString().c_str()); + bool append = false; + uint32_t max_matches = 1; + std::vector <clang::NamedDecl *> decls; + + if (!modules_decl_vendor->FindDecls(interface_name, + append, + max_matches, + decls)) + break; + + ObjCInterfaceDecl *interface_decl_from_modules = dyn_cast<ObjCInterfaceDecl>(decls[0]); + + if (!interface_decl_from_modules) + break; + + if (FindObjCMethodDeclsWithOrigin(current_id, + context, + interface_decl_from_modules, + m_ast_context, + m_ast_importer, + "in modules")) + return; + } + } + while (0); do { - // Check the runtime only if the debug information didn't have a complete interface. + // Check the runtime only if the debug information didn't have a complete interface and the modules don't get us anywhere. lldb::ProcessSP process(m_target->GetProcessSP()); @@ -1184,31 +1287,27 @@ ClangASTSource::FindObjCMethodDecls (NameSearchContext &context) if (!language_runtime) break; - TypeVendor *type_vendor = language_runtime->GetTypeVendor(); + DeclVendor *decl_vendor = language_runtime->GetDeclVendor(); - if (!type_vendor) + if (!decl_vendor) break; ConstString interface_name(interface_decl->getNameAsString().c_str()); bool append = false; uint32_t max_matches = 1; - std::vector <ClangASTType> types; + std::vector <clang::NamedDecl *> decls; - if (!type_vendor->FindTypes(interface_name, + if (!decl_vendor->FindDecls(interface_name, append, max_matches, - types)) + decls)) break; - const clang::Type *runtime_clang_type = QualType::getFromOpaquePtr(types[0].GetOpaqueQualType()).getTypePtr(); - - const ObjCInterfaceType *runtime_interface_type = dyn_cast<ObjCInterfaceType>(runtime_clang_type); - - if (!runtime_interface_type) + ObjCInterfaceDecl *runtime_interface_decl = dyn_cast<ObjCInterfaceDecl>(decls[0]); + + if (!runtime_interface_decl) break; - ObjCInterfaceDecl *runtime_interface_decl = runtime_interface_type->getDecl(); - FindObjCMethodDeclsWithOrigin(current_id, context, runtime_interface_decl, @@ -1339,10 +1438,50 @@ ClangASTSource::FindObjCPropertyAndIvarDecls (NameSearchContext &context) return; } while(0); + + do + { + // Check the modules only if the debug information didn't have a complete interface. + + ClangModulesDeclVendor *modules_decl_vendor = m_target->GetClangModulesDeclVendor(); + + if (!modules_decl_vendor) + break; + + bool append = false; + uint32_t max_matches = 1; + std::vector <clang::NamedDecl *> decls; + + if (!modules_decl_vendor->FindDecls(class_name, + append, + max_matches, + decls)) + break; + + DeclFromUser<const ObjCInterfaceDecl> interface_decl_from_modules(dyn_cast<ObjCInterfaceDecl>(decls[0])); + + if (!interface_decl_from_modules.IsValid()) + break; + + if (log) + log->Printf("CAS::FOPD[%d] trying module (ObjCInterfaceDecl*)%p/(ASTContext*)%p...", + current_id, + static_cast<const void*>(interface_decl_from_modules.decl), + static_cast<void*>(&interface_decl_from_modules->getASTContext())); + + if (FindObjCPropertyAndIvarDeclsWithOrigin(current_id, + context, + *m_ast_context, + m_ast_importer, + interface_decl_from_modules)) + return; + } + while(0); do { - // Check the runtime only if the debug information didn't have a complete interface. + // Check the runtime only if the debug information didn't have a complete interface + // and nothing was in the modules. lldb::ProcessSP process(m_target->GetProcessSP()); @@ -1354,41 +1493,37 @@ ClangASTSource::FindObjCPropertyAndIvarDecls (NameSearchContext &context) if (!language_runtime) return; - TypeVendor *type_vendor = language_runtime->GetTypeVendor(); + DeclVendor *decl_vendor = language_runtime->GetDeclVendor(); - if (!type_vendor) + if (!decl_vendor) break; bool append = false; uint32_t max_matches = 1; - std::vector <ClangASTType> types; + std::vector <clang::NamedDecl *> decls; - if (!type_vendor->FindTypes(class_name, + if (!decl_vendor->FindDecls(class_name, append, max_matches, - types)) + decls)) break; - const clang::Type *runtime_clang_type = QualType::getFromOpaquePtr(types[0].GetOpaqueQualType()).getTypePtr(); - - const ObjCInterfaceType *runtime_interface_type = dyn_cast<ObjCInterfaceType>(runtime_clang_type); - - if (!runtime_interface_type) + DeclFromUser<const ObjCInterfaceDecl> interface_decl_from_runtime(dyn_cast<ObjCInterfaceDecl>(decls[0])); + + if (!interface_decl_from_runtime.IsValid()) break; - DeclFromUser<const ObjCInterfaceDecl> runtime_iface_decl(runtime_interface_type->getDecl()); - if (log) log->Printf("CAS::FOPD[%d] trying runtime (ObjCInterfaceDecl*)%p/(ASTContext*)%p...", current_id, - static_cast<const void*>(runtime_iface_decl.decl), - static_cast<void*>(&runtime_iface_decl->getASTContext())); + static_cast<const void*>(interface_decl_from_runtime.decl), + static_cast<void*>(&interface_decl_from_runtime->getASTContext())); if (FindObjCPropertyAndIvarDeclsWithOrigin(current_id, context, *m_ast_context, m_ast_importer, - runtime_iface_decl)) + interface_decl_from_runtime)) return; } while(0); diff --git a/source/Expression/ClangExpressionDeclMap.cpp b/source/Expression/ClangExpressionDeclMap.cpp index 43c8a5fb1bcb..e3027378422f 100644 --- a/source/Expression/ClangExpressionDeclMap.cpp +++ b/source/Expression/ClangExpressionDeclMap.cpp @@ -36,6 +36,7 @@ #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" @@ -543,6 +544,7 @@ ClangExpressionDeclMap::GetFunctionAddress FindCodeSymbolInContext(name, m_parser_vars->m_sym_ctx, sc_list); uint32_t sc_list_size = sc_list.GetSize(); + if (sc_list_size == 0) { // We occasionally get debug information in which a const function is reported @@ -562,6 +564,25 @@ ClangExpressionDeclMap::GetFunctionAddress sc_list_size = sc_list.GetSize(); } } + + if (sc_list_size == 0) + { + // Sometimes we get a mangled name for a global function that actually should be "extern C." + // This is a hack to compensate. + + const bool is_mangled = true; + Mangled mangled(name, is_mangled); + + CPPLanguageRuntime::MethodName method_name(mangled.GetDemangledName()); + + llvm::StringRef basename = method_name.GetBasename(); + + if (!basename.empty()) + { + FindCodeSymbolInContext(ConstString(basename), m_parser_vars->m_sym_ctx, sc_list); + sc_list_size = sc_list.GetSize(); + } + } for (uint32_t i=0; i<sc_list_size; ++i) { @@ -1274,10 +1295,9 @@ ClangExpressionDeclMap::FindExternalVisibleDecls (NameSearchContext &context, { valobj = frame->GetValueForVariableExpressionPath(name_unique_cstr, eNoDynamicValues, - StackFrame::eExpressionPathOptionCheckPtrVsMember || - StackFrame::eExpressionPathOptionsAllowDirectIVarAccess || - StackFrame::eExpressionPathOptionsNoFragileObjcIvar || - StackFrame::eExpressionPathOptionsNoSyntheticChildren || + StackFrame::eExpressionPathOptionCheckPtrVsMember | + StackFrame::eExpressionPathOptionsNoFragileObjcIvar | + StackFrame::eExpressionPathOptionsNoSyntheticChildren | StackFrame::eExpressionPathOptionsNoSyntheticArrayRange, var, err); @@ -1307,6 +1327,16 @@ ClangExpressionDeclMap::FindExternalVisibleDecls (NameSearchContext &context, 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) { @@ -1384,6 +1414,19 @@ ClangExpressionDeclMap::FindExternalVisibleDecls (NameSearchContext &context, 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->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) { diff --git a/source/Expression/ClangExpressionParser.cpp b/source/Expression/ClangExpressionParser.cpp index f32ca3ae216c..4906108401af 100644 --- a/source/Expression/ClangExpressionParser.cpp +++ b/source/Expression/ClangExpressionParser.cpp @@ -22,6 +22,7 @@ #include "lldb/Expression/ClangASTSource.h" #include "lldb/Expression/ClangExpression.h" #include "lldb/Expression/ClangExpressionDeclMap.h" +#include "lldb/Expression/ClangModulesDeclVendor.h" #include "lldb/Expression/IRExecutionUnit.h" #include "lldb/Expression/IRDynamicChecks.h" #include "lldb/Expression/IRInterpreter.h" @@ -92,6 +93,47 @@ std::string GetBuiltinIncludePath(const char *Argv0) { return P.str(); } +class ClangExpressionParser::LLDBPreprocessorCallbacks : public PPCallbacks +{ + ClangModulesDeclVendor &m_decl_vendor; + StreamString m_error_stream; + bool m_has_errors = false; +public: + LLDBPreprocessorCallbacks(ClangModulesDeclVendor &decl_vendor) : + m_decl_vendor(decl_vendor) + { + } + + virtual void moduleImport(SourceLocation import_location, + ModuleIdPath path, + const clang::Module * /*null*/) + { + std::vector<llvm::StringRef> string_path; + + for (const std::pair<IdentifierInfo *, SourceLocation> &component : path) + { + string_path.push_back(component.first->getName()); + } + + StreamString error_stream; + + if (!m_decl_vendor.AddModule(string_path, m_error_stream)) + { + m_has_errors = true; + } + } + + bool hasErrors() + { + return m_has_errors; + } + + const std::string &getErrorString() + { + return m_error_stream.GetString(); + } +}; + //===----------------------------------------------------------------------===// // Implementation of ClangExpressionParser //===----------------------------------------------------------------------===// @@ -101,7 +143,8 @@ ClangExpressionParser::ClangExpressionParser (ExecutionContextScope *exe_scope, bool generate_debug_info) : m_expr (expr), m_compiler (), - m_code_generator () + m_code_generator (), + m_pp_callbacks(nullptr) { // 1. Create a new compiler instance. m_compiler.reset(new CompilerInstance()); @@ -165,6 +208,7 @@ ClangExpressionParser::ClangExpressionParser (ExecutionContextScope *exe_scope, case lldb::eLanguageTypeC_plus_plus: m_compiler->getLangOpts().CPlusPlus = true; m_compiler->getLangOpts().CPlusPlus11 = true; + m_compiler->getHeaderSearchOpts().UseLibcxx = true; break; case lldb::eLanguageTypeObjC_plus_plus: default: @@ -172,6 +216,7 @@ ClangExpressionParser::ClangExpressionParser (ExecutionContextScope *exe_scope, m_compiler->getLangOpts().ObjC2 = true; m_compiler->getLangOpts().CPlusPlus = true; m_compiler->getLangOpts().CPlusPlus11 = true; + m_compiler->getHeaderSearchOpts().UseLibcxx = true; break; } @@ -246,7 +291,14 @@ ClangExpressionParser::ClangExpressionParser (ExecutionContextScope *exe_scope, m_compiler->createFileManager(); m_compiler->createPreprocessor(TU_Complete); - + + if (ClangModulesDeclVendor *decl_vendor = target_sp->GetClangModulesDeclVendor()) + { + std::unique_ptr<PPCallbacks> pp_callbacks(new LLDBPreprocessorCallbacks(*decl_vendor)); + m_pp_callbacks = static_cast<LLDBPreprocessorCallbacks*>(pp_callbacks.get()); + m_compiler->getPreprocessor().addPPCallbacks(std::move(pp_callbacks)); + } + // 6. Most of this we get from the CompilerInstance, but we // also want to give the context an ExternalASTSource. m_selector_table.reset(new SelectorTable()); @@ -257,6 +309,7 @@ ClangExpressionParser::ClangExpressionParser (ExecutionContextScope *exe_scope, m_compiler->getPreprocessor().getIdentifierTable(), *m_selector_table.get(), *m_builtin_context.get())); + ast_context->InitBuiltinTypes(m_compiler->getTarget()); ClangExpressionDeclMap *decl_map = m_expr.DeclMap(); @@ -299,22 +352,23 @@ ClangExpressionParser::Parse (Stream &stream) { std::string temp_source_path; + int temp_fd = -1; + llvm::SmallString<PATH_MAX> result_path; FileSpec tmpdir_file_spec; if (HostInfo::GetLLDBPath(lldb::ePathTypeLLDBTempSystemDir, tmpdir_file_spec)) { - tmpdir_file_spec.AppendPathComponent("expr.XXXXXX"); + tmpdir_file_spec.AppendPathComponent("lldb-%%%%%%.expr"); temp_source_path = std::move(tmpdir_file_spec.GetPath()); + llvm::sys::fs::createUniqueFile(temp_source_path, temp_fd, result_path); } else { - temp_source_path = "/tmp/expr.XXXXXX"; + llvm::sys::fs::createTemporaryFile("lldb", "expr", temp_fd, result_path); } - - if (mktemp(&temp_source_path[0])) + + if (temp_fd != -1) { - lldb_private::File file (temp_source_path.c_str(), - File::eOpenOptionWrite | File::eOpenOptionCanCreateNewOnly, - lldb::eFilePermissionsFileDefault); + lldb_private::File file (temp_fd, true); const size_t expr_text_len = strlen(expr_text); size_t bytes_written = expr_text_len; if (file.Write(expr_text, bytes_written).Success()) @@ -323,7 +377,7 @@ ClangExpressionParser::Parse (Stream &stream) { file.Close(); SourceMgr.setMainFileID(SourceMgr.createFileID( - m_file_manager->getFile(temp_source_path), + m_file_manager->getFile(result_path), SourceLocation(), SrcMgr::C_User)); created_main_file = true; } @@ -351,14 +405,19 @@ ClangExpressionParser::Parse (Stream &stream) TextDiagnosticBuffer::const_iterator diag_iterator; int num_errors = 0; + + if (m_pp_callbacks && m_pp_callbacks->hasErrors()) + { + num_errors++; + + stream.PutCString(m_pp_callbacks->getErrorString().c_str()); + } for (diag_iterator = diag_buf->warn_begin(); diag_iterator != diag_buf->warn_end(); ++diag_iterator) stream.Printf("warning: %s\n", (*diag_iterator).second.c_str()); - num_errors = 0; - for (diag_iterator = diag_buf->err_begin(); diag_iterator != diag_buf->err_end(); ++diag_iterator) diff --git a/source/Expression/ClangExpressionVariable.cpp b/source/Expression/ClangExpressionVariable.cpp index c3eae41473e9..e86016e53a7d 100644 --- a/source/Expression/ClangExpressionVariable.cpp +++ b/source/Expression/ClangExpressionVariable.cpp @@ -28,6 +28,17 @@ ClangExpressionVariable::ClangExpressionVariable(ExecutionContextScope *exe_scop { } +ClangExpressionVariable::ClangExpressionVariable (ExecutionContextScope *exe_scope, + Value &value, + const ConstString &name, + uint16_t flags) : + m_parser_vars(), + m_jit_vars (), + m_flags (flags), + m_frozen_sp (ValueObjectConstResult::Create (exe_scope, value, name)) +{ +} + ClangExpressionVariable::ClangExpressionVariable (const lldb::ValueObjectSP &valobj_sp) : m_parser_vars(), m_jit_vars (), diff --git a/source/Expression/ClangFunction.cpp b/source/Expression/ClangFunction.cpp index 27afba2898ab..b438dacdfabc 100644 --- a/source/Expression/ClangFunction.cpp +++ b/source/Expression/ClangFunction.cpp @@ -57,8 +57,8 @@ ClangFunction::ClangFunction const ValueList &arg_value_list, const char *name ) : - m_parser(), m_execution_unit_sp(), + m_parser(), m_jit_module_wp(), m_name (name ? name : "<unknown>"), m_function_ptr (NULL), @@ -422,7 +422,7 @@ ClangFunction::InsertFunction (ExecutionContext &exe_ctx, lldb::addr_t &args_add return true; } -ThreadPlan * +lldb::ThreadPlanSP ClangFunction::GetThreadPlanToCallFunction (ExecutionContext &exe_ctx, lldb::addr_t args_addr, const EvaluateExpressionOptions &options, @@ -447,14 +447,14 @@ ClangFunction::GetThreadPlanToCallFunction (ExecutionContext &exe_ctx, lldb::addr_t args = { args_addr }; - ThreadPlan *new_plan = new ThreadPlanCallFunction (*thread, + lldb::ThreadPlanSP new_plan_sp (new ThreadPlanCallFunction (*thread, wrapper_address, ClangASTType(), args, - options); - new_plan->SetIsMasterPlan(true); - new_plan->SetOkayToDiscard (false); - return new_plan; + options)); + new_plan_sp->SetIsMasterPlan(true); + new_plan_sp->SetOkayToDiscard (false); + return new_plan_sp; } bool @@ -541,10 +541,10 @@ ClangFunction::ExecuteFunction( if (log) log->Printf("== [ClangFunction::ExecuteFunction] Executing function \"%s\" ==", m_name.c_str()); - lldb::ThreadPlanSP call_plan_sp (GetThreadPlanToCallFunction (exe_ctx, - args_addr, - real_options, - errors)); + lldb::ThreadPlanSP call_plan_sp = GetThreadPlanToCallFunction (exe_ctx, + args_addr, + real_options, + errors); if (!call_plan_sp) return lldb::eExpressionSetupError; diff --git a/source/Expression/ClangModulesDeclVendor.cpp b/source/Expression/ClangModulesDeclVendor.cpp new file mode 100644 index 000000000000..46adaaff33ce --- /dev/null +++ b/source/Expression/ClangModulesDeclVendor.cpp @@ -0,0 +1,372 @@ +//===-- ClangModulesDeclVendor.cpp ------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lldb/Core/StreamString.h" +#include "lldb/Expression/ClangModulesDeclVendor.h" +#include "lldb/Host/FileSpec.h" +#include "lldb/Host/Host.h" +#include "lldb/Host/HostInfo.h" +#include "lldb/Target/Target.h" + +#include "clang/Basic/TargetInfo.h" +#include "clang/Frontend/CompilerInstance.h" +#include "clang/Frontend/FrontendActions.h" +#include "clang/Lex/Preprocessor.h" +#include "clang/Parse/Parser.h" +#include "clang/Sema/Lookup.h" +#include "clang/Serialization/ASTReader.h" + +#include <mutex> + +using namespace lldb_private; + +namespace { + // Any Clang compiler requires a consumer for diagnostics. This one stores them as strings + // so we can provide them to the user in case a module failed to load. + class StoringDiagnosticConsumer : public clang::DiagnosticConsumer + { + public: + StoringDiagnosticConsumer (); + void + HandleDiagnostic (clang::DiagnosticsEngine::Level DiagLevel, const clang::Diagnostic &info); + + void + ClearDiagnostics (); + + void + DumpDiagnostics (Stream &error_stream); + private: + typedef std::pair<clang::DiagnosticsEngine::Level, std::string> IDAndDiagnostic; + std::vector<IDAndDiagnostic> m_diagnostics; + Log * m_log; + }; + + // The private implementation of our ClangModulesDeclVendor. Contains all the Clang state required + // to load modules. + class ClangModulesDeclVendorImpl : public ClangModulesDeclVendor + { + public: + ClangModulesDeclVendorImpl(llvm::IntrusiveRefCntPtr<clang::DiagnosticsEngine> &diagnostics_engine, + llvm::IntrusiveRefCntPtr<clang::CompilerInvocation> &compiler_invocation, + std::unique_ptr<clang::CompilerInstance> &&compiler_instance, + std::unique_ptr<clang::Parser> &&parser); + + virtual bool + AddModule(std::vector<llvm::StringRef> &path, + Stream &error_stream); + + virtual uint32_t + FindDecls (const ConstString &name, + bool append, + uint32_t max_matches, + std::vector <clang::NamedDecl*> &decls); + + ~ClangModulesDeclVendorImpl(); + + private: + clang::ModuleLoadResult + DoGetModule(clang::ModuleIdPath path, bool make_visible); + + llvm::IntrusiveRefCntPtr<clang::DiagnosticsEngine> m_diagnostics_engine; + llvm::IntrusiveRefCntPtr<clang::CompilerInvocation> m_compiler_invocation; + std::unique_ptr<clang::CompilerInstance> m_compiler_instance; + std::unique_ptr<clang::Parser> m_parser; + }; +} + +StoringDiagnosticConsumer::StoringDiagnosticConsumer () +{ + m_log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS); +} + +void +StoringDiagnosticConsumer::HandleDiagnostic (clang::DiagnosticsEngine::Level DiagLevel, const clang::Diagnostic &info) +{ + llvm::SmallVector<char, 256> diagnostic_string; + + info.FormatDiagnostic(diagnostic_string); + + m_diagnostics.push_back(IDAndDiagnostic(DiagLevel, std::string(diagnostic_string.data(), diagnostic_string.size()))); +} + +void +StoringDiagnosticConsumer::ClearDiagnostics () +{ + m_diagnostics.clear(); +} + +void +StoringDiagnosticConsumer::DumpDiagnostics (Stream &error_stream) +{ + for (IDAndDiagnostic &diag : m_diagnostics) + { + switch (diag.first) + { + default: + error_stream.PutCString(diag.second.c_str()); + error_stream.PutChar('\n'); + break; + case clang::DiagnosticsEngine::Level::Ignored: + break; + } + } +} + +static FileSpec +GetResourceDir () +{ + static FileSpec g_cached_resource_dir; + + static std::once_flag g_once_flag; + + std::call_once(g_once_flag, [](){ + HostInfo::GetLLDBPath (lldb::ePathTypeClangDir, g_cached_resource_dir); + }); + + return g_cached_resource_dir; +} + + +ClangModulesDeclVendor::ClangModulesDeclVendor() +{ +} + +ClangModulesDeclVendor::~ClangModulesDeclVendor() +{ +} + +ClangModulesDeclVendorImpl::ClangModulesDeclVendorImpl(llvm::IntrusiveRefCntPtr<clang::DiagnosticsEngine> &diagnostics_engine, + llvm::IntrusiveRefCntPtr<clang::CompilerInvocation> &compiler_invocation, + std::unique_ptr<clang::CompilerInstance> &&compiler_instance, + std::unique_ptr<clang::Parser> &&parser) : + ClangModulesDeclVendor(), + m_diagnostics_engine(diagnostics_engine), + m_compiler_invocation(compiler_invocation), + m_compiler_instance(std::move(compiler_instance)), + m_parser(std::move(parser)) +{ +} + +bool +ClangModulesDeclVendorImpl::AddModule(std::vector<llvm::StringRef> &path, + Stream &error_stream) +{ + // Fail early. + + if (m_compiler_instance->hadModuleLoaderFatalFailure()) + { + error_stream.PutCString("error: Couldn't load a module because the module loader is in a fatal state.\n"); + return false; + } + + if (!m_compiler_instance->getPreprocessor().getHeaderSearchInfo().lookupModule(path[0])) + { + error_stream.Printf("error: Header search couldn't locate module %s\n", path[0].str().c_str()); + return false; + } + + llvm::SmallVector<std::pair<clang::IdentifierInfo *, clang::SourceLocation>, 4> clang_path; + + { + size_t source_loc_counter = 0; + clang::SourceManager &source_manager = m_compiler_instance->getASTContext().getSourceManager(); + + for (llvm::StringRef &component : path) + { + clang_path.push_back(std::make_pair(&m_compiler_instance->getASTContext().Idents.get(component), + source_manager.getLocForStartOfFile(source_manager.getMainFileID()).getLocWithOffset(source_loc_counter++))); + } + } + + StoringDiagnosticConsumer *diagnostic_consumer = static_cast<StoringDiagnosticConsumer *>(m_compiler_instance->getDiagnostics().getClient()); + + diagnostic_consumer->ClearDiagnostics(); + + clang::Module *top_level_module = DoGetModule(clang_path.front(), false); + + if (!top_level_module) + { + diagnostic_consumer->DumpDiagnostics(error_stream); + error_stream.Printf("error: Couldn't load top-level module %s\n", path[0].str().c_str()); + return false; + } + + clang::Module *submodule = top_level_module; + + for (size_t ci = 1; ci < path.size(); ++ci) + { + llvm::StringRef &component = path[ci]; + submodule = submodule->findSubmodule(component.str()); + if (!submodule) + { + diagnostic_consumer->DumpDiagnostics(error_stream); + error_stream.Printf("error: Couldn't load submodule %s\n", component.str().c_str()); + return false; + } + } + + clang::Module *requested_module = DoGetModule(clang_path, true); + + return (requested_module != nullptr); +} + +// ClangImporter::lookupValue + +uint32_t +ClangModulesDeclVendorImpl::FindDecls (const ConstString &name, + bool append, + uint32_t max_matches, + std::vector <clang::NamedDecl*> &decls) +{ + if (!append) + decls.clear(); + + clang::IdentifierInfo &ident = m_compiler_instance->getASTContext().Idents.get(name.GetStringRef()); + + clang::LookupResult lookup_result(m_compiler_instance->getSema(), + clang::DeclarationName(&ident), + clang::SourceLocation(), + clang::Sema::LookupOrdinaryName); + + m_compiler_instance->getSema().LookupName(lookup_result, m_compiler_instance->getSema().getScopeForContext(m_compiler_instance->getASTContext().getTranslationUnitDecl())); + + uint32_t num_matches = 0; + + for (clang::NamedDecl *named_decl : lookup_result) + { + if (num_matches >= max_matches) + return num_matches; + + decls.push_back(named_decl); + ++num_matches; + } + + return num_matches; +} + +ClangModulesDeclVendorImpl::~ClangModulesDeclVendorImpl() +{ +} + +clang::ModuleLoadResult +ClangModulesDeclVendorImpl::DoGetModule(clang::ModuleIdPath path, + bool make_visible) +{ + clang::Module::NameVisibilityKind visibility = make_visible ? clang::Module::AllVisible : clang::Module::Hidden; + + const bool is_inclusion_directive = false; + + return m_compiler_instance->loadModule(path.front().second, path, visibility, is_inclusion_directive); +} + +static const char *ModuleImportBufferName = "LLDBModulesMemoryBuffer"; + +lldb_private::ClangModulesDeclVendor * +ClangModulesDeclVendor::Create(Target &target) +{ + // FIXME we should insure programmatically that the expression parser's compiler and the modules runtime's + // compiler are both initialized in the same way – preferably by the same code. + + if (!target.GetPlatform()->SupportsModules()) + return nullptr; + + const ArchSpec &arch = target.GetArchitecture(); + + std::vector<std::string> compiler_invocation_arguments = + { + "-fmodules", + "-fcxx-modules", + "-fsyntax-only", + "-femit-all-decls", + "-target", arch.GetTriple().str(), + "-fmodules-validate-system-headers", + "-Werror=non-modular-include-in-framework-module" + }; + + target.GetPlatform()->AddClangModuleCompilationOptions(compiler_invocation_arguments); + + compiler_invocation_arguments.push_back(ModuleImportBufferName); + + // Add additional search paths with { "-I", path } or { "-F", path } here. + + { + llvm::SmallString<128> DefaultModuleCache; + const bool erased_on_reboot = false; + llvm::sys::path::system_temp_directory(erased_on_reboot, DefaultModuleCache); + llvm::sys::path::append(DefaultModuleCache, "org.llvm.clang"); + llvm::sys::path::append(DefaultModuleCache, "ModuleCache"); + std::string module_cache_argument("-fmodules-cache-path="); + module_cache_argument.append(DefaultModuleCache.str().str()); + compiler_invocation_arguments.push_back(module_cache_argument); + } + + { + FileSpec clang_resource_dir = GetResourceDir(); + + if (clang_resource_dir.IsDirectory()) + { + compiler_invocation_arguments.push_back("-resource-dir"); + compiler_invocation_arguments.push_back(clang_resource_dir.GetPath()); + } + } + + llvm::IntrusiveRefCntPtr<clang::DiagnosticsEngine> diagnostics_engine = clang::CompilerInstance::createDiagnostics(new clang::DiagnosticOptions, + new StoringDiagnosticConsumer); + + std::vector<const char *> compiler_invocation_argument_cstrs; + + for (const std::string &arg : compiler_invocation_arguments) { + compiler_invocation_argument_cstrs.push_back(arg.c_str()); + } + + llvm::IntrusiveRefCntPtr<clang::CompilerInvocation> invocation(clang::createInvocationFromCommandLine(compiler_invocation_argument_cstrs, diagnostics_engine)); + + if (!invocation) + return nullptr; + + std::unique_ptr<llvm::MemoryBuffer> source_buffer = llvm::MemoryBuffer::getMemBuffer("extern int __lldb __attribute__((unavailable));", + ModuleImportBufferName); + + invocation->getPreprocessorOpts().addRemappedFile(ModuleImportBufferName, source_buffer.release()); + + std::unique_ptr<clang::CompilerInstance> instance(new clang::CompilerInstance); + + instance->setDiagnostics(diagnostics_engine.get()); + instance->setInvocation(invocation.get()); + + std::unique_ptr<clang::FrontendAction> action(new clang::SyntaxOnlyAction); + + instance->setTarget(clang::TargetInfo::CreateTargetInfo(*diagnostics_engine, instance->getInvocation().TargetOpts)); + + if (!instance->hasTarget()) + return nullptr; + + instance->getTarget().adjust(instance->getLangOpts()); + + if (!action->BeginSourceFile(*instance, instance->getFrontendOpts().Inputs[0])) + return nullptr; + + instance->getPreprocessor().enableIncrementalProcessing(); + + instance->createModuleManager(); + + instance->createSema(action->getTranslationUnitKind(), nullptr); + + const bool skipFunctionBodies = false; + std::unique_ptr<clang::Parser> parser(new clang::Parser(instance->getPreprocessor(), instance->getSema(), skipFunctionBodies)); + + instance->getPreprocessor().EnterMainSourceFile(); + parser->Initialize(); + + clang::Parser::DeclGroupPtrTy parsed; + + while (!parser->ParseTopLevelDecl(parsed)); + + return new ClangModulesDeclVendorImpl (diagnostics_engine, invocation, std::move(instance), std::move(parser)); +} diff --git a/source/Expression/ClangUserExpression.cpp b/source/Expression/ClangUserExpression.cpp index 52ef4d310352..55148462bbc0 100644 --- a/source/Expression/ClangUserExpression.cpp +++ b/source/Expression/ClangUserExpression.cpp @@ -619,15 +619,14 @@ GetObjectPointer (lldb::StackFrameSP frame_sp, valobj_sp = frame_sp->GetValueForVariableExpressionPath(object_name.AsCString(), lldb::eNoDynamicValues, - StackFrame::eExpressionPathOptionCheckPtrVsMember || - StackFrame::eExpressionPathOptionsAllowDirectIVarAccess || - StackFrame::eExpressionPathOptionsNoFragileObjcIvar || - StackFrame::eExpressionPathOptionsNoSyntheticChildren || + StackFrame::eExpressionPathOptionCheckPtrVsMember | + StackFrame::eExpressionPathOptionsNoFragileObjcIvar | + StackFrame::eExpressionPathOptionsNoSyntheticChildren | StackFrame::eExpressionPathOptionsNoSyntheticArrayRange, var_sp, err); - if (!err.Success()) + if (!err.Success() || !valobj_sp.get()) return LLDB_INVALID_ADDRESS; lldb::addr_t ret = valobj_sp->GetValueAsUnsigned(LLDB_INVALID_ADDRESS); @@ -885,17 +884,17 @@ ClangUserExpression::Execute (Stream &error_stream, args.push_back(struct_address); - ThreadPlanCallUserExpression *user_expression_plan = - new ThreadPlanCallUserExpression (exe_ctx.GetThreadRef(), - wrapper_address, - args, - options, - shared_ptr_to_me); - lldb::ThreadPlanSP call_plan_sp(user_expression_plan); + lldb::ThreadPlanSP call_plan_sp(new ThreadPlanCallUserExpression (exe_ctx.GetThreadRef(), + wrapper_address, + args, + options, + shared_ptr_to_me)); if (!call_plan_sp || !call_plan_sp->ValidatePlan (&error_stream)) return lldb::eExpressionSetupError; + ThreadPlanCallUserExpression *user_expression_plan = static_cast<ThreadPlanCallUserExpression *>(call_plan_sp.get()); + lldb::addr_t function_stack_pointer = user_expression_plan->GetFunctionStackPointer(); function_stack_bottom = function_stack_pointer - HostInfo::GetPageSize(); @@ -1070,7 +1069,7 @@ ClangUserExpression::Evaluate (ExecutionContext &exe_ctx, user_expression_sp, expr_result); - if (options.GetResultIsInternal()) + if (options.GetResultIsInternal() && expr_result && process) { process->GetTarget().GetPersistentVariables().RemovePersistentVariable (expr_result); } diff --git a/source/Expression/DWARFExpression.cpp b/source/Expression/DWARFExpression.cpp index 44b64ab1bf29..827bddd8e7bc 100644 --- a/source/Expression/DWARFExpression.cpp +++ b/source/Expression/DWARFExpression.cpp @@ -2690,11 +2690,6 @@ DWARFExpression::Evaluate } break; - default: - if (error_ptr) - error_ptr->SetErrorStringWithFormat ("unhandled value type for DW_OP_piece(%" PRIu64 ")", piece_byte_size); - return false; - } // Check if this is the first piece? @@ -2880,7 +2875,7 @@ DWARFExpression::Evaluate if (cfa != LLDB_INVALID_ADDRESS) { stack.push_back(Scalar(cfa)); - stack.back().SetValueType (Value::eValueTypeHostAddress); + stack.back().SetValueType (Value::eValueTypeLoadAddress); } else if (error_ptr) diff --git a/source/Expression/IRExecutionUnit.cpp b/source/Expression/IRExecutionUnit.cpp index 090f88fc1bfe..e7cb728778e6 100644 --- a/source/Expression/IRExecutionUnit.cpp +++ b/source/Expression/IRExecutionUnit.cpp @@ -13,6 +13,7 @@ #include "llvm/Support/SourceMgr.h" #include "lldb/Core/DataBufferHeap.h" #include "lldb/Core/DataExtractor.h" +#include "lldb/Core/Debugger.h" #include "lldb/Core/Disassembler.h" #include "lldb/Core/Log.h" #include "lldb/Core/Module.h" @@ -199,6 +200,11 @@ IRExecutionUnit::DisassembleFunction (Stream &stream, InstructionList &instruction_list = disassembler_sp->GetInstructionList(); const uint32_t max_opcode_byte_size = instruction_list.GetMaxOpcocdeByteSize(); + const char *disassemble_format = "${addr-file-or-load}: "; + if (exe_ctx.HasTargetScope()) + { + disassemble_format = exe_ctx.GetTargetRef().GetDebugger().GetDisassemblyFormat(); + } for (size_t instruction_index = 0, num_instructions = instruction_list.GetSize(); instruction_index < num_instructions; @@ -209,7 +215,10 @@ IRExecutionUnit::DisassembleFunction (Stream &stream, max_opcode_byte_size, true, true, - &exe_ctx); + &exe_ctx, + NULL, + NULL, + disassemble_format); stream.PutChar('\n'); } // FIXME: The DisassemblerLLVMC has a reference cycle and won't go away if it has any active instructions. @@ -300,11 +309,9 @@ IRExecutionUnit::GetRunnableInfo(Error &error, builder.setEngineKind(llvm::EngineKind::JIT) .setErrorStr(&error_string) .setRelocationModel(relocModel) - .setJITMemoryManager(new MemoryManager(*this)) - .setOptLevel(llvm::CodeGenOpt::Less) - .setAllocateGVsWithCode(true) + .setMCJITMemoryManager(std::unique_ptr<MemoryManager>(new MemoryManager(*this))) .setCodeModel(codeModel) - .setUseMCJIT(true); + .setOptLevel(llvm::CodeGenOpt::Less); llvm::StringRef mArch; llvm::StringRef mCPU; @@ -425,7 +432,7 @@ IRExecutionUnit::~IRExecutionUnit () } IRExecutionUnit::MemoryManager::MemoryManager (IRExecutionUnit &parent) : - m_default_mm_ap (llvm::JITMemoryManager::CreateDefaultMemManager()), + m_default_mm_ap (new llvm::SectionMemoryManager()), m_parent (parent) { } @@ -433,60 +440,6 @@ IRExecutionUnit::MemoryManager::MemoryManager (IRExecutionUnit &parent) : IRExecutionUnit::MemoryManager::~MemoryManager () { } -void -IRExecutionUnit::MemoryManager::setMemoryWritable () -{ - m_default_mm_ap->setMemoryWritable(); -} - -void -IRExecutionUnit::MemoryManager::setMemoryExecutable () -{ - m_default_mm_ap->setMemoryExecutable(); -} - - -uint8_t * -IRExecutionUnit::MemoryManager::startFunctionBody(const llvm::Function *F, - uintptr_t &ActualSize) -{ - return m_default_mm_ap->startFunctionBody(F, ActualSize); -} - -uint8_t * -IRExecutionUnit::MemoryManager::allocateStub(const llvm::GlobalValue* F, - unsigned StubSize, - unsigned Alignment) -{ - Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); - - uint8_t *return_value = m_default_mm_ap->allocateStub(F, StubSize, Alignment); - - m_parent.m_records.push_back(AllocationRecord((uintptr_t)return_value, - lldb::ePermissionsReadable | lldb::ePermissionsWritable, - GetSectionTypeFromSectionName (llvm::StringRef(), AllocationKind::Stub), - StubSize, - Alignment, - eSectionIDInvalid, - NULL)); - - if (log) - { - log->Printf("IRExecutionUnit::allocateStub (F=%p, StubSize=%u, Alignment=%u) = %p", - static_cast<const void*>(F), StubSize, Alignment, - static_cast<void*>(return_value)); - } - - return return_value; -} - -void -IRExecutionUnit::MemoryManager::endFunctionBody(const llvm::Function *F, - uint8_t *FunctionStart, - uint8_t *FunctionEnd) -{ - m_default_mm_ap->endFunctionBody(F, FunctionStart, FunctionEnd); -} lldb::SectionType IRExecutionUnit::GetSectionTypeFromSectionName (const llvm::StringRef &name, IRExecutionUnit::AllocationKind alloc_kind) @@ -598,30 +551,6 @@ IRExecutionUnit::GetSectionTypeFromSectionName (const llvm::StringRef &name, IRE } uint8_t * -IRExecutionUnit::MemoryManager::allocateSpace(intptr_t Size, unsigned Alignment) -{ - Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); - - uint8_t *return_value = m_default_mm_ap->allocateSpace(Size, Alignment); - - m_parent.m_records.push_back(AllocationRecord((uintptr_t)return_value, - lldb::ePermissionsReadable | lldb::ePermissionsWritable, - GetSectionTypeFromSectionName (llvm::StringRef(), AllocationKind::Bytes), - Size, - Alignment, - eSectionIDInvalid, - NULL)); - - if (log) - { - log->Printf("IRExecutionUnit::allocateSpace(Size=%" PRIu64 ", Alignment=%u) = %p", - (uint64_t)Size, Alignment, return_value); - } - - return return_value; -} - -uint8_t * IRExecutionUnit::MemoryManager::allocateCodeSection(uintptr_t Size, unsigned Alignment, unsigned SectionID, @@ -675,37 +604,6 @@ IRExecutionUnit::MemoryManager::allocateDataSection(uintptr_t Size, return return_value; } -uint8_t * -IRExecutionUnit::MemoryManager::allocateGlobal(uintptr_t Size, - unsigned Alignment) -{ - Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); - - uint8_t *return_value = m_default_mm_ap->allocateGlobal(Size, Alignment); - - m_parent.m_records.push_back(AllocationRecord((uintptr_t)return_value, - lldb::ePermissionsReadable | lldb::ePermissionsWritable, - GetSectionTypeFromSectionName (llvm::StringRef(), AllocationKind::Global), - Size, - Alignment, - eSectionIDInvalid, - NULL)); - - if (log) - { - log->Printf("IRExecutionUnit::allocateGlobal(Size=0x%" PRIx64 ", Alignment=%u) = %p", - (uint64_t)Size, Alignment, return_value); - } - - return return_value; -} - -void -IRExecutionUnit::MemoryManager::deallocateFunctionBody(void *Body) -{ - m_default_mm_ap->deallocateFunctionBody(Body); -} - lldb::addr_t IRExecutionUnit::GetRemoteAddressForLocal (lldb::addr_t local_address) { diff --git a/source/Expression/IRForTarget.cpp b/source/Expression/IRForTarget.cpp index b91e1b46f88e..8e75c32183ec 100644 --- a/source/Expression/IRForTarget.cpp +++ b/source/Expression/IRForTarget.cpp @@ -18,6 +18,7 @@ #include "llvm/IR/Module.h" #include "llvm/PassManager.h" #include "llvm/Transforms/IPO.h" +#include "llvm/IR/Metadata.h" #include "llvm/IR/ValueSymbolTable.h" #include "clang/AST/ASTContext.h" @@ -403,18 +404,17 @@ IRForTarget::DeclForGlobal (const GlobalValue *global_val, Module *module) node_index < num_nodes; ++node_index) { - MDNode *metadata_node = named_metadata->getOperand(node_index); - + llvm::MDNode *metadata_node = dyn_cast<llvm::MDNode>(named_metadata->getOperand(node_index)); if (!metadata_node) return NULL; if (metadata_node->getNumOperands() != 2) continue; - if (metadata_node->getOperand(0) != global_val) + if (mdconst::dyn_extract_or_null<GlobalValue>(metadata_node->getOperand(0)) != global_val) continue; - ConstantInt *constant_int = dyn_cast<ConstantInt>(metadata_node->getOperand(1)); + ConstantInt *constant_int = mdconst::dyn_extract<ConstantInt>(metadata_node->getOperand(1)); if (!constant_int) return NULL; @@ -639,11 +639,11 @@ IRForTarget::CreateResultVariable (llvm::Function &llvm_function) reinterpret_cast<uint64_t>(result_decl), false); - llvm::Value* values[2]; - values[0] = new_result_global; - values[1] = new_constant_int; + llvm::Metadata *values[2]; + values[0] = ConstantAsMetadata::get(new_result_global); + values[1] = ConstantAsMetadata::get(new_constant_int); - ArrayRef<Value*> value_ref(values, 2); + ArrayRef<Metadata *> value_ref(values, 2); MDNode *persistent_global_md = MDNode::get(m_module->getContext(), value_ref); NamedMDNode *named_metadata = m_module->getNamedMetadata("clang.global.decl.ptrs"); @@ -1037,7 +1037,7 @@ static bool IsObjCSelectorRef (Value *value) { GlobalVariable *global_variable = dyn_cast<GlobalVariable>(value); - if (!global_variable || !global_variable->hasName() || !global_variable->getName().startswith("\01L_OBJC_SELECTOR_REFERENCES_")) + if (!global_variable || !global_variable->hasName() || !global_variable->getName().startswith("OBJC_SELECTOR_REFERENCES_")) return false; return true; @@ -1056,12 +1056,12 @@ IRForTarget::RewriteObjCSelector (Instruction* selector_load) // Unpack the message name from the selector. In LLVM IR, an objc_msgSend gets represented as // - // %tmp = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_" ; <i8*> + // %tmp = load i8** @"OBJC_SELECTOR_REFERENCES_" ; <i8*> // %call = call i8* (i8*, i8*, ...)* @objc_msgSend(i8* %obj, i8* %tmp, ...) ; <i8*> // // where %obj is the object pointer and %tmp is the selector. // - // @"\01L_OBJC_SELECTOR_REFERENCES_" is a pointer to a character array called @"\01L_OBJC_llvm_moduleETH_VAR_NAllvm_moduleE_". + // @"OBJC_SELECTOR_REFERENCES_" is a pointer to a character array called @"\01L_OBJC_llvm_moduleETH_VAR_NAllvm_moduleE_". // @"\01L_OBJC_llvm_moduleETH_VAR_NAllvm_moduleE_" contains the string. // Find the pointer's initializer (a ConstantExpr with opcode GetElementPtr) and get the string from its target @@ -1215,7 +1215,7 @@ IRForTarget::RewritePersistentAlloc (llvm::Instruction *persistent_alloc) if (!alloc_md || !alloc_md->getNumOperands()) return false; - ConstantInt *constant_int = dyn_cast<ConstantInt>(alloc_md->getOperand(0)); + ConstantInt *constant_int = mdconst::dyn_extract<ConstantInt>(alloc_md->getOperand(0)); if (!constant_int) return false; @@ -1246,11 +1246,11 @@ IRForTarget::RewritePersistentAlloc (llvm::Instruction *persistent_alloc) NamedMDNode *named_metadata = m_module->getOrInsertNamedMetadata("clang.global.decl.ptrs"); - llvm::Value* values[2]; - values[0] = persistent_global; - values[1] = constant_int; + llvm::Metadata *values[2]; + values[0] = ConstantAsMetadata::get(persistent_global); + values[1] = ConstantAsMetadata::get(constant_int); - ArrayRef<llvm::Value*> value_ref(values, 2); + ArrayRef<llvm::Metadata *> value_ref(values, 2); MDNode *persistent_global_md = MDNode::get(m_module->getContext(), value_ref); named_metadata->addOperand(persistent_global_md); @@ -2043,8 +2043,12 @@ static bool isGuardVariableRef(Value *V) GlobalVariable *GV = dyn_cast<GlobalVariable>(Old); - if (!GV || !GV->hasName() || !GV->getName().startswith("_ZGV")) + if (!GV || !GV->hasName() || + (!GV->getName().startswith("_ZGV") && // Itanium ABI guard variable + !GV->getName().endswith("@4IA"))) // Microsoft ABI guard variable + { return false; + } return true; } @@ -2052,20 +2056,8 @@ static bool isGuardVariableRef(Value *V) void IRForTarget::TurnGuardLoadIntoZero(llvm::Instruction* guard_load) { - Constant* zero(ConstantInt::get(Type::getInt8Ty(m_module->getContext()), 0, true)); - - for (llvm::User *u : guard_load->users()) - { - if (isa<Constant>(u)) - { - // do nothing for the moment - } - else - { - u->replaceUsesOfWith(guard_load, zero); - } - } - + Constant *zero(Constant::getNullValue(guard_load->getType())); + guard_load->replaceAllUsesWith(zero); guard_load->eraseFromParent(); } |