forked from OSchip/llvm-project
[NativePDB] Add basic support of methods recostruction in AST
Summary: This patch adds the basic support of methods reconstruction by native PDB plugin. It contains only most obvious changes (it processes LF_ONEMETHOD and LF_METHOD records), some things still remain unsolved: - mangled names retrieving; - support of template methods. Reviewers: zturner, labath, lemo, stella.stamenova Reviewed by: zturner Differential Revision: https://reviews.llvm.org/D56126 llvm-svn: 352464
This commit is contained in:
parent
015f97db8b
commit
ee7c61f10e
|
@ -0,0 +1,5 @@
|
|||
target variable s
|
||||
|
||||
target modules dump ast
|
||||
|
||||
quit
|
|
@ -0,0 +1,36 @@
|
|||
// clang-format off
|
||||
// REQUIRES: lld
|
||||
|
||||
// RUN: %build --compiler=clang-cl --nodefaultlib -o %t.exe -- %s
|
||||
// RUN: env LLDB_USE_NATIVE_PDB_READER=1 %lldb -f %t.exe -s \
|
||||
// RUN: %p/Inputs/ast-methods.lldbinit 2>&1 | FileCheck %s
|
||||
|
||||
struct Struct {
|
||||
void simple_method() {}
|
||||
|
||||
virtual void virtual_method() {}
|
||||
|
||||
static void static_method() {}
|
||||
|
||||
int overloaded_method() {}
|
||||
int overloaded_method(char c) {}
|
||||
int overloaded_method(char c, int i, ...) {}
|
||||
};
|
||||
|
||||
Struct s;
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// CHECK: TranslationUnitDecl
|
||||
// CHECK: |-CXXRecordDecl {{.*}} struct Struct definition
|
||||
// CHECK: | |-CXXMethodDecl {{.*}} simple_method 'void (){{.*}}'
|
||||
// CHECK: | |-CXXMethodDecl {{.*}} virtual_method 'void (){{.*}}' virtual
|
||||
// CHECK: | |-CXXMethodDecl {{.*}} static_method 'void ()' static
|
||||
// CHECK: | |-CXXMethodDecl {{.*}} overloaded_method 'int (){{.*}}'
|
||||
// CHECK: | |-CXXMethodDecl {{.*}} overloaded_method 'int (char){{.*}}'
|
||||
// CHECK: | | `-ParmVarDecl {{.*}} 'char'
|
||||
// CHECK: | `-CXXMethodDecl {{.*}} overloaded_method 'int (char, int, ...)'
|
||||
// CHECK: | |-ParmVarDecl {{.*}} 'char'
|
||||
// CHECK: | `-ParmVarDecl {{.*}} 'int'
|
|
@ -933,7 +933,14 @@ clang::QualType PdbAstBuilder::CreateType(PdbTypeSymId type) {
|
|||
if (cvt.kind() == LF_PROCEDURE) {
|
||||
ProcedureRecord pr;
|
||||
llvm::cantFail(TypeDeserializer::deserializeAs<ProcedureRecord>(cvt, pr));
|
||||
return CreateProcedureType(pr);
|
||||
return CreateFunctionType(pr.ArgumentList, pr.ReturnType, pr.CallConv);
|
||||
}
|
||||
|
||||
if (cvt.kind() == LF_MFUNCTION) {
|
||||
MemberFunctionRecord mfr;
|
||||
llvm::cantFail(
|
||||
TypeDeserializer::deserializeAs<MemberFunctionRecord>(cvt, mfr));
|
||||
return CreateFunctionType(mfr.ArgumentList, mfr.ReturnType, mfr.CallConv);
|
||||
}
|
||||
|
||||
return {};
|
||||
|
@ -1117,10 +1124,11 @@ clang::QualType PdbAstBuilder::CreateArrayType(const ArrayRecord &ar) {
|
|||
return clang::QualType::getFromOpaquePtr(array_ct.GetOpaqueQualType());
|
||||
}
|
||||
|
||||
clang::QualType
|
||||
PdbAstBuilder::CreateProcedureType(const ProcedureRecord &proc) {
|
||||
clang::QualType PdbAstBuilder::CreateFunctionType(
|
||||
TypeIndex args_type_idx, TypeIndex return_type_idx,
|
||||
llvm::codeview::CallingConvention calling_convention) {
|
||||
TpiStream &stream = m_index.tpi();
|
||||
CVType args_cvt = stream.getType(proc.ArgumentList);
|
||||
CVType args_cvt = stream.getType(args_type_idx);
|
||||
ArgListRecord args;
|
||||
llvm::cantFail(
|
||||
TypeDeserializer::deserializeAs<ArgListRecord>(args_cvt, args));
|
||||
|
@ -1138,10 +1146,10 @@ PdbAstBuilder::CreateProcedureType(const ProcedureRecord &proc) {
|
|||
arg_types.push_back(ToCompilerType(arg_type));
|
||||
}
|
||||
|
||||
clang::QualType return_type = GetOrCreateType(proc.ReturnType);
|
||||
clang::QualType return_type = GetOrCreateType(return_type_idx);
|
||||
|
||||
llvm::Optional<clang::CallingConv> cc =
|
||||
TranslateCallingConvention(proc.CallConv);
|
||||
TranslateCallingConvention(calling_convention);
|
||||
if (!cc)
|
||||
return {};
|
||||
|
||||
|
|
|
@ -102,7 +102,8 @@ private:
|
|||
clang::QualType CreateEnumType(PdbTypeSymId id,
|
||||
const llvm::codeview::EnumRecord &record);
|
||||
clang::QualType
|
||||
CreateProcedureType(const llvm::codeview::ProcedureRecord &proc);
|
||||
CreateFunctionType(TypeIndex args_type_idx, TypeIndex return_type_idx,
|
||||
llvm::codeview::CallingConvention calling_convention);
|
||||
clang::QualType CreateType(PdbTypeSymId type);
|
||||
|
||||
void CreateFunctionParameters(PdbCompilandSymId func_id,
|
||||
|
|
|
@ -65,6 +65,22 @@ clang::QualType UdtRecordCompleter::AddBaseClassForTypeIndex(
|
|||
return qt;
|
||||
}
|
||||
|
||||
void UdtRecordCompleter::AddMethod(llvm::StringRef name, TypeIndex type_idx,
|
||||
MemberAccess access, MethodOptions options,
|
||||
MemberAttributes attrs) {
|
||||
clang::QualType method_qt =
|
||||
m_ast_builder.GetOrCreateType(PdbTypeSymId(type_idx));
|
||||
m_ast_builder.CompleteType(method_qt);
|
||||
|
||||
lldb::AccessType access_type = TranslateMemberAccess(access);
|
||||
bool is_artificial = (options & MethodOptions::CompilerGenerated) ==
|
||||
MethodOptions::CompilerGenerated;
|
||||
m_ast_builder.clang().AddMethodToCXXRecordType(
|
||||
m_derived_ct.GetOpaqueQualType(), name.data(), nullptr,
|
||||
m_ast_builder.ToCompilerType(method_qt), access_type, attrs.isVirtual(),
|
||||
attrs.isStatic(), false, false, false, is_artificial);
|
||||
}
|
||||
|
||||
Error UdtRecordCompleter::visitKnownMember(CVMemberRecord &cvr,
|
||||
BaseClassRecord &base) {
|
||||
clang::QualType base_qt =
|
||||
|
@ -158,11 +174,27 @@ Error UdtRecordCompleter::visitKnownMember(CVMemberRecord &cvr,
|
|||
|
||||
Error UdtRecordCompleter::visitKnownMember(CVMemberRecord &cvr,
|
||||
OneMethodRecord &one_method) {
|
||||
AddMethod(one_method.Name, one_method.Type, one_method.getAccess(),
|
||||
one_method.getOptions(), one_method.Attrs);
|
||||
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
Error UdtRecordCompleter::visitKnownMember(CVMemberRecord &cvr,
|
||||
OverloadedMethodRecord &overloaded) {
|
||||
TypeIndex method_list_idx = overloaded.MethodList;
|
||||
|
||||
CVType method_list_type = m_tpi.getType(method_list_idx);
|
||||
assert(method_list_type.Type == LF_METHODLIST);
|
||||
|
||||
MethodOverloadListRecord method_list;
|
||||
llvm::cantFail(TypeDeserializer::deserializeAs<MethodOverloadListRecord>(
|
||||
method_list_type, method_list));
|
||||
|
||||
for (const OneMethodRecord &method : method_list.Methods)
|
||||
AddMethod(overloaded.Name, method.Type, method.getAccess(),
|
||||
method.getOptions(), method.Attrs);
|
||||
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
|
|
|
@ -66,6 +66,10 @@ public:
|
|||
private:
|
||||
clang::QualType AddBaseClassForTypeIndex(llvm::codeview::TypeIndex ti,
|
||||
llvm::codeview::MemberAccess access);
|
||||
void AddMethod(llvm::StringRef name, llvm::codeview::TypeIndex type_idx,
|
||||
llvm::codeview::MemberAccess access,
|
||||
llvm::codeview::MethodOptions options,
|
||||
llvm::codeview::MemberAttributes attrs);
|
||||
};
|
||||
|
||||
} // namespace npdb
|
||||
|
|
Loading…
Reference in New Issue