Add a new SBExpressionOptions::SetLanguage() API (NFCI) (#89981)

that separates out language and version. To avoid reinventing the wheel
and introducing subtle incompatibilities, this API uses the table of
languages and versiond defined by the upcoming DWARF 6 standard
(https://dwarfstd.org/languages-v6.html). While the DWARF 6 spec is not
finialized, the list of languages is broadly considered stable.

The primary motivation for this is to allow the Swift language plugin to
switch between language dialects between, e.g., Swift 5.9 and 6.0 with
out introducing a ton of new language codes. On the main branch this
change is considered NFC.

Depends on https://github.com/llvm/llvm-project/pull/89980
This commit is contained in:
Adrian Prantl 2024-04-29 13:26:24 -07:00 committed by GitHub
parent 8ba880b587
commit 975eca0e6a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
35 changed files with 306 additions and 123 deletions

View File

@ -10,6 +10,7 @@
#define LLDB_API_SBEXPRESSIONOPTIONS_H
#include "lldb/API/SBDefines.h"
#include "lldb/API/SBLanguages.h"
#include <vector>
@ -67,6 +68,10 @@ public:
void SetTrapExceptions(bool trap_exceptions = true);
void SetLanguage(lldb::LanguageType language);
/// Set the language using a pair of language code and version as
/// defined by the DWARF 6 specification.
/// WARNING: These codes may change until DWARF 6 is finalized.
void SetLanguage(SBSourceLanguageName name, uint32_t version);
#ifndef SWIG
void SetCancelCallback(lldb::ExpressionCancelCallback callback, void *baton);

View File

@ -47,11 +47,8 @@ public:
/// expression. Text() should contain the definition of this function.
virtual const char *FunctionName() = 0;
/// Return the language that should be used when parsing. To use the
/// default, return eLanguageTypeUnknown.
virtual lldb::LanguageType Language() const {
return lldb::eLanguageTypeUnknown;
}
/// Return the language that should be used when parsing.
virtual SourceLanguage Language() const { return {}; }
/// Return the Materializer that the parser should use when registering
/// external values.

View File

@ -52,7 +52,7 @@ public:
};
LLVMUserExpression(ExecutionContextScope &exe_scope, llvm::StringRef expr,
llvm::StringRef prefix, lldb::LanguageType language,
llvm::StringRef prefix, SourceLanguage language,
ResultType desired_type,
const EvaluateExpressionOptions &options);
~LLVMUserExpression() override;

View File

@ -56,7 +56,7 @@ public:
/// If not eResultTypeAny, the type to use for the expression
/// result.
UserExpression(ExecutionContextScope &exe_scope, llvm::StringRef expr,
llvm::StringRef prefix, lldb::LanguageType language,
llvm::StringRef prefix, SourceLanguage language,
ResultType desired_type,
const EvaluateExpressionOptions &options);
@ -202,7 +202,7 @@ public:
virtual bool IsParseCacheable() { return true; }
/// Return the language that should be used when parsing. To use the
/// default, return eLanguageTypeUnknown.
lldb::LanguageType Language() const override { return m_language; }
SourceLanguage Language() const override { return m_language; }
/// Return the desired result type of the function, or eResultTypeAny if
/// indifferent.
@ -315,19 +315,22 @@ protected:
lldb::ProcessSP &process_sp,
lldb::StackFrameSP &frame_sp);
Address m_address; ///< The address the process is stopped in.
std::string m_expr_text; ///< The text of the expression, as typed by the user
std::string m_expr_prefix; ///< The text of the translation-level definitions,
///as provided by the user
std::string m_fixed_text; ///< The text of the expression with fix-its applied
///- this won't be set if the fixed text doesn't
///parse.
lldb::LanguageType m_language; ///< The language to use when parsing
///(eLanguageTypeUnknown means use defaults)
ResultType m_desired_type; ///< The type to coerce the expression's result to.
///If eResultTypeAny, inferred from the expression.
EvaluateExpressionOptions
m_options; ///< Additional options provided by the user.
/// The address the process is stopped in.
Address m_address;
/// The text of the expression, as typed by the user.
std::string m_expr_text;
/// The text of the translation-level definitions, as provided by the user.
std::string m_expr_prefix;
/// The text of the expression with fix-its applied this won't be set if the
/// fixed text doesn't parse.
std::string m_fixed_text;
/// The language to use when parsing (unknown means use defaults).
SourceLanguage m_language;
/// The type to coerce the expression's result to. If eResultTypeAny, inferred
/// from the expression.
ResultType m_desired_type;
/// Additional options provided by the user.
EvaluateExpressionOptions m_options;
};
} // namespace lldb_private

View File

