mirror of
https://github.com/intel/llvm.git
synced 2026-01-17 14:48:27 +08:00
Added a SemaConsumer that transforms the ASTs for
an expression, adding code to put the value of the last expression (if there is one) into a variable and write the address of that variable to a global pointer. llvm-svn: 107419
This commit is contained in:
@@ -49,11 +49,15 @@ public:
|
||||
unsigned Compile();
|
||||
|
||||
unsigned
|
||||
ParseExpression (const char *expr_text, Stream &stream);
|
||||
ParseExpression (const char *expr_text,
|
||||
Stream &stream,
|
||||
bool add_result_var = false);
|
||||
|
||||
unsigned
|
||||
ParseBareExpression (llvm::StringRef expr_text, Stream &stream);
|
||||
|
||||
ParseBareExpression (llvm::StringRef expr_text,
|
||||
Stream &stream,
|
||||
bool add_result_var = false);
|
||||
|
||||
unsigned
|
||||
ConvertExpressionToDWARF (ClangExpressionVariableList &expr_local_variable_list,
|
||||
StreamString &dwarf_opcode_strm);
|
||||
|
||||
51
lldb/include/lldb/Expression/ClangResultSynthesizer.h
Normal file
51
lldb/include/lldb/Expression/ClangResultSynthesizer.h
Normal file
@@ -0,0 +1,51 @@
|
||||
//===-- ClangResultSynthesizer.h --------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef liblldb_ClangResultSynthesizer_h_
|
||||
#define liblldb_ClangResultSynthesizer_h_
|
||||
|
||||
#include "clang/Sema/SemaConsumer.h"
|
||||
|
||||
namespace clang {
|
||||
class Action;
|
||||
}
|
||||
|
||||
namespace lldb_private {
|
||||
|
||||
class ClangResultSynthesizer : public clang::SemaConsumer
|
||||
{
|
||||
public:
|
||||
ClangResultSynthesizer(clang::ASTConsumer *passthrough);
|
||||
~ClangResultSynthesizer();
|
||||
|
||||
void Initialize(clang::ASTContext &Context);
|
||||
void HandleTopLevelDecl(clang::DeclGroupRef D);
|
||||
void HandleTranslationUnit(clang::ASTContext &Ctx);
|
||||
void HandleTagDeclDefinition(clang::TagDecl *D);
|
||||
void CompleteTentativeDefinition(clang::VarDecl *D);
|
||||
void HandleVTable(clang::CXXRecordDecl *RD, bool DefinitionRequired);
|
||||
void PrintStats();
|
||||
|
||||
void InitializeSema(clang::Sema &S);
|
||||
void ForgetSema();
|
||||
private:
|
||||
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;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -328,6 +328,8 @@
|
||||
26F5C32D10F3DFDD009D5894 /* libtermcap.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 26F5C32B10F3DFDD009D5894 /* libtermcap.dylib */; };
|
||||
26F5C37510F3F61B009D5894 /* libobjc.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 26F5C37410F3F61B009D5894 /* libobjc.dylib */; };
|
||||
26F5C39110F3FA26009D5894 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 26F5C39010F3FA26009D5894 /* CoreFoundation.framework */; };
|
||||
49A8A3A011D568A300AD3B68 /* ClangResultSynthesizer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49A8A39F11D568A300AD3B68 /* ClangResultSynthesizer.cpp */; };
|
||||
49A8A3A411D568BF00AD3B68 /* ClangResultSynthesizer.h in Headers */ = {isa = PBXBuildFile; fileRef = 49A8A3A311D568BF00AD3B68 /* ClangResultSynthesizer.h */; };
|
||||
49D7072711B5AD03001AD875 /* ClangASTSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 49D7072611B5AD03001AD875 /* ClangASTSource.h */; };
|
||||
49D7072911B5AD11001AD875 /* ClangASTSource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49D7072811B5AD11001AD875 /* ClangASTSource.cpp */; settings = {COMPILER_FLAGS = "-fno-rtti"; }; };
|
||||
49F1A74611B3388F003ED505 /* ClangExpressionDeclMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49F1A74511B3388F003ED505 /* ClangExpressionDeclMap.cpp */; };
|
||||
@@ -896,6 +898,8 @@
|
||||
497E7B9D1188F6690065CCA1 /* ABI.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ABI.cpp; path = source/Target/ABI.cpp; sourceTree = "<group>"; };
|
||||
499F381E11A5B3F300F5CE02 /* CommandObjectArgs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandObjectArgs.h; path = source/Commands/CommandObjectArgs.h; sourceTree = "<group>"; };
|
||||
499F381F11A5B3F300F5CE02 /* CommandObjectArgs.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObjectArgs.cpp; path = source/Commands/CommandObjectArgs.cpp; sourceTree = "<group>"; };
|
||||
49A8A39F11D568A300AD3B68 /* ClangResultSynthesizer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ClangResultSynthesizer.cpp; path = source/Expression/ClangResultSynthesizer.cpp; sourceTree = "<group>"; };
|
||||
49A8A3A311D568BF00AD3B68 /* ClangResultSynthesizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ClangResultSynthesizer.h; path = include/lldb/Expression/ClangResultSynthesizer.h; sourceTree = "<group>"; };
|
||||
49BF48DC11ADF356008863BD /* ObjCObjectPrinter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ObjCObjectPrinter.cpp; path = source/Target/ObjCObjectPrinter.cpp; sourceTree = "<group>"; };
|
||||
49BF48E011ADF37D008863BD /* ObjCObjectPrinter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ObjCObjectPrinter.h; path = include/lldb/Target/ObjCObjectPrinter.h; sourceTree = "<group>"; };
|
||||
49D7072611B5AD03001AD875 /* ClangASTSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ClangASTSource.h; path = include/lldb/Expression/ClangASTSource.h; sourceTree = "<group>"; };
|
||||
@@ -1822,6 +1826,8 @@
|
||||
49F1A74511B3388F003ED505 /* ClangExpressionDeclMap.cpp */,
|
||||
26BC7DC110F1B79500F91463 /* ClangExpressionVariable.h */,
|
||||
26BC7ED610F1B86700F91463 /* ClangExpressionVariable.cpp */,
|
||||
49A8A3A311D568BF00AD3B68 /* ClangResultSynthesizer.h */,
|
||||
49A8A39F11D568A300AD3B68 /* ClangResultSynthesizer.cpp */,
|
||||
26BC7DC210F1B79500F91463 /* ClangStmtVisitor.h */,
|
||||
26BC7ED710F1B86700F91463 /* ClangStmtVisitor.cpp */,
|
||||
26BC7DC310F1B79500F91463 /* DWARFExpression.h */,
|
||||
@@ -2177,6 +2183,7 @@
|
||||
49D7072711B5AD03001AD875 /* ClangASTSource.h in Headers */,
|
||||
261B5A5511C3F2AD00AABD0A /* SharingPtr.h in Headers */,
|
||||
4C08CDEC11C81F1E001610A8 /* ThreadSpec.h in Headers */,
|
||||
49A8A3A411D568BF00AD3B68 /* ClangResultSynthesizer.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -2625,6 +2632,7 @@
|
||||
AF94005911C03F6500085DB9 /* SymbolVendor.cpp in Sources */,
|
||||
261B5A5411C3F2AD00AABD0A /* SharingPtr.cpp in Sources */,
|
||||
4C08CDE811C81EF8001610A8 /* ThreadSpec.cpp in Sources */,
|
||||
49A8A3A011D568A300AD3B68 /* ClangResultSynthesizer.cpp in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
||||
@@ -233,7 +233,7 @@ CommandObjectExpression::EvaluateExpression (const char *expr, bool bare, Stream
|
||||
if (bare)
|
||||
num_errors = clang_expr.ParseBareExpression (llvm::StringRef (expr), error_stream);
|
||||
else
|
||||
num_errors = clang_expr.ParseExpression (expr, error_stream);
|
||||
num_errors = clang_expr.ParseExpression (expr, error_stream, m_options.use_ir);
|
||||
|
||||
if (num_errors)
|
||||
{
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#include "clang/Frontend/VerifyDiagnosticsClient.h"
|
||||
#include "clang/Lex/Preprocessor.h"
|
||||
#include "clang/Sema/ParseAST.h"
|
||||
#include "clang/Sema/SemaConsumer.h"
|
||||
#include "llvm/ExecutionEngine/ExecutionEngine.h"
|
||||
#include "llvm/ExecutionEngine/JIT.h"
|
||||
#include "llvm/Module.h"
|
||||
@@ -53,6 +54,7 @@
|
||||
#include "lldb/Core/Log.h"
|
||||
#include "lldb/Expression/ClangExpression.h"
|
||||
#include "lldb/Expression/ClangASTSource.h"
|
||||
#include "lldb/Expression/ClangResultSynthesizer.h"
|
||||
#include "lldb/Expression/ClangStmtVisitor.h"
|
||||
#include "lldb/Symbol/ClangASTContext.h"
|
||||
#include "lldb/Expression/RecordingMemoryManager.h"
|
||||
@@ -279,19 +281,23 @@ ClangExpression::GetASTContext ()
|
||||
}
|
||||
|
||||
unsigned
|
||||
ClangExpression::ParseExpression (const char *expr_text, Stream &stream)
|
||||
ClangExpression::ParseExpression (const char *expr_text,
|
||||
Stream &stream,
|
||||
bool add_result_var)
|
||||
{
|
||||
// HACK: for now we have to make a function body around our expression
|
||||
// since there is no way to parse a single expression line in LLVM/Clang.
|
||||
std::string func_expr("void ___clang_expr()\n{\n\t");
|
||||
std::string func_expr("extern \"C\" void ___clang_expr()\n{\n\t");
|
||||
func_expr.append(expr_text);
|
||||
func_expr.append(";\n}");
|
||||
return ParseBareExpression (func_expr, stream);
|
||||
return ParseBareExpression (func_expr, stream, add_result_var);
|
||||
|
||||
}
|
||||
|
||||
unsigned
|
||||
ClangExpression::ParseBareExpression (llvm::StringRef expr_text, Stream &stream)
|
||||
ClangExpression::ParseBareExpression (llvm::StringRef expr_text,
|
||||
Stream &stream,
|
||||
bool add_result_var)
|
||||
{
|
||||
Mutex::Locker locker(GetClangMutex ());
|
||||
|
||||
@@ -354,7 +360,17 @@ ClangExpression::ParseBareExpression (llvm::StringRef expr_text, Stream &stream)
|
||||
// - CodeGeneration ASTConsumer (include/clang/ModuleBuilder.h), which will be passed in when you call...
|
||||
// - Call clang::ParseAST (in lib/Sema/ParseAST.cpp) to parse the buffer. The CodeGenerator will generate code for __dbg_expr.
|
||||
// - Once ParseAST completes, you can grab the llvm::Module from the CodeGenerator, which will have an llvm::Function you can hand off to the JIT.
|
||||
ParseAST(m_clang_ap->getPreprocessor(), m_code_generator_ptr, m_clang_ap->getASTContext());
|
||||
|
||||
if (add_result_var)
|
||||
{
|
||||
ClangResultSynthesizer result_synthesizer(m_code_generator_ptr);
|
||||
ParseAST(m_clang_ap->getPreprocessor(), &result_synthesizer, m_clang_ap->getASTContext());
|
||||
}
|
||||
else
|
||||
{
|
||||
ParseAST(m_clang_ap->getPreprocessor(), m_code_generator_ptr, m_clang_ap->getASTContext());
|
||||
}
|
||||
|
||||
|
||||
text_diagnostic_buffer.EndSourceFile();
|
||||
|
||||
@@ -413,7 +429,6 @@ ClangExpression::ParseBareExpression (llvm::StringRef expr_text, Stream &stream)
|
||||
return num_errors;
|
||||
}
|
||||
|
||||
|
||||
static FrontendAction *
|
||||
CreateFrontendAction(CompilerInstance &CI)
|
||||
{
|
||||
@@ -471,41 +486,42 @@ ClangExpression::ConvertIRToDWARF (ClangExpressionVariableList &excpr_local_vari
|
||||
return 1;
|
||||
}
|
||||
|
||||
llvm::Module::iterator fi;
|
||||
|
||||
for (fi = module->begin();
|
||||
fi != module->end();
|
||||
++fi)
|
||||
llvm::Function* function = module->getFunction(StringRef("___clang_expr"));
|
||||
|
||||
if (!function)
|
||||
{
|
||||
llvm::Function &function = *fi;
|
||||
|
||||
if (log)
|
||||
log->Printf("IR for %s:", function.getName().str().c_str());
|
||||
log->Printf("Couldn't find ___clang_expr() in the module");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (log)
|
||||
log->Printf("IR for %s:", function->getName().str().c_str());
|
||||
|
||||
llvm::Function::iterator bbi;
|
||||
|
||||
for (bbi = function->begin();
|
||||
bbi != function->end();
|
||||
++bbi)
|
||||
{
|
||||
llvm::BasicBlock &bb = *bbi;
|
||||
|
||||
llvm::Function::iterator bbi;
|
||||
llvm::BasicBlock::iterator ii;
|
||||
|
||||
for (bbi = function.begin();
|
||||
bbi != function.end();
|
||||
++bbi)
|
||||
for (ii = bb.begin();
|
||||
ii != bb.end();
|
||||
++ii)
|
||||
{
|
||||
llvm::BasicBlock &bb = *bbi;
|
||||
|
||||
llvm::BasicBlock::iterator ii;
|
||||
|
||||
for (ii = bb.begin();
|
||||
ii != bb.end();
|
||||
++ii)
|
||||
{
|
||||
llvm::Instruction &inst = *ii;
|
||||
|
||||
std::string s;
|
||||
llvm::raw_string_ostream os(s);
|
||||
|
||||
inst.print(os);
|
||||
|
||||
if (log)
|
||||
log->Printf(" %s", s.c_str());
|
||||
}
|
||||
llvm::Instruction &inst = *ii;
|
||||
|
||||
std::string s;
|
||||
llvm::raw_string_ostream os(s);
|
||||
|
||||
inst.print(os);
|
||||
|
||||
if (log)
|
||||
log->Printf(" %s", s.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
341
lldb/source/Expression/ClangResultSynthesizer.cpp
Normal file
341
lldb/source/Expression/ClangResultSynthesizer.cpp
Normal file
@@ -0,0 +1,341 @@
|
||||
//===-- ClangResultSynthesizer.cpp ------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "stdlib.h"
|
||||
#include "clang/AST/ASTContext.h"
|
||||
#include "clang/AST/Decl.h"
|
||||
#include "clang/AST/DeclCXX.h"
|
||||
#include "clang/AST/DeclGroup.h"
|
||||
#include "clang/AST/Expr.h"
|
||||
#include "clang/AST/Stmt.h"
|
||||
#include "clang/Parse/Action.h"
|
||||
#include "clang/Parse/Parser.h"
|
||||
#include "clang/Parse/Scope.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "lldb/Core/Log.h"
|
||||
#include "lldb/Expression/ClangResultSynthesizer.h"
|
||||
|
||||
using namespace llvm;
|
||||
using namespace clang;
|
||||
using namespace lldb_private;
|
||||
|
||||
ClangResultSynthesizer::ClangResultSynthesizer(ASTConsumer *passthrough) :
|
||||
m_passthrough(passthrough),
|
||||
m_passthrough_sema(NULL),
|
||||
m_sema(NULL),
|
||||
m_ast_context(NULL)
|
||||
{
|
||||
if (!m_passthrough)
|
||||
return;
|
||||
|
||||
m_passthrough_sema = dyn_cast<SemaConsumer>(passthrough);
|
||||
}
|
||||
|
||||
ClangResultSynthesizer::~ClangResultSynthesizer()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
ClangResultSynthesizer::Initialize(ASTContext &Context)
|
||||
{
|
||||
m_ast_context = &Context;
|
||||
|
||||
if (m_passthrough)
|
||||
m_passthrough->Initialize(Context);
|
||||
}
|
||||
|
||||
void
|
||||
ClangResultSynthesizer::TransformTopLevelDecl(Decl* D)
|
||||
{
|
||||
LinkageSpecDecl *linkage_spec_decl = dyn_cast<LinkageSpecDecl>(D);
|
||||
|
||||
if (linkage_spec_decl)
|
||||
{
|
||||
RecordDecl::decl_iterator decl_iterator;
|
||||
|
||||
for (decl_iterator = linkage_spec_decl->decls_begin();
|
||||
decl_iterator != linkage_spec_decl->decls_end();
|
||||
++decl_iterator)
|
||||
{
|
||||
TransformTopLevelDecl(*decl_iterator);
|
||||
}
|
||||
}
|
||||
|
||||
FunctionDecl *function_decl = dyn_cast<FunctionDecl>(D);
|
||||
|
||||
if (m_ast_context &&
|
||||
function_decl &&
|
||||
!strcmp(function_decl->getNameAsCString(),
|
||||
"___clang_expr"))
|
||||
{
|
||||
SynthesizeResult(*m_ast_context, function_decl);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ClangResultSynthesizer::HandleTopLevelDecl(DeclGroupRef D)
|
||||
{
|
||||
DeclGroupRef::iterator decl_iterator;
|
||||
|
||||
for (decl_iterator = D.begin();
|
||||
decl_iterator != D.end();
|
||||
++decl_iterator)
|
||||
{
|
||||
Decl *decl = *decl_iterator;
|
||||
|
||||
TransformTopLevelDecl(decl);
|
||||
}
|
||||
|
||||
if (m_passthrough)
|
||||
m_passthrough->HandleTopLevelDecl(D);
|
||||
}
|
||||
|
||||
bool
|
||||
ClangResultSynthesizer::SynthesizeResult (ASTContext &Ctx,
|
||||
FunctionDecl *FunDecl)
|
||||
{
|
||||
Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
|
||||
|
||||
if (!m_sema)
|
||||
return false;
|
||||
|
||||
FunctionDecl *function_decl = FunDecl;
|
||||
|
||||
if (!function_decl)
|
||||
return false;
|
||||
|
||||
Stmt *function_body = function_decl->getBody();
|
||||
CompoundStmt *compound_stmt = dyn_cast<CompoundStmt>(function_body);
|
||||
|
||||
if (!compound_stmt)
|
||||
return false;
|
||||
|
||||
if (compound_stmt->body_empty())
|
||||
return false;
|
||||
|
||||
Stmt **last_stmt_ptr = compound_stmt->body_end() - 1;
|
||||
Stmt *last_stmt = *last_stmt_ptr;
|
||||
|
||||
Expr *last_expr = dyn_cast<Expr>(last_stmt);
|
||||
|
||||
if (!last_expr)
|
||||
// No auxiliary variable necessary; expression returns void
|
||||
return true;
|
||||
|
||||
QualType expr_qual_type = last_expr->getType();
|
||||
clang::Type *expr_type = expr_qual_type.getTypePtr();
|
||||
|
||||
if (!expr_type)
|
||||
return false;
|
||||
|
||||
if (expr_type->isVoidType())
|
||||
return true;
|
||||
|
||||
if (log)
|
||||
{
|
||||
std::string s = expr_qual_type.getAsString();
|
||||
|
||||
log->Printf("Last statement's type: %s", s.c_str());
|
||||
}
|
||||
|
||||
IdentifierInfo &result_id = Ctx.Idents.get("___clang_expr_result");
|
||||
|
||||
DeclContext *decl_context = function_decl->getDeclContext();
|
||||
|
||||
clang::VarDecl *result_decl = VarDecl::Create(Ctx,
|
||||
function_decl,
|
||||
SourceLocation(),
|
||||
&result_id,
|
||||
expr_qual_type,
|
||||
NULL,
|
||||
VarDecl::Static,
|
||||
VarDecl::Static);
|
||||
|
||||
if (!result_decl)
|
||||
return false;
|
||||
|
||||
function_decl->addDecl(result_decl);
|
||||
|
||||
///////////////////////////////
|
||||
// call AddInitializerToDecl
|
||||
//
|
||||
|
||||
Parser::DeclPtrTy result_decl_ptr;
|
||||
result_decl_ptr.set(result_decl);
|
||||
|
||||
m_action->AddInitializerToDecl(result_decl_ptr, Parser::ExprArg(*m_action, last_expr));
|
||||
|
||||
/////////////////////////////////
|
||||
// call ConvertDeclToDeclGroup
|
||||
//
|
||||
|
||||
Parser::DeclGroupPtrTy result_decl_group_ptr;
|
||||
|
||||
result_decl_group_ptr = m_action->ConvertDeclToDeclGroup(result_decl_ptr);
|
||||
|
||||
////////////////////////
|
||||
// call ActOnDeclStmt
|
||||
//
|
||||
|
||||
Parser::OwningStmtResult result_initialization_stmt_result(m_action->ActOnDeclStmt(result_decl_group_ptr,
|
||||
SourceLocation(),
|
||||
SourceLocation()));
|
||||
|
||||
|
||||
///////////////////////////////////////////////
|
||||
// Synthesize external void pointer variable
|
||||
//
|
||||
|
||||
IdentifierInfo &result_ptr_id = Ctx.Idents.get("___clang_expr_result_ptr");
|
||||
|
||||
clang::VarDecl *result_ptr_decl = VarDecl::Create(Ctx,
|
||||
decl_context,
|
||||
SourceLocation(),
|
||||
&result_ptr_id,
|
||||
Ctx.VoidPtrTy,
|
||||
NULL,
|
||||
VarDecl::Extern,
|
||||
VarDecl::Extern);
|
||||
|
||||
/////////////////////////////////////////////
|
||||
// Build a DeclRef for the result variable
|
||||
//
|
||||
|
||||
DeclRefExpr *result_decl_ref_expr = DeclRefExpr::Create(Ctx,
|
||||
NULL,
|
||||
SourceRange(),
|
||||
result_decl,
|
||||
SourceLocation(),
|
||||
expr_qual_type);
|
||||
|
||||
///////////////////////
|
||||
// call ActOnUnaryOp
|
||||
//
|
||||
|
||||
Scope my_scope(NULL, (Scope::BlockScope | Scope::FnScope | Scope::DeclScope));
|
||||
|
||||
Parser::DeclPtrTy result_ptr_decl_ptr;
|
||||
result_ptr_decl_ptr.set(result_ptr_decl);
|
||||
|
||||
Parser::OwningExprResult addressof_expr_result(m_action->ActOnUnaryOp(&my_scope,
|
||||
SourceLocation(),
|
||||
tok::amp,
|
||||
Parser::ExprArg(*m_action, result_decl_ref_expr)));
|
||||
|
||||
////////////////////////////////////////////
|
||||
// Build a DeclRef for the result pointer
|
||||
//
|
||||
|
||||
DeclRefExpr *result_ptr_decl_ref_expr = DeclRefExpr::Create(Ctx,
|
||||
NULL,
|
||||
SourceRange(),
|
||||
result_ptr_decl,
|
||||
SourceLocation(),
|
||||
Ctx.VoidPtrTy);
|
||||
|
||||
////////////////////////
|
||||
// call ActOnBinaryOp
|
||||
//
|
||||
|
||||
Parser::OwningExprResult assignment_expr_result(m_action->ActOnBinOp(&my_scope,
|
||||
SourceLocation(),
|
||||
tok::equal,
|
||||
Parser::ExprArg(*m_action, result_ptr_decl_ref_expr),
|
||||
Parser::ExprArg(*m_action, addressof_expr_result.take())));
|
||||
|
||||
////////////////////////////
|
||||
// call ActOnCompoundStmt
|
||||
//
|
||||
|
||||
void *stmts[2];
|
||||
|
||||
stmts[0] = result_initialization_stmt_result.take();
|
||||
stmts[1] = assignment_expr_result.take();
|
||||
|
||||
Parser::OwningStmtResult compound_stmt_result(m_action->ActOnCompoundStmt(SourceLocation(),
|
||||
SourceLocation(),
|
||||
Parser::MultiStmtArg(*m_action, stmts, 2),
|
||||
false));
|
||||
|
||||
////////////////////////////////////////////////
|
||||
// replace the old statement with the new one
|
||||
//
|
||||
|
||||
*last_stmt_ptr = reinterpret_cast<Stmt*>(compound_stmt_result.take());
|
||||
|
||||
if (log)
|
||||
{
|
||||
std::string s;
|
||||
raw_string_ostream os(s);
|
||||
|
||||
function_decl->print(os);
|
||||
|
||||
os.flush();
|
||||
|
||||
log->Printf("Transformed function AST:\n%s", s.c_str());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
ClangResultSynthesizer::HandleTranslationUnit(ASTContext &Ctx)
|
||||
{
|
||||
if (m_passthrough)
|
||||
m_passthrough->HandleTranslationUnit(Ctx);
|
||||
}
|
||||
|
||||
void
|
||||
ClangResultSynthesizer::HandleTagDeclDefinition(TagDecl *D)
|
||||
{
|
||||
if (m_passthrough)
|
||||
m_passthrough->HandleTagDeclDefinition(D);
|
||||
}
|
||||
|
||||
void
|
||||
ClangResultSynthesizer::CompleteTentativeDefinition(VarDecl *D)
|
||||
{
|
||||
if (m_passthrough)
|
||||
m_passthrough->CompleteTentativeDefinition(D);
|
||||
}
|
||||
|
||||
void
|
||||
ClangResultSynthesizer::HandleVTable(CXXRecordDecl *RD, bool DefinitionRequired)
|
||||
{
|
||||
if (m_passthrough)
|
||||
m_passthrough->HandleVTable(RD, DefinitionRequired);
|
||||
}
|
||||
|
||||
void
|
||||
ClangResultSynthesizer::PrintStats()
|
||||
{
|
||||
if (m_passthrough)
|
||||
m_passthrough->PrintStats();
|
||||
}
|
||||
|
||||
void
|
||||
ClangResultSynthesizer::InitializeSema(Sema &S)
|
||||
{
|
||||
m_sema = &S;
|
||||
m_action = reinterpret_cast<Action*>(m_sema);
|
||||
|
||||
if (m_passthrough_sema)
|
||||
m_passthrough_sema->InitializeSema(S);
|
||||
}
|
||||
|
||||
void
|
||||
ClangResultSynthesizer::ForgetSema()
|
||||
{
|
||||
m_sema = NULL;
|
||||
m_action = NULL;
|
||||
|
||||
if (m_passthrough_sema)
|
||||
m_passthrough_sema->ForgetSema();
|
||||
}
|
||||
Reference in New Issue
Block a user