| ... | @@ -324,6 +324,10 @@ static AstNode *add_global_var(Context *c, Buf *var_name, AstNode *value_node) { | ... | @@ -324,6 +324,10 @@ static AstNode *add_global_var(Context *c, Buf *var_name, AstNode *value_node) { |
| 324 | return node; | 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 | static const char *decl_name(const Decl *decl) { | 331 | static const char *decl_name(const Decl *decl) { |
| 328 | const NamedDecl *named_decl = static_cast<const NamedDecl *>(decl); | 332 | const NamedDecl *named_decl = static_cast<const NamedDecl *>(decl); |
| 329 | return (const char *)named_decl->getName().bytes_begin(); | 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,6 +343,44 @@ static AstNode *trans_create_node_apint(Context *c, const llvm::APSInt &aps_int) |
| 339 | | 343 | |
| 340 | static AstNode *trans_qual_type(Context *c, QualType qt, const SourceLocation &source_loc); | 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 | static bool is_c_void_type(AstNode *node) { | 384 | static bool is_c_void_type(AstNode *node) { |
| 343 | return (node->type == NodeTypeSymbol && buf_eql_str(node->data.symbol_expr.symbol, "c_void")); | 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,7 +1377,11 @@ static AstNode *trans_implicit_cast_expr(Context *c, AstNode *block, ImplicitCas |
| 1335 | if (target_node == nullptr) | 1377 | if (target_node == nullptr) |
| 1336 | return nullptr; | 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 | AstNode *node = trans_create_node_builtin_fn_call_str(c, "ptrCast"); | 1386 | AstNode *node = trans_create_node_builtin_fn_call_str(c, "ptrCast"); |
| 1341 | node->data.fn_call_expr.params.append(dest_type_node); | 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,6 +2172,24 @@ static AstNode *trans_do_loop(Context *c, AstNode *block, DoStmt *stmt) { |
| 2126 | return while_node; | 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 | static AstNode *trans_stmt(Context *c, bool result_used, AstNode *block, Stmt *stmt, TransLRValue lrvalue) { | 2193 | static AstNode *trans_stmt(Context *c, bool result_used, AstNode *block, Stmt *stmt, TransLRValue lrvalue) { |
| 2130 | Stmt::StmtClass sc = stmt->getStmtClass(); | 2194 | Stmt::StmtClass sc = stmt->getStmtClass(); |
| 2131 | switch (sc) { | 2195 | switch (sc) { |
| ... | @@ -2167,6 +2231,8 @@ static AstNode *trans_stmt(Context *c, bool result_used, AstNode *block, Stmt *s | ... | @@ -2167,6 +2231,8 @@ static AstNode *trans_stmt(Context *c, bool result_used, AstNode *block, Stmt *s |
| 2167 | return trans_unary_expr_or_type_trait_expr(c, block, (UnaryExprOrTypeTraitExpr *)stmt); | 2231 | return trans_unary_expr_or_type_trait_expr(c, block, (UnaryExprOrTypeTraitExpr *)stmt); |
| 2168 | case Stmt::DoStmtClass: | 2232 | case Stmt::DoStmtClass: |
| 2169 | return trans_do_loop(c, block, (DoStmt *)stmt); | 2233 | return trans_do_loop(c, block, (DoStmt *)stmt); |
| | 2234 | case Stmt::StringLiteralClass: |
| | 2235 | return trans_string_literal(c, block, (StringLiteral *)stmt); |
| 2170 | case Stmt::CaseStmtClass: | 2236 | case Stmt::CaseStmtClass: |
| 2171 | emit_warning(c, stmt->getLocStart(), "TODO handle C CaseStmtClass"); | 2237 | emit_warning(c, stmt->getLocStart(), "TODO handle C CaseStmtClass"); |
| 2172 | return nullptr; | 2238 | return nullptr; |
| ... | @@ -2488,9 +2554,6 @@ static AstNode *trans_stmt(Context *c, bool result_used, AstNode *block, Stmt *s | ... | @@ -2488,9 +2554,6 @@ static AstNode *trans_stmt(Context *c, bool result_used, AstNode *block, Stmt *s |
| 2488 | case Stmt::StmtExprClass: | 2554 | case Stmt::StmtExprClass: |
| 2489 | emit_warning(c, stmt->getLocStart(), "TODO handle C StmtExprClass"); | 2555 | emit_warning(c, stmt->getLocStart(), "TODO handle C StmtExprClass"); |
| 2490 | return nullptr; | 2556 | return nullptr; |
| 2491 | case Stmt::StringLiteralClass: | | |
| 2492 | emit_warning(c, stmt->getLocStart(), "TODO handle C StringLiteralClass"); | | |
| 2493 | return nullptr; | | |
| 2494 | case Stmt::SubstNonTypeTemplateParmExprClass: | 2557 | case Stmt::SubstNonTypeTemplateParmExprClass: |
| 2495 | emit_warning(c, stmt->getLocStart(), "TODO handle C SubstNonTypeTemplateParmExprClass"); | 2558 | emit_warning(c, stmt->getLocStart(), "TODO handle C SubstNonTypeTemplateParmExprClass"); |
| 2496 | return nullptr; | 2559 | return nullptr; |
| ... | @@ -3530,7 +3593,7 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const ch | ... | @@ -3530,7 +3593,7 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const ch |
| 3530 | break; | 3593 | break; |
| 3531 | } | 3594 | } |
| 3532 | StringRef msg_str_ref = it->getMessage(); | 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 | FullSourceLoc fsl = it->getLocation(); | 3597 | FullSourceLoc fsl = it->getLocation(); |
| 3535 | if (fsl.hasManager()) { | 3598 | if (fsl.hasManager()) { |
| 3536 | FileID file_id = fsl.getFileID(); | 3599 | FileID file_id = fsl.getFileID(); |
| ... | @@ -3543,7 +3606,7 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const ch | ... | @@ -3543,7 +3606,7 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const ch |
| 3543 | if (filename.empty()) { | 3606 | if (filename.empty()) { |
| 3544 | path = buf_alloc(); | 3607 | path = buf_alloc(); |
| 3545 | } else { | 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 | ErrorMsg *err_msg = err_msg_create_with_offset(path, line, column, offset, source, msg); | 3612 | ErrorMsg *err_msg = err_msg_create_with_offset(path, line, column, offset, source, msg); |