@ -483,12 +483,10 @@ public:
return IsPointerOrReferenceType(type, nullptr);
}
virtual UserExpression *
GetUserExpression(llvm::StringRef expr, llvm::StringRef prefix,
lldb::LanguageType language,
Expression::ResultType desired_type,
const EvaluateExpressionOptions &options,
ValueObject *ctx_obj) {
virtual UserExpression *GetUserExpression(
llvm::StringRef expr, llvm::StringRef prefix, SourceLanguage language,
Expression::ResultType desired_type,
const EvaluateExpressionOptions &options, ValueObject *ctx_obj) {
return nullptr;
}

View File

@ -1,3 +1,4 @@
//===-- StackFrame.h --------------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
@ -446,13 +447,12 @@ public:
/// Query this frame to determine what the default language should be when
/// parsing expressions given the execution context.
///
/// \return
/// The language of the frame if known, else lldb::eLanguageTypeUnknown.
lldb::LanguageType GetLanguage();
/// \return The language of the frame if known.
SourceLanguage GetLanguage();
// similar to GetLanguage(), but is allowed to take a potentially incorrect
// guess if exact information is not available
lldb::LanguageType GuessLanguage();
/// Similar to GetLanguage(), but is allowed to take a potentially incorrect
/// guess if exact information is not available.
SourceLanguage GuessLanguage();
/// Attempt to econstruct the ValueObject for a given raw address touched by
/// the current instruction. The ExpressionPath should indicate how to get

View File

@ -200,7 +200,7 @@ public:
bool GetBreakpointsConsultPlatformAvoidList();
lldb::LanguageType GetLanguage() const;
SourceLanguage GetLanguage() const;
llvm::StringRef GetExpressionPrefixContents();
@ -310,9 +310,18 @@ public:
m_execution_policy = policy;
}
lldb::LanguageType GetLanguage() const { return m_language; }
SourceLanguage GetLanguage() const { return m_language; }
void SetLanguage(lldb::LanguageType language) { m_language = language; }
void SetLanguage(lldb::LanguageType language_type) {
m_language = SourceLanguage(language_type);
}
/// Set the language using a pair of language code and version as
/// defined by the DWARF 6 specification.
/// WARNING: These codes may change until DWARF 6 is finalized.
void SetLanguage(uint16_t name, uint32_t version) {
m_language = SourceLanguage(name, version);
}
bool DoesCoerceToId() const { return m_coerce_to_id; }
@ -445,7 +454,7 @@ public:
private:
ExecutionPolicy m_execution_policy = default_execution_policy;
lldb::LanguageType m_language = lldb::eLanguageTypeUnknown;
SourceLanguage m_language;
std::string m_prefix;
bool m_coerce_to_id = false;
bool m_unwind_on_error = true;
@ -1160,7 +1169,7 @@ public:
UserExpression *
GetUserExpressionForLanguage(llvm::StringRef expr, llvm::StringRef prefix,
lldb::LanguageType language,
SourceLanguage language,
Expression::ResultType desired_type,
const EvaluateExpressionOptions &options,
ValueObject *ctx_obj, Status &error);

View File

