<div dir="ltr">At least in theory it'd be nice to have test cases for the other call sites this change adds CC to.<br><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Jun 8, 2016 at 1:41 PM, Reid Kleckner via cfe-commits <span dir="ltr"><<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: rnk<br>
Date: Wed Jun  8 15:41:54 2016<br>
New Revision: 272198<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=272198&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=272198&view=rev</a><br>
Log:<br>
[DebugInfo] Add calling conventions to DISubroutineType<br>
<br>
Summary:<br>
This should have been a very simple change, but it was greatly<br>
complicated by the construction of new Decls during IR generation.<br>
<br>
In particular, we reconstruct the AST function type in order to get the<br>
implicit 'this' parameter into C++ method types.<br>
<br>
We also have to worry about FunctionDecls whose types are not<br>
FunctionTypes because CGBlocks.cpp constructs some dummy FunctionDecls<br>
with 'void' type.<br>
<br>
Depends on D21114<br>
<br>
Reviewers: aprantl, dblaikie<br>
<br>
Subscribers: cfe-commits<br>
<br>
Differential Revision: <a href="http://reviews.llvm.org/D21141" rel="noreferrer" target="_blank">http://reviews.llvm.org/D21141</a><br>
<br>
Added:<br>
    cfe/trunk/test/CodeGenCXX/debug-info-calling-conventions.cpp<br>
Modified:<br>
    cfe/trunk/lib/CodeGen/CGDebugInfo.cpp<br>
    cfe/trunk/lib/CodeGen/CodeGenFunction.cpp<br>
<br>
Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.cpp?rev=272198&r1=272197&r2=272198&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.cpp?rev=272198&r1=272197&r2=272198&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp Wed Jun  8 15:41:54 2016<br>
@@ -831,6 +831,39 @@ llvm::DIType *CGDebugInfo::CreateType(co<br>
       getDeclContextDescriptor(Ty->getDecl()));<br>
 }<br>
<br>
+static unsigned getDwarfCC(CallingConv CC) {<br>
+  switch (CC) {<br>
+  case CC_C:<br>
+    // Avoid emitting DW_AT_calling_convention if the C convention was used.<br>
+    return 0;<br>
+<br>
+  case CC_X86StdCall:<br>
+    return llvm::dwarf::DW_CC_BORLAND_stdcall;<br>
+  case CC_X86FastCall:<br>
+    return llvm::dwarf::DW_CC_BORLAND_msfastcall;<br>
+  case CC_X86ThisCall:<br>
+    return llvm::dwarf::DW_CC_BORLAND_thiscall;<br>
+  case CC_X86VectorCall:<br>
+    return llvm::dwarf::DW_CC_LLVM_vectorcall;<br>
+  case CC_X86Pascal:<br>
+    return llvm::dwarf::DW_CC_BORLAND_pascal;<br>
+<br>
+  // FIXME: Create new DW_CC_ codes for these calling conventions.<br>
+  case CC_X86_64Win64:<br>
+  case CC_X86_64SysV:<br>
+  case CC_AAPCS:<br>
+  case CC_AAPCS_VFP:<br>
+  case CC_IntelOclBicc:<br>
+  case CC_SpirFunction:<br>
+  case CC_SpirKernel:<br>
+  case CC_Swift:<br>
+  case CC_PreserveMost:<br>
+  case CC_PreserveAll:<br>
+    return 0;<br>
+  }<br>
+  return 0;<br>
+}<br>
+<br>
 llvm::DIType *CGDebugInfo::CreateType(const FunctionType *Ty,<br>
                                       llvm::DIFile *Unit) {<br>
   SmallVector<llvm::Metadata *, 16> EltTys;<br>
@@ -850,7 +883,8 @@ llvm::DIType *CGDebugInfo::CreateType(co<br>
   }<br>
<br>
   llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(EltTys);<br>
-  return DBuilder.createSubroutineType(EltTypeArray);<br>
+  return DBuilder.createSubroutineType(EltTypeArray, 0,<br>
+                                       getDwarfCC(Ty->getCallConv()));<br>
 }<br>
