summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/lldb/source/Expression
diff options
context:
space:
mode:
authoremaste <emaste@FreeBSD.org>2014-11-26 16:48:12 +0000
committeremaste <emaste@FreeBSD.org>2014-11-26 16:48:12 +0000
commit0147dda7de9580d13778ecb4c9e92b83b7a63911 (patch)
treeb16dc95f693ed59342b6141cd3fd9f59a6cd7e7e /contrib/llvm/tools/lldb/source/Expression
parentbfd4c39c61ae9b29542625bb12b6f7f4b1f8c727 (diff)
parent01ee1789d6aa7294e5966a97f8d29387f6f81699 (diff)
downloadFreeBSD-src-0147dda7de9580d13778ecb4c9e92b83b7a63911.zip
FreeBSD-src-0147dda7de9580d13778ecb4c9e92b83b7a63911.tar.gz
Update LLDB snapshot to upstream r216948 (git 50f7fe44)
This is approximately "LLDB 3.5" although with a little bit of skew, and will go along with the Clang 3.5 import. Sponsored by: DARPA, AFRL
Diffstat (limited to 'contrib/llvm/tools/lldb/source/Expression')
-rw-r--r--contrib/llvm/tools/lldb/source/Expression/ASTResultSynthesizer.cpp218
-rw-r--r--contrib/llvm/tools/lldb/source/Expression/ASTStructExtractor.cpp64
-rw-r--r--contrib/llvm/tools/lldb/source/Expression/ClangASTSource.cpp1010
-rw-r--r--contrib/llvm/tools/lldb/source/Expression/ClangExpressionDeclMap.cpp866
-rw-r--r--contrib/llvm/tools/lldb/source/Expression/ClangExpressionParser.cpp390
-rw-r--r--contrib/llvm/tools/lldb/source/Expression/ClangExpressionVariable.cpp19
-rw-r--r--contrib/llvm/tools/lldb/source/Expression/ClangFunction.cpp88
-rw-r--r--contrib/llvm/tools/lldb/source/Expression/ClangUserExpression.cpp541
-rw-r--r--contrib/llvm/tools/lldb/source/Expression/ClangUtilityFunction.cpp37
-rw-r--r--contrib/llvm/tools/lldb/source/Expression/DWARFExpression.cpp243
-rw-r--r--contrib/llvm/tools/lldb/source/Expression/ExpressionSourceCode.cpp55
-rw-r--r--contrib/llvm/tools/lldb/source/Expression/IRDynamicChecks.cpp213
-rw-r--r--contrib/llvm/tools/lldb/source/Expression/IRExecutionUnit.cpp497
-rw-r--r--contrib/llvm/tools/lldb/source/Expression/IRForTarget.cpp1437
-rw-r--r--contrib/llvm/tools/lldb/source/Expression/IRInterpreter.cpp519
-rw-r--r--contrib/llvm/tools/lldb/source/Expression/IRMemoryMap.cpp274
-rw-r--r--contrib/llvm/tools/lldb/source/Expression/Materializer.cpp96
17 files changed, 3554 insertions, 3013 deletions
diff --git a/contrib/llvm/tools/lldb/source/Expression/ASTResultSynthesizer.cpp b/contrib/llvm/tools/lldb/source/Expression/ASTResultSynthesizer.cpp
index 76c2577..2f14721 100644
--- a/contrib/llvm/tools/lldb/source/Expression/ASTResultSynthesizer.cpp
+++ b/contrib/llvm/tools/lldb/source/Expression/ASTResultSynthesizer.cpp
@@ -40,7 +40,7 @@ ASTResultSynthesizer::ASTResultSynthesizer(ASTConsumer *passthrough,
{
if (!m_passthrough)
return;
-
+
m_passthrough_sema = dyn_cast<SemaConsumer>(passthrough);
}
@@ -49,10 +49,10 @@ ASTResultSynthesizer::~ASTResultSynthesizer()
}
void
-ASTResultSynthesizer::Initialize(ASTContext &Context)
+ASTResultSynthesizer::Initialize(ASTContext &Context)
{
m_ast_context = &Context;
-
+
if (m_passthrough)
m_passthrough->Initialize(Context);
}
@@ -75,11 +75,11 @@ ASTResultSynthesizer::TransformTopLevelDecl(Decl* D)
}
}
-
+
if (LinkageSpecDecl *linkage_spec_decl = dyn_cast<LinkageSpecDecl>(D))
{
RecordDecl::decl_iterator decl_iterator;
-
+
for (decl_iterator = linkage_spec_decl->decls_begin();
decl_iterator != linkage_spec_decl->decls_end();
++decl_iterator)
@@ -107,53 +107,53 @@ ASTResultSynthesizer::TransformTopLevelDecl(Decl* D)
}
}
-bool
+bool
ASTResultSynthesizer::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)
return m_passthrough->HandleTopLevelDecl(D);
return true;
}
-bool
+bool
ASTResultSynthesizer::SynthesizeFunctionResult (FunctionDecl *FunDecl)
{
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
+
if (!m_sema)
return false;
-
+
FunctionDecl *function_decl = FunDecl;
-
+
if (!function_decl)
return false;
-
+
if (log && log->GetVerbose())
{
std::string s;
raw_string_ostream os(s);
-
+
function_decl->print(os);
-
+
os.flush();
-
+
log->Printf ("Untransformed function AST:\n%s", s.c_str());
}
-
+
Stmt *function_body = function_decl->getBody();
CompoundStmt *compound_stmt = dyn_cast<CompoundStmt>(function_body);
-
+
bool ret = SynthesizeBodyResult (compound_stmt,
function_decl);
@@ -161,14 +161,14 @@ ASTResultSynthesizer::SynthesizeFunctionResult (FunctionDecl *FunDecl)
{
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 ret;
}
@@ -176,67 +176,67 @@ bool
ASTResultSynthesizer::SynthesizeObjCMethodResult (ObjCMethodDecl *MethodDecl)
{
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
+
if (!m_sema)
return false;
-
+
if (!MethodDecl)
return false;
-
+
if (log && log->GetVerbose())
{
std::string s;
raw_string_ostream os(s);
-
+
MethodDecl->print(os);
-
+
os.flush();
-
+
log->Printf ("Untransformed method AST:\n%s", s.c_str());
}
-
+
Stmt *method_body = MethodDecl->getBody();
-
+
if (!method_body)
return false;
-
+
CompoundStmt *compound_stmt = dyn_cast<CompoundStmt>(method_body);
-
+
bool ret = SynthesizeBodyResult (compound_stmt,
MethodDecl);
-
+
if (log && log->GetVerbose())
{
std::string s;
raw_string_ostream os(s);
-
+
MethodDecl->print(os);
-
+
os.flush();
-
+
log->Printf("Transformed method AST:\n%s", s.c_str());
}
-
+
return ret;
}
-bool
-ASTResultSynthesizer::SynthesizeBodyResult (CompoundStmt *Body,
+bool
+ASTResultSynthesizer::SynthesizeBodyResult (CompoundStmt *Body,
DeclContext *DC)
{
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
+
ASTContext &Ctx(*m_ast_context);
-
+
if (!Body)
return false;
-
+
if (Body->body_empty())
return false;
-
+
Stmt **last_stmt_ptr = Body->body_end() - 1;
Stmt *last_stmt = *last_stmt_ptr;
-
+
while (dyn_cast<NullStmt>(last_stmt))
{
if (last_stmt_ptr != Body->body_begin())
@@ -249,28 +249,28 @@ ASTResultSynthesizer::SynthesizeBodyResult (CompoundStmt *Body,
return false;
}
}
-
+
Expr *last_expr = dyn_cast<Expr>(last_stmt);
-
+
if (!last_expr)
// No auxiliary variable necessary; expression returns void
return true;
-
+
// In C++11, last_expr can be a LValueToRvalue implicit cast. Strip that off if that's the
// case.
-
+
do {
ImplicitCastExpr *implicit_cast = dyn_cast<ImplicitCastExpr>(last_expr);
-
+
if (!implicit_cast)
break;
-
+
if (implicit_cast->getCastKind() != CK_LValueToRValue)
break;
-
+
last_expr = implicit_cast->getSubExpr();
} while (0);
-
+
// is_lvalue is used to record whether the expression returns an assignable Lvalue or an
// Rvalue. This is relevant because they are handled differently.
//
@@ -302,7 +302,7 @@ ASTResultSynthesizer::SynthesizeBodyResult (CompoundStmt *Body,
//
// - In IR transformations, an instruction is inserted at the beginning of the function to
// dereference the pointer resident in the slot. Reads and writes to $__lldb_expr_result
- // are redirected at that dereferenced version. Guard variables for the static variable
+ // are redirected at that dereferenced version. Guard variables for the static variable
// are excised.
//
// - During materialization, $0 (the result persistent variable) is populated with the location
@@ -310,46 +310,46 @@ ASTResultSynthesizer::SynthesizeBodyResult (CompoundStmt *Body,
//
// - During dematerialization, $0 is ignored.
- bool is_lvalue =
+ bool is_lvalue =
(last_expr->getValueKind() == VK_LValue || last_expr->getValueKind() == VK_XValue) &&
(last_expr->getObjectKind() == OK_Ordinary);
-
+
QualType expr_qual_type = last_expr->getType();
const 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 is an %s with type: %s", (is_lvalue ? "lvalue" : "rvalue"), s.c_str());
}
-
+
clang::VarDecl *result_decl = NULL;
-
+
if (is_lvalue)
{
IdentifierInfo *result_ptr_id;
-
+
if (expr_type->isFunctionType())
result_ptr_id = &Ctx.Idents.get("$__lldb_expr_result"); // functions actually should be treated like function pointers
else
result_ptr_id = &Ctx.Idents.get("$__lldb_expr_result_ptr");
-
+
m_sema->RequireCompleteType(SourceLocation(), expr_qual_type, clang::diag::err_incomplete_type);
-
+
QualType ptr_qual_type;
if (expr_qual_type->getAs<ObjCObjectType>() != NULL)
ptr_qual_type = Ctx.getObjCObjectPointerType(expr_qual_type);
else
ptr_qual_type = Ctx.getPointerType(expr_qual_type);
-
+
result_decl = VarDecl::Create(Ctx,
DC,
SourceLocation(),
@@ -358,69 +358,69 @@ ASTResultSynthesizer::SynthesizeBodyResult (CompoundStmt *Body,
ptr_qual_type,
NULL,
SC_Static);
-
+
if (!result_decl)
return false;
-
+
ExprResult address_of_expr = m_sema->CreateBuiltinUnaryOp(SourceLocation(), UO_AddrOf, last_expr);
-
- m_sema->AddInitializerToDecl(result_decl, address_of_expr.take(), true, false);
+
+ m_sema->AddInitializerToDecl(result_decl, address_of_expr.get(), true, false);
}
else
{
IdentifierInfo &result_id = Ctx.Idents.get("$__lldb_expr_result");
-
- result_decl = VarDecl::Create(Ctx,
- DC,
+
+ result_decl = VarDecl::Create(Ctx,
+ DC,
SourceLocation(),
SourceLocation(),
- &result_id,
- expr_qual_type,
- NULL,
+ &result_id,
+ expr_qual_type,
+ NULL,
SC_Static);
-
+
if (!result_decl)
return false;
-
+
m_sema->AddInitializerToDecl(result_decl, last_expr, true, false);
}
-
+
DC->addDecl(result_decl);
-
+
///////////////////////////////
// call AddInitializerToDecl
//
-
+
//m_sema->AddInitializerToDecl(result_decl, last_expr);
-
+
/////////////////////////////////
// call ConvertDeclToDeclGroup
//
-
+
Sema::DeclGroupPtrTy result_decl_group_ptr;
-
+
result_decl_group_ptr = m_sema->ConvertDeclToDeclGroup(result_decl);
-
+
////////////////////////
// call ActOnDeclStmt
//
-
+
StmtResult result_initialization_stmt_result(m_sema->ActOnDeclStmt(result_decl_group_ptr,
SourceLocation(),
SourceLocation()));
-
+
////////////////////////////////////////////////
// replace the old statement with the new one
//
-
- *last_stmt_ptr = reinterpret_cast<Stmt*>(result_initialization_stmt_result.take());
+
+ *last_stmt_ptr = reinterpret_cast<Stmt*>(result_initialization_stmt_result.get());
return true;
}
void
ASTResultSynthesizer::HandleTranslationUnit(ASTContext &Ctx)
-{
+{
if (m_passthrough)
m_passthrough->HandleTranslationUnit(Ctx);
}
@@ -429,8 +429,8 @@ void
ASTResultSynthesizer::RecordPersistentTypes(DeclContext *FunDeclCtx)
{
typedef DeclContext::specific_decl_iterator<TypeDecl> TypeDeclIterator;
-
- for (TypeDeclIterator i = TypeDeclIterator(FunDeclCtx->decls_begin()),
+
+ for (TypeDeclIterator i = TypeDeclIterator(FunDeclCtx->decls_begin()),
e = TypeDeclIterator(FunDeclCtx->decls_end());
i != e;
++i)
@@ -439,35 +439,35 @@ ASTResultSynthesizer::RecordPersistentTypes(DeclContext *FunDeclCtx)
}
}
-void
+void
ASTResultSynthesizer::MaybeRecordPersistentType(TypeDecl *D)
{
if (!D->getIdentifier())
return;
-
+
StringRef name = D->getName();
-
+
if (name.size() == 0 || name[0] != '$')
return;
-
+
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
ConstString name_cs(name.str().c_str());
-
+
if (log)
log->Printf ("Recording persistent type %s\n", name_cs.GetCString());
-
- Decl *D_scratch = m_target.GetClangASTImporter()->DeportDecl(m_target.GetScratchClangASTContext()->getASTContext(),
+
+ Decl *D_scratch = m_target.GetClangASTImporter()->DeportDecl(m_target.GetScratchClangASTContext()->getASTContext(),
m_ast_context,
D);
-
+
if (TypeDecl *TypeDecl_scratch = dyn_cast<TypeDecl>(D_scratch))
m_target.GetPersistentVariables().RegisterPersistentType(name_cs, TypeDecl_scratch);
}
-void
+void
ASTResultSynthesizer::HandleTagDeclDefinition(TagDecl *D)
-{
+{
if (m_passthrough)
m_passthrough->HandleTagDeclDefinition(D);
}
@@ -479,15 +479,15 @@ ASTResultSynthesizer::CompleteTentativeDefinition(VarDecl *D)
m_passthrough->CompleteTentativeDefinition(D);
}
-void
-ASTResultSynthesizer::HandleVTable(CXXRecordDecl *RD, bool DefinitionRequired)
+void
+ASTResultSynthesizer::HandleVTable(CXXRecordDecl *RD, bool DefinitionRequired)
{
if (m_passthrough)
m_passthrough->HandleVTable(RD, DefinitionRequired);
}
void
-ASTResultSynthesizer::PrintStats()
+ASTResultSynthesizer::PrintStats()
{
if (m_passthrough)
m_passthrough->PrintStats();
@@ -497,16 +497,16 @@ void
ASTResultSynthesizer::InitializeSema(Sema &S)
{
m_sema = &S;
-
+
if (m_passthrough_sema)
m_passthrough_sema->InitializeSema(S);
}
-void
-ASTResultSynthesizer::ForgetSema()
+void
+ASTResultSynthesizer::ForgetSema()
{
m_sema = NULL;
-
+
if (m_passthrough_sema)
m_passthrough_sema->ForgetSema();
}
diff --git a/contrib/llvm/tools/lldb/source/Expression/ASTStructExtractor.cpp b/contrib/llvm/tools/lldb/source/Expression/ASTStructExtractor.cpp
index d1f2192..2a8b7bc 100644
--- a/contrib/llvm/tools/lldb/source/Expression/ASTStructExtractor.cpp
+++ b/contrib/llvm/tools/lldb/source/Expression/ASTStructExtractor.cpp
@@ -39,7 +39,7 @@ ASTStructExtractor::ASTStructExtractor(ASTConsumer *passthrough,
{
if (!m_passthrough)
return;
-
+
m_passthrough_sema = dyn_cast<SemaConsumer>(passthrough);
}
@@ -48,10 +48,10 @@ ASTStructExtractor::~ASTStructExtractor()
}
void
-ASTStructExtractor::Initialize(ASTContext &Context)
+ASTStructExtractor::Initialize(ASTContext &Context)
{
m_ast_context = &Context;
-
+
if (m_passthrough)
m_passthrough->Initialize(Context);
}
@@ -61,17 +61,17 @@ ASTStructExtractor::ExtractFromFunctionDecl(FunctionDecl *F)
{
if (!F->hasBody())
return;
-
+
Stmt *body_stmt = F->getBody();
CompoundStmt *body_compound_stmt = dyn_cast<CompoundStmt>(body_stmt);
-
+
if (!body_compound_stmt)
return; // do we have to handle this?
-
+
RecordDecl *struct_decl = NULL;
-
+
StringRef desired_name(m_struct_name.c_str());
-
+
for (CompoundStmt::const_body_iterator bi = body_compound_stmt->body_begin(), be = body_compound_stmt->body_end();
bi != be;
++bi)
@@ -95,26 +95,26 @@ ASTStructExtractor::ExtractFromFunctionDecl(FunctionDecl *F)
if (struct_decl)
break;
}
-
+
if (!struct_decl)
return;
-
+
const ASTRecordLayout* struct_layout(&m_ast_context->getASTRecordLayout (struct_decl));
-
+
if (!struct_layout)
return;
-
- m_function.m_struct_size = struct_layout->getSize().getQuantity(); // TODO Store m_struct_size as CharUnits
+
+ m_function.m_struct_size = struct_layout->getSize().getQuantity(); // TODO Store m_struct_size as CharUnits
m_function.m_return_offset = struct_layout->getFieldOffset(struct_layout->getFieldCount() - 1) / 8;
m_function.m_return_size = struct_layout->getDataSize().getQuantity() - m_function.m_return_offset;
-
+
for (unsigned field_index = 0, num_fields = struct_layout->getFieldCount();
field_index < num_fields;
++field_index)
{
m_function.m_member_offsets.push_back(struct_layout->getFieldOffset(field_index) / 8);
}
-
+
m_function.m_struct_valid = true;
}
@@ -122,11 +122,11 @@ void
ASTStructExtractor::ExtractFromTopLevelDecl(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)
@@ -134,9 +134,9 @@ ASTStructExtractor::ExtractFromTopLevelDecl(Decl* D)
ExtractFromTopLevelDecl(*decl_iterator);
}
}
-
+
FunctionDecl *function_decl = dyn_cast<FunctionDecl>(D);
-
+
if (m_ast_context &&
function_decl &&
!m_function.m_wrapper_function_name.compare(function_decl->getNameAsString().c_str()))
@@ -145,20 +145,20 @@ ASTStructExtractor::ExtractFromTopLevelDecl(Decl* D)
}
}
-bool
+bool
ASTStructExtractor::HandleTopLevelDecl(DeclGroupRef D)
{
DeclGroupRef::iterator decl_iterator;
-
+
for (decl_iterator = D.begin();
decl_iterator != D.end();
++decl_iterator)
{
Decl *decl = *decl_iterator;
-
+
ExtractFromTopLevelDecl(decl);
}
-
+
if (m_passthrough)
return m_passthrough->HandleTopLevelDecl(D);
return true;
@@ -166,12 +166,12 @@ ASTStructExtractor::HandleTopLevelDecl(DeclGroupRef D)
void
ASTStructExtractor::HandleTranslationUnit(ASTContext &Ctx)
-{
+{
if (m_passthrough)
m_passthrough->HandleTranslationUnit(Ctx);
}
-void
+void
ASTStructExtractor::HandleTagDeclDefinition(TagDecl *D)
{
if (m_passthrough)
@@ -185,15 +185,15 @@ ASTStructExtractor::CompleteTentativeDefinition(VarDecl *D)
m_passthrough->CompleteTentativeDefinition(D);
}
-void
-ASTStructExtractor::HandleVTable(CXXRecordDecl *RD, bool DefinitionRequired)
+void
+ASTStructExtractor::HandleVTable(CXXRecordDecl *RD, bool DefinitionRequired)
{
if (m_passthrough)
m_passthrough->HandleVTable(RD, DefinitionRequired);
}
void
-ASTStructExtractor::PrintStats()
+ASTStructExtractor::PrintStats()
{
if (m_passthrough)
m_passthrough->PrintStats();
@@ -204,17 +204,17 @@ ASTStructExtractor::InitializeSema(Sema &S)
{
m_sema = &S;
m_action = reinterpret_cast<Action*>(m_sema);
-
+
if (m_passthrough_sema)
m_passthrough_sema->InitializeSema(S);
}
-void
-ASTStructExtractor::ForgetSema()
+void
+ASTStructExtractor::ForgetSema()
{
m_sema = NULL;
m_action = NULL;
-
+
if (m_passthrough_sema)
m_passthrough_sema->ForgetSema();
}
diff --git a/contrib/llvm/tools/lldb/source/Expression/ClangASTSource.cpp b/contrib/llvm/tools/lldb/source/Expression/ClangASTSource.cpp
index 853d102..d488993 100644
--- a/contrib/llvm/tools/lldb/source/Expression/ClangASTSource.cpp
+++ b/contrib/llvm/tools/lldb/source/Expression/ClangASTSource.cpp
@@ -25,32 +25,32 @@
using namespace clang;
using namespace lldb_private;
-ClangASTSource::~ClangASTSource()
+ClangASTSource::~ClangASTSource()
{
m_ast_importer->ForgetDestination(m_ast_context);
-
+
// We are in the process of destruction, don't create clang ast context on demand
// by passing false to Target::GetScratchClangASTContext(create_on_demand).
ClangASTContext *scratch_clang_ast_context = m_target->GetScratchClangASTContext(false);
-
+
if (!scratch_clang_ast_context)
return;
-
+
clang::ASTContext *scratch_ast_context = scratch_clang_ast_context->getASTContext();
-
+
if (!scratch_ast_context)
return;
-
+
if (m_ast_context != scratch_ast_context)
m_ast_importer->ForgetSource(scratch_ast_context, m_ast_context);
}
void
-ClangASTSource::StartTranslationUnit(ASTConsumer *Consumer)
+ClangASTSource::StartTranslationUnit(ASTConsumer *Consumer)
{
if (!m_ast_context)
return;
-
+
m_ast_context->getTranslationUnitDecl()->setHasExternalVisibleStorage();
m_ast_context->getTranslationUnitDecl()->setHasExternalLexicalStorage();
}
@@ -59,33 +59,33 @@ ClangASTSource::StartTranslationUnit(ASTConsumer *Consumer)
bool
ClangASTSource::FindExternalVisibleDeclsByName
(
- const DeclContext *decl_ctx,
+ const DeclContext *decl_ctx,
DeclarationName clang_decl_name
-)
+)
{
if (!m_ast_context)
{
SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
return false;
}
-
+
if (GetImportInProgress())
{
SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
return false;
}
-
+
std::string decl_name (clang_decl_name.getAsString());
// if (m_decl_map.DoingASTImport ())
// return DeclContext::lookup_result();
-//
+//
switch (clang_decl_name.getNameKind()) {
// Normal identifiers.
case DeclarationName::Identifier:
{
clang::IdentifierInfo *identifier_info = clang_decl_name.getAsIdentifierInfo();
-
+
if (!identifier_info ||
identifier_info->getBuiltinID() != 0)
{
@@ -94,27 +94,27 @@ ClangASTSource::FindExternalVisibleDeclsByName
}
}
break;
-
+
// Operator names. Not important for now.
case DeclarationName::CXXOperatorName:
case DeclarationName::CXXLiteralOperatorName:
SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
return false;
-
+
// Using directives found in this context.
// Tell Sema we didn't find any or we'll end up getting asked a *lot*.
case DeclarationName::CXXUsingDirective:
SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
return false;
-
+
case DeclarationName::ObjCZeroArgSelector:
case DeclarationName::ObjCOneArgSelector:
case DeclarationName::ObjCMultiArgSelector:
{
- llvm::SmallVector<NamedDecl*, 1> method_decls;
+ llvm::SmallVector<NamedDecl*, 1> method_decls;
NameSearchContext method_search_context (*this, method_decls, clang_decl_name, decl_ctx);
-
+
FindObjCMethodDecls(method_search_context);
SetExternalVisibleDeclsForName (decl_ctx, clang_decl_name, method_decls);
@@ -131,21 +131,21 @@ ClangASTSource::FindExternalVisibleDeclsByName
if (!GetLookupsEnabled())
{
- // Wait until we see a '$' at the start of a name before we start doing
+ // Wait until we see a '$' at the start of a name before we start doing
// any lookups so we can avoid lookup up all of the builtin types.
if (!decl_name.empty() && decl_name[0] == '$')
{
SetLookupsEnabled (true);
}
else
- {
+ {
SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
return false;
}
}
ConstString const_decl_name(decl_name.c_str());
-
+
const char *uniqued_const_decl_name = const_decl_name.GetCString();
if (m_active_lookups.find (uniqued_const_decl_name) != m_active_lookups.end())
{
@@ -157,7 +157,7 @@ ClangASTSource::FindExternalVisibleDeclsByName
// static uint32_t g_depth = 0;
// ++g_depth;
// printf("[%5u] FindExternalVisibleDeclsByName() \"%s\"\n", g_depth, uniqued_const_decl_name);
- llvm::SmallVector<NamedDecl*, 4> name_decls;
+ llvm::SmallVector<NamedDecl*, 4> name_decls;
NameSearchContext name_search_context(*this, name_decls, clang_decl_name, decl_ctx);
FindExternalVisibleDecls(name_search_context);
SetExternalVisibleDeclsForName (decl_ctx, clang_decl_name, name_decls);
@@ -168,50 +168,48 @@ ClangASTSource::FindExternalVisibleDeclsByName
void
ClangASTSource::CompleteType (TagDecl *tag_decl)
-{
+{
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
+
static unsigned int invocation_id = 0;
unsigned int current_id = invocation_id++;
-
+
if (log)
{
- log->Printf(" CompleteTagDecl[%u] on (ASTContext*)%p Completing (TagDecl*)%p named %s",
- current_id,
- m_ast_context,
- tag_decl,
+ log->Printf(" CompleteTagDecl[%u] on (ASTContext*)%p Completing (TagDecl*)%p named %s",
+ current_id, static_cast<void*>(m_ast_context),
+ static_cast<void*>(tag_decl),
tag_decl->getName().str().c_str());
-
+
log->Printf(" CTD[%u] Before:", current_id);
ASTDumper dumper((Decl*)tag_decl);
dumper.ToLog(log, " [CTD] ");
}
-
+
if (!m_ast_importer->CompleteTagDecl (tag_decl))
{
// We couldn't complete the type. Maybe there's a definition
// somewhere else that can be completed.
-
+
if (log)
log->Printf(" CTD[%u] Type could not be completed in the module in which it was first found.", current_id);
-
+
bool found = false;
DeclContext *decl_ctx = tag_decl->getDeclContext();
-
+
if (const NamespaceDecl *namespace_context = dyn_cast<NamespaceDecl>(decl_ctx))
{
ClangASTImporter::NamespaceMapSP namespace_map = m_ast_importer->GetNamespaceMap(namespace_context);
-
+
if (log && log->GetVerbose())
- log->Printf(" CTD[%u] Inspecting namespace map %p (%d entries)",
- current_id,
- namespace_map.get(),
- (int)namespace_map->size());
-
+ log->Printf(" CTD[%u] Inspecting namespace map %p (%d entries)",
+ current_id, static_cast<void*>(namespace_map.get()),
+ static_cast<int>(namespace_map->size()));
+
if (!namespace_map)
return;
-
+
for (ClangASTImporter::NamespaceMap::iterator i = namespace_map->begin(), e = namespace_map->end();
i != e && !found;
++i)
@@ -221,80 +219,80 @@ ClangASTSource::CompleteType (TagDecl *tag_decl)
current_id,
i->second.GetNamespaceDecl()->getNameAsString().c_str(),
i->first->GetFileSpec().GetFilename().GetCString());
-
+
TypeList types;
-
+
SymbolContext null_sc;
ConstString name(tag_decl->getName().str().c_str());
-
+
i->first->FindTypesInNamespace(null_sc, name, &i->second, UINT32_MAX, types);
-
+
for (uint32_t ti = 0, te = types.GetSize();
ti != te && !found;
++ti)
{
lldb::TypeSP type = types.GetTypeAtIndex(ti);
-
+
if (!type)
continue;
-
+
ClangASTType clang_type (type->GetClangFullType());
-
+
if (!clang_type)
continue;
-
+
const TagType *tag_type = clang_type.GetQualType()->getAs<TagType>();
-
+
if (!tag_type)
continue;
-
+
TagDecl *candidate_tag_decl = const_cast<TagDecl*>(tag_type->getDecl());
-
+
if (m_ast_importer->CompleteTagDeclWithOrigin (tag_decl, candidate_tag_decl))
found = true;
}
}
}
- else
+ else
{
TypeList types;
-
+
SymbolContext null_sc;
ConstString name(tag_decl->getName().str().c_str());
ClangNamespaceDecl namespace_decl;
-
+
const ModuleList &module_list = m_target->GetImages();
bool exact_match = false;
module_list.FindTypes (null_sc, name, exact_match, UINT32_MAX, types);
-
+
for (uint32_t ti = 0, te = types.GetSize();
ti != te && !found;
++ti)
{
lldb::TypeSP type = types.GetTypeAtIndex(ti);
-
+
if (!type)
continue;
-
+
ClangASTType clang_type (type->GetClangFullType());
-
+
if (!clang_type)
continue;
-
+
const TagType *tag_type = clang_type.GetQualType()->getAs<TagType>();
-
+
if (!tag_type)
continue;
-
+
TagDecl *candidate_tag_decl = const_cast<TagDecl*>(tag_type->getDecl());
-
+
if (m_ast_importer->CompleteTagDeclWithOrigin (tag_decl, candidate_tag_decl))
found = true;
}
}
}
-
+
if (log)
{
log->Printf(" [CTD] After:");
@@ -305,28 +303,46 @@ ClangASTSource::CompleteType (TagDecl *tag_decl)
void
ClangASTSource::CompleteType (clang::ObjCInterfaceDecl *interface_decl)
-{
+{
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
+
if (log)
{
- log->Printf(" [CompleteObjCInterfaceDecl] on (ASTContext*)%p Completing an ObjCInterfaceDecl named %s", m_ast_context, interface_decl->getName().str().c_str());
+ log->Printf(" [CompleteObjCInterfaceDecl] on (ASTContext*)%p Completing an ObjCInterfaceDecl named %s",
+ static_cast<void*>(m_ast_context),
+ interface_decl->getName().str().c_str());
log->Printf(" [COID] Before:");
ASTDumper dumper((Decl*)interface_decl);
- dumper.ToLog(log, " [COID] ");
+ dumper.ToLog(log, " [COID] ");
+ }
+
+ Decl *original_decl = NULL;
+ ASTContext *original_ctx = NULL;
+
+ if (m_ast_importer->ResolveDeclOrigin(interface_decl, &original_decl, &original_ctx))
+ {
+ if (ObjCInterfaceDecl *original_iface_decl = dyn_cast<ObjCInterfaceDecl>(original_decl))
+ {
+ ObjCInterfaceDecl *complete_iface_decl = GetCompleteObjCInterface(original_iface_decl);
+
+ if (complete_iface_decl && (complete_iface_decl != original_iface_decl))
+ {
+ m_ast_importer->SetDeclOrigin(interface_decl, original_iface_decl);
+ }
+ }
}
-
+
m_ast_importer->CompleteObjCInterfaceDecl (interface_decl);
-
+
if (interface_decl->getSuperClass() &&
interface_decl->getSuperClass() != interface_decl)
CompleteType(interface_decl->getSuperClass());
-
+
if (log)
{
log->Printf(" [COID] After:");
ASTDumper dumper((Decl*)interface_decl);
- dumper.ToLog(log, " [COID] ");
+ dumper.ToLog(log, " [COID] ");
}
}
@@ -334,36 +350,36 @@ clang::ObjCInterfaceDecl *
ClangASTSource::GetCompleteObjCInterface (clang::ObjCInterfaceDecl *interface_decl)
{
lldb::ProcessSP process(m_target->GetProcessSP());
-
+
if (!process)
return NULL;
-
+
ObjCLanguageRuntime *language_runtime(process->GetObjCLanguageRuntime());
-
+
if (!language_runtime)
return NULL;
-
+
ConstString class_name(interface_decl->getNameAsString().c_str());
-
+
lldb::TypeSP complete_type_sp(language_runtime->LookupInCompleteClassCache(class_name));
-
+
if (!complete_type_sp)
return NULL;
-
+
TypeFromUser complete_type = TypeFromUser(complete_type_sp->GetClangFullType());
lldb::clang_type_t complete_opaque_type = complete_type.GetOpaqueQualType();
-
+
if (!complete_opaque_type)
return NULL;
-
+
const clang::Type *complete_clang_type = QualType::getFromOpaquePtr(complete_opaque_type).getTypePtr();
const ObjCInterfaceType *complete_interface_type = dyn_cast<ObjCInterfaceType>(complete_clang_type);
-
+
if (!complete_interface_type)
return NULL;
-
+
ObjCInterfaceDecl *complete_iface_decl(complete_interface_type->getDecl());
-
+
return complete_iface_decl;
}
@@ -375,83 +391,82 @@ ClangASTSource::FindExternalLexicalDecls (const DeclContext *decl_context,
ClangASTMetrics::RegisterLexicalQuery();
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
+
const Decl *context_decl = dyn_cast<Decl>(decl_context);
-
+
if (!context_decl)
return ELR_Failure;
-
+
static unsigned int invocation_id = 0;
unsigned int current_id = invocation_id++;
-
+
if (log)
{
if (const NamedDecl *context_named_decl = dyn_cast<NamedDecl>(context_decl))
log->Printf("FindExternalLexicalDecls[%u] on (ASTContext*)%p in '%s' (%sDecl*)%p with %s predicate",
- current_id,
- m_ast_context,
+ current_id, static_cast<void*>(m_ast_context),
context_named_decl->getNameAsString().c_str(),
context_decl->getDeclKindName(),
- context_decl,
+ static_cast<const void*>(context_decl),
(predicate ? "non-null" : "null"));
else if(context_decl)
log->Printf("FindExternalLexicalDecls[%u] on (ASTContext*)%p in (%sDecl*)%p with %s predicate",
- current_id,
- m_ast_context,
- context_decl->getDeclKindName(),
- context_decl,
+ current_id, static_cast<void*>(m_ast_context),
+ context_decl->getDeclKindName(),
+ static_cast<const void*>(context_decl),
(predicate ? "non-null" : "null"));
else
log->Printf("FindExternalLexicalDecls[%u] on (ASTContext*)%p in a NULL context with %s predicate",
- current_id,
- m_ast_context,
+ current_id, static_cast<const void*>(m_ast_context),
(predicate ? "non-null" : "null"));
}
-
+
Decl *original_decl = NULL;
ASTContext *original_ctx = NULL;
-
+
if (!m_ast_importer->ResolveDeclOrigin(context_decl, &original_decl, &original_ctx))
return ELR_Failure;
-
+
if (log)
- {
- log->Printf(" FELD[%u] Original decl (ASTContext*)%p (Decl*)%p:", current_id, original_ctx, original_decl);
+ {
+ log->Printf(" FELD[%u] Original decl (ASTContext*)%p (Decl*)%p:",
+ current_id, static_cast<void*>(original_ctx),
+ static_cast<void*>(original_decl));
ASTDumper(original_decl).ToLog(log, " ");
}
-
+
if (ObjCInterfaceDecl *original_iface_decl = dyn_cast<ObjCInterfaceDecl>(original_decl))
{
ObjCInterfaceDecl *complete_iface_decl = GetCompleteObjCInterface(original_iface_decl);
-
+
if (complete_iface_decl && (complete_iface_decl != original_iface_decl))
{
original_decl = complete_iface_decl;
original_ctx = &complete_iface_decl->getASTContext();
-
+
m_ast_importer->SetDeclOrigin(context_decl, original_iface_decl);
}
}
-
+
if (TagDecl *original_tag_decl = dyn_cast<TagDecl>(original_decl))
{
ExternalASTSource *external_source = original_ctx->getExternalSource();
-
+
if (external_source)
external_source->CompleteType (original_tag_decl);
}
-
+
const DeclContext *original_decl_context = dyn_cast<DeclContext>(original_decl);
-
+
if (!original_decl_context)
return ELR_Failure;
-
+
for (TagDecl::decl_iterator iter = original_decl_context->decls_begin();
iter != original_decl_context->decls_end();
++iter)
{
Decl *decl = *iter;
-
+
if (!predicate || predicate(decl->getKind()))
{
if (log)
@@ -462,35 +477,35 @@ ClangASTSource::FindExternalLexicalDecls (const DeclContext *decl_context,
else
log->Printf(" FELD[%d] Adding lexical %sDecl %s", current_id, decl->getDeclKindName(), ast_dumper.GetCString());
}
-
+
Decl *copied_decl = m_ast_importer->CopyDecl(m_ast_context, original_ctx, decl);
-
+
if (!copied_decl)
continue;
-
+
if (FieldDecl *copied_field = dyn_cast<FieldDecl>(copied_decl))
{
QualType copied_field_type = copied_field->getType();
-
+
m_ast_importer->RequireCompleteType(copied_field_type);
}
-
+
decls.push_back(copied_decl);
-
+
DeclContext *decl_context_non_const = const_cast<DeclContext *>(decl_context);
-
+
if (copied_decl->getDeclContext() != decl_context)
{
if (copied_decl->getDeclContext()->containsDecl(copied_decl))
copied_decl->getDeclContext()->removeDecl(copied_decl);
copied_decl->setDeclContext(decl_context_non_const);
}
-
+
if (!decl_context_non_const->containsDecl(copied_decl))
decl_context_non_const->addDeclInternal(copied_decl);
}
}
-
+
return ELR_AlreadyLoaded;
}
@@ -498,41 +513,48 @@ void
ClangASTSource::FindExternalVisibleDecls (NameSearchContext &context)
{
assert (m_ast_context);
-
+
ClangASTMetrics::RegisterVisibleQuery();
-
+
const ConstString name(context.m_decl_name.getAsString().c_str());
-
+
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
+
static unsigned int invocation_id = 0;
unsigned int current_id = invocation_id++;
-
+
if (log)
{
if (!context.m_decl_context)
- log->Printf("ClangASTSource::FindExternalVisibleDecls[%u] on (ASTContext*)%p for '%s' in a NULL DeclContext", current_id, m_ast_context, name.GetCString());
+ log->Printf("ClangASTSource::FindExternalVisibleDecls[%u] on (ASTContext*)%p for '%s' in a NULL DeclContext",
+ current_id, static_cast<void*>(m_ast_context),
+ name.GetCString());
else if (const NamedDecl *context_named_decl = dyn_cast<NamedDecl>(context.m_decl_context))
- log->Printf("ClangASTSource::FindExternalVisibleDecls[%u] on (ASTContext*)%p for '%s' in '%s'", current_id, m_ast_context, name.GetCString(), context_named_decl->getNameAsString().c_str());
+ log->Printf("ClangASTSource::FindExternalVisibleDecls[%u] on (ASTContext*)%p for '%s' in '%s'",
+ current_id, static_cast<void*>(m_ast_context),
+ name.GetCString(),
+ context_named_decl->getNameAsString().c_str());
else
- log->Printf("ClangASTSource::FindExternalVisibleDecls[%u] on (ASTContext*)%p for '%s' in a '%s'", current_id, m_ast_context, name.GetCString(), context.m_decl_context->getDeclKindName());
+ log->Printf("ClangASTSource::FindExternalVisibleDecls[%u] on (ASTContext*)%p for '%s' in a '%s'",
+ current_id, static_cast<void*>(m_ast_context),
+ name.GetCString(),
+ context.m_decl_context->getDeclKindName());
}
-
+
context.m_namespace_map.reset(new ClangASTImporter::NamespaceMap);
-
+
if (const NamespaceDecl *namespace_context = dyn_cast<NamespaceDecl>(context.m_decl_context))
{
ClangASTImporter::NamespaceMapSP namespace_map = m_ast_importer->GetNamespaceMap(namespace_context);
-
+
if (log && log->GetVerbose())
- log->Printf(" CAS::FEVD[%u] Inspecting namespace map %p (%d entries)",
- current_id,
- namespace_map.get(),
- (int)namespace_map->size());
-
+ log->Printf(" CAS::FEVD[%u] Inspecting namespace map %p (%d entries)",
+ current_id, static_cast<void*>(namespace_map.get()),
+ static_cast<int>(namespace_map->size()));
+
if (!namespace_map)
return;
-
+
for (ClangASTImporter::NamespaceMap::iterator i = namespace_map->begin(), e = namespace_map->end();
i != e;
++i)
@@ -542,7 +564,7 @@ ClangASTSource::FindExternalVisibleDecls (NameSearchContext &context)
current_id,
i->second.GetNamespaceDecl()->getNameAsString().c_str(),
i->first->GetFileSpec().GetFilename().GetCString());
-
+
FindExternalVisibleDecls(context,
i->first,
i->second,
@@ -561,158 +583,158 @@ ClangASTSource::FindExternalVisibleDecls (NameSearchContext &context)
else
{
ClangNamespaceDecl namespace_decl;
-
+
if (log)
log->Printf(" CAS::FEVD[%u] Searching the root namespace", current_id);
-
+
FindExternalVisibleDecls(context,
lldb::ModuleSP(),
namespace_decl,
current_id);
}
-
+
if (!context.m_namespace_map->empty())
{
if (log && log->GetVerbose())
- log->Printf(" CAS::FEVD[%u] Registering namespace map %p (%d entries)",
+ log->Printf(" CAS::FEVD[%u] Registering namespace map %p (%d entries)",
current_id,
- context.m_namespace_map.get(),
- (int)context.m_namespace_map->size());
-
+ static_cast<void*>(context.m_namespace_map.get()),
+ static_cast<int>(context.m_namespace_map->size()));
+
NamespaceDecl *clang_namespace_decl = AddNamespace(context, context.m_namespace_map);
-
+
if (clang_namespace_decl)
clang_namespace_decl->setHasExternalVisibleStorage();
}
}
-void
-ClangASTSource::FindExternalVisibleDecls (NameSearchContext &context,
+void
+ClangASTSource::FindExternalVisibleDecls (NameSearchContext &context,
lldb::ModuleSP module_sp,
ClangNamespaceDecl &namespace_decl,
unsigned int current_id)
{
assert (m_ast_context);
-
+
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
+
SymbolContextList sc_list;
-
+
const ConstString name(context.m_decl_name.getAsString().c_str());
-
+
const char *name_unique_cstr = name.GetCString();
-
+
static ConstString id_name("id");
static ConstString Class_name("Class");
-
+
if (name == id_name || name == Class_name)
return;
-
+
if (name_unique_cstr == NULL)
return;
-
+
// The ClangASTSource is not responsible for finding $-names.
if (name_unique_cstr[0] == '$')
return;
-
+
if (module_sp && namespace_decl)
{
ClangNamespaceDecl found_namespace_decl;
-
+
SymbolVendor *symbol_vendor = module_sp->GetSymbolVendor();
-
+
if (symbol_vendor)
{
SymbolContext null_sc;
-
+
found_namespace_decl = symbol_vendor->FindNamespace(null_sc, name, &namespace_decl);
-
+
if (found_namespace_decl)
{
context.m_namespace_map->push_back(std::pair<lldb::ModuleSP, ClangNamespaceDecl>(module_sp, found_namespace_decl));
-
+
if (log)
log->Printf(" CAS::FEVD[%u] Found namespace %s in module %s",
current_id,
- name.GetCString(),
+ name.GetCString(),
module_sp->GetFileSpec().GetFilename().GetCString());
}
}
}
- else
+ else
{
const ModuleList &target_images = m_target->GetImages();
Mutex::Locker modules_locker (target_images.GetMutex());
-
+
for (size_t i = 0, e = target_images.GetSize(); i < e; ++i)
{
lldb::ModuleSP image = target_images.GetModuleAtIndexUnlocked(i);
-
+
if (!image)
continue;
-
+
ClangNamespaceDecl found_namespace_decl;
-
+
SymbolVendor *symbol_vendor = image->GetSymbolVendor();
-
+
if (!symbol_vendor)
continue;
-
+
SymbolContext null_sc;
-
+
found_namespace_decl = symbol_vendor->FindNamespace(null_sc, name, &namespace_decl);
-
+
if (found_namespace_decl)
{
context.m_namespace_map->push_back(std::pair<lldb::ModuleSP, ClangNamespaceDecl>(image, found_namespace_decl));
-
+
if (log)
log->Printf(" CAS::FEVD[%u] Found namespace %s in module %s",
current_id,
- name.GetCString(),
+ name.GetCString(),
image->GetFileSpec().GetFilename().GetCString());
}
}
}
-
- do
+
+ do
{
TypeList types;
SymbolContext null_sc;
const bool exact_match = false;
-
+
if (module_sp && namespace_decl)
module_sp->FindTypesInNamespace(null_sc, name, &namespace_decl, 1, types);
- else
+ else
m_target->GetImages().FindTypes(null_sc, name, exact_match, 1, types);
-
+
if (types.GetSize())
{
lldb::TypeSP type_sp = types.GetTypeAtIndex(0);
-
+
if (log)
{
const char *name_string = type_sp->GetName().GetCString();
-
- log->Printf(" CAS::FEVD[%u] Matching type found for \"%s\": %s",
- current_id,
- name.GetCString(),
+
+ log->Printf(" CAS::FEVD[%u] Matching type found for \"%s\": %s",
+ current_id,
+ name.GetCString(),
(name_string ? name_string : "<anonymous>"));
}
-
+
ClangASTType full_type = type_sp->GetClangFullType();
ClangASTType copied_clang_type (GuardedCopyType(full_type));
-
+
if (!copied_clang_type)
- {
+ {
if (log)
log->Printf(" CAS::FEVD[%u] - Couldn't export a type",
current_id);
-
+
break;
}
-
+
context.AddTypeDecl(copied_clang_type);
}
else
@@ -720,55 +742,55 @@ ClangASTSource::FindExternalVisibleDecls (NameSearchContext &context,
do
{
// Couldn't find any types elsewhere. Try the Objective-C runtime if one exists.
-
+
lldb::ProcessSP process(m_target->GetProcessSP());
-
+
if (!process)
break;
-
+
ObjCLanguageRuntime *language_runtime(process->GetObjCLanguageRuntime());
-
+
if (!language_runtime)
break;
-
+
TypeVendor *type_vendor = language_runtime->GetTypeVendor();
-
+
if (!type_vendor)
break;
-
+
bool append = false;
uint32_t max_matches = 1;
std::vector <ClangASTType> types;
-
+
if (!type_vendor->FindTypes(name,
append,
max_matches,
types))
break;
-
+
if (log)
- {
+ {
log->Printf(" CAS::FEVD[%u] Matching type found for \"%s\" in the runtime",
current_id,
name.GetCString());
}
-
+
ClangASTType copied_clang_type (GuardedCopyType(types[0]));
-
+
if (!copied_clang_type)
{
if (log)
log->Printf(" CAS::FEVD[%u] - Couldn't export a type from the runtime",
current_id);
-
+
break;
}
-
+
context.AddTypeDecl(copied_clang_type);
}
while(0);
}
-
+
} while(0);
}
@@ -782,7 +804,7 @@ public:
D *decl;
};
-template <class D2, template <class D> class TD, class D1>
+template <class D2, template <class D> class TD, class D1>
TD<D2>
DynCast(TD<D1> source)
{
@@ -792,19 +814,19 @@ DynCast(TD<D1> source)
template <class D = Decl> class DeclFromParser;
template <class D = Decl> class DeclFromUser;
-template <class D> class DeclFromParser : public TaggedASTDecl<D> {
+template <class D> class DeclFromParser : public TaggedASTDecl<D> {
public:
DeclFromParser() : TaggedASTDecl<D>() { }
DeclFromParser(D *_decl) : TaggedASTDecl<D>(_decl) { }
-
+
DeclFromUser<D> GetOrigin(ClangASTImporter *importer);
};
-template <class D> class DeclFromUser : public TaggedASTDecl<D> {
+template <class D> class DeclFromUser : public TaggedASTDecl<D> {
public:
DeclFromUser() : TaggedASTDecl<D>() { }
DeclFromUser(D *_decl) : TaggedASTDecl<D>(_decl) { }
-
+
DeclFromParser<D> Import(ClangASTImporter *importer, ASTContext &dest_ctx);
};
@@ -841,7 +863,7 @@ FindObjCMethodDeclsWithOrigin (unsigned int current_id,
clang::ASTContext *original_ctx = &original_interface_decl->getASTContext();
Selector original_selector;
-
+
if (decl_name.isObjCZeroArgSelector())
{
IdentifierInfo *ident = &original_ctx->Idents.get(decl_name.getAsString());
@@ -857,59 +879,59 @@ FindObjCMethodDeclsWithOrigin (unsigned int current_id,
else
{
SmallVector<IdentifierInfo *, 4> idents;
-
+
clang::Selector sel = decl_name.getObjCSelector();
-
+
unsigned num_args = sel.getNumArgs();
-
+
for (unsigned i = 0;
i != num_args;
++i)
{
idents.push_back(&original_ctx->Idents.get(sel.getNameForSlot(i)));
}
-
+
original_selector = original_ctx->Selectors.getSelector(num_args, idents.data());
}
-
+
DeclarationName original_decl_name(original_selector);
-
+
ObjCInterfaceDecl::lookup_result result = original_interface_decl->lookup(original_decl_name);
-
+
if (result.empty())
return false;
-
+
if (!result[0])
return false;
-
+
for (NamedDecl *named_decl : result)
{
ObjCMethodDecl *result_method = dyn_cast<ObjCMethodDecl>(named_decl);
-
+
if (!result_method)
return false;
-
+
Decl *copied_decl = ast_importer->CopyDecl(ast_context, &result_method->getASTContext(), result_method);
-
+
if (!copied_decl)
return false;
-
+
ObjCMethodDecl *copied_method_decl = dyn_cast<ObjCMethodDecl>(copied_decl);
-
+
if (!copied_method_decl)
return false;
-
+
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
+
if (log)
{
ASTDumper dumper((Decl*)copied_method_decl);
log->Printf(" CAS::FOMD[%d] found (%s) %s", current_id, log_info, dumper.GetCString());
}
-
+
context.AddNamedDecl(copied_method_decl);
}
-
+
return true;
}
@@ -917,30 +939,30 @@ void
ClangASTSource::FindObjCMethodDecls (NameSearchContext &context)
{
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
+
static unsigned int invocation_id = 0;
unsigned int current_id = invocation_id++;
-
+
const DeclarationName &decl_name(context.m_decl_name);
const DeclContext *decl_ctx(context.m_decl_context);
-
+
const ObjCInterfaceDecl *interface_decl = dyn_cast<ObjCInterfaceDecl>(decl_ctx);
-
+
if (!interface_decl)
return;
-
+
do
{
Decl *original_decl = NULL;
ASTContext *original_ctx = NULL;
-
+
m_ast_importer->ResolveDeclOrigin(interface_decl, &original_decl, &original_ctx);
-
+
if (!original_decl)
break;
-
+
ObjCInterfaceDecl *original_interface_decl = dyn_cast<ObjCInterfaceDecl>(original_decl);
-
+
if (FindObjCMethodDeclsWithOrigin(current_id,
context,
original_interface_decl,
@@ -949,9 +971,9 @@ ClangASTSource::FindObjCMethodDecls (NameSearchContext &context)
"at origin"))
return; // found it, no need to look any further
} while (0);
-
+
StreamString ss;
-
+
if (decl_name.isObjCZeroArgSelector())
{
ss.Printf("%s", decl_name.getAsString().c_str());
@@ -961,234 +983,232 @@ ClangASTSource::FindObjCMethodDecls (NameSearchContext &context)
ss.Printf("%s", decl_name.getAsString().c_str());
}
else
- {
+ {
clang::Selector sel = decl_name.getObjCSelector();
-
+
for (unsigned i = 0, e = sel.getNumArgs();
i != e;
++i)
{
llvm::StringRef r = sel.getNameForSlot(i);
- ss.Printf("%s:", r.str().c_str());
+ ss.Printf("%s:", r.str().c_str());
}
- }
+ }
ss.Flush();
-
+
if (strstr(ss.GetData(), "$__lldb"))
return; // we don't need any results
-
+
ConstString selector_name(ss.GetData());
-
+
if (log)
log->Printf("ClangASTSource::FindObjCMethodDecls[%d] on (ASTContext*)%p for selector [%s %s]",
- current_id,
- m_ast_context,
- interface_decl->getNameAsString().c_str(),
+ current_id, static_cast<void*>(m_ast_context),
+ interface_decl->getNameAsString().c_str(),
selector_name.AsCString());
SymbolContextList sc_list;
-
+
const bool include_symbols = false;
const bool include_inlines = false;
const bool append = false;
-
+
std::string interface_name = interface_decl->getNameAsString();
-
+
do
{
StreamString ms;
ms.Printf("-[%s %s]", interface_name.c_str(), selector_name.AsCString());
ms.Flush();
ConstString instance_method_name(ms.GetData());
-
+
m_target->GetImages().FindFunctions(instance_method_name, lldb::eFunctionNameTypeFull, include_symbols, include_inlines, append, sc_list);
-
+
if (sc_list.GetSize())
break;
-
+
ms.Clear();
ms.Printf("+[%s %s]", interface_name.c_str(), selector_name.AsCString());
ms.Flush();
ConstString class_method_name(ms.GetData());
-
+
m_target->GetImages().FindFunctions(class_method_name, lldb::eFunctionNameTypeFull, include_symbols, include_inlines, append, sc_list);
-
+
if (sc_list.GetSize())
break;
-
+
// Fall back and check for methods in categories. If we find methods this way, we need to check that they're actually in
// categories on the desired class.
-
+
SymbolContextList candidate_sc_list;
-
+
m_target->GetImages().FindFunctions(selector_name, lldb::eFunctionNameTypeSelector, include_symbols, include_inlines, append, candidate_sc_list);
-
+
for (uint32_t ci = 0, ce = candidate_sc_list.GetSize();
ci != ce;
++ci)
{
SymbolContext candidate_sc;
-
+
if (!candidate_sc_list.GetContextAtIndex(ci, candidate_sc))
continue;
-
+
if (!candidate_sc.function)
continue;
-
+
const char *candidate_name = candidate_sc.function->GetName().AsCString();
-
+
const char *cursor = candidate_name;
-
+
if (*cursor != '+' && *cursor != '-')
continue;
-
+
++cursor;
-
+
if (*cursor != '[')
continue;
-
+
++cursor;
-
+
size_t interface_len = interface_name.length();
-
+
if (strncmp(cursor, interface_name.c_str(), interface_len))
continue;
-
+
cursor += interface_len;
-
+
if (*cursor == ' ' || *cursor == '(')
sc_list.Append(candidate_sc);
}
}
while (0);
-
+
if (sc_list.GetSize())
{
// We found a good function symbol. Use that.
-
+
for (uint32_t i = 0, e = sc_list.GetSize();
i != e;
++i)
{
SymbolContext sc;
-
+
if (!sc_list.GetContextAtIndex(i, sc))
continue;
-
+
if (!sc.function)
continue;
-
+
DeclContext *function_ctx = sc.function->GetClangDeclContext();
-
+
if (!function_ctx)
continue;
-
+
ObjCMethodDecl *method_decl = dyn_cast<ObjCMethodDecl>(function_ctx);
-
+
if (!method_decl)
continue;
-
+
ObjCInterfaceDecl *found_interface_decl = method_decl->getClassInterface();
-
+
if (!found_interface_decl)
continue;
-
+
if (found_interface_decl->getName() == interface_decl->getName())
{
Decl *copied_decl = m_ast_importer->CopyDecl(m_ast_context, &method_decl->getASTContext(), method_decl);
-
+
if (!copied_decl)
continue;
-
+
ObjCMethodDecl *copied_method_decl = dyn_cast<ObjCMethodDecl>(copied_decl);
-
+
if (!copied_method_decl)
continue;
-
+
if (log)
{
ASTDumper dumper((Decl*)copied_method_decl);
log->Printf(" CAS::FOMD[%d] found (in symbols) %s", current_id, dumper.GetCString());
}
-
+
context.AddNamedDecl(copied_method_decl);
}
}
-
+
return;
}
-
+
// Try the debug information.
-
+
do
{
ObjCInterfaceDecl *complete_interface_decl = GetCompleteObjCInterface(const_cast<ObjCInterfaceDecl*>(interface_decl));
-
+
if (!complete_interface_decl)
break;
-
+
// We found the complete interface. The runtime never needs to be queried in this scenario.
-
+
DeclFromUser<const ObjCInterfaceDecl> complete_iface_decl(complete_interface_decl);
-
+
if (complete_interface_decl == interface_decl)
break; // already checked this one
-
+
if (log)
log->Printf("CAS::FOPD[%d] trying origin (ObjCInterfaceDecl*)%p/(ASTContext*)%p...",
- current_id,
- complete_interface_decl,
- &complete_iface_decl->getASTContext());
-
+ current_id, static_cast<void*>(complete_interface_decl),
+ static_cast<void*>(&complete_iface_decl->getASTContext()));
+
FindObjCMethodDeclsWithOrigin(current_id,
context,
complete_interface_decl,
m_ast_context,
m_ast_importer,
"in debug info");
-
+
return;
}
while (0);
-
+
do
{
// Check the runtime only if the debug information didn't have a complete interface.
-
+
lldb::ProcessSP process(m_target->GetProcessSP());
-
+
if (!process)
break;
-
+
ObjCLanguageRuntime *language_runtime(process->GetObjCLanguageRuntime());
-
+
if (!language_runtime)
break;
-
+
TypeVendor *type_vendor = language_runtime->GetTypeVendor();
-
+
if (!type_vendor)
break;
-
+
ConstString interface_name(interface_decl->getNameAsString().c_str());
bool append = false;
uint32_t max_matches = 1;
std::vector <ClangASTType> types;
-
+
if (!type_vendor->FindTypes(interface_name,
append,
max_matches,
types))
break;
-
+
const clang::Type *runtime_clang_type = QualType::getFromOpaquePtr(types[0].GetOpaqueQualType()).getTypePtr();
-
+
const ObjCInterfaceType *runtime_interface_type = dyn_cast<ObjCInterfaceType>(runtime_clang_type);
-
+
if (!runtime_interface_type)
break;
-
+
ObjCInterfaceDecl *runtime_interface_decl = runtime_interface_type->getDecl();
-
+
FindObjCMethodDeclsWithOrigin(current_id,
context,
runtime_interface_decl,
@@ -1200,7 +1220,7 @@ ClangASTSource::FindObjCMethodDecls (NameSearchContext &context)
}
static bool
-FindObjCPropertyAndIvarDeclsWithOrigin (unsigned int current_id,
+FindObjCPropertyAndIvarDeclsWithOrigin (unsigned int current_id,
NameSearchContext &context,
clang::ASTContext &ast_context,
ClangASTImporter *ast_importer,
@@ -1210,15 +1230,15 @@ FindObjCPropertyAndIvarDeclsWithOrigin (unsigned int current_id,
if (origin_iface_decl.IsInvalid())
return false;
-
+
std::string name_str = context.m_decl_name.getAsString();
StringRef name(name_str.c_str());
IdentifierInfo &name_identifier(origin_iface_decl->getASTContext().Idents.get(name));
-
+
DeclFromUser<ObjCPropertyDecl> origin_property_decl(origin_iface_decl->FindPropertyDeclaration(&name_identifier));
-
+
bool found = false;
-
+
if (origin_property_decl.IsValid())
{
DeclFromParser<ObjCPropertyDecl> parser_property_decl(origin_property_decl.Import(ast_importer, ast_context));
@@ -1229,14 +1249,14 @@ FindObjCPropertyAndIvarDeclsWithOrigin (unsigned int current_id,
ASTDumper dumper((Decl*)parser_property_decl.decl);
log->Printf(" CAS::FOPD[%d] found %s", current_id, dumper.GetCString());
}
-
+
context.AddNamedDecl(parser_property_decl.decl);
found = true;
}
}
-
+
DeclFromUser<ObjCIvarDecl> origin_ivar_decl(origin_iface_decl->getIvarDecl(&name_identifier));
-
+
if (origin_ivar_decl.IsValid())
{
DeclFromParser<ObjCIvarDecl> parser_ivar_decl(origin_ivar_decl.Import(ast_importer, ast_context));
@@ -1247,12 +1267,12 @@ FindObjCPropertyAndIvarDeclsWithOrigin (unsigned int current_id,
ASTDumper dumper((Decl*)parser_ivar_decl.decl);
log->Printf(" CAS::FOPD[%d] found %s", current_id, dumper.GetCString());
}
-
+
context.AddNamedDecl(parser_ivar_decl.decl);
found = true;
}
}
-
+
return found;
}
@@ -1263,109 +1283,107 @@ ClangASTSource::FindObjCPropertyAndIvarDecls (NameSearchContext &context)
static unsigned int invocation_id = 0;
unsigned int current_id = invocation_id++;
-
+
DeclFromParser<const ObjCInterfaceDecl> parser_iface_decl(cast<ObjCInterfaceDecl>(context.m_decl_context));
DeclFromUser<const ObjCInterfaceDecl> origin_iface_decl(parser_iface_decl.GetOrigin(m_ast_importer));
ConstString class_name(parser_iface_decl->getNameAsString().c_str());
-
+
if (log)
log->Printf("ClangASTSource::FindObjCPropertyAndIvarDecls[%d] on (ASTContext*)%p for '%s.%s'",
- current_id,
- m_ast_context,
- parser_iface_decl->getNameAsString().c_str(),
+ current_id, static_cast<void*>(m_ast_context),
+ parser_iface_decl->getNameAsString().c_str(),
context.m_decl_name.getAsString().c_str());
-
- if (FindObjCPropertyAndIvarDeclsWithOrigin(current_id,
- context,
- *m_ast_context,
- m_ast_importer,
+
+ if (FindObjCPropertyAndIvarDeclsWithOrigin(current_id,
+ context,
+ *m_ast_context,
+ m_ast_importer,
origin_iface_decl))
return;
-
+
if (log)
log->Printf("CAS::FOPD[%d] couldn't find the property on origin (ObjCInterfaceDecl*)%p/(ASTContext*)%p, searching elsewhere...",
- current_id,
- origin_iface_decl.decl,
- &origin_iface_decl->getASTContext());
-
+ current_id, static_cast<const void*>(origin_iface_decl.decl),
+ static_cast<void*>(&origin_iface_decl->getASTContext()));
+
SymbolContext null_sc;
TypeList type_list;
-
+
do
{
ObjCInterfaceDecl *complete_interface_decl = GetCompleteObjCInterface(const_cast<ObjCInterfaceDecl*>(parser_iface_decl.decl));
-
+
if (!complete_interface_decl)
break;
-
+
// We found the complete interface. The runtime never needs to be queried in this scenario.
-
+
DeclFromUser<const ObjCInterfaceDecl> complete_iface_decl(complete_interface_decl);
-
+
if (complete_iface_decl.decl == origin_iface_decl.decl)
break; // already checked this one
-
+
if (log)
log->Printf("CAS::FOPD[%d] trying origin (ObjCInterfaceDecl*)%p/(ASTContext*)%p...",
current_id,
- complete_iface_decl.decl,
- &complete_iface_decl->getASTContext());
-
- FindObjCPropertyAndIvarDeclsWithOrigin(current_id,
- context,
- *m_ast_context,
- m_ast_importer,
+ static_cast<const void*>(complete_iface_decl.decl),
+ static_cast<void*>(&complete_iface_decl->getASTContext()));
+
+ FindObjCPropertyAndIvarDeclsWithOrigin(current_id,
+ context,
+ *m_ast_context,
+ m_ast_importer,
complete_iface_decl);
-
+
return;
}
while(0);
-
+
do
{
// Check the runtime only if the debug information didn't have a complete interface.
-
+
lldb::ProcessSP process(m_target->GetProcessSP());
-
+
if (!process)
return;
-
+
ObjCLanguageRuntime *language_runtime(process->GetObjCLanguageRuntime());
-
+
if (!language_runtime)
return;
-
+
TypeVendor *type_vendor = language_runtime->GetTypeVendor();
-
+
if (!type_vendor)
break;
-
+
bool append = false;
uint32_t max_matches = 1;
std::vector <ClangASTType> types;
-
+
if (!type_vendor->FindTypes(class_name,
append,
max_matches,
types))
break;
-
+
const clang::Type *runtime_clang_type = QualType::getFromOpaquePtr(types[0].GetOpaqueQualType()).getTypePtr();
const ObjCInterfaceType *runtime_interface_type = dyn_cast<ObjCInterfaceType>(runtime_clang_type);
-
+
if (!runtime_interface_type)
break;
-
+
DeclFromUser<const ObjCInterfaceDecl> runtime_iface_decl(runtime_interface_type->getDecl());
-
+
if (log)
log->Printf("CAS::FOPD[%d] trying runtime (ObjCInterfaceDecl*)%p/(ASTContext*)%p...",
current_id,
- runtime_iface_decl.decl,
- &runtime_iface_decl->getASTContext());
-
+ static_cast<const void*>(runtime_iface_decl.decl),
+ static_cast<void*>(&runtime_iface_decl->getASTContext()));
+
if (FindObjCPropertyAndIvarDeclsWithOrigin(current_id,
context,
*m_ast_context,
@@ -1381,13 +1399,13 @@ typedef llvm::DenseMap <const CXXRecordDecl *, CharUnits> BaseOffsetMap;
template <class D, class O>
static bool
-ImportOffsetMap (llvm::DenseMap <const D*, O> &destination_map,
+ImportOffsetMap (llvm::DenseMap <const D*, O> &destination_map,
llvm::DenseMap <const D*, O> &source_map,
ClangASTImporter *importer,
ASTContext &dest_ctx)
{
typedef llvm::DenseMap <const D*, O> MapType;
-
+
for (typename MapType::iterator fi = source_map.begin(), fe = source_map.end();
fi != fe;
++fi)
@@ -1398,7 +1416,7 @@ ImportOffsetMap (llvm::DenseMap <const D*, O> &destination_map,
return false;
destination_map.insert(std::pair<const D *, O>(parser_decl.decl, fi->second));
}
-
+
return true;
}
@@ -1406,102 +1424,98 @@ template <bool IsVirtual> bool ExtractBaseOffsets (const ASTRecordLayout &record
DeclFromUser<const CXXRecordDecl> &record,
BaseOffsetMap &base_offsets)
{
- for (CXXRecordDecl::base_class_const_iterator
- bi = (IsVirtual ? record->vbases_begin() : record->bases_begin()),
+ for (CXXRecordDecl::base_class_const_iterator
+ bi = (IsVirtual ? record->vbases_begin() : record->bases_begin()),
be = (IsVirtual ? record->vbases_end() : record->bases_end());
bi != be;
++bi)
{
if (!IsVirtual && bi->isVirtual())
continue;
-
+
const clang::Type *origin_base_type = bi->getType().getTypePtr();
const clang::RecordType *origin_base_record_type = origin_base_type->getAs<RecordType>();
-
+
if (!origin_base_record_type)
return false;
-
+
DeclFromUser <RecordDecl> origin_base_record(origin_base_record_type->getDecl());
-
+
if (origin_base_record.IsInvalid())
return false;
-
+
DeclFromUser <CXXRecordDecl> origin_base_cxx_record(DynCast<CXXRecordDecl>(origin_base_record));
-
+
if (origin_base_cxx_record.IsInvalid())
return false;
-
+
CharUnits base_offset;
-
+
if (IsVirtual)
base_offset = record_layout.getVBaseClassOffset(origin_base_cxx_record.decl);
else
base_offset = record_layout.getBaseClassOffset(origin_base_cxx_record.decl);
-
+
base_offsets.insert(std::pair<const CXXRecordDecl *, CharUnits>(origin_base_cxx_record.decl, base_offset));
}
-
+
return true;
}
-
-bool
+
+bool
ClangASTSource::layoutRecordType(const RecordDecl *record,
- uint64_t &size,
+ uint64_t &size,
uint64_t &alignment,
FieldOffsetMap &field_offsets,
BaseOffsetMap &base_offsets,
BaseOffsetMap &virtual_base_offsets)
{
ClangASTMetrics::RegisterRecordLayout();
-
+
static unsigned int invocation_id = 0;
unsigned int current_id = invocation_id++;
-
+
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
+
if (log)
- {
log->Printf("LayoutRecordType[%u] on (ASTContext*)%p for (RecordDecl*)%p [name = '%s']",
- current_id,
- m_ast_context,
- record,
+ current_id, static_cast<void*>(m_ast_context),
+ static_cast<const void*>(record),
record->getNameAsString().c_str());
- }
-
-
+
DeclFromParser <const RecordDecl> parser_record(record);
DeclFromUser <const RecordDecl> origin_record(parser_record.GetOrigin(m_ast_importer));
-
+
if (origin_record.IsInvalid())
return false;
-
+
FieldOffsetMap origin_field_offsets;
BaseOffsetMap origin_base_offsets;
BaseOffsetMap origin_virtual_base_offsets;
-
+
ClangASTContext::GetCompleteDecl(&origin_record->getASTContext(), const_cast<RecordDecl*>(origin_record.decl));
-
+
if (!origin_record.decl->getDefinition())
return false;
-
+
const ASTRecordLayout &record_layout(origin_record->getASTContext().getASTRecordLayout(origin_record.decl));
-
+
int field_idx = 0, field_count = record_layout.getFieldCount();
-
+
for (RecordDecl::field_iterator fi = origin_record->field_begin(), fe = origin_record->field_end();
fi != fe;
++fi)
{
if (field_idx >= field_count)
return false; // Layout didn't go well. Bail out.
-
+
uint64_t field_offset = record_layout.getFieldOffset(field_idx);
-
+
origin_field_offsets.insert(std::pair<const FieldDecl *, uint64_t>(*fi, field_offset));
-
+
field_idx++;
}
-
+
ASTContext &parser_ast_context(record->getASTContext());
DeclFromUser <const CXXRecordDecl> origin_cxx_record(DynCast<const CXXRecordDecl>(origin_record));
@@ -1517,14 +1531,15 @@ ClangASTSource::layoutRecordType(const RecordDecl *record,
!ImportOffsetMap(base_offsets, origin_base_offsets, m_ast_importer, parser_ast_context) ||
!ImportOffsetMap(virtual_base_offsets, origin_virtual_base_offsets, m_ast_importer, parser_ast_context))
return false;
-
+
size = record_layout.getSize().getQuantity() * m_ast_context->getCharWidth();
alignment = record_layout.getAlignment().getQuantity() * m_ast_context->getCharWidth();
-
+
if (log)
{
log->Printf("LRT[%u] returned:", current_id);
- log->Printf("LRT[%u] Original = (RecordDecl*)%p", current_id, origin_record.decl);
+ log->Printf("LRT[%u] Original = (RecordDecl*)%p", current_id,
+ static_cast<const void*>(origin_record.decl));
log->Printf("LRT[%u] Size = %" PRId64, current_id, size);
log->Printf("LRT[%u] Alignment = %" PRId64, current_id, alignment);
log->Printf("LRT[%u] Fields:", current_id);
@@ -1533,10 +1548,8 @@ ClangASTSource::layoutRecordType(const RecordDecl *record,
++fi)
{
log->Printf("LRT[%u] (FieldDecl*)%p, Name = '%s', Offset = %" PRId64 " bits",
- current_id,
- *fi,
- fi->getNameAsString().c_str(),
- field_offsets[*fi]);
+ current_id, static_cast<void*>(*fi),
+ fi->getNameAsString().c_str(), field_offsets[*fi]);
}
DeclFromParser <const CXXRecordDecl> parser_cxx_record = DynCast<const CXXRecordDecl>(parser_record);
if (parser_cxx_record.IsValid())
@@ -1547,19 +1560,19 @@ ClangASTSource::layoutRecordType(const RecordDecl *record,
++bi)
{
bool is_virtual = bi->isVirtual();
-
+
QualType base_type = bi->getType();
const RecordType *base_record_type = base_type->getAs<RecordType>();
DeclFromParser <RecordDecl> base_record(base_record_type->getDecl());
DeclFromParser <CXXRecordDecl> base_cxx_record = DynCast<CXXRecordDecl>(base_record);
-
+
log->Printf("LRT[%u] %s(CXXRecordDecl*)%p, Name = '%s', Offset = %" PRId64 " chars",
- current_id,
- (is_virtual ? "Virtual " : ""),
- base_cxx_record.decl,
+ current_id, (is_virtual ? "Virtual " : ""),
+ static_cast<void*>(base_cxx_record.decl),
base_cxx_record.decl->getNameAsString().c_str(),
- (is_virtual ? virtual_base_offsets[base_cxx_record.decl].getQuantity() :
- base_offsets[base_cxx_record.decl].getQuantity()));
+ (is_virtual
+ ? virtual_base_offsets[base_cxx_record.decl].getQuantity()
+ : base_offsets[base_cxx_record.decl].getQuantity()));
}
}
else
@@ -1567,36 +1580,33 @@ ClangASTSource::layoutRecordType(const RecordDecl *record,
log->Printf("LRD[%u] Not a CXXRecord, so no bases", current_id);
}
}
-
+
return true;
}
-void
+void
ClangASTSource::CompleteNamespaceMap (ClangASTImporter::NamespaceMapSP &namespace_map,
const ConstString &name,
ClangASTImporter::NamespaceMapSP &parent_map) const
{
static unsigned int invocation_id = 0;
unsigned int current_id = invocation_id++;
-
+
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
+
if (log)
{
if (parent_map && parent_map->size())
log->Printf("CompleteNamespaceMap[%u] on (ASTContext*)%p Searching for namespace %s in namespace %s",
- current_id,
- m_ast_context,
+ current_id, static_cast<void*>(m_ast_context),
name.GetCString(),
parent_map->begin()->second.GetNamespaceDecl()->getDeclName().getAsString().c_str());
else
log->Printf("CompleteNamespaceMap[%u] on (ASTContext*)%p Searching for namespace %s",
- current_id,
- m_ast_context,
+ current_id, static_cast<void*>(m_ast_context),
name.GetCString());
}
-
-
+
if (parent_map)
{
for (ClangASTImporter::NamespaceMap::iterator i = parent_map->begin(), e = parent_map->end();
@@ -1604,28 +1614,28 @@ ClangASTSource::CompleteNamespaceMap (ClangASTImporter::NamespaceMapSP &namespac
++i)
{
ClangNamespaceDecl found_namespace_decl;
-
+
lldb::ModuleSP module_sp = i->first;
ClangNamespaceDecl module_parent_namespace_decl = i->second;
-
+
SymbolVendor *symbol_vendor = module_sp->GetSymbolVendor();
-
+
if (!symbol_vendor)
continue;
-
+
SymbolContext null_sc;
-
+
found_namespace_decl = symbol_vendor->FindNamespace(null_sc, name, &module_parent_namespace_decl);
-
+
if (!found_namespace_decl)
continue;
-
+
namespace_map->push_back(std::pair<lldb::ModuleSP, ClangNamespaceDecl>(module_sp, found_namespace_decl));
-
+
if (log)
log->Printf(" CMN[%u] Found namespace %s in module %s",
current_id,
- name.GetCString(),
+ name.GetCString(),
module_sp->GetFileSpec().GetFilename().GetCString());
}
}
@@ -1633,36 +1643,36 @@ ClangASTSource::CompleteNamespaceMap (ClangASTImporter::NamespaceMapSP &namespac
{
const ModuleList &target_images = m_target->GetImages();
Mutex::Locker modules_locker(target_images.GetMutex());
-
+
ClangNamespaceDecl null_namespace_decl;
-
+
for (size_t i = 0, e = target_images.GetSize(); i < e; ++i)
{
lldb::ModuleSP image = target_images.GetModuleAtIndexUnlocked(i);
-
+
if (!image)
continue;
-
+
ClangNamespaceDecl found_namespace_decl;
-
+
SymbolVendor *symbol_vendor = image->GetSymbolVendor();
-
+
if (!symbol_vendor)
continue;
-
+
SymbolContext null_sc;
-
+
found_namespace_decl = symbol_vendor->FindNamespace(null_sc, name, &null_namespace_decl);
-
+
if (!found_namespace_decl)
continue;
-
+
namespace_map->push_back(std::pair<lldb::ModuleSP, ClangNamespaceDecl>(image, found_namespace_decl));
-
+
if (log)
log->Printf(" CMN[%u] Found namespace %s in module %s",
current_id,
- name.GetCString(),
+ name.GetCString(),
image->GetFileSpec().GetFilename().GetCString());
}
}
@@ -1673,23 +1683,23 @@ ClangASTSource::AddNamespace (NameSearchContext &context, ClangASTImporter::Name
{
if (!namespace_decls)
return NULL;
-
+
const ClangNamespaceDecl &namespace_decl = namespace_decls->begin()->second;
-
+
Decl *copied_decl = m_ast_importer->CopyDecl(m_ast_context, namespace_decl.GetASTContext(), namespace_decl.GetNamespaceDecl());
-
+
if (!copied_decl)
return NULL;
-
+
NamespaceDecl *copied_namespace_decl = dyn_cast<NamespaceDecl>(copied_decl);
-
+
if (!copied_namespace_decl)
return NULL;
-
+
context.m_decls.push_back(copied_namespace_decl);
-
+
m_ast_importer->RegisterNamespaceMap(copied_namespace_decl, namespace_decls);
-
+
return dyn_cast<NamespaceDecl>(copied_decl);
}
@@ -1697,18 +1707,18 @@ ClangASTType
ClangASTSource::GuardedCopyType (const ClangASTType &src_type)
{
ClangASTMetrics::RegisterLLDBImport();
-
+
SetImportInProgress(true);
-
+
QualType copied_qual_type = m_ast_importer->CopyType (m_ast_context, src_type.GetASTContext(), src_type.GetQualType());
-
+
SetImportInProgress(false);
-
+
if (copied_qual_type.getAsOpaquePtr() && copied_qual_type->getCanonicalTypeInternal().isNull())
// this shouldn't happen, but we're hardening because the AST importer seems to be generating bad types
// on occasion.
return ClangASTType();
-
+
return ClangASTType(m_ast_context, copied_qual_type);
}
@@ -1719,39 +1729,39 @@ NameSearchContext::AddVarDecl(const ClangASTType &type)
if (!type.IsValid())
return NULL;
-
+
IdentifierInfo *ii = m_decl_name.getAsIdentifierInfo();
-
+
clang::ASTContext *ast = type.GetASTContext();
clang::NamedDecl *Decl = VarDecl::Create(*ast,
- const_cast<DeclContext*>(m_decl_context),
- SourceLocation(),
+ const_cast<DeclContext*>(m_decl_context),
+ SourceLocation(),
SourceLocation(),
- ii,
+ ii,
type.GetQualType(),
- 0,
+ 0,
SC_Static);
m_decls.push_back(Decl);
-
+
return Decl;
}
clang::NamedDecl *
-NameSearchContext::AddFunDecl (const ClangASTType &type)
+NameSearchContext::AddFunDecl (const ClangASTType &type)
{
assert (type && "Type for variable must be valid!");
-
+
if (!type.IsValid())
return NULL;
if (m_function_types.count(type))
return NULL;
-
+
m_function_types.insert(type);
-
+
QualType qual_type (type.GetQualType());
-
+
clang::ASTContext *ast = type.GetASTContext();
const bool isInlineSpecified = false;
@@ -1773,20 +1783,20 @@ NameSearchContext::AddFunDecl (const ClangASTType &type)
// We have to do more than just synthesize the FunctionDecl. We have to
// synthesize ParmVarDecls for all of the FunctionDecl's arguments. To do
// this, we raid the function's FunctionProtoType for types.
-
+
const FunctionProtoType *func_proto_type = qual_type.getTypePtr()->getAs<FunctionProtoType>();
-
+
if (func_proto_type)
- {
+ {
unsigned NumArgs = func_proto_type->getNumParams();
unsigned ArgIndex;
-
+
SmallVector<ParmVarDecl *, 5> parm_var_decls;
-
+
for (ArgIndex = 0; ArgIndex < NumArgs; ++ArgIndex)
{
QualType arg_qual_type (func_proto_type->getParamType(ArgIndex));
-
+
parm_var_decls.push_back(ParmVarDecl::Create (*ast,
const_cast<DeclContext*>(m_decl_context),
SourceLocation(),
@@ -1797,7 +1807,7 @@ NameSearchContext::AddFunDecl (const ClangASTType &type)
SC_Static,
NULL));
}
-
+
func_decl->setParams(ArrayRef<ParmVarDecl*>(parm_var_decls));
}
else
@@ -1807,9 +1817,9 @@ NameSearchContext::AddFunDecl (const ClangASTType &type)
if (log)
log->Printf("Function type wasn't a FunctionProtoType");
}
-
+
m_decls.push_back(func_decl);
-
+
return func_decl;
}
@@ -1817,13 +1827,13 @@ clang::NamedDecl *
NameSearchContext::AddGenericFunDecl()
{
FunctionProtoType::ExtProtoInfo proto_info;
-
+
proto_info.Variadic = true;
-
+
QualType generic_function_type(m_ast_source.m_ast_context->getFunctionType (m_ast_source.m_ast_context->UnknownAnyTy, // result
ArrayRef<QualType>(), // argument types
proto_info));
-
+
return AddFunDecl(ClangASTType (m_ast_source.m_ast_context, generic_function_type));
}
@@ -1837,32 +1847,32 @@ NameSearchContext::AddTypeDecl(const ClangASTType &clang_type)
if (const TypedefType *typedef_type = llvm::dyn_cast<TypedefType>(qual_type))
{
TypedefNameDecl *typedef_name_decl = typedef_type->getDecl();
-
+
m_decls.push_back(typedef_name_decl);
-
+
return (NamedDecl*)typedef_name_decl;
}
else if (const TagType *tag_type = qual_type->getAs<TagType>())
{
TagDecl *tag_decl = tag_type->getDecl();
-
+
m_decls.push_back(tag_decl);
-
+
return tag_decl;
}
else if (const ObjCObjectType *objc_object_type = qual_type->getAs<ObjCObjectType>())
{
ObjCInterfaceDecl *interface_decl = objc_object_type->getInterface();
-
+
m_decls.push_back((NamedDecl*)interface_decl);
-
+
return (NamedDecl*)interface_decl;
}
}
return NULL;
}
-void
+void
NameSearchContext::AddLookupResult (clang::DeclContextLookupConstResult result)
{
for (clang::NamedDecl *decl : result)
diff --git a/contrib/llvm/tools/lldb/source/Expression/ClangExpressionDeclMap.cpp b/contrib/llvm/tools/lldb/source/Expression/ClangExpressionDeclMap.cpp
index 198fde9..43c8a5f 100644
--- a/contrib/llvm/tools/lldb/source/Expression/ClangExpressionDeclMap.cpp
+++ b/contrib/llvm/tools/lldb/source/Expression/ClangExpressionDeclMap.cpp
@@ -8,11 +8,6 @@
//===----------------------------------------------------------------------===//
#include "lldb/Expression/ClangExpressionDeclMap.h"
-
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclarationName.h"
#include "clang/AST/Decl.h"
@@ -68,21 +63,21 @@ ClangExpressionDeclMap::~ClangExpressionDeclMap()
{
// Note: The model is now that the parser's AST context and all associated
// data does not vanish until the expression has been executed. This means
- // that valuable lookup data (like namespaces) doesn't vanish, but
-
+ // that valuable lookup data (like namespaces) doesn't vanish, but
+
DidParse();
DisableStructVars();
}
-bool
+bool
ClangExpressionDeclMap::WillParse(ExecutionContext &exe_ctx,
Materializer *materializer)
{
ClangASTMetrics::ClearLocalCounters();
-
+
EnableParserVars();
m_parser_vars->m_exe_ctx = exe_ctx;
-
+
Target *target = exe_ctx.GetTargetPtr();
if (exe_ctx.GetFramePtr())
m_parser_vars->m_sym_ctx = exe_ctx.GetFramePtr()->GetSymbolContext(lldb::eSymbolContextEverything);
@@ -98,18 +93,18 @@ ClangExpressionDeclMap::WillParse(ExecutionContext &exe_ctx,
m_parser_vars->m_sym_ctx.Clear(true);
m_parser_vars->m_sym_ctx.target_sp = exe_ctx.GetTargetSP();
}
-
+
if (target)
{
m_parser_vars->m_persistent_vars = &target->GetPersistentVariables();
-
+
if (!target->GetScratchClangASTContext())
return false;
}
-
+
m_parser_vars->m_target_info = GetTargetInfo();
m_parser_vars->m_materializer = materializer;
-
+
return true;
}
@@ -120,7 +115,7 @@ ClangExpressionDeclMap::DidParse()
if (log)
ClangASTMetrics::DumpCounters(log);
-
+
if (m_parser_vars.get())
{
for (size_t entity_index = 0, num_entities = m_found_entities.GetSize();
@@ -131,7 +126,7 @@ ClangExpressionDeclMap::DidParse()
if (var_sp)
var_sp->DisableParserVars(GetParserID());
}
-
+
for (size_t pvar_index = 0, num_pvars = m_parser_vars->m_persistent_vars->GetSize();
pvar_index < num_pvars;
++pvar_index)
@@ -140,20 +135,20 @@ ClangExpressionDeclMap::DidParse()
if (pvar_sp)
pvar_sp->DisableParserVars(GetParserID());
}
-
+
DisableParserVars();
}
}
// Interface for IRForTarget
-ClangExpressionDeclMap::TargetInfo
+ClangExpressionDeclMap::TargetInfo
ClangExpressionDeclMap::GetTargetInfo()
{
assert (m_parser_vars.get());
-
+
TargetInfo ret;
-
+
ExecutionContext &exe_ctx = m_parser_vars->m_exe_ctx;
Process *process = exe_ctx.GetProcessPtr();
@@ -162,7 +157,7 @@ ClangExpressionDeclMap::GetTargetInfo()
ret.byte_order = process->GetByteOrder();
ret.address_byte_size = process->GetAddressByteSize();
}
- else
+ else
{
Target *target = exe_ctx.GetTargetPtr();
if (target)
@@ -175,61 +170,61 @@ ClangExpressionDeclMap::GetTargetInfo()
return ret;
}
-bool
-ClangExpressionDeclMap::AddPersistentVariable
+bool
+ClangExpressionDeclMap::AddPersistentVariable
(
- const NamedDecl *decl,
- const ConstString &name,
+ const NamedDecl *decl,
+ const ConstString &name,
TypeFromParser parser_type,
bool is_result,
bool is_lvalue
)
{
assert (m_parser_vars.get());
-
+
if (m_parser_vars->m_materializer && is_result)
{
Error err;
-
+
ExecutionContext &exe_ctx = m_parser_vars->m_exe_ctx;
Target *target = exe_ctx.GetTargetPtr();
if (target == NULL)
return false;
-
+
ASTContext *context(target->GetScratchClangASTContext()->getASTContext());
-
+
TypeFromUser user_type(m_ast_importer->DeportType(context,
parser_type.GetASTContext(),
parser_type.GetOpaqueQualType()),
context);
-
+
uint32_t offset = m_parser_vars->m_materializer->AddResultVariable(user_type, is_lvalue, m_keep_result_in_memory, err);
-
+
ClangExpressionVariableSP var_sp = m_found_entities.CreateVariable(exe_ctx.GetBestExecutionContextScope(),
name,
user_type,
m_parser_vars->m_target_info.byte_order,
m_parser_vars->m_target_info.address_byte_size);
-
+
if (!var_sp)
return false;
-
+
var_sp->EnableParserVars(GetParserID());
-
+
ClangExpressionVariable::ParserVars *parser_vars = var_sp->GetParserVars(GetParserID());
parser_vars->m_named_decl = decl;
parser_vars->m_parser_type = parser_type;
-
+
var_sp->EnableJITVars(GetParserID());
-
+
ClangExpressionVariable::JITVars *jit_vars = var_sp->GetJITVars(GetParserID());
-
+
jit_vars->m_offset = offset;
-
+
return true;
}
-
+
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
ExecutionContext &exe_ctx = m_parser_vars->m_exe_ctx;
Target *target = exe_ctx.GetTargetPtr();
@@ -237,38 +232,38 @@ ClangExpressionDeclMap::AddPersistentVariable
return false;
ASTContext *context(target->GetScratchClangASTContext()->getASTContext());
-
- TypeFromUser user_type(m_ast_importer->DeportType(context,
+
+ TypeFromUser user_type(m_ast_importer->DeportType(context,
parser_type.GetASTContext(),
parser_type.GetOpaqueQualType()),
context);
-
+
if (!user_type.GetOpaqueQualType())
{
if (log)
log->Printf("Persistent variable's type wasn't copied successfully");
return false;
}
-
+
if (!m_parser_vars->m_target_info.IsValid())
return false;
-
+
ClangExpressionVariableSP var_sp = m_parser_vars->m_persistent_vars->CreatePersistentVariable (exe_ctx.GetBestExecutionContextScope (),
name,
user_type,
m_parser_vars->m_target_info.byte_order,
m_parser_vars->m_target_info.address_byte_size);
-
+
if (!var_sp)
return false;
-
+
var_sp->m_frozen_sp->SetHasCompleteType();
-
+
if (is_result)
var_sp->m_flags |= ClangExpressionVariable::EVNeedsFreezeDry;
else
var_sp->m_flags |= ClangExpressionVariable::EVKeepInTarget; // explicitly-declared persistent variables should persist
-
+
if (is_lvalue)
{
var_sp->m_flags |= ClangExpressionVariable::EVIsProgramReference;
@@ -278,88 +273,87 @@ ClangExpressionDeclMap::AddPersistentVariable
var_sp->m_flags |= ClangExpressionVariable::EVIsLLDBAllocated;
var_sp->m_flags |= ClangExpressionVariable::EVNeedsAllocation;
}
-
+
if (m_keep_result_in_memory)
{
var_sp->m_flags |= ClangExpressionVariable::EVKeepInTarget;
}
-
+
if (log)
log->Printf("Created persistent variable with flags 0x%hx", var_sp->m_flags);
-
+
var_sp->EnableParserVars(GetParserID());
-
+
ClangExpressionVariable::ParserVars *parser_vars = var_sp->GetParserVars(GetParserID());
-
+
parser_vars->m_named_decl = decl;
parser_vars->m_parser_type = parser_type;
-
+
return true;
}
-bool
-ClangExpressionDeclMap::AddValueToStruct
+bool
+ClangExpressionDeclMap::AddValueToStruct
(
const NamedDecl *decl,
const ConstString &name,
llvm::Value *value,
size_t size,
- off_t alignment
+ lldb::offset_t alignment
)
{
assert (m_struct_vars.get());
assert (m_parser_vars.get());
-
+
bool is_persistent_variable = false;
-
+
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
+
m_struct_vars->m_struct_laid_out = false;
-
+
if (m_struct_members.GetVariable(decl, GetParserID()))
return true;
-
+
ClangExpressionVariableSP var_sp (m_found_entities.GetVariable(decl, GetParserID()));
-
+
if (!var_sp)
{
var_sp = m_parser_vars->m_persistent_vars->GetVariable(decl, GetParserID());
is_persistent_variable = true;
}
-
+
if (!var_sp)
return false;
-
+
if (log)
log->Printf("Adding value for (NamedDecl*)%p [%s - %s] to the structure",
- decl,
- name.GetCString(),
+ static_cast<const void*>(decl), name.GetCString(),
var_sp->GetName().GetCString());
-
+
// We know entity->m_parser_vars is valid because we used a parser variable
// to find it
-
+
ClangExpressionVariable::ParserVars *parser_vars = var_sp->GetParserVars(GetParserID());
parser_vars->m_llvm_value = value;
-
+
if (ClangExpressionVariable::JITVars *jit_vars = var_sp->GetJITVars(GetParserID()))
{
// We already laid this out; do not touch
-
+
if (log)
log->Printf("Already placed at 0x%llx", (unsigned long long)jit_vars->m_offset);
}
-
+
var_sp->EnableJITVars(GetParserID());
-
+
ClangExpressionVariable::JITVars *jit_vars = var_sp->GetJITVars(GetParserID());
jit_vars->m_alignment = alignment;
jit_vars->m_size = size;
-
+
m_struct_members.AddVariable(var_sp);
-
+
if (m_parser_vars->m_materializer)
{
uint32_t offset = 0;
@@ -379,16 +373,16 @@ ClangExpressionDeclMap::AddValueToStruct
else if (parser_vars->m_lldb_var)
offset = m_parser_vars->m_materializer->AddVariable(parser_vars->m_lldb_var, err);
}
-
+
if (!err.Success())
return false;
-
+
if (log)
log->Printf("Placed at 0x%llx", (unsigned long long)offset);
-
+
jit_vars->m_offset = offset; // TODO DoStructLayout() should not change this.
}
-
+
return true;
}
@@ -396,81 +390,81 @@ bool
ClangExpressionDeclMap::DoStructLayout ()
{
assert (m_struct_vars.get());
-
+
if (m_struct_vars->m_struct_laid_out)
return true;
-
+
if (!m_parser_vars->m_materializer)
return false;
-
+
m_struct_vars->m_struct_alignment = m_parser_vars->m_materializer->GetStructAlignment();
m_struct_vars->m_struct_size = m_parser_vars->m_materializer->GetStructByteSize();
m_struct_vars->m_struct_laid_out = true;
return true;
}
-bool ClangExpressionDeclMap::GetStructInfo
+bool ClangExpressionDeclMap::GetStructInfo
(
uint32_t &num_elements,
size_t &size,
- off_t &alignment
+ lldb::offset_t &alignment
)
{
assert (m_struct_vars.get());
-
+
if (!m_struct_vars->m_struct_laid_out)
return false;
-
+
num_elements = m_struct_members.GetSize();
size = m_struct_vars->m_struct_size;
alignment = m_struct_vars->m_struct_alignment;
-
+
return true;
}
-bool
-ClangExpressionDeclMap::GetStructElement
+bool
+ClangExpressionDeclMap::GetStructElement
(
const NamedDecl *&decl,
llvm::Value *&value,
- off_t &offset,
+ lldb::offset_t &offset,
ConstString &name,
uint32_t index
)
{
assert (m_struct_vars.get());
-
+
if (!m_struct_vars->m_struct_laid_out)
return false;
-
+
if (index >= m_struct_members.GetSize())
return false;
-
+
ClangExpressionVariableSP member_sp(m_struct_members.GetVariableAtIndex(index));
-
+
if (!member_sp)
return false;
-
+
ClangExpressionVariable::ParserVars *parser_vars = member_sp->GetParserVars(GetParserID());
ClangExpressionVariable::JITVars *jit_vars = member_sp->GetJITVars(GetParserID());
-
+
if (!parser_vars ||
!jit_vars ||
!member_sp->GetValueObject())
return false;
-
+
decl = parser_vars->m_named_decl;
value = parser_vars->m_llvm_value;
offset = jit_vars->m_offset;
name = member_sp->GetName();
-
+
return true;
}
bool
-ClangExpressionDeclMap::GetFunctionInfo
+ClangExpressionDeclMap::GetFunctionInfo
(
- const NamedDecl *decl,
+ const NamedDecl *decl,
uint64_t &ptr
)
{
@@ -478,14 +472,14 @@ ClangExpressionDeclMap::GetFunctionInfo
if (!entity_sp)
return false;
-
+
// We know m_parser_vars is valid since we searched for the variable by
// its NamedDecl
-
+
ClangExpressionVariable::ParserVars *parser_vars = entity_sp->GetParserVars(GetParserID());
ptr = parser_vars->m_lldb_value.GetScalar().ULongLong();
-
+
return true;
}
@@ -500,7 +494,7 @@ FindCodeSymbolInContext
SymbolContextList temp_sc_list;
if (sym_ctx.module_sp)
sym_ctx.module_sp->FindSymbolsWithNameAndType(name, eSymbolTypeAny, temp_sc_list);
-
+
if (!sc_list.GetSize() && sym_ctx.target_sp)
sym_ctx.target_sp->GetImages().FindSymbolsWithNameAndType(name, eSymbolTypeAny, temp_sc_list);
@@ -527,14 +521,14 @@ FindCodeSymbolInContext
}
bool
-ClangExpressionDeclMap::GetFunctionAddress
+ClangExpressionDeclMap::GetFunctionAddress
(
const ConstString &name,
uint64_t &func_addr
)
{
assert (m_parser_vars.get());
-
+
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
ExecutionContext &exe_ctx = m_parser_vars->m_exe_ctx;
Target *target = exe_ctx.GetTargetPtr();
@@ -545,25 +539,25 @@ ClangExpressionDeclMap::GetFunctionAddress
return false;
SymbolContextList sc_list;
-
+
FindCodeSymbolInContext(name, m_parser_vars->m_sym_ctx, sc_list);
uint32_t sc_list_size = sc_list.GetSize();
if (sc_list_size == 0)
{
- // We occasionally get debug information in which a const function is reported
+ // We occasionally get debug information in which a const function is reported
// as non-const, so the mangled name is wrong. This is a hack to compensate.
-
+
if (!strncmp(name.GetCString(), "_ZN", 3) &&
strncmp(name.GetCString(), "_ZNK", 4))
{
std::string fixed_scratch("_ZNK");
fixed_scratch.append(name.GetCString() + 3);
ConstString fixed_name(fixed_scratch.c_str());
-
+
if (log)
log->Printf("Failed to find symbols given non-const name %s; trying %s", name.GetCString(), fixed_name.GetCString());
-
+
FindCodeSymbolInContext(fixed_name, m_parser_vars->m_sym_ctx, sc_list);
sc_list_size = sc_list.GetSize();
}
@@ -574,37 +568,25 @@ ClangExpressionDeclMap::GetFunctionAddress
SymbolContext sym_ctx;
sc_list.GetContextAtIndex(i, sym_ctx);
- const Address *func_so_addr = NULL;
- bool is_indirect_function = false;
+ lldb::addr_t callable_load_addr = LLDB_INVALID_ADDRESS;
+
if (sym_ctx.function)
- func_so_addr = &sym_ctx.function->GetAddressRange().GetBaseAddress();
- else if (sym_ctx.symbol)
{
- if (sym_ctx.symbol->GetType() == eSymbolTypeReExported)
- {
- Symbol *reexported_symbol = sym_ctx.symbol->ResolveReExportedSymbol(*target);
- if (reexported_symbol)
- {
- func_so_addr = &reexported_symbol->GetAddress();
- is_indirect_function = reexported_symbol->IsIndirect();
- }
- }
- else
+ const Address func_so_addr = sym_ctx.function->GetAddressRange().GetBaseAddress();
+ if (func_so_addr.IsValid())
{
- func_so_addr = &sym_ctx.symbol->GetAddress();
- is_indirect_function = sym_ctx.symbol->IsIndirect();
+ callable_load_addr = func_so_addr.GetCallableLoadAddress(target, false);
}
}
+ else if (sym_ctx.symbol)
+ {
+ callable_load_addr = sym_ctx.symbol->ResolveCallableAddress(*target);
+ }
- if (func_so_addr && func_so_addr->IsValid())
+ if (callable_load_addr != LLDB_INVALID_ADDRESS)
{
- lldb::addr_t load_addr = func_so_addr->GetCallableLoadAddress (target, is_indirect_function);
-
- if (load_addr != LLDB_INVALID_ADDRESS)
- {
- func_addr = load_addr;
- return true;
- }
+ func_addr = callable_load_addr;
+ return true;
}
}
return false;
@@ -618,12 +600,12 @@ ClangExpressionDeclMap::GetSymbolAddress (Target &target,
lldb_private::Module *module)
{
SymbolContextList sc_list;
-
+
if (module)
module->FindSymbolsWithNameAndType(name, symbol_type, sc_list);
else
target.GetImages().FindSymbolsWithNameAndType(name, symbol_type, sc_list);
-
+
const uint32_t num_matches = sc_list.GetSize();
addr_t symbol_load_addr = LLDB_INVALID_ADDRESS;
@@ -631,12 +613,12 @@ ClangExpressionDeclMap::GetSymbolAddress (Target &target,
{
SymbolContext sym_ctx;
sc_list.GetContextAtIndex(i, sym_ctx);
-
+
const Address *sym_address = &sym_ctx.symbol->GetAddress();
-
+
if (!sym_address || !sym_address->IsValid())
continue;
-
+
if (sym_address)
{
switch (sym_ctx.symbol->GetType())
@@ -702,17 +684,17 @@ ClangExpressionDeclMap::GetSymbolAddress (Target &target,
}
}
}
-
+
if (symbol_load_addr == LLDB_INVALID_ADDRESS && process)
{
ObjCLanguageRuntime *runtime = process->GetObjCLanguageRuntime();
-
+
if (runtime)
{
symbol_load_addr = runtime->LookupRuntimeSymbol(name);
}
}
-
+
return symbol_load_addr;
}
@@ -720,10 +702,10 @@ addr_t
ClangExpressionDeclMap::GetSymbolAddress (const ConstString &name, lldb::SymbolType symbol_type)
{
assert (m_parser_vars.get());
-
+
if (!m_parser_vars->m_exe_ctx.GetTargetPtr())
return false;
-
+
return GetSymbolAddress(m_parser_vars->m_exe_ctx.GetTargetRef(), m_parser_vars->m_exe_ctx.GetProcessPtr(), name, symbol_type);
}
@@ -733,12 +715,12 @@ ClangExpressionDeclMap::FindGlobalDataSymbol (Target &target,
lldb_private::Module *module)
{
SymbolContextList sc_list;
-
+
if (module)
module->FindSymbolsWithNameAndType(name, eSymbolTypeAny, sc_list);
else
target.GetImages().FindSymbolsWithNameAndType(name, eSymbolTypeAny, sc_list);
-
+
const uint32_t matches = sc_list.GetSize();
for (uint32_t i=0; i<matches; ++i)
{
@@ -748,7 +730,7 @@ ClangExpressionDeclMap::FindGlobalDataSymbol (Target &target,
{
const Symbol *symbol = sym_ctx.symbol;
const Address *sym_address = &symbol->GetAddress();
-
+
if (sym_address && sym_address->IsValid())
{
switch (symbol->GetType())
@@ -790,7 +772,7 @@ ClangExpressionDeclMap::FindGlobalDataSymbol (Target &target,
}
}
break;
-
+
case eSymbolTypeCode: // We already lookup functions elsewhere
case eSymbolTypeVariable:
case eSymbolTypeLocal:
@@ -818,7 +800,7 @@ ClangExpressionDeclMap::FindGlobalDataSymbol (Target &target,
}
}
}
-
+
return NULL;
}
@@ -833,12 +815,12 @@ ClangExpressionDeclMap::FindGlobalVariable
)
{
VariableList vars;
-
+
if (module && namespace_decl)
module->FindGlobalVariables (name, namespace_decl, true, -1, vars);
else
target.GetImages().FindGlobalVariables(name, true, -1, vars);
-
+
if (vars.GetSize())
{
if (type)
@@ -846,7 +828,7 @@ ClangExpressionDeclMap::FindGlobalVariable
for (size_t i = 0; i < vars.GetSize(); ++i)
{
VariableSP var_sp = vars.GetVariableAtIndex(i);
-
+
if (ClangASTContext::AreTypesSame(*type, var_sp->GetType()->GetClangFullType()))
return var_sp;
}
@@ -856,7 +838,7 @@ ClangExpressionDeclMap::FindGlobalVariable
return vars.GetVariableAtIndex(0);
}
}
-
+
return VariableSP();
}
@@ -866,23 +848,23 @@ void
ClangExpressionDeclMap::FindExternalVisibleDecls (NameSearchContext &context)
{
assert (m_ast_context);
-
+
ClangASTMetrics::RegisterVisibleQuery();
-
+
const ConstString name(context.m_decl_name.getAsString().c_str());
-
+
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
+
if (GetImportInProgress())
{
if (log && log->GetVerbose())
log->Printf("Ignoring a query during an import");
return;
}
-
+
static unsigned int invocation_id = 0;
unsigned int current_id = invocation_id++;
-
+
if (log)
{
if (!context.m_decl_context)
@@ -892,20 +874,19 @@ ClangExpressionDeclMap::FindExternalVisibleDecls (NameSearchContext &context)
else
log->Printf("ClangExpressionDeclMap::FindExternalVisibleDecls[%u] for '%s' in a '%s'", current_id, name.GetCString(), context.m_decl_context->getDeclKindName());
}
-
+
if (const NamespaceDecl *namespace_context = dyn_cast<NamespaceDecl>(context.m_decl_context))
{
ClangASTImporter::NamespaceMapSP namespace_map = m_ast_importer->GetNamespaceMap(namespace_context);
-
+
if (log && log->GetVerbose())
- log->Printf(" CEDM::FEVD[%u] Inspecting (NamespaceMap*)%p (%d entries)",
- current_id,
- namespace_map.get(),
+ log->Printf(" CEDM::FEVD[%u] Inspecting (NamespaceMap*)%p (%d entries)",
+ current_id, static_cast<void*>(namespace_map.get()),
(int)namespace_map->size());
-
+
if (!namespace_map)
return;
-
+
for (ClangASTImporter::NamespaceMap::iterator i = namespace_map->begin(), e = namespace_map->end();
i != e;
++i)
@@ -915,7 +896,7 @@ ClangExpressionDeclMap::FindExternalVisibleDecls (NameSearchContext &context)
current_id,
i->second.GetNamespaceDecl()->getNameAsString().c_str(),
i->first->GetFileSpec().GetFilename().GetCString());
-
+
FindExternalVisibleDecls(context,
i->first,
i->second,
@@ -925,65 +906,65 @@ ClangExpressionDeclMap::FindExternalVisibleDecls (NameSearchContext &context)
else if (isa<TranslationUnitDecl>(context.m_decl_context))
{
ClangNamespaceDecl namespace_decl;
-
+
if (log)
log->Printf(" CEDM::FEVD[%u] Searching the root namespace", current_id);
-
+
FindExternalVisibleDecls(context,
lldb::ModuleSP(),
namespace_decl,
current_id);
}
-
+
if (!context.m_found.variable)
ClangASTSource::FindExternalVisibleDecls(context);
}
-void
-ClangExpressionDeclMap::FindExternalVisibleDecls (NameSearchContext &context,
+void
+ClangExpressionDeclMap::FindExternalVisibleDecls (NameSearchContext &context,
lldb::ModuleSP module_sp,
ClangNamespaceDecl &namespace_decl,
unsigned int current_id)
{
assert (m_ast_context);
-
+
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
+
SymbolContextList sc_list;
-
+
const ConstString name(context.m_decl_name.getAsString().c_str());
-
+
const char *name_unique_cstr = name.GetCString();
-
+
if (name_unique_cstr == NULL)
return;
-
+
static ConstString id_name("id");
static ConstString Class_name("Class");
-
+
if (name == id_name || name == Class_name)
return;
-
- // Only look for functions by name out in our symbols if the function
+
+ // Only look for functions by name out in our symbols if the function
// doesn't start with our phony prefix of '$'
Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr();
if (name_unique_cstr[0] == '$' && !namespace_decl)
{
static ConstString g_lldb_class_name ("$__lldb_class");
-
+
if (name == g_lldb_class_name)
{
// Clang is looking for the type of "this"
-
+
if (frame == NULL)
return;
-
+
SymbolContext sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction);
-
+
if (!sym_ctx.function)
return;
-
+
// Get the block that defines the function
Block *function_block = sym_ctx.GetFunctionBlock();
@@ -991,59 +972,59 @@ ClangExpressionDeclMap::FindExternalVisibleDecls (NameSearchContext &context,
return;
clang::DeclContext *decl_context = function_block->GetClangDeclContext();
-
+
if (!decl_context)
return;
-
+
clang::CXXMethodDecl *method_decl = llvm::dyn_cast<clang::CXXMethodDecl>(decl_context);
-
+
if (method_decl)
{
clang::CXXRecordDecl *class_decl = method_decl->getParent();
-
+
QualType class_qual_type(class_decl->getTypeForDecl(), 0);
-
+
TypeFromUser class_user_type (class_qual_type.getAsOpaquePtr(),
&class_decl->getASTContext());
-
+
if (log)
{
ASTDumper ast_dumper(class_qual_type);
log->Printf(" CEDM::FEVD[%u] Adding type for $__lldb_class: %s", current_id, ast_dumper.GetCString());
}
-
+
TypeFromParser class_type = CopyClassType(class_user_type, current_id);
-
+
if (!class_type.IsValid())
return;
-
+
TypeSourceInfo *type_source_info = m_ast_context->getTrivialTypeSourceInfo(QualType::getFromOpaquePtr(class_type.GetOpaqueQualType()));
-
+
if (!type_source_info)
return;
-
+
TypedefDecl *typedef_decl = TypedefDecl::Create(*m_ast_context,
m_ast_context->getTranslationUnitDecl(),
SourceLocation(),
SourceLocation(),
context.m_decl_name.getAsIdentifierInfo(),
type_source_info);
-
-
+
+
if (!typedef_decl)
return;
-
+
context.AddNamedDecl(typedef_decl);
-
+
if (method_decl->isInstance())
{
// self is a pointer to the object
-
+
QualType class_pointer_type = method_decl->getASTContext().getPointerType(class_qual_type);
-
+
TypeFromUser self_user_type(class_pointer_type.getAsOpaquePtr(),
&method_decl->getASTContext());
-
+
m_struct_vars->m_object_pointer_type = self_user_type;
}
}
@@ -1055,22 +1036,22 @@ ClangExpressionDeclMap::FindExternalVisibleDecls (NameSearchContext &context,
// scope and use its type.
// FIXME: This code is formally correct, but clang doesn't currently emit DW_AT_object_pointer
// for C++ so it hasn't actually been tested.
-
+
VariableList *vars = frame->GetVariableList(false);
-
+
lldb::VariableSP this_var = vars->FindVariable(ConstString("this"));
-
+
if (this_var &&
this_var->IsInScope(frame) &&
this_var->LocationIsValidForFrame (frame))
{
Type *this_type = this_var->GetType();
-
+
if (!this_type)
return;
-
+
ClangASTType pointee_type = this_type->GetClangForwardType().GetPointeeType();
-
+
if (pointee_type.IsValid())
{
if (log)
@@ -1078,89 +1059,89 @@ ClangExpressionDeclMap::FindExternalVisibleDecls (NameSearchContext &context,
ASTDumper ast_dumper(this_type->GetClangFullType());
log->Printf(" FEVD[%u] Adding type for $__lldb_objc_class: %s", current_id, ast_dumper.GetCString());
}
-
+
TypeFromUser class_user_type(pointee_type);
AddOneType(context, class_user_type, current_id);
-
-
+
+
TypeFromUser this_user_type(this_type->GetClangFullType());
m_struct_vars->m_object_pointer_type = this_user_type;
return;
}
}
}
-
+
return;
}
-
+
static ConstString g_lldb_objc_class_name ("$__lldb_objc_class");
if (name == g_lldb_objc_class_name)
{
// Clang is looking for the type of "*self"
-
+
if (!frame)
return;
-
+
SymbolContext sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction);
-
+
if (!sym_ctx.function)
return;
-
+
// Get the block that defines the function
Block *function_block = sym_ctx.GetFunctionBlock();
-
+
if (!function_block)
return;
-
+
clang::DeclContext *decl_context = function_block->GetClangDeclContext();
-
+
if (!decl_context)
return;
-
+
clang::ObjCMethodDecl *method_decl = llvm::dyn_cast<clang::ObjCMethodDecl>(decl_context);
-
+
if (method_decl)
{
ObjCInterfaceDecl* self_interface = method_decl->getClassInterface();
-
+
if (!self_interface)
return;
-
+
const clang::Type *interface_type = self_interface->getTypeForDecl();
-
+
if (!interface_type)
return; // This is unlikely, but we have seen crashes where this occurred
-
+
TypeFromUser class_user_type(QualType(interface_type, 0).getAsOpaquePtr(),
&method_decl->getASTContext());
-
+
if (log)
{
ASTDumper ast_dumper(interface_type);
log->Printf(" FEVD[%u] Adding type for $__lldb_objc_class: %s", current_id, ast_dumper.GetCString());
}
-
+
AddOneType(context, class_user_type, current_id);
-
+
if (method_decl->isInstanceMethod())
{
// self is a pointer to the object
-
+
QualType class_pointer_type = method_decl->getASTContext().getObjCObjectPointerType(QualType(interface_type, 0));
-
+
TypeFromUser self_user_type(class_pointer_type.getAsOpaquePtr(),
&method_decl->getASTContext());
-
+
m_struct_vars->m_object_pointer_type = self_user_type;
}
else
{
// self is a Class pointer
QualType class_type = method_decl->getASTContext().getObjCClassType();
-
+
TypeFromUser self_user_type(class_type.getAsOpaquePtr(),
&method_decl->getASTContext());
-
+
m_struct_vars->m_object_pointer_type = self_user_type;
}
@@ -1172,22 +1153,22 @@ ClangExpressionDeclMap::FindExternalVisibleDecls (NameSearchContext &context,
// claims to have an object pointer (through DW_AT_object_pointer?) but is not formally a
// method of the class. In that case, just look up the "self" variable in the the current
// scope and use its type.
-
+
VariableList *vars = frame->GetVariableList(false);
-
+
lldb::VariableSP self_var = vars->FindVariable(ConstString("self"));
-
+
if (self_var &&
- self_var->IsInScope(frame) &&
+ self_var->IsInScope(frame) &&
self_var->LocationIsValidForFrame (frame))
{
Type *self_type = self_var->GetType();
-
+
if (!self_type)
return;
-
+
ClangASTType self_clang_type = self_type->GetClangFullType();
-
+
if (self_clang_type.IsObjCClassType())
{
return;
@@ -1198,19 +1179,19 @@ ClangExpressionDeclMap::FindExternalVisibleDecls (NameSearchContext &context,
if (!self_clang_type)
return;
-
+
if (log)
{
ASTDumper ast_dumper(self_type->GetClangFullType());
log->Printf(" FEVD[%u] Adding type for $__lldb_objc_class: %s", current_id, ast_dumper.GetCString());
}
-
+
TypeFromUser class_user_type (self_clang_type);
-
+
AddOneType(context, class_user_type, current_id);
-
+
TypeFromUser self_user_type(self_type->GetClangFullType());
-
+
m_struct_vars->m_object_pointer_type = self_user_type;
return;
}
@@ -1219,66 +1200,66 @@ ClangExpressionDeclMap::FindExternalVisibleDecls (NameSearchContext &context,
return;
}
-
+
// any other $__lldb names should be weeded out now
if (!::strncmp(name_unique_cstr, "$__lldb", sizeof("$__lldb") - 1))
return;
-
+
do
{
if (!target)
break;
-
+
ClangASTContext *scratch_clang_ast_context = target->GetScratchClangASTContext();
-
+
if (!scratch_clang_ast_context)
break;
-
+
ASTContext *scratch_ast_context = scratch_clang_ast_context->getASTContext();
-
+
if (!scratch_ast_context)
break;
-
+
TypeDecl *ptype_type_decl = m_parser_vars->m_persistent_vars->GetPersistentType(name);
-
+
if (!ptype_type_decl)
break;
-
+
Decl *parser_ptype_decl = m_ast_importer->CopyDecl(m_ast_context, scratch_ast_context, ptype_type_decl);
-
+
if (!parser_ptype_decl)
break;
-
+
TypeDecl *parser_ptype_type_decl = dyn_cast<TypeDecl>(parser_ptype_decl);
-
+
if (!parser_ptype_type_decl)
break;
-
+
if (log)
log->Printf(" CEDM::FEVD[%u] Found persistent type %s", current_id, name.GetCString());
-
+
context.AddNamedDecl(parser_ptype_type_decl);
} while (0);
-
+
ClangExpressionVariableSP pvar_sp(m_parser_vars->m_persistent_vars->GetVariable(name));
-
+
if (pvar_sp)
{
AddOneVariable(context, pvar_sp, current_id);
return;
}
-
+
const char *reg_name(&name.GetCString()[1]);
-
+
if (m_parser_vars->m_exe_ctx.GetRegisterContext())
{
const RegisterInfo *reg_info(m_parser_vars->m_exe_ctx.GetRegisterContext()->GetRegisterInfoByName(reg_name));
-
+
if (reg_info)
{
if (log)
log->Printf(" CEDM::FEVD[%u] Found register %s", current_id, reg_info->name);
-
+
AddOneRegister(context, reg_info, current_id);
}
}
@@ -1288,11 +1269,11 @@ ClangExpressionDeclMap::FindExternalVisibleDecls (NameSearchContext &context,
ValueObjectSP valobj;
VariableSP var;
Error err;
-
+
if (frame && !namespace_decl)
{
- valobj = frame->GetValueForVariableExpressionPath(name_unique_cstr,
- eNoDynamicValues,
+ valobj = frame->GetValueForVariableExpressionPath(name_unique_cstr,
+ eNoDynamicValues,
StackFrame::eExpressionPathOptionCheckPtrVsMember ||
StackFrame::eExpressionPathOptionsAllowDirectIVarAccess ||
StackFrame::eExpressionPathOptionsNoFragileObjcIvar ||
@@ -1300,7 +1281,7 @@ ClangExpressionDeclMap::FindExternalVisibleDecls (NameSearchContext &context,
StackFrame::eExpressionPathOptionsNoSyntheticArrayRange,
var,
err);
-
+
// If we found a variable in scope, no need to pull up function names
if (err.Success() && var)
{
@@ -1309,7 +1290,7 @@ ClangExpressionDeclMap::FindExternalVisibleDecls (NameSearchContext &context,
return;
}
}
-
+
if (target)
{
var = FindGlobalVariable (*target,
@@ -1317,7 +1298,7 @@ ClangExpressionDeclMap::FindExternalVisibleDecls (NameSearchContext &context,
name,
&namespace_decl,
NULL);
-
+
if (var)
{
valobj = ValueObjectVariable::Create(target, var);
@@ -1326,19 +1307,19 @@ ClangExpressionDeclMap::FindExternalVisibleDecls (NameSearchContext &context,
return;
}
}
-
+
if (!context.m_found.variable)
{
const bool include_inlines = false;
const bool append = false;
-
+
if (namespace_decl && module_sp)
{
const bool include_symbols = false;
module_sp->FindFunctions(name,
&namespace_decl,
- eFunctionNameTypeBase,
+ eFunctionNameTypeBase,
include_symbols,
include_inlines,
append,
@@ -1347,63 +1328,63 @@ ClangExpressionDeclMap::FindExternalVisibleDecls (NameSearchContext &context,
else if (target && !namespace_decl)
{
const bool include_symbols = true;
-
+
// TODO Fix FindFunctions so that it doesn't return
// instance methods for eFunctionNameTypeBase.
-
+
target->GetImages().FindFunctions(name,
eFunctionNameTypeFull,
include_symbols,
include_inlines,
- append,
+ append,
sc_list);
}
-
+
if (sc_list.GetSize())
{
Symbol *extern_symbol = NULL;
Symbol *non_extern_symbol = NULL;
-
+
for (uint32_t index = 0, num_indices = sc_list.GetSize();
index < num_indices;
++index)
{
SymbolContext sym_ctx;
sc_list.GetContextAtIndex(index, sym_ctx);
-
+
if (sym_ctx.function)
{
clang::DeclContext *decl_ctx = sym_ctx.function->GetClangDeclContext();
-
+
if (!decl_ctx)
continue;
-
+
// Filter out class/instance methods.
if (dyn_cast<clang::ObjCMethodDecl>(decl_ctx))
continue;
if (dyn_cast<clang::CXXMethodDecl>(decl_ctx))
continue;
-
+
AddOneFunction(context, sym_ctx.function, NULL, current_id);
context.m_found.function_with_type_info = true;
context.m_found.function = true;
}
else if (sym_ctx.symbol)
{
- if (sym_ctx.symbol->GetType() == eSymbolTypeReExported)
+ if (sym_ctx.symbol->GetType() == eSymbolTypeReExported && target)
{
sym_ctx.symbol = sym_ctx.symbol->ResolveReExportedSymbol(*target);
if (sym_ctx.symbol == NULL)
continue;
}
-
+
if (sym_ctx.symbol->IsExternal())
extern_symbol = sym_ctx.symbol;
else
non_extern_symbol = sym_ctx.symbol;
}
}
-
+
if (!context.m_found.function_with_type_info)
{
if (extern_symbol)
@@ -1418,14 +1399,14 @@ ClangExpressionDeclMap::FindExternalVisibleDecls (NameSearchContext &context,
}
}
}
-
+
if (target && !context.m_found.variable && !namespace_decl)
{
- // We couldn't find a non-symbol variable for this. Now we'll hunt for a generic
+ // We couldn't find a non-symbol variable for this. Now we'll hunt for a generic
// data symbol, and -- if it is found -- treat it as a variable.
-
+
const Symbol *data_symbol = FindGlobalDataSymbol(*target, name);
-
+
if (data_symbol)
{
std::string warning("got name from symbols: ");
@@ -1440,43 +1421,43 @@ ClangExpressionDeclMap::FindExternalVisibleDecls (NameSearchContext &context,
}
}
-static clang_type_t
-MaybePromoteToBlockPointerType
-(
- ASTContext *ast_context,
- clang_type_t candidate_type
-)
-{
- if (!candidate_type)
- return candidate_type;
-
- QualType candidate_qual_type = QualType::getFromOpaquePtr(candidate_type);
-
- const PointerType *candidate_pointer_type = dyn_cast<PointerType>(candidate_qual_type);
-
- if (!candidate_pointer_type)
- return candidate_type;
-
- QualType pointee_qual_type = candidate_pointer_type->getPointeeType();
-
- const RecordType *pointee_record_type = dyn_cast<RecordType>(pointee_qual_type);
-
- if (!pointee_record_type)
- return candidate_type;
-
- RecordDecl *pointee_record_decl = pointee_record_type->getDecl();
-
- if (!pointee_record_decl->isRecord())
- return candidate_type;
-
- if (!pointee_record_decl->getName().startswith(llvm::StringRef("__block_literal_")))
- return candidate_type;
-
- QualType generic_function_type = ast_context->getFunctionNoProtoType(ast_context->UnknownAnyTy);
- QualType block_pointer_type = ast_context->getBlockPointerType(generic_function_type);
-
- return block_pointer_type.getAsOpaquePtr();
-}
+//static clang_type_t
+//MaybePromoteToBlockPointerType
+//(
+// ASTContext *ast_context,
+// clang_type_t candidate_type
+//)
+//{
+// if (!candidate_type)
+// return candidate_type;
+//
+// QualType candidate_qual_type = QualType::getFromOpaquePtr(candidate_type);
+//
+// const PointerType *candidate_pointer_type = dyn_cast<PointerType>(candidate_qual_type);
+//
+// if (!candidate_pointer_type)
+// return candidate_type;
+//
+// QualType pointee_qual_type = candidate_pointer_type->getPointeeType();
+//
+// const RecordType *pointee_record_type = dyn_cast<RecordType>(pointee_qual_type);
+//
+// if (!pointee_record_type)
+// return candidate_type;
+//
+// RecordDecl *pointee_record_decl = pointee_record_type->getDecl();
+//
+// if (!pointee_record_decl->isRecord())
+// return candidate_type;
+//
+// if (!pointee_record_decl->getName().startswith(llvm::StringRef("__block_literal_")))
+// return candidate_type;
+//
+// QualType generic_function_type = ast_context->getFunctionNoProtoType(ast_context->UnknownAnyTy);
+// QualType block_pointer_type = ast_context->getBlockPointerType(generic_function_type);
+//
+// return block_pointer_type.getAsOpaquePtr();
+//}
bool
ClangExpressionDeclMap::GetVariableValue (VariableSP &var,
@@ -1485,25 +1466,25 @@ ClangExpressionDeclMap::GetVariableValue (VariableSP &var,
TypeFromParser *parser_type)
{
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
+
Type *var_type = var->GetType();
-
- if (!var_type)
+
+ if (!var_type)
{
if (log)
log->PutCString("Skipped a definition because it has no type");
return false;
}
-
+
ClangASTType var_clang_type = var_type->GetClangFullType();
-
+
if (!var_clang_type)
{
if (log)
log->PutCString("Skipped a definition because it has no Clang type");
return false;
}
-
+
ASTContext *ast = var_type->GetClangASTContext().getASTContext();
if (!ast)
@@ -1513,25 +1494,16 @@ ClangExpressionDeclMap::GetVariableValue (VariableSP &var,
return false;
}
//var_clang_type = MaybePromoteToBlockPointerType (ast, var_clang_type);
-
+
DWARFExpression &var_location_expr = var->LocationExpression();
-
- lldb::addr_t loclist_base_load_addr = LLDB_INVALID_ADDRESS;
-
- Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
- if (var_location_expr.IsLocationList())
- {
- SymbolContext var_sc;
- var->CalculateSymbolContext (&var_sc);
- loclist_base_load_addr = var_sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress (target);
- }
+ Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
Error err;
-
+
if (var->GetLocationIsConstantValueData())
{
DataExtractor const_value_extractor;
-
+
if (var_location_expr.GetExpressionData(const_value_extractor))
{
var_location = Value(const_value_extractor.GetDataStart(), const_value_extractor.GetByteSize());
@@ -1544,45 +1516,45 @@ ClangExpressionDeclMap::GetVariableValue (VariableSP &var,
return false;
}
}
-
+
ClangASTType type_to_use = GuardedCopyType(var_clang_type);
-
+
if (!type_to_use)
{
if (log)
log->Printf("Couldn't copy a variable's type into the parser's AST context");
-
+
return false;
}
-
+
if (parser_type)
*parser_type = TypeFromParser(type_to_use);
-
+
if (var_location.GetContextType() == Value::eContextTypeInvalid)
var_location.SetClangType(type_to_use);
-
+
if (var_location.GetValueType() == Value::eValueTypeFileAddress)
{
SymbolContext var_sc;
var->CalculateSymbolContext(&var_sc);
-
+
if (!var_sc.module_sp)
return false;
Address so_addr(var_location.GetScalar().ULongLong(), var_sc.module_sp->GetSectionList());
-
+
lldb::addr_t load_addr = so_addr.GetLoadAddress(target);
-
+
if (load_addr != LLDB_INVALID_ADDRESS)
{
var_location.GetScalar() = load_addr;
var_location.SetValueType(Value::eValueTypeLoadAddress);
}
}
-
+
if (user_type)
*user_type = TypeFromUser(var_clang_type);
-
+
return true;
}
@@ -1590,21 +1562,21 @@ void
ClangExpressionDeclMap::AddOneVariable (NameSearchContext &context, VariableSP var, ValueObjectSP valobj, unsigned int current_id)
{
assert (m_parser_vars.get());
-
+
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
+
TypeFromUser ut;
TypeFromParser pt;
Value var_location;
-
+
if (!GetVariableValue (var, var_location, &ut, &pt))
return;
-
+
clang::QualType parser_opaque_type = QualType::getFromOpaquePtr(pt.GetOpaqueQualType());
-
+
if (parser_opaque_type.isNull())
return;
-
+
if (const clang::Type *parser_type = parser_opaque_type.getTypePtr())
{
if (const TagType *tag_type = dyn_cast<TagType>(parser_type))
@@ -1612,8 +1584,8 @@ ClangExpressionDeclMap::AddOneVariable (NameSearchContext &context, VariableSP v
if (const ObjCObjectPointerType *objc_object_ptr_type = dyn_cast<ObjCObjectPointerType>(parser_type))
CompleteType(objc_object_ptr_type->getInterfaceDecl());
}
-
-
+
+
bool is_reference = pt.IsReferenceType();
NamedDecl *var_decl = NULL;
@@ -1621,11 +1593,11 @@ ClangExpressionDeclMap::AddOneVariable (NameSearchContext &context, VariableSP v
var_decl = context.AddVarDecl(pt);
else
var_decl = context.AddVarDecl(pt.GetLValueReferenceType());
-
+
std::string decl_name(context.m_decl_name.getAsString());
ConstString entity_name(decl_name.c_str());
ClangExpressionVariableSP entity(m_found_entities.CreateVariable (valobj));
-
+
assert (entity.get());
entity->EnableParserVars(GetParserID());
ClangExpressionVariable::ParserVars *parser_vars = entity->GetParserVars(GetParserID());
@@ -1634,45 +1606,45 @@ ClangExpressionDeclMap::AddOneVariable (NameSearchContext &context, VariableSP v
parser_vars->m_llvm_value = NULL;
parser_vars->m_lldb_value = var_location;
parser_vars->m_lldb_var = var;
-
+
if (is_reference)
entity->m_flags |= ClangExpressionVariable::EVTypeIsReference;
-
+
if (log)
{
ASTDumper orig_dumper(ut.GetOpaqueQualType());
- ASTDumper ast_dumper(var_decl);
+ ASTDumper ast_dumper(var_decl);
log->Printf(" CEDM::FEVD[%u] Found variable %s, returned %s (original %s)", current_id, decl_name.c_str(), ast_dumper.GetCString(), orig_dumper.GetCString());
}
}
void
ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
- ClangExpressionVariableSP &pvar_sp,
+ ClangExpressionVariableSP &pvar_sp,
unsigned int current_id)
{
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
+
TypeFromUser user_type (pvar_sp->GetTypeFromUser());
-
+
TypeFromParser parser_type (GuardedCopyType(user_type));
-
+
if (!parser_type.GetOpaqueQualType())
{
if (log)
log->Printf(" CEDM::FEVD[%u] Couldn't import type for pvar %s", current_id, pvar_sp->GetName().GetCString());
return;
}
-
+
NamedDecl *var_decl = context.AddVarDecl(parser_type.GetLValueReferenceType());
-
+
pvar_sp->EnableParserVars(GetParserID());
ClangExpressionVariable::ParserVars *parser_vars = pvar_sp->GetParserVars(GetParserID());
parser_vars->m_parser_type = parser_type;
parser_vars->m_named_decl = var_decl;
parser_vars->m_llvm_value = NULL;
parser_vars->m_lldb_value.Clear();
-
+
if (log)
{
ASTDumper ast_dumper(var_decl);
@@ -1681,59 +1653,59 @@ ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
}
void
-ClangExpressionDeclMap::AddOneGenericVariable(NameSearchContext &context,
+ClangExpressionDeclMap::AddOneGenericVariable(NameSearchContext &context,
const Symbol &symbol,
unsigned int current_id)
{
assert(m_parser_vars.get());
-
+
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
+
Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
if (target == NULL)
return;
ASTContext *scratch_ast_context = target->GetScratchClangASTContext()->getASTContext();
-
+
TypeFromUser user_type (ClangASTContext::GetBasicType(scratch_ast_context, eBasicTypeVoid).GetPointerType().GetLValueReferenceType());
TypeFromParser parser_type (ClangASTContext::GetBasicType(m_ast_context, eBasicTypeVoid).GetPointerType().GetLValueReferenceType());
NamedDecl *var_decl = context.AddVarDecl(parser_type);
-
+
std::string decl_name(context.m_decl_name.getAsString());
ConstString entity_name(decl_name.c_str());
ClangExpressionVariableSP entity(m_found_entities.CreateVariable (m_parser_vars->m_exe_ctx.GetBestExecutionContextScope (),
- entity_name,
+ entity_name,
user_type,
m_parser_vars->m_target_info.byte_order,
m_parser_vars->m_target_info.address_byte_size));
assert (entity.get());
-
+
entity->EnableParserVars(GetParserID());
ClangExpressionVariable::ParserVars *parser_vars = entity->GetParserVars(GetParserID());
const Address &symbol_address = symbol.GetAddress();
lldb::addr_t symbol_load_addr = symbol_address.GetLoadAddress(target);
-
+
//parser_vars->m_lldb_value.SetContext(Value::eContextTypeClangType, user_type.GetOpaqueQualType());
parser_vars->m_lldb_value.SetClangType(user_type);
parser_vars->m_lldb_value.GetScalar() = symbol_load_addr;
parser_vars->m_lldb_value.SetValueType(Value::eValueTypeLoadAddress);
-
+
parser_vars->m_parser_type = parser_type;
parser_vars->m_named_decl = var_decl;
parser_vars->m_llvm_value = NULL;
parser_vars->m_lldb_sym = &symbol;
-
+
if (log)
{
ASTDumper ast_dumper(var_decl);
-
+
log->Printf(" CEDM::FEVD[%u] Found variable %s, returned %s", current_id, decl_name.c_str(), ast_dumper.GetCString());
}
}
-bool
+bool
ClangExpressionDeclMap::ResolveUnknownTypes()
{
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
@@ -1746,82 +1718,82 @@ ClangExpressionDeclMap::ResolveUnknownTypes()
++index)
{
ClangExpressionVariableSP entity = m_found_entities.GetVariableAtIndex(index);
-
+
ClangExpressionVariable::ParserVars *parser_vars = entity->GetParserVars(GetParserID());
-
+
if (entity->m_flags & ClangExpressionVariable::EVUnknownType)
{
const NamedDecl *named_decl = parser_vars->m_named_decl;
const VarDecl *var_decl = dyn_cast<VarDecl>(named_decl);
-
+
if (!var_decl)
{
if (log)
log->Printf("Entity of unknown type does not have a VarDecl");
return false;
}
-
+
if (log)
{
ASTDumper ast_dumper(const_cast<VarDecl*>(var_decl));
log->Printf("Variable of unknown type now has Decl %s", ast_dumper.GetCString());
}
-
+
QualType var_type = var_decl->getType();
TypeFromParser parser_type(var_type.getAsOpaquePtr(), &var_decl->getASTContext());
-
+
lldb::clang_type_t copied_type = m_ast_importer->CopyType(scratch_ast_context, &var_decl->getASTContext(), var_type.getAsOpaquePtr());
-
+
if (!copied_type)
- {
+ {
if (log)
log->Printf("ClangExpressionDeclMap::ResolveUnknownType - Couldn't import the type for a variable");
-
+
return (bool) lldb::ClangExpressionVariableSP();
}
-
+
TypeFromUser user_type(copied_type, scratch_ast_context);
-
+
// parser_vars->m_lldb_value.SetContext(Value::eContextTypeClangType, user_type.GetOpaqueQualType());
parser_vars->m_lldb_value.SetClangType(user_type);
parser_vars->m_parser_type = parser_type;
-
+
entity->SetClangType(user_type);
-
+
entity->m_flags &= ~(ClangExpressionVariable::EVUnknownType);
}
}
-
+
return true;
}
void
ClangExpressionDeclMap::AddOneRegister (NameSearchContext &context,
- const RegisterInfo *reg_info,
+ const RegisterInfo *reg_info,
unsigned int current_id)
{
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
+
ClangASTType clang_type = ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (m_ast_context,
reg_info->encoding,
reg_info->byte_size * 8);
-
+
if (!clang_type)
{
if (log)
log->Printf(" Tried to add a type for %s, but couldn't get one", context.m_decl_name.getAsString().c_str());
return;
}
-
+
TypeFromParser parser_clang_type (clang_type);
-
+
NamedDecl *var_decl = context.AddVarDecl(parser_clang_type);
-
+
ClangExpressionVariableSP entity(m_found_entities.CreateVariable (m_parser_vars->m_exe_ctx.GetBestExecutionContextScope(),
m_parser_vars->m_target_info.byte_order,
m_parser_vars->m_target_info.address_byte_size));
assert (entity.get());
-
+
std::string decl_name(context.m_decl_name.getAsString());
entity->SetName (ConstString (decl_name.c_str()));
entity->SetRegisterInfo (reg_info);
@@ -1832,7 +1804,7 @@ ClangExpressionDeclMap::AddOneRegister (NameSearchContext &context,
parser_vars->m_llvm_value = NULL;
parser_vars->m_lldb_value.Clear();
entity->m_flags |= ClangExpressionVariable::EVBareRegister;
-
+
if (log)
{
ASTDumper ast_dumper(var_decl);
@@ -1847,9 +1819,9 @@ ClangExpressionDeclMap::AddOneFunction (NameSearchContext &context,
unsigned int current_id)
{
assert (m_parser_vars.get());
-
+
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
+
NamedDecl *function_decl = NULL;
const Address *fun_address = NULL;
ClangASTType function_clang_type;
@@ -1859,30 +1831,30 @@ ClangExpressionDeclMap::AddOneFunction (NameSearchContext &context,
if (function)
{
Type *function_type = function->GetType();
-
+
if (!function_type)
{
if (log)
log->PutCString(" Skipped a function because it has no type");
return;
}
-
+
function_clang_type = function_type->GetClangFullType();
-
+
if (!function_clang_type)
{
if (log)
log->PutCString(" Skipped a function because it has no Clang type");
return;
}
-
+
fun_address = &function->GetAddressRange().GetBaseAddress();
-
+
ClangASTType copied_function_type = GuardedCopyType(function_clang_type);
if (copied_function_type)
{
function_decl = context.AddFunDecl(copied_function_type);
-
+
if (!function_decl)
{
if (log)
@@ -1891,7 +1863,7 @@ ClangExpressionDeclMap::AddOneFunction (NameSearchContext &context,
function_type->GetName().GetCString(),
function_type->GetID());
}
-
+
return;
}
}
@@ -1904,7 +1876,7 @@ ClangExpressionDeclMap::AddOneFunction (NameSearchContext &context,
function_type->GetName().GetCString(),
function_type->GetID());
}
-
+
return;
}
}
@@ -1920,11 +1892,11 @@ ClangExpressionDeclMap::AddOneFunction (NameSearchContext &context,
log->PutCString(" AddOneFunction called with no function and no symbol");
return;
}
-
+
Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
lldb::addr_t load_addr = fun_address->GetCallableLoadAddress(target, is_indirect_function);
-
+
ClangExpressionVariableSP entity(m_found_entities.CreateVariable (m_parser_vars->m_exe_ctx.GetBestExecutionContextScope (),
m_parser_vars->m_target_info.byte_order,
m_parser_vars->m_target_info.address_byte_size));
@@ -1936,7 +1908,7 @@ ClangExpressionDeclMap::AddOneFunction (NameSearchContext &context,
entity->EnableParserVars(GetParserID());
ClangExpressionVariable::ParserVars *parser_vars = entity->GetParserVars(GetParserID());
-
+
if (load_addr != LLDB_INVALID_ADDRESS)
{
parser_vars->m_lldb_value.SetValueType(Value::eValueTypeLoadAddress);
@@ -1945,25 +1917,25 @@ ClangExpressionDeclMap::AddOneFunction (NameSearchContext &context,
else
{
// We have to try finding a file address.
-
+
lldb::addr_t file_addr = fun_address->GetFileAddress();
-
+
parser_vars->m_lldb_value.SetValueType(Value::eValueTypeFileAddress);
parser_vars->m_lldb_value.GetScalar() = file_addr;
}
-
+
parser_vars->m_named_decl = function_decl;
parser_vars->m_llvm_value = NULL;
-
+
if (log)
{
ASTDumper ast_dumper(function_decl);
-
+
StreamString ss;
-
+
fun_address->Dump(&ss, m_parser_vars->m_exe_ctx.GetBestExecutionContextScope(), Address::DumpStyleResolvedDescription);
-
+
log->Printf(" CEDM::FEVD[%u] Found %s function %s (description %s), returned %s",
current_id,
(function ? "specific" : "generic"),
@@ -1978,14 +1950,14 @@ ClangExpressionDeclMap::CopyClassType(TypeFromUser &ut,
unsigned int current_id)
{
ClangASTType copied_clang_type = GuardedCopyType(ut);
-
+
if (!copied_clang_type)
{
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
+
if (log)
log->Printf("ClangExpressionDeclMap::CopyClassType - Couldn't import the type");
-
+
return TypeFromParser();
}
@@ -1993,21 +1965,21 @@ ClangExpressionDeclMap::CopyClassType(TypeFromUser &ut,
{
ClangASTType void_clang_type = ClangASTContext::GetBasicType(m_ast_context, eBasicTypeVoid);
ClangASTType void_ptr_clang_type = void_clang_type.GetPointerType();
-
+
ClangASTType method_type = ClangASTContext::CreateFunctionType (m_ast_context,
void_clang_type,
&void_ptr_clang_type,
1,
false,
copied_clang_type.GetTypeQualifiers());
-
+
const bool is_virtual = false;
const bool is_static = false;
const bool is_inline = false;
const bool is_explicit = false;
const bool is_attr_used = true;
const bool is_artificial = false;
-
+
copied_clang_type.AddMethodToCXXRecordType ("$__lldb_expr",
method_type,
lldb::eAccessPublic,
@@ -2018,26 +1990,26 @@ ClangExpressionDeclMap::CopyClassType(TypeFromUser &ut,
is_attr_used,
is_artificial);
}
-
+
return TypeFromParser(copied_clang_type);
}
-void
-ClangExpressionDeclMap::AddOneType(NameSearchContext &context,
+void
+ClangExpressionDeclMap::AddOneType(NameSearchContext &context,
TypeFromUser &ut,
unsigned int current_id)
{
ClangASTType copied_clang_type = GuardedCopyType(ut);
-
+
if (!copied_clang_type)
{
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
if (log)
log->Printf("ClangExpressionDeclMap::AddOneType - Couldn't import the type");
-
+
return;
}
-
+
context.AddTypeDecl(copied_clang_type);
}
diff --git a/contrib/llvm/tools/lldb/source/Expression/ClangExpressionParser.cpp b/contrib/llvm/tools/lldb/source/Expression/ClangExpressionParser.cpp
index 615f29f..f32ca3a 100644
--- a/contrib/llvm/tools/lldb/source/Expression/ClangExpressionParser.cpp
+++ b/contrib/llvm/tools/lldb/source/Expression/ClangExpressionParser.cpp
@@ -15,6 +15,7 @@
#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Disassembler.h"
+#include "lldb/Core/Module.h"
#include "lldb/Core/Stream.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Core/StreamString.h"
@@ -24,6 +25,9 @@
#include "lldb/Expression/IRExecutionUnit.h"
#include "lldb/Expression/IRDynamicChecks.h"
#include "lldb/Expression/IRInterpreter.h"
+#include "lldb/Host/File.h"
+#include "lldb/Host/HostInfo.h"
+#include "lldb/Symbol/SymbolVendor.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/ObjCLanguageRuntime.h"
#include "lldb/Target/Process.h"
@@ -55,11 +59,7 @@
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/TargetSelect.h"
-#if defined (USE_STANDARD_JIT)
-#include "llvm/ExecutionEngine/JIT.h"
-#else
#include "llvm/ExecutionEngine/MCJIT.h"
-#endif
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/ErrorHandling.h"
@@ -88,89 +88,8 @@ std::string GetBuiltinIncludePath(const char *Argv0) {
llvm::sys::path::append(P, "lib", "clang", CLANG_VERSION_STRING,
"include");
}
-
- return P.str();
-}
-
-
-//===----------------------------------------------------------------------===//
-// Main driver for Clang
-//===----------------------------------------------------------------------===//
-
-static void LLVMErrorHandler(void *UserData, const std::string &Message) {
- DiagnosticsEngine &Diags = *static_cast<DiagnosticsEngine*>(UserData);
-
- Diags.Report(diag::err_fe_error_backend) << Message;
-
- // We cannot recover from llvm errors.
- assert(0);
-}
-static FrontendAction *CreateFrontendBaseAction(CompilerInstance &CI) {
- using namespace clang::frontend;
-
- switch (CI.getFrontendOpts().ProgramAction) {
- default:
- llvm_unreachable("Invalid program action!");
-
- case ASTDump: return new ASTDumpAction();
- case ASTPrint: return new ASTPrintAction();
- case ASTView: return new ASTViewAction();
- case DumpRawTokens: return new DumpRawTokensAction();
- case DumpTokens: return new DumpTokensAction();
- case EmitAssembly: return new EmitAssemblyAction();
- case EmitBC: return new EmitBCAction();
- case EmitHTML: return new HTMLPrintAction();
- case EmitLLVM: return new EmitLLVMAction();
- case EmitLLVMOnly: return new EmitLLVMOnlyAction();
- case EmitCodeGenOnly: return new EmitCodeGenOnlyAction();
- case EmitObj: return new EmitObjAction();
- case FixIt: return new FixItAction();
- case GeneratePCH: return new GeneratePCHAction();
- case GeneratePTH: return new GeneratePTHAction();
- case InitOnly: return new InitOnlyAction();
- case ParseSyntaxOnly: return new SyntaxOnlyAction();
-
- case PluginAction: {
- for (FrontendPluginRegistry::iterator it =
- FrontendPluginRegistry::begin(), ie = FrontendPluginRegistry::end();
- it != ie; ++it) {
- if (it->getName() == CI.getFrontendOpts().ActionName) {
- llvm::OwningPtr<PluginASTAction> P(it->instantiate());
- if (!P->ParseArgs(CI, CI.getFrontendOpts().PluginArgs))
- return 0;
- return P.take();
- }
- }
-
- CI.getDiagnostics().Report(diag::err_fe_invalid_plugin_name)
- << CI.getFrontendOpts().ActionName;
- return 0;
- }
-
- case PrintDeclContext: return new DeclContextPrintAction();
- case PrintPreamble: return new PrintPreambleAction();
- case PrintPreprocessedInput: return new PrintPreprocessedAction();
- case RewriteMacros: return new RewriteMacrosAction();
- case RewriteObjC: return new RewriteObjCAction();
- case RewriteTest: return new RewriteTestAction();
- //case RunAnalysis: return new AnalysisAction();
- case RunPreprocessorOnly: return new PreprocessOnlyAction();
- }
-}
-
-static FrontendAction *CreateFrontendAction(CompilerInstance &CI) {
- // Create the underlying action.
- FrontendAction *Act = CreateFrontendBaseAction(CI);
- if (!Act)
- return 0;
-
- // If there are any AST files to merge, create a frontend action
- // adaptor to perform the merge.
- if (!CI.getFrontendOpts().ASTMergeFiles.empty())
- Act = new ASTMergeAction(Act, CI.getFrontendOpts().ASTMergeFiles);
-
- return Act;
+ return P.str();
}
//===----------------------------------------------------------------------===//
@@ -178,30 +97,21 @@ static FrontendAction *CreateFrontendAction(CompilerInstance &CI) {
//===----------------------------------------------------------------------===//
ClangExpressionParser::ClangExpressionParser (ExecutionContextScope *exe_scope,
- ClangExpression &expr) :
+ ClangExpression &expr,
+ bool generate_debug_info) :
m_expr (expr),
m_compiler (),
m_code_generator ()
{
- // Initialize targets first, so that --version shows registered targets.
- static struct InitializeLLVM {
- InitializeLLVM() {
- llvm::InitializeAllTargets();
- llvm::InitializeAllAsmPrinters();
- llvm::InitializeAllTargetMCs();
- llvm::InitializeAllDisassemblers();
- }
- } InitializeLLVM;
-
// 1. Create a new compiler instance.
- m_compiler.reset(new CompilerInstance());
-
+ m_compiler.reset(new CompilerInstance());
+
// 2. Install the target.
lldb::TargetSP target_sp;
if (exe_scope)
target_sp = exe_scope->CalculateTarget();
-
+
// TODO: figure out what to really do when we don't have a valid target.
// Sometimes this will be ok to just use the host target triple (when we
// evaluate say "2+3", but other expressions like breakpoint conditions
@@ -210,48 +120,40 @@ ClangExpressionParser::ClangExpressionParser (ExecutionContextScope *exe_scope,
if (target_sp && target_sp->GetArchitecture().IsValid())
{
std::string triple = target_sp->GetArchitecture().GetTriple().str();
-
- int dash_count = 0;
- for (size_t i = 0; i < triple.size(); ++i)
- {
- if (triple[i] == '-')
- dash_count++;
- if (dash_count == 3)
- {
- triple.resize(i);
- break;
- }
- }
-
m_compiler->getTargetOpts().Triple = triple;
}
else
{
m_compiler->getTargetOpts().Triple = llvm::sys::getDefaultTargetTriple();
}
-
+
if (target_sp->GetArchitecture().GetMachine() == llvm::Triple::x86 ||
target_sp->GetArchitecture().GetMachine() == llvm::Triple::x86_64)
{
m_compiler->getTargetOpts().Features.push_back("+sse");
m_compiler->getTargetOpts().Features.push_back("+sse2");
}
-
- if (m_compiler->getTargetOpts().Triple.find("ios") != std::string::npos)
+
+ // Any arm32 iOS environment, but not on arm64
+ if (m_compiler->getTargetOpts().Triple.find("arm64") == std::string::npos &&
+ m_compiler->getTargetOpts().Triple.find("arm") != std::string::npos &&
+ m_compiler->getTargetOpts().Triple.find("ios") != std::string::npos)
+ {
m_compiler->getTargetOpts().ABI = "apcs-gnu";
-
+ }
+
m_compiler->createDiagnostics();
-
+
// Create the target instance.
- m_compiler->setTarget(TargetInfo::CreateTargetInfo(m_compiler->getDiagnostics(),
- &m_compiler->getTargetOpts()));
-
+ m_compiler->setTarget(TargetInfo::CreateTargetInfo(
+ m_compiler->getDiagnostics(), m_compiler->getInvocation().TargetOpts));
+
assert (m_compiler->hasTarget());
-
+
// 3. Set options.
-
+
lldb::LanguageType language = expr.Language();
-
+
switch (language)
{
case lldb::eLanguageTypeC:
@@ -272,20 +174,20 @@ ClangExpressionParser::ClangExpressionParser (ExecutionContextScope *exe_scope,
m_compiler->getLangOpts().CPlusPlus11 = true;
break;
}
-
+
m_compiler->getLangOpts().Bool = true;
m_compiler->getLangOpts().WChar = true;
m_compiler->getLangOpts().Blocks = true;
m_compiler->getLangOpts().DebuggerSupport = true; // Features specifically for debugger clients
if (expr.DesiredResultType() == ClangExpression::eResultTypeId)
m_compiler->getLangOpts().DebuggerCastResultToId = true;
-
+
// Spell checking is a nice feature, but it ends up completing a
// lot of types that we didn't strictly speaking need to complete.
// As a result, we spend a long time parsing and importing debug
// information.
- m_compiler->getLangOpts().SpellChecking = false;
-
+ m_compiler->getLangOpts().SpellChecking = false;
+
lldb::ProcessSP process_sp;
if (exe_scope)
process_sp = exe_scope->CalculateProcess();
@@ -298,7 +200,7 @@ ClangExpressionParser::ClangExpressionParser (ExecutionContextScope *exe_scope,
m_compiler->getLangOpts().ObjCRuntime.set(ObjCRuntime::MacOSX, VersionTuple(10, 7));
else
m_compiler->getLangOpts().ObjCRuntime.set(ObjCRuntime::FragileMacOSX, VersionTuple(10, 7));
-
+
if (process_sp->GetObjCLanguageRuntime()->HasNewLiteralsAndIndexing())
m_compiler->getLangOpts().DebuggerObjCLiteral = true;
}
@@ -307,62 +209,67 @@ ClangExpressionParser::ClangExpressionParser (ExecutionContextScope *exe_scope,
m_compiler->getLangOpts().ThreadsafeStatics = false;
m_compiler->getLangOpts().AccessControl = false; // Debuggers get universal access
m_compiler->getLangOpts().DollarIdents = true; // $ indicates a persistent variable name
-
+
// Set CodeGen options
m_compiler->getCodeGenOpts().EmitDeclMetadata = true;
m_compiler->getCodeGenOpts().InstrumentFunctions = false;
m_compiler->getCodeGenOpts().DisableFPElim = true;
m_compiler->getCodeGenOpts().OmitLeafFramePointer = false;
-
+ if (generate_debug_info)
+ m_compiler->getCodeGenOpts().setDebugInfo(CodeGenOptions::FullDebugInfo);
+ else
+ m_compiler->getCodeGenOpts().setDebugInfo(CodeGenOptions::NoDebugInfo);
+
// Disable some warnings.
- m_compiler->getDiagnostics().setDiagnosticGroupMapping("unused-value", clang::diag::MAP_IGNORE, SourceLocation());
- m_compiler->getDiagnostics().setDiagnosticGroupMapping("odr", clang::diag::MAP_IGNORE, SourceLocation());
-
+ m_compiler->getDiagnostics().setSeverityForGroup(clang::diag::Flavor::WarningOrError,
+ "unused-value", clang::diag::Severity::Ignored, SourceLocation());
+ m_compiler->getDiagnostics().setSeverityForGroup(clang::diag::Flavor::WarningOrError,
+ "odr", clang::diag::Severity::Ignored, SourceLocation());
+
// Inform the target of the language options
//
// FIXME: We shouldn't need to do this, the target should be immutable once
// created. This complexity should be lifted elsewhere.
- m_compiler->getTarget().setForcedLangOptions(m_compiler->getLangOpts());
-
+ m_compiler->getTarget().adjust(m_compiler->getLangOpts());
+
// 4. Set up the diagnostic buffer for reporting errors
-
+
m_compiler->getDiagnostics().setClient(new clang::TextDiagnosticBuffer);
-
+
// 5. Set up the source management objects inside the compiler
-
+
clang::FileSystemOptions file_system_options;
m_file_manager.reset(new clang::FileManager(file_system_options));
-
+
if (!m_compiler->hasSourceManager())
m_compiler->createSourceManager(*m_file_manager.get());
-
+
m_compiler->createFileManager();
- m_compiler->createPreprocessor();
-
- // 6. Most of this we get from the CompilerInstance, but we
+ m_compiler->createPreprocessor(TU_Complete);
+
+ // 6. Most of this we get from the CompilerInstance, but we
// also want to give the context an ExternalASTSource.
m_selector_table.reset(new SelectorTable());
m_builtin_context.reset(new Builtin::Context());
-
+
std::unique_ptr<clang::ASTContext> ast_context(new ASTContext(m_compiler->getLangOpts(),
m_compiler->getSourceManager(),
- &m_compiler->getTarget(),
m_compiler->getPreprocessor().getIdentifierTable(),
*m_selector_table.get(),
- *m_builtin_context.get(),
- 0));
-
+ *m_builtin_context.get()));
+ ast_context->InitBuiltinTypes(m_compiler->getTarget());
+
ClangExpressionDeclMap *decl_map = m_expr.DeclMap();
-
+
if (decl_map)
{
- llvm::OwningPtr<clang::ExternalASTSource> ast_source(decl_map->CreateProxy());
+ llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> ast_source(decl_map->CreateProxy());
decl_map->InstallASTContext(ast_context.get());
ast_context->setExternalSource(ast_source);
}
-
+
m_compiler->setASTContext(ast_context.release());
-
+
std::string module_name("$__lldb_module");
m_llvm_context.reset(new LLVMContext());
@@ -381,34 +288,77 @@ unsigned
ClangExpressionParser::Parse (Stream &stream)
{
TextDiagnosticBuffer *diag_buf = static_cast<TextDiagnosticBuffer*>(m_compiler->getDiagnostics().getClient());
-
+
diag_buf->FlushDiagnostics (m_compiler->getDiagnostics());
-
- MemoryBuffer *memory_buffer = MemoryBuffer::getMemBufferCopy(m_expr.Text(), __FUNCTION__);
- m_compiler->getSourceManager().createMainFileIDForMemBuffer (memory_buffer);
-
+
+ const char *expr_text = m_expr.Text();
+
+ clang::SourceManager &SourceMgr = m_compiler->getSourceManager();
+ bool created_main_file = false;
+ if (m_compiler->getCodeGenOpts().getDebugInfo() == CodeGenOptions::FullDebugInfo)
+ {
+ std::string temp_source_path;
+
+ FileSpec tmpdir_file_spec;
+ if (HostInfo::GetLLDBPath(lldb::ePathTypeLLDBTempSystemDir, tmpdir_file_spec))
+ {
+ tmpdir_file_spec.AppendPathComponent("expr.XXXXXX");
+ temp_source_path = std::move(tmpdir_file_spec.GetPath());
+ }
+ else
+ {
+ temp_source_path = "/tmp/expr.XXXXXX";
+ }
+
+ if (mktemp(&temp_source_path[0]))
+ {
+ lldb_private::File file (temp_source_path.c_str(),
+ File::eOpenOptionWrite | File::eOpenOptionCanCreateNewOnly,
+ lldb::eFilePermissionsFileDefault);
+ const size_t expr_text_len = strlen(expr_text);
+ size_t bytes_written = expr_text_len;
+ if (file.Write(expr_text, bytes_written).Success())
+ {
+ if (bytes_written == expr_text_len)
+ {
+ file.Close();
+ SourceMgr.setMainFileID(SourceMgr.createFileID(
+ m_file_manager->getFile(temp_source_path),
+ SourceLocation(), SrcMgr::C_User));
+ created_main_file = true;
+ }
+ }
+ }
+ }
+
+ if (!created_main_file)
+ {
+ std::unique_ptr<MemoryBuffer> memory_buffer = MemoryBuffer::getMemBufferCopy(expr_text, __FUNCTION__);
+ SourceMgr.setMainFileID(SourceMgr.createFileID(std::move(memory_buffer)));
+ }
+
diag_buf->BeginSourceFile(m_compiler->getLangOpts(), &m_compiler->getPreprocessor());
-
+
ASTConsumer *ast_transformer = m_expr.ASTTransformer(m_code_generator.get());
-
+
if (ast_transformer)
ParseAST(m_compiler->getPreprocessor(), ast_transformer, m_compiler->getASTContext());
- else
- ParseAST(m_compiler->getPreprocessor(), m_code_generator.get(), m_compiler->getASTContext());
-
+ else
+ ParseAST(m_compiler->getPreprocessor(), m_code_generator.get(), m_compiler->getASTContext());
+
diag_buf->EndSourceFile();
-
+
TextDiagnosticBuffer::const_iterator diag_iterator;
-
+
int num_errors = 0;
-
+
for (diag_iterator = diag_buf->warn_begin();
diag_iterator != diag_buf->warn_end();
++diag_iterator)
stream.Printf("warning: %s\n", (*diag_iterator).second.c_str());
-
+
num_errors = 0;
-
+
for (diag_iterator = diag_buf->err_begin();
diag_iterator != diag_buf->err_end();
++diag_iterator)
@@ -416,12 +366,12 @@ ClangExpressionParser::Parse (Stream &stream)
num_errors++;
stream.Printf("error: %s\n", (*diag_iterator).second.c_str());
}
-
+
for (diag_iterator = diag_buf->note_begin();
diag_iterator != diag_buf->note_end();
++diag_iterator)
stream.Printf("note: %s\n", (*diag_iterator).second.c_str());
-
+
if (!num_errors)
{
if (m_expr.DeclMap() && !m_expr.DeclMap()->ResolveUnknownTypes())
@@ -430,7 +380,7 @@ ClangExpressionParser::Parse (Stream &stream)
num_errors++;
}
}
-
+
return num_errors;
}
@@ -441,21 +391,21 @@ static bool FindFunctionInModule (ConstString &mangled_name,
for (llvm::Module::iterator fi = module->getFunctionList().begin(), fe = module->getFunctionList().end();
fi != fe;
++fi)
- {
+ {
if (fi->getName().str().find(orig_name) != std::string::npos)
{
mangled_name.SetCString(fi->getName().str().c_str());
return true;
}
}
-
+
return false;
}
Error
-ClangExpressionParser::PrepareForExecution (lldb::addr_t &func_addr,
+ClangExpressionParser::PrepareForExecution (lldb::addr_t &func_addr,
lldb::addr_t &func_end,
- std::unique_ptr<IRExecutionUnit> &execution_unit_ap,
+ std::shared_ptr<IRExecutionUnit> &execution_unit_sp,
ExecutionContext &exe_ctx,
bool &can_interpret,
ExecutionPolicy execution_policy)
@@ -464,24 +414,22 @@ ClangExpressionParser::PrepareForExecution (lldb::addr_t &func_addr,
func_end = LLDB_INVALID_ADDRESS;
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
- std::unique_ptr<llvm::ExecutionEngine> execution_engine_ap;
-
Error err;
-
- std::unique_ptr<llvm::Module> module_ap (m_code_generator->ReleaseModule());
- if (!module_ap.get())
+ std::unique_ptr<llvm::Module> llvm_module_ap (m_code_generator->ReleaseModule());
+
+ if (!llvm_module_ap.get())
{
err.SetErrorToGenericError();
err.SetErrorString("IR doesn't contain a module");
return err;
}
-
+
// Find the actual name of the function (it's often mangled somehow)
-
+
ConstString function_name;
-
- if (!FindFunctionInModule(function_name, module_ap.get(), m_expr.FunctionName()))
+
+ if (!FindFunctionInModule(function_name, llvm_module_ap.get(), m_expr.FunctionName()))
{
err.SetErrorToGenericError();
err.SetErrorStringWithFormat("Couldn't find %s() in the module", m_expr.FunctionName());
@@ -492,54 +440,54 @@ ClangExpressionParser::PrepareForExecution (lldb::addr_t &func_addr,
if (log)
log->Printf("Found function %s for %s", function_name.AsCString(), m_expr.FunctionName());
}
-
- m_execution_unit.reset(new IRExecutionUnit(m_llvm_context, // handed off here
- module_ap, // handed off here
- function_name,
- exe_ctx.GetTargetSP(),
- m_compiler->getTargetOpts().Features));
-
+
+ execution_unit_sp.reset(new IRExecutionUnit (m_llvm_context, // handed off here
+ llvm_module_ap, // handed off here
+ function_name,
+ exe_ctx.GetTargetSP(),
+ m_compiler->getTargetOpts().Features));
+
ClangExpressionDeclMap *decl_map = m_expr.DeclMap(); // result can be NULL
-
+
if (decl_map)
{
Stream *error_stream = NULL;
Target *target = exe_ctx.GetTargetPtr();
if (target)
error_stream = target->GetDebugger().GetErrorFile().get();
-
+
IRForTarget ir_for_target(decl_map,
m_expr.NeedsVariableResolution(),
- *m_execution_unit,
+ *execution_unit_sp,
error_stream,
function_name.AsCString());
-
- bool ir_can_run = ir_for_target.runOnModule(*m_execution_unit->GetModule());
-
+
+ bool ir_can_run = ir_for_target.runOnModule(*execution_unit_sp->GetModule());
+
Error interpret_error;
-
- can_interpret = IRInterpreter::CanInterpret(*m_execution_unit->GetModule(), *m_execution_unit->GetFunction(), interpret_error);
-
+
+ can_interpret = IRInterpreter::CanInterpret(*execution_unit_sp->GetModule(), *execution_unit_sp->GetFunction(), interpret_error);
+
Process *process = exe_ctx.GetProcessPtr();
-
+
if (!ir_can_run)
{
err.SetErrorString("The expression could not be prepared to run in the target");
return err;
}
-
+
if (!can_interpret && execution_policy == eExecutionPolicyNever)
{
err.SetErrorStringWithFormat("Can't run the expression locally: %s", interpret_error.AsCString());
return err;
}
-
+
if (!process && execution_policy == eExecutionPolicyAlways)
{
err.SetErrorString("Expression needed to run in the target, but the target can't be run");
return err;
}
-
+
if (execution_policy == eExecutionPolicyAlways || !can_interpret)
{
if (m_expr.NeedsValidation() && process)
@@ -547,44 +495,50 @@ ClangExpressionParser::PrepareForExecution (lldb::addr_t &func_addr,
if (!process->GetDynamicCheckers())
{
DynamicCheckerFunctions *dynamic_checkers = new DynamicCheckerFunctions();
-
+
StreamString install_errors;
-
+
if (!dynamic_checkers->Install(install_errors, exe_ctx))
{
if (install_errors.GetString().empty())
err.SetErrorString ("couldn't install checkers, unknown error");
else
err.SetErrorString (install_errors.GetString().c_str());
-
+
return err;
}
-
+
process->SetDynamicCheckers(dynamic_checkers);
-
+
if (log)
log->Printf("== [ClangUserExpression::Evaluate] Finished installing dynamic checkers ==");
}
-
+
IRDynamicChecks ir_dynamic_checks(*process->GetDynamicCheckers(), function_name.AsCString());
-
- if (!ir_dynamic_checks.runOnModule(*m_execution_unit->GetModule()))
+
+ if (!ir_dynamic_checks.runOnModule(*execution_unit_sp->GetModule()))
{
err.SetErrorToGenericError();
err.SetErrorString("Couldn't add dynamic checks to the expression");
return err;
}
}
-
- m_execution_unit->GetRunnableInfo(err, func_addr, func_end);
+
+ execution_unit_sp->GetRunnableInfo(err, func_addr, func_end);
}
}
else
{
- m_execution_unit->GetRunnableInfo(err, func_addr, func_end);
+ execution_unit_sp->GetRunnableInfo(err, func_addr, func_end);
}
-
- execution_unit_ap.reset (m_execution_unit.release());
-
+
return err;
}
+
+bool
+ClangExpressionParser::GetGenerateDebugInfo () const
+{
+ if (m_compiler)
+ return m_compiler->getCodeGenOpts().getDebugInfo() == CodeGenOptions::FullDebugInfo;
+ return false;
+}
diff --git a/contrib/llvm/tools/lldb/source/Expression/ClangExpressionVariable.cpp b/contrib/llvm/tools/lldb/source/Expression/ClangExpressionVariable.cpp
index 0d355ce..c3eae41 100644
--- a/contrib/llvm/tools/lldb/source/Expression/ClangExpressionVariable.cpp
+++ b/contrib/llvm/tools/lldb/source/Expression/ClangExpressionVariable.cpp
@@ -8,11 +8,6 @@
//===----------------------------------------------------------------------===//
#include "lldb/Expression/ClangExpressionVariable.h"
-
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "clang/AST/ASTContext.h"
#include "lldb/Core/ConstString.h"
#include "lldb/Core/DataExtractor.h"
@@ -44,17 +39,17 @@ ClangExpressionVariable::ClangExpressionVariable (const lldb::ValueObjectSP &val
//----------------------------------------------------------------------
/// Return the variable's size in bytes
//----------------------------------------------------------------------
-size_t
+size_t
ClangExpressionVariable::GetByteSize ()
{
return m_frozen_sp->GetByteSize();
-}
+}
const ConstString &
ClangExpressionVariable::GetName ()
{
return m_frozen_sp->GetName();
-}
+}
lldb::ValueObjectSP
ClangExpressionVariable::GetValueObject()
@@ -78,13 +73,13 @@ ClangASTType
ClangExpressionVariable::GetClangType()
{
return m_frozen_sp->GetClangType();
-}
+}
void
ClangExpressionVariable::SetClangType(const ClangASTType &clang_type)
{
m_frozen_sp->GetValue().SetClangType(clang_type);
-}
+}
TypeFromUser
@@ -92,7 +87,7 @@ ClangExpressionVariable::GetTypeFromUser()
{
TypeFromUser tfu (m_frozen_sp->GetClangType());
return tfu;
-}
+}
uint8_t *
ClangExpressionVariable::GetValueBytes()
@@ -130,7 +125,7 @@ ClangExpressionVariable::TransferAddress (bool force)
if (m_frozen_sp.get() == NULL)
return;
-
+
if (force || (m_frozen_sp->GetLiveAddress() == LLDB_INVALID_ADDRESS))
m_frozen_sp->SetLiveAddress(m_live_sp->GetLiveAddress());
}
diff --git a/contrib/llvm/tools/lldb/source/Expression/ClangFunction.cpp b/contrib/llvm/tools/lldb/source/Expression/ClangFunction.cpp
index e707c60..27afba2 100644
--- a/contrib/llvm/tools/lldb/source/Expression/ClangFunction.cpp
+++ b/contrib/llvm/tools/lldb/source/Expression/ClangFunction.cpp
@@ -22,18 +22,20 @@
#include "llvm/IR/Module.h"
// Project includes
-#include "lldb/Expression/ASTStructExtractor.h"
-#include "lldb/Expression/ClangExpressionParser.h"
-#include "lldb/Expression/ClangFunction.h"
-#include "lldb/Expression/IRExecutionUnit.h"
-#include "lldb/Symbol/Type.h"
#include "lldb/Core/DataExtractor.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Core/Module.h"
#include "lldb/Core/State.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Core/ValueObjectList.h"
+#include "lldb/Expression/ASTStructExtractor.h"
+#include "lldb/Expression/ClangExpressionParser.h"
+#include "lldb/Expression/ClangFunction.h"
+#include "lldb/Expression/IRExecutionUnit.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/Function.h"
+#include "lldb/Symbol/Type.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
@@ -41,7 +43,6 @@
#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadPlan.h"
#include "lldb/Target/ThreadPlanCallFunction.h"
-#include "lldb/Core/Log.h"
using namespace lldb_private;
@@ -53,8 +54,13 @@ ClangFunction::ClangFunction
ExecutionContextScope &exe_scope,
const ClangASTType &return_type,
const Address& functionAddress,
- const ValueList &arg_value_list
+ const ValueList &arg_value_list,
+ const char *name
) :
+ m_parser(),
+ m_execution_unit_sp(),
+ m_jit_module_wp(),
+ m_name (name ? name : "<unknown>"),
m_function_ptr (NULL),
m_function_addr (functionAddress),
m_function_return_type(return_type),
@@ -75,8 +81,10 @@ ClangFunction::ClangFunction
ExecutionContextScope &exe_scope,
Function &function,
ClangASTContext *ast_context,
- const ValueList &arg_value_list
+ const ValueList &arg_value_list,
+ const char *name
) :
+ m_name (name ? name : "<unknown>"),
m_function_ptr (&function),
m_function_addr (),
m_function_return_type (),
@@ -87,7 +95,7 @@ ClangFunction::ClangFunction
m_compiled (false),
m_JITted (false)
{
- m_jit_process_wp = lldb::ProcessWP(exe_scope.CalculateProcess());
+ m_jit_process_wp = exe_scope.CalculateProcess();
// Can't make a ClangFunction without a process.
assert (m_jit_process_wp.lock());
@@ -100,6 +108,13 @@ ClangFunction::ClangFunction
//----------------------------------------------------------------------
ClangFunction::~ClangFunction()
{
+ lldb::ProcessSP process_sp (m_jit_process_wp.lock());
+ if (process_sp)
+ {
+ lldb::ModuleSP jit_module_sp (m_jit_module_wp.lock());
+ if (jit_module_sp)
+ process_sp->GetTarget().GetImages().Remove(jit_module_sp);
+ }
}
unsigned
@@ -173,7 +188,7 @@ ClangFunction::CompileFunction (Stream &errors)
}
else
{
- errors.Printf("Could not determine type of input value %zu.", i);
+ errors.Printf("Could not determine type of input value %" PRIu64 ".", (uint64_t)i);
return 1;
}
}
@@ -222,7 +237,8 @@ ClangFunction::CompileFunction (Stream &errors)
lldb::ProcessSP jit_process_sp(m_jit_process_wp.lock());
if (jit_process_sp)
{
- m_parser.reset(new ClangExpressionParser(jit_process_sp.get(), *this));
+ const bool generate_debug_info = true;
+ m_parser.reset(new ClangExpressionParser(jit_process_sp.get(), *this, generate_debug_info));
num_errors = m_parser->Parse (errors);
}
@@ -263,7 +279,7 @@ ClangFunction::WriteFunctionWrapper (ExecutionContext &exe_ctx, Stream &errors)
Error jit_error (m_parser->PrepareForExecution (m_jit_start_addr,
m_jit_end_addr,
- m_execution_unit_ap,
+ m_execution_unit_sp,
exe_ctx,
can_interpret,
eExecutionPolicyAlways));
@@ -271,8 +287,22 @@ ClangFunction::WriteFunctionWrapper (ExecutionContext &exe_ctx, Stream &errors)
if (!jit_error.Success())
return false;
+ if (m_parser->GetGenerateDebugInfo())
+ {
+ lldb::ModuleSP jit_module_sp ( m_execution_unit_sp->GetJITModule());
+
+ if (jit_module_sp)
+ {
+ ConstString const_func_name(FunctionName());
+ FileSpec jit_file;
+ jit_file.GetFilename() = const_func_name;
+ jit_module_sp->SetFileSpecAndObjectName (jit_file, ConstString());
+ m_jit_module_wp = jit_module_sp;
+ process->GetTarget().GetImages().Append(jit_module_sp);
+ }
+ }
if (process && m_jit_start_addr)
- m_jit_process_wp = lldb::ProcessWP(process->shared_from_this());
+ m_jit_process_wp = process->shared_from_this();
m_JITted = true;
@@ -304,7 +334,7 @@ ClangFunction::WriteFunctionArguments (ExecutionContext &exe_ctx,
Error error;
using namespace clang;
- ExecutionResults return_value = eExecutionSetupError;
+ lldb::ExpressionResults return_value = lldb::eExpressionSetupError;
Process *process = exe_ctx.GetProcessPtr();
@@ -344,7 +374,7 @@ ClangFunction::WriteFunctionArguments (ExecutionContext &exe_ctx,
size_t num_args = arg_values.GetSize();
if (num_args != m_arg_values.GetSize())
{
- errors.Printf ("Wrong number of arguments - was: %zu should be: %zu", num_args, m_arg_values.GetSize());
+ errors.Printf ("Wrong number of arguments - was: %" PRIu64 " should be: %" PRIu64 "", (uint64_t)num_args, (uint64_t)m_arg_values.GetSize());
return false;
}
@@ -401,7 +431,7 @@ ClangFunction::GetThreadPlanToCallFunction (ExecutionContext &exe_ctx,
Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP));
if (log)
- log->Printf("-- [ClangFunction::GetThreadPlanToCallFunction] Creating thread plan to call function --");
+ log->Printf("-- [ClangFunction::GetThreadPlanToCallFunction] Creating thread plan to call function \"%s\" --", m_name.c_str());
// FIXME: Use the errors Stream for better error reporting.
Thread *thread = exe_ctx.GetThreadPtr();
@@ -438,7 +468,7 @@ ClangFunction::FetchFunctionResults (ExecutionContext &exe_ctx, lldb::addr_t arg
Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP));
if (log)
- log->Printf("-- [ClangFunction::FetchFunctionResults] Fetching function results --");
+ log->Printf("-- [ClangFunction::FetchFunctionResults] Fetching function results for \"%s\"--", m_name.c_str());
Process *process = exe_ctx.GetProcessPtr();
@@ -472,7 +502,7 @@ ClangFunction::DeallocateFunctionResults (ExecutionContext &exe_ctx, lldb::addr_
exe_ctx.GetProcessRef().DeallocateMemory(args_addr);
}
-ExecutionResults
+lldb::ExpressionResults
ClangFunction::ExecuteFunction(
ExecutionContext &exe_ctx,
lldb::addr_t *args_addr_ptr,
@@ -481,7 +511,7 @@ ClangFunction::ExecuteFunction(
Value &results)
{
using namespace clang;
- ExecutionResults return_value = eExecutionSetupError;
+ lldb::ExpressionResults return_value = lldb::eExpressionSetupError;
// ClangFunction::ExecuteFunction execution is always just to get the result. Do make sure we ignore
// breakpoints, unwind on error, and don't try to debug it.
@@ -498,27 +528,27 @@ ClangFunction::ExecuteFunction(
args_addr = LLDB_INVALID_ADDRESS;
if (CompileFunction(errors) != 0)
- return eExecutionSetupError;
+ return lldb::eExpressionSetupError;
if (args_addr == LLDB_INVALID_ADDRESS)
{
if (!InsertFunction(exe_ctx, args_addr, errors))
- return eExecutionSetupError;
+ return lldb::eExpressionSetupError;
}
Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP));
if (log)
- log->Printf("== [ClangFunction::ExecuteFunction] Executing function ==");
+ log->Printf("== [ClangFunction::ExecuteFunction] Executing function \"%s\" ==", m_name.c_str());
lldb::ThreadPlanSP call_plan_sp (GetThreadPlanToCallFunction (exe_ctx,
args_addr,
real_options,
errors));
if (!call_plan_sp)
- return eExecutionSetupError;
+ return lldb::eExpressionSetupError;
- // <rdar://problem/12027563> we need to make sure we record the fact that we are running an expression here
+ // We need to make sure we record the fact that we are running an expression here
// otherwise this fact will fail to be recorded when fetching an Objective-C object description
if (exe_ctx.GetProcessPtr())
exe_ctx.GetProcessPtr()->SetRunningUserExpression(true);
@@ -530,13 +560,13 @@ ClangFunction::ExecuteFunction(
if (log)
{
- if (return_value != eExecutionCompleted)
+ if (return_value != lldb::eExpressionCompleted)
{
- log->Printf("== [ClangFunction::ExecuteFunction] Execution completed abnormally ==");
+ log->Printf("== [ClangFunction::ExecuteFunction] Execution of \"%s\" completed abnormally ==", m_name.c_str());
}
else
{
- log->Printf("== [ClangFunction::ExecuteFunction] Execution completed normally ==");
+ log->Printf("== [ClangFunction::ExecuteFunction] Execution of \"%s\" completed normally ==", m_name.c_str());
}
}
@@ -546,7 +576,7 @@ ClangFunction::ExecuteFunction(
if (args_addr_ptr != NULL)
*args_addr_ptr = args_addr;
- if (return_value != eExecutionCompleted)
+ if (return_value != lldb::eExpressionCompleted)
return return_value;
FetchFunctionResults(exe_ctx, args_addr, results);
@@ -554,7 +584,7 @@ ClangFunction::ExecuteFunction(
if (args_addr_ptr == NULL)
DeallocateFunctionResults(exe_ctx, args_addr);
- return eExecutionCompleted;
+ return lldb::eExpressionCompleted;
}
clang::ASTConsumer *
diff --git a/contrib/llvm/tools/lldb/source/Expression/ClangUserExpression.cpp b/contrib/llvm/tools/lldb/source/Expression/ClangUserExpression.cpp
index 6b0eee8..52ef4d3 100644
--- a/contrib/llvm/tools/lldb/source/Expression/ClangUserExpression.cpp
+++ b/contrib/llvm/tools/lldb/source/Expression/ClangUserExpression.cpp
@@ -7,19 +7,18 @@
//
//===----------------------------------------------------------------------===//
-// C Includes
#include <stdio.h>
#if HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
-// C++ Includes
#include <cstdlib>
#include <string>
#include <map>
#include "lldb/Core/ConstString.h"
#include "lldb/Core/Log.h"
+#include "lldb/Core/Module.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Core/ValueObjectConstResult.h"
@@ -32,10 +31,12 @@
#include "lldb/Expression/IRExecutionUnit.h"
#include "lldb/Expression/IRInterpreter.h"
#include "lldb/Expression/Materializer.h"
-#include "lldb/Host/Host.h"
+#include "lldb/Host/HostInfo.h"
#include "lldb/Symbol/Block.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/Function.h"
+#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Symbol/SymbolVendor.h"
#include "lldb/Symbol/Type.h"
#include "lldb/Symbol/ClangExternalASTSourceCommon.h"
#include "lldb/Symbol/VariableList.h"
@@ -63,6 +64,11 @@ ClangUserExpression::ClangUserExpression (const char *expr,
m_language (language),
m_transformed_text (),
m_desired_type (desired_type),
+ m_expr_decl_map(),
+ m_execution_unit_sp(),
+ m_materializer_ap(),
+ m_result_synthesizer(),
+ m_jit_module_wp(),
m_enforce_valid_object (true),
m_cplusplus (false),
m_objectivec (false),
@@ -91,6 +97,12 @@ ClangUserExpression::ClangUserExpression (const char *expr,
ClangUserExpression::~ClangUserExpression ()
{
+ if (m_target)
+ {
+ lldb::ModuleSP jit_module_sp (m_jit_module_wp.lock());
+ if (jit_module_sp)
+ m_target->GetImages().Remove(jit_module_sp);
+ }
}
clang::ASTConsumer *
@@ -98,7 +110,7 @@ ClangUserExpression::ASTTransformer (clang::ASTConsumer *passthrough)
{
m_result_synthesizer.reset(new ASTResultSynthesizer(passthrough,
*m_target));
-
+
return m_result_synthesizer.get();
}
@@ -109,16 +121,16 @@ ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Error &err)
if (log)
log->Printf("ClangUserExpression::ScanContext()");
-
+
m_target = exe_ctx.GetTargetPtr();
-
+
if (!(m_allow_cxx || m_allow_objc))
{
if (log)
log->Printf(" [CUE::SC] Settings inhibit C++ and Objective-C");
return;
}
-
+
StackFrame *frame = exe_ctx.GetFramePtr();
if (frame == NULL)
{
@@ -126,19 +138,19 @@ ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Error &err)
log->Printf(" [CUE::SC] Null stack frame");
return;
}
-
+
SymbolContext sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction | lldb::eSymbolContextBlock);
-
+
if (!sym_ctx.function)
{
if (log)
log->Printf(" [CUE::SC] Null function");
return;
}
-
+
// Find the block that defines the function represented by "sym_ctx"
Block *function_block = sym_ctx.GetFunctionBlock();
-
+
if (!function_block)
{
if (log)
@@ -154,7 +166,7 @@ ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Error &err)
log->Printf(" [CUE::SC] Null decl context");
return;
}
-
+
if (clang::CXXMethodDecl *method_decl = llvm::dyn_cast<clang::CXXMethodDecl>(decl_context))
{
if (m_allow_cxx && method_decl->isInstance())
@@ -162,60 +174,60 @@ ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Error &err)
if (m_enforce_valid_object)
{
lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true));
-
+
const char *thisErrorString = "Stopped in a C++ method, but 'this' isn't available; pretending we are in a generic context";
-
+
if (!variable_list_sp)
{
err.SetErrorString(thisErrorString);
return;
}
-
+
lldb::VariableSP this_var_sp (variable_list_sp->FindVariable(ConstString("this")));
-
+
if (!this_var_sp ||
- !this_var_sp->IsInScope(frame) ||
+ !this_var_sp->IsInScope(frame) ||
!this_var_sp->LocationIsValidForFrame (frame))
{
err.SetErrorString(thisErrorString);
return;
}
}
-
+
m_cplusplus = true;
m_needs_object_ptr = true;
}
}
else if (clang::ObjCMethodDecl *method_decl = llvm::dyn_cast<clang::ObjCMethodDecl>(decl_context))
- {
+ {
if (m_allow_objc)
{
if (m_enforce_valid_object)
{
lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true));
-
+
const char *selfErrorString = "Stopped in an Objective-C method, but 'self' isn't available; pretending we are in a generic context";
-
+
if (!variable_list_sp)
{
err.SetErrorString(selfErrorString);
return;
}
-
+
lldb::VariableSP self_variable_sp = variable_list_sp->FindVariable(ConstString("self"));
-
- if (!self_variable_sp ||
- !self_variable_sp->IsInScope(frame) ||
+
+ if (!self_variable_sp ||
+ !self_variable_sp->IsInScope(frame) ||
!self_variable_sp->LocationIsValidForFrame (frame))
{
err.SetErrorString(selfErrorString);
return;
}
}
-
+
m_objectivec = true;
m_needs_object_ptr = true;
-
+
if (!method_decl->isInstanceMethod())
m_static_method = true;
}
@@ -226,7 +238,7 @@ ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Error &err)
// object pointer. The best way to deal with getting to the ivars at present it by pretending
// that this is a method of a class in whatever runtime the debug info says the object pointer
// belongs to. Do that here.
-
+
ClangASTMetadata *metadata = ClangASTContext::GetMetadata (&decl_context->getParentASTContext(), function_decl);
if (metadata && metadata->HasObjectPtr())
{
@@ -236,17 +248,17 @@ ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Error &err)
if (m_enforce_valid_object)
{
lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true));
-
+
const char *thisErrorString = "Stopped in a context claiming to capture a C++ object pointer, but 'this' isn't available; pretending we are in a generic context";
-
+
if (!variable_list_sp)
{
err.SetErrorString(thisErrorString);
return;
}
-
+
lldb::VariableSP this_var_sp (variable_list_sp->FindVariable(ConstString("this")));
-
+
if (!this_var_sp ||
!this_var_sp->IsInScope(frame) ||
!this_var_sp->LocationIsValidForFrame (frame))
@@ -255,7 +267,7 @@ ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Error &err)
return;
}
}
-
+
m_cplusplus = true;
m_needs_object_ptr = true;
}
@@ -264,17 +276,17 @@ ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Error &err)
if (m_enforce_valid_object)
{
lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true));
-
+
const char *selfErrorString = "Stopped in a context claiming to capture an Objective-C object pointer, but 'self' isn't available; pretending we are in a generic context";
-
+
if (!variable_list_sp)
{
err.SetErrorString(selfErrorString);
return;
}
-
+
lldb::VariableSP self_variable_sp = variable_list_sp->FindVariable(ConstString("self"));
-
+
if (!self_variable_sp ||
!self_variable_sp->IsInScope(frame) ||
!self_variable_sp->LocationIsValidForFrame (frame))
@@ -282,23 +294,23 @@ ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Error &err)
err.SetErrorString(selfErrorString);
return;
}
-
+
Type *self_type = self_variable_sp->GetType();
-
+
if (!self_type)
{
err.SetErrorString(selfErrorString);
return;
}
-
+
ClangASTType self_clang_type = self_type->GetClangForwardType();
-
+
if (!self_clang_type)
{
err.SetErrorString(selfErrorString);
return;
}
-
+
if (self_clang_type.IsObjCClassType())
{
return;
@@ -328,9 +340,9 @@ void
ClangUserExpression::InstallContext (ExecutionContext &exe_ctx)
{
m_process_wp = exe_ctx.GetProcessSP();
-
+
lldb::StackFrameSP frame_sp = exe_ctx.GetFrameSP();
-
+
if (frame_sp)
m_address = frame_sp->GetFrameCodeAddress();
}
@@ -346,11 +358,11 @@ ClangUserExpression::LockAndCheckContext (ExecutionContext &exe_ctx,
if (process_sp != expected_process_sp)
return false;
-
+
process_sp = exe_ctx.GetProcessSP();
target_sp = exe_ctx.GetTargetSP();
frame_sp = exe_ctx.GetFrameSP();
-
+
if (m_address.IsValid())
{
if (!frame_sp)
@@ -358,7 +370,7 @@ ClangUserExpression::LockAndCheckContext (ExecutionContext &exe_ctx,
else
return (0 == Address::CompareLoadAddress(m_address, frame_sp->GetFrameCodeAddress(), target_sp.get()));
}
-
+
return true;
}
@@ -368,7 +380,7 @@ ClangUserExpression::MatchesContext (ExecutionContext &exe_ctx)
lldb::TargetSP target_sp;
lldb::ProcessSP process_sp;
lldb::StackFrameSP frame_sp;
-
+
return LockAndCheckContext(exe_ctx, target_sp, process_sp, frame_sp);
}
@@ -383,7 +395,7 @@ ApplyObjcCastHack(std::string &expr)
#define OBJC_CAST_HACK_TO "(int)(long long)["
size_t from_offset;
-
+
while ((from_offset = expr.find(OBJC_CAST_HACK_FROM)) != expr.npos)
expr.replace(from_offset, sizeof(OBJC_CAST_HACK_FROM) - 1, OBJC_CAST_HACK_TO);
@@ -396,99 +408,100 @@ ApplyObjcCastHack(std::string &expr)
// hopefully we'll figure out a way to #include the same environment as is
// present in the original source file rather than try to hack specific type
// definitions in as needed.
-static void
-ApplyUnicharHack(std::string &expr)
-{
-#define UNICHAR_HACK_FROM "unichar"
-#define UNICHAR_HACK_TO "unsigned short"
-
- size_t from_offset;
-
- while ((from_offset = expr.find(UNICHAR_HACK_FROM)) != expr.npos)
- expr.replace(from_offset, sizeof(UNICHAR_HACK_FROM) - 1, UNICHAR_HACK_TO);
-
-#undef UNICHAR_HACK_TO
-#undef UNICHAR_HACK_FROM
-}
+//static void
+//ApplyUnicharHack(std::string &expr)
+//{
+//#define UNICHAR_HACK_FROM "unichar"
+//#define UNICHAR_HACK_TO "unsigned short"
+//
+// size_t from_offset;
+//
+// while ((from_offset = expr.find(UNICHAR_HACK_FROM)) != expr.npos)
+// expr.replace(from_offset, sizeof(UNICHAR_HACK_FROM) - 1, UNICHAR_HACK_TO);
+//
+//#undef UNICHAR_HACK_TO
+//#undef UNICHAR_HACK_FROM
+//}
bool
-ClangUserExpression::Parse (Stream &error_stream,
+ClangUserExpression::Parse (Stream &error_stream,
ExecutionContext &exe_ctx,
lldb_private::ExecutionPolicy execution_policy,
- bool keep_result_in_memory)
+ bool keep_result_in_memory,
+ bool generate_debug_info)
{
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
+
Error err;
-
+
InstallContext(exe_ctx);
-
+
ScanContext(exe_ctx, err);
-
+
if (!err.Success())
{
error_stream.Printf("warning: %s\n", err.AsCString());
}
-
+
StreamString m_transformed_stream;
-
+
////////////////////////////////////
// Generate the expression
//
-
+
ApplyObjcCastHack(m_expr_text);
//ApplyUnicharHack(m_expr_text);
std::unique_ptr<ExpressionSourceCode> source_code (ExpressionSourceCode::CreateWrapped(m_expr_prefix.c_str(), m_expr_text.c_str()));
-
+
lldb::LanguageType lang_type;
-
+
if (m_cplusplus)
lang_type = lldb::eLanguageTypeC_plus_plus;
else if(m_objectivec)
lang_type = lldb::eLanguageTypeObjC;
else
lang_type = lldb::eLanguageTypeC;
-
- if (!source_code->GetText(m_transformed_text, lang_type, m_const_object, m_static_method))
+
+ if (!source_code->GetText(m_transformed_text, lang_type, m_const_object, m_static_method, exe_ctx))
{
error_stream.PutCString ("error: couldn't construct expression body");
return false;
}
-
+
if (log)
log->Printf("Parsing the following code:\n%s", m_transformed_text.c_str());
-
+
////////////////////////////////////
// Set up the target and compiler
//
-
+
Target *target = exe_ctx.GetTargetPtr();
-
+
if (!target)
{
error_stream.PutCString ("error: invalid target\n");
return false;
}
-
+
//////////////////////////
// Parse the expression
//
-
+
m_materializer_ap.reset(new Materializer());
-
+
m_expr_decl_map.reset(new ClangExpressionDeclMap(keep_result_in_memory, exe_ctx));
-
+
class OnExit
{
public:
typedef std::function <void (void)> Callback;
-
+
OnExit (Callback const &callback) :
m_callback(callback)
{
}
-
+
~OnExit ()
{
m_callback();
@@ -496,50 +509,81 @@ ClangUserExpression::Parse (Stream &error_stream,
private:
Callback m_callback;
};
-
+
OnExit on_exit([this]() { m_expr_decl_map.reset(); });
-
+
if (!m_expr_decl_map->WillParse(exe_ctx, m_materializer_ap.get()))
{
error_stream.PutCString ("error: current process state is unsuitable for expression parsing\n");
-
+
m_expr_decl_map.reset(); // We are being careful here in the case of breakpoint conditions.
-
+
return false;
}
-
+
Process *process = exe_ctx.GetProcessPtr();
ExecutionContextScope *exe_scope = process;
-
+
if (!exe_scope)
exe_scope = exe_ctx.GetTargetPtr();
-
- ClangExpressionParser parser(exe_scope, *this);
-
+
+ ClangExpressionParser parser(exe_scope, *this, generate_debug_info);
+
unsigned num_errors = parser.Parse (error_stream);
-
+
if (num_errors)
{
error_stream.Printf ("error: %d errors parsing expression\n", num_errors);
-
+
m_expr_decl_map.reset(); // We are being careful here in the case of breakpoint conditions.
-
+
return false;
}
-
+
//////////////////////////////////////////////////////////////////////////////////////////
// Prepare the output of the parser for execution, evaluating it statically if possible
//
-
+
Error jit_error = parser.PrepareForExecution (m_jit_start_addr,
m_jit_end_addr,
- m_execution_unit_ap,
+ m_execution_unit_sp,
exe_ctx,
m_can_interpret,
execution_policy);
-
+
+ if (generate_debug_info)
+ {
+ lldb::ModuleSP jit_module_sp ( m_execution_unit_sp->GetJITModule());
+
+ if (jit_module_sp)
+ {
+ ConstString const_func_name(FunctionName());
+ FileSpec jit_file;
+ jit_file.GetFilename() = const_func_name;
+ jit_module_sp->SetFileSpecAndObjectName (jit_file, ConstString());
+ m_jit_module_wp = jit_module_sp;
+ target->GetImages().Append(jit_module_sp);
+ }
+// lldb_private::ObjectFile *jit_obj_file = jit_module_sp->GetObjectFile();
+// StreamFile strm (stdout, false);
+// if (jit_obj_file)
+// {
+// jit_obj_file->GetSectionList();
+// jit_obj_file->GetSymtab();
+// jit_obj_file->Dump(&strm);
+// }
+// lldb_private::SymbolVendor *jit_sym_vendor = jit_module_sp->GetSymbolVendor();
+// if (jit_sym_vendor)
+// {
+// lldb_private::SymbolContextList sc_list;
+// jit_sym_vendor->FindFunctions(const_func_name, NULL, lldb::eFunctionNameTypeFull, true, false, sc_list);
+// sc_list.Dump(&strm, target);
+// jit_sym_vendor->Dump(&strm);
+// }
+ }
+
m_expr_decl_map.reset(); // Make this go away since we don't need any of its state after parsing. This also gets rid of any ClangASTImporter::Minions.
-
+
if (jit_error.Success())
{
if (process && m_jit_start_addr != LLDB_INVALID_ADDRESS)
@@ -563,16 +607,16 @@ GetObjectPointer (lldb::StackFrameSP frame_sp,
Error &err)
{
err.Clear();
-
+
if (!frame_sp)
{
err.SetErrorStringWithFormat("Couldn't load '%s' because the context is incomplete", object_name.AsCString());
return LLDB_INVALID_ADDRESS;
}
-
+
lldb::VariableSP var_sp;
lldb::ValueObjectSP valobj_sp;
-
+
valobj_sp = frame_sp->GetValueForVariableExpressionPath(object_name.AsCString(),
lldb::eNoDynamicValues,
StackFrame::eExpressionPathOptionCheckPtrVsMember ||
@@ -582,18 +626,18 @@ GetObjectPointer (lldb::StackFrameSP frame_sp,
StackFrame::eExpressionPathOptionsNoSyntheticArrayRange,
var_sp,
err);
-
+
if (!err.Success())
return LLDB_INVALID_ADDRESS;
-
+
lldb::addr_t ret = valobj_sp->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
-
+
if (ret == LLDB_INVALID_ADDRESS)
{
err.SetErrorStringWithFormat("Couldn't load '%s' because its value couldn't be evaluated", object_name.AsCString());
return LLDB_INVALID_ADDRESS;
}
-
+
return ret;
}
@@ -607,22 +651,22 @@ ClangUserExpression::PrepareToExecuteJITExpression (Stream &error_stream,
lldb::TargetSP target;
lldb::ProcessSP process;
lldb::StackFrameSP frame;
-
+
if (!LockAndCheckContext(exe_ctx,
target,
- process,
+ process,
frame))
{
error_stream.Printf("The context has changed before we could JIT the expression!\n");
return false;
}
-
+
if (m_jit_start_addr != LLDB_INVALID_ADDRESS || m_can_interpret)
- {
+ {
if (m_needs_object_ptr)
{
ConstString object_name;
-
+
if (m_cplusplus)
{
object_name.SetCString("this");
@@ -636,23 +680,23 @@ ClangUserExpression::PrepareToExecuteJITExpression (Stream &error_stream,
error_stream.Printf("Need object pointer but don't know the language\n");
return false;
}
-
+
Error object_ptr_error;
-
+
object_ptr = GetObjectPointer(frame, object_name, object_ptr_error);
-
+
if (!object_ptr_error.Success())
{
error_stream.Printf("warning: couldn't get required object pointer (substituting NULL): %s\n", object_ptr_error.AsCString());
object_ptr = 0;
}
-
+
if (m_objectivec)
{
ConstString cmd_name("_cmd");
-
+
cmd_ptr = GetObjectPointer(frame, cmd_name, object_ptr_error);
-
+
if (!object_ptr_error.Success())
{
error_stream.Printf("warning: couldn't get cmd pointer (substituting NULL): %s\n", object_ptr_error.AsCString());
@@ -660,56 +704,56 @@ ClangUserExpression::PrepareToExecuteJITExpression (Stream &error_stream,
}
}
}
-
+
if (m_materialized_address == LLDB_INVALID_ADDRESS)
{
Error alloc_error;
-
+
IRMemoryMap::AllocationPolicy policy = m_can_interpret ? IRMemoryMap::eAllocationPolicyHostOnly : IRMemoryMap::eAllocationPolicyMirror;
-
- m_materialized_address = m_execution_unit_ap->Malloc(m_materializer_ap->GetStructByteSize(),
+
+ m_materialized_address = m_execution_unit_sp->Malloc(m_materializer_ap->GetStructByteSize(),
m_materializer_ap->GetStructAlignment(),
lldb::ePermissionsReadable | lldb::ePermissionsWritable,
policy,
alloc_error);
-
+
if (!alloc_error.Success())
{
error_stream.Printf("Couldn't allocate space for materialized struct: %s\n", alloc_error.AsCString());
return false;
}
}
-
+
struct_address = m_materialized_address;
-
+
if (m_can_interpret && m_stack_frame_bottom == LLDB_INVALID_ADDRESS)
{
Error alloc_error;
const size_t stack_frame_size = 512 * 1024;
-
- m_stack_frame_bottom = m_execution_unit_ap->Malloc(stack_frame_size,
+
+ m_stack_frame_bottom = m_execution_unit_sp->Malloc(stack_frame_size,
8,
lldb::ePermissionsReadable | lldb::ePermissionsWritable,
IRMemoryMap::eAllocationPolicyHostOnly,
alloc_error);
-
+
m_stack_frame_top = m_stack_frame_bottom + stack_frame_size;
-
+
if (!alloc_error.Success())
{
error_stream.Printf("Couldn't allocate space for the stack frame: %s\n", alloc_error.AsCString());
return false;
}
}
-
+
Error materialize_error;
-
- m_dematerializer_sp = m_materializer_ap->Materialize(frame, *m_execution_unit_ap, struct_address, materialize_error);
-
+
+ m_dematerializer_sp = m_materializer_ap->Materialize(frame, *m_execution_unit_sp, struct_address, materialize_error);
+
if (!materialize_error.Success())
{
- error_stream.Printf("Couldn't materialize struct: %s\n", materialize_error.AsCString());
+ error_stream.Printf("Couldn't materialize: %s\n", materialize_error.AsCString());
return false;
}
}
@@ -724,18 +768,18 @@ ClangUserExpression::FinalizeJITExecution (Stream &error_stream,
lldb::addr_t function_stack_top)
{
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
+
if (log)
log->Printf("-- [ClangUserExpression::FinalizeJITExecution] Dematerializing after execution --");
-
+
if (!m_dematerializer_sp)
{
error_stream.Printf ("Couldn't apply expression side effects : no dematerializer is present");
return false;
}
-
+
Error dematerialize_error;
-
+
m_dematerializer_sp->Dematerialize(dematerialize_error, result, function_stack_bottom, function_stack_top);
if (!dematerialize_error.Success())
@@ -743,16 +787,16 @@ ClangUserExpression::FinalizeJITExecution (Stream &error_stream,
error_stream.Printf ("Couldn't apply expression side effects : %s\n", dematerialize_error.AsCString("unknown error"));
return false;
}
-
+
if (result)
result->TransferAddress();
-
+
m_dematerializer_sp.reset();
-
+
return true;
-}
+}
-ExecutionResults
+lldb::ExpressionResults
ClangUserExpression::Execute (Stream &error_stream,
ExecutionContext &exe_ctx,
const EvaluateExpressionOptions& options,
@@ -766,110 +810,118 @@ ClangUserExpression::Execute (Stream &error_stream,
if (m_jit_start_addr != LLDB_INVALID_ADDRESS || m_can_interpret)
{
lldb::addr_t struct_address = LLDB_INVALID_ADDRESS;
-
+
lldb::addr_t object_ptr = 0;
lldb::addr_t cmd_ptr = 0;
-
+
if (!PrepareToExecuteJITExpression (error_stream, exe_ctx, struct_address, object_ptr, cmd_ptr))
{
error_stream.Printf("Errored out in %s, couldn't PrepareToExecuteJITExpression", __FUNCTION__);
- return eExecutionSetupError;
+ return lldb::eExpressionSetupError;
}
-
+
lldb::addr_t function_stack_bottom = LLDB_INVALID_ADDRESS;
lldb::addr_t function_stack_top = LLDB_INVALID_ADDRESS;
-
+
if (m_can_interpret)
- {
- llvm::Module *module = m_execution_unit_ap->GetModule();
- llvm::Function *function = m_execution_unit_ap->GetFunction();
-
+ {
+ llvm::Module *module = m_execution_unit_sp->GetModule();
+ llvm::Function *function = m_execution_unit_sp->GetFunction();
+
if (!module || !function)
{
error_stream.Printf("Supposed to interpret, but nothing is there");
- return eExecutionSetupError;
+ return lldb::eExpressionSetupError;
}
Error interpreter_error;
-
+
llvm::SmallVector <lldb::addr_t, 3> args;
-
+
if (m_needs_object_ptr)
{
args.push_back(object_ptr);
-
+
if (m_objectivec)
args.push_back(cmd_ptr);
}
-
+
args.push_back(struct_address);
-
+
function_stack_bottom = m_stack_frame_bottom;
function_stack_top = m_stack_frame_top;
-
+
IRInterpreter::Interpret (*module,
*function,
args,
- *m_execution_unit_ap.get(),
+ *m_execution_unit_sp.get(),
interpreter_error,
function_stack_bottom,
function_stack_top);
-
+
if (!interpreter_error.Success())
{
error_stream.Printf("Supposed to interpret, but failed: %s", interpreter_error.AsCString());
- return eExecutionDiscarded;
+ return lldb::eExpressionDiscarded;
}
}
else
{
+ if (!exe_ctx.HasThreadScope())
+ {
+ error_stream.Printf("ClangUserExpression::Execute called with no thread selected.");
+ return lldb::eExpressionSetupError;
+ }
+
Address wrapper_address (m_jit_start_addr);
-
+
llvm::SmallVector <lldb::addr_t, 3> args;
-
+
if (m_needs_object_ptr) {
args.push_back(object_ptr);
if (m_objectivec)
args.push_back(cmd_ptr);
}
-
+
args.push_back(struct_address);
-
- lldb::ThreadPlanSP call_plan_sp(new ThreadPlanCallUserExpression (exe_ctx.GetThreadRef(),
- wrapper_address,
- args,
- options,
- shared_ptr_to_me));
-
+
+ ThreadPlanCallUserExpression *user_expression_plan =
+ new ThreadPlanCallUserExpression (exe_ctx.GetThreadRef(),
+ wrapper_address,
+ args,
+ options,
+ shared_ptr_to_me);
+ lldb::ThreadPlanSP call_plan_sp(user_expression_plan);
+
if (!call_plan_sp || !call_plan_sp->ValidatePlan (&error_stream))
- return eExecutionSetupError;
-
- lldb::addr_t function_stack_pointer = static_cast<ThreadPlanCallFunction *>(call_plan_sp.get())->GetFunctionStackPointer();
+ return lldb::eExpressionSetupError;
- function_stack_bottom = function_stack_pointer - Host::GetPageSize();
+ lldb::addr_t function_stack_pointer = user_expression_plan->GetFunctionStackPointer();
+
+ function_stack_bottom = function_stack_pointer - HostInfo::GetPageSize();
function_stack_top = function_stack_pointer;
-
+
if (log)
log->Printf("-- [ClangUserExpression::Execute] Execution of expression begins --");
-
+
if (exe_ctx.GetProcessPtr())
exe_ctx.GetProcessPtr()->SetRunningUserExpression(true);
-
- ExecutionResults execution_result = exe_ctx.GetProcessRef().RunThreadPlan (exe_ctx,
+
+ lldb::ExpressionResults execution_result = exe_ctx.GetProcessRef().RunThreadPlan (exe_ctx,
call_plan_sp,
options,
error_stream);
-
+
if (exe_ctx.GetProcessPtr())
exe_ctx.GetProcessPtr()->SetRunningUserExpression(false);
-
+
if (log)
log->Printf("-- [ClangUserExpression::Execute] Execution of expression completed --");
- if (execution_result == eExecutionInterrupted || execution_result == eExecutionHitBreakpoint)
+ if (execution_result == lldb::eExpressionInterrupted || execution_result == lldb::eExpressionHitBreakpoint)
{
const char *error_desc = NULL;
-
+
if (call_plan_sp)
{
lldb::StopInfoSP real_stop_info_sp = call_plan_sp->GetRealStopInfo();
@@ -880,45 +932,51 @@ ClangUserExpression::Execute (Stream &error_stream,
error_stream.Printf ("Execution was interrupted, reason: %s.", error_desc);
else
error_stream.PutCString ("Execution was interrupted.");
-
- if ((execution_result == eExecutionInterrupted && options.DoesUnwindOnError())
- || (execution_result == eExecutionHitBreakpoint && options.DoesIgnoreBreakpoints()))
+
+ if ((execution_result == lldb::eExpressionInterrupted && options.DoesUnwindOnError())
+ || (execution_result == lldb::eExpressionHitBreakpoint && options.DoesIgnoreBreakpoints()))
error_stream.PutCString ("\nThe process has been returned to the state before expression evaluation.");
else
- error_stream.PutCString ("\nThe process has been left at the point where it was interrupted, use \"thread return -x\" to return to the state before expression evaluation.");
+ {
+ if (execution_result == lldb::eExpressionHitBreakpoint)
+ user_expression_plan->TransferExpressionOwnership();
+ error_stream.PutCString ("\nThe process has been left at the point where it was interrupted, "
+ "use \"thread return -x\" to return to the state before expression evaluation.");
+ }
return execution_result;
}
- else if (execution_result == eExecutionStoppedForDebug)
+ else if (execution_result == lldb::eExpressionStoppedForDebug)
{
- error_stream.PutCString ("Execution was halted at the first instruction of the expression function because \"debug\" was requested.\n"
+ error_stream.PutCString ("Execution was halted at the first instruction of the expression "
+ "function because \"debug\" was requested.\n"
"Use \"thread return -x\" to return to the state before expression evaluation.");
return execution_result;
}
- else if (execution_result != eExecutionCompleted)
+ else if (execution_result != lldb::eExpressionCompleted)
{
error_stream.Printf ("Couldn't execute function; result was %s\n", Process::ExecutionResultAsCString (execution_result));
return execution_result;
}
}
-
+
if (FinalizeJITExecution (error_stream, exe_ctx, result, function_stack_bottom, function_stack_top))
{
- return eExecutionCompleted;
+ return lldb::eExpressionCompleted;
}
else
{
- return eExecutionSetupError;
+ return lldb::eExpressionResultUnavailable;
}
}
else
{
error_stream.Printf("Expression can't be run, because there is no JIT compiled function");
- return eExecutionSetupError;
+ return lldb::eExpressionSetupError;
}
}
-ExecutionResults
+lldb::ExpressionResults
ClangUserExpression::Evaluate (ExecutionContext &exe_ctx,
const EvaluateExpressionOptions& options,
const char *expr_cstr,
@@ -931,8 +989,8 @@ ClangUserExpression::Evaluate (ExecutionContext &exe_ctx,
lldb_private::ExecutionPolicy execution_policy = options.GetExecutionPolicy();
const lldb::LanguageType language = options.GetLanguage();
const ResultType desired_type = options.DoesCoerceToId() ? ClangUserExpression::eResultTypeId : ClangUserExpression::eResultTypeAny;
- ExecutionResults execution_results = eExecutionSetupError;
-
+ lldb::ExpressionResults execution_results = lldb::eExpressionSetupError;
+
Process *process = exe_ctx.GetProcessPtr();
if (process == NULL || process->GetState() != lldb::eStateStopped)
@@ -941,31 +999,43 @@ ClangUserExpression::Evaluate (ExecutionContext &exe_ctx,
{
if (log)
log->Printf("== [ClangUserExpression::Evaluate] Expression may not run, but is not constant ==");
-
+
error.SetErrorString ("expression needed to run but couldn't");
-
+
return execution_results;
}
}
-
+
if (process == NULL || !process->CanJIT())
execution_policy = eExecutionPolicyNever;
-
+
ClangUserExpressionSP user_expression_sp (new ClangUserExpression (expr_cstr, expr_prefix, language, desired_type));
StreamString error_stream;
-
+
if (log)
log->Printf("== [ClangUserExpression::Evaluate] Parsing expression %s ==", expr_cstr);
-
+
const bool keep_expression_in_memory = true;
-
- if (!user_expression_sp->Parse (error_stream, exe_ctx, execution_policy, keep_expression_in_memory))
+ const bool generate_debug_info = options.GetGenerateDebugInfo();
+
+ if (options.InvokeCancelCallback (lldb::eExpressionEvaluationParse))
+ {
+ error.SetErrorString ("expression interrupted by callback before parse");
+ result_valobj_sp = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(), error);
+ return lldb::eExpressionInterrupted;
+ }
+
+ if (!user_expression_sp->Parse (error_stream,
+ exe_ctx,
+ execution_policy,
+ keep_expression_in_memory,
+ generate_debug_info))
{
if (error_stream.GetString().empty())
- error.SetErrorString ("expression failed to parse, unknown error");
+ error.SetExpressionError (lldb::eExpressionParseError, "expression failed to parse, unknown error");
else
- error.SetErrorString (error_stream.GetString().c_str());
+ error.SetExpressionError (lldb::eExpressionParseError, error_stream.GetString().c_str());
}
else
{
@@ -976,53 +1046,72 @@ ClangUserExpression::Evaluate (ExecutionContext &exe_ctx,
{
if (log)
log->Printf("== [ClangUserExpression::Evaluate] Expression may not run, but is not constant ==");
-
+
if (error_stream.GetString().empty())
- error.SetErrorString ("expression needed to run but couldn't");
+ error.SetExpressionError (lldb::eExpressionSetupError, "expression needed to run but couldn't");
}
else
- {
+ {
+ if (options.InvokeCancelCallback (lldb::eExpressionEvaluationExecution))
+ {
+ error.SetExpressionError (lldb::eExpressionInterrupted, "expression interrupted by callback before execution");
+ result_valobj_sp = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(), error);
+ return lldb::eExpressionInterrupted;
+ }
+
error_stream.GetString().clear();
-
+
if (log)
log->Printf("== [ClangUserExpression::Evaluate] Executing expression ==");
- execution_results = user_expression_sp->Execute (error_stream,
+ execution_results = user_expression_sp->Execute (error_stream,
exe_ctx,
options,
user_expression_sp,
expr_result);
-
- if (execution_results != eExecutionCompleted)
+
+ if (options.GetResultIsInternal())
+ {
+ process->GetTarget().GetPersistentVariables().RemovePersistentVariable (expr_result);
+ }
+
+ if (execution_results != lldb::eExpressionCompleted)
{
if (log)
log->Printf("== [ClangUserExpression::Evaluate] Execution completed abnormally ==");
-
+
if (error_stream.GetString().empty())
- error.SetErrorString ("expression failed to execute, unknown error");
+ error.SetExpressionError (execution_results, "expression failed to execute, unknown error");
else
- error.SetErrorString (error_stream.GetString().c_str());
+ error.SetExpressionError (execution_results, error_stream.GetString().c_str());
}
- else
+ else
{
if (expr_result)
{
result_valobj_sp = expr_result->GetValueObject();
-
+
if (log)
- log->Printf("== [ClangUserExpression::Evaluate] Execution completed normally with result %s ==", result_valobj_sp->GetValueAsCString());
+ log->Printf("== [ClangUserExpression::Evaluate] Execution completed normally with result %s ==",
+ result_valobj_sp->GetValueAsCString());
}
else
{
if (log)
log->Printf("== [ClangUserExpression::Evaluate] Execution completed normally with no result ==");
-
+
error.SetError(ClangUserExpression::kNoResult, lldb::eErrorTypeGeneric);
}
}
}
}
-
+
+ if (options.InvokeCancelCallback(lldb::eExpressionEvaluationComplete))
+ {
+ error.SetExpressionError (lldb::eExpressionInterrupted, "expression interrupted by callback after complete");
+ return lldb::eExpressionInterrupted;
+ }
+
if (result_valobj_sp.get() == NULL)
{
result_valobj_sp = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(), error);
diff --git a/contrib/llvm/tools/lldb/source/Expression/ClangUtilityFunction.cpp b/contrib/llvm/tools/lldb/source/Expression/ClangUtilityFunction.cpp
index c911c27..de5b0c1 100644
--- a/contrib/llvm/tools/lldb/source/Expression/ClangUtilityFunction.cpp
+++ b/contrib/llvm/tools/lldb/source/Expression/ClangUtilityFunction.cpp
@@ -17,6 +17,7 @@
#include "lldb/Core/ConstString.h"
#include "lldb/Core/Log.h"
+#include "lldb/Core/Module.h"
#include "lldb/Core/Stream.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Expression/ClangExpressionDeclMap.h"
@@ -42,6 +43,9 @@ using namespace lldb_private;
ClangUtilityFunction::ClangUtilityFunction (const char *text,
const char *name) :
ClangExpression (),
+ m_expr_decl_map (),
+ m_execution_unit_sp (),
+ m_jit_module_wp (),
m_function_text (ExpressionSourceCode::g_expression_prefix),
m_function_name (name)
{
@@ -51,6 +55,14 @@ ClangUtilityFunction::ClangUtilityFunction (const char *text,
ClangUtilityFunction::~ClangUtilityFunction ()
{
+ lldb::ProcessSP process_sp (m_jit_process_wp.lock());
+ if (process_sp)
+ {
+ lldb::ModuleSP jit_module_sp (m_jit_module_wp.lock());
+ if (jit_module_sp)
+ process_sp->GetTarget().GetImages().Remove(jit_module_sp);
+ }
+
}
//------------------------------------------------------------------
@@ -108,8 +120,9 @@ ClangUtilityFunction::Install (Stream &error_stream,
error_stream.PutCString ("error: current process state is unsuitable for expression parsing\n");
return false;
}
-
- ClangExpressionParser parser(exe_ctx.GetBestExecutionContextScope(), *this);
+
+ const bool generate_debug_info = true;
+ ClangExpressionParser parser(exe_ctx.GetBestExecutionContextScope(), *this, generate_debug_info);
unsigned num_errors = parser.Parse (error_stream);
@@ -130,13 +143,29 @@ ClangUtilityFunction::Install (Stream &error_stream,
Error jit_error = parser.PrepareForExecution (m_jit_start_addr,
m_jit_end_addr,
- m_execution_unit_ap,
+ m_execution_unit_sp,
exe_ctx,
can_interpret,
eExecutionPolicyAlways);
if (m_jit_start_addr != LLDB_INVALID_ADDRESS)
- m_jit_process_wp = lldb::ProcessWP(process->shared_from_this());
+ {
+ m_jit_process_wp = process->shared_from_this();
+ if (parser.GetGenerateDebugInfo())
+ {
+ lldb::ModuleSP jit_module_sp ( m_execution_unit_sp->GetJITModule());
+
+ if (jit_module_sp)
+ {
+ ConstString const_func_name(FunctionName());
+ FileSpec jit_file;
+ jit_file.GetFilename() = const_func_name;
+ jit_module_sp->SetFileSpecAndObjectName (jit_file, ConstString());
+ m_jit_module_wp = jit_module_sp;
+ target->GetImages().Append(jit_module_sp);
+ }
+ }
+ }
#if 0
// jingham: look here
diff --git a/contrib/llvm/tools/lldb/source/Expression/DWARFExpression.cpp b/contrib/llvm/tools/lldb/source/Expression/DWARFExpression.cpp
index 28aa6d0..44b64ab 100644
--- a/contrib/llvm/tools/lldb/source/Expression/DWARFExpression.cpp
+++ b/contrib/llvm/tools/lldb/source/Expression/DWARFExpression.cpp
@@ -282,6 +282,33 @@ DWARFExpression::CopyOpcodeData (lldb::ModuleSP module_sp, const DataExtractor&
}
void
+DWARFExpression::CopyOpcodeData (const void *data,
+ lldb::offset_t data_length,
+ ByteOrder byte_order,
+ uint8_t addr_byte_size)
+{
+ if (data && data_length)
+ {
+ m_data.SetData(DataBufferSP(new DataBufferHeap(data, data_length)));
+ m_data.SetByteOrder(byte_order);
+ m_data.SetAddressByteSize(addr_byte_size);
+ }
+}
+
+void
+DWARFExpression::CopyOpcodeData (uint64_t const_value,
+ lldb::offset_t const_value_byte_size,
+ uint8_t addr_byte_size)
+{
+ if (const_value_byte_size)
+ {
+ m_data.SetData(DataBufferSP(new DataBufferHeap(&const_value, const_value_byte_size)));
+ m_data.SetByteOrder(endian::InlHostByteOrder());
+ m_data.SetAddressByteSize(addr_byte_size);
+ }
+}
+
+void
DWARFExpression::SetOpcodeData (lldb::ModuleSP module_sp, const DataExtractor& data, lldb::offset_t data_offset, lldb::offset_t data_length)
{
m_module_wp = module_sp;
@@ -728,7 +755,7 @@ static bool
ReadRegisterValueAsScalar
(
RegisterContext *reg_ctx,
- uint32_t reg_kind,
+ lldb::RegisterKind reg_kind,
uint32_t reg_num,
Error *error_ptr,
Value &value
@@ -1307,11 +1334,11 @@ DWARFExpression::Evaluate
ClangExpressionVariableList *expr_locals,
ClangExpressionDeclMap *decl_map,
RegisterContext *reg_ctx,
- lldb::ModuleSP opcode_ctx,
+ lldb::ModuleSP module_sp,
const DataExtractor& opcodes,
const lldb::offset_t opcodes_offset,
const lldb::offset_t opcodes_length,
- const uint32_t reg_kind,
+ const lldb::RegisterKind reg_kind,
const Value* initial_value_ptr,
Value& result,
Error *error_ptr
@@ -1345,6 +1372,10 @@ DWARFExpression::Evaluate
Value tmp;
uint32_t reg_num;
+ /// Insertion point for evaluating multi-piece expression.
+ uint64_t op_piece_offset = 0;
+ Value pieces; // Used for DW_OP_piece
+
// Make sure all of the data is available in opcodes.
if (!opcodes.ValidOffsetForDataOfSize(opcodes_offset, opcodes_length))
{
@@ -1363,7 +1394,7 @@ DWARFExpression::Evaluate
if (log && log->GetVerbose())
{
size_t count = stack.size();
- log->Printf("Stack before operation has %zu values:", count);
+ log->Printf("Stack before operation has %" PRIu64 " values:", (uint64_t)count);
for (size_t i=0; i<count; ++i)
{
StreamString new_value;
@@ -1453,14 +1484,11 @@ DWARFExpression::Evaluate
if (process)
{
lldb::addr_t pointer_addr = stack.back().GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
- uint8_t addr_bytes[sizeof(lldb::addr_t)];
- uint32_t addr_size = process->GetAddressByteSize();
Error error;
- if (process->ReadMemory(pointer_addr, &addr_bytes, addr_size, error) == addr_size)
+ lldb::addr_t pointer_value = process->ReadPointerFromMemory(pointer_addr, error);
+ if (pointer_value != LLDB_INVALID_ADDRESS)
{
- DataExtractor addr_data(addr_bytes, sizeof(addr_bytes), process->GetByteOrder(), addr_size);
- lldb::offset_t addr_data_offset = 0;
- stack.back().GetScalar() = addr_data.GetPointer(&addr_data_offset);
+ stack.back().GetScalar() = pointer_value;
stack.back().ClearContext();
}
else
@@ -2574,45 +2602,134 @@ DWARFExpression::Evaluate
// variable a particular DWARF expression refers to.
//----------------------------------------------------------------------
case DW_OP_piece:
- if (stack.size() < 1)
- {
- if (error_ptr)
- error_ptr->SetErrorString("Expression stack needs at least 1 item for DW_OP_piece.");
- return false;
- }
- else
{
const uint64_t piece_byte_size = opcodes.GetULEB128(&offset);
- switch (stack.back().GetValueType())
+
+ if (piece_byte_size > 0)
{
- case Value::eValueTypeScalar:
- case Value::eValueTypeFileAddress:
- case Value::eValueTypeLoadAddress:
- case Value::eValueTypeHostAddress:
+ Value curr_piece;
+
+ if (stack.empty())
+ {
+ // In a multi-piece expression, this means that the current piece is not available.
+ // Fill with zeros for now by resizing the data and appending it
+ curr_piece.ResizeData(piece_byte_size);
+ ::memset (curr_piece.GetBuffer().GetBytes(), 0, piece_byte_size);
+ pieces.AppendDataToHostBuffer(curr_piece);
+ }
+ else
+ {
+ Error error;
+ // Extract the current piece into "curr_piece"
+ Value curr_piece_source_value(stack.back());
+ stack.pop_back();
+
+ const Value::ValueType curr_piece_source_value_type = curr_piece_source_value.GetValueType();
+ switch (curr_piece_source_value_type)
{
- uint32_t bit_size = piece_byte_size * 8;
- uint32_t bit_offset = 0;
- if (!stack.back().GetScalar().ExtractBitfield (bit_size, bit_offset))
+ case Value::eValueTypeLoadAddress:
+ if (process)
+ {
+ if (curr_piece.ResizeData(piece_byte_size) == piece_byte_size)
+ {
+ lldb::addr_t load_addr = curr_piece_source_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
+ if (process->ReadMemory(load_addr, curr_piece.GetBuffer().GetBytes(), piece_byte_size, error) != piece_byte_size)
+ {
+ if (error_ptr)
+ error_ptr->SetErrorStringWithFormat ("failed to read memory DW_OP_piece(%" PRIu64 ") from 0x%" PRIx64,
+ piece_byte_size,
+ load_addr);
+ return false;
+ }
+ }
+ else
+ {
+ if (error_ptr)
+ error_ptr->SetErrorStringWithFormat ("failed to resize the piece memory buffer for DW_OP_piece(%" PRIu64 ")", piece_byte_size);
+ return false;
+ }
+ }
+ break;
+
+ case Value::eValueTypeFileAddress:
+ case Value::eValueTypeHostAddress:
+ if (error_ptr)
+ {
+ lldb::addr_t addr = curr_piece_source_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
+ error_ptr->SetErrorStringWithFormat ("failed to read memory DW_OP_piece(%" PRIu64 ") from %s address 0x%" PRIx64,
+ piece_byte_size,
+ curr_piece_source_value.GetValueType() == Value::eValueTypeFileAddress ? "file" : "host",
+ addr);
+ }
+ return false;
+
+ case Value::eValueTypeScalar:
+ {
+ uint32_t bit_size = piece_byte_size * 8;
+ uint32_t bit_offset = 0;
+ if (!curr_piece_source_value.GetScalar().ExtractBitfield (bit_size, bit_offset))
+ {
+ if (error_ptr)
+ error_ptr->SetErrorStringWithFormat("unable to extract %" PRIu64 " bytes from a %" PRIu64 " byte scalar value.", piece_byte_size, (uint64_t)curr_piece_source_value.GetScalar().GetByteSize());
+ return false;
+ }
+ curr_piece = curr_piece_source_value;
+ }
+ break;
+
+ case Value::eValueTypeVector:
+ {
+ if (curr_piece_source_value.GetVector().length >= piece_byte_size)
+ curr_piece_source_value.GetVector().length = piece_byte_size;
+ else
+ {
+ if (error_ptr)
+ error_ptr->SetErrorStringWithFormat("unable to extract %" PRIu64 " bytes from a %" PRIu64 " byte vector value.", piece_byte_size, (uint64_t)curr_piece_source_value.GetVector().length);
+ return false;
+ }
+ }
+ break;
+
+ default:
+ if (error_ptr)
+ error_ptr->SetErrorStringWithFormat ("unhandled value type for DW_OP_piece(%" PRIu64 ")", piece_byte_size);
+ return false;
+
+ }
+
+ // Check if this is the first piece?
+ if (op_piece_offset == 0)
+ {
+ // This is the first piece, we should push it back onto the stack so subsequent
+ // pieces will be able to access this piece and add to it
+ if (pieces.AppendDataToHostBuffer(curr_piece) == 0)
{
if (error_ptr)
- error_ptr->SetErrorStringWithFormat("unable to extract %" PRIu64 " bytes from a %" PRIu64 " byte scalar value.", piece_byte_size, (uint64_t)stack.back().GetScalar().GetByteSize());
+ error_ptr->SetErrorString("failed to append piece data");
return false;
}
}
- break;
-
- case Value::eValueTypeVector:
+ else if (!stack.empty())
{
- if (stack.back().GetVector().length >= piece_byte_size)
- stack.back().GetVector().length = piece_byte_size;
- else
+ // If this is the second or later piece there should be a value on the stack
+ if (pieces.GetBuffer().GetByteSize() != op_piece_offset)
{
if (error_ptr)
- error_ptr->SetErrorStringWithFormat("unable to extract %" PRIu64 " bytes from a %" PRIu64 " byte vector value.", piece_byte_size, (uint64_t)stack.back().GetVector().length);
+ error_ptr->SetErrorStringWithFormat ("DW_OP_piece for offset %" PRIu64 " but top of stack is of size %" PRIu64,
+ op_piece_offset,
+ pieces.GetBuffer().GetByteSize());
+ return false;
+ }
+
+ if (pieces.AppendDataToHostBuffer(curr_piece) == 0)
+ {
+ if (error_ptr)
+ error_ptr->SetErrorString("failed to append piece data");
return false;
}
}
- break;
+ op_piece_offset += piece_byte_size;
+ }
}
}
break;
@@ -2631,9 +2748,6 @@ DWARFExpression::Evaluate
switch (stack.back().GetValueType())
{
case Value::eValueTypeScalar:
- case Value::eValueTypeFileAddress:
- case Value::eValueTypeLoadAddress:
- case Value::eValueTypeHostAddress:
{
if (!stack.back().GetScalar().ExtractBitfield (piece_bit_size, piece_bit_offset))
{
@@ -2646,11 +2760,22 @@ DWARFExpression::Evaluate
}
}
break;
-
+
+ case Value::eValueTypeFileAddress:
+ case Value::eValueTypeLoadAddress:
+ case Value::eValueTypeHostAddress:
+ if (error_ptr)
+ {
+ error_ptr->SetErrorStringWithFormat ("unable to extract DW_OP_bit_piece(bit_size = %" PRIu64 ", bit_offset = %" PRIu64 ") from an addresss value.",
+ piece_bit_size,
+ piece_bit_offset);
+ }
+ return false;
+
case Value::eValueTypeVector:
if (error_ptr)
{
- error_ptr->SetErrorStringWithFormat ("unable to extract %" PRIu64 " bit value with %" PRIu64 " bit offset from a vector value.",
+ error_ptr->SetErrorStringWithFormat ("unable to extract DW_OP_bit_piece(bit_size = %" PRIu64 ", bit_offset = %" PRIu64 ") from a vector value.",
piece_bit_size,
piece_bit_offset);
}
@@ -2784,7 +2909,7 @@ DWARFExpression::Evaluate
return false;
}
- if (!exe_ctx || !opcode_ctx)
+ if (!exe_ctx || !module_sp)
{
if (error_ptr)
error_ptr->SetErrorString("No context to evaluate TLS within.");
@@ -2800,7 +2925,7 @@ DWARFExpression::Evaluate
}
// Lookup the TLS block address for this thread and module.
- addr_t tls_addr = thread->GetThreadLocalData (opcode_ctx);
+ addr_t tls_addr = thread->GetThreadLocalData (module_sp);
if (tls_addr == LLDB_INVALID_ADDRESS)
{
@@ -2825,24 +2950,34 @@ DWARFExpression::Evaluate
if (stack.empty())
{
- if (error_ptr)
- error_ptr->SetErrorString ("Stack empty after evaluation.");
- return false;
+ // Nothing on the stack, check if we created a piece value from DW_OP_piece or DW_OP_bit_piece opcodes
+ if (pieces.GetBuffer().GetByteSize())
+ {
+ result = pieces;
+ }
+ else
+ {
+ if (error_ptr)
+ error_ptr->SetErrorString ("Stack empty after evaluation.");
+ return false;
+ }
}
- else if (log && log->GetVerbose())
+ else
{
- size_t count = stack.size();
- log->Printf("Stack after operation has %zu values:", count);
- for (size_t i=0; i<count; ++i)
+ if (log && log->GetVerbose())
{
- StreamString new_value;
- new_value.Printf("[%" PRIu64 "]", (uint64_t)i);
- stack[i].Dump(&new_value);
- log->Printf(" %s", new_value.GetData());
+ size_t count = stack.size();
+ log->Printf("Stack after operation has %" PRIu64 " values:", (uint64_t)count);
+ for (size_t i=0; i<count; ++i)
+ {
+ StreamString new_value;
+ new_value.Printf("[%" PRIu64 "]", (uint64_t)i);
+ stack[i].Dump(&new_value);
+ log->Printf(" %s", new_value.GetData());
+ }
}
+ result = stack.back();
}
-
- result = stack.back();
return true; // Return true on success
}
diff --git a/contrib/llvm/tools/lldb/source/Expression/ExpressionSourceCode.cpp b/contrib/llvm/tools/lldb/source/Expression/ExpressionSourceCode.cpp
index aef3b9e..080562e 100644
--- a/contrib/llvm/tools/lldb/source/Expression/ExpressionSourceCode.cpp
+++ b/contrib/llvm/tools/lldb/source/Expression/ExpressionSourceCode.cpp
@@ -10,6 +10,9 @@
#include "lldb/Expression/ExpressionSourceCode.h"
#include "lldb/Core/StreamString.h"
+#include "lldb/Target/ExecutionContext.h"
+#include "lldb/Target/Platform.h"
+#include "lldb/Target/Target.h"
using namespace lldb_private;
@@ -25,25 +28,45 @@ ExpressionSourceCode::g_expression_prefix = R"(
#define nil (__null)
#define YES ((BOOL)1)
#define NO ((BOOL)0)
-typedef signed char BOOL;
-typedef signed __INT8_TYPE__ int8_t;
-typedef unsigned __INT8_TYPE__ uint8_t;
-typedef signed __INT16_TYPE__ int16_t;
-typedef unsigned __INT16_TYPE__ uint16_t;
-typedef signed __INT32_TYPE__ int32_t;
-typedef unsigned __INT32_TYPE__ uint32_t;
-typedef signed __INT64_TYPE__ int64_t;
-typedef unsigned __INT64_TYPE__ uint64_t;
-typedef signed __INTPTR_TYPE__ intptr_t;
-typedef unsigned __INTPTR_TYPE__ uintptr_t;
+typedef __INT8_TYPE__ int8_t;
+typedef __UINT8_TYPE__ uint8_t;
+typedef __INT16_TYPE__ int16_t;
+typedef __UINT16_TYPE__ uint16_t;
+typedef __INT32_TYPE__ int32_t;
+typedef __UINT32_TYPE__ uint32_t;
+typedef __INT64_TYPE__ int64_t;
+typedef __UINT64_TYPE__ uint64_t;
+typedef __INTPTR_TYPE__ intptr_t;
+typedef __UINTPTR_TYPE__ uintptr_t;
typedef __SIZE_TYPE__ size_t;
typedef __PTRDIFF_TYPE__ ptrdiff_t;
typedef unsigned short unichar;
)";
-bool ExpressionSourceCode::GetText (std::string &text, lldb::LanguageType wrapping_language, bool const_object, bool static_method) const
+bool ExpressionSourceCode::GetText (std::string &text, lldb::LanguageType wrapping_language, bool const_object, bool static_method, ExecutionContext &exe_ctx) const
{
+ const char *target_specific_defines = "typedef signed char BOOL;\n";
+ static ConstString g_platform_ios_simulator ("PlatformiOSSimulator");
+
+ if (Target *target = exe_ctx.GetTargetPtr())
+ {
+ if (target->GetArchitecture().GetMachine() == llvm::Triple::aarch64)
+ {
+ target_specific_defines = "typedef bool BOOL;\n";
+ }
+ if (target->GetArchitecture().GetMachine() == llvm::Triple::x86_64)
+ {
+ if (lldb::PlatformSP platform_sp = target->GetPlatform())
+ {
+ if (platform_sp->GetPluginName() == g_platform_ios_simulator)
+ {
+ target_specific_defines = "typedef bool BOOL;\n";
+ }
+ }
+ }
+ }
+
if (m_wrap)
{
switch (wrapping_language)
@@ -65,12 +88,14 @@ bool ExpressionSourceCode::GetText (std::string &text, lldb::LanguageType wrappi
case lldb::eLanguageTypeC:
wrap_stream.Printf("%s \n"
"%s \n"
+ "%s \n"
"void \n"
"%s(void *$__lldb_arg) \n"
"{ \n"
" %s; \n"
"} \n",
g_expression_prefix,
+ target_specific_defines,
m_prefix.c_str(),
m_name.c_str(),
m_body.c_str());
@@ -78,12 +103,14 @@ bool ExpressionSourceCode::GetText (std::string &text, lldb::LanguageType wrappi
case lldb::eLanguageTypeC_plus_plus:
wrap_stream.Printf("%s \n"
"%s \n"
+ "%s \n"
"void \n"
"$__lldb_class::%s(void *$__lldb_arg) %s\n"
"{ \n"
" %s; \n"
"} \n",
g_expression_prefix,
+ target_specific_defines,
m_prefix.c_str(),
m_name.c_str(),
(const_object ? "const" : ""),
@@ -94,6 +121,7 @@ bool ExpressionSourceCode::GetText (std::string &text, lldb::LanguageType wrappi
{
wrap_stream.Printf("%s \n"
"%s \n"
+ "%s \n"
"@interface $__lldb_objc_class ($__lldb_category) \n"
"+(void)%s:(void *)$__lldb_arg; \n"
"@end \n"
@@ -104,6 +132,7 @@ bool ExpressionSourceCode::GetText (std::string &text, lldb::LanguageType wrappi
"} \n"
"@end \n",
g_expression_prefix,
+ target_specific_defines,
m_prefix.c_str(),
m_name.c_str(),
m_name.c_str(),
@@ -113,6 +142,7 @@ bool ExpressionSourceCode::GetText (std::string &text, lldb::LanguageType wrappi
{
wrap_stream.Printf("%s \n"
"%s \n"
+ "%s \n"
"@interface $__lldb_objc_class ($__lldb_category) \n"
"-(void)%s:(void *)$__lldb_arg; \n"
"@end \n"
@@ -123,6 +153,7 @@ bool ExpressionSourceCode::GetText (std::string &text, lldb::LanguageType wrappi
"} \n"
"@end \n",
g_expression_prefix,
+ target_specific_defines,
m_prefix.c_str(),
m_name.c_str(),
m_name.c_str(),
diff --git a/contrib/llvm/tools/lldb/source/Expression/IRDynamicChecks.cpp b/contrib/llvm/tools/lldb/source/Expression/IRDynamicChecks.cpp
index a75a0fc..aa5d28b 100644
--- a/contrib/llvm/tools/lldb/source/Expression/IRDynamicChecks.cpp
+++ b/contrib/llvm/tools/lldb/source/Expression/IRDynamicChecks.cpp
@@ -33,7 +33,7 @@ static char ID;
#define VALID_POINTER_CHECK_NAME "$__lldb_valid_pointer_check"
#define VALID_OBJC_OBJECT_CHECK_NAME "$__lldb_objc_object_check"
-static const char g_valid_pointer_check_text[] =
+static const char g_valid_pointer_check_text[] =
"extern \"C\" void\n"
"$__lldb_valid_pointer_check (unsigned char *$__lldb_arg_ptr)\n"
"{\n"
@@ -56,22 +56,22 @@ DynamicCheckerFunctions::Install(Stream &error_stream,
VALID_POINTER_CHECK_NAME));
if (!m_valid_pointer_check->Install(error_stream, exe_ctx))
return false;
-
+
Process *process = exe_ctx.GetProcessPtr();
if (process)
{
ObjCLanguageRuntime *objc_language_runtime = process->GetObjCLanguageRuntime();
-
+
if (objc_language_runtime)
{
m_objc_object_check.reset(objc_language_runtime->CreateObjectChecker(VALID_OBJC_OBJECT_CHECK_NAME));
-
+
if (!m_objc_object_check->Install(error_stream, exe_ctx))
return false;
}
}
-
+
return true;
}
@@ -94,7 +94,7 @@ DynamicCheckerFunctions::DoCheckersExplainStop (lldb::addr_t addr, Stream &messa
}
-static std::string
+static std::string
PrintValue(llvm::Value *V, bool truncate = false)
{
std::string s;
@@ -128,10 +128,10 @@ PrintValue(llvm::Value *V, bool truncate = false)
///
/// - InspectInstruction [default: does nothing]
///
-/// - InspectBasicBlock [default: iterates through the instructions in a
+/// - InspectBasicBlock [default: iterates through the instructions in a
/// basic block calling InspectInstruction]
///
-/// - InspectFunction [default: iterates through the basic blocks in a
+/// - InspectFunction [default: iterates through the basic blocks in a
/// function calling InspectBasicBlock]
//----------------------------------------------------------------------
class Instrumenter {
@@ -150,7 +150,7 @@ public:
m_intptr_ty(NULL)
{
}
-
+
virtual~Instrumenter ()
{
}
@@ -168,7 +168,7 @@ public:
{
return InspectFunction(function);
}
-
+
//------------------------------------------------------------------
/// Instrument all the instructions found by Inspect()
///
@@ -184,7 +184,7 @@ public:
if (!InstrumentInstruction(*ii))
return false;
}
-
+
return true;
}
protected:
@@ -192,13 +192,13 @@ protected:
/// Add instrumentation to a single instruction
///
/// @param[in] inst
- /// The instruction to be instrumented.
+ /// The instruction to be instrumented.
///
/// @return
/// True on success; false otherwise.
//------------------------------------------------------------------
virtual bool InstrumentInstruction(llvm::Instruction *inst) = 0;
-
+
//------------------------------------------------------------------
/// Register a single instruction to be instrumented
///
@@ -209,7 +209,7 @@ protected:
{
m_to_instrument.push_back(&i);
}
-
+
//------------------------------------------------------------------
/// Determine whether a single instruction is interesting to
/// instrument, and, if so, call RegisterInstruction
@@ -224,7 +224,7 @@ protected:
{
return true;
}
-
+
//------------------------------------------------------------------
/// Scan a basic block to see if any instructions are interesting
///
@@ -243,15 +243,15 @@ protected:
if (!InspectInstruction(*ii))
return false;
}
-
+
return true;
}
-
+
//------------------------------------------------------------------
/// Scan a function to see if any instructions are interesting
///
/// @param[in] f
- /// The function to be inspected.
+ /// The function to be inspected.
///
/// @return
/// False if there was an error scanning; true otherwise.
@@ -265,12 +265,12 @@ protected:
if (!InspectBasicBlock(*bbi))
return false;
}
-
+
return true;
}
-
+
//------------------------------------------------------------------
- /// Build a function pointer for a function with signature
+ /// Build a function pointer for a function with signature
/// void (*)(uint8_t*) with a given address
///
/// @param[in] start_address
@@ -282,19 +282,19 @@ protected:
llvm::Value *BuildPointerValidatorFunc(lldb::addr_t start_address)
{
llvm::Type *param_array[1];
-
+
param_array[0] = const_cast<llvm::PointerType*>(GetI8PtrTy());
-
+
ArrayRef<llvm::Type*> params(param_array, 1);
-
+
FunctionType *fun_ty = FunctionType::get(llvm::Type::getVoidTy(m_module.getContext()), params, true);
PointerType *fun_ptr_ty = PointerType::getUnqual(fun_ty);
Constant *fun_addr_int = ConstantInt::get(GetIntptrTy(), start_address, false);
return ConstantExpr::getIntToPtr(fun_addr_int, fun_ptr_ty);
}
-
+
//------------------------------------------------------------------
- /// Build a function pointer for a function with signature
+ /// Build a function pointer for a function with signature
/// void (*)(uint8_t*, uint8_t*) with a given address
///
/// @param[in] start_address
@@ -306,41 +306,41 @@ protected:
llvm::Value *BuildObjectCheckerFunc(lldb::addr_t start_address)
{
llvm::Type *param_array[2];
-
+
param_array[0] = const_cast<llvm::PointerType*>(GetI8PtrTy());
param_array[1] = const_cast<llvm::PointerType*>(GetI8PtrTy());
-
+
ArrayRef<llvm::Type*> params(param_array, 2);
-
+
FunctionType *fun_ty = FunctionType::get(llvm::Type::getVoidTy(m_module.getContext()), params, true);
PointerType *fun_ptr_ty = PointerType::getUnqual(fun_ty);
Constant *fun_addr_int = ConstantInt::get(GetIntptrTy(), start_address, false);
return ConstantExpr::getIntToPtr(fun_addr_int, fun_ptr_ty);
}
-
+
PointerType *GetI8PtrTy()
{
if (!m_i8ptr_ty)
m_i8ptr_ty = llvm::Type::getInt8PtrTy(m_module.getContext());
-
+
return m_i8ptr_ty;
}
-
+
IntegerType *GetIntptrTy()
{
if (!m_intptr_ty)
{
llvm::DataLayout data_layout(&m_module);
-
+
m_intptr_ty = llvm::Type::getIntNTy(m_module.getContext(), data_layout.getPointerSizeInBits());
}
-
+
return m_intptr_ty;
}
-
+
typedef std::vector <llvm::Instruction *> InstVector;
typedef InstVector::iterator InstIterator;
-
+
InstVector m_to_instrument; ///< List of instructions the inspector found
llvm::Module &m_module; ///< The module which is being instrumented
DynamicCheckerFunctions &m_checker_functions; ///< The dynamic checker functions for the process
@@ -358,7 +358,7 @@ public:
m_valid_pointer_check_func(NULL)
{
}
-
+
virtual ~ValidPointerChecker ()
{
}
@@ -368,53 +368,53 @@ private:
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
if (log)
- log->Printf("Instrumenting load/store instruction: %s\n",
+ log->Printf("Instrumenting load/store instruction: %s\n",
PrintValue(inst).c_str());
-
+
if (!m_valid_pointer_check_func)
m_valid_pointer_check_func = BuildPointerValidatorFunc(m_checker_functions.m_valid_pointer_check->StartAddress());
-
+
llvm::Value *dereferenced_ptr = NULL;
-
+
if (llvm::LoadInst *li = dyn_cast<llvm::LoadInst> (inst))
dereferenced_ptr = li->getPointerOperand();
else if (llvm::StoreInst *si = dyn_cast<llvm::StoreInst> (inst))
dereferenced_ptr = si->getPointerOperand();
else
return false;
-
+
// Insert an instruction to cast the loaded value to int8_t*
-
+
BitCastInst *bit_cast = new BitCastInst(dereferenced_ptr,
GetI8PtrTy(),
"",
inst);
-
+
// Insert an instruction to call the helper with the result
-
+
llvm::Value *arg_array[1];
-
+
arg_array[0] = bit_cast;
-
+
llvm::ArrayRef<llvm::Value *> args(arg_array, 1);
-
- CallInst::Create(m_valid_pointer_check_func,
+
+ CallInst::Create(m_valid_pointer_check_func,
args,
"",
inst);
-
+
return true;
}
-
+
bool InspectInstruction(llvm::Instruction &i)
{
if (dyn_cast<llvm::LoadInst> (&i) ||
dyn_cast<llvm::StoreInst> (&i))
RegisterInstruction(i);
-
+
return true;
}
-
+
llvm::Value *m_valid_pointer_check_func;
};
@@ -427,12 +427,12 @@ public:
m_objc_object_check_func(NULL)
{
}
-
+
virtual
~ObjcObjectChecker ()
{
}
-
+
enum msgSend_type
{
eMsgSend = 0,
@@ -441,25 +441,25 @@ public:
eMsgSend_fpret,
eMsgSend_stret
};
-
+
std::map <llvm::Instruction *, msgSend_type> msgSend_types;
private:
bool InstrumentInstruction(llvm::Instruction *inst)
{
CallInst *call_inst = dyn_cast<CallInst>(inst);
-
+
if (!call_inst)
return false; // call_inst really shouldn't be NULL, because otherwise InspectInstruction wouldn't have registered it
-
+
if (!m_objc_object_check_func)
m_objc_object_check_func = BuildObjectCheckerFunc(m_checker_functions.m_objc_object_check->StartAddress());
-
+
// id objc_msgSend(id theReceiver, SEL theSelector, ...)
-
+
llvm::Value *target_object;
llvm::Value *selector;
-
+
switch (msgSend_types[inst])
{
case eMsgSend:
@@ -475,119 +475,124 @@ private:
case eMsgSendSuper_stret:
return true;
}
-
+
// These objects should always be valid according to Sean Calannan
assert (target_object);
assert (selector);
// Insert an instruction to cast the receiver id to int8_t*
-
+
BitCastInst *bit_cast = new BitCastInst(target_object,
GetI8PtrTy(),
"",
inst);
-
+
// Insert an instruction to call the helper with the result
-
+
llvm::Value *arg_array[2];
-
+
arg_array[0] = bit_cast;
arg_array[1] = selector;
-
+
ArrayRef<llvm::Value*> args(arg_array, 2);
-
- CallInst::Create(m_objc_object_check_func,
+
+ CallInst::Create(m_objc_object_check_func,
args,
"",
inst);
-
+
return true;
}
-
+
bool InspectInstruction(llvm::Instruction &i)
{
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
CallInst *call_inst = dyn_cast<CallInst>(&i);
-
+
if (call_inst)
{
// This metadata is set by IRForTarget::MaybeHandleCall().
-
+
MDNode *metadata = call_inst->getMetadata("lldb.call.realName");
-
+
if (!metadata)
return true;
-
+
if (metadata->getNumOperands() != 1)
{
if (log)
- log->Printf("Function call metadata has %d operands for [%p] %s", metadata->getNumOperands(), call_inst, PrintValue(call_inst).c_str());
+ log->Printf("Function call metadata has %d operands for [%p] %s",
+ metadata->getNumOperands(),
+ static_cast<void*>(call_inst),
+ PrintValue(call_inst).c_str());
return false;
}
-
+
MDString *real_name = dyn_cast<MDString>(metadata->getOperand(0));
-
+
if (!real_name)
{
if (log)
- log->Printf("Function call metadata is not an MDString for [%p] %s", call_inst, PrintValue(call_inst).c_str());
+ log->Printf("Function call metadata is not an MDString for [%p] %s",
+ static_cast<void*>(call_inst),
+ PrintValue(call_inst).c_str());
return false;
}
std::string name_str = real_name->getString();
const char* name_cstr = name_str.c_str();
-
+
if (log)
log->Printf("Found call to %s: %s\n", name_cstr, PrintValue(call_inst).c_str());
-
+
if (name_str.find("objc_msgSend") == std::string::npos)
return true;
-
+
if (!strcmp(name_cstr, "objc_msgSend"))
{
RegisterInstruction(i);
msgSend_types[&i] = eMsgSend;
return true;
}
-
+
if (!strcmp(name_cstr, "objc_msgSend_stret"))
{
RegisterInstruction(i);
msgSend_types[&i] = eMsgSend_stret;
return true;
}
-
+
if (!strcmp(name_cstr, "objc_msgSend_fpret"))
{
RegisterInstruction(i);
msgSend_types[&i] = eMsgSend_fpret;
return true;
}
-
+
if (!strcmp(name_cstr, "objc_msgSendSuper"))
{
RegisterInstruction(i);
msgSend_types[&i] = eMsgSendSuper;
return true;
}
-
+
if (!strcmp(name_cstr, "objc_msgSendSuper_stret"))
{
RegisterInstruction(i);
msgSend_types[&i] = eMsgSendSuper_stret;
return true;
}
-
+
if (log)
log->Printf("Function name '%s' contains 'objc_msgSend' but is not handled", name_str.c_str());
-
+
return true;
}
-
+
return true;
}
-
+
llvm::Value *m_objc_object_check_func;
};
@@ -607,52 +612,52 @@ bool
IRDynamicChecks::runOnModule(llvm::Module &M)
{
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
+
llvm::Function* function = M.getFunction(StringRef(m_func_name.c_str()));
-
+
if (!function)
{
if (log)
log->Printf("Couldn't find %s() in the module", m_func_name.c_str());
-
+
return false;
}
if (m_checker_functions.m_valid_pointer_check.get())
{
ValidPointerChecker vpc(M, m_checker_functions);
-
+
if (!vpc.Inspect(*function))
return false;
-
+
if (!vpc.Instrument())
return false;
}
-
+
if (m_checker_functions.m_objc_object_check.get())
{
ObjcObjectChecker ooc(M, m_checker_functions);
-
+
if (!ooc.Inspect(*function))
return false;
-
+
if (!ooc.Instrument())
return false;
}
-
+
if (log && log->GetVerbose())
{
std::string s;
raw_string_ostream oss(s);
-
+
M.print(oss, NULL);
-
+
oss.flush();
-
+
log->Printf ("Module after dynamic checks: \n%s", s.c_str());
}
-
- return true;
+
+ return true;
}
void
diff --git a/contrib/llvm/tools/lldb/source/Expression/IRExecutionUnit.cpp b/contrib/llvm/tools/lldb/source/Expression/IRExecutionUnit.cpp
index 17bd03a..090f88f 100644
--- a/contrib/llvm/tools/lldb/source/Expression/IRExecutionUnit.cpp
+++ b/contrib/llvm/tools/lldb/source/Expression/IRExecutionUnit.cpp
@@ -7,18 +7,16 @@
//
//===----------------------------------------------------------------------===//
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/SourceMgr.h"
-// Project includes
#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/Disassembler.h"
#include "lldb/Core/Log.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/Section.h"
#include "lldb/Expression/IRExecutionUnit.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Target.h"
@@ -46,39 +44,39 @@ lldb::addr_t
IRExecutionUnit::WriteNow (const uint8_t *bytes,
size_t size,
Error &error)
-{
+{
lldb::addr_t allocation_process_addr = Malloc (size,
8,
lldb::ePermissionsWritable | lldb::ePermissionsReadable,
eAllocationPolicyMirror,
error);
-
+
if (!error.Success())
return LLDB_INVALID_ADDRESS;
-
+
WriteMemory(allocation_process_addr, bytes, size, error);
-
+
if (!error.Success())
{
Error err;
Free (allocation_process_addr, err);
-
+
return LLDB_INVALID_ADDRESS;
}
-
+
if (Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS))
{
DataBufferHeap my_buffer(size, 0);
Error err;
ReadMemory(my_buffer.GetBytes(), allocation_process_addr, size, err);
-
+
if (err.Success())
{
DataExtractor my_extractor(my_buffer.GetBytes(), my_buffer.GetByteSize(), lldb::eByteOrderBig, 8);
my_extractor.PutToLog(log, 0, my_buffer.GetByteSize(), allocation_process_addr, 16, DataExtractor::TypeUInt8);
}
}
-
+
return allocation_process_addr;
}
@@ -87,9 +85,9 @@ IRExecutionUnit::FreeNow (lldb::addr_t allocation)
{
if (allocation == LLDB_INVALID_ADDRESS)
return;
-
+
Error err;
-
+
Free(allocation, err);
}
@@ -98,16 +96,16 @@ IRExecutionUnit::DisassembleFunction (Stream &stream,
lldb::ProcessSP &process_wp)
{
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
+
ExecutionContext exe_ctx(process_wp);
-
+
Error ret;
-
+
ret.Clear();
-
+
lldb::addr_t func_local_addr = LLDB_INVALID_ADDRESS;
lldb::addr_t func_remote_addr = LLDB_INVALID_ADDRESS;
-
+
for (JittedFunction &function : m_jitted_functions)
{
if (strstr(function.m_name.c_str(), m_name.AsCString()))
@@ -116,31 +114,31 @@ IRExecutionUnit::DisassembleFunction (Stream &stream,
func_remote_addr = function.m_remote_addr;
}
}
-
+
if (func_local_addr == LLDB_INVALID_ADDRESS)
{
ret.SetErrorToGenericError();
ret.SetErrorStringWithFormat("Couldn't find function %s for disassembly", m_name.AsCString());
return ret;
}
-
+
if (log)
log->Printf("Found function, has local address 0x%" PRIx64 " and remote address 0x%" PRIx64, (uint64_t)func_local_addr, (uint64_t)func_remote_addr);
-
+
std::pair <lldb::addr_t, lldb::addr_t> func_range;
-
+
func_range = GetRemoteRangeForLocal(func_local_addr);
-
+
if (func_range.first == 0 && func_range.second == 0)
{
ret.SetErrorToGenericError();
ret.SetErrorStringWithFormat("Couldn't find code range for function %s", m_name.AsCString());
return ret;
}
-
+
if (log)
log->Printf("Function's code range is [0x%" PRIx64 "+0x%" PRIx64 "]", func_range.first, func_range.second);
-
+
Target *target = exe_ctx.GetTargetPtr();
if (!target)
{
@@ -148,44 +146,44 @@ IRExecutionUnit::DisassembleFunction (Stream &stream,
ret.SetErrorString("Couldn't find the target");
return ret;
}
-
+
lldb::DataBufferSP buffer_sp(new DataBufferHeap(func_range.second, 0));
-
+
Process *process = exe_ctx.GetProcessPtr();
Error err;
process->ReadMemory(func_remote_addr, buffer_sp->GetBytes(), buffer_sp->GetByteSize(), err);
-
+
if (!err.Success())
{
ret.SetErrorToGenericError();
ret.SetErrorStringWithFormat("Couldn't read from process: %s", err.AsCString("unknown error"));
return ret;
}
-
+
ArchSpec arch(target->GetArchitecture());
-
+
const char *plugin_name = NULL;
const char *flavor_string = NULL;
lldb::DisassemblerSP disassembler_sp = Disassembler::FindPlugin(arch, flavor_string, plugin_name);
-
+
if (!disassembler_sp)
{
ret.SetErrorToGenericError();
ret.SetErrorStringWithFormat("Unable to find disassembler plug-in for %s architecture.", arch.GetArchitectureName());
return ret;
}
-
+
if (!process)
{
ret.SetErrorToGenericError();
ret.SetErrorString("Couldn't find the process");
return ret;
}
-
+
DataExtractor extractor(buffer_sp,
process->GetByteOrder(),
target->GetArchitecture().GetAddressByteSize());
-
+
if (log)
{
log->Printf("Function data has contents:");
@@ -196,12 +194,12 @@ IRExecutionUnit::DisassembleFunction (Stream &stream,
16,
DataExtractor::TypeUInt8);
}
-
+
disassembler_sp->DecodeInstructions (Address (func_remote_addr), extractor, 0, UINT32_MAX, false, false);
-
+
InstructionList &instruction_list = disassembler_sp->GetInstructionList();
const uint32_t max_opcode_byte_size = instruction_list.GetMaxOpcocdeByteSize();
-
+
for (size_t instruction_index = 0, num_instructions = instruction_list.GetSize();
instruction_index < num_instructions;
++instruction_index)
@@ -223,7 +221,7 @@ IRExecutionUnit::DisassembleFunction (Stream &stream,
static void ReportInlineAsmError(const llvm::SMDiagnostic &diagnostic, void *Context, unsigned LocCookie)
{
Error *err = static_cast<Error*>(Context);
-
+
if (err && err->Success())
{
err->SetErrorToGenericError();
@@ -237,52 +235,52 @@ IRExecutionUnit::GetRunnableInfo(Error &error,
lldb::addr_t &func_end)
{
lldb::ProcessSP process_sp(GetProcessWP().lock());
-
+
static Mutex s_runnable_info_mutex(Mutex::Type::eMutexTypeRecursive);
-
+
func_addr = LLDB_INVALID_ADDRESS;
func_end = LLDB_INVALID_ADDRESS;
-
+
if (!process_sp)
{
error.SetErrorToGenericError();
error.SetErrorString("Couldn't write the JIT compiled code into the process because the process is invalid");
return;
}
-
+
if (m_did_jit)
{
func_addr = m_function_load_addr;
func_end = m_function_end_load_addr;
-
+
return;
};
-
+
Mutex::Locker runnable_info_mutex_locker(s_runnable_info_mutex);
-
+
m_did_jit = true;
-
+
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
+
std::string error_string;
-
+
if (log)
{
std::string s;
llvm::raw_string_ostream oss(s);
-
+
m_module->print(oss, NULL);
-
+
oss.flush();
-
+
log->Printf ("Module being sent to JIT: \n%s", s.c_str());
}
-
+
llvm::Triple triple(m_module->getTargetTriple());
llvm::Function *function = m_module->getFunction (m_name.AsCString());
llvm::Reloc::Model relocModel;
llvm::CodeModel::Model codeModel;
-
+
if (triple.isOSBinFormatELF())
{
relocModel = llvm::Reloc::Static;
@@ -294,11 +292,11 @@ IRExecutionUnit::GetRunnableInfo(Error &error,
relocModel = llvm::Reloc::PIC_;
codeModel = llvm::CodeModel::Small;
}
-
+
m_module_ap->getContext().setInlineAsmDiagnosticHandler(ReportInlineAsmError, &error);
-
- llvm::EngineBuilder builder(m_module_ap.get());
-
+
+ llvm::EngineBuilder builder(std::move(m_module_ap));
+
builder.setEngineKind(llvm::EngineKind::JIT)
.setErrorStr(&error_string)
.setRelocationModel(relocModel)
@@ -307,68 +305,67 @@ IRExecutionUnit::GetRunnableInfo(Error &error,
.setAllocateGVsWithCode(true)
.setCodeModel(codeModel)
.setUseMCJIT(true);
-
+
llvm::StringRef mArch;
llvm::StringRef mCPU;
llvm::SmallVector<std::string, 0> mAttrs;
-
+
for (std::string &feature : m_cpu_features)
mAttrs.push_back(feature);
-
+
llvm::TargetMachine *target_machine = builder.selectTarget(triple,
mArch,
mCPU,
mAttrs);
-
+
m_execution_engine_ap.reset(builder.create(target_machine));
-
+
if (!m_execution_engine_ap.get())
{
error.SetErrorToGenericError();
error.SetErrorStringWithFormat("Couldn't JIT the function: %s", error_string.c_str());
return;
}
- else
- {
- m_module_ap.release(); // ownership was transferred
- }
-
+
+ // Make sure we see all sections, including ones that don't have relocations...
+ m_execution_engine_ap->setProcessAllSections(true);
+
m_execution_engine_ap->DisableLazyCompilation();
-
+
// We don't actually need the function pointer here, this just forces it to get resolved.
-
+
void *fun_ptr = m_execution_engine_ap->getPointerToFunction(function);
-
+
if (!error.Success())
{
// We got an error through our callback!
return;
}
-
+
if (!function)
{
error.SetErrorToGenericError();
error.SetErrorStringWithFormat("Couldn't find '%s' in the JITted module", m_name.AsCString());
return;
}
-
+
if (!fun_ptr)
{
error.SetErrorToGenericError();
error.SetErrorStringWithFormat("'%s' was in the JITted module but wasn't lowered", m_name.AsCString());
return;
}
-
+
m_jitted_functions.push_back (JittedFunction(m_name.AsCString(), (lldb::addr_t)fun_ptr));
-
+
CommitAllocations(process_sp);
ReportAllocations(*m_execution_engine_ap);
WriteData(process_sp);
-
+
for (JittedFunction &jitted_function : m_jitted_functions)
{
jitted_function.m_remote_addr = GetRemoteAddressForLocal (jitted_function.m_local_addr);
-
+
if (!jitted_function.m_name.compare(m_name.AsCString()))
{
AddrRange func_range = GetRemoteRangeForLocal(jitted_function.m_local_addr);
@@ -376,15 +373,15 @@ IRExecutionUnit::GetRunnableInfo(Error &error,
m_function_load_addr = jitted_function.m_remote_addr;
}
}
-
+
if (log)
{
log->Printf("Code can be run in the target.");
-
+
StreamString disassembly_stream;
-
+
Error err = DisassembleFunction(disassembly_stream, process_sp);
-
+
if (!err.Success())
{
log->Printf("Couldn't disassemble function : %s", err.AsCString("unknown error"));
@@ -393,18 +390,18 @@ IRExecutionUnit::GetRunnableInfo(Error &error,
{
log->Printf("Function disassembly:\n%s", disassembly_stream.GetData());
}
-
+
log->Printf("Sections: ");
for (AllocationRecord &record : m_records)
{
if (record.m_process_address != LLDB_INVALID_ADDRESS)
{
record.dump(log);
-
+
DataBufferHeap my_buffer(record.m_size, 0);
Error err;
ReadMemory(my_buffer.GetBytes(), record.m_process_address, record.m_size, err);
-
+
if (err.Success())
{
DataExtractor my_extractor(my_buffer.GetBytes(), my_buffer.GetByteSize(), lldb::eByteOrderBig, 8);
@@ -413,10 +410,10 @@ IRExecutionUnit::GetRunnableInfo(Error &error,
}
}
}
-
+
func_addr = m_function_load_addr;
func_end = m_function_end_load_addr;
-
+
return;
}
@@ -433,6 +430,9 @@ IRExecutionUnit::MemoryManager::MemoryManager (IRExecutionUnit &parent) :
{
}
+IRExecutionUnit::MemoryManager::~MemoryManager ()
+{
+}
void
IRExecutionUnit::MemoryManager::setMemoryWritable ()
{
@@ -464,15 +464,19 @@ IRExecutionUnit::MemoryManager::allocateStub(const llvm::GlobalValue* F,
m_parent.m_records.push_back(AllocationRecord((uintptr_t)return_value,
lldb::ePermissionsReadable | lldb::ePermissionsWritable,
+ GetSectionTypeFromSectionName (llvm::StringRef(), AllocationKind::Stub),
StubSize,
- Alignment));
+ Alignment,
+ eSectionIDInvalid,
+ NULL));
if (log)
{
log->Printf("IRExecutionUnit::allocateStub (F=%p, StubSize=%u, Alignment=%u) = %p",
- F, StubSize, Alignment, return_value);
+ static_cast<const void*>(F), StubSize, Alignment,
+ static_cast<void*>(return_value));
}
-
+
return return_value;
}
@@ -484,24 +488,136 @@ IRExecutionUnit::MemoryManager::endFunctionBody(const llvm::Function *F,
m_default_mm_ap->endFunctionBody(F, FunctionStart, FunctionEnd);
}
+lldb::SectionType
+IRExecutionUnit::GetSectionTypeFromSectionName (const llvm::StringRef &name, IRExecutionUnit::AllocationKind alloc_kind)
+{
+ lldb::SectionType sect_type = lldb::eSectionTypeCode;
+ switch (alloc_kind)
+ {
+ case AllocationKind::Stub: sect_type = lldb::eSectionTypeCode; break;
+ case AllocationKind::Code: sect_type = lldb::eSectionTypeCode; break;
+ case AllocationKind::Data: sect_type = lldb::eSectionTypeData; break;
+ case AllocationKind::Global:sect_type = lldb::eSectionTypeData; break;
+ case AllocationKind::Bytes: sect_type = lldb::eSectionTypeOther; break;
+ }
+
+ if (!name.empty())
+ {
+ if (name.equals("__text") || name.equals(".text"))
+ sect_type = lldb::eSectionTypeCode;
+ else if (name.equals("__data") || name.equals(".data"))
+ sect_type = lldb::eSectionTypeCode;
+ else if (name.startswith("__debug_") || name.startswith(".debug_"))
+ {
+ const uint32_t name_idx = name[0] == '_' ? 8 : 7;
+ llvm::StringRef dwarf_name(name.substr(name_idx));
+ switch (dwarf_name[0])
+ {
+ case 'a':
+ if (dwarf_name.equals("abbrev"))
+ sect_type = lldb::eSectionTypeDWARFDebugAbbrev;
+ else if (dwarf_name.equals("aranges"))
+ sect_type = lldb::eSectionTypeDWARFDebugAranges;
+ break;
+
+ case 'f':
+ if (dwarf_name.equals("frame"))
+ sect_type = lldb::eSectionTypeDWARFDebugFrame;
+ break;
+
+ case 'i':
+ if (dwarf_name.equals("info"))
+ sect_type = lldb::eSectionTypeDWARFDebugInfo;
+ break;
+
+ case 'l':
+ if (dwarf_name.equals("line"))
+ sect_type = lldb::eSectionTypeDWARFDebugLine;
+ else if (dwarf_name.equals("loc"))
+ sect_type = lldb::eSectionTypeDWARFDebugLoc;
+ break;
+
+ case 'm':
+ if (dwarf_name.equals("macinfo"))
+ sect_type = lldb::eSectionTypeDWARFDebugMacInfo;
+ break;
+
+ case 'p':
+ if (dwarf_name.equals("pubnames"))
+ sect_type = lldb::eSectionTypeDWARFDebugPubNames;
+ else if (dwarf_name.equals("pubtypes"))
+ sect_type = lldb::eSectionTypeDWARFDebugPubTypes;
+ break;
+
+ case 's':
+ if (dwarf_name.equals("str"))
+ sect_type = lldb::eSectionTypeDWARFDebugStr;
+ break;
+
+ case 'r':
+ if (dwarf_name.equals("ranges"))
+ sect_type = lldb::eSectionTypeDWARFDebugRanges;
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (name.startswith("__apple_") || name.startswith(".apple_"))
+ {
+#if 0
+ const uint32_t name_idx = name[0] == '_' ? 8 : 7;
+ llvm::StringRef apple_name(name.substr(name_idx));
+ switch (apple_name[0])
+ {
+ case 'n':
+ if (apple_name.equals("names"))
+ sect_type = lldb::eSectionTypeDWARFAppleNames;
+ else if (apple_name.equals("namespac") || apple_name.equals("namespaces"))
+ sect_type = lldb::eSectionTypeDWARFAppleNamespaces;
+ break;
+ case 't':
+ if (apple_name.equals("types"))
+ sect_type = lldb::eSectionTypeDWARFAppleTypes;
+ break;
+ case 'o':
+ if (apple_name.equals("objc"))
+ sect_type = lldb::eSectionTypeDWARFAppleObjC;
+ break;
+ default:
+ break;
+ }
+#else
+ sect_type = lldb::eSectionTypeInvalid;
+#endif
+ }
+ else if (name.equals("__objc_imageinfo"))
+ sect_type = lldb::eSectionTypeOther;
+ }
+ return sect_type;
+}
+
uint8_t *
IRExecutionUnit::MemoryManager::allocateSpace(intptr_t Size, unsigned Alignment)
{
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
uint8_t *return_value = m_default_mm_ap->allocateSpace(Size, Alignment);
-
+
m_parent.m_records.push_back(AllocationRecord((uintptr_t)return_value,
lldb::ePermissionsReadable | lldb::ePermissionsWritable,
+ GetSectionTypeFromSectionName (llvm::StringRef(), AllocationKind::Bytes),
Size,
- Alignment));
-
+ Alignment,
+ eSectionIDInvalid,
+ NULL));
+
if (log)
{
log->Printf("IRExecutionUnit::allocateSpace(Size=%" PRIu64 ", Alignment=%u) = %p",
(uint64_t)Size, Alignment, return_value);
}
-
+
return return_value;
}
@@ -512,21 +628,23 @@ IRExecutionUnit::MemoryManager::allocateCodeSection(uintptr_t Size,
llvm::StringRef SectionName)
{
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
+
uint8_t *return_value = m_default_mm_ap->allocateCodeSection(Size, Alignment, SectionID, SectionName);
-
+
m_parent.m_records.push_back(AllocationRecord((uintptr_t)return_value,
lldb::ePermissionsReadable | lldb::ePermissionsExecutable,
+ GetSectionTypeFromSectionName (SectionName, AllocationKind::Code),
Size,
Alignment,
- SectionID));
-
+ SectionID,
+ SectionName.str().c_str()));
+
if (log)
{
log->Printf("IRExecutionUnit::allocateCodeSection(Size=0x%" PRIx64 ", Alignment=%u, SectionID=%u) = %p",
(uint64_t)Size, Alignment, SectionID, return_value);
}
-
+
return return_value;
}
@@ -540,19 +658,21 @@ IRExecutionUnit::MemoryManager::allocateDataSection(uintptr_t Size,
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
uint8_t *return_value = m_default_mm_ap->allocateDataSection(Size, Alignment, SectionID, SectionName, IsReadOnly);
-
+
m_parent.m_records.push_back(AllocationRecord((uintptr_t)return_value,
- lldb::ePermissionsReadable | lldb::ePermissionsWritable,
+ lldb::ePermissionsReadable | (IsReadOnly ? 0 : lldb::ePermissionsWritable),
+ GetSectionTypeFromSectionName (SectionName, AllocationKind::Data),
Size,
Alignment,
- SectionID));
+ SectionID,
+ SectionName.str().c_str()));
if (log)
{
log->Printf("IRExecutionUnit::allocateDataSection(Size=0x%" PRIx64 ", Alignment=%u, SectionID=%u) = %p",
(uint64_t)Size, Alignment, SectionID, return_value);
}
-
- return return_value;
+
+ return return_value;
}
uint8_t *
@@ -562,18 +682,21 @@ IRExecutionUnit::MemoryManager::allocateGlobal(uintptr_t Size,
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
uint8_t *return_value = m_default_mm_ap->allocateGlobal(Size, Alignment);
-
+
m_parent.m_records.push_back(AllocationRecord((uintptr_t)return_value,
lldb::ePermissionsReadable | lldb::ePermissionsWritable,
+ GetSectionTypeFromSectionName (llvm::StringRef(), AllocationKind::Global),
Size,
- Alignment));
-
+ Alignment,
+ eSectionIDInvalid,
+ NULL));
+
if (log)
{
log->Printf("IRExecutionUnit::allocateGlobal(Size=0x%" PRIx64 ", Alignment=%u) = %p",
(uint64_t)Size, Alignment, return_value);
}
-
+
return return_value;
}
@@ -595,9 +718,9 @@ IRExecutionUnit::GetRemoteAddressForLocal (lldb::addr_t local_address)
{
if (record.m_process_address == LLDB_INVALID_ADDRESS)
return LLDB_INVALID_ADDRESS;
-
+
lldb::addr_t ret = record.m_process_address + (local_address - record.m_host_address);
-
+
if (log)
{
log->Printf("IRExecutionUnit::GetRemoteAddressForLocal() found 0x%" PRIx64 " in [0x%" PRIx64 "..0x%" PRIx64 "], and returned 0x%" PRIx64 " from [0x%" PRIx64 "..0x%" PRIx64 "].",
@@ -608,7 +731,7 @@ IRExecutionUnit::GetRemoteAddressForLocal (lldb::addr_t local_address)
record.m_process_address,
record.m_process_address + record.m_size);
}
-
+
return ret;
}
}
@@ -626,11 +749,11 @@ IRExecutionUnit::GetRemoteRangeForLocal (lldb::addr_t local_address)
{
if (record.m_process_address == LLDB_INVALID_ADDRESS)
return AddrRange(0, 0);
-
+
return AddrRange(record.m_process_address, record.m_size);
}
}
-
+
return AddrRange (0, 0);
}
@@ -638,28 +761,50 @@ bool
IRExecutionUnit::CommitAllocations (lldb::ProcessSP &process_sp)
{
bool ret = true;
-
+
lldb_private::Error err;
-
+
for (AllocationRecord &record : m_records)
{
if (record.m_process_address != LLDB_INVALID_ADDRESS)
continue;
-
-
- record.m_process_address = Malloc(record.m_size,
- record.m_alignment,
- record.m_permissions,
- eAllocationPolicyProcessOnly,
- err);
-
+
+ switch (record.m_sect_type)
+ {
+ case lldb::eSectionTypeInvalid:
+ case lldb::eSectionTypeDWARFDebugAbbrev:
+ case lldb::eSectionTypeDWARFDebugAranges:
+ case lldb::eSectionTypeDWARFDebugFrame:
+ case lldb::eSectionTypeDWARFDebugInfo:
+ case lldb::eSectionTypeDWARFDebugLine:
+ case lldb::eSectionTypeDWARFDebugLoc:
+ case lldb::eSectionTypeDWARFDebugMacInfo:
+ case lldb::eSectionTypeDWARFDebugPubNames:
+ case lldb::eSectionTypeDWARFDebugPubTypes:
+ case lldb::eSectionTypeDWARFDebugRanges:
+ case lldb::eSectionTypeDWARFDebugStr:
+ case lldb::eSectionTypeDWARFAppleNames:
+ case lldb::eSectionTypeDWARFAppleTypes:
+ case lldb::eSectionTypeDWARFAppleNamespaces:
+ case lldb::eSectionTypeDWARFAppleObjC:
+ err.Clear();
+ break;
+ default:
+ record.m_process_address = Malloc (record.m_size,
+ record.m_alignment,
+ record.m_permissions,
+ eAllocationPolicyProcessOnly,
+ err);
+ break;
+ }
+
if (!err.Success())
{
ret = false;
break;
}
}
-
+
if (!ret)
{
for (AllocationRecord &record : m_records)
@@ -671,7 +816,7 @@ IRExecutionUnit::CommitAllocations (lldb::ProcessSP &process_sp)
}
}
}
-
+
return ret;
}
@@ -682,13 +827,13 @@ IRExecutionUnit::ReportAllocations (llvm::ExecutionEngine &engine)
{
if (record.m_process_address == LLDB_INVALID_ADDRESS)
continue;
-
+
if (record.m_section_id == eSectionIDInvalid)
continue;
-
+
engine.mapSectionAddress((void*)record.m_host_address, record.m_process_address);
}
-
+
// Trigger re-application of relocations.
engine.finalizeObject();
}
@@ -696,25 +841,26 @@ IRExecutionUnit::ReportAllocations (llvm::ExecutionEngine &engine)
bool
IRExecutionUnit::WriteData (lldb::ProcessSP &process_sp)
{
+ bool wrote_something = false;
for (AllocationRecord &record : m_records)
{
- if (record.m_process_address == LLDB_INVALID_ADDRESS)
- return false;
-
- lldb_private::Error err;
-
- WriteMemory (record.m_process_address, (uint8_t*)record.m_host_address, record.m_size, err);
+ if (record.m_process_address != LLDB_INVALID_ADDRESS)
+ {
+ lldb_private::Error err;
+ WriteMemory (record.m_process_address, (uint8_t*)record.m_host_address, record.m_size, err);
+ if (err.Success())
+ wrote_something = true;
+ }
}
-
- return true;
+ return wrote_something;
}
-void
+void
IRExecutionUnit::AllocationRecord::dump (Log *log)
{
if (!log)
return;
-
+
log->Printf("[0x%llx+0x%llx]->0x%llx (alignment %d, section ID %d)",
(unsigned long long)m_host_address,
(unsigned long long)m_size,
@@ -722,3 +868,80 @@ IRExecutionUnit::AllocationRecord::dump (Log *log)
(unsigned)m_alignment,
(unsigned)m_section_id);
}
+
+
+lldb::ByteOrder
+IRExecutionUnit::GetByteOrder () const
+{
+ ExecutionContext exe_ctx (GetBestExecutionContextScope());
+ return exe_ctx.GetByteOrder();
+}
+
+uint32_t
+IRExecutionUnit::GetAddressByteSize () const
+{
+ ExecutionContext exe_ctx (GetBestExecutionContextScope());
+ return exe_ctx.GetAddressByteSize();
+}
+
+void
+IRExecutionUnit::PopulateSymtab (lldb_private::ObjectFile *obj_file,
+ lldb_private::Symtab &symtab)
+{
+ // No symbols yet...
+}
+
+
+void
+IRExecutionUnit::PopulateSectionList (lldb_private::ObjectFile *obj_file,
+ lldb_private::SectionList &section_list)
+{
+ for (AllocationRecord &record : m_records)
+ {
+ if (record.m_size > 0)
+ {
+ lldb::SectionSP section_sp (new lldb_private::Section (obj_file->GetModule(),
+ obj_file,
+ record.m_section_id,
+ ConstString(record.m_name),
+ record.m_sect_type,
+ record.m_process_address,
+ record.m_size,
+ record.m_host_address, // file_offset (which is the host address for the data)
+ record.m_size, // file_size
+ 0,
+ record.m_permissions)); // flags
+ section_list.AddSection (section_sp);
+ }
+ }
+}
+
+bool
+IRExecutionUnit::GetArchitecture (lldb_private::ArchSpec &arch)
+{
+ ExecutionContext exe_ctx (GetBestExecutionContextScope());
+ Target *target = exe_ctx.GetTargetPtr();
+ if (target)
+ arch = target->GetArchitecture();
+ else
+ arch.Clear();
+ return arch.IsValid();
+}
+
+lldb::ModuleSP
+IRExecutionUnit::GetJITModule ()
+{
+ ExecutionContext exe_ctx (GetBestExecutionContextScope());
+ Target *target = exe_ctx.GetTargetPtr();
+ if (target)
+ {
+ lldb::ModuleSP jit_module_sp = lldb_private::Module::CreateJITModule (std::static_pointer_cast<lldb_private::ObjectFileJITDelegate>(shared_from_this()));
+ if (jit_module_sp)
+ {
+ bool changed = false;
+ jit_module_sp->SetLoadAddress(*target, 0, true, changed);
+ }
+ return jit_module_sp;
+ }
+ return lldb::ModuleSP();
+}
diff --git a/contrib/llvm/tools/lldb/source/Expression/IRForTarget.cpp b/contrib/llvm/tools/lldb/source/Expression/IRForTarget.cpp
index a998896..b91e1b4 100644
--- a/contrib/llvm/tools/lldb/source/Expression/IRForTarget.cpp
+++ b/contrib/llvm/tools/lldb/source/Expression/IRForTarget.cpp
@@ -59,7 +59,7 @@ IRForTarget::FunctionValueCache::~FunctionValueCache()
}
llvm::Value *IRForTarget::FunctionValueCache::GetValue(llvm::Function *function)
-{
+{
if (!m_values.count(function))
{
llvm::Value *ret = m_maker(function);
@@ -72,13 +72,13 @@ llvm::Value *IRForTarget::FunctionValueCache::GetValue(llvm::Function *function)
lldb::addr_t IRForTarget::StaticDataAllocator::Allocate()
{
lldb_private::Error err;
-
+
if (m_allocation != LLDB_INVALID_ADDRESS)
{
m_execution_unit.FreeNow(m_allocation);
m_allocation = LLDB_INVALID_ADDRESS;
}
-
+
m_allocation = m_execution_unit.WriteNow((const uint8_t*)m_stream_string.GetData(), m_stream_string.GetSize(), err);
return m_allocation;
@@ -88,7 +88,7 @@ static llvm::Value *FindEntryInstruction (llvm::Function *function)
{
if (function->empty())
return NULL;
-
+
return function->getEntryBlock().getFirstNonPHIOrDbg();
}
@@ -116,7 +116,7 @@ IRForTarget::IRForTarget (lldb_private::ClangExpressionDeclMap *decl_map,
/* Handy utility functions used at several places in the code */
-static std::string
+static std::string
PrintValue(const Value *value, bool truncate = false)
{
std::string s;
@@ -151,38 +151,38 @@ bool
IRForTarget::FixFunctionLinkage(llvm::Function &llvm_function)
{
llvm_function.setLinkage(GlobalValue::ExternalLinkage);
-
+
std::string name = llvm_function.getName().str();
-
+
return true;
}
-bool
+IRForTarget::LookupResult
IRForTarget::GetFunctionAddress (llvm::Function *fun,
uint64_t &fun_addr,
lldb_private::ConstString &name,
Constant **&value_ptr)
{
lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
+
fun_addr = LLDB_INVALID_ADDRESS;
name.Clear();
value_ptr = NULL;
-
+
if (fun->isIntrinsic())
{
Intrinsic::ID intrinsic_id = (Intrinsic::ID)fun->getIntrinsicID();
-
+
switch (intrinsic_id)
{
default:
if (log)
log->Printf("Unresolved intrinsic \"%s\"", Intrinsic::getName(intrinsic_id).c_str());
-
+
if (m_error_stream)
m_error_stream->Printf("Internal error [IRForTarget]: Call to unhandled compiler intrinsic '%s'\n", Intrinsic::getName(intrinsic_id).c_str());
-
- return false;
+
+ return LookupResult::Fail;
case Intrinsic::memcpy:
{
static lldb_private::ConstString g_memcpy_str ("memcpy");
@@ -195,8 +195,11 @@ IRForTarget::GetFunctionAddress (llvm::Function *fun,
name = g_memset_str;
}
break;
+ case Intrinsic::dbg_declare:
+ case Intrinsic::dbg_value:
+ return LookupResult::Ignore;
}
-
+
if (log && name)
log->Printf("Resolved intrinsic name \"%s\"", name.GetCString());
}
@@ -204,14 +207,14 @@ IRForTarget::GetFunctionAddress (llvm::Function *fun,
{
name.SetCStringWithLength (fun->getName().data(), fun->getName().size());
}
-
+
// Find the address of the function.
-
+
clang::NamedDecl *fun_decl = DeclForGlobal (fun);
-
+
if (fun_decl)
{
- if (!m_decl_map->GetFunctionInfo (fun_decl, fun_addr))
+ if (!m_decl_map->GetFunctionInfo (fun_decl, fun_addr))
{
lldb_private::ConstString altnernate_name;
bool found_it = m_decl_map->GetFunctionAddress (name, fun_addr);
@@ -228,7 +231,7 @@ IRForTarget::GetFunctionAddress (llvm::Function *fun,
found_it = m_decl_map->GetFunctionAddress (altnernate_name, fun_addr);
}
}
-
+
if (!found_it)
{
lldb_private::Mangled mangled_name(name);
@@ -243,7 +246,7 @@ IRForTarget::GetFunctionAddress (llvm::Function *fun,
log->Printf("Function \"%s\" had no address",
mangled_name.GetName().GetCString());
}
-
+
if (m_error_stream)
{
if (alt_mangled_name)
@@ -258,28 +261,28 @@ IRForTarget::GetFunctionAddress (llvm::Function *fun,
m_error_stream->Printf("error: call to a function '%s' that is not present in the target\n",
mangled_name.GetName().GetCString());
}
- return false;
+ return LookupResult::Fail;
}
}
}
- else
+ else
{
if (!m_decl_map->GetFunctionAddress (name, fun_addr))
{
if (log)
log->Printf ("Metadataless function \"%s\" had no address", name.GetCString());
-
+
if (m_error_stream)
m_error_stream->Printf("Error [IRForTarget]: Call to a symbol-only function '%s' that is not present in the target\n", name.GetCString());
-
- return false;
+
+ return LookupResult::Fail;
}
}
-
+
if (log)
log->Printf("Found \"%s\" at 0x%" PRIx64, name.GetCString(), fun_addr);
-
- return true;
+
+ return LookupResult::Success;
}
llvm::Constant *
@@ -293,15 +296,11 @@ IRForTarget::BuildFunctionPointer (llvm::Type *type,
void
IRForTarget::RegisterFunctionMetadata(LLVMContext &context,
- llvm::Value *function_ptr,
+ llvm::Value *function_ptr,
const char *name)
{
- for (Value::use_iterator i = function_ptr->use_begin(), e = function_ptr->use_end();
- i != e;
- ++i)
+ for (llvm::User *user : function_ptr->users())
{
- Value *user = *i;
-
if (Instruction *user_inst = dyn_cast<Instruction>(user))
{
MDString* md_name = MDString::get(context, StringRef(name));
@@ -317,62 +316,74 @@ IRForTarget::RegisterFunctionMetadata(LLVMContext &context,
}
}
-bool
+bool
IRForTarget::ResolveFunctionPointers(llvm::Module &llvm_module)
{
lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
+
for (llvm::Module::iterator fi = llvm_module.begin();
fi != llvm_module.end();
++fi)
{
Function *fun = fi;
-
+
bool is_decl = fun->isDeclaration();
-
+
if (log)
log->Printf("Examining %s function %s", (is_decl ? "declaration" : "non-declaration"), fun->getName().str().c_str());
-
+
if (!is_decl)
continue;
-
- if (fun->hasNUses(0))
+
+ if (fun->use_empty())
continue; // ignore
-
+
uint64_t addr = LLDB_INVALID_ADDRESS;
lldb_private::ConstString name;
Constant **value_ptr = NULL;
-
- if (!GetFunctionAddress(fun,
- addr,
- name,
- value_ptr))
+
+ LookupResult result = GetFunctionAddress(fun,
+ addr,
+ name,
+ value_ptr);
+
+ switch (result)
+ {
+ case LookupResult::Fail:
return false; // GetFunctionAddress reports its own errors
-
- Constant *value = BuildFunctionPointer(fun->getFunctionType(), addr);
-
- RegisterFunctionMetadata (llvm_module.getContext(), fun, name.AsCString());
-
- if (value_ptr)
- *value_ptr = value;
-
- // If we are replacing a function with the nobuiltin attribute, it may
- // be called with the builtin attribute on call sites. Remove any such
- // attributes since it's illegal to have a builtin call to something
- // other than a nobuiltin function.
- if (fun->hasFnAttribute(llvm::Attribute::NoBuiltin)) {
- llvm::Attribute builtin = llvm::Attribute::get(fun->getContext(), llvm::Attribute::Builtin);
-
- for (auto u = fun->use_begin(), e = fun->use_end(); u != e; ++u) {
- if (auto call = dyn_cast<CallInst>(*u)) {
- call->removeAttribute(AttributeSet::FunctionIndex, builtin);
+
+ case LookupResult::Ignore:
+ break; // Nothing to do
+
+ case LookupResult::Success:
+ {
+ Constant *value = BuildFunctionPointer(fun->getFunctionType(), addr);
+
+ RegisterFunctionMetadata (llvm_module.getContext(), fun, name.AsCString());
+
+ if (value_ptr)
+ *value_ptr = value;
+
+ // If we are replacing a function with the nobuiltin attribute, it may
+ // be called with the builtin attribute on call sites. Remove any such
+ // attributes since it's illegal to have a builtin call to something
+ // other than a nobuiltin function.
+ if (fun->hasFnAttribute(llvm::Attribute::NoBuiltin)) {
+ llvm::Attribute builtin = llvm::Attribute::get(fun->getContext(), llvm::Attribute::Builtin);
+
+ for (auto u : fun->users()) {
+ if (auto call = dyn_cast<CallInst>(u)) {
+ call->removeAttribute(AttributeSet::FunctionIndex, builtin);
+ }
+ }
}
+
+ fun->replaceAllUsesWith(value);
}
+ break;
}
-
- fun->replaceAllUsesWith(value);
}
-
+
return true;
}
@@ -381,69 +392,69 @@ clang::NamedDecl *
IRForTarget::DeclForGlobal (const GlobalValue *global_val, Module *module)
{
NamedMDNode *named_metadata = module->getNamedMetadata("clang.global.decl.ptrs");
-
+
if (!named_metadata)
return NULL;
-
+
unsigned num_nodes = named_metadata->getNumOperands();
unsigned node_index;
-
+
for (node_index = 0;
node_index < num_nodes;
++node_index)
{
MDNode *metadata_node = named_metadata->getOperand(node_index);
-
+
if (!metadata_node)
return NULL;
-
+
if (metadata_node->getNumOperands() != 2)
continue;
-
+
if (metadata_node->getOperand(0) != global_val)
continue;
-
+
ConstantInt *constant_int = dyn_cast<ConstantInt>(metadata_node->getOperand(1));
-
+
if (!constant_int)
return NULL;
-
+
uintptr_t ptr = constant_int->getZExtValue();
-
+
return reinterpret_cast<clang::NamedDecl *>(ptr);
}
-
+
return NULL;
}
clang::NamedDecl *
IRForTarget::DeclForGlobal (GlobalValue *global_val)
-{
+{
return DeclForGlobal(global_val, m_module);
}
-bool
+bool
IRForTarget::CreateResultVariable (llvm::Function &llvm_function)
{
lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
+
if (!m_resolve_vars)
return true;
-
+
// Find the result variable. If it doesn't exist, we can give up right here.
-
+
ValueSymbolTable& value_symbol_table = m_module->getValueSymbolTable();
-
+
std::string result_name_str;
const char *result_name = NULL;
-
+
for (ValueSymbolTable::iterator vi = value_symbol_table.begin(), ve = value_symbol_table.end();
vi != ve;
++vi)
{
result_name_str = vi->first().str();
const char *value_name = result_name_str.c_str();
-
+
if (strstr(value_name, "$__lldb_expr_result_ptr") &&
strncmp(value_name, "_ZGV", 4))
{
@@ -451,7 +462,7 @@ IRForTarget::CreateResultVariable (llvm::Function &llvm_function)
m_result_is_pointer = true;
break;
}
-
+
if (strstr(value_name, "$__lldb_expr_result") &&
strncmp(value_name, "_ZGV", 4))
{
@@ -460,105 +471,105 @@ IRForTarget::CreateResultVariable (llvm::Function &llvm_function)
break;
}
}
-
+
if (!result_name)
{
if (log)
log->PutCString("Couldn't find result variable");
-
+
return true;
}
-
+
if (log)
log->Printf("Result name: \"%s\"", result_name);
-
+
Value *result_value = m_module->getNamedValue(result_name);
-
+
if (!result_value)
{
if (log)
log->PutCString("Result variable had no data");
-
+
if (m_error_stream)
m_error_stream->Printf("Internal error [IRForTarget]: Result variable's name (%s) exists, but not its definition\n", result_name);
-
+
return false;
}
-
+
if (log)
log->Printf("Found result in the IR: \"%s\"", PrintValue(result_value, false).c_str());
-
+
GlobalVariable *result_global = dyn_cast<GlobalVariable>(result_value);
-
+
if (!result_global)
{
if (log)
log->PutCString("Result variable isn't a GlobalVariable");
-
+
if (m_error_stream)
m_error_stream->Printf("Internal error [IRForTarget]: Result variable (%s) is defined, but is not a global variable\n", result_name);
-
+
return false;
}
-
+
clang::NamedDecl *result_decl = DeclForGlobal (result_global);
if (!result_decl)
{
if (log)
log->PutCString("Result variable doesn't have a corresponding Decl");
-
+
if (m_error_stream)
m_error_stream->Printf("Internal error [IRForTarget]: Result variable (%s) does not have a corresponding Clang entity\n", result_name);
-
+
return false;
}
-
+
if (log)
{
std::string decl_desc_str;
raw_string_ostream decl_desc_stream(decl_desc_str);
result_decl->print(decl_desc_stream);
decl_desc_stream.flush();
-
+
log->Printf("Found result decl: \"%s\"", decl_desc_str.c_str());
}
-
+
clang::VarDecl *result_var = dyn_cast<clang::VarDecl>(result_decl);
if (!result_var)
{
if (log)
log->PutCString("Result variable Decl isn't a VarDecl");
-
+
if (m_error_stream)
m_error_stream->Printf("Internal error [IRForTarget]: Result variable (%s)'s corresponding Clang entity isn't a variable\n", result_name);
-
+
return false;
}
-
+
// Get the next available result name from m_decl_map and create the persistent
// variable for it
-
+
// If the result is an Lvalue, it is emitted as a pointer; see
// ASTResultSynthesizer::SynthesizeBodyResult.
if (m_result_is_pointer)
{
clang::QualType pointer_qual_type = result_var->getType();
const clang::Type *pointer_type = pointer_qual_type.getTypePtr();
-
+
const clang::PointerType *pointer_pointertype = pointer_type->getAs<clang::PointerType>();
const clang::ObjCObjectPointerType *pointer_objcobjpointertype = pointer_type->getAs<clang::ObjCObjectPointerType>();
-
+
if (pointer_pointertype)
{
clang::QualType element_qual_type = pointer_pointertype->getPointeeType();
-
+
m_result_type = lldb_private::TypeFromParser(element_qual_type.getAsOpaquePtr(),
&result_decl->getASTContext());
}
else if (pointer_objcobjpointertype)
{
clang::QualType element_qual_type = clang::QualType(pointer_objcobjpointertype->getObjectType(), 0);
-
+
m_result_type = lldb_private::TypeFromParser(element_qual_type.getAsOpaquePtr(),
&result_decl->getASTContext());
}
@@ -566,10 +577,10 @@ IRForTarget::CreateResultVariable (llvm::Function &llvm_function)
{
if (log)
log->PutCString("Expected result to have pointer type, but it did not");
-
+
if (m_error_stream)
m_error_stream->Printf("Internal error [IRForTarget]: Lvalue result (%s) is not a pointer variable\n", result_name);
-
+
return false;
}
}
@@ -578,99 +589,99 @@ IRForTarget::CreateResultVariable (llvm::Function &llvm_function)
m_result_type = lldb_private::TypeFromParser(result_var->getType().getAsOpaquePtr(),
&result_decl->getASTContext());
}
-
+
if (m_result_type.GetBitSize() == 0)
{
lldb_private::StreamString type_desc_stream;
m_result_type.DumpTypeDescription(&type_desc_stream);
-
+
if (log)
log->Printf("Result type has size 0");
-
+
if (m_error_stream)
- m_error_stream->Printf("Error [IRForTarget]: Size of result type '%s' couldn't be determined\n",
+ m_error_stream->Printf("Error [IRForTarget]: Size of result type '%s' couldn't be determined\n",
type_desc_stream.GetData());
return false;
}
-
+
if (log)
{
lldb_private::StreamString type_desc_stream;
m_result_type.DumpTypeDescription(&type_desc_stream);
-
+
log->Printf("Result decl type: \"%s\"", type_desc_stream.GetData());
}
-
+
m_result_name = lldb_private::ConstString("$RESULT_NAME");
-
+
if (log)
log->Printf("Creating a new result global: \"%s\" with size 0x%" PRIx64,
m_result_name.GetCString(),
m_result_type.GetByteSize());
-
+
// Construct a new result global and set up its metadata
-
- GlobalVariable *new_result_global = new GlobalVariable((*m_module),
+
+ GlobalVariable *new_result_global = new GlobalVariable((*m_module),
result_global->getType()->getElementType(),
false, /* not constant */
GlobalValue::ExternalLinkage,
NULL, /* no initializer */
m_result_name.GetCString ());
-
+
// It's too late in compilation to create a new VarDecl for this, but we don't
// need to. We point the metadata at the old VarDecl. This creates an odd
// anomaly: a variable with a Value whose name is something like $0 and a
// Decl whose name is $__lldb_expr_result. This condition is handled in
// ClangExpressionDeclMap::DoMaterialize, and the name of the variable is
// fixed up.
-
+
ConstantInt *new_constant_int = ConstantInt::get(llvm::Type::getInt64Ty(m_module->getContext()),
reinterpret_cast<uint64_t>(result_decl),
false);
-
+
llvm::Value* values[2];
values[0] = new_result_global;
values[1] = new_constant_int;
-
+
ArrayRef<Value*> value_ref(values, 2);
-
+
MDNode *persistent_global_md = MDNode::get(m_module->getContext(), value_ref);
NamedMDNode *named_metadata = m_module->getNamedMetadata("clang.global.decl.ptrs");
named_metadata->addOperand(persistent_global_md);
-
+
if (log)
log->Printf("Replacing \"%s\" with \"%s\"",
PrintValue(result_global).c_str(),
PrintValue(new_result_global).c_str());
-
- if (result_global->hasNUses(0))
+
+ if (result_global->use_empty())
{
// We need to synthesize a store for this variable, because otherwise
// there's nothing to put into its equivalent persistent variable.
-
+
BasicBlock &entry_block(llvm_function.getEntryBlock());
Instruction *first_entry_instruction(entry_block.getFirstNonPHIOrDbg());
-
+
if (!first_entry_instruction)
return false;
-
+
if (!result_global->hasInitializer())
{
if (log)
log->Printf("Couldn't find initializer for unused variable");
-
+
if (m_error_stream)
m_error_stream->Printf("Internal error [IRForTarget]: Result variable (%s) has no writes and no initializer\n", result_name);
-
+
return false;
}
-
+
Constant *initializer = result_global->getInitializer();
-
+
StoreInst *synthesized_store = new StoreInst(initializer,
new_result_global,
first_entry_instruction);
-
+
if (log)
log->Printf("Synthesized result store \"%s\"\n", PrintValue(synthesized_store).c_str());
}
@@ -678,76 +689,51 @@ IRForTarget::CreateResultVariable (llvm::Function &llvm_function)
{
result_global->replaceAllUsesWith(new_result_global);
}
-
+
if (!m_decl_map->AddPersistentVariable(result_decl,
- m_result_name,
+ m_result_name,
m_result_type,
true,
m_result_is_pointer))
return false;
-
+
result_global->eraseFromParent();
-
- return true;
-}
-#if 0
-static void DebugUsers(Log *log, Value *value, uint8_t depth)
-{
- if (!depth)
- return;
-
- depth--;
-
- if (log)
- log->Printf(" <Begin %d users>", value->getNumUses());
-
- for (Value::use_iterator ui = value->use_begin(), ue = value->use_end();
- ui != ue;
- ++ui)
- {
- if (log)
- log->Printf(" <Use %p> %s", *ui, PrintValue(*ui).c_str());
- DebugUsers(log, *ui, depth);
- }
-
- if (log)
- log->Printf(" <End uses>");
+ return true;
}
-#endif
bool
IRForTarget::RewriteObjCConstString (llvm::GlobalVariable *ns_str,
llvm::GlobalVariable *cstr)
{
lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
+
Type *ns_str_ty = ns_str->getType();
-
+
Type *i8_ptr_ty = Type::getInt8PtrTy(m_module->getContext());
Type *i32_ty = Type::getInt32Ty(m_module->getContext());
Type *i8_ty = Type::getInt8Ty(m_module->getContext());
-
+
if (!m_CFStringCreateWithBytes)
{
lldb::addr_t CFStringCreateWithBytes_addr;
-
+
static lldb_private::ConstString g_CFStringCreateWithBytes_str ("CFStringCreateWithBytes");
-
+
if (!m_decl_map->GetFunctionAddress (g_CFStringCreateWithBytes_str, CFStringCreateWithBytes_addr))
{
if (log)
log->PutCString("Couldn't find CFStringCreateWithBytes in the target");
-
+
if (m_error_stream)
m_error_stream->Printf("Error [IRForTarget]: Rewriting an Objective-C constant string requires CFStringCreateWithBytes\n");
-
+
return false;
}
-
+
if (log)
log->Printf("Found CFStringCreateWithBytes at 0x%" PRIx64, CFStringCreateWithBytes_addr);
-
+
// Build the function type:
//
// CFStringRef CFStringCreateWithBytes (
@@ -766,66 +752,66 @@ IRForTarget::RewriteObjCConstString (llvm::GlobalVariable *ns_str,
// CFIndex -> long (i32 or i64, as appropriate; we ask the module for its pointer size for now)
// CFStringEncoding -> i32
// Boolean -> i8
-
+
Type *arg_type_array[5];
-
+
arg_type_array[0] = i8_ptr_ty;
arg_type_array[1] = i8_ptr_ty;
arg_type_array[2] = m_intptr_ty;
arg_type_array[3] = i32_ty;
arg_type_array[4] = i8_ty;
-
+
ArrayRef<Type *> CFSCWB_arg_types(arg_type_array, 5);
-
+
llvm::Type *CFSCWB_ty = FunctionType::get(ns_str_ty, CFSCWB_arg_types, false);
-
+
// Build the constant containing the pointer to the function
PointerType *CFSCWB_ptr_ty = PointerType::getUnqual(CFSCWB_ty);
Constant *CFSCWB_addr_int = ConstantInt::get(m_intptr_ty, CFStringCreateWithBytes_addr, false);
m_CFStringCreateWithBytes = ConstantExpr::getIntToPtr(CFSCWB_addr_int, CFSCWB_ptr_ty);
}
-
+
ConstantDataSequential *string_array = NULL;
-
+
if (cstr)
string_array = dyn_cast<ConstantDataSequential>(cstr->getInitializer());
-
+
Constant *alloc_arg = Constant::getNullValue(i8_ptr_ty);
Constant *bytes_arg = cstr ? ConstantExpr::getBitCast(cstr, i8_ptr_ty) : Constant::getNullValue(i8_ptr_ty);
Constant *numBytes_arg = ConstantInt::get(m_intptr_ty, cstr ? string_array->getNumElements() - 1 : 0, false);
Constant *encoding_arg = ConstantInt::get(i32_ty, 0x0600, false); /* 0x0600 is kCFStringEncodingASCII */
Constant *isExternal_arg = ConstantInt::get(i8_ty, 0x0, false); /* 0x0 is false */
-
+
Value *argument_array[5];
-
+
argument_array[0] = alloc_arg;
argument_array[1] = bytes_arg;
argument_array[2] = numBytes_arg;
argument_array[3] = encoding_arg;
argument_array[4] = isExternal_arg;
-
+
ArrayRef <Value *> CFSCWB_arguments(argument_array, 5);
-
+
FunctionValueCache CFSCWB_Caller ([this, &CFSCWB_arguments] (llvm::Function *function)->llvm::Value * {
return CallInst::Create(m_CFStringCreateWithBytes,
CFSCWB_arguments,
"CFStringCreateWithBytes",
llvm::cast<Instruction>(m_entry_instruction_finder.GetValue(function)));
});
-
+
if (!UnfoldConstant(ns_str, CFSCWB_Caller, m_entry_instruction_finder))
{
if (log)
log->PutCString("Couldn't replace the NSString with the result of the call");
-
+
if (m_error_stream)
m_error_stream->Printf("Error [IRForTarget]: Couldn't replace an Objective-C constant string with a dynamic string\n");
-
+
return false;
}
-
+
ns_str->eraseFromParent();
-
+
return true;
}
@@ -833,57 +819,57 @@ bool
IRForTarget::RewriteObjCConstStrings()
{
lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
+
ValueSymbolTable& value_symbol_table = m_module->getValueSymbolTable();
-
+
for (ValueSymbolTable::iterator vi = value_symbol_table.begin(), ve = value_symbol_table.end();
vi != ve;
++vi)
{
std::string value_name = vi->first().str();
const char *value_name_cstr = value_name.c_str();
-
+
if (strstr(value_name_cstr, "_unnamed_cfstring_"))
{
Value *nsstring_value = vi->second;
-
+
GlobalVariable *nsstring_global = dyn_cast<GlobalVariable>(nsstring_value);
-
+
if (!nsstring_global)
{
if (log)
log->PutCString("NSString variable is not a GlobalVariable");
-
+
if (m_error_stream)
m_error_stream->Printf("Internal error [IRForTarget]: An Objective-C constant string is not a global variable\n");
-
+
return false;
}
-
+
if (!nsstring_global->hasInitializer())
{
if (log)
log->PutCString("NSString variable does not have an initializer");
-
+
if (m_error_stream)
m_error_stream->Printf("Internal error [IRForTarget]: An Objective-C constant string does not have an initializer\n");
-
+
return false;
}
-
+
ConstantStruct *nsstring_struct = dyn_cast<ConstantStruct>(nsstring_global->getInitializer());
-
+
if (!nsstring_struct)
{
if (log)
log->PutCString("NSString variable's initializer is not a ConstantStruct");
-
+
if (m_error_stream)
m_error_stream->Printf("Internal error [IRForTarget]: An Objective-C constant string is not a structure constant\n");
-
+
return false;
}
-
+
// We expect the following structure:
//
// struct {
@@ -892,107 +878,107 @@ IRForTarget::RewriteObjCConstStrings()
// char *str;
// long length;
// };
-
+
if (nsstring_struct->getNumOperands() != 4)
{
if (log)
log->Printf("NSString variable's initializer structure has an unexpected number of members. Should be 4, is %d", nsstring_struct->getNumOperands());
-
+
if (m_error_stream)
m_error_stream->Printf("Internal error [IRForTarget]: The struct for an Objective-C constant string is not as expected\n");
-
+
return false;
}
-
+
Constant *nsstring_member = nsstring_struct->getOperand(2);
-
+
if (!nsstring_member)
{
if (log)
log->PutCString("NSString initializer's str element was empty");
-
+
if (m_error_stream)
m_error_stream->Printf("Internal error [IRForTarget]: An Objective-C constant string does not have a string initializer\n");
-
+
return false;
}
-
+
ConstantExpr *nsstring_expr = dyn_cast<ConstantExpr>(nsstring_member);
-
+
if (!nsstring_expr)
{
if (log)
log->PutCString("NSString initializer's str element is not a ConstantExpr");
-
+
if (m_error_stream)
m_error_stream->Printf("Internal error [IRForTarget]: An Objective-C constant string's string initializer is not constant\n");
-
+
return false;
}
-
+
if (nsstring_expr->getOpcode() != Instruction::GetElementPtr)
{
if (log)
log->Printf("NSString initializer's str element is not a GetElementPtr expression, it's a %s", nsstring_expr->getOpcodeName());
-
+
if (m_error_stream)
m_error_stream->Printf("Internal error [IRForTarget]: An Objective-C constant string's string initializer is not an array\n");
-
+
return false;
}
-
+
Constant *nsstring_cstr = nsstring_expr->getOperand(0);
-
+
GlobalVariable *cstr_global = dyn_cast<GlobalVariable>(nsstring_cstr);
-
+
if (!cstr_global)
{
if (log)
log->PutCString("NSString initializer's str element is not a GlobalVariable");
-
+
if (m_error_stream)
m_error_stream->Printf("Internal error [IRForTarget]: An Objective-C constant string's string initializer doesn't point to a global\n");
-
+
return false;
}
-
+
if (!cstr_global->hasInitializer())
{
if (log)
log->PutCString("NSString initializer's str element does not have an initializer");
-
+
if (m_error_stream)
m_error_stream->Printf("Internal error [IRForTarget]: An Objective-C constant string's string initializer doesn't point to initialized data\n");
-
+
return false;
}
-
+
/*
if (!cstr_array)
{
if (log)
log->PutCString("NSString initializer's str element is not a ConstantArray");
-
+
if (m_error_stream)
m_error_stream->Printf("Internal error [IRForTarget]: An Objective-C constant string's string initializer doesn't point to an array\n");
-
+
return false;
}
-
+
if (!cstr_array->isCString())
{
if (log)
log->PutCString("NSString initializer's str element is not a C string array");
-
+
if (m_error_stream)
m_error_stream->Printf("Internal error [IRForTarget]: An Objective-C constant string's string initializer doesn't point to a C string\n");
-
+
return false;
}
*/
-
+
ConstantDataArray *cstr_array = dyn_cast<ConstantDataArray>(cstr_global->getInitializer());
-
+
if (log)
{
if (cstr_array)
@@ -1000,175 +986,175 @@ IRForTarget::RewriteObjCConstStrings()
else
log->Printf("Found NSString constant %s, which contains \"\"", value_name_cstr);
}
-
+
if (!cstr_array)
cstr_global = NULL;
-
+
if (!RewriteObjCConstString(nsstring_global, cstr_global))
- {
+ {
if (log)
log->PutCString("Error rewriting the constant string");
-
+
// We don't print an error message here because RewriteObjCConstString has done so for us.
-
+
return false;
}
}
}
-
+
for (ValueSymbolTable::iterator vi = value_symbol_table.begin(), ve = value_symbol_table.end();
vi != ve;
++vi)
{
std::string value_name = vi->first().str();
const char *value_name_cstr = value_name.c_str();
-
+
if (!strcmp(value_name_cstr, "__CFConstantStringClassReference"))
{
GlobalVariable *gv = dyn_cast<GlobalVariable>(vi->second);
-
+
if (!gv)
{
if (log)
log->PutCString("__CFConstantStringClassReference is not a global variable");
-
+
if (m_error_stream)
m_error_stream->Printf("Internal error [IRForTarget]: Found a CFConstantStringClassReference, but it is not a global object\n");
-
+
return false;
}
-
+
gv->eraseFromParent();
-
+
break;
}
}
-
+
return true;
}
static bool IsObjCSelectorRef (Value *value)
{
GlobalVariable *global_variable = dyn_cast<GlobalVariable>(value);
-
+
if (!global_variable || !global_variable->hasName() || !global_variable->getName().startswith("\01L_OBJC_SELECTOR_REFERENCES_"))
return false;
-
+
return true;
}
// This function does not report errors; its callers are responsible.
-bool
+bool
IRForTarget::RewriteObjCSelector (Instruction* selector_load)
{
lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
LoadInst *load = dyn_cast<LoadInst>(selector_load);
-
+
if (!load)
return false;
-
+
// Unpack the message name from the selector. In LLVM IR, an objc_msgSend gets represented as
//
// %tmp = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_" ; <i8*>
// %call = call i8* (i8*, i8*, ...)* @objc_msgSend(i8* %obj, i8* %tmp, ...) ; <i8*>
//
// where %obj is the object pointer and %tmp is the selector.
- //
+ //
// @"\01L_OBJC_SELECTOR_REFERENCES_" is a pointer to a character array called @"\01L_OBJC_llvm_moduleETH_VAR_NAllvm_moduleE_".
// @"\01L_OBJC_llvm_moduleETH_VAR_NAllvm_moduleE_" contains the string.
-
+
// Find the pointer's initializer (a ConstantExpr with opcode GetElementPtr) and get the string from its target
-
+
GlobalVariable *_objc_selector_references_ = dyn_cast<GlobalVariable>(load->getPointerOperand());
-
+
if (!_objc_selector_references_ || !_objc_selector_references_->hasInitializer())
return false;
-
+
Constant *osr_initializer = _objc_selector_references_->getInitializer();
-
+
ConstantExpr *osr_initializer_expr = dyn_cast<ConstantExpr>(osr_initializer);
-
+
if (!osr_initializer_expr || osr_initializer_expr->getOpcode() != Instruction::GetElementPtr)
return false;
-
+
Value *osr_initializer_base = osr_initializer_expr->getOperand(0);
if (!osr_initializer_base)
return false;
-
+
// Find the string's initializer (a ConstantArray) and get the string from it
-
+
GlobalVariable *_objc_meth_var_name_ = dyn_cast<GlobalVariable>(osr_initializer_base);
-
+
if (!_objc_meth_var_name_ || !_objc_meth_var_name_->hasInitializer())
return false;
-
+
Constant *omvn_initializer = _objc_meth_var_name_->getInitializer();
ConstantDataArray *omvn_initializer_array = dyn_cast<ConstantDataArray>(omvn_initializer);
-
+
if (!omvn_initializer_array->isString())
return false;
-
+
std::string omvn_initializer_string = omvn_initializer_array->getAsString();
-
+
if (log)
log->Printf("Found Objective-C selector reference \"%s\"", omvn_initializer_string.c_str());
-
+
// Construct a call to sel_registerName
-
+
if (!m_sel_registerName)
{
lldb::addr_t sel_registerName_addr;
-
+
static lldb_private::ConstString g_sel_registerName_str ("sel_registerName");
if (!m_decl_map->GetFunctionAddress (g_sel_registerName_str, sel_registerName_addr))
return false;
-
+
if (log)
log->Printf("Found sel_registerName at 0x%" PRIx64, sel_registerName_addr);
-
+
// Build the function type: struct objc_selector *sel_registerName(uint8_t*)
-
+
// The below code would be "more correct," but in actuality what's required is uint8_t*
//Type *sel_type = StructType::get(m_module->getContext());
//Type *sel_ptr_type = PointerType::getUnqual(sel_type);
Type *sel_ptr_type = Type::getInt8PtrTy(m_module->getContext());
-
+
Type *type_array[1];
-
+
type_array[0] = llvm::Type::getInt8PtrTy(m_module->getContext());
-
+
ArrayRef<Type *> srN_arg_types(type_array, 1);
-
+
llvm::Type *srN_type = FunctionType::get(sel_ptr_type, srN_arg_types, false);
-
+
// Build the constant containing the pointer to the function
PointerType *srN_ptr_ty = PointerType::getUnqual(srN_type);
Constant *srN_addr_int = ConstantInt::get(m_intptr_ty, sel_registerName_addr, false);
m_sel_registerName = ConstantExpr::getIntToPtr(srN_addr_int, srN_ptr_ty);
}
-
+
Value *argument_array[1];
-
+
Constant *omvn_pointer = ConstantExpr::getBitCast(_objc_meth_var_name_, Type::getInt8PtrTy(m_module->getContext()));
-
+
argument_array[0] = omvn_pointer;
-
+
ArrayRef<Value *> srN_arguments(argument_array, 1);
-
- CallInst *srN_call = CallInst::Create(m_sel_registerName,
+
+ CallInst *srN_call = CallInst::Create(m_sel_registerName,
srN_arguments,
"sel_registerName",
selector_load);
-
+
// Replace the load with the call in all users
-
+
selector_load->replaceAllUsesWith(srN_call);
-
+
selector_load->eraseFromParent();
-
+
return true;
}
@@ -1178,25 +1164,25 @@ IRForTarget::RewriteObjCSelectors (BasicBlock &basic_block)
lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
BasicBlock::iterator ii;
-
+
typedef SmallVector <Instruction*, 2> InstrList;
typedef InstrList::iterator InstrIterator;
-
+
InstrList selector_loads;
-
+
for (ii = basic_block.begin();
ii != basic_block.end();
++ii)
{
Instruction &inst = *ii;
-
+
if (LoadInst *load = dyn_cast<LoadInst>(&inst))
if (IsObjCSelectorRef(load->getPointerOperand()))
selector_loads.push_back(&inst);
}
-
+
InstrIterator iter;
-
+
for (iter = selector_loads.begin();
iter != selector_loads.end();
++iter)
@@ -1205,111 +1191,111 @@ IRForTarget::RewriteObjCSelectors (BasicBlock &basic_block)
{
if (m_error_stream)
m_error_stream->Printf("Internal error [IRForTarget]: Couldn't change a static reference to an Objective-C selector to a dynamic reference\n");
-
+
if (log)
log->PutCString("Couldn't rewrite a reference to an Objective-C selector");
-
+
return false;
}
}
-
+
return true;
}
// This function does not report errors; its callers are responsible.
-bool
+bool
IRForTarget::RewritePersistentAlloc (llvm::Instruction *persistent_alloc)
{
lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
AllocaInst *alloc = dyn_cast<AllocaInst>(persistent_alloc);
-
+
MDNode *alloc_md = alloc->getMetadata("clang.decl.ptr");
if (!alloc_md || !alloc_md->getNumOperands())
return false;
-
+
ConstantInt *constant_int = dyn_cast<ConstantInt>(alloc_md->getOperand(0));
-
+
if (!constant_int)
return false;
-
+
// We attempt to register this as a new persistent variable with the DeclMap.
-
+
uintptr_t ptr = constant_int->getZExtValue();
-
+
clang::VarDecl *decl = reinterpret_cast<clang::VarDecl *>(ptr);
-
+
lldb_private::TypeFromParser result_decl_type (decl->getType().getAsOpaquePtr(),
&decl->getASTContext());
-
+
StringRef decl_name (decl->getName());
lldb_private::ConstString persistent_variable_name (decl_name.data(), decl_name.size());
if (!m_decl_map->AddPersistentVariable(decl, persistent_variable_name, result_decl_type, false, false))
return false;
-
+
GlobalVariable *persistent_global = new GlobalVariable((*m_module),
alloc->getType(),
false, /* not constant */
GlobalValue::ExternalLinkage,
NULL, /* no initializer */
alloc->getName().str().c_str());
-
+
// What we're going to do here is make believe this was a regular old external
// variable. That means we need to make the metadata valid.
-
+
NamedMDNode *named_metadata = m_module->getOrInsertNamedMetadata("clang.global.decl.ptrs");
-
+
llvm::Value* values[2];
values[0] = persistent_global;
values[1] = constant_int;
-
+
ArrayRef<llvm::Value*> value_ref(values, 2);
MDNode *persistent_global_md = MDNode::get(m_module->getContext(), value_ref);
named_metadata->addOperand(persistent_global_md);
-
+
// Now, since the variable is a pointer variable, we will drop in a load of that
// pointer variable.
-
+
LoadInst *persistent_load = new LoadInst (persistent_global, "", alloc);
-
+
if (log)
log->Printf("Replacing \"%s\" with \"%s\"",
PrintValue(alloc).c_str(),
PrintValue(persistent_load).c_str());
-
+
alloc->replaceAllUsesWith(persistent_load);
alloc->eraseFromParent();
-
+
return true;
}
-bool
+bool
IRForTarget::RewritePersistentAllocs(llvm::BasicBlock &basic_block)
{
if (!m_resolve_vars)
return true;
-
+
lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
+
BasicBlock::iterator ii;
-
+
typedef SmallVector <Instruction*, 2> InstrList;
typedef InstrList::iterator InstrIterator;
-
+
InstrList pvar_allocs;
-
+
for (ii = basic_block.begin();
ii != basic_block.end();
++ii)
{
Instruction &inst = *ii;
-
+
if (AllocaInst *alloc = dyn_cast<AllocaInst>(&inst))
{
llvm::StringRef alloc_name = alloc->getName();
-
+
if (alloc_name.startswith("$") &&
!alloc_name.startswith("$__lldb"))
{
@@ -1317,20 +1303,20 @@ IRForTarget::RewritePersistentAllocs(llvm::BasicBlock &basic_block)
{
if (log)
log->Printf("Rejecting a numeric persistent variable.");
-
+
if (m_error_stream)
m_error_stream->Printf("Error [IRForTarget]: Names starting with $0, $1, ... are reserved for use as result names\n");
-
+
return false;
}
-
+
pvar_allocs.push_back(alloc);
}
}
}
-
+
InstrIterator iter;
-
+
for (iter = pvar_allocs.begin();
iter != pvar_allocs.end();
++iter)
@@ -1339,14 +1325,14 @@ IRForTarget::RewritePersistentAllocs(llvm::BasicBlock &basic_block)
{
if (m_error_stream)
m_error_stream->Printf("Internal error [IRForTarget]: Couldn't rewrite the creation of a persistent variable\n");
-
+
if (log)
log->PutCString("Couldn't rewrite the creation of a persistent variable");
-
+
return false;
}
}
-
+
return true;
}
@@ -1355,14 +1341,14 @@ IRForTarget::MaterializeInitializer (uint8_t *data, Constant *initializer)
{
if (!initializer)
return true;
-
+
lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
if (log && log->GetVerbose())
log->Printf(" MaterializeInitializer(%p, %s)", data, PrintValue(initializer).c_str());
-
+
Type *initializer_type = initializer->getType();
-
+
if (ConstantInt *int_initializer = dyn_cast<ConstantInt>(initializer))
{
memcpy (data, int_initializer->getValue().getRawData(), m_target_data->getTypeStoreSize(initializer_type));
@@ -1379,17 +1365,17 @@ IRForTarget::MaterializeInitializer (uint8_t *data, Constant *initializer)
{
ArrayType *array_initializer_type = array_initializer->getType();
Type *array_element_type = array_initializer_type->getElementType();
-
+
size_t element_size = m_target_data->getTypeAllocSize(array_element_type);
-
+
for (unsigned i = 0; i < array_initializer->getNumOperands(); ++i)
{
Value *operand_value = array_initializer->getOperand(i);
Constant *operand_constant = dyn_cast<Constant>(operand_value);
-
+
if (!operand_constant)
return false;
-
+
if (!MaterializeInitializer(data + (i * element_size), operand_constant))
return false;
}
@@ -1423,52 +1409,52 @@ IRForTarget::MaterializeInternalVariable (GlobalVariable *global_variable)
{
if (GlobalVariable::isExternalLinkage(global_variable->getLinkage()))
return false;
-
+
if (global_variable == m_reloc_placeholder)
return true;
-
+
uint64_t offset = m_data_allocator.GetStream().GetSize();
-
+
llvm::Type *variable_type = global_variable->getType();
-
+
Constant *initializer = global_variable->getInitializer();
-
+
llvm::Type *initializer_type = initializer->getType();
-
+
size_t size = m_target_data->getTypeAllocSize(initializer_type);
size_t align = m_target_data->getPrefTypeAlignment(initializer_type);
-
+
const size_t mask = (align - 1);
uint64_t aligned_offset = (offset + mask) & ~mask;
m_data_allocator.GetStream().PutNHex8(aligned_offset - offset, 0);
offset = aligned_offset;
-
+
lldb_private::DataBufferHeap data(size, '\0');
-
+
if (initializer)
if (!MaterializeInitializer(data.GetBytes(), initializer))
return false;
-
+
m_data_allocator.GetStream().Write(data.GetBytes(), data.GetByteSize());
-
+
Constant *new_pointer = BuildRelocation(variable_type, offset);
-
+
global_variable->replaceAllUsesWith(new_pointer);
global_variable->eraseFromParent();
-
+
return true;
}
// This function does not report errors; its callers are responsible.
-bool
+bool
IRForTarget::MaybeHandleVariable (Value *llvm_value_ptr)
{
lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
+
if (log)
log->Printf("MaybeHandleVariable (%s)", PrintValue(llvm_value_ptr).c_str());
-
+
if (ConstantExpr *constant_expr = dyn_cast<ConstantExpr>(llvm_value_ptr))
{
switch (constant_expr->getOpcode())
@@ -1486,31 +1472,31 @@ IRForTarget::MaybeHandleVariable (Value *llvm_value_ptr)
{
if (!GlobalValue::isExternalLinkage(global_variable->getLinkage()))
return MaterializeInternalVariable(global_variable);
-
+
clang::NamedDecl *named_decl = DeclForGlobal(global_variable);
-
+
if (!named_decl)
{
if (IsObjCSelectorRef(llvm_value_ptr))
return true;
-
+
if (!global_variable->hasExternalLinkage())
return true;
-
+
if (log)
log->Printf("Found global variable \"%s\" without metadata", global_variable->getName().str().c_str());
-
+
return false;
}
-
+
std::string name (named_decl->getName().str());
-
+
clang::ValueDecl *value_decl = dyn_cast<clang::ValueDecl>(named_decl);
if (value_decl == NULL)
return false;
lldb_private::ClangASTType clang_type(&value_decl->getASTContext(), value_decl->getType());
-
+
const Type *value_type = NULL;
if (name[0] == '$')
@@ -1531,25 +1517,25 @@ IRForTarget::MaybeHandleVariable (Value *llvm_value_ptr)
{
value_type = global_variable->getType();
}
-
+
const uint64_t value_size = clang_type.GetByteSize();
- off_t value_alignment = (clang_type.GetTypeBitAlign() + 7ull) / 8ull;
-
+ lldb::offset_t value_alignment = (clang_type.GetTypeBitAlign() + 7ull) / 8ull;
+
if (log)
{
- log->Printf("Type of \"%s\" is [clang \"%s\", llvm \"%s\"] [size %" PRIu64 ", align %" PRId64 "]",
- name.c_str(),
+ log->Printf("Type of \"%s\" is [clang \"%s\", llvm \"%s\"] [size %" PRIu64 ", align %" PRIu64 "]",
+ name.c_str(),
clang_type.GetQualType().getAsString().c_str(),
PrintType(value_type).c_str(),
- value_size,
+ value_size,
value_alignment);
}
-
-
+
+
if (named_decl && !m_decl_map->AddValueToStruct(named_decl,
lldb_private::ConstString (name.c_str()),
llvm_value_ptr,
- value_size,
+ value_size,
value_alignment))
{
if (!global_variable->hasExternalLinkage())
@@ -1564,45 +1550,45 @@ IRForTarget::MaybeHandleVariable (Value *llvm_value_ptr)
{
if (log)
log->Printf("Function pointers aren't handled right now");
-
+
return false;
}
-
+
return true;
}
// This function does not report errors; its callers are responsible.
bool
IRForTarget::HandleSymbol (Value *symbol)
-{
+{
lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
+
lldb_private::ConstString name(symbol->getName().str().c_str());
-
+
lldb::addr_t symbol_addr = m_decl_map->GetSymbolAddress (name, lldb::eSymbolTypeAny);
-
+
if (symbol_addr == LLDB_INVALID_ADDRESS)
{
if (log)
log->Printf ("Symbol \"%s\" had no address", name.GetCString());
-
+
return false;
}
if (log)
log->Printf("Found \"%s\" at 0x%" PRIx64, name.GetCString(), symbol_addr);
-
+
Type *symbol_type = symbol->getType();
-
+
Constant *symbol_addr_int = ConstantInt::get(m_intptr_ty, symbol_addr, false);
-
+
Value *symbol_addr_ptr = ConstantExpr::getIntToPtr(symbol_addr_int, symbol_type);
-
+
if (log)
log->Printf("Replacing %s with %s", PrintValue(symbol).c_str(), PrintValue(symbol_addr_ptr).c_str());
-
+
symbol->replaceAllUsesWith(symbol_addr_ptr);
-
+
return true;
}
@@ -1610,10 +1596,10 @@ bool
IRForTarget::MaybeHandleCallArguments (CallInst *Old)
{
lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
+
if (log)
log->Printf("MaybeHandleCallArguments(%s)", PrintValue(Old).c_str());
-
+
for (unsigned op_index = 0, num_ops = Old->getNumArgOperands();
op_index < num_ops;
++op_index)
@@ -1621,10 +1607,10 @@ IRForTarget::MaybeHandleCallArguments (CallInst *Old)
{
if (m_error_stream)
m_error_stream->Printf("Internal error [IRForTarget]: Couldn't rewrite one of the arguments of a function call.\n");
-
+
return false;
}
-
+
return true;
}
@@ -1634,55 +1620,53 @@ IRForTarget::HandleObjCClass(Value *classlist_reference)
lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
GlobalVariable *global_variable = dyn_cast<GlobalVariable>(classlist_reference);
-
+
if (!global_variable)
return false;
-
+
Constant *initializer = global_variable->getInitializer();
-
+
if (!initializer)
return false;
-
+
if (!initializer->hasName())
return false;
-
+
StringRef name(initializer->getName());
lldb_private::ConstString name_cstr(name.str().c_str());
lldb::addr_t class_ptr = m_decl_map->GetSymbolAddress(name_cstr, lldb::eSymbolTypeObjCClass);
-
+
if (log)
log->Printf("Found reference to Objective-C class %s (0x%llx)", name_cstr.AsCString(), (unsigned long long)class_ptr);
-
+
if (class_ptr == LLDB_INVALID_ADDRESS)
return false;
-
- if (global_variable->use_begin() == global_variable->use_end())
+
+ if (global_variable->use_empty())
return false;
-
+
SmallVector<LoadInst *, 2> load_instructions;
-
- for (Value::use_iterator i = global_variable->use_begin(), e = global_variable->use_end();
- i != e;
- ++i)
+
+ for (llvm::User *u : global_variable->users())
{
- if (LoadInst *load_instruction = dyn_cast<LoadInst>(*i))
+ if (LoadInst *load_instruction = dyn_cast<LoadInst>(u))
load_instructions.push_back(load_instruction);
}
-
+
if (load_instructions.empty())
return false;
-
+
Constant *class_addr = ConstantInt::get(m_intptr_ty, (uint64_t)class_ptr);
-
+
for (LoadInst *load_instruction : load_instructions)
{
Constant *class_bitcast = ConstantExpr::getIntToPtr(class_addr, load_instruction->getType());
-
+
load_instruction->replaceAllUsesWith(class_bitcast);
-
+
load_instruction->eraseFromParent();
}
-
+
return true;
}
@@ -1690,54 +1674,54 @@ bool
IRForTarget::RemoveCXAAtExit (BasicBlock &basic_block)
{
BasicBlock::iterator ii;
-
+
std::vector<CallInst *> calls_to_remove;
-
+
for (ii = basic_block.begin();
ii != basic_block.end();
++ii)
{
Instruction &inst = *ii;
-
+
CallInst *call = dyn_cast<CallInst>(&inst);
-
+
// MaybeHandleCallArguments handles error reporting; we are silent here
if (!call)
continue;
-
+
bool remove = false;
-
+
llvm::Function *func = call->getCalledFunction();
-
+
if (func && func->getName() == "__cxa_atexit")
remove = true;
-
+
llvm::Value *val = call->getCalledValue();
-
+
if (val && val->getName() == "__cxa_atexit")
remove = true;
-
+
if (remove)
calls_to_remove.push_back(call);
}
-
+
for (std::vector<CallInst *>::iterator ci = calls_to_remove.begin(), ce = calls_to_remove.end();
ci != ce;
++ci)
{
(*ci)->eraseFromParent();
}
-
+
return true;
}
bool
IRForTarget::ResolveCalls(BasicBlock &basic_block)
-{
+{
/////////////////////////////////////////////////////////////////////////
// Prepare the current basic block for execution in the remote process
//
-
+
BasicBlock::iterator ii;
for (ii = basic_block.begin();
@@ -1745,14 +1729,14 @@ IRForTarget::ResolveCalls(BasicBlock &basic_block)
++ii)
{
Instruction &inst = *ii;
-
+
CallInst *call = dyn_cast<CallInst>(&inst);
-
+
// MaybeHandleCallArguments handles error reporting; we are silent here
if (call && !MaybeHandleCallArguments(call))
return false;
}
-
+
return true;
}
@@ -1760,68 +1744,58 @@ bool
IRForTarget::ResolveExternals (Function &llvm_function)
{
lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
- for (Module::global_iterator global = m_module->global_begin(), end = m_module->global_end();
- global != end;
- ++global)
+
+ for (GlobalVariable &global_var : m_module->globals())
{
- if (!global)
- {
- if (m_error_stream)
- m_error_stream->Printf("Internal error [IRForTarget]: global variable is NULL");
-
- return false;
- }
-
- std::string global_name = (*global).getName().str();
-
+ std::string global_name = global_var.getName().str();
+
if (log)
- log->Printf("Examining %s, DeclForGlobalValue returns %p",
+ log->Printf("Examining %s, DeclForGlobalValue returns %p",
global_name.c_str(),
- DeclForGlobal(global));
-
+ static_cast<void*>(DeclForGlobal(&global_var)));
+
if (global_name.find("OBJC_IVAR") == 0)
{
- if (!HandleSymbol(global))
+ if (!HandleSymbol(&global_var))
{
if (m_error_stream)
m_error_stream->Printf("Error [IRForTarget]: Couldn't find Objective-C indirect ivar symbol %s\n", global_name.c_str());
-
+
return false;
}
}
else if (global_name.find("OBJC_CLASSLIST_REFERENCES_$") != global_name.npos)
{
- if (!HandleObjCClass(global))
+ if (!HandleObjCClass(&global_var))
{
if (m_error_stream)
m_error_stream->Printf("Error [IRForTarget]: Couldn't resolve the class for an Objective-C static method call\n");
-
+
return false;
}
}
else if (global_name.find("OBJC_CLASSLIST_SUP_REFS_$") != global_name.npos)
{
- if (!HandleObjCClass(global))
+ if (!HandleObjCClass(&global_var))
{
if (m_error_stream)
m_error_stream->Printf("Error [IRForTarget]: Couldn't resolve the class for an Objective-C static method call\n");
-
+
return false;
}
}
- else if (DeclForGlobal(global))
+ else if (DeclForGlobal(&global_var))
{
- if (!MaybeHandleVariable (global))
+ if (!MaybeHandleVariable (&global_var))
{
if (m_error_stream)
m_error_stream->Printf("Internal error [IRForTarget]: Couldn't rewrite external variable %s\n", global_name.c_str());
-
+
return false;
}
}
}
-
+
return true;
}
@@ -1829,40 +1803,36 @@ bool
IRForTarget::ReplaceStrings ()
{
lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
+
typedef std::map <GlobalVariable *, size_t> OffsetsTy;
-
+
OffsetsTy offsets;
-
- for (Module::global_iterator gi = m_module->global_begin(), ge = m_module->global_end();
- gi != ge;
- ++gi)
- {
- GlobalVariable *gv = gi;
-
- if (!gv->hasInitializer())
+
+ for (GlobalVariable &gv : m_module->globals())
+ {
+ if (!gv.hasInitializer())
continue;
-
- Constant *gc = gv->getInitializer();
-
+
+ Constant *gc = gv.getInitializer();
+
std::string str;
-
+
if (gc->isNullValue())
{
Type *gc_type = gc->getType();
-
+
ArrayType *gc_array_type = dyn_cast<ArrayType>(gc_type);
-
+
if (!gc_array_type)
continue;
-
+
Type *gc_element_type = gc_array_type->getElementType();
-
+
IntegerType *gc_integer_type = dyn_cast<IntegerType>(gc_element_type);
-
+
if (gc_integer_type->getBitWidth() != 8)
continue;
-
+
str = "";
}
else
@@ -1871,108 +1841,102 @@ IRForTarget::ReplaceStrings ()
if (!gc_array)
continue;
-
+
if (!gc_array->isCString())
continue;
-
+
if (log)
log->Printf("Found a GlobalVariable with string initializer %s", PrintValue(gc).c_str());
-
+
str = gc_array->getAsString();
}
-
- offsets[gv] = m_data_allocator.GetStream().GetSize();
-
+
+ offsets[&gv] = m_data_allocator.GetStream().GetSize();
+
m_data_allocator.GetStream().Write(str.c_str(), str.length() + 1);
}
-
+
Type *char_ptr_ty = Type::getInt8PtrTy(m_module->getContext());
-
+
for (OffsetsTy::iterator oi = offsets.begin(), oe = offsets.end();
oi != oe;
++oi)
{
GlobalVariable *gv = oi->first;
size_t offset = oi->second;
-
+
Constant *new_initializer = BuildRelocation(char_ptr_ty, offset);
-
+
if (log)
log->Printf("Replacing GV %s with %s", PrintValue(gv).c_str(), PrintValue(new_initializer).c_str());
-
- for (GlobalVariable::use_iterator ui = gv->use_begin(), ue = gv->use_end();
- ui != ue;
- ++ui)
+
+ for (llvm::User *u : gv->users())
{
if (log)
- log->Printf("Found use %s", PrintValue(*ui).c_str());
-
- ConstantExpr *const_expr = dyn_cast<ConstantExpr>(*ui);
- StoreInst *store_inst = dyn_cast<StoreInst>(*ui);
-
+ log->Printf("Found use %s", PrintValue(u).c_str());
+
+ ConstantExpr *const_expr = dyn_cast<ConstantExpr>(u);
+ StoreInst *store_inst = dyn_cast<StoreInst>(u);
+
if (const_expr)
{
if (const_expr->getOpcode() != Instruction::GetElementPtr)
{
if (log)
log->Printf("Use (%s) of string variable is not a GetElementPtr constant", PrintValue(const_expr).c_str());
-
+
return false;
}
-
+
Constant *bit_cast = ConstantExpr::getBitCast(new_initializer, const_expr->getOperand(0)->getType());
Constant *new_gep = const_expr->getWithOperandReplaced(0, bit_cast);
-
+
const_expr->replaceAllUsesWith(new_gep);
}
else if (store_inst)
{
Constant *bit_cast = ConstantExpr::getBitCast(new_initializer, store_inst->getValueOperand()->getType());
-
+
store_inst->setOperand(0, bit_cast);
}
else
{
if (log)
log->Printf("Use (%s) of string variable is neither a constant nor a store", PrintValue(const_expr).c_str());
-
+
return false;
}
}
-
+
gv->eraseFromParent();
}
-
+
return true;
}
-bool
+bool
IRForTarget::ReplaceStaticLiterals (llvm::BasicBlock &basic_block)
{
lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
+
typedef SmallVector <Value*, 2> ConstantList;
typedef SmallVector <llvm::Instruction*, 2> UserList;
typedef ConstantList::iterator ConstantIterator;
typedef UserList::iterator UserIterator;
-
+
ConstantList static_constants;
UserList static_users;
-
+
for (BasicBlock::iterator ii = basic_block.begin(), ie = basic_block.end();
ii != ie;
++ii)
{
llvm::Instruction &inst = *ii;
-
- for (Instruction::op_iterator oi = inst.op_begin(), oe = inst.op_end();
- oi != oe;
- ++oi)
+
+ for (Value *operand_val : inst.operand_values())
{
- Value *operand_val = oi->get();
-
ConstantFP *operand_constant_fp = dyn_cast<ConstantFP>(operand_val);
-
+
if (operand_constant_fp/* && operand_constant_fp->getType()->isX86_FP80Ty()*/)
{
static_constants.push_back(operand_val);
@@ -1980,10 +1944,10 @@ IRForTarget::ReplaceStaticLiterals (llvm::BasicBlock &basic_block)
}
}
}
-
+
ConstantIterator constant_iter;
UserIterator user_iter;
-
+
for (constant_iter = static_constants.begin(), user_iter = static_users.begin();
constant_iter != static_constants.end();
++constant_iter, ++user_iter)
@@ -1992,17 +1956,17 @@ IRForTarget::ReplaceStaticLiterals (llvm::BasicBlock &basic_block)
llvm::Instruction *inst = *user_iter;
ConstantFP *operand_constant_fp = dyn_cast<ConstantFP>(operand_val);
-
+
if (operand_constant_fp)
{
Type *operand_type = operand_constant_fp->getType();
APFloat operand_apfloat = operand_constant_fp->getValueAPF();
APInt operand_apint = operand_apfloat.bitcastToAPInt();
-
+
const uint8_t* operand_raw_data = (const uint8_t*)operand_apint.getRawData();
size_t operand_data_size = operand_apint.getBitWidth() / 8;
-
+
if (log)
{
std::string s;
@@ -2015,16 +1979,16 @@ IRForTarget::ReplaceStaticLiterals (llvm::BasicBlock &basic_block)
ss << " ";
}
ss.flush();
-
- log->Printf("Found ConstantFP with size %zu and raw data %s", operand_data_size, s.c_str());
+
+ log->Printf("Found ConstantFP with size %" PRIu64 " and raw data %s", (uint64_t)operand_data_size, s.c_str());
}
-
+
lldb_private::DataBufferHeap data(operand_data_size, 0);
-
+
if (lldb::endian::InlHostByteOrder() != m_data_allocator.GetStream().GetByteOrder())
{
uint8_t *data_bytes = data.GetBytes();
-
+
for (size_t index = 0;
index < operand_data_size;
++index)
@@ -2036,77 +2000,72 @@ IRForTarget::ReplaceStaticLiterals (llvm::BasicBlock &basic_block)
{
memcpy(data.GetBytes(), operand_raw_data, operand_data_size);
}
-
+
uint64_t offset = m_data_allocator.GetStream().GetSize();
-
+
size_t align = m_target_data->getPrefTypeAlignment(operand_type);
-
+
const size_t mask = (align - 1);
uint64_t aligned_offset = (offset + mask) & ~mask;
m_data_allocator.GetStream().PutNHex8(aligned_offset - offset, 0);
- offset = aligned_offset;
-
+
m_data_allocator.GetStream().Write(data.GetBytes(), operand_data_size);
-
+
llvm::Type *fp_ptr_ty = operand_constant_fp->getType()->getPointerTo();
-
+
Constant *new_pointer = BuildRelocation(fp_ptr_ty, aligned_offset);
-
+
llvm::LoadInst *fp_load = new llvm::LoadInst(new_pointer, "fp_load", inst);
-
+
operand_constant_fp->replaceAllUsesWith(fp_load);
}
}
-
+
return true;
}
static bool isGuardVariableRef(Value *V)
{
Constant *Old = NULL;
-
+
if (!(Old = dyn_cast<Constant>(V)))
return false;
-
+
ConstantExpr *CE = NULL;
-
+
if ((CE = dyn_cast<ConstantExpr>(V)))
{
if (CE->getOpcode() != Instruction::BitCast)
return false;
-
+
Old = CE->getOperand(0);
}
-
+
GlobalVariable *GV = dyn_cast<GlobalVariable>(Old);
-
+
if (!GV || !GV->hasName() || !GV->getName().startswith("_ZGV"))
return false;
-
+
return true;
}
-void
+void
IRForTarget::TurnGuardLoadIntoZero(llvm::Instruction* guard_load)
{
Constant* zero(ConstantInt::get(Type::getInt8Ty(m_module->getContext()), 0, true));
- Value::use_iterator ui;
-
- for (ui = guard_load->use_begin();
- ui != guard_load->use_end();
- ++ui)
+ for (llvm::User *u : guard_load->users())
{
- if (isa<Constant>(*ui))
+ if (isa<Constant>(u))
{
// do nothing for the moment
}
else
{
- ui->replaceUsesOfWith(guard_load, zero);
+ u->replaceUsesOfWith(guard_load, zero);
}
}
-
+
guard_load->eraseFromParent();
}
@@ -2117,46 +2076,46 @@ static void ExciseGuardStore(Instruction* guard_store)
bool
IRForTarget::RemoveGuards(BasicBlock &basic_block)
-{
+{
///////////////////////////////////////////////////////
// Eliminate any reference to guard variables found.
//
-
+
BasicBlock::iterator ii;
-
+
typedef SmallVector <Instruction*, 2> InstrList;
typedef InstrList::iterator InstrIterator;
-
+
InstrList guard_loads;
InstrList guard_stores;
-
+
for (ii = basic_block.begin();
ii != basic_block.end();
++ii)
{
Instruction &inst = *ii;
-
+
if (LoadInst *load = dyn_cast<LoadInst>(&inst))
if (isGuardVariableRef(load->getPointerOperand()))
- guard_loads.push_back(&inst);
-
- if (StoreInst *store = dyn_cast<StoreInst>(&inst))
+ guard_loads.push_back(&inst);
+
+ if (StoreInst *store = dyn_cast<StoreInst>(&inst))
if (isGuardVariableRef(store->getPointerOperand()))
guard_stores.push_back(&inst);
}
-
+
InstrIterator iter;
-
+
for (iter = guard_loads.begin();
iter != guard_loads.end();
++iter)
TurnGuardLoadIntoZero(*iter);
-
+
for (iter = guard_stores.begin();
iter != guard_stores.end();
++iter)
ExciseGuardStore(*iter);
-
+
return true;
}
@@ -2168,27 +2127,23 @@ IRForTarget::UnfoldConstant(Constant *old_constant,
{
lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
- Value::use_iterator ui;
-
SmallVector<User*, 16> users;
-
+
// We do this because the use list might change, invalidating our iterator.
// Much better to keep a work list ourselves.
- for (ui = old_constant->use_begin();
- ui != old_constant->use_end();
- ++ui)
- users.push_back(*ui);
-
+ for (llvm::User *u : old_constant->users())
+ users.push_back(u);
+
for (size_t i = 0;
i < users.size();
++i)
{
User *user = users[i];
-
+
if (Constant *constant = dyn_cast<Constant>(user))
{
// synthesize a new non-constant equivalent of the constant
-
+
if (ConstantExpr *constant_expr = dyn_cast<ConstantExpr>(constant))
{
switch (constant_expr->getOpcode())
@@ -2198,20 +2153,20 @@ IRForTarget::UnfoldConstant(Constant *old_constant,
log->Printf("Unhandled constant expression type: \"%s\"", PrintValue(constant_expr).c_str());
return false;
case Instruction::BitCast:
- {
+ {
FunctionValueCache bit_cast_maker ([&value_maker, &entry_instruction_finder, old_constant, constant_expr] (llvm::Function *function)->llvm::Value* {
// UnaryExpr
// OperandList[0] is value
if (constant_expr->getOperand(0) != old_constant)
return constant_expr;
-
+
return new BitCastInst(value_maker.GetValue(function),
constant_expr->getType(),
"",
llvm::cast<Instruction>(entry_instruction_finder.GetValue(function)));
});
-
+
if (!UnfoldConstant(constant_expr, bit_cast_maker, entry_instruction_finder))
return false;
}
@@ -2221,35 +2176,35 @@ IRForTarget::UnfoldConstant(Constant *old_constant,
// GetElementPtrConstantExpr
// OperandList[0] is base
// OperandList[1]... are indices
-
+
FunctionValueCache get_element_pointer_maker ([&value_maker, &entry_instruction_finder, old_constant, constant_expr] (llvm::Function *function)->llvm::Value* {
Value *ptr = constant_expr->getOperand(0);
-
+
if (ptr == old_constant)
ptr = value_maker.GetValue(function);
-
+
std::vector<Value*> index_vector;
-
+
unsigned operand_index;
unsigned num_operands = constant_expr->getNumOperands();
-
+
for (operand_index = 1;
operand_index < num_operands;
++operand_index)
{
Value *operand = constant_expr->getOperand(operand_index);
-
+
if (operand == old_constant)
operand = value_maker.GetValue(function);
-
+
index_vector.push_back(operand);
}
-
+
ArrayRef <Value*> indices(index_vector);
-
+
return GetElementPtrInst::Create(ptr, indices, "", llvm::cast<Instruction>(entry_instruction_finder.GetValue(function)));
});
-
+
if (!UnfoldConstant(constant_expr, get_element_pointer_maker, entry_instruction_finder))
return false;
}
@@ -2277,162 +2232,162 @@ IRForTarget::UnfoldConstant(Constant *old_constant,
}
}
}
-
+
if (!isa<GlobalValue>(old_constant))
{
old_constant->destroyConstant();
}
-
+
return true;
}
-bool
+bool
IRForTarget::ReplaceVariables (Function &llvm_function)
{
if (!m_resolve_vars)
return true;
-
+
lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
m_decl_map->DoStructLayout();
-
+
if (log)
log->Printf("Element arrangement:");
-
+
uint32_t num_elements;
uint32_t element_index;
-
+
size_t size;
- off_t alignment;
-
+ lldb::offset_t alignment;
+
if (!m_decl_map->GetStructInfo (num_elements, size, alignment))
return false;
-
+
Function::arg_iterator iter(llvm_function.getArgumentList().begin());
-
+
if (iter == llvm_function.getArgumentList().end())
{
if (m_error_stream)
m_error_stream->Printf("Internal error [IRForTarget]: Wrapper takes no arguments (should take at least a struct pointer)");
-
+
return false;
}
-
+
Argument *argument = iter;
-
+
if (argument->getName().equals("this"))
{
++iter;
-
+
if (iter == llvm_function.getArgumentList().end())
{
if (m_error_stream)
m_error_stream->Printf("Internal error [IRForTarget]: Wrapper takes only 'this' argument (should take a struct pointer too)");
-
+
return false;
}
-
+
argument = iter;
}
else if (argument->getName().equals("self"))
{
++iter;
-
+
if (iter == llvm_function.getArgumentList().end())
{
if (m_error_stream)
m_error_stream->Printf("Internal error [IRForTarget]: Wrapper takes only 'self' argument (should take '_cmd' and a struct pointer too)");
-
+
return false;
}
-
+
if (!iter->getName().equals("_cmd"))
{
if (m_error_stream)
m_error_stream->Printf("Internal error [IRForTarget]: Wrapper takes '%s' after 'self' argument (should take '_cmd')", iter->getName().str().c_str());
-
+
return false;
}
-
+
++iter;
-
+
if (iter == llvm_function.getArgumentList().end())
{
if (m_error_stream)
m_error_stream->Printf("Internal error [IRForTarget]: Wrapper takes only 'self' and '_cmd' arguments (should take a struct pointer too)");
-
+
return false;
}
-
+
argument = iter;
}
-
+
if (!argument->getName().equals("$__lldb_arg"))
{
if (m_error_stream)
m_error_stream->Printf("Internal error [IRForTarget]: Wrapper takes an argument named '%s' instead of the struct pointer", argument->getName().str().c_str());
-
+
return false;
}
-
+
if (log)
log->Printf("Arg: \"%s\"", PrintValue(argument).c_str());
-
+
BasicBlock &entry_block(llvm_function.getEntryBlock());
Instruction *FirstEntryInstruction(entry_block.getFirstNonPHIOrDbg());
-
+
if (!FirstEntryInstruction)
{
if (m_error_stream)
m_error_stream->Printf("Internal error [IRForTarget]: Couldn't find the first instruction in the wrapper for use in rewriting");
-
+
return false;
}
-
+
LLVMContext &context(m_module->getContext());
IntegerType *offset_type(Type::getInt32Ty(context));
-
+
if (!offset_type)
{
if (m_error_stream)
m_error_stream->Printf("Internal error [IRForTarget]: Couldn't produce an offset type");
-
+
return false;
}
-
+
for (element_index = 0; element_index < num_elements; ++element_index)
{
const clang::NamedDecl *decl = NULL;
Value *value = NULL;
- off_t offset;
+ lldb::offset_t offset;
lldb_private::ConstString name;
-
+
if (!m_decl_map->GetStructElement (decl, value, offset, name, element_index))
{
if (m_error_stream)
m_error_stream->Printf("Internal error [IRForTarget]: Structure information is incomplete");
-
+
return false;
}
-
+
if (log)
- log->Printf(" \"%s\" (\"%s\") placed at %" PRId64,
+ log->Printf(" \"%s\" (\"%s\") placed at %" PRIu64,
name.GetCString(),
decl->getNameAsString().c_str(),
offset);
-
+
if (value)
{
if (log)
log->Printf(" Replacing [%s]", PrintValue(value).c_str());
-
+
FunctionValueCache body_result_maker ([this, name, offset_type, offset, argument, value] (llvm::Function *function)->llvm::Value * {
// Per the comment at ASTResultSynthesizer::SynthesizeBodyResult, in cases where the result
// variable is an rvalue, we have to synthesize a dereference of the appropriate structure
// entry in order to produce the static variable that the AST thinks it is accessing.
-
+
llvm::Instruction *entry_instruction = llvm::cast<Instruction>(m_entry_instruction_finder.GetValue(function));
-
+
ConstantInt *offset_int(ConstantInt::get(offset_type, offset, true));
GetElementPtrInst *get_element_ptr = GetElementPtrInst::Create(argument,
offset_int,
@@ -2445,19 +2400,19 @@ IRForTarget::ReplaceVariables (Function &llvm_function)
value->getType()->getPointerTo(),
"",
entry_instruction);
-
+
LoadInst *load = new LoadInst(bit_cast, "", entry_instruction);
-
+
return load;
}
else
{
BitCastInst *bit_cast = new BitCastInst(get_element_ptr, value->getType(), "", entry_instruction);
-
+
return bit_cast;
}
- });
-
+ });
+
if (Constant *constant = dyn_cast<Constant>(value))
{
UnfoldConstant(constant, body_result_maker, m_entry_instruction_finder);
@@ -2472,15 +2427,15 @@ IRForTarget::ReplaceVariables (Function &llvm_function)
log->Printf("Unhandled non-constant type: \"%s\"", PrintValue(value).c_str());
return false;
}
-
+
if (GlobalVariable *var = dyn_cast<GlobalVariable>(value))
var->eraseFromParent();
}
}
-
+
if (log)
- log->Printf("Total structure [align %" PRId64 ", size %zu]", alignment, size);
-
+ log->Printf("Total structure [align %" PRId64 ", size %" PRIu64 "]", (int64_t)alignment, (uint64_t)size);
+
return true;
}
@@ -2488,29 +2443,29 @@ llvm::Constant *
IRForTarget::BuildRelocation(llvm::Type *type, uint64_t offset)
{
llvm::Constant *offset_int = ConstantInt::get(m_intptr_ty, offset);
-
+
llvm::Constant *offset_array[1];
-
+
offset_array[0] = offset_int;
-
+
llvm::ArrayRef<llvm::Constant *> offsets(offset_array, 1);
-
+
llvm::Constant *reloc_getelementptr = ConstantExpr::getGetElementPtr(m_reloc_placeholder, offsets);
llvm::Constant *reloc_getbitcast = ConstantExpr::getBitCast(reloc_getelementptr, type);
-
+
return reloc_getbitcast;
}
-bool
+bool
IRForTarget::CompleteDataAllocation ()
-{
+{
lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
if (!m_data_allocator.GetStream().GetSize())
return true;
-
+
lldb::addr_t allocation = m_data_allocator.Allocate();
-
+
if (log)
{
if (allocation)
@@ -2518,15 +2473,15 @@ IRForTarget::CompleteDataAllocation ()
else
log->Printf("Failed to allocate static data");
}
-
+
if (!allocation || allocation == LLDB_INVALID_ADDRESS)
return false;
-
+
Constant *relocated_addr = ConstantInt::get(m_intptr_ty, (uint64_t)allocation);
Constant *relocated_bitcast = ConstantExpr::getIntToPtr(relocated_addr, llvm::Type::getInt8PtrTy(m_module->getContext()));
-
+
m_reloc_placeholder->replaceAllUsesWith(relocated_bitcast);
-
+
m_reloc_placeholder->eraseFromParent();
return true;
@@ -2538,47 +2493,39 @@ IRForTarget::StripAllGVs (Module &llvm_module)
lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
std::vector<GlobalVariable *> global_vars;
std::set<GlobalVariable *>erased_vars;
-
+
bool erased = true;
-
+
while (erased)
{
erased = false;
-
- for (Module::global_iterator gi = llvm_module.global_begin(), ge = llvm_module.global_end();
- gi != ge;
- ++gi)
+
+ for (GlobalVariable &global_var : llvm_module.globals())
{
- GlobalVariable *global_var = dyn_cast<GlobalVariable>(gi);
-
- global_var->removeDeadConstantUsers();
-
- if (global_var->use_empty())
+ global_var.removeDeadConstantUsers();
+
+ if (global_var.use_empty())
{
if (log)
log->Printf("Did remove %s",
- PrintValue(global_var).c_str());
- global_var->eraseFromParent();
+ PrintValue(&global_var).c_str());
+ global_var.eraseFromParent();
erased = true;
break;
}
}
}
-
- for (Module::global_iterator gi = llvm_module.global_begin(), ge = llvm_module.global_end();
- gi != ge;
- ++gi)
+
+ for (GlobalVariable &global_var : llvm_module.globals())
{
- GlobalVariable *global_var = dyn_cast<GlobalVariable>(gi);
+ GlobalValue::user_iterator ui = global_var.user_begin();
- GlobalValue::use_iterator ui = global_var->use_begin();
-
if (log)
log->Printf("Couldn't remove %s because of %s",
- PrintValue(global_var).c_str(),
+ PrintValue(&global_var).c_str(),
PrintValue(*ui).c_str());
}
-
+
return true;
}
@@ -2586,46 +2533,46 @@ bool
IRForTarget::runOnModule (Module &llvm_module)
{
lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
+
m_module = &llvm_module;
m_target_data.reset(new DataLayout(m_module));
m_intptr_ty = llvm::Type::getIntNTy(m_module->getContext(), m_target_data->getPointerSizeInBits());
-
+
if (log)
{
std::string s;
raw_string_ostream oss(s);
-
+
m_module->print(oss, NULL);
-
+
oss.flush();
-
+
log->Printf("Module as passed in to IRForTarget: \n\"%s\"", s.c_str());
}
-
+
Function* main_function = m_module->getFunction(StringRef(m_func_name.c_str()));
-
+
if (!main_function)
{
if (log)
log->Printf("Couldn't find \"%s()\" in the module", m_func_name.c_str());
-
+
if (m_error_stream)
m_error_stream->Printf("Internal error [IRForTarget]: Couldn't find wrapper '%s' in the module", m_func_name.c_str());
return false;
}
-
+
if (!FixFunctionLinkage (*main_function))
{
if (log)
log->Printf("Couldn't fix the linkage for the function");
-
+
return false;
}
-
+
llvm::Type *int8_ty = Type::getInt8Ty(m_module->getContext());
-
+
m_reloc_placeholder = new llvm::GlobalVariable((*m_module),
int8_ty,
false /* IsConstant */,
@@ -2639,14 +2586,14 @@ IRForTarget::runOnModule (Module &llvm_module)
////////////////////////////////////////////////////////////
// Replace $__lldb_expr_result with a persistent variable
//
-
+
if (!CreateResultVariable(*main_function))
{
if (log)
log->Printf("CreateResultVariable() failed");
-
+
// CreateResultVariable() reports its own errors, so we don't do so here
-
+
return false;
}
@@ -2654,25 +2601,25 @@ IRForTarget::runOnModule (Module &llvm_module)
{
std::string s;
raw_string_ostream oss(s);
-
+
m_module->print(oss, NULL);
-
+
oss.flush();
-
+
log->Printf("Module after creating the result variable: \n\"%s\"", s.c_str());
}
-
+
for (Module::iterator fi = m_module->begin(), fe = m_module->end();
fi != fe;
++fi)
{
llvm::Function *function = fi;
-
+
if (function->begin() == function->end())
continue;
-
+
Function::iterator bbi;
-
+
for (bbi = function->begin();
bbi != function->end();
++bbi)
@@ -2681,62 +2628,62 @@ IRForTarget::runOnModule (Module &llvm_module)
{
if (log)
log->Printf("RemoveGuards() failed");
-
+
// RemoveGuards() reports its own errors, so we don't do so here
-
+
return false;
}
-
+
if (!RewritePersistentAllocs(*bbi))
{
if (log)
log->Printf("RewritePersistentAllocs() failed");
-
+
// RewritePersistentAllocs() reports its own errors, so we don't do so here
-
+
return false;
}
-
+
if (!RemoveCXAAtExit(*bbi))
{
if (log)
log->Printf("RemoveCXAAtExit() failed");
-
+
// RemoveCXAAtExit() reports its own errors, so we don't do so here
-
+
return false;
}
}
}
-
+
///////////////////////////////////////////////////////////////////////////////
// Fix all Objective-C constant strings to use NSStringWithCString:encoding:
//
-
+
if (!RewriteObjCConstStrings())
{
if (log)
log->Printf("RewriteObjCConstStrings() failed");
-
+
// RewriteObjCConstStrings() reports its own errors, so we don't do so here
-
+
return false;
}
-
+
///////////////////////////////
// Resolve function pointers
//
-
+
if (!ResolveFunctionPointers(llvm_module))
{
if (log)
log->Printf("ResolveFunctionPointers() failed");
-
+
// ResolveFunctionPointers() reports its own errors, so we don't do so here
-
+
return false;
}
-
+
for (Module::iterator fi = m_module->begin(), fe = m_module->end();
fi != fe;
++fi)
@@ -2751,9 +2698,9 @@ IRForTarget::runOnModule (Module &llvm_module)
{
if (log)
log->Printf("RewriteObjCSelectors() failed");
-
+
// RewriteObjCSelectors() reports its own errors, so we don't do so here
-
+
return false;
}
}
@@ -2764,7 +2711,7 @@ IRForTarget::runOnModule (Module &llvm_module)
++fi)
{
llvm::Function *function = fi;
-
+
for (llvm::Function::iterator bbi = function->begin(), bbe = function->end();
bbi != bbe;
++bbi)
@@ -2773,81 +2720,81 @@ IRForTarget::runOnModule (Module &llvm_module)
{
if (log)
log->Printf("ResolveCalls() failed");
-
+
// ResolveCalls() reports its own errors, so we don't do so here
-
+
return false;
}
-
+
if (!ReplaceStaticLiterals(*bbi))
{
if (log)
log->Printf("ReplaceStaticLiterals() failed");
-
+
return false;
}
}
}
-
+
////////////////////////////////////////////////////////////////////////
// Run function-level passes that only make sense on the main function
//
-
+
if (!ResolveExternals(*main_function))
{
if (log)
log->Printf("ResolveExternals() failed");
-
+
// ResolveExternals() reports its own errors, so we don't do so here
-
+
return false;
}
-
+
if (!ReplaceVariables(*main_function))
{
if (log)
log->Printf("ReplaceVariables() failed");
-
+
// ReplaceVariables() reports its own errors, so we don't do so here
-
+
return false;
}
-
+
if (!ReplaceStrings())
{
if (log)
log->Printf("ReplaceStrings() failed");
-
+
return false;
}
-
+
if (!CompleteDataAllocation())
{
if (log)
log->Printf("CompleteDataAllocation() failed");
-
+
return false;
}
-
+
if (!StripAllGVs(llvm_module))
{
if (log)
log->Printf("StripAllGVs() failed");
}
-
+
if (log && log->GetVerbose())
{
std::string s;
raw_string_ostream oss(s);
-
+
m_module->print(oss, NULL);
-
+
oss.flush();
-
+
log->Printf("Module after preparing for execution: \n\"%s\"", s.c_str());
}
-
- return true;
+
+ return true;
}
void
diff --git a/contrib/llvm/tools/lldb/source/Expression/IRInterpreter.cpp b/contrib/llvm/tools/lldb/source/Expression/IRInterpreter.cpp
index 71ef8d6..d11bdc1 100644
--- a/contrib/llvm/tools/lldb/source/Expression/IRInterpreter.cpp
+++ b/contrib/llvm/tools/lldb/source/Expression/IRInterpreter.cpp
@@ -20,6 +20,7 @@
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Instructions.h"
+#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/raw_ostream.h"
@@ -27,7 +28,7 @@
using namespace llvm;
-static std::string
+static std::string
PrintValue(const Value *value, bool truncate = false)
{
std::string s;
@@ -36,13 +37,13 @@ PrintValue(const Value *value, bool truncate = false)
rso.flush();
if (truncate)
s.resize(s.length() - 1);
-
+
size_t offset;
while ((offset = s.find('\n')) != s.npos)
s.erase(offset, 1);
while (s[0] == ' ' || s[0] == '\t')
s.erase(0, 1);
-
+
return s;
}
@@ -58,25 +59,48 @@ PrintType(const Type *type, bool truncate = false)
return s;
}
+static bool
+CanIgnoreCall (const CallInst *call)
+{
+ const llvm::Function *called_function = call->getCalledFunction();
+
+ if (!called_function)
+ return false;
+
+ if (called_function->isIntrinsic())
+ {
+ switch (called_function->getIntrinsicID())
+ {
+ default:
+ break;
+ case llvm::Intrinsic::dbg_declare:
+ case llvm::Intrinsic::dbg_value:
+ return true;
+ }
+ }
+
+ return false;
+}
+
class InterpreterStackFrame
{
public:
typedef std::map <const Value*, lldb::addr_t> ValueMap;
-
+
ValueMap m_values;
DataLayout &m_target_data;
lldb_private::IRMemoryMap &m_memory_map;
const BasicBlock *m_bb;
BasicBlock::const_iterator m_ii;
BasicBlock::const_iterator m_ie;
-
+
lldb::addr_t m_frame_process_address;
size_t m_frame_size;
lldb::addr_t m_stack_pointer;
-
+
lldb::ByteOrder m_byte_order;
size_t m_addr_byte_size;
-
+
InterpreterStackFrame (DataLayout &target_data,
lldb_private::IRMemoryMap &memory_map,
lldb::addr_t stack_frame_bottom,
@@ -86,41 +110,41 @@ public:
{
m_byte_order = (target_data.isLittleEndian() ? lldb::eByteOrderLittle : lldb::eByteOrderBig);
m_addr_byte_size = (target_data.getPointerSize(0));
-
+
m_frame_process_address = stack_frame_bottom;
m_frame_size = stack_frame_top - stack_frame_bottom;
m_stack_pointer = stack_frame_top;
}
-
+
~InterpreterStackFrame ()
{
}
-
+
void Jump (const BasicBlock *bb)
{
m_bb = bb;
m_ii = m_bb->begin();
m_ie = m_bb->end();
}
-
+
std::string SummarizeValue (const Value *value)
{
lldb_private::StreamString ss;
ss.Printf("%s", PrintValue(value).c_str());
-
+
ValueMap::iterator i = m_values.find(value);
if (i != m_values.end())
{
lldb::addr_t addr = i->second;
-
+
ss.Printf(" 0x%llx", (unsigned long long)addr);
}
-
+
return ss.GetString();
}
-
+
bool AssignToMatchType (lldb_private::Scalar &scalar, uint64_t u64value, Type *type)
{
size_t type_size = m_target_data.getTypeStoreSize(type);
@@ -142,36 +166,36 @@ public:
default:
return false;
}
-
+
return true;
}
-
+
bool EvaluateValue (lldb_private::Scalar &scalar, const Value *value, Module &module)
{
const Constant *constant = dyn_cast<Constant>(value);
-
+
if (constant)
{
APInt value_apint;
-
+
if (!ResolveConstantValue(value_apint, constant))
return false;
-
+
return AssignToMatchType(scalar, value_apint.getLimitedValue(), value->getType());
}
else
{
lldb::addr_t process_address = ResolveValue(value, module);
size_t value_size = m_target_data.getTypeStoreSize(value->getType());
-
+
lldb_private::DataExtractor value_extractor;
lldb_private::Error extract_error;
-
+
m_memory_map.GetMemoryData(value_extractor, process_address, value_size, extract_error);
-
+
if (!extract_error.Success())
return false;
-
+
lldb::offset_t offset = 0;
if (value_size == 1 || value_size == 2 || value_size == 4 || value_size == 8)
{
@@ -179,38 +203,38 @@ public:
return AssignToMatchType(scalar, u64value, value->getType());
}
}
-
+
return false;
}
-
+
bool AssignValue (const Value *value, lldb_private::Scalar &scalar, Module &module)
{
lldb::addr_t process_address = ResolveValue (value, module);
-
+
if (process_address == LLDB_INVALID_ADDRESS)
return false;
-
+
lldb_private::Scalar cast_scalar;
-
+
if (!AssignToMatchType(cast_scalar, scalar.GetRawBits64(0), value->getType()))
return false;
-
+
size_t value_byte_size = m_target_data.getTypeStoreSize(value->getType());
-
+
lldb_private::DataBufferHeap buf(value_byte_size, 0);
-
+
lldb_private::Error get_data_error;
-
+
if (!cast_scalar.GetAsMemoryData(buf.GetBytes(), buf.GetByteSize(), m_byte_order, get_data_error))
return false;
-
+
lldb_private::Error write_error;
-
+
m_memory_map.WriteMemory(process_address, buf.GetBytes(), buf.GetByteSize(), write_error);
-
+
return write_error.Success();
}
-
+
bool ResolveConstantValue (APInt &value, const Constant *constant)
{
switch (constant->getValueID())
@@ -246,27 +270,27 @@ public:
{
ConstantExpr::const_op_iterator op_cursor = constant_expr->op_begin();
ConstantExpr::const_op_iterator op_end = constant_expr->op_end();
-
+
Constant *base = dyn_cast<Constant>(*op_cursor);
-
+
if (!base)
return false;
-
+
if (!ResolveConstantValue(value, base))
return false;
-
+
op_cursor++;
-
+
if (op_cursor == op_end)
return true; // no offset to apply!
-
+
SmallVector <Value *, 8> indices (op_cursor, op_end);
-
+
uint64_t offset = m_target_data.getIndexedOffset(base->getType(), indices);
-
+
const bool is_signed = true;
value += APInt(value.getBitWidth(), offset, is_signed);
-
+
return true;
}
}
@@ -282,27 +306,27 @@ public:
}
return false;
}
-
+
bool MakeArgument(const Argument *value, uint64_t address)
{
lldb::addr_t data_address = Malloc(value->getType());
-
+
if (data_address == LLDB_INVALID_ADDRESS)
return false;
-
+
lldb_private::Error write_error;
-
+
m_memory_map.WritePointerToMemory(data_address, address, write_error);
-
+
if (!write_error.Success())
{
lldb_private::Error free_error;
m_memory_map.Free(data_address, free_error);
return false;
}
-
+
m_values[value] = data_address;
-
+
lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
if (log)
@@ -311,75 +335,75 @@ public:
log->Printf(" Data region : %llx", (unsigned long long)address);
log->Printf(" Ref region : %llx", (unsigned long long)data_address);
}
-
+
return true;
}
-
+
bool ResolveConstant (lldb::addr_t process_address, const Constant *constant)
{
APInt resolved_value;
-
+
if (!ResolveConstantValue(resolved_value, constant))
return false;
-
+
lldb_private::StreamString buffer (lldb_private::Stream::eBinary,
m_memory_map.GetAddressByteSize(),
m_memory_map.GetByteOrder());
-
+
size_t constant_size = m_target_data.getTypeStoreSize(constant->getType());
-
+
const uint64_t *raw_data = resolved_value.getRawData();
-
+
buffer.PutRawBytes(raw_data, constant_size, lldb::endian::InlHostByteOrder());
-
+
lldb_private::Error write_error;
-
+
m_memory_map.WriteMemory(process_address, (const uint8_t*)buffer.GetData(), constant_size, write_error);
-
+
return write_error.Success();
}
-
+
lldb::addr_t Malloc (size_t size, uint8_t byte_alignment)
{
lldb::addr_t ret = m_stack_pointer;
-
+
ret -= size;
ret -= (ret % byte_alignment);
-
+
if (ret < m_frame_process_address)
return LLDB_INVALID_ADDRESS;
-
+
m_stack_pointer = ret;
return ret;
}
-
+
lldb::addr_t MallocPointer ()
{
return Malloc(m_target_data.getPointerSize(), m_target_data.getPointerPrefAlignment());
}
-
+
lldb::addr_t Malloc (llvm::Type *type)
{
lldb_private::Error alloc_error;
-
+
return Malloc(m_target_data.getTypeAllocSize(type), m_target_data.getPrefTypeAlignment(type));
}
-
+
std::string PrintData (lldb::addr_t addr, llvm::Type *type)
{
size_t length = m_target_data.getTypeStoreSize(type);
-
+
lldb_private::DataBufferHeap buf(length, 0);
-
+
lldb_private::Error read_error;
-
+
m_memory_map.ReadMemory(buf.GetBytes(), addr, length, read_error);
-
+
if (!read_error.Success())
return std::string("<couldn't read data>");
-
+
lldb_private::StreamString ss;
-
+
for (size_t i = 0; i < length; i++)
{
if ((!(i & 0xf)) && i)
@@ -387,21 +411,21 @@ public:
else
ss.Printf("%02hhx ", buf.GetBytes()[i]);
}
-
+
return ss.GetString();
}
-
+
lldb::addr_t ResolveValue (const Value *value, Module &module)
{
ValueMap::iterator i = m_values.find(value);
-
+
if (i != m_values.end())
return i->second;
-
+
// Fall back and allocate space [allocation type Alloca]
-
+
lldb::addr_t data_address = Malloc(value->getType());
-
+
if (const Constant *constant = dyn_cast<Constant>(value))
{
if (!ResolveConstant (data_address, constant))
@@ -411,7 +435,7 @@ public:
return LLDB_INVALID_ADDRESS;
}
}
-
+
m_values[value] = data_address;
return data_address;
}
@@ -434,9 +458,9 @@ IRInterpreter::CanInterpret (llvm::Module &module,
lldb_private::Error &error)
{
lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
+
bool saw_function_with_body = false;
-
+
for (Module::iterator fi = module.begin(), fe = module.end();
fi != fe;
++fi)
@@ -448,7 +472,7 @@ IRInterpreter::CanInterpret (llvm::Module &module,
saw_function_with_body = true;
}
}
-
+
for (Function::iterator bbi = function.begin(), bbe = function.end();
bbi != bbe;
++bbi)
@@ -471,26 +495,48 @@ IRInterpreter::CanInterpret (llvm::Module &module,
case Instruction::Alloca:
case Instruction::BitCast:
case Instruction::Br:
+ break;
+ case Instruction::Call:
+ {
+ CallInst *call_inst = dyn_cast<CallInst>(ii);
+
+ if (!call_inst)
+ {
+ error.SetErrorToGenericError();
+ error.SetErrorString(interpreter_internal_error);
+ return false;
+ }
+
+ if (!CanIgnoreCall(call_inst))
+ {
+ if (log)
+ log->Printf("Unsupported instruction: %s", PrintValue(ii).c_str());
+ error.SetErrorToGenericError();
+ error.SetErrorString(unsupported_opcode_error);
+ return false;
+ }
+ }
+ break;
case Instruction::GetElementPtr:
break;
case Instruction::ICmp:
{
ICmpInst *icmp_inst = dyn_cast<ICmpInst>(ii);
-
+
if (!icmp_inst)
{
error.SetErrorToGenericError();
error.SetErrorString(interpreter_internal_error);
return false;
}
-
+
switch (icmp_inst->getPredicate())
{
default:
{
if (log)
log->Printf("Unsupported ICmp predicate: %s", PrintValue(ii).c_str());
-
+
error.SetErrorToGenericError();
error.SetErrorString(unsupported_opcode_error);
return false;
@@ -531,14 +577,14 @@ IRInterpreter::CanInterpret (llvm::Module &module,
case Instruction::ZExt:
break;
}
-
+
for (int oi = 0, oe = ii->getNumOperands();
oi != oe;
++oi)
{
Value *operand = ii->getOperand(oi);
Type *operand_type = operand->getType();
-
+
switch (operand_type->getTypeID())
{
default:
@@ -553,9 +599,9 @@ IRInterpreter::CanInterpret (llvm::Module &module,
}
}
}
-
+
}
-
+
return true;}
bool
@@ -568,60 +614,83 @@ IRInterpreter::Interpret (llvm::Module &module,
lldb::addr_t stack_frame_top)
{
lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
+
if (log)
{
std::string s;
raw_string_ostream oss(s);
-
+
module.print(oss, NULL);
-
+
oss.flush();
-
+
log->Printf("Module as passed in to IRInterpreter::Interpret: \n\"%s\"", s.c_str());
}
-
+
DataLayout data_layout(&module);
-
+
InterpreterStackFrame frame(data_layout, memory_map, stack_frame_bottom, stack_frame_top);
-
+
if (frame.m_frame_process_address == LLDB_INVALID_ADDRESS)
{
error.SetErrorString("Couldn't allocate stack frame");
}
-
+
int arg_index = 0;
-
+
for (llvm::Function::arg_iterator ai = function.arg_begin(), ae = function.arg_end();
ai != ae;
++ai, ++arg_index)
{
- if (args.size() < arg_index)
+ if (args.size() < static_cast<size_t>(arg_index))
{
error.SetErrorString ("Not enough arguments passed in to function");
return false;
}
-
+
lldb::addr_t ptr = args[arg_index];
frame.MakeArgument(ai, ptr);
}
-
+
uint32_t num_insts = 0;
-
+
frame.Jump(function.begin());
-
+
while (frame.m_ii != frame.m_ie && (++num_insts < 4096))
{
const Instruction *inst = frame.m_ii;
-
+
if (log)
log->Printf("Interpreting %s", PrintValue(inst).c_str());
-
+
switch (inst->getOpcode())
{
default:
break;
+ case Instruction::Call:
+ {
+ const CallInst *call_inst = dyn_cast<CallInst>(inst);
+
+ if (!call_inst)
+ {
+ if (log)
+ log->Printf("getOpcode() returns %s, but instruction is not a CallInst", inst->getOpcodeName());
+ error.SetErrorToGenericError();
+ error.SetErrorString(interpreter_internal_error);
+ return false;
+ }
+
+ if (!CanIgnoreCall(call_inst))
+ {
+ if (log)
+ log->Printf("The interpreter shouldn't have accepted %s", PrintValue(call_inst).c_str());
+ error.SetErrorToGenericError();
+ error.SetErrorString(interpreter_internal_error);
+ return false;
+ }
+ }
+ break;
case Instruction::Add:
case Instruction::Sub:
case Instruction::Mul:
@@ -637,7 +706,7 @@ IRInterpreter::Interpret (llvm::Module &module,
case Instruction::Xor:
{
const BinaryOperator *bin_op = dyn_cast<BinaryOperator>(inst);
-
+
if (!bin_op)
{
if (log)
@@ -646,13 +715,13 @@ IRInterpreter::Interpret (llvm::Module &module,
error.SetErrorString(interpreter_internal_error);
return false;
}
-
+
Value *lhs = inst->getOperand(0);
Value *rhs = inst->getOperand(1);
-
+
lldb_private::Scalar L;
lldb_private::Scalar R;
-
+
if (!frame.EvaluateValue(L, lhs, module))
{
if (log)
@@ -661,7 +730,7 @@ IRInterpreter::Interpret (llvm::Module &module,
error.SetErrorString(bad_value_error);
return false;
}
-
+
if (!frame.EvaluateValue(R, rhs, module))
{
if (log)
@@ -670,9 +739,9 @@ IRInterpreter::Interpret (llvm::Module &module,
error.SetErrorString(bad_value_error);
return false;
}
-
+
lldb_private::Scalar result;
-
+
switch (inst->getOpcode())
{
default:
@@ -722,9 +791,9 @@ IRInterpreter::Interpret (llvm::Module &module,
result = L ^ R;
break;
}
-
+
frame.AssignValue(inst, result, module);
-
+
if (log)
{
log->Printf("Interpreted a %s", inst->getOpcodeName());
@@ -737,7 +806,7 @@ IRInterpreter::Interpret (llvm::Module &module,
case Instruction::Alloca:
{
const AllocaInst *alloca_inst = dyn_cast<AllocaInst>(inst);
-
+
if (!alloca_inst)
{
if (log)
@@ -746,7 +815,7 @@ IRInterpreter::Interpret (llvm::Module &module,
error.SetErrorString(interpreter_internal_error);
return false;
}
-
+
if (alloca_inst->isArrayAllocation())
{
if (log)
@@ -755,17 +824,17 @@ IRInterpreter::Interpret (llvm::Module &module,
error.SetErrorString(unsupported_opcode_error);
return false;
}
-
+
// The semantics of Alloca are:
// Create a region R of virtual memory of type T, backed by a data buffer
// Create a region P of virtual memory of type T*, backed by a data buffer
// Write the virtual address of R into P
-
+
Type *T = alloca_inst->getAllocatedType();
Type *Tptr = alloca_inst->getType();
-
+
lldb::addr_t R = frame.Malloc(T);
-
+
if (R == LLDB_INVALID_ADDRESS)
{
if (log)
@@ -774,9 +843,9 @@ IRInterpreter::Interpret (llvm::Module &module,
error.SetErrorString(memory_allocation_error);
return false;
}
-
+
lldb::addr_t P = frame.Malloc(Tptr);
-
+
if (P == LLDB_INVALID_ADDRESS)
{
if (log)
@@ -785,11 +854,11 @@ IRInterpreter::Interpret (llvm::Module &module,
error.SetErrorString(memory_allocation_error);
return false;
}
-
+
lldb_private::Error write_error;
-
+
memory_map.WritePointerToMemory(P, R, write_error);
-
+
if (!write_error.Success())
{
if (log)
@@ -801,9 +870,9 @@ IRInterpreter::Interpret (llvm::Module &module,
memory_map.Free(R, free_error);
return false;
}
-
+
frame.m_values[alloca_inst] = P;
-
+
if (log)
{
log->Printf("Interpreted an AllocaInst");
@@ -816,7 +885,7 @@ IRInterpreter::Interpret (llvm::Module &module,
case Instruction::ZExt:
{
const CastInst *cast_inst = dyn_cast<CastInst>(inst);
-
+
if (!cast_inst)
{
if (log)
@@ -825,11 +894,11 @@ IRInterpreter::Interpret (llvm::Module &module,
error.SetErrorString(interpreter_internal_error);
return false;
}
-
+
Value *source = cast_inst->getOperand(0);
-
+
lldb_private::Scalar S;
-
+
if (!frame.EvaluateValue(S, source, module))
{
if (log)
@@ -838,14 +907,14 @@ IRInterpreter::Interpret (llvm::Module &module,
error.SetErrorString(bad_value_error);
return false;
}
-
+
frame.AssignValue(inst, S, module);
}
break;
case Instruction::SExt:
{
const CastInst *cast_inst = dyn_cast<CastInst>(inst);
-
+
if (!cast_inst)
{
if (log)
@@ -854,11 +923,11 @@ IRInterpreter::Interpret (llvm::Module &module,
error.SetErrorString(interpreter_internal_error);
return false;
}
-
+
Value *source = cast_inst->getOperand(0);
-
+
lldb_private::Scalar S;
-
+
if (!frame.EvaluateValue(S, source, module))
{
if (log)
@@ -867,18 +936,18 @@ IRInterpreter::Interpret (llvm::Module &module,
error.SetErrorString(bad_value_error);
return false;
}
-
+
S.MakeSigned();
-
+
lldb_private::Scalar S_signextend(S.SLongLong());
-
+
frame.AssignValue(inst, S_signextend, module);
}
break;
case Instruction::Br:
{
const BranchInst *br_inst = dyn_cast<BranchInst>(inst);
-
+
if (!br_inst)
{
if (log)
@@ -887,13 +956,13 @@ IRInterpreter::Interpret (llvm::Module &module,
error.SetErrorString(interpreter_internal_error);
return false;
}
-
+
if (br_inst->isConditional())
{
Value *condition = br_inst->getCondition();
-
+
lldb_private::Scalar C;
-
+
if (!frame.EvaluateValue(C, condition, module))
{
if (log)
@@ -902,12 +971,12 @@ IRInterpreter::Interpret (llvm::Module &module,
error.SetErrorString(bad_value_error);
return false;
}
-
+
if (C.GetRawBits64(0))
frame.Jump(br_inst->getSuccessor(0));
else
frame.Jump(br_inst->getSuccessor(1));
-
+
if (log)
{
log->Printf("Interpreted a BrInst with a condition");
@@ -917,7 +986,7 @@ IRInterpreter::Interpret (llvm::Module &module,
else
{
frame.Jump(br_inst->getSuccessor(0));
-
+
if (log)
{
log->Printf("Interpreted a BrInst with no condition");
@@ -928,7 +997,7 @@ IRInterpreter::Interpret (llvm::Module &module,
case Instruction::GetElementPtr:
{
const GetElementPtrInst *gep_inst = dyn_cast<GetElementPtrInst>(inst);
-
+
if (!gep_inst)
{
if (log)
@@ -937,12 +1006,12 @@ IRInterpreter::Interpret (llvm::Module &module,
error.SetErrorString(interpreter_internal_error);
return false;
}
-
+
const Value *pointer_operand = gep_inst->getPointerOperand();
Type *pointer_type = pointer_operand->getType();
-
+
lldb_private::Scalar P;
-
+
if (!frame.EvaluateValue(P, pointer_operand, module))
{
if (log)
@@ -951,25 +1020,25 @@ IRInterpreter::Interpret (llvm::Module &module,
error.SetErrorString(bad_value_error);
return false;
}
-
+
typedef SmallVector <Value *, 8> IndexVector;
typedef IndexVector::iterator IndexIterator;
-
+
SmallVector <Value *, 8> indices (gep_inst->idx_begin(),
gep_inst->idx_end());
-
+
SmallVector <Value *, 8> const_indices;
-
+
for (IndexIterator ii = indices.begin(), ie = indices.end();
ii != ie;
++ii)
{
ConstantInt *constant_index = dyn_cast<ConstantInt>(*ii);
-
+
if (!constant_index)
{
lldb_private::Scalar I;
-
+
if (!frame.EvaluateValue(I, *ii, module))
{
if (log)
@@ -978,22 +1047,22 @@ IRInterpreter::Interpret (llvm::Module &module,
error.SetErrorString(bad_value_error);
return false;
}
-
+
if (log)
log->Printf("Evaluated constant index %s as %llu", PrintValue(*ii).c_str(), I.ULongLong(LLDB_INVALID_ADDRESS));
-
+
constant_index = cast<ConstantInt>(ConstantInt::get((*ii)->getType(), I.ULongLong(LLDB_INVALID_ADDRESS)));
}
-
+
const_indices.push_back(constant_index);
}
-
+
uint64_t offset = data_layout.getIndexedOffset(pointer_type, const_indices);
-
+
lldb_private::Scalar Poffset = P + offset;
-
+
frame.AssignValue(inst, Poffset, module);
-
+
if (log)
{
log->Printf("Interpreted a GetElementPtrInst");
@@ -1005,7 +1074,7 @@ IRInterpreter::Interpret (llvm::Module &module,
case Instruction::ICmp:
{
const ICmpInst *icmp_inst = dyn_cast<ICmpInst>(inst);
-
+
if (!icmp_inst)
{
if (log)
@@ -1014,15 +1083,15 @@ IRInterpreter::Interpret (llvm::Module &module,
error.SetErrorString(interpreter_internal_error);
return false;
}
-
+
CmpInst::Predicate predicate = icmp_inst->getPredicate();
-
+
Value *lhs = inst->getOperand(0);
Value *rhs = inst->getOperand(1);
-
+
lldb_private::Scalar L;
lldb_private::Scalar R;
-
+
if (!frame.EvaluateValue(L, lhs, module))
{
if (log)
@@ -1031,7 +1100,7 @@ IRInterpreter::Interpret (llvm::Module &module,
error.SetErrorString(bad_value_error);
return false;
}
-
+
if (!frame.EvaluateValue(R, rhs, module))
{
if (log)
@@ -1040,9 +1109,9 @@ IRInterpreter::Interpret (llvm::Module &module,
error.SetErrorString(bad_value_error);
return false;
}
-
+
lldb_private::Scalar result;
-
+
switch (predicate)
{
default:
@@ -1086,9 +1155,9 @@ IRInterpreter::Interpret (llvm::Module &module,
result = (L <= R);
break;
}
-
+
frame.AssignValue(inst, result, module);
-
+
if (log)
{
log->Printf("Interpreted an ICmpInst");
@@ -1101,7 +1170,7 @@ IRInterpreter::Interpret (llvm::Module &module,
case Instruction::IntToPtr:
{
const IntToPtrInst *int_to_ptr_inst = dyn_cast<IntToPtrInst>(inst);
-
+
if (!int_to_ptr_inst)
{
if (log)
@@ -1110,11 +1179,11 @@ IRInterpreter::Interpret (llvm::Module &module,
error.SetErrorString(interpreter_internal_error);
return false;
}
-
+
Value *src_operand = int_to_ptr_inst->getOperand(0);
-
+
lldb_private::Scalar I;
-
+
if (!frame.EvaluateValue(I, src_operand, module))
{
if (log)
@@ -1123,9 +1192,9 @@ IRInterpreter::Interpret (llvm::Module &module,
error.SetErrorString(bad_value_error);
return false;
}
-
+
frame.AssignValue(inst, I, module);
-
+
if (log)
{
log->Printf("Interpreted an IntToPtr");
@@ -1137,7 +1206,7 @@ IRInterpreter::Interpret (llvm::Module &module,
case Instruction::PtrToInt:
{
const PtrToIntInst *ptr_to_int_inst = dyn_cast<PtrToIntInst>(inst);
-
+
if (!ptr_to_int_inst)
{
if (log)
@@ -1146,11 +1215,11 @@ IRInterpreter::Interpret (llvm::Module &module,
error.SetErrorString(interpreter_internal_error);
return false;
}
-
+
Value *src_operand = ptr_to_int_inst->getOperand(0);
-
+
lldb_private::Scalar I;
-
+
if (!frame.EvaluateValue(I, src_operand, module))
{
if (log)
@@ -1159,9 +1228,9 @@ IRInterpreter::Interpret (llvm::Module &module,
error.SetErrorString(bad_value_error);
return false;
}
-
+
frame.AssignValue(inst, I, module);
-
+
if (log)
{
log->Printf("Interpreted a PtrToInt");
@@ -1173,7 +1242,7 @@ IRInterpreter::Interpret (llvm::Module &module,
case Instruction::Trunc:
{
const TruncInst *trunc_inst = dyn_cast<TruncInst>(inst);
-
+
if (!trunc_inst)
{
if (log)
@@ -1182,11 +1251,11 @@ IRInterpreter::Interpret (llvm::Module &module,
error.SetErrorString(interpreter_internal_error);
return false;
}
-
+
Value *src_operand = trunc_inst->getOperand(0);
-
+
lldb_private::Scalar I;
-
+
if (!frame.EvaluateValue(I, src_operand, module))
{
if (log)
@@ -1195,9 +1264,9 @@ IRInterpreter::Interpret (llvm::Module &module,
error.SetErrorString(bad_value_error);
return false;
}
-
+
frame.AssignValue(inst, I, module);
-
+
if (log)
{
log->Printf("Interpreted a Trunc");
@@ -1209,7 +1278,7 @@ IRInterpreter::Interpret (llvm::Module &module,
case Instruction::Load:
{
const LoadInst *load_inst = dyn_cast<LoadInst>(inst);
-
+
if (!load_inst)
{
if (log)
@@ -1218,15 +1287,15 @@ IRInterpreter::Interpret (llvm::Module &module,
error.SetErrorString(interpreter_internal_error);
return false;
}
-
+
// The semantics of Load are:
// Create a region D that will contain the loaded data
// Resolve the region P containing a pointer
// Dereference P to get the region R that the data should be loaded from
// Transfer a unit of type type(D) from R to D
-
+
const Value *pointer_operand = load_inst->getPointerOperand();
-
+
Type *pointer_ty = pointer_operand->getType();
PointerType *pointer_ptr_ty = dyn_cast<PointerType>(pointer_ty);
if (!pointer_ptr_ty)
@@ -1238,10 +1307,10 @@ IRInterpreter::Interpret (llvm::Module &module,
return false;
}
Type *target_ty = pointer_ptr_ty->getElementType();
-
+
lldb::addr_t D = frame.ResolveValue(load_inst, module);
lldb::addr_t P = frame.ResolveValue(pointer_operand, module);
-
+
if (D == LLDB_INVALID_ADDRESS)
{
if (log)
@@ -1250,7 +1319,7 @@ IRInterpreter::Interpret (llvm::Module &module,
error.SetErrorString(bad_value_error);
return false;
}
-
+
if (P == LLDB_INVALID_ADDRESS)
{
if (log)
@@ -1259,11 +1328,11 @@ IRInterpreter::Interpret (llvm::Module &module,
error.SetErrorString(bad_value_error);
return false;
}
-
+
lldb::addr_t R;
lldb_private::Error read_error;
memory_map.ReadPointerFromMemory(&R, P, read_error);
-
+
if (!read_error.Success())
{
if (log)
@@ -1272,10 +1341,10 @@ IRInterpreter::Interpret (llvm::Module &module,
error.SetErrorString(memory_read_error);
return false;
}
-
+
size_t target_size = data_layout.getTypeStoreSize(target_ty);
lldb_private::DataBufferHeap buffer(target_size, 0);
-
+
read_error.Clear();
memory_map.ReadMemory(buffer.GetBytes(), R, buffer.GetByteSize(), read_error);
if (!read_error.Success())
@@ -1286,7 +1355,7 @@ IRInterpreter::Interpret (llvm::Module &module,
error.SetErrorString(memory_read_error);
return false;
}
-
+
lldb_private::Error write_error;
memory_map.WriteMemory(D, buffer.GetBytes(), buffer.GetByteSize(), write_error);
if (!write_error.Success())
@@ -1297,7 +1366,7 @@ IRInterpreter::Interpret (llvm::Module &module,
error.SetErrorString(memory_read_error);
return false;
}
-
+
if (log)
{
log->Printf("Interpreted a LoadInst");
@@ -1314,7 +1383,7 @@ IRInterpreter::Interpret (llvm::Module &module,
case Instruction::Store:
{
const StoreInst *store_inst = dyn_cast<StoreInst>(inst);
-
+
if (!store_inst)
{
if (log)
@@ -1323,25 +1392,25 @@ IRInterpreter::Interpret (llvm::Module &module,
error.SetErrorString(interpreter_internal_error);
return false;
}
-
+
// The semantics of Store are:
// Resolve the region D containing the data to be stored
// Resolve the region P containing a pointer
// Dereference P to get the region R that the data should be stored in
// Transfer a unit of type type(D) from D to R
-
+
const Value *value_operand = store_inst->getValueOperand();
const Value *pointer_operand = store_inst->getPointerOperand();
-
+
Type *pointer_ty = pointer_operand->getType();
PointerType *pointer_ptr_ty = dyn_cast<PointerType>(pointer_ty);
if (!pointer_ptr_ty)
return false;
Type *target_ty = pointer_ptr_ty->getElementType();
-
+
lldb::addr_t D = frame.ResolveValue(value_operand, module);
lldb::addr_t P = frame.ResolveValue(pointer_operand, module);
-
+
if (D == LLDB_INVALID_ADDRESS)
{
if (log)
@@ -1350,7 +1419,7 @@ IRInterpreter::Interpret (llvm::Module &module,
error.SetErrorString(bad_value_error);
return false;
}
-
+
if (P == LLDB_INVALID_ADDRESS)
{
if (log)
@@ -1359,11 +1428,11 @@ IRInterpreter::Interpret (llvm::Module &module,
error.SetErrorString(bad_value_error);
return false;
}
-
+
lldb::addr_t R;
lldb_private::Error read_error;
memory_map.ReadPointerFromMemory(&R, P, read_error);
-
+
if (!read_error.Success())
{
if (log)
@@ -1372,10 +1441,10 @@ IRInterpreter::Interpret (llvm::Module &module,
error.SetErrorString(memory_read_error);
return false;
}
-
+
size_t target_size = data_layout.getTypeStoreSize(target_ty);
lldb_private::DataBufferHeap buffer(target_size, 0);
-
+
read_error.Clear();
memory_map.ReadMemory(buffer.GetBytes(), D, buffer.GetByteSize(), read_error);
if (!read_error.Success())
@@ -1386,7 +1455,7 @@ IRInterpreter::Interpret (llvm::Module &module,
error.SetErrorString(memory_read_error);
return false;
}
-
+
lldb_private::Error write_error;
memory_map.WriteMemory(R, buffer.GetBytes(), buffer.GetByteSize(), write_error);
if (!write_error.Success())
@@ -1397,7 +1466,7 @@ IRInterpreter::Interpret (llvm::Module &module,
error.SetErrorString(memory_write_error);
return false;
}
-
+
if (log)
{
log->Printf("Interpreted a StoreInst");
@@ -1408,16 +1477,16 @@ IRInterpreter::Interpret (llvm::Module &module,
}
break;
}
-
+
++frame.m_ii;
}
-
+
if (num_insts >= 4096)
{
error.SetErrorToGenericError();
error.SetErrorString(infinite_loop_error);
return false;
}
-
+
return false;
}
diff --git a/contrib/llvm/tools/lldb/source/Expression/IRMemoryMap.cpp b/contrib/llvm/tools/lldb/source/Expression/IRMemoryMap.cpp
index 53f74ae..a4fe7a9 100644
--- a/contrib/llvm/tools/lldb/source/Expression/IRMemoryMap.cpp
+++ b/contrib/llvm/tools/lldb/source/Expression/IRMemoryMap.cpp
@@ -28,11 +28,11 @@ IRMemoryMap::IRMemoryMap (lldb::TargetSP target_sp) :
IRMemoryMap::~IRMemoryMap ()
{
lldb::ProcessSP process_sp = m_process_wp.lock();
-
+
if (process_sp)
{
AllocationMap::iterator iter;
-
+
Error err;
while ((iter = m_allocations.begin()) != m_allocations.end())
@@ -51,54 +51,32 @@ IRMemoryMap::FindSpace (size_t size)
{
lldb::TargetSP target_sp = m_target_wp.lock();
lldb::ProcessSP process_sp = m_process_wp.lock();
-
+
lldb::addr_t ret = LLDB_INVALID_ADDRESS;
-
+ if (size == 0)
+ return ret;
+
if (process_sp && process_sp->CanJIT() && process_sp->IsAlive())
{
Error alloc_error;
-
+
ret = process_sp->AllocateMemory(size, lldb::ePermissionsReadable | lldb::ePermissionsWritable, alloc_error);
-
+
if (!alloc_error.Success())
return LLDB_INVALID_ADDRESS;
else
return ret;
}
-
- for (int iterations = 0; iterations < 16; ++iterations)
+
+ ret = 0;
+ if (!m_allocations.empty())
{
- lldb::addr_t candidate = LLDB_INVALID_ADDRESS;
-
- switch (target_sp->GetArchitecture().GetAddressByteSize())
- {
- case 4:
- {
- uint32_t random_data = rand();
- candidate = random_data;
- candidate &= ~0xfffull;
- break;
- }
- case 8:
- {
- uint32_t random_low = rand();
- uint32_t random_high = rand();
- candidate = random_high;
- candidate <<= 32ull;
- candidate |= random_low;
- candidate &= ~0xfffull;
- break;
- }
- }
-
- if (IntersectsAllocation(candidate, size))
- continue;
-
- ret = candidate;
-
- return ret;
+ auto back = m_allocations.rbegin();
+ lldb::addr_t addr = back->first;
+ size_t alloc_size = back->second.m_size;
+ ret = llvm::RoundUpToAlignment(addr+alloc_size, 4096);
}
-
+
return ret;
}
@@ -107,9 +85,9 @@ IRMemoryMap::FindAllocation (lldb::addr_t addr, size_t size)
{
if (addr == LLDB_INVALID_ADDRESS)
return m_allocations.end();
-
+
AllocationMap::iterator iter = m_allocations.lower_bound (addr);
-
+
if (iter == m_allocations.end() ||
iter->first > addr)
{
@@ -117,54 +95,69 @@ IRMemoryMap::FindAllocation (lldb::addr_t addr, size_t size)
return m_allocations.end();
iter--;
}
-
+
if (iter->first <= addr && iter->first + iter->second.m_size >= addr + size)
return iter;
-
+
return m_allocations.end();
}
bool
-IRMemoryMap::IntersectsAllocation (lldb::addr_t addr, size_t size)
+IRMemoryMap::IntersectsAllocation (lldb::addr_t addr, size_t size) const
{
if (addr == LLDB_INVALID_ADDRESS)
return false;
-
- AllocationMap::iterator iter = m_allocations.lower_bound (addr);
-
- if (iter == m_allocations.end() ||
- iter->first > addr)
- {
- if (iter == m_allocations.begin())
- return false;
-
- iter--;
+
+ AllocationMap::const_iterator iter = m_allocations.lower_bound (addr);
+
+ // Since we only know that the returned interval begins at a location greater than or
+ // equal to where the given interval begins, it's possible that the given interval
+ // intersects either the returned interval or the previous interval. Thus, we need to
+ // check both. Note that we only need to check these two intervals. Since all intervals
+ // are disjoint it is not possible that an adjacent interval does not intersect, but a
+ // non-adjacent interval does intersect.
+ if (iter != m_allocations.end()) {
+ if (AllocationsIntersect(addr, size, iter->second.m_process_start, iter->second.m_size))
+ return true;
}
-
- while (iter != m_allocations.end() && iter->second.m_process_alloc < addr + size)
- {
- if (iter->second.m_process_start + iter->second.m_size > addr)
+
+ if (iter != m_allocations.begin()) {
+ --iter;
+ if (AllocationsIntersect(addr, size, iter->second.m_process_start, iter->second.m_size))
return true;
-
- ++iter;
}
-
+
return false;
}
+bool
+IRMemoryMap::AllocationsIntersect(lldb::addr_t addr1, size_t size1, lldb::addr_t addr2, size_t size2) {
+ // Given two half open intervals [A, B) and [X, Y), the only 6 permutations that satisfy
+ // A<B and X<Y are the following:
+ // A B X Y
+ // A X B Y (intersects)
+ // A X Y B (intersects)
+ // X A B Y (intersects)
+ // X A Y B (intersects)
+ // X Y A B
+ // The first is B <= X, and the last is Y <= A.
+ // So the condition is !(B <= X || Y <= A)), or (X < B && A < Y)
+ return (addr2 < (addr1 + size1)) && (addr1 < (addr2 + size2));
+}
+
lldb::ByteOrder
IRMemoryMap::GetByteOrder()
{
lldb::ProcessSP process_sp = m_process_wp.lock();
-
+
if (process_sp)
return process_sp->GetByteOrder();
-
+
lldb::TargetSP target_sp = m_target_wp.lock();
-
+
if (target_sp)
return target_sp->GetArchitecture().GetByteOrder();
-
+
return lldb::eByteOrderInvalid;
}
@@ -172,31 +165,31 @@ uint32_t
IRMemoryMap::GetAddressByteSize()
{
lldb::ProcessSP process_sp = m_process_wp.lock();
-
+
if (process_sp)
return process_sp->GetAddressByteSize();
-
+
lldb::TargetSP target_sp = m_target_wp.lock();
-
+
if (target_sp)
return target_sp->GetArchitecture().GetAddressByteSize();
-
+
return UINT32_MAX;
}
ExecutionContextScope *
-IRMemoryMap::GetBestExecutionContextScope()
+IRMemoryMap::GetBestExecutionContextScope() const
{
lldb::ProcessSP process_sp = m_process_wp.lock();
-
+
if (process_sp)
return process_sp.get();
-
+
lldb::TargetSP target_sp = m_target_wp.lock();
-
+
if (target_sp)
return target_sp.get();
-
+
return NULL;
}
@@ -234,8 +227,9 @@ IRMemoryMap::Allocation::Allocation (lldb::addr_t process_alloc,
lldb::addr_t
IRMemoryMap::Malloc (size_t size, uint8_t alignment, uint32_t permissions, AllocationPolicy policy, Error &error)
{
+ lldb_private::Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
error.Clear();
-
+
lldb::ProcessSP process_sp;
lldb::addr_t allocation_address = LLDB_INVALID_ADDRESS;
lldb::addr_t aligned_address = LLDB_INVALID_ADDRESS;
@@ -247,7 +241,7 @@ IRMemoryMap::Malloc (size_t size, uint8_t alignment, uint32_t permissions, Alloc
allocation_size = alignment;
else
allocation_size = (size & alignment_mask) ? ((size + alignment) & (~alignment_mask)) : size;
-
+
switch (policy)
{
default:
@@ -265,6 +259,8 @@ IRMemoryMap::Malloc (size_t size, uint8_t alignment, uint32_t permissions, Alloc
break;
case eAllocationPolicyMirror:
process_sp = m_process_wp.lock();
+ if (log)
+ log->Printf ("IRMemoryMap::%s process_sp=0x%" PRIx64 ", process_sp->CanJIT()=%s, process_sp->IsAlive()=%s", __FUNCTION__, (lldb::addr_t) process_sp.get (), process_sp && process_sp->CanJIT () ? "true" : "false", process_sp && process_sp->IsAlive () ? "true" : "false");
if (process_sp && process_sp->CanJIT() && process_sp->IsAlive())
{
allocation_address = process_sp->AllocateMemory(allocation_size, permissions, error);
@@ -273,6 +269,8 @@ IRMemoryMap::Malloc (size_t size, uint8_t alignment, uint32_t permissions, Alloc
}
else
{
+ if (log)
+ log->Printf ("IRMemoryMap::%s switching to eAllocationPolicyHostOnly due to failed condition (see previous expr log message)", __FUNCTION__);
policy = eAllocationPolicyHostOnly;
allocation_address = FindSpace(allocation_size);
if (allocation_address == LLDB_INVALID_ADDRESS)
@@ -308,8 +306,8 @@ IRMemoryMap::Malloc (size_t size, uint8_t alignment, uint32_t permissions, Alloc
}
break;
}
-
-
+
+
lldb::addr_t mask = alignment - 1;
aligned_address = (allocation_address + mask) & (~mask);
@@ -319,11 +317,11 @@ IRMemoryMap::Malloc (size_t size, uint8_t alignment, uint32_t permissions, Alloc
permissions,
alignment,
policy);
-
- if (lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS))
+
+ if (log)
{
const char * policy_string;
-
+
switch (policy)
{
default:
@@ -339,7 +337,7 @@ IRMemoryMap::Malloc (size_t size, uint8_t alignment, uint32_t permissions, Alloc
policy_string = "eAllocationPolicyMirror";
break;
}
-
+
log->Printf("IRMemoryMap::Malloc (%" PRIu64 ", 0x%" PRIx64 ", 0x%" PRIx64 ", %s) -> 0x%" PRIx64,
(uint64_t)allocation_size,
(uint64_t)alignment,
@@ -347,7 +345,7 @@ IRMemoryMap::Malloc (size_t size, uint8_t alignment, uint32_t permissions, Alloc
policy_string,
aligned_address);
}
-
+
return aligned_address;
}
@@ -355,16 +353,16 @@ void
IRMemoryMap::Leak (lldb::addr_t process_address, Error &error)
{
error.Clear();
-
+
AllocationMap::iterator iter = m_allocations.find(process_address);
-
+
if (iter == m_allocations.end())
{
error.SetErrorToGenericError();
error.SetErrorString("Couldn't leak: allocation doesn't exist");
return;
}
-
+
Allocation &allocation = iter->second;
allocation.m_leak = true;
@@ -374,18 +372,18 @@ void
IRMemoryMap::Free (lldb::addr_t process_address, Error &error)
{
error.Clear();
-
+
AllocationMap::iterator iter = m_allocations.find(process_address);
-
+
if (iter == m_allocations.end())
{
error.SetErrorToGenericError();
error.SetErrorString("Couldn't free: allocation doesn't exist");
return;
}
-
+
Allocation &allocation = iter->second;
-
+
switch (allocation.m_policy)
{
default:
@@ -397,7 +395,7 @@ IRMemoryMap::Free (lldb::addr_t process_address, Error &error)
if (process_sp->CanJIT() && process_sp->IsAlive())
process_sp->DeallocateMemory(allocation.m_process_alloc); // FindSpace allocated this for real
}
-
+
break;
}
case eAllocationPolicyMirror:
@@ -408,15 +406,15 @@ IRMemoryMap::Free (lldb::addr_t process_address, Error &error)
process_sp->DeallocateMemory(allocation.m_process_alloc);
}
}
-
+
if (lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS))
- {
+ {
log->Printf("IRMemoryMap::Free (0x%" PRIx64 ") freed [0x%" PRIx64 "..0x%" PRIx64 ")",
(uint64_t)process_address,
iter->second.m_process_start,
iter->second.m_process_start + iter->second.m_size);
}
-
+
m_allocations.erase(iter);
}
@@ -424,28 +422,28 @@ void
IRMemoryMap::WriteMemory (lldb::addr_t process_address, const uint8_t *bytes, size_t size, Error &error)
{
error.Clear();
-
+
AllocationMap::iterator iter = FindAllocation(process_address, size);
-
+
if (iter == m_allocations.end())
{
lldb::ProcessSP process_sp = m_process_wp.lock();
-
+
if (process_sp)
{
process_sp->WriteMemory(process_address, bytes, size, error);
return;
}
-
+
error.SetErrorToGenericError();
error.SetErrorString("Couldn't write: no allocation contains the target range and the process doesn't exist");
return;
}
-
+
Allocation &allocation = iter->second;
-
+
uint64_t offset = process_address - allocation.m_process_start;
-
+
lldb::ProcessSP process_sp;
switch (allocation.m_policy)
@@ -489,9 +487,9 @@ IRMemoryMap::WriteMemory (lldb::addr_t process_address, const uint8_t *bytes, si
}
break;
}
-
+
if (lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS))
- {
+ {
log->Printf("IRMemoryMap::WriteMemory (0x%" PRIx64 ", 0x%" PRIx64 ", 0x%" PRId64 ") went to [0x%" PRIx64 "..0x%" PRIx64 ")",
(uint64_t)process_address,
(uint64_t)bytes,
@@ -505,10 +503,10 @@ void
IRMemoryMap::WriteScalarToMemory (lldb::addr_t process_address, Scalar &scalar, size_t size, Error &error)
{
error.Clear();
-
+
if (size == UINT32_MAX)
size = scalar.GetByteSize();
-
+
if (size > 0)
{
uint8_t buf[32];
@@ -535,9 +533,9 @@ void
IRMemoryMap::WritePointerToMemory (lldb::addr_t process_address, lldb::addr_t address, Error &error)
{
error.Clear();
-
+
Scalar scalar(address);
-
+
WriteScalarToMemory(process_address, scalar, GetAddressByteSize(), error);
}
@@ -545,39 +543,46 @@ void
IRMemoryMap::ReadMemory (uint8_t *bytes, lldb::addr_t process_address, size_t size, Error &error)
{
error.Clear();
-
+
AllocationMap::iterator iter = FindAllocation(process_address, size);
-
+
if (iter == m_allocations.end())
{
lldb::ProcessSP process_sp = m_process_wp.lock();
-
+
if (process_sp)
{
process_sp->ReadMemory(process_address, bytes, size, error);
return;
}
-
+
lldb::TargetSP target_sp = m_target_wp.lock();
-
+
if (target_sp)
{
Address absolute_address(process_address);
target_sp->ReadMemory(absolute_address, false, bytes, size, error);
return;
}
-
+
error.SetErrorToGenericError();
error.SetErrorString("Couldn't read: no allocation contains the target range, and neither the process nor the target exist");
return;
}
-
+
Allocation &allocation = iter->second;
-
+
uint64_t offset = process_address - allocation.m_process_start;
-
+
+ if (offset > allocation.m_size)
+ {
+ error.SetErrorToGenericError();
+ error.SetErrorString("Couldn't read: data is not in the allocation");
+ return;
+ }
+
lldb::ProcessSP process_sp;
-
+
switch (allocation.m_policy)
{
default:
@@ -591,6 +596,13 @@ IRMemoryMap::ReadMemory (uint8_t *bytes, lldb::addr_t process_address, size_t si
error.SetErrorString("Couldn't read: data buffer is empty");
return;
}
+ if (allocation.m_data.GetByteSize() < offset + size)
+ {
+ error.SetErrorToGenericError();
+ error.SetErrorString("Couldn't read: not enough underlying data");
+ return;
+ }
+
::memcpy (bytes, allocation.m_data.GetBytes() + offset, size);
break;
case eAllocationPolicyMirror:
@@ -622,7 +634,7 @@ IRMemoryMap::ReadMemory (uint8_t *bytes, lldb::addr_t process_address, size_t si
}
break;
}
-
+
if (lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS))
{
log->Printf("IRMemoryMap::ReadMemory (0x%" PRIx64 ", 0x%" PRIx64 ", 0x%" PRId64 ") came from [0x%" PRIx64 "..0x%" PRIx64 ")",
@@ -638,19 +650,19 @@ void
IRMemoryMap::ReadScalarFromMemory (Scalar &scalar, lldb::addr_t process_address, size_t size, Error &error)
{
error.Clear();
-
+
if (size > 0)
{
DataBufferHeap buf(size, 0);
ReadMemory(buf.GetBytes(), process_address, size, error);
-
+
if (!error.Success())
return;
-
+
DataExtractor extractor(buf.GetBytes(), buf.GetByteSize(), GetByteOrder(), GetAddressByteSize());
-
+
lldb::offset_t offset = 0;
-
+
switch (size)
{
default:
@@ -675,15 +687,15 @@ void
IRMemoryMap::ReadPointerFromMemory (lldb::addr_t *address, lldb::addr_t process_address, Error &error)
{
error.Clear();
-
+
Scalar pointer_scalar;
ReadScalarFromMemory(pointer_scalar, process_address, GetAddressByteSize(), error);
-
+
if (!error.Success())
return;
-
+
*address = pointer_scalar.ULongLong();
-
+
return;
}
@@ -691,20 +703,20 @@ void
IRMemoryMap::GetMemoryData (DataExtractor &extractor, lldb::addr_t process_address, size_t size, Error &error)
{
error.Clear();
-
+
if (size > 0)
{
AllocationMap::iterator iter = FindAllocation(process_address, size);
-
+
if (iter == m_allocations.end())
{
error.SetErrorToGenericError();
error.SetErrorStringWithFormat("Couldn't find an allocation containing [0x%" PRIx64 "..0x%" PRIx64 ")", process_address, process_address + size);
return;
}
-
+
Allocation &allocation = iter->second;
-
+
switch (allocation.m_policy)
{
default:
@@ -754,5 +766,3 @@ IRMemoryMap::GetMemoryData (DataExtractor &extractor, lldb::addr_t process_addre
return;
}
}
-
-
diff --git a/contrib/llvm/tools/lldb/source/Expression/Materializer.cpp b/contrib/llvm/tools/lldb/source/Expression/Materializer.cpp
index 90687c0..b119216 100644
--- a/contrib/llvm/tools/lldb/source/Expression/Materializer.cpp
+++ b/contrib/llvm/tools/lldb/source/Expression/Materializer.cpp
@@ -95,7 +95,7 @@ public:
}
if (log)
- log->Printf("Allocated %s (0x%" PRIx64 ") sucessfully", m_persistent_variable_sp->GetName().GetCString(), mem);
+ log->Printf("Allocated %s (0x%" PRIx64 ") successfully", m_persistent_variable_sp->GetName().GetCString(), mem);
// Put the location of the spare memory into the live data of the ValueObject.
@@ -443,10 +443,26 @@ public:
return;
}
+ Error valobj_error = valobj_sp->GetError();
+
+ if (valobj_error.Fail())
+ {
+ err.SetErrorStringWithFormat("couldn't get the value of variable %s: %s", m_variable_sp->GetName().AsCString(), valobj_error.AsCString());
+ return;
+ }
+
if (m_is_reference)
{
DataExtractor valobj_extractor;
- valobj_sp->GetData(valobj_extractor);
+ Error extract_error;
+ valobj_sp->GetData(valobj_extractor, extract_error);
+
+ if (!extract_error.Success())
+ {
+ err.SetErrorStringWithFormat("couldn't read contents of reference variable %s: %s", m_variable_sp->GetName().AsCString(), extract_error.AsCString());
+ return;
+ }
+
lldb::offset_t offset = 0;
lldb::addr_t reference_addr = valobj_extractor.GetAddress(&offset);
@@ -478,8 +494,14 @@ public:
else
{
DataExtractor data;
- valobj_sp->GetData(data);
-
+ Error extract_error;
+ valobj_sp->GetData(data, extract_error);
+ if (!extract_error.Success())
+ {
+ err.SetErrorStringWithFormat("couldn't get the value of %s: %s", m_variable_sp->GetName().AsCString(), extract_error.AsCString());
+ return;
+ }
+
if (m_temporary_allocation != LLDB_INVALID_ADDRESS)
{
err.SetErrorStringWithFormat("trying to create a temporary region for %s but one exists", m_variable_sp->GetName().AsCString());
@@ -513,6 +535,8 @@ public:
m_temporary_allocation = map.Malloc(data.GetByteSize(), byte_align, lldb::ePermissionsReadable | lldb::ePermissionsWritable, IRMemoryMap::eAllocationPolicyMirror, alloc_error);
m_temporary_allocation_size = data.GetByteSize();
+ m_original_data.reset(new DataBufferHeap(data.GetDataStart(), data.GetByteSize()));
+
if (!alloc_error.Success())
{
err.SetErrorStringWithFormat("couldn't allocate a temporary region for %s: %s", m_variable_sp->GetName().AsCString(), alloc_error.AsCString());
@@ -585,14 +609,28 @@ public:
return;
}
- Error set_error;
+ bool actually_write = true;
- valobj_sp->SetData(data, set_error);
+ if (m_original_data)
+ {
+ if ((data.GetByteSize() == m_original_data->GetByteSize()) &&
+ !memcmp(m_original_data->GetBytes(), data.GetDataStart(), data.GetByteSize()))
+ {
+ actually_write = false;
+ }
+ }
- if (!set_error.Success())
+ Error set_error;
+
+ if (actually_write)
{
- err.SetErrorStringWithFormat("couldn't write the new contents of %s back into the variable", m_variable_sp->GetName().AsCString());
- return;
+ valobj_sp->SetData(data, set_error);
+
+ if (!set_error.Success())
+ {
+ err.SetErrorStringWithFormat("couldn't write the new contents of %s back into the variable", m_variable_sp->GetName().AsCString());
+ return;
+ }
}
Error free_error;
@@ -605,6 +643,7 @@ public:
return;
}
+ m_original_data.reset();
m_temporary_allocation = LLDB_INVALID_ADDRESS;
m_temporary_allocation_size = 0;
}
@@ -700,6 +739,7 @@ private:
bool m_is_reference;
lldb::addr_t m_temporary_allocation;
size_t m_temporary_allocation_size;
+ lldb::DataBufferSP m_original_data;
};
uint32_t
@@ -1312,43 +1352,44 @@ Materializer::DematerializerSP
Materializer::Materialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &error)
{
ExecutionContextScope *exe_scope = frame_sp.get();
-
+
if (!exe_scope)
exe_scope = map.GetBestExecutionContextScope();
-
+
DematerializerSP dematerializer_sp = m_dematerializer_wp.lock();
-
+
if (dematerializer_sp)
{
error.SetErrorToGenericError();
error.SetErrorString("Couldn't materialize: already materialized");
}
-
+
DematerializerSP ret(new Dematerializer(*this, frame_sp, map, process_address));
-
+
if (!exe_scope)
{
error.SetErrorToGenericError();
error.SetErrorString("Couldn't materialize: target doesn't exist");
}
-
+
for (EntityUP &entity_up : m_entities)
{
entity_up->Materialize(frame_sp, map, process_address, error);
-
+
if (!error.Success())
return DematerializerSP();
}
-
+
if (Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS))
{
- log->Printf("Materializer::Materialize (frame_sp = %p, process_address = 0x%" PRIx64 ") materialized:", frame_sp.get(), process_address);
+ log->Printf("Materializer::Materialize (frame_sp = %p, process_address = 0x%" PRIx64 ") materialized:",
+ static_cast<void*>(frame_sp.get()), process_address);
for (EntityUP &entity_up : m_entities)
entity_up->DumpToLog(map, process_address, log);
}
-
+
m_dematerializer_wp = ret;
-
+
return ret;
}
@@ -1360,15 +1401,15 @@ Materializer::Dematerializer::Dematerialize (Error &error, lldb::ClangExpression
lldb::ThreadSP thread_sp = m_thread_wp.lock();
if (thread_sp)
frame_sp = thread_sp->GetFrameWithStackID(m_stack_id);
-
+
ExecutionContextScope *exe_scope = m_map->GetBestExecutionContextScope();
-
+
if (!IsValid())
{
error.SetErrorToGenericError();
error.SetErrorString("Couldn't dematerialize: invalid dematerializer");
}
-
+
if (!exe_scope)
{
error.SetErrorToGenericError();
@@ -1378,11 +1419,12 @@ Materializer::Dematerializer::Dematerialize (Error &error, lldb::ClangExpression
{
if (Log *log =lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS))
{
- log->Printf("Materializer::Dematerialize (frame_sp = %p, process_address = 0x%" PRIx64 ") about to dematerialize:", frame_sp.get(), m_process_address);
+ log->Printf("Materializer::Dematerialize (frame_sp = %p, process_address = 0x%" PRIx64 ") about to dematerialize:",
+ static_cast<void*>(frame_sp.get()), m_process_address);
for (EntityUP &entity_up : m_materializer->m_entities)
entity_up->DumpToLog(*m_map, m_process_address, log);
}
-
+
for (EntityUP &entity_up : m_materializer->m_entities)
{
if (entity_up.get() == m_materializer->m_result_entity)
@@ -1393,12 +1435,12 @@ Materializer::Dematerializer::Dematerialize (Error &error, lldb::ClangExpression
{
entity_up->Dematerialize (frame_sp, *m_map, m_process_address, frame_top, frame_bottom, error);
}
-
+
if (!error.Success())
break;
}
}
-
+
Wipe();
}
OpenPOWER on IntegriCloud