diff --git a/CMakeLists.txt b/CMakeLists.txt index db5f50908..b633e0197 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -429,6 +429,7 @@ set(BLAKE_SOURCES ) set(ZIG_CPP_SOURCES "${CMAKE_SOURCE_DIR}/src/zig_llvm.cpp" + "${CMAKE_SOURCE_DIR}/src/zig_clang.cpp" "${CMAKE_SOURCE_DIR}/src/windows_sdk.cpp" ) diff --git a/src/translate_c.cpp b/src/translate_c.cpp index 7d618466b..7462c8e04 100644 --- a/src/translate_c.cpp +++ b/src/translate_c.cpp @@ -14,7 +14,6 @@ #include "translate_c.hpp" #include "parser.hpp" - #if __GNUC__ >= 8 #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wclass-memaccess" @@ -28,6 +27,13 @@ #pragma GCC diagnostic pop #endif + +// Before the #include of zig_clang.h +// Temporary transitional thing: override ZigClangSourceLocation with clang::SourceLocation +#define ZigClangSourceLocation clang::SourceLocation +#define ZIG_CLANG_SOURCE_LOCATION ZigClangABISourceLocation +#include "zig_clang.h" + #include struct Alias { @@ -85,7 +91,7 @@ struct Context { HashMap decl_table; HashMap macro_table; HashMap global_table; - clang::SourceManager *source_manager; + ZigClangSourceManager *source_manager; ZigList aliases; AstNode *source_node; bool warnings_on; @@ -139,16 +145,16 @@ static void emit_warning(Context *c, const clang::SourceLocation &sl, const char Buf *msg = buf_vprintf(format, ap); va_end(ap); - StringRef filename = c->source_manager->getFilename(c->source_manager->getSpellingLoc(sl)); - const char *filename_bytes = (const char *)filename.bytes_begin(); + const char *filename_bytes = ZigClangSourceManager_getFilename(c->source_manager, + ZigClangSourceManager_getSpellingLoc(c->source_manager, sl)); 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); + unsigned line = ZigClangSourceManager_getSpellingLineNumber(c->source_manager, sl); + unsigned column = ZigClangSourceManager_getSpellingColumnNumber(c->source_manager, sl); fprintf(stderr, "%s:%u:%u: warning: %s\n", buf_ptr(path), line, column, buf_ptr(msg)); } @@ -4701,7 +4707,7 @@ static void process_preprocessor_entities(Context *c, clang::ASTUnit &unit) { continue; } - const char *begin_c = c->source_manager->getCharacterData(begin_loc); + const char *begin_c = ZigClangSourceManager_getCharacterData(c->source_manager, begin_loc); process_macro(c, &ctok, name, begin_c); } } @@ -4889,7 +4895,7 @@ Error parse_h_file(ImportTableEntry *import, ZigList *errors, const } c->ctx = &ast_unit->getASTContext(); - c->source_manager = &ast_unit->getSourceManager(); + c->source_manager = reinterpret_cast(&ast_unit->getSourceManager()); c->root = trans_create_node(c, NodeTypeContainerDecl); c->root->data.container_decl.is_root = true; diff --git a/src/zig_clang.cpp b/src/zig_clang.cpp new file mode 100644 index 000000000..62d1e3465 --- /dev/null +++ b/src/zig_clang.cpp @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2019 Andrew Kelley + * + * This file is part of zig, which is MIT licensed. + * See http://opensource.org/licenses/MIT + */ + + +/* + * The point of this file is to contain all the Clang C++ API interaction so that: + * 1. The compile time of other files is kept under control. + * 2. Provide a C interface to the Clang functions we need for self-hosting purposes. + * 3. Prevent C++ from infecting the rest of the project. + */ + +#if __GNUC__ >= 8 +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wclass-memaccess" +#endif + +#include +#include +#include + +#if __GNUC__ >= 8 +#pragma GCC diagnostic pop +#endif + +// Before the #include of zig_clang.h +// We'll check that the types are compatible but just use +// the clang type. +#define ZigClangSourceLocation clang::SourceLocation +#define ZIG_CLANG_SOURCE_LOCATION ZigClangABISourceLocation + +#include "zig_clang.h" + +// Detect additions to the enum +void zig2clang_BO(ZigClangBO op) { + switch (op) { + case ZigClangBO_PtrMemD: + case ZigClangBO_PtrMemI: + case ZigClangBO_Cmp: + case ZigClangBO_Mul: + case ZigClangBO_Div: + case ZigClangBO_Rem: + case ZigClangBO_Add: + case ZigClangBO_Sub: + case ZigClangBO_Shl: + case ZigClangBO_Shr: + case ZigClangBO_LT: + case ZigClangBO_GT: + case ZigClangBO_LE: + case ZigClangBO_GE: + case ZigClangBO_EQ: + case ZigClangBO_NE: + case ZigClangBO_And: + case ZigClangBO_Xor: + case ZigClangBO_Or: + case ZigClangBO_LAnd: + case ZigClangBO_LOr: + case ZigClangBO_Assign: + case ZigClangBO_Comma: + case ZigClangBO_MulAssign: + case ZigClangBO_DivAssign: + case ZigClangBO_RemAssign: + case ZigClangBO_AddAssign: + case ZigClangBO_SubAssign: + case ZigClangBO_ShlAssign: + case ZigClangBO_ShrAssign: + case ZigClangBO_AndAssign: + case ZigClangBO_XorAssign: + case ZigClangBO_OrAssign: + break; + } +} + +static_assert((clang::BinaryOperatorKind)ZigClangBO_Add == clang::BO_Add, ""); +static_assert((clang::BinaryOperatorKind)ZigClangBO_AddAssign == clang::BO_AddAssign, ""); +static_assert((clang::BinaryOperatorKind)ZigClangBO_And == clang::BO_And, ""); +static_assert((clang::BinaryOperatorKind)ZigClangBO_AndAssign == clang::BO_AndAssign, ""); +static_assert((clang::BinaryOperatorKind)ZigClangBO_Assign == clang::BO_Assign, ""); +static_assert((clang::BinaryOperatorKind)ZigClangBO_Cmp == clang::BO_Cmp, ""); +static_assert((clang::BinaryOperatorKind)ZigClangBO_Comma == clang::BO_Comma, ""); +static_assert((clang::BinaryOperatorKind)ZigClangBO_Div == clang::BO_Div, ""); +static_assert((clang::BinaryOperatorKind)ZigClangBO_DivAssign == clang::BO_DivAssign, ""); +static_assert((clang::BinaryOperatorKind)ZigClangBO_EQ == clang::BO_EQ, ""); +static_assert((clang::BinaryOperatorKind)ZigClangBO_GE == clang::BO_GE, ""); +static_assert((clang::BinaryOperatorKind)ZigClangBO_GT == clang::BO_GT, ""); +static_assert((clang::BinaryOperatorKind)ZigClangBO_LAnd == clang::BO_LAnd, ""); +static_assert((clang::BinaryOperatorKind)ZigClangBO_LE == clang::BO_LE, ""); +static_assert((clang::BinaryOperatorKind)ZigClangBO_LOr == clang::BO_LOr, ""); +static_assert((clang::BinaryOperatorKind)ZigClangBO_LT == clang::BO_LT, ""); +static_assert((clang::BinaryOperatorKind)ZigClangBO_Mul == clang::BO_Mul, ""); +static_assert((clang::BinaryOperatorKind)ZigClangBO_MulAssign == clang::BO_MulAssign, ""); +static_assert((clang::BinaryOperatorKind)ZigClangBO_NE == clang::BO_NE, ""); +static_assert((clang::BinaryOperatorKind)ZigClangBO_Or == clang::BO_Or, ""); +static_assert((clang::BinaryOperatorKind)ZigClangBO_OrAssign == clang::BO_OrAssign, ""); +static_assert((clang::BinaryOperatorKind)ZigClangBO_PtrMemD == clang::BO_PtrMemD, ""); +static_assert((clang::BinaryOperatorKind)ZigClangBO_PtrMemI == clang::BO_PtrMemI, ""); +static_assert((clang::BinaryOperatorKind)ZigClangBO_Rem == clang::BO_Rem, ""); +static_assert((clang::BinaryOperatorKind)ZigClangBO_RemAssign == clang::BO_RemAssign, ""); +static_assert((clang::BinaryOperatorKind)ZigClangBO_Shl == clang::BO_Shl, ""); +static_assert((clang::BinaryOperatorKind)ZigClangBO_ShlAssign == clang::BO_ShlAssign, ""); +static_assert((clang::BinaryOperatorKind)ZigClangBO_Shr == clang::BO_Shr, ""); +static_assert((clang::BinaryOperatorKind)ZigClangBO_ShrAssign == clang::BO_ShrAssign, ""); +static_assert((clang::BinaryOperatorKind)ZigClangBO_Sub == clang::BO_Sub, ""); +static_assert((clang::BinaryOperatorKind)ZigClangBO_SubAssign == clang::BO_SubAssign, ""); +static_assert((clang::BinaryOperatorKind)ZigClangBO_Xor == clang::BO_Xor, ""); +static_assert((clang::BinaryOperatorKind)ZigClangBO_XorAssign == clang::BO_XorAssign, ""); + +// This function detects additions to the enum +void zig2clang_UO(ZigClangUO op) { + switch (op) { + case ZigClangUO_AddrOf: + case ZigClangUO_Coawait: + case ZigClangUO_Deref: + case ZigClangUO_Extension: + case ZigClangUO_Imag: + case ZigClangUO_LNot: + case ZigClangUO_Minus: + case ZigClangUO_Not: + case ZigClangUO_Plus: + case ZigClangUO_PostDec: + case ZigClangUO_PostInc: + case ZigClangUO_PreDec: + case ZigClangUO_PreInc: + case ZigClangUO_Real: + break; + } +} + +static_assert((clang::UnaryOperatorKind)ZigClangUO_AddrOf == clang::UO_AddrOf, ""); +static_assert((clang::UnaryOperatorKind)ZigClangUO_Coawait == clang::UO_Coawait, ""); +static_assert((clang::UnaryOperatorKind)ZigClangUO_Deref == clang::UO_Deref, ""); +static_assert((clang::UnaryOperatorKind)ZigClangUO_Extension == clang::UO_Extension, ""); +static_assert((clang::UnaryOperatorKind)ZigClangUO_Imag == clang::UO_Imag, ""); +static_assert((clang::UnaryOperatorKind)ZigClangUO_LNot == clang::UO_LNot, ""); +static_assert((clang::UnaryOperatorKind)ZigClangUO_Minus == clang::UO_Minus, ""); +static_assert((clang::UnaryOperatorKind)ZigClangUO_Not == clang::UO_Not, ""); +static_assert((clang::UnaryOperatorKind)ZigClangUO_Plus == clang::UO_Plus, ""); +static_assert((clang::UnaryOperatorKind)ZigClangUO_PostDec == clang::UO_PostDec, ""); +static_assert((clang::UnaryOperatorKind)ZigClangUO_PostInc == clang::UO_PostInc, ""); +static_assert((clang::UnaryOperatorKind)ZigClangUO_PreDec == clang::UO_PreDec, ""); +static_assert((clang::UnaryOperatorKind)ZigClangUO_PreInc == clang::UO_PreInc, ""); +static_assert((clang::UnaryOperatorKind)ZigClangUO_Real == clang::UO_Real, ""); + +static_assert(sizeof(ZigClangABISourceLocation) == sizeof(clang::SourceLocation)); + +clang::SourceLocation ZigClangSourceManager_getSpellingLoc(const ZigClangSourceManager *self, + clang::SourceLocation Loc) +{ + return reinterpret_cast(self)->getSpellingLoc(Loc); +} + +const char *ZigClangSourceManager_getFilename(const ZigClangSourceManager *self, + clang::SourceLocation SpellingLoc) +{ + StringRef s = reinterpret_cast(self)->getFilename(SpellingLoc); + return (const char *)s.bytes_begin(); +} + +unsigned ZigClangSourceManager_getSpellingLineNumber(const ZigClangSourceManager *self, + ZigClangSourceLocation Loc) +{ + return reinterpret_cast(self)->getSpellingLineNumber(Loc); +} + +unsigned ZigClangSourceManager_getSpellingColumnNumber(const ZigClangSourceManager *self, + ZigClangSourceLocation Loc) +{ + return reinterpret_cast(self)->getSpellingColumnNumber(Loc); +} + +const char* ZigClangSourceManager_getCharacterData(const ZigClangSourceManager *self, + ZigClangSourceLocation SL) +{ + return reinterpret_cast(self)->getCharacterData(SL); +} diff --git a/src/zig_clang.h b/src/zig_clang.h new file mode 100644 index 000000000..840d227bb --- /dev/null +++ b/src/zig_clang.h @@ -0,0 +1,253 @@ +/* + * Copyright (c) 2019 Andrew Kelley + * + * This file is part of zig, which is MIT licensed. + * See http://opensource.org/licenses/MIT + */ + +#ifndef ZIG_ZIG_CLANG_H +#define ZIG_ZIG_CLANG_H + +#ifdef __cplusplus +#define ZIG_EXTERN_C extern "C" +#else +#define ZIG_EXTERN_C +#endif + +// ATTENTION: If you modify this file, be sure to update the corresponding +// extern function declarations in the self-hosted compiler. + +#ifndef ZIG_CLANG_SOURCE_LOCATION +#define ZIG_CLANG_SOURCE_LOCATION ZigClangSourceLocation +#endif + +struct ZIG_CLANG_SOURCE_LOCATION { + unsigned ID; +}; + +struct ZigClangAPValue; +struct ZigClangASTContext; +struct ZigClangASTUnit; +struct ZigClangArraySubscriptExpr; +struct ZigClangArrayType; +struct ZigClangAttributedType; +struct ZigClangBinaryOperator; +struct ZigClangBreakStmt; +struct ZigClangBuiltinType; +struct ZigClangCStyleCastExpr; +struct ZigClangCallExpr; +struct ZigClangCaseStmt; +struct ZigClangCompoundAssignOperator; +struct ZigClangCompoundStmt; +struct ZigClangConditionalOperator; +struct ZigClangConstantArrayType; +struct ZigClangContinueStmt; +struct ZigClangDecayedType; +struct ZigClangDecl; +struct ZigClangDeclRefExpr; +struct ZigClangDeclStmt; +struct ZigClangDefaultStmt; +struct ZigClangDiagnosticOptions; +struct ZigClangDiagnosticsEngine; +struct ZigClangDoStmt; +struct ZigClangElaboratedType; +struct ZigClangEnumConstantDecl; +struct ZigClangEnumDecl; +struct ZigClangEnumType; +struct ZigClangExpr; +struct ZigClangFieldDecl; +struct ZigClangFileID; +struct ZigClangForStmt; +struct ZigClangFullSourceLoc; +struct ZigClangFunctionDecl; +struct ZigClangFunctionProtoType; +struct ZigClangIfStmt; +struct ZigClangImplicitCastExpr; +struct ZigClangIncompleteArrayType; +struct ZigClangIntegerLiteral; +struct ZigClangMacroDefinitionRecord; +struct ZigClangMemberExpr; +struct ZigClangNamedDecl; +struct ZigClangNone; +struct ZigClangPCHContainerOperations; +struct ZigClangParenExpr; +struct ZigClangParenType; +struct ZigClangParmVarDecl; +struct ZigClangPointerType; +struct ZigClangPreprocessedEntity; +struct ZigClangQualType; +struct ZigClangRecordDecl; +struct ZigClangRecordType; +struct ZigClangReturnStmt; +struct ZigClangSkipFunctionBodiesScope; +struct ZigClangSourceManager; +struct ZigClangSourceRange; +struct ZigClangStmt; +struct ZigClangStorageClass; +struct ZigClangStringLiteral; +struct ZigClangStringRef; +struct ZigClangSwitchStmt; +struct ZigClangType; +struct ZigClangTypedefNameDecl; +struct ZigClangTypedefType; +struct ZigClangUnaryExprOrTypeTraitExpr; +struct ZigClangUnaryOperator; +struct ZigClangValueDecl; +struct ZigClangVarDecl; +struct ZigClangWhileStmt; + +enum ZigClangBO { + ZigClangBO_PtrMemD, + ZigClangBO_PtrMemI, + ZigClangBO_Mul, + ZigClangBO_Div, + ZigClangBO_Rem, + ZigClangBO_Add, + ZigClangBO_Sub, + ZigClangBO_Shl, + ZigClangBO_Shr, + ZigClangBO_Cmp, + ZigClangBO_LT, + ZigClangBO_GT, + ZigClangBO_LE, + ZigClangBO_GE, + ZigClangBO_EQ, + ZigClangBO_NE, + ZigClangBO_And, + ZigClangBO_Xor, + ZigClangBO_Or, + ZigClangBO_LAnd, + ZigClangBO_LOr, + ZigClangBO_Assign, + ZigClangBO_MulAssign, + ZigClangBO_DivAssign, + ZigClangBO_RemAssign, + ZigClangBO_AddAssign, + ZigClangBO_SubAssign, + ZigClangBO_ShlAssign, + ZigClangBO_ShrAssign, + ZigClangBO_AndAssign, + ZigClangBO_XorAssign, + ZigClangBO_OrAssign, + ZigClangBO_Comma, +}; + +enum ZigClangUO { + ZigClangUO_PostInc, + ZigClangUO_PostDec, + ZigClangUO_PreInc, + ZigClangUO_PreDec, + ZigClangUO_AddrOf, + ZigClangUO_Deref, + ZigClangUO_Plus, + ZigClangUO_Minus, + ZigClangUO_Not, + ZigClangUO_LNot, + ZigClangUO_Real, + ZigClangUO_Imag, + ZigClangUO_Extension, + ZigClangUO_Coawait, +}; + +//struct ZigClangCC_AAPCS; +//struct ZigClangCC_AAPCS_VFP; +//struct ZigClangCC_C; +//struct ZigClangCC_IntelOclBicc; +//struct ZigClangCC_OpenCLKernel; +//struct ZigClangCC_PreserveAll; +//struct ZigClangCC_PreserveMost; +//struct ZigClangCC_SpirFunction; +//struct ZigClangCC_Swift; +//struct ZigClangCC_Win64; +//struct ZigClangCC_X86FastCall; +//struct ZigClangCC_X86Pascal; +//struct ZigClangCC_X86RegCall; +//struct ZigClangCC_X86StdCall; +//struct ZigClangCC_X86ThisCall; +//struct ZigClangCC_X86VectorCall; +//struct ZigClangCC_X86_64SysV; + +//struct ZigClangCK_ARCConsumeObject; +//struct ZigClangCK_ARCExtendBlockObject; +//struct ZigClangCK_ARCProduceObject; +//struct ZigClangCK_ARCReclaimReturnedObject; +//struct ZigClangCK_AddressSpaceConversion; +//struct ZigClangCK_AnyPointerToBlockPointerCast; +//struct ZigClangCK_ArrayToPointerDecay; +//struct ZigClangCK_AtomicToNonAtomic; +//struct ZigClangCK_BaseToDerived; +//struct ZigClangCK_BaseToDerivedMemberPointer; +//struct ZigClangCK_BitCast; +//struct ZigClangCK_BlockPointerToObjCPointerCast; +//struct ZigClangCK_BooleanToSignedIntegral; +//struct ZigClangCK_BuiltinFnToFnPtr; +//struct ZigClangCK_CPointerToObjCPointerCast; +//struct ZigClangCK_ConstructorConversion; +//struct ZigClangCK_CopyAndAutoreleaseBlockObject; +//struct ZigClangCK_Dependent; +//struct ZigClangCK_DerivedToBase; +//struct ZigClangCK_DerivedToBaseMemberPointer; +//struct ZigClangCK_Dynamic; +//struct ZigClangCK_FloatingCast; +//struct ZigClangCK_FloatingComplexCast; +//struct ZigClangCK_FloatingComplexToBoolean; +//struct ZigClangCK_FloatingComplexToIntegralComplex; +//struct ZigClangCK_FloatingComplexToReal; +//struct ZigClangCK_FloatingRealToComplex; +//struct ZigClangCK_FloatingToBoolean; +//struct ZigClangCK_FloatingToIntegral; +//struct ZigClangCK_FunctionToPointerDecay; +//struct ZigClangCK_IntToOCLSampler; +//struct ZigClangCK_IntegralCast; +//struct ZigClangCK_IntegralComplexCast; +//struct ZigClangCK_IntegralComplexToBoolean; +//struct ZigClangCK_IntegralComplexToFloatingComplex; +//struct ZigClangCK_IntegralComplexToReal; +//struct ZigClangCK_IntegralRealToComplex; +//struct ZigClangCK_IntegralToBoolean; +//struct ZigClangCK_IntegralToFloating; +//struct ZigClangCK_IntegralToPointer; +//struct ZigClangCK_LValueBitCast; +//struct ZigClangCK_LValueToRValue; +//struct ZigClangCK_MemberPointerToBoolean; +//struct ZigClangCK_NoOp; +//struct ZigClangCK_NonAtomicToAtomic; +//struct ZigClangCK_NullToMemberPointer; +//struct ZigClangCK_NullToPointer; +//struct ZigClangCK_ObjCObjectLValueCast; +//struct ZigClangCK_PointerToBoolean; +//struct ZigClangCK_PointerToIntegral; +//struct ZigClangCK_ReinterpretMemberPointer; +//struct ZigClangCK_ToUnion; +//struct ZigClangCK_ToVoid; +//struct ZigClangCK_UncheckedDerivedToBase; +//struct ZigClangCK_UserDefinedConversion; +//struct ZigClangCK_VectorSplat; +//struct ZigClangCK_ZeroToOCLEvent; +//struct ZigClangCK_ZeroToOCLQueue; + +//struct ZigClangETK_Class; +//struct ZigClangETK_Enum; +//struct ZigClangETK_Interface; +//struct ZigClangETK_None; +//struct ZigClangETK_Struct; +//struct ZigClangETK_Typename; +//struct ZigClangETK_Union; + +//struct ZigClangSC_None; +//struct ZigClangSC_PrivateExtern; +//struct ZigClangSC_Static; + +//struct ZigClangTU_Complete; + +ZIG_EXTERN_C ZigClangSourceLocation ZigClangSourceManager_getSpellingLoc(const ZigClangSourceManager *, + ZigClangSourceLocation Loc); +ZIG_EXTERN_C const char *ZigClangSourceManager_getFilename(const ZigClangSourceManager *, + ZigClangSourceLocation SpellingLoc); +ZIG_EXTERN_C unsigned ZigClangSourceManager_getSpellingLineNumber(const ZigClangSourceManager *, + ZigClangSourceLocation Loc); +ZIG_EXTERN_C unsigned ZigClangSourceManager_getSpellingColumnNumber(const ZigClangSourceManager *, + ZigClangSourceLocation Loc); +ZIG_EXTERN_C const char* ZigClangSourceManager_getCharacterData(const ZigClangSourceManager *, + ZigClangSourceLocation SL); +#endif