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