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 20435933ddSDimitry Andric CompileUnit::CompileUnit(const lldb::ModuleSP &module_sp, void *user_data, 21435933ddSDimitry Andric const char *pathname, const lldb::user_id_t cu_sym_id, 22435933ddSDimitry Andric lldb::LanguageType language, 234bb0738eSEd Maste lldb_private::LazyBool is_optimized) 24435933ddSDimitry Andric : ModuleChild(module_sp), FileSpec(pathname, false), UserID(cu_sym_id), 25435933ddSDimitry Andric m_user_data(user_data), m_language(language), m_flags(0), m_functions(), 26435933ddSDimitry Andric m_support_files(), m_line_table_ap(), m_variables(), 27435933ddSDimitry Andric m_is_optimized(is_optimized) { 28ac7ddfbfSEd Maste if (language != eLanguageTypeUnknown) 29ac7ddfbfSEd Maste m_flags.Set(flagsParsedLanguage); 30ac7ddfbfSEd Maste assert(module_sp); 31ac7ddfbfSEd Maste } 32ac7ddfbfSEd Maste 33435933ddSDimitry Andric CompileUnit::CompileUnit(const lldb::ModuleSP &module_sp, void *user_data, 34435933ddSDimitry Andric const FileSpec &fspec, const lldb::user_id_t cu_sym_id, 35435933ddSDimitry Andric lldb::LanguageType language, 364bb0738eSEd Maste lldb_private::LazyBool is_optimized) 37435933ddSDimitry Andric : ModuleChild(module_sp), FileSpec(fspec), UserID(cu_sym_id), 38435933ddSDimitry Andric m_user_data(user_data), m_language(language), m_flags(0), m_functions(), 39435933ddSDimitry Andric m_support_files(), m_line_table_ap(), m_variables(), 40435933ddSDimitry Andric m_is_optimized(is_optimized) { 41ac7ddfbfSEd Maste if (language != eLanguageTypeUnknown) 42ac7ddfbfSEd Maste m_flags.Set(flagsParsedLanguage); 43ac7ddfbfSEd Maste assert(module_sp); 44ac7ddfbfSEd Maste } 45ac7ddfbfSEd Maste 46435933ddSDimitry Andric CompileUnit::~CompileUnit() {} 47ac7ddfbfSEd Maste 48435933ddSDimitry Andric void CompileUnit::CalculateSymbolContext(SymbolContext *sc) { 49ac7ddfbfSEd Maste sc->comp_unit = this; 50ac7ddfbfSEd Maste GetModule()->CalculateSymbolContext(sc); 51ac7ddfbfSEd Maste } 52ac7ddfbfSEd Maste 53435933ddSDimitry Andric ModuleSP CompileUnit::CalculateSymbolContextModule() { return GetModule(); } 54ac7ddfbfSEd Maste 55435933ddSDimitry Andric CompileUnit *CompileUnit::CalculateSymbolContextCompileUnit() { return this; } 56ac7ddfbfSEd Maste 57435933ddSDimitry Andric void CompileUnit::DumpSymbolContext(Stream *s) { 58ac7ddfbfSEd Maste GetModule()->DumpSymbolContext(s); 59ac7ddfbfSEd Maste s->Printf(", CompileUnit{0x%8.8" PRIx64 "}", GetID()); 60ac7ddfbfSEd Maste } 61ac7ddfbfSEd Maste 62435933ddSDimitry Andric void CompileUnit::GetDescription(Stream *s, 63435933ddSDimitry Andric lldb::DescriptionLevel level) const { 649f2f44ceSEd Maste const char *language = Language::GetNameForLanguageType(m_language); 65435933ddSDimitry Andric *s << "id = " << (const UserID &)*this << ", file = \"" 66435933ddSDimitry Andric << (const FileSpec &)*this << "\", language = \"" << language << '"'; 67ac7ddfbfSEd Maste } 68ac7ddfbfSEd Maste 69ac7ddfbfSEd Maste //---------------------------------------------------------------------- 70ac7ddfbfSEd Maste // Dump the current contents of this object. No functions that cause on 71ac7ddfbfSEd Maste // demand parsing of functions, globals, statics are called, so this 72ac7ddfbfSEd Maste // is a good function to call to get an idea of the current contents of 73ac7ddfbfSEd Maste // the CompileUnit object. 74ac7ddfbfSEd Maste //---------------------------------------------------------------------- 75435933ddSDimitry Andric void CompileUnit::Dump(Stream *s, bool show_context) const { 769f2f44ceSEd Maste const char *language = Language::GetNameForLanguageType(m_language); 779f2f44ceSEd Maste 780127ef0fSEd Maste s->Printf("%p: ", static_cast<const void *>(this)); 79ac7ddfbfSEd Maste s->Indent(); 80435933ddSDimitry Andric *s << "CompileUnit" << static_cast<const UserID &>(*this) << ", language = \"" 81435933ddSDimitry Andric << language << "\", file = '" << static_cast<const FileSpec &>(*this) 82435933ddSDimitry Andric << "'\n"; 83ac7ddfbfSEd Maste 84ac7ddfbfSEd Maste // m_types.Dump(s); 85ac7ddfbfSEd Maste 86435933ddSDimitry Andric if (m_variables.get()) { 87ac7ddfbfSEd Maste s->IndentMore(); 88ac7ddfbfSEd Maste m_variables->Dump(s, show_context); 89ac7ddfbfSEd Maste s->IndentLess(); 90ac7ddfbfSEd Maste } 91ac7ddfbfSEd Maste 92435933ddSDimitry Andric if (!m_functions.empty()) { 93ac7ddfbfSEd Maste s->IndentMore(); 94ac7ddfbfSEd Maste std::vector<FunctionSP>::const_iterator pos; 95ac7ddfbfSEd Maste std::vector<FunctionSP>::const_iterator end = m_functions.end(); 96435933ddSDimitry Andric for (pos = m_functions.begin(); pos != end; ++pos) { 97ac7ddfbfSEd Maste (*pos)->Dump(s, show_context); 98ac7ddfbfSEd Maste } 99ac7ddfbfSEd Maste 100ac7ddfbfSEd Maste s->IndentLess(); 101ac7ddfbfSEd Maste s->EOL(); 102ac7ddfbfSEd Maste } 103ac7ddfbfSEd Maste } 104ac7ddfbfSEd Maste 105ac7ddfbfSEd Maste //---------------------------------------------------------------------- 106ac7ddfbfSEd Maste // Add a function to this compile unit 107ac7ddfbfSEd Maste //---------------------------------------------------------------------- 108435933ddSDimitry Andric void CompileUnit::AddFunction(FunctionSP &funcSP) { 109ac7ddfbfSEd Maste // TODO: order these by address 110ac7ddfbfSEd Maste m_functions.push_back(funcSP); 111ac7ddfbfSEd Maste } 112ac7ddfbfSEd Maste 113435933ddSDimitry Andric FunctionSP CompileUnit::GetFunctionAtIndex(size_t idx) { 114ac7ddfbfSEd Maste FunctionSP funcSP; 115ac7ddfbfSEd Maste if (idx < m_functions.size()) 116ac7ddfbfSEd Maste funcSP = m_functions[idx]; 117ac7ddfbfSEd Maste return funcSP; 118ac7ddfbfSEd Maste } 119ac7ddfbfSEd Maste 120ac7ddfbfSEd Maste //---------------------------------------------------------------------- 1211c3bbb01SEd Maste // Find functions using the Mangled::Tokens token list. This 1221c3bbb01SEd Maste // function currently implements an interactive approach designed to find 1231c3bbb01SEd Maste // all instances of certain functions. It isn't designed to the 124ac7ddfbfSEd Maste // quickest way to lookup functions as it will need to iterate through 125ac7ddfbfSEd Maste // all functions and see if they match, though it does provide a powerful 126ac7ddfbfSEd Maste // and context sensitive way to search for all functions with a certain 127ac7ddfbfSEd Maste // name, all functions in a namespace, or all functions of a template 128ac7ddfbfSEd Maste // type. See Mangled::Tokens::Parse() comments for more information. 129ac7ddfbfSEd Maste // 130ac7ddfbfSEd Maste // The function prototype will need to change to return a list of 131ac7ddfbfSEd Maste // results. It was originally used to help debug the Mangled class 132ac7ddfbfSEd Maste // and the Mangled::Tokens::MatchesQuery() function and it currently 133ac7ddfbfSEd Maste // will print out a list of matching results for the functions that 134ac7ddfbfSEd Maste // are currently in this compile unit. 135ac7ddfbfSEd Maste // 136ac7ddfbfSEd Maste // A FindFunctions method should be called prior to this that takes 137ac7ddfbfSEd Maste // a regular function name (const char * or ConstString as a parameter) 138ac7ddfbfSEd Maste // before resorting to this slower but more complete function. The 139ac7ddfbfSEd Maste // other FindFunctions method should be able to take advantage of any 140ac7ddfbfSEd Maste // accelerator tables available in the debug information (which is 141ac7ddfbfSEd Maste // parsed by the SymbolFile parser plug-ins and registered with each 142ac7ddfbfSEd Maste // Module). 143ac7ddfbfSEd Maste //---------------------------------------------------------------------- 144ac7ddfbfSEd Maste // void 145ac7ddfbfSEd Maste // CompileUnit::FindFunctions(const Mangled::Tokens& tokens) 146ac7ddfbfSEd Maste //{ 147ac7ddfbfSEd Maste // if (!m_functions.empty()) 148ac7ddfbfSEd Maste // { 149ac7ddfbfSEd Maste // Stream s(stdout); 150ac7ddfbfSEd Maste // std::vector<FunctionSP>::const_iterator pos; 151ac7ddfbfSEd Maste // std::vector<FunctionSP>::const_iterator end = m_functions.end(); 152ac7ddfbfSEd Maste // for (pos = m_functions.begin(); pos != end; ++pos) 153ac7ddfbfSEd Maste // { 154ac7ddfbfSEd Maste // const ConstString& demangled = (*pos)->Mangled().Demangled(); 155ac7ddfbfSEd Maste // if (demangled) 156ac7ddfbfSEd Maste // { 157435933ddSDimitry Andric // const Mangled::Tokens& func_tokens = 158435933ddSDimitry Andric // (*pos)->Mangled().GetTokens(); 159ac7ddfbfSEd Maste // if (func_tokens.MatchesQuery (tokens)) 160ac7ddfbfSEd Maste // s << "demangled MATCH found: " << demangled << "\n"; 161ac7ddfbfSEd Maste // } 162ac7ddfbfSEd Maste // } 163ac7ddfbfSEd Maste // } 164ac7ddfbfSEd Maste //} 165ac7ddfbfSEd Maste 166435933ddSDimitry Andric FunctionSP CompileUnit::FindFunctionByUID(lldb::user_id_t func_uid) { 167ac7ddfbfSEd Maste FunctionSP funcSP; 168435933ddSDimitry Andric if (!m_functions.empty()) { 169ac7ddfbfSEd Maste std::vector<FunctionSP>::const_iterator pos; 170ac7ddfbfSEd Maste std::vector<FunctionSP>::const_iterator end = m_functions.end(); 171435933ddSDimitry Andric for (pos = m_functions.begin(); pos != end; ++pos) { 172435933ddSDimitry Andric if ((*pos)->GetID() == func_uid) { 173ac7ddfbfSEd Maste funcSP = *pos; 174ac7ddfbfSEd Maste break; 175ac7ddfbfSEd Maste } 176ac7ddfbfSEd Maste } 177ac7ddfbfSEd Maste } 178ac7ddfbfSEd Maste return funcSP; 179ac7ddfbfSEd Maste } 180ac7ddfbfSEd Maste 181435933ddSDimitry Andric lldb::LanguageType CompileUnit::GetLanguage() { 182435933ddSDimitry Andric if (m_language == eLanguageTypeUnknown) { 183435933ddSDimitry Andric if (m_flags.IsClear(flagsParsedLanguage)) { 184ac7ddfbfSEd Maste m_flags.Set(flagsParsedLanguage); 185ac7ddfbfSEd Maste SymbolVendor *symbol_vendor = GetModule()->GetSymbolVendor(); 186435933ddSDimitry Andric if (symbol_vendor) { 187ac7ddfbfSEd Maste SymbolContext sc; 188ac7ddfbfSEd Maste CalculateSymbolContext(&sc); 189ac7ddfbfSEd Maste m_language = symbol_vendor->ParseCompileUnitLanguage(sc); 190ac7ddfbfSEd Maste } 191ac7ddfbfSEd Maste } 192ac7ddfbfSEd Maste } 193ac7ddfbfSEd Maste return m_language; 194ac7ddfbfSEd Maste } 195ac7ddfbfSEd Maste 196435933ddSDimitry Andric LineTable *CompileUnit::GetLineTable() { 197435933ddSDimitry Andric if (m_line_table_ap.get() == nullptr) { 198435933ddSDimitry Andric if (m_flags.IsClear(flagsParsedLineTable)) { 199ac7ddfbfSEd Maste m_flags.Set(flagsParsedLineTable); 200ac7ddfbfSEd Maste SymbolVendor *symbol_vendor = GetModule()->GetSymbolVendor(); 201435933ddSDimitry Andric if (symbol_vendor) { 202ac7ddfbfSEd Maste SymbolContext sc; 203ac7ddfbfSEd Maste CalculateSymbolContext(&sc); 204ac7ddfbfSEd Maste symbol_vendor->ParseCompileUnitLineTable(sc); 205ac7ddfbfSEd Maste } 206ac7ddfbfSEd Maste } 207ac7ddfbfSEd Maste } 208ac7ddfbfSEd Maste return m_line_table_ap.get(); 209ac7ddfbfSEd Maste } 210ac7ddfbfSEd Maste 211435933ddSDimitry Andric void CompileUnit::SetLineTable(LineTable *line_table) { 2120127ef0fSEd Maste if (line_table == nullptr) 213ac7ddfbfSEd Maste m_flags.Clear(flagsParsedLineTable); 214ac7ddfbfSEd Maste else 215ac7ddfbfSEd Maste m_flags.Set(flagsParsedLineTable); 216ac7ddfbfSEd Maste m_line_table_ap.reset(line_table); 217ac7ddfbfSEd Maste } 218ac7ddfbfSEd Maste 219435933ddSDimitry Andric DebugMacros *CompileUnit::GetDebugMacros() { 220435933ddSDimitry Andric if (m_debug_macros_sp.get() == nullptr) { 221435933ddSDimitry Andric if (m_flags.IsClear(flagsParsedDebugMacros)) { 2229f2f44ceSEd Maste m_flags.Set(flagsParsedDebugMacros); 2239f2f44ceSEd Maste SymbolVendor *symbol_vendor = GetModule()->GetSymbolVendor(); 224435933ddSDimitry Andric if (symbol_vendor) { 2259f2f44ceSEd Maste SymbolContext sc; 2269f2f44ceSEd Maste CalculateSymbolContext(&sc); 2279f2f44ceSEd Maste symbol_vendor->ParseCompileUnitDebugMacros(sc); 2289f2f44ceSEd Maste } 2299f2f44ceSEd Maste } 2309f2f44ceSEd Maste } 2319f2f44ceSEd Maste 2329f2f44ceSEd Maste return m_debug_macros_sp.get(); 2339f2f44ceSEd Maste } 2349f2f44ceSEd Maste 235435933ddSDimitry Andric void CompileUnit::SetDebugMacros(const DebugMacrosSP &debug_macros_sp) { 2369f2f44ceSEd Maste if (debug_macros_sp.get() == nullptr) 2379f2f44ceSEd Maste m_flags.Clear(flagsParsedDebugMacros); 2389f2f44ceSEd Maste else 2399f2f44ceSEd Maste m_flags.Set(flagsParsedDebugMacros); 2409f2f44ceSEd Maste m_debug_macros_sp = debug_macros_sp; 2419f2f44ceSEd Maste } 2429f2f44ceSEd Maste 243435933ddSDimitry Andric VariableListSP CompileUnit::GetVariableList(bool can_create) { 244435933ddSDimitry Andric if (m_variables.get() == nullptr && can_create) { 245ac7ddfbfSEd Maste SymbolContext sc; 246ac7ddfbfSEd Maste CalculateSymbolContext(&sc); 247ac7ddfbfSEd Maste assert(sc.module_sp); 248ac7ddfbfSEd Maste sc.module_sp->GetSymbolVendor()->ParseVariablesForContext(sc); 249ac7ddfbfSEd Maste } 250ac7ddfbfSEd Maste 251ac7ddfbfSEd Maste return m_variables; 252ac7ddfbfSEd Maste } 253ac7ddfbfSEd Maste 254435933ddSDimitry Andric uint32_t CompileUnit::FindLineEntry(uint32_t start_idx, uint32_t line, 255435933ddSDimitry Andric const FileSpec *file_spec_ptr, bool exact, 256435933ddSDimitry Andric LineEntry *line_entry_ptr) { 257ac7ddfbfSEd Maste uint32_t file_idx = 0; 258ac7ddfbfSEd Maste 259435933ddSDimitry Andric if (file_spec_ptr) { 260ac7ddfbfSEd Maste file_idx = GetSupportFiles().FindFileIndex(1, *file_spec_ptr, true); 261ac7ddfbfSEd Maste if (file_idx == UINT32_MAX) 262ac7ddfbfSEd Maste return UINT32_MAX; 263435933ddSDimitry Andric } else { 264ac7ddfbfSEd Maste // All the line table entries actually point to the version of the Compile 2651c3bbb01SEd Maste // Unit that is in the support files (the one at 0 was artificially added.) 266ac7ddfbfSEd Maste // So prefer the one further on in the support files if it exists... 267ac7ddfbfSEd Maste FileSpecList &support_files = GetSupportFiles(); 268ac7ddfbfSEd Maste const bool full = true; 269435933ddSDimitry Andric file_idx = support_files.FindFileIndex( 270435933ddSDimitry Andric 1, support_files.GetFileSpecAtIndex(0), full); 271ac7ddfbfSEd Maste if (file_idx == UINT32_MAX) 272ac7ddfbfSEd Maste file_idx = 0; 273ac7ddfbfSEd Maste } 274ac7ddfbfSEd Maste LineTable *line_table = GetLineTable(); 275ac7ddfbfSEd Maste if (line_table) 276435933ddSDimitry Andric return line_table->FindLineEntryIndexByFileIndex(start_idx, file_idx, line, 277435933ddSDimitry Andric exact, line_entry_ptr); 278ac7ddfbfSEd Maste return UINT32_MAX; 279ac7ddfbfSEd Maste } 280ac7ddfbfSEd Maste 281435933ddSDimitry Andric uint32_t CompileUnit::ResolveSymbolContext(const FileSpec &file_spec, 282435933ddSDimitry Andric uint32_t line, bool check_inlines, 283435933ddSDimitry Andric bool exact, uint32_t resolve_scope, 284435933ddSDimitry Andric SymbolContextList &sc_list) { 285ac7ddfbfSEd Maste // First find all of the file indexes that match our "file_spec". If 286ac7ddfbfSEd Maste // "file_spec" has an empty directory, then only compare the basenames 287ac7ddfbfSEd Maste // when finding file indexes 288ac7ddfbfSEd Maste std::vector<uint32_t> file_indexes; 28935617911SEd Maste const bool full_match = (bool)file_spec.GetDirectory(); 2907aa51b79SEd Maste const bool remove_backup_dots = true; 291435933ddSDimitry Andric bool file_spec_matches_cu_file_spec = 292435933ddSDimitry Andric FileSpec::Equal(file_spec, *this, full_match, remove_backup_dots); 293ac7ddfbfSEd Maste 294ac7ddfbfSEd Maste // If we are not looking for inlined functions and our file spec doesn't 295ac7ddfbfSEd Maste // match then we are done... 296ac7ddfbfSEd Maste if (file_spec_matches_cu_file_spec == false && check_inlines == false) 297ac7ddfbfSEd Maste return 0; 298ac7ddfbfSEd Maste 299435933ddSDimitry Andric uint32_t file_idx = 300435933ddSDimitry Andric GetSupportFiles().FindFileIndex(1, file_spec, true, remove_backup_dots); 301435933ddSDimitry Andric while (file_idx != UINT32_MAX) { 302ac7ddfbfSEd Maste file_indexes.push_back(file_idx); 303435933ddSDimitry Andric file_idx = GetSupportFiles().FindFileIndex(file_idx + 1, file_spec, true, 304435933ddSDimitry Andric remove_backup_dots); 305ac7ddfbfSEd Maste } 306ac7ddfbfSEd Maste 307ac7ddfbfSEd Maste const size_t num_file_indexes = file_indexes.size(); 308ac7ddfbfSEd Maste if (num_file_indexes == 0) 309ac7ddfbfSEd Maste return 0; 310ac7ddfbfSEd Maste 311ac7ddfbfSEd Maste const uint32_t prev_size = sc_list.GetSize(); 312ac7ddfbfSEd Maste 313ac7ddfbfSEd Maste SymbolContext sc(GetModule()); 314ac7ddfbfSEd Maste sc.comp_unit = this; 315ac7ddfbfSEd Maste 316435933ddSDimitry Andric if (line != 0) { 317ac7ddfbfSEd Maste LineTable *line_table = sc.comp_unit->GetLineTable(); 318ac7ddfbfSEd Maste 319435933ddSDimitry Andric if (line_table != nullptr) { 320ac7ddfbfSEd Maste uint32_t found_line; 321ac7ddfbfSEd Maste uint32_t line_idx; 322ac7ddfbfSEd Maste 323435933ddSDimitry Andric if (num_file_indexes == 1) { 324ac7ddfbfSEd Maste // We only have a single support file that matches, so use 325ac7ddfbfSEd Maste // the line table function that searches for a line entries 326ac7ddfbfSEd Maste // that match a single support file index 327ac7ddfbfSEd Maste LineEntry line_entry; 328435933ddSDimitry Andric line_idx = line_table->FindLineEntryIndexByFileIndex( 329435933ddSDimitry Andric 0, file_indexes.front(), line, exact, &line_entry); 330ac7ddfbfSEd Maste 331ac7ddfbfSEd Maste // If "exact == true", then "found_line" will be the same 332ac7ddfbfSEd Maste // as "line". If "exact == false", the "found_line" will be the 333ac7ddfbfSEd Maste // closest line entry with a line number greater than "line" and 334ac7ddfbfSEd Maste // we will use this for our subsequent line exact matches below. 335ac7ddfbfSEd Maste found_line = line_entry.line; 336ac7ddfbfSEd Maste 337435933ddSDimitry Andric while (line_idx != UINT32_MAX) { 338435933ddSDimitry Andric // If they only asked for the line entry, then we're done, we can just 339435933ddSDimitry Andric // copy that over. 340ac7ddfbfSEd Maste // But if they wanted more than just the line number, fill it in. 341435933ddSDimitry Andric if (resolve_scope == eSymbolContextLineEntry) { 342ac7ddfbfSEd Maste sc.line_entry = line_entry; 343435933ddSDimitry Andric } else { 344435933ddSDimitry Andric line_entry.range.GetBaseAddress().CalculateSymbolContext( 345435933ddSDimitry Andric &sc, resolve_scope); 346ac7ddfbfSEd Maste } 347ac7ddfbfSEd Maste 348ac7ddfbfSEd Maste sc_list.Append(sc); 349435933ddSDimitry Andric line_idx = line_table->FindLineEntryIndexByFileIndex( 350435933ddSDimitry Andric line_idx + 1, file_indexes.front(), found_line, true, 351435933ddSDimitry Andric &line_entry); 352ac7ddfbfSEd Maste } 353435933ddSDimitry Andric } else { 354ac7ddfbfSEd Maste // We found multiple support files that match "file_spec" so use 355ac7ddfbfSEd Maste // the line table function that searches for a line entries 356ac7ddfbfSEd Maste // that match a multiple support file indexes. 357ac7ddfbfSEd Maste LineEntry line_entry; 358435933ddSDimitry Andric line_idx = line_table->FindLineEntryIndexByFileIndex( 359435933ddSDimitry Andric 0, file_indexes, line, exact, &line_entry); 360ac7ddfbfSEd Maste 361ac7ddfbfSEd Maste // If "exact == true", then "found_line" will be the same 362ac7ddfbfSEd Maste // as "line". If "exact == false", the "found_line" will be the 363ac7ddfbfSEd Maste // closest line entry with a line number greater than "line" and 364ac7ddfbfSEd Maste // we will use this for our subsequent line exact matches below. 365ac7ddfbfSEd Maste found_line = line_entry.line; 366ac7ddfbfSEd Maste 367435933ddSDimitry Andric while (line_idx != UINT32_MAX) { 368435933ddSDimitry Andric if (resolve_scope == eSymbolContextLineEntry) { 369ac7ddfbfSEd Maste sc.line_entry = line_entry; 370435933ddSDimitry Andric } else { 371435933ddSDimitry Andric line_entry.range.GetBaseAddress().CalculateSymbolContext( 372435933ddSDimitry Andric &sc, resolve_scope); 373ac7ddfbfSEd Maste } 374ac7ddfbfSEd Maste 375ac7ddfbfSEd Maste sc_list.Append(sc); 376435933ddSDimitry Andric line_idx = line_table->FindLineEntryIndexByFileIndex( 377435933ddSDimitry Andric line_idx + 1, file_indexes, found_line, true, &line_entry); 378ac7ddfbfSEd Maste } 379ac7ddfbfSEd Maste } 380ac7ddfbfSEd Maste } 381435933ddSDimitry Andric } else if (file_spec_matches_cu_file_spec && !check_inlines) { 382ac7ddfbfSEd Maste // only append the context if we aren't looking for inline call sites 383ac7ddfbfSEd Maste // by file and line and if the file spec matches that of the compile unit 384ac7ddfbfSEd Maste sc_list.Append(sc); 385ac7ddfbfSEd Maste } 386ac7ddfbfSEd Maste return sc_list.GetSize() - prev_size; 387ac7ddfbfSEd Maste } 388ac7ddfbfSEd Maste 389435933ddSDimitry Andric bool CompileUnit::GetIsOptimized() { 390435933ddSDimitry Andric if (m_is_optimized == eLazyBoolCalculate) { 3914bb0738eSEd Maste m_is_optimized = eLazyBoolNo; 392435933ddSDimitry Andric if (SymbolVendor *symbol_vendor = GetModule()->GetSymbolVendor()) { 3934bb0738eSEd Maste SymbolContext sc; 3944bb0738eSEd Maste CalculateSymbolContext(&sc); 3954bb0738eSEd Maste if (symbol_vendor->ParseCompileUnitIsOptimized(sc)) 3964bb0738eSEd Maste m_is_optimized = eLazyBoolYes; 3974bb0738eSEd Maste } 3984bb0738eSEd Maste } 3999f2f44ceSEd Maste return m_is_optimized; 4009f2f44ceSEd Maste } 4019f2f44ceSEd Maste 402435933ddSDimitry Andric void CompileUnit::SetVariableList(VariableListSP &variables) { 403ac7ddfbfSEd Maste m_variables = variables; 404ac7ddfbfSEd Maste } 405ac7ddfbfSEd Maste 406435933ddSDimitry Andric const std::vector<ConstString> &CompileUnit::GetImportedModules() { 4071c3bbb01SEd Maste if (m_imported_modules.empty() && 408435933ddSDimitry Andric m_flags.IsClear(flagsParsedImportedModules)) { 4091c3bbb01SEd Maste m_flags.Set(flagsParsedImportedModules); 410435933ddSDimitry Andric if (SymbolVendor *symbol_vendor = GetModule()->GetSymbolVendor()) { 4111c3bbb01SEd Maste SymbolContext sc; 4121c3bbb01SEd Maste CalculateSymbolContext(&sc); 4131c3bbb01SEd Maste symbol_vendor->ParseImportedModules(sc, m_imported_modules); 4141c3bbb01SEd Maste } 4151c3bbb01SEd Maste } 4161c3bbb01SEd Maste return m_imported_modules; 4171c3bbb01SEd Maste } 4181c3bbb01SEd Maste 419435933ddSDimitry Andric FileSpecList &CompileUnit::GetSupportFiles() { 420435933ddSDimitry Andric if (m_support_files.GetSize() == 0) { 421435933ddSDimitry Andric if (m_flags.IsClear(flagsParsedSupportFiles)) { 422ac7ddfbfSEd Maste m_flags.Set(flagsParsedSupportFiles); 423ac7ddfbfSEd Maste SymbolVendor *symbol_vendor = GetModule()->GetSymbolVendor(); 424435933ddSDimitry Andric if (symbol_vendor) { 425ac7ddfbfSEd Maste SymbolContext sc; 426ac7ddfbfSEd Maste CalculateSymbolContext(&sc); 427ac7ddfbfSEd Maste symbol_vendor->ParseCompileUnitSupportFiles(sc, m_support_files); 428ac7ddfbfSEd Maste } 429ac7ddfbfSEd Maste } 430ac7ddfbfSEd Maste } 431ac7ddfbfSEd Maste return m_support_files; 432ac7ddfbfSEd Maste } 433ac7ddfbfSEd Maste 434435933ddSDimitry Andric void *CompileUnit::GetUserData() const { return m_user_data; } 435