* builtin-types.def (BT_FN_CONST_STRING): Add.
* builtins.def (BUILT_IN_FILE, BUILT_IN_FUNCTION,
BUILT_IN_LINE): New builtins.
* gimplify.c (gimplify_call_expr): Expand them.
* doc/extend.texi (__builtin_LINE, __builtin_FUNCTION,
__builtin_FILE): Document.
* g++.dg/torture/builtin-location.C: New testcase.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@191290
138bc75d-0d04-0410-961f-
82ee72b054a4
+2012-09-14 Richard Guenther <rguenther@suse.de>
+
+ * builtin-types.def (BT_FN_CONST_STRING): Add.
+ * builtins.def (BUILT_IN_FILE, BUILT_IN_FUNCTION,
+ BUILT_IN_LINE): New builtins.
+ * gimplify.c (gimplify_call_expr): Expand them.
+ * doc/extend.texi (__builtin_LINE, __builtin_FUNCTION,
+ __builtin_FILE): Document.
+
2012-09-13 Anthony Green <green@moxielogic.com>
* config/moxie/moxie.h (LINK_SPEC): Add bi-endian support.
DEF_FUNCTION_TYPE_0 (BT_FN_VOID, BT_VOID)
DEF_FUNCTION_TYPE_0 (BT_FN_BOOL, BT_BOOL)
DEF_FUNCTION_TYPE_0 (BT_FN_PTR, BT_PTR)
+DEF_FUNCTION_TYPE_0 (BT_FN_CONST_STRING, BT_CONST_STRING)
DEF_FUNCTION_TYPE_0 (BT_FN_PID, BT_PID)
DEF_FUNCTION_TYPE_0 (BT_FN_INT, BT_INT)
DEF_FUNCTION_TYPE_0 (BT_FN_UINT, BT_UINT)
DEF_BUILTIN_STUB (BUILT_IN_EH_FILTER, "__builtin_eh_filter")
DEF_BUILTIN_STUB (BUILT_IN_EH_COPY_VALUES, "__builtin_eh_copy_values")
+/* __FILE__, __LINE__, __FUNCTION__ as builtins. */
+DEF_GCC_BUILTIN (BUILT_IN_FILE, "FILE", BT_FN_CONST_STRING, ATTR_NOTHROW_LEAF_LIST)
+DEF_GCC_BUILTIN (BUILT_IN_FUNCTION, "FUNCTION", BT_FN_CONST_STRING, ATTR_NOTHROW_LEAF_LIST)
+DEF_GCC_BUILTIN (BUILT_IN_LINE, "LINE", BT_FN_INT, ATTR_NOTHROW_LEAF_LIST)
+
/* Synchronization Primitives. */
#include "sync-builtins.def"
(char *) x - 8 is 32 byte aligned.
@end deftypefn
+@deftypefn {Built-in Function} int __builtin_LINE ()
+This function is the equivalent to the preprocessor @code{__LINE__}
+macro and returns the line number of the invocation of the built-in.
+@end deftypefn
+
+@deftypefn {Built-in Function} int __builtin_FUNCTION ()
+This function is the equivalent to the preprocessor @code{__FUNCTION__}
+macro and returns the function name the invocation of the built-in is in.
+@end deftypefn
+
+@deftypefn {Built-in Function} int __builtin_FILE ()
+This function is the equivalent to the preprocessor @code{__FILE__}
+macro and returns the file name the invocation of the built-in is in.
+@end deftypefn
+
@deftypefn {Built-in Function} void __builtin___clear_cache (char *@var{begin}, char *@var{end})
This function is used to flush the processor's instruction cache for
the region of memory between @var{begin} inclusive and @var{end}
transform all calls in the same manner as the expanders do, but
we do transform most of them. */
fndecl = get_callee_fndecl (*expr_p);
- if (fndecl && DECL_BUILT_IN (fndecl))
- {
- tree new_tree = fold_call_expr (input_location, *expr_p, !want_value);
-
- if (new_tree && new_tree != *expr_p)
- {
- /* There was a transformation of this call which computes the
- same value, but in a more efficient way. Return and try
- again. */
- *expr_p = new_tree;
- return GS_OK;
- }
-
- if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
- && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_VA_START)
+ if (fndecl
+ && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
+ switch (DECL_FUNCTION_CODE (fndecl))
+ {
+ case BUILT_IN_VA_START:
{
builtin_va_start_p = TRUE;
if (call_expr_nargs (*expr_p) < 2)
*expr_p = build_empty_stmt (EXPR_LOCATION (*expr_p));
return GS_OK;
}
+ break;
+ }
+ case BUILT_IN_LINE:
+ {
+ expanded_location loc = expand_location (EXPR_LOCATION (*expr_p));
+ *expr_p = build_int_cst (TREE_TYPE (*expr_p), loc.line);
+ return GS_OK;
+ }
+ case BUILT_IN_FILE:
+ {
+ expanded_location loc = expand_location (EXPR_LOCATION (*expr_p));
+ *expr_p = build_string_literal (strlen (loc.file) + 1, loc.file);
+ return GS_OK;
+ }
+ case BUILT_IN_FUNCTION:
+ {
+ const char *function;
+ function = IDENTIFIER_POINTER (DECL_NAME (current_function_decl));
+ *expr_p = build_string_literal (strlen (function) + 1, function);
+ return GS_OK;
+ }
+ default:
+ ;
+ }
+ if (fndecl && DECL_BUILT_IN (fndecl))
+ {
+ tree new_tree = fold_call_expr (input_location, *expr_p, !want_value);
+ if (new_tree && new_tree != *expr_p)
+ {
+ /* There was a transformation of this call which computes the
+ same value, but in a more efficient way. Return and try
+ again. */
+ *expr_p = new_tree;
+ return GS_OK;
}
}
+2012-09-14 Richard Guenther <rguenther@suse.de>
+
+ * g++.dg/torture/builtin-location.C: New testcase.
+
2012-09-13 Paolo Carlini <paolo.carlini@oracle.com>
Manuel López-Ibáñez <manu@gcc.gnu.org>
--- /dev/null
+// { dg-do run }
+
+#include <cstring>
+
+const char *gfile;
+const char *gfn;
+int gline;
+
+void bar (const char *file = __builtin_FILE (),
+ const char *function = __builtin_FUNCTION (),
+ int line = __builtin_LINE ())
+{
+ gfile = file;
+ gfn = function;
+ gline = line;
+}
+
+extern "C" void abort (void);
+
+int main()
+{
+ int here;
+ bar (); here = __LINE__;
+ if (std::strcmp (gfn, __FUNCTION__) != 0)
+ abort ();
+ if (std::strcmp (gfile, __FILE__) != 0)
+ abort ();
+ if (gline != here)
+ abort ();
+ return 0;
+}