<br>
 /// Convert an AccessSpecifier into the corresponding DINode flag.<br>
@@ -1103,7 +1137,8 @@ llvm::DISubroutineType *CGDebugInfo::get<br>
   if (Func->getExtProtoInfo().RefQualifier == RQ_RValue)<br>
     Flags |= llvm::DINode::FlagRValueReference;<br>
<br>
-  return DBuilder.createSubroutineType(EltTypeArray, Flags);<br>
+  return DBuilder.createSubroutineType(EltTypeArray, Flags,<br>
+                                       getDwarfCC(Func->getCallConv()));<br>
 }<br>
<br>
 /// isFunctionLocalClass - Return true if CXXRecordDecl is defined<br>
@@ -2562,9 +2597,9 @@ CGDebugInfo::getFunctionForwardDeclarati<br>
   SmallVector<QualType, 16> ArgTypes;<br>
   for (const ParmVarDecl *Parm: FD->parameters())<br>
     ArgTypes.push_back(Parm->getType());<br>
-  QualType FnType =<br>
-    CGM.getContext().getFunctionType(FD->getReturnType(), ArgTypes,<br>
-                                     FunctionProtoType::ExtProtoInfo());<br>
+  CallingConv CC = FD->getType()->castAs<FunctionType>()->getCallConv();<br>
+  QualType FnType = CGM.getContext().getFunctionType(<br>
+      FD->getReturnType(), ArgTypes, FunctionProtoType::ExtProtoInfo(CC));<br>
   llvm::DISubprogram *SP = DBuilder.createTempFunctionFwdDecl(<br>
       DContext, Name, LinkageName, Unit, Line,<br>
       getOrCreateFunctionType(FD, FnType, Unit), !FD->isExternallyVisible(),<br>
@@ -2668,6 +2703,10 @@ llvm::DISubroutineType *CGDebugInfo::get<br>
<br>
   if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D))<br>
     return getOrCreateMethodType(Method, F);<br>
+<br>
+  const auto *FTy = FnType->getAs<FunctionType>();<br>
+  CallingConv CC = FTy ? FTy->getCallConv() : CallingConv::CC_C;<br>
+<br>
   if (const ObjCMethodDecl *OMethod = dyn_cast<ObjCMethodDecl>(D)) {<br>
     // Add "self" and "_cmd"<br>
     SmallVector<llvm::Metadata *, 16> Elts;<br>
@@ -2701,7 +2740,7 @@ llvm::DISubroutineType *CGDebugInfo::get<br>
       Elts.push_back(DBuilder.createUnspecifiedParameter());<br>
<br>
     llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);<br>
-    return DBuilder.createSubroutineType(EltTypeArray);<br>
+    return DBuilder.createSubroutineType(EltTypeArray, 0, getDwarfCC(CC));<br>
   }<br>
<br>
   // Handle variadic function types; they need an additional<br>
@@ -2715,7 +2754,7 @@ llvm::DISubroutineType *CGDebugInfo::get<br>
           EltTys.push_back(getOrCreateType(FPT->getParamType(i), F));<br>
       EltTys.push_back(DBuilder.createUnspecifiedParameter());<br>
       llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(EltTys);<br>
-      return DBuilder.createSubroutineType(EltTypeArray);<br>
+      return DBuilder.createSubroutineType(EltTypeArray, 0, getDwarfCC(CC));<br>
     }<br>
<br>
   return cast<llvm::DISubroutineType>(getOrCreateType(FnType, F));<br>
