translate-c supports string literals
parent
68312afcdf
commit
40480c7cdc
|
@ -324,6 +324,10 @@ static AstNode *add_global_var(Context *c, Buf *var_name, AstNode *value_node) {
|
|||
return node;
|
||||
}
|
||||
|
||||
static Buf *string_ref_to_buf(StringRef string_ref) {
|
||||
return buf_create_from_mem((const char *)string_ref.bytes_begin(), string_ref.size());
|
||||
}
|
||||
|
||||
static const char *decl_name(const Decl *decl) {
|
||||
const NamedDecl *named_decl = static_cast<const NamedDecl *>(decl);
|
||||
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)
|
|||
|
||||
static AstNode *trans_qual_type(Context *c, QualType qt, const SourceLocation &source_loc);
|
||||
|
||||
static QualType get_expr_qual_type(Context *c, const Expr *expr) {
|
||||
// String literals in C are `char *` but they should really be `const char *`.
|
||||
if (expr->getStmtClass() == Stmt::ImplicitCastExprClass) {
|
||||
const ImplicitCastExpr *cast_expr = static_cast<const ImplicitCastExpr *>(expr);
|
||||
if (cast_expr->getCastKind() == CK_ArrayToPointerDecay) {
|
||||
const Expr *sub_expr = cast_expr->getSubExpr();
|
||||
if (sub_expr->getStmtClass() == Stmt::StringLiteralClass) {
|
||||
QualType array_qt = sub_expr->getType();
|
||||
const ArrayType *array_type = static_cast<const ArrayType *>(array_qt.getTypePtr());
|
||||
QualType pointee_qt = array_type->getElementType();
|
||||
pointee_qt.addConst();
|
||||
return c->ctx->getPointerType(pointee_qt);
|
||||
}
|
||||
}
|
||||
}
|
||||
return expr->getType();
|
||||
}
|
||||
|
||||
static AstNode *get_expr_type(Context *c, const Expr *expr) {
|
||||
return trans_qual_type(c, get_expr_qual_type(c, expr), expr->getLocStart());
|
||||
}
|
||||
|
||||
static bool expr_types_equal(Context *c, const Expr *expr1, const Expr *expr2) {
|
||||
QualType t1 = get_expr_qual_type(c, expr1);
|
||||
QualType t2 = get_expr_qual_type(c, expr2);
|
||||
|
||||
if (t1.isConstQualified() != t2.isConstQualified()) {
|
||||
return false;
|
||||
}
|
||||
if (t1.isVolatileQualified() != t2.isVolatileQualified()) {
|
||||
return false;
|
||||
}
|
||||
if (t1.isRestrictQualified() != t2.isRestrictQualified()) {
|
||||
return false;
|
||||
}
|
||||
return t1.getTypePtr() == t2.getTypePtr();
|
||||
}
|
||||
|
||||
static bool is_c_void_type(AstNode *node) {
|
||||
return (node->type == NodeTypeSymbol && buf_eql_str(node->data.symbol_expr.symbol, "c_void"));
|
||||
}
|
||||
|
@ -1335,7 +1377,11 @@ static AstNode *trans_implicit_cast_expr(Context *c, AstNode *block, ImplicitCas
|
|||
if (target_node == nullptr)
|
||||
return nullptr;
|
||||
|
||||
AstNode *dest_type_node = trans_qual_type(c, stmt->getType(), stmt->getLocStart());
|
||||
if (expr_types_equal(c, stmt, stmt->getSubExpr())) {
|
||||
return target_node;
|
||||
}
|
||||
|
||||
AstNode *dest_type_node = get_expr_type(c, stmt);
|
||||
|
||||
AstNode *node = trans_create_node_builtin_fn_call_str(c, "ptrCast");
|
||||
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) {
|
|||
return while_node;
|
||||
}
|
||||
|
||||
static AstNode *trans_string_literal(Context *c, AstNode *block, StringLiteral *stmt) {
|
||||
switch (stmt->getKind()) {
|
||||
case StringLiteral::Ascii:
|
||||
case StringLiteral::UTF8:
|
||||
return trans_create_node_str_lit_c(c, string_ref_to_buf(stmt->getString()));
|
||||
case StringLiteral::UTF16:
|
||||
emit_warning(c, stmt->getLocStart(), "TODO support UTF16 string literals");
|
||||
return nullptr;
|
||||
case StringLiteral::UTF32:
|
||||
emit_warning(c, stmt->getLocStart(), "TODO support UTF32 string literals");
|
||||
return nullptr;
|
||||
case StringLiteral::Wide:
|
||||
emit_warning(c, stmt->getLocStart(), "TODO support wide string literals");
|
||||
return nullptr;
|
||||
}
|
||||
zig_unreachable();
|
||||
}
|
||||
|
||||
static AstNode *trans_stmt(Context *c, bool result_used, AstNode *block, Stmt *stmt, TransLRValue lrvalue) {
|
||||
Stmt::StmtClass sc = stmt->getStmtClass();
|
||||
switch (sc) {
|
||||
|
@ -2167,6 +2231,8 @@ static AstNode *trans_stmt(Context *c, bool result_used, AstNode *block, Stmt *s
|
|||
return trans_unary_expr_or_type_trait_expr(c, block, (UnaryExprOrTypeTraitExpr *)stmt);
|
||||
case Stmt::DoStmtClass:
|
||||
return trans_do_loop(c, block, (DoStmt *)stmt);
|
||||
case Stmt::StringLiteralClass:
|
||||
return trans_string_literal(c, block, (StringLiteral *)stmt);
|
||||
case Stmt::CaseStmtClass:
|
||||
emit_warning(c, stmt->getLocStart(), "TODO handle C CaseStmtClass");
|
||||
return nullptr;
|
||||
|
@ -2488,9 +2554,6 @@ static AstNode *trans_stmt(Context *c, bool result_used, AstNode *block, Stmt *s
|
|||
case Stmt::StmtExprClass:
|
||||
emit_warning(c, stmt->getLocStart(), "TODO handle C StmtExprClass");
|
||||
return nullptr;
|
||||
case Stmt::StringLiteralClass:
|
||||
emit_warning(c, stmt->getLocStart(), "TODO handle C StringLiteralClass");
|
||||
return nullptr;
|
||||
case Stmt::SubstNonTypeTemplateParmExprClass:
|
||||
emit_warning(c, stmt->getLocStart(), "TODO handle C SubstNonTypeTemplateParmExprClass");
|
||||
return nullptr;
|
||||
|
@ -3530,7 +3593,7 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const ch
|
|||
break;
|
||||
}
|
||||
StringRef msg_str_ref = it->getMessage();
|
||||
Buf *msg = buf_create_from_str((const char *)msg_str_ref.bytes_begin());
|
||||
Buf *msg = string_ref_to_buf(msg_str_ref);
|
||||
FullSourceLoc fsl = it->getLocation();
|
||||
if (fsl.hasManager()) {
|
||||
FileID file_id = fsl.getFileID();
|
||||
|
@ -3543,7 +3606,7 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const ch
|
|||
if (filename.empty()) {
|
||||
path = buf_alloc();
|
||||
} else {
|
||||
path = buf_create_from_mem((const char *)filename.bytes_begin(), filename.size());
|
||||
path = string_ref_to_buf(filename);
|
||||
}
|
||||
|
||||
ErrorMsg *err_msg = err_msg_create_with_offset(path, line, column, offset, source, msg);
|
||||
|
|
|
@ -929,6 +929,16 @@ pub fn addCases(cases: &tests.TranslateCContext) {
|
|||
\\ return *(??ptr);
|
||||
\\}
|
||||
);
|
||||
|
||||
cases.add("string literal",
|
||||
\\const char *foo(void) {
|
||||
\\ return "bar";
|
||||
\\}
|
||||
,
|
||||
\\pub fn foo() -> ?&const u8 {
|
||||
\\ return c"bar";
|
||||
\\}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue