1ea401ec7SJim Ingham //===-- ClangExpressionSourceCode.h -----------------------------*- C++ -*-===//
2ea401ec7SJim Ingham //
3ea401ec7SJim Ingham // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4ea401ec7SJim Ingham // See https://llvm.org/LICENSE.txt for license information.
5ea401ec7SJim Ingham // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6ea401ec7SJim Ingham //
7ea401ec7SJim Ingham //===----------------------------------------------------------------------===//
8ea401ec7SJim Ingham 
9cdc514e4SJonas Devlieghere #ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXPRESSIONSOURCECODE_H
10cdc514e4SJonas Devlieghere #define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXPRESSIONSOURCECODE_H
11ea401ec7SJim Ingham 
12ea401ec7SJim Ingham #include "lldb/Expression/Expression.h"
13ea401ec7SJim Ingham #include "lldb/Expression/ExpressionSourceCode.h"
14ea401ec7SJim Ingham #include "lldb/lldb-enumerations.h"
15ea401ec7SJim Ingham #include "llvm/ADT/ArrayRef.h"
16ea401ec7SJim Ingham #include "llvm/ADT/StringRef.h"
17ea401ec7SJim Ingham 
18ea401ec7SJim Ingham #include <string>
19ea401ec7SJim Ingham 
20ea401ec7SJim Ingham namespace lldb_private {
21ea401ec7SJim Ingham 
22ea401ec7SJim Ingham class ExecutionContext;
23ea401ec7SJim Ingham 
24ea401ec7SJim Ingham class ClangExpressionSourceCode : public ExpressionSourceCode {
25ea401ec7SJim Ingham public:
26bd2a910aSRaphael Isemann   /// The file name we use for the wrapper code that we inject before
27bd2a910aSRaphael Isemann   /// the user expression.
28bd2a910aSRaphael Isemann   static const llvm::StringRef g_prefix_file_name;
29ea401ec7SJim Ingham   static const char *g_expression_prefix;
3038dfb235SJonas Devlieghere   static const char *g_expression_suffix;
31ea401ec7SJim Ingham 
322b37c5b5SRaphael Isemann   /// The possible ways an expression can be wrapped.
332b37c5b5SRaphael Isemann   enum class WrapKind {
342b37c5b5SRaphael Isemann     /// Wrapped in a non-static member function of a C++ class.
352b37c5b5SRaphael Isemann     CppMemberFunction,
362b37c5b5SRaphael Isemann     /// Wrapped in an instance Objective-C method.
372b37c5b5SRaphael Isemann     ObjCInstanceMethod,
382b37c5b5SRaphael Isemann     /// Wrapped in a static Objective-C method.
392b37c5b5SRaphael Isemann     ObjCStaticMethod,
402b37c5b5SRaphael Isemann     /// Wrapped in a non-member function.
414125b462SRaphael Isemann     /// Note that this is also used for static member functions of a C++ class.
422b37c5b5SRaphael Isemann     Function
432b37c5b5SRaphael Isemann   };
442b37c5b5SRaphael Isemann 
CreateWrapped(llvm::StringRef filename,llvm::StringRef prefix,llvm::StringRef body,WrapKind wrap_kind)451442efeaSRaphael Isemann   static ClangExpressionSourceCode *CreateWrapped(llvm::StringRef filename,
461442efeaSRaphael Isemann                                                   llvm::StringRef prefix,
472b37c5b5SRaphael Isemann                                                   llvm::StringRef body,
482b37c5b5SRaphael Isemann                                                   WrapKind wrap_kind) {
491442efeaSRaphael Isemann     return new ClangExpressionSourceCode(filename, "$__lldb_expr", prefix, body,
502b37c5b5SRaphael Isemann                                          Wrap, wrap_kind);
51ea401ec7SJim Ingham   }
52ea401ec7SJim Ingham 
536c0bbfc0SRaphael Isemann   /// Generates the source code that will evaluate the expression.
546c0bbfc0SRaphael Isemann   ///
556c0bbfc0SRaphael Isemann   /// \param text output parameter containing the source code string.
566c0bbfc0SRaphael Isemann   /// \param exe_ctx The execution context in which the expression will be
576c0bbfc0SRaphael Isemann   ///        evaluated.
586c0bbfc0SRaphael Isemann   /// \param add_locals True iff local variables should be injected into the
596c0bbfc0SRaphael Isemann   ///        expression source code.
6071569d0dSRaphael Isemann   /// \param force_add_all_locals True iff all local variables should be
6171569d0dSRaphael Isemann   ///        injected even if they are not used in the expression.
626c0bbfc0SRaphael Isemann   /// \param modules A list of (C++) modules that the expression should import.
636c0bbfc0SRaphael Isemann   ///
646c0bbfc0SRaphael Isemann   /// \return true iff the source code was successfully generated.
652b37c5b5SRaphael Isemann   bool GetText(std::string &text, ExecutionContext &exe_ctx, bool add_locals,
6671569d0dSRaphael Isemann                bool force_add_all_locals,
676c0bbfc0SRaphael Isemann                llvm::ArrayRef<std::string> modules) const;
68ea401ec7SJim Ingham 
69ea401ec7SJim Ingham   // Given a string returned by GetText, find the beginning and end of the body
70ea401ec7SJim Ingham   // passed to CreateWrapped. Return true if the bounds could be found.  This
71ea401ec7SJim Ingham   // will also work on text with FixItHints applied.
721442efeaSRaphael Isemann   bool GetOriginalBodyBounds(std::string transformed_text,
73ea401ec7SJim Ingham                              size_t &start_loc, size_t &end_loc);
74ea401ec7SJim Ingham 
75ea401ec7SJim Ingham protected:
761442efeaSRaphael Isemann   ClangExpressionSourceCode(llvm::StringRef filename, llvm::StringRef name,
771442efeaSRaphael Isemann                             llvm::StringRef prefix, llvm::StringRef body,
782b37c5b5SRaphael Isemann                             Wrapping wrap, WrapKind wrap_kind);
791442efeaSRaphael Isemann 
801442efeaSRaphael Isemann private:
81*8184b252SMichael Buch   /// Writes "using" declarations for local variables into the specified stream.
82*8184b252SMichael Buch   ///
83*8184b252SMichael Buch   /// Behaviour is undefined if 'frame == nullptr'.
84*8184b252SMichael Buch   ///
85*8184b252SMichael Buch   /// \param[out] stream Stream that this function generates "using"
86*8184b252SMichael Buch   ///             declarations into.
87*8184b252SMichael Buch   ///
88*8184b252SMichael Buch   /// \param[in]  expr Expression source that we're evaluating.
89*8184b252SMichael Buch   ///
90*8184b252SMichael Buch   /// \param[in]  frame StackFrame which carries information about the local
91*8184b252SMichael Buch   ///             variables that we're generating "using" declarations for.
92*8184b252SMichael Buch   void AddLocalVariableDecls(StreamString &stream, const std::string &expr,
93*8184b252SMichael Buch                              StackFrame *frame) const;
942b37c5b5SRaphael Isemann 
951442efeaSRaphael Isemann   /// String marking the start of the user expression.
961442efeaSRaphael Isemann   std::string m_start_marker;
971442efeaSRaphael Isemann   /// String marking the end of the user expression.
981442efeaSRaphael Isemann   std::string m_end_marker;
992b37c5b5SRaphael Isemann   /// How the expression has been wrapped.
1002b37c5b5SRaphael Isemann   const WrapKind m_wrap_kind;
101ea401ec7SJim Ingham };
102ea401ec7SJim Ingham 
103ea401ec7SJim Ingham } // namespace lldb_private
104ea401ec7SJim Ingham 
105ea401ec7SJim Ingham #endif
106