aleksandr.urakov created this revision.
aleksandr.urakov added reviewers: clayborg, zturner, labath, asmith.
aleksandr.urakov added a project: LLDB.
Herald added subscribers: lldb-commits, teemperor.

This patch implements restoring of the calling convention from PDB. It is 
necessary for expressions evaluation, if we want to call a function of the 
debuggee process with a calling convention other than ccall.


Repository:
  rLLDB LLDB

https://reviews.llvm.org/D52501

Files:
  include/lldb/Symbol/ClangASTContext.h
  lit/SymbolFile/PDB/Inputs/AstRestoreTest.cpp
  lit/SymbolFile/PDB/ast-restore.test
  lit/SymbolFile/PDB/pointers.test
  source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
  source/Symbol/ClangASTContext.cpp

Index: source/Symbol/ClangASTContext.cpp
===================================================================
--- source/Symbol/ClangASTContext.cpp
+++ source/Symbol/ClangASTContext.cpp
@@ -2058,7 +2058,8 @@
 
 CompilerType ClangASTContext::CreateFunctionType(
     ASTContext *ast, const CompilerType &result_type, const CompilerType *args,
-    unsigned num_args, bool is_variadic, unsigned type_quals) {
+    unsigned num_args, bool is_variadic, unsigned type_quals,
+    clang::CallingConv cc) {
   if (ast == nullptr)
     return CompilerType(); // invalid AST
 
@@ -2086,6 +2087,7 @@
 
   // TODO: Detect calling convention in DWARF?
   FunctionProtoType::ExtProtoInfo proto_info;
+  proto_info.ExtInfo = cc;
   proto_info.Variadic = is_variadic;
   proto_info.ExceptionSpec = EST_None;
   proto_info.TypeQuals = type_quals;
Index: source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
===================================================================
--- source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
+++ source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
@@ -331,6 +331,26 @@
   return name == "`anonymous namespace'" || name == "`anonymous-namespace'";
 }
 
+static clang::CallingConv TranslateCallingConvention(PDB_CallingConv pdb_cc) {
+  switch (pdb_cc) {
+  case llvm::codeview::CallingConvention::NearC:
+    return clang::CC_C;
+  case llvm::codeview::CallingConvention::NearStdCall:
+    return clang::CC_X86StdCall;
+  case llvm::codeview::CallingConvention::NearFast:
+    return clang::CC_X86FastCall;
+  case llvm::codeview::CallingConvention::ThisCall:
+    return clang::CC_X86ThisCall;
+  case llvm::codeview::CallingConvention::NearVector:
+    return clang::CC_X86VectorCall;
+  case llvm::codeview::CallingConvention::NearPascal:
+    return clang::CC_X86Pascal;
+  default:
+    assert(false && "Unknown calling convention");
+    return clang::CC_C;
+  }
+}
+
 PDBASTParser::PDBASTParser(lldb_private::ClangASTContext &ast) : m_ast(ast) {}
 
 PDBASTParser::~PDBASTParser() {}
@@ -603,9 +623,10 @@
       type_quals |= clang::Qualifiers::Const;
     if (func_sig->isVolatileType())
       type_quals |= clang::Qualifiers::Volatile;
