Skip to content
Snippets Groups Projects
Commit 781701c3 authored by Chandler Carruth's avatar Chandler Carruth
Browse files

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.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@125999 91177308-0d34-0410-b5e6-96231b3b80d8
parent 7ef93242
No related branches found
No related tags found
No related merge requests found
......@@ -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;
}
......
......@@ -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<'\\'>}}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment