1010#define LLDB_VALUEOBJECT_DILPARSER_H
1111
1212#include " lldb/Target/ExecutionContextScope.h"
13+ #include " lldb/Target/StackFrame.h"
1314#include " lldb/Utility/DiagnosticsRendering.h"
1415#include " lldb/Utility/Status.h"
1516#include " lldb/ValueObject/DILAST.h"
@@ -31,6 +32,9 @@ enum class ErrorCode : unsigned char {
3132 kUnknown ,
3233};
3334
35+ llvm::Expected<lldb::TypeSystemSP>
36+ DILGetTypeSystemFromCU (std::shared_ptr<StackFrame> ctx);
37+
3438// The following is modeled on class OptionParseError.
3539class DILDiagnosticError
3640 : public llvm::ErrorInfo<DILDiagnosticError, DiagnosticError> {
@@ -55,6 +59,61 @@ class DILDiagnosticError
5559
5660 std::string message () const override { return m_detail.rendered ; }
5761};
62+ // / TypeDeclaration builds information about the literal type definition as
63+ // / type is being parsed. It doesn't perform semantic analysis for non-basic
64+ // / types -- e.g. "char&&&" is a valid type declaration.
65+ // / NOTE: CV qualifiers are ignored.
66+ class TypeDeclaration {
67+ public:
68+ enum class TypeSpecifier {
69+ kBool ,
70+ kChar ,
71+ kDouble ,
72+ kFloat ,
73+ kInt ,
74+ kLong ,
75+ kLongDouble ,
76+ kLongLong ,
77+ kShort ,
78+ kUnknown ,
79+ kVoid ,
80+ };
81+
82+ enum class SignSpecifier {
83+ kUnknown ,
84+ kSigned ,
85+ kUnsigned ,
86+ };
87+
88+ bool IsEmpty () const { return !m_is_builtin && !m_is_user_type; }
89+
90+ lldb::BasicType GetBasicType () const ;
91+
92+ public:
93+ // Indicates user-defined typename (e.g. "MyClass", "MyTmpl<int>").
94+ std::string m_user_typename;
95+
96+ // Basic type specifier ("void", "char", "intr", "float", "long long", etc.).
97+ TypeSpecifier m_type_specifier = TypeSpecifier::kUnknown ;
98+
99+ // Signedness specifier ("signed", "unsigned").
100+ SignSpecifier m_sign_specifier = SignSpecifier::kUnknown ;
101+
102+ // Does the type declaration includes "int" specifier?
103+ // This is different than `type_specifier_` and is used to detect "int"
104+ // duplication for types that can be combined with "int" specifier (e.g.
105+ // "short int", "long int").
106+ bool m_has_int_specifier = false ;
107+
108+ // Indicates whether there was an error during parsing.
109+ bool m_has_error = false ;
110+
111+ // Indicates whether this declaration describes a builtin type.
112+ bool m_is_builtin = false ;
113+
114+ // Indicates whether this declaration describes a user type.
115+ bool m_is_user_type = false ;
116+ }; // class TypeDeclaration
58117
59118// / Pure recursive descent parser for C++ like expressions.
60119// / EBNF grammar for the parser is described in lldb/docs/dil-expr-lang.ebnf
@@ -100,10 +159,22 @@ class DILParser {
100159 ASTNodeUP ParseIntegerLiteral ();
101160 ASTNodeUP ParseFloatingPointLiteral ();
102161
162+ ASTNodeUP ParseCastExpression ();
163+ std::optional<CompilerType> ParseTypeId (bool must_be_type_id = false );
164+ void ParseTypeSpecifierSeq (TypeDeclaration *type_decl);
165+ bool ParseTypeSpecifier (TypeDeclaration *type_decl);
166+ std::string ParseTypeName ();
167+ CompilerType ResolveTypeDeclarators (CompilerType type,
168+ const std::vector<Token> &ptr_operators);
169+ bool IsSimpleTypeSpecifierKeyword (Token token) const ;
170+ bool HandleSimpleTypeSpecifier (TypeDeclaration *type_decl);
171+
103172 void BailOut (const std::string &error, uint32_t loc, uint16_t err_len);
104173
105174 void Expect (Token::Kind kind);
106175
176+ void ExpectOneOf (std::vector<Token::Kind> kinds_vec);
177+
107178 void TentativeParsingRollback (uint32_t saved_idx) {
108179 if (m_error)
109180 llvm::consumeError (std::move (m_error));
@@ -132,4 +203,66 @@ class DILParser {
132203
133204} // namespace lldb_private::dil
134205
206+ namespace llvm {
207+ template <>
208+ struct format_provider <lldb_private::dil::TypeDeclaration::TypeSpecifier> {
209+ static void format (const lldb_private::dil::TypeDeclaration::TypeSpecifier &t,
210+ raw_ostream &OS, llvm::StringRef Options) {
211+ switch (t) {
212+ case lldb_private::dil::TypeDeclaration::TypeSpecifier::kVoid :
213+ OS << " void" ;
214+ break ;
215+ case lldb_private::dil::TypeDeclaration::TypeSpecifier::kBool :
216+ OS << " bool" ;
217+ break ;
218+ case lldb_private::dil::TypeDeclaration::TypeSpecifier::kChar :
219+ OS << " char" ;
220+ break ;
221+ case lldb_private::dil::TypeDeclaration::TypeSpecifier::kInt :
222+ OS << " int" ;
223+ break ;
224+ case lldb_private::dil::TypeDeclaration::TypeSpecifier::kFloat :
225+ OS << " float" ;
226+ break ;
227+ case lldb_private::dil::TypeDeclaration::TypeSpecifier::kShort :
228+ OS << " short" ;
229+ break ;
230+ case lldb_private::dil::TypeDeclaration::TypeSpecifier::kLong :
231+ OS << " long" ;
232+ break ;
233+ case lldb_private::dil::TypeDeclaration::TypeSpecifier::kLongLong :
234+ OS << " long long" ;
235+ break ;
236+ case lldb_private::dil::TypeDeclaration::TypeSpecifier::kDouble :
237+ OS << " double" ;
238+ break ;
239+ case lldb_private::dil::TypeDeclaration::TypeSpecifier::kLongDouble :
240+ OS << " long double" ;
241+ break ;
242+ default :
243+ OS << " invalid type specifier" ;
244+ break ;
245+ }
246+ }
247+ };
248+
249+ template <>
250+ struct format_provider <lldb_private::dil::TypeDeclaration::SignSpecifier> {
251+ static void format (const lldb_private::dil::TypeDeclaration::SignSpecifier &t,
252+ raw_ostream &OS, llvm::StringRef Options) {
253+ switch (t) {
254+ case lldb_private::dil::TypeDeclaration::SignSpecifier::kSigned :
255+ OS << " signed" ;
256+ break ;
257+ case lldb_private::dil::TypeDeclaration::SignSpecifier::kUnsigned :
258+ OS << " unsigned" ;
259+ break ;
260+ default :
261+ OS << " invalid sign specifier" ;
262+ break ;
263+ }
264+ }
265+ };
266+ } // namespace llvm
267+
135268#endif // LLDB_VALUEOBJECT_DILPARSER_H
0 commit comments