diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2019-10-23 17:53:01 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2019-10-23 17:53:01 +0000 |
commit | ead246455adf1a215ec2715dad6533073a6beb4e (patch) | |
tree | f3f97a47d77053bf96fe74cdbd6fae74380e8a92 /source/Plugins/ExpressionParser | |
parent | fdb00c4408990a0a63ef7f496d809ce59f263bc5 (diff) | |
download | src-vendor/lldb.tar.gz src-vendor/lldb.zip |
Vendor import of stripped lldb trunk r375505, the last commit before thevendor/lldb/lldb-trunk-r375505vendor/lldb
upstream Subversion repository was made read-only, and the LLVM project
migrated to GitHub:
https://llvm.org/svn/llvm-project/lldb/trunk@375505
Notes
Notes:
svn path=/vendor/lldb/dist/; revision=353952
svn path=/vendor/lldb/lldb-r375505/; revision=353953; tag=vendor/lldb/lldb-trunk-r375505
Diffstat (limited to 'source/Plugins/ExpressionParser')
27 files changed, 1269 insertions, 1242 deletions
diff --git a/source/Plugins/ExpressionParser/Clang/ASTDumper.cpp b/source/Plugins/ExpressionParser/Clang/ASTDumper.cpp index 369f88327dd9..f33a713cc0b2 100644 --- a/source/Plugins/ExpressionParser/Clang/ASTDumper.cpp +++ b/source/Plugins/ExpressionParser/Clang/ASTDumper.cpp @@ -75,8 +75,6 @@ ASTDumper::ASTDumper(const CompilerType &compiler_type) { 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; @@ -92,7 +90,7 @@ void ASTDumper::ToLog(Log *log, const char *prefix) { while (end) { *end = '\0'; - log->Printf("%s%s", prefix, str); + LLDB_LOGF(log, "%s%s", prefix, str); *end = '\n'; @@ -100,9 +98,7 @@ void ASTDumper::ToLog(Log *log, const char *prefix) { end = strchr(str, '\n'); } - log->Printf("%s%s", prefix, str); + LLDB_LOGF(log, "%s%s", prefix, str); free(alloc); } - -void ASTDumper::ToStream(lldb::StreamSP &stream) { stream->PutCString(m_dump); } diff --git a/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp b/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp index 526ef90782ef..68eaad33f51c 100644 --- a/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp +++ b/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp @@ -58,13 +58,13 @@ void ASTResultSynthesizer::TransformTopLevelDecl(Decl *D) { if (NamedDecl *named_decl = dyn_cast<NamedDecl>(D)) { if (log && log->GetVerbose()) { if (named_decl->getIdentifier()) - log->Printf("TransformTopLevelDecl(%s)", - named_decl->getIdentifier()->getNameStart()); + LLDB_LOGF(log, "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()); + LLDB_LOGF(log, "TransformTopLevelDecl(%s)", + method_decl->getSelector().getAsString().c_str()); else - log->Printf("TransformTopLevelDecl(<complex>)"); + LLDB_LOGF(log, "TransformTopLevelDecl(<complex>)"); } if (m_top_level) { @@ -130,7 +130,7 @@ bool ASTResultSynthesizer::SynthesizeFunctionResult(FunctionDecl *FunDecl) { os.flush(); - log->Printf("Untransformed function AST:\n%s", s.c_str()); + LLDB_LOGF(log, "Untransformed function AST:\n%s", s.c_str()); } Stmt *function_body = function_decl->getBody(); @@ -146,7 +146,7 @@ bool ASTResultSynthesizer::SynthesizeFunctionResult(FunctionDecl *FunDecl) { os.flush(); - log->Printf("Transformed function AST:\n%s", s.c_str()); + LLDB_LOGF(log, "Transformed function AST:\n%s", s.c_str()); } return ret; @@ -170,7 +170,7 @@ bool ASTResultSynthesizer::SynthesizeObjCMethodResult( os.flush(); - log->Printf("Untransformed method AST:\n%s", s.c_str()); + LLDB_LOGF(log, "Untransformed method AST:\n%s", s.c_str()); } Stmt *method_body = MethodDecl->getBody(); @@ -190,7 +190,7 @@ bool ASTResultSynthesizer::SynthesizeObjCMethodResult( os.flush(); - log->Printf("Transformed method AST:\n%s", s.c_str()); + LLDB_LOGF(log, "Transformed method AST:\n%s", s.c_str()); } return ret; @@ -308,8 +308,8 @@ bool ASTResultSynthesizer::SynthesizeBodyResult(CompoundStmt *Body, 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()); + LLDB_LOGF(log, "Last statement is an %s with type: %s", + (is_lvalue ? "lvalue" : "rvalue"), s.c_str()); } clang::VarDecl *result_decl = nullptr; @@ -422,8 +422,7 @@ void ASTResultSynthesizer::MaybeRecordPersistentType(TypeDecl *D) { ConstString name_cs(name.str().c_str()); - if (log) - log->Printf("Recording persistent type %s\n", name_cs.GetCString()); + LLDB_LOGF(log, "Recording persistent type %s\n", name_cs.GetCString()); m_decls.push_back(D); } @@ -443,8 +442,7 @@ void ASTResultSynthesizer::RecordPersistentDecl(NamedDecl *D) { ConstString name_cs(name.str().c_str()); - if (log) - log->Printf("Recording persistent decl %s\n", name_cs.GetCString()); + LLDB_LOGF(log, "Recording persistent decl %s\n", name_cs.GetCString()); m_decls.push_back(D); } @@ -467,7 +465,7 @@ void ASTResultSynthesizer::CommitPersistentDecls() { decl->dump(ss); ss.flush(); - log->Printf("Couldn't commit persistent decl: %s\n", s.c_str()); + LLDB_LOGF(log, "Couldn't commit persistent decl: %s\n", s.c_str()); } continue; diff --git a/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp b/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp index c5778f86bb62..372c2439ebf0 100644 --- a/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp +++ b/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp @@ -9,6 +9,7 @@ #include "ClangASTSource.h" #include "ASTDumper.h" +#include "ClangDeclVendor.h" #include "ClangModulesDeclVendor.h" #include "lldb/Core/Module.h" @@ -18,7 +19,6 @@ #include "lldb/Symbol/CompilerDeclContext.h" #include "lldb/Symbol/Function.h" #include "lldb/Symbol/SymbolFile.h" -#include "lldb/Symbol/SymbolVendor.h" #include "lldb/Symbol/TaggedASTType.h" #include "lldb/Target/Target.h" #include "lldb/Utility/Log.h" @@ -74,14 +74,19 @@ void ClangASTSource::InstallASTContext(clang::ASTContext &ast_context, file_manager}; std::vector<clang::ExternalASTMerger::ImporterSource> sources; for (lldb::ModuleSP module_sp : m_target->GetImages().Modules()) { - if (auto *module_ast_ctx = llvm::cast_or_null<ClangASTContext>( - module_sp->GetTypeSystemForLanguage(lldb::eLanguageTypeC))) { + auto type_system_or_err = + module_sp->GetTypeSystemForLanguage(lldb::eLanguageTypeC); + if (auto err = type_system_or_err.takeError()) { + LLDB_LOG_ERROR( + lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_EXPRESSIONS), + std::move(err), "Failed to get ClangASTContext"); + } else if (auto *module_ast_ctx = llvm::cast_or_null<ClangASTContext>( + &type_system_or_err.get())) { lldbassert(module_ast_ctx->getASTContext()); lldbassert(module_ast_ctx->getFileManager()); - sources.push_back({*module_ast_ctx->getASTContext(), - *module_ast_ctx->getFileManager(), - module_ast_ctx->GetOriginMap() - }); + sources.emplace_back(*module_ast_ctx->getASTContext(), + *module_ast_ctx->getFileManager(), + module_ast_ctx->GetOriginMap()); } } @@ -96,17 +101,14 @@ void ClangASTSource::InstallASTContext(clang::ASTContext &ast_context, if (!language_runtime) break; - DeclVendor *runtime_decl_vendor = language_runtime->GetDeclVendor(); - - if (!runtime_decl_vendor) - break; - - sources.push_back(runtime_decl_vendor->GetImporterSource()); + if (auto *runtime_decl_vendor = llvm::dyn_cast_or_null<ClangDeclVendor>( + language_runtime->GetDeclVendor())) { + sources.push_back(runtime_decl_vendor->GetImporterSource()); + } } while (false); do { - DeclVendor *modules_decl_vendor = - m_target->GetClangModulesDeclVendor(); + auto *modules_decl_vendor = m_target->GetClangModulesDeclVendor(); if (!modules_decl_vendor) break; @@ -127,11 +129,9 @@ void ClangASTSource::InstallASTContext(clang::ASTContext &ast_context, *scratch_ast_context->getFileManager(), scratch_ast_context->GetOriginMap()}); } - while (false) - ; m_merger_up = - llvm::make_unique<clang::ExternalASTMerger>(target, sources); + std::make_unique<clang::ExternalASTMerger>(target, sources); } else { m_ast_importer_sp->InstallMapCompleter(&ast_context, *this); } @@ -273,13 +273,13 @@ void ClangASTSource::CompleteType(TagDecl *tag_decl) { unsigned int current_id = invocation_id++; 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()); + LLDB_LOGF(log, + " 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); + LLDB_LOGF(log, " CTD[%u] Before:", current_id); ASTDumper dumper((Decl *)tag_decl); dumper.ToLog(log, " [CTD] "); } @@ -301,10 +301,10 @@ void ClangASTSource::CompleteType(TagDecl *tag_decl) { // We couldn't complete the type. Maybe there's a definition somewhere // else that can be completed. - if (log) - log->Printf(" CTD[%u] Type could not be completed in the module in " - "which it was first found.", - current_id); + LLDB_LOGF(log, + " CTD[%u] Type could not be completed in the module in " + "which it was first found.", + current_id); bool found = false; @@ -316,9 +316,9 @@ void ClangASTSource::CompleteType(TagDecl *tag_decl) { m_ast_importer_sp->GetNamespaceMap(namespace_context); 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())); + LLDB_LOGF(log, " CTD[%u] Inspecting namespace map %p (%d entries)", + current_id, static_cast<void *>(namespace_map.get()), + static_cast<int>(namespace_map->size())); if (!namespace_map) return; @@ -326,10 +326,9 @@ void ClangASTSource::CompleteType(TagDecl *tag_decl) { 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()); + LLDB_LOGF(log, " CTD[%u] Searching namespace %s in module %s", + current_id, i->second.GetName().AsCString(), + i->first->GetFileSpec().GetFilename().GetCString()); TypeList types; @@ -409,7 +408,7 @@ void ClangASTSource::CompleteType(TagDecl *tag_decl) { } if (log) { - log->Printf(" [CTD] After:"); + LLDB_LOGF(log, " [CTD] After:"); ASTDumper dumper((Decl *)tag_decl); dumper.ToLog(log, " [CTD] "); } @@ -419,11 +418,12 @@ 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:"); + LLDB_LOGF(log, + " [CompleteObjCInterfaceDecl] on (ASTContext*)%p Completing " + "an ObjCInterfaceDecl named %s", + static_cast<void *>(m_ast_context), + interface_decl->getName().str().c_str()); + LLDB_LOGF(log, " [COID] Before:"); ASTDumper dumper((Decl *)interface_decl); dumper.ToLog(log, " [COID] "); } @@ -467,7 +467,7 @@ void ClangASTSource::CompleteType(clang::ObjCInterfaceDecl *interface_decl) { CompleteType(interface_decl->getSuperClass()); if (log) { - log->Printf(" [COID] After:"); + LLDB_LOGF(log, " [COID] After:"); ASTDumper dumper((Decl *)interface_decl); dumper.ToLog(log, " [COID] "); } @@ -554,20 +554,22 @@ void ClangASTSource::FindExternalLexicalDecls( if (log) { if (const NamedDecl *context_named_decl = dyn_cast<NamedDecl>(context_decl)) - log->Printf( + LLDB_LOGF( + log, "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", + LLDB_LOGF( + log, "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( + LLDB_LOGF( + log, "FindExternalLexicalDecls[%u] on (ASTContext*)%p in a NULL context", current_id, static_cast<const void *>(m_ast_context)); } @@ -580,9 +582,9 @@ void ClangASTSource::FindExternalLexicalDecls( return; if (log) { - log->Printf(" FELD[%u] Original decl (ASTContext*)%p (Decl*)%p:", - current_id, static_cast<void *>(original_ctx), - static_cast<void *>(original_decl)); + LLDB_LOGF( + log, " 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, " "); } @@ -626,13 +628,13 @@ void ClangASTSource::FindExternalLexicalDecls( 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()); + LLDB_LOGF(log, " 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()); + LLDB_LOGF(log, " FELD[%d] Adding lexical %sDecl %s", current_id, + decl->getDeclKindName(), ast_dumper.GetCString()); } Decl *copied_decl = CopyDecl(decl); @@ -645,6 +647,20 @@ void ClangASTSource::FindExternalLexicalDecls( m_ast_importer_sp->RequireCompleteType(copied_field_type); } + auto decl_context_non_const = const_cast<DeclContext *>(decl_context); + + // The decl ended up in the wrong DeclContext. Let's fix that so + // the decl we copied will actually be found. + // FIXME: This is a horrible hack that shouldn't be necessary. However + // it seems our current setup sometimes fails to copy decls to the right + // place. See rdar://55129537. + if (copied_decl->getDeclContext() != decl_context) { + assert(copied_decl->getDeclContext()->containsDecl(copied_decl)); + copied_decl->getDeclContext()->removeDecl(copied_decl); + copied_decl->setDeclContext(decl_context_non_const); + assert(!decl_context_non_const->containsDecl(copied_decl)); + decl_context_non_const->addDeclInternal(copied_decl); + } } else { SkippedDecls = true; } @@ -678,22 +694,25 @@ void ClangASTSource::FindExternalVisibleDecls(NameSearchContext &context) { 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()); + LLDB_LOGF(log, + "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()); + LLDB_LOGF(log, + "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()); + LLDB_LOGF(log, + "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()); } if (HasMerger() && !isa<TranslationUnitDecl>(context.m_decl_context) @@ -723,9 +742,9 @@ void ClangASTSource::FindExternalVisibleDecls(NameSearchContext &context) { m_ast_importer_sp->GetNamespaceMap(namespace_context) : nullptr; 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())); + LLDB_LOGF(log, " 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; @@ -733,10 +752,9 @@ void ClangASTSource::FindExternalVisibleDecls(NameSearchContext &context) { 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()); + LLDB_LOGF(log, " 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); } @@ -748,8 +766,7 @@ void ClangASTSource::FindExternalVisibleDecls(NameSearchContext &context) { } else { CompilerDeclContext namespace_decl; - if (log) - log->Printf(" CAS::FEVD[%u] Searching the root namespace", current_id); + LLDB_LOGF(log, " CAS::FEVD[%u] Searching the root namespace", current_id); FindExternalVisibleDecls(context, lldb::ModuleSP(), namespace_decl, current_id); @@ -757,10 +774,10 @@ void ClangASTSource::FindExternalVisibleDecls(NameSearchContext &context) { 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())); + LLDB_LOGF(log, + " 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())); NamespaceDecl *clang_namespace_decl = AddNamespace(context, context.m_namespace_map); @@ -807,21 +824,17 @@ void ClangASTSource::FindExternalVisibleDecls( if (module_sp && namespace_decl) { CompilerDeclContext found_namespace_decl; - SymbolVendor *symbol_vendor = module_sp->GetSymbolVendor(); - - if (symbol_vendor) { - found_namespace_decl = - symbol_vendor->FindNamespace(name, &namespace_decl); + if (SymbolFile *symbol_file = module_sp->GetSymbolFile()) { + found_namespace_decl = symbol_file->FindNamespace(name, &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] Found namespace %s in module %s", - current_id, name.GetCString(), - module_sp->GetFileSpec().GetFilename().GetCString()); + LLDB_LOGF(log, " CAS::FEVD[%u] Found namespace %s in module %s", + current_id, name.GetCString(), + module_sp->GetFileSpec().GetFilename().GetCString()); } } } else if (!HasMerger()) { @@ -836,23 +849,21 @@ void ClangASTSource::FindExternalVisibleDecls( CompilerDeclContext found_namespace_decl; - SymbolVendor *symbol_vendor = image->GetSymbolVendor(); + SymbolFile *symbol_file = image->GetSymbolFile(); - if (!symbol_vendor) + if (!symbol_file) continue; - found_namespace_decl = - symbol_vendor->FindNamespace(name, &namespace_decl); + found_namespace_decl = symbol_file->FindNamespace(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()); + LLDB_LOGF(log, " CAS::FEVD[%u] Found namespace %s in module %s", + current_id, name.GetCString(), + image->GetFileSpec().GetFilename().GetCString()); } } } @@ -878,9 +889,9 @@ void ClangASTSource::FindExternalVisibleDecls( 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>")); + LLDB_LOGF(log, " CAS::FEVD[%u] Matching type found for \"%s\": %s", + current_id, name.GetCString(), + (name_string ? name_string : "<anonymous>")); } CompilerType full_type = type_sp->GetFullCompilerType(); @@ -888,8 +899,8 @@ void ClangASTSource::FindExternalVisibleDecls( 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); + LLDB_LOGF(log, " CAS::FEVD[%u] - Couldn't export a type", + current_id); continue; } @@ -915,9 +926,10 @@ void ClangASTSource::FindExternalVisibleDecls( break; if (log) { - log->Printf(" CAS::FEVD[%u] Matching entity found for \"%s\" in " - "the modules", - current_id, name.GetCString()); + LLDB_LOGF(log, + " CAS::FEVD[%u] Matching entity found for \"%s\" in " + "the modules", + current_id, name.GetCString()); } clang::NamedDecl *const decl_from_modules = decls[0]; @@ -930,10 +942,10 @@ void ClangASTSource::FindExternalVisibleDecls( 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); + LLDB_LOGF( + log, + " CAS::FEVD[%u] - Couldn't export a type from the modules", + current_id); break; } @@ -971,11 +983,13 @@ void ClangASTSource::FindExternalVisibleDecls( uint32_t max_matches = 1; std::vector<clang::NamedDecl *> decls; - if (!decl_vendor->FindDecls(name, append, max_matches, decls)) + auto *clang_decl_vendor = llvm::cast<ClangDeclVendor>(decl_vendor); + if (!clang_decl_vendor->FindDecls(name, append, max_matches, decls)) break; if (log) { - log->Printf( + LLDB_LOGF( + log, " CAS::FEVD[%u] Matching type found for \"%s\" in the runtime", current_id, name.GetCString()); } @@ -985,10 +999,9 @@ void ClangASTSource::FindExternalVisibleDecls( 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); + LLDB_LOGF(log, + " CAS::FEVD[%u] - Couldn't export a type from the runtime", + current_id); break; } @@ -1126,8 +1139,8 @@ bool ClangASTSource::FindObjCMethodDeclsWithOrigin( if (log) { ASTDumper dumper((Decl *)copied_method_decl); - log->Printf(" CAS::FOMD[%d] found (%s) %s", current_id, log_info, - dumper.GetCString()); + LLDB_LOGF(log, " CAS::FOMD[%d] found (%s) %s", current_id, log_info, + dumper.GetCString()); } context.AddNamedDecl(copied_method_decl); @@ -1205,17 +1218,16 @@ void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) { ConstString selector_name(ss.GetString()); - 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()); + LLDB_LOGF(log, + "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; std::string interface_name = interface_decl->getNameAsString(); @@ -1225,9 +1237,10 @@ void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) { ms.Flush(); ConstString instance_method_name(ms.GetString()); + sc_list.Clear(); m_target->GetImages().FindFunctions( instance_method_name, lldb::eFunctionNameTypeFull, include_symbols, - include_inlines, append, sc_list); + include_inlines, sc_list); if (sc_list.GetSize()) break; @@ -1237,9 +1250,10 @@ void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) { ms.Flush(); ConstString class_method_name(ms.GetString()); + sc_list.Clear(); m_target->GetImages().FindFunctions( class_method_name, lldb::eFunctionNameTypeFull, include_symbols, - include_inlines, append, sc_list); + include_inlines, sc_list); if (sc_list.GetSize()) break; @@ -1252,7 +1266,7 @@ void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) { m_target->GetImages().FindFunctions( selector_name, lldb::eFunctionNameTypeSelector, include_symbols, - include_inlines, append, candidate_sc_list); + include_inlines, candidate_sc_list); for (uint32_t ci = 0, ce = candidate_sc_list.GetSize(); ci != ce; ++ci) { SymbolContext candidate_sc; @@ -1331,8 +1345,8 @@ void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) { if (log) { ASTDumper dumper((Decl *)copied_method_decl); - log->Printf(" CAS::FOMD[%d] found (in symbols) %s", current_id, - dumper.GetCString()); + LLDB_LOGF(log, " CAS::FOMD[%d] found (in symbols) %s", current_id, + dumper.GetCString()); } context.AddNamedDecl(copied_method_decl); @@ -1360,11 +1374,11 @@ void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) { 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())); + LLDB_LOGF(log, + "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, "in debug info"); @@ -1423,7 +1437,9 @@ void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) { uint32_t max_matches = 1; std::vector<clang::NamedDecl *> decls; - if (!decl_vendor->FindDecls(interface_name, append, max_matches, decls)) + auto *clang_decl_vendor = llvm::cast<ClangDeclVendor>(decl_vendor); + if (!clang_decl_vendor->FindDecls(interface_name, append, max_matches, + decls)) break; ObjCInterfaceDecl *runtime_interface_decl = @@ -1462,8 +1478,8 @@ static bool FindObjCPropertyAndIvarDeclsWithOrigin( 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()); + LLDB_LOGF(log, " CAS::FOPD[%d] found %s", current_id, + dumper.GetCString()); } context.AddNamedDecl(parser_property_decl.decl); @@ -1480,8 +1496,8 @@ static bool FindObjCPropertyAndIvarDeclsWithOrigin( 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()); + LLDB_LOGF(log, " CAS::FOPD[%d] found %s", current_id, + dumper.GetCString()); } context.AddNamedDecl(parser_ivar_decl.decl); @@ -1505,23 +1521,23 @@ void ClangASTSource::FindObjCPropertyAndIvarDecls(NameSearchContext &context) { ConstString class_name(parser_iface_decl->getNameAsString().c_str()); - 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()); + LLDB_LOGF(log, + "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, *this, origin_iface_decl)) return; - if (log) - log->Printf("CAS::FOPD[%d] couldn't find the property on origin " - "(ObjCInterfaceDecl*)%p/(ASTContext*)%p, searching " - "elsewhere...", - current_id, static_cast<const void *>(origin_iface_decl.decl), - static_cast<void *>(&origin_iface_decl->getASTContext())); + LLDB_LOGF(log, + "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())); SymbolContext null_sc; TypeList type_list; @@ -1542,12 +1558,11 @@ void ClangASTSource::FindObjCPropertyAndIvarDecls(NameSearchContext &context) { if (complete_iface_decl.decl == origin_iface_decl.decl) break; // already checked this one - if (log) - log->Printf("CAS::FOPD[%d] trying origin " - "(ObjCInterfaceDecl*)%p/(ASTContext*)%p...", - current_id, - static_cast<const void *>(complete_iface_decl.decl), - static_cast<void *>(&complete_iface_decl->getASTContext())); + LLDB_LOGF(log, + "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())); FindObjCPropertyAndIvarDeclsWithOrigin(current_id, context, *this, complete_iface_decl); @@ -1578,13 +1593,12 @@ void ClangASTSource::FindObjCPropertyAndIvarDecls(NameSearchContext &context) { 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())); + LLDB_LOGF( + log, + "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, *this, interface_decl_from_modules)) @@ -1614,7 +1628,8 @@ void ClangASTSource::FindObjCPropertyAndIvarDecls(NameSearchContext &context) { uint32_t max_matches = 1; std::vector<clang::NamedDecl *> decls; - if (!decl_vendor->FindDecls(class_name, append, max_matches, decls)) + auto *clang_decl_vendor = llvm::cast<ClangDeclVendor>(decl_vendor); + if (!clang_decl_vendor->FindDecls(class_name, append, max_matches, decls)) break; DeclFromUser<const ObjCInterfaceDecl> interface_decl_from_runtime( @@ -1623,13 +1638,12 @@ void ClangASTSource::FindObjCPropertyAndIvarDecls(NameSearchContext &context) { 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())); + LLDB_LOGF( + log, + "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, *this, interface_decl_from_runtime)) @@ -1729,12 +1743,12 @@ bool ClangASTSource::layoutRecordType(const RecordDecl *record, uint64_t &size, Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); - 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()); + LLDB_LOGF(log, + "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()); DeclFromParser<const RecordDecl> parser_record(record); DeclFromUser<const RecordDecl> origin_record( @@ -1798,24 +1812,25 @@ bool ClangASTSource::layoutRecordType(const RecordDecl *record, uint64_t &size, 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); + LLDB_LOGF(log, "LRT[%u] returned:", current_id); + LLDB_LOGF(log, "LRT[%u] Original = (RecordDecl*)%p", current_id, + static_cast<const void *>(origin_record.decl)); + LLDB_LOGF(log, "LRT[%u] Size = %" PRId64, current_id, size); + LLDB_LOGF(log, "LRT[%u] Alignment = %" PRId64, current_id, alignment); + LLDB_LOGF(log, "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]); + LLDB_LOGF(log, + "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); + LLDB_LOGF(log, "LRT[%u] Bases:", current_id); for (CXXRecordDecl::base_class_const_iterator bi = parser_cxx_record->bases_begin(), be = parser_cxx_record->bases_end(); @@ -1828,7 +1843,8 @@ bool ClangASTSource::layoutRecordType(const RecordDecl *record, uint64_t &size, DeclFromParser<CXXRecordDecl> base_cxx_record = DynCast<CXXRecordDecl>(base_record); - log->Printf( + LLDB_LOGF( + log, "LRT[%u] %s(CXXRecordDecl*)%p, Name = '%s', Offset = %" PRId64 " chars", current_id, (is_virtual ? "Virtual " : ""), @@ -1839,7 +1855,7 @@ bool ClangASTSource::layoutRecordType(const RecordDecl *record, uint64_t &size, : base_offsets[base_cxx_record.decl].getQuantity())); } } else { - log->Printf("LRD[%u] Not a CXXRecord, so no bases", current_id); + LLDB_LOGF(log, "LRD[%u] Not a CXXRecord, so no bases", current_id); } } @@ -1856,16 +1872,18 @@ void ClangASTSource::CompleteNamespaceMap( 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()); + LLDB_LOGF(log, + "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()); + LLDB_LOGF(log, + "CompleteNamespaceMap[%u] on (ASTContext*)%p Searching for " + "namespace %s", + current_id, static_cast<void *>(m_ast_context), + name.GetCString()); } if (parent_map) { @@ -1877,13 +1895,13 @@ void ClangASTSource::CompleteNamespaceMap( lldb::ModuleSP module_sp = i->first; CompilerDeclContext module_parent_namespace_decl = i->second; - SymbolVendor *symbol_vendor = module_sp->GetSymbolVendor(); + SymbolFile *symbol_file = module_sp->GetSymbolFile(); - if (!symbol_vendor) + if (!symbol_file) continue; found_namespace_decl = - symbol_vendor->FindNamespace(name, &module_parent_namespace_decl); + symbol_file->FindNamespace(name, &module_parent_namespace_decl); if (!found_namespace_decl) continue; @@ -1891,10 +1909,9 @@ void ClangASTSource::CompleteNamespaceMap( 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()); + LLDB_LOGF(log, " 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(); @@ -1910,13 +1927,13 @@ void ClangASTSource::CompleteNamespaceMap( CompilerDeclContext found_namespace_decl; - SymbolVendor *symbol_vendor = image->GetSymbolVendor(); + SymbolFile *symbol_file = image->GetSymbolFile(); - if (!symbol_vendor) + if (!symbol_file) continue; found_namespace_decl = - symbol_vendor->FindNamespace(name, &null_namespace_decl); + symbol_file->FindNamespace(name, &null_namespace_decl); if (!found_namespace_decl) continue; @@ -1924,10 +1941,9 @@ void ClangASTSource::CompleteNamespaceMap( 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()); + LLDB_LOGF(log, " CMN[%u] Found namespace %s in module %s", current_id, + name.GetCString(), + image->GetFileSpec().GetFilename().GetCString()); } } } @@ -2065,7 +2081,8 @@ CompilerType ClangASTSource::GuardedCopyType(const CompilerType &src_type) { // seems to be generating bad types on occasion. return CompilerType(); - return CompilerType(m_ast_context, copied_qual_type); + return CompilerType(ClangASTContext::GetASTContext(m_ast_context), + copied_qual_type.getAsOpaquePtr()); } clang::NamedDecl *NameSearchContext::AddVarDecl(const CompilerType &type) { @@ -2162,8 +2179,7 @@ clang::NamedDecl *NameSearchContext::AddFunDecl(const CompilerType &type, } else { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); - if (log) - log->Printf("Function type wasn't a FunctionProtoType"); + LLDB_LOGF(log, "Function type wasn't a FunctionProtoType"); } // If this is an operator (e.g. operator new or operator==), only insert the @@ -2194,7 +2210,9 @@ clang::NamedDecl *NameSearchContext::AddGenericFunDecl() { proto_info)); return AddFunDecl( - CompilerType(m_ast_source.m_ast_context, generic_function_type), true); + CompilerType(ClangASTContext::GetASTContext(m_ast_source.m_ast_context), + generic_function_type.getAsOpaquePtr()), + true); } clang::NamedDecl * diff --git a/source/Plugins/ExpressionParser/Clang/ClangDeclVendor.cpp b/source/Plugins/ExpressionParser/Clang/ClangDeclVendor.cpp new file mode 100644 index 000000000000..c59722b7b4f8 --- /dev/null +++ b/source/Plugins/ExpressionParser/Clang/ClangDeclVendor.cpp @@ -0,0 +1,30 @@ +//===-- ClangDeclVendor.cpp -------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "Plugins/ExpressionParser/Clang/ClangDeclVendor.h" + +#include "lldb/Symbol/ClangASTContext.h" +#include "lldb/Utility/ConstString.h" + +using namespace lldb_private; + +uint32_t ClangDeclVendor::FindDecls(ConstString name, bool append, + uint32_t max_matches, + std::vector<CompilerDecl> &decls) { + if (!append) + decls.clear(); + + std::vector<clang::NamedDecl *> named_decls; + uint32_t ret = FindDecls(name, /*append*/ false, max_matches, named_decls); + for (auto *named_decl : named_decls) { + decls.push_back(CompilerDecl( + ClangASTContext::GetASTContext(&named_decl->getASTContext()), + named_decl)); + } + return ret; +} diff --git a/source/Plugins/ExpressionParser/Clang/ClangDeclVendor.h b/source/Plugins/ExpressionParser/Clang/ClangDeclVendor.h new file mode 100644 index 000000000000..90b715f37cba --- /dev/null +++ b/source/Plugins/ExpressionParser/Clang/ClangDeclVendor.h @@ -0,0 +1,50 @@ +//===-- ClangDeclVendor.h ---------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_ClangDeclVendor_h_ +#define liblldb_ClangDeclVendor_h_ + +#include "lldb/Core/ClangForward.h" +#include "lldb/Symbol/DeclVendor.h" + +#include "clang/AST/ExternalASTMerger.h" + +namespace lldb_private { + +// A clang specialized extension to DeclVendor. +class ClangDeclVendor : public DeclVendor { +public: + ClangDeclVendor(DeclVendorKind kind) : DeclVendor(kind) {} + + virtual ~ClangDeclVendor() {} + + /// Interface for ExternalASTMerger. Returns an ImporterSource allowing type + /// completion. + /// + /// \return + /// An ImporterSource for this ClangDeclVendor. + virtual clang::ExternalASTMerger::ImporterSource GetImporterSource() = 0; + + uint32_t FindDecls(ConstString name, bool append, uint32_t max_matches, + std::vector<CompilerDecl> &decls) override; + + virtual uint32_t FindDecls(ConstString name, bool append, + uint32_t max_matches, + std::vector<clang::NamedDecl *> &decls) = 0; + + static bool classof(const DeclVendor *vendor) { + return vendor->GetKind() >= eClangDeclVendor && + vendor->GetKind() < eLastClangDeclVendor; + } + +private: + DISALLOW_COPY_AND_ASSIGN(ClangDeclVendor); +}; +} // namespace lldb_private + +#endif diff --git a/source/Plugins/ExpressionParser/Clang/ClangDiagnostic.h b/source/Plugins/ExpressionParser/Clang/ClangDiagnostic.h index db50c2aa3e90..48cd1c4b99fa 100644 --- a/source/Plugins/ExpressionParser/Clang/ClangDiagnostic.h +++ b/source/Plugins/ExpressionParser/Clang/ClangDiagnostic.h @@ -29,7 +29,7 @@ public: return diag->getKind() == eDiagnosticOriginClang; } - ClangDiagnostic(const char *message, DiagnosticSeverity severity, + ClangDiagnostic(llvm::StringRef message, DiagnosticSeverity severity, uint32_t compiler_id) : Diagnostic(message, severity, eDiagnosticOriginClang, compiler_id) {} @@ -42,6 +42,7 @@ public: } const FixItList &FixIts() const { return m_fixit_vec; } +private: FixItList m_fixit_vec; }; diff --git a/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp b/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp index a49a7029e0d2..f4457fc1b740 100644 --- a/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp +++ b/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp @@ -180,98 +180,20 @@ ClangExpressionDeclMap::TargetInfo ClangExpressionDeclMap::GetTargetInfo() { return ret; } -namespace { -/// This class walks an AST and ensures that all DeclContexts defined inside the -/// current source file are properly complete. -/// -/// This is used to ensure that persistent types defined in the current source -/// file migrate completely to the persistent AST context before they are -/// reused. If that didn't happen, it would be impoossible to complete them -/// because their origin would be gone. -/// -/// The stragtegy used by this class is to check the SourceLocation (to be -/// specific, the FileID) and see if it's the FileID for the current expression. -/// Alternate strategies could include checking whether an ExternalASTMerger, -/// set up to not have the current context as a source, can find an original for -/// the type. -class Completer : public clang::RecursiveASTVisitor<Completer> { -private: - clang::ASTImporter &m_exporter; /// Used to import Decl contents - clang::FileID m_file; /// The file that's going away - llvm::DenseSet<clang::Decl *> m_completed; /// Visited Decls, to avoid cycles - - bool ImportAndCheckCompletable(clang::Decl *decl) { - (void)m_exporter.Import(decl); - if (m_completed.count(decl)) - return false; - if (!llvm::isa<DeclContext>(decl)) - return false; - const clang::SourceLocation loc = decl->getLocation(); - if (!loc.isValid()) - return false; - const clang::FileID file = - m_exporter.getFromContext().getSourceManager().getFileID(loc); - if (file != m_file) - return false; - // We are assuming the Decl was parsed in this very expression, so it - // should not have external storage. - lldbassert(!llvm::cast<DeclContext>(decl)->hasExternalLexicalStorage()); - return true; - } - - void Complete(clang::Decl *decl) { - m_completed.insert(decl); - auto *decl_context = llvm::cast<DeclContext>(decl); - (void)m_exporter.Import(decl); - m_exporter.CompleteDecl(decl); - for (Decl *child : decl_context->decls()) - if (ImportAndCheckCompletable(child)) - Complete(child); - } - - void MaybeComplete(clang::Decl *decl) { - if (ImportAndCheckCompletable(decl)) - Complete(decl); - } - -public: - Completer(clang::ASTImporter &exporter, clang::FileID file) - : m_exporter(exporter), m_file(file) {} - - // Implements the RecursiveASTVisitor's core API. It is called on each Decl - // that the RecursiveASTVisitor encounters, and returns true if the traversal - // should continue. - bool VisitDecl(clang::Decl *decl) { - MaybeComplete(decl); - return true; - } -}; -} - -static void CompleteAllDeclContexts(clang::ASTImporter &exporter, - clang::FileID file, - clang::QualType root) { - clang::QualType canonical_type = root.getCanonicalType(); - if (clang::TagDecl *tag_decl = canonical_type->getAsTagDecl()) { - Completer(exporter, file).TraverseDecl(tag_decl); - } else if (auto interface_type = llvm::dyn_cast<ObjCInterfaceType>( - canonical_type.getTypePtr())) { - Completer(exporter, file).TraverseDecl(interface_type->getDecl()); - } else { - Completer(exporter, file).TraverseType(canonical_type); - } -} - static clang::QualType ExportAllDeclaredTypes( - clang::ExternalASTMerger &merger, + clang::ExternalASTMerger &parent_merger, clang::ExternalASTMerger &merger, clang::ASTContext &source, clang::FileManager &source_file_manager, const clang::ExternalASTMerger::OriginMap &source_origin_map, clang::FileID file, clang::QualType root) { - clang::ExternalASTMerger::ImporterSource importer_source = - { source, source_file_manager, source_origin_map }; + // Mark the source as temporary to make sure all declarations from the + // AST are exported. Also add the parent_merger as the merger into the + // source AST so that the merger can track back any declarations from + // the persistent ASTs we used as sources. + clang::ExternalASTMerger::ImporterSource importer_source( + source, source_file_manager, source_origin_map, /*Temporary*/ true, + &parent_merger); merger.AddSources(importer_source); clang::ASTImporter &exporter = merger.ImporterForOrigin(source); - CompleteAllDeclContexts(exporter, file, root); llvm::Expected<clang::QualType> ret_or_error = exporter.Import(root); merger.RemoveSources(importer_source); if (ret_or_error) { @@ -286,10 +208,10 @@ static clang::QualType ExportAllDeclaredTypes( TypeFromUser ClangExpressionDeclMap::DeportType(ClangASTContext &target, ClangASTContext &source, TypeFromParser parser_type) { - assert (&target == m_target->GetScratchClangASTContext()); - assert ((TypeSystem*)&source == parser_type.GetTypeSystem()); - assert (source.getASTContext() == m_ast_context); - + assert(&target == m_target->GetScratchClangASTContext()); + assert((TypeSystem *)&source == parser_type.GetTypeSystem()); + assert(source.getASTContext() == m_ast_context); + if (m_ast_importer_sp) { return TypeFromUser(m_ast_importer_sp->DeportType( target.getASTContext(), source.getASTContext(), @@ -299,13 +221,12 @@ TypeFromUser ClangExpressionDeclMap::DeportType(ClangASTContext &target, clang::FileID source_file = source.getASTContext()->getSourceManager().getFileID( source.getASTContext()->getTranslationUnitDecl()->getLocation()); - auto scratch_ast_context = static_cast<ClangASTContextForExpressions*>( + auto scratch_ast_context = static_cast<ClangASTContextForExpressions *>( m_target->GetScratchClangASTContext()); clang::QualType exported_type = ExportAllDeclaredTypes( - scratch_ast_context->GetMergerUnchecked(), + *m_merger_up.get(), scratch_ast_context->GetMergerUnchecked(), *source.getASTContext(), *source.getFileManager(), - m_merger_up->GetOrigins(), - source_file, + m_merger_up->GetOrigins(), source_file, clang::QualType::getFromOpaquePtr(parser_type.GetOpaqueQualType())); return TypeFromUser(exported_type.getAsOpaquePtr(), &target); } else { @@ -375,8 +296,7 @@ bool ClangExpressionDeclMap::AddPersistentVariable(const NamedDecl *decl, TypeFromUser user_type = DeportType(*context, *ast, parser_type); if (!user_type.GetOpaqueQualType()) { - if (log) - log->Printf("Persistent variable's type wasn't copied successfully"); + LLDB_LOGF(log, "Persistent variable's type wasn't copied successfully"); return false; } @@ -415,8 +335,7 @@ bool ClangExpressionDeclMap::AddPersistentVariable(const NamedDecl *decl, var->m_flags |= ClangExpressionVariable::EVKeepInTarget; } - if (log) - log->Printf("Created persistent variable with flags 0x%hx", var->m_flags); + LLDB_LOGF(log, "Created persistent variable with flags 0x%hx", var->m_flags); var->EnableParserVars(GetParserID()); @@ -458,10 +377,9 @@ bool ClangExpressionDeclMap::AddValueToStruct(const NamedDecl *decl, if (!var) return false; - if (log) - log->Printf("Adding value for (NamedDecl*)%p [%s - %s] to the structure", - static_cast<const void *>(decl), name.GetCString(), - var->GetName().GetCString()); + LLDB_LOGF(log, "Adding value for (NamedDecl*)%p [%s - %s] to the structure", + static_cast<const void *>(decl), name.GetCString(), + var->GetName().GetCString()); // We know entity->m_parser_vars is valid because we used a parser variable // to find it @@ -475,9 +393,8 @@ bool ClangExpressionDeclMap::AddValueToStruct(const NamedDecl *decl, llvm::cast<ClangExpressionVariable>(var)->GetJITVars(GetParserID())) { // We already laid this out; do not touch - if (log) - log->Printf("Already placed at 0x%llx", - (unsigned long long)jit_vars->m_offset); + LLDB_LOGF(log, "Already placed at 0x%llx", + (unsigned long long)jit_vars->m_offset); } llvm::cast<ClangExpressionVariable>(var)->EnableJITVars(GetParserID()); @@ -512,8 +429,7 @@ bool ClangExpressionDeclMap::AddValueToStruct(const NamedDecl *decl, if (!err.Success()) return false; - if (log) - log->Printf("Placed at 0x%llx", (unsigned long long)offset); + LLDB_LOGF(log, "Placed at 0x%llx", (unsigned long long)offset); jit_vars->m_offset = offset; // TODO DoStructLayout() should not change this. @@ -779,7 +695,7 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls( if (GetImportInProgress()) { if (log && log->GetVerbose()) - log->Printf("Ignoring a query during an import"); + LLDB_LOGF(log, "Ignoring a query during an import"); return; } @@ -788,20 +704,23 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls( if (log) { if (!context.m_decl_context) - log->Printf("ClangExpressionDeclMap::FindExternalVisibleDecls[%u] for " - "'%s' in a NULL DeclContext", - current_id, name.GetCString()); + LLDB_LOGF(log, + "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()); + LLDB_LOGF(log, + "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()); + LLDB_LOGF(log, + "ClangExpressionDeclMap::FindExternalVisibleDecls[%u] for " + "'%s' in a '%s'", + current_id, name.GetCString(), + context.m_decl_context->getDeclKindName()); } if (const NamespaceDecl *namespace_context = @@ -828,7 +747,7 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls( log->Printf(" CEDM::FEVD[%u] Inspecting (NamespaceMap*)%p (%d entries)", current_id, static_cast<void *>(namespace_map.get()), (int)namespace_map->size()); - + for (ClangASTImporter::NamespaceMap::iterator i = namespace_map->begin(), e = namespace_map->end(); i != e; ++i) { @@ -848,7 +767,7 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls( FindExternalVisibleDecls(context, lldb::ModuleSP(), namespace_decl, current_id); } - + ClangASTSource::FindExternalVisibleDecls(context); } @@ -922,9 +841,8 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls( MaybeRegisterFunctionBody(parser_function_decl); } - if (log) - log->Printf(" CEDM::FEVD[%u] Found persistent decl %s", current_id, - name.GetCString()); + LLDB_LOGF(log, " CEDM::FEVD[%u] Found persistent decl %s", current_id, + name.GetCString()); context.AddNamedDecl(parser_named_decl); } while (false); @@ -979,8 +897,8 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls( if (log) { ASTDumper ast_dumper(class_qual_type); - log->Printf(" CEDM::FEVD[%u] Adding type for $__lldb_class: %s", - current_id, ast_dumper.GetCString()); + LLDB_LOGF(log, " CEDM::FEVD[%u] Adding type for $__lldb_class: %s", + current_id, ast_dumper.GetCString()); } AddThisType(context, class_user_type, current_id); @@ -1024,8 +942,8 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls( 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()); + LLDB_LOGF(log, " FEVD[%u] Adding type for $__lldb_class: %s", + current_id, ast_dumper.GetCString()); } AddThisType(context, pointee_type, current_id); @@ -1048,7 +966,7 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls( return; AddOneType(context, TypeFromUser(m_ctx_obj->GetCompilerType()), - current_id); + current_id); m_struct_vars->m_object_pointer_type = TypeFromUser(ctx_obj_ptr->GetCompilerType()); @@ -1096,8 +1014,8 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls( if (log) { ASTDumper ast_dumper(interface_type); - log->Printf(" FEVD[%u] Adding type for $__lldb_objc_class: %s", - current_id, ast_dumper.GetCString()); + LLDB_LOGF(log, " FEVD[%u] Adding type for $__lldb_objc_class: %s", + current_id, ast_dumper.GetCString()); } AddOneType(context, class_user_type, current_id); @@ -1157,8 +1075,9 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls( if (log) { ASTDumper ast_dumper(self_type->GetFullCompilerType()); - log->Printf(" FEVD[%u] Adding type for $__lldb_objc_class: %s", - current_id, ast_dumper.GetCString()); + LLDB_LOGF(log, + " FEVD[%u] Adding type for $__lldb_objc_class: %s", + current_id, ast_dumper.GetCString()); } TypeFromUser class_user_type(self_clang_type); @@ -1222,9 +1141,8 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls( reg_name)); if (reg_info) { - if (log) - log->Printf(" CEDM::FEVD[%u] Found register %s", current_id, - reg_info->name); + LLDB_LOGF(log, " CEDM::FEVD[%u] Found register %s", current_id, + reg_info->name); AddOneRegister(context, reg_info, current_id); } @@ -1298,14 +1216,12 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls( } const bool include_inlines = false; - const bool append = false; - + sc_list.Clear(); if (namespace_decl && module_sp) { const bool include_symbols = false; module_sp->FindFunctions(name, &namespace_decl, eFunctionNameTypeBase, - include_symbols, include_inlines, append, - sc_list); + include_symbols, include_inlines, sc_list); } else if (target && !namespace_decl) { const bool include_symbols = true; @@ -1314,7 +1230,7 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls( target->GetImages().FindFunctions(name, eFunctionNameTypeFull, include_symbols, include_inlines, - append, sc_list); + sc_list); } // If we found more than one function, see if we can use the frame's decl @@ -1511,9 +1427,10 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls( 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()); + LLDB_LOGF(log, + " CAS::FEVD[%u] Matching function found for " + "\"%s\" in the modules", + current_id, name.GetCString()); } clang::Decl *copied_decl = CopyDecl(decl_from_modules); @@ -1522,10 +1439,10 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls( : nullptr; if (!copied_function_decl) { - if (log) - log->Printf(" CAS::FEVD[%u] - Couldn't export a function " - "declaration from the modules", - current_id); + LLDB_LOGF(log, + " CAS::FEVD[%u] - Couldn't export a function " + "declaration from the modules", + current_id); break; } @@ -1538,9 +1455,10 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls( 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()); + LLDB_LOGF(log, + " CAS::FEVD[%u] Matching variable found for " + "\"%s\" in the modules", + current_id, name.GetCString()); } clang::Decl *copied_decl = CopyDecl(decl_from_modules); @@ -1549,10 +1467,10 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls( : nullptr; if (!copied_var_decl) { - if (log) - log->Printf(" CAS::FEVD[%u] - Couldn't export a variable " - "declaration from the modules", - current_id); + LLDB_LOGF(log, + " CAS::FEVD[%u] - Couldn't export a variable " + "declaration from the modules", + current_id); break; } @@ -1647,8 +1565,7 @@ bool ClangExpressionDeclMap::GetVariableValue(VariableSP &var, const_value_extractor.GetByteSize()); var_location.SetValueType(Value::eValueTypeHostAddress); } else { - if (log) - log->Printf("Error evaluating constant variable: %s", err.AsCString()); + LLDB_LOGF(log, "Error evaluating constant variable: %s", err.AsCString()); return false; } } @@ -1656,9 +1573,8 @@ bool ClangExpressionDeclMap::GetVariableValue(VariableSP &var, 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"); + LLDB_LOGF(log, + "Couldn't copy a variable's type into the parser's AST context"); return false; } @@ -1751,9 +1667,10 @@ void ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context, 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()); + LLDB_LOGF(log, + " CEDM::FEVD[%u] Found variable %s, returned %s (original %s)", + current_id, decl_name.c_str(), ast_dumper.GetCString(), + orig_dumper.GetCString()); } } @@ -1768,9 +1685,8 @@ void ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context, 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()); + LLDB_LOGF(log, " CEDM::FEVD[%u] Couldn't import type for pvar %s", + current_id, pvar_sp->GetName().GetCString()); return; } @@ -1789,8 +1705,8 @@ void ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context, 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()); + LLDB_LOGF(log, " CEDM::FEVD[%u] Added pvar %s, returned %s", current_id, + pvar_sp->GetName().GetCString(), ast_dumper.GetCString()); } } @@ -1848,8 +1764,8 @@ void ClangExpressionDeclMap::AddOneGenericVariable(NameSearchContext &context, 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()); + LLDB_LOGF(log, " CEDM::FEVD[%u] Found variable %s, returned %s", + current_id, decl_name.c_str(), ast_dumper.GetCString()); } } @@ -1858,7 +1774,7 @@ bool ClangExpressionDeclMap::ResolveUnknownTypes() { Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr(); ClangASTContextForExpressions *scratch_ast_context = - static_cast<ClangASTContextForExpressions*>( + static_cast<ClangASTContextForExpressions *>( target->GetScratchClangASTContext()); for (size_t index = 0, num_entities = m_found_entities.GetSize(); @@ -1874,15 +1790,14 @@ bool ClangExpressionDeclMap::ResolveUnknownTypes() { 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"); + LLDB_LOGF(log, "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()); + LLDB_LOGF(log, "Variable of unknown type now has Decl %s", + ast_dumper.GetCString()); } QualType var_type = var_decl->getType(); @@ -1897,18 +1812,17 @@ bool ClangExpressionDeclMap::ResolveUnknownTypes() { var_type.getAsOpaquePtr()); } else if (HasMerger()) { copied_type = CopyTypeWithMerger( - var_decl->getASTContext(), - scratch_ast_context->GetMergerUnchecked(), - var_type).getAsOpaquePtr(); + var_decl->getASTContext(), + scratch_ast_context->GetMergerUnchecked(), var_type) + .getAsOpaquePtr(); } else { lldbassert(0 && "No mechanism to copy a resolved unknown type!"); return false; } if (!copied_type) { - if (log) - log->Printf("ClangExpressionDeclMap::ResolveUnknownType - Couldn't " - "import the type for a variable"); + LLDB_LOGF(log, "ClangExpressionDeclMap::ResolveUnknownType - Couldn't " + "import the type for a variable"); return (bool)lldb::ExpressionVariableSP(); } @@ -1939,9 +1853,8 @@ void ClangExpressionDeclMap::AddOneRegister(NameSearchContext &context, 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()); + LLDB_LOGF(log, " Tried to add a type for %s, but couldn't get one", + context.m_decl_name.getAsString().c_str()); return; } @@ -1969,9 +1882,9 @@ void ClangExpressionDeclMap::AddOneRegister(NameSearchContext &context, 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()); + LLDB_LOGF(log, " CEDM::FEVD[%d] Added register %s, returned %s", + current_id, context.m_decl_name.getAsString().c_str(), + ast_dumper.GetCString()); } } @@ -2016,24 +1929,24 @@ void ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context, if (copied_function_template) { if (log) { ASTDumper ast_dumper((clang::Decl *)copied_function_template); - + StreamString ss; - + function->DumpSymbolContext(&ss); - + log->Printf(" CEDM::FEVD[%u] Imported decl for function template" " %s (description %s), returned %s", current_id, copied_function_template->getNameAsString().c_str(), ss.GetData(), ast_dumper.GetCString()); } - + context.AddNamedDecl(copied_function_template); } } else if (src_function_decl) { if (clang::FunctionDecl *copied_function_decl = llvm::dyn_cast_or_null<clang::FunctionDecl>( - CopyDecl(src_function_decl))) { + CopyDecl(src_function_decl))) { if (log) { ASTDumper ast_dumper((clang::Decl *)copied_function_decl); @@ -2041,19 +1954,20 @@ void ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context, 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()); + LLDB_LOGF(log, + " 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()); + LLDB_LOGF(log, " Failed to import the function decl for '%s'", + src_function_decl->getName().str().c_str()); } } } @@ -2082,7 +1996,8 @@ void ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context, if (!function_decl) { if (log) { - log->Printf( + LLDB_LOGF( + log, " Failed to create a function decl for '%s' {0x%8.8" PRIx64 "}", function_type->GetName().GetCString(), function_type->GetID()); } @@ -2092,10 +2007,11 @@ void ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context, } 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()); + LLDB_LOGF(log, + " 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; @@ -2154,7 +2070,8 @@ void ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context, m_parser_vars->m_exe_ctx.GetBestExecutionContextScope(), Address::DumpStyleResolvedDescription); - log->Printf( + LLDB_LOGF( + log, " CEDM::FEVD[%u] Found %s function %s (description %s), returned %s", current_id, (function ? "specific" : "generic"), decl_name.c_str(), ss.GetData(), function_str.c_str()); @@ -2170,7 +2087,8 @@ void ClangExpressionDeclMap::AddThisType(NameSearchContext &context, if (!copied_clang_type) { if (log) - log->Printf( + LLDB_LOGF( + log, "ClangExpressionDeclMap::AddThisType - Couldn't import the type"); return; @@ -2203,9 +2121,10 @@ void ClangExpressionDeclMap::AddThisType(NameSearchContext &context, 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()); + LLDB_LOGF(log, + " CEDM::AddThisType Added function $__lldb_expr " + "(description %s) for this type %s", + method_ast_dumper.GetCString(), type_ast_dumper.GetCString()); } } @@ -2244,8 +2163,8 @@ void ClangExpressionDeclMap::AddOneType(NameSearchContext &context, Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); if (log) - log->Printf( - "ClangExpressionDeclMap::AddOneType - Couldn't import the type"); + LLDB_LOGF( + log, "ClangExpressionDeclMap::AddOneType - Couldn't import the type"); return; } diff --git a/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h b/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h index 03b73e6be391..2711e90726e7 100644 --- a/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h +++ b/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h @@ -356,7 +356,7 @@ private: /// Activate parser-specific variables void EnableParserVars() { if (!m_parser_vars.get()) - m_parser_vars = llvm::make_unique<ParserVars>(); + m_parser_vars = std::make_unique<ParserVars>(); } /// Deallocate parser-specific variables diff --git a/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp b/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp index 7d13891ded8d..1422911d6546 100644 --- a/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp +++ b/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp @@ -105,16 +105,26 @@ using namespace lldb_private; class ClangExpressionParser::LLDBPreprocessorCallbacks : public PPCallbacks { ClangModulesDeclVendor &m_decl_vendor; ClangPersistentVariables &m_persistent_vars; + clang::SourceManager &m_source_mgr; 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) {} + ClangPersistentVariables &persistent_vars, + clang::SourceManager &source_mgr) + : m_decl_vendor(decl_vendor), m_persistent_vars(persistent_vars), + m_source_mgr(source_mgr) {} void moduleImport(SourceLocation import_location, clang::ModuleIdPath path, const clang::Module * /*null*/) override { + // Ignore modules that are imported in the wrapper code as these are not + // loaded by the user. + llvm::StringRef filename = + m_source_mgr.getPresumedLoc(import_location).getFilename(); + if (filename == ClangExpressionSourceCode::g_prefix_file_name) + return; + SourceModule module; for (const std::pair<IdentifierInfo *, SourceLocation> &component : path) @@ -137,12 +147,14 @@ public: class ClangDiagnosticManagerAdapter : public clang::DiagnosticConsumer { public: - ClangDiagnosticManagerAdapter() - : m_passthrough(new clang::TextDiagnosticBuffer) {} - - ClangDiagnosticManagerAdapter( - const std::shared_ptr<clang::TextDiagnosticBuffer> &passthrough) - : m_passthrough(passthrough) {} + ClangDiagnosticManagerAdapter(DiagnosticOptions &opts) { + DiagnosticOptions *m_options = new DiagnosticOptions(opts); + m_options->ShowPresumedLoc = true; + m_options->ShowLevel = false; + m_os.reset(new llvm::raw_string_ostream(m_output)); + m_passthrough.reset( + new clang::TextDiagnosticPrinter(*m_os, m_options, false)); + } void ResetManager(DiagnosticManager *manager = nullptr) { m_manager = manager; @@ -150,79 +162,92 @@ public: void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, const clang::Diagnostic &Info) override { - 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); - } - } + if (!m_manager) { + // We have no DiagnosticManager before/after parsing but we still could + // receive diagnostics (e.g., by the ASTImporter failing to copy decls + // when we move the expression result ot the ScratchASTContext). Let's at + // least log these diagnostics until we find a way to properly render + // them and display them to the user. + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + if (log) { + llvm::SmallVector<char, 32> diag_str; + Info.FormatDiagnostic(diag_str); + diag_str.push_back('\0'); + const char *plain_diag = diag_str.data(); + LLDB_LOG(log, "Received diagnostic outside parsing: {0}", plain_diag); } + return; } + // Render diagnostic message to m_output. + m_output.clear(); m_passthrough->HandleDiagnostic(DiagLevel, Info); - } + m_os->flush(); - void FlushDiagnostics(DiagnosticsEngine &Diags) { - m_passthrough->FlushDiagnostics(Diags); - } + 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(m_output); + make_new_diagnostic = false; + } + if (make_new_diagnostic) { + // ClangDiagnostic messages are expected to have no whitespace/newlines + // around them. + std::string stripped_output = llvm::StringRef(m_output).trim(); + + auto new_diagnostic = std::make_unique<ClangDiagnostic>( + stripped_output, severity, Info.getID()); + + // 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); + } + } - DiagnosticConsumer *clone(DiagnosticsEngine &Diags) const { - return new ClangDiagnosticManagerAdapter(m_passthrough); + m_manager->AddDiagnostic(std::move(new_diagnostic)); + } } - clang::TextDiagnosticBuffer *GetPassthrough() { return m_passthrough.get(); } + clang::TextDiagnosticPrinter *GetPassthrough() { return m_passthrough.get(); } private: DiagnosticManager *m_manager = nullptr; - std::shared_ptr<clang::TextDiagnosticBuffer> m_passthrough; + std::shared_ptr<clang::TextDiagnosticPrinter> m_passthrough; + /// Output stream of m_passthrough. + std::shared_ptr<llvm::raw_string_ostream> m_os; + /// Output string filled by m_os. + std::string m_output; }; -static void -SetupModuleHeaderPaths(CompilerInstance *compiler, - std::vector<ConstString> include_directories, - lldb::TargetSP target_sp) { +static void SetupModuleHeaderPaths(CompilerInstance *compiler, + std::vector<std::string> include_directories, + lldb::TargetSP target_sp) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); HeaderSearchOptions &search_opts = compiler->getHeaderSearchOpts(); - for (ConstString dir : include_directories) { - search_opts.AddPath(dir.AsCString(), frontend::System, false, true); + for (const std::string &dir : include_directories) { + search_opts.AddPath(dir, frontend::System, false, true); LLDB_LOG(log, "Added user include dir: {0}", dir); } @@ -232,27 +257,9 @@ SetupModuleHeaderPaths(CompilerInstance *compiler, search_opts.ModuleCachePath = module_cache.str(); LLDB_LOG(log, "Using module cache path: {0}", module_cache.c_str()); - FileSpec clang_resource_dir = GetClangResourceDir(); - std::string resource_dir = clang_resource_dir.GetPath(); - if (FileSystem::Instance().IsDirectory(resource_dir)) { - search_opts.ResourceDir = resource_dir; - std::string resource_include = resource_dir + "/include"; - search_opts.AddPath(resource_include, frontend::System, false, true); - - LLDB_LOG(log, "Added resource include dir: {0}", resource_include); - } + search_opts.ResourceDir = GetClangResourceDir().GetPath(); search_opts.ImplicitModuleMaps = true; - - std::vector<std::string> system_include_directories = - target_sp->GetPlatform()->GetSystemIncludeDirectories( - lldb::eLanguageTypeC_plus_plus); - - for (const std::string &include_dir : system_include_directories) { - search_opts.AddPath(include_dir, frontend::System, false, true); - - LLDB_LOG(log, "Added system include dir: {0}", include_dir); - } } //===----------------------------------------------------------------------===// @@ -261,10 +268,12 @@ SetupModuleHeaderPaths(CompilerInstance *compiler, ClangExpressionParser::ClangExpressionParser( ExecutionContextScope *exe_scope, Expression &expr, - bool generate_debug_info, std::vector<ConstString> include_directories) + bool generate_debug_info, std::vector<std::string> include_directories, + std::string filename) : ExpressionParser(exe_scope, expr, generate_debug_info), m_compiler(), m_pp_callbacks(nullptr), - m_include_directories(std::move(include_directories)) { + m_include_directories(std::move(include_directories)), + m_filename(std::move(filename)) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); // We can't compile expressions without a target. So if the exe_scope is @@ -331,9 +340,8 @@ ClangExpressionParser::ClangExpressionParser( 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)); + LLDB_LOGF(log, "Frame has language of type %s", + Language::GetNameForLanguageType(frame_lang)); } // 2. Configure the compiler with a set of default options that are @@ -341,9 +349,8 @@ ClangExpressionParser::ClangExpressionParser( 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()); + LLDB_LOGF(log, "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 @@ -352,9 +359,8 @@ ClangExpressionParser::ClangExpressionParser( // 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()); + LLDB_LOGF(log, "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 @@ -408,12 +414,13 @@ ClangExpressionParser::ClangExpressionParser( 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()); + LLDB_LOGF(log, "Using SIMD alignment: %d", + target_info->getSimdDefaultAlign()); + LLDB_LOGF(log, "Target datalayout string: '%s'", + target_info->getDataLayout().getStringRepresentation().c_str()); + LLDB_LOGF(log, "Target ABI: '%s'", target_info->getABI().str().c_str()); + LLDB_LOGF(log, "Target vector alignment: %d", + target_info->getMaxVectorAlign()); } m_compiler->setTarget(target_info); @@ -508,6 +515,9 @@ ClangExpressionParser::ClangExpressionParser( lang_opts.DoubleSquareBracketAttributes = true; lang_opts.CPlusPlus11 = true; + // The Darwin libc expects this macro to be set. + lang_opts.GNUCVersion = 40201; + SetupModuleHeaderPaths(m_compiler.get(), m_include_directories, target_sp); } @@ -537,8 +547,8 @@ ClangExpressionParser::ClangExpressionParser( // Set CodeGen options m_compiler->getCodeGenOpts().EmitDeclMetadata = true; m_compiler->getCodeGenOpts().InstrumentFunctions = false; - m_compiler->getCodeGenOpts().DisableFPElim = true; - m_compiler->getCodeGenOpts().OmitLeafFramePointer = false; + m_compiler->getCodeGenOpts().setFramePointer( + CodeGenOptions::FramePointerKind::All); if (generate_debug_info) m_compiler->getCodeGenOpts().setDebugInfo(codegenoptions::FullDebugInfo); else @@ -560,7 +570,9 @@ ClangExpressionParser::ClangExpressionParser( // 6. Set up the diagnostic buffer for reporting errors - m_compiler->getDiagnostics().setClient(new ClangDiagnosticManagerAdapter); + auto diag_mgr = new ClangDiagnosticManagerAdapter( + m_compiler->getDiagnostics().getDiagnosticOptions()); + m_compiler->getDiagnostics().setClient(diag_mgr); // 7. Set up the source management objects inside the compiler m_compiler->createFileManager(); @@ -574,8 +586,8 @@ ClangExpressionParser::ClangExpressionParser( llvm::cast<ClangPersistentVariables>( target_sp->GetPersistentExpressionStateForLanguage( lldb::eLanguageTypeC)); - std::unique_ptr<PPCallbacks> pp_callbacks( - new LLDBPreprocessorCallbacks(*decl_vendor, *clang_persistent_vars)); + std::unique_ptr<PPCallbacks> pp_callbacks(new LLDBPreprocessorCallbacks( + *decl_vendor, *clang_persistent_vars, m_compiler->getSourceManager())); m_pp_callbacks = static_cast<LLDBPreprocessorCallbacks *>(pp_callbacks.get()); m_compiler->getPreprocessor().addPPCallbacks(std::move(pp_callbacks)); @@ -592,9 +604,7 @@ ClangExpressionParser::ClangExpressionParser( m_compiler->createASTContext(); clang::ASTContext &ast_context = m_compiler->getASTContext(); - m_ast_context.reset( - new ClangASTContext(m_compiler->getTargetOpts().Triple.c_str())); - m_ast_context->setASTContext(&ast_context); + m_ast_context.reset(new ClangASTContext(ast_context)); std::string module_name("$__lldb_module"); @@ -872,8 +882,7 @@ ClangExpressionParser::ParseInternal(DiagnosticManager &diagnostic_manager, ClangDiagnosticManagerAdapter *adapter = static_cast<ClangDiagnosticManagerAdapter *>( m_compiler->getDiagnostics().getClient()); - clang::TextDiagnosticBuffer *diag_buf = adapter->GetPassthrough(); - diag_buf->FlushDiagnostics(m_compiler->getDiagnostics()); + auto diag_buf = adapter->GetPassthrough(); adapter->ResetManager(&diagnostic_manager); @@ -904,16 +913,19 @@ ClangExpressionParser::ParseInternal(DiagnosticManager &diagnostic_manager, } if (temp_fd != -1) { - lldb_private::File file(temp_fd, true); + lldb_private::NativeFile file(temp_fd, File::eOpenOptionWrite, 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_compiler->getFileManager().getFile(result_path), - SourceLocation(), SrcMgr::C_User)); - created_main_file = true; + if (auto fileEntry = + m_compiler->getFileManager().getFile(result_path)) { + source_mgr.setMainFileID(source_mgr.createFileID( + *fileEntry, + SourceLocation(), SrcMgr::C_User)); + created_main_file = true; + } } } } @@ -921,7 +933,7 @@ ClangExpressionParser::ParseInternal(DiagnosticManager &diagnostic_manager, if (!created_main_file) { std::unique_ptr<MemoryBuffer> memory_buffer = - MemoryBuffer::getMemBufferCopy(expr_text, "<lldb-expr>"); + MemoryBuffer::getMemBufferCopy(expr_text, m_filename); source_mgr.setMainFileID(source_mgr.createFileID(std::move(memory_buffer))); } @@ -1092,8 +1104,8 @@ bool ClangExpressionParser::RewriteExpression( if (num_diags == 0) return false; - for (const Diagnostic *diag : diagnostic_manager.Diagnostics()) { - const ClangDiagnostic *diagnostic = llvm::dyn_cast<ClangDiagnostic>(diag); + for (const auto &diag : diagnostic_manager.Diagnostics()) { + const auto *diagnostic = llvm::dyn_cast<ClangDiagnostic>(diag.get()); if (diagnostic && diagnostic->HasFixIts()) { for (const FixItHint &fixit : diagnostic->FixIts()) { // This is cobbed from clang::Rewrite::FixItRewriter. @@ -1181,9 +1193,8 @@ lldb_private::Status ClangExpressionParser::PrepareForExecution( m_expr.FunctionName()); return err; } else { - if (log) - log->Printf("Found function %s for %s", function_name.AsCString(), - m_expr.FunctionName()); + LLDB_LOGF(log, "Found function %s for %s", function_name.AsCString(), + m_expr.FunctionName()); } } @@ -1198,9 +1209,8 @@ lldb_private::Status ClangExpressionParser::PrepareForExecution( LLVMUserExpression::IRPasses custom_passes; { auto lang = m_expr.Language(); - if (log) - log->Printf("%s - Current expression language is %s\n", __FUNCTION__, - Language::GetNameForLanguageType(lang)); + LLDB_LOGF(log, "%s - Current expression language is %s\n", __FUNCTION__, + Language::GetNameForLanguageType(lang)); lldb::ProcessSP process_sp = exe_ctx.GetProcessSP(); if (process_sp && lang != lldb::eLanguageTypeUnknown) { auto runtime = process_sp->GetLanguageRuntime(lang); @@ -1210,10 +1220,10 @@ lldb_private::Status ClangExpressionParser::PrepareForExecution( } if (custom_passes.EarlyPasses) { - if (log) - log->Printf("%s - Running Early IR Passes from LanguageRuntime on " - "expression module '%s'", - __FUNCTION__, m_expr.FunctionName()); + LLDB_LOGF(log, + "%s - Running Early IR Passes from LanguageRuntime on " + "expression module '%s'", + __FUNCTION__, m_expr.FunctionName()); custom_passes.EarlyPasses->run(*llvm_module_up); } @@ -1230,12 +1240,10 @@ lldb_private::Status ClangExpressionParser::PrepareForExecution( type_system_helper->DeclMap(); // result can be NULL if (decl_map) { - Stream *error_stream = nullptr; Target *target = exe_ctx.GetTargetPtr(); - error_stream = target->GetDebugger().GetErrorFile().get(); - + auto &error_stream = target->GetDebugger().GetErrorStream(); IRForTarget ir_for_target(decl_map, m_expr.NeedsVariableResolution(), - *execution_unit_sp, *error_stream, + *execution_unit_sp, error_stream, function_name.AsCString()); bool ir_can_run = @@ -1298,9 +1306,8 @@ lldb_private::Status ClangExpressionParser::PrepareForExecution( process->SetDynamicCheckers(dynamic_checkers); - if (log) - log->Printf("== [ClangExpressionParser::PrepareForExecution] " - "Finished installing dynamic checkers =="); + LLDB_LOGF(log, "== [ClangExpressionParser::PrepareForExecution] " + "Finished installing dynamic checkers =="); } if (auto *checker_funcs = llvm::dyn_cast<ClangDynamicCheckerFunctions>( @@ -1316,10 +1323,10 @@ lldb_private::Status ClangExpressionParser::PrepareForExecution( } if (custom_passes.LatePasses) { - if (log) - log->Printf("%s - Running Late IR Passes from LanguageRuntime on " - "expression module '%s'", - __FUNCTION__, m_expr.FunctionName()); + LLDB_LOGF(log, + "%s - Running Late IR Passes from LanguageRuntime on " + "expression module '%s'", + __FUNCTION__, m_expr.FunctionName()); custom_passes.LatePasses->run(*module); } diff --git a/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h b/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h index a42c2190ffb8..79ad5728bf74 100644 --- a/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h +++ b/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h @@ -53,9 +53,14 @@ public: /// @param[in] include_directories /// List of include directories that should be used when parsing the /// expression. + /// + /// @param[in] filename + /// Name of the source file that should be used when rendering + /// diagnostics (i.e. errors, warnings or notes from Clang). ClangExpressionParser(ExecutionContextScope *exe_scope, Expression &expr, bool generate_debug_info, - std::vector<ConstString> include_directories = {}); + std::vector<std::string> include_directories = {}, + std::string filename = "<clang expression>"); /// Destructor ~ClangExpressionParser() override; @@ -177,7 +182,9 @@ private: ///encounters module imports std::unique_ptr<ClangASTContext> m_ast_context; - std::vector<ConstString> m_include_directories; + std::vector<std::string> m_include_directories; + /// File name used for the user expression. + std::string m_filename; }; } diff --git a/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp b/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp index f513b1eea360..21cb33402e7f 100644 --- a/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp +++ b/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp @@ -29,7 +29,15 @@ using namespace lldb_private; -const char *ClangExpressionSourceCode::g_expression_prefix = R"( +#define PREFIX_NAME "<lldb wrapper prefix>" + +const llvm::StringRef ClangExpressionSourceCode::g_prefix_file_name = PREFIX_NAME; + +const char *ClangExpressionSourceCode::g_expression_prefix = +"#line 1 \"" PREFIX_NAME R"(" +#ifndef offsetof +#define offsetof(t, d) __builtin_offsetof(t, d) +#endif #ifndef NULL #define NULL (__null) #endif @@ -64,9 +72,6 @@ extern "C" } )"; -static const char *c_start_marker = " /*LLDB_BODY_START*/\n "; -static const char *c_end_marker = ";\n /*LLDB_BODY_END*/\n"; - namespace { class AddMacroState { @@ -166,6 +171,17 @@ static void AddMacros(const DebugMacros *dm, CompileUnit *comp_unit, } } +lldb_private::ClangExpressionSourceCode::ClangExpressionSourceCode( + llvm::StringRef filename, llvm::StringRef name, llvm::StringRef prefix, + llvm::StringRef body, Wrapping wrap) + : ExpressionSourceCode(name, prefix, body, wrap) { + // Use #line markers to pretend that we have a single-line source file + // containing only the user expression. This will hide our wrapper code + // from the user when we render diagnostics with Clang. + m_start_marker = "#line 1 \"" + filename.str() + "\"\n"; + m_end_marker = "\n;\n#line 1 \"<lldb wrapper suffix>\"\n"; +} + namespace { /// Allows checking if a token is contained in a given expression. class TokenVerifier { @@ -286,7 +302,8 @@ bool ClangExpressionSourceCode::GetText( Target *target = exe_ctx.GetTargetPtr(); if (target) { - if (target->GetArchitecture().GetMachine() == llvm::Triple::aarch64) { + if (target->GetArchitecture().GetMachine() == llvm::Triple::aarch64 || + target->GetArchitecture().GetMachine() == llvm::Triple::aarch64_32) { target_specific_defines = "typedef bool BOOL;\n"; } if (target->GetArchitecture().GetMachine() == llvm::Triple::x86_64) { @@ -398,9 +415,9 @@ bool ClangExpressionSourceCode::GetText( case lldb::eLanguageTypeC: case lldb::eLanguageTypeC_plus_plus: case lldb::eLanguageTypeObjC: - tagged_body.append(c_start_marker); + tagged_body.append(m_start_marker); tagged_body.append(m_body); - tagged_body.append(c_end_marker); + tagged_body.append(m_end_marker); break; } switch (wrapping_language) { @@ -474,24 +491,19 @@ bool ClangExpressionSourceCode::GetText( bool ClangExpressionSourceCode::GetOriginalBodyBounds( std::string transformed_text, lldb::LanguageType wrapping_language, size_t &start_loc, size_t &end_loc) { - const char *start_marker; - const char *end_marker; - switch (wrapping_language) { default: return false; case lldb::eLanguageTypeC: case lldb::eLanguageTypeC_plus_plus: case lldb::eLanguageTypeObjC: - start_marker = c_start_marker; - end_marker = c_end_marker; break; } - start_loc = transformed_text.find(start_marker); + start_loc = transformed_text.find(m_start_marker); if (start_loc == std::string::npos) return false; - start_loc += strlen(start_marker); - end_loc = transformed_text.find(end_marker); + start_loc += m_start_marker.size(); + end_loc = transformed_text.find(m_end_marker); return end_loc != std::string::npos; } diff --git a/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.h b/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.h index 894290295837..1d159670b962 100644 --- a/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.h +++ b/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.h @@ -23,15 +23,18 @@ class ExecutionContext; class ClangExpressionSourceCode : public ExpressionSourceCode { public: + /// The file name we use for the wrapper code that we inject before + /// the user expression. + static const llvm::StringRef g_prefix_file_name; static const char *g_expression_prefix; - static ClangExpressionSourceCode *CreateWrapped(const char *prefix, - const char *body) { - return new ClangExpressionSourceCode("$__lldb_expr", prefix, body, true); + static ClangExpressionSourceCode *CreateWrapped(llvm::StringRef filename, + llvm::StringRef prefix, + llvm::StringRef body) { + return new ClangExpressionSourceCode(filename, "$__lldb_expr", prefix, body, + Wrap); } - uint32_t GetNumBodyLines(); - /// Generates the source code that will evaluate the expression. /// /// \param text output parameter containing the source code string. @@ -56,14 +59,20 @@ public: // Given a string returned by GetText, find the beginning and end of the body // passed to CreateWrapped. Return true if the bounds could be found. This // will also work on text with FixItHints applied. - static bool GetOriginalBodyBounds(std::string transformed_text, - lldb::LanguageType wrapping_language, - size_t &start_loc, size_t &end_loc); + bool GetOriginalBodyBounds(std::string transformed_text, + lldb::LanguageType wrapping_language, + size_t &start_loc, size_t &end_loc); protected: - ClangExpressionSourceCode(const char *name, const char *prefix, const char *body, - bool wrap) : - ExpressionSourceCode(name, prefix, body, wrap) {} + ClangExpressionSourceCode(llvm::StringRef filename, llvm::StringRef name, + llvm::StringRef prefix, llvm::StringRef body, + Wrapping wrap); + +private: + /// String marking the start of the user expression. + std::string m_start_marker; + /// String marking the end of the user expression. + std::string m_end_marker; }; } // namespace lldb_private diff --git a/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp b/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp index eabc96aa8e51..8fbfa6e47578 100644 --- a/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp +++ b/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp @@ -179,8 +179,7 @@ ClangFunctionCaller::CompileFunction(lldb::ThreadSP thread_to_use_sp, 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()); + LLDB_LOGF(log, "Expression: \n\n%s\n\n", m_wrapper_function_text.c_str()); // Okay, now compile this expression diff --git a/source/Plugins/ExpressionParser/Clang/ClangHost.cpp b/source/Plugins/ExpressionParser/Clang/ClangHost.cpp index 65c547391831..42d3f22014dd 100644 --- a/source/Plugins/ExpressionParser/Clang/ClangHost.cpp +++ b/source/Plugins/ExpressionParser/Clang/ClangHost.cpp @@ -30,10 +30,10 @@ static bool VerifyClangPath(const llvm::Twine &clang_path) { if (FileSystem::Instance().IsDirectory(clang_path)) return true; Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); - if (log) - log->Printf("VerifyClangPath(): " - "failed to stat clang resource directory at \"%s\"", - clang_path.str().c_str()); + LLDB_LOGF(log, + "VerifyClangPath(): " + "failed to stat clang resource directory at \"%s\"", + clang_path.str().c_str()); return false; } @@ -67,10 +67,10 @@ static bool DefaultComputeClangResourceDirectory(FileSpec &lldb_shlib_spec, llvm::sys::path::native(relative_path); llvm::sys::path::append(clang_dir, relative_path); if (!verify || VerifyClangPath(clang_dir)) { - if (log) - log->Printf("DefaultComputeClangResourceDir: Setting ClangResourceDir " - "to \"%s\", verify = %s", - clang_dir.str().str().c_str(), verify ? "true" : "false"); + LLDB_LOGF(log, + "DefaultComputeClangResourceDir: Setting ClangResourceDir " + "to \"%s\", verify = %s", + clang_dir.str().str().c_str(), verify ? "true" : "false"); file_spec.GetDirectory().SetString(clang_dir); FileSystem::Instance().Resolve(file_spec); return true; @@ -160,9 +160,8 @@ FileSpec lldb_private::GetClangResourceDir() { ComputeClangResourceDirectory(lldb_file_spec, g_cached_resource_dir, true); Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); - if (log) - log->Printf("GetClangResourceDir() => '%s'", - g_cached_resource_dir.GetPath().c_str()); + LLDB_LOGF(log, "GetClangResourceDir() => '%s'", + g_cached_resource_dir.GetPath().c_str()); }); return g_cached_resource_dir; } diff --git a/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp b/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp index 4a220790e50d..f3df589d7311 100644 --- a/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp +++ b/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp @@ -27,6 +27,7 @@ #include "lldb/Core/ModuleList.h" #include "lldb/Host/Host.h" #include "lldb/Host/HostInfo.h" +#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Symbol/CompileUnit.h" #include "lldb/Symbol/SourceModule.h" #include "lldb/Target/Target.h" @@ -110,6 +111,9 @@ private: ImportedModuleMap m_imported_modules; ImportedModuleSet m_user_imported_modules; const clang::ExternalASTMerger::OriginMap m_origin_map; + // We assume that every ASTContext has an ClangASTContext, so we also store + // a custom ClangASTContext for our internal ASTContext. + std::unique_ptr<ClangASTContext> m_ast_context; }; } // anonymous namespace @@ -143,7 +147,8 @@ void StoringDiagnosticConsumer::DumpDiagnostics(Stream &error_stream) { } } -ClangModulesDeclVendor::ClangModulesDeclVendor() {} +ClangModulesDeclVendor::ClangModulesDeclVendor() + : ClangDeclVendor(eClangModuleDeclVendor) {} ClangModulesDeclVendor::~ClangModulesDeclVendor() {} @@ -155,7 +160,11 @@ ClangModulesDeclVendorImpl::ClangModulesDeclVendorImpl( : m_diagnostics_engine(std::move(diagnostics_engine)), m_compiler_invocation(std::move(compiler_invocation)), m_compiler_instance(std::move(compiler_instance)), - m_parser(std::move(parser)), m_origin_map() {} + m_parser(std::move(parser)), m_origin_map() { + + // Initialize our ClangASTContext. + m_ast_context.reset(new ClangASTContext(m_compiler_instance->getASTContext())); +} void ClangModulesDeclVendorImpl::ReportModuleExportsHelper( std::set<ClangModulesDeclVendor::ModuleID> &exports, @@ -237,11 +246,11 @@ bool ClangModulesDeclVendorImpl::AddModule(const SourceModule &module, bool is_system = true; bool is_framework = false; - auto *dir = + auto dir = HS.getFileMgr().getDirectory(module.search_path.GetStringRef()); if (!dir) return error(); - auto *file = HS.lookupModuleMapFile(dir, is_framework); + auto *file = HS.lookupModuleMapFile(*dir, is_framework); if (!file) return error(); if (!HS.loadModuleMapFile(file, is_system)) @@ -562,8 +571,9 @@ ClangModulesDeclVendorImpl::DoGetModule(clang::ModuleIdPath path, clang::ExternalASTMerger::ImporterSource ClangModulesDeclVendorImpl::GetImporterSource() { - return {m_compiler_instance->getASTContext(), - m_compiler_instance->getFileManager(), m_origin_map}; + return clang::ExternalASTMerger::ImporterSource( + m_compiler_instance->getASTContext(), + m_compiler_instance->getFileManager(), m_origin_map); } static const char *ModuleImportBufferName = "LLDBModulesMemoryBuffer"; diff --git a/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h b/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h index d5c8757bdcd0..e099b59041d8 100644 --- a/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h +++ b/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h @@ -10,22 +10,27 @@ #define liblldb_ClangModulesDeclVendor_h #include "lldb/Core/ClangForward.h" -#include "lldb/Symbol/DeclVendor.h" #include "lldb/Symbol/SourceModule.h" #include "lldb/Target/Platform.h" +#include "Plugins/ExpressionParser/Clang/ClangDeclVendor.h" + #include <set> #include <vector> namespace lldb_private { -class ClangModulesDeclVendor : public DeclVendor { +class ClangModulesDeclVendor : public ClangDeclVendor { public: // Constructors and Destructors ClangModulesDeclVendor(); ~ClangModulesDeclVendor() override; + static bool classof(const DeclVendor *vendor) { + return vendor->GetKind() == eClangModuleDeclVendor; + } + static ClangModulesDeclVendor *Create(Target &target); typedef std::vector<ConstString> ModulePath; diff --git a/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp b/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp index 742a14992dc9..24dd705e37b1 100644 --- a/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp +++ b/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp @@ -23,8 +23,7 @@ using namespace lldb; using namespace lldb_private; ClangPersistentVariables::ClangPersistentVariables() - : lldb_private::PersistentExpressionState(LLVMCastKind::eKindClang), - m_next_persistent_variable_id(0) {} + : lldb_private::PersistentExpressionState(LLVMCastKind::eKindClang) {} ExpressionVariableSP ClangPersistentVariables::CreatePersistentVariable( const lldb::ValueObjectSP &valobj_sp) { @@ -43,13 +42,25 @@ void ClangPersistentVariables::RemovePersistentVariable( lldb::ExpressionVariableSP variable) { RemoveVariable(variable); - const char *name = variable->GetName().AsCString(); + // Check if the removed variable was the last one that was created. If yes, + // reuse the variable id for the next variable. - if (*name != '$') + // Nothing to do if we have not assigned a variable id so far. + if (m_next_persistent_variable_id == 0) return; - name++; - if (strtoul(name, nullptr, 0) == m_next_persistent_variable_id - 1) + llvm::StringRef name = variable->GetName().GetStringRef(); + // Remove the prefix from the variable that only the indes is left. + if (!name.consume_front(GetPersistentVariablePrefix(false))) + return; + + // Check if the variable contained a variable id. + uint32_t variable_id; + if (name.getAsInteger(10, variable_id)) + return; + // If it's the most recent variable id that was assigned, make sure that this + // variable id will be used for the next persistent variable. + if (variable_id == m_next_persistent_variable_id - 1) m_next_persistent_variable_id--; } diff --git a/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h b/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h index b39f89ad7eef..95e6c3ac963d 100644 --- a/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h +++ b/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h @@ -45,11 +45,20 @@ public: uint32_t addr_byte_size) override; void RemovePersistentVariable(lldb::ExpressionVariableSP variable) override; - llvm::StringRef - GetPersistentVariablePrefix(bool is_error) const override { + + llvm::StringRef GetPersistentVariablePrefix(bool is_error) const override { return "$"; } + /// Returns the next file name that should be used for user expressions. + std::string GetNextExprFileName() { + std::string name; + name.append("<user expression "); + name.append(std::to_string(m_next_user_file_id++)); + name.append(">"); + return name; + } + llvm::Optional<CompilerType> GetCompilerTypeFromPersistentDecl(ConstString type_name) override; @@ -66,8 +75,10 @@ public: } private: - uint32_t m_next_persistent_variable_id; ///< The counter used by - ///GetNextResultName(). + /// The counter used by GetNextExprFileName. + uint32_t m_next_user_file_id = 0; + // The counter used by GetNextPersistentVariableName + uint32_t m_next_persistent_variable_id = 0; typedef llvm::DenseMap<const char *, clang::NamedDecl *> PersistentDeclMap; PersistentDeclMap diff --git a/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp b/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp index 2dae5b7022f3..da1ca785635c 100644 --- a/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp +++ b/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp @@ -6,6 +6,8 @@ // //===----------------------------------------------------------------------===// +#include "lldb/Host/Config.h" + #include <stdio.h> #if HAVE_SYS_TYPES_H #include <sys/types.h> @@ -21,9 +23,9 @@ #include "ClangDiagnostic.h" #include "ClangExpressionDeclMap.h" #include "ClangExpressionParser.h" -#include "ClangExpressionSourceCode.h" #include "ClangModulesDeclVendor.h" #include "ClangPersistentVariables.h" +#include "CppModuleConfiguration.h" #include "lldb/Core/Debugger.h" #include "lldb/Core/Module.h" @@ -90,21 +92,18 @@ ClangUserExpression::~ClangUserExpression() {} void ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Status &err) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); - if (log) - log->Printf("ClangUserExpression::ScanContext()"); + LLDB_LOGF(log, "ClangUserExpression::ScanContext()"); m_target = exe_ctx.GetTargetPtr(); if (!(m_allow_cxx || m_allow_objc)) { - if (log) - log->Printf(" [CUE::SC] Settings inhibit C++ and Objective-C"); + LLDB_LOGF(log, " [CUE::SC] Settings inhibit C++ and Objective-C"); return; } StackFrame *frame = exe_ctx.GetFramePtr(); if (frame == nullptr) { - if (log) - log->Printf(" [CUE::SC] Null stack frame"); + LLDB_LOGF(log, " [CUE::SC] Null stack frame"); return; } @@ -112,8 +111,7 @@ void ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Status &err) { lldb::eSymbolContextBlock); if (!sym_ctx.function) { - if (log) - log->Printf(" [CUE::SC] Null function"); + LLDB_LOGF(log, " [CUE::SC] Null function"); return; } @@ -121,16 +119,14 @@ void ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Status &err) { Block *function_block = sym_ctx.GetFunctionBlock(); if (!function_block) { - if (log) - log->Printf(" [CUE::SC] Null function block"); + LLDB_LOGF(log, " [CUE::SC] Null function block"); return; } CompilerDeclContext decl_context = function_block->GetDeclContext(); if (!decl_context) { - if (log) - log->Printf(" [CUE::SC] Null decl context"); + LLDB_LOGF(log, " [CUE::SC] Null decl context"); return; } @@ -317,17 +313,13 @@ void ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Status &err) { // 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) { -#define OBJC_CAST_HACK_FROM "(int)[" -#define OBJC_CAST_HACK_TO "(int)(long long)[" - - size_t from_offset; + const std::string from = "(int)["; + const std::string to = "(int)(long long)["; - 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); + size_t offset; -#undef OBJC_CAST_HACK_TO -#undef OBJC_CAST_HACK_FROM + while ((offset = expr.find(from)) != expr.npos) + expr.replace(offset, from.size(), to); } bool ClangUserExpression::SetupPersistentState(DiagnosticManager &diagnostic_manager, @@ -336,6 +328,7 @@ bool ClangUserExpression::SetupPersistentState(DiagnosticManager &diagnostic_man if (PersistentExpressionState *persistent_state = target->GetPersistentExpressionStateForLanguage( lldb::eLanguageTypeC)) { + m_clang_state = llvm::cast<ClangPersistentVariables>(persistent_state); m_result_delegate.RegisterPersistentState(persistent_state); } else { diagnostic_manager.PutString( @@ -384,30 +377,34 @@ static void SetupDeclVendor(ExecutionContext &exe_ctx, Target *target) { } } -void ClangUserExpression::UpdateLanguageForExpr( +void ClangUserExpression::UpdateLanguageForExpr() { + m_expr_lang = lldb::LanguageType::eLanguageTypeUnknown; + if (m_options.GetExecutionPolicy() == eExecutionPolicyTopLevel) + return; + if (m_in_cplusplus_method) + m_expr_lang = lldb::eLanguageTypeC_plus_plus; + else if (m_in_objectivec_method) + m_expr_lang = lldb::eLanguageTypeObjC; + else + m_expr_lang = lldb::eLanguageTypeC; +} + +void ClangUserExpression::CreateSourceCode( DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx, std::vector<std::string> modules_to_import, bool for_completion) { - m_expr_lang = lldb::LanguageType::eLanguageTypeUnknown; + m_filename = m_clang_state->GetNextExprFileName(); std::string prefix = m_expr_prefix; if (m_options.GetExecutionPolicy() == eExecutionPolicyTopLevel) { m_transformed_text = m_expr_text; } else { - std::unique_ptr<ClangExpressionSourceCode> source_code( - ClangExpressionSourceCode::CreateWrapped(prefix.c_str(), - m_expr_text.c_str())); - - if (m_in_cplusplus_method) - m_expr_lang = lldb::eLanguageTypeC_plus_plus; - else if (m_in_objectivec_method) - m_expr_lang = lldb::eLanguageTypeObjC; - else - m_expr_lang = lldb::eLanguageTypeC; - - if (!source_code->GetText(m_transformed_text, m_expr_lang, - m_in_static_method, exe_ctx, !m_ctx_obj, - for_completion, modules_to_import)) { + m_source_code.reset(ClangExpressionSourceCode::CreateWrapped( + m_filename, prefix.c_str(), m_expr_text.c_str())); + + if (!m_source_code->GetText(m_transformed_text, m_expr_lang, + m_in_static_method, exe_ctx, !m_ctx_obj, + for_completion, modules_to_import)) { diagnostic_manager.PutString(eDiagnosticSeverityError, "couldn't construct expression body"); return; @@ -417,7 +414,7 @@ void ClangUserExpression::UpdateLanguageForExpr( // transformed code. We need this later for the code completion. std::size_t original_start; std::size_t original_end; - bool found_bounds = source_code->GetOriginalBodyBounds( + bool found_bounds = m_source_code->GetOriginalBodyBounds( m_transformed_text, m_expr_lang, original_start, original_end); if (found_bounds) m_user_expression_start_pos = original_start; @@ -437,48 +434,70 @@ static bool SupportsCxxModuleImport(lldb::LanguageType language) { } } -std::vector<std::string> -ClangUserExpression::GetModulesToImport(ExecutionContext &exe_ctx) { +/// Utility method that puts a message into the expression log and +/// returns an invalid module configuration. +static CppModuleConfiguration LogConfigError(const std::string &msg) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + LLDB_LOG(log, "[C++ module config] {0}", msg); + return CppModuleConfiguration(); +} - if (!SupportsCxxModuleImport(Language())) - return {}; +CppModuleConfiguration GetModuleConfig(lldb::LanguageType language, + ExecutionContext &exe_ctx) { + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + + // Don't do anything if this is not a C++ module configuration. + if (!SupportsCxxModuleImport(language)) + return LogConfigError("Language doesn't support C++ modules"); Target *target = exe_ctx.GetTargetPtr(); - if (!target || !target->GetEnableImportStdModule()) - return {}; + if (!target) + return LogConfigError("No target"); + + if (!target->GetEnableImportStdModule()) + return LogConfigError("Importing std module not enabled in settings"); StackFrame *frame = exe_ctx.GetFramePtr(); if (!frame) - return {}; + return LogConfigError("No frame"); Block *block = frame->GetFrameBlock(); if (!block) - return {}; + return LogConfigError("No block"); SymbolContext sc; block->CalculateSymbolContext(&sc); if (!sc.comp_unit) - return {}; - - if (log) { - for (const SourceModule &m : sc.comp_unit->GetImportedModules()) { - LLDB_LOG(log, "Found module in compile unit: {0:$[.]} - include dir: {1}", - llvm::make_range(m.path.begin(), m.path.end()), m.search_path); + return LogConfigError("Couldn't calculate symbol context"); + + // Build a list of files we need to analyze to build the configuration. + FileSpecList files; + for (const FileSpec &f : sc.comp_unit->GetSupportFiles()) + files.AppendIfUnique(f); + // We also need to look at external modules in the case of -gmodules as they + // contain the support files for libc++ and the C library. + sc.comp_unit->ForEachExternalModule([&files](lldb::ModuleSP module) { + for (std::size_t i = 0; i < module->GetNumCompileUnits(); ++i) { + const FileSpecList &support_files = + module->GetCompileUnitAtIndex(i)->GetSupportFiles(); + for (const FileSpec &f : support_files) { + files.AppendIfUnique(f); + } } + }); + + LLDB_LOG(log, "[C++ module config] Found {0} support files to analyze", + files.GetSize()); + if (log && log->GetVerbose()) { + for (const FileSpec &f : files) + LLDB_LOGV(log, "[C++ module config] Analyzing support file: {0}", + f.GetPath()); } - for (const SourceModule &m : sc.comp_unit->GetImportedModules()) - m_include_directories.push_back(m.search_path); - - // Check if we imported 'std' or any of its submodules. - // We currently don't support importing any other modules in the expression - // parser. - for (const SourceModule &m : sc.comp_unit->GetImportedModules()) - if (!m.path.empty() && m.path.front() == "std") - return {"std"}; - - return {}; + // Try to create a configuration from the files. If there is no valid + // configuration possible with the files, this just returns an invalid + // configuration. + return CppModuleConfiguration(files); } bool ClangUserExpression::PrepareForParsing( @@ -506,14 +525,21 @@ bool ClangUserExpression::PrepareForParsing( SetupDeclVendor(exe_ctx, m_target); - std::vector<std::string> used_modules = GetModulesToImport(exe_ctx); - m_imported_cpp_modules = !used_modules.empty(); + CppModuleConfiguration module_config = GetModuleConfig(m_language, exe_ctx); + llvm::ArrayRef<std::string> imported_modules = + module_config.GetImportedModules(); + m_imported_cpp_modules = !imported_modules.empty(); + m_include_directories = module_config.GetIncludeDirs(); LLDB_LOG(log, "List of imported modules in expression: {0}", - llvm::make_range(used_modules.begin(), used_modules.end())); - - UpdateLanguageForExpr(diagnostic_manager, exe_ctx, used_modules, - for_completion); + llvm::make_range(imported_modules.begin(), imported_modules.end())); + LLDB_LOG(log, "List of include directories gathered for modules: {0}", + llvm::make_range(m_include_directories.begin(), + m_include_directories.end())); + + UpdateLanguageForExpr(); + CreateSourceCode(diagnostic_manager, exe_ctx, imported_modules, + for_completion); return true; } @@ -527,8 +553,7 @@ bool ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager, if (!PrepareForParsing(diagnostic_manager, exe_ctx, /*for_completion*/ false)) return false; - if (log) - log->Printf("Parsing the following code:\n%s", m_transformed_text.c_str()); + LLDB_LOGF(log, "Parsing the following code:\n%s", m_transformed_text.c_str()); //////////////////////////////////// // Set up the target and compiler @@ -573,7 +598,7 @@ bool ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager, // parser_sp will never be empty. ClangExpressionParser parser(exe_scope, *this, generate_debug_info, - m_include_directories); + m_include_directories, m_filename); unsigned num_errors = parser.Parse(diagnostic_manager); @@ -586,8 +611,11 @@ bool ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager, size_t fixed_end; const std::string &fixed_expression = diagnostic_manager.GetFixedExpression(); - if (ClangExpressionSourceCode::GetOriginalBodyBounds( - fixed_expression, m_expr_lang, fixed_start, fixed_end)) + // Retrieve the original expression in case we don't have a top level + // expression (which has no surrounding source code). + if (m_source_code && + m_source_code->GetOriginalBodyBounds(fixed_expression, m_expr_lang, + fixed_start, fixed_end)) m_fixed_text = fixed_expression.substr(fixed_start, fixed_end - fixed_start); } @@ -648,12 +676,10 @@ bool ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager, register_execution_unit = true; } - if (register_execution_unit) { - llvm::cast<PersistentExpressionState>( - exe_ctx.GetTargetPtr()->GetPersistentExpressionStateForLanguage( - m_language)) + if (register_execution_unit) + exe_ctx.GetTargetPtr() + ->GetPersistentExpressionStateForLanguage(m_language) ->RegisterExecutionUnit(m_execution_unit_sp); - } } if (generate_debug_info) { @@ -726,8 +752,7 @@ bool ClangUserExpression::Complete(ExecutionContext &exe_ctx, if (!PrepareForParsing(diagnostic_manager, exe_ctx, /*for_completion*/ true)) return false; - if (log) - log->Printf("Parsing the following code:\n%s", m_transformed_text.c_str()); + LLDB_LOGF(log, "Parsing the following code:\n%s", m_transformed_text.c_str()); ////////////////////////// // Parse the expression diff --git a/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h b/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h index 24c152bdb45d..d94f9cc5e066 100644 --- a/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h +++ b/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h @@ -15,6 +15,7 @@ #include "ASTStructExtractor.h" #include "ClangExpressionDeclMap.h" #include "ClangExpressionHelper.h" +#include "ClangExpressionSourceCode.h" #include "ClangExpressionVariable.h" #include "IRForTarget.h" @@ -105,6 +106,9 @@ public: /// If not eResultTypeAny, the type to use for the expression /// result. /// + /// \param[in] options + /// Additional options for the expression. + /// /// \param[in] ctx_obj /// The object (if any) in which context the expression /// must be evaluated. For details see the comment to @@ -175,11 +179,11 @@ private: lldb::addr_t struct_address, DiagnosticManager &diagnostic_manager) override; - std::vector<std::string> GetModulesToImport(ExecutionContext &exe_ctx); - void UpdateLanguageForExpr(DiagnosticManager &diagnostic_manager, - ExecutionContext &exe_ctx, - std::vector<std::string> modules_to_import, - bool for_completion); + void CreateSourceCode(DiagnosticManager &diagnostic_manager, + ExecutionContext &exe_ctx, + std::vector<std::string> modules_to_import, + bool for_completion); + void UpdateLanguageForExpr(); bool SetupPersistentState(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx); bool PrepareForParsing(DiagnosticManager &diagnostic_manager, @@ -205,13 +209,17 @@ private: /// The language type of the current expression. lldb::LanguageType m_expr_lang = lldb::eLanguageTypeUnknown; /// The include directories that should be used when parsing the expression. - std::vector<ConstString> m_include_directories; + std::vector<std::string> m_include_directories; /// The absolute character position in the transformed source code where the /// user code (as typed by the user) starts. If the variable is empty, then we /// were not able to calculate this position. llvm::Optional<size_t> m_user_expression_start_pos; ResultDelegate m_result_delegate; + ClangPersistentVariables *m_clang_state; + std::unique_ptr<ClangExpressionSourceCode> m_source_code; + /// File name used for the expression. + std::string m_filename; /// The object (if any) in which context the expression is evaluated. /// See the comment to `UserExpression::Evaluate` for details. @@ -219,6 +227,23 @@ private: /// True iff this expression explicitly imported C++ modules. bool m_imported_cpp_modules = false; + + /// True if the expression parser should enforce the presence of a valid class + /// pointer in order to generate the expression as a method. + bool m_enforce_valid_object = true; + /// True if the expression is compiled as a C++ member function (true if it + /// was parsed when exe_ctx was in a C++ method). + bool m_in_cplusplus_method = false; + /// True if the expression is compiled as an Objective-C method (true if it + /// was parsed when exe_ctx was in an Objective-C method). + bool m_in_objectivec_method = false; + /// True if the expression is compiled as a static (or class) method + /// (currently true if it was parsed when exe_ctx was in an Objective-C class + /// method). + bool m_in_static_method = false; + /// True if "this" or "self" must be looked up and passed in. False if the + /// expression doesn't really use them and they can be NULL. + bool m_needs_object_ptr = false; }; } // namespace lldb_private diff --git a/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp b/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp index 5eec224477fc..564c62c6a2c6 100644 --- a/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp +++ b/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp @@ -6,6 +6,8 @@ // //===----------------------------------------------------------------------===// +#include "lldb/Host/Config.h" + #include "ClangUtilityFunction.h" #include "ClangExpressionDeclMap.h" #include "ClangExpressionParser.h" diff --git a/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.cpp b/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.cpp new file mode 100644 index 000000000000..51ae73285b53 --- /dev/null +++ b/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.cpp @@ -0,0 +1,82 @@ +//===-- CppModuleConfiguration.cpp ----------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "CppModuleConfiguration.h" + +#include "ClangHost.h" +#include "lldb/Host/FileSystem.h" + +using namespace lldb_private; + +bool CppModuleConfiguration::SetOncePath::TrySet(llvm::StringRef path) { + // Setting for the first time always works. + if (m_first) { + m_path = path.str(); + m_valid = true; + m_first = false; + return true; + } + // Changing the path to the same value is fine. + if (m_path == path) + return true; + + // Changing the path after it was already set is not allowed. + m_valid = false; + return false; +} + +bool CppModuleConfiguration::analyzeFile(const FileSpec &f) { + using namespace llvm::sys::path; + // Convert to slashes to make following operations simpler. + std::string dir_buffer = convert_to_slash(f.GetDirectory().GetStringRef()); + llvm::StringRef posix_dir(dir_buffer); + + // Check for /c++/vX/ that is used by libc++. + static llvm::Regex libcpp_regex(R"regex(/c[+][+]/v[0-9]/)regex"); + if (libcpp_regex.match(f.GetPath())) { + // Strip away libc++'s /experimental directory if there is one. + posix_dir.consume_back("/experimental"); + return m_std_inc.TrySet(posix_dir); + } + + // Check for /usr/include. On Linux this might be /usr/include/bits, so + // we should remove that '/bits' suffix to get the actual include directory. + if (posix_dir.endswith("/usr/include/bits")) + posix_dir.consume_back("/bits"); + if (posix_dir.endswith("/usr/include")) + return m_c_inc.TrySet(posix_dir); + + // File wasn't interesting, continue analyzing. + return true; +} + +bool CppModuleConfiguration::hasValidConfig() { + // We all these include directories to have a valid usable configuration. + return m_c_inc.Valid() && m_std_inc.Valid(); +} + +CppModuleConfiguration::CppModuleConfiguration( + const FileSpecList &support_files) { + // Analyze all files we were given to build the configuration. + bool error = !llvm::all_of(support_files, + std::bind(&CppModuleConfiguration::analyzeFile, + this, std::placeholders::_1)); + // If we have a valid configuration at this point, set the + // include directories and module list that should be used. + if (!error && hasValidConfig()) { + // Calculate the resource directory for LLDB. + llvm::SmallString<256> resource_dir; + llvm::sys::path::append(resource_dir, GetClangResourceDir().GetPath(), + "include"); + m_resource_inc = resource_dir.str(); + + // This order matches the way Clang orders these directories. + m_include_dirs = {m_std_inc.Get(), m_resource_inc, m_c_inc.Get()}; + m_imported_modules = {"std"}; + } +} diff --git a/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.h b/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.h new file mode 100644 index 000000000000..8e892e37d0de --- /dev/null +++ b/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.h @@ -0,0 +1,84 @@ +//===-- CppModuleConfiguration.h --------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_CppModuleConfiguration_h_ +#define liblldb_CppModuleConfiguration_h_ + +#include <lldb/Core/FileSpecList.h> +#include <llvm/Support/Regex.h> + +namespace lldb_private { + +/// A Clang configuration when importing C++ modules. +/// +/// Includes a list of include paths that should be used when importing +/// and a list of modules that can be imported. Currently only used when +/// importing the 'std' module and its dependencies. +class CppModuleConfiguration { + /// Utility class for a path that can only be set once. + class SetOncePath { + std::string m_path; + bool m_valid = false; + /// True iff this path hasn't been set yet. + bool m_first = true; + + public: + /// Try setting the path. Returns true if the path was set and false if + /// the path was already set. + LLVM_NODISCARD bool TrySet(llvm::StringRef path); + /// Return the path if there is one. + std::string Get() const { + assert(m_valid && "Called Get() on an invalid SetOncePath?"); + return m_path; + } + /// Returns true iff this path was set exactly once so far. + bool Valid() const { return m_valid; } + }; + + /// If valid, the include path used for the std module. + SetOncePath m_std_inc; + /// If valid, the include path to the C library (e.g. /usr/include). + SetOncePath m_c_inc; + /// The Clang resource include path for this configuration. + std::string m_resource_inc; + + std::vector<std::string> m_include_dirs; + std::vector<std::string> m_imported_modules; + + /// Analyze a given source file to build the current configuration. + /// Returns false iff there was a fatal error that makes analyzing any + /// further files pointless as the configuration is now invalid. + bool analyzeFile(const FileSpec &f); + +public: + /// Creates a configuraiton by analyzing the given list of used source files. + /// + /// Currently only looks at the used paths and doesn't actually access the + /// files on the disk. + explicit CppModuleConfiguration(const FileSpecList &support_files); + /// Creates an empty and invalid configuration. + CppModuleConfiguration() {} + + /// Returns true iff this is a valid configuration that can be used to + /// load and compile modules. + bool hasValidConfig(); + + /// Returns a list of include directories that should be used when using this + /// configuration (e.g. {"/usr/include", "/usr/include/c++/v1"}). + llvm::ArrayRef<std::string> GetIncludeDirs() const { return m_include_dirs; } + + /// Returns a list of (top level) modules that should be imported when using + /// this configuration (e.g. {"std"}). + llvm::ArrayRef<std::string> GetImportedModules() const { + return m_imported_modules; + } +}; + +} // namespace lldb_private + +#endif diff --git a/source/Plugins/ExpressionParser/Clang/IRDynamicChecks.cpp b/source/Plugins/ExpressionParser/Clang/IRDynamicChecks.cpp index f8e004fe7d4a..d5ffb9529f36 100644 --- a/source/Plugins/ExpressionParser/Clang/IRDynamicChecks.cpp +++ b/source/Plugins/ExpressionParser/Clang/IRDynamicChecks.cpp @@ -320,9 +320,8 @@ protected: bool InstrumentInstruction(llvm::Instruction *inst) override { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); - if (log) - log->Printf("Instrumenting load/store instruction: %s\n", - PrintValue(inst).c_str()); + LLDB_LOGF(log, "Instrumenting load/store instruction: %s\n", + PrintValue(inst).c_str()); if (!m_valid_pointer_check_func) m_valid_pointer_check_func = @@ -483,9 +482,8 @@ protected: std::string name_str = called_function->getName().str(); const char *name_cstr = name_str.c_str(); - if (log) - log->Printf("Found call to %s: %s\n", name_cstr, - PrintValue(call_inst).c_str()); + LLDB_LOGF(log, "Found call to %s: %s\n", name_cstr, + PrintValue(call_inst).c_str()); if (name_str.find("objc_msgSend") == std::string::npos) return true; @@ -520,10 +518,9 @@ protected: return true; } - if (log) - log->Printf( - "Function name '%s' contains 'objc_msgSend' but is not handled", - name_str.c_str()); + LLDB_LOGF(log, + "Function name '%s' contains 'objc_msgSend' but is not handled", + name_str.c_str()); return true; } @@ -548,8 +545,7 @@ bool IRDynamicChecks::runOnModule(llvm::Module &M) { llvm::Function *function = M.getFunction(StringRef(m_func_name)); if (!function) { - if (log) - log->Printf("Couldn't find %s() in the module", m_func_name.c_str()); + LLDB_LOGF(log, "Couldn't find %s() in the module", m_func_name.c_str()); return false; } @@ -582,7 +578,7 @@ bool IRDynamicChecks::runOnModule(llvm::Module &M) { oss.flush(); - log->Printf("Module after dynamic checks: \n%s", s.c_str()); + LLDB_LOGF(log, "Module after dynamic checks: \n%s", s.c_str()); } return true; diff --git a/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp b/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp index 07acb2e1030f..4e871f7d6a44 100644 --- a/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp +++ b/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp @@ -43,6 +43,8 @@ using namespace llvm; static char ID; +typedef SmallVector<Instruction *, 2> InstrList; + IRForTarget::FunctionValueCache::FunctionValueCache(Maker const &maker) : m_maker(maker), m_values() {} @@ -153,6 +155,15 @@ clang::NamedDecl *IRForTarget::DeclForGlobal(GlobalValue *global_val) { return DeclForGlobal(global_val, m_module); } +/// Returns true iff the mangled symbol is for a static guard variable. +static bool isGuardVariableSymbol(llvm::StringRef mangled_symbol, + bool check_ms_abi = true) { + bool result = mangled_symbol.startswith("_ZGV"); // Itanium ABI guard variable + if (check_ms_abi) + result |= mangled_symbol.endswith("@4IA"); // Microsoft ABI + return result; +} + bool IRForTarget::CreateResultVariable(llvm::Function &llvm_function) { lldb_private::Log *log( lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); @@ -164,64 +175,58 @@ bool IRForTarget::CreateResultVariable(llvm::Function &llvm_function) { ValueSymbolTable &value_symbol_table = m_module->getValueSymbolTable(); - std::string result_name_str; - const char *result_name = nullptr; + llvm::StringRef result_name; + bool found_result = false; - 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(); + for (StringMapEntry<llvm::Value *> &value_symbol : value_symbol_table) { + result_name = value_symbol.first(); - if (strstr(value_name, "$__lldb_expr_result_ptr") && - strncmp(value_name, "_ZGV", 4)) { - result_name = value_name; + // Check if this is a guard variable. It seems this causes some hiccups + // on Windows, so let's only check for Itanium guard variables. + bool is_guard_var = isGuardVariableSymbol(result_name, /*MS ABI*/ false); + + if (result_name.contains("$__lldb_expr_result_ptr") && !is_guard_var) { + found_result = true; m_result_is_pointer = true; break; } - if (strstr(value_name, "$__lldb_expr_result") && - strncmp(value_name, "_ZGV", 4)) { - result_name = value_name; + if (result_name.contains("$__lldb_expr_result") && !is_guard_var) { + found_result = true; m_result_is_pointer = false; break; } } - if (!result_name) { - if (log) - log->PutCString("Couldn't find result variable"); + if (!found_result) { + LLDB_LOG(log, "Couldn't find result variable"); return true; } - if (log) - log->Printf("Result name: \"%s\"", result_name); + LLDB_LOG(log, "Result name: \"{0}\"", result_name); Value *result_value = m_module->getNamedValue(result_name); if (!result_value) { - if (log) - log->PutCString("Result variable had no data"); + LLDB_LOG(log, "Result variable had no data"); - m_error_stream.Printf("Internal error [IRForTarget]: Result variable's " - "name (%s) exists, but not its definition\n", + m_error_stream.Format("Internal error [IRForTarget]: Result variable's " + "name ({0}) exists, but not its definition\n", result_name); return false; } - if (log) - log->Printf("Found result in the IR: \"%s\"", - PrintValue(result_value, false).c_str()); + LLDB_LOG(log, "Found result in the IR: \"{0}\"", + PrintValue(result_value, false)); GlobalVariable *result_global = dyn_cast<GlobalVariable>(result_value); if (!result_global) { - if (log) - log->PutCString("Result variable isn't a GlobalVariable"); + LLDB_LOG(log, "Result variable isn't a GlobalVariable"); - m_error_stream.Printf("Internal error [IRForTarget]: Result variable (%s) " + m_error_stream.Format("Internal error [IRForTarget]: Result variable ({0}) " "is defined, but is not a global variable\n", result_name); @@ -230,10 +235,9 @@ bool IRForTarget::CreateResultVariable(llvm::Function &llvm_function) { clang::NamedDecl *result_decl = DeclForGlobal(result_global); if (!result_decl) { - if (log) - log->PutCString("Result variable doesn't have a corresponding Decl"); + LLDB_LOG(log, "Result variable doesn't have a corresponding Decl"); - m_error_stream.Printf("Internal error [IRForTarget]: Result variable (%s) " + m_error_stream.Format("Internal error [IRForTarget]: Result variable ({0}) " "does not have a corresponding Clang entity\n", result_name); @@ -246,16 +250,15 @@ bool IRForTarget::CreateResultVariable(llvm::Function &llvm_function) { result_decl->print(decl_desc_stream); decl_desc_stream.flush(); - log->Printf("Found result decl: \"%s\"", decl_desc_str.c_str()); + LLDB_LOG(log, "Found result decl: \"{0}\"", decl_desc_str); } clang::VarDecl *result_var = dyn_cast<clang::VarDecl>(result_decl); if (!result_var) { - if (log) - log->PutCString("Result variable Decl isn't a VarDecl"); + LLDB_LOG(log, "Result variable Decl isn't a VarDecl"); - m_error_stream.Printf("Internal error [IRForTarget]: Result variable " - "(%s)'s corresponding Clang entity isn't a " + m_error_stream.Format("Internal error [IRForTarget]: Result variable " + "({0})'s corresponding Clang entity isn't a " "variable\n", result_name); @@ -292,10 +295,9 @@ bool IRForTarget::CreateResultVariable(llvm::Function &llvm_function) { lldb_private::ClangASTContext::GetASTContext( &result_decl->getASTContext())); } else { - if (log) - log->PutCString("Expected result to have pointer type, but it did not"); + LLDB_LOG(log, "Expected result to have pointer type, but it did not"); - m_error_stream.Printf("Internal error [IRForTarget]: Lvalue result (%s) " + m_error_stream.Format("Internal error [IRForTarget]: Lvalue result ({0}) " "is not a pointer variable\n", result_name); @@ -316,8 +318,7 @@ bool IRForTarget::CreateResultVariable(llvm::Function &llvm_function) { lldb_private::StreamString type_desc_stream; m_result_type.DumpTypeDescription(&type_desc_stream); - if (log) - log->Printf("Result type has unknown size"); + LLDB_LOG(log, "Result type has unknown size"); m_error_stream.Printf("Error [IRForTarget]: Size of result type '%s' " "couldn't be determined\n", @@ -329,15 +330,13 @@ bool IRForTarget::CreateResultVariable(llvm::Function &llvm_function) { lldb_private::StreamString type_desc_stream; m_result_type.DumpTypeDescription(&type_desc_stream); - log->Printf("Result decl type: \"%s\"", type_desc_stream.GetData()); + LLDB_LOG(log, "Result decl type: \"{0}\"", type_desc_stream.GetData()); } m_result_name = lldb_private::ConstString("$RESULT_NAME"); - if (log) - log->Printf("Creating a new result global: \"%s\" with size 0x%" PRIx64, - m_result_name.GetCString(), - m_result_type.GetByteSize(nullptr).getValueOr(0)); + LLDB_LOG(log, "Creating a new result global: \"{0}\" with size {1}", + m_result_name, m_result_type.GetByteSize(nullptr).getValueOr(0)); // Construct a new result global and set up its metadata @@ -369,10 +368,8 @@ bool IRForTarget::CreateResultVariable(llvm::Function &llvm_function) { m_module->getNamedMetadata("clang.global.decl.ptrs"); named_metadata->addOperand(persistent_global_md); - if (log) - log->Printf("Replacing \"%s\" with \"%s\"", - PrintValue(result_global).c_str(), - PrintValue(new_result_global).c_str()); + LLDB_LOG(log, "Replacing \"{0}\" with \"{1}\"", PrintValue(result_global), + PrintValue(new_result_global)); if (result_global->use_empty()) { // We need to synthesize a store for this variable, because otherwise @@ -385,11 +382,10 @@ bool IRForTarget::CreateResultVariable(llvm::Function &llvm_function) { return false; if (!result_global->hasInitializer()) { - if (log) - log->Printf("Couldn't find initializer for unused variable"); + LLDB_LOG(log, "Couldn't find initializer for unused variable"); - m_error_stream.Printf("Internal error [IRForTarget]: Result variable " - "(%s) has no writes and no initializer\n", + m_error_stream.Format("Internal error [IRForTarget]: Result variable " + "({0}) has no writes and no initializer\n", result_name); return false; @@ -400,9 +396,8 @@ bool IRForTarget::CreateResultVariable(llvm::Function &llvm_function) { StoreInst *synthesized_store = new StoreInst(initializer, new_result_global, first_entry_instruction); - if (log) - log->Printf("Synthesized result store \"%s\"\n", - PrintValue(synthesized_store).c_str()); + LLDB_LOG(log, "Synthesized result store \"{0}\"\n", + PrintValue(synthesized_store)); } else { result_global->replaceAllUsesWith(new_result_global); } @@ -438,7 +433,6 @@ bool IRForTarget::RewriteObjCConstString(llvm::GlobalVariable *ns_str, m_execution_unit.FindSymbol(g_CFStringCreateWithBytes_str, missing_weak); if (CFStringCreateWithBytes_addr == LLDB_INVALID_ADDRESS || missing_weak) { - if (log) log->PutCString("Couldn't find CFStringCreateWithBytes in the target"); m_error_stream.Printf("Error [IRForTarget]: Rewriting an Objective-C " @@ -448,9 +442,8 @@ bool IRForTarget::RewriteObjCConstString(llvm::GlobalVariable *ns_str, return false; } - if (log) - log->Printf("Found CFStringCreateWithBytes at 0x%" PRIx64, - CFStringCreateWithBytes_addr); + LLDB_LOG(log, "Found CFStringCreateWithBytes at {0}", + CFStringCreateWithBytes_addr); // Build the function type: // @@ -543,9 +536,7 @@ bool IRForTarget::RewriteObjCConstString(llvm::GlobalVariable *ns_str, 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"); + LLDB_LOG(log, "Couldn't replace the NSString with the result of the call"); m_error_stream.Printf("error [IRForTarget internal]: Couldn't replace an " "Objective-C constant string with a dynamic " @@ -565,21 +556,17 @@ bool IRForTarget::RewriteObjCConstStrings() { 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(); + for (StringMapEntry<llvm::Value *> &value_symbol : value_symbol_table) { + llvm::StringRef value_name = value_symbol.first(); - if (strstr(value_name_cstr, "_unnamed_cfstring_")) { - Value *nsstring_value = vi->second; + if (value_name.contains("_unnamed_cfstring_")) { + Value *nsstring_value = value_symbol.second; GlobalVariable *nsstring_global = dyn_cast<GlobalVariable>(nsstring_value); if (!nsstring_global) { - if (log) - log->PutCString("NSString variable is not a GlobalVariable"); + LLDB_LOG(log, "NSString variable is not a GlobalVariable"); m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C " "constant string is not a global variable\n"); @@ -588,8 +575,7 @@ bool IRForTarget::RewriteObjCConstStrings() { } if (!nsstring_global->hasInitializer()) { - if (log) - log->PutCString("NSString variable does not have an initializer"); + LLDB_LOG(log, "NSString variable does not have an initializer"); m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C " "constant string does not have an initializer\n"); @@ -601,9 +587,8 @@ bool IRForTarget::RewriteObjCConstStrings() { dyn_cast<ConstantStruct>(nsstring_global->getInitializer()); if (!nsstring_struct) { - if (log) - log->PutCString( - "NSString variable's initializer is not a ConstantStruct"); + LLDB_LOG(log, + "NSString variable's initializer is not a ConstantStruct"); m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C " "constant string is not a structure constant\n"); @@ -621,10 +606,11 @@ bool IRForTarget::RewriteObjCConstStrings() { // }; 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()); + + LLDB_LOG(log, + "NSString variable's initializer structure has an " + "unexpected number of members. Should be 4, is {0}", + nsstring_struct->getNumOperands()); m_error_stream.Printf("Internal error [IRForTarget]: The struct for an " "Objective-C constant string is not as " @@ -636,8 +622,7 @@ bool IRForTarget::RewriteObjCConstStrings() { Constant *nsstring_member = nsstring_struct->getOperand(2); if (!nsstring_member) { - if (log) - log->PutCString("NSString initializer's str element was empty"); + LLDB_LOG(log, "NSString initializer's str element was empty"); m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C " "constant string does not have a string " @@ -649,9 +634,8 @@ bool IRForTarget::RewriteObjCConstStrings() { ConstantExpr *nsstring_expr = dyn_cast<ConstantExpr>(nsstring_member); if (!nsstring_expr) { - if (log) - log->PutCString( - "NSString initializer's str element is not a ConstantExpr"); + LLDB_LOG(log, + "NSString initializer's str element is not a ConstantExpr"); m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C " "constant string's string initializer is not " @@ -671,9 +655,8 @@ bool IRForTarget::RewriteObjCConstStrings() { } if (!cstr_global) { - if (log) - log->PutCString( - "NSString initializer's str element is not a GlobalVariable"); + LLDB_LOG(log, + "NSString initializer's str element is not a GlobalVariable"); m_error_stream.Printf("Internal error [IRForTarget]: Unhandled" "constant string initializer\n"); @@ -682,9 +665,8 @@ bool IRForTarget::RewriteObjCConstStrings() { } if (!cstr_global->hasInitializer()) { - if (log) - log->PutCString("NSString initializer's str element does not have an " - "initializer"); + LLDB_LOG(log, "NSString initializer's str element does not have an " + "initializer"); m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C " "constant string's string initializer doesn't " @@ -726,21 +708,18 @@ bool IRForTarget::RewriteObjCConstStrings() { 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) + LLDB_LOG(log, "Found NSString constant {0}, which contains \"{1}\"", + value_name, cstr_array->getAsString()); + else + LLDB_LOG(log, "Found NSString constant {0}, which contains \"\"", + value_name); if (!cstr_array) cstr_global = nullptr; if (!RewriteObjCConstString(nsstring_global, cstr_global)) { - if (log) - log->PutCString("Error rewriting the constant string"); + LLDB_LOG(log, "Error rewriting the constant string"); // We don't print an error message here because RewriteObjCConstString // has done so for us. @@ -750,19 +729,15 @@ bool IRForTarget::RewriteObjCConstStrings() { } } - 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 (StringMapEntry<llvm::Value *> &value_symbol : value_symbol_table) { + llvm::StringRef value_name = value_symbol.first(); - if (!strcmp(value_name_cstr, "__CFConstantStringClassReference")) { - GlobalVariable *gv = dyn_cast<GlobalVariable>(vi->second); + if (value_name == "__CFConstantStringClassReference") { + GlobalVariable *gv = dyn_cast<GlobalVariable>(value_symbol.second); if (!gv) { - if (log) - log->PutCString( - "__CFConstantStringClassReference is not a global variable"); + LLDB_LOG(log, + "__CFConstantStringClassReference is not a global variable"); m_error_stream.Printf("Internal error [IRForTarget]: Found a " "CFConstantStringClassReference, but it is not a " @@ -850,9 +825,8 @@ bool IRForTarget::RewriteObjCSelector(Instruction *selector_load) { std::string omvn_initializer_string = omvn_initializer_array->getAsString(); - if (log) - log->Printf("Found Objective-C selector reference \"%s\"", - omvn_initializer_string.c_str()); + LLDB_LOG(log, "Found Objective-C selector reference \"{0}\"", + omvn_initializer_string); // Construct a call to sel_registerName @@ -866,9 +840,7 @@ bool IRForTarget::RewriteObjCSelector(Instruction *selector_load) { if (sel_registerName_addr == LLDB_INVALID_ADDRESS || missing_weak) return false; - if (log) - log->Printf("Found sel_registerName at 0x%" PRIx64, - sel_registerName_addr); + LLDB_LOG(log, "Found sel_registerName at {0}", sel_registerName_addr); // Build the function type: struct objc_selector // *sel_registerName(uint8_t*) @@ -921,32 +893,21 @@ bool IRForTarget::RewriteObjCSelectors(BasicBlock &basic_block) { lldb_private::Log *log( lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); - BasicBlock::iterator ii; - - typedef SmallVector<Instruction *, 2> InstrList; - typedef InstrList::iterator InstrIterator; - InstrList selector_loads; - for (ii = basic_block.begin(); ii != basic_block.end(); ++ii) { - Instruction &inst = *ii; - + for (Instruction &inst : basic_block) { if (LoadInst *load = dyn_cast<LoadInst>(&inst)) if (IsObjCSelectorRef(load->getPointerOperand())) selector_loads.push_back(&inst); } - InstrIterator iter; - - for (iter = selector_loads.begin(); iter != selector_loads.end(); ++iter) { - if (!RewriteObjCSelector(*iter)) { + for (Instruction *inst : selector_loads) { + if (!RewriteObjCSelector(inst)) { 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"); + LLDB_LOG(log, "Couldn't rewrite a reference to an Objective-C selector"); return false; } @@ -1022,9 +983,8 @@ bool IRForTarget::RewriteObjCClassReference(Instruction *class_load) { std::string ocn_initializer_string = ocn_initializer_array->getAsString(); - if (log) - log->Printf("Found Objective-C class reference \"%s\"", - ocn_initializer_string.c_str()); + LLDB_LOG(log, "Found Objective-C class reference \"{0}\"", + ocn_initializer_string); // Construct a call to objc_getClass @@ -1038,9 +998,7 @@ bool IRForTarget::RewriteObjCClassReference(Instruction *class_load) { if (objc_getClass_addr == LLDB_INVALID_ADDRESS || missing_weak) return false; - if (log) - log->Printf("Found objc_getClass at 0x%" PRIx64, - objc_getClass_addr); + LLDB_LOG(log, "Found objc_getClass at {0}", objc_getClass_addr); // Build the function type: %struct._objc_class *objc_getClass(i8*) @@ -1086,32 +1044,21 @@ bool IRForTarget::RewriteObjCClassReferences(BasicBlock &basic_block) { lldb_private::Log *log( lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); - BasicBlock::iterator ii; - - typedef SmallVector<Instruction *, 2> InstrList; - typedef InstrList::iterator InstrIterator; - InstrList class_loads; - for (ii = basic_block.begin(); ii != basic_block.end(); ++ii) { - Instruction &inst = *ii; - + for (Instruction &inst : basic_block) { if (LoadInst *load = dyn_cast<LoadInst>(&inst)) if (IsObjCClassReference(load->getPointerOperand())) class_loads.push_back(&inst); } - InstrIterator iter; - - for (iter = class_loads.begin(); iter != class_loads.end(); ++iter) { - if (!RewriteObjCClassReference(*iter)) { + for (Instruction *inst : class_loads) { + if (!RewriteObjCClassReference(inst)) { m_error_stream.Printf("Internal error [IRForTarget]: Couldn't change a " "static reference to an Objective-C class to a " "dynamic reference\n"); - if (log) - log->PutCString( - "Couldn't rewrite a reference to an Objective-C class"); + LLDB_LOG(log, "Couldn't rewrite a reference to an Objective-C class"); return false; } @@ -1180,9 +1127,8 @@ bool IRForTarget::RewritePersistentAlloc(llvm::Instruction *persistent_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()); + LLDB_LOG(log, "Replacing \"{0}\" with \"{1}\"", PrintValue(alloc), + PrintValue(persistent_load)); alloc->replaceAllUsesWith(persistent_load); alloc->eraseFromParent(); @@ -1197,23 +1143,16 @@ bool IRForTarget::RewritePersistentAllocs(llvm::BasicBlock &basic_block) { lldb_private::Log *log( lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); - BasicBlock::iterator ii; - - typedef SmallVector<Instruction *, 2> InstrList; - typedef InstrList::iterator InstrIterator; - InstrList pvar_allocs; - for (ii = basic_block.begin(); ii != basic_block.end(); ++ii) { - Instruction &inst = *ii; + for (Instruction &inst : basic_block) { 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."); + LLDB_LOG(log, "Rejecting a numeric persistent variable."); m_error_stream.Printf("Error [IRForTarget]: Names starting with $0, " "$1, ... are reserved for use as result " @@ -1227,16 +1166,12 @@ bool IRForTarget::RewritePersistentAllocs(llvm::BasicBlock &basic_block) { } } - InstrIterator iter; - - for (iter = pvar_allocs.begin(); iter != pvar_allocs.end(); ++iter) { - if (!RewritePersistentAlloc(*iter)) { + for (Instruction *inst : pvar_allocs) { + if (!RewritePersistentAlloc(inst)) { 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"); + LLDB_LOG(log, "Couldn't rewrite the creation of a persistent variable"); return false; } @@ -1245,79 +1180,12 @@ bool IRForTarget::RewritePersistentAllocs(llvm::BasicBlock &basic_block) { return true; } -bool IRForTarget::MaterializeInitializer(uint8_t *data, Constant *initializer) { - if (!initializer) - return true; - - lldb_private::Log *log( - lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); - - if (log && log->GetVerbose()) - log->Printf(" MaterializeInitializer(%p, %s)", (void *)data, - PrintValue(initializer).c_str()); - - 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); - - lldb_private::Status get_data_error; - return scalar.GetAsMemoryData(data, constant_size, - lldb_private::endian::InlHostByteOrder(), - get_data_error) != 0; - } 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; - } 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()); + LLDB_LOG(log, "MaybeHandleVariable ({0})", PrintValue(llvm_value_ptr)); if (ConstantExpr *constant_expr = dyn_cast<ConstantExpr>(llvm_value_ptr)) { switch (constant_expr->getOpcode()) { @@ -1343,25 +1211,26 @@ bool IRForTarget::MaybeHandleVariable(Value *llvm_value_ptr) { if (!global_variable->hasExternalLinkage()) return true; - if (log) - log->Printf("Found global variable \"%s\" without metadata", - global_variable->getName().str().c_str()); + LLDB_LOG(log, "Found global variable \"{0}\" without metadata", + global_variable->getName()); return false; } - std::string name(named_decl->getName().str()); + llvm::StringRef name(named_decl->getName()); clang::ValueDecl *value_decl = dyn_cast<clang::ValueDecl>(named_decl); if (value_decl == nullptr) return false; - lldb_private::CompilerType compiler_type(&value_decl->getASTContext(), - value_decl->getType()); + lldb_private::CompilerType compiler_type( + lldb_private::ClangASTContext::GetASTContext( + &value_decl->getASTContext()), + value_decl->getType().getAsOpaquePtr()); const Type *value_type = nullptr; - if (name[0] == '$') { + if (name.startswith("$")) { // 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 @@ -1381,31 +1250,24 @@ bool IRForTarget::MaybeHandleVariable(Value *llvm_value_ptr) { llvm::Optional<uint64_t> value_size = compiler_type.GetByteSize(nullptr); if (!value_size) return false; - 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); - } - - 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; - } + llvm::Optional<size_t> opt_alignment = compiler_type.GetTypeBitAlign(nullptr); + if (!opt_alignment) + return false; + lldb::offset_t value_alignment = (*opt_alignment + 7ull) / 8ull; + + LLDB_LOG(log, + "Type of \"{0}\" is [clang \"{1}\", llvm \"{2}\"] [size {3}, " + "align {4}]", + name, + lldb_private::ClangUtil::GetQualType(compiler_type).getAsString(), + PrintType(value_type), *value_size, value_alignment); + + if (named_decl) + m_decl_map->AddValueToStruct(named_decl, lldb_private::ConstString(name), + llvm_value_ptr, *value_size, + value_alignment); } else if (dyn_cast<llvm::Function>(llvm_value_ptr)) { - if (log) - log->Printf("Function pointers aren't handled right now"); + LLDB_LOG(log, "Function pointers aren't handled right now"); return false; } @@ -1424,14 +1286,12 @@ bool IRForTarget::HandleSymbol(Value *symbol) { m_decl_map->GetSymbolAddress(name, lldb::eSymbolTypeAny); if (symbol_addr == LLDB_INVALID_ADDRESS) { - if (log) - log->Printf("Symbol \"%s\" had no address", name.GetCString()); + LLDB_LOG(log, "Symbol \"{0}\" had no address", name); return false; } - if (log) - log->Printf("Found \"%s\" at 0x%" PRIx64, name.GetCString(), symbol_addr); + LLDB_LOG(log, "Found \"{0}\" at {1}", name, symbol_addr); Type *symbol_type = symbol->getType(); @@ -1440,9 +1300,8 @@ bool IRForTarget::HandleSymbol(Value *symbol) { 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()); + LLDB_LOG(log, "Replacing {0} with {1}", PrintValue(symbol), + PrintValue(symbol_addr_ptr)); symbol->replaceAllUsesWith(symbol_addr_ptr); @@ -1453,14 +1312,12 @@ 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()); + LLDB_LOG(log, "MaybeHandleCallArguments({0})", PrintValue(Old)); 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 - { + // conservatively believe that this is a store + if (!MaybeHandleVariable(Old->getArgOperand(op_index))) { m_error_stream.Printf("Internal error [IRForTarget]: Couldn't rewrite " "one of the arguments of a function call.\n"); @@ -1493,9 +1350,8 @@ bool IRForTarget::HandleObjCClass(Value *classlist_reference) { 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); + LLDB_LOG(log, "Found reference to Objective-C class {0} ({1})", name, + (unsigned long long)class_ptr); if (class_ptr == LLDB_INVALID_ADDRESS) return false; @@ -1528,13 +1384,9 @@ bool IRForTarget::HandleObjCClass(Value *classlist_reference) { } bool IRForTarget::RemoveCXAAtExit(BasicBlock &basic_block) { - BasicBlock::iterator ii; - std::vector<CallInst *> calls_to_remove; - for (ii = basic_block.begin(); ii != basic_block.end(); ++ii) { - Instruction &inst = *ii; - + for (Instruction &inst : basic_block) { CallInst *call = dyn_cast<CallInst>(&inst); // MaybeHandleCallArguments handles error reporting; we are silent here @@ -1557,25 +1409,16 @@ bool IRForTarget::RemoveCXAAtExit(BasicBlock &basic_block) { 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 (CallInst *ci : calls_to_remove) + ci->eraseFromParent(); return true; } bool IRForTarget::ResolveCalls(BasicBlock &basic_block) { - ///////////////////////////////////////////////////////////////////////// // Prepare the current basic block for execution in the remote process - // - - BasicBlock::iterator ii; - - for (ii = basic_block.begin(); ii != basic_block.end(); ++ii) { - Instruction &inst = *ii; + for (Instruction &inst : basic_block) { CallInst *call = dyn_cast<CallInst>(&inst); // MaybeHandleCallArguments handles error reporting; we are silent here @@ -1591,31 +1434,27 @@ bool IRForTarget::ResolveExternals(Function &llvm_function) { lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); for (GlobalVariable &global_var : m_module->globals()) { - std::string global_name = global_var.getName().str(); + llvm::StringRef global_name = global_var.getName(); - if (log) - log->Printf("Examining %s, DeclForGlobalValue returns %p", - global_name.c_str(), - static_cast<void *>(DeclForGlobal(&global_var))); + LLDB_LOG(log, "Examining {0}, DeclForGlobalValue returns {1}", global_name, + static_cast<void *>(DeclForGlobal(&global_var))); - if (global_name.find("OBJC_IVAR") == 0) { + if (global_name.startswith("OBJC_IVAR")) { if (!HandleSymbol(&global_var)) { - m_error_stream.Printf("Error [IRForTarget]: Couldn't find Objective-C " - "indirect ivar symbol %s\n", - global_name.c_str()); + m_error_stream.Format("Error [IRForTarget]: Couldn't find Objective-C " + "indirect ivar symbol {0}\n", + global_name); return false; } - } else if (global_name.find("OBJC_CLASSLIST_REFERENCES_$") != - global_name.npos) { + } else if (global_name.contains("OBJC_CLASSLIST_REFERENCES_$")) { 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) { + } else if (global_name.contains("OBJC_CLASSLIST_SUP_REFS_$")) { if (!HandleObjCClass(&global_var)) { m_error_stream.Printf("Error [IRForTarget]: Couldn't resolve the class " "for an Objective-C static method call\n"); @@ -1624,9 +1463,9 @@ bool IRForTarget::ResolveExternals(Function &llvm_function) { } } 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()); + m_error_stream.Format("Internal error [IRForTarget]: Couldn't rewrite " + "external variable {0}\n", + global_name); return false; } @@ -1637,14 +1476,12 @@ bool IRForTarget::ResolveExternals(Function &llvm_function) { } static bool isGuardVariableRef(Value *V) { - Constant *Old = nullptr; + Constant *Old = dyn_cast<Constant>(V); - if (!(Old = dyn_cast<Constant>(V))) + if (!Old) return false; - ConstantExpr *CE = nullptr; - - if ((CE = dyn_cast<ConstantExpr>(V))) { + if (auto CE = dyn_cast<ConstantExpr>(V)) { if (CE->getOpcode() != Instruction::BitCast) return false; @@ -1653,12 +1490,8 @@ static bool isGuardVariableRef(Value *V) { 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 - { + if (!GV || !GV->hasName() || !isGuardVariableSymbol(GV->getName())) return false; - } return true; } @@ -1674,20 +1507,12 @@ static void ExciseGuardStore(Instruction *guard_store) { } bool IRForTarget::RemoveGuards(BasicBlock &basic_block) { - /////////////////////////////////////////////////////// // Eliminate any reference to guard variables found. - // - - BasicBlock::iterator ii; - - typedef SmallVector<Instruction *, 2> InstrList; - typedef InstrList::iterator InstrIterator; InstrList guard_loads; InstrList guard_stores; - for (ii = basic_block.begin(); ii != basic_block.end(); ++ii) { - Instruction &inst = *ii; + for (Instruction &inst : basic_block) { if (LoadInst *load = dyn_cast<LoadInst>(&inst)) if (isGuardVariableRef(load->getPointerOperand())) @@ -1698,13 +1523,11 @@ bool IRForTarget::RemoveGuards(BasicBlock &basic_block) { guard_stores.push_back(&inst); } - InstrIterator iter; + for (Instruction *inst : guard_loads) + TurnGuardLoadIntoZero(inst); - 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 (Instruction *inst : guard_stores) + ExciseGuardStore(inst); return true; } @@ -1837,8 +1660,7 @@ bool IRForTarget::ReplaceVariables(Function &llvm_function) { m_decl_map->DoStructLayout(); - if (log) - log->Printf("Element arrangement:"); + LLDB_LOG(log, "Element arrangement:"); uint32_t num_elements; uint32_t element_index; @@ -1884,9 +1706,9 @@ bool IRForTarget::ReplaceVariables(Function &llvm_function) { } if (!iter->getName().equals("_cmd")) { - m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes '%s' " + m_error_stream.Format("Internal error [IRForTarget]: Wrapper takes '{0}' " "after 'self' argument (should take '_cmd')", - iter->getName().str().c_str()); + iter->getName()); return false; } @@ -1905,15 +1727,14 @@ bool IRForTarget::ReplaceVariables(Function &llvm_function) { } 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()); + m_error_stream.Format("Internal error [IRForTarget]: Wrapper takes an " + "argument named '{0}' instead of the struct pointer", + argument->getName()); return false; } - if (log) - log->Printf("Arg: \"%s\"", PrintValue(argument).c_str()); + LLDB_LOG(log, "Arg: \"{0}\"", PrintValue(argument)); BasicBlock &entry_block(llvm_function.getEntryBlock()); Instruction *FirstEntryInstruction(entry_block.getFirstNonPHIOrDbg()); @@ -1950,13 +1771,11 @@ bool IRForTarget::ReplaceVariables(Function &llvm_function) { return false; } - if (log) - log->Printf(" \"%s\" (\"%s\") placed at %" PRIu64, name.GetCString(), - decl->getNameAsString().c_str(), offset); + LLDB_LOG(log, " \"{0}\" (\"{1}\") placed at {2}", name, + decl->getNameAsString(), offset); if (value) { - if (log) - log->Printf(" Replacing [%s]", PrintValue(value).c_str()); + LLDB_LOG(log, " Replacing [{0}]", PrintValue(value)); FunctionValueCache body_result_maker( [this, name, offset_type, offset, argument, @@ -2005,9 +1824,8 @@ bool IRForTarget::ReplaceVariables(Function &llvm_function) { value->replaceAllUsesWith( body_result_maker.GetValue(instruction->getParent()->getParent())); } else { - if (log) - log->Printf("Unhandled non-constant type: \"%s\"", - PrintValue(value).c_str()); + LLDB_LOG(log, "Unhandled non-constant type: \"{0}\"", + PrintValue(value)); return false; } @@ -2016,35 +1834,12 @@ bool IRForTarget::ReplaceVariables(Function &llvm_function) { } } - if (log) - log->Printf("Total structure [align %" PRId64 ", size %" PRIu64 "]", - (int64_t)alignment, (uint64_t)size); + LLDB_LOG(log, "Total structure [align {0}, size {1}]", (int64_t)alignment, + (uint64_t)size); return true; } -llvm::Constant *IRForTarget::BuildRelocation(llvm::Type *type, - uint64_t offset) { - llvm::Constant *offset_int = ConstantInt::get(m_intptr_ty, offset); - - llvm::Constant *offset_array[1]; - - offset_array[0] = offset_int; - - llvm::ArrayRef<llvm::Constant *> offsets(offset_array, 1); - llvm::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); - - return reloc_bitcast; -} - bool IRForTarget::runOnModule(Module &llvm_module) { lldb_private::Log *log( lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); @@ -2062,7 +1857,7 @@ bool IRForTarget::runOnModule(Module &llvm_module) { oss.flush(); - log->Printf("Module as passed in to IRForTarget: \n\"%s\"", s.c_str()); + LLDB_LOG(log, "Module as passed in to IRForTarget: \n\"{0}\"", s); } Function *const main_function = @@ -2070,21 +1865,18 @@ bool IRForTarget::runOnModule(Module &llvm_module) { : 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()); + LLDB_LOG(log, "Couldn't find \"{0}()\" in the module", m_func_name); - m_error_stream.Printf("Internal error [IRForTarget]: Couldn't find wrapper " - "'%s' in the module", - m_func_name.AsCString()); + m_error_stream.Format("Internal error [IRForTarget]: Couldn't find wrapper " + "'{0}' in the module", + m_func_name); return false; } if (main_function) { if (!FixFunctionLinkage(*main_function)) { - if (log) - log->Printf("Couldn't fix the linkage for the function"); + LLDB_LOG(log, "Couldn't fix the linkage for the function"); return false; } @@ -2104,8 +1896,7 @@ bool IRForTarget::runOnModule(Module &llvm_module) { if (main_function) { if (!CreateResultVariable(*main_function)) { - if (log) - log->Printf("CreateResultVariable() failed"); + LLDB_LOG(log, "CreateResultVariable() failed"); // CreateResultVariable() reports its own errors, so we don't do so here @@ -2121,32 +1912,21 @@ bool IRForTarget::runOnModule(Module &llvm_module) { oss.flush(); - log->Printf("Module after creating the result variable: \n\"%s\"", - s.c_str()); + LLDB_LOG(log, "Module after creating the result variable: \n\"{0}\"", s); } - for (Module::iterator fi = m_module->begin(), fe = m_module->end(); fi != fe; - ++fi) { - llvm::Function *function = &*fi; - - if (function->begin() == function->end()) - continue; - - Function::iterator bbi; - - for (bbi = function->begin(); bbi != function->end(); ++bbi) { - if (!RemoveGuards(*bbi)) { - if (log) - log->Printf("RemoveGuards() failed"); + for (llvm::Function &function : *m_module) { + for (BasicBlock &bb : function) { + if (!RemoveGuards(bb)) { + LLDB_LOG(log, "RemoveGuards() failed"); // RemoveGuards() reports its own errors, so we don't do so here return false; } - if (!RewritePersistentAllocs(*bbi)) { - if (log) - log->Printf("RewritePersistentAllocs() failed"); + if (!RewritePersistentAllocs(bb)) { + LLDB_LOG(log, "RewritePersistentAllocs() failed"); // RewritePersistentAllocs() reports its own errors, so we don't do so // here @@ -2154,9 +1934,8 @@ bool IRForTarget::runOnModule(Module &llvm_module) { return false; } - if (!RemoveCXAAtExit(*bbi)) { - if (log) - log->Printf("RemoveCXAAtExit() failed"); + if (!RemoveCXAAtExit(bb)) { + LLDB_LOG(log, "RemoveCXAAtExit() failed"); // RemoveCXAAtExit() reports its own errors, so we don't do so here @@ -2170,24 +1949,17 @@ bool IRForTarget::runOnModule(Module &llvm_module) { // if (!RewriteObjCConstStrings()) { - if (log) - log->Printf("RewriteObjCConstStrings() failed"); + LLDB_LOG(log, "RewriteObjCConstStrings() failed"); // RewriteObjCConstStrings() reports its own errors, so we don't do so here return false; } - for (Module::iterator fi = m_module->begin(), fe = m_module->end(); fi != fe; - ++fi) { - 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 &function : *m_module) { + for (llvm::BasicBlock &bb : function) { + if (!RewriteObjCSelectors(bb)) { + LLDB_LOG(log, "RewriteObjCSelectors() failed"); // RewriteObjCSelectors() reports its own errors, so we don't do so // here @@ -2195,9 +1967,8 @@ bool IRForTarget::runOnModule(Module &llvm_module) { return false; } - if (!RewriteObjCClassReferences(*bbi)) { - if (log) - log->Printf("RewriteObjCClassReferences() failed"); + if (!RewriteObjCClassReferences(bb)) { + LLDB_LOG(log, "RewriteObjCClassReferences() failed"); // RewriteObjCClasses() reports its own errors, so we don't do so here @@ -2206,16 +1977,10 @@ bool IRForTarget::runOnModule(Module &llvm_module) { } } - 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 &function : *m_module) { + for (BasicBlock &bb : function) { + if (!ResolveCalls(bb)) { + LLDB_LOG(log, "ResolveCalls() failed"); // ResolveCalls() reports its own errors, so we don't do so here @@ -2230,8 +1995,7 @@ bool IRForTarget::runOnModule(Module &llvm_module) { if (main_function) { if (!ResolveExternals(*main_function)) { - if (log) - log->Printf("ResolveExternals() failed"); + LLDB_LOG(log, "ResolveExternals() failed"); // ResolveExternals() reports its own errors, so we don't do so here @@ -2239,8 +2003,7 @@ bool IRForTarget::runOnModule(Module &llvm_module) { } if (!ReplaceVariables(*main_function)) { - if (log) - log->Printf("ReplaceVariables() failed"); + LLDB_LOG(log, "ReplaceVariables() failed"); // ReplaceVariables() reports its own errors, so we don't do so here @@ -2256,7 +2019,7 @@ bool IRForTarget::runOnModule(Module &llvm_module) { oss.flush(); - log->Printf("Module after preparing for execution: \n\"%s\"", s.c_str()); + LLDB_LOG(log, "Module after preparing for execution: \n\"{0}\"", s); } return true; diff --git a/source/Plugins/ExpressionParser/Clang/IRForTarget.h b/source/Plugins/ExpressionParser/Clang/IRForTarget.h index f87fd8ac32cb..893620f7f8e0 100644 --- a/source/Plugins/ExpressionParser/Clang/IRForTarget.h +++ b/source/Plugins/ExpressionParser/Clang/IRForTarget.h @@ -10,6 +10,7 @@ #ifndef liblldb_IRForTarget_h_ #define liblldb_IRForTarget_h_ +#include "lldb/Core/ClangForward.h" #include "lldb/Symbol/TaggedASTType.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/Status.h" @@ -331,27 +332,6 @@ private: /// 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 @@ -539,20 +519,6 @@ private: 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. /// diff --git a/source/Plugins/ExpressionParser/Clang/ModuleDependencyCollector.h b/source/Plugins/ExpressionParser/Clang/ModuleDependencyCollector.h index 0e959f86fd2a..7553860f2492 100644 --- a/source/Plugins/ExpressionParser/Clang/ModuleDependencyCollector.h +++ b/source/Plugins/ExpressionParser/Clang/ModuleDependencyCollector.h @@ -9,21 +9,23 @@ #ifndef liblldb_ModuleDependencyCollector_h_ #define liblldb_ModuleDependencyCollector_h_ -#include "lldb/Utility/FileCollector.h" #include "clang/Frontend/Utils.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Support/FileCollector.h" namespace lldb_private { class ModuleDependencyCollectorAdaptor : public clang::ModuleDependencyCollector { public: - ModuleDependencyCollectorAdaptor(FileCollector &file_collector) + ModuleDependencyCollectorAdaptor( + std::shared_ptr<llvm::FileCollector> file_collector) : clang::ModuleDependencyCollector(""), m_file_collector(file_collector) { } void addFile(llvm::StringRef Filename, llvm::StringRef FileDst = {}) override { - m_file_collector.AddFile(Filename); + if (m_file_collector) + m_file_collector->addFile(Filename); } bool insertSeen(llvm::StringRef Filename) override { return false; } @@ -31,7 +33,7 @@ public: void writeFileMap() override {} private: - FileCollector &m_file_collector; + std::shared_ptr<llvm::FileCollector> m_file_collector; }; } // namespace lldb_private |