zequanwu updated this revision to Diff 389364.
zequanwu added a comment.
This revision is now accepted and ready to land.
Use `lldb-test symbols --find=function --name=full::name --function-flags=full`
for testing.
Add some information about static/virtual/artificial and access type.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D113930/new/
https://reviews.llvm.org/D113930
Files:
lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
lldb/test/Shell/SymbolFile/NativePDB/find-functions.cpp
Index: lldb/test/Shell/SymbolFile/NativePDB/find-functions.cpp
===================================================================
--- lldb/test/Shell/SymbolFile/NativePDB/find-functions.cpp
+++ lldb/test/Shell/SymbolFile/NativePDB/find-functions.cpp
@@ -1,7 +1,7 @@
// clang-format off
// REQUIRES: lld, x86
-// RUN: %clang_cl --target=x86_64-windows-msvc -Od -Z7 -c /Fo%t.obj -- %s
+// RUN: %clang_cl --target=x86_64-windows-msvc -Od -Z7 -c /GR- /Fo%t.obj -- %s
// RUN: lld-link -debug:full -nodefaultlib -entry:main %t.obj -out:%t.exe -pdb:%t.pdb
// RUN: lldb-test symbols --find=function --name=main --function-flags=full %t.exe \
@@ -13,6 +13,44 @@
// RUN: lldb-test symbols --find=function --name=varargs_fn --function-flags=full %t.exe \
// RUN: | FileCheck %s --check-prefix=FIND-VAR
+// RUN: lldb-test symbols --find=function --name=Struct::simple_method --function-flags=full %t.exe \
+// RUN: | FileCheck %s --check-prefix=FIND-SIMPLE
+
+// RUN: lldb-test symbols --find=function --name=Struct::virtual_method --function-flags=full %t.exe \
+// RUN: | FileCheck %s --check-prefix=FIND-VIRTUAL
+
+// RUN: lldb-test symbols --find=function --name=Struct::static_method --function-flags=full %t.exe \
+// RUN: | FileCheck %s --check-prefix=FIND-STATIC-METHOD
+
+// RUN: lldb-test symbols --find=function --name=Struct::overloaded_method --function-flags=full %t.exe \
+// RUN: | FileCheck %s --check-prefix=FIND-OVERLOAD
+
+struct Struct {
+ int simple_method() {
+ return 1;
+ }
+
+ virtual int virtual_method() {
+ return 2;
+ }
+
+ static int static_method() {
+ return 3;
+ }
+
+ int overloaded_method() {
+ return 4;
+ }
+ int overloaded_method(char c) {
+ return 5;
+ }
+ int overloaded_method(char c, int i, ...) {
+ return 6;
+ }
+};
+
+Struct s;
+
static int static_fn() {
return 42;
}
@@ -22,7 +60,9 @@
}
int main(int argc, char **argv) {
- return static_fn() + varargs_fn(argc, argc);
+ return static_fn() + varargs_fn(argc, argc) + s.simple_method() +
+ Struct::static_method() + s.virtual_method() + s.overloaded_method() +
+ s.overloaded_method('c') + s.overloaded_method('a', 1);
}
// FIND-MAIN: Function: id = {{.*}}, name = "main"
@@ -33,3 +73,17 @@
// FIND-VAR: Function: id = {{.*}}, name = "varargs_fn"
// FIND-VAR-NEXT: FuncType: id = {{.*}}, byte-size = 0, compiler_type = "int (int, int, ...)"
+
+// FIND-SIMPLE: Function: id = {{.*}}, name = "Struct::simple_method"
+// FIND-SIMPLE-NEXT: FuncType: id = {{.*}}, byte-size = 0, compiler_type = "int (void)"
+
+// FIND-VIRTUAL: Function: id = {{.*}}, name = "Struct::virtual_method"
+// FIND-VIRTUAL-NEXT: FuncType: id = {{.*}}, byte-size = 0, compiler_type = "int (void)"
+
+// FIND-STATIC-METHOD: Function: id = {{.*}}, name = "Struct::static_method"
+// FIND-STATIC-METHOD-NEXT: FuncType: id = {{.*}}, byte-size = 0, compiler_type = "int (void)"
+
+// FIND-OVERLOAD: Function: id = {{.*}}, name = "Struct::overloaded_method"
+// FIND-OVERLOAD: FuncType: id = {{.*}}, byte-size = 0, compiler_type = "int (void)"
+// FIND-OVERLOAD: FuncType: id = {{.*}}, byte-size = 0, compiler_type = "int (char)"
+// FIND-OVERLOAD: FuncType: id = {{.*}}, byte-size = 0, compiler_type = "int (char, int, ...)"
Index: lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
+++ lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
@@ -1014,8 +1014,87 @@
proc_name.consume_front(context_name);
proc_name.consume_front("::");
- clang::FunctionDecl *function_decl = m_clang.CreateFunctionDeclaration(
- parent, OptionalClangModuleID(), proc_name, func_ct, storage, false);
+ clang::FunctionDecl *function_decl = nullptr;
+ if (parent->isRecord()) {
+ struct ProcessOneMethodRecord : public TypeVisitorCallbacks {
+ ProcessOneMethodRecord(TypeSystemClang &m_clang,
+ clang::FunctionDecl *&function_decl,
+ lldb::opaque_compiler_type_t parent_ty,
+ llvm::StringRef proc_name, CompilerType func_ct)
+ : m_clang(m_clang), function_decl(function_decl),
+ parent_ty(parent_ty), proc_name(proc_name), func_ct(func_ct) {}
+ TypeSystemClang &m_clang;
+ clang::FunctionDecl *&function_decl;
+ lldb::opaque_compiler_type_t parent_ty;
+ llvm::StringRef proc_name;
+ CompilerType func_ct;
+
+ llvm::Error visitKnownMember(CVMemberRecord &CVR,
+ OneMethodRecord &Record) override {
+ if (Record.getName() != proc_name) {
+ return llvm::Error::success();
+ }
+ lldb::AccessType access = TranslateMemberAccess(Record.getAccess());
+ bool is_virtual = Record.Attrs.isVirtual();
+ bool is_static = Record.Attrs.isStatic();
+ bool is_artificial =
+ (Record.getOptions() & MethodOptions::CompilerGenerated) ==
+ MethodOptions::CompilerGenerated;
+ function_decl = m_clang.AddMethodToCXXRecordType(
+ parent_ty, proc_name,
+ /*mangled_name=*/nullptr, func_ct, /*access=*/access,
+ /*is_virtual=*/is_virtual, /*is_static=*/is_static,
+ /*is_inline=*/false, /*is_explicit=*/false,
+ /*is_attr_used=*/false, /*is_artificial=*/is_artificial);
+ return llvm::Error::success();
+ }
+ };
+
+ clang::QualType parent_qt = llvm::dyn_cast<clang::TypeDecl>(parent)
+ ->getTypeForDecl()
+ ->getCanonicalTypeInternal();
+ lldb::opaque_compiler_type_t parent_opaque_ty =
+ ToCompilerType(parent_qt).GetOpaqueQualType();
+
+ CVType cvt = m_index.tpi().getType(type_id.index);
+ MemberFunctionRecord func_record(static_cast<TypeRecordKind>(cvt.kind()));
+ llvm::cantFail(TypeDeserializer::deserializeAs<MemberFunctionRecord>(
+ cvt, func_record));
+ TypeIndex class_index = func_record.getClassType();
+ CVType parent_cvt = m_index.tpi().getType(class_index);
+ ClassRecord class_record = CVTagRecord::create(parent_cvt).asClass();
+ // If it's a forward reference, try to get the real TypeIndex.
+ if (class_record.isForwardRef()) {
+ llvm::Expected<TypeIndex> eti =
+ m_index.tpi().findFullDeclForForwardRef(class_index);
+ if (eti) {
+ class_record =
+ CVTagRecord::create(m_index.tpi().getType(*eti)).asClass();
+ }
+ }
+ if (!class_record.FieldList.isSimple()) {
+ CVType field_list = m_index.tpi().getType(class_record.FieldList);
+ ProcessOneMethodRecord process(m_clang, function_decl, parent_opaque_ty,
+ proc_name, func_ct);
+ if (llvm::Error err = visitMemberRecordStream(field_list.data(), process))
+ llvm::consumeError(std::move(err));
+ }
+
+ if (!function_decl) {
+ function_decl = m_clang.AddMethodToCXXRecordType(
+ parent_opaque_ty, proc_name,
+ /*mangled_name=*/nullptr, func_ct,
+ /*access=*/lldb::AccessType::eAccessPublic,
+ /*is_virtual=*/false, /*is_static=*/false,
+ /*is_inline=*/false, /*is_explicit=*/false,
+ /*is_attr_used=*/false, /*is_artificial=*/false);
+ }
+ } else {
+ function_decl = m_clang.CreateFunctionDeclaration(
+ parent, OptionalClangModuleID(), proc_name, func_ct, storage, false);
+ CreateFunctionParameters(func_id, *function_decl,
+ func_type->getNumParams());
+ }
lldbassert(m_uid_to_decl.count(toOpaqueUid(func_id)) == 0);
m_uid_to_decl[toOpaqueUid(func_id)] = function_decl;
@@ -1024,8 +1103,6 @@
status.uid = toOpaqueUid(func_id);
m_decl_to_status.insert({function_decl, status});
- CreateFunctionParameters(func_id, *function_decl, func_type->getNumParams());
-
return function_decl;
}
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits