21#include "llvm/ADT/StringRef.h"
22#include "llvm/Support/FormatAdapters.h"
32 const std::string &
message, uint32_t loc,
34 : ErrorInfo(make_error_code(std::errc::invalid_argument)) {
36 FileSpec{}, 1,
static_cast<uint16_t
>(loc + 1),
37 err_len,
false,
true};
45 auto msg = llvm::formatv(
"<user expression>:1:{0}: {1}\n 1 | {2}\n |",
47 std::string rendered_str;
48 llvm::raw_string_ostream rendered_os(rendered_str);
49 rendered_os << msg.str();
50 rendered_os << llvm::indent(loc + 1) <<
"^";
53 rendered_os << std::string(err_len - 1,
'~');
58 m_detail.rendered = std::move(rendered_str);
65 llvm::StringRef name_ref(name);
67 if (name_ref.starts_with(
"::"))
68 name_ref = name_ref.drop_front(2);
70 std::vector<CompilerType> result_type_list;
72 if (!name_ref.empty() && target_sp) {
75 TypeQueryOptions::e_find_one};
77 images.
FindTypes(
nullptr, query, results);
80 result_type_list.push_back(type_sp->GetFullCompilerType());
83 if (!result_type_list.empty()) {
93 llvm::StringRef dil_input_expr,
97 llvm::Error
error = llvm::Error::success();
98 DILParser parser(exe_ctx, dil_input_expr, lexer, use_dynamic,
error, mode);
101 assert(node_up &&
"ASTNodeUP must not contain a nullptr");
105 "[DILParser::Parse] DIL parser failed:\n{0}",
106 llvm::toStringWithoutConsuming(
error));
156 assert(lhs &&
"ASTNodeUP must not contain a nullptr");
168 assert(rhs &&
"ASTNodeUP must not contain a nullptr");
169 lhs = std::make_unique<BinaryOpNode>(
171 std::move(lhs), std::move(rhs));
198 assert(lhs &&
"ASTNodeUP must not contain a nullptr");
207 assert(condition &&
"ASTNodeUP must not contain a nullptr");
212 assert(true_op &&
"ASTNodeUP must not contain a nullptr");
216 assert(false_op &&
"ASTNodeUP must not contain a nullptr");
217 return std::make_unique<ConditionalNode>(
218 token.
GetLocation(), std::move(condition), std::move(true_op),
219 std::move(false_op));
229 assert(lhs &&
"ASTNodeUP must not contain a nullptr");
235 assert(rhs &&
"ASTNodeUP must not contain a nullptr");
236 lhs = std::make_unique<BinaryOpNode>(
238 std::move(lhs), std::move(rhs));
251 assert(lhs &&
"ASTNodeUP must not contain a nullptr");
257 assert(rhs &&
"ASTNodeUP must not contain a nullptr");
258 lhs = std::make_unique<BinaryOpNode>(
260 std::move(lhs), std::move(rhs));
273 assert(lhs &&
"ASTNodeUP must not contain a nullptr");
279 assert(rhs &&
"ASTNodeUP must not contain a nullptr");
280 lhs = std::make_unique<BinaryOpNode>(
282 std::move(lhs), std::move(rhs));
295 assert(lhs &&
"ASTNodeUP must not contain a nullptr");
301 assert(rhs &&
"ASTNodeUP must not contain a nullptr");
302 lhs = std::make_unique<BinaryOpNode>(
304 std::move(lhs), std::move(rhs));
317 assert(lhs &&
"ASTNodeUP must not contain a nullptr");
322 BailOut(
"bitwise and (&) is allowed only in DIL full mode",
324 return std::make_unique<ErrorNode>();
328 assert(rhs &&
"ASTNodeUP must not contain a nullptr");
329 lhs = std::make_unique<BinaryOpNode>(
331 std::move(lhs), std::move(rhs));
345 assert(lhs &&
"ASTNodeUP must not contain a nullptr");
351 assert(rhs &&
"ASTNodeUP must not contain a nullptr");
352 lhs = std::make_unique<BinaryOpNode>(
354 std::move(lhs), std::move(rhs));
370 assert(lhs &&
"ASTNodeUP must not contain a nullptr");
377 assert(rhs &&
"ASTNodeUP must not contain a nullptr");
378 lhs = std::make_unique<BinaryOpNode>(
380 std::move(lhs), std::move(rhs));
394 assert(lhs &&
"ASTNodeUP must not contain a nullptr");
400 assert(rhs &&
"ASTNodeUP must not contain a nullptr");
401 lhs = std::make_unique<BinaryOpNode>(
403 std::move(lhs), std::move(rhs));
417 assert(lhs &&
"ASTNodeUP must not contain a nullptr");
423 assert(rhs &&
"ASTNodeUP must not contain a nullptr");
424 lhs = std::make_unique<BinaryOpNode>(
426 std::move(lhs), std::move(rhs));
445 BailOut(
"binary multiplication (*) is allowed only in DIL full mode",
447 return std::make_unique<ErrorNode>();
451 assert(rhs &&
"ASTNodeUP must not contain a nullptr");
452 lhs = std::make_unique<BinaryOpNode>(
454 std::move(lhs), std::move(rhs));
478 uint32_t save_token_idx =
m_dil_lexer.GetCurrentTokenIdx();
490 if (!type_id.value().IsValid())
491 return std::make_unique<ErrorNode>();
496 assert(rhs &&
"ASTNodeUP must not contain a nullptr");
497 return std::make_unique<CastNode>(loc, type_id.value(), std::move(rhs),
530 assert(rhs &&
"ASTNodeUP must not contain a nullptr");
551 BailOut(
"Decrement operator is not supported. Use `-=` instead.",
553 return std::make_unique<ErrorNode>();
555 BailOut(
"Increment operator is not supported. Use `+=` instead.",
557 return std::make_unique<ErrorNode>();
559 llvm_unreachable(
"invalid token kind");
576 assert(lhs &&
"ASTNodeUP must not contain a nullptr");
585 assert(index &&
"ASTNodeUP must not contain a nullptr");
589 assert(last_index &&
"ASTNodeUP must not contain a nullptr");
590 lhs = std::make_unique<BitFieldExtractionNode>(
591 loc, std::move(lhs), std::move(index), std::move(last_index));
593 BailOut(
"use of '-' for bitfield range is deprecated; use ':' instead",
595 return std::make_unique<ErrorNode>();
597 lhs = std::make_unique<ArraySubscriptNode>(loc, std::move(lhs),
609 lhs = std::make_unique<MemberOfNode>(
615 BailOut(
"Decrement operator is not supported. Use `-=` instead.",
617 return std::make_unique<ErrorNode>();
619 BailOut(
"Increment operator is not supported. Use `+=` instead.",
621 return std::make_unique<ErrorNode>();
623 llvm_unreachable(
"invalid token");
649 if (!identifier.empty()) {
652 uint32_t save_token_idx =
m_dil_lexer.GetCurrentTokenIdx();
657 return std::make_unique<SizeOfNode>(loc, *type_id);
663 return std::make_unique<SizeOfNode>(loc, std::move(expr));
665 return std::make_unique<IdentifierNode>(loc, identifier);
679 return std::make_unique<ErrorNode>();
703 (
m_dil_lexer.LookAhead(1).GetSpelling() ==
"anonymous") &&
705 (
m_dil_lexer.LookAhead(2).GetSpelling() ==
"namespace") &&
713 BailOut(
"Expected an identifier or anonymous namespace, but not found.",
719 return "(anonymous namespace)::" + identifier2;
759 if (maybe_builtin_type) {
760 type = *maybe_builtin_type;
764 std::string type_name;
767 if (type_name.empty())
788 std::vector<Token> ptr_operators;
791 ptr_operators.push_back(std::move(tok));
810 std::string type_name =
"";
811 uint32_t save_token_idx =
m_dil_lexer.GetCurrentTokenIdx();
812 bool first_word =
true;
814 if (
CurToken().GetSpelling() ==
"const" ||
815 CurToken().GetSpelling() ==
"volatile") {
820 type_name.push_back(
' ');
823 type_name.append(
CurToken().GetSpelling());
827 if (type_name.size() > 0) {
832 for (
auto type_system_sp : target_sp->GetScratchTypeSystems())
833 if (
auto compiler_type =
834 type_system_sp->GetBuiltinTypeByName(const_type_name))
835 return compiler_type;
852 type_name = *err_or_string;
868 bool global_scope =
false;
879 if (!type_name_or_err)
880 return type_name_or_err;
881 std::string type_name = *type_name_or_err;
886 if (!type_name.empty())
888 return llvm::formatv(
"{0}{1}{2}", global_scope ?
"::" :
"",
889 nested_name_specifier, type_name);
939 bool global_scope =
false;
950 if (!nested_name_specifier.empty()) {
954 return llvm::formatv(
"{0}{1}{2}", global_scope ?
"::" :
"",
955 nested_name_specifier, unqualified_id);
967 return llvm::formatv(
"{0}{1}", global_scope ?
"::" :
"", identifier);
991 const std::vector<Token> &ptr_operators) {
993 for (
Token tk : ptr_operators) {
994 uint32_t loc = tk.GetLocation();
998 BailOut(llvm::formatv(
"'type name' declared as a pointer to a "
999 "reference of type {0}",
1001 loc,
CurToken().GetSpelling().length());
1011 BailOut(
"type name declared as a reference to a reference", loc,
1012 CurToken().GetSpelling().length());
1034 return std::make_unique<BooleanLiteralNode>(loc, literal_value);
1063 BailOut(llvm::formatv(
"Failed to parse token as numeric-constant: {0}",
1066 return numeric_constant;
1069 return numeric_constant;
1075 llvm::StringRef spelling_ref = spelling;
1077 auto radix = llvm::getAutoSenseRadix(spelling_ref);
1079 bool is_unsigned =
false;
1080 if (spelling_ref.consume_back_insensitive(
"u"))
1082 if (spelling_ref.consume_back_insensitive(
"ll"))
1084 else if (spelling_ref.consume_back_insensitive(
"l"))
1087 if (!is_unsigned && spelling_ref.consume_back_insensitive(
"u"))
1090 llvm::APInt raw_value;
1091 if (!spelling_ref.getAsInteger(radix, raw_value))
1092 return std::make_unique<IntegerLiteralNode>(token.
GetLocation(), raw_value,
1093 radix, is_unsigned, type);
1094 return std::make_unique<ErrorNode>();
1100 llvm::StringRef spelling_ref = spelling;
1102 llvm::APFloat raw_float(llvm::APFloat::IEEEdouble());
1103 if (spelling_ref.consume_back_insensitive(
"f"))
1104 raw_float = llvm::APFloat(llvm::APFloat::IEEEsingle());
1106 auto StatusOrErr = raw_float.convertFromString(
1107 spelling_ref, llvm::APFloat::rmNearestTiesToEven);
1108 if (!errorToBool(StatusOrErr.takeError()))
1109 return std::make_unique<FloatLiteralNode>(token.
GetLocation(), raw_float);
1110 return std::make_unique<ErrorNode>();
1115 BailOut(
"Assignment is allowed only at top level.",
1125 if (!
CurToken().IsOneOf(kinds_vec)) {
1126 BailOut(llvm::formatv(
"expected any of ({0}), got: {1}",
1127 llvm::iterator_range(kinds_vec),
CurToken()),
static llvm::raw_ostream & error(Stream &strm)
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
uint32_t GetKind(uint32_t data)
Return the type kind encoded in the given data.
Generic representation of a type in a programming language.
CompilerType GetPointerType() const
Return a new CompilerType that is a pointer to this type.
CompilerType GetLValueReferenceType() const
Return a new CompilerType that is a L value reference to this type if this type is valid and the type...
ConstString GetTypeName(bool BaseOnly=false) const
bool IsReferenceType(CompilerType *pointee_type=nullptr, bool *is_rvalue=nullptr) const
std::string TypeDescription()
A uniqued constant string class.
llvm::StringRef GetStringRef() const
Get the string value as a llvm::StringRef.
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
const lldb::TargetSP & GetTargetSP() const
Get accessor to get the target shared pointer.
A collection class for Module objects.
void FindTypes(Module *search_first, const TypeQuery &query, lldb_private::TypeResults &results) const
Find types using a type-matching object that contains all search parameters.
A class that contains all state required for type lookups.
This class tracks the state and results of a TypeQuery.
lldb::TypeSP GetFirstType() const
DILDiagnosticError(DiagnosticDetail detail)
std::string message() const override
DiagnosticDetail m_detail
Class for doing the simple lexing required by DIL.
ASTNodeUP ParseAdditiveExpression()
ASTNodeUP ParseInclusiveOrExpression()
ASTNodeUP ParseUnaryExpression()
ASTNodeUP ParseLogicalOrExpression()
ASTNodeUP ParseConditionalBranches(ASTNodeUP condition)
void ParseTypeSpecifierSeq(std::string &type_name)
ASTNodeUP ParseIntegerLiteral()
void Expect(Token::Kind kind)
std::optional< CompilerType > ParseTypeId()
void TentativeParsingRollback(uint32_t saved_idx)
ASTNodeUP ParseLogicalAndExpression()
ASTNodeUP ParseEqualityExpression()
ASTNodeUP ParseFloatingPointLiteral()
ASTNodeUP ParseExpression()
ASTNodeUP ParseAndExpression()
void ExpectOneOf(std::vector< Token::Kind > kinds_vec)
std::optional< std::string > ParseTypeSpecifier()
ASTNodeUP ParseRelationalExpression()
DILParser(ExecutionContext &exe_ctx, llvm::StringRef dil_input_expr, DILLexer lexer, lldb::DynamicValueType use_dynamic, llvm::Error &error, lldb::DILMode mode)
ASTNodeUP ParsePureExpression()
ASTNodeUP ParseNumericLiteral()
static llvm::Expected< ASTNodeUP > Parse(ExecutionContext &exe_ctx, llvm::StringRef dil_input_expr, DILLexer lexer, lldb::DynamicValueType use_dynamic, lldb::DILMode mode)
Parse the lexed tokens.
ASTNodeUP ParseAssignmentExpression()
ExecutionContext m_exe_ctx
std::optional< CompilerType > ParseBuiltinType()
ASTNodeUP ParsePrimaryExpression()
void BailOut(const std::string &error, uint32_t loc, uint16_t err_len)
CompilerType ResolveTypeDeclarators(CompilerType type, const std::vector< Token > &ptr_operators)
ASTNodeUP ParsePostfixExpression()
std::string ParseIdExpression()
ASTNodeUP ParseMultiplicativeExpression()
lldb::DynamicValueType m_use_dynamic
std::string ParseUnqualifiedId()
ASTNodeUP ParseCastExpression()
ASTNodeUP ParseBooleanLiteral()
std::optional< std::string > ParseTypeName()
llvm::StringRef m_input_expr
ASTNodeUP ParseConditionalExpression()
std::string ParseNestedNameSpecifier()
ASTNodeUP ParseExclusiveOrExpression()
ASTNodeUP ParseShiftExpression()
Class defining the tokens generated by the DIL lexer and used by the DIL parser.
uint32_t GetLocation() const
std::string GetSpelling() const
@ eNone
Invalid promotion type (results in error).
std::unique_ptr< ASTNode > ASTNodeUP
BinaryOpKind GetBinaryOpKindFromToken(Token::Kind token_kind)
Translates DIL tokens to BinaryOpKind.
lldb::ValueObjectSP LookupGlobalIdentifier(llvm::StringRef name_ref, ExecutionContext &exe_ctx, lldb::DynamicValueType use_dynamic)
Given the name of an identifier, check to see if it matches the name of a global variable.
lldb::ValueObjectSP LookupIdentifier(llvm::StringRef name_ref, ExecutionContext &exe_ctx, lldb::DynamicValueType use_dynamic)
Given the name of an identifier (variable name, member name, type name, etc.), find the ValueObject f...
CompilerType ResolveTypeByName(const std::string &name, ExecutionContext &exe_ctx)
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
std::shared_ptr< lldb_private::Type > TypeSP
std::shared_ptr< lldb_private::Target > TargetSP
DILMode
Data Inspection Language (DIL) evaluation modes.
@ eDILModeFull
Allowed: everything supported by DIL.
A source location consisting of a file name and position.