static tree get_variable_decl (tree exp) { if (TREE_CODE (exp) == VAR_DECL) { if (! TREE_STATIC (exp) || FIELD_FINAL (exp)) return exp; } /* We only care about final parameters. */ else if (TREE_CODE (exp) == PARM_DECL) { if (DECL_FINAL (exp)) return exp; } /* See if exp is this.field. */ else if (TREE_CODE (exp) == COMPONENT_REF) { tree op0 = TREE_OPERAND (exp, 0); tree op1 = TREE_OPERAND (exp, 1); tree mdecl = current_function_decl; if (TREE_CODE (op0) == INDIRECT_REF && TREE_CODE (op1) == FIELD_DECL && ! METHOD_STATIC (mdecl) && FIELD_FINAL (op1)) { op0 = TREE_OPERAND (op0, 0); if (op0 == BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (mdecl))) return op1; } } return NULL_TREE; }
static tree get_variable_decl (tree exp) { /* A static field can be wrapped in a COMPOUND_EXPR where the first argument initializes the class. */ if (TREE_CODE (exp) == COMPOUND_EXPR) exp = extract_field_decl (exp); if (TREE_CODE (exp) == VAR_DECL) { if (! TREE_STATIC (exp) || FIELD_FINAL (exp)) return exp; } /* We only care about final parameters. */ else if (TREE_CODE (exp) == PARM_DECL) { if (DECL_FINAL (exp)) return exp; } /* See if exp is this.field. */ else if (TREE_CODE (exp) == COMPONENT_REF) { tree op0 = TREE_OPERAND (exp, 0); tree op1 = TREE_OPERAND (exp, 1); tree mdecl = current_function_decl; if (TREE_CODE (op0) == INDIRECT_REF && TREE_CODE (op1) == FIELD_DECL && ! METHOD_STATIC (mdecl) && FIELD_FINAL (op1)) { op0 = TREE_OPERAND (op0, 0); if (op0 == BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (mdecl))) return op1; } } else if (TREE_CODE (exp) == INDIRECT_REF) { /* For indirect dispatch, look for an expression of the form (indirect_ref (+ (array_ref otable <N>) this)). FIXME: it would probably be better to generate a JAVA_FIELD_REF expression that gets converted to OTABLE access at gimplification time. */ exp = TREE_OPERAND (exp, 0); if (TREE_CODE (exp) == PLUS_EXPR) { tree op0 = TREE_OPERAND (exp, 0); STRIP_NOPS (op0); if (TREE_CODE (op0) == ARRAY_REF) { tree table = TREE_OPERAND (op0, 0); if (TREE_CODE (table) == VAR_DECL && DECL_LANG_SPECIFIC (table) && DECL_OWNER (table) && TYPE_OTABLE_DECL (DECL_OWNER (table)) == table) { HOST_WIDE_INT index = TREE_INT_CST_LOW (TREE_OPERAND (op0, 1)); tree otable_methods = TYPE_OTABLE_METHODS (DECL_OWNER (table)); tree element; for (element = otable_methods; element; element = TREE_CHAIN (element)) { if (index == 1) { tree purpose = TREE_PURPOSE (element); if (TREE_CODE (purpose) == FIELD_DECL) return purpose; else return NULL_TREE; } --index; } } } } } return NULL_TREE; }