===================================================================
@@ -0,0 +1,59 @@
+// { dg-options -std=c++0x }
+
+#include <cstdint>
+
+int operator"" _bar (long double);
+
+double operator"" _foo (long long unsigned);
+
+int i = 12_bar; // { dg-error "unable to find numeric literal operator|with|argument" }
+
+double d = 1.2_foo; // { dg-error "unable to find numeric literal operator|with|argument" }
+
+int operator"" _char(char);
+
+int operator"" _wchar_t(wchar_t);
+
+int operator"" _char16_t(char16_t);
+
+int operator"" _char32_t(char32_t);
+
+int cwc = 'c'_wchar_t; // { dg-error "unable to find character literal operator|with|argument" }
+int cc16 = 'c'_char16_t; // { dg-error "unable to find character literal operator|with|argument" }
+int cc32 = 'c'_char32_t; // { dg-error "unable to find character literal operator|with|argument" }
+
+int wcc = L'c'_char; // { dg-error "unable to find character literal operator|with|argument" }
+int wcc16 = L'c'_char16_t; // { dg-error "unable to find character literal operator|with|argument" }
+int wcc32 = L'c'_char32_t; // { dg-error "unable to find character literal operator|with|argument" }
+
+int c16c = u'c'_char; // { dg-error "unable to find character literal operator|with|argument" }
+int c16wc = u'c'_wchar_t; // { dg-error "unable to find character literal operator|with|argument" }
+int c16c32 = u'c'_char32_t; // { dg-error "unable to find character literal operator|with|argument" }
+
+int c32c = U'c'_char; // { dg-error "unable to find character literal operator|with|argument" }
+int c32wc = U'c'_wchar_t; // { dg-error "unable to find character literal operator|with|argument" }
+int c32c16 = U'c'_char16_t; // { dg-error "unable to find character literal operator|with|argument" }
+
+int operator"" _char_str(const char*, std::size_t);
+
+int operator"" _wchar_t_str(const wchar_t*, std::size_t);
+
+int operator"" _char16_t_str(const char16_t*, std::size_t);
+
+int operator"" _char32_t_str(const char32_t*, std::size_t);
+
+int strwstr = "str"_wchar_t_str; // { dg-error "unable to find string literal operator|with|arguments" }
+int strstr16 = "str"_char16_t_str; // { dg-error "unable to find string literal operator|with|arguments" }
+int strstr32 = "str"_char32_t_str; // { dg-error "unable to find string literal operator|with|arguments" }
+
+int wstrstr = L"str"_char_str; // { dg-error "unable to find string literal operator|with|arguments" }
+int wstrstr16 = L"str"_char16_t_str; // { dg-error "unable to find string literal operator|with|arguments" }
+int wstrstr32 = L"str"_char32_t_str; // { dg-error "unable to find string literal operator|with|arguments" }
+
+int str16str = u"str"_char_str; // { dg-error "unable to find string literal operator|with|arguments" }
+int str16wstr = u"str"_wchar_t_str; // { dg-error "unable to find string literal operator|with|arguments" }
+int str16str32 = u"str"_char32_t_str; // { dg-error "unable to find string literal operator|with|arguments" }
+
+int str32str = U"str"_char_str; // { dg-error "unable to find string literal operator|with|arguments" }
+int str32wstr = U"str"_wchar_t_str; // { dg-error "unable to find string literal operator|with|arguments" }
+int str32str16 = U"str"_char16_t_str; // { dg-error "unable to find string literal operator string operator|with|arguments" }
===================================================================
@@ -0,0 +1,43 @@
+// { dg-do run }
+// { dg-options "-std=c++0x" }
+
+#include <cstdint>
+#include <cassert>
+
+int operator"" _foo(const char*) { return 0; }
+int operator"" _foo(unsigned long long int) { return 1; }
+int operator"" _foo(long double) { return 2; }
+int operator"" _foo(char) { return 3; }
+int operator"" _foo(wchar_t) { return 4; }
+int operator"" _foo(char16_t) { return 5; }
+int operator"" _foo(char32_t) { return 6; }
+int operator"" _foo(const char*, std::size_t) { return 7; }
+int operator"" _foo(const wchar_t*, std::size_t) { return 8; }
+int operator"" _foo(const char16_t*, std::size_t) { return 9; }
+int operator"" _foo(const char32_t*, std::size_t) { return 10; }
+template<char...> int operator"" _foo2() { return 20; }
+int operator"" _foo2(unsigned long long int) { return 21; }
+
+namespace bar {
+int operator"" _foo(unsigned long long int) { return 101; }
+}
+using namespace bar;
+
+int
+main()
+{
+ //assert(123_foo == 0);
+ //assert(123_foo == 1);
+ assert(123_foo == 101);
+ assert(0.123_foo == 2);
+ assert('c'_foo == 3);
+ assert(L'c'_foo == 4);
+ assert(u'c'_foo == 5);
+ assert(U'c'_foo == 6);
+ assert("abc"_foo == 7);
+ assert(L"abc"_foo == 8);
+ assert(u"abc"_foo == 9);
+ assert(U"abc"_foo == 10);
+ assert(123_foo2 == 21);
+ //assert(_foo == );
+}
===================================================================
@@ -3532,9 +3532,7 @@
{
cp_token *token = NULL;
tree literal, suffix_id, value;
- tree name, decl;
- tree result;
- VEC(tree,gc) *vec;
+ tree name, decl, fns;
token = cp_lexer_consume_token (parser->lexer);
literal = token->u.value;
@@ -3544,20 +3542,37 @@
/* Build up a call to the user-defined operator */
/* Lookup the name we got back from the id-expression. */
- vec = make_tree_vector ();
- VEC_safe_push (tree, gc, vec, value);
- decl = lookup_function_nonclass (name, vec, /*block_p=*/false);
+ decl = lookup_name (name);
if (!decl || decl == error_mark_node)
{
error ("unable to find user-defined character literal operator %qD",
name);
- release_tree_vector (vec);
return error_mark_node;
}
- result = finish_call_expr (decl, &vec, false, true, tf_warning_or_error);
- release_tree_vector (vec);
+ fns = decl;
+ while (fns)
+ {
+ tree fn = OVL_CURRENT (fns);
+ tree argtypes = NULL_TREE;
+ if (TREE_CODE (TREE_TYPE (fn)) != LANG_TYPE)
+ argtypes = TYPE_ARG_TYPES (TREE_TYPE (fn));
+ if (argtypes != NULL_TREE
+ && same_type_p (TREE_VALUE (argtypes), TREE_TYPE (value)))
+ {
+ tree result;
+ VEC(tree,gc) *vec = make_tree_vector ();
+ VEC_safe_push (tree, gc, vec, value);
+ result = finish_call_expr (fn, &vec, false, true, tf_warning_or_error);
+ release_tree_vector (vec);
+ if (result != error_mark_node)
+ return result;
+ }
+ fns = OVL_NEXT (fns);
+ }
- return result;
+ error ("unable to find character literal operator %qD with %qT argument",
+ name, TREE_TYPE (value));
+ return error_mark_node;
}
/* A subroutine of cp_parser_userdef_numeric_literal to
@@ -3594,9 +3609,7 @@
{
cp_token *token = NULL;
tree literal, suffix_id, value, num_string;
- tree name, decl;
- tree result = error_mark_node;
- VEC(tree,gc) *args;
+ tree name, decl, fns;
token = cp_lexer_consume_token (parser->lexer);
literal = token->u.value;
@@ -3605,63 +3618,87 @@
num_string = USERDEF_LITERAL_NUM_STRING (literal);
name = cp_literal_operator_id (IDENTIFIER_POINTER (suffix_id));
- /* Build up a call to the user-defined operator */
- /* Lookup the name we got back from the id-expression. */
- /* Try to find the literal operator by finishing the call expression
- with the numeric argument. */
- args = make_tree_vector ();
- VEC_safe_push (tree, gc, args, value);
- decl = lookup_function_nonclass (name, args, /*block_p=*/false);
- if (decl && decl != error_mark_node)
+ decl = lookup_name (name);
+ if (!decl || decl == error_mark_node)
{
- result = finish_call_expr (decl, &args, false, true, tf_none);
- if (result != error_mark_node)
+ error ("unable to find user-defined numeric literal operator %qD", name);
+ return error_mark_node;
+ }
+
+ /* Look for a literal operator taking the exact type of numeric argument
+ as the literal value. */
+ fns = decl;
+ while (fns)
+ {
+ tree fn = OVL_CURRENT (fns);
+ tree argtypes = NULL_TREE;
+ if (TREE_CODE (TREE_TYPE (fn)) != LANG_TYPE)
+ argtypes = TYPE_ARG_TYPES (TREE_TYPE (fn));
+ if (argtypes != NULL_TREE
+ && same_type_p (TREE_VALUE (argtypes), TREE_TYPE (value)))
{
+ tree result;
+ VEC(tree,gc) *args = make_tree_vector ();
+ VEC_safe_push (tree, gc, args, value);
+ result = finish_call_expr (fn, &args, false, true, tf_none);
release_tree_vector (args);
- return result;
+ if (result != error_mark_node)
+ return result;
}
+ fns = OVL_NEXT (fns);
}
- release_tree_vector (args);
/* If the numeric argument didn't work, look for a raw literal
operator taking a const char* argument consisting of the number
in string format. */
- args = make_tree_vector ();
- VEC_safe_push (tree, gc, args, num_string);
- decl = lookup_function_nonclass (name, args, /*block_p=*/false);
- if (decl && decl != error_mark_node)
+ fns = decl;
+ while (fns)
{
- result = finish_call_expr (decl, &args, false, true, tf_none);
- if (result != error_mark_node)
+ tree fn = OVL_CURRENT (fns);
+ tree argtypes = NULL_TREE;
+ if (TREE_CODE (TREE_TYPE (fn)) != LANG_TYPE)
+ argtypes = TYPE_ARG_TYPES (TREE_TYPE (fn));
+ if (argtypes != NULL_TREE
+ && same_type_p (TREE_VALUE (argtypes), const_string_type_node))
{
+ tree result;
+ VEC(tree,gc) *args = make_tree_vector ();
+ VEC_safe_push (tree, gc, args, num_string);
+ result = finish_call_expr (fn, &args, false, true, tf_none);
release_tree_vector (args);
- return result;
+ if (result != error_mark_node)
+ return result;
}
+ fns = OVL_NEXT (fns);
}
- release_tree_vector (args);
/* If the raw literal didn't work, look for a non-type template
function with parameter pack char.... Call the function with
template parameter characters representing the number. */
- args = make_tree_vector ();
- decl = lookup_function_nonclass (name, args, /*block_p=*/false);
- if (decl && decl != error_mark_node)
+ fns = decl;
+ while (fns)
{
tree tmpl_args = make_char_string_pack (num_string);
- decl = lookup_template_function (decl, tmpl_args);
- result = finish_call_expr (decl, &args, false, true, tf_none);
- if (result != error_mark_node)
+ tree fn = OVL_CURRENT (fns);
+ tree argtypes = NULL_TREE;
+ if (TREE_CODE (TREE_TYPE (fn)) != LANG_TYPE)
+ argtypes = TYPE_ARG_TYPES (TREE_TYPE (fn));
+ if (argtypes != NULL_TREE
+ && same_type_p (TREE_VALUE (argtypes), void_type_node))
{
+ tree result;
+ VEC(tree,gc) *args = make_tree_vector ();
+ fn = lookup_template_function (fn, tmpl_args);
+ result = finish_call_expr (fn, &args, false, true, tf_none);
release_tree_vector (args);
- return result;
+ if (result != error_mark_node)
+ return result;
}
+ fns = OVL_NEXT (fns);
}
- release_tree_vector (args);
- if (result == error_mark_node)
- error ("unable to find user-defined numeric literal operator %qD", name);
-
- return result;
+ error ("unable to find numeric literal operator %qD", name);
+ return error_mark_node;
}
/* Parse a user-defined string constant. Returns a call to a user-defined
@@ -3671,38 +3708,60 @@
static tree
cp_parser_userdef_string_literal (cp_token *token)
{
- tree literal, suffix_id, value;
- tree name, decl;
- tree result;
- VEC(tree,gc) *vec;
- int len;
+ tree literal = token->u.value;
+ tree suffix_id = USERDEF_LITERAL_SUFFIX_ID (literal);
+ tree name = cp_literal_operator_id (IDENTIFIER_POINTER (suffix_id));
+ tree value = USERDEF_LITERAL_VALUE (literal);
+ int len = TREE_STRING_LENGTH (value) - 1;
+ tree fns;
+ bool have_size = false;
- literal = token->u.value;
- suffix_id = USERDEF_LITERAL_SUFFIX_ID (literal);
- name = cp_literal_operator_id (IDENTIFIER_POINTER (suffix_id));
- value = USERDEF_LITERAL_VALUE (literal);
- len = TREE_STRING_LENGTH (value) - 1;
-
/* Build up a call to the user-defined operator */
/* Lookup the name we got back from the id-expression. */
- vec = make_tree_vector ();
- VEC_safe_push (tree, gc, vec, value);
- VEC_safe_push (tree, gc, vec, build_int_cst (size_type_node, len));
- decl = lookup_function_nonclass (name, vec, /*block_p=*/false);
+ tree decl = lookup_name (name);
if (!decl || decl == error_mark_node)
{
error ("unable to find user-defined string literal operator %qD", name);
- release_tree_vector (vec);
return error_mark_node;
}
- result = finish_call_expr (decl, &vec, false, true, tf_none);
- if (result == error_mark_node)
+ fns = decl;
+ while (fns)
+ {
+ tree fn = OVL_CURRENT (fns);
+ tree argtypes = NULL_TREE;
+ if (TREE_CODE (TREE_TYPE (fn)) != LANG_TYPE)
+ argtypes = TYPE_ARG_TYPES (TREE_TYPE (fn));
+ if (argtypes != NULL_TREE && TREE_CHAIN (argtypes) != NULL_TREE)
+ {
+ tree tsize = TREE_CHAIN (argtypes);
+ if (tsize && same_type_p (TREE_VALUE (tsize), size_type_node))
+ have_size = true;
+ if (TREE_CODE (TREE_VALUE (argtypes)) == POINTER_TYPE
+ && same_type_p (TREE_TYPE (TREE_VALUE (argtypes)),
+ TREE_TYPE (TREE_TYPE (value))))
+ {
+ tree result;
+ VEC(tree,gc) *vec = make_tree_vector ();
+ VEC_safe_push (tree, gc, vec, value);
+ VEC_safe_push (tree, gc, vec,
+ build_int_cst (size_type_node, len));
+ result = finish_call_expr (fn, &vec, false, true, tf_none);
+ release_tree_vector (vec);
+ if (result != error_mark_node)
+ return result;
+ }
+ }
+ fns = OVL_NEXT (fns);
+ }
+
+ if (have_size)
+ error ("unable to find string literal operator %qD with %qT, %qT arguments",
+ name, TREE_TYPE (value), size_type_node);
+ else
error ("unable to find valid user-defined string literal operator %qD."
" Possible missing length argument in string literal operator.",
name);
- release_tree_vector (vec);
-
- return result;
+ return error_mark_node;
}
===================================================================
@@ -284,9 +284,9 @@
else if (type == CPP_WCHAR_USERDEF)
return CPP_WCHAR;
else if (type == CPP_CHAR16_USERDEF)
- return CPP_STRING16;
+ return CPP_CHAR16;
else if (type == CPP_CHAR32_USERDEF)
- return CPP_STRING32;
+ return CPP_CHAR32;
else
return type;
}