1 //===-- CompileUnit.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_SYMBOL_COMPILEUNIT_H
10 #define LLDB_SYMBOL_COMPILEUNIT_H
11 
12 #include "lldb/Core/ModuleChild.h"
13 #include "lldb/Core/SourceLocationSpec.h"
14 #include "lldb/Symbol/DebugMacros.h"
15 #include "lldb/Symbol/Function.h"
16 #include "lldb/Symbol/LineTable.h"
17 #include "lldb/Symbol/SourceModule.h"
18 #include "lldb/Utility/FileSpecList.h"
19 #include "lldb/Utility/Stream.h"
20 #include "lldb/Utility/UserID.h"
21 #include "lldb/lldb-enumerations.h"
22 
23 #include "llvm/ADT/DenseMap.h"
24 #include "llvm/ADT/DenseSet.h"
25 
26 namespace lldb_private {
27 /// \class CompileUnit CompileUnit.h "lldb/Symbol/CompileUnit.h"
28 /// A class that describes a compilation unit.
29 ///
30 /// A representation of a compilation unit, or compiled source file.
31 /// The UserID of the compile unit is specified by the SymbolFile plug-in and
32 /// can have any value as long as the value is unique within the Module that
33 /// owns this compile units.
34 ///
35 /// Each compile unit has a list of functions, global and static variables,
36 /// support file list (include files and inlined source files), and a line
37 /// table.
38 class CompileUnit : public std::enable_shared_from_this<CompileUnit>,
39                     public ModuleChild,
40                     public UserID,
41                     public SymbolContextScope {
42 public:
43   /// Construct with a module, path, UID and language.
44   ///
45   /// Initialize the compile unit given the owning \a module, a path to
46   /// convert into a FileSpec, the SymbolFile plug-in supplied \a uid, and the
47   /// source language type.
48   ///
49   /// \param[in] module_sp
50   ///     The parent module that owns this compile unit. This value
51   ///     must be a valid pointer value.
52   ///
53   /// \param[in] user_data
54   ///     User data where the SymbolFile parser can store data.
55   ///
56   /// \param[in] pathname
57   ///     The path to the source file for this compile unit.
58   ///
59   /// \param[in] uid
60   ///     The user ID of the compile unit. This value is supplied by
61   ///     the SymbolFile plug-in and should be a value that allows
62   ///     the SymbolFile plug-in to easily locate and parse additional
63   ///     information for the compile unit.
64   ///
65   /// \param[in] language
66   ///     A language enumeration type that describes the main language
67   ///     of this compile unit.
68   ///
69   /// \param[in] is_optimized
70   ///     A value that can initialized with eLazyBoolYes, eLazyBoolNo
71   ///     or eLazyBoolCalculate. If set to eLazyBoolCalculate, then
72   ///     an extra call into SymbolVendor will be made to calculate if
73   ///     the compile unit is optimized will be made when
74   ///     CompileUnit::GetIsOptimized() is called.
75   ///
76   /// \see lldb::LanguageType
77   CompileUnit(const lldb::ModuleSP &module_sp, void *user_data,
78               const char *pathname, lldb::user_id_t uid,
79               lldb::LanguageType language, lldb_private::LazyBool is_optimized);
80 
81   /// Construct with a module, file spec, UID and language.
82   ///
83   /// Initialize the compile unit given the owning \a module, a path to
84   /// convert into a FileSpec, the SymbolFile plug-in supplied \a uid, and the
85   /// source language type.
86   ///
87   /// \param[in] module_sp
88   ///     The parent module that owns this compile unit. This value
89   ///     must be a valid pointer value.
90   ///
91   /// \param[in] user_data
92   ///     User data where the SymbolFile parser can store data.
93   ///
94   /// \param[in] support_file_sp
95   ///     The file specification for the source file of this compile
96   ///     unit.
97   ///
98   /// \param[in] uid
99   ///     The user ID of the compile unit. This value is supplied by
100   ///     the SymbolFile plug-in and should be a value that allows
101   ///     the plug-in to easily locate and parse
102   ///     additional information for the compile unit.
103   ///
104   /// \param[in] language
105   ///     A language enumeration type that describes the main language
106   ///     of this compile unit.
107   ///
108   /// \param[in] is_optimized
109   ///     A value that can initialized with eLazyBoolYes, eLazyBoolNo
110   ///     or eLazyBoolCalculate. If set to eLazyBoolCalculate, then
111   ///     an extra call into SymbolVendor will be made to calculate if
112   ///     the compile unit is optimized will be made when
113   ///     CompileUnit::GetIsOptimized() is called.
114   ///
115   /// \param[in] support_files
116   ///     An rvalue list of already parsed support files.
117   /// \see lldb::LanguageType
118   CompileUnit(const lldb::ModuleSP &module_sp, void *user_data,
119               lldb::SupportFileSP support_file_sp, lldb::user_id_t uid,
120               lldb::LanguageType language, lldb_private::LazyBool is_optimized,
121               SupportFileList &&support_files = {});
122 
123   /// Add a function to this compile unit.
124   ///
125   /// Typically called by the SymbolFile plug-ins as they partially parse the
126   /// debug information.
127   ///
128   /// \param[in] function_sp
129   ///     A shared pointer to the Function object.
130   void AddFunction(lldb::FunctionSP &function_sp);
131 
132   /// \copydoc SymbolContextScope::CalculateSymbolContext(SymbolContext*)
133   ///
134   /// \see SymbolContextScope
135   void CalculateSymbolContext(SymbolContext *sc) override;
136 
137   lldb::ModuleSP CalculateSymbolContextModule() override;
138 
139   CompileUnit *CalculateSymbolContextCompileUnit() override;
140 
141   /// \copydoc SymbolContextScope::DumpSymbolContext(Stream*)
142   ///
143   /// \see SymbolContextScope
144   void DumpSymbolContext(Stream *s) override;
145 
146   lldb::LanguageType GetLanguage();
147 
SetLanguage(lldb::LanguageType language)148   void SetLanguage(lldb::LanguageType language) {
149     m_flags.Set(flagsParsedLanguage);
150     m_language = language;
151   }
152 
153   void GetDescription(Stream *s, lldb::DescriptionLevel level) const;
154 
155   /// Apply a lambda to each function in this compile unit.
156   ///
157   /// This provides raw access to the function shared pointer list and will not
158   /// cause the SymbolFile plug-in to parse any unparsed functions.
159   ///
160   /// \note Prefer using FindFunctionByUID over this if possible.
161   ///
162   /// \param[in] lambda
163   ///     The lambda that should be applied to every function. The lambda can
164   ///     return true if the iteration should be aborted earlier.
165   void ForeachFunction(
166       llvm::function_ref<bool(const lldb::FunctionSP &)> lambda) const;
167 
168   /// Find a function in the compile unit based on the predicate matching_lambda
169   ///
170   /// \param[in] matching_lambda
171   ///     A predicate that will be used within FindFunction to evaluate each
172   ///     FunctionSP in m_functions_by_uid. When the predicate returns true
173   ///     FindFunction will return the corresponding FunctionSP.
174   ///
175   /// \return
176   ///   The first FunctionSP that the matching_lambda prediate returns true for.
177   lldb::FunctionSP FindFunction(
178       llvm::function_ref<bool(const lldb::FunctionSP &)> matching_lambda);
179 
180   /// Dump the compile unit contents to the stream \a s.
181   ///
182   /// \param[in] s
183   ///     The stream to which to dump the object description.
184   ///
185   /// \param[in] show_context
186   ///     If \b true, variables will dump their symbol context
187   ///     information.
188   void Dump(Stream *s, bool show_context) const;
189 
190   /// Find the line entry by line and optional inlined file spec.
191   ///
192   /// Finds the first line entry that has an index greater than \a start_idx
193   /// that matches \a line. If \a file_spec_ptr is NULL, then the search
194   /// matches line entries whose file matches the file for the compile unit.
195   /// If \a file_spec_ptr is not NULL, line entries must match the specified
196   /// file spec (for inlined line table entries).
197   ///
198   /// Multiple calls to this function can find all entries that match a given
199   /// file and line by starting with \a start_idx equal to zero, and calling
200   /// this function back with the return value + 1.
201   ///
202   /// \param[in] start_idx
203   ///     The zero based index at which to start looking for matches.
204   ///
205   /// \param[in] line
206   ///     The line number to search for.
207   ///
208   /// \param[in] file_spec_ptr
209   ///     If non-NULL search for entries that match this file spec,
210   ///     else if NULL, search for line entries that match the compile
211   ///     unit file.
212   ///
213   /// \param[in] exact
214   ///     If \b true match only if there is a line table entry for this line
215   ///     number.
216   ///     If \b false, find the line table entry equal to or after this line
217   ///     number.
218   ///
219   /// \param[out] line_entry
220   ///     If non-NULL, a copy of the line entry that was found.
221   ///
222   /// \return
223   ///     The zero based index of a matching line entry, or UINT32_MAX
224   ///     if no matching line entry is found.
225   uint32_t FindLineEntry(uint32_t start_idx, uint32_t line,
226                          const FileSpec *file_spec_ptr, bool exact,
227                          LineEntry *line_entry);
228 
229   /// Return the primary source spec associated with this compile unit.
GetPrimaryFile()230   const FileSpec &GetPrimaryFile() const {
231     return m_primary_support_file_sp->GetSpecOnly();
232   }
233 
234   /// Return the primary source file associated with this compile unit.
GetPrimarySupportFile()235   lldb::SupportFileSP GetPrimarySupportFile() const {
236     return m_primary_support_file_sp;
237   }
238 
239   /// Get the line table for the compile unit.
240   ///
241   /// Called by clients and the SymbolFile plug-in. The SymbolFile plug-ins
242   /// use this function to determine if the line table has be parsed yet.
243   /// Clients use this function to get the line table from a compile unit.
244   ///
245   /// \return
246   ///     The line table object pointer, or NULL if this line table
247   ///     hasn't been parsed yet.
248   LineTable *GetLineTable();
249 
250   DebugMacros *GetDebugMacros();
251 
252   /// Apply a lambda to each external lldb::Module referenced by this
253   /// compilation unit. Recursively also descends into the referenced external
254   /// modules of any encountered compilation unit.
255   ///
256   /// \param visited_symbol_files
257   ///     A set of SymbolFiles that were already visited to avoid
258   ///     visiting one file more than once.
259   ///
260   /// \param[in] lambda
261   ///     The lambda that should be applied to every function. The lambda can
262   ///     return true if the iteration should be aborted earlier.
263   ///
264   /// \return
265   ///     If the lambda early-exited, this function returns true to
266   ///     propagate the early exit.
267   virtual bool ForEachExternalModule(
268       llvm::DenseSet<lldb_private::SymbolFile *> &visited_symbol_files,
269       llvm::function_ref<bool(Module &)> lambda);
270 
271   /// Get the compile unit's support file list.
272   ///
273   /// The support file list is used by the line table, and any objects that
274   /// have valid Declaration objects.
275   ///
276   /// \return
277   ///     A support file list object.
278   const SupportFileList &GetSupportFiles();
279 
280   /// Used by plugins that parse the support file list.
GetSupportFileList()281   SupportFileList &GetSupportFileList() {
282     m_flags.Set(flagsParsedSupportFiles);
283     return m_support_files;
284   }
285 
286   /// Get the compile unit's imported module list.
287   ///
288   /// This reports all the imports that the compile unit made, including the
289   /// current module.
290   ///
291   /// \return
292   ///     A list of imported modules.
293   const std::vector<SourceModule> &GetImportedModules();
294 
295   /// Get the SymbolFile plug-in user data.
296   ///
297   /// SymbolFile plug-ins can store user data to internal state or objects to
298   /// quickly allow them to parse more information for a given object.
299   ///
300   /// \return
301   ///     The user data stored with the CompileUnit when it was
302   ///     constructed.
303   void *GetUserData() const;
304 
305   /// Get the variable list for a compile unit.
306   ///
307   /// Called by clients to get the variable list for a compile unit. The
308   /// variable list will contain all global and static variables that were
309   /// defined at the compile unit level.
310   ///
311   /// \param[in] can_create
312   ///     If \b true, the variable list will be parsed on demand. If
313   ///     \b false, the current variable list will be returned even
314   ///     if it contains a NULL VariableList object (typically
315   ///     called by dumping routines that want to display only what
316   ///     has currently been parsed).
317   ///
318   /// \return
319   ///     A shared pointer to a variable list, that can contain NULL
320   ///     VariableList pointer if there are no global or static
321   ///     variables.
322   lldb::VariableListSP GetVariableList(bool can_create);
323 
324   /// Finds a function by user ID.
325   ///
326   /// Typically used by SymbolFile plug-ins when partially parsing the debug
327   /// information to see if the function has been parsed yet.
328   ///
329   /// \param[in] uid
330   ///     The user ID of the function to find. This value is supplied
331   ///     by the SymbolFile plug-in and should be a value that
332   ///     allows the plug-in to easily locate and parse additional
333   ///     information in the function.
334   ///
335   /// \return
336   ///     A shared pointer to the function object that might contain
337   ///     a NULL Function pointer.
338   lldb::FunctionSP FindFunctionByUID(lldb::user_id_t uid);
339 
340   /// Set the line table for the compile unit.
341   ///
342   /// Called by the SymbolFile plug-in when if first parses the line table and
343   /// hands ownership of the line table to this object. The compile unit owns
344   /// the line table object and will delete the object when it is deleted.
345   ///
346   /// \param[in] line_table
347   ///     A line table object pointer that this object now owns.
348   void SetLineTable(LineTable *line_table);
349 
350   void SetDebugMacros(const DebugMacrosSP &debug_macros);
351 
352   /// Set accessor for the variable list.
353   ///
354   /// Called by the SymbolFile plug-ins after they have parsed the variable
355   /// lists and are ready to hand ownership of the list over to this object.
356   ///
357   /// \param[in] variable_list_sp
358   ///     A shared pointer to a VariableList.
359   void SetVariableList(lldb::VariableListSP &variable_list_sp);
360 
361   /// Resolve symbol contexts by file and line.
362   ///
363   /// Given a file in \a src_location_spec, find all instances and
364   /// append them to the supplied symbol context list \a sc_list.
365   ///
366   /// \param[in] src_location_spec
367   ///     The \a src_location_spec containing the \a file_spec, the line and the
368   ///     column of the symbol to look for. Also hold the inlines and
369   ///     exact_match flags.
370   ///
371   ///     If check_inlines is \b true, this function will also match any inline
372   ///     file and line matches. If \b false, the compile unit's
373   ///     file specification must match \a file_spec for any matches
374   ///     to be returned.
375   ///
376   ///     If exact_match is \b true, only resolve the context if \a line and \a
377   ///     column exists in the line table. If \b false, resolve the context to
378   ///     the closest line greater than \a line in the line table.
379   ///
380   /// \param[in] resolve_scope
381   ///     For each matching line entry, this bitfield indicates what
382   ///     values within each SymbolContext that gets added to \a
383   ///     sc_list will be resolved. See the SymbolContext::Scope
384   ///     enumeration for a list of all available bits that can be
385   ///     resolved. Only SymbolContext entries that can be resolved
386   ///     using a LineEntry base address will be able to be resolved.
387   ///
388   /// \param[out] sc_list
389   ///     A SymbolContext list class that will get any matching
390   ///     entries appended to.
391   ///
392   /// \see enum SymbolContext::Scope
393   void ResolveSymbolContext(const SourceLocationSpec &src_location_spec,
394                             lldb::SymbolContextItem resolve_scope,
395                             SymbolContextList &sc_list);
396 
397   /// Get whether compiler optimizations were enabled for this compile unit
398   ///
399   /// "optimized" means that the debug experience may be difficult for the
400   /// user to understand.  Variables may not be available when the developer
401   /// would expect them, stepping through the source lines in the function may
402   /// appear strange, etc.
403   ///
404   /// \return
405   ///     Returns 'true' if this compile unit was compiled with
406   ///     optimization.  'false' indicates that either the optimization
407   ///     is unknown, or this compile unit was built without optimization.
408   bool GetIsOptimized();
409 
410   /// Returns the number of functions in this compile unit
GetNumFunctions()411   size_t GetNumFunctions() const { return m_functions_by_uid.size(); }
412 
413 protected:
414   /// User data for the SymbolFile parser to store information into.
415   void *m_user_data;
416   /// The programming language enumeration value.
417   lldb::LanguageType m_language;
418   /// Compile unit flags that help with partial parsing.
419   Flags m_flags;
420   /// Maps UIDs to functions.
421   llvm::DenseMap<lldb::user_id_t, lldb::FunctionSP> m_functions_by_uid;
422   /// All modules, including the current module, imported by this
423   /// compile unit.
424   std::vector<SourceModule> m_imported_modules;
425   /// The primary file associated with this compile unit.
426   lldb::SupportFileSP m_primary_support_file_sp;
427   /// Files associated with this compile unit's line table and declarations.
428   SupportFileList m_support_files;
429   /// Line table that will get parsed on demand.
430   std::unique_ptr<LineTable> m_line_table_up;
431   /// Debug macros that will get parsed on demand.
432   DebugMacrosSP m_debug_macros_sp;
433   /// Global and static variable list that will get parsed on demand.
434   lldb::VariableListSP m_variables;
435   /// eLazyBoolYes if this compile unit was compiled with
436   /// optimization.
437   lldb_private::LazyBool m_is_optimized;
438 
439 private:
440   enum {
441     flagsParsedAllFunctions =
442         (1u << 0), ///< Have we already parsed all our functions
443     flagsParsedVariables =
444         (1u << 1), ///< Have we already parsed globals and statics?
445     flagsParsedSupportFiles = (1u << 2), ///< Have we already parsed the support
446                                          ///files for this compile unit?
447     flagsParsedLineTable =
448         (1u << 3),                   ///< Have we parsed the line table already?
449     flagsParsedLanguage = (1u << 4), ///< Have we parsed the language already?
450     flagsParsedImportedModules =
451         (1u << 5), ///< Have we parsed the imported modules already?
452     flagsParsedDebugMacros =
453         (1u << 6) ///< Have we parsed the debug macros already?
454   };
455 
456   CompileUnit(const CompileUnit &) = delete;
457   const CompileUnit &operator=(const CompileUnit &) = delete;
458   const char *GetCachedLanguage() const;
459 };
460 
461 } // namespace lldb_private
462 
463 #endif // LLDB_SYMBOL_COMPILEUNIT_H
464