xref: /freebsd-src/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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