summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/ExpressionParser
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Plugins/ExpressionParser')
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ASTDumper.cpp162
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ASTDumper.h33
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp795
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.h357
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ASTStructExtractor.cpp277
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ASTStructExtractor.h246
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp3146
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.h937
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangDiagnostic.h58
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp3645
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h1226
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionHelper.h75
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp1639
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h254
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.cpp79
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.h359
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp317
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.h195
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp1215
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h197
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp106
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h127
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp1093
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h302
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp210
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.h152
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp3143
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.h1191
-rw-r--r--lldb/source/Plugins/ExpressionParser/Go/GoAST.h4405
-rw-r--r--lldb/source/Plugins/ExpressionParser/Go/GoLexer.cpp650
-rw-r--r--lldb/source/Plugins/ExpressionParser/Go/GoLexer.h322
-rw-r--r--lldb/source/Plugins/ExpressionParser/Go/GoParser.cpp1717
-rw-r--r--lldb/source/Plugins/ExpressionParser/Go/GoParser.h272
-rw-r--r--lldb/source/Plugins/ExpressionParser/Go/GoUserExpression.cpp1154
-rw-r--r--lldb/source/Plugins/ExpressionParser/Go/GoUserExpression.h108
-rw-r--r--lldb/source/Plugins/ExpressionParser/Go/gen_go_ast.py150
36 files changed, 14043 insertions, 16271 deletions
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ASTDumper.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ASTDumper.cpp
index 0b819948115..3c20b516c10 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ASTDumper.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ASTDumper.cpp
@@ -18,118 +18,94 @@
using namespace lldb_private;
-ASTDumper::ASTDumper (clang::Decl *decl)
-{
- clang::DeclContext *decl_ctx = llvm::dyn_cast<clang::DeclContext>(decl);
-
- bool has_external_lexical_storage;
- bool has_external_visible_storage;
-
- if (decl_ctx)
- {
- has_external_lexical_storage = decl_ctx->hasExternalLexicalStorage();
- has_external_visible_storage = decl_ctx->hasExternalVisibleStorage();
- decl_ctx->setHasExternalLexicalStorage(false);
- decl_ctx->setHasExternalVisibleStorage(false);
- }
-
- llvm::raw_string_ostream os(m_dump);
- decl->print (os);
- os.flush();
-
- if (decl_ctx)
- {
- decl_ctx->setHasExternalLexicalStorage(has_external_lexical_storage);
- decl_ctx->setHasExternalVisibleStorage(has_external_visible_storage);
- }
-}
+ASTDumper::ASTDumper(clang::Decl *decl) {
+ clang::DeclContext *decl_ctx = llvm::dyn_cast<clang::DeclContext>(decl);
+
+ bool has_external_lexical_storage;
+ bool has_external_visible_storage;
-ASTDumper::ASTDumper (clang::DeclContext *decl_ctx)
-{
- bool has_external_lexical_storage = decl_ctx->hasExternalLexicalStorage();
- bool has_external_visible_storage = decl_ctx->hasExternalVisibleStorage();
-
+ if (decl_ctx) {
+ has_external_lexical_storage = decl_ctx->hasExternalLexicalStorage();
+ has_external_visible_storage = decl_ctx->hasExternalVisibleStorage();
decl_ctx->setHasExternalLexicalStorage(false);
decl_ctx->setHasExternalVisibleStorage(false);
-
- if (clang::Decl *decl = llvm::dyn_cast<clang::Decl>(decl_ctx))
- {
- llvm::raw_string_ostream os(m_dump);
- decl->print (os);
- os.flush();
- }
- else
- {
- m_dump.assign("<DeclContext is not a Decl>");
- }
-
+ }
+
+ llvm::raw_string_ostream os(m_dump);
+ decl->print(os);
+ os.flush();
+
+ if (decl_ctx) {
decl_ctx->setHasExternalLexicalStorage(has_external_lexical_storage);
decl_ctx->setHasExternalVisibleStorage(has_external_visible_storage);
+ }
}
-ASTDumper::ASTDumper (const clang::Type *type)
-{
- m_dump = clang::QualType(type, 0).getAsString();
-}
+ASTDumper::ASTDumper(clang::DeclContext *decl_ctx) {
+ bool has_external_lexical_storage = decl_ctx->hasExternalLexicalStorage();
+ bool has_external_visible_storage = decl_ctx->hasExternalVisibleStorage();
-ASTDumper::ASTDumper (clang::QualType type)
-{
- m_dump = type.getAsString();
-}
+ decl_ctx->setHasExternalLexicalStorage(false);
+ decl_ctx->setHasExternalVisibleStorage(false);
+
+ if (clang::Decl *decl = llvm::dyn_cast<clang::Decl>(decl_ctx)) {
+ llvm::raw_string_ostream os(m_dump);
+ decl->print(os);
+ os.flush();
+ } else {
+ m_dump.assign("<DeclContext is not a Decl>");
+ }
-ASTDumper::ASTDumper (lldb::opaque_compiler_type_t type)
-{
- m_dump = clang::QualType::getFromOpaquePtr(type).getAsString();
+ decl_ctx->setHasExternalLexicalStorage(has_external_lexical_storage);
+ decl_ctx->setHasExternalVisibleStorage(has_external_visible_storage);
}
-ASTDumper::ASTDumper (const CompilerType &compiler_type)
-{
- m_dump = ClangUtil::GetQualType(compiler_type).getAsString();
+ASTDumper::ASTDumper(const clang::Type *type) {
+ m_dump = clang::QualType(type, 0).getAsString();
}
+ASTDumper::ASTDumper(clang::QualType type) { m_dump = type.getAsString(); }
-const char *
-ASTDumper::GetCString()
-{
- return m_dump.c_str();
+ASTDumper::ASTDumper(lldb::opaque_compiler_type_t type) {
+ m_dump = clang::QualType::getFromOpaquePtr(type).getAsString();
}
-void ASTDumper::ToSTDERR()
-{
- fprintf(stderr, "%s\n", m_dump.c_str());
+ASTDumper::ASTDumper(const CompilerType &compiler_type) {
+ m_dump = ClangUtil::GetQualType(compiler_type).getAsString();
}
-void ASTDumper::ToLog(Log *log, const char *prefix)
-{
- size_t len = m_dump.length() + 1;
-
- char *alloc = (char*)malloc(len);
- char *str = alloc;
-
- memcpy(str, m_dump.c_str(), len);
-
- char *end = NULL;
-
- end = strchr(str, '\n');
-
- while (end)
- {
- *end = '\0';
-
- log->Printf("%s%s", prefix, str);
-
- *end = '\n';
-
- str = end + 1;
- end = strchr(str, '\n');
- }
-
+const char *ASTDumper::GetCString() { return m_dump.c_str(); }
+
+void ASTDumper::ToSTDERR() { fprintf(stderr, "%s\n", m_dump.c_str()); }
+
+void ASTDumper::ToLog(Log *log, const char *prefix) {
+ size_t len = m_dump.length() + 1;
+
+ char *alloc = (char *)malloc(len);
+ char *str = alloc;
+
+ memcpy(str, m_dump.c_str(), len);
+
+ char *end = NULL;
+
+ end = strchr(str, '\n');
+
+ while (end) {
+ *end = '\0';
+
log->Printf("%s%s", prefix, str);
-
- free(alloc);
+
+ *end = '\n';
+
+ str = end + 1;
+ end = strchr(str, '\n');
+ }
+
+ log->Printf("%s%s", prefix, str);
+
+ free(alloc);
}
-void ASTDumper::ToStream(lldb::StreamSP &stream)
-{
- stream->PutCString(m_dump.c_str());
+void ASTDumper::ToStream(lldb::StreamSP &stream) {
+ stream->PutCString(m_dump.c_str());
}
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ASTDumper.h b/lldb/source/Plugins/ExpressionParser/Clang/ASTDumper.h
index c8dc6847d6c..9a72fb64e53 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ASTDumper.h
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ASTDumper.h
@@ -16,25 +16,24 @@
#include "lldb/Core/Stream.h"
#include "llvm/ADT/DenseSet.h"
-namespace lldb_private
-{
-
-class ASTDumper
-{
+namespace lldb_private {
+
+class ASTDumper {
public:
- ASTDumper (clang::Decl *decl);
- ASTDumper (clang::DeclContext *decl_ctx);
- ASTDumper (const clang::Type *type);
- ASTDumper (clang::QualType type);
- ASTDumper (lldb::opaque_compiler_type_t type);
- ASTDumper (const CompilerType &compiler_type);
-
- const char *GetCString();
- void ToSTDERR();
- void ToLog(Log *log, const char *prefix);
- void ToStream(lldb::StreamSP &stream);
+ ASTDumper(clang::Decl *decl);
+ ASTDumper(clang::DeclContext *decl_ctx);
+ ASTDumper(const clang::Type *type);
+ ASTDumper(clang::QualType type);
+ ASTDumper(lldb::opaque_compiler_type_t type);
+ ASTDumper(const CompilerType &compiler_type);
+
+ const char *GetCString();
+ void ToSTDERR();
+ void ToLog(Log *log, const char *prefix);
+ void ToStream(lldb::StreamSP &stream);
+
private:
- std::string m_dump;
+ std::string m_dump;
};
} // namespace lldb_private
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp
index f1231572e26..f8539379f7d 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp
@@ -33,542 +33,485 @@ using namespace llvm;
using namespace clang;
using namespace lldb_private;
-ASTResultSynthesizer::ASTResultSynthesizer(ASTConsumer *passthrough, bool top_level, Target &target)
- : m_ast_context(NULL),
- m_passthrough(passthrough),
- m_passthrough_sema(NULL),
- m_target(target),
- m_sema(NULL),
- m_top_level(top_level)
-{
- if (!m_passthrough)
- return;
-
- m_passthrough_sema = dyn_cast<SemaConsumer>(passthrough);
+ASTResultSynthesizer::ASTResultSynthesizer(ASTConsumer *passthrough,
+ bool top_level, Target &target)
+ : m_ast_context(NULL), m_passthrough(passthrough), m_passthrough_sema(NULL),
+ m_target(target), m_sema(NULL), m_top_level(top_level) {
+ if (!m_passthrough)
+ return;
+
+ m_passthrough_sema = dyn_cast<SemaConsumer>(passthrough);
}
-ASTResultSynthesizer::~ASTResultSynthesizer()
-{
-}
+ASTResultSynthesizer::~ASTResultSynthesizer() {}
-void
-ASTResultSynthesizer::Initialize(ASTContext &Context)
-{
- m_ast_context = &Context;
+void ASTResultSynthesizer::Initialize(ASTContext &Context) {
+ m_ast_context = &Context;
- if (m_passthrough)
- m_passthrough->Initialize(Context);
+ if (m_passthrough)
+ m_passthrough->Initialize(Context);
}
-void
-ASTResultSynthesizer::TransformTopLevelDecl(Decl* D)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
- if (NamedDecl *named_decl = dyn_cast<NamedDecl>(D))
- {
- if (log && log->GetVerbose())
- {
- if (named_decl->getIdentifier())
- log->Printf("TransformTopLevelDecl(%s)", named_decl->getIdentifier()->getNameStart());
- else if (ObjCMethodDecl *method_decl = dyn_cast<ObjCMethodDecl>(D))
- log->Printf("TransformTopLevelDecl(%s)", method_decl->getSelector().getAsString().c_str());
- else
- log->Printf("TransformTopLevelDecl(<complex>)");
- }
-
- if (m_top_level)
- {
- RecordPersistentDecl(named_decl);
- }
+void ASTResultSynthesizer::TransformTopLevelDecl(Decl *D) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+
+ if (NamedDecl *named_decl = dyn_cast<NamedDecl>(D)) {
+ if (log && log->GetVerbose()) {
+ if (named_decl->getIdentifier())
+ log->Printf("TransformTopLevelDecl(%s)",
+ named_decl->getIdentifier()->getNameStart());
+ else if (ObjCMethodDecl *method_decl = dyn_cast<ObjCMethodDecl>(D))
+ log->Printf("TransformTopLevelDecl(%s)",
+ method_decl->getSelector().getAsString().c_str());
+ else
+ log->Printf("TransformTopLevelDecl(<complex>)");
+ }
+
+ if (m_top_level) {
+ RecordPersistentDecl(named_decl);
}
+ }
- if (LinkageSpecDecl *linkage_spec_decl = dyn_cast<LinkageSpecDecl>(D))
- {
- RecordDecl::decl_iterator decl_iterator;
+ 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)
- {
- TransformTopLevelDecl(*decl_iterator);
- }
+ for (decl_iterator = linkage_spec_decl->decls_begin();
+ decl_iterator != linkage_spec_decl->decls_end(); ++decl_iterator) {
+ TransformTopLevelDecl(*decl_iterator);
}
- else if (!m_top_level)
- {
- if (ObjCMethodDecl *method_decl = dyn_cast<ObjCMethodDecl>(D))
- {
- if (m_ast_context && !method_decl->getSelector().getAsString().compare("$__lldb_expr:"))
- {
- RecordPersistentTypes(method_decl);
- SynthesizeObjCMethodResult(method_decl);
- }
- }
- else if (FunctionDecl *function_decl = dyn_cast<FunctionDecl>(D))
- {
- if (m_ast_context && !function_decl->getNameInfo().getAsString().compare("$__lldb_expr"))
- {
- RecordPersistentTypes(function_decl);
- SynthesizeFunctionResult(function_decl);
- }
- }
+ } else if (!m_top_level) {
+ if (ObjCMethodDecl *method_decl = dyn_cast<ObjCMethodDecl>(D)) {
+ if (m_ast_context &&
+ !method_decl->getSelector().getAsString().compare("$__lldb_expr:")) {
+ RecordPersistentTypes(method_decl);
+ SynthesizeObjCMethodResult(method_decl);
+ }
+ } else if (FunctionDecl *function_decl = dyn_cast<FunctionDecl>(D)) {
+ if (m_ast_context &&
+ !function_decl->getNameInfo().getAsString().compare("$__lldb_expr")) {
+ RecordPersistentTypes(function_decl);
+ SynthesizeFunctionResult(function_decl);
+ }
}
+ }
}
-bool
-ASTResultSynthesizer::HandleTopLevelDecl(DeclGroupRef D)
-{
- DeclGroupRef::iterator decl_iterator;
+bool ASTResultSynthesizer::HandleTopLevelDecl(DeclGroupRef D) {
+ DeclGroupRef::iterator decl_iterator;
- for (decl_iterator = D.begin();
- decl_iterator != D.end();
- ++decl_iterator)
- {
- Decl *decl = *decl_iterator;
+ for (decl_iterator = D.begin(); decl_iterator != D.end(); ++decl_iterator) {
+ Decl *decl = *decl_iterator;
- TransformTopLevelDecl(decl);
- }
+ TransformTopLevelDecl(decl);
+ }
- if (m_passthrough)
- return m_passthrough->HandleTopLevelDecl(D);
- return true;
+ if (m_passthrough)
+ return m_passthrough->HandleTopLevelDecl(D);
+ return true;
}
-bool
-ASTResultSynthesizer::SynthesizeFunctionResult (FunctionDecl *FunDecl)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+bool ASTResultSynthesizer::SynthesizeFunctionResult(FunctionDecl *FunDecl) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- if (!m_sema)
- return false;
+ if (!m_sema)
+ return false;
- FunctionDecl *function_decl = FunDecl;
+ FunctionDecl *function_decl = FunDecl;
- if (!function_decl)
- return false;
+ if (!function_decl)
+ return false;
- if (log && log->GetVerbose())
- {
- std::string s;
- raw_string_ostream os(s);
+ if (log && log->GetVerbose()) {
+ std::string s;
+ raw_string_ostream os(s);
- function_decl->print(os);
+ function_decl->print(os);
- os.flush();
+ os.flush();
- log->Printf ("Untransformed function AST:\n%s", s.c_str());
- }
+ log->Printf("Untransformed function AST:\n%s", s.c_str());
+ }
- Stmt *function_body = function_decl->getBody();
- CompoundStmt *compound_stmt = dyn_cast<CompoundStmt>(function_body);
+ Stmt *function_body = function_decl->getBody();
+ CompoundStmt *compound_stmt = dyn_cast<CompoundStmt>(function_body);
- bool ret = SynthesizeBodyResult (compound_stmt,
- function_decl);
+ bool ret = SynthesizeBodyResult(compound_stmt, function_decl);
- if (log && log->GetVerbose())
- {
- std::string s;
- raw_string_ostream os(s);
+ if (log && log->GetVerbose()) {
+ std::string s;
+ raw_string_ostream os(s);
- function_decl->print(os);
+ function_decl->print(os);
- os.flush();
+ os.flush();
- log->Printf ("Transformed function AST:\n%s", s.c_str());
- }
+ log->Printf("Transformed function AST:\n%s", s.c_str());
+ }
- return ret;
+ return ret;
}
-bool
-ASTResultSynthesizer::SynthesizeObjCMethodResult (ObjCMethodDecl *MethodDecl)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+bool ASTResultSynthesizer::SynthesizeObjCMethodResult(
+ ObjCMethodDecl *MethodDecl) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- if (!m_sema)
- return false;
+ if (!m_sema)
+ return false;
- if (!MethodDecl)
- return false;
+ if (!MethodDecl)
+ return false;
- if (log && log->GetVerbose())
- {
- std::string s;
- raw_string_ostream os(s);
+ if (log && log->GetVerbose()) {
+ std::string s;
+ raw_string_ostream os(s);
- MethodDecl->print(os);
+ MethodDecl->print(os);
- os.flush();
+ os.flush();
- log->Printf ("Untransformed method AST:\n%s", s.c_str());
- }
+ log->Printf("Untransformed method AST:\n%s", s.c_str());
+ }
- Stmt *method_body = MethodDecl->getBody();
+ Stmt *method_body = MethodDecl->getBody();
- if (!method_body)
- return false;
+ if (!method_body)
+ return false;
- CompoundStmt *compound_stmt = dyn_cast<CompoundStmt>(method_body);
+ CompoundStmt *compound_stmt = dyn_cast<CompoundStmt>(method_body);
- bool ret = SynthesizeBodyResult (compound_stmt,
- MethodDecl);
+ bool ret = SynthesizeBodyResult(compound_stmt, MethodDecl);
- if (log && log->GetVerbose())
- {
- std::string s;
- raw_string_ostream os(s);
+ if (log && log->GetVerbose()) {
+ std::string s;
+ raw_string_ostream os(s);
- MethodDecl->print(os);
+ MethodDecl->print(os);
- os.flush();
+ os.flush();
- log->Printf("Transformed method AST:\n%s", s.c_str());
- }
+ log->Printf("Transformed method AST:\n%s", s.c_str());
+ }
- return ret;
+ return ret;
}
-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())
- {
- last_stmt_ptr--;
- last_stmt = *last_stmt_ptr;
- }
- else
- {
- return false;
- }
- }
+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;
- 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.
- //
- // For Lvalues
- //
- // - In AST result synthesis (here!) the expression E is transformed into an initialization
- // T *$__lldb_expr_result_ptr = &E.
- //
- // - In structure allocation, a pointer-sized slot is allocated in the struct that is to be
- // passed into the expression.
- //
- // - In IR transformations, reads and writes to $__lldb_expr_result_ptr are redirected at
- // an entry in the struct ($__lldb_arg) passed into the expression. (Other persistent
- // variables are treated similarly, having been materialized as references, but in those
- // cases the value of the reference itself is never modified.)
- //
- // - During materialization, $0 (the result persistent variable) is ignored.
- //
- // - During dematerialization, $0 is marked up as a load address with value equal to the
- // contents of the structure entry.
- //
- // For Rvalues
- //
- // - In AST result synthesis the expression E is transformed into an initialization
- // static T $__lldb_expr_result = E.
- //
- // - In structure allocation, a pointer-sized slot is allocated in the struct that is to be
- // passed into the expression.
- //
- // - 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 excised.
- //
- // - During materialization, $0 (the result persistent variable) is populated with the location
- // of a newly-allocated area of memory.
- //
- // - During dematerialization, $0 is ignored.
-
- 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());
+ while (dyn_cast<NullStmt>(last_stmt)) {
+ if (last_stmt_ptr != Body->body_begin()) {
+ last_stmt_ptr--;
+ last_stmt = *last_stmt_ptr;
+ } else {
+ return false;
}
+ }
- clang::VarDecl *result_decl = NULL;
+ Expr *last_expr = dyn_cast<Expr>(last_stmt);
- if (is_lvalue)
- {
- IdentifierInfo *result_ptr_id;
+ if (!last_expr)
+ // No auxiliary variable necessary; expression returns void
+ return true;
- 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");
+ // 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.
+ //
+ // For Lvalues
+ //
+ // - In AST result synthesis (here!) the expression E is transformed into an
+ // initialization
+ // T *$__lldb_expr_result_ptr = &E.
+ //
+ // - In structure allocation, a pointer-sized slot is allocated in the
+ // struct that is to be
+ // passed into the expression.
+ //
+ // - In IR transformations, reads and writes to $__lldb_expr_result_ptr are
+ // redirected at
+ // an entry in the struct ($__lldb_arg) passed into the expression.
+ // (Other persistent
+ // variables are treated similarly, having been materialized as
+ // references, but in those
+ // cases the value of the reference itself is never modified.)
+ //
+ // - During materialization, $0 (the result persistent variable) is ignored.
+ //
+ // - During dematerialization, $0 is marked up as a load address with value
+ // equal to the
+ // contents of the structure entry.
+ //
+ // For Rvalues
+ //
+ // - In AST result synthesis the expression E is transformed into an
+ // initialization
+ // static T $__lldb_expr_result = E.
+ //
+ // - In structure allocation, a pointer-sized slot is allocated in the
+ // struct that is to be
+ // passed into the expression.
+ //
+ // - 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 excised.
+ //
+ // - During materialization, $0 (the result persistent variable) is
+ // populated with the location
+ // of a newly-allocated area of memory.
+ //
+ // - During dematerialization, $0 is ignored.
+
+ 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;
- m_sema->RequireCompleteType(SourceLocation(), expr_qual_type, clang::diag::err_incomplete_type);
+ if (log) {
+ std::string s = expr_qual_type.getAsString();
- QualType ptr_qual_type;
+ log->Printf("Last statement is an %s with type: %s",
+ (is_lvalue ? "lvalue" : "rvalue"), s.c_str());
+ }
- if (expr_qual_type->getAs<ObjCObjectType>() != NULL)
- ptr_qual_type = Ctx.getObjCObjectPointerType(expr_qual_type);
- else
- ptr_qual_type = Ctx.getPointerType(expr_qual_type);
+ clang::VarDecl *result_decl = NULL;
- result_decl = VarDecl::Create(Ctx,
- DC,
- SourceLocation(),
- SourceLocation(),
- result_ptr_id,
- ptr_qual_type,
- NULL,
- SC_Static);
+ if (is_lvalue) {
+ IdentifierInfo *result_ptr_id;
- if (!result_decl)
- return false;
+ 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");
- ExprResult address_of_expr = m_sema->CreateBuiltinUnaryOp(SourceLocation(), UO_AddrOf, last_expr);
- if (address_of_expr.get())
- m_sema->AddInitializerToDecl(result_decl, address_of_expr.get(), true, false);
- else
- return false;
- }
+ 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
- {
- IdentifierInfo &result_id = Ctx.Idents.get("$__lldb_expr_result");
-
- result_decl = VarDecl::Create(Ctx,
- DC,
- SourceLocation(),
- SourceLocation(),
- &result_id,
- expr_qual_type,
- NULL,
- SC_Static);
-
- if (!result_decl)
- return false;
-
- m_sema->AddInitializerToDecl(result_decl, last_expr, true, false);
- }
+ ptr_qual_type = Ctx.getPointerType(expr_qual_type);
+
+ result_decl =
+ VarDecl::Create(Ctx, DC, SourceLocation(), SourceLocation(),
+ result_ptr_id, ptr_qual_type, NULL, SC_Static);
- DC->addDecl(result_decl);
+ if (!result_decl)
+ return false;
- ///////////////////////////////
- // call AddInitializerToDecl
- //
+ ExprResult address_of_expr =
+ m_sema->CreateBuiltinUnaryOp(SourceLocation(), UO_AddrOf, last_expr);
+ if (address_of_expr.get())
+ m_sema->AddInitializerToDecl(result_decl, address_of_expr.get(), true,
+ false);
+ else
+ return false;
+ } else {
+ IdentifierInfo &result_id = Ctx.Idents.get("$__lldb_expr_result");
- //m_sema->AddInitializerToDecl(result_decl, last_expr);
+ result_decl = VarDecl::Create(Ctx, DC, SourceLocation(), SourceLocation(),
+ &result_id, expr_qual_type, NULL, SC_Static);
- /////////////////////////////////
- // call ConvertDeclToDeclGroup
- //
+ if (!result_decl)
+ return false;
- Sema::DeclGroupPtrTy result_decl_group_ptr;
+ m_sema->AddInitializerToDecl(result_decl, last_expr, true, false);
+ }
- result_decl_group_ptr = m_sema->ConvertDeclToDeclGroup(result_decl);
+ DC->addDecl(result_decl);
- ////////////////////////
- // call ActOnDeclStmt
- //
+ ///////////////////////////////
+ // call AddInitializerToDecl
+ //
- StmtResult result_initialization_stmt_result(m_sema->ActOnDeclStmt(result_decl_group_ptr,
- SourceLocation(),
- SourceLocation()));
+ // m_sema->AddInitializerToDecl(result_decl, last_expr);
- ////////////////////////////////////////////////
- // replace the old statement with the new one
- //
+ /////////////////////////////////
+ // call ConvertDeclToDeclGroup
+ //
- *last_stmt_ptr = reinterpret_cast<Stmt*>(result_initialization_stmt_result.get());
+ Sema::DeclGroupPtrTy result_decl_group_ptr;
- return true;
+ 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.get());
+
+ return true;
}
-void
-ASTResultSynthesizer::HandleTranslationUnit(ASTContext &Ctx)
-{
- if (m_passthrough)
- m_passthrough->HandleTranslationUnit(Ctx);
+void ASTResultSynthesizer::HandleTranslationUnit(ASTContext &Ctx) {
+ if (m_passthrough)
+ m_passthrough->HandleTranslationUnit(Ctx);
}
-void
-ASTResultSynthesizer::RecordPersistentTypes(DeclContext *FunDeclCtx)
-{
- typedef DeclContext::specific_decl_iterator<TypeDecl> TypeDeclIterator;
-
- for (TypeDeclIterator i = TypeDeclIterator(FunDeclCtx->decls_begin()),
- e = TypeDeclIterator(FunDeclCtx->decls_end());
- i != e;
- ++i)
- {
- MaybeRecordPersistentType(*i);
- }
+void ASTResultSynthesizer::RecordPersistentTypes(DeclContext *FunDeclCtx) {
+ typedef DeclContext::specific_decl_iterator<TypeDecl> TypeDeclIterator;
+
+ for (TypeDeclIterator i = TypeDeclIterator(FunDeclCtx->decls_begin()),
+ e = TypeDeclIterator(FunDeclCtx->decls_end());
+ i != e; ++i) {
+ MaybeRecordPersistentType(*i);
+ }
}
-void
-ASTResultSynthesizer::MaybeRecordPersistentType(TypeDecl *D)
-{
- if (!D->getIdentifier())
- return;
+void ASTResultSynthesizer::MaybeRecordPersistentType(TypeDecl *D) {
+ if (!D->getIdentifier())
+ return;
- StringRef name = D->getName();
+ StringRef name = D->getName();
- if (name.size() == 0 || name[0] != '$')
- return;
+ if (name.size() == 0 || name[0] != '$')
+ return;
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- ConstString name_cs(name.str().c_str());
+ ConstString name_cs(name.str().c_str());
- if (log)
- log->Printf("Recording persistent type %s\n", name_cs.GetCString());
+ if (log)
+ log->Printf("Recording persistent type %s\n", name_cs.GetCString());
- m_decls.push_back(D);
+ m_decls.push_back(D);
}
-void
-ASTResultSynthesizer::RecordPersistentDecl(NamedDecl *D)
-{
- lldbassert(m_top_level);
+void ASTResultSynthesizer::RecordPersistentDecl(NamedDecl *D) {
+ lldbassert(m_top_level);
- if (!D->getIdentifier())
- return;
+ if (!D->getIdentifier())
+ return;
- StringRef name = D->getName();
+ StringRef name = D->getName();
- if (name.size() == 0)
- return;
+ if (name.size() == 0)
+ return;
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- ConstString name_cs(name.str().c_str());
+ ConstString name_cs(name.str().c_str());
- if (log)
- log->Printf("Recording persistent decl %s\n", name_cs.GetCString());
+ if (log)
+ log->Printf("Recording persistent decl %s\n", name_cs.GetCString());
- m_decls.push_back(D);
+ m_decls.push_back(D);
}
-void
-ASTResultSynthesizer::CommitPersistentDecls()
-{
- for (clang::NamedDecl *decl : m_decls)
- {
- StringRef name = decl->getName();
- ConstString name_cs(name.str().c_str());
-
- Decl *D_scratch = m_target.GetClangASTImporter()->DeportDecl(
- m_target.GetScratchClangASTContext()->getASTContext(), m_ast_context, decl);
-
- if (!D_scratch)
- {
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
-
- if (log)
- {
- std::string s;
- llvm::raw_string_ostream ss(s);
- decl->dump(ss);
- ss.flush();
-
- log->Printf("Couldn't commit persistent decl: %s\n", s.c_str());
- }
-
- continue;
- }
-
- if (NamedDecl *NamedDecl_scratch = dyn_cast<NamedDecl>(D_scratch))
- llvm::cast<ClangPersistentVariables>(m_target.GetPersistentExpressionStateForLanguage(lldb::eLanguageTypeC))
- ->RegisterPersistentDecl(name_cs, NamedDecl_scratch);
+void ASTResultSynthesizer::CommitPersistentDecls() {
+ for (clang::NamedDecl *decl : m_decls) {
+ StringRef name = decl->getName();
+ ConstString name_cs(name.str().c_str());
+
+ Decl *D_scratch = m_target.GetClangASTImporter()->DeportDecl(
+ m_target.GetScratchClangASTContext()->getASTContext(), m_ast_context,
+ decl);
+
+ if (!D_scratch) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+
+ if (log) {
+ std::string s;
+ llvm::raw_string_ostream ss(s);
+ decl->dump(ss);
+ ss.flush();
+
+ log->Printf("Couldn't commit persistent decl: %s\n", s.c_str());
+ }
+
+ continue;
}
+
+ if (NamedDecl *NamedDecl_scratch = dyn_cast<NamedDecl>(D_scratch))
+ llvm::cast<ClangPersistentVariables>(
+ m_target.GetPersistentExpressionStateForLanguage(
+ lldb::eLanguageTypeC))
+ ->RegisterPersistentDecl(name_cs, NamedDecl_scratch);
+ }
}
-void
-ASTResultSynthesizer::HandleTagDeclDefinition(TagDecl *D)
-{
- if (m_passthrough)
- m_passthrough->HandleTagDeclDefinition(D);
+void ASTResultSynthesizer::HandleTagDeclDefinition(TagDecl *D) {
+ if (m_passthrough)
+ m_passthrough->HandleTagDeclDefinition(D);
}
-void
-ASTResultSynthesizer::CompleteTentativeDefinition(VarDecl *D)
-{
- if (m_passthrough)
- m_passthrough->CompleteTentativeDefinition(D);
+void ASTResultSynthesizer::CompleteTentativeDefinition(VarDecl *D) {
+ if (m_passthrough)
+ m_passthrough->CompleteTentativeDefinition(D);
}
-void
-ASTResultSynthesizer::HandleVTable(CXXRecordDecl *RD)
-{
- if (m_passthrough)
- m_passthrough->HandleVTable(RD);
+void ASTResultSynthesizer::HandleVTable(CXXRecordDecl *RD) {
+ if (m_passthrough)
+ m_passthrough->HandleVTable(RD);
}
-void
-ASTResultSynthesizer::PrintStats()
-{
- if (m_passthrough)
- m_passthrough->PrintStats();
+void ASTResultSynthesizer::PrintStats() {
+ if (m_passthrough)
+ m_passthrough->PrintStats();
}
-void
-ASTResultSynthesizer::InitializeSema(Sema &S)
-{
- m_sema = &S;
+void ASTResultSynthesizer::InitializeSema(Sema &S) {
+ m_sema = &S;
- if (m_passthrough_sema)
- m_passthrough_sema->InitializeSema(S);
+ if (m_passthrough_sema)
+ m_passthrough_sema->InitializeSema(S);
}
-void
-ASTResultSynthesizer::ForgetSema()
-{
- m_sema = NULL;
+void ASTResultSynthesizer::ForgetSema() {
+ m_sema = NULL;
- if (m_passthrough_sema)
- m_passthrough_sema->ForgetSema();
+ if (m_passthrough_sema)
+ m_passthrough_sema->ForgetSema();
}
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.h b/lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.h
index 4556713e993..c0e6c0358a2 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.h
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.h
@@ -10,201 +10,204 @@
#ifndef liblldb_ASTResultSynthesizer_h_
#define liblldb_ASTResultSynthesizer_h_
-#include "clang/Sema/SemaConsumer.h"
#include "lldb/Core/ClangForward.h"
#include "lldb/Target/Target.h"
+#include "clang/Sema/SemaConsumer.h"
namespace lldb_private {
//----------------------------------------------------------------------
-/// @class ASTResultSynthesizer ASTResultSynthesizer.h "lldb/Expression/ASTResultSynthesizer.h"
+/// @class ASTResultSynthesizer ASTResultSynthesizer.h
+/// "lldb/Expression/ASTResultSynthesizer.h"
/// @brief Adds a result variable declaration to the ASTs for an expression.
///
/// Users expect the expression "i + 3" to return a result, even if a result
-/// variable wasn't specifically declared. To fulfil this requirement, LLDB adds
-/// a result variable to the expression, transforming it to
+/// variable wasn't specifically declared. To fulfil this requirement, LLDB
+/// adds
+/// a result variable to the expression, transforming it to
/// "int $__lldb_expr_result = i + 3." The IR transformers ensure that the
/// resulting variable is mapped to the right piece of memory.
/// ASTResultSynthesizer's job is to add the variable and its initialization to
/// the ASTs for the expression, and it does so by acting as a SemaConsumer for
/// Clang.
//----------------------------------------------------------------------
-class ASTResultSynthesizer : public clang::SemaConsumer
-{
+class ASTResultSynthesizer : public clang::SemaConsumer {
public:
- //----------------------------------------------------------------------
- /// Constructor
- ///
- /// @param[in] passthrough
- /// Since the ASTs must typically go through to the Clang code generator
- /// in order to produce LLVM IR, this SemaConsumer must allow them to
- /// pass to the next step in the chain after processing. Passthrough is
- /// the next ASTConsumer, or NULL if none is required.
- ///
- /// @param[in] top_level
- /// If true, register all top-level Decls and don't try to handle the
- /// main function.
- ///
- /// @param[in] target
- /// The target, which contains the persistent variable store and the
- /// AST importer.
- //----------------------------------------------------------------------
- ASTResultSynthesizer(clang::ASTConsumer *passthrough, bool top_level, Target &target);
-
- //----------------------------------------------------------------------
- /// Destructor
- //----------------------------------------------------------------------
- ~ASTResultSynthesizer() override;
-
- //----------------------------------------------------------------------
- /// Link this consumer with a particular AST context
- ///
- /// @param[in] Context
- /// This AST context will be used for types and identifiers, and also
- /// forwarded to the passthrough consumer, if one exists.
- //----------------------------------------------------------------------
- void Initialize(clang::ASTContext &Context) override;
-
- //----------------------------------------------------------------------
- /// Examine a list of Decls to find the function $__lldb_expr and
- /// transform its code
- ///
- /// @param[in] D
- /// The list of Decls to search. These may contain LinkageSpecDecls,
- /// which need to be searched recursively. That job falls to
- /// TransformTopLevelDecl.
- //----------------------------------------------------------------------
- bool HandleTopLevelDecl(clang::DeclGroupRef D) override;
-
- //----------------------------------------------------------------------
- /// Passthrough stub
- //----------------------------------------------------------------------
- void HandleTranslationUnit(clang::ASTContext &Ctx) override;
-
- //----------------------------------------------------------------------
- /// Passthrough stub
- //----------------------------------------------------------------------
- void HandleTagDeclDefinition(clang::TagDecl *D) override;
-
- //----------------------------------------------------------------------
- /// Passthrough stub
- //----------------------------------------------------------------------
- void CompleteTentativeDefinition(clang::VarDecl *D) override;
-
- //----------------------------------------------------------------------
- /// Passthrough stub
- //----------------------------------------------------------------------
- void HandleVTable(clang::CXXRecordDecl *RD) override;
-
- //----------------------------------------------------------------------
- /// Passthrough stub
- //----------------------------------------------------------------------
- void PrintStats() override;
-
- //----------------------------------------------------------------------
- /// Set the Sema object to use when performing transforms, and pass it on
- ///
- /// @param[in] S
- /// The Sema to use. Because Sema isn't externally visible, this class
- /// casts it to an Action for actual use.
- //----------------------------------------------------------------------
- void InitializeSema(clang::Sema &S) override;
-
- //----------------------------------------------------------------------
- /// Reset the Sema to NULL now that transformations are done
- //----------------------------------------------------------------------
- void
- ForgetSema() override;
-
- //----------------------------------------------------------------------
- /// The parse has succeeded, so record its persistent decls
- //----------------------------------------------------------------------
- void
- CommitPersistentDecls();
+ //----------------------------------------------------------------------
+ /// Constructor
+ ///
+ /// @param[in] passthrough
+ /// Since the ASTs must typically go through to the Clang code generator
+ /// in order to produce LLVM IR, this SemaConsumer must allow them to
+ /// pass to the next step in the chain after processing. Passthrough is
+ /// the next ASTConsumer, or NULL if none is required.
+ ///
+ /// @param[in] top_level
+ /// If true, register all top-level Decls and don't try to handle the
+ /// main function.
+ ///
+ /// @param[in] target
+ /// The target, which contains the persistent variable store and the
+ /// AST importer.
+ //----------------------------------------------------------------------
+ ASTResultSynthesizer(clang::ASTConsumer *passthrough, bool top_level,
+ Target &target);
+
+ //----------------------------------------------------------------------
+ /// Destructor
+ //----------------------------------------------------------------------
+ ~ASTResultSynthesizer() override;
+
+ //----------------------------------------------------------------------
+ /// Link this consumer with a particular AST context
+ ///
+ /// @param[in] Context
+ /// This AST context will be used for types and identifiers, and also
+ /// forwarded to the passthrough consumer, if one exists.
+ //----------------------------------------------------------------------
+ void Initialize(clang::ASTContext &Context) override;
+
+ //----------------------------------------------------------------------
+ /// Examine a list of Decls to find the function $__lldb_expr and
+ /// transform its code
+ ///
+ /// @param[in] D
+ /// The list of Decls to search. These may contain LinkageSpecDecls,
+ /// which need to be searched recursively. That job falls to
+ /// TransformTopLevelDecl.
+ //----------------------------------------------------------------------
+ bool HandleTopLevelDecl(clang::DeclGroupRef D) override;
+
+ //----------------------------------------------------------------------
+ /// Passthrough stub
+ //----------------------------------------------------------------------
+ void HandleTranslationUnit(clang::ASTContext &Ctx) override;
+
+ //----------------------------------------------------------------------
+ /// Passthrough stub
+ //----------------------------------------------------------------------
+ void HandleTagDeclDefinition(clang::TagDecl *D) override;
+
+ //----------------------------------------------------------------------
+ /// Passthrough stub
+ //----------------------------------------------------------------------
+ void CompleteTentativeDefinition(clang::VarDecl *D) override;
+
+ //----------------------------------------------------------------------
+ /// Passthrough stub
+ //----------------------------------------------------------------------
+ void HandleVTable(clang::CXXRecordDecl *RD) override;
+
+ //----------------------------------------------------------------------
+ /// Passthrough stub
+ //----------------------------------------------------------------------
+ void PrintStats() override;
+
+ //----------------------------------------------------------------------
+ /// Set the Sema object to use when performing transforms, and pass it on
+ ///
+ /// @param[in] S
+ /// The Sema to use. Because Sema isn't externally visible, this class
+ /// casts it to an Action for actual use.
+ //----------------------------------------------------------------------
+ void InitializeSema(clang::Sema &S) override;
+
+ //----------------------------------------------------------------------
+ /// Reset the Sema to NULL now that transformations are done
+ //----------------------------------------------------------------------
+ void ForgetSema() override;
+
+ //----------------------------------------------------------------------
+ /// The parse has succeeded, so record its persistent decls
+ //----------------------------------------------------------------------
+ void CommitPersistentDecls();
private:
- //----------------------------------------------------------------------
- /// Hunt the given Decl for FunctionDecls named $__lldb_expr, recursing
- /// as necessary through LinkageSpecDecls, and calling SynthesizeResult on
- /// anything that was found
- ///
- /// @param[in] D
- /// The Decl to hunt.
- //----------------------------------------------------------------------
- void TransformTopLevelDecl(clang::Decl *D);
-
- //----------------------------------------------------------------------
- /// Process an Objective-C method and produce the result variable and
- /// initialization
- ///
- /// @param[in] MethodDecl
- /// The method to process.
- //----------------------------------------------------------------------
- bool SynthesizeObjCMethodResult(clang::ObjCMethodDecl *MethodDecl);
-
- //----------------------------------------------------------------------
- /// Process a function and produce the result variable and initialization
- ///
- /// @param[in] FunDecl
- /// The function to process.
- //----------------------------------------------------------------------
- bool SynthesizeFunctionResult(clang::FunctionDecl *FunDecl);
-
- //----------------------------------------------------------------------
- /// Process a function body and produce the result variable and
- /// initialization
- ///
- /// @param[in] Body
- /// The body of the function.
- ///
- /// @param[in] DC
- /// The DeclContext of the function, into which the result variable
- /// is inserted.
- //----------------------------------------------------------------------
- bool SynthesizeBodyResult(clang::CompoundStmt *Body,
- clang::DeclContext *DC);
-
- //----------------------------------------------------------------------
- /// Given a DeclContext for a function or method, find all types
- /// declared in the context and record any persistent types found.
- ///
- /// @param[in] FunDeclCtx
- /// The context for the function to process.
- //----------------------------------------------------------------------
- void RecordPersistentTypes(clang::DeclContext *FunDeclCtx);
-
- //----------------------------------------------------------------------
- /// Given a TypeDecl, if it declares a type whose name starts with a
- /// dollar sign, register it as a pointer type in the target's scratch
- /// AST context.
- ///
- /// @param[in] Body
- /// The body of the function.
- //----------------------------------------------------------------------
- void
- MaybeRecordPersistentType(clang::TypeDecl *D);
-
- //----------------------------------------------------------------------
- /// Given a NamedDecl, register it as a pointer type in the target's scratch
- /// AST context.
- ///
- /// @param[in] Body
- /// The body of the function.
- //----------------------------------------------------------------------
- void
- RecordPersistentDecl(clang::NamedDecl *D);
-
- clang::ASTContext *m_ast_context; ///< The AST context to use for identifiers and types.
- clang::ASTConsumer
- *m_passthrough; ///< The ASTConsumer down the chain, for passthrough. NULL if it's a SemaConsumer.
- clang::SemaConsumer
- *m_passthrough_sema; ///< The SemaConsumer down the chain, for passthrough. NULL if it's an ASTConsumer.
-
- std::vector<clang::NamedDecl *> m_decls; ///< Persistent declarations to register assuming the expression succeeds.
-
- Target &m_target; ///< The target, which contains the persistent variable store and the
- clang::Sema *m_sema; ///< The Sema to use.
- bool m_top_level;
+ //----------------------------------------------------------------------
+ /// Hunt the given Decl for FunctionDecls named $__lldb_expr, recursing
+ /// as necessary through LinkageSpecDecls, and calling SynthesizeResult on
+ /// anything that was found
+ ///
+ /// @param[in] D
+ /// The Decl to hunt.
+ //----------------------------------------------------------------------
+ void TransformTopLevelDecl(clang::Decl *D);
+
+ //----------------------------------------------------------------------
+ /// Process an Objective-C method and produce the result variable and
+ /// initialization
+ ///
+ /// @param[in] MethodDecl
+ /// The method to process.
+ //----------------------------------------------------------------------
+ bool SynthesizeObjCMethodResult(clang::ObjCMethodDecl *MethodDecl);
+
+ //----------------------------------------------------------------------
+ /// Process a function and produce the result variable and initialization
+ ///
+ /// @param[in] FunDecl
+ /// The function to process.
+ //----------------------------------------------------------------------
+ bool SynthesizeFunctionResult(clang::FunctionDecl *FunDecl);
+
+ //----------------------------------------------------------------------
+ /// Process a function body and produce the result variable and
+ /// initialization
+ ///
+ /// @param[in] Body
+ /// The body of the function.
+ ///
+ /// @param[in] DC
+ /// The DeclContext of the function, into which the result variable
+ /// is inserted.
+ //----------------------------------------------------------------------
+ bool SynthesizeBodyResult(clang::CompoundStmt *Body, clang::DeclContext *DC);
+
+ //----------------------------------------------------------------------
+ /// Given a DeclContext for a function or method, find all types
+ /// declared in the context and record any persistent types found.
+ ///
+ /// @param[in] FunDeclCtx
+ /// The context for the function to process.
+ //----------------------------------------------------------------------
+ void RecordPersistentTypes(clang::DeclContext *FunDeclCtx);
+
+ //----------------------------------------------------------------------
+ /// Given a TypeDecl, if it declares a type whose name starts with a
+ /// dollar sign, register it as a pointer type in the target's scratch
+ /// AST context.
+ ///
+ /// @param[in] Body
+ /// The body of the function.
+ //----------------------------------------------------------------------
+ void MaybeRecordPersistentType(clang::TypeDecl *D);
+
+ //----------------------------------------------------------------------
+ /// Given a NamedDecl, register it as a pointer type in the target's scratch
+ /// AST context.
+ ///
+ /// @param[in] Body
+ /// The body of the function.
+ //----------------------------------------------------------------------
+ void RecordPersistentDecl(clang::NamedDecl *D);
+
+ clang::ASTContext
+ *m_ast_context; ///< The AST context to use for identifiers and types.
+ clang::ASTConsumer *m_passthrough; ///< The ASTConsumer down the chain, for
+ ///passthrough. NULL if it's a
+ ///SemaConsumer.
+ clang::SemaConsumer *m_passthrough_sema; ///< The SemaConsumer down the chain,
+ ///for passthrough. NULL if it's an
+ ///ASTConsumer.
+
+ std::vector<clang::NamedDecl *> m_decls; ///< Persistent declarations to
+ ///register assuming the expression
+ ///succeeds.
+
+ Target &m_target; ///< The target, which contains the persistent variable
+ ///store and the
+ clang::Sema *m_sema; ///< The Sema to use.
+ bool m_top_level;
};
} // namespace lldb_private
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ASTStructExtractor.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ASTStructExtractor.cpp
index 38a2b6b33a8..4081bc990c9 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ASTStructExtractor.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ASTStructExtractor.cpp
@@ -9,6 +9,7 @@
#include "ASTStructExtractor.h"
+#include "lldb/Core/Log.h"
#include "stdlib.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
@@ -21,7 +22,6 @@
#include "clang/Sema/Sema.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/raw_ostream.h"
-#include "lldb/Core/Log.h"
using namespace llvm;
using namespace clang;
@@ -29,193 +29,158 @@ using namespace lldb_private;
ASTStructExtractor::ASTStructExtractor(ASTConsumer *passthrough,
const char *struct_name,
- ClangFunctionCaller &function) :
- m_ast_context (NULL),
- m_passthrough (passthrough),
- m_passthrough_sema (NULL),
- m_sema (NULL),
- m_action (NULL),
- m_function (function),
- m_struct_name (struct_name)
-{
- if (!m_passthrough)
- return;
-
- m_passthrough_sema = dyn_cast<SemaConsumer>(passthrough);
+ ClangFunctionCaller &function)
+ : m_ast_context(NULL), m_passthrough(passthrough), m_passthrough_sema(NULL),
+ m_sema(NULL), m_action(NULL), m_function(function),
+ m_struct_name(struct_name) {
+ if (!m_passthrough)
+ return;
+
+ m_passthrough_sema = dyn_cast<SemaConsumer>(passthrough);
}
-ASTStructExtractor::~ASTStructExtractor()
-{
-}
+ASTStructExtractor::~ASTStructExtractor() {}
-void
-ASTStructExtractor::Initialize(ASTContext &Context)
-{
- m_ast_context = &Context;
+void ASTStructExtractor::Initialize(ASTContext &Context) {
+ m_ast_context = &Context;
- if (m_passthrough)
- m_passthrough->Initialize(Context);
+ if (m_passthrough)
+ m_passthrough->Initialize(Context);
}
-void
-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)
- {
- Stmt *curr_stmt = *bi;
- DeclStmt *curr_decl_stmt = dyn_cast<DeclStmt>(curr_stmt);
- if (!curr_decl_stmt)
- continue;
- DeclGroupRef decl_group = curr_decl_stmt->getDeclGroup();
- for (Decl *candidate_decl : decl_group)
- {
- RecordDecl *candidate_record_decl = dyn_cast<RecordDecl>(candidate_decl);
- if (!candidate_record_decl)
- continue;
- if (candidate_record_decl->getName() == desired_name)
- {
- struct_decl = candidate_record_decl;
- break;
- }
- }
- if (struct_decl)
- break;
+void 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) {
+ Stmt *curr_stmt = *bi;
+ DeclStmt *curr_decl_stmt = dyn_cast<DeclStmt>(curr_stmt);
+ if (!curr_decl_stmt)
+ continue;
+ DeclGroupRef decl_group = curr_decl_stmt->getDeclGroup();
+ for (Decl *candidate_decl : decl_group) {
+ RecordDecl *candidate_record_decl = dyn_cast<RecordDecl>(candidate_decl);
+ if (!candidate_record_decl)
+ continue;
+ if (candidate_record_decl->getName() == desired_name) {
+ struct_decl = candidate_record_decl;
+ break;
+ }
}
+ 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_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;
+}
- 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_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);
- }
+void ASTStructExtractor::ExtractFromTopLevelDecl(Decl *D) {
+ LinkageSpecDecl *linkage_spec_decl = dyn_cast<LinkageSpecDecl>(D);
- m_function.m_struct_valid = true;
-}
+ if (linkage_spec_decl) {
+ RecordDecl::decl_iterator decl_iterator;
-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)
- {
- ExtractFromTopLevelDecl(*decl_iterator);
- }
+ for (decl_iterator = linkage_spec_decl->decls_begin();
+ decl_iterator != linkage_spec_decl->decls_end(); ++decl_iterator) {
+ ExtractFromTopLevelDecl(*decl_iterator);
}
+ }
- FunctionDecl *function_decl = dyn_cast<FunctionDecl>(D);
+ 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()))
- {
- ExtractFromFunctionDecl(function_decl);
- }
+ if (m_ast_context && function_decl &&
+ !m_function.m_wrapper_function_name.compare(
+ function_decl->getNameAsString().c_str())) {
+ ExtractFromFunctionDecl(function_decl);
+ }
}
-bool
-ASTStructExtractor::HandleTopLevelDecl(DeclGroupRef D)
-{
- DeclGroupRef::iterator decl_iterator;
+bool ASTStructExtractor::HandleTopLevelDecl(DeclGroupRef D) {
+ DeclGroupRef::iterator decl_iterator;
- for (decl_iterator = D.begin();
- decl_iterator != D.end();
- ++decl_iterator)
- {
- Decl *decl = *decl_iterator;
+ for (decl_iterator = D.begin(); decl_iterator != D.end(); ++decl_iterator) {
+ Decl *decl = *decl_iterator;
- ExtractFromTopLevelDecl(decl);
- }
+ ExtractFromTopLevelDecl(decl);
+ }
- if (m_passthrough)
- return m_passthrough->HandleTopLevelDecl(D);
- return true;
+ if (m_passthrough)
+ return m_passthrough->HandleTopLevelDecl(D);
+ return true;
}
-void
-ASTStructExtractor::HandleTranslationUnit(ASTContext &Ctx)
-{
- if (m_passthrough)
- m_passthrough->HandleTranslationUnit(Ctx);
+void ASTStructExtractor::HandleTranslationUnit(ASTContext &Ctx) {
+ if (m_passthrough)
+ m_passthrough->HandleTranslationUnit(Ctx);
}
-void
-ASTStructExtractor::HandleTagDeclDefinition(TagDecl *D)
-{
- if (m_passthrough)
- m_passthrough->HandleTagDeclDefinition(D);
+void ASTStructExtractor::HandleTagDeclDefinition(TagDecl *D) {
+ if (m_passthrough)
+ m_passthrough->HandleTagDeclDefinition(D);
}
-void
-ASTStructExtractor::CompleteTentativeDefinition(VarDecl *D)
-{
- if (m_passthrough)
- m_passthrough->CompleteTentativeDefinition(D);
+void ASTStructExtractor::CompleteTentativeDefinition(VarDecl *D) {
+ if (m_passthrough)
+ m_passthrough->CompleteTentativeDefinition(D);
}
-void
-ASTStructExtractor::HandleVTable(CXXRecordDecl *RD)
-{
- if (m_passthrough)
- m_passthrough->HandleVTable(RD);
+void ASTStructExtractor::HandleVTable(CXXRecordDecl *RD) {
+ if (m_passthrough)
+ m_passthrough->HandleVTable(RD);
}
-void
-ASTStructExtractor::PrintStats()
-{
- if (m_passthrough)
- m_passthrough->PrintStats();
+void ASTStructExtractor::PrintStats() {
+ if (m_passthrough)
+ m_passthrough->PrintStats();
}
-void
-ASTStructExtractor::InitializeSema(Sema &S)
-{
- m_sema = &S;
- m_action = reinterpret_cast<Action*>(m_sema);
+void ASTStructExtractor::InitializeSema(Sema &S) {
+ m_sema = &S;
+ m_action = reinterpret_cast<Action *>(m_sema);
- if (m_passthrough_sema)
- m_passthrough_sema->InitializeSema(S);
+ if (m_passthrough_sema)
+ m_passthrough_sema->InitializeSema(S);
}
-void
-ASTStructExtractor::ForgetSema()
-{
- m_sema = NULL;
- m_action = NULL;
+void ASTStructExtractor::ForgetSema() {
+ m_sema = NULL;
+ m_action = NULL;
- if (m_passthrough_sema)
- m_passthrough_sema->ForgetSema();
+ if (m_passthrough_sema)
+ m_passthrough_sema->ForgetSema();
}
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ASTStructExtractor.h b/lldb/source/Plugins/ExpressionParser/Clang/ASTStructExtractor.h
index 2152cff911f..63e3161cae8 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ASTStructExtractor.h
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ASTStructExtractor.h
@@ -13,16 +13,18 @@
#include "ClangExpressionVariable.h"
#include "ClangFunctionCaller.h"
-#include "clang/Sema/SemaConsumer.h"
#include "lldb/Core/ClangForward.h"
+#include "clang/Sema/SemaConsumer.h"
namespace lldb_private {
-
+
//----------------------------------------------------------------------
-/// @class ASTStructExtractor ASTStructExtractor.h "lldb/Expression/ASTStructExtractor.h"
+/// @class ASTStructExtractor ASTStructExtractor.h
+/// "lldb/Expression/ASTStructExtractor.h"
/// @brief Extracts and describes the argument structure for a wrapped function.
///
-/// This pass integrates with ClangFunctionCaller, which calls functions with custom
+/// This pass integrates with ClangFunctionCaller, which calls functions with
+/// custom
/// sets of arguments. To avoid having to implement the full calling convention
/// for the target's architecture, ClangFunctionCaller writes a simple wrapper
/// function that takes a pointer to an argument structure that contains room
@@ -33,126 +35,130 @@ namespace lldb_private {
/// so Clang does the structure layout itself. ASTStructExtractor reads through
/// the AST for the wrapper function and finds the struct.
//----------------------------------------------------------------------
-class ASTStructExtractor : public clang::SemaConsumer
-{
+class ASTStructExtractor : public clang::SemaConsumer {
public:
- //----------------------------------------------------------------------
- /// Constructor
- ///
- /// @param[in] passthrough
- /// Since the ASTs must typically go through to the Clang code generator
- /// in order to produce LLVM IR, this SemaConsumer must allow them to
- /// pass to the next step in the chain after processing. Passthrough is
- /// the next ASTConsumer, or NULL if none is required.
- ///
- /// @param[in] struct_name
- /// The name of the structure to extract from the wrapper function.
- ///
- /// @param[in] function
- /// The caller object whose members should be populated with information
- /// about the argument struct. ClangFunctionCaller friends ASTStructExtractor
- /// for this purpose.
- //----------------------------------------------------------------------
- ASTStructExtractor(clang::ASTConsumer *passthrough,
- const char *struct_name,
- ClangFunctionCaller &function);
-
- //----------------------------------------------------------------------
- /// Destructor
- //----------------------------------------------------------------------
- ~ASTStructExtractor() override;
-
- //----------------------------------------------------------------------
- /// Link this consumer with a particular AST context
- ///
- /// @param[in] Context
- /// This AST context will be used for types and identifiers, and also
- /// forwarded to the passthrough consumer, if one exists.
- //----------------------------------------------------------------------
- void Initialize(clang::ASTContext &Context) override;
-
- //----------------------------------------------------------------------
- /// Examine a list of Decls to find the function $__lldb_expr and
- /// transform its code
- ///
- /// @param[in] D
- /// The list of Decls to search. These may contain LinkageSpecDecls,
- /// which need to be searched recursively. That job falls to
- /// TransformTopLevelDecl.
- //----------------------------------------------------------------------
- bool HandleTopLevelDecl(clang::DeclGroupRef D) override;
-
- //----------------------------------------------------------------------
- /// Passthrough stub
- //----------------------------------------------------------------------
- void HandleTranslationUnit(clang::ASTContext &Ctx) override;
-
- //----------------------------------------------------------------------
- /// Passthrough stub
- //----------------------------------------------------------------------
- void HandleTagDeclDefinition(clang::TagDecl *D) override;
-
- //----------------------------------------------------------------------
- /// Passthrough stub
- //----------------------------------------------------------------------
- void CompleteTentativeDefinition(clang::VarDecl *D) override;
-
- //----------------------------------------------------------------------
- /// Passthrough stub
- //----------------------------------------------------------------------
- void HandleVTable(clang::CXXRecordDecl *RD) override;
-
- //----------------------------------------------------------------------
- /// Passthrough stub
- //----------------------------------------------------------------------
- void PrintStats() override;
-
- //----------------------------------------------------------------------
- /// Set the Sema object to use when performing transforms, and pass it on
- ///
- /// @param[in] S
- /// The Sema to use. Because Sema isn't externally visible, this class
- /// casts it to an Action for actual use.
- //----------------------------------------------------------------------
- void InitializeSema(clang::Sema &S) override;
-
- //----------------------------------------------------------------------
- /// Reset the Sema to NULL now that transformations are done
- //----------------------------------------------------------------------
- void ForgetSema() override;
+ //----------------------------------------------------------------------
+ /// Constructor
+ ///
+ /// @param[in] passthrough
+ /// Since the ASTs must typically go through to the Clang code generator
+ /// in order to produce LLVM IR, this SemaConsumer must allow them to
+ /// pass to the next step in the chain after processing. Passthrough is
+ /// the next ASTConsumer, or NULL if none is required.
+ ///
+ /// @param[in] struct_name
+ /// The name of the structure to extract from the wrapper function.
+ ///
+ /// @param[in] function
+ /// The caller object whose members should be populated with information
+ /// about the argument struct. ClangFunctionCaller friends
+ /// ASTStructExtractor
+ /// for this purpose.
+ //----------------------------------------------------------------------
+ ASTStructExtractor(clang::ASTConsumer *passthrough, const char *struct_name,
+ ClangFunctionCaller &function);
+
+ //----------------------------------------------------------------------
+ /// Destructor
+ //----------------------------------------------------------------------
+ ~ASTStructExtractor() override;
+
+ //----------------------------------------------------------------------
+ /// Link this consumer with a particular AST context
+ ///
+ /// @param[in] Context
+ /// This AST context will be used for types and identifiers, and also
+ /// forwarded to the passthrough consumer, if one exists.
+ //----------------------------------------------------------------------
+ void Initialize(clang::ASTContext &Context) override;
+
+ //----------------------------------------------------------------------
+ /// Examine a list of Decls to find the function $__lldb_expr and
+ /// transform its code
+ ///
+ /// @param[in] D
+ /// The list of Decls to search. These may contain LinkageSpecDecls,
+ /// which need to be searched recursively. That job falls to
+ /// TransformTopLevelDecl.
+ //----------------------------------------------------------------------
+ bool HandleTopLevelDecl(clang::DeclGroupRef D) override;
+
+ //----------------------------------------------------------------------
+ /// Passthrough stub
+ //----------------------------------------------------------------------
+ void HandleTranslationUnit(clang::ASTContext &Ctx) override;
+
+ //----------------------------------------------------------------------
+ /// Passthrough stub
+ //----------------------------------------------------------------------
+ void HandleTagDeclDefinition(clang::TagDecl *D) override;
+
+ //----------------------------------------------------------------------
+ /// Passthrough stub
+ //----------------------------------------------------------------------
+ void CompleteTentativeDefinition(clang::VarDecl *D) override;
+
+ //----------------------------------------------------------------------
+ /// Passthrough stub
+ //----------------------------------------------------------------------
+ void HandleVTable(clang::CXXRecordDecl *RD) override;
+
+ //----------------------------------------------------------------------
+ /// Passthrough stub
+ //----------------------------------------------------------------------
+ void PrintStats() override;
+
+ //----------------------------------------------------------------------
+ /// Set the Sema object to use when performing transforms, and pass it on
+ ///
+ /// @param[in] S
+ /// The Sema to use. Because Sema isn't externally visible, this class
+ /// casts it to an Action for actual use.
+ //----------------------------------------------------------------------
+ void InitializeSema(clang::Sema &S) override;
+
+ //----------------------------------------------------------------------
+ /// Reset the Sema to NULL now that transformations are done
+ //----------------------------------------------------------------------
+ void ForgetSema() override;
private:
- //----------------------------------------------------------------------
- /// Hunt the given FunctionDecl for the argument struct and place
- /// information about it into m_function
- ///
- /// @param[in] F
- /// The FunctionDecl to hunt.
- //----------------------------------------------------------------------
- void
- ExtractFromFunctionDecl(clang::FunctionDecl* F);
-
- //----------------------------------------------------------------------
- /// Hunt the given Decl for FunctionDecls named the same as the wrapper
- /// function name, recursing as necessary through LinkageSpecDecls, and
- /// calling ExtractFromFunctionDecl on anything that was found
- ///
- /// @param[in] D
- /// The Decl to hunt.
- //----------------------------------------------------------------------
- void
- ExtractFromTopLevelDecl(clang::Decl* D);
-
- clang::ASTContext *m_ast_context; ///< The AST context to use for identifiers and types.
- clang::ASTConsumer *m_passthrough; ///< The ASTConsumer down the chain, for passthrough. NULL if it's a SemaConsumer.
- clang::SemaConsumer *m_passthrough_sema; ///< The SemaConsumer down the chain, for passthrough. NULL if it's an ASTConsumer.
- clang::Sema *m_sema; ///< The Sema to use.
- clang::Action *m_action; ///< The Sema to use, cast to an Action so it's usable.
-
- ClangFunctionCaller &m_function; ///< The function to populate with information about the argument structure.
- std::string m_struct_name; ///< The name of the structure to extract.
+ //----------------------------------------------------------------------
+ /// Hunt the given FunctionDecl for the argument struct and place
+ /// information about it into m_function
+ ///
+ /// @param[in] F
+ /// The FunctionDecl to hunt.
+ //----------------------------------------------------------------------
+ void ExtractFromFunctionDecl(clang::FunctionDecl *F);
+
+ //----------------------------------------------------------------------
+ /// Hunt the given Decl for FunctionDecls named the same as the wrapper
+ /// function name, recursing as necessary through LinkageSpecDecls, and
+ /// calling ExtractFromFunctionDecl on anything that was found
+ ///
+ /// @param[in] D
+ /// The Decl to hunt.
+ //----------------------------------------------------------------------
+ void ExtractFromTopLevelDecl(clang::Decl *D);
+
+ clang::ASTContext
+ *m_ast_context; ///< The AST context to use for identifiers and types.
+ clang::ASTConsumer *m_passthrough; ///< The ASTConsumer down the chain, for
+ ///passthrough. NULL if it's a
+ ///SemaConsumer.
+ clang::SemaConsumer *m_passthrough_sema; ///< The SemaConsumer down the chain,
+ ///for passthrough. NULL if it's an
+ ///ASTConsumer.
+ clang::Sema *m_sema; ///< The Sema to use.
+ clang::Action
+ *m_action; ///< The Sema to use, cast to an Action so it's usable.
+
+ ClangFunctionCaller &m_function; ///< The function to populate with
+ ///information about the argument structure.
+ std::string m_struct_name; ///< The name of the structure to extract.
};
-
+
} // namespace lldb_private
#endif // liblldb_ASTStructExtractor_h_
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp
index def0d42d32d..7a5f4f7a192 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp
@@ -1,4 +1,5 @@
-//===-- ClangASTSource.cpp ---------------------------------------*- C++ -*-===//
+//===-- ClangASTSource.cpp ---------------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -37,884 +38,833 @@ using namespace lldb_private;
// when it goes out of scope.
//------------------------------------------------------------------
namespace {
- class ScopedLexicalDeclEraser
- {
- public:
- ScopedLexicalDeclEraser(std::set<const clang::Decl *> &decls,
- const clang::Decl *decl)
- : m_active_lexical_decls(decls), m_decl(decl)
- {
- }
+class ScopedLexicalDeclEraser {
+public:
+ ScopedLexicalDeclEraser(std::set<const clang::Decl *> &decls,
+ const clang::Decl *decl)
+ : m_active_lexical_decls(decls), m_decl(decl) {}
- ~ScopedLexicalDeclEraser()
- {
- m_active_lexical_decls.erase(m_decl);
- }
+ ~ScopedLexicalDeclEraser() { m_active_lexical_decls.erase(m_decl); }
- private:
- std::set<const clang::Decl *> &m_active_lexical_decls;
- const clang::Decl *m_decl;
- };
+private:
+ std::set<const clang::Decl *> &m_active_lexical_decls;
+ const clang::Decl *m_decl;
+};
}
-ClangASTSource::~ClangASTSource()
-{
- m_ast_importer_sp->ForgetDestination(m_ast_context);
+ClangASTSource::~ClangASTSource() {
+ m_ast_importer_sp->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);
+ // 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;
+ if (!scratch_clang_ast_context)
+ return;
- clang::ASTContext *scratch_ast_context = scratch_clang_ast_context->getASTContext();
+ clang::ASTContext *scratch_ast_context =
+ scratch_clang_ast_context->getASTContext();
- if (!scratch_ast_context)
- return;
+ if (!scratch_ast_context)
+ return;
- if (m_ast_context != scratch_ast_context)
- m_ast_importer_sp->ForgetSource(scratch_ast_context, m_ast_context);
+ if (m_ast_context != scratch_ast_context)
+ m_ast_importer_sp->ForgetSource(scratch_ast_context, m_ast_context);
}
-void
-ClangASTSource::StartTranslationUnit(ASTConsumer *Consumer)
-{
- if (!m_ast_context)
- return;
+void ClangASTSource::StartTranslationUnit(ASTConsumer *Consumer) {
+ if (!m_ast_context)
+ return;
- m_ast_context->getTranslationUnitDecl()->setHasExternalVisibleStorage();
- m_ast_context->getTranslationUnitDecl()->setHasExternalLexicalStorage();
+ m_ast_context->getTranslationUnitDecl()->setHasExternalVisibleStorage();
+ m_ast_context->getTranslationUnitDecl()->setHasExternalLexicalStorage();
}
// The core lookup interface.
-bool
-ClangASTSource::FindExternalVisibleDeclsByName
-(
- const DeclContext *decl_ctx,
- DeclarationName clang_decl_name
-)
-{
- if (!m_ast_context)
- {
- SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
- return false;
+bool ClangASTSource::FindExternalVisibleDeclsByName(
+ 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) {
+ SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
+ return false;
}
-
- if (GetImportInProgress())
- {
- SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
- return false;
+ } break;
+
+ // Operator names.
+ case DeclarationName::CXXOperatorName:
+ case DeclarationName::CXXLiteralOperatorName:
+ break;
+
+ // 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;
+
+ NameSearchContext method_search_context(*this, method_decls,
+ clang_decl_name, decl_ctx);
+
+ FindObjCMethodDecls(method_search_context);
+
+ SetExternalVisibleDeclsForName(decl_ctx, clang_decl_name, method_decls);
+ return (method_decls.size() > 0);
+ }
+ // These aren't possible in the global context.
+ case DeclarationName::CXXConstructorName:
+ case DeclarationName::CXXDestructorName:
+ case DeclarationName::CXXConversionFunctionName:
+ SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
+ return false;
+ }
+
+ if (!GetLookupsEnabled()) {
+ // 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()) {
+ // We are currently looking up this name...
+ SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
+ return false;
+ }
+ m_active_lookups.insert(uniqued_const_decl_name);
+ // 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;
+ NameSearchContext name_search_context(*this, name_decls, clang_decl_name,
+ decl_ctx);
+ FindExternalVisibleDecls(name_search_context);
+ SetExternalVisibleDeclsForName(decl_ctx, clang_decl_name, name_decls);
+ // --g_depth;
+ m_active_lookups.erase(uniqued_const_decl_name);
+ return (name_decls.size() != 0);
+}
- std::string decl_name (clang_decl_name.getAsString());
+void ClangASTSource::CompleteType(TagDecl *tag_decl) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
-// 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)
- {
- SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
- return false;
- }
- }
- break;
+ static unsigned int invocation_id = 0;
+ unsigned int current_id = invocation_id++;
- // Operator names.
- case DeclarationName::CXXOperatorName:
- case DeclarationName::CXXLiteralOperatorName:
- break;
+ if (log) {
+ 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());
- // 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;
+ log->Printf(" CTD[%u] Before:", current_id);
+ ASTDumper dumper((Decl *)tag_decl);
+ dumper.ToLog(log, " [CTD] ");
+ }
- case DeclarationName::ObjCZeroArgSelector:
- case DeclarationName::ObjCOneArgSelector:
- case DeclarationName::ObjCMultiArgSelector:
- {
- llvm::SmallVector<NamedDecl*, 1> method_decls;
+ auto iter = m_active_lexical_decls.find(tag_decl);
+ if (iter != m_active_lexical_decls.end())
+ return;
+ m_active_lexical_decls.insert(tag_decl);
+ ScopedLexicalDeclEraser eraser(m_active_lexical_decls, tag_decl);
- NameSearchContext method_search_context (*this, method_decls, clang_decl_name, decl_ctx);
+ if (!m_ast_importer_sp->CompleteTagDecl(tag_decl)) {
+ // We couldn't complete the type. Maybe there's a definition
+ // somewhere else that can be completed.
- FindObjCMethodDecls(method_search_context);
+ if (log)
+ log->Printf(" CTD[%u] Type could not be completed in the module in "
+ "which it was first found.",
+ current_id);
- SetExternalVisibleDeclsForName (decl_ctx, clang_decl_name, method_decls);
- return (method_decls.size() > 0);
- }
- // These aren't possible in the global context.
- case DeclarationName::CXXConstructorName:
- case DeclarationName::CXXDestructorName:
- case DeclarationName::CXXConversionFunctionName:
- SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
- return false;
- }
+ bool found = false;
+ DeclContext *decl_ctx = tag_decl->getDeclContext();
- if (!GetLookupsEnabled())
- {
- // 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;
- }
- }
+ if (const NamespaceDecl *namespace_context =
+ dyn_cast<NamespaceDecl>(decl_ctx)) {
+ ClangASTImporter::NamespaceMapSP namespace_map =
+ m_ast_importer_sp->GetNamespaceMap(namespace_context);
- ConstString const_decl_name(decl_name.c_str());
+ if (log && log->GetVerbose())
+ log->Printf(" CTD[%u] Inspecting namespace map %p (%d entries)",
+ current_id, static_cast<void *>(namespace_map.get()),
+ static_cast<int>(namespace_map->size()));
- const char *uniqued_const_decl_name = const_decl_name.GetCString();
- if (m_active_lookups.find (uniqued_const_decl_name) != m_active_lookups.end())
- {
- // We are currently looking up this name...
- SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
- return false;
- }
- m_active_lookups.insert(uniqued_const_decl_name);
-// 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;
- NameSearchContext name_search_context(*this, name_decls, clang_decl_name, decl_ctx);
- FindExternalVisibleDecls(name_search_context);
- SetExternalVisibleDeclsForName (decl_ctx, clang_decl_name, name_decls);
-// --g_depth;
- m_active_lookups.erase (uniqued_const_decl_name);
- return (name_decls.size() != 0);
-}
+ if (!namespace_map)
+ return;
-void
-ClangASTSource::CompleteType (TagDecl *tag_decl)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ for (ClangASTImporter::NamespaceMap::iterator i = namespace_map->begin(),
+ e = namespace_map->end();
+ i != e && !found; ++i) {
+ if (log)
+ log->Printf(" CTD[%u] Searching namespace %s in module %s",
+ current_id, i->second.GetName().AsCString(),
+ i->first->GetFileSpec().GetFilename().GetCString());
- static unsigned int invocation_id = 0;
- unsigned int current_id = invocation_id++;
+ TypeList types;
- if (log)
- {
- 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] ");
- }
+ SymbolContext null_sc;
+ ConstString name(tag_decl->getName().str().c_str());
- auto iter = m_active_lexical_decls.find(tag_decl);
- if (iter != m_active_lexical_decls.end())
- return;
- m_active_lexical_decls.insert(tag_decl);
- ScopedLexicalDeclEraser eraser(m_active_lexical_decls, tag_decl);
+ i->first->FindTypesInNamespace(null_sc, name, &i->second, UINT32_MAX,
+ types);
- if (!m_ast_importer_sp->CompleteTagDecl (tag_decl))
- {
- // We couldn't complete the type. Maybe there's a definition
- // somewhere else that can be completed.
+ for (uint32_t ti = 0, te = types.GetSize(); ti != te && !found; ++ti) {
+ lldb::TypeSP type = types.GetTypeAtIndex(ti);
- if (log)
- log->Printf(" CTD[%u] Type could not be completed in the module in which it was first found.", current_id);
+ if (!type)
+ continue;
- bool found = false;
+ CompilerType clang_type(type->GetFullCompilerType());
- DeclContext *decl_ctx = tag_decl->getDeclContext();
+ if (!ClangUtil::IsClangType(clang_type))
+ continue;
- if (const NamespaceDecl *namespace_context = dyn_cast<NamespaceDecl>(decl_ctx))
- {
- ClangASTImporter::NamespaceMapSP namespace_map = m_ast_importer_sp->GetNamespaceMap(namespace_context);
+ const TagType *tag_type =
+ ClangUtil::GetQualType(clang_type)->getAs<TagType>();
- if (log && log->GetVerbose())
- 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 (!tag_type)
+ continue;
- if (!namespace_map)
- return;
+ TagDecl *candidate_tag_decl =
+ const_cast<TagDecl *>(tag_type->getDecl());
- for (ClangASTImporter::NamespaceMap::iterator i = namespace_map->begin(), e = namespace_map->end();
- i != e && !found;
- ++i)
- {
- if (log)
- log->Printf(" CTD[%u] Searching namespace %s in module %s",
- current_id,
- i->second.GetName().AsCString(),
- i->first->GetFileSpec().GetFilename().GetCString());
+ if (m_ast_importer_sp->CompleteTagDeclWithOrigin(tag_decl,
+ candidate_tag_decl))
+ found = true;
+ }
+ }
+ } else {
+ TypeList types;
- TypeList types;
+ SymbolContext null_sc;
+ ConstString name(tag_decl->getName().str().c_str());
+ CompilerDeclContext namespace_decl;
- SymbolContext null_sc;
- ConstString name(tag_decl->getName().str().c_str());
+ const ModuleList &module_list = m_target->GetImages();
- i->first->FindTypesInNamespace(null_sc, name, &i->second, UINT32_MAX, types);
+ bool exact_match = false;
+ llvm::DenseSet<SymbolFile *> searched_symbol_files;
+ module_list.FindTypes(null_sc, name, exact_match, UINT32_MAX,
+ searched_symbol_files, types);
- for (uint32_t ti = 0, te = types.GetSize();
- ti != te && !found;
- ++ti)
- {
- lldb::TypeSP type = types.GetTypeAtIndex(ti);
+ for (uint32_t ti = 0, te = types.GetSize(); ti != te && !found; ++ti) {
+ lldb::TypeSP type = types.GetTypeAtIndex(ti);
- if (!type)
- continue;
+ if (!type)
+ continue;
- CompilerType clang_type (type->GetFullCompilerType ());
+ CompilerType clang_type(type->GetFullCompilerType());
- if (!ClangUtil::IsClangType(clang_type))
- continue;
+ if (!ClangUtil::IsClangType(clang_type))
+ continue;
- const TagType *tag_type = ClangUtil::GetQualType(clang_type)->getAs<TagType>();
+ const TagType *tag_type =
+ ClangUtil::GetQualType(clang_type)->getAs<TagType>();
- if (!tag_type)
- continue;
+ if (!tag_type)
+ continue;
- TagDecl *candidate_tag_decl = const_cast<TagDecl*>(tag_type->getDecl());
+ TagDecl *candidate_tag_decl =
+ const_cast<TagDecl *>(tag_type->getDecl());
- if (m_ast_importer_sp->CompleteTagDeclWithOrigin (tag_decl, candidate_tag_decl))
- found = true;
- }
- }
- }
- else
- {
- TypeList types;
+ // We have found a type by basename and we need to make sure the decl
+ // contexts
+ // are the same before we can try to complete this type with another
+ if (!ClangASTContext::DeclsAreEquivalent(tag_decl, candidate_tag_decl))
+ continue;
- SymbolContext null_sc;
- ConstString name(tag_decl->getName().str().c_str());
- CompilerDeclContext namespace_decl;
+ if (m_ast_importer_sp->CompleteTagDeclWithOrigin(tag_decl,
+ candidate_tag_decl))
+ found = true;
+ }
+ }
+ }
- const ModuleList &module_list = m_target->GetImages();
+ if (log) {
+ log->Printf(" [CTD] After:");
+ ASTDumper dumper((Decl *)tag_decl);
+ dumper.ToLog(log, " [CTD] ");
+ }
+}
- bool exact_match = false;
- llvm::DenseSet<SymbolFile *> searched_symbol_files;
- module_list.FindTypes (null_sc, name, exact_match, UINT32_MAX, searched_symbol_files, types);
+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",
+ 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] ");
+ }
+
+ Decl *original_decl = NULL;
+ ASTContext *original_ctx = NULL;
+
+ if (m_ast_importer_sp->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_sp->SetDeclOrigin(interface_decl, original_iface_decl);
+ }
+ }
+ }
- for (uint32_t ti = 0, te = types.GetSize();
- ti != te && !found;
- ++ti)
- {
- lldb::TypeSP type = types.GetTypeAtIndex(ti);
+ m_ast_importer_sp->CompleteObjCInterfaceDecl(interface_decl);
- if (!type)
- continue;
+ if (interface_decl->getSuperClass() &&
+ interface_decl->getSuperClass() != interface_decl)
+ CompleteType(interface_decl->getSuperClass());
- CompilerType clang_type (type->GetFullCompilerType ());
+ if (log) {
+ log->Printf(" [COID] After:");
+ ASTDumper dumper((Decl *)interface_decl);
+ dumper.ToLog(log, " [COID] ");
+ }
+}
- if (!ClangUtil::IsClangType(clang_type))
- continue;
+clang::ObjCInterfaceDecl *ClangASTSource::GetCompleteObjCInterface(
+ clang::ObjCInterfaceDecl *interface_decl) {
+ lldb::ProcessSP process(m_target->GetProcessSP());
- const TagType *tag_type = ClangUtil::GetQualType(clang_type)->getAs<TagType>();
+ if (!process)
+ return NULL;
- if (!tag_type)
- continue;
+ ObjCLanguageRuntime *language_runtime(process->GetObjCLanguageRuntime());
- TagDecl *candidate_tag_decl = const_cast<TagDecl*>(tag_type->getDecl());
+ if (!language_runtime)
+ return NULL;
- // We have found a type by basename and we need to make sure the decl contexts
- // are the same before we can try to complete this type with another
- if (!ClangASTContext::DeclsAreEquivalent (tag_decl, candidate_tag_decl))
- continue;
+ ConstString class_name(interface_decl->getNameAsString().c_str());
- if (m_ast_importer_sp->CompleteTagDeclWithOrigin (tag_decl, candidate_tag_decl))
- found = true;
- }
- }
- }
+ lldb::TypeSP complete_type_sp(
+ language_runtime->LookupInCompleteClassCache(class_name));
- if (log)
- {
- log->Printf(" [CTD] After:");
- ASTDumper dumper((Decl*)tag_decl);
- dumper.ToLog(log, " [CTD] ");
- }
-}
+ if (!complete_type_sp)
+ return NULL;
-void
-ClangASTSource::CompleteType (clang::ObjCInterfaceDecl *interface_decl)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ TypeFromUser complete_type =
+ TypeFromUser(complete_type_sp->GetFullCompilerType());
+ lldb::opaque_compiler_type_t complete_opaque_type =
+ complete_type.GetOpaqueQualType();
- if (log)
- {
- 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] ");
- }
+ if (!complete_opaque_type)
+ return NULL;
- Decl *original_decl = NULL;
- ASTContext *original_ctx = 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 (m_ast_importer_sp->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_interface_type)
+ return NULL;
- if (complete_iface_decl && (complete_iface_decl != original_iface_decl))
- {
- m_ast_importer_sp->SetDeclOrigin(interface_decl, original_iface_decl);
- }
- }
- }
+ ObjCInterfaceDecl *complete_iface_decl(complete_interface_type->getDecl());
- m_ast_importer_sp->CompleteObjCInterfaceDecl (interface_decl);
+ return complete_iface_decl;
+}
- if (interface_decl->getSuperClass() &&
- interface_decl->getSuperClass() != interface_decl)
- CompleteType(interface_decl->getSuperClass());
+void ClangASTSource::FindExternalLexicalDecls(
+ const DeclContext *decl_context,
+ llvm::function_ref<bool(Decl::Kind)> predicate,
+ llvm::SmallVectorImpl<Decl *> &decls) {
+ ClangASTMetrics::RegisterLexicalQuery();
- if (log)
- {
- log->Printf(" [COID] After:");
- ASTDumper dumper((Decl*)interface_decl);
- dumper.ToLog(log, " [COID] ");
- }
-}
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
-clang::ObjCInterfaceDecl *
-ClangASTSource::GetCompleteObjCInterface (clang::ObjCInterfaceDecl *interface_decl)
-{
- lldb::ProcessSP process(m_target->GetProcessSP());
+ const Decl *context_decl = dyn_cast<Decl>(decl_context);
- if (!process)
- return NULL;
+ if (!context_decl)
+ return;
- ObjCLanguageRuntime *language_runtime(process->GetObjCLanguageRuntime());
+ auto iter = m_active_lexical_decls.find(context_decl);
+ if (iter != m_active_lexical_decls.end())
+ return;
+ m_active_lexical_decls.insert(context_decl);
+ ScopedLexicalDeclEraser eraser(m_active_lexical_decls, context_decl);
+
+ 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",
+ current_id, static_cast<void *>(m_ast_context),
+ context_named_decl->getNameAsString().c_str(),
+ context_decl->getDeclKindName(),
+ static_cast<const void *>(context_decl));
+ else if (context_decl)
+ log->Printf(
+ "FindExternalLexicalDecls[%u] on (ASTContext*)%p in (%sDecl*)%p",
+ current_id, static_cast<void *>(m_ast_context),
+ context_decl->getDeclKindName(),
+ static_cast<const void *>(context_decl));
+ else
+ log->Printf(
+ "FindExternalLexicalDecls[%u] on (ASTContext*)%p in a NULL context",
+ current_id, static_cast<const void *>(m_ast_context));
+ }
- if (!language_runtime)
- return NULL;
+ Decl *original_decl = NULL;
+ ASTContext *original_ctx = NULL;
- ConstString class_name(interface_decl->getNameAsString().c_str());
+ if (!m_ast_importer_sp->ResolveDeclOrigin(context_decl, &original_decl,
+ &original_ctx))
+ return;
- lldb::TypeSP complete_type_sp(language_runtime->LookupInCompleteClassCache(class_name));
+ if (log) {
+ 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 (!complete_type_sp)
- return NULL;
+ if (ObjCInterfaceDecl *original_iface_decl =
+ dyn_cast<ObjCInterfaceDecl>(original_decl)) {
+ ObjCInterfaceDecl *complete_iface_decl =
+ GetCompleteObjCInterface(original_iface_decl);
- TypeFromUser complete_type = TypeFromUser(complete_type_sp->GetFullCompilerType ());
- lldb::opaque_compiler_type_t complete_opaque_type = complete_type.GetOpaqueQualType();
+ if (complete_iface_decl && (complete_iface_decl != original_iface_decl)) {
+ original_decl = complete_iface_decl;
+ original_ctx = &complete_iface_decl->getASTContext();
- if (!complete_opaque_type)
- return NULL;
+ m_ast_importer_sp->SetDeclOrigin(context_decl, original_iface_decl);
+ }
+ }
- const clang::Type *complete_clang_type = QualType::getFromOpaquePtr(complete_opaque_type).getTypePtr();
- const ObjCInterfaceType *complete_interface_type = dyn_cast<ObjCInterfaceType>(complete_clang_type);
+ if (TagDecl *original_tag_decl = dyn_cast<TagDecl>(original_decl)) {
+ ExternalASTSource *external_source = original_ctx->getExternalSource();
- if (!complete_interface_type)
- return NULL;
+ if (external_source)
+ external_source->CompleteType(original_tag_decl);
+ }
- ObjCInterfaceDecl *complete_iface_decl(complete_interface_type->getDecl());
+ const DeclContext *original_decl_context =
+ dyn_cast<DeclContext>(original_decl);
- return complete_iface_decl;
-}
+ if (!original_decl_context)
+ return;
+
+ for (TagDecl::decl_iterator iter = original_decl_context->decls_begin();
+ iter != original_decl_context->decls_end(); ++iter) {
+ Decl *decl = *iter;
+
+ if (predicate(decl->getKind())) {
+ if (log) {
+ ASTDumper ast_dumper(decl);
+ if (const NamedDecl *context_named_decl =
+ dyn_cast<NamedDecl>(context_decl))
+ log->Printf(" FELD[%d] Adding [to %sDecl %s] lexical %sDecl %s",
+ current_id, context_named_decl->getDeclKindName(),
+ context_named_decl->getNameAsString().c_str(),
+ decl->getDeclKindName(), ast_dumper.GetCString());
+ else
+ log->Printf(" FELD[%d] Adding lexical %sDecl %s", current_id,
+ decl->getDeclKindName(), ast_dumper.GetCString());
+ }
-void
-ClangASTSource::FindExternalLexicalDecls (const DeclContext *decl_context,
- llvm::function_ref<bool(Decl::Kind)> predicate,
- llvm::SmallVectorImpl<Decl*> &decls)
-{
- ClangASTMetrics::RegisterLexicalQuery();
+ Decl *copied_decl =
+ m_ast_importer_sp->CopyDecl(m_ast_context, original_ctx, decl);
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ if (!copied_decl)
+ continue;
- const Decl *context_decl = dyn_cast<Decl>(decl_context);
+ if (FieldDecl *copied_field = dyn_cast<FieldDecl>(copied_decl)) {
+ QualType copied_field_type = copied_field->getType();
- if (!context_decl)
- return;
+ m_ast_importer_sp->RequireCompleteType(copied_field_type);
+ }
- auto iter = m_active_lexical_decls.find(context_decl);
- if (iter != m_active_lexical_decls.end())
- return;
- m_active_lexical_decls.insert(context_decl);
- ScopedLexicalDeclEraser eraser(m_active_lexical_decls, context_decl);
+ DeclContext *decl_context_non_const =
+ const_cast<DeclContext *>(decl_context);
- static unsigned int invocation_id = 0;
- unsigned int current_id = invocation_id++;
+ 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 (log)
- {
- if (const NamedDecl *context_named_decl = dyn_cast<NamedDecl>(context_decl))
- log->Printf("FindExternalLexicalDecls[%u] on (ASTContext*)%p in '%s' (%sDecl*)%p",
- current_id, static_cast<void*>(m_ast_context),
- context_named_decl->getNameAsString().c_str(),
- context_decl->getDeclKindName(),
- static_cast<const void*>(context_decl));
- else if(context_decl)
- log->Printf("FindExternalLexicalDecls[%u] on (ASTContext*)%p in (%sDecl*)%p",
- current_id, static_cast<void*>(m_ast_context),
- context_decl->getDeclKindName(),
- static_cast<const void*>(context_decl));
- else
- log->Printf("FindExternalLexicalDecls[%u] on (ASTContext*)%p in a NULL context",
- current_id, static_cast<const void*>(m_ast_context));
+ if (!decl_context_non_const->containsDecl(copied_decl))
+ decl_context_non_const->addDeclInternal(copied_decl);
}
+ }
- Decl *original_decl = NULL;
- ASTContext *original_ctx = NULL;
+ return;
+}
- if (!m_ast_importer_sp->ResolveDeclOrigin(context_decl, &original_decl, &original_ctx))
- return;
+void ClangASTSource::FindExternalVisibleDecls(NameSearchContext &context) {
+ assert(m_ast_context);
- if (log)
- {
- 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, " ");
- }
+ ClangASTMetrics::RegisterVisibleQuery();
- if (ObjCInterfaceDecl *original_iface_decl = dyn_cast<ObjCInterfaceDecl>(original_decl))
- {
- ObjCInterfaceDecl *complete_iface_decl = GetCompleteObjCInterface(original_iface_decl);
+ const ConstString name(context.m_decl_name.getAsString().c_str());
- if (complete_iface_decl && (complete_iface_decl != original_iface_decl))
- {
- original_decl = complete_iface_decl;
- original_ctx = &complete_iface_decl->getASTContext();
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- m_ast_importer_sp->SetDeclOrigin(context_decl, original_iface_decl);
- }
+ 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, 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, 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, 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_sp->GetNamespaceMap(namespace_context);
+
+ if (log && log->GetVerbose())
+ 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) {
+ if (log)
+ log->Printf(" CAS::FEVD[%u] Searching namespace %s in module %s",
+ current_id, i->second.GetName().AsCString(),
+ i->first->GetFileSpec().GetFilename().GetCString());
+
+ FindExternalVisibleDecls(context, i->first, i->second, current_id);
}
+ } else if (isa<ObjCInterfaceDecl>(context.m_decl_context)) {
+ FindObjCPropertyAndIvarDecls(context);
+ } else if (!isa<TranslationUnitDecl>(context.m_decl_context)) {
+ // we shouldn't be getting FindExternalVisibleDecls calls for these
+ return;
+ } else {
+ CompilerDeclContext namespace_decl;
- if (TagDecl *original_tag_decl = dyn_cast<TagDecl>(original_decl))
- {
- ExternalASTSource *external_source = original_ctx->getExternalSource();
+ if (log)
+ log->Printf(" CAS::FEVD[%u] Searching the root namespace", current_id);
- if (external_source)
- external_source->CompleteType (original_tag_decl);
- }
+ FindExternalVisibleDecls(context, lldb::ModuleSP(), namespace_decl,
+ current_id);
+ }
- const DeclContext *original_decl_context = dyn_cast<DeclContext>(original_decl);
+ if (!context.m_namespace_map->empty()) {
+ if (log && log->GetVerbose())
+ log->Printf(" CAS::FEVD[%u] Registering namespace map %p (%d entries)",
+ current_id,
+ static_cast<void *>(context.m_namespace_map.get()),
+ static_cast<int>(context.m_namespace_map->size()));
- if (!original_decl_context)
- return;
+ NamespaceDecl *clang_namespace_decl =
+ AddNamespace(context, context.m_namespace_map);
- for (TagDecl::decl_iterator iter = original_decl_context->decls_begin();
- iter != original_decl_context->decls_end();
- ++iter)
- {
- Decl *decl = *iter;
-
- if (predicate(decl->getKind()))
- {
- if (log)
- {
- ASTDumper ast_dumper(decl);
- if (const NamedDecl *context_named_decl = dyn_cast<NamedDecl>(context_decl))
- log->Printf(" FELD[%d] Adding [to %sDecl %s] lexical %sDecl %s", current_id, context_named_decl->getDeclKindName(), context_named_decl->getNameAsString().c_str(), decl->getDeclKindName(), ast_dumper.GetCString());
- else
- log->Printf(" FELD[%d] Adding lexical %sDecl %s", current_id, decl->getDeclKindName(), ast_dumper.GetCString());
- }
-
- Decl *copied_decl = m_ast_importer_sp->CopyDecl(m_ast_context, original_ctx, decl);
+ if (clang_namespace_decl)
+ clang_namespace_decl->setHasExternalVisibleStorage();
+ }
+}
- if (!copied_decl)
- continue;
+void ClangASTSource::FindExternalVisibleDecls(
+ NameSearchContext &context, lldb::ModuleSP module_sp,
+ CompilerDeclContext &namespace_decl, unsigned int current_id) {
+ assert(m_ast_context);
- if (FieldDecl *copied_field = dyn_cast<FieldDecl>(copied_decl))
- {
- QualType copied_field_type = copied_field->getType();
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- m_ast_importer_sp->RequireCompleteType(copied_field_type);
- }
+ SymbolContextList sc_list;
- DeclContext *decl_context_non_const = const_cast<DeclContext *>(decl_context);
+ const ConstString name(context.m_decl_name.getAsString().c_str());
- 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);
- }
+ const char *name_unique_cstr = name.GetCString();
- if (!decl_context_non_const->containsDecl(copied_decl))
- decl_context_non_const->addDeclInternal(copied_decl);
- }
- }
+ static ConstString id_name("id");
+ static ConstString Class_name("Class");
+ if (name == id_name || name == Class_name)
return;
-}
-void
-ClangASTSource::FindExternalVisibleDecls (NameSearchContext &context)
-{
- assert (m_ast_context);
+ if (name_unique_cstr == NULL)
+ return;
- ClangASTMetrics::RegisterVisibleQuery();
+ // The ClangASTSource is not responsible for finding $-names.
+ if (name_unique_cstr[0] == '$')
+ return;
- const ConstString name(context.m_decl_name.getAsString().c_str());
+ if (module_sp && namespace_decl) {
+ CompilerDeclContext found_namespace_decl;
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ SymbolVendor *symbol_vendor = module_sp->GetSymbolVendor();
- static unsigned int invocation_id = 0;
- unsigned int current_id = invocation_id++;
+ if (symbol_vendor) {
+ SymbolContext null_sc;
- if (log)
- {
- if (!context.m_decl_context)
- 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, 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, static_cast<void*>(m_ast_context),
- name.GetCString(),
- context.m_decl_context->getDeclKindName());
- }
+ found_namespace_decl =
+ symbol_vendor->FindNamespace(null_sc, name, &namespace_decl);
- 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_sp->GetNamespaceMap(namespace_context);
-
- if (log && log->GetVerbose())
- 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)
- {
- if (log)
- log->Printf(" CAS::FEVD[%u] Searching namespace %s in module %s",
- current_id,
- i->second.GetName().AsCString(),
- i->first->GetFileSpec().GetFilename().GetCString());
-
- FindExternalVisibleDecls(context,
- i->first,
- i->second,
- current_id);
- }
- }
- else if (isa<ObjCInterfaceDecl>(context.m_decl_context))
- {
- FindObjCPropertyAndIvarDecls(context);
- }
- else if (!isa<TranslationUnitDecl>(context.m_decl_context))
- {
- // we shouldn't be getting FindExternalVisibleDecls calls for these
- return;
- }
- else
- {
- CompilerDeclContext namespace_decl;
+ if (found_namespace_decl) {
+ context.m_namespace_map->push_back(
+ std::pair<lldb::ModuleSP, CompilerDeclContext>(
+ module_sp, found_namespace_decl));
if (log)
- log->Printf(" CAS::FEVD[%u] Searching the root namespace", current_id);
-
- FindExternalVisibleDecls(context,
- lldb::ModuleSP(),
- namespace_decl,
- current_id);
+ log->Printf(" CAS::FEVD[%u] Found namespace %s in module %s",
+ current_id, name.GetCString(),
+ module_sp->GetFileSpec().GetFilename().GetCString());
+ }
}
+ } else {
+ const ModuleList &target_images = m_target->GetImages();
+ std::lock_guard<std::recursive_mutex> guard(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;
+
+ CompilerDeclContext found_namespace_decl;
- if (!context.m_namespace_map->empty())
- {
- if (log && log->GetVerbose())
- log->Printf(" CAS::FEVD[%u] Registering namespace map %p (%d entries)",
- current_id,
- static_cast<void*>(context.m_namespace_map.get()),
- static_cast<int>(context.m_namespace_map->size()));
+ SymbolVendor *symbol_vendor = image->GetSymbolVendor();
- NamespaceDecl *clang_namespace_decl = AddNamespace(context, context.m_namespace_map);
+ if (!symbol_vendor)
+ continue;
- if (clang_namespace_decl)
- clang_namespace_decl->setHasExternalVisibleStorage();
+ 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, CompilerDeclContext>(
+ image, found_namespace_decl));
+
+ if (log)
+ log->Printf(" CAS::FEVD[%u] Found namespace %s in module %s",
+ current_id, name.GetCString(),
+ image->GetFileSpec().GetFilename().GetCString());
+ }
}
-}
+ }
-void
-ClangASTSource::FindExternalVisibleDecls (NameSearchContext &context,
- lldb::ModuleSP module_sp,
- CompilerDeclContext &namespace_decl,
- unsigned int current_id)
-{
- assert (m_ast_context);
+ do {
+ if (context.m_found.type)
+ break;
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ TypeList types;
+ SymbolContext null_sc;
+ const bool exact_match = false;
+ llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
+ if (module_sp && namespace_decl)
+ module_sp->FindTypesInNamespace(null_sc, name, &namespace_decl, 1, types);
+ else
+ m_target->GetImages().FindTypes(null_sc, name, exact_match, 1,
+ searched_symbol_files, types);
- SymbolContextList sc_list;
+ if (size_t num_types = types.GetSize()) {
+ for (size_t ti = 0; ti < num_types; ++ti) {
+ lldb::TypeSP type_sp = types.GetTypeAtIndex(ti);
- const ConstString name(context.m_decl_name.getAsString().c_str());
+ if (log) {
+ const char *name_string = type_sp->GetName().GetCString();
- const char *name_unique_cstr = name.GetCString();
+ log->Printf(" CAS::FEVD[%u] Matching type found for \"%s\": %s",
+ current_id, name.GetCString(),
+ (name_string ? name_string : "<anonymous>"));
+ }
- static ConstString id_name("id");
- static ConstString Class_name("Class");
+ CompilerType full_type = type_sp->GetFullCompilerType();
- if (name == id_name || name == Class_name)
- return;
+ CompilerType copied_clang_type(GuardedCopyType(full_type));
- if (name_unique_cstr == NULL)
- return;
+ if (!copied_clang_type) {
+ if (log)
+ log->Printf(" CAS::FEVD[%u] - Couldn't export a type", current_id);
- // The ClangASTSource is not responsible for finding $-names.
- if (name_unique_cstr[0] == '$')
- return;
+ continue;
+ }
- if (module_sp && namespace_decl)
- {
- CompilerDeclContext found_namespace_decl;
+ context.AddTypeDecl(copied_clang_type);
- SymbolVendor *symbol_vendor = module_sp->GetSymbolVendor();
+ context.m_found.type = true;
+ break;
+ }
+ }
- if (symbol_vendor)
- {
- SymbolContext null_sc;
+ if (!context.m_found.type) {
+ // Try the modules next.
- found_namespace_decl = symbol_vendor->FindNamespace(null_sc, name, &namespace_decl);
+ do {
+ if (ClangModulesDeclVendor *modules_decl_vendor =
+ m_target->GetClangModulesDeclVendor()) {
+ bool append = false;
+ uint32_t max_matches = 1;
+ std::vector<clang::NamedDecl *> decls;
- if (found_namespace_decl)
- {
- context.m_namespace_map->push_back(std::pair<lldb::ModuleSP, CompilerDeclContext>(module_sp, found_namespace_decl));
+ if (!modules_decl_vendor->FindDecls(name, append, max_matches, decls))
+ break;
- if (log)
- log->Printf(" CAS::FEVD[%u] Found namespace %s in module %s",
- current_id,
- name.GetCString(),
- module_sp->GetFileSpec().GetFilename().GetCString());
+ if (log) {
+ log->Printf(" CAS::FEVD[%u] Matching entity found for \"%s\" in "
+ "the modules",
+ current_id, name.GetCString());
+ }
+
+ clang::NamedDecl *const decl_from_modules = decls[0];
+
+ if (llvm::isa<clang::TypeDecl>(decl_from_modules) ||
+ llvm::isa<clang::ObjCContainerDecl>(decl_from_modules) ||
+ llvm::isa<clang::EnumConstantDecl>(decl_from_modules)) {
+ clang::Decl *copied_decl = m_ast_importer_sp->CopyDecl(
+ m_ast_context, &decl_from_modules->getASTContext(),
+ decl_from_modules);
+ clang::NamedDecl *copied_named_decl =
+ copied_decl ? dyn_cast<clang::NamedDecl>(copied_decl) : nullptr;
+
+ if (!copied_named_decl) {
+ if (log)
+ log->Printf(
+ " CAS::FEVD[%u] - Couldn't export a type from the modules",
+ current_id);
+
+ break;
}
+
+ context.AddNamedDecl(copied_named_decl);
+
+ context.m_found.type = true;
+ }
}
+ } while (0);
}
- else
- {
- const ModuleList &target_images = m_target->GetImages();
- std::lock_guard<std::recursive_mutex> guard(target_images.GetMutex());
- for (size_t i = 0, e = target_images.GetSize(); i < e; ++i)
- {
- lldb::ModuleSP image = target_images.GetModuleAtIndexUnlocked(i);
+ if (!context.m_found.type) {
+ do {
+ // Couldn't find any types elsewhere. Try the Objective-C runtime if
+ // one exists.
- if (!image)
- continue;
+ lldb::ProcessSP process(m_target->GetProcessSP());
- CompilerDeclContext found_namespace_decl;
+ if (!process)
+ break;
- SymbolVendor *symbol_vendor = image->GetSymbolVendor();
+ ObjCLanguageRuntime *language_runtime(
+ process->GetObjCLanguageRuntime());
- if (!symbol_vendor)
- continue;
+ if (!language_runtime)
+ break;
- SymbolContext null_sc;
+ DeclVendor *decl_vendor = language_runtime->GetDeclVendor();
- found_namespace_decl = symbol_vendor->FindNamespace(null_sc, name, &namespace_decl);
+ if (!decl_vendor)
+ break;
- if (found_namespace_decl)
- {
- context.m_namespace_map->push_back(std::pair<lldb::ModuleSP, CompilerDeclContext>(image, found_namespace_decl));
+ bool append = false;
+ uint32_t max_matches = 1;
+ std::vector<clang::NamedDecl *> decls;
- if (log)
- log->Printf(" CAS::FEVD[%u] Found namespace %s in module %s",
- current_id,
- name.GetCString(),
- image->GetFileSpec().GetFilename().GetCString());
- }
- }
- }
+ if (!decl_vendor->FindDecls(name, append, max_matches, decls))
+ break;
- do
- {
- if (context.m_found.type)
- break;
-
- TypeList types;
- SymbolContext null_sc;
- const bool exact_match = false;
- llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
- if (module_sp && namespace_decl)
- module_sp->FindTypesInNamespace(null_sc, name, &namespace_decl, 1, types);
- else
- m_target->GetImages().FindTypes(null_sc, name, exact_match, 1, searched_symbol_files, types);
-
- if (size_t num_types = types.GetSize())
- {
- for (size_t ti = 0; ti < num_types; ++ti)
- {
- lldb::TypeSP type_sp = types.GetTypeAtIndex(ti);
-
- 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(),
- (name_string ? name_string : "<anonymous>"));
- }
-
- CompilerType full_type = type_sp->GetFullCompilerType();
-
- CompilerType copied_clang_type (GuardedCopyType(full_type));
-
- if (!copied_clang_type)
- {
- if (log)
- log->Printf(" CAS::FEVD[%u] - Couldn't export a type",
- current_id);
-
- continue;
- }
-
- context.AddTypeDecl(copied_clang_type);
-
- context.m_found.type = true;
- break;
- }
+ if (log) {
+ log->Printf(
+ " CAS::FEVD[%u] Matching type found for \"%s\" in the runtime",
+ current_id, name.GetCString());
}
- if (!context.m_found.type)
- {
- // Try the modules next.
-
- do
- {
- if (ClangModulesDeclVendor *modules_decl_vendor = m_target->GetClangModulesDeclVendor())
- {
- bool append = false;
- uint32_t max_matches = 1;
- std::vector <clang::NamedDecl *> decls;
-
- if (!modules_decl_vendor->FindDecls(name,
- append,
- max_matches,
- decls))
- break;
-
- if (log)
- {
- log->Printf(" CAS::FEVD[%u] Matching entity found for \"%s\" in the modules",
- current_id,
- name.GetCString());
- }
-
- clang::NamedDecl *const decl_from_modules = decls[0];
-
- if (llvm::isa<clang::TypeDecl>(decl_from_modules) ||
- llvm::isa<clang::ObjCContainerDecl>(decl_from_modules) ||
- llvm::isa<clang::EnumConstantDecl>(decl_from_modules))
- {
- clang::Decl *copied_decl = m_ast_importer_sp->CopyDecl(m_ast_context, &decl_from_modules->getASTContext(), decl_from_modules);
- clang::NamedDecl *copied_named_decl = copied_decl ? dyn_cast<clang::NamedDecl>(copied_decl) : nullptr;
-
- if (!copied_named_decl)
- {
- if (log)
- log->Printf(" CAS::FEVD[%u] - Couldn't export a type from the modules",
- current_id);
-
- break;
- }
-
- context.AddNamedDecl(copied_named_decl);
-
- context.m_found.type = true;
- }
- }
- } while (0);
- }
-
- if (!context.m_found.type)
- {
- 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;
-
- DeclVendor *decl_vendor = language_runtime->GetDeclVendor();
-
- if (!decl_vendor)
- break;
-
- bool append = false;
- uint32_t max_matches = 1;
- std::vector <clang::NamedDecl *> decls;
-
- if (!decl_vendor->FindDecls(name,
- append,
- max_matches,
- decls))
- break;
-
- if (log)
- {
- log->Printf(" CAS::FEVD[%u] Matching type found for \"%s\" in the runtime",
- current_id,
- name.GetCString());
- }
-
- clang::Decl *copied_decl = m_ast_importer_sp->CopyDecl(m_ast_context, &decls[0]->getASTContext(), decls[0]);
- clang::NamedDecl *copied_named_decl = copied_decl ? dyn_cast<clang::NamedDecl>(copied_decl) : nullptr;
-
- if (!copied_named_decl)
- {
- if (log)
- log->Printf(" CAS::FEVD[%u] - Couldn't export a type from the runtime",
- current_id);
-
- break;
- }
-
- context.AddNamedDecl(copied_named_decl);
- }
- while(0);
+ clang::Decl *copied_decl = m_ast_importer_sp->CopyDecl(
+ m_ast_context, &decls[0]->getASTContext(), decls[0]);
+ clang::NamedDecl *copied_named_decl =
+ copied_decl ? dyn_cast<clang::NamedDecl>(copied_decl) : nullptr;
+
+ if (!copied_named_decl) {
+ if (log)
+ log->Printf(
+ " CAS::FEVD[%u] - Couldn't export a type from the runtime",
+ current_id);
+
+ break;
}
- } while(0);
+ context.AddNamedDecl(copied_named_decl);
+ } while (0);
+ }
+
+ } while (0);
}
template <class D> class TaggedASTDecl {
public:
- TaggedASTDecl() : decl(NULL) { }
- TaggedASTDecl(D *_decl) : decl(_decl) { }
- bool IsValid() const { return (decl != NULL); }
- bool IsInvalid() const { return !IsValid(); }
- D *operator->() const { return decl; }
- D *decl;
+ TaggedASTDecl() : decl(NULL) {}
+ TaggedASTDecl(D *_decl) : decl(_decl) {}
+ bool IsValid() const { return (decl != NULL); }
+ bool IsInvalid() const { return !IsValid(); }
+ D *operator->() const { return decl; }
+ D *decl;
};
template <class D2, template <class D> class TD, class D1>
-TD<D2>
-DynCast(TD<D1> source)
-{
- return TD<D2> (dyn_cast<D2>(source.decl));
+TD<D2> DynCast(TD<D1> source) {
+ return TD<D2>(dyn_cast<D2>(source.decl));
}
template <class D = Decl> class DeclFromParser;
@@ -922,1179 +872,1141 @@ template <class D = Decl> class DeclFromUser;
template <class D> class DeclFromParser : public TaggedASTDecl<D> {
public:
- DeclFromParser() : TaggedASTDecl<D>() { }
- DeclFromParser(D *_decl) : TaggedASTDecl<D>(_decl) { }
+ DeclFromParser() : TaggedASTDecl<D>() {}
+ DeclFromParser(D *_decl) : TaggedASTDecl<D>(_decl) {}
- DeclFromUser<D> GetOrigin(ClangASTImporter *importer);
+ DeclFromUser<D> GetOrigin(ClangASTImporter *importer);
};
template <class D> class DeclFromUser : public TaggedASTDecl<D> {
public:
- DeclFromUser() : TaggedASTDecl<D>() { }
- DeclFromUser(D *_decl) : TaggedASTDecl<D>(_decl) { }
+ DeclFromUser() : TaggedASTDecl<D>() {}
+ DeclFromUser(D *_decl) : TaggedASTDecl<D>(_decl) {}
- DeclFromParser<D> Import(ClangASTImporter *importer, ASTContext &dest_ctx);
+ DeclFromParser<D> Import(ClangASTImporter *importer, ASTContext &dest_ctx);
};
template <class D>
-DeclFromUser<D>
-DeclFromParser<D>::GetOrigin(ClangASTImporter *importer)
-{
- DeclFromUser <> origin_decl;
- importer->ResolveDeclOrigin(this->decl, &origin_decl.decl, NULL);
- if (origin_decl.IsInvalid())
- return DeclFromUser<D>();
- return DeclFromUser<D>(dyn_cast<D>(origin_decl.decl));
+DeclFromUser<D> DeclFromParser<D>::GetOrigin(ClangASTImporter *importer) {
+ DeclFromUser<> origin_decl;
+ importer->ResolveDeclOrigin(this->decl, &origin_decl.decl, NULL);
+ if (origin_decl.IsInvalid())
+ return DeclFromUser<D>();
+ return DeclFromUser<D>(dyn_cast<D>(origin_decl.decl));
}
template <class D>
-DeclFromParser<D>
-DeclFromUser<D>::Import(ClangASTImporter *importer, ASTContext &dest_ctx)
-{
- DeclFromParser <> parser_generic_decl(importer->CopyDecl(&dest_ctx, &this->decl->getASTContext(), this->decl));
- if (parser_generic_decl.IsInvalid())
- return DeclFromParser<D>();
- return DeclFromParser<D>(dyn_cast<D>(parser_generic_decl.decl));
+DeclFromParser<D> DeclFromUser<D>::Import(ClangASTImporter *importer,
+ ASTContext &dest_ctx) {
+ DeclFromParser<> parser_generic_decl(
+ importer->CopyDecl(&dest_ctx, &this->decl->getASTContext(), this->decl));
+ if (parser_generic_decl.IsInvalid())
+ return DeclFromParser<D>();
+ return DeclFromParser<D>(dyn_cast<D>(parser_generic_decl.decl));
}
-static bool
-FindObjCMethodDeclsWithOrigin (unsigned int current_id,
- NameSearchContext &context,
- ObjCInterfaceDecl *original_interface_decl,
- clang::ASTContext *ast_context,
- ClangASTImporter *ast_importer,
- const char *log_info)
-{
- const DeclarationName &decl_name(context.m_decl_name);
- clang::ASTContext *original_ctx = &original_interface_decl->getASTContext();
-
- Selector original_selector;
-
- if (decl_name.isObjCZeroArgSelector())
- {
- IdentifierInfo *ident = &original_ctx->Idents.get(decl_name.getAsString());
- original_selector = original_ctx->Selectors.getSelector(0, &ident);
- }
- else if (decl_name.isObjCOneArgSelector())
- {
- const std::string &decl_name_string = decl_name.getAsString();
- std::string decl_name_string_without_colon(decl_name_string.c_str(), decl_name_string.length() - 1);
- IdentifierInfo *ident = &original_ctx->Idents.get(decl_name_string_without_colon.c_str());
- original_selector = original_ctx->Selectors.getSelector(1, &ident);
+static bool FindObjCMethodDeclsWithOrigin(
+ unsigned int current_id, NameSearchContext &context,
+ ObjCInterfaceDecl *original_interface_decl, clang::ASTContext *ast_context,
+ ClangASTImporter *ast_importer, const char *log_info) {
+ const DeclarationName &decl_name(context.m_decl_name);
+ clang::ASTContext *original_ctx = &original_interface_decl->getASTContext();
+
+ Selector original_selector;
+
+ if (decl_name.isObjCZeroArgSelector()) {
+ IdentifierInfo *ident = &original_ctx->Idents.get(decl_name.getAsString());
+ original_selector = original_ctx->Selectors.getSelector(0, &ident);
+ } else if (decl_name.isObjCOneArgSelector()) {
+ const std::string &decl_name_string = decl_name.getAsString();
+ std::string decl_name_string_without_colon(decl_name_string.c_str(),
+ decl_name_string.length() - 1);
+ IdentifierInfo *ident =
+ &original_ctx->Idents.get(decl_name_string_without_colon.c_str());
+ original_selector = original_ctx->Selectors.getSelector(1, &ident);
+ } 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)));
}
- else
- {
- SmallVector<IdentifierInfo *, 4> idents;
- clang::Selector sel = decl_name.getObjCSelector();
+ original_selector =
+ original_ctx->Selectors.getSelector(num_args, idents.data());
+ }
- unsigned num_args = sel.getNumArgs();
+ DeclarationName original_decl_name(original_selector);
- for (unsigned i = 0;
- i != num_args;
- ++i)
- {
- idents.push_back(&original_ctx->Idents.get(sel.getNameForSlot(i)));
- }
+ llvm::SmallVector<NamedDecl *, 1> methods;
- original_selector = original_ctx->Selectors.getSelector(num_args, idents.data());
- }
+ ClangASTContext::GetCompleteDecl(original_ctx, original_interface_decl);
- DeclarationName original_decl_name(original_selector);
-
- llvm::SmallVector<NamedDecl *, 1> methods;
-
- ClangASTContext::GetCompleteDecl(original_ctx, original_interface_decl);
-
- if (ObjCMethodDecl *instance_method_decl = original_interface_decl->lookupInstanceMethod(original_selector))
- {
- methods.push_back(instance_method_decl);
- }
- else if (ObjCMethodDecl *class_method_decl = original_interface_decl->lookupClassMethod(original_selector))
- {
- methods.push_back(class_method_decl);
- }
-
- if (methods.empty())
- {
- return false;
- }
-
- for (NamedDecl *named_decl : methods)
- {
- if (!named_decl)
- continue;
-
- ObjCMethodDecl *result_method = dyn_cast<ObjCMethodDecl>(named_decl);
+ if (ObjCMethodDecl *instance_method_decl =
+ original_interface_decl->lookupInstanceMethod(original_selector)) {
+ methods.push_back(instance_method_decl);
+ } else if (ObjCMethodDecl *class_method_decl =
+ original_interface_decl->lookupClassMethod(
+ original_selector)) {
+ methods.push_back(class_method_decl);
+ }
- if (!result_method)
- continue;
+ if (methods.empty()) {
+ return false;
+ }
- Decl *copied_decl = ast_importer->CopyDecl(ast_context, &result_method->getASTContext(), result_method);
+ for (NamedDecl *named_decl : methods) {
+ if (!named_decl)
+ continue;
- if (!copied_decl)
- continue;
+ ObjCMethodDecl *result_method = dyn_cast<ObjCMethodDecl>(named_decl);
- ObjCMethodDecl *copied_method_decl = dyn_cast<ObjCMethodDecl>(copied_decl);
+ if (!result_method)
+ continue;
- if (!copied_method_decl)
- continue;
+ Decl *copied_decl = ast_importer->CopyDecl(
+ ast_context, &result_method->getASTContext(), result_method);
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ if (!copied_decl)
+ continue;
- if (log)
- {
- ASTDumper dumper((Decl*)copied_method_decl);
- log->Printf(" CAS::FOMD[%d] found (%s) %s", current_id, log_info, dumper.GetCString());
- }
+ ObjCMethodDecl *copied_method_decl = dyn_cast<ObjCMethodDecl>(copied_decl);
- context.AddNamedDecl(copied_method_decl);
+ if (!copied_method_decl)
+ continue;
+
+ 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());
}
- return true;
+ context.AddNamedDecl(copied_method_decl);
+ }
+
+ return true;
}
-void
-ClangASTSource::FindObjCMethodDecls (NameSearchContext &context)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+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++;
+ 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 DeclarationName &decl_name(context.m_decl_name);
+ const DeclContext *decl_ctx(context.m_decl_context);
- const ObjCInterfaceDecl *interface_decl = dyn_cast<ObjCInterfaceDecl>(decl_ctx);
+ const ObjCInterfaceDecl *interface_decl =
+ dyn_cast<ObjCInterfaceDecl>(decl_ctx);
- if (!interface_decl)
- return;
+ if (!interface_decl)
+ return;
- do
- {
- Decl *original_decl = NULL;
- ASTContext *original_ctx = NULL;
+ do {
+ Decl *original_decl = NULL;
+ ASTContext *original_ctx = NULL;
- m_ast_importer_sp->ResolveDeclOrigin(interface_decl, &original_decl, &original_ctx);
+ m_ast_importer_sp->ResolveDeclOrigin(interface_decl, &original_decl,
+ &original_ctx);
- if (!original_decl)
- break;
+ if (!original_decl)
+ break;
- ObjCInterfaceDecl *original_interface_decl = dyn_cast<ObjCInterfaceDecl>(original_decl);
+ ObjCInterfaceDecl *original_interface_decl =
+ dyn_cast<ObjCInterfaceDecl>(original_decl);
- if (FindObjCMethodDeclsWithOrigin(current_id,
- context,
- original_interface_decl,
- m_ast_context,
- m_ast_importer_sp.get(),
- "at origin"))
- return; // found it, no need to look any further
- } while (0);
+ if (FindObjCMethodDeclsWithOrigin(current_id, context,
+ original_interface_decl, m_ast_context,
+ m_ast_importer_sp.get(), "at origin"))
+ return; // found it, no need to look any further
+ } while (0);
- StreamString ss;
+ StreamString ss;
- if (decl_name.isObjCZeroArgSelector())
- {
- ss.Printf("%s", decl_name.getAsString().c_str());
- }
- else if (decl_name.isObjCOneArgSelector())
- {
- 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());
- }
+ if (decl_name.isObjCZeroArgSelector()) {
+ ss.Printf("%s", decl_name.getAsString().c_str());
+ } else if (decl_name.isObjCOneArgSelector()) {
+ 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.Flush();
+ }
+ ss.Flush();
- if (strstr(ss.GetData(), "$__lldb"))
- return; // we don't need any results
+ if (strstr(ss.GetData(), "$__lldb"))
+ return; // we don't need any results
- ConstString selector_name(ss.GetData());
+ ConstString selector_name(ss.GetData());
- if (log)
- log->Printf("ClangASTSource::FindObjCMethodDecls[%d] on (ASTContext*)%p for selector [%s %s]",
- current_id, static_cast<void*>(m_ast_context),
- interface_decl->getNameAsString().c_str(),
- selector_name.AsCString());
- SymbolContextList sc_list;
+ if (log)
+ log->Printf("ClangASTSource::FindObjCMethodDecls[%d] on (ASTContext*)%p "
+ "for selector [%s %s]",
+ 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;
+ const bool include_symbols = false;
+ const bool include_inlines = false;
+ const bool append = false;
- std::string interface_name = interface_decl->getNameAsString();
+ 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());
+ 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);
+ m_target->GetImages().FindFunctions(
+ instance_method_name, lldb::eFunctionNameTypeFull, include_symbols,
+ include_inlines, append, sc_list);
- if (sc_list.GetSize())
- break;
+ 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());
+ 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);
+ m_target->GetImages().FindFunctions(
+ class_method_name, lldb::eFunctionNameTypeFull, include_symbols,
+ include_inlines, append, sc_list);
- if (sc_list.GetSize())
- break;
+ 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.
+ // 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;
+ SymbolContextList candidate_sc_list;
- m_target->GetImages().FindFunctions(selector_name, lldb::eFunctionNameTypeSelector, include_symbols, include_inlines, append, 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;
+ 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_list.GetContextAtIndex(ci, candidate_sc))
+ continue;
- if (!candidate_sc.function)
- continue;
+ if (!candidate_sc.function)
+ continue;
- const char *candidate_name = candidate_sc.function->GetName().AsCString();
+ const char *candidate_name = candidate_sc.function->GetName().AsCString();
- const char *cursor = candidate_name;
+ const char *cursor = candidate_name;
- if (*cursor != '+' && *cursor != '-')
- continue;
+ if (*cursor != '+' && *cursor != '-')
+ continue;
- ++cursor;
+ ++cursor;
- if (*cursor != '[')
- continue;
+ if (*cursor != '[')
+ continue;
- ++cursor;
+ ++cursor;
- size_t interface_len = interface_name.length();
+ size_t interface_len = interface_name.length();
- if (strncmp(cursor, interface_name.c_str(), interface_len))
- continue;
+ if (strncmp(cursor, interface_name.c_str(), interface_len))
+ continue;
- cursor += interface_len;
+ cursor += interface_len;
- if (*cursor == ' ' || *cursor == '(')
- sc_list.Append(candidate_sc);
- }
+ if (*cursor == ' ' || *cursor == '(')
+ sc_list.Append(candidate_sc);
}
- while (0);
-
- if (sc_list.GetSize())
- {
- // We found a good function symbol. Use that.
+ } while (0);
- for (uint32_t i = 0, e = sc_list.GetSize();
- i != e;
- ++i)
- {
- SymbolContext sc;
+ if (sc_list.GetSize()) {
+ // We found a good function symbol. Use that.
- if (!sc_list.GetContextAtIndex(i, sc))
- continue;
+ for (uint32_t i = 0, e = sc_list.GetSize(); i != e; ++i) {
+ SymbolContext sc;
- if (!sc.function)
- continue;
+ if (!sc_list.GetContextAtIndex(i, sc))
+ continue;
- CompilerDeclContext function_decl_ctx = sc.function->GetDeclContext();
- if (!function_decl_ctx)
- continue;
+ if (!sc.function)
+ continue;
- ObjCMethodDecl *method_decl = ClangASTContext::DeclContextGetAsObjCMethodDecl(function_decl_ctx);
+ CompilerDeclContext function_decl_ctx = sc.function->GetDeclContext();
+ if (!function_decl_ctx)
+ continue;
- if (!method_decl)
- continue;
+ ObjCMethodDecl *method_decl =
+ ClangASTContext::DeclContextGetAsObjCMethodDecl(function_decl_ctx);
- ObjCInterfaceDecl *found_interface_decl = method_decl->getClassInterface();
+ if (!method_decl)
+ continue;
- if (!found_interface_decl)
- continue;
+ ObjCInterfaceDecl *found_interface_decl =
+ method_decl->getClassInterface();
- if (found_interface_decl->getName() == interface_decl->getName())
- {
- Decl *copied_decl = m_ast_importer_sp->CopyDecl(m_ast_context, &method_decl->getASTContext(), method_decl);
+ if (!found_interface_decl)
+ continue;
- if (!copied_decl)
- continue;
+ if (found_interface_decl->getName() == interface_decl->getName()) {
+ Decl *copied_decl = m_ast_importer_sp->CopyDecl(
+ m_ast_context, &method_decl->getASTContext(), method_decl);
- ObjCMethodDecl *copied_method_decl = dyn_cast<ObjCMethodDecl>(copied_decl);
+ if (!copied_decl)
+ continue;
- if (!copied_method_decl)
- continue;
+ ObjCMethodDecl *copied_method_decl =
+ dyn_cast<ObjCMethodDecl>(copied_decl);
- if (log)
- {
- ASTDumper dumper((Decl*)copied_method_decl);
- log->Printf(" CAS::FOMD[%d] found (in symbols) %s", current_id, dumper.GetCString());
- }
+ if (!copied_method_decl)
+ continue;
- context.AddNamedDecl(copied_method_decl);
- }
+ if (log) {
+ ASTDumper dumper((Decl *)copied_method_decl);
+ log->Printf(" CAS::FOMD[%d] found (in symbols) %s", current_id,
+ dumper.GetCString());
}
- return;
+ context.AddNamedDecl(copied_method_decl);
+ }
}
- // Try the debug information.
+ return;
+ }
- do
- {
- ObjCInterfaceDecl *complete_interface_decl = GetCompleteObjCInterface(const_cast<ObjCInterfaceDecl*>(interface_decl));
+ // Try the debug information.
- if (!complete_interface_decl)
- break;
+ do {
+ ObjCInterfaceDecl *complete_interface_decl = GetCompleteObjCInterface(
+ const_cast<ObjCInterfaceDecl *>(interface_decl));
- // We found the complete interface. The runtime never needs to be queried in this scenario.
+ if (!complete_interface_decl)
+ break;
- DeclFromUser<const ObjCInterfaceDecl> complete_iface_decl(complete_interface_decl);
+ // We found the complete interface. The runtime never needs to be queried
+ // in this scenario.
- if (complete_interface_decl == interface_decl)
- break; // already checked this one
+ DeclFromUser<const ObjCInterfaceDecl> complete_iface_decl(
+ complete_interface_decl);
- if (log)
- log->Printf("CAS::FOPD[%d] trying origin (ObjCInterfaceDecl*)%p/(ASTContext*)%p...",
- current_id, static_cast<void*>(complete_interface_decl),
- static_cast<void*>(&complete_iface_decl->getASTContext()));
+ 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, 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_sp.get(),
+ "in debug info");
+
+ return;
+ } while (0);
+
+ do {
+ // Check the modules only if the debug information didn't have a complete
+ // interface.
+
+ if (ClangModulesDeclVendor *modules_decl_vendor =
+ m_target->GetClangModulesDeclVendor()) {
+ ConstString interface_name(interface_decl->getNameAsString().c_str());
+ bool append = false;
+ uint32_t max_matches = 1;
+ std::vector<clang::NamedDecl *> decls;
+
+ if (!modules_decl_vendor->FindDecls(interface_name, append, max_matches,
+ decls))
+ break;
+
+ ObjCInterfaceDecl *interface_decl_from_modules =
+ dyn_cast<ObjCInterfaceDecl>(decls[0]);
- FindObjCMethodDeclsWithOrigin(current_id,
- context,
- complete_interface_decl,
- m_ast_context,
- m_ast_importer_sp.get(),
- "in debug info");
+ if (!interface_decl_from_modules)
+ break;
+ if (FindObjCMethodDeclsWithOrigin(
+ current_id, context, interface_decl_from_modules, m_ast_context,
+ m_ast_importer_sp.get(), "in modules"))
return;
}
- while (0);
-
- do
- {
- // Check the modules only if the debug information didn't have a complete interface.
-
- if (ClangModulesDeclVendor *modules_decl_vendor = m_target->GetClangModulesDeclVendor())
- {
- ConstString interface_name(interface_decl->getNameAsString().c_str());
- bool append = false;
- uint32_t max_matches = 1;
- std::vector <clang::NamedDecl *> decls;
-
- if (!modules_decl_vendor->FindDecls(interface_name,
- append,
- max_matches,
- decls))
- break;
-
- ObjCInterfaceDecl *interface_decl_from_modules = dyn_cast<ObjCInterfaceDecl>(decls[0]);
-
- if (!interface_decl_from_modules)
- break;
-
- if (FindObjCMethodDeclsWithOrigin(current_id,
- context,
- interface_decl_from_modules,
- m_ast_context,
- m_ast_importer_sp.get(),
- "in modules"))
- return;
- }
- }
- while (0);
+ } while (0);
- do
- {
- // Check the runtime only if the debug information didn't have a complete interface and the modules don't get us anywhere.
+ do {
+ // Check the runtime only if the debug information didn't have a complete
+ // interface and the modules don't get us anywhere.
- lldb::ProcessSP process(m_target->GetProcessSP());
+ lldb::ProcessSP process(m_target->GetProcessSP());
- if (!process)
- break;
+ if (!process)
+ break;
- ObjCLanguageRuntime *language_runtime(process->GetObjCLanguageRuntime());
+ ObjCLanguageRuntime *language_runtime(process->GetObjCLanguageRuntime());
- if (!language_runtime)
- break;
+ if (!language_runtime)
+ break;
- DeclVendor *decl_vendor = language_runtime->GetDeclVendor();
+ DeclVendor *decl_vendor = language_runtime->GetDeclVendor();
- if (!decl_vendor)
- break;
+ if (!decl_vendor)
+ break;
- ConstString interface_name(interface_decl->getNameAsString().c_str());
- bool append = false;
- uint32_t max_matches = 1;
- std::vector <clang::NamedDecl *> decls;
+ ConstString interface_name(interface_decl->getNameAsString().c_str());
+ bool append = false;
+ uint32_t max_matches = 1;
+ std::vector<clang::NamedDecl *> decls;
- if (!decl_vendor->FindDecls(interface_name,
- append,
- max_matches,
- decls))
- break;
+ if (!decl_vendor->FindDecls(interface_name, append, max_matches, decls))
+ break;
- ObjCInterfaceDecl *runtime_interface_decl = dyn_cast<ObjCInterfaceDecl>(decls[0]);
-
- if (!runtime_interface_decl)
- break;
+ ObjCInterfaceDecl *runtime_interface_decl =
+ dyn_cast<ObjCInterfaceDecl>(decls[0]);
- FindObjCMethodDeclsWithOrigin(current_id,
- context,
- runtime_interface_decl,
- m_ast_context,
- m_ast_importer_sp.get(),
- "in runtime");
- }
- while(0);
+ if (!runtime_interface_decl)
+ break;
+
+ FindObjCMethodDeclsWithOrigin(current_id, context, runtime_interface_decl,
+ m_ast_context, m_ast_importer_sp.get(),
+ "in runtime");
+ } while (0);
}
-static bool
-FindObjCPropertyAndIvarDeclsWithOrigin (unsigned int current_id,
- NameSearchContext &context,
- clang::ASTContext &ast_context,
- ClangASTImporter *ast_importer,
- DeclFromUser<const ObjCInterfaceDecl> &origin_iface_decl)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+static bool FindObjCPropertyAndIvarDeclsWithOrigin(
+ unsigned int current_id, NameSearchContext &context,
+ clang::ASTContext &ast_context, ClangASTImporter *ast_importer,
+ DeclFromUser<const ObjCInterfaceDecl> &origin_iface_decl) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+
+ 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, ObjCPropertyQueryKind::OBJC_PR_query_instance));
+
+ bool found = false;
+
+ if (origin_property_decl.IsValid()) {
+ DeclFromParser<ObjCPropertyDecl> parser_property_decl(
+ origin_property_decl.Import(ast_importer, ast_context));
+ if (parser_property_decl.IsValid()) {
+ if (log) {
+ 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));
+ if (parser_ivar_decl.IsValid()) {
+ if (log) {
+ 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;
+ }
+ }
- if (origin_iface_decl.IsInvalid())
- return false;
+ return found;
+}
- 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));
+void ClangASTSource::FindObjCPropertyAndIvarDecls(NameSearchContext &context) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- DeclFromUser<ObjCPropertyDecl> origin_property_decl(origin_iface_decl->FindPropertyDeclaration(&name_identifier, ObjCPropertyQueryKind::OBJC_PR_query_instance));
+ static unsigned int invocation_id = 0;
+ unsigned int current_id = invocation_id++;
- bool found = false;
+ 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_sp.get()));
- if (origin_property_decl.IsValid())
- {
- DeclFromParser<ObjCPropertyDecl> parser_property_decl(origin_property_decl.Import(ast_importer, ast_context));
- if (parser_property_decl.IsValid())
- {
- if (log)
- {
- ASTDumper dumper((Decl*)parser_property_decl.decl);
- log->Printf(" CAS::FOPD[%d] found %s", current_id, dumper.GetCString());
- }
+ ConstString class_name(parser_iface_decl->getNameAsString().c_str());
- context.AddNamedDecl(parser_property_decl.decl);
- found = true;
- }
- }
+ if (log)
+ log->Printf("ClangASTSource::FindObjCPropertyAndIvarDecls[%d] on "
+ "(ASTContext*)%p for '%s.%s'",
+ current_id, static_cast<void *>(m_ast_context),
+ parser_iface_decl->getNameAsString().c_str(),
+ context.m_decl_name.getAsString().c_str());
- 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));
- if (parser_ivar_decl.IsValid())
- {
- if (log)
- {
- ASTDumper dumper((Decl*)parser_ivar_decl.decl);
- log->Printf(" CAS::FOPD[%d] found %s", current_id, dumper.GetCString());
- }
+ if (FindObjCPropertyAndIvarDeclsWithOrigin(
+ current_id, context, *m_ast_context, m_ast_importer_sp.get(),
+ origin_iface_decl))
+ return;
- context.AddNamedDecl(parser_ivar_decl.decl);
- found = true;
- }
- }
+ if (log)
+ log->Printf("CAS::FOPD[%d] couldn't find the property on origin "
+ "(ObjCInterfaceDecl*)%p/(ASTContext*)%p, searching "
+ "elsewhere...",
+ current_id, static_cast<const void *>(origin_iface_decl.decl),
+ static_cast<void *>(&origin_iface_decl->getASTContext()));
- return found;
-}
+ SymbolContext null_sc;
+ TypeList type_list;
-void
-ClangASTSource::FindObjCPropertyAndIvarDecls (NameSearchContext &context)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ do {
+ ObjCInterfaceDecl *complete_interface_decl = GetCompleteObjCInterface(
+ const_cast<ObjCInterfaceDecl *>(parser_iface_decl.decl));
- static unsigned int invocation_id = 0;
- unsigned int current_id = invocation_id++;
+ if (!complete_interface_decl)
+ break;
- 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_sp.get()));
+ // We found the complete interface. The runtime never needs to be queried
+ // in this scenario.
- ConstString class_name(parser_iface_decl->getNameAsString().c_str());
+ DeclFromUser<const ObjCInterfaceDecl> complete_iface_decl(
+ complete_interface_decl);
- if (log)
- log->Printf("ClangASTSource::FindObjCPropertyAndIvarDecls[%d] on (ASTContext*)%p for '%s.%s'",
- 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_sp.get(),
- origin_iface_decl))
- return;
+ if (complete_iface_decl.decl == origin_iface_decl.decl)
+ break; // already checked this one
if (log)
- log->Printf("CAS::FOPD[%d] couldn't find the property on origin (ObjCInterfaceDecl*)%p/(ASTContext*)%p, searching elsewhere...",
- current_id, static_cast<const void*>(origin_iface_decl.decl),
- static_cast<void*>(&origin_iface_decl->getASTContext()));
+ log->Printf("CAS::FOPD[%d] trying origin "
+ "(ObjCInterfaceDecl*)%p/(ASTContext*)%p...",
+ current_id,
+ static_cast<const void *>(complete_iface_decl.decl),
+ static_cast<void *>(&complete_iface_decl->getASTContext()));
- SymbolContext null_sc;
- TypeList type_list;
+ FindObjCPropertyAndIvarDeclsWithOrigin(current_id, context, *m_ast_context,
+ m_ast_importer_sp.get(),
+ complete_iface_decl);
- do
- {
- ObjCInterfaceDecl *complete_interface_decl = GetCompleteObjCInterface(const_cast<ObjCInterfaceDecl*>(parser_iface_decl.decl));
+ return;
+ } while (0);
- if (!complete_interface_decl)
- break;
+ do {
+ // Check the modules only if the debug information didn't have a complete
+ // interface.
- // We found the complete interface. The runtime never needs to be queried in this scenario.
+ ClangModulesDeclVendor *modules_decl_vendor =
+ m_target->GetClangModulesDeclVendor();
- DeclFromUser<const ObjCInterfaceDecl> complete_iface_decl(complete_interface_decl);
+ if (!modules_decl_vendor)
+ break;
- if (complete_iface_decl.decl == origin_iface_decl.decl)
- break; // already checked this one
+ bool append = false;
+ uint32_t max_matches = 1;
+ std::vector<clang::NamedDecl *> decls;
- if (log)
- log->Printf("CAS::FOPD[%d] trying origin (ObjCInterfaceDecl*)%p/(ASTContext*)%p...",
- current_id,
- static_cast<const void*>(complete_iface_decl.decl),
- static_cast<void*>(&complete_iface_decl->getASTContext()));
+ if (!modules_decl_vendor->FindDecls(class_name, append, max_matches, decls))
+ break;
- FindObjCPropertyAndIvarDeclsWithOrigin(current_id,
- context,
- *m_ast_context,
- m_ast_importer_sp.get(),
- complete_iface_decl);
+ DeclFromUser<const ObjCInterfaceDecl> interface_decl_from_modules(
+ dyn_cast<ObjCInterfaceDecl>(decls[0]));
- return;
- }
- while(0);
-
- do
- {
- // Check the modules only if the debug information didn't have a complete interface.
-
- ClangModulesDeclVendor *modules_decl_vendor = m_target->GetClangModulesDeclVendor();
-
- if (!modules_decl_vendor)
- break;
-
- bool append = false;
- uint32_t max_matches = 1;
- std::vector <clang::NamedDecl *> decls;
-
- if (!modules_decl_vendor->FindDecls(class_name,
- append,
- max_matches,
- decls))
- break;
-
- DeclFromUser<const ObjCInterfaceDecl> interface_decl_from_modules(dyn_cast<ObjCInterfaceDecl>(decls[0]));
-
- if (!interface_decl_from_modules.IsValid())
- break;
-
- if (log)
- log->Printf("CAS::FOPD[%d] trying module (ObjCInterfaceDecl*)%p/(ASTContext*)%p...",
- current_id,
- static_cast<const void*>(interface_decl_from_modules.decl),
- static_cast<void*>(&interface_decl_from_modules->getASTContext()));
-
- if (FindObjCPropertyAndIvarDeclsWithOrigin(current_id,
- context,
- *m_ast_context,
- m_ast_importer_sp.get(),
- interface_decl_from_modules))
- return;
- }
- while(0);
+ if (!interface_decl_from_modules.IsValid())
+ break;
- do
- {
- // Check the runtime only if the debug information didn't have a complete interface
- // and nothing was in the modules.
+ if (log)
+ log->Printf(
+ "CAS::FOPD[%d] trying module "
+ "(ObjCInterfaceDecl*)%p/(ASTContext*)%p...",
+ current_id,
+ static_cast<const void *>(interface_decl_from_modules.decl),
+ static_cast<void *>(&interface_decl_from_modules->getASTContext()));
+
+ if (FindObjCPropertyAndIvarDeclsWithOrigin(
+ current_id, context, *m_ast_context, m_ast_importer_sp.get(),
+ interface_decl_from_modules))
+ return;
+ } while (0);
+
+ do {
+ // Check the runtime only if the debug information didn't have a complete
+ // interface
+ // and nothing was in the modules.
- lldb::ProcessSP process(m_target->GetProcessSP());
+ lldb::ProcessSP process(m_target->GetProcessSP());
- if (!process)
- return;
+ if (!process)
+ return;
- ObjCLanguageRuntime *language_runtime(process->GetObjCLanguageRuntime());
+ ObjCLanguageRuntime *language_runtime(process->GetObjCLanguageRuntime());
- if (!language_runtime)
- return;
+ if (!language_runtime)
+ return;
- DeclVendor *decl_vendor = language_runtime->GetDeclVendor();
+ DeclVendor *decl_vendor = language_runtime->GetDeclVendor();
- if (!decl_vendor)
- break;
+ if (!decl_vendor)
+ break;
- bool append = false;
- uint32_t max_matches = 1;
- std::vector <clang::NamedDecl *> decls;
+ bool append = false;
+ uint32_t max_matches = 1;
+ std::vector<clang::NamedDecl *> decls;
- if (!decl_vendor->FindDecls(class_name,
- append,
- max_matches,
- decls))
- break;
+ if (!decl_vendor->FindDecls(class_name, append, max_matches, decls))
+ break;
- DeclFromUser<const ObjCInterfaceDecl> interface_decl_from_runtime(dyn_cast<ObjCInterfaceDecl>(decls[0]));
-
- if (!interface_decl_from_runtime.IsValid())
- break;
+ DeclFromUser<const ObjCInterfaceDecl> interface_decl_from_runtime(
+ dyn_cast<ObjCInterfaceDecl>(decls[0]));
- if (log)
- log->Printf("CAS::FOPD[%d] trying runtime (ObjCInterfaceDecl*)%p/(ASTContext*)%p...",
- current_id,
- static_cast<const void*>(interface_decl_from_runtime.decl),
- static_cast<void*>(&interface_decl_from_runtime->getASTContext()));
-
- if (FindObjCPropertyAndIvarDeclsWithOrigin(current_id,
- context,
- *m_ast_context,
- m_ast_importer_sp.get(),
- interface_decl_from_runtime))
- return;
- }
- while(0);
+ if (!interface_decl_from_runtime.IsValid())
+ break;
+
+ if (log)
+ log->Printf(
+ "CAS::FOPD[%d] trying runtime "
+ "(ObjCInterfaceDecl*)%p/(ASTContext*)%p...",
+ current_id,
+ static_cast<const void *>(interface_decl_from_runtime.decl),
+ static_cast<void *>(&interface_decl_from_runtime->getASTContext()));
+
+ if (FindObjCPropertyAndIvarDeclsWithOrigin(
+ current_id, context, *m_ast_context, m_ast_importer_sp.get(),
+ interface_decl_from_runtime))
+ return;
+ } while (0);
}
typedef llvm::DenseMap<const FieldDecl *, uint64_t> FieldOffsetMap;
typedef llvm::DenseMap<const CXXRecordDecl *, CharUnits> BaseOffsetMap;
template <class D, class O>
-static bool
-ImportOffsetMap(llvm::DenseMap<const D *, O> &destination_map, llvm::DenseMap<const D *, O> &source_map,
- ClangASTImporter *importer, ASTContext &dest_ctx)
-{
- // When importing fields into a new record, clang has a hard requirement that
- // fields be imported in field offset order. Since they are stored in a DenseMap
- // with a pointer as the key type, this means we cannot simply iterate over the
- // map, as the order will be non-deterministic. Instead we have to sort by the offset
- // and then insert in sorted order.
- typedef llvm::DenseMap<const D *, O> MapType;
- typedef typename MapType::value_type PairType;
- std::vector<PairType> sorted_items;
- sorted_items.reserve(source_map.size());
- sorted_items.assign(source_map.begin(), source_map.end());
- std::sort(sorted_items.begin(), sorted_items.end(),
- [](const PairType &lhs, const PairType &rhs)
- {
- return lhs.second < rhs.second;
- });
-
- for (const auto &item : sorted_items)
- {
- DeclFromUser<D> user_decl(const_cast<D *>(item.first));
- DeclFromParser <D> parser_decl(user_decl.Import(importer, dest_ctx));
- if (parser_decl.IsInvalid())
- return false;
- destination_map.insert(std::pair<const D *, O>(parser_decl.decl, item.second));
- }
+static bool ImportOffsetMap(llvm::DenseMap<const D *, O> &destination_map,
+ llvm::DenseMap<const D *, O> &source_map,
+ ClangASTImporter *importer, ASTContext &dest_ctx) {
+ // When importing fields into a new record, clang has a hard requirement that
+ // fields be imported in field offset order. Since they are stored in a
+ // DenseMap
+ // with a pointer as the key type, this means we cannot simply iterate over
+ // the
+ // map, as the order will be non-deterministic. Instead we have to sort by
+ // the offset
+ // and then insert in sorted order.
+ typedef llvm::DenseMap<const D *, O> MapType;
+ typedef typename MapType::value_type PairType;
+ std::vector<PairType> sorted_items;
+ sorted_items.reserve(source_map.size());
+ sorted_items.assign(source_map.begin(), source_map.end());
+ std::sort(sorted_items.begin(), sorted_items.end(),
+ [](const PairType &lhs, const PairType &rhs) {
+ return lhs.second < rhs.second;
+ });
+
+ for (const auto &item : sorted_items) {
+ DeclFromUser<D> user_decl(const_cast<D *>(item.first));
+ DeclFromParser<D> parser_decl(user_decl.Import(importer, dest_ctx));
+ if (parser_decl.IsInvalid())
+ return false;
+ destination_map.insert(
+ std::pair<const D *, O>(parser_decl.decl, item.second));
+ }
- return true;
+ return true;
}
template <bool IsVirtual>
-bool
-ExtractBaseOffsets(const ASTRecordLayout &record_layout, DeclFromUser<const CXXRecordDecl> &record,
- BaseOffsetMap &base_offsets)
-{
- 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;
+bool ExtractBaseOffsets(const ASTRecordLayout &record_layout,
+ DeclFromUser<const CXXRecordDecl> &record,
+ BaseOffsetMap &base_offsets) {
+ 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;
- const clang::Type *origin_base_type = bi->getType().getTypePtr();
- const clang::RecordType *origin_base_record_type = origin_base_type->getAs<RecordType>();
+ DeclFromUser<RecordDecl> origin_base_record(
+ origin_base_record_type->getDecl());
- if (!origin_base_record_type)
- return false;
+ if (origin_base_record.IsInvalid())
+ return false;
- DeclFromUser <RecordDecl> origin_base_record(origin_base_record_type->getDecl());
+ DeclFromUser<CXXRecordDecl> origin_base_cxx_record(
+ DynCast<CXXRecordDecl>(origin_base_record));
- if (origin_base_record.IsInvalid())
- return false;
+ if (origin_base_cxx_record.IsInvalid())
+ return false;
- DeclFromUser <CXXRecordDecl> origin_base_cxx_record(DynCast<CXXRecordDecl>(origin_base_record));
+ CharUnits base_offset;
- if (origin_base_cxx_record.IsInvalid())
- return false;
+ if (IsVirtual)
+ base_offset =
+ record_layout.getVBaseClassOffset(origin_base_cxx_record.decl);
+ else
+ base_offset =
+ record_layout.getBaseClassOffset(origin_base_cxx_record.decl);
- CharUnits base_offset;
+ base_offsets.insert(std::pair<const CXXRecordDecl *, CharUnits>(
+ origin_base_cxx_record.decl, 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);
+ return true;
+}
- base_offsets.insert(std::pair<const CXXRecordDecl *, CharUnits>(origin_base_cxx_record.decl, base_offset));
- }
+bool ClangASTSource::layoutRecordType(const RecordDecl *record, uint64_t &size,
+ uint64_t &alignment,
+ FieldOffsetMap &field_offsets,
+ BaseOffsetMap &base_offsets,
+ BaseOffsetMap &virtual_base_offsets) {
+ ClangASTMetrics::RegisterRecordLayout();
- return true;
-}
+ static unsigned int invocation_id = 0;
+ unsigned int current_id = invocation_id++;
-bool
-ClangASTSource::layoutRecordType(const RecordDecl *record, uint64_t &size, uint64_t &alignment,
- FieldOffsetMap &field_offsets, BaseOffsetMap &base_offsets,
- BaseOffsetMap &virtual_base_offsets)
-{
- ClangASTMetrics::RegisterRecordLayout();
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- static unsigned int invocation_id = 0;
- unsigned int current_id = invocation_id++;
+ if (log)
+ log->Printf("LayoutRecordType[%u] on (ASTContext*)%p for (RecordDecl*)%p "
+ "[name = '%s']",
+ current_id, static_cast<void *>(m_ast_context),
+ static_cast<const void *>(record),
+ record->getNameAsString().c_str());
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ DeclFromParser<const RecordDecl> parser_record(record);
+ DeclFromUser<const RecordDecl> origin_record(
+ parser_record.GetOrigin(m_ast_importer_sp.get()));
- if (log)
- log->Printf("LayoutRecordType[%u] on (ASTContext*)%p for (RecordDecl*)%p [name = '%s']",
- current_id, static_cast<void*>(m_ast_context),
- static_cast<const void*>(record),
- record->getNameAsString().c_str());
+ if (origin_record.IsInvalid())
+ return false;
+
+ FieldOffsetMap origin_field_offsets;
+ BaseOffsetMap origin_base_offsets;
+ BaseOffsetMap origin_virtual_base_offsets;
- DeclFromParser <const RecordDecl> parser_record(record);
- DeclFromUser <const RecordDecl> origin_record(parser_record.GetOrigin(m_ast_importer_sp.get()));
+ ClangASTContext::GetCompleteDecl(
+ &origin_record->getASTContext(),
+ const_cast<RecordDecl *>(origin_record.decl));
- if (origin_record.IsInvalid())
- return false;
+ clang::RecordDecl *definition = origin_record.decl->getDefinition();
+ if (!definition || !definition->isCompleteDefinition())
+ return false;
- FieldOffsetMap origin_field_offsets;
- BaseOffsetMap origin_base_offsets;
- BaseOffsetMap origin_virtual_base_offsets;
+ const ASTRecordLayout &record_layout(
+ origin_record->getASTContext().getASTRecordLayout(origin_record.decl));
- ClangASTContext::GetCompleteDecl(&origin_record->getASTContext(), const_cast<RecordDecl*>(origin_record.decl));
+ int field_idx = 0, field_count = record_layout.getFieldCount();
- clang::RecordDecl* definition = origin_record.decl->getDefinition();
- if (!definition || !definition->isCompleteDefinition())
- return false;
+ 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.
- const ASTRecordLayout &record_layout(origin_record->getASTContext().getASTRecordLayout(origin_record.decl));
+ uint64_t field_offset = record_layout.getFieldOffset(field_idx);
- int field_idx = 0, field_count = record_layout.getFieldCount();
+ origin_field_offsets.insert(
+ std::pair<const FieldDecl *, uint64_t>(*fi, field_offset));
- 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.
+ field_idx++;
+ }
- uint64_t field_offset = record_layout.getFieldOffset(field_idx);
+ ASTContext &parser_ast_context(record->getASTContext());
- origin_field_offsets.insert(std::pair<const FieldDecl *, uint64_t>(*fi, field_offset));
+ DeclFromUser<const CXXRecordDecl> origin_cxx_record(
+ DynCast<const CXXRecordDecl>(origin_record));
- field_idx++;
+ if (origin_cxx_record.IsValid()) {
+ if (!ExtractBaseOffsets<false>(record_layout, origin_cxx_record,
+ origin_base_offsets) ||
+ !ExtractBaseOffsets<true>(record_layout, origin_cxx_record,
+ origin_virtual_base_offsets))
+ return false;
+ }
+
+ if (!ImportOffsetMap(field_offsets, origin_field_offsets,
+ m_ast_importer_sp.get(), parser_ast_context) ||
+ !ImportOffsetMap(base_offsets, origin_base_offsets,
+ m_ast_importer_sp.get(), parser_ast_context) ||
+ !ImportOffsetMap(virtual_base_offsets, origin_virtual_base_offsets,
+ m_ast_importer_sp.get(), 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,
+ 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);
+ for (RecordDecl::field_iterator fi = record->field_begin(),
+ fe = record->field_end();
+ fi != fe; ++fi) {
+ log->Printf("LRT[%u] (FieldDecl*)%p, Name = '%s', Offset = %" PRId64
+ " bits",
+ 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()) {
+ log->Printf("LRT[%u] Bases:", current_id);
+ for (CXXRecordDecl::base_class_const_iterator
+ bi = parser_cxx_record->bases_begin(),
+ be = parser_cxx_record->bases_end();
+ bi != be; ++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 " : ""),
+ 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()));
+ }
+ } else {
+ log->Printf("LRD[%u] Not a CXXRecord, so no bases", current_id);
+ }
+ }
- ASTContext &parser_ast_context(record->getASTContext());
+ return true;
+}
- DeclFromUser <const CXXRecordDecl> origin_cxx_record(DynCast<const CXXRecordDecl>(origin_record));
+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, static_cast<void *>(m_ast_context),
+ name.GetCString(),
+ parent_map->begin()->second.GetName().AsCString());
+ else
+ log->Printf("CompleteNamespaceMap[%u] on (ASTContext*)%p Searching for "
+ "namespace %s",
+ current_id, static_cast<void *>(m_ast_context),
+ name.GetCString());
+ }
- if (origin_cxx_record.IsValid())
- {
- if (!ExtractBaseOffsets<false>(record_layout, origin_cxx_record, origin_base_offsets) ||
- !ExtractBaseOffsets<true>(record_layout, origin_cxx_record, origin_virtual_base_offsets))
- return false;
- }
+ if (parent_map) {
+ for (ClangASTImporter::NamespaceMap::iterator i = parent_map->begin(),
+ e = parent_map->end();
+ i != e; ++i) {
+ CompilerDeclContext found_namespace_decl;
- if (!ImportOffsetMap(field_offsets, origin_field_offsets, m_ast_importer_sp.get(), parser_ast_context) ||
- !ImportOffsetMap(base_offsets, origin_base_offsets, m_ast_importer_sp.get(), parser_ast_context) ||
- !ImportOffsetMap(virtual_base_offsets, origin_virtual_base_offsets, m_ast_importer_sp.get(), parser_ast_context))
- return false;
+ lldb::ModuleSP module_sp = i->first;
+ CompilerDeclContext module_parent_namespace_decl = i->second;
- size = record_layout.getSize().getQuantity() * m_ast_context->getCharWidth();
- alignment = record_layout.getAlignment().getQuantity() * m_ast_context->getCharWidth();
+ SymbolVendor *symbol_vendor = module_sp->GetSymbolVendor();
- if (log)
- {
- log->Printf("LRT[%u] returned:", current_id);
- 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);
- for (RecordDecl::field_iterator fi = record->field_begin(), fe = record->field_end();
- fi != fe;
- ++fi)
- {
- log->Printf("LRT[%u] (FieldDecl*)%p, Name = '%s', Offset = %" PRId64 " bits", 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())
- {
- log->Printf("LRT[%u] Bases:", current_id);
- for (CXXRecordDecl::base_class_const_iterator bi = parser_cxx_record->bases_begin(), be = parser_cxx_record->bases_end();
- bi != be;
- ++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 " : ""), 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()));
- }
- }
- else
- {
- log->Printf("LRD[%u] Not a CXXRecord, so no bases", current_id);
- }
- }
+ if (!symbol_vendor)
+ continue;
- return true;
-}
+ SymbolContext null_sc;
-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++;
+ found_namespace_decl = symbol_vendor->FindNamespace(
+ null_sc, name, &module_parent_namespace_decl);
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ if (!found_namespace_decl)
+ continue;
- if (log)
- {
- if (parent_map && parent_map->size())
- log->Printf("CompleteNamespaceMap[%u] on (ASTContext*)%p Searching for namespace %s in namespace %s",
- current_id, static_cast<void*>(m_ast_context),
- name.GetCString(),
- parent_map->begin()->second.GetName().AsCString());
- else
- log->Printf("CompleteNamespaceMap[%u] on (ASTContext*)%p Searching for namespace %s",
- current_id, static_cast<void*>(m_ast_context),
- name.GetCString());
+ namespace_map->push_back(std::pair<lldb::ModuleSP, CompilerDeclContext>(
+ module_sp, found_namespace_decl));
+
+ if (log)
+ log->Printf(" CMN[%u] Found namespace %s in module %s", current_id,
+ name.GetCString(),
+ module_sp->GetFileSpec().GetFilename().GetCString());
}
+ } else {
+ const ModuleList &target_images = m_target->GetImages();
+ std::lock_guard<std::recursive_mutex> guard(target_images.GetMutex());
- if (parent_map)
- {
- for (ClangASTImporter::NamespaceMap::iterator i = parent_map->begin(), e = parent_map->end();
- i != e;
- ++i)
- {
- CompilerDeclContext found_namespace_decl;
+ CompilerDeclContext null_namespace_decl;
- lldb::ModuleSP module_sp = i->first;
- CompilerDeclContext module_parent_namespace_decl = i->second;
+ for (size_t i = 0, e = target_images.GetSize(); i < e; ++i) {
+ lldb::ModuleSP image = target_images.GetModuleAtIndexUnlocked(i);
- SymbolVendor *symbol_vendor = module_sp->GetSymbolVendor();
+ if (!image)
+ continue;
- if (!symbol_vendor)
- continue;
+ CompilerDeclContext found_namespace_decl;
- SymbolContext null_sc;
+ SymbolVendor *symbol_vendor = image->GetSymbolVendor();
- found_namespace_decl = symbol_vendor->FindNamespace(null_sc, name, &module_parent_namespace_decl);
+ if (!symbol_vendor)
+ continue;
- if (!found_namespace_decl)
- continue;
+ SymbolContext null_sc;
- namespace_map->push_back(std::pair<lldb::ModuleSP, CompilerDeclContext>(module_sp, found_namespace_decl));
+ found_namespace_decl =
+ symbol_vendor->FindNamespace(null_sc, name, &null_namespace_decl);
- if (log)
- log->Printf(" CMN[%u] Found namespace %s in module %s",
- current_id,
- name.GetCString(),
- module_sp->GetFileSpec().GetFilename().GetCString());
- }
+ if (!found_namespace_decl)
+ continue;
+
+ namespace_map->push_back(std::pair<lldb::ModuleSP, CompilerDeclContext>(
+ image, found_namespace_decl));
+
+ if (log)
+ log->Printf(" CMN[%u] Found namespace %s in module %s", current_id,
+ name.GetCString(),
+ image->GetFileSpec().GetFilename().GetCString());
}
- else
- {
- const ModuleList &target_images = m_target->GetImages();
- std::lock_guard<std::recursive_mutex> guard(target_images.GetMutex());
+ }
+}
- CompilerDeclContext null_namespace_decl;
+NamespaceDecl *ClangASTSource::AddNamespace(
+ NameSearchContext &context,
+ ClangASTImporter::NamespaceMapSP &namespace_decls) {
+ if (!namespace_decls)
+ return nullptr;
- for (size_t i = 0, e = target_images.GetSize(); i < e; ++i)
- {
- lldb::ModuleSP image = target_images.GetModuleAtIndexUnlocked(i);
+ const CompilerDeclContext &namespace_decl = namespace_decls->begin()->second;
- if (!image)
- continue;
+ clang::ASTContext *src_ast =
+ ClangASTContext::DeclContextGetClangASTContext(namespace_decl);
+ if (!src_ast)
+ return nullptr;
+ clang::NamespaceDecl *src_namespace_decl =
+ ClangASTContext::DeclContextGetAsNamespaceDecl(namespace_decl);
- CompilerDeclContext found_namespace_decl;
+ if (!src_namespace_decl)
+ return nullptr;
- SymbolVendor *symbol_vendor = image->GetSymbolVendor();
+ Decl *copied_decl =
+ m_ast_importer_sp->CopyDecl(m_ast_context, src_ast, src_namespace_decl);
- if (!symbol_vendor)
- continue;
+ if (!copied_decl)
+ return nullptr;
- SymbolContext null_sc;
+ NamespaceDecl *copied_namespace_decl = dyn_cast<NamespaceDecl>(copied_decl);
- found_namespace_decl = symbol_vendor->FindNamespace(null_sc, name, &null_namespace_decl);
+ if (!copied_namespace_decl)
+ return nullptr;
- if (!found_namespace_decl)
- continue;
+ context.m_decls.push_back(copied_namespace_decl);
- namespace_map->push_back(std::pair<lldb::ModuleSP, CompilerDeclContext>(image, found_namespace_decl));
+ m_ast_importer_sp->RegisterNamespaceMap(copied_namespace_decl,
+ namespace_decls);
- if (log)
- log->Printf(" CMN[%u] Found namespace %s in module %s",
- current_id,
- name.GetCString(),
- image->GetFileSpec().GetFilename().GetCString());
- }
- }
+ return dyn_cast<NamespaceDecl>(copied_decl);
}
-NamespaceDecl *
-ClangASTSource::AddNamespace (NameSearchContext &context, ClangASTImporter::NamespaceMapSP &namespace_decls)
-{
- if (!namespace_decls)
- return nullptr;
+CompilerType ClangASTSource::GuardedCopyType(const CompilerType &src_type) {
+ ClangASTContext *src_ast =
+ llvm::dyn_cast_or_null<ClangASTContext>(src_type.GetTypeSystem());
+ if (src_ast == nullptr)
+ return CompilerType();
- const CompilerDeclContext &namespace_decl = namespace_decls->begin()->second;
+ ClangASTMetrics::RegisterLLDBImport();
- clang::ASTContext *src_ast = ClangASTContext::DeclContextGetClangASTContext(namespace_decl);
- if (!src_ast)
- return nullptr;
- clang::NamespaceDecl *src_namespace_decl = ClangASTContext::DeclContextGetAsNamespaceDecl(namespace_decl);
+ SetImportInProgress(true);
- if (!src_namespace_decl)
- return nullptr;
+ QualType copied_qual_type =
+ m_ast_importer_sp->CopyType(m_ast_context, src_ast->getASTContext(),
+ ClangUtil::GetQualType(src_type));
- Decl *copied_decl = m_ast_importer_sp->CopyDecl(m_ast_context, src_ast, src_namespace_decl);
+ SetImportInProgress(false);
- if (!copied_decl)
- return nullptr;
+ 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 CompilerType();
- NamespaceDecl *copied_namespace_decl = dyn_cast<NamespaceDecl>(copied_decl);
+ return CompilerType(m_ast_context, copied_qual_type);
+}
+
+clang::NamedDecl *NameSearchContext::AddVarDecl(const CompilerType &type) {
+ assert(type && "Type for variable must be valid!");
- if (!copied_namespace_decl)
- return nullptr;
+ if (!type.IsValid())
+ return NULL;
+
+ ClangASTContext *lldb_ast =
+ llvm::dyn_cast<ClangASTContext>(type.GetTypeSystem());
+ if (!lldb_ast)
+ return NULL;
- context.m_decls.push_back(copied_namespace_decl);
+ IdentifierInfo *ii = m_decl_name.getAsIdentifierInfo();
- m_ast_importer_sp->RegisterNamespaceMap(copied_namespace_decl, namespace_decls);
+ clang::ASTContext *ast = lldb_ast->getASTContext();
- return dyn_cast<NamespaceDecl>(copied_decl);
+ clang::NamedDecl *Decl = VarDecl::Create(
+ *ast, const_cast<DeclContext *>(m_decl_context), SourceLocation(),
+ SourceLocation(), ii, ClangUtil::GetQualType(type), 0, SC_Static);
+ m_decls.push_back(Decl);
+
+ return Decl;
}
-CompilerType
-ClangASTSource::GuardedCopyType (const CompilerType &src_type)
-{
- ClangASTContext *src_ast = llvm::dyn_cast_or_null<ClangASTContext>(src_type.GetTypeSystem());
- if (src_ast == nullptr)
- return CompilerType();
+clang::NamedDecl *NameSearchContext::AddFunDecl(const CompilerType &type,
+ bool extern_c) {
+ assert(type && "Type for variable must be valid!");
- ClangASTMetrics::RegisterLLDBImport();
+ if (!type.IsValid())
+ return NULL;
- SetImportInProgress(true);
+ if (m_function_types.count(type))
+ return NULL;
- QualType copied_qual_type =
- m_ast_importer_sp->CopyType(m_ast_context, src_ast->getASTContext(), ClangUtil::GetQualType(src_type));
+ ClangASTContext *lldb_ast =
+ llvm::dyn_cast<ClangASTContext>(type.GetTypeSystem());
+ if (!lldb_ast)
+ return NULL;
- SetImportInProgress(false);
+ m_function_types.insert(type);
- 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 CompilerType();
+ QualType qual_type(ClangUtil::GetQualType(type));
- return CompilerType(m_ast_context, copied_qual_type);
-}
+ clang::ASTContext *ast = lldb_ast->getASTContext();
-clang::NamedDecl *
-NameSearchContext::AddVarDecl(const CompilerType &type)
-{
- assert (type && "Type for variable must be valid!");
+ const bool isInlineSpecified = false;
+ const bool hasWrittenPrototype = true;
+ const bool isConstexprSpecified = false;
- if (!type.IsValid())
- return NULL;
+ clang::DeclContext *context = const_cast<DeclContext *>(m_decl_context);
- ClangASTContext* lldb_ast = llvm::dyn_cast<ClangASTContext>(type.GetTypeSystem());
- if (!lldb_ast)
- return NULL;
-
- IdentifierInfo *ii = m_decl_name.getAsIdentifierInfo();
+ if (extern_c) {
+ context = LinkageSpecDecl::Create(
+ *ast, context, SourceLocation(), SourceLocation(),
+ clang::LinkageSpecDecl::LanguageIDs::lang_c, false);
+ }
- clang::ASTContext *ast = lldb_ast->getASTContext();
+ // Pass the identifier info for functions the decl_name is needed for
+ // operators
+ clang::DeclarationName decl_name =
+ m_decl_name.getNameKind() == DeclarationName::Identifier
+ ? m_decl_name.getAsIdentifierInfo()
+ : m_decl_name;
- clang::NamedDecl *Decl = VarDecl::Create(*ast, const_cast<DeclContext *>(m_decl_context), SourceLocation(),
- SourceLocation(), ii, ClangUtil::GetQualType(type), 0, SC_Static);
- m_decls.push_back(Decl);
+ clang::FunctionDecl *func_decl = FunctionDecl::Create(
+ *ast, context, SourceLocation(), SourceLocation(), decl_name, qual_type,
+ NULL, SC_Extern, isInlineSpecified, hasWrittenPrototype,
+ isConstexprSpecified);
- return Decl;
-}
+ // 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.
-clang::NamedDecl *
-NameSearchContext::AddFunDecl (const CompilerType &type, bool extern_c)
-{
- assert (type && "Type for variable must be valid!");
-
- if (!type.IsValid())
- return NULL;
-
- if (m_function_types.count(type))
- return NULL;
-
- ClangASTContext* lldb_ast = llvm::dyn_cast<ClangASTContext>(type.GetTypeSystem());
- if (!lldb_ast)
- return NULL;
-
- m_function_types.insert(type);
-
- QualType qual_type(ClangUtil::GetQualType(type));
-
- clang::ASTContext *ast = lldb_ast->getASTContext();
-
- const bool isInlineSpecified = false;
- const bool hasWrittenPrototype = true;
- const bool isConstexprSpecified = false;
-
- clang::DeclContext *context = const_cast<DeclContext*>(m_decl_context);
-
- if (extern_c) {
- context = LinkageSpecDecl::Create(*ast,
- context,
- SourceLocation(),
- SourceLocation(),
- clang::LinkageSpecDecl::LanguageIDs::lang_c,
- false);
- }
+ const FunctionProtoType *func_proto_type =
+ qual_type.getTypePtr()->getAs<FunctionProtoType>();
- // Pass the identifier info for functions the decl_name is needed for operators
- clang::DeclarationName decl_name = m_decl_name.getNameKind() == DeclarationName::Identifier ? m_decl_name.getAsIdentifierInfo() : m_decl_name;
-
- clang::FunctionDecl *func_decl = FunctionDecl::Create (*ast,
- context,
- SourceLocation(),
- SourceLocation(),
- decl_name,
- qual_type,
- NULL,
- SC_Extern,
- isInlineSpecified,
- hasWrittenPrototype,
- isConstexprSpecified);
-
- // 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*>(context),
- SourceLocation(),
- SourceLocation(),
- NULL,
- arg_qual_type,
- NULL,
- SC_Static,
- NULL));
- }
+ if (func_proto_type) {
+ unsigned NumArgs = func_proto_type->getNumParams();
+ unsigned ArgIndex;
- func_decl->setParams(ArrayRef<ParmVarDecl*>(parm_var_decls));
- }
- else
- {
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ SmallVector<ParmVarDecl *, 5> parm_var_decls;
- if (log)
- log->Printf("Function type wasn't a FunctionProtoType");
+ 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 *>(context), SourceLocation(),
+ SourceLocation(), NULL, arg_qual_type, NULL, SC_Static, NULL));
}
- m_decls.push_back(func_decl);
+ func_decl->setParams(ArrayRef<ParmVarDecl *>(parm_var_decls));
+ } else {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+
+ if (log)
+ log->Printf("Function type wasn't a FunctionProtoType");
+ }
+
+ m_decls.push_back(func_decl);
- return func_decl;
+ return func_decl;
}
-clang::NamedDecl *
-NameSearchContext::AddGenericFunDecl()
-{
- FunctionProtoType::ExtProtoInfo proto_info;
+clang::NamedDecl *NameSearchContext::AddGenericFunDecl() {
+ FunctionProtoType::ExtProtoInfo proto_info;
- proto_info.Variadic = true;
+ 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));
+ 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(CompilerType (m_ast_source.m_ast_context, generic_function_type), true);
+ return AddFunDecl(
+ CompilerType(m_ast_source.m_ast_context, generic_function_type), true);
}
clang::NamedDecl *
-NameSearchContext::AddTypeDecl(const CompilerType &clang_type)
-{
- if (ClangUtil::IsClangType(clang_type))
- {
- QualType qual_type = ClangUtil::GetQualType(clang_type);
+NameSearchContext::AddTypeDecl(const CompilerType &clang_type) {
+ if (ClangUtil::IsClangType(clang_type)) {
+ QualType qual_type = ClangUtil::GetQualType(clang_type);
- if (const TypedefType *typedef_type = llvm::dyn_cast<TypedefType>(qual_type))
- {
- TypedefNameDecl *typedef_name_decl = typedef_type->getDecl();
+ 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);
+ 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();
+ 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);
+ 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();
+ 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);
+ m_decls.push_back((NamedDecl *)interface_decl);
- return (NamedDecl*)interface_decl;
- }
+ return (NamedDecl *)interface_decl;
}
- return NULL;
+ }
+ return NULL;
}
-void
-NameSearchContext::AddLookupResult (clang::DeclContextLookupResult result)
-{
- for (clang::NamedDecl *decl : result)
- m_decls.push_back (decl);
+void NameSearchContext::AddLookupResult(clang::DeclContextLookupResult result) {
+ for (clang::NamedDecl *decl : result)
+ m_decls.push_back(decl);
}
-void
-NameSearchContext::AddNamedDecl (clang::NamedDecl *decl)
-{
- m_decls.push_back (decl);
+void NameSearchContext::AddNamedDecl(clang::NamedDecl *decl) {
+ m_decls.push_back(decl);
}
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.h b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.h
index 13791d7e627..72ee50f5220 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.h
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.h
@@ -12,16 +12,16 @@
#include <set>
-#include "clang/Basic/IdentifierTable.h"
-#include "lldb/Symbol/ClangExternalASTSourceCommon.h"
#include "lldb/Symbol/ClangASTImporter.h"
+#include "lldb/Symbol/ClangExternalASTSourceCommon.h"
#include "lldb/Symbol/CompilerType.h"
#include "lldb/Target/Target.h"
+#include "clang/Basic/IdentifierTable.h"
#include "llvm/ADT/SmallSet.h"
namespace lldb_private {
-
+
//----------------------------------------------------------------------
/// @class ClangASTSource ClangASTSource.h "lldb/Expression/ClangASTSource.h"
/// @brief Provider for named objects defined in the debug info for Clang
@@ -33,494 +33,479 @@ namespace lldb_private {
/// to Clang for these names, consulting the ClangExpressionDeclMap to do
/// the actual lookups.
//----------------------------------------------------------------------
-class ClangASTSource :
- public ClangExternalASTSourceCommon,
- public ClangASTImporter::MapCompleter
-{
+class ClangASTSource : public ClangExternalASTSourceCommon,
+ public ClangASTImporter::MapCompleter {
public:
- //------------------------------------------------------------------
- /// Constructor
- ///
- /// Initializes class variables.
- ///
- /// @param[in] declMap
- /// A reference to the LLDB object that handles entity lookup.
- //------------------------------------------------------------------
- ClangASTSource (const lldb::TargetSP &target) :
- m_import_in_progress (false),
- m_lookups_enabled (false),
- m_target (target),
- m_ast_context (NULL),
- m_active_lexical_decls (),
- m_active_lookups ()
- {
- m_ast_importer_sp = m_target->GetClangASTImporter();
- }
-
- //------------------------------------------------------------------
- /// Destructor
- //------------------------------------------------------------------
- ~ClangASTSource() override;
-
- //------------------------------------------------------------------
- /// Interface stubs.
- //------------------------------------------------------------------
- clang::Decl *GetExternalDecl (uint32_t) override { return NULL; }
- clang::Stmt *GetExternalDeclStmt (uint64_t) override { return NULL; }
- clang::Selector GetExternalSelector (uint32_t) override { return clang::Selector(); }
- uint32_t GetNumExternalSelectors () override { return 0; }
- clang::CXXBaseSpecifier *GetExternalCXXBaseSpecifiers (uint64_t Offset) override
- { return NULL; }
- void MaterializeVisibleDecls (const clang::DeclContext *DC)
- { return; }
-
- void InstallASTContext (clang::ASTContext *ast_context)
- {
- m_ast_context = ast_context;
- m_ast_importer_sp->InstallMapCompleter(ast_context, *this);
+ //------------------------------------------------------------------
+ /// Constructor
+ ///
+ /// Initializes class variables.
+ ///
+ /// @param[in] declMap
+ /// A reference to the LLDB object that handles entity lookup.
+ //------------------------------------------------------------------
+ ClangASTSource(const lldb::TargetSP &target)
+ : m_import_in_progress(false), m_lookups_enabled(false), m_target(target),
+ m_ast_context(NULL), m_active_lexical_decls(), m_active_lookups() {
+ m_ast_importer_sp = m_target->GetClangASTImporter();
+ }
+
+ //------------------------------------------------------------------
+ /// Destructor
+ //------------------------------------------------------------------
+ ~ClangASTSource() override;
+
+ //------------------------------------------------------------------
+ /// Interface stubs.
+ //------------------------------------------------------------------
+ clang::Decl *GetExternalDecl(uint32_t) override { return NULL; }
+ clang::Stmt *GetExternalDeclStmt(uint64_t) override { return NULL; }
+ clang::Selector GetExternalSelector(uint32_t) override {
+ return clang::Selector();
+ }
+ uint32_t GetNumExternalSelectors() override { return 0; }
+ clang::CXXBaseSpecifier *
+ GetExternalCXXBaseSpecifiers(uint64_t Offset) override {
+ return NULL;
+ }
+ void MaterializeVisibleDecls(const clang::DeclContext *DC) { return; }
+
+ void InstallASTContext(clang::ASTContext *ast_context) {
+ m_ast_context = ast_context;
+ m_ast_importer_sp->InstallMapCompleter(ast_context, *this);
+ }
+
+ //
+ // APIs for ExternalASTSource
+ //
+
+ //------------------------------------------------------------------
+ /// Look up all Decls that match a particular name. Only handles
+ /// Identifiers and DeclContexts that are either NamespaceDecls or
+ /// TranslationUnitDecls. Calls SetExternalVisibleDeclsForName with
+ /// the result.
+ ///
+ /// The work for this function is done by
+ /// void FindExternalVisibleDecls (NameSearchContext &);
+ ///
+ /// @param[in] DC
+ /// The DeclContext to register the found Decls in.
+ ///
+ /// @param[in] Name
+ /// The name to find entries for.
+ ///
+ /// @return
+ /// Whatever SetExternalVisibleDeclsForName returns.
+ //------------------------------------------------------------------
+ bool FindExternalVisibleDeclsByName(const clang::DeclContext *DC,
+ clang::DeclarationName Name) override;
+
+ //------------------------------------------------------------------
+ /// Enumerate all Decls in a given lexical context.
+ ///
+ /// @param[in] DC
+ /// The DeclContext being searched.
+ ///
+ /// @param[in] isKindWeWant
+ /// A callback function that returns true given the
+ /// DeclKinds of desired Decls, and false otherwise.
+ ///
+ /// @param[in] Decls
+ /// A vector that is filled in with matching Decls.
+ //------------------------------------------------------------------
+ void FindExternalLexicalDecls(
+ const clang::DeclContext *DC,
+ llvm::function_ref<bool(clang::Decl::Kind)> IsKindWeWant,
+ llvm::SmallVectorImpl<clang::Decl *> &Decls) override;
+
+ //------------------------------------------------------------------
+ /// Specify the layout of the contents of a RecordDecl.
+ ///
+ /// @param[in] Record
+ /// The record (in the parser's AST context) that needs to be
+ /// laid out.
+ ///
+ /// @param[out] Size
+ /// The total size of the record in bits.
+ ///
+ /// @param[out] Alignment
+ /// The alignment of the record in bits.
+ ///
+ /// @param[in] FieldOffsets
+ /// A map that must be populated with pairs of the record's
+ /// fields (in the parser's AST context) and their offsets
+ /// (measured in bits).
+ ///
+ /// @param[in] BaseOffsets
+ /// A map that must be populated with pairs of the record's
+ /// C++ concrete base classes (in the parser's AST context,
+ /// and only if the record is a CXXRecordDecl and has base
+ /// classes) and their offsets (measured in bytes).
+ ///
+ /// @param[in] VirtualBaseOffsets
+ /// A map that must be populated with pairs of the record's
+ /// C++ virtual base classes (in the parser's AST context,
+ /// and only if the record is a CXXRecordDecl and has base
+ /// classes) and their offsets (measured in bytes).
+ ///
+ /// @return
+ /// True <=> the layout is valid.
+ //-----------------------------------------------------------------
+ bool layoutRecordType(
+ const clang::RecordDecl *Record, uint64_t &Size, uint64_t &Alignment,
+ llvm::DenseMap<const clang::FieldDecl *, uint64_t> &FieldOffsets,
+ llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
+ &BaseOffsets,
+ llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
+ &VirtualBaseOffsets) override;
+
+ //------------------------------------------------------------------
+ /// Complete a TagDecl.
+ ///
+ /// @param[in] Tag
+ /// The Decl to be completed in place.
+ //------------------------------------------------------------------
+ void CompleteType(clang::TagDecl *Tag) override;
+
+ //------------------------------------------------------------------
+ /// Complete an ObjCInterfaceDecl.
+ ///
+ /// @param[in] Class
+ /// The Decl to be completed in place.
+ //------------------------------------------------------------------
+ void CompleteType(clang::ObjCInterfaceDecl *Class) override;
+
+ //------------------------------------------------------------------
+ /// Called on entering a translation unit. Tells Clang by calling
+ /// setHasExternalVisibleStorage() and setHasExternalLexicalStorage()
+ /// that this object has something to say about undefined names.
+ ///
+ /// @param[in] ASTConsumer
+ /// Unused.
+ //------------------------------------------------------------------
+ void StartTranslationUnit(clang::ASTConsumer *Consumer) override;
+
+ //
+ // APIs for NamespaceMapCompleter
+ //
+
+ //------------------------------------------------------------------
+ /// Look up the modules containing a given namespace and put the
+ /// appropriate entries in the namespace map.
+ ///
+ /// @param[in] namespace_map
+ /// The map to be completed.
+ ///
+ /// @param[in] name
+ /// The name of the namespace to be found.
+ ///
+ /// @param[in] parent_map
+ /// The map for the namespace's parent namespace, if there is
+ /// one.
+ //------------------------------------------------------------------
+ void CompleteNamespaceMap(
+ ClangASTImporter::NamespaceMapSP &namespace_map, const ConstString &name,
+ ClangASTImporter::NamespaceMapSP &parent_map) const override;
+
+ //
+ // Helper APIs
+ //
+
+ clang::NamespaceDecl *
+ AddNamespace(NameSearchContext &context,
+ ClangASTImporter::NamespaceMapSP &namespace_decls);
+
+ //------------------------------------------------------------------
+ /// The worker function for FindExternalVisibleDeclsByName.
+ ///
+ /// @param[in] context
+ /// The NameSearchContext to use when filing results.
+ //------------------------------------------------------------------
+ virtual void FindExternalVisibleDecls(NameSearchContext &context);
+
+ void SetImportInProgress(bool import_in_progress) {
+ m_import_in_progress = import_in_progress;
+ }
+ bool GetImportInProgress() { return m_import_in_progress; }
+
+ void SetLookupsEnabled(bool lookups_enabled) {
+ m_lookups_enabled = lookups_enabled;
+ }
+ bool GetLookupsEnabled() { return m_lookups_enabled; }
+
+ //----------------------------------------------------------------------
+ /// @class ClangASTSourceProxy ClangASTSource.h
+ /// "lldb/Expression/ClangASTSource.h"
+ /// @brief Proxy for ClangASTSource
+ ///
+ /// Clang AST contexts like to own their AST sources, so this is a
+ /// state-free proxy object.
+ //----------------------------------------------------------------------
+ class ClangASTSourceProxy : public ClangExternalASTSourceCommon {
+ public:
+ ClangASTSourceProxy(ClangASTSource &original) : m_original(original) {}
+
+ bool FindExternalVisibleDeclsByName(const clang::DeclContext *DC,
+ clang::DeclarationName Name) override {
+ return m_original.FindExternalVisibleDeclsByName(DC, Name);
}
-
- //
- // APIs for ExternalASTSource
- //
-
- //------------------------------------------------------------------
- /// Look up all Decls that match a particular name. Only handles
- /// Identifiers and DeclContexts that are either NamespaceDecls or
- /// TranslationUnitDecls. Calls SetExternalVisibleDeclsForName with
- /// the result.
- ///
- /// The work for this function is done by
- /// void FindExternalVisibleDecls (NameSearchContext &);
- ///
- /// @param[in] DC
- /// The DeclContext to register the found Decls in.
- ///
- /// @param[in] Name
- /// The name to find entries for.
- ///
- /// @return
- /// Whatever SetExternalVisibleDeclsForName returns.
- //------------------------------------------------------------------
- bool FindExternalVisibleDeclsByName(const clang::DeclContext *DC, clang::DeclarationName Name) override;
-
- //------------------------------------------------------------------
- /// Enumerate all Decls in a given lexical context.
- ///
- /// @param[in] DC
- /// The DeclContext being searched.
- ///
- /// @param[in] isKindWeWant
- /// A callback function that returns true given the
- /// DeclKinds of desired Decls, and false otherwise.
- ///
- /// @param[in] Decls
- /// A vector that is filled in with matching Decls.
- //------------------------------------------------------------------
+
void FindExternalLexicalDecls(
- const clang::DeclContext *DC, llvm::function_ref<bool(clang::Decl::Kind)> IsKindWeWant,
- llvm::SmallVectorImpl<clang::Decl *> &Decls) override;
-
- //------------------------------------------------------------------
- /// Specify the layout of the contents of a RecordDecl.
- ///
- /// @param[in] Record
- /// The record (in the parser's AST context) that needs to be
- /// laid out.
- ///
- /// @param[out] Size
- /// The total size of the record in bits.
- ///
- /// @param[out] Alignment
- /// The alignment of the record in bits.
- ///
- /// @param[in] FieldOffsets
- /// A map that must be populated with pairs of the record's
- /// fields (in the parser's AST context) and their offsets
- /// (measured in bits).
- ///
- /// @param[in] BaseOffsets
- /// A map that must be populated with pairs of the record's
- /// C++ concrete base classes (in the parser's AST context,
- /// and only if the record is a CXXRecordDecl and has base
- /// classes) and their offsets (measured in bytes).
- ///
- /// @param[in] VirtualBaseOffsets
- /// A map that must be populated with pairs of the record's
- /// C++ virtual base classes (in the parser's AST context,
- /// and only if the record is a CXXRecordDecl and has base
- /// classes) and their offsets (measured in bytes).
- ///
- /// @return
- /// True <=> the layout is valid.
- //-----------------------------------------------------------------
- bool layoutRecordType(const clang::RecordDecl *Record, uint64_t &Size, uint64_t &Alignment,
- llvm::DenseMap<const clang::FieldDecl *, uint64_t> &FieldOffsets,
- llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &BaseOffsets,
- llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &VirtualBaseOffsets) override;
-
- //------------------------------------------------------------------
- /// Complete a TagDecl.
- ///
- /// @param[in] Tag
- /// The Decl to be completed in place.
- //------------------------------------------------------------------
- void CompleteType(clang::TagDecl *Tag) override;
-
- //------------------------------------------------------------------
- /// Complete an ObjCInterfaceDecl.
- ///
- /// @param[in] Class
- /// The Decl to be completed in place.
- //------------------------------------------------------------------
- void CompleteType(clang::ObjCInterfaceDecl *Class) override;
-
- //------------------------------------------------------------------
- /// Called on entering a translation unit. Tells Clang by calling
- /// setHasExternalVisibleStorage() and setHasExternalLexicalStorage()
- /// that this object has something to say about undefined names.
- ///
- /// @param[in] ASTConsumer
- /// Unused.
- //------------------------------------------------------------------
- void StartTranslationUnit(clang::ASTConsumer *Consumer) override;
-
- //
- // APIs for NamespaceMapCompleter
- //
-
- //------------------------------------------------------------------
- /// Look up the modules containing a given namespace and put the
- /// appropriate entries in the namespace map.
- ///
- /// @param[in] namespace_map
- /// The map to be completed.
- ///
- /// @param[in] name
- /// The name of the namespace to be found.
- ///
- /// @param[in] parent_map
- /// The map for the namespace's parent namespace, if there is
- /// one.
- //------------------------------------------------------------------
- void CompleteNamespaceMap(ClangASTImporter::NamespaceMapSP &namespace_map, const ConstString &name,
- ClangASTImporter::NamespaceMapSP &parent_map) const override;
-
- //
- // Helper APIs
- //
-
- clang::NamespaceDecl *
- AddNamespace (NameSearchContext &context,
- ClangASTImporter::NamespaceMapSP &namespace_decls);
-
- //------------------------------------------------------------------
- /// The worker function for FindExternalVisibleDeclsByName.
- ///
- /// @param[in] context
- /// The NameSearchContext to use when filing results.
- //------------------------------------------------------------------
- virtual void FindExternalVisibleDecls (NameSearchContext &context);
-
- void SetImportInProgress (bool import_in_progress) { m_import_in_progress = import_in_progress; }
- bool GetImportInProgress () { return m_import_in_progress; }
-
- void SetLookupsEnabled (bool lookups_enabled) { m_lookups_enabled = lookups_enabled; }
- bool GetLookupsEnabled () { return m_lookups_enabled; }
-
- //----------------------------------------------------------------------
- /// @class ClangASTSourceProxy ClangASTSource.h "lldb/Expression/ClangASTSource.h"
- /// @brief Proxy for ClangASTSource
- ///
- /// Clang AST contexts like to own their AST sources, so this is a
- /// state-free proxy object.
- //----------------------------------------------------------------------
- class ClangASTSourceProxy : public ClangExternalASTSourceCommon
- {
- public:
- ClangASTSourceProxy (ClangASTSource &original) :
- m_original(original)
- {
- }
-
- bool
- FindExternalVisibleDeclsByName(const clang::DeclContext *DC, clang::DeclarationName Name) override
- {
- return m_original.FindExternalVisibleDeclsByName(DC, Name);
- }
-
- void
- FindExternalLexicalDecls(const clang::DeclContext *DC,
- llvm::function_ref<bool(clang::Decl::Kind)> IsKindWeWant,
- llvm::SmallVectorImpl<clang::Decl *> &Decls) override
- {
- return m_original.FindExternalLexicalDecls(DC, IsKindWeWant, Decls);
- }
-
- void
- CompleteType(clang::TagDecl *Tag) override
- {
- return m_original.CompleteType(Tag);
- }
-
- void
- CompleteType(clang::ObjCInterfaceDecl *Class) override
- {
- return m_original.CompleteType(Class);
- }
-
- bool
- layoutRecordType(const clang::RecordDecl *Record, uint64_t &Size, uint64_t &Alignment,
- llvm::DenseMap<const clang::FieldDecl *, uint64_t> &FieldOffsets,
- llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &BaseOffsets,
- llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &VirtualBaseOffsets) override
- {
- return m_original.layoutRecordType(Record,
- Size,
- Alignment,
- FieldOffsets,
- BaseOffsets,
- VirtualBaseOffsets);
- }
-
- void
- StartTranslationUnit(clang::ASTConsumer *Consumer) override
- {
- return m_original.StartTranslationUnit(Consumer);
- }
-
- ClangASTMetadata *
- GetMetadata(const void * object)
- {
- return m_original.GetMetadata(object);
- }
-
- void
- SetMetadata(const void * object, ClangASTMetadata &metadata)
- {
- return m_original.SetMetadata(object, metadata);
- }
-
- bool
- HasMetadata(const void * object)
- {
- return m_original.HasMetadata(object);
- }
- private:
- ClangASTSource &m_original;
- };
-
- clang::ExternalASTSource *CreateProxy()
- {
- return new ClangASTSourceProxy(*this);
+ const clang::DeclContext *DC,
+ llvm::function_ref<bool(clang::Decl::Kind)> IsKindWeWant,
+ llvm::SmallVectorImpl<clang::Decl *> &Decls) override {
+ return m_original.FindExternalLexicalDecls(DC, IsKindWeWant, Decls);
+ }
+
+ void CompleteType(clang::TagDecl *Tag) override {
+ return m_original.CompleteType(Tag);
+ }
+
+ void CompleteType(clang::ObjCInterfaceDecl *Class) override {
+ return m_original.CompleteType(Class);
}
-
+
+ bool layoutRecordType(
+ const clang::RecordDecl *Record, uint64_t &Size, uint64_t &Alignment,
+ llvm::DenseMap<const clang::FieldDecl *, uint64_t> &FieldOffsets,
+ llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
+ &BaseOffsets,
+ llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
+ &VirtualBaseOffsets) override {
+ return m_original.layoutRecordType(Record, Size, Alignment, FieldOffsets,
+ BaseOffsets, VirtualBaseOffsets);
+ }
+
+ void StartTranslationUnit(clang::ASTConsumer *Consumer) override {
+ return m_original.StartTranslationUnit(Consumer);
+ }
+
+ ClangASTMetadata *GetMetadata(const void *object) {
+ return m_original.GetMetadata(object);
+ }
+
+ void SetMetadata(const void *object, ClangASTMetadata &metadata) {
+ return m_original.SetMetadata(object, metadata);
+ }
+
+ bool HasMetadata(const void *object) {
+ return m_original.HasMetadata(object);
+ }
+
+ private:
+ ClangASTSource &m_original;
+ };
+
+ clang::ExternalASTSource *CreateProxy() {
+ return new ClangASTSourceProxy(*this);
+ }
+
protected:
- //------------------------------------------------------------------
- /// Look for the complete version of an Objective-C interface, and
- /// return it if found.
- ///
- /// @param[in] interface_decl
- /// An ObjCInterfaceDecl that may not be the complete one.
- ///
- /// @return
- /// NULL if the complete interface couldn't be found;
- /// the complete interface otherwise.
- //------------------------------------------------------------------
- clang::ObjCInterfaceDecl *
- GetCompleteObjCInterface (clang::ObjCInterfaceDecl *interface_decl);
-
- //------------------------------------------------------------------
- /// Find all entities matching a given name in a given module,
- /// using a NameSearchContext to make Decls for them.
- ///
- /// @param[in] context
- /// The NameSearchContext that can construct Decls for this name.
- ///
- /// @param[in] module
- /// If non-NULL, the module to query.
- ///
- /// @param[in] namespace_decl
- /// If valid and module is non-NULL, the parent namespace.
- ///
- /// @param[in] current_id
- /// The ID for the current FindExternalVisibleDecls invocation,
- /// for logging purposes.
- ///
- /// @return
- /// True on success; false otherwise.
- //------------------------------------------------------------------
- void
- FindExternalVisibleDecls (NameSearchContext &context,
- lldb::ModuleSP module,
- CompilerDeclContext &namespace_decl,
- unsigned int current_id);
-
- //------------------------------------------------------------------
- /// Find all Objective-C methods matching a given selector.
- ///
- /// @param[in] context
- /// The NameSearchContext that can construct Decls for this name.
- /// Its m_decl_name contains the selector and its m_decl_context
- /// is the containing object.
- //------------------------------------------------------------------
- void
- FindObjCMethodDecls (NameSearchContext &context);
-
- //------------------------------------------------------------------
- /// Find all Objective-C properties and ivars with a given name.
- ///
- /// @param[in] context
- /// The NameSearchContext that can construct Decls for this name.
- /// Its m_decl_name contains the name and its m_decl_context
- /// is the containing object.
- //------------------------------------------------------------------
- void
- FindObjCPropertyAndIvarDecls (NameSearchContext &context);
-
- //------------------------------------------------------------------
- /// A wrapper for ClangASTContext::CopyType that sets a flag that
- /// indicates that we should not respond to queries during import.
- ///
- /// @param[in] dest_context
- /// The target AST context, typically the parser's AST context.
- ///
- /// @param[in] source_context
- /// The source AST context, typically the AST context of whatever
- /// symbol file the type was found in.
- ///
- /// @param[in] src_type
- /// The source type.
- ///
- /// @return
- /// The imported type.
- //------------------------------------------------------------------
- CompilerType
- GuardedCopyType (const CompilerType &src_type);
-
- friend struct NameSearchContext;
-
- bool m_import_in_progress;
- bool m_lookups_enabled;
-
- const lldb::TargetSP m_target; ///< The target to use in finding variables and types.
- clang::ASTContext *m_ast_context; ///< The AST context requests are coming in for.
- lldb::ClangASTImporterSP m_ast_importer_sp; ///< The target's AST importer.
- std::set<const clang::Decl *> m_active_lexical_decls;
- std::set<const char *> m_active_lookups;
+ //------------------------------------------------------------------
+ /// Look for the complete version of an Objective-C interface, and
+ /// return it if found.
+ ///
+ /// @param[in] interface_decl
+ /// An ObjCInterfaceDecl that may not be the complete one.
+ ///
+ /// @return
+ /// NULL if the complete interface couldn't be found;
+ /// the complete interface otherwise.
+ //------------------------------------------------------------------
+ clang::ObjCInterfaceDecl *
+ GetCompleteObjCInterface(clang::ObjCInterfaceDecl *interface_decl);
+
+ //------------------------------------------------------------------
+ /// Find all entities matching a given name in a given module,
+ /// using a NameSearchContext to make Decls for them.
+ ///
+ /// @param[in] context
+ /// The NameSearchContext that can construct Decls for this name.
+ ///
+ /// @param[in] module
+ /// If non-NULL, the module to query.
+ ///
+ /// @param[in] namespace_decl
+ /// If valid and module is non-NULL, the parent namespace.
+ ///
+ /// @param[in] current_id
+ /// The ID for the current FindExternalVisibleDecls invocation,
+ /// for logging purposes.
+ ///
+ /// @return
+ /// True on success; false otherwise.
+ //------------------------------------------------------------------
+ void FindExternalVisibleDecls(NameSearchContext &context,
+ lldb::ModuleSP module,
+ CompilerDeclContext &namespace_decl,
+ unsigned int current_id);
+
+ //------------------------------------------------------------------
+ /// Find all Objective-C methods matching a given selector.
+ ///
+ /// @param[in] context
+ /// The NameSearchContext that can construct Decls for this name.
+ /// Its m_decl_name contains the selector and its m_decl_context
+ /// is the containing object.
+ //------------------------------------------------------------------
+ void FindObjCMethodDecls(NameSearchContext &context);
+
+ //------------------------------------------------------------------
+ /// Find all Objective-C properties and ivars with a given name.
+ ///
+ /// @param[in] context
+ /// The NameSearchContext that can construct Decls for this name.
+ /// Its m_decl_name contains the name and its m_decl_context
+ /// is the containing object.
+ //------------------------------------------------------------------
+ void FindObjCPropertyAndIvarDecls(NameSearchContext &context);
+
+ //------------------------------------------------------------------
+ /// A wrapper for ClangASTContext::CopyType that sets a flag that
+ /// indicates that we should not respond to queries during import.
+ ///
+ /// @param[in] dest_context
+ /// The target AST context, typically the parser's AST context.
+ ///
+ /// @param[in] source_context
+ /// The source AST context, typically the AST context of whatever
+ /// symbol file the type was found in.
+ ///
+ /// @param[in] src_type
+ /// The source type.
+ ///
+ /// @return
+ /// The imported type.
+ //------------------------------------------------------------------
+ CompilerType GuardedCopyType(const CompilerType &src_type);
+
+ friend struct NameSearchContext;
+
+ bool m_import_in_progress;
+ bool m_lookups_enabled;
+
+ const lldb::TargetSP
+ m_target; ///< The target to use in finding variables and types.
+ clang::ASTContext
+ *m_ast_context; ///< The AST context requests are coming in for.
+ lldb::ClangASTImporterSP m_ast_importer_sp; ///< The target's AST importer.
+ std::set<const clang::Decl *> m_active_lexical_decls;
+ std::set<const char *> m_active_lookups;
};
//----------------------------------------------------------------------
/// @class NameSearchContext ClangASTSource.h "lldb/Expression/ClangASTSource.h"
/// @brief Container for all objects relevant to a single name lookup
-///
+///
/// LLDB needs to create Decls for entities it finds. This class communicates
/// what name is being searched for and provides helper functions to construct
/// Decls given appropriate type information.
//----------------------------------------------------------------------
struct NameSearchContext {
- ClangASTSource &m_ast_source; ///< The AST source making the request
- llvm::SmallVectorImpl<clang::NamedDecl*> &m_decls; ///< The list of declarations already constructed
- ClangASTImporter::NamespaceMapSP m_namespace_map; ///< The mapping of all namespaces found for this request back to their modules
- const clang::DeclarationName &m_decl_name; ///< The name being looked for
- const clang::DeclContext *m_decl_context; ///< The DeclContext to put declarations into
- llvm::SmallSet <CompilerType, 5> m_function_types; ///< All the types of functions that have been reported, so we don't report conflicts
-
- struct {
- bool variable : 1;
- bool function_with_type_info : 1;
- bool function : 1;
- bool local_vars_nsp : 1;
- bool type : 1;
- } m_found;
-
- //------------------------------------------------------------------
- /// Constructor
- ///
- /// Initializes class variables.
- ///
- /// @param[in] astSource
- /// A reference to the AST source making a request.
- ///
- /// @param[in] decls
- /// A reference to a list into which new Decls will be placed. This
- /// list is typically empty when the function is called.
- ///
- /// @param[in] name
- /// The name being searched for (always an Identifier).
- ///
- /// @param[in] dc
- /// The DeclContext to register Decls in.
- //------------------------------------------------------------------
- NameSearchContext (ClangASTSource &astSource,
- llvm::SmallVectorImpl<clang::NamedDecl*> &decls,
- clang::DeclarationName &name,
- const clang::DeclContext *dc) :
- m_ast_source(astSource),
- m_decls(decls),
- m_decl_name(name),
- m_decl_context(dc)
- {
- memset(&m_found, 0, sizeof(m_found));
- }
-
- //------------------------------------------------------------------
- /// Create a VarDecl with the name being searched for and the provided
- /// type and register it in the right places.
- ///
- /// @param[in] type
- /// The opaque QualType for the VarDecl being registered.
- //------------------------------------------------------------------
- clang::NamedDecl *AddVarDecl(const CompilerType &type);
-
- //------------------------------------------------------------------
- /// Create a FunDecl with the name being searched for and the provided
- /// type and register it in the right places.
- ///
- /// @param[in] type
- /// The opaque QualType for the FunDecl being registered.
- ///
- /// @param[in] extern_c
- /// If true, build an extern "C" linkage specification for this.
- //------------------------------------------------------------------
- clang::NamedDecl *AddFunDecl(const CompilerType &type,
- bool extern_c = false);
-
- //------------------------------------------------------------------
- /// Create a FunDecl with the name being searched for and generic
- /// type (i.e. intptr_t NAME_GOES_HERE(...)) and register it in the
- /// right places.
- //------------------------------------------------------------------
- clang::NamedDecl *AddGenericFunDecl();
-
- //------------------------------------------------------------------
- /// Create a TypeDecl with the name being searched for and the provided
- /// type and register it in the right places.
- ///
- /// @param[in] compiler_type
- /// The opaque QualType for the TypeDecl being registered.
- //------------------------------------------------------------------
- clang::NamedDecl *AddTypeDecl(const CompilerType &compiler_type);
-
-
- //------------------------------------------------------------------
- /// Add Decls from the provided DeclContextLookupResult to the list
- /// of results.
- ///
- /// @param[in] result
- /// The DeclContextLookupResult, usually returned as the result
- /// of querying a DeclContext.
- //------------------------------------------------------------------
- void AddLookupResult (clang::DeclContextLookupResult result);
-
- //------------------------------------------------------------------
- /// Add a NamedDecl to the list of results.
- ///
- /// @param[in] decl
- /// The NamedDecl, usually returned as the result
- /// of querying a DeclContext.
- //------------------------------------------------------------------
- void AddNamedDecl (clang::NamedDecl *decl);
+ ClangASTSource &m_ast_source; ///< The AST source making the request
+ llvm::SmallVectorImpl<clang::NamedDecl *>
+ &m_decls; ///< The list of declarations already constructed
+ ClangASTImporter::NamespaceMapSP m_namespace_map; ///< The mapping of all
+ ///namespaces found for this
+ ///request back to their
+ ///modules
+ const clang::DeclarationName &m_decl_name; ///< The name being looked for
+ const clang::DeclContext
+ *m_decl_context; ///< The DeclContext to put declarations into
+ llvm::SmallSet<CompilerType, 5> m_function_types; ///< All the types of
+ ///functions that have been
+ ///reported, so we don't
+ ///report conflicts
+
+ struct {
+ bool variable : 1;
+ bool function_with_type_info : 1;
+ bool function : 1;
+ bool local_vars_nsp : 1;
+ bool type : 1;
+ } m_found;
+
+ //------------------------------------------------------------------
+ /// Constructor
+ ///
+ /// Initializes class variables.
+ ///
+ /// @param[in] astSource
+ /// A reference to the AST source making a request.
+ ///
+ /// @param[in] decls
+ /// A reference to a list into which new Decls will be placed. This
+ /// list is typically empty when the function is called.
+ ///
+ /// @param[in] name
+ /// The name being searched for (always an Identifier).
+ ///
+ /// @param[in] dc
+ /// The DeclContext to register Decls in.
+ //------------------------------------------------------------------
+ NameSearchContext(ClangASTSource &astSource,
+ llvm::SmallVectorImpl<clang::NamedDecl *> &decls,
+ clang::DeclarationName &name, const clang::DeclContext *dc)
+ : m_ast_source(astSource), m_decls(decls), m_decl_name(name),
+ m_decl_context(dc) {
+ memset(&m_found, 0, sizeof(m_found));
+ }
+
+ //------------------------------------------------------------------
+ /// Create a VarDecl with the name being searched for and the provided
+ /// type and register it in the right places.
+ ///
+ /// @param[in] type
+ /// The opaque QualType for the VarDecl being registered.
+ //------------------------------------------------------------------
+ clang::NamedDecl *AddVarDecl(const CompilerType &type);
+
+ //------------------------------------------------------------------
+ /// Create a FunDecl with the name being searched for and the provided
+ /// type and register it in the right places.
+ ///
+ /// @param[in] type
+ /// The opaque QualType for the FunDecl being registered.
+ ///
+ /// @param[in] extern_c
+ /// If true, build an extern "C" linkage specification for this.
+ //------------------------------------------------------------------
+ clang::NamedDecl *AddFunDecl(const CompilerType &type, bool extern_c = false);
+
+ //------------------------------------------------------------------
+ /// Create a FunDecl with the name being searched for and generic
+ /// type (i.e. intptr_t NAME_GOES_HERE(...)) and register it in the
+ /// right places.
+ //------------------------------------------------------------------
+ clang::NamedDecl *AddGenericFunDecl();
+
+ //------------------------------------------------------------------
+ /// Create a TypeDecl with the name being searched for and the provided
+ /// type and register it in the right places.
+ ///
+ /// @param[in] compiler_type
+ /// The opaque QualType for the TypeDecl being registered.
+ //------------------------------------------------------------------
+ clang::NamedDecl *AddTypeDecl(const CompilerType &compiler_type);
+
+ //------------------------------------------------------------------
+ /// Add Decls from the provided DeclContextLookupResult to the list
+ /// of results.
+ ///
+ /// @param[in] result
+ /// The DeclContextLookupResult, usually returned as the result
+ /// of querying a DeclContext.
+ //------------------------------------------------------------------
+ void AddLookupResult(clang::DeclContextLookupResult result);
+
+ //------------------------------------------------------------------
+ /// Add a NamedDecl to the list of results.
+ ///
+ /// @param[in] decl
+ /// The NamedDecl, usually returned as the result
+ /// of querying a DeclContext.
+ //------------------------------------------------------------------
+ void AddNamedDecl(clang::NamedDecl *decl);
};
} // namespace lldb_private
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangDiagnostic.h b/lldb/source/Plugins/ExpressionParser/Clang/ClangDiagnostic.h
index 8273bca105c..9ea4e3aa7da 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangDiagnostic.h
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangDiagnostic.h
@@ -19,42 +19,32 @@
#include "lldb/Expression/DiagnosticManager.h"
-namespace lldb_private
-{
+namespace lldb_private {
-
-class ClangDiagnostic : public Diagnostic
-{
+class ClangDiagnostic : public Diagnostic {
public:
- typedef std::vector<clang::FixItHint> FixItList;
-
- static inline bool classof(const ClangDiagnostic *) { return true; }
- static inline bool classof(const Diagnostic *diag) {
- return diag->getKind() == eDiagnosticOriginClang;
- }
-
- ClangDiagnostic(const char *message, DiagnosticSeverity severity, uint32_t compiler_id) :
- Diagnostic(message, severity, eDiagnosticOriginClang, compiler_id)
- {
- }
-
- virtual ~ClangDiagnostic() = default;
-
- bool HasFixIts () const override { return !m_fixit_vec.empty(); }
-
- void
- AddFixitHint (const clang::FixItHint &fixit)
- {
- m_fixit_vec.push_back(fixit);
- }
-
- const FixItList &
- FixIts() const
- {
- return m_fixit_vec;
- }
- FixItList m_fixit_vec;
+ typedef std::vector<clang::FixItHint> FixItList;
+
+ static inline bool classof(const ClangDiagnostic *) { return true; }
+ static inline bool classof(const Diagnostic *diag) {
+ return diag->getKind() == eDiagnosticOriginClang;
+ }
+
+ ClangDiagnostic(const char *message, DiagnosticSeverity severity,
+ uint32_t compiler_id)
+ : Diagnostic(message, severity, eDiagnosticOriginClang, compiler_id) {}
+
+ virtual ~ClangDiagnostic() = default;
+
+ bool HasFixIts() const override { return !m_fixit_vec.empty(); }
+
+ void AddFixitHint(const clang::FixItHint &fixit) {
+ m_fixit_vec.push_back(fixit);
+ }
+
+ const FixItList &FixIts() const { return m_fixit_vec; }
+ FixItList m_fixit_vec;
};
-} // namespace lldb_private
+} // namespace lldb_private
#endif /* lldb_ClangDiagnostic_h */
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
index a0ea8ae730f..3fa78f01f51 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
@@ -14,11 +14,6 @@
#include "ClangModulesDeclVendor.h"
#include "ClangPersistentVariables.h"
-#include "clang/AST/ASTConsumer.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/DeclarationName.h"
-#include "clang/AST/Decl.h"
-#include "lldb/lldb-private.h"
#include "lldb/Core/Address.h"
#include "lldb/Core/Error.h"
#include "lldb/Core/Log.h"
@@ -30,9 +25,9 @@
#include "lldb/Expression/Materializer.h"
#include "lldb/Host/Endian.h"
#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/CompilerDecl.h"
#include "lldb/Symbol/CompilerDeclContext.h"
-#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SymbolContext.h"
@@ -50,6 +45,11 @@
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
+#include "lldb/lldb-private.h"
+#include "clang/AST/ASTConsumer.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclarationName.h"
#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
@@ -57,1586 +57,1501 @@ using namespace lldb;
using namespace lldb_private;
using namespace clang;
-namespace
-{
- const char *g_lldb_local_vars_namespace_cstr = "$__lldb_local_vars";
+namespace {
+const char *g_lldb_local_vars_namespace_cstr = "$__lldb_local_vars";
} // anonymous namespace
-ClangExpressionDeclMap::ClangExpressionDeclMap (bool keep_result_in_memory,
- Materializer::PersistentVariableDelegate *result_delegate,
- ExecutionContext &exe_ctx) :
- ClangASTSource (exe_ctx.GetTargetSP()),
- m_found_entities (),
- m_struct_members (),
- m_keep_result_in_memory (keep_result_in_memory),
- m_result_delegate (result_delegate),
- m_parser_vars (),
- m_struct_vars ()
-{
- EnableStructVars();
+ClangExpressionDeclMap::ClangExpressionDeclMap(
+ bool keep_result_in_memory,
+ Materializer::PersistentVariableDelegate *result_delegate,
+ ExecutionContext &exe_ctx)
+ : ClangASTSource(exe_ctx.GetTargetSP()), m_found_entities(),
+ m_struct_members(), m_keep_result_in_memory(keep_result_in_memory),
+ m_result_delegate(result_delegate), m_parser_vars(), m_struct_vars() {
+ EnableStructVars();
}
-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
+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
- DidParse();
- DisableStructVars();
+ DidParse();
+ DisableStructVars();
}
-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);
- else if (exe_ctx.GetThreadPtr() && exe_ctx.GetThreadPtr()->GetStackFrameAtIndex(0))
- m_parser_vars->m_sym_ctx = exe_ctx.GetThreadPtr()->GetStackFrameAtIndex(0)->GetSymbolContext(lldb::eSymbolContextEverything);
- else if (exe_ctx.GetProcessPtr())
- {
- m_parser_vars->m_sym_ctx.Clear(true);
- m_parser_vars->m_sym_ctx.target_sp = exe_ctx.GetTargetSP();
- }
- else if (target)
- {
- 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 = llvm::cast<ClangPersistentVariables>(target->GetPersistentExpressionStateForLanguage(eLanguageTypeC));
-
- if (!target->GetScratchClangASTContext())
- return false;
- }
-
- m_parser_vars->m_target_info = GetTargetInfo();
- m_parser_vars->m_materializer = materializer;
-
- return true;
+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);
+ else if (exe_ctx.GetThreadPtr() &&
+ exe_ctx.GetThreadPtr()->GetStackFrameAtIndex(0))
+ m_parser_vars->m_sym_ctx =
+ exe_ctx.GetThreadPtr()->GetStackFrameAtIndex(0)->GetSymbolContext(
+ lldb::eSymbolContextEverything);
+ else if (exe_ctx.GetProcessPtr()) {
+ m_parser_vars->m_sym_ctx.Clear(true);
+ m_parser_vars->m_sym_ctx.target_sp = exe_ctx.GetTargetSP();
+ } else if (target) {
+ 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 = llvm::cast<ClangPersistentVariables>(
+ target->GetPersistentExpressionStateForLanguage(eLanguageTypeC));
+
+ if (!target->GetScratchClangASTContext())
+ return false;
+ }
+
+ m_parser_vars->m_target_info = GetTargetInfo();
+ m_parser_vars->m_materializer = materializer;
+
+ return true;
}
-void
-ClangExpressionDeclMap::InstallCodeGenerator (clang::ASTConsumer *code_gen)
-{
- assert(m_parser_vars);
- m_parser_vars->m_code_gen = code_gen;
+void ClangExpressionDeclMap::InstallCodeGenerator(
+ clang::ASTConsumer *code_gen) {
+ assert(m_parser_vars);
+ m_parser_vars->m_code_gen = code_gen;
}
-void
-ClangExpressionDeclMap::DidParse()
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+void ClangExpressionDeclMap::DidParse() {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- if (log)
- ClangASTMetrics::DumpCounters(log);
-
- if (m_parser_vars.get())
- {
- for (size_t entity_index = 0, num_entities = m_found_entities.GetSize();
- entity_index < num_entities;
- ++entity_index)
- {
- ExpressionVariableSP var_sp(m_found_entities.GetVariableAtIndex(entity_index));
- if (var_sp)
- llvm::cast<ClangExpressionVariable>(var_sp.get())->DisableParserVars(GetParserID());
- }
+ if (log)
+ ClangASTMetrics::DumpCounters(log);
- for (size_t pvar_index = 0, num_pvars = m_parser_vars->m_persistent_vars->GetSize();
- pvar_index < num_pvars;
- ++pvar_index)
- {
- ExpressionVariableSP pvar_sp(m_parser_vars->m_persistent_vars->GetVariableAtIndex(pvar_index));
- if (ClangExpressionVariable *clang_var = llvm::dyn_cast<ClangExpressionVariable>(pvar_sp.get()))
- clang_var->DisableParserVars(GetParserID());
- }
+ if (m_parser_vars.get()) {
+ for (size_t entity_index = 0, num_entities = m_found_entities.GetSize();
+ entity_index < num_entities; ++entity_index) {
+ ExpressionVariableSP var_sp(
+ m_found_entities.GetVariableAtIndex(entity_index));
+ if (var_sp)
+ llvm::cast<ClangExpressionVariable>(var_sp.get())
+ ->DisableParserVars(GetParserID());
+ }
- DisableParserVars();
+ for (size_t pvar_index = 0,
+ num_pvars = m_parser_vars->m_persistent_vars->GetSize();
+ pvar_index < num_pvars; ++pvar_index) {
+ ExpressionVariableSP pvar_sp(
+ m_parser_vars->m_persistent_vars->GetVariableAtIndex(pvar_index));
+ if (ClangExpressionVariable *clang_var =
+ llvm::dyn_cast<ClangExpressionVariable>(pvar_sp.get()))
+ clang_var->DisableParserVars(GetParserID());
}
+
+ DisableParserVars();
+ }
}
// Interface for IRForTarget
-ClangExpressionDeclMap::TargetInfo
-ClangExpressionDeclMap::GetTargetInfo()
-{
- assert (m_parser_vars.get());
+ClangExpressionDeclMap::TargetInfo ClangExpressionDeclMap::GetTargetInfo() {
+ assert(m_parser_vars.get());
- TargetInfo ret;
+ TargetInfo ret;
- ExecutionContext &exe_ctx = m_parser_vars->m_exe_ctx;
+ ExecutionContext &exe_ctx = m_parser_vars->m_exe_ctx;
- Process *process = exe_ctx.GetProcessPtr();
- if (process)
- {
- ret.byte_order = process->GetByteOrder();
- ret.address_byte_size = process->GetAddressByteSize();
- }
- else
- {
- Target *target = exe_ctx.GetTargetPtr();
- if (target)
- {
- ret.byte_order = target->GetArchitecture().GetByteOrder();
- ret.address_byte_size = target->GetArchitecture().GetAddressByteSize();
- }
+ Process *process = exe_ctx.GetProcessPtr();
+ if (process) {
+ ret.byte_order = process->GetByteOrder();
+ ret.address_byte_size = process->GetAddressByteSize();
+ } else {
+ Target *target = exe_ctx.GetTargetPtr();
+ if (target) {
+ ret.byte_order = target->GetArchitecture().GetByteOrder();
+ ret.address_byte_size = target->GetArchitecture().GetAddressByteSize();
}
+ }
- return ret;
+ return ret;
}
-bool
-ClangExpressionDeclMap::AddPersistentVariable
-(
- const NamedDecl *decl,
- const ConstString &name,
- TypeFromParser parser_type,
- bool is_result,
- bool is_lvalue
-)
-{
- assert (m_parser_vars.get());
-
- ClangASTContext *ast = llvm::dyn_cast_or_null<ClangASTContext>(parser_type.GetTypeSystem());
- if (ast == nullptr)
- return false;
+bool ClangExpressionDeclMap::AddPersistentVariable(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;
+ ClangASTContext *ast =
+ llvm::dyn_cast_or_null<ClangASTContext>(parser_type.GetTypeSystem());
+ if (ast == nullptr)
+ return false;
- ExecutionContext &exe_ctx = m_parser_vars->m_exe_ctx;
- Target *target = exe_ctx.GetTargetPtr();
- if (target == nullptr)
- return false;
+ if (m_parser_vars->m_materializer && is_result) {
+ Error err;
- ClangASTContext *context(target->GetScratchClangASTContext());
+ ExecutionContext &exe_ctx = m_parser_vars->m_exe_ctx;
+ Target *target = exe_ctx.GetTargetPtr();
+ if (target == nullptr)
+ return false;
- TypeFromUser user_type(m_ast_importer_sp->DeportType(context->getASTContext(),
- ast->getASTContext(),
- parser_type.GetOpaqueQualType()),
- context);
-
- uint32_t offset = m_parser_vars->m_materializer->AddResultVariable(user_type,
- is_lvalue,
- m_keep_result_in_memory,
- m_result_delegate,
- err);
+ ClangASTContext *context(target->GetScratchClangASTContext());
- ClangExpressionVariable *var = new ClangExpressionVariable(exe_ctx.GetBestExecutionContextScope(),
- name,
- user_type,
- m_parser_vars->m_target_info.byte_order,
- m_parser_vars->m_target_info.address_byte_size);
+ TypeFromUser user_type(m_ast_importer_sp->DeportType(
+ context->getASTContext(), ast->getASTContext(),
+ parser_type.GetOpaqueQualType()),
+ context);
- m_found_entities.AddNewlyConstructedVariable(var);
-
- var->EnableParserVars(GetParserID());
+ uint32_t offset = m_parser_vars->m_materializer->AddResultVariable(
+ user_type, is_lvalue, m_keep_result_in_memory, m_result_delegate, err);
- ClangExpressionVariable::ParserVars *parser_vars = var->GetParserVars(GetParserID());
+ ClangExpressionVariable *var = new ClangExpressionVariable(
+ exe_ctx.GetBestExecutionContextScope(), name, user_type,
+ m_parser_vars->m_target_info.byte_order,
+ m_parser_vars->m_target_info.address_byte_size);
- parser_vars->m_named_decl = decl;
- parser_vars->m_parser_type = parser_type;
+ m_found_entities.AddNewlyConstructedVariable(var);
- var->EnableJITVars(GetParserID());
+ var->EnableParserVars(GetParserID());
- ClangExpressionVariable::JITVars *jit_vars = var->GetJITVars(GetParserID());
+ ClangExpressionVariable::ParserVars *parser_vars =
+ var->GetParserVars(GetParserID());
- jit_vars->m_offset = offset;
+ parser_vars->m_named_decl = decl;
+ parser_vars->m_parser_type = parser_type;
- return true;
- }
+ var->EnableJITVars(GetParserID());
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
- ExecutionContext &exe_ctx = m_parser_vars->m_exe_ctx;
- Target *target = exe_ctx.GetTargetPtr();
- if (target == NULL)
- return false;
+ ClangExpressionVariable::JITVars *jit_vars = var->GetJITVars(GetParserID());
- ClangASTContext *context(target->GetScratchClangASTContext());
+ jit_vars->m_offset = offset;
- TypeFromUser user_type(m_ast_importer_sp->DeportType(context->getASTContext(),
- ast->getASTContext(),
- parser_type.GetOpaqueQualType()),
- context);
+ return true;
+ }
- if (!user_type.GetOpaqueQualType())
- {
- if (log)
- log->Printf("Persistent variable's type wasn't copied successfully");
- return false;
- }
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+ ExecutionContext &exe_ctx = m_parser_vars->m_exe_ctx;
+ Target *target = exe_ctx.GetTargetPtr();
+ if (target == NULL)
+ return false;
- if (!m_parser_vars->m_target_info.IsValid())
- return false;
+ ClangASTContext *context(target->GetScratchClangASTContext());
- ClangExpressionVariable *var = llvm::cast<ClangExpressionVariable>(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).get());
+ TypeFromUser user_type(m_ast_importer_sp->DeportType(
+ context->getASTContext(), ast->getASTContext(),
+ parser_type.GetOpaqueQualType()),
+ context);
- if (!var)
- return false;
+ if (!user_type.GetOpaqueQualType()) {
+ if (log)
+ log->Printf("Persistent variable's type wasn't copied successfully");
+ return false;
+ }
- var->m_frozen_sp->SetHasCompleteType();
+ if (!m_parser_vars->m_target_info.IsValid())
+ return false;
- if (is_result)
- var->m_flags |= ClangExpressionVariable::EVNeedsFreezeDry;
- else
- var->m_flags |= ClangExpressionVariable::EVKeepInTarget; // explicitly-declared persistent variables should persist
+ ClangExpressionVariable *var = llvm::cast<ClangExpressionVariable>(
+ 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)
+ .get());
- if (is_lvalue)
- {
- var->m_flags |= ClangExpressionVariable::EVIsProgramReference;
- }
- else
- {
- var->m_flags |= ClangExpressionVariable::EVIsLLDBAllocated;
- var->m_flags |= ClangExpressionVariable::EVNeedsAllocation;
- }
+ if (!var)
+ return false;
- if (m_keep_result_in_memory)
- {
- var->m_flags |= ClangExpressionVariable::EVKeepInTarget;
- }
+ var->m_frozen_sp->SetHasCompleteType();
- if (log)
- log->Printf("Created persistent variable with flags 0x%hx", var->m_flags);
+ if (is_result)
+ var->m_flags |= ClangExpressionVariable::EVNeedsFreezeDry;
+ else
+ var->m_flags |=
+ ClangExpressionVariable::EVKeepInTarget; // explicitly-declared
+ // persistent variables should
+ // persist
- var->EnableParserVars(GetParserID());
+ if (is_lvalue) {
+ var->m_flags |= ClangExpressionVariable::EVIsProgramReference;
+ } else {
+ var->m_flags |= ClangExpressionVariable::EVIsLLDBAllocated;
+ var->m_flags |= ClangExpressionVariable::EVNeedsAllocation;
+ }
- ClangExpressionVariable::ParserVars *parser_vars = var->GetParserVars(GetParserID());
+ if (m_keep_result_in_memory) {
+ var->m_flags |= ClangExpressionVariable::EVKeepInTarget;
+ }
- parser_vars->m_named_decl = decl;
- parser_vars->m_parser_type = parser_type;
+ if (log)
+ log->Printf("Created persistent variable with flags 0x%hx", var->m_flags);
- return true;
-}
+ var->EnableParserVars(GetParserID());
-bool
-ClangExpressionDeclMap::AddValueToStruct
-(
- const NamedDecl *decl,
- const ConstString &name,
- llvm::Value *value,
- size_t size,
- lldb::offset_t alignment
-)
-{
- assert (m_struct_vars.get());
- assert (m_parser_vars.get());
+ ClangExpressionVariable::ParserVars *parser_vars =
+ var->GetParserVars(GetParserID());
- bool is_persistent_variable = false;
+ parser_vars->m_named_decl = decl;
+ parser_vars->m_parser_type = parser_type;
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ return true;
+}
- m_struct_vars->m_struct_laid_out = false;
+bool ClangExpressionDeclMap::AddValueToStruct(const NamedDecl *decl,
+ const ConstString &name,
+ llvm::Value *value, size_t size,
+ lldb::offset_t alignment) {
+ assert(m_struct_vars.get());
+ assert(m_parser_vars.get());
- if (ClangExpressionVariable::FindVariableInList(m_struct_members, decl, GetParserID()))
- return true;
+ bool is_persistent_variable = false;
- ClangExpressionVariable *var(ClangExpressionVariable::FindVariableInList(m_found_entities, decl, GetParserID()));
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- if (!var)
- {
- var = ClangExpressionVariable::FindVariableInList(*m_parser_vars->m_persistent_vars, decl, GetParserID());
- is_persistent_variable = true;
- }
+ m_struct_vars->m_struct_laid_out = false;
- if (!var)
- return false;
+ if (ClangExpressionVariable::FindVariableInList(m_struct_members, decl,
+ GetParserID()))
+ return true;
- if (log)
- log->Printf("Adding value for (NamedDecl*)%p [%s - %s] to the structure",
- static_cast<const void*>(decl), name.GetCString(),
- var->GetName().GetCString());
+ ClangExpressionVariable *var(ClangExpressionVariable::FindVariableInList(
+ m_found_entities, decl, GetParserID()));
- // We know entity->m_parser_vars is valid because we used a parser variable
- // to find it
+ if (!var) {
+ var = ClangExpressionVariable::FindVariableInList(
+ *m_parser_vars->m_persistent_vars, decl, GetParserID());
+ is_persistent_variable = true;
+ }
- ClangExpressionVariable::ParserVars *parser_vars = llvm::cast<ClangExpressionVariable>(var)->GetParserVars(GetParserID());
+ if (!var)
+ return false;
- parser_vars->m_llvm_value = value;
+ if (log)
+ log->Printf("Adding value for (NamedDecl*)%p [%s - %s] to the structure",
+ static_cast<const void *>(decl), name.GetCString(),
+ var->GetName().GetCString());
- if (ClangExpressionVariable::JITVars *jit_vars = llvm::cast<ClangExpressionVariable>(var)->GetJITVars(GetParserID()))
- {
- // We already laid this out; do not touch
+ // We know entity->m_parser_vars is valid because we used a parser variable
+ // to find it
- if (log)
- log->Printf("Already placed at 0x%llx", (unsigned long long)jit_vars->m_offset);
- }
+ ClangExpressionVariable::ParserVars *parser_vars =
+ llvm::cast<ClangExpressionVariable>(var)->GetParserVars(GetParserID());
- llvm::cast<ClangExpressionVariable>(var)->EnableJITVars(GetParserID());
+ parser_vars->m_llvm_value = value;
- ClangExpressionVariable::JITVars *jit_vars = llvm::cast<ClangExpressionVariable>(var)->GetJITVars(GetParserID());
+ if (ClangExpressionVariable::JITVars *jit_vars =
+ llvm::cast<ClangExpressionVariable>(var)->GetJITVars(GetParserID())) {
+ // We already laid this out; do not touch
- jit_vars->m_alignment = alignment;
- jit_vars->m_size = size;
+ if (log)
+ log->Printf("Already placed at 0x%llx",
+ (unsigned long long)jit_vars->m_offset);
+ }
- m_struct_members.AddVariable(var->shared_from_this());
+ llvm::cast<ClangExpressionVariable>(var)->EnableJITVars(GetParserID());
- if (m_parser_vars->m_materializer)
- {
- uint32_t offset = 0;
+ ClangExpressionVariable::JITVars *jit_vars =
+ llvm::cast<ClangExpressionVariable>(var)->GetJITVars(GetParserID());
- Error err;
+ jit_vars->m_alignment = alignment;
+ jit_vars->m_size = size;
- if (is_persistent_variable)
- {
- ExpressionVariableSP var_sp(var->shared_from_this());
- offset = m_parser_vars->m_materializer->AddPersistentVariable(var_sp, nullptr, err);
- }
- else
- {
- if (const lldb_private::Symbol *sym = parser_vars->m_lldb_sym)
- offset = m_parser_vars->m_materializer->AddSymbol(*sym, err);
- else if (const RegisterInfo *reg_info = var->GetRegisterInfo())
- offset = m_parser_vars->m_materializer->AddRegister(*reg_info, err);
- else if (parser_vars->m_lldb_var)
- offset = m_parser_vars->m_materializer->AddVariable(parser_vars->m_lldb_var, err);
- }
+ m_struct_members.AddVariable(var->shared_from_this());
- if (!err.Success())
- return false;
+ if (m_parser_vars->m_materializer) {
+ uint32_t offset = 0;
- if (log)
- log->Printf("Placed at 0x%llx", (unsigned long long)offset);
+ Error err;
- jit_vars->m_offset = offset; // TODO DoStructLayout() should not change this.
+ if (is_persistent_variable) {
+ ExpressionVariableSP var_sp(var->shared_from_this());
+ offset = m_parser_vars->m_materializer->AddPersistentVariable(
+ var_sp, nullptr, err);
+ } else {
+ if (const lldb_private::Symbol *sym = parser_vars->m_lldb_sym)
+ offset = m_parser_vars->m_materializer->AddSymbol(*sym, err);
+ else if (const RegisterInfo *reg_info = var->GetRegisterInfo())
+ offset = m_parser_vars->m_materializer->AddRegister(*reg_info, err);
+ else if (parser_vars->m_lldb_var)
+ offset = m_parser_vars->m_materializer->AddVariable(
+ parser_vars->m_lldb_var, err);
}
- return true;
-}
-
-bool
-ClangExpressionDeclMap::DoStructLayout ()
-{
- assert (m_struct_vars.get());
+ if (!err.Success())
+ return false;
- if (m_struct_vars->m_struct_laid_out)
- return true;
+ if (log)
+ log->Printf("Placed at 0x%llx", (unsigned long long)offset);
- if (!m_parser_vars->m_materializer)
- return false;
+ jit_vars->m_offset =
+ offset; // TODO DoStructLayout() should not change this.
+ }
- 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;
+ return true;
}
-bool ClangExpressionDeclMap::GetStructInfo
-(
- uint32_t &num_elements,
- size_t &size,
- lldb::offset_t &alignment
-)
-{
- assert (m_struct_vars.get());
+bool ClangExpressionDeclMap::DoStructLayout() {
+ assert(m_struct_vars.get());
- if (!m_struct_vars->m_struct_laid_out)
- return false;
+ if (m_struct_vars->m_struct_laid_out)
+ return true;
- num_elements = m_struct_members.GetSize();
- size = m_struct_vars->m_struct_size;
- alignment = m_struct_vars->m_struct_alignment;
+ if (!m_parser_vars->m_materializer)
+ return false;
- return true;
+ 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::GetStructElement
-(
- const NamedDecl *&decl,
- llvm::Value *&value,
- lldb::offset_t &offset,
- ConstString &name,
- uint32_t index
-)
-{
- assert (m_struct_vars.get());
-
- if (!m_struct_vars->m_struct_laid_out)
- return false;
+bool ClangExpressionDeclMap::GetStructInfo(uint32_t &num_elements, size_t &size,
+ lldb::offset_t &alignment) {
+ assert(m_struct_vars.get());
- if (index >= m_struct_members.GetSize())
- return false;
+ if (!m_struct_vars->m_struct_laid_out)
+ return false;
- ExpressionVariableSP member_sp(m_struct_members.GetVariableAtIndex(index));
+ num_elements = m_struct_members.GetSize();
+ size = m_struct_vars->m_struct_size;
+ alignment = m_struct_vars->m_struct_alignment;
- if (!member_sp)
- return false;
-
- ClangExpressionVariable::ParserVars *parser_vars = llvm::cast<ClangExpressionVariable>(member_sp.get())->GetParserVars(GetParserID());
- ClangExpressionVariable::JITVars *jit_vars = llvm::cast<ClangExpressionVariable>(member_sp.get())->GetJITVars(GetParserID());
+ return true;
+}
- if (!parser_vars ||
- !jit_vars ||
- !member_sp->GetValueObject())
- return false;
+bool ClangExpressionDeclMap::GetStructElement(const NamedDecl *&decl,
+ llvm::Value *&value,
+ lldb::offset_t &offset,
+ ConstString &name,
+ uint32_t index) {
+ assert(m_struct_vars.get());
- decl = parser_vars->m_named_decl;
- value = parser_vars->m_llvm_value;
- offset = jit_vars->m_offset;
- name = member_sp->GetName();
+ if (!m_struct_vars->m_struct_laid_out)
+ return false;
- return true;
-}
+ if (index >= m_struct_members.GetSize())
+ return false;
-bool
-ClangExpressionDeclMap::GetFunctionInfo
-(
- const NamedDecl *decl,
- uint64_t &ptr
-)
-{
- ClangExpressionVariable *entity(ClangExpressionVariable::FindVariableInList(m_found_entities, decl, GetParserID()));
+ ExpressionVariableSP member_sp(m_struct_members.GetVariableAtIndex(index));
- if (!entity)
- return false;
+ if (!member_sp)
+ return false;
- // We know m_parser_vars is valid since we searched for the variable by
- // its NamedDecl
+ ClangExpressionVariable::ParserVars *parser_vars =
+ llvm::cast<ClangExpressionVariable>(member_sp.get())
+ ->GetParserVars(GetParserID());
+ ClangExpressionVariable::JITVars *jit_vars =
+ llvm::cast<ClangExpressionVariable>(member_sp.get())
+ ->GetJITVars(GetParserID());
- ClangExpressionVariable::ParserVars *parser_vars = entity->GetParserVars(GetParserID());
+ if (!parser_vars || !jit_vars || !member_sp->GetValueObject())
+ return false;
- ptr = parser_vars->m_lldb_value.GetScalar().ULongLong();
+ decl = parser_vars->m_named_decl;
+ value = parser_vars->m_llvm_value;
+ offset = jit_vars->m_offset;
+ name = member_sp->GetName();
- return true;
+ return true;
}
-addr_t
-ClangExpressionDeclMap::GetSymbolAddress (Target &target,
- Process *process,
- const ConstString &name,
- lldb::SymbolType symbol_type,
- 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;
+bool ClangExpressionDeclMap::GetFunctionInfo(const NamedDecl *decl,
+ uint64_t &ptr) {
+ ClangExpressionVariable *entity(ClangExpressionVariable::FindVariableInList(
+ m_found_entities, decl, GetParserID()));
- for (uint32_t i=0; i<num_matches && (symbol_load_addr == 0 || symbol_load_addr == LLDB_INVALID_ADDRESS); i++)
- {
- SymbolContext sym_ctx;
- sc_list.GetContextAtIndex(i, sym_ctx);
+ if (!entity)
+ return false;
- const Address sym_address = sym_ctx.symbol->GetAddress();
+ // We know m_parser_vars is valid since we searched for the variable by
+ // its NamedDecl
- if (!sym_address.IsValid())
- continue;
+ ClangExpressionVariable::ParserVars *parser_vars =
+ entity->GetParserVars(GetParserID());
- switch (sym_ctx.symbol->GetType())
- {
- case eSymbolTypeCode:
- case eSymbolTypeTrampoline:
- symbol_load_addr = sym_address.GetCallableLoadAddress (&target);
- break;
-
- case eSymbolTypeResolver:
- symbol_load_addr = sym_address.GetCallableLoadAddress (&target, true);
- break;
+ ptr = parser_vars->m_lldb_value.GetScalar().ULongLong();
- case eSymbolTypeReExported:
- {
- ConstString reexport_name = sym_ctx.symbol->GetReExportedSymbolName();
- if (reexport_name)
- {
- ModuleSP reexport_module_sp;
- ModuleSpec reexport_module_spec;
- reexport_module_spec.GetPlatformFileSpec() = sym_ctx.symbol->GetReExportedSymbolSharedLibrary();
- if (reexport_module_spec.GetPlatformFileSpec())
- {
- reexport_module_sp = target.GetImages().FindFirstModule(reexport_module_spec);
- if (!reexport_module_sp)
- {
- reexport_module_spec.GetPlatformFileSpec().GetDirectory().Clear();
- reexport_module_sp = target.GetImages().FindFirstModule(reexport_module_spec);
- }
- }
- symbol_load_addr = GetSymbolAddress(target, process, sym_ctx.symbol->GetReExportedSymbolName(), symbol_type, reexport_module_sp.get());
- }
- }
- break;
+ return true;
+}
- case eSymbolTypeData:
- case eSymbolTypeRuntime:
- case eSymbolTypeVariable:
- case eSymbolTypeLocal:
- case eSymbolTypeParam:
- case eSymbolTypeInvalid:
- case eSymbolTypeAbsolute:
- case eSymbolTypeException:
- case eSymbolTypeSourceFile:
- case eSymbolTypeHeaderFile:
- case eSymbolTypeObjectFile:
- case eSymbolTypeCommonBlock:
- case eSymbolTypeBlock:
- case eSymbolTypeVariableType:
- case eSymbolTypeLineEntry:
- case eSymbolTypeLineHeader:
- case eSymbolTypeScopeBegin:
- case eSymbolTypeScopeEnd:
- case eSymbolTypeAdditional:
- case eSymbolTypeCompiler:
- case eSymbolTypeInstrumentation:
- case eSymbolTypeUndefined:
- case eSymbolTypeObjCClass:
- case eSymbolTypeObjCMetaClass:
- case eSymbolTypeObjCIVar:
- symbol_load_addr = sym_address.GetLoadAddress (&target);
- break;
+addr_t ClangExpressionDeclMap::GetSymbolAddress(Target &target,
+ Process *process,
+ const ConstString &name,
+ lldb::SymbolType symbol_type,
+ 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;
+
+ for (uint32_t i = 0;
+ i < num_matches &&
+ (symbol_load_addr == 0 || symbol_load_addr == LLDB_INVALID_ADDRESS);
+ i++) {
+ SymbolContext sym_ctx;
+ sc_list.GetContextAtIndex(i, sym_ctx);
+
+ const Address sym_address = sym_ctx.symbol->GetAddress();
+
+ if (!sym_address.IsValid())
+ continue;
+
+ switch (sym_ctx.symbol->GetType()) {
+ case eSymbolTypeCode:
+ case eSymbolTypeTrampoline:
+ symbol_load_addr = sym_address.GetCallableLoadAddress(&target);
+ break;
+
+ case eSymbolTypeResolver:
+ symbol_load_addr = sym_address.GetCallableLoadAddress(&target, true);
+ break;
+
+ case eSymbolTypeReExported: {
+ ConstString reexport_name = sym_ctx.symbol->GetReExportedSymbolName();
+ if (reexport_name) {
+ ModuleSP reexport_module_sp;
+ ModuleSpec reexport_module_spec;
+ reexport_module_spec.GetPlatformFileSpec() =
+ sym_ctx.symbol->GetReExportedSymbolSharedLibrary();
+ if (reexport_module_spec.GetPlatformFileSpec()) {
+ reexport_module_sp =
+ target.GetImages().FindFirstModule(reexport_module_spec);
+ if (!reexport_module_sp) {
+ reexport_module_spec.GetPlatformFileSpec().GetDirectory().Clear();
+ reexport_module_sp =
+ target.GetImages().FindFirstModule(reexport_module_spec);
+ }
}
+ symbol_load_addr = GetSymbolAddress(
+ target, process, sym_ctx.symbol->GetReExportedSymbolName(),
+ symbol_type, reexport_module_sp.get());
+ }
+ } break;
+
+ case eSymbolTypeData:
+ case eSymbolTypeRuntime:
+ case eSymbolTypeVariable:
+ case eSymbolTypeLocal:
+ case eSymbolTypeParam:
+ case eSymbolTypeInvalid:
+ case eSymbolTypeAbsolute:
+ case eSymbolTypeException:
+ case eSymbolTypeSourceFile:
+ case eSymbolTypeHeaderFile:
+ case eSymbolTypeObjectFile:
+ case eSymbolTypeCommonBlock:
+ case eSymbolTypeBlock:
+ case eSymbolTypeVariableType:
+ case eSymbolTypeLineEntry:
+ case eSymbolTypeLineHeader:
+ case eSymbolTypeScopeBegin:
+ case eSymbolTypeScopeEnd:
+ case eSymbolTypeAdditional:
+ case eSymbolTypeCompiler:
+ case eSymbolTypeInstrumentation:
+ case eSymbolTypeUndefined:
+ case eSymbolTypeObjCClass:
+ case eSymbolTypeObjCMetaClass:
+ case eSymbolTypeObjCIVar:
+ symbol_load_addr = sym_address.GetLoadAddress(&target);
+ break;
}
+ }
- if (symbol_load_addr == LLDB_INVALID_ADDRESS && process)
- {
- ObjCLanguageRuntime *runtime = process->GetObjCLanguageRuntime();
+ if (symbol_load_addr == LLDB_INVALID_ADDRESS && process) {
+ ObjCLanguageRuntime *runtime = process->GetObjCLanguageRuntime();
- if (runtime)
- {
- symbol_load_addr = runtime->LookupRuntimeSymbol(name);
- }
+ if (runtime) {
+ symbol_load_addr = runtime->LookupRuntimeSymbol(name);
}
+ }
- return symbol_load_addr;
+ return symbol_load_addr;
}
-addr_t
-ClangExpressionDeclMap::GetSymbolAddress (const ConstString &name, lldb::SymbolType symbol_type)
-{
- assert (m_parser_vars.get());
+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;
+ 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);
+ return GetSymbolAddress(m_parser_vars->m_exe_ctx.GetTargetRef(),
+ m_parser_vars->m_exe_ctx.GetProcessPtr(), name,
+ symbol_type);
}
-const Symbol *
-ClangExpressionDeclMap::FindGlobalDataSymbol (Target &target,
- const ConstString &name,
- lldb_private::Module *module)
-{
- SymbolContextList sc_list;
+const Symbol *ClangExpressionDeclMap::FindGlobalDataSymbol(
+ Target &target, const ConstString &name, 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)
- {
- SymbolContext sym_ctx;
- sc_list.GetContextAtIndex(i, sym_ctx);
- if (sym_ctx.symbol)
- {
- const Symbol *symbol = sym_ctx.symbol;
- const Address sym_address = symbol->GetAddress();
-
- if (sym_address.IsValid())
- {
- switch (symbol->GetType())
- {
- case eSymbolTypeData:
- case eSymbolTypeRuntime:
- case eSymbolTypeAbsolute:
- case eSymbolTypeObjCClass:
- case eSymbolTypeObjCMetaClass:
- case eSymbolTypeObjCIVar:
- if (symbol->GetDemangledNameIsSynthesized())
- {
- // If the demangled name was synthesized, then don't use it
- // for expressions. Only let the symbol match if the mangled
- // named matches for these symbols.
- if (symbol->GetMangled().GetMangledName() != name)
- break;
- }
- return symbol;
-
- case eSymbolTypeReExported:
- {
- ConstString reexport_name = symbol->GetReExportedSymbolName();
- if (reexport_name)
- {
- ModuleSP reexport_module_sp;
- ModuleSpec reexport_module_spec;
- reexport_module_spec.GetPlatformFileSpec() = symbol->GetReExportedSymbolSharedLibrary();
- if (reexport_module_spec.GetPlatformFileSpec())
- {
- reexport_module_sp = target.GetImages().FindFirstModule(reexport_module_spec);
- if (!reexport_module_sp)
- {
- reexport_module_spec.GetPlatformFileSpec().GetDirectory().Clear();
- reexport_module_sp = target.GetImages().FindFirstModule(reexport_module_spec);
- }
- }
- // Don't allow us to try and resolve a re-exported symbol if it is the same
- // as the current symbol
- if (name == symbol->GetReExportedSymbolName() && module == reexport_module_sp.get())
- return NULL;
-
- return FindGlobalDataSymbol(target, symbol->GetReExportedSymbolName(), reexport_module_sp.get());
- }
- }
- break;
-
- case eSymbolTypeCode: // We already lookup functions elsewhere
- case eSymbolTypeVariable:
- case eSymbolTypeLocal:
- case eSymbolTypeParam:
- case eSymbolTypeTrampoline:
- case eSymbolTypeInvalid:
- case eSymbolTypeException:
- case eSymbolTypeSourceFile:
- case eSymbolTypeHeaderFile:
- case eSymbolTypeObjectFile:
- case eSymbolTypeCommonBlock:
- case eSymbolTypeBlock:
- case eSymbolTypeVariableType:
- case eSymbolTypeLineEntry:
- case eSymbolTypeLineHeader:
- case eSymbolTypeScopeBegin:
- case eSymbolTypeScopeEnd:
- case eSymbolTypeAdditional:
- case eSymbolTypeCompiler:
- case eSymbolTypeInstrumentation:
- case eSymbolTypeUndefined:
- case eSymbolTypeResolver:
- break;
- }
+ 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) {
+ SymbolContext sym_ctx;
+ sc_list.GetContextAtIndex(i, sym_ctx);
+ if (sym_ctx.symbol) {
+ const Symbol *symbol = sym_ctx.symbol;
+ const Address sym_address = symbol->GetAddress();
+
+ if (sym_address.IsValid()) {
+ switch (symbol->GetType()) {
+ case eSymbolTypeData:
+ case eSymbolTypeRuntime:
+ case eSymbolTypeAbsolute:
+ case eSymbolTypeObjCClass:
+ case eSymbolTypeObjCMetaClass:
+ case eSymbolTypeObjCIVar:
+ if (symbol->GetDemangledNameIsSynthesized()) {
+ // If the demangled name was synthesized, then don't use it
+ // for expressions. Only let the symbol match if the mangled
+ // named matches for these symbols.
+ if (symbol->GetMangled().GetMangledName() != name)
+ break;
+ }
+ return symbol;
+
+ case eSymbolTypeReExported: {
+ ConstString reexport_name = symbol->GetReExportedSymbolName();
+ if (reexport_name) {
+ ModuleSP reexport_module_sp;
+ ModuleSpec reexport_module_spec;
+ reexport_module_spec.GetPlatformFileSpec() =
+ symbol->GetReExportedSymbolSharedLibrary();
+ if (reexport_module_spec.GetPlatformFileSpec()) {
+ reexport_module_sp =
+ target.GetImages().FindFirstModule(reexport_module_spec);
+ if (!reexport_module_sp) {
+ reexport_module_spec.GetPlatformFileSpec()
+ .GetDirectory()
+ .Clear();
+ reexport_module_sp =
+ target.GetImages().FindFirstModule(reexport_module_spec);
+ }
}
+ // Don't allow us to try and resolve a re-exported symbol if it is
+ // the same
+ // as the current symbol
+ if (name == symbol->GetReExportedSymbolName() &&
+ module == reexport_module_sp.get())
+ return NULL;
+
+ return FindGlobalDataSymbol(target,
+ symbol->GetReExportedSymbolName(),
+ reexport_module_sp.get());
+ }
+ } break;
+
+ case eSymbolTypeCode: // We already lookup functions elsewhere
+ case eSymbolTypeVariable:
+ case eSymbolTypeLocal:
+ case eSymbolTypeParam:
+ case eSymbolTypeTrampoline:
+ case eSymbolTypeInvalid:
+ case eSymbolTypeException:
+ case eSymbolTypeSourceFile:
+ case eSymbolTypeHeaderFile:
+ case eSymbolTypeObjectFile:
+ case eSymbolTypeCommonBlock:
+ case eSymbolTypeBlock:
+ case eSymbolTypeVariableType:
+ case eSymbolTypeLineEntry:
+ case eSymbolTypeLineHeader:
+ case eSymbolTypeScopeBegin:
+ case eSymbolTypeScopeEnd:
+ case eSymbolTypeAdditional:
+ case eSymbolTypeCompiler:
+ case eSymbolTypeInstrumentation:
+ case eSymbolTypeUndefined:
+ case eSymbolTypeResolver:
+ break;
}
+ }
}
+ }
- return NULL;
+ return NULL;
}
-lldb::VariableSP
-ClangExpressionDeclMap::FindGlobalVariable
-(
- Target &target,
- ModuleSP &module,
- const ConstString &name,
- CompilerDeclContext *namespace_decl,
- TypeFromUser *type
-)
-{
- 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)
- {
- for (size_t i = 0; i < vars.GetSize(); ++i)
- {
- VariableSP var_sp = vars.GetVariableAtIndex(i);
-
- if (ClangASTContext::AreTypesSame(*type, var_sp->GetType()->GetFullCompilerType ()))
- return var_sp;
- }
- }
- else
- {
- return vars.GetVariableAtIndex(0);
- }
+lldb::VariableSP ClangExpressionDeclMap::FindGlobalVariable(
+ Target &target, ModuleSP &module, const ConstString &name,
+ CompilerDeclContext *namespace_decl, TypeFromUser *type) {
+ 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) {
+ for (size_t i = 0; i < vars.GetSize(); ++i) {
+ VariableSP var_sp = vars.GetVariableAtIndex(i);
+
+ if (ClangASTContext::AreTypesSame(
+ *type, var_sp->GetType()->GetFullCompilerType()))
+ return var_sp;
+ }
+ } else {
+ return vars.GetVariableAtIndex(0);
}
+ }
- return VariableSP();
+ return VariableSP();
}
-ClangASTContext *
-ClangExpressionDeclMap::GetClangASTContext ()
-{
- StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr();
- if (frame == nullptr)
- return nullptr;
+ClangASTContext *ClangExpressionDeclMap::GetClangASTContext() {
+ StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr();
+ if (frame == nullptr)
+ return nullptr;
- SymbolContext sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction|lldb::eSymbolContextBlock);
- if (sym_ctx.block == nullptr)
- return nullptr;
+ SymbolContext sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction |
+ lldb::eSymbolContextBlock);
+ if (sym_ctx.block == nullptr)
+ return nullptr;
- CompilerDeclContext frame_decl_context = sym_ctx.block->GetDeclContext();
- if (!frame_decl_context)
- return nullptr;
+ CompilerDeclContext frame_decl_context = sym_ctx.block->GetDeclContext();
+ if (!frame_decl_context)
+ return nullptr;
- return llvm::dyn_cast_or_null<ClangASTContext>(frame_decl_context.GetTypeSystem());
+ return llvm::dyn_cast_or_null<ClangASTContext>(
+ frame_decl_context.GetTypeSystem());
}
// Interface for ClangASTSource
-void
-ClangExpressionDeclMap::FindExternalVisibleDecls (NameSearchContext &context)
-{
- assert (m_ast_context);
+void ClangExpressionDeclMap::FindExternalVisibleDecls(
+ NameSearchContext &context) {
+ assert(m_ast_context);
- ClangASTMetrics::RegisterVisibleQuery();
+ ClangASTMetrics::RegisterVisibleQuery();
- const ConstString name(context.m_decl_name.getAsString().c_str());
+ const ConstString name(context.m_decl_name.getAsString().c_str());
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- if (GetImportInProgress())
- {
- if (log && log->GetVerbose())
- log->Printf("Ignoring a query during an import");
- return;
+ 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)
+ log->Printf("ClangExpressionDeclMap::FindExternalVisibleDecls[%u] for "
+ "'%s' in a NULL DeclContext",
+ current_id, name.GetCString());
+ else if (const NamedDecl *context_named_decl =
+ dyn_cast<NamedDecl>(context.m_decl_context))
+ log->Printf("ClangExpressionDeclMap::FindExternalVisibleDecls[%u] for "
+ "'%s' in '%s'",
+ current_id, name.GetCString(),
+ context_named_decl->getNameAsString().c_str());
+ 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)) {
+ if (namespace_context->getName().str() ==
+ std::string(g_lldb_local_vars_namespace_cstr)) {
+ CompilerDeclContext compiler_decl_ctx(
+ GetClangASTContext(), const_cast<void *>(static_cast<const void *>(
+ context.m_decl_context)));
+ FindExternalVisibleDecls(context, lldb::ModuleSP(), compiler_decl_ctx,
+ current_id);
+ return;
}
- static unsigned int invocation_id = 0;
- unsigned int current_id = invocation_id++;
+ ClangASTImporter::NamespaceMapSP namespace_map =
+ m_ast_importer_sp->GetNamespaceMap(namespace_context);
- if (log)
- {
- if (!context.m_decl_context)
- log->Printf("ClangExpressionDeclMap::FindExternalVisibleDecls[%u] for '%s' in a NULL DeclContext", current_id, name.GetCString());
- else if (const NamedDecl *context_named_decl = dyn_cast<NamedDecl>(context.m_decl_context))
- log->Printf("ClangExpressionDeclMap::FindExternalVisibleDecls[%u] for '%s' in '%s'", current_id, name.GetCString(), context_named_decl->getNameAsString().c_str());
- else
- log->Printf("ClangExpressionDeclMap::FindExternalVisibleDecls[%u] for '%s' in a '%s'", current_id, name.GetCString(), context.m_decl_context->getDeclKindName());
+ if (log && log->GetVerbose())
+ 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) {
+ if (log)
+ log->Printf(" CEDM::FEVD[%u] Searching namespace %s in module %s",
+ current_id, i->second.GetName().AsCString(),
+ i->first->GetFileSpec().GetFilename().GetCString());
+
+ FindExternalVisibleDecls(context, i->first, i->second, current_id);
}
+ } else if (isa<TranslationUnitDecl>(context.m_decl_context)) {
+ CompilerDeclContext namespace_decl;
- if (const NamespaceDecl *namespace_context = dyn_cast<NamespaceDecl>(context.m_decl_context))
- {
- if (namespace_context->getName().str() == std::string(g_lldb_local_vars_namespace_cstr))
- {
- CompilerDeclContext compiler_decl_ctx(GetClangASTContext(), const_cast<void *>(static_cast<const void *>(context.m_decl_context)));
- FindExternalVisibleDecls(context, lldb::ModuleSP(), compiler_decl_ctx, current_id);
- return;
- }
+ if (log)
+ log->Printf(" CEDM::FEVD[%u] Searching the root namespace", current_id);
- ClangASTImporter::NamespaceMapSP namespace_map = m_ast_importer_sp->GetNamespaceMap(namespace_context);
+ FindExternalVisibleDecls(context, lldb::ModuleSP(), namespace_decl,
+ current_id);
+ }
- if (log && log->GetVerbose())
- log->Printf(" CEDM::FEVD[%u] Inspecting (NamespaceMap*)%p (%d entries)",
- current_id, static_cast<void*>(namespace_map.get()),
- (int)namespace_map->size());
+ if (!context.m_found.variable && !context.m_found.local_vars_nsp)
+ ClangASTSource::FindExternalVisibleDecls(context);
+}
- if (!namespace_map)
- return;
+void ClangExpressionDeclMap::FindExternalVisibleDecls(
+ NameSearchContext &context, lldb::ModuleSP module_sp,
+ CompilerDeclContext &namespace_decl, unsigned int current_id) {
+ assert(m_ast_context);
- for (ClangASTImporter::NamespaceMap::iterator i = namespace_map->begin(), e = namespace_map->end();
- i != e;
- ++i)
- {
- if (log)
- log->Printf(" CEDM::FEVD[%u] Searching namespace %s in module %s",
- current_id,
- i->second.GetName().AsCString(),
- i->first->GetFileSpec().GetFilename().GetCString());
-
- FindExternalVisibleDecls(context,
- i->first,
- i->second,
- current_id);
+ std::function<void(clang::FunctionDecl *)> MaybeRegisterFunctionBody =
+ [this](clang::FunctionDecl *copied_function_decl) {
+ if (copied_function_decl->getBody() && m_parser_vars->m_code_gen) {
+ DeclGroupRef decl_group_ref(copied_function_decl);
+ m_parser_vars->m_code_gen->HandleTopLevelDecl(decl_group_ref);
}
- }
- else if (isa<TranslationUnitDecl>(context.m_decl_context))
- {
- CompilerDeclContext namespace_decl;
+ };
- if (log)
- log->Printf(" CEDM::FEVD[%u] Searching the root namespace", current_id);
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- FindExternalVisibleDecls(context,
- lldb::ModuleSP(),
- namespace_decl,
- current_id);
- }
+ SymbolContextList sc_list;
- if (!context.m_found.variable && !context.m_found.local_vars_nsp)
- ClangASTSource::FindExternalVisibleDecls(context);
-}
+ const ConstString name(context.m_decl_name.getAsString().c_str());
-void
-ClangExpressionDeclMap::FindExternalVisibleDecls (NameSearchContext &context,
- lldb::ModuleSP module_sp,
- CompilerDeclContext &namespace_decl,
- unsigned int current_id)
-{
- assert (m_ast_context);
-
- std::function<void (clang::FunctionDecl *)> MaybeRegisterFunctionBody =
- [this](clang::FunctionDecl *copied_function_decl)
- {
- if (copied_function_decl->getBody() && m_parser_vars->m_code_gen)
- {
- DeclGroupRef decl_group_ref(copied_function_decl);
- m_parser_vars->m_code_gen->HandleTopLevelDecl(decl_group_ref);
- }
- };
+ const char *name_unique_cstr = name.GetCString();
+
+ if (name_unique_cstr == NULL)
+ return;
+ static ConstString id_name("id");
+ static ConstString Class_name("Class");
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ if (name == id_name || name == Class_name)
+ return;
- SymbolContextList sc_list;
+ // 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();
+ SymbolContext sym_ctx;
+ if (frame != nullptr)
+ sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction |
+ lldb::eSymbolContextBlock);
- const ConstString name(context.m_decl_name.getAsString().c_str());
+ // Try the persistent decls, which take precedence over all else.
+ if (!namespace_decl) {
+ do {
+ if (!target)
+ break;
- const char *name_unique_cstr = name.GetCString();
+ ClangASTContext *scratch_clang_ast_context =
+ target->GetScratchClangASTContext();
- if (name_unique_cstr == NULL)
- return;
+ if (!scratch_clang_ast_context)
+ break;
- static ConstString id_name("id");
- static ConstString Class_name("Class");
+ ASTContext *scratch_ast_context =
+ scratch_clang_ast_context->getASTContext();
- if (name == id_name || name == Class_name)
- return;
+ if (!scratch_ast_context)
+ break;
- // 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();
- SymbolContext sym_ctx;
- if (frame != nullptr)
- sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction|lldb::eSymbolContextBlock);
-
- // Try the persistent decls, which take precedence over all else.
- if (!namespace_decl)
- {
- 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;
-
- NamedDecl *persistent_decl = m_parser_vars->m_persistent_vars->GetPersistentDecl(name);
-
- if (!persistent_decl)
- break;
-
- Decl *parser_persistent_decl = m_ast_importer_sp->CopyDecl(m_ast_context, scratch_ast_context, persistent_decl);
-
- if (!parser_persistent_decl)
- break;
-
- NamedDecl *parser_named_decl = dyn_cast<NamedDecl>(parser_persistent_decl);
-
- if (!parser_named_decl)
- break;
-
- if (clang::FunctionDecl *parser_function_decl = llvm::dyn_cast<clang::FunctionDecl>(parser_named_decl))
- {
- MaybeRegisterFunctionBody(parser_function_decl);
- }
-
- if (log)
- log->Printf(" CEDM::FEVD[%u] Found persistent decl %s", current_id, name.GetCString());
-
- context.AddNamedDecl(parser_named_decl);
- } while (0);
- }
-
- if (name_unique_cstr[0] == '$' && !namespace_decl)
- {
- static ConstString g_lldb_class_name ("$__lldb_class");
+ NamedDecl *persistent_decl =
+ m_parser_vars->m_persistent_vars->GetPersistentDecl(name);
- if (name == g_lldb_class_name)
- {
- // Clang is looking for the type of "this"
+ if (!persistent_decl)
+ break;
- if (frame == NULL)
- return;
+ Decl *parser_persistent_decl = m_ast_importer_sp->CopyDecl(
+ m_ast_context, scratch_ast_context, persistent_decl);
+ if (!parser_persistent_decl)
+ break;
- // Find the block that defines the function represented by "sym_ctx"
- Block *function_block = sym_ctx.GetFunctionBlock();
+ NamedDecl *parser_named_decl =
+ dyn_cast<NamedDecl>(parser_persistent_decl);
- if (!function_block)
- return;
+ if (!parser_named_decl)
+ break;
- CompilerDeclContext function_decl_ctx = function_block->GetDeclContext();
+ if (clang::FunctionDecl *parser_function_decl =
+ llvm::dyn_cast<clang::FunctionDecl>(parser_named_decl)) {
+ MaybeRegisterFunctionBody(parser_function_decl);
+ }
- if (!function_decl_ctx)
- return;
+ if (log)
+ log->Printf(" CEDM::FEVD[%u] Found persistent decl %s", current_id,
+ name.GetCString());
- clang::CXXMethodDecl *method_decl = ClangASTContext::DeclContextGetAsCXXMethodDecl(function_decl_ctx);
+ context.AddNamedDecl(parser_named_decl);
+ } while (0);
+ }
- if (method_decl)
- {
- clang::CXXRecordDecl *class_decl = method_decl->getParent();
+ if (name_unique_cstr[0] == '$' && !namespace_decl) {
+ static ConstString g_lldb_class_name("$__lldb_class");
- QualType class_qual_type(class_decl->getTypeForDecl(), 0);
+ if (name == g_lldb_class_name) {
+ // Clang is looking for the type of "this"
- TypeFromUser class_user_type (class_qual_type.getAsOpaquePtr(),
- ClangASTContext::GetASTContext(&class_decl->getASTContext()));
+ if (frame == NULL)
+ return;
- if (log)
- {
- ASTDumper ast_dumper(class_qual_type);
- log->Printf(" CEDM::FEVD[%u] Adding type for $__lldb_class: %s", current_id, ast_dumper.GetCString());
- }
+ // Find the block that defines the function represented by "sym_ctx"
+ Block *function_block = sym_ctx.GetFunctionBlock();
- AddThisType(context, class_user_type, current_id);
+ if (!function_block)
+ return;
- if (method_decl->isInstance())
- {
- // self is a pointer to the object
+ CompilerDeclContext function_decl_ctx = function_block->GetDeclContext();
- QualType class_pointer_type = method_decl->getASTContext().getPointerType(class_qual_type);
+ if (!function_decl_ctx)
+ return;
- TypeFromUser self_user_type(class_pointer_type.getAsOpaquePtr(),
- ClangASTContext::GetASTContext(&method_decl->getASTContext()));
+ clang::CXXMethodDecl *method_decl =
+ ClangASTContext::DeclContextGetAsCXXMethodDecl(function_decl_ctx);
- m_struct_vars->m_object_pointer_type = self_user_type;
- }
- }
- else
- {
- // This branch will get hit if we are executing code in the context of a function that
- // 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 "this" variable in the current
- // 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;
-
- TypeFromUser pointee_type = this_type->GetForwardCompilerType ().GetPointeeType();
-
- if (pointee_type.IsValid())
- {
- if (log)
- {
- ASTDumper ast_dumper(pointee_type);
- log->Printf(" FEVD[%u] Adding type for $__lldb_class: %s", current_id, ast_dumper.GetCString());
- }
-
- AddThisType(context, pointee_type, current_id);
- TypeFromUser this_user_type(this_type->GetFullCompilerType ());
- m_struct_vars->m_object_pointer_type = this_user_type;
- return;
- }
- }
+ 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(),
+ ClangASTContext::GetASTContext(&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());
+ }
+
+ AddThisType(context, class_user_type, current_id);
+
+ 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(),
+ ClangASTContext::GetASTContext(&method_decl->getASTContext()));
+
+ m_struct_vars->m_object_pointer_type = self_user_type;
+ }
+ } else {
+ // This branch will get hit if we are executing code in the context of a
+ // function that
+ // 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 "this" variable
+ // in the current
+ // 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;
+
+ TypeFromUser pointee_type =
+ this_type->GetForwardCompilerType().GetPointeeType();
+
+ if (pointee_type.IsValid()) {
+ if (log) {
+ ASTDumper ast_dumper(pointee_type);
+ log->Printf(" FEVD[%u] Adding type for $__lldb_class: %s",
+ current_id, ast_dumper.GetCString());
}
+ AddThisType(context, pointee_type, current_id);
+ TypeFromUser this_user_type(this_type->GetFullCompilerType());
+ m_struct_vars->m_object_pointer_type = this_user_type;
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"
+ return;
+ }
- if (!frame)
- 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"
- SymbolContext sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction|lldb::eSymbolContextBlock);
+ if (!frame)
+ return;
- // Find the block that defines the function represented by "sym_ctx"
- Block *function_block = sym_ctx.GetFunctionBlock();
+ SymbolContext sym_ctx = frame->GetSymbolContext(
+ lldb::eSymbolContextFunction | lldb::eSymbolContextBlock);
- if (!function_block)
- return;
+ // Find the block that defines the function represented by "sym_ctx"
+ Block *function_block = sym_ctx.GetFunctionBlock();
- CompilerDeclContext function_decl_ctx = function_block->GetDeclContext();
+ if (!function_block)
+ return;
- if (!function_decl_ctx)
- return;
+ CompilerDeclContext function_decl_ctx = function_block->GetDeclContext();
- clang::ObjCMethodDecl *method_decl = ClangASTContext::DeclContextGetAsObjCMethodDecl(function_decl_ctx);
+ if (!function_decl_ctx)
+ return;
- if (method_decl)
- {
- ObjCInterfaceDecl* self_interface = method_decl->getClassInterface();
+ clang::ObjCMethodDecl *method_decl =
+ ClangASTContext::DeclContextGetAsObjCMethodDecl(function_decl_ctx);
- if (!self_interface)
- return;
+ if (method_decl) {
+ ObjCInterfaceDecl *self_interface = method_decl->getClassInterface();
- const clang::Type *interface_type = self_interface->getTypeForDecl();
+ if (!self_interface)
+ return;
- if (!interface_type)
- return; // This is unlikely, but we have seen crashes where this occurred
+ const clang::Type *interface_type = self_interface->getTypeForDecl();
- TypeFromUser class_user_type(QualType(interface_type, 0).getAsOpaquePtr(),
- ClangASTContext::GetASTContext(&method_decl->getASTContext()));
+ if (!interface_type)
+ return; // This is unlikely, but we have seen crashes where this
+ // occurred
- if (log)
- {
- ASTDumper ast_dumper(interface_type);
- log->Printf(" FEVD[%u] Adding type for $__lldb_objc_class: %s", current_id, ast_dumper.GetCString());
- }
+ TypeFromUser class_user_type(
+ QualType(interface_type, 0).getAsOpaquePtr(),
+ ClangASTContext::GetASTContext(&method_decl->getASTContext()));
- AddOneType(context, class_user_type, current_id);
+ if (log) {
+ ASTDumper ast_dumper(interface_type);
+ log->Printf(" FEVD[%u] Adding type for $__lldb_objc_class: %s",
+ current_id, ast_dumper.GetCString());
+ }
- if (method_decl->isInstanceMethod())
- {
- // self is a pointer to the object
+ AddOneType(context, class_user_type, current_id);
- QualType class_pointer_type = method_decl->getASTContext().getObjCObjectPointerType(QualType(interface_type, 0));
+ if (method_decl->isInstanceMethod()) {
+ // self is a pointer to the object
- TypeFromUser self_user_type(class_pointer_type.getAsOpaquePtr(),
- ClangASTContext::GetASTContext(&method_decl->getASTContext()));
+ QualType class_pointer_type =
+ method_decl->getASTContext().getObjCObjectPointerType(
+ QualType(interface_type, 0));
- 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_pointer_type.getAsOpaquePtr(),
+ ClangASTContext::GetASTContext(&method_decl->getASTContext()));
- TypeFromUser self_user_type(class_type.getAsOpaquePtr(),
- ClangASTContext::GetASTContext(&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();
- m_struct_vars->m_object_pointer_type = self_user_type;
- }
+ TypeFromUser self_user_type(
+ class_type.getAsOpaquePtr(),
+ ClangASTContext::GetASTContext(&method_decl->getASTContext()));
- return;
- }
- else
- {
- // This branch will get hit if we are executing code in the context of a function that
- // 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 current
- // scope and use its type.
+ m_struct_vars->m_object_pointer_type = self_user_type;
+ }
- VariableList *vars = frame->GetVariableList(false);
+ return;
+ } else {
+ // This branch will get hit if we are executing code in the context of a
+ // function that
+ // 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 current
+ // scope and use its type.
- lldb::VariableSP self_var = vars->FindVariable(ConstString("self"));
+ VariableList *vars = frame->GetVariableList(false);
- if (self_var &&
- self_var->IsInScope(frame) &&
- self_var->LocationIsValidForFrame (frame))
- {
- Type *self_type = self_var->GetType();
+ lldb::VariableSP self_var = vars->FindVariable(ConstString("self"));
- if (!self_type)
- return;
+ if (self_var && self_var->IsInScope(frame) &&
+ self_var->LocationIsValidForFrame(frame)) {
+ Type *self_type = self_var->GetType();
- CompilerType self_clang_type = self_type->GetFullCompilerType ();
+ if (!self_type)
+ return;
- if (ClangASTContext::IsObjCClassType(self_clang_type))
- {
- return;
- }
- else if (ClangASTContext::IsObjCObjectPointerType(self_clang_type))
- {
- self_clang_type = self_clang_type.GetPointeeType();
+ CompilerType self_clang_type = self_type->GetFullCompilerType();
- if (!self_clang_type)
- return;
+ if (ClangASTContext::IsObjCClassType(self_clang_type)) {
+ return;
+ } else if (ClangASTContext::IsObjCObjectPointerType(
+ self_clang_type)) {
+ self_clang_type = self_clang_type.GetPointeeType();
- if (log)
- {
- ASTDumper ast_dumper(self_type->GetFullCompilerType ());
- log->Printf(" FEVD[%u] Adding type for $__lldb_objc_class: %s", current_id, ast_dumper.GetCString());
- }
+ if (!self_clang_type)
+ return;
- TypeFromUser class_user_type (self_clang_type);
+ if (log) {
+ ASTDumper ast_dumper(self_type->GetFullCompilerType());
+ log->Printf(" FEVD[%u] Adding type for $__lldb_objc_class: %s",
+ current_id, ast_dumper.GetCString());
+ }
- AddOneType(context, class_user_type, current_id);
+ TypeFromUser class_user_type(self_clang_type);
- TypeFromUser self_user_type(self_type->GetFullCompilerType ());
+ AddOneType(context, class_user_type, current_id);
- m_struct_vars->m_object_pointer_type = self_user_type;
- return;
- }
- }
- }
+ TypeFromUser self_user_type(self_type->GetFullCompilerType());
+ m_struct_vars->m_object_pointer_type = self_user_type;
return;
+ }
}
+ }
- if (name == ConstString(g_lldb_local_vars_namespace_cstr))
- {
- CompilerDeclContext frame_decl_context = sym_ctx.block != nullptr ?
- sym_ctx.block->GetDeclContext() :
- CompilerDeclContext();
-
- if (frame_decl_context)
- {
- ClangASTContext *ast = llvm::dyn_cast_or_null<ClangASTContext>(frame_decl_context.GetTypeSystem());
-
- if (ast)
- {
- clang::NamespaceDecl *namespace_decl = ClangASTContext::GetUniqueNamespaceDeclaration(
- m_ast_context, name_unique_cstr, nullptr);
- if (namespace_decl)
- {
- context.AddNamedDecl(namespace_decl);
- clang::DeclContext *clang_decl_ctx = clang::Decl::castToDeclContext(namespace_decl);
- clang_decl_ctx->setHasExternalVisibleStorage(true);
- context.m_found.local_vars_nsp = true;
- }
- }
- }
+ return;
+ }
- return;
+ if (name == ConstString(g_lldb_local_vars_namespace_cstr)) {
+ CompilerDeclContext frame_decl_context =
+ sym_ctx.block != nullptr ? sym_ctx.block->GetDeclContext()
+ : CompilerDeclContext();
+
+ if (frame_decl_context) {
+ ClangASTContext *ast = llvm::dyn_cast_or_null<ClangASTContext>(
+ frame_decl_context.GetTypeSystem());
+
+ if (ast) {
+ clang::NamespaceDecl *namespace_decl =
+ ClangASTContext::GetUniqueNamespaceDeclaration(
+ m_ast_context, name_unique_cstr, nullptr);
+ if (namespace_decl) {
+ context.AddNamedDecl(namespace_decl);
+ clang::DeclContext *clang_decl_ctx =
+ clang::Decl::castToDeclContext(namespace_decl);
+ clang_decl_ctx->setHasExternalVisibleStorage(true);
+ context.m_found.local_vars_nsp = true;
+ }
}
+ }
- // any other $__lldb names should be weeded out now
- if (!::strncmp(name_unique_cstr, "$__lldb", sizeof("$__lldb") - 1))
- return;
+ return;
+ }
- ExpressionVariableSP pvar_sp(m_parser_vars->m_persistent_vars->GetVariable(name));
+ // any other $__lldb names should be weeded out now
+ if (!::strncmp(name_unique_cstr, "$__lldb", sizeof("$__lldb") - 1))
+ return;
- if (pvar_sp)
- {
- AddOneVariable(context, pvar_sp, current_id);
- return;
- }
+ ExpressionVariableSP pvar_sp(
+ m_parser_vars->m_persistent_vars->GetVariable(name));
- const char *reg_name(&name.GetCString()[1]);
+ if (pvar_sp) {
+ AddOneVariable(context, pvar_sp, current_id);
+ return;
+ }
- if (m_parser_vars->m_exe_ctx.GetRegisterContext())
- {
- const RegisterInfo *reg_info(m_parser_vars->m_exe_ctx.GetRegisterContext()->GetRegisterInfoByName(reg_name));
+ const char *reg_name(&name.GetCString()[1]);
- if (reg_info)
- {
- if (log)
- log->Printf(" CEDM::FEVD[%u] Found register %s", current_id, reg_info->name);
+ if (m_parser_vars->m_exe_ctx.GetRegisterContext()) {
+ const RegisterInfo *reg_info(
+ m_parser_vars->m_exe_ctx.GetRegisterContext()->GetRegisterInfoByName(
+ reg_name));
- AddOneRegister(context, reg_info, current_id);
- }
- }
+ if (reg_info) {
+ if (log)
+ log->Printf(" CEDM::FEVD[%u] Found register %s", current_id,
+ reg_info->name);
+
+ AddOneRegister(context, reg_info, current_id);
+ }
}
- else
- {
- ValueObjectSP valobj;
- VariableSP var;
-
- bool local_var_lookup = !namespace_decl ||
- (namespace_decl.GetName() == ConstString(g_lldb_local_vars_namespace_cstr));
- if (frame && local_var_lookup)
- {
- CompilerDeclContext compiler_decl_context = sym_ctx.block != nullptr ? sym_ctx.block->GetDeclContext() : CompilerDeclContext();
-
- if (compiler_decl_context)
- {
- // Make sure that the variables are parsed so that we have the declarations.
- VariableListSP vars = frame->GetInScopeVariableList(true);
- for (size_t i = 0; i < vars->GetSize(); i++)
- vars->GetVariableAtIndex(i)->GetDecl();
-
- // Search for declarations matching the name. Do not include imported decls
- // in the search if we are looking for decls in the artificial namespace
- // $__lldb_local_vars.
- std::vector<CompilerDecl> found_decls = compiler_decl_context.FindDeclByName(name, namespace_decl.IsValid());
-
- bool variable_found = false;
- for (CompilerDecl decl : found_decls)
- {
- for (size_t vi = 0, ve = vars->GetSize(); vi != ve; ++vi)
- {
- VariableSP candidate_var = vars->GetVariableAtIndex(vi);
- if (candidate_var->GetDecl() == decl)
- {
- var = candidate_var;
- break;
- }
- }
-
- if (var)
- {
- variable_found = true;
- valobj = ValueObjectVariable::Create(frame, var);
- AddOneVariable(context, var, valobj, current_id);
- context.m_found.variable = true;
- }
- }
- if (variable_found)
- return;
+ } else {
+ ValueObjectSP valobj;
+ VariableSP var;
+
+ bool local_var_lookup =
+ !namespace_decl || (namespace_decl.GetName() ==
+ ConstString(g_lldb_local_vars_namespace_cstr));
+ if (frame && local_var_lookup) {
+ CompilerDeclContext compiler_decl_context =
+ sym_ctx.block != nullptr ? sym_ctx.block->GetDeclContext()
+ : CompilerDeclContext();
+
+ if (compiler_decl_context) {
+ // Make sure that the variables are parsed so that we have the
+ // declarations.
+ VariableListSP vars = frame->GetInScopeVariableList(true);
+ for (size_t i = 0; i < vars->GetSize(); i++)
+ vars->GetVariableAtIndex(i)->GetDecl();
+
+ // Search for declarations matching the name. Do not include imported
+ // decls
+ // in the search if we are looking for decls in the artificial namespace
+ // $__lldb_local_vars.
+ std::vector<CompilerDecl> found_decls =
+ compiler_decl_context.FindDeclByName(name,
+ namespace_decl.IsValid());
+
+ bool variable_found = false;
+ for (CompilerDecl decl : found_decls) {
+ for (size_t vi = 0, ve = vars->GetSize(); vi != ve; ++vi) {
+ VariableSP candidate_var = vars->GetVariableAtIndex(vi);
+ if (candidate_var->GetDecl() == decl) {
+ var = candidate_var;
+ break;
}
+ }
+
+ if (var) {
+ variable_found = true;
+ valobj = ValueObjectVariable::Create(frame, var);
+ AddOneVariable(context, var, valobj, current_id);
+ context.m_found.variable = true;
+ }
}
- if (target)
- {
- var = FindGlobalVariable (*target,
- module_sp,
- name,
- &namespace_decl,
- NULL);
-
- if (var)
- {
- valobj = ValueObjectVariable::Create(target, var);
- AddOneVariable(context, var, valobj, current_id);
- context.m_found.variable = true;
- return;
+ if (variable_found)
+ return;
+ }
+ }
+ if (target) {
+ var = FindGlobalVariable(*target, module_sp, name, &namespace_decl, NULL);
+
+ if (var) {
+ valobj = ValueObjectVariable::Create(target, var);
+ AddOneVariable(context, var, valobj, current_id);
+ context.m_found.variable = true;
+ return;
+ }
+ }
+
+ std::vector<clang::NamedDecl *> decls_from_modules;
+
+ if (target) {
+ if (ClangModulesDeclVendor *decl_vendor =
+ target->GetClangModulesDeclVendor()) {
+ decl_vendor->FindDecls(name, false, UINT32_MAX, decls_from_modules);
+ }
+ }
+
+ 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,
+ include_symbols, include_inlines, append,
+ sc_list);
+ } 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, sc_list);
+ }
+
+ // If we found more than one function, see if we can use the
+ // frame's decl context to remove functions that are shadowed
+ // by other functions which match in type but are nearer in scope.
+ //
+ // AddOneFunction will not add a function whose type has already been
+ // added, so if there's another function in the list with a matching
+ // type, check to see if their decl context is a parent of the current
+ // frame's or was imported via a and using statement, and pick the
+ // best match according to lookup rules.
+ if (sc_list.GetSize() > 1) {
+ // Collect some info about our frame's context.
+ StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr();
+ SymbolContext frame_sym_ctx;
+ if (frame != nullptr)
+ frame_sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction |
+ lldb::eSymbolContextBlock);
+ CompilerDeclContext frame_decl_context =
+ frame_sym_ctx.block != nullptr
+ ? frame_sym_ctx.block->GetDeclContext()
+ : CompilerDeclContext();
+
+ // We can't do this without a compiler decl context for our frame.
+ if (frame_decl_context) {
+ clang::DeclContext *frame_decl_ctx =
+ (clang::DeclContext *)frame_decl_context.GetOpaqueDeclContext();
+ ClangASTContext *ast = llvm::dyn_cast_or_null<ClangASTContext>(
+ frame_decl_context.GetTypeSystem());
+
+ // Structure to hold the info needed when comparing function
+ // declarations.
+ struct FuncDeclInfo {
+ ConstString m_name;
+ CompilerType m_copied_type;
+ uint32_t m_decl_lvl;
+ SymbolContext m_sym_ctx;
+ };
+
+ // First, symplify things by looping through the symbol contexts
+ // to remove unwanted functions and separate out the functions we
+ // want to compare and prune into a separate list.
+ // Cache the info needed about the function declarations in a
+ // vector for efficiency.
+ SymbolContextList sc_sym_list;
+ uint32_t num_indices = sc_list.GetSize();
+ std::vector<FuncDeclInfo> fdi_cache;
+ fdi_cache.reserve(num_indices);
+ for (uint32_t index = 0; index < num_indices; ++index) {
+ FuncDeclInfo fdi;
+ SymbolContext sym_ctx;
+ sc_list.GetContextAtIndex(index, sym_ctx);
+
+ // We don't know enough about symbols to compare them,
+ // but we should keep them in the list.
+ Function *function = sym_ctx.function;
+ if (!function) {
+ sc_sym_list.Append(sym_ctx);
+ continue;
}
- }
-
- std::vector<clang::NamedDecl *> decls_from_modules;
-
- if (target)
- {
- if (ClangModulesDeclVendor *decl_vendor = target->GetClangModulesDeclVendor())
- {
- decl_vendor->FindDecls(name, false, UINT32_MAX, decls_from_modules);
+ // Filter out functions without declaration contexts, as well as
+ // class/instance methods, since they'll be skipped in the
+ // code that follows anyway.
+ CompilerDeclContext func_decl_context = function->GetDeclContext();
+ if (!func_decl_context ||
+ func_decl_context.IsClassMethod(nullptr, nullptr, nullptr))
+ continue;
+ // We can only prune functions for which we can copy the type.
+ CompilerType func_clang_type =
+ function->GetType()->GetFullCompilerType();
+ CompilerType copied_func_type = GuardedCopyType(func_clang_type);
+ if (!copied_func_type) {
+ sc_sym_list.Append(sym_ctx);
+ continue;
}
- }
- 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,
- include_symbols,
- include_inlines,
- append,
- sc_list);
+ fdi.m_sym_ctx = sym_ctx;
+ fdi.m_name = function->GetName();
+ fdi.m_copied_type = copied_func_type;
+ fdi.m_decl_lvl = LLDB_INVALID_DECL_LEVEL;
+ if (fdi.m_copied_type && func_decl_context) {
+ // Call CountDeclLevels to get the number of parent scopes we
+ // have to look through before we find the function declaration.
+ // When comparing functions of the same type, the one with a
+ // lower count will be closer to us in the lookup scope and
+ // shadows the other.
+ clang::DeclContext *func_decl_ctx =
+ (clang::DeclContext *)
+ func_decl_context.GetOpaqueDeclContext();
+ fdi.m_decl_lvl =
+ ast->CountDeclLevels(frame_decl_ctx, func_decl_ctx,
+ &fdi.m_name, &fdi.m_copied_type);
}
- 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,
- sc_list);
+ fdi_cache.emplace_back(fdi);
+ }
+
+ // Loop through the functions in our cache looking for matching types,
+ // then compare their scope levels to see which is closer.
+ std::multimap<CompilerType, const FuncDeclInfo *> matches;
+ for (const FuncDeclInfo &fdi : fdi_cache) {
+ const CompilerType t = fdi.m_copied_type;
+ auto q = matches.find(t);
+ if (q != matches.end()) {
+ if (q->second->m_decl_lvl > fdi.m_decl_lvl)
+ // This function is closer; remove the old set.
+ matches.erase(t);
+ else if (q->second->m_decl_lvl < fdi.m_decl_lvl)
+ // The functions in our set are closer - skip this one.
+ continue;
}
+ matches.insert(std::make_pair(t, &fdi));
+ }
- // If we found more than one function, see if we can use the
- // frame's decl context to remove functions that are shadowed
- // by other functions which match in type but are nearer in scope.
- //
- // AddOneFunction will not add a function whose type has already been
- // added, so if there's another function in the list with a matching
- // type, check to see if their decl context is a parent of the current
- // frame's or was imported via a and using statement, and pick the
- // best match according to lookup rules.
- if (sc_list.GetSize() > 1)
- {
- // Collect some info about our frame's context.
- StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr();
- SymbolContext frame_sym_ctx;
- if (frame != nullptr)
- frame_sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction|lldb::eSymbolContextBlock);
- CompilerDeclContext frame_decl_context = frame_sym_ctx.block != nullptr ? frame_sym_ctx.block->GetDeclContext() : CompilerDeclContext();
-
- // We can't do this without a compiler decl context for our frame.
- if (frame_decl_context)
- {
- clang::DeclContext *frame_decl_ctx = (clang::DeclContext *)frame_decl_context.GetOpaqueDeclContext();
- ClangASTContext *ast = llvm::dyn_cast_or_null<ClangASTContext>(frame_decl_context.GetTypeSystem());
-
- // Structure to hold the info needed when comparing function
- // declarations.
- struct FuncDeclInfo
- {
- ConstString m_name;
- CompilerType m_copied_type;
- uint32_t m_decl_lvl;
- SymbolContext m_sym_ctx;
- };
-
- // First, symplify things by looping through the symbol contexts
- // to remove unwanted functions and separate out the functions we
- // want to compare and prune into a separate list.
- // Cache the info needed about the function declarations in a
- // vector for efficiency.
- SymbolContextList sc_sym_list;
- uint32_t num_indices = sc_list.GetSize();
- std::vector<FuncDeclInfo> fdi_cache;
- fdi_cache.reserve(num_indices);
- for (uint32_t index = 0; index < num_indices; ++index)
- {
- FuncDeclInfo fdi;
- SymbolContext sym_ctx;
- sc_list.GetContextAtIndex(index, sym_ctx);
-
- // We don't know enough about symbols to compare them,
- // but we should keep them in the list.
- Function *function = sym_ctx.function;
- if (!function)
- {
- sc_sym_list.Append(sym_ctx);
- continue;
- }
- // Filter out functions without declaration contexts, as well as
- // class/instance methods, since they'll be skipped in the
- // code that follows anyway.
- CompilerDeclContext func_decl_context = function->GetDeclContext();
- if (!func_decl_context || func_decl_context.IsClassMethod(nullptr, nullptr, nullptr))
- continue;
- // We can only prune functions for which we can copy the type.
- CompilerType func_clang_type = function->GetType()->GetFullCompilerType();
- CompilerType copied_func_type = GuardedCopyType(func_clang_type);
- if (!copied_func_type)
- {
- sc_sym_list.Append(sym_ctx);
- continue;
- }
-
- fdi.m_sym_ctx = sym_ctx;
- fdi.m_name = function->GetName();
- fdi.m_copied_type = copied_func_type;
- fdi.m_decl_lvl = LLDB_INVALID_DECL_LEVEL;
- if (fdi.m_copied_type && func_decl_context)
- {
- // Call CountDeclLevels to get the number of parent scopes we
- // have to look through before we find the function declaration.
- // When comparing functions of the same type, the one with a
- // lower count will be closer to us in the lookup scope and
- // shadows the other.
- clang::DeclContext *func_decl_ctx = (clang::DeclContext *)func_decl_context.GetOpaqueDeclContext();
- fdi.m_decl_lvl = ast->CountDeclLevels(frame_decl_ctx,
- func_decl_ctx,
- &fdi.m_name,
- &fdi.m_copied_type);
- }
- fdi_cache.emplace_back(fdi);
- }
-
- // Loop through the functions in our cache looking for matching types,
- // then compare their scope levels to see which is closer.
- std::multimap<CompilerType, const FuncDeclInfo*> matches;
- for (const FuncDeclInfo &fdi : fdi_cache)
- {
- const CompilerType t = fdi.m_copied_type;
- auto q = matches.find(t);
- if (q != matches.end())
- {
- if (q->second->m_decl_lvl > fdi.m_decl_lvl)
- // This function is closer; remove the old set.
- matches.erase(t);
- else if (q->second->m_decl_lvl < fdi.m_decl_lvl)
- // The functions in our set are closer - skip this one.
- continue;
- }
- matches.insert(std::make_pair(t, &fdi));
- }
-
- // Loop through our matches and add their symbol contexts to our list.
- SymbolContextList sc_func_list;
- for (const auto &q : matches)
- sc_func_list.Append(q.second->m_sym_ctx);
-
- // Rejoin the lists with the functions in front.
- sc_list = sc_func_list;
- sc_list.Append(sc_sym_list);
- }
- }
+ // Loop through our matches and add their symbol contexts to our list.
+ SymbolContextList sc_func_list;
+ for (const auto &q : matches)
+ sc_func_list.Append(q.second->m_sym_ctx);
- 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)
- {
- CompilerDeclContext decl_ctx = sym_ctx.function->GetDeclContext();
-
- if (!decl_ctx)
- continue;
-
- // Filter out class/instance methods.
- if (decl_ctx.IsClassMethod(nullptr, nullptr, nullptr))
- 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 && 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)
- {
- for (clang::NamedDecl *decl : decls_from_modules)
- {
- if (llvm::isa<clang::FunctionDecl>(decl))
- {
- clang::NamedDecl *copied_decl = llvm::cast_or_null<FunctionDecl>(m_ast_importer_sp->CopyDecl(m_ast_context, &decl->getASTContext(), decl));
- if (copied_decl)
- {
- context.AddNamedDecl(copied_decl);
- context.m_found.function_with_type_info = true;
- }
- }
- }
- }
-
- if (!context.m_found.function_with_type_info)
- {
- if (extern_symbol)
- {
- AddOneFunction (context, NULL, extern_symbol, current_id);
- context.m_found.function = true;
- }
- else if (non_extern_symbol)
- {
- AddOneFunction (context, NULL, non_extern_symbol, current_id);
- context.m_found.function = true;
- }
- }
+ // Rejoin the lists with the functions in front.
+ sc_list = sc_func_list;
+ sc_list.Append(sc_sym_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) {
+ CompilerDeclContext decl_ctx = sym_ctx.function->GetDeclContext();
+
+ if (!decl_ctx)
+ continue;
+
+ // Filter out class/instance methods.
+ if (decl_ctx.IsClassMethod(nullptr, nullptr, nullptr))
+ 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 && target) {
+ sym_ctx.symbol = sym_ctx.symbol->ResolveReExportedSymbol(*target);
+ if (sym_ctx.symbol == NULL)
+ continue;
}
-
- if (!context.m_found.function_with_type_info)
- {
- // Try the modules next.
-
- do
- {
- if (ClangModulesDeclVendor *modules_decl_vendor = m_target->GetClangModulesDeclVendor())
- {
- bool append = false;
- uint32_t max_matches = 1;
- std::vector <clang::NamedDecl *> decls;
-
- if (!modules_decl_vendor->FindDecls(name,
- append,
- max_matches,
- decls))
- break;
-
- clang::NamedDecl *const decl_from_modules = decls[0];
-
- if (llvm::isa<clang::FunctionDecl>(decl_from_modules))
- {
- if (log)
- {
- log->Printf(" CAS::FEVD[%u] Matching function found for \"%s\" in the modules",
- current_id,
- name.GetCString());
- }
-
- clang::Decl *copied_decl = m_ast_importer_sp->CopyDecl(m_ast_context, &decl_from_modules->getASTContext(), decl_from_modules);
- clang::FunctionDecl *copied_function_decl = copied_decl ? dyn_cast<clang::FunctionDecl>(copied_decl) : nullptr;
-
- if (!copied_function_decl)
- {
- if (log)
- log->Printf(" CAS::FEVD[%u] - Couldn't export a function declaration from the modules",
- current_id);
-
- break;
- }
-
- MaybeRegisterFunctionBody(copied_function_decl);
-
- context.AddNamedDecl(copied_function_decl);
-
- context.m_found.function_with_type_info = true;
- context.m_found.function = true;
- }
- else if (llvm::isa<clang::VarDecl>(decl_from_modules))
- {
- if (log)
- {
- log->Printf(" CAS::FEVD[%u] Matching variable found for \"%s\" in the modules",
- current_id,
- name.GetCString());
- }
-
- clang::Decl *copied_decl = m_ast_importer_sp->CopyDecl(m_ast_context, &decl_from_modules->getASTContext(), decl_from_modules);
- clang::VarDecl *copied_var_decl = copied_decl ? dyn_cast_or_null<clang::VarDecl>(copied_decl) : nullptr;
-
- if (!copied_var_decl)
- {
- if (log)
- log->Printf(" CAS::FEVD[%u] - Couldn't export a variable declaration from the modules",
- current_id);
-
- break;
- }
-
- context.AddNamedDecl(copied_var_decl);
-
- context.m_found.variable = true;
- }
- }
- } while (0);
+
+ 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) {
+ for (clang::NamedDecl *decl : decls_from_modules) {
+ if (llvm::isa<clang::FunctionDecl>(decl)) {
+ clang::NamedDecl *copied_decl =
+ llvm::cast_or_null<FunctionDecl>(m_ast_importer_sp->CopyDecl(
+ m_ast_context, &decl->getASTContext(), decl));
+ if (copied_decl) {
+ context.AddNamedDecl(copied_decl);
+ context.m_found.function_with_type_info = true;
+ }
}
+ }
+ }
- 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
- // 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: ");
- warning.append(name.AsCString());
- const unsigned diag_id = m_ast_context->getDiagnostics().getCustomDiagID(clang::DiagnosticsEngine::Level::Warning, "%0");
- m_ast_context->getDiagnostics().Report(diag_id) << warning.c_str();
- AddOneGenericVariable(context, *data_symbol, current_id);
- context.m_found.variable = true;
- }
+ if (!context.m_found.function_with_type_info) {
+ if (extern_symbol) {
+ AddOneFunction(context, NULL, extern_symbol, current_id);
+ context.m_found.function = true;
+ } else if (non_extern_symbol) {
+ AddOneFunction(context, NULL, non_extern_symbol, current_id);
+ context.m_found.function = true;
+ }
+ }
+ }
+
+ if (!context.m_found.function_with_type_info) {
+ // Try the modules next.
+
+ do {
+ if (ClangModulesDeclVendor *modules_decl_vendor =
+ m_target->GetClangModulesDeclVendor()) {
+ bool append = false;
+ uint32_t max_matches = 1;
+ std::vector<clang::NamedDecl *> decls;
+
+ if (!modules_decl_vendor->FindDecls(name, append, max_matches,
+ decls))
+ break;
+
+ clang::NamedDecl *const decl_from_modules = decls[0];
+
+ if (llvm::isa<clang::FunctionDecl>(decl_from_modules)) {
+ if (log) {
+ log->Printf(" CAS::FEVD[%u] Matching function found for "
+ "\"%s\" in the modules",
+ current_id, name.GetCString());
+ }
+
+ clang::Decl *copied_decl = m_ast_importer_sp->CopyDecl(
+ m_ast_context, &decl_from_modules->getASTContext(),
+ decl_from_modules);
+ clang::FunctionDecl *copied_function_decl =
+ copied_decl ? dyn_cast<clang::FunctionDecl>(copied_decl)
+ : nullptr;
+
+ if (!copied_function_decl) {
+ if (log)
+ log->Printf(" CAS::FEVD[%u] - Couldn't export a function "
+ "declaration from the modules",
+ current_id);
+
+ break;
+ }
+
+ MaybeRegisterFunctionBody(copied_function_decl);
+
+ context.AddNamedDecl(copied_function_decl);
+
+ context.m_found.function_with_type_info = true;
+ context.m_found.function = true;
+ } else if (llvm::isa<clang::VarDecl>(decl_from_modules)) {
+ if (log) {
+ log->Printf(" CAS::FEVD[%u] Matching variable found for "
+ "\"%s\" in the modules",
+ current_id, name.GetCString());
+ }
+
+ clang::Decl *copied_decl = m_ast_importer_sp->CopyDecl(
+ m_ast_context, &decl_from_modules->getASTContext(),
+ decl_from_modules);
+ clang::VarDecl *copied_var_decl =
+ copied_decl ? dyn_cast_or_null<clang::VarDecl>(copied_decl)
+ : nullptr;
+
+ if (!copied_var_decl) {
+ if (log)
+ log->Printf(" CAS::FEVD[%u] - Couldn't export a variable "
+ "declaration from the modules",
+ current_id);
+
+ break;
+ }
+
+ context.AddNamedDecl(copied_var_decl);
+
+ context.m_found.variable = true;
}
+ }
+ } while (0);
+ }
+
+ 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
+ // 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: ");
+ warning.append(name.AsCString());
+ const unsigned diag_id =
+ m_ast_context->getDiagnostics().getCustomDiagID(
+ clang::DiagnosticsEngine::Level::Warning, "%0");
+ m_ast_context->getDiagnostics().Report(diag_id) << warning.c_str();
+ AddOneGenericVariable(context, *data_symbol, current_id);
+ context.m_found.variable = true;
}
+ }
}
+ }
}
-//static opaque_compiler_type_t
-//MaybePromoteToBlockPointerType
+// static opaque_compiler_type_t
+// MaybePromoteToBlockPointerType
//(
// ASTContext *ast_context,
// opaque_compiler_type_t candidate_type
@@ -1647,14 +1562,16 @@ ClangExpressionDeclMap::FindExternalVisibleDecls (NameSearchContext &context,
//
// QualType candidate_qual_type = QualType::getFromOpaquePtr(candidate_type);
//
-// const PointerType *candidate_pointer_type = dyn_cast<PointerType>(candidate_qual_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);
+// const RecordType *pointee_record_type =
+// dyn_cast<RecordType>(pointee_qual_type);
//
// if (!pointee_record_type)
// return candidate_type;
@@ -1664,659 +1581,639 @@ ClangExpressionDeclMap::FindExternalVisibleDecls (NameSearchContext &context,
// if (!pointee_record_decl->isRecord())
// return candidate_type;
//
-// if (!pointee_record_decl->getName().startswith(llvm::StringRef("__block_literal_")))
+// 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);
+// 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,
- lldb_private::Value &var_location,
- TypeFromUser *user_type,
- TypeFromParser *parser_type)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
- Type *var_type = var->GetType();
-
- if (!var_type)
- {
- if (log)
- log->PutCString("Skipped a definition because it has no type");
- return false;
- }
-
- CompilerType var_clang_type = var_type->GetFullCompilerType ();
+bool ClangExpressionDeclMap::GetVariableValue(VariableSP &var,
+ lldb_private::Value &var_location,
+ TypeFromUser *user_type,
+ TypeFromParser *parser_type) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- if (!var_clang_type)
- {
- if (log)
- log->PutCString("Skipped a definition because it has no Clang type");
- return false;
- }
-
- ClangASTContext *clang_ast = llvm::dyn_cast_or_null<ClangASTContext>(var_type->GetForwardCompilerType().GetTypeSystem());
-
- if (!clang_ast)
- {
- if (log)
- log->PutCString("Skipped a definition because it has no Clang AST");
- return false;
- }
+ Type *var_type = var->GetType();
+ if (!var_type) {
+ if (log)
+ log->PutCString("Skipped a definition because it has no type");
+ return false;
+ }
- ASTContext *ast = clang_ast->getASTContext();
+ CompilerType var_clang_type = var_type->GetFullCompilerType();
- if (!ast)
- {
- if (log)
- log->PutCString("There is no AST context for the current execution context");
- return false;
- }
- //var_clang_type = MaybePromoteToBlockPointerType (ast, var_clang_type);
+ if (!var_clang_type) {
+ if (log)
+ log->PutCString("Skipped a definition because it has no Clang type");
+ return false;
+ }
- DWARFExpression &var_location_expr = var->LocationExpression();
+ ClangASTContext *clang_ast = llvm::dyn_cast_or_null<ClangASTContext>(
+ var_type->GetForwardCompilerType().GetTypeSystem());
- Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
- Error err;
+ if (!clang_ast) {
+ if (log)
+ log->PutCString("Skipped a definition because it has no Clang AST");
+ return false;
+ }
- if (var->GetLocationIsConstantValueData())
- {
- DataExtractor const_value_extractor;
+ ASTContext *ast = clang_ast->getASTContext();
- if (var_location_expr.GetExpressionData(const_value_extractor))
- {
- var_location = Value(const_value_extractor.GetDataStart(), const_value_extractor.GetByteSize());
- var_location.SetValueType(Value::eValueTypeHostAddress);
- }
- else
- {
- if (log)
- log->Printf("Error evaluating constant variable: %s", err.AsCString());
- return false;
- }
+ if (!ast) {
+ if (log)
+ log->PutCString(
+ "There is no AST context for the current execution context");
+ return false;
+ }
+ // var_clang_type = MaybePromoteToBlockPointerType (ast, var_clang_type);
+
+ DWARFExpression &var_location_expr = var->LocationExpression();
+
+ 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());
+ var_location.SetValueType(Value::eValueTypeHostAddress);
+ } else {
+ if (log)
+ log->Printf("Error evaluating constant variable: %s", err.AsCString());
+ return false;
}
+ }
- CompilerType type_to_use = GuardedCopyType(var_clang_type);
+ CompilerType 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");
+ if (!type_to_use) {
+ if (log)
+ log->Printf(
+ "Couldn't copy a variable's type into the parser's AST context");
- return false;
- }
+ return false;
+ }
- if (parser_type)
- *parser_type = TypeFromParser(type_to_use);
+ if (parser_type)
+ *parser_type = TypeFromParser(type_to_use);
- if (var_location.GetContextType() == Value::eContextTypeInvalid)
- var_location.SetCompilerType(type_to_use);
+ if (var_location.GetContextType() == Value::eContextTypeInvalid)
+ var_location.SetCompilerType(type_to_use);
- if (var_location.GetValueType() == Value::eValueTypeFileAddress)
- {
- SymbolContext var_sc;
- var->CalculateSymbolContext(&var_sc);
+ if (var_location.GetValueType() == Value::eValueTypeFileAddress) {
+ SymbolContext var_sc;
+ var->CalculateSymbolContext(&var_sc);
- if (!var_sc.module_sp)
- return false;
+ if (!var_sc.module_sp)
+ return false;
- Address so_addr(var_location.GetScalar().ULongLong(), var_sc.module_sp->GetSectionList());
+ Address so_addr(var_location.GetScalar().ULongLong(),
+ var_sc.module_sp->GetSectionList());
- lldb::addr_t load_addr = so_addr.GetLoadAddress(target);
+ 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 (load_addr != LLDB_INVALID_ADDRESS) {
+ var_location.GetScalar() = load_addr;
+ var_location.SetValueType(Value::eValueTypeLoadAddress);
}
+ }
- if (user_type)
- *user_type = TypeFromUser(var_clang_type);
+ if (user_type)
+ *user_type = TypeFromUser(var_clang_type);
- return true;
+ return true;
}
-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));
+void ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
+ VariableSP var,
+ ValueObjectSP valobj,
+ unsigned int current_id) {
+ assert(m_parser_vars.get());
- TypeFromUser ut;
- TypeFromParser pt;
- Value var_location;
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- 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))
- CompleteType(tag_type->getDecl());
- if (const ObjCObjectPointerType *objc_object_ptr_type = dyn_cast<ObjCObjectPointerType>(parser_type))
- CompleteType(objc_object_ptr_type->getInterfaceDecl());
- }
+ TypeFromUser ut;
+ TypeFromParser pt;
+ Value var_location;
+ if (!GetVariableValue(var, var_location, &ut, &pt))
+ return;
- bool is_reference = pt.IsReferenceType();
-
- NamedDecl *var_decl = NULL;
- if (is_reference)
- 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());
- ClangExpressionVariable *entity(new ClangExpressionVariable(valobj));
- m_found_entities.AddNewlyConstructedVariable(entity);
-
- assert (entity);
- entity->EnableParserVars(GetParserID());
- ClangExpressionVariable::ParserVars *parser_vars = entity->GetParserVars(GetParserID());
- parser_vars->m_parser_type = pt;
- parser_vars->m_named_decl = var_decl;
- parser_vars->m_llvm_value = NULL;
- parser_vars->m_lldb_value = var_location;
- parser_vars->m_lldb_var = var;
+ clang::QualType parser_opaque_type =
+ QualType::getFromOpaquePtr(pt.GetOpaqueQualType());
- if (is_reference)
- entity->m_flags |= ClangExpressionVariable::EVTypeIsReference;
+ if (parser_opaque_type.isNull())
+ return;
- if (log)
- {
- ASTDumper orig_dumper(ut.GetOpaqueQualType());
- 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());
- }
+ if (const clang::Type *parser_type = parser_opaque_type.getTypePtr()) {
+ if (const TagType *tag_type = dyn_cast<TagType>(parser_type))
+ CompleteType(tag_type->getDecl());
+ 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;
+ if (is_reference)
+ 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());
+ ClangExpressionVariable *entity(new ClangExpressionVariable(valobj));
+ m_found_entities.AddNewlyConstructedVariable(entity);
+
+ assert(entity);
+ entity->EnableParserVars(GetParserID());
+ ClangExpressionVariable::ParserVars *parser_vars =
+ entity->GetParserVars(GetParserID());
+ parser_vars->m_parser_type = pt;
+ parser_vars->m_named_decl = var_decl;
+ 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);
+ 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,
- ExpressionVariableSP &pvar_sp,
- unsigned int current_id)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
- TypeFromUser user_type (llvm::cast<ClangExpressionVariable>(pvar_sp.get())->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;
- }
+void ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
+ ExpressionVariableSP &pvar_sp,
+ unsigned int current_id) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- NamedDecl *var_decl = context.AddVarDecl(parser_type.GetLValueReferenceType());
+ TypeFromUser user_type(
+ llvm::cast<ClangExpressionVariable>(pvar_sp.get())->GetTypeFromUser());
- llvm::cast<ClangExpressionVariable>(pvar_sp.get())->EnableParserVars(GetParserID());
- ClangExpressionVariable::ParserVars *parser_vars = llvm::cast<ClangExpressionVariable>(pvar_sp.get())->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();
+ TypeFromParser parser_type(GuardedCopyType(user_type));
+ if (!parser_type.GetOpaqueQualType()) {
if (log)
- {
- ASTDumper ast_dumper(var_decl);
- log->Printf(" CEDM::FEVD[%u] Added pvar %s, returned %s", current_id, pvar_sp->GetName().GetCString(), ast_dumper.GetCString());
- }
+ 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());
+
+ llvm::cast<ClangExpressionVariable>(pvar_sp.get())
+ ->EnableParserVars(GetParserID());
+ ClangExpressionVariable::ParserVars *parser_vars =
+ llvm::cast<ClangExpressionVariable>(pvar_sp.get())
+ ->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);
+ log->Printf(" CEDM::FEVD[%u] Added pvar %s, returned %s", current_id,
+ pvar_sp->GetName().GetCString(), ast_dumper.GetCString());
+ }
}
-void
-ClangExpressionDeclMap::AddOneGenericVariable(NameSearchContext &context,
- const Symbol &symbol,
- unsigned int current_id)
-{
- assert(m_parser_vars.get());
+void ClangExpressionDeclMap::AddOneGenericVariable(NameSearchContext &context,
+ const Symbol &symbol,
+ unsigned int current_id) {
+ assert(m_parser_vars.get());
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
+ 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());
- ClangExpressionVariable *entity(new ClangExpressionVariable(m_parser_vars->m_exe_ctx.GetBestExecutionContextScope (),
- entity_name,
- user_type,
- m_parser_vars->m_target_info.byte_order,
- m_parser_vars->m_target_info.address_byte_size));
- m_found_entities.AddNewlyConstructedVariable(entity);
-
- 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.SetCompilerType(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);
+ if (target == NULL)
+ return;
- log->Printf(" CEDM::FEVD[%u] Found variable %s, returned %s", current_id, decl_name.c_str(), ast_dumper.GetCString());
- }
+ 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());
+ ClangExpressionVariable *entity(new ClangExpressionVariable(
+ m_parser_vars->m_exe_ctx.GetBestExecutionContextScope(), entity_name,
+ user_type, m_parser_vars->m_target_info.byte_order,
+ m_parser_vars->m_target_info.address_byte_size));
+ m_found_entities.AddNewlyConstructedVariable(entity);
+
+ 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.SetCompilerType(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
-ClangExpressionDeclMap::ResolveUnknownTypes()
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
- Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
+bool ClangExpressionDeclMap::ResolveUnknownTypes() {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+ Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
- ClangASTContext *scratch_ast_context = target->GetScratchClangASTContext();
+ ClangASTContext *scratch_ast_context = target->GetScratchClangASTContext();
- for (size_t index = 0, num_entities = m_found_entities.GetSize();
- index < num_entities;
- ++index)
- {
- ExpressionVariableSP entity = m_found_entities.GetVariableAtIndex(index);
+ for (size_t index = 0, num_entities = m_found_entities.GetSize();
+ index < num_entities; ++index) {
+ ExpressionVariableSP entity = m_found_entities.GetVariableAtIndex(index);
- ClangExpressionVariable::ParserVars *parser_vars = llvm::cast<ClangExpressionVariable>(entity.get())->GetParserVars(GetParserID());
+ ClangExpressionVariable::ParserVars *parser_vars =
+ llvm::cast<ClangExpressionVariable>(entity.get())
+ ->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 (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 (!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());
- }
+ 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(), ClangASTContext::GetASTContext(&var_decl->getASTContext()));
+ QualType var_type = var_decl->getType();
+ TypeFromParser parser_type(
+ var_type.getAsOpaquePtr(),
+ ClangASTContext::GetASTContext(&var_decl->getASTContext()));
- lldb::opaque_compiler_type_t copied_type = m_ast_importer_sp->CopyType(scratch_ast_context->getASTContext(), &var_decl->getASTContext(), var_type.getAsOpaquePtr());
+ lldb::opaque_compiler_type_t copied_type = m_ast_importer_sp->CopyType(
+ scratch_ast_context->getASTContext(), &var_decl->getASTContext(),
+ var_type.getAsOpaquePtr());
- if (!copied_type)
- {
- if (log)
- log->Printf("ClangExpressionDeclMap::ResolveUnknownType - Couldn't import the type for a variable");
+ if (!copied_type) {
+ if (log)
+ log->Printf("ClangExpressionDeclMap::ResolveUnknownType - Couldn't "
+ "import the type for a variable");
- return (bool) lldb::ExpressionVariableSP();
- }
+ return (bool)lldb::ExpressionVariableSP();
+ }
- TypeFromUser user_type(copied_type, scratch_ast_context);
+ TypeFromUser user_type(copied_type, scratch_ast_context);
-// parser_vars->m_lldb_value.SetContext(Value::eContextTypeClangType, user_type.GetOpaqueQualType());
- parser_vars->m_lldb_value.SetCompilerType(user_type);
- parser_vars->m_parser_type = parser_type;
+ // parser_vars->m_lldb_value.SetContext(Value::eContextTypeClangType,
+ // user_type.GetOpaqueQualType());
+ parser_vars->m_lldb_value.SetCompilerType(user_type);
+ parser_vars->m_parser_type = parser_type;
- entity->SetCompilerType(user_type);
+ entity->SetCompilerType(user_type);
- entity->m_flags &= ~(ClangExpressionVariable::EVUnknownType);
- }
+ entity->m_flags &= ~(ClangExpressionVariable::EVUnknownType);
}
+ }
- return true;
+ return true;
}
-void
-ClangExpressionDeclMap::AddOneRegister (NameSearchContext &context,
- const RegisterInfo *reg_info,
- unsigned int current_id)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
- CompilerType 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);
-
- ClangExpressionVariable *entity(new ClangExpressionVariable(m_parser_vars->m_exe_ctx.GetBestExecutionContextScope(),
- m_parser_vars->m_target_info.byte_order,
- m_parser_vars->m_target_info.address_byte_size));
- m_found_entities.AddNewlyConstructedVariable(entity);
+void ClangExpressionDeclMap::AddOneRegister(NameSearchContext &context,
+ const RegisterInfo *reg_info,
+ unsigned int current_id) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- std::string decl_name(context.m_decl_name.getAsString());
- entity->SetName (ConstString (decl_name.c_str()));
- entity->SetRegisterInfo (reg_info);
- entity->EnableParserVars(GetParserID());
- ClangExpressionVariable::ParserVars *parser_vars = entity->GetParserVars(GetParserID());
- parser_vars->m_parser_type = parser_clang_type;
- parser_vars->m_named_decl = var_decl;
- parser_vars->m_llvm_value = NULL;
- parser_vars->m_lldb_value.Clear();
- entity->m_flags |= ClangExpressionVariable::EVBareRegister;
+ CompilerType clang_type =
+ ClangASTContext::GetBuiltinTypeForEncodingAndBitSize(
+ m_ast_context, reg_info->encoding, reg_info->byte_size * 8);
+ if (!clang_type) {
if (log)
- {
- ASTDumper ast_dumper(var_decl);
- log->Printf(" CEDM::FEVD[%d] Added register %s, returned %s", current_id, context.m_decl_name.getAsString().c_str(), ast_dumper.GetCString());
- }
+ 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);
+
+ ClangExpressionVariable *entity(new ClangExpressionVariable(
+ m_parser_vars->m_exe_ctx.GetBestExecutionContextScope(),
+ m_parser_vars->m_target_info.byte_order,
+ m_parser_vars->m_target_info.address_byte_size));
+ m_found_entities.AddNewlyConstructedVariable(entity);
+
+ std::string decl_name(context.m_decl_name.getAsString());
+ entity->SetName(ConstString(decl_name.c_str()));
+ entity->SetRegisterInfo(reg_info);
+ entity->EnableParserVars(GetParserID());
+ ClangExpressionVariable::ParserVars *parser_vars =
+ entity->GetParserVars(GetParserID());
+ parser_vars->m_parser_type = parser_clang_type;
+ parser_vars->m_named_decl = var_decl;
+ parser_vars->m_llvm_value = NULL;
+ parser_vars->m_lldb_value.Clear();
+ entity->m_flags |= ClangExpressionVariable::EVBareRegister;
+
+ if (log) {
+ ASTDumper ast_dumper(var_decl);
+ log->Printf(" CEDM::FEVD[%d] Added register %s, returned %s", current_id,
+ context.m_decl_name.getAsString().c_str(),
+ ast_dumper.GetCString());
+ }
}
-void
-ClangExpressionDeclMap::AddOneFunction (NameSearchContext &context,
- Function* function,
- Symbol* symbol,
- unsigned int current_id)
-{
- assert (m_parser_vars.get());
-
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
- NamedDecl *function_decl = NULL;
- Address fun_address;
- CompilerType function_clang_type;
-
- bool is_indirect_function = false;
-
- if (function)
- {
- Type *function_type = function->GetType();
-
- const lldb::LanguageType comp_unit_language = function->GetCompileUnit()->GetLanguage();
- const bool extern_c = Language::LanguageIsC(comp_unit_language) ||
- (Language::LanguageIsObjC(comp_unit_language) &&
- !Language::LanguageIsCPlusPlus(comp_unit_language));
-
- if (!extern_c)
- {
- TypeSystem *type_system = function->GetDeclContext().GetTypeSystem();
- if (ClangASTContext *src_ast = llvm::dyn_cast<ClangASTContext>(type_system))
- {
- clang::DeclContext *src_decl_context = (clang::DeclContext*)function->GetDeclContext().GetOpaqueDeclContext();
- clang::FunctionDecl *src_function_decl = llvm::dyn_cast_or_null<clang::FunctionDecl>(src_decl_context);
-
- if (src_function_decl)
- {
- if (clang::FunctionDecl *copied_function_decl = llvm::dyn_cast_or_null<clang::FunctionDecl>(m_ast_importer_sp->CopyDecl(m_ast_context, src_ast->getASTContext(), src_function_decl)))
- {
- if (log)
- {
- ASTDumper ast_dumper((clang::Decl*)copied_function_decl);
-
- StreamString ss;
-
- function->DumpSymbolContext(&ss);
-
- log->Printf(" CEDM::FEVD[%u] Imported decl for function %s (description %s), returned %s",
- current_id, copied_function_decl->getNameAsString().c_str(), ss.GetData(),
- ast_dumper.GetCString());
- }
-
- context.AddNamedDecl(copied_function_decl);
- return;
- }
- else
- {
- if (log)
- {
- log->Printf (" Failed to import the function decl for '%s'",
- src_function_decl->getName().str().c_str());
- }
- }
- }
+void ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context,
+ Function *function, Symbol *symbol,
+ unsigned int current_id) {
+ assert(m_parser_vars.get());
+
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+
+ NamedDecl *function_decl = NULL;
+ Address fun_address;
+ CompilerType function_clang_type;
+
+ bool is_indirect_function = false;
+
+ if (function) {
+ Type *function_type = function->GetType();
+
+ const lldb::LanguageType comp_unit_language =
+ function->GetCompileUnit()->GetLanguage();
+ const bool extern_c = Language::LanguageIsC(comp_unit_language) ||
+ (Language::LanguageIsObjC(comp_unit_language) &&
+ !Language::LanguageIsCPlusPlus(comp_unit_language));
+
+ if (!extern_c) {
+ TypeSystem *type_system = function->GetDeclContext().GetTypeSystem();
+ if (ClangASTContext *src_ast =
+ llvm::dyn_cast<ClangASTContext>(type_system)) {
+ clang::DeclContext *src_decl_context =
+ (clang::DeclContext *)function->GetDeclContext()
+ .GetOpaqueDeclContext();
+ clang::FunctionDecl *src_function_decl =
+ llvm::dyn_cast_or_null<clang::FunctionDecl>(src_decl_context);
+
+ if (src_function_decl) {
+ if (clang::FunctionDecl *copied_function_decl =
+ llvm::dyn_cast_or_null<clang::FunctionDecl>(
+ m_ast_importer_sp->CopyDecl(m_ast_context,
+ src_ast->getASTContext(),
+ src_function_decl))) {
+ if (log) {
+ ASTDumper ast_dumper((clang::Decl *)copied_function_decl);
+
+ StreamString ss;
+
+ function->DumpSymbolContext(&ss);
+
+ log->Printf(" CEDM::FEVD[%u] Imported decl for function %s "
+ "(description %s), returned %s",
+ current_id,
+ copied_function_decl->getNameAsString().c_str(),
+ ss.GetData(), ast_dumper.GetCString());
}
- }
- if (!function_type)
- {
- if (log)
- log->PutCString(" Skipped a function because it has no type");
+ context.AddNamedDecl(copied_function_decl);
return;
+ } else {
+ if (log) {
+ log->Printf(" Failed to import the function decl for '%s'",
+ src_function_decl->getName().str().c_str());
+ }
+ }
}
+ }
+ }
- function_clang_type = function_type->GetFullCompilerType ();
+ if (!function_type) {
+ if (log)
+ log->PutCString(" Skipped a function because it has no type");
+ return;
+ }
- if (!function_clang_type)
- {
- if (log)
- log->PutCString(" Skipped a function because it has no Clang type");
- return;
- }
+ function_clang_type = function_type->GetFullCompilerType();
- fun_address = function->GetAddressRange().GetBaseAddress();
+ if (!function_clang_type) {
+ if (log)
+ log->PutCString(" Skipped a function because it has no Clang type");
+ return;
+ }
- CompilerType copied_function_type = GuardedCopyType(function_clang_type);
- if (copied_function_type)
- {
- function_decl = context.AddFunDecl(copied_function_type, extern_c);
+ fun_address = function->GetAddressRange().GetBaseAddress();
- if (!function_decl)
- {
- if (log)
- {
- log->Printf (" Failed to create a function decl for '%s' {0x%8.8" PRIx64 "}",
- function_type->GetName().GetCString(),
- function_type->GetID());
- }
+ CompilerType copied_function_type = GuardedCopyType(function_clang_type);
+ if (copied_function_type) {
+ function_decl = context.AddFunDecl(copied_function_type, extern_c);
- return;
- }
+ if (!function_decl) {
+ if (log) {
+ log->Printf(
+ " Failed to create a function decl for '%s' {0x%8.8" PRIx64 "}",
+ function_type->GetName().GetCString(), function_type->GetID());
}
- else
- {
- // We failed to copy the type we found
- if (log)
- {
- log->Printf (" Failed to import the function type '%s' {0x%8.8" PRIx64 "} into the expression parser AST contenxt",
- function_type->GetName().GetCString(),
- function_type->GetID());
- }
- return;
- }
- }
- else if (symbol)
- {
- fun_address = symbol->GetAddress();
- function_decl = context.AddGenericFunDecl();
- is_indirect_function = symbol->IsIndirect();
- }
- else
- {
- if (log)
- log->PutCString(" AddOneFunction called with no function and no symbol");
return;
+ }
+ } else {
+ // We failed to copy the type we found
+ if (log) {
+ log->Printf(" Failed to import the function type '%s' {0x%8.8" PRIx64
+ "} into the expression parser AST contenxt",
+ function_type->GetName().GetCString(),
+ function_type->GetID());
+ }
+
+ return;
}
+ } else if (symbol) {
+ fun_address = symbol->GetAddress();
+ function_decl = context.AddGenericFunDecl();
+ is_indirect_function = symbol->IsIndirect();
+ } else {
+ if (log)
+ 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);
+ Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
- ClangExpressionVariable *entity(new ClangExpressionVariable (m_parser_vars->m_exe_ctx.GetBestExecutionContextScope (),
- m_parser_vars->m_target_info.byte_order,
- m_parser_vars->m_target_info.address_byte_size));
- m_found_entities.AddNewlyConstructedVariable(entity);
+ lldb::addr_t load_addr =
+ fun_address.GetCallableLoadAddress(target, is_indirect_function);
- std::string decl_name(context.m_decl_name.getAsString());
- entity->SetName(ConstString(decl_name.c_str()));
- entity->SetCompilerType (function_clang_type);
- entity->EnableParserVars(GetParserID());
+ ClangExpressionVariable *entity(new ClangExpressionVariable(
+ m_parser_vars->m_exe_ctx.GetBestExecutionContextScope(),
+ m_parser_vars->m_target_info.byte_order,
+ m_parser_vars->m_target_info.address_byte_size));
+ m_found_entities.AddNewlyConstructedVariable(entity);
- ClangExpressionVariable::ParserVars *parser_vars = entity->GetParserVars(GetParserID());
+ std::string decl_name(context.m_decl_name.getAsString());
+ entity->SetName(ConstString(decl_name.c_str()));
+ entity->SetCompilerType(function_clang_type);
+ entity->EnableParserVars(GetParserID());
- if (load_addr != LLDB_INVALID_ADDRESS)
- {
- parser_vars->m_lldb_value.SetValueType(Value::eValueTypeLoadAddress);
- parser_vars->m_lldb_value.GetScalar() = load_addr;
- }
- else
- {
- // We have to try finding a file address.
+ ClangExpressionVariable::ParserVars *parser_vars =
+ entity->GetParserVars(GetParserID());
- lldb::addr_t file_addr = fun_address.GetFileAddress();
+ if (load_addr != LLDB_INVALID_ADDRESS) {
+ parser_vars->m_lldb_value.SetValueType(Value::eValueTypeLoadAddress);
+ parser_vars->m_lldb_value.GetScalar() = load_addr;
+ } else {
+ // We have to try finding a file address.
- parser_vars->m_lldb_value.SetValueType(Value::eValueTypeFileAddress);
- parser_vars->m_lldb_value.GetScalar() = file_addr;
- }
+ 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;
+ parser_vars->m_named_decl = function_decl;
+ parser_vars->m_llvm_value = NULL;
- if (log)
- {
- ASTDumper ast_dumper(function_decl);
+ if (log) {
+ ASTDumper ast_dumper(function_decl);
- StreamString ss;
+ StreamString ss;
- fun_address.Dump(&ss, m_parser_vars->m_exe_ctx.GetBestExecutionContextScope(), Address::DumpStyleResolvedDescription);
+ 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"),
- decl_name.c_str(),
- ss.GetData(),
- ast_dumper.GetCString());
- }
+ log->Printf(
+ " CEDM::FEVD[%u] Found %s function %s (description %s), returned %s",
+ current_id, (function ? "specific" : "generic"), decl_name.c_str(),
+ ss.GetData(), ast_dumper.GetCString());
+ }
}
-void
-ClangExpressionDeclMap::AddThisType(NameSearchContext &context,
- TypeFromUser &ut,
- unsigned int current_id)
-{
- CompilerType copied_clang_type = GuardedCopyType(ut);
+void ClangExpressionDeclMap::AddThisType(NameSearchContext &context,
+ TypeFromUser &ut,
+ unsigned int current_id) {
+ CompilerType copied_clang_type = GuardedCopyType(ut);
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- if (!copied_clang_type)
- {
- if (log)
- log->Printf("ClangExpressionDeclMap::AddThisType - Couldn't import the type");
+ if (!copied_clang_type) {
+ if (log)
+ log->Printf(
+ "ClangExpressionDeclMap::AddThisType - Couldn't import the type");
- return;
+ return;
+ }
+
+ if (copied_clang_type.IsAggregateType() &&
+ copied_clang_type.GetCompleteType()) {
+ CompilerType void_clang_type =
+ ClangASTContext::GetBasicType(m_ast_context, eBasicTypeVoid);
+ CompilerType void_ptr_clang_type = void_clang_type.GetPointerType();
+
+ CompilerType method_type = ClangASTContext::CreateFunctionType(
+ m_ast_context, void_clang_type, &void_ptr_clang_type, 1, false, 0);
+
+ 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;
+
+ CXXMethodDecl *method_decl =
+ ClangASTContext::GetASTContext(m_ast_context)
+ ->AddMethodToCXXRecordType(
+ copied_clang_type.GetOpaqueQualType(), "$__lldb_expr",
+ method_type, lldb::eAccessPublic, is_virtual, is_static,
+ is_inline, is_explicit, is_attr_used, is_artificial);
+
+ if (log) {
+ ASTDumper method_ast_dumper((clang::Decl *)method_decl);
+ ASTDumper type_ast_dumper(copied_clang_type);
+
+ log->Printf(" CEDM::AddThisType Added function $__lldb_expr "
+ "(description %s) for this type %s",
+ method_ast_dumper.GetCString(), type_ast_dumper.GetCString());
}
+ }
- if (copied_clang_type.IsAggregateType() && copied_clang_type.GetCompleteType ())
- {
- CompilerType void_clang_type = ClangASTContext::GetBasicType(m_ast_context, eBasicTypeVoid);
- CompilerType void_ptr_clang_type = void_clang_type.GetPointerType();
-
- CompilerType method_type = ClangASTContext::CreateFunctionType (m_ast_context,
- void_clang_type,
- &void_ptr_clang_type,
- 1,
- false,
- 0);
-
- 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;
-
- CXXMethodDecl *method_decl = ClangASTContext::GetASTContext(m_ast_context)->
- AddMethodToCXXRecordType (copied_clang_type.GetOpaqueQualType(),
- "$__lldb_expr",
- method_type,
- lldb::eAccessPublic,
- is_virtual,
- is_static,
- is_inline,
- is_explicit,
- is_attr_used,
- is_artificial);
-
- if (log)
- {
- ASTDumper method_ast_dumper((clang::Decl*)method_decl);
- ASTDumper type_ast_dumper(copied_clang_type);
-
- log->Printf(" CEDM::AddThisType Added function $__lldb_expr (description %s) for this type %s",
- method_ast_dumper.GetCString(),
- type_ast_dumper.GetCString());
- }
- }
+ if (!copied_clang_type.IsValid())
+ return;
- if (!copied_clang_type.IsValid())
- return;
-
- TypeSourceInfo *type_source_info = m_ast_context->getTrivialTypeSourceInfo(QualType::getFromOpaquePtr(copied_clang_type.GetOpaqueQualType()));
-
- if (!type_source_info)
- return;
-
- // Construct a typedef type because if "*this" is a templated type we can't just return ClassTemplateSpecializationDecls in response to name queries.
- // Using a typedef makes this much more robust.
-
- 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);
+ TypeSourceInfo *type_source_info = m_ast_context->getTrivialTypeSourceInfo(
+ QualType::getFromOpaquePtr(copied_clang_type.GetOpaqueQualType()));
+ if (!type_source_info)
return;
+
+ // Construct a typedef type because if "*this" is a templated type we can't
+ // just return ClassTemplateSpecializationDecls in response to name queries.
+ // Using a typedef makes this much more robust.
+
+ 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);
+
+ return;
}
-void
-ClangExpressionDeclMap::AddOneType(NameSearchContext &context,
- TypeFromUser &ut,
- unsigned int current_id)
-{
- CompilerType copied_clang_type = GuardedCopyType(ut);
+void ClangExpressionDeclMap::AddOneType(NameSearchContext &context,
+ TypeFromUser &ut,
+ unsigned int current_id) {
+ CompilerType copied_clang_type = GuardedCopyType(ut);
- if (!copied_clang_type)
- {
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ if (!copied_clang_type) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- if (log)
- log->Printf("ClangExpressionDeclMap::AddOneType - Couldn't import the type");
+ if (log)
+ log->Printf(
+ "ClangExpressionDeclMap::AddOneType - Couldn't import the type");
- return;
- }
+ return;
+ }
- context.AddTypeDecl(copied_clang_type);
+ context.AddTypeDecl(copied_clang_type);
}
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h
index 537db71cfeb..ab15d330539 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h
@@ -17,37 +17,40 @@
// C++ Includes
#include <vector>
-#include "ClangExpressionVariable.h"
#include "ClangASTSource.h"
+#include "ClangExpressionVariable.h"
// Other libraries and framework includes
// Project includes
-#include "llvm/ADT/DenseMap.h"
-#include "clang/AST/Decl.h"
-#include "lldb/lldb-public.h"
#include "lldb/Core/ClangForward.h"
#include "lldb/Core/Value.h"
#include "lldb/Expression/Materializer.h"
-#include "lldb/Symbol/TaggedASTType.h"
#include "lldb/Symbol/SymbolContext.h"
+#include "lldb/Symbol/TaggedASTType.h"
#include "lldb/Target/ExecutionContext.h"
+#include "lldb/lldb-public.h"
+#include "clang/AST/Decl.h"
+#include "llvm/ADT/DenseMap.h"
namespace lldb_private {
//----------------------------------------------------------------------
-/// @class ClangExpressionDeclMap ClangExpressionDeclMap.h "lldb/Expression/ClangExpressionDeclMap.h"
+/// @class ClangExpressionDeclMap ClangExpressionDeclMap.h
+/// "lldb/Expression/ClangExpressionDeclMap.h"
/// @brief Manages named entities that are defined in LLDB's debug information.
///
/// The Clang parser uses the ClangASTSource as an interface to request named
-/// entities from outside an expression. The ClangASTSource reports back, listing
+/// entities from outside an expression. The ClangASTSource reports back,
+/// listing
/// all possible objects corresponding to a particular name. But it in turn
-/// relies on ClangExpressionDeclMap, which performs several important functions.
+/// relies on ClangExpressionDeclMap, which performs several important
+/// functions.
///
/// First, it records what variables and functions were looked up and what Decls
/// were returned for them.
///
-/// Second, it constructs a struct on behalf of IRForTarget, recording which
-/// variables should be placed where and relaying this information back so that
+/// Second, it constructs a struct on behalf of IRForTarget, recording which
+/// variables should be placed where and relaying this information back so that
/// IRForTarget can generate context-independent code.
///
/// Third, it "materializes" this struct on behalf of the expression command,
@@ -57,642 +60,581 @@ namespace lldb_private {
/// Fourth and finally, it "dematerializes" the struct after the JITted code has
/// has executed, placing the new values back where it found the old ones.
//----------------------------------------------------------------------
-class ClangExpressionDeclMap :
- public ClangASTSource
-{
+class ClangExpressionDeclMap : public ClangASTSource {
public:
- //------------------------------------------------------------------
- /// Constructor
- ///
- /// Initializes class variables.
- ///
- /// @param[in] keep_result_in_memory
- /// If true, inhibits the normal deallocation of the memory for
- /// the result persistent variable, and instead marks the variable
- /// as persisting.
- ///
- /// @param[in] delegate
- /// If non-NULL, use this delegate to report result values. This
- /// allows the client ClangUserExpression to report a result.
- ///
- /// @param[in] exe_ctx
- /// The execution context to use when parsing.
- //------------------------------------------------------------------
- ClangExpressionDeclMap (bool keep_result_in_memory,
- Materializer::PersistentVariableDelegate *result_delegate,
- ExecutionContext &exe_ctx);
-
- //------------------------------------------------------------------
- /// Destructor
- //------------------------------------------------------------------
- ~ClangExpressionDeclMap() override;
-
- //------------------------------------------------------------------
- /// Enable the state needed for parsing and IR transformation.
- ///
- /// @param[in] exe_ctx
- /// The execution context to use when finding types for variables.
- /// Also used to find a "scratch" AST context to store result types.
- ///
- /// @param[in] materializer
- /// If non-NULL, the materializer to populate with information about
- /// the variables to use
- ///
- /// @return
- /// True if parsing is possible; false if it is unsafe to continue.
- //------------------------------------------------------------------
- bool
- WillParse (ExecutionContext &exe_ctx,
- Materializer *materializer);
-
- void
- InstallCodeGenerator (clang::ASTConsumer *code_gen);
-
- //------------------------------------------------------------------
- /// [Used by ClangExpressionParser] For each variable that had an unknown
- /// type at the beginning of parsing, determine its final type now.
- ///
- /// @return
- /// True on success; false otherwise.
- //------------------------------------------------------------------
- bool
- ResolveUnknownTypes();
-
- //------------------------------------------------------------------
- /// Disable the state needed for parsing and IR transformation.
- //------------------------------------------------------------------
- void
- DidParse ();
-
- //------------------------------------------------------------------
- /// [Used by IRForTarget] Add a variable to the list of persistent
- /// variables for the process.
- ///
- /// @param[in] decl
- /// The Clang declaration for the persistent variable, used for
- /// lookup during parsing.
- ///
- /// @param[in] name
- /// The name of the persistent variable, usually $something.
- ///
- /// @param[in] type
- /// The type of the variable, in the Clang parser's context.
- ///
- /// @return
- /// True on success; false otherwise.
- //------------------------------------------------------------------
- bool
- AddPersistentVariable (const clang::NamedDecl *decl,
- const ConstString &name,
- TypeFromParser type,
- bool is_result,
- bool is_lvalue);
-
- //------------------------------------------------------------------
- /// [Used by IRForTarget] Add a variable to the struct that needs to
- /// be materialized each time the expression runs.
- ///
- /// @param[in] decl
- /// The Clang declaration for the variable.
- ///
- /// @param[in] name
- /// The name of the variable.
- ///
- /// @param[in] value
- /// The LLVM IR value for this variable.
- ///
- /// @param[in] size
- /// The size of the variable in bytes.
- ///
- /// @param[in] alignment
- /// The required alignment of the variable in bytes.
- ///
- /// @return
- /// True on success; false otherwise.
- //------------------------------------------------------------------
- bool
- AddValueToStruct (const clang::NamedDecl *decl,
- const ConstString &name,
- llvm::Value *value,
- size_t size,
- lldb::offset_t alignment);
-
- //------------------------------------------------------------------
- /// [Used by IRForTarget] Finalize the struct, laying out the position
- /// of each object in it.
- ///
- /// @return
- /// True on success; false otherwise.
- //------------------------------------------------------------------
- bool
- DoStructLayout ();
-
- //------------------------------------------------------------------
- /// [Used by IRForTarget] Get general information about the laid-out
- /// struct after DoStructLayout() has been called.
- ///
- /// @param[out] num_elements
- /// The number of elements in the struct.
- ///
- /// @param[out] size
- /// The size of the struct, in bytes.
- ///
- /// @param[out] alignment
- /// The alignment of the struct, in bytes.
- ///
- /// @return
- /// True if the information could be retrieved; false otherwise.
- //------------------------------------------------------------------
- bool
- GetStructInfo (uint32_t &num_elements,
- size_t &size,
- lldb::offset_t &alignment);
-
- //------------------------------------------------------------------
- /// [Used by IRForTarget] Get specific information about one field
- /// of the laid-out struct after DoStructLayout() has been called.
- ///
- /// @param[out] decl
- /// The parsed Decl for the field, as generated by ClangASTSource
- /// on ClangExpressionDeclMap's behalf. In the case of the result
- /// value, this will have the name $__lldb_result even if the
- /// result value ends up having the name $1. This is an
- /// implementation detail of IRForTarget.
- ///
- /// @param[out] value
- /// The IR value for the field (usually a GlobalVariable). In
- /// the case of the result value, this will have the correct
- /// name ($1, for instance). This is an implementation detail
- /// of IRForTarget.
- ///
- /// @param[out] offset
- /// The offset of the field from the beginning of the struct.
- /// As long as the struct is aligned according to its required
- /// alignment, this offset will align the field correctly.
- ///
- /// @param[out] name
- /// The name of the field as used in materialization.
- ///
- /// @param[in] index
- /// The index of the field about which information is requested.
- ///
- /// @return
- /// True if the information could be retrieved; false otherwise.
- //------------------------------------------------------------------
- bool
- GetStructElement (const clang::NamedDecl *&decl,
- llvm::Value *&value,
- lldb::offset_t &offset,
- ConstString &name,
- uint32_t index);
-
- //------------------------------------------------------------------
- /// [Used by IRForTarget] Get information about a function given its
- /// Decl.
- ///
- /// @param[in] decl
- /// The parsed Decl for the Function, as generated by ClangASTSource
- /// on ClangExpressionDeclMap's behalf.
- ///
- /// @param[out] ptr
- /// The absolute address of the function in the target.
- ///
- /// @return
- /// True if the information could be retrieved; false otherwise.
- //------------------------------------------------------------------
- bool
- GetFunctionInfo (const clang::NamedDecl *decl,
- uint64_t &ptr);
-
- //------------------------------------------------------------------
- /// [Used by IRForTarget] Get the address of a symbol given nothing
- /// but its name.
- ///
- /// @param[in] target
- /// The target to find the symbol in. If not provided,
- /// then the current parsing context's Target.
- ///
- /// @param[in] process
- /// The process to use. For Objective-C symbols, the process's
- /// Objective-C language runtime may be queried if the process
- /// is non-NULL.
- ///
- /// @param[in] name
- /// The name of the symbol.
- ///
- /// @param[in] module
- /// The module to limit the search to. This can be NULL
- ///
- /// @return
- /// Valid load address for the symbol
- //------------------------------------------------------------------
- lldb::addr_t
- GetSymbolAddress (Target &target,
- Process *process,
- const ConstString &name,
- lldb::SymbolType symbol_type,
- Module *module = NULL);
-
- lldb::addr_t
- GetSymbolAddress (const ConstString &name,
- lldb::SymbolType symbol_type);
-
- //------------------------------------------------------------------
- /// [Used by IRInterpreter] Get basic target information.
- ///
- /// @param[out] byte_order
- /// The byte order of the target.
- ///
- /// @param[out] address_byte_size
- /// The size of a pointer in bytes.
- ///
- /// @return
- /// True if the information could be determined; false
- /// otherwise.
- //------------------------------------------------------------------
- struct TargetInfo
- {
- lldb::ByteOrder byte_order;
- size_t address_byte_size;
-
- TargetInfo() :
- byte_order(lldb::eByteOrderInvalid),
- address_byte_size(0)
- {
- }
-
- bool IsValid()
- {
- return (byte_order != lldb::eByteOrderInvalid &&
- address_byte_size != 0);
- }
- };
- TargetInfo GetTargetInfo();
-
- //------------------------------------------------------------------
- /// [Used by ClangASTSource] Find all entities matching a given name,
- /// using a NameSearchContext to make Decls for them.
- ///
- /// @param[in] context
- /// The NameSearchContext that can construct Decls for this name.
- ///
- /// @return
- /// True on success; false otherwise.
- //------------------------------------------------------------------
- void
- FindExternalVisibleDecls(NameSearchContext &context) override;
-
- //------------------------------------------------------------------
- /// Find all entities matching a given name in a given module/namespace,
- /// using a NameSearchContext to make Decls for them.
- ///
- /// @param[in] context
- /// The NameSearchContext that can construct Decls for this name.
- ///
- /// @param[in] module
- /// If non-NULL, the module to query.
- ///
- /// @param[in] namespace_decl
- /// If valid and module is non-NULL, the parent namespace.
- ///
- /// @param[in] name
- /// The name as a plain C string. The NameSearchContext contains
- /// a DeclarationName for the name so at first the name may seem
- /// redundant, but ClangExpressionDeclMap operates in RTTI land so
- /// it can't access DeclarationName.
- ///
- /// @param[in] current_id
- /// The ID for the current FindExternalVisibleDecls invocation,
- /// for logging purposes.
- ///
- /// @return
- /// True on success; false otherwise.
- //------------------------------------------------------------------
- void
- FindExternalVisibleDecls (NameSearchContext &context,
- lldb::ModuleSP module,
- CompilerDeclContext &namespace_decl,
- unsigned int current_id);
-private:
- ExpressionVariableList m_found_entities; ///< All entities that were looked up for the parser.
- ExpressionVariableList m_struct_members; ///< All entities that need to be placed in the struct.
- bool m_keep_result_in_memory; ///< True if result persistent variables generated by this expression should stay in memory.
- Materializer::PersistentVariableDelegate *m_result_delegate; ///< If non-NULL, used to report expression results to ClangUserExpression.
-
- //----------------------------------------------------------------------
- /// The following values should not live beyond parsing
- //----------------------------------------------------------------------
- class ParserVars
- {
- public:
- ParserVars(ClangExpressionDeclMap &decl_map) :
- m_decl_map(decl_map)
- {
- }
-
- Target *
- GetTarget()
- {
- if (m_exe_ctx.GetTargetPtr())
- return m_exe_ctx.GetTargetPtr();
- else if (m_sym_ctx.target_sp)
- m_sym_ctx.target_sp.get();
- return NULL;
- }
-
- ExecutionContext m_exe_ctx; ///< The execution context to use when parsing.
- SymbolContext m_sym_ctx; ///< The symbol context to use in finding variables and types.
- ClangPersistentVariables *m_persistent_vars = nullptr; ///< The persistent variables for the process.
- bool m_enable_lookups = false; ///< Set to true during parsing if we have found the first "$__lldb" name.
- TargetInfo m_target_info; ///< Basic information about the target.
- Materializer *m_materializer = nullptr; ///< If non-NULL, the materializer to use when reporting used variables.
- clang::ASTConsumer *m_code_gen = nullptr; ///< If non-NULL, a code generator that receives new top-level functions.
- private:
- ClangExpressionDeclMap &m_decl_map;
- DISALLOW_COPY_AND_ASSIGN (ParserVars);
- };
-
- std::unique_ptr<ParserVars> m_parser_vars;
-
- //----------------------------------------------------------------------
- /// Activate parser-specific variables
- //----------------------------------------------------------------------
- void
- EnableParserVars()
- {
- if (!m_parser_vars.get())
- m_parser_vars.reset(new ParserVars(*this));
- }
-
- //----------------------------------------------------------------------
- /// Deallocate parser-specific variables
- //----------------------------------------------------------------------
- void
- DisableParserVars()
- {
- m_parser_vars.reset();
- }
-
- //----------------------------------------------------------------------
- /// The following values contain layout information for the materialized
- /// struct, but are not specific to a single materialization
- //----------------------------------------------------------------------
- struct StructVars {
- StructVars() :
- m_struct_alignment(0),
- m_struct_size(0),
- m_struct_laid_out(false),
- m_result_name(),
- m_object_pointer_type(NULL, NULL)
- {
- }
-
- lldb::offset_t m_struct_alignment; ///< The alignment of the struct in bytes.
- size_t m_struct_size; ///< The size of the struct in bytes.
- bool m_struct_laid_out; ///< True if the struct has been laid out and the layout is valid (that is, no new fields have been added since).
- ConstString m_result_name; ///< The name of the result variable ($1, for example)
- TypeFromUser m_object_pointer_type; ///< The type of the "this" variable, if one exists
- };
-
- std::unique_ptr<StructVars> m_struct_vars;
-
- //----------------------------------------------------------------------
- /// Activate struct variables
- //----------------------------------------------------------------------
- void
- EnableStructVars()
- {
- if (!m_struct_vars.get())
- m_struct_vars.reset(new struct StructVars);
- }
-
- //----------------------------------------------------------------------
- /// Deallocate struct variables
- //----------------------------------------------------------------------
- void
- DisableStructVars()
- {
- m_struct_vars.reset();
+ //------------------------------------------------------------------
+ /// Constructor
+ ///
+ /// Initializes class variables.
+ ///
+ /// @param[in] keep_result_in_memory
+ /// If true, inhibits the normal deallocation of the memory for
+ /// the result persistent variable, and instead marks the variable
+ /// as persisting.
+ ///
+ /// @param[in] delegate
+ /// If non-NULL, use this delegate to report result values. This
+ /// allows the client ClangUserExpression to report a result.
+ ///
+ /// @param[in] exe_ctx
+ /// The execution context to use when parsing.
+ //------------------------------------------------------------------
+ ClangExpressionDeclMap(
+ bool keep_result_in_memory,
+ Materializer::PersistentVariableDelegate *result_delegate,
+ ExecutionContext &exe_ctx);
+
+ //------------------------------------------------------------------
+ /// Destructor
+ //------------------------------------------------------------------
+ ~ClangExpressionDeclMap() override;
+
+ //------------------------------------------------------------------
+ /// Enable the state needed for parsing and IR transformation.
+ ///
+ /// @param[in] exe_ctx
+ /// The execution context to use when finding types for variables.
+ /// Also used to find a "scratch" AST context to store result types.
+ ///
+ /// @param[in] materializer
+ /// If non-NULL, the materializer to populate with information about
+ /// the variables to use
+ ///
+ /// @return
+ /// True if parsing is possible; false if it is unsafe to continue.
+ //------------------------------------------------------------------
+ bool WillParse(ExecutionContext &exe_ctx, Materializer *materializer);
+
+ void InstallCodeGenerator(clang::ASTConsumer *code_gen);
+
+ //------------------------------------------------------------------
+ /// [Used by ClangExpressionParser] For each variable that had an unknown
+ /// type at the beginning of parsing, determine its final type now.
+ ///
+ /// @return
+ /// True on success; false otherwise.
+ //------------------------------------------------------------------
+ bool ResolveUnknownTypes();
+
+ //------------------------------------------------------------------
+ /// Disable the state needed for parsing and IR transformation.
+ //------------------------------------------------------------------
+ void DidParse();
+
+ //------------------------------------------------------------------
+ /// [Used by IRForTarget] Add a variable to the list of persistent
+ /// variables for the process.
+ ///
+ /// @param[in] decl
+ /// The Clang declaration for the persistent variable, used for
+ /// lookup during parsing.
+ ///
+ /// @param[in] name
+ /// The name of the persistent variable, usually $something.
+ ///
+ /// @param[in] type
+ /// The type of the variable, in the Clang parser's context.
+ ///
+ /// @return
+ /// True on success; false otherwise.
+ //------------------------------------------------------------------
+ bool AddPersistentVariable(const clang::NamedDecl *decl,
+ const ConstString &name, TypeFromParser type,
+ bool is_result, bool is_lvalue);
+
+ //------------------------------------------------------------------
+ /// [Used by IRForTarget] Add a variable to the struct that needs to
+ /// be materialized each time the expression runs.
+ ///
+ /// @param[in] decl
+ /// The Clang declaration for the variable.
+ ///
+ /// @param[in] name
+ /// The name of the variable.
+ ///
+ /// @param[in] value
+ /// The LLVM IR value for this variable.
+ ///
+ /// @param[in] size
+ /// The size of the variable in bytes.
+ ///
+ /// @param[in] alignment
+ /// The required alignment of the variable in bytes.
+ ///
+ /// @return
+ /// True on success; false otherwise.
+ //------------------------------------------------------------------
+ bool AddValueToStruct(const clang::NamedDecl *decl, const ConstString &name,
+ llvm::Value *value, size_t size,
+ lldb::offset_t alignment);
+
+ //------------------------------------------------------------------
+ /// [Used by IRForTarget] Finalize the struct, laying out the position
+ /// of each object in it.
+ ///
+ /// @return
+ /// True on success; false otherwise.
+ //------------------------------------------------------------------
+ bool DoStructLayout();
+
+ //------------------------------------------------------------------
+ /// [Used by IRForTarget] Get general information about the laid-out
+ /// struct after DoStructLayout() has been called.
+ ///
+ /// @param[out] num_elements
+ /// The number of elements in the struct.
+ ///
+ /// @param[out] size
+ /// The size of the struct, in bytes.
+ ///
+ /// @param[out] alignment
+ /// The alignment of the struct, in bytes.
+ ///
+ /// @return
+ /// True if the information could be retrieved; false otherwise.
+ //------------------------------------------------------------------
+ bool GetStructInfo(uint32_t &num_elements, size_t &size,
+ lldb::offset_t &alignment);
+
+ //------------------------------------------------------------------
+ /// [Used by IRForTarget] Get specific information about one field
+ /// of the laid-out struct after DoStructLayout() has been called.
+ ///
+ /// @param[out] decl
+ /// The parsed Decl for the field, as generated by ClangASTSource
+ /// on ClangExpressionDeclMap's behalf. In the case of the result
+ /// value, this will have the name $__lldb_result even if the
+ /// result value ends up having the name $1. This is an
+ /// implementation detail of IRForTarget.
+ ///
+ /// @param[out] value
+ /// The IR value for the field (usually a GlobalVariable). In
+ /// the case of the result value, this will have the correct
+ /// name ($1, for instance). This is an implementation detail
+ /// of IRForTarget.
+ ///
+ /// @param[out] offset
+ /// The offset of the field from the beginning of the struct.
+ /// As long as the struct is aligned according to its required
+ /// alignment, this offset will align the field correctly.
+ ///
+ /// @param[out] name
+ /// The name of the field as used in materialization.
+ ///
+ /// @param[in] index
+ /// The index of the field about which information is requested.
+ ///
+ /// @return
+ /// True if the information could be retrieved; false otherwise.
+ //------------------------------------------------------------------
+ bool GetStructElement(const clang::NamedDecl *&decl, llvm::Value *&value,
+ lldb::offset_t &offset, ConstString &name,
+ uint32_t index);
+
+ //------------------------------------------------------------------
+ /// [Used by IRForTarget] Get information about a function given its
+ /// Decl.
+ ///
+ /// @param[in] decl
+ /// The parsed Decl for the Function, as generated by ClangASTSource
+ /// on ClangExpressionDeclMap's behalf.
+ ///
+ /// @param[out] ptr
+ /// The absolute address of the function in the target.
+ ///
+ /// @return
+ /// True if the information could be retrieved; false otherwise.
+ //------------------------------------------------------------------
+ bool GetFunctionInfo(const clang::NamedDecl *decl, uint64_t &ptr);
+
+ //------------------------------------------------------------------
+ /// [Used by IRForTarget] Get the address of a symbol given nothing
+ /// but its name.
+ ///
+ /// @param[in] target
+ /// The target to find the symbol in. If not provided,
+ /// then the current parsing context's Target.
+ ///
+ /// @param[in] process
+ /// The process to use. For Objective-C symbols, the process's
+ /// Objective-C language runtime may be queried if the process
+ /// is non-NULL.
+ ///
+ /// @param[in] name
+ /// The name of the symbol.
+ ///
+ /// @param[in] module
+ /// The module to limit the search to. This can be NULL
+ ///
+ /// @return
+ /// Valid load address for the symbol
+ //------------------------------------------------------------------
+ lldb::addr_t GetSymbolAddress(Target &target, Process *process,
+ const ConstString &name,
+ lldb::SymbolType symbol_type,
+ Module *module = NULL);
+
+ lldb::addr_t GetSymbolAddress(const ConstString &name,
+ lldb::SymbolType symbol_type);
+
+ //------------------------------------------------------------------
+ /// [Used by IRInterpreter] Get basic target information.
+ ///
+ /// @param[out] byte_order
+ /// The byte order of the target.
+ ///
+ /// @param[out] address_byte_size
+ /// The size of a pointer in bytes.
+ ///
+ /// @return
+ /// True if the information could be determined; false
+ /// otherwise.
+ //------------------------------------------------------------------
+ struct TargetInfo {
+ lldb::ByteOrder byte_order;
+ size_t address_byte_size;
+
+ TargetInfo() : byte_order(lldb::eByteOrderInvalid), address_byte_size(0) {}
+
+ bool IsValid() {
+ return (byte_order != lldb::eByteOrderInvalid && address_byte_size != 0);
}
-
- //----------------------------------------------------------------------
- /// Get this parser's ID for use in extracting parser- and JIT-specific
- /// data from persistent variables.
- //----------------------------------------------------------------------
- uint64_t
- GetParserID()
- {
- return (uint64_t)this;
+ };
+ TargetInfo GetTargetInfo();
+
+ //------------------------------------------------------------------
+ /// [Used by ClangASTSource] Find all entities matching a given name,
+ /// using a NameSearchContext to make Decls for them.
+ ///
+ /// @param[in] context
+ /// The NameSearchContext that can construct Decls for this name.
+ ///
+ /// @return
+ /// True on success; false otherwise.
+ //------------------------------------------------------------------
+ void FindExternalVisibleDecls(NameSearchContext &context) override;
+
+ //------------------------------------------------------------------
+ /// Find all entities matching a given name in a given module/namespace,
+ /// using a NameSearchContext to make Decls for them.
+ ///
+ /// @param[in] context
+ /// The NameSearchContext that can construct Decls for this name.
+ ///
+ /// @param[in] module
+ /// If non-NULL, the module to query.
+ ///
+ /// @param[in] namespace_decl
+ /// If valid and module is non-NULL, the parent namespace.
+ ///
+ /// @param[in] name
+ /// The name as a plain C string. The NameSearchContext contains
+ /// a DeclarationName for the name so at first the name may seem
+ /// redundant, but ClangExpressionDeclMap operates in RTTI land so
+ /// it can't access DeclarationName.
+ ///
+ /// @param[in] current_id
+ /// The ID for the current FindExternalVisibleDecls invocation,
+ /// for logging purposes.
+ ///
+ /// @return
+ /// True on success; false otherwise.
+ //------------------------------------------------------------------
+ void FindExternalVisibleDecls(NameSearchContext &context,
+ lldb::ModuleSP module,
+ CompilerDeclContext &namespace_decl,
+ unsigned int current_id);
+
+private:
+ ExpressionVariableList
+ m_found_entities; ///< All entities that were looked up for the parser.
+ ExpressionVariableList
+ m_struct_members; ///< All entities that need to be placed in the struct.
+ bool m_keep_result_in_memory; ///< True if result persistent variables
+ ///generated by this expression should stay in
+ ///memory.
+ Materializer::PersistentVariableDelegate
+ *m_result_delegate; ///< If non-NULL, used to report expression results to
+ ///ClangUserExpression.
+
+ //----------------------------------------------------------------------
+ /// The following values should not live beyond parsing
+ //----------------------------------------------------------------------
+ class ParserVars {
+ public:
+ ParserVars(ClangExpressionDeclMap &decl_map) : m_decl_map(decl_map) {}
+
+ Target *GetTarget() {
+ if (m_exe_ctx.GetTargetPtr())
+ return m_exe_ctx.GetTargetPtr();
+ else if (m_sym_ctx.target_sp)
+ m_sym_ctx.target_sp.get();
+ return NULL;
}
-
- //------------------------------------------------------------------
- /// Given a target, find a data symbol that has the given name.
- ///
- /// @param[in] target
- /// The target to use as the basis for the search.
- ///
- /// @param[in] name
- /// The name as a plain C string.
- ///
- /// @param[in] module
- /// The module to limit the search to. This can be NULL
- ///
- /// @return
- /// The LLDB Symbol found, or NULL if none was found.
- //------------------------------------------------------------------
- const Symbol *
- FindGlobalDataSymbol (Target &target,
- const ConstString &name,
- Module *module = NULL);
-
- //------------------------------------------------------------------
- /// Given a target, find a variable that matches the given name and
- /// type.
- ///
- /// @param[in] target
- /// The target to use as a basis for finding the variable.
- ///
- /// @param[in] module
- /// If non-NULL, the module to search.
- ///
- /// @param[in] name
- /// The name as a plain C string.
- ///
- /// @param[in] namespace_decl
- /// If non-NULL and module is non-NULL, the parent namespace.
- ///
- /// @param[in] type
- /// The required type for the variable. This function may be called
- /// during parsing, in which case we don't know its type; hence the
- /// default.
- ///
- /// @return
- /// The LLDB Variable found, or NULL if none was found.
- //------------------------------------------------------------------
- lldb::VariableSP
- FindGlobalVariable (Target &target,
- lldb::ModuleSP &module,
- const ConstString &name,
- CompilerDeclContext *namespace_decl,
- TypeFromUser *type = NULL);
-
- //------------------------------------------------------------------
- /// Get the value of a variable in a given execution context and return
- /// the associated Types if needed.
- ///
- /// @param[in] var
- /// The variable to evaluate.
- ///
- /// @param[out] var_location
- /// The variable location value to fill in
- ///
- /// @param[out] found_type
- /// The type of the found value, as it was found in the user process.
- /// This is only useful when the variable is being inspected on behalf
- /// of the parser, hence the default.
- ///
- /// @param[out] parser_type
- /// The type of the found value, as it was copied into the parser's
- /// AST context. This is only useful when the variable is being
- /// inspected on behalf of the parser, hence the default.
- ///
- /// @param[in] decl
- /// The Decl to be looked up.
- ///
- /// @return
- /// Return true if the value was successfully filled in.
- //------------------------------------------------------------------
- bool
- GetVariableValue (lldb::VariableSP &var,
- lldb_private::Value &var_location,
- TypeFromUser *found_type = NULL,
- TypeFromParser *parser_type = NULL);
-
- //------------------------------------------------------------------
- /// Use the NameSearchContext to generate a Decl for the given LLDB
- /// Variable, and put it in the Tuple list.
- ///
- /// @param[in] context
- /// The NameSearchContext to use when constructing the Decl.
- ///
- /// @param[in] var
- /// The LLDB Variable that needs a Decl.
- ///
- /// @param[in] valobj
- /// The LLDB ValueObject for that variable.
- //------------------------------------------------------------------
- void
- AddOneVariable (NameSearchContext &context,
- lldb::VariableSP var,
- lldb::ValueObjectSP valobj,
- unsigned int current_id);
-
- //------------------------------------------------------------------
- /// Use the NameSearchContext to generate a Decl for the given
- /// persistent variable, and put it in the list of found entities.
- ///
- /// @param[in] context
- /// The NameSearchContext to use when constructing the Decl.
- ///
- /// @param[in] pvar
- /// The persistent variable that needs a Decl.
- ///
- /// @param[in] current_id
- /// The ID of the current invocation of FindExternalVisibleDecls
- /// for logging purposes.
- //------------------------------------------------------------------
- void
- AddOneVariable (NameSearchContext &context,
- lldb::ExpressionVariableSP &pvar_sp,
- unsigned int current_id);
-
- //------------------------------------------------------------------
- /// Use the NameSearchContext to generate a Decl for the given LLDB
- /// symbol (treated as a variable), and put it in the list of found
- /// entities.
- ///
- /// @param[in] context
- /// The NameSearchContext to use when constructing the Decl.
- ///
- /// @param[in] var
- /// The LLDB Variable that needs a Decl.
- //------------------------------------------------------------------
- void
- AddOneGenericVariable (NameSearchContext &context,
- const Symbol &symbol,
- unsigned int current_id);
-
- //------------------------------------------------------------------
- /// Use the NameSearchContext to generate a Decl for the given
- /// function. (Functions are not placed in the Tuple list.) Can
- /// handle both fully typed functions and generic functions.
- ///
- /// @param[in] context
- /// The NameSearchContext to use when constructing the Decl.
- ///
- /// @param[in] fun
- /// The Function that needs to be created. If non-NULL, this is
- /// a fully-typed function.
- ///
- /// @param[in] sym
- /// The Symbol that corresponds to a function that needs to be
- /// created with generic type (unitptr_t foo(...)).
- //------------------------------------------------------------------
- void
- AddOneFunction (NameSearchContext &context,
- Function *fun,
- Symbol *sym,
- unsigned int current_id);
-
- //------------------------------------------------------------------
- /// Use the NameSearchContext to generate a Decl for the given
- /// register.
- ///
- /// @param[in] context
- /// The NameSearchContext to use when constructing the Decl.
- ///
- /// @param[in] reg_info
- /// The information corresponding to that register.
- //------------------------------------------------------------------
- void
- AddOneRegister (NameSearchContext &context,
- const RegisterInfo *reg_info,
- unsigned int current_id);
-
- //------------------------------------------------------------------
- /// Use the NameSearchContext to generate a Decl for the given
- /// type. (Types are not placed in the Tuple list.)
- ///
- /// @param[in] context
- /// The NameSearchContext to use when constructing the Decl.
- ///
- /// @param[in] type
- /// The type that needs to be created.
- //------------------------------------------------------------------
- void
- AddOneType (NameSearchContext &context,
- TypeFromUser &type,
- unsigned int current_id);
-
- //------------------------------------------------------------------
- /// Generate a Decl for "*this" and add a member function declaration
- /// to it for the expression, then report it.
- ///
- /// @param[in] context
- /// The NameSearchContext to use when constructing the Decl.
- ///
- /// @param[in] type
- /// The type for *this.
- //------------------------------------------------------------------
- void
- AddThisType(NameSearchContext &context,
- TypeFromUser &type,
- unsigned int current_id);
-
- ClangASTContext *
- GetClangASTContext();
+
+ ExecutionContext m_exe_ctx; ///< The execution context to use when parsing.
+ SymbolContext m_sym_ctx; ///< The symbol context to use in finding variables
+ ///and types.
+ ClangPersistentVariables *m_persistent_vars =
+ nullptr; ///< The persistent variables for the process.
+ bool m_enable_lookups = false; ///< Set to true during parsing if we have
+ ///found the first "$__lldb" name.
+ TargetInfo m_target_info; ///< Basic information about the target.
+ Materializer *m_materializer = nullptr; ///< If non-NULL, the materializer
+ ///to use when reporting used
+ ///variables.
+ clang::ASTConsumer *m_code_gen = nullptr; ///< If non-NULL, a code generator
+ ///that receives new top-level
+ ///functions.
+ private:
+ ClangExpressionDeclMap &m_decl_map;
+ DISALLOW_COPY_AND_ASSIGN(ParserVars);
+ };
+
+ std::unique_ptr<ParserVars> m_parser_vars;
+
+ //----------------------------------------------------------------------
+ /// Activate parser-specific variables
+ //----------------------------------------------------------------------
+ void EnableParserVars() {
+ if (!m_parser_vars.get())
+ m_parser_vars.reset(new ParserVars(*this));
+ }
+
+ //----------------------------------------------------------------------
+ /// Deallocate parser-specific variables
+ //----------------------------------------------------------------------
+ void DisableParserVars() { m_parser_vars.reset(); }
+
+ //----------------------------------------------------------------------
+ /// The following values contain layout information for the materialized
+ /// struct, but are not specific to a single materialization
+ //----------------------------------------------------------------------
+ struct StructVars {
+ StructVars()
+ : m_struct_alignment(0), m_struct_size(0), m_struct_laid_out(false),
+ m_result_name(), m_object_pointer_type(NULL, NULL) {}
+
+ lldb::offset_t
+ m_struct_alignment; ///< The alignment of the struct in bytes.
+ size_t m_struct_size; ///< The size of the struct in bytes.
+ bool m_struct_laid_out; ///< True if the struct has been laid out and the
+ ///layout is valid (that is, no new fields have been
+ ///added since).
+ ConstString
+ m_result_name; ///< The name of the result variable ($1, for example)
+ TypeFromUser m_object_pointer_type; ///< The type of the "this" variable, if
+ ///one exists
+ };
+
+ std::unique_ptr<StructVars> m_struct_vars;
+
+ //----------------------------------------------------------------------
+ /// Activate struct variables
+ //----------------------------------------------------------------------
+ void EnableStructVars() {
+ if (!m_struct_vars.get())
+ m_struct_vars.reset(new struct StructVars);
+ }
+
+ //----------------------------------------------------------------------
+ /// Deallocate struct variables
+ //----------------------------------------------------------------------
+ void DisableStructVars() { m_struct_vars.reset(); }
+
+ //----------------------------------------------------------------------
+ /// Get this parser's ID for use in extracting parser- and JIT-specific
+ /// data from persistent variables.
+ //----------------------------------------------------------------------
+ uint64_t GetParserID() { return (uint64_t) this; }
+
+ //------------------------------------------------------------------
+ /// Given a target, find a data symbol that has the given name.
+ ///
+ /// @param[in] target
+ /// The target to use as the basis for the search.
+ ///
+ /// @param[in] name
+ /// The name as a plain C string.
+ ///
+ /// @param[in] module
+ /// The module to limit the search to. This can be NULL
+ ///
+ /// @return
+ /// The LLDB Symbol found, or NULL if none was found.
+ //------------------------------------------------------------------
+ const Symbol *FindGlobalDataSymbol(Target &target, const ConstString &name,
+ Module *module = NULL);
+
+ //------------------------------------------------------------------
+ /// Given a target, find a variable that matches the given name and
+ /// type.
+ ///
+ /// @param[in] target
+ /// The target to use as a basis for finding the variable.
+ ///
+ /// @param[in] module
+ /// If non-NULL, the module to search.
+ ///
+ /// @param[in] name
+ /// The name as a plain C string.
+ ///
+ /// @param[in] namespace_decl
+ /// If non-NULL and module is non-NULL, the parent namespace.
+ ///
+ /// @param[in] type
+ /// The required type for the variable. This function may be called
+ /// during parsing, in which case we don't know its type; hence the
+ /// default.
+ ///
+ /// @return
+ /// The LLDB Variable found, or NULL if none was found.
+ //------------------------------------------------------------------
+ lldb::VariableSP FindGlobalVariable(Target &target, lldb::ModuleSP &module,
+ const ConstString &name,
+ CompilerDeclContext *namespace_decl,
+ TypeFromUser *type = NULL);
+
+ //------------------------------------------------------------------
+ /// Get the value of a variable in a given execution context and return
+ /// the associated Types if needed.
+ ///
+ /// @param[in] var
+ /// The variable to evaluate.
+ ///
+ /// @param[out] var_location
+ /// The variable location value to fill in
+ ///
+ /// @param[out] found_type
+ /// The type of the found value, as it was found in the user process.
+ /// This is only useful when the variable is being inspected on behalf
+ /// of the parser, hence the default.
+ ///
+ /// @param[out] parser_type
+ /// The type of the found value, as it was copied into the parser's
+ /// AST context. This is only useful when the variable is being
+ /// inspected on behalf of the parser, hence the default.
+ ///
+ /// @param[in] decl
+ /// The Decl to be looked up.
+ ///
+ /// @return
+ /// Return true if the value was successfully filled in.
+ //------------------------------------------------------------------
+ bool GetVariableValue(lldb::VariableSP &var,
+ lldb_private::Value &var_location,
+ TypeFromUser *found_type = NULL,
+ TypeFromParser *parser_type = NULL);
+
+ //------------------------------------------------------------------
+ /// Use the NameSearchContext to generate a Decl for the given LLDB
+ /// Variable, and put it in the Tuple list.
+ ///
+ /// @param[in] context
+ /// The NameSearchContext to use when constructing the Decl.
+ ///
+ /// @param[in] var
+ /// The LLDB Variable that needs a Decl.
+ ///
+ /// @param[in] valobj
+ /// The LLDB ValueObject for that variable.
+ //------------------------------------------------------------------
+ void AddOneVariable(NameSearchContext &context, lldb::VariableSP var,
+ lldb::ValueObjectSP valobj, unsigned int current_id);
+
+ //------------------------------------------------------------------
+ /// Use the NameSearchContext to generate a Decl for the given
+ /// persistent variable, and put it in the list of found entities.
+ ///
+ /// @param[in] context
+ /// The NameSearchContext to use when constructing the Decl.
+ ///
+ /// @param[in] pvar
+ /// The persistent variable that needs a Decl.
+ ///
+ /// @param[in] current_id
+ /// The ID of the current invocation of FindExternalVisibleDecls
+ /// for logging purposes.
+ //------------------------------------------------------------------
+ void AddOneVariable(NameSearchContext &context,
+ lldb::ExpressionVariableSP &pvar_sp,
+ unsigned int current_id);
+
+ //------------------------------------------------------------------
+ /// Use the NameSearchContext to generate a Decl for the given LLDB
+ /// symbol (treated as a variable), and put it in the list of found
+ /// entities.
+ ///
+ /// @param[in] context
+ /// The NameSearchContext to use when constructing the Decl.
+ ///
+ /// @param[in] var
+ /// The LLDB Variable that needs a Decl.
+ //------------------------------------------------------------------
+ void AddOneGenericVariable(NameSearchContext &context, const Symbol &symbol,
+ unsigned int current_id);
+
+ //------------------------------------------------------------------
+ /// Use the NameSearchContext to generate a Decl for the given
+ /// function. (Functions are not placed in the Tuple list.) Can
+ /// handle both fully typed functions and generic functions.
+ ///
+ /// @param[in] context
+ /// The NameSearchContext to use when constructing the Decl.
+ ///
+ /// @param[in] fun
+ /// The Function that needs to be created. If non-NULL, this is
+ /// a fully-typed function.
+ ///
+ /// @param[in] sym
+ /// The Symbol that corresponds to a function that needs to be
+ /// created with generic type (unitptr_t foo(...)).
+ //------------------------------------------------------------------
+ void AddOneFunction(NameSearchContext &context, Function *fun, Symbol *sym,
+ unsigned int current_id);
+
+ //------------------------------------------------------------------
+ /// Use the NameSearchContext to generate a Decl for the given
+ /// register.
+ ///
+ /// @param[in] context
+ /// The NameSearchContext to use when constructing the Decl.
+ ///
+ /// @param[in] reg_info
+ /// The information corresponding to that register.
+ //------------------------------------------------------------------
+ void AddOneRegister(NameSearchContext &context, const RegisterInfo *reg_info,
+ unsigned int current_id);
+
+ //------------------------------------------------------------------
+ /// Use the NameSearchContext to generate a Decl for the given
+ /// type. (Types are not placed in the Tuple list.)
+ ///
+ /// @param[in] context
+ /// The NameSearchContext to use when constructing the Decl.
+ ///
+ /// @param[in] type
+ /// The type that needs to be created.
+ //------------------------------------------------------------------
+ void AddOneType(NameSearchContext &context, TypeFromUser &type,
+ unsigned int current_id);
+
+ //------------------------------------------------------------------
+ /// Generate a Decl for "*this" and add a member function declaration
+ /// to it for the expression, then report it.
+ ///
+ /// @param[in] context
+ /// The NameSearchContext to use when constructing the Decl.
+ ///
+ /// @param[in] type
+ /// The type for *this.
+ //------------------------------------------------------------------
+ void AddThisType(NameSearchContext &context, TypeFromUser &type,
+ unsigned int current_id);
+
+ ClangASTContext *GetClangASTContext();
};
-
+
} // namespace lldb_private
#endif // liblldb_ClangExpressionDeclMap_h_
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionHelper.h b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionHelper.h
index bcd30ec4af2..4562bf9a67b 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionHelper.h
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionHelper.h
@@ -12,17 +12,17 @@
// C Includes
// C++ Includes
-#include <string>
#include <map>
+#include <string>
#include <vector>
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-forward.h"
-#include "lldb/lldb-private.h"
#include "lldb/Core/ClangForward.h"
#include "lldb/Expression/ExpressionTypeSystemHelper.h"
+#include "lldb/lldb-forward.h"
+#include "lldb/lldb-private.h"
namespace lldb_private {
@@ -31,52 +31,43 @@ class RecordingMemoryManager;
//----------------------------------------------------------------------
// ClangExpressionHelper
//----------------------------------------------------------------------
-class ClangExpressionHelper : public ExpressionTypeSystemHelper
-{
+class ClangExpressionHelper : public ExpressionTypeSystemHelper {
public:
- static bool classof(const ExpressionTypeSystemHelper *ts)
- {
- return ts->getKind() == eKindClangHelper;
- }
+ static bool classof(const ExpressionTypeSystemHelper *ts) {
+ return ts->getKind() == eKindClangHelper;
+ }
+
+ ClangExpressionHelper()
+ : ExpressionTypeSystemHelper(
+ ExpressionTypeSystemHelper::LLVMCastKind::eKindClangHelper) {}
+
+ //------------------------------------------------------------------
+ /// Destructor
+ //------------------------------------------------------------------
+ virtual ~ClangExpressionHelper() {}
- ClangExpressionHelper () :
- ExpressionTypeSystemHelper(ExpressionTypeSystemHelper::LLVMCastKind::eKindClangHelper)
- {
- }
+ //------------------------------------------------------------------
+ /// Return the object that the parser should use when resolving external
+ /// values. May be NULL if everything should be self-contained.
+ //------------------------------------------------------------------
+ virtual ClangExpressionDeclMap *DeclMap() = 0;
- //------------------------------------------------------------------
- /// Destructor
- //------------------------------------------------------------------
- virtual ~ClangExpressionHelper ()
- {
- }
-
- //------------------------------------------------------------------
- /// Return the object that the parser should use when resolving external
- /// values. May be NULL if everything should be self-contained.
- //------------------------------------------------------------------
- virtual ClangExpressionDeclMap *
- DeclMap () = 0;
-
- //------------------------------------------------------------------
- /// Return the object that the parser should allow to access ASTs.
- /// May be NULL if the ASTs do not need to be transformed.
- ///
- /// @param[in] passthrough
- /// The ASTConsumer that the returned transformer should send
- /// the ASTs to after transformation.
- //------------------------------------------------------------------
- virtual clang::ASTConsumer *
- ASTTransformer(clang::ASTConsumer *passthrough) = 0;
+ //------------------------------------------------------------------
+ /// Return the object that the parser should allow to access ASTs.
+ /// May be NULL if the ASTs do not need to be transformed.
+ ///
+ /// @param[in] passthrough
+ /// The ASTConsumer that the returned transformer should send
+ /// the ASTs to after transformation.
+ //------------------------------------------------------------------
+ virtual clang::ASTConsumer *
+ ASTTransformer(clang::ASTConsumer *passthrough) = 0;
- virtual void
- CommitPersistentDecls()
- {
- }
+ virtual void CommitPersistentDecls() {}
protected:
};
} // namespace lldb_private
-#endif // liblldb_ClangExpression_h_
+#endif // liblldb_ClangExpression_h_
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
index 6a27cd3ef3f..95efb5c76c8 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
@@ -17,12 +17,12 @@
#include "clang/Basic/FileManager.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/TargetInfo.h"
-#include "clang/Basic/Version.h"
+#include "clang/Basic/Version.h"
#include "clang/CodeGen/CodeGenAction.h"
#include "clang/CodeGen/ModuleBuilder.h"
#include "clang/Edit/Commit.h"
-#include "clang/Edit/EditsReceiver.h"
#include "clang/Edit/EditedSource.h"
+#include "clang/Edit/EditsReceiver.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/CompilerInvocation.h"
#include "clang/Frontend/FrontendActions.h"
@@ -32,8 +32,8 @@
#include "clang/Frontend/TextDiagnosticPrinter.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Parse/ParseAST.h"
-#include "clang/Rewrite/Frontend/FrontendActions.h"
#include "clang/Rewrite/Core/Rewriter.h"
+#include "clang/Rewrite/Frontend/FrontendActions.h"
#include "clang/Sema/SemaConsumer.h"
#include "clang/StaticAnalyzer/Frontend/FrontendActions.h"
@@ -50,19 +50,19 @@
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/DynamicLibrary.h"
+#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Host.h"
+#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Signals.h"
// Project includes
-#include "ClangExpressionParser.h"
#include "ClangDiagnostic.h"
+#include "ClangExpressionParser.h"
#include "ClangASTSource.h"
-#include "ClangExpressionHelper.h"
#include "ClangExpressionDeclMap.h"
+#include "ClangExpressionHelper.h"
#include "ClangModulesDeclVendor.h"
#include "ClangPersistentVariables.h"
#include "IRForTarget.h"
@@ -100,931 +100,888 @@ using namespace lldb_private;
// Utility Methods for Clang
//===----------------------------------------------------------------------===//
-
-class ClangExpressionParser::LLDBPreprocessorCallbacks : public PPCallbacks
-{
- ClangModulesDeclVendor &m_decl_vendor;
- ClangPersistentVariables &m_persistent_vars;
- StreamString m_error_stream;
- bool m_has_errors = false;
+class ClangExpressionParser::LLDBPreprocessorCallbacks : public PPCallbacks {
+ ClangModulesDeclVendor &m_decl_vendor;
+ ClangPersistentVariables &m_persistent_vars;
+ StreamString m_error_stream;
+ bool m_has_errors = false;
public:
- LLDBPreprocessorCallbacks(ClangModulesDeclVendor &decl_vendor,
- ClangPersistentVariables &persistent_vars) :
- m_decl_vendor(decl_vendor),
- m_persistent_vars(persistent_vars)
- {
- }
-
- void
- moduleImport(SourceLocation import_location,
- clang::ModuleIdPath path,
- const clang::Module * /*null*/) override
- {
- std::vector<ConstString> string_path;
-
- for (const std::pair<IdentifierInfo *, SourceLocation> &component : path)
- {
- string_path.push_back(ConstString(component.first->getName()));
- }
-
- StreamString error_stream;
-
- ClangModulesDeclVendor::ModuleVector exported_modules;
-
- if (!m_decl_vendor.AddModule(string_path, &exported_modules, m_error_stream))
- {
- m_has_errors = true;
- }
-
- for (ClangModulesDeclVendor::ModuleID module : exported_modules)
- {
- m_persistent_vars.AddHandLoadedClangModule(module);
- }
- }
-
- bool hasErrors()
- {
- return m_has_errors;
- }
-
- const std::string &getErrorString()
- {
- return m_error_stream.GetString();
- }
-};
+ LLDBPreprocessorCallbacks(ClangModulesDeclVendor &decl_vendor,
+ ClangPersistentVariables &persistent_vars)
+ : m_decl_vendor(decl_vendor), m_persistent_vars(persistent_vars) {}
-class ClangDiagnosticManagerAdapter : public clang::DiagnosticConsumer
-{
-public:
- ClangDiagnosticManagerAdapter() : m_passthrough(new clang::TextDiagnosticBuffer) {}
+ void moduleImport(SourceLocation import_location, clang::ModuleIdPath path,
+ const clang::Module * /*null*/) override {
+ std::vector<ConstString> string_path;
- ClangDiagnosticManagerAdapter(const std::shared_ptr<clang::TextDiagnosticBuffer> &passthrough)
- : m_passthrough(passthrough)
- {
+ for (const std::pair<IdentifierInfo *, SourceLocation> &component : path) {
+ string_path.push_back(ConstString(component.first->getName()));
}
- void
- ResetManager(DiagnosticManager *manager = nullptr)
- {
- m_manager = manager;
- }
+ StreamString error_stream;
- void
- HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, const clang::Diagnostic &Info)
- {
- if (m_manager)
- {
- llvm::SmallVector<char, 32> diag_str;
- Info.FormatDiagnostic(diag_str);
- diag_str.push_back('\0');
- const char *data = diag_str.data();
-
- lldb_private::DiagnosticSeverity severity;
- bool make_new_diagnostic = true;
-
- switch (DiagLevel)
- {
- case DiagnosticsEngine::Level::Fatal:
- case DiagnosticsEngine::Level::Error:
- severity = eDiagnosticSeverityError;
- break;
- case DiagnosticsEngine::Level::Warning:
- severity = eDiagnosticSeverityWarning;
- break;
- case DiagnosticsEngine::Level::Remark:
- case DiagnosticsEngine::Level::Ignored:
- severity = eDiagnosticSeverityRemark;
- break;
- case DiagnosticsEngine::Level::Note:
- m_manager->AppendMessageToDiagnostic(data);
- make_new_diagnostic = false;
- }
- if (make_new_diagnostic)
- {
- ClangDiagnostic *new_diagnostic = new ClangDiagnostic(data, severity, Info.getID());
- m_manager->AddDiagnostic(new_diagnostic);
-
- // Don't store away warning fixits, since the compiler doesn't have enough
- // context in an expression for the warning to be useful.
- // FIXME: Should we try to filter out FixIts that apply to our generated
- // code, and not the user's expression?
- if (severity == eDiagnosticSeverityError)
- {
- size_t num_fixit_hints = Info.getNumFixItHints();
- for (size_t i = 0; i < num_fixit_hints; i++)
- {
- const clang::FixItHint &fixit = Info.getFixItHint(i);
- if (!fixit.isNull())
- new_diagnostic->AddFixitHint(fixit);
- }
- }
- }
- }
-
- m_passthrough->HandleDiagnostic(DiagLevel, Info);
- }
+ ClangModulesDeclVendor::ModuleVector exported_modules;
- void
- FlushDiagnostics(DiagnosticsEngine &Diags)
- {
- m_passthrough->FlushDiagnostics(Diags);
+ if (!m_decl_vendor.AddModule(string_path, &exported_modules,
+ m_error_stream)) {
+ m_has_errors = true;
}
- DiagnosticConsumer *
- clone(DiagnosticsEngine &Diags) const
- {
- return new ClangDiagnosticManagerAdapter(m_passthrough);
+ for (ClangModulesDeclVendor::ModuleID module : exported_modules) {
+ m_persistent_vars.AddHandLoadedClangModule(module);
}
+ }
- clang::TextDiagnosticBuffer *
- GetPassthrough()
- {
- return m_passthrough.get();
- }
+ bool hasErrors() { return m_has_errors; }
-private:
- DiagnosticManager *m_manager = nullptr;
- std::shared_ptr<clang::TextDiagnosticBuffer> m_passthrough;
+ const std::string &getErrorString() { return m_error_stream.GetString(); }
};
-//===----------------------------------------------------------------------===//
-// Implementation of ClangExpressionParser
-//===----------------------------------------------------------------------===//
-
-ClangExpressionParser::ClangExpressionParser (ExecutionContextScope *exe_scope,
- Expression &expr,
- bool generate_debug_info) :
- ExpressionParser (exe_scope, expr, generate_debug_info),
- m_compiler (),
- m_code_generator (),
- m_pp_callbacks(nullptr)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
- // We can't compile expressions without a target. So if the exe_scope is null or doesn't have a target,
- // then we just need to get out of here. I'll lldb_assert and not make any of the compiler objects since
- // I can't return errors directly from the constructor. Further calls will check if the compiler was made and
- // bag out if it wasn't.
-
- if (!exe_scope)
- {
- lldb_assert(exe_scope, "Can't make an expression parser with a null scope.", __FUNCTION__, __FILE__, __LINE__);
- return;
- }
-
- lldb::TargetSP target_sp;
- target_sp = exe_scope->CalculateTarget();
- if (!target_sp)
- {
- lldb_assert(target_sp.get(), "Can't make an expression parser with a null target.", __FUNCTION__, __FILE__, __LINE__);
- return;
- }
-
- // 1. Create a new compiler instance.
- m_compiler.reset(new CompilerInstance());
- lldb::LanguageType frame_lang = expr.Language(); // defaults to lldb::eLanguageTypeUnknown
- bool overridden_target_opts = false;
- lldb_private::LanguageRuntime *lang_rt = nullptr;
-
- std::string abi;
- ArchSpec target_arch;
- target_arch = target_sp->GetArchitecture();
-
- const auto target_machine = target_arch.GetMachine();
-
- // If the expression is being evaluated in the context of an existing
- // stack frame, we introspect to see if the language runtime is available.
-
- lldb::StackFrameSP frame_sp = exe_scope->CalculateStackFrame();
- lldb::ProcessSP process_sp = exe_scope->CalculateProcess();
-
- // Make sure the user hasn't provided a preferred execution language
- // with `expression --language X -- ...`
- if (frame_sp && frame_lang == lldb::eLanguageTypeUnknown)
- frame_lang = frame_sp->GetLanguage();
-
- if (process_sp && frame_lang != lldb::eLanguageTypeUnknown)
- {
- lang_rt = process_sp->GetLanguageRuntime(frame_lang);
- if (log)
- log->Printf("Frame has language of type %s", Language::GetNameForLanguageType(frame_lang));
- }
-
- // 2. Configure the compiler with a set of default options that are appropriate
- // for most situations.
- if (target_arch.IsValid())
- {
- std::string triple = target_arch.GetTriple().str();
- m_compiler->getTargetOpts().Triple = triple;
- if (log)
- log->Printf("Using %s as the target triple", m_compiler->getTargetOpts().Triple.c_str());
- }
- else
- {
- // If we get here we don't have a valid target and just have to guess.
- // Sometimes this will be ok to just use the host target triple (when we evaluate say "2+3", but other
- // expressions like breakpoint conditions and other things that _are_ target specific really shouldn't just be
- // using the host triple. In such a case the language runtime should expose an overridden options set (3),
- // below.
- m_compiler->getTargetOpts().Triple = llvm::sys::getDefaultTargetTriple();
- if (log)
- log->Printf("Using default target triple of %s", m_compiler->getTargetOpts().Triple.c_str());
- }
- // Now add some special fixes for known architectures:
- // 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";
- }
- // Supported subsets of x86
- if (target_machine == llvm::Triple::x86 ||
- target_machine == llvm::Triple::x86_64)
- {
- m_compiler->getTargetOpts().Features.push_back("+sse");
- m_compiler->getTargetOpts().Features.push_back("+sse2");
- }
-
- // Set the target CPU to generate code for.
- // This will be empty for any CPU that doesn't really need to make a special CPU string.
- m_compiler->getTargetOpts().CPU = target_arch.GetClangTargetCPU();
-
- // Set the target ABI
- abi = GetClangTargetABI(target_arch);
- if (!abi.empty())
- m_compiler->getTargetOpts().ABI = abi;
-
- // 3. Now allow the runtime to provide custom configuration options for the target.
- // In this case, a specialized language runtime is available and we can query it for extra options.
- // For 99% of use cases, this will not be needed and should be provided when basic platform detection is not enough.
- if (lang_rt)
- overridden_target_opts = lang_rt->GetOverrideExprOptions(m_compiler->getTargetOpts());
-
- if (overridden_target_opts)
- if (log)
- {
- log->Debug("Using overridden target options for the expression evaluation");
-
- auto opts = m_compiler->getTargetOpts();
- log->Debug("Triple: '%s'", opts.Triple.c_str());
- log->Debug("CPU: '%s'", opts.CPU.c_str());
- log->Debug("FPMath: '%s'", opts.FPMath.c_str());
- log->Debug("ABI: '%s'", opts.ABI.c_str());
- log->Debug("LinkerVersion: '%s'", opts.LinkerVersion.c_str());
- StringList::LogDump(log, opts.FeaturesAsWritten, "FeaturesAsWritten");
- StringList::LogDump(log, opts.Features, "Features");
- StringList::LogDump(log, opts.Reciprocals, "Reciprocals");
- }
-
- // 4. Create and install the target on the compiler.
- m_compiler->createDiagnostics();
- auto target_info = TargetInfo::CreateTargetInfo(m_compiler->getDiagnostics(), m_compiler->getInvocation().TargetOpts);
- if (log)
- {
- log->Printf("Using SIMD alignment: %d", target_info->getSimdDefaultAlign());
- log->Printf("Target datalayout string: '%s'", target_info->getDataLayout().getStringRepresentation().c_str());
- log->Printf("Target ABI: '%s'", target_info->getABI().str().c_str());
- log->Printf("Target vector alignment: %d", target_info->getMaxVectorAlign());
- }
- m_compiler->setTarget(target_info);
-
- assert (m_compiler->hasTarget());
-
- // 5. Set language options.
- lldb::LanguageType language = expr.Language();
-
- switch (language)
- {
- case lldb::eLanguageTypeC:
- case lldb::eLanguageTypeC89:
- case lldb::eLanguageTypeC99:
- case lldb::eLanguageTypeC11:
- // FIXME: the following language option is a temporary workaround,
- // to "ask for C, get C++."
- // For now, the expression parser must use C++ anytime the
- // language is a C family language, because the expression parser
- // uses features of C++ to capture values.
- m_compiler->getLangOpts().CPlusPlus = true;
+class ClangDiagnosticManagerAdapter : public clang::DiagnosticConsumer {
+public:
+ ClangDiagnosticManagerAdapter()
+ : m_passthrough(new clang::TextDiagnosticBuffer) {}
+
+ ClangDiagnosticManagerAdapter(
+ const std::shared_ptr<clang::TextDiagnosticBuffer> &passthrough)
+ : m_passthrough(passthrough) {}
+
+ void ResetManager(DiagnosticManager *manager = nullptr) {
+ m_manager = manager;
+ }
+
+ void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
+ const clang::Diagnostic &Info) {
+ if (m_manager) {
+ llvm::SmallVector<char, 32> diag_str;
+ Info.FormatDiagnostic(diag_str);
+ diag_str.push_back('\0');
+ const char *data = diag_str.data();
+
+ lldb_private::DiagnosticSeverity severity;
+ bool make_new_diagnostic = true;
+
+ switch (DiagLevel) {
+ case DiagnosticsEngine::Level::Fatal:
+ case DiagnosticsEngine::Level::Error:
+ severity = eDiagnosticSeverityError;
break;
- case lldb::eLanguageTypeObjC:
- m_compiler->getLangOpts().ObjC1 = true;
- m_compiler->getLangOpts().ObjC2 = true;
- // FIXME: the following language option is a temporary workaround,
- // to "ask for ObjC, get ObjC++" (see comment above).
- m_compiler->getLangOpts().CPlusPlus = true;
+ case DiagnosticsEngine::Level::Warning:
+ severity = eDiagnosticSeverityWarning;
break;
- case lldb::eLanguageTypeC_plus_plus:
- case lldb::eLanguageTypeC_plus_plus_11:
- case lldb::eLanguageTypeC_plus_plus_14:
- m_compiler->getLangOpts().CPlusPlus11 = true;
- m_compiler->getHeaderSearchOpts().UseLibcxx = true;
- LLVM_FALLTHROUGH;
- case lldb::eLanguageTypeC_plus_plus_03:
- m_compiler->getLangOpts().CPlusPlus = true;
- // FIXME: the following language option is a temporary workaround,
- // to "ask for C++, get ObjC++". Apple hopes to remove this requirement
- // on non-Apple platforms, but for now it is needed.
- m_compiler->getLangOpts().ObjC1 = true;
- break;
- case lldb::eLanguageTypeObjC_plus_plus:
- case lldb::eLanguageTypeUnknown:
- default:
- m_compiler->getLangOpts().ObjC1 = true;
- m_compiler->getLangOpts().ObjC2 = true;
- m_compiler->getLangOpts().CPlusPlus = true;
- m_compiler->getLangOpts().CPlusPlus11 = true;
- m_compiler->getHeaderSearchOpts().UseLibcxx = true;
+ case DiagnosticsEngine::Level::Remark:
+ case DiagnosticsEngine::Level::Ignored:
+ severity = eDiagnosticSeverityRemark;
break;
+ case DiagnosticsEngine::Level::Note:
+ m_manager->AppendMessageToDiagnostic(data);
+ make_new_diagnostic = false;
+ }
+ if (make_new_diagnostic) {
+ ClangDiagnostic *new_diagnostic =
+ new ClangDiagnostic(data, severity, Info.getID());
+ m_manager->AddDiagnostic(new_diagnostic);
+
+ // Don't store away warning fixits, since the compiler doesn't have
+ // enough
+ // context in an expression for the warning to be useful.
+ // FIXME: Should we try to filter out FixIts that apply to our generated
+ // code, and not the user's expression?
+ if (severity == eDiagnosticSeverityError) {
+ size_t num_fixit_hints = Info.getNumFixItHints();
+ for (size_t i = 0; i < num_fixit_hints; i++) {
+ const clang::FixItHint &fixit = Info.getFixItHint(i);
+ if (!fixit.isNull())
+ new_diagnostic->AddFixitHint(fixit);
+ }
+ }
+ }
}
- 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() == Expression::eResultTypeId)
- m_compiler->getLangOpts().DebuggerCastResultToId = true;
-
- m_compiler->getLangOpts().CharIsSigned =
- ArchSpec(m_compiler->getTargetOpts().Triple.c_str()).CharIsSignedByDefault();
-
- // 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;
-
- if (process_sp && m_compiler->getLangOpts().ObjC1)
- {
- if (process_sp->GetObjCLanguageRuntime())
- {
- if (process_sp->GetObjCLanguageRuntime()->GetRuntimeVersion() == ObjCLanguageRuntime::ObjCRuntimeVersions::eAppleObjC_V2)
- m_compiler->getLangOpts().ObjCRuntime.set(ObjCRuntime::MacOSX, VersionTuple(10, 7));
- else
- m_compiler->getLangOpts().ObjCRuntime.set(ObjCRuntime::FragileMacOSX, VersionTuple(10, 7));
+ m_passthrough->HandleDiagnostic(DiagLevel, Info);
+ }
- if (process_sp->GetObjCLanguageRuntime()->HasNewLiteralsAndIndexing())
- m_compiler->getLangOpts().DebuggerObjCLiteral = true;
- }
- }
+ void FlushDiagnostics(DiagnosticsEngine &Diags) {
+ m_passthrough->FlushDiagnostics(Diags);
+ }
- 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().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().adjust(m_compiler->getLangOpts());
-
- // 6. Set up the diagnostic buffer for reporting errors
-
- m_compiler->getDiagnostics().setClient(new ClangDiagnosticManagerAdapter);
-
- // 7. 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(TU_Complete);
-
- if (ClangModulesDeclVendor *decl_vendor = target_sp->GetClangModulesDeclVendor())
- {
- ClangPersistentVariables *clang_persistent_vars = llvm::cast<ClangPersistentVariables>(target_sp->GetPersistentExpressionStateForLanguage(lldb::eLanguageTypeC));
- std::unique_ptr<PPCallbacks> pp_callbacks(new LLDBPreprocessorCallbacks(*decl_vendor, *clang_persistent_vars));
- m_pp_callbacks = static_cast<LLDBPreprocessorCallbacks*>(pp_callbacks.get());
- m_compiler->getPreprocessor().addPPCallbacks(std::move(pp_callbacks));
- }
-
- // 8. 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->getPreprocessor().getIdentifierTable(),
- *m_selector_table.get(),
- *m_builtin_context.get()));
-
- ast_context->InitBuiltinTypes(m_compiler->getTarget());
-
- ClangExpressionHelper *type_system_helper = dyn_cast<ClangExpressionHelper>(m_expr.GetTypeSystemHelper());
- ClangExpressionDeclMap *decl_map = type_system_helper->DeclMap();
-
- if (decl_map)
- {
- llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> ast_source(decl_map->CreateProxy());
- decl_map->InstallASTContext(ast_context.get());
- ast_context->setExternalSource(ast_source);
- }
+ DiagnosticConsumer *clone(DiagnosticsEngine &Diags) const {
+ return new ClangDiagnosticManagerAdapter(m_passthrough);
+ }
- m_ast_context.reset(new ClangASTContext(m_compiler->getTargetOpts().Triple.c_str()));
- m_ast_context->setASTContext(ast_context.get());
- m_compiler->setASTContext(ast_context.release());
+ clang::TextDiagnosticBuffer *GetPassthrough() { return m_passthrough.get(); }
- std::string module_name("$__lldb_module");
+private:
+ DiagnosticManager *m_manager = nullptr;
+ std::shared_ptr<clang::TextDiagnosticBuffer> m_passthrough;
+};
- m_llvm_context.reset(new LLVMContext());
- m_code_generator.reset(CreateLLVMCodeGen(m_compiler->getDiagnostics(),
- module_name,
- m_compiler->getHeaderSearchOpts(),
- m_compiler->getPreprocessorOpts(),
- m_compiler->getCodeGenOpts(),
- *m_llvm_context));
-}
+//===----------------------------------------------------------------------===//
+// Implementation of ClangExpressionParser
+//===----------------------------------------------------------------------===//
-ClangExpressionParser::~ClangExpressionParser()
-{
+ClangExpressionParser::ClangExpressionParser(ExecutionContextScope *exe_scope,
+ Expression &expr,
+ bool generate_debug_info)
+ : ExpressionParser(exe_scope, expr, generate_debug_info), m_compiler(),
+ m_code_generator(), m_pp_callbacks(nullptr) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+
+ // We can't compile expressions without a target. So if the exe_scope is null
+ // or doesn't have a target,
+ // then we just need to get out of here. I'll lldb_assert and not make any of
+ // the compiler objects since
+ // I can't return errors directly from the constructor. Further calls will
+ // check if the compiler was made and
+ // bag out if it wasn't.
+
+ if (!exe_scope) {
+ lldb_assert(exe_scope, "Can't make an expression parser with a null scope.",
+ __FUNCTION__, __FILE__, __LINE__);
+ return;
+ }
+
+ lldb::TargetSP target_sp;
+ target_sp = exe_scope->CalculateTarget();
+ if (!target_sp) {
+ lldb_assert(target_sp.get(),
+ "Can't make an expression parser with a null target.",
+ __FUNCTION__, __FILE__, __LINE__);
+ return;
+ }
+
+ // 1. Create a new compiler instance.
+ m_compiler.reset(new CompilerInstance());
+ lldb::LanguageType frame_lang =
+ expr.Language(); // defaults to lldb::eLanguageTypeUnknown
+ bool overridden_target_opts = false;
+ lldb_private::LanguageRuntime *lang_rt = nullptr;
+
+ std::string abi;
+ ArchSpec target_arch;
+ target_arch = target_sp->GetArchitecture();
+
+ const auto target_machine = target_arch.GetMachine();
+
+ // If the expression is being evaluated in the context of an existing
+ // stack frame, we introspect to see if the language runtime is available.
+
+ lldb::StackFrameSP frame_sp = exe_scope->CalculateStackFrame();
+ lldb::ProcessSP process_sp = exe_scope->CalculateProcess();
+
+ // Make sure the user hasn't provided a preferred execution language
+ // with `expression --language X -- ...`
+ if (frame_sp && frame_lang == lldb::eLanguageTypeUnknown)
+ frame_lang = frame_sp->GetLanguage();
+
+ if (process_sp && frame_lang != lldb::eLanguageTypeUnknown) {
+ lang_rt = process_sp->GetLanguageRuntime(frame_lang);
+ if (log)
+ log->Printf("Frame has language of type %s",
+ Language::GetNameForLanguageType(frame_lang));
+ }
+
+ // 2. Configure the compiler with a set of default options that are
+ // appropriate
+ // for most situations.
+ if (target_arch.IsValid()) {
+ std::string triple = target_arch.GetTriple().str();
+ m_compiler->getTargetOpts().Triple = triple;
+ if (log)
+ log->Printf("Using %s as the target triple",
+ m_compiler->getTargetOpts().Triple.c_str());
+ } else {
+ // If we get here we don't have a valid target and just have to guess.
+ // Sometimes this will be ok to just use the host target triple (when we
+ // evaluate say "2+3", but other
+ // expressions like breakpoint conditions and other things that _are_ target
+ // specific really shouldn't just be
+ // using the host triple. In such a case the language runtime should expose
+ // an overridden options set (3),
+ // below.
+ m_compiler->getTargetOpts().Triple = llvm::sys::getDefaultTargetTriple();
+ if (log)
+ log->Printf("Using default target triple of %s",
+ m_compiler->getTargetOpts().Triple.c_str());
+ }
+ // Now add some special fixes for known architectures:
+ // 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";
+ }
+ // Supported subsets of x86
+ if (target_machine == llvm::Triple::x86 ||
+ target_machine == llvm::Triple::x86_64) {
+ m_compiler->getTargetOpts().Features.push_back("+sse");
+ m_compiler->getTargetOpts().Features.push_back("+sse2");
+ }
+
+ // Set the target CPU to generate code for.
+ // This will be empty for any CPU that doesn't really need to make a special
+ // CPU string.
+ m_compiler->getTargetOpts().CPU = target_arch.GetClangTargetCPU();
+
+ // Set the target ABI
+ abi = GetClangTargetABI(target_arch);
+ if (!abi.empty())
+ m_compiler->getTargetOpts().ABI = abi;
+
+ // 3. Now allow the runtime to provide custom configuration options for the
+ // target.
+ // In this case, a specialized language runtime is available and we can query
+ // it for extra options.
+ // For 99% of use cases, this will not be needed and should be provided when
+ // basic platform detection is not enough.
+ if (lang_rt)
+ overridden_target_opts =
+ lang_rt->GetOverrideExprOptions(m_compiler->getTargetOpts());
+
+ if (overridden_target_opts)
+ if (log) {
+ log->Debug(
+ "Using overridden target options for the expression evaluation");
+
+ auto opts = m_compiler->getTargetOpts();
+ log->Debug("Triple: '%s'", opts.Triple.c_str());
+ log->Debug("CPU: '%s'", opts.CPU.c_str());
+ log->Debug("FPMath: '%s'", opts.FPMath.c_str());
+ log->Debug("ABI: '%s'", opts.ABI.c_str());
+ log->Debug("LinkerVersion: '%s'", opts.LinkerVersion.c_str());
+ StringList::LogDump(log, opts.FeaturesAsWritten, "FeaturesAsWritten");
+ StringList::LogDump(log, opts.Features, "Features");
+ StringList::LogDump(log, opts.Reciprocals, "Reciprocals");
+ }
+
+ // 4. Create and install the target on the compiler.
+ m_compiler->createDiagnostics();
+ auto target_info = TargetInfo::CreateTargetInfo(
+ m_compiler->getDiagnostics(), m_compiler->getInvocation().TargetOpts);
+ if (log) {
+ log->Printf("Using SIMD alignment: %d", target_info->getSimdDefaultAlign());
+ log->Printf("Target datalayout string: '%s'",
+ target_info->getDataLayout().getStringRepresentation().c_str());
+ log->Printf("Target ABI: '%s'", target_info->getABI().str().c_str());
+ log->Printf("Target vector alignment: %d",
+ target_info->getMaxVectorAlign());
+ }
+ m_compiler->setTarget(target_info);
+
+ assert(m_compiler->hasTarget());
+
+ // 5. Set language options.
+ lldb::LanguageType language = expr.Language();
+
+ switch (language) {
+ case lldb::eLanguageTypeC:
+ case lldb::eLanguageTypeC89:
+ case lldb::eLanguageTypeC99:
+ case lldb::eLanguageTypeC11:
+ // FIXME: the following language option is a temporary workaround,
+ // to "ask for C, get C++."
+ // For now, the expression parser must use C++ anytime the
+ // language is a C family language, because the expression parser
+ // uses features of C++ to capture values.
+ m_compiler->getLangOpts().CPlusPlus = true;
+ break;
+ case lldb::eLanguageTypeObjC:
+ m_compiler->getLangOpts().ObjC1 = true;
+ m_compiler->getLangOpts().ObjC2 = true;
+ // FIXME: the following language option is a temporary workaround,
+ // to "ask for ObjC, get ObjC++" (see comment above).
+ m_compiler->getLangOpts().CPlusPlus = true;
+ break;
+ case lldb::eLanguageTypeC_plus_plus:
+ case lldb::eLanguageTypeC_plus_plus_11:
+ case lldb::eLanguageTypeC_plus_plus_14:
+ m_compiler->getLangOpts().CPlusPlus11 = true;
+ m_compiler->getHeaderSearchOpts().UseLibcxx = true;
+ LLVM_FALLTHROUGH;
+ case lldb::eLanguageTypeC_plus_plus_03:
+ m_compiler->getLangOpts().CPlusPlus = true;
+ // FIXME: the following language option is a temporary workaround,
+ // to "ask for C++, get ObjC++". Apple hopes to remove this requirement
+ // on non-Apple platforms, but for now it is needed.
+ m_compiler->getLangOpts().ObjC1 = true;
+ break;
+ case lldb::eLanguageTypeObjC_plus_plus:
+ case lldb::eLanguageTypeUnknown:
+ default:
+ m_compiler->getLangOpts().ObjC1 = true;
+ m_compiler->getLangOpts().ObjC2 = true;
+ m_compiler->getLangOpts().CPlusPlus = true;
+ m_compiler->getLangOpts().CPlusPlus11 = true;
+ m_compiler->getHeaderSearchOpts().UseLibcxx = 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() == Expression::eResultTypeId)
+ m_compiler->getLangOpts().DebuggerCastResultToId = true;
+
+ m_compiler->getLangOpts().CharIsSigned =
+ ArchSpec(m_compiler->getTargetOpts().Triple.c_str())
+ .CharIsSignedByDefault();
+
+ // 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;
+
+ if (process_sp && m_compiler->getLangOpts().ObjC1) {
+ if (process_sp->GetObjCLanguageRuntime()) {
+ if (process_sp->GetObjCLanguageRuntime()->GetRuntimeVersion() ==
+ ObjCLanguageRuntime::ObjCRuntimeVersions::eAppleObjC_V2)
+ 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;
+ }
+ }
+
+ 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().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().adjust(m_compiler->getLangOpts());
+
+ // 6. Set up the diagnostic buffer for reporting errors
+
+ m_compiler->getDiagnostics().setClient(new ClangDiagnosticManagerAdapter);
+
+ // 7. 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(TU_Complete);
+
+ if (ClangModulesDeclVendor *decl_vendor =
+ target_sp->GetClangModulesDeclVendor()) {
+ ClangPersistentVariables *clang_persistent_vars =
+ llvm::cast<ClangPersistentVariables>(
+ target_sp->GetPersistentExpressionStateForLanguage(
+ lldb::eLanguageTypeC));
+ std::unique_ptr<PPCallbacks> pp_callbacks(
+ new LLDBPreprocessorCallbacks(*decl_vendor, *clang_persistent_vars));
+ m_pp_callbacks =
+ static_cast<LLDBPreprocessorCallbacks *>(pp_callbacks.get());
+ m_compiler->getPreprocessor().addPPCallbacks(std::move(pp_callbacks));
+ }
+
+ // 8. 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->getPreprocessor().getIdentifierTable(),
+ *m_selector_table.get(), *m_builtin_context.get()));
+
+ ast_context->InitBuiltinTypes(m_compiler->getTarget());
+
+ ClangExpressionHelper *type_system_helper =
+ dyn_cast<ClangExpressionHelper>(m_expr.GetTypeSystemHelper());
+ ClangExpressionDeclMap *decl_map = type_system_helper->DeclMap();
+
+ if (decl_map) {
+ llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> ast_source(
+ decl_map->CreateProxy());
+ decl_map->InstallASTContext(ast_context.get());
+ ast_context->setExternalSource(ast_source);
+ }
+
+ m_ast_context.reset(
+ new ClangASTContext(m_compiler->getTargetOpts().Triple.c_str()));
+ m_ast_context->setASTContext(ast_context.get());
+ m_compiler->setASTContext(ast_context.release());
+
+ std::string module_name("$__lldb_module");
+
+ m_llvm_context.reset(new LLVMContext());
+ m_code_generator.reset(CreateLLVMCodeGen(
+ m_compiler->getDiagnostics(), module_name,
+ m_compiler->getHeaderSearchOpts(), m_compiler->getPreprocessorOpts(),
+ m_compiler->getCodeGenOpts(), *m_llvm_context));
}
-unsigned
-ClangExpressionParser::Parse(DiagnosticManager &diagnostic_manager)
-{
- ClangDiagnosticManagerAdapter *adapter =
- static_cast<ClangDiagnosticManagerAdapter *>(m_compiler->getDiagnostics().getClient());
- clang::TextDiagnosticBuffer *diag_buf = adapter->GetPassthrough();
- diag_buf->FlushDiagnostics(m_compiler->getDiagnostics());
-
- adapter->ResetManager(&diagnostic_manager);
-
- const char *expr_text = m_expr.Text();
-
- clang::SourceManager &source_mgr = m_compiler->getSourceManager();
- bool created_main_file = false;
- if (m_compiler->getCodeGenOpts().getDebugInfo() == codegenoptions::FullDebugInfo)
- {
- int temp_fd = -1;
- llvm::SmallString<PATH_MAX> result_path;
- FileSpec tmpdir_file_spec;
- if (HostInfo::GetLLDBPath(lldb::ePathTypeLLDBTempSystemDir, tmpdir_file_spec))
- {
- tmpdir_file_spec.AppendPathComponent("lldb-%%%%%%.expr");
- std::string temp_source_path = tmpdir_file_spec.GetPath();
- llvm::sys::fs::createUniqueFile(temp_source_path, temp_fd, result_path);
- }
- else
- {
- llvm::sys::fs::createTemporaryFile("lldb", "expr", temp_fd, result_path);
- }
-
- if (temp_fd != -1)
- {
- lldb_private::File file(temp_fd, true);
- 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();
- source_mgr.setMainFileID(source_mgr.createFileID(m_file_manager->getFile(result_path),
- SourceLocation(), SrcMgr::C_User));
- created_main_file = true;
- }
- }
+ClangExpressionParser::~ClangExpressionParser() {}
+
+unsigned ClangExpressionParser::Parse(DiagnosticManager &diagnostic_manager) {
+ ClangDiagnosticManagerAdapter *adapter =
+ static_cast<ClangDiagnosticManagerAdapter *>(
+ m_compiler->getDiagnostics().getClient());
+ clang::TextDiagnosticBuffer *diag_buf = adapter->GetPassthrough();
+ diag_buf->FlushDiagnostics(m_compiler->getDiagnostics());
+
+ adapter->ResetManager(&diagnostic_manager);
+
+ const char *expr_text = m_expr.Text();
+
+ clang::SourceManager &source_mgr = m_compiler->getSourceManager();
+ bool created_main_file = false;
+ if (m_compiler->getCodeGenOpts().getDebugInfo() ==
+ codegenoptions::FullDebugInfo) {
+ int temp_fd = -1;
+ llvm::SmallString<PATH_MAX> result_path;
+ FileSpec tmpdir_file_spec;
+ if (HostInfo::GetLLDBPath(lldb::ePathTypeLLDBTempSystemDir,
+ tmpdir_file_spec)) {
+ tmpdir_file_spec.AppendPathComponent("lldb-%%%%%%.expr");
+ std::string temp_source_path = tmpdir_file_spec.GetPath();
+ llvm::sys::fs::createUniqueFile(temp_source_path, temp_fd, result_path);
+ } else {
+ llvm::sys::fs::createTemporaryFile("lldb", "expr", temp_fd, result_path);
+ }
+
+ if (temp_fd != -1) {
+ lldb_private::File file(temp_fd, true);
+ 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();
+ source_mgr.setMainFileID(
+ source_mgr.createFileID(m_file_manager->getFile(result_path),
+ SourceLocation(), SrcMgr::C_User));
+ created_main_file = true;
}
+ }
}
+ }
- if (!created_main_file)
- {
- std::unique_ptr<MemoryBuffer> memory_buffer = MemoryBuffer::getMemBufferCopy(expr_text, __FUNCTION__);
- source_mgr.setMainFileID(source_mgr.createFileID(std::move(memory_buffer)));
- }
+ if (!created_main_file) {
+ std::unique_ptr<MemoryBuffer> memory_buffer =
+ MemoryBuffer::getMemBufferCopy(expr_text, __FUNCTION__);
+ source_mgr.setMainFileID(source_mgr.createFileID(std::move(memory_buffer)));
+ }
- diag_buf->BeginSourceFile(m_compiler->getLangOpts(), &m_compiler->getPreprocessor());
+ diag_buf->BeginSourceFile(m_compiler->getLangOpts(),
+ &m_compiler->getPreprocessor());
- ClangExpressionHelper *type_system_helper = dyn_cast<ClangExpressionHelper>(m_expr.GetTypeSystemHelper());
+ ClangExpressionHelper *type_system_helper =
+ dyn_cast<ClangExpressionHelper>(m_expr.GetTypeSystemHelper());
- ASTConsumer *ast_transformer = type_system_helper->ASTTransformer(m_code_generator.get());
+ ASTConsumer *ast_transformer =
+ type_system_helper->ASTTransformer(m_code_generator.get());
- if (ClangExpressionDeclMap *decl_map = type_system_helper->DeclMap())
- decl_map->InstallCodeGenerator(m_code_generator.get());
+ if (ClangExpressionDeclMap *decl_map = type_system_helper->DeclMap())
+ decl_map->InstallCodeGenerator(m_code_generator.get());
- if (ast_transformer)
- {
- ast_transformer->Initialize(m_compiler->getASTContext());
- ParseAST(m_compiler->getPreprocessor(), ast_transformer, m_compiler->getASTContext());
- }
- else
- {
- m_code_generator->Initialize(m_compiler->getASTContext());
- ParseAST(m_compiler->getPreprocessor(), m_code_generator.get(), m_compiler->getASTContext());
- }
+ if (ast_transformer) {
+ ast_transformer->Initialize(m_compiler->getASTContext());
+ ParseAST(m_compiler->getPreprocessor(), ast_transformer,
+ m_compiler->getASTContext());
+ } else {
+ m_code_generator->Initialize(m_compiler->getASTContext());
+ ParseAST(m_compiler->getPreprocessor(), m_code_generator.get(),
+ m_compiler->getASTContext());
+ }
- diag_buf->EndSourceFile();
+ diag_buf->EndSourceFile();
- unsigned num_errors = diag_buf->getNumErrors();
+ unsigned num_errors = diag_buf->getNumErrors();
- if (m_pp_callbacks && m_pp_callbacks->hasErrors())
- {
- num_errors++;
- diagnostic_manager.PutCString(eDiagnosticSeverityError, "while importing modules:");
- diagnostic_manager.AppendMessageToDiagnostic(m_pp_callbacks->getErrorString().c_str());
- }
+ if (m_pp_callbacks && m_pp_callbacks->hasErrors()) {
+ num_errors++;
+ diagnostic_manager.PutCString(eDiagnosticSeverityError,
+ "while importing modules:");
+ diagnostic_manager.AppendMessageToDiagnostic(
+ m_pp_callbacks->getErrorString().c_str());
+ }
- if (!num_errors)
- {
- if (type_system_helper->DeclMap() && !type_system_helper->DeclMap()->ResolveUnknownTypes())
- {
- diagnostic_manager.Printf(eDiagnosticSeverityError, "Couldn't infer the type of a variable");
- num_errors++;
- }
+ if (!num_errors) {
+ if (type_system_helper->DeclMap() &&
+ !type_system_helper->DeclMap()->ResolveUnknownTypes()) {
+ diagnostic_manager.Printf(eDiagnosticSeverityError,
+ "Couldn't infer the type of a variable");
+ num_errors++;
}
+ }
- if (!num_errors)
- {
- type_system_helper->CommitPersistentDecls();
- }
+ if (!num_errors) {
+ type_system_helper->CommitPersistentDecls();
+ }
- adapter->ResetManager();
+ adapter->ResetManager();
- return num_errors;
+ return num_errors;
}
std::string
-ClangExpressionParser::GetClangTargetABI (const ArchSpec &target_arch)
-{
- std::string abi;
-
- if(target_arch.IsMIPS())
- {
- switch (target_arch.GetFlags () & ArchSpec::eMIPSABI_mask)
- {
- case ArchSpec::eMIPSABI_N64:
- abi = "n64"; break;
- case ArchSpec::eMIPSABI_N32:
- abi = "n32"; break;
- case ArchSpec::eMIPSABI_O32:
- abi = "o32"; break;
- default:
- break;
- }
+ClangExpressionParser::GetClangTargetABI(const ArchSpec &target_arch) {
+ std::string abi;
+
+ if (target_arch.IsMIPS()) {
+ switch (target_arch.GetFlags() & ArchSpec::eMIPSABI_mask) {
+ case ArchSpec::eMIPSABI_N64:
+ abi = "n64";
+ break;
+ case ArchSpec::eMIPSABI_N32:
+ abi = "n32";
+ break;
+ case ArchSpec::eMIPSABI_O32:
+ abi = "o32";
+ break;
+ default:
+ break;
}
- return abi;
+ }
+ return abi;
}
-bool
-ClangExpressionParser::RewriteExpression(DiagnosticManager &diagnostic_manager)
-{
- clang::SourceManager &source_manager = m_compiler->getSourceManager();
- clang::edit::EditedSource editor(source_manager, m_compiler->getLangOpts(), nullptr);
- clang::edit::Commit commit(editor);
- clang::Rewriter rewriter(source_manager, m_compiler->getLangOpts());
-
- class RewritesReceiver : public edit::EditsReceiver {
- Rewriter &rewrite;
-
- public:
- RewritesReceiver(Rewriter &in_rewrite) : rewrite(in_rewrite) { }
-
- void insert(SourceLocation loc, StringRef text) override {
- rewrite.InsertText(loc, text);
- }
- void replace(CharSourceRange range, StringRef text) override {
- rewrite.ReplaceText(range.getBegin(), rewrite.getRangeSize(range), text);
- }
- };
-
- RewritesReceiver rewrites_receiver(rewriter);
-
- const DiagnosticList &diagnostics = diagnostic_manager.Diagnostics();
- size_t num_diags = diagnostics.size();
- if (num_diags == 0)
- return false;
-
- for (const Diagnostic *diag : diagnostic_manager.Diagnostics())
- {
- const ClangDiagnostic *diagnostic = llvm::dyn_cast<ClangDiagnostic>(diag);
- if (diagnostic && diagnostic->HasFixIts())
- {
- for (const FixItHint &fixit : diagnostic->FixIts())
- {
- // This is cobbed from clang::Rewrite::FixItRewriter.
- if (fixit.CodeToInsert.empty())
- {
- if (fixit.InsertFromRange.isValid())
- {
- commit.insertFromRange(fixit.RemoveRange.getBegin(),
- fixit.InsertFromRange, /*afterToken=*/false,
- fixit.BeforePreviousInsertions);
- }
- else
- commit.remove(fixit.RemoveRange);
- }
- else
- {
- if (fixit.RemoveRange.isTokenRange() ||
- fixit.RemoveRange.getBegin() != fixit.RemoveRange.getEnd())
- commit.replace(fixit.RemoveRange, fixit.CodeToInsert);
- else
- commit.insert(fixit.RemoveRange.getBegin(), fixit.CodeToInsert,
- /*afterToken=*/false, fixit.BeforePreviousInsertions);
- }
- }
- }
+bool ClangExpressionParser::RewriteExpression(
+ DiagnosticManager &diagnostic_manager) {
+ clang::SourceManager &source_manager = m_compiler->getSourceManager();
+ clang::edit::EditedSource editor(source_manager, m_compiler->getLangOpts(),
+ nullptr);
+ clang::edit::Commit commit(editor);
+ clang::Rewriter rewriter(source_manager, m_compiler->getLangOpts());
+
+ class RewritesReceiver : public edit::EditsReceiver {
+ Rewriter &rewrite;
+
+ public:
+ RewritesReceiver(Rewriter &in_rewrite) : rewrite(in_rewrite) {}
+
+ void insert(SourceLocation loc, StringRef text) override {
+ rewrite.InsertText(loc, text);
}
-
- // FIXME - do we want to try to propagate specific errors here?
- if (!commit.isCommitable())
- return false;
- else if (!editor.commit(commit))
- return false;
-
- // Now play all the edits, and stash the result in the diagnostic manager.
- editor.applyRewrites(rewrites_receiver);
- RewriteBuffer &main_file_buffer = rewriter.getEditBuffer(source_manager.getMainFileID());
-
- std::string fixed_expression;
- llvm::raw_string_ostream out_stream(fixed_expression);
-
- main_file_buffer.write(out_stream);
- out_stream.flush();
- diagnostic_manager.SetFixedExpression(fixed_expression);
-
- return true;
-}
+ void replace(CharSourceRange range, StringRef text) override {
+ rewrite.ReplaceText(range.getBegin(), rewrite.getRangeSize(range), text);
+ }
+ };
+
+ RewritesReceiver rewrites_receiver(rewriter);
+
+ const DiagnosticList &diagnostics = diagnostic_manager.Diagnostics();
+ size_t num_diags = diagnostics.size();
+ if (num_diags == 0)
+ return false;
-static bool FindFunctionInModule (ConstString &mangled_name,
- llvm::Module *module,
- const char *orig_name)
-{
- for (const auto &func : module->getFunctionList())
- {
- const StringRef &name = func.getName();
- if (name.find(orig_name) != StringRef::npos)
- {
- mangled_name.SetString(name);
- return true;
+ for (const Diagnostic *diag : diagnostic_manager.Diagnostics()) {
+ const ClangDiagnostic *diagnostic = llvm::dyn_cast<ClangDiagnostic>(diag);
+ if (diagnostic && diagnostic->HasFixIts()) {
+ for (const FixItHint &fixit : diagnostic->FixIts()) {
+ // This is cobbed from clang::Rewrite::FixItRewriter.
+ if (fixit.CodeToInsert.empty()) {
+ if (fixit.InsertFromRange.isValid()) {
+ commit.insertFromRange(fixit.RemoveRange.getBegin(),
+ fixit.InsertFromRange, /*afterToken=*/false,
+ fixit.BeforePreviousInsertions);
+ } else
+ commit.remove(fixit.RemoveRange);
+ } else {
+ if (fixit.RemoveRange.isTokenRange() ||
+ fixit.RemoveRange.getBegin() != fixit.RemoveRange.getEnd())
+ commit.replace(fixit.RemoveRange, fixit.CodeToInsert);
+ else
+ commit.insert(fixit.RemoveRange.getBegin(), fixit.CodeToInsert,
+ /*afterToken=*/false, fixit.BeforePreviousInsertions);
}
+ }
}
+ }
+ // FIXME - do we want to try to propagate specific errors here?
+ if (!commit.isCommitable())
+ return false;
+ else if (!editor.commit(commit))
return false;
+
+ // Now play all the edits, and stash the result in the diagnostic manager.
+ editor.applyRewrites(rewrites_receiver);
+ RewriteBuffer &main_file_buffer =
+ rewriter.getEditBuffer(source_manager.getMainFileID());
+
+ std::string fixed_expression;
+ llvm::raw_string_ostream out_stream(fixed_expression);
+
+ main_file_buffer.write(out_stream);
+ out_stream.flush();
+ diagnostic_manager.SetFixedExpression(fixed_expression);
+
+ return true;
}
-lldb_private::Error
-ClangExpressionParser::PrepareForExecution (lldb::addr_t &func_addr,
- lldb::addr_t &func_end,
- lldb::IRExecutionUnitSP &execution_unit_sp,
- ExecutionContext &exe_ctx,
- bool &can_interpret,
- ExecutionPolicy execution_policy)
-{
- func_addr = LLDB_INVALID_ADDRESS;
- func_end = LLDB_INVALID_ADDRESS;
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
- lldb_private::Error err;
-
- 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;
+static bool FindFunctionInModule(ConstString &mangled_name,
+ llvm::Module *module, const char *orig_name) {
+ for (const auto &func : module->getFunctionList()) {
+ const StringRef &name = func.getName();
+ if (name.find(orig_name) != StringRef::npos) {
+ mangled_name.SetString(name);
+ return true;
}
+ }
- ConstString function_name;
+ return false;
+}
- if (execution_policy != eExecutionPolicyTopLevel)
- {
- // Find the actual name of the function (it's often mangled somehow)
+lldb_private::Error ClangExpressionParser::PrepareForExecution(
+ lldb::addr_t &func_addr, lldb::addr_t &func_end,
+ lldb::IRExecutionUnitSP &execution_unit_sp, ExecutionContext &exe_ctx,
+ bool &can_interpret, ExecutionPolicy execution_policy) {
+ func_addr = LLDB_INVALID_ADDRESS;
+ func_end = LLDB_INVALID_ADDRESS;
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- 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());
- return err;
- }
- else
- {
- if (log)
- log->Printf("Found function %s for %s", function_name.AsCString(), m_expr.FunctionName());
- }
- }
+ lldb_private::Error err;
- SymbolContext sc;
+ std::unique_ptr<llvm::Module> llvm_module_ap(
+ m_code_generator->ReleaseModule());
- if (lldb::StackFrameSP frame_sp = exe_ctx.GetFrameSP())
- {
- sc = frame_sp->GetSymbolContext(lldb::eSymbolContextEverything);
- }
- else if (lldb::TargetSP target_sp = exe_ctx.GetTargetSP())
- {
- sc.target_sp = target_sp;
- }
+ if (!llvm_module_ap.get()) {
+ err.SetErrorToGenericError();
+ err.SetErrorString("IR doesn't contain a module");
+ return err;
+ }
- LLVMUserExpression::IRPasses custom_passes;
- {
- auto lang = m_expr.Language();
- if (log)
- log->Printf("%s - Currrent expression language is %s\n", __FUNCTION__,
- Language::GetNameForLanguageType(lang));
-
- if (lang != lldb::eLanguageTypeUnknown)
- {
- auto runtime = exe_ctx.GetProcessSP()->GetLanguageRuntime(lang);
- if (runtime)
- runtime->GetIRPasses(custom_passes);
- }
+ ConstString function_name;
+
+ if (execution_policy != eExecutionPolicyTopLevel) {
+ // Find the actual name of the function (it's often mangled somehow)
+
+ 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());
+ return err;
+ } else {
+ if (log)
+ log->Printf("Found function %s for %s", function_name.AsCString(),
+ m_expr.FunctionName());
}
+ }
+
+ SymbolContext sc;
- if (custom_passes.EarlyPasses)
- {
- if (log)
- log->Printf("%s - Running Early IR Passes from LanguageRuntime on expression module '%s'", __FUNCTION__,
- m_expr.FunctionName());
+ if (lldb::StackFrameSP frame_sp = exe_ctx.GetFrameSP()) {
+ sc = frame_sp->GetSymbolContext(lldb::eSymbolContextEverything);
+ } else if (lldb::TargetSP target_sp = exe_ctx.GetTargetSP()) {
+ sc.target_sp = target_sp;
+ }
- custom_passes.EarlyPasses->run(*llvm_module_ap);
+ LLVMUserExpression::IRPasses custom_passes;
+ {
+ auto lang = m_expr.Language();
+ if (log)
+ log->Printf("%s - Currrent expression language is %s\n", __FUNCTION__,
+ Language::GetNameForLanguageType(lang));
+
+ if (lang != lldb::eLanguageTypeUnknown) {
+ auto runtime = exe_ctx.GetProcessSP()->GetLanguageRuntime(lang);
+ if (runtime)
+ runtime->GetIRPasses(custom_passes);
}
+ }
- execution_unit_sp.reset(new IRExecutionUnit (m_llvm_context, // handed off here
- llvm_module_ap, // handed off here
- function_name,
- exe_ctx.GetTargetSP(),
- sc,
- m_compiler->getTargetOpts().Features));
+ if (custom_passes.EarlyPasses) {
+ if (log)
+ log->Printf("%s - Running Early IR Passes from LanguageRuntime on "
+ "expression module '%s'",
+ __FUNCTION__, m_expr.FunctionName());
- ClangExpressionHelper *type_system_helper = dyn_cast<ClangExpressionHelper>(m_expr.GetTypeSystemHelper());
- ClangExpressionDeclMap *decl_map = type_system_helper->DeclMap(); // result can be NULL
+ custom_passes.EarlyPasses->run(*llvm_module_ap);
+ }
- if (decl_map)
- {
- Stream *error_stream = NULL;
- Target *target = exe_ctx.GetTargetPtr();
- error_stream = target->GetDebugger().GetErrorFile().get();
+ execution_unit_sp.reset(
+ new IRExecutionUnit(m_llvm_context, // handed off here
+ llvm_module_ap, // handed off here
+ function_name, exe_ctx.GetTargetSP(), sc,
+ m_compiler->getTargetOpts().Features));
- IRForTarget ir_for_target(decl_map, m_expr.NeedsVariableResolution(), *execution_unit_sp, *error_stream,
- function_name.AsCString());
+ ClangExpressionHelper *type_system_helper =
+ dyn_cast<ClangExpressionHelper>(m_expr.GetTypeSystemHelper());
+ ClangExpressionDeclMap *decl_map =
+ type_system_helper->DeclMap(); // result can be NULL
- bool ir_can_run = ir_for_target.runOnModule(*execution_unit_sp->GetModule());
+ if (decl_map) {
+ Stream *error_stream = NULL;
+ Target *target = exe_ctx.GetTargetPtr();
+ error_stream = target->GetDebugger().GetErrorFile().get();
- if (!ir_can_run)
- {
- err.SetErrorString("The expression could not be prepared to run in the target");
- return err;
- }
+ IRForTarget ir_for_target(decl_map, m_expr.NeedsVariableResolution(),
+ *execution_unit_sp, *error_stream,
+ function_name.AsCString());
- Process *process = exe_ctx.GetProcessPtr();
+ bool ir_can_run =
+ ir_for_target.runOnModule(*execution_unit_sp->GetModule());
- if (execution_policy != eExecutionPolicyAlways && execution_policy != eExecutionPolicyTopLevel)
- {
- lldb_private::Error interpret_error;
+ if (!ir_can_run) {
+ err.SetErrorString(
+ "The expression could not be prepared to run in the target");
+ return err;
+ }
- bool interpret_function_calls = !process ? false : process->CanInterpretFunctionCalls();
- can_interpret =
- IRInterpreter::CanInterpret(*execution_unit_sp->GetModule(), *execution_unit_sp->GetFunction(),
- interpret_error, interpret_function_calls);
+ Process *process = exe_ctx.GetProcessPtr();
- if (!can_interpret && execution_policy == eExecutionPolicyNever)
- {
- err.SetErrorStringWithFormat("Can't run the expression locally: %s", interpret_error.AsCString());
- return err;
- }
- }
+ if (execution_policy != eExecutionPolicyAlways &&
+ execution_policy != eExecutionPolicyTopLevel) {
+ lldb_private::Error interpret_error;
- if (!process && execution_policy == eExecutionPolicyAlways)
- {
- err.SetErrorString("Expression needed to run in the target, but the target can't be run");
- return err;
- }
+ bool interpret_function_calls =
+ !process ? false : process->CanInterpretFunctionCalls();
+ can_interpret = IRInterpreter::CanInterpret(
+ *execution_unit_sp->GetModule(), *execution_unit_sp->GetFunction(),
+ interpret_error, interpret_function_calls);
+
+ 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 (!process && execution_policy == eExecutionPolicyTopLevel) {
+ err.SetErrorString("Top-level code needs to be inserted into a runnable "
+ "target, but the target can't be run");
+ return err;
+ }
+
+ if (execution_policy == eExecutionPolicyAlways ||
+ (execution_policy != eExecutionPolicyTopLevel && !can_interpret)) {
+ if (m_expr.NeedsValidation() && process) {
+ if (!process->GetDynamicCheckers()) {
+ DynamicCheckerFunctions *dynamic_checkers =
+ new DynamicCheckerFunctions();
+
+ DiagnosticManager install_diagnostics;
+
+ if (!dynamic_checkers->Install(install_diagnostics, exe_ctx)) {
+ if (install_diagnostics.Diagnostics().size())
+ err.SetErrorString("couldn't install checkers, unknown error");
+ else
+ err.SetErrorString(install_diagnostics.GetString().c_str());
- if (!process && execution_policy == eExecutionPolicyTopLevel)
- {
- err.SetErrorString(
- "Top-level code needs to be inserted into a runnable target, but the target can't be run");
return err;
+ }
+
+ process->SetDynamicCheckers(dynamic_checkers);
+
+ if (log)
+ log->Printf("== [ClangUserExpression::Evaluate] Finished "
+ "installing dynamic checkers ==");
}
- if (execution_policy == eExecutionPolicyAlways ||
- (execution_policy != eExecutionPolicyTopLevel && !can_interpret))
- {
- if (m_expr.NeedsValidation() && process)
- {
- if (!process->GetDynamicCheckers())
- {
- DynamicCheckerFunctions *dynamic_checkers = new DynamicCheckerFunctions();
-
- DiagnosticManager install_diagnostics;
-
- if (!dynamic_checkers->Install(install_diagnostics, exe_ctx))
- {
- if (install_diagnostics.Diagnostics().size())
- err.SetErrorString("couldn't install checkers, unknown error");
- else
- err.SetErrorString(install_diagnostics.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());
-
- llvm::Module *module = execution_unit_sp->GetModule();
- if (!module || !ir_dynamic_checks.runOnModule(*module))
- {
- err.SetErrorToGenericError();
- err.SetErrorString("Couldn't add dynamic checks to the expression");
- return err;
- }
-
- if (custom_passes.LatePasses)
- {
- if (log)
- log->Printf("%s - Running Late IR Passes from LanguageRuntime on expression module '%s'",
- __FUNCTION__, m_expr.FunctionName());
-
- custom_passes.LatePasses->run(*module);
- }
- }
+ IRDynamicChecks ir_dynamic_checks(*process->GetDynamicCheckers(),
+ function_name.AsCString());
+
+ llvm::Module *module = execution_unit_sp->GetModule();
+ if (!module || !ir_dynamic_checks.runOnModule(*module)) {
+ err.SetErrorToGenericError();
+ err.SetErrorString("Couldn't add dynamic checks to the expression");
+ return err;
}
- if (execution_policy == eExecutionPolicyAlways || execution_policy == eExecutionPolicyTopLevel ||
- !can_interpret)
- {
- execution_unit_sp->GetRunnableInfo(err, func_addr, func_end);
+ if (custom_passes.LatePasses) {
+ if (log)
+ log->Printf("%s - Running Late IR Passes from LanguageRuntime on "
+ "expression module '%s'",
+ __FUNCTION__, m_expr.FunctionName());
+
+ custom_passes.LatePasses->run(*module);
}
+ }
}
- else
- {
- execution_unit_sp->GetRunnableInfo(err, func_addr, func_end);
+
+ if (execution_policy == eExecutionPolicyAlways ||
+ execution_policy == eExecutionPolicyTopLevel || !can_interpret) {
+ execution_unit_sp->GetRunnableInfo(err, func_addr, func_end);
}
+ } else {
+ execution_unit_sp->GetRunnableInfo(err, func_addr, func_end);
+ }
- return err;
+ return err;
}
-lldb_private::Error
-ClangExpressionParser::RunStaticInitializers (lldb::IRExecutionUnitSP &execution_unit_sp,
- ExecutionContext &exe_ctx)
-{
- lldb_private::Error err;
-
- lldbassert(execution_unit_sp.get());
- lldbassert(exe_ctx.HasThreadScope());
-
- if (!execution_unit_sp.get())
- {
- err.SetErrorString ("can't run static initializers for a NULL execution unit");
- return err;
- }
-
- if (!exe_ctx.HasThreadScope())
- {
- err.SetErrorString ("can't run static initializers without a thread");
- return err;
- }
-
- std::vector<lldb::addr_t> static_initializers;
-
- execution_unit_sp->GetStaticInitializers(static_initializers);
-
- for (lldb::addr_t static_initializer : static_initializers)
- {
- EvaluateExpressionOptions options;
-
- lldb::ThreadPlanSP call_static_initializer(new ThreadPlanCallFunction(exe_ctx.GetThreadRef(),
- Address(static_initializer),
- CompilerType(),
- llvm::ArrayRef<lldb::addr_t>(),
- options));
-
- DiagnosticManager execution_errors;
- lldb::ExpressionResults results = exe_ctx.GetThreadRef().GetProcess()->RunThreadPlan(exe_ctx, call_static_initializer, options, execution_errors);
-
- if (results != lldb::eExpressionCompleted)
- {
- err.SetErrorStringWithFormat ("couldn't run static initializer: %s", execution_errors.GetString().c_str());
- return err;
- }
- }
-
+lldb_private::Error ClangExpressionParser::RunStaticInitializers(
+ lldb::IRExecutionUnitSP &execution_unit_sp, ExecutionContext &exe_ctx) {
+ lldb_private::Error err;
+
+ lldbassert(execution_unit_sp.get());
+ lldbassert(exe_ctx.HasThreadScope());
+
+ if (!execution_unit_sp.get()) {
+ err.SetErrorString(
+ "can't run static initializers for a NULL execution unit");
return err;
+ }
+
+ if (!exe_ctx.HasThreadScope()) {
+ err.SetErrorString("can't run static initializers without a thread");
+ return err;
+ }
+
+ std::vector<lldb::addr_t> static_initializers;
+
+ execution_unit_sp->GetStaticInitializers(static_initializers);
+
+ for (lldb::addr_t static_initializer : static_initializers) {
+ EvaluateExpressionOptions options;
+
+ lldb::ThreadPlanSP call_static_initializer(new ThreadPlanCallFunction(
+ exe_ctx.GetThreadRef(), Address(static_initializer), CompilerType(),
+ llvm::ArrayRef<lldb::addr_t>(), options));
+
+ DiagnosticManager execution_errors;
+ lldb::ExpressionResults results =
+ exe_ctx.GetThreadRef().GetProcess()->RunThreadPlan(
+ exe_ctx, call_static_initializer, options, execution_errors);
+
+ if (results != lldb::eExpressionCompleted) {
+ err.SetErrorStringWithFormat("couldn't run static initializer: %s",
+ execution_errors.GetString().c_str());
+ return err;
+ }
+ }
+
+ return err;
}
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h
index 34c0212b73a..3f01156c6de 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h
@@ -20,13 +20,13 @@
#include <string>
#include <vector>
-namespace lldb_private
-{
+namespace lldb_private {
class IRExecutionUnit;
-
+
//----------------------------------------------------------------------
-/// @class ClangExpressionParser ClangExpressionParser.h "lldb/Expression/ClangExpressionParser.h"
+/// @class ClangExpressionParser ClangExpressionParser.h
+/// "lldb/Expression/ClangExpressionParser.h"
/// @brief Encapsulates an instance of Clang that can parse expressions.
///
/// ClangExpressionParser is responsible for preparing an instance of
@@ -35,134 +35,132 @@ class IRExecutionUnit;
/// conversion to formats (DWARF bytecode, or JIT compiled machine code)
/// that can be executed.
//----------------------------------------------------------------------
-class ClangExpressionParser : public ExpressionParser
-{
+class ClangExpressionParser : public ExpressionParser {
public:
- //------------------------------------------------------------------
- /// Constructor
- ///
- /// Initializes class variables.
- ///
- /// @param[in] exe_scope,
- /// If non-NULL, an execution context scope that can help to
- /// correctly create an expression with a valid process for
- /// optional tuning Objective-C runtime support. Can be NULL.
- ///
- /// @param[in] expr
- /// The expression to be parsed.
- //------------------------------------------------------------------
- ClangExpressionParser (ExecutionContextScope *exe_scope,
- Expression &expr,
- bool generate_debug_info);
-
- //------------------------------------------------------------------
- /// Destructor
- //------------------------------------------------------------------
- ~ClangExpressionParser () override;
-
- //------------------------------------------------------------------
- /// Parse a single expression and convert it to IR using Clang. Don't
- /// wrap the expression in anything at all.
- ///
- /// @param[in] diagnostic_manager
- /// The diagnostic manager to report errors to.
- ///
- /// @return
- /// The number of errors encountered during parsing. 0 means
- /// success.
- //------------------------------------------------------------------
- unsigned
- Parse(DiagnosticManager &diagnostic_manager) override;
-
- bool
- RewriteExpression(DiagnosticManager &diagnostic_manager) override;
+ //------------------------------------------------------------------
+ /// Constructor
+ ///
+ /// Initializes class variables.
+ ///
+ /// @param[in] exe_scope,
+ /// If non-NULL, an execution context scope that can help to
+ /// correctly create an expression with a valid process for
+ /// optional tuning Objective-C runtime support. Can be NULL.
+ ///
+ /// @param[in] expr
+ /// The expression to be parsed.
+ //------------------------------------------------------------------
+ ClangExpressionParser(ExecutionContextScope *exe_scope, Expression &expr,
+ bool generate_debug_info);
+
+ //------------------------------------------------------------------
+ /// Destructor
+ //------------------------------------------------------------------
+ ~ClangExpressionParser() override;
+
+ //------------------------------------------------------------------
+ /// Parse a single expression and convert it to IR using Clang. Don't
+ /// wrap the expression in anything at all.
+ ///
+ /// @param[in] diagnostic_manager
+ /// The diagnostic manager to report errors to.
+ ///
+ /// @return
+ /// The number of errors encountered during parsing. 0 means
+ /// success.
+ //------------------------------------------------------------------
+ unsigned Parse(DiagnosticManager &diagnostic_manager) override;
+
+ bool RewriteExpression(DiagnosticManager &diagnostic_manager) override;
- //------------------------------------------------------------------
- /// Ready an already-parsed expression for execution, possibly
- /// evaluating it statically.
- ///
- /// @param[out] func_addr
- /// The address to which the function has been written.
- ///
- /// @param[out] func_end
- /// The end of the function's allocated memory region. (func_addr
- /// and func_end do not delimit an allocated region; the allocated
- /// region may begin before func_addr.)
- ///
- /// @param[in] execution_unit_sp
- /// After parsing, ownership of the execution unit for
- /// for the expression is handed to this shared pointer.
- ///
- /// @param[in] exe_ctx
- /// The execution context to write the function into.
- ///
- /// @param[out] evaluated_statically
- /// Set to true if the expression could be interpreted statically;
- /// untouched otherwise.
- ///
- /// @param[out] const_result
- /// If the result of the expression is constant, and the
- /// expression has no side effects, this is set to the result of the
- /// expression.
- ///
- /// @param[in] execution_policy
- /// Determines whether the expression must be JIT-compiled, must be
- /// evaluated statically, or whether this decision may be made
- /// opportunistically.
- ///
- /// @return
- /// An error code indicating the success or failure of the operation.
- /// Test with Success().
- //------------------------------------------------------------------
- Error
- PrepareForExecution (lldb::addr_t &func_addr,
- lldb::addr_t &func_end,
- lldb::IRExecutionUnitSP &execution_unit_sp,
- ExecutionContext &exe_ctx,
- bool &can_interpret,
- lldb_private::ExecutionPolicy execution_policy) override;
-
- //------------------------------------------------------------------
- /// Run all static initializers for an execution unit.
- ///
- /// @param[in] execution_unit_sp
- /// The execution unit.
- ///
- /// @param[in] exe_ctx
- /// The execution context to use when running them. Thread can't be null.
- ///
- /// @return
- /// The error code indicating the
- //------------------------------------------------------------------
- Error
- RunStaticInitializers (lldb::IRExecutionUnitSP &execution_unit_sp,
- ExecutionContext &exe_ctx);
+ //------------------------------------------------------------------
+ /// Ready an already-parsed expression for execution, possibly
+ /// evaluating it statically.
+ ///
+ /// @param[out] func_addr
+ /// The address to which the function has been written.
+ ///
+ /// @param[out] func_end
+ /// The end of the function's allocated memory region. (func_addr
+ /// and func_end do not delimit an allocated region; the allocated
+ /// region may begin before func_addr.)
+ ///
+ /// @param[in] execution_unit_sp
+ /// After parsing, ownership of the execution unit for
+ /// for the expression is handed to this shared pointer.
+ ///
+ /// @param[in] exe_ctx
+ /// The execution context to write the function into.
+ ///
+ /// @param[out] evaluated_statically
+ /// Set to true if the expression could be interpreted statically;
+ /// untouched otherwise.
+ ///
+ /// @param[out] const_result
+ /// If the result of the expression is constant, and the
+ /// expression has no side effects, this is set to the result of the
+ /// expression.
+ ///
+ /// @param[in] execution_policy
+ /// Determines whether the expression must be JIT-compiled, must be
+ /// evaluated statically, or whether this decision may be made
+ /// opportunistically.
+ ///
+ /// @return
+ /// An error code indicating the success or failure of the operation.
+ /// Test with Success().
+ //------------------------------------------------------------------
+ Error
+ PrepareForExecution(lldb::addr_t &func_addr, lldb::addr_t &func_end,
+ lldb::IRExecutionUnitSP &execution_unit_sp,
+ ExecutionContext &exe_ctx, bool &can_interpret,
+ lldb_private::ExecutionPolicy execution_policy) override;
+
+ //------------------------------------------------------------------
+ /// Run all static initializers for an execution unit.
+ ///
+ /// @param[in] execution_unit_sp
+ /// The execution unit.
+ ///
+ /// @param[in] exe_ctx
+ /// The execution context to use when running them. Thread can't be null.
+ ///
+ /// @return
+ /// The error code indicating the
+ //------------------------------------------------------------------
+ Error RunStaticInitializers(lldb::IRExecutionUnitSP &execution_unit_sp,
+ ExecutionContext &exe_ctx);
+
+ //------------------------------------------------------------------
+ /// Returns a string representing current ABI.
+ ///
+ /// @param[in] target_arch
+ /// The target architecture.
+ ///
+ /// @return
+ /// A string representing target ABI for the current architecture.
+ //-------------------------------------------------------------------
+ std::string GetClangTargetABI(const ArchSpec &target_arch);
- //------------------------------------------------------------------
- /// Returns a string representing current ABI.
- ///
- /// @param[in] target_arch
- /// The target architecture.
- ///
- /// @return
- /// A string representing target ABI for the current architecture.
- //-------------------------------------------------------------------
- std::string
- GetClangTargetABI (const ArchSpec &target_arch);
-
private:
- std::unique_ptr<llvm::LLVMContext> m_llvm_context; ///< The LLVM context to generate IR into
- std::unique_ptr<clang::FileManager> m_file_manager; ///< The Clang file manager object used by the compiler
- std::unique_ptr<clang::CompilerInstance> m_compiler; ///< The Clang compiler used to parse expressions into IR
- std::unique_ptr<clang::Builtin::Context> m_builtin_context; ///< Context for Clang built-ins
- std::unique_ptr<clang::SelectorTable> m_selector_table; ///< Selector table for Objective-C methods
- std::unique_ptr<clang::CodeGenerator> m_code_generator; ///< The Clang object that generates IR
-
- class LLDBPreprocessorCallbacks;
- LLDBPreprocessorCallbacks *m_pp_callbacks; ///< Called when the preprocessor encounters module imports
- std::unique_ptr<ClangASTContext> m_ast_context;
+ std::unique_ptr<llvm::LLVMContext>
+ m_llvm_context; ///< The LLVM context to generate IR into
+ std::unique_ptr<clang::FileManager>
+ m_file_manager; ///< The Clang file manager object used by the compiler
+ std::unique_ptr<clang::CompilerInstance>
+ m_compiler; ///< The Clang compiler used to parse expressions into IR
+ std::unique_ptr<clang::Builtin::Context>
+ m_builtin_context; ///< Context for Clang built-ins
+ std::unique_ptr<clang::SelectorTable>
+ m_selector_table; ///< Selector table for Objective-C methods
+ std::unique_ptr<clang::CodeGenerator>
+ m_code_generator; ///< The Clang object that generates IR
+
+ class LLDBPreprocessorCallbacks;
+ LLDBPreprocessorCallbacks *m_pp_callbacks; ///< Called when the preprocessor
+ ///encounters module imports
+ std::unique_ptr<ClangASTContext> m_ast_context;
};
-
}
-#endif // liblldb_ClangExpressionParser_h_
+#endif // liblldb_ClangExpressionParser_h_
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.cpp
index 908546b3ecd..ee0c0318256 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.cpp
@@ -9,7 +9,6 @@
#include "ClangExpressionVariable.h"
-#include "clang/AST/ASTContext.h"
#include "lldb/Core/ConstString.h"
#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/Stream.h"
@@ -17,60 +16,54 @@
#include "lldb/Core/ValueObjectConstResult.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Process.h"
+#include "clang/AST/ASTContext.h"
using namespace lldb_private;
using namespace clang;
const char *g_clang_expression_variable_kind_name = "ClangExpressionVariable";
-ClangExpressionVariable::ClangExpressionVariable(ExecutionContextScope *exe_scope, lldb::ByteOrder byte_order, uint32_t addr_byte_size) :
- ExpressionVariable(LLVMCastKind::eKindClang),
- m_parser_vars(),
- m_jit_vars ()
-{
- m_flags = EVNone;
- m_frozen_sp = ValueObjectConstResult::Create (exe_scope, byte_order, addr_byte_size);
+ClangExpressionVariable::ClangExpressionVariable(
+ ExecutionContextScope *exe_scope, lldb::ByteOrder byte_order,
+ uint32_t addr_byte_size)
+ : ExpressionVariable(LLVMCastKind::eKindClang), m_parser_vars(),
+ m_jit_vars() {
+ m_flags = EVNone;
+ m_frozen_sp =
+ ValueObjectConstResult::Create(exe_scope, byte_order, addr_byte_size);
}
-ClangExpressionVariable::ClangExpressionVariable (ExecutionContextScope *exe_scope,
- Value &value,
- const ConstString &name,
- uint16_t flags) :
- ExpressionVariable(LLVMCastKind::eKindClang),
- m_parser_vars(),
- m_jit_vars ()
-{
- m_flags = flags;
- m_frozen_sp = ValueObjectConstResult::Create (exe_scope, value, name);
+ClangExpressionVariable::ClangExpressionVariable(
+ ExecutionContextScope *exe_scope, Value &value, const ConstString &name,
+ uint16_t flags)
+ : ExpressionVariable(LLVMCastKind::eKindClang), m_parser_vars(),
+ m_jit_vars() {
+ m_flags = flags;
+ m_frozen_sp = ValueObjectConstResult::Create(exe_scope, value, name);
}
-ClangExpressionVariable::ClangExpressionVariable (const lldb::ValueObjectSP &valobj_sp) :
- ExpressionVariable(LLVMCastKind::eKindClang),
- m_parser_vars(),
- m_jit_vars ()
-{
- m_flags = EVNone;
- m_frozen_sp = valobj_sp;
+ClangExpressionVariable::ClangExpressionVariable(
+ const lldb::ValueObjectSP &valobj_sp)
+ : ExpressionVariable(LLVMCastKind::eKindClang), m_parser_vars(),
+ m_jit_vars() {
+ m_flags = EVNone;
+ m_frozen_sp = valobj_sp;
}
-ClangExpressionVariable::ClangExpressionVariable(ExecutionContextScope *exe_scope,
- const ConstString &name,
- const TypeFromUser& user_type,
- lldb::ByteOrder byte_order,
- uint32_t addr_byte_size) :
- ExpressionVariable(LLVMCastKind::eKindClang),
- m_parser_vars(),
- m_jit_vars()
-{
- m_flags = EVNone;
- m_frozen_sp = ValueObjectConstResult::Create (exe_scope, byte_order, addr_byte_size);
- SetName (name);
- SetCompilerType (user_type);
+ClangExpressionVariable::ClangExpressionVariable(
+ ExecutionContextScope *exe_scope, const ConstString &name,
+ const TypeFromUser &user_type, lldb::ByteOrder byte_order,
+ uint32_t addr_byte_size)
+ : ExpressionVariable(LLVMCastKind::eKindClang), m_parser_vars(),
+ m_jit_vars() {
+ m_flags = EVNone;
+ m_frozen_sp =
+ ValueObjectConstResult::Create(exe_scope, byte_order, addr_byte_size);
+ SetName(name);
+ SetCompilerType(user_type);
}
-TypeFromUser
-ClangExpressionVariable::GetTypeFromUser()
-{
- TypeFromUser tfu (m_frozen_sp->GetCompilerType());
- return tfu;
+TypeFromUser ClangExpressionVariable::GetTypeFromUser() {
+ TypeFromUser tfu(m_frozen_sp->GetCompilerType());
+ return tfu;
}
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.h b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.h
index a4596148f6c..c894506a227 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.h
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.h
@@ -24,15 +24,15 @@
#include "llvm/Support/Casting.h"
// Project includes
-#include "lldb/lldb-public.h"
#include "lldb/Core/ClangForward.h"
#include "lldb/Core/ConstString.h"
#include "lldb/Core/Value.h"
#include "lldb/Expression/ExpressionVariable.h"
#include "lldb/Symbol/TaggedASTType.h"
+#include "lldb/lldb-public.h"
namespace llvm {
- class Value;
+class Value;
}
namespace lldb_private {
@@ -40,7 +40,8 @@ namespace lldb_private {
class ValueObjectConstResult;
//----------------------------------------------------------------------
-/// @class ClangExpressionVariable ClangExpressionVariable.h "lldb/Expression/ClangExpressionVariable.h"
+/// @class ClangExpressionVariable ClangExpressionVariable.h
+/// "lldb/Expression/ClangExpressionVariable.h"
/// @brief Encapsulates one variable for the expression parser.
///
/// The expression parser uses variables in three different contexts:
@@ -62,204 +63,178 @@ class ValueObjectConstResult;
/// polymorphism, and provides necessary support methods. Its interface
/// is RTTI-neutral.
//----------------------------------------------------------------------
-class ClangExpressionVariable : public ExpressionVariable
-{
+class ClangExpressionVariable : public ExpressionVariable {
public:
- ClangExpressionVariable(ExecutionContextScope *exe_scope, lldb::ByteOrder byte_order, uint32_t addr_byte_size);
-
- ClangExpressionVariable (ExecutionContextScope *exe_scope,
- Value &value,
- const ConstString &name,
- uint16_t flags = EVNone);
-
- ClangExpressionVariable(const lldb::ValueObjectSP &valobj_sp);
-
- ClangExpressionVariable(ExecutionContextScope *exe_scope,
- const ConstString &name,
- const TypeFromUser& user_type,
- lldb::ByteOrder byte_order,
- uint32_t addr_byte_size);
-
- //----------------------------------------------------------------------
- /// Utility functions for dealing with ExpressionVariableLists in Clang-specific ways
- //----------------------------------------------------------------------
-
- //----------------------------------------------------------------------
- /// Finds a variable by NamedDecl in the list.
- ///
- /// @param[in] name
- /// The name of the requested variable.
- ///
- /// @return
- /// The variable requested, or NULL if that variable is not in the list.
- //----------------------------------------------------------------------
- static ClangExpressionVariable *
- FindVariableInList (ExpressionVariableList &list, const clang::NamedDecl *decl, uint64_t parser_id)
- {
- lldb::ExpressionVariableSP var_sp;
- for (size_t index = 0, size = list.GetSize(); index < size; ++index)
- {
- var_sp = list.GetVariableAtIndex(index);
-
- if (ClangExpressionVariable *clang_var = llvm::dyn_cast<ClangExpressionVariable>(var_sp.get()))
- {
- ClangExpressionVariable::ParserVars *parser_vars = clang_var->GetParserVars(parser_id);
-
- if (parser_vars && parser_vars->m_named_decl == decl)
- return clang_var;
- }
- }
- return nullptr;
+ ClangExpressionVariable(ExecutionContextScope *exe_scope,
+ lldb::ByteOrder byte_order, uint32_t addr_byte_size);
+
+ ClangExpressionVariable(ExecutionContextScope *exe_scope, Value &value,
+ const ConstString &name, uint16_t flags = EVNone);
+
+ ClangExpressionVariable(const lldb::ValueObjectSP &valobj_sp);
+
+ ClangExpressionVariable(ExecutionContextScope *exe_scope,
+ const ConstString &name,
+ const TypeFromUser &user_type,
+ lldb::ByteOrder byte_order, uint32_t addr_byte_size);
+
+ //----------------------------------------------------------------------
+ /// Utility functions for dealing with ExpressionVariableLists in
+ /// Clang-specific ways
+ //----------------------------------------------------------------------
+
+ //----------------------------------------------------------------------
+ /// Finds a variable by NamedDecl in the list.
+ ///
+ /// @param[in] name
+ /// The name of the requested variable.
+ ///
+ /// @return
+ /// The variable requested, or NULL if that variable is not in the list.
+ //----------------------------------------------------------------------
+ static ClangExpressionVariable *
+ FindVariableInList(ExpressionVariableList &list, const clang::NamedDecl *decl,
+ uint64_t parser_id) {
+ lldb::ExpressionVariableSP var_sp;
+ for (size_t index = 0, size = list.GetSize(); index < size; ++index) {
+ var_sp = list.GetVariableAtIndex(index);
+
+ if (ClangExpressionVariable *clang_var =
+ llvm::dyn_cast<ClangExpressionVariable>(var_sp.get())) {
+ ClangExpressionVariable::ParserVars *parser_vars =
+ clang_var->GetParserVars(parser_id);
+
+ if (parser_vars && parser_vars->m_named_decl == decl)
+ return clang_var;
+ }
}
+ return nullptr;
+ }
+
+ //----------------------------------------------------------------------
+ /// If the variable contains its own data, make a Value point at it.
+ /// If \a exe_ctx in not NULL, the value will be resolved in with
+ /// that execution context.
+ ///
+ /// @param[in] value
+ /// The value to point at the data.
+ ///
+ /// @param[in] exe_ctx
+ /// The execution context to use to resolve \a value.
+ ///
+ /// @return
+ /// True on success; false otherwise (in particular, if this variable
+ /// does not contain its own data).
+ //----------------------------------------------------------------------
+ bool PointValueAtData(Value &value, ExecutionContext *exe_ctx);
+
+ //----------------------------------------------------------------------
+ /// The following values should not live beyond parsing
+ //----------------------------------------------------------------------
+ class ParserVars {
+ public:
+ ParserVars()
+ : m_parser_type(), m_named_decl(NULL), m_llvm_value(NULL),
+ m_lldb_value(), m_lldb_var(), m_lldb_sym(NULL) {}
+
+ TypeFromParser
+ m_parser_type; ///< The type of the variable according to the parser
+ const clang::NamedDecl
+ *m_named_decl; ///< The Decl corresponding to this variable
+ llvm::Value *m_llvm_value; ///< The IR value corresponding to this variable;
+ ///usually a GlobalValue
+ lldb_private::Value
+ m_lldb_value; ///< The value found in LLDB for this variable
+ lldb::VariableSP m_lldb_var; ///< The original variable for this variable
+ const lldb_private::Symbol *m_lldb_sym; ///< The original symbol for this
+ ///variable, if it was a symbol
+ };
- //----------------------------------------------------------------------
- /// If the variable contains its own data, make a Value point at it.
- /// If \a exe_ctx in not NULL, the value will be resolved in with
- /// that execution context.
- ///
- /// @param[in] value
- /// The value to point at the data.
- ///
- /// @param[in] exe_ctx
- /// The execution context to use to resolve \a value.
- ///
- /// @return
- /// True on success; false otherwise (in particular, if this variable
- /// does not contain its own data).
- //----------------------------------------------------------------------
- bool
- PointValueAtData(Value &value, ExecutionContext *exe_ctx);
-
- //----------------------------------------------------------------------
- /// The following values should not live beyond parsing
- //----------------------------------------------------------------------
- class ParserVars
- {
- public:
-
- ParserVars() :
- m_parser_type(),
- m_named_decl (NULL),
- m_llvm_value (NULL),
- m_lldb_value (),
- m_lldb_var (),
- m_lldb_sym (NULL)
- {
- }
-
- TypeFromParser m_parser_type; ///< The type of the variable according to the parser
- const clang::NamedDecl *m_named_decl; ///< The Decl corresponding to this variable
- llvm::Value *m_llvm_value; ///< The IR value corresponding to this variable; usually a GlobalValue
- lldb_private::Value m_lldb_value; ///< The value found in LLDB for this variable
- lldb::VariableSP m_lldb_var; ///< The original variable for this variable
- const lldb_private::Symbol *m_lldb_sym; ///< The original symbol for this variable, if it was a symbol
- };
-
private:
- typedef std::map <uint64_t, ParserVars> ParserVarMap;
- ParserVarMap m_parser_vars;
+ typedef std::map<uint64_t, ParserVars> ParserVarMap;
+ ParserVarMap m_parser_vars;
public:
- //----------------------------------------------------------------------
- /// Make this variable usable by the parser by allocating space for
- /// parser-specific variables
- //----------------------------------------------------------------------
- void
- EnableParserVars(uint64_t parser_id)
- {
- m_parser_vars.insert(std::make_pair(parser_id, ParserVars()));
- }
-
- //----------------------------------------------------------------------
- /// Deallocate parser-specific variables
- //----------------------------------------------------------------------
- void
- DisableParserVars(uint64_t parser_id)
- {
- m_parser_vars.erase(parser_id);
- }
-
- //----------------------------------------------------------------------
- /// Access parser-specific variables
- //----------------------------------------------------------------------
- ParserVars *
- GetParserVars(uint64_t parser_id)
- {
- ParserVarMap::iterator i = m_parser_vars.find(parser_id);
-
- if (i == m_parser_vars.end())
- return NULL;
- else
- return &i->second;
- }
-
- //----------------------------------------------------------------------
- /// The following values are valid if the variable is used by JIT code
- //----------------------------------------------------------------------
- struct JITVars {
- JITVars () :
- m_alignment (0),
- m_size (0),
- m_offset (0)
- {
- }
-
- lldb::offset_t m_alignment; ///< The required alignment of the variable, in bytes
- size_t m_size; ///< The space required for the variable, in bytes
- lldb::offset_t m_offset; ///< The offset of the variable in the struct, in bytes
- };
-
+ //----------------------------------------------------------------------
+ /// Make this variable usable by the parser by allocating space for
+ /// parser-specific variables
+ //----------------------------------------------------------------------
+ void EnableParserVars(uint64_t parser_id) {
+ m_parser_vars.insert(std::make_pair(parser_id, ParserVars()));
+ }
+
+ //----------------------------------------------------------------------
+ /// Deallocate parser-specific variables
+ //----------------------------------------------------------------------
+ void DisableParserVars(uint64_t parser_id) { m_parser_vars.erase(parser_id); }
+
+ //----------------------------------------------------------------------
+ /// Access parser-specific variables
+ //----------------------------------------------------------------------
+ ParserVars *GetParserVars(uint64_t parser_id) {
+ ParserVarMap::iterator i = m_parser_vars.find(parser_id);
+
+ if (i == m_parser_vars.end())
+ return NULL;
+ else
+ return &i->second;
+ }
+
+ //----------------------------------------------------------------------
+ /// The following values are valid if the variable is used by JIT code
+ //----------------------------------------------------------------------
+ struct JITVars {
+ JITVars() : m_alignment(0), m_size(0), m_offset(0) {}
+
+ lldb::offset_t
+ m_alignment; ///< The required alignment of the variable, in bytes
+ size_t m_size; ///< The space required for the variable, in bytes
+ lldb::offset_t
+ m_offset; ///< The offset of the variable in the struct, in bytes
+ };
+
private:
- typedef std::map <uint64_t, JITVars> JITVarMap;
- JITVarMap m_jit_vars;
-
+ typedef std::map<uint64_t, JITVars> JITVarMap;
+ JITVarMap m_jit_vars;
+
public:
- //----------------------------------------------------------------------
- /// Make this variable usable for materializing for the JIT by allocating
- /// space for JIT-specific variables
- //----------------------------------------------------------------------
- void
- EnableJITVars(uint64_t parser_id)
- {
- m_jit_vars.insert(std::make_pair(parser_id, JITVars()));
- }
-
- //----------------------------------------------------------------------
- /// Deallocate JIT-specific variables
- //----------------------------------------------------------------------
- void
- DisableJITVars(uint64_t parser_id)
- {
- m_jit_vars.erase(parser_id);
- }
-
- JITVars *GetJITVars(uint64_t parser_id)
- {
- JITVarMap::iterator i = m_jit_vars.find(parser_id);
-
- if (i == m_jit_vars.end())
- return NULL;
- else
- return &i->second;
- }
-
- TypeFromUser
- GetTypeFromUser ();
-
- //------------------------------------------------------------------
- // llvm casting support
- //------------------------------------------------------------------
- static bool classof(const ExpressionVariable *ev)
- {
- return ev->getKind() == ExpressionVariable::eKindClang;
- }
-
- //----------------------------------------------------------------------
- /// Members
- //----------------------------------------------------------------------
- DISALLOW_COPY_AND_ASSIGN (ClangExpressionVariable);
+ //----------------------------------------------------------------------
+ /// Make this variable usable for materializing for the JIT by allocating
+ /// space for JIT-specific variables
+ //----------------------------------------------------------------------
+ void EnableJITVars(uint64_t parser_id) {
+ m_jit_vars.insert(std::make_pair(parser_id, JITVars()));
+ }
+
+ //----------------------------------------------------------------------
+ /// Deallocate JIT-specific variables
+ //----------------------------------------------------------------------
+ void DisableJITVars(uint64_t parser_id) { m_jit_vars.erase(parser_id); }
+
+ JITVars *GetJITVars(uint64_t parser_id) {
+ JITVarMap::iterator i = m_jit_vars.find(parser_id);
+
+ if (i == m_jit_vars.end())
+ return NULL;
+ else
+ return &i->second;
+ }
+
+ TypeFromUser GetTypeFromUser();
+
+ //------------------------------------------------------------------
+ // llvm casting support
+ //------------------------------------------------------------------
+ static bool classof(const ExpressionVariable *ev) {
+ return ev->getKind() == ExpressionVariable::eKindClang;
+ }
+
+ //----------------------------------------------------------------------
+ /// Members
+ //----------------------------------------------------------------------
+ DISALLOW_COPY_AND_ASSIGN(ClangExpressionVariable);
};
} // namespace lldb_private
-#endif // liblldb_ClangExpressionVariable_h_
+#endif // liblldb_ClangExpressionVariable_h_
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp
index 02c0ad5013e..87d77386782 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp
@@ -50,178 +50,177 @@ using namespace lldb_private;
//----------------------------------------------------------------------
// ClangFunctionCaller constructor
//----------------------------------------------------------------------
-ClangFunctionCaller::ClangFunctionCaller
-(
- ExecutionContextScope &exe_scope,
- const CompilerType &return_type,
- const Address& functionAddress,
- const ValueList &arg_value_list,
- const char *name
-) :
- FunctionCaller(exe_scope, return_type, functionAddress, arg_value_list, name),
- m_type_system_helper (*this)
-{
- m_jit_process_wp = lldb::ProcessWP(exe_scope.CalculateProcess());
- // Can't make a ClangFunctionCaller without a process.
- assert (m_jit_process_wp.lock());
+ClangFunctionCaller::ClangFunctionCaller(ExecutionContextScope &exe_scope,
+ const CompilerType &return_type,
+ const Address &functionAddress,
+ const ValueList &arg_value_list,
+ const char *name)
+ : FunctionCaller(exe_scope, return_type, functionAddress, arg_value_list,
+ name),
+ m_type_system_helper(*this) {
+ m_jit_process_wp = lldb::ProcessWP(exe_scope.CalculateProcess());
+ // Can't make a ClangFunctionCaller without a process.
+ assert(m_jit_process_wp.lock());
}
//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
-ClangFunctionCaller::~ClangFunctionCaller()
-{
-}
+ClangFunctionCaller::~ClangFunctionCaller() {}
unsigned
-ClangFunctionCaller::CompileFunction (lldb::ThreadSP thread_to_use_sp,
- DiagnosticManager &diagnostic_manager)
-{
- if (m_compiled)
- return 0;
-
- // Compilation might call code, make sure to keep on the thread the caller indicated.
- ThreadList::ExpressionExecutionThreadPusher execution_thread_pusher(thread_to_use_sp);
-
- // FIXME: How does clang tell us there's no return value? We need to handle that case.
- unsigned num_errors = 0;
-
- std::string return_type_str (m_function_return_type.GetTypeName().AsCString(""));
-
- // Cons up the function we're going to wrap our call in, then compile it...
- // We declare the function "extern "C"" because the compiler might be in C++
- // mode which would mangle the name and then we couldn't find it again...
- m_wrapper_function_text.clear();
- m_wrapper_function_text.append ("extern \"C\" void ");
- m_wrapper_function_text.append (m_wrapper_function_name);
- m_wrapper_function_text.append (" (void *input)\n{\n struct ");
- m_wrapper_function_text.append (m_wrapper_struct_name);
- m_wrapper_function_text.append (" \n {\n");
- m_wrapper_function_text.append (" ");
- m_wrapper_function_text.append (return_type_str);
- m_wrapper_function_text.append (" (*fn_ptr) (");
-
- // Get the number of arguments. If we have a function type and it is prototyped,
- // trust that, otherwise use the values we were given.
-
- // FIXME: This will need to be extended to handle Variadic functions. We'll need
- // to pull the defined arguments out of the function, then add the types from the
- // arguments list for the variable arguments.
-
- uint32_t num_args = UINT32_MAX;
- bool trust_function = false;
- // GetArgumentCount returns -1 for an unprototyped function.
- CompilerType function_clang_type;
- if (m_function_ptr)
- {
- function_clang_type = m_function_ptr->GetCompilerType();
- if (function_clang_type)
- {
- int num_func_args = function_clang_type.GetFunctionArgumentCount();
- if (num_func_args >= 0)
- {
- trust_function = true;
- num_args = num_func_args;
- }
- }
- }
-
- if (num_args == UINT32_MAX)
- num_args = m_arg_values.GetSize();
-
- std::string args_buffer; // This one stores the definition of all the args in "struct caller".
- std::string args_list_buffer; // This one stores the argument list called from the structure.
- for (size_t i = 0; i < num_args; i++)
- {
- std::string type_name;
-
- if (trust_function)
- {
- type_name = function_clang_type.GetFunctionArgumentTypeAtIndex(i).GetTypeName().AsCString("");
- }
- else
- {
- CompilerType clang_qual_type = m_arg_values.GetValueAtIndex(i)->GetCompilerType ();
- if (clang_qual_type)
- {
- type_name = clang_qual_type.GetTypeName().AsCString("");
- }
- else
- {
- diagnostic_manager.Printf(eDiagnosticSeverityError,
- "Could not determine type of input value %" PRIu64 ".", (uint64_t)i);
- return 1;
- }
- }
-
- m_wrapper_function_text.append (type_name);
- if (i < num_args - 1)
- m_wrapper_function_text.append (", ");
-
- char arg_buf[32];
- args_buffer.append (" ");
- args_buffer.append (type_name);
- snprintf(arg_buf, 31, "arg_%" PRIu64, (uint64_t)i);
- args_buffer.push_back (' ');
- args_buffer.append (arg_buf);
- args_buffer.append (";\n");
-
- args_list_buffer.append ("__lldb_fn_data->");
- args_list_buffer.append (arg_buf);
- if (i < num_args - 1)
- args_list_buffer.append (", ");
-
+ClangFunctionCaller::CompileFunction(lldb::ThreadSP thread_to_use_sp,
+ DiagnosticManager &diagnostic_manager) {
+ if (m_compiled)
+ return 0;
+
+ // Compilation might call code, make sure to keep on the thread the caller
+ // indicated.
+ ThreadList::ExpressionExecutionThreadPusher execution_thread_pusher(
+ thread_to_use_sp);
+
+ // FIXME: How does clang tell us there's no return value? We need to handle
+ // that case.
+ unsigned num_errors = 0;
+
+ std::string return_type_str(
+ m_function_return_type.GetTypeName().AsCString(""));
+
+ // Cons up the function we're going to wrap our call in, then compile it...
+ // We declare the function "extern "C"" because the compiler might be in C++
+ // mode which would mangle the name and then we couldn't find it again...
+ m_wrapper_function_text.clear();
+ m_wrapper_function_text.append("extern \"C\" void ");
+ m_wrapper_function_text.append(m_wrapper_function_name);
+ m_wrapper_function_text.append(" (void *input)\n{\n struct ");
+ m_wrapper_function_text.append(m_wrapper_struct_name);
+ m_wrapper_function_text.append(" \n {\n");
+ m_wrapper_function_text.append(" ");
+ m_wrapper_function_text.append(return_type_str);
+ m_wrapper_function_text.append(" (*fn_ptr) (");
+
+ // Get the number of arguments. If we have a function type and it is
+ // prototyped,
+ // trust that, otherwise use the values we were given.
+
+ // FIXME: This will need to be extended to handle Variadic functions. We'll
+ // need
+ // to pull the defined arguments out of the function, then add the types from
+ // the
+ // arguments list for the variable arguments.
+
+ uint32_t num_args = UINT32_MAX;
+ bool trust_function = false;
+ // GetArgumentCount returns -1 for an unprototyped function.
+ CompilerType function_clang_type;
+ if (m_function_ptr) {
+ function_clang_type = m_function_ptr->GetCompilerType();
+ if (function_clang_type) {
+ int num_func_args = function_clang_type.GetFunctionArgumentCount();
+ if (num_func_args >= 0) {
+ trust_function = true;
+ num_args = num_func_args;
+ }
}
- m_wrapper_function_text.append (");\n"); // Close off the function calling prototype.
-
- m_wrapper_function_text.append (args_buffer);
-
- m_wrapper_function_text.append (" ");
- m_wrapper_function_text.append (return_type_str);
- m_wrapper_function_text.append (" return_value;");
- m_wrapper_function_text.append ("\n };\n struct ");
- m_wrapper_function_text.append (m_wrapper_struct_name);
- m_wrapper_function_text.append ("* __lldb_fn_data = (struct ");
- m_wrapper_function_text.append (m_wrapper_struct_name);
- m_wrapper_function_text.append (" *) input;\n");
-
- m_wrapper_function_text.append (" __lldb_fn_data->return_value = __lldb_fn_data->fn_ptr (");
- m_wrapper_function_text.append (args_list_buffer);
- m_wrapper_function_text.append (");\n}\n");
-
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
- if (log)
- log->Printf ("Expression: \n\n%s\n\n", m_wrapper_function_text.c_str());
-
- // Okay, now compile this expression
-
- lldb::ProcessSP jit_process_sp(m_jit_process_wp.lock());
- if (jit_process_sp)
- {
- const bool generate_debug_info = true;
- m_parser.reset(new ClangExpressionParser(jit_process_sp.get(), *this, generate_debug_info));
-
- num_errors = m_parser->Parse(diagnostic_manager);
+ }
+
+ if (num_args == UINT32_MAX)
+ num_args = m_arg_values.GetSize();
+
+ std::string args_buffer; // This one stores the definition of all the args in
+ // "struct caller".
+ std::string args_list_buffer; // This one stores the argument list called from
+ // the structure.
+ for (size_t i = 0; i < num_args; i++) {
+ std::string type_name;
+
+ if (trust_function) {
+ type_name = function_clang_type.GetFunctionArgumentTypeAtIndex(i)
+ .GetTypeName()
+ .AsCString("");
+ } else {
+ CompilerType clang_qual_type =
+ m_arg_values.GetValueAtIndex(i)->GetCompilerType();
+ if (clang_qual_type) {
+ type_name = clang_qual_type.GetTypeName().AsCString("");
+ } else {
+ diagnostic_manager.Printf(
+ eDiagnosticSeverityError,
+ "Could not determine type of input value %" PRIu64 ".",
+ (uint64_t)i);
+ return 1;
+ }
}
- else
- {
- diagnostic_manager.PutCString(eDiagnosticSeverityError, "no process - unable to inject function");
- num_errors = 1;
- }
-
- m_compiled = (num_errors == 0);
-
- if (!m_compiled)
- return num_errors;
+ m_wrapper_function_text.append(type_name);
+ if (i < num_args - 1)
+ m_wrapper_function_text.append(", ");
+
+ char arg_buf[32];
+ args_buffer.append(" ");
+ args_buffer.append(type_name);
+ snprintf(arg_buf, 31, "arg_%" PRIu64, (uint64_t)i);
+ args_buffer.push_back(' ');
+ args_buffer.append(arg_buf);
+ args_buffer.append(";\n");
+
+ args_list_buffer.append("__lldb_fn_data->");
+ args_list_buffer.append(arg_buf);
+ if (i < num_args - 1)
+ args_list_buffer.append(", ");
+ }
+ m_wrapper_function_text.append(
+ ");\n"); // Close off the function calling prototype.
+
+ m_wrapper_function_text.append(args_buffer);
+
+ m_wrapper_function_text.append(" ");
+ m_wrapper_function_text.append(return_type_str);
+ m_wrapper_function_text.append(" return_value;");
+ m_wrapper_function_text.append("\n };\n struct ");
+ m_wrapper_function_text.append(m_wrapper_struct_name);
+ m_wrapper_function_text.append("* __lldb_fn_data = (struct ");
+ m_wrapper_function_text.append(m_wrapper_struct_name);
+ m_wrapper_function_text.append(" *) input;\n");
+
+ m_wrapper_function_text.append(
+ " __lldb_fn_data->return_value = __lldb_fn_data->fn_ptr (");
+ m_wrapper_function_text.append(args_list_buffer);
+ m_wrapper_function_text.append(");\n}\n");
+
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+ if (log)
+ log->Printf("Expression: \n\n%s\n\n", m_wrapper_function_text.c_str());
+
+ // Okay, now compile this expression
+
+ lldb::ProcessSP jit_process_sp(m_jit_process_wp.lock());
+ if (jit_process_sp) {
+ const bool generate_debug_info = true;
+ m_parser.reset(new ClangExpressionParser(jit_process_sp.get(), *this,
+ generate_debug_info));
+
+ num_errors = m_parser->Parse(diagnostic_manager);
+ } else {
+ diagnostic_manager.PutCString(eDiagnosticSeverityError,
+ "no process - unable to inject function");
+ num_errors = 1;
+ }
+
+ m_compiled = (num_errors == 0);
+
+ if (!m_compiled)
return num_errors;
+
+ return num_errors;
}
clang::ASTConsumer *
-ClangFunctionCaller::ClangFunctionCallerHelper::ASTTransformer (clang::ASTConsumer *passthrough)
-{
- m_struct_extractor.reset(new ASTStructExtractor(passthrough, m_owner.GetWrapperStructName(), m_owner));
-
- return m_struct_extractor.get();
+ClangFunctionCaller::ClangFunctionCallerHelper::ASTTransformer(
+ clang::ASTConsumer *passthrough) {
+ m_struct_extractor.reset(new ASTStructExtractor(
+ passthrough, m_owner.GetWrapperStructName(), m_owner));
+
+ return m_struct_extractor.get();
}
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.h b/lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.h
index 468b9c1c76d..56d1d8412f7 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.h
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.h
@@ -16,23 +16,23 @@
// Project includes
#include "ClangExpressionHelper.h"
-#include "lldb/Core/ClangForward.h"
#include "lldb/Core/Address.h"
#include "lldb/Core/ArchSpec.h"
+#include "lldb/Core/ClangForward.h"
#include "lldb/Core/Value.h"
#include "lldb/Core/ValueObjectList.h"
#include "lldb/Expression/FunctionCaller.h"
#include "lldb/Symbol/CompilerType.h"
#include "lldb/Target/Process.h"
-namespace lldb_private
-{
-
+namespace lldb_private {
+
class ASTStructExtractor;
class ClangExpressionParser;
//----------------------------------------------------------------------
-/// @class ClangFunctionCaller ClangFunctionCaller.h "lldb/Expression/ClangFunctionCaller.h"
+/// @class ClangFunctionCaller ClangFunctionCaller.h
+/// "lldb/Expression/ClangFunctionCaller.h"
/// @brief Encapsulates a function that can be called.
///
/// A given ClangFunctionCaller object can handle a single function signature.
@@ -42,7 +42,7 @@ class ClangExpressionParser;
/// It performs the call by synthesizing a structure that contains the pointer
/// to the function and the arguments that should be passed to that function,
/// and producing a special-purpose JIT-compiled function that accepts a void*
-/// pointing to this struct as its only argument and calls the function in the
+/// pointing to this struct as its only argument and calls the function in the
/// struct with the written arguments. This method lets Clang handle the
/// vagaries of function calling conventions.
///
@@ -54,124 +54,111 @@ class ClangExpressionParser;
/// InsertFunction() followed by WriteFunctionArguments(), which will return
/// the location of the args struct for the wrapper function in args_addr_ref.
///
-/// If you need to call the function on the thread plan stack, you can also
+/// If you need to call the function on the thread plan stack, you can also
/// call InsertFunction() followed by GetThreadPlanToCallFunction().
///
/// Any of the methods that take arg_addr_ptr or arg_addr_ref can be passed
/// a pointer set to LLDB_INVALID_ADDRESS and new structure will be allocated
/// and its address returned in that variable.
-///
+///
/// Any of the methods that take arg_addr_ptr can be passed NULL, and the
/// argument space will be managed for you.
-//----------------------------------------------------------------------
-class ClangFunctionCaller : public FunctionCaller
-{
- friend class ASTStructExtractor;
-
- class ClangFunctionCallerHelper : public ClangExpressionHelper
- {
- public:
- ClangFunctionCallerHelper (ClangFunctionCaller &owner) :
- m_owner(owner)
- {
- }
-
- ~ClangFunctionCallerHelper() override = default;
-
- //------------------------------------------------------------------
- /// Return the object that the parser should use when resolving external
- /// values. May be NULL if everything should be self-contained.
- //------------------------------------------------------------------
- ClangExpressionDeclMap *
- DeclMap() override
- {
- return NULL;
- }
-
- //------------------------------------------------------------------
- /// Return the object that the parser should allow to access ASTs.
- /// May be NULL if the ASTs do not need to be transformed.
- ///
- /// @param[in] passthrough
- /// The ASTConsumer that the returned transformer should send
- /// the ASTs to after transformation.
- //------------------------------------------------------------------
- clang::ASTConsumer *
- ASTTransformer(clang::ASTConsumer *passthrough) override;
-
- private:
- ClangFunctionCaller &m_owner;
- std::unique_ptr<ASTStructExtractor> m_struct_extractor; ///< The class that generates the argument struct layout.
- };
+//----------------------------------------------------------------------
+class ClangFunctionCaller : public FunctionCaller {
+ friend class ASTStructExtractor;
+
+ class ClangFunctionCallerHelper : public ClangExpressionHelper {
+ public:
+ ClangFunctionCallerHelper(ClangFunctionCaller &owner) : m_owner(owner) {}
+
+ ~ClangFunctionCallerHelper() override = default;
-public:
//------------------------------------------------------------------
- /// Constructor
- ///
- /// @param[in] exe_scope
- /// An execution context scope that gets us at least a target and
- /// process.
- ///
- /// @param[in] ast_context
- /// The AST context to evaluate argument types in.
- ///
- /// @param[in] return_qualtype
- /// An opaque Clang QualType for the function result. Should be
- /// defined in ast_context.
- ///
- /// @param[in] function_address
- /// The address of the function to call.
- ///
- /// @param[in] arg_value_list
- /// The default values to use when calling this function. Can
- /// be overridden using WriteFunctionArguments().
+ /// Return the object that the parser should use when resolving external
+ /// values. May be NULL if everything should be self-contained.
//------------------------------------------------------------------
- ClangFunctionCaller (ExecutionContextScope &exe_scope,
- const CompilerType &return_type,
- const Address& function_address,
- const ValueList &arg_value_list,
- const char *name);
-
- ~ClangFunctionCaller() override;
+ ClangExpressionDeclMap *DeclMap() override { return NULL; }
//------------------------------------------------------------------
- /// Compile the wrapper function
- ///
- /// @param[in] thread_to_use_sp
- /// Compilation might end up calling functions. Pass in the thread you
- /// want the compilation to use. If you pass in an empty ThreadSP it will
- /// use the currently selected thread.
+ /// Return the object that the parser should allow to access ASTs.
+ /// May be NULL if the ASTs do not need to be transformed.
///
- /// @param[in] diagnostic_manager
- /// The diagnostic manager to report parser errors to.
- ///
- /// @return
- /// The number of errors.
+ /// @param[in] passthrough
+ /// The ASTConsumer that the returned transformer should send
+ /// the ASTs to after transformation.
//------------------------------------------------------------------
- unsigned
- CompileFunction (lldb::ThreadSP thread_to_use_sp,
- DiagnosticManager &diagnostic_manager) override;
+ clang::ASTConsumer *
+ ASTTransformer(clang::ASTConsumer *passthrough) override;
+
+ private:
+ ClangFunctionCaller &m_owner;
+ std::unique_ptr<ASTStructExtractor> m_struct_extractor; ///< The class that
+ ///generates the
+ ///argument struct
+ ///layout.
+ };
- ExpressionTypeSystemHelper *
- GetTypeSystemHelper() override
- {
- return &m_type_system_helper;
- }
+public:
+ //------------------------------------------------------------------
+ /// Constructor
+ ///
+ /// @param[in] exe_scope
+ /// An execution context scope that gets us at least a target and
+ /// process.
+ ///
+ /// @param[in] ast_context
+ /// The AST context to evaluate argument types in.
+ ///
+ /// @param[in] return_qualtype
+ /// An opaque Clang QualType for the function result. Should be
+ /// defined in ast_context.
+ ///
+ /// @param[in] function_address
+ /// The address of the function to call.
+ ///
+ /// @param[in] arg_value_list
+ /// The default values to use when calling this function. Can
+ /// be overridden using WriteFunctionArguments().
+ //------------------------------------------------------------------
+ ClangFunctionCaller(ExecutionContextScope &exe_scope,
+ const CompilerType &return_type,
+ const Address &function_address,
+ const ValueList &arg_value_list, const char *name);
+
+ ~ClangFunctionCaller() override;
+
+ //------------------------------------------------------------------
+ /// Compile the wrapper function
+ ///
+ /// @param[in] thread_to_use_sp
+ /// Compilation might end up calling functions. Pass in the thread you
+ /// want the compilation to use. If you pass in an empty ThreadSP it will
+ /// use the currently selected thread.
+ ///
+ /// @param[in] diagnostic_manager
+ /// The diagnostic manager to report parser errors to.
+ ///
+ /// @return
+ /// The number of errors.
+ //------------------------------------------------------------------
+ unsigned CompileFunction(lldb::ThreadSP thread_to_use_sp,
+ DiagnosticManager &diagnostic_manager) override;
+
+ ExpressionTypeSystemHelper *GetTypeSystemHelper() override {
+ return &m_type_system_helper;
+ }
protected:
- const char *GetWrapperStructName()
- {
- return m_wrapper_struct_name.c_str();
- }
+ const char *GetWrapperStructName() { return m_wrapper_struct_name.c_str(); }
private:
- //------------------------------------------------------------------
- // For ClangFunctionCaller only
- //------------------------------------------------------------------
+ //------------------------------------------------------------------
+ // For ClangFunctionCaller only
+ //------------------------------------------------------------------
- // Note: the parser needs to be destructed before the execution unit, so
- // declare the execution unit first.
- ClangFunctionCallerHelper m_type_system_helper;
+ // Note: the parser needs to be destructed before the execution unit, so
+ // declare the execution unit first.
+ ClangFunctionCallerHelper m_type_system_helper;
};
} // namespace lldb_private
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp
index eed63dcc34c..3c21de241c4 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp
@@ -37,700 +37,643 @@
using namespace lldb_private;
namespace {
- // Any Clang compiler requires a consumer for diagnostics. This one stores them as strings
- // so we can provide them to the user in case a module failed to load.
- class StoringDiagnosticConsumer : public clang::DiagnosticConsumer
- {
- public:
- StoringDiagnosticConsumer ();
-
- void
- HandleDiagnostic(clang::DiagnosticsEngine::Level DiagLevel,
- const clang::Diagnostic &info) override;
-
- void
- ClearDiagnostics ();
-
- void
- DumpDiagnostics (Stream &error_stream);
-
- private:
- typedef std::pair<clang::DiagnosticsEngine::Level, std::string> IDAndDiagnostic;
- std::vector<IDAndDiagnostic> m_diagnostics;
- Log * m_log;
- };
-
- // The private implementation of our ClangModulesDeclVendor. Contains all the Clang state required
- // to load modules.
- class ClangModulesDeclVendorImpl : public ClangModulesDeclVendor
- {
- public:
- ClangModulesDeclVendorImpl(llvm::IntrusiveRefCntPtr<clang::DiagnosticsEngine> &diagnostics_engine,
- llvm::IntrusiveRefCntPtr<clang::CompilerInvocation> &compiler_invocation,
- std::unique_ptr<clang::CompilerInstance> &&compiler_instance,
- std::unique_ptr<clang::Parser> &&parser);
-
- ~ClangModulesDeclVendorImpl() override = default;
-
- bool
- AddModule(ModulePath &path,
- ModuleVector *exported_modules,
- Stream &error_stream) override;
-
- bool
- AddModulesForCompileUnit(CompileUnit &cu,
- ModuleVector &exported_modules,
- Stream &error_stream) override;
-
- uint32_t
- FindDecls(const ConstString &name,
- bool append,
- uint32_t max_matches,
- std::vector <clang::NamedDecl*> &decls) override;
-
- void
- ForEachMacro(const ModuleVector &modules,
- std::function<bool (const std::string &)> handler) override;
-
- private:
- void
- ReportModuleExportsHelper (std::set<ClangModulesDeclVendor::ModuleID> &exports,
- clang::Module *module);
-
- void
- ReportModuleExports (ModuleVector &exports,
- clang::Module *module);
-
- clang::ModuleLoadResult
- DoGetModule(clang::ModuleIdPath path, bool make_visible);
-
- bool m_enabled = false;
-
- llvm::IntrusiveRefCntPtr<clang::DiagnosticsEngine> m_diagnostics_engine;
- llvm::IntrusiveRefCntPtr<clang::CompilerInvocation> m_compiler_invocation;
- std::unique_ptr<clang::CompilerInstance> m_compiler_instance;
- std::unique_ptr<clang::Parser> m_parser;
- size_t m_source_location_index = 0; // used to give name components fake SourceLocations
-
- typedef std::vector<ConstString> ImportedModule;
- typedef std::map<ImportedModule, clang::Module *> ImportedModuleMap;
- typedef std::set<ModuleID> ImportedModuleSet;
- ImportedModuleMap m_imported_modules;
- ImportedModuleSet m_user_imported_modules;
- };
+// Any Clang compiler requires a consumer for diagnostics. This one stores them
+// as strings
+// so we can provide them to the user in case a module failed to load.
+class StoringDiagnosticConsumer : public clang::DiagnosticConsumer {
+public:
+ StoringDiagnosticConsumer();
+
+ void HandleDiagnostic(clang::DiagnosticsEngine::Level DiagLevel,
+ const clang::Diagnostic &info) override;
+
+ void ClearDiagnostics();
+
+ void DumpDiagnostics(Stream &error_stream);
+
+private:
+ typedef std::pair<clang::DiagnosticsEngine::Level, std::string>
+ IDAndDiagnostic;
+ std::vector<IDAndDiagnostic> m_diagnostics;
+ Log *m_log;
+};
+
+// The private implementation of our ClangModulesDeclVendor. Contains all the
+// Clang state required
+// to load modules.
+class ClangModulesDeclVendorImpl : public ClangModulesDeclVendor {
+public:
+ ClangModulesDeclVendorImpl(
+ llvm::IntrusiveRefCntPtr<clang::DiagnosticsEngine> &diagnostics_engine,
+ llvm::IntrusiveRefCntPtr<clang::CompilerInvocation> &compiler_invocation,
+ std::unique_ptr<clang::CompilerInstance> &&compiler_instance,
+ std::unique_ptr<clang::Parser> &&parser);
+
+ ~ClangModulesDeclVendorImpl() override = default;
+
+ bool AddModule(ModulePath &path, ModuleVector *exported_modules,
+ Stream &error_stream) override;
+
+ bool AddModulesForCompileUnit(CompileUnit &cu, ModuleVector &exported_modules,
+ Stream &error_stream) override;
+
+ uint32_t FindDecls(const ConstString &name, bool append, uint32_t max_matches,
+ std::vector<clang::NamedDecl *> &decls) override;
+
+ void ForEachMacro(const ModuleVector &modules,
+ std::function<bool(const std::string &)> handler) override;
+
+private:
+ void
+ ReportModuleExportsHelper(std::set<ClangModulesDeclVendor::ModuleID> &exports,
+ clang::Module *module);
+
+ void ReportModuleExports(ModuleVector &exports, clang::Module *module);
+
+ clang::ModuleLoadResult DoGetModule(clang::ModuleIdPath path,
+ bool make_visible);
+
+ bool m_enabled = false;
+
+ llvm::IntrusiveRefCntPtr<clang::DiagnosticsEngine> m_diagnostics_engine;
+ llvm::IntrusiveRefCntPtr<clang::CompilerInvocation> m_compiler_invocation;
+ std::unique_ptr<clang::CompilerInstance> m_compiler_instance;
+ std::unique_ptr<clang::Parser> m_parser;
+ size_t m_source_location_index =
+ 0; // used to give name components fake SourceLocations
+
+ typedef std::vector<ConstString> ImportedModule;
+ typedef std::map<ImportedModule, clang::Module *> ImportedModuleMap;
+ typedef std::set<ModuleID> ImportedModuleSet;
+ ImportedModuleMap m_imported_modules;
+ ImportedModuleSet m_user_imported_modules;
+};
} // anonymous namespace
-StoringDiagnosticConsumer::StoringDiagnosticConsumer ()
-{
- m_log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
+StoringDiagnosticConsumer::StoringDiagnosticConsumer() {
+ m_log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS);
}
-void
-StoringDiagnosticConsumer::HandleDiagnostic (clang::DiagnosticsEngine::Level DiagLevel, const clang::Diagnostic &info)
-{
- llvm::SmallVector<char, 256> diagnostic_string;
-
- info.FormatDiagnostic(diagnostic_string);
-
- m_diagnostics.push_back(IDAndDiagnostic(DiagLevel, std::string(diagnostic_string.data(), diagnostic_string.size())));
-}
+void StoringDiagnosticConsumer::HandleDiagnostic(
+ clang::DiagnosticsEngine::Level DiagLevel, const clang::Diagnostic &info) {
+ llvm::SmallVector<char, 256> diagnostic_string;
-void
-StoringDiagnosticConsumer::ClearDiagnostics ()
-{
- m_diagnostics.clear();
+ info.FormatDiagnostic(diagnostic_string);
+
+ m_diagnostics.push_back(
+ IDAndDiagnostic(DiagLevel, std::string(diagnostic_string.data(),
+ diagnostic_string.size())));
}
-void
-StoringDiagnosticConsumer::DumpDiagnostics (Stream &error_stream)
-{
- for (IDAndDiagnostic &diag : m_diagnostics)
- {
- switch (diag.first)
- {
- default:
- error_stream.PutCString(diag.second.c_str());
- error_stream.PutChar('\n');
- break;
- case clang::DiagnosticsEngine::Level::Ignored:
- break;
- }
+void StoringDiagnosticConsumer::ClearDiagnostics() { m_diagnostics.clear(); }
+
+void StoringDiagnosticConsumer::DumpDiagnostics(Stream &error_stream) {
+ for (IDAndDiagnostic &diag : m_diagnostics) {
+ switch (diag.first) {
+ default:
+ error_stream.PutCString(diag.second.c_str());
+ error_stream.PutChar('\n');
+ break;
+ case clang::DiagnosticsEngine::Level::Ignored:
+ break;
}
+ }
}
-static FileSpec
-GetResourceDir ()
-{
- static FileSpec g_cached_resource_dir;
-
- static std::once_flag g_once_flag;
-
- std::call_once(g_once_flag, [](){
- HostInfo::GetLLDBPath (lldb::ePathTypeClangDir, g_cached_resource_dir);
- });
-
- return g_cached_resource_dir;
-}
+static FileSpec GetResourceDir() {
+ static FileSpec g_cached_resource_dir;
-ClangModulesDeclVendor::ClangModulesDeclVendor()
-{
-}
+ static std::once_flag g_once_flag;
-ClangModulesDeclVendor::~ClangModulesDeclVendor()
-{
-}
+ std::call_once(g_once_flag, []() {
+ HostInfo::GetLLDBPath(lldb::ePathTypeClangDir, g_cached_resource_dir);
+ });
-ClangModulesDeclVendorImpl::ClangModulesDeclVendorImpl(llvm::IntrusiveRefCntPtr<clang::DiagnosticsEngine> &diagnostics_engine,
- llvm::IntrusiveRefCntPtr<clang::CompilerInvocation> &compiler_invocation,
- std::unique_ptr<clang::CompilerInstance> &&compiler_instance,
- std::unique_ptr<clang::Parser> &&parser) :
- ClangModulesDeclVendor(),
- m_diagnostics_engine(diagnostics_engine),
- m_compiler_invocation(compiler_invocation),
- m_compiler_instance(std::move(compiler_instance)),
- m_parser(std::move(parser)),
- m_imported_modules()
-{
+ return g_cached_resource_dir;
}
-void
-ClangModulesDeclVendorImpl::ReportModuleExportsHelper (std::set<ClangModulesDeclVendor::ModuleID> &exports,
- clang::Module *module)
-{
- if (exports.count(reinterpret_cast<ClangModulesDeclVendor::ModuleID>(module)))
- return;
-
- exports.insert(reinterpret_cast<ClangModulesDeclVendor::ModuleID>(module));
-
- llvm::SmallVector<clang::Module*, 2> sub_exports;
-
- module->getExportedModules(sub_exports);
-
- for (clang::Module *module : sub_exports)
- {
- ReportModuleExportsHelper(exports, module);
- }
+ClangModulesDeclVendor::ClangModulesDeclVendor() {}
+
+ClangModulesDeclVendor::~ClangModulesDeclVendor() {}
+
+ClangModulesDeclVendorImpl::ClangModulesDeclVendorImpl(
+ llvm::IntrusiveRefCntPtr<clang::DiagnosticsEngine> &diagnostics_engine,
+ llvm::IntrusiveRefCntPtr<clang::CompilerInvocation> &compiler_invocation,
+ std::unique_ptr<clang::CompilerInstance> &&compiler_instance,
+ std::unique_ptr<clang::Parser> &&parser)
+ : ClangModulesDeclVendor(), m_diagnostics_engine(diagnostics_engine),
+ m_compiler_invocation(compiler_invocation),
+ m_compiler_instance(std::move(compiler_instance)),
+ m_parser(std::move(parser)), m_imported_modules() {}
+
+void ClangModulesDeclVendorImpl::ReportModuleExportsHelper(
+ std::set<ClangModulesDeclVendor::ModuleID> &exports,
+ clang::Module *module) {
+ if (exports.count(reinterpret_cast<ClangModulesDeclVendor::ModuleID>(module)))
+ return;
+
+ exports.insert(reinterpret_cast<ClangModulesDeclVendor::ModuleID>(module));
+
+ llvm::SmallVector<clang::Module *, 2> sub_exports;
+
+ module->getExportedModules(sub_exports);
+
+ for (clang::Module *module : sub_exports) {
+ ReportModuleExportsHelper(exports, module);
+ }
}
-void
-ClangModulesDeclVendorImpl::ReportModuleExports (ClangModulesDeclVendor::ModuleVector &exports,
- clang::Module *module)
-{
- std::set<ClangModulesDeclVendor::ModuleID> exports_set;
-
- ReportModuleExportsHelper(exports_set, module);
-
- for (ModuleID module : exports_set)
- {
- exports.push_back(module);
- }
+void ClangModulesDeclVendorImpl::ReportModuleExports(
+ ClangModulesDeclVendor::ModuleVector &exports, clang::Module *module) {
+ std::set<ClangModulesDeclVendor::ModuleID> exports_set;
+
+ ReportModuleExportsHelper(exports_set, module);
+
+ for (ModuleID module : exports_set) {
+ exports.push_back(module);
+ }
}
-bool
-ClangModulesDeclVendorImpl::AddModule(ModulePath &path,
- ModuleVector *exported_modules,
- Stream &error_stream)
-{
- // Fail early.
-
- if (m_compiler_instance->hadModuleLoaderFatalFailure())
- {
- error_stream.PutCString("error: Couldn't load a module because the module loader is in a fatal state.\n");
- return false;
- }
-
- // Check if we've already imported this module.
-
- std::vector<ConstString> imported_module;
-
- for (ConstString path_component : path)
- {
- imported_module.push_back(path_component);
- }
-
- {
- ImportedModuleMap::iterator mi = m_imported_modules.find(imported_module);
-
- if (mi != m_imported_modules.end())
- {
- if (exported_modules)
- {
- ReportModuleExports(*exported_modules, mi->second);
- }
- return true;
- }
- }
-
- if (!m_compiler_instance->getPreprocessor().getHeaderSearchInfo().lookupModule(path[0].GetStringRef()))
- {
- error_stream.Printf("error: Header search couldn't locate module %s\n", path[0].AsCString());
- return false;
- }
-
- llvm::SmallVector<std::pair<clang::IdentifierInfo *, clang::SourceLocation>, 4> clang_path;
-
- {
- clang::SourceManager &source_manager = m_compiler_instance->getASTContext().getSourceManager();
-
- for (ConstString path_component : path)
- {
- clang_path.push_back(std::make_pair(&m_compiler_instance->getASTContext().Idents.get(path_component.GetStringRef()),
- source_manager.getLocForStartOfFile(source_manager.getMainFileID()).getLocWithOffset(m_source_location_index++)));
- }
+bool ClangModulesDeclVendorImpl::AddModule(ModulePath &path,
+ ModuleVector *exported_modules,
+ Stream &error_stream) {
+ // Fail early.
+
+ if (m_compiler_instance->hadModuleLoaderFatalFailure()) {
+ error_stream.PutCString("error: Couldn't load a module because the module "
+ "loader is in a fatal state.\n");
+ return false;
+ }
+
+ // Check if we've already imported this module.
+
+ std::vector<ConstString> imported_module;
+
+ for (ConstString path_component : path) {
+ imported_module.push_back(path_component);
+ }
+
+ {
+ ImportedModuleMap::iterator mi = m_imported_modules.find(imported_module);
+
+ if (mi != m_imported_modules.end()) {
+ if (exported_modules) {
+ ReportModuleExports(*exported_modules, mi->second);
+ }
+ return true;
}
-
- StoringDiagnosticConsumer *diagnostic_consumer = static_cast<StoringDiagnosticConsumer *>(m_compiler_instance->getDiagnostics().getClient());
-
- diagnostic_consumer->ClearDiagnostics();
-
- clang::Module *top_level_module = DoGetModule(clang_path.front(), false);
-
- if (!top_level_module)
- {
- diagnostic_consumer->DumpDiagnostics(error_stream);
- error_stream.Printf("error: Couldn't load top-level module %s\n", path[0].AsCString());
- return false;
+ }
+
+ if (!m_compiler_instance->getPreprocessor()
+ .getHeaderSearchInfo()
+ .lookupModule(path[0].GetStringRef())) {
+ error_stream.Printf("error: Header search couldn't locate module %s\n",
+ path[0].AsCString());
+ return false;
+ }
+
+ llvm::SmallVector<std::pair<clang::IdentifierInfo *, clang::SourceLocation>,
+ 4>
+ clang_path;
+
+ {
+ clang::SourceManager &source_manager =
+ m_compiler_instance->getASTContext().getSourceManager();
+
+ for (ConstString path_component : path) {
+ clang_path.push_back(std::make_pair(
+ &m_compiler_instance->getASTContext().Idents.get(
+ path_component.GetStringRef()),
+ source_manager.getLocForStartOfFile(source_manager.getMainFileID())
+ .getLocWithOffset(m_source_location_index++)));
}
-
- clang::Module *submodule = top_level_module;
-
- for (size_t ci = 1; ci < path.size(); ++ci)
- {
- llvm::StringRef component = path[ci].GetStringRef();
- submodule = submodule->findSubmodule(component.str());
- if (!submodule)
- {
- diagnostic_consumer->DumpDiagnostics(error_stream);
- error_stream.Printf("error: Couldn't load submodule %s\n", component.str().c_str());
- return false;
- }
+ }
+
+ StoringDiagnosticConsumer *diagnostic_consumer =
+ static_cast<StoringDiagnosticConsumer *>(
+ m_compiler_instance->getDiagnostics().getClient());
+
+ diagnostic_consumer->ClearDiagnostics();
+
+ clang::Module *top_level_module = DoGetModule(clang_path.front(), false);
+
+ if (!top_level_module) {
+ diagnostic_consumer->DumpDiagnostics(error_stream);
+ error_stream.Printf("error: Couldn't load top-level module %s\n",
+ path[0].AsCString());
+ return false;
+ }
+
+ clang::Module *submodule = top_level_module;
+
+ for (size_t ci = 1; ci < path.size(); ++ci) {
+ llvm::StringRef component = path[ci].GetStringRef();
+ submodule = submodule->findSubmodule(component.str());
+ if (!submodule) {
+ diagnostic_consumer->DumpDiagnostics(error_stream);
+ error_stream.Printf("error: Couldn't load submodule %s\n",
+ component.str().c_str());
+ return false;
}
-
- clang::Module *requested_module = DoGetModule(clang_path, true);
-
- if (requested_module != nullptr)
- {
- if (exported_modules)
- {
- ReportModuleExports(*exported_modules, requested_module);
- }
+ }
+
+ clang::Module *requested_module = DoGetModule(clang_path, true);
- m_imported_modules[imported_module] = requested_module;
-
- m_enabled = true;
-
- return true;
+ if (requested_module != nullptr) {
+ if (exported_modules) {
+ ReportModuleExports(*exported_modules, requested_module);
}
-
- return false;
+
+ m_imported_modules[imported_module] = requested_module;
+
+ m_enabled = true;
+
+ return true;
+ }
+
+ return false;
}
-bool
-ClangModulesDeclVendor::LanguageSupportsClangModules (lldb::LanguageType language)
-{
- switch (language)
- {
- default:
- return false;
- // C++ and friends to be added
- case lldb::LanguageType::eLanguageTypeC:
- case lldb::LanguageType::eLanguageTypeC11:
- case lldb::LanguageType::eLanguageTypeC89:
- case lldb::LanguageType::eLanguageTypeC99:
- case lldb::LanguageType::eLanguageTypeObjC:
- return true;
- }
+bool ClangModulesDeclVendor::LanguageSupportsClangModules(
+ lldb::LanguageType language) {
+ switch (language) {
+ default:
+ return false;
+ // C++ and friends to be added
+ case lldb::LanguageType::eLanguageTypeC:
+ case lldb::LanguageType::eLanguageTypeC11:
+ case lldb::LanguageType::eLanguageTypeC89:
+ case lldb::LanguageType::eLanguageTypeC99:
+ case lldb::LanguageType::eLanguageTypeObjC:
+ return true;
+ }
}
-bool
-ClangModulesDeclVendorImpl::AddModulesForCompileUnit(CompileUnit &cu,
- ClangModulesDeclVendor::ModuleVector &exported_modules,
- Stream &error_stream)
-{
- if (LanguageSupportsClangModules(cu.GetLanguage()))
- {
- std::vector<ConstString> imported_modules = cu.GetImportedModules();
-
- for (ConstString imported_module : imported_modules)
- {
- std::vector<ConstString> path;
-
- path.push_back(imported_module);
-
- if (!AddModule(path, &exported_modules, error_stream))
- {
- return false;
- }
- }
-
- return true;
+bool ClangModulesDeclVendorImpl::AddModulesForCompileUnit(
+ CompileUnit &cu, ClangModulesDeclVendor::ModuleVector &exported_modules,
+ Stream &error_stream) {
+ if (LanguageSupportsClangModules(cu.GetLanguage())) {
+ std::vector<ConstString> imported_modules = cu.GetImportedModules();
+
+ for (ConstString imported_module : imported_modules) {
+ std::vector<ConstString> path;
+
+ path.push_back(imported_module);
+
+ if (!AddModule(path, &exported_modules, error_stream)) {
+ return false;
+ }
}
return true;
+ }
+
+ return true;
}
// ClangImporter::lookupValue
uint32_t
-ClangModulesDeclVendorImpl::FindDecls (const ConstString &name,
- bool append,
- uint32_t max_matches,
- std::vector <clang::NamedDecl*> &decls)
-{
- if (!m_enabled)
- {
- return 0;
- }
+ClangModulesDeclVendorImpl::FindDecls(const ConstString &name, bool append,
+ uint32_t max_matches,
+ std::vector<clang::NamedDecl *> &decls) {
+ if (!m_enabled) {
+ return 0;
+ }
- if (!append)
- decls.clear();
-
- clang::IdentifierInfo &ident = m_compiler_instance->getASTContext().Idents.get(name.GetStringRef());
-
- clang::LookupResult lookup_result(m_compiler_instance->getSema(),
- clang::DeclarationName(&ident),
- clang::SourceLocation(),
- clang::Sema::LookupOrdinaryName);
-
- m_compiler_instance->getSema().LookupName(lookup_result, m_compiler_instance->getSema().getScopeForContext(m_compiler_instance->getASTContext().getTranslationUnitDecl()));
-
- uint32_t num_matches = 0;
-
- for (clang::NamedDecl *named_decl : lookup_result)
- {
- if (num_matches >= max_matches)
- return num_matches;
-
- decls.push_back(named_decl);
- ++num_matches;
- }
-
- return num_matches;
+ if (!append)
+ decls.clear();
+
+ clang::IdentifierInfo &ident =
+ m_compiler_instance->getASTContext().Idents.get(name.GetStringRef());
+
+ clang::LookupResult lookup_result(
+ m_compiler_instance->getSema(), clang::DeclarationName(&ident),
+ clang::SourceLocation(), clang::Sema::LookupOrdinaryName);
+
+ m_compiler_instance->getSema().LookupName(
+ lookup_result,
+ m_compiler_instance->getSema().getScopeForContext(
+ m_compiler_instance->getASTContext().getTranslationUnitDecl()));
+
+ uint32_t num_matches = 0;
+
+ for (clang::NamedDecl *named_decl : lookup_result) {
+ if (num_matches >= max_matches)
+ return num_matches;
+
+ decls.push_back(named_decl);
+ ++num_matches;
+ }
+
+ return num_matches;
}
-void
-ClangModulesDeclVendorImpl::ForEachMacro(const ClangModulesDeclVendor::ModuleVector &modules,
- std::function<bool (const std::string &)> handler)
-{
- if (!m_enabled)
- {
- return;
- }
-
- typedef std::map<ModuleID, ssize_t> ModulePriorityMap;
- ModulePriorityMap module_priorities;
-
- ssize_t priority = 0;
-
- for (ModuleID module : modules)
+void ClangModulesDeclVendorImpl::ForEachMacro(
+ const ClangModulesDeclVendor::ModuleVector &modules,
+ std::function<bool(const std::string &)> handler) {
+ if (!m_enabled) {
+ return;
+ }
+
+ typedef std::map<ModuleID, ssize_t> ModulePriorityMap;
+ ModulePriorityMap module_priorities;
+
+ ssize_t priority = 0;
+
+ for (ModuleID module : modules) {
+ module_priorities[module] = priority++;
+ }
+
+ if (m_compiler_instance->getPreprocessor().getExternalSource()) {
+ m_compiler_instance->getPreprocessor()
+ .getExternalSource()
+ ->ReadDefinedMacros();
+ }
+
+ for (clang::Preprocessor::macro_iterator
+ mi = m_compiler_instance->getPreprocessor().macro_begin(),
+ me = m_compiler_instance->getPreprocessor().macro_end();
+ mi != me; ++mi) {
+ const clang::IdentifierInfo *ii = nullptr;
+
{
- module_priorities[module] = priority++;
+ if (clang::IdentifierInfoLookup *lookup =
+ m_compiler_instance->getPreprocessor()
+ .getIdentifierTable()
+ .getExternalIdentifierLookup()) {
+ lookup->get(mi->first->getName());
+ }
+ if (!ii) {
+ ii = mi->first;
+ }
}
-
- if (m_compiler_instance->getPreprocessor().getExternalSource())
- {
- m_compiler_instance->getPreprocessor().getExternalSource()->ReadDefinedMacros();
+
+ ssize_t found_priority = -1;
+ clang::MacroInfo *macro_info = nullptr;
+
+ for (clang::ModuleMacro *module_macro :
+ m_compiler_instance->getPreprocessor().getLeafModuleMacros(ii)) {
+ clang::Module *module = module_macro->getOwningModule();
+
+ {
+ ModulePriorityMap::iterator pi =
+ module_priorities.find(reinterpret_cast<ModuleID>(module));
+
+ if (pi != module_priorities.end() && pi->second > found_priority) {
+ macro_info = module_macro->getMacroInfo();
+ found_priority = pi->second;
+ }
+ }
+
+ clang::Module *top_level_module = module->getTopLevelModule();
+
+ if (top_level_module != module) {
+ ModulePriorityMap::iterator pi = module_priorities.find(
+ reinterpret_cast<ModuleID>(top_level_module));
+
+ if ((pi != module_priorities.end()) && pi->second > found_priority) {
+ macro_info = module_macro->getMacroInfo();
+ found_priority = pi->second;
+ }
+ }
}
-
- for (clang::Preprocessor::macro_iterator mi = m_compiler_instance->getPreprocessor().macro_begin(),
- me = m_compiler_instance->getPreprocessor().macro_end();
- mi != me;
- ++mi)
- {
- const clang::IdentifierInfo *ii = nullptr;
-
- {
- if (clang::IdentifierInfoLookup *lookup = m_compiler_instance->getPreprocessor().getIdentifierTable().getExternalIdentifierLookup())
- {
- lookup->get(mi->first->getName());
+
+ if (macro_info) {
+ std::string macro_expansion = "#define ";
+ macro_expansion.append(mi->first->getName().str().c_str());
+
+ {
+ if (macro_info->isFunctionLike()) {
+ macro_expansion.append("(");
+
+ bool first_arg = true;
+
+ for (clang::MacroInfo::arg_iterator ai = macro_info->arg_begin(),
+ ae = macro_info->arg_end();
+ ai != ae; ++ai) {
+ if (!first_arg) {
+ macro_expansion.append(", ");
+ } else {
+ first_arg = false;
}
- if (!ii)
- {
- ii = mi->first;
+
+ macro_expansion.append((*ai)->getName().str());
+ }
+
+ if (macro_info->isC99Varargs()) {
+ if (first_arg) {
+ macro_expansion.append("...");
+ } else {
+ macro_expansion.append(", ...");
}
+ } else if (macro_info->isGNUVarargs()) {
+ macro_expansion.append("...");
+ }
+
+ macro_expansion.append(")");
}
-
- ssize_t found_priority = -1;
- clang::MacroInfo *macro_info = nullptr;
-
- for (clang::ModuleMacro *module_macro : m_compiler_instance->getPreprocessor().getLeafModuleMacros(ii))
- {
- clang::Module *module = module_macro->getOwningModule();
-
- {
- ModulePriorityMap::iterator pi = module_priorities.find(reinterpret_cast<ModuleID>(module));
-
- if (pi != module_priorities.end() && pi->second > found_priority)
- {
- macro_info = module_macro->getMacroInfo();
- found_priority = pi->second;
- }
+
+ macro_expansion.append(" ");
+
+ bool first_token = true;
+
+ for (clang::MacroInfo::tokens_iterator ti = macro_info->tokens_begin(),
+ te = macro_info->tokens_end();
+ ti != te; ++ti) {
+ if (!first_token) {
+ macro_expansion.append(" ");
+ } else {
+ first_token = false;
+ }
+
+ if (ti->isLiteral()) {
+ if (const char *literal_data = ti->getLiteralData()) {
+ std::string token_str(literal_data, ti->getLength());
+ macro_expansion.append(token_str);
+ } else {
+ bool invalid = false;
+ const char *literal_source =
+ m_compiler_instance->getSourceManager().getCharacterData(
+ ti->getLocation(), &invalid);
+
+ if (invalid) {
+ lldbassert(!"Unhandled token kind");
+ macro_expansion.append("<unknown literal value>");
+ } else {
+ macro_expansion.append(
+ std::string(literal_source, ti->getLength()));
+ }
}
-
- clang::Module *top_level_module = module->getTopLevelModule();
-
- if (top_level_module != module)
- {
- ModulePriorityMap::iterator pi = module_priorities.find(reinterpret_cast<ModuleID>(top_level_module));
-
- if ((pi != module_priorities.end()) && pi->second > found_priority)
- {
- macro_info = module_macro->getMacroInfo();
- found_priority = pi->second;
- }
+ } else if (const char *punctuator_spelling =
+ clang::tok::getPunctuatorSpelling(ti->getKind())) {
+ macro_expansion.append(punctuator_spelling);
+ } else if (const char *keyword_spelling =
+ clang::tok::getKeywordSpelling(ti->getKind())) {
+ macro_expansion.append(keyword_spelling);
+ } else {
+ switch (ti->getKind()) {
+ case clang::tok::TokenKind::identifier:
+ macro_expansion.append(ti->getIdentifierInfo()->getName().str());
+ break;
+ case clang::tok::TokenKind::raw_identifier:
+ macro_expansion.append(ti->getRawIdentifier().str());
+ break;
+ default:
+ macro_expansion.append(ti->getName());
+ break;
}
+ }
}
-
- if (macro_info)
- {
- std::string macro_expansion = "#define ";
- macro_expansion.append(mi->first->getName().str().c_str());
-
- {
- if (macro_info->isFunctionLike())
- {
- macro_expansion.append("(");
-
- bool first_arg = true;
-
- for (clang::MacroInfo::arg_iterator ai = macro_info->arg_begin(),
- ae = macro_info->arg_end();
- ai != ae;
- ++ai)
- {
- if (!first_arg)
- {
- macro_expansion.append(", ");
- }
- else
- {
- first_arg = false;
- }
-
- macro_expansion.append((*ai)->getName().str());
- }
-
- if (macro_info->isC99Varargs())
- {
- if (first_arg)
- {
- macro_expansion.append("...");
- }
- else
- {
- macro_expansion.append(", ...");
- }
- }
- else if (macro_info->isGNUVarargs())
- {
- macro_expansion.append("...");
- }
-
- macro_expansion.append(")");
- }
-
- macro_expansion.append(" ");
-
- bool first_token = true;
-
- for (clang::MacroInfo::tokens_iterator ti = macro_info->tokens_begin(),
- te = macro_info->tokens_end();
- ti != te;
- ++ti)
- {
- if (!first_token)
- {
- macro_expansion.append(" ");
- }
- else
- {
- first_token = false;
- }
-
- if (ti->isLiteral())
- {
- if (const char *literal_data = ti->getLiteralData())
- {
- std::string token_str(literal_data, ti->getLength());
- macro_expansion.append(token_str);
- }
- else
- {
- bool invalid = false;
- const char *literal_source = m_compiler_instance->getSourceManager().getCharacterData(ti->getLocation(), &invalid);
-
- if (invalid)
- {
- lldbassert(!"Unhandled token kind");
- macro_expansion.append("<unknown literal value>");
- }
- else
- {
- macro_expansion.append(std::string(literal_source, ti->getLength()));
- }
- }
- }
- else if (const char *punctuator_spelling = clang::tok::getPunctuatorSpelling(ti->getKind()))
- {
- macro_expansion.append(punctuator_spelling);
- }
- else if (const char *keyword_spelling = clang::tok::getKeywordSpelling(ti->getKind()))
- {
- macro_expansion.append(keyword_spelling);
- }
- else
- {
- switch (ti->getKind())
- {
- case clang::tok::TokenKind::identifier:
- macro_expansion.append(ti->getIdentifierInfo()->getName().str());
- break;
- case clang::tok::TokenKind::raw_identifier:
- macro_expansion.append(ti->getRawIdentifier().str());
- break;
- default:
- macro_expansion.append(ti->getName());
- break;
- }
- }
- }
-
- if (handler(macro_expansion))
- {
- return;
- }
- }
+
+ if (handler(macro_expansion)) {
+ return;
}
+ }
}
+ }
}
clang::ModuleLoadResult
ClangModulesDeclVendorImpl::DoGetModule(clang::ModuleIdPath path,
- bool make_visible)
-{
- clang::Module::NameVisibilityKind visibility = make_visible ? clang::Module::AllVisible : clang::Module::Hidden;
-
- const bool is_inclusion_directive = false;
-
- return m_compiler_instance->loadModule(path.front().second, path, visibility, is_inclusion_directive);
+ bool make_visible) {
+ clang::Module::NameVisibilityKind visibility =
+ make_visible ? clang::Module::AllVisible : clang::Module::Hidden;
+
+ const bool is_inclusion_directive = false;
+
+ return m_compiler_instance->loadModule(path.front().second, path, visibility,
+ is_inclusion_directive);
}
static const char *ModuleImportBufferName = "LLDBModulesMemoryBuffer";
lldb_private::ClangModulesDeclVendor *
-ClangModulesDeclVendor::Create(Target &target)
-{
- // FIXME we should insure programmatically that the expression parser's compiler and the modules runtime's
- // compiler are both initialized in the same way – preferably by the same code.
-
- if (!target.GetPlatform()->SupportsModules())
- return nullptr;
-
- const ArchSpec &arch = target.GetArchitecture();
-
- std::vector<std::string> compiler_invocation_arguments =
- {
- "clang",
- "-fmodules",
- "-fimplicit-module-maps",
- "-fcxx-modules",
- "-fsyntax-only",
- "-femit-all-decls",
- "-target", arch.GetTriple().str(),
- "-fmodules-validate-system-headers",
- "-Werror=non-modular-include-in-framework-module"
- };
-
- target.GetPlatform()->AddClangModuleCompilationOptions(&target, compiler_invocation_arguments);
-
- compiler_invocation_arguments.push_back(ModuleImportBufferName);
-
- // Add additional search paths with { "-I", path } or { "-F", path } here.
-
- {
- llvm::SmallString<128> DefaultModuleCache;
- const bool erased_on_reboot = false;
- llvm::sys::path::system_temp_directory(erased_on_reboot, DefaultModuleCache);
- llvm::sys::path::append(DefaultModuleCache, "org.llvm.clang");
- llvm::sys::path::append(DefaultModuleCache, "ModuleCache");
- std::string module_cache_argument("-fmodules-cache-path=");
- module_cache_argument.append(DefaultModuleCache.str().str());
- compiler_invocation_arguments.push_back(module_cache_argument);
+ClangModulesDeclVendor::Create(Target &target) {
+ // FIXME we should insure programmatically that the expression parser's
+ // compiler and the modules runtime's
+ // compiler are both initialized in the same way – preferably by the same
+ // code.
+
+ if (!target.GetPlatform()->SupportsModules())
+ return nullptr;
+
+ const ArchSpec &arch = target.GetArchitecture();
+
+ std::vector<std::string> compiler_invocation_arguments = {
+ "clang",
+ "-fmodules",
+ "-fimplicit-module-maps",
+ "-fcxx-modules",
+ "-fsyntax-only",
+ "-femit-all-decls",
+ "-target",
+ arch.GetTriple().str(),
+ "-fmodules-validate-system-headers",
+ "-Werror=non-modular-include-in-framework-module"};
+
+ target.GetPlatform()->AddClangModuleCompilationOptions(
+ &target, compiler_invocation_arguments);
+
+ compiler_invocation_arguments.push_back(ModuleImportBufferName);
+
+ // Add additional search paths with { "-I", path } or { "-F", path } here.
+
+ {
+ llvm::SmallString<128> DefaultModuleCache;
+ const bool erased_on_reboot = false;
+ llvm::sys::path::system_temp_directory(erased_on_reboot,
+ DefaultModuleCache);
+ llvm::sys::path::append(DefaultModuleCache, "org.llvm.clang");
+ llvm::sys::path::append(DefaultModuleCache, "ModuleCache");
+ std::string module_cache_argument("-fmodules-cache-path=");
+ module_cache_argument.append(DefaultModuleCache.str().str());
+ compiler_invocation_arguments.push_back(module_cache_argument);
+ }
+
+ FileSpecList &module_search_paths = target.GetClangModuleSearchPaths();
+
+ for (size_t spi = 0, spe = module_search_paths.GetSize(); spi < spe; ++spi) {
+ const FileSpec &search_path = module_search_paths.GetFileSpecAtIndex(spi);
+
+ std::string search_path_argument = "-I";
+ search_path_argument.append(search_path.GetPath());
+
+ compiler_invocation_arguments.push_back(search_path_argument);
+ }
+
+ {
+ FileSpec clang_resource_dir = GetResourceDir();
+
+ if (clang_resource_dir.IsDirectory()) {
+ compiler_invocation_arguments.push_back("-resource-dir");
+ compiler_invocation_arguments.push_back(clang_resource_dir.GetPath());
}
-
- FileSpecList &module_search_paths = target.GetClangModuleSearchPaths();
-
- for (size_t spi = 0, spe = module_search_paths.GetSize(); spi < spe; ++spi)
- {
- const FileSpec &search_path = module_search_paths.GetFileSpecAtIndex(spi);
-
- std::string search_path_argument = "-I";
- search_path_argument.append(search_path.GetPath());
-
- compiler_invocation_arguments.push_back(search_path_argument);
- }
-
- {
- FileSpec clang_resource_dir = GetResourceDir();
-
- if (clang_resource_dir.IsDirectory())
- {
- compiler_invocation_arguments.push_back("-resource-dir");
- compiler_invocation_arguments.push_back(clang_resource_dir.GetPath());
- }
- }
-
- llvm::IntrusiveRefCntPtr<clang::DiagnosticsEngine> diagnostics_engine = clang::CompilerInstance::createDiagnostics(new clang::DiagnosticOptions,
- new StoringDiagnosticConsumer);
-
- std::vector<const char *> compiler_invocation_argument_cstrs;
-
- for (const std::string &arg : compiler_invocation_arguments) {
- compiler_invocation_argument_cstrs.push_back(arg.c_str());
- }
-
- llvm::IntrusiveRefCntPtr<clang::CompilerInvocation> invocation(clang::createInvocationFromCommandLine(compiler_invocation_argument_cstrs, diagnostics_engine));
-
- if (!invocation)
- return nullptr;
-
- std::unique_ptr<llvm::MemoryBuffer> source_buffer = llvm::MemoryBuffer::getMemBuffer("extern int __lldb __attribute__((unavailable));",
- ModuleImportBufferName);
-
- invocation->getPreprocessorOpts().addRemappedFile(ModuleImportBufferName, source_buffer.release());
-
- std::unique_ptr<clang::CompilerInstance> instance(new clang::CompilerInstance);
-
- instance->setDiagnostics(diagnostics_engine.get());
- instance->setInvocation(invocation.get());
-
- std::unique_ptr<clang::FrontendAction> action(new clang::SyntaxOnlyAction);
-
- instance->setTarget(clang::TargetInfo::CreateTargetInfo(*diagnostics_engine, instance->getInvocation().TargetOpts));
-
- if (!instance->hasTarget())
- return nullptr;
-
- instance->getTarget().adjust(instance->getLangOpts());
-
- if (!action->BeginSourceFile(*instance, instance->getFrontendOpts().Inputs[0]))
- return nullptr;
-
- instance->getPreprocessor().enableIncrementalProcessing();
-
- instance->createModuleManager();
-
- instance->createSema(action->getTranslationUnitKind(), nullptr);
-
- const bool skipFunctionBodies = false;
- std::unique_ptr<clang::Parser> parser(new clang::Parser(instance->getPreprocessor(), instance->getSema(), skipFunctionBodies));
-
- instance->getPreprocessor().EnterMainSourceFile();
- parser->Initialize();
-
- clang::Parser::DeclGroupPtrTy parsed;
-
- while (!parser->ParseTopLevelDecl(parsed));
-
- return new ClangModulesDeclVendorImpl (diagnostics_engine, invocation, std::move(instance), std::move(parser));
+ }
+
+ llvm::IntrusiveRefCntPtr<clang::DiagnosticsEngine> diagnostics_engine =
+ clang::CompilerInstance::createDiagnostics(new clang::DiagnosticOptions,
+ new StoringDiagnosticConsumer);
+
+ std::vector<const char *> compiler_invocation_argument_cstrs;
+
+ for (const std::string &arg : compiler_invocation_arguments) {
+ compiler_invocation_argument_cstrs.push_back(arg.c_str());
+ }
+
+ llvm::IntrusiveRefCntPtr<clang::CompilerInvocation> invocation(
+ clang::createInvocationFromCommandLine(compiler_invocation_argument_cstrs,
+ diagnostics_engine));
+
+ if (!invocation)
+ return nullptr;
+
+ std::unique_ptr<llvm::MemoryBuffer> source_buffer =
+ llvm::MemoryBuffer::getMemBuffer(
+ "extern int __lldb __attribute__((unavailable));",
+ ModuleImportBufferName);
+
+ invocation->getPreprocessorOpts().addRemappedFile(ModuleImportBufferName,
+ source_buffer.release());
+
+ std::unique_ptr<clang::CompilerInstance> instance(
+ new clang::CompilerInstance);
+
+ instance->setDiagnostics(diagnostics_engine.get());
+ instance->setInvocation(invocation.get());
+
+ std::unique_ptr<clang::FrontendAction> action(new clang::SyntaxOnlyAction);
+
+ instance->setTarget(clang::TargetInfo::CreateTargetInfo(
+ *diagnostics_engine, instance->getInvocation().TargetOpts));
+
+ if (!instance->hasTarget())
+ return nullptr;
+
+ instance->getTarget().adjust(instance->getLangOpts());
+
+ if (!action->BeginSourceFile(*instance,
+ instance->getFrontendOpts().Inputs[0]))
+ return nullptr;
+
+ instance->getPreprocessor().enableIncrementalProcessing();
+
+ instance->createModuleManager();
+
+ instance->createSema(action->getTranslationUnitKind(), nullptr);
+
+ const bool skipFunctionBodies = false;
+ std::unique_ptr<clang::Parser> parser(new clang::Parser(
+ instance->getPreprocessor(), instance->getSema(), skipFunctionBodies));
+
+ instance->getPreprocessor().EnterMainSourceFile();
+ parser->Initialize();
+
+ clang::Parser::DeclGroupPtrTy parsed;
+
+ while (!parser->ParseTopLevelDecl(parsed))
+ ;
+
+ return new ClangModulesDeclVendorImpl(diagnostics_engine, invocation,
+ std::move(instance), std::move(parser));
}
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h b/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h
index df3b20550f9..fbabcd73686 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h
@@ -18,111 +18,104 @@
#include <set>
#include <vector>
-namespace lldb_private
-{
-
-class ClangModulesDeclVendor : public DeclVendor
-{
+namespace lldb_private {
+
+class ClangModulesDeclVendor : public DeclVendor {
public:
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- ClangModulesDeclVendor();
-
- ~ClangModulesDeclVendor() override;
-
- static ClangModulesDeclVendor *
- Create(Target &target);
-
- typedef std::vector<ConstString> ModulePath;
- typedef uintptr_t ModuleID;
- typedef std::vector<ModuleID> ModuleVector;
-
- //------------------------------------------------------------------
- /// Add a module to the list of modules to search.
- ///
- /// @param[in] path
- /// The path to the exact module to be loaded. E.g., if the desired
- /// module is std.io, then this should be { "std", "io" }.
- ///
- /// @param[in] exported_modules
- /// If non-NULL, a pointer to a vector to populate with the ID of every
- /// module that is re-exported by the specified module.
- ///
- /// @param[in] error_stream
- /// A stream to populate with the output of the Clang parser when
- /// it tries to load the module.
- ///
- /// @return
- /// True if the module could be loaded; false if not. If the
- /// compiler encountered a fatal error during a previous module
- /// load, then this will always return false for this ModuleImporter.
- //------------------------------------------------------------------
- virtual bool
- AddModule(ModulePath &path,
- ModuleVector *exported_modules,
- Stream &error_stream) = 0;
-
- //------------------------------------------------------------------
- /// Add all modules referred to in a given compilation unit to the list
- /// of modules to search.
- ///
- /// @param[in] cu
- /// The compilation unit to scan for imported modules.
- ///
- /// @param[in] exported_modules
- /// A vector to populate with the ID of each module loaded (directly
- /// and via re-exports) in this way.
- ///
- /// @param[in] error_stream
- /// A stream to populate with the output of the Clang parser when
- /// it tries to load the modules.
- ///
- /// @return
- /// True if all modules referred to by the compilation unit could be
- /// loaded; false if one could not be loaded. If the compiler
- /// encountered a fatal error during a previous module
- /// load, then this will always return false for this ModuleImporter.
- //------------------------------------------------------------------
- virtual bool
- AddModulesForCompileUnit(CompileUnit &cu,
- ModuleVector &exported_modules,
- Stream &error_stream) = 0;
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ ClangModulesDeclVendor();
+
+ ~ClangModulesDeclVendor() override;
+
+ static ClangModulesDeclVendor *Create(Target &target);
+
+ typedef std::vector<ConstString> ModulePath;
+ typedef uintptr_t ModuleID;
+ typedef std::vector<ModuleID> ModuleVector;
- //------------------------------------------------------------------
- /// Enumerate all the macros that are defined by a given set of modules
- /// that are already imported.
- ///
- /// @param[in] modules
- /// The unique IDs for all modules to query. Later modules have higher
- /// priority, just as if you @imported them in that order. This matters
- /// if module A #defines a macro and module B #undefs it.
- ///
- /// @param[in] handler
- /// A function to call with the text of each #define (including the
- /// #define directive). #undef directives are not included; we simply
- /// elide any corresponding #define. If this function returns true,
- /// we stop the iteration immediately.
- //------------------------------------------------------------------
- virtual void
- ForEachMacro(const ModuleVector &modules,
- std::function<bool (const std::string &)> handler) = 0;
-
- //------------------------------------------------------------------
- /// Query whether Clang supports modules for a particular language.
- /// LLDB uses this to decide whether to try to find the modules loaded
- /// by a gaiven compile unit.
- ///
- /// @param[in] language
- /// The language to query for.
- ///
- /// @return
- /// True if Clang has modules for the given language.
- //------------------------------------------------------------------
- static bool
- LanguageSupportsClangModules (lldb::LanguageType language);
+ //------------------------------------------------------------------
+ /// Add a module to the list of modules to search.
+ ///
+ /// @param[in] path
+ /// The path to the exact module to be loaded. E.g., if the desired
+ /// module is std.io, then this should be { "std", "io" }.
+ ///
+ /// @param[in] exported_modules
+ /// If non-NULL, a pointer to a vector to populate with the ID of every
+ /// module that is re-exported by the specified module.
+ ///
+ /// @param[in] error_stream
+ /// A stream to populate with the output of the Clang parser when
+ /// it tries to load the module.
+ ///
+ /// @return
+ /// True if the module could be loaded; false if not. If the
+ /// compiler encountered a fatal error during a previous module
+ /// load, then this will always return false for this ModuleImporter.
+ //------------------------------------------------------------------
+ virtual bool AddModule(ModulePath &path, ModuleVector *exported_modules,
+ Stream &error_stream) = 0;
+
+ //------------------------------------------------------------------
+ /// Add all modules referred to in a given compilation unit to the list
+ /// of modules to search.
+ ///
+ /// @param[in] cu
+ /// The compilation unit to scan for imported modules.
+ ///
+ /// @param[in] exported_modules
+ /// A vector to populate with the ID of each module loaded (directly
+ /// and via re-exports) in this way.
+ ///
+ /// @param[in] error_stream
+ /// A stream to populate with the output of the Clang parser when
+ /// it tries to load the modules.
+ ///
+ /// @return
+ /// True if all modules referred to by the compilation unit could be
+ /// loaded; false if one could not be loaded. If the compiler
+ /// encountered a fatal error during a previous module
+ /// load, then this will always return false for this ModuleImporter.
+ //------------------------------------------------------------------
+ virtual bool AddModulesForCompileUnit(CompileUnit &cu,
+ ModuleVector &exported_modules,
+ Stream &error_stream) = 0;
+
+ //------------------------------------------------------------------
+ /// Enumerate all the macros that are defined by a given set of modules
+ /// that are already imported.
+ ///
+ /// @param[in] modules
+ /// The unique IDs for all modules to query. Later modules have higher
+ /// priority, just as if you @imported them in that order. This matters
+ /// if module A #defines a macro and module B #undefs it.
+ ///
+ /// @param[in] handler
+ /// A function to call with the text of each #define (including the
+ /// #define directive). #undef directives are not included; we simply
+ /// elide any corresponding #define. If this function returns true,
+ /// we stop the iteration immediately.
+ //------------------------------------------------------------------
+ virtual void
+ ForEachMacro(const ModuleVector &modules,
+ std::function<bool(const std::string &)> handler) = 0;
+
+ //------------------------------------------------------------------
+ /// Query whether Clang supports modules for a particular language.
+ /// LLDB uses this to decide whether to try to find the modules loaded
+ /// by a gaiven compile unit.
+ ///
+ /// @param[in] language
+ /// The language to query for.
+ ///
+ /// @return
+ /// True if Clang has modules for the given language.
+ //------------------------------------------------------------------
+ static bool LanguageSupportsClangModules(lldb::LanguageType language);
};
-
+
} // namespace lldb_private
#endif // liblldb_ClangModulesDeclVendor_h
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp
index d1478e49bff..4d30956177d 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp
@@ -21,74 +21,66 @@
using namespace lldb;
using namespace lldb_private;
-ClangPersistentVariables::ClangPersistentVariables () :
- lldb_private::PersistentExpressionState(LLVMCastKind::eKindClang),
- m_next_persistent_variable_id (0)
-{
-}
+ClangPersistentVariables::ClangPersistentVariables()
+ : lldb_private::PersistentExpressionState(LLVMCastKind::eKindClang),
+ m_next_persistent_variable_id(0) {}
-ExpressionVariableSP
-ClangPersistentVariables::CreatePersistentVariable (const lldb::ValueObjectSP &valobj_sp)
-{
- return AddNewlyConstructedVariable(new ClangExpressionVariable(valobj_sp));
+ExpressionVariableSP ClangPersistentVariables::CreatePersistentVariable(
+ const lldb::ValueObjectSP &valobj_sp) {
+ return AddNewlyConstructedVariable(new ClangExpressionVariable(valobj_sp));
}
-ExpressionVariableSP
-ClangPersistentVariables::CreatePersistentVariable (ExecutionContextScope *exe_scope,
- const ConstString &name,
- const CompilerType& compiler_type,
- lldb::ByteOrder byte_order,
- uint32_t addr_byte_size)
-{
- return AddNewlyConstructedVariable(new ClangExpressionVariable(exe_scope, name, compiler_type, byte_order, addr_byte_size));
+ExpressionVariableSP ClangPersistentVariables::CreatePersistentVariable(
+ ExecutionContextScope *exe_scope, const ConstString &name,
+ const CompilerType &compiler_type, lldb::ByteOrder byte_order,
+ uint32_t addr_byte_size) {
+ return AddNewlyConstructedVariable(new ClangExpressionVariable(
+ exe_scope, name, compiler_type, byte_order, addr_byte_size));
}
-void
-ClangPersistentVariables::RemovePersistentVariable (lldb::ExpressionVariableSP variable)
-{
- RemoveVariable(variable);
-
- const char *name = variable->GetName().AsCString();
-
- if (*name != '$')
- return;
- name++;
-
- if (strtoul(name, NULL, 0) == m_next_persistent_variable_id - 1)
- m_next_persistent_variable_id--;
+void ClangPersistentVariables::RemovePersistentVariable(
+ lldb::ExpressionVariableSP variable) {
+ RemoveVariable(variable);
+
+ const char *name = variable->GetName().AsCString();
+
+ if (*name != '$')
+ return;
+ name++;
+
+ if (strtoul(name, NULL, 0) == m_next_persistent_variable_id - 1)
+ m_next_persistent_variable_id--;
}
-ConstString
-ClangPersistentVariables::GetNextPersistentVariableName ()
-{
- char name_cstr[256];
- ::snprintf (name_cstr, sizeof(name_cstr), "$%u", m_next_persistent_variable_id++);
- ConstString name(name_cstr);
- return name;
+ConstString ClangPersistentVariables::GetNextPersistentVariableName() {
+ char name_cstr[256];
+ ::snprintf(name_cstr, sizeof(name_cstr), "$%u",
+ m_next_persistent_variable_id++);
+ ConstString name(name_cstr);
+ return name;
}
-void
-ClangPersistentVariables::RegisterPersistentDecl (const ConstString &name,
- clang::NamedDecl *decl)
-{
- m_persistent_decls.insert(std::pair<const char*, clang::NamedDecl*>(name.GetCString(), decl));
-
- if (clang::EnumDecl *enum_decl = llvm::dyn_cast<clang::EnumDecl>(decl))
- {
- for (clang::EnumConstantDecl *enumerator_decl : enum_decl->enumerators())
- {
- m_persistent_decls.insert(std::pair<const char*, clang::NamedDecl*>(ConstString(enumerator_decl->getNameAsString()).GetCString(), enumerator_decl));
- }
+void ClangPersistentVariables::RegisterPersistentDecl(const ConstString &name,
+ clang::NamedDecl *decl) {
+ m_persistent_decls.insert(
+ std::pair<const char *, clang::NamedDecl *>(name.GetCString(), decl));
+
+ if (clang::EnumDecl *enum_decl = llvm::dyn_cast<clang::EnumDecl>(decl)) {
+ for (clang::EnumConstantDecl *enumerator_decl : enum_decl->enumerators()) {
+ m_persistent_decls.insert(std::pair<const char *, clang::NamedDecl *>(
+ ConstString(enumerator_decl->getNameAsString()).GetCString(),
+ enumerator_decl));
}
+ }
}
clang::NamedDecl *
-ClangPersistentVariables::GetPersistentDecl (const ConstString &name)
-{
- PersistentDeclMap::const_iterator i = m_persistent_decls.find(name.GetCString());
-
- if (i == m_persistent_decls.end())
- return NULL;
- else
- return i->second;
+ClangPersistentVariables::GetPersistentDecl(const ConstString &name) {
+ PersistentDeclMap::const_iterator i =
+ m_persistent_decls.find(name.GetCString());
+
+ if (i == m_persistent_decls.end())
+ return NULL;
+ else
+ return i->second;
}
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h b/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h
index 2928976592d..16981a7fe14 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h
@@ -21,81 +21,74 @@
#include "lldb/Expression/ExpressionVariable.h"
-namespace lldb_private
-{
-
+namespace lldb_private {
+
//----------------------------------------------------------------------
-/// @class ClangPersistentVariables ClangPersistentVariables.h "lldb/Expression/ClangPersistentVariables.h"
-/// @brief Manages persistent values that need to be preserved between expression invocations.
+/// @class ClangPersistentVariables ClangPersistentVariables.h
+/// "lldb/Expression/ClangPersistentVariables.h"
+/// @brief Manages persistent values that need to be preserved between
+/// expression invocations.
///
/// A list of variables that can be accessed and updated by any expression. See
/// ClangPersistentVariable for more discussion. Also provides an increasing,
/// 0-based counter for naming result variables.
//----------------------------------------------------------------------
-class ClangPersistentVariables : public PersistentExpressionState
-{
+class ClangPersistentVariables : public PersistentExpressionState {
public:
- ClangPersistentVariables();
-
- ~ClangPersistentVariables() override = default;
-
- //------------------------------------------------------------------
- // llvm casting support
- //------------------------------------------------------------------
- static bool classof(const PersistentExpressionState *pv)
- {
- return pv->getKind() == PersistentExpressionState::eKindClang;
- }
-
- lldb::ExpressionVariableSP
- CreatePersistentVariable (const lldb::ValueObjectSP &valobj_sp) override;
-
- lldb::ExpressionVariableSP
- CreatePersistentVariable (ExecutionContextScope *exe_scope,
- const ConstString &name,
- const CompilerType& compiler_type,
- lldb::ByteOrder byte_order,
- uint32_t addr_byte_size) override;
-
- //----------------------------------------------------------------------
- /// Return the next entry in the sequence of strings "$0", "$1", ... for
- /// use naming persistent expression convenience variables.
- ///
- /// @return
- /// A string that contains the next persistent variable name.
- //----------------------------------------------------------------------
- ConstString
- GetNextPersistentVariableName () override;
-
- void
- RemovePersistentVariable (lldb::ExpressionVariableSP variable) override;
-
- void
- RegisterPersistentDecl (const ConstString &name,
- clang::NamedDecl *decl);
-
- clang::NamedDecl *
- GetPersistentDecl (const ConstString &name);
-
- void
- AddHandLoadedClangModule(ClangModulesDeclVendor::ModuleID module)
- {
- m_hand_loaded_clang_modules.push_back(module);
- }
-
- const ClangModulesDeclVendor::ModuleVector &GetHandLoadedClangModules()
- {
- return m_hand_loaded_clang_modules;
- }
-
+ ClangPersistentVariables();
+
+ ~ClangPersistentVariables() override = default;
+
+ //------------------------------------------------------------------
+ // llvm casting support
+ //------------------------------------------------------------------
+ static bool classof(const PersistentExpressionState *pv) {
+ return pv->getKind() == PersistentExpressionState::eKindClang;
+ }
+
+ lldb::ExpressionVariableSP
+ CreatePersistentVariable(const lldb::ValueObjectSP &valobj_sp) override;
+
+ lldb::ExpressionVariableSP CreatePersistentVariable(
+ ExecutionContextScope *exe_scope, const ConstString &name,
+ const CompilerType &compiler_type, lldb::ByteOrder byte_order,
+ uint32_t addr_byte_size) override;
+
+ //----------------------------------------------------------------------
+ /// Return the next entry in the sequence of strings "$0", "$1", ... for
+ /// use naming persistent expression convenience variables.
+ ///
+ /// @return
+ /// A string that contains the next persistent variable name.
+ //----------------------------------------------------------------------
+ ConstString GetNextPersistentVariableName() override;
+
+ void RemovePersistentVariable(lldb::ExpressionVariableSP variable) override;
+
+ void RegisterPersistentDecl(const ConstString &name, clang::NamedDecl *decl);
+
+ clang::NamedDecl *GetPersistentDecl(const ConstString &name);
+
+ void AddHandLoadedClangModule(ClangModulesDeclVendor::ModuleID module) {
+ m_hand_loaded_clang_modules.push_back(module);
+ }
+
+ const ClangModulesDeclVendor::ModuleVector &GetHandLoadedClangModules() {
+ return m_hand_loaded_clang_modules;
+ }
+
private:
- uint32_t m_next_persistent_variable_id; ///< The counter used by GetNextResultName().
-
- typedef llvm::DenseMap<const char *, clang::NamedDecl *> PersistentDeclMap;
- PersistentDeclMap m_persistent_decls; ///< Persistent entities declared by the user.
-
- ClangModulesDeclVendor::ModuleVector m_hand_loaded_clang_modules; ///< These are Clang modules we hand-loaded; these are the highest-
- ///< priority source for macros.
+ uint32_t m_next_persistent_variable_id; ///< The counter used by
+ ///GetNextResultName().
+
+ typedef llvm::DenseMap<const char *, clang::NamedDecl *> PersistentDeclMap;
+ PersistentDeclMap
+ m_persistent_decls; ///< Persistent entities declared by the user.
+
+ ClangModulesDeclVendor::ModuleVector
+ m_hand_loaded_clang_modules; ///< These are Clang modules we hand-loaded;
+ ///these are the highest-
+ ///< priority source for macros.
};
} // namespace lldb_private
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
index 52d49aecec9..c456e411b19 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
@@ -9,21 +9,21 @@
#include <stdio.h>
#if HAVE_SYS_TYPES_H
-# include <sys/types.h>
+#include <sys/types.h>
#endif
#include <cstdlib>
-#include <string>
#include <map>
+#include <string>
#include "ClangUserExpression.h"
#include "ASTResultSynthesizer.h"
+#include "ClangDiagnostic.h"
#include "ClangExpressionDeclMap.h"
#include "ClangExpressionParser.h"
#include "ClangModulesDeclVendor.h"
#include "ClangPersistentVariables.h"
-#include "ClangDiagnostic.h"
#include "lldb/Core/ConstString.h"
#include "lldb/Core/Debugger.h"
@@ -39,11 +39,11 @@
#include "lldb/Host/HostInfo.h"
#include "lldb/Symbol/Block.h"
#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Symbol/ClangExternalASTSourceCommon.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"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Process.h"
@@ -57,676 +57,633 @@
using namespace lldb_private;
-ClangUserExpression::ClangUserExpression(ExecutionContextScope &exe_scope, const char *expr, const char *expr_prefix,
- lldb::LanguageType language, ResultType desired_type,
- const EvaluateExpressionOptions &options)
- : LLVMUserExpression(exe_scope, expr, expr_prefix, language, desired_type, options),
- m_type_system_helper(*m_target_wp.lock().get(), options.GetExecutionPolicy() == eExecutionPolicyTopLevel)
-{
- switch (m_language)
- {
- case lldb::eLanguageTypeC_plus_plus:
- m_allow_cxx = true;
- break;
- case lldb::eLanguageTypeObjC:
- m_allow_objc = true;
- break;
- case lldb::eLanguageTypeObjC_plus_plus:
- default:
- m_allow_cxx = true;
- m_allow_objc = true;
- break;
- }
+ClangUserExpression::ClangUserExpression(
+ ExecutionContextScope &exe_scope, const char *expr, const char *expr_prefix,
+ lldb::LanguageType language, ResultType desired_type,
+ const EvaluateExpressionOptions &options)
+ : LLVMUserExpression(exe_scope, expr, expr_prefix, language, desired_type,
+ options),
+ m_type_system_helper(*m_target_wp.lock().get(),
+ options.GetExecutionPolicy() ==
+ eExecutionPolicyTopLevel) {
+ switch (m_language) {
+ case lldb::eLanguageTypeC_plus_plus:
+ m_allow_cxx = true;
+ break;
+ case lldb::eLanguageTypeObjC:
+ m_allow_objc = true;
+ break;
+ case lldb::eLanguageTypeObjC_plus_plus:
+ default:
+ m_allow_cxx = true;
+ m_allow_objc = true;
+ break;
+ }
}
-ClangUserExpression::~ClangUserExpression ()
-{
-}
+ClangUserExpression::~ClangUserExpression() {}
+
+void ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Error &err) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
-void
-ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Error &err)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ if (log)
+ log->Printf("ClangUserExpression::ScanContext()");
+ m_target = exe_ctx.GetTargetPtr();
+
+ if (!(m_allow_cxx || m_allow_objc)) {
if (log)
- log->Printf("ClangUserExpression::ScanContext()");
+ log->Printf(" [CUE::SC] Settings inhibit C++ and Objective-C");
+ return;
+ }
- m_target = exe_ctx.GetTargetPtr();
+ StackFrame *frame = exe_ctx.GetFramePtr();
+ if (frame == NULL) {
+ if (log)
+ log->Printf(" [CUE::SC] Null stack frame");
+ return;
+ }
- if (!(m_allow_cxx || m_allow_objc))
- {
- if (log)
- log->Printf(" [CUE::SC] Settings inhibit C++ and Objective-C");
- return;
- }
+ SymbolContext sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction |
+ lldb::eSymbolContextBlock);
- StackFrame *frame = exe_ctx.GetFramePtr();
- if (frame == NULL)
- {
- if (log)
- log->Printf(" [CUE::SC] Null stack frame");
- return;
- }
+ if (!sym_ctx.function) {
+ if (log)
+ log->Printf(" [CUE::SC] Null function");
+ return;
+ }
- SymbolContext sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction | lldb::eSymbolContextBlock);
+ // Find the block that defines the function represented by "sym_ctx"
+ Block *function_block = sym_ctx.GetFunctionBlock();
- if (!sym_ctx.function)
- {
- if (log)
- log->Printf(" [CUE::SC] Null function");
- return;
- }
+ if (!function_block) {
+ if (log)
+ log->Printf(" [CUE::SC] Null function block");
+ return;
+ }
- // Find the block that defines the function represented by "sym_ctx"
- Block *function_block = sym_ctx.GetFunctionBlock();
+ CompilerDeclContext decl_context = function_block->GetDeclContext();
- if (!function_block)
- {
- if (log)
- log->Printf(" [CUE::SC] Null function block");
- return;
- }
+ if (!decl_context) {
+ if (log)
+ log->Printf(" [CUE::SC] Null decl context");
+ return;
+ }
+
+ if (clang::CXXMethodDecl *method_decl =
+ ClangASTContext::DeclContextGetAsCXXMethodDecl(decl_context)) {
+ if (m_allow_cxx && method_decl->isInstance()) {
+ 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;
+ }
- CompilerDeclContext decl_context = function_block->GetDeclContext();
+ 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)) {
+ err.SetErrorString(thisErrorString);
+ return;
+ }
+ }
- if (!decl_context)
- {
- if (log)
- log->Printf(" [CUE::SC] Null decl context");
- return;
+ m_in_cplusplus_method = true;
+ m_needs_object_ptr = true;
}
+ } else if (clang::ObjCMethodDecl *method_decl =
+ ClangASTContext::DeclContextGetAsObjCMethodDecl(
+ 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;
+ }
- if (clang::CXXMethodDecl *method_decl = ClangASTContext::DeclContextGetAsCXXMethodDecl(decl_context))
- {
- if (m_allow_cxx && method_decl->isInstance())
- {
- 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->LocationIsValidForFrame (frame))
- {
- err.SetErrorString(thisErrorString);
- return;
- }
- }
-
- m_in_cplusplus_method = true;
- m_needs_object_ptr = true;
+ 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)) {
+ err.SetErrorString(selfErrorString);
+ return;
}
+ }
+
+ m_in_objectivec_method = true;
+ m_needs_object_ptr = true;
+
+ if (!method_decl->isInstanceMethod())
+ m_in_static_method = true;
}
- else if (clang::ObjCMethodDecl *method_decl = ClangASTContext::DeclContextGetAsObjCMethodDecl(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) ||
- !self_variable_sp->LocationIsValidForFrame (frame))
- {
- err.SetErrorString(selfErrorString);
- return;
- }
- }
+ } else if (clang::FunctionDecl *function_decl =
+ ClangASTContext::DeclContextGetAsFunctionDecl(decl_context)) {
+ // We might also have a function that said in the debug information that it
+ // captured an
+ // object pointer. The best way to deal with getting to the ivars at
+ // present is 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::DeclContextGetMetaData(decl_context, function_decl);
+ if (metadata && metadata->HasObjectPtr()) {
+ lldb::LanguageType language = metadata->GetObjectPtrLanguage();
+ if (language == lldb::eLanguageTypeC_plus_plus) {
+ 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)) {
+ err.SetErrorString(thisErrorString);
+ return;
+ }
+ }
+ m_in_cplusplus_method = true;
+ m_needs_object_ptr = true;
+ } else if (language == lldb::eLanguageTypeObjC) {
+ 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)) {
+ err.SetErrorString(selfErrorString);
+ return;
+ }
+
+ Type *self_type = self_variable_sp->GetType();
+
+ if (!self_type) {
+ err.SetErrorString(selfErrorString);
+ return;
+ }
+
+ CompilerType self_clang_type = self_type->GetForwardCompilerType();
+
+ if (!self_clang_type) {
+ err.SetErrorString(selfErrorString);
+ return;
+ }
+
+ if (ClangASTContext::IsObjCClassType(self_clang_type)) {
+ return;
+ } else if (ClangASTContext::IsObjCObjectPointerType(
+ self_clang_type)) {
m_in_objectivec_method = true;
m_needs_object_ptr = true;
-
- if (!method_decl->isInstanceMethod())
- m_in_static_method = true;
- }
- }
- else if (clang::FunctionDecl *function_decl = ClangASTContext::DeclContextGetAsFunctionDecl(decl_context))
- {
- // We might also have a function that said in the debug information that it captured an
- // object pointer. The best way to deal with getting to the ivars at present is 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::DeclContextGetMetaData (decl_context, function_decl);
- if (metadata && metadata->HasObjectPtr())
- {
- lldb::LanguageType language = metadata->GetObjectPtrLanguage();
- if (language == lldb::eLanguageTypeC_plus_plus)
- {
- 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))
- {
- err.SetErrorString(thisErrorString);
- return;
- }
- }
-
- m_in_cplusplus_method = true;
- m_needs_object_ptr = true;
- }
- else if (language == lldb::eLanguageTypeObjC)
- {
- 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))
- {
- err.SetErrorString(selfErrorString);
- return;
- }
-
- Type *self_type = self_variable_sp->GetType();
-
- if (!self_type)
- {
- err.SetErrorString(selfErrorString);
- return;
- }
-
- CompilerType self_clang_type = self_type->GetForwardCompilerType ();
-
- if (!self_clang_type)
- {
- err.SetErrorString(selfErrorString);
- return;
- }
-
- if (ClangASTContext::IsObjCClassType(self_clang_type))
- {
- return;
- }
- else if (ClangASTContext::IsObjCObjectPointerType(self_clang_type))
- {
- m_in_objectivec_method = true;
- m_needs_object_ptr = true;
- }
- else
- {
- err.SetErrorString(selfErrorString);
- return;
- }
- }
- else
- {
- m_in_objectivec_method = true;
- m_needs_object_ptr = true;
- }
- }
+ } else {
+ err.SetErrorString(selfErrorString);
+ return;
+ }
+ } else {
+ m_in_objectivec_method = true;
+ m_needs_object_ptr = true;
}
+ }
}
+ }
}
// This is a really nasty hack, meant to fix Objective-C expressions of the form
// (int)[myArray count]. Right now, because the type information for count is
// not available, [myArray count] returns id, which can't be directly cast to
// int without causing a clang error.
-static void
-ApplyObjcCastHack(std::string &expr)
-{
+static void ApplyObjcCastHack(std::string &expr) {
#define OBJC_CAST_HACK_FROM "(int)["
-#define OBJC_CAST_HACK_TO "(int)(long long)["
+#define OBJC_CAST_HACK_TO "(int)(long long)["
- size_t from_offset;
+ 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);
+ 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);
#undef OBJC_CAST_HACK_TO
#undef OBJC_CAST_HACK_FROM
}
-bool
-ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx,
- lldb_private::ExecutionPolicy execution_policy, bool keep_result_in_memory,
- bool generate_debug_info)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
- Error err;
-
- InstallContext(exe_ctx);
-
- if (Target *target = exe_ctx.GetTargetPtr())
- {
- if (PersistentExpressionState *persistent_state = target->GetPersistentExpressionStateForLanguage(lldb::eLanguageTypeC))
- {
- m_result_delegate.RegisterPersistentState(persistent_state);
- }
- else
- {
- diagnostic_manager.PutCString(eDiagnosticSeverityError, "couldn't start parsing (no persistent data)");
- return false;
- }
+bool ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager,
+ ExecutionContext &exe_ctx,
+ lldb_private::ExecutionPolicy execution_policy,
+ bool keep_result_in_memory,
+ bool generate_debug_info) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+
+ Error err;
+
+ InstallContext(exe_ctx);
+
+ if (Target *target = exe_ctx.GetTargetPtr()) {
+ if (PersistentExpressionState *persistent_state =
+ target->GetPersistentExpressionStateForLanguage(
+ lldb::eLanguageTypeC)) {
+ m_result_delegate.RegisterPersistentState(persistent_state);
+ } else {
+ diagnostic_manager.PutCString(
+ eDiagnosticSeverityError,
+ "couldn't start parsing (no persistent data)");
+ return false;
}
- else
- {
- diagnostic_manager.PutCString(eDiagnosticSeverityError, "error: couldn't start parsing (no target)");
- return false;
+ } else {
+ diagnostic_manager.PutCString(eDiagnosticSeverityError,
+ "error: couldn't start parsing (no target)");
+ return false;
+ }
+
+ ScanContext(exe_ctx, err);
+
+ if (!err.Success()) {
+ diagnostic_manager.PutCString(eDiagnosticSeverityWarning, err.AsCString());
+ }
+
+ ////////////////////////////////////
+ // Generate the expression
+ //
+
+ ApplyObjcCastHack(m_expr_text);
+ // ApplyUnicharHack(m_expr_text);
+
+ std::string prefix = m_expr_prefix;
+
+ if (ClangModulesDeclVendor *decl_vendor =
+ m_target->GetClangModulesDeclVendor()) {
+ const ClangModulesDeclVendor::ModuleVector &hand_imported_modules =
+ llvm::cast<ClangPersistentVariables>(
+ m_target->GetPersistentExpressionStateForLanguage(
+ lldb::eLanguageTypeC))
+ ->GetHandLoadedClangModules();
+ ClangModulesDeclVendor::ModuleVector modules_for_macros;
+
+ for (ClangModulesDeclVendor::ModuleID module : hand_imported_modules) {
+ modules_for_macros.push_back(module);
}
- ScanContext(exe_ctx, err);
+ if (m_target->GetEnableAutoImportClangModules()) {
+ if (StackFrame *frame = exe_ctx.GetFramePtr()) {
+ if (Block *block = frame->GetFrameBlock()) {
+ SymbolContext sc;
- if (!err.Success())
- {
- diagnostic_manager.PutCString(eDiagnosticSeverityWarning, err.AsCString());
- }
+ block->CalculateSymbolContext(&sc);
- ////////////////////////////////////
- // Generate the expression
- //
-
- ApplyObjcCastHack(m_expr_text);
- //ApplyUnicharHack(m_expr_text);
-
- std::string prefix = m_expr_prefix;
-
- if (ClangModulesDeclVendor *decl_vendor = m_target->GetClangModulesDeclVendor())
- {
- const ClangModulesDeclVendor::ModuleVector &hand_imported_modules = llvm::cast<ClangPersistentVariables>(m_target->GetPersistentExpressionStateForLanguage(lldb::eLanguageTypeC))->GetHandLoadedClangModules();
- ClangModulesDeclVendor::ModuleVector modules_for_macros;
-
- for (ClangModulesDeclVendor::ModuleID module : hand_imported_modules)
- {
- modules_for_macros.push_back(module);
- }
+ if (sc.comp_unit) {
+ StreamString error_stream;
- if (m_target->GetEnableAutoImportClangModules())
- {
- if (StackFrame *frame = exe_ctx.GetFramePtr())
- {
- if (Block *block = frame->GetFrameBlock())
- {
- SymbolContext sc;
-
- block->CalculateSymbolContext(&sc);
-
- if (sc.comp_unit)
- {
- StreamString error_stream;
-
- decl_vendor->AddModulesForCompileUnit(*sc.comp_unit, modules_for_macros, error_stream);
- }
- }
- }
+ decl_vendor->AddModulesForCompileUnit(
+ *sc.comp_unit, modules_for_macros, error_stream);
+ }
}
+ }
}
+ }
- lldb::LanguageType lang_type = lldb::eLanguageTypeUnknown;
+ lldb::LanguageType lang_type = lldb::eLanguageTypeUnknown;
- if (m_options.GetExecutionPolicy() == eExecutionPolicyTopLevel)
- {
- m_transformed_text = m_expr_text;
- }
+ if (m_options.GetExecutionPolicy() == eExecutionPolicyTopLevel) {
+ m_transformed_text = m_expr_text;
+ } else {
+ std::unique_ptr<ExpressionSourceCode> source_code(
+ ExpressionSourceCode::CreateWrapped(prefix.c_str(),
+ m_expr_text.c_str()));
+
+ if (m_in_cplusplus_method)
+ lang_type = lldb::eLanguageTypeC_plus_plus;
+ else if (m_in_objectivec_method)
+ lang_type = lldb::eLanguageTypeObjC;
else
- {
- std::unique_ptr<ExpressionSourceCode> source_code(
- ExpressionSourceCode::CreateWrapped(prefix.c_str(), m_expr_text.c_str()));
-
- if (m_in_cplusplus_method)
- lang_type = lldb::eLanguageTypeC_plus_plus;
- else if (m_in_objectivec_method)
- lang_type = lldb::eLanguageTypeObjC;
- else
- lang_type = lldb::eLanguageTypeC;
-
- if (!source_code->GetText(m_transformed_text, lang_type, m_in_static_method, exe_ctx))
- {
- diagnostic_manager.PutCString(eDiagnosticSeverityError, "couldn't construct expression body");
- return false;
- }
+ lang_type = lldb::eLanguageTypeC;
+
+ if (!source_code->GetText(m_transformed_text, lang_type, m_in_static_method,
+ exe_ctx)) {
+ diagnostic_manager.PutCString(eDiagnosticSeverityError,
+ "couldn't construct expression body");
+ return false;
}
+ }
- if (log)
- log->Printf("Parsing the following code:\n%s", m_transformed_text.c_str());
+ if (log)
+ log->Printf("Parsing the following code:\n%s", m_transformed_text.c_str());
- ////////////////////////////////////
- // Set up the target and compiler
- //
+ ////////////////////////////////////
+ // Set up the target and compiler
+ //
- Target *target = exe_ctx.GetTargetPtr();
+ Target *target = exe_ctx.GetTargetPtr();
- if (!target)
- {
- diagnostic_manager.PutCString(eDiagnosticSeverityError, "invalid target");
- return false;
- }
+ if (!target) {
+ diagnostic_manager.PutCString(eDiagnosticSeverityError, "invalid target");
+ return false;
+ }
- //////////////////////////
- // Parse the expression
- //
+ //////////////////////////
+ // Parse the expression
+ //
- m_materializer_ap.reset(new Materializer());
+ m_materializer_ap.reset(new Materializer());
- ResetDeclMap(exe_ctx, m_result_delegate, keep_result_in_memory);
+ ResetDeclMap(exe_ctx, m_result_delegate, keep_result_in_memory);
- class OnExit
- {
- public:
- typedef std::function <void (void)> Callback;
+ class OnExit {
+ public:
+ typedef std::function<void(void)> Callback;
- OnExit (Callback const &callback) :
- m_callback(callback)
- {
- }
+ OnExit(Callback const &callback) : m_callback(callback) {}
- ~OnExit ()
- {
- m_callback();
- }
- private:
- Callback m_callback;
- };
+ ~OnExit() { m_callback(); }
- OnExit on_exit([this]() { ResetDeclMap(); });
+ private:
+ Callback m_callback;
+ };
- if (!DeclMap()->WillParse(exe_ctx, m_materializer_ap.get()))
- {
- diagnostic_manager.PutCString(eDiagnosticSeverityError,
- "current process state is unsuitable for expression parsing");
+ OnExit on_exit([this]() { ResetDeclMap(); });
- ResetDeclMap(); // We are being careful here in the case of breakpoint conditions.
+ if (!DeclMap()->WillParse(exe_ctx, m_materializer_ap.get())) {
+ diagnostic_manager.PutCString(
+ eDiagnosticSeverityError,
+ "current process state is unsuitable for expression parsing");
- return false;
- }
+ ResetDeclMap(); // We are being careful here in the case of breakpoint
+ // conditions.
- if (m_options.GetExecutionPolicy() == eExecutionPolicyTopLevel)
- {
- DeclMap()->SetLookupsEnabled(true);
- }
+ return false;
+ }
- Process *process = exe_ctx.GetProcessPtr();
- ExecutionContextScope *exe_scope = process;
-
- if (!exe_scope)
- exe_scope = exe_ctx.GetTargetPtr();
-
- // We use a shared pointer here so we can use the original parser - if it succeeds
- // or the rewrite parser we might make if it fails. But the parser_sp will never be empty.
-
- ClangExpressionParser parser(exe_scope, *this, generate_debug_info);
-
- unsigned num_errors = parser.Parse(diagnostic_manager);
-
- // Check here for FixItHints. If there are any try to apply the fixits and set the fixed text in m_fixed_text
- // before returning an error.
- if (num_errors)
- {
- if (diagnostic_manager.HasFixIts())
- {
- if (parser.RewriteExpression(diagnostic_manager))
- {
- size_t fixed_start;
- size_t fixed_end;
- const std::string &fixed_expression = diagnostic_manager.GetFixedExpression();
- if (ExpressionSourceCode::GetOriginalBodyBounds(fixed_expression, lang_type, fixed_start, fixed_end))
- m_fixed_text = fixed_expression.substr(fixed_start, fixed_end - fixed_start);
- }
- }
+ if (m_options.GetExecutionPolicy() == eExecutionPolicyTopLevel) {
+ DeclMap()->SetLookupsEnabled(true);
+ }
- ResetDeclMap(); // We are being careful here in the case of breakpoint conditions.
+ Process *process = exe_ctx.GetProcessPtr();
+ ExecutionContextScope *exe_scope = process;
- return false;
- }
+ if (!exe_scope)
+ exe_scope = exe_ctx.GetTargetPtr();
- //////////////////////////////////////////////////////////////////////////////////////////
- // 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_sp,
- exe_ctx,
- m_can_interpret,
- execution_policy);
-
- if (!jit_error.Success())
- {
- const char *error_cstr = jit_error.AsCString();
- if (error_cstr && error_cstr[0])
- diagnostic_manager.PutCString(eDiagnosticSeverityError, error_cstr);
- else
- diagnostic_manager.PutCString(eDiagnosticSeverityError, "expression can't be interpreted or run");
- return false;
- }
+ // We use a shared pointer here so we can use the original parser - if it
+ // succeeds
+ // or the rewrite parser we might make if it fails. But the parser_sp will
+ // never be empty.
+
+ ClangExpressionParser parser(exe_scope, *this, generate_debug_info);
+
+ unsigned num_errors = parser.Parse(diagnostic_manager);
+
+ // Check here for FixItHints. If there are any try to apply the fixits and
+ // set the fixed text in m_fixed_text
+ // before returning an error.
+ if (num_errors) {
+ if (diagnostic_manager.HasFixIts()) {
+ if (parser.RewriteExpression(diagnostic_manager)) {
+ size_t fixed_start;
+ size_t fixed_end;
+ const std::string &fixed_expression =
+ diagnostic_manager.GetFixedExpression();
+ if (ExpressionSourceCode::GetOriginalBodyBounds(
+ fixed_expression, lang_type, fixed_start, fixed_end))
+ m_fixed_text =
+ fixed_expression.substr(fixed_start, fixed_end - fixed_start);
+ }
}
- if (exe_ctx.GetProcessPtr() && execution_policy == eExecutionPolicyTopLevel)
- {
- Error static_init_error = parser.RunStaticInitializers(m_execution_unit_sp, exe_ctx);
-
- if (!static_init_error.Success())
- {
- const char *error_cstr = static_init_error.AsCString();
- if (error_cstr && error_cstr[0])
- diagnostic_manager.Printf(eDiagnosticSeverityError, "couldn't run static initializers: %s\n",
- error_cstr);
- else
- diagnostic_manager.PutCString(eDiagnosticSeverityError, "couldn't run static initializers\n");
- return false;
- }
+ ResetDeclMap(); // 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_sp, exe_ctx,
+ m_can_interpret, execution_policy);
+
+ if (!jit_error.Success()) {
+ const char *error_cstr = jit_error.AsCString();
+ if (error_cstr && error_cstr[0])
+ diagnostic_manager.PutCString(eDiagnosticSeverityError, error_cstr);
+ else
+ diagnostic_manager.PutCString(eDiagnosticSeverityError,
+ "expression can't be interpreted or run");
+ return false;
+ }
+ }
+
+ if (exe_ctx.GetProcessPtr() && execution_policy == eExecutionPolicyTopLevel) {
+ Error static_init_error =
+ parser.RunStaticInitializers(m_execution_unit_sp, exe_ctx);
+
+ if (!static_init_error.Success()) {
+ const char *error_cstr = static_init_error.AsCString();
+ if (error_cstr && error_cstr[0])
+ diagnostic_manager.Printf(eDiagnosticSeverityError,
+ "couldn't run static initializers: %s\n",
+ error_cstr);
+ else
+ diagnostic_manager.PutCString(eDiagnosticSeverityError,
+ "couldn't run static initializers\n");
+ return false;
}
+ }
- if (m_execution_unit_sp)
- {
- bool register_execution_unit = false;
+ if (m_execution_unit_sp) {
+ bool register_execution_unit = false;
- if (m_options.GetExecutionPolicy() == eExecutionPolicyTopLevel)
- {
- register_execution_unit = true;
- }
-
- // If there is more than one external function in the execution
- // unit, it needs to keep living even if it's not top level, because
- // the result could refer to that function.
-
- if (m_execution_unit_sp->GetJittedFunctions().size() > 1)
- {
- register_execution_unit = true;
- }
+ if (m_options.GetExecutionPolicy() == eExecutionPolicyTopLevel) {
+ register_execution_unit = true;
+ }
- if (register_execution_unit)
- {
- llvm::cast<PersistentExpressionState>(
- exe_ctx.GetTargetPtr()->GetPersistentExpressionStateForLanguage(m_language))
- ->RegisterExecutionUnit(m_execution_unit_sp);
- }
+ // If there is more than one external function in the execution
+ // unit, it needs to keep living even if it's not top level, because
+ // the result could refer to that function.
+
+ if (m_execution_unit_sp->GetJittedFunctions().size() > 1) {
+ register_execution_unit = true;
}
- 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);
- }
+ if (register_execution_unit) {
+ llvm::cast<PersistentExpressionState>(
+ exe_ctx.GetTargetPtr()->GetPersistentExpressionStateForLanguage(
+ m_language))
+ ->RegisterExecutionUnit(m_execution_unit_sp);
+ }
+ }
+
+ 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);
}
+ }
- ResetDeclMap(); // Make this go away since we don't need any of its state after parsing. This also gets rid of any
- // ClangASTImporter::Minions.
+ ResetDeclMap(); // Make this go away since we don't need any of its state
+ // after parsing. This also gets rid of any
+ // ClangASTImporter::Minions.
- if (process && m_jit_start_addr != LLDB_INVALID_ADDRESS)
- m_jit_process_wp = lldb::ProcessWP(process->shared_from_this());
- return true;
+ if (process && m_jit_start_addr != LLDB_INVALID_ADDRESS)
+ m_jit_process_wp = lldb::ProcessWP(process->shared_from_this());
+ return true;
}
-bool
-ClangUserExpression::AddArguments(ExecutionContext &exe_ctx, std::vector<lldb::addr_t> &args,
- lldb::addr_t struct_address, DiagnosticManager &diagnostic_manager)
-{
- lldb::addr_t object_ptr = LLDB_INVALID_ADDRESS;
- lldb::addr_t cmd_ptr = LLDB_INVALID_ADDRESS;
-
- if (m_needs_object_ptr)
- {
- lldb::StackFrameSP frame_sp = exe_ctx.GetFrameSP();
- if (!frame_sp)
- return true;
-
- ConstString object_name;
-
- if (m_in_cplusplus_method)
- {
- object_name.SetCString("this");
- }
- else if (m_in_objectivec_method)
- {
- object_name.SetCString("self");
- }
- else
- {
- diagnostic_manager.PutCString(eDiagnosticSeverityError, "need object pointer but don't know the language");
- return false;
- }
+bool ClangUserExpression::AddArguments(ExecutionContext &exe_ctx,
+ std::vector<lldb::addr_t> &args,
+ lldb::addr_t struct_address,
+ DiagnosticManager &diagnostic_manager) {
+ lldb::addr_t object_ptr = LLDB_INVALID_ADDRESS;
+ lldb::addr_t cmd_ptr = LLDB_INVALID_ADDRESS;
+
+ if (m_needs_object_ptr) {
+ lldb::StackFrameSP frame_sp = exe_ctx.GetFrameSP();
+ if (!frame_sp)
+ return true;
+
+ ConstString object_name;
+
+ if (m_in_cplusplus_method) {
+ object_name.SetCString("this");
+ } else if (m_in_objectivec_method) {
+ object_name.SetCString("self");
+ } else {
+ diagnostic_manager.PutCString(
+ eDiagnosticSeverityError,
+ "need object pointer but don't know the language");
+ return false;
+ }
- Error object_ptr_error;
+ Error object_ptr_error;
- object_ptr = GetObjectPointer(frame_sp, object_name, object_ptr_error);
+ object_ptr = GetObjectPointer(frame_sp, object_name, object_ptr_error);
- if (!object_ptr_error.Success())
- {
- exe_ctx.GetTargetRef().GetDebugger().GetAsyncOutputStream()->Printf("warning: `%s' is not accessible (subsituting 0)\n", object_name.AsCString());
- object_ptr = 0;
- }
+ if (!object_ptr_error.Success()) {
+ exe_ctx.GetTargetRef().GetDebugger().GetAsyncOutputStream()->Printf(
+ "warning: `%s' is not accessible (subsituting 0)\n",
+ object_name.AsCString());
+ object_ptr = 0;
+ }
- if (m_in_objectivec_method)
- {
- ConstString cmd_name("_cmd");
+ if (m_in_objectivec_method) {
+ ConstString cmd_name("_cmd");
- cmd_ptr = GetObjectPointer(frame_sp, cmd_name, object_ptr_error);
+ cmd_ptr = GetObjectPointer(frame_sp, cmd_name, object_ptr_error);
- if (!object_ptr_error.Success())
- {
- diagnostic_manager.Printf(eDiagnosticSeverityWarning,
- "couldn't get cmd pointer (substituting NULL): %s",
- object_ptr_error.AsCString());
- cmd_ptr = 0;
- }
- }
-
- args.push_back(object_ptr);
+ if (!object_ptr_error.Success()) {
+ diagnostic_manager.Printf(
+ eDiagnosticSeverityWarning,
+ "couldn't get cmd pointer (substituting NULL): %s",
+ object_ptr_error.AsCString());
+ cmd_ptr = 0;
+ }
+ }
- if (m_in_objectivec_method)
- args.push_back(cmd_ptr);
+ args.push_back(object_ptr);
- args.push_back(struct_address);
- }
- else
- {
- args.push_back(struct_address);
- }
- return true;
+ if (m_in_objectivec_method)
+ args.push_back(cmd_ptr);
+
+ args.push_back(struct_address);
+ } else {
+ args.push_back(struct_address);
+ }
+ return true;
}
-lldb::ExpressionVariableSP
-ClangUserExpression::GetResultAfterDematerialization(ExecutionContextScope *exe_scope)
-{
- return m_result_delegate.GetVariable();
+lldb::ExpressionVariableSP ClangUserExpression::GetResultAfterDematerialization(
+ ExecutionContextScope *exe_scope) {
+ return m_result_delegate.GetVariable();
}
-void
-ClangUserExpression::ClangUserExpressionHelper::ResetDeclMap(ExecutionContext &exe_ctx, Materializer::PersistentVariableDelegate &delegate, bool keep_result_in_memory)
-{
- m_expr_decl_map_up.reset(new ClangExpressionDeclMap(keep_result_in_memory, &delegate, exe_ctx));
+void ClangUserExpression::ClangUserExpressionHelper::ResetDeclMap(
+ ExecutionContext &exe_ctx,
+ Materializer::PersistentVariableDelegate &delegate,
+ bool keep_result_in_memory) {
+ m_expr_decl_map_up.reset(
+ new ClangExpressionDeclMap(keep_result_in_memory, &delegate, exe_ctx));
}
clang::ASTConsumer *
-ClangUserExpression::ClangUserExpressionHelper::ASTTransformer(clang::ASTConsumer *passthrough)
-{
- m_result_synthesizer_up.reset(new ASTResultSynthesizer(passthrough, m_top_level, m_target));
+ClangUserExpression::ClangUserExpressionHelper::ASTTransformer(
+ clang::ASTConsumer *passthrough) {
+ m_result_synthesizer_up.reset(
+ new ASTResultSynthesizer(passthrough, m_top_level, m_target));
- return m_result_synthesizer_up.get();
+ return m_result_synthesizer_up.get();
}
-void
-ClangUserExpression::ClangUserExpressionHelper::CommitPersistentDecls()
-{
- if (m_result_synthesizer_up.get())
- {
- m_result_synthesizer_up->CommitPersistentDecls();
- }
+void ClangUserExpression::ClangUserExpressionHelper::CommitPersistentDecls() {
+ if (m_result_synthesizer_up.get()) {
+ m_result_synthesizer_up->CommitPersistentDecls();
+ }
}
-ClangUserExpression::ResultDelegate::ResultDelegate()
-{
-}
+ClangUserExpression::ResultDelegate::ResultDelegate() {}
-ConstString
-ClangUserExpression::ResultDelegate::GetName()
-{
- return m_persistent_state->GetNextPersistentVariableName();
+ConstString ClangUserExpression::ResultDelegate::GetName() {
+ return m_persistent_state->GetNextPersistentVariableName();
}
-void
-ClangUserExpression::ResultDelegate::DidDematerialize(lldb::ExpressionVariableSP &variable)
-{
- m_variable = variable;
+void ClangUserExpression::ResultDelegate::DidDematerialize(
+ lldb::ExpressionVariableSP &variable) {
+ m_variable = variable;
}
-void
-ClangUserExpression::ResultDelegate::RegisterPersistentState(PersistentExpressionState *persistent_state)
-{
- m_persistent_state = persistent_state;
+void ClangUserExpression::ResultDelegate::RegisterPersistentState(
+ PersistentExpressionState *persistent_state) {
+ m_persistent_state = persistent_state;
}
-lldb::ExpressionVariableSP &
-ClangUserExpression::ResultDelegate::GetVariable()
-{
- return m_variable;
+lldb::ExpressionVariableSP &ClangUserExpression::ResultDelegate::GetVariable() {
+ return m_variable;
}
-
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h b/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h
index 6077588b024..1aea69fd45f 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h
@@ -16,26 +16,26 @@
// Other libraries and framework includes
// Project includes
-#include "ASTStructExtractor.h"
#include "ASTResultSynthesizer.h"
+#include "ASTStructExtractor.h"
#include "ClangExpressionDeclMap.h"
#include "ClangExpressionHelper.h"
#include "ClangExpressionVariable.h"
#include "IRForTarget.h"
-#include "lldb/lldb-forward.h"
-#include "lldb/lldb-private.h"
#include "lldb/Core/Address.h"
#include "lldb/Core/ClangForward.h"
#include "lldb/Expression/LLVMUserExpression.h"
#include "lldb/Expression/Materializer.h"
#include "lldb/Target/ExecutionContext.h"
+#include "lldb/lldb-forward.h"
+#include "lldb/lldb-private.h"
-namespace lldb_private
-{
+namespace lldb_private {
//----------------------------------------------------------------------
-/// @class ClangUserExpression ClangUserExpression.h "lldb/Expression/ClangUserExpression.h"
+/// @class ClangUserExpression ClangUserExpression.h
+/// "lldb/Expression/ClangUserExpression.h"
/// @brief Encapsulates a single expression for use with Clang
///
/// LLDB uses expressions for various purposes, notably to call functions
@@ -43,172 +43,154 @@ namespace lldb_private
/// the objects needed to parse and interpret or JIT an expression. It
/// uses the Clang parser to produce LLVM IR from the expression.
//----------------------------------------------------------------------
-class ClangUserExpression : public LLVMUserExpression
-{
+class ClangUserExpression : public LLVMUserExpression {
public:
- enum { kDefaultTimeout = 500000u };
-
- class ClangUserExpressionHelper : public ClangExpressionHelper
- {
- public:
- ClangUserExpressionHelper(Target &target, bool top_level) : m_target(target), m_top_level(top_level) {}
-
- ~ClangUserExpressionHelper() override = default;
-
- //------------------------------------------------------------------
- /// Return the object that the parser should use when resolving external
- /// values. May be NULL if everything should be self-contained.
- //------------------------------------------------------------------
- ClangExpressionDeclMap *
- DeclMap() override
- {
- return m_expr_decl_map_up.get();
- }
-
- void
- ResetDeclMap()
- {
- m_expr_decl_map_up.reset();
- }
-
- void
- ResetDeclMap (ExecutionContext & exe_ctx, Materializer::PersistentVariableDelegate &result_delegate, bool keep_result_in_memory);
-
- //------------------------------------------------------------------
- /// Return the object that the parser should allow to access ASTs.
- /// May be NULL if the ASTs do not need to be transformed.
- ///
- /// @param[in] passthrough
- /// The ASTConsumer that the returned transformer should send
- /// the ASTs to after transformation.
- //------------------------------------------------------------------
- clang::ASTConsumer *
- ASTTransformer(clang::ASTConsumer *passthrough) override;
-
- void
- CommitPersistentDecls() override;
-
- private:
- Target &m_target;
- std::unique_ptr<ClangExpressionDeclMap> m_expr_decl_map_up;
- std::unique_ptr<ASTStructExtractor>
- m_struct_extractor_up; ///< The class that generates the argument struct layout.
- std::unique_ptr<ASTResultSynthesizer> m_result_synthesizer_up;
- bool m_top_level;
- };
+ enum { kDefaultTimeout = 500000u };
+
+ class ClangUserExpressionHelper : public ClangExpressionHelper {
+ public:
+ ClangUserExpressionHelper(Target &target, bool top_level)
+ : m_target(target), m_top_level(top_level) {}
+
+ ~ClangUserExpressionHelper() override = default;
//------------------------------------------------------------------
- /// Constructor
- ///
- /// @param[in] expr
- /// The expression to parse.
- ///
- /// @param[in] expr_prefix
- /// If non-NULL, a C string containing translation-unit level
- /// definitions to be included when the expression is parsed.
- ///
- /// @param[in] language
- /// If not eLanguageTypeUnknown, a language to use when parsing
- /// the expression. Currently restricted to those languages
- /// supported by Clang.
- ///
- /// @param[in] desired_type
- /// If not eResultTypeAny, the type to use for the expression
- /// result.
+ /// Return the object that the parser should use when resolving external
+ /// values. May be NULL if everything should be self-contained.
//------------------------------------------------------------------
- ClangUserExpression (ExecutionContextScope &exe_scope,
- const char *expr,
- const char *expr_prefix,
- lldb::LanguageType language,
- ResultType desired_type,
- const EvaluateExpressionOptions &options);
+ ClangExpressionDeclMap *DeclMap() override {
+ return m_expr_decl_map_up.get();
+ }
+
+ void ResetDeclMap() { m_expr_decl_map_up.reset(); }
- ~ClangUserExpression() override;
+ void ResetDeclMap(ExecutionContext &exe_ctx,
+ Materializer::PersistentVariableDelegate &result_delegate,
+ bool keep_result_in_memory);
//------------------------------------------------------------------
- /// Parse the expression
- ///
- /// @param[in] diagnostic_manager
- /// A diagnostic manager to report parse errors and warnings to.
+ /// Return the object that the parser should allow to access ASTs.
+ /// May be NULL if the ASTs do not need to be transformed.
///
- /// @param[in] exe_ctx
- /// The execution context to use when looking up entities that
- /// are needed for parsing (locations of functions, types of
- /// variables, persistent variables, etc.)
- ///
- /// @param[in] execution_policy
- /// Determines whether interpretation is possible or mandatory.
- ///
- /// @param[in] keep_result_in_memory
- /// True if the resulting persistent variable should reside in
- /// target memory, if applicable.
- ///
- /// @return
- /// True on success (no errors); false otherwise.
+ /// @param[in] passthrough
+ /// The ASTConsumer that the returned transformer should send
+ /// the ASTs to after transformation.
//------------------------------------------------------------------
- bool
- Parse(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx,
- lldb_private::ExecutionPolicy execution_policy, bool keep_result_in_memory,
- bool generate_debug_info) override;
-
- ExpressionTypeSystemHelper *
- GetTypeSystemHelper () override
- {
- return &m_type_system_helper;
- }
-
- ClangExpressionDeclMap *
- DeclMap ()
- {
- return m_type_system_helper.DeclMap();
- }
-
- void
- ResetDeclMap ()
- {
- m_type_system_helper.ResetDeclMap();
- }
-
- void
- ResetDeclMap (ExecutionContext & exe_ctx, Materializer::PersistentVariableDelegate &result_delegate, bool keep_result_in_memory)
- {
- m_type_system_helper.ResetDeclMap(exe_ctx, result_delegate, keep_result_in_memory);
- }
+ clang::ASTConsumer *
+ ASTTransformer(clang::ASTConsumer *passthrough) override;
+
+ void CommitPersistentDecls() override;
+
+ private:
+ Target &m_target;
+ std::unique_ptr<ClangExpressionDeclMap> m_expr_decl_map_up;
+ std::unique_ptr<ASTStructExtractor> m_struct_extractor_up; ///< The class
+ ///that generates
+ ///the argument
+ ///struct layout.
+ std::unique_ptr<ASTResultSynthesizer> m_result_synthesizer_up;
+ bool m_top_level;
+ };
+
+ //------------------------------------------------------------------
+ /// Constructor
+ ///
+ /// @param[in] expr
+ /// The expression to parse.
+ ///
+ /// @param[in] expr_prefix
+ /// If non-NULL, a C string containing translation-unit level
+ /// definitions to be included when the expression is parsed.
+ ///
+ /// @param[in] language
+ /// If not eLanguageTypeUnknown, a language to use when parsing
+ /// the expression. Currently restricted to those languages
+ /// supported by Clang.
+ ///
+ /// @param[in] desired_type
+ /// If not eResultTypeAny, the type to use for the expression
+ /// result.
+ //------------------------------------------------------------------
+ ClangUserExpression(ExecutionContextScope &exe_scope, const char *expr,
+ const char *expr_prefix, lldb::LanguageType language,
+ ResultType desired_type,
+ const EvaluateExpressionOptions &options);
+
+ ~ClangUserExpression() override;
+
+ //------------------------------------------------------------------
+ /// Parse the expression
+ ///
+ /// @param[in] diagnostic_manager
+ /// A diagnostic manager to report parse errors and warnings to.
+ ///
+ /// @param[in] exe_ctx
+ /// The execution context to use when looking up entities that
+ /// are needed for parsing (locations of functions, types of
+ /// variables, persistent variables, etc.)
+ ///
+ /// @param[in] execution_policy
+ /// Determines whether interpretation is possible or mandatory.
+ ///
+ /// @param[in] keep_result_in_memory
+ /// True if the resulting persistent variable should reside in
+ /// target memory, if applicable.
+ ///
+ /// @return
+ /// True on success (no errors); false otherwise.
+ //------------------------------------------------------------------
+ bool Parse(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx,
+ lldb_private::ExecutionPolicy execution_policy,
+ bool keep_result_in_memory, bool generate_debug_info) override;
+
+ ExpressionTypeSystemHelper *GetTypeSystemHelper() override {
+ return &m_type_system_helper;
+ }
+
+ ClangExpressionDeclMap *DeclMap() { return m_type_system_helper.DeclMap(); }
+
+ void ResetDeclMap() { m_type_system_helper.ResetDeclMap(); }
+
+ void ResetDeclMap(ExecutionContext &exe_ctx,
+ Materializer::PersistentVariableDelegate &result_delegate,
+ bool keep_result_in_memory) {
+ m_type_system_helper.ResetDeclMap(exe_ctx, result_delegate,
+ keep_result_in_memory);
+ }
+
+ lldb::ExpressionVariableSP
+ GetResultAfterDematerialization(ExecutionContextScope *exe_scope) override;
- lldb::ExpressionVariableSP
- GetResultAfterDematerialization(ExecutionContextScope *exe_scope) override;
-
private:
- //------------------------------------------------------------------
- /// Populate m_in_cplusplus_method and m_in_objectivec_method based on the environment.
- //------------------------------------------------------------------
+ //------------------------------------------------------------------
+ /// Populate m_in_cplusplus_method and m_in_objectivec_method based on the
+ /// environment.
+ //------------------------------------------------------------------
+
+ void ScanContext(ExecutionContext &exe_ctx,
+ lldb_private::Error &err) override;
+
+ bool AddArguments(ExecutionContext &exe_ctx, std::vector<lldb::addr_t> &args,
+ lldb::addr_t struct_address,
+ DiagnosticManager &diagnostic_manager) override;
+
+ ClangUserExpressionHelper m_type_system_helper;
+
+ class ResultDelegate : public Materializer::PersistentVariableDelegate {
+ public:
+ ResultDelegate();
+ ConstString GetName() override;
+ void DidDematerialize(lldb::ExpressionVariableSP &variable) override;
+
+ void RegisterPersistentState(PersistentExpressionState *persistent_state);
+ lldb::ExpressionVariableSP &GetVariable();
+
+ private:
+ PersistentExpressionState *m_persistent_state;
+ lldb::ExpressionVariableSP m_variable;
+ };
- void
- ScanContext (ExecutionContext &exe_ctx,
- lldb_private::Error &err) override;
-
- bool
- AddArguments(ExecutionContext &exe_ctx, std::vector<lldb::addr_t> &args, lldb::addr_t struct_address,
- DiagnosticManager &diagnostic_manager) override;
-
- ClangUserExpressionHelper m_type_system_helper;
-
- class ResultDelegate : public Materializer::PersistentVariableDelegate
- {
- public:
- ResultDelegate();
- ConstString GetName() override;
- void DidDematerialize(lldb::ExpressionVariableSP &variable) override;
-
- void RegisterPersistentState(PersistentExpressionState *persistent_state);
- lldb::ExpressionVariableSP &GetVariable();
-
- private:
- PersistentExpressionState *m_persistent_state;
- lldb::ExpressionVariableSP m_variable;
- };
-
- ResultDelegate m_result_delegate;
+ ResultDelegate m_result_delegate;
};
} // namespace lldb_private
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp
index 727e4b3329b..d3af620145b 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp
@@ -1,4 +1,5 @@
-//===-- ClangUserExpression.cpp -------------------------------------*- C++ -*-===//
+//===-- ClangUserExpression.cpp -------------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,14 +8,14 @@
//
//===----------------------------------------------------------------------===//
+#include "ClangUtilityFunction.h"
#include "ClangExpressionDeclMap.h"
#include "ClangExpressionParser.h"
-#include "ClangUtilityFunction.h"
// C Includes
#include <stdio.h>
#if HAVE_SYS_TYPES_H
-# include <sys/types.h>
+#include <sys/types.h>
#endif
// C++ Includes
@@ -41,16 +42,11 @@ using namespace lldb_private;
/// @param[in] name
/// The name of the function, as used in the text.
//------------------------------------------------------------------
-ClangUtilityFunction::ClangUtilityFunction (ExecutionContextScope &exe_scope,
- const char *text,
- const char *name) :
- UtilityFunction (exe_scope, text, name)
-{
-}
+ClangUtilityFunction::ClangUtilityFunction(ExecutionContextScope &exe_scope,
+ const char *text, const char *name)
+ : UtilityFunction(exe_scope, text, name) {}
-ClangUtilityFunction::~ClangUtilityFunction ()
-{
-}
+ClangUtilityFunction::~ClangUtilityFunction() {}
//------------------------------------------------------------------
/// Install the utility function into a process
@@ -64,94 +60,85 @@ ClangUtilityFunction::~ClangUtilityFunction ()
/// @return
/// True on success (no errors); false otherwise.
//------------------------------------------------------------------
-bool
-ClangUtilityFunction::Install(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx)
-{
- if (m_jit_start_addr != LLDB_INVALID_ADDRESS)
- {
- diagnostic_manager.PutCString(eDiagnosticSeverityWarning, "already installed");
- return false;
- }
+bool ClangUtilityFunction::Install(DiagnosticManager &diagnostic_manager,
+ ExecutionContext &exe_ctx) {
+ if (m_jit_start_addr != LLDB_INVALID_ADDRESS) {
+ diagnostic_manager.PutCString(eDiagnosticSeverityWarning,
+ "already installed");
+ return false;
+ }
- ////////////////////////////////////
- // Set up the target and compiler
- //
-
- Target *target = exe_ctx.GetTargetPtr();
+ ////////////////////////////////////
+ // Set up the target and compiler
+ //
- if (!target)
- {
- diagnostic_manager.PutCString(eDiagnosticSeverityError, "invalid target");
- return false;
- }
+ Target *target = exe_ctx.GetTargetPtr();
- Process *process = exe_ctx.GetProcessPtr();
+ if (!target) {
+ diagnostic_manager.PutCString(eDiagnosticSeverityError, "invalid target");
+ return false;
+ }
- if (!process)
- {
- diagnostic_manager.PutCString(eDiagnosticSeverityError, "invalid process");
- return false;
- }
+ Process *process = exe_ctx.GetProcessPtr();
- //////////////////////////
- // Parse the expression
- //
-
- bool keep_result_in_memory = false;
-
- ResetDeclMap(exe_ctx, keep_result_in_memory);
-
- if (!DeclMap()->WillParse(exe_ctx, NULL))
- {
- diagnostic_manager.PutCString(eDiagnosticSeverityError,
- "current process state is unsuitable for expression parsing");
- return false;
- }
+ if (!process) {
+ diagnostic_manager.PutCString(eDiagnosticSeverityError, "invalid process");
+ return false;
+ }
- const bool generate_debug_info = true;
- ClangExpressionParser parser(exe_ctx.GetBestExecutionContextScope(), *this, generate_debug_info);
+ //////////////////////////
+ // Parse the expression
+ //
- unsigned num_errors = parser.Parse(diagnostic_manager);
+ bool keep_result_in_memory = false;
- if (num_errors)
- {
- ResetDeclMap();
+ ResetDeclMap(exe_ctx, keep_result_in_memory);
- return false;
- }
-
- //////////////////////////////////
- // JIT the output of the parser
- //
-
- bool can_interpret = false; // should stay that way
-
- Error jit_error = parser.PrepareForExecution (m_jit_start_addr,
- m_jit_end_addr,
- m_execution_unit_sp,
- exe_ctx,
- can_interpret,
- eExecutionPolicyAlways);
-
- if (m_jit_start_addr != LLDB_INVALID_ADDRESS)
- {
- 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 (!DeclMap()->WillParse(exe_ctx, NULL)) {
+ diagnostic_manager.PutCString(
+ eDiagnosticSeverityError,
+ "current process state is unsuitable for expression parsing");
+ return false;
+ }
+
+ const bool generate_debug_info = true;
+ ClangExpressionParser parser(exe_ctx.GetBestExecutionContextScope(), *this,
+ generate_debug_info);
+
+ unsigned num_errors = parser.Parse(diagnostic_manager);
+
+ if (num_errors) {
+ ResetDeclMap();
+
+ return false;
+ }
+
+ //////////////////////////////////
+ // JIT the output of the parser
+ //
+
+ bool can_interpret = false; // should stay that way
+
+ Error jit_error = parser.PrepareForExecution(
+ m_jit_start_addr, m_jit_end_addr, m_execution_unit_sp, exe_ctx,
+ can_interpret, eExecutionPolicyAlways);
+
+ if (m_jit_start_addr != LLDB_INVALID_ADDRESS) {
+ 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
StreamFile logfile ("/tmp/exprs.txt", "a");
@@ -161,31 +148,26 @@ ClangUtilityFunction::Install(DiagnosticManager &diagnostic_manager, ExecutionCo
m_function_text.c_str());
#endif
- DeclMap()->DidParse();
-
- ResetDeclMap();
-
- if (jit_error.Success())
- {
- return true;
- }
- else
- {
- const char *error_cstr = jit_error.AsCString();
- if (error_cstr && error_cstr[0])
- {
- diagnostic_manager.Printf(eDiagnosticSeverityError, "%s", error_cstr);
- }
- else
- {
- diagnostic_manager.PutCString(eDiagnosticSeverityError, "expression can't be interpreted or run");
- }
- return false;
+ DeclMap()->DidParse();
+
+ ResetDeclMap();
+
+ if (jit_error.Success()) {
+ return true;
+ } else {
+ const char *error_cstr = jit_error.AsCString();
+ if (error_cstr && error_cstr[0]) {
+ diagnostic_manager.Printf(eDiagnosticSeverityError, "%s", error_cstr);
+ } else {
+ diagnostic_manager.PutCString(eDiagnosticSeverityError,
+ "expression can't be interpreted or run");
}
+ return false;
+ }
}
-void
-ClangUtilityFunction::ClangUtilityFunctionHelper::ResetDeclMap(ExecutionContext &exe_ctx, bool keep_result_in_memory)
-{
- m_expr_decl_map_up.reset(new ClangExpressionDeclMap(keep_result_in_memory, nullptr, exe_ctx));
+void ClangUtilityFunction::ClangUtilityFunctionHelper::ResetDeclMap(
+ ExecutionContext &exe_ctx, bool keep_result_in_memory) {
+ m_expr_decl_map_up.reset(
+ new ClangExpressionDeclMap(keep_result_in_memory, nullptr, exe_ctx));
}
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.h b/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.h
index d4ed37eee04..80577199b81 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.h
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.h
@@ -12,24 +12,24 @@
// C Includes
// C++ Includes
-#include <string>
#include <map>
+#include <string>
#include <vector>
// Other libraries and framework includes
// Project includes
#include "ClangExpressionHelper.h"
-#include "lldb/lldb-forward.h"
-#include "lldb/lldb-private.h"
#include "lldb/Core/ClangForward.h"
#include "lldb/Expression/UtilityFunction.h"
+#include "lldb/lldb-forward.h"
+#include "lldb/lldb-private.h"
-namespace lldb_private
-{
+namespace lldb_private {
//----------------------------------------------------------------------
-/// @class ClangUtilityFunction ClangUtilityFunction.h "lldb/Expression/ClangUtilityFunction.h"
+/// @class ClangUtilityFunction ClangUtilityFunction.h
+/// "lldb/Expression/ClangUtilityFunction.h"
/// @brief Encapsulates a single expression for use with Clang
///
/// LLDB uses expressions for various purposes, notably to call functions
@@ -39,97 +39,75 @@ namespace lldb_private
/// simply provide a way to push a function into the target for the debugger to
/// call later on.
//----------------------------------------------------------------------
-class ClangUtilityFunction : public UtilityFunction
-{
+class ClangUtilityFunction : public UtilityFunction {
public:
- class ClangUtilityFunctionHelper : public ClangExpressionHelper
- {
- public:
- ClangUtilityFunctionHelper ()
- {
- }
-
- ~ClangUtilityFunctionHelper() override {}
-
- //------------------------------------------------------------------
- /// Return the object that the parser should use when resolving external
- /// values. May be NULL if everything should be self-contained.
- //------------------------------------------------------------------
- ClangExpressionDeclMap *
- DeclMap() override
- {
- return m_expr_decl_map_up.get();
- }
-
- void
- ResetDeclMap()
- {
- m_expr_decl_map_up.reset();
- }
-
- void
- ResetDeclMap (ExecutionContext & exe_ctx, bool keep_result_in_memory);
-
- //------------------------------------------------------------------
- /// Return the object that the parser should allow to access ASTs.
- /// May be NULL if the ASTs do not need to be transformed.
- ///
- /// @param[in] passthrough
- /// The ASTConsumer that the returned transformer should send
- /// the ASTs to after transformation.
- //------------------------------------------------------------------
- clang::ASTConsumer *
- ASTTransformer(clang::ASTConsumer *passthrough) override
- {
- return nullptr;
- }
- private:
- std::unique_ptr<ClangExpressionDeclMap> m_expr_decl_map_up;
- };
+ class ClangUtilityFunctionHelper : public ClangExpressionHelper {
+ public:
+ ClangUtilityFunctionHelper() {}
+
+ ~ClangUtilityFunctionHelper() override {}
+
//------------------------------------------------------------------
- /// Constructor
- ///
- /// @param[in] text
- /// The text of the function. Must be a full translation unit.
- ///
- /// @param[in] name
- /// The name of the function, as used in the text.
+ /// Return the object that the parser should use when resolving external
+ /// values. May be NULL if everything should be self-contained.
//------------------------------------------------------------------
- ClangUtilityFunction (ExecutionContextScope &exe_scope,
- const char *text,
- const char *name);
-
- ~ClangUtilityFunction() override;
-
- ExpressionTypeSystemHelper *
- GetTypeSystemHelper () override
- {
- return &m_type_system_helper;
+ ClangExpressionDeclMap *DeclMap() override {
+ return m_expr_decl_map_up.get();
}
- ClangExpressionDeclMap *
- DeclMap()
- {
- return m_type_system_helper.DeclMap();
- }
+ void ResetDeclMap() { m_expr_decl_map_up.reset(); }
- void
- ResetDeclMap ()
- {
- m_type_system_helper.ResetDeclMap();
- }
-
- void
- ResetDeclMap (ExecutionContext & exe_ctx, bool keep_result_in_memory)
- {
- m_type_system_helper.ResetDeclMap(exe_ctx, keep_result_in_memory);
+ void ResetDeclMap(ExecutionContext &exe_ctx, bool keep_result_in_memory);
+
+ //------------------------------------------------------------------
+ /// Return the object that the parser should allow to access ASTs.
+ /// May be NULL if the ASTs do not need to be transformed.
+ ///
+ /// @param[in] passthrough
+ /// The ASTConsumer that the returned transformer should send
+ /// the ASTs to after transformation.
+ //------------------------------------------------------------------
+ clang::ASTConsumer *
+ ASTTransformer(clang::ASTConsumer *passthrough) override {
+ return nullptr;
}
- bool
- Install(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx) override;
+ private:
+ std::unique_ptr<ClangExpressionDeclMap> m_expr_decl_map_up;
+ };
+ //------------------------------------------------------------------
+ /// Constructor
+ ///
+ /// @param[in] text
+ /// The text of the function. Must be a full translation unit.
+ ///
+ /// @param[in] name
+ /// The name of the function, as used in the text.
+ //------------------------------------------------------------------
+ ClangUtilityFunction(ExecutionContextScope &exe_scope, const char *text,
+ const char *name);
+
+ ~ClangUtilityFunction() override;
+
+ ExpressionTypeSystemHelper *GetTypeSystemHelper() override {
+ return &m_type_system_helper;
+ }
+
+ ClangExpressionDeclMap *DeclMap() { return m_type_system_helper.DeclMap(); }
+
+ void ResetDeclMap() { m_type_system_helper.ResetDeclMap(); }
+
+ void ResetDeclMap(ExecutionContext &exe_ctx, bool keep_result_in_memory) {
+ m_type_system_helper.ResetDeclMap(exe_ctx, keep_result_in_memory);
+ }
+
+ bool Install(DiagnosticManager &diagnostic_manager,
+ ExecutionContext &exe_ctx) override;
private:
- ClangUtilityFunctionHelper m_type_system_helper; ///< The map to use when parsing and materializing the expression.
+ ClangUtilityFunctionHelper m_type_system_helper; ///< The map to use when
+ ///parsing and materializing
+ ///the expression.
};
} // namespace lldb_private
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp b/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp
index 30e00ff6c72..db3f1589fa5 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp
@@ -11,17 +11,17 @@
#include "ClangExpressionDeclMap.h"
-#include "llvm/Support/raw_ostream.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Intrinsics.h"
-#include "llvm/IR/Module.h"
#include "llvm/IR/LegacyPassManager.h"
-#include "llvm/Transforms/IPO.h"
#include "llvm/IR/Metadata.h"
+#include "llvm/IR/Module.h"
#include "llvm/IR/ValueSymbolTable.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Transforms/IPO.h"
#include "clang/AST/ASTContext.h"
@@ -44,2116 +44,2047 @@ using namespace llvm;
static char ID;
-IRForTarget::FunctionValueCache::FunctionValueCache(Maker const &maker) :
- m_maker(maker),
- m_values()
-{
-}
+IRForTarget::FunctionValueCache::FunctionValueCache(Maker const &maker)
+ : m_maker(maker), m_values() {}
-IRForTarget::FunctionValueCache::~FunctionValueCache()
-{
-}
+IRForTarget::FunctionValueCache::~FunctionValueCache() {}
llvm::Value *
-IRForTarget::FunctionValueCache::GetValue(llvm::Function *function)
-{
- if (!m_values.count(function))
- {
- llvm::Value *ret = m_maker(function);
- m_values[function] = ret;
- return ret;
- }
- return m_values[function];
+IRForTarget::FunctionValueCache::GetValue(llvm::Function *function) {
+ if (!m_values.count(function)) {
+ llvm::Value *ret = m_maker(function);
+ m_values[function] = ret;
+ return ret;
+ }
+ return m_values[function];
}
-static llvm::Value *
-FindEntryInstruction (llvm::Function *function)
-{
- if (function->empty())
- return NULL;
+static llvm::Value *FindEntryInstruction(llvm::Function *function) {
+ if (function->empty())
+ return NULL;
- return function->getEntryBlock().getFirstNonPHIOrDbg();
+ return function->getEntryBlock().getFirstNonPHIOrDbg();
}
-IRForTarget::IRForTarget (lldb_private::ClangExpressionDeclMap *decl_map,
- bool resolve_vars,
- lldb_private::IRExecutionUnit &execution_unit,
- lldb_private::Stream &error_stream,
- const char *func_name) :
- ModulePass(ID),
- m_resolve_vars(resolve_vars),
- m_func_name(func_name),
- m_module(NULL),
- m_decl_map(decl_map),
- m_CFStringCreateWithBytes(NULL),
- m_sel_registerName(NULL),
- m_intptr_ty(NULL),
- m_error_stream(error_stream),
- m_execution_unit(execution_unit),
- m_result_store(NULL),
- m_result_is_pointer(false),
- m_reloc_placeholder(NULL),
- m_entry_instruction_finder (FindEntryInstruction)
-{
-}
+IRForTarget::IRForTarget(lldb_private::ClangExpressionDeclMap *decl_map,
+ bool resolve_vars,
+ lldb_private::IRExecutionUnit &execution_unit,
+ lldb_private::Stream &error_stream,
+ const char *func_name)
+ : ModulePass(ID), m_resolve_vars(resolve_vars), m_func_name(func_name),
+ m_module(NULL), m_decl_map(decl_map), m_CFStringCreateWithBytes(NULL),
+ m_sel_registerName(NULL), m_intptr_ty(NULL), m_error_stream(error_stream),
+ m_execution_unit(execution_unit), m_result_store(NULL),
+ m_result_is_pointer(false), m_reloc_placeholder(NULL),
+ m_entry_instruction_finder(FindEntryInstruction) {}
/* Handy utility functions used at several places in the code */
-static std::string
-PrintValue(const Value *value, bool truncate = false)
-{
- std::string s;
- if (value)
- {
- raw_string_ostream rso(s);
- value->print(rso);
- rso.flush();
- if (truncate)
- s.resize(s.length() - 1);
- }
- return s;
-}
-
-static std::string
-PrintType(const llvm::Type *type, bool truncate = false)
-{
- std::string s;
+static std::string PrintValue(const Value *value, bool truncate = false) {
+ std::string s;
+ if (value) {
raw_string_ostream rso(s);
- type->print(rso);
+ value->print(rso);
rso.flush();
if (truncate)
- s.resize(s.length() - 1);
- return s;
+ s.resize(s.length() - 1);
+ }
+ return s;
}
-IRForTarget::~IRForTarget()
-{
+static std::string PrintType(const llvm::Type *type, bool truncate = false) {
+ std::string s;
+ raw_string_ostream rso(s);
+ type->print(rso);
+ rso.flush();
+ if (truncate)
+ s.resize(s.length() - 1);
+ return s;
}
-bool
-IRForTarget::FixFunctionLinkage(llvm::Function &llvm_function)
-{
- llvm_function.setLinkage(GlobalValue::ExternalLinkage);
+IRForTarget::~IRForTarget() {}
- return true;
+bool IRForTarget::FixFunctionLinkage(llvm::Function &llvm_function) {
+ llvm_function.setLinkage(GlobalValue::ExternalLinkage);
+
+ return true;
}
-clang::NamedDecl *
-IRForTarget::DeclForGlobal (const GlobalValue *global_val, Module *module)
-{
- NamedMDNode *named_metadata = module->getNamedMetadata("clang.global.decl.ptrs");
+clang::NamedDecl *IRForTarget::DeclForGlobal(const GlobalValue *global_val,
+ Module *module) {
+ NamedMDNode *named_metadata =
+ module->getNamedMetadata("clang.global.decl.ptrs");
- if (!named_metadata)
- return NULL;
+ if (!named_metadata)
+ return NULL;
- unsigned num_nodes = named_metadata->getNumOperands();
- unsigned node_index;
+ unsigned num_nodes = named_metadata->getNumOperands();
+ unsigned node_index;
- for (node_index = 0;
- node_index < num_nodes;
- ++node_index)
- {
- llvm::MDNode *metadata_node = dyn_cast<llvm::MDNode>(named_metadata->getOperand(node_index));
- if (!metadata_node)
- return NULL;
+ for (node_index = 0; node_index < num_nodes; ++node_index) {
+ llvm::MDNode *metadata_node =
+ dyn_cast<llvm::MDNode>(named_metadata->getOperand(node_index));
+ if (!metadata_node)
+ return NULL;
- if (metadata_node->getNumOperands() != 2)
- continue;
+ if (metadata_node->getNumOperands() != 2)
+ continue;
- if (mdconst::dyn_extract_or_null<GlobalValue>(metadata_node->getOperand(0)) != global_val)
- continue;
+ if (mdconst::dyn_extract_or_null<GlobalValue>(
+ metadata_node->getOperand(0)) != global_val)
+ continue;
- ConstantInt *constant_int = mdconst::dyn_extract<ConstantInt>(metadata_node->getOperand(1));
+ ConstantInt *constant_int =
+ mdconst::dyn_extract<ConstantInt>(metadata_node->getOperand(1));
- if (!constant_int)
- return NULL;
+ if (!constant_int)
+ return NULL;
- uintptr_t ptr = constant_int->getZExtValue();
+ uintptr_t ptr = constant_int->getZExtValue();
- return reinterpret_cast<clang::NamedDecl *>(ptr);
- }
+ return reinterpret_cast<clang::NamedDecl *>(ptr);
+ }
- return NULL;
+ return NULL;
}
-clang::NamedDecl *
-IRForTarget::DeclForGlobal (GlobalValue *global_val)
-{
- return DeclForGlobal(global_val, m_module);
+clang::NamedDecl *IRForTarget::DeclForGlobal(GlobalValue *global_val) {
+ return DeclForGlobal(global_val, m_module);
}
-bool
-IRForTarget::CreateResultVariable (llvm::Function &llvm_function)
-{
- lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+bool IRForTarget::CreateResultVariable(llvm::Function &llvm_function) {
+ lldb_private::Log *log(
+ lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- if (!m_resolve_vars)
- return true;
+ if (!m_resolve_vars)
+ return true;
- // Find the result variable. If it doesn't exist, we can give up right here.
+ // Find the result variable. If it doesn't exist, we can give up right here.
- ValueSymbolTable& value_symbol_table = m_module->getValueSymbolTable();
+ ValueSymbolTable &value_symbol_table = m_module->getValueSymbolTable();
- std::string result_name_str;
- const char *result_name = NULL;
+ 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))
- {
- result_name = value_name;
- m_result_is_pointer = true;
- break;
- }
+ 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") &&
- strncmp(value_name, "_ZGV", 4))
- {
- result_name = value_name;
- m_result_is_pointer = false;
- break;
- }
+ if (strstr(value_name, "$__lldb_expr_result_ptr") &&
+ strncmp(value_name, "_ZGV", 4)) {
+ result_name = value_name;
+ m_result_is_pointer = true;
+ break;
}
- if (!result_name)
- {
- if (log)
- log->PutCString("Couldn't find result variable");
-
- return true;
+ if (strstr(value_name, "$__lldb_expr_result") &&
+ strncmp(value_name, "_ZGV", 4)) {
+ result_name = value_name;
+ m_result_is_pointer = false;
+ break;
}
+ }
+ if (!result_name) {
if (log)
- log->Printf("Result name: \"%s\"", result_name);
-
- Value *result_value = m_module->getNamedValue(result_name);
+ log->PutCString("Couldn't find result variable");
- if (!result_value)
- {
- if (log)
- log->PutCString("Result variable had no data");
+ return true;
+ }
- m_error_stream.Printf("Internal error [IRForTarget]: Result variable's name (%s) exists, but not its definition\n", result_name);
+ if (log)
+ log->Printf("Result name: \"%s\"", result_name);
- return false;
- }
+ Value *result_value = m_module->getNamedValue(result_name);
+ if (!result_value) {
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");
-
- m_error_stream.Printf("Internal error [IRForTarget]: Result variable (%s) is defined, but is not a global variable\n", result_name);
+ log->PutCString("Result variable had no data");
- return false;
- }
+ m_error_stream.Printf("Internal error [IRForTarget]: Result variable's "
+ "name (%s) exists, but not its definition\n",
+ result_name);
- clang::NamedDecl *result_decl = DeclForGlobal (result_global);
- if (!result_decl)
- {
- if (log)
- log->PutCString("Result variable doesn't have a corresponding Decl");
+ return false;
+ }
- m_error_stream.Printf("Internal error [IRForTarget]: Result variable (%s) does not have a corresponding Clang entity\n", result_name);
+ if (log)
+ log->Printf("Found result in the IR: \"%s\"",
+ PrintValue(result_value, false).c_str());
- return false;
- }
+ GlobalVariable *result_global = dyn_cast<GlobalVariable>(result_value);
+ if (!result_global) {
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());
- }
+ log->PutCString("Result variable isn't a GlobalVariable");
- clang::VarDecl *result_var = dyn_cast<clang::VarDecl>(result_decl);
- if (!result_var)
- {
- if (log)
- log->PutCString("Result variable Decl isn't a VarDecl");
-
- m_error_stream.Printf("Internal error [IRForTarget]: Result variable (%s)'s corresponding Clang entity isn't a variable\n", result_name);
-
- return false;
- }
+ m_error_stream.Printf("Internal error [IRForTarget]: Result variable (%s) "
+ "is defined, but is not a global variable\n",
+ result_name);
- // 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();
+ return false;
+ }
- m_result_type = lldb_private::TypeFromParser(element_qual_type.getAsOpaquePtr(),
- lldb_private::ClangASTContext::GetASTContext(&result_decl->getASTContext()));
- }
- else if (pointer_objcobjpointertype)
- {
- clang::QualType element_qual_type = clang::QualType(pointer_objcobjpointertype->getObjectType(), 0);
+ clang::NamedDecl *result_decl = DeclForGlobal(result_global);
+ if (!result_decl) {
+ if (log)
+ log->PutCString("Result variable doesn't have a corresponding Decl");
- m_result_type = lldb_private::TypeFromParser(element_qual_type.getAsOpaquePtr(),
- lldb_private::ClangASTContext::GetASTContext(&result_decl->getASTContext()));
- }
- else
- {
- if (log)
- log->PutCString("Expected result to have pointer type, but it did not");
+ m_error_stream.Printf("Internal error [IRForTarget]: Result variable (%s) "
+ "does not have a corresponding Clang entity\n",
+ result_name);
- m_error_stream.Printf("Internal error [IRForTarget]: Lvalue result (%s) is not a pointer variable\n", result_name);
+ return false;
+ }
- return false;
- }
- }
- else
- {
- m_result_type = lldb_private::TypeFromParser(result_var->getType().getAsOpaquePtr(),
- lldb_private::ClangASTContext::GetASTContext(&result_decl->getASTContext()));
- }
+ 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());
+ }
- lldb::TargetSP target_sp (m_execution_unit.GetTarget());
- lldb_private::ExecutionContext exe_ctx (target_sp, true);
- if (m_result_type.GetBitSize(exe_ctx.GetBestExecutionContextScope()) == 0)
- {
- lldb_private::StreamString type_desc_stream;
- m_result_type.DumpTypeDescription(&type_desc_stream);
+ 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 (log)
- log->Printf("Result type has size 0");
+ m_error_stream.Printf("Internal error [IRForTarget]: Result variable "
+ "(%s)'s corresponding Clang entity isn't a "
+ "variable\n",
+ result_name);
- m_error_stream.Printf("Error [IRForTarget]: Size of result type '%s' couldn't be determined\n",
- type_desc_stream.GetData());
- return false;
+ 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(),
+ lldb_private::ClangASTContext::GetASTContext(
+ &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(),
+ lldb_private::ClangASTContext::GetASTContext(
+ &result_decl->getASTContext()));
+ } else {
+ if (log)
+ log->PutCString("Expected result to have pointer type, but it did not");
+
+ m_error_stream.Printf("Internal error [IRForTarget]: Lvalue result (%s) "
+ "is not a pointer variable\n",
+ result_name);
+
+ return false;
}
+ } else {
+ m_result_type = lldb_private::TypeFromParser(
+ result_var->getType().getAsOpaquePtr(),
+ lldb_private::ClangASTContext::GetASTContext(
+ &result_decl->getASTContext()));
+ }
+
+ lldb::TargetSP target_sp(m_execution_unit.GetTarget());
+ lldb_private::ExecutionContext exe_ctx(target_sp, true);
+ if (m_result_type.GetBitSize(exe_ctx.GetBestExecutionContextScope()) == 0) {
+ lldb_private::StreamString type_desc_stream;
+ m_result_type.DumpTypeDescription(&type_desc_stream);
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());
- }
+ log->Printf("Result type has size 0");
- m_result_name = lldb_private::ConstString("$RESULT_NAME");
+ m_error_stream.Printf("Error [IRForTarget]: Size of result type '%s' "
+ "couldn't be determined\n",
+ type_desc_stream.GetData());
+ return false;
+ }
- if (log)
- log->Printf("Creating a new result global: \"%s\" with size 0x%" PRIx64,
- m_result_name.GetCString(),
- m_result_type.GetByteSize(nullptr));
+ if (log) {
+ lldb_private::StreamString type_desc_stream;
+ m_result_type.DumpTypeDescription(&type_desc_stream);
- // Construct a new result global and set up its metadata
+ log->Printf("Result decl type: \"%s\"", type_desc_stream.GetData());
+ }
- GlobalVariable *new_result_global = new GlobalVariable((*m_module),
- result_global->getType()->getElementType(),
- false, /* not constant */
- GlobalValue::ExternalLinkage,
- NULL, /* no initializer */
- m_result_name.GetCString ());
+ m_result_name = lldb_private::ConstString("$RESULT_NAME");
- // 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.
+ if (log)
+ log->Printf("Creating a new result global: \"%s\" with size 0x%" PRIx64,
+ m_result_name.GetCString(), m_result_type.GetByteSize(nullptr));
- ConstantInt *new_constant_int = ConstantInt::get(llvm::Type::getInt64Ty(m_module->getContext()),
- reinterpret_cast<uint64_t>(result_decl),
- false);
+ // Construct a new result global and set up its metadata
- llvm::Metadata *values[2];
- values[0] = ConstantAsMetadata::get(new_result_global);
- values[1] = ConstantAsMetadata::get(new_constant_int);
+ GlobalVariable *new_result_global = new GlobalVariable(
+ (*m_module), result_global->getType()->getElementType(),
+ false, /* not constant */
+ GlobalValue::ExternalLinkage, NULL, /* no initializer */
+ m_result_name.GetCString());
- ArrayRef<Metadata *> value_ref(values, 2);
+ // 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.
- 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);
+ ConstantInt *new_constant_int =
+ ConstantInt::get(llvm::Type::getInt64Ty(m_module->getContext()),
+ reinterpret_cast<uint64_t>(result_decl), false);
- if (log)
- log->Printf("Replacing \"%s\" with \"%s\"",
- PrintValue(result_global).c_str(),
- PrintValue(new_result_global).c_str());
+ llvm::Metadata *values[2];
+ values[0] = ConstantAsMetadata::get(new_result_global);
+ values[1] = ConstantAsMetadata::get(new_constant_int);
- 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.
+ ArrayRef<Metadata *> value_ref(values, 2);
- BasicBlock &entry_block(llvm_function.getEntryBlock());
- Instruction *first_entry_instruction(entry_block.getFirstNonPHIOrDbg());
+ 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 (!first_entry_instruction)
- return false;
+ if (log)
+ log->Printf("Replacing \"%s\" with \"%s\"",
+ PrintValue(result_global).c_str(),
+ PrintValue(new_result_global).c_str());
- if (!result_global->hasInitializer())
- {
- if (log)
- log->Printf("Couldn't find initializer for unused variable");
+ 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.
- m_error_stream.Printf("Internal error [IRForTarget]: Result variable (%s) has no writes and no initializer\n", result_name);
+ BasicBlock &entry_block(llvm_function.getEntryBlock());
+ Instruction *first_entry_instruction(entry_block.getFirstNonPHIOrDbg());
- return false;
- }
+ if (!first_entry_instruction)
+ return false;
- Constant *initializer = result_global->getInitializer();
+ if (!result_global->hasInitializer()) {
+ if (log)
+ log->Printf("Couldn't find initializer for unused variable");
- StoreInst *synthesized_store = new StoreInst(initializer,
- new_result_global,
- first_entry_instruction);
+ m_error_stream.Printf("Internal error [IRForTarget]: Result variable "
+ "(%s) has no writes and no initializer\n",
+ result_name);
- if (log)
- log->Printf("Synthesized result store \"%s\"\n", PrintValue(synthesized_store).c_str());
- }
- else
- {
- result_global->replaceAllUsesWith(new_result_global);
+ return false;
}
- if (!m_decl_map->AddPersistentVariable(result_decl,
- m_result_name,
- m_result_type,
- true,
- m_result_is_pointer))
- return false;
-
- result_global->eraseFromParent();
-
- return true;
-}
-
-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());
+ Constant *initializer = result_global->getInitializer();
- if (!m_CFStringCreateWithBytes)
- {
- lldb::addr_t CFStringCreateWithBytes_addr;
-
- static lldb_private::ConstString g_CFStringCreateWithBytes_str ("CFStringCreateWithBytes");
-
- CFStringCreateWithBytes_addr = m_execution_unit.FindSymbol (g_CFStringCreateWithBytes_str);
- if (CFStringCreateWithBytes_addr == LLDB_INVALID_ADDRESS)
- {
- if (log)
- log->PutCString("Couldn't find CFStringCreateWithBytes in the target");
-
- m_error_stream.Printf("Error [IRForTarget]: Rewriting an Objective-C constant string requires CFStringCreateWithBytes\n");
+ StoreInst *synthesized_store =
+ new StoreInst(initializer, new_result_global, first_entry_instruction);
- return false;
- }
-
- if (log)
- log->Printf("Found CFStringCreateWithBytes at 0x%" PRIx64, CFStringCreateWithBytes_addr);
-
- // Build the function type:
- //
- // CFStringRef CFStringCreateWithBytes (
- // CFAllocatorRef alloc,
- // const UInt8 *bytes,
- // CFIndex numBytes,
- // CFStringEncoding encoding,
- // Boolean isExternalRepresentation
- // );
- //
- // We make the following substitutions:
- //
- // CFStringRef -> i8*
- // CFAllocatorRef -> i8*
- // UInt8 * -> i8*
- // 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);
- }
+ if (log)
+ log->Printf("Synthesized result store \"%s\"\n",
+ PrintValue(synthesized_store).c_str());
+ } else {
+ result_global->replaceAllUsesWith(new_result_global);
+ }
+
+ if (!m_decl_map->AddPersistentVariable(
+ result_decl, m_result_name, m_result_type, true, m_result_is_pointer))
+ return false;
- ConstantDataSequential *string_array = NULL;
+ result_global->eraseFromParent();
- if (cstr)
- string_array = dyn_cast<ConstantDataSequential>(cstr->getInitializer());
+ return true;
+}
- 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 */
+bool IRForTarget::RewriteObjCConstString(llvm::GlobalVariable *ns_str,
+ llvm::GlobalVariable *cstr) {
+ lldb_private::Log *log(
+ lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- Value *argument_array[5];
+ Type *ns_str_ty = ns_str->getType();
- 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;
+ 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());
- ArrayRef <Value *> CFSCWB_arguments(argument_array, 5);
+ if (!m_CFStringCreateWithBytes) {
+ lldb::addr_t CFStringCreateWithBytes_addr;
- 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)));
- });
+ static lldb_private::ConstString g_CFStringCreateWithBytes_str(
+ "CFStringCreateWithBytes");
- if (!UnfoldConstant(ns_str, nullptr, CFSCWB_Caller, m_entry_instruction_finder, m_error_stream))
- {
- if (log)
- log->PutCString("Couldn't replace the NSString with the result of the call");
+ CFStringCreateWithBytes_addr =
+ m_execution_unit.FindSymbol(g_CFStringCreateWithBytes_str);
+ if (CFStringCreateWithBytes_addr == LLDB_INVALID_ADDRESS) {
+ if (log)
+ log->PutCString("Couldn't find CFStringCreateWithBytes in the target");
- m_error_stream.Printf("error [IRForTarget internal]: Couldn't replace an Objective-C constant string with a dynamic string\n");
+ m_error_stream.Printf("Error [IRForTarget]: Rewriting an Objective-C "
+ "constant string requires "
+ "CFStringCreateWithBytes\n");
- return false;
+ return false;
}
- ns_str->eraseFromParent();
-
- return true;
-}
-
-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 (log)
+ log->Printf("Found CFStringCreateWithBytes at 0x%" PRIx64,
+ CFStringCreateWithBytes_addr);
- if (!nsstring_global)
- {
- if (log)
- log->PutCString("NSString variable is not a GlobalVariable");
+ // Build the function type:
+ //
+ // CFStringRef CFStringCreateWithBytes (
+ // CFAllocatorRef alloc,
+ // const UInt8 *bytes,
+ // CFIndex numBytes,
+ // CFStringEncoding encoding,
+ // Boolean isExternalRepresentation
+ // );
+ //
+ // We make the following substitutions:
+ //
+ // CFStringRef -> i8*
+ // CFAllocatorRef -> i8*
+ // UInt8 * -> i8*
+ // 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, nullptr, CFSCWB_Caller,
+ m_entry_instruction_finder, m_error_stream)) {
+ if (log)
+ log->PutCString(
+ "Couldn't replace the NSString with the result of the call");
- m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C constant string is not a global variable\n");
+ m_error_stream.Printf("error [IRForTarget internal]: Couldn't replace an "
+ "Objective-C constant string with a dynamic "
+ "string\n");
- return false;
- }
+ return false;
+ }
- if (!nsstring_global->hasInitializer())
- {
- if (log)
- log->PutCString("NSString variable does not have an initializer");
+ ns_str->eraseFromParent();
- m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C constant string does not have an initializer\n");
+ return true;
+}
- return false;
- }
+bool IRForTarget::RewriteObjCConstStrings() {
+ lldb_private::Log *log(
+ lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- ConstantStruct *nsstring_struct = dyn_cast<ConstantStruct>(nsstring_global->getInitializer());
+ ValueSymbolTable &value_symbol_table = m_module->getValueSymbolTable();
- if (!nsstring_struct)
- {
- if (log)
- log->PutCString("NSString variable's initializer is not a ConstantStruct");
+ 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();
- m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C constant string is not a structure constant\n");
+ if (strstr(value_name_cstr, "_unnamed_cfstring_")) {
+ Value *nsstring_value = vi->second;
- return false;
- }
+ GlobalVariable *nsstring_global =
+ dyn_cast<GlobalVariable>(nsstring_value);
- // We expect the following structure:
- //
- // struct {
- // int *isa;
- // int flags;
- // char *str;
- // long length;
- // };
+ if (!nsstring_global) {
+ if (log)
+ log->PutCString("NSString variable is not a GlobalVariable");
- 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());
+ m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "
+ "constant string is not a global variable\n");
- m_error_stream.Printf("Internal error [IRForTarget]: The struct for an Objective-C constant string is not as expected\n");
+ return false;
+ }
- return false;
- }
+ if (!nsstring_global->hasInitializer()) {
+ if (log)
+ log->PutCString("NSString variable does not have an initializer");
- Constant *nsstring_member = nsstring_struct->getOperand(2);
+ m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "
+ "constant string does not have an initializer\n");
- if (!nsstring_member)
- {
- if (log)
- log->PutCString("NSString initializer's str element was empty");
+ return false;
+ }
- m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C constant string does not have a string initializer\n");
+ ConstantStruct *nsstring_struct =
+ dyn_cast<ConstantStruct>(nsstring_global->getInitializer());
- return false;
- }
+ if (!nsstring_struct) {
+ if (log)
+ log->PutCString(
+ "NSString variable's initializer is not a ConstantStruct");
- ConstantExpr *nsstring_expr = dyn_cast<ConstantExpr>(nsstring_member);
+ m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "
+ "constant string is not a structure constant\n");
- if (!nsstring_expr)
- {
- if (log)
- log->PutCString("NSString initializer's str element is not a ConstantExpr");
+ return false;
+ }
+
+ // We expect the following structure:
+ //
+ // struct {
+ // int *isa;
+ // int flags;
+ // 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());
- m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C constant string's string initializer is not constant\n");
+ m_error_stream.Printf("Internal error [IRForTarget]: The struct for an "
+ "Objective-C constant string is not as "
+ "expected\n");
- return false;
- }
+ 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());
+ Constant *nsstring_member = nsstring_struct->getOperand(2);
- m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C constant string's string initializer is not an array\n");
+ if (!nsstring_member) {
+ if (log)
+ log->PutCString("NSString initializer's str element was empty");
- return false;
- }
+ m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "
+ "constant string does not have a string "
+ "initializer\n");
- Constant *nsstring_cstr = nsstring_expr->getOperand(0);
+ return false;
+ }
- GlobalVariable *cstr_global = dyn_cast<GlobalVariable>(nsstring_cstr);
+ ConstantExpr *nsstring_expr = dyn_cast<ConstantExpr>(nsstring_member);
- if (!cstr_global)
- {
- if (log)
- log->PutCString("NSString initializer's str element is not a GlobalVariable");
+ if (!nsstring_expr) {
+ if (log)
+ log->PutCString(
+ "NSString initializer's str element is not a ConstantExpr");
- m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C constant string's string initializer doesn't point to a global\n");
+ m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "
+ "constant string's string initializer is not "
+ "constant\n");
- return false;
- }
+ return false;
+ }
- if (!cstr_global->hasInitializer())
- {
- if (log)
- log->PutCString("NSString initializer's str element does not have an initializer");
+ 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());
- m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C constant string's string initializer doesn't point to initialized data\n");
+ m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "
+ "constant string's string initializer is not an "
+ "array\n");
- return false;
- }
+ return false;
+ }
- /*
- if (!cstr_array)
- {
- if (log)
- log->PutCString("NSString initializer's str element is not a ConstantArray");
+ Constant *nsstring_cstr = nsstring_expr->getOperand(0);
- 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");
+ GlobalVariable *cstr_global = dyn_cast<GlobalVariable>(nsstring_cstr);
- return false;
- }
+ if (!cstr_global) {
+ if (log)
+ log->PutCString(
+ "NSString initializer's str element is not a GlobalVariable");
- if (!cstr_array->isCString())
- {
- if (log)
- log->PutCString("NSString initializer's str element is not a C string array");
+ m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "
+ "constant string's string initializer doesn't "
+ "point to a global\n");
- 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;
+ }
- return false;
- }
- */
+ if (!cstr_global->hasInitializer()) {
+ if (log)
+ log->PutCString("NSString initializer's str element does not have an "
+ "initializer");
- ConstantDataArray *cstr_array = dyn_cast<ConstantDataArray>(cstr_global->getInitializer());
+ m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "
+ "constant string's string initializer doesn't "
+ "point to initialized data\n");
- if (log)
- {
- if (cstr_array)
- log->Printf("Found NSString constant %s, which contains \"%s\"", value_name_cstr, cstr_array->getAsString().str().c_str());
- else
- log->Printf("Found NSString constant %s, which contains \"\"", value_name_cstr);
- }
+ 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)
+ log->Printf("Found NSString constant %s, which contains \"%s\"",
+ value_name_cstr, cstr_array->getAsString().str().c_str());
+ else
+ log->Printf("Found NSString constant %s, which contains \"\"",
+ value_name_cstr);
+ }
- if (!cstr_array)
- cstr_global = NULL;
+ if (!cstr_array)
+ cstr_global = NULL;
- if (!RewriteObjCConstString(nsstring_global, cstr_global))
- {
- if (log)
- log->PutCString("Error rewriting the constant string");
+ 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.
+ // We don't print an error message here because RewriteObjCConstString
+ // has done so for us.
- return false;
- }
- }
+ 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();
+ 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 (!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 (!gv) {
+ if (log)
+ log->PutCString(
+ "__CFConstantStringClassReference is not a global variable");
- m_error_stream.Printf("Internal error [IRForTarget]: Found a CFConstantStringClassReference, but it is not a global object\n");
+ m_error_stream.Printf("Internal error [IRForTarget]: Found a "
+ "CFConstantStringClassReference, but it is not a "
+ "global object\n");
- return false;
- }
+ return false;
+ }
- gv->eraseFromParent();
+ gv->eraseFromParent();
- break;
- }
+ break;
}
+ }
- return true;
+ return true;
}
-static bool IsObjCSelectorRef (Value *value)
-{
- GlobalVariable *global_variable = dyn_cast<GlobalVariable>(value);
+static bool IsObjCSelectorRef(Value *value) {
+ GlobalVariable *global_variable = dyn_cast<GlobalVariable>(value);
- if (!global_variable || !global_variable->hasName() || !global_variable->getName().startswith("OBJC_SELECTOR_REFERENCES_"))
- return false;
+ if (!global_variable || !global_variable->hasName() ||
+ !global_variable->getName().startswith("OBJC_SELECTOR_REFERENCES_"))
+ return false;
- return true;
+ return true;
}
// This function does not report errors; its callers are responsible.
-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** @"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.
- //
- // @"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.
+bool IRForTarget::RewriteObjCSelector(Instruction *selector_load) {
+ lldb_private::Log *log(
+ lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- // Find the pointer's initializer (a ConstantExpr with opcode GetElementPtr) and get the string from its target
+ LoadInst *load = dyn_cast<LoadInst>(selector_load);
- GlobalVariable *_objc_selector_references_ = dyn_cast<GlobalVariable>(load->getPointerOperand());
+ if (!load)
+ return false;
- if (!_objc_selector_references_ || !_objc_selector_references_->hasInitializer())
- return false;
+ // Unpack the message name from the selector. In LLVM IR, an objc_msgSend
+ // gets represented as
+ //
+ // %tmp = load i8** @"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.
+ //
+ // @"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();
+ Constant *osr_initializer = _objc_selector_references_->getInitializer();
- ConstantExpr *osr_initializer_expr = dyn_cast<ConstantExpr>(osr_initializer);
+ ConstantExpr *osr_initializer_expr = dyn_cast<ConstantExpr>(osr_initializer);
- if (!osr_initializer_expr || osr_initializer_expr->getOpcode() != Instruction::GetElementPtr)
- return false;
+ if (!osr_initializer_expr ||
+ osr_initializer_expr->getOpcode() != Instruction::GetElementPtr)
+ return false;
- Value *osr_initializer_base = osr_initializer_expr->getOperand(0);
+ Value *osr_initializer_base = osr_initializer_expr->getOperand(0);
- if (!osr_initializer_base)
- return false;
+ if (!osr_initializer_base)
+ return false;
- // Find the string's initializer (a ConstantArray) and get the string from it
+ // Find the string's initializer (a ConstantArray) and get the string from it
- GlobalVariable *_objc_meth_var_name_ = dyn_cast<GlobalVariable>(osr_initializer_base);
+ GlobalVariable *_objc_meth_var_name_ =
+ dyn_cast<GlobalVariable>(osr_initializer_base);
- if (!_objc_meth_var_name_ || !_objc_meth_var_name_->hasInitializer())
- return false;
+ if (!_objc_meth_var_name_ || !_objc_meth_var_name_->hasInitializer())
+ return false;
- Constant *omvn_initializer = _objc_meth_var_name_->getInitializer();
+ Constant *omvn_initializer = _objc_meth_var_name_->getInitializer();
- ConstantDataArray *omvn_initializer_array = dyn_cast<ConstantDataArray>(omvn_initializer);
+ ConstantDataArray *omvn_initializer_array =
+ dyn_cast<ConstantDataArray>(omvn_initializer);
- if (!omvn_initializer_array->isString())
- return false;
+ if (!omvn_initializer_array->isString())
+ return false;
- std::string omvn_initializer_string = omvn_initializer_array->getAsString();
+ std::string omvn_initializer_string = omvn_initializer_array->getAsString();
- if (log)
- log->Printf("Found Objective-C selector reference \"%s\"", omvn_initializer_string.c_str());
+ if (log)
+ log->Printf("Found Objective-C selector reference \"%s\"",
+ omvn_initializer_string.c_str());
- // Construct a call to sel_registerName
+ // Construct a call to sel_registerName
- if (!m_sel_registerName)
- {
- lldb::addr_t sel_registerName_addr;
+ if (!m_sel_registerName) {
+ lldb::addr_t sel_registerName_addr;
- static lldb_private::ConstString g_sel_registerName_str ("sel_registerName");
- sel_registerName_addr = m_execution_unit.FindSymbol (g_sel_registerName_str);
- if (sel_registerName_addr == LLDB_INVALID_ADDRESS)
- return false;
+ static lldb_private::ConstString g_sel_registerName_str("sel_registerName");
+ sel_registerName_addr = m_execution_unit.FindSymbol(g_sel_registerName_str);
+ if (sel_registerName_addr == LLDB_INVALID_ADDRESS)
+ return false;
- if (log)
- log->Printf("Found sel_registerName at 0x%" PRIx64, sel_registerName_addr);
+ if (log)
+ log->Printf("Found sel_registerName at 0x%" PRIx64,
+ sel_registerName_addr);
- // Build the function type: struct objc_selector *sel_registerName(uint8_t*)
+ // 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());
+ // 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 *type_array[1];
- type_array[0] = llvm::Type::getInt8PtrTy(m_module->getContext());
+ type_array[0] = llvm::Type::getInt8PtrTy(m_module->getContext());
- ArrayRef<Type *> srN_arg_types(type_array, 1);
+ ArrayRef<Type *> srN_arg_types(type_array, 1);
- llvm::Type *srN_type = FunctionType::get(sel_ptr_type, srN_arg_types, false);
+ 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);
- }
+ // 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];
+ Value *argument_array[1];
- Constant *omvn_pointer = ConstantExpr::getBitCast(_objc_meth_var_name_, Type::getInt8PtrTy(m_module->getContext()));
+ Constant *omvn_pointer = ConstantExpr::getBitCast(
+ _objc_meth_var_name_, Type::getInt8PtrTy(m_module->getContext()));
- argument_array[0] = omvn_pointer;
+ argument_array[0] = omvn_pointer;
- ArrayRef<Value *> srN_arguments(argument_array, 1);
+ ArrayRef<Value *> srN_arguments(argument_array, 1);
- CallInst *srN_call = CallInst::Create(m_sel_registerName,
- srN_arguments,
- "sel_registerName",
- selector_load);
+ CallInst *srN_call = CallInst::Create(m_sel_registerName, srN_arguments,
+ "sel_registerName", selector_load);
- // Replace the load with the call in all users
+ // Replace the load with the call in all users
- selector_load->replaceAllUsesWith(srN_call);
+ selector_load->replaceAllUsesWith(srN_call);
- selector_load->eraseFromParent();
+ selector_load->eraseFromParent();
- return true;
+ return true;
}
-bool
-IRForTarget::RewriteObjCSelectors (BasicBlock &basic_block)
-{
- lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+bool IRForTarget::RewriteObjCSelectors(BasicBlock &basic_block) {
+ lldb_private::Log *log(
+ lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- BasicBlock::iterator ii;
+ BasicBlock::iterator ii;
- typedef SmallVector <Instruction*, 2> InstrList;
- typedef InstrList::iterator InstrIterator;
+ typedef SmallVector<Instruction *, 2> InstrList;
+ typedef InstrList::iterator InstrIterator;
- InstrList selector_loads;
+ InstrList selector_loads;
- for (ii = basic_block.begin();
- ii != basic_block.end();
- ++ii)
- {
- Instruction &inst = *ii;
+ 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);
- }
+ if (LoadInst *load = dyn_cast<LoadInst>(&inst))
+ if (IsObjCSelectorRef(load->getPointerOperand()))
+ selector_loads.push_back(&inst);
+ }
- InstrIterator iter;
+ InstrIterator iter;
- for (iter = selector_loads.begin();
- iter != selector_loads.end();
- ++iter)
- {
- if (!RewriteObjCSelector(*iter))
- {
- m_error_stream.Printf("Internal error [IRForTarget]: Couldn't change a static reference to an Objective-C selector to a dynamic reference\n");
+ for (iter = selector_loads.begin(); iter != selector_loads.end(); ++iter) {
+ if (!RewriteObjCSelector(*iter)) {
+ 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");
+ if (log)
+ log->PutCString(
+ "Couldn't rewrite a reference to an Objective-C selector");
- return false;
- }
+ return false;
}
+ }
- return true;
+ return true;
}
// This function does not report errors; its callers are responsible.
-bool
-IRForTarget::RewritePersistentAlloc (llvm::Instruction *persistent_alloc)
-{
- lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+bool IRForTarget::RewritePersistentAlloc(llvm::Instruction *persistent_alloc) {
+ lldb_private::Log *log(
+ lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- AllocaInst *alloc = dyn_cast<AllocaInst>(persistent_alloc);
+ AllocaInst *alloc = dyn_cast<AllocaInst>(persistent_alloc);
- MDNode *alloc_md = alloc->getMetadata("clang.decl.ptr");
+ MDNode *alloc_md = alloc->getMetadata("clang.decl.ptr");
- if (!alloc_md || !alloc_md->getNumOperands())
- return false;
+ if (!alloc_md || !alloc_md->getNumOperands())
+ return false;
- ConstantInt *constant_int = mdconst::dyn_extract<ConstantInt>(alloc_md->getOperand(0));
+ ConstantInt *constant_int =
+ mdconst::dyn_extract<ConstantInt>(alloc_md->getOperand(0));
- if (!constant_int)
- return false;
+ if (!constant_int)
+ return false;
- // We attempt to register this as a new persistent variable with the DeclMap.
+ // We attempt to register this as a new persistent variable with the DeclMap.
- uintptr_t ptr = constant_int->getZExtValue();
+ uintptr_t ptr = constant_int->getZExtValue();
- clang::VarDecl *decl = reinterpret_cast<clang::VarDecl *>(ptr);
+ clang::VarDecl *decl = reinterpret_cast<clang::VarDecl *>(ptr);
- lldb_private::TypeFromParser result_decl_type (decl->getType().getAsOpaquePtr(),
- lldb_private::ClangASTContext::GetASTContext(&decl->getASTContext()));
+ lldb_private::TypeFromParser result_decl_type(
+ decl->getType().getAsOpaquePtr(),
+ lldb_private::ClangASTContext::GetASTContext(&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;
+ 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());
+ 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.
+ // 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");
+ NamedMDNode *named_metadata =
+ m_module->getOrInsertNamedMetadata("clang.global.decl.ptrs");
- llvm::Metadata *values[2];
- values[0] = ConstantAsMetadata::get(persistent_global);
- values[1] = ConstantAsMetadata::get(constant_int);
+ llvm::Metadata *values[2];
+ values[0] = ConstantAsMetadata::get(persistent_global);
+ values[1] = ConstantAsMetadata::get(constant_int);
- ArrayRef<llvm::Metadata *> value_ref(values, 2);
+ ArrayRef<llvm::Metadata *> value_ref(values, 2);
- MDNode *persistent_global_md = MDNode::get(m_module->getContext(), value_ref);
- named_metadata->addOperand(persistent_global_md);
+ 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.
+ // 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);
+ 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());
+ if (log)
+ log->Printf("Replacing \"%s\" with \"%s\"", PrintValue(alloc).c_str(),
+ PrintValue(persistent_load).c_str());
- alloc->replaceAllUsesWith(persistent_load);
- alloc->eraseFromParent();
+ alloc->replaceAllUsesWith(persistent_load);
+ alloc->eraseFromParent();
- return true;
+ return true;
}
-bool
-IRForTarget::RewritePersistentAllocs(llvm::BasicBlock &basic_block)
-{
- if (!m_resolve_vars)
- return true;
+bool IRForTarget::RewritePersistentAllocs(llvm::BasicBlock &basic_block) {
+ if (!m_resolve_vars)
+ return true;
- lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ lldb_private::Log *log(
+ lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- BasicBlock::iterator ii;
+ BasicBlock::iterator ii;
- typedef SmallVector <Instruction*, 2> InstrList;
- typedef InstrList::iterator InstrIterator;
+ typedef SmallVector<Instruction *, 2> InstrList;
+ typedef InstrList::iterator InstrIterator;
- InstrList pvar_allocs;
+ InstrList pvar_allocs;
- for (ii = basic_block.begin();
- ii != basic_block.end();
- ++ii)
- {
- Instruction &inst = *ii;
+ 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 (AllocaInst *alloc = dyn_cast<AllocaInst>(&inst)) {
+ llvm::StringRef alloc_name = alloc->getName();
- if (alloc_name.startswith("$") &&
- !alloc_name.startswith("$__lldb"))
- {
- if (alloc_name.find_first_of("0123456789") == 1)
- {
- if (log)
- log->Printf("Rejecting a numeric persistent variable.");
+ if (alloc_name.startswith("$") && !alloc_name.startswith("$__lldb")) {
+ if (alloc_name.find_first_of("0123456789") == 1) {
+ if (log)
+ log->Printf("Rejecting a numeric persistent variable.");
- m_error_stream.Printf("Error [IRForTarget]: Names starting with $0, $1, ... are reserved for use as result names\n");
+ 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);
- }
+ return false;
}
+
+ pvar_allocs.push_back(alloc);
+ }
}
+ }
- InstrIterator iter;
+ InstrIterator iter;
- for (iter = pvar_allocs.begin();
- iter != pvar_allocs.end();
- ++iter)
- {
- if (!RewritePersistentAlloc(*iter))
- {
- m_error_stream.Printf("Internal error [IRForTarget]: Couldn't rewrite the creation of a persistent variable\n");
+ for (iter = pvar_allocs.begin(); iter != pvar_allocs.end(); ++iter) {
+ if (!RewritePersistentAlloc(*iter)) {
+ 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");
+ if (log)
+ log->PutCString(
+ "Couldn't rewrite the creation of a persistent variable");
- return false;
- }
+ return false;
}
+ }
- return true;
+ return true;
}
-bool
-IRForTarget::MaterializeInitializer (uint8_t *data, Constant *initializer)
-{
- if (!initializer)
- return true;
+bool IRForTarget::MaterializeInitializer(uint8_t *data, Constant *initializer) {
+ if (!initializer)
+ return true;
- lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ lldb_private::Log *log(
+ lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- if (log && log->GetVerbose())
- log->Printf(" MaterializeInitializer(%p, %s)", (void *)data, PrintValue(initializer).c_str());
+ if (log && log->GetVerbose())
+ log->Printf(" MaterializeInitializer(%p, %s)", (void *)data,
+ PrintValue(initializer).c_str());
- Type *initializer_type = initializer->getType();
+ Type *initializer_type = initializer->getType();
- if (ConstantInt *int_initializer = dyn_cast<ConstantInt>(initializer))
- {
- size_t constant_size = m_target_data->getTypeStoreSize(initializer_type);
- lldb_private::Scalar scalar = int_initializer->getValue().zextOrTrunc(llvm::NextPowerOf2(constant_size) * 8);
+ if (ConstantInt *int_initializer = dyn_cast<ConstantInt>(initializer)) {
+ size_t constant_size = m_target_data->getTypeStoreSize(initializer_type);
+ lldb_private::Scalar scalar = int_initializer->getValue().zextOrTrunc(
+ llvm::NextPowerOf2(constant_size) * 8);
- lldb_private::Error get_data_error;
- if (!scalar.GetAsMemoryData(data, constant_size, lldb_private::endian::InlHostByteOrder(), get_data_error))
- return false;
+ lldb_private::Error get_data_error;
+ if (!scalar.GetAsMemoryData(data, constant_size,
+ lldb_private::endian::InlHostByteOrder(),
+ get_data_error))
+ return false;
- return true;
- }
- else if (ConstantDataArray *array_initializer = dyn_cast<ConstantDataArray>(initializer))
- {
- if (array_initializer->isString())
- {
- std::string array_initializer_string = array_initializer->getAsString();
- memcpy (data, array_initializer_string.c_str(), m_target_data->getTypeStoreSize(initializer_type));
- }
- else
- {
- 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;
- }
- }
- return true;
- }
- else if (ConstantStruct *struct_initializer = dyn_cast<ConstantStruct>(initializer))
- {
- StructType *struct_initializer_type = struct_initializer->getType();
- const StructLayout *struct_layout = m_target_data->getStructLayout(struct_initializer_type);
-
- for (unsigned i = 0;
- i < struct_initializer->getNumOperands();
- ++i)
- {
- if (!MaterializeInitializer(data + struct_layout->getElementOffset(i), struct_initializer->getOperand(i)))
- return false;
- }
- return true;
+ return true;
+ } else if (ConstantDataArray *array_initializer =
+ dyn_cast<ConstantDataArray>(initializer)) {
+ if (array_initializer->isString()) {
+ std::string array_initializer_string = array_initializer->getAsString();
+ memcpy(data, array_initializer_string.c_str(),
+ m_target_data->getTypeStoreSize(initializer_type));
+ } else {
+ 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;
+ }
}
- else if (isa<ConstantAggregateZero>(initializer))
- {
- memset(data, 0, m_target_data->getTypeStoreSize(initializer_type));
- return true;
+ return true;
+ } else if (ConstantStruct *struct_initializer =
+ dyn_cast<ConstantStruct>(initializer)) {
+ StructType *struct_initializer_type = struct_initializer->getType();
+ const StructLayout *struct_layout =
+ m_target_data->getStructLayout(struct_initializer_type);
+
+ for (unsigned i = 0; i < struct_initializer->getNumOperands(); ++i) {
+ if (!MaterializeInitializer(data + struct_layout->getElementOffset(i),
+ struct_initializer->getOperand(i)))
+ return false;
}
- return false;
+ return true;
+ } else if (isa<ConstantAggregateZero>(initializer)) {
+ memset(data, 0, m_target_data->getTypeStoreSize(initializer_type));
+ return true;
+ }
+ return false;
}
// This function does not report errors; its callers are responsible.
-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())
- {
- default:
- break;
- case Instruction::GetElementPtr:
- case Instruction::BitCast:
- Value *s = constant_expr->getOperand(0);
- if (!MaybeHandleVariable(s))
- return false;
- }
+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()) {
+ default:
+ break;
+ case Instruction::GetElementPtr:
+ case Instruction::BitCast:
+ Value *s = constant_expr->getOperand(0);
+ if (!MaybeHandleVariable(s))
+ return false;
}
- else if (GlobalVariable *global_variable = dyn_cast<GlobalVariable>(llvm_value_ptr))
- {
- if (!GlobalValue::isExternalLinkage(global_variable->getLinkage()))
- return true;
-
- clang::NamedDecl *named_decl = DeclForGlobal(global_variable);
-
- if (!named_decl)
- {
- if (IsObjCSelectorRef(llvm_value_ptr))
- return true;
-
- if (!global_variable->hasExternalLinkage())
- return true;
+ } else if (GlobalVariable *global_variable =
+ dyn_cast<GlobalVariable>(llvm_value_ptr)) {
+ if (!GlobalValue::isExternalLinkage(global_variable->getLinkage()))
+ return true;
- if (log)
- log->Printf("Found global variable \"%s\" without metadata", global_variable->getName().str().c_str());
+ clang::NamedDecl *named_decl = DeclForGlobal(global_variable);
- 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;
+ if (!named_decl) {
+ if (IsObjCSelectorRef(llvm_value_ptr))
+ return true;
- lldb_private::CompilerType compiler_type(&value_decl->getASTContext(), value_decl->getType());
-
- const Type *value_type = NULL;
-
- if (name[0] == '$')
- {
- // The $__lldb_expr_result name indicates the return value has allocated as
- // a static variable. Per the comment at ASTResultSynthesizer::SynthesizeBodyResult,
- // accesses to this static variable need to be redirected to the result of dereferencing
- // a pointer that is passed in as one of the arguments.
- //
- // Consequently, when reporting the size of the type, we report a pointer type pointing
- // to the type of $__lldb_expr_result, not the type itself.
- //
- // We also do this for any user-declared persistent variables.
- compiler_type = compiler_type.GetPointerType();
- value_type = PointerType::get(global_variable->getType(), 0);
- }
- else
- {
- value_type = global_variable->getType();
- }
+ if (!global_variable->hasExternalLinkage())
+ return true;
- const uint64_t value_size = compiler_type.GetByteSize(nullptr);
- lldb::offset_t value_alignment = (compiler_type.GetTypeBitAlign() + 7ull) / 8ull;
+ if (log)
+ log->Printf("Found global variable \"%s\" without metadata",
+ global_variable->getName().str().c_str());
- if (log)
- {
- log->Printf("Type of \"%s\" is [clang \"%s\", llvm \"%s\"] [size %" PRIu64 ", align %" PRIu64 "]",
- name.c_str(), lldb_private::ClangUtil::GetQualType(compiler_type).getAsString().c_str(),
- PrintType(value_type).c_str(), value_size, value_alignment);
- }
+ 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::CompilerType compiler_type(&value_decl->getASTContext(),
+ value_decl->getType());
+
+ const Type *value_type = NULL;
+
+ if (name[0] == '$') {
+ // The $__lldb_expr_result name indicates the return value has allocated
+ // as
+ // a static variable. Per the comment at
+ // ASTResultSynthesizer::SynthesizeBodyResult,
+ // accesses to this static variable need to be redirected to the result of
+ // dereferencing
+ // a pointer that is passed in as one of the arguments.
+ //
+ // Consequently, when reporting the size of the type, we report a pointer
+ // type pointing
+ // to the type of $__lldb_expr_result, not the type itself.
+ //
+ // We also do this for any user-declared persistent variables.
+ compiler_type = compiler_type.GetPointerType();
+ value_type = PointerType::get(global_variable->getType(), 0);
+ } else {
+ value_type = global_variable->getType();
+ }
- if (named_decl && !m_decl_map->AddValueToStruct(named_decl,
- lldb_private::ConstString (name.c_str()),
- llvm_value_ptr,
- value_size,
- value_alignment))
- {
- if (!global_variable->hasExternalLinkage())
- return true;
- else
- return true;
- }
+ const uint64_t value_size = compiler_type.GetByteSize(nullptr);
+ lldb::offset_t value_alignment =
+ (compiler_type.GetTypeBitAlign() + 7ull) / 8ull;
+
+ if (log) {
+ log->Printf("Type of \"%s\" is [clang \"%s\", llvm \"%s\"] [size %" PRIu64
+ ", align %" PRIu64 "]",
+ name.c_str(),
+ lldb_private::ClangUtil::GetQualType(compiler_type)
+ .getAsString()
+ .c_str(),
+ PrintType(value_type).c_str(), value_size, value_alignment);
}
- else if (dyn_cast<llvm::Function>(llvm_value_ptr))
- {
- if (log)
- log->Printf("Function pointers aren't handled right now");
- return false;
+ if (named_decl &&
+ !m_decl_map->AddValueToStruct(
+ named_decl, lldb_private::ConstString(name.c_str()), llvm_value_ptr,
+ value_size, value_alignment)) {
+ if (!global_variable->hasExternalLinkage())
+ return true;
+ else
+ return true;
}
+ } else if (dyn_cast<llvm::Function>(llvm_value_ptr)) {
+ if (log)
+ log->Printf("Function pointers aren't handled right now");
- return true;
+ 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));
+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_private::ConstString name(symbol->getName().str().c_str());
- lldb::addr_t symbol_addr = m_decl_map->GetSymbolAddress (name, lldb::eSymbolTypeAny);
+ 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());
+ if (symbol_addr == LLDB_INVALID_ADDRESS) {
+ if (log)
+ log->Printf("Symbol \"%s\" had no address", name.GetCString());
- return false;
- }
+ return false;
+ }
- if (log)
- log->Printf("Found \"%s\" at 0x%" PRIx64, name.GetCString(), symbol_addr);
+ if (log)
+ log->Printf("Found \"%s\" at 0x%" PRIx64, name.GetCString(), symbol_addr);
- Type *symbol_type = symbol->getType();
+ Type *symbol_type = symbol->getType();
- Constant *symbol_addr_int = ConstantInt::get(m_intptr_ty, symbol_addr, false);
+ Constant *symbol_addr_int = ConstantInt::get(m_intptr_ty, symbol_addr, false);
- Value *symbol_addr_ptr = ConstantExpr::getIntToPtr(symbol_addr_int, symbol_type);
+ 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());
+ if (log)
+ log->Printf("Replacing %s with %s", PrintValue(symbol).c_str(),
+ PrintValue(symbol_addr_ptr).c_str());
- symbol->replaceAllUsesWith(symbol_addr_ptr);
+ symbol->replaceAllUsesWith(symbol_addr_ptr);
- return true;
+ return true;
}
-bool
-IRForTarget::MaybeHandleCallArguments (CallInst *Old)
-{
- lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+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());
+ 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)
- if (!MaybeHandleVariable(Old->getArgOperand(op_index))) // conservatively believe that this is a store
- {
- m_error_stream.Printf("Internal error [IRForTarget]: Couldn't rewrite one of the arguments of a function call.\n");
+ for (unsigned op_index = 0, num_ops = Old->getNumArgOperands();
+ op_index < num_ops; ++op_index)
+ if (!MaybeHandleVariable(Old->getArgOperand(
+ op_index))) // conservatively believe that this is a store
+ {
+ m_error_stream.Printf("Internal error [IRForTarget]: Couldn't rewrite "
+ "one of the arguments of a function call.\n");
- return false;
- }
+ return false;
+ }
- return true;
+ return true;
}
-bool
-IRForTarget::HandleObjCClass(Value *classlist_reference)
-{
- lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+bool IRForTarget::HandleObjCClass(Value *classlist_reference) {
+ lldb_private::Log *log(
+ lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- GlobalVariable *global_variable = dyn_cast<GlobalVariable>(classlist_reference);
+ GlobalVariable *global_variable =
+ dyn_cast<GlobalVariable>(classlist_reference);
- if (!global_variable)
- return false;
+ if (!global_variable)
+ return false;
- Constant *initializer = global_variable->getInitializer();
+ Constant *initializer = global_variable->getInitializer();
- if (!initializer)
- return false;
+ if (!initializer)
+ return false;
- if (!initializer->hasName())
- 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);
+ 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 (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 (class_ptr == LLDB_INVALID_ADDRESS)
+ return false;
- if (global_variable->use_empty())
- return false;
+ if (global_variable->use_empty())
+ return false;
- SmallVector<LoadInst *, 2> load_instructions;
+ SmallVector<LoadInst *, 2> load_instructions;
- for (llvm::User *u : global_variable->users())
- {
- if (LoadInst *load_instruction = dyn_cast<LoadInst>(u))
- load_instructions.push_back(load_instruction);
- }
+ for (llvm::User *u : global_variable->users()) {
+ if (LoadInst *load_instruction = dyn_cast<LoadInst>(u))
+ load_instructions.push_back(load_instruction);
+ }
- if (load_instructions.empty())
- return false;
+ if (load_instructions.empty())
+ return false;
- Constant *class_addr = ConstantInt::get(m_intptr_ty, (uint64_t)class_ptr);
+ 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());
+ for (LoadInst *load_instruction : load_instructions) {
+ Constant *class_bitcast =
+ ConstantExpr::getIntToPtr(class_addr, load_instruction->getType());
- load_instruction->replaceAllUsesWith(class_bitcast);
+ load_instruction->replaceAllUsesWith(class_bitcast);
- load_instruction->eraseFromParent();
- }
+ load_instruction->eraseFromParent();
+ }
- return true;
+ return true;
}
-bool
-IRForTarget::RemoveCXAAtExit (BasicBlock &basic_block)
-{
- BasicBlock::iterator ii;
+bool IRForTarget::RemoveCXAAtExit(BasicBlock &basic_block) {
+ BasicBlock::iterator ii;
- std::vector<CallInst *> calls_to_remove;
+ std::vector<CallInst *> calls_to_remove;
- for (ii = basic_block.begin();
- ii != basic_block.end();
- ++ii)
- {
- Instruction &inst = *ii;
+ for (ii = basic_block.begin(); ii != basic_block.end(); ++ii) {
+ Instruction &inst = *ii;
- CallInst *call = dyn_cast<CallInst>(&inst);
+ CallInst *call = dyn_cast<CallInst>(&inst);
- // MaybeHandleCallArguments handles error reporting; we are silent here
- if (!call)
- continue;
+ // MaybeHandleCallArguments handles error reporting; we are silent here
+ if (!call)
+ continue;
- bool remove = false;
+ bool remove = false;
- llvm::Function *func = call->getCalledFunction();
+ llvm::Function *func = call->getCalledFunction();
- if (func && func->getName() == "__cxa_atexit")
- remove = true;
+ if (func && func->getName() == "__cxa_atexit")
+ remove = true;
- llvm::Value *val = call->getCalledValue();
+ llvm::Value *val = call->getCalledValue();
- if (val && val->getName() == "__cxa_atexit")
- remove = true;
+ if (val && val->getName() == "__cxa_atexit")
+ remove = true;
- if (remove)
- calls_to_remove.push_back(call);
- }
+ 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();
- }
+ for (std::vector<CallInst *>::iterator ci = calls_to_remove.begin(),
+ ce = calls_to_remove.end();
+ ci != ce; ++ci) {
+ (*ci)->eraseFromParent();
+ }
- return true;
+ return true;
}
-bool
-IRForTarget::ResolveCalls(BasicBlock &basic_block)
-{
- /////////////////////////////////////////////////////////////////////////
- // Prepare the current basic block for execution in the remote process
- //
+bool IRForTarget::ResolveCalls(BasicBlock &basic_block) {
+ /////////////////////////////////////////////////////////////////////////
+ // Prepare the current basic block for execution in the remote process
+ //
- BasicBlock::iterator ii;
+ BasicBlock::iterator ii;
- for (ii = basic_block.begin();
- ii != basic_block.end();
- ++ii)
- {
- Instruction &inst = *ii;
+ for (ii = basic_block.begin(); ii != basic_block.end(); ++ii) {
+ Instruction &inst = *ii;
- CallInst *call = dyn_cast<CallInst>(&inst);
+ CallInst *call = dyn_cast<CallInst>(&inst);
- // MaybeHandleCallArguments handles error reporting; we are silent here
- if (call && !MaybeHandleCallArguments(call))
- return false;
- }
+ // MaybeHandleCallArguments handles error reporting; we are silent here
+ if (call && !MaybeHandleCallArguments(call))
+ return false;
+ }
- return true;
+ return true;
}
-bool
-IRForTarget::ResolveExternals (Function &llvm_function)
-{
- lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+bool IRForTarget::ResolveExternals(Function &llvm_function) {
+ lldb_private::Log *log(
+ lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- for (GlobalVariable &global_var : m_module->globals())
- {
- std::string global_name = global_var.getName().str();
+ for (GlobalVariable &global_var : m_module->globals()) {
+ std::string global_name = global_var.getName().str();
- if (log)
- log->Printf("Examining %s, DeclForGlobalValue returns %p",
- global_name.c_str(),
- static_cast<void*>(DeclForGlobal(&global_var)));
+ if (log)
+ log->Printf("Examining %s, DeclForGlobalValue returns %p",
+ global_name.c_str(),
+ static_cast<void *>(DeclForGlobal(&global_var)));
- if (global_name.find("OBJC_IVAR") == 0)
- {
- if (!HandleSymbol(&global_var))
- {
- m_error_stream.Printf("Error [IRForTarget]: Couldn't find Objective-C indirect ivar symbol %s\n", global_name.c_str());
+ if (global_name.find("OBJC_IVAR") == 0) {
+ if (!HandleSymbol(&global_var)) {
+ 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_var))
- {
- 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_REFERENCES_$") !=
+ global_name.npos) {
+ if (!HandleObjCClass(&global_var)) {
+ 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_var))
- {
- 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_var)) {
+ 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_var))
- {
- if (!MaybeHandleVariable (&global_var))
- {
- m_error_stream.Printf("Internal error [IRForTarget]: Couldn't rewrite external variable %s\n", global_name.c_str());
+ return false;
+ }
+ } else if (DeclForGlobal(&global_var)) {
+ if (!MaybeHandleVariable(&global_var)) {
+ m_error_stream.Printf("Internal error [IRForTarget]: Couldn't rewrite "
+ "external variable %s\n",
+ global_name.c_str());
- return false;
- }
- }
+ return false;
+ }
}
+ }
- return true;
+ return true;
}
-static bool isGuardVariableRef(Value *V)
-{
- Constant *Old = NULL;
+static bool isGuardVariableRef(Value *V) {
+ Constant *Old = NULL;
- if (!(Old = dyn_cast<Constant>(V)))
- return false;
+ if (!(Old = dyn_cast<Constant>(V)))
+ return false;
- ConstantExpr *CE = NULL;
+ ConstantExpr *CE = NULL;
- if ((CE = dyn_cast<ConstantExpr>(V)))
- {
- if (CE->getOpcode() != Instruction::BitCast)
- return false;
+ if ((CE = dyn_cast<ConstantExpr>(V))) {
+ if (CE->getOpcode() != Instruction::BitCast)
+ return false;
- Old = CE->getOperand(0);
- }
+ Old = CE->getOperand(0);
+ }
- GlobalVariable *GV = dyn_cast<GlobalVariable>(Old);
+ GlobalVariable *GV = dyn_cast<GlobalVariable>(Old);
- if (!GV || !GV->hasName() ||
- (!GV->getName().startswith("_ZGV") && // Itanium ABI guard variable
- !GV->getName().endswith("@4IA"))) // Microsoft ABI guard variable
- {
- return false;
- }
+ if (!GV || !GV->hasName() ||
+ (!GV->getName().startswith("_ZGV") && // Itanium ABI guard variable
+ !GV->getName().endswith("@4IA"))) // Microsoft ABI guard variable
+ {
+ return false;
+ }
- return true;
+ return true;
}
-void
-IRForTarget::TurnGuardLoadIntoZero(llvm::Instruction* guard_load)
-{
- Constant *zero(Constant::getNullValue(guard_load->getType()));
- guard_load->replaceAllUsesWith(zero);
- guard_load->eraseFromParent();
+void IRForTarget::TurnGuardLoadIntoZero(llvm::Instruction *guard_load) {
+ Constant *zero(Constant::getNullValue(guard_load->getType()));
+ guard_load->replaceAllUsesWith(zero);
+ guard_load->eraseFromParent();
}
-static void ExciseGuardStore(Instruction* guard_store)
-{
- guard_store->eraseFromParent();
+static void ExciseGuardStore(Instruction *guard_store) {
+ guard_store->eraseFromParent();
}
-bool
-IRForTarget::RemoveGuards(BasicBlock &basic_block)
-{
- ///////////////////////////////////////////////////////
- // Eliminate any reference to guard variables found.
- //
+bool IRForTarget::RemoveGuards(BasicBlock &basic_block) {
+ ///////////////////////////////////////////////////////
+ // Eliminate any reference to guard variables found.
+ //
- BasicBlock::iterator ii;
+ BasicBlock::iterator ii;
- typedef SmallVector <Instruction*, 2> InstrList;
- typedef InstrList::iterator InstrIterator;
+ typedef SmallVector<Instruction *, 2> InstrList;
+ typedef InstrList::iterator InstrIterator;
- InstrList guard_loads;
- InstrList guard_stores;
+ InstrList guard_loads;
+ InstrList guard_stores;
- for (ii = basic_block.begin();
- ii != basic_block.end();
- ++ii)
- {
- Instruction &inst = *ii;
+ 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 (LoadInst *load = dyn_cast<LoadInst>(&inst))
+ if (isGuardVariableRef(load->getPointerOperand()))
+ guard_loads.push_back(&inst);
- if (StoreInst *store = dyn_cast<StoreInst>(&inst))
- if (isGuardVariableRef(store->getPointerOperand()))
- guard_stores.push_back(&inst);
- }
+ if (StoreInst *store = dyn_cast<StoreInst>(&inst))
+ if (isGuardVariableRef(store->getPointerOperand()))
+ guard_stores.push_back(&inst);
+ }
- InstrIterator iter;
+ InstrIterator iter;
- for (iter = guard_loads.begin();
- iter != guard_loads.end();
- ++iter)
- TurnGuardLoadIntoZero(*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);
+ for (iter = guard_stores.begin(); iter != guard_stores.end(); ++iter)
+ ExciseGuardStore(*iter);
- return true;
+ return true;
}
// This function does not report errors; its callers are responsible.
-bool
-IRForTarget::UnfoldConstant(Constant *old_constant,
- llvm::Function *llvm_function,
- FunctionValueCache &value_maker,
- FunctionValueCache &entry_instruction_finder,
- lldb_private::Stream &error_stream)
-{
- 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 (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())
- {
- default:
- error_stream.Printf("error [IRForTarget internal]: 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, llvm_function, bit_cast_maker, entry_instruction_finder, error_stream))
- return false;
- }
- break;
- case Instruction::GetElementPtr:
- {
- // 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(nullptr, ptr, indices, "", llvm::cast<Instruction>(entry_instruction_finder.GetValue(function)));
- });
-
- if (!UnfoldConstant(constant_expr, llvm_function, get_element_pointer_maker, entry_instruction_finder, error_stream))
- return false;
- }
- break;
+bool IRForTarget::UnfoldConstant(Constant *old_constant,
+ llvm::Function *llvm_function,
+ FunctionValueCache &value_maker,
+ FunctionValueCache &entry_instruction_finder,
+ lldb_private::Stream &error_stream) {
+ 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 (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()) {
+ default:
+ error_stream.Printf("error [IRForTarget internal]: 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, llvm_function, bit_cast_maker,
+ entry_instruction_finder, error_stream))
+ return false;
+ } break;
+ case Instruction::GetElementPtr: {
+ // 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);
}
- }
- else
- {
- error_stream.Printf("error [IRForTarget internal]: Unhandled constant type: \"%s\"", PrintValue(constant).c_str());
- return false;
- }
+
+ ArrayRef<Value *> indices(index_vector);
+
+ return GetElementPtrInst::Create(
+ nullptr, ptr, indices, "",
+ llvm::cast<Instruction>(
+ entry_instruction_finder.GetValue(function)));
+ });
+
+ if (!UnfoldConstant(constant_expr, llvm_function,
+ get_element_pointer_maker,
+ entry_instruction_finder, error_stream))
+ return false;
+ } break;
}
- else
- {
- if (Instruction *inst = llvm::dyn_cast<Instruction>(user))
- {
- if (llvm_function && inst->getParent()->getParent() != llvm_function)
- {
- error_stream.PutCString("error: Capturing non-local variables in expressions is unsupported.\n");
- return false;
- }
- inst->replaceUsesOfWith(old_constant, value_maker.GetValue(inst->getParent()->getParent()));
- }
- else
- {
- error_stream.Printf("error [IRForTarget internal]: Unhandled non-constant type: \"%s\"", PrintValue(user).c_str());
- return false;
- }
+ } else {
+ error_stream.Printf(
+ "error [IRForTarget internal]: Unhandled constant type: \"%s\"",
+ PrintValue(constant).c_str());
+ return false;
+ }
+ } else {
+ if (Instruction *inst = llvm::dyn_cast<Instruction>(user)) {
+ if (llvm_function && inst->getParent()->getParent() != llvm_function) {
+ error_stream.PutCString("error: Capturing non-local variables in "
+ "expressions is unsupported.\n");
+ return false;
}
+ inst->replaceUsesOfWith(
+ old_constant, value_maker.GetValue(inst->getParent()->getParent()));
+ } else {
+ error_stream.Printf(
+ "error [IRForTarget internal]: Unhandled non-constant type: \"%s\"",
+ PrintValue(user).c_str());
+ return false;
+ }
}
+ }
- if (!isa<GlobalValue>(old_constant))
- {
- old_constant->destroyConstant();
- }
+ if (!isa<GlobalValue>(old_constant)) {
+ old_constant->destroyConstant();
+ }
- return true;
+ return true;
}
-bool
-IRForTarget::ReplaceVariables (Function &llvm_function)
-{
- if (!m_resolve_vars)
- return true;
-
- lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+bool IRForTarget::ReplaceVariables(Function &llvm_function) {
+ if (!m_resolve_vars)
+ return true;
- m_decl_map->DoStructLayout();
+ lldb_private::Log *log(
+ lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- if (log)
- log->Printf("Element arrangement:");
+ m_decl_map->DoStructLayout();
- uint32_t num_elements;
- uint32_t element_index;
+ if (log)
+ log->Printf("Element arrangement:");
- size_t size;
- lldb::offset_t alignment;
+ uint32_t num_elements;
+ uint32_t element_index;
- if (!m_decl_map->GetStructInfo (num_elements, size, alignment))
- return false;
+ size_t size;
+ lldb::offset_t alignment;
- Function::arg_iterator iter(llvm_function.getArgumentList().begin());
+ if (!m_decl_map->GetStructInfo(num_elements, size, alignment))
+ return false;
- if (iter == llvm_function.getArgumentList().end())
- {
- m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes no arguments (should take at least a struct pointer)");
+ Function::arg_iterator iter(llvm_function.getArgumentList().begin());
- return false;
- }
+ if (iter == llvm_function.getArgumentList().end()) {
+ m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes no "
+ "arguments (should take at least a struct pointer)");
- Argument *argument = &*iter;
+ return false;
+ }
- if (argument->getName().equals("this"))
- {
- ++iter;
+ Argument *argument = &*iter;
- if (iter == llvm_function.getArgumentList().end())
- {
- m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes only 'this' argument (should take a struct pointer too)");
+ if (argument->getName().equals("this")) {
+ ++iter;
- return false;
- }
+ if (iter == llvm_function.getArgumentList().end()) {
+ m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes only "
+ "'this' argument (should take a struct pointer "
+ "too)");
- argument = &*iter;
+ return false;
}
- else if (argument->getName().equals("self"))
- {
- ++iter;
- if (iter == llvm_function.getArgumentList().end())
- {
- m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes only 'self' argument (should take '_cmd' and a struct pointer too)");
+ argument = &*iter;
+ } else if (argument->getName().equals("self")) {
+ ++iter;
- return false;
- }
+ if (iter == llvm_function.getArgumentList().end()) {
+ m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes only "
+ "'self' argument (should take '_cmd' and a struct "
+ "pointer too)");
- if (!iter->getName().equals("_cmd"))
- {
- m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes '%s' after 'self' argument (should take '_cmd')", iter->getName().str().c_str());
+ return false;
+ }
- return false;
- }
+ if (!iter->getName().equals("_cmd")) {
+ m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes '%s' "
+ "after 'self' argument (should take '_cmd')",
+ iter->getName().str().c_str());
- ++iter;
+ return false;
+ }
- if (iter == llvm_function.getArgumentList().end())
- {
- m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes only 'self' and '_cmd' arguments (should take a struct pointer too)");
+ ++iter;
- return false;
- }
+ if (iter == llvm_function.getArgumentList().end()) {
+ m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes only "
+ "'self' and '_cmd' arguments (should take a struct "
+ "pointer too)");
- argument = &*iter;
+ return false;
}
- if (!argument->getName().equals("$__lldb_arg"))
- {
- 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;
- }
+ argument = &*iter;
+ }
- if (log)
- log->Printf("Arg: \"%s\"", PrintValue(argument).c_str());
+ if (!argument->getName().equals("$__lldb_arg")) {
+ m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes an "
+ "argument named '%s' instead of the struct pointer",
+ argument->getName().str().c_str());
- BasicBlock &entry_block(llvm_function.getEntryBlock());
- Instruction *FirstEntryInstruction(entry_block.getFirstNonPHIOrDbg());
+ return false;
+ }
- if (!FirstEntryInstruction)
- {
- m_error_stream.Printf("Internal error [IRForTarget]: Couldn't find the first instruction in the wrapper for use in rewriting");
+ if (log)
+ log->Printf("Arg: \"%s\"", PrintValue(argument).c_str());
- return false;
- }
+ BasicBlock &entry_block(llvm_function.getEntryBlock());
+ Instruction *FirstEntryInstruction(entry_block.getFirstNonPHIOrDbg());
- LLVMContext &context(m_module->getContext());
- IntegerType *offset_type(Type::getInt32Ty(context));
+ if (!FirstEntryInstruction) {
+ m_error_stream.Printf("Internal error [IRForTarget]: Couldn't find the "
+ "first instruction in the wrapper for use in "
+ "rewriting");
- if (!offset_type)
- {
- m_error_stream.Printf("Internal error [IRForTarget]: Couldn't produce an offset type");
+ return false;
+ }
- return false;
- }
+ LLVMContext &context(m_module->getContext());
+ IntegerType *offset_type(Type::getInt32Ty(context));
- for (element_index = 0; element_index < num_elements; ++element_index)
- {
- const clang::NamedDecl *decl = NULL;
- Value *value = NULL;
- lldb::offset_t offset;
- lldb_private::ConstString name;
+ if (!offset_type) {
+ m_error_stream.Printf(
+ "Internal error [IRForTarget]: Couldn't produce an offset type");
- if (!m_decl_map->GetStructElement (decl, value, offset, name, element_index))
- {
- m_error_stream.Printf("Internal error [IRForTarget]: Structure information is incomplete");
+ return false;
+ }
- return false;
- }
+ for (element_index = 0; element_index < num_elements; ++element_index) {
+ const clang::NamedDecl *decl = NULL;
+ Value *value = NULL;
+ lldb::offset_t offset;
+ lldb_private::ConstString name;
- if (log)
- 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(nullptr,
- argument,
- offset_int,
- "",
- entry_instruction);
-
- if (name == m_result_name && !m_result_is_pointer)
- {
- BitCastInst *bit_cast = new BitCastInst(get_element_ptr,
- 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);
+ if (!m_decl_map->GetStructElement(decl, value, offset, name,
+ element_index)) {
+ m_error_stream.Printf(
+ "Internal error [IRForTarget]: Structure information is incomplete");
- return bit_cast;
- }
- });
+ return false;
+ }
- if (Constant *constant = dyn_cast<Constant>(value))
- {
- if (!UnfoldConstant(constant, &llvm_function, body_result_maker, m_entry_instruction_finder, m_error_stream))
- {
- return false;
- }
- }
- else if (Instruction *instruction = dyn_cast<Instruction>(value))
- {
- if (instruction->getParent()->getParent() != &llvm_function)
- {
- m_error_stream.PutCString("error: Capturing non-local variables in expressions is unsupported.\n");
- return false;
- }
- value->replaceAllUsesWith(body_result_maker.GetValue(instruction->getParent()->getParent()));
- }
- else
- {
- if (log)
- log->Printf("Unhandled non-constant type: \"%s\"", PrintValue(value).c_str());
- return false;
+ if (log)
+ 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(
+ nullptr, argument, offset_int, "", entry_instruction);
+
+ if (name == m_result_name && !m_result_is_pointer) {
+ BitCastInst *bit_cast = new BitCastInst(
+ get_element_ptr, 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 (GlobalVariable *var = dyn_cast<GlobalVariable>(value))
- var->eraseFromParent();
+ if (Constant *constant = dyn_cast<Constant>(value)) {
+ if (!UnfoldConstant(constant, &llvm_function, body_result_maker,
+ m_entry_instruction_finder, m_error_stream)) {
+ return false;
}
+ } else if (Instruction *instruction = dyn_cast<Instruction>(value)) {
+ if (instruction->getParent()->getParent() != &llvm_function) {
+ m_error_stream.PutCString("error: Capturing non-local variables in "
+ "expressions is unsupported.\n");
+ return false;
+ }
+ value->replaceAllUsesWith(
+ body_result_maker.GetValue(instruction->getParent()->getParent()));
+ } else {
+ if (log)
+ 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 %" PRIu64 "]", (int64_t)alignment, (uint64_t)size);
+ if (log)
+ log->Printf("Total structure [align %" PRId64 ", size %" PRIu64 "]",
+ (int64_t)alignment, (uint64_t)size);
- return true;
+ return true;
}
-llvm::Constant *
-IRForTarget::BuildRelocation(llvm::Type *type, uint64_t offset)
-{
- llvm::Constant *offset_int = ConstantInt::get(m_intptr_ty, offset);
+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];
+ llvm::Constant *offset_array[1];
- offset_array[0] = offset_int;
+ offset_array[0] = offset_int;
- llvm::ArrayRef<llvm::Constant *> offsets(offset_array, 1);
- llvm::Type *char_type = llvm::Type::getInt8Ty(m_module->getContext());
- llvm::Type *char_pointer_type = char_type->getPointerTo();
+ llvm::ArrayRef<llvm::Constant *> offsets(offset_array, 1);
+ llvm::Type *char_type = llvm::Type::getInt8Ty(m_module->getContext());
+ llvm::Type *char_pointer_type = char_type->getPointerTo();
- llvm::Constant *reloc_placeholder_bitcast = ConstantExpr::getBitCast(m_reloc_placeholder, char_pointer_type);
- llvm::Constant *reloc_getelementptr = ConstantExpr::getGetElementPtr(char_type, reloc_placeholder_bitcast, offsets);
- llvm::Constant *reloc_bitcast = ConstantExpr::getBitCast(reloc_getelementptr, type);
+ llvm::Constant *reloc_placeholder_bitcast =
+ ConstantExpr::getBitCast(m_reloc_placeholder, char_pointer_type);
+ llvm::Constant *reloc_getelementptr = ConstantExpr::getGetElementPtr(
+ char_type, reloc_placeholder_bitcast, offsets);
+ llvm::Constant *reloc_bitcast =
+ ConstantExpr::getBitCast(reloc_getelementptr, type);
- return reloc_bitcast;
+ return reloc_bitcast;
}
-bool
-IRForTarget::runOnModule (Module &llvm_module)
-{
- lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+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());
+ 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);
+ if (log) {
+ std::string s;
+ raw_string_ostream oss(s);
- m_module->print(oss, NULL);
+ m_module->print(oss, NULL);
- oss.flush();
+ oss.flush();
- log->Printf("Module as passed in to IRForTarget: \n\"%s\"", s.c_str());
- }
+ log->Printf("Module as passed in to IRForTarget: \n\"%s\"", s.c_str());
+ }
- Function *const main_function = m_func_name.IsEmpty() ? nullptr : m_module->getFunction(m_func_name.GetStringRef());
+ Function *const main_function =
+ m_func_name.IsEmpty() ? nullptr
+ : m_module->getFunction(m_func_name.GetStringRef());
- if (!m_func_name.IsEmpty() && !main_function)
- {
- if (log)
- log->Printf("Couldn't find \"%s()\" in the module", m_func_name.AsCString());
+ if (!m_func_name.IsEmpty() && !main_function) {
+ if (log)
+ log->Printf("Couldn't find \"%s()\" in the module",
+ m_func_name.AsCString());
- m_error_stream.Printf("Internal error [IRForTarget]: Couldn't find wrapper '%s' in the module",
- m_func_name.AsCString());
+ m_error_stream.Printf("Internal error [IRForTarget]: Couldn't find wrapper "
+ "'%s' in the module",
+ m_func_name.AsCString());
- return false;
- }
+ return false;
+ }
- if (main_function)
- {
- if (!FixFunctionLinkage(*main_function))
- {
- if (log)
- log->Printf("Couldn't fix the linkage for the function");
+ if (main_function) {
+ if (!FixFunctionLinkage(*main_function)) {
+ if (log)
+ log->Printf("Couldn't fix the linkage for the function");
- return false;
- }
+ return false;
}
+ }
- llvm::Type *int8_ty = Type::getInt8Ty(m_module->getContext());
+ llvm::Type *int8_ty = Type::getInt8Ty(m_module->getContext());
- m_reloc_placeholder = new llvm::GlobalVariable((*m_module),
- int8_ty,
- false /* IsConstant */,
- GlobalVariable::InternalLinkage,
- Constant::getNullValue(int8_ty),
- "reloc_placeholder",
- NULL /* InsertBefore */,
- GlobalVariable::NotThreadLocal /* ThreadLocal */,
- 0 /* AddressSpace */);
+ m_reloc_placeholder = new llvm::GlobalVariable(
+ (*m_module), int8_ty, false /* IsConstant */,
+ GlobalVariable::InternalLinkage, Constant::getNullValue(int8_ty),
+ "reloc_placeholder", NULL /* InsertBefore */,
+ GlobalVariable::NotThreadLocal /* ThreadLocal */, 0 /* AddressSpace */);
- ////////////////////////////////////////////////////////////
- // Replace $__lldb_expr_result with a persistent variable
- //
+ ////////////////////////////////////////////////////////////
+ // Replace $__lldb_expr_result with a persistent variable
+ //
- if (main_function)
- {
- if (!CreateResultVariable(*main_function))
- {
- if (log)
- log->Printf("CreateResultVariable() failed");
+ if (main_function) {
+ if (!CreateResultVariable(*main_function)) {
+ if (log)
+ log->Printf("CreateResultVariable() failed");
- // CreateResultVariable() reports its own errors, so we don't do so here
+ // CreateResultVariable() reports its own errors, so we don't do so here
- return false;
- }
+ return false;
}
+ }
- if (log && log->GetVerbose())
- {
- std::string s;
- raw_string_ostream oss(s);
+ if (log && log->GetVerbose()) {
+ std::string s;
+ raw_string_ostream oss(s);
- m_module->print(oss, NULL);
+ m_module->print(oss, NULL);
- oss.flush();
+ oss.flush();
- log->Printf("Module after creating the result variable: \n\"%s\"", s.c_str());
- }
+ 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;
+ for (Module::iterator fi = m_module->begin(), fe = m_module->end(); fi != fe;
+ ++fi) {
+ llvm::Function *function = &*fi;
- if (function->begin() == function->end())
- continue;
+ if (function->begin() == function->end())
+ continue;
- Function::iterator bbi;
+ Function::iterator bbi;
- for (bbi = function->begin();
- bbi != function->end();
- ++bbi)
- {
- if (!RemoveGuards(*bbi))
- {
- if (log)
- log->Printf("RemoveGuards() failed");
+ for (bbi = function->begin(); bbi != function->end(); ++bbi) {
+ if (!RemoveGuards(*bbi)) {
+ if (log)
+ log->Printf("RemoveGuards() failed");
- // RemoveGuards() reports its own errors, so we don't do so here
+ // RemoveGuards() reports its own errors, so we don't do so here
- return false;
- }
+ return false;
+ }
- if (!RewritePersistentAllocs(*bbi))
- {
- if (log)
- log->Printf("RewritePersistentAllocs() failed");
+ if (!RewritePersistentAllocs(*bbi)) {
+ if (log)
+ log->Printf("RewritePersistentAllocs() failed");
- // RewritePersistentAllocs() reports its own errors, so we don't do so here
+ // RewritePersistentAllocs() reports its own errors, so we don't do so
+ // here
- return false;
- }
+ return false;
+ }
- if (!RemoveCXAAtExit(*bbi))
- {
- if (log)
- log->Printf("RemoveCXAAtExit() failed");
+ if (!RemoveCXAAtExit(*bbi)) {
+ if (log)
+ log->Printf("RemoveCXAAtExit() failed");
- // RemoveCXAAtExit() reports its own errors, so we don't do so here
+ // RemoveCXAAtExit() reports its own errors, so we don't do so here
- return false;
- }
- }
+ return false;
+ }
}
+ }
- ///////////////////////////////////////////////////////////////////////////////
- // Fix all Objective-C constant strings to use NSStringWithCString:encoding:
- //
+ ///////////////////////////////////////////////////////////////////////////////
+ // Fix all Objective-C constant strings to use NSStringWithCString:encoding:
+ //
- if (!RewriteObjCConstStrings())
- {
- if (log)
- log->Printf("RewriteObjCConstStrings() failed");
+ if (!RewriteObjCConstStrings()) {
+ if (log)
+ log->Printf("RewriteObjCConstStrings() failed");
- // RewriteObjCConstStrings() reports its own errors, so we don't do so here
+ // RewriteObjCConstStrings() reports its own errors, so we don't do so here
- return false;
- }
+ return false;
+ }
- for (Module::iterator fi = m_module->begin(), fe = m_module->end();
- fi != fe;
- ++fi)
- {
- llvm::Function *function = &*fi;
+ for (Module::iterator fi = m_module->begin(), fe = m_module->end(); fi != fe;
+ ++fi) {
+ llvm::Function *function = &*fi;
- for (llvm::Function::iterator bbi = function->begin(), bbe = function->end();
- bbi != bbe;
- ++bbi)
- {
- if (!RewriteObjCSelectors(*bbi))
- {
- if (log)
- log->Printf("RewriteObjCSelectors() failed");
+ for (llvm::Function::iterator bbi = function->begin(),
+ bbe = function->end();
+ bbi != bbe; ++bbi) {
+ if (!RewriteObjCSelectors(*bbi)) {
+ if (log)
+ log->Printf("RewriteObjCSelectors() failed");
- // RewriteObjCSelectors() reports its own errors, so we don't do so here
+ // RewriteObjCSelectors() reports its own errors, so we don't do so here
- return false;
- }
- }
+ return false;
+ }
}
+ }
- for (Module::iterator fi = m_module->begin(), fe = m_module->end();
- fi != fe;
- ++fi)
- {
- llvm::Function *function = &*fi;
+ for (Module::iterator fi = m_module->begin(), fe = m_module->end(); fi != fe;
+ ++fi) {
+ llvm::Function *function = &*fi;
- for (llvm::Function::iterator bbi = function->begin(), bbe = function->end();
- bbi != bbe;
- ++bbi)
- {
- if (!ResolveCalls(*bbi))
- {
- if (log)
- log->Printf("ResolveCalls() failed");
+ for (llvm::Function::iterator bbi = function->begin(),
+ bbe = function->end();
+ bbi != bbe; ++bbi) {
+ if (!ResolveCalls(*bbi)) {
+ if (log)
+ log->Printf("ResolveCalls() failed");
- // ResolveCalls() reports its own errors, so we don't do so here
+ // ResolveCalls() reports its own errors, so we don't do so here
- return false;
- }
- }
+ return false;
+ }
}
+ }
- ////////////////////////////////////////////////////////////////////////
- // Run function-level passes that only make sense on the main function
- //
+ ////////////////////////////////////////////////////////////////////////
+ // Run function-level passes that only make sense on the main function
+ //
- if (main_function)
- {
- if (!ResolveExternals(*main_function))
- {
- if (log)
- log->Printf("ResolveExternals() failed");
+ if (main_function) {
+ if (!ResolveExternals(*main_function)) {
+ if (log)
+ log->Printf("ResolveExternals() failed");
- // ResolveExternals() reports its own errors, so we don't do so here
+ // ResolveExternals() reports its own errors, so we don't do so here
- return false;
- }
+ return false;
+ }
- if (!ReplaceVariables(*main_function))
- {
- if (log)
- log->Printf("ReplaceVariables() failed");
+ if (!ReplaceVariables(*main_function)) {
+ if (log)
+ log->Printf("ReplaceVariables() failed");
- // ReplaceVariables() reports its own errors, so we don't do so here
+ // ReplaceVariables() reports its own errors, so we don't do so here
- return false;
- }
+ return false;
}
+ }
- if (log && log->GetVerbose())
- {
- std::string s;
- raw_string_ostream oss(s);
+ if (log && log->GetVerbose()) {
+ std::string s;
+ raw_string_ostream oss(s);
- m_module->print(oss, NULL);
+ m_module->print(oss, NULL);
- oss.flush();
+ oss.flush();
- log->Printf("Module after preparing for execution: \n\"%s\"", s.c_str());
- }
+ log->Printf("Module after preparing for execution: \n\"%s\"", s.c_str());
+ }
- return true;
+ return true;
}
-void
-IRForTarget::assignPassManager (PMStack &pass_mgr_stack, PassManagerType pass_mgr_type)
-{
-}
+void IRForTarget::assignPassManager(PMStack &pass_mgr_stack,
+ PassManagerType pass_mgr_type) {}
-PassManagerType
-IRForTarget::getPotentialPassManagerType() const
-{
- return PMT_ModulePassManager;
+PassManagerType IRForTarget::getPotentialPassManagerType() const {
+ return PMT_ModulePassManager;
}
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.h b/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.h
index 39d5159acf9..fecb32f685c 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.h
+++ b/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.h
@@ -1,4 +1,5 @@
-//===-- IRForTarget.h ---------------------------------------------*- C++ -*-===//
+//===-- IRForTarget.h ---------------------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -10,38 +11,38 @@
#ifndef liblldb_IRForTarget_h_
#define liblldb_IRForTarget_h_
-#include "lldb/lldb-public.h"
#include "lldb/Core/ConstString.h"
#include "lldb/Core/Error.h"
#include "lldb/Core/Stream.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Symbol/TaggedASTType.h"
+#include "lldb/lldb-public.h"
#include "llvm/Pass.h"
-#include <map>
#include <functional>
+#include <map>
namespace llvm {
- class BasicBlock;
- class CallInst;
- class Constant;
- class ConstantInt;
- class Function;
- class GlobalValue;
- class GlobalVariable;
- class Instruction;
- class IntegerType;
- class Module;
- class StoreInst;
- class DataLayout;
- class Type;
- class Value;
+class BasicBlock;
+class CallInst;
+class Constant;
+class ConstantInt;
+class Function;
+class GlobalValue;
+class GlobalVariable;
+class Instruction;
+class IntegerType;
+class Module;
+class StoreInst;
+class DataLayout;
+class Type;
+class Value;
}
namespace lldb_private {
- class ClangExpressionDeclMap;
- class IRExecutionUnit;
- class IRMemoryMap;
+class ClangExpressionDeclMap;
+class IRExecutionUnit;
+class IRMemoryMap;
}
//----------------------------------------------------------------------
@@ -58,596 +59,578 @@ namespace lldb_private {
/// transformations are discussed in more detail next to their relevant
/// functions.
//----------------------------------------------------------------------
-class IRForTarget : public llvm::ModulePass
-{
+class IRForTarget : public llvm::ModulePass {
public:
- enum class LookupResult {
- Success,
- Fail,
- Ignore
- };
-
- //------------------------------------------------------------------
- /// Constructor
- ///
- /// @param[in] decl_map
- /// The list of externally-referenced variables for the expression,
- /// for use in looking up globals and allocating the argument
- /// struct. See the documentation for ClangExpressionDeclMap.
- ///
- /// @param[in] resolve_vars
- /// True if the external variable references (including persistent
- /// variables) should be resolved. If not, only external functions
- /// are resolved.
- ///
- /// @param[in] execution_policy
- /// Determines whether an IR interpreter can be used to statically
- /// evaluate the expression.
- ///
- /// @param[in] const_result
- /// This variable is populated with the statically-computed result
- /// of the function, if it has no side-effects and the result can
- /// be computed statically.
- ///
- /// @param[in] execution_unit
- /// The holder for raw data associated with the expression.
- ///
- /// @param[in] error_stream
- /// If non-NULL, a stream on which errors can be printed.
- ///
- /// @param[in] func_name
- /// The name of the function to prepare for execution in the target.
- //------------------------------------------------------------------
- IRForTarget(lldb_private::ClangExpressionDeclMap *decl_map,
- bool resolve_vars,
- lldb_private::IRExecutionUnit &execution_unit,
- lldb_private::Stream &error_stream,
- const char* func_name = "$__lldb_expr");
-
- //------------------------------------------------------------------
- /// Destructor
- //------------------------------------------------------------------
- ~IRForTarget() override;
-
- //------------------------------------------------------------------
- /// Run this IR transformer on a single module
- ///
- /// Implementation of the llvm::ModulePass::runOnModule() function.
- ///
- /// @param[in] llvm_module
- /// The module to run on. This module is searched for the function
- /// $__lldb_expr, and that function is passed to the passes one by
- /// one.
- ///
- /// @param[in] interpreter_error
- /// An error. If the expression fails to be interpreted, this error
- /// is set to a reason why.
- ///
- /// @return
- /// True on success; false otherwise
- //------------------------------------------------------------------
- bool
- runOnModule(llvm::Module &llvm_module) override;
-
- //------------------------------------------------------------------
- /// Interface stub
- ///
- /// Implementation of the llvm::ModulePass::assignPassManager()
- /// function.
- //------------------------------------------------------------------
- void
- assignPassManager(llvm::PMStack &pass_mgr_stack,
- llvm::PassManagerType pass_mgr_type = llvm::PMT_ModulePassManager) override;
-
- //------------------------------------------------------------------
- /// Returns PMT_ModulePassManager
- ///
- /// Implementation of the llvm::ModulePass::getPotentialPassManagerType()
- /// function.
- //------------------------------------------------------------------
- llvm::PassManagerType
- getPotentialPassManagerType() const override;
+ enum class LookupResult { Success, Fail, Ignore };
+
+ //------------------------------------------------------------------
+ /// Constructor
+ ///
+ /// @param[in] decl_map
+ /// The list of externally-referenced variables for the expression,
+ /// for use in looking up globals and allocating the argument
+ /// struct. See the documentation for ClangExpressionDeclMap.
+ ///
+ /// @param[in] resolve_vars
+ /// True if the external variable references (including persistent
+ /// variables) should be resolved. If not, only external functions
+ /// are resolved.
+ ///
+ /// @param[in] execution_policy
+ /// Determines whether an IR interpreter can be used to statically
+ /// evaluate the expression.
+ ///
+ /// @param[in] const_result
+ /// This variable is populated with the statically-computed result
+ /// of the function, if it has no side-effects and the result can
+ /// be computed statically.
+ ///
+ /// @param[in] execution_unit
+ /// The holder for raw data associated with the expression.
+ ///
+ /// @param[in] error_stream
+ /// If non-NULL, a stream on which errors can be printed.
+ ///
+ /// @param[in] func_name
+ /// The name of the function to prepare for execution in the target.
+ //------------------------------------------------------------------
+ IRForTarget(lldb_private::ClangExpressionDeclMap *decl_map, bool resolve_vars,
+ lldb_private::IRExecutionUnit &execution_unit,
+ lldb_private::Stream &error_stream,
+ const char *func_name = "$__lldb_expr");
+
+ //------------------------------------------------------------------
+ /// Destructor
+ //------------------------------------------------------------------
+ ~IRForTarget() override;
+
+ //------------------------------------------------------------------
+ /// Run this IR transformer on a single module
+ ///
+ /// Implementation of the llvm::ModulePass::runOnModule() function.
+ ///
+ /// @param[in] llvm_module
+ /// The module to run on. This module is searched for the function
+ /// $__lldb_expr, and that function is passed to the passes one by
+ /// one.
+ ///
+ /// @param[in] interpreter_error
+ /// An error. If the expression fails to be interpreted, this error
+ /// is set to a reason why.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool runOnModule(llvm::Module &llvm_module) override;
+
+ //------------------------------------------------------------------
+ /// Interface stub
+ ///
+ /// Implementation of the llvm::ModulePass::assignPassManager()
+ /// function.
+ //------------------------------------------------------------------
+ void assignPassManager(llvm::PMStack &pass_mgr_stack,
+ llvm::PassManagerType pass_mgr_type =
+ llvm::PMT_ModulePassManager) override;
+
+ //------------------------------------------------------------------
+ /// Returns PMT_ModulePassManager
+ ///
+ /// Implementation of the llvm::ModulePass::getPotentialPassManagerType()
+ /// function.
+ //------------------------------------------------------------------
+ llvm::PassManagerType getPotentialPassManagerType() const override;
private:
- //------------------------------------------------------------------
- /// Ensures that the current function's linkage is set to external.
- /// Otherwise the JIT may not return an address for it.
- ///
- /// @param[in] llvm_function
- /// The function whose linkage is to be fixed.
- ///
- /// @return
- /// True on success; false otherwise.
- //------------------------------------------------------------------
- bool
- FixFunctionLinkage (llvm::Function &llvm_function);
-
- //------------------------------------------------------------------
- /// A module-level pass to replace all function pointers with their
- /// integer equivalents.
- //------------------------------------------------------------------
-
- //------------------------------------------------------------------
- /// The top-level pass implementation
- ///
- /// @param[in] llvm_module
- /// The module currently being processed.
- ///
- /// @param[in] llvm_function
- /// The function currently being processed.
- ///
- /// @return
- /// True on success; false otherwise.
- //------------------------------------------------------------------
- bool
- HasSideEffects (llvm::Function &llvm_function);
-
- //------------------------------------------------------------------
- /// A function-level pass to check whether the function has side
- /// effects.
- //------------------------------------------------------------------
-
- //------------------------------------------------------------------
- /// Get the address of a function, and a location to put the complete
- /// Value of the function if one is available.
- ///
- /// @param[in] function
- /// The function to find the location of.
- ///
- /// @param[out] ptr
- /// The location of the function in the target.
- ///
- /// @param[out] name
- /// The resolved name of the function (matters for intrinsics).
- ///
- /// @param[out] value_ptr
- /// A variable to put the function's completed Value* in, or NULL
- /// if the Value* shouldn't be stored anywhere.
- ///
- /// @return
- /// The pointer.
- //------------------------------------------------------------------
- LookupResult
- GetFunctionAddress (llvm::Function *function,
- uint64_t &ptr,
- lldb_private::ConstString &name,
- llvm::Constant **&value_ptr);
-
- //------------------------------------------------------------------
- /// A function-level pass to take the generated global value
- /// $__lldb_expr_result and make it into a persistent variable.
- /// Also see ASTResultSynthesizer.
- //------------------------------------------------------------------
-
- //------------------------------------------------------------------
- /// Find the NamedDecl corresponding to a Value. This interface is
- /// exposed for the IR interpreter.
- ///
- /// @param[in] module
- /// The module containing metadata to search
- ///
- /// @param[in] global
- /// The global entity to search for
- ///
- /// @return
- /// The corresponding variable declaration
- //------------------------------------------------------------------
+ //------------------------------------------------------------------
+ /// Ensures that the current function's linkage is set to external.
+ /// Otherwise the JIT may not return an address for it.
+ ///
+ /// @param[in] llvm_function
+ /// The function whose linkage is to be fixed.
+ ///
+ /// @return
+ /// True on success; false otherwise.
+ //------------------------------------------------------------------
+ bool FixFunctionLinkage(llvm::Function &llvm_function);
+
+ //------------------------------------------------------------------
+ /// A module-level pass to replace all function pointers with their
+ /// integer equivalents.
+ //------------------------------------------------------------------
+
+ //------------------------------------------------------------------
+ /// The top-level pass implementation
+ ///
+ /// @param[in] llvm_module
+ /// The module currently being processed.
+ ///
+ /// @param[in] llvm_function
+ /// The function currently being processed.
+ ///
+ /// @return
+ /// True on success; false otherwise.
+ //------------------------------------------------------------------
+ bool HasSideEffects(llvm::Function &llvm_function);
+
+ //------------------------------------------------------------------
+ /// A function-level pass to check whether the function has side
+ /// effects.
+ //------------------------------------------------------------------
+
+ //------------------------------------------------------------------
+ /// Get the address of a function, and a location to put the complete
+ /// Value of the function if one is available.
+ ///
+ /// @param[in] function
+ /// The function to find the location of.
+ ///
+ /// @param[out] ptr
+ /// The location of the function in the target.
+ ///
+ /// @param[out] name
+ /// The resolved name of the function (matters for intrinsics).
+ ///
+ /// @param[out] value_ptr
+ /// A variable to put the function's completed Value* in, or NULL
+ /// if the Value* shouldn't be stored anywhere.
+ ///
+ /// @return
+ /// The pointer.
+ //------------------------------------------------------------------
+ LookupResult GetFunctionAddress(llvm::Function *function, uint64_t &ptr,
+ lldb_private::ConstString &name,
+ llvm::Constant **&value_ptr);
+
+ //------------------------------------------------------------------
+ /// A function-level pass to take the generated global value
+ /// $__lldb_expr_result and make it into a persistent variable.
+ /// Also see ASTResultSynthesizer.
+ //------------------------------------------------------------------
+
+ //------------------------------------------------------------------
+ /// Find the NamedDecl corresponding to a Value. This interface is
+ /// exposed for the IR interpreter.
+ ///
+ /// @param[in] module
+ /// The module containing metadata to search
+ ///
+ /// @param[in] global
+ /// The global entity to search for
+ ///
+ /// @return
+ /// The corresponding variable declaration
+ //------------------------------------------------------------------
public:
- static clang::NamedDecl *
- DeclForGlobal (const llvm::GlobalValue *global_val, llvm::Module *module);
+ static clang::NamedDecl *DeclForGlobal(const llvm::GlobalValue *global_val,
+ llvm::Module *module);
+
private:
- clang::NamedDecl *
- DeclForGlobal (llvm::GlobalValue *global);
-
- //------------------------------------------------------------------
- /// Set the constant result variable m_const_result to the provided
- /// constant, assuming it can be evaluated. The result variable
- /// will be reset to NULL later if the expression has side effects.
- ///
- /// @param[in] initializer
- /// The constant initializer for the variable.
- ///
- /// @param[in] name
- /// The name of the result variable.
- ///
- /// @param[in] type
- /// The Clang type of the result variable.
- //------------------------------------------------------------------
- void
- MaybeSetConstantResult (llvm::Constant *initializer,
- const lldb_private::ConstString &name,
- lldb_private::TypeFromParser type);
-
- //------------------------------------------------------------------
- /// If the IR represents a cast of a variable, set m_const_result
- /// to the result of the cast. The result variable will be reset to
- /// NULL latger if the expression has side effects.
- ///
- /// @param[in] type
- /// The Clang type of the result variable.
- //------------------------------------------------------------------
- void
- MaybeSetCastResult (lldb_private::TypeFromParser type);
-
- //------------------------------------------------------------------
- /// The top-level pass implementation
- ///
- /// @param[in] llvm_function
- /// The function currently being processed.
- ///
- /// @return
- /// True on success; false otherwise
- //------------------------------------------------------------------
- bool
- CreateResultVariable (llvm::Function &llvm_function);
-
- //------------------------------------------------------------------
- /// A module-level pass to find Objective-C constant strings and
- /// transform them to calls to CFStringCreateWithBytes.
- //------------------------------------------------------------------
-
- //------------------------------------------------------------------
- /// Rewrite a single Objective-C constant string.
- ///
- /// @param[in] NSStr
- /// The constant NSString to be transformed
- ///
- /// @param[in] CStr
- /// The constant C string inside the NSString. This will be
- /// passed as the bytes argument to CFStringCreateWithBytes.
- ///
- /// @return
- /// True on success; false otherwise
- //------------------------------------------------------------------
- bool
- RewriteObjCConstString (llvm::GlobalVariable *NSStr,
- llvm::GlobalVariable *CStr);
-
- //------------------------------------------------------------------
- /// The top-level pass implementation
- ///
- /// @return
- /// True on success; false otherwise
- //------------------------------------------------------------------
- bool
- RewriteObjCConstStrings ();
-
- //------------------------------------------------------------------
- /// A basic block-level pass to find all Objective-C method calls and
- /// rewrite them to use sel_registerName instead of statically allocated
- /// selectors. The reason is that the selectors are created on the
- /// assumption that the Objective-C runtime will scan the appropriate
- /// section and prepare them. This doesn't happen when code is copied
- /// into the target, though, and there's no easy way to induce the
- /// runtime to scan them. So instead we get our selectors from
- /// sel_registerName.
- //------------------------------------------------------------------
-
- //------------------------------------------------------------------
- /// Replace a single selector reference
- ///
- /// @param[in] selector_load
- /// The load of the statically-allocated selector.
- ///
- /// @return
- /// True on success; false otherwise
- //------------------------------------------------------------------
- bool
- RewriteObjCSelector (llvm::Instruction* selector_load);
-
- //------------------------------------------------------------------
- /// The top-level pass implementation
- ///
- /// @param[in] basic_block
- /// The basic block currently being processed.
- ///
- /// @return
- /// True on success; false otherwise
- //------------------------------------------------------------------
- bool
- RewriteObjCSelectors (llvm::BasicBlock &basic_block);
-
- //------------------------------------------------------------------
- /// A basic block-level pass to find all newly-declared persistent
- /// variables and register them with the ClangExprDeclMap. This
- /// allows them to be materialized and dematerialized like normal
- /// external variables. Before transformation, these persistent
- /// variables look like normal locals, so they have an allocation.
- /// This pass excises these allocations and makes references look
- /// like external references where they will be resolved -- like all
- /// other external references -- by ResolveExternals().
- //------------------------------------------------------------------
-
- //------------------------------------------------------------------
- /// Handle a single allocation of a persistent variable
- ///
- /// @param[in] persistent_alloc
- /// The allocation of the persistent variable.
- ///
- /// @return
- /// True on success; false otherwise
- //------------------------------------------------------------------
- bool
- RewritePersistentAlloc (llvm::Instruction *persistent_alloc);
-
- //------------------------------------------------------------------
- /// The top-level pass implementation
- ///
- /// @param[in] basic_block
- /// The basic block currently being processed.
- //------------------------------------------------------------------
- bool
- RewritePersistentAllocs (llvm::BasicBlock &basic_block);
-
- //------------------------------------------------------------------
- /// A function-level pass to find all external variables and functions
- /// used in the IR. Each found external variable is added to the
- /// struct, and each external function is resolved in place, its call
- /// replaced with a call to a function pointer whose value is the
- /// address of the function in the target process.
- //------------------------------------------------------------------
-
- //------------------------------------------------------------------
- /// Write an initializer to a memory array of assumed sufficient
- /// size.
- ///
- /// @param[in] data
- /// A pointer to the data to write to.
- ///
- /// @param[in] initializer
- /// The initializer itself.
- ///
- /// @return
- /// True on success; false otherwise
- //------------------------------------------------------------------
- bool
- MaterializeInitializer (uint8_t *data, llvm::Constant *initializer);
-
- //------------------------------------------------------------------
- /// Move an internal variable into the static allocation section.
- ///
- /// @param[in] global_variable
- /// The variable.
- ///
- /// @return
- /// True on success; false otherwise
- //------------------------------------------------------------------
- bool
- MaterializeInternalVariable (llvm::GlobalVariable *global_variable);
-
- //------------------------------------------------------------------
- /// Handle a single externally-defined variable
- ///
- /// @param[in] value
- /// The variable.
- ///
- /// @return
- /// True on success; false otherwise
- //------------------------------------------------------------------
- bool
- MaybeHandleVariable (llvm::Value *value);
-
- //------------------------------------------------------------------
- /// Handle a single externally-defined symbol
- ///
- /// @param[in] symbol
- /// The symbol.
- ///
- /// @return
- /// True on success; false otherwise
- //------------------------------------------------------------------
- bool
- HandleSymbol (llvm::Value *symbol);
-
- //------------------------------------------------------------------
- /// Handle a single externally-defined Objective-C class
- ///
- /// @param[in] classlist_reference
- /// The reference, usually "01L_OBJC_CLASSLIST_REFERENCES_$_n"
- /// where n (if present) is an index.
- ///
- /// @return
- /// True on success; false otherwise
- //------------------------------------------------------------------
- bool
- HandleObjCClass(llvm::Value *classlist_reference);
-
- //------------------------------------------------------------------
- /// Handle all the arguments to a function call
- ///
- /// @param[in] C
- /// The call instruction.
- ///
- /// @return
- /// True on success; false otherwise
- //------------------------------------------------------------------
- bool
- MaybeHandleCallArguments (llvm::CallInst *call_inst);
-
- //------------------------------------------------------------------
- /// Resolve variable references in calls to external functions
- ///
- /// @param[in] basic_block
- /// The basic block currently being processed.
- ///
- /// @return
- /// True on success; false otherwise
- //------------------------------------------------------------------
- bool
- ResolveCalls (llvm::BasicBlock &basic_block);
-
- //------------------------------------------------------------------
- /// Remove calls to __cxa_atexit, which should never be generated by
- /// expressions.
- ///
- /// @param[in] call_inst
- /// The call instruction.
- ///
- /// @return
- /// True if the scan was successful; false if some operation
- /// failed
- //------------------------------------------------------------------
- bool
- RemoveCXAAtExit (llvm::BasicBlock &basic_block);
-
- //------------------------------------------------------------------
- /// The top-level pass implementation
- ///
- /// @param[in] basic_block
- /// The function currently being processed.
- ///
- /// @return
- /// True on success; false otherwise
- //------------------------------------------------------------------
- bool
- ResolveExternals (llvm::Function &llvm_function);
-
- //------------------------------------------------------------------
- /// A basic block-level pass to excise guard variables from the code.
- /// The result for the function is passed through Clang as a static
- /// variable. Static variables normally have guard variables to
- /// ensure that they are only initialized once.
- //------------------------------------------------------------------
-
- //------------------------------------------------------------------
- /// Rewrite a load to a guard variable to return constant 0.
- ///
- /// @param[in] guard_load
- /// The load instruction to zero out.
- //------------------------------------------------------------------
- void
- TurnGuardLoadIntoZero(llvm::Instruction* guard_load);
-
- //------------------------------------------------------------------
- /// The top-level pass implementation
- ///
- /// @param[in] basic_block
- /// The basic block currently being processed.
- ///
- /// @return
- /// True on success; false otherwise
- //------------------------------------------------------------------
- bool
- RemoveGuards (llvm::BasicBlock &basic_block);
-
- //------------------------------------------------------------------
- /// A function-level pass to make all external variable references
- /// point at the correct offsets from the void* passed into the
- /// function. ClangExpressionDeclMap::DoStructLayout() must be called
- /// beforehand, so that the offsets are valid.
- //------------------------------------------------------------------
-
- //------------------------------------------------------------------
- /// The top-level pass implementation
- ///
- /// @param[in] llvm_function
- /// The function currently being processed.
- ///
- /// @return
- /// True on success; false otherwise
- //------------------------------------------------------------------
- bool
- ReplaceVariables(llvm::Function &llvm_function);
-
- /// Flags
- bool m_resolve_vars; ///< True if external variable references and persistent variable references should be resolved
- lldb_private::ConstString m_func_name; ///< The name of the function to translate
- lldb_private::ConstString m_result_name; ///< The name of the result variable ($0, $1, ...)
- lldb_private::TypeFromParser m_result_type; ///< The type of the result variable.
- llvm::Module *m_module; ///< The module being processed, or NULL if that has not been determined yet.
- std::unique_ptr<llvm::DataLayout>
- m_target_data; ///< The target data for the module being processed, or NULL if there is no module.
- lldb_private::ClangExpressionDeclMap *m_decl_map; ///< The DeclMap containing the Decls
- llvm::Constant *m_CFStringCreateWithBytes; ///< The address of the function CFStringCreateWithBytes, cast to the
- ///appropriate function pointer type
- llvm::Constant *m_sel_registerName; ///< The address of the function sel_registerName, cast to the appropriate
- ///function pointer type
- llvm::IntegerType *m_intptr_ty; ///< The type of an integer large enough to hold a pointer.
- lldb_private::Stream &m_error_stream; ///< The stream on which errors should be printed
- lldb_private::IRExecutionUnit &m_execution_unit; ///< The execution unit containing the IR being created.
-
- llvm::StoreInst *m_result_store; ///< If non-NULL, the store instruction that writes to the result variable. If
- ///m_has_side_effects is true, this is NULL.
- bool m_result_is_pointer; ///< True if the function's result in the AST is a pointer (see comments in
- ///ASTResultSynthesizer::SynthesizeBodyResult)
-
- llvm::GlobalVariable *m_reloc_placeholder; ///< A placeholder that will be replaced by a pointer to the final
- ///location of the static allocation.
-
- //------------------------------------------------------------------
- /// UnfoldConstant operates on a constant [Old] which has just been
- /// replaced with a value [New]. We assume that new_value has
- /// been properly placed early in the function, in front of the
- /// first instruction in the entry basic block
- /// [FirstEntryInstruction].
- ///
- /// UnfoldConstant reads through the uses of Old and replaces Old
- /// in those uses with New. Where those uses are constants, the
- /// function generates new instructions to compute the result of the
- /// new, non-constant expression and places them before
- /// FirstEntryInstruction. These instructions replace the constant
- /// uses, so UnfoldConstant calls itself recursively for those.
- ///
- /// @param[in] llvm_function
- /// The function currently being processed.
- ///
- /// @return
- /// True on success; false otherwise
- //------------------------------------------------------------------
-
- class FunctionValueCache {
- public:
- typedef std::function <llvm::Value *(llvm::Function *)> Maker;
-
- FunctionValueCache (Maker const &maker);
- ~FunctionValueCache ();
- llvm::Value *GetValue (llvm::Function *function);
- private:
- Maker const m_maker;
- typedef std::map<llvm::Function *, llvm::Value *> FunctionValueMap;
- FunctionValueMap m_values;
- };
-
- FunctionValueCache m_entry_instruction_finder;
-
- static bool
- UnfoldConstant (llvm::Constant *old_constant,
- llvm::Function *llvm_function,
- FunctionValueCache &value_maker,
- FunctionValueCache &entry_instruction_finder,
- lldb_private::Stream &error_stream);
-
- //------------------------------------------------------------------
- /// Construct a reference to m_reloc_placeholder with a given type
- /// and offset. This typically happens after inserting data into
- /// m_data_allocator.
- ///
- /// @param[in] type
- /// The type of the value being loaded.
- ///
- /// @param[in] offset
- /// The offset of the value from the base of m_data_allocator.
- ///
- /// @return
- /// The Constant for the reference, usually a ConstantExpr.
- //------------------------------------------------------------------
- llvm::Constant *
- BuildRelocation(llvm::Type *type,
- uint64_t offset);
-
- //------------------------------------------------------------------
- /// Commit the allocation in m_data_allocator and use its final
- /// location to replace m_reloc_placeholder.
- ///
- /// @param[in] module
- /// The module that m_data_allocator resides in
- ///
- /// @return
- /// True on success; false otherwise
- //------------------------------------------------------------------
- bool
- CompleteDataAllocation ();
+ clang::NamedDecl *DeclForGlobal(llvm::GlobalValue *global);
+
+ //------------------------------------------------------------------
+ /// Set the constant result variable m_const_result to the provided
+ /// constant, assuming it can be evaluated. The result variable
+ /// will be reset to NULL later if the expression has side effects.
+ ///
+ /// @param[in] initializer
+ /// The constant initializer for the variable.
+ ///
+ /// @param[in] name
+ /// The name of the result variable.
+ ///
+ /// @param[in] type
+ /// The Clang type of the result variable.
+ //------------------------------------------------------------------
+ void MaybeSetConstantResult(llvm::Constant *initializer,
+ const lldb_private::ConstString &name,
+ lldb_private::TypeFromParser type);
+
+ //------------------------------------------------------------------
+ /// If the IR represents a cast of a variable, set m_const_result
+ /// to the result of the cast. The result variable will be reset to
+ /// NULL latger if the expression has side effects.
+ ///
+ /// @param[in] type
+ /// The Clang type of the result variable.
+ //------------------------------------------------------------------
+ void MaybeSetCastResult(lldb_private::TypeFromParser type);
+
+ //------------------------------------------------------------------
+ /// The top-level pass implementation
+ ///
+ /// @param[in] llvm_function
+ /// The function currently being processed.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool CreateResultVariable(llvm::Function &llvm_function);
+
+ //------------------------------------------------------------------
+ /// A module-level pass to find Objective-C constant strings and
+ /// transform them to calls to CFStringCreateWithBytes.
+ //------------------------------------------------------------------
+
+ //------------------------------------------------------------------
+ /// Rewrite a single Objective-C constant string.
+ ///
+ /// @param[in] NSStr
+ /// The constant NSString to be transformed
+ ///
+ /// @param[in] CStr
+ /// The constant C string inside the NSString. This will be
+ /// passed as the bytes argument to CFStringCreateWithBytes.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool RewriteObjCConstString(llvm::GlobalVariable *NSStr,
+ llvm::GlobalVariable *CStr);
+
+ //------------------------------------------------------------------
+ /// The top-level pass implementation
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool RewriteObjCConstStrings();
+
+ //------------------------------------------------------------------
+ /// A basic block-level pass to find all Objective-C method calls and
+ /// rewrite them to use sel_registerName instead of statically allocated
+ /// selectors. The reason is that the selectors are created on the
+ /// assumption that the Objective-C runtime will scan the appropriate
+ /// section and prepare them. This doesn't happen when code is copied
+ /// into the target, though, and there's no easy way to induce the
+ /// runtime to scan them. So instead we get our selectors from
+ /// sel_registerName.
+ //------------------------------------------------------------------
+
+ //------------------------------------------------------------------
+ /// Replace a single selector reference
+ ///
+ /// @param[in] selector_load
+ /// The load of the statically-allocated selector.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool RewriteObjCSelector(llvm::Instruction *selector_load);
+
+ //------------------------------------------------------------------
+ /// The top-level pass implementation
+ ///
+ /// @param[in] basic_block
+ /// The basic block currently being processed.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool RewriteObjCSelectors(llvm::BasicBlock &basic_block);
+
+ //------------------------------------------------------------------
+ /// A basic block-level pass to find all newly-declared persistent
+ /// variables and register them with the ClangExprDeclMap. This
+ /// allows them to be materialized and dematerialized like normal
+ /// external variables. Before transformation, these persistent
+ /// variables look like normal locals, so they have an allocation.
+ /// This pass excises these allocations and makes references look
+ /// like external references where they will be resolved -- like all
+ /// other external references -- by ResolveExternals().
+ //------------------------------------------------------------------
+
+ //------------------------------------------------------------------
+ /// Handle a single allocation of a persistent variable
+ ///
+ /// @param[in] persistent_alloc
+ /// The allocation of the persistent variable.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool RewritePersistentAlloc(llvm::Instruction *persistent_alloc);
+
+ //------------------------------------------------------------------
+ /// The top-level pass implementation
+ ///
+ /// @param[in] basic_block
+ /// The basic block currently being processed.
+ //------------------------------------------------------------------
+ bool RewritePersistentAllocs(llvm::BasicBlock &basic_block);
+
+ //------------------------------------------------------------------
+ /// A function-level pass to find all external variables and functions
+ /// used in the IR. Each found external variable is added to the
+ /// struct, and each external function is resolved in place, its call
+ /// replaced with a call to a function pointer whose value is the
+ /// address of the function in the target process.
+ //------------------------------------------------------------------
+
+ //------------------------------------------------------------------
+ /// Write an initializer to a memory array of assumed sufficient
+ /// size.
+ ///
+ /// @param[in] data
+ /// A pointer to the data to write to.
+ ///
+ /// @param[in] initializer
+ /// The initializer itself.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool MaterializeInitializer(uint8_t *data, llvm::Constant *initializer);
+
+ //------------------------------------------------------------------
+ /// Move an internal variable into the static allocation section.
+ ///
+ /// @param[in] global_variable
+ /// The variable.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool MaterializeInternalVariable(llvm::GlobalVariable *global_variable);
+
+ //------------------------------------------------------------------
+ /// Handle a single externally-defined variable
+ ///
+ /// @param[in] value
+ /// The variable.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool MaybeHandleVariable(llvm::Value *value);
+
+ //------------------------------------------------------------------
+ /// Handle a single externally-defined symbol
+ ///
+ /// @param[in] symbol
+ /// The symbol.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool HandleSymbol(llvm::Value *symbol);
+
+ //------------------------------------------------------------------
+ /// Handle a single externally-defined Objective-C class
+ ///
+ /// @param[in] classlist_reference
+ /// The reference, usually "01L_OBJC_CLASSLIST_REFERENCES_$_n"
+ /// where n (if present) is an index.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool HandleObjCClass(llvm::Value *classlist_reference);
+
+ //------------------------------------------------------------------
+ /// Handle all the arguments to a function call
+ ///
+ /// @param[in] C
+ /// The call instruction.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool MaybeHandleCallArguments(llvm::CallInst *call_inst);
+
+ //------------------------------------------------------------------
+ /// Resolve variable references in calls to external functions
+ ///
+ /// @param[in] basic_block
+ /// The basic block currently being processed.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool ResolveCalls(llvm::BasicBlock &basic_block);
+
+ //------------------------------------------------------------------
+ /// Remove calls to __cxa_atexit, which should never be generated by
+ /// expressions.
+ ///
+ /// @param[in] call_inst
+ /// The call instruction.
+ ///
+ /// @return
+ /// True if the scan was successful; false if some operation
+ /// failed
+ //------------------------------------------------------------------
+ bool RemoveCXAAtExit(llvm::BasicBlock &basic_block);
+
+ //------------------------------------------------------------------
+ /// The top-level pass implementation
+ ///
+ /// @param[in] basic_block
+ /// The function currently being processed.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool ResolveExternals(llvm::Function &llvm_function);
+
+ //------------------------------------------------------------------
+ /// A basic block-level pass to excise guard variables from the code.
+ /// The result for the function is passed through Clang as a static
+ /// variable. Static variables normally have guard variables to
+ /// ensure that they are only initialized once.
+ //------------------------------------------------------------------
+
+ //------------------------------------------------------------------
+ /// Rewrite a load to a guard variable to return constant 0.
+ ///
+ /// @param[in] guard_load
+ /// The load instruction to zero out.
+ //------------------------------------------------------------------
+ void TurnGuardLoadIntoZero(llvm::Instruction *guard_load);
+
+ //------------------------------------------------------------------
+ /// The top-level pass implementation
+ ///
+ /// @param[in] basic_block
+ /// The basic block currently being processed.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool RemoveGuards(llvm::BasicBlock &basic_block);
+
+ //------------------------------------------------------------------
+ /// A function-level pass to make all external variable references
+ /// point at the correct offsets from the void* passed into the
+ /// function. ClangExpressionDeclMap::DoStructLayout() must be called
+ /// beforehand, so that the offsets are valid.
+ //------------------------------------------------------------------
+
+ //------------------------------------------------------------------
+ /// The top-level pass implementation
+ ///
+ /// @param[in] llvm_function
+ /// The function currently being processed.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool ReplaceVariables(llvm::Function &llvm_function);
+
+ /// Flags
+ bool m_resolve_vars; ///< True if external variable references and persistent
+ ///variable references should be resolved
+ lldb_private::ConstString
+ m_func_name; ///< The name of the function to translate
+ lldb_private::ConstString
+ m_result_name; ///< The name of the result variable ($0, $1, ...)
+ lldb_private::TypeFromParser
+ m_result_type; ///< The type of the result variable.
+ llvm::Module *m_module; ///< The module being processed, or NULL if that has
+ ///not been determined yet.
+ std::unique_ptr<llvm::DataLayout> m_target_data; ///< The target data for the
+ ///module being processed, or
+ ///NULL if there is no
+ ///module.
+ lldb_private::ClangExpressionDeclMap
+ *m_decl_map; ///< The DeclMap containing the Decls
+ llvm::Constant *m_CFStringCreateWithBytes; ///< The address of the function
+ ///CFStringCreateWithBytes, cast to
+ ///the
+ /// appropriate function pointer type
+ llvm::Constant *m_sel_registerName; ///< The address of the function
+ ///sel_registerName, cast to the
+ ///appropriate
+ /// function pointer type
+ llvm::IntegerType
+ *m_intptr_ty; ///< The type of an integer large enough to hold a pointer.
+ lldb_private::Stream
+ &m_error_stream; ///< The stream on which errors should be printed
+ lldb_private::IRExecutionUnit &
+ m_execution_unit; ///< The execution unit containing the IR being created.
+
+ llvm::StoreInst *m_result_store; ///< If non-NULL, the store instruction that
+ ///writes to the result variable. If
+ /// m_has_side_effects is true, this is NULL.
+ bool m_result_is_pointer; ///< True if the function's result in the AST is a
+ ///pointer (see comments in
+ /// ASTResultSynthesizer::SynthesizeBodyResult)
+
+ llvm::GlobalVariable *m_reloc_placeholder; ///< A placeholder that will be
+ ///replaced by a pointer to the
+ ///final
+ /// location of the static allocation.
+
+ //------------------------------------------------------------------
+ /// UnfoldConstant operates on a constant [Old] which has just been
+ /// replaced with a value [New]. We assume that new_value has
+ /// been properly placed early in the function, in front of the
+ /// first instruction in the entry basic block
+ /// [FirstEntryInstruction].
+ ///
+ /// UnfoldConstant reads through the uses of Old and replaces Old
+ /// in those uses with New. Where those uses are constants, the
+ /// function generates new instructions to compute the result of the
+ /// new, non-constant expression and places them before
+ /// FirstEntryInstruction. These instructions replace the constant
+ /// uses, so UnfoldConstant calls itself recursively for those.
+ ///
+ /// @param[in] llvm_function
+ /// The function currently being processed.
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+
+ class FunctionValueCache {
+ public:
+ typedef std::function<llvm::Value *(llvm::Function *)> Maker;
+
+ FunctionValueCache(Maker const &maker);
+ ~FunctionValueCache();
+ llvm::Value *GetValue(llvm::Function *function);
+
+ private:
+ Maker const m_maker;
+ typedef std::map<llvm::Function *, llvm::Value *> FunctionValueMap;
+ FunctionValueMap m_values;
+ };
+
+ FunctionValueCache m_entry_instruction_finder;
+
+ static bool UnfoldConstant(llvm::Constant *old_constant,
+ llvm::Function *llvm_function,
+ FunctionValueCache &value_maker,
+ FunctionValueCache &entry_instruction_finder,
+ lldb_private::Stream &error_stream);
+
+ //------------------------------------------------------------------
+ /// Construct a reference to m_reloc_placeholder with a given type
+ /// and offset. This typically happens after inserting data into
+ /// m_data_allocator.
+ ///
+ /// @param[in] type
+ /// The type of the value being loaded.
+ ///
+ /// @param[in] offset
+ /// The offset of the value from the base of m_data_allocator.
+ ///
+ /// @return
+ /// The Constant for the reference, usually a ConstantExpr.
+ //------------------------------------------------------------------
+ llvm::Constant *BuildRelocation(llvm::Type *type, uint64_t offset);
+ //------------------------------------------------------------------
+ /// Commit the allocation in m_data_allocator and use its final
+ /// location to replace m_reloc_placeholder.
+ ///
+ /// @param[in] module
+ /// The module that m_data_allocator resides in
+ ///
+ /// @return
+ /// True on success; false otherwise
+ //------------------------------------------------------------------
+ bool CompleteDataAllocation();
};
#endif // liblldb_IRForTarget_h_
diff --git a/lldb/source/Plugins/ExpressionParser/Go/GoAST.h b/lldb/source/Plugins/ExpressionParser/Go/GoAST.h
index 89836a38acb..d24e6c54871 100644
--- a/lldb/source/Plugins/ExpressionParser/Go/GoAST.h
+++ b/lldb/source/Plugins/ExpressionParser/Go/GoAST.h
@@ -13,3214 +13,1965 @@
#ifndef liblldb_GoAST_h
#define liblldb_GoAST_h
+#include "Plugins/ExpressionParser/Go/GoLexer.h"
#include "lldb/lldb-forward.h"
#include "lldb/lldb-private.h"
#include "llvm/Support/Casting.h"
-#include "Plugins/ExpressionParser/Go/GoLexer.h"
-namespace lldb_private
-{
-
-class GoASTNode
-{
- public:
- typedef GoLexer::TokenType TokenType;
- typedef GoLexer::Token Token;
- enum ChanDir
- {
- eChanBidir,
- eChanSend,
- eChanRecv,
- };
- enum NodeKind
- {
- eBadDecl,
- eFuncDecl,
- eGenDecl,
- eArrayType,
- eBadExpr,
- eBasicLit,
- eBinaryExpr,
- eIdent,
- eCallExpr,
- eChanType,
- eCompositeLit,
- eEllipsis,
- eFuncType,
- eFuncLit,
- eIndexExpr,
- eInterfaceType,
- eKeyValueExpr,
- eMapType,
- eParenExpr,
- eSelectorExpr,
- eSliceExpr,
- eStarExpr,
- eStructType,
- eTypeAssertExpr,
- eUnaryExpr,
- eImportSpec,
- eTypeSpec,
- eValueSpec,
- eAssignStmt,
- eBadStmt,
- eBlockStmt,
- eBranchStmt,
- eCaseClause,
- eCommClause,
- eDeclStmt,
- eDeferStmt,
- eEmptyStmt,
- eExprStmt,
- eForStmt,
- eGoStmt,
- eIfStmt,
- eIncDecStmt,
- eLabeledStmt,
- eRangeStmt,
- eReturnStmt,
- eSelectStmt,
- eSendStmt,
- eSwitchStmt,
- eTypeSwitchStmt,
- eField,
- eFieldList,
- };
-
- virtual ~GoASTNode() = default;
-
- NodeKind
- GetKind() const
- {
- return m_kind;
- }
+namespace lldb_private {
+
+class GoASTNode {
+public:
+ typedef GoLexer::TokenType TokenType;
+ typedef GoLexer::Token Token;
+ enum ChanDir {
+ eChanBidir,
+ eChanSend,
+ eChanRecv,
+ };
+ enum NodeKind {
+ eBadDecl,
+ eFuncDecl,
+ eGenDecl,
+ eArrayType,
+ eBadExpr,
+ eBasicLit,
+ eBinaryExpr,
+ eIdent,
+ eCallExpr,
+ eChanType,
+ eCompositeLit,
+ eEllipsis,
+ eFuncType,
+ eFuncLit,
+ eIndexExpr,
+ eInterfaceType,
+ eKeyValueExpr,
+ eMapType,
+ eParenExpr,
+ eSelectorExpr,
+ eSliceExpr,
+ eStarExpr,
+ eStructType,
+ eTypeAssertExpr,
+ eUnaryExpr,
+ eImportSpec,
+ eTypeSpec,
+ eValueSpec,
+ eAssignStmt,
+ eBadStmt,
+ eBlockStmt,
+ eBranchStmt,
+ eCaseClause,
+ eCommClause,
+ eDeclStmt,
+ eDeferStmt,
+ eEmptyStmt,
+ eExprStmt,
+ eForStmt,
+ eGoStmt,
+ eIfStmt,
+ eIncDecStmt,
+ eLabeledStmt,
+ eRangeStmt,
+ eReturnStmt,
+ eSelectStmt,
+ eSendStmt,
+ eSwitchStmt,
+ eTypeSwitchStmt,
+ eField,
+ eFieldList,
+ };
+
+ virtual ~GoASTNode() = default;
+
+ NodeKind GetKind() const { return m_kind; }
+
+ virtual const char *GetKindName() const = 0;
+
+ template <typename V> void WalkChildren(V &v);
+
+protected:
+ explicit GoASTNode(NodeKind kind) : m_kind(kind) {}
+
+private:
+ const NodeKind m_kind;
+
+ GoASTNode(const GoASTNode &) = delete;
+ const GoASTNode &operator=(const GoASTNode &) = delete;
+};
- virtual const char *GetKindName() const = 0;
+class GoASTDecl : public GoASTNode {
+public:
+ template <typename R, typename V> R Visit(V *v) const;
- template <typename V> void WalkChildren(V &v);
+ static bool classof(const GoASTNode *n) {
+ return n->GetKind() >= eBadDecl && n->GetKind() <= eGenDecl;
+ }
- protected:
- explicit GoASTNode(NodeKind kind) : m_kind(kind) { }
+protected:
+ explicit GoASTDecl(NodeKind kind) : GoASTNode(kind) {}
- private:
- const NodeKind m_kind;
-
- GoASTNode(const GoASTNode &) = delete;
- const GoASTNode &operator=(const GoASTNode &) = delete;
+private:
+ GoASTDecl(const GoASTDecl &) = delete;
+ const GoASTDecl &operator=(const GoASTDecl &) = delete;
};
+class GoASTExpr : public GoASTNode {
+public:
+ template <typename R, typename V> R Visit(V *v) const;
-class GoASTDecl : public GoASTNode
-{
- public:
- template <typename R, typename V> R Visit(V *v) const;
-
- static bool
- classof(const GoASTNode *n)
- {
- return n->GetKind() >= eBadDecl && n->GetKind() <= eGenDecl;
- }
+ static bool classof(const GoASTNode *n) {
+ return n->GetKind() >= eArrayType && n->GetKind() <= eUnaryExpr;
+ }
- protected:
- explicit GoASTDecl(NodeKind kind) : GoASTNode(kind) { }
- private:
+protected:
+ explicit GoASTExpr(NodeKind kind) : GoASTNode(kind) {}
- GoASTDecl(const GoASTDecl &) = delete;
- const GoASTDecl &operator=(const GoASTDecl &) = delete;
+private:
+ GoASTExpr(const GoASTExpr &) = delete;
+ const GoASTExpr &operator=(const GoASTExpr &) = delete;
};
-class GoASTExpr : public GoASTNode
-{
- public:
- template <typename R, typename V> R Visit(V *v) const;
+class GoASTSpec : public GoASTNode {
+public:
+ template <typename R, typename V> R Visit(V *v) const;
- static bool
- classof(const GoASTNode *n)
- {
- return n->GetKind() >= eArrayType && n->GetKind() <= eUnaryExpr;
- }
+ static bool classof(const GoASTNode *n) {
+ return n->GetKind() >= eImportSpec && n->GetKind() <= eValueSpec;
+ }
- protected:
- explicit GoASTExpr(NodeKind kind) : GoASTNode(kind) { }
- private:
+protected:
+ explicit GoASTSpec(NodeKind kind) : GoASTNode(kind) {}
- GoASTExpr(const GoASTExpr &) = delete;
- const GoASTExpr &operator=(const GoASTExpr &) = delete;
+private:
+ GoASTSpec(const GoASTSpec &) = delete;
+ const GoASTSpec &operator=(const GoASTSpec &) = delete;
};
-class GoASTSpec : public GoASTNode
-{
- public:
- template <typename R, typename V> R Visit(V *v) const;
+class GoASTStmt : public GoASTNode {
+public:
+ template <typename R, typename V> R Visit(V *v) const;
- static bool
- classof(const GoASTNode *n)
- {
- return n->GetKind() >= eImportSpec && n->GetKind() <= eValueSpec;
- }
+ static bool classof(const GoASTNode *n) {
+ return n->GetKind() >= eAssignStmt && n->GetKind() <= eTypeSwitchStmt;
+ }
- protected:
- explicit GoASTSpec(NodeKind kind) : GoASTNode(kind) { }
- private:
+protected:
+ explicit GoASTStmt(NodeKind kind) : GoASTNode(kind) {}
- GoASTSpec(const GoASTSpec &) = delete;
- const GoASTSpec &operator=(const GoASTSpec &) = delete;
+private:
+ GoASTStmt(const GoASTStmt &) = delete;
+ const GoASTStmt &operator=(const GoASTStmt &) = delete;
};
-class GoASTStmt : public GoASTNode
-{
- public:
- template <typename R, typename V> R Visit(V *v) const;
+class GoASTArrayType : public GoASTExpr {
+public:
+ GoASTArrayType(GoASTExpr *len, GoASTExpr *elt)
+ : GoASTExpr(eArrayType), m_len_up(len), m_elt_up(elt) {}
+ ~GoASTArrayType() override = default;
- static bool
- classof(const GoASTNode *n)
- {
- return n->GetKind() >= eAssignStmt && n->GetKind() <= eTypeSwitchStmt;
- }
+ const char *GetKindName() const override { return "ArrayType"; }
- protected:
- explicit GoASTStmt(NodeKind kind) : GoASTNode(kind) { }
- private:
+ static bool classof(const GoASTNode *n) { return n->GetKind() == eArrayType; }
- GoASTStmt(const GoASTStmt &) = delete;
- const GoASTStmt &operator=(const GoASTStmt &) = delete;
-};
+ const GoASTExpr *GetLen() const { return m_len_up.get(); }
+ void SetLen(GoASTExpr *len) { m_len_up.reset(len); }
+ const GoASTExpr *GetElt() const { return m_elt_up.get(); }
+ void SetElt(GoASTExpr *elt) { m_elt_up.reset(elt); }
-class GoASTArrayType : public GoASTExpr
-{
- public:
- GoASTArrayType(GoASTExpr *len, GoASTExpr *elt) : GoASTExpr(eArrayType), m_len_up(len), m_elt_up(elt) {}
- ~GoASTArrayType() override = default;
+private:
+ friend class GoASTNode;
+ std::unique_ptr<GoASTExpr> m_len_up;
+ std::unique_ptr<GoASTExpr> m_elt_up;
- const char *
- GetKindName() const override
- {
- return "ArrayType";
- }
+ GoASTArrayType(const GoASTArrayType &) = delete;
+ const GoASTArrayType &operator=(const GoASTArrayType &) = delete;
+};
- static bool
- classof(const GoASTNode *n)
- {
- return n->GetKind() == eArrayType;
- }
-
- const GoASTExpr *
- GetLen() const
- {
- return m_len_up.get();
- }
- void
- SetLen(GoASTExpr *len)
- {
- m_len_up.reset(len);
- }
+class GoASTAssignStmt : public GoASTStmt {
+public:
+ explicit GoASTAssignStmt(bool define)
+ : GoASTStmt(eAssignStmt), m_define(define) {}
+ ~GoASTAssignStmt() override = default;
+
+ const char *GetKindName() const override { return "AssignStmt"; }
+
+ static bool classof(const GoASTNode *n) {
+ return n->GetKind() == eAssignStmt;
+ }
+
+ size_t NumLhs() const { return m_lhs.size(); }
+ const GoASTExpr *GetLhs(int i) const { return m_lhs[i].get(); }
+ void AddLhs(GoASTExpr *lhs) {
+ m_lhs.push_back(std::unique_ptr<GoASTExpr>(lhs));
+ }
+
+ size_t NumRhs() const { return m_rhs.size(); }
+ const GoASTExpr *GetRhs(int i) const { return m_rhs[i].get(); }
+ void AddRhs(GoASTExpr *rhs) {
+ m_rhs.push_back(std::unique_ptr<GoASTExpr>(rhs));
+ }
+
+ bool GetDefine() const { return m_define; }
+ void SetDefine(bool define) { m_define = define; }
+
+private:
+ friend class GoASTNode;
+ std::vector<std::unique_ptr<GoASTExpr>> m_lhs;
+ std::vector<std::unique_ptr<GoASTExpr>> m_rhs;
+ bool m_define;
+
+ GoASTAssignStmt(const GoASTAssignStmt &) = delete;
+ const GoASTAssignStmt &operator=(const GoASTAssignStmt &) = delete;
+};
- const GoASTExpr *
- GetElt() const
- {
- return m_elt_up.get();
- }
- void
- SetElt(GoASTExpr *elt)
- {
- m_elt_up.reset(elt);
- }
+class GoASTBadDecl : public GoASTDecl {
+public:
+ GoASTBadDecl() : GoASTDecl(eBadDecl) {}
+ ~GoASTBadDecl() override = default;
- private:
- friend class GoASTNode;
- std::unique_ptr<GoASTExpr> m_len_up;
- std::unique_ptr<GoASTExpr> m_elt_up;
+ const char *GetKindName() const override { return "BadDecl"; }
- GoASTArrayType(const GoASTArrayType &) = delete;
- const GoASTArrayType &operator=(const GoASTArrayType &) = delete;
+ static bool classof(const GoASTNode *n) { return n->GetKind() == eBadDecl; }
+
+ GoASTBadDecl(const GoASTBadDecl &) = delete;
+ const GoASTBadDecl &operator=(const GoASTBadDecl &) = delete;
};
-class GoASTAssignStmt : public GoASTStmt
-{
- public:
- explicit GoASTAssignStmt(bool define) : GoASTStmt(eAssignStmt), m_define(define) {}
- ~GoASTAssignStmt() override = default;
+class GoASTBadExpr : public GoASTExpr {
+public:
+ GoASTBadExpr() : GoASTExpr(eBadExpr) {}
+ ~GoASTBadExpr() override = default;
- const char *
- GetKindName() const override
- {
- return "AssignStmt";
- }
+ const char *GetKindName() const override { return "BadExpr"; }
- static bool
- classof(const GoASTNode *n)
- {
- return n->GetKind() == eAssignStmt;
- }
-
- size_t
- NumLhs() const
- {
- return m_lhs.size();
- }
- const GoASTExpr *
- GetLhs(int i) const
- {
- return m_lhs[i].get();
- }
- void
- AddLhs(GoASTExpr *lhs)
- {
- m_lhs.push_back(std::unique_ptr<GoASTExpr>(lhs));
- }
+ static bool classof(const GoASTNode *n) { return n->GetKind() == eBadExpr; }
- size_t
- NumRhs() const
- {
- return m_rhs.size();
- }
- const GoASTExpr *
- GetRhs(int i) const
- {
- return m_rhs[i].get();
- }
- void
- AddRhs(GoASTExpr *rhs)
- {
- m_rhs.push_back(std::unique_ptr<GoASTExpr>(rhs));
- }
+ GoASTBadExpr(const GoASTBadExpr &) = delete;
+ const GoASTBadExpr &operator=(const GoASTBadExpr &) = delete;
+};
- bool
- GetDefine() const
- {
- return m_define;
- }
- void
- SetDefine(bool define)
- {
- m_define = define;
- }
+class GoASTBadStmt : public GoASTStmt {
+public:
+ GoASTBadStmt() : GoASTStmt(eBadStmt) {}
+ ~GoASTBadStmt() override = default;
- private:
- friend class GoASTNode;
- std::vector<std::unique_ptr<GoASTExpr> > m_lhs;
- std::vector<std::unique_ptr<GoASTExpr> > m_rhs;
- bool m_define;
+ const char *GetKindName() const override { return "BadStmt"; }
- GoASTAssignStmt(const GoASTAssignStmt &) = delete;
- const GoASTAssignStmt &operator=(const GoASTAssignStmt &) = delete;
+ static bool classof(const GoASTNode *n) { return n->GetKind() == eBadStmt; }
+
+ GoASTBadStmt(const GoASTBadStmt &) = delete;
+ const GoASTBadStmt &operator=(const GoASTBadStmt &) = delete;
};
-class GoASTBadDecl : public GoASTDecl
-{
- public:
- GoASTBadDecl() : GoASTDecl(eBadDecl) {}
- ~GoASTBadDecl() override = default;
+class GoASTBasicLit : public GoASTExpr {
+public:
+ explicit GoASTBasicLit(Token value) : GoASTExpr(eBasicLit), m_value(value) {}
+ ~GoASTBasicLit() override = default;
- const char *
- GetKindName() const override
- {
- return "BadDecl";
- }
+ const char *GetKindName() const override { return "BasicLit"; }
- static bool
- classof(const GoASTNode *n)
- {
- return n->GetKind() == eBadDecl;
- }
-
- GoASTBadDecl(const GoASTBadDecl &) = delete;
- const GoASTBadDecl &operator=(const GoASTBadDecl &) = delete;
-};
+ static bool classof(const GoASTNode *n) { return n->GetKind() == eBasicLit; }
-class GoASTBadExpr : public GoASTExpr
-{
- public:
- GoASTBadExpr() : GoASTExpr(eBadExpr) {}
- ~GoASTBadExpr() override = default;
+ Token GetValue() const { return m_value; }
+ void SetValue(Token value) { m_value = value; }
- const char *
- GetKindName() const override
- {
- return "BadExpr";
- }
+private:
+ friend class GoASTNode;
+ Token m_value;
- static bool
- classof(const GoASTNode *n)
- {
- return n->GetKind() == eBadExpr;
- }
-
- GoASTBadExpr(const GoASTBadExpr &) = delete;
- const GoASTBadExpr &operator=(const GoASTBadExpr &) = delete;
+ GoASTBasicLit(const GoASTBasicLit &) = delete;
+ const GoASTBasicLit &operator=(const GoASTBasicLit &) = delete;
};
-class GoASTBadStmt : public GoASTStmt
-{
- public:
- GoASTBadStmt() : GoASTStmt(eBadStmt) {}
- ~GoASTBadStmt() override = default;
+class GoASTBinaryExpr : public GoASTExpr {
+public:
+ GoASTBinaryExpr(GoASTExpr *x, GoASTExpr *y, TokenType op)
+ : GoASTExpr(eBinaryExpr), m_x_up(x), m_y_up(y), m_op(op) {}
+ ~GoASTBinaryExpr() override = default;
- const char *
- GetKindName() const override
- {
- return "BadStmt";
- }
+ const char *GetKindName() const override { return "BinaryExpr"; }
- static bool
- classof(const GoASTNode *n)
- {
- return n->GetKind() == eBadStmt;
- }
-
- GoASTBadStmt(const GoASTBadStmt &) = delete;
- const GoASTBadStmt &operator=(const GoASTBadStmt &) = delete;
-};
+ static bool classof(const GoASTNode *n) {
+ return n->GetKind() == eBinaryExpr;
+ }
-class GoASTBasicLit : public GoASTExpr
-{
- public:
- explicit GoASTBasicLit(Token value) : GoASTExpr(eBasicLit), m_value(value) {}
- ~GoASTBasicLit() override = default;
+ const GoASTExpr *GetX() const { return m_x_up.get(); }
+ void SetX(GoASTExpr *x) { m_x_up.reset(x); }
- const char *
- GetKindName() const override
- {
- return "BasicLit";
- }
+ const GoASTExpr *GetY() const { return m_y_up.get(); }
+ void SetY(GoASTExpr *y) { m_y_up.reset(y); }
- static bool
- classof(const GoASTNode *n)
- {
- return n->GetKind() == eBasicLit;
- }
-
- Token
- GetValue() const
- {
- return m_value;
- }
- void
- SetValue(Token value)
- {
- m_value = value;
- }
+ TokenType GetOp() const { return m_op; }
+ void SetOp(TokenType op) { m_op = op; }
- private:
- friend class GoASTNode;
- Token m_value;
+private:
+ friend class GoASTNode;
+ std::unique_ptr<GoASTExpr> m_x_up;
+ std::unique_ptr<GoASTExpr> m_y_up;
+ TokenType m_op;
- GoASTBasicLit(const GoASTBasicLit &) = delete;
- const GoASTBasicLit &operator=(const GoASTBasicLit &) = delete;
+ GoASTBinaryExpr(const GoASTBinaryExpr &) = delete;
+ const GoASTBinaryExpr &operator=(const GoASTBinaryExpr &) = delete;
};
-class GoASTBinaryExpr : public GoASTExpr
-{
- public:
- GoASTBinaryExpr(GoASTExpr *x, GoASTExpr *y, TokenType op) : GoASTExpr(eBinaryExpr), m_x_up(x), m_y_up(y), m_op(op) {}
- ~GoASTBinaryExpr() override = default;
-
- const char *
- GetKindName() const override
- {
- return "BinaryExpr";
- }
+class GoASTBlockStmt : public GoASTStmt {
+public:
+ GoASTBlockStmt() : GoASTStmt(eBlockStmt) {}
+ ~GoASTBlockStmt() override = default;
- static bool
- classof(const GoASTNode *n)
- {
- return n->GetKind() == eBinaryExpr;
- }
-
- const GoASTExpr *
- GetX() const
- {
- return m_x_up.get();
- }
- void
- SetX(GoASTExpr *x)
- {
- m_x_up.reset(x);
- }
+ const char *GetKindName() const override { return "BlockStmt"; }
- const GoASTExpr *
- GetY() const
- {
- return m_y_up.get();
- }
- void
- SetY(GoASTExpr *y)
- {
- m_y_up.reset(y);
- }
+ static bool classof(const GoASTNode *n) { return n->GetKind() == eBlockStmt; }
- TokenType
- GetOp() const
- {
- return m_op;
- }
- void
- SetOp(TokenType op)
- {
- m_op = op;
- }
+ size_t NumList() const { return m_list.size(); }
+ const GoASTStmt *GetList(int i) const { return m_list[i].get(); }
+ void AddList(GoASTStmt *list) {
+ m_list.push_back(std::unique_ptr<GoASTStmt>(list));
+ }
- private:
- friend class GoASTNode;
- std::unique_ptr<GoASTExpr> m_x_up;
- std::unique_ptr<GoASTExpr> m_y_up;
- TokenType m_op;
+private:
+ friend class GoASTNode;
+ std::vector<std::unique_ptr<GoASTStmt>> m_list;
- GoASTBinaryExpr(const GoASTBinaryExpr &) = delete;
- const GoASTBinaryExpr &operator=(const GoASTBinaryExpr &) = delete;
+ GoASTBlockStmt(const GoASTBlockStmt &) = delete;
+ const GoASTBlockStmt &operator=(const GoASTBlockStmt &) = delete;
};
-class GoASTBlockStmt : public GoASTStmt
-{
- public:
- GoASTBlockStmt() : GoASTStmt(eBlockStmt) {}
- ~GoASTBlockStmt() override = default;
+class GoASTIdent : public GoASTExpr {
+public:
+ explicit GoASTIdent(Token name) : GoASTExpr(eIdent), m_name(name) {}
+ ~GoASTIdent() override = default;
- const char *
- GetKindName() const override
- {
- return "BlockStmt";
- }
+ const char *GetKindName() const override { return "Ident"; }
- static bool
- classof(const GoASTNode *n)
- {
- return n->GetKind() == eBlockStmt;
- }
-
- size_t
- NumList() const
- {
- return m_list.size();
- }
- const GoASTStmt *
- GetList(int i) const
- {
- return m_list[i].get();
- }
- void
- AddList(GoASTStmt *list)
- {
- m_list.push_back(std::unique_ptr<GoASTStmt>(list));
- }
+ static bool classof(const GoASTNode *n) { return n->GetKind() == eIdent; }
- private:
- friend class GoASTNode;
- std::vector<std::unique_ptr<GoASTStmt> > m_list;
+ Token GetName() const { return m_name; }
+ void SetName(Token name) { m_name = name; }
- GoASTBlockStmt(const GoASTBlockStmt &) = delete;
- const GoASTBlockStmt &operator=(const GoASTBlockStmt &) = delete;
+private:
+ friend class GoASTNode;
+ Token m_name;
+
+ GoASTIdent(const GoASTIdent &) = delete;
+ const GoASTIdent &operator=(const GoASTIdent &) = delete;
};
-class GoASTIdent : public GoASTExpr
-{
- public:
- explicit GoASTIdent(Token name) : GoASTExpr(eIdent), m_name(name) {}
- ~GoASTIdent() override = default;
+class GoASTBranchStmt : public GoASTStmt {
+public:
+ GoASTBranchStmt(GoASTIdent *label, TokenType tok)
+ : GoASTStmt(eBranchStmt), m_label_up(label), m_tok(tok) {}
+ ~GoASTBranchStmt() override = default;
- const char *
- GetKindName() const override
- {
- return "Ident";
- }
+ const char *GetKindName() const override { return "BranchStmt"; }
- static bool
- classof(const GoASTNode *n)
- {
- return n->GetKind() == eIdent;
- }
-
- Token
- GetName() const
- {
- return m_name;
- }
- void
- SetName(Token name)
- {
- m_name = name;
- }
+ static bool classof(const GoASTNode *n) {
+ return n->GetKind() == eBranchStmt;
+ }
+
+ const GoASTIdent *GetLabel() const { return m_label_up.get(); }
+ void SetLabel(GoASTIdent *label) { m_label_up.reset(label); }
- private:
- friend class GoASTNode;
- Token m_name;
+ TokenType GetTok() const { return m_tok; }
+ void SetTok(TokenType tok) { m_tok = tok; }
- GoASTIdent(const GoASTIdent &) = delete;
- const GoASTIdent &operator=(const GoASTIdent &) = delete;
+private:
+ friend class GoASTNode;
+ std::unique_ptr<GoASTIdent> m_label_up;
+ TokenType m_tok;
+
+ GoASTBranchStmt(const GoASTBranchStmt &) = delete;
+ const GoASTBranchStmt &operator=(const GoASTBranchStmt &) = delete;
};
-class GoASTBranchStmt : public GoASTStmt
-{
- public:
- GoASTBranchStmt(GoASTIdent *label, TokenType tok) : GoASTStmt(eBranchStmt), m_label_up(label), m_tok(tok) {}
- ~GoASTBranchStmt() override = default;
+class GoASTCallExpr : public GoASTExpr {
+public:
+ explicit GoASTCallExpr(bool ellipsis)
+ : GoASTExpr(eCallExpr), m_ellipsis(ellipsis) {}
+ ~GoASTCallExpr() override = default;
- const char *
- GetKindName() const override
- {
- return "BranchStmt";
- }
+ const char *GetKindName() const override { return "CallExpr"; }
- static bool
- classof(const GoASTNode *n)
- {
- return n->GetKind() == eBranchStmt;
- }
-
- const GoASTIdent *
- GetLabel() const
- {
- return m_label_up.get();
- }
- void
- SetLabel(GoASTIdent *label)
- {
- m_label_up.reset(label);
- }
+ static bool classof(const GoASTNode *n) { return n->GetKind() == eCallExpr; }
- TokenType
- GetTok() const
- {
- return m_tok;
- }
- void
- SetTok(TokenType tok)
- {
- m_tok = tok;
- }
+ const GoASTExpr *GetFun() const { return m_fun_up.get(); }
+ void SetFun(GoASTExpr *fun) { m_fun_up.reset(fun); }
+
+ size_t NumArgs() const { return m_args.size(); }
+ const GoASTExpr *GetArgs(int i) const { return m_args[i].get(); }
+ void AddArgs(GoASTExpr *args) {
+ m_args.push_back(std::unique_ptr<GoASTExpr>(args));
+ }
+
+ bool GetEllipsis() const { return m_ellipsis; }
+ void SetEllipsis(bool ellipsis) { m_ellipsis = ellipsis; }
- private:
- friend class GoASTNode;
- std::unique_ptr<GoASTIdent> m_label_up;
- TokenType m_tok;
+private:
+ friend class GoASTNode;
+ std::unique_ptr<GoASTExpr> m_fun_up;
+ std::vector<std::unique_ptr<GoASTExpr>> m_args;
+ bool m_ellipsis;
- GoASTBranchStmt(const GoASTBranchStmt &) = delete;
- const GoASTBranchStmt &operator=(const GoASTBranchStmt &) = delete;
+ GoASTCallExpr(const GoASTCallExpr &) = delete;
+ const GoASTCallExpr &operator=(const GoASTCallExpr &) = delete;
};
-class GoASTCallExpr : public GoASTExpr
-{
- public:
- explicit GoASTCallExpr(bool ellipsis) : GoASTExpr(eCallExpr), m_ellipsis(ellipsis) {}
- ~GoASTCallExpr() override = default;
+class GoASTCaseClause : public GoASTStmt {
+public:
+ GoASTCaseClause() : GoASTStmt(eCaseClause) {}
+ ~GoASTCaseClause() override = default;
- const char *
- GetKindName() const override
- {
- return "CallExpr";
- }
+ const char *GetKindName() const override { return "CaseClause"; }
- static bool
- classof(const GoASTNode *n)
- {
- return n->GetKind() == eCallExpr;
- }
-
- const GoASTExpr *
- GetFun() const
- {
- return m_fun_up.get();
- }
- void
- SetFun(GoASTExpr *fun)
- {
- m_fun_up.reset(fun);
- }
+ static bool classof(const GoASTNode *n) {
+ return n->GetKind() == eCaseClause;
+ }
- size_t
- NumArgs() const
- {
- return m_args.size();
- }
- const GoASTExpr *
- GetArgs(int i) const
- {
- return m_args[i].get();
- }
- void
- AddArgs(GoASTExpr *args)
- {
- m_args.push_back(std::unique_ptr<GoASTExpr>(args));
- }
+ size_t NumList() const { return m_list.size(); }
+ const GoASTExpr *GetList(int i) const { return m_list[i].get(); }
+ void AddList(GoASTExpr *list) {
+ m_list.push_back(std::unique_ptr<GoASTExpr>(list));
+ }
- bool
- GetEllipsis() const
- {
- return m_ellipsis;
- }
- void
- SetEllipsis(bool ellipsis)
- {
- m_ellipsis = ellipsis;
- }
+ size_t NumBody() const { return m_body.size(); }
+ const GoASTStmt *GetBody(int i) const { return m_body[i].get(); }
+ void AddBody(GoASTStmt *body) {
+ m_body.push_back(std::unique_ptr<GoASTStmt>(body));
+ }
- private:
- friend class GoASTNode;
- std::unique_ptr<GoASTExpr> m_fun_up;
- std::vector<std::unique_ptr<GoASTExpr> > m_args;
- bool m_ellipsis;
+private:
+ friend class GoASTNode;
+ std::vector<std::unique_ptr<GoASTExpr>> m_list;
+ std::vector<std::unique_ptr<GoASTStmt>> m_body;
- GoASTCallExpr(const GoASTCallExpr &) = delete;
- const GoASTCallExpr &operator=(const GoASTCallExpr &) = delete;
+ GoASTCaseClause(const GoASTCaseClause &) = delete;
+ const GoASTCaseClause &operator=(const GoASTCaseClause &) = delete;
};
-class GoASTCaseClause : public GoASTStmt
-{
- public:
- GoASTCaseClause() : GoASTStmt(eCaseClause) {}
- ~GoASTCaseClause() override = default;
+class GoASTChanType : public GoASTExpr {
+public:
+ GoASTChanType(ChanDir dir, GoASTExpr *value)
+ : GoASTExpr(eChanType), m_dir(dir), m_value_up(value) {}
+ ~GoASTChanType() override = default;
- const char *
- GetKindName() const override
- {
- return "CaseClause";
- }
+ const char *GetKindName() const override { return "ChanType"; }
- static bool
- classof(const GoASTNode *n)
- {
- return n->GetKind() == eCaseClause;
- }
-
- size_t
- NumList() const
- {
- return m_list.size();
- }
- const GoASTExpr *
- GetList(int i) const
- {
- return m_list[i].get();
- }
- void
- AddList(GoASTExpr *list)
- {
- m_list.push_back(std::unique_ptr<GoASTExpr>(list));
- }
+ static bool classof(const GoASTNode *n) { return n->GetKind() == eChanType; }
- size_t
- NumBody() const
- {
- return m_body.size();
- }
- const GoASTStmt *
- GetBody(int i) const
- {
- return m_body[i].get();
- }
- void
- AddBody(GoASTStmt *body)
- {
- m_body.push_back(std::unique_ptr<GoASTStmt>(body));
- }
+ ChanDir GetDir() const { return m_dir; }
+ void SetDir(ChanDir dir) { m_dir = dir; }
+
+ const GoASTExpr *GetValue() const { return m_value_up.get(); }
+ void SetValue(GoASTExpr *value) { m_value_up.reset(value); }
- private:
- friend class GoASTNode;
- std::vector<std::unique_ptr<GoASTExpr> > m_list;
- std::vector<std::unique_ptr<GoASTStmt> > m_body;
+private:
+ friend class GoASTNode;
+ ChanDir m_dir;
+ std::unique_ptr<GoASTExpr> m_value_up;
- GoASTCaseClause(const GoASTCaseClause &) = delete;
- const GoASTCaseClause &operator=(const GoASTCaseClause &) = delete;
+ GoASTChanType(const GoASTChanType &) = delete;
+ const GoASTChanType &operator=(const GoASTChanType &) = delete;
};
-class GoASTChanType : public GoASTExpr
-{
- public:
- GoASTChanType(ChanDir dir, GoASTExpr *value) : GoASTExpr(eChanType), m_dir(dir), m_value_up(value) {}
- ~GoASTChanType() override = default;
+class GoASTCommClause : public GoASTStmt {
+public:
+ GoASTCommClause() : GoASTStmt(eCommClause) {}
+ ~GoASTCommClause() override = default;
- const char *
- GetKindName() const override
- {
- return "ChanType";
- }
+ const char *GetKindName() const override { return "CommClause"; }
- static bool
- classof(const GoASTNode *n)
- {
- return n->GetKind() == eChanType;
- }
-
- ChanDir
- GetDir() const
- {
- return m_dir;
- }
- void
- SetDir(ChanDir dir)
- {
- m_dir = dir;
- }
+ static bool classof(const GoASTNode *n) {
+ return n->GetKind() == eCommClause;
+ }
- const GoASTExpr *
- GetValue() const
- {
- return m_value_up.get();
- }
- void
- SetValue(GoASTExpr *value)
- {
- m_value_up.reset(value);
- }
+ const GoASTStmt *GetComm() const { return m_comm_up.get(); }
+ void SetComm(GoASTStmt *comm) { m_comm_up.reset(comm); }
- private:
- friend class GoASTNode;
- ChanDir m_dir;
- std::unique_ptr<GoASTExpr> m_value_up;
+ size_t NumBody() const { return m_body.size(); }
+ const GoASTStmt *GetBody(int i) const { return m_body[i].get(); }
+ void AddBody(GoASTStmt *body) {
+ m_body.push_back(std::unique_ptr<GoASTStmt>(body));
+ }
- GoASTChanType(const GoASTChanType &) = delete;
- const GoASTChanType &operator=(const GoASTChanType &) = delete;
+private:
+ friend class GoASTNode;
+ std::unique_ptr<GoASTStmt> m_comm_up;
+ std::vector<std::unique_ptr<GoASTStmt>> m_body;
+
+ GoASTCommClause(const GoASTCommClause &) = delete;
+ const GoASTCommClause &operator=(const GoASTCommClause &) = delete;
};
-class GoASTCommClause : public GoASTStmt
-{
- public:
- GoASTCommClause() : GoASTStmt(eCommClause) {}
- ~GoASTCommClause() override = default;
+class GoASTCompositeLit : public GoASTExpr {
+public:
+ GoASTCompositeLit() : GoASTExpr(eCompositeLit) {}
+ ~GoASTCompositeLit() override = default;
- const char *
- GetKindName() const override
- {
- return "CommClause";
- }
+ const char *GetKindName() const override { return "CompositeLit"; }
- static bool
- classof(const GoASTNode *n)
- {
- return n->GetKind() == eCommClause;
- }
-
- const GoASTStmt *
- GetComm() const
- {
- return m_comm_up.get();
- }
- void
- SetComm(GoASTStmt *comm)
- {
- m_comm_up.reset(comm);
- }
+ static bool classof(const GoASTNode *n) {
+ return n->GetKind() == eCompositeLit;
+ }
- size_t
- NumBody() const
- {
- return m_body.size();
- }
- const GoASTStmt *
- GetBody(int i) const
- {
- return m_body[i].get();
- }
- void
- AddBody(GoASTStmt *body)
- {
- m_body.push_back(std::unique_ptr<GoASTStmt>(body));
- }
+ const GoASTExpr *GetType() const { return m_type_up.get(); }
+ void SetType(GoASTExpr *type) { m_type_up.reset(type); }
+
+ size_t NumElts() const { return m_elts.size(); }
+ const GoASTExpr *GetElts(int i) const { return m_elts[i].get(); }
+ void AddElts(GoASTExpr *elts) {
+ m_elts.push_back(std::unique_ptr<GoASTExpr>(elts));
+ }
- private:
- friend class GoASTNode;
- std::unique_ptr<GoASTStmt> m_comm_up;
- std::vector<std::unique_ptr<GoASTStmt> > m_body;
+private:
+ friend class GoASTNode;
+ std::unique_ptr<GoASTExpr> m_type_up;
+ std::vector<std::unique_ptr<GoASTExpr>> m_elts;
- GoASTCommClause(const GoASTCommClause &) = delete;
- const GoASTCommClause &operator=(const GoASTCommClause &) = delete;
+ GoASTCompositeLit(const GoASTCompositeLit &) = delete;
+ const GoASTCompositeLit &operator=(const GoASTCompositeLit &) = delete;
};
-class GoASTCompositeLit : public GoASTExpr
-{
- public:
- GoASTCompositeLit() : GoASTExpr(eCompositeLit) {}
- ~GoASTCompositeLit() override = default;
+class GoASTDeclStmt : public GoASTStmt {
+public:
+ explicit GoASTDeclStmt(GoASTDecl *decl)
+ : GoASTStmt(eDeclStmt), m_decl_up(decl) {}
+ ~GoASTDeclStmt() override = default;
- const char *
- GetKindName() const override
- {
- return "CompositeLit";
- }
+ const char *GetKindName() const override { return "DeclStmt"; }
- static bool
- classof(const GoASTNode *n)
- {
- return n->GetKind() == eCompositeLit;
- }
-
- const GoASTExpr *
- GetType() const
- {
- return m_type_up.get();
- }
- void
- SetType(GoASTExpr *type)
- {
- m_type_up.reset(type);
- }
+ static bool classof(const GoASTNode *n) { return n->GetKind() == eDeclStmt; }
- size_t
- NumElts() const
- {
- return m_elts.size();
- }
- const GoASTExpr *
- GetElts(int i) const
- {
- return m_elts[i].get();
- }
- void
- AddElts(GoASTExpr *elts)
- {
- m_elts.push_back(std::unique_ptr<GoASTExpr>(elts));
- }
+ const GoASTDecl *GetDecl() const { return m_decl_up.get(); }
+ void SetDecl(GoASTDecl *decl) { m_decl_up.reset(decl); }
- private:
- friend class GoASTNode;
- std::unique_ptr<GoASTExpr> m_type_up;
- std::vector<std::unique_ptr<GoASTExpr> > m_elts;
+private:
+ friend class GoASTNode;
+ std::unique_ptr<GoASTDecl> m_decl_up;
- GoASTCompositeLit(const GoASTCompositeLit &) = delete;
- const GoASTCompositeLit &operator=(const GoASTCompositeLit &) = delete;
+ GoASTDeclStmt(const GoASTDeclStmt &) = delete;
+ const GoASTDeclStmt &operator=(const GoASTDeclStmt &) = delete;
};
-class GoASTDeclStmt : public GoASTStmt
-{
- public:
- explicit GoASTDeclStmt(GoASTDecl *decl) : GoASTStmt(eDeclStmt), m_decl_up(decl) {}
- ~GoASTDeclStmt() override = default;
+class GoASTDeferStmt : public GoASTStmt {
+public:
+ explicit GoASTDeferStmt(GoASTCallExpr *call)
+ : GoASTStmt(eDeferStmt), m_call_up(call) {}
+ ~GoASTDeferStmt() override = default;
- const char *
- GetKindName() const override
- {
- return "DeclStmt";
- }
+ const char *GetKindName() const override { return "DeferStmt"; }
- static bool
- classof(const GoASTNode *n)
- {
- return n->GetKind() == eDeclStmt;
- }
-
- const GoASTDecl *
- GetDecl() const
- {
- return m_decl_up.get();
- }
- void
- SetDecl(GoASTDecl *decl)
- {
- m_decl_up.reset(decl);
- }
+ static bool classof(const GoASTNode *n) { return n->GetKind() == eDeferStmt; }
+
+ const GoASTCallExpr *GetCall() const { return m_call_up.get(); }
+ void SetCall(GoASTCallExpr *call) { m_call_up.reset(call); }
- private:
- friend class GoASTNode;
- std::unique_ptr<GoASTDecl> m_decl_up;
+private:
+ friend class GoASTNode;
+ std::unique_ptr<GoASTCallExpr> m_call_up;
- GoASTDeclStmt(const GoASTDeclStmt &) = delete;
- const GoASTDeclStmt &operator=(const GoASTDeclStmt &) = delete;
+ GoASTDeferStmt(const GoASTDeferStmt &) = delete;
+ const GoASTDeferStmt &operator=(const GoASTDeferStmt &) = delete;
};
-class GoASTDeferStmt : public GoASTStmt
-{
- public:
- explicit GoASTDeferStmt(GoASTCallExpr *call) : GoASTStmt(eDeferStmt), m_call_up(call) {}
- ~GoASTDeferStmt() override = default;
+class GoASTEllipsis : public GoASTExpr {
+public:
+ explicit GoASTEllipsis(GoASTExpr *elt)
+ : GoASTExpr(eEllipsis), m_elt_up(elt) {}
+ ~GoASTEllipsis() override = default;
- const char *
- GetKindName() const override
- {
- return "DeferStmt";
- }
+ const char *GetKindName() const override { return "Ellipsis"; }
- static bool
- classof(const GoASTNode *n)
- {
- return n->GetKind() == eDeferStmt;
- }
-
- const GoASTCallExpr *
- GetCall() const
- {
- return m_call_up.get();
- }
- void
- SetCall(GoASTCallExpr *call)
- {
- m_call_up.reset(call);
- }
+ static bool classof(const GoASTNode *n) { return n->GetKind() == eEllipsis; }
- private:
- friend class GoASTNode;
- std::unique_ptr<GoASTCallExpr> m_call_up;
+ const GoASTExpr *GetElt() const { return m_elt_up.get(); }
+ void SetElt(GoASTExpr *elt) { m_elt_up.reset(elt); }
- GoASTDeferStmt(const GoASTDeferStmt &) = delete;
- const GoASTDeferStmt &operator=(const GoASTDeferStmt &) = delete;
-};
+private:
+ friend class GoASTNode;
+ std::unique_ptr<GoASTExpr> m_elt_up;
-class GoASTEllipsis : public GoASTExpr
-{
- public:
- explicit GoASTEllipsis(GoASTExpr *elt) : GoASTExpr(eEllipsis), m_elt_up(elt) {}
- ~GoASTEllipsis() override = default;
+ GoASTEllipsis(const GoASTEllipsis &) = delete;
+ const GoASTEllipsis &operator=(const GoASTEllipsis &) = delete;
+};
- const char *
- GetKindName() const override
- {
- return "Ellipsis";
- }
+class GoASTEmptyStmt : public GoASTStmt {
+public:
+ GoASTEmptyStmt() : GoASTStmt(eEmptyStmt) {}
+ ~GoASTEmptyStmt() override = default;
- static bool
- classof(const GoASTNode *n)
- {
- return n->GetKind() == eEllipsis;
- }
-
- const GoASTExpr *
- GetElt() const
- {
- return m_elt_up.get();
- }
- void
- SetElt(GoASTExpr *elt)
- {
- m_elt_up.reset(elt);
- }
+ const char *GetKindName() const override { return "EmptyStmt"; }
- private:
- friend class GoASTNode;
- std::unique_ptr<GoASTExpr> m_elt_up;
+ static bool classof(const GoASTNode *n) { return n->GetKind() == eEmptyStmt; }
- GoASTEllipsis(const GoASTEllipsis &) = delete;
- const GoASTEllipsis &operator=(const GoASTEllipsis &) = delete;
+ GoASTEmptyStmt(const GoASTEmptyStmt &) = delete;
+ const GoASTEmptyStmt &operator=(const GoASTEmptyStmt &) = delete;
};
-class GoASTEmptyStmt : public GoASTStmt
-{
- public:
- GoASTEmptyStmt() : GoASTStmt(eEmptyStmt) {}
- ~GoASTEmptyStmt() override = default;
-
- const char *
- GetKindName() const override
- {
- return "EmptyStmt";
- }
-
- static bool
- classof(const GoASTNode *n)
- {
- return n->GetKind() == eEmptyStmt;
- }
-
- GoASTEmptyStmt(const GoASTEmptyStmt &) = delete;
- const GoASTEmptyStmt &operator=(const GoASTEmptyStmt &) = delete;
-};
+class GoASTExprStmt : public GoASTStmt {
+public:
+ explicit GoASTExprStmt(GoASTExpr *x) : GoASTStmt(eExprStmt), m_x_up(x) {}
+ ~GoASTExprStmt() override = default;
-class GoASTExprStmt : public GoASTStmt
-{
- public:
- explicit GoASTExprStmt(GoASTExpr *x) : GoASTStmt(eExprStmt), m_x_up(x) {}
- ~GoASTExprStmt() override = default;
+ const char *GetKindName() const override { return "ExprStmt"; }
- const char *
- GetKindName() const override
- {
- return "ExprStmt";
- }
+ static bool classof(const GoASTNode *n) { return n->GetKind() == eExprStmt; }
- static bool
- classof(const GoASTNode *n)
- {
- return n->GetKind() == eExprStmt;
- }
-
- const GoASTExpr *
- GetX() const
- {
- return m_x_up.get();
- }
- void
- SetX(GoASTExpr *x)
- {
- m_x_up.reset(x);
- }
+ const GoASTExpr *GetX() const { return m_x_up.get(); }
+ void SetX(GoASTExpr *x) { m_x_up.reset(x); }
- private:
- friend class GoASTNode;
- std::unique_ptr<GoASTExpr> m_x_up;
+private:
+ friend class GoASTNode;
+ std::unique_ptr<GoASTExpr> m_x_up;
- GoASTExprStmt(const GoASTExprStmt &) = delete;
- const GoASTExprStmt &operator=(const GoASTExprStmt &) = delete;
+ GoASTExprStmt(const GoASTExprStmt &) = delete;
+ const GoASTExprStmt &operator=(const GoASTExprStmt &) = delete;
};
-class GoASTField : public GoASTNode
-{
- public:
- GoASTField() : GoASTNode(eField) {}
- ~GoASTField() override = default;
+class GoASTField : public GoASTNode {
+public:
+ GoASTField() : GoASTNode(eField) {}
+ ~GoASTField() override = default;
- const char *
- GetKindName() const override
- {
- return "Field";
- }
+ const char *GetKindName() const override { return "Field"; }
- static bool
- classof(const GoASTNode *n)
- {
- return n->GetKind() == eField;
- }
-
- size_t
- NumNames() const
- {
- return m_names.size();
- }
- const GoASTIdent *
- GetNames(int i) const
- {
- return m_names[i].get();
- }
- void
- AddNames(GoASTIdent *names)
- {
- m_names.push_back(std::unique_ptr<GoASTIdent>(names));
- }
+ static bool classof(const GoASTNode *n) { return n->GetKind() == eField; }
- const GoASTExpr *
- GetType() const
- {
- return m_type_up.get();
- }
- void
- SetType(GoASTExpr *type)
- {
- m_type_up.reset(type);
- }
+ size_t NumNames() const { return m_names.size(); }
+ const GoASTIdent *GetNames(int i) const { return m_names[i].get(); }
+ void AddNames(GoASTIdent *names) {
+ m_names.push_back(std::unique_ptr<GoASTIdent>(names));
+ }
- const GoASTBasicLit *
- GetTag() const
- {
- return m_tag_up.get();
- }
- void
- SetTag(GoASTBasicLit *tag)
- {
- m_tag_up.reset(tag);
- }
+ const GoASTExpr *GetType() const { return m_type_up.get(); }
+ void SetType(GoASTExpr *type) { m_type_up.reset(type); }
+
+ const GoASTBasicLit *GetTag() const { return m_tag_up.get(); }
+ void SetTag(GoASTBasicLit *tag) { m_tag_up.reset(tag); }
- private:
- friend class GoASTNode;
- std::vector<std::unique_ptr<GoASTIdent> > m_names;
- std::unique_ptr<GoASTExpr> m_type_up;
- std::unique_ptr<GoASTBasicLit> m_tag_up;
+private:
+ friend class GoASTNode;
+ std::vector<std::unique_ptr<GoASTIdent>> m_names;
+ std::unique_ptr<GoASTExpr> m_type_up;
+ std::unique_ptr<GoASTBasicLit> m_tag_up;
- GoASTField(const GoASTField &) = delete;
- const GoASTField &operator=(const GoASTField &) = delete;
+ GoASTField(const GoASTField &) = delete;
+ const GoASTField &operator=(const GoASTField &) = delete;
};
-class GoASTFieldList : public GoASTNode
-{
- public:
- GoASTFieldList() : GoASTNode(eFieldList) {}
- ~GoASTFieldList() override = default;
+class GoASTFieldList : public GoASTNode {
+public:
+ GoASTFieldList() : GoASTNode(eFieldList) {}
+ ~GoASTFieldList() override = default;
- const char *
- GetKindName() const override
- {
- return "FieldList";
- }
+ const char *GetKindName() const override { return "FieldList"; }
- static bool
- classof(const GoASTNode *n)
- {
- return n->GetKind() == eFieldList;
- }
-
- size_t
- NumList() const
- {
- return m_list.size();
- }
- const GoASTField *
- GetList(int i) const
- {
- return m_list[i].get();
- }
- void
- AddList(GoASTField *list)
- {
- m_list.push_back(std::unique_ptr<GoASTField>(list));
- }
+ static bool classof(const GoASTNode *n) { return n->GetKind() == eFieldList; }
+
+ size_t NumList() const { return m_list.size(); }
+ const GoASTField *GetList(int i) const { return m_list[i].get(); }
+ void AddList(GoASTField *list) {
+ m_list.push_back(std::unique_ptr<GoASTField>(list));
+ }
- private:
- friend class GoASTNode;
- std::vector<std::unique_ptr<GoASTField> > m_list;
+private:
+ friend class GoASTNode;
+ std::vector<std::unique_ptr<GoASTField>> m_list;
- GoASTFieldList(const GoASTFieldList &) = delete;
- const GoASTFieldList &operator=(const GoASTFieldList &) = delete;
+ GoASTFieldList(const GoASTFieldList &) = delete;
+ const GoASTFieldList &operator=(const GoASTFieldList &) = delete;
};
-class GoASTForStmt : public GoASTStmt
-{
- public:
- GoASTForStmt(GoASTStmt *init, GoASTExpr *cond, GoASTStmt *post, GoASTBlockStmt *body) : GoASTStmt(eForStmt), m_init_up(init), m_cond_up(cond), m_post_up(post), m_body_up(body) {}
- ~GoASTForStmt() override = default;
+class GoASTForStmt : public GoASTStmt {
+public:
+ GoASTForStmt(GoASTStmt *init, GoASTExpr *cond, GoASTStmt *post,
+ GoASTBlockStmt *body)
+ : GoASTStmt(eForStmt), m_init_up(init), m_cond_up(cond), m_post_up(post),
+ m_body_up(body) {}
+ ~GoASTForStmt() override = default;
- const char *
- GetKindName() const override
- {
- return "ForStmt";
- }
+ const char *GetKindName() const override { return "ForStmt"; }
- static bool
- classof(const GoASTNode *n)
- {
- return n->GetKind() == eForStmt;
- }
-
- const GoASTStmt *
- GetInit() const
- {
- return m_init_up.get();
- }
- void
- SetInit(GoASTStmt *init)
- {
- m_init_up.reset(init);
- }
+ static bool classof(const GoASTNode *n) { return n->GetKind() == eForStmt; }
- const GoASTExpr *
- GetCond() const
- {
- return m_cond_up.get();
- }
- void
- SetCond(GoASTExpr *cond)
- {
- m_cond_up.reset(cond);
- }
+ const GoASTStmt *GetInit() const { return m_init_up.get(); }
+ void SetInit(GoASTStmt *init) { m_init_up.reset(init); }
- const GoASTStmt *
- GetPost() const
- {
- return m_post_up.get();
- }
- void
- SetPost(GoASTStmt *post)
- {
- m_post_up.reset(post);
- }
+ const GoASTExpr *GetCond() const { return m_cond_up.get(); }
+ void SetCond(GoASTExpr *cond) { m_cond_up.reset(cond); }
- const GoASTBlockStmt *
- GetBody() const
- {
- return m_body_up.get();
- }
- void
- SetBody(GoASTBlockStmt *body)
- {
- m_body_up.reset(body);
- }
+ const GoASTStmt *GetPost() const { return m_post_up.get(); }
+ void SetPost(GoASTStmt *post) { m_post_up.reset(post); }
- private:
- friend class GoASTNode;
- std::unique_ptr<GoASTStmt> m_init_up;
- std::unique_ptr<GoASTExpr> m_cond_up;
- std::unique_ptr<GoASTStmt> m_post_up;
- std::unique_ptr<GoASTBlockStmt> m_body_up;
+ const GoASTBlockStmt *GetBody() const { return m_body_up.get(); }
+ void SetBody(GoASTBlockStmt *body) { m_body_up.reset(body); }
- GoASTForStmt(const GoASTForStmt &) = delete;
- const GoASTForStmt &operator=(const GoASTForStmt &) = delete;
+private:
+ friend class GoASTNode;
+ std::unique_ptr<GoASTStmt> m_init_up;
+ std::unique_ptr<GoASTExpr> m_cond_up;
+ std::unique_ptr<GoASTStmt> m_post_up;
+ std::unique_ptr<GoASTBlockStmt> m_body_up;
+
+ GoASTForStmt(const GoASTForStmt &) = delete;
+ const GoASTForStmt &operator=(const GoASTForStmt &) = delete;
};
-class GoASTFuncType : public GoASTExpr
-{
- public:
- GoASTFuncType(GoASTFieldList *params, GoASTFieldList *results) : GoASTExpr(eFuncType), m_params_up(params), m_results_up(results) {}
- ~GoASTFuncType() override = default;
+class GoASTFuncType : public GoASTExpr {
+public:
+ GoASTFuncType(GoASTFieldList *params, GoASTFieldList *results)
+ : GoASTExpr(eFuncType), m_params_up(params), m_results_up(results) {}
+ ~GoASTFuncType() override = default;
- const char *
- GetKindName() const override
- {
- return "FuncType";
- }
+ const char *GetKindName() const override { return "FuncType"; }
- static bool
- classof(const GoASTNode *n)
- {
- return n->GetKind() == eFuncType;
- }
-
- const GoASTFieldList *
- GetParams() const
- {
- return m_params_up.get();
- }
- void
- SetParams(GoASTFieldList *params)
- {
- m_params_up.reset(params);
- }
+ static bool classof(const GoASTNode *n) { return n->GetKind() == eFuncType; }
- const GoASTFieldList *
- GetResults() const
- {
- return m_results_up.get();
- }
- void
- SetResults(GoASTFieldList *results)
- {
- m_results_up.reset(results);
- }
+ const GoASTFieldList *GetParams() const { return m_params_up.get(); }
+ void SetParams(GoASTFieldList *params) { m_params_up.reset(params); }
+
+ const GoASTFieldList *GetResults() const { return m_results_up.get(); }
+ void SetResults(GoASTFieldList *results) { m_results_up.reset(results); }
- private:
- friend class GoASTNode;
- std::unique_ptr<GoASTFieldList> m_params_up;
- std::unique_ptr<GoASTFieldList> m_results_up;
+private:
+ friend class GoASTNode;
+ std::unique_ptr<GoASTFieldList> m_params_up;
+ std::unique_ptr<GoASTFieldList> m_results_up;
- GoASTFuncType(const GoASTFuncType &) = delete;
- const GoASTFuncType &operator=(const GoASTFuncType &) = delete;
+ GoASTFuncType(const GoASTFuncType &) = delete;
+ const GoASTFuncType &operator=(const GoASTFuncType &) = delete;
};
-class GoASTFuncDecl : public GoASTDecl
-{
- public:
- GoASTFuncDecl(GoASTFieldList *recv, GoASTIdent *name, GoASTFuncType *type, GoASTBlockStmt *body) : GoASTDecl(eFuncDecl), m_recv_up(recv), m_name_up(name), m_type_up(type), m_body_up(body) {}
- ~GoASTFuncDecl() override = default;
+class GoASTFuncDecl : public GoASTDecl {
+public:
+ GoASTFuncDecl(GoASTFieldList *recv, GoASTIdent *name, GoASTFuncType *type,
+ GoASTBlockStmt *body)
+ : GoASTDecl(eFuncDecl), m_recv_up(recv), m_name_up(name), m_type_up(type),
+ m_body_up(body) {}
+ ~GoASTFuncDecl() override = default;
- const char *
- GetKindName() const override
- {
- return "FuncDecl";
- }
+ const char *GetKindName() const override { return "FuncDecl"; }
- static bool
- classof(const GoASTNode *n)
- {
- return n->GetKind() == eFuncDecl;
- }
-
- const GoASTFieldList *
- GetRecv() const
- {
- return m_recv_up.get();
- }
- void
- SetRecv(GoASTFieldList *recv)
- {
- m_recv_up.reset(recv);
- }
+ static bool classof(const GoASTNode *n) { return n->GetKind() == eFuncDecl; }
- const GoASTIdent *
- GetName() const
- {
- return m_name_up.get();
- }
- void
- SetName(GoASTIdent *name)
- {
- m_name_up.reset(name);
- }
+ const GoASTFieldList *GetRecv() const { return m_recv_up.get(); }
+ void SetRecv(GoASTFieldList *recv) { m_recv_up.reset(recv); }
- const GoASTFuncType *
- GetType() const
- {
- return m_type_up.get();
- }
- void
- SetType(GoASTFuncType *type)
- {
- m_type_up.reset(type);
- }
+ const GoASTIdent *GetName() const { return m_name_up.get(); }
+ void SetName(GoASTIdent *name) { m_name_up.reset(name); }
- const GoASTBlockStmt *
- GetBody() const
- {
- return m_body_up.get();
- }
- void
- SetBody(GoASTBlockStmt *body)
- {
- m_body_up.reset(body);
- }
+ const GoASTFuncType *GetType() const { return m_type_up.get(); }
+ void SetType(GoASTFuncType *type) { m_type_up.reset(type); }
- private:
- friend class GoASTNode;
- std::unique_ptr<GoASTFieldList> m_recv_up;
- std::unique_ptr<GoASTIdent> m_name_up;
- std::unique_ptr<GoASTFuncType> m_type_up;
- std::unique_ptr<GoASTBlockStmt> m_body_up;
+ const GoASTBlockStmt *GetBody() const { return m_body_up.get(); }
+ void SetBody(GoASTBlockStmt *body) { m_body_up.reset(body); }
- GoASTFuncDecl(const GoASTFuncDecl &) = delete;
- const GoASTFuncDecl &operator=(const GoASTFuncDecl &) = delete;
+private:
+ friend class GoASTNode;
+ std::unique_ptr<GoASTFieldList> m_recv_up;
+ std::unique_ptr<GoASTIdent> m_name_up;
+ std::unique_ptr<GoASTFuncType> m_type_up;
+ std::unique_ptr<GoASTBlockStmt> m_body_up;
+
+ GoASTFuncDecl(const GoASTFuncDecl &) = delete;
+ const GoASTFuncDecl &operator=(const GoASTFuncDecl &) = delete;
};
-class GoASTFuncLit : public GoASTExpr
-{
- public:
- GoASTFuncLit(GoASTFuncType *type, GoASTBlockStmt *body) : GoASTExpr(eFuncLit), m_type_up(type), m_body_up(body) {}
- ~GoASTFuncLit() override = default;
+class GoASTFuncLit : public GoASTExpr {
+public:
+ GoASTFuncLit(GoASTFuncType *type, GoASTBlockStmt *body)
+ : GoASTExpr(eFuncLit), m_type_up(type), m_body_up(body) {}
+ ~GoASTFuncLit() override = default;
- const char *
- GetKindName() const override
- {
- return "FuncLit";
- }
+ const char *GetKindName() const override { return "FuncLit"; }
- static bool
- classof(const GoASTNode *n)
- {
- return n->GetKind() == eFuncLit;
- }
-
- const GoASTFuncType *
- GetType() const
- {
- return m_type_up.get();
- }
- void
- SetType(GoASTFuncType *type)
- {
- m_type_up.reset(type);
- }
+ static bool classof(const GoASTNode *n) { return n->GetKind() == eFuncLit; }
- const GoASTBlockStmt *
- GetBody() const
- {
- return m_body_up.get();
- }
- void
- SetBody(GoASTBlockStmt *body)
- {
- m_body_up.reset(body);
- }
+ const GoASTFuncType *GetType() const { return m_type_up.get(); }
+ void SetType(GoASTFuncType *type) { m_type_up.reset(type); }
+
+ const GoASTBlockStmt *GetBody() const { return m_body_up.get(); }
+ void SetBody(GoASTBlockStmt *body) { m_body_up.reset(body); }
- private:
- friend class GoASTNode;
- std::unique_ptr<GoASTFuncType> m_type_up;
- std::unique_ptr<GoASTBlockStmt> m_body_up;
+private:
+ friend class GoASTNode;
+ std::unique_ptr<GoASTFuncType> m_type_up;
+ std::unique_ptr<GoASTBlockStmt> m_body_up;
- GoASTFuncLit(const GoASTFuncLit &) = delete;
- const GoASTFuncLit &operator=(const GoASTFuncLit &) = delete;
+ GoASTFuncLit(const GoASTFuncLit &) = delete;
+ const GoASTFuncLit &operator=(const GoASTFuncLit &) = delete;
};
-class GoASTGenDecl : public GoASTDecl
-{
- public:
- explicit GoASTGenDecl(TokenType tok) : GoASTDecl(eGenDecl), m_tok(tok) {}
- ~GoASTGenDecl() override = default;
+class GoASTGenDecl : public GoASTDecl {
+public:
+ explicit GoASTGenDecl(TokenType tok) : GoASTDecl(eGenDecl), m_tok(tok) {}
+ ~GoASTGenDecl() override = default;
- const char *
- GetKindName() const override
- {
- return "GenDecl";
- }
+ const char *GetKindName() const override { return "GenDecl"; }
- static bool
- classof(const GoASTNode *n)
- {
- return n->GetKind() == eGenDecl;
- }
-
- TokenType
- GetTok() const
- {
- return m_tok;
- }
- void
- SetTok(TokenType tok)
- {
- m_tok = tok;
- }
+ static bool classof(const GoASTNode *n) { return n->GetKind() == eGenDecl; }
- size_t
- NumSpecs() const
- {
- return m_specs.size();
- }
- const GoASTSpec *
- GetSpecs(int i) const
- {
- return m_specs[i].get();
- }
- void
- AddSpecs(GoASTSpec *specs)
- {
- m_specs.push_back(std::unique_ptr<GoASTSpec>(specs));
- }
+ TokenType GetTok() const { return m_tok; }
+ void SetTok(TokenType tok) { m_tok = tok; }
+
+ size_t NumSpecs() const { return m_specs.size(); }
+ const GoASTSpec *GetSpecs(int i) const { return m_specs[i].get(); }
+ void AddSpecs(GoASTSpec *specs) {
+ m_specs.push_back(std::unique_ptr<GoASTSpec>(specs));
+ }
- private:
- friend class GoASTNode;
- TokenType m_tok;
- std::vector<std::unique_ptr<GoASTSpec> > m_specs;
+private:
+ friend class GoASTNode;
+ TokenType m_tok;
+ std::vector<std::unique_ptr<GoASTSpec>> m_specs;
- GoASTGenDecl(const GoASTGenDecl &) = delete;
- const GoASTGenDecl &operator=(const GoASTGenDecl &) = delete;
+ GoASTGenDecl(const GoASTGenDecl &) = delete;
+ const GoASTGenDecl &operator=(const GoASTGenDecl &) = delete;
};
-class GoASTGoStmt : public GoASTStmt
-{
- public:
- explicit GoASTGoStmt(GoASTCallExpr *call) : GoASTStmt(eGoStmt), m_call_up(call) {}
- ~GoASTGoStmt() override = default;
+class GoASTGoStmt : public GoASTStmt {
+public:
+ explicit GoASTGoStmt(GoASTCallExpr *call)
+ : GoASTStmt(eGoStmt), m_call_up(call) {}
+ ~GoASTGoStmt() override = default;
- const char *
- GetKindName() const override
- {
- return "GoStmt";
- }
+ const char *GetKindName() const override { return "GoStmt"; }
- static bool
- classof(const GoASTNode *n)
- {
- return n->GetKind() == eGoStmt;
- }
-
- const GoASTCallExpr *
- GetCall() const
- {
- return m_call_up.get();
- }
- void
- SetCall(GoASTCallExpr *call)
- {
- m_call_up.reset(call);
- }
+ static bool classof(const GoASTNode *n) { return n->GetKind() == eGoStmt; }
- private:
- friend class GoASTNode;
- std::unique_ptr<GoASTCallExpr> m_call_up;
+ const GoASTCallExpr *GetCall() const { return m_call_up.get(); }
+ void SetCall(GoASTCallExpr *call) { m_call_up.reset(call); }
- GoASTGoStmt(const GoASTGoStmt &) = delete;
- const GoASTGoStmt &operator=(const GoASTGoStmt &) = delete;
+private:
+ friend class GoASTNode;
+ std::unique_ptr<GoASTCallExpr> m_call_up;
+
+ GoASTGoStmt(const GoASTGoStmt &) = delete;
+ const GoASTGoStmt &operator=(const GoASTGoStmt &) = delete;
};
-class GoASTIfStmt : public GoASTStmt
-{
- public:
- GoASTIfStmt(GoASTStmt *init, GoASTExpr *cond, GoASTBlockStmt *body, GoASTStmt *els) : GoASTStmt(eIfStmt), m_init_up(init), m_cond_up(cond), m_body_up(body), m_els_up(els) {}
- ~GoASTIfStmt() override = default;
+class GoASTIfStmt : public GoASTStmt {
+public:
+ GoASTIfStmt(GoASTStmt *init, GoASTExpr *cond, GoASTBlockStmt *body,
+ GoASTStmt *els)
+ : GoASTStmt(eIfStmt), m_init_up(init), m_cond_up(cond), m_body_up(body),
+ m_els_up(els) {}
+ ~GoASTIfStmt() override = default;
- const char *
- GetKindName() const override
- {
- return "IfStmt";
- }
+ const char *GetKindName() const override { return "IfStmt"; }
- static bool
- classof(const GoASTNode *n)
- {
- return n->GetKind() == eIfStmt;
- }
-
- const GoASTStmt *
- GetInit() const
- {
- return m_init_up.get();
- }
- void
- SetInit(GoASTStmt *init)
- {
- m_init_up.reset(init);
- }
+ static bool classof(const GoASTNode *n) { return n->GetKind() == eIfStmt; }
- const GoASTExpr *
- GetCond() const
- {
- return m_cond_up.get();
- }
- void
- SetCond(GoASTExpr *cond)
- {
- m_cond_up.reset(cond);
- }
+ const GoASTStmt *GetInit() const { return m_init_up.get(); }
+ void SetInit(GoASTStmt *init) { m_init_up.reset(init); }
- const GoASTBlockStmt *
- GetBody() const
- {
- return m_body_up.get();
- }
- void
- SetBody(GoASTBlockStmt *body)
- {
- m_body_up.reset(body);
- }
+ const GoASTExpr *GetCond() const { return m_cond_up.get(); }
+ void SetCond(GoASTExpr *cond) { m_cond_up.reset(cond); }
- const GoASTStmt *
- GetEls() const
- {
- return m_els_up.get();
- }
- void
- SetEls(GoASTStmt *els)
- {
- m_els_up.reset(els);
- }
+ const GoASTBlockStmt *GetBody() const { return m_body_up.get(); }
+ void SetBody(GoASTBlockStmt *body) { m_body_up.reset(body); }
+
+ const GoASTStmt *GetEls() const { return m_els_up.get(); }
+ void SetEls(GoASTStmt *els) { m_els_up.reset(els); }
- private:
- friend class GoASTNode;
- std::unique_ptr<GoASTStmt> m_init_up;
- std::unique_ptr<GoASTExpr> m_cond_up;
- std::unique_ptr<GoASTBlockStmt> m_body_up;
- std::unique_ptr<GoASTStmt> m_els_up;
+private:
+ friend class GoASTNode;
+ std::unique_ptr<GoASTStmt> m_init_up;
+ std::unique_ptr<GoASTExpr> m_cond_up;
+ std::unique_ptr<GoASTBlockStmt> m_body_up;
+ std::unique_ptr<GoASTStmt> m_els_up;
- GoASTIfStmt(const GoASTIfStmt &) = delete;
- const GoASTIfStmt &operator=(const GoASTIfStmt &) = delete;
+ GoASTIfStmt(const GoASTIfStmt &) = delete;
+ const GoASTIfStmt &operator=(const GoASTIfStmt &) = delete;
};
-class GoASTImportSpec : public GoASTSpec
-{
- public:
- GoASTImportSpec(GoASTIdent *name, GoASTBasicLit *path) : GoASTSpec(eImportSpec), m_name_up(name), m_path_up(path) {}
- ~GoASTImportSpec() override = default;
+class GoASTImportSpec : public GoASTSpec {
+public:
+ GoASTImportSpec(GoASTIdent *name, GoASTBasicLit *path)
+ : GoASTSpec(eImportSpec), m_name_up(name), m_path_up(path) {}
+ ~GoASTImportSpec() override = default;
- const char *
- GetKindName() const override
- {
- return "ImportSpec";
- }
+ const char *GetKindName() const override { return "ImportSpec"; }
- static bool
- classof(const GoASTNode *n)
- {
- return n->GetKind() == eImportSpec;
- }
-
- const GoASTIdent *
- GetName() const
- {
- return m_name_up.get();
- }
- void
- SetName(GoASTIdent *name)
- {
- m_name_up.reset(name);
- }
+ static bool classof(const GoASTNode *n) {
+ return n->GetKind() == eImportSpec;
+ }
- const GoASTBasicLit *
- GetPath() const
- {
- return m_path_up.get();
- }
- void
- SetPath(GoASTBasicLit *path)
- {
- m_path_up.reset(path);
- }
+ const GoASTIdent *GetName() const { return m_name_up.get(); }
+ void SetName(GoASTIdent *name) { m_name_up.reset(name); }
- private:
- friend class GoASTNode;
- std::unique_ptr<GoASTIdent> m_name_up;
- std::unique_ptr<GoASTBasicLit> m_path_up;
+ const GoASTBasicLit *GetPath() const { return m_path_up.get(); }
+ void SetPath(GoASTBasicLit *path) { m_path_up.reset(path); }
- GoASTImportSpec(const GoASTImportSpec &) = delete;
- const GoASTImportSpec &operator=(const GoASTImportSpec &) = delete;
+private:
+ friend class GoASTNode;
+ std::unique_ptr<GoASTIdent> m_name_up;
+ std::unique_ptr<GoASTBasicLit> m_path_up;
+
+ GoASTImportSpec(const GoASTImportSpec &) = delete;
+ const GoASTImportSpec &operator=(const GoASTImportSpec &) = delete;
};
-class GoASTIncDecStmt : public GoASTStmt
-{
- public:
- GoASTIncDecStmt(GoASTExpr *x, TokenType tok) : GoASTStmt(eIncDecStmt), m_x_up(x), m_tok(tok) {}
- ~GoASTIncDecStmt() override = default;
+class GoASTIncDecStmt : public GoASTStmt {
+public:
+ GoASTIncDecStmt(GoASTExpr *x, TokenType tok)
+ : GoASTStmt(eIncDecStmt), m_x_up(x), m_tok(tok) {}
+ ~GoASTIncDecStmt() override = default;
- const char *
- GetKindName() const override
- {
- return "IncDecStmt";
- }
+ const char *GetKindName() const override { return "IncDecStmt"; }
- static bool
- classof(const GoASTNode *n)
- {
- return n->GetKind() == eIncDecStmt;
- }
-
- const GoASTExpr *
- GetX() const
- {
- return m_x_up.get();
- }
- void
- SetX(GoASTExpr *x)
- {
- m_x_up.reset(x);
- }
+ static bool classof(const GoASTNode *n) {
+ return n->GetKind() == eIncDecStmt;
+ }
- TokenType
- GetTok() const
- {
- return m_tok;
- }
- void
- SetTok(TokenType tok)
- {
- m_tok = tok;
- }
+ const GoASTExpr *GetX() const { return m_x_up.get(); }
+ void SetX(GoASTExpr *x) { m_x_up.reset(x); }
+
+ TokenType GetTok() const { return m_tok; }
+ void SetTok(TokenType tok) { m_tok = tok; }
- private:
- friend class GoASTNode;
- std::unique_ptr<GoASTExpr> m_x_up;
- TokenType m_tok;
+private:
+ friend class GoASTNode;
+ std::unique_ptr<GoASTExpr> m_x_up;
+ TokenType m_tok;
- GoASTIncDecStmt(const GoASTIncDecStmt &) = delete;
- const GoASTIncDecStmt &operator=(const GoASTIncDecStmt &) = delete;
+ GoASTIncDecStmt(const GoASTIncDecStmt &) = delete;
+ const GoASTIncDecStmt &operator=(const GoASTIncDecStmt &) = delete;
};
-class GoASTIndexExpr : public GoASTExpr
-{
- public:
- GoASTIndexExpr(GoASTExpr *x, GoASTExpr *index) : GoASTExpr(eIndexExpr), m_x_up(x), m_index_up(index) {}
- ~GoASTIndexExpr() override = default;
+class GoASTIndexExpr : public GoASTExpr {
+public:
+ GoASTIndexExpr(GoASTExpr *x, GoASTExpr *index)
+ : GoASTExpr(eIndexExpr), m_x_up(x), m_index_up(index) {}
+ ~GoASTIndexExpr() override = default;
- const char *
- GetKindName() const override
- {
- return "IndexExpr";
- }
+ const char *GetKindName() const override { return "IndexExpr"; }
- static bool
- classof(const GoASTNode *n)
- {
- return n->GetKind() == eIndexExpr;
- }
-
- const GoASTExpr *
- GetX() const
- {
- return m_x_up.get();
- }
- void
- SetX(GoASTExpr *x)
- {
- m_x_up.reset(x);
- }
+ static bool classof(const GoASTNode *n) { return n->GetKind() == eIndexExpr; }
- const GoASTExpr *
- GetIndex() const
- {
- return m_index_up.get();
- }
- void
- SetIndex(GoASTExpr *index)
- {
- m_index_up.reset(index);
- }
+ const GoASTExpr *GetX() const { return m_x_up.get(); }
+ void SetX(GoASTExpr *x) { m_x_up.reset(x); }
+
+ const GoASTExpr *GetIndex() const { return m_index_up.get(); }
+ void SetIndex(GoASTExpr *index) { m_index_up.reset(index); }
- private:
- friend class GoASTNode;
- std::unique_ptr<GoASTExpr> m_x_up;
- std::unique_ptr<GoASTExpr> m_index_up;
+private:
+ friend class GoASTNode;
+ std::unique_ptr<GoASTExpr> m_x_up;
+ std::unique_ptr<GoASTExpr> m_index_up;
- GoASTIndexExpr(const GoASTIndexExpr &) = delete;
- const GoASTIndexExpr &operator=(const GoASTIndexExpr &) = delete;
+ GoASTIndexExpr(const GoASTIndexExpr &) = delete;
+ const GoASTIndexExpr &operator=(const GoASTIndexExpr &) = delete;
};
-class GoASTInterfaceType : public GoASTExpr
-{
- public:
- explicit GoASTInterfaceType(GoASTFieldList *methods) : GoASTExpr(eInterfaceType), m_methods_up(methods) {}
- ~GoASTInterfaceType() override = default;
+class GoASTInterfaceType : public GoASTExpr {
+public:
+ explicit GoASTInterfaceType(GoASTFieldList *methods)
+ : GoASTExpr(eInterfaceType), m_methods_up(methods) {}
+ ~GoASTInterfaceType() override = default;
- const char *
- GetKindName() const override
- {
- return "InterfaceType";
- }
+ const char *GetKindName() const override { return "InterfaceType"; }
- static bool
- classof(const GoASTNode *n)
- {
- return n->GetKind() == eInterfaceType;
- }
-
- const GoASTFieldList *
- GetMethods() const
- {
- return m_methods_up.get();
- }
- void
- SetMethods(GoASTFieldList *methods)
- {
- m_methods_up.reset(methods);
- }
+ static bool classof(const GoASTNode *n) {
+ return n->GetKind() == eInterfaceType;
+ }
+
+ const GoASTFieldList *GetMethods() const { return m_methods_up.get(); }
+ void SetMethods(GoASTFieldList *methods) { m_methods_up.reset(methods); }
- private:
- friend class GoASTNode;
- std::unique_ptr<GoASTFieldList> m_methods_up;
+private:
+ friend class GoASTNode;
+ std::unique_ptr<GoASTFieldList> m_methods_up;
- GoASTInterfaceType(const GoASTInterfaceType &) = delete;
- const GoASTInterfaceType &operator=(const GoASTInterfaceType &) = delete;
+ GoASTInterfaceType(const GoASTInterfaceType &) = delete;
+ const GoASTInterfaceType &operator=(const GoASTInterfaceType &) = delete;
};
-class GoASTKeyValueExpr : public GoASTExpr
-{
- public:
- GoASTKeyValueExpr(GoASTExpr *key, GoASTExpr *value) : GoASTExpr(eKeyValueExpr), m_key_up(key), m_value_up(value) {}
- ~GoASTKeyValueExpr() override = default;
+class GoASTKeyValueExpr : public GoASTExpr {
+public:
+ GoASTKeyValueExpr(GoASTExpr *key, GoASTExpr *value)
+ : GoASTExpr(eKeyValueExpr), m_key_up(key), m_value_up(value) {}
+ ~GoASTKeyValueExpr() override = default;
- const char *
- GetKindName() const override
- {
- return "KeyValueExpr";
- }
+ const char *GetKindName() const override { return "KeyValueExpr"; }
- static bool
- classof(const GoASTNode *n)
- {
- return n->GetKind() == eKeyValueExpr;
- }
-
- const GoASTExpr *
- GetKey() const
- {
- return m_key_up.get();
- }
- void
- SetKey(GoASTExpr *key)
- {
- m_key_up.reset(key);
- }
+ static bool classof(const GoASTNode *n) {
+ return n->GetKind() == eKeyValueExpr;
+ }
- const GoASTExpr *
- GetValue() const
- {
- return m_value_up.get();
- }
- void
- SetValue(GoASTExpr *value)
- {
- m_value_up.reset(value);
- }
+ const GoASTExpr *GetKey() const { return m_key_up.get(); }
+ void SetKey(GoASTExpr *key) { m_key_up.reset(key); }
+
+ const GoASTExpr *GetValue() const { return m_value_up.get(); }
+ void SetValue(GoASTExpr *value) { m_value_up.reset(value); }
- private:
- friend class GoASTNode;
- std::unique_ptr<GoASTExpr> m_key_up;
- std::unique_ptr<GoASTExpr> m_value_up;
+private:
+ friend class GoASTNode;
+ std::unique_ptr<GoASTExpr> m_key_up;
+ std::unique_ptr<GoASTExpr> m_value_up;
- GoASTKeyValueExpr(const GoASTKeyValueExpr &) = delete;
- const GoASTKeyValueExpr &operator=(const GoASTKeyValueExpr &) = delete;
+ GoASTKeyValueExpr(const GoASTKeyValueExpr &) = delete;
+ const GoASTKeyValueExpr &operator=(const GoASTKeyValueExpr &) = delete;
};
-class GoASTLabeledStmt : public GoASTStmt
-{
- public:
- GoASTLabeledStmt(GoASTIdent *label, GoASTStmt *stmt) : GoASTStmt(eLabeledStmt), m_label_up(label), m_stmt_up(stmt) {}
- ~GoASTLabeledStmt() override = default;
+class GoASTLabeledStmt : public GoASTStmt {
+public:
+ GoASTLabeledStmt(GoASTIdent *label, GoASTStmt *stmt)
+ : GoASTStmt(eLabeledStmt), m_label_up(label), m_stmt_up(stmt) {}
+ ~GoASTLabeledStmt() override = default;
- const char *
- GetKindName() const override
- {
- return "LabeledStmt";
- }
+ const char *GetKindName() const override { return "LabeledStmt"; }
- static bool
- classof(const GoASTNode *n)
- {
- return n->GetKind() == eLabeledStmt;
- }
-
- const GoASTIdent *
- GetLabel() const
- {
- return m_label_up.get();
- }
- void
- SetLabel(GoASTIdent *label)
- {
- m_label_up.reset(label);
- }
+ static bool classof(const GoASTNode *n) {
+ return n->GetKind() == eLabeledStmt;
+ }
- const GoASTStmt *
- GetStmt() const
- {
- return m_stmt_up.get();
- }
- void
- SetStmt(GoASTStmt *stmt)
- {
- m_stmt_up.reset(stmt);
- }
+ const GoASTIdent *GetLabel() const { return m_label_up.get(); }
+ void SetLabel(GoASTIdent *label) { m_label_up.reset(label); }
- private:
- friend class GoASTNode;
- std::unique_ptr<GoASTIdent> m_label_up;
- std::unique_ptr<GoASTStmt> m_stmt_up;
+ const GoASTStmt *GetStmt() const { return m_stmt_up.get(); }
+ void SetStmt(GoASTStmt *stmt) { m_stmt_up.reset(stmt); }
- GoASTLabeledStmt(const GoASTLabeledStmt &) = delete;
- const GoASTLabeledStmt &operator=(const GoASTLabeledStmt &) = delete;
+private:
+ friend class GoASTNode;
+ std::unique_ptr<GoASTIdent> m_label_up;
+ std::unique_ptr<GoASTStmt> m_stmt_up;
+
+ GoASTLabeledStmt(const GoASTLabeledStmt &) = delete;
+ const GoASTLabeledStmt &operator=(const GoASTLabeledStmt &) = delete;
};
-class GoASTMapType : public GoASTExpr
-{
- public:
- GoASTMapType(GoASTExpr *key, GoASTExpr *value) : GoASTExpr(eMapType), m_key_up(key), m_value_up(value) {}
- ~GoASTMapType() override = default;
+class GoASTMapType : public GoASTExpr {
+public:
+ GoASTMapType(GoASTExpr *key, GoASTExpr *value)
+ : GoASTExpr(eMapType), m_key_up(key), m_value_up(value) {}
+ ~GoASTMapType() override = default;
- const char *
- GetKindName() const override
- {
- return "MapType";
- }
+ const char *GetKindName() const override { return "MapType"; }
- static bool
- classof(const GoASTNode *n)
- {
- return n->GetKind() == eMapType;
- }
-
- const GoASTExpr *
- GetKey() const
- {
- return m_key_up.get();
- }
- void
- SetKey(GoASTExpr *key)
- {
- m_key_up.reset(key);
- }
+ static bool classof(const GoASTNode *n) { return n->GetKind() == eMapType; }
- const GoASTExpr *
- GetValue() const
- {
- return m_value_up.get();
- }
- void
- SetValue(GoASTExpr *value)
- {
- m_value_up.reset(value);
- }
+ const GoASTExpr *GetKey() const { return m_key_up.get(); }
+ void SetKey(GoASTExpr *key) { m_key_up.reset(key); }
+
+ const GoASTExpr *GetValue() const { return m_value_up.get(); }
+ void SetValue(GoASTExpr *value) { m_value_up.reset(value); }
- private:
- friend class GoASTNode;
- std::unique_ptr<GoASTExpr> m_key_up;
- std::unique_ptr<GoASTExpr> m_value_up;
+private:
+ friend class GoASTNode;
+ std::unique_ptr<GoASTExpr> m_key_up;
+ std::unique_ptr<GoASTExpr> m_value_up;
- GoASTMapType(const GoASTMapType &) = delete;
- const GoASTMapType &operator=(const GoASTMapType &) = delete;
+ GoASTMapType(const GoASTMapType &) = delete;
+ const GoASTMapType &operator=(const GoASTMapType &) = delete;
};
-class GoASTParenExpr : public GoASTExpr
-{
- public:
- explicit GoASTParenExpr(GoASTExpr *x) : GoASTExpr(eParenExpr), m_x_up(x) {}
- ~GoASTParenExpr() override = default;
+class GoASTParenExpr : public GoASTExpr {
+public:
+ explicit GoASTParenExpr(GoASTExpr *x) : GoASTExpr(eParenExpr), m_x_up(x) {}
+ ~GoASTParenExpr() override = default;
- const char *
- GetKindName() const override
- {
- return "ParenExpr";
- }
+ const char *GetKindName() const override { return "ParenExpr"; }
- static bool
- classof(const GoASTNode *n)
- {
- return n->GetKind() == eParenExpr;
- }
-
- const GoASTExpr *
- GetX() const
- {
- return m_x_up.get();
- }
- void
- SetX(GoASTExpr *x)
- {
- m_x_up.reset(x);
- }
+ static bool classof(const GoASTNode *n) { return n->GetKind() == eParenExpr; }
- private:
- friend class GoASTNode;
- std::unique_ptr<GoASTExpr> m_x_up;
+ const GoASTExpr *GetX() const { return m_x_up.get(); }
+ void SetX(GoASTExpr *x) { m_x_up.reset(x); }
- GoASTParenExpr(const GoASTParenExpr &) = delete;
- const GoASTParenExpr &operator=(const GoASTParenExpr &) = delete;
+private:
+ friend class GoASTNode;
+ std::unique_ptr<GoASTExpr> m_x_up;
+
+ GoASTParenExpr(const GoASTParenExpr &) = delete;
+ const GoASTParenExpr &operator=(const GoASTParenExpr &) = delete;
};
-class GoASTRangeStmt : public GoASTStmt
-{
- public:
- GoASTRangeStmt(GoASTExpr *key, GoASTExpr *value, bool define, GoASTExpr *x, GoASTBlockStmt *body) : GoASTStmt(eRangeStmt), m_key_up(key), m_value_up(value), m_define(define), m_x_up(x), m_body_up(body) {}
- ~GoASTRangeStmt() override = default;
+class GoASTRangeStmt : public GoASTStmt {
+public:
+ GoASTRangeStmt(GoASTExpr *key, GoASTExpr *value, bool define, GoASTExpr *x,
+ GoASTBlockStmt *body)
+ : GoASTStmt(eRangeStmt), m_key_up(key), m_value_up(value),
+ m_define(define), m_x_up(x), m_body_up(body) {}
+ ~GoASTRangeStmt() override = default;
- const char *
- GetKindName() const override
- {
- return "RangeStmt";
- }
+ const char *GetKindName() const override { return "RangeStmt"; }
- static bool
- classof(const GoASTNode *n)
- {
- return n->GetKind() == eRangeStmt;
- }
-
- const GoASTExpr *
- GetKey() const
- {
- return m_key_up.get();
- }
- void
- SetKey(GoASTExpr *key)
- {
- m_key_up.reset(key);
- }
+ static bool classof(const GoASTNode *n) { return n->GetKind() == eRangeStmt; }
- const GoASTExpr *
- GetValue() const
- {
- return m_value_up.get();
- }
- void
- SetValue(GoASTExpr *value)
- {
- m_value_up.reset(value);
- }
+ const GoASTExpr *GetKey() const { return m_key_up.get(); }
+ void SetKey(GoASTExpr *key) { m_key_up.reset(key); }
- bool
- GetDefine() const
- {
- return m_define;
- }
- void
- SetDefine(bool define)
- {
- m_define = define;
- }
+ const GoASTExpr *GetValue() const { return m_value_up.get(); }
+ void SetValue(GoASTExpr *value) { m_value_up.reset(value); }
- const GoASTExpr *
- GetX() const
- {
- return m_x_up.get();
- }
- void
- SetX(GoASTExpr *x)
- {
- m_x_up.reset(x);
- }
+ bool GetDefine() const { return m_define; }
+ void SetDefine(bool define) { m_define = define; }
- const GoASTBlockStmt *
- GetBody() const
- {
- return m_body_up.get();
- }
- void
- SetBody(GoASTBlockStmt *body)
- {
- m_body_up.reset(body);
- }
+ const GoASTExpr *GetX() const { return m_x_up.get(); }
+ void SetX(GoASTExpr *x) { m_x_up.reset(x); }
+
+ const GoASTBlockStmt *GetBody() const { return m_body_up.get(); }
+ void SetBody(GoASTBlockStmt *body) { m_body_up.reset(body); }
- private:
- friend class GoASTNode;
- std::unique_ptr<GoASTExpr> m_key_up;
- std::unique_ptr<GoASTExpr> m_value_up;
- bool m_define;
- std::unique_ptr<GoASTExpr> m_x_up;
- std::unique_ptr<GoASTBlockStmt> m_body_up;
+private:
+ friend class GoASTNode;
+ std::unique_ptr<GoASTExpr> m_key_up;
+ std::unique_ptr<GoASTExpr> m_value_up;
+ bool m_define;
+ std::unique_ptr<GoASTExpr> m_x_up;
+ std::unique_ptr<GoASTBlockStmt> m_body_up;
- GoASTRangeStmt(const GoASTRangeStmt &) = delete;
- const GoASTRangeStmt &operator=(const GoASTRangeStmt &) = delete;
+ GoASTRangeStmt(const GoASTRangeStmt &) = delete;
+ const GoASTRangeStmt &operator=(const GoASTRangeStmt &) = delete;
};
-class GoASTReturnStmt : public GoASTStmt
-{
- public:
- GoASTReturnStmt() : GoASTStmt(eReturnStmt) {}
- ~GoASTReturnStmt() override = default;
+class GoASTReturnStmt : public GoASTStmt {
+public:
+ GoASTReturnStmt() : GoASTStmt(eReturnStmt) {}
+ ~GoASTReturnStmt() override = default;
- const char *
- GetKindName() const override
- {
- return "ReturnStmt";
- }
+ const char *GetKindName() const override { return "ReturnStmt"; }
- static bool
- classof(const GoASTNode *n)
- {
- return n->GetKind() == eReturnStmt;
- }
-
- size_t
- NumResults() const
- {
- return m_results.size();
- }
- const GoASTExpr *
- GetResults(int i) const
- {
- return m_results[i].get();
- }
- void
- AddResults(GoASTExpr *results)
- {
- m_results.push_back(std::unique_ptr<GoASTExpr>(results));
- }
+ static bool classof(const GoASTNode *n) {
+ return n->GetKind() == eReturnStmt;
+ }
+
+ size_t NumResults() const { return m_results.size(); }
+ const GoASTExpr *GetResults(int i) const { return m_results[i].get(); }
+ void AddResults(GoASTExpr *results) {
+ m_results.push_back(std::unique_ptr<GoASTExpr>(results));
+ }
- private:
- friend class GoASTNode;
- std::vector<std::unique_ptr<GoASTExpr> > m_results;
+private:
+ friend class GoASTNode;
+ std::vector<std::unique_ptr<GoASTExpr>> m_results;
- GoASTReturnStmt(const GoASTReturnStmt &) = delete;
- const GoASTReturnStmt &operator=(const GoASTReturnStmt &) = delete;
+ GoASTReturnStmt(const GoASTReturnStmt &) = delete;
+ const GoASTReturnStmt &operator=(const GoASTReturnStmt &) = delete;
};
-class GoASTSelectStmt : public GoASTStmt
-{
- public:
- explicit GoASTSelectStmt(GoASTBlockStmt *body) : GoASTStmt(eSelectStmt), m_body_up(body) {}
- ~GoASTSelectStmt() override = default;
+class GoASTSelectStmt : public GoASTStmt {
+public:
+ explicit GoASTSelectStmt(GoASTBlockStmt *body)
+ : GoASTStmt(eSelectStmt), m_body_up(body) {}
+ ~GoASTSelectStmt() override = default;
- const char *
- GetKindName() const override
- {
- return "SelectStmt";
- }
+ const char *GetKindName() const override { return "SelectStmt"; }
- static bool
- classof(const GoASTNode *n)
- {
- return n->GetKind() == eSelectStmt;
- }
-
- const GoASTBlockStmt *
- GetBody() const
- {
- return m_body_up.get();
- }
- void
- SetBody(GoASTBlockStmt *body)
- {
- m_body_up.reset(body);
- }
+ static bool classof(const GoASTNode *n) {
+ return n->GetKind() == eSelectStmt;
+ }
- private:
- friend class GoASTNode;
- std::unique_ptr<GoASTBlockStmt> m_body_up;
+ const GoASTBlockStmt *GetBody() const { return m_body_up.get(); }
+ void SetBody(GoASTBlockStmt *body) { m_body_up.reset(body); }
- GoASTSelectStmt(const GoASTSelectStmt &) = delete;
- const GoASTSelectStmt &operator=(const GoASTSelectStmt &) = delete;
+private:
+ friend class GoASTNode;
+ std::unique_ptr<GoASTBlockStmt> m_body_up;
+
+ GoASTSelectStmt(const GoASTSelectStmt &) = delete;
+ const GoASTSelectStmt &operator=(const GoASTSelectStmt &) = delete;
};
-class GoASTSelectorExpr : public GoASTExpr
-{
- public:
- GoASTSelectorExpr(GoASTExpr *x, GoASTIdent *sel) : GoASTExpr(eSelectorExpr), m_x_up(x), m_sel_up(sel) {}
- ~GoASTSelectorExpr() override = default;
+class GoASTSelectorExpr : public GoASTExpr {
+public:
+ GoASTSelectorExpr(GoASTExpr *x, GoASTIdent *sel)
+ : GoASTExpr(eSelectorExpr), m_x_up(x), m_sel_up(sel) {}
+ ~GoASTSelectorExpr() override = default;
- const char *
- GetKindName() const override
- {
- return "SelectorExpr";
- }
+ const char *GetKindName() const override { return "SelectorExpr"; }
- static bool
- classof(const GoASTNode *n)
- {
- return n->GetKind() == eSelectorExpr;
- }
-
- const GoASTExpr *
- GetX() const
- {
- return m_x_up.get();
- }
- void
- SetX(GoASTExpr *x)
- {
- m_x_up.reset(x);
- }
+ static bool classof(const GoASTNode *n) {
+ return n->GetKind() == eSelectorExpr;
+ }
- const GoASTIdent *
- GetSel() const
- {
- return m_sel_up.get();
- }
- void
- SetSel(GoASTIdent *sel)
- {
- m_sel_up.reset(sel);
- }
+ const GoASTExpr *GetX() const { return m_x_up.get(); }
+ void SetX(GoASTExpr *x) { m_x_up.reset(x); }
+
+ const GoASTIdent *GetSel() const { return m_sel_up.get(); }
+ void SetSel(GoASTIdent *sel) { m_sel_up.reset(sel); }
- private:
- friend class GoASTNode;
- std::unique_ptr<GoASTExpr> m_x_up;
- std::unique_ptr<GoASTIdent> m_sel_up;
+private:
+ friend class GoASTNode;
+ std::unique_ptr<GoASTExpr> m_x_up;
+ std::unique_ptr<GoASTIdent> m_sel_up;
- GoASTSelectorExpr(const GoASTSelectorExpr &) = delete;
- const GoASTSelectorExpr &operator=(const GoASTSelectorExpr &) = delete;
+ GoASTSelectorExpr(const GoASTSelectorExpr &) = delete;
+ const GoASTSelectorExpr &operator=(const GoASTSelectorExpr &) = delete;
};
-class GoASTSendStmt : public GoASTStmt
-{
- public:
- GoASTSendStmt(GoASTExpr *chan, GoASTExpr *value) : GoASTStmt(eSendStmt), m_chan_up(chan), m_value_up(value) {}
- ~GoASTSendStmt() override = default;
+class GoASTSendStmt : public GoASTStmt {
+public:
+ GoASTSendStmt(GoASTExpr *chan, GoASTExpr *value)
+ : GoASTStmt(eSendStmt), m_chan_up(chan), m_value_up(value) {}
+ ~GoASTSendStmt() override = default;
- const char *
- GetKindName() const override
- {
- return "SendStmt";
- }
+ const char *GetKindName() const override { return "SendStmt"; }
- static bool
- classof(const GoASTNode *n)
- {
- return n->GetKind() == eSendStmt;
- }
-
- const GoASTExpr *
- GetChan() const
- {
- return m_chan_up.get();
- }
- void
- SetChan(GoASTExpr *chan)
- {
- m_chan_up.reset(chan);
- }
+ static bool classof(const GoASTNode *n) { return n->GetKind() == eSendStmt; }
- const GoASTExpr *
- GetValue() const
- {
- return m_value_up.get();
- }
- void
- SetValue(GoASTExpr *value)
- {
- m_value_up.reset(value);
- }
+ const GoASTExpr *GetChan() const { return m_chan_up.get(); }
+ void SetChan(GoASTExpr *chan) { m_chan_up.reset(chan); }
+
+ const GoASTExpr *GetValue() const { return m_value_up.get(); }
+ void SetValue(GoASTExpr *value) { m_value_up.reset(value); }
- private:
- friend class GoASTNode;
- std::unique_ptr<GoASTExpr> m_chan_up;
- std::unique_ptr<GoASTExpr> m_value_up;
+private:
+ friend class GoASTNode;
+ std::unique_ptr<GoASTExpr> m_chan_up;
+ std::unique_ptr<GoASTExpr> m_value_up;
- GoASTSendStmt(const GoASTSendStmt &) = delete;
- const GoASTSendStmt &operator=(const GoASTSendStmt &) = delete;
+ GoASTSendStmt(const GoASTSendStmt &) = delete;
+ const GoASTSendStmt &operator=(const GoASTSendStmt &) = delete;
};
-class GoASTSliceExpr : public GoASTExpr
-{
- public:
- GoASTSliceExpr(GoASTExpr *x, GoASTExpr *low, GoASTExpr *high, GoASTExpr *max, bool slice3) : GoASTExpr(eSliceExpr), m_x_up(x), m_low_up(low), m_high_up(high), m_max_up(max), m_slice3(slice3) {}
- ~GoASTSliceExpr() override = default;
+class GoASTSliceExpr : public GoASTExpr {
+public:
+ GoASTSliceExpr(GoASTExpr *x, GoASTExpr *low, GoASTExpr *high, GoASTExpr *max,
+ bool slice3)
+ : GoASTExpr(eSliceExpr), m_x_up(x), m_low_up(low), m_high_up(high),
+ m_max_up(max), m_slice3(slice3) {}
+ ~GoASTSliceExpr() override = default;
- const char *
- GetKindName() const override
- {
- return "SliceExpr";
- }
+ const char *GetKindName() const override { return "SliceExpr"; }
- static bool
- classof(const GoASTNode *n)
- {
- return n->GetKind() == eSliceExpr;
- }
-
- const GoASTExpr *
- GetX() const
- {
- return m_x_up.get();
- }
- void
- SetX(GoASTExpr *x)
- {
- m_x_up.reset(x);
- }
+ static bool classof(const GoASTNode *n) { return n->GetKind() == eSliceExpr; }
- const GoASTExpr *
- GetLow() const
- {
- return m_low_up.get();
- }
- void
- SetLow(GoASTExpr *low)
- {
- m_low_up.reset(low);
- }
+ const GoASTExpr *GetX() const { return m_x_up.get(); }
+ void SetX(GoASTExpr *x) { m_x_up.reset(x); }
- const GoASTExpr *
- GetHigh() const
- {
- return m_high_up.get();
- }
- void
- SetHigh(GoASTExpr *high)
- {
- m_high_up.reset(high);
- }
+ const GoASTExpr *GetLow() const { return m_low_up.get(); }
+ void SetLow(GoASTExpr *low) { m_low_up.reset(low); }
- const GoASTExpr *
- GetMax() const
- {
- return m_max_up.get();
- }
- void
- SetMax(GoASTExpr *max)
- {
- m_max_up.reset(max);
- }
+ const GoASTExpr *GetHigh() const { return m_high_up.get(); }
+ void SetHigh(GoASTExpr *high) { m_high_up.reset(high); }
- bool
- GetSlice3() const
- {
- return m_slice3;
- }
- void
- SetSlice3(bool slice3)
- {
- m_slice3 = slice3;
- }
+ const GoASTExpr *GetMax() const { return m_max_up.get(); }
+ void SetMax(GoASTExpr *max) { m_max_up.reset(max); }
- private:
- friend class GoASTNode;
- std::unique_ptr<GoASTExpr> m_x_up;
- std::unique_ptr<GoASTExpr> m_low_up;
- std::unique_ptr<GoASTExpr> m_high_up;
- std::unique_ptr<GoASTExpr> m_max_up;
- bool m_slice3;
+ bool GetSlice3() const { return m_slice3; }
+ void SetSlice3(bool slice3) { m_slice3 = slice3; }
- GoASTSliceExpr(const GoASTSliceExpr &) = delete;
- const GoASTSliceExpr &operator=(const GoASTSliceExpr &) = delete;
+private:
+ friend class GoASTNode;
+ std::unique_ptr<GoASTExpr> m_x_up;
+ std::unique_ptr<GoASTExpr> m_low_up;
+ std::unique_ptr<GoASTExpr> m_high_up;
+ std::unique_ptr<GoASTExpr> m_max_up;
+ bool m_slice3;
+
+ GoASTSliceExpr(const GoASTSliceExpr &) = delete;
+ const GoASTSliceExpr &operator=(const GoASTSliceExpr &) = delete;
};
-class GoASTStarExpr : public GoASTExpr
-{
- public:
- explicit GoASTStarExpr(GoASTExpr *x) : GoASTExpr(eStarExpr), m_x_up(x) {}
- ~GoASTStarExpr() override = default;
+class GoASTStarExpr : public GoASTExpr {
+public:
+ explicit GoASTStarExpr(GoASTExpr *x) : GoASTExpr(eStarExpr), m_x_up(x) {}
+ ~GoASTStarExpr() override = default;
- const char *
- GetKindName() const override
- {
- return "StarExpr";
- }
+ const char *GetKindName() const override { return "StarExpr"; }
- static bool
- classof(const GoASTNode *n)
- {
- return n->GetKind() == eStarExpr;
- }
-
- const GoASTExpr *
- GetX() const
- {
- return m_x_up.get();
- }
- void
- SetX(GoASTExpr *x)
- {
- m_x_up.reset(x);
- }
+ static bool classof(const GoASTNode *n) { return n->GetKind() == eStarExpr; }
+
+ const GoASTExpr *GetX() const { return m_x_up.get(); }
+ void SetX(GoASTExpr *x) { m_x_up.reset(x); }
- private:
- friend class GoASTNode;
- std::unique_ptr<GoASTExpr> m_x_up;
+private:
+ friend class GoASTNode;
+ std::unique_ptr<GoASTExpr> m_x_up;
- GoASTStarExpr(const GoASTStarExpr &) = delete;
- const GoASTStarExpr &operator=(const GoASTStarExpr &) = delete;
+ GoASTStarExpr(const GoASTStarExpr &) = delete;
+ const GoASTStarExpr &operator=(const GoASTStarExpr &) = delete;
};
-class GoASTStructType : public GoASTExpr
-{
- public:
- explicit GoASTStructType(GoASTFieldList *fields) : GoASTExpr(eStructType), m_fields_up(fields) {}
- ~GoASTStructType() override = default;
+class GoASTStructType : public GoASTExpr {
+public:
+ explicit GoASTStructType(GoASTFieldList *fields)
+ : GoASTExpr(eStructType), m_fields_up(fields) {}
+ ~GoASTStructType() override = default;
- const char *
- GetKindName() const override
- {
- return "StructType";
- }
+ const char *GetKindName() const override { return "StructType"; }
- static bool
- classof(const GoASTNode *n)
- {
- return n->GetKind() == eStructType;
- }
-
- const GoASTFieldList *
- GetFields() const
- {
- return m_fields_up.get();
- }
- void
- SetFields(GoASTFieldList *fields)
- {
- m_fields_up.reset(fields);
- }
+ static bool classof(const GoASTNode *n) {
+ return n->GetKind() == eStructType;
+ }
+
+ const GoASTFieldList *GetFields() const { return m_fields_up.get(); }
+ void SetFields(GoASTFieldList *fields) { m_fields_up.reset(fields); }
- private:
- friend class GoASTNode;
- std::unique_ptr<GoASTFieldList> m_fields_up;
+private:
+ friend class GoASTNode;
+ std::unique_ptr<GoASTFieldList> m_fields_up;
- GoASTStructType(const GoASTStructType &) = delete;
- const GoASTStructType &operator=(const GoASTStructType &) = delete;
+ GoASTStructType(const GoASTStructType &) = delete;
+ const GoASTStructType &operator=(const GoASTStructType &) = delete;
};
-class GoASTSwitchStmt : public GoASTStmt
-{
- public:
- GoASTSwitchStmt(GoASTStmt *init, GoASTExpr *tag, GoASTBlockStmt *body) : GoASTStmt(eSwitchStmt), m_init_up(init), m_tag_up(tag), m_body_up(body) {}
- ~GoASTSwitchStmt() override = default;
+class GoASTSwitchStmt : public GoASTStmt {
+public:
+ GoASTSwitchStmt(GoASTStmt *init, GoASTExpr *tag, GoASTBlockStmt *body)
+ : GoASTStmt(eSwitchStmt), m_init_up(init), m_tag_up(tag),
+ m_body_up(body) {}
+ ~GoASTSwitchStmt() override = default;
- const char *
- GetKindName() const override
- {
- return "SwitchStmt";
- }
+ const char *GetKindName() const override { return "SwitchStmt"; }
- static bool
- classof(const GoASTNode *n)
- {
- return n->GetKind() == eSwitchStmt;
- }
-
- const GoASTStmt *
- GetInit() const
- {
- return m_init_up.get();
- }
- void
- SetInit(GoASTStmt *init)
- {
- m_init_up.reset(init);
- }
+ static bool classof(const GoASTNode *n) {
+ return n->GetKind() == eSwitchStmt;
+ }
- const GoASTExpr *
- GetTag() const
- {
- return m_tag_up.get();
- }
- void
- SetTag(GoASTExpr *tag)
- {
- m_tag_up.reset(tag);
- }
+ const GoASTStmt *GetInit() const { return m_init_up.get(); }
+ void SetInit(GoASTStmt *init) { m_init_up.reset(init); }
- const GoASTBlockStmt *
- GetBody() const
- {
- return m_body_up.get();
- }
- void
- SetBody(GoASTBlockStmt *body)
- {
- m_body_up.reset(body);
- }
+ const GoASTExpr *GetTag() const { return m_tag_up.get(); }
+ void SetTag(GoASTExpr *tag) { m_tag_up.reset(tag); }
+
+ const GoASTBlockStmt *GetBody() const { return m_body_up.get(); }
+ void SetBody(GoASTBlockStmt *body) { m_body_up.reset(body); }
- private:
- friend class GoASTNode;
- std::unique_ptr<GoASTStmt> m_init_up;
- std::unique_ptr<GoASTExpr> m_tag_up;
- std::unique_ptr<GoASTBlockStmt> m_body_up;
+private:
+ friend class GoASTNode;
+ std::unique_ptr<GoASTStmt> m_init_up;
+ std::unique_ptr<GoASTExpr> m_tag_up;
+ std::unique_ptr<GoASTBlockStmt> m_body_up;
- GoASTSwitchStmt(const GoASTSwitchStmt &) = delete;
- const GoASTSwitchStmt &operator=(const GoASTSwitchStmt &) = delete;
+ GoASTSwitchStmt(const GoASTSwitchStmt &) = delete;
+ const GoASTSwitchStmt &operator=(const GoASTSwitchStmt &) = delete;
};
-class GoASTTypeAssertExpr : public GoASTExpr
-{
- public:
- GoASTTypeAssertExpr(GoASTExpr *x, GoASTExpr *type) : GoASTExpr(eTypeAssertExpr), m_x_up(x), m_type_up(type) {}
- ~GoASTTypeAssertExpr() override = default;
+class GoASTTypeAssertExpr : public GoASTExpr {
+public:
+ GoASTTypeAssertExpr(GoASTExpr *x, GoASTExpr *type)
+ : GoASTExpr(eTypeAssertExpr), m_x_up(x), m_type_up(type) {}
+ ~GoASTTypeAssertExpr() override = default;
- const char *
- GetKindName() const override
- {
- return "TypeAssertExpr";
- }
+ const char *GetKindName() const override { return "TypeAssertExpr"; }
- static bool
- classof(const GoASTNode *n)
- {
- return n->GetKind() == eTypeAssertExpr;
- }
-
- const GoASTExpr *
- GetX() const
- {
- return m_x_up.get();
- }
- void
- SetX(GoASTExpr *x)
- {
- m_x_up.reset(x);
- }
+ static bool classof(const GoASTNode *n) {
+ return n->GetKind() == eTypeAssertExpr;
+ }
- const GoASTExpr *
- GetType() const
- {
- return m_type_up.get();
- }
- void
- SetType(GoASTExpr *type)
- {
- m_type_up.reset(type);
- }
+ const GoASTExpr *GetX() const { return m_x_up.get(); }
+ void SetX(GoASTExpr *x) { m_x_up.reset(x); }
+
+ const GoASTExpr *GetType() const { return m_type_up.get(); }
+ void SetType(GoASTExpr *type) { m_type_up.reset(type); }
- private:
- friend class GoASTNode;
- std::unique_ptr<GoASTExpr> m_x_up;
- std::unique_ptr<GoASTExpr> m_type_up;
+private:
+ friend class GoASTNode;
+ std::unique_ptr<GoASTExpr> m_x_up;
+ std::unique_ptr<GoASTExpr> m_type_up;
- GoASTTypeAssertExpr(const GoASTTypeAssertExpr &) = delete;
- const GoASTTypeAssertExpr &operator=(const GoASTTypeAssertExpr &) = delete;
+ GoASTTypeAssertExpr(const GoASTTypeAssertExpr &) = delete;
+ const GoASTTypeAssertExpr &operator=(const GoASTTypeAssertExpr &) = delete;
};
-class GoASTTypeSpec : public GoASTSpec
-{
- public:
- GoASTTypeSpec(GoASTIdent *name, GoASTExpr *type) : GoASTSpec(eTypeSpec), m_name_up(name), m_type_up(type) {}
- ~GoASTTypeSpec() override = default;
+class GoASTTypeSpec : public GoASTSpec {
+public:
+ GoASTTypeSpec(GoASTIdent *name, GoASTExpr *type)
+ : GoASTSpec(eTypeSpec), m_name_up(name), m_type_up(type) {}
+ ~GoASTTypeSpec() override = default;
- const char *
- GetKindName() const override
- {
- return "TypeSpec";
- }
+ const char *GetKindName() const override { return "TypeSpec"; }
- static bool
- classof(const GoASTNode *n)
- {
- return n->GetKind() == eTypeSpec;
- }
-
- const GoASTIdent *
- GetName() const
- {
- return m_name_up.get();
- }
- void
- SetName(GoASTIdent *name)
- {
- m_name_up.reset(name);
- }
+ static bool classof(const GoASTNode *n) { return n->GetKind() == eTypeSpec; }
- const GoASTExpr *
- GetType() const
- {
- return m_type_up.get();
- }
- void
- SetType(GoASTExpr *type)
- {
- m_type_up.reset(type);
- }
+ const GoASTIdent *GetName() const { return m_name_up.get(); }
+ void SetName(GoASTIdent *name) { m_name_up.reset(name); }
- private:
- friend class GoASTNode;
- std::unique_ptr<GoASTIdent> m_name_up;
- std::unique_ptr<GoASTExpr> m_type_up;
+ const GoASTExpr *GetType() const { return m_type_up.get(); }
+ void SetType(GoASTExpr *type) { m_type_up.reset(type); }
- GoASTTypeSpec(const GoASTTypeSpec &) = delete;
- const GoASTTypeSpec &operator=(const GoASTTypeSpec &) = delete;
+private:
+ friend class GoASTNode;
+ std::unique_ptr<GoASTIdent> m_name_up;
+ std::unique_ptr<GoASTExpr> m_type_up;
+
+ GoASTTypeSpec(const GoASTTypeSpec &) = delete;
+ const GoASTTypeSpec &operator=(const GoASTTypeSpec &) = delete;
};
-class GoASTTypeSwitchStmt : public GoASTStmt
-{
- public:
- GoASTTypeSwitchStmt(GoASTStmt *init, GoASTStmt *assign, GoASTBlockStmt *body) : GoASTStmt(eTypeSwitchStmt), m_init_up(init), m_assign_up(assign), m_body_up(body) {}
- ~GoASTTypeSwitchStmt() override = default;
+class GoASTTypeSwitchStmt : public GoASTStmt {
+public:
+ GoASTTypeSwitchStmt(GoASTStmt *init, GoASTStmt *assign, GoASTBlockStmt *body)
+ : GoASTStmt(eTypeSwitchStmt), m_init_up(init), m_assign_up(assign),
+ m_body_up(body) {}
+ ~GoASTTypeSwitchStmt() override = default;
- const char *
- GetKindName() const override
- {
- return "TypeSwitchStmt";
- }
+ const char *GetKindName() const override { return "TypeSwitchStmt"; }
- static bool
- classof(const GoASTNode *n)
- {
- return n->GetKind() == eTypeSwitchStmt;
- }
-
- const GoASTStmt *
- GetInit() const
- {
- return m_init_up.get();
- }
- void
- SetInit(GoASTStmt *init)
- {
- m_init_up.reset(init);
- }
+ static bool classof(const GoASTNode *n) {
+ return n->GetKind() == eTypeSwitchStmt;
+ }
- const GoASTStmt *
- GetAssign() const
- {
- return m_assign_up.get();
- }
- void
- SetAssign(GoASTStmt *assign)
- {
- m_assign_up.reset(assign);
- }
+ const GoASTStmt *GetInit() const { return m_init_up.get(); }
+ void SetInit(GoASTStmt *init) { m_init_up.reset(init); }
- const GoASTBlockStmt *
- GetBody() const
- {
- return m_body_up.get();
- }
- void
- SetBody(GoASTBlockStmt *body)
- {
- m_body_up.reset(body);
- }
+ const GoASTStmt *GetAssign() const { return m_assign_up.get(); }
+ void SetAssign(GoASTStmt *assign) { m_assign_up.reset(assign); }
- private:
- friend class GoASTNode;
- std::unique_ptr<GoASTStmt> m_init_up;
- std::unique_ptr<GoASTStmt> m_assign_up;
- std::unique_ptr<GoASTBlockStmt> m_body_up;
+ const GoASTBlockStmt *GetBody() const { return m_body_up.get(); }
+ void SetBody(GoASTBlockStmt *body) { m_body_up.reset(body); }
- GoASTTypeSwitchStmt(const GoASTTypeSwitchStmt &) = delete;
- const GoASTTypeSwitchStmt &operator=(const GoASTTypeSwitchStmt &) = delete;
+private:
+ friend class GoASTNode;
+ std::unique_ptr<GoASTStmt> m_init_up;
+ std::unique_ptr<GoASTStmt> m_assign_up;
+ std::unique_ptr<GoASTBlockStmt> m_body_up;
+
+ GoASTTypeSwitchStmt(const GoASTTypeSwitchStmt &) = delete;
+ const GoASTTypeSwitchStmt &operator=(const GoASTTypeSwitchStmt &) = delete;
};
-class GoASTUnaryExpr : public GoASTExpr
-{
- public:
- GoASTUnaryExpr(TokenType op, GoASTExpr *x) : GoASTExpr(eUnaryExpr), m_op(op), m_x_up(x) {}
- ~GoASTUnaryExpr() override = default;
+class GoASTUnaryExpr : public GoASTExpr {
+public:
+ GoASTUnaryExpr(TokenType op, GoASTExpr *x)
+ : GoASTExpr(eUnaryExpr), m_op(op), m_x_up(x) {}
+ ~GoASTUnaryExpr() override = default;
- const char *
- GetKindName() const override
- {
- return "UnaryExpr";
- }
+ const char *GetKindName() const override { return "UnaryExpr"; }
- static bool
- classof(const GoASTNode *n)
- {
- return n->GetKind() == eUnaryExpr;
- }
-
- TokenType
- GetOp() const
- {
- return m_op;
- }
- void
- SetOp(TokenType op)
- {
- m_op = op;
- }
+ static bool classof(const GoASTNode *n) { return n->GetKind() == eUnaryExpr; }
- const GoASTExpr *
- GetX() const
- {
- return m_x_up.get();
- }
- void
- SetX(GoASTExpr *x)
- {
- m_x_up.reset(x);
- }
+ TokenType GetOp() const { return m_op; }
+ void SetOp(TokenType op) { m_op = op; }
+
+ const GoASTExpr *GetX() const { return m_x_up.get(); }
+ void SetX(GoASTExpr *x) { m_x_up.reset(x); }
- private:
- friend class GoASTNode;
- TokenType m_op;
- std::unique_ptr<GoASTExpr> m_x_up;
+private:
+ friend class GoASTNode;
+ TokenType m_op;
+ std::unique_ptr<GoASTExpr> m_x_up;
- GoASTUnaryExpr(const GoASTUnaryExpr &) = delete;
- const GoASTUnaryExpr &operator=(const GoASTUnaryExpr &) = delete;
+ GoASTUnaryExpr(const GoASTUnaryExpr &) = delete;
+ const GoASTUnaryExpr &operator=(const GoASTUnaryExpr &) = delete;
};
-class GoASTValueSpec : public GoASTSpec
-{
- public:
- GoASTValueSpec() : GoASTSpec(eValueSpec) {}
- ~GoASTValueSpec() override = default;
+class GoASTValueSpec : public GoASTSpec {
+public:
+ GoASTValueSpec() : GoASTSpec(eValueSpec) {}
+ ~GoASTValueSpec() override = default;
- const char *
- GetKindName() const override
- {
- return "ValueSpec";
- }
+ const char *GetKindName() const override { return "ValueSpec"; }
- static bool
- classof(const GoASTNode *n)
- {
- return n->GetKind() == eValueSpec;
- }
-
- size_t
- NumNames() const
- {
- return m_names.size();
- }
- const GoASTIdent *
- GetNames(int i) const
- {
- return m_names[i].get();
- }
- void
- AddNames(GoASTIdent *names)
- {
- m_names.push_back(std::unique_ptr<GoASTIdent>(names));
- }
+ static bool classof(const GoASTNode *n) { return n->GetKind() == eValueSpec; }
- const GoASTExpr *
- GetType() const
- {
- return m_type_up.get();
- }
- void
- SetType(GoASTExpr *type)
- {
- m_type_up.reset(type);
- }
+ size_t NumNames() const { return m_names.size(); }
+ const GoASTIdent *GetNames(int i) const { return m_names[i].get(); }
+ void AddNames(GoASTIdent *names) {
+ m_names.push_back(std::unique_ptr<GoASTIdent>(names));
+ }
- size_t
- NumValues() const
- {
- return m_values.size();
- }
- const GoASTExpr *
- GetValues(int i) const
- {
- return m_values[i].get();
- }
- void
- AddValues(GoASTExpr *values)
- {
- m_values.push_back(std::unique_ptr<GoASTExpr>(values));
- }
+ const GoASTExpr *GetType() const { return m_type_up.get(); }
+ void SetType(GoASTExpr *type) { m_type_up.reset(type); }
- private:
- friend class GoASTNode;
- std::vector<std::unique_ptr<GoASTIdent> > m_names;
- std::unique_ptr<GoASTExpr> m_type_up;
- std::vector<std::unique_ptr<GoASTExpr> > m_values;
+ size_t NumValues() const { return m_values.size(); }
+ const GoASTExpr *GetValues(int i) const { return m_values[i].get(); }
+ void AddValues(GoASTExpr *values) {
+ m_values.push_back(std::unique_ptr<GoASTExpr>(values));
+ }
- GoASTValueSpec(const GoASTValueSpec &) = delete;
- const GoASTValueSpec &operator=(const GoASTValueSpec &) = delete;
-};
+private:
+ friend class GoASTNode;
+ std::vector<std::unique_ptr<GoASTIdent>> m_names;
+ std::unique_ptr<GoASTExpr> m_type_up;
+ std::vector<std::unique_ptr<GoASTExpr>> m_values;
+ GoASTValueSpec(const GoASTValueSpec &) = delete;
+ const GoASTValueSpec &operator=(const GoASTValueSpec &) = delete;
+};
-template <typename R, typename V>
-R GoASTDecl::Visit(V* v) const
-{
- switch(GetKind())
- {
- case eBadDecl:
- return v->VisitBadDecl(llvm::cast<const GoASTBadDecl>(this));
- case eFuncDecl:
- return v->VisitFuncDecl(llvm::cast<const GoASTFuncDecl>(this));
- case eGenDecl:
- return v->VisitGenDecl(llvm::cast<const GoASTGenDecl>(this));
- default:
- assert(false && "Invalid kind");
- }
+template <typename R, typename V> R GoASTDecl::Visit(V *v) const {
+ switch (GetKind()) {
+ case eBadDecl:
+ return v->VisitBadDecl(llvm::cast<const GoASTBadDecl>(this));
+ case eFuncDecl:
+ return v->VisitFuncDecl(llvm::cast<const GoASTFuncDecl>(this));
+ case eGenDecl:
+ return v->VisitGenDecl(llvm::cast<const GoASTGenDecl>(this));
+ default:
+ assert(false && "Invalid kind");
+ }
}
-template <typename R, typename V>
-R GoASTExpr::Visit(V* v) const
-{
- switch(GetKind())
- {
- case eArrayType:
- return v->VisitArrayType(llvm::cast<const GoASTArrayType>(this));
- case eBadExpr:
- return v->VisitBadExpr(llvm::cast<const GoASTBadExpr>(this));
- case eBasicLit:
- return v->VisitBasicLit(llvm::cast<const GoASTBasicLit>(this));
- case eBinaryExpr:
- return v->VisitBinaryExpr(llvm::cast<const GoASTBinaryExpr>(this));
- case eIdent:
- return v->VisitIdent(llvm::cast<const GoASTIdent>(this));
- case eCallExpr:
- return v->VisitCallExpr(llvm::cast<const GoASTCallExpr>(this));
- case eChanType:
- return v->VisitChanType(llvm::cast<const GoASTChanType>(this));
- case eCompositeLit:
- return v->VisitCompositeLit(llvm::cast<const GoASTCompositeLit>(this));
- case eEllipsis:
- return v->VisitEllipsis(llvm::cast<const GoASTEllipsis>(this));
- case eFuncType:
- return v->VisitFuncType(llvm::cast<const GoASTFuncType>(this));
- case eFuncLit:
- return v->VisitFuncLit(llvm::cast<const GoASTFuncLit>(this));
- case eIndexExpr:
- return v->VisitIndexExpr(llvm::cast<const GoASTIndexExpr>(this));
- case eInterfaceType:
- return v->VisitInterfaceType(llvm::cast<const GoASTInterfaceType>(this));
- case eKeyValueExpr:
- return v->VisitKeyValueExpr(llvm::cast<const GoASTKeyValueExpr>(this));
- case eMapType:
- return v->VisitMapType(llvm::cast<const GoASTMapType>(this));
- case eParenExpr:
- return v->VisitParenExpr(llvm::cast<const GoASTParenExpr>(this));
- case eSelectorExpr:
- return v->VisitSelectorExpr(llvm::cast<const GoASTSelectorExpr>(this));
- case eSliceExpr:
- return v->VisitSliceExpr(llvm::cast<const GoASTSliceExpr>(this));
- case eStarExpr:
- return v->VisitStarExpr(llvm::cast<const GoASTStarExpr>(this));
- case eStructType:
- return v->VisitStructType(llvm::cast<const GoASTStructType>(this));
- case eTypeAssertExpr:
- return v->VisitTypeAssertExpr(llvm::cast<const GoASTTypeAssertExpr>(this));
- case eUnaryExpr:
- return v->VisitUnaryExpr(llvm::cast<const GoASTUnaryExpr>(this));
- default:
- assert(false && "Invalid kind");
- return R();
- }
+template <typename R, typename V> R GoASTExpr::Visit(V *v) const {
+ switch (GetKind()) {
+ case eArrayType:
+ return v->VisitArrayType(llvm::cast<const GoASTArrayType>(this));
+ case eBadExpr:
+ return v->VisitBadExpr(llvm::cast<const GoASTBadExpr>(this));
+ case eBasicLit:
+ return v->VisitBasicLit(llvm::cast<const GoASTBasicLit>(this));
+ case eBinaryExpr:
+ return v->VisitBinaryExpr(llvm::cast<const GoASTBinaryExpr>(this));
+ case eIdent:
+ return v->VisitIdent(llvm::cast<const GoASTIdent>(this));
+ case eCallExpr:
+ return v->VisitCallExpr(llvm::cast<const GoASTCallExpr>(this));
+ case eChanType:
+ return v->VisitChanType(llvm::cast<const GoASTChanType>(this));
+ case eCompositeLit:
+ return v->VisitCompositeLit(llvm::cast<const GoASTCompositeLit>(this));
+ case eEllipsis:
+ return v->VisitEllipsis(llvm::cast<const GoASTEllipsis>(this));
+ case eFuncType:
+ return v->VisitFuncType(llvm::cast<const GoASTFuncType>(this));
+ case eFuncLit:
+ return v->VisitFuncLit(llvm::cast<const GoASTFuncLit>(this));
+ case eIndexExpr:
+ return v->VisitIndexExpr(llvm::cast<const GoASTIndexExpr>(this));
+ case eInterfaceType:
+ return v->VisitInterfaceType(llvm::cast<const GoASTInterfaceType>(this));
+ case eKeyValueExpr:
+ return v->VisitKeyValueExpr(llvm::cast<const GoASTKeyValueExpr>(this));
+ case eMapType:
+ return v->VisitMapType(llvm::cast<const GoASTMapType>(this));
+ case eParenExpr:
+ return v->VisitParenExpr(llvm::cast<const GoASTParenExpr>(this));
+ case eSelectorExpr:
+ return v->VisitSelectorExpr(llvm::cast<const GoASTSelectorExpr>(this));
+ case eSliceExpr:
+ return v->VisitSliceExpr(llvm::cast<const GoASTSliceExpr>(this));
+ case eStarExpr:
+ return v->VisitStarExpr(llvm::cast<const GoASTStarExpr>(this));
+ case eStructType:
+ return v->VisitStructType(llvm::cast<const GoASTStructType>(this));
+ case eTypeAssertExpr:
+ return v->VisitTypeAssertExpr(llvm::cast<const GoASTTypeAssertExpr>(this));
+ case eUnaryExpr:
+ return v->VisitUnaryExpr(llvm::cast<const GoASTUnaryExpr>(this));
+ default:
+ assert(false && "Invalid kind");
+ return R();
+ }
}
-template <typename R, typename V>
-R GoASTSpec::Visit(V* v) const
-{
- switch(GetKind())
- {
- case eImportSpec:
- return v->VisitImportSpec(llvm::cast<const GoASTImportSpec>(this));
- case eTypeSpec:
- return v->VisitTypeSpec(llvm::cast<const GoASTTypeSpec>(this));
- case eValueSpec:
- return v->VisitValueSpec(llvm::cast<const GoASTValueSpec>(this));
- default:
- assert(false && "Invalid kind");
- }
+template <typename R, typename V> R GoASTSpec::Visit(V *v) const {
+ switch (GetKind()) {
+ case eImportSpec:
+ return v->VisitImportSpec(llvm::cast<const GoASTImportSpec>(this));
+ case eTypeSpec:
+ return v->VisitTypeSpec(llvm::cast<const GoASTTypeSpec>(this));
+ case eValueSpec:
+ return v->VisitValueSpec(llvm::cast<const GoASTValueSpec>(this));
+ default:
+ assert(false && "Invalid kind");
+ }
}
-template <typename R, typename V>
-R GoASTStmt::Visit(V* v) const
-{
- switch(GetKind())
- {
- case eAssignStmt:
- return v->VisitAssignStmt(llvm::cast<const GoASTAssignStmt>(this));
- case eBadStmt:
- return v->VisitBadStmt(llvm::cast<const GoASTBadStmt>(this));
- case eBlockStmt:
- return v->VisitBlockStmt(llvm::cast<const GoASTBlockStmt>(this));
- case eBranchStmt:
- return v->VisitBranchStmt(llvm::cast<const GoASTBranchStmt>(this));
- case eCaseClause:
- return v->VisitCaseClause(llvm::cast<const GoASTCaseClause>(this));
- case eCommClause:
- return v->VisitCommClause(llvm::cast<const GoASTCommClause>(this));
- case eDeclStmt:
- return v->VisitDeclStmt(llvm::cast<const GoASTDeclStmt>(this));
- case eDeferStmt:
- return v->VisitDeferStmt(llvm::cast<const GoASTDeferStmt>(this));
- case eEmptyStmt:
- return v->VisitEmptyStmt(llvm::cast<const GoASTEmptyStmt>(this));
- case eExprStmt:
- return v->VisitExprStmt(llvm::cast<const GoASTExprStmt>(this));
- case eForStmt:
- return v->VisitForStmt(llvm::cast<const GoASTForStmt>(this));
- case eGoStmt:
- return v->VisitGoStmt(llvm::cast<const GoASTGoStmt>(this));
- case eIfStmt:
- return v->VisitIfStmt(llvm::cast<const GoASTIfStmt>(this));
- case eIncDecStmt:
- return v->VisitIncDecStmt(llvm::cast<const GoASTIncDecStmt>(this));
- case eLabeledStmt:
- return v->VisitLabeledStmt(llvm::cast<const GoASTLabeledStmt>(this));
- case eRangeStmt:
- return v->VisitRangeStmt(llvm::cast<const GoASTRangeStmt>(this));
- case eReturnStmt:
- return v->VisitReturnStmt(llvm::cast<const GoASTReturnStmt>(this));
- case eSelectStmt:
- return v->VisitSelectStmt(llvm::cast<const GoASTSelectStmt>(this));
- case eSendStmt:
- return v->VisitSendStmt(llvm::cast<const GoASTSendStmt>(this));
- case eSwitchStmt:
- return v->VisitSwitchStmt(llvm::cast<const GoASTSwitchStmt>(this));
- case eTypeSwitchStmt:
- return v->VisitTypeSwitchStmt(llvm::cast<const GoASTTypeSwitchStmt>(this));
- default:
- assert(false && "Invalid kind");
- }
+template <typename R, typename V> R GoASTStmt::Visit(V *v) const {
+ switch (GetKind()) {
+ case eAssignStmt:
+ return v->VisitAssignStmt(llvm::cast<const GoASTAssignStmt>(this));
+ case eBadStmt:
+ return v->VisitBadStmt(llvm::cast<const GoASTBadStmt>(this));
+ case eBlockStmt:
+ return v->VisitBlockStmt(llvm::cast<const GoASTBlockStmt>(this));
+ case eBranchStmt:
+ return v->VisitBranchStmt(llvm::cast<const GoASTBranchStmt>(this));
+ case eCaseClause:
+ return v->VisitCaseClause(llvm::cast<const GoASTCaseClause>(this));
+ case eCommClause:
+ return v->VisitCommClause(llvm::cast<const GoASTCommClause>(this));
+ case eDeclStmt:
+ return v->VisitDeclStmt(llvm::cast<const GoASTDeclStmt>(this));
+ case eDeferStmt:
+ return v->VisitDeferStmt(llvm::cast<const GoASTDeferStmt>(this));
+ case eEmptyStmt:
+ return v->VisitEmptyStmt(llvm::cast<const GoASTEmptyStmt>(this));
+ case eExprStmt:
+ return v->VisitExprStmt(llvm::cast<const GoASTExprStmt>(this));
+ case eForStmt:
+ return v->VisitForStmt(llvm::cast<const GoASTForStmt>(this));
+ case eGoStmt:
+ return v->VisitGoStmt(llvm::cast<const GoASTGoStmt>(this));
+ case eIfStmt:
+ return v->VisitIfStmt(llvm::cast<const GoASTIfStmt>(this));
+ case eIncDecStmt:
+ return v->VisitIncDecStmt(llvm::cast<const GoASTIncDecStmt>(this));
+ case eLabeledStmt:
+ return v->VisitLabeledStmt(llvm::cast<const GoASTLabeledStmt>(this));
+ case eRangeStmt:
+ return v->VisitRangeStmt(llvm::cast<const GoASTRangeStmt>(this));
+ case eReturnStmt:
+ return v->VisitReturnStmt(llvm::cast<const GoASTReturnStmt>(this));
+ case eSelectStmt:
+ return v->VisitSelectStmt(llvm::cast<const GoASTSelectStmt>(this));
+ case eSendStmt:
+ return v->VisitSendStmt(llvm::cast<const GoASTSendStmt>(this));
+ case eSwitchStmt:
+ return v->VisitSwitchStmt(llvm::cast<const GoASTSwitchStmt>(this));
+ case eTypeSwitchStmt:
+ return v->VisitTypeSwitchStmt(llvm::cast<const GoASTTypeSwitchStmt>(this));
+ default:
+ assert(false && "Invalid kind");
+ }
}
-template <typename V>
-void GoASTNode::WalkChildren(V &v)
-{
- switch (m_kind)
- {
-
-
- case eArrayType:
- {
- GoASTArrayType *n = llvm::cast<GoASTArrayType>(this);
- (void)n;
- v(n->m_len_up.get());
- v(n->m_elt_up.get());
- return;
- }
- case eAssignStmt:
- {
- GoASTAssignStmt *n = llvm::cast<GoASTAssignStmt>(this);
- (void)n;
- for (auto& e : n->m_lhs) { v(e.get()); }
- for (auto& e : n->m_rhs) { v(e.get()); }
- return;
- }
- case eBasicLit:
- {
- GoASTBasicLit *n = llvm::cast<GoASTBasicLit>(this);
- (void)n;
- return;
- }
- case eBinaryExpr:
- {
- GoASTBinaryExpr *n = llvm::cast<GoASTBinaryExpr>(this);
- (void)n;
- v(n->m_x_up.get());
- v(n->m_y_up.get());
- return;
- }
- case eBlockStmt:
- {
- GoASTBlockStmt *n = llvm::cast<GoASTBlockStmt>(this);
- (void)n;
- for (auto& e : n->m_list) { v(e.get()); }
- return;
- }
- case eIdent:
- {
- GoASTIdent *n = llvm::cast<GoASTIdent>(this);
- (void)n;
- return;
- }
- case eBranchStmt:
- {
- GoASTBranchStmt *n = llvm::cast<GoASTBranchStmt>(this);
- (void)n;
- v(n->m_label_up.get());
- return;
- }
- case eCallExpr:
- {
- GoASTCallExpr *n = llvm::cast<GoASTCallExpr>(this);
- (void)n;
- v(n->m_fun_up.get());
- for (auto& e : n->m_args) { v(e.get()); }
- return;
- }
- case eCaseClause:
- {
- GoASTCaseClause *n = llvm::cast<GoASTCaseClause>(this);
- (void)n;
- for (auto& e : n->m_list) { v(e.get()); }
- for (auto& e : n->m_body) { v(e.get()); }
- return;
- }
- case eChanType:
- {
- GoASTChanType *n = llvm::cast<GoASTChanType>(this);
- (void)n;
- v(n->m_value_up.get());
- return;
- }
- case eCommClause:
- {
- GoASTCommClause *n = llvm::cast<GoASTCommClause>(this);
- (void)n;
- v(n->m_comm_up.get());
- for (auto& e : n->m_body) { v(e.get()); }
- return;
- }
- case eCompositeLit:
- {
- GoASTCompositeLit *n = llvm::cast<GoASTCompositeLit>(this);
- (void)n;
- v(n->m_type_up.get());
- for (auto& e : n->m_elts) { v(e.get()); }
- return;
- }
- case eDeclStmt:
- {
- GoASTDeclStmt *n = llvm::cast<GoASTDeclStmt>(this);
- (void)n;
- v(n->m_decl_up.get());
- return;
- }
- case eDeferStmt:
- {
- GoASTDeferStmt *n = llvm::cast<GoASTDeferStmt>(this);
- (void)n;
- v(n->m_call_up.get());
- return;
- }
- case eEllipsis:
- {
- GoASTEllipsis *n = llvm::cast<GoASTEllipsis>(this);
- (void)n;
- v(n->m_elt_up.get());
- return;
- }
- case eExprStmt:
- {
- GoASTExprStmt *n = llvm::cast<GoASTExprStmt>(this);
- (void)n;
- v(n->m_x_up.get());
- return;
- }
- case eField:
- {
- GoASTField *n = llvm::cast<GoASTField>(this);
- (void)n;
- for (auto& e : n->m_names) { v(e.get()); }
- v(n->m_type_up.get());
- v(n->m_tag_up.get());
- return;
- }
- case eFieldList:
- {
- GoASTFieldList *n = llvm::cast<GoASTFieldList>(this);
- (void)n;
- for (auto& e : n->m_list) { v(e.get()); }
- return;
- }
- case eForStmt:
- {
- GoASTForStmt *n = llvm::cast<GoASTForStmt>(this);
- (void)n;
- v(n->m_init_up.get());
- v(n->m_cond_up.get());
- v(n->m_post_up.get());
- v(n->m_body_up.get());
- return;
- }
- case eFuncType:
- {
- GoASTFuncType *n = llvm::cast<GoASTFuncType>(this);
- (void)n;
- v(n->m_params_up.get());
- v(n->m_results_up.get());
- return;
- }
- case eFuncDecl:
- {
- GoASTFuncDecl *n = llvm::cast<GoASTFuncDecl>(this);
- (void)n;
- v(n->m_recv_up.get());
- v(n->m_name_up.get());
- v(n->m_type_up.get());
- v(n->m_body_up.get());
- return;
- }
- case eFuncLit:
- {
- GoASTFuncLit *n = llvm::cast<GoASTFuncLit>(this);
- (void)n;
- v(n->m_type_up.get());
- v(n->m_body_up.get());
- return;
- }
- case eGenDecl:
- {
- GoASTGenDecl *n = llvm::cast<GoASTGenDecl>(this);
- (void)n;
- for (auto& e : n->m_specs) { v(e.get()); }
- return;
- }
- case eGoStmt:
- {
- GoASTGoStmt *n = llvm::cast<GoASTGoStmt>(this);
- (void)n;
- v(n->m_call_up.get());
- return;
- }
- case eIfStmt:
- {
- GoASTIfStmt *n = llvm::cast<GoASTIfStmt>(this);
- (void)n;
- v(n->m_init_up.get());
- v(n->m_cond_up.get());
- v(n->m_body_up.get());
- v(n->m_els_up.get());
- return;
- }
- case eImportSpec:
- {
- GoASTImportSpec *n = llvm::cast<GoASTImportSpec>(this);
- (void)n;
- v(n->m_name_up.get());
- v(n->m_path_up.get());
- return;
- }
- case eIncDecStmt:
- {
- GoASTIncDecStmt *n = llvm::cast<GoASTIncDecStmt>(this);
- (void)n;
- v(n->m_x_up.get());
- return;
- }
- case eIndexExpr:
- {
- GoASTIndexExpr *n = llvm::cast<GoASTIndexExpr>(this);
- (void)n;
- v(n->m_x_up.get());
- v(n->m_index_up.get());
- return;
- }
- case eInterfaceType:
- {
- GoASTInterfaceType *n = llvm::cast<GoASTInterfaceType>(this);
- (void)n;
- v(n->m_methods_up.get());
- return;
- }
- case eKeyValueExpr:
- {
- GoASTKeyValueExpr *n = llvm::cast<GoASTKeyValueExpr>(this);
- (void)n;
- v(n->m_key_up.get());
- v(n->m_value_up.get());
- return;
- }
- case eLabeledStmt:
- {
- GoASTLabeledStmt *n = llvm::cast<GoASTLabeledStmt>(this);
- (void)n;
- v(n->m_label_up.get());
- v(n->m_stmt_up.get());
- return;
- }
- case eMapType:
- {
- GoASTMapType *n = llvm::cast<GoASTMapType>(this);
- (void)n;
- v(n->m_key_up.get());
- v(n->m_value_up.get());
- return;
- }
- case eParenExpr:
- {
- GoASTParenExpr *n = llvm::cast<GoASTParenExpr>(this);
- (void)n;
- v(n->m_x_up.get());
- return;
- }
- case eRangeStmt:
- {
- GoASTRangeStmt *n = llvm::cast<GoASTRangeStmt>(this);
- (void)n;
- v(n->m_key_up.get());
- v(n->m_value_up.get());
- v(n->m_x_up.get());
- v(n->m_body_up.get());
- return;
- }
- case eReturnStmt:
- {
- GoASTReturnStmt *n = llvm::cast<GoASTReturnStmt>(this);
- (void)n;
- for (auto& e : n->m_results) { v(e.get()); }
- return;
- }
- case eSelectStmt:
- {
- GoASTSelectStmt *n = llvm::cast<GoASTSelectStmt>(this);
- (void)n;
- v(n->m_body_up.get());
- return;
- }
- case eSelectorExpr:
- {
- GoASTSelectorExpr *n = llvm::cast<GoASTSelectorExpr>(this);
- (void)n;
- v(n->m_x_up.get());
- v(n->m_sel_up.get());
- return;
- }
- case eSendStmt:
- {
- GoASTSendStmt *n = llvm::cast<GoASTSendStmt>(this);
- (void)n;
- v(n->m_chan_up.get());
- v(n->m_value_up.get());
- return;
- }
- case eSliceExpr:
- {
- GoASTSliceExpr *n = llvm::cast<GoASTSliceExpr>(this);
- (void)n;
- v(n->m_x_up.get());
- v(n->m_low_up.get());
- v(n->m_high_up.get());
- v(n->m_max_up.get());
- return;
- }
- case eStarExpr:
- {
- GoASTStarExpr *n = llvm::cast<GoASTStarExpr>(this);
- (void)n;
- v(n->m_x_up.get());
- return;
- }
- case eStructType:
- {
- GoASTStructType *n = llvm::cast<GoASTStructType>(this);
- (void)n;
- v(n->m_fields_up.get());
- return;
- }
- case eSwitchStmt:
- {
- GoASTSwitchStmt *n = llvm::cast<GoASTSwitchStmt>(this);
- (void)n;
- v(n->m_init_up.get());
- v(n->m_tag_up.get());
- v(n->m_body_up.get());
- return;
- }
- case eTypeAssertExpr:
- {
- GoASTTypeAssertExpr *n = llvm::cast<GoASTTypeAssertExpr>(this);
- (void)n;
- v(n->m_x_up.get());
- v(n->m_type_up.get());
- return;
- }
- case eTypeSpec:
- {
- GoASTTypeSpec *n = llvm::cast<GoASTTypeSpec>(this);
- (void)n;
- v(n->m_name_up.get());
- v(n->m_type_up.get());
- return;
- }
- case eTypeSwitchStmt:
- {
- GoASTTypeSwitchStmt *n = llvm::cast<GoASTTypeSwitchStmt>(this);
- (void)n;
- v(n->m_init_up.get());
- v(n->m_assign_up.get());
- v(n->m_body_up.get());
- return;
- }
- case eUnaryExpr:
- {
- GoASTUnaryExpr *n = llvm::cast<GoASTUnaryExpr>(this);
- (void)n;
- v(n->m_x_up.get());
- return;
- }
- case eValueSpec:
- {
- GoASTValueSpec *n = llvm::cast<GoASTValueSpec>(this);
- (void)n;
- for (auto& e : n->m_names) { v(e.get()); }
- v(n->m_type_up.get());
- for (auto& e : n->m_values) { v(e.get()); }
- return;
- }
-
- case eEmptyStmt:
- case eBadDecl:
- case eBadExpr:
- case eBadStmt:
- break;
- }
+template <typename V> void GoASTNode::WalkChildren(V &v) {
+ switch (m_kind) {
+
+ case eArrayType: {
+ GoASTArrayType *n = llvm::cast<GoASTArrayType>(this);
+ (void)n;
+ v(n->m_len_up.get());
+ v(n->m_elt_up.get());
+ return;
+ }
+ case eAssignStmt: {
+ GoASTAssignStmt *n = llvm::cast<GoASTAssignStmt>(this);
+ (void)n;
+ for (auto &e : n->m_lhs) {
+ v(e.get());
+ }
+ for (auto &e : n->m_rhs) {
+ v(e.get());
+ }
+ return;
+ }
+ case eBasicLit: {
+ GoASTBasicLit *n = llvm::cast<GoASTBasicLit>(this);
+ (void)n;
+ return;
+ }
+ case eBinaryExpr: {
+ GoASTBinaryExpr *n = llvm::cast<GoASTBinaryExpr>(this);
+ (void)n;
+ v(n->m_x_up.get());
+ v(n->m_y_up.get());
+ return;
+ }
+ case eBlockStmt: {
+ GoASTBlockStmt *n = llvm::cast<GoASTBlockStmt>(this);
+ (void)n;
+ for (auto &e : n->m_list) {
+ v(e.get());
+ }
+ return;
+ }
+ case eIdent: {
+ GoASTIdent *n = llvm::cast<GoASTIdent>(this);
+ (void)n;
+ return;
+ }
+ case eBranchStmt: {
+ GoASTBranchStmt *n = llvm::cast<GoASTBranchStmt>(this);
+ (void)n;
+ v(n->m_label_up.get());
+ return;
+ }
+ case eCallExpr: {
+ GoASTCallExpr *n = llvm::cast<GoASTCallExpr>(this);
+ (void)n;
+ v(n->m_fun_up.get());
+ for (auto &e : n->m_args) {
+ v(e.get());
+ }
+ return;
+ }
+ case eCaseClause: {
+ GoASTCaseClause *n = llvm::cast<GoASTCaseClause>(this);
+ (void)n;
+ for (auto &e : n->m_list) {
+ v(e.get());
+ }
+ for (auto &e : n->m_body) {
+ v(e.get());
+ }
+ return;
+ }
+ case eChanType: {
+ GoASTChanType *n = llvm::cast<GoASTChanType>(this);
+ (void)n;
+ v(n->m_value_up.get());
+ return;
+ }
+ case eCommClause: {
+ GoASTCommClause *n = llvm::cast<GoASTCommClause>(this);
+ (void)n;
+ v(n->m_comm_up.get());
+ for (auto &e : n->m_body) {
+ v(e.get());
+ }
+ return;
+ }
+ case eCompositeLit: {
+ GoASTCompositeLit *n = llvm::cast<GoASTCompositeLit>(this);
+ (void)n;
+ v(n->m_type_up.get());
+ for (auto &e : n->m_elts) {
+ v(e.get());
+ }
+ return;
+ }
+ case eDeclStmt: {
+ GoASTDeclStmt *n = llvm::cast<GoASTDeclStmt>(this);
+ (void)n;
+ v(n->m_decl_up.get());
+ return;
+ }
+ case eDeferStmt: {
+ GoASTDeferStmt *n = llvm::cast<GoASTDeferStmt>(this);
+ (void)n;
+ v(n->m_call_up.get());
+ return;
+ }
+ case eEllipsis: {
+ GoASTEllipsis *n = llvm::cast<GoASTEllipsis>(this);
+ (void)n;
+ v(n->m_elt_up.get());
+ return;
+ }
+ case eExprStmt: {
+ GoASTExprStmt *n = llvm::cast<GoASTExprStmt>(this);
+ (void)n;
+ v(n->m_x_up.get());
+ return;
+ }
+ case eField: {
+ GoASTField *n = llvm::cast<GoASTField>(this);
+ (void)n;
+ for (auto &e : n->m_names) {
+ v(e.get());
+ }
+ v(n->m_type_up.get());
+ v(n->m_tag_up.get());
+ return;
+ }
+ case eFieldList: {
+ GoASTFieldList *n = llvm::cast<GoASTFieldList>(this);
+ (void)n;
+ for (auto &e : n->m_list) {
+ v(e.get());
+ }
+ return;
+ }
+ case eForStmt: {
+ GoASTForStmt *n = llvm::cast<GoASTForStmt>(this);
+ (void)n;
+ v(n->m_init_up.get());
+ v(n->m_cond_up.get());
+ v(n->m_post_up.get());
+ v(n->m_body_up.get());
+ return;
+ }
+ case eFuncType: {
+ GoASTFuncType *n = llvm::cast<GoASTFuncType>(this);
+ (void)n;
+ v(n->m_params_up.get());
+ v(n->m_results_up.get());
+ return;
+ }
+ case eFuncDecl: {
+ GoASTFuncDecl *n = llvm::cast<GoASTFuncDecl>(this);
+ (void)n;
+ v(n->m_recv_up.get());
+ v(n->m_name_up.get());
+ v(n->m_type_up.get());
+ v(n->m_body_up.get());
+ return;
+ }
+ case eFuncLit: {
+ GoASTFuncLit *n = llvm::cast<GoASTFuncLit>(this);
+ (void)n;
+ v(n->m_type_up.get());
+ v(n->m_body_up.get());
+ return;
+ }
+ case eGenDecl: {
+ GoASTGenDecl *n = llvm::cast<GoASTGenDecl>(this);
+ (void)n;
+ for (auto &e : n->m_specs) {
+ v(e.get());
+ }
+ return;
+ }
+ case eGoStmt: {
+ GoASTGoStmt *n = llvm::cast<GoASTGoStmt>(this);
+ (void)n;
+ v(n->m_call_up.get());
+ return;
+ }
+ case eIfStmt: {
+ GoASTIfStmt *n = llvm::cast<GoASTIfStmt>(this);
+ (void)n;
+ v(n->m_init_up.get());
+ v(n->m_cond_up.get());
+ v(n->m_body_up.get());
+ v(n->m_els_up.get());
+ return;
+ }
+ case eImportSpec: {
+ GoASTImportSpec *n = llvm::cast<GoASTImportSpec>(this);
+ (void)n;
+ v(n->m_name_up.get());
+ v(n->m_path_up.get());
+ return;
+ }
+ case eIncDecStmt: {
+ GoASTIncDecStmt *n = llvm::cast<GoASTIncDecStmt>(this);
+ (void)n;
+ v(n->m_x_up.get());
+ return;
+ }
+ case eIndexExpr: {
+ GoASTIndexExpr *n = llvm::cast<GoASTIndexExpr>(this);
+ (void)n;
+ v(n->m_x_up.get());
+ v(n->m_index_up.get());
+ return;
+ }
+ case eInterfaceType: {
+ GoASTInterfaceType *n = llvm::cast<GoASTInterfaceType>(this);
+ (void)n;
+ v(n->m_methods_up.get());
+ return;
+ }
+ case eKeyValueExpr: {
+ GoASTKeyValueExpr *n = llvm::cast<GoASTKeyValueExpr>(this);
+ (void)n;
+ v(n->m_key_up.get());
+ v(n->m_value_up.get());
+ return;
+ }
+ case eLabeledStmt: {
+ GoASTLabeledStmt *n = llvm::cast<GoASTLabeledStmt>(this);
+ (void)n;
+ v(n->m_label_up.get());
+ v(n->m_stmt_up.get());
+ return;
+ }
+ case eMapType: {
+ GoASTMapType *n = llvm::cast<GoASTMapType>(this);
+ (void)n;
+ v(n->m_key_up.get());
+ v(n->m_value_up.get());
+ return;
+ }
+ case eParenExpr: {
+ GoASTParenExpr *n = llvm::cast<GoASTParenExpr>(this);
+ (void)n;
+ v(n->m_x_up.get());
+ return;
+ }
+ case eRangeStmt: {
+ GoASTRangeStmt *n = llvm::cast<GoASTRangeStmt>(this);
+ (void)n;
+ v(n->m_key_up.get());
+ v(n->m_value_up.get());
+ v(n->m_x_up.get());
+ v(n->m_body_up.get());
+ return;
+ }
+ case eReturnStmt: {
+ GoASTReturnStmt *n = llvm::cast<GoASTReturnStmt>(this);
+ (void)n;
+ for (auto &e : n->m_results) {
+ v(e.get());
+ }
+ return;
+ }
+ case eSelectStmt: {
+ GoASTSelectStmt *n = llvm::cast<GoASTSelectStmt>(this);
+ (void)n;
+ v(n->m_body_up.get());
+ return;
+ }
+ case eSelectorExpr: {
+ GoASTSelectorExpr *n = llvm::cast<GoASTSelectorExpr>(this);
+ (void)n;
+ v(n->m_x_up.get());
+ v(n->m_sel_up.get());
+ return;
+ }
+ case eSendStmt: {
+ GoASTSendStmt *n = llvm::cast<GoASTSendStmt>(this);
+ (void)n;
+ v(n->m_chan_up.get());
+ v(n->m_value_up.get());
+ return;
+ }
+ case eSliceExpr: {
+ GoASTSliceExpr *n = llvm::cast<GoASTSliceExpr>(this);
+ (void)n;
+ v(n->m_x_up.get());
+ v(n->m_low_up.get());
+ v(n->m_high_up.get());
+ v(n->m_max_up.get());
+ return;
+ }
+ case eStarExpr: {
+ GoASTStarExpr *n = llvm::cast<GoASTStarExpr>(this);
+ (void)n;
+ v(n->m_x_up.get());
+ return;
+ }
+ case eStructType: {
+ GoASTStructType *n = llvm::cast<GoASTStructType>(this);
+ (void)n;
+ v(n->m_fields_up.get());
+ return;
+ }
+ case eSwitchStmt: {
+ GoASTSwitchStmt *n = llvm::cast<GoASTSwitchStmt>(this);
+ (void)n;
+ v(n->m_init_up.get());
+ v(n->m_tag_up.get());
+ v(n->m_body_up.get());
+ return;
+ }
+ case eTypeAssertExpr: {
+ GoASTTypeAssertExpr *n = llvm::cast<GoASTTypeAssertExpr>(this);
+ (void)n;
+ v(n->m_x_up.get());
+ v(n->m_type_up.get());
+ return;
+ }
+ case eTypeSpec: {
+ GoASTTypeSpec *n = llvm::cast<GoASTTypeSpec>(this);
+ (void)n;
+ v(n->m_name_up.get());
+ v(n->m_type_up.get());
+ return;
+ }
+ case eTypeSwitchStmt: {
+ GoASTTypeSwitchStmt *n = llvm::cast<GoASTTypeSwitchStmt>(this);
+ (void)n;
+ v(n->m_init_up.get());
+ v(n->m_assign_up.get());
+ v(n->m_body_up.get());
+ return;
+ }
+ case eUnaryExpr: {
+ GoASTUnaryExpr *n = llvm::cast<GoASTUnaryExpr>(this);
+ (void)n;
+ v(n->m_x_up.get());
+ return;
+ }
+ case eValueSpec: {
+ GoASTValueSpec *n = llvm::cast<GoASTValueSpec>(this);
+ (void)n;
+ for (auto &e : n->m_names) {
+ v(e.get());
+ }
+ v(n->m_type_up.get());
+ for (auto &e : n->m_values) {
+ v(e.get());
+ }
+ return;
+ }
+
+ case eEmptyStmt:
+ case eBadDecl:
+ case eBadExpr:
+ case eBadStmt:
+ break;
+ }
}
-} // namespace lldb_private
+} // namespace lldb_private
#endif
-
diff --git a/lldb/source/Plugins/ExpressionParser/Go/GoLexer.cpp b/lldb/source/Plugins/ExpressionParser/Go/GoLexer.cpp
index 6de0f5619ca..63e267eaadc 100644
--- a/lldb/source/Plugins/ExpressionParser/Go/GoLexer.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Go/GoLexer.cpp
@@ -15,388 +15,336 @@ using namespace lldb_private;
llvm::StringMap<GoLexer::TokenType> *GoLexer::m_keywords;
-GoLexer::GoLexer(const char *src) : m_src(src), m_end(src + strlen(src)), m_last_token(TOK_INVALID, "")
-{
-}
+GoLexer::GoLexer(const char *src)
+ : m_src(src), m_end(src + strlen(src)), m_last_token(TOK_INVALID, "") {}
-bool
-GoLexer::SkipWhitespace()
-{
- bool saw_newline = false;
- for (; m_src < m_end; ++m_src)
- {
- if (*m_src == '\n')
- saw_newline = true;
- if (*m_src == '/' && !SkipComment())
- return saw_newline;
- else if (!IsWhitespace(*m_src))
- return saw_newline;
- }
- return saw_newline;
+bool GoLexer::SkipWhitespace() {
+ bool saw_newline = false;
+ for (; m_src < m_end; ++m_src) {
+ if (*m_src == '\n')
+ saw_newline = true;
+ if (*m_src == '/' && !SkipComment())
+ return saw_newline;
+ else if (!IsWhitespace(*m_src))
+ return saw_newline;
+ }
+ return saw_newline;
}
-bool
-GoLexer::SkipComment()
-{
- if (m_src[0] == '/' && m_src[1] == '/')
- {
- for (const char *c = m_src + 2; c < m_end; ++c)
- {
- if (*c == '\n')
- {
- m_src = c - 1;
- return true;
- }
- }
+bool GoLexer::SkipComment() {
+ if (m_src[0] == '/' && m_src[1] == '/') {
+ for (const char *c = m_src + 2; c < m_end; ++c) {
+ if (*c == '\n') {
+ m_src = c - 1;
return true;
+ }
}
- else if (m_src[0] == '/' && m_src[1] == '*')
- {
- for (const char *c = m_src + 2; c < m_end; ++c)
- {
- if (c[0] == '*' && c[1] == '/')
- {
- m_src = c + 1;
- return true;
- }
- }
+ return true;
+ } else if (m_src[0] == '/' && m_src[1] == '*') {
+ for (const char *c = m_src + 2; c < m_end; ++c) {
+ if (c[0] == '*' && c[1] == '/') {
+ m_src = c + 1;
+ return true;
+ }
}
- return false;
+ }
+ return false;
}
-const GoLexer::Token &
-GoLexer::Lex()
-{
- bool newline = SkipWhitespace();
- const char *start = m_src;
- m_last_token.m_type = InternalLex(newline);
- m_last_token.m_value = llvm::StringRef(start, m_src - start);
- return m_last_token;
+const GoLexer::Token &GoLexer::Lex() {
+ bool newline = SkipWhitespace();
+ const char *start = m_src;
+ m_last_token.m_type = InternalLex(newline);
+ m_last_token.m_value = llvm::StringRef(start, m_src - start);
+ return m_last_token;
}
-GoLexer::TokenType
-GoLexer::InternalLex(bool newline)
-{
- if (m_src >= m_end)
- {
- return TOK_EOF;
- }
- if (newline)
- {
- switch (m_last_token.m_type)
- {
- case TOK_IDENTIFIER:
- case LIT_FLOAT:
- case LIT_IMAGINARY:
- case LIT_INTEGER:
- case LIT_RUNE:
- case LIT_STRING:
- case KEYWORD_BREAK:
- case KEYWORD_CONTINUE:
- case KEYWORD_FALLTHROUGH:
- case KEYWORD_RETURN:
- case OP_PLUS_PLUS:
- case OP_MINUS_MINUS:
- case OP_RPAREN:
- case OP_RBRACK:
- case OP_RBRACE:
- return OP_SEMICOLON;
- default:
- break;
- }
+GoLexer::TokenType GoLexer::InternalLex(bool newline) {
+ if (m_src >= m_end) {
+ return TOK_EOF;
+ }
+ if (newline) {
+ switch (m_last_token.m_type) {
+ case TOK_IDENTIFIER:
+ case LIT_FLOAT:
+ case LIT_IMAGINARY:
+ case LIT_INTEGER:
+ case LIT_RUNE:
+ case LIT_STRING:
+ case KEYWORD_BREAK:
+ case KEYWORD_CONTINUE:
+ case KEYWORD_FALLTHROUGH:
+ case KEYWORD_RETURN:
+ case OP_PLUS_PLUS:
+ case OP_MINUS_MINUS:
+ case OP_RPAREN:
+ case OP_RBRACK:
+ case OP_RBRACE:
+ return OP_SEMICOLON;
+ default:
+ break;
}
- char c = *m_src;
- switch (c)
- {
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- return DoNumber();
- case '+':
- case '-':
- case '*':
- case '/':
- case '%':
- case '&':
- case '|':
- case '^':
- case '<':
- case '>':
- case '!':
- case ':':
- case ';':
- case '(':
- case ')':
- case '[':
- case ']':
- case '{':
- case '}':
- case ',':
- case '=':
- return DoOperator();
- case '.':
- if (IsDecimal(m_src[1]))
- return DoNumber();
- return DoOperator();
- case '$':
- // For lldb persistent vars.
- return DoIdent();
- case '"':
- case '`':
- return DoString();
- case '\'':
- return DoRune();
- default:
- break;
- }
- if (IsLetterOrDigit(c))
- return DoIdent();
+ }
+ char c = *m_src;
+ switch (c) {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ return DoNumber();
+ case '+':
+ case '-':
+ case '*':
+ case '/':
+ case '%':
+ case '&':
+ case '|':
+ case '^':
+ case '<':
+ case '>':
+ case '!':
+ case ':':
+ case ';':
+ case '(':
+ case ')':
+ case '[':
+ case ']':
+ case '{':
+ case '}':
+ case ',':
+ case '=':
+ return DoOperator();
+ case '.':
+ if (IsDecimal(m_src[1]))
+ return DoNumber();
+ return DoOperator();
+ case '$':
+ // For lldb persistent vars.
+ return DoIdent();
+ case '"':
+ case '`':
+ return DoString();
+ case '\'':
+ return DoRune();
+ default:
+ break;
+ }
+ if (IsLetterOrDigit(c))
+ return DoIdent();
+ ++m_src;
+ return TOK_INVALID;
+}
+
+GoLexer::TokenType GoLexer::DoOperator() {
+ TokenType t = TOK_INVALID;
+ if (m_end - m_src > 2) {
+ t = LookupKeyword(llvm::StringRef(m_src, 3));
+ if (t != TOK_INVALID)
+ m_src += 3;
+ }
+ if (t == TOK_INVALID && m_end - m_src > 1) {
+ t = LookupKeyword(llvm::StringRef(m_src, 2));
+ if (t != TOK_INVALID)
+ m_src += 2;
+ }
+ if (t == TOK_INVALID) {
+ t = LookupKeyword(llvm::StringRef(m_src, 1));
++m_src;
- return TOK_INVALID;
+ }
+ return t;
}
-GoLexer::TokenType
-GoLexer::DoOperator()
-{
- TokenType t = TOK_INVALID;
- if (m_end - m_src > 2)
- {
- t = LookupKeyword(llvm::StringRef(m_src, 3));
- if (t != TOK_INVALID)
- m_src += 3;
- }
- if (t == TOK_INVALID && m_end - m_src > 1)
- {
- t = LookupKeyword(llvm::StringRef(m_src, 2));
- if (t != TOK_INVALID)
- m_src += 2;
- }
- if (t == TOK_INVALID)
- {
- t = LookupKeyword(llvm::StringRef(m_src, 1));
- ++m_src;
- }
- return t;
+GoLexer::TokenType GoLexer::DoIdent() {
+ const char *start = m_src++;
+ while (m_src < m_end && IsLetterOrDigit(*m_src)) {
+ ++m_src;
+ }
+ TokenType kw = LookupKeyword(llvm::StringRef(start, m_src - start));
+ if (kw != TOK_INVALID)
+ return kw;
+ return TOK_IDENTIFIER;
}
-GoLexer::TokenType
-GoLexer::DoIdent()
-{
- const char *start = m_src++;
- while (m_src < m_end && IsLetterOrDigit(*m_src))
- {
+GoLexer::TokenType GoLexer::DoNumber() {
+ if (m_src[0] == '0' && (m_src[1] == 'x' || m_src[1] == 'X')) {
+ m_src += 2;
+ while (IsHexChar(*m_src))
+ ++m_src;
+ return LIT_INTEGER;
+ }
+ bool dot_ok = true;
+ bool e_ok = true;
+ while (true) {
+ while (IsDecimal(*m_src))
+ ++m_src;
+ switch (*m_src) {
+ case 'i':
+ ++m_src;
+ return LIT_IMAGINARY;
+ case '.':
+ if (!dot_ok)
+ return LIT_FLOAT;
+ ++m_src;
+ dot_ok = false;
+ break;
+ case 'e':
+ case 'E':
+ if (!e_ok)
+ return LIT_FLOAT;
+ dot_ok = e_ok = false;
+ ++m_src;
+ if (*m_src == '+' || *m_src == '-')
++m_src;
+ break;
+ default:
+ if (dot_ok)
+ return LIT_INTEGER;
+ return LIT_FLOAT;
}
- TokenType kw = LookupKeyword(llvm::StringRef(start, m_src - start));
- if (kw != TOK_INVALID)
- return kw;
- return TOK_IDENTIFIER;
+ }
}
-GoLexer::TokenType
-GoLexer::DoNumber()
-{
- if (m_src[0] == '0' && (m_src[1] == 'x' || m_src[1] == 'X'))
- {
- m_src += 2;
- while (IsHexChar(*m_src))
- ++m_src;
- return LIT_INTEGER;
- }
- bool dot_ok = true;
- bool e_ok = true;
- while (true)
- {
- while (IsDecimal(*m_src))
- ++m_src;
- switch (*m_src)
- {
- case 'i':
- ++m_src;
- return LIT_IMAGINARY;
- case '.':
- if (!dot_ok)
- return LIT_FLOAT;
- ++m_src;
- dot_ok = false;
- break;
- case 'e':
- case 'E':
- if (!e_ok)
- return LIT_FLOAT;
- dot_ok = e_ok = false;
- ++m_src;
- if (*m_src == '+' || *m_src == '-')
- ++m_src;
- break;
- default:
- if (dot_ok)
- return LIT_INTEGER;
- return LIT_FLOAT;
- }
+GoLexer::TokenType GoLexer::DoRune() {
+ while (++m_src < m_end) {
+ switch (*m_src) {
+ case '\'':
+ ++m_src;
+ return LIT_RUNE;
+ case '\n':
+ return TOK_INVALID;
+ case '\\':
+ if (m_src[1] == '\n')
+ return TOK_INVALID;
+ ++m_src;
}
+ }
+ return TOK_INVALID;
}
-GoLexer::TokenType
-GoLexer::DoRune()
-{
- while (++m_src < m_end)
- {
- switch (*m_src)
- {
- case '\'':
- ++m_src;
- return LIT_RUNE;
- case '\n':
- return TOK_INVALID;
- case '\\':
- if (m_src[1] == '\n')
- return TOK_INVALID;
- ++m_src;
- }
+GoLexer::TokenType GoLexer::DoString() {
+ if (*m_src == '`') {
+ while (++m_src < m_end) {
+ if (*m_src == '`') {
+ ++m_src;
+ return LIT_STRING;
+ }
}
return TOK_INVALID;
-}
-
-GoLexer::TokenType
-GoLexer::DoString()
-{
- if (*m_src == '`')
- {
- while (++m_src < m_end)
- {
- if (*m_src == '`')
- {
- ++m_src;
- return LIT_STRING;
- }
- }
+ }
+ while (++m_src < m_end) {
+ switch (*m_src) {
+ case '"':
+ ++m_src;
+ return LIT_STRING;
+ case '\n':
+ return TOK_INVALID;
+ case '\\':
+ if (m_src[1] == '\n')
return TOK_INVALID;
+ ++m_src;
}
- while (++m_src < m_end)
- {
- switch (*m_src)
- {
- case '"':
- ++m_src;
- return LIT_STRING;
- case '\n':
- return TOK_INVALID;
- case '\\':
- if (m_src[1] == '\n')
- return TOK_INVALID;
- ++m_src;
- }
- }
- return TOK_INVALID;
+ }
+ return TOK_INVALID;
}
-GoLexer::TokenType
-GoLexer::LookupKeyword(llvm::StringRef id)
-{
- if (m_keywords == nullptr)
- m_keywords = InitKeywords();
- const auto &it = m_keywords->find(id);
- if (it == m_keywords->end())
- return TOK_INVALID;
- return it->second;
+GoLexer::TokenType GoLexer::LookupKeyword(llvm::StringRef id) {
+ if (m_keywords == nullptr)
+ m_keywords = InitKeywords();
+ const auto &it = m_keywords->find(id);
+ if (it == m_keywords->end())
+ return TOK_INVALID;
+ return it->second;
}
-llvm::StringRef
-GoLexer::LookupToken(TokenType t)
-{
- if (m_keywords == nullptr)
- m_keywords = InitKeywords();
- for (const auto &e : *m_keywords)
- {
- if (e.getValue() == t)
- return e.getKey();
- }
- return "";
+llvm::StringRef GoLexer::LookupToken(TokenType t) {
+ if (m_keywords == nullptr)
+ m_keywords = InitKeywords();
+ for (const auto &e : *m_keywords) {
+ if (e.getValue() == t)
+ return e.getKey();
+ }
+ return "";
}
-llvm::StringMap<GoLexer::TokenType> *
-GoLexer::InitKeywords()
-{
- auto &result = *new llvm::StringMap<TokenType>(128);
- result["break"] = KEYWORD_BREAK;
- result["default"] = KEYWORD_DEFAULT;
- result["func"] = KEYWORD_FUNC;
- result["interface"] = KEYWORD_INTERFACE;
- result["select"] = KEYWORD_SELECT;
- result["case"] = KEYWORD_CASE;
- result["defer"] = KEYWORD_DEFER;
- result["go"] = KEYWORD_GO;
- result["map"] = KEYWORD_MAP;
- result["struct"] = KEYWORD_STRUCT;
- result["chan"] = KEYWORD_CHAN;
- result["else"] = KEYWORD_ELSE;
- result["goto"] = KEYWORD_GOTO;
- result["package"] = KEYWORD_PACKAGE;
- result["switch"] = KEYWORD_SWITCH;
- result["const"] = KEYWORD_CONST;
- result["fallthrough"] = KEYWORD_FALLTHROUGH;
- result["if"] = KEYWORD_IF;
- result["range"] = KEYWORD_RANGE;
- result["type"] = KEYWORD_TYPE;
- result["continue"] = KEYWORD_CONTINUE;
- result["for"] = KEYWORD_FOR;
- result["import"] = KEYWORD_IMPORT;
- result["return"] = KEYWORD_RETURN;
- result["var"] = KEYWORD_VAR;
- result["+"] = OP_PLUS;
- result["-"] = OP_MINUS;
- result["*"] = OP_STAR;
- result["/"] = OP_SLASH;
- result["%"] = OP_PERCENT;
- result["&"] = OP_AMP;
- result["|"] = OP_PIPE;
- result["^"] = OP_CARET;
- result["<<"] = OP_LSHIFT;
- result[">>"] = OP_RSHIFT;
- result["&^"] = OP_AMP_CARET;
- result["+="] = OP_PLUS_EQ;
- result["-="] = OP_MINUS_EQ;
- result["*="] = OP_STAR_EQ;
- result["/="] = OP_SLASH_EQ;
- result["%="] = OP_PERCENT_EQ;
- result["&="] = OP_AMP_EQ;
- result["|="] = OP_PIPE_EQ;
- result["^="] = OP_CARET_EQ;
- result["<<="] = OP_LSHIFT_EQ;
- result[">>="] = OP_RSHIFT_EQ;
- result["&^="] = OP_AMP_CARET_EQ;
- result["&&"] = OP_AMP_AMP;
- result["||"] = OP_PIPE_PIPE;
- result["<-"] = OP_LT_MINUS;
- result["++"] = OP_PLUS_PLUS;
- result["--"] = OP_MINUS_MINUS;
- result["=="] = OP_EQ_EQ;
- result["<"] = OP_LT;
- result[">"] = OP_GT;
- result["="] = OP_EQ;
- result["!"] = OP_BANG;
- result["!="] = OP_BANG_EQ;
- result["<="] = OP_LT_EQ;
- result[">="] = OP_GT_EQ;
- result[":="] = OP_COLON_EQ;
- result["..."] = OP_DOTS;
- result["("] = OP_LPAREN;
- result["["] = OP_LBRACK;
- result["{"] = OP_LBRACE;
- result[","] = OP_COMMA;
- result["."] = OP_DOT;
- result[")"] = OP_RPAREN;
- result["]"] = OP_RBRACK;
- result["}"] = OP_RBRACE;
- result[";"] = OP_SEMICOLON;
- result[":"] = OP_COLON;
- return &result;
+llvm::StringMap<GoLexer::TokenType> *GoLexer::InitKeywords() {
+ auto &result = *new llvm::StringMap<TokenType>(128);
+ result["break"] = KEYWORD_BREAK;
+ result["default"] = KEYWORD_DEFAULT;
+ result["func"] = KEYWORD_FUNC;
+ result["interface"] = KEYWORD_INTERFACE;
+ result["select"] = KEYWORD_SELECT;
+ result["case"] = KEYWORD_CASE;
+ result["defer"] = KEYWORD_DEFER;
+ result["go"] = KEYWORD_GO;
+ result["map"] = KEYWORD_MAP;
+ result["struct"] = KEYWORD_STRUCT;
+ result["chan"] = KEYWORD_CHAN;
+ result["else"] = KEYWORD_ELSE;
+ result["goto"] = KEYWORD_GOTO;
+ result["package"] = KEYWORD_PACKAGE;
+ result["switch"] = KEYWORD_SWITCH;
+ result["const"] = KEYWORD_CONST;
+ result["fallthrough"] = KEYWORD_FALLTHROUGH;
+ result["if"] = KEYWORD_IF;
+ result["range"] = KEYWORD_RANGE;
+ result["type"] = KEYWORD_TYPE;
+ result["continue"] = KEYWORD_CONTINUE;
+ result["for"] = KEYWORD_FOR;
+ result["import"] = KEYWORD_IMPORT;
+ result["return"] = KEYWORD_RETURN;
+ result["var"] = KEYWORD_VAR;
+ result["+"] = OP_PLUS;
+ result["-"] = OP_MINUS;
+ result["*"] = OP_STAR;
+ result["/"] = OP_SLASH;
+ result["%"] = OP_PERCENT;
+ result["&"] = OP_AMP;
+ result["|"] = OP_PIPE;
+ result["^"] = OP_CARET;
+ result["<<"] = OP_LSHIFT;
+ result[">>"] = OP_RSHIFT;
+ result["&^"] = OP_AMP_CARET;
+ result["+="] = OP_PLUS_EQ;
+ result["-="] = OP_MINUS_EQ;
+ result["*="] = OP_STAR_EQ;
+ result["/="] = OP_SLASH_EQ;
+ result["%="] = OP_PERCENT_EQ;
+ result["&="] = OP_AMP_EQ;
+ result["|="] = OP_PIPE_EQ;
+ result["^="] = OP_CARET_EQ;
+ result["<<="] = OP_LSHIFT_EQ;
+ result[">>="] = OP_RSHIFT_EQ;
+ result["&^="] = OP_AMP_CARET_EQ;
+ result["&&"] = OP_AMP_AMP;
+ result["||"] = OP_PIPE_PIPE;
+ result["<-"] = OP_LT_MINUS;
+ result["++"] = OP_PLUS_PLUS;
+ result["--"] = OP_MINUS_MINUS;
+ result["=="] = OP_EQ_EQ;
+ result["<"] = OP_LT;
+ result[">"] = OP_GT;
+ result["="] = OP_EQ;
+ result["!"] = OP_BANG;
+ result["!="] = OP_BANG_EQ;
+ result["<="] = OP_LT_EQ;
+ result[">="] = OP_GT_EQ;
+ result[":="] = OP_COLON_EQ;
+ result["..."] = OP_DOTS;
+ result["("] = OP_LPAREN;
+ result["["] = OP_LBRACK;
+ result["{"] = OP_LBRACE;
+ result[","] = OP_COMMA;
+ result["."] = OP_DOT;
+ result[")"] = OP_RPAREN;
+ result["]"] = OP_RBRACK;
+ result["}"] = OP_RBRACE;
+ result[";"] = OP_SEMICOLON;
+ result[":"] = OP_COLON;
+ return &result;
}
diff --git a/lldb/source/Plugins/ExpressionParser/Go/GoLexer.h b/lldb/source/Plugins/ExpressionParser/Go/GoLexer.h
index e8e1635bab7..f0b5b336fbe 100644
--- a/lldb/source/Plugins/ExpressionParser/Go/GoLexer.h
+++ b/lldb/source/Plugins/ExpressionParser/Go/GoLexer.h
@@ -10,190 +10,170 @@
#ifndef liblldb_GoLexer_h
#define liblldb_GoLexer_h
-#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
-namespace lldb_private
-{
-
-class GoLexer
-{
- public:
- explicit GoLexer(const char *src);
-
- enum TokenType
- {
- TOK_EOF,
- TOK_INVALID,
- TOK_IDENTIFIER,
- LIT_INTEGER,
- LIT_FLOAT,
- LIT_IMAGINARY,
- LIT_RUNE,
- LIT_STRING,
- KEYWORD_BREAK,
- KEYWORD_DEFAULT,
- KEYWORD_FUNC,
- KEYWORD_INTERFACE,
- KEYWORD_SELECT,
- KEYWORD_CASE,
- KEYWORD_DEFER,
- KEYWORD_GO,
- KEYWORD_MAP,
- KEYWORD_STRUCT,
- KEYWORD_CHAN,
- KEYWORD_ELSE,
- KEYWORD_GOTO,
- KEYWORD_PACKAGE,
- KEYWORD_SWITCH,
- KEYWORD_CONST,
- KEYWORD_FALLTHROUGH,
- KEYWORD_IF,
- KEYWORD_RANGE,
- KEYWORD_TYPE,
- KEYWORD_CONTINUE,
- KEYWORD_FOR,
- KEYWORD_IMPORT,
- KEYWORD_RETURN,
- KEYWORD_VAR,
- OP_PLUS,
- OP_MINUS,
- OP_STAR,
- OP_SLASH,
- OP_PERCENT,
- OP_AMP,
- OP_PIPE,
- OP_CARET,
- OP_LSHIFT,
- OP_RSHIFT,
- OP_AMP_CARET,
- OP_PLUS_EQ,
- OP_MINUS_EQ,
- OP_STAR_EQ,
- OP_SLASH_EQ,
- OP_PERCENT_EQ,
- OP_AMP_EQ,
- OP_PIPE_EQ,
- OP_CARET_EQ,
- OP_LSHIFT_EQ,
- OP_RSHIFT_EQ,
- OP_AMP_CARET_EQ,
- OP_AMP_AMP,
- OP_PIPE_PIPE,
- OP_LT_MINUS,
- OP_PLUS_PLUS,
- OP_MINUS_MINUS,
- OP_EQ_EQ,
- OP_LT,
- OP_GT,
- OP_EQ,
- OP_BANG,
- OP_BANG_EQ,
- OP_LT_EQ,
- OP_GT_EQ,
- OP_COLON_EQ,
- OP_DOTS,
- OP_LPAREN,
- OP_LBRACK,
- OP_LBRACE,
- OP_COMMA,
- OP_DOT,
- OP_RPAREN,
- OP_RBRACK,
- OP_RBRACE,
- OP_SEMICOLON,
- OP_COLON,
- };
-
- struct Token
- {
- explicit Token(TokenType t, llvm::StringRef text) : m_type(t), m_value(text) {}
- TokenType m_type;
- llvm::StringRef m_value;
- };
-
- const Token &Lex();
-
- size_t
- BytesRemaining() const
- {
- return m_end - m_src;
- }
- llvm::StringRef
- GetString(int len) const
- {
- return llvm::StringRef(m_src, len);
- }
-
- static TokenType LookupKeyword(llvm::StringRef id);
- static llvm::StringRef LookupToken(TokenType t);
-
- private:
- bool
- IsDecimal(char c)
- {
- return c >= '0' && c <= '9';
- }
- bool
- IsHexChar(char c)
- {
- if (c >= '0' && c <= '9')
- return true;
- if (c >= 'A' && c <= 'F')
- return true;
- if (c >= 'a' && c <= 'f')
- return true;
- return false;
- }
- bool
- IsLetterOrDigit(char c)
- {
- if (c >= 'a' && c <= 'z')
- return true;
- if (c >= 'A' && c <= 'Z')
- return true;
- if (c == '_')
- return true;
- if (c >= '0' && c <= '9')
- return true;
- // Treat all non-ascii chars as letters for simplicity.
- return 0 != (c & 0x80);
- }
- bool
- IsWhitespace(char c)
- {
- switch (c)
- {
- case ' ':
- case '\t':
- case '\r':
- return true;
- }
- return false;
+namespace lldb_private {
+
+class GoLexer {
+public:
+ explicit GoLexer(const char *src);
+
+ enum TokenType {
+ TOK_EOF,
+ TOK_INVALID,
+ TOK_IDENTIFIER,
+ LIT_INTEGER,
+ LIT_FLOAT,
+ LIT_IMAGINARY,
+ LIT_RUNE,
+ LIT_STRING,
+ KEYWORD_BREAK,
+ KEYWORD_DEFAULT,
+ KEYWORD_FUNC,
+ KEYWORD_INTERFACE,
+ KEYWORD_SELECT,
+ KEYWORD_CASE,
+ KEYWORD_DEFER,
+ KEYWORD_GO,
+ KEYWORD_MAP,
+ KEYWORD_STRUCT,
+ KEYWORD_CHAN,
+ KEYWORD_ELSE,
+ KEYWORD_GOTO,
+ KEYWORD_PACKAGE,
+ KEYWORD_SWITCH,
+ KEYWORD_CONST,
+ KEYWORD_FALLTHROUGH,
+ KEYWORD_IF,
+ KEYWORD_RANGE,
+ KEYWORD_TYPE,
+ KEYWORD_CONTINUE,
+ KEYWORD_FOR,
+ KEYWORD_IMPORT,
+ KEYWORD_RETURN,
+ KEYWORD_VAR,
+ OP_PLUS,
+ OP_MINUS,
+ OP_STAR,
+ OP_SLASH,
+ OP_PERCENT,
+ OP_AMP,
+ OP_PIPE,
+ OP_CARET,
+ OP_LSHIFT,
+ OP_RSHIFT,
+ OP_AMP_CARET,
+ OP_PLUS_EQ,
+ OP_MINUS_EQ,
+ OP_STAR_EQ,
+ OP_SLASH_EQ,
+ OP_PERCENT_EQ,
+ OP_AMP_EQ,
+ OP_PIPE_EQ,
+ OP_CARET_EQ,
+ OP_LSHIFT_EQ,
+ OP_RSHIFT_EQ,
+ OP_AMP_CARET_EQ,
+ OP_AMP_AMP,
+ OP_PIPE_PIPE,
+ OP_LT_MINUS,
+ OP_PLUS_PLUS,
+ OP_MINUS_MINUS,
+ OP_EQ_EQ,
+ OP_LT,
+ OP_GT,
+ OP_EQ,
+ OP_BANG,
+ OP_BANG_EQ,
+ OP_LT_EQ,
+ OP_GT_EQ,
+ OP_COLON_EQ,
+ OP_DOTS,
+ OP_LPAREN,
+ OP_LBRACK,
+ OP_LBRACE,
+ OP_COMMA,
+ OP_DOT,
+ OP_RPAREN,
+ OP_RBRACK,
+ OP_RBRACE,
+ OP_SEMICOLON,
+ OP_COLON,
+ };
+
+ struct Token {
+ explicit Token(TokenType t, llvm::StringRef text)
+ : m_type(t), m_value(text) {}
+ TokenType m_type;
+ llvm::StringRef m_value;
+ };
+
+ const Token &Lex();
+
+ size_t BytesRemaining() const { return m_end - m_src; }
+ llvm::StringRef GetString(int len) const {
+ return llvm::StringRef(m_src, len);
+ }
+
+ static TokenType LookupKeyword(llvm::StringRef id);
+ static llvm::StringRef LookupToken(TokenType t);
+
+private:
+ bool IsDecimal(char c) { return c >= '0' && c <= '9'; }
+ bool IsHexChar(char c) {
+ if (c >= '0' && c <= '9')
+ return true;
+ if (c >= 'A' && c <= 'F')
+ return true;
+ if (c >= 'a' && c <= 'f')
+ return true;
+ return false;
+ }
+ bool IsLetterOrDigit(char c) {
+ if (c >= 'a' && c <= 'z')
+ return true;
+ if (c >= 'A' && c <= 'Z')
+ return true;
+ if (c == '_')
+ return true;
+ if (c >= '0' && c <= '9')
+ return true;
+ // Treat all non-ascii chars as letters for simplicity.
+ return 0 != (c & 0x80);
+ }
+ bool IsWhitespace(char c) {
+ switch (c) {
+ case ' ':
+ case '\t':
+ case '\r':
+ return true;
}
+ return false;
+ }
- bool SkipWhitespace();
- bool SkipComment();
+ bool SkipWhitespace();
+ bool SkipComment();
- TokenType InternalLex(bool newline);
+ TokenType InternalLex(bool newline);
- TokenType DoOperator();
+ TokenType DoOperator();
- TokenType DoIdent();
+ TokenType DoIdent();
- TokenType DoNumber();
+ TokenType DoNumber();
- TokenType DoRune();
+ TokenType DoRune();
- TokenType DoString();
+ TokenType DoString();
- static llvm::StringMap<TokenType> *InitKeywords();
+ static llvm::StringMap<TokenType> *InitKeywords();
- static llvm::StringMap<TokenType> *m_keywords;
+ static llvm::StringMap<TokenType> *m_keywords;
- const char *m_src;
- const char *m_end;
- Token m_last_token;
+ const char *m_src;
+ const char *m_end;
+ Token m_last_token;
};
} // namespace lldb_private
diff --git a/lldb/source/Plugins/ExpressionParser/Go/GoParser.cpp b/lldb/source/Plugins/ExpressionParser/Go/GoParser.cpp
index 0f136f7e61d..327b9df43db 100644
--- a/lldb/source/Plugins/ExpressionParser/Go/GoParser.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Go/GoParser.cpp
@@ -11,1025 +11,870 @@
#include "GoParser.h"
+#include "Plugins/ExpressionParser/Go/GoAST.h"
#include "lldb/Core/Error.h"
#include "llvm/ADT/SmallString.h"
-#include "Plugins/ExpressionParser/Go/GoAST.h"
using namespace lldb_private;
using namespace lldb;
-namespace
-{
-llvm::StringRef
-DescribeToken(GoLexer::TokenType t)
-{
- switch (t)
- {
- case GoLexer::TOK_EOF:
- return "<eof>";
- case GoLexer::TOK_IDENTIFIER:
- return "identifier";
- case GoLexer::LIT_FLOAT:
- return "float";
- case GoLexer::LIT_IMAGINARY:
- return "imaginary";
- case GoLexer::LIT_INTEGER:
- return "integer";
- case GoLexer::LIT_RUNE:
- return "rune";
- case GoLexer::LIT_STRING:
- return "string";
- default:
- return GoLexer::LookupToken(t);
- }
+namespace {
+llvm::StringRef DescribeToken(GoLexer::TokenType t) {
+ switch (t) {
+ case GoLexer::TOK_EOF:
+ return "<eof>";
+ case GoLexer::TOK_IDENTIFIER:
+ return "identifier";
+ case GoLexer::LIT_FLOAT:
+ return "float";
+ case GoLexer::LIT_IMAGINARY:
+ return "imaginary";
+ case GoLexer::LIT_INTEGER:
+ return "integer";
+ case GoLexer::LIT_RUNE:
+ return "rune";
+ case GoLexer::LIT_STRING:
+ return "string";
+ default:
+ return GoLexer::LookupToken(t);
+ }
}
} // namespace
-class GoParser::Rule
-{
- public:
- Rule(llvm::StringRef name, GoParser *p) : m_name(name), m_parser(p), m_pos(p->m_pos) {}
-
- std::nullptr_t
- error()
- {
- if (!m_parser->m_failed)
- {
- // Set m_error in case this is the top level.
- if (m_parser->m_last_tok == GoLexer::TOK_INVALID)
- m_parser->m_error = m_parser->m_last;
- else
- m_parser->m_error = DescribeToken(m_parser->m_last_tok);
- // And set m_last in case it isn't.
- m_parser->m_last = m_name;
- m_parser->m_last_tok = GoLexer::TOK_INVALID;
- m_parser->m_pos = m_pos;
- }
- return nullptr;
+class GoParser::Rule {
+public:
+ Rule(llvm::StringRef name, GoParser *p)
+ : m_name(name), m_parser(p), m_pos(p->m_pos) {}
+
+ std::nullptr_t error() {
+ if (!m_parser->m_failed) {
+ // Set m_error in case this is the top level.
+ if (m_parser->m_last_tok == GoLexer::TOK_INVALID)
+ m_parser->m_error = m_parser->m_last;
+ else
+ m_parser->m_error = DescribeToken(m_parser->m_last_tok);
+ // And set m_last in case it isn't.
+ m_parser->m_last = m_name;
+ m_parser->m_last_tok = GoLexer::TOK_INVALID;
+ m_parser->m_pos = m_pos;
}
+ return nullptr;
+ }
- private:
- llvm::StringRef m_name;
- GoParser *m_parser;
- size_t m_pos;
+private:
+ llvm::StringRef m_name;
+ GoParser *m_parser;
+ size_t m_pos;
};
-GoParser::GoParser(const char *src) : m_lexer(src), m_pos(0), m_failed(false)
-{
-}
-
-GoASTStmt *
-GoParser::Statement()
-{
- Rule r("Statement", this);
- GoLexer::TokenType t = peek();
- GoASTStmt *ret = nullptr;
- switch (t)
- {
- case GoLexer::TOK_EOF:
- case GoLexer::OP_SEMICOLON:
- case GoLexer::OP_RPAREN:
- case GoLexer::OP_RBRACE:
- case GoLexer::TOK_INVALID:
- return EmptyStmt();
- case GoLexer::OP_LBRACE:
- return Block();
-
- /* TODO:
- case GoLexer::KEYWORD_GO:
- return GoStmt();
- case GoLexer::KEYWORD_RETURN:
- return ReturnStmt();
- case GoLexer::KEYWORD_BREAK:
- case GoLexer::KEYWORD_CONTINUE:
- case GoLexer::KEYWORD_GOTO:
- case GoLexer::KEYWORD_FALLTHROUGH:
- return BranchStmt();
- case GoLexer::KEYWORD_IF:
- return IfStmt();
- case GoLexer::KEYWORD_SWITCH:
- return SwitchStmt();
- case GoLexer::KEYWORD_SELECT:
- return SelectStmt();
- case GoLexer::KEYWORD_FOR:
- return ForStmt();
- case GoLexer::KEYWORD_DEFER:
- return DeferStmt();
- case GoLexer::KEYWORD_CONST:
- case GoLexer::KEYWORD_TYPE:
- case GoLexer::KEYWORD_VAR:
- return DeclStmt();
- case GoLexer::TOK_IDENTIFIER:
- if ((ret = LabeledStmt()) ||
- (ret = ShortVarDecl()))
- {
- return ret;
- }
+GoParser::GoParser(const char *src) : m_lexer(src), m_pos(0), m_failed(false) {}
+
+GoASTStmt *GoParser::Statement() {
+ Rule r("Statement", this);
+ GoLexer::TokenType t = peek();
+ GoASTStmt *ret = nullptr;
+ switch (t) {
+ case GoLexer::TOK_EOF:
+ case GoLexer::OP_SEMICOLON:
+ case GoLexer::OP_RPAREN:
+ case GoLexer::OP_RBRACE:
+ case GoLexer::TOK_INVALID:
+ return EmptyStmt();
+ case GoLexer::OP_LBRACE:
+ return Block();
+
+ /* TODO:
+case GoLexer::KEYWORD_GO:
+ return GoStmt();
+case GoLexer::KEYWORD_RETURN:
+ return ReturnStmt();
+case GoLexer::KEYWORD_BREAK:
+case GoLexer::KEYWORD_CONTINUE:
+case GoLexer::KEYWORD_GOTO:
+case GoLexer::KEYWORD_FALLTHROUGH:
+ return BranchStmt();
+case GoLexer::KEYWORD_IF:
+ return IfStmt();
+case GoLexer::KEYWORD_SWITCH:
+ return SwitchStmt();
+case GoLexer::KEYWORD_SELECT:
+ return SelectStmt();
+case GoLexer::KEYWORD_FOR:
+ return ForStmt();
+case GoLexer::KEYWORD_DEFER:
+ return DeferStmt();
+case GoLexer::KEYWORD_CONST:
+case GoLexer::KEYWORD_TYPE:
+case GoLexer::KEYWORD_VAR:
+ return DeclStmt();
+case GoLexer::TOK_IDENTIFIER:
+ if ((ret = LabeledStmt()) ||
+ (ret = ShortVarDecl()))
+ {
+ return ret;
+ }
*/
- default:
- break;
- }
- GoASTExpr *expr = Expression();
- if (expr == nullptr)
- return r.error();
- if (/*(ret = SendStmt(expr)) ||*/
- (ret = IncDecStmt(expr)) || (ret = Assignment(expr)) || (ret = ExpressionStmt(expr)))
- {
- return ret;
- }
- delete expr;
+ default:
+ break;
+ }
+ GoASTExpr *expr = Expression();
+ if (expr == nullptr)
return r.error();
-}
-
-GoASTStmt *
-GoParser::ExpressionStmt(GoASTExpr *e)
-{
- if (Semicolon())
- return new GoASTExprStmt(e);
- return nullptr;
-}
-
-GoASTStmt *
-GoParser::IncDecStmt(GoASTExpr *e)
-{
- Rule r("IncDecStmt", this);
- if (match(GoLexer::OP_PLUS_PLUS))
- return Semicolon() ? new GoASTIncDecStmt(e, GoLexer::OP_PLUS_PLUS) : r.error();
- if (match(GoLexer::OP_MINUS_MINUS))
- return Semicolon() ? new GoASTIncDecStmt(e, GoLexer::OP_MINUS_MINUS) : r.error();
+ if (/*(ret = SendStmt(expr)) ||*/
+ (ret = IncDecStmt(expr)) || (ret = Assignment(expr)) ||
+ (ret = ExpressionStmt(expr))) {
+ return ret;
+ }
+ delete expr;
+ return r.error();
+}
+
+GoASTStmt *GoParser::ExpressionStmt(GoASTExpr *e) {
+ if (Semicolon())
+ return new GoASTExprStmt(e);
+ return nullptr;
+}
+
+GoASTStmt *GoParser::IncDecStmt(GoASTExpr *e) {
+ Rule r("IncDecStmt", this);
+ if (match(GoLexer::OP_PLUS_PLUS))
+ return Semicolon() ? new GoASTIncDecStmt(e, GoLexer::OP_PLUS_PLUS)
+ : r.error();
+ if (match(GoLexer::OP_MINUS_MINUS))
+ return Semicolon() ? new GoASTIncDecStmt(e, GoLexer::OP_MINUS_MINUS)
+ : r.error();
+ return nullptr;
+}
+
+GoASTStmt *GoParser::Assignment(lldb_private::GoASTExpr *e) {
+ Rule r("Assignment", this);
+ std::vector<std::unique_ptr<GoASTExpr>> lhs;
+ for (GoASTExpr *l = MoreExpressionList(); l; l = MoreExpressionList())
+ lhs.push_back(std::unique_ptr<GoASTExpr>(l));
+ switch (peek()) {
+ case GoLexer::OP_EQ:
+ case GoLexer::OP_PLUS_EQ:
+ case GoLexer::OP_MINUS_EQ:
+ case GoLexer::OP_PIPE_EQ:
+ case GoLexer::OP_CARET_EQ:
+ case GoLexer::OP_STAR_EQ:
+ case GoLexer::OP_SLASH_EQ:
+ case GoLexer::OP_PERCENT_EQ:
+ case GoLexer::OP_LSHIFT_EQ:
+ case GoLexer::OP_RSHIFT_EQ:
+ case GoLexer::OP_AMP_EQ:
+ case GoLexer::OP_AMP_CARET_EQ:
+ break;
+ default:
+ return r.error();
+ }
+ // We don't want to own e until we know this is an assignment.
+ std::unique_ptr<GoASTAssignStmt> stmt(new GoASTAssignStmt(false));
+ stmt->AddLhs(e);
+ for (auto &l : lhs)
+ stmt->AddLhs(l.release());
+ for (GoASTExpr *r = Expression(); r; r = MoreExpressionList())
+ stmt->AddRhs(r);
+ if (!Semicolon() || stmt->NumRhs() == 0)
+ return new GoASTBadStmt;
+ return stmt.release();
+}
+
+GoASTStmt *GoParser::EmptyStmt() {
+ if (match(GoLexer::TOK_EOF))
return nullptr;
-}
-
-GoASTStmt *
-GoParser::Assignment(lldb_private::GoASTExpr *e)
-{
- Rule r("Assignment", this);
- std::vector<std::unique_ptr<GoASTExpr>> lhs;
- for (GoASTExpr *l = MoreExpressionList(); l; l = MoreExpressionList())
- lhs.push_back(std::unique_ptr<GoASTExpr>(l));
- switch (peek())
- {
- case GoLexer::OP_EQ:
- case GoLexer::OP_PLUS_EQ:
- case GoLexer::OP_MINUS_EQ:
- case GoLexer::OP_PIPE_EQ:
- case GoLexer::OP_CARET_EQ:
- case GoLexer::OP_STAR_EQ:
- case GoLexer::OP_SLASH_EQ:
- case GoLexer::OP_PERCENT_EQ:
- case GoLexer::OP_LSHIFT_EQ:
- case GoLexer::OP_RSHIFT_EQ:
- case GoLexer::OP_AMP_EQ:
- case GoLexer::OP_AMP_CARET_EQ:
- break;
- default:
- return r.error();
+ if (Semicolon())
+ return new GoASTEmptyStmt;
+ return nullptr;
+}
+
+GoASTStmt *GoParser::GoStmt() {
+ if (match(GoLexer::KEYWORD_GO)) {
+ if (GoASTCallExpr *e =
+ llvm::dyn_cast_or_null<GoASTCallExpr>(Expression())) {
+ return FinishStmt(new GoASTGoStmt(e));
+ }
+ m_last = "call expression";
+ m_failed = true;
+ return new GoASTBadStmt();
+ }
+ return nullptr;
+}
+
+GoASTStmt *GoParser::ReturnStmt() {
+ if (match(GoLexer::KEYWORD_RETURN)) {
+ std::unique_ptr<GoASTReturnStmt> r(new GoASTReturnStmt());
+ for (GoASTExpr *e = Expression(); e; e = MoreExpressionList())
+ r->AddResults(e);
+ return FinishStmt(r.release());
+ }
+ return nullptr;
+}
+
+GoASTStmt *GoParser::BranchStmt() {
+ GoLexer::Token *tok;
+ if ((tok = match(GoLexer::KEYWORD_BREAK)) ||
+ (tok = match(GoLexer::KEYWORD_CONTINUE)) ||
+ (tok = match(GoLexer::KEYWORD_GOTO))) {
+ auto *e = Identifier();
+ if (tok->m_type == GoLexer::KEYWORD_GOTO && !e)
+ return syntaxerror();
+ return FinishStmt(new GoASTBranchStmt(e, tok->m_type));
+ }
+ if ((tok = match(GoLexer::KEYWORD_FALLTHROUGH)))
+ return FinishStmt(new GoASTBranchStmt(nullptr, tok->m_type));
+
+ return nullptr;
+}
+
+GoASTIdent *GoParser::Identifier() {
+ if (auto *tok = match(GoLexer::TOK_IDENTIFIER))
+ return new GoASTIdent(*tok);
+ return nullptr;
+}
+
+GoASTExpr *GoParser::MoreExpressionList() {
+ if (match(GoLexer::OP_COMMA)) {
+ auto *e = Expression();
+ if (!e)
+ return syntaxerror();
+ return e;
+ }
+ return nullptr;
+}
+
+GoASTIdent *GoParser::MoreIdentifierList() {
+ if (match(GoLexer::OP_COMMA)) {
+ auto *i = Identifier();
+ if (!i)
+ return syntaxerror();
+ return i;
+ }
+ return nullptr;
+}
+
+GoASTExpr *GoParser::Expression() {
+ Rule r("Expression", this);
+ if (GoASTExpr *ret = OrExpr())
+ return ret;
+ return r.error();
+}
+
+GoASTExpr *GoParser::UnaryExpr() {
+ switch (peek()) {
+ case GoLexer::OP_PLUS:
+ case GoLexer::OP_MINUS:
+ case GoLexer::OP_BANG:
+ case GoLexer::OP_CARET:
+ case GoLexer::OP_STAR:
+ case GoLexer::OP_AMP:
+ case GoLexer::OP_LT_MINUS: {
+ const GoLexer::Token t = next();
+ if (GoASTExpr *e = UnaryExpr()) {
+ if (t.m_type == GoLexer::OP_STAR)
+ return new GoASTStarExpr(e);
+ else
+ return new GoASTUnaryExpr(t.m_type, e);
}
- // We don't want to own e until we know this is an assignment.
- std::unique_ptr<GoASTAssignStmt> stmt(new GoASTAssignStmt(false));
- stmt->AddLhs(e);
- for (auto &l : lhs)
- stmt->AddLhs(l.release());
- for (GoASTExpr *r = Expression(); r; r = MoreExpressionList())
- stmt->AddRhs(r);
- if (!Semicolon() || stmt->NumRhs() == 0)
- return new GoASTBadStmt;
- return stmt.release();
-}
-
-GoASTStmt *
-GoParser::EmptyStmt()
-{
- if (match(GoLexer::TOK_EOF))
- return nullptr;
- if (Semicolon())
- return new GoASTEmptyStmt;
- return nullptr;
-}
-
-GoASTStmt *
-GoParser::GoStmt()
-{
- if (match(GoLexer::KEYWORD_GO))
- {
- if (GoASTCallExpr *e = llvm::dyn_cast_or_null<GoASTCallExpr>(Expression()))
- {
- return FinishStmt(new GoASTGoStmt(e));
- }
- m_last = "call expression";
- m_failed = true;
- return new GoASTBadStmt();
+ return syntaxerror();
+ }
+ default:
+ return PrimaryExpr();
+ }
+}
+
+GoASTExpr *GoParser::OrExpr() {
+ std::unique_ptr<GoASTExpr> l(AndExpr());
+ if (l) {
+ while (match(GoLexer::OP_PIPE_PIPE)) {
+ GoASTExpr *r = AndExpr();
+ if (r)
+ l.reset(new GoASTBinaryExpr(l.release(), r, GoLexer::OP_PIPE_PIPE));
+ else
+ return syntaxerror();
}
- return nullptr;
-}
-
-GoASTStmt *
-GoParser::ReturnStmt()
-{
- if (match(GoLexer::KEYWORD_RETURN))
- {
- std::unique_ptr<GoASTReturnStmt> r(new GoASTReturnStmt());
- for (GoASTExpr *e = Expression(); e; e = MoreExpressionList())
- r->AddResults(e);
- return FinishStmt(r.release());
+ return l.release();
+ }
+ return nullptr;
+}
+
+GoASTExpr *GoParser::AndExpr() {
+ std::unique_ptr<GoASTExpr> l(RelExpr());
+ if (l) {
+ while (match(GoLexer::OP_AMP_AMP)) {
+ GoASTExpr *r = RelExpr();
+ if (r)
+ l.reset(new GoASTBinaryExpr(l.release(), r, GoLexer::OP_AMP_AMP));
+ else
+ return syntaxerror();
}
- return nullptr;
-}
-
-GoASTStmt *
-GoParser::BranchStmt()
-{
- GoLexer::Token *tok;
- if ((tok = match(GoLexer::KEYWORD_BREAK)) || (tok = match(GoLexer::KEYWORD_CONTINUE)) ||
- (tok = match(GoLexer::KEYWORD_GOTO)))
- {
- auto *e = Identifier();
- if (tok->m_type == GoLexer::KEYWORD_GOTO && !e)
- return syntaxerror();
- return FinishStmt(new GoASTBranchStmt(e, tok->m_type));
+ return l.release();
+ }
+ return nullptr;
+}
+
+GoASTExpr *GoParser::RelExpr() {
+ std::unique_ptr<GoASTExpr> l(AddExpr());
+ if (l) {
+ for (GoLexer::Token *t;
+ (t = match(GoLexer::OP_EQ_EQ)) || (t = match(GoLexer::OP_BANG_EQ)) ||
+ (t = match(GoLexer::OP_LT)) || (t = match(GoLexer::OP_LT_EQ)) ||
+ (t = match(GoLexer::OP_GT)) || (t = match(GoLexer::OP_GT_EQ));) {
+ GoLexer::TokenType op = t->m_type;
+ GoASTExpr *r = AddExpr();
+ if (r)
+ l.reset(new GoASTBinaryExpr(l.release(), r, op));
+ else
+ return syntaxerror();
}
- if ((tok = match(GoLexer::KEYWORD_FALLTHROUGH)))
- return FinishStmt(new GoASTBranchStmt(nullptr, tok->m_type));
-
- return nullptr;
+ return l.release();
+ }
+ return nullptr;
+}
+
+GoASTExpr *GoParser::AddExpr() {
+ std::unique_ptr<GoASTExpr> l(MulExpr());
+ if (l) {
+ for (GoLexer::Token *t;
+ (t = match(GoLexer::OP_PLUS)) || (t = match(GoLexer::OP_MINUS)) ||
+ (t = match(GoLexer::OP_PIPE)) || (t = match(GoLexer::OP_CARET));) {
+ GoLexer::TokenType op = t->m_type;
+ GoASTExpr *r = MulExpr();
+ if (r)
+ l.reset(new GoASTBinaryExpr(l.release(), r, op));
+ else
+ return syntaxerror();
+ }
+ return l.release();
+ }
+ return nullptr;
+}
+
+GoASTExpr *GoParser::MulExpr() {
+ std::unique_ptr<GoASTExpr> l(UnaryExpr());
+ if (l) {
+ for (GoLexer::Token *t;
+ (t = match(GoLexer::OP_STAR)) || (t = match(GoLexer::OP_SLASH)) ||
+ (t = match(GoLexer::OP_PERCENT)) || (t = match(GoLexer::OP_LSHIFT)) ||
+ (t = match(GoLexer::OP_RSHIFT)) || (t = match(GoLexer::OP_AMP)) ||
+ (t = match(GoLexer::OP_AMP_CARET));) {
+ GoLexer::TokenType op = t->m_type;
+ GoASTExpr *r = UnaryExpr();
+ if (r)
+ l.reset(new GoASTBinaryExpr(l.release(), r, op));
+ else
+ return syntaxerror();
+ }
+ return l.release();
+ }
+ return nullptr;
}
-GoASTIdent *
-GoParser::Identifier()
-{
- if (auto *tok = match(GoLexer::TOK_IDENTIFIER))
- return new GoASTIdent(*tok);
+GoASTExpr *GoParser::PrimaryExpr() {
+ GoASTExpr *l;
+ GoASTExpr *r;
+ (l = Conversion()) || (l = Operand());
+ if (!l)
return nullptr;
-}
-
-GoASTExpr *
-GoParser::MoreExpressionList()
-{
- if (match(GoLexer::OP_COMMA))
- {
- auto *e = Expression();
- if (!e)
- return syntaxerror();
- return e;
- }
+ while ((r = Selector(l)) || (r = IndexOrSlice(l)) || (r = TypeAssertion(l)) ||
+ (r = Arguments(l))) {
+ l = r;
+ }
+ return l;
+}
+
+GoASTExpr *GoParser::Operand() {
+ GoLexer::Token *lit;
+ if ((lit = match(GoLexer::LIT_INTEGER)) ||
+ (lit = match(GoLexer::LIT_FLOAT)) ||
+ (lit = match(GoLexer::LIT_IMAGINARY)) ||
+ (lit = match(GoLexer::LIT_RUNE)) || (lit = match(GoLexer::LIT_STRING)))
+ return new GoASTBasicLit(*lit);
+ if (match(GoLexer::OP_LPAREN)) {
+ GoASTExpr *e;
+ if (!((e = Expression()) && match(GoLexer::OP_RPAREN)))
+ return syntaxerror();
+ return e;
+ }
+ // MethodExpr should be handled by Selector
+ if (GoASTExpr *e = CompositeLit())
+ return e;
+ if (GoASTExpr *n = Name())
+ return n;
+ return FunctionLit();
+}
+
+GoASTExpr *GoParser::FunctionLit() {
+ if (!match(GoLexer::KEYWORD_FUNC))
return nullptr;
+ auto *sig = Signature();
+ if (!sig)
+ return syntaxerror();
+ auto *body = Block();
+ if (!body) {
+ delete sig;
+ return syntaxerror();
+ }
+ return new GoASTFuncLit(sig, body);
}
-GoASTIdent *
-GoParser::MoreIdentifierList()
-{
- if (match(GoLexer::OP_COMMA))
- {
- auto *i = Identifier();
- if (!i)
- return syntaxerror();
- return i;
- }
+GoASTBlockStmt *GoParser::Block() {
+ if (!match(GoLexer::OP_LBRACE))
return nullptr;
+ std::unique_ptr<GoASTBlockStmt> block(new GoASTBlockStmt);
+ for (auto *s = Statement(); s; s = Statement())
+ block->AddList(s);
+ if (!match(GoLexer::OP_RBRACE))
+ return syntaxerror();
+ return block.release();
}
-GoASTExpr *
-GoParser::Expression()
-{
- Rule r("Expression", this);
- if (GoASTExpr *ret = OrExpr())
- return ret;
+GoASTExpr *GoParser::CompositeLit() {
+ Rule r("CompositeLit", this);
+ GoASTExpr *type;
+ (type = StructType()) || (type = ArrayOrSliceType(true)) ||
+ (type = MapType()) || (type = Name());
+ if (!type)
return r.error();
+ GoASTCompositeLit *lit = LiteralValue();
+ if (!lit)
+ return r.error();
+ lit->SetType(type);
+ return lit;
}
-GoASTExpr *
-GoParser::UnaryExpr()
-{
- switch (peek())
- {
- case GoLexer::OP_PLUS:
- case GoLexer::OP_MINUS:
- case GoLexer::OP_BANG:
- case GoLexer::OP_CARET:
- case GoLexer::OP_STAR:
- case GoLexer::OP_AMP:
- case GoLexer::OP_LT_MINUS:
- {
- const GoLexer::Token t = next();
- if (GoASTExpr *e = UnaryExpr())
- {
- if (t.m_type == GoLexer::OP_STAR)
- return new GoASTStarExpr(e);
- else
- return new GoASTUnaryExpr(t.m_type, e);
- }
- return syntaxerror();
- }
- default:
- return PrimaryExpr();
- }
-}
-
-GoASTExpr *
-GoParser::OrExpr()
-{
- std::unique_ptr<GoASTExpr> l(AndExpr());
- if (l)
- {
- while (match(GoLexer::OP_PIPE_PIPE))
- {
- GoASTExpr *r = AndExpr();
- if (r)
- l.reset(new GoASTBinaryExpr(l.release(), r, GoLexer::OP_PIPE_PIPE));
- else
- return syntaxerror();
- }
- return l.release();
- }
+GoASTCompositeLit *GoParser::LiteralValue() {
+ if (!match(GoLexer::OP_LBRACE))
return nullptr;
-}
-
-GoASTExpr *
-GoParser::AndExpr()
-{
- std::unique_ptr<GoASTExpr> l(RelExpr());
- if (l)
- {
- while (match(GoLexer::OP_AMP_AMP))
- {
- GoASTExpr *r = RelExpr();
- if (r)
- l.reset(new GoASTBinaryExpr(l.release(), r, GoLexer::OP_AMP_AMP));
- else
- return syntaxerror();
- }
- return l.release();
- }
+ std::unique_ptr<GoASTCompositeLit> lit(new GoASTCompositeLit);
+ for (GoASTExpr *e = Element(); e; e = Element()) {
+ lit->AddElts(e);
+ if (!match(GoLexer::OP_COMMA))
+ break;
+ }
+ if (!mustMatch(GoLexer::OP_RBRACE))
return nullptr;
+ return lit.release();
}
-GoASTExpr *
-GoParser::RelExpr()
-{
- std::unique_ptr<GoASTExpr> l(AddExpr());
- if (l)
- {
- for (GoLexer::Token *t; (t = match(GoLexer::OP_EQ_EQ)) || (t = match(GoLexer::OP_BANG_EQ)) ||
- (t = match(GoLexer::OP_LT)) || (t = match(GoLexer::OP_LT_EQ)) ||
- (t = match(GoLexer::OP_GT)) || (t = match(GoLexer::OP_GT_EQ));)
- {
- GoLexer::TokenType op = t->m_type;
- GoASTExpr *r = AddExpr();
- if (r)
- l.reset(new GoASTBinaryExpr(l.release(), r, op));
- else
- return syntaxerror();
- }
- return l.release();
- }
+GoASTExpr *GoParser::Element() {
+ GoASTExpr *key;
+ if (!((key = Expression()) || (key = LiteralValue())))
return nullptr;
-}
-
-GoASTExpr *
-GoParser::AddExpr()
-{
- std::unique_ptr<GoASTExpr> l(MulExpr());
- if (l)
- {
- for (GoLexer::Token *t; (t = match(GoLexer::OP_PLUS)) || (t = match(GoLexer::OP_MINUS)) ||
- (t = match(GoLexer::OP_PIPE)) || (t = match(GoLexer::OP_CARET));)
- {
- GoLexer::TokenType op = t->m_type;
- GoASTExpr *r = MulExpr();
- if (r)
- l.reset(new GoASTBinaryExpr(l.release(), r, op));
- else
- return syntaxerror();
- }
- return l.release();
- }
- return nullptr;
-}
-
-GoASTExpr *
-GoParser::MulExpr()
-{
- std::unique_ptr<GoASTExpr> l(UnaryExpr());
- if (l)
- {
- for (GoLexer::Token *t; (t = match(GoLexer::OP_STAR)) || (t = match(GoLexer::OP_SLASH)) ||
- (t = match(GoLexer::OP_PERCENT)) || (t = match(GoLexer::OP_LSHIFT)) ||
- (t = match(GoLexer::OP_RSHIFT)) || (t = match(GoLexer::OP_AMP)) ||
- (t = match(GoLexer::OP_AMP_CARET));)
- {
- GoLexer::TokenType op = t->m_type;
- GoASTExpr *r = UnaryExpr();
- if (r)
- l.reset(new GoASTBinaryExpr(l.release(), r, op));
- else
- return syntaxerror();
- }
- return l.release();
- }
- return nullptr;
-}
-
-GoASTExpr *
-GoParser::PrimaryExpr()
-{
- GoASTExpr *l;
- GoASTExpr *r;
- (l = Conversion()) || (l = Operand());
- if (!l)
+ if (!match(GoLexer::OP_COLON))
+ return key;
+ GoASTExpr *value;
+ if ((value = Expression()) || (value = LiteralValue()))
+ return new GoASTKeyValueExpr(key, value);
+ delete key;
+ return syntaxerror();
+}
+
+GoASTExpr *GoParser::Selector(GoASTExpr *e) {
+ Rule r("Selector", this);
+ if (match(GoLexer::OP_DOT)) {
+ if (auto *name = Identifier())
+ return new GoASTSelectorExpr(e, name);
+ }
+ return r.error();
+}
+
+GoASTExpr *GoParser::IndexOrSlice(GoASTExpr *e) {
+ Rule r("IndexOrSlice", this);
+ if (match(GoLexer::OP_LBRACK)) {
+ std::unique_ptr<GoASTExpr> i1(Expression()), i2, i3;
+ bool slice = false;
+ if (match(GoLexer::OP_COLON)) {
+ slice = true;
+ i2.reset(Expression());
+ if (i2 && match(GoLexer::OP_COLON)) {
+ i3.reset(Expression());
+ if (!i3)
+ return syntaxerror();
+ }
+ }
+ if (!(slice || i1))
+ return syntaxerror();
+ if (!mustMatch(GoLexer::OP_RBRACK))
+ return nullptr;
+ if (slice) {
+ bool slice3 = i3.get();
+ return new GoASTSliceExpr(e, i1.release(), i2.release(), i3.release(),
+ slice3);
+ }
+ return new GoASTIndexExpr(e, i1.release());
+ }
+ return r.error();
+}
+
+GoASTExpr *GoParser::TypeAssertion(GoASTExpr *e) {
+ Rule r("TypeAssertion", this);
+ if (match(GoLexer::OP_DOT) && match(GoLexer::OP_LPAREN)) {
+ if (auto *t = Type()) {
+ if (!mustMatch(GoLexer::OP_RPAREN))
return nullptr;
- while ((r = Selector(l)) || (r = IndexOrSlice(l)) || (r = TypeAssertion(l)) || (r = Arguments(l)))
- {
- l = r;
+ return new GoASTTypeAssertExpr(e, t);
}
- return l;
+ return syntaxerror();
+ }
+ return r.error();
}
-GoASTExpr *
-GoParser::Operand()
-{
- GoLexer::Token *lit;
- if ((lit = match(GoLexer::LIT_INTEGER)) || (lit = match(GoLexer::LIT_FLOAT)) ||
- (lit = match(GoLexer::LIT_IMAGINARY)) || (lit = match(GoLexer::LIT_RUNE)) || (lit = match(GoLexer::LIT_STRING)))
- return new GoASTBasicLit(*lit);
- if (match(GoLexer::OP_LPAREN))
- {
- GoASTExpr *e;
- if (!((e = Expression()) && match(GoLexer::OP_RPAREN)))
- return syntaxerror();
- return e;
+GoASTExpr *GoParser::Arguments(GoASTExpr *e) {
+ if (match(GoLexer::OP_LPAREN)) {
+ std::unique_ptr<GoASTCallExpr> call(new GoASTCallExpr(false));
+ GoASTExpr *arg;
+ // ( ExpressionList | Type [ "," ExpressionList ] )
+ for ((arg = Expression()) || (arg = Type()); arg;
+ arg = MoreExpressionList()) {
+ call->AddArgs(arg);
}
- // MethodExpr should be handled by Selector
- if (GoASTExpr *e = CompositeLit())
- return e;
- if (GoASTExpr *n = Name())
- return n;
- return FunctionLit();
-}
+ if (match(GoLexer::OP_DOTS))
+ call->SetEllipsis(true);
-GoASTExpr *
-GoParser::FunctionLit()
-{
- if (!match(GoLexer::KEYWORD_FUNC))
- return nullptr;
- auto *sig = Signature();
- if (!sig)
- return syntaxerror();
- auto *body = Block();
- if (!body)
- {
- delete sig;
- return syntaxerror();
- }
- return new GoASTFuncLit(sig, body);
-}
+ // Eat trailing comma
+ match(GoLexer::OP_COMMA);
-GoASTBlockStmt *
-GoParser::Block()
-{
- if (!match(GoLexer::OP_LBRACE))
- return nullptr;
- std::unique_ptr<GoASTBlockStmt> block(new GoASTBlockStmt);
- for (auto *s = Statement(); s; s = Statement())
- block->AddList(s);
- if (!match(GoLexer::OP_RBRACE))
+ if (!mustMatch(GoLexer::OP_RPAREN))
+ return nullptr;
+ call->SetFun(e);
+ return call.release();
+ }
+ return nullptr;
+}
+
+GoASTExpr *GoParser::Conversion() {
+ Rule r("Conversion", this);
+ if (GoASTExpr *t = Type2()) {
+ if (match(GoLexer::OP_LPAREN)) {
+ GoASTExpr *v = Expression();
+ if (!v)
return syntaxerror();
- return block.release();
-}
-
-GoASTExpr *
-GoParser::CompositeLit()
-{
- Rule r("CompositeLit", this);
- GoASTExpr *type;
- (type = StructType()) || (type = ArrayOrSliceType(true)) || (type = MapType()) || (type = Name());
- if (!type)
+ match(GoLexer::OP_COMMA);
+ if (!mustMatch(GoLexer::OP_RPAREN))
return r.error();
- GoASTCompositeLit *lit = LiteralValue();
- if (!lit)
- return r.error();
- lit->SetType(type);
- return lit;
+ GoASTCallExpr *call = new GoASTCallExpr(false);
+ call->SetFun(t);
+ call->AddArgs(v);
+ return call;
+ }
+ }
+ return r.error();
+}
+
+GoASTExpr *GoParser::Type2() {
+ switch (peek()) {
+ case GoLexer::OP_LBRACK:
+ return ArrayOrSliceType(false);
+ case GoLexer::KEYWORD_STRUCT:
+ return StructType();
+ case GoLexer::KEYWORD_FUNC:
+ return FunctionType();
+ case GoLexer::KEYWORD_INTERFACE:
+ return InterfaceType();
+ case GoLexer::KEYWORD_MAP:
+ return MapType();
+ case GoLexer::KEYWORD_CHAN:
+ return ChanType2();
+ default:
+ return nullptr;
+ }
}
-GoASTCompositeLit *
-GoParser::LiteralValue()
-{
- if (!match(GoLexer::OP_LBRACE))
- return nullptr;
- std::unique_ptr<GoASTCompositeLit> lit(new GoASTCompositeLit);
- for (GoASTExpr *e = Element(); e; e = Element())
- {
- lit->AddElts(e);
- if (!match(GoLexer::OP_COMMA))
- break;
+GoASTExpr *GoParser::ArrayOrSliceType(bool allowEllipsis) {
+ Rule r("ArrayType", this);
+ if (match(GoLexer::OP_LBRACK)) {
+ std::unique_ptr<GoASTExpr> len;
+ if (allowEllipsis && match(GoLexer::OP_DOTS)) {
+ len.reset(new GoASTEllipsis(nullptr));
+ } else {
+ len.reset(Expression());
}
- if (!mustMatch(GoLexer::OP_RBRACE))
- return nullptr;
- return lit.release();
-}
-GoASTExpr *
-GoParser::Element()
-{
- GoASTExpr *key;
- if (!((key = Expression()) || (key = LiteralValue())))
- return nullptr;
- if (!match(GoLexer::OP_COLON))
- return key;
- GoASTExpr *value;
- if ((value = Expression()) || (value = LiteralValue()))
- return new GoASTKeyValueExpr(key, value);
- delete key;
- return syntaxerror();
+ if (!match(GoLexer::OP_RBRACK))
+ return r.error();
+ GoASTExpr *elem = Type();
+ if (!elem)
+ return syntaxerror();
+ return new GoASTArrayType(len.release(), elem);
+ }
+ return r.error();
}
-GoASTExpr *
-GoParser::Selector(GoASTExpr *e)
-{
- Rule r("Selector", this);
- if (match(GoLexer::OP_DOT))
- {
- if (auto *name = Identifier())
- return new GoASTSelectorExpr(e, name);
- }
- return r.error();
+GoASTExpr *GoParser::StructType() {
+ if (!(match(GoLexer::KEYWORD_STRUCT) && mustMatch(GoLexer::OP_LBRACE)))
+ return nullptr;
+ std::unique_ptr<GoASTFieldList> fields(new GoASTFieldList);
+ while (auto *field = FieldDecl())
+ fields->AddList(field);
+ if (!mustMatch(GoLexer::OP_RBRACE))
+ return nullptr;
+ return new GoASTStructType(fields.release());
}
-GoASTExpr *
-GoParser::IndexOrSlice(GoASTExpr *e)
-{
- Rule r("IndexOrSlice", this);
- if (match(GoLexer::OP_LBRACK))
- {
- std::unique_ptr<GoASTExpr> i1(Expression()), i2, i3;
- bool slice = false;
- if (match(GoLexer::OP_COLON))
- {
- slice = true;
- i2.reset(Expression());
- if (i2 && match(GoLexer::OP_COLON))
- {
- i3.reset(Expression());
- if (!i3)
- return syntaxerror();
- }
- }
- if (!(slice || i1))
- return syntaxerror();
- if (!mustMatch(GoLexer::OP_RBRACK))
- return nullptr;
- if (slice)
- {
- bool slice3 = i3.get();
- return new GoASTSliceExpr(e, i1.release(), i2.release(), i3.release(), slice3);
- }
- return new GoASTIndexExpr(e, i1.release());
- }
- return r.error();
-}
+GoASTField *GoParser::FieldDecl() {
+ std::unique_ptr<GoASTField> f(new GoASTField);
+ GoASTExpr *t = FieldNamesAndType(f.get());
+ if (!t)
+ t = AnonymousFieldType();
+ if (!t)
+ return nullptr;
-GoASTExpr *
-GoParser::TypeAssertion(GoASTExpr *e)
-{
- Rule r("TypeAssertion", this);
- if (match(GoLexer::OP_DOT) && match(GoLexer::OP_LPAREN))
- {
- if (auto *t = Type())
- {
- if (!mustMatch(GoLexer::OP_RPAREN))
- return nullptr;
- return new GoASTTypeAssertExpr(e, t);
- }
- return syntaxerror();
- }
- return r.error();
+ if (auto *tok = match(GoLexer::LIT_STRING))
+ f->SetTag(new GoASTBasicLit(*tok));
+ if (!Semicolon())
+ return syntaxerror();
+ return f.release();
}
-GoASTExpr *
-GoParser::Arguments(GoASTExpr *e)
-{
- if (match(GoLexer::OP_LPAREN))
- {
- std::unique_ptr<GoASTCallExpr> call(new GoASTCallExpr(false));
- GoASTExpr *arg;
- // ( ExpressionList | Type [ "," ExpressionList ] )
- for ((arg = Expression()) || (arg = Type()); arg; arg = MoreExpressionList())
- {
- call->AddArgs(arg);
- }
- if (match(GoLexer::OP_DOTS))
- call->SetEllipsis(true);
-
- // Eat trailing comma
- match(GoLexer::OP_COMMA);
-
- if (!mustMatch(GoLexer::OP_RPAREN))
- return nullptr;
- call->SetFun(e);
- return call.release();
- }
+GoASTExpr *GoParser::FieldNamesAndType(GoASTField *field) {
+ Rule r("FieldNames", this);
+ for (auto *id = Identifier(); id; id = MoreIdentifierList())
+ field->AddNames(id);
+ if (m_failed)
return nullptr;
+ GoASTExpr *t = Type();
+ if (t)
+ return t;
+ return r.error();
}
-GoASTExpr *
-GoParser::Conversion()
-{
- Rule r("Conversion", this);
- if (GoASTExpr *t = Type2())
- {
- if (match(GoLexer::OP_LPAREN))
- {
- GoASTExpr *v = Expression();
- if (!v)
- return syntaxerror();
- match(GoLexer::OP_COMMA);
- if (!mustMatch(GoLexer::OP_RPAREN))
- return r.error();
- GoASTCallExpr *call = new GoASTCallExpr(false);
- call->SetFun(t);
- call->AddArgs(v);
- return call;
- }
- }
- return r.error();
+GoASTExpr *GoParser::AnonymousFieldType() {
+ bool pointer = match(GoLexer::OP_STAR);
+ GoASTExpr *t = Type();
+ if (!t)
+ return nullptr;
+ if (pointer)
+ return new GoASTStarExpr(t);
+ return t;
}
-GoASTExpr *
-GoParser::Type2()
-{
- switch (peek())
- {
- case GoLexer::OP_LBRACK:
- return ArrayOrSliceType(false);
- case GoLexer::KEYWORD_STRUCT:
- return StructType();
- case GoLexer::KEYWORD_FUNC:
- return FunctionType();
- case GoLexer::KEYWORD_INTERFACE:
- return InterfaceType();
- case GoLexer::KEYWORD_MAP:
- return MapType();
- case GoLexer::KEYWORD_CHAN:
- return ChanType2();
- default:
- return nullptr;
- }
+GoASTExpr *GoParser::FunctionType() {
+ if (!match(GoLexer::KEYWORD_FUNC))
+ return nullptr;
+ return Signature();
}
-GoASTExpr *
-GoParser::ArrayOrSliceType(bool allowEllipsis)
-{
- Rule r("ArrayType", this);
- if (match(GoLexer::OP_LBRACK))
- {
- std::unique_ptr<GoASTExpr> len;
- if (allowEllipsis && match(GoLexer::OP_DOTS))
- {
- len.reset(new GoASTEllipsis(nullptr));
- }
- else
- {
- len.reset(Expression());
- }
-
- if (!match(GoLexer::OP_RBRACK))
- return r.error();
- GoASTExpr *elem = Type();
- if (!elem)
- return syntaxerror();
- return new GoASTArrayType(len.release(), elem);
+GoASTFuncType *GoParser::Signature() {
+ auto *params = Params();
+ if (!params)
+ return syntaxerror();
+ auto *result = Params();
+ if (!result) {
+ if (auto *t = Type()) {
+ result = new GoASTFieldList;
+ auto *f = new GoASTField;
+ f->SetType(t);
+ result->AddList(f);
}
- return r.error();
-}
-
-GoASTExpr *
-GoParser::StructType()
-{
- if (!(match(GoLexer::KEYWORD_STRUCT) && mustMatch(GoLexer::OP_LBRACE)))
- return nullptr;
- std::unique_ptr<GoASTFieldList> fields(new GoASTFieldList);
- while (auto *field = FieldDecl())
- fields->AddList(field);
- if (!mustMatch(GoLexer::OP_RBRACE))
- return nullptr;
- return new GoASTStructType(fields.release());
+ }
+ return new GoASTFuncType(params, result);
}
-GoASTField *
-GoParser::FieldDecl()
-{
- std::unique_ptr<GoASTField> f(new GoASTField);
- GoASTExpr *t = FieldNamesAndType(f.get());
- if (!t)
- t = AnonymousFieldType();
- if (!t)
- return nullptr;
-
- if (auto *tok = match(GoLexer::LIT_STRING))
- f->SetTag(new GoASTBasicLit(*tok));
- if (!Semicolon())
- return syntaxerror();
- return f.release();
-}
-
-GoASTExpr *
-GoParser::FieldNamesAndType(GoASTField *field)
-{
- Rule r("FieldNames", this);
- for (auto *id = Identifier(); id; id = MoreIdentifierList())
- field->AddNames(id);
- if (m_failed)
- return nullptr;
- GoASTExpr *t = Type();
- if (t)
- return t;
- return r.error();
-}
-
-GoASTExpr *
-GoParser::AnonymousFieldType()
-{
- bool pointer = match(GoLexer::OP_STAR);
- GoASTExpr *t = Type();
- if (!t)
- return nullptr;
- if (pointer)
- return new GoASTStarExpr(t);
+GoASTFieldList *GoParser::Params() {
+ if (!match(GoLexer::OP_LPAREN))
+ return nullptr;
+ std::unique_ptr<GoASTFieldList> l(new GoASTFieldList);
+ while (GoASTField *p = ParamDecl()) {
+ l->AddList(p);
+ if (!match(GoLexer::OP_COMMA))
+ break;
+ }
+ if (!mustMatch(GoLexer::OP_RPAREN))
+ return nullptr;
+ return l.release();
+}
+
+GoASTField *GoParser::ParamDecl() {
+ std::unique_ptr<GoASTField> field(new GoASTField);
+ GoASTIdent *id = Identifier();
+ if (id) {
+ // Try `IdentifierList [ "..." ] Type`.
+ // If that fails, backtrack and try `[ "..." ] Type`.
+ Rule r("NamedParam", this);
+ for (; id; id = MoreIdentifierList())
+ field->AddNames(id);
+ GoASTExpr *t = ParamType();
+ if (t) {
+ field->SetType(t);
+ return field.release();
+ }
+ field.reset(new GoASTField);
+ r.error();
+ }
+ GoASTExpr *t = ParamType();
+ if (t) {
+ field->SetType(t);
+ return field.release();
+ }
+ return nullptr;
+}
+
+GoASTExpr *GoParser::ParamType() {
+ bool dots = match(GoLexer::OP_DOTS);
+ GoASTExpr *t = Type();
+ if (!dots)
return t;
+ if (!t)
+ return syntaxerror();
+ return new GoASTEllipsis(t);
}
-GoASTExpr *
-GoParser::FunctionType()
-{
- if (!match(GoLexer::KEYWORD_FUNC))
- return nullptr;
- return Signature();
-}
-
-GoASTFuncType *
-GoParser::Signature()
-{
- auto *params = Params();
- if (!params)
- return syntaxerror();
- auto *result = Params();
- if (!result)
- {
- if (auto *t = Type())
- {
- result = new GoASTFieldList;
- auto *f = new GoASTField;
- f->SetType(t);
- result->AddList(f);
- }
- }
- return new GoASTFuncType(params, result);
-}
-
-GoASTFieldList *
-GoParser::Params()
-{
- if (!match(GoLexer::OP_LPAREN))
- return nullptr;
- std::unique_ptr<GoASTFieldList> l(new GoASTFieldList);
- while (GoASTField *p = ParamDecl())
- {
- l->AddList(p);
- if (!match(GoLexer::OP_COMMA))
- break;
+GoASTExpr *GoParser::InterfaceType() {
+ if (!match(GoLexer::KEYWORD_INTERFACE) || !mustMatch(GoLexer::OP_LBRACE))
+ return nullptr;
+ std::unique_ptr<GoASTFieldList> methods(new GoASTFieldList);
+ while (true) {
+ Rule r("MethodSpec", this);
+ // ( identifier Signature | TypeName ) ;
+ std::unique_ptr<GoASTIdent> id(Identifier());
+ if (!id)
+ break;
+ GoASTExpr *type = Signature();
+ if (!type) {
+ r.error();
+ id.reset();
+ type = Name();
}
- if (!mustMatch(GoLexer::OP_RPAREN))
- return nullptr;
- return l.release();
-}
-
-GoASTField *
-GoParser::ParamDecl()
-{
- std::unique_ptr<GoASTField> field(new GoASTField);
- GoASTIdent *id = Identifier();
+ if (!Semicolon())
+ return syntaxerror();
+ auto *f = new GoASTField;
if (id)
- {
- // Try `IdentifierList [ "..." ] Type`.
- // If that fails, backtrack and try `[ "..." ] Type`.
- Rule r("NamedParam", this);
- for (; id; id = MoreIdentifierList())
- field->AddNames(id);
- GoASTExpr *t = ParamType();
- if (t)
- {
- field->SetType(t);
- return field.release();
- }
- field.reset(new GoASTField);
- r.error();
- }
- GoASTExpr *t = ParamType();
- if (t)
- {
- field->SetType(t);
- return field.release();
- }
+ f->AddNames(id.release());
+ f->SetType(type);
+ methods->AddList(f);
+ }
+ if (!mustMatch(GoLexer::OP_RBRACE))
return nullptr;
+ return new GoASTInterfaceType(methods.release());
}
-GoASTExpr *
-GoParser::ParamType()
-{
- bool dots = match(GoLexer::OP_DOTS);
- GoASTExpr *t = Type();
- if (!dots)
- return t;
- if (!t)
- return syntaxerror();
- return new GoASTEllipsis(t);
-}
-
-GoASTExpr *
-GoParser::InterfaceType()
-{
- if (!match(GoLexer::KEYWORD_INTERFACE) || !mustMatch(GoLexer::OP_LBRACE))
- return nullptr;
- std::unique_ptr<GoASTFieldList> methods(new GoASTFieldList);
- while (true)
- {
- Rule r("MethodSpec", this);
- // ( identifier Signature | TypeName ) ;
- std::unique_ptr<GoASTIdent> id(Identifier());
- if (!id)
- break;
- GoASTExpr *type = Signature();
- if (!type)
- {
- r.error();
- id.reset();
- type = Name();
- }
- if (!Semicolon())
- return syntaxerror();
- auto *f = new GoASTField;
- if (id)
- f->AddNames(id.release());
- f->SetType(type);
- methods->AddList(f);
- }
- if (!mustMatch(GoLexer::OP_RBRACE))
- return nullptr;
- return new GoASTInterfaceType(methods.release());
-}
-
-GoASTExpr *
-GoParser::MapType()
-{
- if (!(match(GoLexer::KEYWORD_MAP) && mustMatch(GoLexer::OP_LBRACK)))
- return nullptr;
- std::unique_ptr<GoASTExpr> key(Type());
- if (!key)
- return syntaxerror();
- if (!mustMatch(GoLexer::OP_RBRACK))
- return nullptr;
- auto *elem = Type();
- if (!elem)
- return syntaxerror();
- return new GoASTMapType(key.release(), elem);
-}
-
-GoASTExpr *
-GoParser::ChanType()
-{
- Rule r("chan", this);
- if (match(GoLexer::OP_LT_MINUS))
- {
- if (match(GoLexer::KEYWORD_CHAN))
- {
- auto *elem = Type();
- if (!elem)
- return syntaxerror();
- return new GoASTChanType(GoASTNode::eChanRecv, elem);
- }
- return r.error();
- }
- return ChanType2();
-}
-
-GoASTExpr *
-GoParser::ChanType2()
-{
- if (!match(GoLexer::KEYWORD_CHAN))
- return nullptr;
- auto dir = GoASTNode::eChanBidir;
- if (match(GoLexer::OP_LT_MINUS))
- dir = GoASTNode::eChanSend;
- auto *elem = Type();
- if (!elem)
- return syntaxerror();
- return new GoASTChanType(dir, elem);
-}
-
-GoASTExpr *
-GoParser::Type()
-{
- if (GoASTExpr *t = Type2())
- return t;
- if (GoASTExpr *t = Name())
- return t;
- if (GoASTExpr *t = ChanType())
- return t;
- if (match(GoLexer::OP_STAR))
- {
- GoASTExpr *t = Type();
- if (!t)
- return syntaxerror();
- return new GoASTStarExpr(t);
- }
- if (match(GoLexer::OP_LPAREN))
- {
- std::unique_ptr<GoASTExpr> t(Type());
- if (!t || !match(GoLexer::OP_RPAREN))
- return syntaxerror();
- return t.release();
- }
+GoASTExpr *GoParser::MapType() {
+ if (!(match(GoLexer::KEYWORD_MAP) && mustMatch(GoLexer::OP_LBRACK)))
return nullptr;
-}
-
-bool
-GoParser::Semicolon()
-{
- if (match(GoLexer::OP_SEMICOLON))
- return true;
- switch (peek())
- {
- case GoLexer::OP_RPAREN:
- case GoLexer::OP_RBRACE:
- case GoLexer::TOK_EOF:
- return true;
- default:
- return false;
- }
-}
-
-GoASTExpr *
-GoParser::Name()
-{
- if (auto *id = Identifier())
- {
- if (GoASTExpr *qual = QualifiedIdent(id))
- return qual;
- return id;
- }
+ std::unique_ptr<GoASTExpr> key(Type());
+ if (!key)
+ return syntaxerror();
+ if (!mustMatch(GoLexer::OP_RBRACK))
return nullptr;
+ auto *elem = Type();
+ if (!elem)
+ return syntaxerror();
+ return new GoASTMapType(key.release(), elem);
}
-GoASTExpr *
-GoParser::QualifiedIdent(lldb_private::GoASTIdent *p)
-{
- Rule r("QualifiedIdent", this);
- llvm::SmallString<32> path(p->GetName().m_value);
- GoLexer::Token *next;
- bool have_slashes = false;
- // LLDB extension: support full/package/path.name
- while (match(GoLexer::OP_SLASH) && (next = match(GoLexer::TOK_IDENTIFIER)))
- {
- have_slashes = true;
- path.append("/");
- path.append(next->m_value);
- }
- if (match(GoLexer::OP_DOT))
- {
- auto *name = Identifier();
- if (name)
- {
- if (have_slashes)
- {
- p->SetName(GoLexer::Token(GoLexer::TOK_IDENTIFIER, CopyString(path)));
- }
- return new GoASTSelectorExpr(p, name);
- }
+GoASTExpr *GoParser::ChanType() {
+ Rule r("chan", this);
+ if (match(GoLexer::OP_LT_MINUS)) {
+ if (match(GoLexer::KEYWORD_CHAN)) {
+ auto *elem = Type();
+ if (!elem)
+ return syntaxerror();
+ return new GoASTChanType(GoASTNode::eChanRecv, elem);
}
return r.error();
+ }
+ return ChanType2();
}
-llvm::StringRef
-GoParser::CopyString(llvm::StringRef s)
-{
- return m_strings.insert(std::make_pair(s, 'x')).first->getKey();
+GoASTExpr *GoParser::ChanType2() {
+ if (!match(GoLexer::KEYWORD_CHAN))
+ return nullptr;
+ auto dir = GoASTNode::eChanBidir;
+ if (match(GoLexer::OP_LT_MINUS))
+ dir = GoASTNode::eChanSend;
+ auto *elem = Type();
+ if (!elem)
+ return syntaxerror();
+ return new GoASTChanType(dir, elem);
}
-void
-GoParser::GetError(Error &error)
-{
- llvm::StringRef want;
- if (m_failed)
- want = m_last_tok == GoLexer::TOK_INVALID ? DescribeToken(m_last_tok) : m_last;
- else
- want = m_error;
- size_t len = m_lexer.BytesRemaining();
- if (len > 10)
- len = 10;
- llvm::StringRef got;
- if (len == 0)
- got = "<eof>";
- else
- got = m_lexer.GetString(len);
- error.SetErrorStringWithFormat("Syntax error: expected %s before '%s'.", want.str().c_str(), got.str().c_str());
+GoASTExpr *GoParser::Type() {
+ if (GoASTExpr *t = Type2())
+ return t;
+ if (GoASTExpr *t = Name())
+ return t;
+ if (GoASTExpr *t = ChanType())
+ return t;
+ if (match(GoLexer::OP_STAR)) {
+ GoASTExpr *t = Type();
+ if (!t)
+ return syntaxerror();
+ return new GoASTStarExpr(t);
+ }
+ if (match(GoLexer::OP_LPAREN)) {
+ std::unique_ptr<GoASTExpr> t(Type());
+ if (!t || !match(GoLexer::OP_RPAREN))
+ return syntaxerror();
+ return t.release();
+ }
+ return nullptr;
+}
+
+bool GoParser::Semicolon() {
+ if (match(GoLexer::OP_SEMICOLON))
+ return true;
+ switch (peek()) {
+ case GoLexer::OP_RPAREN:
+ case GoLexer::OP_RBRACE:
+ case GoLexer::TOK_EOF:
+ return true;
+ default:
+ return false;
+ }
+}
+
+GoASTExpr *GoParser::Name() {
+ if (auto *id = Identifier()) {
+ if (GoASTExpr *qual = QualifiedIdent(id))
+ return qual;
+ return id;
+ }
+ return nullptr;
+}
+
+GoASTExpr *GoParser::QualifiedIdent(lldb_private::GoASTIdent *p) {
+ Rule r("QualifiedIdent", this);
+ llvm::SmallString<32> path(p->GetName().m_value);
+ GoLexer::Token *next;
+ bool have_slashes = false;
+ // LLDB extension: support full/package/path.name
+ while (match(GoLexer::OP_SLASH) && (next = match(GoLexer::TOK_IDENTIFIER))) {
+ have_slashes = true;
+ path.append("/");
+ path.append(next->m_value);
+ }
+ if (match(GoLexer::OP_DOT)) {
+ auto *name = Identifier();
+ if (name) {
+ if (have_slashes) {
+ p->SetName(GoLexer::Token(GoLexer::TOK_IDENTIFIER, CopyString(path)));
+ }
+ return new GoASTSelectorExpr(p, name);
+ }
+ }
+ return r.error();
+}
+
+llvm::StringRef GoParser::CopyString(llvm::StringRef s) {
+ return m_strings.insert(std::make_pair(s, 'x')).first->getKey();
+}
+
+void GoParser::GetError(Error &error) {
+ llvm::StringRef want;
+ if (m_failed)
+ want =
+ m_last_tok == GoLexer::TOK_INVALID ? DescribeToken(m_last_tok) : m_last;
+ else
+ want = m_error;
+ size_t len = m_lexer.BytesRemaining();
+ if (len > 10)
+ len = 10;
+ llvm::StringRef got;
+ if (len == 0)
+ got = "<eof>";
+ else
+ got = m_lexer.GetString(len);
+ error.SetErrorStringWithFormat("Syntax error: expected %s before '%s'.",
+ want.str().c_str(), got.str().c_str());
}
diff --git a/lldb/source/Plugins/ExpressionParser/Go/GoParser.h b/lldb/source/Plugins/ExpressionParser/Go/GoParser.h
index 9ceb670ccd1..bd128558022 100644
--- a/lldb/source/Plugins/ExpressionParser/Go/GoParser.h
+++ b/lldb/source/Plugins/ExpressionParser/Go/GoParser.h
@@ -1,4 +1,5 @@
-//===-- GoParser.h -----------------------------------------------*- C++ -*-===//
+//===-- GoParser.h -----------------------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -10,155 +11,134 @@
#ifndef liblldb_GoParser_h
#define liblldb_GoParser_h
-#include "lldb/lldb-private.h"
#include "Plugins/ExpressionParser/Go/GoAST.h"
#include "Plugins/ExpressionParser/Go/GoLexer.h"
+#include "lldb/lldb-private.h"
-namespace lldb_private
-{
-class GoParser
-{
- public:
- explicit GoParser(const char *src);
-
- GoASTStmt *Statement();
-
- GoASTStmt *GoStmt();
- GoASTStmt *ReturnStmt();
- GoASTStmt *BranchStmt();
- GoASTStmt *EmptyStmt();
- GoASTStmt *ExpressionStmt(GoASTExpr *e);
- GoASTStmt *IncDecStmt(GoASTExpr *e);
- GoASTStmt *Assignment(GoASTExpr *e);
- GoASTBlockStmt *Block();
-
- GoASTExpr *MoreExpressionList(); // ["," Expression]
- GoASTIdent *MoreIdentifierList(); // ["," Identifier]
-
- GoASTExpr *Expression();
- GoASTExpr *UnaryExpr();
- GoASTExpr *OrExpr();
- GoASTExpr *AndExpr();
- GoASTExpr *RelExpr();
- GoASTExpr *AddExpr();
- GoASTExpr *MulExpr();
- GoASTExpr *PrimaryExpr();
- GoASTExpr *Operand();
- GoASTExpr *Conversion();
-
- GoASTExpr *Selector(GoASTExpr *e);
- GoASTExpr *IndexOrSlice(GoASTExpr *e);
- GoASTExpr *TypeAssertion(GoASTExpr *e);
- GoASTExpr *Arguments(GoASTExpr *e);
-
- GoASTExpr *Type();
- GoASTExpr *Type2();
- GoASTExpr *ArrayOrSliceType(bool allowEllipsis);
- GoASTExpr *StructType();
- GoASTExpr *FunctionType();
- GoASTExpr *InterfaceType();
- GoASTExpr *MapType();
- GoASTExpr *ChanType();
- GoASTExpr *ChanType2();
-
- GoASTExpr *Name();
- GoASTExpr *QualifiedIdent(GoASTIdent *p);
- GoASTIdent *Identifier();
-
- GoASTField *FieldDecl();
- GoASTExpr *AnonymousFieldType();
- GoASTExpr *FieldNamesAndType(GoASTField *f);
-
- GoASTFieldList *Params();
- GoASTField *ParamDecl();
- GoASTExpr *ParamType();
- GoASTFuncType *Signature();
- GoASTExpr *CompositeLit();
- GoASTExpr *FunctionLit();
- GoASTExpr *Element();
- GoASTCompositeLit *LiteralValue();
-
- bool
- Failed() const
- {
- return m_failed;
- }
- bool
- AtEOF() const
- {
- return m_lexer.BytesRemaining() == 0 && m_pos == m_tokens.size();
- }
-
- void GetError(Error &error);
-
- private:
- class Rule;
- friend class Rule;
-
- std::nullptr_t
- syntaxerror()
- {
- m_failed = true;
- return nullptr;
+namespace lldb_private {
+class GoParser {
+public:
+ explicit GoParser(const char *src);
+
+ GoASTStmt *Statement();
+
+ GoASTStmt *GoStmt();
+ GoASTStmt *ReturnStmt();
+ GoASTStmt *BranchStmt();
+ GoASTStmt *EmptyStmt();
+ GoASTStmt *ExpressionStmt(GoASTExpr *e);
+ GoASTStmt *IncDecStmt(GoASTExpr *e);
+ GoASTStmt *Assignment(GoASTExpr *e);
+ GoASTBlockStmt *Block();
+
+ GoASTExpr *MoreExpressionList(); // ["," Expression]
+ GoASTIdent *MoreIdentifierList(); // ["," Identifier]
+
+ GoASTExpr *Expression();
+ GoASTExpr *UnaryExpr();
+ GoASTExpr *OrExpr();
+ GoASTExpr *AndExpr();
+ GoASTExpr *RelExpr();
+ GoASTExpr *AddExpr();
+ GoASTExpr *MulExpr();
+ GoASTExpr *PrimaryExpr();
+ GoASTExpr *Operand();
+ GoASTExpr *Conversion();
+
+ GoASTExpr *Selector(GoASTExpr *e);
+ GoASTExpr *IndexOrSlice(GoASTExpr *e);
+ GoASTExpr *TypeAssertion(GoASTExpr *e);
+ GoASTExpr *Arguments(GoASTExpr *e);
+
+ GoASTExpr *Type();
+ GoASTExpr *Type2();
+ GoASTExpr *ArrayOrSliceType(bool allowEllipsis);
+ GoASTExpr *StructType();
+ GoASTExpr *FunctionType();
+ GoASTExpr *InterfaceType();
+ GoASTExpr *MapType();
+ GoASTExpr *ChanType();
+ GoASTExpr *ChanType2();
+
+ GoASTExpr *Name();
+ GoASTExpr *QualifiedIdent(GoASTIdent *p);
+ GoASTIdent *Identifier();
+
+ GoASTField *FieldDecl();
+ GoASTExpr *AnonymousFieldType();
+ GoASTExpr *FieldNamesAndType(GoASTField *f);
+
+ GoASTFieldList *Params();
+ GoASTField *ParamDecl();
+ GoASTExpr *ParamType();
+ GoASTFuncType *Signature();
+ GoASTExpr *CompositeLit();
+ GoASTExpr *FunctionLit();
+ GoASTExpr *Element();
+ GoASTCompositeLit *LiteralValue();
+
+ bool Failed() const { return m_failed; }
+ bool AtEOF() const {
+ return m_lexer.BytesRemaining() == 0 && m_pos == m_tokens.size();
+ }
+
+ void GetError(Error &error);
+
+private:
+ class Rule;
+ friend class Rule;
+
+ std::nullptr_t syntaxerror() {
+ m_failed = true;
+ return nullptr;
+ }
+ GoLexer::Token &next() {
+ if (m_pos >= m_tokens.size()) {
+ if (m_pos != 0 && (m_tokens.back().m_type == GoLexer::TOK_EOF ||
+ m_tokens.back().m_type == GoLexer::TOK_INVALID))
+ return m_tokens.back();
+ m_pos = m_tokens.size();
+ m_tokens.push_back(m_lexer.Lex());
}
- GoLexer::Token &
- next()
- {
- if (m_pos >= m_tokens.size())
- {
- if (m_pos != 0 &&
- (m_tokens.back().m_type == GoLexer::TOK_EOF || m_tokens.back().m_type == GoLexer::TOK_INVALID))
- return m_tokens.back();
- m_pos = m_tokens.size();
- m_tokens.push_back(m_lexer.Lex());
- }
- return m_tokens[m_pos++];
- }
- GoLexer::TokenType
- peek()
- {
- GoLexer::Token &tok = next();
- --m_pos;
- return tok.m_type;
- }
- GoLexer::Token *
- match(GoLexer::TokenType t)
- {
- GoLexer::Token &tok = next();
- if (tok.m_type == t)
- return &tok;
- --m_pos;
- m_last_tok = t;
- return nullptr;
- }
- GoLexer::Token *
- mustMatch(GoLexer::TokenType t)
- {
- GoLexer::Token *tok = match(t);
- if (tok)
- return tok;
- return syntaxerror();
- }
- bool Semicolon();
-
- GoASTStmt *
- FinishStmt(GoASTStmt *s)
- {
- if (!Semicolon())
- m_failed = true;
- return s;
- }
-
- llvm::StringRef CopyString(llvm::StringRef s);
-
- GoLexer m_lexer;
- std::vector<GoLexer::Token> m_tokens;
- size_t m_pos;
- llvm::StringRef m_error;
- llvm::StringRef m_last;
- GoLexer::TokenType m_last_tok;
- llvm::StringMap<uint8_t> m_strings;
- bool m_failed;
+ return m_tokens[m_pos++];
+ }
+ GoLexer::TokenType peek() {
+ GoLexer::Token &tok = next();
+ --m_pos;
+ return tok.m_type;
+ }
+ GoLexer::Token *match(GoLexer::TokenType t) {
+ GoLexer::Token &tok = next();
+ if (tok.m_type == t)
+ return &tok;
+ --m_pos;
+ m_last_tok = t;
+ return nullptr;
+ }
+ GoLexer::Token *mustMatch(GoLexer::TokenType t) {
+ GoLexer::Token *tok = match(t);
+ if (tok)
+ return tok;
+ return syntaxerror();
+ }
+ bool Semicolon();
+
+ GoASTStmt *FinishStmt(GoASTStmt *s) {
+ if (!Semicolon())
+ m_failed = true;
+ return s;
+ }
+
+ llvm::StringRef CopyString(llvm::StringRef s);
+
+ GoLexer m_lexer;
+ std::vector<GoLexer::Token> m_tokens;
+ size_t m_pos;
+ llvm::StringRef m_error;
+ llvm::StringRef m_last;
+ GoLexer::TokenType m_last_tok;
+ llvm::StringMap<uint8_t> m_strings;
+ bool m_failed;
};
}
diff --git a/lldb/source/Plugins/ExpressionParser/Go/GoUserExpression.cpp b/lldb/source/Plugins/ExpressionParser/Go/GoUserExpression.cpp
index 5ec8662172c..67b62ceaf7e 100644
--- a/lldb/source/Plugins/ExpressionParser/Go/GoUserExpression.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Go/GoUserExpression.cpp
@@ -20,8 +20,8 @@
#include <vector>
// Other libraries and framework includes
-#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
// Project includes
#include "GoUserExpression.h"
@@ -57,705 +57,621 @@
using namespace lldb_private;
using namespace lldb;
-class GoUserExpression::GoInterpreter
-{
- public:
- GoInterpreter(ExecutionContext &exe_ctx, const char *expr)
- : m_exe_ctx(exe_ctx), m_frame(exe_ctx.GetFrameSP()), m_parser(expr)
- {
- if (m_frame)
- {
- const SymbolContext &ctx = m_frame->GetSymbolContext(eSymbolContextFunction);
- ConstString fname = ctx.GetFunctionName();
- if (fname.GetLength() > 0)
- {
- size_t dot = fname.GetStringRef().find('.');
- if (dot != llvm::StringRef::npos)
- m_package = llvm::StringRef(fname.AsCString(), dot);
- }
- }
- }
-
- void
- set_use_dynamic(DynamicValueType use_dynamic)
- {
- m_use_dynamic = use_dynamic;
- }
-
- bool Parse();
- lldb::ValueObjectSP Evaluate(ExecutionContext &exe_ctx);
- lldb::ValueObjectSP EvaluateStatement(const GoASTStmt *s);
- lldb::ValueObjectSP EvaluateExpr(const GoASTExpr *e);
-
- ValueObjectSP
- VisitBadExpr(const GoASTBadExpr *e)
- {
- m_parser.GetError(m_error);
- return nullptr;
- }
+class GoUserExpression::GoInterpreter {
+public:
+ GoInterpreter(ExecutionContext &exe_ctx, const char *expr)
+ : m_exe_ctx(exe_ctx), m_frame(exe_ctx.GetFrameSP()), m_parser(expr) {
+ if (m_frame) {
+ const SymbolContext &ctx =
+ m_frame->GetSymbolContext(eSymbolContextFunction);
+ ConstString fname = ctx.GetFunctionName();
+ if (fname.GetLength() > 0) {
+ size_t dot = fname.GetStringRef().find('.');
+ if (dot != llvm::StringRef::npos)
+ m_package = llvm::StringRef(fname.AsCString(), dot);
+ }
+ }
+ }
+
+ void set_use_dynamic(DynamicValueType use_dynamic) {
+ m_use_dynamic = use_dynamic;
+ }
+
+ bool Parse();
+ lldb::ValueObjectSP Evaluate(ExecutionContext &exe_ctx);
+ lldb::ValueObjectSP EvaluateStatement(const GoASTStmt *s);
+ lldb::ValueObjectSP EvaluateExpr(const GoASTExpr *e);
+
+ ValueObjectSP VisitBadExpr(const GoASTBadExpr *e) {
+ m_parser.GetError(m_error);
+ return nullptr;
+ }
- ValueObjectSP VisitParenExpr(const GoASTParenExpr *e);
- ValueObjectSP VisitIdent(const GoASTIdent *e);
- ValueObjectSP VisitStarExpr(const GoASTStarExpr *e);
- ValueObjectSP VisitSelectorExpr(const GoASTSelectorExpr *e);
- ValueObjectSP VisitBasicLit(const GoASTBasicLit *e);
- ValueObjectSP VisitIndexExpr(const GoASTIndexExpr *e);
- ValueObjectSP VisitUnaryExpr(const GoASTUnaryExpr *e);
- ValueObjectSP VisitCallExpr(const GoASTCallExpr *e);
-
- ValueObjectSP
- VisitTypeAssertExpr(const GoASTTypeAssertExpr *e)
- {
- return NotImplemented(e);
- }
+ ValueObjectSP VisitParenExpr(const GoASTParenExpr *e);
+ ValueObjectSP VisitIdent(const GoASTIdent *e);
+ ValueObjectSP VisitStarExpr(const GoASTStarExpr *e);
+ ValueObjectSP VisitSelectorExpr(const GoASTSelectorExpr *e);
+ ValueObjectSP VisitBasicLit(const GoASTBasicLit *e);
+ ValueObjectSP VisitIndexExpr(const GoASTIndexExpr *e);
+ ValueObjectSP VisitUnaryExpr(const GoASTUnaryExpr *e);
+ ValueObjectSP VisitCallExpr(const GoASTCallExpr *e);
- ValueObjectSP
- VisitBinaryExpr(const GoASTBinaryExpr *e)
- {
- return NotImplemented(e);
- }
+ ValueObjectSP VisitTypeAssertExpr(const GoASTTypeAssertExpr *e) {
+ return NotImplemented(e);
+ }
- ValueObjectSP
- VisitArrayType(const GoASTArrayType *e)
- {
- return NotImplemented(e);
- }
+ ValueObjectSP VisitBinaryExpr(const GoASTBinaryExpr *e) {
+ return NotImplemented(e);
+ }
- ValueObjectSP
- VisitChanType(const GoASTChanType *e)
- {
- return NotImplemented(e);
- }
+ ValueObjectSP VisitArrayType(const GoASTArrayType *e) {
+ return NotImplemented(e);
+ }
- ValueObjectSP
- VisitCompositeLit(const GoASTCompositeLit *e)
- {
- return NotImplemented(e);
- }
+ ValueObjectSP VisitChanType(const GoASTChanType *e) {
+ return NotImplemented(e);
+ }
- ValueObjectSP
- VisitEllipsis(const GoASTEllipsis *e)
- {
- return NotImplemented(e);
- }
+ ValueObjectSP VisitCompositeLit(const GoASTCompositeLit *e) {
+ return NotImplemented(e);
+ }
- ValueObjectSP
- VisitFuncType(const GoASTFuncType *e)
- {
- return NotImplemented(e);
- }
+ ValueObjectSP VisitEllipsis(const GoASTEllipsis *e) {
+ return NotImplemented(e);
+ }
- ValueObjectSP
- VisitFuncLit(const GoASTFuncLit *e)
- {
- return NotImplemented(e);
- }
+ ValueObjectSP VisitFuncType(const GoASTFuncType *e) {
+ return NotImplemented(e);
+ }
- ValueObjectSP
- VisitInterfaceType(const GoASTInterfaceType *e)
- {
- return NotImplemented(e);
- }
+ ValueObjectSP VisitFuncLit(const GoASTFuncLit *e) {
+ return NotImplemented(e);
+ }
- ValueObjectSP
- VisitKeyValueExpr(const GoASTKeyValueExpr *e)
- {
- return NotImplemented(e);
- }
+ ValueObjectSP VisitInterfaceType(const GoASTInterfaceType *e) {
+ return NotImplemented(e);
+ }
- ValueObjectSP
- VisitMapType(const GoASTMapType *e)
- {
- return NotImplemented(e);
- }
+ ValueObjectSP VisitKeyValueExpr(const GoASTKeyValueExpr *e) {
+ return NotImplemented(e);
+ }
- ValueObjectSP
- VisitSliceExpr(const GoASTSliceExpr *e)
- {
- return NotImplemented(e);
- }
+ ValueObjectSP VisitMapType(const GoASTMapType *e) {
+ return NotImplemented(e);
+ }
- ValueObjectSP
- VisitStructType(const GoASTStructType *e)
- {
- return NotImplemented(e);
- }
+ ValueObjectSP VisitSliceExpr(const GoASTSliceExpr *e) {
+ return NotImplemented(e);
+ }
- CompilerType EvaluateType(const GoASTExpr *e);
+ ValueObjectSP VisitStructType(const GoASTStructType *e) {
+ return NotImplemented(e);
+ }
- Error &
- error()
- {
- return m_error;
- }
+ CompilerType EvaluateType(const GoASTExpr *e);
- private:
- std::nullptr_t
- NotImplemented(const GoASTExpr *e)
- {
- m_error.SetErrorStringWithFormat("%s node not implemented", e->GetKindName());
- return nullptr;
- }
+ Error &error() { return m_error; }
- ExecutionContext m_exe_ctx;
- lldb::StackFrameSP m_frame;
- GoParser m_parser;
- DynamicValueType m_use_dynamic;
- Error m_error;
- llvm::StringRef m_package;
- std::vector<std::unique_ptr<GoASTStmt>> m_statements;
+private:
+ std::nullptr_t NotImplemented(const GoASTExpr *e) {
+ m_error.SetErrorStringWithFormat("%s node not implemented",
+ e->GetKindName());
+ return nullptr;
+ }
+
+ ExecutionContext m_exe_ctx;
+ lldb::StackFrameSP m_frame;
+ GoParser m_parser;
+ DynamicValueType m_use_dynamic;
+ Error m_error;
+ llvm::StringRef m_package;
+ std::vector<std::unique_ptr<GoASTStmt>> m_statements;
};
-VariableSP
-FindGlobalVariable(TargetSP target, llvm::Twine name)
-{
- ConstString fullname(name.str());
- VariableList variable_list;
- const bool append = true;
- if (!target)
- {
- return nullptr;
- }
- const uint32_t match_count = target->GetImages().FindGlobalVariables(fullname, append, 1, variable_list);
- if (match_count == 1)
- {
- return variable_list.GetVariableAtIndex(0);
- }
+VariableSP FindGlobalVariable(TargetSP target, llvm::Twine name) {
+ ConstString fullname(name.str());
+ VariableList variable_list;
+ const bool append = true;
+ if (!target) {
return nullptr;
+ }
+ const uint32_t match_count = target->GetImages().FindGlobalVariables(
+ fullname, append, 1, variable_list);
+ if (match_count == 1) {
+ return variable_list.GetVariableAtIndex(0);
+ }
+ return nullptr;
}
-CompilerType
-LookupType(TargetSP target, ConstString name)
-{
- if (!target)
- return CompilerType();
- SymbolContext sc;
- TypeList type_list;
- llvm::DenseSet<SymbolFile *> searched_symbol_files;
- uint32_t num_matches = target->GetImages().FindTypes(sc, name, false, 2, searched_symbol_files, type_list);
- if (num_matches > 0)
- {
- return type_list.GetTypeAtIndex(0)->GetFullCompilerType();
- }
+CompilerType LookupType(TargetSP target, ConstString name) {
+ if (!target)
return CompilerType();
+ SymbolContext sc;
+ TypeList type_list;
+ llvm::DenseSet<SymbolFile *> searched_symbol_files;
+ uint32_t num_matches = target->GetImages().FindTypes(
+ sc, name, false, 2, searched_symbol_files, type_list);
+ if (num_matches > 0) {
+ return type_list.GetTypeAtIndex(0)->GetFullCompilerType();
+ }
+ return CompilerType();
}
-GoUserExpression::GoUserExpression(ExecutionContextScope &exe_scope, const char *expr, const char *expr_prefix,
- lldb::LanguageType language, ResultType desired_type,
+GoUserExpression::GoUserExpression(ExecutionContextScope &exe_scope,
+ const char *expr, const char *expr_prefix,
+ lldb::LanguageType language,
+ ResultType desired_type,
const EvaluateExpressionOptions &options)
- : UserExpression(exe_scope, expr, expr_prefix, language, desired_type, options)
-{
-}
-
-bool
-GoUserExpression::Parse(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx,
- lldb_private::ExecutionPolicy execution_policy, bool keep_result_in_memory,
- bool generate_debug_info)
-{
- InstallContext(exe_ctx);
- m_interpreter.reset(new GoInterpreter(exe_ctx, GetUserText()));
- if (m_interpreter->Parse())
- return true;
- const char *error_cstr = m_interpreter->error().AsCString();
- if (error_cstr && error_cstr[0])
- diagnostic_manager.PutCString(eDiagnosticSeverityError, error_cstr);
- else
- diagnostic_manager.Printf(eDiagnosticSeverityError, "expression can't be interpreted or run");
- return false;
+ : UserExpression(exe_scope, expr, expr_prefix, language, desired_type,
+ options) {}
+
+bool GoUserExpression::Parse(DiagnosticManager &diagnostic_manager,
+ ExecutionContext &exe_ctx,
+ lldb_private::ExecutionPolicy execution_policy,
+ bool keep_result_in_memory,
+ bool generate_debug_info) {
+ InstallContext(exe_ctx);
+ m_interpreter.reset(new GoInterpreter(exe_ctx, GetUserText()));
+ if (m_interpreter->Parse())
+ return true;
+ const char *error_cstr = m_interpreter->error().AsCString();
+ if (error_cstr && error_cstr[0])
+ diagnostic_manager.PutCString(eDiagnosticSeverityError, error_cstr);
+ else
+ diagnostic_manager.Printf(eDiagnosticSeverityError,
+ "expression can't be interpreted or run");
+ return false;
}
lldb::ExpressionResults
-GoUserExpression::DoExecute(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx,
- const EvaluateExpressionOptions &options, lldb::UserExpressionSP &shared_ptr_to_me,
- lldb::ExpressionVariableSP &result)
-{
- Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP));
+GoUserExpression::DoExecute(DiagnosticManager &diagnostic_manager,
+ ExecutionContext &exe_ctx,
+ const EvaluateExpressionOptions &options,
+ lldb::UserExpressionSP &shared_ptr_to_me,
+ lldb::ExpressionVariableSP &result) {
+ Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_EXPRESSIONS |
+ LIBLLDB_LOG_STEP));
- lldb_private::ExecutionPolicy execution_policy = options.GetExecutionPolicy();
- lldb::ExpressionResults execution_results = lldb::eExpressionSetupError;
+ lldb_private::ExecutionPolicy execution_policy = options.GetExecutionPolicy();
+ lldb::ExpressionResults execution_results = lldb::eExpressionSetupError;
- Process *process = exe_ctx.GetProcessPtr();
- Target *target = exe_ctx.GetTargetPtr();
+ Process *process = exe_ctx.GetProcessPtr();
+ Target *target = exe_ctx.GetTargetPtr();
- if (target == nullptr || process == nullptr || process->GetState() != lldb::eStateStopped)
- {
- if (execution_policy == eExecutionPolicyAlways)
- {
- if (log)
- log->Printf("== [GoUserExpression::Evaluate] Expression may not run, but is not constant ==");
+ if (target == nullptr || process == nullptr ||
+ process->GetState() != lldb::eStateStopped) {
+ if (execution_policy == eExecutionPolicyAlways) {
+ if (log)
+ log->Printf("== [GoUserExpression::Evaluate] Expression may not run, "
+ "but is not constant ==");
- diagnostic_manager.PutCString(eDiagnosticSeverityError, "expression needed to run but couldn't");
+ diagnostic_manager.PutCString(eDiagnosticSeverityError,
+ "expression needed to run but couldn't");
- return execution_results;
- }
+ return execution_results;
}
+ }
- m_interpreter->set_use_dynamic(options.GetUseDynamic());
- ValueObjectSP result_val_sp = m_interpreter->Evaluate(exe_ctx);
- Error err = m_interpreter->error();
- m_interpreter.reset();
-
- if (!result_val_sp)
- {
- const char *error_cstr = err.AsCString();
- if (error_cstr && error_cstr[0])
- diagnostic_manager.PutCString(eDiagnosticSeverityError, error_cstr);
- else
- diagnostic_manager.PutCString(eDiagnosticSeverityError, "expression can't be interpreted or run");
- return lldb::eExpressionDiscarded;
- }
- result.reset(new ExpressionVariable(ExpressionVariable::eKindGo));
- result->m_live_sp = result->m_frozen_sp = result_val_sp;
- result->m_flags |= ExpressionVariable::EVIsProgramReference;
- PersistentExpressionState *pv = target->GetPersistentExpressionStateForLanguage(eLanguageTypeGo);
- if (pv != nullptr)
- {
- result->SetName(pv->GetNextPersistentVariableName());
- pv->AddVariable(result);
- }
- return lldb::eExpressionCompleted;
-}
+ m_interpreter->set_use_dynamic(options.GetUseDynamic());
+ ValueObjectSP result_val_sp = m_interpreter->Evaluate(exe_ctx);
+ Error err = m_interpreter->error();
+ m_interpreter.reset();
-bool
-GoUserExpression::GoInterpreter::Parse()
-{
- for (std::unique_ptr<GoASTStmt> stmt(m_parser.Statement()); stmt; stmt.reset(m_parser.Statement()))
- {
- if (m_parser.Failed())
- break;
- m_statements.emplace_back(std::move(stmt));
- }
- if (m_parser.Failed() || !m_parser.AtEOF())
- m_parser.GetError(m_error);
+ if (!result_val_sp) {
+ const char *error_cstr = err.AsCString();
+ if (error_cstr && error_cstr[0])
+ diagnostic_manager.PutCString(eDiagnosticSeverityError, error_cstr);
+ else
+ diagnostic_manager.PutCString(eDiagnosticSeverityError,
+ "expression can't be interpreted or run");
+ return lldb::eExpressionDiscarded;
+ }
+ result.reset(new ExpressionVariable(ExpressionVariable::eKindGo));
+ result->m_live_sp = result->m_frozen_sp = result_val_sp;
+ result->m_flags |= ExpressionVariable::EVIsProgramReference;
+ PersistentExpressionState *pv =
+ target->GetPersistentExpressionStateForLanguage(eLanguageTypeGo);
+ if (pv != nullptr) {
+ result->SetName(pv->GetNextPersistentVariableName());
+ pv->AddVariable(result);
+ }
+ return lldb::eExpressionCompleted;
+}
- return m_error.Success();
+bool GoUserExpression::GoInterpreter::Parse() {
+ for (std::unique_ptr<GoASTStmt> stmt(m_parser.Statement()); stmt;
+ stmt.reset(m_parser.Statement())) {
+ if (m_parser.Failed())
+ break;
+ m_statements.emplace_back(std::move(stmt));
+ }
+ if (m_parser.Failed() || !m_parser.AtEOF())
+ m_parser.GetError(m_error);
+
+ return m_error.Success();
}
ValueObjectSP
-GoUserExpression::GoInterpreter::Evaluate(ExecutionContext &exe_ctx)
-{
- m_exe_ctx = exe_ctx;
- ValueObjectSP result;
- for (const std::unique_ptr<GoASTStmt> &stmt : m_statements)
- {
- result = EvaluateStatement(stmt.get());
- if (m_error.Fail())
- return nullptr;
- }
- return result;
+GoUserExpression::GoInterpreter::Evaluate(ExecutionContext &exe_ctx) {
+ m_exe_ctx = exe_ctx;
+ ValueObjectSP result;
+ for (const std::unique_ptr<GoASTStmt> &stmt : m_statements) {
+ result = EvaluateStatement(stmt.get());
+ if (m_error.Fail())
+ return nullptr;
+ }
+ return result;
}
-ValueObjectSP
-GoUserExpression::GoInterpreter::EvaluateStatement(const lldb_private::GoASTStmt *stmt)
-{
- ValueObjectSP result;
- switch (stmt->GetKind())
- {
- case GoASTNode::eBlockStmt:
- {
- const GoASTBlockStmt *block = llvm::cast<GoASTBlockStmt>(stmt);
- for (size_t i = 0; i < block->NumList(); ++i)
- result = EvaluateStatement(block->GetList(i));
- break;
- }
- case GoASTNode::eBadStmt:
- m_parser.GetError(m_error);
- break;
- case GoASTNode::eExprStmt:
- {
- const GoASTExprStmt *expr = llvm::cast<GoASTExprStmt>(stmt);
- return EvaluateExpr(expr->GetX());
- }
- default:
- m_error.SetErrorStringWithFormat("%s node not supported", stmt->GetKindName());
- }
- return result;
+ValueObjectSP GoUserExpression::GoInterpreter::EvaluateStatement(
+ const lldb_private::GoASTStmt *stmt) {
+ ValueObjectSP result;
+ switch (stmt->GetKind()) {
+ case GoASTNode::eBlockStmt: {
+ const GoASTBlockStmt *block = llvm::cast<GoASTBlockStmt>(stmt);
+ for (size_t i = 0; i < block->NumList(); ++i)
+ result = EvaluateStatement(block->GetList(i));
+ break;
+ }
+ case GoASTNode::eBadStmt:
+ m_parser.GetError(m_error);
+ break;
+ case GoASTNode::eExprStmt: {
+ const GoASTExprStmt *expr = llvm::cast<GoASTExprStmt>(stmt);
+ return EvaluateExpr(expr->GetX());
+ }
+ default:
+ m_error.SetErrorStringWithFormat("%s node not supported",
+ stmt->GetKindName());
+ }
+ return result;
}
-ValueObjectSP
-GoUserExpression::GoInterpreter::EvaluateExpr(const lldb_private::GoASTExpr *e)
-{
- if (e)
- return e->Visit<ValueObjectSP>(this);
- return ValueObjectSP();
+ValueObjectSP GoUserExpression::GoInterpreter::EvaluateExpr(
+ const lldb_private::GoASTExpr *e) {
+ if (e)
+ return e->Visit<ValueObjectSP>(this);
+ return ValueObjectSP();
}
-ValueObjectSP
-GoUserExpression::GoInterpreter::VisitParenExpr(const lldb_private::GoASTParenExpr *e)
-{
- return EvaluateExpr(e->GetX());
+ValueObjectSP GoUserExpression::GoInterpreter::VisitParenExpr(
+ const lldb_private::GoASTParenExpr *e) {
+ return EvaluateExpr(e->GetX());
}
-ValueObjectSP
-GoUserExpression::GoInterpreter::VisitIdent(const GoASTIdent *e)
-{
- ValueObjectSP val;
- if (m_frame)
- {
- VariableSP var_sp;
- std::string varname = e->GetName().m_value.str();
- if (varname.size() > 1 && varname[0] == '$')
- {
- RegisterContextSP reg_ctx_sp = m_frame->GetRegisterContext();
- const RegisterInfo *reg = reg_ctx_sp->GetRegisterInfoByName(varname.c_str() + 1);
- if (reg)
- {
- std::string type;
- switch (reg->encoding)
- {
- case lldb::eEncodingSint:
- type.append("int");
- break;
- case lldb::eEncodingUint:
- type.append("uint");
- break;
- case lldb::eEncodingIEEE754:
- type.append("float");
- break;
- default:
- m_error.SetErrorString("Invalid register encoding");
- return nullptr;
- }
- switch (reg->byte_size)
- {
- case 8:
- type.append("64");
- break;
- case 4:
- type.append("32");
- break;
- case 2:
- type.append("16");
- break;
- case 1:
- type.append("8");
- break;
- default:
- m_error.SetErrorString("Invalid register size");
- return nullptr;
- }
- ValueObjectSP regVal =
- ValueObjectRegister::Create(m_frame.get(), reg_ctx_sp, reg->kinds[eRegisterKindLLDB]);
- CompilerType goType = LookupType(m_frame->CalculateTarget(), ConstString(type));
- if (regVal)
- {
- regVal = regVal->Cast(goType);
- return regVal;
- }
- }
- m_error.SetErrorString("Invalid register name");
- return nullptr;
+ValueObjectSP GoUserExpression::GoInterpreter::VisitIdent(const GoASTIdent *e) {
+ ValueObjectSP val;
+ if (m_frame) {
+ VariableSP var_sp;
+ std::string varname = e->GetName().m_value.str();
+ if (varname.size() > 1 && varname[0] == '$') {
+ RegisterContextSP reg_ctx_sp = m_frame->GetRegisterContext();
+ const RegisterInfo *reg =
+ reg_ctx_sp->GetRegisterInfoByName(varname.c_str() + 1);
+ if (reg) {
+ std::string type;
+ switch (reg->encoding) {
+ case lldb::eEncodingSint:
+ type.append("int");
+ break;
+ case lldb::eEncodingUint:
+ type.append("uint");
+ break;
+ case lldb::eEncodingIEEE754:
+ type.append("float");
+ break;
+ default:
+ m_error.SetErrorString("Invalid register encoding");
+ return nullptr;
}
- VariableListSP var_list_sp(m_frame->GetInScopeVariableList(false));
- if (var_list_sp)
- {
- var_sp = var_list_sp->FindVariable(ConstString(varname));
- if (var_sp)
- val = m_frame->GetValueObjectForFrameVariable(var_sp, m_use_dynamic);
- else
- {
- // When a variable is on the heap instead of the stack, go records a variable
- // '&x' instead of 'x'.
- var_sp = var_list_sp->FindVariable(ConstString("&" + varname));
- if (var_sp)
- {
- val = m_frame->GetValueObjectForFrameVariable(var_sp, m_use_dynamic);
- if (val)
- val = val->Dereference(m_error);
- if (m_error.Fail())
- return nullptr;
- }
- }
+ switch (reg->byte_size) {
+ case 8:
+ type.append("64");
+ break;
+ case 4:
+ type.append("32");
+ break;
+ case 2:
+ type.append("16");
+ break;
+ case 1:
+ type.append("8");
+ break;
+ default:
+ m_error.SetErrorString("Invalid register size");
+ return nullptr;
+ }
+ ValueObjectSP regVal = ValueObjectRegister::Create(
+ m_frame.get(), reg_ctx_sp, reg->kinds[eRegisterKindLLDB]);
+ CompilerType goType =
+ LookupType(m_frame->CalculateTarget(), ConstString(type));
+ if (regVal) {
+ regVal = regVal->Cast(goType);
+ return regVal;
}
- if (!val)
- {
- m_error.Clear();
- TargetSP target = m_frame->CalculateTarget();
- if (!target)
- {
- m_error.SetErrorString("No target");
- return nullptr;
- }
- var_sp = FindGlobalVariable(target, m_package + "." + e->GetName().m_value);
- if (var_sp)
- return m_frame->TrackGlobalVariable(var_sp, m_use_dynamic);
+ }
+ m_error.SetErrorString("Invalid register name");
+ return nullptr;
+ }
+ VariableListSP var_list_sp(m_frame->GetInScopeVariableList(false));
+ if (var_list_sp) {
+ var_sp = var_list_sp->FindVariable(ConstString(varname));
+ if (var_sp)
+ val = m_frame->GetValueObjectForFrameVariable(var_sp, m_use_dynamic);
+ else {
+ // When a variable is on the heap instead of the stack, go records a
+ // variable
+ // '&x' instead of 'x'.
+ var_sp = var_list_sp->FindVariable(ConstString("&" + varname));
+ if (var_sp) {
+ val = m_frame->GetValueObjectForFrameVariable(var_sp, m_use_dynamic);
+ if (val)
+ val = val->Dereference(m_error);
+ if (m_error.Fail())
+ return nullptr;
}
+ }
}
- if (!val)
- m_error.SetErrorStringWithFormat("Unknown variable %s", e->GetName().m_value.str().c_str());
- return val;
+ if (!val) {
+ m_error.Clear();
+ TargetSP target = m_frame->CalculateTarget();
+ if (!target) {
+ m_error.SetErrorString("No target");
+ return nullptr;
+ }
+ var_sp =
+ FindGlobalVariable(target, m_package + "." + e->GetName().m_value);
+ if (var_sp)
+ return m_frame->TrackGlobalVariable(var_sp, m_use_dynamic);
+ }
+ }
+ if (!val)
+ m_error.SetErrorStringWithFormat("Unknown variable %s",
+ e->GetName().m_value.str().c_str());
+ return val;
}
ValueObjectSP
-GoUserExpression::GoInterpreter::VisitStarExpr(const GoASTStarExpr *e)
-{
- ValueObjectSP target = EvaluateExpr(e->GetX());
- if (!target)
- return nullptr;
- return target->Dereference(m_error);
+GoUserExpression::GoInterpreter::VisitStarExpr(const GoASTStarExpr *e) {
+ ValueObjectSP target = EvaluateExpr(e->GetX());
+ if (!target)
+ return nullptr;
+ return target->Dereference(m_error);
}
-ValueObjectSP
-GoUserExpression::GoInterpreter::VisitSelectorExpr(const lldb_private::GoASTSelectorExpr *e)
-{
- ValueObjectSP target = EvaluateExpr(e->GetX());
- if (target)
- {
- if (target->GetCompilerType().IsPointerType())
- {
- target = target->Dereference(m_error);
- if (m_error.Fail())
- return nullptr;
- }
- ConstString field(e->GetSel()->GetName().m_value);
- ValueObjectSP result = target->GetChildMemberWithName(field, true);
- if (!result)
- m_error.SetErrorStringWithFormat("Unknown child %s", field.AsCString());
- return result;
- }
- if (const GoASTIdent *package = llvm::dyn_cast<GoASTIdent>(e->GetX()))
- {
- if (VariableSP global = FindGlobalVariable(m_exe_ctx.GetTargetSP(),
- package->GetName().m_value + "." + e->GetSel()->GetName().m_value))
- {
- if (m_frame)
- {
- m_error.Clear();
- return m_frame->GetValueObjectForFrameVariable(global, m_use_dynamic);
- }
- }
+ValueObjectSP GoUserExpression::GoInterpreter::VisitSelectorExpr(
+ const lldb_private::GoASTSelectorExpr *e) {
+ ValueObjectSP target = EvaluateExpr(e->GetX());
+ if (target) {
+ if (target->GetCompilerType().IsPointerType()) {
+ target = target->Dereference(m_error);
+ if (m_error.Fail())
+ return nullptr;
}
- if (const GoASTBasicLit *packageLit = llvm::dyn_cast<GoASTBasicLit>(e->GetX()))
- {
- if (packageLit->GetValue().m_type == GoLexer::LIT_STRING)
- {
- std::string value = packageLit->GetValue().m_value.str();
- value = value.substr(1, value.size() - 2);
- if (VariableSP global =
- FindGlobalVariable(m_exe_ctx.GetTargetSP(), value + "." + e->GetSel()->GetName().m_value))
- {
- if (m_frame)
- {
- m_error.Clear();
- return m_frame->TrackGlobalVariable(global, m_use_dynamic);
- }
- }
+ ConstString field(e->GetSel()->GetName().m_value);
+ ValueObjectSP result = target->GetChildMemberWithName(field, true);
+ if (!result)
+ m_error.SetErrorStringWithFormat("Unknown child %s", field.AsCString());
+ return result;
+ }
+ if (const GoASTIdent *package = llvm::dyn_cast<GoASTIdent>(e->GetX())) {
+ if (VariableSP global = FindGlobalVariable(
+ m_exe_ctx.GetTargetSP(), package->GetName().m_value + "." +
+ e->GetSel()->GetName().m_value)) {
+ if (m_frame) {
+ m_error.Clear();
+ return m_frame->GetValueObjectForFrameVariable(global, m_use_dynamic);
+ }
+ }
+ }
+ if (const GoASTBasicLit *packageLit =
+ llvm::dyn_cast<GoASTBasicLit>(e->GetX())) {
+ if (packageLit->GetValue().m_type == GoLexer::LIT_STRING) {
+ std::string value = packageLit->GetValue().m_value.str();
+ value = value.substr(1, value.size() - 2);
+ if (VariableSP global = FindGlobalVariable(
+ m_exe_ctx.GetTargetSP(),
+ value + "." + e->GetSel()->GetName().m_value)) {
+ if (m_frame) {
+ m_error.Clear();
+ return m_frame->TrackGlobalVariable(global, m_use_dynamic);
}
+ }
}
- // EvaluateExpr should have already set m_error.
- return target;
+ }
+ // EvaluateExpr should have already set m_error.
+ return target;
}
-ValueObjectSP
-GoUserExpression::GoInterpreter::VisitBasicLit(const lldb_private::GoASTBasicLit *e)
-{
- std::string value = e->GetValue().m_value.str();
- if (e->GetValue().m_type != GoLexer::LIT_INTEGER)
- {
- m_error.SetErrorStringWithFormat("Unsupported literal %s", value.c_str());
- return nullptr;
- }
- errno = 0;
- int64_t intvalue = strtol(value.c_str(), nullptr, 0);
- if (errno != 0)
- {
- m_error.SetErrorToErrno();
- return nullptr;
- }
- DataBufferSP buf(new DataBufferHeap(sizeof(intvalue), 0));
- TargetSP target = m_exe_ctx.GetTargetSP();
- if (!target)
- {
- m_error.SetErrorString("No target");
- return nullptr;
- }
- ByteOrder order = target->GetArchitecture().GetByteOrder();
- uint8_t addr_size = target->GetArchitecture().GetAddressByteSize();
- DataEncoder enc(buf, order, addr_size);
- enc.PutU64(0, static_cast<uint64_t>(intvalue));
- DataExtractor data(buf, order, addr_size);
-
- CompilerType type = LookupType(target, ConstString("int64"));
- return ValueObject::CreateValueObjectFromData(nullptr, data, m_exe_ctx, type);
+ValueObjectSP GoUserExpression::GoInterpreter::VisitBasicLit(
+ const lldb_private::GoASTBasicLit *e) {
+ std::string value = e->GetValue().m_value.str();
+ if (e->GetValue().m_type != GoLexer::LIT_INTEGER) {
+ m_error.SetErrorStringWithFormat("Unsupported literal %s", value.c_str());
+ return nullptr;
+ }
+ errno = 0;
+ int64_t intvalue = strtol(value.c_str(), nullptr, 0);
+ if (errno != 0) {
+ m_error.SetErrorToErrno();
+ return nullptr;
+ }
+ DataBufferSP buf(new DataBufferHeap(sizeof(intvalue), 0));
+ TargetSP target = m_exe_ctx.GetTargetSP();
+ if (!target) {
+ m_error.SetErrorString("No target");
+ return nullptr;
+ }
+ ByteOrder order = target->GetArchitecture().GetByteOrder();
+ uint8_t addr_size = target->GetArchitecture().GetAddressByteSize();
+ DataEncoder enc(buf, order, addr_size);
+ enc.PutU64(0, static_cast<uint64_t>(intvalue));
+ DataExtractor data(buf, order, addr_size);
+
+ CompilerType type = LookupType(target, ConstString("int64"));
+ return ValueObject::CreateValueObjectFromData(nullptr, data, m_exe_ctx, type);
}
-ValueObjectSP
-GoUserExpression::GoInterpreter::VisitIndexExpr(const lldb_private::GoASTIndexExpr *e)
-{
- ValueObjectSP target = EvaluateExpr(e->GetX());
- if (!target)
- return nullptr;
- ValueObjectSP index = EvaluateExpr(e->GetIndex());
- if (!index)
- return nullptr;
- bool is_signed;
- if (!index->GetCompilerType().IsIntegerType(is_signed))
- {
- m_error.SetErrorString("Unsupported index");
+ValueObjectSP GoUserExpression::GoInterpreter::VisitIndexExpr(
+ const lldb_private::GoASTIndexExpr *e) {
+ ValueObjectSP target = EvaluateExpr(e->GetX());
+ if (!target)
+ return nullptr;
+ ValueObjectSP index = EvaluateExpr(e->GetIndex());
+ if (!index)
+ return nullptr;
+ bool is_signed;
+ if (!index->GetCompilerType().IsIntegerType(is_signed)) {
+ m_error.SetErrorString("Unsupported index");
+ return nullptr;
+ }
+ size_t idx;
+ if (is_signed)
+ idx = index->GetValueAsSigned(0);
+ else
+ idx = index->GetValueAsUnsigned(0);
+ if (GoASTContext::IsGoSlice(target->GetCompilerType())) {
+ target = target->GetStaticValue();
+ ValueObjectSP cap =
+ target->GetChildMemberWithName(ConstString("cap"), true);
+ if (cap) {
+ uint64_t capval = cap->GetValueAsUnsigned(0);
+ if (idx >= capval) {
+ m_error.SetErrorStringWithFormat("Invalid index %" PRIu64
+ " , cap = %" PRIu64,
+ uint64_t(idx), capval);
return nullptr;
+ }
}
- size_t idx;
- if (is_signed)
- idx = index->GetValueAsSigned(0);
- else
- idx = index->GetValueAsUnsigned(0);
- if (GoASTContext::IsGoSlice(target->GetCompilerType()))
- {
- target = target->GetStaticValue();
- ValueObjectSP cap = target->GetChildMemberWithName(ConstString("cap"), true);
- if (cap)
- {
- uint64_t capval = cap->GetValueAsUnsigned(0);
- if (idx >= capval)
- {
- m_error.SetErrorStringWithFormat("Invalid index %" PRIu64 " , cap = %" PRIu64, uint64_t(idx), capval);
- return nullptr;
- }
- }
- target = target->GetChildMemberWithName(ConstString("array"), true);
- if (target && m_use_dynamic != eNoDynamicValues)
- {
- ValueObjectSP dynamic = target->GetDynamicValue(m_use_dynamic);
- if (dynamic)
- target = dynamic;
- }
- if (!target)
- return nullptr;
- return target->GetSyntheticArrayMember(idx, true);
+ target = target->GetChildMemberWithName(ConstString("array"), true);
+ if (target && m_use_dynamic != eNoDynamicValues) {
+ ValueObjectSP dynamic = target->GetDynamicValue(m_use_dynamic);
+ if (dynamic)
+ target = dynamic;
}
- return target->GetChildAtIndex(idx, true);
+ if (!target)
+ return nullptr;
+ return target->GetSyntheticArrayMember(idx, true);
+ }
+ return target->GetChildAtIndex(idx, true);
}
ValueObjectSP
-GoUserExpression::GoInterpreter::VisitUnaryExpr(const GoASTUnaryExpr *e)
-{
- ValueObjectSP x = EvaluateExpr(e->GetX());
- if (!x)
- return nullptr;
- switch (e->GetOp())
- {
- case GoLexer::OP_AMP:
- {
- CompilerType type = x->GetCompilerType().GetPointerType();
- uint64_t address = x->GetAddressOf();
- return ValueObject::CreateValueObjectFromAddress(nullptr, address, m_exe_ctx, type);
- }
- case GoLexer::OP_PLUS:
- return x;
- default:
- m_error.SetErrorStringWithFormat("Operator %s not supported",
- GoLexer::LookupToken(e->GetOp()).str().c_str());
- return nullptr;
- }
+GoUserExpression::GoInterpreter::VisitUnaryExpr(const GoASTUnaryExpr *e) {
+ ValueObjectSP x = EvaluateExpr(e->GetX());
+ if (!x)
+ return nullptr;
+ switch (e->GetOp()) {
+ case GoLexer::OP_AMP: {
+ CompilerType type = x->GetCompilerType().GetPointerType();
+ uint64_t address = x->GetAddressOf();
+ return ValueObject::CreateValueObjectFromAddress(nullptr, address,
+ m_exe_ctx, type);
+ }
+ case GoLexer::OP_PLUS:
+ return x;
+ default:
+ m_error.SetErrorStringWithFormat(
+ "Operator %s not supported",
+ GoLexer::LookupToken(e->GetOp()).str().c_str());
+ return nullptr;
+ }
}
-CompilerType
-GoUserExpression::GoInterpreter::EvaluateType(const GoASTExpr *e)
-{
- TargetSP target = m_exe_ctx.GetTargetSP();
- if (auto *id = llvm::dyn_cast<GoASTIdent>(e))
- {
- CompilerType result = LookupType(target, ConstString(id->GetName().m_value));
- if (result.IsValid())
- return result;
- std::string fullname = (m_package + "." + id->GetName().m_value).str();
- result = LookupType(target, ConstString(fullname));
- if (!result)
- m_error.SetErrorStringWithFormat("Unknown type %s", fullname.c_str());
- return result;
- }
- if (auto *sel = llvm::dyn_cast<GoASTSelectorExpr>(e))
- {
- std::string package;
- if (auto *pkg_node = llvm::dyn_cast<GoASTIdent>(sel->GetX()))
- {
- package = pkg_node->GetName().m_value.str();
- }
- else if (auto *str_node = llvm::dyn_cast<GoASTBasicLit>(sel->GetX()))
- {
- if (str_node->GetValue().m_type == GoLexer::LIT_STRING)
- {
- package = str_node->GetValue().m_value.substr(1).str();
- package.resize(package.length() - 1);
- }
- }
- if (package.empty())
- {
- m_error.SetErrorStringWithFormat("Invalid %s in type expression", sel->GetX()->GetKindName());
- return CompilerType();
- }
- std::string fullname = (package + "." + sel->GetSel()->GetName().m_value).str();
- CompilerType result = LookupType(target, ConstString(fullname));
- if (!result)
- m_error.SetErrorStringWithFormat("Unknown type %s", fullname.c_str());
- return result;
- }
- if (auto *star = llvm::dyn_cast<GoASTStarExpr>(e))
- {
- CompilerType elem = EvaluateType(star->GetX());
- return elem.GetPointerType();
- }
- if (auto *paren = llvm::dyn_cast<GoASTParenExpr>(e))
- return EvaluateType(paren->GetX());
- if (auto *array = llvm::dyn_cast<GoASTArrayType>(e))
- {
- CompilerType elem = EvaluateType(array->GetElt());
- }
-
- m_error.SetErrorStringWithFormat("Invalid %s in type expression", e->GetKindName());
- return CompilerType();
+CompilerType GoUserExpression::GoInterpreter::EvaluateType(const GoASTExpr *e) {
+ TargetSP target = m_exe_ctx.GetTargetSP();
+ if (auto *id = llvm::dyn_cast<GoASTIdent>(e)) {
+ CompilerType result =
+ LookupType(target, ConstString(id->GetName().m_value));
+ if (result.IsValid())
+ return result;
+ std::string fullname = (m_package + "." + id->GetName().m_value).str();
+ result = LookupType(target, ConstString(fullname));
+ if (!result)
+ m_error.SetErrorStringWithFormat("Unknown type %s", fullname.c_str());
+ return result;
+ }
+ if (auto *sel = llvm::dyn_cast<GoASTSelectorExpr>(e)) {
+ std::string package;
+ if (auto *pkg_node = llvm::dyn_cast<GoASTIdent>(sel->GetX())) {
+ package = pkg_node->GetName().m_value.str();
+ } else if (auto *str_node = llvm::dyn_cast<GoASTBasicLit>(sel->GetX())) {
+ if (str_node->GetValue().m_type == GoLexer::LIT_STRING) {
+ package = str_node->GetValue().m_value.substr(1).str();
+ package.resize(package.length() - 1);
+ }
+ }
+ if (package.empty()) {
+ m_error.SetErrorStringWithFormat("Invalid %s in type expression",
+ sel->GetX()->GetKindName());
+ return CompilerType();
+ }
+ std::string fullname =
+ (package + "." + sel->GetSel()->GetName().m_value).str();
+ CompilerType result = LookupType(target, ConstString(fullname));
+ if (!result)
+ m_error.SetErrorStringWithFormat("Unknown type %s", fullname.c_str());
+ return result;
+ }
+ if (auto *star = llvm::dyn_cast<GoASTStarExpr>(e)) {
+ CompilerType elem = EvaluateType(star->GetX());
+ return elem.GetPointerType();
+ }
+ if (auto *paren = llvm::dyn_cast<GoASTParenExpr>(e))
+ return EvaluateType(paren->GetX());
+ if (auto *array = llvm::dyn_cast<GoASTArrayType>(e)) {
+ CompilerType elem = EvaluateType(array->GetElt());
+ }
+
+ m_error.SetErrorStringWithFormat("Invalid %s in type expression",
+ e->GetKindName());
+ return CompilerType();
}
-ValueObjectSP
-GoUserExpression::GoInterpreter::VisitCallExpr(const lldb_private::GoASTCallExpr *e)
-{
- ValueObjectSP x = EvaluateExpr(e->GetFun());
- if (x || e->NumArgs() != 1)
- {
- m_error.SetErrorStringWithFormat("Code execution not supported");
- return nullptr;
- }
- m_error.Clear();
- CompilerType type = EvaluateType(e->GetFun());
- if (!type)
- {
- return nullptr;
- }
- ValueObjectSP value = EvaluateExpr(e->GetArgs(0));
- if (!value)
- return nullptr;
- // TODO: Handle special conversions
- return value->Cast(type);
+ValueObjectSP GoUserExpression::GoInterpreter::VisitCallExpr(
+ const lldb_private::GoASTCallExpr *e) {
+ ValueObjectSP x = EvaluateExpr(e->GetFun());
+ if (x || e->NumArgs() != 1) {
+ m_error.SetErrorStringWithFormat("Code execution not supported");
+ return nullptr;
+ }
+ m_error.Clear();
+ CompilerType type = EvaluateType(e->GetFun());
+ if (!type) {
+ return nullptr;
+ }
+ ValueObjectSP value = EvaluateExpr(e->GetArgs(0));
+ if (!value)
+ return nullptr;
+ // TODO: Handle special conversions
+ return value->Cast(type);
}
-GoPersistentExpressionState::GoPersistentExpressionState() : PersistentExpressionState(eKindGo)
-{
-}
+GoPersistentExpressionState::GoPersistentExpressionState()
+ : PersistentExpressionState(eKindGo) {}
-ConstString
-GoPersistentExpressionState::GetNextPersistentVariableName()
-{
- char name_cstr[256];
- // We can't use the same variable format as clang.
- ::snprintf(name_cstr, sizeof(name_cstr), "$go%u", m_next_persistent_variable_id++);
- ConstString name(name_cstr);
- return name;
+ConstString GoPersistentExpressionState::GetNextPersistentVariableName() {
+ char name_cstr[256];
+ // We can't use the same variable format as clang.
+ ::snprintf(name_cstr, sizeof(name_cstr), "$go%u",
+ m_next_persistent_variable_id++);
+ ConstString name(name_cstr);
+ return name;
}
-void
-GoPersistentExpressionState::RemovePersistentVariable(lldb::ExpressionVariableSP variable)
-{
- RemoveVariable(variable);
+void GoPersistentExpressionState::RemovePersistentVariable(
+ lldb::ExpressionVariableSP variable) {
+ RemoveVariable(variable);
- const char *name = variable->GetName().AsCString();
+ const char *name = variable->GetName().AsCString();
- if (*(name++) != '$')
- return;
- if (*(name++) != 'g')
- return;
- if (*(name++) != 'o')
- return;
+ if (*(name++) != '$')
+ return;
+ if (*(name++) != 'g')
+ return;
+ if (*(name++) != 'o')
+ return;
- if (strtoul(name, nullptr, 0) == m_next_persistent_variable_id - 1)
- m_next_persistent_variable_id--;
+ if (strtoul(name, nullptr, 0) == m_next_persistent_variable_id - 1)
+ m_next_persistent_variable_id--;
}
diff --git a/lldb/source/Plugins/ExpressionParser/Go/GoUserExpression.h b/lldb/source/Plugins/ExpressionParser/Go/GoUserExpression.h
index 711a4c46215..4976f694bd7 100644
--- a/lldb/source/Plugins/ExpressionParser/Go/GoUserExpression.h
+++ b/lldb/source/Plugins/ExpressionParser/Go/GoUserExpression.h
@@ -16,83 +16,75 @@
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-forward.h"
-#include "lldb/lldb-private.h"
-#include "lldb/Expression/UserExpression.h"
#include "lldb/Expression/ExpressionVariable.h"
+#include "lldb/Expression/UserExpression.h"
#include "lldb/Target/ExecutionContext.h"
+#include "lldb/lldb-forward.h"
+#include "lldb/lldb-private.h"
-namespace lldb_private
-{
+namespace lldb_private {
class GoParser;
-class GoPersistentExpressionState : public PersistentExpressionState
-{
- public:
- GoPersistentExpressionState();
+class GoPersistentExpressionState : public PersistentExpressionState {
+public:
+ GoPersistentExpressionState();
- ConstString GetNextPersistentVariableName() override;
+ ConstString GetNextPersistentVariableName() override;
- void RemovePersistentVariable(lldb::ExpressionVariableSP variable) override;
+ void RemovePersistentVariable(lldb::ExpressionVariableSP variable) override;
- lldb::addr_t
- LookupSymbol(const ConstString &name) override
- {
- return LLDB_INVALID_ADDRESS;
- }
+ lldb::addr_t LookupSymbol(const ConstString &name) override {
+ return LLDB_INVALID_ADDRESS;
+ }
- static bool
- classof(const PersistentExpressionState *pv)
- {
- return pv->getKind() == PersistentExpressionState::eKindGo;
- }
+ static bool classof(const PersistentExpressionState *pv) {
+ return pv->getKind() == PersistentExpressionState::eKindGo;
+ }
- private:
- uint32_t m_next_persistent_variable_id; ///< The counter used by GetNextResultName().
+private:
+ uint32_t m_next_persistent_variable_id; ///< The counter used by
+ ///GetNextResultName().
};
//----------------------------------------------------------------------
-/// @class GoUserExpression GoUserExpression.h "lldb/Expression/GoUserExpression.h"
+/// @class GoUserExpression GoUserExpression.h
+/// "lldb/Expression/GoUserExpression.h"
/// @brief Encapsulates a single expression for use with Go
///
/// LLDB uses expressions for various purposes, notably to call functions
/// and as a backend for the expr command. GoUserExpression encapsulates
/// the objects needed to parse and interpret an expression.
//----------------------------------------------------------------------
-class GoUserExpression : public UserExpression
-{
- public:
- GoUserExpression(ExecutionContextScope &exe_scope, const char *expr, const char *expr_prefix,
- lldb::LanguageType language, ResultType desired_type, const EvaluateExpressionOptions &options);
-
- bool
- Parse(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx,
- lldb_private::ExecutionPolicy execution_policy, bool keep_result_in_memory,
- bool generate_debug_info) override;
-
- bool
- CanInterpret() override
- {
- return true;
- }
- bool
- FinalizeJITExecution(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx,
- lldb::ExpressionVariableSP &result,
- lldb::addr_t function_stack_bottom = LLDB_INVALID_ADDRESS,
- lldb::addr_t function_stack_top = LLDB_INVALID_ADDRESS) override
- {
- return true;
- }
-
- protected:
- lldb::ExpressionResults
- DoExecute(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx,
- const EvaluateExpressionOptions &options, lldb::UserExpressionSP &shared_ptr_to_me,
- lldb::ExpressionVariableSP &result) override;
-
- private:
- class GoInterpreter;
- std::unique_ptr<GoInterpreter> m_interpreter;
+class GoUserExpression : public UserExpression {
+public:
+ GoUserExpression(ExecutionContextScope &exe_scope, const char *expr,
+ const char *expr_prefix, lldb::LanguageType language,
+ ResultType desired_type,
+ const EvaluateExpressionOptions &options);
+
+ bool Parse(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx,
+ lldb_private::ExecutionPolicy execution_policy,
+ bool keep_result_in_memory, bool generate_debug_info) override;
+
+ bool CanInterpret() override { return true; }
+ bool FinalizeJITExecution(
+ DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx,
+ lldb::ExpressionVariableSP &result,
+ lldb::addr_t function_stack_bottom = LLDB_INVALID_ADDRESS,
+ lldb::addr_t function_stack_top = LLDB_INVALID_ADDRESS) override {
+ return true;
+ }
+
+protected:
+ lldb::ExpressionResults
+ DoExecute(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx,
+ const EvaluateExpressionOptions &options,
+ lldb::UserExpressionSP &shared_ptr_to_me,
+ lldb::ExpressionVariableSP &result) override;
+
+private:
+ class GoInterpreter;
+ std::unique_ptr<GoInterpreter> m_interpreter;
};
} // namespace lldb_private
diff --git a/lldb/source/Plugins/ExpressionParser/Go/gen_go_ast.py b/lldb/source/Plugins/ExpressionParser/Go/gen_go_ast.py
index 05b589a9976..3be0e5f506e 100644
--- a/lldb/source/Plugins/ExpressionParser/Go/gen_go_ast.py
+++ b/lldb/source/Plugins/ExpressionParser/Go/gen_go_ast.py
@@ -1,8 +1,17 @@
import StringIO
+
def addNodes():
addNode("ArrayType", "Expr", "len", "Expr", "elt", "Expr")
- addNode("AssignStmt", "Stmt", "lhs", "[]Expr", "rhs", "[]Expr", "define", "bool")
+ addNode(
+ "AssignStmt",
+ "Stmt",
+ "lhs",
+ "[]Expr",
+ "rhs",
+ "[]Expr",
+ "define",
+ "bool")
addNode("BadDecl", "Decl")
addNode("BadExpr", "Expr")
addNode("BadStmt", "Stmt")
@@ -11,7 +20,15 @@ def addNodes():
addNode("BlockStmt", "Stmt", "list", "[]Stmt")
addNode("Ident", "Expr", "name", "Token")
addNode("BranchStmt", "Stmt", "label", "Ident", "tok", "TokenType")
- addNode("CallExpr", "Expr", "fun", "Expr", "args", "[]Expr", "ellipsis", "bool")
+ addNode(
+ "CallExpr",
+ "Expr",
+ "fun",
+ "Expr",
+ "args",
+ "[]Expr",
+ "ellipsis",
+ "bool")
addNode("CaseClause", "Stmt", "list", "[]Expr", "body", "[]Stmt")
addNode("ChanType", "Expr", "dir", "ChanDir", "value", "Expr")
addNode("CommClause", "Stmt", "comm", "Stmt", "body", "[]Stmt")
@@ -21,15 +38,53 @@ def addNodes():
addNode("Ellipsis", "Expr", "elt", "Expr")
addNode("EmptyStmt", "Stmt")
addNode("ExprStmt", "Stmt", "x", "Expr")
- addNode("Field", "Node", "names", "[]Ident", "type", "Expr", "tag", "BasicLit")
+ addNode(
+ "Field",
+ "Node",
+ "names",
+ "[]Ident",
+ "type",
+ "Expr",
+ "tag",
+ "BasicLit")
addNode("FieldList", "Node", "list", "[]Field")
- addNode("ForStmt", "Stmt", "init", "Stmt", "cond", "Expr", "post", "Stmt", "body", "BlockStmt")
+ addNode(
+ "ForStmt",
+ "Stmt",
+ "init",
+ "Stmt",
+ "cond",
+ "Expr",
+ "post",
+ "Stmt",
+ "body",
+ "BlockStmt")
addNode("FuncType", "Expr", "params", "FieldList", "results", "FieldList")
- addNode("FuncDecl", "Decl", "recv", "FieldList", "name", "Ident", "type", "FuncType", "body", "BlockStmt")
+ addNode(
+ "FuncDecl",
+ "Decl",
+ "recv",
+ "FieldList",
+ "name",
+ "Ident",
+ "type",
+ "FuncType",
+ "body",
+ "BlockStmt")
addNode("FuncLit", "Expr", "type", "FuncType", "body", "BlockStmt")
addNode("GenDecl", "Decl", "tok", "TokenType", "specs", "[]Spec")
addNode("GoStmt", "Stmt", "call", "CallExpr")
- addNode("IfStmt", "Stmt", "init", "Stmt", "cond", "Expr", "body", "BlockStmt", "els", "Stmt")
+ addNode(
+ "IfStmt",
+ "Stmt",
+ "init",
+ "Stmt",
+ "cond",
+ "Expr",
+ "body",
+ "BlockStmt",
+ "els",
+ "Stmt")
addNode("ImportSpec", "Spec", "name", "Ident", "path", "BasicLit")
addNode("IncDecStmt", "Stmt", "x", "Expr", "tok", "TokenType")
addNode("IndexExpr", "Expr", "x", "Expr", "index", "Expr")
@@ -38,20 +93,68 @@ def addNodes():
addNode("LabeledStmt", "Stmt", "label", "Ident", "stmt", "Stmt")
addNode("MapType", "Expr", "key", "Expr", "value", "Expr")
addNode("ParenExpr", "Expr", "x", "Expr")
- addNode("RangeStmt", "Stmt", "key", "Expr", "value", "Expr", "define", "bool", "x", "Expr", "body", "BlockStmt")
+ addNode(
+ "RangeStmt",
+ "Stmt",
+ "key",
+ "Expr",
+ "value",
+ "Expr",
+ "define",
+ "bool",
+ "x",
+ "Expr",
+ "body",
+ "BlockStmt")
addNode("ReturnStmt", "Stmt", "results", "[]Expr")
addNode("SelectStmt", "Stmt", "body", "BlockStmt")
addNode("SelectorExpr", "Expr", "x", "Expr", "sel", "Ident")
addNode("SendStmt", "Stmt", "chan", "Expr", "value", "Expr")
- addNode("SliceExpr", "Expr", "x", "Expr", "low", "Expr", "high", "Expr", "max", "Expr", "slice3", "bool")
+ addNode(
+ "SliceExpr",
+ "Expr",
+ "x",
+ "Expr",
+ "low",
+ "Expr",
+ "high",
+ "Expr",
+ "max",
+ "Expr",
+ "slice3",
+ "bool")
addNode("StarExpr", "Expr", "x", "Expr")
addNode("StructType", "Expr", "fields", "FieldList")
- addNode("SwitchStmt", "Stmt", "init", "Stmt", "tag", "Expr", "body", "BlockStmt")
+ addNode(
+ "SwitchStmt",
+ "Stmt",
+ "init",
+ "Stmt",
+ "tag",
+ "Expr",
+ "body",
+ "BlockStmt")
addNode("TypeAssertExpr", "Expr", "x", "Expr", "type", "Expr")
addNode("TypeSpec", "Spec", "name", "Ident", "type", "Expr")
- addNode("TypeSwitchStmt", "Stmt", "init", "Stmt", "assign", "Stmt", "body", "BlockStmt")
+ addNode(
+ "TypeSwitchStmt",
+ "Stmt",
+ "init",
+ "Stmt",
+ "assign",
+ "Stmt",
+ "body",
+ "BlockStmt")
addNode("UnaryExpr", "Expr", "op", "TokenType", "x", "Expr")
- addNode("ValueSpec", "Spec", "names", "[]Ident", "type", "Expr", "values", "[]Expr")
+ addNode(
+ "ValueSpec",
+ "Spec",
+ "names",
+ "[]Ident",
+ "type",
+ "Expr",
+ "values",
+ "[]Expr")
addParent("Decl", "Node")
addParent("Expr", "Node")
addParent("Spec", "Node")
@@ -59,6 +162,7 @@ def addNodes():
class Member(object):
+
def __init__(self, name, typename):
self.title = name.title()
self.sname = name
@@ -75,13 +179,14 @@ class Member(object):
self.argtype = 'GoAST' + typename
self.mtype = 'std::unique_ptr<%s>' % self.argtype
self.mname = self.mname + '_up'
-
+
kinds = {}
parentClasses = StringIO.StringIO()
childClasses = StringIO.StringIO()
walker = StringIO.StringIO()
+
def startClass(name, parent, out):
out.write("""
class GoAST%s : public GoAST%s
@@ -89,6 +194,7 @@ class GoAST%s : public GoAST%s
public:
""" % (name, parent))
+
def endClass(name, out):
out.write("""
%(name)s(const %(name)s &) = delete;
@@ -96,6 +202,7 @@ def endClass(name, out):
};
""" % {'name': 'GoAST' + name})
+
def addNode(name, parent, *children):
startClass(name, parent, childClasses)
l = kinds.setdefault(parent, [])
@@ -114,10 +221,11 @@ def addNode(name, parent, *children):
{
return n->GetKind() == e%(name)s;
}
- """ % {'name':name})
+ """ % {'name': name})
addChildren(name, children)
endClass(name, childClasses)
+
def isValueType(typename):
if typename[0].islower():
return True
@@ -161,7 +269,7 @@ def addConstructor(name, parent, children):
~GoAST%s() override = default;
""" % name)
-
+
def addChildren(name, children):
if len(children) == 0:
return
@@ -169,7 +277,7 @@ def addChildren(name, children):
case e%(n)s:
{
GoAST%(n)s *n = llvm::cast<GoAST%(n)s>(this);
- (void)n;""" % {'n':name})
+ (void)n;""" % {'n': name})
for c in children:
if c.is_list:
childClasses.write("""
@@ -217,14 +325,14 @@ def addChildren(name, children):
{
%(set)s;
}
-""" % {'const':const, 'title': c.title, 'sname': c.sname, 'get': get, 'set': set, 'type': t, 'mname': c.mname})
+""" % {'const': const, 'title': c.title, 'sname': c.sname, 'get': get, 'set': set, 'type': t, 'mname': c.mname})
childClasses.write('\n private:\n friend class GoASTNode;\n')
walker.write("""
return;
}""")
for c in children:
- childClasses.write(' %s %s;\n' %(c.mtype, c.mname))
-
+ childClasses.write(' %s %s;\n' % (c.mtype, c.mname))
+
def addParent(name, parent):
startClass(name, parent, parentClasses)
@@ -244,7 +352,7 @@ def addParent(name, parent):
private:
""" % (minName, maxName, name))
endClass(name, parentClasses)
-
+
addNodes()
print """//===-- GoAST.h -------------------------------------------------*- C++ -*-===//
@@ -305,7 +413,7 @@ print """ };
private:
const NodeKind m_kind;
-
+
GoASTNode(const GoASTNode &) = delete;
const GoASTNode &operator=(const GoASTNode &) = delete;
};
@@ -326,7 +434,7 @@ R GoAST%s::Visit(V* v) const
{""" % k
for subtype in l:
print """ case e%(n)s:
- return v->Visit%(n)s(llvm::cast<const GoAST%(n)s>(this));""" % {'n':subtype}
+ return v->Visit%(n)s(llvm::cast<const GoAST%(n)s>(this));""" % {'n': subtype}
print """ default:
assert(false && "Invalid kind");
OpenPOWER on IntegriCloud