1 //===-- ASTResultSynthesizer.h ----------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #ifndef liblldb_ASTResultSynthesizer_h_
11 #define liblldb_ASTResultSynthesizer_h_
12 
13 #include "clang/Sema/SemaConsumer.h"
14 #include "lldb/Core/ClangForward.h"
15 #include "lldb/Symbol/TaggedASTType.h"
16 
17 namespace lldb_private {
18 
19 //----------------------------------------------------------------------
20 /// @class ASTResultSynthesizer ASTResultSynthesizer.h "lldb/Expression/ASTResultSynthesizer.h"
21 /// @brief Adds a result variable declaration to the ASTs for an expression.
22 ///
23 /// Users expect the expression "i + 3" to return a result, even if a result
24 /// variable wasn't specifically declared.  To fulfil this requirement, LLDB adds
25 /// a result variable to the expression, transforming it to
26 /// "int $__lldb_expr_result = i + 3."  The IR transformers ensure that the
27 /// resulting variable is mapped to the right piece of memory.
28 /// ASTResultSynthesizer's job is to add the variable and its initialization to
29 /// the ASTs for the expression, and it does so by acting as a SemaConsumer for
30 /// Clang.
31 //----------------------------------------------------------------------
32 class ASTResultSynthesizer : public clang::SemaConsumer
33 {
34 public:
35     //----------------------------------------------------------------------
36     /// Constructor
37     ///
38     /// @param[in] passthrough
39     ///     Since the ASTs must typically go through to the Clang code generator
40     ///     in order to produce LLVM IR, this SemaConsumer must allow them to
41     ///     pass to the next step in the chain after processing.  Passthrough is
42     ///     the next ASTConsumer, or NULL if none is required.
43     ///
44     /// @param[in] target
45     ///     The target, which contains the persistent variable store and the
46     ///     AST importer.
47     //----------------------------------------------------------------------
48     ASTResultSynthesizer(clang::ASTConsumer *passthrough,
49                          Target &target);
50 
51     //----------------------------------------------------------------------
52     /// Destructor
53     //----------------------------------------------------------------------
54     ~ASTResultSynthesizer();
55 
56     //----------------------------------------------------------------------
57     /// Link this consumer with a particular AST context
58     ///
59     /// @param[in] Context
60     ///     This AST context will be used for types and identifiers, and also
61     ///     forwarded to the passthrough consumer, if one exists.
62     //----------------------------------------------------------------------
63     void Initialize(clang::ASTContext &Context);
64 
65     //----------------------------------------------------------------------
66     /// Examine a list of Decls to find the function $__lldb_expr and
67     /// transform its code
68     ///
69     /// @param[in] D
70     ///     The list of Decls to search.  These may contain LinkageSpecDecls,
71     ///     which need to be searched recursively.  That job falls to
72     ///     TransformTopLevelDecl.
73     //----------------------------------------------------------------------
74     bool HandleTopLevelDecl(clang::DeclGroupRef D);
75 
76     //----------------------------------------------------------------------
77     /// Passthrough stub
78     //----------------------------------------------------------------------
79     void HandleTranslationUnit(clang::ASTContext &Ctx);
80 
81     //----------------------------------------------------------------------
82     /// Passthrough stub
83     //----------------------------------------------------------------------
84     void HandleTagDeclDefinition(clang::TagDecl *D);
85 
86     //----------------------------------------------------------------------
87     /// Passthrough stub
88     //----------------------------------------------------------------------
89     void CompleteTentativeDefinition(clang::VarDecl *D);
90 
91     //----------------------------------------------------------------------
92     /// Passthrough stub
93     //----------------------------------------------------------------------
94     void HandleVTable(clang::CXXRecordDecl *RD, bool DefinitionRequired);
95 
96     //----------------------------------------------------------------------
97     /// Passthrough stub
98     //----------------------------------------------------------------------
99     void PrintStats();
100 
101     //----------------------------------------------------------------------
102     /// Set the Sema object to use when performing transforms, and pass it on
103     ///
104     /// @param[in] S
105     ///     The Sema to use.  Because Sema isn't externally visible, this class
106     ///     casts it to an Action for actual use.
107     //----------------------------------------------------------------------
108     void InitializeSema(clang::Sema &S);
109 
110     //----------------------------------------------------------------------
111     /// Reset the Sema to NULL now that transformations are done
112     //----------------------------------------------------------------------
113     void ForgetSema();
114 private:
115     //----------------------------------------------------------------------
116     /// Hunt the given Decl for FunctionDecls named $__lldb_expr, recursing
117     /// as necessary through LinkageSpecDecls, and calling SynthesizeResult on
118     /// anything that was found
119     ///
120     /// @param[in] D
121     ///     The Decl to hunt.
122     //----------------------------------------------------------------------
123     void TransformTopLevelDecl(clang::Decl *D);
124 
125     //----------------------------------------------------------------------
126     /// Process an Objective-C method and produce the result variable and
127     /// initialization
128     ///
129     /// @param[in] MethodDecl
130     ///     The method to process.
131     //----------------------------------------------------------------------
132     bool SynthesizeObjCMethodResult(clang::ObjCMethodDecl *MethodDecl);
133 
134     //----------------------------------------------------------------------
135     /// Process a function and produce the result variable and initialization
136     ///
137     /// @param[in] FunDecl
138     ///     The function to process.
139     //----------------------------------------------------------------------
140     bool SynthesizeFunctionResult(clang::FunctionDecl *FunDecl);
141 
142     //----------------------------------------------------------------------
143     /// Process a function body and produce the result variable and
144     /// initialization
145     ///
146     /// @param[in] Body
147     ///     The body of the function.
148     ///
149     /// @param[in] DC
150     ///     The DeclContext of the function, into which the result variable
151     ///     is inserted.
152     //----------------------------------------------------------------------
153     bool SynthesizeBodyResult(clang::CompoundStmt *Body,
154                               clang::DeclContext *DC);
155 
156     //----------------------------------------------------------------------
157     /// Given a DeclContext for a function or method, find all types
158     /// declared in the context and record any persistent types found.
159     ///
160     /// @param[in] FunDeclCtx
161     ///     The context for the function to process.
162     //----------------------------------------------------------------------
163     void RecordPersistentTypes(clang::DeclContext *FunDeclCtx);
164 
165     //----------------------------------------------------------------------
166     /// Given a TypeDecl, if it declares a type whose name starts with a
167     /// dollar sign, register it as a pointer type in the target's scratch
168     /// AST context.
169     ///
170     /// @param[in] Body
171     ///     The body of the function.
172     //----------------------------------------------------------------------
173     void MaybeRecordPersistentType(clang::TypeDecl *D);
174 
175     clang::ASTContext *m_ast_context;           ///< The AST context to use for identifiers and types.
176     clang::ASTConsumer *m_passthrough;          ///< The ASTConsumer down the chain, for passthrough.  NULL if it's a SemaConsumer.
177     clang::SemaConsumer *m_passthrough_sema;    ///< The SemaConsumer down the chain, for passthrough.  NULL if it's an ASTConsumer.
178     Target &m_target;                           ///< The target, which contains the persistent variable store and the
179     clang::Sema *m_sema;                        ///< The Sema to use.
180 };
181 
182 }
183 
184 #endif
185