[Lldb-commits] [PATCH] D51162: [PDB] Restore AST from PDB symbols

Zachary Turner via Phabricator via lldb-commits lldb-commits at lists.llvm.org
Mon Sep 10 16:36:59 PDT 2018


zturner added inline comments.


================
Comment at: lldb/trunk/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp:268-269
+
+std::unique_ptr<llvm::pdb::PDBSymbol>
+GetClassOrFunctionParent(const llvm::pdb::PDBSymbol &symbol) {
+  const IPDBSession &session = symbol.getSession();
----------------
All file local functions should be marked `static`.


================
Comment at: lldb/trunk/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp:273-288
+  auto class_parent_id = raw.getClassParentId();
+  if (auto class_parent = session.getSymbolById(class_parent_id))
+    return class_parent;
+
+  auto lexical_parent_id = raw.getLexicalParentId();
+  auto lexical_parent = session.getSymbolById(lexical_parent_id);
+  if (!lexical_parent)
----------------
This function is a little too general because it hits the `IPDBRawSymbol` interface which I would strongly discourage, and as a result I think it's probably wrong.  class parent id only valid for certain types of symbols in the first place.  Likewise, `getLexicalParentId()` is only valid for certain types of symbols.  The full list is:



| SymbolType | LexicalParent | ClassParent |
| Array | Compiland | <invalid> |
| BaseClass | Compiland | Enclosing Class |
| BuiltinType | Compiland |  <invalid> |
| Enum | Compiland | Enclosing Class |
| FunctionArg | Compiland | Enclosing Function |
| FunctionType | Compiland | Enclosing Class |
| Pointer | Compiland | <invalid> |
| UDT | Compiland | Class Parent  |
| VTable | Compiland | Class Parent |
| VTableShape | Compiland | <invalid> |
| Compiland | Exe File | <invalid> |
| CompilandDetails | Compiland | <invalid> |
| CompilandEnv | Compiland | <invalid> |
| Data | Compiland, Function, or Block | Enclosing Class (or null) |
| Exe | <invalid> | <invalid> |
| Function | Compiland | Class Parent (if member function) |
| FunctionDebugStart | Function | <invalid> |
| FunctionDebugEnd | Function | <invalid> |
| PublicSymbol | Exe | <invalid> |
| Thunk | Compiland or Function | <invalid> |



================
Comment at: lldb/trunk/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp:289
+  return GetClassOrFunctionParent(*lexical_parent);
+}
+
----------------
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:


```
uint32_t ParentId = 0;
switch (raw.getSymTag()) {
case PDB_SymType::Array:
case PDB_SymType::BaseClass:
case PDB_SymType::BuiltinType:
case PDB_SymType::Enum:
case PDB_SymType::FunctionArg:
case PDB_SymType::FunctionType:
case PDB_SymType::PointerType:
case PDB_SymType::UDTType:
case PDB_SymType::VTable:
case PDB_SymType::VTableShape:
  assert(false && "This is a type not a symbol!");
  return nullptr;
default:
  break;
}
```

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:

template<typename T>
static std::unique_ptr<llvm::pdb::PDBSymbol>
classOrLexicalParent(const T& t, IPDBSession &Session) {
  uint32_t parent = t.getClassParentId();
  if (parent == 0)
    parent = t.getLexicalParentId();
  return Session.getSymbolById(parent);
}

```
if (auto &F = dyn_cast<PDBSymbolFunc>(symbol)) {
  return classOrLexicalParent(F);
} else if (auto &D = dyn_cast<PDBSymbolData>(symbol)) {
  return classOrLexicalParent(F);
} else if (auto &P = dyn_cast<PDBSymbolPublic>(symbol)) {
  return P.getLexicalParent();
}

```


Repository:
  rL LLVM

https://reviews.llvm.org/D51162





More information about the lldb-commits mailing list