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 
CompileUnit(const lldb::ModuleSP & module_sp,void * user_data,const char * pathname,const lldb::user_id_t cu_sym_id,lldb::LanguageType language,lldb_private::LazyBool is_optimized)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)
24*b5893f02SDimitry Andric     : ModuleChild(module_sp), FileSpec(pathname), UserID(cu_sym_id),
25*b5893f02SDimitry Andric       m_user_data(user_data), m_language(language), m_flags(0),
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 
CompileUnit(const lldb::ModuleSP & module_sp,void * user_data,const FileSpec & fspec,const lldb::user_id_t cu_sym_id,lldb::LanguageType language,lldb_private::LazyBool is_optimized)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),
38*b5893f02SDimitry Andric       m_user_data(user_data), m_language(language), m_flags(0),
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 
~CompileUnit()46435933ddSDimitry Andric CompileUnit::~CompileUnit() {}
47ac7ddfbfSEd Maste 
CalculateSymbolContext(SymbolContext * sc)48435933ddSDimitry Andric void CompileUnit::CalculateSymbolContext(SymbolContext *sc) {
49ac7ddfbfSEd Maste   sc->comp_unit = this;
50ac7ddfbfSEd Maste   GetModule()->CalculateSymbolContext(sc);
51ac7ddfbfSEd Maste }
52ac7ddfbfSEd Maste 
CalculateSymbolContextModule()53435933ddSDimitry Andric ModuleSP CompileUnit::CalculateSymbolContextModule() { return GetModule(); }
54ac7ddfbfSEd Maste 
CalculateSymbolContextCompileUnit()55435933ddSDimitry Andric CompileUnit *CompileUnit::CalculateSymbolContextCompileUnit() { return this; }
56ac7ddfbfSEd Maste 
DumpSymbolContext(Stream * s)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 
GetDescription(Stream * s,lldb::DescriptionLevel level) const62435933ddSDimitry 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 
ForeachFunction(llvm::function_ref<bool (const FunctionSP &)> lambda) const69*b5893f02SDimitry Andric void CompileUnit::ForeachFunction(
70*b5893f02SDimitry Andric     llvm::function_ref<bool(const FunctionSP &)> lambda) const {
71*b5893f02SDimitry Andric   std::vector<lldb::FunctionSP> sorted_functions;
72*b5893f02SDimitry Andric   sorted_functions.reserve(m_functions_by_uid.size());
73*b5893f02SDimitry Andric   for (auto &p : m_functions_by_uid)
74*b5893f02SDimitry Andric     sorted_functions.push_back(p.second);
75*b5893f02SDimitry Andric   llvm::sort(sorted_functions.begin(), sorted_functions.end(),
76*b5893f02SDimitry Andric              [](const lldb::FunctionSP &a, const lldb::FunctionSP &b) {
77*b5893f02SDimitry Andric                return a->GetID() < b->GetID();
78*b5893f02SDimitry Andric              });
79*b5893f02SDimitry Andric 
80*b5893f02SDimitry Andric   for (auto &f : sorted_functions)
81*b5893f02SDimitry Andric     if (lambda(f))
82*b5893f02SDimitry Andric       return;
83*b5893f02SDimitry Andric }
84*b5893f02SDimitry Andric 
85ac7ddfbfSEd Maste //----------------------------------------------------------------------
864ba319b5SDimitry Andric // Dump the current contents of this object. No functions that cause on demand
874ba319b5SDimitry Andric // parsing of functions, globals, statics are called, so this is a good
884ba319b5SDimitry Andric // function to call to get an idea of the current contents of the CompileUnit
894ba319b5SDimitry Andric // object.
90ac7ddfbfSEd Maste //----------------------------------------------------------------------
Dump(Stream * s,bool show_context) const91435933ddSDimitry Andric void CompileUnit::Dump(Stream *s, bool show_context) const {
929f2f44ceSEd Maste   const char *language = Language::GetNameForLanguageType(m_language);
939f2f44ceSEd Maste 
940127ef0fSEd Maste   s->Printf("%p: ", static_cast<const void *>(this));
95ac7ddfbfSEd Maste   s->Indent();
96435933ddSDimitry Andric   *s << "CompileUnit" << static_cast<const UserID &>(*this) << ", language = \""
97435933ddSDimitry Andric      << language << "\", file = '" << static_cast<const FileSpec &>(*this)
98435933ddSDimitry Andric      << "'\n";
99ac7ddfbfSEd Maste 
100ac7ddfbfSEd Maste   //  m_types.Dump(s);
101ac7ddfbfSEd Maste 
102435933ddSDimitry Andric   if (m_variables.get()) {
103ac7ddfbfSEd Maste     s->IndentMore();
104ac7ddfbfSEd Maste     m_variables->Dump(s, show_context);
105ac7ddfbfSEd Maste     s->IndentLess();
106ac7ddfbfSEd Maste   }
107ac7ddfbfSEd Maste 
108*b5893f02SDimitry Andric   if (!m_functions_by_uid.empty()) {
109ac7ddfbfSEd Maste     s->IndentMore();
110*b5893f02SDimitry Andric     ForeachFunction([&s, show_context](const FunctionSP &f) {
111*b5893f02SDimitry Andric       f->Dump(s, show_context);
112*b5893f02SDimitry Andric       return false;
113*b5893f02SDimitry Andric     });
114ac7ddfbfSEd Maste 
115ac7ddfbfSEd Maste     s->IndentLess();
116ac7ddfbfSEd Maste     s->EOL();
117ac7ddfbfSEd Maste   }
118ac7ddfbfSEd Maste }
119ac7ddfbfSEd Maste 
120ac7ddfbfSEd Maste //----------------------------------------------------------------------
121ac7ddfbfSEd Maste // Add a function to this compile unit
122ac7ddfbfSEd Maste //----------------------------------------------------------------------
AddFunction(FunctionSP & funcSP)123435933ddSDimitry Andric void CompileUnit::AddFunction(FunctionSP &funcSP) {
124*b5893f02SDimitry Andric   m_functions_by_uid[funcSP->GetID()] = funcSP;
125ac7ddfbfSEd Maste }
126ac7ddfbfSEd Maste 
127ac7ddfbfSEd Maste //----------------------------------------------------------------------
1284ba319b5SDimitry Andric // Find functions using the Mangled::Tokens token list. This function currently
1294ba319b5SDimitry Andric // implements an interactive approach designed to find all instances of certain
1304ba319b5SDimitry Andric // functions. It isn't designed to the quickest way to lookup functions as it
1314ba319b5SDimitry Andric // will need to iterate through all functions and see if they match, though it
1324ba319b5SDimitry Andric // does provide a powerful and context sensitive way to search for all
1334ba319b5SDimitry Andric // functions with a certain name, all functions in a namespace, or all
1344ba319b5SDimitry Andric // functions of a template type. See Mangled::Tokens::Parse() comments for more
1354ba319b5SDimitry Andric // information.
136ac7ddfbfSEd Maste //
1374ba319b5SDimitry Andric // The function prototype will need to change to return a list of results. It
1384ba319b5SDimitry Andric // was originally used to help debug the Mangled class and the
1394ba319b5SDimitry Andric // Mangled::Tokens::MatchesQuery() function and it currently will print out a
1404ba319b5SDimitry Andric // list of matching results for the functions that are currently in this
1414ba319b5SDimitry Andric // compile unit.
142ac7ddfbfSEd Maste //
143ac7ddfbfSEd Maste // A FindFunctions method should be called prior to this that takes
1444ba319b5SDimitry Andric // a regular function name (const char * or ConstString as a parameter) before
1454ba319b5SDimitry Andric // resorting to this slower but more complete function. The other FindFunctions
1464ba319b5SDimitry Andric // method should be able to take advantage of any accelerator tables available
1474ba319b5SDimitry Andric // in the debug information (which is parsed by the SymbolFile parser plug-ins
1484ba319b5SDimitry Andric // and registered with each Module).
149ac7ddfbfSEd Maste //----------------------------------------------------------------------
150ac7ddfbfSEd Maste // void
151ac7ddfbfSEd Maste // CompileUnit::FindFunctions(const Mangled::Tokens& tokens)
152ac7ddfbfSEd Maste //{
153ac7ddfbfSEd Maste //  if (!m_functions.empty())
154ac7ddfbfSEd Maste //  {
155ac7ddfbfSEd Maste //      Stream s(stdout);
156ac7ddfbfSEd Maste //      std::vector<FunctionSP>::const_iterator pos;
157ac7ddfbfSEd Maste //      std::vector<FunctionSP>::const_iterator end = m_functions.end();
158ac7ddfbfSEd Maste //      for (pos = m_functions.begin(); pos != end; ++pos)
159ac7ddfbfSEd Maste //      {
160ac7ddfbfSEd Maste //          const ConstString& demangled = (*pos)->Mangled().Demangled();
161ac7ddfbfSEd Maste //          if (demangled)
162ac7ddfbfSEd Maste //          {
163435933ddSDimitry Andric //              const Mangled::Tokens& func_tokens =
164435933ddSDimitry Andric //              (*pos)->Mangled().GetTokens();
165ac7ddfbfSEd Maste //              if (func_tokens.MatchesQuery (tokens))
166ac7ddfbfSEd Maste //                  s << "demangled MATCH found: " << demangled << "\n";
167ac7ddfbfSEd Maste //          }
168ac7ddfbfSEd Maste //      }
169ac7ddfbfSEd Maste //  }
170ac7ddfbfSEd Maste //}
171ac7ddfbfSEd Maste 
FindFunctionByUID(lldb::user_id_t func_uid)172435933ddSDimitry Andric FunctionSP CompileUnit::FindFunctionByUID(lldb::user_id_t func_uid) {
173*b5893f02SDimitry Andric   auto it = m_functions_by_uid.find(func_uid);
174*b5893f02SDimitry Andric   if (it == m_functions_by_uid.end())
175*b5893f02SDimitry Andric     return FunctionSP();
176*b5893f02SDimitry Andric   return it->second;
177ac7ddfbfSEd Maste }
178ac7ddfbfSEd Maste 
GetLanguage()179435933ddSDimitry Andric lldb::LanguageType CompileUnit::GetLanguage() {
180435933ddSDimitry Andric   if (m_language == eLanguageTypeUnknown) {
181435933ddSDimitry Andric     if (m_flags.IsClear(flagsParsedLanguage)) {
182ac7ddfbfSEd Maste       m_flags.Set(flagsParsedLanguage);
183ac7ddfbfSEd Maste       SymbolVendor *symbol_vendor = GetModule()->GetSymbolVendor();
184435933ddSDimitry Andric       if (symbol_vendor) {
185*b5893f02SDimitry Andric         m_language = symbol_vendor->ParseLanguage(*this);
186ac7ddfbfSEd Maste       }
187ac7ddfbfSEd Maste     }
188ac7ddfbfSEd Maste   }
189ac7ddfbfSEd Maste   return m_language;
190ac7ddfbfSEd Maste }
191ac7ddfbfSEd Maste 
GetLineTable()192435933ddSDimitry Andric LineTable *CompileUnit::GetLineTable() {
193435933ddSDimitry Andric   if (m_line_table_ap.get() == nullptr) {
194435933ddSDimitry Andric     if (m_flags.IsClear(flagsParsedLineTable)) {
195ac7ddfbfSEd Maste       m_flags.Set(flagsParsedLineTable);
196ac7ddfbfSEd Maste       SymbolVendor *symbol_vendor = GetModule()->GetSymbolVendor();
197*b5893f02SDimitry Andric       if (symbol_vendor)
198*b5893f02SDimitry Andric         symbol_vendor->ParseLineTable(*this);
199ac7ddfbfSEd Maste     }
200ac7ddfbfSEd Maste   }
201ac7ddfbfSEd Maste   return m_line_table_ap.get();
202ac7ddfbfSEd Maste }
203ac7ddfbfSEd Maste 
SetLineTable(LineTable * line_table)204435933ddSDimitry Andric void CompileUnit::SetLineTable(LineTable *line_table) {
2050127ef0fSEd Maste   if (line_table == nullptr)
206ac7ddfbfSEd Maste     m_flags.Clear(flagsParsedLineTable);
207ac7ddfbfSEd Maste   else
208ac7ddfbfSEd Maste     m_flags.Set(flagsParsedLineTable);
209ac7ddfbfSEd Maste   m_line_table_ap.reset(line_table);
210ac7ddfbfSEd Maste }
211ac7ddfbfSEd Maste 
GetDebugMacros()212435933ddSDimitry Andric DebugMacros *CompileUnit::GetDebugMacros() {
213435933ddSDimitry Andric   if (m_debug_macros_sp.get() == nullptr) {
214435933ddSDimitry Andric     if (m_flags.IsClear(flagsParsedDebugMacros)) {
2159f2f44ceSEd Maste       m_flags.Set(flagsParsedDebugMacros);
2169f2f44ceSEd Maste       SymbolVendor *symbol_vendor = GetModule()->GetSymbolVendor();
217435933ddSDimitry Andric       if (symbol_vendor) {
218*b5893f02SDimitry Andric         symbol_vendor->ParseDebugMacros(*this);
2199f2f44ceSEd Maste       }
2209f2f44ceSEd Maste     }
2219f2f44ceSEd Maste   }
2229f2f44ceSEd Maste 
2239f2f44ceSEd Maste   return m_debug_macros_sp.get();
2249f2f44ceSEd Maste }
2259f2f44ceSEd Maste 
SetDebugMacros(const DebugMacrosSP & debug_macros_sp)226435933ddSDimitry Andric void CompileUnit::SetDebugMacros(const DebugMacrosSP &debug_macros_sp) {
2279f2f44ceSEd Maste   if (debug_macros_sp.get() == nullptr)
2289f2f44ceSEd Maste     m_flags.Clear(flagsParsedDebugMacros);
2299f2f44ceSEd Maste   else
2309f2f44ceSEd Maste     m_flags.Set(flagsParsedDebugMacros);
2319f2f44ceSEd Maste   m_debug_macros_sp = debug_macros_sp;
2329f2f44ceSEd Maste }
2339f2f44ceSEd Maste 
GetVariableList(bool can_create)234435933ddSDimitry Andric VariableListSP CompileUnit::GetVariableList(bool can_create) {
235435933ddSDimitry Andric   if (m_variables.get() == nullptr && can_create) {
236ac7ddfbfSEd Maste     SymbolContext sc;
237ac7ddfbfSEd Maste     CalculateSymbolContext(&sc);
238ac7ddfbfSEd Maste     assert(sc.module_sp);
239ac7ddfbfSEd Maste     sc.module_sp->GetSymbolVendor()->ParseVariablesForContext(sc);
240ac7ddfbfSEd Maste   }
241ac7ddfbfSEd Maste 
242ac7ddfbfSEd Maste   return m_variables;
243ac7ddfbfSEd Maste }
244ac7ddfbfSEd Maste 
FindLineEntry(uint32_t start_idx,uint32_t line,const FileSpec * file_spec_ptr,bool exact,LineEntry * line_entry_ptr)245435933ddSDimitry Andric uint32_t CompileUnit::FindLineEntry(uint32_t start_idx, uint32_t line,
246435933ddSDimitry Andric                                     const FileSpec *file_spec_ptr, bool exact,
247435933ddSDimitry Andric                                     LineEntry *line_entry_ptr) {
248ac7ddfbfSEd Maste   uint32_t file_idx = 0;
249ac7ddfbfSEd Maste 
250435933ddSDimitry Andric   if (file_spec_ptr) {
251ac7ddfbfSEd Maste     file_idx = GetSupportFiles().FindFileIndex(1, *file_spec_ptr, true);
252ac7ddfbfSEd Maste     if (file_idx == UINT32_MAX)
253ac7ddfbfSEd Maste       return UINT32_MAX;
254435933ddSDimitry Andric   } else {
255ac7ddfbfSEd Maste     // All the line table entries actually point to the version of the Compile
2561c3bbb01SEd Maste     // Unit that is in the support files (the one at 0 was artificially added.)
257ac7ddfbfSEd Maste     // So prefer the one further on in the support files if it exists...
258ac7ddfbfSEd Maste     FileSpecList &support_files = GetSupportFiles();
259ac7ddfbfSEd Maste     const bool full = true;
260435933ddSDimitry Andric     file_idx = support_files.FindFileIndex(
261435933ddSDimitry Andric         1, support_files.GetFileSpecAtIndex(0), full);
262ac7ddfbfSEd Maste     if (file_idx == UINT32_MAX)
263ac7ddfbfSEd Maste       file_idx = 0;
264ac7ddfbfSEd Maste   }
265ac7ddfbfSEd Maste   LineTable *line_table = GetLineTable();
266ac7ddfbfSEd Maste   if (line_table)
267435933ddSDimitry Andric     return line_table->FindLineEntryIndexByFileIndex(start_idx, file_idx, line,
268435933ddSDimitry Andric                                                      exact, line_entry_ptr);
269ac7ddfbfSEd Maste   return UINT32_MAX;
270ac7ddfbfSEd Maste }
271ac7ddfbfSEd Maste 
ResolveSymbolContext(const FileSpec & file_spec,uint32_t line,bool check_inlines,bool exact,SymbolContextItem resolve_scope,SymbolContextList & sc_list)272435933ddSDimitry Andric uint32_t CompileUnit::ResolveSymbolContext(const FileSpec &file_spec,
273435933ddSDimitry Andric                                            uint32_t line, bool check_inlines,
274*b5893f02SDimitry Andric                                            bool exact,
275*b5893f02SDimitry Andric                                            SymbolContextItem resolve_scope,
276435933ddSDimitry Andric                                            SymbolContextList &sc_list) {
277ac7ddfbfSEd Maste   // First find all of the file indexes that match our "file_spec". If
2784ba319b5SDimitry Andric   // "file_spec" has an empty directory, then only compare the basenames when
2794ba319b5SDimitry Andric   // finding file indexes
280ac7ddfbfSEd Maste   std::vector<uint32_t> file_indexes;
28135617911SEd Maste   const bool full_match = (bool)file_spec.GetDirectory();
282435933ddSDimitry Andric   bool file_spec_matches_cu_file_spec =
2834ba319b5SDimitry Andric       FileSpec::Equal(file_spec, *this, full_match);
284ac7ddfbfSEd Maste 
285ac7ddfbfSEd Maste   // If we are not looking for inlined functions and our file spec doesn't
286ac7ddfbfSEd Maste   // match then we are done...
287*b5893f02SDimitry Andric   if (!file_spec_matches_cu_file_spec && !check_inlines)
288ac7ddfbfSEd Maste     return 0;
289ac7ddfbfSEd Maste 
290435933ddSDimitry Andric   uint32_t file_idx =
2914ba319b5SDimitry Andric       GetSupportFiles().FindFileIndex(1, file_spec, true);
292435933ddSDimitry Andric   while (file_idx != UINT32_MAX) {
293ac7ddfbfSEd Maste     file_indexes.push_back(file_idx);
2944ba319b5SDimitry Andric     file_idx = GetSupportFiles().FindFileIndex(file_idx + 1, file_spec, true);
295ac7ddfbfSEd Maste   }
296ac7ddfbfSEd Maste 
297ac7ddfbfSEd Maste   const size_t num_file_indexes = file_indexes.size();
298ac7ddfbfSEd Maste   if (num_file_indexes == 0)
299ac7ddfbfSEd Maste     return 0;
300ac7ddfbfSEd Maste 
301ac7ddfbfSEd Maste   const uint32_t prev_size = sc_list.GetSize();
302ac7ddfbfSEd Maste 
303ac7ddfbfSEd Maste   SymbolContext sc(GetModule());
304ac7ddfbfSEd Maste   sc.comp_unit = this;
305ac7ddfbfSEd Maste 
306435933ddSDimitry Andric   if (line != 0) {
307ac7ddfbfSEd Maste     LineTable *line_table = sc.comp_unit->GetLineTable();
308ac7ddfbfSEd Maste 
309435933ddSDimitry Andric     if (line_table != nullptr) {
310ac7ddfbfSEd Maste       uint32_t found_line;
311ac7ddfbfSEd Maste       uint32_t line_idx;
312ac7ddfbfSEd Maste 
313435933ddSDimitry Andric       if (num_file_indexes == 1) {
3144ba319b5SDimitry Andric         // We only have a single support file that matches, so use the line
3154ba319b5SDimitry Andric         // table function that searches for a line entries that match a single
3164ba319b5SDimitry Andric         // support file index
317ac7ddfbfSEd Maste         LineEntry line_entry;
318435933ddSDimitry Andric         line_idx = line_table->FindLineEntryIndexByFileIndex(
319435933ddSDimitry Andric             0, file_indexes.front(), line, exact, &line_entry);
320ac7ddfbfSEd Maste 
3214ba319b5SDimitry Andric         // If "exact == true", then "found_line" will be the same as "line". If
3224ba319b5SDimitry Andric         // "exact == false", the "found_line" will be the closest line entry
3234ba319b5SDimitry Andric         // with a line number greater than "line" and we will use this for our
3244ba319b5SDimitry Andric         // subsequent line exact matches below.
325ac7ddfbfSEd Maste         found_line = line_entry.line;
326ac7ddfbfSEd Maste 
327435933ddSDimitry Andric         while (line_idx != UINT32_MAX) {
3284ba319b5SDimitry Andric           // If they only asked for the line entry, then we're done, we can
3294ba319b5SDimitry Andric           // just copy that over. But if they wanted more than just the line
3304ba319b5SDimitry Andric           // number, fill it in.
331435933ddSDimitry Andric           if (resolve_scope == eSymbolContextLineEntry) {
332ac7ddfbfSEd Maste             sc.line_entry = line_entry;
333435933ddSDimitry Andric           } else {
334435933ddSDimitry Andric             line_entry.range.GetBaseAddress().CalculateSymbolContext(
335435933ddSDimitry Andric                 &sc, resolve_scope);
336ac7ddfbfSEd Maste           }
337ac7ddfbfSEd Maste 
338ac7ddfbfSEd Maste           sc_list.Append(sc);
339435933ddSDimitry Andric           line_idx = line_table->FindLineEntryIndexByFileIndex(
340435933ddSDimitry Andric               line_idx + 1, file_indexes.front(), found_line, true,
341435933ddSDimitry Andric               &line_entry);
342ac7ddfbfSEd Maste         }
343435933ddSDimitry Andric       } else {
3444ba319b5SDimitry Andric         // We found multiple support files that match "file_spec" so use the
3454ba319b5SDimitry Andric         // line table function that searches for a line entries that match a
3464ba319b5SDimitry Andric         // multiple support file indexes.
347ac7ddfbfSEd Maste         LineEntry line_entry;
348435933ddSDimitry Andric         line_idx = line_table->FindLineEntryIndexByFileIndex(
349435933ddSDimitry Andric             0, file_indexes, line, exact, &line_entry);
350ac7ddfbfSEd Maste 
3514ba319b5SDimitry Andric         // If "exact == true", then "found_line" will be the same as "line". If
3524ba319b5SDimitry Andric         // "exact == false", the "found_line" will be the closest line entry
3534ba319b5SDimitry Andric         // with a line number greater than "line" and we will use this for our
3544ba319b5SDimitry Andric         // subsequent line exact matches below.
355ac7ddfbfSEd Maste         found_line = line_entry.line;
356ac7ddfbfSEd Maste 
357435933ddSDimitry Andric         while (line_idx != UINT32_MAX) {
358435933ddSDimitry Andric           if (resolve_scope == eSymbolContextLineEntry) {
359ac7ddfbfSEd Maste             sc.line_entry = line_entry;
360435933ddSDimitry Andric           } else {
361435933ddSDimitry Andric             line_entry.range.GetBaseAddress().CalculateSymbolContext(
362435933ddSDimitry Andric                 &sc, resolve_scope);
363ac7ddfbfSEd Maste           }
364ac7ddfbfSEd Maste 
365ac7ddfbfSEd Maste           sc_list.Append(sc);
366435933ddSDimitry Andric           line_idx = line_table->FindLineEntryIndexByFileIndex(
367435933ddSDimitry Andric               line_idx + 1, file_indexes, found_line, true, &line_entry);
368ac7ddfbfSEd Maste         }
369ac7ddfbfSEd Maste       }
370ac7ddfbfSEd Maste     }
371435933ddSDimitry Andric   } else if (file_spec_matches_cu_file_spec && !check_inlines) {
3724ba319b5SDimitry Andric     // only append the context if we aren't looking for inline call sites by
3734ba319b5SDimitry Andric     // file and line and if the file spec matches that of the compile unit
374ac7ddfbfSEd Maste     sc_list.Append(sc);
375ac7ddfbfSEd Maste   }
376ac7ddfbfSEd Maste   return sc_list.GetSize() - prev_size;
377ac7ddfbfSEd Maste }
378ac7ddfbfSEd Maste 
GetIsOptimized()379435933ddSDimitry Andric bool CompileUnit::GetIsOptimized() {
380435933ddSDimitry Andric   if (m_is_optimized == eLazyBoolCalculate) {
3814bb0738eSEd Maste     m_is_optimized = eLazyBoolNo;
382435933ddSDimitry Andric     if (SymbolVendor *symbol_vendor = GetModule()->GetSymbolVendor()) {
383*b5893f02SDimitry Andric       if (symbol_vendor->ParseIsOptimized(*this))
3844bb0738eSEd Maste         m_is_optimized = eLazyBoolYes;
3854bb0738eSEd Maste     }
3864bb0738eSEd Maste   }
3879f2f44ceSEd Maste   return m_is_optimized;
3889f2f44ceSEd Maste }
3899f2f44ceSEd Maste 
SetVariableList(VariableListSP & variables)390435933ddSDimitry Andric void CompileUnit::SetVariableList(VariableListSP &variables) {
391ac7ddfbfSEd Maste   m_variables = variables;
392ac7ddfbfSEd Maste }
393ac7ddfbfSEd Maste 
GetImportedModules()394435933ddSDimitry Andric const std::vector<ConstString> &CompileUnit::GetImportedModules() {
3951c3bbb01SEd Maste   if (m_imported_modules.empty() &&
396435933ddSDimitry Andric       m_flags.IsClear(flagsParsedImportedModules)) {
3971c3bbb01SEd Maste     m_flags.Set(flagsParsedImportedModules);
398435933ddSDimitry Andric     if (SymbolVendor *symbol_vendor = GetModule()->GetSymbolVendor()) {
3991c3bbb01SEd Maste       SymbolContext sc;
4001c3bbb01SEd Maste       CalculateSymbolContext(&sc);
4011c3bbb01SEd Maste       symbol_vendor->ParseImportedModules(sc, m_imported_modules);
4021c3bbb01SEd Maste     }
4031c3bbb01SEd Maste   }
4041c3bbb01SEd Maste   return m_imported_modules;
4051c3bbb01SEd Maste }
4061c3bbb01SEd Maste 
GetSupportFiles()407435933ddSDimitry Andric FileSpecList &CompileUnit::GetSupportFiles() {
408435933ddSDimitry Andric   if (m_support_files.GetSize() == 0) {
409435933ddSDimitry Andric     if (m_flags.IsClear(flagsParsedSupportFiles)) {
410ac7ddfbfSEd Maste       m_flags.Set(flagsParsedSupportFiles);
411ac7ddfbfSEd Maste       SymbolVendor *symbol_vendor = GetModule()->GetSymbolVendor();
412435933ddSDimitry Andric       if (symbol_vendor) {
413*b5893f02SDimitry Andric         symbol_vendor->ParseSupportFiles(*this, m_support_files);
414ac7ddfbfSEd Maste       }
415ac7ddfbfSEd Maste     }
416ac7ddfbfSEd Maste   }
417ac7ddfbfSEd Maste   return m_support_files;
418ac7ddfbfSEd Maste }
419ac7ddfbfSEd Maste 
GetUserData() const420435933ddSDimitry Andric void *CompileUnit::GetUserData() const { return m_user_data; }
421