From 2fa5c2833910071684403ef60ac0b82180e197bc Mon Sep 17 00:00:00 2001 From: Aleksandr Urakov Date: Fri, 14 Sep 2018 07:46:06 +0000 Subject: [PATCH] [PDB] Use the raw PDB symbol interface more accurately Summary: This patch adds some symbol tag checks before using the `IPDBRawSymbol` interface to improve safety and readability. Reviewers: zturner Reviewed By: zturner Subscribers: lldb-commits, stella.stamenova Tags: #lldb Differential Revision: https://reviews.llvm.org/D51967 llvm-svn: 342208 --- .../source/Plugins/SymbolFile/PDB/PDBASTParser.cpp | 52 ++++++++++++++++------ 1 file changed, 39 insertions(+), 13 deletions(-) diff --git a/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp b/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp index 48dac80..a4c4459 100644 --- a/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp +++ b/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp @@ -269,23 +269,49 @@ static std::unique_ptr GetClassOrFunctionParent(const llvm::pdb::PDBSymbol &symbol) { const IPDBSession &session = symbol.getSession(); const IPDBRawSymbol &raw = symbol.getRawSymbol(); + auto tag = symbol.getSymTag(); - auto class_parent_id = raw.getClassParentId(); - if (auto class_parent = session.getSymbolById(class_parent_id)) - return class_parent; + // For items that are nested inside of a class, return the class that it is + // nested inside of. + // Note that only certain items can be nested inside of classes. + switch (tag) { + case PDB_SymType::Function: + case PDB_SymType::Data: + case PDB_SymType::UDT: + case PDB_SymType::Enum: + case PDB_SymType::FunctionSig: + case PDB_SymType::Typedef: + case PDB_SymType::BaseClass: + case PDB_SymType::VTable: { + auto class_parent_id = raw.getClassParentId(); + if (auto class_parent = session.getSymbolById(class_parent_id)) + return class_parent; + } + default: + break; + } - auto lexical_parent_id = raw.getLexicalParentId(); - auto lexical_parent = session.getSymbolById(lexical_parent_id); - if (!lexical_parent) - return nullptr; + // Otherwise, if it is nested inside of a function, return the function. + // Note that only certain items can be nested inside of functions. + switch (tag) { + case PDB_SymType::Block: + case PDB_SymType::Data: { + auto lexical_parent_id = raw.getLexicalParentId(); + auto lexical_parent = session.getSymbolById(lexical_parent_id); + if (!lexical_parent) + return nullptr; - auto lexical_parent_tag = lexical_parent->getSymTag(); - if (lexical_parent_tag == PDB_SymType::Function) - return lexical_parent; - if (lexical_parent_tag == PDB_SymType::Exe) - return nullptr; + auto lexical_parent_tag = lexical_parent->getSymTag(); + if (lexical_parent_tag == PDB_SymType::Function) + return lexical_parent; + if (lexical_parent_tag == PDB_SymType::Exe) + return nullptr; - return GetClassOrFunctionParent(*lexical_parent); + return GetClassOrFunctionParent(*lexical_parent); + } + default: + return nullptr; + } } static clang::NamedDecl * -- 2.7.4