22#include "llvm/ADT/StringRef.h"
23#include "llvm/Support/FormatAdapters.h"
33 const std::string &
message, uint32_t loc,
35 : ErrorInfo(make_error_code(std::errc::invalid_argument)) {
37 FileSpec{}, 1,
static_cast<uint16_t
>(loc + 1),
38 err_len,
false,
true};
46 auto msg = llvm::formatv(
"<user expression>:1:{0}: {1}\n 1 | {2}\n |",
48 std::string rendered_str;
49 llvm::raw_string_ostream rendered_os(rendered_str);
50 rendered_os << msg.str();
51 rendered_os << llvm::indent(loc + 1) <<
"^";
54 rendered_os << std::string(err_len - 1,
'~');
59 m_detail.rendered = std::move(rendered_str);
66 llvm::StringRef name_ref(name);
68 if (name_ref.starts_with(
"::"))
69 name_ref = name_ref.drop_front(2);
71 std::vector<CompilerType> result_type_list;
73 if (!name_ref.empty() && target_sp) {
76 TypeQueryOptions::e_find_one};
78 images.
FindTypes(
nullptr, query, results);
81 result_type_list.push_back(type_sp->GetFullCompilerType());
84 if (!result_type_list.empty()) {
98 llvm::Error
error = llvm::Error::success();
99 DILParser parser(dil_input_expr, lexer, stack_frame, use_dynamic,
error,
103 assert(node_up &&
"ASTNodeUP must not contain a nullptr");
152 assert(lhs &&
"ASTNodeUP must not contain a nullptr");
164 assert(rhs &&
"ASTNodeUP must not contain a nullptr");
165 lhs = std::make_unique<BinaryOpNode>(
167 std::move(lhs), std::move(rhs));
194 assert(lhs &&
"ASTNodeUP must not contain a nullptr");
203 assert(condition &&
"ASTNodeUP must not contain a nullptr");
208 assert(true_op &&
"ASTNodeUP must not contain a nullptr");
212 assert(false_op &&
"ASTNodeUP must not contain a nullptr");
213 return std::make_unique<ConditionalNode>(
214 token.
GetLocation(), std::move(condition), std::move(true_op),
215 std::move(false_op));
225 assert(lhs &&
"ASTNodeUP must not contain a nullptr");
231 assert(rhs &&
"ASTNodeUP must not contain a nullptr");
232 lhs = std::make_unique<BinaryOpNode>(
234 std::move(lhs), std::move(rhs));
247 assert(lhs &&
"ASTNodeUP must not contain a nullptr");
253 assert(rhs &&
"ASTNodeUP must not contain a nullptr");
254 lhs = std::make_unique<BinaryOpNode>(
256 std::move(lhs), std::move(rhs));
269 assert(lhs &&
"ASTNodeUP must not contain a nullptr");
275 assert(rhs &&
"ASTNodeUP must not contain a nullptr");
276 lhs = std::make_unique<BinaryOpNode>(
278 std::move(lhs), std::move(rhs));
291 assert(lhs &&
"ASTNodeUP must not contain a nullptr");
297 assert(rhs &&
"ASTNodeUP must not contain a nullptr");
298 lhs = std::make_unique<BinaryOpNode>(
300 std::move(lhs), std::move(rhs));
313 assert(lhs &&
"ASTNodeUP must not contain a nullptr");
318 BailOut(
"bitwise and (&) is allowed only in DIL full mode",
320 return std::make_unique<ErrorNode>();
324 assert(rhs &&
"ASTNodeUP must not contain a nullptr");
325 lhs = std::make_unique<BinaryOpNode>(
327 std::move(lhs), std::move(rhs));
341 assert(lhs &&
"ASTNodeUP must not contain a nullptr");
347 assert(rhs &&
"ASTNodeUP must not contain a nullptr");
348 lhs = std::make_unique<BinaryOpNode>(
350 std::move(lhs), std::move(rhs));
366 assert(lhs &&
"ASTNodeUP must not contain a nullptr");
373 assert(rhs &&
"ASTNodeUP must not contain a nullptr");
374 lhs = std::make_unique<BinaryOpNode>(
376 std::move(lhs), std::move(rhs));
390 assert(lhs &&
"ASTNodeUP must not contain a nullptr");
396 assert(rhs &&
"ASTNodeUP must not contain a nullptr");
397 lhs = std::make_unique<BinaryOpNode>(
399 std::move(lhs), std::move(rhs));
413 assert(lhs &&
"ASTNodeUP must not contain a nullptr");
419 assert(rhs &&
"ASTNodeUP must not contain a nullptr");
420 lhs = std::make_unique<BinaryOpNode>(
422 std::move(lhs), std::move(rhs));
441 BailOut(
"binary multiplication (*) is allowed only in DIL full mode",
443 return std::make_unique<ErrorNode>();
447 assert(rhs &&
"ASTNodeUP must not contain a nullptr");
448 lhs = std::make_unique<BinaryOpNode>(
450 std::move(lhs), std::move(rhs));
474 uint32_t save_token_idx =
m_dil_lexer.GetCurrentTokenIdx();
486 if (!type_id.value().IsValid())
487 return std::make_unique<ErrorNode>();
492 assert(rhs &&
"ASTNodeUP must not contain a nullptr");
493 return std::make_unique<CastNode>(loc, type_id.value(), std::move(rhs),
526 assert(rhs &&
"ASTNodeUP must not contain a nullptr");
547 BailOut(
"Decrement operator is not supported. Use `-=` instead.",
549 return std::make_unique<ErrorNode>();
551 BailOut(
"Increment operator is not supported. Use `+=` instead.",
553 return std::make_unique<ErrorNode>();
555 llvm_unreachable(
"invalid token kind");
572 assert(lhs &&
"ASTNodeUP must not contain a nullptr");
581 assert(index &&
"ASTNodeUP must not contain a nullptr");
585 assert(last_index &&
"ASTNodeUP must not contain a nullptr");
586 lhs = std::make_unique<BitFieldExtractionNode>(
587 loc, std::move(lhs), std::move(index), std::move(last_index));
589 BailOut(
"use of '-' for bitfield range is deprecated; use ':' instead",
591 return std::make_unique<ErrorNode>();
593 lhs = std::make_unique<ArraySubscriptNode>(loc, std::move(lhs),
605 lhs = std::make_unique<MemberOfNode>(
611 BailOut(
"Decrement operator is not supported. Use `-=` instead.",
613 return std::make_unique<ErrorNode>();
615 BailOut(
"Increment operator is not supported. Use `+=` instead.",
617 return std::make_unique<ErrorNode>();
619 llvm_unreachable(
"invalid token");
645 if (!identifier.empty()) {
648 uint32_t save_token_idx =
m_dil_lexer.GetCurrentTokenIdx();
653 return std::make_unique<SizeOfNode>(loc, *type_id);
659 return std::make_unique<SizeOfNode>(loc, std::move(expr));
661 return std::make_unique<IdentifierNode>(loc, identifier);
675 return std::make_unique<ErrorNode>();
699 (
m_dil_lexer.LookAhead(1).GetSpelling() ==
"anonymous") &&
701 (
m_dil_lexer.LookAhead(2).GetSpelling() ==
"namespace") &&
709 BailOut(
"Expected an identifier or anonymous namespace, but not found.",
715 return "(anonymous namespace)::" + identifier2;
755 if (maybe_builtin_type) {
756 type = *maybe_builtin_type;
760 std::string type_name;
763 if (type_name.empty())
785 std::vector<Token> ptr_operators;
788 ptr_operators.push_back(std::move(tok));
807 std::string type_name =
"";
808 uint32_t save_token_idx =
m_dil_lexer.GetCurrentTokenIdx();
809 bool first_word =
true;
811 if (
CurToken().GetSpelling() ==
"const" ||
812 CurToken().GetSpelling() ==
"volatile") {
817 type_name.push_back(
' ');
820 type_name.append(
CurToken().GetSpelling());
824 if (type_name.size() > 0) {
827 for (
auto type_system_sp : target_sp->GetScratchTypeSystems())
828 if (
auto compiler_type =
829 type_system_sp->GetBuiltinTypeByName(const_type_name))
830 return compiler_type;
847 type_name = *err_or_string;
863 bool global_scope =
false;
874 if (!type_name_or_err)
875 return type_name_or_err;
876 std::string type_name = *type_name_or_err;
881 if (!type_name.empty())
883 return llvm::formatv(
"{0}{1}{2}", global_scope ?
"::" :
"",
884 nested_name_specifier, type_name);
934 bool global_scope =
false;
945 if (!nested_name_specifier.empty()) {
949 return llvm::formatv(
"{0}{1}{2}", global_scope ?
"::" :
"",
950 nested_name_specifier, unqualified_id);
962 return llvm::formatv(
"{0}{1}", global_scope ?
"::" :
"", identifier);
986 const std::vector<Token> &ptr_operators) {
988 for (
Token tk : ptr_operators) {
989 uint32_t loc = tk.GetLocation();
993 BailOut(llvm::formatv(
"'type name' declared as a pointer to a "
994 "reference of type {0}",
996 loc,
CurToken().GetSpelling().length());
1006 BailOut(
"type name declared as a reference to a reference", loc,
1007 CurToken().GetSpelling().length());
1029 return std::make_unique<BooleanLiteralNode>(loc, literal_value);
1058 BailOut(llvm::formatv(
"Failed to parse token as numeric-constant: {0}",
1061 return numeric_constant;
1064 return numeric_constant;
1070 llvm::StringRef spelling_ref = spelling;
1072 auto radix = llvm::getAutoSenseRadix(spelling_ref);
1074 bool is_unsigned =
false;
1075 if (spelling_ref.consume_back_insensitive(
"u"))
1077 if (spelling_ref.consume_back_insensitive(
"ll"))
1079 else if (spelling_ref.consume_back_insensitive(
"l"))
1082 if (!is_unsigned && spelling_ref.consume_back_insensitive(
"u"))
1085 llvm::APInt raw_value;
1086 if (!spelling_ref.getAsInteger(radix, raw_value))
1087 return std::make_unique<IntegerLiteralNode>(token.
GetLocation(), raw_value,
1088 radix, is_unsigned, type);
1089 return std::make_unique<ErrorNode>();
1095 llvm::StringRef spelling_ref = spelling;
1097 llvm::APFloat raw_float(llvm::APFloat::IEEEdouble());
1098 if (spelling_ref.consume_back_insensitive(
"f"))
1099 raw_float = llvm::APFloat(llvm::APFloat::IEEEsingle());
1101 auto StatusOrErr = raw_float.convertFromString(
1102 spelling_ref, llvm::APFloat::rmNearestTiesToEven);
1103 if (!errorToBool(StatusOrErr.takeError()))
1104 return std::make_unique<FloatLiteralNode>(token.
GetLocation(), raw_float);
1105 return std::make_unique<ErrorNode>();
1110 BailOut(
"Assignment is allowed only at top level.",
1120 if (!
CurToken().IsOneOf(kinds_vec)) {
1121 BailOut(llvm::formatv(
"expected any of ({0}), got: {1}",
1122 llvm::iterator_range(kinds_vec),
CurToken()),
static llvm::raw_ostream & error(Stream &strm)
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/ExecutionContextScope.h" Inherit from this if your object can reconstruct its execution ...
virtual lldb::TargetSP CalculateTarget()=0
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.
This base class provides an interface to stack frames.
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()
static llvm::Expected< ASTNodeUP > Parse(llvm::StringRef dil_input_expr, DILLexer lexer, StackFrame &stack_frame, lldb::DynamicValueType use_dynamic, lldb::DILMode mode)
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()
ASTNodeUP ParsePureExpression()
ASTNodeUP ParseNumericLiteral()
ASTNodeUP ParseAssignmentExpression()
std::optional< CompilerType > ParseBuiltinType()
ASTNodeUP ParsePrimaryExpression()
DILParser(llvm::StringRef dil_input_expr, DILLexer lexer, StackFrame &stack_frame, lldb::DynamicValueType use_dynamic, llvm::Error &error, lldb::DILMode mode)
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()
StackFrame & m_stack_frame
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).
lldb::ValueObjectSP LookupIdentifier(llvm::StringRef name_ref, StackFrame &stack_frame, lldb::DynamicValueType use_dynamic)
Given the name of an identifier (variable name, member name, type name, etc.), find the ValueObject f...
std::unique_ptr< ASTNode > ASTNodeUP
lldb::ValueObjectSP LookupGlobalIdentifier(llvm::StringRef name_ref, StackFrame &stack_frame, lldb::TargetSP target_sp, lldb::DynamicValueType use_dynamic)
Given the name of an identifier, check to see if it matches the name of a global variable.
BinaryOpKind GetBinaryOpKindFromToken(Token::Kind token_kind)
Translates DIL tokens to BinaryOpKind.
CompilerType ResolveTypeByName(const std::string &name, ExecutionContextScope &ctx_scope)
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.