zloyrobot created this revision.
zloyrobot added reviewers: amccarth, aleksandr.urakov, stella.stamenova.
zloyrobot added a project: LLDB.
Herald added subscribers: lldb-commits, teemperor.
This path implements member function support in
PdbAstBuilder::GetOrCreateFunctionDecl. It allows to lookup and evaluate struct
fields inside struct members
Repository:
rLLDB LLDB
https://reviews.llvm.org/D61886
Files:
lldb/lit/SymbolFile/NativePDB/Inputs/struct-fields.lldbinit
lldb/lit/SymbolFile/NativePDB/struct-fields.cpp
lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h
Index: lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h
===
--- lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h
+++ lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h
@@ -109,6 +109,9 @@
clang::VarDecl *CreateVariableDecl(PdbSymUid uid,
llvm::codeview::CVSymbol sym,
clang::DeclContext );
+ clang::CXXMethodDecl* LookupOrCreateMethodDecl(clang::CXXRecordDecl* parent,
+ const llvm::codeview::ProcSym& method_sym,
+ llvm::StringRef proc_name);
clang::DeclContext *
GetParentDeclContextForSymbol(const llvm::codeview::CVSymbol );
Index: lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
===
--- lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
+++ lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
@@ -983,19 +983,39 @@
return qt;
}
+clang::CXXMethodDecl *
+PdbAstBuilder::LookupOrCreateMethodDecl(clang::CXXRecordDecl* parent,
+const ProcSym& method_sym,
+llvm::StringRef proc_name) {
+
+ PdbTypeSymId type_id(method_sym.FunctionType);
+ clang::QualType qt = GetOrCreateType(type_id);
+ if (qt.isNull())
+return nullptr;
+
+ CompilerType parent_tag = m_clang.GetTypeForDecl(parent);
+ if (parent_tag.GetCompleteType()) {
+for (clang::CXXMethodDecl *method : parent->methods()) {
+ if (method->getNameAsString() == proc_name && method->getType() == qt)
+return method;
+}
+ }
+
+ PdbTypeSymId type = PdbTypeSymId(method_sym.FunctionType);
+ clang::QualType method_qt = GetOrCreateType(type);
+ CompleteType(method_qt);
+
+ return clang().AddMethodToCXXRecordType(parent_tag.GetOpaqueQualType(),
+proc_name.data(),nullptr, ToCompilerType(method_qt),
+lldb::eAccessPublic,false,false,false,
+false,false,false);
+}
+
clang::FunctionDecl *
PdbAstBuilder::GetOrCreateFunctionDecl(PdbCompilandSymId func_id) {
if (clang::Decl *decl = TryGetDecl(func_id))
return llvm::dyn_cast(decl);
- clang::DeclContext *parent = GetParentDeclContext(PdbSymUid(func_id));
- std::string context_name;
- if (clang::NamespaceDecl *ns = llvm::dyn_cast(parent)) {
-context_name = ns->getQualifiedNameAsString();
- } else if (clang::TagDecl *tag = llvm::dyn_cast(parent)) {
-context_name = tag->getQualifiedNameAsString();
- }
-
CVSymbol cvs = m_index.ReadSymbolRecord(func_id);
ProcSym proc(static_cast(cvs.kind()));
llvm::cantFail(SymbolDeserializer::deserializeAs(cvs, proc));
@@ -1005,21 +1025,27 @@
if (qt.isNull())
return nullptr;
- clang::StorageClass storage = clang::SC_None;
- if (proc.Kind == SymbolRecordKind::ProcSym)
-storage = clang::SC_Static;
-
- const clang::FunctionProtoType *func_type =
- llvm::dyn_cast(qt);
+ clang::DeclContext *parent = GetParentDeclContext(PdbSymUid(func_id));
+
+ llvm::StringRef proc_name = proc.Name;
+ if (clang::NamedDecl *ns = llvm::dyn_cast(parent)) {
+proc_name.consume_front(ns->getQualifiedNameAsString());
+proc_name.consume_front("::");
+ }
- CompilerType func_ct = ToCompilerType(qt);
+ clang::FunctionDecl *function_decl = nullptr;
+ if (clang::CXXRecordDecl *tag = llvm::dyn_cast(parent))
+function_decl = LookupOrCreateMethodDecl(tag, proc, proc_name);
- llvm::StringRef proc_name = proc.Name;
- proc_name.consume_front(context_name);
- proc_name.consume_front("::");
+ if (function_decl == nullptr) {
+clang::StorageClass storage = clang::SC_None;
+if (proc.Kind == SymbolRecordKind::ProcSym)
+ storage = clang::SC_Static;
- clang::FunctionDecl *function_decl = m_clang.CreateFunctionDeclaration(
+CompilerType func_ct = ToCompilerType(qt);
+function_decl = m_clang.CreateFunctionDeclaration(
parent, proc_name.str().c_str(), func_ct, storage, false);
+ }
lldbassert(m_uid_to_decl.count(toOpaqueUid(func_id)) == 0);
m_uid_to_decl[toOpaqueUid(func_id)] = function_decl;
@@ -1028,7 +1054,9 @@
status.uid = toOpaqueUid(func_id);
m_decl_to_status.insert({function_decl, status});
-