return value;
}
+/* Look up a literal operator with the name and the exact arguments. */
+
+static tree
+lookup_literal_operator (tree name, VEC(tree,gc) *args)
+{
+ tree decl, fns;
+ decl = lookup_name (name);
+ if (!decl || decl == error_mark_node)
+ return error_mark_node;
+
+ for (fns = decl; fns; fns = OVL_NEXT (fns))
+ {
+ unsigned int ix;
+ bool found = true;
+ tree fn = OVL_CURRENT (fns);
+ tree argtypes = NULL_TREE;
+ argtypes = TYPE_ARG_TYPES (TREE_TYPE (fn));
+ if (argtypes != NULL_TREE)
+ {
+ for (ix = 0; ix < VEC_length (tree, args) && argtypes != NULL_TREE;
+ ++ix, argtypes = TREE_CHAIN (argtypes))
+ {
+ tree targ = TREE_VALUE (argtypes);
+ tree tparm = TREE_TYPE (VEC_index (tree, args, ix));
+ bool ptr = TREE_CODE (targ) == POINTER_TYPE;
+ bool arr = TREE_CODE (tparm) == ARRAY_TYPE;
+ if ((ptr || arr || !same_type_p (targ, tparm))
+ && (!ptr || !arr
+ || !same_type_p (TREE_TYPE (targ),
+ TREE_TYPE (tparm))))
+ found = false;
+ }
+ if (found)
+ return fn;
+ }
+ }
+
+ return error_mark_node;
+}
+
/* Parse a user-defined char constant. Returns a call to a user-defined
literal operator taking the character as an argument. */
static tree
cp_parser_userdef_char_literal (cp_parser *parser)
{
- cp_token *token = NULL;
- tree literal, suffix_id, value;
- tree name, decl;
- tree result;
- VEC(tree,gc) *vec;
-
- token = cp_lexer_consume_token (parser->lexer);
- literal = token->u.value;
- suffix_id = USERDEF_LITERAL_SUFFIX_ID (literal);
- value = USERDEF_LITERAL_VALUE (literal);
- name = cp_literal_operator_id (IDENTIFIER_POINTER (suffix_id));
+ cp_token *token = cp_lexer_consume_token (parser->lexer);
+ tree literal = token->u.value;
+ tree suffix_id = USERDEF_LITERAL_SUFFIX_ID (literal);
+ tree value = USERDEF_LITERAL_VALUE (literal);
+ tree name = cp_literal_operator_id (IDENTIFIER_POINTER (suffix_id));
+ tree decl, result;
/* 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);
+ VEC(tree,gc) *args = make_tree_vector ();
+ VEC_safe_push (tree, gc, args, value);
+ decl = lookup_literal_operator (name, args);
if (!decl || decl == error_mark_node)
{
- error ("unable to find user-defined character literal operator %qD",
- name);
- release_tree_vector (vec);
+ error ("unable to find character literal operator %qD with %qT argument",
+ name, TREE_TYPE (value));
+ release_tree_vector (args);
return error_mark_node;
}
- result = finish_call_expr (decl, &vec, false, true, tf_warning_or_error);
- release_tree_vector (vec);
+ result = finish_call_expr (decl, &args, false, true, tf_warning_or_error);
+ release_tree_vector (args);
+ if (result != error_mark_node)
+ return result;
- 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
static tree
cp_parser_userdef_numeric_literal (cp_parser *parser)
{
- cp_token *token = NULL;
- tree literal, suffix_id, value, num_string;
- tree name, decl;
- tree result = error_mark_node;
+ cp_token *token = cp_lexer_consume_token (parser->lexer);
+ tree literal = token->u.value;
+ tree suffix_id = USERDEF_LITERAL_SUFFIX_ID (literal);
+ tree value = USERDEF_LITERAL_VALUE (literal);
+ tree num_string = USERDEF_LITERAL_NUM_STRING (literal);
+ tree name = cp_literal_operator_id (IDENTIFIER_POINTER (suffix_id));
+ tree decl, result;
VEC(tree,gc) *args;
- token = cp_lexer_consume_token (parser->lexer);
- literal = token->u.value;
- suffix_id = USERDEF_LITERAL_SUFFIX_ID (literal);
- value = USERDEF_LITERAL_VALUE (literal);
- 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. */
+ /* Look for a literal operator taking the exact type of numeric argument
+ as the literal value. */
args = make_tree_vector ();
VEC_safe_push (tree, gc, args, value);
- decl = lookup_function_nonclass (name, args, /*block_p=*/false);
+ decl = lookup_literal_operator (name, args);
if (decl && decl != error_mark_node)
{
result = finish_call_expr (decl, &args, false, true, tf_none);
in string format. */
args = make_tree_vector ();
VEC_safe_push (tree, gc, args, num_string);
- decl = lookup_function_nonclass (name, args, /*block_p=*/false);
+ decl = lookup_literal_operator (name, args);
if (decl && decl != error_mark_node)
{
result = finish_call_expr (decl, &args, false, true, tf_none);
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);
+ decl = lookup_literal_operator (name, args);
if (decl && decl != error_mark_node)
{
tree tmpl_args = make_char_string_pack (num_string);
}
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
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;
-
- 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)
+ 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)
/ TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (value)))) - 1;
+ tree decl, result;
+
/* 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);
+ VEC(tree,gc) *args = make_tree_vector ();
+ VEC_safe_push (tree, gc, args, value);
+ VEC_safe_push (tree, gc, args, build_int_cst (size_type_node, len));
+ 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);
+ error ("unable to find string literal operator %qD", name);
+ release_tree_vector (args);
return error_mark_node;
}
- result = finish_call_expr (decl, &vec, false, true, tf_none);
- if (result == error_mark_node)
- error ("unable to find valid user-defined string literal operator %qD."
- " Possible missing length argument in string literal operator.",
- name);
- release_tree_vector (vec);
+ result = finish_call_expr (decl, &args, false, true, tf_none);
+ release_tree_vector (args);
+ if (result != error_mark_node)
+ return result;
- return result;
+ error ("unable to find string literal operator %qD with %qT, %qT arguments",
+ name, TREE_TYPE (value), size_type_node);
+ return error_mark_node;
}
--- /dev/null
+// { 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 cwcx = '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 wccx = 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 str8wstr = u8"str"_wchar_t_str; // { dg-error "unable to find string literal operator|with|arguments" }
+int str8str16 = u8"str"_char16_t_str; // { dg-error "unable to find string literal operator|with|arguments" }
+int str8str32 = u8"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" }