]> granicus.if.org Git - clang/commitdiff
Improve bool and char integral template argument printing in
authorChandler Carruth <chandlerc@gmail.com>
Sat, 19 Feb 2011 00:21:00 +0000 (00:21 +0000)
committerChandler Carruth <chandlerc@gmail.com>
Sat, 19 Feb 2011 00:21:00 +0000 (00:21 +0000)
diagnostics, resolving PR9227.

Patch originally by Mihai Rusu and Stephen Hines with some minimal style
tweaks from me.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@125999 91177308-0d34-0410-b5e6-96231b3b80d8

lib/AST/TemplateBase.cpp
test/SemaTemplate/temp_arg_nontype.cpp

index f3def3eff2cf0156c1791e1899568bb9e7734ff0..5ab5f4644c88fa879dc8d27f1e2984d727c7fbf8 100644 (file)
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/ExprCXX.h"
+#include "clang/AST/Type.h"
 #include "clang/AST/TypeLoc.h"
 #include "clang/Basic/Diagnostic.h"
 #include "llvm/ADT/FoldingSet.h"
 #include <algorithm>
+#include <cctype>
+#include <iomanip>
+#include <sstream>
 
 using namespace clang;
 
+/// \brief Print a template integral argument value.
+///
+/// \param TemplArg the TemplateArgument instance to print.
+///
+/// \param Out the raw_ostream instance to use for printing.
+static void printIntegral(const TemplateArgument &TemplArg,
+                          llvm::raw_ostream &Out) {
+  const ::clang::Type *T = TemplArg.getIntegralType().getTypePtr();
+  const llvm::APSInt *Val = TemplArg.getAsIntegral();
+
+  if (T->isBooleanType()) {
+    Out << (Val->getBoolValue() ? "true" : "false");
+  } else if (T->isCharType()) {
+    char Ch = Val->getSExtValue();
+    if (std::isprint(Ch)) {
+      Out << "'";
+      if (Ch == '\'' || Ch == '\\')
+        Out << '\\';
+      Out << Ch << "'";
+    } else {
+      std::ostringstream Str;
+      Str << std::setw(2) << std::setfill('0') << std::hex << (int)Ch;
+      Out << "'\\x" << Str.str() << "'";
+    }
+  } else {
+    Out << Val->toString(10);
+  }
+}
+
 //===----------------------------------------------------------------------===//
 // TemplateArgument Implementation
 //===----------------------------------------------------------------------===//
@@ -283,7 +316,7 @@ void TemplateArgument::print(const PrintingPolicy &Policy,
     break;
       
   case Integral: {
-    Out << getAsIntegral()->toString(10);
+    printIntegral(*this, Out);
     break;
   }
     
index b5e382c93e87da40e1b9d51d3f087db3f5089a4d..5be5a1303136dd55ed67207d0367d8746ff9f760 100644 (file)
@@ -170,7 +170,7 @@ namespace pr6249 {
 
 namespace PR6723 {
   template<unsigned char C> void f(int (&a)[C]); // expected-note {{candidate template ignored}} \
-  // expected-note{{candidate function [with C = 0] not viable: no known conversion from 'int [512]' to 'int (&)[0]' for 1st argument}}
+  // expected-note{{candidate function [with C = '\x00'] not viable: no known conversion from 'int [512]' to 'int (&)[0]' for 1st argument}}
   void g() {
     int arr512[512];
     f(arr512); // expected-error{{no matching function for call}}
@@ -249,3 +249,17 @@ namespace PR8372 {
   template <int I> void foo() { } // expected-note{{template parameter is declared here}}
   void bar() { foo <0x80000000> (); } // expected-warning{{non-type template argument value '2147483648' truncated to '-2147483648' for template parameter of type 'int'}}
 }
+
+namespace PR9227 {
+  template <bool B> struct enable_if_bool { };
+  template <> struct enable_if_bool<true> { typedef int type; };
+  void test_bool() { enable_if_bool<false>::type i; } // expected-error{{enable_if_bool<false>}}
+
+  template <char C> struct enable_if_char { };
+  template <> struct enable_if_char<'a'> { typedef int type; };
+  void test_char_0() { enable_if_char<0>::type i; } // expected-error{{enable_if_char<'\x00'>}}
+  void test_char_b() { enable_if_char<'b'>::type i; } // expected-error{{enable_if_char<'b'>}}
+  void test_char_possibly_negative() { enable_if_char<'\x02'>::type i; } // expected-error{{enable_if_char<'\x02'>}}
+  void test_char_single_quote() { enable_if_char<'\''>::type i; } // expected-error{{enable_if_char<'\''>}}
+  void test_char_backslash() { enable_if_char<'\\'>::type i; } // expected-error{{enable_if_char<'\\'>}}
+}