Advertisement

このページを編集する際は,編集に関する方針に従ってください.

概要

4846 /* Expand EXP, a call to printf or printf_unlocked.
4847    Return 0 if a normal call should be emitted rather than transforming
4848    the function inline.  If convenient, the result should be placed in
4849    TARGET with mode MODE.  UNLOCKED indicates this is a printf_unlocked
4850    call.  */

例えば printf("hoge\n"); は puts("hoge"); に,printf("%c", c) は putchar(c) に展開される.


ネタ元 : http://www.issei.org/diary/_20030224/d200101a.html#05-1-3

引数

  • rtx
    • Register Transfer languate eXpression code (struct rtx)

実装


4851 static rtx
4852 expand_builtin_printf (tree exp, rtx target, enum machine_mode mode,
4853                        bool unlocked)
4854 {
4855   tree arglist = TREE_OPERAND (exp, 1);
 4856   /* If we're using an unlocked function, assume the other unlocked
 4857      functions exist explicitly.  */
4858   tree const fn_putchar = unlocked ? built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED]
4859     : implicit_built_in_decls[BUILT_IN_PUTCHAR];
4860   tree const fn_puts = unlocked ? built_in_decls[BUILT_IN_PUTS_UNLOCKED]
4861     : implicit_built_in_decls[BUILT_IN_PUTS];
4862   const char *fmt_str;
4863   tree fn, fmt, arg;
4864 
 4865   /* If the return value is used, don't do the transformation.  */
4866   if (target != const0_rtx)
4867     return 0;
4868 
 4869   /* Verify the required arguments in the original call.  */
4870   if (! arglist)
4871     return 0;
4872   fmt = TREE_VALUE (arglist);
4873   if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
4874     return 0;
4875   arglist = TREE_CHAIN (arglist);
4876 
 4877   /* Check whether the format is a literal string constant.  */
4878   fmt_str = c_getstr (fmt);
4879   if (fmt_str == NULL)
4880     return 0;
4881 
4882   if (!init_target_chars())
4883     return 0;
 4885   /* If the format specifier was "%s\n", call __builtin_puts(arg).  */
4886   if (strcmp (fmt_str, target_percent_s_newline) == 0)
4887     {
4888       if (! arglist
4889           || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
4890           || TREE_CHAIN (arglist))
4891         return 0;
4892       fn = fn_puts;
4893     }
 4894   /* If the format specifier was "%c", call __builtin_putchar(arg).  */
4895   else if (strcmp (fmt_str, target_percent_c) == 0)
4896     {
4897       if (! arglist
4898           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
4899           || TREE_CHAIN (arglist))
4900         return 0;
4901       fn = fn_putchar;
4902     }
4903   else
4904     {
 4905       /* We can't handle anything else with % args or %% ... yet.  */
4906       if (strchr (fmt_str, target_percent))
4907         return 0;
4908 
4909       if (arglist)
4910         return 0;
4911 
 4912       /* If the format specifier was "", printf does nothing.  */
4913       if (fmt_str[0] == '\0')
4914         return const0_rtx;
 4915       /* If the format specifier has length of 1, call putchar.  */
4916       if (fmt_str[1] == '\0')
4917         {
 4918           /* Given printf("c"), (where c is any one character,)
 4919              convert "c"[0] to an int and pass that to the replacement
 4920              function.  */
4921           arg = build_int_cst (NULL_TREE, fmt_str[0]);
4922           arglist = build_tree_list (NULL_TREE, arg);
4923           fn = fn_putchar;
4924         }
4925       else
4926         {
 4927           /* If the format specifier was "string\n", call puts("string").  */
4928           size_t len = strlen (fmt_str);
4929           if ((unsigned char)fmt_str[len - 1] == target_newline)
4930             {
 4931               /* Create a NUL-terminated string that's one char shorter
 4932                  than the original, stripping off the trailing '\n'.  */
4933               char *newstr = alloca (len);
4934               memcpy (newstr, fmt_str, len - 1);
4935               newstr[len - 1] = 0;
4936 
4937               arg = build_string_literal (len, newstr);
4938               arglist = build_tree_list (NULL_TREE, arg);
4939               fn = fn_puts;
4940             }
4941           else
 4942             /* We'd like to arrange to call fputs(string,stdout) here,
 4943                but we need stdout and don't have a way to get it yet.  */
4944             return 0;
4945         }
4946     }
4947 
4948   if (!fn)
4949     return 0;
4950   fn = build_function_call_expr (fn, arglist);
4951   if (TREE_CODE (fn) == CALL_EXPR)
4952     CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
4953   return expand_expr (fn, target, mode, EXPAND_NORMAL);
4954 }



リンク元

特に記載のない限り、コミュニティのコンテンツはCC-BY-SAライセンスの下で利用可能です。