Mercurial > hg > CbC > CbC_gcc
comparison gcc/go/gofrontend/gogo.cc @ 131:84e7813d76e9
gcc-8.2
author | mir3636 |
---|---|
date | Thu, 25 Oct 2018 07:37:49 +0900 |
parents | 04ced10e8804 |
children | 1830386684a0 |
comparison
equal
deleted
inserted
replaced
111:04ced10e8804 | 131:84e7813d76e9 |
---|---|
53 c_header_(), | 53 c_header_(), |
54 check_divide_by_zero_(true), | 54 check_divide_by_zero_(true), |
55 check_divide_overflow_(true), | 55 check_divide_overflow_(true), |
56 compiling_runtime_(false), | 56 compiling_runtime_(false), |
57 debug_escape_level_(0), | 57 debug_escape_level_(0), |
58 nil_check_size_threshold_(4096), | |
58 verify_types_(), | 59 verify_types_(), |
59 interface_types_(), | 60 interface_types_(), |
60 specific_type_functions_(), | 61 specific_type_functions_(), |
61 specific_type_functions_are_written_(false), | 62 specific_type_functions_are_written_(false), |
62 named_types_are_converted_(false), | 63 named_types_are_converted_(false), |
708 std::string user_name = ii->package_name() + ".init"; | 709 std::string user_name = ii->package_name() + ".init"; |
709 const std::string& init_name(ii->init_name()); | 710 const std::string& init_name(ii->init_name()); |
710 | 711 |
711 Bfunction* pfunc = this->backend()->function(fntype, user_name, init_name, | 712 Bfunction* pfunc = this->backend()->function(fntype, user_name, init_name, |
712 true, true, true, false, | 713 true, true, true, false, |
713 false, unknown_loc); | 714 false, false, unknown_loc); |
714 Bexpression* pfunc_code = | 715 Bexpression* pfunc_code = |
715 this->backend()->function_code_expression(pfunc, unknown_loc); | 716 this->backend()->function_code_expression(pfunc, unknown_loc); |
716 Bexpression* pfunc_call = | 717 Bexpression* pfunc_call = |
717 this->backend()->call_expression(bfunction, pfunc_code, empty_args, | 718 this->backend()->call_expression(bfunction, pfunc_code, empty_args, |
718 NULL, unknown_loc); | 719 NULL, unknown_loc); |
907 return NULL; | 908 return NULL; |
908 } | 909 } |
909 return initfn; | 910 return initfn; |
910 } | 911 } |
911 | 912 |
912 // Search for references to VAR in any statements or called functions. | 913 // Given an expression, collect all the global variables defined in |
913 | 914 // this package that it references. |
914 class Find_var : public Traverse | 915 |
915 { | 916 class Find_vars : public Traverse |
917 { | |
918 private: | |
919 // The list of variables we accumulate. | |
920 typedef Unordered_set(Named_object*) Vars; | |
921 | |
922 // A hash table we use to avoid looping. The index is a | |
923 // Named_object* or a Temporary_statement*. We only look through | |
924 // objects defined in this package. | |
925 typedef Unordered_set(const void*) Seen_objects; | |
926 | |
916 public: | 927 public: |
917 // A hash table we use to avoid looping. The index is the name of a | 928 Find_vars() |
918 // named object. We only look through objects defined in this | |
919 // package. | |
920 typedef Unordered_set(const void*) Seen_objects; | |
921 | |
922 Find_var(Named_object* var, Seen_objects* seen_objects) | |
923 : Traverse(traverse_expressions), | 929 : Traverse(traverse_expressions), |
924 var_(var), seen_objects_(seen_objects), found_(false) | 930 vars_(), seen_objects_() |
925 { } | 931 { } |
926 | 932 |
927 // Whether the variable was found. | 933 // An iterator through the variables found, after the traversal. |
928 bool | 934 typedef Vars::const_iterator const_iterator; |
929 found() const | 935 |
930 { return this->found_; } | 936 const_iterator |
937 begin() const | |
938 { return this->vars_.begin(); } | |
939 | |
940 const_iterator | |
941 end() const | |
942 { return this->vars_.end(); } | |
931 | 943 |
932 int | 944 int |
933 expression(Expression**); | 945 expression(Expression**); |
934 | 946 |
935 private: | 947 private: |
936 // The variable we are looking for. | 948 // Accumulated variables. |
937 Named_object* var_; | 949 Vars vars_; |
938 // Names of objects we have already seen. | 950 // Objects we have already seen. |
939 Seen_objects* seen_objects_; | 951 Seen_objects seen_objects_; |
940 // True if the variable was found. | |
941 bool found_; | |
942 }; | 952 }; |
943 | 953 |
944 // See if EXPR refers to VAR, looking through function calls and | 954 // Collect global variables referenced by EXPR. Look through function |
945 // variable initializations. | 955 // calls and variable initializations. |
946 | 956 |
947 int | 957 int |
948 Find_var::expression(Expression** pexpr) | 958 Find_vars::expression(Expression** pexpr) |
949 { | 959 { |
950 Expression* e = *pexpr; | 960 Expression* e = *pexpr; |
951 | 961 |
952 Var_expression* ve = e->var_expression(); | 962 Var_expression* ve = e->var_expression(); |
953 if (ve != NULL) | 963 if (ve != NULL) |
954 { | 964 { |
955 Named_object* v = ve->named_object(); | 965 Named_object* v = ve->named_object(); |
956 if (v == this->var_) | 966 if (!v->is_variable() || v->package() != NULL) |
957 { | 967 { |
958 this->found_ = true; | 968 // This is a result parameter or a variable defined in a |
959 return TRAVERSE_EXIT; | 969 // different package. Either way we don't care about it. |
960 } | 970 return TRAVERSE_CONTINUE; |
961 | 971 } |
962 if (v->is_variable() && v->package() == NULL) | 972 |
963 { | 973 std::pair<Seen_objects::iterator, bool> ins = |
964 Expression* init = v->var_value()->init(); | 974 this->seen_objects_.insert(v); |
965 if (init != NULL) | 975 if (!ins.second) |
966 { | 976 { |
967 std::pair<Seen_objects::iterator, bool> ins = | 977 // We've seen this variable before. |
968 this->seen_objects_->insert(v); | 978 return TRAVERSE_CONTINUE; |
969 if (ins.second) | 979 } |
970 { | 980 |
971 // This is the first time we have seen this name. | 981 if (v->var_value()->is_global()) |
972 if (Expression::traverse(&init, this) == TRAVERSE_EXIT) | 982 this->vars_.insert(v); |
973 return TRAVERSE_EXIT; | 983 |
974 } | 984 Expression* init = v->var_value()->init(); |
975 } | 985 if (init != NULL) |
986 { | |
987 if (Expression::traverse(&init, this) == TRAVERSE_EXIT) | |
988 return TRAVERSE_EXIT; | |
976 } | 989 } |
977 } | 990 } |
978 | 991 |
979 // We traverse the code of any function or bound method we see. Note that | 992 // We traverse the code of any function or bound method we see. Note that |
980 // this means that we will traverse the code of a function or bound method | 993 // this means that we will traverse the code of a function or bound method |
985 { | 998 { |
986 const Named_object* f = fe != NULL ? fe->named_object() : bme->function(); | 999 const Named_object* f = fe != NULL ? fe->named_object() : bme->function(); |
987 if (f->is_function() && f->package() == NULL) | 1000 if (f->is_function() && f->package() == NULL) |
988 { | 1001 { |
989 std::pair<Seen_objects::iterator, bool> ins = | 1002 std::pair<Seen_objects::iterator, bool> ins = |
990 this->seen_objects_->insert(f); | 1003 this->seen_objects_.insert(f); |
991 if (ins.second) | 1004 if (ins.second) |
992 { | 1005 { |
993 // This is the first time we have seen this name. | 1006 // This is the first time we have seen this name. |
994 if (f->func_value()->block()->traverse(this) == TRAVERSE_EXIT) | 1007 if (f->func_value()->block()->traverse(this) == TRAVERSE_EXIT) |
995 return TRAVERSE_EXIT; | 1008 return TRAVERSE_EXIT; |
1003 Temporary_statement* ts = tre->statement(); | 1016 Temporary_statement* ts = tre->statement(); |
1004 Expression* init = ts->init(); | 1017 Expression* init = ts->init(); |
1005 if (init != NULL) | 1018 if (init != NULL) |
1006 { | 1019 { |
1007 std::pair<Seen_objects::iterator, bool> ins = | 1020 std::pair<Seen_objects::iterator, bool> ins = |
1008 this->seen_objects_->insert(ts); | 1021 this->seen_objects_.insert(ts); |
1009 if (ins.second) | 1022 if (ins.second) |
1010 { | 1023 { |
1011 // This is the first time we have seen this temporary | 1024 // This is the first time we have seen this temporary |
1012 // statement. | 1025 // statement. |
1013 if (Expression::traverse(&init, this) == TRAVERSE_EXIT) | 1026 if (Expression::traverse(&init, this) == TRAVERSE_EXIT) |
1023 | 1036 |
1024 static bool | 1037 static bool |
1025 expression_requires(Expression* expr, Block* preinit, Named_object* dep, | 1038 expression_requires(Expression* expr, Block* preinit, Named_object* dep, |
1026 Named_object* var) | 1039 Named_object* var) |
1027 { | 1040 { |
1028 Find_var::Seen_objects seen_objects; | 1041 Find_vars find_vars; |
1029 Find_var find_var(var, &seen_objects); | |
1030 if (expr != NULL) | 1042 if (expr != NULL) |
1031 Expression::traverse(&expr, &find_var); | 1043 Expression::traverse(&expr, &find_vars); |
1032 if (preinit != NULL) | 1044 if (preinit != NULL) |
1033 preinit->traverse(&find_var); | 1045 preinit->traverse(&find_vars); |
1034 if (dep != NULL) | 1046 if (dep != NULL) |
1035 { | 1047 { |
1036 Expression* init = dep->var_value()->init(); | 1048 Expression* init = dep->var_value()->init(); |
1037 if (init != NULL) | 1049 if (init != NULL) |
1038 Expression::traverse(&init, &find_var); | 1050 Expression::traverse(&init, &find_vars); |
1039 if (dep->var_value()->has_pre_init()) | 1051 if (dep->var_value()->has_pre_init()) |
1040 dep->var_value()->preinit()->traverse(&find_var); | 1052 dep->var_value()->preinit()->traverse(&find_vars); |
1041 } | 1053 } |
1042 | 1054 |
1043 return find_var.found(); | 1055 for (Find_vars::const_iterator p = find_vars.begin(); |
1056 p != find_vars.end(); | |
1057 ++p) | |
1058 { | |
1059 if (*p == var) | |
1060 return true; | |
1061 } | |
1062 return false; | |
1044 } | 1063 } |
1045 | 1064 |
1046 // Sort variable initializations. If the initialization expression | 1065 // Sort variable initializations. If the initialization expression |
1047 // for variable A refers directly or indirectly to the initialization | 1066 // for variable A refers directly or indirectly to the initialization |
1048 // expression for variable B, then we must initialize B before A. | 1067 // expression for variable B, then we must initialize B before A. |
1049 | 1068 |
1050 class Var_init | 1069 class Var_init |
1051 { | 1070 { |
1052 public: | 1071 public: |
1053 Var_init() | 1072 Var_init() |
1054 : var_(NULL), init_(NULL), dep_count_(0) | 1073 : var_(NULL), init_(NULL), refs_(NULL), dep_count_(0) |
1055 { } | 1074 { } |
1056 | 1075 |
1057 Var_init(Named_object* var, Bstatement* init) | 1076 Var_init(Named_object* var, Bstatement* init) |
1058 : var_(var), init_(init), dep_count_(0) | 1077 : var_(var), init_(init), refs_(NULL), dep_count_(0) |
1059 { } | 1078 { } |
1060 | 1079 |
1061 // Return the variable. | 1080 // Return the variable. |
1062 Named_object* | 1081 Named_object* |
1063 var() const | 1082 var() const |
1066 // Return the initialization expression. | 1085 // Return the initialization expression. |
1067 Bstatement* | 1086 Bstatement* |
1068 init() const | 1087 init() const |
1069 { return this->init_; } | 1088 { return this->init_; } |
1070 | 1089 |
1090 // Add a reference. | |
1091 void | |
1092 add_ref(Named_object* var); | |
1093 | |
1094 // The variables which this variable's initializers refer to. | |
1095 const std::vector<Named_object*>* | |
1096 refs() | |
1097 { return this->refs_; } | |
1098 | |
1099 // Clear the references, if any. | |
1100 void | |
1101 clear_refs(); | |
1102 | |
1071 // Return the number of remaining dependencies. | 1103 // Return the number of remaining dependencies. |
1072 size_t | 1104 size_t |
1073 dep_count() const | 1105 dep_count() const |
1074 { return this->dep_count_; } | 1106 { return this->dep_count_; } |
1075 | 1107 |
1084 { --this->dep_count_; } | 1116 { --this->dep_count_; } |
1085 | 1117 |
1086 private: | 1118 private: |
1087 // The variable being initialized. | 1119 // The variable being initialized. |
1088 Named_object* var_; | 1120 Named_object* var_; |
1089 // The initialization statement. | 1121 // The backend initialization statement. |
1090 Bstatement* init_; | 1122 Bstatement* init_; |
1123 // Variables this refers to. | |
1124 std::vector<Named_object*>* refs_; | |
1091 // The number of initializations this is dependent on. A variable | 1125 // The number of initializations this is dependent on. A variable |
1092 // initialization should not be emitted if any of its dependencies | 1126 // initialization should not be emitted if any of its dependencies |
1093 // have not yet been resolved. | 1127 // have not yet been resolved. |
1094 size_t dep_count_; | 1128 size_t dep_count_; |
1095 }; | 1129 }; |
1096 | 1130 |
1131 // Add a reference. | |
1132 | |
1133 void | |
1134 Var_init::add_ref(Named_object* var) | |
1135 { | |
1136 if (this->refs_ == NULL) | |
1137 this->refs_ = new std::vector<Named_object*>; | |
1138 this->refs_->push_back(var); | |
1139 } | |
1140 | |
1141 // Clear the references, if any. | |
1142 | |
1143 void | |
1144 Var_init::clear_refs() | |
1145 { | |
1146 if (this->refs_ != NULL) | |
1147 { | |
1148 delete this->refs_; | |
1149 this->refs_ = NULL; | |
1150 } | |
1151 } | |
1152 | |
1097 // For comparing Var_init keys in a map. | 1153 // For comparing Var_init keys in a map. |
1098 | 1154 |
1099 inline bool | 1155 inline bool |
1100 operator<(const Var_init& v1, const Var_init& v2) | 1156 operator<(const Var_init& v1, const Var_init& v2) |
1101 { return v1.var()->name() < v2.var()->name(); } | 1157 { return v1.var()->name() < v2.var()->name(); } |
1111 sort_var_inits(Gogo* gogo, Var_inits* var_inits) | 1167 sort_var_inits(Gogo* gogo, Var_inits* var_inits) |
1112 { | 1168 { |
1113 if (var_inits->empty()) | 1169 if (var_inits->empty()) |
1114 return; | 1170 return; |
1115 | 1171 |
1116 typedef std::pair<Named_object*, Named_object*> No_no; | 1172 std::map<Named_object*, Var_init*> var_to_init; |
1117 typedef std::map<No_no, bool> Cache; | |
1118 Cache cache; | |
1119 | 1173 |
1120 // A mapping from a variable initialization to a set of | 1174 // A mapping from a variable initialization to a set of |
1121 // variable initializations that depend on it. | 1175 // variable initializations that depend on it. |
1122 typedef std::map<Var_init, std::set<Var_init*> > Init_deps; | 1176 typedef std::map<Var_init, std::set<Var_init*> > Init_deps; |
1123 Init_deps init_deps; | 1177 Init_deps init_deps; |
1124 bool init_loop = false; | 1178 bool init_loop = false; |
1125 for (Var_inits::iterator p1 = var_inits->begin(); | 1179 |
1126 p1 != var_inits->end(); | 1180 // Compute all variable references. |
1127 ++p1) | 1181 for (Var_inits::iterator pvar = var_inits->begin(); |
1128 { | 1182 pvar != var_inits->end(); |
1129 Named_object* var = p1->var(); | 1183 ++pvar) |
1184 { | |
1185 Named_object* var = pvar->var(); | |
1186 var_to_init[var] = &*pvar; | |
1187 | |
1188 Find_vars find_vars; | |
1130 Expression* init = var->var_value()->init(); | 1189 Expression* init = var->var_value()->init(); |
1131 Block* preinit = var->var_value()->preinit(); | 1190 if (init != NULL) |
1191 Expression::traverse(&init, &find_vars); | |
1192 if (var->var_value()->has_pre_init()) | |
1193 var->var_value()->preinit()->traverse(&find_vars); | |
1132 Named_object* dep = gogo->var_depends_on(var->var_value()); | 1194 Named_object* dep = gogo->var_depends_on(var->var_value()); |
1133 | 1195 if (dep != NULL) |
1134 // Start walking through the list to see which variables VAR | 1196 { |
1135 // needs to wait for. | 1197 Expression* dinit = dep->var_value()->init(); |
1136 for (Var_inits::iterator p2 = var_inits->begin(); | 1198 if (dinit != NULL) |
1137 p2 != var_inits->end(); | 1199 Expression::traverse(&dinit, &find_vars); |
1138 ++p2) | 1200 if (dep->var_value()->has_pre_init()) |
1139 { | 1201 dep->var_value()->preinit()->traverse(&find_vars); |
1140 if (var == p2->var()) | 1202 } |
1203 for (Find_vars::const_iterator p = find_vars.begin(); | |
1204 p != find_vars.end(); | |
1205 ++p) | |
1206 pvar->add_ref(*p); | |
1207 } | |
1208 | |
1209 // Add dependencies to init_deps, and check for cycles. | |
1210 for (Var_inits::iterator pvar = var_inits->begin(); | |
1211 pvar != var_inits->end(); | |
1212 ++pvar) | |
1213 { | |
1214 Named_object* var = pvar->var(); | |
1215 | |
1216 const std::vector<Named_object*>* refs = pvar->refs(); | |
1217 if (refs == NULL) | |
1218 continue; | |
1219 for (std::vector<Named_object*>::const_iterator pdep = refs->begin(); | |
1220 pdep != refs->end(); | |
1221 ++pdep) | |
1222 { | |
1223 Named_object* dep = *pdep; | |
1224 if (var == dep) | |
1225 { | |
1226 // This is a reference from a variable to itself, which | |
1227 // may indicate a loop. We only report an error if | |
1228 // there is an initializer and there is no dependency. | |
1229 // When there is no initializer, it means that the | |
1230 // preinitializer sets the variable, which will appear | |
1231 // to be a loop here. | |
1232 if (var->var_value()->init() != NULL | |
1233 && gogo->var_depends_on(var->var_value()) == NULL) | |
1234 go_error_at(var->location(), | |
1235 ("initialization expression for %qs " | |
1236 "depends upon itself"), | |
1237 var->message_name().c_str()); | |
1238 | |
1239 continue; | |
1240 } | |
1241 | |
1242 Var_init* dep_init = var_to_init[dep]; | |
1243 if (dep_init == NULL) | |
1244 { | |
1245 // This is a dependency on some variable that doesn't | |
1246 // have an initializer, so for purposes of | |
1247 // initialization ordering this is irrelevant. | |
1248 continue; | |
1249 } | |
1250 | |
1251 init_deps[*dep_init].insert(&(*pvar)); | |
1252 pvar->add_dependency(); | |
1253 | |
1254 // Check for cycles. | |
1255 const std::vector<Named_object*>* deprefs = dep_init->refs(); | |
1256 if (deprefs == NULL) | |
1141 continue; | 1257 continue; |
1142 | 1258 for (std::vector<Named_object*>::const_iterator pdepdep = |
1143 Named_object* p2var = p2->var(); | 1259 deprefs->begin(); |
1144 No_no key(var, p2var); | 1260 pdepdep != deprefs->end(); |
1145 std::pair<Cache::iterator, bool> ins = | 1261 ++pdepdep) |
1146 cache.insert(std::make_pair(key, false)); | |
1147 if (ins.second) | |
1148 ins.first->second = expression_requires(init, preinit, dep, p2var); | |
1149 if (ins.first->second) | |
1150 { | 1262 { |
1151 // VAR depends on P2VAR. | 1263 if (*pdepdep == var) |
1152 init_deps[*p2].insert(&(*p1)); | |
1153 p1->add_dependency(); | |
1154 | |
1155 // Check for cycles. | |
1156 key = std::make_pair(p2var, var); | |
1157 ins = cache.insert(std::make_pair(key, false)); | |
1158 if (ins.second) | |
1159 ins.first->second = | |
1160 expression_requires(p2var->var_value()->init(), | |
1161 p2var->var_value()->preinit(), | |
1162 gogo->var_depends_on(p2var->var_value()), | |
1163 var); | |
1164 if (ins.first->second) | |
1165 { | 1264 { |
1166 go_error_at(var->location(), | 1265 go_error_at(var->location(), |
1167 ("initialization expressions for %qs and " | 1266 ("initialization expressions for %qs and " |
1168 "%qs depend upon each other"), | 1267 "%qs depend upon each other"), |
1169 var->message_name().c_str(), | 1268 var->message_name().c_str(), |
1170 p2var->message_name().c_str()); | 1269 dep->message_name().c_str()); |
1171 go_inform(p2->var()->location(), "%qs defined here", | 1270 go_inform(dep->location(), "%qs defined here", |
1172 p2var->message_name().c_str()); | 1271 dep->message_name().c_str()); |
1173 init_loop = true; | 1272 init_loop = true; |
1174 break; | 1273 break; |
1175 } | 1274 } |
1176 } | 1275 } |
1177 } | 1276 } |
1178 } | 1277 } |
1278 | |
1279 var_to_init.clear(); | |
1280 for (Var_inits::iterator pvar = var_inits->begin(); | |
1281 pvar != var_inits->end(); | |
1282 ++pvar) | |
1283 pvar->clear_refs(); | |
1179 | 1284 |
1180 // If there are no dependencies then the declaration order is sorted. | 1285 // If there are no dependencies then the declaration order is sorted. |
1181 if (!init_deps.empty() && !init_loop) | 1286 if (!init_deps.empty() && !init_loop) |
1182 { | 1287 { |
1183 // Otherwise, sort variable initializations by emitting all variables with | 1288 // Otherwise, sort variable initializations by emitting all variables with |
1211 } | 1316 } |
1212 } | 1317 } |
1213 var_inits->swap(ready); | 1318 var_inits->swap(ready); |
1214 go_assert(init_deps.empty()); | 1319 go_assert(init_deps.empty()); |
1215 } | 1320 } |
1216 | |
1217 // VAR_INITS is in the correct order. For each VAR in VAR_INITS, | |
1218 // check for a loop of VAR on itself. | |
1219 // interpret as a loop. | |
1220 for (Var_inits::const_iterator p = var_inits->begin(); | |
1221 p != var_inits->end(); | |
1222 ++p) | |
1223 gogo->check_self_dep(p->var()); | |
1224 } | 1321 } |
1225 | 1322 |
1226 // Give an error if the initialization expression for VAR depends on | 1323 // Give an error if the initialization expression for VAR depends on |
1227 // itself. We only check if INIT is not NULL and there is no | 1324 // itself. We only check if INIT is not NULL and there is no |
1228 // dependency; when INIT is NULL, it means that PREINIT sets VAR, | 1325 // dependency; when INIT is NULL, it means that PREINIT sets VAR, |
1392 this->backend()->expression_statement(init_bfn, var_binit); | 1489 this->backend()->expression_statement(init_bfn, var_binit); |
1393 else | 1490 else |
1394 { | 1491 { |
1395 Location loc = var->location(); | 1492 Location loc = var->location(); |
1396 Bexpression* var_expr = | 1493 Bexpression* var_expr = |
1397 this->backend()->var_expression(bvar, VE_lvalue, loc); | 1494 this->backend()->var_expression(bvar, loc); |
1398 var_init_stmt = | 1495 var_init_stmt = |
1399 this->backend()->assignment_statement(init_bfn, var_expr, | 1496 this->backend()->assignment_statement(init_bfn, var_expr, |
1400 var_binit, loc); | 1497 var_binit, loc); |
1401 } | 1498 } |
1402 } | 1499 } |
1436 if (!is_sink && var->type()->has_pointer()) | 1533 if (!is_sink && var->type()->has_pointer()) |
1437 { | 1534 { |
1438 // Avoid putting runtime.gcRoots itself on the list. | 1535 // Avoid putting runtime.gcRoots itself on the list. |
1439 if (this->compiling_runtime() | 1536 if (this->compiling_runtime() |
1440 && this->package_name() == "runtime" | 1537 && this->package_name() == "runtime" |
1441 && Gogo::unpack_hidden_name(no->name()) == "gcRoots") | 1538 && (Gogo::unpack_hidden_name(no->name()) == "gcRoots" |
1539 || Gogo::unpack_hidden_name(no->name()) == "gcRootsIndex")) | |
1442 ; | 1540 ; |
1443 else | 1541 else |
1444 var_gc.push_back(no); | 1542 var_gc.push_back(no); |
1445 } | 1543 } |
1446 } | 1544 } |
1755 else if (!name.empty()) | 1853 else if (!name.empty()) |
1756 pname = &name; | 1854 pname = &name; |
1757 else | 1855 else |
1758 { | 1856 { |
1759 // Invent a name for a nested function. | 1857 // Invent a name for a nested function. |
1760 nested_name = this->nested_function_name(); | 1858 nested_name = this->nested_function_name(enclosing); |
1761 pname = &nested_name; | 1859 pname = &nested_name; |
1762 } | 1860 } |
1763 | 1861 |
1764 Named_object* ret; | 1862 Named_object* ret; |
1765 if (Gogo::is_sink_name(*pname)) | 1863 if (Gogo::is_sink_name(*pname)) |
2748 break; | 2846 break; |
2749 if (enew->traverse_subexpressions(this) == TRAVERSE_EXIT) | 2847 if (enew->traverse_subexpressions(this) == TRAVERSE_EXIT) |
2750 return TRAVERSE_EXIT; | 2848 return TRAVERSE_EXIT; |
2751 *pexpr = enew; | 2849 *pexpr = enew; |
2752 } | 2850 } |
2851 | |
2852 // Lower the type of this expression before the parent looks at it, | |
2853 // in case the type contains an array that has expressions in its | |
2854 // length. Skip an Unknown_expression, as at this point that means | |
2855 // a composite literal key that does not have a type. | |
2856 if ((*pexpr)->unknown_expression() == NULL) | |
2857 Type::traverse((*pexpr)->type(), this); | |
2858 | |
2753 return TRAVERSE_SKIP_COMPONENTS; | 2859 return TRAVERSE_SKIP_COMPONENTS; |
2754 } | 2860 } |
2755 | 2861 |
2756 // Lower the parse tree. This is called after the parse is complete, | 2862 // Lower the parse tree. This is called after the parse is complete, |
2757 // when all names should be resolved. | 2863 // when all names should be resolved. |
3325 { | 3431 { |
3326 Check_types_traverse traverse(this); | 3432 Check_types_traverse traverse(this); |
3327 block->traverse(&traverse); | 3433 block->traverse(&traverse); |
3328 } | 3434 } |
3329 | 3435 |
3330 // A traversal class used to find a single shortcut operator within an | |
3331 // expression. | |
3332 | |
3333 class Find_shortcut : public Traverse | |
3334 { | |
3335 public: | |
3336 Find_shortcut() | |
3337 : Traverse(traverse_blocks | |
3338 | traverse_statements | |
3339 | traverse_expressions), | |
3340 found_(NULL) | |
3341 { } | |
3342 | |
3343 // A pointer to the expression which was found, or NULL if none was | |
3344 // found. | |
3345 Expression** | |
3346 found() const | |
3347 { return this->found_; } | |
3348 | |
3349 protected: | |
3350 int | |
3351 block(Block*) | |
3352 { return TRAVERSE_SKIP_COMPONENTS; } | |
3353 | |
3354 int | |
3355 statement(Block*, size_t*, Statement*) | |
3356 { return TRAVERSE_SKIP_COMPONENTS; } | |
3357 | |
3358 int | |
3359 expression(Expression**); | |
3360 | |
3361 private: | |
3362 Expression** found_; | |
3363 }; | |
3364 | |
3365 // Find a shortcut expression. | |
3366 | |
3367 int | |
3368 Find_shortcut::expression(Expression** pexpr) | |
3369 { | |
3370 Expression* expr = *pexpr; | |
3371 Binary_expression* be = expr->binary_expression(); | |
3372 if (be == NULL) | |
3373 return TRAVERSE_CONTINUE; | |
3374 Operator op = be->op(); | |
3375 if (op != OPERATOR_OROR && op != OPERATOR_ANDAND) | |
3376 return TRAVERSE_CONTINUE; | |
3377 go_assert(this->found_ == NULL); | |
3378 this->found_ = pexpr; | |
3379 return TRAVERSE_EXIT; | |
3380 } | |
3381 | |
3382 // A traversal class used to turn shortcut operators into explicit if | |
3383 // statements. | |
3384 | |
3385 class Shortcuts : public Traverse | |
3386 { | |
3387 public: | |
3388 Shortcuts(Gogo* gogo) | |
3389 : Traverse(traverse_variables | |
3390 | traverse_statements), | |
3391 gogo_(gogo) | |
3392 { } | |
3393 | |
3394 protected: | |
3395 int | |
3396 variable(Named_object*); | |
3397 | |
3398 int | |
3399 statement(Block*, size_t*, Statement*); | |
3400 | |
3401 private: | |
3402 // Convert a shortcut operator. | |
3403 Statement* | |
3404 convert_shortcut(Block* enclosing, Expression** pshortcut); | |
3405 | |
3406 // The IR. | |
3407 Gogo* gogo_; | |
3408 }; | |
3409 | |
3410 // Remove shortcut operators in a single statement. | |
3411 | |
3412 int | |
3413 Shortcuts::statement(Block* block, size_t* pindex, Statement* s) | |
3414 { | |
3415 // FIXME: This approach doesn't work for switch statements, because | |
3416 // we add the new statements before the whole switch when we need to | |
3417 // instead add them just before the switch expression. The right | |
3418 // fix is probably to lower switch statements with nonconstant cases | |
3419 // to a series of conditionals. | |
3420 if (s->switch_statement() != NULL) | |
3421 return TRAVERSE_CONTINUE; | |
3422 | |
3423 while (true) | |
3424 { | |
3425 Find_shortcut find_shortcut; | |
3426 | |
3427 // If S is a variable declaration, then ordinary traversal won't | |
3428 // do anything. We want to explicitly traverse the | |
3429 // initialization expression if there is one. | |
3430 Variable_declaration_statement* vds = s->variable_declaration_statement(); | |
3431 Expression* init = NULL; | |
3432 if (vds == NULL) | |
3433 s->traverse_contents(&find_shortcut); | |
3434 else | |
3435 { | |
3436 init = vds->var()->var_value()->init(); | |
3437 if (init == NULL) | |
3438 return TRAVERSE_CONTINUE; | |
3439 init->traverse(&init, &find_shortcut); | |
3440 } | |
3441 Expression** pshortcut = find_shortcut.found(); | |
3442 if (pshortcut == NULL) | |
3443 return TRAVERSE_CONTINUE; | |
3444 | |
3445 Statement* snew = this->convert_shortcut(block, pshortcut); | |
3446 block->insert_statement_before(*pindex, snew); | |
3447 ++*pindex; | |
3448 | |
3449 if (pshortcut == &init) | |
3450 vds->var()->var_value()->set_init(init); | |
3451 } | |
3452 } | |
3453 | |
3454 // Remove shortcut operators in the initializer of a global variable. | |
3455 | |
3456 int | |
3457 Shortcuts::variable(Named_object* no) | |
3458 { | |
3459 if (no->is_result_variable()) | |
3460 return TRAVERSE_CONTINUE; | |
3461 Variable* var = no->var_value(); | |
3462 Expression* init = var->init(); | |
3463 if (!var->is_global() || init == NULL) | |
3464 return TRAVERSE_CONTINUE; | |
3465 | |
3466 while (true) | |
3467 { | |
3468 Find_shortcut find_shortcut; | |
3469 init->traverse(&init, &find_shortcut); | |
3470 Expression** pshortcut = find_shortcut.found(); | |
3471 if (pshortcut == NULL) | |
3472 return TRAVERSE_CONTINUE; | |
3473 | |
3474 Statement* snew = this->convert_shortcut(NULL, pshortcut); | |
3475 var->add_preinit_statement(this->gogo_, snew); | |
3476 if (pshortcut == &init) | |
3477 var->set_init(init); | |
3478 } | |
3479 } | |
3480 | |
3481 // Given an expression which uses a shortcut operator, return a | |
3482 // statement which implements it, and update *PSHORTCUT accordingly. | |
3483 | |
3484 Statement* | |
3485 Shortcuts::convert_shortcut(Block* enclosing, Expression** pshortcut) | |
3486 { | |
3487 Binary_expression* shortcut = (*pshortcut)->binary_expression(); | |
3488 Expression* left = shortcut->left(); | |
3489 Expression* right = shortcut->right(); | |
3490 Location loc = shortcut->location(); | |
3491 | |
3492 Block* retblock = new Block(enclosing, loc); | |
3493 retblock->set_end_location(loc); | |
3494 | |
3495 Temporary_statement* ts = Statement::make_temporary(shortcut->type(), | |
3496 left, loc); | |
3497 retblock->add_statement(ts); | |
3498 | |
3499 Block* block = new Block(retblock, loc); | |
3500 block->set_end_location(loc); | |
3501 Expression* tmpref = Expression::make_temporary_reference(ts, loc); | |
3502 Statement* assign = Statement::make_assignment(tmpref, right, loc); | |
3503 block->add_statement(assign); | |
3504 | |
3505 Expression* cond = Expression::make_temporary_reference(ts, loc); | |
3506 if (shortcut->binary_expression()->op() == OPERATOR_OROR) | |
3507 cond = Expression::make_unary(OPERATOR_NOT, cond, loc); | |
3508 | |
3509 Statement* if_statement = Statement::make_if_statement(cond, block, NULL, | |
3510 loc); | |
3511 retblock->add_statement(if_statement); | |
3512 | |
3513 *pshortcut = Expression::make_temporary_reference(ts, loc); | |
3514 | |
3515 delete shortcut; | |
3516 | |
3517 // Now convert any shortcut operators in LEFT and RIGHT. | |
3518 Shortcuts shortcuts(this->gogo_); | |
3519 retblock->traverse(&shortcuts); | |
3520 | |
3521 return Statement::make_block_statement(retblock, loc); | |
3522 } | |
3523 | |
3524 // Turn shortcut operators into explicit if statements. Doing this | |
3525 // considerably simplifies the order of evaluation rules. | |
3526 | |
3527 void | |
3528 Gogo::remove_shortcuts() | |
3529 { | |
3530 Shortcuts shortcuts(this); | |
3531 this->traverse(&shortcuts); | |
3532 } | |
3533 | |
3534 // A traversal class which finds all the expressions which must be | 3436 // A traversal class which finds all the expressions which must be |
3535 // evaluated in order within a statement or larger expression. This | 3437 // evaluated in order within a statement or larger expression. This |
3536 // is used to implement the rules about order of evaluation. | 3438 // is used to implement the rules about order of evaluation. |
3537 | 3439 |
3538 class Find_eval_ordering : public Traverse | 3440 class Find_eval_ordering : public Traverse |
3582 // If an expression must be evaluated in order, put it on the list. | 3484 // If an expression must be evaluated in order, put it on the list. |
3583 | 3485 |
3584 int | 3486 int |
3585 Find_eval_ordering::expression(Expression** expression_pointer) | 3487 Find_eval_ordering::expression(Expression** expression_pointer) |
3586 { | 3488 { |
3489 Binary_expression* binexp = (*expression_pointer)->binary_expression(); | |
3490 if (binexp != NULL | |
3491 && (binexp->op() == OPERATOR_ANDAND || binexp->op() == OPERATOR_OROR)) | |
3492 { | |
3493 // Shortcut expressions may potentially have side effects which need | |
3494 // to be ordered, so add them to the list. | |
3495 // We don't order its subexpressions here since they may be evaluated | |
3496 // conditionally. This is handled in remove_shortcuts. | |
3497 this->exprs_.push_back(expression_pointer); | |
3498 return TRAVERSE_SKIP_COMPONENTS; | |
3499 } | |
3500 | |
3587 // We have to look at subexpressions before this one. | 3501 // We have to look at subexpressions before this one. |
3588 if ((*expression_pointer)->traverse_subexpressions(this) == TRAVERSE_EXIT) | 3502 if ((*expression_pointer)->traverse_subexpressions(this) == TRAVERSE_EXIT) |
3589 return TRAVERSE_EXIT; | 3503 return TRAVERSE_EXIT; |
3590 if ((*expression_pointer)->must_eval_in_order()) | 3504 if ((*expression_pointer)->must_eval_in_order()) |
3591 this->exprs_.push_back(expression_pointer); | 3505 this->exprs_.push_back(expression_pointer); |
3818 { | 3732 { |
3819 Order_eval order_eval(this); | 3733 Order_eval order_eval(this); |
3820 this->traverse(&order_eval); | 3734 this->traverse(&order_eval); |
3821 } | 3735 } |
3822 | 3736 |
3737 // A traversal class used to find a single shortcut operator within an | |
3738 // expression. | |
3739 | |
3740 class Find_shortcut : public Traverse | |
3741 { | |
3742 public: | |
3743 Find_shortcut() | |
3744 : Traverse(traverse_blocks | |
3745 | traverse_statements | |
3746 | traverse_expressions), | |
3747 found_(NULL) | |
3748 { } | |
3749 | |
3750 // A pointer to the expression which was found, or NULL if none was | |
3751 // found. | |
3752 Expression** | |
3753 found() const | |
3754 { return this->found_; } | |
3755 | |
3756 protected: | |
3757 int | |
3758 block(Block*) | |
3759 { return TRAVERSE_SKIP_COMPONENTS; } | |
3760 | |
3761 int | |
3762 statement(Block*, size_t*, Statement*) | |
3763 { return TRAVERSE_SKIP_COMPONENTS; } | |
3764 | |
3765 int | |
3766 expression(Expression**); | |
3767 | |
3768 private: | |
3769 Expression** found_; | |
3770 }; | |
3771 | |
3772 // Find a shortcut expression. | |
3773 | |
3774 int | |
3775 Find_shortcut::expression(Expression** pexpr) | |
3776 { | |
3777 Expression* expr = *pexpr; | |
3778 Binary_expression* be = expr->binary_expression(); | |
3779 if (be == NULL) | |
3780 return TRAVERSE_CONTINUE; | |
3781 Operator op = be->op(); | |
3782 if (op != OPERATOR_OROR && op != OPERATOR_ANDAND) | |
3783 return TRAVERSE_CONTINUE; | |
3784 go_assert(this->found_ == NULL); | |
3785 this->found_ = pexpr; | |
3786 return TRAVERSE_EXIT; | |
3787 } | |
3788 | |
3789 // A traversal class used to turn shortcut operators into explicit if | |
3790 // statements. | |
3791 | |
3792 class Shortcuts : public Traverse | |
3793 { | |
3794 public: | |
3795 Shortcuts(Gogo* gogo) | |
3796 : Traverse(traverse_variables | |
3797 | traverse_statements), | |
3798 gogo_(gogo) | |
3799 { } | |
3800 | |
3801 protected: | |
3802 int | |
3803 variable(Named_object*); | |
3804 | |
3805 int | |
3806 statement(Block*, size_t*, Statement*); | |
3807 | |
3808 private: | |
3809 // Convert a shortcut operator. | |
3810 Statement* | |
3811 convert_shortcut(Block* enclosing, Expression** pshortcut); | |
3812 | |
3813 // The IR. | |
3814 Gogo* gogo_; | |
3815 }; | |
3816 | |
3817 // Remove shortcut operators in a single statement. | |
3818 | |
3819 int | |
3820 Shortcuts::statement(Block* block, size_t* pindex, Statement* s) | |
3821 { | |
3822 // FIXME: This approach doesn't work for switch statements, because | |
3823 // we add the new statements before the whole switch when we need to | |
3824 // instead add them just before the switch expression. The right | |
3825 // fix is probably to lower switch statements with nonconstant cases | |
3826 // to a series of conditionals. | |
3827 if (s->switch_statement() != NULL) | |
3828 return TRAVERSE_CONTINUE; | |
3829 | |
3830 while (true) | |
3831 { | |
3832 Find_shortcut find_shortcut; | |
3833 | |
3834 // If S is a variable declaration, then ordinary traversal won't | |
3835 // do anything. We want to explicitly traverse the | |
3836 // initialization expression if there is one. | |
3837 Variable_declaration_statement* vds = s->variable_declaration_statement(); | |
3838 Expression* init = NULL; | |
3839 if (vds == NULL) | |
3840 s->traverse_contents(&find_shortcut); | |
3841 else | |
3842 { | |
3843 init = vds->var()->var_value()->init(); | |
3844 if (init == NULL) | |
3845 return TRAVERSE_CONTINUE; | |
3846 init->traverse(&init, &find_shortcut); | |
3847 } | |
3848 Expression** pshortcut = find_shortcut.found(); | |
3849 if (pshortcut == NULL) | |
3850 return TRAVERSE_CONTINUE; | |
3851 | |
3852 Statement* snew = this->convert_shortcut(block, pshortcut); | |
3853 block->insert_statement_before(*pindex, snew); | |
3854 ++*pindex; | |
3855 | |
3856 if (pshortcut == &init) | |
3857 vds->var()->var_value()->set_init(init); | |
3858 } | |
3859 } | |
3860 | |
3861 // Remove shortcut operators in the initializer of a global variable. | |
3862 | |
3863 int | |
3864 Shortcuts::variable(Named_object* no) | |
3865 { | |
3866 if (no->is_result_variable()) | |
3867 return TRAVERSE_CONTINUE; | |
3868 Variable* var = no->var_value(); | |
3869 Expression* init = var->init(); | |
3870 if (!var->is_global() || init == NULL) | |
3871 return TRAVERSE_CONTINUE; | |
3872 | |
3873 while (true) | |
3874 { | |
3875 Find_shortcut find_shortcut; | |
3876 init->traverse(&init, &find_shortcut); | |
3877 Expression** pshortcut = find_shortcut.found(); | |
3878 if (pshortcut == NULL) | |
3879 return TRAVERSE_CONTINUE; | |
3880 | |
3881 Statement* snew = this->convert_shortcut(NULL, pshortcut); | |
3882 var->add_preinit_statement(this->gogo_, snew); | |
3883 if (pshortcut == &init) | |
3884 var->set_init(init); | |
3885 } | |
3886 } | |
3887 | |
3888 // Given an expression which uses a shortcut operator, return a | |
3889 // statement which implements it, and update *PSHORTCUT accordingly. | |
3890 | |
3891 Statement* | |
3892 Shortcuts::convert_shortcut(Block* enclosing, Expression** pshortcut) | |
3893 { | |
3894 Binary_expression* shortcut = (*pshortcut)->binary_expression(); | |
3895 Expression* left = shortcut->left(); | |
3896 Expression* right = shortcut->right(); | |
3897 Location loc = shortcut->location(); | |
3898 | |
3899 Block* retblock = new Block(enclosing, loc); | |
3900 retblock->set_end_location(loc); | |
3901 | |
3902 Temporary_statement* ts = Statement::make_temporary(shortcut->type(), | |
3903 left, loc); | |
3904 retblock->add_statement(ts); | |
3905 | |
3906 Block* block = new Block(retblock, loc); | |
3907 block->set_end_location(loc); | |
3908 Expression* tmpref = Expression::make_temporary_reference(ts, loc); | |
3909 Statement* assign = Statement::make_assignment(tmpref, right, loc); | |
3910 block->add_statement(assign); | |
3911 | |
3912 Expression* cond = Expression::make_temporary_reference(ts, loc); | |
3913 if (shortcut->binary_expression()->op() == OPERATOR_OROR) | |
3914 cond = Expression::make_unary(OPERATOR_NOT, cond, loc); | |
3915 | |
3916 Statement* if_statement = Statement::make_if_statement(cond, block, NULL, | |
3917 loc); | |
3918 retblock->add_statement(if_statement); | |
3919 | |
3920 *pshortcut = Expression::make_temporary_reference(ts, loc); | |
3921 | |
3922 delete shortcut; | |
3923 | |
3924 // Now convert any shortcut operators in LEFT and RIGHT. | |
3925 // LEFT and RIGHT were skipped in the top level | |
3926 // Gogo::order_evaluations. We need to order their | |
3927 // components first. | |
3928 Order_eval order_eval(this->gogo_); | |
3929 retblock->traverse(&order_eval); | |
3930 Shortcuts shortcuts(this->gogo_); | |
3931 retblock->traverse(&shortcuts); | |
3932 | |
3933 return Statement::make_block_statement(retblock, loc); | |
3934 } | |
3935 | |
3936 // Turn shortcut operators into explicit if statements. Doing this | |
3937 // considerably simplifies the order of evaluation rules. | |
3938 | |
3939 void | |
3940 Gogo::remove_shortcuts() | |
3941 { | |
3942 Shortcuts shortcuts(this); | |
3943 this->traverse(&shortcuts); | |
3944 } | |
3945 | |
3823 // Traversal to flatten parse tree after order of evaluation rules are applied. | 3946 // Traversal to flatten parse tree after order of evaluation rules are applied. |
3824 | 3947 |
3825 class Flatten : public Traverse | 3948 class Flatten : public Traverse |
3826 { | 3949 { |
3827 public: | 3950 public: |
3871 // Global variables can have loops in their initialization | 3994 // Global variables can have loops in their initialization |
3872 // expressions. This is handled in flatten_init_expression. | 3995 // expressions. This is handled in flatten_init_expression. |
3873 no->var_value()->flatten_init_expression(this->gogo_, this->function_, | 3996 no->var_value()->flatten_init_expression(this->gogo_, this->function_, |
3874 &this->inserter_); | 3997 &this->inserter_); |
3875 return TRAVERSE_CONTINUE; | 3998 return TRAVERSE_CONTINUE; |
3999 } | |
4000 | |
4001 if (!no->var_value()->is_parameter() | |
4002 && !no->var_value()->is_receiver() | |
4003 && !no->var_value()->is_closure() | |
4004 && no->var_value()->is_non_escaping_address_taken() | |
4005 && !no->var_value()->is_in_heap() | |
4006 && no->var_value()->toplevel_decl() == NULL) | |
4007 { | |
4008 // Local variable that has address taken but not escape. | |
4009 // It needs to be live beyond its lexical scope. So we | |
4010 // create a top-level declaration for it. | |
4011 // No need to do it if it is already in the top level. | |
4012 Block* top_block = function_->func_value()->block(); | |
4013 if (top_block->bindings()->lookup_local(no->name()) != no) | |
4014 { | |
4015 Variable* var = no->var_value(); | |
4016 Temporary_statement* ts = | |
4017 Statement::make_temporary(var->type(), NULL, var->location()); | |
4018 ts->set_is_address_taken(); | |
4019 top_block->add_statement_at_front(ts); | |
4020 var->set_toplevel_decl(ts); | |
4021 } | |
3876 } | 4022 } |
3877 | 4023 |
3878 go_assert(!no->var_value()->has_pre_init()); | 4024 go_assert(!no->var_value()->has_pre_init()); |
3879 | 4025 |
3880 return TRAVERSE_SKIP_COMPONENTS; | 4026 return TRAVERSE_SKIP_COMPONENTS; |
4607 && (name != "_defer" && name != "_panic")) | 4753 && (name != "_defer" && name != "_panic")) |
4608 continue; | 4754 continue; |
4609 | 4755 |
4610 if (no->is_type() && no->type_value()->struct_type() != NULL) | 4756 if (no->is_type() && no->type_value()->struct_type() != NULL) |
4611 types.push_back(no); | 4757 types.push_back(no); |
4612 if (no->is_const() && no->const_value()->type()->integer_type() != NULL) | 4758 if (no->is_const() |
4759 && no->const_value()->type()->integer_type() != NULL | |
4760 && !no->const_value()->is_sink()) | |
4613 { | 4761 { |
4614 Numeric_constant nc; | 4762 Numeric_constant nc; |
4615 unsigned long val; | 4763 unsigned long val; |
4616 if (no->const_value()->expr()->numeric_constant_value(&nc) | 4764 if (no->const_value()->expr()->numeric_constant_value(&nc) |
4617 && nc.to_unsigned_long(&val) == Numeric_constant::NC_UL_VALID) | 4765 && nc.to_unsigned_long(&val) == Numeric_constant::NC_UL_VALID) |
4795 Function::Function(Function_type* type, Named_object* enclosing, Block* block, | 4943 Function::Function(Function_type* type, Named_object* enclosing, Block* block, |
4796 Location location) | 4944 Location location) |
4797 : type_(type), enclosing_(enclosing), results_(NULL), | 4945 : type_(type), enclosing_(enclosing), results_(NULL), |
4798 closure_var_(NULL), block_(block), location_(location), labels_(), | 4946 closure_var_(NULL), block_(block), location_(location), labels_(), |
4799 local_type_count_(0), descriptor_(NULL), fndecl_(NULL), defer_stack_(NULL), | 4947 local_type_count_(0), descriptor_(NULL), fndecl_(NULL), defer_stack_(NULL), |
4800 pragmas_(0), is_sink_(false), results_are_named_(false), | 4948 pragmas_(0), nested_functions_(0), is_sink_(false), |
4801 is_unnamed_type_stub_method_(false), calls_recover_(false), | 4949 results_are_named_(false), is_unnamed_type_stub_method_(false), |
4802 is_recover_thunk_(false), has_recover_thunk_(false), | 4950 calls_recover_(false), is_recover_thunk_(false), has_recover_thunk_(false), |
4803 calls_defer_retaddr_(false), is_type_specific_function_(false), | 4951 calls_defer_retaddr_(false), is_type_specific_function_(false), |
4804 in_unique_section_(false) | 4952 in_unique_section_(false) |
4805 { | 4953 { |
4806 } | 4954 } |
4807 | 4955 |
4922 Struct_type* st = closure->var_value()->type()->deref()->struct_type(); | 5070 Struct_type* st = closure->var_value()->type()->deref()->struct_type(); |
4923 | 5071 |
4924 // The first field of a closure is always a pointer to the function | 5072 // The first field of a closure is always a pointer to the function |
4925 // code. | 5073 // code. |
4926 Type* voidptr_type = Type::make_pointer_type(Type::make_void_type()); | 5074 Type* voidptr_type = Type::make_pointer_type(Type::make_void_type()); |
4927 st->push_field(Struct_field(Typed_identifier(".$f", voidptr_type, | 5075 st->push_field(Struct_field(Typed_identifier(".f", voidptr_type, |
4928 this->location_))); | 5076 this->location_))); |
4929 | 5077 |
4930 unsigned int index = 1; | 5078 unsigned int index = 1; |
4931 for (Closure_fields::const_iterator p = this->closure_fields_.begin(); | 5079 for (Closure_fields::const_iterator p = this->closure_fields_.begin(); |
4932 p != this->closure_fields_.end(); | 5080 p != this->closure_fields_.end(); |
5153 // Export the function. | 5301 // Export the function. |
5154 | 5302 |
5155 void | 5303 void |
5156 Function::export_func(Export* exp, const std::string& name) const | 5304 Function::export_func(Export* exp, const std::string& name) const |
5157 { | 5305 { |
5158 Function::export_func_with_type(exp, name, this->type_); | 5306 Function::export_func_with_type(exp, name, this->type_, |
5307 this->is_method() && this->nointerface()); | |
5159 } | 5308 } |
5160 | 5309 |
5161 // Export a function with a type. | 5310 // Export a function with a type. |
5162 | 5311 |
5163 void | 5312 void |
5164 Function::export_func_with_type(Export* exp, const std::string& name, | 5313 Function::export_func_with_type(Export* exp, const std::string& name, |
5165 const Function_type* fntype) | 5314 const Function_type* fntype, bool nointerface) |
5166 { | 5315 { |
5167 exp->write_c_string("func "); | 5316 exp->write_c_string("func "); |
5317 | |
5318 if (nointerface) | |
5319 { | |
5320 go_assert(fntype->is_method()); | |
5321 exp->write_c_string("/*nointerface*/ "); | |
5322 } | |
5168 | 5323 |
5169 if (fntype->is_method()) | 5324 if (fntype->is_method()) |
5170 { | 5325 { |
5171 exp->write_c_string("("); | 5326 exp->write_c_string("("); |
5172 const Typed_identifier* receiver = fntype->receiver(); | 5327 const Typed_identifier* receiver = fntype->receiver(); |
5234 exp->write_type(p->type()); | 5389 exp->write_type(p->type()); |
5235 } | 5390 } |
5236 exp->write_c_string(")"); | 5391 exp->write_c_string(")"); |
5237 } | 5392 } |
5238 } | 5393 } |
5239 exp->write_c_string(";\n"); | 5394 exp->write_c_string("\n"); |
5240 } | 5395 } |
5241 | 5396 |
5242 // Import a function. | 5397 // Import a function. |
5243 | 5398 |
5244 void | 5399 void |
5245 Function::import_func(Import* imp, std::string* pname, | 5400 Function::import_func(Import* imp, std::string* pname, |
5246 Typed_identifier** preceiver, | 5401 Typed_identifier** preceiver, |
5247 Typed_identifier_list** pparameters, | 5402 Typed_identifier_list** pparameters, |
5248 Typed_identifier_list** presults, | 5403 Typed_identifier_list** presults, |
5249 bool* is_varargs) | 5404 bool* is_varargs, |
5405 bool* nointerface) | |
5250 { | 5406 { |
5251 imp->require_c_string("func "); | 5407 imp->require_c_string("func "); |
5408 | |
5409 *nointerface = false; | |
5410 if (imp->match_c_string("/*")) | |
5411 { | |
5412 imp->require_c_string("/*nointerface*/ "); | |
5413 *nointerface = true; | |
5414 | |
5415 // Only a method can be nointerface. | |
5416 go_assert(imp->peek_char() == '('); | |
5417 } | |
5252 | 5418 |
5253 *preceiver = NULL; | 5419 *preceiver = NULL; |
5254 if (imp->peek_char() == '(') | 5420 if (imp->peek_char() == '(') |
5255 { | 5421 { |
5256 imp->require_c_string("("); | 5422 imp->require_c_string("("); |
5330 imp->require_c_string(", "); | 5496 imp->require_c_string(", "); |
5331 } | 5497 } |
5332 imp->require_c_string(")"); | 5498 imp->require_c_string(")"); |
5333 } | 5499 } |
5334 } | 5500 } |
5335 imp->require_c_string(";\n"); | 5501 imp->require_semicolon_if_old_version(); |
5502 imp->require_c_string("\n"); | |
5336 *presults = results; | 5503 *presults = results; |
5337 } | 5504 } |
5338 | 5505 |
5339 // Get the backend representation. | 5506 // Get the backend representation. |
5340 | 5507 |
5432 | 5599 |
5433 Btype* functype = this->type_->get_backend_fntype(gogo); | 5600 Btype* functype = this->type_->get_backend_fntype(gogo); |
5434 this->fndecl_ = | 5601 this->fndecl_ = |
5435 gogo->backend()->function(functype, no->get_id(gogo), asm_name, | 5602 gogo->backend()->function(functype, no->get_id(gogo), asm_name, |
5436 is_visible, false, is_inlinable, | 5603 is_visible, false, is_inlinable, |
5437 disable_split_stack, in_unique_section, | 5604 disable_split_stack, false, |
5438 this->location()); | 5605 in_unique_section, this->location()); |
5439 } | 5606 } |
5440 return this->fndecl_; | 5607 return this->fndecl_; |
5441 } | 5608 } |
5442 | 5609 |
5443 // Get the backend representation. | 5610 // Get the backend representation. |
5445 Bfunction* | 5612 Bfunction* |
5446 Function_declaration::get_or_make_decl(Gogo* gogo, Named_object* no) | 5613 Function_declaration::get_or_make_decl(Gogo* gogo, Named_object* no) |
5447 { | 5614 { |
5448 if (this->fndecl_ == NULL) | 5615 if (this->fndecl_ == NULL) |
5449 { | 5616 { |
5617 bool does_not_return = false; | |
5618 | |
5450 // Let Go code use an asm declaration to pick up a builtin | 5619 // Let Go code use an asm declaration to pick up a builtin |
5451 // function. | 5620 // function. |
5452 if (!this->asm_name_.empty()) | 5621 if (!this->asm_name_.empty()) |
5453 { | 5622 { |
5454 Bfunction* builtin_decl = | 5623 Bfunction* builtin_decl = |
5456 if (builtin_decl != NULL) | 5625 if (builtin_decl != NULL) |
5457 { | 5626 { |
5458 this->fndecl_ = builtin_decl; | 5627 this->fndecl_ = builtin_decl; |
5459 return this->fndecl_; | 5628 return this->fndecl_; |
5460 } | 5629 } |
5630 | |
5631 if (this->asm_name_ == "runtime.gopanic" | |
5632 || this->asm_name_ == "__go_runtime_error") | |
5633 does_not_return = true; | |
5461 } | 5634 } |
5462 | 5635 |
5463 std::string asm_name; | 5636 std::string asm_name; |
5464 if (this->asm_name_.empty()) | 5637 if (this->asm_name_.empty()) |
5465 { | 5638 { |
5472 asm_name = go_encode_id(no->get_id(gogo)); | 5645 asm_name = go_encode_id(no->get_id(gogo)); |
5473 | 5646 |
5474 Btype* functype = this->fntype_->get_backend_fntype(gogo); | 5647 Btype* functype = this->fntype_->get_backend_fntype(gogo); |
5475 this->fndecl_ = | 5648 this->fndecl_ = |
5476 gogo->backend()->function(functype, no->get_id(gogo), asm_name, | 5649 gogo->backend()->function(functype, no->get_id(gogo), asm_name, |
5477 true, true, true, false, false, | 5650 true, true, true, false, does_not_return, |
5478 this->location()); | 5651 false, this->location()); |
5479 } | 5652 } |
5480 | 5653 |
5481 return this->fndecl_; | 5654 return this->fndecl_; |
5482 } | 5655 } |
5483 | 5656 |
5536 | 5709 |
5537 // Variables that need to be declared for this function and their | 5710 // Variables that need to be declared for this function and their |
5538 // initial values. | 5711 // initial values. |
5539 std::vector<Bvariable*> vars; | 5712 std::vector<Bvariable*> vars; |
5540 std::vector<Bexpression*> var_inits; | 5713 std::vector<Bexpression*> var_inits; |
5714 std::vector<Statement*> var_decls_stmts; | |
5541 for (Bindings::const_definitions_iterator p = | 5715 for (Bindings::const_definitions_iterator p = |
5542 this->block_->bindings()->begin_definitions(); | 5716 this->block_->bindings()->begin_definitions(); |
5543 p != this->block_->bindings()->end_definitions(); | 5717 p != this->block_->bindings()->end_definitions(); |
5544 ++p) | 5718 ++p) |
5545 { | 5719 { |
5565 parm_bvar = parm_no->get_backend_variable(gogo, named_function); | 5739 parm_bvar = parm_no->get_backend_variable(gogo, named_function); |
5566 | 5740 |
5567 vars.push_back(bvar); | 5741 vars.push_back(bvar); |
5568 Expression* parm_ref = | 5742 Expression* parm_ref = |
5569 Expression::make_var_reference(parm_no, loc); | 5743 Expression::make_var_reference(parm_no, loc); |
5570 parm_ref = Expression::make_unary(OPERATOR_MULT, parm_ref, loc); | 5744 parm_ref = |
5745 Expression::make_dereference(parm_ref, | |
5746 Expression::NIL_CHECK_NEEDED, | |
5747 loc); | |
5571 if ((*p)->var_value()->is_in_heap()) | 5748 if ((*p)->var_value()->is_in_heap()) |
5572 parm_ref = Expression::make_heap_expression(parm_ref, loc); | 5749 parm_ref = Expression::make_heap_expression(parm_ref, loc); |
5573 var_inits.push_back(parm_ref->get_backend(&context)); | 5750 var_inits.push_back(parm_ref->get_backend(&context)); |
5574 } | 5751 } |
5575 else if ((*p)->var_value()->is_in_heap()) | 5752 else if ((*p)->var_value()->is_in_heap()) |
5607 loc)->get_backend(&context); | 5784 loc)->get_backend(&context); |
5608 | 5785 |
5609 vars.push_back(bvar); | 5786 vars.push_back(bvar); |
5610 var_inits.push_back(init); | 5787 var_inits.push_back(init); |
5611 } | 5788 } |
5789 else if (this->defer_stack_ != NULL | |
5790 && (*p)->is_variable() | |
5791 && (*p)->var_value()->is_non_escaping_address_taken() | |
5792 && !(*p)->var_value()->is_in_heap()) | |
5793 { | |
5794 // Local variable captured by deferred closure needs to be live | |
5795 // until the end of the function. We create a top-level | |
5796 // declaration for it. | |
5797 // TODO: we don't need to do this if the variable is not captured | |
5798 // by the defer closure. There is no easy way to check it here, | |
5799 // so we do this for all address-taken variables for now. | |
5800 Variable* var = (*p)->var_value(); | |
5801 Temporary_statement* ts = | |
5802 Statement::make_temporary(var->type(), NULL, var->location()); | |
5803 ts->set_is_address_taken(); | |
5804 var->set_toplevel_decl(ts); | |
5805 var_decls_stmts.push_back(ts); | |
5806 } | |
5612 } | 5807 } |
5613 if (!gogo->backend()->function_set_parameters(this->fndecl_, param_vars)) | 5808 if (!gogo->backend()->function_set_parameters(this->fndecl_, param_vars)) |
5614 { | 5809 { |
5615 go_assert(saw_errors()); | 5810 go_assert(saw_errors()); |
5616 return; | 5811 return; |
5626 | 5821 |
5627 if (this->block_ != NULL) | 5822 if (this->block_ != NULL) |
5628 { | 5823 { |
5629 // Declare variables if necessary. | 5824 // Declare variables if necessary. |
5630 Bblock* var_decls = NULL; | 5825 Bblock* var_decls = NULL; |
5631 | 5826 std::vector<Bstatement*> var_decls_bstmt_list; |
5632 Bstatement* defer_init = NULL; | 5827 Bstatement* defer_init = NULL; |
5633 if (!vars.empty() || this->defer_stack_ != NULL) | 5828 if (!vars.empty() || this->defer_stack_ != NULL) |
5634 { | 5829 { |
5635 var_decls = | 5830 var_decls = |
5636 gogo->backend()->block(this->fndecl_, NULL, vars, | 5831 gogo->backend()->block(this->fndecl_, NULL, vars, |
5640 if (this->defer_stack_ != NULL) | 5835 if (this->defer_stack_ != NULL) |
5641 { | 5836 { |
5642 Translate_context dcontext(gogo, named_function, this->block_, | 5837 Translate_context dcontext(gogo, named_function, this->block_, |
5643 var_decls); | 5838 var_decls); |
5644 defer_init = this->defer_stack_->get_backend(&dcontext); | 5839 defer_init = this->defer_stack_->get_backend(&dcontext); |
5840 var_decls_bstmt_list.push_back(defer_init); | |
5841 for (std::vector<Statement*>::iterator p = var_decls_stmts.begin(); | |
5842 p != var_decls_stmts.end(); | |
5843 ++p) | |
5844 { | |
5845 Bstatement* bstmt = (*p)->get_backend(&dcontext); | |
5846 var_decls_bstmt_list.push_back(bstmt); | |
5847 } | |
5645 } | 5848 } |
5646 } | 5849 } |
5647 | 5850 |
5648 // Build the backend representation for all the statements in the | 5851 // Build the backend representation for all the statements in the |
5649 // function. | 5852 // function. |
5658 Bstatement* init_stmt = | 5861 Bstatement* init_stmt = |
5659 gogo->backend()->init_statement(this->fndecl_, vars[i], | 5862 gogo->backend()->init_statement(this->fndecl_, vars[i], |
5660 var_inits[i]); | 5863 var_inits[i]); |
5661 init.push_back(init_stmt); | 5864 init.push_back(init_stmt); |
5662 } | 5865 } |
5663 if (defer_init != NULL) | |
5664 init.push_back(defer_init); | |
5665 Bstatement* var_init = gogo->backend()->statement_list(init); | 5866 Bstatement* var_init = gogo->backend()->statement_list(init); |
5666 | 5867 |
5667 // Initialize all variables before executing this code block. | 5868 // Initialize all variables before executing this code block. |
5668 Bstatement* code_stmt = gogo->backend()->block_statement(code_block); | 5869 Bstatement* code_stmt = gogo->backend()->block_statement(code_block); |
5669 code_stmt = gogo->backend()->compound_statement(var_init, code_stmt); | 5870 code_stmt = gogo->backend()->compound_statement(var_init, code_stmt); |
5687 | 5888 |
5688 // Stick the code into the block we built for the receiver, if | 5889 // Stick the code into the block we built for the receiver, if |
5689 // we built one. | 5890 // we built one. |
5690 if (var_decls != NULL) | 5891 if (var_decls != NULL) |
5691 { | 5892 { |
5692 std::vector<Bstatement*> code_stmt_list(1, code_stmt); | 5893 var_decls_bstmt_list.push_back(code_stmt); |
5693 gogo->backend()->block_add_statements(var_decls, code_stmt_list); | 5894 gogo->backend()->block_add_statements(var_decls, var_decls_bstmt_list); |
5694 code_stmt = gogo->backend()->block_statement(var_decls); | 5895 code_stmt = gogo->backend()->block_statement(var_decls); |
5695 } | 5896 } |
5696 | 5897 |
5697 if (!gogo->backend()->function_set_body(this->fndecl_, code_stmt)) | 5898 if (!gogo->backend()->function_set_body(this->fndecl_, code_stmt)) |
5698 { | 5899 { |
5796 std::vector<Bexpression*> vals(results->size()); | 5997 std::vector<Bexpression*> vals(results->size()); |
5797 for (size_t i = 0; i < vals.size(); ++i) | 5998 for (size_t i = 0; i < vals.size(); ++i) |
5798 { | 5999 { |
5799 Named_object* no = (*this->results_)[i]; | 6000 Named_object* no = (*this->results_)[i]; |
5800 Bvariable* bvar = no->get_backend_variable(gogo, named_function); | 6001 Bvariable* bvar = no->get_backend_variable(gogo, named_function); |
5801 Bexpression* val = gogo->backend()->var_expression(bvar, VE_rvalue, | 6002 Bexpression* val = gogo->backend()->var_expression(bvar, location); |
5802 location); | |
5803 if (no->result_var_value()->is_in_heap()) | 6003 if (no->result_var_value()->is_in_heap()) |
5804 { | 6004 { |
5805 Btype* bt = no->result_var_value()->type()->get_backend(gogo); | 6005 Btype* bt = no->result_var_value()->type()->get_backend(gogo); |
5806 val = gogo->backend()->indirect_expression(bt, val, true, location); | 6006 val = gogo->backend()->indirect_expression(bt, val, true, location); |
5807 } | 6007 } |
6130 go_assert(p != block->bindings()->end_definitions()); | 6330 go_assert(p != block->bindings()->end_definitions()); |
6131 ++p; | 6331 ++p; |
6132 } | 6332 } |
6133 go_assert(p != block->bindings()->end_definitions()); | 6333 go_assert(p != block->bindings()->end_definitions()); |
6134 | 6334 |
6135 std::string n = (*p)->message_name(); | 6335 for (; p != block->bindings()->end_definitions(); ++p) |
6136 go_error_at(loc, "goto jumps over declaration of %qs", n.c_str()); | 6336 { |
6137 go_inform((*p)->location(), "%qs defined here", n.c_str()); | 6337 if ((*p)->is_variable()) |
6338 { | |
6339 std::string n = (*p)->message_name(); | |
6340 go_error_at(loc, "goto jumps over declaration of %qs", n.c_str()); | |
6341 go_inform((*p)->location(), "%qs defined here", n.c_str()); | |
6342 } | |
6343 } | |
6138 } | 6344 } |
6139 } | 6345 } |
6140 | 6346 |
6141 // Class Function_declaration. | 6347 // Class Function_declaration. |
6348 | |
6349 // Whether this declares a method. | |
6350 | |
6351 bool | |
6352 Function_declaration::is_method() const | |
6353 { | |
6354 return this->fntype_->is_method(); | |
6355 } | |
6356 | |
6357 // Whether this method should not be included in the type descriptor. | |
6358 | |
6359 bool | |
6360 Function_declaration::nointerface() const | |
6361 { | |
6362 go_assert(this->is_method()); | |
6363 return (this->pragmas_ & GOPRAGMA_NOINTERFACE) != 0; | |
6364 } | |
6365 | |
6366 // Record that this method should not be included in the type | |
6367 // descriptor. | |
6368 | |
6369 void | |
6370 Function_declaration::set_nointerface() | |
6371 { | |
6372 this->pragmas_ |= GOPRAGMA_NOINTERFACE; | |
6373 } | |
6142 | 6374 |
6143 // Return the function descriptor. | 6375 // Return the function descriptor. |
6144 | 6376 |
6145 Expression* | 6377 Expression* |
6146 Function_declaration::descriptor(Gogo*, Named_object* no) | 6378 Function_declaration::descriptor(Gogo*, Named_object* no) |
6163 is_address_taken_(false), is_non_escaping_address_taken_(false), | 6395 is_address_taken_(false), is_non_escaping_address_taken_(false), |
6164 seen_(false), init_is_lowered_(false), init_is_flattened_(false), | 6396 seen_(false), init_is_lowered_(false), init_is_flattened_(false), |
6165 type_from_init_tuple_(false), type_from_range_index_(false), | 6397 type_from_init_tuple_(false), type_from_range_index_(false), |
6166 type_from_range_value_(false), type_from_chan_element_(false), | 6398 type_from_range_value_(false), type_from_chan_element_(false), |
6167 is_type_switch_var_(false), determined_type_(false), | 6399 is_type_switch_var_(false), determined_type_(false), |
6168 in_unique_section_(false), escapes_(true) | 6400 in_unique_section_(false), escapes_(true), |
6401 toplevel_decl_(NULL) | |
6169 { | 6402 { |
6170 go_assert(type != NULL || init != NULL); | 6403 go_assert(type != NULL || init != NULL); |
6171 go_assert(!is_parameter || init == NULL); | 6404 go_assert(!is_parameter || init == NULL); |
6172 } | 6405 } |
6173 | 6406 |
6257 gogo->flatten_expression(function, inserter, &this->init_); | 6490 gogo->flatten_expression(function, inserter, &this->init_); |
6258 | 6491 |
6259 // If an interface conversion is needed, we need a temporary | 6492 // If an interface conversion is needed, we need a temporary |
6260 // variable. | 6493 // variable. |
6261 if (this->type_ != NULL | 6494 if (this->type_ != NULL |
6262 && !Type::are_identical(this->type_, this->init_->type(), false, | 6495 && !Type::are_identical(this->type_, this->init_->type(), |
6496 Type::COMPARE_ERRORS | Type::COMPARE_TAGS, | |
6263 NULL) | 6497 NULL) |
6264 && this->init_->type()->interface_type() != NULL | 6498 && this->init_->type()->interface_type() != NULL |
6265 && !this->init_->is_variable()) | 6499 && !this->init_->is_variable()) |
6266 { | 6500 { |
6267 Temporary_statement* temp = | 6501 Temporary_statement* temp = |
6630 Location loc = this->location(); | 6864 Location loc = this->location(); |
6631 Expression* val_expr = | 6865 Expression* val_expr = |
6632 Expression::make_cast(this->type(), this->init_, loc); | 6866 Expression::make_cast(this->type(), this->init_, loc); |
6633 Bexpression* val = val_expr->get_backend(&context); | 6867 Bexpression* val = val_expr->get_backend(&context); |
6634 Bexpression* var_ref = | 6868 Bexpression* var_ref = |
6635 gogo->backend()->var_expression(var_decl, VE_lvalue, loc); | 6869 gogo->backend()->var_expression(var_decl, loc); |
6636 decl_init = gogo->backend()->assignment_statement(bfunction, var_ref, | 6870 decl_init = gogo->backend()->assignment_statement(bfunction, var_ref, |
6637 val, loc); | 6871 val, loc); |
6638 } | 6872 } |
6639 } | 6873 } |
6640 Bstatement* block_stmt = gogo->backend()->block_statement(bblock); | 6874 Bstatement* block_stmt = gogo->backend()->block_statement(bblock); |
6651 go_assert(this->is_global_); | 6885 go_assert(this->is_global_); |
6652 exp->write_c_string("var "); | 6886 exp->write_c_string("var "); |
6653 exp->write_string(name); | 6887 exp->write_string(name); |
6654 exp->write_c_string(" "); | 6888 exp->write_c_string(" "); |
6655 exp->write_type(this->type()); | 6889 exp->write_type(this->type()); |
6656 exp->write_c_string(";\n"); | 6890 exp->write_c_string("\n"); |
6657 } | 6891 } |
6658 | 6892 |
6659 // Import a variable. | 6893 // Import a variable. |
6660 | 6894 |
6661 void | 6895 void |
6663 { | 6897 { |
6664 imp->require_c_string("var "); | 6898 imp->require_c_string("var "); |
6665 *pname = imp->read_identifier(); | 6899 *pname = imp->read_identifier(); |
6666 imp->require_c_string(" "); | 6900 imp->require_c_string(" "); |
6667 *ptype = imp->read_type(); | 6901 *ptype = imp->read_type(); |
6668 imp->require_c_string(";\n"); | 6902 imp->require_semicolon_if_old_version(); |
6903 imp->require_c_string("\n"); | |
6669 } | 6904 } |
6670 | 6905 |
6671 // Convert a variable to the backend representation. | 6906 // Convert a variable to the backend representation. |
6672 | 6907 |
6673 Bvariable* | 6908 Bvariable* |
6740 else if (is_parameter) | 6975 else if (is_parameter) |
6741 bvar = backend->parameter_variable(bfunction, n, btype, | 6976 bvar = backend->parameter_variable(bfunction, n, btype, |
6742 is_address_taken, | 6977 is_address_taken, |
6743 this->location_); | 6978 this->location_); |
6744 else | 6979 else |
6745 bvar = backend->local_variable(bfunction, n, btype, | 6980 { |
6746 is_address_taken, | 6981 Bvariable* bvar_decl = NULL; |
6747 this->location_); | 6982 if (this->toplevel_decl_ != NULL) |
6983 { | |
6984 Translate_context context(gogo, NULL, NULL, NULL); | |
6985 bvar_decl = this->toplevel_decl_->temporary_statement() | |
6986 ->get_backend_variable(&context); | |
6987 } | |
6988 bvar = backend->local_variable(bfunction, n, btype, | |
6989 bvar_decl, | |
6990 is_address_taken, | |
6991 this->location_); | |
6992 } | |
6748 } | 6993 } |
6749 this->backend_ = bvar; | 6994 this->backend_ = bvar; |
6750 } | 6995 } |
6751 } | 6996 } |
6752 return this->backend_; | 6997 return this->backend_; |
6774 Bfunction* bfunction = function->func_value()->get_decl(); | 7019 Bfunction* bfunction = function->func_value()->get_decl(); |
6775 std::string n = Gogo::unpack_hidden_name(name); | 7020 std::string n = Gogo::unpack_hidden_name(name); |
6776 bool is_address_taken = (this->is_non_escaping_address_taken_ | 7021 bool is_address_taken = (this->is_non_escaping_address_taken_ |
6777 && !this->is_in_heap()); | 7022 && !this->is_in_heap()); |
6778 this->backend_ = backend->local_variable(bfunction, n, btype, | 7023 this->backend_ = backend->local_variable(bfunction, n, btype, |
6779 is_address_taken, | 7024 NULL, is_address_taken, |
6780 this->location_); | 7025 this->location_); |
6781 } | 7026 } |
6782 } | 7027 } |
6783 return this->backend_; | 7028 return this->backend_; |
6784 } | 7029 } |
6785 | 7030 |
6786 // Class Named_constant. | 7031 // Class Named_constant. |
7032 | |
7033 // Set the type of a named constant. This is only used to set the | |
7034 // type to an error type. | |
7035 | |
7036 void | |
7037 Named_constant::set_type(Type* t) | |
7038 { | |
7039 go_assert(this->type_ == NULL || t->is_error_type()); | |
7040 this->type_ = t; | |
7041 } | |
6787 | 7042 |
6788 // Traverse the initializer expression. | 7043 // Traverse the initializer expression. |
6789 | 7044 |
6790 int | 7045 int |
6791 Named_constant::traverse_expression(Traverse* traverse) | 7046 Named_constant::traverse_expression(Traverse* traverse) |
6835 exp->write_type(this->type_); | 7090 exp->write_type(this->type_); |
6836 exp->write_c_string(" "); | 7091 exp->write_c_string(" "); |
6837 } | 7092 } |
6838 exp->write_c_string("= "); | 7093 exp->write_c_string("= "); |
6839 this->expr()->export_expression(exp); | 7094 this->expr()->export_expression(exp); |
6840 exp->write_c_string(";\n"); | 7095 exp->write_c_string("\n"); |
6841 } | 7096 } |
6842 | 7097 |
6843 // Import a constant. | 7098 // Import a constant. |
6844 | 7099 |
6845 void | 7100 void |
6856 *ptype = imp->read_type(); | 7111 *ptype = imp->read_type(); |
6857 imp->require_c_string(" "); | 7112 imp->require_c_string(" "); |
6858 } | 7113 } |
6859 imp->require_c_string("= "); | 7114 imp->require_c_string("= "); |
6860 *pexpr = Expression::import_expression(imp); | 7115 *pexpr = Expression::import_expression(imp); |
6861 imp->require_c_string(";\n"); | 7116 imp->require_semicolon_if_old_version(); |
7117 imp->require_c_string("\n"); | |
6862 } | 7118 } |
6863 | 7119 |
6864 // Get the backend representation. | 7120 // Get the backend representation. |
6865 | 7121 |
6866 Bexpression* | 7122 Bexpression* |
7253 case NAMED_OBJECT_CONST: | 7509 case NAMED_OBJECT_CONST: |
7254 this->const_value()->export_const(exp, this->name_); | 7510 this->const_value()->export_const(exp, this->name_); |
7255 break; | 7511 break; |
7256 | 7512 |
7257 case NAMED_OBJECT_TYPE: | 7513 case NAMED_OBJECT_TYPE: |
7258 this->type_value()->export_named_type(exp, this->name_); | 7514 // Types are handled by export::write_types. |
7259 break; | 7515 go_unreachable(); |
7260 | 7516 |
7261 case NAMED_OBJECT_TYPE_DECLARATION: | 7517 case NAMED_OBJECT_TYPE_DECLARATION: |
7262 go_error_at(this->type_declaration_value()->location(), | 7518 go_error_at(this->type_declaration_value()->location(), |
7263 "attempt to export %<%s%> which was declared but not defined", | 7519 "attempt to export %<%s%> which was declared but not defined", |
7264 this->message_name().c_str()); | 7520 this->message_name().c_str()); |
7368 break; | 7624 break; |
7369 | 7625 |
7370 case NAMED_OBJECT_TYPE: | 7626 case NAMED_OBJECT_TYPE: |
7371 { | 7627 { |
7372 Named_type* named_type = this->u_.type_value; | 7628 Named_type* named_type = this->u_.type_value; |
7373 if (!Gogo::is_erroneous_name(this->name_)) | 7629 if (!Gogo::is_erroneous_name(this->name_) && !named_type->is_alias()) |
7374 type_decls.push_back(named_type->get_backend(gogo)); | 7630 type_decls.push_back(named_type->get_backend(gogo)); |
7375 | 7631 |
7376 // We need to produce a type descriptor for every named | 7632 // We need to produce a type descriptor for every named |
7377 // type, and for a pointer to every named type, since | 7633 // type, and for a pointer to every named type, since |
7378 // other files or packages might refer to them. We need | 7634 // other files or packages might refer to them. We need |
7622 | 7878 |
7623 case Named_object::NAMED_OBJECT_SINK: | 7879 case Named_object::NAMED_OBJECT_SINK: |
7624 go_unreachable(); | 7880 go_unreachable(); |
7625 | 7881 |
7626 case Named_object::NAMED_OBJECT_FUNC: | 7882 case Named_object::NAMED_OBJECT_FUNC: |
7627 if (new_object->is_function_declaration()) | |
7628 { | |
7629 if (!new_object->func_declaration_value()->asm_name().empty()) | |
7630 go_error_at(Linemap::unknown_location(), | |
7631 ("sorry, not implemented: " | |
7632 "__asm__ for function definitions")); | |
7633 Function_type* old_type = old_object->func_value()->type(); | |
7634 Function_type* new_type = | |
7635 new_object->func_declaration_value()->type(); | |
7636 if (old_type->is_valid_redeclaration(new_type, &reason)) | |
7637 return old_object; | |
7638 } | |
7639 break; | 7883 break; |
7640 | 7884 |
7641 case Named_object::NAMED_OBJECT_FUNC_DECLARATION: | 7885 case Named_object::NAMED_OBJECT_FUNC_DECLARATION: |
7642 { | 7886 { |
7643 if (new_object->is_function()) | 7887 // We declare the hash and equality functions before defining |
7888 // them, because we sometimes see that we need the declaration | |
7889 // while we are in the middle of a different function. We | |
7890 // declare the main function before the user defines it, to | |
7891 // give better error messages. | |
7892 if (new_object->is_function() | |
7893 && ((Linemap::is_predeclared_location(old_object->location()) | |
7894 && Linemap::is_predeclared_location(new_object->location())) | |
7895 || (Gogo::unpack_hidden_name(old_object->name()) == "main" | |
7896 && Linemap::is_unknown_location(old_object->location())))) | |
7644 { | 7897 { |
7645 Function_type* old_type = | 7898 Function_type* old_type = |
7646 old_object->func_declaration_value()->type(); | 7899 old_object->func_declaration_value()->type(); |
7647 Function_type* new_type = new_object->func_value()->type(); | 7900 Function_type* new_type = new_object->func_value()->type(); |
7648 if (old_type->is_valid_redeclaration(new_type, &reason)) | 7901 if (old_type->is_valid_redeclaration(new_type, &reason)) |
7649 { | 7902 { |
7650 if (!old_object->func_declaration_value()->asm_name().empty()) | 7903 Function_declaration* fd = |
7651 go_error_at(Linemap::unknown_location(), | 7904 old_object->func_declaration_value(); |
7652 ("sorry, not implemented: " | 7905 go_assert(fd->asm_name().empty()); |
7653 "__asm__ for function definitions")); | |
7654 old_object->set_function_value(new_object->func_value()); | 7906 old_object->set_function_value(new_object->func_value()); |
7655 this->named_objects_.push_back(old_object); | 7907 this->named_objects_.push_back(old_object); |
7656 return old_object; | 7908 return old_object; |
7657 } | 7909 } |
7658 } | 7910 } |
7670 go_error_at(new_object->location(), "redefinition of %qs: %s", n.c_str(), | 7922 go_error_at(new_object->location(), "redefinition of %qs: %s", n.c_str(), |
7671 reason.c_str()); | 7923 reason.c_str()); |
7672 old_object->set_is_redefinition(); | 7924 old_object->set_is_redefinition(); |
7673 new_object->set_is_redefinition(); | 7925 new_object->set_is_redefinition(); |
7674 | 7926 |
7675 go_inform(old_object->location(), "previous definition of %qs was here", | 7927 if (!Linemap::is_unknown_location(old_object->location()) |
7676 n.c_str()); | 7928 && !Linemap::is_predeclared_location(old_object->location())) |
7929 go_inform(old_object->location(), "previous definition of %qs was here", | |
7930 n.c_str()); | |
7677 | 7931 |
7678 return old_object; | 7932 return old_object; |
7679 } | 7933 } |
7680 | 7934 |
7681 // Add a named type. | 7935 // Add a named type. |
7867 } | 8121 } |
7868 } | 8122 } |
7869 } | 8123 } |
7870 } | 8124 } |
7871 | 8125 |
8126 // Traverse function declarations when needed. | |
8127 if ((traverse_mask & Traverse::traverse_func_declarations) != 0) | |
8128 { | |
8129 for (Bindings::const_declarations_iterator p = this->begin_declarations(); | |
8130 p != this->end_declarations(); | |
8131 ++p) | |
8132 { | |
8133 if (p->second->is_function_declaration()) | |
8134 { | |
8135 if (traverse->function_declaration(p->second) == TRAVERSE_EXIT) | |
8136 return TRAVERSE_EXIT; | |
8137 } | |
8138 } | |
8139 } | |
8140 | |
7872 return TRAVERSE_CONTINUE; | 8141 return TRAVERSE_CONTINUE; |
7873 } | 8142 } |
7874 | 8143 |
7875 // Class Label. | 8144 // Class Label. |
7876 | 8145 |
8105 go_assert((this->traverse_mask() & traverse_types) != 0 | 8374 go_assert((this->traverse_mask() & traverse_types) != 0 |
8106 || (this->traverse_mask() & traverse_expressions) != 0); | 8375 || (this->traverse_mask() & traverse_expressions) != 0); |
8107 // We mostly only have to remember named types. But it turns out | 8376 // We mostly only have to remember named types. But it turns out |
8108 // that an interface type can refer to itself without using a name | 8377 // that an interface type can refer to itself without using a name |
8109 // by relying on interface inheritance, as in | 8378 // by relying on interface inheritance, as in |
8110 // type I interface { F() interface{I} } | 8379 // |
8380 // type I interface { F() interface{I} } | |
8381 // | |
8382 // Similarly it is possible for array types to refer to themselves | |
8383 // without a name, e.g. | |
8384 // | |
8385 // var x [uintptr(unsafe.Sizeof(&x))]byte | |
8386 // | |
8111 if (type->classification() != Type::TYPE_NAMED | 8387 if (type->classification() != Type::TYPE_NAMED |
8388 && type->classification() != Type::TYPE_ARRAY | |
8112 && type->classification() != Type::TYPE_INTERFACE) | 8389 && type->classification() != Type::TYPE_INTERFACE) |
8113 return false; | 8390 return false; |
8114 if (this->types_seen_ == NULL) | 8391 if (this->types_seen_ == NULL) |
8115 this->types_seen_ = new Types_seen(); | 8392 this->types_seen_ = new Types_seen(); |
8116 std::pair<Types_seen::iterator, bool> ins = this->types_seen_->insert(type); | 8393 std::pair<Types_seen::iterator, bool> ins = this->types_seen_->insert(type); |
8176 Traverse::type(Type*) | 8453 Traverse::type(Type*) |
8177 { | 8454 { |
8178 go_unreachable(); | 8455 go_unreachable(); |
8179 } | 8456 } |
8180 | 8457 |
8458 int | |
8459 Traverse::function_declaration(Named_object*) | |
8460 { | |
8461 go_unreachable(); | |
8462 } | |
8463 | |
8181 // Class Statement_inserter. | 8464 // Class Statement_inserter. |
8182 | 8465 |
8183 void | 8466 void |
8184 Statement_inserter::insert(Statement* s) | 8467 Statement_inserter::insert(Statement* s) |
8185 { | 8468 { |
8469 if (this->statements_added_ != NULL) | |
8470 this->statements_added_->insert(s); | |
8471 | |
8186 if (this->block_ != NULL) | 8472 if (this->block_ != NULL) |
8187 { | 8473 { |
8188 go_assert(this->pindex_ != NULL); | 8474 go_assert(this->pindex_ != NULL); |
8189 this->block_->insert_statement_before(*this->pindex_, s); | 8475 this->block_->insert_statement_before(*this->pindex_, s); |
8190 ++*this->pindex_; | 8476 ++*this->pindex_; |