Home | History | Annotate | Download | only in Expression
      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