1 //===-- DWARFASTParserClang.h -----------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFASTPARSERCLANG_H
10 #define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFASTPARSERCLANG_H
11 
12 #include "clang/AST/CharUnits.h"
13 #include "llvm/ADT/DenseMap.h"
14 #include "llvm/ADT/SmallPtrSet.h"
15 #include "llvm/ADT/SmallVector.h"
16 
17 #include "DWARFASTParser.h"
18 #include "DWARFDIE.h"
19 #include "DWARFDefines.h"
20 #include "DWARFFormValue.h"
21 #include "LogChannelDWARF.h"
22 #include "lldb/Core/PluginInterface.h"
23 
24 #include "Plugins/ExpressionParser/Clang/ClangASTImporter.h"
25 #include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
26 
27 #include <vector>
28 
29 namespace lldb_private {
30 class CompileUnit;
31 }
32 class DWARFDebugInfoEntry;
33 class SymbolFileDWARF;
34 
35 struct ParsedDWARFTypeAttributes;
36 
37 class DWARFASTParserClang : public DWARFASTParser {
38 public:
39   DWARFASTParserClang(lldb_private::TypeSystemClang &ast);
40 
41   ~DWARFASTParserClang() override;
42 
43   // DWARFASTParser interface.
44   lldb::TypeSP ParseTypeFromDWARF(const lldb_private::SymbolContext &sc,
45                                   const DWARFDIE &die,
46                                   bool *type_is_new_ptr) override;
47 
48   lldb_private::Function *
49   ParseFunctionFromDWARF(lldb_private::CompileUnit &comp_unit,
50                          const DWARFDIE &die,
51                          const lldb_private::AddressRange &func_range) override;
52 
53   bool
54   CompleteTypeFromDWARF(const DWARFDIE &die, lldb_private::Type *type,
55                         lldb_private::CompilerType &compiler_type) override;
56 
57   lldb_private::CompilerDecl
58   GetDeclForUIDFromDWARF(const DWARFDIE &die) override;
59 
60   void EnsureAllDIEsInDeclContextHaveBeenParsed(
61       lldb_private::CompilerDeclContext decl_context) override;
62 
63   lldb_private::CompilerDeclContext
64   GetDeclContextForUIDFromDWARF(const DWARFDIE &die) override;
65 
66   lldb_private::CompilerDeclContext
67   GetDeclContextContainingUIDFromDWARF(const DWARFDIE &die) override;
68 
69   lldb_private::ClangASTImporter &GetClangASTImporter();
70 
71   /// Extracts an value for a given Clang integer type from a DWARFFormValue.
72   ///
73   /// \param int_type The Clang type that defines the bit size and signedness
74   ///                 of the integer that should be extracted. Has to be either
75   ///                 an integer type or an enum type. For enum types the
76   ///                 underlying integer type will be considered as the
77   ///                 expected integer type that should be extracted.
78   /// \param form_value The DWARFFormValue that contains the integer value.
79   /// \return An APInt containing the same integer value as the given
80   ///         DWARFFormValue with the bit width of the given integer type.
81   ///         Returns an error if the value in the DWARFFormValue does not fit
82   ///         into the given integer type or the integer type isn't supported.
83   llvm::Expected<llvm::APInt>
84   ExtractIntFromFormValue(const lldb_private::CompilerType &int_type,
85                           const DWARFFormValue &form_value) const;
86 
87 protected:
88   /// Protected typedefs and members.
89   /// @{
90   class DelayedAddObjCClassProperty;
91   typedef std::vector<DelayedAddObjCClassProperty> DelayedPropertyList;
92 
93   typedef llvm::DenseMap<const DWARFDebugInfoEntry *, clang::DeclContext *>
94       DIEToDeclContextMap;
95   typedef std::multimap<const clang::DeclContext *, const DWARFDIE>
96       DeclContextToDIEMap;
97   typedef llvm::DenseMap<const DWARFDebugInfoEntry *,
98                          lldb_private::OptionalClangModuleID>
99       DIEToModuleMap;
100   typedef llvm::DenseMap<const DWARFDebugInfoEntry *, clang::Decl *>
101       DIEToDeclMap;
102 
103   lldb_private::TypeSystemClang &m_ast;
104   DIEToDeclMap m_die_to_decl;
105   DIEToDeclContextMap m_die_to_decl_ctx;
106   DeclContextToDIEMap m_decl_ctx_to_die;
107   DIEToModuleMap m_die_to_module;
108   std::unique_ptr<lldb_private::ClangASTImporter> m_clang_ast_importer_up;
109   /// @}
110 
111   clang::DeclContext *GetDeclContextForBlock(const DWARFDIE &die);
112 
113   clang::BlockDecl *ResolveBlockDIE(const DWARFDIE &die);
114 
115   clang::NamespaceDecl *ResolveNamespaceDIE(const DWARFDIE &die);
116 
117   bool ParseTemplateDIE(const DWARFDIE &die,
118                         lldb_private::TypeSystemClang::TemplateParameterInfos
119                             &template_param_infos);
120   bool ParseTemplateParameterInfos(
121       const DWARFDIE &parent_die,
122       lldb_private::TypeSystemClang::TemplateParameterInfos
123           &template_param_infos);
124 
125   bool ParseChildMembers(
126       const DWARFDIE &die, lldb_private::CompilerType &class_compiler_type,
127       std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> &base_classes,
128       std::vector<DWARFDIE> &member_function_dies,
129       DelayedPropertyList &delayed_properties,
130       const lldb::AccessType default_accessibility,
131       lldb_private::ClangASTImporter::LayoutInfo &layout_info);
132 
133   size_t
134   ParseChildParameters(clang::DeclContext *containing_decl_ctx,
135                        const DWARFDIE &parent_die, bool skip_artificial,
136                        bool &is_static, bool &is_variadic,
137                        bool &has_template_params,
138                        std::vector<lldb_private::CompilerType> &function_args,
139                        std::vector<clang::ParmVarDecl *> &function_param_decls,
140                        unsigned &type_quals);
141 
142   size_t ParseChildEnumerators(lldb_private::CompilerType &compiler_type,
143                                bool is_signed, uint32_t enumerator_byte_size,
144                                const DWARFDIE &parent_die);
145 
146   /// Parse a structure, class, or union type DIE.
147   lldb::TypeSP ParseStructureLikeDIE(const lldb_private::SymbolContext &sc,
148                                      const DWARFDIE &die,
149                                      ParsedDWARFTypeAttributes &attrs);
150 
151   lldb_private::Type *GetTypeForDIE(const DWARFDIE &die);
152 
153   clang::Decl *GetClangDeclForDIE(const DWARFDIE &die);
154 
155   clang::DeclContext *GetClangDeclContextForDIE(const DWARFDIE &die);
156 
157   clang::DeclContext *GetClangDeclContextContainingDIE(const DWARFDIE &die,
158                                                        DWARFDIE *decl_ctx_die);
159   lldb_private::OptionalClangModuleID GetOwningClangModule(const DWARFDIE &die);
160 
161   bool CopyUniqueClassMethodTypes(const DWARFDIE &src_class_die,
162                                   const DWARFDIE &dst_class_die,
163                                   lldb_private::Type *class_type,
164                                   std::vector<DWARFDIE> &failures);
165 
166   clang::DeclContext *GetCachedClangDeclContextForDIE(const DWARFDIE &die);
167 
168   void LinkDeclContextToDIE(clang::DeclContext *decl_ctx, const DWARFDIE &die);
169 
170   void LinkDeclToDIE(clang::Decl *decl, const DWARFDIE &die);
171 
172   /// If \p type_sp is valid, calculate and set its symbol context scope, and
173   /// update the type list for its backing symbol file.
174   ///
175   /// Returns \p type_sp.
176   lldb::TypeSP
177   UpdateSymbolContextScopeForType(const lldb_private::SymbolContext &sc,
178                                   const DWARFDIE &die, lldb::TypeSP type_sp);
179 
180   /// Follow Clang Module Skeleton CU references to find a type definition.
181   lldb::TypeSP ParseTypeFromClangModule(const lldb_private::SymbolContext &sc,
182                                         const DWARFDIE &die,
183                                         lldb_private::Log *log);
184 
185   // Return true if this type is a declaration to a type in an external
186   // module.
187   lldb::ModuleSP GetModuleForType(const DWARFDIE &die);
188 
189 private:
190   struct FieldInfo {
191     uint64_t bit_size = 0;
192     uint64_t bit_offset = 0;
193     bool is_bitfield = false;
194 
195     FieldInfo() = default;
196 
197     void SetIsBitfield(bool flag) { is_bitfield = flag; }
198     bool IsBitfield() { return is_bitfield; }
199 
200     bool NextBitfieldOffsetIsValid(const uint64_t next_bit_offset) const {
201       // Any subsequent bitfields must not overlap and must be at a higher
202       // bit offset than any previous bitfield + size.
203       return (bit_size + bit_offset) <= next_bit_offset;
204     }
205   };
206 
207   /// Parses a DW_TAG_APPLE_property DIE and appends the parsed data to the
208   /// list of delayed Objective-C properties.
209   ///
210   /// Note: The delayed property needs to be finalized to actually create the
211   /// property declarations in the module AST.
212   ///
213   /// \param die The DW_TAG_APPLE_property DIE that will be parsed.
214   /// \param parent_die The parent DIE.
215   /// \param class_clang_type The Objective-C class that will contain the
216   /// created property.
217   /// \param delayed_properties The list of delayed properties that the result
218   /// will be appended to.
219   void ParseObjCProperty(const DWARFDIE &die, const DWARFDIE &parent_die,
220                          const lldb_private::CompilerType &class_clang_type,
221                          DelayedPropertyList &delayed_properties);
222 
223   void
224   ParseSingleMember(const DWARFDIE &die, const DWARFDIE &parent_die,
225                     const lldb_private::CompilerType &class_clang_type,
226                     lldb::AccessType default_accessibility,
227                     lldb_private::ClangASTImporter::LayoutInfo &layout_info,
228                     FieldInfo &last_field_info);
229 
230   bool CompleteRecordType(const DWARFDIE &die, lldb_private::Type *type,
231                           lldb_private::CompilerType &clang_type);
232   bool CompleteEnumType(const DWARFDIE &die, lldb_private::Type *type,
233                         lldb_private::CompilerType &clang_type);
234 
235   lldb::TypeSP ParseTypeModifier(const lldb_private::SymbolContext &sc,
236                                  const DWARFDIE &die,
237                                  ParsedDWARFTypeAttributes &attrs);
238   lldb::TypeSP ParseEnum(const lldb_private::SymbolContext &sc,
239                          const DWARFDIE &die, ParsedDWARFTypeAttributes &attrs);
240   lldb::TypeSP ParseSubroutine(const DWARFDIE &die,
241                                ParsedDWARFTypeAttributes &attrs);
242   // FIXME: attrs should be passed as a const reference.
243   lldb::TypeSP ParseArrayType(const DWARFDIE &die,
244                               ParsedDWARFTypeAttributes &attrs);
245   lldb::TypeSP ParsePointerToMemberType(const DWARFDIE &die,
246                                         const ParsedDWARFTypeAttributes &attrs);
247 
248   /// Parses a DW_TAG_inheritance DIE into a base/super class.
249   ///
250   /// \param die The DW_TAG_inheritance DIE to parse.
251   /// \param parent_die The parent DIE of the given DIE.
252   /// \param class_clang_type The C++/Objective-C class representing parent_die.
253   /// For an Objective-C class this method sets the super class on success. For
254   /// a C++ class this will *not* add the result as a base class.
255   /// \param default_accessibility The default accessibility that is given to
256   /// base classes if they don't have an explicit accessibility set.
257   /// \param module_sp The current Module.
258   /// \param base_classes The list of C++ base classes that will be appended
259   /// with the parsed base class on success.
260   /// \param layout_info The layout information that will be updated for C++
261   /// base classes with the base offset.
262   void ParseInheritance(
263       const DWARFDIE &die, const DWARFDIE &parent_die,
264       const lldb_private::CompilerType class_clang_type,
265       const lldb::AccessType default_accessibility,
266       const lldb::ModuleSP &module_sp,
267       std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> &base_classes,
268       lldb_private::ClangASTImporter::LayoutInfo &layout_info);
269 };
270 
271 /// Parsed form of all attributes that are relevant for type reconstruction.
272 /// Some attributes are relevant for all kinds of types (declaration), while
273 /// others are only meaningful to a specific type (is_virtual)
274 struct ParsedDWARFTypeAttributes {
275   explicit ParsedDWARFTypeAttributes(const DWARFDIE &die);
276 
277   lldb::AccessType accessibility = lldb::eAccessNone;
278   bool is_artificial = false;
279   bool is_complete_objc_class = false;
280   bool is_explicit = false;
281   bool is_forward_declaration = false;
282   bool is_inline = false;
283   bool is_scoped_enum = false;
284   bool is_vector = false;
285   bool is_virtual = false;
286   bool is_objc_direct_call = false;
287   bool exports_symbols = false;
288   clang::StorageClass storage = clang::SC_None;
289   const char *mangled_name = nullptr;
290   lldb_private::ConstString name;
291   lldb_private::Declaration decl;
292   DWARFDIE object_pointer;
293   DWARFFormValue abstract_origin;
294   DWARFFormValue containing_type;
295   DWARFFormValue signature;
296   DWARFFormValue specification;
297   DWARFFormValue type;
298   lldb::LanguageType class_language = lldb::eLanguageTypeUnknown;
299   llvm::Optional<uint64_t> byte_size;
300   size_t calling_convention = llvm::dwarf::DW_CC_normal;
301   uint32_t bit_stride = 0;
302   uint32_t byte_stride = 0;
303   uint32_t encoding = 0;
304 };
305 
306 #endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFASTPARSERCLANG_H
307