jdenny updated this revision to Diff 141715.
jdenny added a comment.

Rebased onto a more recent master.


https://reviews.llvm.org/D45093

Files:
  include/clang/AST/ASTContext.h
  include/clang/Sema/Sema.h
  lib/Parse/ParseDecl.cpp
  lib/Sema/Sema.cpp
  lib/Sema/SemaChecking.cpp
  lib/Sema/SemaCodeComplete.cpp
  lib/Sema/SemaDecl.cpp
  lib/Sema/SemaDeclCXX.cpp
  lib/Sema/SemaExceptionSpec.cpp
  lib/Sema/SemaExprCXX.cpp
  lib/Sema/SemaLookup.cpp
  lib/Sema/SemaOverload.cpp
  lib/Sema/SemaTemplate.cpp
  lib/Sema/SemaTemplateInstantiate.cpp
  test/Misc/ast-print-bool.c

Index: test/Misc/ast-print-bool.c
===================================================================
--- /dev/null
+++ test/Misc/ast-print-bool.c
@@ -0,0 +1,44 @@
+// RUN: %clang_cc1 -verify -ast-print %s -xc -DDEF_BOOL_CBOOL \
+// RUN: | FileCheck %s --check-prefixes=BOOL-AS-CBOOL,CBOOL
+//
+// RUN: %clang_cc1 -verify -ast-print %s -xc -DDEF_BOOL_CBOOL -DDIAG \
+// RUN: | FileCheck %s --check-prefixes=BOOL-AS-CBOOL,CBOOL
+//
+// RUN: %clang_cc1 -verify -ast-print %s -xc -DDEF_BOOL_INT \
+// RUN: | FileCheck %s --check-prefixes=BOOL-AS-INT,CBOOL
+//
+// RUN: %clang_cc1 -verify -ast-print %s -xc -DDEF_BOOL_INT -DDIAG \
+// RUN: | FileCheck %s --check-prefixes=BOOL-AS-INT,CBOOL
+//
+// RUN: %clang_cc1 -verify -ast-print %s -xc++ \
+// RUN: | FileCheck %s --check-prefixes=BOOL-AS-BOOL
+//
+// RUN: %clang_cc1 -verify -ast-print %s -xc++ -DDIAG \
+// RUN: | FileCheck %s --check-prefixes=BOOL-AS-BOOL
+
+#if DEF_BOOL_CBOOL
+# define bool _Bool
+#elif DEF_BOOL_INT
+# define bool int
+#endif
+
+// BOOL-AS-CBOOL: _Bool i;
+// BOOL-AS-INT:   int i;
+// BOOL-AS-BOOL:  bool i;
+bool i;
+
+#ifndef __cplusplus
+// CBOOL: _Bool j;
+_Bool j;
+#endif
+
+// Induce a diagnostic (and verify we actually managed to do so), which used to
+// permanently alter the -ast-print printing policy for _Bool.  How bool is
+// defined by the preprocessor is examined only once per compilation, when the
+// diagnostic is emitted, and it used to affect the entirety of -ast-print, so
+// test only one definition of bool per compilation.
+#if DIAG
+void fn() { 1; } // expected-warning {{expression result unused}}
+#else
+// expected-no-diagnostics
+#endif
Index: lib/Sema/SemaTemplateInstantiate.cpp
===================================================================
--- lib/Sema/SemaTemplateInstantiate.cpp
+++ lib/Sema/SemaTemplateInstantiate.cpp
@@ -505,7 +505,7 @@
       llvm::raw_svector_ostream OS(TemplateArgsStr);
       Template->printName(OS);
       printTemplateArgumentList(OS, Active->template_arguments(),
-                                getPrintingPolicy());
+                                getDiagPrintingPolicy());
       Diags.Report(Active->PointOfInstantiation,
                    diag::note_default_arg_instantiation_here)
         << OS.str()
@@ -571,7 +571,7 @@
       llvm::raw_svector_ostream OS(TemplateArgsStr);
       FD->printName(OS);
       printTemplateArgumentList(OS, Active->template_arguments(),
-                                getPrintingPolicy());
+                                getDiagPrintingPolicy());
       Diags.Report(Active->PointOfInstantiation,
                    diag::note_default_function_arg_instantiation_here)
         << OS.str()
