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