9#include "clang/AST/ASTContext.h"
10#include "clang/AST/ASTDiagnostic.h"
11#include "clang/AST/ExternalASTSource.h"
12#include "clang/AST/PrettyPrinter.h"
13#include "clang/Basic/Builtins.h"
14#include "clang/Basic/DiagnosticIDs.h"
15#include "clang/Basic/SourceLocation.h"
16#include "clang/Basic/TargetInfo.h"
17#include "clang/Basic/Version.h"
18#include "clang/CodeGen/CodeGenAction.h"
19#include "clang/CodeGen/ModuleBuilder.h"
20#include "clang/Edit/Commit.h"
21#include "clang/Edit/EditedSource.h"
22#include "clang/Edit/EditsReceiver.h"
23#include "clang/Frontend/CompilerInstance.h"
24#include "clang/Frontend/CompilerInvocation.h"
25#include "clang/Frontend/FrontendActions.h"
26#include "clang/Frontend/FrontendDiagnostic.h"
27#include "clang/Frontend/FrontendPluginRegistry.h"
28#include "clang/Frontend/TextDiagnosticBuffer.h"
29#include "clang/Frontend/TextDiagnosticPrinter.h"
30#include "clang/Lex/Preprocessor.h"
31#include "clang/Parse/ParseAST.h"
32#include "clang/Rewrite/Core/Rewriter.h"
33#include "clang/Rewrite/Frontend/FrontendActions.h"
34#include "clang/Sema/CodeCompleteConsumer.h"
35#include "clang/Sema/Sema.h"
36#include "clang/Sema/SemaConsumer.h"
38#include "llvm/ADT/StringRef.h"
39#include "llvm/ExecutionEngine/ExecutionEngine.h"
40#include "llvm/Support/CrashRecoveryContext.h"
41#include "llvm/Support/Debug.h"
42#include "llvm/Support/FileSystem.h"
43#include "llvm/Support/TargetSelect.h"
45#include "llvm/IR/LLVMContext.h"
46#include "llvm/IR/Module.h"
47#include "llvm/Support/DynamicLibrary.h"
48#include "llvm/Support/ErrorHandling.h"
49#include "llvm/Support/MemoryBuffer.h"
50#include "llvm/Support/Signals.h"
51#include "llvm/TargetParser/Host.h"
116 clang::SourceManager &source_mgr)
120 void moduleImport(SourceLocation import_location, clang::ModuleIdPath path,
121 const clang::Module * )
override {
124 llvm::StringRef filename =
125 m_source_mgr.getPresumedLoc(import_location).getFilename();
131 for (
const std::pair<IdentifierInfo *, SourceLocation> &component : path)
150 for (
auto &fix_it : Info.getFixItHints()) {
160 DiagnosticOptions *options =
new DiagnosticOptions(opts);
161 options->ShowPresumedLoc =
true;
162 options->ShowLevel =
false;
163 m_os = std::make_shared<llvm::raw_string_ostream>(
m_output);
165 std::make_shared<clang::TextDiagnosticPrinter>(*
m_os, options);
184 const clang::Diagnostic &Info)
override {
193 llvm::SmallVector<char, 32> diag_str;
194 Info.FormatDiagnostic(diag_str);
195 diag_str.push_back(
'\0');
196 const char *plain_diag = diag_str.data();
197 LLDB_LOG(log,
"Received diagnostic outside parsing: {0}", plain_diag);
203 DiagnosticConsumer::HandleDiagnostic(DiagLevel, Info);
211 bool make_new_diagnostic =
true;
214 case DiagnosticsEngine::Level::Fatal:
215 case DiagnosticsEngine::Level::Error:
218 case DiagnosticsEngine::Level::Warning:
221 case DiagnosticsEngine::Level::Remark:
222 case DiagnosticsEngine::Level::Ignored:
225 case DiagnosticsEngine::Level::Note:
227 make_new_diagnostic =
false;
238 if (!clang_diag || clang_diag->HasFixIts())
246 if (make_new_diagnostic) {
249 std::string stripped_output =
250 std::string(llvm::StringRef(
m_output).trim());
252 auto new_diagnostic = std::make_unique<ClangDiagnostic>(
253 stripped_output, severity, Info.getID());
276 std::shared_ptr<llvm::raw_string_ostream>
m_os;
282 std::vector<std::string> include_directories,
286 HeaderSearchOptions &search_opts = compiler->getHeaderSearchOpts();
288 for (
const std::string &dir : include_directories) {
289 search_opts.AddPath(dir, frontend::System,
false,
true);
290 LLDB_LOG(log,
"Added user include dir: {0}", dir);
293 llvm::SmallString<128> module_cache;
295 props.GetClangModulesCachePath().GetPath(module_cache);
296 search_opts.ModuleCachePath = std::string(module_cache.str());
297 LLDB_LOG(log,
"Using module cache path: {0}", module_cache.c_str());
301 search_opts.ImplicitModuleMaps =
true;
309 if (token ==
"using")
312 if (token ==
"__null")
315 LangOptions cpp_lang_opts;
316 cpp_lang_opts.CPlusPlus =
true;
317 cpp_lang_opts.CPlusPlus11 =
true;
318 cpp_lang_opts.CPlusPlus20 =
true;
320 clang::IdentifierInfo &ii = idents.get(token);
323 if (!ii.isCPlusPlusKeyword(cpp_lang_opts))
326 if (ii.getTokenID() == clang::tok::identifier)
330 ii.revertTokenIDToIdentifier();
335#define KEYWORD(NAME, FLAGS) RemoveCppKeyword(idents, llvm::StringRef(#NAME));
336#include "clang/Basic/TokenKinds.def"
342 const std::vector<const char *> groupsToIgnore = {
345 "unused-getter-return-value",
347 for (
const char *group : groupsToIgnore) {
348 compiler.getDiagnostics().setSeverityForGroup(
349 clang::diag::Flavor::WarningOrError, group,
350 clang::diag::Severity::Ignored, SourceLocation());
360 bool generate_debug_info, std::vector<std::string> include_directories,
361 std::string filename)
363 m_pp_callbacks(nullptr),
364 m_include_directories(std::move(include_directories)),
365 m_filename(std::move(filename)) {
377 "Can't make an expression parser with a null scope.");
385 "Can't make an expression parser with a null target.");
390 m_compiler = std::make_unique<CompilerInstance>();
400 target_arch = target_sp->GetArchitecture();
402 const auto target_machine = target_arch.
GetMachine();
413 frame_lang = frame_sp->GetLanguage();
416 LLDB_LOGF(log,
"Frame has language of type %s",
423 std::string triple = target_arch.
GetTriple().str();
425 LLDB_LOGF(log,
"Using %s as the target triple",
434 m_compiler->getTargetOpts().Triple = llvm::sys::getDefaultTargetTriple();
435 LLDB_LOGF(log,
"Using default target triple of %s",
440 if (
m_compiler->getTargetOpts().Triple.find(
"arm64") == std::string::npos &&
441 m_compiler->getTargetOpts().Triple.find(
"arm") != std::string::npos &&
442 m_compiler->getTargetOpts().Triple.find(
"ios") != std::string::npos) {
446 if (target_machine == llvm::Triple::x86 ||
447 target_machine == llvm::Triple::x86_64) {
448 m_compiler->getTargetOpts().FeaturesAsWritten.push_back(
"+sse");
449 m_compiler->getTargetOpts().FeaturesAsWritten.push_back(
"+sse2");
466 m_compiler->getDiagnostics().setErrorLimit(target_sp->GetExprErrorLimit());
468 auto target_info = TargetInfo::CreateTargetInfo(
471 LLDB_LOGF(log,
"Target datalayout string: '%s'",
472 target_info->getDataLayoutString());
473 LLDB_LOGF(log,
"Target ABI: '%s'", target_info->getABI().str().c_str());
474 LLDB_LOGF(log,
"Target vector alignment: %d",
475 target_info->getMaxVectorAlign());
483 LangOptions &lang_opts =
m_compiler->getLangOpts();
495 lang_opts.CPlusPlus =
true;
498 lang_opts.ObjC =
true;
501 lang_opts.CPlusPlus =
true;
509 lang_opts.CPlusPlus11 =
true;
512 lang_opts.CPlusPlus20 =
true;
518 lang_opts.CPlusPlus14 =
true;
519 lang_opts.CPlusPlus17 =
true;
524 lang_opts.CPlusPlus11 =
true;
525 m_compiler->getHeaderSearchOpts().UseLibcxx =
true;
528 lang_opts.CPlusPlus =
true;
532 && !(frame_sp && frame_sp->HasDebugInformation()))
539 lang_opts.ObjC =
true;
540 lang_opts.CPlusPlus =
true;
541 lang_opts.CPlusPlus11 =
true;
542 m_compiler->getHeaderSearchOpts().UseLibcxx =
true;
546 lang_opts.Bool =
true;
547 lang_opts.WChar =
true;
548 lang_opts.Blocks =
true;
549 lang_opts.DebuggerSupport =
552 lang_opts.DebuggerCastResultToId =
true;
560 lang_opts.SpellChecking =
false;
562 auto *clang_expr = dyn_cast<ClangUserExpression>(&
m_expr);
563 if (clang_expr && clang_expr->DidImportCxxModules()) {
564 LLDB_LOG(log,
"Adding lang options for importing C++ modules");
566 lang_opts.Modules =
true;
568 lang_opts.ImplicitModules =
true;
570 lang_opts.ModulesLocalVisibility =
false;
574 lang_opts.ObjC =
true;
578 lang_opts.GNUMode =
true;
579 lang_opts.GNUKeywords =
true;
580 lang_opts.CPlusPlus11 =
true;
581 lang_opts.BuiltinHeadersInSystemModules =
true;
584 lang_opts.GNUCVersion = 40201;
590 if (process_sp && lang_opts.ObjC) {
592 switch (runtime->GetRuntimeVersion()) {
594 lang_opts.ObjCRuntime.set(ObjCRuntime::MacOSX, VersionTuple(10, 7));
598 lang_opts.ObjCRuntime.set(ObjCRuntime::FragileMacOSX,
599 VersionTuple(10, 7));
602 lang_opts.ObjCRuntime.set(ObjCRuntime::GNUstep, VersionTuple(2, 0));
606 if (runtime->HasNewLiteralsAndIndexing())
607 lang_opts.DebuggerObjCLiteral =
true;
611 lang_opts.ThreadsafeStatics =
false;
612 lang_opts.AccessControl =
false;
613 lang_opts.DollarIdents =
true;
617 lang_opts.NoBuiltin =
true;
620 m_compiler->getCodeGenOpts().EmitDeclMetadata =
true;
621 m_compiler->getCodeGenOpts().InstrumentFunctions =
false;
623 CodeGenOptions::FramePointerKind::All);
624 if (generate_debug_info)
625 m_compiler->getCodeGenOpts().setDebugInfo(codegenoptions::FullDebugInfo);
627 m_compiler->getCodeGenOpts().setDebugInfo(codegenoptions::NoDebugInfo);
642 m_compiler->getDiagnostics().getDiagnosticOptions());
643 m_compiler->getDiagnostics().setClient(diag_mgr);
666 if (
auto *clang_persistent_vars = llvm::cast<ClangPersistentVariables>(
667 target_sp->GetPersistentExpressionStateForLanguage(
669 if (std::shared_ptr<ClangModulesDeclVendor> decl_vendor =
670 clang_persistent_vars->GetClangModulesDeclVendor()) {
671 std::unique_ptr<PPCallbacks> pp_callbacks(
676 m_compiler->getPreprocessor().addPPCallbacks(std::move(pp_callbacks));
684 auto &builtin_context = PP.getBuiltinInfo();
685 builtin_context.initializeBuiltins(PP.getIdentifierTable(),
689 clang::ASTContext &ast_context =
m_compiler->getASTContext();
692 "Expression ASTContext for '" +
m_filename +
"'", ast_context);
694 std::string module_name(
"$__lldb_module");
713class CodeComplete :
public CodeCompleteConsumer {
714 CodeCompletionTUInfo m_info;
717 unsigned m_position = 0;
720 clang::PrintingPolicy m_desc_policy;
722 struct CompletionWithPriority {
730 bool operator<(
const CompletionWithPriority &o)
const {
732 if (Priority != o.Priority)
733 return Priority > o.Priority;
736 return completion.
GetUniqueKey() < o.completion.GetUniqueKey();
743 std::vector<CompletionWithPriority> m_completions;
750 static bool IsIdChar(
char c) {
751 return c ==
'_' || std::isalnum(c) || c ==
'$';
756 static bool IsTokenSeparator(
char c) {
return c ==
' ' || c ==
'\t'; }
761 StringRef dropUnrelatedFrontTokens(StringRef cmd)
const {
767 if (IsTokenSeparator(cmd.back()))
772 StringRef to_remove = cmd;
773 while (!to_remove.empty() && !IsTokenSeparator(to_remove.back())) {
774 to_remove = to_remove.drop_back();
776 cmd = cmd.drop_front(to_remove.size());
782 StringRef removeLastToken(StringRef cmd)
const {
783 while (!cmd.empty() && IsIdChar(cmd.back())) {
784 cmd = cmd.drop_back();
792 std::string mergeCompletion(StringRef existing,
unsigned pos,
793 StringRef completion)
const {
794 StringRef existing_command = existing.substr(0, pos);
797 existing_command = removeLastToken(existing_command);
801 existing_command = dropUnrelatedFrontTokens(existing_command);
802 return existing_command.str() + completion.str();
815 CodeComplete(clang::LangOptions ops, std::string expr,
unsigned position)
816 : CodeCompleteConsumer(CodeCompleteOptions()),
817 m_info(std::make_shared<GlobalCodeCompletionAllocator>()), m_expr(expr),
818 m_position(position), m_desc_policy(ops) {
822 m_desc_policy.SuppressScope =
true;
823 m_desc_policy.SuppressTagKeyword =
true;
824 m_desc_policy.FullyQualifiedName =
false;
825 m_desc_policy.TerseOutput =
true;
826 m_desc_policy.IncludeNewlines =
false;
827 m_desc_policy.UseVoidForZeroParams =
false;
828 m_desc_policy.Bool =
true;
833 bool isResultFilteredOut(StringRef Filter,
834 CodeCompletionResult Result)
override {
836 switch (Result.Kind) {
837 case CodeCompletionResult::RK_Declaration:
839 Result.Declaration->getIdentifier() &&
840 Result.Declaration->getIdentifier()->getName().starts_with(Filter));
841 case CodeCompletionResult::RK_Keyword:
842 return !StringRef(Result.Keyword).starts_with(Filter);
843 case CodeCompletionResult::RK_Macro:
844 return !Result.Macro->getName().starts_with(Filter);
845 case CodeCompletionResult::RK_Pattern:
846 return !StringRef(Result.Pattern->getAsString()).starts_with(Filter);
851 assert(
false &&
"Unknown completion result type?");
866 std::optional<CompletionWithPriority>
867 getCompletionForResult(
const CodeCompletionResult &R)
const {
868 std::string ToInsert;
869 std::string Description;
872 case CodeCompletionResult::RK_Declaration: {
873 const NamedDecl *D = R.Declaration;
874 ToInsert = R.Declaration->getNameAsString();
878 if (
const FunctionDecl *F = dyn_cast<FunctionDecl>(D)) {
879 if (F->getNumParams() == 0)
883 raw_string_ostream
OS(Description);
884 F->print(
OS, m_desc_policy,
false);
886 }
else if (
const VarDecl *V = dyn_cast<VarDecl>(D)) {
887 Description = V->getType().getAsString(m_desc_policy);
888 }
else if (
const FieldDecl *F = dyn_cast<FieldDecl>(D)) {
889 Description = F->getType().getAsString(m_desc_policy);
890 }
else if (
const NamespaceDecl *N = dyn_cast<NamespaceDecl>(D)) {
893 if (!N->isAnonymousNamespace())
898 case CodeCompletionResult::RK_Keyword:
899 ToInsert = R.Keyword;
901 case CodeCompletionResult::RK_Macro:
902 ToInsert = R.Macro->getName().str();
904 case CodeCompletionResult::RK_Pattern:
905 ToInsert = R.Pattern->getTypedText();
910 if (llvm::StringRef(ToInsert).starts_with(
"$__lldb_"))
912 if (ToInsert.empty())
916 std::string CompletionSuggestion =
917 mergeCompletion(m_expr, m_position, ToInsert);
920 CompletionMode::Normal);
921 return {{completion, R.Priority}};
929 llvm::sort(m_completions);
931 for (
const CompletionWithPriority &C : m_completions)
933 C.completion.GetDescription(),
934 C.completion.GetMode());
939 void ProcessCodeCompleteResults(Sema &SemaRef, CodeCompletionContext Context,
940 CodeCompletionResult *Results,
941 unsigned NumResults)
override {
945 StringRef Filter = SemaRef.getPreprocessor().getCodeCompletionFilter();
949 for (
unsigned I = 0; I != NumResults; ++I) {
951 if (!Filter.empty() && isResultFilteredOut(Filter, Results[I]))
954 CodeCompletionResult &R = Results[I];
955 std::optional<CompletionWithPriority> CompletionAndPriority =
956 getCompletionForResult(R);
957 if (!CompletionAndPriority)
959 m_completions.push_back(*CompletionAndPriority);
971 void ProcessOverloadCandidates(Sema &S,
unsigned CurrentArg,
972 OverloadCandidate *Candidates,
973 unsigned NumCandidates,
974 SourceLocation OpenParLoc,
975 bool Braced)
override {
979 CodeCompletionAllocator &getAllocator()
override {
980 return m_info.getAllocator();
983 CodeCompletionTUInfo &getCodeCompletionTUInfo()
override {
return m_info; }
988 unsigned pos,
unsigned typed_pos) {
1003 CC.GetCompletions(request);
1013 CodeCompleteConsumer *completion_consumer,
1014 unsigned completion_line,
1015 unsigned completion_column) {
1024 clang::SourceManager &source_mgr =
m_compiler->getSourceManager();
1025 bool created_main_file =
false;
1031 bool should_create_file = completion_consumer !=
nullptr;
1034 should_create_file |=
m_compiler->getCodeGenOpts().getDebugInfo() ==
1035 codegenoptions::FullDebugInfo;
1037 if (should_create_file) {
1039 llvm::SmallString<128> result_path;
1040 if (
FileSpec tmpdir_file_spec = HostInfo::GetProcessTempDir()) {
1041 tmpdir_file_spec.AppendPathComponent(
"lldb-%%%%%%.expr");
1042 std::string temp_source_path = tmpdir_file_spec.GetPath();
1043 llvm::sys::fs::createUniqueFile(temp_source_path, temp_fd, result_path);
1045 llvm::sys::fs::createTemporaryFile(
"lldb",
"expr", temp_fd, result_path);
1048 if (temp_fd != -1) {
1050 const size_t expr_text_len = strlen(expr_text);
1051 size_t bytes_written = expr_text_len;
1053 if (bytes_written == expr_text_len) {
1055 if (
auto fileEntry =
m_compiler->getFileManager().getOptionalFileRef(
1057 source_mgr.setMainFileID(source_mgr.createFileID(
1059 SourceLocation(), SrcMgr::C_User));
1060 created_main_file =
true;
1067 if (!created_main_file) {
1068 std::unique_ptr<MemoryBuffer> memory_buffer =
1069 MemoryBuffer::getMemBufferCopy(expr_text,
m_filename);
1070 source_mgr.setMainFileID(source_mgr.createFileID(std::move(memory_buffer)));
1083 if (completion_consumer) {
1085 source_mgr.getFileEntryRefForID(source_mgr.getMainFileID());
1090 ++completion_column;
1091 PP.SetCodeCompletionPoint(*main_file, completion_line, completion_column);
1094 ASTConsumer *ast_transformer =
1097 std::unique_ptr<clang::ASTConsumer> Consumer;
1098 if (ast_transformer) {
1099 Consumer = std::make_unique<ASTConsumerForwarder>(ast_transformer);
1103 Consumer = std::make_unique<ASTConsumer>();
1106 clang::ASTContext &ast_context =
m_compiler->getASTContext();
1109 *Consumer, TU_Complete, completion_consumer));
1110 m_compiler->setASTConsumer(std::move(Consumer));
1112 if (ast_context.getLangOpts().Modules) {
1122 clang::ExternalASTSource *ast_source = decl_map->
CreateProxy();
1124 if (ast_context.getExternalSource()) {
1125 auto module_wrapper =
1132 IntrusiveRefCntPtr<ExternalASTSource>
Source(multiplexer);
1133 ast_context.setExternalSource(
Source);
1135 ast_context.setExternalSource(ast_source);
1141 if (ast_context.getLangOpts().Modules) {
1142 assert(
m_compiler->getASTContext().getExternalSource() &&
1143 "ASTContext doesn't know about the ASTReader?");
1144 assert(
m_compiler->getSema().getExternalSource() &&
1145 "Sema doesn't know about the ASTReader?");
1149 llvm::CrashRecoveryContextCleanupRegistrar<Sema> CleanupSema(
1151 ParseAST(
m_compiler->getSema(),
false,
false);
1155 if (ast_context.getLangOpts().Modules)
1163 unsigned num_errors = adapter->getNumErrors();
1168 "while importing modules:");
1186 if (target_arch.
IsMIPS()) {
1205static void ApplyFixIt(
const FixItHint &fixit, clang::edit::Commit &commit) {
1207 if (fixit.CodeToInsert.empty()) {
1208 if (fixit.InsertFromRange.isValid()) {
1209 commit.insertFromRange(fixit.RemoveRange.getBegin(),
1210 fixit.InsertFromRange,
false,
1211 fixit.BeforePreviousInsertions);
1214 commit.remove(fixit.RemoveRange);
1217 if (fixit.RemoveRange.isTokenRange() ||
1218 fixit.RemoveRange.getBegin() != fixit.RemoveRange.getEnd()) {
1219 commit.replace(fixit.RemoveRange, fixit.CodeToInsert);
1222 commit.insert(fixit.RemoveRange.getBegin(), fixit.CodeToInsert,
1223 false, fixit.BeforePreviousInsertions);
1228 clang::SourceManager &source_manager =
m_compiler->getSourceManager();
1229 clang::edit::EditedSource editor(source_manager,
m_compiler->getLangOpts(),
1231 clang::edit::Commit commit(editor);
1232 clang::Rewriter rewriter(source_manager,
m_compiler->getLangOpts());
1234 class RewritesReceiver :
public edit::EditsReceiver {
1238 RewritesReceiver(Rewriter &in_rewrite) : rewrite(in_rewrite) {}
1240 void insert(SourceLocation loc, StringRef text)
override {
1241 rewrite.InsertText(loc, text);
1243 void replace(CharSourceRange range, StringRef text)
override {
1244 rewrite.ReplaceText(range.getBegin(), rewrite.getRangeSize(range), text);
1248 RewritesReceiver rewrites_receiver(rewriter);
1251 size_t num_diags = diagnostics.size();
1255 for (
const auto &diag : diagnostic_manager.
Diagnostics()) {
1256 const auto *diagnostic = llvm::dyn_cast<ClangDiagnostic>(diag.get());
1259 if (!diagnostic->HasFixIts())
1261 for (
const FixItHint &fixit : diagnostic->FixIts())
1266 if (!commit.isCommitable())
1268 else if (!editor.commit(commit))
1272 editor.applyRewrites(rewrites_receiver);
1273 RewriteBuffer &main_file_buffer =
1274 rewriter.getEditBuffer(source_manager.getMainFileID());
1276 std::string fixed_expression;
1277 llvm::raw_string_ostream out_stream(fixed_expression);
1279 main_file_buffer.write(out_stream);
1287 llvm::Module *module,
const char *orig_name) {
1288 for (
const auto &func : module->getFunctionList()) {
1289 const StringRef &name = func.getName();
1290 if (name.contains(orig_name)) {
1309 std::unique_ptr<llvm::Module> llvm_module_up(
1312 if (!llvm_module_up) {
1338 sc = frame_sp->GetSymbolContext(lldb::eSymbolContextEverything);
1346 LLDB_LOGF(log,
"%s - Current expression language is %s\n", __FUNCTION__,
1350 auto runtime = process_sp->GetLanguageRuntime(lang);
1352 runtime->GetIRPasses(custom_passes);
1358 "%s - Running Early IR Passes from LanguageRuntime on "
1359 "expression module '%s'",
1365 execution_unit_sp = std::make_shared<IRExecutionUnit>(
1374 type_system_helper->
DeclMap();
1379 *execution_unit_sp, error_stream,
1382 if (!ir_for_target.
runOnModule(*execution_unit_sp->GetModule())) {
1393 bool interpret_function_calls =
1396 *execution_unit_sp->GetModule(), *execution_unit_sp->GetFunction(),
1397 interpret_error, interpret_function_calls);
1401 "Can't evaluate the expression without a running target due to: %s",
1408 err.
SetErrorString(
"Expression needed to run in the target, but the "
1409 "target can't be run");
1414 err.
SetErrorString(
"Top-level code needs to be inserted into a runnable "
1415 "target, but the target can't be run");
1427 if (
Error Err = dynamic_checkers->
Install(install_diags, exe_ctx)) {
1428 std::string ErrMsg =
"couldn't install checkers: " +
toString(std::move(Err));
1430 ErrMsg = ErrMsg +
"\n" + install_diags.
GetString().c_str();
1437 LLDB_LOGF(log,
"== [ClangExpressionParser::PrepareForExecution] "
1438 "Finished installing dynamic checkers ==");
1441 if (
auto *checker_funcs = llvm::dyn_cast<ClangDynamicCheckerFunctions>(
1446 llvm::Module *module = execution_unit_sp->GetModule();
1447 if (!module || !ir_dynamic_checks.
runOnModule(*module)) {
1449 err.
SetErrorString(
"Couldn't add dynamic checks to the expression");
1455 "%s - Running Late IR Passes from LanguageRuntime on "
1456 "expression module '%s'",
1467 execution_unit_sp->GetRunnableInfo(err, func_addr, func_end);
1470 execution_unit_sp->GetRunnableInfo(err, func_addr, func_end);
1483 if (!execution_unit_sp.get()) {
1485 "can't run static initializers for a NULL execution unit");
1490 err.
SetErrorString(
"can't run static initializers without a thread");
1494 std::vector<lldb::addr_t> static_initializers;
1496 execution_unit_sp->GetStaticInitializers(static_initializers);
1498 for (
lldb::addr_t static_initializer : static_initializers) {
1503 llvm::ArrayRef<lldb::addr_t>(), options));
1508 exe_ctx, call_static_initializer, options, execution_errors);
static void SetupModuleHeaderPaths(CompilerInstance *compiler, std::vector< std::string > include_directories, lldb::TargetSP target_sp)
static void RemoveAllCppKeywords(IdentifierTable &idents)
Remove all C++ keywords from the given identifier table.
static void ApplyFixIt(const FixItHint &fixit, clang::edit::Commit &commit)
Applies the given Fix-It hint to the given commit.
static void AddAllFixIts(ClangDiagnostic *diag, const clang::Diagnostic &Info)
static void SetupDefaultClangDiagnostics(CompilerInstance &compiler)
Configures Clang diagnostics for the expression parser.
static void RemoveCppKeyword(IdentifierTable &idents, llvm::StringRef token)
Iff the given identifier is a C++ keyword, remove it from the identifier table (i....
static bool FindFunctionInModule(ConstString &mangled_name, llvm::Module *module, const char *orig_name)
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
#define LLDB_LOGF(log,...)
void BeginSourceFile(const LangOptions &LO, const Preprocessor *PP) override
void EndSourceFile() override
std::shared_ptr< llvm::raw_string_ostream > m_os
Output stream of m_passthrough.
std::string m_output
Output string filled by m_os.
std::shared_ptr< clang::TextDiagnosticPrinter > m_passthrough
ClangDiagnosticManagerAdapter(DiagnosticOptions &opts)
void ResetManager(DiagnosticManager *manager=nullptr)
void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, const clang::Diagnostic &Info) override
ClangDiagnostic * MaybeGetLastClangDiag() const
Returns the last ClangDiagnostic message that the DiagnosticManager received or a nullptr if the Diag...
DiagnosticManager * m_manager
llvm::StringRef getErrorString()
ClangModulesDeclVendor & m_decl_vendor
void moduleImport(SourceLocation import_location, clang::ModuleIdPath path, const clang::Module *) override
clang::SourceManager & m_source_mgr
ClangPersistentVariables & m_persistent_vars
LLDBPreprocessorCallbacks(ClangModulesDeclVendor &decl_vendor, ClangPersistentVariables &persistent_vars, clang::SourceManager &source_mgr)
StreamString m_error_stream
Transforms the IR for a function to run in the target.
bool runOnModule(llvm::Module &llvm_module)
Run this IR transformer on a single module.
static bool CanInterpret(llvm::Module &module, llvm::Function &function, lldb_private::Status &error, const bool support_function_calls)
A section + offset based address class.
An architecture specification class.
bool IsValid() const
Tests if this ArchSpec is valid.
llvm::Triple & GetTriple()
Architecture triple accessor.
bool IsMIPS() const
if MIPS architecture return true.
bool CharIsSignedByDefault() const
Returns true if 'char' is a signed type by default in the architecture false otherwise.
uint32_t GetFlags() const
llvm::Triple::ArchType GetMachine() const
Returns a machine family for the current architecture.
std::string GetClangTargetCPU() const
Returns a string representing current architecture as a target CPU for tools like compiler,...
void InstallASTContext(TypeSystemClang &ast_context)
clang::ExternalASTSource * CreateProxy()
void AddFixitHint(const clang::FixItHint &fixit)
llvm::Error Install(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx) override
Install the utility functions into a process.
"lldb/Expression/ClangExpressionDeclMap.h" Manages named entities that are defined in LLDB's debug in...
void InstallDiagnosticManager(DiagnosticManager &diag_manager)
void InstallCodeGenerator(clang::ASTConsumer *code_gen)
virtual void CommitPersistentDecls()
virtual clang::ASTConsumer * ASTTransformer(clang::ASTConsumer *passthrough)=0
Return the object that the parser should allow to access ASTs.
virtual ClangExpressionDeclMap * DeclMap()=0
Return the object that the parser should use when resolving external values.
std::string m_filename
File name used for the user expression.
bool RewriteExpression(DiagnosticManager &diagnostic_manager) override
Try to use the FixIts in the diagnostic_manager to rewrite the expression.
unsigned ParseInternal(DiagnosticManager &diagnostic_manager, clang::CodeCompleteConsumer *completion=nullptr, unsigned completion_line=0, unsigned completion_column=0)
Parses the expression.
ClangExpressionParser(ExecutionContextScope *exe_scope, Expression &expr, bool generate_debug_info, std::vector< std::string > include_directories={}, std::string filename="<clang expression>")
Constructor.
Status PrepareForExecution(lldb::addr_t &func_addr, lldb::addr_t &func_end, lldb::IRExecutionUnitSP &execution_unit_sp, ExecutionContext &exe_ctx, bool &can_interpret, lldb_private::ExecutionPolicy execution_policy) override
Ready an already-parsed expression for execution, possibly evaluating it statically.
std::unique_ptr< clang::CompilerInstance > m_compiler
The Clang compiler used to parse expressions into IR.
unsigned Parse(DiagnosticManager &diagnostic_manager)
Parse a single expression and convert it to IR using Clang.
bool Complete(CompletionRequest &request, unsigned line, unsigned pos, unsigned typed_pos) override
Attempts to find possible command line completions for the given expression.
~ClangExpressionParser() override
Destructor.
std::unique_ptr< llvm::LLVMContext > m_llvm_context
The LLVM context to generate IR into.
std::string GetClangTargetABI(const ArchSpec &target_arch)
Returns a string representing current ABI.
Status RunStaticInitializers(lldb::IRExecutionUnitSP &execution_unit_sp, ExecutionContext &exe_ctx)
Run all static initializers for an execution unit.
std::unique_ptr< clang::CodeGenerator > m_code_generator
The Clang object that generates IR.
LLDBPreprocessorCallbacks * m_pp_callbacks
Called when the preprocessor encounters module imports.
std::vector< std::string > m_include_directories
std::shared_ptr< TypeSystemClang > m_ast_context
static const llvm::StringRef g_prefix_file_name
The file name we use for the wrapper code that we inject before the user expression.
std::vector< ModuleID > ModuleVector
virtual bool AddModule(const SourceModule &module, ModuleVector *exported_modules, Stream &error_stream)=0
Add a module to the list of modules to search.
"lldb/Expression/ClangPersistentVariables.h" Manages persistent values that need to be preserved betw...
void AddHandLoadedClangModule(ClangModulesDeclVendor::ModuleID module)
"lldb/Expression/ClangUserExpression.h" Encapsulates a single expression for use with Clang
Generic representation of a type in a programming language.
"lldb/Utility/ArgCompletionRequest.h"
void AddCompletion(llvm::StringRef completion, llvm::StringRef description="", CompletionMode mode=CompletionMode::Normal)
Adds a possible completion string.
A single completion and all associated data.
std::string GetUniqueKey() const
Generates a string that uniquely identifies this completion result.
A uniqued constant string class.
const char * AsCString(const char *value_if_empty=nullptr) const
Get the string value as a C string.
void SetString(llvm::StringRef s)
void SetFixedExpression(std::string fixed_expression)
void AppendMessageToDiagnostic(llvm::StringRef str)
std::string GetString(char separator='\n')
const DiagnosticList & Diagnostics()
size_t void PutString(DiagnosticSeverity severity, llvm::StringRef str)
void AddDiagnostic(llvm::StringRef message, DiagnosticSeverity severity, DiagnosticOrigin origin, uint32_t compiler_id=LLDB_INVALID_COMPILER_ID)
"lldb/Target/ExecutionContextScope.h" Inherit from this if your object can reconstruct its execution ...
virtual lldb::StackFrameSP CalculateStackFrame()=0
virtual lldb::ProcessSP CalculateProcess()=0
virtual lldb::TargetSP CalculateTarget()=0
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
bool HasThreadScope() const
Returns true the ExecutionContext object contains a valid target, process, and thread.
const lldb::TargetSP & GetTargetSP() const
Get accessor to get the target shared pointer.
const lldb::ProcessSP & GetProcessSP() const
Get accessor to get the process shared pointer.
const lldb::StackFrameSP & GetFrameSP() const
Get accessor to get the frame shared pointer.
Process * GetProcessPtr() const
Returns a pointer to the process object.
Thread & GetThreadRef() const
Returns a reference to the thread object.
"lldb/Expression/ExpressionParser.h" Encapsulates an instance of a compiler that can parse expression...
Expression & m_expr
The expression to be parsed.
Encapsulates a single expression for use in lldb.
virtual bool NeedsValidation()=0
Flags.
virtual const char * Text()=0
Return the string that the parser should parse.
virtual lldb::LanguageType Language() const
Return the language that should be used when parsing.
virtual bool NeedsVariableResolution()=0
Return true if external variables in the expression should be resolved.
virtual ExpressionTypeSystemHelper * GetTypeSystemHelper()
virtual const char * FunctionName()=0
Return the function name that should be used for executing the expression.
virtual ResultType DesiredResultType()
Return the desired result type of the function, or eResultTypeAny if indifferent.
Wraps an ExternalASTSource into an ExternalSemaSource.
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
static FileSystem & Instance()
"lldb/Expression/IRDynamicChecks.h" Adds dynamic checks to a user-entered expression to reduce its li...
bool runOnModule(llvm::Module &M) override
Run this IR transformer on a single module.
static const char * GetNameForLanguageType(lldb::LanguageType language)
static ModuleListProperties & GetGlobalModuleListProperties()
Status Close() override
Flush any buffers and release any resources owned by the file.
Status Write(const void *buf, size_t &num_bytes) override
Write bytes from buf to a file at the current file position.
static ObjCLanguageRuntime * Get(Process &process)
A plug-in interface definition class for debugging a process.
void SetDynamicCheckers(DynamicCheckerFunctions *dynamic_checkers)
DynamicCheckerFunctions * GetDynamicCheckers()
bool CanInterpretFunctionCalls()
Determines whether executing function calls using the interpreter is possible for this process.
A ExternalSemaSource multiplexer that prioritizes its sources.
void SetErrorToGenericError()
Set the current error to a generic error.
int SetErrorStringWithFormat(const char *format,...) __attribute__((format(printf
Set the current error string to a formatted error string.
const char * AsCString(const char *default_error_str="unknown error") const
Get the error string associated with the current error.
void SetErrorString(llvm::StringRef err_str)
Set the current error string to err_str.
bool Success() const
Test for success condition.
llvm::StringRef GetString() const
Defines a symbol context baton that can be handed other debug core functions.
lldb::TargetSP target_sp
The Target for a given query.
lldb::ProcessSP GetProcess() const
const char * GetUserText()
Return the string that the user typed.
#define LLDB_INVALID_ADDRESS
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
FileSpec GetClangResourceDir()
@ eDiagnosticSeverityError
@ eDiagnosticSeverityWarning
@ eDiagnosticSeverityRemark
ExecutionPolicy
Expression execution policies.
@ eExecutionPolicyTopLevel
std::vector< std::unique_ptr< Diagnostic > > DiagnosticList
const char * toString(AppleArm64ExceptionClass EC)
bool operator<(const Address &lhs, const Address &rhs)
std::shared_ptr< lldb_private::ThreadPlan > ThreadPlanSP
std::shared_ptr< lldb_private::IRExecutionUnit > IRExecutionUnitSP
std::shared_ptr< lldb_private::StackFrame > StackFrameSP
LanguageType
Programming language type.
@ eLanguageTypeC_plus_plus_20
ISO C++:2020.
@ eLanguageTypeC_plus_plus_14
ISO C++:2014.
@ eLanguageTypeC11
ISO C:2011.
@ eLanguageTypeC99
ISO C:1999.
@ eLanguageTypeC_plus_plus_03
ISO C++:2003.
@ eLanguageTypeUnknown
Unknown or invalid language value.
@ eLanguageTypeC_plus_plus_17
ISO C++:2017.
@ eLanguageTypeObjC_plus_plus
Objective-C++.
@ eLanguageTypeC_plus_plus_11
ISO C++:2011.
@ eLanguageTypeC89
ISO C:1989.
@ eLanguageTypeC
Non-standardized C, such as K&R.
@ eLanguageTypeObjC
Objective-C.
@ eLanguageTypeC_plus_plus
ISO C++:1998.
ExpressionResults
The results of expression evaluation.
std::shared_ptr< lldb_private::Process > ProcessSP
std::shared_ptr< lldb_private::Target > TargetSP
std::shared_ptr< llvm::legacy::PassManager > EarlyPasses
std::shared_ptr< llvm::legacy::PassManager > LatePasses
Information needed to import a source-language module.
std::vector< ConstString > path
Something like "Module.Submodule".