+    auto cc = TranslateCallingConvention(func_sig->getCallingConvention());
     CompilerType func_sig_ast_type =
         m_ast.CreateFunctionType(return_ast_type, arg_list.data(),
-                                 arg_list.size(), is_variadic, type_quals);
+                                 arg_list.size(), is_variadic, type_quals, cc);
 
     GetDeclarationForSymbol(type, decl);
     return std::make_shared<lldb_private::Type>(
Index: lit/SymbolFile/PDB/pointers.test
===================================================================
--- lit/SymbolFile/PDB/pointers.test
+++ lit/SymbolFile/PDB/pointers.test
@@ -28,7 +28,7 @@
 MAIN:     Variable{{.*}}, name = "p_member_field"
 MAIN-SAME:    (int ST::*), scope = local
 MAIN:     Variable{{.*}}, name = "p_member_method"
-MAIN-SAME:    (int (ST::*)(int)), scope = local
+MAIN-SAME:    (int (ST::*)(int) __attribute__((thiscall))), scope = local
 
 F:   Function{[[FID2:.*]]}, demangled = {{.*}}f(int)
 F-NEXT:  Block{[[FID2]]}
Index: lit/SymbolFile/PDB/ast-restore.test
===================================================================
--- lit/SymbolFile/PDB/ast-restore.test
+++ lit/SymbolFile/PDB/ast-restore.test
@@ -7,6 +7,7 @@
 RUN: lldb-test symbols -dump-ast %t.exe | FileCheck --check-prefix=CLASS %s
 RUN: lldb-test symbols -dump-ast %t.exe | FileCheck --check-prefix=INNER %s
 RUN: lldb-test symbols -dump-ast %t.exe | FileCheck --check-prefix=FOO %s
+RUN: lldb-test symbols -dump-ast %t.exe | FileCheck --check-prefix=CC %s
 RUN: lldb-test symbols -dump-ast %t.exe | FileCheck --check-prefix=MAIN %s
 
 ENUM: Module: {{.*}}
@@ -73,5 +74,10 @@
 FOO:     }
 FOO: }
 
+CC: Module: {{.*}}
+CC-DAG: int (*FuncStdCallPtr)() __attribute__((stdcall));
+CC-DAG: int (*FuncFastCallPtr)() __attribute__((fastcall));
+CC-DAG: int (*FuncVectorCallPtr)() __attribute__((vectorcall));
+
 MAIN: Module: {{.*}}
 MAIN: int main();
Index: lit/SymbolFile/PDB/Inputs/AstRestoreTest.cpp
===================================================================
--- lit/SymbolFile/PDB/Inputs/AstRestoreTest.cpp
+++ lit/SymbolFile/PDB/Inputs/AstRestoreTest.cpp
@@ -41,6 +41,13 @@
 } // namespace N1
 } // namespace N0
 
+int __stdcall FuncStdCall() { return 0; }
+auto FuncStdCallPtr = &FuncStdCall;
+int __fastcall FuncFastCall() { return 0; }
+auto FuncFastCallPtr = &FuncFastCall;
+int __vectorcall FuncVectorCall() { return 0; }
+auto FuncVectorCallPtr = &FuncVectorCall;
+
 int main() {
   N0::N1::foo();
   return 0;
Index: include/lldb/Symbol/ClangASTContext.h
===================================================================
--- include/lldb/Symbol/ClangASTContext.h
+++ include/lldb/Symbol/ClangASTContext.h
@@ -377,15 +377,34 @@
                                          const CompilerType &result_type,
                                          const CompilerType *args,
                                          unsigned num_args, bool is_variadic,
-                                         unsigned type_quals);
+                                         unsigned type_quals,
+                                         clang::CallingConv cc);
+
+  static CompilerType CreateFunctionType(clang::ASTContext *ast,
+                                         const CompilerType &result_type,
+                                         const CompilerType *args,
+                                         unsigned num_args, bool is_variadic,
+                                         unsigned type_quals) {
+    return ClangASTContext::CreateFunctionType(
+        ast, result_type, args, num_args, is_variadic, type_quals, clang::CC_C);
+  }
 
   CompilerType CreateFunctionType(const CompilerType &result_type,
                                   const CompilerType *args, unsigned num_args,
                                   bool is_variadic, unsigned type_quals) {
     return ClangASTContext::CreateFunctionType(
         getASTContext(), result_type, args, num_args, is_variadic, type_quals);
   }
 
+  CompilerType CreateFunctionType(const CompilerType &result_type,
+                                  const CompilerType *args, unsigned num_args,
+                                  bool is_variadic, unsigned type_quals,
+                                  clang::CallingConv cc) {
+    return ClangASTContext::CreateFunctionType(getASTContext(), result_type,
+                                               args, num_args, is_variadic,
+                                               type_quals, cc);
+  }
+
   clang::ParmVarDecl *CreateParameterDeclaration(const char *name,
                                                  const CompilerType &param_type,
                                                  int storage);
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to