| ... | ... | @@ -324,6 +324,10 @@ static AstNode *add_global_var(Context *c, Buf *var_name, AstNode *value_node) { |
| 324 | 324 | return node; |
| 325 | 325 | } |
| 326 | 326 | |
| 327 | static Buf *string_ref_to_buf(StringRef string_ref) { |
| 328 | return buf_create_from_mem((const char *)string_ref.bytes_begin(), string_ref.size()); |
| 329 | } |
| 330 | |
| 327 | 331 | static const char *decl_name(const Decl *decl) { |
| 328 | 332 | const NamedDecl *named_decl = static_cast<const NamedDecl *>(decl); |
| 329 | 333 | return (const char *)named_decl->getName().bytes_begin(); |
| ... | ... | @@ -339,6 +343,44 @@ static AstNode *trans_create_node_apint(Context *c, const llvm::APSInt &aps_int) |
| 339 | 343 | |
| 340 | 344 | static AstNode *trans_qual_type(Context *c, QualType qt, const SourceLocation &source_loc); |
| 341 | 345 | |
| 346 | static QualType get_expr_qual_type(Context *c, const Expr *expr) { |
| 347 | // String literals in C are `char *` but they should really be `const char *`. |
| 348 | if (expr->getStmtClass() == Stmt::ImplicitCastExprClass) { |
| 349 | const ImplicitCastExpr *cast_expr = static_cast<const ImplicitCastExpr *>(expr); |
| 350 | if (cast_expr->getCastKind() == CK_ArrayToPointerDecay) { |
| 351 | const Expr *sub_expr = cast_expr->getSubExpr(); |
| 352 | if (sub_expr->getStmtClass() == Stmt::StringLiteralClass) { |
| 353 | QualType array_qt = sub_expr->getType(); |
| 354 | const ArrayType *array_type = static_cast<const ArrayType *>(array_qt.getTypePtr()); |
| 355 | QualType pointee_qt = array_type->getElementType(); |
| 356 | pointee_qt.addConst(); |
| 357 | return c->ctx->getPointerType(pointee_qt); |
| 358 | } |
| 359 | } |
| 360 | } |
| 361 | return expr->getType(); |
| 362 | } |
| 363 | |
| 364 | static AstNode *get_expr_type(Context *c, const Expr *expr) { |
| 365 | return trans_qual_type(c, get_expr_qual_type(c, expr), expr->getLocStart()); |
| 366 | } |
| 367 | |
| 368 | static bool expr_types_equal(Context *c, const Expr *expr1, const Expr *expr2) { |
| 369 | QualType t1 = get_expr_qual_type(c, expr1); |
| 370 | QualType t2 = get_expr_qual_type(c, expr2); |
| 371 | |
| 372 | if (t1.isConstQualified() != t2.isConstQualified()) { |
| 373 | return false; |
| 374 | } |
| 375 | if (t1.isVolatileQualified() != t2.isVolatileQualified()) { |
| 376 | return false; |
| 377 | } |
| 378 | if (t1.isRestrictQualified() != t2.isRestrictQualified()) { |
| 379 | return false; |
| 380 | } |
| 381 | return t1.getTypePtr() == t2.getTypePtr(); |
| 382 | } |
| 383 | |
| 342 | 384 | static bool is_c_void_type(AstNode *node) { |
| 343 | 385 | return (node->type == NodeTypeSymbol && buf_eql_str(node->data.symbol_expr.symbol, "c_void")); |
| 344 | 386 | } |
| ... | ... | @@ -1335,7 +1377,11 @@ static AstNode *trans_implicit_cast_expr(Context *c, AstNode *block, ImplicitCas |
| 1335 | 1377 | if (target_node == nullptr) |
| 1336 | 1378 | return nullptr; |
| 1337 | 1379 | |
| 1338 | | AstNode *dest_type_node = trans_qual_type(c, stmt->getType(), stmt->getLocStart()); |
| 1380 | if (expr_types_equal(c, stmt, stmt->getSubExpr())) { |
| 1381 | return target_node; |
| 1382 | } |
| 1383 | |
| 1384 | AstNode *dest_type_node = get_expr_type(c, stmt); |
| 1339 | 1385 | |
| 1340 | 1386 | AstNode *node = trans_create_node_builtin_fn_call_str(c, "ptrCast"); |
| 1341 | 1387 | node->data.fn_call_expr.params.append(dest_type_node); |
| ... | ... | @@ -2126,6 +2172,24 @@ static AstNode *trans_do_loop(Context *c, AstNode *block, DoStmt *stmt) { |
| 2126 | 2172 | return while_node; |
| 2127 | 2173 | } |
| 2128 | 2174 | |
| 2175 | static AstNode *trans_string_literal(Context *c, AstNode *block, StringLiteral *stmt) { |
| 2176 | switch (stmt->getKind()) { |
| 2177 | case StringLiteral::Ascii: |
| 2178 | case StringLiteral::UTF8: |
| 2179 | return trans_create_node_str_lit_c(c, string_ref_to_buf(stmt->getString())); |
| 2180 | case StringLiteral::UTF16: |
| 2181 | emit_warning(c, stmt->getLocStart(), "TODO support UTF16 string literals"); |
| 2182 | return nullptr; |
| 2183 | case StringLiteral::UTF32: |
| 2184 | emit_warning(c, stmt->getLocStart(), "TODO support UTF32 string literals"); |
| 2185 | return nullptr; |
| 2186 | case StringLiteral::Wide: |
| 2187 | emit_warning(c, stmt->getLocStart(), "TODO support wide string literals"); |
| 2188 | return nullptr; |
| 2189 | } |
| 2190 | zig_unreachable(); |
| 2191 | } |
| 2192 | |
| 2129 | 2193 | static AstNode *trans_stmt(Context *c, bool result_used, AstNode *block, Stmt *stmt, TransLRValue lrvalue) { |
| 2130 | 2194 | Stmt::StmtClass sc = stmt->getStmtClass(); |
| 2131 | 2195 | switch (sc) { |
| ... | ... | @@ -2167,6 +2231,8 @@ static AstNode *trans_stmt(Context *c, bool result_used, AstNode *block, Stmt *s |
| 2167 | 2231 | return trans_unary_expr_or_type_trait_expr(c, block, (UnaryExprOrTypeTraitExpr *)stmt); |
| 2168 | 2232 | case Stmt::DoStmtClass: |
| 2169 | 2233 | return trans_do_loop(c, block, (DoStmt *)stmt); |
| 2234 | case Stmt::StringLiteralClass: |
| 2235 | return trans_string_literal(c, block, (StringLiteral *)stmt); |
| 2170 | 2236 | case Stmt::CaseStmtClass: |
| 2171 | 2237 | emit_warning(c, stmt->getLocStart(), "TODO handle C CaseStmtClass"); |
| 2172 | 2238 | return nullptr; |
| ... | ... | @@ -2488,9 +2554,6 @@ static AstNode *trans_stmt(Context *c, bool result_used, AstNode *block, Stmt *s |
| 2488 | 2554 | case Stmt::StmtExprClass: |
| 2489 | 2555 | emit_warning(c, stmt->getLocStart(), "TODO handle C StmtExprClass"); |
| 2490 | 2556 | return nullptr; |
| 2491 | | case Stmt::StringLiteralClass: |
| 2492 | | emit_warning(c, stmt->getLocStart(), "TODO handle C StringLiteralClass"); |
| 2493 | | return nullptr; |
| 2494 | 2557 | case Stmt::SubstNonTypeTemplateParmExprClass: |
| 2495 | 2558 | emit_warning(c, stmt->getLocStart(), "TODO handle C SubstNonTypeTemplateParmExprClass"); |
| 2496 | 2559 | return nullptr; |
| ... | ... | @@ -3530,7 +3593,7 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const ch |
| 3530 | 3593 | break; |
| 3531 | 3594 | } |
| 3532 | 3595 | StringRef msg_str_ref = it->getMessage(); |
| 3533 | | Buf *msg = buf_create_from_str((const char *)msg_str_ref.bytes_begin()); |
| 3596 | Buf *msg = string_ref_to_buf(msg_str_ref); |
| 3534 | 3597 | FullSourceLoc fsl = it->getLocation(); |
| 3535 | 3598 | if (fsl.hasManager()) { |
| 3536 | 3599 | FileID file_id = fsl.getFileID(); |
| ... | ... | @@ -3543,7 +3606,7 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const ch |
| 3543 | 3606 | if (filename.empty()) { |
| 3544 | 3607 | path = buf_alloc(); |
| 3545 | 3608 | } else { |
| 3546 | | path = buf_create_from_mem((const char *)filename.bytes_begin(), filename.size()); |
| 3609 | path = string_ref_to_buf(filename); |
| 3547 | 3610 | } |
| 3548 | 3611 | |
| 3549 | 3612 | ErrorMsg *err_msg = err_msg_create_with_offset(path, line, column, offset, source, msg); |