translate-c: proof of concept for transitioning to userland

See #1964
master
Andrew Kelley 2019-02-16 15:14:51 -05:00
parent bd52d81dc3
commit 356cfa08f4
No known key found for this signature in database
GPG Key ID: 7C5F548F728501A9
4 changed files with 446 additions and 8 deletions

View File

@ -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"
)

View File

@ -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 <string.h>
struct Alias {
@ -85,7 +91,7 @@ struct Context {
HashMap<const void *, AstNode *, ptr_hash, ptr_eq> decl_table;
HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> macro_table;
HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> global_table;
clang::SourceManager *source_manager;
ZigClangSourceManager *source_manager;
ZigList<Alias> 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<ErrorMsg *> *errors, const
}
c->ctx = &ast_unit->getASTContext();
c->source_manager = &ast_unit->getSourceManager();
c->source_manager = reinterpret_cast<ZigClangSourceManager *>(&ast_unit->getSourceManager());
c->root = trans_create_node(c, NodeTypeContainerDecl);
c->root->data.container_decl.is_root = true;

178
src/zig_clang.cpp Normal file
View File

@ -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 <clang/Frontend/ASTUnit.h>
#include <clang/Frontend/CompilerInstance.h>
#include <clang/AST/Expr.h>
#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<const clang::SourceManager *>(self)->getSpellingLoc(Loc);
}
const char *ZigClangSourceManager_getFilename(const ZigClangSourceManager *self,
clang::SourceLocation SpellingLoc)
{
StringRef s = reinterpret_cast<const clang::SourceManager *>(self)->getFilename(SpellingLoc);
return (const char *)s.bytes_begin();
}
unsigned ZigClangSourceManager_getSpellingLineNumber(const ZigClangSourceManager *self,
ZigClangSourceLocation Loc)
{
return reinterpret_cast<const clang::SourceManager *>(self)->getSpellingLineNumber(Loc);
}
unsigned ZigClangSourceManager_getSpellingColumnNumber(const ZigClangSourceManager *self,
ZigClangSourceLocation Loc)
{
return reinterpret_cast<const clang::SourceManager *>(self)->getSpellingColumnNumber(Loc);
}
const char* ZigClangSourceManager_getCharacterData(const ZigClangSourceManager *self,
ZigClangSourceLocation SL)
{
return reinterpret_cast<const clang::SourceManager *>(self)->getCharacterData(SL);
}

253
src/zig_clang.h Normal file
View File

@ -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