<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>