xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/cp/expr.c (revision bdc22b2e01993381dcefeff2bc9b56ca75a4235c)
1 /* Convert language-specific tree expression to rtl instructions,
2    for GNU compiler.
3    Copyright (C) 1988-2015 Free Software Foundation, Inc.
4 
5 This file is part of GCC.
6 
7 GCC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
10 any later version.
11 
12 GCC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3.  If not see
19 <http://www.gnu.org/licenses/>.  */
20 
21 
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "hash-set.h"
27 #include "machmode.h"
28 #include "vec.h"
29 #include "double-int.h"
30 #include "input.h"
31 #include "alias.h"
32 #include "symtab.h"
33 #include "wide-int.h"
34 #include "inchash.h"
35 #include "tree.h"
36 #include "flags.h"
37 #include "cp-tree.h"
38 #include "tm_p.h"
39 
40 /* Expand C++-specific constants.  Currently, this means PTRMEM_CST.  */
41 
42 tree
43 cplus_expand_constant (tree cst)
44 {
45   switch (TREE_CODE (cst))
46     {
47     case PTRMEM_CST:
48       {
49 	tree type = TREE_TYPE (cst);
50 	tree member;
51 
52 	/* Find the member.  */
53 	member = PTRMEM_CST_MEMBER (cst);
54 
55 	/* We can't lower this until the class is complete.  */
56 	if (!COMPLETE_TYPE_P (DECL_CONTEXT (member)))
57 	  return cst;
58 
59 	if (TREE_CODE (member) == FIELD_DECL)
60 	  {
61 	    /* Find the offset for the field.  */
62 	    cst = byte_position (member);
63 	    while (!same_type_p (DECL_CONTEXT (member),
64 				 TYPE_PTRMEM_CLASS_TYPE (type)))
65 	      {
66 		/* The MEMBER must have been nestled within an
67 		   anonymous aggregate contained in TYPE.  Find the
68 		   anonymous aggregate.  */
69 		member = lookup_anon_field (TYPE_PTRMEM_CLASS_TYPE (type),
70 					    DECL_CONTEXT (member));
71 		cst = size_binop (PLUS_EXPR, cst, byte_position (member));
72 	      }
73 	    cst = fold (build_nop (type, cst));
74 	  }
75 	else
76 	  {
77 	    tree delta;
78 	    tree pfn;
79 
80 	    expand_ptrmemfunc_cst (cst, &delta, &pfn);
81 	    cst = build_ptrmemfunc1 (type, delta, pfn);
82 	  }
83       }
84       break;
85 
86     case CONSTRUCTOR:
87       {
88 	constructor_elt *elt;
89 	unsigned HOST_WIDE_INT idx;
90 	FOR_EACH_VEC_SAFE_ELT (CONSTRUCTOR_ELTS (cst), idx, elt)
91 	  elt->value = cplus_expand_constant (elt->value);
92       }
93 
94     default:
95       /* There's nothing to do.  */
96       break;
97     }
98 
99   return cst;
100 }
101 
102 /* Called whenever an expression is used
103    in a rvalue context.  */
104 
105 tree
106 mark_rvalue_use (tree expr)
107 {
108   mark_exp_read (expr);
109   return expr;
110 }
111 
112 /* Called whenever an expression is used
113    in a lvalue context.  */
114 
115 tree
116 mark_lvalue_use (tree expr)
117 {
118   mark_exp_read (expr);
119   return expr;
120 }
121 
122 /* Called whenever an expression is used in a type use context.  */
123 
124 tree
125 mark_type_use (tree expr)
126 {
127   mark_exp_read (expr);
128   return expr;
129 }
130 
131 /* Mark EXP as read, not just set, for set but not used -Wunused
132    warning purposes.  */
133 
134 void
135 mark_exp_read (tree exp)
136 {
137   if (exp == NULL)
138     return;
139 
140   switch (TREE_CODE (exp))
141     {
142     case VAR_DECL:
143     case PARM_DECL:
144       DECL_READ_P (exp) = 1;
145       break;
146     case ARRAY_REF:
147     case COMPONENT_REF:
148     case MODIFY_EXPR:
149     case REALPART_EXPR:
150     case IMAGPART_EXPR:
151     CASE_CONVERT:
152     case ADDR_EXPR:
153     case INDIRECT_REF:
154     case FLOAT_EXPR:
155       mark_exp_read (TREE_OPERAND (exp, 0));
156       break;
157     case COMPOUND_EXPR:
158       mark_exp_read (TREE_OPERAND (exp, 1));
159       break;
160     case COND_EXPR:
161       if (TREE_OPERAND (exp, 1))
162 	mark_exp_read (TREE_OPERAND (exp, 1));
163       if (TREE_OPERAND (exp, 2))
164 	mark_exp_read (TREE_OPERAND (exp, 2));
165       break;
166     default:
167       break;
168     }
169 }
170 
171