#include "lldb/Core/Module.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Utility/LLDBAssert.h"
-
#include "PdbUtil.h"
#include "UdtRecordCompleter.h"
#include "SymbolFileNativePDB.h"
return llvm::isa<clang::BlockDecl>(&context);
}
-void PdbAstBuilder::ParseAllNamespacesPlusChildrenOf(
- llvm::Optional<llvm::StringRef> parent) {
+void PdbAstBuilder::ParseNamespace(clang::DeclContext &context) {
+ clang::NamespaceDecl *ns = llvm::dyn_cast<clang::NamespaceDecl>(&context);
+ if (m_parsed_namespaces.contains(ns))
+ return;
+ std::string qname = ns->getQualifiedNameAsString();
SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(
m_clang.GetSymbolFile()->GetBackingSymbolFile());
PdbIndex &index = pdb->GetIndex();
CVTagRecord tag = CVTagRecord::create(cvt);
- if (!parent) {
- clang::QualType qt = GetOrCreateType(tid);
- CompleteType(qt);
- continue;
- }
-
// Call CreateDeclInfoForType unconditionally so that the namespace info
// gets created. But only call CreateRecordType if the namespace name
// matches.
continue;
clang::NamespaceDecl *ns = llvm::cast<clang::NamespaceDecl>(context);
- std::string actual_ns = ns->getQualifiedNameAsString();
- if (llvm::StringRef(actual_ns).startswith(*parent)) {
- clang::QualType qt = GetOrCreateType(tid);
- CompleteType(qt);
- continue;
+ llvm::StringRef ns_name = ns->getName();
+ if (ns_name.startswith(qname)) {
+ ns_name = ns_name.drop_front(qname.size());
+ if (ns_name.startswith("::"))
+ GetOrCreateType(tid);
}
}
+ ParseAllFunctionsAndNonLocalVars();
+ m_parsed_namespaces.insert(ns);
+}
- uint32_t module_count = index.dbi().modules().getModuleCount();
- for (uint16_t modi = 0; modi < module_count; ++modi) {
- CompilandIndexItem &cii = index.compilands().GetOrCreateCompiland(modi);
- const CVSymbolArray &symbols = cii.m_debug_stream.getSymbolArray();
- auto iter = symbols.begin();
- while (iter != symbols.end()) {
- PdbCompilandSymId sym_id{modi, iter.offset()};
-
- switch (iter->kind()) {
- case S_GPROC32:
- case S_LPROC32:
- GetOrCreateFunctionDecl(sym_id);
- iter = symbols.at(getScopeEndOffset(*iter));
- break;
- case S_GDATA32:
- case S_GTHREAD32:
- case S_LDATA32:
- case S_LTHREAD32:
- GetOrCreateVariableDecl(PdbCompilandSymId(modi, 0), sym_id);
- ++iter;
- break;
- default:
- ++iter;
+void PdbAstBuilder::ParseAllTypes() {
+ llvm::call_once(m_parse_all_types, [this]() {
+ SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(
+ m_clang.GetSymbolFile()->GetBackingSymbolFile());
+ PdbIndex &index = pdb->GetIndex();
+ TypeIndex ti{index.tpi().TypeIndexBegin()};
+ for (const CVType &cvt : index.tpi().typeArray()) {
+ PdbTypeSymId tid{ti};
+ ++ti;
+
+ if (!IsTagRecord(cvt))
continue;
+
+ GetOrCreateType(tid);
+ }
+ });
+}
+
+void PdbAstBuilder::ParseAllFunctionsAndNonLocalVars() {
+ llvm::call_once(m_parse_functions_and_non_local_vars, [this]() {
+ SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(
+ m_clang.GetSymbolFile()->GetBackingSymbolFile());
+ PdbIndex &index = pdb->GetIndex();
+ uint32_t module_count = index.dbi().modules().getModuleCount();
+ for (uint16_t modi = 0; modi < module_count; ++modi) {
+ CompilandIndexItem &cii = index.compilands().GetOrCreateCompiland(modi);
+ const CVSymbolArray &symbols = cii.m_debug_stream.getSymbolArray();
+ auto iter = symbols.begin();
+ while (iter != symbols.end()) {
+ PdbCompilandSymId sym_id{modi, iter.offset()};
+
+ switch (iter->kind()) {
+ case S_GPROC32:
+ case S_LPROC32:
+ GetOrCreateFunctionDecl(sym_id);
+ iter = symbols.at(getScopeEndOffset(*iter));
+ break;
+ case S_GDATA32:
+ case S_GTHREAD32:
+ case S_LDATA32:
+ case S_LTHREAD32:
+ GetOrCreateVariableDecl(PdbCompilandSymId(modi, 0), sym_id);
+ ++iter;
+ break;
+ default:
+ ++iter;
+ continue;
+ }
}
}
- }
+ });
}
static CVSymbolArray skipFunctionParameters(clang::Decl &decl,
// work (such as parsing the items that appear within the namespaces) at the
// same time.
if (context.isTranslationUnit()) {
- ParseAllNamespacesPlusChildrenOf(llvm::None);
+ ParseAllTypes();
+ ParseAllFunctionsAndNonLocalVars();
return;
}
if (context.isNamespace()) {
- clang::NamespaceDecl &ns = *llvm::dyn_cast<clang::NamespaceDecl>(&context);
- std::string qname = ns.getQualifiedNameAsString();
- ParseAllNamespacesPlusChildrenOf(llvm::StringRef{qname});
+ ParseNamespace(context);
return;
}
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Threading.h"
#include "Plugins/ExpressionParser/Clang/ClangASTImporter.h"
TypeIndex func_ti, CompilerType func_ct,
uint32_t param_count, clang::StorageClass func_storage,
bool is_inline, clang::DeclContext *parent);
- void ParseAllNamespacesPlusChildrenOf(llvm::Optional<llvm::StringRef> parent);
+ void ParseNamespace(clang::DeclContext &parent);
+ void ParseAllTypes();
+ void ParseAllFunctionsAndNonLocalVars();
void ParseDeclsForSimpleContext(clang::DeclContext &context);
void ParseBlockChildren(PdbCompilandSymId block_id);
TypeSystemClang &m_clang;
ClangASTImporter m_importer;
-
+ llvm::once_flag m_parse_functions_and_non_local_vars;
+ llvm::once_flag m_parse_all_types;
llvm::DenseMap<clang::Decl *, DeclStatus> m_decl_to_status;
llvm::DenseMap<lldb::user_id_t, clang::Decl *> m_uid_to_decl;
llvm::DenseMap<lldb::user_id_t, clang::QualType> m_uid_to_type;
llvm::DenseMap<lldb::opaque_compiler_type_t,
llvm::SmallSet<std::pair<llvm::StringRef, CompilerType>, 8>>
m_cxx_record_map;
+ llvm::DenseSet<clang::NamespaceDecl *> m_parsed_namespaces;
};
} // namespace npdb