diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2020-01-17 20:45:01 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2020-01-17 20:45:01 +0000 |
commit | 706b4fc47bbc608932d3b491ae19a3b9cde9497b (patch) | |
tree | 4adf86a776049cbf7f69a1929c4babcbbef925eb /lldb/source/Symbol | |
parent | 7cc9cf2bf09f069cb2dd947ead05d0b54301fb71 (diff) |
Vendor import of llvm-project master e26a78e70, the last commit beforevendor/llvm-project/llvmorg-10-init-17466-ge26a78e7085
the llvmorg-11-init tag, from which release/10.x was branched.
Diffstat (limited to 'lldb/source/Symbol')
26 files changed, 1593 insertions, 2979 deletions
diff --git a/lldb/source/Symbol/Block.cpp b/lldb/source/Symbol/Block.cpp index 77a4830dea7c..bf380064200a 100644 --- a/lldb/source/Symbol/Block.cpp +++ b/lldb/source/Symbol/Block.cpp @@ -44,8 +44,8 @@ void Block::GetDescription(Stream *s, Function *function, s->Printf(", range%s = ", num_ranges > 1 ? "s" : ""); for (size_t i = 0; i < num_ranges; ++i) { const Range &range = m_ranges.GetEntryRef(i); - s->AddressRange(base_addr + range.GetRangeBase(), - base_addr + range.GetRangeEnd(), 4); + DumpAddressRange(s->AsRawOstream(), base_addr + range.GetRangeBase(), + base_addr + range.GetRangeEnd(), 4); } } @@ -87,8 +87,8 @@ void Block::Dump(Stream *s, addr_t base_addr, int32_t depth, *s << '!'; else *s << ' '; - s->AddressRange(base_addr + range.GetRangeBase(), - base_addr + range.GetRangeEnd(), 4); + DumpAddressRange(s->AsRawOstream(), base_addr + range.GetRangeBase(), + base_addr + range.GetRangeEnd(), 4); } } s->EOL(); @@ -160,8 +160,8 @@ void Block::DumpAddressRanges(Stream *s, lldb::addr_t base_addr) { size_t num_ranges = m_ranges.GetSize(); for (size_t i = 0; i < num_ranges; ++i) { const Range &range = m_ranges.GetEntryRef(i); - s->AddressRange(base_addr + range.GetRangeBase(), - base_addr + range.GetRangeEnd(), 4); + DumpAddressRange(s->AsRawOstream(), base_addr + range.GetRangeBase(), + base_addr + range.GetRangeEnd(), 4); } } } @@ -406,11 +406,10 @@ Block::AppendBlockVariables(bool can_create, bool get_child_block_variables, uint32_t num_variables_added = 0; VariableList *block_var_list = GetBlockVariableList(can_create).get(); if (block_var_list) { - for (size_t i = 0; i < block_var_list->GetSize(); ++i) { - VariableSP variable = block_var_list->GetVariableAtIndex(i); - if (filter(variable.get())) { + for (const VariableSP &var_sp : *block_var_list) { + if (filter(var_sp.get())) { num_variables_added++; - variable_list->AddVariable(variable); + variable_list->AddVariable(var_sp); } } } diff --git a/lldb/source/Symbol/ClangASTContext.cpp b/lldb/source/Symbol/ClangASTContext.cpp index 565b15a007da..ac3bce179d9e 100644 --- a/lldb/source/Symbol/ClangASTContext.cpp +++ b/lldb/source/Symbol/ClangASTContext.cpp @@ -15,24 +15,6 @@ #include <string> #include <vector> - -// Clang headers like to use NDEBUG inside of them to enable/disable debug -// related features using "#ifndef NDEBUG" preprocessor blocks to do one thing -// or another. This is bad because it means that if clang was built in release -// mode, it assumes that you are building in release mode which is not always -// the case. You can end up with functions that are defined as empty in header -// files when NDEBUG is not defined, and this can cause link errors with the -// clang .a files that you have since you might be missing functions in the .a -// file. So we have to define NDEBUG when including clang headers to avoid any -// mismatches. This is covered by rdar://problem/8691220 - -#if !defined(NDEBUG) && !defined(LLVM_NDEBUG_OFF) -#define LLDB_DEFINED_NDEBUG_FOR_CLANG -#define NDEBUG -// Need to include assert.h so it is as clang would expect it to be (disabled) -#include <assert.h> -#endif - #include "clang/AST/ASTContext.h" #include "clang/AST/ASTImporter.h" #include "clang/AST/Attr.h" @@ -54,13 +36,6 @@ #include "clang/Frontend/FrontendOptions.h" #include "clang/Sema/Sema.h" -#ifdef LLDB_DEFINED_NDEBUG_FOR_CLANG -#undef NDEBUG -#undef LLDB_DEFINED_NDEBUG_FOR_CLANG -// Need to re-include assert.h so it is as _we_ would expect it to be (enabled) -#include <assert.h> -#endif - #include "llvm/Support/Signals.h" #include "llvm/Support/Threading.h" @@ -78,8 +53,8 @@ #include "lldb/Core/ThreadSafeDenseMap.h" #include "lldb/Core/UniqueCStringMap.h" #include "lldb/Symbol/ClangASTImporter.h" +#include "lldb/Symbol/ClangASTMetadata.h" #include "lldb/Symbol/ClangExternalASTSourceCallbacks.h" -#include "lldb/Symbol/ClangExternalASTSourceCommon.h" #include "lldb/Symbol/ClangUtil.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Symbol/SymbolFile.h" @@ -337,6 +312,8 @@ static ClangASTMap &GetASTMap() { return *g_map_ptr; } +char ClangASTContext::ID; + bool ClangASTContext::IsOperator(llvm::StringRef name, clang::OverloadedOperatorKind &op_kind) { // All operators have to start with "operator". @@ -522,25 +499,15 @@ static void ParseLangArgs(LangOptions &Opts, InputKind IK, const char *triple) { Opts.NoInlineDefine = !Opt; } -ClangASTContext::ClangASTContext(llvm::StringRef target_triple) - : TypeSystem(TypeSystem::eKindClang) { - if (!target_triple.empty()) - SetTargetTriple(target_triple); - // The caller didn't pass an ASTContext so create a new one for this - // ClangASTContext. - CreateASTContext(); -} - -ClangASTContext::ClangASTContext(ArchSpec arch) - : TypeSystem(TypeSystem::eKindClang) { - SetTargetTriple(arch.GetTriple().str()); +ClangASTContext::ClangASTContext(llvm::Triple target_triple) { + if (!target_triple.str().empty()) + SetTargetTriple(target_triple.str()); // The caller didn't pass an ASTContext so create a new one for this // ClangASTContext. CreateASTContext(); } -ClangASTContext::ClangASTContext(ASTContext &existing_ctxt) - : TypeSystem(TypeSystem::eKindClang) { +ClangASTContext::ClangASTContext(ASTContext &existing_ctxt) { SetTargetTriple(existing_ctxt.getTargetInfo().getTriple().str()); m_ast_up.reset(&existing_ctxt); @@ -563,48 +530,36 @@ uint32_t ClangASTContext::GetPluginVersion() { return 1; } lldb::TypeSystemSP ClangASTContext::CreateInstance(lldb::LanguageType language, lldb_private::Module *module, Target *target) { - if (ClangASTContextSupportsLanguage(language)) { - ArchSpec arch; - if (module) - arch = module->GetArchitecture(); - else if (target) - arch = target->GetArchitecture(); - - if (arch.IsValid()) { - ArchSpec fixed_arch = arch; - // LLVM wants this to be set to iOS or MacOSX; if we're working on - // a bare-boards type image, change the triple for llvm's benefit. - if (fixed_arch.GetTriple().getVendor() == llvm::Triple::Apple && - fixed_arch.GetTriple().getOS() == llvm::Triple::UnknownOS) { - if (fixed_arch.GetTriple().getArch() == llvm::Triple::arm || - fixed_arch.GetTriple().getArch() == llvm::Triple::aarch64 || - fixed_arch.GetTriple().getArch() == llvm::Triple::aarch64_32 || - fixed_arch.GetTriple().getArch() == llvm::Triple::thumb) { - fixed_arch.GetTriple().setOS(llvm::Triple::IOS); - } else { - fixed_arch.GetTriple().setOS(llvm::Triple::MacOSX); - } - } - - if (module) { - std::shared_ptr<ClangASTContext> ast_sp( - new ClangASTContext(fixed_arch)); - return ast_sp; - } else if (target && target->IsValid()) { - std::shared_ptr<ClangASTContextForExpressions> ast_sp( - new ClangASTContextForExpressions(*target, fixed_arch)); - ast_sp->m_scratch_ast_source_up.reset( - new ClangASTSource(target->shared_from_this())); - lldbassert(ast_sp->getFileManager()); - ast_sp->m_scratch_ast_source_up->InstallASTContext( - *ast_sp->getASTContext(), *ast_sp->getFileManager(), true); - llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> proxy_ast_source( - ast_sp->m_scratch_ast_source_up->CreateProxy()); - ast_sp->SetExternalSource(proxy_ast_source); - return ast_sp; - } + if (!ClangASTContextSupportsLanguage(language)) + return lldb::TypeSystemSP(); + ArchSpec arch; + if (module) + arch = module->GetArchitecture(); + else if (target) + arch = target->GetArchitecture(); + + if (!arch.IsValid()) + return lldb::TypeSystemSP(); + + llvm::Triple triple = arch.GetTriple(); + // LLVM wants this to be set to iOS or MacOSX; if we're working on + // a bare-boards type image, change the triple for llvm's benefit. + if (triple.getVendor() == llvm::Triple::Apple && + triple.getOS() == llvm::Triple::UnknownOS) { + if (triple.getArch() == llvm::Triple::arm || + triple.getArch() == llvm::Triple::aarch64 || + triple.getArch() == llvm::Triple::aarch64_32 || + triple.getArch() == llvm::Triple::thumb) { + triple.setOS(llvm::Triple::IOS); + } else { + triple.setOS(llvm::Triple::MacOSX); } } + + if (module) + return std::make_shared<ClangASTContext>(triple); + else if (target && target->IsValid()) + return std::make_shared<ClangASTContextForExpressions>(*target, triple); return lldb::TypeSystemSP(); } @@ -658,7 +613,6 @@ void ClangASTContext::Finalize() { m_diagnostics_engine_up.reset(); m_source_manager_up.reset(); m_language_options_up.reset(); - m_scratch_ast_source_up.reset(); } void ClangASTContext::setSema(Sema *s) { @@ -677,26 +631,70 @@ void ClangASTContext::SetTargetTriple(llvm::StringRef target_triple) { void ClangASTContext::SetExternalSource( llvm::IntrusiveRefCntPtr<ExternalASTSource> &ast_source_up) { - ASTContext *ast = getASTContext(); - if (ast) { - ast->setExternalSource(ast_source_up); - ast->getTranslationUnitDecl()->setHasExternalLexicalStorage(true); - } + ASTContext &ast = getASTContext(); + ast.setExternalSource(ast_source_up); + ast.getTranslationUnitDecl()->setHasExternalLexicalStorage(true); } -ASTContext *ClangASTContext::getASTContext() { +ASTContext &ClangASTContext::getASTContext() { assert(m_ast_up); - return m_ast_up.get(); + return *m_ast_up; } +class NullDiagnosticConsumer : public DiagnosticConsumer { +public: + NullDiagnosticConsumer() { + m_log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS); + } + + void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, + const clang::Diagnostic &info) override { + if (m_log) { + llvm::SmallVector<char, 32> diag_str(10); + info.FormatDiagnostic(diag_str); + diag_str.push_back('\0'); + LLDB_LOGF(m_log, "Compiler diagnostic: %s\n", diag_str.data()); + } + } + + DiagnosticConsumer *clone(DiagnosticsEngine &Diags) const { + return new NullDiagnosticConsumer(); + } + +private: + Log *m_log; +}; + void ClangASTContext::CreateASTContext() { assert(!m_ast_up); m_ast_owned = true; - m_ast_up.reset(new ASTContext(*getLanguageOptions(), *getSourceManager(), - *getIdentifierTable(), *getSelectorTable(), - *getBuiltinContext())); - m_ast_up->getDiagnostics().setClient(getDiagnosticConsumer(), false); + m_language_options_up.reset(new LangOptions()); + ParseLangArgs(*m_language_options_up, clang::Language::ObjCXX, + GetTargetTriple()); + + m_identifier_table_up.reset( + new IdentifierTable(*m_language_options_up, nullptr)); + m_builtins_up.reset(new Builtin::Context()); + + m_selector_table_up.reset(new SelectorTable()); + + clang::FileSystemOptions file_system_options; + m_file_manager_up.reset(new clang::FileManager( + file_system_options, FileSystem::Instance().GetVirtualFileSystem())); + + llvm::IntrusiveRefCntPtr<DiagnosticIDs> diag_id_sp(new DiagnosticIDs()); + m_diagnostics_engine_up.reset( + new DiagnosticsEngine(diag_id_sp, new DiagnosticOptions())); + + m_source_manager_up.reset( + new clang::SourceManager(*m_diagnostics_engine_up, *m_file_manager_up)); + m_ast_up.reset(new ASTContext(*m_language_options_up, *m_source_manager_up, + *m_identifier_table_up, *m_selector_table_up, + *m_builtins_up)); + + m_diagnostic_consumer_up.reset(new NullDiagnosticConsumer); + m_ast_up->getDiagnostics().setClient(m_diagnostic_consumer_up.get(), false); // This can be NULL if we don't know anything about the architecture or if // the target for an architecture isn't enabled in the llvm/clang that we @@ -705,18 +703,10 @@ void ClangASTContext::CreateASTContext() { if (target_info) m_ast_up->InitBuiltinTypes(*target_info); - if ((m_callback_tag_decl || m_callback_objc_decl) && m_callback_baton) { - m_ast_up->getTranslationUnitDecl()->setHasExternalLexicalStorage(); - // m_ast_up->getTranslationUnitDecl()->setHasExternalVisibleStorage(); - } - GetASTMap().Insert(m_ast_up.get(), this); llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> ast_source_up( - new ClangExternalASTSourceCallbacks( - ClangASTContext::CompleteTagDecl, - ClangASTContext::CompleteObjCInterfaceDecl, nullptr, - ClangASTContext::LayoutRecordType, this)); + new ClangExternalASTSourceCallbacks(*this)); SetExternalSource(ast_source_up); } @@ -725,97 +715,12 @@ ClangASTContext *ClangASTContext::GetASTContext(clang::ASTContext *ast) { return clang_ast; } -Builtin::Context *ClangASTContext::getBuiltinContext() { - if (m_builtins_up == nullptr) - m_builtins_up.reset(new Builtin::Context()); - return m_builtins_up.get(); -} - -IdentifierTable *ClangASTContext::getIdentifierTable() { - if (m_identifier_table_up == nullptr) - m_identifier_table_up.reset( - new IdentifierTable(*ClangASTContext::getLanguageOptions(), nullptr)); - return m_identifier_table_up.get(); -} - -LangOptions *ClangASTContext::getLanguageOptions() { - if (m_language_options_up == nullptr) { - m_language_options_up.reset(new LangOptions()); - ParseLangArgs(*m_language_options_up, clang::Language::ObjCXX, - GetTargetTriple()); - // InitializeLangOptions(*m_language_options_up, Language::ObjCXX); - } - return m_language_options_up.get(); -} - -SelectorTable *ClangASTContext::getSelectorTable() { - if (m_selector_table_up == nullptr) - m_selector_table_up.reset(new SelectorTable()); - return m_selector_table_up.get(); -} - -clang::FileManager *ClangASTContext::getFileManager() { - if (m_file_manager_up == nullptr) { - clang::FileSystemOptions file_system_options; - m_file_manager_up.reset(new clang::FileManager( - file_system_options, FileSystem::Instance().GetVirtualFileSystem())); - } - return m_file_manager_up.get(); -} - -clang::SourceManager *ClangASTContext::getSourceManager() { - if (m_source_manager_up == nullptr) - m_source_manager_up.reset( - new clang::SourceManager(*getDiagnosticsEngine(), *getFileManager())); - return m_source_manager_up.get(); -} - -clang::DiagnosticsEngine *ClangASTContext::getDiagnosticsEngine() { - if (m_diagnostics_engine_up == nullptr) { - llvm::IntrusiveRefCntPtr<DiagnosticIDs> diag_id_sp(new DiagnosticIDs()); - m_diagnostics_engine_up.reset( - new DiagnosticsEngine(diag_id_sp, new DiagnosticOptions())); - } - return m_diagnostics_engine_up.get(); -} - clang::MangleContext *ClangASTContext::getMangleContext() { if (m_mangle_ctx_up == nullptr) - m_mangle_ctx_up.reset(getASTContext()->createMangleContext()); + m_mangle_ctx_up.reset(getASTContext().createMangleContext()); return m_mangle_ctx_up.get(); } -class NullDiagnosticConsumer : public DiagnosticConsumer { -public: - NullDiagnosticConsumer() { - m_log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS); - } - - void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, - const clang::Diagnostic &info) override { - if (m_log) { - llvm::SmallVector<char, 32> diag_str(10); - info.FormatDiagnostic(diag_str); - diag_str.push_back('\0'); - LLDB_LOGF(m_log, "Compiler diagnostic: %s\n", diag_str.data()); - } - } - - DiagnosticConsumer *clone(DiagnosticsEngine &Diags) const { - return new NullDiagnosticConsumer(); - } - -private: - Log *m_log; -}; - -DiagnosticConsumer *ClangASTContext::getDiagnosticConsumer() { - if (m_diagnostic_consumer_up == nullptr) - m_diagnostic_consumer_up.reset(new NullDiagnosticConsumer); - - return m_diagnostic_consumer_up.get(); -} - std::shared_ptr<clang::TargetOptions> &ClangASTContext::getTargetOptions() { if (m_target_options_rp == nullptr && !m_target_triple.empty()) { m_target_options_rp = std::make_shared<clang::TargetOptions>(); @@ -828,93 +733,74 @@ std::shared_ptr<clang::TargetOptions> &ClangASTContext::getTargetOptions() { TargetInfo *ClangASTContext::getTargetInfo() { // target_triple should be something like "x86_64-apple-macosx" if (m_target_info_up == nullptr && !m_target_triple.empty()) - m_target_info_up.reset(TargetInfo::CreateTargetInfo(*getDiagnosticsEngine(), - getTargetOptions())); + m_target_info_up.reset(TargetInfo::CreateTargetInfo( + getASTContext().getDiagnostics(), getTargetOptions())); return m_target_info_up.get(); } #pragma mark Basic Types static inline bool QualTypeMatchesBitSize(const uint64_t bit_size, - ASTContext *ast, QualType qual_type) { - uint64_t qual_type_bit_size = ast->getTypeSize(qual_type); + ASTContext &ast, QualType qual_type) { + uint64_t qual_type_bit_size = ast.getTypeSize(qual_type); return qual_type_bit_size == bit_size; } CompilerType ClangASTContext::GetBuiltinTypeForEncodingAndBitSize(Encoding encoding, size_t bit_size) { - return ClangASTContext::GetBuiltinTypeForEncodingAndBitSize( - getASTContext(), encoding, bit_size); -} - -CompilerType ClangASTContext::GetBuiltinTypeForEncodingAndBitSize( - ASTContext *ast, Encoding encoding, uint32_t bit_size) { - auto *clang_ast_context = ClangASTContext::GetASTContext(ast); - if (!ast) - return CompilerType(); + ASTContext &ast = getASTContext(); switch (encoding) { case eEncodingInvalid: - if (QualTypeMatchesBitSize(bit_size, ast, ast->VoidPtrTy)) - return CompilerType(clang_ast_context, ast->VoidPtrTy.getAsOpaquePtr()); + if (QualTypeMatchesBitSize(bit_size, ast, ast.VoidPtrTy)) + return GetType(ast.VoidPtrTy); break; case eEncodingUint: - if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedCharTy)) - return CompilerType(clang_ast_context, - ast->UnsignedCharTy.getAsOpaquePtr()); - if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedShortTy)) - return CompilerType(clang_ast_context, - ast->UnsignedShortTy.getAsOpaquePtr()); - if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedIntTy)) - return CompilerType(clang_ast_context, - ast->UnsignedIntTy.getAsOpaquePtr()); - if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedLongTy)) - return CompilerType(clang_ast_context, - ast->UnsignedLongTy.getAsOpaquePtr()); - if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedLongLongTy)) - return CompilerType(clang_ast_context, - ast->UnsignedLongLongTy.getAsOpaquePtr()); - if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedInt128Ty)) - return CompilerType(clang_ast_context, - ast->UnsignedInt128Ty.getAsOpaquePtr()); + if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedCharTy)) + return GetType(ast.UnsignedCharTy); + if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedShortTy)) + return GetType(ast.UnsignedShortTy); + if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedIntTy)) + return GetType(ast.UnsignedIntTy); + if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedLongTy)) + return GetType(ast.UnsignedLongTy); + if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedLongLongTy)) + return GetType(ast.UnsignedLongLongTy); + if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedInt128Ty)) + return GetType(ast.UnsignedInt128Ty); break; case eEncodingSint: - if (QualTypeMatchesBitSize(bit_size, ast, ast->SignedCharTy)) - return CompilerType(clang_ast_context, - ast->SignedCharTy.getAsOpaquePtr()); - if (QualTypeMatchesBitSize(bit_size, ast, ast->ShortTy)) - return CompilerType(clang_ast_context, ast->ShortTy.getAsOpaquePtr()); - if (QualTypeMatchesBitSize(bit_size, ast, ast->IntTy)) - return CompilerType(clang_ast_context, ast->IntTy.getAsOpaquePtr()); - if (QualTypeMatchesBitSize(bit_size, ast, ast->LongTy)) - return CompilerType(clang_ast_context, ast->LongTy.getAsOpaquePtr()); - if (QualTypeMatchesBitSize(bit_size, ast, ast->LongLongTy)) - return CompilerType(clang_ast_context, ast->LongLongTy.getAsOpaquePtr()); - if (QualTypeMatchesBitSize(bit_size, ast, ast->Int128Ty)) - return CompilerType(clang_ast_context, ast->Int128Ty.getAsOpaquePtr()); + if (QualTypeMatchesBitSize(bit_size, ast, ast.SignedCharTy)) + return GetType(ast.SignedCharTy); + if (QualTypeMatchesBitSize(bit_size, ast, ast.ShortTy)) + return GetType(ast.ShortTy); + if (QualTypeMatchesBitSize(bit_size, ast, ast.IntTy)) + return GetType(ast.IntTy); + if (QualTypeMatchesBitSize(bit_size, ast, ast.LongTy)) + return GetType(ast.LongTy); + if (QualTypeMatchesBitSize(bit_size, ast, ast.LongLongTy)) + return GetType(ast.LongLongTy); + if (QualTypeMatchesBitSize(bit_size, ast, ast.Int128Ty)) + return GetType(ast.Int128Ty); break; case eEncodingIEEE754: - if (QualTypeMatchesBitSize(bit_size, ast, ast->FloatTy)) - return CompilerType(clang_ast_context, ast->FloatTy.getAsOpaquePtr()); - if (QualTypeMatchesBitSize(bit_size, ast, ast->DoubleTy)) - return CompilerType(clang_ast_context, ast->DoubleTy.getAsOpaquePtr()); - if (QualTypeMatchesBitSize(bit_size, ast, ast->LongDoubleTy)) - return CompilerType(clang_ast_context, - ast->LongDoubleTy.getAsOpaquePtr()); - if (QualTypeMatchesBitSize(bit_size, ast, ast->HalfTy)) - return CompilerType(clang_ast_context, ast->HalfTy.getAsOpaquePtr()); + if (QualTypeMatchesBitSize(bit_size, ast, ast.FloatTy)) + return GetType(ast.FloatTy); + if (QualTypeMatchesBitSize(bit_size, ast, ast.DoubleTy)) + return GetType(ast.DoubleTy); + if (QualTypeMatchesBitSize(bit_size, ast, ast.LongDoubleTy)) + return GetType(ast.LongDoubleTy); + if (QualTypeMatchesBitSize(bit_size, ast, ast.HalfTy)) + return GetType(ast.HalfTy); break; case eEncodingVector: // Sanity check that bit_size is a multiple of 8's. if (bit_size && !(bit_size & 0x7u)) - return CompilerType( - clang_ast_context, - ast->getExtVectorType(ast->UnsignedCharTy, bit_size / 8) - .getAsOpaquePtr()); + return GetType(ast.getExtVectorType(ast.UnsignedCharTy, bit_size / 8)); break; } @@ -987,15 +873,6 @@ ClangASTContext::GetBasicTypeEnumeration(ConstString name) { return eBasicTypeInvalid; } -CompilerType ClangASTContext::GetBasicType(ASTContext *ast, - ConstString name) { - if (ast) { - lldb::BasicType basic_type = ClangASTContext::GetBasicTypeEnumeration(name); - return ClangASTContext::GetBasicType(ast, basic_type); - } - return CompilerType(); -} - uint32_t ClangASTContext::GetPointerByteSize() { if (m_pointer_byte_size == 0) if (auto size = GetBasicType(lldb::eBasicTypeVoid) @@ -1006,236 +883,220 @@ uint32_t ClangASTContext::GetPointerByteSize() { } CompilerType ClangASTContext::GetBasicType(lldb::BasicType basic_type) { - return GetBasicType(getASTContext(), basic_type); -} + clang::ASTContext &ast = getASTContext(); -CompilerType ClangASTContext::GetBasicType(ASTContext *ast, - lldb::BasicType basic_type) { - if (!ast) - return CompilerType(); lldb::opaque_compiler_type_t clang_type = - GetOpaqueCompilerType(ast, basic_type); + GetOpaqueCompilerType(&ast, basic_type); if (clang_type) - return CompilerType(GetASTContext(ast), clang_type); + return CompilerType(this, clang_type); return CompilerType(); } CompilerType ClangASTContext::GetBuiltinTypeForDWARFEncodingAndBitSize( - const char *type_name, uint32_t dw_ate, uint32_t bit_size) { - ASTContext *ast = getASTContext(); + llvm::StringRef type_name, uint32_t dw_ate, uint32_t bit_size) { + ASTContext &ast = getASTContext(); -#define streq(a, b) strcmp(a, b) == 0 - assert(ast != nullptr); - if (ast) { - switch (dw_ate) { - default: - break; + switch (dw_ate) { + default: + break; - case DW_ATE_address: - if (QualTypeMatchesBitSize(bit_size, ast, ast->VoidPtrTy)) - return CompilerType(this, ast->VoidPtrTy.getAsOpaquePtr()); - break; + case DW_ATE_address: + if (QualTypeMatchesBitSize(bit_size, ast, ast.VoidPtrTy)) + return GetType(ast.VoidPtrTy); + break; - case DW_ATE_boolean: - if (QualTypeMatchesBitSize(bit_size, ast, ast->BoolTy)) - return CompilerType(this, ast->BoolTy.getAsOpaquePtr()); - if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedCharTy)) - return CompilerType(this, ast->UnsignedCharTy.getAsOpaquePtr()); - if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedShortTy)) - return CompilerType(this, ast->UnsignedShortTy.getAsOpaquePtr()); - if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedIntTy)) - return CompilerType(this, ast->UnsignedIntTy.getAsOpaquePtr()); - break; + case DW_ATE_boolean: + if (QualTypeMatchesBitSize(bit_size, ast, ast.BoolTy)) + return GetType(ast.BoolTy); + if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedCharTy)) + return GetType(ast.UnsignedCharTy); + if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedShortTy)) + return GetType(ast.UnsignedShortTy); + if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedIntTy)) + return GetType(ast.UnsignedIntTy); + break; - case DW_ATE_lo_user: - // This has been seen to mean DW_AT_complex_integer - if (type_name) { - if (::strstr(type_name, "complex")) { - CompilerType complex_int_clang_type = - GetBuiltinTypeForDWARFEncodingAndBitSize("int", DW_ATE_signed, - bit_size / 2); - return CompilerType( - this, ast->getComplexType( - ClangUtil::GetQualType(complex_int_clang_type)) - .getAsOpaquePtr()); - } - } - break; + case DW_ATE_lo_user: + // This has been seen to mean DW_AT_complex_integer + if (type_name.contains("complex")) { + CompilerType complex_int_clang_type = + GetBuiltinTypeForDWARFEncodingAndBitSize("int", DW_ATE_signed, + bit_size / 2); + return GetType( + ast.getComplexType(ClangUtil::GetQualType(complex_int_clang_type))); + } + break; - case DW_ATE_complex_float: - if (QualTypeMatchesBitSize(bit_size, ast, ast->FloatComplexTy)) - return CompilerType(this, ast->FloatComplexTy.getAsOpaquePtr()); - else if (QualTypeMatchesBitSize(bit_size, ast, ast->DoubleComplexTy)) - return CompilerType(this, ast->DoubleComplexTy.getAsOpaquePtr()); - else if (QualTypeMatchesBitSize(bit_size, ast, ast->LongDoubleComplexTy)) - return CompilerType(this, ast->LongDoubleComplexTy.getAsOpaquePtr()); - else { - CompilerType complex_float_clang_type = - GetBuiltinTypeForDWARFEncodingAndBitSize("float", DW_ATE_float, - bit_size / 2); - return CompilerType( - this, ast->getComplexType( - ClangUtil::GetQualType(complex_float_clang_type)) - .getAsOpaquePtr()); - } - break; + case DW_ATE_complex_float: + if (QualTypeMatchesBitSize(bit_size, ast, ast.FloatComplexTy)) + return GetType(ast.FloatComplexTy); + else if (QualTypeMatchesBitSize(bit_size, ast, ast.DoubleComplexTy)) + return GetType(ast.DoubleComplexTy); + else if (QualTypeMatchesBitSize(bit_size, ast, ast.LongDoubleComplexTy)) + return GetType(ast.LongDoubleComplexTy); + else { + CompilerType complex_float_clang_type = + GetBuiltinTypeForDWARFEncodingAndBitSize("float", DW_ATE_float, + bit_size / 2); + return GetType( + ast.getComplexType(ClangUtil::GetQualType(complex_float_clang_type))); + } + break; - case DW_ATE_float: - if (streq(type_name, "float") && - QualTypeMatchesBitSize(bit_size, ast, ast->FloatTy)) - return CompilerType(this, ast->FloatTy.getAsOpaquePtr()); - if (streq(type_name, "double") && - QualTypeMatchesBitSize(bit_size, ast, ast->DoubleTy)) - return CompilerType(this, ast->DoubleTy.getAsOpaquePtr()); - if (streq(type_name, "long double") && - QualTypeMatchesBitSize(bit_size, ast, ast->LongDoubleTy)) - return CompilerType(this, ast->LongDoubleTy.getAsOpaquePtr()); - // Fall back to not requiring a name match - if (QualTypeMatchesBitSize(bit_size, ast, ast->FloatTy)) - return CompilerType(this, ast->FloatTy.getAsOpaquePtr()); - if (QualTypeMatchesBitSize(bit_size, ast, ast->DoubleTy)) - return CompilerType(this, ast->DoubleTy.getAsOpaquePtr()); - if (QualTypeMatchesBitSize(bit_size, ast, ast->LongDoubleTy)) - return CompilerType(this, ast->LongDoubleTy.getAsOpaquePtr()); - if (QualTypeMatchesBitSize(bit_size, ast, ast->HalfTy)) - return CompilerType(this, ast->HalfTy.getAsOpaquePtr()); - break; + case DW_ATE_float: + if (type_name == "float" && + QualTypeMatchesBitSize(bit_size, ast, ast.FloatTy)) + return GetType(ast.FloatTy); + if (type_name == "double" && + QualTypeMatchesBitSize(bit_size, ast, ast.DoubleTy)) + return GetType(ast.DoubleTy); + if (type_name == "long double" && + QualTypeMatchesBitSize(bit_size, ast, ast.LongDoubleTy)) + return GetType(ast.LongDoubleTy); + // Fall back to not requiring a name match + if (QualTypeMatchesBitSize(bit_size, ast, ast.FloatTy)) + return GetType(ast.FloatTy); + if (QualTypeMatchesBitSize(bit_size, ast, ast.DoubleTy)) + return GetType(ast.DoubleTy); + if (QualTypeMatchesBitSize(bit_size, ast, ast.LongDoubleTy)) + return GetType(ast.LongDoubleTy); + if (QualTypeMatchesBitSize(bit_size, ast, ast.HalfTy)) + return GetType(ast.HalfTy); + break; - case DW_ATE_signed: - if (type_name) { - if (streq(type_name, "wchar_t") && - QualTypeMatchesBitSize(bit_size, ast, ast->WCharTy) && - (getTargetInfo() && - TargetInfo::isTypeSigned(getTargetInfo()->getWCharType()))) - return CompilerType(this, ast->WCharTy.getAsOpaquePtr()); - if (streq(type_name, "void") && - QualTypeMatchesBitSize(bit_size, ast, ast->VoidTy)) - return CompilerType(this, ast->VoidTy.getAsOpaquePtr()); - if (strstr(type_name, "long long") && - QualTypeMatchesBitSize(bit_size, ast, ast->LongLongTy)) - return CompilerType(this, ast->LongLongTy.getAsOpaquePtr()); - if (strstr(type_name, "long") && - QualTypeMatchesBitSize(bit_size, ast, ast->LongTy)) - return CompilerType(this, ast->LongTy.getAsOpaquePtr()); - if (strstr(type_name, "short") && - QualTypeMatchesBitSize(bit_size, ast, ast->ShortTy)) - return CompilerType(this, ast->ShortTy.getAsOpaquePtr()); - if (strstr(type_name, "char")) { - if (QualTypeMatchesBitSize(bit_size, ast, ast->CharTy)) - return CompilerType(this, ast->CharTy.getAsOpaquePtr()); - if (QualTypeMatchesBitSize(bit_size, ast, ast->SignedCharTy)) - return CompilerType(this, ast->SignedCharTy.getAsOpaquePtr()); - } - if (strstr(type_name, "int")) { - if (QualTypeMatchesBitSize(bit_size, ast, ast->IntTy)) - return CompilerType(this, ast->IntTy.getAsOpaquePtr()); - if (QualTypeMatchesBitSize(bit_size, ast, ast->Int128Ty)) - return CompilerType(this, ast->Int128Ty.getAsOpaquePtr()); - } + case DW_ATE_signed: + if (!type_name.empty()) { + if (type_name == "wchar_t" && + QualTypeMatchesBitSize(bit_size, ast, ast.WCharTy) && + (getTargetInfo() && + TargetInfo::isTypeSigned(getTargetInfo()->getWCharType()))) + return GetType(ast.WCharTy); + if (type_name == "void" && + QualTypeMatchesBitSize(bit_size, ast, ast.VoidTy)) + return GetType(ast.VoidTy); + if (type_name.contains("long long") && + QualTypeMatchesBitSize(bit_size, ast, ast.LongLongTy)) + return GetType(ast.LongLongTy); + if (type_name.contains("long") && + QualTypeMatchesBitSize(bit_size, ast, ast.LongTy)) + return GetType(ast.LongTy); + if (type_name.contains("short") && + QualTypeMatchesBitSize(bit_size, ast, ast.ShortTy)) + return GetType(ast.ShortTy); + if (type_name.contains("char")) { + if (QualTypeMatchesBitSize(bit_size, ast, ast.CharTy)) + return GetType(ast.CharTy); + if (QualTypeMatchesBitSize(bit_size, ast, ast.SignedCharTy)) + return GetType(ast.SignedCharTy); } - // We weren't able to match up a type name, just search by size - if (QualTypeMatchesBitSize(bit_size, ast, ast->CharTy)) - return CompilerType(this, ast->CharTy.getAsOpaquePtr()); - if (QualTypeMatchesBitSize(bit_size, ast, ast->ShortTy)) - return CompilerType(this, ast->ShortTy.getAsOpaquePtr()); - if (QualTypeMatchesBitSize(bit_size, ast, ast->IntTy)) - return CompilerType(this, ast->IntTy.getAsOpaquePtr()); - if (QualTypeMatchesBitSize(bit_size, ast, ast->LongTy)) - return CompilerType(this, ast->LongTy.getAsOpaquePtr()); - if (QualTypeMatchesBitSize(bit_size, ast, ast->LongLongTy)) - return CompilerType(this, ast->LongLongTy.getAsOpaquePtr()); - if (QualTypeMatchesBitSize(bit_size, ast, ast->Int128Ty)) - return CompilerType(this, ast->Int128Ty.getAsOpaquePtr()); - break; - - case DW_ATE_signed_char: - if (ast->getLangOpts().CharIsSigned && type_name && - streq(type_name, "char")) { - if (QualTypeMatchesBitSize(bit_size, ast, ast->CharTy)) - return CompilerType(this, ast->CharTy.getAsOpaquePtr()); + if (type_name.contains("int")) { + if (QualTypeMatchesBitSize(bit_size, ast, ast.IntTy)) + return GetType(ast.IntTy); + if (QualTypeMatchesBitSize(bit_size, ast, ast.Int128Ty)) + return GetType(ast.Int128Ty); } - if (QualTypeMatchesBitSize(bit_size, ast, ast->SignedCharTy)) - return CompilerType(this, ast->SignedCharTy.getAsOpaquePtr()); - break; + } + // We weren't able to match up a type name, just search by size + if (QualTypeMatchesBitSize(bit_size, ast, ast.CharTy)) + return GetType(ast.CharTy); + if (QualTypeMatchesBitSize(bit_size, ast, ast.ShortTy)) + return GetType(ast.ShortTy); + if (QualTypeMatchesBitSize(bit_size, ast, ast.IntTy)) + return GetType(ast.IntTy); + if (QualTypeMatchesBitSize(bit_size, ast, ast.LongTy)) + return GetType(ast.LongTy); + if (QualTypeMatchesBitSize(bit_size, ast, ast.LongLongTy)) + return GetType(ast.LongLongTy); + if (QualTypeMatchesBitSize(bit_size, ast, ast.Int128Ty)) + return GetType(ast.Int128Ty); + break; - case DW_ATE_unsigned: - if (type_name) { - if (streq(type_name, "wchar_t")) { - if (QualTypeMatchesBitSize(bit_size, ast, ast->WCharTy)) { - if (!(getTargetInfo() && - TargetInfo::isTypeSigned(getTargetInfo()->getWCharType()))) - return CompilerType(this, ast->WCharTy.getAsOpaquePtr()); - } - } - if (strstr(type_name, "long long")) { - if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedLongLongTy)) - return CompilerType(this, ast->UnsignedLongLongTy.getAsOpaquePtr()); - } else if (strstr(type_name, "long")) { - if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedLongTy)) - return CompilerType(this, ast->UnsignedLongTy.getAsOpaquePtr()); - } else if (strstr(type_name, "short")) { - if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedShortTy)) - return CompilerType(this, ast->UnsignedShortTy.getAsOpaquePtr()); - } else if (strstr(type_name, "char")) { - if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedCharTy)) - return CompilerType(this, ast->UnsignedCharTy.getAsOpaquePtr()); - } else if (strstr(type_name, "int")) { - if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedIntTy)) - return CompilerType(this, ast->UnsignedIntTy.getAsOpaquePtr()); - if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedInt128Ty)) - return CompilerType(this, ast->UnsignedInt128Ty.getAsOpaquePtr()); + case DW_ATE_signed_char: + if (ast.getLangOpts().CharIsSigned && type_name == "char") { + if (QualTypeMatchesBitSize(bit_size, ast, ast.CharTy)) + return GetType(ast.CharTy); + } + if (QualTypeMatchesBitSize(bit_size, ast, ast.SignedCharTy)) + return GetType(ast.SignedCharTy); + break; + + case DW_ATE_unsigned: + if (!type_name.empty()) { + if (type_name == "wchar_t") { + if (QualTypeMatchesBitSize(bit_size, ast, ast.WCharTy)) { + if (!(getTargetInfo() && + TargetInfo::isTypeSigned(getTargetInfo()->getWCharType()))) + return GetType(ast.WCharTy); } } - // We weren't able to match up a type name, just search by size - if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedCharTy)) - return CompilerType(this, ast->UnsignedCharTy.getAsOpaquePtr()); - if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedShortTy)) - return CompilerType(this, ast->UnsignedShortTy.getAsOpaquePtr()); - if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedIntTy)) - return CompilerType(this, ast->UnsignedIntTy.getAsOpaquePtr()); - if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedLongTy)) - return CompilerType(this, ast->UnsignedLongTy.getAsOpaquePtr()); - if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedLongLongTy)) - return CompilerType(this, ast->UnsignedLongLongTy.getAsOpaquePtr()); - if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedInt128Ty)) - return CompilerType(this, ast->UnsignedInt128Ty.getAsOpaquePtr()); - break; - - case DW_ATE_unsigned_char: - if (!ast->getLangOpts().CharIsSigned && type_name && - streq(type_name, "char")) { - if (QualTypeMatchesBitSize(bit_size, ast, ast->CharTy)) - return CompilerType(this, ast->CharTy.getAsOpaquePtr()); + if (type_name.contains("long long")) { + if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedLongLongTy)) + return GetType(ast.UnsignedLongLongTy); + } else if (type_name.contains("long")) { + if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedLongTy)) + return GetType(ast.UnsignedLongTy); + } else if (type_name.contains("short")) { + if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedShortTy)) + return GetType(ast.UnsignedShortTy); + } else if (type_name.contains("char")) { + if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedCharTy)) + return GetType(ast.UnsignedCharTy); + } else if (type_name.contains("int")) { + if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedIntTy)) + return GetType(ast.UnsignedIntTy); + if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedInt128Ty)) + return GetType(ast.UnsignedInt128Ty); } - if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedCharTy)) - return CompilerType(this, ast->UnsignedCharTy.getAsOpaquePtr()); - if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedShortTy)) - return CompilerType(this, ast->UnsignedShortTy.getAsOpaquePtr()); - break; + } + // We weren't able to match up a type name, just search by size + if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedCharTy)) + return GetType(ast.UnsignedCharTy); + if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedShortTy)) + return GetType(ast.UnsignedShortTy); + if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedIntTy)) + return GetType(ast.UnsignedIntTy); + if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedLongTy)) + return GetType(ast.UnsignedLongTy); + if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedLongLongTy)) + return GetType(ast.UnsignedLongLongTy); + if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedInt128Ty)) + return GetType(ast.UnsignedInt128Ty); + break; - case DW_ATE_imaginary_float: - break; + case DW_ATE_unsigned_char: + if (!ast.getLangOpts().CharIsSigned && type_name == "char") { + if (QualTypeMatchesBitSize(bit_size, ast, ast.CharTy)) + return GetType(ast.CharTy); + } + if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedCharTy)) + return GetType(ast.UnsignedCharTy); + if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedShortTy)) + return GetType(ast.UnsignedShortTy); + break; - case DW_ATE_UTF: - if (type_name) { - if (streq(type_name, "char16_t")) - return CompilerType(this, ast->Char16Ty.getAsOpaquePtr()); - if (streq(type_name, "char32_t")) - return CompilerType(this, ast->Char32Ty.getAsOpaquePtr()); - if (streq(type_name, "char8_t")) - return CompilerType(this, ast->Char8Ty.getAsOpaquePtr()); - } - break; + case DW_ATE_imaginary_float: + break; + + case DW_ATE_UTF: + if (!type_name.empty()) { + if (type_name == "char16_t") + return GetType(ast.Char16Ty); + if (type_name == "char32_t") + return GetType(ast.Char32Ty); + if (type_name == "char8_t") + return GetType(ast.Char8Ty); } + break; } // This assert should fire for anything that we don't catch above so we know // to fix any issues we run into. - if (type_name) { - Host::SystemLog(Host::eSystemLogError, "error: need to add support for " - "DW_TAG_base_type '%s' encoded with " - "DW_ATE = 0x%x, bit_size = %u\n", - type_name, dw_ate, bit_size); + if (!type_name.empty()) { + std::string type_name_str = type_name.str(); + Host::SystemLog(Host::eSystemLogError, + "error: need to add support for DW_TAG_base_type '%s' " + "encoded with DW_ATE = 0x%x, bit_size = %u\n", + type_name_str.c_str(), dw_ate, bit_size); } else { Host::SystemLog(Host::eSystemLogError, "error: need to add support for " "DW_TAG_base_type encoded with " @@ -1245,42 +1106,14 @@ CompilerType ClangASTContext::GetBuiltinTypeForDWARFEncodingAndBitSize( return CompilerType(); } -CompilerType ClangASTContext::GetUnknownAnyType(clang::ASTContext *ast) { - if (ast) - return CompilerType(ClangASTContext::GetASTContext(ast), - ast->UnknownAnyTy.getAsOpaquePtr()); - return CompilerType(); -} - CompilerType ClangASTContext::GetCStringType(bool is_const) { - ASTContext *ast = getASTContext(); - QualType char_type(ast->CharTy); + ASTContext &ast = getASTContext(); + QualType char_type(ast.CharTy); if (is_const) char_type.addConst(); - return CompilerType(this, ast->getPointerType(char_type).getAsOpaquePtr()); -} - -clang::DeclContext * -ClangASTContext::GetTranslationUnitDecl(clang::ASTContext *ast) { - return ast->getTranslationUnitDecl(); -} - -clang::Decl *ClangASTContext::CopyDecl(ASTContext *dst_ast, ASTContext *src_ast, - clang::Decl *source_decl) { - FileSystemOptions file_system_options; - FileManager file_manager(file_system_options); - ASTImporter importer(*dst_ast, file_manager, *src_ast, file_manager, false); - - if (llvm::Expected<clang::Decl *> ret_or_error = - importer.Import(source_decl)) { - return *ret_or_error; - } else { - Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS); - LLDB_LOG_ERROR(log, ret_or_error.takeError(), "Couldn't import decl: {0}"); - return nullptr; - } + return GetType(ast.getPointerType(char_type)); } bool ClangASTContext::AreTypesSame(CompilerType type1, CompilerType type2, @@ -1301,7 +1134,7 @@ bool ClangASTContext::AreTypesSame(CompilerType type1, CompilerType type2, type2_qual = type2_qual.getUnqualifiedType(); } - return ast->getASTContext()->hasSameType(type1_qual, type2_qual); + return ast->getASTContext().hasSameType(type1_qual, type2_qual); } CompilerType ClangASTContext::GetTypeForDecl(void *opaque_decl) { @@ -1314,9 +1147,15 @@ CompilerType ClangASTContext::GetTypeForDecl(void *opaque_decl) { return CompilerType(); } +CompilerDeclContext ClangASTContext::CreateDeclContext(DeclContext *ctx) { + // Check that the DeclContext actually belongs to this ASTContext. + assert(&ctx->getParentASTContext() == &getASTContext()); + return CompilerDeclContext(this, ctx); +} + CompilerType ClangASTContext::GetTypeForDecl(clang::NamedDecl *decl) { if (clang::ObjCInterfaceDecl *interface_decl = - llvm::dyn_cast<clang::ObjCInterfaceDecl>(decl)) + llvm::dyn_cast<clang::ObjCInterfaceDecl>(decl)) return GetTypeForDecl(interface_decl); if (clang::TagDecl *tag_decl = llvm::dyn_cast<clang::TagDecl>(decl)) return GetTypeForDecl(tag_decl); @@ -1324,39 +1163,25 @@ CompilerType ClangASTContext::GetTypeForDecl(clang::NamedDecl *decl) { } CompilerType ClangASTContext::GetTypeForDecl(TagDecl *decl) { - // No need to call the getASTContext() accessor (which can create the AST if - // it isn't created yet, because we can't have created a decl in this - // AST if our AST didn't already exist... - ASTContext *ast = &decl->getASTContext(); - if (ast) - return CompilerType(ClangASTContext::GetASTContext(ast), - ast->getTagDeclType(decl).getAsOpaquePtr()); - return CompilerType(); + return GetType(getASTContext().getTagDeclType(decl)); } CompilerType ClangASTContext::GetTypeForDecl(ObjCInterfaceDecl *decl) { - // No need to call the getASTContext() accessor (which can create the AST if - // it isn't created yet, because we can't have created a decl in this - // AST if our AST didn't already exist... - ASTContext *ast = &decl->getASTContext(); - if (ast) - return CompilerType(ClangASTContext::GetASTContext(ast), - ast->getObjCInterfaceType(decl).getAsOpaquePtr()); - return CompilerType(); + return GetType(getASTContext().getObjCInterfaceType(decl)); } #pragma mark Structure, Unions, Classes CompilerType ClangASTContext::CreateRecordType(DeclContext *decl_ctx, AccessType access_type, - const char *name, int kind, + llvm::StringRef name, int kind, LanguageType language, - ClangASTMetadata *metadata) { - ASTContext *ast = getASTContext(); - assert(ast != nullptr); + ClangASTMetadata *metadata, + bool exports_symbols) { + ASTContext &ast = getASTContext(); if (decl_ctx == nullptr) - decl_ctx = ast->getTranslationUnitDecl(); + decl_ctx = ast.getTranslationUnitDecl(); if (language == eLanguageTypeObjC || language == eLanguageTypeObjC_plus_plus) { @@ -1371,11 +1196,11 @@ CompilerType ClangASTContext::CreateRecordType(DeclContext *decl_ctx, // something is struct or a class, so we default to always use the more // complete definition just in case. - bool has_name = name && name[0]; + bool has_name = !name.empty(); CXXRecordDecl *decl = CXXRecordDecl::Create( - *ast, (TagDecl::TagKind)kind, decl_ctx, SourceLocation(), - SourceLocation(), has_name ? &ast->Idents.get(name) : nullptr); + ast, (TagDecl::TagKind)kind, decl_ctx, SourceLocation(), SourceLocation(), + has_name ? &ast.Idents.get(name) : nullptr); if (!has_name) { // In C++ a lambda is also represented as an unnamed class. This is @@ -1402,16 +1227,13 @@ CompilerType ClangASTContext::CreateRecordType(DeclContext *decl_ctx, // Anonymous classes is a GNU/MSVC extension that clang supports. It // requires the anonymous class be embedded within a class. So the new // heuristic verifies this condition. - // - // FIXME: An unnamed class within a class is also wrongly recognized as an - // anonymous struct. - if (isa<CXXRecordDecl>(decl_ctx)) + if (isa<CXXRecordDecl>(decl_ctx) && exports_symbols) decl->setAnonymousStructOrUnion(true); } if (decl) { if (metadata) - SetMetadata(ast, decl, *metadata); + SetMetadata(decl, *metadata); if (access_type != eAccessNone) decl->setAccess(ConvertAccessTypeToAccessSpecifier(access_type)); @@ -1419,7 +1241,7 @@ CompilerType ClangASTContext::CreateRecordType(DeclContext *decl_ctx, if (decl_ctx) decl_ctx->addDecl(decl); - return CompilerType(this, ast->getTagDeclType(decl).getAsOpaquePtr()); + return GetType(ast.getTagDeclType(decl)); } return CompilerType(); } @@ -1492,14 +1314,14 @@ clang::FunctionTemplateDecl *ClangASTContext::CreateFunctionTemplateDecl( clang::DeclContext *decl_ctx, clang::FunctionDecl *func_decl, const char *name, const TemplateParameterInfos &template_param_infos) { // /// Create a function template node. - ASTContext *ast = getASTContext(); + ASTContext &ast = getASTContext(); llvm::SmallVector<NamedDecl *, 8> template_param_decls; TemplateParameterList *template_param_list = CreateTemplateParameterList( - ast, template_param_infos, template_param_decls); + &ast, template_param_infos, template_param_decls); FunctionTemplateDecl *func_tmpl_decl = FunctionTemplateDecl::Create( - *ast, decl_ctx, func_decl->getLocation(), func_decl->getDeclName(), + ast, decl_ctx, func_decl->getLocation(), func_decl->getDeclName(), template_param_list, func_decl); for (size_t i = 0, template_param_decl_count = template_param_decls.size(); @@ -1507,6 +1329,11 @@ clang::FunctionTemplateDecl *ClangASTContext::CreateFunctionTemplateDecl( // TODO: verify which decl context we should put template_param_decls into.. template_param_decls[i]->setDeclContext(func_decl); } + // Function templates inside a record need to have an access specifier. + // It doesn't matter what access specifier we give the template as LLDB + // anyway allows accessing everything inside a record. + if (decl_ctx->isRecord()) + func_tmpl_decl->setAccess(clang::AccessSpecifier::AS_public); return func_tmpl_decl; } @@ -1524,13 +1351,13 @@ void ClangASTContext::CreateFunctionTemplateSpecializationInfo( ClassTemplateDecl *ClangASTContext::CreateClassTemplateDecl( DeclContext *decl_ctx, lldb::AccessType access_type, const char *class_name, int kind, const TemplateParameterInfos &template_param_infos) { - ASTContext *ast = getASTContext(); + ASTContext &ast = getASTContext(); ClassTemplateDecl *class_template_decl = nullptr; if (decl_ctx == nullptr) - decl_ctx = ast->getTranslationUnitDecl(); + decl_ctx = ast.getTranslationUnitDecl(); - IdentifierInfo &identifier_info = ast->Idents.get(class_name); + IdentifierInfo &identifier_info = ast.Idents.get(class_name); DeclarationName decl_name(&identifier_info); clang::DeclContext::lookup_result result = decl_ctx->lookup(decl_name); @@ -1544,10 +1371,10 @@ ClassTemplateDecl *ClangASTContext::CreateClassTemplateDecl( llvm::SmallVector<NamedDecl *, 8> template_param_decls; TemplateParameterList *template_param_list = CreateTemplateParameterList( - ast, template_param_infos, template_param_decls); + &ast, template_param_infos, template_param_decls); CXXRecordDecl *template_cxx_decl = CXXRecordDecl::Create( - *ast, (TagDecl::TagKind)kind, + ast, (TagDecl::TagKind)kind, decl_ctx, // What decl context do we use here? TU? The actual decl // context? SourceLocation(), SourceLocation(), &identifier_info); @@ -1563,7 +1390,7 @@ ClassTemplateDecl *ClangASTContext::CreateClassTemplateDecl( // template_cxx_decl->completeDefinition(); class_template_decl = ClassTemplateDecl::Create( - *ast, + ast, decl_ctx, // What decl context do we use here? TU? The actual decl // context? SourceLocation(), decl_name, template_param_list, template_cxx_decl); @@ -1589,23 +1416,23 @@ ClassTemplateDecl *ClangASTContext::CreateClassTemplateDecl( TemplateTemplateParmDecl * ClangASTContext::CreateTemplateTemplateParmDecl(const char *template_name) { - ASTContext *ast = getASTContext(); + ASTContext &ast = getASTContext(); - auto *decl_ctx = ast->getTranslationUnitDecl(); + auto *decl_ctx = ast.getTranslationUnitDecl(); - IdentifierInfo &identifier_info = ast->Idents.get(template_name); + IdentifierInfo &identifier_info = ast.Idents.get(template_name); llvm::SmallVector<NamedDecl *, 8> template_param_decls; ClangASTContext::TemplateParameterInfos template_param_infos; TemplateParameterList *template_param_list = CreateTemplateParameterList( - ast, template_param_infos, template_param_decls); + &ast, template_param_infos, template_param_decls); // LLDB needs to create those decls only to be able to display a // type that includes a template template argument. Only the name matters for // this purpose, so we use dummy values for the other characterisitcs of the // type. return TemplateTemplateParmDecl::Create( - *ast, decl_ctx, SourceLocation(), + ast, decl_ctx, SourceLocation(), /*Depth*/ 0, /*Position*/ 0, /*IsParameterPack*/ false, &identifier_info, template_param_list); } @@ -1614,7 +1441,7 @@ ClassTemplateSpecializationDecl * ClangASTContext::CreateClassTemplateSpecializationDecl( DeclContext *decl_ctx, ClassTemplateDecl *class_template_decl, int kind, const TemplateParameterInfos &template_param_infos) { - ASTContext *ast = getASTContext(); + ASTContext &ast = getASTContext(); llvm::SmallVector<clang::TemplateArgument, 2> args( template_param_infos.args.size() + (template_param_infos.packed_args ? 1 : 0)); @@ -1622,13 +1449,12 @@ ClangASTContext::CreateClassTemplateSpecializationDecl( args.begin()); if (template_param_infos.packed_args) { args[args.size() - 1] = TemplateArgument::CreatePackCopy( - *ast, template_param_infos.packed_args->args); + ast, template_param_infos.packed_args->args); } ClassTemplateSpecializationDecl *class_template_specialization_decl = ClassTemplateSpecializationDecl::Create( - *ast, (TagDecl::TagKind)kind, decl_ctx, SourceLocation(), - SourceLocation(), class_template_decl, args, - nullptr); + ast, (TagDecl::TagKind)kind, decl_ctx, SourceLocation(), + SourceLocation(), class_template_decl, args, nullptr); class_template_specialization_decl->setSpecializationKind( TSK_ExplicitSpecialization); @@ -1639,11 +1465,8 @@ ClangASTContext::CreateClassTemplateSpecializationDecl( CompilerType ClangASTContext::CreateClassTemplateSpecializationType( ClassTemplateSpecializationDecl *class_template_specialization_decl) { if (class_template_specialization_decl) { - ASTContext *ast = getASTContext(); - if (ast) - return CompilerType( - this, ast->getTagDeclType(class_template_specialization_decl) - .getAsOpaquePtr()); + ASTContext &ast = getASTContext(); + return GetType(ast.getTagDeclType(class_template_specialization_decl)); } return CompilerType(); } @@ -1708,19 +1531,15 @@ ClangASTContext::UnifyAccessSpecifiers(clang::AccessSpecifier lhs, bool ClangASTContext::FieldIsBitfield(FieldDecl *field, uint32_t &bitfield_bit_size) { - return FieldIsBitfield(getASTContext(), field, bitfield_bit_size); -} - -bool ClangASTContext::FieldIsBitfield(ASTContext *ast, FieldDecl *field, - uint32_t &bitfield_bit_size) { - if (ast == nullptr || field == nullptr) + ASTContext &ast = getASTContext(); + if (field == nullptr) return false; if (field->isBitField()) { Expr *bit_width_expr = field->getBitWidth(); if (bit_width_expr) { llvm::APSInt bit_width_apsint; - if (bit_width_expr->isIntegerConstantExpr(bit_width_apsint, *ast)) { + if (bit_width_expr->isIntegerConstantExpr(bit_width_apsint, ast)) { bitfield_bit_size = bit_width_apsint.getLimitedValue(UINT32_MAX); return true; } @@ -1754,27 +1573,26 @@ bool ClangASTContext::RecordHasFields(const RecordDecl *record_decl) { #pragma mark Objective-C Classes -CompilerType ClangASTContext::CreateObjCClass(const char *name, +CompilerType ClangASTContext::CreateObjCClass(llvm::StringRef name, DeclContext *decl_ctx, bool isForwardDecl, bool isInternal, ClangASTMetadata *metadata) { - ASTContext *ast = getASTContext(); - assert(ast != nullptr); - assert(name && name[0]); + ASTContext &ast = getASTContext(); + assert(!name.empty()); if (decl_ctx == nullptr) - decl_ctx = ast->getTranslationUnitDecl(); + decl_ctx = ast.getTranslationUnitDecl(); ObjCInterfaceDecl *decl = ObjCInterfaceDecl::Create( - *ast, decl_ctx, SourceLocation(), &ast->Idents.get(name), nullptr, - nullptr, SourceLocation(), + ast, decl_ctx, SourceLocation(), &ast.Idents.get(name), nullptr, nullptr, + SourceLocation(), /*isForwardDecl,*/ isInternal); if (decl && metadata) - SetMetadata(ast, decl, *metadata); + SetMetadata(decl, *metadata); - return CompilerType(this, ast->getObjCInterfaceType(decl).getAsOpaquePtr()); + return GetType(ast.getObjCInterfaceType(decl)); } static inline bool BaseSpecifierIsEmpty(const CXXBaseSpecifier *b) { @@ -1809,13 +1627,13 @@ ClangASTContext::GetNumBaseClasses(const CXXRecordDecl *cxx_record_decl, NamespaceDecl *ClangASTContext::GetUniqueNamespaceDeclaration( const char *name, DeclContext *decl_ctx, bool is_inline) { NamespaceDecl *namespace_decl = nullptr; - ASTContext *ast = getASTContext(); - TranslationUnitDecl *translation_unit_decl = ast->getTranslationUnitDecl(); + ASTContext &ast = getASTContext(); + TranslationUnitDecl *translation_unit_decl = ast.getTranslationUnitDecl(); if (decl_ctx == nullptr) decl_ctx = translation_unit_decl; if (name) { - IdentifierInfo &identifier_info = ast->Idents.get(name); + IdentifierInfo &identifier_info = ast.Idents.get(name); DeclarationName decl_name(&identifier_info); clang::DeclContext::lookup_result result = decl_ctx->lookup(decl_name); for (NamedDecl *decl : result) { @@ -1825,7 +1643,7 @@ NamespaceDecl *ClangASTContext::GetUniqueNamespaceDeclaration( } namespace_decl = - NamespaceDecl::Create(*ast, decl_ctx, is_inline, SourceLocation(), + NamespaceDecl::Create(ast, decl_ctx, is_inline, SourceLocation(), SourceLocation(), &identifier_info, nullptr); decl_ctx->addDecl(namespace_decl); @@ -1836,7 +1654,7 @@ NamespaceDecl *ClangASTContext::GetUniqueNamespaceDeclaration( return namespace_decl; namespace_decl = - NamespaceDecl::Create(*ast, decl_ctx, false, SourceLocation(), + NamespaceDecl::Create(ast, decl_ctx, false, SourceLocation(), SourceLocation(), nullptr, nullptr); translation_unit_decl->setAnonymousNamespace(namespace_decl); translation_unit_decl->addDecl(namespace_decl); @@ -1848,7 +1666,7 @@ NamespaceDecl *ClangASTContext::GetUniqueNamespaceDeclaration( if (namespace_decl) return namespace_decl; namespace_decl = - NamespaceDecl::Create(*ast, decl_ctx, false, SourceLocation(), + NamespaceDecl::Create(ast, decl_ctx, false, SourceLocation(), SourceLocation(), nullptr, nullptr); parent_namespace_decl->setAnonymousNamespace(namespace_decl); parent_namespace_decl->addDecl(namespace_decl); @@ -1866,21 +1684,11 @@ NamespaceDecl *ClangASTContext::GetUniqueNamespaceDeclaration( return namespace_decl; } -NamespaceDecl *ClangASTContext::GetUniqueNamespaceDeclaration( - clang::ASTContext *ast, const char *name, clang::DeclContext *decl_ctx, - bool is_inline) { - ClangASTContext *ast_ctx = ClangASTContext::GetASTContext(ast); - if (ast_ctx == nullptr) - return nullptr; - - return ast_ctx->GetUniqueNamespaceDeclaration(name, decl_ctx, is_inline); -} - clang::BlockDecl * ClangASTContext::CreateBlockDeclaration(clang::DeclContext *ctx) { if (ctx != nullptr) { - clang::BlockDecl *decl = clang::BlockDecl::Create(*getASTContext(), ctx, - clang::SourceLocation()); + clang::BlockDecl *decl = + clang::BlockDecl::Create(getASTContext(), ctx, clang::SourceLocation()); ctx->addDecl(decl); return decl; } @@ -1907,10 +1715,9 @@ clang::DeclContext *FindLCABetweenDecls(clang::DeclContext *left, clang::UsingDirectiveDecl *ClangASTContext::CreateUsingDirectiveDeclaration( clang::DeclContext *decl_ctx, clang::NamespaceDecl *ns_decl) { if (decl_ctx != nullptr && ns_decl != nullptr) { - clang::TranslationUnitDecl *translation_unit = - (clang::TranslationUnitDecl *)GetTranslationUnitDecl(getASTContext()); + auto *translation_unit = getASTContext().getTranslationUnitDecl(); clang::UsingDirectiveDecl *using_decl = clang::UsingDirectiveDecl::Create( - *getASTContext(), decl_ctx, clang::SourceLocation(), + getASTContext(), decl_ctx, clang::SourceLocation(), clang::SourceLocation(), clang::NestedNameSpecifierLoc(), clang::SourceLocation(), ns_decl, FindLCABetweenDecls(decl_ctx, ns_decl, translation_unit)); @@ -1925,10 +1732,10 @@ ClangASTContext::CreateUsingDeclaration(clang::DeclContext *current_decl_ctx, clang::NamedDecl *target) { if (current_decl_ctx != nullptr && target != nullptr) { clang::UsingDecl *using_decl = clang::UsingDecl::Create( - *getASTContext(), current_decl_ctx, clang::SourceLocation(), + getASTContext(), current_decl_ctx, clang::SourceLocation(), clang::NestedNameSpecifierLoc(), clang::DeclarationNameInfo(), false); clang::UsingShadowDecl *shadow_decl = clang::UsingShadowDecl::Create( - *getASTContext(), current_decl_ctx, clang::SourceLocation(), using_decl, + getASTContext(), current_decl_ctx, clang::SourceLocation(), using_decl, target); using_decl->addShadowDecl(shadow_decl); current_decl_ctx->addDecl(using_decl); @@ -1941,9 +1748,9 @@ clang::VarDecl *ClangASTContext::CreateVariableDeclaration( clang::DeclContext *decl_context, const char *name, clang::QualType type) { if (decl_context != nullptr) { clang::VarDecl *var_decl = clang::VarDecl::Create( - *getASTContext(), decl_context, clang::SourceLocation(), + getASTContext(), decl_context, clang::SourceLocation(), clang::SourceLocation(), - name && name[0] ? &getASTContext()->Idents.getOwn(name) : nullptr, type, + name && name[0] ? &getASTContext().Idents.getOwn(name) : nullptr, type, nullptr, clang::SC_None); var_decl->setAccess(clang::AS_public); decl_context->addDecl(var_decl); @@ -2033,7 +1840,7 @@ ClangASTContext::GetDeclarationName(const char *name, clang::OverloadedOperatorKind op_kind = clang::NUM_OVERLOADED_OPERATORS; if (!IsOperator(name, op_kind) || op_kind == clang::NUM_OVERLOADED_OPERATORS) - return DeclarationName(&getASTContext()->Idents.get( + return DeclarationName(&getASTContext().Idents.get( name)); // Not operator, but a regular function. // Check the number of operator parameters. Sometimes we have seen bad DWARF @@ -2052,16 +1859,16 @@ ClangASTContext::GetDeclarationName(const char *name, is_method, op_kind, num_params)) return clang::DeclarationName(); - return getASTContext()->DeclarationNames.getCXXOperatorName(op_kind); + return getASTContext().DeclarationNames.getCXXOperatorName(op_kind); } FunctionDecl *ClangASTContext::CreateFunctionDeclaration( DeclContext *decl_ctx, const char *name, const CompilerType &function_clang_type, int storage, bool is_inline) { FunctionDecl *func_decl = nullptr; - ASTContext *ast = getASTContext(); + ASTContext &ast = getASTContext(); if (decl_ctx == nullptr) - decl_ctx = ast->getTranslationUnitDecl(); + decl_ctx = ast.getTranslationUnitDecl(); const bool hasWrittenPrototype = true; const bool isConstexprSpecified = false; @@ -2069,7 +1876,7 @@ FunctionDecl *ClangASTContext::CreateFunctionDeclaration( clang::DeclarationName declarationName = GetDeclarationName(name, function_clang_type); func_decl = FunctionDecl::Create( - *ast, decl_ctx, SourceLocation(), SourceLocation(), declarationName, + ast, decl_ctx, SourceLocation(), SourceLocation(), declarationName, ClangUtil::GetQualType(function_clang_type), nullptr, (clang::StorageClass)storage, is_inline, hasWrittenPrototype, isConstexprSpecified ? CSK_constexpr : CSK_unspecified); @@ -2083,13 +1890,11 @@ FunctionDecl *ClangASTContext::CreateFunctionDeclaration( return func_decl; } -CompilerType ClangASTContext::CreateFunctionType( - ASTContext *ast, const CompilerType &result_type, const CompilerType *args, - unsigned num_args, bool is_variadic, unsigned type_quals, - clang::CallingConv cc) { - if (ast == nullptr) - return CompilerType(); // invalid AST - +CompilerType +ClangASTContext::CreateFunctionType(const CompilerType &result_type, + const CompilerType *args, unsigned num_args, + bool is_variadic, unsigned type_quals, + clang::CallingConv cc) { if (!result_type || !ClangUtil::IsClangType(result_type)) return CompilerType(); // invalid return type @@ -2120,19 +1925,17 @@ CompilerType ClangASTContext::CreateFunctionType( proto_info.TypeQuals = clang::Qualifiers::fromFastMask(type_quals); proto_info.RefQualifier = RQ_None; - return CompilerType(ClangASTContext::GetASTContext(ast), - ast->getFunctionType(ClangUtil::GetQualType(result_type), - qual_type_args, proto_info).getAsOpaquePtr()); + return GetType(getASTContext().getFunctionType( + ClangUtil::GetQualType(result_type), qual_type_args, proto_info)); } ParmVarDecl *ClangASTContext::CreateParameterDeclaration( clang::DeclContext *decl_ctx, const char *name, const CompilerType ¶m_type, int storage, bool add_decl) { - ASTContext *ast = getASTContext(); - assert(ast != nullptr); + ASTContext &ast = getASTContext(); auto *decl = - ParmVarDecl::Create(*ast, decl_ctx, SourceLocation(), SourceLocation(), - name && name[0] ? &ast->Idents.get(name) : nullptr, + ParmVarDecl::Create(ast, decl_ctx, SourceLocation(), SourceLocation(), + name && name[0] ? &ast.Idents.get(name) : nullptr, ClangUtil::GetQualType(param_type), nullptr, (clang::StorageClass)storage, nullptr); if (add_decl) @@ -2153,7 +1956,7 @@ ClangASTContext::CreateBlockPointerType(const CompilerType &function_type) { QualType block_type = m_ast_up->getBlockPointerType( clang::QualType::getFromOpaquePtr(function_type.GetOpaqueQualType())); - return CompilerType(this, block_type.getAsOpaquePtr()); + return GetType(block_type); } #pragma mark Array Types @@ -2162,28 +1965,21 @@ CompilerType ClangASTContext::CreateArrayType(const CompilerType &element_type, size_t element_count, bool is_vector) { if (element_type.IsValid()) { - ASTContext *ast = getASTContext(); - assert(ast != nullptr); + ASTContext &ast = getASTContext(); if (is_vector) { - return CompilerType( - this, ast->getExtVectorType(ClangUtil::GetQualType(element_type), - element_count) - .getAsOpaquePtr()); + return GetType(ast.getExtVectorType(ClangUtil::GetQualType(element_type), + element_count)); } else { llvm::APInt ap_element_count(64, element_count); if (element_count == 0) { - return CompilerType(this, ast->getIncompleteArrayType( - ClangUtil::GetQualType(element_type), - clang::ArrayType::Normal, 0) - .getAsOpaquePtr()); + return GetType(ast.getIncompleteArrayType( + ClangUtil::GetQualType(element_type), clang::ArrayType::Normal, 0)); } else { - return CompilerType(this, ast->getConstantArrayType( - ClangUtil::GetQualType(element_type), - ap_element_count, nullptr, - clang::ArrayType::Normal, 0) - .getAsOpaquePtr()); + return GetType(ast.getConstantArrayType( + ClangUtil::GetQualType(element_type), ap_element_count, nullptr, + clang::ArrayType::Normal, 0)); } } } @@ -2236,14 +2032,14 @@ ClangASTContext::CreateEnumerationType(const char *name, DeclContext *decl_ctx, bool is_scoped) { // TODO: Do something intelligent with the Declaration object passed in // like maybe filling in the SourceLocation with it... - ASTContext *ast = getASTContext(); + ASTContext &ast = getASTContext(); // TODO: ask about these... // const bool IsFixed = false; EnumDecl *enum_decl = EnumDecl::Create( - *ast, decl_ctx, SourceLocation(), SourceLocation(), - name && name[0] ? &ast->Idents.get(name) : nullptr, nullptr, + ast, decl_ctx, SourceLocation(), SourceLocation(), + name && name[0] ? &ast.Idents.get(name) : nullptr, nullptr, is_scoped, // IsScoped is_scoped, // IsScopedUsingClassTag false); // IsFixed @@ -2257,71 +2053,58 @@ ClangASTContext::CreateEnumerationType(const char *name, DeclContext *decl_ctx, enum_decl->setAccess(AS_public); // TODO respect what's in the debug info - return CompilerType(this, ast->getTagDeclType(enum_decl).getAsOpaquePtr()); + return GetType(ast.getTagDeclType(enum_decl)); } return CompilerType(); } -CompilerType ClangASTContext::GetIntTypeFromBitSize(clang::ASTContext *ast, - size_t bit_size, +CompilerType ClangASTContext::GetIntTypeFromBitSize(size_t bit_size, bool is_signed) { - if (ast) { - auto *clang_ast_context = ClangASTContext::GetASTContext(ast); - if (is_signed) { - if (bit_size == ast->getTypeSize(ast->SignedCharTy)) - return CompilerType(clang_ast_context, - ast->SignedCharTy.getAsOpaquePtr()); + clang::ASTContext &ast = getASTContext(); - if (bit_size == ast->getTypeSize(ast->ShortTy)) - return CompilerType(clang_ast_context, ast->ShortTy.getAsOpaquePtr()); + if (is_signed) { + if (bit_size == ast.getTypeSize(ast.SignedCharTy)) + return GetType(ast.SignedCharTy); - if (bit_size == ast->getTypeSize(ast->IntTy)) - return CompilerType(clang_ast_context, ast->IntTy.getAsOpaquePtr()); + if (bit_size == ast.getTypeSize(ast.ShortTy)) + return GetType(ast.ShortTy); - if (bit_size == ast->getTypeSize(ast->LongTy)) - return CompilerType(clang_ast_context, ast->LongTy.getAsOpaquePtr()); + if (bit_size == ast.getTypeSize(ast.IntTy)) + return GetType(ast.IntTy); - if (bit_size == ast->getTypeSize(ast->LongLongTy)) - return CompilerType(clang_ast_context, - ast->LongLongTy.getAsOpaquePtr()); + if (bit_size == ast.getTypeSize(ast.LongTy)) + return GetType(ast.LongTy); - if (bit_size == ast->getTypeSize(ast->Int128Ty)) - return CompilerType(clang_ast_context, ast->Int128Ty.getAsOpaquePtr()); - } else { - if (bit_size == ast->getTypeSize(ast->UnsignedCharTy)) - return CompilerType(clang_ast_context, - ast->UnsignedCharTy.getAsOpaquePtr()); + if (bit_size == ast.getTypeSize(ast.LongLongTy)) + return GetType(ast.LongLongTy); - if (bit_size == ast->getTypeSize(ast->UnsignedShortTy)) - return CompilerType(clang_ast_context, - ast->UnsignedShortTy.getAsOpaquePtr()); + if (bit_size == ast.getTypeSize(ast.Int128Ty)) + return GetType(ast.Int128Ty); + } else { + if (bit_size == ast.getTypeSize(ast.UnsignedCharTy)) + return GetType(ast.UnsignedCharTy); - if (bit_size == ast->getTypeSize(ast->UnsignedIntTy)) - return CompilerType(clang_ast_context, - ast->UnsignedIntTy.getAsOpaquePtr()); + if (bit_size == ast.getTypeSize(ast.UnsignedShortTy)) + return GetType(ast.UnsignedShortTy); - if (bit_size == ast->getTypeSize(ast->UnsignedLongTy)) - return CompilerType(clang_ast_context, - ast->UnsignedLongTy.getAsOpaquePtr()); + if (bit_size == ast.getTypeSize(ast.UnsignedIntTy)) + return GetType(ast.UnsignedIntTy); - if (bit_size == ast->getTypeSize(ast->UnsignedLongLongTy)) - return CompilerType(clang_ast_context, - ast->UnsignedLongLongTy.getAsOpaquePtr()); + if (bit_size == ast.getTypeSize(ast.UnsignedLongTy)) + return GetType(ast.UnsignedLongTy); - if (bit_size == ast->getTypeSize(ast->UnsignedInt128Ty)) - return CompilerType(clang_ast_context, - ast->UnsignedInt128Ty.getAsOpaquePtr()); - } + if (bit_size == ast.getTypeSize(ast.UnsignedLongLongTy)) + return GetType(ast.UnsignedLongLongTy); + + if (bit_size == ast.getTypeSize(ast.UnsignedInt128Ty)) + return GetType(ast.UnsignedInt128Ty); } return CompilerType(); } -CompilerType ClangASTContext::GetPointerSizedIntType(clang::ASTContext *ast, - bool is_signed) { - if (ast) - return GetIntTypeFromBitSize(ast, ast->getTypeSize(ast->VoidPtrTy), - is_signed); - return CompilerType(); +CompilerType ClangASTContext::GetPointerSizedIntType(bool is_signed) { + return GetIntTypeFromBitSize( + getASTContext().getTypeSize(getASTContext().VoidPtrTy), is_signed); } void ClangASTContext::DumpDeclContextHiearchy(clang::DeclContext *decl_ctx) { @@ -2479,41 +2262,42 @@ bool ClangASTContext::GetCompleteDecl(clang::ASTContext *ast, } } -void ClangASTContext::SetMetadataAsUserID(const void *object, +void ClangASTContext::SetMetadataAsUserID(const clang::Decl *decl, user_id_t user_id) { ClangASTMetadata meta_data; meta_data.SetUserID(user_id); - SetMetadata(object, meta_data); + SetMetadata(decl, meta_data); } -void ClangASTContext::SetMetadata(clang::ASTContext *ast, const void *object, - ClangASTMetadata &metadata) { - ClangExternalASTSourceCommon *external_source = - ClangExternalASTSourceCommon::Lookup(ast->getExternalSource()); - - if (external_source) - external_source->SetMetadata(object, metadata); +void ClangASTContext::SetMetadataAsUserID(const clang::Type *type, + user_id_t user_id) { + ClangASTMetadata meta_data; + meta_data.SetUserID(user_id); + SetMetadata(type, meta_data); } -ClangASTMetadata *ClangASTContext::GetMetadata(clang::ASTContext *ast, - const void *object) { - ClangExternalASTSourceCommon *external_source = - ClangExternalASTSourceCommon::Lookup(ast->getExternalSource()); +void ClangASTContext::SetMetadata(const clang::Decl *object, + ClangASTMetadata &metadata) { + m_decl_metadata[object] = metadata; +} - if (external_source && external_source->HasMetadata(object)) - return external_source->GetMetadata(object); - else - return nullptr; +void ClangASTContext::SetMetadata(const clang::Type *object, + ClangASTMetadata &metadata) { + m_type_metadata[object] = metadata; } -clang::DeclContext * -ClangASTContext::GetAsDeclContext(clang::CXXMethodDecl *cxx_method_decl) { - return llvm::dyn_cast<clang::DeclContext>(cxx_method_decl); +ClangASTMetadata *ClangASTContext::GetMetadata(const clang::Decl *object) { + auto It = m_decl_metadata.find(object); + if (It != m_decl_metadata.end()) + return &It->second; + return nullptr; } -clang::DeclContext * -ClangASTContext::GetAsDeclContext(clang::ObjCMethodDecl *objc_method_decl) { - return llvm::dyn_cast<clang::DeclContext>(objc_method_decl); +ClangASTMetadata *ClangASTContext::GetMetadata(const clang::Type *object) { + auto It = m_type_metadata.find(object); + if (It != m_type_metadata.end()) + return &It->second; + return nullptr; } bool ClangASTContext::SetTagTypeKind(clang::QualType tag_qual_type, @@ -2557,12 +2341,42 @@ ClangASTContext::GetDeclContextForType(const CompilerType &type) { return GetDeclContextForType(ClangUtil::GetQualType(type)); } +/// Aggressively desugar the provided type, skipping past various kinds of +/// syntactic sugar and other constructs one typically wants to ignore. +/// The \p mask argument allows one to skip certain kinds of simplifications, +/// when one wishes to handle a certain kind of type directly. +static QualType +RemoveWrappingTypes(QualType type, ArrayRef<clang::Type::TypeClass> mask = {}) { + while (true) { + if (find(mask, type->getTypeClass()) != mask.end()) + return type; + switch (type->getTypeClass()) { + // This is not fully correct as _Atomic is more than sugar, but it is + // sufficient for the purposes we care about. + case clang::Type::Atomic: + type = cast<clang::AtomicType>(type)->getValueType(); + break; + case clang::Type::Auto: + case clang::Type::Decltype: + case clang::Type::Elaborated: + case clang::Type::Paren: + case clang::Type::Typedef: + case clang::Type::TypeOf: + case clang::Type::TypeOfExpr: + type = type->getLocallyUnqualifiedSingleStepDesugaredType(); + break; + default: + return type; + } + } +} + clang::DeclContext * ClangASTContext::GetDeclContextForType(clang::QualType type) { if (type.isNull()) return nullptr; - clang::QualType qual_type = type.getCanonicalType(); + clang::QualType qual_type = RemoveWrappingTypes(type.getCanonicalType()); const clang::Type::TypeClass type_class = qual_type->getTypeClass(); switch (type_class) { case clang::Type::ObjCInterface: @@ -2576,19 +2390,6 @@ ClangASTContext::GetDeclContextForType(clang::QualType type) { return llvm::cast<clang::RecordType>(qual_type)->getDecl(); case clang::Type::Enum: return llvm::cast<clang::EnumType>(qual_type)->getDecl(); - case clang::Type::Typedef: - return GetDeclContextForType(llvm::cast<clang::TypedefType>(qual_type) - ->getDecl() - ->getUnderlyingType()); - case clang::Type::Auto: - return GetDeclContextForType( - llvm::cast<clang::AutoType>(qual_type)->getDeducedType()); - case clang::Type::Elaborated: - return GetDeclContextForType( - llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()); - case clang::Type::Paren: - return GetDeclContextForType( - llvm::cast<clang::ParenType>(qual_type)->desugar()); default: break; } @@ -2599,6 +2400,7 @@ ClangASTContext::GetDeclContextForType(clang::QualType type) { static bool GetCompleteQualType(clang::ASTContext *ast, clang::QualType qual_type, bool allow_completion = true) { + qual_type = RemoveWrappingTypes(qual_type); const clang::Type::TypeClass type_class = qual_type->getTypeClass(); switch (type_class) { case clang::Type::ConstantArray: @@ -2700,27 +2502,6 @@ static bool GetCompleteQualType(clang::ASTContext *ast, } } break; - case clang::Type::Typedef: - return GetCompleteQualType(ast, llvm::cast<clang::TypedefType>(qual_type) - ->getDecl() - ->getUnderlyingType(), - allow_completion); - - case clang::Type::Auto: - return GetCompleteQualType( - ast, llvm::cast<clang::AutoType>(qual_type)->getDeducedType(), - allow_completion); - - case clang::Type::Elaborated: - return GetCompleteQualType( - ast, llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType(), - allow_completion); - - case clang::Type::Paren: - return GetCompleteQualType( - ast, llvm::cast<clang::ParenType>(qual_type)->desugar(), - allow_completion); - case clang::Type::Attributed: return GetCompleteQualType( ast, llvm::cast<clang::AttributedType>(qual_type)->getModifiedType(), @@ -2753,7 +2534,7 @@ ConvertAccessTypeToObjCIvarAccessControl(AccessType access) { // Tests bool ClangASTContext::IsAggregateType(lldb::opaque_compiler_type_t type) { - clang::QualType qual_type(GetCanonicalQualType(type)); + clang::QualType qual_type(RemoveWrappingTypes(GetCanonicalQualType(type))); const clang::Type::TypeClass type_class = qual_type->getTypeClass(); switch (type_class) { @@ -2766,22 +2547,6 @@ bool ClangASTContext::IsAggregateType(lldb::opaque_compiler_type_t type) { case clang::Type::ObjCObject: case clang::Type::ObjCInterface: return true; - case clang::Type::Auto: - return IsAggregateType(llvm::cast<clang::AutoType>(qual_type) - ->getDeducedType() - .getAsOpaquePtr()); - case clang::Type::Elaborated: - return IsAggregateType(llvm::cast<clang::ElaboratedType>(qual_type) - ->getNamedType() - .getAsOpaquePtr()); - case clang::Type::Typedef: - return IsAggregateType(llvm::cast<clang::TypedefType>(qual_type) - ->getDecl() - ->getUnderlyingType() - .getAsOpaquePtr()); - case clang::Type::Paren: - return IsAggregateType( - llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr()); default: break; } @@ -2790,7 +2555,7 @@ bool ClangASTContext::IsAggregateType(lldb::opaque_compiler_type_t type) { } bool ClangASTContext::IsAnonymousType(lldb::opaque_compiler_type_t type) { - clang::QualType qual_type(GetCanonicalQualType(type)); + clang::QualType qual_type(RemoveWrappingTypes(GetCanonicalQualType(type))); const clang::Type::TypeClass type_class = qual_type->getTypeClass(); switch (type_class) { @@ -2804,22 +2569,6 @@ bool ClangASTContext::IsAnonymousType(lldb::opaque_compiler_type_t type) { } break; } - case clang::Type::Auto: - return IsAnonymousType(llvm::cast<clang::AutoType>(qual_type) - ->getDeducedType() - .getAsOpaquePtr()); - case clang::Type::Elaborated: - return IsAnonymousType(llvm::cast<clang::ElaboratedType>(qual_type) - ->getNamedType() - .getAsOpaquePtr()); - case clang::Type::Typedef: - return IsAnonymousType(llvm::cast<clang::TypedefType>(qual_type) - ->getDecl() - ->getUnderlyingType() - .getAsOpaquePtr()); - case clang::Type::Paren: - return IsAnonymousType( - llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr()); default: break; } @@ -2830,7 +2579,7 @@ bool ClangASTContext::IsAnonymousType(lldb::opaque_compiler_type_t type) { bool ClangASTContext::IsArrayType(lldb::opaque_compiler_type_t type, CompilerType *element_type_ptr, uint64_t *size, bool *is_incomplete) { - clang::QualType qual_type(GetCanonicalQualType(type)); + clang::QualType qual_type(RemoveWrappingTypes(GetCanonicalQualType(type))); const clang::Type::TypeClass type_class = qual_type->getTypeClass(); switch (type_class) { @@ -2886,27 +2635,6 @@ bool ClangASTContext::IsArrayType(lldb::opaque_compiler_type_t type, if (is_incomplete) *is_incomplete = false; return true; - - case clang::Type::Typedef: - return IsArrayType(llvm::cast<clang::TypedefType>(qual_type) - ->getDecl() - ->getUnderlyingType() - .getAsOpaquePtr(), - element_type_ptr, size, is_incomplete); - case clang::Type::Auto: - return IsArrayType(llvm::cast<clang::AutoType>(qual_type) - ->getDeducedType() - .getAsOpaquePtr(), - element_type_ptr, size, is_incomplete); - case clang::Type::Elaborated: - return IsArrayType(llvm::cast<clang::ElaboratedType>(qual_type) - ->getNamedType() - .getAsOpaquePtr(), - element_type_ptr, size, is_incomplete); - case clang::Type::Paren: - return IsArrayType( - llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(), - element_type_ptr, size, is_incomplete); } if (element_type_ptr) element_type_ptr->Clear(); @@ -2930,8 +2658,7 @@ bool ClangASTContext::IsVectorType(lldb::opaque_compiler_type_t type, if (size) *size = vector_type->getNumElements(); if (element_type) - *element_type = - CompilerType(this, vector_type->getElementType().getAsOpaquePtr()); + *element_type = GetType(vector_type->getElementType()); } return true; } break; @@ -2955,8 +2682,7 @@ bool ClangASTContext::IsVectorType(lldb::opaque_compiler_type_t type, bool ClangASTContext::IsRuntimeGeneratedType( lldb::opaque_compiler_type_t type) { - clang::DeclContext *decl_ctx = ClangASTContext::GetASTContext(getASTContext()) - ->GetDeclContextForType(GetQualType(type)); + clang::DeclContext *decl_ctx = GetDeclContextForType(GetQualType(type)); if (!decl_ctx) return false; @@ -2966,8 +2692,7 @@ bool ClangASTContext::IsRuntimeGeneratedType( clang::ObjCInterfaceDecl *result_iface_decl = llvm::dyn_cast<clang::ObjCInterfaceDecl>(decl_ctx); - ClangASTMetadata *ast_metadata = - ClangASTContext::GetMetadata(getASTContext(), result_iface_decl); + ClangASTMetadata *ast_metadata = GetMetadata(result_iface_decl); if (!ast_metadata) return false; return (ast_metadata->GetISAPtr() != 0); @@ -2979,7 +2704,7 @@ bool ClangASTContext::IsCharType(lldb::opaque_compiler_type_t type) { bool ClangASTContext::IsCompleteType(lldb::opaque_compiler_type_t type) { const bool allow_completion = false; - return GetCompleteQualType(getASTContext(), GetQualType(type), + return GetCompleteQualType(&getASTContext(), GetQualType(type), allow_completion); } @@ -3015,7 +2740,7 @@ bool ClangASTContext::IsCStringType(lldb::opaque_compiler_type_t type, bool ClangASTContext::IsFunctionType(lldb::opaque_compiler_type_t type, bool *is_variadic_ptr) { if (type) { - clang::QualType qual_type(GetCanonicalQualType(type)); + clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type)); if (qual_type->isFunctionType()) { if (is_variadic_ptr) { @@ -3033,26 +2758,6 @@ bool ClangASTContext::IsFunctionType(lldb::opaque_compiler_type_t type, switch (type_class) { default: break; - case clang::Type::Typedef: - return IsFunctionType(llvm::cast<clang::TypedefType>(qual_type) - ->getDecl() - ->getUnderlyingType() - .getAsOpaquePtr(), - nullptr); - case clang::Type::Auto: - return IsFunctionType(llvm::cast<clang::AutoType>(qual_type) - ->getDeducedType() - .getAsOpaquePtr(), - nullptr); - case clang::Type::Elaborated: - return IsFunctionType(llvm::cast<clang::ElaboratedType>(qual_type) - ->getNamedType() - .getAsOpaquePtr(), - nullptr); - case clang::Type::Paren: - return IsFunctionType( - llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(), - nullptr); case clang::Type::LValueReference: case clang::Type::RValueReference: { const clang::ReferenceType *reference_type = @@ -3073,7 +2778,7 @@ ClangASTContext::IsHomogeneousAggregate(lldb::opaque_compiler_type_t type, if (!type) return 0; - clang::QualType qual_type(GetCanonicalQualType(type)); + clang::QualType qual_type(RemoveWrappingTypes(GetCanonicalQualType(type))); const clang::Type::TypeClass type_class = qual_type->getTypeClass(); switch (type_class) { case clang::Type::Record: @@ -3101,7 +2806,7 @@ ClangASTContext::IsHomogeneousAggregate(lldb::opaque_compiler_type_t type, for (field_pos = record_decl->field_begin(); field_pos != field_end; ++field_pos) { clang::QualType field_qual_type = field_pos->getType(); - uint64_t field_bitwidth = getASTContext()->getTypeSize(qual_type); + uint64_t field_bitwidth = getASTContext().getTypeSize(qual_type); if (field_qual_type->isFloatingType()) { if (field_qual_type->isComplexType()) return 0; @@ -3143,24 +2848,6 @@ ClangASTContext::IsHomogeneousAggregate(lldb::opaque_compiler_type_t type, } break; - case clang::Type::Typedef: - return IsHomogeneousAggregate(llvm::cast<clang::TypedefType>(qual_type) - ->getDecl() - ->getUnderlyingType() - .getAsOpaquePtr(), - base_type_ptr); - - case clang::Type::Auto: - return IsHomogeneousAggregate(llvm::cast<clang::AutoType>(qual_type) - ->getDeducedType() - .getAsOpaquePtr(), - base_type_ptr); - - case clang::Type::Elaborated: - return IsHomogeneousAggregate(llvm::cast<clang::ElaboratedType>(qual_type) - ->getNamedType() - .getAsOpaquePtr(), - base_type_ptr); default: break; } @@ -3196,7 +2883,7 @@ ClangASTContext::GetFunctionArgumentAtIndex(lldb::opaque_compiler_type_t type, bool ClangASTContext::IsFunctionPointerType(lldb::opaque_compiler_type_t type) { if (type) { - clang::QualType qual_type(GetCanonicalQualType(type)); + clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type)); if (qual_type->isFunctionPointerType()) return true; @@ -3205,22 +2892,6 @@ bool ClangASTContext::IsFunctionPointerType(lldb::opaque_compiler_type_t type) { switch (type_class) { default: break; - case clang::Type::Typedef: - return IsFunctionPointerType(llvm::cast<clang::TypedefType>(qual_type) - ->getDecl() - ->getUnderlyingType() - .getAsOpaquePtr()); - case clang::Type::Auto: - return IsFunctionPointerType(llvm::cast<clang::AutoType>(qual_type) - ->getDeducedType() - .getAsOpaquePtr()); - case clang::Type::Elaborated: - return IsFunctionPointerType(llvm::cast<clang::ElaboratedType>(qual_type) - ->getNamedType() - .getAsOpaquePtr()); - case clang::Type::Paren: - return IsFunctionPointerType( - llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr()); case clang::Type::LValueReference: case clang::Type::RValueReference: { @@ -3239,7 +2910,7 @@ bool ClangASTContext::IsBlockPointerType( lldb::opaque_compiler_type_t type, CompilerType *function_pointer_type_ptr) { if (type) { - clang::QualType qual_type(GetCanonicalQualType(type)); + clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type)); if (qual_type->isBlockPointerType()) { if (function_pointer_type_ptr) { @@ -3257,26 +2928,6 @@ bool ClangASTContext::IsBlockPointerType( switch (type_class) { default: break; - case clang::Type::Typedef: - return IsBlockPointerType(llvm::cast<clang::TypedefType>(qual_type) - ->getDecl() - ->getUnderlyingType() - .getAsOpaquePtr(), - function_pointer_type_ptr); - case clang::Type::Auto: - return IsBlockPointerType(llvm::cast<clang::AutoType>(qual_type) - ->getDeducedType() - .getAsOpaquePtr(), - function_pointer_type_ptr); - case clang::Type::Elaborated: - return IsBlockPointerType(llvm::cast<clang::ElaboratedType>(qual_type) - ->getNamedType() - .getAsOpaquePtr(), - function_pointer_type_ptr); - case clang::Type::Paren: - return IsBlockPointerType( - llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(), - function_pointer_type_ptr); case clang::Type::LValueReference: case clang::Type::RValueReference: { @@ -3330,7 +2981,7 @@ bool ClangASTContext::IsEnumerationType(lldb::opaque_compiler_type_t type, bool ClangASTContext::IsPointerType(lldb::opaque_compiler_type_t type, CompilerType *pointee_type) { if (type) { - clang::QualType qual_type(GetCanonicalQualType(type)); + clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type)); const clang::Type::TypeClass type_class = qual_type->getTypeClass(); switch (type_class) { case clang::Type::Builtin: @@ -3370,26 +3021,6 @@ bool ClangASTContext::IsPointerType(lldb::opaque_compiler_type_t type, ->getPointeeType() .getAsOpaquePtr()); return true; - case clang::Type::Typedef: - return IsPointerType(llvm::cast<clang::TypedefType>(qual_type) - ->getDecl() - ->getUnderlyingType() - .getAsOpaquePtr(), - pointee_type); - case clang::Type::Auto: - return IsPointerType(llvm::cast<clang::AutoType>(qual_type) - ->getDeducedType() - .getAsOpaquePtr(), - pointee_type); - case clang::Type::Elaborated: - return IsPointerType(llvm::cast<clang::ElaboratedType>(qual_type) - ->getNamedType() - .getAsOpaquePtr(), - pointee_type); - case clang::Type::Paren: - return IsPointerType( - llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(), - pointee_type); default: break; } @@ -3402,7 +3033,7 @@ bool ClangASTContext::IsPointerType(lldb::opaque_compiler_type_t type, bool ClangASTContext::IsPointerOrReferenceType( lldb::opaque_compiler_type_t type, CompilerType *pointee_type) { if (type) { - clang::QualType qual_type(GetCanonicalQualType(type)); + clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type)); const clang::Type::TypeClass type_class = qual_type->getTypeClass(); switch (type_class) { case clang::Type::Builtin: @@ -3455,27 +3086,6 @@ bool ClangASTContext::IsPointerOrReferenceType( ->desugar() .getAsOpaquePtr()); return true; - case clang::Type::Typedef: - return IsPointerOrReferenceType(llvm::cast<clang::TypedefType>(qual_type) - ->getDecl() - ->getUnderlyingType() - .getAsOpaquePtr(), - pointee_type); - case clang::Type::Auto: - return IsPointerOrReferenceType(llvm::cast<clang::AutoType>(qual_type) - ->getDeducedType() - .getAsOpaquePtr(), - pointee_type); - case clang::Type::Elaborated: - return IsPointerOrReferenceType( - llvm::cast<clang::ElaboratedType>(qual_type) - ->getNamedType() - .getAsOpaquePtr(), - pointee_type); - case clang::Type::Paren: - return IsPointerOrReferenceType( - llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(), - pointee_type); default: break; } @@ -3489,7 +3099,7 @@ bool ClangASTContext::IsReferenceType(lldb::opaque_compiler_type_t type, CompilerType *pointee_type, bool *is_rvalue) { if (type) { - clang::QualType qual_type(GetCanonicalQualType(type)); + clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type)); const clang::Type::TypeClass type_class = qual_type->getTypeClass(); switch (type_class) { @@ -3511,26 +3121,6 @@ bool ClangASTContext::IsReferenceType(lldb::opaque_compiler_type_t type, if (is_rvalue) *is_rvalue = true; return true; - case clang::Type::Typedef: - return IsReferenceType(llvm::cast<clang::TypedefType>(qual_type) - ->getDecl() - ->getUnderlyingType() - .getAsOpaquePtr(), - pointee_type, is_rvalue); - case clang::Type::Auto: - return IsReferenceType(llvm::cast<clang::AutoType>(qual_type) - ->getDeducedType() - .getAsOpaquePtr(), - pointee_type, is_rvalue); - case clang::Type::Elaborated: - return IsReferenceType(llvm::cast<clang::ElaboratedType>(qual_type) - ->getNamedType() - .getAsOpaquePtr(), - pointee_type, is_rvalue); - case clang::Type::Paren: - return IsReferenceType( - llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(), - pointee_type, is_rvalue); default: break; @@ -3606,7 +3196,7 @@ bool ClangASTContext::IsDefined(lldb::opaque_compiler_type_t type) { } bool ClangASTContext::IsObjCClassType(const CompilerType &type) { - if (type) { + if (ClangUtil::IsClangType(type)) { clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type)); const clang::ObjCObjectPointerType *obj_pointer_type = @@ -3672,7 +3262,7 @@ bool ClangASTContext::IsPossibleDynamicType(lldb::opaque_compiler_type_t type, bool check_objc) { clang::QualType pointee_qual_type; if (type) { - clang::QualType qual_type(GetCanonicalQualType(type)); + clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type)); bool success = false; const clang::Type::TypeClass type_class = qual_type->getTypeClass(); switch (type_class) { @@ -3719,32 +3309,6 @@ bool ClangASTContext::IsPossibleDynamicType(lldb::opaque_compiler_type_t type, success = true; break; - case clang::Type::Typedef: - return IsPossibleDynamicType(llvm::cast<clang::TypedefType>(qual_type) - ->getDecl() - ->getUnderlyingType() - .getAsOpaquePtr(), - dynamic_pointee_type, check_cplusplus, - check_objc); - - case clang::Type::Auto: - return IsPossibleDynamicType(llvm::cast<clang::AutoType>(qual_type) - ->getDeducedType() - .getAsOpaquePtr(), - dynamic_pointee_type, check_cplusplus, - check_objc); - - case clang::Type::Elaborated: - return IsPossibleDynamicType(llvm::cast<clang::ElaboratedType>(qual_type) - ->getNamedType() - .getAsOpaquePtr(), - dynamic_pointee_type, check_cplusplus, - check_objc); - - case clang::Type::Paren: - return IsPossibleDynamicType( - llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(), - dynamic_pointee_type, check_cplusplus, check_objc); default: break; } @@ -3779,14 +3343,11 @@ bool ClangASTContext::IsPossibleDynamicType(lldb::opaque_compiler_type_t type, if (is_complete) success = cxx_record_decl->isDynamicClass(); else { - ClangASTMetadata *metadata = ClangASTContext::GetMetadata( - getASTContext(), cxx_record_decl); + ClangASTMetadata *metadata = GetMetadata(cxx_record_decl); if (metadata) success = metadata->GetIsDynamicCXXType(); else { - is_complete = - CompilerType(this, pointee_qual_type.getAsOpaquePtr()) - .GetCompleteType(); + is_complete = GetType(pointee_qual_type).GetCompleteType(); if (is_complete) success = cxx_record_decl->isDynamicClass(); else @@ -3855,20 +3416,20 @@ bool ClangASTContext::SupportsLanguage(lldb::LanguageType language) { return ClangASTContextSupportsLanguage(language); } -bool ClangASTContext::GetCXXClassName(const CompilerType &type, - std::string &class_name) { - if (type) { - clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type)); - if (!qual_type.isNull()) { - clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl(); - if (cxx_record_decl) { - class_name.assign(cxx_record_decl->getIdentifier()->getNameStart()); - return true; - } - } - } - class_name.clear(); - return false; +Optional<std::string> +ClangASTContext::GetCXXClassName(const CompilerType &type) { + if (!type) + return llvm::None; + + clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type)); + if (qual_type.isNull()) + return llvm::None; + + clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl(); + if (!cxx_record_decl) + return llvm::None; + + return std::string(cxx_record_decl->getIdentifier()->getNameStart()); } bool ClangASTContext::IsCXXClassType(const CompilerType &type) { @@ -3891,7 +3452,7 @@ bool ClangASTContext::IsBeingDefined(lldb::opaque_compiler_type_t type) { bool ClangASTContext::IsObjCObjectPointerType(const CompilerType &type, CompilerType *class_type_ptr) { - if (!type) + if (!ClangUtil::IsClangType(type)) return false; clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type)); @@ -3923,14 +3484,14 @@ bool ClangASTContext::GetCompleteType(lldb::opaque_compiler_type_t type) { if (!type) return false; const bool allow_completion = true; - return GetCompleteQualType(getASTContext(), GetQualType(type), + return GetCompleteQualType(&getASTContext(), GetQualType(type), allow_completion); } ConstString ClangASTContext::GetTypeName(lldb::opaque_compiler_type_t type) { std::string type_name; if (type) { - clang::PrintingPolicy printing_policy(getASTContext()->getPrintingPolicy()); + clang::PrintingPolicy printing_policy(getASTContext().getPrintingPolicy()); clang::QualType qual_type(GetQualType(type)); printing_policy.SuppressTagKeyword = true; const clang::TypedefType *typedef_type = @@ -3954,7 +3515,8 @@ ClangASTContext::GetTypeInfo(lldb::opaque_compiler_type_t type, if (pointee_or_element_clang_type) pointee_or_element_clang_type->Clear(); - clang::QualType qual_type(GetQualType(type)); + clang::QualType qual_type = + RemoveWrappingTypes(GetQualType(type), {clang::Type::Typedef}); const clang::Type::TypeClass type_class = qual_type->getTypeClass(); switch (type_class) { @@ -3973,14 +3535,14 @@ ClangASTContext::GetTypeInfo(lldb::opaque_compiler_type_t type, case clang::BuiltinType::ObjCClass: if (pointee_or_element_clang_type) pointee_or_element_clang_type->SetCompilerType( - this, getASTContext()->ObjCBuiltinClassTy.getAsOpaquePtr()); + this, getASTContext().ObjCBuiltinClassTy.getAsOpaquePtr()); builtin_type_flags |= eTypeIsPointer | eTypeIsObjC; break; case clang::BuiltinType::ObjCSel: if (pointee_or_element_clang_type) pointee_or_element_clang_type->SetCompilerType( - this, getASTContext()->CharTy.getAsOpaquePtr()); + this, getASTContext().CharTy.getAsOpaquePtr()); builtin_type_flags |= eTypeIsPointer | eTypeIsObjC; break; @@ -4058,11 +3620,6 @@ ClangASTContext::GetTypeInfo(lldb::opaque_compiler_type_t type, return eTypeHasChildren | eTypeIsVector; case clang::Type::DependentTemplateSpecialization: return eTypeIsTemplate; - case clang::Type::Decltype: - return CompilerType(this, llvm::cast<clang::DecltypeType>(qual_type) - ->getUnderlyingType() - .getAsOpaquePtr()) - .GetTypeInfo(pointee_or_element_clang_type); case clang::Type::Enum: if (pointee_or_element_clang_type) @@ -4073,22 +3630,6 @@ ClangASTContext::GetTypeInfo(lldb::opaque_compiler_type_t type, .getAsOpaquePtr()); return eTypeIsEnumeration | eTypeHasValue; - case clang::Type::Auto: - return CompilerType(this, llvm::cast<clang::AutoType>(qual_type) - ->getDeducedType() - .getAsOpaquePtr()) - .GetTypeInfo(pointee_or_element_clang_type); - case clang::Type::Elaborated: - return CompilerType(this, llvm::cast<clang::ElaboratedType>(qual_type) - ->getNamedType() - .getAsOpaquePtr()) - .GetTypeInfo(pointee_or_element_clang_type); - case clang::Type::Paren: - return CompilerType(this, llvm::cast<clang::ParenType>(qual_type) - ->desugar() - .getAsOpaquePtr()) - .GetTypeInfo(pointee_or_element_clang_type); - case clang::Type::FunctionProto: return eTypeIsFuncPrototype | eTypeHasValue; case clang::Type::FunctionNoProto: @@ -4140,23 +3681,10 @@ ClangASTContext::GetTypeInfo(lldb::opaque_compiler_type_t type, return eTypeIsTemplate; case clang::Type::Typedef: - return eTypeIsTypedef | - CompilerType(this, llvm::cast<clang::TypedefType>(qual_type) - ->getDecl() - ->getUnderlyingType() - .getAsOpaquePtr()) - .GetTypeInfo(pointee_or_element_clang_type); - case clang::Type::TypeOfExpr: - return CompilerType(this, llvm::cast<clang::TypeOfExprType>(qual_type) - ->getUnderlyingExpr() - ->getType() - .getAsOpaquePtr()) - .GetTypeInfo(pointee_or_element_clang_type); - case clang::Type::TypeOf: - return CompilerType(this, llvm::cast<clang::TypeOfType>(qual_type) - ->getUnderlyingType() - .getAsOpaquePtr()) - .GetTypeInfo(pointee_or_element_clang_type); + return eTypeIsTypedef | GetType(llvm::cast<clang::TypedefType>(qual_type) + ->getDecl() + ->getUnderlyingType()) + .GetTypeInfo(pointee_or_element_clang_type); case clang::Type::UnresolvedUsing: return 0; @@ -4200,7 +3728,7 @@ ClangASTContext::GetMinimumLanguage(lldb::opaque_compiler_type_t type) { if (pointee_type->isObjCClassType()) return lldb::eLanguageTypeObjC; if (pointee_type.getTypePtr() == - getASTContext()->ObjCBuiltinIdTy.getTypePtr()) + getASTContext().ObjCBuiltinIdTy.getTypePtr()) return lldb::eLanguageTypeObjC; } else { if (qual_type->isObjCObjectOrInterfaceType()) @@ -4254,10 +3782,9 @@ ClangASTContext::GetMinimumLanguage(lldb::opaque_compiler_type_t type) { } break; case clang::Type::Typedef: - return CompilerType(this, llvm::cast<clang::TypedefType>(qual_type) - ->getDecl() - ->getUnderlyingType() - .getAsOpaquePtr()) + return GetType(llvm::cast<clang::TypedefType>(qual_type) + ->getDecl() + ->getUnderlyingType()) .GetMinimumLanguage(); } } @@ -4269,9 +3796,18 @@ ClangASTContext::GetTypeClass(lldb::opaque_compiler_type_t type) { if (!type) return lldb::eTypeClassInvalid; - clang::QualType qual_type(GetQualType(type)); + clang::QualType qual_type = + RemoveWrappingTypes(GetQualType(type), {clang::Type::Typedef}); switch (qual_type->getTypeClass()) { + case clang::Type::Atomic: + case clang::Type::Auto: + case clang::Type::Decltype: + case clang::Type::Elaborated: + case clang::Type::Paren: + case clang::Type::TypeOf: + case clang::Type::TypeOfExpr: + llvm_unreachable("Handled in RemoveWrappingTypes!"); case clang::Type::UnaryTransform: break; case clang::Type::FunctionNoProto: @@ -4334,21 +3870,6 @@ ClangASTContext::GetTypeClass(lldb::opaque_compiler_type_t type) { return lldb::eTypeClassTypedef; case clang::Type::UnresolvedUsing: break; - case clang::Type::Paren: - return CompilerType(this, llvm::cast<clang::ParenType>(qual_type) - ->desugar() - .getAsOpaquePtr()) - .GetTypeClass(); - case clang::Type::Auto: - return CompilerType(this, llvm::cast<clang::AutoType>(qual_type) - ->getDeducedType() - .getAsOpaquePtr()) - .GetTypeClass(); - case clang::Type::Elaborated: - return CompilerType(this, llvm::cast<clang::ElaboratedType>(qual_type) - ->getNamedType() - .getAsOpaquePtr()) - .GetTypeClass(); case clang::Type::Attributed: break; @@ -4367,28 +3888,10 @@ ClangASTContext::GetTypeClass(lldb::opaque_compiler_type_t type) { case clang::Type::PackExpansion: break; - case clang::Type::TypeOfExpr: - return CompilerType(this, llvm::cast<clang::TypeOfExprType>(qual_type) - ->getUnderlyingExpr() - ->getType() - .getAsOpaquePtr()) - .GetTypeClass(); - case clang::Type::TypeOf: - return CompilerType(this, llvm::cast<clang::TypeOfType>(qual_type) - ->getUnderlyingType() - .getAsOpaquePtr()) - .GetTypeClass(); - case clang::Type::Decltype: - return CompilerType(this, llvm::cast<clang::TypeOfType>(qual_type) - ->getUnderlyingType() - .getAsOpaquePtr()) - .GetTypeClass(); case clang::Type::TemplateSpecialization: break; case clang::Type::DeducedTemplateSpecialization: break; - case clang::Type::Atomic: - break; case clang::Type::Pipe: break; @@ -4421,7 +3924,7 @@ CompilerType ClangASTContext::GetArrayElementType(lldb::opaque_compiler_type_t type, uint64_t *stride) { if (type) { - clang::QualType qual_type(GetCanonicalQualType(type)); + clang::QualType qual_type(GetQualType(type)); const clang::Type *array_eletype = qual_type.getTypePtr()->getArrayElementTypeNoTypeQual(); @@ -4429,8 +3932,7 @@ ClangASTContext::GetArrayElementType(lldb::opaque_compiler_type_t type, if (!array_eletype) return CompilerType(); - CompilerType element_type( - this, array_eletype->getCanonicalTypeUnqualified().getAsOpaquePtr()); + CompilerType element_type = GetType(clang::QualType(array_eletype, 0)); // TODO: the real stride will be >= this value.. find the real one! if (stride) @@ -4446,22 +3948,14 @@ CompilerType ClangASTContext::GetArrayType(lldb::opaque_compiler_type_t type, uint64_t size) { if (type) { clang::QualType qual_type(GetCanonicalQualType(type)); - if (clang::ASTContext *ast_ctx = getASTContext()) { - if (size != 0) - return CompilerType( - this, ast_ctx - ->getConstantArrayType( - qual_type, llvm::APInt(64, size), nullptr, - clang::ArrayType::ArraySizeModifier::Normal, 0) - .getAsOpaquePtr()); - else - return CompilerType( - this, - ast_ctx - ->getIncompleteArrayType( - qual_type, clang::ArrayType::ArraySizeModifier::Normal, 0) - .getAsOpaquePtr()); - } + clang::ASTContext &ast_ctx = getASTContext(); + if (size != 0) + return GetType(ast_ctx.getConstantArrayType( + qual_type, llvm::APInt(64, size), nullptr, + clang::ArrayType::ArraySizeModifier::Normal, 0)); + else + return GetType(ast_ctx.getIncompleteArrayType( + qual_type, clang::ArrayType::ArraySizeModifier::Normal, 0)); } return CompilerType(); @@ -4470,7 +3964,7 @@ CompilerType ClangASTContext::GetArrayType(lldb::opaque_compiler_type_t type, CompilerType ClangASTContext::GetCanonicalType(lldb::opaque_compiler_type_t type) { if (type) - return CompilerType(this, GetCanonicalQualType(type).getAsOpaquePtr()); + return GetType(GetCanonicalQualType(type)); return CompilerType(); } @@ -4490,9 +3984,8 @@ static clang::QualType GetFullyUnqualifiedType_Impl(clang::ASTContext *ast, CompilerType ClangASTContext::GetFullyUnqualifiedType(lldb::opaque_compiler_type_t type) { if (type) - return CompilerType( - this, - GetFullyUnqualifiedType_Impl(getASTContext(), GetQualType(type)).getAsOpaquePtr()); + return GetType( + GetFullyUnqualifiedType_Impl(&getASTContext(), GetQualType(type))); return CompilerType(); } @@ -4515,7 +4008,7 @@ CompilerType ClangASTContext::GetFunctionArgumentTypeAtIndex( if (func) { const uint32_t num_args = func->getNumParams(); if (idx < num_args) - return CompilerType(this, func->getParamType(idx).getAsOpaquePtr()); + return GetType(func->getParamType(idx)); } } return CompilerType(); @@ -4528,7 +4021,7 @@ ClangASTContext::GetFunctionReturnType(lldb::opaque_compiler_type_t type) { const clang::FunctionProtoType *func = llvm::dyn_cast<clang::FunctionProtoType>(qual_type.getTypePtr()); if (func) - return CompilerType(this, func->getReturnType().getAsOpaquePtr()); + return GetType(func->getReturnType()); } return CompilerType(); } @@ -4537,10 +4030,10 @@ size_t ClangASTContext::GetNumMemberFunctions(lldb::opaque_compiler_type_t type) { size_t num_functions = 0; if (type) { - clang::QualType qual_type(GetCanonicalQualType(type)); + clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type)); switch (qual_type->getTypeClass()) { case clang::Type::Record: - if (GetCompleteQualType(getASTContext(), qual_type)) { + if (GetCompleteQualType(&getASTContext(), qual_type)) { const clang::RecordType *record_type = llvm::cast<clang::RecordType>(qual_type.getTypePtr()); const clang::RecordDecl *record_decl = record_type->getDecl(); @@ -4586,31 +4079,6 @@ ClangASTContext::GetNumMemberFunctions(lldb::opaque_compiler_type_t type) { } break; - case clang::Type::Typedef: - return CompilerType(this, llvm::cast<clang::TypedefType>(qual_type) - ->getDecl() - ->getUnderlyingType() - .getAsOpaquePtr()) - .GetNumMemberFunctions(); - - case clang::Type::Auto: - return CompilerType(this, llvm::cast<clang::AutoType>(qual_type) - ->getDeducedType() - .getAsOpaquePtr()) - .GetNumMemberFunctions(); - - case clang::Type::Elaborated: - return CompilerType(this, llvm::cast<clang::ElaboratedType>(qual_type) - ->getNamedType() - .getAsOpaquePtr()) - .GetNumMemberFunctions(); - - case clang::Type::Paren: - return CompilerType(this, llvm::cast<clang::ParenType>(qual_type) - ->desugar() - .getAsOpaquePtr()) - .GetNumMemberFunctions(); - default: break; } @@ -4626,10 +4094,10 @@ ClangASTContext::GetMemberFunctionAtIndex(lldb::opaque_compiler_type_t type, CompilerType clang_type; CompilerDecl clang_decl; if (type) { - clang::QualType qual_type(GetCanonicalQualType(type)); + clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type)); switch (qual_type->getTypeClass()) { case clang::Type::Record: - if (GetCompleteQualType(getASTContext(), qual_type)) { + if (GetCompleteQualType(&getASTContext(), qual_type)) { const clang::RecordType *record_type = llvm::cast<clang::RecordType>(qual_type.getTypePtr()); const clang::RecordDecl *record_decl = record_type->getDecl(); @@ -4654,8 +4122,7 @@ ClangASTContext::GetMemberFunctionAtIndex(lldb::opaque_compiler_type_t type, kind = lldb::eMemberFunctionKindDestructor; else kind = lldb::eMemberFunctionKindInstanceMethod; - clang_type = CompilerType( - this, cxx_method_decl->getType().getAsOpaquePtr()); + clang_type = GetType(cxx_method_decl->getType()); clang_decl = CompilerDecl(this, cxx_method_decl); } } @@ -4725,31 +4192,6 @@ ClangASTContext::GetMemberFunctionAtIndex(lldb::opaque_compiler_type_t type, } break; - case clang::Type::Typedef: - return GetMemberFunctionAtIndex(llvm::cast<clang::TypedefType>(qual_type) - ->getDecl() - ->getUnderlyingType() - .getAsOpaquePtr(), - idx); - - case clang::Type::Auto: - return GetMemberFunctionAtIndex(llvm::cast<clang::AutoType>(qual_type) - ->getDeducedType() - .getAsOpaquePtr(), - idx); - - case clang::Type::Elaborated: - return GetMemberFunctionAtIndex( - llvm::cast<clang::ElaboratedType>(qual_type) - ->getNamedType() - .getAsOpaquePtr(), - idx); - - case clang::Type::Paren: - return GetMemberFunctionAtIndex( - llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(), - idx); - default: break; } @@ -4764,8 +4206,7 @@ ClangASTContext::GetMemberFunctionAtIndex(lldb::opaque_compiler_type_t type, CompilerType ClangASTContext::GetNonReferenceType(lldb::opaque_compiler_type_t type) { if (type) - return CompilerType( - this, GetQualType(type).getNonReferenceType().getAsOpaquePtr()); + return GetType(GetQualType(type).getNonReferenceType()); return CompilerType(); } @@ -4777,25 +4218,25 @@ CompilerType ClangASTContext::CreateTypedefType( llvm::dyn_cast<ClangASTContext>(type.GetTypeSystem()); if (!ast) return CompilerType(); - clang::ASTContext *clang_ast = ast->getASTContext(); + clang::ASTContext &clang_ast = ast->getASTContext(); clang::QualType qual_type(ClangUtil::GetQualType(type)); clang::DeclContext *decl_ctx = ClangASTContext::DeclContextGetAsDeclContext(compiler_decl_ctx); if (decl_ctx == nullptr) - decl_ctx = ast->getASTContext()->getTranslationUnitDecl(); + decl_ctx = ast->getASTContext().getTranslationUnitDecl(); clang::TypedefDecl *decl = clang::TypedefDecl::Create( - *clang_ast, decl_ctx, clang::SourceLocation(), clang::SourceLocation(), - &clang_ast->Idents.get(typedef_name), - clang_ast->getTrivialTypeSourceInfo(qual_type)); + clang_ast, decl_ctx, clang::SourceLocation(), clang::SourceLocation(), + &clang_ast.Idents.get(typedef_name), + clang_ast.getTrivialTypeSourceInfo(qual_type)); decl->setAccess(clang::AS_public); // TODO respect proper access specifier decl_ctx->addDecl(decl); // Get a uniqued clang::QualType for the typedef decl type - return CompilerType(ast, clang_ast->getTypedefType(decl).getAsOpaquePtr()); + return ast->GetType(clang_ast.getTypedefType(decl)); } return CompilerType(); } @@ -4804,8 +4245,7 @@ CompilerType ClangASTContext::GetPointeeType(lldb::opaque_compiler_type_t type) { if (type) { clang::QualType qual_type(GetQualType(type)); - return CompilerType( - this, qual_type.getTypePtr()->getPointeeType().getAsOpaquePtr()); + return GetType(qual_type.getTypePtr()->getPointeeType()); } return CompilerType(); } @@ -4819,13 +4259,10 @@ ClangASTContext::GetPointerType(lldb::opaque_compiler_type_t type) { switch (type_class) { case clang::Type::ObjCObject: case clang::Type::ObjCInterface: - return CompilerType(this, getASTContext() - ->getObjCObjectPointerType(qual_type) - .getAsOpaquePtr()); + return GetType(getASTContext().getObjCObjectPointerType(qual_type)); default: - return CompilerType( - this, getASTContext()->getPointerType(qual_type).getAsOpaquePtr()); + return GetType(getASTContext().getPointerType(qual_type)); } } return CompilerType(); @@ -4834,9 +4271,7 @@ ClangASTContext::GetPointerType(lldb::opaque_compiler_type_t type) { CompilerType ClangASTContext::GetLValueReferenceType(lldb::opaque_compiler_type_t type) { if (type) - return CompilerType(this, getASTContext() - ->getLValueReferenceType(GetQualType(type)) - .getAsOpaquePtr()); + return GetType(getASTContext().getLValueReferenceType(GetQualType(type))); else return CompilerType(); } @@ -4844,19 +4279,23 @@ ClangASTContext::GetLValueReferenceType(lldb::opaque_compiler_type_t type) { CompilerType ClangASTContext::GetRValueReferenceType(lldb::opaque_compiler_type_t type) { if (type) - return CompilerType(this, getASTContext() - ->getRValueReferenceType(GetQualType(type)) - .getAsOpaquePtr()); + return GetType(getASTContext().getRValueReferenceType(GetQualType(type))); else return CompilerType(); } +CompilerType ClangASTContext::GetAtomicType(lldb::opaque_compiler_type_t type) { + if (!type) + return CompilerType(); + return GetType(getASTContext().getAtomicType(GetQualType(type))); +} + CompilerType ClangASTContext::AddConstModifier(lldb::opaque_compiler_type_t type) { if (type) { clang::QualType result(GetQualType(type)); result.addConst(); - return CompilerType(this, result.getAsOpaquePtr()); + return GetType(result); } return CompilerType(); } @@ -4866,7 +4305,7 @@ ClangASTContext::AddVolatileModifier(lldb::opaque_compiler_type_t type) { if (type) { clang::QualType result(GetQualType(type)); result.addVolatile(); - return CompilerType(this, result.getAsOpaquePtr()); + return GetType(result); } return CompilerType(); } @@ -4876,7 +4315,7 @@ ClangASTContext::AddRestrictModifier(lldb::opaque_compiler_type_t type) { if (type) { clang::QualType result(GetQualType(type)); result.addRestrict(); - return CompilerType(this, result.getAsOpaquePtr()); + return GetType(result); } return CompilerType(); } @@ -4886,18 +4325,18 @@ ClangASTContext::CreateTypedef(lldb::opaque_compiler_type_t type, const char *typedef_name, const CompilerDeclContext &compiler_decl_ctx) { if (type) { - clang::ASTContext *clang_ast = getASTContext(); + clang::ASTContext &clang_ast = getASTContext(); clang::QualType qual_type(GetQualType(type)); clang::DeclContext *decl_ctx = ClangASTContext::DeclContextGetAsDeclContext(compiler_decl_ctx); if (decl_ctx == nullptr) - decl_ctx = getASTContext()->getTranslationUnitDecl(); + decl_ctx = getASTContext().getTranslationUnitDecl(); clang::TypedefDecl *decl = clang::TypedefDecl::Create( - *clang_ast, decl_ctx, clang::SourceLocation(), clang::SourceLocation(), - &clang_ast->Idents.get(typedef_name), - clang_ast->getTrivialTypeSourceInfo(qual_type)); + clang_ast, decl_ctx, clang::SourceLocation(), clang::SourceLocation(), + &clang_ast.Idents.get(typedef_name), + clang_ast.getTrivialTypeSourceInfo(qual_type)); clang::TagDecl *tdecl = nullptr; if (!qual_type.isNull()) { @@ -4916,7 +4355,7 @@ ClangASTContext::CreateTypedef(lldb::opaque_compiler_type_t type, decl->setAccess(clang::AS_public); // TODO respect proper access specifier // Get a uniqued clang::QualType for the typedef decl type - return CompilerType(this, clang_ast->getTypedefType(decl).getAsOpaquePtr()); + return GetType(clang_ast.getTypedefType(decl)); } return CompilerType(); } @@ -4927,8 +4366,7 @@ ClangASTContext::GetTypedefedType(lldb::opaque_compiler_type_t type) { const clang::TypedefType *typedef_type = llvm::dyn_cast<clang::TypedefType>(GetQualType(type)); if (typedef_type) - return CompilerType( - this, typedef_type->getDecl()->getUnderlyingType().getAsOpaquePtr()); + return GetType(typedef_type->getDecl()->getUnderlyingType()); } return CompilerType(); } @@ -4936,23 +4374,22 @@ ClangASTContext::GetTypedefedType(lldb::opaque_compiler_type_t type) { // Create related types using the current type's AST CompilerType ClangASTContext::GetBasicTypeFromAST(lldb::BasicType basic_type) { - return ClangASTContext::GetBasicType(getASTContext(), basic_type); + return ClangASTContext::GetBasicType(basic_type); } // Exploring the type const llvm::fltSemantics & ClangASTContext::GetFloatTypeSemantics(size_t byte_size) { - if (auto *ast = getASTContext()) { - const size_t bit_size = byte_size * 8; - if (bit_size == ast->getTypeSize(ast->FloatTy)) - return ast->getFloatTypeSemantics(ast->FloatTy); - else if (bit_size == ast->getTypeSize(ast->DoubleTy)) - return ast->getFloatTypeSemantics(ast->DoubleTy); - else if (bit_size == ast->getTypeSize(ast->LongDoubleTy)) - return ast->getFloatTypeSemantics(ast->LongDoubleTy); - else if (bit_size == ast->getTypeSize(ast->HalfTy)) - return ast->getFloatTypeSemantics(ast->HalfTy); - } + clang::ASTContext &ast = getASTContext(); + const size_t bit_size = byte_size * 8; + if (bit_size == ast.getTypeSize(ast.FloatTy)) + return ast.getFloatTypeSemantics(ast.FloatTy); + else if (bit_size == ast.getTypeSize(ast.DoubleTy)) + return ast.getFloatTypeSemantics(ast.DoubleTy); + else if (bit_size == ast.getTypeSize(ast.LongDoubleTy)) + return ast.getFloatTypeSemantics(ast.LongDoubleTy); + else if (bit_size == ast.getTypeSize(ast.HalfTy)) + return ast.getFloatTypeSemantics(ast.HalfTy); return llvm::APFloatBase::Bogus(); } @@ -4965,7 +4402,7 @@ ClangASTContext::GetBitSize(lldb::opaque_compiler_type_t type, switch (type_class) { case clang::Type::Record: if (GetCompleteType(type)) - return getASTContext()->getTypeSize(qual_type); + return getASTContext().getTypeSize(qual_type); else return None; break; @@ -4978,8 +4415,7 @@ ClangASTContext::GetBitSize(lldb::opaque_compiler_type_t type, ObjCLanguageRuntime *objc_runtime = ObjCLanguageRuntime::Get(*process); if (objc_runtime) { uint64_t bit_size = 0; - if (objc_runtime->GetTypeBitSize( - CompilerType(this, qual_type.getAsOpaquePtr()), bit_size)) + if (objc_runtime->GetTypeBitSize(GetType(qual_type), bit_size)) return bit_size; } } else { @@ -5001,17 +4437,16 @@ ClangASTContext::GetBitSize(lldb::opaque_compiler_type_t type, } LLVM_FALLTHROUGH; default: - const uint32_t bit_size = getASTContext()->getTypeSize(qual_type); + const uint32_t bit_size = getASTContext().getTypeSize(qual_type); if (bit_size == 0) { if (qual_type->isIncompleteArrayType()) - return getASTContext()->getTypeSize( + return getASTContext().getTypeSize( qual_type->getArrayElementTypeNoTypeQual() ->getCanonicalTypeUnqualified()); } if (qual_type->isObjCObjectOrInterfaceType()) return bit_size + - getASTContext()->getTypeSize( - getASTContext()->ObjCBuiltinClassTy); + getASTContext().getTypeSize(getASTContext().ObjCBuiltinClassTy); // Function types actually have a size of 0, that's not an error. if (qual_type->isFunctionProtoType()) return bit_size; @@ -5026,7 +4461,7 @@ llvm::Optional<size_t> ClangASTContext::GetTypeBitAlign(lldb::opaque_compiler_type_t type, ExecutionContextScope *exe_scope) { if (GetCompleteType(type)) - return getASTContext()->getTypeAlign(GetQualType(type)); + return getASTContext().getTypeAlign(GetQualType(type)); return {}; } @@ -5036,9 +4471,19 @@ lldb::Encoding ClangASTContext::GetEncoding(lldb::opaque_compiler_type_t type, return lldb::eEncodingInvalid; count = 1; - clang::QualType qual_type(GetCanonicalQualType(type)); + clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type)); switch (qual_type->getTypeClass()) { + case clang::Type::Atomic: + case clang::Type::Auto: + case clang::Type::Decltype: + case clang::Type::Elaborated: + case clang::Type::Paren: + case clang::Type::Typedef: + case clang::Type::TypeOf: + case clang::Type::TypeOfExpr: + llvm_unreachable("Handled in RemoveWrappingTypes!"); + case clang::Type::UnaryTransform: break; @@ -5228,9 +4673,7 @@ lldb::Encoding ClangASTContext::GetEncoding(lldb::opaque_compiler_type_t type, const clang::ComplexType *complex_type = qual_type->getAsComplexIntegerType(); if (complex_type) - encoding = - CompilerType(this, complex_type->getElementType().getAsOpaquePtr()) - .GetEncoding(count); + encoding = GetType(complex_type->getElementType()).GetEncoding(count); else encoding = lldb::eEncodingSint; } @@ -5244,46 +4687,6 @@ lldb::Encoding ClangASTContext::GetEncoding(lldb::opaque_compiler_type_t type, break; case clang::Type::Enum: return lldb::eEncodingSint; - case clang::Type::Typedef: - return CompilerType(this, llvm::cast<clang::TypedefType>(qual_type) - ->getDecl() - ->getUnderlyingType() - .getAsOpaquePtr()) - .GetEncoding(count); - - case clang::Type::Auto: - return CompilerType(this, llvm::cast<clang::AutoType>(qual_type) - ->getDeducedType() - .getAsOpaquePtr()) - .GetEncoding(count); - - case clang::Type::Elaborated: - return CompilerType(this, llvm::cast<clang::ElaboratedType>(qual_type) - ->getNamedType() - .getAsOpaquePtr()) - .GetEncoding(count); - - case clang::Type::Paren: - return CompilerType(this, llvm::cast<clang::ParenType>(qual_type) - ->desugar() - .getAsOpaquePtr()) - .GetEncoding(count); - case clang::Type::TypeOfExpr: - return CompilerType(this, llvm::cast<clang::TypeOfExprType>(qual_type) - ->getUnderlyingExpr() - ->getType() - .getAsOpaquePtr()) - .GetEncoding(count); - case clang::Type::TypeOf: - return CompilerType(this, llvm::cast<clang::TypeOfType>(qual_type) - ->getUnderlyingType() - .getAsOpaquePtr()) - .GetEncoding(count); - case clang::Type::Decltype: - return CompilerType(this, llvm::cast<clang::DecltypeType>(qual_type) - ->getUnderlyingType() - .getAsOpaquePtr()) - .GetEncoding(count); case clang::Type::DependentSizedArray: case clang::Type::DependentSizedExtVector: case clang::Type::UnresolvedUsing: @@ -5299,7 +4702,6 @@ lldb::Encoding ClangASTContext::GetEncoding(lldb::opaque_compiler_type_t type, case clang::Type::TemplateSpecialization: case clang::Type::DeducedTemplateSpecialization: - case clang::Type::Atomic: case clang::Type::Adjusted: case clang::Type::Pipe: break; @@ -5323,9 +4725,18 @@ lldb::Format ClangASTContext::GetFormat(lldb::opaque_compiler_type_t type) { if (!type) return lldb::eFormatDefault; - clang::QualType qual_type(GetCanonicalQualType(type)); + clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type)); switch (qual_type->getTypeClass()) { + case clang::Type::Atomic: + case clang::Type::Auto: + case clang::Type::Decltype: + case clang::Type::Elaborated: + case clang::Type::Paren: + case clang::Type::Typedef: + case clang::Type::TypeOf: + case clang::Type::TypeOfExpr: + llvm_unreachable("Handled in RemoveWrappingTypes!"); case clang::Type::UnaryTransform: break; @@ -5418,43 +4829,6 @@ lldb::Format ClangASTContext::GetFormat(lldb::opaque_compiler_type_t type) { break; case clang::Type::Enum: return lldb::eFormatEnum; - case clang::Type::Typedef: - return CompilerType(this, llvm::cast<clang::TypedefType>(qual_type) - ->getDecl() - ->getUnderlyingType() - .getAsOpaquePtr()) - .GetFormat(); - case clang::Type::Auto: - return CompilerType(this, llvm::cast<clang::AutoType>(qual_type) - ->desugar() - .getAsOpaquePtr()) - .GetFormat(); - case clang::Type::Paren: - return CompilerType(this, llvm::cast<clang::ParenType>(qual_type) - ->desugar() - .getAsOpaquePtr()) - .GetFormat(); - case clang::Type::Elaborated: - return CompilerType(this, llvm::cast<clang::ElaboratedType>(qual_type) - ->getNamedType() - .getAsOpaquePtr()) - .GetFormat(); - case clang::Type::TypeOfExpr: - return CompilerType(this, llvm::cast<clang::TypeOfExprType>(qual_type) - ->getUnderlyingExpr() - ->getType() - .getAsOpaquePtr()) - .GetFormat(); - case clang::Type::TypeOf: - return CompilerType(this, llvm::cast<clang::TypeOfType>(qual_type) - ->getUnderlyingType() - .getAsOpaquePtr()) - .GetFormat(); - case clang::Type::Decltype: - return CompilerType(this, llvm::cast<clang::DecltypeType>(qual_type) - ->getUnderlyingType() - .getAsOpaquePtr()) - .GetFormat(); case clang::Type::DependentSizedArray: case clang::Type::DependentSizedExtVector: case clang::Type::UnresolvedUsing: @@ -5470,7 +4844,6 @@ lldb::Format ClangASTContext::GetFormat(lldb::opaque_compiler_type_t type) { case clang::Type::TemplateSpecialization: case clang::Type::DeducedTemplateSpecialization: - case clang::Type::Atomic: case clang::Type::Adjusted: case clang::Type::Pipe: break; @@ -5509,7 +4882,7 @@ GetDynamicArrayInfo(ClangASTContext &ast, SymbolFile *sym_file, clang::QualType qual_type, const ExecutionContext *exe_ctx) { if (qual_type->isIncompleteArrayType()) - if (auto *metadata = ast.GetMetadata(qual_type.getAsOpaquePtr())) + if (auto *metadata = ast.GetMetadata(qual_type.getTypePtr())) return sym_file->GetDynamicArrayInfoForUID(metadata->GetUserID(), exe_ctx); return llvm::None; @@ -5522,7 +4895,7 @@ uint32_t ClangASTContext::GetNumChildren(lldb::opaque_compiler_type_t type, return 0; uint32_t num_children = 0; - clang::QualType qual_type(GetQualType(type)); + clang::QualType qual_type(RemoveWrappingTypes(GetQualType(type))); const clang::Type::TypeClass type_class = qual_type->getTypeClass(); switch (type_class) { case clang::Type::Builtin: @@ -5540,7 +4913,7 @@ uint32_t ClangASTContext::GetNumChildren(lldb::opaque_compiler_type_t type, case clang::Type::Complex: return 0; case clang::Type::Record: - if (GetCompleteQualType(getASTContext(), qual_type)) { + if (GetCompleteQualType(&getASTContext(), qual_type)) { const clang::RecordType *record_type = llvm::cast<clang::RecordType>(qual_type.getTypePtr()); const clang::RecordDecl *record_decl = record_type->getDecl(); @@ -5584,7 +4957,7 @@ uint32_t ClangASTContext::GetNumChildren(lldb::opaque_compiler_type_t type, case clang::Type::ObjCObject: case clang::Type::ObjCInterface: - if (GetCompleteQualType(getASTContext(), qual_type)) { + if (GetCompleteQualType(&getASTContext(), qual_type)) { const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr()); assert(objc_class_type); @@ -5615,8 +4988,7 @@ uint32_t ClangASTContext::GetNumChildren(lldb::opaque_compiler_type_t type, llvm::cast<clang::ObjCObjectPointerType>(qual_type.getTypePtr()); clang::QualType pointee_type = pointer_type->getPointeeType(); uint32_t num_pointee_children = - CompilerType(this, pointee_type.getAsOpaquePtr()) - .GetNumChildren(omit_empty_base_classes, exe_ctx); + GetType(pointee_type).GetNumChildren(omit_empty_base_classes, exe_ctx); // If this type points to a simple type, then it has 1 child if (num_pointee_children == 0) num_children = 1; @@ -5649,8 +5021,7 @@ uint32_t ClangASTContext::GetNumChildren(lldb::opaque_compiler_type_t type, llvm::cast<clang::PointerType>(qual_type.getTypePtr()); clang::QualType pointee_type(pointer_type->getPointeeType()); uint32_t num_pointee_children = - CompilerType(this, pointee_type.getAsOpaquePtr()) - .GetNumChildren(omit_empty_base_classes, exe_ctx); + GetType(pointee_type).GetNumChildren(omit_empty_base_classes, exe_ctx); if (num_pointee_children == 0) { // We have a pointer to a pointee type that claims it has no children. We // will want to look at @@ -5665,8 +5036,7 @@ uint32_t ClangASTContext::GetNumChildren(lldb::opaque_compiler_type_t type, llvm::cast<clang::ReferenceType>(qual_type.getTypePtr()); clang::QualType pointee_type = reference_type->getPointeeType(); uint32_t num_pointee_children = - CompilerType(this, pointee_type.getAsOpaquePtr()) - .GetNumChildren(omit_empty_base_classes, exe_ctx); + GetType(pointee_type).GetNumChildren(omit_empty_base_classes, exe_ctx); // If this type points to a simple type, then it has 1 child if (num_pointee_children == 0) num_children = 1; @@ -5674,36 +5044,6 @@ uint32_t ClangASTContext::GetNumChildren(lldb::opaque_compiler_type_t type, num_children = num_pointee_children; } break; - case clang::Type::Typedef: - num_children = CompilerType(this, llvm::cast<clang::TypedefType>(qual_type) - ->getDecl() - ->getUnderlyingType() - .getAsOpaquePtr()) - .GetNumChildren(omit_empty_base_classes, exe_ctx); - break; - - case clang::Type::Auto: - num_children = CompilerType(this, llvm::cast<clang::AutoType>(qual_type) - ->getDeducedType() - .getAsOpaquePtr()) - .GetNumChildren(omit_empty_base_classes, exe_ctx); - break; - - case clang::Type::Elaborated: - num_children = - CompilerType(this, llvm::cast<clang::ElaboratedType>(qual_type) - ->getNamedType() - .getAsOpaquePtr()) - .GetNumChildren(omit_empty_base_classes, exe_ctx); - break; - - case clang::Type::Paren: - num_children = - CompilerType( - this, - llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr()) - .GetNumChildren(omit_empty_base_classes, exe_ctx); - break; default: break; } @@ -5797,8 +5137,7 @@ void ClangASTContext::ForEachEnumerator( if (enum_type) { const clang::EnumDecl *enum_decl = enum_type->getDecl(); if (enum_decl) { - CompilerType integer_type(this, - enum_decl->getIntegerType().getAsOpaquePtr()); + CompilerType integer_type = GetType(enum_decl->getIntegerType()); clang::EnumDecl::enumerator_iterator enum_pos, enum_end_pos; for (enum_pos = enum_decl->enumerator_begin(), @@ -5819,7 +5158,7 @@ uint32_t ClangASTContext::GetNumFields(lldb::opaque_compiler_type_t type) { return 0; uint32_t count = 0; - clang::QualType qual_type(GetCanonicalQualType(type)); + clang::QualType qual_type(RemoveWrappingTypes(GetCanonicalQualType(type))); const clang::Type::TypeClass type_class = qual_type->getTypeClass(); switch (type_class) { case clang::Type::Record: @@ -5841,36 +5180,6 @@ uint32_t ClangASTContext::GetNumFields(lldb::opaque_compiler_type_t type) { } break; - case clang::Type::Typedef: - count = CompilerType(this, llvm::cast<clang::TypedefType>(qual_type) - ->getDecl() - ->getUnderlyingType() - .getAsOpaquePtr()) - .GetNumFields(); - break; - - case clang::Type::Auto: - count = CompilerType(this, llvm::cast<clang::AutoType>(qual_type) - ->getDeducedType() - .getAsOpaquePtr()) - .GetNumFields(); - break; - - case clang::Type::Elaborated: - count = CompilerType(this, llvm::cast<clang::ElaboratedType>(qual_type) - ->getNamedType() - .getAsOpaquePtr()) - .GetNumFields(); - break; - - case clang::Type::Paren: - count = - CompilerType( - this, - llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr()) - .GetNumFields(); - break; - case clang::Type::ObjCObjectPointer: { const clang::ObjCObjectPointerType *objc_class_type = qual_type->getAs<clang::ObjCObjectPointerType>(); @@ -5969,7 +5278,7 @@ CompilerType ClangASTContext::GetFieldAtIndex(lldb::opaque_compiler_type_t type, if (!type) return CompilerType(); - clang::QualType qual_type(GetCanonicalQualType(type)); + clang::QualType qual_type(RemoveWrappingTypes(GetCanonicalQualType(type))); const clang::Type::TypeClass type_class = qual_type->getTypeClass(); switch (type_class) { case clang::Type::Record: @@ -5991,7 +5300,7 @@ CompilerType ClangASTContext::GetFieldAtIndex(lldb::opaque_compiler_type_t type, // alignment (field_type_info.second) from the AST context. if (bit_offset_ptr) { const clang::ASTRecordLayout &record_layout = - getASTContext()->getASTRecordLayout(record_decl); + getASTContext().getASTRecordLayout(record_decl); *bit_offset_ptr = record_layout.getFieldOffset(field_idx); } @@ -6005,7 +5314,7 @@ CompilerType ClangASTContext::GetFieldAtIndex(lldb::opaque_compiler_type_t type, clang::Expr::EvalResult result; if (bitfield_bit_size_expr && bitfield_bit_size_expr->EvaluateAsInt(result, - *getASTContext())) { + getASTContext())) { llvm::APSInt bitfield_apsint = result.Val.getInt(); *bitfield_bit_size_ptr = bitfield_apsint.getLimitedValue(); } @@ -6014,7 +5323,7 @@ CompilerType ClangASTContext::GetFieldAtIndex(lldb::opaque_compiler_type_t type, if (is_bitfield_ptr) *is_bitfield_ptr = is_bitfield; - return CompilerType(this, field->getType().getAsOpaquePtr()); + return GetType(field->getType()); } } } @@ -6032,7 +5341,7 @@ CompilerType ClangASTContext::GetFieldAtIndex(lldb::opaque_compiler_type_t type, objc_interface_type->getDecl(); if (class_interface_decl) { return CompilerType( - this, GetObjCFieldAtIndex(getASTContext(), class_interface_decl, + this, GetObjCFieldAtIndex(&getASTContext(), class_interface_decl, idx, name, bit_offset_ptr, bitfield_bit_size_ptr, is_bitfield_ptr)); } @@ -6050,42 +5359,13 @@ CompilerType ClangASTContext::GetFieldAtIndex(lldb::opaque_compiler_type_t type, clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); return CompilerType( - this, GetObjCFieldAtIndex(getASTContext(), class_interface_decl, + this, GetObjCFieldAtIndex(&getASTContext(), class_interface_decl, idx, name, bit_offset_ptr, bitfield_bit_size_ptr, is_bitfield_ptr)); } } break; - case clang::Type::Typedef: - return CompilerType(this, llvm::cast<clang::TypedefType>(qual_type) - ->getDecl() - ->getUnderlyingType() - .getAsOpaquePtr()) - .GetFieldAtIndex(idx, name, bit_offset_ptr, bitfield_bit_size_ptr, - is_bitfield_ptr); - - case clang::Type::Auto: - return CompilerType(this, llvm::cast<clang::AutoType>(qual_type) - ->getDeducedType() - .getAsOpaquePtr()) - .GetFieldAtIndex(idx, name, bit_offset_ptr, bitfield_bit_size_ptr, - is_bitfield_ptr); - - case clang::Type::Elaborated: - return CompilerType(this, llvm::cast<clang::ElaboratedType>(qual_type) - ->getNamedType() - .getAsOpaquePtr()) - .GetFieldAtIndex(idx, name, bit_offset_ptr, bitfield_bit_size_ptr, - is_bitfield_ptr); - - case clang::Type::Paren: - return CompilerType(this, llvm::cast<clang::ParenType>(qual_type) - ->desugar() - .getAsOpaquePtr()) - .GetFieldAtIndex(idx, name, bit_offset_ptr, bitfield_bit_size_ptr, - is_bitfield_ptr); - default: break; } @@ -6095,7 +5375,7 @@ CompilerType ClangASTContext::GetFieldAtIndex(lldb::opaque_compiler_type_t type, uint32_t ClangASTContext::GetNumDirectBaseClasses(lldb::opaque_compiler_type_t type) { uint32_t count = 0; - clang::QualType qual_type(GetCanonicalQualType(type)); + clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type)); const clang::Type::TypeClass type_class = qual_type->getTypeClass(); switch (type_class) { case clang::Type::Record: @@ -6138,29 +5418,6 @@ ClangASTContext::GetNumDirectBaseClasses(lldb::opaque_compiler_type_t type) { } break; - case clang::Type::Typedef: - count = GetNumDirectBaseClasses(llvm::cast<clang::TypedefType>(qual_type) - ->getDecl() - ->getUnderlyingType() - .getAsOpaquePtr()); - break; - - case clang::Type::Auto: - count = GetNumDirectBaseClasses(llvm::cast<clang::AutoType>(qual_type) - ->getDeducedType() - .getAsOpaquePtr()); - break; - - case clang::Type::Elaborated: - count = GetNumDirectBaseClasses(llvm::cast<clang::ElaboratedType>(qual_type) - ->getNamedType() - .getAsOpaquePtr()); - break; - - case clang::Type::Paren: - return GetNumDirectBaseClasses( - llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr()); - default: break; } @@ -6170,7 +5427,7 @@ ClangASTContext::GetNumDirectBaseClasses(lldb::opaque_compiler_type_t type) { uint32_t ClangASTContext::GetNumVirtualBaseClasses(lldb::opaque_compiler_type_t type) { uint32_t count = 0; - clang::QualType qual_type(GetCanonicalQualType(type)); + clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type)); const clang::Type::TypeClass type_class = qual_type->getTypeClass(); switch (type_class) { case clang::Type::Record: @@ -6182,31 +5439,6 @@ ClangASTContext::GetNumVirtualBaseClasses(lldb::opaque_compiler_type_t type) { } break; - case clang::Type::Typedef: - count = GetNumVirtualBaseClasses(llvm::cast<clang::TypedefType>(qual_type) - ->getDecl() - ->getUnderlyingType() - .getAsOpaquePtr()); - break; - - case clang::Type::Auto: - count = GetNumVirtualBaseClasses(llvm::cast<clang::AutoType>(qual_type) - ->getDeducedType() - .getAsOpaquePtr()); - break; - - case clang::Type::Elaborated: - count = - GetNumVirtualBaseClasses(llvm::cast<clang::ElaboratedType>(qual_type) - ->getNamedType() - .getAsOpaquePtr()); - break; - - case clang::Type::Paren: - count = GetNumVirtualBaseClasses( - llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr()); - break; - default: break; } @@ -6215,7 +5447,7 @@ ClangASTContext::GetNumVirtualBaseClasses(lldb::opaque_compiler_type_t type) { CompilerType ClangASTContext::GetDirectBaseClassAtIndex( lldb::opaque_compiler_type_t type, size_t idx, uint32_t *bit_offset_ptr) { - clang::QualType qual_type(GetCanonicalQualType(type)); + clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type)); const clang::Type::TypeClass type_class = qual_type->getTypeClass(); switch (type_class) { case clang::Type::Record: @@ -6232,7 +5464,7 @@ CompilerType ClangASTContext::GetDirectBaseClassAtIndex( if (curr_idx == idx) { if (bit_offset_ptr) { const clang::ASTRecordLayout &record_layout = - getASTContext()->getASTRecordLayout(cxx_record_decl); + getASTContext().getASTRecordLayout(cxx_record_decl); const clang::CXXRecordDecl *base_class_decl = llvm::cast<clang::CXXRecordDecl>( base_class->getType() @@ -6249,7 +5481,7 @@ CompilerType ClangASTContext::GetDirectBaseClassAtIndex( .getQuantity() * 8; } - return CompilerType(this, base_class->getType().getAsOpaquePtr()); + return GetType(base_class->getType()); } } } @@ -6273,9 +5505,8 @@ CompilerType ClangASTContext::GetDirectBaseClassAtIndex( if (superclass_interface_decl) { if (bit_offset_ptr) *bit_offset_ptr = 0; - return CompilerType(this, - getASTContext()->getObjCInterfaceType( - superclass_interface_decl).getAsOpaquePtr()); + return GetType(getASTContext().getObjCInterfaceType( + superclass_interface_decl)); } } } @@ -6295,41 +5526,14 @@ CompilerType ClangASTContext::GetDirectBaseClassAtIndex( if (superclass_interface_decl) { if (bit_offset_ptr) *bit_offset_ptr = 0; - return CompilerType( - this, getASTContext() - ->getObjCInterfaceType(superclass_interface_decl) - .getAsOpaquePtr()); + return GetType(getASTContext().getObjCInterfaceType( + superclass_interface_decl)); } } } } break; - case clang::Type::Typedef: - return GetDirectBaseClassAtIndex(llvm::cast<clang::TypedefType>(qual_type) - ->getDecl() - ->getUnderlyingType() - .getAsOpaquePtr(), - idx, bit_offset_ptr); - - case clang::Type::Auto: - return GetDirectBaseClassAtIndex(llvm::cast<clang::AutoType>(qual_type) - ->getDeducedType() - .getAsOpaquePtr(), - idx, bit_offset_ptr); - - case clang::Type::Elaborated: - return GetDirectBaseClassAtIndex( - llvm::cast<clang::ElaboratedType>(qual_type) - ->getNamedType() - .getAsOpaquePtr(), - idx, bit_offset_ptr); - - case clang::Type::Paren: - return GetDirectBaseClassAtIndex( - llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(), - idx, bit_offset_ptr); - default: break; } @@ -6338,7 +5542,7 @@ CompilerType ClangASTContext::GetDirectBaseClassAtIndex( CompilerType ClangASTContext::GetVirtualBaseClassAtIndex( lldb::opaque_compiler_type_t type, size_t idx, uint32_t *bit_offset_ptr) { - clang::QualType qual_type(GetCanonicalQualType(type)); + clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type)); const clang::Type::TypeClass type_class = qual_type->getTypeClass(); switch (type_class) { case clang::Type::Record: @@ -6355,7 +5559,7 @@ CompilerType ClangASTContext::GetVirtualBaseClassAtIndex( if (curr_idx == idx) { if (bit_offset_ptr) { const clang::ASTRecordLayout &record_layout = - getASTContext()->getASTRecordLayout(cxx_record_decl); + getASTContext().getASTRecordLayout(cxx_record_decl); const clang::CXXRecordDecl *base_class_decl = llvm::cast<clang::CXXRecordDecl>( base_class->getType() @@ -6366,38 +5570,13 @@ CompilerType ClangASTContext::GetVirtualBaseClassAtIndex( .getQuantity() * 8; } - return CompilerType(this, base_class->getType().getAsOpaquePtr()); + return GetType(base_class->getType()); } } } } break; - case clang::Type::Typedef: - return GetVirtualBaseClassAtIndex(llvm::cast<clang::TypedefType>(qual_type) - ->getDecl() - ->getUnderlyingType() - .getAsOpaquePtr(), - idx, bit_offset_ptr); - - case clang::Type::Auto: - return GetVirtualBaseClassAtIndex(llvm::cast<clang::AutoType>(qual_type) - ->getDeducedType() - .getAsOpaquePtr(), - idx, bit_offset_ptr); - - case clang::Type::Elaborated: - return GetVirtualBaseClassAtIndex( - llvm::cast<clang::ElaboratedType>(qual_type) - ->getNamedType() - .getAsOpaquePtr(), - idx, bit_offset_ptr); - - case clang::Type::Paren: - return GetVirtualBaseClassAtIndex( - llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(), - idx, bit_offset_ptr); - default: break; } @@ -6413,7 +5592,7 @@ uint32_t ClangASTContext::GetNumPointeeChildren(clang::QualType type) { if (type.isNull()) return 0; - clang::QualType qual_type(type.getCanonicalType()); + clang::QualType qual_type = RemoveWrappingTypes(type.getCanonicalType()); const clang::Type::TypeClass type_class = qual_type->getTypeClass(); switch (type_class) { case clang::Type::Builtin: @@ -6514,29 +5693,6 @@ uint32_t ClangASTContext::GetNumPointeeChildren(clang::QualType type) { return 0; // When we function pointers, they have no children... case clang::Type::UnresolvedUsing: return 0; - case clang::Type::Paren: - return GetNumPointeeChildren( - llvm::cast<clang::ParenType>(qual_type)->desugar()); - case clang::Type::Typedef: - return GetNumPointeeChildren(llvm::cast<clang::TypedefType>(qual_type) - ->getDecl() - ->getUnderlyingType()); - case clang::Type::Auto: - return GetNumPointeeChildren( - llvm::cast<clang::AutoType>(qual_type)->getDeducedType()); - case clang::Type::Elaborated: - return GetNumPointeeChildren( - llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()); - case clang::Type::TypeOfExpr: - return GetNumPointeeChildren(llvm::cast<clang::TypeOfExprType>(qual_type) - ->getUnderlyingExpr() - ->getType()); - case clang::Type::TypeOf: - return GetNumPointeeChildren( - llvm::cast<clang::TypeOfType>(qual_type)->getUnderlyingType()); - case clang::Type::Decltype: - return GetNumPointeeChildren( - llvm::cast<clang::DecltypeType>(qual_type)->getUnderlyingType()); case clang::Type::Record: return 0; case clang::Type::Enum: @@ -6580,7 +5736,8 @@ CompilerType ClangASTContext::GetChildCompilerTypeAtIndex( return exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr; }; - clang::QualType parent_qual_type(GetCanonicalQualType(type)); + clang::QualType parent_qual_type( + RemoveWrappingTypes(GetCanonicalQualType(type))); const clang::Type::TypeClass parent_type_class = parent_qual_type->getTypeClass(); child_bitfield_bit_size = 0; @@ -6599,10 +5756,9 @@ CompilerType ClangASTContext::GetChildCompilerTypeAtIndex( case clang::BuiltinType::ObjCClass: child_name = "isa"; child_byte_size = - getASTContext()->getTypeSize(getASTContext()->ObjCBuiltinClassTy) / + getASTContext().getTypeSize(getASTContext().ObjCBuiltinClassTy) / CHAR_BIT; - return CompilerType( - this, getASTContext()->ObjCBuiltinClassTy.getAsOpaquePtr()); + return GetType(getASTContext().ObjCBuiltinClassTy); default: break; @@ -6617,7 +5773,7 @@ CompilerType ClangASTContext::GetChildCompilerTypeAtIndex( const clang::RecordDecl *record_decl = record_type->getDecl(); assert(record_decl); const clang::ASTRecordLayout &record_layout = - getASTContext()->getASTRecordLayout(record_decl); + getASTContext().getASTRecordLayout(record_decl); uint32_t child_idx = 0; const clang::CXXRecordDecl *cxx_record_decl = @@ -6648,7 +5804,7 @@ CompilerType ClangASTContext::GetChildCompilerTypeAtIndex( bool handled = false; if (valobj) { clang::VTableContextBase *vtable_ctx = - getASTContext()->getVTableContext(); + getASTContext().getVTableContext(); if (vtable_ctx) handled = GetVBaseBitOffset(*vtable_ctx, *valobj, record_layout, cxx_record_decl, @@ -6665,8 +5821,7 @@ CompilerType ClangASTContext::GetChildCompilerTypeAtIndex( // Base classes should be a multiple of 8 bits in size child_byte_offset = bit_offset / 8; - CompilerType base_class_clang_type( - this, base_class->getType().getAsOpaquePtr()); + CompilerType base_class_clang_type = GetType(base_class->getType()); child_name = base_class_clang_type.GetTypeName().AsCString(""); Optional<uint64_t> size = base_class_clang_type.GetBitSize(get_exe_scope()); @@ -6698,8 +5853,7 @@ CompilerType ClangASTContext::GetChildCompilerTypeAtIndex( // Figure out the type byte size (field_type_info.first) and // alignment (field_type_info.second) from the AST context. - CompilerType field_clang_type(this, - field->getType().getAsOpaquePtr()); + CompilerType field_clang_type = GetType(field->getType()); assert(field_idx < record_layout.getFieldCount()); Optional<uint64_t> size = field_clang_type.GetByteSize(get_exe_scope()); @@ -6711,8 +5865,7 @@ CompilerType ClangASTContext::GetChildCompilerTypeAtIndex( // Figure out the field offset within the current struct/union/class // type bit_offset = record_layout.getFieldOffset(field_idx); - if (ClangASTContext::FieldIsBitfield(getASTContext(), *field, - child_bitfield_bit_size)) { + if (FieldIsBitfield(*field, child_bitfield_bit_size)) { child_bitfield_bit_offset = bit_offset % child_bit_size; const uint32_t child_bit_offset = bit_offset - child_bitfield_bit_offset; @@ -6741,33 +5894,32 @@ CompilerType ClangASTContext::GetChildCompilerTypeAtIndex( if (class_interface_decl) { const clang::ASTRecordLayout &interface_layout = - getASTContext()->getASTObjCInterfaceLayout(class_interface_decl); + getASTContext().getASTObjCInterfaceLayout(class_interface_decl); clang::ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass(); if (superclass_interface_decl) { if (omit_empty_base_classes) { - CompilerType base_class_clang_type( - this, getASTContext() - ->getObjCInterfaceType(superclass_interface_decl) - .getAsOpaquePtr()); + CompilerType base_class_clang_type = + GetType(getASTContext().getObjCInterfaceType( + superclass_interface_decl)); if (base_class_clang_type.GetNumChildren(omit_empty_base_classes, exe_ctx) > 0) { if (idx == 0) { clang::QualType ivar_qual_type( - getASTContext()->getObjCInterfaceType( + getASTContext().getObjCInterfaceType( superclass_interface_decl)); child_name.assign( superclass_interface_decl->getNameAsString()); clang::TypeInfo ivar_type_info = - getASTContext()->getTypeInfo(ivar_qual_type.getTypePtr()); + getASTContext().getTypeInfo(ivar_qual_type.getTypePtr()); child_byte_size = ivar_type_info.Width / 8; child_byte_offset = 0; child_is_base_class = true; - return CompilerType(this, ivar_qual_type.getAsOpaquePtr()); + return GetType(ivar_qual_type); } ++child_idx; @@ -6792,7 +5944,7 @@ CompilerType ClangASTContext::GetChildCompilerTypeAtIndex( child_name.assign(ivar_decl->getNameAsString()); clang::TypeInfo ivar_type_info = - getASTContext()->getTypeInfo(ivar_qual_type.getTypePtr()); + getASTContext().getTypeInfo(ivar_qual_type.getTypePtr()); child_byte_size = ivar_type_info.Width / 8; @@ -6811,8 +5963,7 @@ CompilerType ClangASTContext::GetChildCompilerTypeAtIndex( ObjCLanguageRuntime *objc_runtime = ObjCLanguageRuntime::Get(*process); if (objc_runtime != nullptr) { - CompilerType parent_ast_type( - this, parent_qual_type.getAsOpaquePtr()); + CompilerType parent_ast_type = GetType(parent_qual_type); child_byte_offset = objc_runtime->GetByteOffsetForIvar( parent_ast_type, ivar_decl->getNameAsString().c_str()); } @@ -6835,15 +5986,14 @@ CompilerType ClangASTContext::GetChildCompilerTypeAtIndex( // offset from, we still need to get the bit offset for // bitfields from the layout. - if (ClangASTContext::FieldIsBitfield(getASTContext(), ivar_decl, - child_bitfield_bit_size)) { + if (FieldIsBitfield(ivar_decl, child_bitfield_bit_size)) { if (bit_offset == INT32_MAX) bit_offset = interface_layout.getFieldOffset( child_idx - superclass_idx); child_bitfield_bit_offset = bit_offset % 8; } - return CompilerType(this, ivar_qual_type.getAsOpaquePtr()); + return GetType(ivar_qual_type); } ++child_idx; } @@ -6894,8 +6044,7 @@ CompilerType ClangASTContext::GetChildCompilerTypeAtIndex( const clang::VectorType *array = llvm::cast<clang::VectorType>(parent_qual_type.getTypePtr()); if (array) { - CompilerType element_type(this, - array->getElementType().getAsOpaquePtr()); + CompilerType element_type = GetType(array->getElementType()); if (element_type.GetCompleteType()) { char element_name[64]; ::snprintf(element_name, sizeof(element_name), "[%" PRIu64 "]", @@ -6917,8 +6066,7 @@ CompilerType ClangASTContext::GetChildCompilerTypeAtIndex( if (ignore_array_bounds || idx_is_valid) { const clang::ArrayType *array = GetQualType(type)->getAsArrayTypeUnsafe(); if (array) { - CompilerType element_type(this, - array->getElementType().getAsOpaquePtr()); + CompilerType element_type = GetType(array->getElementType()); if (element_type.GetCompleteType()) { child_name = llvm::formatv("[{0}]", idx); if (Optional<uint64_t> size = @@ -6976,8 +6124,8 @@ CompilerType ClangASTContext::GetChildCompilerTypeAtIndex( if (idx_is_valid) { const clang::ReferenceType *reference_type = llvm::cast<clang::ReferenceType>(parent_qual_type.getTypePtr()); - CompilerType pointee_clang_type( - this, reference_type->getPointeeType().getAsOpaquePtr()); + CompilerType pointee_clang_type = + GetType(reference_type->getPointeeType()); if (transparent_pointers && pointee_clang_type.IsAggregateType()) { child_is_deref_of_parent = false; bool tmp_child_is_deref_of_parent = false; @@ -7008,55 +6156,6 @@ CompilerType ClangASTContext::GetChildCompilerTypeAtIndex( } break; - case clang::Type::Typedef: { - CompilerType typedefed_clang_type( - this, llvm::cast<clang::TypedefType>(parent_qual_type) - ->getDecl() - ->getUnderlyingType() - .getAsOpaquePtr()); - return typedefed_clang_type.GetChildCompilerTypeAtIndex( - exe_ctx, idx, transparent_pointers, omit_empty_base_classes, - ignore_array_bounds, child_name, child_byte_size, child_byte_offset, - child_bitfield_bit_size, child_bitfield_bit_offset, child_is_base_class, - child_is_deref_of_parent, valobj, language_flags); - } break; - - case clang::Type::Auto: { - CompilerType elaborated_clang_type( - this, llvm::cast<clang::AutoType>(parent_qual_type) - ->getDeducedType() - .getAsOpaquePtr()); - return elaborated_clang_type.GetChildCompilerTypeAtIndex( - exe_ctx, idx, transparent_pointers, omit_empty_base_classes, - ignore_array_bounds, child_name, child_byte_size, child_byte_offset, - child_bitfield_bit_size, child_bitfield_bit_offset, child_is_base_class, - child_is_deref_of_parent, valobj, language_flags); - } - - case clang::Type::Elaborated: { - CompilerType elaborated_clang_type( - this, llvm::cast<clang::ElaboratedType>(parent_qual_type) - ->getNamedType() - .getAsOpaquePtr()); - return elaborated_clang_type.GetChildCompilerTypeAtIndex( - exe_ctx, idx, transparent_pointers, omit_empty_base_classes, - ignore_array_bounds, child_name, child_byte_size, child_byte_offset, - child_bitfield_bit_size, child_bitfield_bit_offset, child_is_base_class, - child_is_deref_of_parent, valobj, language_flags); - } - - case clang::Type::Paren: { - CompilerType paren_clang_type(this, - llvm::cast<clang::ParenType>(parent_qual_type) - ->desugar() - .getAsOpaquePtr()); - return paren_clang_type.GetChildCompilerTypeAtIndex( - exe_ctx, idx, transparent_pointers, omit_empty_base_classes, - ignore_array_bounds, child_name, child_byte_size, child_byte_offset, - child_bitfield_bit_size, child_bitfield_bit_offset, child_is_base_class, - child_is_deref_of_parent, valobj, language_flags); - } - default: break; } @@ -7155,7 +6254,7 @@ size_t ClangASTContext::GetIndexOfChildMemberWithName( lldb::opaque_compiler_type_t type, const char *name, bool omit_empty_base_classes, std::vector<uint32_t> &child_indexes) { if (type && name && name[0]) { - clang::QualType qual_type(GetCanonicalQualType(type)); + clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type)); const clang::Type::TypeClass type_class = qual_type->getTypeClass(); switch (type_class) { case clang::Type::Record: @@ -7178,7 +6277,7 @@ size_t ClangASTContext::GetIndexOfChildMemberWithName( field != field_end; ++field, ++child_idx) { llvm::StringRef field_name = field->getName(); if (field_name.empty()) { - CompilerType field_type(this, field->getType().getAsOpaquePtr()); + CompilerType field_type = GetType(field->getType()); child_indexes.push_back(child_idx); if (field_type.GetIndexOfChildMemberWithName( name, omit_empty_base_classes, child_indexes)) @@ -7202,7 +6301,7 @@ size_t ClangASTContext::GetIndexOfChildMemberWithName( // const Decl *root_cdecl = cxx_record_decl->getCanonicalDecl(); // Didn't find things easily, lets let clang do its thang... clang::IdentifierInfo &ident_ref = - getASTContext()->Idents.get(name_sref); + getASTContext().Idents.get(name_sref); clang::DeclarationName decl_name(&ident_ref); clang::CXXBasePaths paths; @@ -7289,10 +6388,9 @@ size_t ClangASTContext::GetIndexOfChildMemberWithName( // superclass... child_indexes.push_back(0); - CompilerType superclass_clang_type( - this, getASTContext() - ->getObjCInterfaceType(superclass_interface_decl) - .getAsOpaquePtr()); + CompilerType superclass_clang_type = + GetType(getASTContext().getObjCInterfaceType( + superclass_interface_decl)); if (superclass_clang_type.GetIndexOfChildMemberWithName( name, omit_empty_base_classes, child_indexes)) { // We did find an ivar in a superclass so just return the @@ -7310,10 +6408,9 @@ size_t ClangASTContext::GetIndexOfChildMemberWithName( break; case clang::Type::ObjCObjectPointer: { - CompilerType objc_object_clang_type( - this, llvm::cast<clang::ObjCObjectPointerType>(qual_type.getTypePtr()) - ->getPointeeType() - .getAsOpaquePtr()); + CompilerType objc_object_clang_type = GetType( + llvm::cast<clang::ObjCObjectPointerType>(qual_type.getTypePtr()) + ->getPointeeType()); return objc_object_clang_type.GetIndexOfChildMemberWithName( name, omit_empty_base_classes, child_indexes); } break; @@ -7363,7 +6460,7 @@ size_t ClangASTContext::GetIndexOfChildMemberWithName( const clang::ReferenceType *reference_type = llvm::cast<clang::ReferenceType>(qual_type.getTypePtr()); clang::QualType pointee_type(reference_type->getPointeeType()); - CompilerType pointee_clang_type(this, pointee_type.getAsOpaquePtr()); + CompilerType pointee_clang_type = GetType(pointee_type); if (pointee_clang_type.IsAggregateType()) { return pointee_clang_type.GetIndexOfChildMemberWithName( @@ -7380,35 +6477,6 @@ size_t ClangASTContext::GetIndexOfChildMemberWithName( } } break; - case clang::Type::Typedef: - return CompilerType(this, llvm::cast<clang::TypedefType>(qual_type) - ->getDecl() - ->getUnderlyingType() - .getAsOpaquePtr()) - .GetIndexOfChildMemberWithName(name, omit_empty_base_classes, - child_indexes); - - case clang::Type::Auto: - return CompilerType(this, llvm::cast<clang::AutoType>(qual_type) - ->getDeducedType() - .getAsOpaquePtr()) - .GetIndexOfChildMemberWithName(name, omit_empty_base_classes, - child_indexes); - - case clang::Type::Elaborated: - return CompilerType(this, llvm::cast<clang::ElaboratedType>(qual_type) - ->getNamedType() - .getAsOpaquePtr()) - .GetIndexOfChildMemberWithName(name, omit_empty_base_classes, - child_indexes); - - case clang::Type::Paren: - return CompilerType(this, llvm::cast<clang::ParenType>(qual_type) - ->desugar() - .getAsOpaquePtr()) - .GetIndexOfChildMemberWithName(name, omit_empty_base_classes, - child_indexes); - default: break; } @@ -7425,7 +6493,7 @@ ClangASTContext::GetIndexOfChildWithName(lldb::opaque_compiler_type_t type, const char *name, bool omit_empty_base_classes) { if (type && name && name[0]) { - clang::QualType qual_type(GetCanonicalQualType(type)); + clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type)); const clang::Type::TypeClass type_class = qual_type->getTypeClass(); @@ -7458,8 +6526,7 @@ ClangASTContext::GetIndexOfChildWithName(lldb::opaque_compiler_type_t type, !ClangASTContext::RecordHasFields(base_class_decl)) continue; - CompilerType base_class_clang_type( - this, base_class->getType().getAsOpaquePtr()); + CompilerType base_class_clang_type = GetType(base_class->getType()); std::string base_class_type_name( base_class_clang_type.GetTypeName().AsCString("")); if (base_class_type_name == name) @@ -7522,10 +6589,9 @@ ClangASTContext::GetIndexOfChildWithName(lldb::opaque_compiler_type_t type, break; case clang::Type::ObjCObjectPointer: { - CompilerType pointee_clang_type( - this, llvm::cast<clang::ObjCObjectPointerType>(qual_type.getTypePtr()) - ->getPointeeType() - .getAsOpaquePtr()); + CompilerType pointee_clang_type = GetType( + llvm::cast<clang::ObjCObjectPointerType>(qual_type.getTypePtr()) + ->getPointeeType()); return pointee_clang_type.GetIndexOfChildWithName( name, omit_empty_base_classes); } break; @@ -7574,8 +6640,7 @@ ClangASTContext::GetIndexOfChildWithName(lldb::opaque_compiler_type_t type, case clang::Type::RValueReference: { const clang::ReferenceType *reference_type = llvm::cast<clang::ReferenceType>(qual_type.getTypePtr()); - CompilerType pointee_type( - this, reference_type->getPointeeType().getAsOpaquePtr()); + CompilerType pointee_type = GetType(reference_type->getPointeeType()); if (pointee_type.IsAggregateType()) { return pointee_type.GetIndexOfChildWithName(name, @@ -7586,8 +6651,7 @@ ClangASTContext::GetIndexOfChildWithName(lldb::opaque_compiler_type_t type, case clang::Type::Pointer: { const clang::PointerType *pointer_type = llvm::cast<clang::PointerType>(qual_type.getTypePtr()); - CompilerType pointee_type( - this, pointer_type->getPointeeType().getAsOpaquePtr()); + CompilerType pointee_type = GetType(pointer_type->getPointeeType()); if (pointee_type.IsAggregateType()) { return pointee_type.GetIndexOfChildWithName(name, @@ -7612,31 +6676,6 @@ ClangASTContext::GetIndexOfChildWithName(lldb::opaque_compiler_type_t type, } } break; - case clang::Type::Auto: - return CompilerType(this, llvm::cast<clang::AutoType>(qual_type) - ->getDeducedType() - .getAsOpaquePtr()) - .GetIndexOfChildWithName(name, omit_empty_base_classes); - - case clang::Type::Elaborated: - return CompilerType(this, llvm::cast<clang::ElaboratedType>(qual_type) - ->getNamedType() - .getAsOpaquePtr()) - .GetIndexOfChildWithName(name, omit_empty_base_classes); - - case clang::Type::Paren: - return CompilerType(this, llvm::cast<clang::ParenType>(qual_type) - ->desugar() - .getAsOpaquePtr()) - .GetIndexOfChildWithName(name, omit_empty_base_classes); - - case clang::Type::Typedef: - return CompilerType(this, llvm::cast<clang::TypedefType>(qual_type) - ->getDecl() - ->getUnderlyingType() - .getAsOpaquePtr()) - .GetIndexOfChildWithName(name, omit_empty_base_classes); - default: break; } @@ -7649,7 +6688,7 @@ ClangASTContext::GetNumTemplateArguments(lldb::opaque_compiler_type_t type) { if (!type) return 0; - clang::QualType qual_type(GetCanonicalQualType(type)); + clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type)); const clang::Type::TypeClass type_class = qual_type->getTypeClass(); switch (type_class) { case clang::Type::Record: @@ -7666,31 +6705,6 @@ ClangASTContext::GetNumTemplateArguments(lldb::opaque_compiler_type_t type) { } break; - case clang::Type::Typedef: - return CompilerType(this, llvm::cast<clang::TypedefType>(qual_type) - ->getDecl() - ->getUnderlyingType() - .getAsOpaquePtr()) - .GetNumTemplateArguments(); - - case clang::Type::Auto: - return CompilerType(this, llvm::cast<clang::AutoType>(qual_type) - ->getDeducedType() - .getAsOpaquePtr()) - .GetNumTemplateArguments(); - - case clang::Type::Elaborated: - return CompilerType(this, llvm::cast<clang::ElaboratedType>(qual_type) - ->getNamedType() - .getAsOpaquePtr()) - .GetNumTemplateArguments(); - - case clang::Type::Paren: - return CompilerType(this, llvm::cast<clang::ParenType>(qual_type) - ->desugar() - .getAsOpaquePtr()) - .GetNumTemplateArguments(); - default: break; } @@ -7704,7 +6718,7 @@ ClangASTContext::GetAsTemplateSpecialization( if (!type) return nullptr; - clang::QualType qual_type(GetCanonicalQualType(type)); + clang::QualType qual_type(RemoveWrappingTypes(GetCanonicalQualType(type))); const clang::Type::TypeClass type_class = qual_type->getTypeClass(); switch (type_class) { case clang::Type::Record: { @@ -7718,27 +6732,6 @@ ClangASTContext::GetAsTemplateSpecialization( cxx_record_decl); } - case clang::Type::Typedef: - return GetAsTemplateSpecialization(llvm::cast<clang::TypedefType>(qual_type) - ->getDecl() - ->getUnderlyingType() - .getAsOpaquePtr()); - - case clang::Type::Auto: - return GetAsTemplateSpecialization(llvm::cast<clang::AutoType>(qual_type) - ->getDeducedType() - .getAsOpaquePtr()); - - case clang::Type::Elaborated: - return GetAsTemplateSpecialization( - llvm::cast<clang::ElaboratedType>(qual_type) - ->getNamedType() - .getAsOpaquePtr()); - - case clang::Type::Paren: - return GetAsTemplateSpecialization( - llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr()); - default: return nullptr; } @@ -7796,7 +6789,7 @@ ClangASTContext::GetTypeTemplateArgument(lldb::opaque_compiler_type_t type, if (template_arg.getKind() != clang::TemplateArgument::Type) return CompilerType(); - return CompilerType(this, template_arg.getAsType().getAsOpaquePtr()); + return GetType(template_arg.getAsType()); } Optional<CompilerType::IntegralTemplateArgument> @@ -7813,8 +6806,7 @@ ClangASTContext::GetIntegralTemplateArgument(lldb::opaque_compiler_type_t type, return llvm::None; return { - {template_arg.getAsIntegral(), - CompilerType(this, template_arg.getIntegralType().getAsOpaquePtr())}}; + {template_arg.getAsIntegral(), GetType(template_arg.getIntegralType())}}; } CompilerType ClangASTContext::GetTypeForFormatters(void *type) { @@ -7877,26 +6869,26 @@ clang::FieldDecl *ClangASTContext::AddFieldToRecordType( llvm::dyn_cast_or_null<ClangASTContext>(type.GetTypeSystem()); if (!ast) return nullptr; - clang::ASTContext *clang_ast = ast->getASTContext(); + clang::ASTContext &clang_ast = ast->getASTContext(); clang::IdentifierInfo *ident = nullptr; if (!name.empty()) - ident = &clang_ast->Idents.get(name); + ident = &clang_ast.Idents.get(name); clang::FieldDecl *field = nullptr; clang::Expr *bit_width = nullptr; if (bitfield_bit_size != 0) { - llvm::APInt bitfield_bit_size_apint( - clang_ast->getTypeSize(clang_ast->IntTy), bitfield_bit_size); - bit_width = new (*clang_ast) - clang::IntegerLiteral(*clang_ast, bitfield_bit_size_apint, - clang_ast->IntTy, clang::SourceLocation()); + llvm::APInt bitfield_bit_size_apint(clang_ast.getTypeSize(clang_ast.IntTy), + bitfield_bit_size); + bit_width = new (clang_ast) + clang::IntegerLiteral(clang_ast, bitfield_bit_size_apint, + clang_ast.IntTy, clang::SourceLocation()); } clang::RecordDecl *record_decl = ast->GetAsRecordDecl(type); if (record_decl) { field = clang::FieldDecl::Create( - *clang_ast, record_decl, clang::SourceLocation(), + clang_ast, record_decl, clang::SourceLocation(), clang::SourceLocation(), ident, // Identifier ClangUtil::GetQualType(field_clang_type), // Field type @@ -7939,7 +6931,7 @@ clang::FieldDecl *ClangASTContext::AddFieldToRecordType( field_clang_type.GetCompleteType(); field = clang::ObjCIvarDecl::Create( - *clang_ast, class_interface_decl, clang::SourceLocation(), + clang_ast, class_interface_decl, clang::SourceLocation(), clang::SourceLocation(), ident, // Identifier ClangUtil::GetQualType(field_clang_type), // Field type @@ -8001,12 +6993,12 @@ void ClangASTContext::BuildIndirectFields(const CompilerType &type) { if (clang::FieldDecl *nested_field_decl = llvm::dyn_cast<clang::FieldDecl>(*di)) { clang::NamedDecl **chain = - new (*ast->getASTContext()) clang::NamedDecl *[2]; + new (ast->getASTContext()) clang::NamedDecl *[2]; chain[0] = *field_pos; chain[1] = nested_field_decl; clang::IndirectFieldDecl *indirect_field = clang::IndirectFieldDecl::Create( - *ast->getASTContext(), record_decl, clang::SourceLocation(), + ast->getASTContext(), record_decl, clang::SourceLocation(), nested_field_decl->getIdentifier(), nested_field_decl->getType(), {chain, 2}); @@ -8020,7 +7012,7 @@ void ClangASTContext::BuildIndirectFields(const CompilerType &type) { llvm::dyn_cast<clang::IndirectFieldDecl>(*di)) { size_t nested_chain_size = nested_indirect_field_decl->getChainingSize(); - clang::NamedDecl **chain = new (*ast->getASTContext()) + clang::NamedDecl **chain = new (ast->getASTContext()) clang::NamedDecl *[nested_chain_size + 1]; chain[0] = *field_pos; @@ -8035,7 +7027,7 @@ void ClangASTContext::BuildIndirectFields(const CompilerType &type) { clang::IndirectFieldDecl *indirect_field = clang::IndirectFieldDecl::Create( - *ast->getASTContext(), record_decl, clang::SourceLocation(), + ast->getASTContext(), record_decl, clang::SourceLocation(), nested_indirect_field_decl->getIdentifier(), nested_indirect_field_decl->getType(), {chain, nested_chain_size + 1}); @@ -8076,7 +7068,7 @@ void ClangASTContext::SetIsPacked(const CompilerType &type) { return; record_decl->addAttr( - clang::PackedAttr::CreateImplicit(*ast->getASTContext())); + clang::PackedAttr::CreateImplicit(ast->getASTContext())); } } } @@ -8098,10 +7090,10 @@ clang::VarDecl *ClangASTContext::AddVariableToRecordType( clang::VarDecl *var_decl = nullptr; clang::IdentifierInfo *ident = nullptr; if (!name.empty()) - ident = &ast->getASTContext()->Idents.get(name); + ident = &ast->getASTContext().Idents.get(name); var_decl = clang::VarDecl::Create( - *ast->getASTContext(), // ASTContext & + ast->getASTContext(), // ASTContext & record_decl, // DeclContext * clang::SourceLocation(), // clang::SourceLocation StartLoc clang::SourceLocation(), // clang::SourceLocation IdLoc @@ -8124,12 +7116,11 @@ clang::VarDecl *ClangASTContext::AddVariableToRecordType( } clang::CXXMethodDecl *ClangASTContext::AddMethodToCXXRecordType( - lldb::opaque_compiler_type_t type, const char *name, const char *mangled_name, - const CompilerType &method_clang_type, lldb::AccessType access, - bool is_virtual, bool is_static, bool is_inline, bool is_explicit, - bool is_attr_used, bool is_artificial) { - if (!type || !method_clang_type.IsValid() || name == nullptr || - name[0] == '\0') + lldb::opaque_compiler_type_t type, llvm::StringRef name, + const char *mangled_name, const CompilerType &method_clang_type, + lldb::AccessType access, bool is_virtual, bool is_static, bool is_inline, + bool is_explicit, bool is_attr_used, bool is_artificial) { + if (!type || !method_clang_type.IsValid() || name.empty()) return nullptr; clang::QualType record_qual_type(GetCanonicalQualType(type)); @@ -8144,7 +7135,7 @@ clang::CXXMethodDecl *ClangASTContext::AddMethodToCXXRecordType( clang::CXXMethodDecl *cxx_method_decl = nullptr; - clang::DeclarationName decl_name(&getASTContext()->Idents.get(name)); + clang::DeclarationName decl_name(&getASTContext().Idents.get(name)); const clang::FunctionType *function_type = llvm::dyn_cast<clang::FunctionType>(method_qual_type.getTypePtr()); @@ -8170,22 +7161,22 @@ clang::CXXMethodDecl *ClangASTContext::AddMethodToCXXRecordType( nullptr /*expr*/, is_explicit ? clang::ExplicitSpecKind::ResolvedTrue : clang::ExplicitSpecKind::ResolvedFalse); - if (name[0] == '~') { + if (name.startswith("~")) { cxx_dtor_decl = clang::CXXDestructorDecl::Create( - *getASTContext(), cxx_record_decl, clang::SourceLocation(), + getASTContext(), cxx_record_decl, clang::SourceLocation(), clang::DeclarationNameInfo( - getASTContext()->DeclarationNames.getCXXDestructorName( - getASTContext()->getCanonicalType(record_qual_type)), + getASTContext().DeclarationNames.getCXXDestructorName( + getASTContext().getCanonicalType(record_qual_type)), clang::SourceLocation()), method_qual_type, nullptr, is_inline, is_artificial, - ConstexprSpecKind::CSK_unspecified); + ConstexprSpecKind::CSK_unspecified); cxx_method_decl = cxx_dtor_decl; } else if (decl_name == cxx_record_decl->getDeclName()) { cxx_ctor_decl = clang::CXXConstructorDecl::Create( - *getASTContext(), cxx_record_decl, clang::SourceLocation(), + getASTContext(), cxx_record_decl, clang::SourceLocation(), clang::DeclarationNameInfo( - getASTContext()->DeclarationNames.getCXXConstructorName( - getASTContext()->getCanonicalType(record_qual_type)), + getASTContext().DeclarationNames.getCXXConstructorName( + getASTContext().getCanonicalType(record_qual_type)), clang::SourceLocation()), method_qual_type, nullptr, // TypeSourceInfo * @@ -8206,9 +7197,9 @@ clang::CXXMethodDecl *ClangASTContext::AddMethodToCXXRecordType( is_method, op_kind, num_params)) return nullptr; cxx_method_decl = clang::CXXMethodDecl::Create( - *getASTContext(), cxx_record_decl, clang::SourceLocation(), + getASTContext(), cxx_record_decl, clang::SourceLocation(), clang::DeclarationNameInfo( - getASTContext()->DeclarationNames.getCXXOperatorName(op_kind), + getASTContext().DeclarationNames.getCXXOperatorName(op_kind), clang::SourceLocation()), method_qual_type, nullptr, // TypeSourceInfo * @@ -8216,22 +7207,21 @@ clang::CXXMethodDecl *ClangASTContext::AddMethodToCXXRecordType( } else if (num_params == 0) { // Conversion operators don't take params... cxx_method_decl = clang::CXXConversionDecl::Create( - *getASTContext(), cxx_record_decl, clang::SourceLocation(), + getASTContext(), cxx_record_decl, clang::SourceLocation(), clang::DeclarationNameInfo( - getASTContext()->DeclarationNames.getCXXConversionFunctionName( - getASTContext()->getCanonicalType( + getASTContext().DeclarationNames.getCXXConversionFunctionName( + getASTContext().getCanonicalType( function_type->getReturnType())), clang::SourceLocation()), method_qual_type, nullptr, // TypeSourceInfo * - is_inline, explicit_spec, CSK_unspecified, - clang::SourceLocation()); + is_inline, explicit_spec, CSK_unspecified, clang::SourceLocation()); } } if (cxx_method_decl == nullptr) { cxx_method_decl = clang::CXXMethodDecl::Create( - *getASTContext(), cxx_record_decl, clang::SourceLocation(), + getASTContext(), cxx_record_decl, clang::SourceLocation(), clang::DeclarationNameInfo(decl_name, clang::SourceLocation()), method_qual_type, nullptr, // TypeSourceInfo * @@ -8246,11 +7236,11 @@ clang::CXXMethodDecl *ClangASTContext::AddMethodToCXXRecordType( cxx_method_decl->setVirtualAsWritten(is_virtual); if (is_attr_used) - cxx_method_decl->addAttr(clang::UsedAttr::CreateImplicit(*getASTContext())); + cxx_method_decl->addAttr(clang::UsedAttr::CreateImplicit(getASTContext())); if (mangled_name != nullptr) { cxx_method_decl->addAttr(clang::AsmLabelAttr::CreateImplicit( - *getASTContext(), mangled_name, /*literal=*/false)); + getASTContext(), mangled_name, /*literal=*/false)); } // Populate the method decl with parameter decls @@ -8259,7 +7249,7 @@ clang::CXXMethodDecl *ClangASTContext::AddMethodToCXXRecordType( for (unsigned param_index = 0; param_index < num_params; ++param_index) { params.push_back(clang::ParmVarDecl::Create( - *getASTContext(), cxx_method_decl, clang::SourceLocation(), + getASTContext(), cxx_method_decl, clang::SourceLocation(), clang::SourceLocation(), nullptr, // anonymous method_function_prototype->getParamType(param_index), nullptr, @@ -8326,7 +7316,7 @@ ClangASTContext::CreateBaseClassSpecifier(lldb::opaque_compiler_type_t type, return std::make_unique<clang::CXXBaseSpecifier>( clang::SourceRange(), is_virtual, base_of_class, ClangASTContext::ConvertAccessTypeToAccessSpecifier(access), - getASTContext()->getTrivialTypeSourceInfo(GetQualType(type)), + getASTContext().getTrivialTypeSourceInfo(GetQualType(type)), clang::SourceLocation()); } @@ -8355,7 +7345,7 @@ bool ClangASTContext::SetObjCSuperClass( llvm::dyn_cast_or_null<ClangASTContext>(type.GetTypeSystem()); if (!ast) return false; - clang::ASTContext *clang_ast = ast->getASTContext(); + clang::ASTContext &clang_ast = ast->getASTContext(); if (type && superclass_clang_type.IsValid() && superclass_clang_type.GetTypeSystem() == type.GetTypeSystem()) { @@ -8364,8 +7354,8 @@ bool ClangASTContext::SetObjCSuperClass( clang::ObjCInterfaceDecl *super_interface_decl = GetAsObjCInterfaceDecl(superclass_clang_type); if (class_interface_decl && super_interface_decl) { - class_interface_decl->setSuperClass(clang_ast->getTrivialTypeSourceInfo( - clang_ast->getObjCInterfaceType(super_interface_decl))); + class_interface_decl->setSuperClass(clang_ast.getTrivialTypeSourceInfo( + clang_ast.getObjCInterfaceType(super_interface_decl))); return true; } } @@ -8383,188 +7373,182 @@ bool ClangASTContext::AddObjCClassProperty( ClangASTContext *ast = llvm::dyn_cast<ClangASTContext>(type.GetTypeSystem()); if (!ast) return false; - clang::ASTContext *clang_ast = ast->getASTContext(); + clang::ASTContext &clang_ast = ast->getASTContext(); clang::ObjCInterfaceDecl *class_interface_decl = GetAsObjCInterfaceDecl(type); + if (!class_interface_decl) + return false; - if (class_interface_decl) { - CompilerType property_clang_type_to_access; - - if (property_clang_type.IsValid()) - property_clang_type_to_access = property_clang_type; - else if (ivar_decl) - property_clang_type_to_access = - CompilerType(ast, ivar_decl->getType().getAsOpaquePtr()); - - if (class_interface_decl && property_clang_type_to_access.IsValid()) { - clang::TypeSourceInfo *prop_type_source; - if (ivar_decl) - prop_type_source = - clang_ast->getTrivialTypeSourceInfo(ivar_decl->getType()); - else - prop_type_source = clang_ast->getTrivialTypeSourceInfo( - ClangUtil::GetQualType(property_clang_type)); - - clang::ObjCPropertyDecl *property_decl = clang::ObjCPropertyDecl::Create( - *clang_ast, class_interface_decl, - clang::SourceLocation(), // Source Location - &clang_ast->Idents.get(property_name), - clang::SourceLocation(), // Source Location for AT - clang::SourceLocation(), // Source location for ( - ivar_decl ? ivar_decl->getType() - : ClangUtil::GetQualType(property_clang_type), - prop_type_source); - - if (property_decl) { - if (metadata) - ClangASTContext::SetMetadata(clang_ast, property_decl, *metadata); - - class_interface_decl->addDecl(property_decl); - - clang::Selector setter_sel, getter_sel; - - if (property_setter_name != nullptr) { - std::string property_setter_no_colon( - property_setter_name, strlen(property_setter_name) - 1); - clang::IdentifierInfo *setter_ident = - &clang_ast->Idents.get(property_setter_no_colon); - setter_sel = clang_ast->Selectors.getSelector(1, &setter_ident); - } else if (!(property_attributes & DW_APPLE_PROPERTY_readonly)) { - std::string setter_sel_string("set"); - setter_sel_string.push_back(::toupper(property_name[0])); - setter_sel_string.append(&property_name[1]); - clang::IdentifierInfo *setter_ident = - &clang_ast->Idents.get(setter_sel_string); - setter_sel = clang_ast->Selectors.getSelector(1, &setter_ident); - } - property_decl->setSetterName(setter_sel); - property_decl->setPropertyAttributes( - clang::ObjCPropertyDecl::OBJC_PR_setter); - - if (property_getter_name != nullptr) { - clang::IdentifierInfo *getter_ident = - &clang_ast->Idents.get(property_getter_name); - getter_sel = clang_ast->Selectors.getSelector(0, &getter_ident); - } else { - clang::IdentifierInfo *getter_ident = - &clang_ast->Idents.get(property_name); - getter_sel = clang_ast->Selectors.getSelector(0, &getter_ident); - } - property_decl->setGetterName(getter_sel); - property_decl->setPropertyAttributes( - clang::ObjCPropertyDecl::OBJC_PR_getter); - - if (ivar_decl) - property_decl->setPropertyIvarDecl(ivar_decl); - - if (property_attributes & DW_APPLE_PROPERTY_readonly) - property_decl->setPropertyAttributes( - clang::ObjCPropertyDecl::OBJC_PR_readonly); - if (property_attributes & DW_APPLE_PROPERTY_readwrite) - property_decl->setPropertyAttributes( - clang::ObjCPropertyDecl::OBJC_PR_readwrite); - if (property_attributes & DW_APPLE_PROPERTY_assign) - property_decl->setPropertyAttributes( - clang::ObjCPropertyDecl::OBJC_PR_assign); - if (property_attributes & DW_APPLE_PROPERTY_retain) - property_decl->setPropertyAttributes( - clang::ObjCPropertyDecl::OBJC_PR_retain); - if (property_attributes & DW_APPLE_PROPERTY_copy) - property_decl->setPropertyAttributes( - clang::ObjCPropertyDecl::OBJC_PR_copy); - if (property_attributes & DW_APPLE_PROPERTY_nonatomic) - property_decl->setPropertyAttributes( - clang::ObjCPropertyDecl::OBJC_PR_nonatomic); - if (property_attributes & clang::ObjCPropertyDecl::OBJC_PR_nullability) - property_decl->setPropertyAttributes( - clang::ObjCPropertyDecl::OBJC_PR_nullability); - if (property_attributes & - clang::ObjCPropertyDecl::OBJC_PR_null_resettable) - property_decl->setPropertyAttributes( - clang::ObjCPropertyDecl::OBJC_PR_null_resettable); - if (property_attributes & clang::ObjCPropertyDecl::OBJC_PR_class) - property_decl->setPropertyAttributes( - clang::ObjCPropertyDecl::OBJC_PR_class); - - const bool isInstance = - (property_attributes & clang::ObjCPropertyDecl::OBJC_PR_class) == 0; - - if (!getter_sel.isNull() && - !(isInstance - ? class_interface_decl->lookupInstanceMethod(getter_sel) - : class_interface_decl->lookupClassMethod(getter_sel))) { - const bool isVariadic = false; - const bool isSynthesized = false; - const bool isImplicitlyDeclared = true; - const bool isDefined = false; - const clang::ObjCMethodDecl::ImplementationControl impControl = - clang::ObjCMethodDecl::None; - const bool HasRelatedResultType = false; - - clang::ObjCMethodDecl *getter = clang::ObjCMethodDecl::Create( - *clang_ast, clang::SourceLocation(), clang::SourceLocation(), - getter_sel, ClangUtil::GetQualType(property_clang_type_to_access), - nullptr, class_interface_decl, isInstance, isVariadic, - isSynthesized, isImplicitlyDeclared, isDefined, impControl, - HasRelatedResultType); - - if (getter && metadata) - ClangASTContext::SetMetadata(clang_ast, getter, *metadata); - - if (getter) { - getter->setMethodParams(*clang_ast, - llvm::ArrayRef<clang::ParmVarDecl *>(), - llvm::ArrayRef<clang::SourceLocation>()); - - class_interface_decl->addDecl(getter); - } - } + CompilerType property_clang_type_to_access; - if (!setter_sel.isNull() && - !(isInstance - ? class_interface_decl->lookupInstanceMethod(setter_sel) - : class_interface_decl->lookupClassMethod(setter_sel))) { - clang::QualType result_type = clang_ast->VoidTy; - const bool isVariadic = false; - const bool isSynthesized = false; - const bool isImplicitlyDeclared = true; - const bool isDefined = false; - const clang::ObjCMethodDecl::ImplementationControl impControl = - clang::ObjCMethodDecl::None; - const bool HasRelatedResultType = false; - - clang::ObjCMethodDecl *setter = clang::ObjCMethodDecl::Create( - *clang_ast, clang::SourceLocation(), clang::SourceLocation(), - setter_sel, result_type, nullptr, class_interface_decl, - isInstance, isVariadic, isSynthesized, isImplicitlyDeclared, - isDefined, impControl, HasRelatedResultType); - - if (setter && metadata) - ClangASTContext::SetMetadata(clang_ast, setter, *metadata); - - llvm::SmallVector<clang::ParmVarDecl *, 1> params; - - params.push_back(clang::ParmVarDecl::Create( - *clang_ast, setter, clang::SourceLocation(), - clang::SourceLocation(), - nullptr, // anonymous - ClangUtil::GetQualType(property_clang_type_to_access), nullptr, - clang::SC_Auto, nullptr)); - - if (setter) { - setter->setMethodParams( - *clang_ast, llvm::ArrayRef<clang::ParmVarDecl *>(params), - llvm::ArrayRef<clang::SourceLocation>()); - - class_interface_decl->addDecl(setter); - } - } + if (property_clang_type.IsValid()) + property_clang_type_to_access = property_clang_type; + else if (ivar_decl) + property_clang_type_to_access = ast->GetType(ivar_decl->getType()); - return true; - } + if (!class_interface_decl || !property_clang_type_to_access.IsValid()) + return false; + + clang::TypeSourceInfo *prop_type_source; + if (ivar_decl) + prop_type_source = clang_ast.getTrivialTypeSourceInfo(ivar_decl->getType()); + else + prop_type_source = clang_ast.getTrivialTypeSourceInfo( + ClangUtil::GetQualType(property_clang_type)); + + clang::ObjCPropertyDecl *property_decl = clang::ObjCPropertyDecl::Create( + clang_ast, class_interface_decl, + clang::SourceLocation(), // Source Location + &clang_ast.Idents.get(property_name), + clang::SourceLocation(), // Source Location for AT + clang::SourceLocation(), // Source location for ( + ivar_decl ? ivar_decl->getType() + : ClangUtil::GetQualType(property_clang_type), + prop_type_source); + + if (!property_decl) + return false; + + if (metadata) + ast->SetMetadata(property_decl, *metadata); + + class_interface_decl->addDecl(property_decl); + + clang::Selector setter_sel, getter_sel; + + if (property_setter_name) { + std::string property_setter_no_colon(property_setter_name, + strlen(property_setter_name) - 1); + clang::IdentifierInfo *setter_ident = + &clang_ast.Idents.get(property_setter_no_colon); + setter_sel = clang_ast.Selectors.getSelector(1, &setter_ident); + } else if (!(property_attributes & DW_APPLE_PROPERTY_readonly)) { + std::string setter_sel_string("set"); + setter_sel_string.push_back(::toupper(property_name[0])); + setter_sel_string.append(&property_name[1]); + clang::IdentifierInfo *setter_ident = + &clang_ast.Idents.get(setter_sel_string); + setter_sel = clang_ast.Selectors.getSelector(1, &setter_ident); + } + property_decl->setSetterName(setter_sel); + property_decl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_setter); + + if (property_getter_name != nullptr) { + clang::IdentifierInfo *getter_ident = + &clang_ast.Idents.get(property_getter_name); + getter_sel = clang_ast.Selectors.getSelector(0, &getter_ident); + } else { + clang::IdentifierInfo *getter_ident = &clang_ast.Idents.get(property_name); + getter_sel = clang_ast.Selectors.getSelector(0, &getter_ident); + } + property_decl->setGetterName(getter_sel); + property_decl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_getter); + + if (ivar_decl) + property_decl->setPropertyIvarDecl(ivar_decl); + + if (property_attributes & DW_APPLE_PROPERTY_readonly) + property_decl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_readonly); + if (property_attributes & DW_APPLE_PROPERTY_readwrite) + property_decl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_readwrite); + if (property_attributes & DW_APPLE_PROPERTY_assign) + property_decl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_assign); + if (property_attributes & DW_APPLE_PROPERTY_retain) + property_decl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_retain); + if (property_attributes & DW_APPLE_PROPERTY_copy) + property_decl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_copy); + if (property_attributes & DW_APPLE_PROPERTY_nonatomic) + property_decl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_nonatomic); + if (property_attributes & ObjCPropertyDecl::OBJC_PR_nullability) + property_decl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_nullability); + if (property_attributes & ObjCPropertyDecl::OBJC_PR_null_resettable) + property_decl->setPropertyAttributes( + ObjCPropertyDecl::OBJC_PR_null_resettable); + if (property_attributes & ObjCPropertyDecl::OBJC_PR_class) + property_decl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_class); + + const bool isInstance = + (property_attributes & ObjCPropertyDecl::OBJC_PR_class) == 0; + + clang::ObjCMethodDecl *getter = nullptr; + if (!getter_sel.isNull()) + getter = isInstance ? class_interface_decl->lookupInstanceMethod(getter_sel) + : class_interface_decl->lookupClassMethod(getter_sel); + if (!getter_sel.isNull() && !getter) { + const bool isVariadic = false; + const bool isPropertyAccessor = false; + const bool isSynthesizedAccessorStub = false; + const bool isImplicitlyDeclared = true; + const bool isDefined = false; + const clang::ObjCMethodDecl::ImplementationControl impControl = + clang::ObjCMethodDecl::None; + const bool HasRelatedResultType = false; + + getter = clang::ObjCMethodDecl::Create( + clang_ast, clang::SourceLocation(), clang::SourceLocation(), getter_sel, + ClangUtil::GetQualType(property_clang_type_to_access), nullptr, + class_interface_decl, isInstance, isVariadic, isPropertyAccessor, + isSynthesizedAccessorStub, isImplicitlyDeclared, isDefined, impControl, + HasRelatedResultType); + + if (getter) { + if (metadata) + ast->SetMetadata(getter, *metadata); + + getter->setMethodParams(clang_ast, llvm::ArrayRef<clang::ParmVarDecl *>(), + llvm::ArrayRef<clang::SourceLocation>()); + class_interface_decl->addDecl(getter); + } + } + if (getter) { + getter->setPropertyAccessor(true); + property_decl->setGetterMethodDecl(getter); + } + + clang::ObjCMethodDecl *setter = nullptr; + setter = isInstance ? class_interface_decl->lookupInstanceMethod(setter_sel) + : class_interface_decl->lookupClassMethod(setter_sel); + if (!setter_sel.isNull() && !setter) { + clang::QualType result_type = clang_ast.VoidTy; + const bool isVariadic = false; + const bool isPropertyAccessor = true; + const bool isSynthesizedAccessorStub = false; + const bool isImplicitlyDeclared = true; + const bool isDefined = false; + const clang::ObjCMethodDecl::ImplementationControl impControl = + clang::ObjCMethodDecl::None; + const bool HasRelatedResultType = false; + + setter = clang::ObjCMethodDecl::Create( + clang_ast, clang::SourceLocation(), clang::SourceLocation(), setter_sel, + result_type, nullptr, class_interface_decl, isInstance, isVariadic, + isPropertyAccessor, isSynthesizedAccessorStub, isImplicitlyDeclared, + isDefined, impControl, HasRelatedResultType); + + if (setter) { + if (metadata) + ast->SetMetadata(setter, *metadata); + + llvm::SmallVector<clang::ParmVarDecl *, 1> params; + params.push_back(clang::ParmVarDecl::Create( + clang_ast, setter, clang::SourceLocation(), clang::SourceLocation(), + nullptr, // anonymous + ClangUtil::GetQualType(property_clang_type_to_access), nullptr, + clang::SC_Auto, nullptr)); + + setter->setMethodParams(clang_ast, + llvm::ArrayRef<clang::ParmVarDecl *>(params), + llvm::ArrayRef<clang::SourceLocation>()); + + class_interface_decl->addDecl(setter); } } - return false; + if (setter) { + setter->setPropertyAccessor(true); + property_decl->setSetterMethodDecl(setter); + } + + return true; } bool ClangASTContext::IsObjCClassTypeAndHasIVars(const CompilerType &type, @@ -8581,7 +7565,7 @@ clang::ObjCMethodDecl *ClangASTContext::AddMethodToObjCObjectType( // (lldb::opaque_compiler_type_t type, "-[NString // stringWithCString:]") const CompilerType &method_clang_type, lldb::AccessType access, - bool is_artificial, bool is_variadic) { + bool is_artificial, bool is_variadic, bool is_objc_direct_call) { if (!type || !method_clang_type.IsValid()) return nullptr; @@ -8593,7 +7577,7 @@ clang::ObjCMethodDecl *ClangASTContext::AddMethodToObjCObjectType( llvm::dyn_cast<ClangASTContext>(type.GetTypeSystem()); if (lldb_ast == nullptr) return nullptr; - clang::ASTContext *ast = lldb_ast->getASTContext(); + clang::ASTContext &ast = lldb_ast->getASTContext(); const char *selector_start = ::strchr(name, ' '); if (selector_start == nullptr) @@ -8613,7 +7597,7 @@ clang::ObjCMethodDecl *ClangASTContext::AddMethodToObjCObjectType( bool has_arg = (start[len] == ':'); if (has_arg) ++num_selectors_with_args; - selector_idents.push_back(&ast->Idents.get(llvm::StringRef(start, len))); + selector_idents.push_back(&ast.Idents.get(llvm::StringRef(start, len))); if (has_arg) len += 1; } @@ -8621,7 +7605,7 @@ clang::ObjCMethodDecl *ClangASTContext::AddMethodToObjCObjectType( if (selector_idents.size() == 0) return nullptr; - clang::Selector method_selector = ast->Selectors.getSelector( + clang::Selector method_selector = ast.Selectors.getSelector( num_selectors_with_args ? selector_idents.size() : 0, selector_idents.data()); @@ -8639,10 +7623,16 @@ clang::ObjCMethodDecl *ClangASTContext::AddMethodToObjCObjectType( if (!method_function_prototype) return nullptr; - bool is_synthesized = false; - bool is_defined = false; - clang::ObjCMethodDecl::ImplementationControl imp_control = + const bool isInstance = (name[0] == '-'); + const bool isVariadic = is_variadic; + const bool isPropertyAccessor = false; + const bool isSynthesizedAccessorStub = false; + /// Force this to true because we don't have source locations. + const bool isImplicitlyDeclared = true; + const bool isDefined = false; + const clang::ObjCMethodDecl::ImplementationControl impControl = clang::ObjCMethodDecl::None; + const bool HasRelatedResultType = false; const unsigned num_args = method_function_prototype->getNumParams(); @@ -8651,17 +7641,14 @@ clang::ObjCMethodDecl *ClangASTContext::AddMethodToObjCObjectType( // deal with it. clang::ObjCMethodDecl *objc_method_decl = clang::ObjCMethodDecl::Create( - *ast, + ast, clang::SourceLocation(), // beginLoc, clang::SourceLocation(), // endLoc, method_selector, method_function_prototype->getReturnType(), nullptr, // TypeSourceInfo *ResultTInfo, - ClangASTContext::GetASTContext(ast)->GetDeclContextForType( - ClangUtil::GetQualType(type)), - name[0] == '-', is_variadic, is_synthesized, - true, // is_implicitly_declared; we force this to true because we don't - // have source locations - is_defined, imp_control, false /*has_related_result_type*/); + lldb_ast->GetDeclContextForType(ClangUtil::GetQualType(type)), isInstance, + isVariadic, isPropertyAccessor, isSynthesizedAccessorStub, + isImplicitlyDeclared, isDefined, impControl, HasRelatedResultType); if (objc_method_decl == nullptr) return nullptr; @@ -8671,7 +7658,7 @@ clang::ObjCMethodDecl *ClangASTContext::AddMethodToObjCObjectType( for (unsigned param_index = 0; param_index < num_args; ++param_index) { params.push_back(clang::ParmVarDecl::Create( - *ast, objc_method_decl, clang::SourceLocation(), + ast, objc_method_decl, clang::SourceLocation(), clang::SourceLocation(), nullptr, // anonymous method_function_prototype->getParamType(param_index), nullptr, @@ -8679,10 +7666,22 @@ clang::ObjCMethodDecl *ClangASTContext::AddMethodToObjCObjectType( } objc_method_decl->setMethodParams( - *ast, llvm::ArrayRef<clang::ParmVarDecl *>(params), + ast, llvm::ArrayRef<clang::ParmVarDecl *>(params), llvm::ArrayRef<clang::SourceLocation>()); } + if (is_objc_direct_call) { + // Add a the objc_direct attribute to the declaration we generate that + // we generate a direct method call for this ObjCMethodDecl. + objc_method_decl->addAttr( + clang::ObjCDirectAttr::CreateImplicit(ast, SourceLocation())); + // Usually Sema is creating implicit parameters (e.g., self) when it + // parses the method. We don't have a parsing Sema when we build our own + // AST here so we manually need to create these implicit parameters to + // make the direct call code generation happy. + objc_method_decl->createImplicitParams(ast, class_interface_decl); + } + class_interface_decl->addDecl(objc_method_decl); #ifdef LLDB_CONFIGURATION_DEBUG @@ -8697,7 +7696,7 @@ bool ClangASTContext::SetHasExternalStorage(lldb::opaque_compiler_type_t type, if (!type) return false; - clang::QualType qual_type(GetCanonicalQualType(type)); + clang::QualType qual_type(RemoveWrappingTypes(GetCanonicalQualType(type))); const clang::Type::TypeClass type_class = qual_type->getTypeClass(); switch (type_class) { @@ -8737,30 +7736,6 @@ bool ClangASTContext::SetHasExternalStorage(lldb::opaque_compiler_type_t type, } } break; - case clang::Type::Typedef: - return SetHasExternalStorage(llvm::cast<clang::TypedefType>(qual_type) - ->getDecl() - ->getUnderlyingType() - .getAsOpaquePtr(), - has_extern); - - case clang::Type::Auto: - return SetHasExternalStorage(llvm::cast<clang::AutoType>(qual_type) - ->getDeducedType() - .getAsOpaquePtr(), - has_extern); - - case clang::Type::Elaborated: - return SetHasExternalStorage(llvm::cast<clang::ElaboratedType>(qual_type) - ->getNamedType() - .getAsOpaquePtr(), - has_extern); - - case clang::Type::Paren: - return SetHasExternalStorage( - llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(), - has_extern); - default: break; } @@ -8797,70 +7772,65 @@ bool ClangASTContext::StartTagDeclarationDefinition(const CompilerType &type) { bool ClangASTContext::CompleteTagDeclarationDefinition( const CompilerType &type) { clang::QualType qual_type(ClangUtil::GetQualType(type)); - if (!qual_type.isNull()) { - // Make sure we use the same methodology as - // ClangASTContext::StartTagDeclarationDefinition() as to how we start/end - // the definition. Previously we were calling - const clang::TagType *tag_type = qual_type->getAs<clang::TagType>(); - if (tag_type) { - clang::TagDecl *tag_decl = tag_type->getDecl(); - if (tag_decl) { - clang::CXXRecordDecl *cxx_record_decl = - llvm::dyn_cast_or_null<clang::CXXRecordDecl>(tag_decl); + if (qual_type.isNull()) + return false; - if (cxx_record_decl) { - if (!cxx_record_decl->isCompleteDefinition()) - cxx_record_decl->completeDefinition(); - cxx_record_decl->setHasLoadedFieldsFromExternalStorage(true); - cxx_record_decl->setHasExternalLexicalStorage(false); - cxx_record_decl->setHasExternalVisibleStorage(false); - return true; - } - } + // Make sure we use the same methodology as + // ClangASTContext::StartTagDeclarationDefinition() as to how we start/end + // the definition. + const clang::TagType *tag_type = qual_type->getAs<clang::TagType>(); + if (tag_type) { + clang::TagDecl *tag_decl = tag_type->getDecl(); + + if (auto *cxx_record_decl = llvm::dyn_cast<CXXRecordDecl>(tag_decl)) { + if (!cxx_record_decl->isCompleteDefinition()) + cxx_record_decl->completeDefinition(); + cxx_record_decl->setHasLoadedFieldsFromExternalStorage(true); + cxx_record_decl->setHasExternalLexicalStorage(false); + cxx_record_decl->setHasExternalVisibleStorage(false); + return true; } + } - const clang::EnumType *enutype = qual_type->getAs<clang::EnumType>(); + const clang::EnumType *enutype = qual_type->getAs<clang::EnumType>(); - if (enutype) { - clang::EnumDecl *enum_decl = enutype->getDecl(); + if (!enutype) + return false; + clang::EnumDecl *enum_decl = enutype->getDecl(); - if (enum_decl) { - if (!enum_decl->isCompleteDefinition()) { - ClangASTContext *lldb_ast = - llvm::dyn_cast<ClangASTContext>(type.GetTypeSystem()); - if (lldb_ast == nullptr) - return false; - clang::ASTContext *ast = lldb_ast->getASTContext(); - - /// TODO This really needs to be fixed. - - QualType integer_type(enum_decl->getIntegerType()); - if (!integer_type.isNull()) { - unsigned NumPositiveBits = 1; - unsigned NumNegativeBits = 0; - - clang::QualType promotion_qual_type; - // If the enum integer type is less than an integer in bit width, - // then we must promote it to an integer size. - if (ast->getTypeSize(enum_decl->getIntegerType()) < - ast->getTypeSize(ast->IntTy)) { - if (enum_decl->getIntegerType()->isSignedIntegerType()) - promotion_qual_type = ast->IntTy; - else - promotion_qual_type = ast->UnsignedIntTy; - } else - promotion_qual_type = enum_decl->getIntegerType(); + if (enum_decl->isCompleteDefinition()) + return true; - enum_decl->completeDefinition(enum_decl->getIntegerType(), - promotion_qual_type, NumPositiveBits, - NumNegativeBits); - } - } - return true; - } - } + ClangASTContext *lldb_ast = + llvm::dyn_cast<ClangASTContext>(type.GetTypeSystem()); + if (lldb_ast == nullptr) + return false; + clang::ASTContext &ast = lldb_ast->getASTContext(); + + /// TODO This really needs to be fixed. + + QualType integer_type(enum_decl->getIntegerType()); + if (!integer_type.isNull()) { + unsigned NumPositiveBits = 1; + unsigned NumNegativeBits = 0; + + clang::QualType promotion_qual_type; + // If the enum integer type is less than an integer in bit width, + // then we must promote it to an integer size. + if (ast.getTypeSize(enum_decl->getIntegerType()) < + ast.getTypeSize(ast.IntTy)) { + if (enum_decl->getIntegerType()->isSignedIntegerType()) + promotion_qual_type = ast.IntTy; + else + promotion_qual_type = ast.UnsignedIntTy; + } else + promotion_qual_type = enum_decl->getIntegerType(); + + enum_decl->completeDefinition(enum_decl->getIntegerType(), + promotion_qual_type, NumPositiveBits, + NumNegativeBits); } - return false; + return true; } clang::EnumConstantDecl *ClangASTContext::AddEnumerationValueToEnumerationType( @@ -8892,8 +7862,8 @@ clang::EnumConstantDecl *ClangASTContext::AddEnumerationValueToEnumerationType( return nullptr; clang::EnumConstantDecl *enumerator_decl = clang::EnumConstantDecl::Create( - *getASTContext(), enutype->getDecl(), clang::SourceLocation(), - name ? &getASTContext()->Idents.get(name) : nullptr, // Identifier + getASTContext(), enutype->getDecl(), clang::SourceLocation(), + name ? &getASTContext().Idents.get(name) : nullptr, // Identifier clang::QualType(enutype, 0), nullptr, value); if (!enumerator_decl) @@ -8932,7 +7902,7 @@ ClangASTContext::GetEnumerationIntegerType(lldb::opaque_compiler_type_t type) { if (enutype) { clang::EnumDecl *enum_decl = enutype->getDecl(); if (enum_decl) - return CompilerType(this, enum_decl->getIntegerType().getAsOpaquePtr()); + return GetType(enum_decl->getIntegerType()); } } return CompilerType(); @@ -8947,11 +7917,9 @@ ClangASTContext::CreateMemberPointerType(const CompilerType &type, llvm::dyn_cast<ClangASTContext>(type.GetTypeSystem()); if (!ast) return CompilerType(); - return CompilerType(ast, ast->getASTContext() - ->getMemberPointerType( - ClangUtil::GetQualType(pointee_type), - ClangUtil::GetQualType(type).getTypePtr()) - .getAsOpaquePtr()); + return ast->GetType(ast->getASTContext().getMemberPointerType( + ClangUtil::GetQualType(pointee_type), + ClangUtil::GetQualType(type).getTypePtr())); } return CompilerType(); } @@ -8989,27 +7957,34 @@ void ClangASTContext::DumpFromSymbolFile(Stream &s, TypeSP type = type_list.GetTypeAtIndex(i); if (!symbol_name.empty()) - if (symbol_name.compare(type->GetName().GetStringRef()) != 0) + if (symbol_name != type->GetName().GetStringRef()) continue; s << type->GetName().AsCString() << "\n"; - if (clang::TagDecl *tag_decl = - GetAsTagDecl(type->GetFullCompilerType())) + CompilerType full_type = type->GetFullCompilerType(); + if (clang::TagDecl *tag_decl = GetAsTagDecl(full_type)) { tag_decl->dump(s.AsRawOstream()); - else if (clang::TypedefNameDecl *typedef_decl = - GetAsTypedefDecl(type->GetFullCompilerType())) + continue; + } + if (clang::TypedefNameDecl *typedef_decl = GetAsTypedefDecl(full_type)) { typedef_decl->dump(s.AsRawOstream()); - else { - GetCanonicalQualType(type->GetFullCompilerType().GetOpaqueQualType()) - .dump(s.AsRawOstream()); + continue; + } + if (auto *objc_obj = llvm::dyn_cast<clang::ObjCObjectType>( + ClangUtil::GetQualType(full_type).getTypePtr())) { + if (clang::ObjCInterfaceDecl *interface_decl = objc_obj->getInterface()) { + interface_decl->dump(s.AsRawOstream()); + continue; + } } + GetCanonicalQualType(full_type.GetOpaqueQualType()).dump(s.AsRawOstream()); } } void ClangASTContext::DumpValue( lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, Stream *s, - lldb::Format format, const DataExtractor &data, + lldb::Format format, const lldb_private::DataExtractor &data, lldb::offset_t data_byte_offset, size_t data_byte_size, uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset, bool show_types, bool show_summary, bool verbose, uint32_t depth) { @@ -9027,7 +8002,7 @@ void ClangASTContext::DumpValue( uint32_t field_bit_offset = 0; uint32_t field_byte_offset = 0; const clang::ASTRecordLayout &record_layout = - getASTContext()->getASTRecordLayout(record_decl); + getASTContext().getASTRecordLayout(record_decl); uint32_t child_idx = 0; const clang::CXXRecordDecl *cxx_record_decl = @@ -9071,11 +8046,10 @@ void ClangASTContext::DumpValue( base_class_type_name); clang::TypeInfo base_class_type_info = - getASTContext()->getTypeInfo(base_class_qual_type); + getASTContext().getTypeInfo(base_class_qual_type); // Dump the value of the member - CompilerType base_clang_type(this, - base_class_qual_type.getAsOpaquePtr()); + CompilerType base_clang_type = GetType(base_class_qual_type); base_clang_type.DumpValue( exe_ctx, s, // Stream to dump to @@ -9118,7 +8092,7 @@ void ClangASTContext::DumpValue( // Figure out the type byte size (field_type_info.first) and alignment // (field_type_info.second) from the AST context. clang::TypeInfo field_type_info = - getASTContext()->getTypeInfo(field_type); + getASTContext().getTypeInfo(field_type); assert(field_idx < record_layout.getFieldCount()); // Figure out the field offset within the current struct/union/class // type @@ -9126,8 +8100,7 @@ void ClangASTContext::DumpValue( field_byte_offset = field_bit_offset / 8; uint32_t field_bitfield_bit_size = 0; uint32_t field_bitfield_bit_offset = 0; - if (ClangASTContext::FieldIsBitfield(getASTContext(), *field, - field_bitfield_bit_size)) + if (FieldIsBitfield(*field, field_bitfield_bit_size)) field_bitfield_bit_offset = field_bit_offset % 8; if (show_types) { @@ -9142,7 +8115,7 @@ void ClangASTContext::DumpValue( s->Printf("%s = ", field->getNameAsString().c_str()); // Dump the value of the member - CompilerType field_clang_type(this, field_type.getAsOpaquePtr()); + CompilerType field_clang_type = GetType(field_type); field_clang_type.DumpValue( exe_ctx, s, // Stream to dump to @@ -9207,7 +8180,7 @@ void ClangASTContext::DumpValue( const uint64_t element_count = array->getSize().getLimitedValue(); clang::TypeInfo field_type_info = - getASTContext()->getTypeInfo(element_qual_type); + getASTContext().getTypeInfo(element_qual_type); uint32_t element_idx = 0; uint32_t element_offset = 0; @@ -9222,7 +8195,7 @@ void ClangASTContext::DumpValue( s->PutChar('"'); return; } else { - CompilerType element_clang_type(this, element_qual_type.getAsOpaquePtr()); + CompilerType element_clang_type = GetType(element_qual_type); lldb::Format element_format = element_clang_type.GetFormat(); for (element_idx = 0; element_idx < element_count; ++element_idx) { @@ -9273,10 +8246,10 @@ void ClangASTContext::DumpValue( ->getDecl() ->getUnderlyingType(); - CompilerType typedef_clang_type(this, typedef_qual_type.getAsOpaquePtr()); + CompilerType typedef_clang_type = GetType(typedef_qual_type); lldb::Format typedef_format = typedef_clang_type.GetFormat(); clang::TypeInfo typedef_type_info = - getASTContext()->getTypeInfo(typedef_qual_type); + getASTContext().getTypeInfo(typedef_qual_type); uint64_t typedef_byte_size = typedef_type_info.Width / 8; return typedef_clang_type.DumpValue( @@ -9298,11 +8271,10 @@ void ClangASTContext::DumpValue( case clang::Type::Auto: { clang::QualType elaborated_qual_type = llvm::cast<clang::AutoType>(qual_type)->getDeducedType(); - CompilerType elaborated_clang_type(this, - elaborated_qual_type.getAsOpaquePtr()); + CompilerType elaborated_clang_type = GetType(elaborated_qual_type); lldb::Format elaborated_format = elaborated_clang_type.GetFormat(); clang::TypeInfo elaborated_type_info = - getASTContext()->getTypeInfo(elaborated_qual_type); + getASTContext().getTypeInfo(elaborated_qual_type); uint64_t elaborated_byte_size = elaborated_type_info.Width / 8; return elaborated_clang_type.DumpValue( @@ -9324,11 +8296,10 @@ void ClangASTContext::DumpValue( case clang::Type::Elaborated: { clang::QualType elaborated_qual_type = llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType(); - CompilerType elaborated_clang_type(this, - elaborated_qual_type.getAsOpaquePtr()); + CompilerType elaborated_clang_type = GetType(elaborated_qual_type); lldb::Format elaborated_format = elaborated_clang_type.GetFormat(); clang::TypeInfo elaborated_type_info = - getASTContext()->getTypeInfo(elaborated_qual_type); + getASTContext().getTypeInfo(elaborated_qual_type); uint64_t elaborated_byte_size = elaborated_type_info.Width / 8; return elaborated_clang_type.DumpValue( @@ -9350,11 +8321,11 @@ void ClangASTContext::DumpValue( case clang::Type::Paren: { clang::QualType desugar_qual_type = llvm::cast<clang::ParenType>(qual_type)->desugar(); - CompilerType desugar_clang_type(this, desugar_qual_type.getAsOpaquePtr()); + CompilerType desugar_clang_type = GetType(desugar_qual_type); lldb::Format desugar_format = desugar_clang_type.GetFormat(); clang::TypeInfo desugar_type_info = - getASTContext()->getTypeInfo(desugar_qual_type); + getASTContext().getTypeInfo(desugar_qual_type); uint64_t desugar_byte_size = desugar_type_info.Width / 8; return desugar_clang_type.DumpValue( @@ -9467,8 +8438,8 @@ static bool DumpEnumValue(const clang::QualType &qual_type, Stream *s, bool ClangASTContext::DumpTypeValue( lldb::opaque_compiler_type_t type, Stream *s, lldb::Format format, - const DataExtractor &data, lldb::offset_t byte_offset, size_t byte_size, - uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset, + const lldb_private::DataExtractor &data, lldb::offset_t byte_offset, + size_t byte_size, uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset, ExecutionContextScope *exe_scope) { if (!type) return false; @@ -9491,11 +8462,11 @@ bool ClangASTContext::DumpTypeValue( llvm::cast<clang::TypedefType>(qual_type) ->getDecl() ->getUnderlyingType(); - CompilerType typedef_clang_type(this, typedef_qual_type.getAsOpaquePtr()); + CompilerType typedef_clang_type = GetType(typedef_qual_type); if (format == eFormatDefault) format = typedef_clang_type.GetFormat(); clang::TypeInfo typedef_type_info = - getASTContext()->getTypeInfo(typedef_qual_type); + getASTContext().getTypeInfo(typedef_qual_type); uint64_t typedef_byte_size = typedef_type_info.Width / 8; return typedef_clang_type.DumpTypeValue( @@ -9636,8 +8607,10 @@ void ClangASTContext::DumpSummary(lldb::opaque_compiler_type_t type, void ClangASTContext::DumpTypeDescription(lldb::opaque_compiler_type_t type) { StreamFile s(stdout, false); DumpTypeDescription(type, &s); - ClangASTMetadata *metadata = - ClangASTContext::GetMetadata(getASTContext(), type); + + CompilerType ct(this, type); + const clang::Type *clang_type = ClangUtil::GetQualType(ct).getTypePtr(); + ClangASTMetadata *metadata = GetMetadata(clang_type); if (metadata) { metadata->Dump(&s); } @@ -9646,7 +8619,8 @@ void ClangASTContext::DumpTypeDescription(lldb::opaque_compiler_type_t type) { void ClangASTContext::DumpTypeDescription(lldb::opaque_compiler_type_t type, Stream *s) { if (type) { - clang::QualType qual_type(GetQualType(type)); + clang::QualType qual_type = + RemoveWrappingTypes(GetQualType(type), {clang::Type::Typedef}); llvm::SmallVector<char, 1024> buf; llvm::raw_svector_ostream llvm_ostrm(buf); @@ -9664,7 +8638,7 @@ void ClangASTContext::DumpTypeDescription(lldb::opaque_compiler_type_t type, clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); if (class_interface_decl) { - clang::PrintingPolicy policy = getASTContext()->getPrintingPolicy(); + clang::PrintingPolicy policy = getASTContext().getPrintingPolicy(); class_interface_decl->print(llvm_ostrm, policy, s->GetIndentLevel()); } } @@ -9684,27 +8658,6 @@ void ClangASTContext::DumpTypeDescription(lldb::opaque_compiler_type_t type, } } break; - case clang::Type::Auto: - CompilerType(this, llvm::cast<clang::AutoType>(qual_type) - ->getDeducedType() - .getAsOpaquePtr()) - .DumpTypeDescription(s); - return; - - case clang::Type::Elaborated: - CompilerType(this, llvm::cast<clang::ElaboratedType>(qual_type) - ->getNamedType() - .getAsOpaquePtr()) - .DumpTypeDescription(s); - return; - - case clang::Type::Paren: - CompilerType( - this, - llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr()) - .DumpTypeDescription(s); - return; - case clang::Type::Record: { GetCompleteType(type); @@ -9715,10 +8668,10 @@ void ClangASTContext::DumpTypeDescription(lldb::opaque_compiler_type_t type, llvm::dyn_cast<clang::CXXRecordDecl>(record_decl); if (cxx_record_decl) - cxx_record_decl->print(llvm_ostrm, getASTContext()->getPrintingPolicy(), + cxx_record_decl->print(llvm_ostrm, getASTContext().getPrintingPolicy(), s->GetIndentLevel()); else - record_decl->print(llvm_ostrm, getASTContext()->getPrintingPolicy(), + record_decl->print(llvm_ostrm, getASTContext().getPrintingPolicy(), s->GetIndentLevel()); } break; @@ -9830,9 +8783,8 @@ clang::ClassTemplateDecl *ClangASTContext::ParseClassTemplateDecl( return nullptr; } -void ClangASTContext::CompleteTagDecl(void *baton, clang::TagDecl *decl) { - ClangASTContext *ast = (ClangASTContext *)baton; - SymbolFile *sym_file = ast->GetSymbolFile(); +void ClangASTContext::CompleteTagDecl(clang::TagDecl *decl) { + SymbolFile *sym_file = GetSymbolFile(); if (sym_file) { CompilerType clang_type = GetTypeForDecl(decl); if (clang_type) @@ -9841,9 +8793,8 @@ void ClangASTContext::CompleteTagDecl(void *baton, clang::TagDecl *decl) { } void ClangASTContext::CompleteObjCInterfaceDecl( - void *baton, clang::ObjCInterfaceDecl *decl) { - ClangASTContext *ast = (ClangASTContext *)baton; - SymbolFile *sym_file = ast->GetSymbolFile(); + clang::ObjCInterfaceDecl *decl) { + SymbolFile *sym_file = GetSymbolFile(); if (sym_file) { CompilerType clang_type = GetTypeForDecl(decl); if (clang_type) @@ -9864,19 +8815,18 @@ PDBASTParser *ClangASTContext::GetPDBParser() { } bool ClangASTContext::LayoutRecordType( - void *baton, const clang::RecordDecl *record_decl, uint64_t &bit_size, + const clang::RecordDecl *record_decl, uint64_t &bit_size, uint64_t &alignment, llvm::DenseMap<const clang::FieldDecl *, uint64_t> &field_offsets, llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &base_offsets, llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &vbase_offsets) { - ClangASTContext *ast = (ClangASTContext *)baton; lldb_private::ClangASTImporter *importer = nullptr; - if (ast->m_dwarf_ast_parser_up) - importer = &ast->m_dwarf_ast_parser_up->GetClangASTImporter(); - if (!importer && ast->m_pdb_ast_parser_up) - importer = &ast->m_pdb_ast_parser_up->GetClangASTImporter(); + if (m_dwarf_ast_parser_up) + importer = &m_dwarf_ast_parser_up->GetClangASTImporter(); + if (!importer && m_pdb_ast_parser_up) + importer = &m_pdb_ast_parser_up->GetClangASTImporter(); if (!importer) return false; @@ -9924,19 +8874,17 @@ ConstString ClangASTContext::DeclGetMangledName(void *opaque_decl) { CompilerDeclContext ClangASTContext::DeclGetDeclContext(void *opaque_decl) { if (opaque_decl) - return CompilerDeclContext(this, - ((clang::Decl *)opaque_decl)->getDeclContext()); - else - return CompilerDeclContext(); + return CreateDeclContext(((clang::Decl *)opaque_decl)->getDeclContext()); + return CompilerDeclContext(); } CompilerType ClangASTContext::DeclGetFunctionReturnType(void *opaque_decl) { if (clang::FunctionDecl *func_decl = llvm::dyn_cast<clang::FunctionDecl>((clang::Decl *)opaque_decl)) - return CompilerType(this, func_decl->getReturnType().getAsOpaquePtr()); + return GetType(func_decl->getReturnType()); if (clang::ObjCMethodDecl *objc_method = llvm::dyn_cast<clang::ObjCMethodDecl>((clang::Decl *)opaque_decl)) - return CompilerType(this, objc_method->getReturnType().getAsOpaquePtr()); + return GetType(objc_method->getReturnType()); else return CompilerType(); } @@ -9959,15 +8907,13 @@ CompilerType ClangASTContext::DeclGetFunctionArgumentType(void *opaque_decl, if (idx < func_decl->param_size()) { ParmVarDecl *var_decl = func_decl->getParamDecl(idx); if (var_decl) - return CompilerType(this, var_decl->getOriginalType().getAsOpaquePtr()); + return GetType(var_decl->getOriginalType()); } } else if (clang::ObjCMethodDecl *objc_method = llvm::dyn_cast<clang::ObjCMethodDecl>( (clang::Decl *)opaque_decl)) { if (idx < objc_method->param_size()) - return CompilerType( - this, - objc_method->parameters()[idx]->getOriginalType().getAsOpaquePtr()); + return GetType(objc_method->parameters()[idx]->getOriginalType()); } return CompilerType(); } @@ -9993,7 +8939,7 @@ std::vector<CompilerDecl> ClangASTContext::DeclContextFindDeclByName( if (!searched.insert(it->second).second) continue; symbol_file->ParseDeclsForContext( - CompilerDeclContext(this, it->second)); + CreateDeclContext(it->second)); for (clang::Decl *child : it->second->decls()) { if (clang::UsingDirectiveDecl *ud = @@ -10108,7 +9054,7 @@ uint32_t ClangASTContext::CountDeclLevels(clang::DeclContext *frame_decl_ctx, searched.insert(it->second); symbol_file->ParseDeclsForContext( - CompilerDeclContext(this, it->second)); + CreateDeclContext(it->second)); for (clang::Decl *child : it->second->decls()) { if (clang::UsingDirectiveDecl *ud = @@ -10135,7 +9081,7 @@ uint32_t ClangASTContext::CountDeclLevels(clang::DeclContext *frame_decl_ctx, continue; // Check types, if one was provided. if (child_type) { - CompilerType clang_type = ClangASTContext::GetTypeForDecl(nd); + CompilerType clang_type = GetTypeForDecl(nd); if (!AreTypesSame(clang_type, *child_type, /*ignore_qualifiers=*/true)) continue; @@ -10153,13 +9099,6 @@ uint32_t ClangASTContext::CountDeclLevels(clang::DeclContext *frame_decl_ctx, return LLDB_INVALID_DECL_LEVEL; } -bool ClangASTContext::DeclContextIsStructUnionOrClass(void *opaque_decl_ctx) { - if (opaque_decl_ctx) - return ((clang::DeclContext *)opaque_decl_ctx)->isRecord(); - else - return false; -} - ConstString ClangASTContext::DeclContextGetName(void *opaque_decl_ctx) { if (opaque_decl_ctx) { clang::NamedDecl *named_decl = @@ -10207,8 +9146,7 @@ bool ClangASTContext::DeclContextIsClassMethod( return true; } else if (clang::FunctionDecl *function_decl = llvm::dyn_cast<clang::FunctionDecl>(decl_ctx)) { - ClangASTMetadata *metadata = - GetMetadata(&decl_ctx->getParentASTContext(), function_decl); + ClangASTMetadata *metadata = GetMetadata(function_decl); if (metadata && metadata->HasObjectPtr()) { if (is_instance_method_ptr) *is_instance_method_ptr = true; @@ -10240,16 +9178,20 @@ bool ClangASTContext::DeclContextIsContainedInLookup( return false; } +static bool IsClangDeclContext(const CompilerDeclContext &dc) { + return dc.IsValid() && isa<ClangASTContext>(dc.GetTypeSystem()); +} + clang::DeclContext * ClangASTContext::DeclContextGetAsDeclContext(const CompilerDeclContext &dc) { - if (dc.IsClang()) + if (IsClangDeclContext(dc)) return (clang::DeclContext *)dc.GetOpaqueDeclContext(); return nullptr; } ObjCMethodDecl * ClangASTContext::DeclContextGetAsObjCMethodDecl(const CompilerDeclContext &dc) { - if (dc.IsClang()) + if (IsClangDeclContext(dc)) return llvm::dyn_cast<clang::ObjCMethodDecl>( (clang::DeclContext *)dc.GetOpaqueDeclContext()); return nullptr; @@ -10257,7 +9199,7 @@ ClangASTContext::DeclContextGetAsObjCMethodDecl(const CompilerDeclContext &dc) { CXXMethodDecl * ClangASTContext::DeclContextGetAsCXXMethodDecl(const CompilerDeclContext &dc) { - if (dc.IsClang()) + if (IsClangDeclContext(dc)) return llvm::dyn_cast<clang::CXXMethodDecl>( (clang::DeclContext *)dc.GetOpaqueDeclContext()); return nullptr; @@ -10265,7 +9207,7 @@ ClangASTContext::DeclContextGetAsCXXMethodDecl(const CompilerDeclContext &dc) { clang::FunctionDecl * ClangASTContext::DeclContextGetAsFunctionDecl(const CompilerDeclContext &dc) { - if (dc.IsClang()) + if (IsClangDeclContext(dc)) return llvm::dyn_cast<clang::FunctionDecl>( (clang::DeclContext *)dc.GetOpaqueDeclContext()); return nullptr; @@ -10273,7 +9215,7 @@ ClangASTContext::DeclContextGetAsFunctionDecl(const CompilerDeclContext &dc) { clang::NamespaceDecl * ClangASTContext::DeclContextGetAsNamespaceDecl(const CompilerDeclContext &dc) { - if (dc.IsClang()) + if (IsClangDeclContext(dc)) return llvm::dyn_cast<clang::NamespaceDecl>( (clang::DeclContext *)dc.GetOpaqueDeclContext()); return nullptr; @@ -10281,11 +9223,9 @@ ClangASTContext::DeclContextGetAsNamespaceDecl(const CompilerDeclContext &dc) { ClangASTMetadata * ClangASTContext::DeclContextGetMetaData(const CompilerDeclContext &dc, - const void *object) { - clang::ASTContext *ast = DeclContextGetClangASTContext(dc); - if (ast) - return ClangASTContext::GetMetadata(ast, object); - return nullptr; + const Decl *object) { + ClangASTContext *ast = llvm::cast<ClangASTContext>(dc.GetTypeSystem()); + return ast->GetMetadata(object); } clang::ASTContext * @@ -10293,14 +9233,26 @@ ClangASTContext::DeclContextGetClangASTContext(const CompilerDeclContext &dc) { ClangASTContext *ast = llvm::dyn_cast_or_null<ClangASTContext>(dc.GetTypeSystem()); if (ast) - return ast->getASTContext(); + return &ast->getASTContext(); return nullptr; } -ClangASTContextForExpressions::ClangASTContextForExpressions(Target &target, - ArchSpec arch) - : ClangASTContext(arch), m_target_wp(target.shared_from_this()), - m_persistent_variables(new ClangPersistentVariables) {} +ClangASTContextForExpressions::ClangASTContextForExpressions( + Target &target, llvm::Triple triple) + : ClangASTContext(triple), m_target_wp(target.shared_from_this()), + m_persistent_variables(new ClangPersistentVariables) { + m_scratch_ast_source_up.reset(new ClangASTSource( + target.shared_from_this(), target.GetClangASTImporter())); + m_scratch_ast_source_up->InstallASTContext(*this); + llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> proxy_ast_source( + m_scratch_ast_source_up->CreateProxy()); + SetExternalSource(proxy_ast_source); +} + +void ClangASTContextForExpressions::Finalize() { + ClangASTContext::Finalize(); + m_scratch_ast_source_up.reset(); +} UserExpression *ClangASTContextForExpressions::GetUserExpression( llvm::StringRef expr, llvm::StringRef prefix, lldb::LanguageType language, @@ -10344,9 +9296,3 @@ PersistentExpressionState * ClangASTContextForExpressions::GetPersistentExpressionState() { return m_persistent_variables.get(); } - -clang::ExternalASTMerger & -ClangASTContextForExpressions::GetMergerUnchecked() { - lldbassert(m_scratch_ast_source_up != nullptr); - return m_scratch_ast_source_up->GetMergerUnchecked(); -} diff --git a/lldb/source/Symbol/ClangASTImporter.cpp b/lldb/source/Symbol/ClangASTImporter.cpp index 92d51f79a007..8cb404231a8d 100644 --- a/lldb/source/Symbol/ClangASTImporter.cpp +++ b/lldb/source/Symbol/ClangASTImporter.cpp @@ -9,7 +9,7 @@ #include "lldb/Symbol/ClangASTImporter.h" #include "lldb/Core/Module.h" #include "lldb/Symbol/ClangASTContext.h" -#include "lldb/Symbol/ClangExternalASTSourceCommon.h" +#include "lldb/Symbol/ClangASTMetadata.h" #include "lldb/Symbol/ClangUtil.h" #include "lldb/Utility/LLDBAssert.h" #include "lldb/Utility/Log.h" @@ -25,90 +25,46 @@ using namespace lldb_private; using namespace clang; -ClangASTMetrics::Counters ClangASTMetrics::global_counters = {0, 0, 0, 0, 0, 0}; -ClangASTMetrics::Counters ClangASTMetrics::local_counters = {0, 0, 0, 0, 0, 0}; - -void ClangASTMetrics::DumpCounters(Log *log, - ClangASTMetrics::Counters &counters) { - LLDB_LOGF(log, " Number of visible Decl queries by name : %" PRIu64, - counters.m_visible_query_count); - LLDB_LOGF(log, " Number of lexical Decl queries : %" PRIu64, - counters.m_lexical_query_count); - LLDB_LOGF(log, " Number of imports initiated by LLDB : %" PRIu64, - counters.m_lldb_import_count); - LLDB_LOGF(log, " Number of imports conducted by Clang : %" PRIu64, - counters.m_clang_import_count); - LLDB_LOGF(log, " Number of Decls completed : %" PRIu64, - counters.m_decls_completed_count); - LLDB_LOGF(log, " Number of records laid out : %" PRIu64, - counters.m_record_layout_count); -} - -void ClangASTMetrics::DumpCounters(Log *log) { - if (!log) - return; +CompilerType ClangASTImporter::CopyType(ClangASTContext &dst_ast, + const CompilerType &src_type) { + clang::ASTContext &dst_clang_ast = dst_ast.getASTContext(); - LLDB_LOGF(log, "== ClangASTMetrics output =="); - LLDB_LOGF(log, "-- Global metrics --"); - DumpCounters(log, global_counters); - LLDB_LOGF(log, "-- Local metrics --"); - DumpCounters(log, local_counters); -} + ClangASTContext *src_ast = + llvm::dyn_cast_or_null<ClangASTContext>(src_type.GetTypeSystem()); + if (!src_ast) + return CompilerType(); -clang::QualType ClangASTImporter::CopyType(clang::ASTContext *dst_ast, - clang::ASTContext *src_ast, - clang::QualType type) { - ImporterDelegateSP delegate_sp(GetDelegate(dst_ast, src_ast)); + clang::ASTContext &src_clang_ast = src_ast->getASTContext(); - ASTImporterDelegate::CxxModuleScope std_scope(*delegate_sp, dst_ast); + clang::QualType src_qual_type = ClangUtil::GetQualType(src_type); + ImporterDelegateSP delegate_sp(GetDelegate(&dst_clang_ast, &src_clang_ast)); if (!delegate_sp) - return QualType(); + return CompilerType(); - llvm::Expected<QualType> ret_or_error = delegate_sp->Import(type); + ASTImporterDelegate::CxxModuleScope std_scope(*delegate_sp, &dst_clang_ast); + + llvm::Expected<QualType> ret_or_error = delegate_sp->Import(src_qual_type); if (!ret_or_error) { Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS); LLDB_LOG_ERROR(log, ret_or_error.takeError(), "Couldn't import type: {0}"); - return QualType(); + return CompilerType(); } - return *ret_or_error; -} -lldb::opaque_compiler_type_t -ClangASTImporter::CopyType(clang::ASTContext *dst_ast, - clang::ASTContext *src_ast, - lldb::opaque_compiler_type_t type) { - return CopyType(dst_ast, src_ast, QualType::getFromOpaquePtr(type)) - .getAsOpaquePtr(); -} + lldb::opaque_compiler_type_t dst_clang_type = ret_or_error->getAsOpaquePtr(); -CompilerType ClangASTImporter::CopyType(ClangASTContext &dst_ast, - const CompilerType &src_type) { - clang::ASTContext *dst_clang_ast = dst_ast.getASTContext(); - if (dst_clang_ast) { - ClangASTContext *src_ast = - llvm::dyn_cast_or_null<ClangASTContext>(src_type.GetTypeSystem()); - if (src_ast) { - clang::ASTContext *src_clang_ast = src_ast->getASTContext(); - if (src_clang_ast) { - lldb::opaque_compiler_type_t dst_clang_type = CopyType( - dst_clang_ast, src_clang_ast, src_type.GetOpaqueQualType()); - - if (dst_clang_type) - return CompilerType(&dst_ast, dst_clang_type); - } - } - } + if (dst_clang_type) + return CompilerType(&dst_ast, dst_clang_type); return CompilerType(); } clang::Decl *ClangASTImporter::CopyDecl(clang::ASTContext *dst_ast, - clang::ASTContext *src_ast, clang::Decl *decl) { ImporterDelegateSP delegate_sp; + clang::ASTContext *src_ast = &decl->getASTContext(); delegate_sp = GetDelegate(dst_ast, src_ast); ASTImporterDelegate::CxxModuleScope std_scope(*delegate_sp, dst_ast); @@ -151,7 +107,7 @@ private: clang::DeclContext *lexical_decl_context; }; - std::map<clang::Decl *, Backup> m_backups; + llvm::DenseMap<clang::Decl *, Backup> m_backups; void OverrideOne(clang::Decl *decl) { if (m_backups.find(decl) != m_backups.end()) { @@ -258,10 +214,8 @@ namespace { /// imported while completing the original Decls). class CompleteTagDeclsScope : public ClangASTImporter::NewDeclListener { ClangASTImporter::ImporterDelegateSP m_delegate; - // FIXME: Investigate how many decls we usually have in these sets and - // see if we can use SmallPtrSet instead here. - std::set<NamedDecl *> m_decls_to_complete; - std::set<NamedDecl *> m_decls_already_completed; + llvm::SmallVector<NamedDecl *, 32> m_decls_to_complete; + llvm::SmallPtrSet<NamedDecl *, 32> m_decls_already_completed; clang::ASTContext *m_dst_ctx; clang::ASTContext *m_src_ctx; ClangASTImporter &importer; @@ -285,10 +239,8 @@ public: // Complete all decls we collected until now. while (!m_decls_to_complete.empty()) { - NamedDecl *decl = *m_decls_to_complete.begin(); - + NamedDecl *decl = m_decls_to_complete.pop_back_val(); m_decls_already_completed.insert(decl); - m_decls_to_complete.erase(decl); // We should only complete decls coming from the source context. assert(to_context_md->m_origins[decl].ctx == m_src_ctx); @@ -333,46 +285,39 @@ public: // Check if we already completed this type. if (m_decls_already_completed.count(to_named_decl) != 0) return; - m_decls_to_complete.insert(to_named_decl); + m_decls_to_complete.push_back(to_named_decl); } }; } // namespace -lldb::opaque_compiler_type_t -ClangASTImporter::DeportType(clang::ASTContext *dst_ctx, - clang::ASTContext *src_ctx, - lldb::opaque_compiler_type_t type) { +CompilerType ClangASTImporter::DeportType(ClangASTContext &dst, + const CompilerType &src_type) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); - LLDB_LOGF(log, - " [ClangASTImporter] DeportType called on (%sType*)0x%llx " - "from (ASTContext*)%p to (ASTContext*)%p", - QualType::getFromOpaquePtr(type)->getTypeClassName(), - (unsigned long long)type, static_cast<void *>(src_ctx), - static_cast<void *>(dst_ctx)); + ClangASTContext *src_ctxt = + llvm::cast<ClangASTContext>(src_type.GetTypeSystem()); + + LLDB_LOG(log, + " [ClangASTImporter] DeportType called on ({0}Type*){1:x} " + "from (ASTContext*){2:x} to (ASTContext*){3:x}", + src_type.GetTypeName(), src_type.GetOpaqueQualType(), + &src_ctxt->getASTContext(), &dst.getASTContext()); DeclContextOverride decl_context_override; - if (auto *t = QualType::getFromOpaquePtr(type)->getAs<TagType>()) + if (auto *t = ClangUtil::GetQualType(src_type)->getAs<TagType>()) decl_context_override.OverrideAllDeclsFromContainingFunction(t->getDecl()); - lldb::opaque_compiler_type_t result; - { - CompleteTagDeclsScope complete_scope(*this, dst_ctx, src_ctx); - result = CopyType(dst_ctx, src_ctx, type); - } - - if (!result) - return nullptr; - - return result; + CompleteTagDeclsScope complete_scope(*this, &dst.getASTContext(), + &src_ctxt->getASTContext()); + return CopyType(dst, src_type); } clang::Decl *ClangASTImporter::DeportDecl(clang::ASTContext *dst_ctx, - clang::ASTContext *src_ctx, clang::Decl *decl) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + clang::ASTContext *src_ctx = &decl->getASTContext(); LLDB_LOGF(log, " [ClangASTImporter] DeportDecl called on (%sDecl*)%p from " "(ASTContext*)%p to (ASTContext*)%p", @@ -386,7 +331,7 @@ clang::Decl *ClangASTImporter::DeportDecl(clang::ASTContext *dst_ctx, clang::Decl *result; { CompleteTagDeclsScope complete_scope(*this, dst_ctx, src_ctx); - result = CopyDecl(dst_ctx, src_ctx, decl); + result = CopyDecl(dst_ctx, decl); } if (!result) @@ -417,7 +362,7 @@ bool ClangASTImporter::CanImport(const CompilerType &type) { const clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl(); if (cxx_record_decl) { - if (ResolveDeclOrigin(cxx_record_decl, nullptr, nullptr)) + if (GetDeclOrigin(cxx_record_decl).Valid()) return true; } } break; @@ -426,7 +371,7 @@ bool ClangASTImporter::CanImport(const CompilerType &type) { clang::EnumDecl *enum_decl = llvm::cast<clang::EnumType>(qual_type)->getDecl(); if (enum_decl) { - if (ResolveDeclOrigin(enum_decl, nullptr, nullptr)) + if (GetDeclOrigin(enum_decl).Valid()) return true; } } break; @@ -441,7 +386,7 @@ bool ClangASTImporter::CanImport(const CompilerType &type) { // We currently can't complete objective C types through the newly added // ASTContext because it only supports TagDecl objects right now... if (class_interface_decl) { - if (ResolveDeclOrigin(class_interface_decl, nullptr, nullptr)) + if (GetDeclOrigin(class_interface_decl).Valid()) return true; } } @@ -493,7 +438,7 @@ bool ClangASTImporter::Import(const CompilerType &type) { const clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl(); if (cxx_record_decl) { - if (ResolveDeclOrigin(cxx_record_decl, nullptr, nullptr)) + if (GetDeclOrigin(cxx_record_decl).Valid()) return CompleteAndFetchChildren(qual_type); } } break; @@ -502,7 +447,7 @@ bool ClangASTImporter::Import(const CompilerType &type) { clang::EnumDecl *enum_decl = llvm::cast<clang::EnumType>(qual_type)->getDecl(); if (enum_decl) { - if (ResolveDeclOrigin(enum_decl, nullptr, nullptr)) + if (GetDeclOrigin(enum_decl).Valid()) return CompleteAndFetchChildren(qual_type); } } break; @@ -517,7 +462,7 @@ bool ClangASTImporter::Import(const CompilerType &type) { // We currently can't complete objective C types through the newly added // ASTContext because it only supports TagDecl objects right now... if (class_interface_decl) { - if (ResolveDeclOrigin(class_interface_decl, nullptr, nullptr)) + if (GetDeclOrigin(class_interface_decl).Valid()) return CompleteAndFetchChildren(qual_type); } } @@ -596,7 +541,7 @@ bool ClangASTImporter::LayoutRecordType( return success; } -void ClangASTImporter::InsertRecordDecl(clang::RecordDecl *decl, +void ClangASTImporter::SetRecordLayout(clang::RecordDecl *decl, const LayoutInfo &layout) { m_record_decl_to_layout_map.insert(std::make_pair(decl, layout)); } @@ -628,8 +573,6 @@ void ClangASTImporter::CompleteDecl(clang::Decl *decl) { } bool ClangASTImporter::CompleteTagDecl(clang::TagDecl *decl) { - ClangASTMetrics::RegisterDeclCompletion(); - DeclOrigin decl_origin = GetDeclOrigin(decl); if (!decl_origin.Valid()) @@ -651,8 +594,6 @@ bool ClangASTImporter::CompleteTagDecl(clang::TagDecl *decl) { bool ClangASTImporter::CompleteTagDeclWithOrigin(clang::TagDecl *decl, clang::TagDecl *origin_decl) { - ClangASTMetrics::RegisterDeclCompletion(); - clang::ASTContext *origin_ast_ctx = &origin_decl->getASTContext(); if (!ClangASTContext::GetCompleteDecl(origin_ast_ctx, origin_decl)) @@ -675,8 +616,6 @@ bool ClangASTImporter::CompleteTagDeclWithOrigin(clang::TagDecl *decl, bool ClangASTImporter::CompleteObjCInterfaceDecl( clang::ObjCInterfaceDecl *interface_decl) { - ClangASTMetrics::RegisterDeclCompletion(); - DeclOrigin decl_origin = GetDeclOrigin(interface_decl); if (!decl_origin.Valid()) @@ -729,9 +668,8 @@ bool ClangASTImporter::CompleteAndFetchChildren(clang::QualType type) { } } - if (RecordDecl *record_decl = dyn_cast<RecordDecl>(origin_tag_decl)) { + if (RecordDecl *record_decl = dyn_cast<RecordDecl>(origin_tag_decl)) record_decl->setHasLoadedFieldsFromExternalStorage(true); - } return true; } @@ -761,9 +699,8 @@ bool ClangASTImporter::CompleteAndFetchChildren(clang::QualType type) { } return true; - } else { - return false; } + return false; } return true; @@ -785,15 +722,12 @@ bool ClangASTImporter::RequireCompleteType(clang::QualType type) { if (ObjCInterfaceDecl *objc_interface_decl = objc_object_type->getInterface()) return CompleteObjCInterfaceDecl(objc_interface_decl); - else - return false; + return false; } - if (const ArrayType *array_type = type->getAsArrayTypeUnsafe()) { + if (const ArrayType *array_type = type->getAsArrayTypeUnsafe()) return RequireCompleteType(array_type->getElementType()); - } - if (const AtomicType *atomic_type = type->getAs<AtomicType>()) { + if (const AtomicType *atomic_type = type->getAs<AtomicType>()) return RequireCompleteType(atomic_type->getPointeeType()); - } return true; } @@ -801,10 +735,12 @@ bool ClangASTImporter::RequireCompleteType(clang::QualType type) { ClangASTMetadata *ClangASTImporter::GetDeclMetadata(const clang::Decl *decl) { DeclOrigin decl_origin = GetDeclOrigin(decl); - if (decl_origin.Valid()) - return ClangASTContext::GetMetadata(decl_origin.ctx, decl_origin.decl); - else - return ClangASTContext::GetMetadata(&decl->getASTContext(), decl); + if (decl_origin.Valid()) { + ClangASTContext *ast = ClangASTContext::GetASTContext(decl_origin.ctx); + return ast->GetMetadata(decl_origin.decl); + } + ClangASTContext *ast = ClangASTContext::GetASTContext(&decl->getASTContext()); + return ast->GetMetadata(decl); } ClangASTImporter::DeclOrigin @@ -817,8 +753,7 @@ ClangASTImporter::GetDeclOrigin(const clang::Decl *decl) { if (iter != origins.end()) return iter->second; - else - return DeclOrigin(); + return DeclOrigin(); } void ClangASTImporter::SetDeclOrigin(const clang::Decl *decl, @@ -832,9 +767,9 @@ void ClangASTImporter::SetDeclOrigin(const clang::Decl *decl, if (iter != origins.end()) { iter->second.decl = original_decl; iter->second.ctx = &original_decl->getASTContext(); - } else { - origins[decl] = DeclOrigin(&original_decl->getASTContext(), original_decl); + return; } + origins[decl] = DeclOrigin(&original_decl->getASTContext(), original_decl); } void ClangASTImporter::RegisterNamespaceMap(const clang::NamespaceDecl *decl, @@ -854,8 +789,7 @@ ClangASTImporter::GetNamespaceMap(const clang::NamespaceDecl *decl) { if (iter != namespace_maps.end()) return iter->second; - else - return NamespaceMapSP(); + return NamespaceMapSP(); } void ClangASTImporter::BuildNamespaceMap(const clang::NamespaceDecl *decl) { @@ -936,6 +870,39 @@ ClangASTImporter::ASTImporterDelegate::ImportImpl(Decl *From) { } } + // Check which ASTContext this declaration originally came from. + DeclOrigin origin = m_master.GetDeclOrigin(From); + // If it originally came from the target ASTContext then we can just + // pretend that the original is the one we imported. This can happen for + // example when inspecting a persistent declaration from the scratch + // ASTContext (which will provide the declaration when parsing the + // expression and then we later try to copy the declaration back to the + // scratch ASTContext to store the result). + // Without this check we would ask the ASTImporter to import a declaration + // into the same ASTContext where it came from (which doesn't make a lot of + // sense). + if (origin.Valid() && origin.ctx == &getToContext()) { + RegisterImportedDecl(From, origin.decl); + return origin.decl; + } + + // This declaration came originally from another ASTContext. Instead of + // copying our potentially incomplete 'From' Decl we instead go to the + // original ASTContext and copy the original to the target. This is not + // only faster than first completing our current decl and then copying it + // to the target, but it also prevents that indirectly copying the same + // declaration to the same target requires the ASTImporter to merge all + // the different decls that appear to come from different ASTContexts (even + // though all these different source ASTContexts just got a copy from + // one source AST). + if (origin.Valid()) { + auto R = m_master.CopyDecl(&getToContext(), origin.decl); + if (R) { + RegisterImportedDecl(From, R); + return R; + } + } + return ASTImporter::ImportImpl(From); } @@ -1037,8 +1004,6 @@ void ClangASTImporter::ASTImporterDelegate::ImportDefinitionTo( void ClangASTImporter::ASTImporterDelegate::Imported(clang::Decl *from, clang::Decl *to) { - ClangASTMetrics::RegisterClangImport(); - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); // Some decls shouldn't be tracked here because they were not created by @@ -1196,16 +1161,5 @@ void ClangASTImporter::ASTImporterDelegate::Imported(clang::Decl *from, clang::Decl * ClangASTImporter::ASTImporterDelegate::GetOriginalDecl(clang::Decl *To) { - ASTContextMetadataSP to_context_md = - m_master.GetContextMetadata(&To->getASTContext()); - - if (!to_context_md) - return nullptr; - - OriginMap::iterator iter = to_context_md->m_origins.find(To); - - if (iter == to_context_md->m_origins.end()) - return nullptr; - - return const_cast<clang::Decl *>(iter->second.decl); + return m_master.GetDeclOrigin(To).decl; } diff --git a/lldb/source/Symbol/ClangASTMetadata.cpp b/lldb/source/Symbol/ClangASTMetadata.cpp new file mode 100644 index 000000000000..31b012f553fa --- /dev/null +++ b/lldb/source/Symbol/ClangASTMetadata.cpp @@ -0,0 +1,35 @@ +//===-- ClangASTMetadata.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 "lldb/Symbol/ClangASTMetadata.h" +#include "lldb/Utility/Stream.h" + +using namespace lldb_private; + +void ClangASTMetadata::Dump(Stream *s) { + lldb::user_id_t uid = GetUserID(); + + if (uid != LLDB_INVALID_UID) { + s->Printf("uid=0x%" PRIx64, uid); + } + + uint64_t isa_ptr = GetISAPtr(); + if (isa_ptr != 0) { + s->Printf("isa_ptr=0x%" PRIx64, isa_ptr); + } + + const char *obj_ptr_name = GetObjectPtrName(); + if (obj_ptr_name) { + s->Printf("obj_ptr_name=\"%s\" ", obj_ptr_name); + } + + if (m_is_dynamic_cxx) { + s->Printf("is_dynamic_cxx=%i ", m_is_dynamic_cxx); + } + s->EOL(); +} diff --git a/lldb/source/Symbol/ClangExternalASTSourceCallbacks.cpp b/lldb/source/Symbol/ClangExternalASTSourceCallbacks.cpp index c35fc585bfa5..008c2acd9b48 100644 --- a/lldb/source/Symbol/ClangExternalASTSourceCallbacks.cpp +++ b/lldb/source/Symbol/ClangExternalASTSourceCallbacks.cpp @@ -7,69 +7,19 @@ //===----------------------------------------------------------------------===// #include "lldb/Symbol/ClangExternalASTSourceCallbacks.h" +#include "lldb/Symbol/ClangASTContext.h" - -// Clang headers like to use NDEBUG inside of them to enable/disable debug -// related features using "#ifndef NDEBUG" preprocessor blocks to do one thing -// or another. This is bad because it means that if clang was built in release -// mode, it assumes that you are building in release mode which is not always -// the case. You can end up with functions that are defined as empty in header -// files when NDEBUG is not defined, and this can cause link errors with the -// clang .a files that you have since you might be missing functions in the .a -// file. So we have to define NDEBUG when including clang headers to avoid any -// mismatches. This is covered by rdar://problem/8691220 - -#if !defined(NDEBUG) && !defined(LLVM_NDEBUG_OFF) -#define LLDB_DEFINED_NDEBUG_FOR_CLANG -#define NDEBUG -// Need to include assert.h so it is as clang would expect it to be (disabled) -#include <assert.h> -#endif - -#include "clang/AST/DeclBase.h" -#include "clang/AST/DeclarationName.h" - -#ifdef LLDB_DEFINED_NDEBUG_FOR_CLANG -#undef NDEBUG -#undef LLDB_DEFINED_NDEBUG_FOR_CLANG -// Need to re-include assert.h so it is as _we_ would expect it to be (enabled) -#include <assert.h> -#endif - -#include "lldb/Utility/Log.h" #include "clang/AST/Decl.h" -using namespace clang; using namespace lldb_private; -bool ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName( - const clang::DeclContext *decl_ctx, - clang::DeclarationName clang_decl_name) { - if (m_callback_find_by_name) { - llvm::SmallVector<clang::NamedDecl *, 3> results; - - m_callback_find_by_name(m_callback_baton, decl_ctx, clang_decl_name, - &results); - - SetExternalVisibleDeclsForName(decl_ctx, clang_decl_name, results); - - return (results.size() != 0); - } - - std::string decl_name(clang_decl_name.getAsString()); - SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name); - return false; -} - -void ClangExternalASTSourceCallbacks::CompleteType(TagDecl *tag_decl) { - if (m_callback_tag_decl) - m_callback_tag_decl(m_callback_baton, tag_decl); +void ClangExternalASTSourceCallbacks::CompleteType(clang::TagDecl *tag_decl) { + m_ast.CompleteTagDecl(tag_decl); } void ClangExternalASTSourceCallbacks::CompleteType( - ObjCInterfaceDecl *objc_decl) { - if (m_callback_objc_decl) - m_callback_objc_decl(m_callback_baton, objc_decl); + clang::ObjCInterfaceDecl *objc_decl) { + m_ast.CompleteObjCInterfaceDecl(objc_decl); } bool ClangExternalASTSourceCallbacks::layoutRecordType( @@ -78,19 +28,15 @@ bool ClangExternalASTSourceCallbacks::layoutRecordType( llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &BaseOffsets, llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &VirtualBaseOffsets) { - if (m_callback_layout_record_type) - return m_callback_layout_record_type(m_callback_baton, Record, Size, - Alignment, FieldOffsets, BaseOffsets, - VirtualBaseOffsets); - - return false; + return m_ast.LayoutRecordType(Record, Size, Alignment, FieldOffsets, + BaseOffsets, VirtualBaseOffsets); } void ClangExternalASTSourceCallbacks::FindExternalLexicalDecls( const clang::DeclContext *decl_ctx, llvm::function_ref<bool(clang::Decl::Kind)> IsKindWeWant, llvm::SmallVectorImpl<clang::Decl *> &decls) { - if (m_callback_tag_decl && decl_ctx) { + if (decl_ctx) { clang::TagDecl *tag_decl = llvm::dyn_cast<clang::TagDecl>( const_cast<clang::DeclContext *>(decl_ctx)); if (tag_decl) diff --git a/lldb/source/Symbol/ClangExternalASTSourceCommon.cpp b/lldb/source/Symbol/ClangExternalASTSourceCommon.cpp deleted file mode 100644 index 3dcf9051d0a4..000000000000 --- a/lldb/source/Symbol/ClangExternalASTSourceCommon.cpp +++ /dev/null @@ -1,99 +0,0 @@ -//===-- ClangExternalASTSourceCommon.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 "lldb/Symbol/ClangExternalASTSourceCommon.h" -#include "lldb/Utility/Stream.h" - -#include <mutex> - -using namespace lldb_private; - -uint64_t g_TotalSizeOfMetadata = 0; - -typedef llvm::DenseMap<clang::ExternalASTSource *, - ClangExternalASTSourceCommon *> - ASTSourceMap; - -static ASTSourceMap &GetSourceMap(std::unique_lock<std::mutex> &guard) { - // Intentionally leaked to avoid problems with global destructors. - static ASTSourceMap *s_source_map = new ASTSourceMap; - static std::mutex s_mutex; - std::unique_lock<std::mutex> locked_guard(s_mutex); - guard.swap(locked_guard); - return *s_source_map; -} - -ClangExternalASTSourceCommon * -ClangExternalASTSourceCommon::Lookup(clang::ExternalASTSource *source) { - std::unique_lock<std::mutex> guard; - ASTSourceMap &source_map = GetSourceMap(guard); - - ASTSourceMap::iterator iter = source_map.find(source); - - if (iter != source_map.end()) { - return iter->second; - } else { - return nullptr; - } -} - -ClangExternalASTSourceCommon::ClangExternalASTSourceCommon() - : clang::ExternalASTSource() { - g_TotalSizeOfMetadata += m_metadata.size(); - std::unique_lock<std::mutex> guard; - GetSourceMap(guard)[this] = this; -} - -ClangExternalASTSourceCommon::~ClangExternalASTSourceCommon() { - std::unique_lock<std::mutex> guard; - GetSourceMap(guard).erase(this); - g_TotalSizeOfMetadata -= m_metadata.size(); -} - -ClangASTMetadata * -ClangExternalASTSourceCommon::GetMetadata(const void *object) { - if (HasMetadata(object)) - return &m_metadata[object]; - else - return nullptr; -} - -void ClangExternalASTSourceCommon::SetMetadata(const void *object, - ClangASTMetadata &metadata) { - uint64_t orig_size = m_metadata.size(); - m_metadata[object] = metadata; - uint64_t new_size = m_metadata.size(); - g_TotalSizeOfMetadata += (new_size - orig_size); -} - -bool ClangExternalASTSourceCommon::HasMetadata(const void *object) { - return m_metadata.find(object) != m_metadata.end(); -} - -void ClangASTMetadata::Dump(Stream *s) { - lldb::user_id_t uid = GetUserID(); - - if (uid != LLDB_INVALID_UID) { - s->Printf("uid=0x%" PRIx64, uid); - } - - uint64_t isa_ptr = GetISAPtr(); - if (isa_ptr != 0) { - s->Printf("isa_ptr=0x%" PRIx64, isa_ptr); - } - - const char *obj_ptr_name = GetObjectPtrName(); - if (obj_ptr_name) { - s->Printf("obj_ptr_name=\"%s\" ", obj_ptr_name); - } - - if (m_is_dynamic_cxx) { - s->Printf("is_dynamic_cxx=%i ", m_is_dynamic_cxx); - } - s->EOL(); -} diff --git a/lldb/source/Symbol/ClangUtil.cpp b/lldb/source/Symbol/ClangUtil.cpp index 86be895fadcb..52ea4f5111d6 100644 --- a/lldb/source/Symbol/ClangUtil.cpp +++ b/lldb/source/Symbol/ClangUtil.cpp @@ -15,6 +15,10 @@ using namespace clang; using namespace lldb_private; bool ClangUtil::IsClangType(const CompilerType &ct) { + // Invalid types are never Clang types. + if (!ct) + return false; + if (llvm::dyn_cast_or_null<ClangASTContext>(ct.GetTypeSystem()) == nullptr) return false; @@ -55,3 +59,24 @@ clang::TagDecl *ClangUtil::GetAsTagDecl(const CompilerType &type) { return qual_type->getAsTagDecl(); } + +std::string ClangUtil::DumpDecl(const clang::Decl *d) { + if (!d) + return "nullptr"; + + std::string result; + llvm::raw_string_ostream stream(result); + bool deserialize = false; + d->dump(stream, deserialize); + + stream.flush(); + return result; +} + +std::string ClangUtil::ToString(const clang::Type *t) { + return clang::QualType(t, 0).getAsString(); +} + +std::string ClangUtil::ToString(const CompilerType &c) { + return ClangUtil::GetQualType(c).getAsString(); +} diff --git a/lldb/source/Symbol/CompileUnit.cpp b/lldb/source/Symbol/CompileUnit.cpp index 41086d2df3df..b05036e27fcf 100644 --- a/lldb/source/Symbol/CompileUnit.cpp +++ b/lldb/source/Symbol/CompileUnit.cpp @@ -12,6 +12,7 @@ #include "lldb/Symbol/SymbolFile.h" #include "lldb/Symbol/VariableList.h" #include "lldb/Target/Language.h" +#include "lldb/Utility/Timer.h" using namespace lldb; using namespace lldb_private; @@ -20,30 +21,21 @@ CompileUnit::CompileUnit(const lldb::ModuleSP &module_sp, void *user_data, const char *pathname, const lldb::user_id_t cu_sym_id, lldb::LanguageType language, lldb_private::LazyBool is_optimized) - : ModuleChild(module_sp), FileSpec(pathname), UserID(cu_sym_id), - m_user_data(user_data), m_language(language), m_flags(0), - m_support_files(), m_line_table_up(), m_variables(), - m_is_optimized(is_optimized) { - if (language != eLanguageTypeUnknown) - m_flags.Set(flagsParsedLanguage); - assert(module_sp); -} + : CompileUnit(module_sp, user_data, FileSpec(pathname), cu_sym_id, language, + is_optimized) {} CompileUnit::CompileUnit(const lldb::ModuleSP &module_sp, void *user_data, const FileSpec &fspec, const lldb::user_id_t cu_sym_id, lldb::LanguageType language, lldb_private::LazyBool is_optimized) - : ModuleChild(module_sp), FileSpec(fspec), UserID(cu_sym_id), - m_user_data(user_data), m_language(language), m_flags(0), - m_support_files(), m_line_table_up(), m_variables(), + : ModuleChild(module_sp), UserID(cu_sym_id), m_user_data(user_data), + m_language(language), m_flags(0), m_file_spec(fspec), m_is_optimized(is_optimized) { if (language != eLanguageTypeUnknown) m_flags.Set(flagsParsedLanguage); assert(module_sp); } -CompileUnit::~CompileUnit() {} - void CompileUnit::CalculateSymbolContext(SymbolContext *sc) { sc->comp_unit = this; GetModule()->CalculateSymbolContext(sc); @@ -62,7 +54,7 @@ void CompileUnit::GetDescription(Stream *s, lldb::DescriptionLevel level) const { const char *language = Language::GetNameForLanguageType(m_language); *s << "id = " << (const UserID &)*this << ", file = \"" - << (const FileSpec &)*this << "\", language = \"" << language << '"'; + << this->GetPrimaryFile() << "\", language = \"" << language << '"'; } void CompileUnit::ForeachFunction( @@ -81,6 +73,31 @@ void CompileUnit::ForeachFunction( return; } +lldb::FunctionSP CompileUnit::FindFunction( + llvm::function_ref<bool(const FunctionSP &)> matching_lambda) { + static Timer::Category func_cat(LLVM_PRETTY_FUNCTION); + Timer scoped_timer(func_cat, "CompileUnit::FindFunction"); + + lldb::ModuleSP module = CalculateSymbolContextModule(); + + if (!module) + return {}; + + SymbolFile *symbol_file = module->GetSymbolFile(); + + if (!symbol_file) + return {}; + + // m_functions_by_uid is filled in lazily but we need all the entries. + symbol_file->ParseFunctions(*this); + + for (auto &p : m_functions_by_uid) { + if (matching_lambda(p.second)) + return p.second; + } + return {}; +} + // Dump the current contents of this object. No functions that cause on demand // parsing of functions, globals, statics are called, so this is a good // function to call to get an idea of the current contents of the CompileUnit @@ -91,8 +108,7 @@ void CompileUnit::Dump(Stream *s, bool show_context) const { s->Printf("%p: ", static_cast<const void *>(this)); s->Indent(); *s << "CompileUnit" << static_cast<const UserID &>(*this) << ", language = \"" - << language << "\", file = '" << static_cast<const FileSpec &>(*this) - << "'\n"; + << language << "\", file = '" << GetPrimaryFile() << "'\n"; // m_types.Dump(s); @@ -191,53 +207,50 @@ VariableListSP CompileUnit::GetVariableList(bool can_create) { return m_variables; } +std::vector<uint32_t> FindFileIndexes(const FileSpecList &files, const FileSpec &file) { + std::vector<uint32_t> result; + uint32_t idx = -1; + while ((idx = files.FindFileIndex(idx + 1, file, /*full=*/true)) != + UINT32_MAX) + result.push_back(idx); + return result; +} + uint32_t CompileUnit::FindLineEntry(uint32_t start_idx, uint32_t line, const FileSpec *file_spec_ptr, bool exact, LineEntry *line_entry_ptr) { - uint32_t file_idx = 0; + if (!file_spec_ptr) + file_spec_ptr = &GetPrimaryFile(); + std::vector<uint32_t> file_indexes = FindFileIndexes(GetSupportFiles(), *file_spec_ptr); + if (file_indexes.empty()) + return UINT32_MAX; - if (file_spec_ptr) { - file_idx = GetSupportFiles().FindFileIndex(1, *file_spec_ptr, true); - if (file_idx == UINT32_MAX) - return UINT32_MAX; - } else { - // All the line table entries actually point to the version of the Compile - // Unit that is in the support files (the one at 0 was artificially added.) - // So prefer the one further on in the support files if it exists... - const FileSpecList &support_files = GetSupportFiles(); - const bool full = true; - file_idx = support_files.FindFileIndex( - 1, support_files.GetFileSpecAtIndex(0), full); - if (file_idx == UINT32_MAX) - file_idx = 0; - } LineTable *line_table = GetLineTable(); if (line_table) - return line_table->FindLineEntryIndexByFileIndex(start_idx, file_idx, line, - exact, line_entry_ptr); + return line_table->FindLineEntryIndexByFileIndex( + start_idx, file_indexes, line, exact, line_entry_ptr); return UINT32_MAX; } -uint32_t CompileUnit::ResolveSymbolContext(const FileSpec &file_spec, - uint32_t line, bool check_inlines, - bool exact, - SymbolContextItem resolve_scope, - SymbolContextList &sc_list) { +void CompileUnit::ResolveSymbolContext(const FileSpec &file_spec, + uint32_t line, bool check_inlines, + bool exact, + SymbolContextItem resolve_scope, + SymbolContextList &sc_list) { // First find all of the file indexes that match our "file_spec". If // "file_spec" has an empty directory, then only compare the basenames when // finding file indexes std::vector<uint32_t> file_indexes; - const bool full_match = (bool)file_spec.GetDirectory(); bool file_spec_matches_cu_file_spec = - FileSpec::Equal(file_spec, *this, full_match); + FileSpec::Match(file_spec, this->GetPrimaryFile()); // If we are not looking for inlined functions and our file spec doesn't // match then we are done... if (!file_spec_matches_cu_file_spec && !check_inlines) - return 0; + return; uint32_t file_idx = - GetSupportFiles().FindFileIndex(1, file_spec, true); + GetSupportFiles().FindFileIndex(0, file_spec, true); while (file_idx != UINT32_MAX) { file_indexes.push_back(file_idx); file_idx = GetSupportFiles().FindFileIndex(file_idx + 1, file_spec, true); @@ -245,84 +258,67 @@ uint32_t CompileUnit::ResolveSymbolContext(const FileSpec &file_spec, const size_t num_file_indexes = file_indexes.size(); if (num_file_indexes == 0) - return 0; - - const uint32_t prev_size = sc_list.GetSize(); + return; SymbolContext sc(GetModule()); sc.comp_unit = this; - if (line != 0) { - LineTable *line_table = sc.comp_unit->GetLineTable(); - - if (line_table != nullptr) { - uint32_t found_line; - uint32_t line_idx; - - if (num_file_indexes == 1) { - // We only have a single support file that matches, so use the line - // table function that searches for a line entries that match a single - // support file index - LineEntry line_entry; - line_idx = line_table->FindLineEntryIndexByFileIndex( - 0, file_indexes.front(), line, exact, &line_entry); - - // If "exact == true", then "found_line" will be the same as "line". If - // "exact == false", the "found_line" will be the closest line entry - // with a line number greater than "line" and we will use this for our - // subsequent line exact matches below. - found_line = line_entry.line; - - while (line_idx != UINT32_MAX) { - // If they only asked for the line entry, then we're done, we can - // just copy that over. But if they wanted more than just the line - // number, fill it in. - if (resolve_scope == eSymbolContextLineEntry) { - sc.line_entry = line_entry; - } else { - line_entry.range.GetBaseAddress().CalculateSymbolContext( - &sc, resolve_scope); - } - - sc_list.Append(sc); - line_idx = line_table->FindLineEntryIndexByFileIndex( - line_idx + 1, file_indexes.front(), found_line, true, - &line_entry); - } - } else { - // We found multiple support files that match "file_spec" so use the - // line table function that searches for a line entries that match a - // multiple support file indexes. - LineEntry line_entry; - line_idx = line_table->FindLineEntryIndexByFileIndex( - 0, file_indexes, line, exact, &line_entry); - - // If "exact == true", then "found_line" will be the same as "line". If - // "exact == false", the "found_line" will be the closest line entry - // with a line number greater than "line" and we will use this for our - // subsequent line exact matches below. - found_line = line_entry.line; - - while (line_idx != UINT32_MAX) { - if (resolve_scope == eSymbolContextLineEntry) { - sc.line_entry = line_entry; - } else { - line_entry.range.GetBaseAddress().CalculateSymbolContext( - &sc, resolve_scope); - } - - sc_list.Append(sc); - line_idx = line_table->FindLineEntryIndexByFileIndex( - line_idx + 1, file_indexes, found_line, true, &line_entry); - } - } + if (line == 0) { + if (file_spec_matches_cu_file_spec && !check_inlines) { + // only append the context if we aren't looking for inline call sites by + // file and line and if the file spec matches that of the compile unit + sc_list.Append(sc); } - } else if (file_spec_matches_cu_file_spec && !check_inlines) { - // only append the context if we aren't looking for inline call sites by - // file and line and if the file spec matches that of the compile unit + return; + } + + LineTable *line_table = sc.comp_unit->GetLineTable(); + + if (line_table == nullptr) + return; + + uint32_t line_idx; + LineEntry line_entry; + + if (num_file_indexes == 1) { + // We only have a single support file that matches, so use the line + // table function that searches for a line entries that match a single + // support file index + line_idx = line_table->FindLineEntryIndexByFileIndex( + 0, file_indexes.front(), line, exact, &line_entry); + } else { + // We found multiple support files that match "file_spec" so use the + // line table function that searches for a line entries that match a + // multiple support file indexes. + line_idx = line_table->FindLineEntryIndexByFileIndex(0, file_indexes, line, + exact, &line_entry); + } + + // If "exact == true", then "found_line" will be the same as "line". If + // "exact == false", the "found_line" will be the closest line entry + // with a line number greater than "line" and we will use this for our + // subsequent line exact matches below. + uint32_t found_line = line_entry.line; + + while (line_idx != UINT32_MAX) { + // If they only asked for the line entry, then we're done, we can + // just copy that over. But if they wanted more than just the line + // number, fill it in. + if (resolve_scope == eSymbolContextLineEntry) { + sc.line_entry = line_entry; + } else { + line_entry.range.GetBaseAddress().CalculateSymbolContext(&sc, + resolve_scope); + } + sc_list.Append(sc); + if (num_file_indexes == 1) + line_idx = line_table->FindLineEntryIndexByFileIndex( + line_idx + 1, file_indexes.front(), found_line, true, &line_entry); + else + line_idx = line_table->FindLineEntryIndexByFileIndex( + line_idx + 1, file_indexes, found_line, true, &line_entry); } - return sc_list.GetSize() - prev_size; } bool CompileUnit::GetIsOptimized() { @@ -353,9 +349,12 @@ const std::vector<SourceModule> &CompileUnit::GetImportedModules() { return m_imported_modules; } -void CompileUnit::ForEachExternalModule(llvm::function_ref<void(ModuleSP)> f) { +bool CompileUnit::ForEachExternalModule( + llvm::DenseSet<SymbolFile *> &visited_symbol_files, + llvm::function_ref<bool(Module &)> lambda) { if (SymbolFile *symfile = GetModule()->GetSymbolFile()) - symfile->ForEachExternalModule(*this, f); + return symfile->ForEachExternalModule(*this, visited_symbol_files, lambda); + return false; } const FileSpecList &CompileUnit::GetSupportFiles() { diff --git a/lldb/source/Symbol/CompilerDecl.cpp b/lldb/source/Symbol/CompilerDecl.cpp index 2c64113a2bbe..48d9169c1a7a 100644 --- a/lldb/source/Symbol/CompilerDecl.cpp +++ b/lldb/source/Symbol/CompilerDecl.cpp @@ -12,10 +12,6 @@ using namespace lldb_private; -bool CompilerDecl::IsClang() const { - return IsValid() && m_type_system->getKind() == TypeSystem::eKindClang; -} - ConstString CompilerDecl::GetName() const { return m_type_system->DeclGetName(m_opaque_decl); } diff --git a/lldb/source/Symbol/CompilerDeclContext.cpp b/lldb/source/Symbol/CompilerDeclContext.cpp index a6f046c4eb22..581e0872a6a7 100644 --- a/lldb/source/Symbol/CompilerDeclContext.cpp +++ b/lldb/source/Symbol/CompilerDeclContext.cpp @@ -19,33 +19,19 @@ CompilerDeclContext::FindDeclByName(ConstString name, if (IsValid()) return m_type_system->DeclContextFindDeclByName(m_opaque_decl_ctx, name, ignore_using_decls); - else - return std::vector<CompilerDecl>(); -} - -bool CompilerDeclContext::IsClang() const { - return IsValid() && m_type_system->getKind() == TypeSystem::eKindClang; + return std::vector<CompilerDecl>(); } ConstString CompilerDeclContext::GetName() const { if (IsValid()) return m_type_system->DeclContextGetName(m_opaque_decl_ctx); - else - return ConstString(); + return ConstString(); } ConstString CompilerDeclContext::GetScopeQualifiedName() const { if (IsValid()) return m_type_system->DeclContextGetScopeQualifiedName(m_opaque_decl_ctx); - else - return ConstString(); -} - -bool CompilerDeclContext::IsStructUnionOrClass() const { - if (IsValid()) - return m_type_system->DeclContextIsStructUnionOrClass(m_opaque_decl_ctx); - else - return false; + return ConstString(); } bool CompilerDeclContext::IsClassMethod(lldb::LanguageType *language_ptr, @@ -55,8 +41,7 @@ bool CompilerDeclContext::IsClassMethod(lldb::LanguageType *language_ptr, return m_type_system->DeclContextIsClassMethod( m_opaque_decl_ctx, language_ptr, is_instance_method_ptr, language_object_name_ptr); - else - return false; + return false; } bool CompilerDeclContext::IsContainedInLookup(CompilerDeclContext other) const { diff --git a/lldb/source/Symbol/CompilerType.cpp b/lldb/source/Symbol/CompilerType.cpp index 571a8570a43b..09930f7a800e 100644 --- a/lldb/source/Symbol/CompilerType.cpp +++ b/lldb/source/Symbol/CompilerType.cpp @@ -26,12 +26,6 @@ using namespace lldb; using namespace lldb_private; -CompilerType::CompilerType(TypeSystem *type_system, - lldb::opaque_compiler_type_t type) - : m_type(type), m_type_system(type_system) {} - -CompilerType::~CompilerType() {} - // Tests bool CompilerType::IsAggregateType() const { @@ -427,6 +421,12 @@ CompilerType CompilerType::GetRValueReferenceType() const { return CompilerType(); } +CompilerType CompilerType::GetAtomicType() const { + if (IsValid()) + return m_type_system->GetAtomicType(m_type); + return CompilerType(); +} + CompilerType CompilerType::AddConstModifier() const { if (IsValid()) return m_type_system->AddConstModifier(m_type); @@ -874,173 +874,6 @@ bool CompilerType::GetValueAsScalar(const lldb_private::DataExtractor &data, return false; } -bool CompilerType::SetValueFromScalar(const Scalar &value, Stream &strm) { - if (!IsValid()) - return false; - - // Aggregate types don't have scalar values - if (!IsAggregateType()) { - strm.GetFlags().Set(Stream::eBinary); - uint64_t count = 0; - lldb::Encoding encoding = GetEncoding(count); - - if (encoding == lldb::eEncodingInvalid || count != 1) - return false; - - llvm::Optional<uint64_t> bit_width = GetBitSize(nullptr); - if (!bit_width) - return false; - - // This function doesn't currently handle non-byte aligned assignments - if ((*bit_width % 8) != 0) - return false; - - const uint64_t byte_size = (*bit_width + 7) / 8; - switch (encoding) { - case lldb::eEncodingInvalid: - break; - case lldb::eEncodingVector: - break; - case lldb::eEncodingUint: - switch (byte_size) { - case 1: - strm.PutHex8(value.UInt()); - return true; - case 2: - strm.PutHex16(value.UInt()); - return true; - case 4: - strm.PutHex32(value.UInt()); - return true; - case 8: - strm.PutHex64(value.ULongLong()); - return true; - default: - break; - } - break; - - case lldb::eEncodingSint: - switch (byte_size) { - case 1: - strm.PutHex8(value.SInt()); - return true; - case 2: - strm.PutHex16(value.SInt()); - return true; - case 4: - strm.PutHex32(value.SInt()); - return true; - case 8: - strm.PutHex64(value.SLongLong()); - return true; - default: - break; - } - break; - - case lldb::eEncodingIEEE754: - if (byte_size <= sizeof(long double)) { - if (byte_size == sizeof(float)) { - strm.PutFloat(value.Float()); - return true; - } else if (byte_size == sizeof(double)) { - strm.PutDouble(value.Double()); - return true; - } else if (byte_size == sizeof(long double)) { - strm.PutDouble(value.LongDouble()); - return true; - } - } - break; - } - } - return false; -} - -bool CompilerType::ReadFromMemory(lldb_private::ExecutionContext *exe_ctx, - lldb::addr_t addr, AddressType address_type, - lldb_private::DataExtractor &data) { - if (!IsValid()) - return false; - - // Can't convert a file address to anything valid without more context (which - // Module it came from) - if (address_type == eAddressTypeFile) - return false; - - if (!GetCompleteType()) - return false; - - auto byte_size = - GetByteSize(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr); - if (!byte_size) - return false; - - if (data.GetByteSize() < *byte_size) { - lldb::DataBufferSP data_sp(new DataBufferHeap(*byte_size, '\0')); - data.SetData(data_sp); - } - - uint8_t *dst = const_cast<uint8_t *>(data.PeekData(0, *byte_size)); - if (dst != nullptr) { - if (address_type == eAddressTypeHost) { - if (addr == 0) - return false; - // The address is an address in this process, so just copy it - memcpy(dst, reinterpret_cast<uint8_t *>(addr), *byte_size); - return true; - } else { - Process *process = nullptr; - if (exe_ctx) - process = exe_ctx->GetProcessPtr(); - if (process) { - Status error; - return process->ReadMemory(addr, dst, *byte_size, error) == *byte_size; - } - } - } - return false; -} - -bool CompilerType::WriteToMemory(lldb_private::ExecutionContext *exe_ctx, - lldb::addr_t addr, AddressType address_type, - StreamString &new_value) { - if (!IsValid()) - return false; - - // Can't convert a file address to anything valid without more context (which - // Module it came from) - if (address_type == eAddressTypeFile) - return false; - - if (!GetCompleteType()) - return false; - - auto byte_size = - GetByteSize(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr); - if (!byte_size) - return false; - - if (*byte_size > 0) { - if (address_type == eAddressTypeHost) { - // The address is an address in this process, so just copy it - memcpy((void *)addr, new_value.GetData(), *byte_size); - return true; - } else { - Process *process = nullptr; - if (exe_ctx) - process = exe_ctx->GetProcessPtr(); - if (process) { - Status error; - return process->WriteMemory(addr, new_value.GetData(), *byte_size, - error) == *byte_size; - } - } - } - return false; -} - bool lldb_private::operator==(const lldb_private::CompilerType &lhs, const lldb_private::CompilerType &rhs) { return lhs.GetTypeSystem() == rhs.GetTypeSystem() && diff --git a/lldb/source/Symbol/Declaration.cpp b/lldb/source/Symbol/Declaration.cpp index d78ba967d280..4d0975d34256 100644 --- a/lldb/source/Symbol/Declaration.cpp +++ b/lldb/source/Symbol/Declaration.cpp @@ -90,12 +90,9 @@ bool Declaration::FileAndLineEqual(const Declaration &declaration) const { bool lldb_private::operator==(const Declaration &lhs, const Declaration &rhs) { #ifdef LLDB_ENABLE_DECLARATION_COLUMNS - if (lhs.GetColumn() == rhs.GetColumn()) - if (lhs.GetLine() == rhs.GetLine()) - return lhs.GetFile() == rhs.GetFile(); + if (lhs.GetColumn() != rhs.GetColumn()) + return false; #else - if (lhs.GetLine() == rhs.GetLine()) - return FileSpec::Equal(lhs.GetFile(), rhs.GetFile(), true); + return lhs.GetLine() == rhs.GetLine() && lhs.GetFile() == rhs.GetFile(); #endif - return false; } diff --git a/lldb/source/Symbol/FuncUnwinders.cpp b/lldb/source/Symbol/FuncUnwinders.cpp index f609bf7821e1..7a6f3cefea66 100644 --- a/lldb/source/Symbol/FuncUnwinders.cpp +++ b/lldb/source/Symbol/FuncUnwinders.cpp @@ -41,7 +41,9 @@ FuncUnwinders::FuncUnwinders(UnwindTable &unwind_table, AddressRange range) m_unwind_plan_arch_default_sp(), m_unwind_plan_arch_default_at_func_entry_sp(), m_tried_unwind_plan_assembly(false), m_tried_unwind_plan_eh_frame(false), + m_tried_unwind_plan_object_file(false), m_tried_unwind_plan_debug_frame(false), + m_tried_unwind_plan_object_file_augmented(false), m_tried_unwind_plan_eh_frame_augmented(false), m_tried_unwind_plan_debug_frame_augmented(false), m_tried_unwind_plan_compact_unwind(false), diff --git a/lldb/source/Symbol/Function.cpp b/lldb/source/Symbol/Function.cpp index a4c2d3b4b44a..e92585ccfed7 100644 --- a/lldb/source/Symbol/Function.cpp +++ b/lldb/source/Symbol/Function.cpp @@ -17,6 +17,7 @@ #include "lldb/Symbol/LineTable.h" #include "lldb/Symbol/SymbolFile.h" #include "lldb/Target/Language.h" +#include "lldb/Target/Target.h" #include "lldb/Utility/Log.h" #include "llvm/Support/Casting.h" @@ -75,16 +76,6 @@ InlineFunctionInfo::InlineFunctionInfo(ConstString name, InlineFunctionInfo::~InlineFunctionInfo() {} -int InlineFunctionInfo::Compare(const InlineFunctionInfo &a, - const InlineFunctionInfo &b) { - - int result = FunctionInfo::Compare(a, b); - if (result) - return result; - // only compare the mangled names if both have them - return Mangled::Compare(a.m_mangled, a.m_mangled); -} - void InlineFunctionInfo::Dump(Stream *s, bool show_fullpaths) const { FunctionInfo::Dump(s, show_fullpaths); if (m_mangled) @@ -127,23 +118,21 @@ size_t InlineFunctionInfo::MemorySize() const { return FunctionInfo::MemorySize() + m_mangled.MemorySize(); } -// -CallEdge::CallEdge(const char *symbol_name, lldb::addr_t return_pc, - CallSiteParameterArray parameters) - : return_pc(return_pc), parameters(std::move(parameters)), resolved(false) { - lazy_callee.symbol_name = symbol_name; -} +/// @name Call site related structures +/// @{ -llvm::ArrayRef<CallSiteParameter> CallEdge::GetCallSiteParameters() const { - return parameters; +lldb::addr_t CallEdge::GetReturnPCAddress(Function &caller, + Target &target) const { + const Address &base = caller.GetAddressRange().GetBaseAddress(); + return base.GetLoadAddress(&target) + return_pc; } -void CallEdge::ParseSymbolFileAndResolve(ModuleList &images) { +void DirectCallEdge::ParseSymbolFileAndResolve(ModuleList &images) { if (resolved) return; Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); - LLDB_LOG(log, "CallEdge: Lazily parsing the call graph for {0}", + LLDB_LOG(log, "DirectCallEdge: Lazily parsing the call graph for {0}", lazy_callee.symbol_name); auto resolve_lazy_callee = [&]() -> Function * { @@ -152,18 +141,19 @@ void CallEdge::ParseSymbolFileAndResolve(ModuleList &images) { images.FindFunctionSymbols(callee_name, eFunctionNameTypeAuto, sc_list); size_t num_matches = sc_list.GetSize(); if (num_matches == 0 || !sc_list[0].symbol) { - LLDB_LOG(log, "CallEdge: Found no symbols for {0}, cannot resolve it", + LLDB_LOG(log, + "DirectCallEdge: Found no symbols for {0}, cannot resolve it", callee_name); return nullptr; } Address callee_addr = sc_list[0].symbol->GetAddress(); if (!callee_addr.IsValid()) { - LLDB_LOG(log, "CallEdge: Invalid symbol address"); + LLDB_LOG(log, "DirectCallEdge: Invalid symbol address"); return nullptr; } Function *f = callee_addr.CalculateSymbolContextFunction(); if (!f) { - LLDB_LOG(log, "CallEdge: Could not find complete function"); + LLDB_LOG(log, "DirectCallEdge: Could not find complete function"); return nullptr; } return f; @@ -172,18 +162,50 @@ void CallEdge::ParseSymbolFileAndResolve(ModuleList &images) { resolved = true; } -Function *CallEdge::GetCallee(ModuleList &images) { +Function *DirectCallEdge::GetCallee(ModuleList &images, ExecutionContext &) { ParseSymbolFileAndResolve(images); assert(resolved && "Did not resolve lazy callee"); return lazy_callee.def; } -lldb::addr_t CallEdge::GetReturnPCAddress(Function &caller, - Target &target) const { - const Address &base = caller.GetAddressRange().GetBaseAddress(); - return base.GetLoadAddress(&target) + return_pc; +Function *IndirectCallEdge::GetCallee(ModuleList &images, + ExecutionContext &exe_ctx) { + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + Status error; + Value callee_addr_val; + if (!call_target.Evaluate(&exe_ctx, exe_ctx.GetRegisterContext(), + /*loclist_base_addr=*/LLDB_INVALID_ADDRESS, + /*initial_value_ptr=*/nullptr, + /*object_address_ptr=*/nullptr, callee_addr_val, + &error)) { + LLDB_LOGF(log, "IndirectCallEdge: Could not evaluate expression: %s", + error.AsCString()); + return nullptr; + } + + addr_t raw_addr = callee_addr_val.GetScalar().ULongLong(LLDB_INVALID_ADDRESS); + if (raw_addr == LLDB_INVALID_ADDRESS) { + LLDB_LOG(log, "IndirectCallEdge: Could not extract address from scalar"); + return nullptr; + } + + Address callee_addr; + if (!exe_ctx.GetTargetPtr()->ResolveLoadAddress(raw_addr, callee_addr)) { + LLDB_LOG(log, "IndirectCallEdge: Could not resolve callee's load address"); + return nullptr; + } + + Function *f = callee_addr.CalculateSymbolContextFunction(); + if (!f) { + LLDB_LOG(log, "IndirectCallEdge: Could not find complete function"); + return nullptr; + } + + return f; } +/// @} + // Function::Function(CompileUnit *comp_unit, lldb::user_id_t func_uid, lldb::user_id_t type_uid, const Mangled &mangled, Type *type, @@ -246,7 +268,7 @@ void Function::GetEndLineSourceInfo(FileSpec &source_file, uint32_t &line_no) { } } -llvm::MutableArrayRef<CallEdge> Function::GetCallEdges() { +llvm::ArrayRef<std::unique_ptr<CallEdge>> Function::GetCallEdges() { if (m_call_edges_resolved) return m_call_edges; @@ -267,19 +289,20 @@ llvm::MutableArrayRef<CallEdge> Function::GetCallEdges() { // Sort the call edges to speed up return_pc lookups. llvm::sort(m_call_edges.begin(), m_call_edges.end(), - [](const CallEdge &LHS, const CallEdge &RHS) { - return LHS.GetUnresolvedReturnPCAddress() < - RHS.GetUnresolvedReturnPCAddress(); + [](const std::unique_ptr<CallEdge> &LHS, + const std::unique_ptr<CallEdge> &RHS) { + return LHS->GetUnresolvedReturnPCAddress() < + RHS->GetUnresolvedReturnPCAddress(); }); return m_call_edges; } -llvm::MutableArrayRef<CallEdge> Function::GetTailCallingEdges() { +llvm::ArrayRef<std::unique_ptr<CallEdge>> Function::GetTailCallingEdges() { // Call edges are sorted by return PC, and tail calling edges have invalid // return PCs. Find them at the end of the list. - return GetCallEdges().drop_until([](const CallEdge &edge) { - return edge.GetUnresolvedReturnPCAddress() == LLDB_INVALID_ADDRESS; + return GetCallEdges().drop_until([](const std::unique_ptr<CallEdge> &edge) { + return edge->GetUnresolvedReturnPCAddress() == LLDB_INVALID_ADDRESS; }); } @@ -288,13 +311,13 @@ CallEdge *Function::GetCallEdgeForReturnAddress(addr_t return_pc, auto edges = GetCallEdges(); auto edge_it = std::lower_bound(edges.begin(), edges.end(), return_pc, - [&](const CallEdge &edge, addr_t pc) { - return edge.GetReturnPCAddress(*this, target) < pc; + [&](const std::unique_ptr<CallEdge> &edge, addr_t pc) { + return edge->GetReturnPCAddress(*this, target) < pc; }); if (edge_it == edges.end() || - edge_it->GetReturnPCAddress(*this, target) != return_pc) + edge_it->get()->GetReturnPCAddress(*this, target) != return_pc) return nullptr; - return &const_cast<CallEdge &>(*edge_it); + return &const_cast<CallEdge &>(*edge_it->get()); } Block &Function::GetBlock(bool can_create) { @@ -307,7 +330,8 @@ Block &Function::GetBlock(bool can_create) { "error: unable to find module " "shared pointer for function '%s' " "in %s\n", - GetName().GetCString(), m_comp_unit->GetPath().c_str()); + GetName().GetCString(), + m_comp_unit->GetPrimaryFile().GetPath().c_str()); } m_block.SetBlockInfoHasBeenParsed(true, true); } diff --git a/lldb/source/Symbol/LineEntry.cpp b/lldb/source/Symbol/LineEntry.cpp index 959a3274ec92..bb3828fef784 100644 --- a/lldb/source/Symbol/LineEntry.cpp +++ b/lldb/source/Symbol/LineEntry.cpp @@ -51,7 +51,7 @@ bool LineEntry::IsValid() const { bool LineEntry::DumpStopContext(Stream *s, bool show_fullpaths) const { if (file) { if (show_fullpaths) - file.Dump(s); + file.Dump(s->AsRawOstream()); else file.GetFilename().Dump(s); diff --git a/lldb/source/Symbol/LineTable.cpp b/lldb/source/Symbol/LineTable.cpp index 1433dc156d91..fecc90c409f2 100644 --- a/lldb/source/Symbol/LineTable.cpp +++ b/lldb/source/Symbol/LineTable.cpp @@ -34,11 +34,9 @@ void LineTable::InsertLineEntry(lldb::addr_t file_addr, uint32_t line, is_start_of_basic_block, is_prologue_end, is_epilogue_begin, is_terminal_entry); - entry_collection::iterator begin_pos = m_entries.begin(); - entry_collection::iterator end_pos = m_entries.end(); LineTable::Entry::LessThanBinaryPredicate less_than_bp(this); entry_collection::iterator pos = - upper_bound(begin_pos, end_pos, entry, less_than_bp); + llvm::upper_bound(m_entries, entry, less_than_bp); // Stream s(stdout); // s << "\n\nBefore:\n"; @@ -289,8 +287,6 @@ uint32_t LineTable::FindLineEntryIndexByFileIndex( uint32_t line, bool exact, LineEntry *line_entry_ptr) { const size_t count = m_entries.size(); - std::vector<uint32_t>::const_iterator begin_pos = file_indexes.begin(); - std::vector<uint32_t>::const_iterator end_pos = file_indexes.end(); size_t best_match = UINT32_MAX; for (size_t idx = start_idx; idx < count; ++idx) { @@ -299,7 +295,7 @@ uint32_t LineTable::FindLineEntryIndexByFileIndex( if (m_entries[idx].is_terminal_entry) continue; - if (find(begin_pos, end_pos, m_entries[idx].file_idx) == end_pos) + if (llvm::find(file_indexes, m_entries[idx].file_idx) == file_indexes.end()) continue; // Exact match always wins. Otherwise try to find the closest line > the diff --git a/lldb/source/Symbol/LocateSymbolFile.cpp b/lldb/source/Symbol/LocateSymbolFile.cpp index 0d0e5300668f..d2b39d6acd70 100644 --- a/lldb/source/Symbol/LocateSymbolFile.cpp +++ b/lldb/source/Symbol/LocateSymbolFile.cpp @@ -230,19 +230,19 @@ static FileSpec LocateExecutableSymbolFileDsym(const ModuleSpec &module_spec) { ModuleSpec Symbols::LocateExecutableObjectFile(const ModuleSpec &module_spec) { ModuleSpec result; - const FileSpec *exec_fspec = module_spec.GetFileSpecPtr(); + const FileSpec &exec_fspec = module_spec.GetFileSpec(); const ArchSpec *arch = module_spec.GetArchitecturePtr(); const UUID *uuid = module_spec.GetUUIDPtr(); static Timer::Category func_cat(LLVM_PRETTY_FUNCTION); Timer scoped_timer( func_cat, "LocateExecutableObjectFile (file = %s, arch = %s, uuid = %p)", - exec_fspec ? exec_fspec->GetFilename().AsCString("<NULL>") : "<NULL>", + exec_fspec ? exec_fspec.GetFilename().AsCString("<NULL>") : "<NULL>", arch ? arch->GetArchitectureName() : "<NULL>", (const void *)uuid); ModuleSpecList module_specs; ModuleSpec matched_module_spec; if (exec_fspec && - ObjectFile::GetModuleSpecifications(*exec_fspec, 0, 0, module_specs) && + ObjectFile::GetModuleSpecifications(exec_fspec, 0, 0, module_specs) && module_specs.FindMatchingModuleSpec(module_spec, matched_module_spec)) { result.GetFileSpec() = exec_fspec; } else { diff --git a/lldb/source/Symbol/LocateSymbolFileMacOSX.cpp b/lldb/source/Symbol/LocateSymbolFileMacOSX.cpp index 74718a8c5e30..5ee632ec2077 100644 --- a/lldb/source/Symbol/LocateSymbolFileMacOSX.cpp +++ b/lldb/source/Symbol/LocateSymbolFileMacOSX.cpp @@ -595,7 +595,7 @@ bool Symbols::DownloadObjectAndSymbolFile(ModuleSpec &module_spec, } Status error = Host::RunShellCommand( command.GetData(), - NULL, // current working directory + FileSpec(), // current working directory &exit_status, // Exit status &signo, // Signal int * &command_output, // Command output diff --git a/lldb/source/Symbol/ObjectFile.cpp b/lldb/source/Symbol/ObjectFile.cpp index 38bc7722d0d0..8a72b5fe6f67 100644 --- a/lldb/source/Symbol/ObjectFile.cpp +++ b/lldb/source/Symbol/ObjectFile.cpp @@ -352,7 +352,9 @@ AddressClass ObjectFile::GetAddressClass(addr_t file_addr) { case eSectionTypeDWARFDebugLine: case eSectionTypeDWARFDebugLineStr: case eSectionTypeDWARFDebugLoc: + case eSectionTypeDWARFDebugLocDwo: case eSectionTypeDWARFDebugLocLists: + case eSectionTypeDWARFDebugLocListsDwo: case eSectionTypeDWARFDebugMacInfo: case eSectionTypeDWARFDebugMacro: case eSectionTypeDWARFDebugNames: @@ -360,6 +362,7 @@ AddressClass ObjectFile::GetAddressClass(addr_t file_addr) { case eSectionTypeDWARFDebugPubTypes: case eSectionTypeDWARFDebugRanges: case eSectionTypeDWARFDebugRngLists: + case eSectionTypeDWARFDebugRngListsDwo: case eSectionTypeDWARFDebugStr: case eSectionTypeDWARFDebugStrDwo: case eSectionTypeDWARFDebugStrOffsets: diff --git a/lldb/source/Symbol/Symbol.cpp b/lldb/source/Symbol/Symbol.cpp index 3f2414335813..3ace153d32ab 100644 --- a/lldb/source/Symbol/Symbol.cpp +++ b/lldb/source/Symbol/Symbol.cpp @@ -210,7 +210,8 @@ void Symbol::GetDescription(Stream *s, lldb::DescriptionLevel level, s->Printf(", mangled=\"%s\"", m_mangled.GetMangledName().AsCString()); } -void Symbol::Dump(Stream *s, Target *target, uint32_t index) const { +void Symbol::Dump(Stream *s, Target *target, uint32_t index, + Mangled::NamePreference name_preference) const { s->Printf("[%5u] %6u %c%c%c %-15s ", index, GetID(), m_is_debug ? 'D' : ' ', m_is_synthetic ? 'S' : ' ', m_is_external ? 'X' : ' ', GetTypeAsString()); @@ -218,7 +219,7 @@ void Symbol::Dump(Stream *s, Target *target, uint32_t index) const { // Make sure the size of the symbol is up to date before dumping GetByteSize(); - ConstString name = m_mangled.GetName(GetLanguage()); + ConstString name = m_mangled.GetName(GetLanguage(), name_preference); if (ValueIsAddress()) { if (!m_addr_range.GetBaseAddress().Dump(s, nullptr, Address::DumpStyleFileAddress)) diff --git a/lldb/source/Symbol/SymbolContext.cpp b/lldb/source/Symbol/SymbolContext.cpp index 31e0c89eed94..9eb805976f95 100644 --- a/lldb/source/Symbol/SymbolContext.cpp +++ b/lldb/source/Symbol/SymbolContext.cpp @@ -55,20 +55,6 @@ SymbolContext::SymbolContext(SymbolContextScope *sc_scope) SymbolContext::~SymbolContext() {} -const SymbolContext &SymbolContext::operator=(const SymbolContext &rhs) { - if (this != &rhs) { - target_sp = rhs.target_sp; - module_sp = rhs.module_sp; - comp_unit = rhs.comp_unit; - function = rhs.function; - block = rhs.block; - line_entry = rhs.line_entry; - symbol = rhs.symbol; - variable = rhs.variable; - } - return *this; -} - void SymbolContext::Clear(bool clear_target) { if (clear_target) target_sp.reset(); @@ -198,7 +184,7 @@ void SymbolContext::GetDescription(Stream *s, lldb::DescriptionLevel level, Target *target) const { if (module_sp) { s->Indent(" Module: file = \""); - module_sp->GetFileSpec().Dump(s); + module_sp->GetFileSpec().Dump(s->AsRawOstream()); *s << '"'; if (module_sp->GetArchitecture().IsValid()) s->Printf(", arch = \"%s\"", @@ -324,19 +310,19 @@ void SymbolContext::Dump(Stream *s, Target *target) const { s->Indent(); *s << "Module = " << module_sp.get() << ' '; if (module_sp) - module_sp->GetFileSpec().Dump(s); + module_sp->GetFileSpec().Dump(s->AsRawOstream()); s->EOL(); s->Indent(); *s << "CompileUnit = " << comp_unit; if (comp_unit != nullptr) - *s << " {0x" << comp_unit->GetID() << "} " - << *(static_cast<FileSpec *>(comp_unit)); + s->Format(" {{{0:x-16}} {1}", comp_unit->GetID(), + comp_unit->GetPrimaryFile()); s->EOL(); s->Indent(); *s << "Function = " << function; if (function != nullptr) { - *s << " {0x" << function->GetID() << "} " << function->GetType()->GetName() - << ", address-range = "; + s->Format(" {{{0:x-16}} {1}, address-range = ", function->GetID(), + function->GetType()->GetName()); function->GetAddressRange().Dump(s, target, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress); s->EOL(); @@ -351,10 +337,7 @@ void SymbolContext::Dump(Stream *s, Target *target) const { s->Indent(); *s << "Block = " << block; if (block != nullptr) - *s << " {0x" << block->GetID() << '}'; - // Dump the block and pass it a negative depth to we print all the parent - // blocks if (block != NULL) - // block->Dump(s, function->GetFileAddress(), INT_MIN); + s->Format(" {{{0:x-16}}", block->GetID()); s->EOL(); s->Indent(); *s << "LineEntry = "; @@ -368,7 +351,8 @@ void SymbolContext::Dump(Stream *s, Target *target) const { s->EOL(); *s << "Variable = " << variable; if (variable != nullptr) { - *s << " {0x" << variable->GetID() << "} " << variable->GetType()->GetName(); + s->Format(" {{{0:x-16}} {1}", variable->GetID(), + variable->GetType()->GetName()); s->EOL(); } s->IndentLess(); @@ -1042,8 +1026,7 @@ bool SymbolContextSpecifier::SymbolContextMatches(SymbolContext &sc) { return false; } else { FileSpec module_file_spec(m_module_spec); - if (!FileSpec::Equal(module_file_spec, sc.module_sp->GetFileSpec(), - false)) + if (!FileSpec::Match(module_file_spec, sc.module_sp->GetFileSpec())) return false; } } @@ -1062,8 +1045,8 @@ bool SymbolContextSpecifier::SymbolContextMatches(SymbolContext &sc) { sc.block->GetInlinedFunctionInfo(); if (inline_info != nullptr) { was_inlined = true; - if (!FileSpec::Equal(inline_info->GetDeclaration().GetFile(), - *(m_file_spec_up.get()), false)) + if (!FileSpec::Match(*m_file_spec_up, + inline_info->GetDeclaration().GetFile())) return false; } } @@ -1071,7 +1054,7 @@ bool SymbolContextSpecifier::SymbolContextMatches(SymbolContext &sc) { // Next check the comp unit, but only if the SymbolContext was not // inlined. if (!was_inlined && sc.comp_unit != nullptr) { - if (!FileSpec::Equal(*(sc.comp_unit), *(m_file_spec_up.get()), false)) + if (!FileSpec::Match(*m_file_spec_up, sc.comp_unit->GetPrimaryFile())) return false; } } diff --git a/lldb/source/Symbol/SymbolFile.cpp b/lldb/source/Symbol/SymbolFile.cpp index c4f3a9c1a8c8..90f7d1011716 100644 --- a/lldb/source/Symbol/SymbolFile.cpp +++ b/lldb/source/Symbol/SymbolFile.cpp @@ -24,6 +24,8 @@ using namespace lldb_private; using namespace lldb; +char SymbolFile::ID; + void SymbolFile::PreloadSymbols() { // No-op for most implementations. } @@ -134,7 +136,9 @@ void SymbolFile::FindTypes( TypeMap &types) {} void SymbolFile::FindTypes(llvm::ArrayRef<CompilerContext> pattern, - LanguageSet languages, TypeMap &types) {} + LanguageSet languages, + llvm::DenseSet<SymbolFile *> &searched_symbol_files, + TypeMap &types) {} void SymbolFile::AssertModuleLock() { // The code below is too expensive to leave enabled in release builds. It's diff --git a/lldb/source/Symbol/Symtab.cpp b/lldb/source/Symbol/Symtab.cpp index c4e6c2ccfb09..f5bd22ee5ee2 100644 --- a/lldb/source/Symbol/Symtab.cpp +++ b/lldb/source/Symbol/Symtab.cpp @@ -13,7 +13,6 @@ #include "lldb/Core/Module.h" #include "lldb/Core/RichManglingContext.h" -#include "lldb/Core/STLUtils.h" #include "lldb/Core/Section.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Symbol/Symbol.h" @@ -29,7 +28,7 @@ using namespace lldb; using namespace lldb_private; Symtab::Symtab(ObjectFile *objfile) - : m_objfile(objfile), m_symbols(), m_file_addr_to_index(), + : m_objfile(objfile), m_symbols(), m_file_addr_to_index(*this), m_name_to_index(), m_mutex(), m_file_addr_to_index_computed(false), m_name_indexes_computed(false) {} @@ -70,7 +69,8 @@ void Symtab::SectionFileAddressesChanged() { m_file_addr_to_index_computed = false; } -void Symtab::Dump(Stream *s, Target *target, SortOrder sort_order) { +void Symtab::Dump(Stream *s, Target *target, SortOrder sort_order, + Mangled::NamePreference name_preference) { std::lock_guard<std::recursive_mutex> guard(m_mutex); // s->Printf("%.*p: ", (int)sizeof(void*) * 2, this); @@ -97,7 +97,7 @@ void Symtab::Dump(Stream *s, Target *target, SortOrder sort_order) { const_iterator end = m_symbols.end(); for (const_iterator pos = m_symbols.begin(); pos != end; ++pos) { s->Indent(); - pos->Dump(s, target, std::distance(begin, pos)); + pos->Dump(s, target, std::distance(begin, pos), name_preference); } } break; @@ -106,10 +106,8 @@ void Symtab::Dump(Stream *s, Target *target, SortOrder sort_order) { // sorted by name. So we must make the ordered symbol list up ourselves. s->PutCString(" (sorted by name):\n"); DumpSymbolHeader(s); - typedef std::multimap<const char *, const Symbol *, - CStringCompareFunctionObject> - CStringToSymbol; - CStringToSymbol name_map; + + std::multimap<llvm::StringRef, const Symbol *> name_map; for (const_iterator pos = m_symbols.begin(), end = m_symbols.end(); pos != end; ++pos) { const char *name = pos->GetName().AsCString(); @@ -117,11 +115,10 @@ void Symtab::Dump(Stream *s, Target *target, SortOrder sort_order) { name_map.insert(std::make_pair(name, &(*pos))); } - for (CStringToSymbol::const_iterator pos = name_map.begin(), - end = name_map.end(); - pos != end; ++pos) { + for (const auto &name_to_symbol : name_map) { + const Symbol *symbol = name_to_symbol.second; s->Indent(); - pos->second->Dump(s, target, pos->second - &m_symbols[0]); + symbol->Dump(s, target, symbol - &m_symbols[0], name_preference); } } break; @@ -134,7 +131,7 @@ void Symtab::Dump(Stream *s, Target *target, SortOrder sort_order) { for (size_t i = 0; i < num_entries; ++i) { s->Indent(); const uint32_t symbol_idx = m_file_addr_to_index.GetEntryRef(i).data; - m_symbols[symbol_idx].Dump(s, target, symbol_idx); + m_symbols[symbol_idx].Dump(s, target, symbol_idx, name_preference); } break; } @@ -143,8 +140,8 @@ void Symtab::Dump(Stream *s, Target *target, SortOrder sort_order) { } } -void Symtab::Dump(Stream *s, Target *target, - std::vector<uint32_t> &indexes) const { +void Symtab::Dump(Stream *s, Target *target, std::vector<uint32_t> &indexes, + Mangled::NamePreference name_preference) const { std::lock_guard<std::recursive_mutex> guard(m_mutex); const size_t num_symbols = GetNumSymbols(); @@ -162,7 +159,7 @@ void Symtab::Dump(Stream *s, Target *target, size_t idx = *pos; if (idx < num_symbols) { s->Indent(); - m_symbols[idx].Dump(s, target, idx); + m_symbols[idx].Dump(s, target, idx, name_preference); } } } @@ -893,14 +890,8 @@ void Symtab::InitAddressIndexes() { for (size_t i = 0; i < num_entries; i++) { FileRangeToIndexMap::Entry *entry = m_file_addr_to_index.GetMutableEntryAtIndex(i); - if (entry->GetByteSize() > 0) - continue; - addr_t curr_base_addr = entry->GetRangeBase(); - // Symbols with non-zero size will show after zero-sized symbols on the - // same address. So do not set size of a non-last zero-sized symbol. - if (i == num_entries - 1 || - m_file_addr_to_index.GetMutableEntryAtIndex(i + 1) - ->GetRangeBase() != curr_base_addr) { + if (entry->GetByteSize() == 0) { + addr_t curr_base_addr = entry->GetRangeBase(); const RangeVector<addr_t, addr_t>::Entry *containing_section = section_ranges.FindEntryThatContains(curr_base_addr); diff --git a/lldb/source/Symbol/Type.cpp b/lldb/source/Symbol/Type.cpp index 5666590c2246..f194356a0a07 100644 --- a/lldb/source/Symbol/Type.cpp +++ b/lldb/source/Symbol/Type.cpp @@ -139,16 +139,19 @@ Type *SymbolFileType::GetType() { return m_type_sp.get(); } -Type::Type(lldb::user_id_t uid, SymbolFile *symbol_file, - ConstString name, llvm::Optional<uint64_t> byte_size, - SymbolContextScope *context, user_id_t encoding_uid, - EncodingDataType encoding_uid_type, const Declaration &decl, - const CompilerType &compiler_type, +Type::Type(lldb::user_id_t uid, SymbolFile *symbol_file, ConstString name, + llvm::Optional<uint64_t> byte_size, SymbolContextScope *context, + user_id_t encoding_uid, EncodingDataType encoding_uid_type, + const Declaration &decl, const CompilerType &compiler_type, ResolveState compiler_type_resolve_state) : std::enable_shared_from_this<Type>(), UserID(uid), m_name(name), m_symbol_file(symbol_file), m_context(context), m_encoding_type(nullptr), m_encoding_uid(encoding_uid), m_encoding_uid_type(encoding_uid_type), - m_decl(decl), m_compiler_type(compiler_type) { + m_decl(decl), m_compiler_type(compiler_type), + m_compiler_type_resolve_state( + compiler_type ? compiler_type_resolve_state + : ResolveState::Unresolved), + m_is_complete_objc_class(false) { if (byte_size) { m_byte_size = *byte_size; m_byte_size_has_value = true; @@ -156,19 +159,15 @@ Type::Type(lldb::user_id_t uid, SymbolFile *symbol_file, m_byte_size = 0; m_byte_size_has_value = false; } - m_flags.compiler_type_resolve_state = - (compiler_type ? compiler_type_resolve_state : eResolveStateUnresolved); - m_flags.is_complete_objc_class = false; } Type::Type() : std::enable_shared_from_this<Type>(), UserID(0), m_name("<INVALID TYPE>"), m_symbol_file(nullptr), m_context(nullptr), m_encoding_type(nullptr), m_encoding_uid(LLDB_INVALID_UID), m_encoding_uid_type(eEncodingInvalid), - m_byte_size(0), m_byte_size_has_value(false), m_decl(), - m_compiler_type() { - m_flags.compiler_type_resolve_state = eResolveStateUnresolved; - m_flags.is_complete_objc_class = false; + m_compiler_type_resolve_state(ResolveState::Unresolved) { + m_byte_size = 0; + m_byte_size_has_value = false; } void Type::GetDescription(Stream *s, lldb::DescriptionLevel level, @@ -214,6 +213,9 @@ void Type::GetDescription(Stream *s, lldb::DescriptionLevel level, case eEncodingIsVolatileUID: s->PutCString(" (unresolved volatile type)"); break; + case eEncodingIsAtomicUID: + s->PutCString(" (unresolved atomic type)"); + break; case eEncodingIsTypedefUID: s->PutCString(" (unresolved typedef)"); break; @@ -256,7 +258,7 @@ void Type::Dump(Stream *s, bool show_context) { *s << ", compiler_type = " << m_compiler_type.GetOpaqueQualType() << ' '; GetForwardCompilerType().DumpTypeDescription(s); } else if (m_encoding_uid != LLDB_INVALID_UID) { - *s << ", type_data = " << (uint64_t)m_encoding_uid; + s->Format(", type_data = {0:x-16}", m_encoding_uid); switch (m_encoding_uid_type) { case eEncodingInvalid: break; @@ -272,6 +274,9 @@ void Type::Dump(Stream *s, bool show_context) { case eEncodingIsVolatileUID: s->PutCString(" (unresolved volatile type)"); break; + case eEncodingIsAtomicUID: + s->PutCString(" (unresolved atomic type)"); + break; case eEncodingIsTypedefUID: s->PutCString(" (unresolved typedef)"); break; @@ -308,7 +313,7 @@ void Type::DumpValue(ExecutionContext *exe_ctx, Stream *s, const DataExtractor &data, uint32_t data_byte_offset, bool show_types, bool show_summary, bool verbose, lldb::Format format) { - if (ResolveClangType(eResolveStateForward)) { + if (ResolveClangType(ResolveState::Forward)) { if (show_types) { s->PutChar('('); if (verbose) @@ -344,6 +349,7 @@ llvm::Optional<uint64_t> Type::GetByteSize() { case eEncodingIsConstUID: case eEncodingIsRestrictUID: case eEncodingIsVolatileUID: + case eEncodingIsAtomicUID: case eEncodingIsTypedefUID: { Type *encoding_type = GetEncodingType(); if (encoding_type) @@ -472,8 +478,8 @@ bool Type::ResolveClangType(ResolveState compiler_type_resolve_state) { encoding_type->GetForwardCompilerType(); if (encoding_compiler_type.IsValid()) { m_compiler_type = encoding_compiler_type; - m_flags.compiler_type_resolve_state = - encoding_type->m_flags.compiler_type_resolve_state; + m_compiler_type_resolve_state = + encoding_type->m_compiler_type_resolve_state; } } break; @@ -492,6 +498,11 @@ bool Type::ResolveClangType(ResolveState compiler_type_resolve_state) { encoding_type->GetForwardCompilerType().AddVolatileModifier(); break; + case eEncodingIsAtomicUID: + m_compiler_type = + encoding_type->GetForwardCompilerType().GetAtomicType(); + break; + case eEncodingIsTypedefUID: m_compiler_type = encoding_type->GetForwardCompilerType().CreateTypedef( m_name.AsCString("__lldb_invalid_typedef_name"), @@ -546,6 +557,10 @@ bool Type::ResolveClangType(ResolveState compiler_type_resolve_state) { m_compiler_type = void_compiler_type.AddVolatileModifier(); break; + case eEncodingIsAtomicUID: + m_compiler_type = void_compiler_type.GetAtomicType(); + break; + case eEncodingIsTypedefUID: m_compiler_type = void_compiler_type.CreateTypedef( m_name.AsCString("__lldb_invalid_typedef_name"), @@ -574,16 +589,16 @@ bool Type::ResolveClangType(ResolveState compiler_type_resolve_state) { // set to eResolveStateUnresolved so we need to update it to say that we // now have a forward declaration since that is what we created above. if (m_compiler_type.IsValid()) - m_flags.compiler_type_resolve_state = eResolveStateForward; + m_compiler_type_resolve_state = ResolveState::Forward; } // Check if we have a forward reference to a class/struct/union/enum? - if (compiler_type_resolve_state == eResolveStateLayout || - compiler_type_resolve_state == eResolveStateFull) { + if (compiler_type_resolve_state == ResolveState::Layout || + compiler_type_resolve_state == ResolveState::Full) { // Check if we have a forward reference to a class/struct/union/enum? if (m_compiler_type.IsValid() && - m_flags.compiler_type_resolve_state < compiler_type_resolve_state) { - m_flags.compiler_type_resolve_state = eResolveStateFull; + m_compiler_type_resolve_state < compiler_type_resolve_state) { + m_compiler_type_resolve_state = ResolveState::Full; if (!m_compiler_type.IsDefined()) { // We have a forward declaration, we need to resolve it to a complete // definition. @@ -601,12 +616,12 @@ bool Type::ResolveClangType(ResolveState compiler_type_resolve_state) { ResolveState encoding_compiler_type_resolve_state = compiler_type_resolve_state; - if (compiler_type_resolve_state == eResolveStateLayout) { + if (compiler_type_resolve_state == ResolveState::Layout) { switch (m_encoding_uid_type) { case eEncodingIsPointerUID: case eEncodingIsLValueReferenceUID: case eEncodingIsRValueReferenceUID: - encoding_compiler_type_resolve_state = eResolveStateForward; + encoding_compiler_type_resolve_state = ResolveState::Forward; break; default: break; @@ -627,31 +642,20 @@ uint32_t Type::GetEncodingMask() { } CompilerType Type::GetFullCompilerType() { - ResolveClangType(eResolveStateFull); + ResolveClangType(ResolveState::Full); return m_compiler_type; } CompilerType Type::GetLayoutCompilerType() { - ResolveClangType(eResolveStateLayout); + ResolveClangType(ResolveState::Layout); return m_compiler_type; } CompilerType Type::GetForwardCompilerType() { - ResolveClangType(eResolveStateForward); + ResolveClangType(ResolveState::Forward); return m_compiler_type; } -int Type::Compare(const Type &a, const Type &b) { - // Just compare the UID values for now... - lldb::user_id_t a_uid = a.GetID(); - lldb::user_id_t b_uid = b.GetID(); - if (a_uid < b_uid) - return -1; - if (a_uid > b_uid) - return 1; - return 0; -} - ConstString Type::GetQualifiedName() { return GetForwardCompilerType().GetConstTypeName(); } diff --git a/lldb/source/Symbol/TypeSystem.cpp b/lldb/source/Symbol/TypeSystem.cpp index c63f24aea335..29a49a6fb1d4 100644 --- a/lldb/source/Symbol/TypeSystem.cpp +++ b/lldb/source/Symbol/TypeSystem.cpp @@ -43,8 +43,6 @@ size_t LanguageSet::Size() const { return bitvector.count(); } bool LanguageSet::Empty() const { return bitvector.none(); } bool LanguageSet::operator[](unsigned i) const { return bitvector[i]; } -TypeSystem::TypeSystem(LLVMCastKind kind) : m_kind(kind), m_sym_file(nullptr) {} - TypeSystem::~TypeSystem() {} static lldb::TypeSystemSP CreateInstanceHelper(lldb::LanguageType language, @@ -91,6 +89,10 @@ TypeSystem::GetRValueReferenceType(lldb::opaque_compiler_type_t type) { return CompilerType(); } +CompilerType TypeSystem::GetAtomicType(lldb::opaque_compiler_type_t type) { + return CompilerType(); +} + CompilerType TypeSystem::AddConstModifier(lldb::opaque_compiler_type_t type) { return CompilerType(); } diff --git a/lldb/source/Symbol/Variable.cpp b/lldb/source/Symbol/Variable.cpp index 3f3d7c198f15..a0496824a0a3 100644 --- a/lldb/source/Symbol/Variable.cpp +++ b/lldb/source/Symbol/Variable.cpp @@ -112,7 +112,7 @@ void Variable::Dump(Stream *s, bool show_context) const { if (m_symfile_type_sp) { Type *type = m_symfile_type_sp->GetType(); if (type) { - *s << ", type = {" << type->GetID() << "} " << (void *)type << " ("; + s->Format(", type = {{{0:x-16}} {1} (", type->GetID(), type); type->DumpTypeName(s); s->PutChar(')'); } @@ -134,7 +134,7 @@ void Variable::Dump(Stream *s, bool show_context) const { s->PutCString("thread local"); break; default: - *s << "??? (" << m_scope << ')'; + s->AsRawOstream() << "??? (" << m_scope << ')'; } } @@ -492,13 +492,6 @@ static void PrivateAutoCompleteMembers( llvm::StringRef partial_path, const llvm::Twine &prefix_path, // Anything that has been resolved already will be in here - const CompilerType &compiler_type, CompletionRequest &request); - -static void PrivateAutoCompleteMembers( - StackFrame *frame, const std::string &partial_member_name, - llvm::StringRef partial_path, - const llvm::Twine - &prefix_path, // Anything that has been resolved already will be in here const CompilerType &compiler_type, CompletionRequest &request) { // We are in a type parsing child members @@ -609,11 +602,8 @@ static void PrivateAutoComplete( VariableList *variable_list = frame->GetVariableList(get_file_globals); if (variable_list) { - const size_t num_variables = variable_list->GetSize(); - for (size_t i = 0; i < num_variables; ++i) { - Variable *variable = variable_list->GetVariableAtIndex(i).get(); - request.AddCompletion(variable->GetName().AsCString()); - } + for (const VariableSP &var_sp : *variable_list) + request.AddCompletion(var_sp->GetName().AsCString()); } } } @@ -710,17 +700,15 @@ static void PrivateAutoComplete( if (!variable_list) break; - const size_t num_variables = variable_list->GetSize(); - for (size_t i = 0; i < num_variables; ++i) { - Variable *variable = variable_list->GetVariableAtIndex(i).get(); + for (VariableSP var_sp : *variable_list) { - if (!variable) + if (!var_sp) continue; - const char *variable_name = variable->GetName().AsCString(); - if (strstr(variable_name, token.c_str()) == variable_name) { - if (strcmp(variable_name, token.c_str()) == 0) { - Type *variable_type = variable->GetType(); + llvm::StringRef variable_name = var_sp->GetName().GetStringRef(); + if (variable_name.startswith(token)) { + if (variable_name == token) { + Type *variable_type = var_sp->GetType(); if (variable_type) { CompilerType variable_compiler_type( variable_type->GetForwardCompilerType()); |