diff --git a/lldb/include/lldb/Symbol/CompilerDeclContext.h b/lldb/include/lldb/Symbol/CompilerDeclContext.h --- a/lldb/include/lldb/Symbol/CompilerDeclContext.h +++ b/lldb/include/lldb/Symbol/CompilerDeclContext.h @@ -61,27 +61,13 @@ /// Checks if this decl context represents a method of a class. /// - /// \param[out] language_ptr - /// If non NULL and \b true is returned from this function, - /// this will indicate if the language that respresents the method. - /// - /// \param[out] is_instance_method_ptr - /// If non NULL and \b true is returned from this function, - /// this will indicate if the method is an instance function (true) - /// or a class method (false indicating the function is static, or - /// doesn't require an instance of the class to be called). - /// - /// \param[out] language_object_name_ptr - /// If non NULL and \b true is returned from this function, - /// this will indicate if implicit object name for the language - /// like "this" for C++, and "self" for Objective C. - /// /// \return /// Returns true if this is a decl context that represents a method /// in a struct, union or class. - bool IsClassMethod(lldb::LanguageType *language_ptr, - bool *is_instance_method_ptr, - ConstString *language_object_name_ptr); + bool IsClassMethod(); + + lldb::LanguageType GetLanguage(); + ConstString GetInstanceVariableName(lldb::LanguageType language); /// Check if the given other decl context is contained in the lookup /// of this decl context (for example because the other context is a nested diff --git a/lldb/include/lldb/Symbol/SymbolContext.h b/lldb/include/lldb/Symbol/SymbolContext.h --- a/lldb/include/lldb/Symbol/SymbolContext.h +++ b/lldb/include/lldb/Symbol/SymbolContext.h @@ -245,26 +245,7 @@ /// represented by this symbol context object, nullptr otherwise. Block *GetFunctionBlock(); - /// If this symbol context represents a function that is a method, return - /// true and provide information about the method. - /// - /// \param[out] language - /// If \b true is returned, the language for the method. - /// - /// \param[out] is_instance_method - /// If \b true is returned, \b true if this is a instance method, - /// \b false if this is a static/class function. - /// - /// \param[out] language_object_name - /// If \b true is returned, the name of the artificial variable - /// for the language ("this" for C++, "self" for ObjC). - /// - /// \return - /// \b True if this symbol context represents a function that - /// is a method of a class, \b false otherwise. - bool GetFunctionMethodInfo(lldb::LanguageType &language, - bool &is_instance_method, - ConstString &language_object_name); + ConstString GetInstanceVariableName(); /// Sorts the types in TypeMap according to SymbolContext to TypeList /// diff --git a/lldb/include/lldb/Symbol/TypeSystem.h b/lldb/include/lldb/Symbol/TypeSystem.h --- a/lldb/include/lldb/Symbol/TypeSystem.h +++ b/lldb/include/lldb/Symbol/TypeSystem.h @@ -127,13 +127,13 @@ virtual ConstString DeclContextGetScopeQualifiedName(void *opaque_decl_ctx) = 0; - virtual bool DeclContextIsClassMethod( - void *opaque_decl_ctx, lldb::LanguageType *language_ptr, - bool *is_instance_method_ptr, ConstString *language_object_name_ptr) = 0; + virtual bool DeclContextIsClassMethod(void *opaque_decl_ctx) = 0; virtual bool DeclContextIsContainedInLookup(void *opaque_decl_ctx, void *other_opaque_decl_ctx) = 0; + virtual lldb::LanguageType DeclContextGetLanguage(void *opaque_decl_ctx) = 0; + // Tests #ifndef NDEBUG /// Verify the integrity of the type to catch CompilerTypes that mix @@ -199,6 +199,10 @@ // TypeSystems can support more than one language virtual bool SupportsLanguage(lldb::LanguageType language) = 0; + /// The name of the variable used for explicitly accessing data scoped to the + /// current instance (or type). C++ uses "this", ObjC uses "self". + virtual ConstString GetInstanceVariableName(lldb::LanguageType language) = 0; + // Type Completion virtual bool GetCompleteType(lldb::opaque_compiler_type_t type) = 0; diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp --- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp +++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp @@ -1172,8 +1172,7 @@ // class/instance methods, since they'll be skipped in the code that // follows anyway. CompilerDeclContext func_decl_context = function->GetDeclContext(); - if (!func_decl_context || - func_decl_context.IsClassMethod(nullptr, nullptr, nullptr)) + if (!func_decl_context || func_decl_context.IsClassMethod()) continue; // We can only prune functions for which we can copy the type. CompilerType func_clang_type = function->GetType()->GetFullCompilerType(); @@ -1307,7 +1306,7 @@ continue; // Filter out class/instance methods. - if (decl_ctx.IsClassMethod(nullptr, nullptr, nullptr)) + if (decl_ctx.IsClassMethod()) continue; AddOneFunction(context, sym_ctx.function, nullptr); diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h --- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h +++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h @@ -579,14 +579,13 @@ ConstString DeclContextGetScopeQualifiedName(void *opaque_decl_ctx) override; - bool DeclContextIsClassMethod(void *opaque_decl_ctx, - lldb::LanguageType *language_ptr, - bool *is_instance_method_ptr, - ConstString *language_object_name_ptr) override; + bool DeclContextIsClassMethod(void *opaque_decl_ctx) override; bool DeclContextIsContainedInLookup(void *opaque_decl_ctx, void *other_opaque_decl_ctx) override; + lldb::LanguageType DeclContextGetLanguage(void *opaque_decl_ctx) override; + // Clang specific clang::DeclContext functions static clang::DeclContext * @@ -710,6 +709,8 @@ bool SupportsLanguage(lldb::LanguageType language) override; + ConstString GetInstanceVariableName(lldb::LanguageType language) override; + static std::optional GetCXXClassName(const CompilerType &type); // Type Completion diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp --- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp +++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp @@ -8,6 +8,8 @@ #include "TypeSystemClang.h" +#include "clang/AST/DeclBase.h" +#include "llvm/Support/Casting.h" #include "llvm/Support/FormatAdapters.h" #include "llvm/Support/FormatVariadic.h" @@ -3739,6 +3741,21 @@ return TypeSystemClangSupportsLanguage(language); } +ConstString +TypeSystemClang::GetInstanceVariableName(lldb::LanguageType language) { + switch (language) { + case LanguageType::eLanguageTypeC_plus_plus: + case LanguageType::eLanguageTypeC_plus_plus_03: + case LanguageType::eLanguageTypeC_plus_plus_11: + case LanguageType::eLanguageTypeC_plus_plus_14: + return ConstString("this"); + case LanguageType::eLanguageTypeObjC: + return ConstString("self"); + default: + return {}; + } +} + std::optional TypeSystemClang::GetCXXClassName(const CompilerType &type) { if (!type) @@ -9764,43 +9781,21 @@ return ConstString(); } -bool TypeSystemClang::DeclContextIsClassMethod( - void *opaque_decl_ctx, lldb::LanguageType *language_ptr, - bool *is_instance_method_ptr, ConstString *language_object_name_ptr) { - if (opaque_decl_ctx) { - clang::DeclContext *decl_ctx = (clang::DeclContext *)opaque_decl_ctx; - if (ObjCMethodDecl *objc_method = - llvm::dyn_cast(decl_ctx)) { - if (is_instance_method_ptr) - *is_instance_method_ptr = objc_method->isInstanceMethod(); - if (language_ptr) - *language_ptr = eLanguageTypeObjC; - if (language_object_name_ptr) - language_object_name_ptr->SetCString("self"); - return true; - } else if (CXXMethodDecl *cxx_method = - llvm::dyn_cast(decl_ctx)) { - if (is_instance_method_ptr) - *is_instance_method_ptr = cxx_method->isInstance(); - if (language_ptr) - *language_ptr = eLanguageTypeC_plus_plus; - if (language_object_name_ptr) - language_object_name_ptr->SetCString("this"); - return true; - } else if (clang::FunctionDecl *function_decl = - llvm::dyn_cast(decl_ctx)) { - ClangASTMetadata *metadata = GetMetadata(function_decl); - if (metadata && metadata->HasObjectPtr()) { - if (is_instance_method_ptr) - *is_instance_method_ptr = true; - if (language_ptr) - *language_ptr = metadata->GetObjectPtrLanguage(); - if (language_object_name_ptr) - language_object_name_ptr->SetCString(metadata->GetObjectPtrName()); - return true; - } - } +bool TypeSystemClang::DeclContextIsClassMethod(void *opaque_decl_ctx) { + if (!opaque_decl_ctx) + return false; + + clang::DeclContext *decl_ctx = (clang::DeclContext *)opaque_decl_ctx; + if (llvm::isa(decl_ctx)) { + return true; + } else if (llvm::isa(decl_ctx)) { + return true; + } else if (clang::FunctionDecl *fun_decl = + llvm::dyn_cast(decl_ctx)) { + if (ClangASTMetadata *metadata = GetMetadata(fun_decl)) + return metadata->HasObjectPtr(); } + return false; } @@ -9821,6 +9816,24 @@ return false; } +lldb::LanguageType +TypeSystemClang::DeclContextGetLanguage(void *opaque_decl_ctx) { + if (!opaque_decl_ctx) + return eLanguageTypeUnknown; + + auto *decl_ctx = (clang::DeclContext *)opaque_decl_ctx; + if (llvm::isa(decl_ctx)) { + return eLanguageTypeObjC; + } else if (llvm::isa(decl_ctx)) { + return eLanguageTypeC_plus_plus; + } else if (auto *fun_decl = llvm::dyn_cast(decl_ctx)) { + if (ClangASTMetadata *metadata = GetMetadata(fun_decl)) + return metadata->GetObjectPtrLanguage(); + } + + return eLanguageTypeUnknown; +} + static bool IsClangDeclContext(const CompilerDeclContext &dc) { return dc.IsValid() && isa(dc.GetTypeSystem()); } diff --git a/lldb/source/Symbol/CompilerDeclContext.cpp b/lldb/source/Symbol/CompilerDeclContext.cpp --- a/lldb/source/Symbol/CompilerDeclContext.cpp +++ b/lldb/source/Symbol/CompilerDeclContext.cpp @@ -34,16 +34,25 @@ return ConstString(); } -bool CompilerDeclContext::IsClassMethod(lldb::LanguageType *language_ptr, - bool *is_instance_method_ptr, - ConstString *language_object_name_ptr) { +bool CompilerDeclContext::IsClassMethod() { if (IsValid()) - return m_type_system->DeclContextIsClassMethod( - m_opaque_decl_ctx, language_ptr, is_instance_method_ptr, - language_object_name_ptr); + return m_type_system->DeclContextIsClassMethod(m_opaque_decl_ctx); return false; } +lldb::LanguageType CompilerDeclContext::GetLanguage() { + if (IsValid()) + return m_type_system->DeclContextGetLanguage(m_opaque_decl_ctx); + return {}; +} + +ConstString +CompilerDeclContext::GetInstanceVariableName(lldb::LanguageType language) { + if (IsValid()) + return m_type_system->GetInstanceVariableName(language); + return {}; +} + bool CompilerDeclContext::IsContainedInLookup(CompilerDeclContext other) const { if (!IsValid()) return false; diff --git a/lldb/source/Symbol/SymbolContext.cpp b/lldb/source/Symbol/SymbolContext.cpp --- a/lldb/source/Symbol/SymbolContext.cpp +++ b/lldb/source/Symbol/SymbolContext.cpp @@ -539,19 +539,16 @@ return nullptr; } -bool SymbolContext::GetFunctionMethodInfo(lldb::LanguageType &language, - bool &is_instance_method, - ConstString &language_object_name) +ConstString SymbolContext::GetInstanceVariableName() { + if (Block *function_block = GetFunctionBlock()) + if (CompilerDeclContext decl_ctx = function_block->GetDeclContext()) { + auto language = decl_ctx.GetLanguage(); + if (language == eLanguageTypeUnknown) + language = GetLanguage(); + return decl_ctx.GetInstanceVariableName(language); + } -{ - Block *function_block = GetFunctionBlock(); - if (function_block) { - CompilerDeclContext decl_ctx = function_block->GetDeclContext(); - if (decl_ctx) - return decl_ctx.IsClassMethod(&language, &is_instance_method, - &language_object_name); - } - return false; + return {}; } void SymbolContext::SortTypeList(TypeMap &type_map, TypeList &type_list) const { diff --git a/lldb/source/Target/StackFrame.cpp b/lldb/source/Target/StackFrame.cpp --- a/lldb/source/Target/StackFrame.cpp +++ b/lldb/source/Target/StackFrame.cpp @@ -567,26 +567,20 @@ // Check for direct ivars access which helps us with implicit access to // ivars using "this" or "self". GetSymbolContext(eSymbolContextFunction | eSymbolContextBlock); - lldb::LanguageType method_language = eLanguageTypeUnknown; - bool is_instance_method = false; - ConstString method_object_name; - if (m_sc.GetFunctionMethodInfo(method_language, is_instance_method, - method_object_name)) { - if (is_instance_method && method_object_name) { - var_sp = variable_list->FindVariable(method_object_name); - if (var_sp) { - separator_idx = 0; - if (Type *var_type = var_sp->GetType()) - if (auto compiler_type = var_type->GetForwardCompilerType()) - if (!compiler_type.IsPointerType()) - var_expr_storage = "."; + if (auto instance_var_name = m_sc.GetInstanceVariableName()) { + var_sp = variable_list->FindVariable(instance_var_name); + if (var_sp) { + separator_idx = 0; + if (Type *var_type = var_sp->GetType()) + if (auto compiler_type = var_type->GetForwardCompilerType()) + if (!compiler_type.IsPointerType()) + var_expr_storage = "."; - if (var_expr_storage.empty()) - var_expr_storage = "->"; - var_expr_storage += var_expr; - var_expr = var_expr_storage; - synthetically_added_instance_object = true; - } + if (var_expr_storage.empty()) + var_expr_storage = "->"; + var_expr_storage += var_expr; + var_expr = var_expr_storage; + synthetically_added_instance_object = true; } } }