Skip to content

Commit e9b2e98

Browse files
committed
Add a new SBExpressionOptions::SetLanguage() API (NFCI)
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.
1 parent 300340f commit e9b2e98

35 files changed

+298
-121
lines changed

lldb/include/lldb/API/SBExpressionOptions.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#define LLDB_API_SBEXPRESSIONOPTIONS_H
1111

1212
#include "lldb/API/SBDefines.h"
13+
#include "lldb/API/SBLanguages.h"
1314

1415
#include <vector>
1516

@@ -67,6 +68,10 @@ class LLDB_API SBExpressionOptions {
6768
void SetTrapExceptions(bool trap_exceptions = true);
6869

6970
void SetLanguage(lldb::LanguageType language);
71+
/// Set the language using a pair of language code and version as
72+
/// defined by the DWARF 6 specification.
73+
/// WARNING: These codes may change until DWARF 6 is finalized.
74+
void SetLanguage(SBSourceLanguageName name, uint32_t version);
7075

7176
#ifndef SWIG
7277
void SetCancelCallback(lldb::ExpressionCancelCallback callback, void *baton);

lldb/include/lldb/Expression/Expression.h

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,8 @@ class Expression {
4747
/// expression. Text() should contain the definition of this function.
4848
virtual const char *FunctionName() = 0;
4949

50-
/// Return the language that should be used when parsing. To use the
51-
/// default, return eLanguageTypeUnknown.
52-
virtual lldb::LanguageType Language() const {
53-
return lldb::eLanguageTypeUnknown;
54-
}
50+
/// Return the language that should be used when parsing.
51+
virtual SourceLanguage Language() const { return {}; }
5552

5653
/// Return the Materializer that the parser should use when registering
5754
/// external values.

lldb/include/lldb/Expression/LLVMUserExpression.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ class LLVMUserExpression : public UserExpression {
5252
};
5353

5454
LLVMUserExpression(ExecutionContextScope &exe_scope, llvm::StringRef expr,
55-
llvm::StringRef prefix, lldb::LanguageType language,
55+
llvm::StringRef prefix, SourceLanguage language,
5656
ResultType desired_type,
5757
const EvaluateExpressionOptions &options);
5858
~LLVMUserExpression() override;

lldb/include/lldb/Expression/UserExpression.h

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ class UserExpression : public Expression {
5656
/// If not eResultTypeAny, the type to use for the expression
5757
/// result.
5858
UserExpression(ExecutionContextScope &exe_scope, llvm::StringRef expr,
59-
llvm::StringRef prefix, lldb::LanguageType language,
59+
llvm::StringRef prefix, SourceLanguage language,
6060
ResultType desired_type,
6161
const EvaluateExpressionOptions &options);
6262

@@ -202,7 +202,7 @@ class UserExpression : public Expression {
202202
virtual bool IsParseCacheable() { return true; }
203203
/// Return the language that should be used when parsing. To use the
204204
/// default, return eLanguageTypeUnknown.
205-
lldb::LanguageType Language() const override { return m_language; }
205+
SourceLanguage Language() const override { return m_language; }
206206

207207
/// Return the desired result type of the function, or eResultTypeAny if
208208
/// indifferent.
@@ -315,19 +315,22 @@ class UserExpression : public Expression {
315315
lldb::ProcessSP &process_sp,
316316
lldb::StackFrameSP &frame_sp);
317317

318-
Address m_address; ///< The address the process is stopped in.
319-
std::string m_expr_text; ///< The text of the expression, as typed by the user
320-
std::string m_expr_prefix; ///< The text of the translation-level definitions,
321-
///as provided by the user
322-
std::string m_fixed_text; ///< The text of the expression with fix-its applied
323-
///- this won't be set if the fixed text doesn't
324-
///parse.
325-
lldb::LanguageType m_language; ///< The language to use when parsing
326-
///(eLanguageTypeUnknown means use defaults)
327-
ResultType m_desired_type; ///< The type to coerce the expression's result to.
328-
///If eResultTypeAny, inferred from the expression.
329-
EvaluateExpressionOptions
330-
m_options; ///< Additional options provided by the user.
318+
/// The address the process is stopped in.
319+
Address m_address;
320+
/// The text of the expression, as typed by the user.
321+
std::string m_expr_text;
322+
/// The text of the translation-level definitions, as provided by the user.
323+
std::string m_expr_prefix;
324+
/// The text of the expression with fix-its applied this won't be set if the
325+
/// fixed text doesn't parse.
326+
std::string m_fixed_text;
327+
/// The language to use when parsing (unknown means use defaults).
328+
SourceLanguage m_language;
329+
/// The type to coerce the expression's result to. If eResultTypeAny, inferred
330+
/// from the expression.
331+
ResultType m_desired_type;
332+
/// Additional options provided by the user.
333+
EvaluateExpressionOptions m_options;
331334
};
332335

333336
} // namespace lldb_private

lldb/include/lldb/Symbol/TypeSystem.h

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -483,12 +483,10 @@ class TypeSystem : public PluginInterface,
483483
return IsPointerOrReferenceType(type, nullptr);
484484
}
485485

486-
virtual UserExpression *
487-
GetUserExpression(llvm::StringRef expr, llvm::StringRef prefix,
488-
lldb::LanguageType language,
489-
Expression::ResultType desired_type,
490-
const EvaluateExpressionOptions &options,
491-
ValueObject *ctx_obj) {
486+
virtual UserExpression *GetUserExpression(
487+
llvm::StringRef expr, llvm::StringRef prefix, SourceLanguage language,
488+
Expression::ResultType desired_type,
489+
const EvaluateExpressionOptions &options, ValueObject *ctx_obj) {
492490
return nullptr;
493491
}
494492

lldb/include/lldb/Target/StackFrame.h

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -446,13 +446,12 @@ class StackFrame : public ExecutionContextScope,
446446
/// Query this frame to determine what the default language should be when
447447
/// parsing expressions given the execution context.
448448
///
449-
/// \return
450-
/// The language of the frame if known, else lldb::eLanguageTypeUnknown.
451-
lldb::LanguageType GetLanguage();
449+
/// \return The language of the frame if known.
450+
SourceLanguage GetLanguage();
452451

453-
// similar to GetLanguage(), but is allowed to take a potentially incorrect
454-
// guess if exact information is not available
455-
lldb::LanguageType GuessLanguage();
452+
/// Similar to GetLanguage(), but is allowed to take a potentially incorrect
453+
/// guess if exact information is not available
454+
SourceLanguage GuessLanguage();
456455

457456
/// Attempt to econstruct the ValueObject for a given raw address touched by
458457
/// the current instruction. The ExpressionPath should indicate how to get

lldb/include/lldb/Target/Target.h

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ class TargetProperties : public Properties {
200200

201201
bool GetBreakpointsConsultPlatformAvoidList();
202202

203-
lldb::LanguageType GetLanguage() const;
203+
SourceLanguage GetLanguage() const;
204204

205205
llvm::StringRef GetExpressionPrefixContents();
206206

@@ -310,9 +310,18 @@ class EvaluateExpressionOptions {
310310
m_execution_policy = policy;
311311
}
312312

313-
lldb::LanguageType GetLanguage() const { return m_language; }
313+
SourceLanguage GetLanguage() const { return m_language; }
314314

315-
void SetLanguage(lldb::LanguageType language) { m_language = language; }
315+
void SetLanguage(lldb::LanguageType language_type) {
316+
m_language = SourceLanguage(language_type);
317+
}
318+
319+
/// Set the language using a pair of language code and version as
320+
/// defined by the DWARF 6 specification.
321+
/// WARNING: These codes may change until DWARF 6 is finalized.
322+
void SetLanguage(uint16_t name, uint32_t version) {
323+
m_language = SourceLanguage(name, version);
324+
}
316325

317326
bool DoesCoerceToId() const { return m_coerce_to_id; }
318327

@@ -445,7 +454,7 @@ class EvaluateExpressionOptions {
445454

446455
private:
447456
ExecutionPolicy m_execution_policy = default_execution_policy;
448-
lldb::LanguageType m_language = lldb::eLanguageTypeUnknown;
457+
SourceLanguage m_language;
449458
std::string m_prefix;
450459
bool m_coerce_to_id = false;
451460
bool m_unwind_on_error = true;
@@ -1160,7 +1169,7 @@ class Target : public std::enable_shared_from_this<Target>,
11601169

11611170
UserExpression *
11621171
GetUserExpressionForLanguage(llvm::StringRef expr, llvm::StringRef prefix,
1163-
lldb::LanguageType language,
1172+
SourceLanguage language,
11641173
Expression::ResultType desired_type,
11651174
const EvaluateExpressionOptions &options,
11661175
ValueObject *ctx_obj, Status &error);

lldb/include/lldb/lldb-private-types.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,25 @@ struct RegisterSet {
9696
const uint32_t *registers;
9797
};
9898

99+
/// A type-erased pair of llvm::dwarf::SourceLanguageName and version.
100+
struct SourceLanguage {
101+
SourceLanguage() = default;
102+
SourceLanguage(lldb::LanguageType language_type);
103+
SourceLanguage(uint16_t name, uint32_t version)
104+
: name(name), version(version) {}
105+
SourceLanguage(std::optional<std::pair<uint32_t, uint16_t>> name_vers)
106+
: name(name_vers ? name_vers->first : 0),
107+
version(name_vers ? name_vers->second : 0) {}
108+
operator bool() const { return name > 0; }
109+
lldb::LanguageType AsLanguageType() const;
110+
llvm::StringRef GetDescription() const;
111+
bool IsC() const;
112+
bool IsObjC() const;
113+
bool IsCPlusPlus() const;
114+
uint16_t name = 0;
115+
uint32_t version = 0;
116+
};
117+
99118
struct OptionEnumValueElement {
100119
int64_t value;
101120
const char *string_value;

lldb/packages/Python/lldbsuite/test/configuration.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@
119119

120120
# LLDB library directory.
121121
lldb_libs_dir = None
122+
lldb_built_include_dir = None
122123

123124
libcxx_include_dir = None
124125
libcxx_include_target_dir = None

lldb/packages/Python/lldbsuite/test/dotest.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,7 @@ def parseOptionsAndInitTestdirs():
423423
configuration.lldb_module_cache_dir = os.path.join(
424424
configuration.test_build_dir, "module-cache-lldb"
425425
)
426+
426427
if args.clang_module_cache_dir:
427428
configuration.clang_module_cache_dir = args.clang_module_cache_dir
428429
else:
@@ -432,6 +433,8 @@ def parseOptionsAndInitTestdirs():
432433

433434
if args.lldb_libs_dir:
434435
configuration.lldb_libs_dir = args.lldb_libs_dir
436+
if args.lldb_built_include_dir:
437+
configuration.lldb_built_include_dir = args.lldb_built_include_dir
435438

436439
if args.enabled_plugins:
437440
configuration.enabled_plugins = args.enabled_plugins

lldb/packages/Python/lldbsuite/test/dotest_args.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,12 @@ def create_parser():
236236
metavar="The clang module cache directory used by Clang",
237237
help="The clang module cache directory used in the Make files by Clang while building tests. Defaults to <test build directory>/module-cache-clang.",
238238
)
239+
group.add_argument(
240+
"--lldb-built-include-dir",
241+
dest="lldb_built_include_dir",
242+
metavar="path",
243+
help="The path to LLDB built includes directory (containing languages.h)",
244+
)
239245
group.add_argument(
240246
"--lldb-libs-dir",
241247
dest="lldb_libs_dir",

lldb/packages/Python/lldbsuite/test/lldbtest.py

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1473,23 +1473,25 @@ def buildDriver(self, sources, exe_name):
14731473
d = {
14741474
"CXX_SOURCES": sources,
14751475
"EXE": exe_name,
1476-
"CFLAGS_EXTRAS": "%s %s -I%s"
1476+
"CFLAGS_EXTRAS": "%s %s -I%s -I%s"
14771477
% (
14781478
stdflag,
14791479
stdlibflag,
14801480
os.path.join(os.environ["LLDB_SRC"], "include"),
1481+
configuration.lldb_built_include_dir,
14811482
),
14821483
"LD_EXTRAS": "-L%s -lliblldb" % lib_dir,
14831484
}
14841485
else:
14851486
d = {
14861487
"CXX_SOURCES": sources,
14871488
"EXE": exe_name,
1488-
"CFLAGS_EXTRAS": "%s %s -I%s"
1489+
"CFLAGS_EXTRAS": "%s %s -I%s -I%s"
14891490
% (
14901491
stdflag,
14911492
stdlibflag,
14921493
os.path.join(os.environ["LLDB_SRC"], "include"),
1494+
configuration.lldb_built_include_dir,
14931495
),
14941496
"LD_EXTRAS": "-L%s -llldb -Wl,-rpath,%s" % (lib_dir, lib_dir),
14951497
}
@@ -1508,7 +1510,8 @@ def buildLibrary(self, sources, lib_name):
15081510
d = {
15091511
"DYLIB_CXX_SOURCES": sources,
15101512
"DYLIB_NAME": lib_name,
1511-
"CFLAGS_EXTRAS": "%s -stdlib=libc++" % stdflag,
1513+
"CFLAGS_EXTRAS": "%s -stdlib=libc++ -I%s" %
1514+
(stdflag, configuration.lldb_built_include_dir),
15121515
"FRAMEWORK_INCLUDES": "-F%s" % self.framework_dir,
15131516
"LD_EXTRAS": "%s -Wl,-rpath,%s -dynamiclib"
15141517
% (self.lib_lldb, self.framework_dir),
@@ -1517,16 +1520,18 @@ def buildLibrary(self, sources, lib_name):
15171520
d = {
15181521
"DYLIB_CXX_SOURCES": sources,
15191522
"DYLIB_NAME": lib_name,
1520-
"CFLAGS_EXTRAS": "%s -I%s "
1521-
% (stdflag, os.path.join(os.environ["LLDB_SRC"], "include")),
1523+
"CFLAGS_EXTRAS": "%s -I%s -I%s"
1524+
% (stdflag, os.path.join(os.environ["LLDB_SRC"], "include"),
1525+
configuration.lldb_built_include_dir),
15221526
"LD_EXTRAS": "-shared -l%s\liblldb.lib" % lib_dir,
15231527
}
15241528
else:
15251529
d = {
15261530
"DYLIB_CXX_SOURCES": sources,
15271531
"DYLIB_NAME": lib_name,
1528-
"CFLAGS_EXTRAS": "%s -I%s -fPIC"
1529-
% (stdflag, os.path.join(os.environ["LLDB_SRC"], "include")),
1532+
"CFLAGS_EXTRAS": "%s -I%s -I%s -fPIC"
1533+
% (stdflag, os.path.join(os.environ["LLDB_SRC"], "include"),
1534+
configuration.lldb_built_include_dir),
15301535
"LD_EXTRAS": "-shared -L%s -llldb -Wl,-rpath,%s" % (lib_dir, lib_dir),
15311536
}
15321537
if self.TraceOn():

lldb/source/API/CMakeLists.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ if(LLDB_ENABLE_LUA)
2020
set(lldb_lua_wrapper ${lua_bindings_dir}/LLDBWrapLua.cpp)
2121
endif()
2222

23+
lldb_tablegen(../../include/lldb/API/SBLanguages.h -gen-lldb-sbapi-dwarf-enum
24+
SOURCE ${LLVM_MAIN_INCLUDE_DIR}/llvm/BinaryFormat/Dwarf.def
25+
TARGET lldb-sbapi-dwarf-enums)
26+
2327
add_lldb_library(liblldb SHARED ${option_framework}
2428
SBAddress.cpp
2529
SBAttachInfo.cpp
@@ -100,6 +104,9 @@ add_lldb_library(liblldb SHARED ${option_framework}
100104
${lldb_python_wrapper}
101105
${lldb_lua_wrapper}
102106

107+
DEPENDS
108+
lldb-sbapi-dwarf-enums
109+
103110
LINK_LIBS
104111
lldbBreakpoint
105112
lldbCore

lldb/source/API/SBExpressionOptions.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,13 @@ void SBExpressionOptions::SetLanguage(lldb::LanguageType language) {
156156
m_opaque_up->SetLanguage(language);
157157
}
158158

159+
void SBExpressionOptions::SetLanguage(SBSourceLanguageName name,
160+
uint32_t version) {
161+
LLDB_INSTRUMENT_VA(this, name, version);
162+
163+
m_opaque_up->SetLanguage(name, version);
164+
}
165+
159166
void SBExpressionOptions::SetCancelCallback(
160167
lldb::ExpressionCancelCallback callback, void *baton) {
161168
LLDB_INSTRUMENT_VA(this, callback, baton);

lldb/source/API/SBFrame.cpp

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1024,10 +1024,10 @@ SBValue SBFrame::EvaluateExpression(const char *expr) {
10241024
options.SetFetchDynamicValue(fetch_dynamic_value);
10251025
options.SetUnwindOnError(true);
10261026
options.SetIgnoreBreakpoints(true);
1027-
if (target->GetLanguage() != eLanguageTypeUnknown)
1028-
options.SetLanguage(target->GetLanguage());
1029-
else
1030-
options.SetLanguage(frame->GetLanguage());
1027+
SourceLanguage language = target->GetLanguage();
1028+
if (!language)
1029+
language = frame->GetLanguage();
1030+
options.SetLanguage((SBSourceLanguageName)language.name, language.version);
10311031
return EvaluateExpression(expr, options);
10321032
} else {
10331033
Status error;
@@ -1053,10 +1053,12 @@ SBFrame::EvaluateExpression(const char *expr,
10531053

10541054
StackFrame *frame = exe_ctx.GetFramePtr();
10551055
Target *target = exe_ctx.GetTargetPtr();
1056-
if (target && target->GetLanguage() != eLanguageTypeUnknown)
1057-
options.SetLanguage(target->GetLanguage());
1058-
else if (frame)
1059-
options.SetLanguage(frame->GetLanguage());
1056+
SourceLanguage language;
1057+
if (target)
1058+
language = target->GetLanguage();
1059+
if (!language && frame)
1060+
language = frame->GetLanguage();
1061+
options.SetLanguage((SBSourceLanguageName)language.name, language.version);
10601062
return EvaluateExpression(expr, options);
10611063
}
10621064

@@ -1074,10 +1076,12 @@ SBValue SBFrame::EvaluateExpression(const char *expr,
10741076
options.SetIgnoreBreakpoints(true);
10751077
StackFrame *frame = exe_ctx.GetFramePtr();
10761078
Target *target = exe_ctx.GetTargetPtr();
1077-
if (target && target->GetLanguage() != eLanguageTypeUnknown)
1078-
options.SetLanguage(target->GetLanguage());
1079-
else if (frame)
1080-
options.SetLanguage(frame->GetLanguage());
1079+
SourceLanguage language;
1080+
if (target)
1081+
language = target->GetLanguage();
1082+
if (!language && frame)
1083+
language = frame->GetLanguage();
1084+
options.SetLanguage((SBSourceLanguageName)language.name, language.version);
10811085
return EvaluateExpression(expr, options);
10821086
}
10831087

@@ -1218,7 +1222,7 @@ lldb::LanguageType SBFrame::GuessLanguage() const {
12181222
if (stop_locker.TryLock(&process->GetRunLock())) {
12191223
frame = exe_ctx.GetFramePtr();
12201224
if (frame) {
1221-
return frame->GuessLanguage();
1225+
return frame->GuessLanguage().AsLanguageType();
12221226
}
12231227
}
12241228
}

0 commit comments

Comments
 (0)