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().Features.push_back(
"+sse");
449 m_compiler->getTargetOpts().Features.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;
536 lang_opts.ObjC =
true;
537 lang_opts.CPlusPlus =
true;
538 lang_opts.CPlusPlus11 =
true;
539 m_compiler->getHeaderSearchOpts().UseLibcxx =
true;
543 lang_opts.Bool =
true;
544 lang_opts.WChar =
true;
545 lang_opts.Blocks =
true;
546 lang_opts.DebuggerSupport =
549 lang_opts.DebuggerCastResultToId =
true;
557 lang_opts.SpellChecking =
false;
559 auto *clang_expr = dyn_cast<ClangUserExpression>(&
m_expr);
560 if (clang_expr && clang_expr->DidImportCxxModules()) {
561 LLDB_LOG(log,
"Adding lang options for importing C++ modules");
563 lang_opts.Modules =
true;
565 lang_opts.ImplicitModules =
true;
567 lang_opts.ModulesLocalVisibility =
false;
571 lang_opts.ObjC =
true;
575 lang_opts.GNUMode =
true;
576 lang_opts.GNUKeywords =
true;
577 lang_opts.CPlusPlus11 =
true;
578 lang_opts.BuiltinHeadersInSystemModules =
true;
581 lang_opts.GNUCVersion = 40201;
587 if (process_sp && lang_opts.ObjC) {
589 switch (runtime->GetRuntimeVersion()) {
591 lang_opts.ObjCRuntime.set(ObjCRuntime::MacOSX, VersionTuple(10, 7));
595 lang_opts.ObjCRuntime.set(ObjCRuntime::FragileMacOSX,
596 VersionTuple(10, 7));
599 lang_opts.ObjCRuntime.set(ObjCRuntime::GNUstep, VersionTuple(2, 0));
603 if (runtime->HasNewLiteralsAndIndexing())
604 lang_opts.DebuggerObjCLiteral =
true;
608 lang_opts.ThreadsafeStatics =
false;
609 lang_opts.AccessControl =
false;
610 lang_opts.DollarIdents =
true;
614 lang_opts.NoBuiltin =
true;
617 m_compiler->getCodeGenOpts().EmitDeclMetadata =
true;
618 m_compiler->getCodeGenOpts().InstrumentFunctions =
false;
620 CodeGenOptions::FramePointerKind::All);
621 if (generate_debug_info)
622 m_compiler->getCodeGenOpts().setDebugInfo(codegenoptions::FullDebugInfo);
624 m_compiler->getCodeGenOpts().setDebugInfo(codegenoptions::NoDebugInfo);
639 m_compiler->getDiagnostics().getDiagnosticOptions());
640 m_compiler->getDiagnostics().setClient(diag_mgr);
663 if (
auto *clang_persistent_vars = llvm::cast<ClangPersistentVariables>(
664 target_sp->GetPersistentExpressionStateForLanguage(
666 if (std::shared_ptr<ClangModulesDeclVendor> decl_vendor =
667 clang_persistent_vars->GetClangModulesDeclVendor()) {
668 std::unique_ptr<PPCallbacks> pp_callbacks(
673 m_compiler->getPreprocessor().addPPCallbacks(std::move(pp_callbacks));
681 auto &builtin_context = PP.getBuiltinInfo();
682 builtin_context.initializeBuiltins(PP.getIdentifierTable(),
686 clang::ASTContext &ast_context =
m_compiler->getASTContext();
689 "Expression ASTContext for '" +
m_filename +
"'", ast_context);
691 std::string module_name(
"$__lldb_module");
710class CodeComplete :
public CodeCompleteConsumer {
711 CodeCompletionTUInfo m_info;
714 unsigned m_position = 0;
717 clang::PrintingPolicy m_desc_policy;
719 struct CompletionWithPriority {
727 bool operator<(
const CompletionWithPriority &o)
const {
729 if (Priority != o.Priority)
730 return Priority > o.Priority;
733 return completion.
GetUniqueKey() < o.completion.GetUniqueKey();
740 std::vector<CompletionWithPriority> m_completions;
747 static bool IsIdChar(
char c) {
748 return c ==
'_' || std::isalnum(c) || c ==
'$';
753 static bool IsTokenSeparator(
char c) {
return c ==
' ' || c ==
'\t'; }
758 StringRef dropUnrelatedFrontTokens(StringRef cmd)
const {
764 if (IsTokenSeparator(cmd.back()))
769 StringRef to_remove = cmd;
770 while (!to_remove.empty() && !IsTokenSeparator(to_remove.back())) {
771 to_remove = to_remove.drop_back();
773 cmd = cmd.drop_front(to_remove.size());
779 StringRef removeLastToken(StringRef cmd)
const {
780 while (!cmd.empty() && IsIdChar(cmd.back())) {
781 cmd = cmd.drop_back();
789 std::string mergeCompletion(StringRef existing,
unsigned pos,
790 StringRef completion)
const {
791 StringRef existing_command = existing.substr(0, pos);
794 existing_command = removeLastToken(existing_command);
798 existing_command = dropUnrelatedFrontTokens(existing_command);
799 return existing_command.str() + completion.str();
812 CodeComplete(clang::LangOptions ops, std::string expr,
unsigned position)
813 : CodeCompleteConsumer(CodeCompleteOptions()),
814 m_info(std::make_shared<GlobalCodeCompletionAllocator>()), m_expr(expr),
815 m_position(position), m_desc_policy(ops) {
819 m_desc_policy.SuppressScope =
true;
820 m_desc_policy.SuppressTagKeyword =
true;
821 m_desc_policy.FullyQualifiedName =
false;
822 m_desc_policy.TerseOutput =
true;
823 m_desc_policy.IncludeNewlines =
false;
824 m_desc_policy.UseVoidForZeroParams =
false;
825 m_desc_policy.Bool =
true;
830 bool isResultFilteredOut(StringRef Filter,
831 CodeCompletionResult Result)
override {
833 switch (Result.Kind) {
834 case CodeCompletionResult::RK_Declaration:
836 Result.Declaration->getIdentifier() &&
837 Result.Declaration->getIdentifier()->getName().startswith(Filter));
838 case CodeCompletionResult::RK_Keyword:
839 return !StringRef(Result.Keyword).startswith(Filter);
840 case CodeCompletionResult::RK_Macro:
841 return !Result.Macro->getName().startswith(Filter);
842 case CodeCompletionResult::RK_Pattern:
843 return !StringRef(Result.Pattern->getAsString()).startswith(Filter);
848 assert(
false &&
"Unknown completion result type?");
863 std::optional<CompletionWithPriority>
864 getCompletionForResult(
const CodeCompletionResult &R)
const {
865 std::string ToInsert;
866 std::string Description;
869 case CodeCompletionResult::RK_Declaration: {
870 const NamedDecl *D = R.Declaration;
871 ToInsert = R.Declaration->getNameAsString();
875 if (
const FunctionDecl *F = dyn_cast<FunctionDecl>(D)) {
876 if (F->getNumParams() == 0)
880 raw_string_ostream
OS(Description);
881 F->print(
OS, m_desc_policy,
false);
883 }
else if (
const VarDecl *V = dyn_cast<VarDecl>(D)) {
884 Description = V->getType().getAsString(m_desc_policy);
885 }
else if (
const FieldDecl *F = dyn_cast<FieldDecl>(D)) {
886 Description = F->getType().getAsString(m_desc_policy);
887 }
else if (
const NamespaceDecl *N = dyn_cast<NamespaceDecl>(D)) {
890 if (!N->isAnonymousNamespace())
895 case CodeCompletionResult::RK_Keyword:
896 ToInsert = R.Keyword;
898 case CodeCompletionResult::RK_Macro:
899 ToInsert = R.Macro->getName().str();
901 case CodeCompletionResult::RK_Pattern:
902 ToInsert = R.Pattern->getTypedText();
907 if (llvm::StringRef(ToInsert).startswith(
"$__lldb_"))
909 if (ToInsert.empty())
913 std::string CompletionSuggestion =
914 mergeCompletion(m_expr, m_position, ToInsert);
917 CompletionMode::Normal);
918 return {{completion, R.Priority}};
926 llvm::sort(m_completions);
928 for (
const CompletionWithPriority &C : m_completions)
930 C.completion.GetDescription(),
931 C.completion.GetMode());
936 void ProcessCodeCompleteResults(Sema &SemaRef, CodeCompletionContext Context,
937 CodeCompletionResult *Results,
938 unsigned NumResults)
override {
942 StringRef Filter = SemaRef.getPreprocessor().getCodeCompletionFilter();
946 for (
unsigned I = 0; I != NumResults; ++I) {
948 if (!Filter.empty() && isResultFilteredOut(Filter, Results[I]))
951 CodeCompletionResult &R = Results[I];
952 std::optional<CompletionWithPriority> CompletionAndPriority =
953 getCompletionForResult(R);
954 if (!CompletionAndPriority)
956 m_completions.push_back(*CompletionAndPriority);
968 void ProcessOverloadCandidates(Sema &S,
unsigned CurrentArg,
969 OverloadCandidate *Candidates,
970 unsigned NumCandidates,
971 SourceLocation OpenParLoc,
972 bool Braced)
override {
976 CodeCompletionAllocator &getAllocator()
override {
977 return m_info.getAllocator();
980 CodeCompletionTUInfo &getCodeCompletionTUInfo()
override {
return m_info; }
985 unsigned pos,
unsigned typed_pos) {
1000 CC.GetCompletions(request);
1010 CodeCompleteConsumer *completion_consumer,
1011 unsigned completion_line,
1012 unsigned completion_column) {
1021 clang::SourceManager &source_mgr =
m_compiler->getSourceManager();
1022 bool created_main_file =
false;
1028 bool should_create_file = completion_consumer !=
nullptr;
1031 should_create_file |=
m_compiler->getCodeGenOpts().getDebugInfo() ==
1032 codegenoptions::FullDebugInfo;
1034 if (should_create_file) {
1036 llvm::SmallString<128> result_path;
1037 if (
FileSpec tmpdir_file_spec = HostInfo::GetProcessTempDir()) {
1038 tmpdir_file_spec.AppendPathComponent(
"lldb-%%%%%%.expr");
1039 std::string temp_source_path = tmpdir_file_spec.GetPath();
1040 llvm::sys::fs::createUniqueFile(temp_source_path, temp_fd, result_path);
1042 llvm::sys::fs::createTemporaryFile(
"lldb",
"expr", temp_fd, result_path);
1045 if (temp_fd != -1) {
1047 const size_t expr_text_len = strlen(expr_text);
1048 size_t bytes_written = expr_text_len;
1050 if (bytes_written == expr_text_len) {
1052 if (
auto fileEntry =
m_compiler->getFileManager().getOptionalFileRef(
1054 source_mgr.setMainFileID(source_mgr.createFileID(
1056 SourceLocation(), SrcMgr::C_User));
1057 created_main_file =
true;
1064 if (!created_main_file) {
1065 std::unique_ptr<MemoryBuffer> memory_buffer =
1066 MemoryBuffer::getMemBufferCopy(expr_text,
m_filename);
1067 source_mgr.setMainFileID(source_mgr.createFileID(std::move(memory_buffer)));
1080 if (completion_consumer) {
1082 source_mgr.getFileEntryRefForID(source_mgr.getMainFileID());
1087 ++completion_column;
1088 PP.SetCodeCompletionPoint(*main_file, completion_line, completion_column);
1091 ASTConsumer *ast_transformer =
1094 std::unique_ptr<clang::ASTConsumer> Consumer;
1095 if (ast_transformer) {
1096 Consumer = std::make_unique<ASTConsumerForwarder>(ast_transformer);
1100 Consumer = std::make_unique<ASTConsumer>();
1103 clang::ASTContext &ast_context =
m_compiler->getASTContext();
1106 *Consumer, TU_Complete, completion_consumer));
1107 m_compiler->setASTConsumer(std::move(Consumer));
1109 if (ast_context.getLangOpts().Modules) {
1119 clang::ExternalASTSource *ast_source = decl_map->
CreateProxy();
1121 if (ast_context.getExternalSource()) {
1122 auto module_wrapper =
1129 IntrusiveRefCntPtr<ExternalASTSource>
Source(multiplexer);
1130 ast_context.setExternalSource(
Source);
1132 ast_context.setExternalSource(ast_source);
1138 if (ast_context.getLangOpts().Modules) {
1139 assert(
m_compiler->getASTContext().getExternalSource() &&
1140 "ASTContext doesn't know about the ASTReader?");
1141 assert(
m_compiler->getSema().getExternalSource() &&
1142 "Sema doesn't know about the ASTReader?");
1146 llvm::CrashRecoveryContextCleanupRegistrar<Sema> CleanupSema(
1148 ParseAST(
m_compiler->getSema(),
false,
false);
1152 if (ast_context.getLangOpts().Modules)
1160 unsigned num_errors = adapter->getNumErrors();
1165 "while importing modules:");
1183 if (target_arch.
IsMIPS()) {
1202static void ApplyFixIt(
const FixItHint &fixit, clang::edit::Commit &commit) {
1204 if (fixit.CodeToInsert.empty()) {
1205 if (fixit.InsertFromRange.isValid()) {
1206 commit.insertFromRange(fixit.RemoveRange.getBegin(),
1207 fixit.InsertFromRange,
false,
1208 fixit.BeforePreviousInsertions);
1211 commit.remove(fixit.RemoveRange);
1214 if (fixit.RemoveRange.isTokenRange() ||
1215 fixit.RemoveRange.getBegin() != fixit.RemoveRange.getEnd()) {
1216 commit.replace(fixit.RemoveRange, fixit.CodeToInsert);
1219 commit.insert(fixit.RemoveRange.getBegin(), fixit.CodeToInsert,
1220 false, fixit.BeforePreviousInsertions);
1225 clang::SourceManager &source_manager =
m_compiler->getSourceManager();
1226 clang::edit::EditedSource editor(source_manager,
m_compiler->getLangOpts(),
1228 clang::edit::Commit commit(editor);
1229 clang::Rewriter rewriter(source_manager,
m_compiler->getLangOpts());
1231 class RewritesReceiver :
public edit::EditsReceiver {
1235 RewritesReceiver(Rewriter &in_rewrite) : rewrite(in_rewrite) {}
1237 void insert(SourceLocation loc, StringRef text)
override {
1238 rewrite.InsertText(loc, text);
1240 void replace(CharSourceRange range, StringRef text)
override {
1241 rewrite.ReplaceText(range.getBegin(), rewrite.getRangeSize(range), text);
1245 RewritesReceiver rewrites_receiver(rewriter);
1248 size_t num_diags = diagnostics.size();
1252 for (
const auto &diag : diagnostic_manager.
Diagnostics()) {
1253 const auto *diagnostic = llvm::dyn_cast<ClangDiagnostic>(diag.get());
1256 if (!diagnostic->HasFixIts())
1258 for (
const FixItHint &fixit : diagnostic->FixIts())
1263 if (!commit.isCommitable())
1265 else if (!editor.commit(commit))
1269 editor.applyRewrites(rewrites_receiver);
1270 RewriteBuffer &main_file_buffer =
1271 rewriter.getEditBuffer(source_manager.getMainFileID());
1273 std::string fixed_expression;
1274 llvm::raw_string_ostream out_stream(fixed_expression);
1276 main_file_buffer.write(out_stream);
1284 llvm::Module *module,
const char *orig_name) {
1285 for (
const auto &func : module->getFunctionList()) {
1286 const StringRef &name = func.getName();
1287 if (name.contains(orig_name)) {
1306 std::unique_ptr<llvm::Module> llvm_module_up(
1309 if (!llvm_module_up) {
1335 sc = frame_sp->GetSymbolContext(lldb::eSymbolContextEverything);
1343 LLDB_LOGF(log,
"%s - Current expression language is %s\n", __FUNCTION__,
1347 auto runtime = process_sp->GetLanguageRuntime(lang);
1349 runtime->GetIRPasses(custom_passes);
1355 "%s - Running Early IR Passes from LanguageRuntime on "
1356 "expression module '%s'",
1362 execution_unit_sp = std::make_shared<IRExecutionUnit>(
1371 type_system_helper->
DeclMap();
1376 *execution_unit_sp, error_stream,
1379 if (!ir_for_target.
runOnModule(*execution_unit_sp->GetModule())) {
1390 bool interpret_function_calls =
1393 *execution_unit_sp->GetModule(), *execution_unit_sp->GetFunction(),
1394 interpret_error, interpret_function_calls);
1398 "Can't evaluate the expression without a running target due to: %s",
1405 err.
SetErrorString(
"Expression needed to run in the target, but the "
1406 "target can't be run");
1411 err.
SetErrorString(
"Top-level code needs to be inserted into a runnable "
1412 "target, but the target can't be run");
1424 if (
Error Err = dynamic_checkers->
Install(install_diags, exe_ctx)) {
1425 std::string ErrMsg =
"couldn't install checkers: " +
toString(std::move(Err));
1427 ErrMsg = ErrMsg +
"\n" + install_diags.
GetString().c_str();
1434 LLDB_LOGF(log,
"== [ClangExpressionParser::PrepareForExecution] "
1435 "Finished installing dynamic checkers ==");
1438 if (
auto *checker_funcs = llvm::dyn_cast<ClangDynamicCheckerFunctions>(
1443 llvm::Module *module = execution_unit_sp->GetModule();
1444 if (!module || !ir_dynamic_checks.
runOnModule(*module)) {
1446 err.
SetErrorString(
"Couldn't add dynamic checks to the expression");
1452 "%s - Running Late IR Passes from LanguageRuntime on "
1453 "expression module '%s'",
1464 execution_unit_sp->GetRunnableInfo(err, func_addr, func_end);
1467 execution_unit_sp->GetRunnableInfo(err, func_addr, func_end);
1480 if (!execution_unit_sp.get()) {
1482 "can't run static initializers for a NULL execution unit");
1487 err.
SetErrorString(
"can't run static initializers without a thread");
1491 std::vector<lldb::addr_t> static_initializers;
1493 execution_unit_sp->GetStaticInitializers(static_initializers);
1495 for (
lldb::addr_t static_initializer : static_initializers) {
1500 llvm::ArrayRef<lldb::addr_t>(), options));
1505 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".