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/Host.h"
50#include "llvm/Support/MemoryBuffer.h"
51#include "llvm/Support/Signals.h"
100using namespace clang;
118 clang::SourceManager &source_mgr)
122 void moduleImport(SourceLocation import_location, clang::ModuleIdPath path,
123 const clang::Module * )
override {
126 llvm::StringRef filename =
127 m_source_mgr.getPresumedLoc(import_location).getFilename();
133 for (
const std::pair<IdentifierInfo *, SourceLocation> &component : path)
152 for (
auto &fix_it : Info.getFixItHints()) {
162 DiagnosticOptions *options =
new DiagnosticOptions(opts);
163 options->ShowPresumedLoc =
true;
164 options->ShowLevel =
false;
165 m_os = std::make_shared<llvm::raw_string_ostream>(
m_output);
167 std::make_shared<clang::TextDiagnosticPrinter>(*
m_os, options);
186 const clang::Diagnostic &Info)
override {
195 llvm::SmallVector<char, 32> diag_str;
196 Info.FormatDiagnostic(diag_str);
197 diag_str.push_back(
'\0');
198 const char *plain_diag = diag_str.data();
199 LLDB_LOG(log,
"Received diagnostic outside parsing: {0}", plain_diag);
205 DiagnosticConsumer::HandleDiagnostic(DiagLevel, Info);
213 bool make_new_diagnostic =
true;
216 case DiagnosticsEngine::Level::Fatal:
217 case DiagnosticsEngine::Level::Error:
220 case DiagnosticsEngine::Level::Warning:
223 case DiagnosticsEngine::Level::Remark:
224 case DiagnosticsEngine::Level::Ignored:
227 case DiagnosticsEngine::Level::Note:
229 make_new_diagnostic =
false;
240 if (!clang_diag || clang_diag->HasFixIts())
248 if (make_new_diagnostic) {
251 std::string stripped_output =
252 std::string(llvm::StringRef(
m_output).trim());
254 auto new_diagnostic = std::make_unique<ClangDiagnostic>(
255 stripped_output, severity, Info.getID());
278 std::shared_ptr<llvm::raw_string_ostream>
m_os;
284 std::vector<std::string> include_directories,
285 lldb::TargetSP target_sp) {
288 HeaderSearchOptions &search_opts = compiler->getHeaderSearchOpts();
290 for (
const std::string &dir : include_directories) {
291 search_opts.AddPath(dir, frontend::System,
false,
true);
292 LLDB_LOG(log,
"Added user include dir: {0}", dir);
295 llvm::SmallString<128> module_cache;
297 props.GetClangModulesCachePath().GetPath(module_cache);
298 search_opts.ModuleCachePath = std::string(module_cache.str());
299 LLDB_LOG(log,
"Using module cache path: {0}", module_cache.c_str());
303 search_opts.ImplicitModuleMaps =
true;
311 if (token ==
"using")
314 if (token ==
"__null")
317 LangOptions cpp_lang_opts;
318 cpp_lang_opts.CPlusPlus =
true;
319 cpp_lang_opts.CPlusPlus11 =
true;
320 cpp_lang_opts.CPlusPlus20 =
true;
322 clang::IdentifierInfo &ii = idents.get(token);
325 if (!ii.isCPlusPlusKeyword(cpp_lang_opts))
328 if (ii.getTokenID() == clang::tok::identifier)
332 ii.revertTokenIDToIdentifier();
337#define KEYWORD(NAME, FLAGS) RemoveCppKeyword(idents, llvm::StringRef(#NAME));
338#include "clang/Basic/TokenKinds.def"
344 const std::vector<const char *> groupsToIgnore = {
347 "unused-getter-return-value",
349 for (
const char *group : groupsToIgnore) {
350 compiler.getDiagnostics().setSeverityForGroup(
351 clang::diag::Flavor::WarningOrError, group,
352 clang::diag::Severity::Ignored, SourceLocation());
362 bool generate_debug_info, std::vector<std::string> include_directories,
363 std::string filename)
365 m_pp_callbacks(nullptr),
366 m_include_directories(std::move(include_directories)),
367 m_filename(std::move(filename)) {
379 "Can't make an expression parser with a null scope.");
383 lldb::TargetSP target_sp;
387 "Can't make an expression parser with a null target.");
392 m_compiler = std::make_unique<CompilerInstance>();
399 bool overridden_target_opts =
false;
404 target_arch = target_sp->GetArchitecture();
406 const auto target_machine = target_arch.
GetMachine();
417 frame_lang = frame_sp->GetLanguage();
420 lang_rt = process_sp->GetLanguageRuntime(frame_lang);
421 LLDB_LOGF(log,
"Frame has language of type %s",
428 std::string triple = target_arch.
GetTriple().str();
430 LLDB_LOGF(log,
"Using %s as the target triple",
439 m_compiler->getTargetOpts().Triple = llvm::sys::getDefaultTargetTriple();
440 LLDB_LOGF(log,
"Using default target triple of %s",
445 if (
m_compiler->getTargetOpts().Triple.find(
"arm64") == std::string::npos &&
446 m_compiler->getTargetOpts().Triple.find(
"arm") != std::string::npos &&
447 m_compiler->getTargetOpts().Triple.find(
"ios") != std::string::npos) {
451 if (target_machine == llvm::Triple::x86 ||
452 target_machine == llvm::Triple::x86_64) {
453 m_compiler->getTargetOpts().Features.push_back(
"+sse");
454 m_compiler->getTargetOpts().Features.push_back(
"+sse2");
474 if (
auto *renderscript_rt =
475 llvm::dyn_cast_or_null<RenderScriptRuntime>(lang_rt))
476 overridden_target_opts =
477 renderscript_rt->GetOverrideExprOptions(
m_compiler->getTargetOpts());
479 if (overridden_target_opts)
482 log,
"Using overridden target options for the expression evaluation");
485 LLDB_LOGV(log,
"Triple: '{0}'", opts.Triple);
487 LLDB_LOGV(log,
"FPMath: '{0}'", opts.FPMath);
489 LLDB_LOGV(log,
"LinkerVersion: '{0}'", opts.LinkerVersion);
498 m_compiler->getDiagnostics().setErrorLimit(target_sp->GetExprErrorLimit());
500 auto target_info = TargetInfo::CreateTargetInfo(
503 LLDB_LOGF(log,
"Using SIMD alignment: %d",
504 target_info->getSimdDefaultAlign());
505 LLDB_LOGF(log,
"Target datalayout string: '%s'",
506 target_info->getDataLayoutString());
507 LLDB_LOGF(log,
"Target ABI: '%s'", target_info->getABI().str().c_str());
508 LLDB_LOGF(log,
"Target vector alignment: %d",
509 target_info->getMaxVectorAlign());
517 LangOptions &lang_opts =
m_compiler->getLangOpts();
529 lang_opts.CPlusPlus =
true;
532 lang_opts.ObjC =
true;
535 lang_opts.CPlusPlus =
true;
543 lang_opts.CPlusPlus11 =
true;
548 lang_opts.CPlusPlus11 =
true;
549 m_compiler->getHeaderSearchOpts().UseLibcxx =
true;
552 lang_opts.CPlusPlus =
true;
560 lang_opts.ObjC =
true;
561 lang_opts.CPlusPlus =
true;
562 lang_opts.CPlusPlus11 =
true;
563 m_compiler->getHeaderSearchOpts().UseLibcxx =
true;
567 lang_opts.Bool =
true;
568 lang_opts.WChar =
true;
569 lang_opts.Blocks =
true;
570 lang_opts.DebuggerSupport =
573 lang_opts.DebuggerCastResultToId =
true;
581 lang_opts.SpellChecking =
false;
583 auto *clang_expr = dyn_cast<ClangUserExpression>(&
m_expr);
584 if (clang_expr && clang_expr->DidImportCxxModules()) {
585 LLDB_LOG(log,
"Adding lang options for importing C++ modules");
587 lang_opts.Modules =
true;
589 lang_opts.ImplicitModules =
true;
591 lang_opts.ModulesLocalVisibility =
false;
595 lang_opts.ObjC =
true;
599 lang_opts.GNUMode =
true;
600 lang_opts.GNUKeywords =
true;
601 lang_opts.DoubleSquareBracketAttributes =
true;
602 lang_opts.CPlusPlus11 =
true;
605 lang_opts.GNUCVersion = 40201;
611 if (process_sp && lang_opts.ObjC) {
613 if (runtime->GetRuntimeVersion() ==
615 lang_opts.ObjCRuntime.set(ObjCRuntime::MacOSX, VersionTuple(10, 7));
617 lang_opts.ObjCRuntime.set(ObjCRuntime::FragileMacOSX,
618 VersionTuple(10, 7));
620 if (runtime->HasNewLiteralsAndIndexing())
621 lang_opts.DebuggerObjCLiteral =
true;
625 lang_opts.ThreadsafeStatics =
false;
626 lang_opts.AccessControl =
false;
627 lang_opts.DollarIdents =
true;
631 lang_opts.NoBuiltin =
true;
634 m_compiler->getCodeGenOpts().EmitDeclMetadata =
true;
635 m_compiler->getCodeGenOpts().InstrumentFunctions =
false;
637 CodeGenOptions::FramePointerKind::All);
638 if (generate_debug_info)
639 m_compiler->getCodeGenOpts().setDebugInfo(codegenoptions::FullDebugInfo);
641 m_compiler->getCodeGenOpts().setDebugInfo(codegenoptions::NoDebugInfo);
656 m_compiler->getDiagnostics().getDiagnosticOptions());
657 m_compiler->getDiagnostics().setClient(diag_mgr);
680 if (
auto *clang_persistent_vars = llvm::cast<ClangPersistentVariables>(
681 target_sp->GetPersistentExpressionStateForLanguage(
683 if (std::shared_ptr<ClangModulesDeclVendor> decl_vendor =
684 clang_persistent_vars->GetClangModulesDeclVendor()) {
685 std::unique_ptr<PPCallbacks> pp_callbacks(
690 m_compiler->getPreprocessor().addPPCallbacks(std::move(pp_callbacks));
698 auto &builtin_context = PP.getBuiltinInfo();
699 builtin_context.initializeBuiltins(PP.getIdentifierTable(),
703 clang::ASTContext &ast_context =
m_compiler->getASTContext();
706 "Expression ASTContext for '" +
m_filename +
"'", ast_context);
708 std::string module_name(
"$__lldb_module");
727class CodeComplete :
public CodeCompleteConsumer {
728 CodeCompletionTUInfo m_info;
731 unsigned m_position = 0;
734 clang::PrintingPolicy m_desc_policy;
736 struct CompletionWithPriority {
744 bool operator<(
const CompletionWithPriority &o)
const {
746 if (Priority != o.Priority)
747 return Priority > o.Priority;
750 return completion.
GetUniqueKey() < o.completion.GetUniqueKey();
757 std::vector<CompletionWithPriority> m_completions;
764 static bool IsIdChar(
char c) {
765 return c ==
'_' || std::isalnum(c) || c ==
'$';
770 static bool IsTokenSeparator(
char c) {
return c ==
' ' || c ==
'\t'; }
775 StringRef dropUnrelatedFrontTokens(StringRef cmd)
const {
781 if (IsTokenSeparator(cmd.back()))
786 StringRef to_remove = cmd;
787 while (!to_remove.empty() && !IsTokenSeparator(to_remove.back())) {
788 to_remove = to_remove.drop_back();
790 cmd = cmd.drop_front(to_remove.size());
796 StringRef removeLastToken(StringRef cmd)
const {
797 while (!cmd.empty() && IsIdChar(cmd.back())) {
798 cmd = cmd.drop_back();
806 std::string mergeCompletion(StringRef existing,
unsigned pos,
807 StringRef completion)
const {
808 StringRef existing_command = existing.substr(0, pos);
811 existing_command = removeLastToken(existing_command);
815 existing_command = dropUnrelatedFrontTokens(existing_command);
816 return existing_command.str() + completion.str();
829 CodeComplete(clang::LangOptions ops, std::string expr,
unsigned position)
830 : CodeCompleteConsumer(CodeCompleteOptions()),
831 m_info(std::make_shared<GlobalCodeCompletionAllocator>()), m_expr(expr),
832 m_position(position), m_desc_policy(ops) {
836 m_desc_policy.SuppressScope =
true;
837 m_desc_policy.SuppressTagKeyword =
true;
838 m_desc_policy.FullyQualifiedName =
false;
839 m_desc_policy.TerseOutput =
true;
840 m_desc_policy.IncludeNewlines =
false;
841 m_desc_policy.UseVoidForZeroParams =
false;
842 m_desc_policy.Bool =
true;
847 bool isResultFilteredOut(StringRef Filter,
848 CodeCompletionResult Result)
override {
850 switch (Result.Kind) {
851 case CodeCompletionResult::RK_Declaration:
853 Result.Declaration->getIdentifier() &&
854 Result.Declaration->getIdentifier()->getName().startswith(Filter));
855 case CodeCompletionResult::RK_Keyword:
856 return !StringRef(Result.Keyword).startswith(Filter);
857 case CodeCompletionResult::RK_Macro:
858 return !Result.Macro->getName().startswith(Filter);
859 case CodeCompletionResult::RK_Pattern:
860 return !StringRef(Result.Pattern->getAsString()).startswith(Filter);
865 assert(
false &&
"Unknown completion result type?");
880 std::optional<CompletionWithPriority>
881 getCompletionForResult(
const CodeCompletionResult &R)
const {
882 std::string ToInsert;
883 std::string Description;
886 case CodeCompletionResult::RK_Declaration: {
887 const NamedDecl *D = R.Declaration;
888 ToInsert = R.Declaration->getNameAsString();
892 if (
const FunctionDecl *F = dyn_cast<FunctionDecl>(D)) {
893 if (F->getNumParams() == 0)
897 raw_string_ostream
OS(Description);
898 F->print(
OS, m_desc_policy,
false);
900 }
else if (
const VarDecl *V = dyn_cast<VarDecl>(D)) {
901 Description = V->getType().getAsString(m_desc_policy);
902 }
else if (
const FieldDecl *F = dyn_cast<FieldDecl>(D)) {
903 Description = F->getType().getAsString(m_desc_policy);
904 }
else if (
const NamespaceDecl *N = dyn_cast<NamespaceDecl>(D)) {
907 if (!N->isAnonymousNamespace())
912 case CodeCompletionResult::RK_Keyword:
913 ToInsert = R.Keyword;
915 case CodeCompletionResult::RK_Macro:
916 ToInsert = R.Macro->getName().str();
918 case CodeCompletionResult::RK_Pattern:
919 ToInsert = R.Pattern->getTypedText();
924 if (llvm::StringRef(ToInsert).startswith(
"$__lldb_"))
926 if (ToInsert.empty())
930 std::string CompletionSuggestion =
931 mergeCompletion(m_expr, m_position, ToInsert);
934 CompletionMode::Normal);
935 return {{completion, R.Priority}};
943 llvm::sort(m_completions);
945 for (
const CompletionWithPriority &C : m_completions)
947 C.completion.GetDescription(),
948 C.completion.GetMode());
953 void ProcessCodeCompleteResults(Sema &SemaRef, CodeCompletionContext Context,
954 CodeCompletionResult *Results,
955 unsigned NumResults)
override {
959 StringRef Filter = SemaRef.getPreprocessor().getCodeCompletionFilter();
963 for (
unsigned I = 0; I != NumResults; ++I) {
965 if (!Filter.empty() && isResultFilteredOut(Filter, Results[I]))
968 CodeCompletionResult &R = Results[I];
969 std::optional<CompletionWithPriority> CompletionAndPriority =
970 getCompletionForResult(R);
971 if (!CompletionAndPriority)
973 m_completions.push_back(*CompletionAndPriority);
985 void ProcessOverloadCandidates(Sema &S,
unsigned CurrentArg,
986 OverloadCandidate *Candidates,
987 unsigned NumCandidates,
988 SourceLocation OpenParLoc,
989 bool Braced)
override {
993 CodeCompletionAllocator &getAllocator()
override {
994 return m_info.getAllocator();
997 CodeCompletionTUInfo &getCodeCompletionTUInfo()
override {
return m_info; }
1002 unsigned pos,
unsigned typed_pos) {
1017 CC.GetCompletions(request);
1027 CodeCompleteConsumer *completion_consumer,
1028 unsigned completion_line,
1029 unsigned completion_column) {
1038 clang::SourceManager &source_mgr =
m_compiler->getSourceManager();
1039 bool created_main_file =
false;
1045 bool should_create_file = completion_consumer !=
nullptr;
1048 should_create_file |=
m_compiler->getCodeGenOpts().getDebugInfo() ==
1049 codegenoptions::FullDebugInfo;
1051 if (should_create_file) {
1053 llvm::SmallString<128> result_path;
1054 if (
FileSpec tmpdir_file_spec = HostInfo::GetProcessTempDir()) {
1055 tmpdir_file_spec.AppendPathComponent(
"lldb-%%%%%%.expr");
1056 std::string temp_source_path = tmpdir_file_spec.GetPath();
1057 llvm::sys::fs::createUniqueFile(temp_source_path, temp_fd, result_path);
1059 llvm::sys::fs::createTemporaryFile(
"lldb",
"expr", temp_fd, result_path);
1062 if (temp_fd != -1) {
1064 const size_t expr_text_len = strlen(expr_text);
1065 size_t bytes_written = expr_text_len;
1067 if (bytes_written == expr_text_len) {
1069 if (
auto fileEntry =
m_compiler->getFileManager().getOptionalFileRef(
1071 source_mgr.setMainFileID(source_mgr.createFileID(
1073 SourceLocation(), SrcMgr::C_User));
1074 created_main_file =
true;
1081 if (!created_main_file) {
1082 std::unique_ptr<MemoryBuffer> memory_buffer =
1083 MemoryBuffer::getMemBufferCopy(expr_text,
m_filename);
1084 source_mgr.setMainFileID(source_mgr.createFileID(std::move(memory_buffer)));
1097 if (completion_consumer) {
1098 auto main_file = source_mgr.getFileEntryForID(source_mgr.getMainFileID());
1103 ++completion_column;
1104 PP.SetCodeCompletionPoint(main_file, completion_line, completion_column);
1107 ASTConsumer *ast_transformer =
1110 std::unique_ptr<clang::ASTConsumer> Consumer;
1111 if (ast_transformer) {
1112 Consumer = std::make_unique<ASTConsumerForwarder>(ast_transformer);
1116 Consumer = std::make_unique<ASTConsumer>();
1119 clang::ASTContext &ast_context =
m_compiler->getASTContext();
1122 *Consumer, TU_Complete, completion_consumer));
1123 m_compiler->setASTConsumer(std::move(Consumer));
1125 if (ast_context.getLangOpts().Modules) {
1135 clang::ExternalASTSource *ast_source = decl_map->
CreateProxy();
1137 if (ast_context.getExternalSource()) {
1138 auto module_wrapper =
1145 IntrusiveRefCntPtr<ExternalASTSource> Source(multiplexer);
1146 ast_context.setExternalSource(Source);
1148 ast_context.setExternalSource(ast_source);
1154 if (ast_context.getLangOpts().Modules) {
1155 assert(
m_compiler->getASTContext().getExternalSource() &&
1156 "ASTContext doesn't know about the ASTReader?");
1157 assert(
m_compiler->getSema().getExternalSource() &&
1158 "Sema doesn't know about the ASTReader?");
1162 llvm::CrashRecoveryContextCleanupRegistrar<Sema> CleanupSema(
1164 ParseAST(
m_compiler->getSema(),
false,
false);
1168 if (ast_context.getLangOpts().Modules)
1176 unsigned num_errors = adapter->getNumErrors();
1181 "while importing modules:");
1199 if (target_arch.
IsMIPS()) {
1218static void ApplyFixIt(
const FixItHint &fixit, clang::edit::Commit &commit) {
1220 if (fixit.CodeToInsert.empty()) {
1221 if (fixit.InsertFromRange.isValid()) {
1222 commit.insertFromRange(fixit.RemoveRange.getBegin(),
1223 fixit.InsertFromRange,
false,
1224 fixit.BeforePreviousInsertions);
1227 commit.remove(fixit.RemoveRange);
1230 if (fixit.RemoveRange.isTokenRange() ||
1231 fixit.RemoveRange.getBegin() != fixit.RemoveRange.getEnd()) {
1232 commit.replace(fixit.RemoveRange, fixit.CodeToInsert);
1235 commit.insert(fixit.RemoveRange.getBegin(), fixit.CodeToInsert,
1236 false, fixit.BeforePreviousInsertions);
1241 clang::SourceManager &source_manager =
m_compiler->getSourceManager();
1242 clang::edit::EditedSource editor(source_manager,
m_compiler->getLangOpts(),
1244 clang::edit::Commit commit(editor);
1245 clang::Rewriter rewriter(source_manager,
m_compiler->getLangOpts());
1247 class RewritesReceiver :
public edit::EditsReceiver {
1251 RewritesReceiver(Rewriter &in_rewrite) : rewrite(in_rewrite) {}
1253 void insert(SourceLocation loc, StringRef text)
override {
1254 rewrite.InsertText(loc, text);
1256 void replace(CharSourceRange range, StringRef text)
override {
1257 rewrite.ReplaceText(range.getBegin(), rewrite.getRangeSize(range), text);
1261 RewritesReceiver rewrites_receiver(rewriter);
1264 size_t num_diags = diagnostics.size();
1268 for (
const auto &diag : diagnostic_manager.
Diagnostics()) {
1269 const auto *diagnostic = llvm::dyn_cast<ClangDiagnostic>(diag.get());
1272 if (!diagnostic->HasFixIts())
1274 for (
const FixItHint &fixit : diagnostic->FixIts())
1279 if (!commit.isCommitable())
1281 else if (!editor.commit(commit))
1285 editor.applyRewrites(rewrites_receiver);
1286 RewriteBuffer &main_file_buffer =
1287 rewriter.getEditBuffer(source_manager.getMainFileID());
1289 std::string fixed_expression;
1290 llvm::raw_string_ostream out_stream(fixed_expression);
1292 main_file_buffer.write(out_stream);
1300 llvm::Module *module,
const char *orig_name) {
1301 for (
const auto &func : module->getFunctionList()) {
1302 const StringRef &name = func.getName();
1303 if (name.contains(orig_name)) {
1322 std::unique_ptr<llvm::Module> llvm_module_up(
1325 if (!llvm_module_up) {
1350 if (lldb::StackFrameSP frame_sp = exe_ctx.
GetFrameSP()) {
1351 sc = frame_sp->GetSymbolContext(lldb::eSymbolContextEverything);
1352 }
else if (lldb::TargetSP target_sp = exe_ctx.
GetTargetSP()) {
1359 LLDB_LOGF(log,
"%s - Current expression language is %s\n", __FUNCTION__,
1363 auto runtime = process_sp->GetLanguageRuntime(lang);
1365 runtime->GetIRPasses(custom_passes);
1371 "%s - Running Early IR Passes from LanguageRuntime on "
1372 "expression module '%s'",
1378 execution_unit_sp = std::make_shared<IRExecutionUnit>(
1387 type_system_helper->
DeclMap();
1392 *execution_unit_sp, error_stream,
1395 if (!ir_for_target.
runOnModule(*execution_unit_sp->GetModule())) {
1406 bool interpret_function_calls =
1409 *execution_unit_sp->GetModule(), *execution_unit_sp->GetFunction(),
1410 interpret_error, interpret_function_calls);
1414 "Can't evaluate the expression without a running target due to: %s",
1421 err.
SetErrorString(
"Expression needed to run in the target, but the "
1422 "target can't be run");
1427 err.
SetErrorString(
"Top-level code needs to be inserted into a runnable "
1428 "target, but the target can't be run");
1441 if (!dynamic_checkers->
Install(install_diagnostics, exe_ctx)) {
1452 LLDB_LOGF(log,
"== [ClangExpressionParser::PrepareForExecution] "
1453 "Finished installing dynamic checkers ==");
1456 if (
auto *checker_funcs = llvm::dyn_cast<ClangDynamicCheckerFunctions>(
1461 llvm::Module *module = execution_unit_sp->GetModule();
1462 if (!module || !ir_dynamic_checks.
runOnModule(*module)) {
1464 err.
SetErrorString(
"Couldn't add dynamic checks to the expression");
1470 "%s - Running Late IR Passes from LanguageRuntime on "
1471 "expression module '%s'",
1482 execution_unit_sp->GetRunnableInfo(err, func_addr, func_end);
1485 execution_unit_sp->GetRunnableInfo(err, func_addr, func_end);
1498 if (!execution_unit_sp.get()) {
1500 "can't run static initializers for a NULL execution unit");
1505 err.
SetErrorString(
"can't run static initializers without a thread");
1509 std::vector<lldb::addr_t> static_initializers;
1511 execution_unit_sp->GetStaticInitializers(static_initializers);
1513 for (
lldb::addr_t static_initializer : static_initializers) {
1518 llvm::ArrayRef<lldb::addr_t>(), options));
1523 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,...)
#define LLDB_LOGV(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)
bool 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(const 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
virtual void LogDump(Log *log, const char *name=nullptr)
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
bool operator<(const Address &lhs, const Address &rhs)
LanguageType
Programming language type.
@ 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.
@ 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< 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".