1ac7ddfbfSEd Maste //===-- CompileUnit.cpp -----------------------------------------*- C++ -*-===// 2ac7ddfbfSEd Maste // 3ac7ddfbfSEd Maste // The LLVM Compiler Infrastructure 4ac7ddfbfSEd Maste // 5ac7ddfbfSEd Maste // This file is distributed under the University of Illinois Open Source 6ac7ddfbfSEd Maste // License. See LICENSE.TXT for details. 7ac7ddfbfSEd Maste // 8ac7ddfbfSEd Maste //===----------------------------------------------------------------------===// 9ac7ddfbfSEd Maste 10ac7ddfbfSEd Maste #include "lldb/Symbol/CompileUnit.h" 11ac7ddfbfSEd Maste #include "lldb/Core/Module.h" 12ac7ddfbfSEd Maste #include "lldb/Symbol/LineTable.h" 13ac7ddfbfSEd Maste #include "lldb/Symbol/SymbolVendor.h" 14ac7ddfbfSEd Maste #include "lldb/Symbol/VariableList.h" 159f2f44ceSEd Maste #include "lldb/Target/Language.h" 16ac7ddfbfSEd Maste 17ac7ddfbfSEd Maste using namespace lldb; 18ac7ddfbfSEd Maste using namespace lldb_private; 19ac7ddfbfSEd Maste 204bb0738eSEd Maste CompileUnit::CompileUnit(const lldb::ModuleSP &module_sp, void *user_data, const char *pathname, 214bb0738eSEd Maste const lldb::user_id_t cu_sym_id, lldb::LanguageType language, 224bb0738eSEd Maste lldb_private::LazyBool is_optimized) 234bb0738eSEd Maste : ModuleChild(module_sp), 24ac7ddfbfSEd Maste FileSpec(pathname, false), 25ac7ddfbfSEd Maste UserID(cu_sym_id), 26ac7ddfbfSEd Maste m_user_data(user_data), 27ac7ddfbfSEd Maste m_language(language), 28ac7ddfbfSEd Maste m_flags(0), 29ac7ddfbfSEd Maste m_functions(), 30ac7ddfbfSEd Maste m_support_files(), 31ac7ddfbfSEd Maste m_line_table_ap(), 329f2f44ceSEd Maste m_variables(), 339f2f44ceSEd Maste m_is_optimized(is_optimized) 34ac7ddfbfSEd Maste { 35ac7ddfbfSEd Maste if (language != eLanguageTypeUnknown) 36ac7ddfbfSEd Maste m_flags.Set(flagsParsedLanguage); 37ac7ddfbfSEd Maste assert(module_sp); 38ac7ddfbfSEd Maste } 39ac7ddfbfSEd Maste 404bb0738eSEd Maste CompileUnit::CompileUnit(const lldb::ModuleSP &module_sp, void *user_data, const FileSpec &fspec, 414bb0738eSEd Maste const lldb::user_id_t cu_sym_id, lldb::LanguageType language, 424bb0738eSEd Maste lldb_private::LazyBool is_optimized) 434bb0738eSEd Maste : ModuleChild(module_sp), 44ac7ddfbfSEd Maste FileSpec(fspec), 45ac7ddfbfSEd Maste UserID(cu_sym_id), 46ac7ddfbfSEd Maste m_user_data(user_data), 47ac7ddfbfSEd Maste m_language(language), 48ac7ddfbfSEd Maste m_flags(0), 49ac7ddfbfSEd Maste m_functions(), 50ac7ddfbfSEd Maste m_support_files(), 51ac7ddfbfSEd Maste m_line_table_ap(), 529f2f44ceSEd Maste m_variables(), 539f2f44ceSEd Maste m_is_optimized(is_optimized) 54ac7ddfbfSEd Maste { 55ac7ddfbfSEd Maste if (language != eLanguageTypeUnknown) 56ac7ddfbfSEd Maste m_flags.Set(flagsParsedLanguage); 57ac7ddfbfSEd Maste assert(module_sp); 58ac7ddfbfSEd Maste } 59ac7ddfbfSEd Maste 60ac7ddfbfSEd Maste CompileUnit::~CompileUnit () 61ac7ddfbfSEd Maste { 62ac7ddfbfSEd Maste } 63ac7ddfbfSEd Maste 64ac7ddfbfSEd Maste void 65ac7ddfbfSEd Maste CompileUnit::CalculateSymbolContext(SymbolContext* sc) 66ac7ddfbfSEd Maste { 67ac7ddfbfSEd Maste sc->comp_unit = this; 68ac7ddfbfSEd Maste GetModule()->CalculateSymbolContext(sc); 69ac7ddfbfSEd Maste } 70ac7ddfbfSEd Maste 71ac7ddfbfSEd Maste ModuleSP 72ac7ddfbfSEd Maste CompileUnit::CalculateSymbolContextModule () 73ac7ddfbfSEd Maste { 74ac7ddfbfSEd Maste return GetModule(); 75ac7ddfbfSEd Maste } 76ac7ddfbfSEd Maste 77ac7ddfbfSEd Maste CompileUnit * 78ac7ddfbfSEd Maste CompileUnit::CalculateSymbolContextCompileUnit () 79ac7ddfbfSEd Maste { 80ac7ddfbfSEd Maste return this; 81ac7ddfbfSEd Maste } 82ac7ddfbfSEd Maste 83ac7ddfbfSEd Maste void 84ac7ddfbfSEd Maste CompileUnit::DumpSymbolContext(Stream *s) 85ac7ddfbfSEd Maste { 86ac7ddfbfSEd Maste GetModule()->DumpSymbolContext(s); 87ac7ddfbfSEd Maste s->Printf(", CompileUnit{0x%8.8" PRIx64 "}", GetID()); 88ac7ddfbfSEd Maste } 89ac7ddfbfSEd Maste 90ac7ddfbfSEd Maste 91ac7ddfbfSEd Maste void 92ac7ddfbfSEd Maste CompileUnit::GetDescription(Stream *s, lldb::DescriptionLevel level) const 93ac7ddfbfSEd Maste { 949f2f44ceSEd Maste const char* language = Language::GetNameForLanguageType(m_language); 95ac7ddfbfSEd Maste *s << "id = " << (const UserID&)*this << ", file = \"" << (const FileSpec&)*this << "\", language = \"" << language << '"'; 96ac7ddfbfSEd Maste } 97ac7ddfbfSEd Maste 98ac7ddfbfSEd Maste 99ac7ddfbfSEd Maste //---------------------------------------------------------------------- 100ac7ddfbfSEd Maste // Dump the current contents of this object. No functions that cause on 101ac7ddfbfSEd Maste // demand parsing of functions, globals, statics are called, so this 102ac7ddfbfSEd Maste // is a good function to call to get an idea of the current contents of 103ac7ddfbfSEd Maste // the CompileUnit object. 104ac7ddfbfSEd Maste //---------------------------------------------------------------------- 105ac7ddfbfSEd Maste void 106ac7ddfbfSEd Maste CompileUnit::Dump(Stream *s, bool show_context) const 107ac7ddfbfSEd Maste { 1089f2f44ceSEd Maste const char* language = Language::GetNameForLanguageType(m_language); 1099f2f44ceSEd Maste 1100127ef0fSEd Maste s->Printf("%p: ", static_cast<const void*>(this)); 111ac7ddfbfSEd Maste s->Indent(); 1120127ef0fSEd Maste *s << "CompileUnit" << static_cast<const UserID&>(*this) 1139f2f44ceSEd Maste << ", language = \"" << language 1140127ef0fSEd Maste << "\", file = '" << static_cast<const FileSpec&>(*this) << "'\n"; 115ac7ddfbfSEd Maste 116ac7ddfbfSEd Maste // m_types.Dump(s); 117ac7ddfbfSEd Maste 118ac7ddfbfSEd Maste if (m_variables.get()) 119ac7ddfbfSEd Maste { 120ac7ddfbfSEd Maste s->IndentMore(); 121ac7ddfbfSEd Maste m_variables->Dump(s, show_context); 122ac7ddfbfSEd Maste s->IndentLess(); 123ac7ddfbfSEd Maste } 124ac7ddfbfSEd Maste 125ac7ddfbfSEd Maste if (!m_functions.empty()) 126ac7ddfbfSEd Maste { 127ac7ddfbfSEd Maste s->IndentMore(); 128ac7ddfbfSEd Maste std::vector<FunctionSP>::const_iterator pos; 129ac7ddfbfSEd Maste std::vector<FunctionSP>::const_iterator end = m_functions.end(); 130ac7ddfbfSEd Maste for (pos = m_functions.begin(); pos != end; ++pos) 131ac7ddfbfSEd Maste { 132ac7ddfbfSEd Maste (*pos)->Dump(s, show_context); 133ac7ddfbfSEd Maste } 134ac7ddfbfSEd Maste 135ac7ddfbfSEd Maste s->IndentLess(); 136ac7ddfbfSEd Maste s->EOL(); 137ac7ddfbfSEd Maste } 138ac7ddfbfSEd Maste } 139ac7ddfbfSEd Maste 140ac7ddfbfSEd Maste //---------------------------------------------------------------------- 141ac7ddfbfSEd Maste // Add a function to this compile unit 142ac7ddfbfSEd Maste //---------------------------------------------------------------------- 143ac7ddfbfSEd Maste void 144ac7ddfbfSEd Maste CompileUnit::AddFunction(FunctionSP& funcSP) 145ac7ddfbfSEd Maste { 146ac7ddfbfSEd Maste // TODO: order these by address 147ac7ddfbfSEd Maste m_functions.push_back(funcSP); 148ac7ddfbfSEd Maste } 149ac7ddfbfSEd Maste 150ac7ddfbfSEd Maste FunctionSP 151ac7ddfbfSEd Maste CompileUnit::GetFunctionAtIndex (size_t idx) 152ac7ddfbfSEd Maste { 153ac7ddfbfSEd Maste FunctionSP funcSP; 154ac7ddfbfSEd Maste if (idx < m_functions.size()) 155ac7ddfbfSEd Maste funcSP = m_functions[idx]; 156ac7ddfbfSEd Maste return funcSP; 157ac7ddfbfSEd Maste } 158ac7ddfbfSEd Maste 159ac7ddfbfSEd Maste //---------------------------------------------------------------------- 1601c3bbb01SEd Maste // Find functions using the Mangled::Tokens token list. This 1611c3bbb01SEd Maste // function currently implements an interactive approach designed to find 1621c3bbb01SEd Maste // all instances of certain functions. It isn't designed to the 163ac7ddfbfSEd Maste // quickest way to lookup functions as it will need to iterate through 164ac7ddfbfSEd Maste // all functions and see if they match, though it does provide a powerful 165ac7ddfbfSEd Maste // and context sensitive way to search for all functions with a certain 166ac7ddfbfSEd Maste // name, all functions in a namespace, or all functions of a template 167ac7ddfbfSEd Maste // type. See Mangled::Tokens::Parse() comments for more information. 168ac7ddfbfSEd Maste // 169ac7ddfbfSEd Maste // The function prototype will need to change to return a list of 170ac7ddfbfSEd Maste // results. It was originally used to help debug the Mangled class 171ac7ddfbfSEd Maste // and the Mangled::Tokens::MatchesQuery() function and it currently 172ac7ddfbfSEd Maste // will print out a list of matching results for the functions that 173ac7ddfbfSEd Maste // are currently in this compile unit. 174ac7ddfbfSEd Maste // 175ac7ddfbfSEd Maste // A FindFunctions method should be called prior to this that takes 176ac7ddfbfSEd Maste // a regular function name (const char * or ConstString as a parameter) 177ac7ddfbfSEd Maste // before resorting to this slower but more complete function. The 178ac7ddfbfSEd Maste // other FindFunctions method should be able to take advantage of any 179ac7ddfbfSEd Maste // accelerator tables available in the debug information (which is 180ac7ddfbfSEd Maste // parsed by the SymbolFile parser plug-ins and registered with each 181ac7ddfbfSEd Maste // Module). 182ac7ddfbfSEd Maste //---------------------------------------------------------------------- 183ac7ddfbfSEd Maste //void 184ac7ddfbfSEd Maste //CompileUnit::FindFunctions(const Mangled::Tokens& tokens) 185ac7ddfbfSEd Maste //{ 186ac7ddfbfSEd Maste // if (!m_functions.empty()) 187ac7ddfbfSEd Maste // { 188ac7ddfbfSEd Maste // Stream s(stdout); 189ac7ddfbfSEd Maste // std::vector<FunctionSP>::const_iterator pos; 190ac7ddfbfSEd Maste // std::vector<FunctionSP>::const_iterator end = m_functions.end(); 191ac7ddfbfSEd Maste // for (pos = m_functions.begin(); pos != end; ++pos) 192ac7ddfbfSEd Maste // { 193ac7ddfbfSEd Maste // const ConstString& demangled = (*pos)->Mangled().Demangled(); 194ac7ddfbfSEd Maste // if (demangled) 195ac7ddfbfSEd Maste // { 196ac7ddfbfSEd Maste // const Mangled::Tokens& func_tokens = (*pos)->Mangled().GetTokens(); 197ac7ddfbfSEd Maste // if (func_tokens.MatchesQuery (tokens)) 198ac7ddfbfSEd Maste // s << "demangled MATCH found: " << demangled << "\n"; 199ac7ddfbfSEd Maste // } 200ac7ddfbfSEd Maste // } 201ac7ddfbfSEd Maste // } 202ac7ddfbfSEd Maste //} 203ac7ddfbfSEd Maste 204ac7ddfbfSEd Maste FunctionSP 205ac7ddfbfSEd Maste CompileUnit::FindFunctionByUID (lldb::user_id_t func_uid) 206ac7ddfbfSEd Maste { 207ac7ddfbfSEd Maste FunctionSP funcSP; 208ac7ddfbfSEd Maste if (!m_functions.empty()) 209ac7ddfbfSEd Maste { 210ac7ddfbfSEd Maste std::vector<FunctionSP>::const_iterator pos; 211ac7ddfbfSEd Maste std::vector<FunctionSP>::const_iterator end = m_functions.end(); 212ac7ddfbfSEd Maste for (pos = m_functions.begin(); pos != end; ++pos) 213ac7ddfbfSEd Maste { 214ac7ddfbfSEd Maste if ((*pos)->GetID() == func_uid) 215ac7ddfbfSEd Maste { 216ac7ddfbfSEd Maste funcSP = *pos; 217ac7ddfbfSEd Maste break; 218ac7ddfbfSEd Maste } 219ac7ddfbfSEd Maste } 220ac7ddfbfSEd Maste } 221ac7ddfbfSEd Maste return funcSP; 222ac7ddfbfSEd Maste } 223ac7ddfbfSEd Maste 224ac7ddfbfSEd Maste 225ac7ddfbfSEd Maste lldb::LanguageType 226ac7ddfbfSEd Maste CompileUnit::GetLanguage() 227ac7ddfbfSEd Maste { 228ac7ddfbfSEd Maste if (m_language == eLanguageTypeUnknown) 229ac7ddfbfSEd Maste { 230ac7ddfbfSEd Maste if (m_flags.IsClear(flagsParsedLanguage)) 231ac7ddfbfSEd Maste { 232ac7ddfbfSEd Maste m_flags.Set(flagsParsedLanguage); 233ac7ddfbfSEd Maste SymbolVendor* symbol_vendor = GetModule()->GetSymbolVendor(); 234ac7ddfbfSEd Maste if (symbol_vendor) 235ac7ddfbfSEd Maste { 236ac7ddfbfSEd Maste SymbolContext sc; 237ac7ddfbfSEd Maste CalculateSymbolContext(&sc); 238ac7ddfbfSEd Maste m_language = symbol_vendor->ParseCompileUnitLanguage(sc); 239ac7ddfbfSEd Maste } 240ac7ddfbfSEd Maste } 241ac7ddfbfSEd Maste } 242ac7ddfbfSEd Maste return m_language; 243ac7ddfbfSEd Maste } 244ac7ddfbfSEd Maste 245ac7ddfbfSEd Maste LineTable* 246ac7ddfbfSEd Maste CompileUnit::GetLineTable() 247ac7ddfbfSEd Maste { 2480127ef0fSEd Maste if (m_line_table_ap.get() == nullptr) 249ac7ddfbfSEd Maste { 250ac7ddfbfSEd Maste if (m_flags.IsClear(flagsParsedLineTable)) 251ac7ddfbfSEd Maste { 252ac7ddfbfSEd Maste m_flags.Set(flagsParsedLineTable); 253ac7ddfbfSEd Maste SymbolVendor* symbol_vendor = GetModule()->GetSymbolVendor(); 254ac7ddfbfSEd Maste if (symbol_vendor) 255ac7ddfbfSEd Maste { 256ac7ddfbfSEd Maste SymbolContext sc; 257ac7ddfbfSEd Maste CalculateSymbolContext(&sc); 258ac7ddfbfSEd Maste symbol_vendor->ParseCompileUnitLineTable(sc); 259ac7ddfbfSEd Maste } 260ac7ddfbfSEd Maste } 261ac7ddfbfSEd Maste } 262ac7ddfbfSEd Maste return m_line_table_ap.get(); 263ac7ddfbfSEd Maste } 264ac7ddfbfSEd Maste 265ac7ddfbfSEd Maste void 266ac7ddfbfSEd Maste CompileUnit::SetLineTable(LineTable* line_table) 267ac7ddfbfSEd Maste { 2680127ef0fSEd Maste if (line_table == nullptr) 269ac7ddfbfSEd Maste m_flags.Clear(flagsParsedLineTable); 270ac7ddfbfSEd Maste else 271ac7ddfbfSEd Maste m_flags.Set(flagsParsedLineTable); 272ac7ddfbfSEd Maste m_line_table_ap.reset(line_table); 273ac7ddfbfSEd Maste } 274ac7ddfbfSEd Maste 2759f2f44ceSEd Maste DebugMacros* 2769f2f44ceSEd Maste CompileUnit::GetDebugMacros() 2779f2f44ceSEd Maste { 2789f2f44ceSEd Maste if (m_debug_macros_sp.get() == nullptr) 2799f2f44ceSEd Maste { 2809f2f44ceSEd Maste if (m_flags.IsClear(flagsParsedDebugMacros)) 2819f2f44ceSEd Maste { 2829f2f44ceSEd Maste m_flags.Set(flagsParsedDebugMacros); 2839f2f44ceSEd Maste SymbolVendor* symbol_vendor = GetModule()->GetSymbolVendor(); 2849f2f44ceSEd Maste if (symbol_vendor) 2859f2f44ceSEd Maste { 2869f2f44ceSEd Maste SymbolContext sc; 2879f2f44ceSEd Maste CalculateSymbolContext(&sc); 2889f2f44ceSEd Maste symbol_vendor->ParseCompileUnitDebugMacros(sc); 2899f2f44ceSEd Maste } 2909f2f44ceSEd Maste } 2919f2f44ceSEd Maste } 2929f2f44ceSEd Maste 2939f2f44ceSEd Maste return m_debug_macros_sp.get(); 2949f2f44ceSEd Maste } 2959f2f44ceSEd Maste 2969f2f44ceSEd Maste void 2979f2f44ceSEd Maste CompileUnit::SetDebugMacros(const DebugMacrosSP &debug_macros_sp) 2989f2f44ceSEd Maste { 2999f2f44ceSEd Maste if (debug_macros_sp.get() == nullptr) 3009f2f44ceSEd Maste m_flags.Clear(flagsParsedDebugMacros); 3019f2f44ceSEd Maste else 3029f2f44ceSEd Maste m_flags.Set(flagsParsedDebugMacros); 3039f2f44ceSEd Maste m_debug_macros_sp = debug_macros_sp; 3049f2f44ceSEd Maste } 3059f2f44ceSEd Maste 306ac7ddfbfSEd Maste VariableListSP 307ac7ddfbfSEd Maste CompileUnit::GetVariableList(bool can_create) 308ac7ddfbfSEd Maste { 3090127ef0fSEd Maste if (m_variables.get() == nullptr && can_create) 310ac7ddfbfSEd Maste { 311ac7ddfbfSEd Maste SymbolContext sc; 312ac7ddfbfSEd Maste CalculateSymbolContext(&sc); 313ac7ddfbfSEd Maste assert(sc.module_sp); 314ac7ddfbfSEd Maste sc.module_sp->GetSymbolVendor()->ParseVariablesForContext(sc); 315ac7ddfbfSEd Maste } 316ac7ddfbfSEd Maste 317ac7ddfbfSEd Maste return m_variables; 318ac7ddfbfSEd Maste } 319ac7ddfbfSEd Maste 320ac7ddfbfSEd Maste uint32_t 321ac7ddfbfSEd Maste CompileUnit::FindLineEntry (uint32_t start_idx, uint32_t line, const FileSpec* file_spec_ptr, bool exact, LineEntry *line_entry_ptr) 322ac7ddfbfSEd Maste { 323ac7ddfbfSEd Maste uint32_t file_idx = 0; 324ac7ddfbfSEd Maste 325ac7ddfbfSEd Maste if (file_spec_ptr) 326ac7ddfbfSEd Maste { 327ac7ddfbfSEd Maste file_idx = GetSupportFiles().FindFileIndex (1, *file_spec_ptr, true); 328ac7ddfbfSEd Maste if (file_idx == UINT32_MAX) 329ac7ddfbfSEd Maste return UINT32_MAX; 330ac7ddfbfSEd Maste } 331ac7ddfbfSEd Maste else 332ac7ddfbfSEd Maste { 333ac7ddfbfSEd Maste // All the line table entries actually point to the version of the Compile 3341c3bbb01SEd Maste // Unit that is in the support files (the one at 0 was artificially added.) 335ac7ddfbfSEd Maste // So prefer the one further on in the support files if it exists... 336ac7ddfbfSEd Maste FileSpecList &support_files = GetSupportFiles(); 337ac7ddfbfSEd Maste const bool full = true; 338ac7ddfbfSEd Maste file_idx = support_files.FindFileIndex (1, support_files.GetFileSpecAtIndex(0), full); 339ac7ddfbfSEd Maste if (file_idx == UINT32_MAX) 340ac7ddfbfSEd Maste file_idx = 0; 341ac7ddfbfSEd Maste } 342ac7ddfbfSEd Maste LineTable *line_table = GetLineTable(); 343ac7ddfbfSEd Maste if (line_table) 344ac7ddfbfSEd Maste return line_table->FindLineEntryIndexByFileIndex (start_idx, file_idx, line, exact, line_entry_ptr); 345ac7ddfbfSEd Maste return UINT32_MAX; 346ac7ddfbfSEd Maste } 347ac7ddfbfSEd Maste 348ac7ddfbfSEd Maste 349ac7ddfbfSEd Maste 350ac7ddfbfSEd Maste 351ac7ddfbfSEd Maste uint32_t 352ac7ddfbfSEd Maste CompileUnit::ResolveSymbolContext 353ac7ddfbfSEd Maste ( 354ac7ddfbfSEd Maste const FileSpec& file_spec, 355ac7ddfbfSEd Maste uint32_t line, 356ac7ddfbfSEd Maste bool check_inlines, 357ac7ddfbfSEd Maste bool exact, 358ac7ddfbfSEd Maste uint32_t resolve_scope, 359ac7ddfbfSEd Maste SymbolContextList &sc_list 360ac7ddfbfSEd Maste ) 361ac7ddfbfSEd Maste { 362ac7ddfbfSEd Maste // First find all of the file indexes that match our "file_spec". If 363ac7ddfbfSEd Maste // "file_spec" has an empty directory, then only compare the basenames 364ac7ddfbfSEd Maste // when finding file indexes 365ac7ddfbfSEd Maste std::vector<uint32_t> file_indexes; 36635617911SEd Maste const bool full_match = (bool)file_spec.GetDirectory(); 3677aa51b79SEd Maste const bool remove_backup_dots = true; 3687aa51b79SEd Maste bool file_spec_matches_cu_file_spec = FileSpec::Equal(file_spec, *this, full_match, remove_backup_dots); 369ac7ddfbfSEd Maste 370ac7ddfbfSEd Maste // If we are not looking for inlined functions and our file spec doesn't 371ac7ddfbfSEd Maste // match then we are done... 372ac7ddfbfSEd Maste if (file_spec_matches_cu_file_spec == false && check_inlines == false) 373ac7ddfbfSEd Maste return 0; 374ac7ddfbfSEd Maste 3757aa51b79SEd Maste uint32_t file_idx = GetSupportFiles().FindFileIndex (1, file_spec, true, remove_backup_dots); 376ac7ddfbfSEd Maste while (file_idx != UINT32_MAX) 377ac7ddfbfSEd Maste { 378ac7ddfbfSEd Maste file_indexes.push_back (file_idx); 3797aa51b79SEd Maste file_idx = GetSupportFiles().FindFileIndex (file_idx + 1, file_spec, true, remove_backup_dots); 380ac7ddfbfSEd Maste } 381ac7ddfbfSEd Maste 382ac7ddfbfSEd Maste const size_t num_file_indexes = file_indexes.size(); 383ac7ddfbfSEd Maste if (num_file_indexes == 0) 384ac7ddfbfSEd Maste return 0; 385ac7ddfbfSEd Maste 386ac7ddfbfSEd Maste const uint32_t prev_size = sc_list.GetSize(); 387ac7ddfbfSEd Maste 388ac7ddfbfSEd Maste SymbolContext sc(GetModule()); 389ac7ddfbfSEd Maste sc.comp_unit = this; 390ac7ddfbfSEd Maste 391ac7ddfbfSEd Maste 392ac7ddfbfSEd Maste if (line != 0) 393ac7ddfbfSEd Maste { 394ac7ddfbfSEd Maste LineTable *line_table = sc.comp_unit->GetLineTable(); 395ac7ddfbfSEd Maste 3960127ef0fSEd Maste if (line_table != nullptr) 397ac7ddfbfSEd Maste { 398ac7ddfbfSEd Maste uint32_t found_line; 399ac7ddfbfSEd Maste uint32_t line_idx; 400ac7ddfbfSEd Maste 401ac7ddfbfSEd Maste if (num_file_indexes == 1) 402ac7ddfbfSEd Maste { 403ac7ddfbfSEd Maste // We only have a single support file that matches, so use 404ac7ddfbfSEd Maste // the line table function that searches for a line entries 405ac7ddfbfSEd Maste // that match a single support file index 406ac7ddfbfSEd Maste LineEntry line_entry; 407ac7ddfbfSEd Maste line_idx = line_table->FindLineEntryIndexByFileIndex (0, file_indexes.front(), line, exact, &line_entry); 408ac7ddfbfSEd Maste 409ac7ddfbfSEd Maste // If "exact == true", then "found_line" will be the same 410ac7ddfbfSEd Maste // as "line". If "exact == false", the "found_line" will be the 411ac7ddfbfSEd Maste // closest line entry with a line number greater than "line" and 412ac7ddfbfSEd Maste // we will use this for our subsequent line exact matches below. 413ac7ddfbfSEd Maste found_line = line_entry.line; 414ac7ddfbfSEd Maste 415ac7ddfbfSEd Maste while (line_idx != UINT32_MAX) 416ac7ddfbfSEd Maste { 417ac7ddfbfSEd Maste // If they only asked for the line entry, then we're done, we can just copy that over. 418ac7ddfbfSEd Maste // But if they wanted more than just the line number, fill it in. 419ac7ddfbfSEd Maste if (resolve_scope == eSymbolContextLineEntry) 420ac7ddfbfSEd Maste { 421ac7ddfbfSEd Maste sc.line_entry = line_entry; 422ac7ddfbfSEd Maste } 423ac7ddfbfSEd Maste else 424ac7ddfbfSEd Maste { 425ac7ddfbfSEd Maste line_entry.range.GetBaseAddress().CalculateSymbolContext(&sc, resolve_scope); 426ac7ddfbfSEd Maste } 427ac7ddfbfSEd Maste 428ac7ddfbfSEd Maste sc_list.Append(sc); 429ac7ddfbfSEd Maste line_idx = line_table->FindLineEntryIndexByFileIndex (line_idx + 1, file_indexes.front(), found_line, true, &line_entry); 430ac7ddfbfSEd Maste } 431ac7ddfbfSEd Maste } 432ac7ddfbfSEd Maste else 433ac7ddfbfSEd Maste { 434ac7ddfbfSEd Maste // We found multiple support files that match "file_spec" so use 435ac7ddfbfSEd Maste // the line table function that searches for a line entries 436ac7ddfbfSEd Maste // that match a multiple support file indexes. 437ac7ddfbfSEd Maste LineEntry line_entry; 438ac7ddfbfSEd Maste line_idx = line_table->FindLineEntryIndexByFileIndex (0, file_indexes, line, exact, &line_entry); 439ac7ddfbfSEd Maste 440ac7ddfbfSEd Maste // If "exact == true", then "found_line" will be the same 441ac7ddfbfSEd Maste // as "line". If "exact == false", the "found_line" will be the 442ac7ddfbfSEd Maste // closest line entry with a line number greater than "line" and 443ac7ddfbfSEd Maste // we will use this for our subsequent line exact matches below. 444ac7ddfbfSEd Maste found_line = line_entry.line; 445ac7ddfbfSEd Maste 446ac7ddfbfSEd Maste while (line_idx != UINT32_MAX) 447ac7ddfbfSEd Maste { 448ac7ddfbfSEd Maste if (resolve_scope == eSymbolContextLineEntry) 449ac7ddfbfSEd Maste { 450ac7ddfbfSEd Maste sc.line_entry = line_entry; 451ac7ddfbfSEd Maste } 452ac7ddfbfSEd Maste else 453ac7ddfbfSEd Maste { 454ac7ddfbfSEd Maste line_entry.range.GetBaseAddress().CalculateSymbolContext(&sc, resolve_scope); 455ac7ddfbfSEd Maste } 456ac7ddfbfSEd Maste 457ac7ddfbfSEd Maste sc_list.Append(sc); 458ac7ddfbfSEd Maste line_idx = line_table->FindLineEntryIndexByFileIndex (line_idx + 1, file_indexes, found_line, true, &line_entry); 459ac7ddfbfSEd Maste } 460ac7ddfbfSEd Maste } 461ac7ddfbfSEd Maste } 462ac7ddfbfSEd Maste } 463ac7ddfbfSEd Maste else if (file_spec_matches_cu_file_spec && !check_inlines) 464ac7ddfbfSEd Maste { 465ac7ddfbfSEd Maste // only append the context if we aren't looking for inline call sites 466ac7ddfbfSEd Maste // by file and line and if the file spec matches that of the compile unit 467ac7ddfbfSEd Maste sc_list.Append(sc); 468ac7ddfbfSEd Maste } 469ac7ddfbfSEd Maste return sc_list.GetSize() - prev_size; 470ac7ddfbfSEd Maste } 471ac7ddfbfSEd Maste 4729f2f44ceSEd Maste bool 4739f2f44ceSEd Maste CompileUnit::GetIsOptimized () 4749f2f44ceSEd Maste { 4754bb0738eSEd Maste if (m_is_optimized == eLazyBoolCalculate) 4764bb0738eSEd Maste { 4774bb0738eSEd Maste m_is_optimized = eLazyBoolNo; 4784bb0738eSEd Maste if (SymbolVendor *symbol_vendor = GetModule()->GetSymbolVendor()) 4794bb0738eSEd Maste { 4804bb0738eSEd Maste SymbolContext sc; 4814bb0738eSEd Maste CalculateSymbolContext(&sc); 4824bb0738eSEd Maste if (symbol_vendor->ParseCompileUnitIsOptimized(sc)) 4834bb0738eSEd Maste m_is_optimized = eLazyBoolYes; 4844bb0738eSEd Maste } 4854bb0738eSEd Maste } 4869f2f44ceSEd Maste return m_is_optimized; 4879f2f44ceSEd Maste } 4889f2f44ceSEd Maste 489ac7ddfbfSEd Maste void 490ac7ddfbfSEd Maste CompileUnit::SetVariableList(VariableListSP &variables) 491ac7ddfbfSEd Maste { 492ac7ddfbfSEd Maste m_variables = variables; 493ac7ddfbfSEd Maste } 494ac7ddfbfSEd Maste 4951c3bbb01SEd Maste const std::vector<ConstString> & 4961c3bbb01SEd Maste CompileUnit::GetImportedModules () 4971c3bbb01SEd Maste { 4981c3bbb01SEd Maste if (m_imported_modules.empty() && 4991c3bbb01SEd Maste m_flags.IsClear(flagsParsedImportedModules)) 5001c3bbb01SEd Maste { 5011c3bbb01SEd Maste m_flags.Set(flagsParsedImportedModules); 5021c3bbb01SEd Maste if (SymbolVendor *symbol_vendor = GetModule()->GetSymbolVendor()) 5031c3bbb01SEd Maste { 5041c3bbb01SEd Maste SymbolContext sc; 5051c3bbb01SEd Maste CalculateSymbolContext(&sc); 5061c3bbb01SEd Maste symbol_vendor->ParseImportedModules(sc, m_imported_modules); 5071c3bbb01SEd Maste } 5081c3bbb01SEd Maste } 5091c3bbb01SEd Maste return m_imported_modules; 5101c3bbb01SEd Maste } 5111c3bbb01SEd Maste 512ac7ddfbfSEd Maste FileSpecList& 513ac7ddfbfSEd Maste CompileUnit::GetSupportFiles () 514ac7ddfbfSEd Maste { 515ac7ddfbfSEd Maste if (m_support_files.GetSize() == 0) 516ac7ddfbfSEd Maste { 517ac7ddfbfSEd Maste if (m_flags.IsClear(flagsParsedSupportFiles)) 518ac7ddfbfSEd Maste { 519ac7ddfbfSEd Maste m_flags.Set(flagsParsedSupportFiles); 520ac7ddfbfSEd Maste SymbolVendor* symbol_vendor = GetModule()->GetSymbolVendor(); 521ac7ddfbfSEd Maste if (symbol_vendor) 522ac7ddfbfSEd Maste { 523ac7ddfbfSEd Maste SymbolContext sc; 524ac7ddfbfSEd Maste CalculateSymbolContext(&sc); 525ac7ddfbfSEd Maste symbol_vendor->ParseCompileUnitSupportFiles(sc, m_support_files); 526ac7ddfbfSEd Maste } 527ac7ddfbfSEd Maste } 528ac7ddfbfSEd Maste } 529ac7ddfbfSEd Maste return m_support_files; 530ac7ddfbfSEd Maste } 531ac7ddfbfSEd Maste 532ac7ddfbfSEd Maste void * 533ac7ddfbfSEd Maste CompileUnit::GetUserData () const 534ac7ddfbfSEd Maste { 535ac7ddfbfSEd Maste return m_user_data; 536ac7ddfbfSEd Maste } 537ac7ddfbfSEd Maste 538ac7ddfbfSEd Maste 539