diff options
Diffstat (limited to 'gcc/cp/method.c')
-rw-r--r-- | gcc/cp/method.c | 64 |
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; } |