summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChandler Carruth <chandlerc@gmail.com>2011-02-19 00:21:00 +0000
committerChandler Carruth <chandlerc@gmail.com>2011-02-19 00:21:00 +0000
commit4c4f8de421cf2ae376968f43161f50643c314b87 (patch)
tree093ae2e0fd9b6576b7ec2cc4e2587ae54a87ecd1
parent9c9127eacea4d58bf328de90d7da3245a552b9c4 (diff)
downloadbcm5719-llvm-4c4f8de421cf2ae376968f43161f50643c314b87.tar.gz
bcm5719-llvm-4c4f8de421cf2ae376968f43161f50643c314b87.zip
Improve bool and char integral template argument printing in
diagnostics, resolving PR9227. Patch originally by Mihai Rusu and Stephen Hines with some minimal style tweaks from me. llvm-svn: 125999
-rw-r--r--clang/lib/AST/TemplateBase.cpp35
-rw-r--r--clang/test/SemaTemplate/temp_arg_nontype.cpp16
2 files changed, 49 insertions, 2 deletions
diff --git a/clang/lib/AST/TemplateBase.cpp b/clang/lib/AST/TemplateBase.cpp
index f3def3eff2c..5ab5f4644c8 100644
--- a/clang/lib/AST/TemplateBase.cpp
+++ b/clang/lib/AST/TemplateBase.cpp
@@ -18,13 +18,46 @@
#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;
}
diff --git a/clang/test/SemaTemplate/temp_arg_nontype.cpp b/clang/test/SemaTemplate/temp_arg_nontype.cpp
index b5e382c93e8..5be5a130313 100644
--- a/clang/test/SemaTemplate/temp_arg_nontype.cpp
+++ b/clang/test/SemaTemplate/temp_arg_nontype.cpp
@@ -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<'\\'>}}
+}
OpenPOWER on IntegriCloud