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