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