<br>
Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.cpp?rev=272198&r1=272197&r2=272198&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.cpp?rev=272198&r1=272197&r2=272198&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/CodeGen/CodeGenFunction.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.cpp Wed Jun  8 15:41:54 2016<br>
@@ -762,15 +762,18 @@ void CodeGenFunction::StartFunction(Glob<br>
<br>
   // Emit subprogram debug descriptor.<br>
   if (CGDebugInfo *DI = getDebugInfo()) {<br>
+    // Reconstruct the type from the argument list so that implicit parameters,<br>
+    // such as 'this' and 'vtt', show up in the debug info. Preserve the calling<br>
+    // convention.<br>
+    CallingConv CC = CallingConv::CC_C;<br>
+    if (auto *FD = dyn_cast_or_null<FunctionDecl>(D))<br>
+      if (const auto *SrcFnTy = FD->getType()->getAs<FunctionType>())<br>
+        CC = SrcFnTy->getCallConv();<br>
     SmallVector<QualType, 16> ArgTypes;<br>
-    for (FunctionArgList::const_iterator i = Args.begin(), e = Args.end();<br>
-        i != e; ++i) {<br>
-      ArgTypes.push_back((*i)->getType());<br>
-    }<br>
-<br>
-    QualType FnType =<br>
-      getContext().getFunctionType(RetTy, ArgTypes,<br>
-                                   FunctionProtoType::ExtProtoInfo());<br>
+    for (const VarDecl *VD : Args)<br>
+      ArgTypes.push_back(VD->getType());<br>
+    QualType FnType = getContext().getFunctionType(<br>
+        RetTy, ArgTypes, FunctionProtoType::ExtProtoInfo(CC));<br>
     DI->EmitFunctionStart(GD, Loc, StartLoc, FnType, CurFn, Builder);<br>
   }<br>
<br>
<br>
Added: cfe/trunk/test/CodeGenCXX/debug-info-calling-conventions.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/debug-info-calling-conventions.cpp?rev=272198&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/debug-info-calling-conventions.cpp?rev=272198&view=auto</a><br>
==============================================================================<br>
--- cfe/trunk/test/CodeGenCXX/debug-info-calling-conventions.cpp (added)<br>
+++ cfe/trunk/test/CodeGenCXX/debug-info-calling-conventions.cpp Wed Jun  8 15:41:54 2016<br>
@@ -0,0 +1,26 @@<br>
+// RUN: %clang_cc1 %s -triple=i686-pc-windows-msvc -debug-info-kind=limited -emit-llvm -o - | FileCheck %s<br>
+<br>
+struct A {<br>
+  void thiscallcc();<br>
+};<br>
+void A::thiscallcc() {}<br>
+<br>
+// CHECK: !DISubprogram(name: "thiscallcc", {{.*}} type: ![[thiscallty:[^,]*]], {{.*}})<br>
+// CHECK: ![[thiscallty]] = !DISubroutineType(cc: DW_CC_BORLAND_thiscall, types: ![[thisargs:[^,)]*]])<br>
+// CHECK: ![[thisargs]] = !{null, ![[thisptrty:[^,}]*]]}<br>
+// CHECK: ![[thisptrty]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !{{.*}}, size: 32, align: 32, flags: DIFlagArtificial | DIFlagObjectPointer)<br>
+<br>
+void cdeclcc() {}<br>
+void __fastcall fastcallcc() {}<br>
+void __stdcall stdcallcc() {}<br>
+void __vectorcall vectorcallcc() {}<br>
+<br>
+// CHECK: !DISubprogram(name: "cdeclcc", {{.*}} type: ![[cdeclty:[^,]*]], {{.*}})<br>
+// CHECK: ![[cdeclty]] = !DISubroutineType(types: ![[noargs:[^,)]*]])<br>
+// CHECK: ![[noargs]] = !{null}<br>
+// CHECK: !DISubprogram(name: "fastcallcc", {{.*}} type: ![[fastcallty:[^,]*]], {{.*}})<br>
+// CHECK: ![[fastcallty]] = !DISubroutineType(cc: DW_CC_BORLAND_msfastcall, types: ![[noargs]])<br>
+// CHECK: !DISubprogram(name: "stdcallcc", {{.*}} type: ![[stdcallty:[^,]*]], {{.*}})<br>
+// CHECK: ![[stdcallty]] = !DISubroutineType(cc: DW_CC_BORLAND_stdcall, types: ![[noargs]])<br>
+// CHECK: !DISubprogram(name: "vectorcallcc", {{.*}} type: ![[vectorcallty:[^,]*]], {{.*}})<br>
+// CHECK: ![[vectorcallty]] = !DISubroutineType(cc: DW_CC_LLVM_vectorcall, types: ![[noargs]])<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div></div>