<div><br></div><div><br><div class="gmail_quote"><div dir="ltr">On Tue, Sep 11, 2018 at 4:28 AM Aleksandr Urakov via Phabricator <<a href="mailto:reviews@reviews.llvm.org">reviews@reviews.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">aleksandr.urakov added inline comments.<br>
<br>
<br>
================<br>
Comment at: lldb/trunk/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp:289<br>
+  return GetClassOrFunctionParent(*lexical_parent);<br>
+}<br>
+<br>
----------------<br>
zturner wrote:<br>
> However, this is only for symbols (not types).  So we can exclude everything above Compiland.  In fact, we should `assert` that we don't get anything from above Compiland.  So I would write this as:<br>
> <br>
> <br>
> ```<br>
> uint32_t ParentId = 0;<br>
> switch (raw.getSymTag()) {<br>
> case PDB_SymType::Array:<br>
> case PDB_SymType::BaseClass:<br>
> case PDB_SymType::BuiltinType:<br>
> case PDB_SymType::Enum:<br>
> case PDB_SymType::FunctionArg:<br>
> case PDB_SymType::FunctionType:<br>
> case PDB_SymType::PointerType:<br>
> case PDB_SymType::UDTType:<br>
> case PDB_SymType::VTable:<br>
> case PDB_SymType::VTableShape:<br>
>   assert(false && "This is a type not a symbol!");<br>
>   return nullptr;<br>
> default:<br>
>   break;<br>
> }<br>
> ```<br>
> <br>
> And for the rest it's quite simple because you probably really only care about functions, public symbols, and data.  In which case you can continue:<br>
> <br>
> template<typename T><br>
> static std::unique_ptr<llvm::pdb::PDBSymbol><br>
> classOrLexicalParent(const T& t, IPDBSession &Session) {<br>
>   uint32_t parent = t.getClassParentId();<br>
>   if (parent == 0)<br>
>     parent = t.getLexicalParentId();<br>
>   return Session.getSymbolById(parent);<br>
> }<br>
> <br>
> ```<br>
> if (auto &F = dyn_cast<PDBSymbolFunc>(symbol)) {<br>
>   return classOrLexicalParent(F);<br>
> } else if (auto &D = dyn_cast<PDBSymbolData>(symbol)) {<br>
>   return classOrLexicalParent(F);<br>
> } else if (auto &P = dyn_cast<PDBSymbolPublic>(symbol)) {<br>
>   return P.getLexicalParent();<br>
> }<br>
> <br>
> ```<br>
The problem is that this function is used also for type symbols. When creating a type, we use `GetDeclContextContainingSymbol` to find a correct context for the type declaration, and call `GetClassOrFunctionParent` there. So we can find an enclosing class for an inner class for example.<br>
<br>
The main reason why I have used the low-level interface here is to avoid extra dynamic casts. But what you are saying about (if I understand correctly) is the type safety, and may be it's worth several dynamic casts. Do you mind if I'll commit the fix for the test and the warning and then will try to figure out (considering the table you have sent) how to make this function more type safe? I think that it requires some more time to find the solution.<br>
</blockquote><div dir="auto">It’s not just about type safety but also readability. Handling each case makes the expectations more clear so someone reading the code will have a better idea what it’s doing.  Using the raw interface might still be fine if the cases are enumerated and getClassParent / getLexicalParent are only called when it makes sense</div><div dir="auto"><br></div><div dir="auto"><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br>
<br>
Repository:<br>
  rL LLVM<br>
<br>
<a href="https://reviews.llvm.org/D51162" rel="noreferrer" target="_blank">https://reviews.llvm.org/D51162</a><br>
<br>
<br>
<br>
</blockquote></div></div>