<div dir="ltr">How large of a change do you think it would be to abstract out the location information for the variable?  As far as I can tell, our uses of this DWARFExpression on Variables are very limited:<div><br></div><div>1. In ValueObjectVariable::UpdateValue and ClangExpressionDeclMap::GetVariableValue, if the location is a constant value, it refers to a a host address, we just read the value out as a number.</div><div>2. In EntityVariable::Materialize(), we check whether it is valid.</div><div>3. In SymbolFileDWARF, we "evaluate" the expression.<br></div><div>4. In a few places, we check whether an input address matches the location specified.</div><div>5. We dump the location to stdout in a few places.</div><div><br></div><div>Everything else could just as easily be private methods, because that's all that public users of DWARFExpression actually use.</div><div><br></div><div>This seems like an easy abstraction to create.  #3 is irrelevant because that code is in SymbolFileDWARF, it could downcast from Location to DWARFLocation.  #1, 2, 4, and 5 could easily be implemented directly against a PDB.</div><div><br></div><div>While I haven't tried to actually *do* either approach yet, I like the idea of creating the abstraction because it provides the native / most optimized debugging experience no matter what you're using.  For example, I can easily imagine a scenario where I have to keep the PDB open in memory to query some types of information, but I have to do a conversion of location information for Variables, and the memory usage becomes unacceptable because everything is memory twice (even though it's lazily evaluated, the memory usage would double over time).</div><div><br></div><div><br><div><br><div class="gmail_quote"><div dir="ltr">On Fri, Mar 11, 2016 at 11:56 AM Greg Clayton <<a href="mailto:gclayton@apple.com" target="_blank">gclayton@apple.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Feel free to abstract if you need to. The page you sent me to has _very_ simple locations that would convert to DWARF expressions very easily. Probably less that a hundred lines of code.<br>
<br>
If you need to abstract, making a lldb_private::Location class that DWARFExpression would implement the needed pure virtuals. Then each things that contains DWARFExpression would now contain a lldb_private::LocationSP which would be a shared pointer to a lldb_private::Location. DWARFExpression has grown over the years to contain a bunch of evaluate variants.<br>
<br>
Just know that LLDB lazily parses things. We don't say "convert the entire PDB into the internal LLDB format now!". We say "get the line table for this one compile unit". Find the function for address "0x123000" and parse it. Later we will ask to get the function type and its args. Later, if we ever need to, we will lazily parse the blocks in the function. Nothing is parsed in full.<br>
<br>
Let me know what you want to do. Abstraction is great, but comes at a cost of breaking things when our tests don't cover everything, so that is a worry on my end with any large changes...<br>
<br>
<br>
> On Mar 11, 2016, at 11:47 AM, Zachary Turner <<a href="mailto:zturner@google.com" target="_blank">zturner@google.com</a>> wrote:<br>
><br>
> The only "spec" is the API that allows you to access the info.  There's no spec of the bit format.  This is probably all you are actually looking for though:<br>
><br>
> The problem isn't necessarily that one is more pwoerful than the other, it's just that PDBs can get huge (on the order of gigabytes), and converting between formats is an unnecessary step that a) will be slow to do the conversion, b) might not map 1 to 1 between the formats, and c) it' already trivial (on the order of a few lines of code) to just query the PDB for everything you need.<br>
><br>
> So we're talking about potentially thousands of lines of code to do something that would take about 10 (as well as being more efficient) with a proper abstraction.<br>
><br>
> On Fri, Mar 11, 2016 at 11:43 AM Greg Clayton <<a href="mailto:gclayton@apple.com" target="_blank">gclayton@apple.com</a>> wrote:<br>
> See my other email. You can abstract this, but it doesn't seem worth it unless PDB has some really powerful way to express variable locations?<br>
><br>
> > On Mar 11, 2016, at 11:39 AM, Zachary Turner via lldb-dev <<a href="mailto:lldb-dev@lists.llvm.org" target="_blank">lldb-dev@lists.llvm.org</a>> wrote:<br>
> ><br>
> > Can we abstract this somehow?  Converting all my debug info to DWARF seems like a non-starter, as it doesn't look like you can just do it partially, you have to go all the way (just based on glancing at the DWARFExpression header file)<br>
> ><br>
> > On Fri, Mar 11, 2016 at 11:38 AM Jim Ingham <<a href="mailto:jingham@apple.com" target="_blank">jingham@apple.com</a>> wrote:<br>
> > lldb uses DWARF expressions internally as a convenient language to represent locations of values.  We had to pick some representation, and the DWARF expression was powerful enough for our purposes, meant we didn't have to reinvent something that already existed, and had the added benefit that if you did your DWARF then you don't have to transcode.<br>
> ><br>
> > Jim<br>
> ><br>
> > > On Mar 11, 2016, at 11:32 AM, Zachary Turner via lldb-dev <<a href="mailto:lldb-dev@lists.llvm.org" target="_blank">lldb-dev@lists.llvm.org</a>> wrote:<br>
> > ><br>
> > > Also why does the lldb_private::Variable() class take a DWARFExpression to its constructor?  Seems like this is wrong in the face of non-DWARF debug information.<br>
> > ><br>
> > > On Fri, Mar 11, 2016 at 11:02 AM Zachary Turner <<a href="mailto:zturner@google.com" target="_blank">zturner@google.com</a>> wrote:<br>
> > > I'm trying to implement this function for PDB.  There are two overloads:<br>
> > ><br>
> > > uint32_t<br>
> > > FindGlobalVariables (const ConstString &name, const CompilerDeclContext *parent_decl_ctx, bool append, uint32_t max_matches, VariableList& variables)<br>
> > ><br>
> > > uint32_t<br>
> > > FindGlobalVariables(const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables)<br>
> > ><br>
> > > I know how to implement the second overload, but not the first.  What is a CompilerDeclContext?  Some comments in the DWARF implementation of the function seem to imply it's related to namespaces, but there's a lot of strange code that I don't understand.  What is the relationship between a namespace and a symbol file?  And why does `DeclContextMatchesThisSymbolFile` contain no code at all that accesses any property of the symbol file?  It just checks if decl_ctx->GetTypeSystem()->GetMinimumLanguage(nullptr) == decl_ctx->GetTypeSystem(), which appears to have nothing to do with any symbol file.<br>
> > ><br>
> > > What user command or debugger operation results in FindGlobalVariables getting called with this particular overload, and how does it build the CompilerDeclContext?<br>
> > ><br>
> > > On another note, why is the decl context stored as void* instead of having an actual wrapper with an abstract interface such as ClangDeclContext / JavaDeclContext, etc that all inherit from LanguageDeclContext, and pass the LanguageDeclContext around instead of a void*?<br>
> > > _______________________________________________<br>
> > > lldb-dev mailing list<br>
> > > <a href="mailto:lldb-dev@lists.llvm.org" target="_blank">lldb-dev@lists.llvm.org</a><br>
> > > <a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev</a><br>
> ><br>
> > _______________________________________________<br>
> > lldb-dev mailing list<br>
> > <a href="mailto:lldb-dev@lists.llvm.org" target="_blank">lldb-dev@lists.llvm.org</a><br>
> > <a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev</a><br>
><br>
<br>
</blockquote></div></div></div></div>