diff options
| author | Chandler Carruth <chandlerc@gmail.com> | 2011-02-19 00:21:00 +0000 |
|---|---|---|
| committer | Chandler Carruth <chandlerc@gmail.com> | 2011-02-19 00:21:00 +0000 |
| commit | 4c4f8de421cf2ae376968f43161f50643c314b87 (patch) | |
| tree | 093ae2e0fd9b6576b7ec2cc4e2587ae54a87ecd1 | |
| parent | 9c9127eacea4d58bf328de90d7da3245a552b9c4 (diff) | |
| download | bcm5719-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.cpp | 35 | ||||
| -rw-r--r-- | clang/test/SemaTemplate/temp_arg_nontype.cpp | 16 |
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<'\\'>}} +} |

