1061da546Spatrick //===-- DWARFASTParserClang.h -----------------------------------*- C++ -*-===// 2061da546Spatrick // 3061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4061da546Spatrick // See https://llvm.org/LICENSE.txt for license information. 5061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6061da546Spatrick // 7061da546Spatrick //===----------------------------------------------------------------------===// 8061da546Spatrick 9dda28197Spatrick #ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFASTPARSERCLANG_H 10dda28197Spatrick #define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFASTPARSERCLANG_H 11061da546Spatrick 12061da546Spatrick #include "clang/AST/CharUnits.h" 13*f6aab3d8Srobert #include "clang/AST/Type.h" 14061da546Spatrick #include "llvm/ADT/DenseMap.h" 15061da546Spatrick #include "llvm/ADT/SmallPtrSet.h" 16061da546Spatrick #include "llvm/ADT/SmallVector.h" 17061da546Spatrick 18061da546Spatrick #include "DWARFASTParser.h" 19061da546Spatrick #include "DWARFDIE.h" 20061da546Spatrick #include "DWARFDefines.h" 21061da546Spatrick #include "DWARFFormValue.h" 22061da546Spatrick #include "LogChannelDWARF.h" 23061da546Spatrick #include "lldb/Core/PluginInterface.h" 24dda28197Spatrick 25dda28197Spatrick #include "Plugins/ExpressionParser/Clang/ClangASTImporter.h" 26dda28197Spatrick #include "Plugins/TypeSystem/Clang/TypeSystemClang.h" 27061da546Spatrick 28*f6aab3d8Srobert #include <optional> 29061da546Spatrick #include <vector> 30061da546Spatrick 31061da546Spatrick namespace lldb_private { 32061da546Spatrick class CompileUnit; 33061da546Spatrick } 34061da546Spatrick class DWARFDebugInfoEntry; 35061da546Spatrick class SymbolFileDWARF; 36061da546Spatrick 37061da546Spatrick struct ParsedDWARFTypeAttributes; 38061da546Spatrick 39061da546Spatrick class DWARFASTParserClang : public DWARFASTParser { 40061da546Spatrick public: 41dda28197Spatrick DWARFASTParserClang(lldb_private::TypeSystemClang &ast); 42061da546Spatrick 43061da546Spatrick ~DWARFASTParserClang() override; 44061da546Spatrick 45061da546Spatrick // DWARFASTParser interface. 46061da546Spatrick lldb::TypeSP ParseTypeFromDWARF(const lldb_private::SymbolContext &sc, 47061da546Spatrick const DWARFDIE &die, 48061da546Spatrick bool *type_is_new_ptr) override; 49061da546Spatrick 50*f6aab3d8Srobert lldb_private::ConstString 51*f6aab3d8Srobert ConstructDemangledNameFromDWARF(const DWARFDIE &die) override; 52*f6aab3d8Srobert 53061da546Spatrick lldb_private::Function * 54061da546Spatrick ParseFunctionFromDWARF(lldb_private::CompileUnit &comp_unit, 55*f6aab3d8Srobert const DWARFDIE &die, 56*f6aab3d8Srobert const lldb_private::AddressRange &func_range) override; 57061da546Spatrick 58061da546Spatrick bool 59061da546Spatrick CompleteTypeFromDWARF(const DWARFDIE &die, lldb_private::Type *type, 60061da546Spatrick lldb_private::CompilerType &compiler_type) override; 61061da546Spatrick 62061da546Spatrick lldb_private::CompilerDecl 63061da546Spatrick GetDeclForUIDFromDWARF(const DWARFDIE &die) override; 64061da546Spatrick 65061da546Spatrick void EnsureAllDIEsInDeclContextHaveBeenParsed( 66061da546Spatrick lldb_private::CompilerDeclContext decl_context) override; 67061da546Spatrick 68061da546Spatrick lldb_private::CompilerDeclContext 69061da546Spatrick GetDeclContextForUIDFromDWARF(const DWARFDIE &die) override; 70061da546Spatrick 71061da546Spatrick lldb_private::CompilerDeclContext 72061da546Spatrick GetDeclContextContainingUIDFromDWARF(const DWARFDIE &die) override; 73061da546Spatrick 74061da546Spatrick lldb_private::ClangASTImporter &GetClangASTImporter(); 75061da546Spatrick 76*f6aab3d8Srobert /// Extracts an value for a given Clang integer type from a DWARFFormValue. 77*f6aab3d8Srobert /// 78*f6aab3d8Srobert /// \param int_type The Clang type that defines the bit size and signedness 79*f6aab3d8Srobert /// of the integer that should be extracted. Has to be either 80*f6aab3d8Srobert /// an integer type or an enum type. For enum types the 81*f6aab3d8Srobert /// underlying integer type will be considered as the 82*f6aab3d8Srobert /// expected integer type that should be extracted. 83*f6aab3d8Srobert /// \param form_value The DWARFFormValue that contains the integer value. 84*f6aab3d8Srobert /// \return An APInt containing the same integer value as the given 85*f6aab3d8Srobert /// DWARFFormValue with the bit width of the given integer type. 86*f6aab3d8Srobert /// Returns an error if the value in the DWARFFormValue does not fit 87*f6aab3d8Srobert /// into the given integer type or the integer type isn't supported. 88*f6aab3d8Srobert llvm::Expected<llvm::APInt> 89*f6aab3d8Srobert ExtractIntFromFormValue(const lldb_private::CompilerType &int_type, 90*f6aab3d8Srobert const DWARFFormValue &form_value) const; 91*f6aab3d8Srobert 92*f6aab3d8Srobert /// Returns the template parameters of a class DWARFDIE as a string. 93*f6aab3d8Srobert /// 94*f6aab3d8Srobert /// This is mostly useful for -gsimple-template-names which omits template 95*f6aab3d8Srobert /// parameters from the DIE name and instead always adds template parameter 96*f6aab3d8Srobert /// children DIEs. 97*f6aab3d8Srobert /// 98*f6aab3d8Srobert /// \param die The struct/class DWARFDIE containing template parameters. 99*f6aab3d8Srobert /// \return A string, including surrounding '<>', of the template parameters. 100*f6aab3d8Srobert /// If the DIE's name already has '<>', returns an empty ConstString because 101*f6aab3d8Srobert /// it's assumed that the caller is using the DIE name anyway. 102*f6aab3d8Srobert lldb_private::ConstString 103*f6aab3d8Srobert GetDIEClassTemplateParams(const DWARFDIE &die) override; 104*f6aab3d8Srobert 105061da546Spatrick protected: 106061da546Spatrick /// Protected typedefs and members. 107061da546Spatrick /// @{ 108061da546Spatrick class DelayedAddObjCClassProperty; 109061da546Spatrick typedef std::vector<DelayedAddObjCClassProperty> DelayedPropertyList; 110061da546Spatrick 111061da546Spatrick typedef llvm::DenseMap<const DWARFDebugInfoEntry *, clang::DeclContext *> 112061da546Spatrick DIEToDeclContextMap; 113061da546Spatrick typedef std::multimap<const clang::DeclContext *, const DWARFDIE> 114061da546Spatrick DeclContextToDIEMap; 115dda28197Spatrick typedef llvm::DenseMap<const DWARFDebugInfoEntry *, 116dda28197Spatrick lldb_private::OptionalClangModuleID> 117dda28197Spatrick DIEToModuleMap; 118061da546Spatrick typedef llvm::DenseMap<const DWARFDebugInfoEntry *, clang::Decl *> 119061da546Spatrick DIEToDeclMap; 120061da546Spatrick 121dda28197Spatrick lldb_private::TypeSystemClang &m_ast; 122061da546Spatrick DIEToDeclMap m_die_to_decl; 123061da546Spatrick DIEToDeclContextMap m_die_to_decl_ctx; 124061da546Spatrick DeclContextToDIEMap m_decl_ctx_to_die; 125dda28197Spatrick DIEToModuleMap m_die_to_module; 126061da546Spatrick std::unique_ptr<lldb_private::ClangASTImporter> m_clang_ast_importer_up; 127061da546Spatrick /// @} 128061da546Spatrick 129061da546Spatrick clang::DeclContext *GetDeclContextForBlock(const DWARFDIE &die); 130061da546Spatrick 131061da546Spatrick clang::BlockDecl *ResolveBlockDIE(const DWARFDIE &die); 132061da546Spatrick 133061da546Spatrick clang::NamespaceDecl *ResolveNamespaceDIE(const DWARFDIE &die); 134061da546Spatrick 135061da546Spatrick bool ParseTemplateDIE(const DWARFDIE &die, 136dda28197Spatrick lldb_private::TypeSystemClang::TemplateParameterInfos 137061da546Spatrick &template_param_infos); 138*f6aab3d8Srobert 139061da546Spatrick bool ParseTemplateParameterInfos( 140061da546Spatrick const DWARFDIE &parent_die, 141dda28197Spatrick lldb_private::TypeSystemClang::TemplateParameterInfos 142061da546Spatrick &template_param_infos); 143061da546Spatrick 144*f6aab3d8Srobert std::string GetCPlusPlusQualifiedName(const DWARFDIE &die); 145*f6aab3d8Srobert 146061da546Spatrick bool ParseChildMembers( 147061da546Spatrick const DWARFDIE &die, lldb_private::CompilerType &class_compiler_type, 148061da546Spatrick std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> &base_classes, 149061da546Spatrick std::vector<DWARFDIE> &member_function_dies, 150061da546Spatrick DelayedPropertyList &delayed_properties, 151*f6aab3d8Srobert const lldb::AccessType default_accessibility, 152061da546Spatrick lldb_private::ClangASTImporter::LayoutInfo &layout_info); 153061da546Spatrick 154061da546Spatrick size_t 155061da546Spatrick ParseChildParameters(clang::DeclContext *containing_decl_ctx, 156061da546Spatrick const DWARFDIE &parent_die, bool skip_artificial, 157061da546Spatrick bool &is_static, bool &is_variadic, 158061da546Spatrick bool &has_template_params, 159061da546Spatrick std::vector<lldb_private::CompilerType> &function_args, 160061da546Spatrick std::vector<clang::ParmVarDecl *> &function_param_decls, 161061da546Spatrick unsigned &type_quals); 162061da546Spatrick 163061da546Spatrick size_t ParseChildEnumerators(lldb_private::CompilerType &compiler_type, 164061da546Spatrick bool is_signed, uint32_t enumerator_byte_size, 165061da546Spatrick const DWARFDIE &parent_die); 166061da546Spatrick 167061da546Spatrick /// Parse a structure, class, or union type DIE. 168061da546Spatrick lldb::TypeSP ParseStructureLikeDIE(const lldb_private::SymbolContext &sc, 169061da546Spatrick const DWARFDIE &die, 170061da546Spatrick ParsedDWARFTypeAttributes &attrs); 171061da546Spatrick 172061da546Spatrick lldb_private::Type *GetTypeForDIE(const DWARFDIE &die); 173061da546Spatrick 174061da546Spatrick clang::Decl *GetClangDeclForDIE(const DWARFDIE &die); 175061da546Spatrick 176061da546Spatrick clang::DeclContext *GetClangDeclContextForDIE(const DWARFDIE &die); 177061da546Spatrick 178061da546Spatrick clang::DeclContext *GetClangDeclContextContainingDIE(const DWARFDIE &die, 179061da546Spatrick DWARFDIE *decl_ctx_die); 180dda28197Spatrick lldb_private::OptionalClangModuleID GetOwningClangModule(const DWARFDIE &die); 181061da546Spatrick 182061da546Spatrick bool CopyUniqueClassMethodTypes(const DWARFDIE &src_class_die, 183061da546Spatrick const DWARFDIE &dst_class_die, 184061da546Spatrick lldb_private::Type *class_type, 185061da546Spatrick std::vector<DWARFDIE> &failures); 186061da546Spatrick 187061da546Spatrick clang::DeclContext *GetCachedClangDeclContextForDIE(const DWARFDIE &die); 188061da546Spatrick 189061da546Spatrick void LinkDeclContextToDIE(clang::DeclContext *decl_ctx, const DWARFDIE &die); 190061da546Spatrick 191061da546Spatrick void LinkDeclToDIE(clang::Decl *decl, const DWARFDIE &die); 192061da546Spatrick 193061da546Spatrick /// If \p type_sp is valid, calculate and set its symbol context scope, and 194061da546Spatrick /// update the type list for its backing symbol file. 195061da546Spatrick /// 196061da546Spatrick /// Returns \p type_sp. 197061da546Spatrick lldb::TypeSP 198061da546Spatrick UpdateSymbolContextScopeForType(const lldb_private::SymbolContext &sc, 199061da546Spatrick const DWARFDIE &die, lldb::TypeSP type_sp); 200061da546Spatrick 201061da546Spatrick /// Follow Clang Module Skeleton CU references to find a type definition. 202061da546Spatrick lldb::TypeSP ParseTypeFromClangModule(const lldb_private::SymbolContext &sc, 203061da546Spatrick const DWARFDIE &die, 204061da546Spatrick lldb_private::Log *log); 205061da546Spatrick 206061da546Spatrick // Return true if this type is a declaration to a type in an external 207061da546Spatrick // module. 208061da546Spatrick lldb::ModuleSP GetModuleForType(const DWARFDIE &die); 209061da546Spatrick 210061da546Spatrick private: 211061da546Spatrick struct FieldInfo { 212061da546Spatrick uint64_t bit_size = 0; 213061da546Spatrick uint64_t bit_offset = 0; 214061da546Spatrick bool is_bitfield = false; 215061da546Spatrick 216061da546Spatrick FieldInfo() = default; 217061da546Spatrick SetIsBitfieldFieldInfo218061da546Spatrick void SetIsBitfield(bool flag) { is_bitfield = flag; } IsBitfieldFieldInfo219061da546Spatrick bool IsBitfield() { return is_bitfield; } 220061da546Spatrick NextBitfieldOffsetIsValidFieldInfo221061da546Spatrick bool NextBitfieldOffsetIsValid(const uint64_t next_bit_offset) const { 222061da546Spatrick // Any subsequent bitfields must not overlap and must be at a higher 223061da546Spatrick // bit offset than any previous bitfield + size. 224061da546Spatrick return (bit_size + bit_offset) <= next_bit_offset; 225061da546Spatrick } 226061da546Spatrick }; 227061da546Spatrick 228*f6aab3d8Srobert /// Parses a DW_TAG_APPLE_property DIE and appends the parsed data to the 229*f6aab3d8Srobert /// list of delayed Objective-C properties. 230*f6aab3d8Srobert /// 231*f6aab3d8Srobert /// Note: The delayed property needs to be finalized to actually create the 232*f6aab3d8Srobert /// property declarations in the module AST. 233*f6aab3d8Srobert /// 234*f6aab3d8Srobert /// \param die The DW_TAG_APPLE_property DIE that will be parsed. 235*f6aab3d8Srobert /// \param parent_die The parent DIE. 236*f6aab3d8Srobert /// \param class_clang_type The Objective-C class that will contain the 237*f6aab3d8Srobert /// created property. 238*f6aab3d8Srobert /// \param delayed_properties The list of delayed properties that the result 239*f6aab3d8Srobert /// will be appended to. 240*f6aab3d8Srobert void ParseObjCProperty(const DWARFDIE &die, const DWARFDIE &parent_die, 241*f6aab3d8Srobert const lldb_private::CompilerType &class_clang_type, 242*f6aab3d8Srobert DelayedPropertyList &delayed_properties); 243*f6aab3d8Srobert 244061da546Spatrick void 245061da546Spatrick ParseSingleMember(const DWARFDIE &die, const DWARFDIE &parent_die, 246dda28197Spatrick const lldb_private::CompilerType &class_clang_type, 247dda28197Spatrick lldb::AccessType default_accessibility, 248061da546Spatrick lldb_private::ClangASTImporter::LayoutInfo &layout_info, 249061da546Spatrick FieldInfo &last_field_info); 250061da546Spatrick 251061da546Spatrick bool CompleteRecordType(const DWARFDIE &die, lldb_private::Type *type, 252061da546Spatrick lldb_private::CompilerType &clang_type); 253061da546Spatrick bool CompleteEnumType(const DWARFDIE &die, lldb_private::Type *type, 254061da546Spatrick lldb_private::CompilerType &clang_type); 255061da546Spatrick 256061da546Spatrick lldb::TypeSP ParseTypeModifier(const lldb_private::SymbolContext &sc, 257061da546Spatrick const DWARFDIE &die, 258061da546Spatrick ParsedDWARFTypeAttributes &attrs); 259061da546Spatrick lldb::TypeSP ParseEnum(const lldb_private::SymbolContext &sc, 260061da546Spatrick const DWARFDIE &die, ParsedDWARFTypeAttributes &attrs); 261061da546Spatrick lldb::TypeSP ParseSubroutine(const DWARFDIE &die, 262061da546Spatrick ParsedDWARFTypeAttributes &attrs); 263061da546Spatrick lldb::TypeSP ParseArrayType(const DWARFDIE &die, 264*f6aab3d8Srobert const ParsedDWARFTypeAttributes &attrs); 265061da546Spatrick lldb::TypeSP ParsePointerToMemberType(const DWARFDIE &die, 266061da546Spatrick const ParsedDWARFTypeAttributes &attrs); 267*f6aab3d8Srobert 268*f6aab3d8Srobert /// Parses a DW_TAG_inheritance DIE into a base/super class. 269*f6aab3d8Srobert /// 270*f6aab3d8Srobert /// \param die The DW_TAG_inheritance DIE to parse. 271*f6aab3d8Srobert /// \param parent_die The parent DIE of the given DIE. 272*f6aab3d8Srobert /// \param class_clang_type The C++/Objective-C class representing parent_die. 273*f6aab3d8Srobert /// For an Objective-C class this method sets the super class on success. For 274*f6aab3d8Srobert /// a C++ class this will *not* add the result as a base class. 275*f6aab3d8Srobert /// \param default_accessibility The default accessibility that is given to 276*f6aab3d8Srobert /// base classes if they don't have an explicit accessibility set. 277*f6aab3d8Srobert /// \param module_sp The current Module. 278*f6aab3d8Srobert /// \param base_classes The list of C++ base classes that will be appended 279*f6aab3d8Srobert /// with the parsed base class on success. 280*f6aab3d8Srobert /// \param layout_info The layout information that will be updated for C++ 281*f6aab3d8Srobert /// base classes with the base offset. 282*f6aab3d8Srobert void ParseInheritance( 283*f6aab3d8Srobert const DWARFDIE &die, const DWARFDIE &parent_die, 284*f6aab3d8Srobert const lldb_private::CompilerType class_clang_type, 285*f6aab3d8Srobert const lldb::AccessType default_accessibility, 286*f6aab3d8Srobert const lldb::ModuleSP &module_sp, 287*f6aab3d8Srobert std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> &base_classes, 288*f6aab3d8Srobert lldb_private::ClangASTImporter::LayoutInfo &layout_info); 289061da546Spatrick }; 290061da546Spatrick 291061da546Spatrick /// Parsed form of all attributes that are relevant for type reconstruction. 292061da546Spatrick /// Some attributes are relevant for all kinds of types (declaration), while 293061da546Spatrick /// others are only meaningful to a specific type (is_virtual) 294061da546Spatrick struct ParsedDWARFTypeAttributes { 295061da546Spatrick explicit ParsedDWARFTypeAttributes(const DWARFDIE &die); 296061da546Spatrick 297061da546Spatrick lldb::AccessType accessibility = lldb::eAccessNone; 298061da546Spatrick bool is_artificial = false; 299061da546Spatrick bool is_complete_objc_class = false; 300061da546Spatrick bool is_explicit = false; 301061da546Spatrick bool is_forward_declaration = false; 302061da546Spatrick bool is_inline = false; 303061da546Spatrick bool is_scoped_enum = false; 304061da546Spatrick bool is_vector = false; 305061da546Spatrick bool is_virtual = false; 306061da546Spatrick bool is_objc_direct_call = false; 307061da546Spatrick bool exports_symbols = false; 308061da546Spatrick clang::StorageClass storage = clang::SC_None; 309061da546Spatrick const char *mangled_name = nullptr; 310061da546Spatrick lldb_private::ConstString name; 311061da546Spatrick lldb_private::Declaration decl; 312061da546Spatrick DWARFDIE object_pointer; 313061da546Spatrick DWARFFormValue abstract_origin; 314061da546Spatrick DWARFFormValue containing_type; 315061da546Spatrick DWARFFormValue signature; 316061da546Spatrick DWARFFormValue specification; 317061da546Spatrick DWARFFormValue type; 318061da546Spatrick lldb::LanguageType class_language = lldb::eLanguageTypeUnknown; 319*f6aab3d8Srobert std::optional<uint64_t> byte_size; 320061da546Spatrick size_t calling_convention = llvm::dwarf::DW_CC_normal; 321061da546Spatrick uint32_t bit_stride = 0; 322061da546Spatrick uint32_t byte_stride = 0; 323061da546Spatrick uint32_t encoding = 0; 324*f6aab3d8Srobert clang::RefQualifierKind ref_qual = 325*f6aab3d8Srobert clang::RQ_None; ///< Indicates ref-qualifier of 326*f6aab3d8Srobert ///< C++ member function if present. 327*f6aab3d8Srobert ///< Is RQ_None otherwise. 328061da546Spatrick }; 329061da546Spatrick 330dda28197Spatrick #endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFASTPARSERCLANG_H 331