public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Jason Merrill <jason@redhat.com>
To: Ed Smith-Rowland <3dw4rd@verizon.net>
Cc: gcc-patches <gcc-patches@gcc.gnu.org>
Subject: Re: [C++-11] User defined literals
Date: Wed, 14 Sep 2011 08:00:00 -0000	[thread overview]
Message-ID: <4E7008DA.6090703@redhat.com> (raw)
In-Reply-To: <4E6F6A1C.90305@verizon.net>

Since we're starting to come up on the end of stage 1, I'll go ahead and 
review the current patch even though it isn't finished yet.  Thanks for 
all your work on this, it definitely seems to be coming together.

On 09/13/2011 10:35 AM, Ed Smith-Rowland wrote:
> +#define CPP_N_USERDEF  0x1000000 /* C++0x user-defned literal.  */

"defined"

> -extern unsigned cpp_classify_number (cpp_reader *, const cpp_token *);
> +extern unsigned cpp_classify_number (cpp_reader *, const cpp_token *,
> +                                    char **ud_suffix);
> +
> +/* Return the classification flags for a float suffix.  */
> +unsigned int cpp_interpret_float_suffix (const char *s, size_t len);
> +
> +/* Return the classification flags for an int suffix.  */
> +unsigned int cpp_interpret_int_suffix (const char *s, size_t len);
>
>  /* Evaluate a token classified as category CPP_N_INTEGER.  */
>  extern cpp_num cpp_interpret_integer (cpp_reader *, const cpp_token *,

Let's follow the pattern of the existing declarations by adding explicit 
'extern' and not naming the parameters.

> @@ -327,6 +327,10 @@ pp_cxx_constant (cxx_pretty_printer *pp, tree t)
> +    case USERDEF_LITERAL:
> +      pp_c_constant (pp_c_base (pp), USERDEF_LITERAL_VALUE (t));
> +      break;
> @@ -1755,6 +1757,11 @@ dump_expr (tree t, int flags)
> +    case USERDEF_LITERAL:
> +      pp_constant (cxx_pp, USERDEF_LITERAL_VALUE (t));
> +      dump_decl (USERDEF_LITERAL_SUFFIX_ID (t), flags);
> +      break;

These should be the same--or just call pp_cxx_constant from dump_expr.

> +/* Extract the suffix from a user-defined literal string or char.  */
> +void
> +cpp_get_userdef_suffix (cpp_string string, char delim, char *suffix)
> +{
> +  unsigned int len = string.len;
> +  const char *text = (const char *)string.text;
> +  int i;
> +  for (i = len; i > 0; --i)
> +    {
> +      if (text[i - 1] == delim)
> +       break;
> +    }
> +  strncpy (suffix, text + i, len - i);
> +  suffix[len - i] = '\0';
> +}

Since you're just going to be passing the pointer to get_identifier 
anyway, we don't need to copy the suffix into the pointer.  Just return 
a pointer to the start of the suffix.

> +             if (ud_suffix)
> +               *ud_suffix = xstrdup ((const char *)str);

Similarly here.

> +             const char *curr_suffix = NULL;
> +             suffix_id = USERDEF_LITERAL_SUFFIX_ID (tok->u.value);
> +             curr_suffix = IDENTIFIER_POINTER (suffix_id);
> +             if (have_suffix_p == 0)
> +               {
> +                 suffix = xstrdup (curr_suffix);
> +                 have_suffix_p = 1;
> +               }
> +             else if (have_suffix_p == 1 && strcmp (suffix, curr_suffix) != 0)

And here, you can compare the identifiers with ==, since identifiers are 
unique.

> +                 error ("inconsistent user-defined literal suffixes");

Let's print the suffixes involved.

> +             error ("%qD has illegal argument list", decl);

Use "invalid" rather than "illegal".

> +         suffix = UDLIT_OP_SUFFIX (DECL_NAME (decl));
> +         if (long_long_unsigned_p)
> +           {
> +             if (cpp_interpret_int_suffix (suffix, strlen (suffix)))
> +               warning (0, "integer suffix shadowed by implementation");
> +           }
> +         else if (long_double_p)
> +           {
> +             if (cpp_interpret_float_suffix (suffix, strlen (suffix)))
> +               warning (0, "floating point suffix"
> +                           " shadowed by implementation");
> +           }

Let's print the suffix as part of the warning.

> +  if (dname
> +      && TREE_CODE (dname) == IDENTIFIER_NODE
> +      && UDLIT_OPER_P (dname)
> +      && innermost_code != cdk_function
> +      && ! (ctype && !declspecs->any_specifiers_p))

I think we can drop the last check, as it only applies to constructors.

> +/* User-defined literal operator.
> +DEF_SIMPLE_OPERATOR ("\"\"", USERDEF_LITERAL_EXPR, "ud", 1)  */

Are you planning to use this for something?

> +/* 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)

There should be a blank line after the comment here and before the other 
new functions, at least in gcc/.

> +make_numeric_string(tree value)

This function tries to recreate a printed form for a numeric constant, 
but that's not right; we need the actual source characters, which are 
likely to be different, especially for floating-point numbers.  So we 
need to get back to the actual spelling of the token here.

I notice that later in cp_parser_userdef_numeric_literal when calling 
the variadic template version you assume that you have the spelling of 
the token, which is indeed what we want.

> +check_literal_operator_args(const_tree decl,

Space before (.

> +      tree const_char_ptr_type_node
> +          = build_pointer_type(build_type_variant(char_type_node, 1, 0));
> +      tree const_wchar_ptr_type_node
> +          = build_pointer_type(build_type_variant(wchar_type_node, 1, 0));
> +      tree const_char16_ptr_type_node
> +          = build_pointer_type(build_type_variant(char16_type_node, 1, 0));
> +      tree const_char32_ptr_type_node
> +          = build_pointer_type(build_type_variant(char32_type_node, 1, 0));

It seems to me that rather than build these up to compare against, it it 
would be faster to check for POINTER_TYPE, then check that the 
pointed-to type is CP_TYPE_CONST_NON_VOLATILE_P, and then compare the 
TYPE_MAIN_VARIANT to char_type_node, etc.

> +++ b/gcc/testsuite/g++.dg/cpp0x/udlit-operator-neg.C
> @@ -0,0 +1,16 @@
> +// { dg-options "-std=c++0x" }
> +
> +//  Both of these can't have *both* of these.
> +
> +int
> +operator"" _abc(const char*)
> +  {
> +    return 42;
> +  }
> +
> +template<char...>
> +  int
> +  operator"" _abc()
> +  {
> +    return 13;
> +  }

Shouldn't this have a dg-error tag somewhere?

Jason

  parent reply	other threads:[~2011-09-14  1:53 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-09-13 15:36 Ed Smith-Rowland
2011-09-13 16:43 ` Jason Merrill
2011-09-14  8:00 ` Jason Merrill [this message]
2011-09-19  8:33   ` Ed Smith-Rowland
2011-09-19 22:43     ` Jason Merrill
2011-09-20  7:23       ` Ed Smith-Rowland
2011-09-20 21:48         ` Jason Merrill
2011-10-05 15:57           ` Ed Smith-Rowland
2011-10-05 21:24             ` Jason Merrill
2011-10-08 21:38               ` Ed Smith-Rowland
2011-10-09  1:18                 ` Jason Merrill
2011-10-09 23:46                   ` Ed Smith-Rowland
2011-10-11 19:20                     ` Jason Merrill
2011-10-11 17:39                       ` Jason Merrill
2011-10-12  6:51                         ` Ed Smith-Rowland
2011-10-12 18:49                           ` Jason Merrill
2011-10-12 21:12 3dw4rd
2011-10-15 23:13 ` Jason Merrill
2011-10-16  7:59 ` Jason Merrill
2011-10-21 14:56   ` Ed Smith-Rowland
2011-10-21 21:20     ` Tom Tromey
2011-10-21 23:38       ` Jason Merrill
2011-10-23 22:29         ` Ed Smith-Rowland
2011-10-24 15:41         ` Ed Smith-Rowland
2011-10-25 23:38           ` Jason Merrill
2011-10-26  9:16             ` Ed Smith-Rowland
2011-10-26 20:13               ` Jason Merrill
2011-10-27 19:15                 ` Ed Smith-Rowland
2011-10-27 19:55                 ` Ed Smith-Rowland
2011-10-27 20:37                   ` Jason Merrill
2011-10-30 19:10                     ` Ed Smith-Rowland
2011-10-31 17:52                       ` Jason Merrill
2011-10-25  7:07         ` Ed Smith-Rowland
2011-10-21 17:04 3dw4rd
2011-10-26 20:33 3dw4rd
2011-10-26 20:46 ` Jason Merrill
2011-10-31 17:58 3dw4rd
2011-10-31 20:20 ` Jason Merrill

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4E7008DA.6090703@redhat.com \
    --to=jason@redhat.com \
    --cc=3dw4rd@verizon.net \
    --cc=gcc-patches@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).