Index: lib/Sema/SemaTemplate.cpp
===================================================================
--- lib/Sema/SemaTemplate.cpp
+++ lib/Sema/SemaTemplate.cpp
@@ -3012,7 +3012,7 @@
   std::string Description;
   {
     llvm::raw_string_ostream Out(Description);
-    FailedCond->printPretty(Out, nullptr, getPrintingPolicy());
+    FailedCond->printPretty(Out, nullptr, getDiagPrintingPolicy());
   }
   return { FailedCond, Description };
 }
@@ -9821,7 +9821,7 @@
     }
 
     Out << " = ";
-    Args[I].print(getPrintingPolicy(), Out);
+    Args[I].print(getDiagPrintingPolicy(), Out);
   }
 
   Out << ']';
Index: lib/Sema/SemaOverload.cpp
===================================================================
--- lib/Sema/SemaOverload.cpp
+++ lib/Sema/SemaOverload.cpp
@@ -5546,7 +5546,7 @@
     // conversion; use it.
     QualType ConvTy = Conversion->getConversionType().getNonReferenceType();
     std::string TypeStr;
-    ConvTy.getAsStringInternal(TypeStr, SemaRef.getPrintingPolicy());
+    ConvTy.getAsStringInternal(TypeStr, SemaRef.getDiagPrintingPolicy());
 
     Converter.diagnoseExplicitConv(SemaRef, Loc, T, ConvTy)
         << FixItHint::CreateInsertion(From->getLocStart(),
Index: lib/Sema/SemaLookup.cpp
===================================================================
--- lib/Sema/SemaLookup.cpp
+++ lib/Sema/SemaLookup.cpp
@@ -4202,7 +4202,7 @@
           std::string NewQualified = TC.getAsString(SemaRef.getLangOpts());
           std::string OldQualified;
           llvm::raw_string_ostream OldOStream(OldQualified);
-          SS->getScopeRep()->print(OldOStream, SemaRef.getPrintingPolicy());
+          SS->getScopeRep()->print(OldOStream, SemaRef.getDiagPrintingPolicy());
           OldOStream << Typo->getName();
           // If correction candidate would be an identical written qualified
           // identifer, then the existing CXXScopeSpec probably included a
Index: lib/Sema/SemaExprCXX.cpp
===================================================================
--- lib/Sema/SemaExprCXX.cpp
+++ lib/Sema/SemaExprCXX.cpp
@@ -3511,7 +3511,7 @@
   }
   if (!IsDelete) {
     std::string TypeStr;
-    ClassType.getAsStringInternal(TypeStr, getPrintingPolicy());
+    ClassType.getAsStringInternal(TypeStr, getDiagPrintingPolicy());
     Diag(DtorLoc, diag::note_delete_non_virtual)
         << FixItHint::CreateInsertion(DtorLoc, TypeStr + "::");
   }
Index: lib/Sema/SemaExceptionSpec.cpp
===================================================================
--- lib/Sema/SemaExceptionSpec.cpp
+++ lib/Sema/SemaExceptionSpec.cpp
@@ -356,8 +356,8 @@
         OnFirstException = false;
       else
         OS << ", ";
-      
-      OS << E.getAsString(getPrintingPolicy());
+
+      OS << E.getAsString(getDiagPrintingPolicy());
     }
     OS << ")";
     break;
@@ -370,7 +370,8 @@
   case EST_ComputedNoexcept:
     OS << "noexcept(";
     assert(OldProto->getNoexceptExpr() != nullptr && "Expected non-null Expr");
-    OldProto->getNoexceptExpr()->printPretty(OS, nullptr, getPrintingPolicy());
+    OldProto->getNoexceptExpr()->printPretty(OS, nullptr,
+                                             getDiagPrintingPolicy());
     OS << ")";
     break;
 
