[clang] e4b9f5e - DebugInfo: Add support for template parameters with reference qualifiers

David Blaikie via cfe-commits cfe-commits at lists.llvm.org
Tue Sep 14 00:40:44 PDT 2021


Author: David Blaikie
Date: 2021-09-14T00:39:47-07:00
New Revision: e4b9f5e851d1fe0ba93cbb11b2ed4558602c379e

URL: https://github.com/llvm/llvm-project/commit/e4b9f5e851d1fe0ba93cbb11b2ed4558602c379e
DIFF: https://github.com/llvm/llvm-project/commit/e4b9f5e851d1fe0ba93cbb11b2ed4558602c379e.diff

LOG: DebugInfo: Add support for template parameters with reference qualifiers

Followon from the previous commit supporting cvr qualifiers.

Added: 
    

Modified: 
    clang/lib/CodeGen/CGDebugInfo.cpp
    clang/test/CodeGenCXX/debug-info-template.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index b7a6cd4fdf84..e4dc3121a10f 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -1338,6 +1338,15 @@ static unsigned getDwarfCC(CallingConv CC) {
   return 0;
 }
 
+static llvm::DINode::DIFlags getRefFlags(const FunctionProtoType *Func) {
+  llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
+  if (Func->getExtProtoInfo().RefQualifier == RQ_LValue)
+    Flags |= llvm::DINode::FlagLValueReference;
+  if (Func->getExtProtoInfo().RefQualifier == RQ_RValue)
+    Flags |= llvm::DINode::FlagRValueReference;
+  return Flags;
+}
+
 llvm::DIType *CGDebugInfo::CreateType(const FunctionType *Ty,
                                       llvm::DIFile *Unit) {
   const auto *FPT = dyn_cast<FunctionProtoType>(Ty);
@@ -1353,11 +1362,13 @@ llvm::DIType *CGDebugInfo::CreateType(const FunctionType *Ty,
   // Add the result type at least.
   EltTys.push_back(getOrCreateType(Ty->getReturnType(), Unit));
 
+  llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
   // Set up remainder of arguments if there is a prototype.
   // otherwise emit it as a variadic function.
   if (!FPT)
     EltTys.push_back(DBuilder.createUnspecifiedParameter());
   else {
+    Flags = getRefFlags(FPT);
     for (const QualType &ParamType : FPT->param_types())
       EltTys.push_back(getOrCreateType(ParamType, Unit));
     if (FPT->isVariadic())
@@ -1365,7 +1376,7 @@ llvm::DIType *CGDebugInfo::CreateType(const FunctionType *Ty,
   }
 
   llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(EltTys);
-  llvm::DIType *F = DBuilder.createSubroutineType(EltTypeArray, llvm::DINode::FlagZero,
+  llvm::DIType *F = DBuilder.createSubroutineType(EltTypeArray, Flags,
                                        getDwarfCC(Ty->getCallConv()));
   return F;
 }
@@ -1640,15 +1651,17 @@ CGDebugInfo::getOrCreateInstanceMethodType(QualType ThisPtr,
   Qc.removeUnaligned();
   // Keep the removed qualifiers in sync with
   // CreateQualifiedType(const FunctionPrototype*, DIFile *Unit)
+  // on a 'real' member function type, these qualifiers are carried on the type
+  // of the first parameter, not as separate DW_TAG_const_type (etc) decorator
+  // tags around them. (but in the raw function types with qualifiers, they have
+  // to use wrapper types)
 
   // Add "this" pointer.
-  llvm::DITypeRefArray Args(
-      cast<llvm::DISubroutineType>(
-          getOrCreateType(
-              CGM.getContext().getFunctionType(Func->getReturnType(),
-                                               Func->getParamTypes(), EPI),
-              Unit))
-          ->getTypeArray());
+  const auto *OriginalFunc = cast<llvm::DISubroutineType>(
+      getOrCreateType(CGM.getContext().getFunctionType(
+                          Func->getReturnType(), Func->getParamTypes(), EPI),
+                      Unit));
+  llvm::DITypeRefArray Args = OriginalFunc->getTypeArray();
   assert(Args.size() && "Invalid number of arguments!");
 
   SmallVector<llvm::Metadata *, 16> Elts;
@@ -1690,13 +1703,7 @@ CGDebugInfo::getOrCreateInstanceMethodType(QualType ThisPtr,
 
   llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);
 
-  llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
-  if (Func->getExtProtoInfo().RefQualifier == RQ_LValue)
-    Flags |= llvm::DINode::FlagLValueReference;
-  if (Func->getExtProtoInfo().RefQualifier == RQ_RValue)
-    Flags |= llvm::DINode::FlagRValueReference;
-
-  return DBuilder.createSubroutineType(EltTypeArray, Flags,
+  return DBuilder.createSubroutineType(EltTypeArray, OriginalFunc->getFlags(),
                                        getDwarfCC(Func->getCallConv()));
 }
 

diff  --git a/clang/test/CodeGenCXX/debug-info-template.cpp b/clang/test/CodeGenCXX/debug-info-template.cpp
index 0abb669b6535..510c82a5074f 100644
--- a/clang/test/CodeGenCXX/debug-info-template.cpp
+++ b/clang/test/CodeGenCXX/debug-info-template.cpp
@@ -218,13 +218,13 @@ template void f1<>();
 
 namespace RawFuncQual {
 struct t1; // use this to ensure the type parameter doesn't shift due to other test cases in this file
-template<typename T1, typename T2>
+template<typename T1, typename T2, typename T3, typename T4>
 void f1() { }
-template void f1<t1 () volatile, t1 () const volatile>();
-// CHECK: !DISubprogram(name: "f1<RawFuncQual::t1 () volatile, RawFuncQual::t1 () const volatile>", 
+template void f1<t1 () volatile, t1 () const volatile, t1 () &, t1 () &&>();
+// CHECK: !DISubprogram(name: "f1<RawFuncQual::t1 () volatile, RawFuncQual::t1 () const volatile, RawFuncQual::t1 () &, RawFuncQual::t1 () &&>", 
 // CHECK-SAME: templateParams: ![[RAW_FUNC_QUAL_ARGS:[0-9]*]],
 
-// CHECK: ![[RAW_FUNC_QUAL_ARGS]] = !{![[RAW_FUNC_QUAL_T1:[0-9]*]], ![[RAW_FUNC_QUAL_T2:[0-9]*]]}
+// CHECK: ![[RAW_FUNC_QUAL_ARGS]] = !{![[RAW_FUNC_QUAL_T1:[0-9]*]], ![[RAW_FUNC_QUAL_T2:[0-9]*]], ![[RAW_FUNC_QUAL_T3:[0-9]*]], ![[RAW_FUNC_QUAL_T4:[0-9]*]]}
 // CHECK: ![[RAW_FUNC_QUAL_T1]] = !DITemplateTypeParameter(name: "T1", type: ![[RAW_FUNC_QUAL_VOL:[0-9]*]]) 
 // CHECK: ![[RAW_FUNC_QUAL_VOL]] = !DIDerivedType(tag: DW_TAG_volatile_type, baseType: ![[RAW_FUNC_QUAL_TYPE:[0-9]*]])
 // CHECK: ![[RAW_FUNC_QUAL_TYPE]] = !DISubroutineType(types: ![[RAW_FUNC_QUAL_LIST:[0-9]*]]
@@ -232,5 +232,9 @@ template void f1<t1 () volatile, t1 () const volatile>();
 // CHECK: ![[RAW_FUNC_QUAL_STRUCT]] = !DICompositeType(tag: DW_TAG_structure_type, name: "t1"
 // CHECK: ![[RAW_FUNC_QUAL_T2]] = !DITemplateTypeParameter(name: "T2", type: ![[RAW_FUNC_QUAL_CNST:[0-9]*]]) 
 // CHECK: ![[RAW_FUNC_QUAL_CNST]] = !DIDerivedType(tag: DW_TAG_const_type, baseType: ![[RAW_FUNC_QUAL_TYPE:[0-9]*]])
+// CHECK: ![[RAW_FUNC_QUAL_T3]] = !DITemplateTypeParameter(name: "T3", type: ![[RAW_FUNC_QUAL_REF:[0-9]*]]) 
+// CHECK: ![[RAW_FUNC_QUAL_REF]] = !DISubroutineType(flags: DIFlagLValueReference, types: ![[RAW_FUNC_QUAL_LIST]])
+// CHECK: ![[RAW_FUNC_QUAL_T4]] = !DITemplateTypeParameter(name: "T4", type: ![[RAW_FUNC_QUAL_REF_REF:[0-9]*]]) 
+// CHECK: ![[RAW_FUNC_QUAL_REF_REF]] = !DISubroutineType(flags: DIFlagRValueReference, types: ![[RAW_FUNC_QUAL_LIST]])
 
 } // namespace RawFuncQual


        


More information about the cfe-commits mailing list