forked from OSchip/llvm-project
Documented ClangResultSynthesizer and added very minor
API fixes. llvm-svn: 111202
This commit is contained in:
parent
be6cca2b7d
commit
6dce6de80c
|
@ -15,32 +15,120 @@
|
|||
|
||||
namespace lldb_private {
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/// @class ClangResultSynthesizer ClangResultSynthesizer.h "lldb/Expression/ClangResultSynthesizer.h"
|
||||
/// @brief Adds a result variable declaration to the ASTs for an expression.
|
||||
///
|
||||
/// Users expect the expression "i + 3" to return a result, even if a result
|
||||
/// variable wasn't specifically declared. To fulfil this requirement, LLDB adds
|
||||
/// a result variable to the expression, transforming it to
|
||||
/// "int ___clang_expr_result = i + 3." The IR transformers ensure that the
|
||||
/// resulting variable is mapped to the right piece of memory.
|
||||
/// ClangResultSynthesizer's job is to add the variable and its initialization to
|
||||
/// the ASTs for the expression, and it does so by acting as a SemaConsumer for
|
||||
/// Clang.
|
||||
//----------------------------------------------------------------------
|
||||
class ClangResultSynthesizer : public clang::SemaConsumer
|
||||
{
|
||||
public:
|
||||
//----------------------------------------------------------------------
|
||||
/// Constructor
|
||||
///
|
||||
/// @param[in] passthrough
|
||||
/// Since the ASTs must typically go through to the Clang code generator
|
||||
/// in order to produce LLVM IR, this SemaConsumer must allow them to
|
||||
/// pass to the next step in the chain after processing. Passthrough is
|
||||
/// the next ASTConsumer, or NULL if none is required.
|
||||
//----------------------------------------------------------------------
|
||||
ClangResultSynthesizer(clang::ASTConsumer *passthrough);
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/// Destructor
|
||||
//----------------------------------------------------------------------
|
||||
~ClangResultSynthesizer();
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/// Link this consumer with a particular AST context
|
||||
///
|
||||
/// @param[in] Context
|
||||
/// This AST context will be used for types and identifiers, and also
|
||||
/// forwarded to the passthrough consumer, if one exists.
|
||||
//----------------------------------------------------------------------
|
||||
void Initialize(clang::ASTContext &Context);
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/// Examine a list of Decls to find the function ___clang_expr and
|
||||
/// transform its code
|
||||
///
|
||||
/// @param[in] D
|
||||
/// The list of Decls to search. These may contain LinkageSpecDecls,
|
||||
/// which need to be searched recursively. That job falls to
|
||||
/// TransformTopLevelDecl.
|
||||
//----------------------------------------------------------------------
|
||||
void HandleTopLevelDecl(clang::DeclGroupRef D);
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/// Passthrough stub
|
||||
//----------------------------------------------------------------------
|
||||
void HandleTranslationUnit(clang::ASTContext &Ctx);
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/// Passthrough stub
|
||||
//----------------------------------------------------------------------
|
||||
void HandleTagDeclDefinition(clang::TagDecl *D);
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/// Passthrough stub
|
||||
//----------------------------------------------------------------------
|
||||
void CompleteTentativeDefinition(clang::VarDecl *D);
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/// Passthrough stub
|
||||
//----------------------------------------------------------------------
|
||||
void HandleVTable(clang::CXXRecordDecl *RD, bool DefinitionRequired);
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/// Passthrough stub
|
||||
//----------------------------------------------------------------------
|
||||
void PrintStats();
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/// Set the Sema object to use when performing transforms, and pass it on
|
||||
///
|
||||
/// @param[in] S
|
||||
/// The Sema to use. Because Sema isn't externally visible, this class
|
||||
/// casts it to an Action for actual use.
|
||||
//----------------------------------------------------------------------
|
||||
void InitializeSema(clang::Sema &S);
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/// Reset the Sema to NULL now that transformations are done
|
||||
//----------------------------------------------------------------------
|
||||
void ForgetSema();
|
||||
private:
|
||||
//----------------------------------------------------------------------
|
||||
/// Hunt the given Decl for FunctionDecls named ___clang_expr, recursing
|
||||
/// as necessary through LinkageSpecDecls, and calling SynthesizeResult on
|
||||
/// anything that was found
|
||||
///
|
||||
/// @param[in] D
|
||||
/// The Decl to hunt.
|
||||
//----------------------------------------------------------------------
|
||||
void TransformTopLevelDecl(clang::Decl *D);
|
||||
bool SynthesizeResult(clang::ASTContext &Ctx,
|
||||
clang::FunctionDecl *FunDecl);
|
||||
|
||||
clang::ASTContext *m_ast_context;
|
||||
clang::ASTConsumer *m_passthrough;
|
||||
clang::SemaConsumer *m_passthrough_sema;
|
||||
clang::Sema *m_sema;
|
||||
clang::Action *m_action;
|
||||
//----------------------------------------------------------------------
|
||||
/// Process a function and produce the result variable and initialization
|
||||
///
|
||||
/// @param[in] FunDecl
|
||||
/// The function to process.
|
||||
//----------------------------------------------------------------------
|
||||
bool SynthesizeResult(clang::FunctionDecl *FunDecl);
|
||||
|
||||
clang::ASTContext *m_ast_context; ///< The AST context to use for identifiers and types.
|
||||
clang::ASTConsumer *m_passthrough; ///< The ASTConsumer down the chain, for passthrough. NULL if it's a SemaConsumer.
|
||||
clang::SemaConsumer *m_passthrough_sema; ///< The SemaConsumer down the chain, for passthrough. NULL if it's an ASTConsumer.
|
||||
clang::Sema *m_sema; ///< The Sema to use.
|
||||
clang::Action *m_action; ///< The Sema to use, cast to an Action so it's usable.
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -76,7 +76,7 @@ ClangResultSynthesizer::TransformTopLevelDecl(Decl* D)
|
|||
!strcmp(function_decl->getNameAsCString(),
|
||||
"___clang_expr"))
|
||||
{
|
||||
SynthesizeResult(*m_ast_context, function_decl);
|
||||
SynthesizeResult(function_decl);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -99,9 +99,10 @@ ClangResultSynthesizer::HandleTopLevelDecl(DeclGroupRef D)
|
|||
}
|
||||
|
||||
bool
|
||||
ClangResultSynthesizer::SynthesizeResult (ASTContext &Ctx,
|
||||
FunctionDecl *FunDecl)
|
||||
ClangResultSynthesizer::SynthesizeResult (FunctionDecl *FunDecl)
|
||||
{
|
||||
ASTContext &Ctx(*m_ast_context);
|
||||
|
||||
Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
|
||||
|
||||
if (!m_sema)
|
||||
|
|
Loading…
Reference in New Issue