aboutsummaryrefslogtreecommitdiff
path: root/src/parseh.cpp
diff options
context:
space:
mode:
authorAndrew Kelley <superjoe30@gmail.com>2017-09-05 18:51:48 -0400
committerAndrew Kelley <superjoe30@gmail.com>2017-09-05 18:51:48 -0400
commit48c44615a4f03c105a8053db552320d26482436a (patch)
treea2fa30353c38f068ec5510b38ff3e4bb8df30477 /src/parseh.cpp
parent1449e71de87891757b35302a73f9f1ad03429030 (diff)
parent3ff465e2883b556cd08afc08b0a2098255314d4a (diff)
downloadzig-48c44615a4f03c105a8053db552320d26482436a.tar.gz
zig-48c44615a4f03c105a8053db552320d26482436a.zip
Merge branch 'c-to-zig'
Diffstat (limited to 'src/parseh.cpp')
-rw-r--r--src/parseh.cpp2207
1 files changed, 1571 insertions, 636 deletions
diff --git a/src/parseh.cpp b/src/parseh.cpp
index 9acbc7c57c..f7e0b909c7 100644
--- a/src/parseh.cpp
+++ b/src/parseh.cpp
@@ -15,8 +15,10 @@
#include "parseh.hpp"
#include "parser.hpp"
+
#include <clang/Frontend/ASTUnit.h>
#include <clang/Frontend/CompilerInstance.h>
+#include <clang/AST/Expr.h>
#include <string.h>
@@ -27,14 +29,9 @@ struct MacroSymbol {
Buf *value;
};
-struct GlobalValue {
- TypeTableEntry *type;
- bool is_const;
-};
-
struct Alias {
- Buf *name;
- Tld *tld;
+ Buf *new_name;
+ Buf *canon_name;
};
struct Context {
@@ -42,30 +39,27 @@ struct Context {
ZigList<ErrorMsg *> *errors;
bool warnings_on;
VisibMod visib_mod;
- HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> global_type_table;
- HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> struct_type_table;
- HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> enum_type_table;
- HashMap<const void *, TypeTableEntry *, ptr_hash, ptr_eq> decl_table;
- HashMap<Buf *, Tld *, buf_hash, buf_eql_buf> macro_table;
+ AstNode *root;
+ HashMap<const void *, AstNode *, ptr_hash, ptr_eq> decl_table;
+ HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> macro_table;
SourceManager *source_manager;
ZigList<Alias> aliases;
ZigList<MacroSymbol> macro_symbols;
AstNode *source_node;
- uint32_t next_anon_index;
CodeGen *codegen;
+ ASTContext *ctx;
};
-static TypeTableEntry *resolve_qual_type_with_table(Context *c, QualType qt, const Decl *decl,
- HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> *type_table);
-
-static TypeTableEntry *resolve_qual_type(Context *c, QualType qt, const Decl *decl);
-static TypeTableEntry *resolve_record_decl(Context *c, const RecordDecl *record_decl);
-static TypeTableEntry *resolve_enum_decl(Context *c, const EnumDecl *enum_decl);
+static AstNode *resolve_record_decl(Context *c, const RecordDecl *record_decl);
+static AstNode *resolve_enum_decl(Context *c, const EnumDecl *enum_decl);
+static AstNode *resolve_typedef_decl(Context *c, const TypedefNameDecl *typedef_decl);
+static AstNode *trans_qual_type_with_table(Context *c, QualType qt, const SourceLocation &source_loc);
+static AstNode *trans_qual_type(Context *c, QualType qt, const SourceLocation &source_loc);
__attribute__ ((format (printf, 3, 4)))
-static void emit_warning(Context *c, const Decl *decl, const char *format, ...) {
+static void emit_warning(Context *c, const SourceLocation &sl, const char *format, ...) {
if (!c->warnings_on) {
return;
}
@@ -75,8 +69,6 @@ static void emit_warning(Context *c, const Decl *decl, const char *format, ...)
Buf *msg = buf_vprintf(format, ap);
va_end(ap);
- SourceLocation sl = decl->getLocation();
-
StringRef filename = c->source_manager->getFilename(sl);
const char *filename_bytes = (const char *)filename.bytes_begin();
Buf *path;
@@ -90,141 +82,214 @@ static void emit_warning(Context *c, const Decl *decl, const char *format, ...)
fprintf(stderr, "%s:%u:%u: warning: %s\n", buf_ptr(path), line, column, buf_ptr(msg));
}
-static uint32_t get_next_anon_index(Context *c) {
- uint32_t result = c->next_anon_index;
- c->next_anon_index += 1;
- return result;
+static void add_global_weak_alias(Context *c, Buf *new_name, Buf *canon_name) {
+ Alias *alias = c->aliases.add_one();
+ alias->new_name = new_name;
+ alias->canon_name = canon_name;
}
-static void add_global_alias(Context *c, Buf *name, Tld *tld) {
- c->import->decls_scope->decl_table.put(name, tld);
+static AstNode * trans_create_node(Context *c, NodeType id) {
+ AstNode *node = allocate<AstNode>(1);
+ node->type = id;
+ node->owner = c->import;
+ // TODO line/column. mapping to C file??
+ return node;
}
-static void add_global_weak_alias(Context *c, Buf *name, Tld *tld) {
- Alias *alias = c->aliases.add_one();
- alias->name = name;
- alias->tld = tld;
+static AstNode *trans_create_node_float_lit(Context *c, double value) {
+ AstNode *node = trans_create_node(c, NodeTypeFloatLiteral);
+ node->data.float_literal.bigfloat = allocate<BigFloat>(1);
+ bigfloat_init_64(node->data.float_literal.bigfloat, value);
+ return node;
}
-static void add_global(Context *c, Tld *tld) {
- return add_global_alias(c, tld->name, tld);
+static AstNode *trans_create_node_symbol(Context *c, Buf *name) {
+ AstNode *node = trans_create_node(c, NodeTypeSymbol);
+ node->data.symbol_expr.symbol = name;
+ return node;
}
-static Tld *get_global(Context *c, Buf *name) {
- {
- auto entry = c->import->decls_scope->decl_table.maybe_get(name);
- if (entry)
- return entry->value;
- }
- {
- auto entry = c->macro_table.maybe_get(name);
- if (entry)
- return entry->value;
- }
- return nullptr;
+static AstNode *trans_create_node_symbol_str(Context *c, const char *name) {
+ return trans_create_node_symbol(c, buf_create_from_str(name));
}
-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();
+static AstNode *trans_create_node_builtin_fn_call(Context *c, Buf *name) {
+ AstNode *node = trans_create_node(c, NodeTypeFnCallExpr);
+ node->data.fn_call_expr.fn_ref_expr = trans_create_node_symbol(c, name);
+ node->data.fn_call_expr.is_builtin = true;
+ return node;
}
-static void parseh_init_tld(Context *c, Tld *tld, TldId id, Buf *name) {
- init_tld(tld, id, name, c->visib_mod, c->source_node, &c->import->decls_scope->base);
- tld->resolution = TldResolutionOk;
- tld->import = c->import;
+static AstNode *trans_create_node_builtin_fn_call_str(Context *c, const char *name) {
+ return trans_create_node_builtin_fn_call(c, buf_create_from_str(name));
}
-static Tld *create_inline_fn_tld(Context *c, Buf *fn_name, TldVar *tld_var) {
- TldFn *tld_fn = allocate<TldFn>(1);
- parseh_init_tld(c, &tld_fn->base, TldIdFn, fn_name);
- tld_fn->fn_entry = ir_create_inline_fn(c->codegen, fn_name, tld_var->var, &c->import->decls_scope->base);
- return &tld_fn->base;
+static AstNode *trans_create_node_opaque(Context *c) {
+ return trans_create_node_builtin_fn_call_str(c, "OpaqueType");
}
-static TldVar *create_global_var(Context *c, Buf *name, ConstExprValue *var_value, bool is_const) {
- auto entry = c->import->decls_scope->decl_table.maybe_get(name);
- if (entry) {
- Tld *existing_tld = entry->value;
- assert(existing_tld->id == TldIdVar);
- return (TldVar *)existing_tld;
- }
- TldVar *tld_var = allocate<TldVar>(1);
- parseh_init_tld(c, &tld_var->base, TldIdVar, name);
- tld_var->var = add_variable(c->codegen, c->source_node, &c->import->decls_scope->base,
- name, is_const, var_value, &tld_var->base);
- c->codegen->global_vars.append(tld_var);
- return tld_var;
+static AstNode *trans_create_node_field_access(Context *c, AstNode *container, Buf *field_name) {
+ AstNode *node = trans_create_node(c, NodeTypeFieldAccessExpr);
+ node->data.field_access_expr.struct_expr = container;
+ node->data.field_access_expr.field_name = field_name;
+ return node;
}
-static Tld *create_global_str_lit_var(Context *c, Buf *name, Buf *value) {
- TldVar *tld_var = create_global_var(c, name, create_const_c_str_lit(c->codegen, value), true);
- return &tld_var->base;
+static AstNode *trans_create_node_prefix_op(Context *c, PrefixOp op, AstNode *child_node) {
+ AstNode *node = trans_create_node(c, NodeTypePrefixOpExpr);
+ node->data.prefix_op_expr.prefix_op = op;
+ node->data.prefix_op_expr.primary_expr = child_node;
+ return node;
}
-static Tld *create_global_num_lit_unsigned_negative_type(Context *c, Buf *name, uint64_t x, bool negative, TypeTableEntry *type_entry) {
- ConstExprValue *var_val = create_const_unsigned_negative(type_entry, x, negative);
- TldVar *tld_var = create_global_var(c, name, var_val, true);
- return &tld_var->base;
+static AstNode *trans_create_node_addr_of(Context *c, bool is_const, bool is_volatile, AstNode *child_node) {
+ AstNode *node = trans_create_node(c, NodeTypeAddrOfExpr);
+ node->data.addr_of_expr.is_const = is_const;
+ node->data.addr_of_expr.is_volatile = is_volatile;
+ node->data.addr_of_expr.op_expr = child_node;
+ return node;
}
-static Tld *create_global_num_lit_unsigned_negative(Context *c, Buf *name, uint64_t x, bool negative) {
- return create_global_num_lit_unsigned_negative_type(c, name, x, negative, c->codegen->builtin_types.entry_num_lit_int);
+static AstNode *trans_create_node_str_lit_c(Context *c, Buf *buf) {
+ AstNode *node = trans_create_node(c, NodeTypeStringLiteral);
+ node->data.string_literal.buf = buf;
+ node->data.string_literal.c = true;
+ return node;
}
-static Tld *create_global_num_lit_float(Context *c, Buf *name, double value) {
- ConstExprValue *var_val = create_const_float(c->codegen->builtin_types.entry_num_lit_float, value);
- TldVar *tld_var = create_global_var(c, name, var_val, true);
- return &tld_var->base;
+static AstNode *trans_create_node_unsigned_negative(Context *c, uint64_t x, bool is_negative) {
+ AstNode *node = trans_create_node(c, NodeTypeIntLiteral);
+ node->data.int_literal.bigint = allocate<BigInt>(1);
+ bigint_init_data(node->data.int_literal.bigint, &x, 1, is_negative);
+ return node;
}
-static ConstExprValue *create_const_int_ap(Context *c, TypeTableEntry *type, const Decl *source_decl,
- const llvm::APSInt &aps_int)
+static AstNode *trans_create_node_unsigned(Context *c, uint64_t x) {
+ return trans_create_node_unsigned_negative(c, x, false);
+}
+
+static AstNode *trans_create_node_cast(Context *c, AstNode *dest, AstNode *src) {
+ AstNode *node = trans_create_node(c, NodeTypeFnCallExpr);
+ node->data.fn_call_expr.fn_ref_expr = dest;
+ node->data.fn_call_expr.params.resize(1);
+ node->data.fn_call_expr.params.items[0] = src;
+ return node;
+}
+
+static AstNode *trans_create_node_unsigned_negative_type(Context *c, uint64_t x, bool is_negative,
+ const char *type_name)
{
- if (aps_int.isSigned()) {
- if (aps_int > INT64_MAX || aps_int < INT64_MIN) {
- emit_warning(c, source_decl, "integer overflow\n");
- return nullptr;
- } else {
- return create_const_signed(type, aps_int.getExtValue());
- }
- } else {
- if (aps_int > INT64_MAX) {
- emit_warning(c, source_decl, "integer overflow\n");
- return nullptr;
- } else {
- return create_const_unsigned_negative(type, aps_int.getExtValue(), false);
- }
- }
+ AstNode *lit_node = trans_create_node_unsigned_negative(c, x, is_negative);
+ return trans_create_node_cast(c, trans_create_node_symbol_str(c, type_name), lit_node);
}
-static Tld *create_global_num_lit_ap(Context *c, const Decl *source_decl, Buf *name,
- const llvm::APSInt &aps_int)
+static AstNode *trans_create_node_array_type(Context *c, AstNode *size_node, AstNode *child_type_node) {
+ AstNode *node = trans_create_node(c, NodeTypeArrayType);
+ node->data.array_type.size = size_node;
+ node->data.array_type.child_type = child_type_node;
+ return node;
+}
+
+static AstNode *trans_create_node_var_decl(Context *c, bool is_const, Buf *var_name, AstNode *type_node,
+ AstNode *init_node)
{
- ConstExprValue *const_value = create_const_int_ap(c, c->codegen->builtin_types.entry_num_lit_int,
- source_decl, aps_int);
- if (!const_value)
- return nullptr;
- TldVar *tld_var = create_global_var(c, name, const_value, true);
- return &tld_var->base;
+ AstNode *node = trans_create_node(c, NodeTypeVariableDeclaration);
+ node->data.variable_declaration.visib_mod = c->visib_mod;
+ node->data.variable_declaration.symbol = var_name;
+ node->data.variable_declaration.is_const = is_const;
+ node->data.variable_declaration.type = type_node;
+ node->data.variable_declaration.expr = init_node;
+ return node;
}
-static Tld *add_const_type(Context *c, Buf *name, TypeTableEntry *type_entry) {
- ConstExprValue *var_value = create_const_type(c->codegen, type_entry);
- TldVar *tld_var = create_global_var(c, name, var_value, true);
- add_global(c, &tld_var->base);
+static AstNode *trans_create_node_inline_fn(Context *c, Buf *fn_name, Buf *var_name, AstNode *src_proto_node) {
+ AstNode *fn_def = trans_create_node(c, NodeTypeFnDef);
+ AstNode *fn_proto = trans_create_node(c, NodeTypeFnProto);
+ fn_proto->data.fn_proto.visib_mod = c->visib_mod;
+ fn_proto->data.fn_proto.name = fn_name;
+ fn_proto->data.fn_proto.is_inline = true;
+ fn_proto->data.fn_proto.return_type = src_proto_node->data.fn_proto.return_type; // TODO ok for these to alias?
+
+ fn_def->data.fn_def.fn_proto = fn_proto;
+ fn_proto->data.fn_proto.fn_def_node = fn_def;
+
+ AstNode *unwrap_node = trans_create_node_prefix_op(c, PrefixOpUnwrapMaybe, trans_create_node_symbol(c, var_name));
+ AstNode *fn_call_node = trans_create_node(c, NodeTypeFnCallExpr);
+ fn_call_node->data.fn_call_expr.fn_ref_expr = unwrap_node;
+
+ for (size_t i = 0; i < src_proto_node->data.fn_proto.params.length; i += 1) {
+ AstNode *src_param_node = src_proto_node->data.fn_proto.params.at(i);
+ Buf *param_name = src_param_node->data.param_decl.name;
+ if (!param_name) param_name = buf_sprintf("arg%" ZIG_PRI_usize "", i);
+
+ AstNode *dest_param_node = trans_create_node(c, NodeTypeParamDecl);
+ dest_param_node->data.param_decl.name = param_name;
+ dest_param_node->data.param_decl.type = src_param_node->data.param_decl.type;
+ dest_param_node->data.param_decl.is_noalias = src_param_node->data.param_decl.is_noalias;
+ fn_proto->data.fn_proto.params.append(dest_param_node);
+
+ fn_call_node->data.fn_call_expr.params.append(trans_create_node_symbol(c, param_name));
+
+ }
+
+ AstNode *block = trans_create_node(c, NodeTypeBlock);
+ block->data.block.statements.resize(1);
+ block->data.block.statements.items[0] = fn_call_node;
+ block->data.block.last_statement_is_result_expression = true;
+
+ fn_def->data.fn_def.body = block;
+ return fn_def;
+}
+
+static AstNode *get_global(Context *c, Buf *name) {
+ for (size_t i = 0; i < c->root->data.root.top_level_decls.length; i += 1) {
+ AstNode *decl_node = c->root->data.root.top_level_decls.items[i];
+ if (decl_node->type == NodeTypeVariableDeclaration) {
+ if (buf_eql_buf(decl_node->data.variable_declaration.symbol, name)) {
+ return decl_node;
+ }
+ } else if (decl_node->type == NodeTypeFnDef) {
+ if (buf_eql_buf(decl_node->data.fn_def.fn_proto->data.fn_proto.name, name)) {
+ return decl_node;
+ }
+ } else if (decl_node->type == NodeTypeFnProto) {
+ if (buf_eql_buf(decl_node->data.fn_proto.name, name)) {
+ return decl_node;
+ }
+ }
+ }
+ {
+ auto entry = c->macro_table.maybe_get(name);
+ if (entry)
+ return entry->value;
+ }
+ return nullptr;
+}
+
+static AstNode *add_global_var(Context *c, Buf *var_name, AstNode *value_node) {
+ bool is_const = true;
+ AstNode *type_node = nullptr;
+ AstNode *node = trans_create_node_var_decl(c, is_const, var_name, type_node, value_node);
+ c->root->data.root.top_level_decls.append(node);
+ return node;
+}
- c->global_type_table.put(name, type_entry);
- return &tld_var->base;
+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();
}
-static Tld *add_container_tld(Context *c, TypeTableEntry *type_entry) {
- return add_const_type(c, &type_entry->name, type_entry);
+static AstNode *trans_create_node_apint(Context *c, const llvm::APSInt &aps_int) {
+ AstNode *node = trans_create_node(c, NodeTypeIntLiteral);
+ node->data.int_literal.bigint = allocate<BigInt>(1);
+ bigint_init_data(node->data.int_literal.bigint, aps_int.getRawData(), aps_int.getNumWords(), aps_int.isNegative());
+ return node;
+
}
-static bool is_c_void_type(Context *c, TypeTableEntry *type_entry) {
- return (type_entry == c->codegen->builtin_types.entry_c_void);
+static bool is_c_void_type(AstNode *node) {
+ return (node->type == NodeTypeSymbol && buf_eql_str(node->data.symbol_expr.symbol, "c_void"));
}
static bool qual_type_child_is_fn_proto(const QualType &qt) {
@@ -240,52 +305,118 @@ static bool qual_type_child_is_fn_proto(const QualType &qt) {
return false;
}
-static TypeTableEntry *resolve_type_with_table(Context *c, const Type *ty, const Decl *decl,
- HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> *type_table)
-{
+static bool c_is_signed_integer(Context *c, QualType qt) {
+ const Type *c_type = qt.getTypePtr();
+ if (c_type->getTypeClass() != Type::Builtin)
+ return false;
+ const BuiltinType *builtin_ty = static_cast<const BuiltinType*>(c_type);
+ switch (builtin_ty->getKind()) {
+ case BuiltinType::SChar:
+ case BuiltinType::Short:
+ case BuiltinType::Int:
+ case BuiltinType::Long:
+ case BuiltinType::LongLong:
+ case BuiltinType::Int128:
+ case BuiltinType::WChar_S:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static bool c_is_unsigned_integer(Context *c, QualType qt) {
+ const Type *c_type = qt.getTypePtr();
+ if (c_type->getTypeClass() != Type::Builtin)
+ return false;
+ const BuiltinType *builtin_ty = static_cast<const BuiltinType*>(c_type);
+ switch (builtin_ty->getKind()) {
+ case BuiltinType::Char_U:
+ case BuiltinType::UChar:
+ case BuiltinType::Char_S:
+ case BuiltinType::UShort:
+ case BuiltinType::UInt:
+ case BuiltinType::ULong:
+ case BuiltinType::ULongLong:
+ case BuiltinType::UInt128:
+ case BuiltinType::WChar_U:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static bool c_is_float(Context *c, QualType qt) {
+ const Type *c_type = qt.getTypePtr();
+ if (c_type->getTypeClass() != Type::Builtin)
+ return false;
+ const BuiltinType *builtin_ty = static_cast<const BuiltinType*>(c_type);
+ switch (builtin_ty->getKind()) {
+ case BuiltinType::Half:
+ case BuiltinType::Float:
+ case BuiltinType::Double:
+ case BuiltinType::Float128:
+ case BuiltinType::LongDouble:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static AstNode * trans_stmt(Context *c, AstNode *block, Stmt *stmt);
+static AstNode * trans_qual_type(Context *c, QualType qt, const SourceLocation &source_loc);
+
+static AstNode * trans_expr(Context *c, AstNode *block, Expr *expr) {
+ return trans_stmt(c, block, expr);
+}
+
+static AstNode *trans_type_with_table(Context *c, const Type *ty, const SourceLocation &source_loc) {
switch (ty->getTypeClass()) {
case Type::Builtin:
{
const BuiltinType *builtin_ty = static_cast<const BuiltinType*>(ty);
switch (builtin_ty->getKind()) {
case BuiltinType::Void:
- return c->codegen->builtin_types.entry_c_void;
+ return trans_create_node_symbol_str(c, "c_void");
case BuiltinType::Bool:
- return c->codegen->builtin_types.entry_bool;
+ return trans_create_node_symbol_str(c, "bool");
case BuiltinType::Char_U:
case BuiltinType::UChar:
case BuiltinType::Char_S:
- return c->codegen->builtin_types.entry_u8;
+ return trans_create_node_symbol_str(c, "u8");
case BuiltinType::SChar:
- return c->codegen->builtin_types.entry_i8;
+ return trans_create_node_symbol_str(c, "i8");
case BuiltinType::UShort:
- return get_c_int_type(c->codegen, CIntTypeUShort);
+ return trans_create_node_symbol_str(c, "c_ushort");
case BuiltinType::UInt:
- return get_c_int_type(c->codegen, CIntTypeUInt);
+ return trans_create_node_symbol_str(c, "c_uint");
case BuiltinType::ULong:
- return get_c_int_type(c->codegen, CIntTypeULong);
+ return trans_create_node_symbol_str(c, "c_ulong");
case BuiltinType::ULongLong:
- return get_c_int_type(c->codegen, CIntTypeULongLong);
+ return trans_create_node_symbol_str(c, "c_ulonglong");
case BuiltinType::Short:
- return get_c_int_type(c->codegen, CIntTypeShort);
+ return trans_create_node_symbol_str(c, "c_short");
case BuiltinType::Int:
- return get_c_int_type(c->codegen, CIntTypeInt);
+ return trans_create_node_symbol_str(c, "c_int");
case BuiltinType::Long:
- return get_c_int_type(c->codegen, CIntTypeLong);
+ return trans_create_node_symbol_str(c, "c_long");
case BuiltinType::LongLong:
- return get_c_int_type(c->codegen, CIntTypeLongLong);
+ return trans_create_node_symbol_str(c, "c_longlong");
+ case BuiltinType::UInt128:
+ return trans_create_node_symbol_str(c, "u128");
+ case BuiltinType::Int128:
+ return trans_create_node_symbol_str(c, "i128");
case BuiltinType::Float:
- return c->codegen->builtin_types.entry_f32;
+ return trans_create_node_symbol_str(c, "f32");
case BuiltinType::Double:
- return c->codegen->builtin_types.entry_f64;
+ return trans_create_node_symbol_str(c, "f64");
+ case BuiltinType::Float128:
+ return trans_create_node_symbol_str(c, "f128");
case BuiltinType::LongDouble:
- return c->codegen->builtin_types.entry_c_longdouble;
+ return trans_create_node_symbol_str(c, "c_longdouble");
case BuiltinType::WChar_U:
case BuiltinType::Char16:
case BuiltinType::Char32:
- case BuiltinType::UInt128:
case BuiltinType::WChar_S:
- case BuiltinType::Int128:
case BuiltinType::Half:
case BuiltinType::NullPtr:
case BuiltinType::ObjCId:
@@ -336,14 +467,13 @@ static TypeTableEntry *resolve_type_with_table(Context *c, const Type *ty, const
case BuiltinType::OCLImage2dMSAADepthRW:
case BuiltinType::OCLImage2dArrayMSAADepthRW:
case BuiltinType::OCLImage3dRW:
- case BuiltinType::Float128:
case BuiltinType::OCLSampler:
case BuiltinType::OCLEvent:
case BuiltinType::OCLClkEvent:
case BuiltinType::OCLQueue:
case BuiltinType::OCLReserveID:
- emit_warning(c, decl, "missed a builtin type");
- return c->codegen->builtin_types.entry_invalid;
+ emit_warning(c, source_loc, "unsupported builtin type");
+ return nullptr;
}
break;
}
@@ -351,170 +481,150 @@ static TypeTableEntry *resolve_type_with_table(Context *c, const Type *ty, const
{
const PointerType *pointer_ty = static_cast<const PointerType*>(ty);
QualType child_qt = pointer_ty->getPointeeType();
- TypeTableEntry *child_type = resolve_qual_type(c, child_qt, decl);
- if (type_is_invalid(child_type)) {
- emit_warning(c, decl, "pointer to unresolved type");
- return c->codegen->builtin_types.entry_invalid;
+ AstNode *child_node = trans_qual_type(c, child_qt, source_loc);
+ if (child_node == nullptr) {
+ emit_warning(c, source_loc, "pointer to unsupported type");
+ return nullptr;
}
if (qual_type_child_is_fn_proto(child_qt)) {
- return get_maybe_type(c->codegen, child_type);
+ return trans_create_node_prefix_op(c, PrefixOpMaybe, child_node);
}
- bool is_const = child_qt.isConstQualified();
- TypeTableEntry *non_null_pointer_type = get_pointer_to_type(c->codegen, child_type, is_const);
- return get_maybe_type(c->codegen, non_null_pointer_type);
+ AstNode *pointer_node = trans_create_node_addr_of(c, child_qt.isConstQualified(),
+ child_qt.isVolatileQualified(), child_node);
+ return trans_create_node_prefix_op(c, PrefixOpMaybe, pointer_node);
}
case Type::Typedef:
{
const TypedefType *typedef_ty = static_cast<const TypedefType*>(ty);
const TypedefNameDecl *typedef_decl = typedef_ty->getDecl();
- Buf *type_name = buf_create_from_str(decl_name(typedef_decl));
- if (buf_eql_str(type_name, "uint8_t")) {
- return c->codegen->builtin_types.entry_u8;
- } else if (buf_eql_str(type_name, "int8_t")) {
- return c->codegen->builtin_types.entry_i8;
- } else if (buf_eql_str(type_name, "uint16_t")) {
- return c->codegen->builtin_types.entry_u16;
- } else if (buf_eql_str(type_name, "int16_t")) {
- return c->codegen->builtin_types.entry_i16;
- } else if (buf_eql_str(type_name, "uint32_t")) {
- return c->codegen->builtin_types.entry_u32;
- } else if (buf_eql_str(type_name, "int32_t")) {
- return c->codegen->builtin_types.entry_i32;
- } else if (buf_eql_str(type_name, "uint64_t")) {
- return c->codegen->builtin_types.entry_u64;
- } else if (buf_eql_str(type_name, "int64_t")) {
- return c->codegen->builtin_types.entry_i64;
- } else if (buf_eql_str(type_name, "intptr_t")) {
- return c->codegen->builtin_types.entry_isize;
- } else if (buf_eql_str(type_name, "uintptr_t")) {
- return c->codegen->builtin_types.entry_usize;
- } else {
- auto entry = type_table->maybe_get(type_name);
- if (entry) {
- if (type_is_invalid(entry->value)) {
- return c->codegen->builtin_types.entry_invalid;
- } else {
- return entry->value;
- }
- } else {
- return c->codegen->builtin_types.entry_invalid;
- }
- }
+ return resolve_typedef_decl(c, typedef_decl);
}
case Type::Elaborated:
{
const ElaboratedType *elaborated_ty = static_cast<const ElaboratedType*>(ty);
switch (elaborated_ty->getKeyword()) {
case ETK_Struct:
- return resolve_qual_type_with_table(c, elaborated_ty->getNamedType(),
- decl, &c->struct_type_table);
+ return trans_qual_type_with_table(c, elaborated_ty->getNamedType(), source_loc);
case ETK_Enum:
- return resolve_qual_type_with_table(c, elaborated_ty->getNamedType(),
- decl, &c->enum_type_table);
+ return trans_qual_type_with_table(c, elaborated_ty->getNamedType(), source_loc);
case ETK_Interface:
case ETK_Union:
case ETK_Class:
case ETK_Typename:
case ETK_None:
- emit_warning(c, decl, "unsupported elaborated type");
- return c->codegen->builtin_types.entry_invalid;
+ emit_warning(c, source_loc, "unsupported elaborated type");
+ return nullptr;
}
}
case Type::FunctionProto:
{
const FunctionProtoType *fn_proto_ty = static_cast<const FunctionProtoType*>(ty);
+ AstNode *proto_node = trans_create_node(c, NodeTypeFnProto);
switch (fn_proto_ty->getCallConv()) {
case CC_C: // __attribute__((cdecl))
+ proto_node->data.fn_proto.cc = CallingConventionC;
+ proto_node->data.fn_proto.is_extern = true;
break;
case CC_X86StdCall: // __attribute__((stdcall))
- emit_warning(c, decl, "function type has x86 stdcall calling convention");
- return c->codegen->builtin_types.entry_invalid;
+ proto_node->data.fn_proto.cc = CallingConventionStdcall;
+ break;
case CC_X86FastCall: // __attribute__((fastcall))
- emit_warning(c, decl, "function type has x86 fastcall calling convention");
- return c->codegen->builtin_types.entry_invalid;
+ emit_warning(c, source_loc, "unsupported calling convention: x86 fastcall");
+ return nullptr;
case CC_X86ThisCall: // __attribute__((thiscall))
- emit_warning(c, decl, "function type has x86 thiscall calling convention");
- return c->codegen->builtin_types.entry_invalid;
+ emit_warning(c, source_loc, "unsupported calling convention: x86 thiscall");
+ return nullptr;
case CC_X86VectorCall: // __attribute__((vectorcall))
- emit_warning(c, decl, "function type has x86 vectorcall calling convention");
- return c->codegen->builtin_types.entry_invalid;
+ emit_warning(c, source_loc, "unsupported calling convention: x86 vectorcall");
+ return nullptr;
case CC_X86Pascal: // __attribute__((pascal))
- emit_warning(c, decl, "function type has x86 pascal calling convention");
- return c->codegen->builtin_types.entry_invalid;
+ emit_warning(c, source_loc, "unsupported calling convention: x86 pascal");
+ return nullptr;
case CC_Win64: // __attribute__((ms_abi))
- emit_warning(c, decl, "function type has win64 calling convention");
- return c->codegen->builtin_types.entry_invalid;
+ emit_warning(c, source_loc, "unsupported calling convention: win64");
+ return nullptr;
case CC_X86_64SysV: // __attribute__((sysv_abi))
- emit_warning(c, decl, "function type has x86 64sysv calling convention");
- return c->codegen->builtin_types.entry_invalid;
+ emit_warning(c, source_loc, "unsupported calling convention: x86 64sysv");
+ return nullptr;
case CC_X86RegCall:
- emit_warning(c, decl, "function type has x86 reg calling convention");
- return c->codegen->builtin_types.entry_invalid;
+ emit_warning(c, source_loc, "unsupported calling convention: x86 reg");
+ return nullptr;
case CC_AAPCS: // __attribute__((pcs("aapcs")))
- emit_warning(c, decl, "function type has aapcs calling convention");
- return c->codegen->builtin_types.entry_invalid;
+ emit_warning(c, source_loc, "unsupported calling convention: aapcs");
+ return nullptr;
case CC_AAPCS_VFP: // __attribute__((pcs("aapcs-vfp")))
- emit_warning(c, decl, "function type has aapcs-vfp calling convention");
- return c->codegen->builtin_types.entry_invalid;
+ emit_warning(c, source_loc, "unsupported calling convention: aapcs-vfp");
+ return nullptr;
case CC_IntelOclBicc: // __attribute__((intel_ocl_bicc))
- emit_warning(c, decl, "function type has intel_ocl_bicc calling convention");
- return c->codegen->builtin_types.entry_invalid;
+ emit_warning(c, source_loc, "unsupported calling convention: intel_ocl_bicc");
+ return nullptr;
case CC_SpirFunction: // default for OpenCL functions on SPIR target
- emit_warning(c, decl, "function type has SPIR function calling convention");
- return c->codegen->builtin_types.entry_invalid;
+ emit_warning(c, source_loc, "unsupported calling convention: SPIR function");
+ return nullptr;
case CC_OpenCLKernel:
- emit_warning(c, decl, "function type has OpenCLKernel calling convention");
- return c->codegen->builtin_types.entry_invalid;
+ emit_warning(c, source_loc, "unsupported calling convention: OpenCLKernel");
+ return nullptr;
case CC_Swift:
- emit_warning(c, decl, "function type has Swift calling convention");
- return c->codegen->builtin_types.entry_invalid;
+ emit_warning(c, source_loc, "unsupported calling convention: Swift");
+ return nullptr;
case CC_PreserveMost:
- emit_warning(c, decl, "function type has PreserveMost calling convention");
- return c->codegen->builtin_types.entry_invalid;
+ emit_warning(c, source_loc, "unsupported calling convention: PreserveMost");
+ return nullptr;
case CC_PreserveAll:
- emit_warning(c, decl, "function type has PreserveAll calling convention");
- return c->codegen->builtin_types.entry_invalid;
+ emit_warning(c, source_loc, "unsupported calling convention: PreserveAll");
+ return nullptr;
}
- FnTypeId fn_type_id = {0};
- fn_type_id.cc = CallingConventionC;
- fn_type_id.is_var_args = fn_proto_ty->isVariadic();
- fn_type_id.param_count = fn_proto_ty->getNumParams();
-
+ proto_node->data.fn_proto.is_var_args = fn_proto_ty->isVariadic();
+ size_t param_count = fn_proto_ty->getNumParams();
if (fn_proto_ty->getNoReturnAttr()) {
- fn_type_id.return_type = c->codegen->builtin_types.entry_unreachable;
+ proto_node->data.fn_proto.return_type = trans_create_node_symbol_str(c, "noreturn");
} else {
- fn_type_id.return_type = resolve_qual_type(c, fn_proto_ty->getReturnType(), decl);
- if (type_is_invalid(fn_type_id.return_type)) {
- emit_warning(c, decl, "unresolved function proto return type");
- return c->codegen->builtin_types.entry_invalid;
+ proto_node->data.fn_proto.return_type = trans_qual_type(c, fn_proto_ty->getReturnType(),
+ source_loc);
+ if (proto_node->data.fn_proto.return_type == nullptr) {
+ emit_warning(c, source_loc, "unsupported function proto return type");
+ return nullptr;
}
// convert c_void to actual void (only for return type)
- if (is_c_void_type(c, fn_type_id.return_type)) {
- fn_type_id.return_type = c->codegen->builtin_types.entry_void;
+ if (is_c_void_type(proto_node->data.fn_proto.return_type)) {
+ proto_node->data.fn_proto.return_type = nullptr;
}
}
- fn_type_id.param_info = allocate_nonzero<FnTypeParamInfo>(fn_type_id.param_count);
- for (size_t i = 0; i < fn_type_id.param_count; i += 1) {
+ //emit_warning(c, source_loc, "TODO figure out fn prototype fn name");
+ const char *fn_name = nullptr;
+ if (fn_name != nullptr) {
+ proto_node->data.fn_proto.name = buf_create_from_str(fn_name);
+ }
+
+ for (size_t i = 0; i < param_count; i += 1) {
QualType qt = fn_proto_ty->getParamType(i);
- TypeTableEntry *param_type = resolve_qual_type(c, qt, decl);
+ AstNode *param_type_node = trans_qual_type(c, qt, source_loc);
- if (type_is_invalid(param_type)) {
- emit_warning(c, decl, "unresolved function proto parameter type");
- return c->codegen->builtin_types.entry_invalid;
+ if (param_type_node == nullptr) {
+ emit_warning(c, source_loc, "unresolved function proto parameter type");
+ return nullptr;
}
- FnTypeParamInfo *param_info = &fn_type_id.param_info[i];
- param_info->type = param_type;
- param_info->is_noalias = qt.isRestrictQualified();
+ AstNode *param_node = trans_create_node(c, NodeTypeParamDecl);
+ //emit_warning(c, source_loc, "TODO figure out fn prototype param name");
+ const char *param_name = nullptr;
+ if (param_name != nullptr) {
+ param_node->data.param_decl.name = buf_create_from_str(param_name);
+ }
+ param_node->data.param_decl.is_noalias = qt.isRestrictQualified();
+ param_node->data.param_decl.type = param_type_node;
+ proto_node->data.fn_proto.params.append(param_node);
}
+ // TODO check for always_inline attribute
+ // TODO check for align attribute
- return get_fn_type(c->codegen, &fn_type_id);
+ return proto_node;
}
case Type::Record:
{
@@ -529,28 +639,29 @@ static TypeTableEntry *resolve_type_with_table(Context *c, const Type *ty, const
case Type::ConstantArray:
{
const ConstantArrayType *const_arr_ty = static_cast<const ConstantArrayType *>(ty);
- TypeTableEntry *child_type = resolve_qual_type(c, const_arr_ty->getElementType(), decl);
- if (child_type->id == TypeTableEntryIdInvalid) {
- emit_warning(c, decl, "unresolved array element type");
- return child_type;
+ AstNode *child_type_node = trans_qual_type(c, const_arr_ty->getElementType(), source_loc);
+ if (child_type_node == nullptr) {
+ emit_warning(c, source_loc, "unresolved array element type");
+ return nullptr;
}
uint64_t size = const_arr_ty->getSize().getLimitedValue();
- return get_array_type(c->codegen, child_type, size);
+ AstNode *size_node = trans_create_node_unsigned(c, size);
+ return trans_create_node_array_type(c, size_node, child_type_node);
}
case Type::Paren:
{
const ParenType *paren_ty = static_cast<const ParenType *>(ty);
- return resolve_qual_type(c, paren_ty->getInnerType(), decl);
+ return trans_qual_type(c, paren_ty->getInnerType(), source_loc);
}
case Type::Decayed:
{
const DecayedType *decayed_ty = static_cast<const DecayedType *>(ty);
- return resolve_qual_type(c, decayed_ty->getDecayedType(), decl);
+ return trans_qual_type(c, decayed_ty->getDecayedType(), source_loc);
}
case Type::Attributed:
{
const AttributedType *attributed_ty = static_cast<const AttributedType *>(ty);
- return resolve_qual_type(c, attributed_ty->getEquivalentType(), decl);
+ return trans_qual_type(c, attributed_ty->getEquivalentType(), source_loc);
}
case Type::BlockPointer:
case Type::LValueReference:
@@ -586,20 +697,897 @@ static TypeTableEntry *resolve_type_with_table(Context *c, const Type *ty, const
case Type::Pipe:
case Type::ObjCTypeParam:
case Type::DeducedTemplateSpecialization:
- emit_warning(c, decl, "missed a '%s' type", ty->getTypeClassName());
- return c->codegen->builtin_types.entry_invalid;
+ emit_warning(c, source_loc, "unsupported type: '%s'", ty->getTypeClassName());
+ return nullptr;
}
zig_unreachable();
}
-static TypeTableEntry *resolve_qual_type_with_table(Context *c, QualType qt, const Decl *decl,
- HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> *type_table)
-{
- return resolve_type_with_table(c, qt.getTypePtr(), decl, type_table);
+static AstNode * trans_qual_type_with_table(Context *c, QualType qt, const SourceLocation &source_loc) {
+ return trans_type_with_table(c, qt.getTypePtr(), source_loc);
+}
+
+static AstNode * trans_qual_type(Context *c, QualType qt, const SourceLocation &source_loc) {
+ return trans_qual_type_with_table(c, qt, source_loc);
}
-static TypeTableEntry *resolve_qual_type(Context *c, QualType qt, const Decl *decl) {
- return resolve_qual_type_with_table(c, qt, decl, &c->global_type_table);
+static AstNode * trans_compound_stmt(Context *c, AstNode *parent, CompoundStmt *stmt) {
+ AstNode *child_block = trans_create_node(c, NodeTypeBlock);
+ for (CompoundStmt::body_iterator it = stmt->body_begin(), end_it = stmt->body_end(); it != end_it; ++it) {
+ AstNode *child_node = trans_stmt(c, child_block, *it);
+ if (child_node != nullptr)
+ child_block->data.block.statements.append(child_node);
+ }
+ return child_block;
+}
+
+static AstNode *trans_return_stmt(Context *c, AstNode *block, ReturnStmt *stmt) {
+ Expr *value_expr = stmt->getRetValue();
+ if (value_expr == nullptr) {
+ zig_panic("TODO handle C return void");
+ } else {
+ AstNode *return_node = trans_create_node(c, NodeTypeReturnExpr);
+ return_node->data.return_expr.expr = trans_expr(c, block, value_expr);
+ return return_node;
+ }
+}
+
+static AstNode *trans_integer_literal(Context *c, IntegerLiteral *stmt) {
+ llvm::APSInt result;
+ if (!stmt->EvaluateAsInt(result, *c->ctx)) {
+ zig_panic("TODO handle libclang unable to evaluate C integer literal");
+ }
+ return trans_create_node_apint(c, result);
+}
+
+static AstNode *trans_conditional_operator(Context *c, AstNode *block, ConditionalOperator *stmt) {
+ AstNode *node = trans_create_node(c, NodeTypeIfBoolExpr);
+
+ Expr *cond_expr = stmt->getCond();
+ Expr *true_expr = stmt->getTrueExpr();
+ Expr *false_expr = stmt->getFalseExpr();
+
+ node->data.if_bool_expr.condition = trans_expr(c, block, cond_expr);
+ node->data.if_bool_expr.then_block = trans_expr(c, block, true_expr);
+ node->data.if_bool_expr.else_node = trans_expr(c, block, false_expr);
+
+ return node;
+}
+
+static AstNode * trans_create_bin_op(Context *c, AstNode *block, Expr *lhs, BinOpType bin_op, Expr *rhs) {
+ AstNode *node = trans_create_node(c, NodeTypeBinOpExpr);
+ node->data.bin_op_expr.bin_op = bin_op;
+ node->data.bin_op_expr.op1 = trans_expr(c, block, lhs);
+ node->data.bin_op_expr.op2 = trans_expr(c, block, rhs);
+ return node;
+}
+
+static AstNode * trans_binary_operator(Context *c, AstNode *block, BinaryOperator *stmt) {
+ switch (stmt->getOpcode()) {
+ case BO_PtrMemD:
+ zig_panic("TODO handle more C binary operators: BO_PtrMemD");
+ case BO_PtrMemI:
+ zig_panic("TODO handle more C binary operators: BO_PtrMemI");
+ case BO_Mul:
+ zig_panic("TODO handle more C binary operators: BO_Mul");
+ case BO_Div:
+ zig_panic("TODO handle more C binary operators: BO_Div");
+ case BO_Rem:
+ zig_panic("TODO handle more C binary operators: BO_Rem");
+ case BO_Add:
+ zig_panic("TODO handle more C binary operators: BO_Add");
+ case BO_Sub:
+ zig_panic("TODO handle more C binary operators: BO_Sub");
+ case BO_Shl:
+ zig_panic("TODO handle more C binary operators: BO_Shl");
+ case BO_Shr:
+ zig_panic("TODO handle more C binary operators: BO_Shr");
+ case BO_LT:
+ return trans_create_bin_op(c, block, stmt->getLHS(), BinOpTypeCmpLessThan, stmt->getRHS());
+ case BO_GT:
+ return trans_create_bin_op(c, block, stmt->getLHS(), BinOpTypeCmpGreaterThan, stmt->getRHS());
+ case BO_LE:
+ return trans_create_bin_op(c, block, stmt->getLHS(), BinOpTypeCmpLessOrEq, stmt->getRHS());
+ case BO_GE:
+ return trans_create_bin_op(c, block, stmt->getLHS(), BinOpTypeCmpGreaterOrEq, stmt->getRHS());
+ case BO_EQ:
+ zig_panic("TODO handle more C binary operators: BO_EQ");
+ case BO_NE:
+ zig_panic("TODO handle more C binary operators: BO_NE");
+ case BO_And:
+ zig_panic("TODO handle more C binary operators: BO_And");
+ case BO_Xor:
+ zig_panic("TODO handle more C binary operators: BO_Xor");
+ case BO_Or:
+ zig_panic("TODO handle more C binary operators: BO_Or");
+ case BO_LAnd:
+ zig_panic("TODO handle more C binary operators: BO_LAnd");
+ case BO_LOr:
+ zig_panic("TODO handle more C binary operators: BO_LOr");
+ case BO_Assign:
+ zig_panic("TODO handle more C binary operators: BO_Assign");
+ case BO_MulAssign:
+ zig_panic("TODO handle more C binary operators: BO_MulAssign");
+ case BO_DivAssign:
+ zig_panic("TODO handle more C binary operators: BO_DivAssign");
+ case BO_RemAssign:
+ zig_panic("TODO handle more C binary operators: BO_RemAssign");
+ case BO_AddAssign:
+ zig_panic("TODO handle more C binary operators: BO_AddAssign");
+ case BO_SubAssign:
+ zig_panic("TODO handle more C binary operators: BO_SubAssign");
+ case BO_ShlAssign:
+ zig_panic("TODO handle more C binary operators: BO_ShlAssign");
+ case BO_ShrAssign:
+ zig_panic("TODO handle more C binary operators: BO_ShrAssign");
+ case BO_AndAssign:
+ zig_panic("TODO handle more C binary operators: BO_AndAssign");
+ case BO_XorAssign:
+ zig_panic("TODO handle more C binary operators: BO_XorAssign");
+ case BO_OrAssign:
+ zig_panic("TODO handle more C binary operators: BO_OrAssign");
+ case BO_Comma:
+ zig_panic("TODO handle more C binary operators: BO_Comma");
+ }
+
+ zig_unreachable();
+}
+
+static AstNode * trans_implicit_cast_expr(Context *c, AstNode *block, ImplicitCastExpr *stmt) {
+ switch (stmt->getCastKind()) {
+ case CK_LValueToRValue:
+ return trans_expr(c, block, stmt->getSubExpr());
+ case CK_IntegralCast:
+ {
+ AstNode *node = trans_create_node_builtin_fn_call_str(c, "bitCast");
+ node->data.fn_call_expr.params.append(trans_qual_type(c, stmt->getType(), stmt->getExprLoc()));
+ node->data.fn_call_expr.params.append(trans_expr(c, block, stmt->getSubExpr()));
+ return node;
+ }
+ case CK_Dependent:
+ zig_panic("TODO handle C translation cast CK_Dependent");
+ case CK_BitCast:
+ zig_panic("TODO handle C translation cast CK_BitCast");
+ case CK_LValueBitCast:
+ zig_panic("TODO handle C translation cast CK_LValueBitCast");
+ case CK_NoOp:
+ zig_panic("TODO handle C translation cast CK_NoOp");
+ case CK_BaseToDerived:
+ zig_panic("TODO handle C translation cast CK_BaseToDerived");
+ case CK_DerivedToBase:
+ zig_panic("TODO handle C translation cast CK_DerivedToBase");
+ case CK_UncheckedDerivedToBase:
+ zig_panic("TODO handle C translation cast CK_UncheckedDerivedToBase");
+ case CK_Dynamic:
+ zig_panic("TODO handle C translation cast CK_Dynamic");
+ case CK_ToUnion:
+ zig_panic("TODO handle C translation cast CK_ToUnion");
+ case CK_ArrayToPointerDecay:
+ zig_panic("TODO handle C translation cast CK_ArrayToPointerDecay");
+ case CK_FunctionToPointerDecay:
+ zig_panic("TODO handle C translation cast CK_FunctionToPointerDecay");
+ case CK_NullToPointer:
+ zig_panic("TODO handle C translation cast CK_NullToPointer");
+ case CK_NullToMemberPointer:
+ zig_panic("TODO handle C translation cast CK_NullToMemberPointer");
+ case CK_BaseToDerivedMemberPointer:
+ zig_panic("TODO handle C translation cast CK_BaseToDerivedMemberPointer");
+ case CK_DerivedToBaseMemberPointer:
+ zig_panic("TODO handle C translation cast CK_DerivedToBaseMemberPointer");
+ case CK_MemberPointerToBoolean:
+ zig_panic("TODO handle C translation cast CK_MemberPointerToBoolean");
+ case CK_ReinterpretMemberPointer:
+ zig_panic("TODO handle C translation cast CK_ReinterpretMemberPointer");
+ case CK_UserDefinedConversion:
+ zig_panic("TODO handle C translation cast CK_UserDefinedConversion");
+ case CK_ConstructorConversion:
+ zig_panic("TODO handle C translation cast CK_ConstructorConversion");
+ case CK_IntegralToPointer:
+ zig_panic("TODO handle C translation cast CK_IntegralToPointer");
+ case CK_PointerToIntegral:
+ zig_panic("TODO handle C translation cast CK_PointerToIntegral");
+ case CK_PointerToBoolean:
+ zig_panic("TODO handle C translation cast CK_PointerToBoolean");
+ case CK_ToVoid:
+ zig_panic("TODO handle C translation cast CK_ToVoid");
+ case CK_VectorSplat:
+ zig_panic("TODO handle C translation cast CK_VectorSplat");
+ case CK_IntegralToBoolean:
+ zig_panic("TODO handle C translation cast CK_IntegralToBoolean");
+ case CK_IntegralToFloating:
+ zig_panic("TODO handle C translation cast CK_IntegralToFloating");
+ case CK_FloatingToIntegral:
+ zig_panic("TODO handle C translation cast CK_FloatingToIntegral");
+ case CK_FloatingToBoolean:
+ zig_panic("TODO handle C translation cast CK_FloatingToBoolean");
+ case CK_BooleanToSignedIntegral:
+ zig_panic("TODO handle C translation cast CK_BooleanToSignedIntegral");
+ case CK_FloatingCast:
+ zig_panic("TODO handle C translation cast CK_FloatingCast");
+ case CK_CPointerToObjCPointerCast:
+ zig_panic("TODO handle C translation cast CK_CPointerToObjCPointerCast");
+ case CK_BlockPointerToObjCPointerCast:
+ zig_panic("TODO handle C translation cast CK_BlockPointerToObjCPointerCast");
+ case CK_AnyPointerToBlockPointerCast:
+ zig_panic("TODO handle C translation cast CK_AnyPointerToBlockPointerCast");
+ case CK_ObjCObjectLValueCast:
+ zig_panic("TODO handle C translation cast CK_ObjCObjectLValueCast");
+ case CK_FloatingRealToComplex:
+ zig_panic("TODO handle C translation cast CK_FloatingRealToComplex");
+ case CK_FloatingComplexToReal:
+ zig_panic("TODO handle C translation cast CK_FloatingComplexToReal");
+ case CK_FloatingComplexToBoolean:
+ zig_panic("TODO handle C translation cast CK_FloatingComplexToBoolean");
+ case CK_FloatingComplexCast:
+ zig_panic("TODO handle C translation cast CK_FloatingComplexCast");
+ case CK_FloatingComplexToIntegralComplex:
+ zig_panic("TODO handle C translation cast CK_FloatingComplexToIntegralComplex");
+ case CK_IntegralRealToComplex:
+ zig_panic("TODO handle C translation cast CK_IntegralRealToComplex");
+ case CK_IntegralComplexToReal:
+ zig_panic("TODO handle C translation cast CK_IntegralComplexToReal");
+ case CK_IntegralComplexToBoolean:
+ zig_panic("TODO handle C translation cast CK_IntegralComplexToBoolean");
+ case CK_IntegralComplexCast:
+ zig_panic("TODO handle C translation cast CK_IntegralComplexCast");
+ case CK_IntegralComplexToFloatingComplex:
+ zig_panic("TODO handle C translation cast CK_IntegralComplexToFloatingComplex");
+ case CK_ARCProduceObject:
+ zig_panic("TODO handle C translation cast CK_ARCProduceObject");
+ case CK_ARCConsumeObject:
+ zig_panic("TODO handle C translation cast CK_ARCConsumeObject");
+ case CK_ARCReclaimReturnedObject:
+ zig_panic("TODO handle C translation cast CK_ARCReclaimReturnedObject");
+ case CK_ARCExtendBlockObject:
+ zig_panic("TODO handle C translation cast CK_ARCExtendBlockObject");
+ case CK_AtomicToNonAtomic:
+ zig_panic("TODO handle C translation cast CK_AtomicToNonAtomic");
+ case CK_NonAtomicToAtomic:
+ zig_panic("TODO handle C translation cast CK_NonAtomicToAtomic");
+ case CK_CopyAndAutoreleaseBlockObject:
+ zig_panic("TODO handle C translation cast CK_CopyAndAutoreleaseBlockObject");
+ case CK_BuiltinFnToFnPtr:
+ zig_panic("TODO handle C translation cast CK_BuiltinFnToFnPtr");
+ case CK_ZeroToOCLEvent:
+ zig_panic("TODO handle C translation cast CK_ZeroToOCLEvent");
+ case CK_ZeroToOCLQueue:
+ zig_panic("TODO handle C translation cast CK_ZeroToOCLQueue");
+ case CK_AddressSpaceConversion:
+ zig_panic("TODO handle C translation cast CK_AddressSpaceConversion");
+ case CK_IntToOCLSampler:
+ zig_panic("TODO handle C translation cast CK_IntToOCLSampler");
+ }
+ zig_unreachable();
+}
+
+static AstNode * trans_decl_ref_expr(Context *c, DeclRefExpr *stmt) {
+ ValueDecl *value_decl = stmt->getDecl();
+ const char *name = decl_name(value_decl);
+
+ AstNode *node = trans_create_node(c, NodeTypeSymbol);
+ node->data.symbol_expr.symbol = buf_create_from_str(name);
+ return node;
+}
+
+static AstNode * trans_unary_operator(Context *c, AstNode *block, UnaryOperator *stmt) {
+ switch (stmt->getOpcode()) {
+ case UO_PostInc:
+ zig_panic("TODO handle C translation UO_PostInc");
+ case UO_PostDec:
+ zig_panic("TODO handle C translation UO_PostDec");
+ case UO_PreInc:
+ zig_panic("TODO handle C translation UO_PreInc");
+ case UO_PreDec:
+ zig_panic("TODO handle C translation UO_PreDec");
+ case UO_AddrOf:
+ zig_panic("TODO handle C translation UO_AddrOf");
+ case UO_Deref:
+ zig_panic("TODO handle C translation UO_Deref");
+ case UO_Plus:
+ zig_panic("TODO handle C translation UO_Plus");
+ case UO_Minus:
+ {
+ Expr *op_expr = stmt->getSubExpr();
+ if (c_is_signed_integer(c, op_expr->getType()) || c_is_float(c, op_expr->getType())) {
+ AstNode *node = trans_create_node(c, NodeTypePrefixOpExpr);
+ node->data.prefix_op_expr.prefix_op = PrefixOpNegation;
+ node->data.prefix_op_expr.primary_expr = trans_expr(c, block, op_expr);
+ return node;
+ } else if (c_is_unsigned_integer(c, op_expr->getType())) {
+ // we gotta emit 0 -% x
+ AstNode *node = trans_create_node(c, NodeTypeBinOpExpr);
+ node->data.bin_op_expr.op1 = trans_create_node_unsigned(c, 0);
+ node->data.bin_op_expr.op2 = trans_expr(c, block, op_expr);
+ node->data.bin_op_expr.bin_op = BinOpTypeSubWrap;
+ return node;
+ } else {
+ zig_panic("TODO translate C negation with non float non integer");
+ }
+ }
+ case UO_Not:
+ zig_panic("TODO handle C translation UO_Not");
+ case UO_LNot:
+ zig_panic("TODO handle C translation UO_LNot");
+ case UO_Real:
+ zig_panic("TODO handle C translation UO_Real");
+ case UO_Imag:
+ zig_panic("TODO handle C translation UO_Imag");
+ case UO_Extension:
+ zig_panic("TODO handle C translation UO_Extension");
+ case UO_Coawait:
+ zig_panic("TODO handle C translation UO_Coawait");
+ }
+ zig_unreachable();
+}
+
+static AstNode * trans_local_declaration(Context *c, AstNode *block, DeclStmt *stmt) {
+ for (auto iter = stmt->decl_begin(); iter != stmt->decl_end(); iter++) {
+ Decl *decl = *iter;
+ switch (decl->getKind()) {
+ case Decl::Var: {
+ VarDecl *var_decl = (VarDecl *)decl;
+ QualType qual_type = var_decl->getTypeSourceInfo()->getType();
+ AstNode *init_node = var_decl->hasInit() ? trans_expr(c, block, var_decl->getInit()) : nullptr;
+ AstNode *type_node = trans_qual_type(c, qual_type, stmt->getStartLoc());
+ AstNode *node = trans_create_node_var_decl(c, qual_type.isConstQualified(),
+ buf_create_from_str(decl_name(var_decl)), type_node, init_node);
+ block->data.block.statements.append(node);
+ continue;
+ }
+ case Decl::AccessSpec:
+ zig_panic("TODO handle decl kind AccessSpec");
+ case Decl::Block:
+ zig_panic("TODO handle decl kind Block");
+ case Decl::Captured:
+ zig_panic("TODO handle decl kind Captured");
+ case Decl::ClassScopeFunctionSpecialization:
+ zig_panic("TODO handle decl kind ClassScopeFunctionSpecialization");
+ case Decl::Empty:
+ zig_panic("TODO handle decl kind Empty");
+ case Decl::Export:
+ zig_panic("TODO handle decl kind Export");
+ case Decl::ExternCContext:
+ zig_panic("TODO handle decl kind ExternCContext");
+ case Decl::FileScopeAsm:
+ zig_panic("TODO handle decl kind FileScopeAsm");
+ case Decl::Friend:
+ zig_panic("TODO handle decl kind Friend");
+ case Decl::FriendTemplate:
+ zig_panic("TODO handle decl kind FriendTemplate");
+ case Decl::Import:
+ zig_panic("TODO handle decl kind Import");
+ case Decl::LinkageSpec:
+ zig_panic("TODO handle decl kind LinkageSpec");
+ case Decl::Label:
+ zig_panic("TODO handle decl kind Label");
+ case Decl::Namespace:
+ zig_panic("TODO handle decl kind Namespace");
+ case Decl::NamespaceAlias:
+ zig_panic("TODO handle decl kind NamespaceAlias");
+ case Decl::ObjCCompatibleAlias:
+ zig_panic("TODO handle decl kind ObjCCompatibleAlias");
+ case Decl::ObjCCategory:
+ zig_panic("TODO handle decl kind ObjCCategory");
+ case Decl::ObjCCategoryImpl:
+ zig_panic("TODO handle decl kind ObjCCategoryImpl");
+ case Decl::ObjCImplementation:
+ zig_panic("TODO handle decl kind ObjCImplementation");
+ case Decl::ObjCInterface:
+ zig_panic("TODO handle decl kind ObjCInterface");
+ case Decl::ObjCProtocol:
+ zig_panic("TODO handle decl kind ObjCProtocol");
+ case Decl::ObjCMethod:
+ zig_panic("TODO handle decl kind ObjCMethod");
+ case Decl::ObjCProperty:
+ zig_panic("TODO handle decl kind ObjCProperty");
+ case Decl::BuiltinTemplate:
+ zig_panic("TODO handle decl kind BuiltinTemplate");
+ case Decl::ClassTemplate:
+ zig_panic("TODO handle decl kind ClassTemplate");
+ case Decl::FunctionTemplate:
+ zig_panic("TODO handle decl kind FunctionTemplate");
+ case Decl::TypeAliasTemplate:
+ zig_panic("TODO handle decl kind TypeAliasTemplate");
+ case Decl::VarTemplate:
+ zig_panic("TODO handle decl kind VarTemplate");
+ case Decl::TemplateTemplateParm:
+ zig_panic("TODO handle decl kind TemplateTemplateParm");
+ case Decl::Enum:
+ zig_panic("TODO handle decl kind Enum");
+ case Decl::Record:
+ zig_panic("TODO handle decl kind Record");
+ case Decl::CXXRecord:
+ zig_panic("TODO handle decl kind CXXRecord");
+ case Decl::ClassTemplateSpecialization:
+ zig_panic("TODO handle decl kind ClassTemplateSpecialization");
+ case Decl::ClassTemplatePartialSpecialization:
+ zig_panic("TODO handle decl kind ClassTemplatePartialSpecialization");
+ case Decl::TemplateTypeParm:
+ zig_panic("TODO handle decl kind TemplateTypeParm");
+ case Decl::ObjCTypeParam:
+ zig_panic("TODO handle decl kind ObjCTypeParam");
+ case Decl::TypeAlias:
+ zig_panic("TODO handle decl kind TypeAlias");
+ case Decl::Typedef:
+ zig_panic("TODO handle decl kind Typedef");
+ case Decl::UnresolvedUsingTypename:
+ zig_panic("TODO handle decl kind UnresolvedUsingTypename");
+ case Decl::Using:
+ zig_panic("TODO handle decl kind Using");
+ case Decl::UsingDirective:
+ zig_panic("TODO handle decl kind UsingDirective");
+ case Decl::UsingPack:
+ zig_panic("TODO handle decl kind UsingPack");
+ case Decl::UsingShadow:
+ zig_panic("TODO handle decl kind UsingShadow");
+ case Decl::ConstructorUsingShadow:
+ zig_panic("TODO handle decl kind ConstructorUsingShadow");
+ case Decl::Binding:
+ zig_panic("TODO handle decl kind Binding");
+ case Decl::Field:
+ zig_panic("TODO handle decl kind Field");
+ case Decl::ObjCAtDefsField:
+ zig_panic("TODO handle decl kind ObjCAtDefsField");
+ case Decl::ObjCIvar:
+ zig_panic("TODO handle decl kind ObjCIvar");
+ case Decl::Function:
+ zig_panic("TODO handle decl kind Function");
+ case Decl::CXXDeductionGuide:
+ zig_panic("TODO handle decl kind CXXDeductionGuide");
+ case Decl::CXXMethod:
+ zig_panic("TODO handle decl kind CXXMethod");
+ case Decl::CXXConstructor:
+ zig_panic("TODO handle decl kind CXXConstructor");
+ case Decl::CXXConversion:
+ zig_panic("TODO handle decl kind CXXConversion");
+ case Decl::CXXDestructor:
+ zig_panic("TODO handle decl kind CXXDestructor");
+ case Decl::MSProperty:
+ zig_panic("TODO handle decl kind MSProperty");
+ case Decl::NonTypeTemplateParm:
+ zig_panic("TODO handle decl kind NonTypeTemplateParm");
+ case Decl::Decomposition:
+ zig_panic("TODO handle decl kind Decomposition");
+ case Decl::ImplicitParam:
+ zig_panic("TODO handle decl kind ImplicitParam");
+ case Decl::OMPCapturedExpr:
+ zig_panic("TODO handle decl kind OMPCapturedExpr");
+ case Decl::ParmVar:
+ zig_panic("TODO handle decl kind ParmVar");
+ case Decl::VarTemplateSpecialization:
+ zig_panic("TODO handle decl kind VarTemplateSpecialization");
+ case Decl::VarTemplatePartialSpecialization:
+ zig_panic("TODO handle decl kind VarTemplatePartialSpecialization");
+ case Decl::EnumConstant:
+ zig_panic("TODO handle decl kind EnumConstant");
+ case Decl::IndirectField:
+ zig_panic("TODO handle decl kind IndirectField");
+ case Decl::OMPDeclareReduction:
+ zig_panic("TODO handle decl kind OMPDeclareReduction");
+ case Decl::UnresolvedUsingValue:
+ zig_panic("TODO handle decl kind UnresolvedUsingValue");
+ case Decl::OMPThreadPrivate:
+ zig_panic("TODO handle decl kind OMPThreadPrivate");
+ case Decl::ObjCPropertyImpl:
+ zig_panic("TODO handle decl kind ObjCPropertyImpl");
+ case Decl::PragmaComment:
+ zig_panic("TODO handle decl kind PragmaComment");
+ case Decl::PragmaDetectMismatch:
+ zig_panic("TODO handle decl kind PragmaDetectMismatch");
+ case Decl::StaticAssert:
+ zig_panic("TODO handle decl kind StaticAssert");
+ case Decl::TranslationUnit:
+ zig_panic("TODO handle decl kind TranslationUnit");
+ }
+ zig_unreachable();
+ }
+
+ // declarations were already added
+ return nullptr;
+}
+
+static AstNode *trans_while_loop(Context *c, AstNode *block, WhileStmt *stmt) {
+ AstNode *while_node = trans_create_node(c, NodeTypeWhileExpr);
+ while_node->data.while_expr.condition = trans_expr(c, block, stmt->getCond());
+ while_node->data.while_expr.body = trans_stmt(c, block, stmt->getBody());
+ return while_node;
+}
+
+static AstNode *trans_stmt(Context *c, AstNode *block, Stmt *stmt) {
+ Stmt::StmtClass sc = stmt->getStmtClass();
+ switch (sc) {
+ case Stmt::ReturnStmtClass:
+ return trans_return_stmt(c, block, (ReturnStmt *)stmt);
+ case Stmt::CompoundStmtClass:
+ return trans_compound_stmt(c, block, (CompoundStmt *)stmt);
+ case Stmt::IntegerLiteralClass:
+ return trans_integer_literal(c, (IntegerLiteral *)stmt);
+ case Stmt::ConditionalOperatorClass:
+ return trans_conditional_operator(c, block, (ConditionalOperator *)stmt);
+ case Stmt::BinaryOperatorClass:
+ return trans_binary_operator(c, block, (BinaryOperator *)stmt);
+ case Stmt::ImplicitCastExprClass:
+ return trans_implicit_cast_expr(c, block, (ImplicitCastExpr *)stmt);
+ case Stmt::DeclRefExprClass:
+ return trans_decl_ref_expr(c, (DeclRefExpr *)stmt);
+ case Stmt::UnaryOperatorClass:
+ return trans_unary_operator(c, block, (UnaryOperator *)stmt);
+ case Stmt::DeclStmtClass:
+ return trans_local_declaration(c, block, (DeclStmt *)stmt);
+ case Stmt::WhileStmtClass:
+ return trans_while_loop(c, block, (WhileStmt *)stmt);
+ case Stmt::CaseStmtClass:
+ zig_panic("TODO handle C CaseStmtClass");
+ case Stmt::DefaultStmtClass:
+ zig_panic("TODO handle C DefaultStmtClass");
+ case Stmt::SwitchStmtClass:
+ zig_panic("TODO handle C SwitchStmtClass");
+ case Stmt::NoStmtClass:
+ zig_panic("TODO handle C NoStmtClass");
+ case Stmt::GCCAsmStmtClass:
+ zig_panic("TODO handle C GCCAsmStmtClass");
+ case Stmt::MSAsmStmtClass:
+ zig_panic("TODO handle C MSAsmStmtClass");
+ case Stmt::AttributedStmtClass:
+ zig_panic("TODO handle C AttributedStmtClass");
+ case Stmt::BreakStmtClass:
+ zig_panic("TODO handle C BreakStmtClass");
+ case Stmt::CXXCatchStmtClass:
+ zig_panic("TODO handle C CXXCatchStmtClass");
+ case Stmt::CXXForRangeStmtClass:
+ zig_panic("TODO handle C CXXForRangeStmtClass");
+ case Stmt::CXXTryStmtClass:
+ zig_panic("TODO handle C CXXTryStmtClass");
+ case Stmt::CapturedStmtClass:
+ zig_panic("TODO handle C CapturedStmtClass");
+ case Stmt::ContinueStmtClass:
+ zig_panic("TODO handle C ContinueStmtClass");
+ case Stmt::CoreturnStmtClass:
+ zig_panic("TODO handle C CoreturnStmtClass");
+ case Stmt::CoroutineBodyStmtClass:
+ zig_panic("TODO handle C CoroutineBodyStmtClass");
+ case Stmt::DoStmtClass:
+ zig_panic("TODO handle C DoStmtClass");
+ case Stmt::BinaryConditionalOperatorClass:
+ zig_panic("TODO handle C BinaryConditionalOperatorClass");
+ case Stmt::AddrLabelExprClass:
+ zig_panic("TODO handle C AddrLabelExprClass");
+ case Stmt::ArrayInitIndexExprClass:
+ zig_panic("TODO handle C ArrayInitIndexExprClass");
+ case Stmt::ArrayInitLoopExprClass:
+ zig_panic("TODO handle C ArrayInitLoopExprClass");
+ case Stmt::ArraySubscriptExprClass:
+ zig_panic("TODO handle C ArraySubscriptExprClass");
+ case Stmt::ArrayTypeTraitExprClass:
+ zig_panic("TODO handle C ArrayTypeTraitExprClass");
+ case Stmt::AsTypeExprClass:
+ zig_panic("TODO handle C AsTypeExprClass");
+ case Stmt::AtomicExprClass:
+ zig_panic("TODO handle C AtomicExprClass");
+ case Stmt::CompoundAssignOperatorClass:
+ zig_panic("TODO handle C CompoundAssignOperatorClass");
+ case Stmt::BlockExprClass:
+ zig_panic("TODO handle C BlockExprClass");
+ case Stmt::CXXBindTemporaryExprClass:
+ zig_panic("TODO handle C CXXBindTemporaryExprClass");
+ case Stmt::CXXBoolLiteralExprClass:
+ zig_panic("TODO handle C CXXBoolLiteralExprClass");
+ case Stmt::CXXConstructExprClass:
+ zig_panic("TODO handle C CXXConstructExprClass");
+ case Stmt::CXXTemporaryObjectExprClass:
+ zig_panic("TODO handle C CXXTemporaryObjectExprClass");
+ case Stmt::CXXDefaultArgExprClass:
+ zig_panic("TODO handle C CXXDefaultArgExprClass");
+ case Stmt::CXXDefaultInitExprClass:
+ zig_panic("TODO handle C CXXDefaultInitExprClass");
+ case Stmt::CXXDeleteExprClass:
+ zig_panic("TODO handle C CXXDeleteExprClass");
+ case Stmt::CXXDependentScopeMemberExprClass:
+ zig_panic("TODO handle C CXXDependentScopeMemberExprClass");
+ case Stmt::CXXFoldExprClass:
+ zig_panic("TODO handle C CXXFoldExprClass");
+ case Stmt::CXXInheritedCtorInitExprClass:
+ zig_panic("TODO handle C CXXInheritedCtorInitExprClass");
+ case Stmt::CXXNewExprClass:
+ zig_panic("TODO handle C CXXNewExprClass");
+ case Stmt::CXXNoexceptExprClass:
+ zig_panic("TODO handle C CXXNoexceptExprClass");
+ case Stmt::CXXNullPtrLiteralExprClass:
+ zig_panic("TODO handle C CXXNullPtrLiteralExprClass");
+ case Stmt::CXXPseudoDestructorExprClass:
+ zig_panic("TODO handle C CXXPseudoDestructorExprClass");
+ case Stmt::CXXScalarValueInitExprClass:
+ zig_panic("TODO handle C CXXScalarValueInitExprClass");
+ case Stmt::CXXStdInitializerListExprClass:
+ zig_panic("TODO handle C CXXStdInitializerListExprClass");
+ case Stmt::CXXThisExprClass:
+ zig_panic("TODO handle C CXXThisExprClass");
+ case Stmt::CXXThrowExprClass:
+ zig_panic("TODO handle C CXXThrowExprClass");
+ case Stmt::CXXTypeidExprClass:
+ zig_panic("TODO handle C CXXTypeidExprClass");
+ case Stmt::CXXUnresolvedConstructExprClass:
+ zig_panic("TODO handle C CXXUnresolvedConstructExprClass");
+ case Stmt::CXXUuidofExprClass:
+ zig_panic("TODO handle C CXXUuidofExprClass");
+ case Stmt::CallExprClass:
+ zig_panic("TODO handle C CallExprClass");
+ case Stmt::CUDAKernelCallExprClass:
+ zig_panic("TODO handle C CUDAKernelCallExprClass");
+ case Stmt::CXXMemberCallExprClass:
+ zig_panic("TODO handle C CXXMemberCallExprClass");
+ case Stmt::CXXOperatorCallExprClass:
+ zig_panic("TODO handle C CXXOperatorCallExprClass");
+ case Stmt::UserDefinedLiteralClass:
+ zig_panic("TODO handle C UserDefinedLiteralClass");
+ case Stmt::CStyleCastExprClass:
+ zig_panic("TODO handle C CStyleCastExprClass");
+ case Stmt::CXXFunctionalCastExprClass:
+ zig_panic("TODO handle C CXXFunctionalCastExprClass");
+ case Stmt::CXXConstCastExprClass:
+ zig_panic("TODO handle C CXXConstCastExprClass");
+ case Stmt::CXXDynamicCastExprClass:
+ zig_panic("TODO handle C CXXDynamicCastExprClass");
+ case Stmt::CXXReinterpretCastExprClass:
+ zig_panic("TODO handle C CXXReinterpretCastExprClass");
+ case Stmt::CXXStaticCastExprClass:
+ zig_panic("TODO handle C CXXStaticCastExprClass");
+ case Stmt::ObjCBridgedCastExprClass:
+ zig_panic("TODO handle C ObjCBridgedCastExprClass");
+ case Stmt::CharacterLiteralClass:
+ zig_panic("TODO handle C CharacterLiteralClass");
+ case Stmt::ChooseExprClass:
+ zig_panic("TODO handle C ChooseExprClass");
+ case Stmt::CompoundLiteralExprClass:
+ zig_panic("TODO handle C CompoundLiteralExprClass");
+ case Stmt::ConvertVectorExprClass:
+ zig_panic("TODO handle C ConvertVectorExprClass");
+ case Stmt::CoawaitExprClass:
+ zig_panic("TODO handle C CoawaitExprClass");
+ case Stmt::CoyieldExprClass:
+ zig_panic("TODO handle C CoyieldExprClass");
+ case Stmt::DependentCoawaitExprClass:
+ zig_panic("TODO handle C DependentCoawaitExprClass");
+ case Stmt::DependentScopeDeclRefExprClass:
+ zig_panic("TODO handle C DependentScopeDeclRefExprClass");
+ case Stmt::DesignatedInitExprClass:
+ zig_panic("TODO handle C DesignatedInitExprClass");
+ case Stmt::DesignatedInitUpdateExprClass:
+ zig_panic("TODO handle C DesignatedInitUpdateExprClass");
+ case Stmt::ExprWithCleanupsClass:
+ zig_panic("TODO handle C ExprWithCleanupsClass");
+ case Stmt::ExpressionTraitExprClass:
+ zig_panic("TODO handle C ExpressionTraitExprClass");
+ case Stmt::ExtVectorElementExprClass:
+ zig_panic("TODO handle C ExtVectorElementExprClass");
+ case Stmt::FloatingLiteralClass:
+ zig_panic("TODO handle C FloatingLiteralClass");
+ case Stmt::FunctionParmPackExprClass:
+ zig_panic("TODO handle C FunctionParmPackExprClass");
+ case Stmt::GNUNullExprClass:
+ zig_panic("TODO handle C GNUNullExprClass");
+ case Stmt::GenericSelectionExprClass:
+ zig_panic("TODO handle C GenericSelectionExprClass");
+ case Stmt::ImaginaryLiteralClass:
+ zig_panic("TODO handle C ImaginaryLiteralClass");
+ case Stmt::ImplicitValueInitExprClass:
+ zig_panic("TODO handle C ImplicitValueInitExprClass");
+ case Stmt::InitListExprClass:
+ zig_panic("TODO handle C InitListExprClass");
+ case Stmt::LambdaExprClass:
+ zig_panic("TODO handle C LambdaExprClass");
+ case Stmt::MSPropertyRefExprClass:
+ zig_panic("TODO handle C MSPropertyRefExprClass");
+ case Stmt::MSPropertySubscriptExprClass:
+ zig_panic("TODO handle C MSPropertySubscriptExprClass");
+ case Stmt::MaterializeTemporaryExprClass:
+ zig_panic("TODO handle C MaterializeTemporaryExprClass");
+ case Stmt::MemberExprClass:
+ zig_panic("TODO handle C MemberExprClass");
+ case Stmt::NoInitExprClass:
+ zig_panic("TODO handle C NoInitExprClass");
+ case Stmt::OMPArraySectionExprClass:
+ zig_panic("TODO handle C OMPArraySectionExprClass");
+ case Stmt::ObjCArrayLiteralClass:
+ zig_panic("TODO handle C ObjCArrayLiteralClass");
+ case Stmt::ObjCAvailabilityCheckExprClass:
+ zig_panic("TODO handle C ObjCAvailabilityCheckExprClass");
+ case Stmt::ObjCBoolLiteralExprClass:
+ zig_panic("TODO handle C ObjCBoolLiteralExprClass");
+ case Stmt::ObjCBoxedExprClass:
+ zig_panic("TODO handle C ObjCBoxedExprClass");
+ case Stmt::ObjCDictionaryLiteralClass:
+ zig_panic("TODO handle C ObjCDictionaryLiteralClass");
+ case Stmt::ObjCEncodeExprClass:
+ zig_panic("TODO handle C ObjCEncodeExprClass");
+ case Stmt::ObjCIndirectCopyRestoreExprClass:
+ zig_panic("TODO handle C ObjCIndirectCopyRestoreExprClass");
+ case Stmt::ObjCIsaExprClass:
+ zig_panic("TODO handle C ObjCIsaExprClass");
+ case Stmt::ObjCIvarRefExprClass:
+ zig_panic("TODO handle C ObjCIvarRefExprClass");
+ case Stmt::ObjCMessageExprClass:
+ zig_panic("TODO handle C ObjCMessageExprClass");
+ case Stmt::ObjCPropertyRefExprClass:
+ zig_panic("TODO handle C ObjCPropertyRefExprClass");
+ case Stmt::ObjCProtocolExprClass:
+ zig_panic("TODO handle C ObjCProtocolExprClass");
+ case Stmt::ObjCSelectorExprClass:
+ zig_panic("TODO handle C ObjCSelectorExprClass");
+ case Stmt::ObjCStringLiteralClass:
+ zig_panic("TODO handle C ObjCStringLiteralClass");
+ case Stmt::ObjCSubscriptRefExprClass:
+ zig_panic("TODO handle C ObjCSubscriptRefExprClass");
+ case Stmt::OffsetOfExprClass:
+ zig_panic("TODO handle C OffsetOfExprClass");
+ case Stmt::OpaqueValueExprClass:
+ zig_panic("TODO handle C OpaqueValueExprClass");
+ case Stmt::UnresolvedLookupExprClass:
+ zig_panic("TODO handle C UnresolvedLookupExprClass");
+ case Stmt::UnresolvedMemberExprClass:
+ zig_panic("TODO handle C UnresolvedMemberExprClass");
+ case Stmt::PackExpansionExprClass:
+ zig_panic("TODO handle C PackExpansionExprClass");
+ case Stmt::ParenExprClass:
+ zig_panic("TODO handle C ParenExprClass");
+ case Stmt::ParenListExprClass:
+ zig_panic("TODO handle C ParenListExprClass");
+ case Stmt::PredefinedExprClass:
+ zig_panic("TODO handle C PredefinedExprClass");
+ case Stmt::PseudoObjectExprClass:
+ zig_panic("TODO handle C PseudoObjectExprClass");
+ case Stmt::ShuffleVectorExprClass:
+ zig_panic("TODO handle C ShuffleVectorExprClass");
+ case Stmt::SizeOfPackExprClass:
+ zig_panic("TODO handle C SizeOfPackExprClass");
+ case Stmt::StmtExprClass:
+ zig_panic("TODO handle C StmtExprClass");
+ case Stmt::StringLiteralClass:
+ zig_panic("TODO handle C StringLiteralClass");
+ case Stmt::SubstNonTypeTemplateParmExprClass:
+ zig_panic("TODO handle C SubstNonTypeTemplateParmExprClass");
+ case Stmt::SubstNonTypeTemplateParmPackExprClass:
+ zig_panic("TODO handle C SubstNonTypeTemplateParmPackExprClass");
+ case Stmt::TypeTraitExprClass:
+ zig_panic("TODO handle C TypeTraitExprClass");
+ case Stmt::TypoExprClass:
+ zig_panic("TODO handle C TypoExprClass");
+ case Stmt::UnaryExprOrTypeTraitExprClass:
+ zig_panic("TODO handle C UnaryExprOrTypeTraitExprClass");
+ case Stmt::VAArgExprClass:
+ zig_panic("TODO handle C VAArgExprClass");
+ case Stmt::ForStmtClass:
+ zig_panic("TODO handle C ForStmtClass");
+ case Stmt::GotoStmtClass:
+ zig_panic("TODO handle C GotoStmtClass");
+ case Stmt::IfStmtClass:
+ zig_panic("TODO handle C IfStmtClass");
+ case Stmt::IndirectGotoStmtClass:
+ zig_panic("TODO handle C IndirectGotoStmtClass");
+ case Stmt::LabelStmtClass:
+ zig_panic("TODO handle C LabelStmtClass");
+ case Stmt::MSDependentExistsStmtClass:
+ zig_panic("TODO handle C MSDependentExistsStmtClass");
+ case Stmt::NullStmtClass:
+ zig_panic("TODO handle C NullStmtClass");
+ case Stmt::OMPAtomicDirectiveClass:
+ zig_panic("TODO handle C OMPAtomicDirectiveClass");
+ case Stmt::OMPBarrierDirectiveClass:
+ zig_panic("TODO handle C OMPBarrierDirectiveClass");
+ case Stmt::OMPCancelDirectiveClass:
+ zig_panic("TODO handle C OMPCancelDirectiveClass");
+ case Stmt::OMPCancellationPointDirectiveClass:
+ zig_panic("TODO handle C OMPCancellationPointDirectiveClass");
+ case Stmt::OMPCriticalDirectiveClass:
+ zig_panic("TODO handle C OMPCriticalDirectiveClass");
+ case Stmt::OMPFlushDirectiveClass:
+ zig_panic("TODO handle C OMPFlushDirectiveClass");
+ case Stmt::OMPDistributeDirectiveClass:
+ zig_panic("TODO handle C OMPDistributeDirectiveClass");
+ case Stmt::OMPDistributeParallelForDirectiveClass:
+ zig_panic("TODO handle C OMPDistributeParallelForDirectiveClass");
+ case Stmt::OMPDistributeParallelForSimdDirectiveClass:
+ zig_panic("TODO handle C OMPDistributeParallelForSimdDirectiveClass");
+ case Stmt::OMPDistributeSimdDirectiveClass:
+ zig_panic("TODO handle C OMPDistributeSimdDirectiveClass");
+ case Stmt::OMPForDirectiveClass:
+ zig_panic("TODO handle C OMPForDirectiveClass");
+ case Stmt::OMPForSimdDirectiveClass:
+ zig_panic("TODO handle C OMPForSimdDirectiveClass");
+ case Stmt::OMPParallelForDirectiveClass:
+ zig_panic("TODO handle C OMPParallelForDirectiveClass");
+ case Stmt::OMPParallelForSimdDirectiveClass:
+ zig_panic("TODO handle C OMPParallelForSimdDirectiveClass");
+ case Stmt::OMPSimdDirectiveClass:
+ zig_panic("TODO handle C OMPSimdDirectiveClass");
+ case Stmt::OMPTargetParallelForSimdDirectiveClass:
+ zig_panic("TODO handle C OMPTargetParallelForSimdDirectiveClass");
+ case Stmt::OMPTargetSimdDirectiveClass:
+ zig_panic("TODO handle C OMPTargetSimdDirectiveClass");
+ case Stmt::OMPTargetTeamsDistributeDirectiveClass:
+ zig_panic("TODO handle C OMPTargetTeamsDistributeDirectiveClass");
+ case Stmt::OMPTargetTeamsDistributeParallelForDirectiveClass:
+ zig_panic("TODO handle C OMPTargetTeamsDistributeParallelForDirectiveClass");
+ case Stmt::OMPTargetTeamsDistributeParallelForSimdDirectiveClass:
+ zig_panic("TODO handle C OMPTargetTeamsDistributeParallelForSimdDirectiveClass");
+ case Stmt::OMPTargetTeamsDistributeSimdDirectiveClass:
+ zig_panic("TODO handle C OMPTargetTeamsDistributeSimdDirectiveClass");
+ case Stmt::OMPTaskLoopDirectiveClass:
+ zig_panic("TODO handle C OMPTaskLoopDirectiveClass");
+ case Stmt::OMPTaskLoopSimdDirectiveClass:
+ zig_panic("TODO handle C OMPTaskLoopSimdDirectiveClass");
+ case Stmt::OMPTeamsDistributeDirectiveClass:
+ zig_panic("TODO handle C OMPTeamsDistributeDirectiveClass");
+ case Stmt::OMPTeamsDistributeParallelForDirectiveClass:
+ zig_panic("TODO handle C OMPTeamsDistributeParallelForDirectiveClass");
+ case Stmt::OMPTeamsDistributeParallelForSimdDirectiveClass:
+ zig_panic("TODO handle C OMPTeamsDistributeParallelForSimdDirectiveClass");
+ case Stmt::OMPTeamsDistributeSimdDirectiveClass:
+ zig_panic("TODO handle C OMPTeamsDistributeSimdDirectiveClass");
+ case Stmt::OMPMasterDirectiveClass:
+ zig_panic("TODO handle C OMPMasterDirectiveClass");
+ case Stmt::OMPOrderedDirectiveClass:
+ zig_panic("TODO handle C OMPOrderedDirectiveClass");
+ case Stmt::OMPParallelDirectiveClass:
+ zig_panic("TODO handle C OMPParallelDirectiveClass");
+ case Stmt::OMPParallelSectionsDirectiveClass:
+ zig_panic("TODO handle C OMPParallelSectionsDirectiveClass");
+ case Stmt::OMPSectionDirectiveClass:
+ zig_panic("TODO handle C OMPSectionDirectiveClass");
+ case Stmt::OMPSectionsDirectiveClass:
+ zig_panic("TODO handle C OMPSectionsDirectiveClass");
+ case Stmt::OMPSingleDirectiveClass:
+ zig_panic("TODO handle C OMPSingleDirectiveClass");
+ case Stmt::OMPTargetDataDirectiveClass:
+ zig_panic("TODO handle C OMPTargetDataDirectiveClass");
+ case Stmt::OMPTargetDirectiveClass:
+ zig_panic("TODO handle C OMPTargetDirectiveClass");
+ case Stmt::OMPTargetEnterDataDirectiveClass:
+ zig_panic("TODO handle C OMPTargetEnterDataDirectiveClass");
+ case Stmt::OMPTargetExitDataDirectiveClass:
+ zig_panic("TODO handle C OMPTargetExitDataDirectiveClass");
+ case Stmt::OMPTargetParallelDirectiveClass:
+ zig_panic("TODO handle C OMPTargetParallelDirectiveClass");
+ case Stmt::OMPTargetParallelForDirectiveClass:
+ zig_panic("TODO handle C OMPTargetParallelForDirectiveClass");
+ case Stmt::OMPTargetTeamsDirectiveClass:
+ zig_panic("TODO handle C OMPTargetTeamsDirectiveClass");
+ case Stmt::OMPTargetUpdateDirectiveClass:
+ zig_panic("TODO handle C OMPTargetUpdateDirectiveClass");
+ case Stmt::OMPTaskDirectiveClass:
+ zig_panic("TODO handle C OMPTaskDirectiveClass");
+ case Stmt::OMPTaskgroupDirectiveClass:
+ zig_panic("TODO handle C OMPTaskgroupDirectiveClass");
+ case Stmt::OMPTaskwaitDirectiveClass:
+ zig_panic("TODO handle C OMPTaskwaitDirectiveClass");
+ case Stmt::OMPTaskyieldDirectiveClass:
+ zig_panic("TODO handle C OMPTaskyieldDirectiveClass");
+ case Stmt::OMPTeamsDirectiveClass:
+ zig_panic("TODO handle C OMPTeamsDirectiveClass");
+ case Stmt::ObjCAtCatchStmtClass:
+ zig_panic("TODO handle C ObjCAtCatchStmtClass");
+ case Stmt::ObjCAtFinallyStmtClass:
+ zig_panic("TODO handle C ObjCAtFinallyStmtClass");
+ case Stmt::ObjCAtSynchronizedStmtClass:
+ zig_panic("TODO handle C ObjCAtSynchronizedStmtClass");
+ case Stmt::ObjCAtThrowStmtClass:
+ zig_panic("TODO handle C ObjCAtThrowStmtClass");
+ case Stmt::ObjCAtTryStmtClass:
+ zig_panic("TODO handle C ObjCAtTryStmtClass");
+ case Stmt::ObjCAutoreleasePoolStmtClass:
+ zig_panic("TODO handle C ObjCAutoreleasePoolStmtClass");
+ case Stmt::ObjCForCollectionStmtClass:
+ zig_panic("TODO handle C ObjCForCollectionStmtClass");
+ case Stmt::SEHExceptStmtClass:
+ zig_panic("TODO handle C SEHExceptStmtClass");
+ case Stmt::SEHFinallyStmtClass:
+ zig_panic("TODO handle C SEHFinallyStmtClass");
+ case Stmt::SEHLeaveStmtClass:
+ zig_panic("TODO handle C SEHLeaveStmtClass");
+ case Stmt::SEHTryStmtClass:
+ zig_panic("TODO handle C SEHTryStmtClass");
+ }
+ zig_unreachable();
}
static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) {
@@ -610,112 +1598,146 @@ static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) {
return;
}
- TypeTableEntry *fn_type = resolve_qual_type(c, fn_decl->getType(), fn_decl);
-
- if (fn_type->id == TypeTableEntryIdInvalid) {
- emit_warning(c, fn_decl, "ignoring function '%s' - unable to resolve type", buf_ptr(fn_name));
+ AstNode *proto_node = trans_qual_type(c, fn_decl->getType(), fn_decl->getLocation());
+ if (proto_node == nullptr) {
+ emit_warning(c, fn_decl->getLocation(), "unable to resolve prototype of function '%s'", buf_ptr(fn_name));
return;
}
- assert(fn_type->id == TypeTableEntryIdFn);
- FnTableEntry *fn_entry = create_fn_raw(FnInlineAuto, GlobalLinkageIdStrong);
- buf_init_from_buf(&fn_entry->symbol_name, fn_name);
- fn_entry->type_entry = fn_type;
+ proto_node->data.fn_proto.name = fn_name;
+ proto_node->data.fn_proto.is_extern = !fn_decl->hasBody();
- assert(fn_type->data.fn.fn_type_id.cc != CallingConventionNaked);
+ StorageClass sc = fn_decl->getStorageClass();
+ if (sc == SC_None) {
+ proto_node->data.fn_proto.visib_mod = fn_decl->hasBody() ? VisibModExport : c->visib_mod;
+ } else if (sc == SC_Extern || sc == SC_Static) {
+ proto_node->data.fn_proto.visib_mod = c->visib_mod;
+ } else if (sc == SC_PrivateExtern) {
+ emit_warning(c, fn_decl->getLocation(), "unsupported storage class: private extern");
+ return;
+ } else {
+ emit_warning(c, fn_decl->getLocation(), "unsupported storage class: unknown");
+ return;
+ }
- size_t arg_count = fn_type->data.fn.fn_type_id.param_count;
- fn_entry->param_names = allocate<Buf *>(arg_count);
- Buf *name_buf;
- for (size_t i = 0; i < arg_count; i += 1) {
+ for (size_t i = 0; i < proto_node->data.fn_proto.params.length; i += 1) {
+ AstNode *param_node = proto_node->data.fn_proto.params.at(i);
const ParmVarDecl *param = fn_decl->getParamDecl(i);
const char *name = decl_name(param);
if (strlen(name) == 0) {
- name_buf = buf_sprintf("arg%" ZIG_PRI_usize "", i);
+ Buf *proto_param_name = param_node->data.param_decl.name;
+ if (proto_param_name == nullptr) {
+ param_node->data.param_decl.name = buf_sprintf("arg%" ZIG_PRI_usize "", i);
+ } else {
+ param_node->data.param_decl.name = proto_param_name;
+ }
} else {
- name_buf = buf_create_from_str(name);
+ param_node->data.param_decl.name = buf_create_from_str(name);
}
- fn_entry->param_names[i] = name_buf;
}
- TldFn *tld_fn = allocate<TldFn>(1);
- parseh_init_tld(c, &tld_fn->base, TldIdFn, fn_name);
- tld_fn->fn_entry = fn_entry;
- add_global(c, &tld_fn->base);
+ if (fn_decl->hasBody()) {
+ Stmt *body = fn_decl->getBody();
+
+ AstNode *fn_def_node = trans_create_node(c, NodeTypeFnDef);
+ fn_def_node->data.fn_def.fn_proto = proto_node;
+ fn_def_node->data.fn_def.body = trans_stmt(c, nullptr, body);
- c->codegen->fn_protos.append(fn_entry);
+ proto_node->data.fn_proto.fn_def_node = fn_def_node;
+ c->root->data.root.top_level_decls.append(fn_def_node);
+ return;
+ }
+
+ c->root->data.root.top_level_decls.append(proto_node);
+}
+
+static AstNode *resolve_typdef_as_builtin(Context *c, const TypedefNameDecl *typedef_decl, const char *primitive_name) {
+ AstNode *node = trans_create_node_symbol_str(c, primitive_name);
+ c->decl_table.put(typedef_decl, node);
+ return node;
}
-static void visit_typedef_decl(Context *c, const TypedefNameDecl *typedef_decl) {
+static AstNode *resolve_typedef_decl(Context *c, const TypedefNameDecl *typedef_decl) {
+ auto existing_entry = c->decl_table.maybe_get((void*)typedef_decl);
+ if (existing_entry) {
+ return existing_entry->value;
+ }
+
QualType child_qt = typedef_decl->getUnderlyingType();
Buf *type_name = buf_create_from_str(decl_name(typedef_decl));
- if (buf_eql_str(type_name, "uint8_t") ||
- buf_eql_str(type_name, "int8_t") ||
- buf_eql_str(type_name, "uint16_t") ||
- buf_eql_str(type_name, "int16_t") ||
- buf_eql_str(type_name, "uint32_t") ||
- buf_eql_str(type_name, "int32_t") ||
- buf_eql_str(type_name, "uint64_t") ||
- buf_eql_str(type_name, "int64_t") ||
- buf_eql_str(type_name, "intptr_t") ||
- buf_eql_str(type_name, "uintptr_t"))
- {
- // special case we can just use the builtin types
- return;
+ if (buf_eql_str(type_name, "uint8_t")) {
+ return resolve_typdef_as_builtin(c, typedef_decl, "u8");
+ } else if (buf_eql_str(type_name, "int8_t")) {
+ return resolve_typdef_as_builtin(c, typedef_decl, "i8");
+ } else if (buf_eql_str(type_name, "uint16_t")) {
+ return resolve_typdef_as_builtin(c, typedef_decl, "u16");
+ } else if (buf_eql_str(type_name, "int16_t")) {
+ return resolve_typdef_as_builtin(c, typedef_decl, "i16");
+ } else if (buf_eql_str(type_name, "uint32_t")) {
+ return resolve_typdef_as_builtin(c, typedef_decl, "u32");
+ } else if (buf_eql_str(type_name, "int32_t")) {
+ return resolve_typdef_as_builtin(c, typedef_decl, "i32");
+ } else if (buf_eql_str(type_name, "uint64_t")) {
+ return resolve_typdef_as_builtin(c, typedef_decl, "u64");
+ } else if (buf_eql_str(type_name, "int64_t")) {
+ return resolve_typdef_as_builtin(c, typedef_decl, "i64");
+ } else if (buf_eql_str(type_name, "intptr_t")) {
+ return resolve_typdef_as_builtin(c, typedef_decl, "isize");
+ } else if (buf_eql_str(type_name, "uintptr_t")) {
+ return resolve_typdef_as_builtin(c, typedef_decl, "usize");
+ } else if (buf_eql_str(type_name, "ssize_t")) {
+ return resolve_typdef_as_builtin(c, typedef_decl, "isize");
+ } else if (buf_eql_str(type_name, "size_t")) {
+ return resolve_typdef_as_builtin(c, typedef_decl, "usize");
}
// if the underlying type is anonymous, we can special case it to just
// use the name of this typedef
// TODO
- TypeTableEntry *child_type = resolve_qual_type(c, child_qt, typedef_decl);
- if (child_type->id == TypeTableEntryIdInvalid) {
- emit_warning(c, typedef_decl, "typedef %s - unresolved child type", buf_ptr(type_name));
- return;
+ AstNode *type_node = trans_qual_type(c, child_qt, typedef_decl->getLocation());
+ if (type_node == nullptr) {
+ emit_warning(c, typedef_decl->getLocation(), "typedef %s - unresolved child type", buf_ptr(type_name));
+ c->decl_table.put(typedef_decl, nullptr);
+ return nullptr;
}
- add_const_type(c, type_name, child_type);
-}
+ add_global_var(c, type_name, type_node);
-static void replace_with_fwd_decl(Context *c, TypeTableEntry *struct_type, Buf *full_type_name) {
- unsigned line = c->source_node ? c->source_node->line : 0;
- ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugForwardDeclType(c->codegen->dbuilder,
- ZigLLVMTag_DW_structure_type(), buf_ptr(full_type_name),
- ZigLLVMFileToScope(c->import->di_file), c->import->di_file, line);
+ AstNode *symbol_node = trans_create_node_symbol(c, type_name);
+ c->decl_table.put(typedef_decl, symbol_node);
+ return symbol_node;
+}
- ZigLLVMReplaceTemporary(c->codegen->dbuilder, struct_type->di_type, replacement_di_type);
- struct_type->di_type = replacement_di_type;
- struct_type->id = TypeTableEntryIdOpaque;
+struct AstNode *demote_enum_to_opaque(Context *c, const EnumDecl *enum_decl,
+ Buf *full_type_name, Buf *bare_name)
+{
+ AstNode *opaque_node = trans_create_node_opaque(c);
+ if (full_type_name == nullptr) {
+ c->decl_table.put(enum_decl->getCanonicalDecl(), opaque_node);
+ return opaque_node;
+ }
+ AstNode *symbol_node = trans_create_node_symbol(c, full_type_name);
+ add_global_weak_alias(c, bare_name, full_type_name);
+ add_global_var(c, full_type_name, opaque_node);
+ c->decl_table.put(enum_decl->getCanonicalDecl(), symbol_node);
+ return symbol_node;
}
-static TypeTableEntry *resolve_enum_decl(Context *c, const EnumDecl *enum_decl) {
- auto existing_entry = c->decl_table.maybe_get((void*)enum_decl);
+static AstNode *resolve_enum_decl(Context *c, const EnumDecl *enum_decl) {
+ auto existing_entry = c->decl_table.maybe_get((void*)enum_decl->getCanonicalDecl());
if (existing_entry) {
return existing_entry->value;
}
const char *raw_name = decl_name(enum_decl);
-
- Buf *bare_name;
- if (raw_name[0] == 0) {
- bare_name = buf_sprintf("anon_$%" PRIu32, get_next_anon_index(c));
- } else {
- bare_name = buf_create_from_str(raw_name);
- }
-
- Buf *full_type_name = buf_sprintf("enum_%s", buf_ptr(bare_name));
+ bool is_anonymous = (raw_name[0] == 0);
+ Buf *bare_name = is_anonymous ? nullptr : buf_create_from_str(raw_name);
+ Buf *full_type_name = is_anonymous ? nullptr : buf_sprintf("enum_%s", buf_ptr(bare_name));
const EnumDecl *enum_def = enum_decl->getDefinition();
if (!enum_def) {
- TypeTableEntry *enum_type = get_partial_container_type(c->codegen, &c->import->decls_scope->base,
- ContainerKindEnum, c->source_node, buf_ptr(full_type_name), ContainerLayoutExtern);
- enum_type->data.enumeration.zero_bits_known = true;
- enum_type->data.enumeration.abi_alignment = 1;
- c->enum_type_table.put(bare_name, enum_type);
- c->decl_table.put(enum_decl, enum_type);
- replace_with_fwd_decl(c, enum_type, full_type_name);
-
- return enum_type;
+ return demote_enum_to_opaque(c, enum_decl, full_type_name, bare_name);
}
bool pure_enum = true;
@@ -730,25 +1752,16 @@ static TypeTableEntry *resolve_enum_decl(Context *c, const EnumDecl *enum_decl)
}
}
- TypeTableEntry *tag_int_type = resolve_qual_type(c, enum_decl->getIntegerType(), enum_decl);
+ AstNode *tag_int_type = trans_qual_type(c, enum_decl->getIntegerType(), enum_decl->getLocation());
+ assert(tag_int_type);
if (pure_enum) {
- TypeTableEntry *enum_type = get_partial_container_type(c->codegen, &c->import->decls_scope->base,
- ContainerKindEnum, c->source_node, buf_ptr(full_type_name), ContainerLayoutExtern);
- TypeTableEntry *tag_type_entry = create_enum_tag_type(c->codegen, enum_type, tag_int_type);
- c->enum_type_table.put(bare_name, enum_type);
- c->decl_table.put(enum_decl, enum_type);
-
- enum_type->data.enumeration.gen_field_count = 0;
- enum_type->data.enumeration.complete = true;
- enum_type->data.enumeration.zero_bits_known = true;
- enum_type->data.enumeration.abi_alignment = 1;
- enum_type->data.enumeration.tag_type = tag_type_entry;
-
- enum_type->data.enumeration.src_field_count = field_count;
- enum_type->data.enumeration.fields = allocate<TypeEnumField>(field_count);
- ZigLLVMDIEnumerator **di_enumerators = allocate<ZigLLVMDIEnumerator*>(field_count);
+ AstNode *enum_node = trans_create_node(c, NodeTypeContainerDecl);
+ enum_node->data.container_decl.kind = ContainerKindEnum;
+ enum_node->data.container_decl.layout = ContainerLayoutExtern;
+ enum_node->data.container_decl.init_arg_expr = tag_int_type;
+ enum_node->data.container_decl.fields.resize(field_count);
uint32_t i = 0;
for (auto it = enum_def->enumerator_begin(),
it_end = enum_def->enumerator_end();
@@ -758,93 +1771,82 @@ static TypeTableEntry *resolve_enum_decl(Context *c, const EnumDecl *enum_decl)
Buf *enum_val_name = buf_create_from_str(decl_name(enum_const));
Buf *field_name;
- if (buf_starts_with_buf(enum_val_name, bare_name)) {
+ if (bare_name != nullptr && buf_starts_with_buf(enum_val_name, bare_name)) {
field_name = buf_slice(enum_val_name, buf_len(bare_name), buf_len(enum_val_name));
} else {
field_name = enum_val_name;
}
- TypeEnumField *type_enum_field = &enum_type->data.enumeration.fields[i];
- type_enum_field->name = field_name;
- type_enum_field->type_entry = c->codegen->builtin_types.entry_void;
- type_enum_field->value = i;
-
- di_enumerators[i] = ZigLLVMCreateDebugEnumerator(c->codegen->dbuilder, buf_ptr(type_enum_field->name), i);
-
+ AstNode *field_node = trans_create_node(c, NodeTypeStructField);
+ field_node->data.struct_field.name = field_name;
+ field_node->data.struct_field.type = nullptr;
+ enum_node->data.container_decl.fields.items[i] = field_node;
// in C each enum value is in the global namespace. so we put them there too.
// at this point we can rely on the enum emitting successfully
- add_global(c, create_global_num_lit_unsigned_negative(c, enum_val_name, i, false));
+ AstNode *field_access_node = trans_create_node_field_access(c,
+ trans_create_node_symbol(c, full_type_name), field_name);
+ add_global_var(c, enum_val_name, field_access_node);
}
- // create llvm type for root struct
- enum_type->type_ref = tag_type_entry->type_ref;
-
- enum_type->data.enumeration.abi_alignment = LLVMABIAlignmentOfType(c->codegen->target_data_ref,
- enum_type->type_ref);
-
- // create debug type for tag
- unsigned line = c->source_node ? (c->source_node->line + 1) : 0;
- uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(c->codegen->target_data_ref, enum_type->type_ref);
- uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(c->codegen->target_data_ref, enum_type->type_ref);
- ZigLLVMDIType *tag_di_type = ZigLLVMCreateDebugEnumerationType(c->codegen->dbuilder,
- ZigLLVMFileToScope(c->import->di_file), buf_ptr(bare_name),
- c->import->di_file, line,
- debug_size_in_bits,
- debug_align_in_bits,
- di_enumerators, field_count, tag_type_entry->di_type, "");
-
- ZigLLVMReplaceTemporary(c->codegen->dbuilder, enum_type->di_type, tag_di_type);
- enum_type->di_type = tag_di_type;
-
- return enum_type;
- } else {
- // TODO after issue #305 is solved, make this be an enum with tag_int_type
- // as the integer type and set the custom enum values
- TypeTableEntry *enum_type = tag_int_type;
- c->enum_type_table.put(bare_name, enum_type);
- c->decl_table.put(enum_decl, enum_type);
+ if (is_anonymous) {
+ c->decl_table.put(enum_decl->getCanonicalDecl(), enum_node);
+ return enum_node;
+ } else {
+ AstNode *symbol_node = trans_create_node_symbol(c, full_type_name);
+ add_global_weak_alias(c, bare_name, full_type_name);
+ add_global_var(c, full_type_name, enum_node);
+ c->decl_table.put(enum_decl->getCanonicalDecl(), symbol_node);
+ return enum_node;
+ }
+ }
- // add variables for all the values with enum_type
- for (auto it = enum_def->enumerator_begin(),
- it_end = enum_def->enumerator_end();
- it != it_end; ++it)
- {
- const EnumConstantDecl *enum_const = *it;
+ // TODO after issue #305 is solved, make this be an enum with tag_int_type
+ // as the integer type and set the custom enum values
+ AstNode *enum_node = tag_int_type;
- Buf *enum_val_name = buf_create_from_str(decl_name(enum_const));
- Tld *tld = create_global_num_lit_ap(c, enum_decl, enum_val_name, enum_const->getInitVal());
- if (!tld)
- return c->codegen->builtin_types.entry_invalid;
+ // add variables for all the values with enum_node
+ for (auto it = enum_def->enumerator_begin(),
+ it_end = enum_def->enumerator_end();
+ it != it_end; ++it)
+ {
+ const EnumConstantDecl *enum_const = *it;
- add_global(c, tld);
- }
+ Buf *enum_val_name = buf_create_from_str(decl_name(enum_const));
+ AstNode *int_node = trans_create_node_apint(c, enum_const->getInitVal());
+ AstNode *var_node = add_global_var(c, enum_val_name, int_node);
+ var_node->data.variable_declaration.type = tag_int_type;
+ }
- return enum_type;
+ if (is_anonymous) {
+ c->decl_table.put(enum_decl->getCanonicalDecl(), enum_node);
+ return enum_node;
+ } else {
+ AstNode *symbol_node = trans_create_node_symbol(c, full_type_name);
+ add_global_weak_alias(c, bare_name, full_type_name);
+ add_global_var(c, full_type_name, enum_node);
+ return symbol_node;
}
}
-static void visit_enum_decl(Context *c, const EnumDecl *enum_decl) {
- TypeTableEntry *enum_type = resolve_enum_decl(c, enum_decl);
-
- if (enum_type->id == TypeTableEntryIdInvalid)
- return;
-
- // make an alias without the "enum_" prefix. this will get emitted at the
- // end if it doesn't conflict with anything else
- bool is_anonymous = (decl_name(enum_decl)[0] == 0);
- if (is_anonymous)
- return;
-
- Buf *bare_name = buf_create_from_str(decl_name(enum_decl));
-
- Tld *tld = add_container_tld(c, enum_type);
- add_global_weak_alias(c, bare_name, tld);
+static AstNode *demote_struct_to_opaque(Context *c, const RecordDecl *record_decl,
+ Buf *full_type_name, Buf *bare_name)
+{
+ AstNode *opaque_node = trans_create_node_opaque(c);
+ if (full_type_name == nullptr) {
+ c->decl_table.put(record_decl->getCanonicalDecl(), opaque_node);
+ return opaque_node;
+ }
+ AstNode *symbol_node = trans_create_node_symbol(c, full_type_name);
+ add_global_weak_alias(c, bare_name, full_type_name);
+ add_global_var(c, full_type_name, opaque_node);
+ c->decl_table.put(record_decl->getCanonicalDecl(), symbol_node);
+ return symbol_node;
}
-static TypeTableEntry *resolve_record_decl(Context *c, const RecordDecl *record_decl) {
- auto existing_entry = c->decl_table.maybe_get((void*)record_decl);
+static AstNode *resolve_record_decl(Context *c, const RecordDecl *record_decl) {
+ auto existing_entry = c->decl_table.maybe_get((void*)record_decl->getCanonicalDecl());
if (existing_entry) {
return existing_entry->value;
}
@@ -852,36 +1854,20 @@ static TypeTableEntry *resolve_record_decl(Context *c, const RecordDecl *record_
const char *raw_name = decl_name(record_decl);
if (!record_decl->isStruct()) {
- emit_warning(c, record_decl, "skipping record %s, not a struct", raw_name);
- return c->codegen->builtin_types.entry_invalid;
- }
-
- Buf *bare_name;
- if (record_decl->isAnonymousStructOrUnion() || raw_name[0] == 0) {
- bare_name = buf_sprintf("anon_$%" PRIu32, get_next_anon_index(c));
- } else {
- bare_name = buf_create_from_str(raw_name);
+ emit_warning(c, record_decl->getLocation(), "skipping record %s, not a struct", raw_name);
+ c->decl_table.put(record_decl->getCanonicalDecl(), nullptr);
+ return nullptr;
}
- Buf *full_type_name = buf_sprintf("struct_%s", buf_ptr(bare_name));
-
-
- TypeTableEntry *struct_type = get_partial_container_type(c->codegen, &c->import->decls_scope->base,
- ContainerKindStruct, c->source_node, buf_ptr(full_type_name), ContainerLayoutExtern);
- struct_type->data.structure.zero_bits_known = true;
- struct_type->data.structure.abi_alignment = 1;
-
- c->struct_type_table.put(bare_name, struct_type);
- c->decl_table.put(record_decl, struct_type);
+ bool is_anonymous = record_decl->isAnonymousStructOrUnion() || raw_name[0] == 0;
+ Buf *bare_name = is_anonymous ? nullptr : buf_create_from_str(raw_name);
+ Buf *full_type_name = (bare_name == nullptr) ? nullptr : buf_sprintf("struct_%s", buf_ptr(bare_name));
RecordDecl *record_def = record_decl->getDefinition();
- unsigned line = c->source_node ? c->source_node->line : 0;
- if (!record_def) {
- replace_with_fwd_decl(c, struct_type, full_type_name);
- return struct_type;
+ if (record_def == nullptr) {
+ return demote_struct_to_opaque(c, record_decl, full_type_name, bare_name);
}
-
// count fields and validate
uint32_t field_count = 0;
for (auto it = record_def->field_begin(),
@@ -891,105 +1877,56 @@ static TypeTableEntry *resolve_record_decl(Context *c, const RecordDecl *record_
const FieldDecl *field_decl = *it;
if (field_decl->isBitField()) {
- emit_warning(c, field_decl, "struct %s demoted to opaque type - has bitfield\n", buf_ptr(bare_name));
- replace_with_fwd_decl(c, struct_type, full_type_name);
- return struct_type;
+ emit_warning(c, field_decl->getLocation(), "struct %s demoted to opaque type - has bitfield",
+ is_anonymous ? "(anon)" : buf_ptr(bare_name));
+ return demote_struct_to_opaque(c, record_decl, full_type_name, bare_name);
}
}
- struct_type->data.structure.src_field_count = field_count;
- struct_type->data.structure.fields = allocate<TypeStructField>(field_count);
- LLVMTypeRef *element_types = allocate<LLVMTypeRef>(field_count);
- ZigLLVMDIType **di_element_types = allocate<ZigLLVMDIType*>(field_count);
+ AstNode *struct_node = trans_create_node(c, NodeTypeContainerDecl);
+ struct_node->data.container_decl.kind = ContainerKindStruct;
+ struct_node->data.container_decl.layout = ContainerLayoutExtern;
- // next, populate element_types as its needed for LLVMStructSetBody which is needed for LLVMOffsetOfElement
- uint32_t i = 0;
- for (auto it = record_def->field_begin(),
- it_end = record_def->field_end();
- it != it_end; ++it, i += 1)
- {
- const FieldDecl *field_decl = *it;
+ // TODO handle attribute packed
- TypeStructField *type_struct_field = &struct_type->data.structure.fields[i];
- type_struct_field->name = buf_create_from_str(decl_name(field_decl));
- type_struct_field->src_index = i;
- type_struct_field->gen_index = i;
- TypeTableEntry *field_type = resolve_qual_type(c, field_decl->getType(), field_decl);
- type_struct_field->type_entry = field_type;
-
- if (type_is_invalid(field_type) || !type_is_complete(field_type)) {
- emit_warning(c, field_decl, "struct %s demoted to opaque type - unresolved type\n", buf_ptr(bare_name));
- replace_with_fwd_decl(c, struct_type, full_type_name);
- return struct_type;
- }
+ struct_node->data.container_decl.fields.resize(field_count);
- element_types[i] = field_type->type_ref;
- assert(element_types[i]);
+ // must be before fields in case a circular reference happens
+ if (is_anonymous) {
+ c->decl_table.put(record_decl->getCanonicalDecl(), struct_node);
+ } else {
+ c->decl_table.put(record_decl->getCanonicalDecl(), trans_create_node_symbol(c, full_type_name));
}
- LLVMStructSetBody(struct_type->type_ref, element_types, field_count, false);
-
- // finally populate debug info
- i = 0;
+ uint32_t i = 0;
for (auto it = record_def->field_begin(),
it_end = record_def->field_end();
it != it_end; ++it, i += 1)
{
- TypeStructField *type_struct_field = &struct_type->data.structure.fields[i];
- TypeTableEntry *field_type = type_struct_field->type_entry;
-
- uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(c->codegen->target_data_ref, field_type->type_ref);
- uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(c->codegen->target_data_ref, field_type->type_ref);
- uint64_t debug_offset_in_bits = 8*LLVMOffsetOfElement(c->codegen->target_data_ref, struct_type->type_ref, i);
- di_element_types[i] = ZigLLVMCreateDebugMemberType(c->codegen->dbuilder,
- ZigLLVMTypeToScope(struct_type->di_type), buf_ptr(type_struct_field->name),
- c->import->di_file, line + 1,
- debug_size_in_bits,
- debug_align_in_bits,
- debug_offset_in_bits,
- 0, field_type->di_type);
-
- assert(di_element_types[i]);
+ const FieldDecl *field_decl = *it;
- }
- struct_type->data.structure.embedded_in_current = false;
-
- struct_type->data.structure.gen_field_count = field_count;
- struct_type->data.structure.complete = true;
- struct_type->data.structure.abi_alignment = LLVMABIAlignmentOfType(c->codegen->target_data_ref,
- struct_type->type_ref);
-
- uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(c->codegen->target_data_ref, struct_type->type_ref);
- uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(c->codegen->target_data_ref, struct_type->type_ref);
- ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugStructType(c->codegen->dbuilder,
- ZigLLVMFileToScope(c->import->di_file),
- buf_ptr(full_type_name), c->import->di_file, line + 1,
- debug_size_in_bits,
- debug_align_in_bits,
- 0,
- nullptr, di_element_types, field_count, 0, nullptr, "");
-
- ZigLLVMReplaceTemporary(c->codegen->dbuilder, struct_type->di_type, replacement_di_type);
- struct_type->di_type = replacement_di_type;
-
- return struct_type;
-}
+ AstNode *field_node = trans_create_node(c, NodeTypeStructField);
+ field_node->data.struct_field.name = buf_create_from_str(decl_name(field_decl));
+ field_node->data.struct_field.type = trans_qual_type(c, field_decl->getType(), field_decl->getLocation());
-static void visit_record_decl(Context *c, const RecordDecl *record_decl) {
- TypeTableEntry *struct_type = resolve_record_decl(c, record_decl);
+ if (field_node->data.struct_field.type == nullptr) {
+ emit_warning(c, field_decl->getLocation(),
+ "struct %s demoted to opaque type - unresolved type",
+ is_anonymous ? "(anon)" : buf_ptr(bare_name));
- if (struct_type->id == TypeTableEntryIdInvalid) {
- return;
- }
-
- bool is_anonymous = (record_decl->isAnonymousStructOrUnion() || decl_name(record_decl)[0] == 0);
- if (is_anonymous)
- return;
+ return demote_struct_to_opaque(c, record_decl, full_type_name, bare_name);
+ }
- Buf *bare_name = buf_create_from_str(decl_name(record_decl));
+ struct_node->data.container_decl.fields.items[i] = field_node;
+ }
- Tld *tld = add_container_tld(c, struct_type);
- add_global_weak_alias(c, bare_name, tld);
+ if (is_anonymous) {
+ return struct_node;
+ } else {
+ add_global_weak_alias(c, bare_name, full_type_name);
+ add_global_var(c, full_type_name, struct_node);
+ return trans_create_node_symbol(c, full_type_name);
+ }
}
static void visit_var_decl(Context *c, const VarDecl *var_decl) {
@@ -999,17 +1936,19 @@ static void visit_var_decl(Context *c, const VarDecl *var_decl) {
case VarDecl::TLS_None:
break;
case VarDecl::TLS_Static:
- emit_warning(c, var_decl, "ignoring variable '%s' - static thread local storage\n", buf_ptr(name));
+ emit_warning(c, var_decl->getLocation(),
+ "ignoring variable '%s' - static thread local storage", buf_ptr(name));
return;
case VarDecl::TLS_Dynamic:
- emit_warning(c, var_decl, "ignoring variable '%s' - dynamic thread local storage\n", buf_ptr(name));
+ emit_warning(c, var_decl->getLocation(),
+ "ignoring variable '%s' - dynamic thread local storage", buf_ptr(name));
return;
}
QualType qt = var_decl->getType();
- TypeTableEntry *var_type = resolve_qual_type(c, qt, var_decl);
- if (var_type->id == TypeTableEntryIdInvalid) {
- emit_warning(c, var_decl, "ignoring variable '%s' - unresolved type\n", buf_ptr(name));
+ AstNode *var_type = trans_qual_type(c, qt, var_decl->getLocation());
+ if (var_type == nullptr) {
+ emit_warning(c, var_decl->getLocation(), "ignoring variable '%s' - unresolved type", buf_ptr(name));
return;
}
@@ -1018,59 +1957,53 @@ static void visit_var_decl(Context *c, const VarDecl *var_decl) {
bool is_const = qt.isConstQualified();
if (is_static && !is_extern) {
- if (!var_decl->hasInit()) {
- emit_warning(c, var_decl, "ignoring variable '%s' - no initializer\n", buf_ptr(name));
- return;
- }
- APValue *ap_value = var_decl->evaluateValue();
- if (!ap_value) {
- emit_warning(c, var_decl, "ignoring variable '%s' - unable to evaluate initializer\n", buf_ptr(name));
- return;
- }
- ConstExprValue *init_value = nullptr;
- switch (ap_value->getKind()) {
- case APValue::Int:
- {
- if (var_type->id != TypeTableEntryIdInt) {
- emit_warning(c, var_decl,
- "ignoring variable '%s' - int initializer for non int type\n", buf_ptr(name));
- return;
- }
- init_value = create_const_int_ap(c, var_type, var_decl, ap_value->getInt());
- if (!init_value)
- return;
-
- break;
- }
- case APValue::Uninitialized:
- case APValue::Float:
- case APValue::ComplexInt:
- case APValue::ComplexFloat:
- case APValue::LValue:
- case APValue::Vector:
- case APValue::Array:
- case APValue::Struct:
- case APValue::Union:
- case APValue::MemberPointer:
- case APValue::AddrLabelDiff:
- emit_warning(c, var_decl,
- "ignoring variable '%s' - unrecognized initializer value kind\n", buf_ptr(name));
+ AstNode *init_node;
+ if (var_decl->hasInit()) {
+ APValue *ap_value = var_decl->evaluateValue();
+ if (ap_value == nullptr) {
+ emit_warning(c, var_decl->getLocation(),
+ "ignoring variable '%s' - unable to evaluate initializer", buf_ptr(name));
return;
+ }
+ switch (ap_value->getKind()) {
+ case APValue::Int:
+ init_node = trans_create_node_apint(c, ap_value->getInt());
+ break;
+ case APValue::Uninitialized:
+ init_node = trans_create_node_symbol_str(c, "undefined");
+ break;
+ case APValue::Float:
+ case APValue::ComplexInt:
+ case APValue::ComplexFloat:
+ case APValue::LValue:
+ case APValue::Vector:
+ case APValue::Array:
+ case APValue::Struct:
+ case APValue::Union:
+ case APValue::MemberPointer:
+ case APValue::AddrLabelDiff:
+ emit_warning(c, var_decl->getLocation(),
+ "ignoring variable '%s' - unrecognized initializer value kind", buf_ptr(name));
+ return;
+ }
+ } else {
+ init_node = trans_create_node_symbol_str(c, "undefined");
}
- TldVar *tld_var = create_global_var(c, name, init_value, true);
- add_global(c, &tld_var->base);
+ AstNode *var_node = trans_create_node_var_decl(c, is_const, name, var_type, init_node);
+ c->root->data.root.top_level_decls.append(var_node);
return;
}
if (is_extern) {
- TldVar *tld_var = create_global_var(c, name, create_const_runtime(var_type), is_const);
- tld_var->var->linkage = VarLinkageExternal;
- add_global(c, &tld_var->base);
+ AstNode *var_node = trans_create_node_var_decl(c, is_const, name, var_type, nullptr);
+ var_node->data.variable_declaration.is_extern = true;
+ c->root->data.root.top_level_decls.append(var_node);
return;
}
- emit_warning(c, var_decl, "ignoring variable '%s' - non-extern, non-static variable\n", buf_ptr(name));
+ emit_warning(c, var_decl->getLocation(),
+ "ignoring variable '%s' - non-extern, non-static variable", buf_ptr(name));
return;
}
@@ -1082,44 +2015,35 @@ static bool decl_visitor(void *context, const Decl *decl) {
visit_fn_decl(c, static_cast<const FunctionDecl*>(decl));
break;
case Decl::Typedef:
- visit_typedef_decl(c, static_cast<const TypedefNameDecl *>(decl));
+ resolve_typedef_decl(c, static_cast<const TypedefNameDecl *>(decl));
break;
case Decl::Enum:
- visit_enum_decl(c, static_cast<const EnumDecl *>(decl));
+ resolve_enum_decl(c, static_cast<const EnumDecl *>(decl));
break;
case Decl::Record:
- visit_record_decl(c, static_cast<const RecordDecl *>(decl));
+ resolve_record_decl(c, static_cast<const RecordDecl *>(decl));
break;
case Decl::Var:
visit_var_decl(c, static_cast<const VarDecl *>(decl));
break;
default:
- emit_warning(c, decl, "ignoring %s decl\n", decl->getDeclKindName());
+ emit_warning(c, decl->getLocation(), "ignoring %s decl", decl->getDeclKindName());
}
return true;
}
static bool name_exists(Context *c, Buf *name) {
- if (c->global_type_table.maybe_get(name)) {
- return true;
- }
- if (get_global(c, name)) {
- return true;
- }
- if (c->macro_table.maybe_get(name)) {
- return true;
- }
- return false;
+ return get_global(c, name) != nullptr;
}
static void render_aliases(Context *c) {
for (size_t i = 0; i < c->aliases.length; i += 1) {
Alias *alias = &c->aliases.at(i);
- if (name_exists(c, alias->name))
+ if (name_exists(c, alias->new_name))
continue;
- add_global_alias(c, alias->name, alias->tld);
+ add_global_var(c, alias->new_name, trans_create_node_symbol(c, alias->canon_name));
}
}
@@ -1130,8 +2054,12 @@ static void render_macros(Context *c) {
if (!entry)
break;
- Tld *var_tld = entry->value;
- add_global(c, var_tld);
+ AstNode *value_node = entry->value;
+ if (value_node->type == NodeTypeFnDef) {
+ c->root->data.root.top_level_decls.append(value_node);
+ } else {
+ add_global_var(c, entry->key, value_node);
+ }
}
}
@@ -1150,52 +2078,52 @@ static void process_macro(Context *c, CTokenize *ctok, Buf *name, const char *ch
switch (tok->id) {
case CTokIdCharLit:
if (is_last && is_first) {
- Tld *tld = create_global_num_lit_unsigned_negative(c, name, tok->data.char_lit, false);
- c->macro_table.put(name, tld);
+ AstNode *node = trans_create_node_unsigned(c, tok->data.char_lit);
+ c->macro_table.put(name, node);
}
return;
case CTokIdStrLit:
if (is_last && is_first) {
- Tld *tld = create_global_str_lit_var(c, name, buf_create_from_buf(&tok->data.str_lit));
- c->macro_table.put(name, tld);
+ AstNode *node = trans_create_node_str_lit_c(c, buf_create_from_buf(&tok->data.str_lit));
+ c->macro_table.put(name, node);
}
return;
case CTokIdNumLitInt:
if (is_last) {
- Tld *tld;
+ AstNode *node;
switch (tok->data.num_lit_int.suffix) {
case CNumLitSuffixNone:
- tld = create_global_num_lit_unsigned_negative(c, name, tok->data.num_lit_int.x, negate);
+ node = trans_create_node_unsigned_negative(c, tok->data.num_lit_int.x, negate);
break;
case CNumLitSuffixL:
- tld = create_global_num_lit_unsigned_negative_type(c, name, tok->data.num_lit_int.x, negate,
- c->codegen->builtin_types.entry_c_int[CIntTypeLong]);
+ node = trans_create_node_unsigned_negative_type(c, tok->data.num_lit_int.x, negate,
+ "c_long");
break;
case CNumLitSuffixU:
- tld = create_global_num_lit_unsigned_negative_type(c, name, tok->data.num_lit_int.x, negate,
- c->codegen->builtin_types.entry_c_int[CIntTypeUInt]);
+ node = trans_create_node_unsigned_negative_type(c, tok->data.num_lit_int.x, negate,
+ "c_uint");
break;
case CNumLitSuffixLU:
- tld = create_global_num_lit_unsigned_negative_type(c, name, tok->data.num_lit_int.x, negate,
- c->codegen->builtin_types.entry_c_int[CIntTypeULong]);
+ node = trans_create_node_unsigned_negative_type(c, tok->data.num_lit_int.x, negate,
+ "c_ulong");
break;
case CNumLitSuffixLL:
- tld = create_global_num_lit_unsigned_negative_type(c, name, tok->data.num_lit_int.x, negate,
- c->codegen->builtin_types.entry_c_int[CIntTypeLongLong]);
+ node = trans_create_node_unsigned_negative_type(c, tok->data.num_lit_int.x, negate,
+ "c_longlong");
break;
case CNumLitSuffixLLU:
- tld = create_global_num_lit_unsigned_negative_type(c, name, tok->data.num_lit_int.x, negate,
- c->codegen->builtin_types.entry_c_int[CIntTypeULongLong]);
+ node = trans_create_node_unsigned_negative_type(c, tok->data.num_lit_int.x, negate,
+ "c_ulonglong");
break;
}
- c->macro_table.put(name, tld);
+ c->macro_table.put(name, node);
}
return;
case CTokIdNumLitFloat:
if (is_last) {
double value = negate ? -tok->data.num_lit_float : tok->data.num_lit_float;
- Tld *tld = create_global_num_lit_float(c, name, value);
- c->macro_table.put(name, tld);
+ AstNode *node = trans_create_node_float_lit(c, value);
+ c->macro_table.put(name, node);
}
return;
case CTokIdSymbol:
@@ -1224,35 +2152,37 @@ static void process_symbol_macros(Context *c) {
for (size_t i = 0; i < c->macro_symbols.length; i += 1) {
MacroSymbol ms = c->macro_symbols.at(i);
- // If this macro aliases another top level declaration, we can make that happen by
- // putting another entry in the decl table pointing to the same top level decl.
- Tld *existing_tld = get_global(c, ms.value);
- if (!existing_tld)
+ // Check if this macro aliases another top level declaration
+ AstNode *existing_node = get_global(c, ms.value);
+ if (!existing_node || name_exists(c, ms.name))
continue;
// If a macro aliases a global variable which is a function pointer, we conclude that
// the macro is intended to represent a function that assumes the function pointer
// variable is non-null and calls it.
- if (existing_tld->id == TldIdVar) {
- TldVar *tld_var = (TldVar *)existing_tld;
- TypeTableEntry *var_type = tld_var->var->value->type;
- if (var_type->id == TypeTableEntryIdMaybe && !tld_var->var->src_is_const) {
- TypeTableEntry *child_type = var_type->data.maybe.child_type;
- if (child_type->id == TypeTableEntryIdFn) {
- Tld *tld = create_inline_fn_tld(c, ms.name, tld_var);
- c->macro_table.put(ms.name, tld);
+ if (existing_node->type == NodeTypeVariableDeclaration) {
+ AstNode *var_type = existing_node->data.variable_declaration.type;
+ if (var_type != nullptr && var_type->type == NodeTypePrefixOpExpr &&
+ var_type->data.prefix_op_expr.prefix_op == PrefixOpMaybe)
+ {
+ AstNode *fn_proto_node = var_type->data.prefix_op_expr.primary_expr;
+ if (fn_proto_node->type == NodeTypeFnProto) {
+ AstNode *inline_fn_node = trans_create_node_inline_fn(c, ms.name, ms.value, fn_proto_node);
+ c->macro_table.put(ms.name, inline_fn_node);
continue;
}
}
}
- add_global_alias(c, ms.name, existing_tld);
+ add_global_var(c, ms.name, trans_create_node_symbol(c, ms.value));
}
}
static void process_preprocessor_entities(Context *c, ASTUnit &unit) {
CTokenize ctok = {{0}};
+ // TODO if we see #undef, delete it from the table
+
for (PreprocessedEntity *entity : unit.getLocalPreprocessingEntities()) {
switch (entity->getKind()) {
case PreprocessedEntity::InvalidKind:
@@ -1309,9 +2239,6 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const ch
c->import = import;
c->errors = errors;
c->visib_mod = VisibModPub;
- c->global_type_table.init(8);
- c->enum_type_table.init(8);
- c->struct_type_table.init(8);
c->decl_table.init(8);
c->macro_table.init(8);
c->codegen = codegen;
@@ -1373,7 +2300,7 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const ch
std::shared_ptr<PCHContainerOperations> pch_container_ops = std::make_shared<PCHContainerOperations>();
- bool skip_function_bodies = true;
+ bool skip_function_bodies = false;
bool only_local_decls = true;
bool capture_diagnostics = true;
bool user_files_are_volatile = true;
@@ -1390,7 +2317,6 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const ch
single_file_parse, user_files_are_volatile, for_serialization, None, &err_unit,
nullptr));
-
// Early failures in LoadFromCommandLine may return with ErrUnit unset.
if (!ast_unit && !err_unit) {
return ErrorFileSystem;
@@ -1416,39 +2342,48 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const ch
break;
}
StringRef msg_str_ref = it->getMessage();
- FullSourceLoc fsl = it->getLocation();
- FileID file_id = fsl.getFileID();
- StringRef filename = fsl.getManager().getFilename(fsl);
- unsigned line = fsl.getSpellingLineNumber() - 1;
- unsigned column = fsl.getSpellingColumnNumber() - 1;
- unsigned offset = fsl.getManager().getFileOffset(fsl);
- const char *source = (const char *)fsl.getManager().getBufferData(file_id).bytes_begin();
Buf *msg = buf_create_from_str((const char *)msg_str_ref.bytes_begin());
- Buf *path;
- if (filename.empty()) {
- path = buf_alloc();
- } else {
- path = buf_create_from_mem((const char *)filename.bytes_begin(), filename.size());
- }
+ FullSourceLoc fsl = it->getLocation();
+ if (fsl.hasManager()) {
+ FileID file_id = fsl.getFileID();
+ StringRef filename = fsl.getManager().getFilename(fsl);
+ unsigned line = fsl.getSpellingLineNumber() - 1;
+ unsigned column = fsl.getSpellingColumnNumber() - 1;
+ unsigned offset = fsl.getManager().getFileOffset(fsl);
+ const char *source = (const char *)fsl.getManager().getBufferData(file_id).bytes_begin();
+ Buf *path;
+ if (filename.empty()) {
+ path = buf_alloc();
+ } else {
+ path = buf_create_from_mem((const char *)filename.bytes_begin(), filename.size());
+ }
- ErrorMsg *err_msg = err_msg_create_with_offset(path, line, column, offset, source, msg);
+ ErrorMsg *err_msg = err_msg_create_with_offset(path, line, column, offset, source, msg);
- c->errors->append(err_msg);
+ c->errors->append(err_msg);
+ } else {
+ // NOTE the only known way this gets triggered right now is if you have a lot of errors
+ // clang emits "too many errors emitted, stopping now"
+ fprintf(stderr, "unexpected error from clang: %s\n", buf_ptr(msg));
+ }
}
return 0;
}
+ c->ctx = &ast_unit->getASTContext();
c->source_manager = &ast_unit->getSourceManager();
+ c->root = trans_create_node(c, NodeTypeRoot);
ast_unit->visitLocalTopLevelDecls(c, decl_visitor);
process_preprocessor_entities(c, *ast_unit);
process_symbol_macros(c);
-
render_macros(c);
render_aliases(c);
+ import->root = c->root;
+
return 0;
}