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