@@ -30,6 +30,7 @@ along with GCC; see the file COPYING3. If not see
#include "flags.h"
#include "output.h"
#include "tree-iterator.h"
+#include "langhooks.h"
/* Create an empty statement tree rooted at T. */
@@ -42,7 +43,11 @@ push_stmt_list (void)
return t;
}
-/* Finish the statement tree rooted at T. */
+/* Finish the statement tree rooted at T. Note that this will call
+ lang_hooks.decls.statement_at_end_of_scope with the list of
+ statements of the current scope in argument. That language hook
+ expects input_location to be set to the closing '}' of the current
+ scope. */
tree
pop_stmt_list (tree t)
@@ -59,6 +64,7 @@ pop_stmt_list (tree t)
tree x = VEC_last (tree, stmt_list_stack);
STATEMENT_LIST_HAS_LABEL (x) |= STATEMENT_LIST_HAS_LABEL (u);
}
+ lang_hooks.decls.statement_at_end_of_scope (u);
if (t == u)
break;
}
@@ -284,7 +284,8 @@ cp/decl2.o: cp/decl2.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) cp/decl.h \
cp/cp-objcp-common.o : cp/cp-objcp-common.c $(CONFIG_H) $(SYSTEM_H) \
coretypes.h $(TM_H) $(TREE_H) $(CXX_TREE_H) $(C_COMMON_H) \
langhooks.h $(LANGHOOKS_DEF_H) $(DIAGNOSTIC_H) debug.h \
- $(CXX_PRETTY_PRINT_H) cp/cp-objcp-common.h gt-cp-cp-objcp-common.h
+ $(CXX_PRETTY_PRINT_H) cp/cp-objcp-common.h gt-cp-cp-objcp-common.h \
+ tree-iterator.h
cp/typeck2.o: cp/typeck2.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) output.h \
$(TM_P_H) $(DIAGNOSTIC_CORE_H) gt-cp-typeck2.h $(REAL_H) intl.h
cp/typeck.o: cp/typeck.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) \
@@ -32,6 +32,7 @@ along with GCC; see the file COPYING3. If not see
#include "debug.h"
#include "cxx-pretty-print.h"
#include "cp-objcp-common.h"
+#include "tree-iterator.h"
/* Special routine to get the alias set for C++. */
@@ -69,6 +70,37 @@ cxx_warn_unused_global_decl (const_tree decl)
return true;
}
+/* Langhook for struct
+ lang_hooks_for_decls::statement_at_end_of_scope. Is called at the
+ end of each scope with the statement list of that scope as an
+ argument. */
+
+void
+cxx_statement_at_end_of_scope (tree stmt_list)
+{
+ tree_stmt_iterator i;
+
+ if (stmt_list == NULL_TREE
+ || TREE_CODE (stmt_list) != STATEMENT_LIST)
+ return;
+
+ /* Let's find the CLEANUP_STMTs and set their location to input_location
+ that we expect to be the location of of the ending '}' of their
+ containing block. */
+ i = tsi_start (stmt_list);
+ for (i = tsi_start (stmt_list); !tsi_end_p (i); tsi_next (&i))
+ {
+ tree cleanup, stmt = tsi_stmt (i);
+ if (TREE_CODE (stmt) != CLEANUP_STMT)
+ continue;
+
+ cleanup = CLEANUP_EXPR (stmt);
+ if (cleanup != NULL_TREE
+ && IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (cleanup))))
+ SET_EXPR_LOCATION (cleanup, input_location);
+ }
+}
+
/* Langhook for tree_size: determine size of our 'x' and 'c' nodes. */
size_t
cp_tree_size (enum tree_code code)
@@ -84,6 +84,8 @@ extern void cp_common_init_ts (void);
#define LANG_HOOKS_PRINT_ERROR_FUNCTION cxx_print_error_function
#undef LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL
#define LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL cxx_warn_unused_global_decl
+#undef LANG_HOOKS_STATEMENT_AT_END_OF_SCOPE
+#define LANG_HOOKS_STATEMENT_AT_END_OF_SCOPE cxx_statement_at_end_of_scope
#undef LANG_HOOKS_WRITE_GLOBALS
#define LANG_HOOKS_WRITE_GLOBALS cp_write_global_declarations
#undef LANG_HOOKS_BUILTIN_FUNCTION
@@ -5873,6 +5873,7 @@ extern bool cp_dump_tree (void *, tree);
extern alias_set_type cxx_get_alias_set (tree);
extern bool cxx_warn_unused_global_decl (const_tree);
+extern void cxx_statement_at_end_of_scope (tree);
extern size_t cp_tree_size (enum tree_code);
extern bool cp_var_mod_type_p (tree, tree);
extern void cxx_initialize_diagnostics (diagnostic_context *);
@@ -8918,11 +8918,14 @@ cp_parser_compound_statement (cp_parser *parser, tree in_statement_expr,
cp_parser_label_declaration (parser);
/* Parse an (optional) statement-seq. */
cp_parser_statement_seq_opt (parser, in_statement_expr);
- /* Finish the compound-statement. */
- finish_compound_stmt (compound_stmt);
/* Consume the `}'. */
cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE);
-
+ /* Finish the compound-statement. Note that among other things,
+ this will call lang_hooks.decls.statement_at_end_of_scope (via
+ pop_stmt_list) with the list of statements in this scope and it
+ expects input_location to be set to the location of the
+ enclosing '}' that we just parsed above. */
+ finish_compound_stmt (compound_stmt);
return compound_stmt;
}
@@ -204,6 +204,7 @@ extern tree lhd_make_node (enum tree_code);
#define LANG_HOOKS_GETDECLS getdecls
#define LANG_HOOKS_FUNCTION_DECL_EXPLICIT_P hook_bool_tree_false
#define LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL lhd_warn_unused_global_decl
+#define LANG_HOOKS_STATEMENT_AT_END_OF_SCOPE hook_void_tree
#define LANG_HOOKS_WRITE_GLOBALS write_global_declarations
#define LANG_HOOKS_DECL_OK_FOR_SIBCALL lhd_decl_ok_for_sibcall
#define LANG_HOOKS_OMP_PRIVATIZE_BY_REFERENCE hook_bool_const_tree_false
@@ -227,6 +228,7 @@ extern tree lhd_make_node (enum tree_code);
LANG_HOOKS_FUNCTION_PARM_EXPANDED_FROM_PACK_P, \
LANG_HOOKS_GET_GENERIC_FUNCTION_DECL, \
LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL, \
+ LANG_HOOKS_STATEMENT_AT_END_OF_SCOPE, \
LANG_HOOKS_WRITE_GLOBALS, \
LANG_HOOKS_DECL_OK_FOR_SIBCALL, \
LANG_HOOKS_OMP_PRIVATIZE_BY_REFERENCE, \
@@ -180,6 +180,10 @@ struct lang_hooks_for_decls
We will already have checked that it has static binding. */
bool (*warn_unused_global) (const_tree);
+ /* Called on each statement, at the point of the of that
+ statement's scope. */
+ void (*statement_at_end_of_scope) (tree);
+
/* Obtain a list of globals and do final output on them at end
of compilation */
void (*final_write_globals) (void);
@@ -20,9 +20,9 @@ private:
void foo()
{
- C c; /* count(2) */
+ C c; /* count(1) */
c.seti (1); /* count(1) */
-}
+} /* count(1) <- destructor of c runs here. */
int main()
{