1 //===-- ASTStructExtractor.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_ASTStructExtractor_h_
11 #define liblldb_ASTStructExtractor_h_
12 
13 #include "ClangExpressionVariable.h"
14 #include "ClangFunctionCaller.h"
15 
16 #include "clang/Sema/SemaConsumer.h"
17 #include "lldb/Core/ClangForward.h"
18 
19 namespace lldb_private {
20 
21 //----------------------------------------------------------------------
22 /// @class ASTStructExtractor ASTStructExtractor.h "lldb/Expression/ASTStructExtractor.h"
23 /// @brief Extracts and describes the argument structure for a wrapped function.
24 ///
25 /// This pass integrates with ClangFunctionCaller, which calls functions with custom
26 /// sets of arguments.  To avoid having to implement the full calling convention
27 /// for the target's architecture, ClangFunctionCaller writes a simple wrapper
28 /// function that takes a pointer to an argument structure that contains room
29 /// for the address of the function to be called, the values of all its
30 /// arguments, and room for the function's return value.
31 ///
32 /// The definition of this struct is itself in the body of the wrapper function,
33 /// so Clang does the structure layout itself.  ASTStructExtractor reads through
34 /// the AST for the wrapper function and finds the struct.
35 //----------------------------------------------------------------------
36 class ASTStructExtractor : public clang::SemaConsumer
37 {
38 public:
39     //----------------------------------------------------------------------
40     /// Constructor
41     ///
42     /// @param[in] passthrough
43     ///     Since the ASTs must typically go through to the Clang code generator
44     ///     in order to produce LLVM IR, this SemaConsumer must allow them to
45     ///     pass to the next step in the chain after processing.  Passthrough is
46     ///     the next ASTConsumer, or NULL if none is required.
47     ///
48     /// @param[in] struct_name
49     ///     The name of the structure to extract from the wrapper function.
50     ///
51     /// @param[in] function
52     ///     The caller object whose members should be populated with information
53     ///     about the argument struct.  ClangFunctionCaller friends ASTStructExtractor
54     ///     for this purpose.
55     //----------------------------------------------------------------------
56     ASTStructExtractor(clang::ASTConsumer *passthrough,
57                        const char *struct_name,
58                        ClangFunctionCaller &function);
59 
60     //----------------------------------------------------------------------
61     /// Destructor
62     //----------------------------------------------------------------------
63     ~ASTStructExtractor() override;
64 
65     //----------------------------------------------------------------------
66     /// Link this consumer with a particular AST context
67     ///
68     /// @param[in] Context
69     ///     This AST context will be used for types and identifiers, and also
70     ///     forwarded to the passthrough consumer, if one exists.
71     //----------------------------------------------------------------------
72     void Initialize(clang::ASTContext &Context) override;
73 
74     //----------------------------------------------------------------------
75     /// Examine a list of Decls to find the function $__lldb_expr and
76     /// transform its code
77     ///
78     /// @param[in] D
79     ///     The list of Decls to search.  These may contain LinkageSpecDecls,
80     ///     which need to be searched recursively.  That job falls to
81     ///     TransformTopLevelDecl.
82     //----------------------------------------------------------------------
83     bool HandleTopLevelDecl(clang::DeclGroupRef D) override;
84 
85     //----------------------------------------------------------------------
86     /// Passthrough stub
87     //----------------------------------------------------------------------
88     void HandleTranslationUnit(clang::ASTContext &Ctx) override;
89 
90     //----------------------------------------------------------------------
91     /// Passthrough stub
92     //----------------------------------------------------------------------
93     void HandleTagDeclDefinition(clang::TagDecl *D) override;
94 
95     //----------------------------------------------------------------------
96     /// Passthrough stub
97     //----------------------------------------------------------------------
98     void CompleteTentativeDefinition(clang::VarDecl *D) override;
99 
100     //----------------------------------------------------------------------
101     /// Passthrough stub
102     //----------------------------------------------------------------------
103     void HandleVTable(clang::CXXRecordDecl *RD) override;
104 
105     //----------------------------------------------------------------------
106     /// Passthrough stub
107     //----------------------------------------------------------------------
108     void PrintStats() override;
109 
110     //----------------------------------------------------------------------
111     /// Set the Sema object to use when performing transforms, and pass it on
112     ///
113     /// @param[in] S
114     ///     The Sema to use.  Because Sema isn't externally visible, this class
115     ///     casts it to an Action for actual use.
116     //----------------------------------------------------------------------
117     void InitializeSema(clang::Sema &S) override;
118 
119     //----------------------------------------------------------------------
120     /// Reset the Sema to NULL now that transformations are done
121     //----------------------------------------------------------------------
122     void ForgetSema() override;
123 
124 private:
125     //----------------------------------------------------------------------
126     /// Hunt the given FunctionDecl for the argument struct and place
127     /// information about it into m_function
128     ///
129     /// @param[in] F
130     ///     The FunctionDecl to hunt.
131     //----------------------------------------------------------------------
132     void
133     ExtractFromFunctionDecl(clang::FunctionDecl* F);
134 
135     //----------------------------------------------------------------------
136     /// Hunt the given Decl for FunctionDecls named the same as the wrapper
137     /// function name, recursing as necessary through LinkageSpecDecls, and
138     /// calling ExtractFromFunctionDecl on anything that was found
139     ///
140     /// @param[in] D
141     ///     The Decl to hunt.
142     //----------------------------------------------------------------------
143     void
144     ExtractFromTopLevelDecl(clang::Decl* D);
145 
146     clang::ASTContext              *m_ast_context;          ///< The AST context to use for identifiers and types.
147     clang::ASTConsumer             *m_passthrough;          ///< The ASTConsumer down the chain, for passthrough.  NULL if it's a SemaConsumer.
148     clang::SemaConsumer            *m_passthrough_sema;     ///< The SemaConsumer down the chain, for passthrough.  NULL if it's an ASTConsumer.
149     clang::Sema                    *m_sema;                 ///< The Sema to use.
150     clang::Action                  *m_action;               ///< The Sema to use, cast to an Action so it's usable.
151 
152     ClangFunctionCaller            &m_function;             ///< The function to populate with information about the argument structure.
153     std::string                     m_struct_name;          ///< The name of the structure to extract.
154 };
155 
156 } // namespace lldb_private
157 
158 #endif // liblldb_ASTStructExtractor_h_
159