Index: lib/Sema/SemaDeclCXX.cpp
===================================================================
--- lib/Sema/SemaDeclCXX.cpp
+++ lib/Sema/SemaDeclCXX.cpp
@@ -8514,7 +8514,7 @@
   }
   void check(SourceLocation SpecLoc, DeclSpec::TST Spec) {
     return check(SpecLoc,
-                 DeclSpec::getSpecifierName(Spec, S.getPrintingPolicy()));
+                 DeclSpec::getSpecifierName(Spec, S.getDiagPrintingPolicy()));
   }
   void check(SourceLocation SpecLoc, const char *Spec) {
     if (SpecLoc.isInvalid()) return;
@@ -13580,7 +13580,7 @@
       SmallString<256> MsgBuffer;
       llvm::raw_svector_ostream Msg(MsgBuffer);
       if (AssertMessage)
-        AssertMessage->printPretty(Msg, nullptr, getPrintingPolicy());
+        AssertMessage->printPretty(Msg, nullptr, getDiagPrintingPolicy());
 
       Expr *InnerCond = nullptr;
       std::string InnerCondDescription;
Index: lib/Sema/SemaDecl.cpp
===================================================================
--- lib/Sema/SemaDecl.cpp
+++ lib/Sema/SemaDecl.cpp
@@ -11287,7 +11287,7 @@
   const char *PrevSpec;
   unsigned DiagID;
   DS.SetTypeSpecType(DeclSpec::TST_auto, IdentLoc, PrevSpec, DiagID,
-                     getPrintingPolicy());
+                     getDiagPrintingPolicy());
 
   Declarator D(DS, DeclaratorContext::ForContext);
   D.SetIdentifier(Ident, IdentLoc);
