diff options
author | Nathan Sidwell <nathan@acm.org> | 2020-09-14 09:42:29 -0700 |
---|---|---|
committer | Nathan Sidwell <nathan@acm.org> | 2020-09-14 09:45:24 -0700 |
commit | e9fdb9a73249f95f3da2d7fde6f268ae12d0d22c (patch) | |
tree | bc6b255876ccd75fd7e03e5d271d7b929305ce96 /gcc | |
parent | 05ab8befe1230c46116aae37d44f2ce0933e8dae (diff) | |
download | gcc-e9fdb9a73249f95f3da2d7fde6f268ae12d0d22c.zip gcc-e9fdb9a73249f95f3da2d7fde6f268ae12d0d22c.tar.gz gcc-e9fdb9a73249f95f3da2d7fde6f268ae12d0d22c.tar.bz2 |
c++: local externs in templates do not get template head
Now we consistently mark local externs with DECL_LOCAL_DECL_P, we can
teach the template machinery not to give them a TEMPLATE_DECL head,
and the instantiation machinery treat them as the local specialiations
they are. (openmp UDRs also fall into this category, and are dealt
with similarly.)
gcc/cp/
* pt.c (push_template_decl_real): Don't attach a template head to
local externs.
(tsubst_function_decl): Add support for headless local extern
decls.
(tsubst_decl): Add support for headless local extern decls.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/pt.c | 47 |
1 files changed, 27 insertions, 20 deletions
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 0f52a9e..8124efc 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -6071,7 +6071,11 @@ push_template_decl_real (tree decl, bool is_friend) { if (is_primary) retrofit_lang_decl (decl); - if (DECL_LANG_SPECIFIC (decl)) + if (DECL_LANG_SPECIFIC (decl) + && ((TREE_CODE (decl) != VAR_DECL + && TREE_CODE (decl) != FUNCTION_DECL) + || !ctx + || !DECL_LOCAL_DECL_P (decl))) DECL_TEMPLATE_INFO (decl) = info; } @@ -13701,14 +13705,20 @@ static tree tsubst_function_decl (tree t, tree args, tsubst_flags_t complain, tree lambda_fntype) { - tree gen_tmpl, argvec; + tree gen_tmpl = NULL_TREE, argvec = NULL_TREE; hashval_t hash = 0; tree in_decl = t; /* Nobody should be tsubst'ing into non-template functions. */ - gcc_assert (DECL_TEMPLATE_INFO (t) != NULL_TREE); + gcc_assert (DECL_TEMPLATE_INFO (t) != NULL_TREE + || DECL_LOCAL_DECL_P (t)); - if (TREE_CODE (DECL_TI_TEMPLATE (t)) == TEMPLATE_DECL) + if (DECL_LOCAL_DECL_P (t)) + { + if (tree spec = retrieve_local_specialization (t)) + return spec; + } + else if (TREE_CODE (DECL_TI_TEMPLATE (t)) == TEMPLATE_DECL) { /* If T is not dependent, just return it. */ if (!uses_template_parms (DECL_TI_ARGS (t)) @@ -13958,6 +13968,11 @@ tsubst_function_decl (tree t, tree args, tsubst_flags_t complain, && !uses_template_parms (argvec)) tsubst_default_arguments (r, complain); } + else if (DECL_LOCAL_DECL_P (r)) + { + if (!cp_unevaluated_operand) + register_local_specialization (r, t); + } else DECL_TEMPLATE_INFO (r) = NULL_TREE; @@ -14503,11 +14518,8 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) { tree argvec = NULL_TREE; tree gen_tmpl = NULL_TREE; - tree spec; tree tmpl = NULL_TREE; - tree ctx; tree type = NULL_TREE; - bool local_p; if (TREE_TYPE (t) == error_mark_node) RETURN (error_mark_node); @@ -14529,19 +14541,13 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) /* Check to see if we already have the specialization we need. */ - spec = NULL_TREE; - if (DECL_CLASS_SCOPE_P (t) || DECL_NAMESPACE_SCOPE_P (t)) + tree spec = NULL_TREE; + bool local_p = false; + tree ctx = DECL_CONTEXT (t); + if (!(VAR_P (t) && DECL_LOCAL_DECL_P (t)) + && (DECL_CLASS_SCOPE_P (t) || DECL_NAMESPACE_SCOPE_P (t))) { - /* T is a static data member or namespace-scope entity. - We have to substitute into namespace-scope variables - (not just variable templates) because of cases like: - - template <class T> void f() { extern T t; } - - where the entity referenced is not known until - instantiation time. */ local_p = false; - ctx = DECL_CONTEXT (t); if (DECL_CLASS_SCOPE_P (t)) { ctx = tsubst_aggr_type (ctx, args, @@ -14581,10 +14587,11 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) } else { + if (!(VAR_P (t) && DECL_LOCAL_DECL_P (t))) + /* Subsequent calls to pushdecl will fill this in. */ + ctx = NULL_TREE; /* A local variable. */ local_p = true; - /* Subsequent calls to pushdecl will fill this in. */ - ctx = NULL_TREE; /* Unless this is a reference to a static variable from an enclosing function, in which case we need to fill it in now. */ if (TREE_STATIC (t)) |