@ -96,6 +96,25 @@ struct RegisterSet {
const uint32_t *registers;
};
/// A type-erased pair of llvm::dwarf::SourceLanguageName and version.
struct SourceLanguage {
SourceLanguage() = default;
SourceLanguage(lldb::LanguageType language_type);
SourceLanguage(uint16_t name, uint32_t version)
: name(name), version(version) {}
SourceLanguage(std::optional<std::pair<uint16_t, uint32_t>> name_vers)
: name(name_vers ? name_vers->first : 0),
version(name_vers ? name_vers->second : 0) {}
operator bool() const { return name > 0; }
lldb::LanguageType AsLanguageType() const;
llvm::StringRef GetDescription() const;
bool IsC() const;
bool IsObjC() const;
bool IsCPlusPlus() const;
uint16_t name = 0;
uint32_t version = 0;
};
struct OptionEnumValueElement {
int64_t value;
const char *string_value;

View File

@ -119,6 +119,7 @@ all_tests = set()
# LLDB library directory.
lldb_libs_dir = None
lldb_obj_root = None
libcxx_include_dir = None
libcxx_include_target_dir = None

View File

@ -423,6 +423,7 @@ def parseOptionsAndInitTestdirs():
configuration.lldb_module_cache_dir = os.path.join(
configuration.test_build_dir, "module-cache-lldb"
)
if args.clang_module_cache_dir:
configuration.clang_module_cache_dir = args.clang_module_cache_dir
else:
@ -432,6 +433,8 @@ def parseOptionsAndInitTestdirs():
if args.lldb_libs_dir:
configuration.lldb_libs_dir = args.lldb_libs_dir
if args.lldb_obj_root:
configuration.lldb_obj_root = args.lldb_obj_root
if args.enabled_plugins:
configuration.enabled_plugins = args.enabled_plugins

View File

@ -236,11 +236,17 @@ def create_parser():
metavar="The clang module cache directory used by Clang",
help="The clang module cache directory used in the Make files by Clang while building tests. Defaults to <test build directory>/module-cache-clang.",
)
group.add_argument(
"--lldb-obj-root",
dest="lldb_obj_root",
metavar="path",
help="The path to the LLDB object files.",
)
group.add_argument(
"--lldb-libs-dir",
dest="lldb_libs_dir",
metavar="path",
help="The path to LLDB library directory (containing liblldb)",
help="The path to LLDB library directory (containing liblldb).",
)
group.add_argument(
"--enable-plugin",

View File

@ -1473,11 +1473,12 @@ class Base(unittest.TestCase):
d = {
"CXX_SOURCES": sources,
"EXE": exe_name,
"CFLAGS_EXTRAS": "%s %s -I%s"
"CFLAGS_EXTRAS": "%s %s -I%s -I%s"
% (
stdflag,
stdlibflag,
os.path.join(os.environ["LLDB_SRC"], "include"),
os.path.join(configuration.lldb_obj_root, "include"),
),
"LD_EXTRAS": "-L%s -lliblldb" % lib_dir,
}
@ -1485,11 +1486,12 @@ class Base(unittest.TestCase):
d = {
"CXX_SOURCES": sources,
"EXE": exe_name,
"CFLAGS_EXTRAS": "%s %s -I%s"
"CFLAGS_EXTRAS": "%s %s -I%s -I%s"
% (
stdflag,
stdlibflag,
os.path.join(os.environ["LLDB_SRC"], "include"),
os.path.join(configuration.lldb_obj_root, "include"),
),
"LD_EXTRAS": "-L%s -llldb -Wl,-rpath,%s" % (lib_dir, lib_dir),
}
@ -1508,7 +1510,8 @@ class Base(unittest.TestCase):
d = {
"DYLIB_CXX_SOURCES": sources,
"DYLIB_NAME": lib_name,
"CFLAGS_EXTRAS": "%s -stdlib=libc++" % stdflag,
"CFLAGS_EXTRAS": "%s -stdlib=libc++ -I%s"
% (stdflag, os.path.join(configuration.lldb_obj_root, "include")),
"FRAMEWORK_INCLUDES": "-F%s" % self.framework_dir,
"LD_EXTRAS": "%s -Wl,-rpath,%s -dynamiclib"
% (self.lib_lldb, self.framework_dir),
@ -1517,16 +1520,24 @@ class Base(unittest.TestCase):
d = {
"DYLIB_CXX_SOURCES": sources,
"DYLIB_NAME": lib_name,
"CFLAGS_EXTRAS": "%s -I%s "
% (stdflag, os.path.join(os.environ["LLDB_SRC"], "include")),
"CFLAGS_EXTRAS": "%s -I%s -I%s"
% (
stdflag,
os.path.join(os.environ["LLDB_SRC"], "include"),
os.path.join(configuration.lldb_obj_root, "include"),
),
"LD_EXTRAS": "-shared -l%s\liblldb.lib" % lib_dir,
}
else:
d = {
"DYLIB_CXX_SOURCES": sources,
"DYLIB_NAME": lib_name,
"CFLAGS_EXTRAS": "%s -I%s -fPIC"
% (stdflag, os.path.join(os.environ["LLDB_SRC"], "include")),
"CFLAGS_EXTRAS": "%s -I%s -I%s -fPIC"
% (
stdflag,
os.path.join(os.environ["LLDB_SRC"], "include"),
os.path.join(configuration.lldb_obj_root, "include"),
),
"LD_EXTRAS": "-shared -L%s -llldb -Wl,-rpath,%s" % (lib_dir, lib_dir),
}
if self.TraceOn():

View File

@ -20,6 +20,10 @@ if(LLDB_ENABLE_LUA)
set(lldb_lua_wrapper ${lua_bindings_dir}/LLDBWrapLua.cpp)
endif()
lldb_tablegen(../../include/lldb/API/SBLanguages.h -gen-lldb-sbapi-dwarf-enum
SOURCE ${LLVM_MAIN_INCLUDE_DIR}/llvm/BinaryFormat/Dwarf.def
TARGET lldb-sbapi-dwarf-enums)
add_lldb_library(liblldb SHARED ${option_framework}
SBAddress.cpp
SBAttachInfo.cpp
@ -100,6 +104,9 @@ add_lldb_library(liblldb SHARED ${option_framework}
${lldb_python_wrapper}
${lldb_lua_wrapper}
DEPENDS
lldb-sbapi-dwarf-enums
LINK_LIBS
lldbBreakpoint
lldbCore

View File

@ -156,6 +156,13 @@ void SBExpressionOptions::SetLanguage(lldb::LanguageType language) {
m_opaque_up->SetLanguage(language);
}
void SBExpressionOptions::SetLanguage(SBSourceLanguageName name,
uint32_t version) {
LLDB_INSTRUMENT_VA(this, name, version);
m_opaque_up->SetLanguage(name, version);
}
void SBExpressionOptions::SetCancelCallback(
lldb::ExpressionCancelCallback callback, void *baton) {
LLDB_INSTRUMENT_VA(this, callback, baton);

View File

@ -1024,10 +1024,10 @@ SBValue SBFrame::EvaluateExpression(const char *expr) {
options.SetFetchDynamicValue(fetch_dynamic_value);
options.SetUnwindOnError(true);
options.SetIgnoreBreakpoints(true);
if (target->GetLanguage() != eLanguageTypeUnknown)
options.SetLanguage(target->GetLanguage());
else
options.SetLanguage(frame->GetLanguage());
SourceLanguage language = target->GetLanguage();
if (!language)
language = frame->GetLanguage();
options.SetLanguage((SBSourceLanguageName)language.name, language.version);
return EvaluateExpression(expr, options);
} else {
Status error;
@ -1053,10 +1053,12 @@ SBFrame::EvaluateExpression(const char *expr,
StackFrame *frame = exe_ctx.GetFramePtr();
Target *target = exe_ctx.GetTargetPtr();
if (target && target->GetLanguage() != eLanguageTypeUnknown)
options.SetLanguage(target->GetLanguage());
else if (frame)
options.SetLanguage(frame->GetLanguage());
SourceLanguage language;
if (target)
language = target->GetLanguage();
if (!language && frame)
language = frame->GetLanguage();
options.SetLanguage((SBSourceLanguageName)language.name, language.version);
return EvaluateExpression(expr, options);
}
@ -1074,10 +1076,12 @@ SBValue SBFrame::EvaluateExpression(const char *expr,
options.SetIgnoreBreakpoints(true);
StackFrame *frame = exe_ctx.GetFramePtr();
Target *target = exe_ctx.GetTargetPtr();
if (target && target->GetLanguage() != eLanguageTypeUnknown)
options.SetLanguage(target->GetLanguage());
else if (frame)
options.SetLanguage(frame->GetLanguage());
SourceLanguage language;
if (target)
language = target->GetLanguage();
if (!language && frame)
language = frame->GetLanguage();
options.SetLanguage((SBSourceLanguageName)language.name, language.version);
return EvaluateExpression(expr, options);
}
@ -1218,7 +1222,7 @@ lldb::LanguageType SBFrame::GuessLanguage() const {
if (stop_locker.TryLock(&process->GetRunLock())) {
frame = exe_ctx.GetFramePtr();
if (frame) {
return frame->GuessLanguage();
return frame->GuessLanguage().AsLanguageType();
}
}
}

View File

@ -460,9 +460,8 @@ void Watchpoint::SetCondition(const char *condition) {
// Pass nullptr for expr_prefix (no translation-unit level definitions).
Status error;
m_condition_up.reset(m_target.GetUserExpressionForLanguage(
condition, llvm::StringRef(), lldb::eLanguageTypeUnknown,
UserExpression::eResultTypeAny, EvaluateExpressionOptions(), nullptr,
error));
condition, {}, {}, UserExpression::eResultTypeAny,
EvaluateExpressionOptions(), nullptr, error));
if (error.Fail()) {
// FIXME: Log something...
m_condition_up.reset();

View File

@ -96,7 +96,7 @@ void CommandObjectDWIMPrint::DoExecute(StringRef command,
// Either Swift was explicitly specified, or the frame is Swift.
lldb::LanguageType language = m_expr_options.language;
if (language == lldb::eLanguageTypeUnknown && frame)
language = frame->GuessLanguage();
language = frame->GuessLanguage().AsLanguageType();
// Add a hint if object description was requested, but no description
// function was implemented.

View File

@ -2509,7 +2509,7 @@ protected:
if (!frame)
return lang_type;
lang_type = frame->GuessLanguage();
lang_type = frame->GuessLanguage().AsLanguageType();
if (lang_type != lldb::eLanguageTypeUnknown)
return lang_type;

View File

@ -42,7 +42,7 @@ char LLVMUserExpression::ID;
LLVMUserExpression::LLVMUserExpression(ExecutionContextScope &exe_scope,
llvm::StringRef expr,
llvm::StringRef prefix,
lldb::LanguageType language,
SourceLanguage language,
ResultType desired_type,
const EvaluateExpressionOptions &options)
: UserExpression(exe_scope, expr, prefix, language, desired_type, options),

View File

@ -39,6 +39,7 @@
#include "lldb/Utility/Log.h"
#include "lldb/Utility/State.h"
#include "lldb/Utility/StreamString.h"
#include "llvm/BinaryFormat/Dwarf.h"
using namespace lldb_private;
@ -46,8 +47,7 @@ char UserExpression::ID;
UserExpression::UserExpression(ExecutionContextScope &exe_scope,
llvm::StringRef expr, llvm::StringRef prefix,
lldb::LanguageType language,
ResultType desired_type,
SourceLanguage language, ResultType desired_type,
const EvaluateExpressionOptions &options)
: Expression(exe_scope), m_expr_text(std::string(expr)),
m_expr_prefix(std::string(prefix)), m_language(language),
@ -176,7 +176,7 @@ UserExpression::Evaluate(ExecutionContext &exe_ctx,
}
lldb_private::ExecutionPolicy execution_policy = options.GetExecutionPolicy();
lldb::LanguageType language = options.GetLanguage();
SourceLanguage language = options.GetLanguage();
const ResultType desired_type = options.DoesCoerceToId()
? UserExpression::eResultTypeId
: UserExpression::eResultTypeAny;
@ -242,7 +242,7 @@ UserExpression::Evaluate(ExecutionContext &exe_ctx,
// If the language was not specified in the expression command, set it to the
// language in the target's properties if specified, else default to the
// langage for the frame.
if (language == lldb::eLanguageTypeUnknown) {
if (!language.name) {
if (target->GetLanguage() != lldb::eLanguageTypeUnknown)
language = target->GetLanguage();
else if (StackFrame *frame = exe_ctx.GetFramePtr())
@ -384,7 +384,8 @@ UserExpression::Evaluate(ExecutionContext &exe_ctx,
} else {
if (expr_result) {
result_valobj_sp = expr_result->GetValueObject();
result_valobj_sp->SetPreferredDisplayLanguage(language);
result_valobj_sp->SetPreferredDisplayLanguage(
language.AsLanguageType());
LLDB_LOG(log,
"== [UserExpression::Evaluate] Execution completed "
@ -426,7 +427,8 @@ UserExpression::Execute(DiagnosticManager &diagnostic_manager,
Target *target = exe_ctx.GetTargetPtr();
if (options.GetSuppressPersistentResult() && result_var && target) {
if (auto *persistent_state =
target->GetPersistentExpressionStateForLanguage(m_language))
target->GetPersistentExpressionStateForLanguage(
m_language.AsLanguageType()))
persistent_state->RemovePersistentVariable(result_var);
}
return expr_result;

View File

@ -80,8 +80,8 @@ FunctionCaller *UtilityFunction::MakeFunctionCaller(
name.append("-caller");
m_caller_up.reset(process_sp->GetTarget().GetFunctionCallerForLanguage(
Language(), return_type, impl_code_address, arg_value_list, name.c_str(),
error));
Language().AsLanguageType(), return_type, impl_code_address,
arg_value_list, name.c_str(), error));
if (error.Fail()) {
return nullptr;

View File

@ -392,8 +392,8 @@ ClangExpressionParser::ClangExpressionParser(
// Make sure clang uses the same VFS as LLDB.
m_compiler->createFileManager(FileSystem::Instance().GetVirtualFileSystem());
lldb::LanguageType frame_lang =
expr.Language(); // defaults to lldb::eLanguageTypeUnknown
// Defaults to lldb::eLanguageTypeUnknown.
lldb::LanguageType frame_lang = expr.Language().AsLanguageType();
std::string abi;
ArchSpec target_arch;
@ -410,7 +410,7 @@ ClangExpressionParser::ClangExpressionParser(
// Make sure the user hasn't provided a preferred execution language with
// `expression --language X -- ...`
if (frame_sp && frame_lang == lldb::eLanguageTypeUnknown)
frame_lang = frame_sp->GetLanguage();
frame_lang = frame_sp->GetLanguage().AsLanguageType();
if (process_sp && frame_lang != lldb::eLanguageTypeUnknown) {
LLDB_LOGF(log, "Frame has language of type %s",
@ -479,7 +479,7 @@ ClangExpressionParser::ClangExpressionParser(
assert(m_compiler->hasTarget());
// 4. Set language options.
lldb::LanguageType language = expr.Language();
lldb::LanguageType language = expr.Language().AsLanguageType();
LangOptions &lang_opts = m_compiler->getLangOpts();
switch (language) {
@ -1344,10 +1344,10 @@ lldb_private::Status ClangExpressionParser::PrepareForExecution(
{
auto lang = m_expr.Language();
LLDB_LOGF(log, "%s - Current expression language is %s\n", __FUNCTION__,
Language::GetNameForLanguageType(lang));
lang.GetDescription().data());
lldb::ProcessSP process_sp = exe_ctx.GetProcessSP();
if (process_sp && lang != lldb::eLanguageTypeUnknown) {
auto runtime = process_sp->GetLanguageRuntime(lang);
auto runtime = process_sp->GetLanguageRuntime(lang.AsLanguageType());
if (runtime)
runtime->GetIRPasses(custom_passes);
}

View File

@ -56,6 +56,7 @@
#include "clang/AST/DeclObjC.h"
#include "llvm/ADT/ScopeExit.h"
#include "llvm/BinaryFormat/Dwarf.h"
using namespace lldb_private;
@ -63,22 +64,21 @@ char ClangUserExpression::ID;
ClangUserExpression::ClangUserExpression(
ExecutionContextScope &exe_scope, llvm::StringRef expr,
llvm::StringRef prefix, lldb::LanguageType language,
ResultType desired_type, const EvaluateExpressionOptions &options,
ValueObject *ctx_obj)
llvm::StringRef prefix, SourceLanguage language, ResultType desired_type,
const EvaluateExpressionOptions &options, ValueObject *ctx_obj)
: LLVMUserExpression(exe_scope, expr, prefix, language, desired_type,
options),
m_type_system_helper(*m_target_wp.lock(), options.GetExecutionPolicy() ==
eExecutionPolicyTopLevel),
m_result_delegate(exe_scope.CalculateTarget()), m_ctx_obj(ctx_obj) {
switch (m_language) {
case lldb::eLanguageTypeC_plus_plus:
switch (m_language.name) {
case llvm::dwarf::DW_LNAME_C_plus_plus:
m_allow_cxx = true;
break;
case lldb::eLanguageTypeObjC:
case llvm::dwarf::DW_LNAME_ObjC:
m_allow_objc = true;
break;
case lldb::eLanguageTypeObjC_plus_plus:
case llvm::dwarf::DW_LNAME_ObjC_plus_plus:
default:
m_allow_cxx = true;
m_allow_objc = true;
@ -624,7 +624,8 @@ bool ClangUserExpression::TryParse(
void ClangUserExpression::SetupCppModuleImports(ExecutionContext &exe_ctx) {
Log *log = GetLog(LLDBLog::Expressions);
CppModuleConfiguration module_config = GetModuleConfig(m_language, exe_ctx);
CppModuleConfiguration module_config =
GetModuleConfig(m_language.AsLanguageType(), exe_ctx);
m_imported_cpp_modules = module_config.GetImportedModules();
m_include_directories = module_config.GetIncludeDirs();
@ -734,7 +735,7 @@ bool ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager,
if (register_execution_unit) {
if (auto *persistent_state =
exe_ctx.GetTargetPtr()->GetPersistentExpressionStateForLanguage(
m_language))
m_language.AsLanguageType()))
persistent_state->RegisterExecutionUnit(m_execution_unit_sp);
}
}

View File

@ -106,8 +106,8 @@ public:
/// definitions to be included when the expression is parsed.
///
/// \param[in] language
/// If not eLanguageTypeUnknown, a language to use when parsing
/// the expression. Currently restricted to those languages
/// If not unknown, a language to use when parsing the
/// expression. Currently restricted to those languages
/// supported by Clang.
///
/// \param[in] desired_type
@ -122,7 +122,7 @@ public:
/// must be evaluated. For details see the comment to
/// `UserExpression::Evaluate`.
ClangUserExpression(ExecutionContextScope &exe_scope, llvm::StringRef expr,
llvm::StringRef prefix, lldb::LanguageType language,
llvm::StringRef prefix, SourceLanguage language,
ResultType desired_type,
const EvaluateExpressionOptions &options,
ValueObject *ctx_obj);

View File

@ -9596,7 +9596,7 @@ void ScratchTypeSystemClang::Dump(llvm::raw_ostream &output) {
}
UserExpression *ScratchTypeSystemClang::GetUserExpression(
llvm::StringRef expr, llvm::StringRef prefix, lldb::LanguageType language,
llvm::StringRef expr, llvm::StringRef prefix, SourceLanguage language,
Expression::ResultType desired_type,
const EvaluateExpressionOptions &options, ValueObject *ctx_obj) {
TargetSP target_sp = m_target_wp.lock();

View File

@ -1280,12 +1280,12 @@ public:
/// \see lldb_private::TypeSystem::Dump
void Dump(llvm::raw_ostream &output) override;
UserExpression *
GetUserExpression(llvm::StringRef expr, llvm::StringRef prefix,
lldb::LanguageType language,
Expression::ResultType desired_type,
const EvaluateExpressionOptions &options,
ValueObject *ctx_obj) override;
UserExpression *GetUserExpression(llvm::StringRef expr,
llvm::StringRef prefix,
SourceLanguage language,
Expression::ResultType desired_type,
const EvaluateExpressionOptions &options,
ValueObject *ctx_obj) override;
FunctionCaller *GetFunctionCaller(const CompilerType &return_type,
const Address &function_address,

View File

@ -19,6 +19,7 @@
#include "lldb/Target/Target.h"
#include "lldb/Utility/Stream.h"
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/Support/Threading.h"
using namespace lldb;
@ -532,3 +533,36 @@ Language::Language() = default;
// Destructor
Language::~Language() = default;
SourceLanguage::SourceLanguage(lldb::LanguageType language_type) {
auto lname =
llvm::dwarf::toDW_LNAME((llvm::dwarf::SourceLanguage)language_type);
if (!lname)
return;
name = lname->first;
version = lname->second;
}
lldb::LanguageType SourceLanguage::AsLanguageType() const {
if (auto lang = llvm::dwarf::toDW_LANG((llvm::dwarf::SourceLanguageName)name,
version))
return (lldb::LanguageType)*lang;
return lldb::eLanguageTypeUnknown;
}
llvm::StringRef SourceLanguage::GetDescription() const {
LanguageType type = AsLanguageType();
if (type)
return Language::GetNameForLanguageType(type);
return llvm::dwarf::LanguageDescription(
(llvm::dwarf::SourceLanguageName)name);
}
bool SourceLanguage::IsC() const { return name == llvm::dwarf::DW_LNAME_C; }
bool SourceLanguage::IsObjC() const {
return name == llvm::dwarf::DW_LNAME_ObjC;
}
bool SourceLanguage::IsCPlusPlus() const {
return name == llvm::dwarf::DW_LNAME_C_plus_plus;
}

View File

@ -1203,26 +1203,23 @@ bool StackFrame::IsArtificial() const {
return m_stack_frame_kind == StackFrame::Kind::Artificial;
}
lldb::LanguageType StackFrame::GetLanguage() {
SourceLanguage StackFrame::GetLanguage() {
CompileUnit *cu = GetSymbolContext(eSymbolContextCompUnit).comp_unit;
if (cu)
return cu->GetLanguage();
return lldb::eLanguageTypeUnknown;
return {};
}
lldb::LanguageType StackFrame::GuessLanguage() {
LanguageType lang_type = GetLanguage();
SourceLanguage StackFrame::GuessLanguage() {
SourceLanguage lang_type = GetLanguage();
if (lang_type == eLanguageTypeUnknown) {
SymbolContext sc = GetSymbolContext(eSymbolContextFunction
| eSymbolContextSymbol);
if (sc.function) {
lang_type = sc.function->GetMangled().GuessLanguage();
}
SymbolContext sc =
GetSymbolContext(eSymbolContextFunction | eSymbolContextSymbol);
if (sc.function)
lang_type = LanguageType(sc.function->GetMangled().GuessLanguage());
else if (sc.symbol)
{
lang_type = sc.symbol->GetMangled().GuessLanguage();
}
lang_type = SourceLanguage(sc.symbol->GetMangled().GuessLanguage());
}
return lang_type;
@ -1302,7 +1299,7 @@ GetBaseExplainingDereference(const Instruction::Operand &operand,
}
return std::make_pair(nullptr, 0);
}
}
} // namespace
lldb::ValueObjectSP StackFrame::GuessValueForAddress(lldb::addr_t addr) {
TargetSP target_sp = CalculateTarget();

View File

@ -504,7 +504,7 @@ BreakpointSP Target::CreateBreakpoint(
if (skip_prologue == eLazyBoolCalculate)
skip_prologue = GetSkipPrologue() ? eLazyBoolYes : eLazyBoolNo;
if (language == lldb::eLanguageTypeUnknown)
language = GetLanguage();
language = GetLanguage().AsLanguageType();
BreakpointResolverSP resolver_sp(new BreakpointResolverName(
nullptr, func_name, func_name_type_mask, language, Breakpoint::Exact,
@ -530,7 +530,7 @@ Target::CreateBreakpoint(const FileSpecList *containingModules,
if (skip_prologue == eLazyBoolCalculate)
skip_prologue = GetSkipPrologue() ? eLazyBoolYes : eLazyBoolNo;
if (language == lldb::eLanguageTypeUnknown)
language = GetLanguage();
language = GetLanguage().AsLanguageType();
BreakpointResolverSP resolver_sp(
new BreakpointResolverName(nullptr, func_names, func_name_type_mask,
@ -559,7 +559,7 @@ Target::CreateBreakpoint(const FileSpecList *containingModules,
skip_prologue = eLazyBoolNo;
}
if (language == lldb::eLanguageTypeUnknown)
language = GetLanguage();
language = GetLanguage().AsLanguageType();
BreakpointResolverSP resolver_sp(new BreakpointResolverName(
nullptr, func_names, num_names, func_name_type_mask, language, offset,
@ -2504,15 +2504,16 @@ Target::GetPersistentExpressionStateForLanguage(lldb::LanguageType language) {
}
UserExpression *Target::GetUserExpressionForLanguage(
llvm::StringRef expr, llvm::StringRef prefix, lldb::LanguageType language,
llvm::StringRef expr, llvm::StringRef prefix, SourceLanguage language,
Expression::ResultType desired_type,
const EvaluateExpressionOptions &options, ValueObject *ctx_obj,
Status &error) {
auto type_system_or_err = GetScratchTypeSystemForLanguage(language);
auto type_system_or_err =
GetScratchTypeSystemForLanguage(language.AsLanguageType());
if (auto err = type_system_or_err.takeError()) {
error.SetErrorStringWithFormat(
"Could not find type system for language %s: %s",
Language::GetNameForLanguageType(language),
Language::GetNameForLanguageType(language.AsLanguageType()),
llvm::toString(std::move(err)).c_str());
return nullptr;
}
@ -2521,7 +2522,7 @@ UserExpression *Target::GetUserExpressionForLanguage(
if (!ts) {
error.SetErrorStringWithFormat(
"Type system for language %s is no longer live",
Language::GetNameForLanguageType(language));
language.GetDescription().data());
return nullptr;
}
@ -2530,7 +2531,7 @@ UserExpression *Target::GetUserExpressionForLanguage(
if (!user_expr)
error.SetErrorStringWithFormat(
"Could not create an expression for language %s",
Language::GetNameForLanguageType(language));
language.GetDescription().data());
return user_expr;
}
@ -4646,9 +4647,9 @@ void TargetProperties::SetStandardErrorPath(llvm::StringRef path) {
SetPropertyAtIndex(idx, path);
}
LanguageType TargetProperties::GetLanguage() const {
SourceLanguage TargetProperties::GetLanguage() const {
const uint32_t idx = ePropertyLanguage;
return GetPropertyAtIndexAs<LanguageType>(idx, {});
return {GetPropertyAtIndexAs<LanguageType>(idx, {})};
}
llvm::StringRef TargetProperties::GetExpressionPrefixContents() {

View File

@ -239,6 +239,9 @@ if is_configured("llvm_tools_dir"):
if is_configured("server"):
dotest_cmd += ["--server", config.server]
if is_configured("lldb_obj_root"):
dotest_cmd += ["--lldb-obj-root", config.lldb_obj_root]
if is_configured("lldb_libs_dir"):
dotest_cmd += ["--lldb-libs-dir", config.lldb_libs_dir]

View File

@ -8,7 +8,7 @@ config.llvm_include_dir = lit_config.substitute("@LLVM_INCLUDE_DIR@")
config.llvm_shlib_dir = lit_config.substitute("@SHLIBDIR@")
config.llvm_build_mode = lit_config.substitute("@LLVM_BUILD_MODE@")
config.lit_tools_dir = "@LLVM_LIT_TOOLS_DIR@"
config.lldb_obj_root = "@LLDB_BINARY_DIR@"
config.lldb_obj_root = lit_config.substitute("@LLDB_BINARY_DIR@")
config.lldb_src_root = "@LLDB_SOURCE_DIR@"
config.lldb_libs_dir = lit_config.substitute("@LLDB_LIBS_DIR@")
config.lldb_framework_dir = lit_config.substitute("@LLDB_FRAMEWORK_DIR@")

View File

@ -10,6 +10,7 @@ if (NOT DEFINED LLDB_TABLEGEN_EXE)
add_tablegen(lldb-tblgen LLDB
LLDBOptionDefEmitter.cpp
LLDBPropertyDefEmitter.cpp
LLDBSBAPIDWARFEnum.cpp
LLDBTableGen.cpp
LLDBTableGenUtils.cpp
)

View File

@ -0,0 +1,67 @@
//===- LLDBPropertyDefEmitter.cpp -----------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// Produce the list of source languages header file fragment for the SBAPI.
//
//===----------------------------------------------------------------------===//
#include <fstream>
#include <llvm/ADT/StringRef.h>
#include <regex>
namespace lldb_private {
int EmitSBAPIDWARFEnum(int argc, char **argv) {
std::string InputFilename;
std::string OutputFilename;
std::string DepFilename;
// This command line option parser is as robust as the worst shell script.
for (int i = 0; i < argc; ++i) {
if (llvm::StringRef(argv[i]).ends_with("Dwarf.def"))
InputFilename = std::string(argv[i]);
if (llvm::StringRef(argv[i]) == "-o" && i + 1 < argc)
OutputFilename = std::string(argv[i + 1]);
if (llvm::StringRef(argv[i]) == "-d" && i + 1 < argc)
DepFilename = std::string(argv[i + 1]);
}
std::ifstream input(InputFilename);
std::ofstream output(OutputFilename);
output
<< R"(//===-- SBLanguages.h -----------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef LLDB_API_SBLANGUAGE_H
#define LLDB_API_SBLANGUAGE_H
/// Used by \ref SBExpressionOptions.
/// These enumerations use the same language enumerations as the DWARF
/// specification for ease of use and consistency.
enum SBSourceLanguageName : uint16_t {
)";
std::string line;
std::regex macro_regex(R"(^ *HANDLE_DW_LNAME *\( *([^,]+), ([^,]+), )"
"\"(.*)\",.*\\).*",
std::regex::extended);
while (std::getline(input, line)) {
std::smatch match;
if (!std::regex_match(line, match, macro_regex))
continue;
output << " /// " << match[3] << ".\n";
output << " eLanguageName" << match[2] << " = " << match[1] << ",\n";
}
output << "};\n\n";
output << "#endif\n";
// Emit the dependencies file.
std::ofstream(DepFilename) << OutputFilename << ": " << InputFilename << '\n';
return 0;
}
} // namespace lldb_private

View File

@ -27,6 +27,7 @@ enum ActionType {
GenOptionDefs,
GenPropertyDefs,
GenPropertyEnumDefs,
GenSBAPIDWARFEnum
};
static cl::opt<ActionType> Action(
@ -40,6 +41,8 @@ static cl::opt<ActionType> Action(
clEnumValN(GenPropertyDefs, "gen-lldb-property-defs",
"Generate lldb property definitions"),
clEnumValN(GenPropertyEnumDefs, "gen-lldb-property-enum-defs",
"Generate lldb property enum definitions"),
clEnumValN(GenSBAPIDWARFEnum, "gen-lldb-sbapi-dwarf-enum",
"Generate lldb property enum definitions")));
static bool LLDBTableGenMain(raw_ostream &OS, RecordKeeper &Records) {
@ -59,6 +62,8 @@ static bool LLDBTableGenMain(raw_ostream &OS, RecordKeeper &Records) {
case GenPropertyEnumDefs:
EmitPropertyEnumDefs(Records, OS);
break;
case GenSBAPIDWARFEnum:
llvm_unreachable("already handled");
}
return false;
}
@ -67,9 +72,11 @@ int main(int argc, char **argv) {
sys::PrintStackTraceOnErrorSignal(argv[0]);
PrettyStackTraceProgram X(argc, argv);
cl::ParseCommandLineOptions(argc, argv);
llvm_shutdown_obj Y;
if (Action == GenSBAPIDWARFEnum)
return EmitSBAPIDWARFEnum(argc, argv);
return TableGenMain(argv[0], &LLDBTableGenMain);
}

View File

@ -32,6 +32,7 @@ namespace lldb_private {
void EmitOptionDefs(RecordKeeper &RK, raw_ostream &OS);
void EmitPropertyDefs(RecordKeeper &RK, raw_ostream &OS);
void EmitPropertyEnumDefs(RecordKeeper &RK, raw_ostream &OS);
int EmitSBAPIDWARFEnum(int argc, char **argv);
} // namespace lldb_private