| 1128 | } |
| 1129 | |
| 1130 | static unique_ptr<Instr> parse_call(string_view name) { |
| 1131 | // call ty name(ty_1 %op_1, ..., ty_n %op_n) |
| 1132 | auto &ret_ty = parse_type(); |
| 1133 | auto fn_name = parse_global_name(); |
| 1134 | tokenizer.ensure(LPAREN); |
| 1135 | |
| 1136 | vector<Value*> args; |
| 1137 | bool first = true; |
| 1138 | |
| 1139 | while (tokenizer.peek() != RPAREN) { |
| 1140 | if (!first) |
| 1141 | tokenizer.ensure(COMMA); |
| 1142 | first = false; |
| 1143 | auto &ty = parse_type(); |
| 1144 | args.emplace_back(&parse_operand(ty)); |
| 1145 | } |
| 1146 | tokenizer.ensure(RPAREN); |
| 1147 | |
| 1148 | FnAttrs attrs; |
| 1149 | attrs.mem.setFullAccess(); |
| 1150 | |
| 1151 | while (true) { |
| 1152 | switch (auto t = *tokenizer) { |
| 1153 | case MEMORY: parse_memory_access(attrs.mem); break; |
| 1154 | case NORETURN: attrs.set(FnAttrs::NoReturn); break; |
| 1155 | case WILLRETURN: attrs.set(FnAttrs::WillReturn); break; |
| 1156 | default: |
| 1157 | tokenizer.unget(t); |
| 1158 | goto exit; |
| 1159 | } |
| 1160 | } |
| 1161 | exit: |
| 1162 | attrs.inferImpliedAttributes(); |
| 1163 | auto call = make_unique<FnCall>(ret_ty, string(name), std::move(fn_name), |
| 1164 | std::move(attrs)); |
| 1165 | |
| 1166 | for (auto arg : args) { |
| 1167 | call->addArg(*arg, ParamAttrs::None); |
| 1168 | } |
| 1169 | return call; |
| 1170 | } |
| 1171 | |
| 1172 | static unique_ptr<Instr> parse_extractelement(string_view name) { |
| 1173 | // %p = extractelement vty %v, ty %idx |
no test coverage detected