15ffd83dbSDimitry Andric //===-- ClangExpressionParser.cpp -----------------------------------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 90b57cec5SDimitry Andric #include "clang/AST/ASTContext.h" 100b57cec5SDimitry Andric #include "clang/AST/ASTDiagnostic.h" 110b57cec5SDimitry Andric #include "clang/AST/ExternalASTSource.h" 120b57cec5SDimitry Andric #include "clang/AST/PrettyPrinter.h" 13480093f4SDimitry Andric #include "clang/Basic/Builtins.h" 140b57cec5SDimitry Andric #include "clang/Basic/DiagnosticIDs.h" 150b57cec5SDimitry Andric #include "clang/Basic/SourceLocation.h" 160b57cec5SDimitry Andric #include "clang/Basic/TargetInfo.h" 170b57cec5SDimitry Andric #include "clang/Basic/Version.h" 180b57cec5SDimitry Andric #include "clang/CodeGen/CodeGenAction.h" 190b57cec5SDimitry Andric #include "clang/CodeGen/ModuleBuilder.h" 200b57cec5SDimitry Andric #include "clang/Edit/Commit.h" 210b57cec5SDimitry Andric #include "clang/Edit/EditedSource.h" 220b57cec5SDimitry Andric #include "clang/Edit/EditsReceiver.h" 230b57cec5SDimitry Andric #include "clang/Frontend/CompilerInstance.h" 240b57cec5SDimitry Andric #include "clang/Frontend/CompilerInvocation.h" 250b57cec5SDimitry Andric #include "clang/Frontend/FrontendActions.h" 260b57cec5SDimitry Andric #include "clang/Frontend/FrontendDiagnostic.h" 270b57cec5SDimitry Andric #include "clang/Frontend/FrontendPluginRegistry.h" 280b57cec5SDimitry Andric #include "clang/Frontend/TextDiagnosticBuffer.h" 290b57cec5SDimitry Andric #include "clang/Frontend/TextDiagnosticPrinter.h" 300b57cec5SDimitry Andric #include "clang/Lex/Preprocessor.h" 310b57cec5SDimitry Andric #include "clang/Parse/ParseAST.h" 320b57cec5SDimitry Andric #include "clang/Rewrite/Core/Rewriter.h" 330b57cec5SDimitry Andric #include "clang/Rewrite/Frontend/FrontendActions.h" 340b57cec5SDimitry Andric #include "clang/Sema/CodeCompleteConsumer.h" 350b57cec5SDimitry Andric #include "clang/Sema/Sema.h" 360b57cec5SDimitry Andric #include "clang/Sema/SemaConsumer.h" 370b57cec5SDimitry Andric 380b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h" 390b57cec5SDimitry Andric #include "llvm/ExecutionEngine/ExecutionEngine.h" 400b57cec5SDimitry Andric #include "llvm/Support/CrashRecoveryContext.h" 410b57cec5SDimitry Andric #include "llvm/Support/Debug.h" 420b57cec5SDimitry Andric #include "llvm/Support/FileSystem.h" 430b57cec5SDimitry Andric #include "llvm/Support/TargetSelect.h" 440b57cec5SDimitry Andric 450b57cec5SDimitry Andric #include "llvm/IR/LLVMContext.h" 460b57cec5SDimitry Andric #include "llvm/IR/Module.h" 470b57cec5SDimitry Andric #include "llvm/Support/DynamicLibrary.h" 480b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h" 490b57cec5SDimitry Andric #include "llvm/Support/MemoryBuffer.h" 500b57cec5SDimitry Andric #include "llvm/Support/Signals.h" 5106c3fb27SDimitry Andric #include "llvm/TargetParser/Host.h" 520b57cec5SDimitry Andric 530b57cec5SDimitry Andric #include "ClangDiagnostic.h" 540b57cec5SDimitry Andric #include "ClangExpressionParser.h" 550b57cec5SDimitry Andric #include "ClangUserExpression.h" 560b57cec5SDimitry Andric 570b57cec5SDimitry Andric #include "ASTUtils.h" 580b57cec5SDimitry Andric #include "ClangASTSource.h" 590b57cec5SDimitry Andric #include "ClangDiagnostic.h" 600b57cec5SDimitry Andric #include "ClangExpressionDeclMap.h" 610b57cec5SDimitry Andric #include "ClangExpressionHelper.h" 620b57cec5SDimitry Andric #include "ClangExpressionParser.h" 630b57cec5SDimitry Andric #include "ClangHost.h" 640b57cec5SDimitry Andric #include "ClangModulesDeclVendor.h" 650b57cec5SDimitry Andric #include "ClangPersistentVariables.h" 660b57cec5SDimitry Andric #include "IRDynamicChecks.h" 670b57cec5SDimitry Andric #include "IRForTarget.h" 680b57cec5SDimitry Andric #include "ModuleDependencyCollector.h" 690b57cec5SDimitry Andric 705ffd83dbSDimitry Andric #include "Plugins/TypeSystem/Clang/TypeSystemClang.h" 710b57cec5SDimitry Andric #include "lldb/Core/Debugger.h" 720b57cec5SDimitry Andric #include "lldb/Core/Disassembler.h" 730b57cec5SDimitry Andric #include "lldb/Core/Module.h" 740b57cec5SDimitry Andric #include "lldb/Expression/IRExecutionUnit.h" 750b57cec5SDimitry Andric #include "lldb/Expression/IRInterpreter.h" 760b57cec5SDimitry Andric #include "lldb/Host/File.h" 770b57cec5SDimitry Andric #include "lldb/Host/HostInfo.h" 780b57cec5SDimitry Andric #include "lldb/Symbol/SymbolVendor.h" 790b57cec5SDimitry Andric #include "lldb/Target/ExecutionContext.h" 800b57cec5SDimitry Andric #include "lldb/Target/Language.h" 810b57cec5SDimitry Andric #include "lldb/Target/Process.h" 820b57cec5SDimitry Andric #include "lldb/Target/Target.h" 830b57cec5SDimitry Andric #include "lldb/Target/ThreadPlanCallFunction.h" 840b57cec5SDimitry Andric #include "lldb/Utility/DataBufferHeap.h" 850b57cec5SDimitry Andric #include "lldb/Utility/LLDBAssert.h" 8681ad6265SDimitry Andric #include "lldb/Utility/LLDBLog.h" 870b57cec5SDimitry Andric #include "lldb/Utility/Log.h" 880b57cec5SDimitry Andric #include "lldb/Utility/Stream.h" 890b57cec5SDimitry Andric #include "lldb/Utility/StreamString.h" 900b57cec5SDimitry Andric #include "lldb/Utility/StringList.h" 910b57cec5SDimitry Andric 920b57cec5SDimitry Andric #include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h" 930b57cec5SDimitry Andric 940b57cec5SDimitry Andric #include <cctype> 950b57cec5SDimitry Andric #include <memory> 96bdd1243dSDimitry Andric #include <optional> 970b57cec5SDimitry Andric 980b57cec5SDimitry Andric using namespace clang; 990b57cec5SDimitry Andric using namespace llvm; 1000b57cec5SDimitry Andric using namespace lldb_private; 1010b57cec5SDimitry Andric 1020b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 1030b57cec5SDimitry Andric // Utility Methods for Clang 1040b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 1050b57cec5SDimitry Andric 1060b57cec5SDimitry Andric class ClangExpressionParser::LLDBPreprocessorCallbacks : public PPCallbacks { 1070b57cec5SDimitry Andric ClangModulesDeclVendor &m_decl_vendor; 1080b57cec5SDimitry Andric ClangPersistentVariables &m_persistent_vars; 1099dba64beSDimitry Andric clang::SourceManager &m_source_mgr; 1100b57cec5SDimitry Andric StreamString m_error_stream; 1110b57cec5SDimitry Andric bool m_has_errors = false; 1120b57cec5SDimitry Andric 1130b57cec5SDimitry Andric public: 1140b57cec5SDimitry Andric LLDBPreprocessorCallbacks(ClangModulesDeclVendor &decl_vendor, 1159dba64beSDimitry Andric ClangPersistentVariables &persistent_vars, 1169dba64beSDimitry Andric clang::SourceManager &source_mgr) 1179dba64beSDimitry Andric : m_decl_vendor(decl_vendor), m_persistent_vars(persistent_vars), 1189dba64beSDimitry Andric m_source_mgr(source_mgr) {} 1190b57cec5SDimitry Andric 1200b57cec5SDimitry Andric void moduleImport(SourceLocation import_location, clang::ModuleIdPath path, 1210b57cec5SDimitry Andric const clang::Module * /*null*/) override { 1229dba64beSDimitry Andric // Ignore modules that are imported in the wrapper code as these are not 1239dba64beSDimitry Andric // loaded by the user. 1249dba64beSDimitry Andric llvm::StringRef filename = 1259dba64beSDimitry Andric m_source_mgr.getPresumedLoc(import_location).getFilename(); 1269dba64beSDimitry Andric if (filename == ClangExpressionSourceCode::g_prefix_file_name) 1279dba64beSDimitry Andric return; 1289dba64beSDimitry Andric 1290b57cec5SDimitry Andric SourceModule module; 1300b57cec5SDimitry Andric 1310b57cec5SDimitry Andric for (const std::pair<IdentifierInfo *, SourceLocation> &component : path) 1320b57cec5SDimitry Andric module.path.push_back(ConstString(component.first->getName())); 1330b57cec5SDimitry Andric 1340b57cec5SDimitry Andric StreamString error_stream; 1350b57cec5SDimitry Andric 1360b57cec5SDimitry Andric ClangModulesDeclVendor::ModuleVector exported_modules; 1370b57cec5SDimitry Andric if (!m_decl_vendor.AddModule(module, &exported_modules, m_error_stream)) 1380b57cec5SDimitry Andric m_has_errors = true; 1390b57cec5SDimitry Andric 1400b57cec5SDimitry Andric for (ClangModulesDeclVendor::ModuleID module : exported_modules) 1410b57cec5SDimitry Andric m_persistent_vars.AddHandLoadedClangModule(module); 1420b57cec5SDimitry Andric } 1430b57cec5SDimitry Andric 1440b57cec5SDimitry Andric bool hasErrors() { return m_has_errors; } 1450b57cec5SDimitry Andric 1460b57cec5SDimitry Andric llvm::StringRef getErrorString() { return m_error_stream.GetString(); } 1470b57cec5SDimitry Andric }; 1480b57cec5SDimitry Andric 1495ffd83dbSDimitry Andric static void AddAllFixIts(ClangDiagnostic *diag, const clang::Diagnostic &Info) { 1505ffd83dbSDimitry Andric for (auto &fix_it : Info.getFixItHints()) { 1515ffd83dbSDimitry Andric if (fix_it.isNull()) 1525ffd83dbSDimitry Andric continue; 1535ffd83dbSDimitry Andric diag->AddFixitHint(fix_it); 1545ffd83dbSDimitry Andric } 1555ffd83dbSDimitry Andric } 1565ffd83dbSDimitry Andric 1570b57cec5SDimitry Andric class ClangDiagnosticManagerAdapter : public clang::DiagnosticConsumer { 1580b57cec5SDimitry Andric public: 1599dba64beSDimitry Andric ClangDiagnosticManagerAdapter(DiagnosticOptions &opts) { 1605ffd83dbSDimitry Andric DiagnosticOptions *options = new DiagnosticOptions(opts); 1615ffd83dbSDimitry Andric options->ShowPresumedLoc = true; 1625ffd83dbSDimitry Andric options->ShowLevel = false; 1635ffd83dbSDimitry Andric m_os = std::make_shared<llvm::raw_string_ostream>(m_output); 1645ffd83dbSDimitry Andric m_passthrough = 1655ffd83dbSDimitry Andric std::make_shared<clang::TextDiagnosticPrinter>(*m_os, options); 1669dba64beSDimitry Andric } 1670b57cec5SDimitry Andric 1680b57cec5SDimitry Andric void ResetManager(DiagnosticManager *manager = nullptr) { 1690b57cec5SDimitry Andric m_manager = manager; 1700b57cec5SDimitry Andric } 1710b57cec5SDimitry Andric 1725ffd83dbSDimitry Andric /// Returns the last ClangDiagnostic message that the DiagnosticManager 1735ffd83dbSDimitry Andric /// received or a nullptr if the DiagnosticMangager hasn't seen any 1745ffd83dbSDimitry Andric /// Clang diagnostics yet. 1755ffd83dbSDimitry Andric ClangDiagnostic *MaybeGetLastClangDiag() const { 1765ffd83dbSDimitry Andric if (m_manager->Diagnostics().empty()) 1775ffd83dbSDimitry Andric return nullptr; 1785ffd83dbSDimitry Andric lldb_private::Diagnostic *diag = m_manager->Diagnostics().back().get(); 1795ffd83dbSDimitry Andric ClangDiagnostic *clang_diag = dyn_cast<ClangDiagnostic>(diag); 1805ffd83dbSDimitry Andric return clang_diag; 1815ffd83dbSDimitry Andric } 1825ffd83dbSDimitry Andric 1830b57cec5SDimitry Andric void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, 1840b57cec5SDimitry Andric const clang::Diagnostic &Info) override { 1859dba64beSDimitry Andric if (!m_manager) { 1869dba64beSDimitry Andric // We have no DiagnosticManager before/after parsing but we still could 1879dba64beSDimitry Andric // receive diagnostics (e.g., by the ASTImporter failing to copy decls 1889dba64beSDimitry Andric // when we move the expression result ot the ScratchASTContext). Let's at 1899dba64beSDimitry Andric // least log these diagnostics until we find a way to properly render 1909dba64beSDimitry Andric // them and display them to the user. 19181ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Expressions); 1929dba64beSDimitry Andric if (log) { 1930b57cec5SDimitry Andric llvm::SmallVector<char, 32> diag_str; 1940b57cec5SDimitry Andric Info.FormatDiagnostic(diag_str); 1950b57cec5SDimitry Andric diag_str.push_back('\0'); 1969dba64beSDimitry Andric const char *plain_diag = diag_str.data(); 1979dba64beSDimitry Andric LLDB_LOG(log, "Received diagnostic outside parsing: {0}", plain_diag); 1989dba64beSDimitry Andric } 1999dba64beSDimitry Andric return; 2009dba64beSDimitry Andric } 2019dba64beSDimitry Andric 2025ffd83dbSDimitry Andric // Update error/warning counters. 2035ffd83dbSDimitry Andric DiagnosticConsumer::HandleDiagnostic(DiagLevel, Info); 2045ffd83dbSDimitry Andric 2059dba64beSDimitry Andric // Render diagnostic message to m_output. 2069dba64beSDimitry Andric m_output.clear(); 2079dba64beSDimitry Andric m_passthrough->HandleDiagnostic(DiagLevel, Info); 2089dba64beSDimitry Andric m_os->flush(); 2090b57cec5SDimitry Andric 210*0fca6ea1SDimitry Andric lldb::Severity severity; 2110b57cec5SDimitry Andric bool make_new_diagnostic = true; 2120b57cec5SDimitry Andric 2130b57cec5SDimitry Andric switch (DiagLevel) { 2140b57cec5SDimitry Andric case DiagnosticsEngine::Level::Fatal: 2150b57cec5SDimitry Andric case DiagnosticsEngine::Level::Error: 216*0fca6ea1SDimitry Andric severity = lldb::eSeverityError; 2170b57cec5SDimitry Andric break; 2180b57cec5SDimitry Andric case DiagnosticsEngine::Level::Warning: 219*0fca6ea1SDimitry Andric severity = lldb::eSeverityWarning; 2200b57cec5SDimitry Andric break; 2210b57cec5SDimitry Andric case DiagnosticsEngine::Level::Remark: 2220b57cec5SDimitry Andric case DiagnosticsEngine::Level::Ignored: 223*0fca6ea1SDimitry Andric severity = lldb::eSeverityInfo; 2240b57cec5SDimitry Andric break; 2250b57cec5SDimitry Andric case DiagnosticsEngine::Level::Note: 2269dba64beSDimitry Andric m_manager->AppendMessageToDiagnostic(m_output); 2270b57cec5SDimitry Andric make_new_diagnostic = false; 2285ffd83dbSDimitry Andric 2295ffd83dbSDimitry Andric // 'note:' diagnostics for errors and warnings can also contain Fix-Its. 2305ffd83dbSDimitry Andric // We add these Fix-Its to the last error diagnostic to make sure 2315ffd83dbSDimitry Andric // that we later have all Fix-Its related to an 'error' diagnostic when 2325ffd83dbSDimitry Andric // we apply them to the user expression. 2335ffd83dbSDimitry Andric auto *clang_diag = MaybeGetLastClangDiag(); 2345ffd83dbSDimitry Andric // If we don't have a previous diagnostic there is nothing to do. 2355ffd83dbSDimitry Andric // If the previous diagnostic already has its own Fix-Its, assume that 2365ffd83dbSDimitry Andric // the 'note:' Fix-It is just an alternative way to solve the issue and 2375ffd83dbSDimitry Andric // ignore these Fix-Its. 2385ffd83dbSDimitry Andric if (!clang_diag || clang_diag->HasFixIts()) 2395ffd83dbSDimitry Andric break; 2405ffd83dbSDimitry Andric // Ignore all Fix-Its that are not associated with an error. 241*0fca6ea1SDimitry Andric if (clang_diag->GetSeverity() != lldb::eSeverityError) 2425ffd83dbSDimitry Andric break; 2435ffd83dbSDimitry Andric AddAllFixIts(clang_diag, Info); 2445ffd83dbSDimitry Andric break; 2450b57cec5SDimitry Andric } 2460b57cec5SDimitry Andric if (make_new_diagnostic) { 2479dba64beSDimitry Andric // ClangDiagnostic messages are expected to have no whitespace/newlines 2489dba64beSDimitry Andric // around them. 2495ffd83dbSDimitry Andric std::string stripped_output = 2505ffd83dbSDimitry Andric std::string(llvm::StringRef(m_output).trim()); 2519dba64beSDimitry Andric 2529dba64beSDimitry Andric auto new_diagnostic = std::make_unique<ClangDiagnostic>( 2539dba64beSDimitry Andric stripped_output, severity, Info.getID()); 2540b57cec5SDimitry Andric 2550b57cec5SDimitry Andric // Don't store away warning fixits, since the compiler doesn't have 2560b57cec5SDimitry Andric // enough context in an expression for the warning to be useful. 2570b57cec5SDimitry Andric // FIXME: Should we try to filter out FixIts that apply to our generated 2580b57cec5SDimitry Andric // code, and not the user's expression? 259*0fca6ea1SDimitry Andric if (severity == lldb::eSeverityError) 2605ffd83dbSDimitry Andric AddAllFixIts(new_diagnostic.get(), Info); 2619dba64beSDimitry Andric 2629dba64beSDimitry Andric m_manager->AddDiagnostic(std::move(new_diagnostic)); 2630b57cec5SDimitry Andric } 2640b57cec5SDimitry Andric } 2650b57cec5SDimitry Andric 2665ffd83dbSDimitry Andric void BeginSourceFile(const LangOptions &LO, const Preprocessor *PP) override { 2675ffd83dbSDimitry Andric m_passthrough->BeginSourceFile(LO, PP); 2685ffd83dbSDimitry Andric } 2695ffd83dbSDimitry Andric 2705ffd83dbSDimitry Andric void EndSourceFile() override { m_passthrough->EndSourceFile(); } 2710b57cec5SDimitry Andric 2720b57cec5SDimitry Andric private: 2730b57cec5SDimitry Andric DiagnosticManager *m_manager = nullptr; 2749dba64beSDimitry Andric std::shared_ptr<clang::TextDiagnosticPrinter> m_passthrough; 2759dba64beSDimitry Andric /// Output stream of m_passthrough. 2769dba64beSDimitry Andric std::shared_ptr<llvm::raw_string_ostream> m_os; 2779dba64beSDimitry Andric /// Output string filled by m_os. 2789dba64beSDimitry Andric std::string m_output; 2790b57cec5SDimitry Andric }; 2800b57cec5SDimitry Andric 2819dba64beSDimitry Andric static void SetupModuleHeaderPaths(CompilerInstance *compiler, 2829dba64beSDimitry Andric std::vector<std::string> include_directories, 2830b57cec5SDimitry Andric lldb::TargetSP target_sp) { 28481ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Expressions); 2850b57cec5SDimitry Andric 2860b57cec5SDimitry Andric HeaderSearchOptions &search_opts = compiler->getHeaderSearchOpts(); 2870b57cec5SDimitry Andric 2889dba64beSDimitry Andric for (const std::string &dir : include_directories) { 2899dba64beSDimitry Andric search_opts.AddPath(dir, frontend::System, false, true); 2900b57cec5SDimitry Andric LLDB_LOG(log, "Added user include dir: {0}", dir); 2910b57cec5SDimitry Andric } 2920b57cec5SDimitry Andric 2930b57cec5SDimitry Andric llvm::SmallString<128> module_cache; 2945ffd83dbSDimitry Andric const auto &props = ModuleList::GetGlobalModuleListProperties(); 2950b57cec5SDimitry Andric props.GetClangModulesCachePath().GetPath(module_cache); 2965ffd83dbSDimitry Andric search_opts.ModuleCachePath = std::string(module_cache.str()); 2970b57cec5SDimitry Andric LLDB_LOG(log, "Using module cache path: {0}", module_cache.c_str()); 2980b57cec5SDimitry Andric 2999dba64beSDimitry Andric search_opts.ResourceDir = GetClangResourceDir().GetPath(); 3000b57cec5SDimitry Andric 3010b57cec5SDimitry Andric search_opts.ImplicitModuleMaps = true; 3020b57cec5SDimitry Andric } 3030b57cec5SDimitry Andric 304e8d8bef9SDimitry Andric /// Iff the given identifier is a C++ keyword, remove it from the 305e8d8bef9SDimitry Andric /// identifier table (i.e., make the token a normal identifier). 306e8d8bef9SDimitry Andric static void RemoveCppKeyword(IdentifierTable &idents, llvm::StringRef token) { 307e8d8bef9SDimitry Andric // FIXME: 'using' is used by LLDB for local variables, so we can't remove 308e8d8bef9SDimitry Andric // this keyword without breaking this functionality. 309e8d8bef9SDimitry Andric if (token == "using") 310e8d8bef9SDimitry Andric return; 311e8d8bef9SDimitry Andric // GCC's '__null' is used by LLDB to define NULL/Nil/nil. 312e8d8bef9SDimitry Andric if (token == "__null") 313e8d8bef9SDimitry Andric return; 314e8d8bef9SDimitry Andric 315e8d8bef9SDimitry Andric LangOptions cpp_lang_opts; 316e8d8bef9SDimitry Andric cpp_lang_opts.CPlusPlus = true; 317e8d8bef9SDimitry Andric cpp_lang_opts.CPlusPlus11 = true; 318e8d8bef9SDimitry Andric cpp_lang_opts.CPlusPlus20 = true; 319e8d8bef9SDimitry Andric 320e8d8bef9SDimitry Andric clang::IdentifierInfo &ii = idents.get(token); 321e8d8bef9SDimitry Andric // The identifier has to be a C++-exclusive keyword. if not, then there is 322e8d8bef9SDimitry Andric // nothing to do. 323e8d8bef9SDimitry Andric if (!ii.isCPlusPlusKeyword(cpp_lang_opts)) 324e8d8bef9SDimitry Andric return; 325e8d8bef9SDimitry Andric // If the token is already an identifier, then there is nothing to do. 326e8d8bef9SDimitry Andric if (ii.getTokenID() == clang::tok::identifier) 327e8d8bef9SDimitry Andric return; 328e8d8bef9SDimitry Andric // Otherwise the token is a C++ keyword, so turn it back into a normal 329e8d8bef9SDimitry Andric // identifier. 330e8d8bef9SDimitry Andric ii.revertTokenIDToIdentifier(); 331e8d8bef9SDimitry Andric } 332e8d8bef9SDimitry Andric 333e8d8bef9SDimitry Andric /// Remove all C++ keywords from the given identifier table. 334e8d8bef9SDimitry Andric static void RemoveAllCppKeywords(IdentifierTable &idents) { 335e8d8bef9SDimitry Andric #define KEYWORD(NAME, FLAGS) RemoveCppKeyword(idents, llvm::StringRef(#NAME)); 336e8d8bef9SDimitry Andric #include "clang/Basic/TokenKinds.def" 337e8d8bef9SDimitry Andric } 338e8d8bef9SDimitry Andric 339e8d8bef9SDimitry Andric /// Configures Clang diagnostics for the expression parser. 340e8d8bef9SDimitry Andric static void SetupDefaultClangDiagnostics(CompilerInstance &compiler) { 341e8d8bef9SDimitry Andric // List of Clang warning groups that are not useful when parsing expressions. 342e8d8bef9SDimitry Andric const std::vector<const char *> groupsToIgnore = { 343e8d8bef9SDimitry Andric "unused-value", 344e8d8bef9SDimitry Andric "odr", 345fe6060f1SDimitry Andric "unused-getter-return-value", 346e8d8bef9SDimitry Andric }; 347e8d8bef9SDimitry Andric for (const char *group : groupsToIgnore) { 348e8d8bef9SDimitry Andric compiler.getDiagnostics().setSeverityForGroup( 349e8d8bef9SDimitry Andric clang::diag::Flavor::WarningOrError, group, 350e8d8bef9SDimitry Andric clang::diag::Severity::Ignored, SourceLocation()); 351e8d8bef9SDimitry Andric } 352e8d8bef9SDimitry Andric } 353e8d8bef9SDimitry Andric 3540b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 3550b57cec5SDimitry Andric // Implementation of ClangExpressionParser 3560b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 3570b57cec5SDimitry Andric 3580b57cec5SDimitry Andric ClangExpressionParser::ClangExpressionParser( 3590b57cec5SDimitry Andric ExecutionContextScope *exe_scope, Expression &expr, 3609dba64beSDimitry Andric bool generate_debug_info, std::vector<std::string> include_directories, 3619dba64beSDimitry Andric std::string filename) 3620b57cec5SDimitry Andric : ExpressionParser(exe_scope, expr, generate_debug_info), m_compiler(), 3630b57cec5SDimitry Andric m_pp_callbacks(nullptr), 3649dba64beSDimitry Andric m_include_directories(std::move(include_directories)), 3659dba64beSDimitry Andric m_filename(std::move(filename)) { 36681ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Expressions); 3670b57cec5SDimitry Andric 3680b57cec5SDimitry Andric // We can't compile expressions without a target. So if the exe_scope is 3690b57cec5SDimitry Andric // null or doesn't have a target, then we just need to get out of here. I'll 3705ffd83dbSDimitry Andric // lldbassert and not make any of the compiler objects since 3710b57cec5SDimitry Andric // I can't return errors directly from the constructor. Further calls will 3720b57cec5SDimitry Andric // check if the compiler was made and 3730b57cec5SDimitry Andric // bag out if it wasn't. 3740b57cec5SDimitry Andric 3750b57cec5SDimitry Andric if (!exe_scope) { 3765ffd83dbSDimitry Andric lldbassert(exe_scope && 3775ffd83dbSDimitry Andric "Can't make an expression parser with a null scope."); 3780b57cec5SDimitry Andric return; 3790b57cec5SDimitry Andric } 3800b57cec5SDimitry Andric 3810b57cec5SDimitry Andric lldb::TargetSP target_sp; 3820b57cec5SDimitry Andric target_sp = exe_scope->CalculateTarget(); 3830b57cec5SDimitry Andric if (!target_sp) { 3845ffd83dbSDimitry Andric lldbassert(target_sp.get() && 3855ffd83dbSDimitry Andric "Can't make an expression parser with a null target."); 3860b57cec5SDimitry Andric return; 3870b57cec5SDimitry Andric } 3880b57cec5SDimitry Andric 3890b57cec5SDimitry Andric // 1. Create a new compiler instance. 3905ffd83dbSDimitry Andric m_compiler = std::make_unique<CompilerInstance>(); 3910b57cec5SDimitry Andric 3920b57cec5SDimitry Andric // Make sure clang uses the same VFS as LLDB. 3930b57cec5SDimitry Andric m_compiler->createFileManager(FileSystem::Instance().GetVirtualFileSystem()); 3940b57cec5SDimitry Andric 395*0fca6ea1SDimitry Andric // Defaults to lldb::eLanguageTypeUnknown. 396*0fca6ea1SDimitry Andric lldb::LanguageType frame_lang = expr.Language().AsLanguageType(); 3970b57cec5SDimitry Andric 3980b57cec5SDimitry Andric std::string abi; 3990b57cec5SDimitry Andric ArchSpec target_arch; 4000b57cec5SDimitry Andric target_arch = target_sp->GetArchitecture(); 4010b57cec5SDimitry Andric 4020b57cec5SDimitry Andric const auto target_machine = target_arch.GetMachine(); 4030b57cec5SDimitry Andric 4040b57cec5SDimitry Andric // If the expression is being evaluated in the context of an existing stack 4050b57cec5SDimitry Andric // frame, we introspect to see if the language runtime is available. 4060b57cec5SDimitry Andric 4070b57cec5SDimitry Andric lldb::StackFrameSP frame_sp = exe_scope->CalculateStackFrame(); 4080b57cec5SDimitry Andric lldb::ProcessSP process_sp = exe_scope->CalculateProcess(); 4090b57cec5SDimitry Andric 4100b57cec5SDimitry Andric // Make sure the user hasn't provided a preferred execution language with 4110b57cec5SDimitry Andric // `expression --language X -- ...` 4120b57cec5SDimitry Andric if (frame_sp && frame_lang == lldb::eLanguageTypeUnknown) 413*0fca6ea1SDimitry Andric frame_lang = frame_sp->GetLanguage().AsLanguageType(); 4140b57cec5SDimitry Andric 4150b57cec5SDimitry Andric if (process_sp && frame_lang != lldb::eLanguageTypeUnknown) { 4169dba64beSDimitry Andric LLDB_LOGF(log, "Frame has language of type %s", 4170b57cec5SDimitry Andric Language::GetNameForLanguageType(frame_lang)); 4180b57cec5SDimitry Andric } 4190b57cec5SDimitry Andric 4200b57cec5SDimitry Andric // 2. Configure the compiler with a set of default options that are 4210b57cec5SDimitry Andric // appropriate for most situations. 4220b57cec5SDimitry Andric if (target_arch.IsValid()) { 4230b57cec5SDimitry Andric std::string triple = target_arch.GetTriple().str(); 4240b57cec5SDimitry Andric m_compiler->getTargetOpts().Triple = triple; 4259dba64beSDimitry Andric LLDB_LOGF(log, "Using %s as the target triple", 4260b57cec5SDimitry Andric m_compiler->getTargetOpts().Triple.c_str()); 4270b57cec5SDimitry Andric } else { 4280b57cec5SDimitry Andric // If we get here we don't have a valid target and just have to guess. 4290b57cec5SDimitry Andric // Sometimes this will be ok to just use the host target triple (when we 4300b57cec5SDimitry Andric // evaluate say "2+3", but other expressions like breakpoint conditions and 4310b57cec5SDimitry Andric // other things that _are_ target specific really shouldn't just be using 4320b57cec5SDimitry Andric // the host triple. In such a case the language runtime should expose an 4330b57cec5SDimitry Andric // overridden options set (3), below. 4340b57cec5SDimitry Andric m_compiler->getTargetOpts().Triple = llvm::sys::getDefaultTargetTriple(); 4359dba64beSDimitry Andric LLDB_LOGF(log, "Using default target triple of %s", 4360b57cec5SDimitry Andric m_compiler->getTargetOpts().Triple.c_str()); 4370b57cec5SDimitry Andric } 4380b57cec5SDimitry Andric // Now add some special fixes for known architectures: Any arm32 iOS 4390b57cec5SDimitry Andric // environment, but not on arm64 4400b57cec5SDimitry Andric if (m_compiler->getTargetOpts().Triple.find("arm64") == std::string::npos && 4410b57cec5SDimitry Andric m_compiler->getTargetOpts().Triple.find("arm") != std::string::npos && 4420b57cec5SDimitry Andric m_compiler->getTargetOpts().Triple.find("ios") != std::string::npos) { 4430b57cec5SDimitry Andric m_compiler->getTargetOpts().ABI = "apcs-gnu"; 4440b57cec5SDimitry Andric } 4450b57cec5SDimitry Andric // Supported subsets of x86 4460b57cec5SDimitry Andric if (target_machine == llvm::Triple::x86 || 4470b57cec5SDimitry Andric target_machine == llvm::Triple::x86_64) { 448*0fca6ea1SDimitry Andric m_compiler->getTargetOpts().FeaturesAsWritten.push_back("+sse"); 449*0fca6ea1SDimitry Andric m_compiler->getTargetOpts().FeaturesAsWritten.push_back("+sse2"); 4500b57cec5SDimitry Andric } 4510b57cec5SDimitry Andric 4520b57cec5SDimitry Andric // Set the target CPU to generate code for. This will be empty for any CPU 4530b57cec5SDimitry Andric // that doesn't really need to make a special 4540b57cec5SDimitry Andric // CPU string. 4550b57cec5SDimitry Andric m_compiler->getTargetOpts().CPU = target_arch.GetClangTargetCPU(); 4560b57cec5SDimitry Andric 4570b57cec5SDimitry Andric // Set the target ABI 4580b57cec5SDimitry Andric abi = GetClangTargetABI(target_arch); 4590b57cec5SDimitry Andric if (!abi.empty()) 4600b57cec5SDimitry Andric m_compiler->getTargetOpts().ABI = abi; 4610b57cec5SDimitry Andric 46206c3fb27SDimitry Andric // 3. Create and install the target on the compiler. 4630b57cec5SDimitry Andric m_compiler->createDiagnostics(); 464e8d8bef9SDimitry Andric // Limit the number of error diagnostics we emit. 465e8d8bef9SDimitry Andric // A value of 0 means no limit for both LLDB and Clang. 466e8d8bef9SDimitry Andric m_compiler->getDiagnostics().setErrorLimit(target_sp->GetExprErrorLimit()); 467e8d8bef9SDimitry Andric 4680b57cec5SDimitry Andric auto target_info = TargetInfo::CreateTargetInfo( 4690b57cec5SDimitry Andric m_compiler->getDiagnostics(), m_compiler->getInvocation().TargetOpts); 4700b57cec5SDimitry Andric if (log) { 4719dba64beSDimitry Andric LLDB_LOGF(log, "Target datalayout string: '%s'", 472fe6060f1SDimitry Andric target_info->getDataLayoutString()); 4739dba64beSDimitry Andric LLDB_LOGF(log, "Target ABI: '%s'", target_info->getABI().str().c_str()); 4749dba64beSDimitry Andric LLDB_LOGF(log, "Target vector alignment: %d", 4750b57cec5SDimitry Andric target_info->getMaxVectorAlign()); 4760b57cec5SDimitry Andric } 4770b57cec5SDimitry Andric m_compiler->setTarget(target_info); 4780b57cec5SDimitry Andric 4790b57cec5SDimitry Andric assert(m_compiler->hasTarget()); 4800b57cec5SDimitry Andric 48106c3fb27SDimitry Andric // 4. Set language options. 482*0fca6ea1SDimitry Andric lldb::LanguageType language = expr.Language().AsLanguageType(); 4830b57cec5SDimitry Andric LangOptions &lang_opts = m_compiler->getLangOpts(); 4840b57cec5SDimitry Andric 4850b57cec5SDimitry Andric switch (language) { 4860b57cec5SDimitry Andric case lldb::eLanguageTypeC: 4870b57cec5SDimitry Andric case lldb::eLanguageTypeC89: 4880b57cec5SDimitry Andric case lldb::eLanguageTypeC99: 4890b57cec5SDimitry Andric case lldb::eLanguageTypeC11: 4900b57cec5SDimitry Andric // FIXME: the following language option is a temporary workaround, 4910b57cec5SDimitry Andric // to "ask for C, get C++." 4920b57cec5SDimitry Andric // For now, the expression parser must use C++ anytime the language is a C 4930b57cec5SDimitry Andric // family language, because the expression parser uses features of C++ to 4940b57cec5SDimitry Andric // capture values. 4950b57cec5SDimitry Andric lang_opts.CPlusPlus = true; 4960b57cec5SDimitry Andric break; 4970b57cec5SDimitry Andric case lldb::eLanguageTypeObjC: 4980b57cec5SDimitry Andric lang_opts.ObjC = true; 4990b57cec5SDimitry Andric // FIXME: the following language option is a temporary workaround, 5000b57cec5SDimitry Andric // to "ask for ObjC, get ObjC++" (see comment above). 5010b57cec5SDimitry Andric lang_opts.CPlusPlus = true; 5020b57cec5SDimitry Andric 5030b57cec5SDimitry Andric // Clang now sets as default C++14 as the default standard (with 5040b57cec5SDimitry Andric // GNU extensions), so we do the same here to avoid mismatches that 5050b57cec5SDimitry Andric // cause compiler error when evaluating expressions (e.g. nullptr not found 5060b57cec5SDimitry Andric // as it's a C++11 feature). Currently lldb evaluates C++14 as C++11 (see 5070b57cec5SDimitry Andric // two lines below) so we decide to be consistent with that, but this could 5080b57cec5SDimitry Andric // be re-evaluated in the future. 5090b57cec5SDimitry Andric lang_opts.CPlusPlus11 = true; 5100b57cec5SDimitry Andric break; 51106c3fb27SDimitry Andric case lldb::eLanguageTypeC_plus_plus_20: 51206c3fb27SDimitry Andric lang_opts.CPlusPlus20 = true; 51306c3fb27SDimitry Andric [[fallthrough]]; 51406c3fb27SDimitry Andric case lldb::eLanguageTypeC_plus_plus_17: 51506c3fb27SDimitry Andric // FIXME: add a separate case for CPlusPlus14. Currently folded into C++17 51606c3fb27SDimitry Andric // because C++14 is the default standard for Clang but enabling CPlusPlus14 51706c3fb27SDimitry Andric // expression evaluatino doesn't pass the test-suite cleanly. 51806c3fb27SDimitry Andric lang_opts.CPlusPlus14 = true; 51906c3fb27SDimitry Andric lang_opts.CPlusPlus17 = true; 52006c3fb27SDimitry Andric [[fallthrough]]; 5210b57cec5SDimitry Andric case lldb::eLanguageTypeC_plus_plus: 5220b57cec5SDimitry Andric case lldb::eLanguageTypeC_plus_plus_11: 5230b57cec5SDimitry Andric case lldb::eLanguageTypeC_plus_plus_14: 5240b57cec5SDimitry Andric lang_opts.CPlusPlus11 = true; 5250b57cec5SDimitry Andric m_compiler->getHeaderSearchOpts().UseLibcxx = true; 526bdd1243dSDimitry Andric [[fallthrough]]; 5270b57cec5SDimitry Andric case lldb::eLanguageTypeC_plus_plus_03: 5280b57cec5SDimitry Andric lang_opts.CPlusPlus = true; 529*0fca6ea1SDimitry Andric if (process_sp 530*0fca6ea1SDimitry Andric // We're stopped in a frame without debug-info. The user probably 531*0fca6ea1SDimitry Andric // intends to make global queries (which should include Objective-C). 532*0fca6ea1SDimitry Andric && !(frame_sp && frame_sp->HasDebugInformation())) 5330b57cec5SDimitry Andric lang_opts.ObjC = 5340b57cec5SDimitry Andric process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC) != nullptr; 5350b57cec5SDimitry Andric break; 5360b57cec5SDimitry Andric case lldb::eLanguageTypeObjC_plus_plus: 5370b57cec5SDimitry Andric case lldb::eLanguageTypeUnknown: 5380b57cec5SDimitry Andric default: 5390b57cec5SDimitry Andric lang_opts.ObjC = true; 5400b57cec5SDimitry Andric lang_opts.CPlusPlus = true; 5410b57cec5SDimitry Andric lang_opts.CPlusPlus11 = true; 5420b57cec5SDimitry Andric m_compiler->getHeaderSearchOpts().UseLibcxx = true; 5430b57cec5SDimitry Andric break; 5440b57cec5SDimitry Andric } 5450b57cec5SDimitry Andric 5460b57cec5SDimitry Andric lang_opts.Bool = true; 5470b57cec5SDimitry Andric lang_opts.WChar = true; 5480b57cec5SDimitry Andric lang_opts.Blocks = true; 5490b57cec5SDimitry Andric lang_opts.DebuggerSupport = 5500b57cec5SDimitry Andric true; // Features specifically for debugger clients 5510b57cec5SDimitry Andric if (expr.DesiredResultType() == Expression::eResultTypeId) 5520b57cec5SDimitry Andric lang_opts.DebuggerCastResultToId = true; 5530b57cec5SDimitry Andric 5540b57cec5SDimitry Andric lang_opts.CharIsSigned = ArchSpec(m_compiler->getTargetOpts().Triple.c_str()) 5550b57cec5SDimitry Andric .CharIsSignedByDefault(); 5560b57cec5SDimitry Andric 5570b57cec5SDimitry Andric // Spell checking is a nice feature, but it ends up completing a lot of types 5580b57cec5SDimitry Andric // that we didn't strictly speaking need to complete. As a result, we spend a 5590b57cec5SDimitry Andric // long time parsing and importing debug information. 5600b57cec5SDimitry Andric lang_opts.SpellChecking = false; 5610b57cec5SDimitry Andric 5620b57cec5SDimitry Andric auto *clang_expr = dyn_cast<ClangUserExpression>(&m_expr); 5630b57cec5SDimitry Andric if (clang_expr && clang_expr->DidImportCxxModules()) { 5640b57cec5SDimitry Andric LLDB_LOG(log, "Adding lang options for importing C++ modules"); 5650b57cec5SDimitry Andric 5660b57cec5SDimitry Andric lang_opts.Modules = true; 5670b57cec5SDimitry Andric // We want to implicitly build modules. 5680b57cec5SDimitry Andric lang_opts.ImplicitModules = true; 5690b57cec5SDimitry Andric // To automatically import all submodules when we import 'std'. 5700b57cec5SDimitry Andric lang_opts.ModulesLocalVisibility = false; 5710b57cec5SDimitry Andric 5720b57cec5SDimitry Andric // We use the @import statements, so we need this: 5730b57cec5SDimitry Andric // FIXME: We could use the modules-ts, but that currently doesn't work. 5740b57cec5SDimitry Andric lang_opts.ObjC = true; 5750b57cec5SDimitry Andric 5760b57cec5SDimitry Andric // Options we need to parse libc++ code successfully. 5770b57cec5SDimitry Andric // FIXME: We should ask the driver for the appropriate default flags. 5780b57cec5SDimitry Andric lang_opts.GNUMode = true; 5790b57cec5SDimitry Andric lang_opts.GNUKeywords = true; 5800b57cec5SDimitry Andric lang_opts.CPlusPlus11 = true; 5815f757f3fSDimitry Andric lang_opts.BuiltinHeadersInSystemModules = true; 5820b57cec5SDimitry Andric 5839dba64beSDimitry Andric // The Darwin libc expects this macro to be set. 5849dba64beSDimitry Andric lang_opts.GNUCVersion = 40201; 5859dba64beSDimitry Andric 5860b57cec5SDimitry Andric SetupModuleHeaderPaths(m_compiler.get(), m_include_directories, 5870b57cec5SDimitry Andric target_sp); 5880b57cec5SDimitry Andric } 5890b57cec5SDimitry Andric 5900b57cec5SDimitry Andric if (process_sp && lang_opts.ObjC) { 5910b57cec5SDimitry Andric if (auto *runtime = ObjCLanguageRuntime::Get(*process_sp)) { 59206c3fb27SDimitry Andric switch (runtime->GetRuntimeVersion()) { 59306c3fb27SDimitry Andric case ObjCLanguageRuntime::ObjCRuntimeVersions::eAppleObjC_V2: 5940b57cec5SDimitry Andric lang_opts.ObjCRuntime.set(ObjCRuntime::MacOSX, VersionTuple(10, 7)); 59506c3fb27SDimitry Andric break; 59606c3fb27SDimitry Andric case ObjCLanguageRuntime::ObjCRuntimeVersions::eObjC_VersionUnknown: 59706c3fb27SDimitry Andric case ObjCLanguageRuntime::ObjCRuntimeVersions::eAppleObjC_V1: 5980b57cec5SDimitry Andric lang_opts.ObjCRuntime.set(ObjCRuntime::FragileMacOSX, 5990b57cec5SDimitry Andric VersionTuple(10, 7)); 60006c3fb27SDimitry Andric break; 60106c3fb27SDimitry Andric case ObjCLanguageRuntime::ObjCRuntimeVersions::eGNUstep_libobjc2: 60206c3fb27SDimitry Andric lang_opts.ObjCRuntime.set(ObjCRuntime::GNUstep, VersionTuple(2, 0)); 60306c3fb27SDimitry Andric break; 60406c3fb27SDimitry Andric } 6050b57cec5SDimitry Andric 6060b57cec5SDimitry Andric if (runtime->HasNewLiteralsAndIndexing()) 6070b57cec5SDimitry Andric lang_opts.DebuggerObjCLiteral = true; 6080b57cec5SDimitry Andric } 6090b57cec5SDimitry Andric } 6100b57cec5SDimitry Andric 6110b57cec5SDimitry Andric lang_opts.ThreadsafeStatics = false; 6120b57cec5SDimitry Andric lang_opts.AccessControl = false; // Debuggers get universal access 6130b57cec5SDimitry Andric lang_opts.DollarIdents = true; // $ indicates a persistent variable name 6140b57cec5SDimitry Andric // We enable all builtin functions beside the builtins from libc/libm (e.g. 6150b57cec5SDimitry Andric // 'fopen'). Those libc functions are already correctly handled by LLDB, and 6160b57cec5SDimitry Andric // additionally enabling them as expandable builtins is breaking Clang. 6170b57cec5SDimitry Andric lang_opts.NoBuiltin = true; 6180b57cec5SDimitry Andric 6190b57cec5SDimitry Andric // Set CodeGen options 6200b57cec5SDimitry Andric m_compiler->getCodeGenOpts().EmitDeclMetadata = true; 6210b57cec5SDimitry Andric m_compiler->getCodeGenOpts().InstrumentFunctions = false; 6229dba64beSDimitry Andric m_compiler->getCodeGenOpts().setFramePointer( 6239dba64beSDimitry Andric CodeGenOptions::FramePointerKind::All); 6240b57cec5SDimitry Andric if (generate_debug_info) 6250b57cec5SDimitry Andric m_compiler->getCodeGenOpts().setDebugInfo(codegenoptions::FullDebugInfo); 6260b57cec5SDimitry Andric else 6270b57cec5SDimitry Andric m_compiler->getCodeGenOpts().setDebugInfo(codegenoptions::NoDebugInfo); 6280b57cec5SDimitry Andric 6290b57cec5SDimitry Andric // Disable some warnings. 630e8d8bef9SDimitry Andric SetupDefaultClangDiagnostics(*m_compiler); 6310b57cec5SDimitry Andric 6320b57cec5SDimitry Andric // Inform the target of the language options 6330b57cec5SDimitry Andric // 6340b57cec5SDimitry Andric // FIXME: We shouldn't need to do this, the target should be immutable once 6350b57cec5SDimitry Andric // created. This complexity should be lifted elsewhere. 636fe6060f1SDimitry Andric m_compiler->getTarget().adjust(m_compiler->getDiagnostics(), 637fe6060f1SDimitry Andric m_compiler->getLangOpts()); 6380b57cec5SDimitry Andric 63906c3fb27SDimitry Andric // 5. Set up the diagnostic buffer for reporting errors 6400b57cec5SDimitry Andric 6419dba64beSDimitry Andric auto diag_mgr = new ClangDiagnosticManagerAdapter( 6429dba64beSDimitry Andric m_compiler->getDiagnostics().getDiagnosticOptions()); 6439dba64beSDimitry Andric m_compiler->getDiagnostics().setClient(diag_mgr); 6440b57cec5SDimitry Andric 64506c3fb27SDimitry Andric // 6. Set up the source management objects inside the compiler 6460b57cec5SDimitry Andric m_compiler->createFileManager(); 6470b57cec5SDimitry Andric if (!m_compiler->hasSourceManager()) 6480b57cec5SDimitry Andric m_compiler->createSourceManager(m_compiler->getFileManager()); 6490b57cec5SDimitry Andric m_compiler->createPreprocessor(TU_Complete); 6500b57cec5SDimitry Andric 651e8d8bef9SDimitry Andric switch (language) { 652e8d8bef9SDimitry Andric case lldb::eLanguageTypeC: 653e8d8bef9SDimitry Andric case lldb::eLanguageTypeC89: 654e8d8bef9SDimitry Andric case lldb::eLanguageTypeC99: 655e8d8bef9SDimitry Andric case lldb::eLanguageTypeC11: 656e8d8bef9SDimitry Andric case lldb::eLanguageTypeObjC: 657e8d8bef9SDimitry Andric // This is not a C++ expression but we enabled C++ as explained above. 658e8d8bef9SDimitry Andric // Remove all C++ keywords from the PP so that the user can still use 659e8d8bef9SDimitry Andric // variables that have C++ keywords as names (e.g. 'int template;'). 660e8d8bef9SDimitry Andric RemoveAllCppKeywords(m_compiler->getPreprocessor().getIdentifierTable()); 661e8d8bef9SDimitry Andric break; 662e8d8bef9SDimitry Andric default: 663e8d8bef9SDimitry Andric break; 664e8d8bef9SDimitry Andric } 665e8d8bef9SDimitry Andric 666480093f4SDimitry Andric if (auto *clang_persistent_vars = llvm::cast<ClangPersistentVariables>( 6670b57cec5SDimitry Andric target_sp->GetPersistentExpressionStateForLanguage( 668480093f4SDimitry Andric lldb::eLanguageTypeC))) { 669fe6060f1SDimitry Andric if (std::shared_ptr<ClangModulesDeclVendor> decl_vendor = 670fe6060f1SDimitry Andric clang_persistent_vars->GetClangModulesDeclVendor()) { 671480093f4SDimitry Andric std::unique_ptr<PPCallbacks> pp_callbacks( 672480093f4SDimitry Andric new LLDBPreprocessorCallbacks(*decl_vendor, *clang_persistent_vars, 673480093f4SDimitry Andric m_compiler->getSourceManager())); 6740b57cec5SDimitry Andric m_pp_callbacks = 6750b57cec5SDimitry Andric static_cast<LLDBPreprocessorCallbacks *>(pp_callbacks.get()); 6760b57cec5SDimitry Andric m_compiler->getPreprocessor().addPPCallbacks(std::move(pp_callbacks)); 6770b57cec5SDimitry Andric } 678480093f4SDimitry Andric } 6790b57cec5SDimitry Andric 68006c3fb27SDimitry Andric // 7. Most of this we get from the CompilerInstance, but we also want to give 6810b57cec5SDimitry Andric // the context an ExternalASTSource. 6820b57cec5SDimitry Andric 6830b57cec5SDimitry Andric auto &PP = m_compiler->getPreprocessor(); 6840b57cec5SDimitry Andric auto &builtin_context = PP.getBuiltinInfo(); 6850b57cec5SDimitry Andric builtin_context.initializeBuiltins(PP.getIdentifierTable(), 6860b57cec5SDimitry Andric m_compiler->getLangOpts()); 6870b57cec5SDimitry Andric 6880b57cec5SDimitry Andric m_compiler->createASTContext(); 6890b57cec5SDimitry Andric clang::ASTContext &ast_context = m_compiler->getASTContext(); 6900b57cec5SDimitry Andric 691bdd1243dSDimitry Andric m_ast_context = std::make_shared<TypeSystemClang>( 6925ffd83dbSDimitry Andric "Expression ASTContext for '" + m_filename + "'", ast_context); 6930b57cec5SDimitry Andric 6940b57cec5SDimitry Andric std::string module_name("$__lldb_module"); 6950b57cec5SDimitry Andric 6965ffd83dbSDimitry Andric m_llvm_context = std::make_unique<LLVMContext>(); 6970b57cec5SDimitry Andric m_code_generator.reset(CreateLLVMCodeGen( 6980b57cec5SDimitry Andric m_compiler->getDiagnostics(), module_name, 699972a253aSDimitry Andric &m_compiler->getVirtualFileSystem(), m_compiler->getHeaderSearchOpts(), 700972a253aSDimitry Andric m_compiler->getPreprocessorOpts(), m_compiler->getCodeGenOpts(), 701972a253aSDimitry Andric *m_llvm_context)); 7020b57cec5SDimitry Andric } 7030b57cec5SDimitry Andric 704fe6060f1SDimitry Andric ClangExpressionParser::~ClangExpressionParser() = default; 7050b57cec5SDimitry Andric 7060b57cec5SDimitry Andric namespace { 7070b57cec5SDimitry Andric 7080b57cec5SDimitry Andric /// \class CodeComplete 7090b57cec5SDimitry Andric /// 7100b57cec5SDimitry Andric /// A code completion consumer for the clang Sema that is responsible for 7110b57cec5SDimitry Andric /// creating the completion suggestions when a user requests completion 7120b57cec5SDimitry Andric /// of an incomplete `expr` invocation. 7130b57cec5SDimitry Andric class CodeComplete : public CodeCompleteConsumer { 7140b57cec5SDimitry Andric CodeCompletionTUInfo m_info; 7150b57cec5SDimitry Andric 7160b57cec5SDimitry Andric std::string m_expr; 7170b57cec5SDimitry Andric unsigned m_position = 0; 7180b57cec5SDimitry Andric /// The printing policy we use when printing declarations for our completion 7190b57cec5SDimitry Andric /// descriptions. 7200b57cec5SDimitry Andric clang::PrintingPolicy m_desc_policy; 7210b57cec5SDimitry Andric 7225ffd83dbSDimitry Andric struct CompletionWithPriority { 7235ffd83dbSDimitry Andric CompletionResult::Completion completion; 7245ffd83dbSDimitry Andric /// See CodeCompletionResult::Priority; 7255ffd83dbSDimitry Andric unsigned Priority; 7265ffd83dbSDimitry Andric 7275ffd83dbSDimitry Andric /// Establishes a deterministic order in a list of CompletionWithPriority. 7285ffd83dbSDimitry Andric /// The order returned here is the order in which the completions are 7295ffd83dbSDimitry Andric /// displayed to the user. 7305ffd83dbSDimitry Andric bool operator<(const CompletionWithPriority &o) const { 7315ffd83dbSDimitry Andric // High priority results should come first. 7325ffd83dbSDimitry Andric if (Priority != o.Priority) 7335ffd83dbSDimitry Andric return Priority > o.Priority; 7345ffd83dbSDimitry Andric 7355ffd83dbSDimitry Andric // Identical priority, so just make sure it's a deterministic order. 7365ffd83dbSDimitry Andric return completion.GetUniqueKey() < o.completion.GetUniqueKey(); 7375ffd83dbSDimitry Andric } 7385ffd83dbSDimitry Andric }; 7395ffd83dbSDimitry Andric 7405ffd83dbSDimitry Andric /// The stored completions. 7415ffd83dbSDimitry Andric /// Warning: These are in a non-deterministic order until they are sorted 7425ffd83dbSDimitry Andric /// and returned back to the caller. 7435ffd83dbSDimitry Andric std::vector<CompletionWithPriority> m_completions; 7445ffd83dbSDimitry Andric 7450b57cec5SDimitry Andric /// Returns true if the given character can be used in an identifier. 7460b57cec5SDimitry Andric /// This also returns true for numbers because for completion we usually 7470b57cec5SDimitry Andric /// just iterate backwards over iterators. 7480b57cec5SDimitry Andric /// 7490b57cec5SDimitry Andric /// Note: lldb uses '$' in its internal identifiers, so we also allow this. 7500b57cec5SDimitry Andric static bool IsIdChar(char c) { 7510b57cec5SDimitry Andric return c == '_' || std::isalnum(c) || c == '$'; 7520b57cec5SDimitry Andric } 7530b57cec5SDimitry Andric 7540b57cec5SDimitry Andric /// Returns true if the given character is used to separate arguments 7550b57cec5SDimitry Andric /// in the command line of lldb. 7560b57cec5SDimitry Andric static bool IsTokenSeparator(char c) { return c == ' ' || c == '\t'; } 7570b57cec5SDimitry Andric 7580b57cec5SDimitry Andric /// Drops all tokens in front of the expression that are unrelated for 7590b57cec5SDimitry Andric /// the completion of the cmd line. 'unrelated' means here that the token 7600b57cec5SDimitry Andric /// is not interested for the lldb completion API result. 7615ffd83dbSDimitry Andric StringRef dropUnrelatedFrontTokens(StringRef cmd) const { 7620b57cec5SDimitry Andric if (cmd.empty()) 7630b57cec5SDimitry Andric return cmd; 7640b57cec5SDimitry Andric 7650b57cec5SDimitry Andric // If we are at the start of a word, then all tokens are unrelated to 7660b57cec5SDimitry Andric // the current completion logic. 7670b57cec5SDimitry Andric if (IsTokenSeparator(cmd.back())) 7680b57cec5SDimitry Andric return StringRef(); 7690b57cec5SDimitry Andric 7700b57cec5SDimitry Andric // Remove all previous tokens from the string as they are unrelated 7710b57cec5SDimitry Andric // to completing the current token. 7720b57cec5SDimitry Andric StringRef to_remove = cmd; 7730b57cec5SDimitry Andric while (!to_remove.empty() && !IsTokenSeparator(to_remove.back())) { 7740b57cec5SDimitry Andric to_remove = to_remove.drop_back(); 7750b57cec5SDimitry Andric } 7760b57cec5SDimitry Andric cmd = cmd.drop_front(to_remove.size()); 7770b57cec5SDimitry Andric 7780b57cec5SDimitry Andric return cmd; 7790b57cec5SDimitry Andric } 7800b57cec5SDimitry Andric 7810b57cec5SDimitry Andric /// Removes the last identifier token from the given cmd line. 7825ffd83dbSDimitry Andric StringRef removeLastToken(StringRef cmd) const { 7830b57cec5SDimitry Andric while (!cmd.empty() && IsIdChar(cmd.back())) { 7840b57cec5SDimitry Andric cmd = cmd.drop_back(); 7850b57cec5SDimitry Andric } 7860b57cec5SDimitry Andric return cmd; 7870b57cec5SDimitry Andric } 7880b57cec5SDimitry Andric 7895ffd83dbSDimitry Andric /// Attempts to merge the given completion from the given position into the 7900b57cec5SDimitry Andric /// existing command. Returns the completion string that can be returned to 7910b57cec5SDimitry Andric /// the lldb completion API. 7920b57cec5SDimitry Andric std::string mergeCompletion(StringRef existing, unsigned pos, 7935ffd83dbSDimitry Andric StringRef completion) const { 7940b57cec5SDimitry Andric StringRef existing_command = existing.substr(0, pos); 7950b57cec5SDimitry Andric // We rewrite the last token with the completion, so let's drop that 7960b57cec5SDimitry Andric // token from the command. 7970b57cec5SDimitry Andric existing_command = removeLastToken(existing_command); 7980b57cec5SDimitry Andric // We also should remove all previous tokens from the command as they 7990b57cec5SDimitry Andric // would otherwise be added to the completion that already has the 8000b57cec5SDimitry Andric // completion. 8010b57cec5SDimitry Andric existing_command = dropUnrelatedFrontTokens(existing_command); 8020b57cec5SDimitry Andric return existing_command.str() + completion.str(); 8030b57cec5SDimitry Andric } 8040b57cec5SDimitry Andric 8050b57cec5SDimitry Andric public: 8060b57cec5SDimitry Andric /// Constructs a CodeComplete consumer that can be attached to a Sema. 807480093f4SDimitry Andric /// 8080b57cec5SDimitry Andric /// \param[out] expr 8090b57cec5SDimitry Andric /// The whole expression string that we are currently parsing. This 8100b57cec5SDimitry Andric /// string needs to be equal to the input the user typed, and NOT the 8110b57cec5SDimitry Andric /// final code that Clang is parsing. 8120b57cec5SDimitry Andric /// \param[out] position 8130b57cec5SDimitry Andric /// The character position of the user cursor in the `expr` parameter. 8140b57cec5SDimitry Andric /// 8155ffd83dbSDimitry Andric CodeComplete(clang::LangOptions ops, std::string expr, unsigned position) 8160b57cec5SDimitry Andric : CodeCompleteConsumer(CodeCompleteOptions()), 8170b57cec5SDimitry Andric m_info(std::make_shared<GlobalCodeCompletionAllocator>()), m_expr(expr), 8185ffd83dbSDimitry Andric m_position(position), m_desc_policy(ops) { 8190b57cec5SDimitry Andric 8200b57cec5SDimitry Andric // Ensure that the printing policy is producing a description that is as 8210b57cec5SDimitry Andric // short as possible. 8220b57cec5SDimitry Andric m_desc_policy.SuppressScope = true; 8230b57cec5SDimitry Andric m_desc_policy.SuppressTagKeyword = true; 8240b57cec5SDimitry Andric m_desc_policy.FullyQualifiedName = false; 8250b57cec5SDimitry Andric m_desc_policy.TerseOutput = true; 8260b57cec5SDimitry Andric m_desc_policy.IncludeNewlines = false; 8270b57cec5SDimitry Andric m_desc_policy.UseVoidForZeroParams = false; 8280b57cec5SDimitry Andric m_desc_policy.Bool = true; 8290b57cec5SDimitry Andric } 8300b57cec5SDimitry Andric 8310b57cec5SDimitry Andric /// \name Code-completion filtering 8320b57cec5SDimitry Andric /// Check if the result should be filtered out. 8330b57cec5SDimitry Andric bool isResultFilteredOut(StringRef Filter, 8340b57cec5SDimitry Andric CodeCompletionResult Result) override { 8350b57cec5SDimitry Andric // This code is mostly copied from CodeCompleteConsumer. 8360b57cec5SDimitry Andric switch (Result.Kind) { 8370b57cec5SDimitry Andric case CodeCompletionResult::RK_Declaration: 8380b57cec5SDimitry Andric return !( 8390b57cec5SDimitry Andric Result.Declaration->getIdentifier() && 8405f757f3fSDimitry Andric Result.Declaration->getIdentifier()->getName().starts_with(Filter)); 8410b57cec5SDimitry Andric case CodeCompletionResult::RK_Keyword: 8425f757f3fSDimitry Andric return !StringRef(Result.Keyword).starts_with(Filter); 8430b57cec5SDimitry Andric case CodeCompletionResult::RK_Macro: 8445f757f3fSDimitry Andric return !Result.Macro->getName().starts_with(Filter); 8450b57cec5SDimitry Andric case CodeCompletionResult::RK_Pattern: 8465f757f3fSDimitry Andric return !StringRef(Result.Pattern->getAsString()).starts_with(Filter); 8470b57cec5SDimitry Andric } 8480b57cec5SDimitry Andric // If we trigger this assert or the above switch yields a warning, then 8490b57cec5SDimitry Andric // CodeCompletionResult has been enhanced with more kinds of completion 8500b57cec5SDimitry Andric // results. Expand the switch above in this case. 8510b57cec5SDimitry Andric assert(false && "Unknown completion result type?"); 8520b57cec5SDimitry Andric // If we reach this, then we should just ignore whatever kind of unknown 8530b57cec5SDimitry Andric // result we got back. We probably can't turn it into any kind of useful 8540b57cec5SDimitry Andric // completion suggestion with the existing code. 8550b57cec5SDimitry Andric return true; 8560b57cec5SDimitry Andric } 8570b57cec5SDimitry Andric 8585ffd83dbSDimitry Andric private: 8595ffd83dbSDimitry Andric /// Generate the completion strings for the given CodeCompletionResult. 8605ffd83dbSDimitry Andric /// Note that this function has to process results that could come in 8615ffd83dbSDimitry Andric /// non-deterministic order, so this function should have no side effects. 8625ffd83dbSDimitry Andric /// To make this easier to enforce, this function and all its parameters 8635ffd83dbSDimitry Andric /// should always be const-qualified. 864bdd1243dSDimitry Andric /// \return Returns std::nullopt if no completion should be provided for the 8655ffd83dbSDimitry Andric /// given CodeCompletionResult. 866bdd1243dSDimitry Andric std::optional<CompletionWithPriority> 8675ffd83dbSDimitry Andric getCompletionForResult(const CodeCompletionResult &R) const { 8680b57cec5SDimitry Andric std::string ToInsert; 8690b57cec5SDimitry Andric std::string Description; 8700b57cec5SDimitry Andric // Handle the different completion kinds that come from the Sema. 8710b57cec5SDimitry Andric switch (R.Kind) { 8720b57cec5SDimitry Andric case CodeCompletionResult::RK_Declaration: { 8730b57cec5SDimitry Andric const NamedDecl *D = R.Declaration; 8740b57cec5SDimitry Andric ToInsert = R.Declaration->getNameAsString(); 8750b57cec5SDimitry Andric // If we have a function decl that has no arguments we want to 8760b57cec5SDimitry Andric // complete the empty parantheses for the user. If the function has 8770b57cec5SDimitry Andric // arguments, we at least complete the opening bracket. 8780b57cec5SDimitry Andric if (const FunctionDecl *F = dyn_cast<FunctionDecl>(D)) { 8790b57cec5SDimitry Andric if (F->getNumParams() == 0) 8800b57cec5SDimitry Andric ToInsert += "()"; 8810b57cec5SDimitry Andric else 8820b57cec5SDimitry Andric ToInsert += "("; 8830b57cec5SDimitry Andric raw_string_ostream OS(Description); 8840b57cec5SDimitry Andric F->print(OS, m_desc_policy, false); 8850b57cec5SDimitry Andric OS.flush(); 8860b57cec5SDimitry Andric } else if (const VarDecl *V = dyn_cast<VarDecl>(D)) { 8870b57cec5SDimitry Andric Description = V->getType().getAsString(m_desc_policy); 8880b57cec5SDimitry Andric } else if (const FieldDecl *F = dyn_cast<FieldDecl>(D)) { 8890b57cec5SDimitry Andric Description = F->getType().getAsString(m_desc_policy); 8900b57cec5SDimitry Andric } else if (const NamespaceDecl *N = dyn_cast<NamespaceDecl>(D)) { 8910b57cec5SDimitry Andric // If we try to complete a namespace, then we can directly append 8920b57cec5SDimitry Andric // the '::'. 8930b57cec5SDimitry Andric if (!N->isAnonymousNamespace()) 8940b57cec5SDimitry Andric ToInsert += "::"; 8950b57cec5SDimitry Andric } 8960b57cec5SDimitry Andric break; 8970b57cec5SDimitry Andric } 8980b57cec5SDimitry Andric case CodeCompletionResult::RK_Keyword: 8990b57cec5SDimitry Andric ToInsert = R.Keyword; 9000b57cec5SDimitry Andric break; 9010b57cec5SDimitry Andric case CodeCompletionResult::RK_Macro: 9020b57cec5SDimitry Andric ToInsert = R.Macro->getName().str(); 9030b57cec5SDimitry Andric break; 9040b57cec5SDimitry Andric case CodeCompletionResult::RK_Pattern: 9050b57cec5SDimitry Andric ToInsert = R.Pattern->getTypedText(); 9060b57cec5SDimitry Andric break; 9070b57cec5SDimitry Andric } 9080b57cec5SDimitry Andric // We also filter some internal lldb identifiers here. The user 9090b57cec5SDimitry Andric // shouldn't see these. 9105f757f3fSDimitry Andric if (llvm::StringRef(ToInsert).starts_with("$__lldb_")) 911bdd1243dSDimitry Andric return std::nullopt; 9125ffd83dbSDimitry Andric if (ToInsert.empty()) 913bdd1243dSDimitry Andric return std::nullopt; 9140b57cec5SDimitry Andric // Merge the suggested Token into the existing command line to comply 9150b57cec5SDimitry Andric // with the kind of result the lldb API expects. 9160b57cec5SDimitry Andric std::string CompletionSuggestion = 9170b57cec5SDimitry Andric mergeCompletion(m_expr, m_position, ToInsert); 9185ffd83dbSDimitry Andric 9195ffd83dbSDimitry Andric CompletionResult::Completion completion(CompletionSuggestion, Description, 9205ffd83dbSDimitry Andric CompletionMode::Normal); 9215ffd83dbSDimitry Andric return {{completion, R.Priority}}; 9220b57cec5SDimitry Andric } 9235ffd83dbSDimitry Andric 9245ffd83dbSDimitry Andric public: 9255ffd83dbSDimitry Andric /// Adds the completions to the given CompletionRequest. 9265ffd83dbSDimitry Andric void GetCompletions(CompletionRequest &request) { 9275ffd83dbSDimitry Andric // Bring m_completions into a deterministic order and pass it on to the 9285ffd83dbSDimitry Andric // CompletionRequest. 9295ffd83dbSDimitry Andric llvm::sort(m_completions); 9305ffd83dbSDimitry Andric 9315ffd83dbSDimitry Andric for (const CompletionWithPriority &C : m_completions) 9325ffd83dbSDimitry Andric request.AddCompletion(C.completion.GetCompletion(), 9335ffd83dbSDimitry Andric C.completion.GetDescription(), 9345ffd83dbSDimitry Andric C.completion.GetMode()); 9355ffd83dbSDimitry Andric } 9365ffd83dbSDimitry Andric 9375ffd83dbSDimitry Andric /// \name Code-completion callbacks 9385ffd83dbSDimitry Andric /// Process the finalized code-completion results. 9395ffd83dbSDimitry Andric void ProcessCodeCompleteResults(Sema &SemaRef, CodeCompletionContext Context, 9405ffd83dbSDimitry Andric CodeCompletionResult *Results, 9415ffd83dbSDimitry Andric unsigned NumResults) override { 9425ffd83dbSDimitry Andric 9435ffd83dbSDimitry Andric // The Sema put the incomplete token we try to complete in here during 9445ffd83dbSDimitry Andric // lexing, so we need to retrieve it here to know what we are completing. 9455ffd83dbSDimitry Andric StringRef Filter = SemaRef.getPreprocessor().getCodeCompletionFilter(); 9465ffd83dbSDimitry Andric 9475ffd83dbSDimitry Andric // Iterate over all the results. Filter out results we don't want and 9485ffd83dbSDimitry Andric // process the rest. 9495ffd83dbSDimitry Andric for (unsigned I = 0; I != NumResults; ++I) { 9505ffd83dbSDimitry Andric // Filter the results with the information from the Sema. 9515ffd83dbSDimitry Andric if (!Filter.empty() && isResultFilteredOut(Filter, Results[I])) 9525ffd83dbSDimitry Andric continue; 9535ffd83dbSDimitry Andric 9545ffd83dbSDimitry Andric CodeCompletionResult &R = Results[I]; 955bdd1243dSDimitry Andric std::optional<CompletionWithPriority> CompletionAndPriority = 9565ffd83dbSDimitry Andric getCompletionForResult(R); 9575ffd83dbSDimitry Andric if (!CompletionAndPriority) 9585ffd83dbSDimitry Andric continue; 9595ffd83dbSDimitry Andric m_completions.push_back(*CompletionAndPriority); 9600b57cec5SDimitry Andric } 9610b57cec5SDimitry Andric } 9620b57cec5SDimitry Andric 9630b57cec5SDimitry Andric /// \param S the semantic-analyzer object for which code-completion is being 9640b57cec5SDimitry Andric /// done. 9650b57cec5SDimitry Andric /// 9660b57cec5SDimitry Andric /// \param CurrentArg the index of the current argument. 9670b57cec5SDimitry Andric /// 9680b57cec5SDimitry Andric /// \param Candidates an array of overload candidates. 9690b57cec5SDimitry Andric /// 9700b57cec5SDimitry Andric /// \param NumCandidates the number of overload candidates 9710b57cec5SDimitry Andric void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg, 9720b57cec5SDimitry Andric OverloadCandidate *Candidates, 9730b57cec5SDimitry Andric unsigned NumCandidates, 97404eeddc0SDimitry Andric SourceLocation OpenParLoc, 97504eeddc0SDimitry Andric bool Braced) override { 9760b57cec5SDimitry Andric // At the moment we don't filter out any overloaded candidates. 9770b57cec5SDimitry Andric } 9780b57cec5SDimitry Andric 9790b57cec5SDimitry Andric CodeCompletionAllocator &getAllocator() override { 9800b57cec5SDimitry Andric return m_info.getAllocator(); 9810b57cec5SDimitry Andric } 9820b57cec5SDimitry Andric 9830b57cec5SDimitry Andric CodeCompletionTUInfo &getCodeCompletionTUInfo() override { return m_info; } 9840b57cec5SDimitry Andric }; 9850b57cec5SDimitry Andric } // namespace 9860b57cec5SDimitry Andric 9870b57cec5SDimitry Andric bool ClangExpressionParser::Complete(CompletionRequest &request, unsigned line, 9880b57cec5SDimitry Andric unsigned pos, unsigned typed_pos) { 9890b57cec5SDimitry Andric DiagnosticManager mgr; 9900b57cec5SDimitry Andric // We need the raw user expression here because that's what the CodeComplete 9910b57cec5SDimitry Andric // class uses to provide completion suggestions. 9920b57cec5SDimitry Andric // However, the `Text` method only gives us the transformed expression here. 9930b57cec5SDimitry Andric // To actually get the raw user input here, we have to cast our expression to 9940b57cec5SDimitry Andric // the LLVMUserExpression which exposes the right API. This should never fail 9950b57cec5SDimitry Andric // as we always have a ClangUserExpression whenever we call this. 9960b57cec5SDimitry Andric ClangUserExpression *llvm_expr = cast<ClangUserExpression>(&m_expr); 9975ffd83dbSDimitry Andric CodeComplete CC(m_compiler->getLangOpts(), llvm_expr->GetUserText(), 9980b57cec5SDimitry Andric typed_pos); 9990b57cec5SDimitry Andric // We don't need a code generator for parsing. 10000b57cec5SDimitry Andric m_code_generator.reset(); 10010b57cec5SDimitry Andric // Start parsing the expression with our custom code completion consumer. 10020b57cec5SDimitry Andric ParseInternal(mgr, &CC, line, pos); 10035ffd83dbSDimitry Andric CC.GetCompletions(request); 10040b57cec5SDimitry Andric return true; 10050b57cec5SDimitry Andric } 10060b57cec5SDimitry Andric 10070b57cec5SDimitry Andric unsigned ClangExpressionParser::Parse(DiagnosticManager &diagnostic_manager) { 10080b57cec5SDimitry Andric return ParseInternal(diagnostic_manager); 10090b57cec5SDimitry Andric } 10100b57cec5SDimitry Andric 10110b57cec5SDimitry Andric unsigned 10120b57cec5SDimitry Andric ClangExpressionParser::ParseInternal(DiagnosticManager &diagnostic_manager, 10130b57cec5SDimitry Andric CodeCompleteConsumer *completion_consumer, 10140b57cec5SDimitry Andric unsigned completion_line, 10150b57cec5SDimitry Andric unsigned completion_column) { 10160b57cec5SDimitry Andric ClangDiagnosticManagerAdapter *adapter = 10170b57cec5SDimitry Andric static_cast<ClangDiagnosticManagerAdapter *>( 10180b57cec5SDimitry Andric m_compiler->getDiagnostics().getClient()); 10190b57cec5SDimitry Andric 10200b57cec5SDimitry Andric adapter->ResetManager(&diagnostic_manager); 10210b57cec5SDimitry Andric 10220b57cec5SDimitry Andric const char *expr_text = m_expr.Text(); 10230b57cec5SDimitry Andric 10240b57cec5SDimitry Andric clang::SourceManager &source_mgr = m_compiler->getSourceManager(); 10250b57cec5SDimitry Andric bool created_main_file = false; 10260b57cec5SDimitry Andric 10270b57cec5SDimitry Andric // Clang wants to do completion on a real file known by Clang's file manager, 10280b57cec5SDimitry Andric // so we have to create one to make this work. 10290b57cec5SDimitry Andric // TODO: We probably could also simulate to Clang's file manager that there 10300b57cec5SDimitry Andric // is a real file that contains our code. 10310b57cec5SDimitry Andric bool should_create_file = completion_consumer != nullptr; 10320b57cec5SDimitry Andric 10330b57cec5SDimitry Andric // We also want a real file on disk if we generate full debug info. 10340b57cec5SDimitry Andric should_create_file |= m_compiler->getCodeGenOpts().getDebugInfo() == 10350b57cec5SDimitry Andric codegenoptions::FullDebugInfo; 10360b57cec5SDimitry Andric 10370b57cec5SDimitry Andric if (should_create_file) { 10380b57cec5SDimitry Andric int temp_fd = -1; 10390b57cec5SDimitry Andric llvm::SmallString<128> result_path; 10400b57cec5SDimitry Andric if (FileSpec tmpdir_file_spec = HostInfo::GetProcessTempDir()) { 10410b57cec5SDimitry Andric tmpdir_file_spec.AppendPathComponent("lldb-%%%%%%.expr"); 10420b57cec5SDimitry Andric std::string temp_source_path = tmpdir_file_spec.GetPath(); 10430b57cec5SDimitry Andric llvm::sys::fs::createUniqueFile(temp_source_path, temp_fd, result_path); 10440b57cec5SDimitry Andric } else { 10450b57cec5SDimitry Andric llvm::sys::fs::createTemporaryFile("lldb", "expr", temp_fd, result_path); 10460b57cec5SDimitry Andric } 10470b57cec5SDimitry Andric 10480b57cec5SDimitry Andric if (temp_fd != -1) { 1049349cc55cSDimitry Andric lldb_private::NativeFile file(temp_fd, File::eOpenOptionWriteOnly, true); 10500b57cec5SDimitry Andric const size_t expr_text_len = strlen(expr_text); 10510b57cec5SDimitry Andric size_t bytes_written = expr_text_len; 10520b57cec5SDimitry Andric if (file.Write(expr_text, bytes_written).Success()) { 10530b57cec5SDimitry Andric if (bytes_written == expr_text_len) { 10540b57cec5SDimitry Andric file.Close(); 1055e8d8bef9SDimitry Andric if (auto fileEntry = m_compiler->getFileManager().getOptionalFileRef( 1056e8d8bef9SDimitry Andric result_path)) { 10570b57cec5SDimitry Andric source_mgr.setMainFileID(source_mgr.createFileID( 10589dba64beSDimitry Andric *fileEntry, 10590b57cec5SDimitry Andric SourceLocation(), SrcMgr::C_User)); 10600b57cec5SDimitry Andric created_main_file = true; 10610b57cec5SDimitry Andric } 10620b57cec5SDimitry Andric } 10630b57cec5SDimitry Andric } 10640b57cec5SDimitry Andric } 10659dba64beSDimitry Andric } 10660b57cec5SDimitry Andric 10670b57cec5SDimitry Andric if (!created_main_file) { 10680b57cec5SDimitry Andric std::unique_ptr<MemoryBuffer> memory_buffer = 10699dba64beSDimitry Andric MemoryBuffer::getMemBufferCopy(expr_text, m_filename); 10700b57cec5SDimitry Andric source_mgr.setMainFileID(source_mgr.createFileID(std::move(memory_buffer))); 10710b57cec5SDimitry Andric } 10720b57cec5SDimitry Andric 10735ffd83dbSDimitry Andric adapter->BeginSourceFile(m_compiler->getLangOpts(), 10740b57cec5SDimitry Andric &m_compiler->getPreprocessor()); 10750b57cec5SDimitry Andric 10760b57cec5SDimitry Andric ClangExpressionHelper *type_system_helper = 10770b57cec5SDimitry Andric dyn_cast<ClangExpressionHelper>(m_expr.GetTypeSystemHelper()); 10780b57cec5SDimitry Andric 10790b57cec5SDimitry Andric // If we want to parse for code completion, we need to attach our code 10800b57cec5SDimitry Andric // completion consumer to the Sema and specify a completion position. 10810b57cec5SDimitry Andric // While parsing the Sema will call this consumer with the provided 10820b57cec5SDimitry Andric // completion suggestions. 10830b57cec5SDimitry Andric if (completion_consumer) { 10845f757f3fSDimitry Andric auto main_file = 10855f757f3fSDimitry Andric source_mgr.getFileEntryRefForID(source_mgr.getMainFileID()); 10860b57cec5SDimitry Andric auto &PP = m_compiler->getPreprocessor(); 10870b57cec5SDimitry Andric // Lines and columns start at 1 in Clang, but code completion positions are 10880b57cec5SDimitry Andric // indexed from 0, so we need to add 1 to the line and column here. 10890b57cec5SDimitry Andric ++completion_line; 10900b57cec5SDimitry Andric ++completion_column; 10915f757f3fSDimitry Andric PP.SetCodeCompletionPoint(*main_file, completion_line, completion_column); 10920b57cec5SDimitry Andric } 10930b57cec5SDimitry Andric 10940b57cec5SDimitry Andric ASTConsumer *ast_transformer = 10950b57cec5SDimitry Andric type_system_helper->ASTTransformer(m_code_generator.get()); 10960b57cec5SDimitry Andric 10970b57cec5SDimitry Andric std::unique_ptr<clang::ASTConsumer> Consumer; 10980b57cec5SDimitry Andric if (ast_transformer) { 10995ffd83dbSDimitry Andric Consumer = std::make_unique<ASTConsumerForwarder>(ast_transformer); 11000b57cec5SDimitry Andric } else if (m_code_generator) { 11015ffd83dbSDimitry Andric Consumer = std::make_unique<ASTConsumerForwarder>(m_code_generator.get()); 11020b57cec5SDimitry Andric } else { 11035ffd83dbSDimitry Andric Consumer = std::make_unique<ASTConsumer>(); 11040b57cec5SDimitry Andric } 11050b57cec5SDimitry Andric 11060b57cec5SDimitry Andric clang::ASTContext &ast_context = m_compiler->getASTContext(); 11070b57cec5SDimitry Andric 11080b57cec5SDimitry Andric m_compiler->setSema(new Sema(m_compiler->getPreprocessor(), ast_context, 11090b57cec5SDimitry Andric *Consumer, TU_Complete, completion_consumer)); 11100b57cec5SDimitry Andric m_compiler->setASTConsumer(std::move(Consumer)); 11110b57cec5SDimitry Andric 11120b57cec5SDimitry Andric if (ast_context.getLangOpts().Modules) { 1113480093f4SDimitry Andric m_compiler->createASTReader(); 11140b57cec5SDimitry Andric m_ast_context->setSema(&m_compiler->getSema()); 11150b57cec5SDimitry Andric } 11160b57cec5SDimitry Andric 11170b57cec5SDimitry Andric ClangExpressionDeclMap *decl_map = type_system_helper->DeclMap(); 11180b57cec5SDimitry Andric if (decl_map) { 11190b57cec5SDimitry Andric decl_map->InstallCodeGenerator(&m_compiler->getASTConsumer()); 1120e8d8bef9SDimitry Andric decl_map->InstallDiagnosticManager(diagnostic_manager); 11210b57cec5SDimitry Andric 11220b57cec5SDimitry Andric clang::ExternalASTSource *ast_source = decl_map->CreateProxy(); 11230b57cec5SDimitry Andric 11240b57cec5SDimitry Andric if (ast_context.getExternalSource()) { 11250b57cec5SDimitry Andric auto module_wrapper = 11260b57cec5SDimitry Andric new ExternalASTSourceWrapper(ast_context.getExternalSource()); 11270b57cec5SDimitry Andric 11280b57cec5SDimitry Andric auto ast_source_wrapper = new ExternalASTSourceWrapper(ast_source); 11290b57cec5SDimitry Andric 11300b57cec5SDimitry Andric auto multiplexer = 11310b57cec5SDimitry Andric new SemaSourceWithPriorities(*module_wrapper, *ast_source_wrapper); 11320b57cec5SDimitry Andric IntrusiveRefCntPtr<ExternalASTSource> Source(multiplexer); 11330b57cec5SDimitry Andric ast_context.setExternalSource(Source); 11340b57cec5SDimitry Andric } else { 11350b57cec5SDimitry Andric ast_context.setExternalSource(ast_source); 11360b57cec5SDimitry Andric } 1137480093f4SDimitry Andric decl_map->InstallASTContext(*m_ast_context); 11380b57cec5SDimitry Andric } 11390b57cec5SDimitry Andric 11400b57cec5SDimitry Andric // Check that the ASTReader is properly attached to ASTContext and Sema. 11410b57cec5SDimitry Andric if (ast_context.getLangOpts().Modules) { 11420b57cec5SDimitry Andric assert(m_compiler->getASTContext().getExternalSource() && 11430b57cec5SDimitry Andric "ASTContext doesn't know about the ASTReader?"); 11440b57cec5SDimitry Andric assert(m_compiler->getSema().getExternalSource() && 11450b57cec5SDimitry Andric "Sema doesn't know about the ASTReader?"); 11460b57cec5SDimitry Andric } 11470b57cec5SDimitry Andric 11480b57cec5SDimitry Andric { 11490b57cec5SDimitry Andric llvm::CrashRecoveryContextCleanupRegistrar<Sema> CleanupSema( 11500b57cec5SDimitry Andric &m_compiler->getSema()); 11510b57cec5SDimitry Andric ParseAST(m_compiler->getSema(), false, false); 11520b57cec5SDimitry Andric } 11530b57cec5SDimitry Andric 11540b57cec5SDimitry Andric // Make sure we have no pointer to the Sema we are about to destroy. 11550b57cec5SDimitry Andric if (ast_context.getLangOpts().Modules) 11560b57cec5SDimitry Andric m_ast_context->setSema(nullptr); 11570b57cec5SDimitry Andric // Destroy the Sema. This is necessary because we want to emulate the 11580b57cec5SDimitry Andric // original behavior of ParseAST (which also destroys the Sema after parsing). 11590b57cec5SDimitry Andric m_compiler->setSema(nullptr); 11600b57cec5SDimitry Andric 11615ffd83dbSDimitry Andric adapter->EndSourceFile(); 11620b57cec5SDimitry Andric 11635ffd83dbSDimitry Andric unsigned num_errors = adapter->getNumErrors(); 11640b57cec5SDimitry Andric 11650b57cec5SDimitry Andric if (m_pp_callbacks && m_pp_callbacks->hasErrors()) { 11660b57cec5SDimitry Andric num_errors++; 1167*0fca6ea1SDimitry Andric diagnostic_manager.PutString(lldb::eSeverityError, 11680b57cec5SDimitry Andric "while importing modules:"); 11690b57cec5SDimitry Andric diagnostic_manager.AppendMessageToDiagnostic( 11700b57cec5SDimitry Andric m_pp_callbacks->getErrorString()); 11710b57cec5SDimitry Andric } 11720b57cec5SDimitry Andric 11730b57cec5SDimitry Andric if (!num_errors) { 11740b57cec5SDimitry Andric type_system_helper->CommitPersistentDecls(); 11750b57cec5SDimitry Andric } 11760b57cec5SDimitry Andric 11770b57cec5SDimitry Andric adapter->ResetManager(); 11780b57cec5SDimitry Andric 11790b57cec5SDimitry Andric return num_errors; 11800b57cec5SDimitry Andric } 11810b57cec5SDimitry Andric 11820b57cec5SDimitry Andric std::string 11830b57cec5SDimitry Andric ClangExpressionParser::GetClangTargetABI(const ArchSpec &target_arch) { 11840b57cec5SDimitry Andric std::string abi; 11850b57cec5SDimitry Andric 11860b57cec5SDimitry Andric if (target_arch.IsMIPS()) { 11870b57cec5SDimitry Andric switch (target_arch.GetFlags() & ArchSpec::eMIPSABI_mask) { 11880b57cec5SDimitry Andric case ArchSpec::eMIPSABI_N64: 11890b57cec5SDimitry Andric abi = "n64"; 11900b57cec5SDimitry Andric break; 11910b57cec5SDimitry Andric case ArchSpec::eMIPSABI_N32: 11920b57cec5SDimitry Andric abi = "n32"; 11930b57cec5SDimitry Andric break; 11940b57cec5SDimitry Andric case ArchSpec::eMIPSABI_O32: 11950b57cec5SDimitry Andric abi = "o32"; 11960b57cec5SDimitry Andric break; 11970b57cec5SDimitry Andric default: 11980b57cec5SDimitry Andric break; 11990b57cec5SDimitry Andric } 12000b57cec5SDimitry Andric } 12010b57cec5SDimitry Andric return abi; 12020b57cec5SDimitry Andric } 12030b57cec5SDimitry Andric 12045ffd83dbSDimitry Andric /// Applies the given Fix-It hint to the given commit. 12055ffd83dbSDimitry Andric static void ApplyFixIt(const FixItHint &fixit, clang::edit::Commit &commit) { 12065ffd83dbSDimitry Andric // This is cobbed from clang::Rewrite::FixItRewriter. 12075ffd83dbSDimitry Andric if (fixit.CodeToInsert.empty()) { 12085ffd83dbSDimitry Andric if (fixit.InsertFromRange.isValid()) { 12095ffd83dbSDimitry Andric commit.insertFromRange(fixit.RemoveRange.getBegin(), 12105ffd83dbSDimitry Andric fixit.InsertFromRange, /*afterToken=*/false, 12115ffd83dbSDimitry Andric fixit.BeforePreviousInsertions); 12125ffd83dbSDimitry Andric return; 12135ffd83dbSDimitry Andric } 12145ffd83dbSDimitry Andric commit.remove(fixit.RemoveRange); 12155ffd83dbSDimitry Andric return; 12165ffd83dbSDimitry Andric } 12175ffd83dbSDimitry Andric if (fixit.RemoveRange.isTokenRange() || 12185ffd83dbSDimitry Andric fixit.RemoveRange.getBegin() != fixit.RemoveRange.getEnd()) { 12195ffd83dbSDimitry Andric commit.replace(fixit.RemoveRange, fixit.CodeToInsert); 12205ffd83dbSDimitry Andric return; 12215ffd83dbSDimitry Andric } 12225ffd83dbSDimitry Andric commit.insert(fixit.RemoveRange.getBegin(), fixit.CodeToInsert, 12235ffd83dbSDimitry Andric /*afterToken=*/false, fixit.BeforePreviousInsertions); 12245ffd83dbSDimitry Andric } 12255ffd83dbSDimitry Andric 12260b57cec5SDimitry Andric bool ClangExpressionParser::RewriteExpression( 12270b57cec5SDimitry Andric DiagnosticManager &diagnostic_manager) { 12280b57cec5SDimitry Andric clang::SourceManager &source_manager = m_compiler->getSourceManager(); 12290b57cec5SDimitry Andric clang::edit::EditedSource editor(source_manager, m_compiler->getLangOpts(), 12300b57cec5SDimitry Andric nullptr); 12310b57cec5SDimitry Andric clang::edit::Commit commit(editor); 12320b57cec5SDimitry Andric clang::Rewriter rewriter(source_manager, m_compiler->getLangOpts()); 12330b57cec5SDimitry Andric 12340b57cec5SDimitry Andric class RewritesReceiver : public edit::EditsReceiver { 12350b57cec5SDimitry Andric Rewriter &rewrite; 12360b57cec5SDimitry Andric 12370b57cec5SDimitry Andric public: 12380b57cec5SDimitry Andric RewritesReceiver(Rewriter &in_rewrite) : rewrite(in_rewrite) {} 12390b57cec5SDimitry Andric 12400b57cec5SDimitry Andric void insert(SourceLocation loc, StringRef text) override { 12410b57cec5SDimitry Andric rewrite.InsertText(loc, text); 12420b57cec5SDimitry Andric } 12430b57cec5SDimitry Andric void replace(CharSourceRange range, StringRef text) override { 12440b57cec5SDimitry Andric rewrite.ReplaceText(range.getBegin(), rewrite.getRangeSize(range), text); 12450b57cec5SDimitry Andric } 12460b57cec5SDimitry Andric }; 12470b57cec5SDimitry Andric 12480b57cec5SDimitry Andric RewritesReceiver rewrites_receiver(rewriter); 12490b57cec5SDimitry Andric 12500b57cec5SDimitry Andric const DiagnosticList &diagnostics = diagnostic_manager.Diagnostics(); 12510b57cec5SDimitry Andric size_t num_diags = diagnostics.size(); 12520b57cec5SDimitry Andric if (num_diags == 0) 12530b57cec5SDimitry Andric return false; 12540b57cec5SDimitry Andric 12559dba64beSDimitry Andric for (const auto &diag : diagnostic_manager.Diagnostics()) { 12569dba64beSDimitry Andric const auto *diagnostic = llvm::dyn_cast<ClangDiagnostic>(diag.get()); 12575ffd83dbSDimitry Andric if (!diagnostic) 12585ffd83dbSDimitry Andric continue; 12595ffd83dbSDimitry Andric if (!diagnostic->HasFixIts()) 12605ffd83dbSDimitry Andric continue; 12615ffd83dbSDimitry Andric for (const FixItHint &fixit : diagnostic->FixIts()) 12625ffd83dbSDimitry Andric ApplyFixIt(fixit, commit); 12630b57cec5SDimitry Andric } 12640b57cec5SDimitry Andric 12650b57cec5SDimitry Andric // FIXME - do we want to try to propagate specific errors here? 12660b57cec5SDimitry Andric if (!commit.isCommitable()) 12670b57cec5SDimitry Andric return false; 12680b57cec5SDimitry Andric else if (!editor.commit(commit)) 12690b57cec5SDimitry Andric return false; 12700b57cec5SDimitry Andric 12710b57cec5SDimitry Andric // Now play all the edits, and stash the result in the diagnostic manager. 12720b57cec5SDimitry Andric editor.applyRewrites(rewrites_receiver); 12730b57cec5SDimitry Andric RewriteBuffer &main_file_buffer = 12740b57cec5SDimitry Andric rewriter.getEditBuffer(source_manager.getMainFileID()); 12750b57cec5SDimitry Andric 12760b57cec5SDimitry Andric std::string fixed_expression; 12770b57cec5SDimitry Andric llvm::raw_string_ostream out_stream(fixed_expression); 12780b57cec5SDimitry Andric 12790b57cec5SDimitry Andric main_file_buffer.write(out_stream); 12800b57cec5SDimitry Andric out_stream.flush(); 12810b57cec5SDimitry Andric diagnostic_manager.SetFixedExpression(fixed_expression); 12820b57cec5SDimitry Andric 12830b57cec5SDimitry Andric return true; 12840b57cec5SDimitry Andric } 12850b57cec5SDimitry Andric 12860b57cec5SDimitry Andric static bool FindFunctionInModule(ConstString &mangled_name, 12870b57cec5SDimitry Andric llvm::Module *module, const char *orig_name) { 12880b57cec5SDimitry Andric for (const auto &func : module->getFunctionList()) { 12890b57cec5SDimitry Andric const StringRef &name = func.getName(); 1290349cc55cSDimitry Andric if (name.contains(orig_name)) { 12910b57cec5SDimitry Andric mangled_name.SetString(name); 12920b57cec5SDimitry Andric return true; 12930b57cec5SDimitry Andric } 12940b57cec5SDimitry Andric } 12950b57cec5SDimitry Andric 12960b57cec5SDimitry Andric return false; 12970b57cec5SDimitry Andric } 12980b57cec5SDimitry Andric 1299*0fca6ea1SDimitry Andric lldb_private::Status ClangExpressionParser::DoPrepareForExecution( 13000b57cec5SDimitry Andric lldb::addr_t &func_addr, lldb::addr_t &func_end, 13010b57cec5SDimitry Andric lldb::IRExecutionUnitSP &execution_unit_sp, ExecutionContext &exe_ctx, 13020b57cec5SDimitry Andric bool &can_interpret, ExecutionPolicy execution_policy) { 13030b57cec5SDimitry Andric func_addr = LLDB_INVALID_ADDRESS; 13040b57cec5SDimitry Andric func_end = LLDB_INVALID_ADDRESS; 130581ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Expressions); 13060b57cec5SDimitry Andric 13070b57cec5SDimitry Andric lldb_private::Status err; 13080b57cec5SDimitry Andric 13090b57cec5SDimitry Andric std::unique_ptr<llvm::Module> llvm_module_up( 13100b57cec5SDimitry Andric m_code_generator->ReleaseModule()); 13110b57cec5SDimitry Andric 13120b57cec5SDimitry Andric if (!llvm_module_up) { 13130b57cec5SDimitry Andric err.SetErrorToGenericError(); 13140b57cec5SDimitry Andric err.SetErrorString("IR doesn't contain a module"); 13150b57cec5SDimitry Andric return err; 13160b57cec5SDimitry Andric } 13170b57cec5SDimitry Andric 13180b57cec5SDimitry Andric ConstString function_name; 13190b57cec5SDimitry Andric 13200b57cec5SDimitry Andric if (execution_policy != eExecutionPolicyTopLevel) { 13210b57cec5SDimitry Andric // Find the actual name of the function (it's often mangled somehow) 13220b57cec5SDimitry Andric 13230b57cec5SDimitry Andric if (!FindFunctionInModule(function_name, llvm_module_up.get(), 13240b57cec5SDimitry Andric m_expr.FunctionName())) { 13250b57cec5SDimitry Andric err.SetErrorToGenericError(); 13260b57cec5SDimitry Andric err.SetErrorStringWithFormat("Couldn't find %s() in the module", 13270b57cec5SDimitry Andric m_expr.FunctionName()); 13280b57cec5SDimitry Andric return err; 13290b57cec5SDimitry Andric } else { 13309dba64beSDimitry Andric LLDB_LOGF(log, "Found function %s for %s", function_name.AsCString(), 13310b57cec5SDimitry Andric m_expr.FunctionName()); 13320b57cec5SDimitry Andric } 13330b57cec5SDimitry Andric } 13340b57cec5SDimitry Andric 13350b57cec5SDimitry Andric SymbolContext sc; 13360b57cec5SDimitry Andric 13370b57cec5SDimitry Andric if (lldb::StackFrameSP frame_sp = exe_ctx.GetFrameSP()) { 13380b57cec5SDimitry Andric sc = frame_sp->GetSymbolContext(lldb::eSymbolContextEverything); 13390b57cec5SDimitry Andric } else if (lldb::TargetSP target_sp = exe_ctx.GetTargetSP()) { 13400b57cec5SDimitry Andric sc.target_sp = target_sp; 13410b57cec5SDimitry Andric } 13420b57cec5SDimitry Andric 13430b57cec5SDimitry Andric LLVMUserExpression::IRPasses custom_passes; 13440b57cec5SDimitry Andric { 13450b57cec5SDimitry Andric auto lang = m_expr.Language(); 13469dba64beSDimitry Andric LLDB_LOGF(log, "%s - Current expression language is %s\n", __FUNCTION__, 1347*0fca6ea1SDimitry Andric lang.GetDescription().data()); 13480b57cec5SDimitry Andric lldb::ProcessSP process_sp = exe_ctx.GetProcessSP(); 13490b57cec5SDimitry Andric if (process_sp && lang != lldb::eLanguageTypeUnknown) { 1350*0fca6ea1SDimitry Andric auto runtime = process_sp->GetLanguageRuntime(lang.AsLanguageType()); 13510b57cec5SDimitry Andric if (runtime) 13520b57cec5SDimitry Andric runtime->GetIRPasses(custom_passes); 13530b57cec5SDimitry Andric } 13540b57cec5SDimitry Andric } 13550b57cec5SDimitry Andric 13560b57cec5SDimitry Andric if (custom_passes.EarlyPasses) { 13579dba64beSDimitry Andric LLDB_LOGF(log, 13589dba64beSDimitry Andric "%s - Running Early IR Passes from LanguageRuntime on " 13590b57cec5SDimitry Andric "expression module '%s'", 13600b57cec5SDimitry Andric __FUNCTION__, m_expr.FunctionName()); 13610b57cec5SDimitry Andric 13620b57cec5SDimitry Andric custom_passes.EarlyPasses->run(*llvm_module_up); 13630b57cec5SDimitry Andric } 13640b57cec5SDimitry Andric 13650b57cec5SDimitry Andric execution_unit_sp = std::make_shared<IRExecutionUnit>( 13660b57cec5SDimitry Andric m_llvm_context, // handed off here 13670b57cec5SDimitry Andric llvm_module_up, // handed off here 13680b57cec5SDimitry Andric function_name, exe_ctx.GetTargetSP(), sc, 13690b57cec5SDimitry Andric m_compiler->getTargetOpts().Features); 13700b57cec5SDimitry Andric 13710b57cec5SDimitry Andric ClangExpressionHelper *type_system_helper = 13720b57cec5SDimitry Andric dyn_cast<ClangExpressionHelper>(m_expr.GetTypeSystemHelper()); 13730b57cec5SDimitry Andric ClangExpressionDeclMap *decl_map = 13740b57cec5SDimitry Andric type_system_helper->DeclMap(); // result can be NULL 13750b57cec5SDimitry Andric 13760b57cec5SDimitry Andric if (decl_map) { 13775ffd83dbSDimitry Andric StreamString error_stream; 13780b57cec5SDimitry Andric IRForTarget ir_for_target(decl_map, m_expr.NeedsVariableResolution(), 13799dba64beSDimitry Andric *execution_unit_sp, error_stream, 13800b57cec5SDimitry Andric function_name.AsCString()); 13810b57cec5SDimitry Andric 13825ffd83dbSDimitry Andric if (!ir_for_target.runOnModule(*execution_unit_sp->GetModule())) { 13835ffd83dbSDimitry Andric err.SetErrorString(error_stream.GetString()); 13840b57cec5SDimitry Andric return err; 13850b57cec5SDimitry Andric } 13860b57cec5SDimitry Andric 13870b57cec5SDimitry Andric Process *process = exe_ctx.GetProcessPtr(); 13880b57cec5SDimitry Andric 13890b57cec5SDimitry Andric if (execution_policy != eExecutionPolicyAlways && 13900b57cec5SDimitry Andric execution_policy != eExecutionPolicyTopLevel) { 13910b57cec5SDimitry Andric lldb_private::Status interpret_error; 13920b57cec5SDimitry Andric 13930b57cec5SDimitry Andric bool interpret_function_calls = 13940b57cec5SDimitry Andric !process ? false : process->CanInterpretFunctionCalls(); 13950b57cec5SDimitry Andric can_interpret = IRInterpreter::CanInterpret( 13960b57cec5SDimitry Andric *execution_unit_sp->GetModule(), *execution_unit_sp->GetFunction(), 13970b57cec5SDimitry Andric interpret_error, interpret_function_calls); 13980b57cec5SDimitry Andric 13990b57cec5SDimitry Andric if (!can_interpret && execution_policy == eExecutionPolicyNever) { 1400480093f4SDimitry Andric err.SetErrorStringWithFormat( 1401480093f4SDimitry Andric "Can't evaluate the expression without a running target due to: %s", 14020b57cec5SDimitry Andric interpret_error.AsCString()); 14030b57cec5SDimitry Andric return err; 14040b57cec5SDimitry Andric } 14050b57cec5SDimitry Andric } 14060b57cec5SDimitry Andric 14070b57cec5SDimitry Andric if (!process && execution_policy == eExecutionPolicyAlways) { 14080b57cec5SDimitry Andric err.SetErrorString("Expression needed to run in the target, but the " 14090b57cec5SDimitry Andric "target can't be run"); 14100b57cec5SDimitry Andric return err; 14110b57cec5SDimitry Andric } 14120b57cec5SDimitry Andric 14130b57cec5SDimitry Andric if (!process && execution_policy == eExecutionPolicyTopLevel) { 14140b57cec5SDimitry Andric err.SetErrorString("Top-level code needs to be inserted into a runnable " 14150b57cec5SDimitry Andric "target, but the target can't be run"); 14160b57cec5SDimitry Andric return err; 14170b57cec5SDimitry Andric } 14180b57cec5SDimitry Andric 14190b57cec5SDimitry Andric if (execution_policy == eExecutionPolicyAlways || 14200b57cec5SDimitry Andric (execution_policy != eExecutionPolicyTopLevel && !can_interpret)) { 14210b57cec5SDimitry Andric if (m_expr.NeedsValidation() && process) { 14220b57cec5SDimitry Andric if (!process->GetDynamicCheckers()) { 14230b57cec5SDimitry Andric ClangDynamicCheckerFunctions *dynamic_checkers = 14240b57cec5SDimitry Andric new ClangDynamicCheckerFunctions(); 14250b57cec5SDimitry Andric 142606c3fb27SDimitry Andric DiagnosticManager install_diags; 142706c3fb27SDimitry Andric if (Error Err = dynamic_checkers->Install(install_diags, exe_ctx)) { 142806c3fb27SDimitry Andric std::string ErrMsg = "couldn't install checkers: " + toString(std::move(Err)); 142906c3fb27SDimitry Andric if (install_diags.Diagnostics().size()) 143006c3fb27SDimitry Andric ErrMsg = ErrMsg + "\n" + install_diags.GetString().c_str(); 143106c3fb27SDimitry Andric err.SetErrorString(ErrMsg); 14320b57cec5SDimitry Andric return err; 14330b57cec5SDimitry Andric } 14340b57cec5SDimitry Andric 14350b57cec5SDimitry Andric process->SetDynamicCheckers(dynamic_checkers); 14360b57cec5SDimitry Andric 14379dba64beSDimitry Andric LLDB_LOGF(log, "== [ClangExpressionParser::PrepareForExecution] " 14380b57cec5SDimitry Andric "Finished installing dynamic checkers =="); 14390b57cec5SDimitry Andric } 14400b57cec5SDimitry Andric 14410b57cec5SDimitry Andric if (auto *checker_funcs = llvm::dyn_cast<ClangDynamicCheckerFunctions>( 14420b57cec5SDimitry Andric process->GetDynamicCheckers())) { 14430b57cec5SDimitry Andric IRDynamicChecks ir_dynamic_checks(*checker_funcs, 14440b57cec5SDimitry Andric function_name.AsCString()); 14450b57cec5SDimitry Andric 14460b57cec5SDimitry Andric llvm::Module *module = execution_unit_sp->GetModule(); 14470b57cec5SDimitry Andric if (!module || !ir_dynamic_checks.runOnModule(*module)) { 14480b57cec5SDimitry Andric err.SetErrorToGenericError(); 14490b57cec5SDimitry Andric err.SetErrorString("Couldn't add dynamic checks to the expression"); 14500b57cec5SDimitry Andric return err; 14510b57cec5SDimitry Andric } 14520b57cec5SDimitry Andric 14530b57cec5SDimitry Andric if (custom_passes.LatePasses) { 14549dba64beSDimitry Andric LLDB_LOGF(log, 14559dba64beSDimitry Andric "%s - Running Late IR Passes from LanguageRuntime on " 14560b57cec5SDimitry Andric "expression module '%s'", 14570b57cec5SDimitry Andric __FUNCTION__, m_expr.FunctionName()); 14580b57cec5SDimitry Andric 14590b57cec5SDimitry Andric custom_passes.LatePasses->run(*module); 14600b57cec5SDimitry Andric } 14610b57cec5SDimitry Andric } 14620b57cec5SDimitry Andric } 14630b57cec5SDimitry Andric } 14640b57cec5SDimitry Andric 14650b57cec5SDimitry Andric if (execution_policy == eExecutionPolicyAlways || 14660b57cec5SDimitry Andric execution_policy == eExecutionPolicyTopLevel || !can_interpret) { 14670b57cec5SDimitry Andric execution_unit_sp->GetRunnableInfo(err, func_addr, func_end); 14680b57cec5SDimitry Andric } 14690b57cec5SDimitry Andric } else { 14700b57cec5SDimitry Andric execution_unit_sp->GetRunnableInfo(err, func_addr, func_end); 14710b57cec5SDimitry Andric } 14720b57cec5SDimitry Andric 14730b57cec5SDimitry Andric return err; 14740b57cec5SDimitry Andric } 1475