[PATCH] D39622: Fix type debug information generation for enum-based template specialization

Anton via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Fri Nov 3 16:16:02 PDT 2017


xgsa created this revision.
xgsa added a project: clang.
Herald added a subscriber: aprantl.

Currently, there is an inconsistency between type name record in ".apple_types" section and entry in symbols table for the same type. In particular, for such types lldb is unable to resolve the real type using RTTI. Consider an example:

  enum class TagType : bool
  {
      Tag1
  };
  
  class I
  {
  };
  
  template <TagType Tag>
  class Impl : public I
  {
  private:
      int v = 123;    
  };
  
  int main(int argc, const char * argv[]) {
      Impl<TagType::Tag1> impl;
      I& i = impl;
      return 0;  // [*]
  }

For such code clang generates class name "Impl<TagType::Tag1>" into ".apple_types" and "Impl<(TagType)0>" into symbols table. Thus at point [*], the lldb is unable to resolve the real type of the "i" variable (shows the type as "I&"), whereas it is expected to be "Impl<TagType::Tag1>" or "Impl<(TagType)0>".

This patch fixes the issue. I haven't found the existing ticket in bugzilla for the described issue (https://bugs.llvm.org/show_bug.cgi?id=24198 -- this one looks similar, but it's not the same and actually it is not reproducible anymore).


Repository:
  rL LLVM

https://reviews.llvm.org/D39622

Files:
  include/clang/AST/PrettyPrinter.h
  lib/AST/TemplateBase.cpp
  lib/CodeGen/CGDebugInfo.cpp


Index: lib/CodeGen/CGDebugInfo.cpp
===================================================================
--- lib/CodeGen/CGDebugInfo.cpp
+++ lib/CodeGen/CGDebugInfo.cpp
@@ -234,6 +234,7 @@
   if (CGM.getCodeGenOpts().EmitCodeView)
     PP.MSVCFormatting = true;
 
+  PP.ABICompatibleFormatting = true;
   return PP;
 }
 
Index: lib/AST/TemplateBase.cpp
===================================================================
--- lib/AST/TemplateBase.cpp
+++ lib/AST/TemplateBase.cpp
@@ -41,14 +41,22 @@
   const llvm::APSInt &Val = TemplArg.getAsIntegral();
 
   if (const EnumType *ET = T->getAs<EnumType>()) {
-    for (const EnumConstantDecl* ECD : ET->getDecl()->enumerators()) {
-      // In Sema::CheckTemplateArugment, enum template arguments value are
-      // extended to the size of the integer underlying the enum type.  This
-      // may create a size difference between the enum value and template
-      // argument value, requiring isSameValue here instead of operator==.
-      if (llvm::APSInt::isSameValue(ECD->getInitVal(), Val)) {
-        ECD->printQualifiedName(Out, Policy);
-        return;
+    if (Policy.ABICompatibleFormatting) {
+      Out << "(";
+      ET->getDecl()->getNameForDiagnostic(Out, Policy, true);
+      Out << ")";
+      Out << Val;
+      return;
+    } else {
+      for (const EnumConstantDecl* ECD : ET->getDecl()->enumerators()) {
+        // In Sema::CheckTemplateArugment, enum template arguments value are
+        // extended to the size of the integer underlying the enum type.  This
+        // may create a size difference between the enum value and template
+        // argument value, requiring isSameValue here instead of operator==.
+        if (llvm::APSInt::isSameValue(ECD->getInitVal(), Val)) {
+          ECD->printQualifiedName(Out, Policy);
+          return;
+        }
       }
     }
   }
Index: include/clang/AST/PrettyPrinter.h
===================================================================
--- include/clang/AST/PrettyPrinter.h
+++ include/clang/AST/PrettyPrinter.h
@@ -51,7 +51,8 @@
       TerseOutput(false), PolishForDeclaration(false),
       Half(LO.Half), MSWChar(LO.MicrosoftExt && !LO.WChar),
       IncludeNewlines(true), MSVCFormatting(false),
-      ConstantsAsWritten(false), SuppressImplicitBase(false) { }
+      ConstantsAsWritten(false), SuppressImplicitBase(false),
+      ABICompatibleFormatting(false) { }
 
   /// \brief Adjust this printing policy for cases where it's known that
   /// we're printing C++ code (for instance, if AST dumping reaches a
@@ -64,7 +65,7 @@
   }
 
   /// \brief The number of spaces to use to indent each line.
-  unsigned Indentation : 8;
+  unsigned Indentation : 7;
 
   /// \brief Whether we should suppress printing of the actual specifiers for
   /// the given type or declaration.
@@ -222,6 +223,13 @@
 
   /// \brief When true, don't print the implicit 'self' or 'this' expressions.
   bool SuppressImplicitBase : 1;
+
+  /// \brief Use formatting compatible with ABI specification. It is necessary for
+  /// saving entities into debug tables which have to be compatible with
+  /// the representation, described in ABI specification. In particular, this forces
+  /// templates parametrized with enums to be represented as "T<(Enum)0>" instead of
+  /// "T<Enum::Item0>".
+  bool ABICompatibleFormatting : 1;
 };
 
 } // end namespace clang


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D39622.121557.patch
Type: text/x-patch
Size: 3375 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20171103/48dc0cd4/attachment.bin>


More information about the cfe-commits mailing list