From 2c9bdad3462f356f4c2ed2442f2cd6de80b9805b Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Tue, 5 Sep 2017 22:55:03 -0400 Subject: rename parseh to parsec --- src/parseh.cpp | 2389 -------------------------------------------------------- 1 file changed, 2389 deletions(-) delete mode 100644 src/parseh.cpp (limited to 'src/parseh.cpp') diff --git a/src/parseh.cpp b/src/parseh.cpp deleted file mode 100644 index f7e0b909c7..0000000000 --- a/src/parseh.cpp +++ /dev/null @@ -1,2389 +0,0 @@ -/* - * Copyright (c) 2015 Andrew Kelley - * - * This file is part of zig, which is MIT licensed. - * See http://opensource.org/licenses/MIT - */ - -#include "all_types.hpp" -#include "analyze.hpp" -#include "c_tokenizer.hpp" -#include "config.h" -#include "error.hpp" -#include "ir.hpp" -#include "os.hpp" -#include "parseh.hpp" -#include "parser.hpp" - - -#include -#include -#include - -#include - -using namespace clang; - -struct MacroSymbol { - Buf *name; - Buf *value; -}; - -struct Alias { - Buf *new_name; - Buf *canon_name; -}; - -struct Context { - ImportTableEntry *import; - ZigList *errors; - bool warnings_on; - VisibMod visib_mod; - AstNode *root; - HashMap decl_table; - HashMap macro_table; - SourceManager *source_manager; - ZigList aliases; - ZigList macro_symbols; - AstNode *source_node; - - CodeGen *codegen; - ASTContext *ctx; -}; - -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 SourceLocation &sl, const char *format, ...) { - if (!c->warnings_on) { - return; - } - - va_list ap; - va_start(ap, format); - Buf *msg = buf_vprintf(format, ap); - va_end(ap); - - StringRef filename = c->source_manager->getFilename(sl); - const char *filename_bytes = (const char *)filename.bytes_begin(); - Buf *path; - if (filename_bytes) { - path = buf_create_from_str(filename_bytes); - } else { - path = buf_sprintf("(no file)"); - } - unsigned line = c->source_manager->getSpellingLineNumber(sl); - unsigned column = c->source_manager->getSpellingColumnNumber(sl); - fprintf(stderr, "%s:%u:%u: warning: %s\n", buf_ptr(path), line, column, buf_ptr(msg)); -} - -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 AstNode * trans_create_node(Context *c, NodeType id) { - AstNode *node = allocate(1); - node->type = id; - node->owner = c->import; - // TODO line/column. mapping to C file?? - return node; -} - -static AstNode *trans_create_node_float_lit(Context *c, double value) { - AstNode *node = trans_create_node(c, NodeTypeFloatLiteral); - node->data.float_literal.bigfloat = allocate(1); - bigfloat_init_64(node->data.float_literal.bigfloat, value); - return node; -} - -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 AstNode *trans_create_node_symbol_str(Context *c, const char *name) { - return trans_create_node_symbol(c, buf_create_from_str(name)); -} - -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 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 AstNode *trans_create_node_opaque(Context *c) { - return trans_create_node_builtin_fn_call_str(c, "OpaqueType"); -} - -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 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 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 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 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(1); - bigint_init_data(node->data.int_literal.bigint, &x, 1, is_negative); - return node; -} - -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) -{ - 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 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) -{ - 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 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; -} - -static const char *decl_name(const Decl *decl) { - const NamedDecl *named_decl = static_cast(decl); - return (const char *)named_decl->getName().bytes_begin(); -} - -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(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(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) { - if (qt.getTypePtr()->getTypeClass() == Type::Paren) { - const ParenType *paren_type = static_cast(qt.getTypePtr()); - if (paren_type->getInnerType()->getTypeClass() == Type::FunctionProto) { - return true; - } - } else if (qt.getTypePtr()->getTypeClass() == Type::Attributed) { - const AttributedType *attr_type = static_cast(qt.getTypePtr()); - return qual_type_child_is_fn_proto(attr_type->getEquivalentType()); - } - return false; -} - -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(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(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(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(ty); - switch (builtin_ty->getKind()) { - case BuiltinType::Void: - return trans_create_node_symbol_str(c, "c_void"); - case BuiltinType::Bool: - return trans_create_node_symbol_str(c, "bool"); - case BuiltinType::Char_U: - case BuiltinType::UChar: - case BuiltinType::Char_S: - return trans_create_node_symbol_str(c, "u8"); - case BuiltinType::SChar: - return trans_create_node_symbol_str(c, "i8"); - case BuiltinType::UShort: - return trans_create_node_symbol_str(c, "c_ushort"); - case BuiltinType::UInt: - return trans_create_node_symbol_str(c, "c_uint"); - case BuiltinType::ULong: - return trans_create_node_symbol_str(c, "c_ulong"); - case BuiltinType::ULongLong: - return trans_create_node_symbol_str(c, "c_ulonglong"); - case BuiltinType::Short: - return trans_create_node_symbol_str(c, "c_short"); - case BuiltinType::Int: - return trans_create_node_symbol_str(c, "c_int"); - case BuiltinType::Long: - return trans_create_node_symbol_str(c, "c_long"); - case BuiltinType::LongLong: - 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 trans_create_node_symbol_str(c, "f32"); - case BuiltinType::Double: - return trans_create_node_symbol_str(c, "f64"); - case BuiltinType::Float128: - return trans_create_node_symbol_str(c, "f128"); - case BuiltinType::LongDouble: - return trans_create_node_symbol_str(c, "c_longdouble"); - case BuiltinType::WChar_U: - case BuiltinType::Char16: - case BuiltinType::Char32: - case BuiltinType::WChar_S: - case BuiltinType::Half: - case BuiltinType::NullPtr: - case BuiltinType::ObjCId: - case BuiltinType::ObjCClass: - case BuiltinType::ObjCSel: - case BuiltinType::OMPArraySection: - case BuiltinType::Dependent: - case BuiltinType::Overload: - case BuiltinType::BoundMember: - case BuiltinType::PseudoObject: - case BuiltinType::UnknownAny: - case BuiltinType::BuiltinFn: - case BuiltinType::ARCUnbridgedCast: - - case BuiltinType::OCLImage1dRO: - case BuiltinType::OCLImage1dArrayRO: - case BuiltinType::OCLImage1dBufferRO: - case BuiltinType::OCLImage2dRO: - case BuiltinType::OCLImage2dArrayRO: - case BuiltinType::OCLImage2dDepthRO: - case BuiltinType::OCLImage2dArrayDepthRO: - case BuiltinType::OCLImage2dMSAARO: - case BuiltinType::OCLImage2dArrayMSAARO: - case BuiltinType::OCLImage2dMSAADepthRO: - case BuiltinType::OCLImage2dArrayMSAADepthRO: - case BuiltinType::OCLImage3dRO: - case BuiltinType::OCLImage1dWO: - case BuiltinType::OCLImage1dArrayWO: - case BuiltinType::OCLImage1dBufferWO: - case BuiltinType::OCLImage2dWO: - case BuiltinType::OCLImage2dArrayWO: - case BuiltinType::OCLImage2dDepthWO: - case BuiltinType::OCLImage2dArrayDepthWO: - case BuiltinType::OCLImage2dMSAAWO: - case BuiltinType::OCLImage2dArrayMSAAWO: - case BuiltinType::OCLImage2dMSAADepthWO: - case BuiltinType::OCLImage2dArrayMSAADepthWO: - case BuiltinType::OCLImage3dWO: - case BuiltinType::OCLImage1dRW: - case BuiltinType::OCLImage1dArrayRW: - case BuiltinType::OCLImage1dBufferRW: - case BuiltinType::OCLImage2dRW: - case BuiltinType::OCLImage2dArrayRW: - case BuiltinType::OCLImage2dDepthRW: - case BuiltinType::OCLImage2dArrayDepthRW: - case BuiltinType::OCLImage2dMSAARW: - case BuiltinType::OCLImage2dArrayMSAARW: - case BuiltinType::OCLImage2dMSAADepthRW: - case BuiltinType::OCLImage2dArrayMSAADepthRW: - case BuiltinType::OCLImage3dRW: - case BuiltinType::OCLSampler: - case BuiltinType::OCLEvent: - case BuiltinType::OCLClkEvent: - case BuiltinType::OCLQueue: - case BuiltinType::OCLReserveID: - emit_warning(c, source_loc, "unsupported builtin type"); - return nullptr; - } - break; - } - case Type::Pointer: - { - const PointerType *pointer_ty = static_cast(ty); - QualType child_qt = pointer_ty->getPointeeType(); - 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 trans_create_node_prefix_op(c, PrefixOpMaybe, child_node); - } - - 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(ty); - const TypedefNameDecl *typedef_decl = typedef_ty->getDecl(); - return resolve_typedef_decl(c, typedef_decl); - } - case Type::Elaborated: - { - const ElaboratedType *elaborated_ty = static_cast(ty); - switch (elaborated_ty->getKeyword()) { - case ETK_Struct: - return trans_qual_type_with_table(c, elaborated_ty->getNamedType(), source_loc); - case ETK_Enum: - 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, source_loc, "unsupported elaborated type"); - return nullptr; - } - } - case Type::FunctionProto: - { - const FunctionProtoType *fn_proto_ty = static_cast(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)) - proto_node->data.fn_proto.cc = CallingConventionStdcall; - break; - case CC_X86FastCall: // __attribute__((fastcall)) - emit_warning(c, source_loc, "unsupported calling convention: x86 fastcall"); - return nullptr; - case CC_X86ThisCall: // __attribute__((thiscall)) - emit_warning(c, source_loc, "unsupported calling convention: x86 thiscall"); - return nullptr; - case CC_X86VectorCall: // __attribute__((vectorcall)) - emit_warning(c, source_loc, "unsupported calling convention: x86 vectorcall"); - return nullptr; - case CC_X86Pascal: // __attribute__((pascal)) - emit_warning(c, source_loc, "unsupported calling convention: x86 pascal"); - return nullptr; - case CC_Win64: // __attribute__((ms_abi)) - emit_warning(c, source_loc, "unsupported calling convention: win64"); - return nullptr; - case CC_X86_64SysV: // __attribute__((sysv_abi)) - emit_warning(c, source_loc, "unsupported calling convention: x86 64sysv"); - return nullptr; - case CC_X86RegCall: - emit_warning(c, source_loc, "unsupported calling convention: x86 reg"); - return nullptr; - case CC_AAPCS: // __attribute__((pcs("aapcs"))) - emit_warning(c, source_loc, "unsupported calling convention: aapcs"); - return nullptr; - case CC_AAPCS_VFP: // __attribute__((pcs("aapcs-vfp"))) - emit_warning(c, source_loc, "unsupported calling convention: aapcs-vfp"); - return nullptr; - case CC_IntelOclBicc: // __attribute__((intel_ocl_bicc)) - 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, source_loc, "unsupported calling convention: SPIR function"); - return nullptr; - case CC_OpenCLKernel: - emit_warning(c, source_loc, "unsupported calling convention: OpenCLKernel"); - return nullptr; - case CC_Swift: - emit_warning(c, source_loc, "unsupported calling convention: Swift"); - return nullptr; - case CC_PreserveMost: - emit_warning(c, source_loc, "unsupported calling convention: PreserveMost"); - return nullptr; - case CC_PreserveAll: - emit_warning(c, source_loc, "unsupported calling convention: PreserveAll"); - return nullptr; - } - - 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()) { - proto_node->data.fn_proto.return_type = trans_create_node_symbol_str(c, "noreturn"); - } else { - 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(proto_node->data.fn_proto.return_type)) { - proto_node->data.fn_proto.return_type = nullptr; - } - } - - //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); - AstNode *param_type_node = trans_qual_type(c, qt, source_loc); - - if (param_type_node == nullptr) { - emit_warning(c, source_loc, "unresolved function proto parameter type"); - return nullptr; - } - - 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 proto_node; - } - case Type::Record: - { - const RecordType *record_ty = static_cast(ty); - return resolve_record_decl(c, record_ty->getDecl()); - } - case Type::Enum: - { - const EnumType *enum_ty = static_cast(ty); - return resolve_enum_decl(c, enum_ty->getDecl()); - } - case Type::ConstantArray: - { - const ConstantArrayType *const_arr_ty = static_cast(ty); - 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(); - 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(ty); - return trans_qual_type(c, paren_ty->getInnerType(), source_loc); - } - case Type::Decayed: - { - const DecayedType *decayed_ty = static_cast(ty); - return trans_qual_type(c, decayed_ty->getDecayedType(), source_loc); - } - case Type::Attributed: - { - const AttributedType *attributed_ty = static_cast(ty); - return trans_qual_type(c, attributed_ty->getEquivalentType(), source_loc); - } - case Type::BlockPointer: - case Type::LValueReference: - case Type::RValueReference: - case Type::MemberPointer: - case Type::IncompleteArray: - case Type::VariableArray: - case Type::DependentSizedArray: - case Type::DependentSizedExtVector: - case Type::Vector: - case Type::ExtVector: - case Type::FunctionNoProto: - case Type::UnresolvedUsing: - case Type::Adjusted: - case Type::TypeOfExpr: - case Type::TypeOf: - case Type::Decltype: - case Type::UnaryTransform: - case Type::TemplateTypeParm: - case Type::SubstTemplateTypeParm: - case Type::SubstTemplateTypeParmPack: - case Type::TemplateSpecialization: - case Type::Auto: - case Type::InjectedClassName: - case Type::DependentName: - case Type::DependentTemplateSpecialization: - case Type::PackExpansion: - case Type::ObjCObject: - case Type::ObjCInterface: - case Type::Complex: - case Type::ObjCObjectPointer: - case Type::Atomic: - case Type::Pipe: - case Type::ObjCTypeParam: - case Type::DeducedTemplateSpecialization: - emit_warning(c, source_loc, "unsupported type: '%s'", ty->getTypeClassName()); - return nullptr; - } - zig_unreachable(); -} - -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 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) { - Buf *fn_name = buf_create_from_str(decl_name(fn_decl)); - - if (get_global(c, fn_name)) { - // we already saw this function - return; - } - - 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; - } - - proto_node->data.fn_proto.name = fn_name; - proto_node->data.fn_proto.is_extern = !fn_decl->hasBody(); - - 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; - } - - 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) { - 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 { - param_node->data.param_decl.name = buf_create_from_str(name); - } - } - - 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); - - 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 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")) { - 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 - - 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_global_var(c, type_name, type_node); - - AstNode *symbol_node = trans_create_node_symbol(c, type_name); - c->decl_table.put(typedef_decl, symbol_node); - return symbol_node; -} - -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 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); - 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) { - return demote_enum_to_opaque(c, enum_decl, full_type_name, bare_name); - } - - bool pure_enum = true; - uint32_t field_count = 0; - for (auto it = enum_def->enumerator_begin(), - it_end = enum_def->enumerator_end(); - it != it_end; ++it, field_count += 1) - { - const EnumConstantDecl *enum_const = *it; - if (enum_const->getInitExpr()) { - pure_enum = false; - } - } - - AstNode *tag_int_type = trans_qual_type(c, enum_decl->getIntegerType(), enum_decl->getLocation()); - assert(tag_int_type); - - if (pure_enum) { - 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(); - it != it_end; ++it, i += 1) - { - const EnumConstantDecl *enum_const = *it; - - Buf *enum_val_name = buf_create_from_str(decl_name(enum_const)); - Buf *field_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; - } - - 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 - 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); - } - - 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; - } - } - - // 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; - - - // 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; - - 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; - } - - 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 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 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; - } - - const char *raw_name = decl_name(record_decl); - - if (!record_decl->isStruct()) { - emit_warning(c, record_decl->getLocation(), "skipping record %s, not a struct", raw_name); - c->decl_table.put(record_decl->getCanonicalDecl(), nullptr); - return nullptr; - } - - 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(); - 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(), - it_end = record_def->field_end(); - it != it_end; ++it, field_count += 1) - { - const FieldDecl *field_decl = *it; - - if (field_decl->isBitField()) { - 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); - } - } - - AstNode *struct_node = trans_create_node(c, NodeTypeContainerDecl); - struct_node->data.container_decl.kind = ContainerKindStruct; - struct_node->data.container_decl.layout = ContainerLayoutExtern; - - // TODO handle attribute packed - - struct_node->data.container_decl.fields.resize(field_count); - - // 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)); - } - - 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; - - 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()); - - 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)); - - return demote_struct_to_opaque(c, record_decl, full_type_name, bare_name); - } - - struct_node->data.container_decl.fields.items[i] = field_node; - } - - 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) { - Buf *name = buf_create_from_str(decl_name(var_decl)); - - switch (var_decl->getTLSKind()) { - case VarDecl::TLS_None: - break; - case VarDecl::TLS_Static: - 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->getLocation(), - "ignoring variable '%s' - dynamic thread local storage", buf_ptr(name)); - return; - } - - QualType qt = var_decl->getType(); - 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; - } - - bool is_extern = var_decl->hasExternalStorage(); - bool is_static = var_decl->isFileVarDecl(); - bool is_const = qt.isConstQualified(); - - if (is_static && !is_extern) { - 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"); - } - - 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) { - 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->getLocation(), - "ignoring variable '%s' - non-extern, non-static variable", buf_ptr(name)); - return; -} - -static bool decl_visitor(void *context, const Decl *decl) { - Context *c = (Context*)context; - - switch (decl->getKind()) { - case Decl::Function: - visit_fn_decl(c, static_cast(decl)); - break; - case Decl::Typedef: - resolve_typedef_decl(c, static_cast(decl)); - break; - case Decl::Enum: - resolve_enum_decl(c, static_cast(decl)); - break; - case Decl::Record: - resolve_record_decl(c, static_cast(decl)); - break; - case Decl::Var: - visit_var_decl(c, static_cast(decl)); - break; - default: - emit_warning(c, decl->getLocation(), "ignoring %s decl", decl->getDeclKindName()); - } - - return true; -} - -static bool name_exists(Context *c, Buf *name) { - 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->new_name)) - continue; - - add_global_var(c, alias->new_name, trans_create_node_symbol(c, alias->canon_name)); - } -} - -static void render_macros(Context *c) { - auto it = c->macro_table.entry_iterator(); - for (;;) { - auto *entry = it.next(); - if (!entry) - break; - - 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); - } - } -} - -static void process_macro(Context *c, CTokenize *ctok, Buf *name, const char *char_ptr) { - tokenize_c_macro(ctok, (const uint8_t *)char_ptr); - - if (ctok->error) { - return; - } - - bool negate = false; - for (size_t i = 0; i < ctok->tokens.length; i += 1) { - bool is_first = (i == 0); - bool is_last = (i == ctok->tokens.length - 1); - CTok *tok = &ctok->tokens.at(i); - switch (tok->id) { - case CTokIdCharLit: - if (is_last && is_first) { - 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) { - 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) { - AstNode *node; - switch (tok->data.num_lit_int.suffix) { - case CNumLitSuffixNone: - node = trans_create_node_unsigned_negative(c, tok->data.num_lit_int.x, negate); - break; - case CNumLitSuffixL: - node = trans_create_node_unsigned_negative_type(c, tok->data.num_lit_int.x, negate, - "c_long"); - break; - case CNumLitSuffixU: - node = trans_create_node_unsigned_negative_type(c, tok->data.num_lit_int.x, negate, - "c_uint"); - break; - case CNumLitSuffixLU: - node = trans_create_node_unsigned_negative_type(c, tok->data.num_lit_int.x, negate, - "c_ulong"); - break; - case CNumLitSuffixLL: - node = trans_create_node_unsigned_negative_type(c, tok->data.num_lit_int.x, negate, - "c_longlong"); - break; - case CNumLitSuffixLLU: - node = trans_create_node_unsigned_negative_type(c, tok->data.num_lit_int.x, negate, - "c_ulonglong"); - break; - } - 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; - AstNode *node = trans_create_node_float_lit(c, value); - c->macro_table.put(name, node); - } - return; - case CTokIdSymbol: - if (is_last && is_first) { - // if it equals itself, ignore. for example, from stdio.h: - // #define stdin stdin - Buf *symbol_name = buf_create_from_buf(&tok->data.symbol); - if (buf_eql_buf(name, symbol_name)) { - return; - } - c->macro_symbols.append({name, symbol_name}); - return; - } - case CTokIdMinus: - if (is_first) { - negate = true; - break; - } else { - return; - } - } - } -} - -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); - - // 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_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_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: - case PreprocessedEntity::InclusionDirectiveKind: - case PreprocessedEntity::MacroExpansionKind: - continue; - case PreprocessedEntity::MacroDefinitionKind: - { - MacroDefinitionRecord *macro = static_cast(entity); - const char *raw_name = macro->getName()->getNameStart(); - SourceRange range = macro->getSourceRange(); - SourceLocation begin_loc = range.getBegin(); - SourceLocation end_loc = range.getEnd(); - - if (begin_loc == end_loc) { - // this means it is a macro without a value - // we don't care about such things - continue; - } - Buf *name = buf_create_from_str(raw_name); - if (name_exists(c, name)) { - continue; - } - - const char *end_c = c->source_manager->getCharacterData(end_loc); - process_macro(c, &ctok, name, end_c); - } - } - } -} - -int parse_h_buf(ImportTableEntry *import, ZigList *errors, Buf *source, - CodeGen *codegen, AstNode *source_node) -{ - int err; - Buf tmp_file_path = BUF_INIT; - if ((err = os_buf_to_tmp_file(source, buf_create_from_str(".h"), &tmp_file_path))) { - return err; - } - - err = parse_h_file(import, errors, buf_ptr(&tmp_file_path), codegen, source_node); - - os_delete_file(&tmp_file_path); - - return err; -} - -int parse_h_file(ImportTableEntry *import, ZigList *errors, const char *target_file, - CodeGen *codegen, AstNode *source_node) -{ - Context context = {0}; - Context *c = &context; - c->warnings_on = codegen->verbose; - c->import = import; - c->errors = errors; - c->visib_mod = VisibModPub; - c->decl_table.init(8); - c->macro_table.init(8); - c->codegen = codegen; - c->source_node = source_node; - - ZigList clang_argv = {0}; - - clang_argv.append("-x"); - clang_argv.append("c"); - - if (c->codegen->is_native_target) { - char *ZIG_PARSEH_CFLAGS = getenv("ZIG_NATIVE_PARSEH_CFLAGS"); - if (ZIG_PARSEH_CFLAGS) { - Buf tmp_buf = BUF_INIT; - char *start = ZIG_PARSEH_CFLAGS; - char *space = strstr(start, " "); - while (space) { - if (space - start > 0) { - buf_init_from_mem(&tmp_buf, start, space - start); - clang_argv.append(buf_ptr(buf_create_from_buf(&tmp_buf))); - } - start = space + 1; - space = strstr(start, " "); - } - buf_init_from_str(&tmp_buf, start); - clang_argv.append(buf_ptr(buf_create_from_buf(&tmp_buf))); - } - } - - clang_argv.append("-isystem"); - clang_argv.append(ZIG_HEADERS_DIR); - - clang_argv.append("-isystem"); - clang_argv.append(buf_ptr(codegen->libc_include_dir)); - - for (size_t i = 0; i < codegen->clang_argv_len; i += 1) { - clang_argv.append(codegen->clang_argv[i]); - } - - // we don't need spell checking and it slows things down - clang_argv.append("-fno-spell-checking"); - - // this gives us access to preprocessing entities, presumably at - // the cost of performance - clang_argv.append("-Xclang"); - clang_argv.append("-detailed-preprocessing-record"); - - if (!c->codegen->is_native_target) { - clang_argv.append("-target"); - clang_argv.append(buf_ptr(&c->codegen->triple_str)); - } - - clang_argv.append(target_file); - - // to make the [start...end] argument work - clang_argv.append(nullptr); - - IntrusiveRefCntPtr diags(CompilerInstance::createDiagnostics(new DiagnosticOptions)); - - std::shared_ptr pch_container_ops = std::make_shared(); - - bool skip_function_bodies = false; - bool only_local_decls = true; - bool capture_diagnostics = true; - bool user_files_are_volatile = true; - bool allow_pch_with_compiler_errors = false; - bool single_file_parse = false; - bool for_serialization = false; - const char *resources_path = ZIG_HEADERS_DIR; - std::unique_ptr err_unit; - std::unique_ptr ast_unit(ASTUnit::LoadFromCommandLine( - &clang_argv.at(0), &clang_argv.last(), - pch_container_ops, diags, resources_path, - only_local_decls, capture_diagnostics, None, true, 0, TU_Complete, - false, false, allow_pch_with_compiler_errors, skip_function_bodies, - 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; - } - - if (diags->getClient()->getNumErrors() > 0) { - if (ast_unit) { - err_unit = std::move(ast_unit); - } - - for (ASTUnit::stored_diag_iterator it = err_unit->stored_diag_begin(), - it_end = err_unit->stored_diag_end(); - it != it_end; ++it) - { - switch (it->getLevel()) { - case DiagnosticsEngine::Ignored: - case DiagnosticsEngine::Note: - case DiagnosticsEngine::Remark: - case DiagnosticsEngine::Warning: - continue; - case DiagnosticsEngine::Error: - case DiagnosticsEngine::Fatal: - break; - } - StringRef msg_str_ref = it->getMessage(); - Buf *msg = buf_create_from_str((const char *)msg_str_ref.bytes_begin()); - 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); - - 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; -} -- cgit v1.2.3