mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-07-28 21:40:30 +00:00
Add chibicc
This program popped up on Hacker News recently. It's the only modern compiler I've ever seen that doesn't have dependencies and is easily modified. So I added all of the missing GNU extensions I like to use which means it might be possible soon to build on non-Linux and have third party not vendor gcc binaries.
This commit is contained in:
parent
e44a0cf6f8
commit
8da931a7f6
298 changed files with 19493 additions and 11950 deletions
537
third_party/chibicc/chibicc.h
vendored
537
third_party/chibicc/chibicc.h
vendored
|
@ -1,21 +1,21 @@
|
|||
#ifndef COSMOPOLITAN_THIRD_PARTY_CHIBICC_CHIBICC_H_
|
||||
#define COSMOPOLITAN_THIRD_PARTY_CHIBICC_CHIBICC_H_
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
#define _POSIX_C_SOURCE 200809L
|
||||
|
||||
#include "libc/assert.h"
|
||||
#include "libc/bits/popcnt.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/struct/stat.h"
|
||||
#include "libc/calls/weirdtypes.h"
|
||||
#include "libc/conv/conv.h"
|
||||
#include "libc/conv/itoa.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/fmt/fmt.h"
|
||||
#include "libc/limits.h"
|
||||
#include "libc/log/check.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/macros.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/nexgen32e/bsf.h"
|
||||
#include "libc/nexgen32e/bsr.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/stdio/temp.h"
|
||||
|
@ -25,30 +25,38 @@ COSMOPOLITAN_C_START_
|
|||
#include "libc/unicode/unicode.h"
|
||||
#include "libc/x/x.h"
|
||||
#include "third_party/gdtoa/gdtoa.h"
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
#pragma GCC diagnostic ignored "-Wswitch"
|
||||
|
||||
#ifndef __GNUC__
|
||||
#define __attribute__(x)
|
||||
#endif
|
||||
|
||||
typedef struct Type Type;
|
||||
typedef struct Node Node;
|
||||
typedef struct Member Member;
|
||||
typedef struct Relocation Relocation;
|
||||
typedef struct Asm Asm;
|
||||
typedef struct AsmOperand AsmOperand;
|
||||
typedef struct File File;
|
||||
typedef struct FpClassify FpClassify;
|
||||
typedef struct Hideset Hideset;
|
||||
typedef struct Member Member;
|
||||
typedef struct Node Node;
|
||||
typedef struct Obj Obj;
|
||||
typedef struct Relocation Relocation;
|
||||
typedef struct Relocation Relocation;
|
||||
typedef struct StaticAsm StaticAsm;
|
||||
typedef struct StringArray StringArray;
|
||||
typedef struct Token Token;
|
||||
typedef struct TokenStack TokenStack;
|
||||
typedef struct Type Type;
|
||||
|
||||
//
|
||||
// strarray.c
|
||||
//
|
||||
|
||||
typedef struct {
|
||||
struct StringArray {
|
||||
char **data;
|
||||
int capacity;
|
||||
int len;
|
||||
} StringArray;
|
||||
};
|
||||
|
||||
void strarray_push(StringArray *arr, char *s);
|
||||
void strarray_push(StringArray *, char *);
|
||||
|
||||
//
|
||||
// tokenize.c
|
||||
|
@ -64,74 +72,144 @@ typedef enum {
|
|||
TK_EOF, // End-of-file markers
|
||||
} TokenKind;
|
||||
|
||||
typedef struct {
|
||||
struct File {
|
||||
char *name;
|
||||
int file_no;
|
||||
char *contents;
|
||||
|
||||
// For #line directive
|
||||
char *display_name;
|
||||
int line_delta;
|
||||
} File;
|
||||
};
|
||||
|
||||
// Token type
|
||||
typedef struct Token Token;
|
||||
struct Token {
|
||||
TokenKind kind; // Token kind
|
||||
Token *next; // Next token
|
||||
int64_t val; // If kind is TK_NUM, its value
|
||||
long double fval; // If kind is TK_NUM, its value
|
||||
char *loc; // Token location
|
||||
int len; // Token length
|
||||
Type *ty; // Used if TK_NUM or TK_STR
|
||||
char *str; // String literal contents including terminating '\0'
|
||||
|
||||
File *file; // Source location
|
||||
char *filename; // Filename
|
||||
int line_no; // Line number
|
||||
int line_delta; // Line number
|
||||
bool at_bol; // True if this token is at beginning of line
|
||||
bool has_space; // True if this token follows a space character
|
||||
Token *next; // Next token
|
||||
char *loc; // Token location
|
||||
Type *ty; // Used if TK_NUM or TK_STR
|
||||
File *file; // Source location
|
||||
char *filename; // Filename
|
||||
Hideset *hideset; // For macro expansion
|
||||
Token *origin; // If this is expanded from a macro, the original token
|
||||
union {
|
||||
int64_t val; // If kind is TK_NUM, its value
|
||||
long double fval; // If kind is TK_NUM, its value
|
||||
char *str; // String literal contents including terminating '\0'
|
||||
};
|
||||
};
|
||||
|
||||
noreturn void error(char *fmt, ...) __attribute__((format(printf, 1, 2)));
|
||||
noreturn void error_at(char *loc, char *fmt, ...)
|
||||
__attribute__((format(printf, 2, 3)));
|
||||
noreturn void error_tok(Token *tok, char *fmt, ...)
|
||||
__attribute__((format(printf, 2, 3)));
|
||||
void warn_tok(Token *tok, char *fmt, ...) __attribute__((format(printf, 2, 3)));
|
||||
bool equal(Token *tok, char *op);
|
||||
Token *skip(Token *tok, char *op);
|
||||
bool consume(Token **rest, Token *tok, char *str);
|
||||
void convert_pp_tokens(Token *tok);
|
||||
File **get_input_files(void);
|
||||
File *new_file(char *name, int file_no, char *contents);
|
||||
Token *tokenize_string_literal(Token *tok, Type *basety);
|
||||
Token *tokenize(File *file);
|
||||
Token *tokenize_file(char *filename);
|
||||
void error(char *, ...)
|
||||
__attribute__((__noreturn__, __format__(__printf__, 1, 2)));
|
||||
void error_at(char *, char *, ...)
|
||||
__attribute__((__noreturn__, __format__(__printf__, 2, 3)));
|
||||
void error_tok(Token *, char *, ...)
|
||||
__attribute__((__noreturn__, __format__(__printf__, 2, 3)));
|
||||
void warn_tok(Token *, char *, ...)
|
||||
__attribute__((__format__(__printf__, 2, 3)));
|
||||
|
||||
#define UNREACHABLE() error("internal error at %s:%d", __FILE__, __LINE__)
|
||||
File **get_input_files(void);
|
||||
File *new_file(char *, int, char *);
|
||||
Token *skip(Token *, char *);
|
||||
Token *tokenize(File *);
|
||||
Token *tokenize_file(char *);
|
||||
Token *tokenize_string_literal(Token *, Type *);
|
||||
bool consume(Token **, Token *, char *, size_t);
|
||||
bool equal(Token *, char *, size_t);
|
||||
void convert_pp_tokens(Token *);
|
||||
|
||||
#define UNREACHABLE() error("internal error at %s:%d", __FILE__, __LINE__)
|
||||
#define EQUAL(T, S) equal(T, S, strlen(S))
|
||||
#define CONSUME(R, T, S) consume(R, T, S, strlen(S))
|
||||
|
||||
//
|
||||
// preprocess.c
|
||||
//
|
||||
|
||||
char *format(char *fmt, ...);
|
||||
char *search_include_paths(char *filename);
|
||||
bool file_exists(char *path);
|
||||
char *search_include_paths(char *);
|
||||
void init_macros(void);
|
||||
void define_macro(char *name, char *buf);
|
||||
void undef_macro(char *name);
|
||||
Token *preprocess(Token *tok);
|
||||
void define_macro(char *, char *);
|
||||
void undef_macro(char *);
|
||||
Token *preprocess(Token *);
|
||||
|
||||
//
|
||||
// asm.c
|
||||
//
|
||||
|
||||
#define kAsmImm 1
|
||||
#define kAsmMem 2
|
||||
#define kAsmReg 4
|
||||
#define kAsmMmx 8
|
||||
#define kAsmXmm 16
|
||||
#define kAsmFpu 32
|
||||
#define kAsmRaw 64
|
||||
#define kAsmFlag 128
|
||||
|
||||
struct AsmOperand {
|
||||
uint8_t reg;
|
||||
uint8_t type;
|
||||
char flow;
|
||||
char x87mask;
|
||||
bool isused;
|
||||
int regmask;
|
||||
int predicate;
|
||||
char *str;
|
||||
Node *node;
|
||||
Token *tok;
|
||||
int64_t val;
|
||||
char **label;
|
||||
};
|
||||
|
||||
struct Asm {
|
||||
int n;
|
||||
char *str;
|
||||
Token *tok;
|
||||
AsmOperand ops[20];
|
||||
bool isgnu;
|
||||
bool flagclob;
|
||||
uint8_t x87clob;
|
||||
uint16_t regclob;
|
||||
uint16_t xmmclob;
|
||||
};
|
||||
|
||||
struct StaticAsm {
|
||||
StaticAsm *next;
|
||||
Asm *body;
|
||||
};
|
||||
|
||||
extern StaticAsm *staticasms;
|
||||
|
||||
Asm *asm_stmt(Token **, Token *);
|
||||
void flushln(void);
|
||||
void gen_addr(Node *);
|
||||
void gen_asm(Asm *);
|
||||
void gen_expr(Node *);
|
||||
void pop(char *);
|
||||
void popreg(char *);
|
||||
void print_loc(int64_t, int64_t);
|
||||
void push(void);
|
||||
void pushreg(char *);
|
||||
|
||||
//
|
||||
// fpclassify.c
|
||||
//
|
||||
|
||||
struct FpClassify {
|
||||
Node *node;
|
||||
int args[5];
|
||||
};
|
||||
|
||||
void gen_fpclassify(FpClassify *);
|
||||
|
||||
//
|
||||
// parse.c
|
||||
//
|
||||
|
||||
// Variable or function
|
||||
typedef struct Obj Obj;
|
||||
struct Obj {
|
||||
Obj *next;
|
||||
char *name; // Variable name
|
||||
|
@ -139,31 +217,36 @@ struct Obj {
|
|||
Token *tok; // representative token
|
||||
bool is_local; // local or global/function
|
||||
int align; // alignment
|
||||
|
||||
// Local variable
|
||||
int offset;
|
||||
|
||||
// Global variable or function
|
||||
bool is_function;
|
||||
bool is_definition;
|
||||
bool is_static;
|
||||
|
||||
bool is_weak;
|
||||
bool is_externally_visible;
|
||||
char *asmname;
|
||||
char *section;
|
||||
char *visibility;
|
||||
// Global variable
|
||||
bool is_tentative;
|
||||
bool is_string_literal;
|
||||
bool is_tls;
|
||||
char *init_data;
|
||||
Relocation *rel;
|
||||
|
||||
// Function
|
||||
bool is_inline;
|
||||
bool is_aligned;
|
||||
bool is_noreturn;
|
||||
bool is_destructor;
|
||||
bool is_constructor;
|
||||
int stack_size;
|
||||
Obj *params;
|
||||
Node *body;
|
||||
Obj *locals;
|
||||
Obj *va_area;
|
||||
Obj *alloca_bottom;
|
||||
int stack_size;
|
||||
|
||||
// Static inline function
|
||||
// Dead Code Elimination
|
||||
bool is_live;
|
||||
bool is_root;
|
||||
StringArray refs;
|
||||
|
@ -172,7 +255,6 @@ struct Obj {
|
|||
// Global variable can be initialized either by a constant expression
|
||||
// or a pointer to another global variable. This struct represents the
|
||||
// latter.
|
||||
typedef struct Relocation Relocation;
|
||||
struct Relocation {
|
||||
Relocation *next;
|
||||
int offset;
|
||||
|
@ -180,127 +262,139 @@ struct Relocation {
|
|||
long addend;
|
||||
};
|
||||
|
||||
// AST node
|
||||
typedef enum {
|
||||
ND_NULL_EXPR, // Do nothing
|
||||
ND_ADD, // +
|
||||
ND_SUB, // -
|
||||
ND_MUL, // *
|
||||
ND_DIV, // /
|
||||
ND_NEG, // unary -
|
||||
ND_MOD, // %
|
||||
ND_BITAND, // &
|
||||
ND_BITOR, // |
|
||||
ND_BITXOR, // ^
|
||||
ND_SHL, // <<
|
||||
ND_SHR, // >>
|
||||
ND_EQ, // ==
|
||||
ND_NE, // !=
|
||||
ND_LT, // <
|
||||
ND_LE, // <=
|
||||
ND_ASSIGN, // =
|
||||
ND_COND, // ?:
|
||||
ND_COMMA, // ,
|
||||
ND_MEMBER, // . (struct member access)
|
||||
ND_ADDR, // unary &
|
||||
ND_DEREF, // unary *
|
||||
ND_NOT, // !
|
||||
ND_BITNOT, // ~
|
||||
ND_LOGAND, // &&
|
||||
ND_LOGOR, // ||
|
||||
ND_RETURN, // "return"
|
||||
ND_IF, // "if"
|
||||
ND_FOR, // "for" or "while"
|
||||
ND_DO, // "do"
|
||||
ND_SWITCH, // "switch"
|
||||
ND_CASE, // "case"
|
||||
ND_BLOCK, // { ... }
|
||||
ND_GOTO, // "goto"
|
||||
ND_GOTO_EXPR, // "goto" labels-as-values
|
||||
ND_LABEL, // Labeled statement
|
||||
ND_LABEL_VAL, // [GNU] Labels-as-values
|
||||
ND_FUNCALL, // Function call
|
||||
ND_EXPR_STMT, // Expression statement
|
||||
ND_STMT_EXPR, // Statement expression
|
||||
ND_VAR, // Variable
|
||||
ND_VLA_PTR, // VLA designator
|
||||
ND_NUM, // Integer
|
||||
ND_CAST, // Type cast
|
||||
ND_MEMZERO, // Zero-clear a stack variable
|
||||
ND_ASM, // "asm"
|
||||
ND_CAS, // Atomic compare-and-swap
|
||||
ND_EXCH, // Atomic exchange
|
||||
ND_NULL_EXPR, // Do nothing
|
||||
ND_ADD, // +
|
||||
ND_SUB, // -
|
||||
ND_MUL, // *
|
||||
ND_DIV, // /
|
||||
ND_NEG, // unary -
|
||||
ND_MOD, // %
|
||||
ND_BITAND, // &
|
||||
ND_BITOR, // |
|
||||
ND_BITXOR, // ^
|
||||
ND_SHL, // <<
|
||||
ND_SHR, // >>
|
||||
ND_EQ, // ==
|
||||
ND_NE, // !=
|
||||
ND_LT, // <
|
||||
ND_LE, // <=
|
||||
ND_ASSIGN, // =
|
||||
ND_COND, // ?:
|
||||
ND_COMMA, // ,
|
||||
ND_MEMBER, // . (struct member access)
|
||||
ND_ADDR, // unary &
|
||||
ND_DEREF, // unary *
|
||||
ND_NOT, // !
|
||||
ND_BITNOT, // ~
|
||||
ND_LOGAND, // &&
|
||||
ND_LOGOR, // ||
|
||||
ND_RETURN, // "return"
|
||||
ND_IF, // "if"
|
||||
ND_FOR, // "for" or "while"
|
||||
ND_DO, // "do"
|
||||
ND_SWITCH, // "switch"
|
||||
ND_CASE, // "case"
|
||||
ND_BLOCK, // { ... }
|
||||
ND_GOTO, // "goto"
|
||||
ND_GOTO_EXPR, // "goto" labels-as-values
|
||||
ND_LABEL, // Labeled statement
|
||||
ND_LABEL_VAL, // [GNU] Labels-as-values
|
||||
ND_FUNCALL, // Function call
|
||||
ND_EXPR_STMT, // Expression statement
|
||||
ND_STMT_EXPR, // Statement expression
|
||||
ND_VAR, // Variable
|
||||
ND_VLA_PTR, // VLA designator
|
||||
ND_NUM, // Integer
|
||||
ND_CAST, // Type cast
|
||||
ND_MEMZERO, // Zero-clear a stack variable
|
||||
ND_ASM, // "asm"
|
||||
ND_CAS, // Atomic compare-and-swap
|
||||
ND_EXCH, // Atomic exchange
|
||||
ND_FPCLASSIFY, // floating point classify
|
||||
} NodeKind;
|
||||
|
||||
// AST node type
|
||||
struct Node {
|
||||
NodeKind kind; // Node kind
|
||||
Node *next; // Next node
|
||||
Type *ty; // Type, e.g. int or pointer to int
|
||||
Token *tok; // Representative token
|
||||
|
||||
Node *lhs; // Left-hand side
|
||||
Node *rhs; // Right-hand side
|
||||
|
||||
Node *lhs; // Left-hand side
|
||||
Node *rhs; // Right-hand side
|
||||
// "if" or "for" statement
|
||||
Node *cond;
|
||||
Node *then;
|
||||
Node *els;
|
||||
Node *init;
|
||||
Node *inc;
|
||||
|
||||
// "break" and "continue" labels
|
||||
char *brk_label;
|
||||
char *cont_label;
|
||||
|
||||
// Block or statement expression
|
||||
Node *body;
|
||||
|
||||
// Struct member access
|
||||
Member *member;
|
||||
|
||||
// Function call
|
||||
Type *func_ty;
|
||||
Node *args;
|
||||
bool pass_by_stack;
|
||||
Obj *ret_buffer;
|
||||
|
||||
// Goto or labeled statement, or labels-as-values
|
||||
char *label;
|
||||
char *unique_label;
|
||||
Node *goto_next;
|
||||
|
||||
// Switch
|
||||
Node *case_next;
|
||||
Node *default_case;
|
||||
|
||||
// Case
|
||||
long begin;
|
||||
long end;
|
||||
|
||||
// "asm" string literal
|
||||
char *asm_str;
|
||||
|
||||
// Atomic compare-and-swap
|
||||
Node *cas_addr;
|
||||
Node *cas_old;
|
||||
Node *cas_new;
|
||||
|
||||
// Atomic op= operators
|
||||
Obj *atomic_addr;
|
||||
Node *atomic_expr;
|
||||
|
||||
// Variable
|
||||
Obj *var;
|
||||
|
||||
// Numeric literal
|
||||
int64_t val;
|
||||
long double fval;
|
||||
union {
|
||||
struct {
|
||||
// Function call
|
||||
Type *func_ty;
|
||||
Node *args;
|
||||
bool pass_by_stack;
|
||||
Obj *ret_buffer;
|
||||
};
|
||||
struct {
|
||||
// Switch
|
||||
Node *case_next;
|
||||
Node *default_case;
|
||||
// Goto or labeled statement, or labels-as-values
|
||||
char *label;
|
||||
char *unique_label;
|
||||
Node *goto_next;
|
||||
// "break" and "continue" labels
|
||||
char *brk_label;
|
||||
char *cont_label;
|
||||
// Case
|
||||
long begin;
|
||||
long end;
|
||||
};
|
||||
struct {
|
||||
// Struct member access
|
||||
Member *member;
|
||||
};
|
||||
struct {
|
||||
// Assembly
|
||||
Asm *azm;
|
||||
};
|
||||
struct {
|
||||
// Atomic compare-and-swap
|
||||
Node *cas_addr;
|
||||
Node *cas_old;
|
||||
Node *cas_new;
|
||||
};
|
||||
struct {
|
||||
// Atomic op= operators
|
||||
Obj *atomic_addr;
|
||||
Node *atomic_expr;
|
||||
};
|
||||
struct {
|
||||
// Variable
|
||||
Obj *var;
|
||||
};
|
||||
struct {
|
||||
// Numeric literal
|
||||
int64_t val;
|
||||
long double fval;
|
||||
};
|
||||
struct {
|
||||
FpClassify *fpc;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
Node *new_cast(Node *expr, Type *ty);
|
||||
int64_t const_expr(Token **rest, Token *tok);
|
||||
Obj *parse(Token *tok);
|
||||
Node *expr(Token **, Token *);
|
||||
Node *new_cast(Node *, Type *);
|
||||
Node *new_node(NodeKind, Token *);
|
||||
Obj *parse(Token *);
|
||||
bool is_const_expr(Node *);
|
||||
char *ConsumeStringLiteral(Token **, Token *);
|
||||
int64_t const_expr(Token **, Token *);
|
||||
int64_t eval(Node *);
|
||||
int64_t eval2(Node *, char ***);
|
||||
|
||||
//
|
||||
// type.c
|
||||
|
@ -313,6 +407,7 @@ typedef enum {
|
|||
TY_SHORT,
|
||||
TY_INT,
|
||||
TY_LONG,
|
||||
TY_INT128,
|
||||
TY_FLOAT,
|
||||
TY_DOUBLE,
|
||||
TY_LDOUBLE,
|
||||
|
@ -332,7 +427,6 @@ struct Type {
|
|||
bool is_unsigned; // unsigned or signed
|
||||
bool is_atomic; // true if _Atomic
|
||||
Type *origin; // for type compatibility check
|
||||
|
||||
// Pointer-to or array-of type. We intentionally use the same member
|
||||
// to represent pointer/array duality in C.
|
||||
//
|
||||
|
@ -342,23 +436,20 @@ struct Type {
|
|||
// naturally handled as if it were "pointer to T", as required by
|
||||
// the C spec.
|
||||
Type *base;
|
||||
|
||||
// Declaration
|
||||
Token *name;
|
||||
Token *name_pos;
|
||||
|
||||
// Array
|
||||
int array_len;
|
||||
|
||||
int vector_size;
|
||||
// Variable-length array
|
||||
Node *vla_len; // # of elements
|
||||
Obj *vla_size; // sizeof() value
|
||||
|
||||
// Struct
|
||||
Member *members;
|
||||
bool is_flexible;
|
||||
bool is_packed;
|
||||
|
||||
bool is_aligned;
|
||||
// Function type
|
||||
Type *return_ty;
|
||||
Type *params;
|
||||
|
@ -375,59 +466,70 @@ struct Member {
|
|||
int idx;
|
||||
int align;
|
||||
int offset;
|
||||
|
||||
// Bitfield
|
||||
bool is_bitfield;
|
||||
int bit_offset;
|
||||
int bit_width;
|
||||
};
|
||||
|
||||
extern Type *ty_void;
|
||||
extern Type *ty_bool;
|
||||
extern Type ty_void[1];
|
||||
extern Type ty_bool[1];
|
||||
extern Type ty_char[1];
|
||||
extern Type ty_short[1];
|
||||
extern Type ty_int[1];
|
||||
extern Type ty_long[1];
|
||||
extern Type ty_int128[1];
|
||||
extern Type ty_uchar[1];
|
||||
extern Type ty_ushort[1];
|
||||
extern Type ty_uint[1];
|
||||
extern Type ty_ulong[1];
|
||||
extern Type ty_uint128[1];
|
||||
extern Type ty_float[1];
|
||||
extern Type ty_double[1];
|
||||
extern Type ty_ldouble[1];
|
||||
|
||||
extern Type *ty_char;
|
||||
extern Type *ty_short;
|
||||
extern Type *ty_int;
|
||||
extern Type *ty_long;
|
||||
|
||||
extern Type *ty_uchar;
|
||||
extern Type *ty_ushort;
|
||||
extern Type *ty_uint;
|
||||
extern Type *ty_ulong;
|
||||
|
||||
extern Type *ty_float;
|
||||
extern Type *ty_double;
|
||||
extern Type *ty_ldouble;
|
||||
|
||||
bool is_integer(Type *ty);
|
||||
bool is_flonum(Type *ty);
|
||||
bool is_numeric(Type *ty);
|
||||
bool is_compatible(Type *t1, Type *t2);
|
||||
Type *copy_type(Type *ty);
|
||||
Type *pointer_to(Type *base);
|
||||
Type *func_type(Type *return_ty);
|
||||
Type *array_of(Type *base, int size);
|
||||
Type *vla_of(Type *base, Node *expr);
|
||||
bool is_integer(Type *);
|
||||
bool is_flonum(Type *);
|
||||
bool is_numeric(Type *);
|
||||
bool is_compatible(Type *, Type *);
|
||||
Type *copy_type(Type *);
|
||||
Type *pointer_to(Type *);
|
||||
Type *func_type(Type *);
|
||||
Type *array_of(Type *, int);
|
||||
Type *vla_of(Type *, Node *);
|
||||
Type *enum_type(void);
|
||||
Type *struct_type(void);
|
||||
void add_type(Node *node);
|
||||
void add_type(Node *);
|
||||
|
||||
//
|
||||
// cast.c
|
||||
//
|
||||
|
||||
void gen_cast(Type *, Type *);
|
||||
|
||||
//
|
||||
// codegen.c
|
||||
//
|
||||
|
||||
void codegen(Obj *prog, FILE *out);
|
||||
int align_to(int n, int align);
|
||||
extern int depth;
|
||||
extern FILE *output_stream;
|
||||
|
||||
int align_to(int, int);
|
||||
int count(void);
|
||||
void cmp_zero(Type *);
|
||||
void codegen(Obj *, FILE *);
|
||||
void gen_stmt(Node *);
|
||||
void println(char *, ...) __attribute__((__format__(__printf__, 1, 2)));
|
||||
|
||||
//
|
||||
// unicode.c
|
||||
//
|
||||
|
||||
int encode_utf8(char *buf, uint32_t c);
|
||||
uint32_t decode_utf8(char **new_pos, char *p);
|
||||
bool is_ident1(uint32_t c);
|
||||
bool is_ident2(uint32_t c);
|
||||
int str_width(char *p, int len);
|
||||
int encode_utf8(char *, uint32_t);
|
||||
uint32_t decode_utf8(char **, char *);
|
||||
bool is_ident1(uint32_t);
|
||||
bool is_ident2(uint32_t);
|
||||
int str_width(char *, int);
|
||||
|
||||
//
|
||||
// hashmap.c
|
||||
|
@ -445,29 +547,28 @@ typedef struct {
|
|||
int used;
|
||||
} HashMap;
|
||||
|
||||
void *hashmap_get(HashMap *map, char *key);
|
||||
void *hashmap_get2(HashMap *map, char *key, int keylen);
|
||||
void hashmap_put(HashMap *map, char *key, void *val);
|
||||
void hashmap_put2(HashMap *map, char *key, int keylen, void *val);
|
||||
void hashmap_delete(HashMap *map, char *key);
|
||||
void hashmap_delete2(HashMap *map, char *key, int keylen);
|
||||
void *hashmap_get(HashMap *, char *);
|
||||
void *hashmap_get2(HashMap *, char *, int);
|
||||
void hashmap_put(HashMap *, char *, void *);
|
||||
void hashmap_put2(HashMap *, char *, int, void *);
|
||||
void hashmap_delete(HashMap *, char *);
|
||||
void hashmap_delete2(HashMap *, char *, int);
|
||||
void hashmap_test(void);
|
||||
|
||||
//
|
||||
// main.c
|
||||
// chibicc.c
|
||||
//
|
||||
|
||||
extern StringArray include_paths;
|
||||
extern bool opt_fpic;
|
||||
extern bool opt_fcommon;
|
||||
extern bool opt_fpic;
|
||||
extern bool opt_verbose;
|
||||
extern bool opt_mpopcnt;
|
||||
extern char *base_file;
|
||||
|
||||
typedef struct StaticAsm {
|
||||
struct StaticAsm *next;
|
||||
Node *body;
|
||||
} StaticAsm;
|
||||
|
||||
extern struct StaticAsm *staticasms;
|
||||
extern bool opt_pg;
|
||||
extern bool opt_mfentry;
|
||||
extern bool opt_mnop_mcount;
|
||||
extern bool opt_mrecord_mcount;
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue