translate-c: progress on self-hosted function prototypes

See #1964
This commit is contained in:
Andrew Kelley 2019-05-09 16:52:30 -04:00
parent 214625587c
commit eea2de108d
No known key found for this signature in database
GPG Key ID: 7C5F548F728501A9
5 changed files with 730 additions and 766 deletions

File diff suppressed because it is too large Load Diff

View File

@ -11,6 +11,15 @@ pub const Mode = enum {
translate,
};
// TODO merge with Type.Fn.CallingConvention
pub const CallingConvention = enum {
auto,
c,
cold,
naked,
stdcall,
};
pub const ClangErrMsg = Stage2ErrorMsg;
pub const Error = error{
@ -165,9 +174,95 @@ fn transQualType(c: *Context, qt: ZigClangQualType, source_loc: ZigClangSourceLo
}
fn transType(c: *Context, ty: *const ZigClangType, source_loc: ZigClangSourceLocation) !*ast.Node {
switch (ZigClangType_getTypeClass(ty)) {
.Builtin => {
const builtin_ty = @ptrCast(*const ZigClangBuiltinType, ty);
switch (ZigClangBuiltinType_getKind(builtin_ty)) {
else => {
try emitWarning(c, source_loc, "unsupported builtin type");
return error.UnsupportedType;
},
}
},
.FunctionProto => {
const fn_ty = @ptrCast(*const ZigClangFunctionType, ty);
const cc = switch (ZigClangFunctionType_getCallConv(fn_ty)) {
.C => CallingConvention.c,
.X86StdCall => CallingConvention.stdcall,
.X86FastCall => {
try emitWarning(c, source_loc, "unsupported calling convention: x86 fastcall");
return error.UnsupportedType;
},
.X86ThisCall => {
try emitWarning(c, source_loc, "unsupported calling convention: x86 thiscall");
return error.UnsupportedType;
},
.X86VectorCall => {
try emitWarning(c, source_loc, "unsupported calling convention: x86 vectorcall");
return error.UnsupportedType;
},
.X86Pascal => {
try emitWarning(c, source_loc, "unsupported calling convention: x86 pascal");
return error.UnsupportedType;
},
.Win64 => {
try emitWarning(c, source_loc, "unsupported calling convention: win64");
return error.UnsupportedType;
},
.X86_64SysV => {
try emitWarning(c, source_loc, "unsupported calling convention: x86 64sysv");
return error.UnsupportedType;
},
.X86RegCall => {
try emitWarning(c, source_loc, "unsupported calling convention: x86 reg");
return error.UnsupportedType;
},
.AAPCS => {
try emitWarning(c, source_loc, "unsupported calling convention: aapcs");
return error.UnsupportedType;
},
.AAPCS_VFP => {
try emitWarning(c, source_loc, "unsupported calling convention: aapcs-vfp");
return error.UnsupportedType;
},
.IntelOclBicc => {
try emitWarning(c, source_loc, "unsupported calling convention: intel_ocl_bicc");
return error.UnsupportedType;
},
.SpirFunction => {
try emitWarning(c, source_loc, "unsupported calling convention: SPIR function");
return error.UnsupportedType;
},
.OpenCLKernel => {
try emitWarning(c, source_loc, "unsupported calling convention: OpenCLKernel");
return error.UnsupportedType;
},
.Swift => {
try emitWarning(c, source_loc, "unsupported calling convention: Swift");
return error.UnsupportedType;
},
.PreserveMost => {
try emitWarning(c, source_loc, "unsupported calling convention: PreserveMost");
return error.UnsupportedType;
},
.PreserveAll => {
try emitWarning(c, source_loc, "unsupported calling convention: PreserveAll");
return error.UnsupportedType;
},
.AArch64VectorCall => {
try emitWarning(c, source_loc, "unsupported calling convention: AArch64VectorCall");
return error.UnsupportedType;
},
};
try emitWarning(c, source_loc, "TODO: implement transType for FunctionProto");
return error.UnsupportedType;
},
else => {
const type_name = c.str(ZigClangType_getTypeClassName(ty));
try emitWarning(c, source_loc, "unsupported type: '{}'", type_name);
return error.UnsupportedType;
},
}
}
fn emitWarning(c: *Context, loc: ZigClangSourceLocation, comptime format: []const u8, args: ...) !void {

View File

@ -1061,72 +1061,72 @@ static AstNode *trans_type(Context *c, const ZigClangType *ty, ZigClangSourceLoc
case ZigClangType_FunctionProto:
case ZigClangType_FunctionNoProto:
{
const clang::FunctionType *fn_ty = reinterpret_cast<const clang::FunctionType*>(ty);
const ZigClangFunctionType *fn_ty = reinterpret_cast<const ZigClangFunctionType*>(ty);
AstNode *proto_node = trans_create_node(c, NodeTypeFnProto);
switch (fn_ty->getCallConv()) {
case clang::CC_C: // __attribute__((cdecl))
switch (ZigClangFunctionType_getCallConv(fn_ty)) {
case ZigClangCallingConv_C: // __attribute__((cdecl))
proto_node->data.fn_proto.cc = CallingConventionC;
proto_node->data.fn_proto.is_extern = true;
break;
case clang::CC_X86StdCall: // __attribute__((stdcall))
case ZigClangCallingConv_X86StdCall: // __attribute__((stdcall))
proto_node->data.fn_proto.cc = CallingConventionStdcall;
break;
case clang::CC_X86FastCall: // __attribute__((fastcall))
case ZigClangCallingConv_X86FastCall: // __attribute__((fastcall))
emit_warning(c, source_loc, "unsupported calling convention: x86 fastcall");
return nullptr;
case clang::CC_X86ThisCall: // __attribute__((thiscall))
case ZigClangCallingConv_X86ThisCall: // __attribute__((thiscall))
emit_warning(c, source_loc, "unsupported calling convention: x86 thiscall");
return nullptr;
case clang::CC_X86VectorCall: // __attribute__((vectorcall))
case ZigClangCallingConv_X86VectorCall: // __attribute__((vectorcall))
emit_warning(c, source_loc, "unsupported calling convention: x86 vectorcall");
return nullptr;
case clang::CC_X86Pascal: // __attribute__((pascal))
case ZigClangCallingConv_X86Pascal: // __attribute__((pascal))
emit_warning(c, source_loc, "unsupported calling convention: x86 pascal");
return nullptr;
case clang::CC_Win64: // __attribute__((ms_abi))
case ZigClangCallingConv_Win64: // __attribute__((ms_abi))
emit_warning(c, source_loc, "unsupported calling convention: win64");
return nullptr;
case clang::CC_X86_64SysV: // __attribute__((sysv_abi))
case ZigClangCallingConv_X86_64SysV: // __attribute__((sysv_abi))
emit_warning(c, source_loc, "unsupported calling convention: x86 64sysv");
return nullptr;
case clang::CC_X86RegCall:
case ZigClangCallingConv_X86RegCall:
emit_warning(c, source_loc, "unsupported calling convention: x86 reg");
return nullptr;
case clang::CC_AAPCS: // __attribute__((pcs("aapcs")))
case ZigClangCallingConv_AAPCS: // __attribute__((pcs("aapcs")))
emit_warning(c, source_loc, "unsupported calling convention: aapcs");
return nullptr;
case clang::CC_AAPCS_VFP: // __attribute__((pcs("aapcs-vfp")))
case ZigClangCallingConv_AAPCS_VFP: // __attribute__((pcs("aapcs-vfp")))
emit_warning(c, source_loc, "unsupported calling convention: aapcs-vfp");
return nullptr;
case clang::CC_IntelOclBicc: // __attribute__((intel_ocl_bicc))
case ZigClangCallingConv_IntelOclBicc: // __attribute__((intel_ocl_bicc))
emit_warning(c, source_loc, "unsupported calling convention: intel_ocl_bicc");
return nullptr;
case clang::CC_SpirFunction: // default for OpenCL functions on SPIR target
case ZigClangCallingConv_SpirFunction: // default for OpenCL functions on SPIR target
emit_warning(c, source_loc, "unsupported calling convention: SPIR function");
return nullptr;
case clang::CC_OpenCLKernel:
case ZigClangCallingConv_OpenCLKernel:
emit_warning(c, source_loc, "unsupported calling convention: OpenCLKernel");
return nullptr;
case clang::CC_Swift:
case ZigClangCallingConv_Swift:
emit_warning(c, source_loc, "unsupported calling convention: Swift");
return nullptr;
case clang::CC_PreserveMost:
case ZigClangCallingConv_PreserveMost:
emit_warning(c, source_loc, "unsupported calling convention: PreserveMost");
return nullptr;
case clang::CC_PreserveAll:
case ZigClangCallingConv_PreserveAll:
emit_warning(c, source_loc, "unsupported calling convention: PreserveAll");
return nullptr;
case clang::CC_AArch64VectorCall:
case ZigClangCallingConv_AArch64VectorCall:
emit_warning(c, source_loc, "unsupported calling convention: AArch64VectorCall");
return nullptr;
}
if (fn_ty->getNoReturnAttr()) {
if (ZigClangFunctionType_getNoReturnAttr(fn_ty)) {
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, bitcast(fn_ty->getReturnType()),
source_loc);
proto_node->data.fn_proto.return_type = trans_qual_type(c,
ZigClangFunctionType_getReturnType(fn_ty), source_loc);
if (proto_node->data.fn_proto.return_type == nullptr) {
emit_warning(c, source_loc, "unsupported function proto return type");
return nullptr;

View File

@ -1193,6 +1193,49 @@ static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeBuiltinFn == clang::B
static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeARCUnbridgedCast == clang::BuiltinType::ARCUnbridgedCast, "");
static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeOMPArraySection == clang::BuiltinType::OMPArraySection, "");
void ZigClang_detect_enum_CallingConv(clang::CallingConv x) {
switch (x) {
case clang::CC_C:
case clang::CC_X86StdCall:
case clang::CC_X86FastCall:
case clang::CC_X86ThisCall:
case clang::CC_X86VectorCall:
case clang::CC_X86Pascal:
case clang::CC_Win64:
case clang::CC_X86_64SysV:
case clang::CC_X86RegCall:
case clang::CC_AAPCS:
case clang::CC_AAPCS_VFP:
case clang::CC_IntelOclBicc:
case clang::CC_SpirFunction:
case clang::CC_OpenCLKernel:
case clang::CC_Swift:
case clang::CC_PreserveMost:
case clang::CC_PreserveAll:
case clang::CC_AArch64VectorCall:
break;
}
}
static_assert((clang::CallingConv)ZigClangCallingConv_C == clang::CC_C, "");
static_assert((clang::CallingConv)ZigClangCallingConv_X86StdCall == clang::CC_X86StdCall, "");
static_assert((clang::CallingConv)ZigClangCallingConv_X86FastCall == clang::CC_X86FastCall, "");
static_assert((clang::CallingConv)ZigClangCallingConv_X86ThisCall == clang::CC_X86ThisCall, "");
static_assert((clang::CallingConv)ZigClangCallingConv_X86VectorCall == clang::CC_X86VectorCall, "");
static_assert((clang::CallingConv)ZigClangCallingConv_X86Pascal == clang::CC_X86Pascal, "");
static_assert((clang::CallingConv)ZigClangCallingConv_Win64 == clang::CC_Win64, "");
static_assert((clang::CallingConv)ZigClangCallingConv_X86_64SysV == clang::CC_X86_64SysV, "");
static_assert((clang::CallingConv)ZigClangCallingConv_X86RegCall == clang::CC_X86RegCall, "");
static_assert((clang::CallingConv)ZigClangCallingConv_AAPCS == clang::CC_AAPCS, "");
static_assert((clang::CallingConv)ZigClangCallingConv_AAPCS_VFP == clang::CC_AAPCS_VFP, "");
static_assert((clang::CallingConv)ZigClangCallingConv_IntelOclBicc == clang::CC_IntelOclBicc, "");
static_assert((clang::CallingConv)ZigClangCallingConv_SpirFunction == clang::CC_SpirFunction, "");
static_assert((clang::CallingConv)ZigClangCallingConv_OpenCLKernel == clang::CC_OpenCLKernel, "");
static_assert((clang::CallingConv)ZigClangCallingConv_Swift == clang::CC_Swift, "");
static_assert((clang::CallingConv)ZigClangCallingConv_PreserveMost == clang::CC_PreserveMost, "");
static_assert((clang::CallingConv)ZigClangCallingConv_PreserveAll == clang::CC_PreserveAll, "");
static_assert((clang::CallingConv)ZigClangCallingConv_AArch64VectorCall == clang::CC_AArch64VectorCall, "");
static_assert(sizeof(ZigClangSourceLocation) == sizeof(clang::SourceLocation), "");
static ZigClangSourceLocation bitcast(clang::SourceLocation src) {
@ -1693,3 +1736,18 @@ enum ZigClangBuiltinTypeKind ZigClangBuiltinType_getKind(const struct ZigClangBu
auto casted = reinterpret_cast<const clang::BuiltinType *>(self);
return (ZigClangBuiltinTypeKind)casted->getKind();
}
bool ZigClangFunctionType_getNoReturnAttr(const struct ZigClangFunctionType *self) {
auto casted = reinterpret_cast<const clang::FunctionType *>(self);
return casted->getNoReturnAttr();
}
enum ZigClangCallingConv ZigClangFunctionType_getCallConv(const struct ZigClangFunctionType *self) {
auto casted = reinterpret_cast<const clang::FunctionType *>(self);
return (ZigClangCallingConv)casted->getCallConv();
}
struct ZigClangQualType ZigClangFunctionType_getReturnType(const struct ZigClangFunctionType *self) {
auto casted = reinterpret_cast<const clang::FunctionType *>(self);
return bitcast(casted->getReturnType());
}

View File

@ -101,6 +101,7 @@ struct ZigClangUnaryOperator;
struct ZigClangValueDecl;
struct ZigClangVarDecl;
struct ZigClangWhileStmt;
struct ZigClangFunctionType;
enum ZigClangBO {
ZigClangBO_PtrMemD,
@ -678,6 +679,27 @@ enum ZigClangBuiltinTypeKind {
ZigClangBuiltinTypeOMPArraySection,
};
enum ZigClangCallingConv {
ZigClangCallingConv_C, // __attribute__((cdecl))
ZigClangCallingConv_X86StdCall, // __attribute__((stdcall))
ZigClangCallingConv_X86FastCall, // __attribute__((fastcall))
ZigClangCallingConv_X86ThisCall, // __attribute__((thiscall))
ZigClangCallingConv_X86VectorCall, // __attribute__((vectorcall))
ZigClangCallingConv_X86Pascal, // __attribute__((pascal))
ZigClangCallingConv_Win64, // __attribute__((ms_abi))
ZigClangCallingConv_X86_64SysV, // __attribute__((sysv_abi))
ZigClangCallingConv_X86RegCall, // __attribute__((regcall))
ZigClangCallingConv_AAPCS, // __attribute__((pcs("aapcs")))
ZigClangCallingConv_AAPCS_VFP, // __attribute__((pcs("aapcs-vfp")))
ZigClangCallingConv_IntelOclBicc, // __attribute__((intel_ocl_bicc))
ZigClangCallingConv_SpirFunction, // default for OpenCL functions on SPIR target
ZigClangCallingConv_OpenCLKernel, // inferred for OpenCL kernels
ZigClangCallingConv_Swift, // __attribute__((swiftcall))
ZigClangCallingConv_PreserveMost, // __attribute__((preserve_most))
ZigClangCallingConv_PreserveAll, // __attribute__((preserve_all))
ZigClangCallingConv_AArch64VectorCall, // __attribute__((aarch64_vector_pcs))
};
ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangSourceManager_getSpellingLoc(const struct ZigClangSourceManager *,
struct ZigClangSourceLocation Loc);
ZIG_EXTERN_C const char *ZigClangSourceManager_getFilename(const struct ZigClangSourceManager *,
@ -776,4 +798,8 @@ ZIG_EXTERN_C const struct ZigClangExpr *ZigClangAPValueLValueBase_dyn_cast_Expr(
ZIG_EXTERN_C enum ZigClangBuiltinTypeKind ZigClangBuiltinType_getKind(const struct ZigClangBuiltinType *self);
ZIG_EXTERN_C bool ZigClangFunctionType_getNoReturnAttr(const struct ZigClangFunctionType *self);
ZIG_EXTERN_C enum ZigClangCallingConv ZigClangFunctionType_getCallConv(const struct ZigClangFunctionType *self);
ZIG_EXTERN_C struct ZigClangQualType ZigClangFunctionType_getReturnType(const struct ZigClangFunctionType *self);
#endif