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