Index: lib/Sema/SemaCodeComplete.cpp
===================================================================
--- lib/Sema/SemaCodeComplete.cpp
+++ lib/Sema/SemaCodeComplete.cpp
@@ -1514,7 +1514,7 @@
 
 static PrintingPolicy getCompletionPrintingPolicy(const ASTContext &Context,
                                                   const Preprocessor &PP) {
-  PrintingPolicy Policy = Sema::getPrintingPolicy(Context, PP);
+  PrintingPolicy Policy = Sema::getDiagPrintingPolicy(Context, PP);
   Policy.AnonymousTagLocations = false;
   Policy.SuppressStrongLifetime = true;
   Policy.SuppressUnwrittenScope = true;
Index: lib/Sema/SemaChecking.cpp
===================================================================
--- lib/Sema/SemaChecking.cpp
+++ lib/Sema/SemaChecking.cpp
@@ -7596,7 +7596,7 @@
   SmallString<128> sizeString;
   llvm::raw_svector_ostream OS(sizeString);
   OS << "sizeof(";
-  DstArg->printPretty(OS, nullptr, getPrintingPolicy());
+  DstArg->printPretty(OS, nullptr, getDiagPrintingPolicy());
   OS << ")";
   
   Diag(OriginalSizeArg->getLocStart(), diag::note_strlcpycat_wrong_size)
@@ -7697,10 +7697,10 @@
   SmallString<128> sizeString;
   llvm::raw_svector_ostream OS(sizeString);
   OS << "sizeof(";
-  DstArg->printPretty(OS, nullptr, getPrintingPolicy());
+  DstArg->printPretty(OS, nullptr, getDiagPrintingPolicy());
   OS << ") - ";
   OS << "strlen(";
-  DstArg->printPretty(OS, nullptr, getPrintingPolicy());
+  DstArg->printPretty(OS, nullptr, getDiagPrintingPolicy());
   OS << ") - 1";
 
   Diag(SL, diag::note_strncat_wrong_size)
@@ -10053,7 +10053,7 @@
     bool IsParam = isa<NonNullAttr>(NonnullAttr);
     std::string Str;
     llvm::raw_string_ostream S(Str);
-    E->printPretty(S, nullptr, getPrintingPolicy());
+    E->printPretty(S, nullptr, getDiagPrintingPolicy());
     unsigned DiagID = IsCompare ? diag::warn_nonnull_expr_compare
                                 : diag::warn_cast_nonnull_to_bool;
     Diag(E->getExprLoc(), DiagID) << IsParam << S.str()
@@ -10130,7 +10130,7 @@
   // Pretty print the expression for the diagnostic.
   std::string Str;
   llvm::raw_string_ostream S(Str);
-  E->printPretty(S, nullptr, getPrintingPolicy());
+  E->printPretty(S, nullptr, getDiagPrintingPolicy());
 
   unsigned DiagID = IsCompare ? diag::warn_null_pointer_compare
                               : diag::warn_impcast_pointer_to_bool;
Index: lib/Sema/Sema.cpp
===================================================================
--- lib/Sema/Sema.cpp
+++ lib/Sema/Sema.cpp
@@ -49,11 +49,12 @@
 
 ModuleLoader &Sema::getModuleLoader() const { return PP.getModuleLoader(); }
 
-PrintingPolicy Sema::getPrintingPolicy(const ASTContext &Context,
-                                       const Preprocessor &PP) {
+PrintingPolicy Sema::getDiagPrintingPolicy(const ASTContext &Context,
+                                           const Preprocessor &PP) {
   PrintingPolicy Policy = Context.getPrintingPolicy();
-  // Our printing policy is copied over the ASTContext printing policy whenever
-  // a diagnostic is emitted, so recompute it.
+  // The ASTContext printing policy is for -ast-print, which must print _Bool
+  // as _Bool.  In diagnostics, we print _Bool as bool if the latter is defined
+  // as the former.
   Policy.Bool = Context.getLangOpts().Bool;
   if (!Policy.Bool) {
     if (const MacroInfo *BoolMacro = PP.getMacroInfo(Context.getBoolName())) {
@@ -1202,6 +1203,16 @@
   return nullptr;
 }
 
+class DiagPrintingPolicyRAII {
+  Sema &S;
+
+public:
+  DiagPrintingPolicyRAII(Sema &S) : S(S) {
+    S.getASTContext().setPrintingPolicy(S.getDiagPrintingPolicy());
+  }
+  ~DiagPrintingPolicyRAII() { S.getASTContext().restorePrintingPolicy(); }
+};
+
 void Sema::EmitCurrentDiagnostic(unsigned DiagID) {
   // FIXME: It doesn't make sense to me that DiagID is an incoming argument here
   // and yet we also use the current diag ID on the DiagnosticsEngine. This has
@@ -1284,8 +1295,9 @@
     }
   }
 
-  // Set up the context's printing policy based on our current state.
-  Context.setPrintingPolicy(getPrintingPolicy());
+  // Copy the diagnostic printing policy over the ASTContext printing policy,
+  // and then restore it after emitting the diagnostic.
+  DiagPrintingPolicyRAII DiagPrintingPolicy(*this);
 
   // Emit the diagnostic.
   if (!Diags.EmitCurrentDiagnostic())
Index: lib/Parse/ParseDecl.cpp
===================================================================
--- lib/Parse/ParseDecl.cpp
+++ lib/Parse/ParseDecl.cpp
@@ -2920,7 +2920,7 @@
   bool AttrsLastTime = false;
   ParsedAttributesWithRange attrs(AttrFactory);
   // We use Sema's policy to get bool macros right.
-  PrintingPolicy Policy = Actions.getPrintingPolicy();
+  PrintingPolicy Policy = Actions.getDiagPrintingPolicy();
   while (1) {
     bool isInvalid = false;
     bool isStorageClass = false;
Index: include/clang/Sema/Sema.h
===================================================================
--- include/clang/Sema/Sema.h
+++ include/clang/Sema/Sema.h
@@ -2111,14 +2111,14 @@
   void checkPartialSpecializationVisibility(SourceLocation Loc,
                                             NamedDecl *Spec);
 
-  /// \brief Retrieve a suitable printing policy.
-  PrintingPolicy getPrintingPolicy() const {
-    return getPrintingPolicy(Context, PP);
+  /// \brief Retrieve a suitable printing policy for diagnostics.
+  PrintingPolicy getDiagPrintingPolicy() const {
+    return getDiagPrintingPolicy(Context, PP);
   }
 
-  /// \brief Retrieve a suitable printing policy.
-  static PrintingPolicy getPrintingPolicy(const ASTContext &Ctx,
-                                          const Preprocessor &PP);
+  /// \brief Retrieve a suitable printing policy for diagnostics.
+  static PrintingPolicy getDiagPrintingPolicy(const ASTContext &Ctx,
+                                              const Preprocessor &PP);
 
   /// Scope actions.
   void ActOnPopScope(SourceLocation Loc, Scope *S);
Index: include/clang/AST/ASTContext.h
===================================================================
--- include/clang/AST/ASTContext.h
+++ include/clang/AST/ASTContext.h
@@ -639,6 +639,10 @@
   void setPrintingPolicy(const clang::PrintingPolicy &Policy) {
     PrintingPolicy = Policy;
   }
+  /// Restore the printing policy computed when the context was constructed.
+  void restorePrintingPolicy() {
+    PrintingPolicy = clang::PrintingPolicy(LangOpts);
+  }
 
   SourceManager& getSourceManager() { return SourceMgr; }
   const SourceManager& getSourceManager() const { return SourceMgr; }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to