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/DarwinSDKInfo.h"
15#include "clang/Basic/DiagnosticIDs.h"
16#include "clang/Basic/SourceLocation.h"
17#include "clang/Basic/TargetInfo.h"
18#include "clang/Basic/Version.h"
19#include "clang/CodeGen/CodeGenAction.h"
20#include "clang/CodeGen/ModuleBuilder.h"
21#include "clang/Edit/Commit.h"
22#include "clang/Edit/EditedSource.h"
23#include "clang/Edit/EditsReceiver.h"
24#include "clang/Frontend/CompilerInstance.h"
25#include "clang/Frontend/CompilerInvocation.h"
26#include "clang/Frontend/FrontendActions.h"
27#include "clang/Frontend/FrontendDiagnostic.h"
28#include "clang/Frontend/FrontendPluginRegistry.h"
29#include "clang/Frontend/TextDiagnosticBuffer.h"
30#include "clang/Frontend/TextDiagnosticPrinter.h"
31#include "clang/Lex/Preprocessor.h"
32#include "clang/Parse/ParseAST.h"
33#include "clang/Rewrite/Core/Rewriter.h"
34#include "clang/Rewrite/Frontend/FrontendActions.h"
35#include "clang/Sema/CodeCompleteConsumer.h"
36#include "clang/Sema/Sema.h"
37#include "clang/Sema/SemaConsumer.h"
39#include "llvm/ADT/StringRef.h"
40#include "llvm/ExecutionEngine/ExecutionEngine.h"
41#include "llvm/Support/CrashRecoveryContext.h"
42#include "llvm/Support/Debug.h"
43#include "llvm/Support/Error.h"
44#include "llvm/Support/FileSystem.h"
45#include "llvm/Support/TargetSelect.h"
47#include "llvm/IR/LLVMContext.h"
48#include "llvm/IR/Module.h"
49#include "llvm/Support/DynamicLibrary.h"
50#include "llvm/Support/ErrorHandling.h"
51#include "llvm/Support/MemoryBuffer.h"
52#include "llvm/Support/Signals.h"
53#include "llvm/TargetParser/Host.h"
103using namespace clang;
121 clang::SourceManager &source_mgr)
125 void moduleImport(SourceLocation import_location, clang::ModuleIdPath path,
126 const clang::Module * )
override {
129 llvm::StringRef filename =
130 m_source_mgr.getPresumedLoc(import_location).getFilename();
136 for (
const std::pair<IdentifierInfo *, SourceLocation> &component : path)
155 for (
auto &fix_it : Info.getFixItHints()) {
165 DiagnosticOptions *options =
new DiagnosticOptions(opts);
166 options->ShowPresumedLoc =
true;
167 options->ShowLevel =
false;
168 m_os = std::make_shared<llvm::raw_string_ostream>(
m_output);
170 std::make_shared<clang::TextDiagnosticPrinter>(*
m_os, options);
189 const clang::Diagnostic &Info)
override {
198 llvm::SmallVector<char, 32> diag_str;
199 Info.FormatDiagnostic(diag_str);
200 diag_str.push_back(
'\0');
201 const char *plain_diag = diag_str.data();
202 LLDB_LOG(log,
"Received diagnostic outside parsing: {0}", plain_diag);
208 DiagnosticConsumer::HandleDiagnostic(DiagLevel, Info);
216 bool make_new_diagnostic =
true;
219 case DiagnosticsEngine::Level::Fatal:
220 case DiagnosticsEngine::Level::Error:
223 case DiagnosticsEngine::Level::Warning:
226 case DiagnosticsEngine::Level::Remark:
227 case DiagnosticsEngine::Level::Ignored:
230 case DiagnosticsEngine::Level::Note:
232 make_new_diagnostic =
false;
243 if (!clang_diag || clang_diag->HasFixIts())
251 if (make_new_diagnostic) {
254 std::string stripped_output =
255 std::string(llvm::StringRef(
m_output).trim());
257 auto new_diagnostic = std::make_unique<ClangDiagnostic>(
258 stripped_output, severity, Info.getID());
281 std::shared_ptr<llvm::raw_string_ostream>
m_os;
290static llvm::Expected<bool>
293 auto const &triple = arch_spec.
GetTriple();
296 return llvm::createStringError(
"Executable module not found.");
301 return llvm::createStringError(
"No Platform plugin found on target.");
303 auto sdk_or_err = platform_sp->GetSDKPathFromDebugInfo(*module_sp);
305 return sdk_or_err.takeError();
308 auto sdk_path_or_err =
309 HostInfo::GetSDKRoot(HostInfo::SDKOptions{std::move(sdk_or_err->first)});
310 if (!sdk_path_or_err)
311 return sdk_path_or_err.takeError();
315 return llvm::createStringError(
"No virtual filesystem available.");
318 auto parsed_or_err = clang::parseDarwinSDKInfo(*VFS, *sdk_path_or_err);
320 return parsed_or_err.takeError();
322 auto maybe_sdk = *parsed_or_err;
324 return llvm::createStringError(
"Couldn't find Darwin SDK info.");
330 std::vector<std::string> include_directories,
334 HeaderSearchOptions &search_opts = compiler->getHeaderSearchOpts();
336 for (
const std::string &dir : include_directories) {
337 search_opts.AddPath(dir, frontend::System,
false,
true);
338 LLDB_LOG(log,
"Added user include dir: {0}", dir);
341 llvm::SmallString<128> module_cache;
343 props.GetClangModulesCachePath().GetPath(module_cache);
344 search_opts.ModuleCachePath = std::string(module_cache.str());
345 LLDB_LOG(log,
"Using module cache path: {0}", module_cache.c_str());
349 search_opts.ImplicitModuleMaps =
true;
357 if (token ==
"using")
360 if (token ==
"__null")
363 LangOptions cpp_lang_opts;
364 cpp_lang_opts.CPlusPlus =
true;
365 cpp_lang_opts.CPlusPlus11 =
true;
366 cpp_lang_opts.CPlusPlus20 =
true;
368 clang::IdentifierInfo &ii = idents.get(token);
371 if (!ii.isCPlusPlusKeyword(cpp_lang_opts))
374 if (ii.getTokenID() == clang::tok::identifier)
378 ii.revertTokenIDToIdentifier();
383#define KEYWORD(NAME, FLAGS) RemoveCppKeyword(idents, llvm::StringRef(#NAME));
384#include "clang/Basic/TokenKinds.def"
390 const std::vector<const char *> groupsToIgnore = {
393 "unused-getter-return-value",
395 for (
const char *group : groupsToIgnore) {
396 compiler.getDiagnostics().setSeverityForGroup(
397 clang::diag::Flavor::WarningOrError, group,
398 clang::diag::Severity::Ignored, SourceLocation());
412 if (target_arch.
IsMIPS()) {
435 const auto target_machine = target_arch.
GetMachine();
437 std::string triple = target_arch.
GetTriple().str();
438 compiler.getTargetOpts().Triple = triple;
439 LLDB_LOGF(log,
"Using %s as the target triple",
440 compiler.getTargetOpts().Triple.c_str());
448 compiler.getTargetOpts().Triple = llvm::sys::getDefaultTargetTriple();
449 LLDB_LOGF(log,
"Using default target triple of %s",
450 compiler.getTargetOpts().Triple.c_str());
454 if (compiler.getTargetOpts().Triple.find(
"arm64") == std::string::npos &&
455 compiler.getTargetOpts().Triple.find(
"arm") != std::string::npos &&
456 compiler.getTargetOpts().Triple.find(
"ios") != std::string::npos) {
457 compiler.getTargetOpts().ABI =
"apcs-gnu";
460 if (target_machine == llvm::Triple::x86 ||
461 target_machine == llvm::Triple::x86_64) {
462 compiler.getTargetOpts().FeaturesAsWritten.push_back(
"+sse");
463 compiler.getTargetOpts().FeaturesAsWritten.push_back(
"+sse2");
473 compiler.getTargetOpts().ABI = std::move(abi);
493 frame_lang = frame_sp->GetLanguage().AsLanguageType();
496 LLDB_LOGF(log,
"Frame has language of type %s",
501 LangOptions &lang_opts = compiler.getLangOpts();
514 lang_opts.CPlusPlus =
true;
517 lang_opts.ObjC =
true;
520 lang_opts.CPlusPlus =
true;
528 lang_opts.CPlusPlus11 =
true;
531 lang_opts.CPlusPlus20 =
true;
537 lang_opts.CPlusPlus14 =
true;
538 lang_opts.CPlusPlus17 =
true;
543 lang_opts.CPlusPlus11 =
true;
544 compiler.getHeaderSearchOpts().UseLibcxx =
true;
547 lang_opts.CPlusPlus =
true;
551 && !(frame_sp && frame_sp->HasDebugInformation()))
558 lang_opts.ObjC =
true;
559 lang_opts.CPlusPlus =
true;
560 lang_opts.CPlusPlus11 =
true;
561 compiler.getHeaderSearchOpts().UseLibcxx =
true;
565 lang_opts.Bool =
true;
566 lang_opts.WChar =
true;
567 lang_opts.Blocks =
true;
568 lang_opts.DebuggerSupport =
571 lang_opts.DebuggerCastResultToId =
true;
573 lang_opts.CharIsSigned =
579 lang_opts.SpellChecking =
false;
581 if (process_sp && lang_opts.ObjC) {
583 switch (runtime->GetRuntimeVersion()) {
584 case ObjCLanguageRuntime::ObjCRuntimeVersions::eAppleObjC_V2:
585 lang_opts.ObjCRuntime.set(ObjCRuntime::MacOSX, VersionTuple(10, 7));
587 case ObjCLanguageRuntime::ObjCRuntimeVersions::eObjC_VersionUnknown:
588 case ObjCLanguageRuntime::ObjCRuntimeVersions::eAppleObjC_V1:
589 lang_opts.ObjCRuntime.set(ObjCRuntime::FragileMacOSX,
590 VersionTuple(10, 7));
592 case ObjCLanguageRuntime::ObjCRuntimeVersions::eGNUstep_libobjc2:
593 lang_opts.ObjCRuntime.set(ObjCRuntime::GNUstep, VersionTuple(2, 0));
597 if (runtime->HasNewLiteralsAndIndexing())
598 lang_opts.DebuggerObjCLiteral =
true;
602 lang_opts.ThreadsafeStatics =
false;
603 lang_opts.AccessControl =
false;
604 lang_opts.DollarIdents =
true;
608 lang_opts.NoBuiltin =
true;
614 LangOptions &lang_opts = compiler.getLangOpts();
615 lang_opts.Modules =
true;
617 lang_opts.ImplicitModules =
true;
619 lang_opts.ModulesLocalVisibility =
false;
623 lang_opts.ObjC =
true;
627 lang_opts.GNUMode =
true;
628 lang_opts.GNUKeywords =
true;
629 lang_opts.CPlusPlus11 =
true;
632 lang_opts.BuiltinHeadersInSystemModules = !*supported_or_err;
635 "Failed to determine BuiltinHeadersInSystemModules when "
636 "setting up import-std-module: {0}");
639 lang_opts.GNUCVersion = 40201;
648 bool generate_debug_info, std::vector<std::string> include_directories,
649 std::string filename)
651 m_pp_callbacks(nullptr),
652 m_include_directories(std::move(include_directories)),
653 m_filename(std::move(filename)) {
665 "Can't make an expression parser with a null scope.");
673 "Can't make an expression parser with a null target.");
678 m_compiler = std::make_unique<CompilerInstance>();
691 m_compiler->getDiagnostics().setErrorLimit(target_sp->GetExprErrorLimit());
693 if (
auto *target_info = TargetInfo::CreateTargetInfo(
697 LLDB_LOGF(log,
"Target datalayout string: '%s'",
698 target_info->getDataLayoutString());
699 LLDB_LOGF(log,
"Target ABI: '%s'", target_info->getABI().str().c_str());
700 LLDB_LOGF(log,
"Target vector alignment: %d",
701 target_info->getMaxVectorAlign());
706 LLDB_LOGF(log,
"Failed to create TargetInfo for '%s'",
709 lldbassert(
false &&
"Failed to create TargetInfo.");
714 if (
auto *clang_expr = dyn_cast<ClangUserExpression>(&
m_expr);
715 clang_expr && clang_expr->DidImportCxxModules()) {
716 LLDB_LOG(log,
"Adding lang options for importing C++ modules");
722 m_compiler->getCodeGenOpts().EmitDeclMetadata =
true;
723 m_compiler->getCodeGenOpts().InstrumentFunctions =
false;
725 CodeGenOptions::FramePointerKind::All);
726 if (generate_debug_info)
727 m_compiler->getCodeGenOpts().setDebugInfo(codegenoptions::FullDebugInfo);
729 m_compiler->getCodeGenOpts().setDebugInfo(codegenoptions::NoDebugInfo);
744 m_compiler->getDiagnostics().getDiagnosticOptions());
745 m_compiler->getDiagnostics().setClient(diag_mgr);
768 if (
auto *clang_persistent_vars = llvm::cast<ClangPersistentVariables>(
769 target_sp->GetPersistentExpressionStateForLanguage(
771 if (std::shared_ptr<ClangModulesDeclVendor> decl_vendor =
772 clang_persistent_vars->GetClangModulesDeclVendor()) {
773 std::unique_ptr<PPCallbacks> pp_callbacks(
778 m_compiler->getPreprocessor().addPPCallbacks(std::move(pp_callbacks));
786 auto &builtin_context = PP.getBuiltinInfo();
787 builtin_context.initializeBuiltins(PP.getIdentifierTable(),
791 clang::ASTContext &ast_context =
m_compiler->getASTContext();
794 "Expression ASTContext for '" +
m_filename +
"'", ast_context);
796 std::string module_name(
"$__lldb_module");
815class CodeComplete :
public CodeCompleteConsumer {
816 CodeCompletionTUInfo m_info;
819 unsigned m_position = 0;
822 clang::PrintingPolicy m_desc_policy;
824 struct CompletionWithPriority {
832 bool operator<(
const CompletionWithPriority &o)
const {
834 if (Priority != o.Priority)
835 return Priority > o.Priority;
838 return completion.
GetUniqueKey() < o.completion.GetUniqueKey();
845 std::vector<CompletionWithPriority> m_completions;
852 static bool IsIdChar(
char c) {
853 return c ==
'_' || std::isalnum(c) || c ==
'$';
858 static bool IsTokenSeparator(
char c) {
return c ==
' ' || c ==
'\t'; }
863 StringRef dropUnrelatedFrontTokens(StringRef cmd)
const {
869 if (IsTokenSeparator(cmd.back()))
874 StringRef to_remove = cmd;
875 while (!to_remove.empty() && !IsTokenSeparator(to_remove.back())) {
876 to_remove = to_remove.drop_back();
878 cmd = cmd.drop_front(to_remove.size());
884 StringRef removeLastToken(StringRef cmd)
const {
885 while (!cmd.empty() && IsIdChar(cmd.back())) {
886 cmd = cmd.drop_back();
894 std::string mergeCompletion(StringRef existing,
unsigned pos,
895 StringRef completion)
const {
896 StringRef existing_command = existing.substr(0, pos);
899 existing_command = removeLastToken(existing_command);
903 existing_command = dropUnrelatedFrontTokens(existing_command);
904 return existing_command.str() + completion.str();
917 CodeComplete(clang::LangOptions ops, std::string expr,
unsigned position)
918 : CodeCompleteConsumer(CodeCompleteOptions()),
919 m_info(std::make_shared<GlobalCodeCompletionAllocator>()), m_expr(expr),
920 m_position(position), m_desc_policy(ops) {
924 m_desc_policy.SuppressScope =
true;
925 m_desc_policy.SuppressTagKeyword =
true;
926 m_desc_policy.FullyQualifiedName =
false;
927 m_desc_policy.TerseOutput =
true;
928 m_desc_policy.IncludeNewlines =
false;
929 m_desc_policy.UseVoidForZeroParams =
false;
930 m_desc_policy.Bool =
true;
935 bool isResultFilteredOut(StringRef Filter,
936 CodeCompletionResult Result)
override {
938 switch (Result.Kind) {
939 case CodeCompletionResult::RK_Declaration:
941 Result.Declaration->getIdentifier() &&
942 Result.Declaration->getIdentifier()->getName().starts_with(Filter));
943 case CodeCompletionResult::RK_Keyword:
944 return !StringRef(Result.Keyword).starts_with(Filter);
945 case CodeCompletionResult::RK_Macro:
946 return !Result.Macro->getName().starts_with(Filter);
947 case CodeCompletionResult::RK_Pattern:
948 return !StringRef(Result.Pattern->getAsString()).starts_with(Filter);
953 assert(
false &&
"Unknown completion result type?");
968 std::optional<CompletionWithPriority>
969 getCompletionForResult(
const CodeCompletionResult &R)
const {
970 std::string ToInsert;
971 std::string Description;
974 case CodeCompletionResult::RK_Declaration: {
975 const NamedDecl *D = R.Declaration;
976 ToInsert = R.Declaration->getNameAsString();
980 if (
const FunctionDecl *F = dyn_cast<FunctionDecl>(D)) {
981 if (F->getNumParams() == 0)
985 raw_string_ostream
OS(Description);
986 F->print(
OS, m_desc_policy,
false);
988 }
else if (
const VarDecl *V = dyn_cast<VarDecl>(D)) {
989 Description = V->getType().getAsString(m_desc_policy);
990 }
else if (
const FieldDecl *F = dyn_cast<FieldDecl>(D)) {
991 Description = F->getType().getAsString(m_desc_policy);
992 }
else if (
const NamespaceDecl *N = dyn_cast<NamespaceDecl>(D)) {
995 if (!N->isAnonymousNamespace())
1000 case CodeCompletionResult::RK_Keyword:
1001 ToInsert = R.Keyword;
1003 case CodeCompletionResult::RK_Macro:
1004 ToInsert = R.Macro->getName().str();
1006 case CodeCompletionResult::RK_Pattern:
1007 ToInsert = R.Pattern->getTypedText();
1012 if (llvm::StringRef(ToInsert).starts_with(
"$__lldb_"))
1013 return std::nullopt;
1014 if (ToInsert.empty())
1015 return std::nullopt;
1018 std::string CompletionSuggestion =
1019 mergeCompletion(m_expr, m_position, ToInsert);
1022 CompletionMode::Normal);
1023 return {{completion, R.Priority}};
1031 llvm::sort(m_completions);
1033 for (
const CompletionWithPriority &C : m_completions)
1035 C.completion.GetDescription(),
1036 C.completion.GetMode());
1041 void ProcessCodeCompleteResults(Sema &SemaRef, CodeCompletionContext Context,
1042 CodeCompletionResult *Results,
1043 unsigned NumResults)
override {
1047 StringRef Filter = SemaRef.getPreprocessor().getCodeCompletionFilter();
1051 for (
unsigned I = 0; I != NumResults; ++I) {
1053 if (!Filter.empty() && isResultFilteredOut(Filter, Results[I]))
1056 CodeCompletionResult &R = Results[I];
1057 std::optional<CompletionWithPriority> CompletionAndPriority =
1058 getCompletionForResult(R);
1059 if (!CompletionAndPriority)
1061 m_completions.push_back(*CompletionAndPriority);
1073 void ProcessOverloadCandidates(Sema &S,
unsigned CurrentArg,
1074 OverloadCandidate *Candidates,
1075 unsigned NumCandidates,
1076 SourceLocation OpenParLoc,
1077 bool Braced)
override {
1081 CodeCompletionAllocator &getAllocator()
override {
1082 return m_info.getAllocator();
1085 CodeCompletionTUInfo &getCodeCompletionTUInfo()
override {
return m_info; }
1090 unsigned pos,
unsigned typed_pos) {
1105 CC.GetCompletions(request);
1115 CodeCompleteConsumer *completion_consumer,
1116 unsigned completion_line,
1117 unsigned completion_column) {
1126 clang::SourceManager &source_mgr =
m_compiler->getSourceManager();
1127 bool created_main_file =
false;
1133 bool should_create_file = completion_consumer !=
nullptr;
1136 should_create_file |=
m_compiler->getCodeGenOpts().getDebugInfo() ==
1137 codegenoptions::FullDebugInfo;
1139 if (should_create_file) {
1141 llvm::SmallString<128> result_path;
1142 if (
FileSpec tmpdir_file_spec = HostInfo::GetProcessTempDir()) {
1143 tmpdir_file_spec.AppendPathComponent(
"lldb-%%%%%%.expr");
1144 std::string temp_source_path = tmpdir_file_spec.GetPath();
1145 llvm::sys::fs::createUniqueFile(temp_source_path, temp_fd, result_path);
1147 llvm::sys::fs::createTemporaryFile(
"lldb",
"expr", temp_fd, result_path);
1150 if (temp_fd != -1) {
1152 const size_t expr_text_len = strlen(expr_text);
1153 size_t bytes_written = expr_text_len;
1155 if (bytes_written == expr_text_len) {
1157 if (
auto fileEntry =
m_compiler->getFileManager().getOptionalFileRef(
1159 source_mgr.setMainFileID(source_mgr.createFileID(
1161 SourceLocation(), SrcMgr::C_User));
1162 created_main_file =
true;
1169 if (!created_main_file) {
1170 std::unique_ptr<MemoryBuffer> memory_buffer =
1171 MemoryBuffer::getMemBufferCopy(expr_text,
m_filename);
1172 source_mgr.setMainFileID(source_mgr.createFileID(std::move(memory_buffer)));
1185 if (completion_consumer) {
1187 source_mgr.getFileEntryRefForID(source_mgr.getMainFileID());
1192 ++completion_column;
1193 PP.SetCodeCompletionPoint(*main_file, completion_line, completion_column);
1196 ASTConsumer *ast_transformer =
1199 std::unique_ptr<clang::ASTConsumer> Consumer;
1200 if (ast_transformer) {
1201 Consumer = std::make_unique<ASTConsumerForwarder>(ast_transformer);
1205 Consumer = std::make_unique<ASTConsumer>();
1208 clang::ASTContext &ast_context =
m_compiler->getASTContext();
1211 *Consumer, TU_Complete, completion_consumer));
1212 m_compiler->setASTConsumer(std::move(Consumer));
1214 if (ast_context.getLangOpts().Modules) {
1224 clang::ExternalASTSource *ast_source = decl_map->
CreateProxy();
1228 if (ast_context.getExternalSource()) {
1229 auto *module_wrapper =
1237 ast_context.setExternalSource(multiplexer);
1239 ast_context.setExternalSource(ast_source);
1241 m_compiler->getSema().addExternalSource(ast_source_wrapper);
1246 if (ast_context.getLangOpts().Modules) {
1247 assert(
m_compiler->getASTContext().getExternalSource() &&
1248 "ASTContext doesn't know about the ASTReader?");
1249 assert(
m_compiler->getSema().getExternalSource() &&
1250 "Sema doesn't know about the ASTReader?");
1254 llvm::CrashRecoveryContextCleanupRegistrar<Sema> CleanupSema(
1256 ParseAST(
m_compiler->getSema(),
false,
false);
1260 if (ast_context.getLangOpts().Modules)
1268 unsigned num_errors = adapter->getNumErrors();
1273 "while importing modules:");
1288static void ApplyFixIt(
const FixItHint &fixit, clang::edit::Commit &commit) {
1290 if (fixit.CodeToInsert.empty()) {
1291 if (fixit.InsertFromRange.isValid()) {
1292 commit.insertFromRange(fixit.RemoveRange.getBegin(),
1293 fixit.InsertFromRange,
false,
1294 fixit.BeforePreviousInsertions);
1297 commit.remove(fixit.RemoveRange);
1300 if (fixit.RemoveRange.isTokenRange() ||
1301 fixit.RemoveRange.getBegin() != fixit.RemoveRange.getEnd()) {
1302 commit.replace(fixit.RemoveRange, fixit.CodeToInsert);
1305 commit.insert(fixit.RemoveRange.getBegin(), fixit.CodeToInsert,
1306 false, fixit.BeforePreviousInsertions);
1311 clang::SourceManager &source_manager =
m_compiler->getSourceManager();
1312 clang::edit::EditedSource editor(source_manager,
m_compiler->getLangOpts(),
1314 clang::edit::Commit commit(editor);
1315 clang::Rewriter rewriter(source_manager,
m_compiler->getLangOpts());
1317 class RewritesReceiver :
public edit::EditsReceiver {
1321 RewritesReceiver(Rewriter &in_rewrite) : rewrite(in_rewrite) {}
1323 void insert(SourceLocation loc, StringRef text)
override {
1324 rewrite.InsertText(loc, text);
1326 void replace(CharSourceRange range, StringRef text)
override {
1327 rewrite.ReplaceText(range.getBegin(), rewrite.getRangeSize(range), text);
1331 RewritesReceiver rewrites_receiver(rewriter);
1334 size_t num_diags = diagnostics.size();
1338 for (
const auto &diag : diagnostic_manager.
Diagnostics()) {
1339 const auto *diagnostic = llvm::dyn_cast<ClangDiagnostic>(diag.get());
1342 if (!diagnostic->HasFixIts())
1344 for (
const FixItHint &fixit : diagnostic->FixIts())
1349 if (!commit.isCommitable())
1351 else if (!editor.commit(commit))
1355 editor.applyRewrites(rewrites_receiver);
1356 RewriteBuffer &main_file_buffer =
1357 rewriter.getEditBuffer(source_manager.getMainFileID());
1359 std::string fixed_expression;
1360 llvm::raw_string_ostream out_stream(fixed_expression);
1362 main_file_buffer.write(out_stream);
1370 llvm::Module *module,
const char *orig_name) {
1371 for (
const auto &func : module->getFunctionList()) {
1372 const StringRef &name = func.getName();
1373 if (name.contains(orig_name)) {
1392 std::unique_ptr<llvm::Module> llvm_module_up(
1395 if (!llvm_module_up) {
1421 sc = frame_sp->GetSymbolContext(lldb::eSymbolContextEverything);
1429 LLDB_LOGF(log,
"%s - Current expression language is %s\n", __FUNCTION__,
1430 lang.GetDescription().data());
1433 auto runtime = process_sp->GetLanguageRuntime(lang.AsLanguageType());
1435 runtime->GetIRPasses(custom_passes);
1441 "%s - Running Early IR Passes from LanguageRuntime on "
1442 "expression module '%s'",
1448 execution_unit_sp = std::make_shared<IRExecutionUnit>(
1457 type_system_helper->
DeclMap();
1462 *execution_unit_sp, error_stream,
1465 if (!ir_for_target.
runOnModule(*execution_unit_sp->GetModule())) {
1476 bool interpret_function_calls =
1479 *execution_unit_sp->GetModule(), *execution_unit_sp->GetFunction(),
1480 interpret_error, interpret_function_calls);
1484 "Can't evaluate the expression without a running target due to: %s",
1491 err.
SetErrorString(
"Expression needed to run in the target, but the "
1492 "target can't be run");
1497 err.
SetErrorString(
"Top-level code needs to be inserted into a runnable "
1498 "target, but the target can't be run");
1510 if (
Error Err = dynamic_checkers->
Install(install_diags, exe_ctx)) {
1511 std::string ErrMsg =
"couldn't install checkers: " +
toString(std::move(Err));
1513 ErrMsg = ErrMsg +
"\n" + install_diags.
GetString().c_str();
1520 LLDB_LOGF(log,
"== [ClangExpressionParser::PrepareForExecution] "
1521 "Finished installing dynamic checkers ==");
1524 if (
auto *checker_funcs = llvm::dyn_cast<ClangDynamicCheckerFunctions>(
1529 llvm::Module *module = execution_unit_sp->GetModule();
1530 if (!module || !ir_dynamic_checks.
runOnModule(*module)) {
1532 err.
SetErrorString(
"Couldn't add dynamic checks to the expression");
1538 "%s - Running Late IR Passes from LanguageRuntime on "
1539 "expression module '%s'",
1550 execution_unit_sp->GetRunnableInfo(err, func_addr, func_end);
1553 execution_unit_sp->GetRunnableInfo(err, func_addr, func_end);
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 SetupImportStdModuleLangOpts(CompilerInstance &compiler, lldb_private::Target &target)
static void AddAllFixIts(ClangDiagnostic *diag, const clang::Diagnostic &Info)
static void SetupDefaultClangDiagnostics(CompilerInstance &compiler)
Configures Clang diagnostics for the expression parser.
static void SetupLangOpts(CompilerInstance &compiler, ExecutionContextScope &exe_scope, const Expression &expr)
static void SetupTargetOpts(CompilerInstance &compiler, lldb_private::Target const &target)
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)
static std::string GetClangTargetABI(const ArchSpec &target_arch)
Returns a string representing current ABI.
static llvm::Expected< bool > sdkSupportsBuiltinModules(lldb_private::Target &target)
Returns true if the SDK for the specified triple supports builtin modules in system headers.
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
#define LLDB_LOGF(log,...)
#define LLDB_LOG_ERROR(log, error,...)
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)
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.
std::unique_ptr< clang::CompilerInstance > m_compiler
The Clang compiler used to parse expressions into IR.
Status DoPrepareForExecution(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.
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::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
"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)
size_t void PutString(lldb::Severity severity, llvm::StringRef str)
void SetFixedExpression(std::string fixed_expression)
void AppendMessageToDiagnostic(llvm::StringRef str)
std::string GetString(char separator='\n')
const DiagnosticList & Diagnostics()
void AddDiagnostic(llvm::StringRef message, lldb::Severity 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.
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.
"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 SourceLanguage Language() const
Return the language that should be used when parsing.
virtual ResultType DesiredResultType() const
Return the desired result type of the function, or eResultTypeAny if indifferent.
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.
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.
llvm::IntrusiveRefCntPtr< llvm::vfs::FileSystem > GetVirtualFileSystem()
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::ModuleSP GetExecutableModule()
Gets the module for the main executable.
lldb::PlatformSP GetPlatform()
const ArchSpec & GetArchitecture() const
const char * GetUserText()
Return the string that the user typed.
static bool SDKSupportsBuiltinModules(const llvm::Triple &target_triple, llvm::VersionTuple sdk_version)
Returns true if the SDK for the specified triple supports builtin modules in system headers.
#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()
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)
Severity
Used for expressing severity in logs and diagnostics.
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.
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
lldb::LanguageType AsLanguageType() const
Information needed to import a source-language module.
std::vector< ConstString > path
Something like "Module.Submodule".