aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/method.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/method.c')
-rw-r--r--gcc/cp/method.c64
1 files changed, 49 insertions, 15 deletions
diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index f606c7014c8..0621fe2b140 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -38,6 +38,7 @@ Boston, MA 02111-1307, USA. */
#include "target.h"
#include "cgraph.h"
#include "tree-pass.h"
+#include "diagnostic.h"
/* Various flags to control the mangling process. */
@@ -259,16 +260,10 @@ static GTY (()) int thunk_labelno;
/* Create a static alias to function. */
-static tree
-make_alias_for_thunk (tree function)
+tree
+make_alias_for (tree function, tree newid)
{
- tree alias;
- char buf[256];
-
- ASM_GENERATE_INTERNAL_LABEL (buf, "LTHUNK", thunk_labelno);
- thunk_labelno++;
- alias = build_decl (FUNCTION_DECL, get_identifier (buf),
- TREE_TYPE (function));
+ tree alias = build_decl (FUNCTION_DECL, newid, TREE_TYPE (function));
DECL_LANG_SPECIFIC (alias) = DECL_LANG_SPECIFIC (function);
cxx_dup_lang_specific_decl (alias);
DECL_CONTEXT (alias) = NULL;
@@ -297,8 +292,23 @@ make_alias_for_thunk (tree function)
TREE_USED (alias) = 1;
SET_DECL_ASSEMBLER_NAME (alias, DECL_NAME (alias));
TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (alias)) = 1;
+ return alias;
+}
+
+static tree
+make_alias_for_thunk (tree function)
+{
+ tree alias;
+ char buf[256];
+
+ ASM_GENERATE_INTERNAL_LABEL (buf, "LTHUNK", thunk_labelno);
+ thunk_labelno++;
+
+ alias = make_alias_for (function, get_identifier (buf));
+
if (!flag_syntax_only)
assemble_alias (alias, DECL_ASSEMBLER_NAME (function));
+
return alias;
}
@@ -725,6 +735,8 @@ do_build_assign_ref (tree fndecl)
finish_compound_stmt (compound_stmt);
}
+/* Synthesize FNDECL, a non-static member function. */
+
void
synthesize_method (tree fndecl)
{
@@ -733,17 +745,19 @@ synthesize_method (tree fndecl)
bool need_body = true;
tree stmt;
location_t save_input_location = input_location;
+ int error_count = errorcount;
+ int warning_count = warningcount;
+ /* Reset the source location, we might have been previously
+ deferred, and thus have saved where we were first needed. */
+ DECL_SOURCE_LOCATION (fndecl)
+ = DECL_SOURCE_LOCATION (TYPE_NAME (DECL_CONTEXT (fndecl)));
+
/* If we've been asked to synthesize a clone, just synthesize the
cloned function instead. Doing so will automatically fill in the
body for the clone. */
if (DECL_CLONED_FUNCTION_P (fndecl))
- {
- DECL_SOURCE_LOCATION (DECL_CLONED_FUNCTION (fndecl)) =
- DECL_SOURCE_LOCATION (fndecl);
- synthesize_method (DECL_CLONED_FUNCTION (fndecl));
- return;
- }
+ fndecl = DECL_CLONED_FUNCTION (fndecl);
/* We may be in the middle of deferred access check. Disable
it now. */
@@ -793,6 +807,10 @@ synthesize_method (tree fndecl)
pop_function_context_from (context);
pop_deferring_access_checks ();
+
+ if (error_count != errorcount || warning_count != warningcount)
+ warning (0, "%Hsynthesized method %qD first required here ",
+ &input_location, fndecl);
}
/* Use EXTRACTOR to locate the relevant function called for each base &
@@ -962,6 +980,19 @@ implicitly_declare_fn (special_function_kind kind, tree type, bool const_p)
tree raises = empty_except_spec;
tree rhs_parm_type = NULL_TREE;
tree name;
+ HOST_WIDE_INT saved_processing_template_decl;
+
+ /* Because we create declarations for implictly declared functions
+ lazily, we may be creating the declaration for a member of TYPE
+ while in some completely different context. However, TYPE will
+ never be a dependent class (because we never want to do lookups
+ for implicitly defined functions in a dependent class).
+ Furthermore, we must set PROCESSING_TEMPLATE_DECL to zero here
+ because we only create clones for constructors and destructors
+ when not in a template. */
+ gcc_assert (!dependent_type_p (type));
+ saved_processing_template_decl = processing_template_decl;
+ processing_template_decl = 0;
type = TYPE_MAIN_VARIANT (type);
@@ -1060,6 +1091,9 @@ implicitly_declare_fn (special_function_kind kind, tree type, bool const_p)
DECL_INLINE (fn) = 1;
gcc_assert (!TREE_USED (fn));
+ /* Restore PROCESSING_TEMPLATE_DECL. */
+ processing_template_decl = saved_processing_template_decl;
+
return fn;
}