[PATCH] D77979: [clang-tidy] modernize-use-using: Fix broken fixit with InjectedClassName

Matthias Gehre via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Sun Apr 12 12:16:42 PDT 2020


mgehre created this revision.
mgehre added reviewers: aaron.ballman, alexfh, hokein, njames93.
Herald added a subscriber: xazax.hun.
Herald added a project: clang.

Before this PR, `modernize-use-using` would transform the typedef in

  template <int A>
  struct InjectedClassName {
    typedef InjectedClassName b;
  };

into `using b = InjectedClassName<A>;` and

  template <int>
  struct InjectedClassNameWithUnnamedArgument {
    typedef InjectedClassNameWithUnnamedArgument b;
  };

into `using b = InjectedClassNameWithUnnamedArgument<>;`.
The first fixit is surprising because its different than the code
before, but the second fixit doesn't even compile.

This PR adds an option to the TypePrinter to print InjectedClassNameType without
template parameters (i.e. as written).


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D77979

Files:
  clang-tools-extra/clang-tidy/modernize/UseUsingCheck.cpp
  clang-tools-extra/test/clang-tidy/checkers/modernize-use-using.cpp
  clang/include/clang/AST/PrettyPrinter.h
  clang/lib/AST/TypePrinter.cpp


Index: clang/lib/AST/TypePrinter.cpp
===================================================================
--- clang/lib/AST/TypePrinter.cpp
+++ clang/lib/AST/TypePrinter.cpp
@@ -1305,7 +1305,12 @@
 
 void TypePrinter::printInjectedClassNameBefore(const InjectedClassNameType *T,
                                                raw_ostream &OS) {
-  printTemplateSpecializationBefore(T->getInjectedTST(), OS);
+  if (Policy.PrintInjectedClassNameWithArguments)
+    return printTemplateSpecializationBefore(T->getInjectedTST(), OS);
+
+  IncludeStrongLifetimeRAII Strong(Policy);
+  T->getTemplateName().print(OS, Policy);
+  spaceBeforePlaceHolder(OS);
 }
 
 void TypePrinter::printInjectedClassNameAfter(const InjectedClassNameType *T,
Index: clang/include/clang/AST/PrettyPrinter.h
===================================================================
--- clang/include/clang/AST/PrettyPrinter.h
+++ clang/include/clang/AST/PrettyPrinter.h
@@ -63,7 +63,7 @@
         MSWChar(LO.MicrosoftExt && !LO.WChar), IncludeNewlines(true),
         MSVCFormatting(false), ConstantsAsWritten(false),
         SuppressImplicitBase(false), FullyQualifiedName(false),
-        PrintCanonicalTypes(false) {}
+        PrintCanonicalTypes(false), PrintInjectedClassNameWithArguments(true) {}
 
   /// Adjust this printing policy for cases where it's known that we're
   /// printing C++ code (for instance, if AST dumping reaches a C++-only
@@ -244,6 +244,11 @@
   /// Whether to print types as written or canonically.
   unsigned PrintCanonicalTypes : 1;
 
+  /// Whether to print an InjectedClassNameType with template arguments or as
+  /// written. When a template arguments are unnamed, printing them results in
+  /// invalid C++ code.
+  unsigned PrintInjectedClassNameWithArguments : 1;
+
   /// Callbacks to use to allow the behavior of printing to be customized.
   const PrintingCallbacks *Callbacks = nullptr;
 };
Index: clang-tools-extra/test/clang-tidy/checkers/modernize-use-using.cpp
===================================================================
--- clang-tools-extra/test/clang-tidy/checkers/modernize-use-using.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/modernize-use-using.cpp
@@ -278,3 +278,16 @@
 // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
 // CHECK-FIXES: using EnumT2_CheckTypedefImpactFromAnotherFile = enum { ea2, eb2 };
 
+template <int A>
+struct InjectedClassName {
+  typedef InjectedClassName b;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use 'using' instead of 'typedef'
+  // CHECK-FIXES: using b = InjectedClassName;
+};
+
+template <int>
+struct InjectedClassNameWithUnnamedArgument {
+  typedef InjectedClassNameWithUnnamedArgument b;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use 'using' instead of 'typedef'
+  // CHECK-FIXES: using b = InjectedClassNameWithUnnamedArgument;
+};
Index: clang-tools-extra/clang-tidy/modernize/UseUsingCheck.cpp
===================================================================
--- clang-tools-extra/clang-tidy/modernize/UseUsingCheck.cpp
+++ clang-tools-extra/clang-tidy/modernize/UseUsingCheck.cpp
@@ -58,6 +58,7 @@
   printPolicy.SuppressScope = true;
   printPolicy.ConstantArraySizeAsWritten = true;
   printPolicy.UseVoidForZeroParams = false;
+  printPolicy.PrintInjectedClassNameWithArguments = false;
 
   std::string Type = MatchedDecl->getUnderlyingType().getAsString(printPolicy);
   std::string Name = MatchedDecl->getNameAsString();


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D77979.256872.patch
Type: text/x-patch
Size: 3455 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20200412/4baae640/attachment.bin>


More information about the cfe-commits mailing list