-
-/* This section of the code handle assignment check with FINAL
- variables. */
-
-static void
-reset_static_final_variable_assignment_flag (class)
- tree class;
-{
- tree field;
- for (field = TYPE_FIELDS (class); field; field = TREE_CHAIN (field))
- if (CLASS_FINAL_VARIABLE_P (field))
- DECL_FIELD_FINAL_LIIC (field) = 0;
-}
-
-/* Figure whether all final static variable have been initialized. */
-
-static void
-check_static_final_variable_assignment_flag (class)
- tree class;
-{
- tree field;
-
- for (field = TYPE_FIELDS (class); field; field = TREE_CHAIN (field))
- if (CLASS_FINAL_VARIABLE_P (field)
- && !DECL_FIELD_FINAL_IUD (field) && !DECL_FIELD_FINAL_LIIC (field))
- parse_error_context
- (DECL_FIELD_FINAL_WFL (field),
- "Blank static final variable `%s' may not have been initialized",
- IDENTIFIER_POINTER (DECL_NAME (field)));
-}
-
-/* This function marks all final variable locally unassigned. */
-
-static void
-reset_final_variable_local_assignment_flag (class)
- tree class;
-{
- tree field;
- for (field = TYPE_FIELDS (class); field; field = TREE_CHAIN (field))
- if (FINAL_VARIABLE_P (field))
- DECL_FIELD_FINAL_LIIC (field) = 0;
-}
-
-/* Figure whether all final variables have beem initialized in MDECL
- and mark MDECL accordingly. */
-
-static void
-check_final_variable_local_assignment_flag (class, mdecl)
- tree class;
- tree mdecl;
-{
- tree field;
- int initialized = 0;
- int non_initialized = 0;
-
- if (DECL_FUNCTION_SYNTHETIC_CTOR (mdecl))
- return;
-
- /* First find out whether all final variables or no final variable
- are initialized in this ctor. We don't take into account final
- variable that have been initialized upon declaration. */
- for (field = TYPE_FIELDS (class); field; field = TREE_CHAIN (field))
- if (FINAL_VARIABLE_P (field) && !DECL_FIELD_FINAL_IUD (field))
- {
- if (DECL_FIELD_FINAL_LIIC (field))
- initialized++;
- else
- non_initialized++;
- }
-
- /* There were no non initialized variable and no initialized variable.
- This ctor is fine. */
- if (!non_initialized && !initialized)
- DECL_FUNCTION_ALL_FINAL_INITIALIZED (mdecl) = 1;
- /* If no variables have been initialized, that fine. We'll check
- later whether this ctor calls a constructor which initializes
- them. We mark the ctor as not initializing all its finals. */
- else if (initialized == 0)
- DECL_FUNCTION_ALL_FINAL_INITIALIZED (mdecl) = 0;
- /* If we have a mixed bag, then we have a problem. We need to report
- all the variables we're not initializing. */
- else if (initialized && non_initialized)
- {
- DECL_FUNCTION_ALL_FINAL_INITIALIZED (mdecl) = 0;
- for (field = TYPE_FIELDS (class); field; field = TREE_CHAIN (field))
- if (FIELD_FINAL (field)
- && !DECL_FIELD_FINAL_IUD (field) && !DECL_FIELD_FINAL_LIIC (field))
- {
- parse_error_context
- (lookup_cl (mdecl),
- "Blank final variable `%s' may not have been initialized in this constructor",
- IDENTIFIER_POINTER (DECL_NAME (field)));
- DECL_FIELD_FINAL_IERR (field) = 1;
- }
- }
- /* Otherwise we know this ctor is initializing all its final
- variable. We mark it so. */
- else
- DECL_FUNCTION_ALL_FINAL_INITIALIZED (mdecl) = 1;
-}
-
-/* This function recurses in a simple what through STMT and stops when
- it finds a constructor call. It then verifies that the called
- constructor initialized its final properly. Return 1 upon success,
- 0 or -1 otherwise. */
-
-static int
-check_final_variable_indirect_assignment (stmt)
- tree stmt;
-{
- int res;
- switch (TREE_CODE (stmt))
- {
- case EXPR_WITH_FILE_LOCATION:
- return check_final_variable_indirect_assignment (EXPR_WFL_NODE (stmt));
- case COMPOUND_EXPR:
- res = check_final_variable_indirect_assignment (TREE_OPERAND (stmt, 0));
- if (res)
- return res;
- return check_final_variable_indirect_assignment (TREE_OPERAND (stmt, 1));
- case SAVE_EXPR:
- return check_final_variable_indirect_assignment (TREE_OPERAND (stmt, 0));
- case CALL_EXPR:
- {
- tree decl = TREE_OPERAND (stmt, 0);
- tree fbody;
-
- if (TREE_CODE (decl) != FUNCTION_DECL)
- decl = TREE_OPERAND (TREE_OPERAND (decl, 0), 0);
- if (TREE_CODE (decl) != FUNCTION_DECL)
- abort ();
- if (DECL_FUNCTION_ALL_FINAL_INITIALIZED (decl))
- return 1;
- if (DECL_FINIT_P (decl) || DECL_CONTEXT (decl) != current_class)
- return -1;
- fbody = BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (decl));
- if (fbody == error_mark_node)
- return -1;
- fbody = BLOCK_EXPR_BODY (fbody);
- return check_final_variable_indirect_assignment (fbody);
- }
- default:
- break;
- }
- return 0;
-}
-
-/* This is the last chance to catch a final variable initialization
- problem. This routine will report an error if a final variable was
- never (globally) initialized and never reported as not having been
- initialized properly. */
-
-static void
-check_final_variable_global_assignment_flag (class)
- tree class;
-{
- tree field, mdecl;
- int nnctor = 0;
-
- /* We go through all natural ctors and see whether they're
- initializing all their final variables or not. */
- current_function_decl = NULL_TREE; /* For the error report. */
- for (mdecl = TYPE_METHODS (class); mdecl; mdecl = TREE_CHAIN (mdecl))
- if (DECL_CONSTRUCTOR_P (mdecl) && ! DECL_FUNCTION_SYNTHETIC_CTOR (mdecl))
- {
- if (!DECL_FUNCTION_ALL_FINAL_INITIALIZED (mdecl))
- {
- /* It doesn't. Maybe it calls a constructor that initializes
- them. find out. */
- tree fbody = BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (mdecl));
- if (fbody == error_mark_node)
- continue;
- fbody = BLOCK_EXPR_BODY (fbody);
- if (check_final_variable_indirect_assignment (fbody) == 1)
- {
- DECL_FUNCTION_ALL_FINAL_INITIALIZED (mdecl) = 1;
- nnctor++;
- }
- else
- parse_error_context
- (lookup_cl (mdecl),
- "Final variable initialization error in this constructor");
- }
- else
- nnctor++;
- }
-
- /* Finally we catch final variables that never were initialized */
- for (field = TYPE_FIELDS (class); field; field = TREE_CHAIN (field))
- if (FINAL_VARIABLE_P (field)
- /* If the field wasn't initialized upon declaration */
- && !DECL_FIELD_FINAL_IUD (field)
- /* There wasn't natural ctor in which the field could have been
- initialized */
- && !nnctor
- /* If we never reported a problem with this field */
- && !DECL_FIELD_FINAL_IERR (field))
- {
- current_function_decl = NULL;
- parse_error_context
- (DECL_FIELD_FINAL_WFL (field),
- "Final variable `%s' hasn't been initialized upon its declaration",
- IDENTIFIER_POINTER (DECL_NAME (field)));
- }
-
-}
-