├── .gitattributes ├── .gitmodules ├── .firmplugin_update ├── src ├── adt │ ├── array.h │ ├── xmalloc.h │ ├── panic.h │ ├── panic.c │ ├── obst.h │ ├── strutil.h │ ├── separator_t.h │ ├── hash_string.h │ ├── strutil.c │ ├── hashset.h │ ├── pset_new.c │ ├── util.h │ ├── unicode.h │ ├── pset_new.h │ └── bitfiddle.h ├── driver │ ├── version.h │ ├── predefs.h │ ├── actions.h │ ├── tempfile.h │ ├── timing.h │ ├── driver_t.h │ ├── help.h │ ├── options.h │ ├── actions.c │ ├── enable_posix.h │ ├── diagnostic.h │ ├── target.h │ ├── timing.c │ ├── driver.h │ ├── c_driver.h │ ├── tempfile.c │ ├── warning.c │ └── target.c ├── wrappergen │ ├── write_compoundsizes.h │ ├── write_fluffy.h │ ├── write_jna.h │ ├── write_compoundsizes.c │ └── write_fluffy.c ├── firm │ ├── jittest.h │ ├── mangle.h │ ├── ast2firm.h │ ├── jump_target.h │ ├── jump_target.c │ ├── jittest.c │ └── firm_opt.h ├── ast │ ├── type_hash.h │ ├── symbol.h │ ├── symbol_table.h │ ├── symbol_t.h │ ├── position.h │ ├── constfold.h │ ├── walk.h │ ├── string_hash.h │ ├── attribute.h │ ├── symbol_table_t.h │ ├── string_rep.c │ ├── string_rep.h │ ├── dialect.h │ ├── printer.h │ ├── entity.h │ ├── symbol_table.c │ ├── printer.c │ ├── string_hash.c │ ├── constfoldbits.h │ ├── types.h │ ├── entity.c │ ├── attribute_t.h │ ├── ast.h │ ├── type.h │ ├── type_hash.c │ └── entity_t.h └── parser │ ├── format_check.h │ ├── tokens_preprocessor.h │ ├── parser_t.h │ ├── builtins.h │ ├── parser.h │ ├── input.h │ ├── token_t.h │ ├── preprocessor.h │ ├── token.c │ └── tokens.h ├── .gitignore ├── include ├── stdbool.h ├── iso646.h ├── stdarg.h ├── stddef.h ├── limits.h └── float.h ├── .build_plugin ├── AUTHOR ├── support ├── make_release.sh └── check_options.py ├── config.default.mak ├── README.md ├── CMakeLists.txt ├── Makefile └── NEWS.md /.gitattributes: -------------------------------------------------------------------------------- 1 | libfirm export-ignore 2 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "libfirm"] 2 | path = libfirm 3 | url = ../libfirm.git 4 | 5 | -------------------------------------------------------------------------------- /.firmplugin_update: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | ./make_revision.sh "$PLUGINDIR/revision.h" "$PLUGINDIR" cparser_REVISION 3 | -------------------------------------------------------------------------------- /src/adt/array.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of cparser. 3 | * Copyright (C) 2012 Matthias Braun 4 | */ 5 | #include 6 | -------------------------------------------------------------------------------- /src/adt/xmalloc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of cparser. 3 | * Copyright (C) 2012 Matthias Braun 4 | */ 5 | #include 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | /revision.h 3 | /cparser.bootstrap 4 | /cparser.bootstrap2 5 | /cparser.bootstrape 6 | /config.mak 7 | /release 8 | *.vcproj.*.*.user 9 | *.suo 10 | *.ncb 11 | -------------------------------------------------------------------------------- /src/driver/version.h: -------------------------------------------------------------------------------- 1 | #define CPARSER_MAJOR "1" 2 | #define CPARSER_MINOR "22" 3 | #define CPARSER_PATCHLEVEL "1" 4 | #define CPARSER_VERSION CPARSER_MAJOR "." CPARSER_MINOR "." CPARSER_PATCHLEVEL 5 | -------------------------------------------------------------------------------- /src/wrappergen/write_compoundsizes.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of cparser. 3 | * Copyright (C) 2012 Matthias Braun 4 | */ 5 | #include "ast/ast.h" 6 | 7 | void write_compoundsizes(FILE *out, const translation_unit_t *unit); 8 | -------------------------------------------------------------------------------- /include/stdbool.h: -------------------------------------------------------------------------------- 1 | #ifndef _STDBOOL_H 2 | #define _STDBOOL_H 3 | 4 | #ifndef __cplusplus 5 | 6 | #define bool _Bool 7 | #define true 1 8 | #define false 0 9 | 10 | #endif 11 | 12 | #define __bool_true_false_are_defined 1 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /src/firm/jittest.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of cparser. 3 | * Copyright (C) 2016 Matthias Braun 4 | */ 5 | #ifndef FIRM_JITTEST_H 6 | #define FIRM_JITTEST_H 7 | 8 | void jit_compile_execute_main(void); 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /src/driver/predefs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of cparser. 3 | * Copyright (C) 2013 Matthias Braun 4 | */ 5 | #ifndef PREDEFS_H 6 | #define PREDEFS_H 7 | 8 | #include 9 | 10 | void add_predefined_macros(void); 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /src/wrappergen/write_fluffy.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of cparser. 3 | * Copyright (C) 2012 Matthias Braun 4 | */ 5 | #ifndef WRITE_FLUFFY_H 6 | #define WRITE_FLUFFY_H 7 | 8 | #include "ast/ast.h" 9 | 10 | void write_fluffy_decls(FILE *out, const translation_unit_t *unit); 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /src/ast/type_hash.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of cparser. 3 | * Copyright (C) 2012 Matthias Braun 4 | */ 5 | #ifndef TYPE_HASH_H 6 | #define TYPE_HASH_H 7 | 8 | #include "type.h" 9 | 10 | void init_typehash(void); 11 | void exit_typehash(void); 12 | 13 | type_t *typehash_insert(type_t *type); 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /src/driver/actions.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of cparser. 3 | * Copyright (C) 2013 Matthias Braun 4 | */ 5 | #ifndef ACTIONS_H 6 | #define ACTIONS_H 7 | 8 | int action_version(const char *argv0); 9 | 10 | int action_version_short(const char *argv0); 11 | 12 | int action_dumpmachine(const char *argv0); 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /include/iso646.h: -------------------------------------------------------------------------------- 1 | #ifndef _ISO646_H 2 | #define _ISO646_H 3 | 4 | #ifndef __cplusplus 5 | #define and && 6 | #define and_eq &= 7 | #define bitand & 8 | #define bitor | 9 | #define compl ~ 10 | #define not ! 11 | #define not_eq != 12 | #define or || 13 | #define or_eq |= 14 | #define xor ^ 15 | #define xor_eq ^= 16 | #endif 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /src/adt/panic.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of cparser. 3 | * Copyright (C) 2012 Matthias Braun 4 | */ 5 | #ifndef ADT_ERROR_H 6 | #define ADT_ERROR_H 7 | 8 | void __attribute__((noreturn)) panic(char const *file, int line, char const *func, char const *msg, ...); 9 | 10 | #define panic(...) panic(__FILE__, __LINE__, __func__, __VA_ARGS__) 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /src/firm/mangle.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of cparser. 3 | * Copyright (C) 2012 Matthias Braun 4 | */ 5 | #ifndef MANGLE_H 6 | #define MANGLE_H 7 | 8 | #include 9 | 10 | #include "ast/entity.h" 11 | 12 | ident *create_ld_ident(entity_t const *entity); 13 | 14 | void init_mangle(void); 15 | void exit_mangle(void); 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /include/stdarg.h: -------------------------------------------------------------------------------- 1 | #ifndef _STDARG_H 2 | #define _STDARG_H 3 | 4 | typedef __builtin_va_list va_list; 5 | 6 | #define va_start(v,l) __builtin_va_start(v,l) 7 | #define va_end(v) __builtin_va_end(v) 8 | #define va_arg(v,l) __builtin_va_arg(v,l) 9 | #define va_copy(d,s) __builtin_va_copy(d,s) 10 | 11 | typedef va_list __gnuc_va_list; 12 | #define _VA_LIST_DEFINED 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /src/driver/tempfile.h: -------------------------------------------------------------------------------- 1 | #ifndef TEMPFILE_H 2 | #define TEMPFILE_H 3 | 4 | #include 5 | 6 | /** 7 | * Creates temporary files named $name_orig inside a temporary 8 | * directory created with mkdtemp(). 9 | */ 10 | FILE *make_temp_file(const char *name_orig, const char **name_result); 11 | 12 | void init_temp_files(void); 13 | void exit_temp_files(void); 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /src/firm/ast2firm.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of cparser. 3 | * Copyright (C) 2012 Matthias Braun 4 | */ 5 | #ifndef AST2FIRM_H 6 | #define AST2FIRM_H 7 | 8 | #include 9 | 10 | #include "ast/ast.h" 11 | #include "ast/type.h" 12 | 13 | void translation_unit_to_firm(translation_unit_t *unit); 14 | 15 | void exit_ast2firm(void); 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /src/ast/symbol.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of cparser. 3 | * Copyright (C) 2012 Matthias Braun 4 | */ 5 | #ifndef SYMBOL_H 6 | #define SYMBOL_H 7 | 8 | typedef struct symbol_t symbol_t; 9 | typedef struct pp_definition_t pp_definition_t; 10 | 11 | /** special symbol used for anonymous/error entities. */ 12 | extern symbol_t *sym_anonymous; 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /.build_plugin: -------------------------------------------------------------------------------- 1 | DIRS = "" adt driver wrappergen ; 2 | SOURCES = ; 3 | for d in $(DIRS) { 4 | SOURCES += [ Wildcard $(PLUGIN_DIR)/$(d) : *.c *.h ] ; 5 | } 6 | 7 | Application cparser : $(SOURCES) ; 8 | IncludeDir cparser : libfirm/include libfirm/include/libfirm ; 9 | IncludeDir cparser : $(PLUGIN_DIR) ; 10 | CFlags cparser : -std=c99 ; 11 | LinkWith cparser : firm ; 12 | LFlags cparser : -lm ; 13 | -------------------------------------------------------------------------------- /include/stddef.h: -------------------------------------------------------------------------------- 1 | #ifndef _STDDEF_H 2 | #define _STDDEF_H 3 | 4 | typedef __PTRDIFF_TYPE__ ptrdiff_t; 5 | typedef __SIZE_TYPE__ size_t; 6 | typedef __WCHAR_TYPE__ wchar_t; 7 | 8 | #ifndef NULL 9 | #ifndef __cplusplus 10 | #define NULL ((void *)0) 11 | #else 12 | #define NULL 0 13 | #endif 14 | #endif 15 | 16 | #define offsetof(TYPE, MEMBER) __builtin_offsetof (TYPE, MEMBER) 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /src/wrappergen/write_jna.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of cparser. 3 | * Copyright (C) 2012 Matthias Braun 4 | */ 5 | #ifndef WRITE_JNA_H 6 | #define WRITE_JNA_H 7 | 8 | #include "ast/ast.h" 9 | 10 | void jna_limit_output(const char *filename); 11 | 12 | void jna_set_libname(const char *libname); 13 | 14 | void write_jna_decls(FILE *out, const translation_unit_t *unit); 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /AUTHOR: -------------------------------------------------------------------------------- 1 | CParser was written by Matthias Braun 2 | 3 | It probably wouldn't be where it is now without all the bugfixes, new features 4 | and general support by: 5 | 6 | Christoph Mallon (he understands the standard :), bugfixes, 7 | diagnostic infrastructure and printf format checker, 8 | warnings) 9 | Michael Beck (bugfixes, firm optimization driver, warnings, comments) 10 | -------------------------------------------------------------------------------- /src/ast/symbol_table.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of cparser. 3 | * Copyright (C) 2012 Matthias Braun 4 | */ 5 | #ifndef SYMBOL_TABLE_H 6 | #define SYMBOL_TABLE_H 7 | 8 | #include "adt/obst.h" 9 | #include "symbol.h" 10 | 11 | symbol_t *symbol_table_insert(const char *string); 12 | 13 | void init_symbol_table(void); 14 | void exit_symbol_table(void); 15 | 16 | extern struct obstack symbol_obstack; 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /src/adt/panic.c: -------------------------------------------------------------------------------- 1 | #include "panic.h" 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | void (panic)(char const *const file, int const line, char const *const func, char const *const msg, ...) 8 | { 9 | FILE *const out = stderr; 10 | fprintf(out, "%s:%d: panic in %s: ", file, line, func); 11 | va_list ap; 12 | va_start(ap, msg); 13 | vfprintf(out, msg, ap); 14 | va_end(ap); 15 | fputc('\n', out); 16 | abort(); 17 | } 18 | -------------------------------------------------------------------------------- /src/ast/symbol_t.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of cparser. 3 | * Copyright (C) 2012 Matthias Braun 4 | */ 5 | #ifndef SYMBOL_T_H 6 | #define SYMBOL_T_H 7 | 8 | #include "entity.h" 9 | #include "parser/token_t.h" 10 | #include "position.h" 11 | #include "symbol.h" 12 | 13 | struct symbol_t { 14 | char const *string; 15 | token_kind_t ID; 16 | pp_token_kind_t pp_ID; 17 | entity_t *entity; 18 | pp_definition_t *pp_definition; 19 | }; 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /src/adt/obst.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of cparser. 3 | * Copyright (C) 2012 Matthias Braun 4 | */ 5 | #ifndef ADT_OBST_H 6 | #define ADT_OBST_H 7 | 8 | #include "adt/xmalloc.h" 9 | #include 10 | 11 | #define obstack_chunk_alloc xmalloc 12 | #define obstack_chunk_free free 13 | 14 | static inline void *obstack_nul_finish(struct obstack *const obst) 15 | { 16 | obstack_1grow(obst, '\0'); 17 | return obstack_finish(obst); 18 | } 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /src/ast/position.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of cparser. 3 | * Copyright (C) 2012 Matthias Braun 4 | */ 5 | #ifndef POSITION_H 6 | #define POSITION_H 7 | 8 | #include 9 | 10 | typedef struct position_t position_t; 11 | struct position_t { 12 | const char *input_name; 13 | unsigned lineno; 14 | unsigned colno : 31; 15 | bool is_system_header : 1; 16 | }; 17 | 18 | /* position used for "builtin" declarations/types */ 19 | extern const position_t builtin_position; 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /src/parser/format_check.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of cparser. 3 | * Copyright (C) 2012 Matthias Braun 4 | */ 5 | #ifndef FORMAT_CHECK_H 6 | #define FORMAT_CHECK_H 7 | 8 | #include "ast/ast.h" 9 | 10 | typedef enum { 11 | FORMAT_PRINTF, /**< printf style format */ 12 | FORMAT_SCANF, /**< scanf style format */ 13 | FORMAT_STRFTIME, /**< strftime time format */ 14 | FORMAT_STRFMON /**< strfmon monetary format */ 15 | } format_kind_t; 16 | 17 | void check_format(const call_expression_t *call); 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /src/ast/constfold.h: -------------------------------------------------------------------------------- 1 | #ifndef CONSTFOLD_H 2 | #define CONSTFOLD_H 3 | 4 | #include 5 | #include "ast/ast_t.h" 6 | #include "ast/type.h" 7 | 8 | bool fold_expression_to_bool(const expression_t *expression); 9 | long fold_expression_to_int(const expression_t *expression); 10 | bool folded_expression_is_negative(const expression_t *expression); 11 | 12 | ir_tarval *fold_expression(const expression_t *expression); 13 | ir_tarval *get_enum_value(const enum_value_t *enum_value); 14 | 15 | void init_constfold(void); 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /src/driver/timing.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of cparser. 3 | * Copyright (C) 2012 Michael Beck 4 | */ 5 | 6 | /** 7 | * @file 8 | * @brief timing for the Firm compiler 9 | */ 10 | #ifndef TIMING_H 11 | #define TIMING_H 12 | 13 | #include 14 | #include 15 | 16 | void timer_init(void); 17 | void timer_register(ir_timer_t *timer, const char *description); 18 | void timer_term(FILE *f); 19 | void timer_push(ir_timer_t *timer); 20 | void timer_pop(ir_timer_t *timer); 21 | void timer_start(ir_timer_t *timer); 22 | void timer_stop(ir_timer_t *timer); 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /src/parser/tokens_preprocessor.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of cparser. 3 | * Copyright (C) 2012 Matthias Braun 4 | */ 5 | T(CX_LIMITED_RANGE) 6 | T(DEFAULT) 7 | T(FENV_ACCESS) 8 | T(FP_CONTRACT) 9 | T(L) 10 | T(OFF) 11 | T(ON) 12 | T(STDC) 13 | T(U) 14 | T(define) 15 | T(defined) 16 | T(elif) 17 | T(else) /* remember that this gives T_else, not T_IDENTIFIER like most others */ 18 | T(endif) 19 | T(error) 20 | T(ident) 21 | T(if) /* remember that this gives T_if */ 22 | T(ifdef) 23 | T(ifndef) 24 | T(include) 25 | T(include_next) 26 | T(line) 27 | T(pragma) 28 | T(sccs) 29 | T(u) 30 | T(u8) 31 | T(undef) 32 | T(warning) 33 | -------------------------------------------------------------------------------- /src/ast/walk.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of cparser. 3 | * Copyright (C) 2012 Matthias Braun 4 | */ 5 | #ifndef WALK_STATEMENTS_H 6 | #define WALK_STATEMENTS_H 7 | 8 | #include "ast.h" 9 | 10 | typedef void (*statement_callback)(statement_t*, void *env); 11 | typedef void (*expression_callback)(expression_t*, void *env); 12 | typedef void (*declaration_callback)(entity_t*, void *env); 13 | 14 | void walk_translation_unit(translation_unit_t *unit, 15 | declaration_callback, 16 | statement_callback, 17 | expression_callback, 18 | void *env); 19 | 20 | void walk_statements(statement_t*, statement_callback, void *env); 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /src/ast/string_hash.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of cparser. 3 | * Copyright (C) 2014 Matthias Braun 4 | */ 5 | #ifndef STRING_HASH_H 6 | #define STRING_HASH_H 7 | 8 | #include "adt/obst.h" 9 | #include "string_rep.h" 10 | 11 | extern struct obstack string_obst; 12 | 13 | void init_string_hash(void); 14 | void exit_string_hash(void); 15 | 16 | void begin_string_construction(void); 17 | void abort_string_construction(void); 18 | string_t *finish_string_construction(string_encoding_t encoding); 19 | 20 | void begin_string_construction_on(struct obstack *obst); 21 | string_t *finish_string_construction_on(struct obstack *on, 22 | string_encoding_t encoding); 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /src/ast/attribute.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of cparser. 3 | * Copyright (C) 2012 Matthias Braun 4 | */ 5 | #ifndef ATTRIBUTE_H 6 | #define ATTRIBUTE_H 7 | 8 | #include "entity.h" 9 | #include "string_rep.h" 10 | #include "type.h" 11 | 12 | typedef struct attribute_t attribute_t; 13 | 14 | string_t const *get_deprecated_string(attribute_t const *attribute); 15 | 16 | type_t *handle_type_attributes(const attribute_t *attributes, type_t *type); 17 | void handle_entity_attributes(const attribute_t *attributes, entity_t *entity); 18 | type_t *handle_attribute_mode(const attribute_t *attribute, type_t *orig_type); 19 | 20 | /** array of entities using attribute((alias())) */ 21 | extern entity_t **alias_entities; 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /src/parser/parser_t.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of cparser. 3 | * Copyright (C) 2014 Matthias Braun 4 | */ 5 | #ifndef PARSER_T_H 6 | #define PARSER_T_H 7 | 8 | #include "parser.h" 9 | 10 | /** 11 | * record entities for the NAMESPACE_NORMAL, and produce error messages/warnings 12 | * for various problems that occur for multiple definitions 13 | */ 14 | entity_t *record_entity(entity_t *entity, bool is_definition); 15 | 16 | /** 17 | * Merge two declarations/a definition and a declaration. 18 | */ 19 | void merge_into_decl(entity_t *decl, const entity_t *other); 20 | 21 | /** 22 | * Search an entity by its symbol in a given namespace. 23 | */ 24 | entity_t *get_entity(const symbol_t *const symbol, entity_namespace_t namespc); 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /src/firm/jump_target.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of cparser. 3 | * Copyright (C) 2012 Christoph Mallon 4 | */ 5 | #ifndef JUMP_TARGET_H 6 | #define JUMP_TARGET_H 7 | 8 | #include 9 | #include 10 | 11 | typedef struct jump_target { 12 | ir_node *block; 13 | bool first; 14 | } jump_target; 15 | 16 | static inline jump_target init_jump_target(ir_node *const block) 17 | { 18 | return (jump_target){block, false}; 19 | } 20 | 21 | void jump_from_block_to_target(jump_target *tgt, ir_node *block); 22 | 23 | void jump_to_target(jump_target *tgt); 24 | 25 | void add_pred_to_jump_target(jump_target *tgt, ir_node *pred); 26 | 27 | ir_node *enter_jump_target(jump_target *tgt); 28 | 29 | void enter_immature_jump_target(jump_target *tgt); 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /src/ast/symbol_table_t.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of cparser. 3 | * Copyright (C) 2012 Matthias Braun 4 | */ 5 | #ifndef SYMBOL_TABLE_T_H 6 | #define SYMBOL_TABLE_T_H 7 | 8 | #include "symbol.h" 9 | #include "symbol_table.h" 10 | 11 | typedef struct symbol_table_iterator_t symbol_table_iterator_t; 12 | typedef struct symbol_table_t symbol_table_t; 13 | 14 | void symbol_table_iterator_init(symbol_table_iterator_t *iterator); 15 | symbol_t* symbol_table_iterator_next(symbol_table_iterator_t *iterator); 16 | 17 | #define HashSet symbol_table_t 18 | #define HashSetIterator symbol_table_iterator_t 19 | #define HashSetEntry symbol_table_hash_entry_t 20 | #define ValueType symbol_t* 21 | #include "adt/hashset.h" 22 | #undef ValueType 23 | #undef HashSetEntry 24 | #undef HashSet 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /src/driver/driver_t.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of cparser. 3 | * Copyright (C) 2013 Matthias Braun 4 | */ 5 | #ifndef DRIVER_T_H 6 | #define DRIVER_T_H 7 | 8 | #include 9 | #include 10 | 11 | #include "ast/ast.h" 12 | #include "c_driver.h" 13 | #include "driver.h" 14 | 15 | struct compilation_unit_t { 16 | const char *name; /**< filename or "-" for stdin */ 17 | FILE *input; /**< input (NULL if not opened yet) */ 18 | bool input_is_pipe; 19 | const char *original_name; 20 | compilation_unit_type_t type; 21 | lang_standard_t standard; 22 | translation_unit_t *ast; 23 | compilation_unit_t *next; 24 | }; 25 | 26 | struct compilation_env_t { 27 | FILE *out; 28 | const char *outname; 29 | }; 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /src/ast/string_rep.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of cparser. 3 | * Copyright (C) 2012 Matthias Braun 4 | */ 5 | #include "string_rep.h" 6 | 7 | #include "adt/panic.h" 8 | #include "adt/unicode.h" 9 | 10 | static inline size_t wstrlen(const string_t *string) 11 | { 12 | size_t result = 0; 13 | const char *p = string->begin; 14 | const char *end = p + string->size; 15 | while (p < end) { 16 | read_utf8_char(&p); 17 | ++result; 18 | } 19 | return result; 20 | } 21 | 22 | size_t get_string_len(string_t const *const str) 23 | { 24 | switch (str->encoding) { 25 | case STRING_ENCODING_CHAR: 26 | case STRING_ENCODING_UTF8: return str->size; 27 | case STRING_ENCODING_CHAR16: 28 | case STRING_ENCODING_CHAR32: 29 | case STRING_ENCODING_WIDE: return wstrlen(str); 30 | } 31 | panic("invalid string encoding"); 32 | } 33 | -------------------------------------------------------------------------------- /src/adt/strutil.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of cparser. 3 | * Copyright (C) 2012 Christoph Mallon 4 | */ 5 | #ifndef STRUTIL_H 6 | #define STRUTIL_H 7 | 8 | #include 9 | #include 10 | 11 | static inline bool streq(char const* a, char const* b) 12 | { 13 | return strcmp(a, b) == 0; 14 | } 15 | 16 | static inline char const* strstart(char const* str, char const* start) 17 | { 18 | do { 19 | if (*start == '\0') 20 | return str; 21 | } while (*str++ == *start++); 22 | return NULL; 23 | } 24 | 25 | /** 26 | * Test two strings for equality, ignoring double underscores on the second. 27 | */ 28 | bool streq_underscore(const char *s1, const char *s2); 29 | 30 | /** 31 | * Search for start of extension and optionally start of filename. 32 | */ 33 | char const *find_extension(char const *path, char const **name_out); 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /src/adt/separator_t.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of cparser. 3 | * Copyright (C) 2012 Christoph Mallon 4 | */ 5 | #ifndef SEPARATOR_H 6 | #define SEPARATOR_H 7 | 8 | #include 9 | 10 | typedef struct separator_t separator_t; 11 | struct separator_t 12 | { 13 | char const *first; /**< Returned on the first call to sep_next(). */ 14 | char const *rest; /**< Returned on all further calls to sep_next(). */ 15 | }; 16 | 17 | /** 18 | * Returns first on the first call for s and rest on all further calls. 19 | */ 20 | static inline char const* sep_next(separator_t* const s) 21 | { 22 | char const *const cur = s->first; 23 | s->first = s->rest; 24 | return cur; 25 | } 26 | 27 | /** 28 | * Returns whether sep_next() has not been called for s. 29 | */ 30 | static inline bool sep_at_first(separator_t const* const s) 31 | { 32 | return s->first != s->rest; 33 | } 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /src/adt/hash_string.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of cparser. 3 | * Copyright (C) 2012 Matthias Braun 4 | */ 5 | #ifndef _FIRM_HASH_STRING_H_ 6 | #define _FIRM_HASH_STRING_H_ 7 | 8 | #define _FIRM_FNV_OFFSET_BASIS 2166136261U 9 | #define _FIRM_FNV_FNV_PRIME 16777619U 10 | 11 | static inline __attribute__((pure)) 12 | unsigned hash_string(const char* str) 13 | { 14 | const unsigned char *p; 15 | unsigned hash = _FIRM_FNV_OFFSET_BASIS; 16 | 17 | for(p = (const unsigned char*) str; *p != 0; ++p) { 18 | hash *= _FIRM_FNV_FNV_PRIME; 19 | hash ^= *p; 20 | } 21 | 22 | return hash; 23 | } 24 | 25 | static inline __attribute__((pure)) 26 | unsigned hash_string_size(const char* str, size_t size) 27 | { 28 | size_t i; 29 | unsigned hash = _FIRM_FNV_OFFSET_BASIS; 30 | 31 | for(i = 0; i < size; ++i) { 32 | hash *= _FIRM_FNV_FNV_PRIME; 33 | hash ^= str[i]; 34 | } 35 | 36 | return hash; 37 | } 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /src/ast/string_rep.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of cparser. 3 | * Copyright (C) 2012 Matthias Braun 4 | */ 5 | #ifndef STRING_REP_H 6 | #define STRING_REP_H 7 | 8 | #include 9 | 10 | enum string_encoding_t { 11 | STRING_ENCODING_CHAR, 12 | STRING_ENCODING_CHAR16, 13 | STRING_ENCODING_CHAR32, 14 | STRING_ENCODING_UTF8, 15 | STRING_ENCODING_WIDE 16 | }; 17 | typedef enum string_encoding_t string_encoding_t; 18 | 19 | typedef struct string_t { 20 | size_t size; /**< size of string in bytes (not characters), 21 | without terminating \0. */ 22 | string_encoding_t encoding; 23 | void *entity; /**< firm entity if available */ 24 | char begin[]; /**< UTF-8 encoded string, the last character is 25 | guaranteed to be \0. */ 26 | } string_t; 27 | 28 | size_t get_string_len(string_t const *str); 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /src/adt/strutil.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of cparser. 3 | * Copyright (C) 2012 Christoph Mallon 4 | */ 5 | #include "strutil.h" 6 | 7 | bool streq_underscore(const char *const s1, const char *const s2) 8 | { 9 | char const* const middle = strstart(s2, "__"); 10 | if (middle) { 11 | char const* const rest = strstart(middle, s1); 12 | if (rest && streq(rest, "__")) 13 | return true; 14 | } 15 | 16 | return streq(s1, s2); 17 | } 18 | 19 | char const *find_extension(char const *path, char const **const name_out) 20 | { 21 | char const *name = path; 22 | char const *ext = NULL; 23 | for (char const *i = path;; ++i) { 24 | switch (*i) { 25 | case '\0': 26 | if (!ext) 27 | ext = i; 28 | if (name_out) 29 | *name_out = name; 30 | return ext; 31 | 32 | case '.': 33 | ext = i; 34 | break; 35 | 36 | case '/': 37 | name = i + 1; 38 | ext = NULL; 39 | break; 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/parser/builtins.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of cparser. 3 | * Copyright (C) 2012 Matthias Braun 4 | */ 5 | #ifndef BUILTINS_H 6 | #define BUILTINS_H 7 | 8 | #include "ast/entity.h" 9 | 10 | /** 11 | * Create predefined gnu builtins. 12 | */ 13 | void create_gnu_builtins(void); 14 | 15 | /** 16 | * Create predefined MS intrinsics. 17 | */ 18 | void create_microsoft_intrinsics(void); 19 | 20 | /** 21 | * Some functions like setjmp,longjmp are known from libc and need special 22 | * attributes like noreturn or returns_twice. 23 | * (Adding __attribute__(())s in the libc headers would be enough but apparently 24 | * this is not done in most cases since people rely on a list of hardcoded 25 | * names in gcc, so we have to duplicate this here) 26 | */ 27 | void adapt_special_functions(function_t *function); 28 | 29 | /** 30 | * Search for known libc functions in the current scope (must be file top 31 | * scope) and replace them with builtins. 32 | */ 33 | void find_known_libc_functions(void); 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /src/driver/help.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of cparser. 3 | * Copyright (C) 2012 Matthias Braun 4 | */ 5 | #ifndef HELP_H 6 | #define HELP_H 7 | 8 | /** 9 | * Display information about a commandline option 10 | */ 11 | void help_simple(const char *option, const char *explanation); 12 | 13 | /** 14 | * Display a choice value for a multiple-choice option 15 | */ 16 | void put_choice(const char *choice, const char *explanation); 17 | 18 | typedef enum { 19 | HELP_NONE = 0, 20 | HELP_BASIC = 1 << 0, 21 | HELP_PREPROCESSOR = 1 << 1, 22 | HELP_PARSER = 1 << 2, 23 | HELP_WARNINGS = 1 << 3, 24 | HELP_OPTIMIZATION = 1 << 4, 25 | HELP_CODEGEN = 1 << 5, 26 | HELP_LINKER = 1 << 6, 27 | HELP_LANGUAGETOOLS = 1 << 7, 28 | HELP_DEBUG = 1 << 8, 29 | HELP_FIRM = 1 << 9, 30 | 31 | HELP_ALL = -1 32 | } help_sections_t; 33 | 34 | void help_usage(const char *argv0); 35 | 36 | int action_help(const char *argv0); 37 | 38 | extern help_sections_t help; 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /src/ast/dialect.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of cparser. 3 | * Copyright (C) 2012 Matthias Braun 4 | */ 5 | #ifndef DIALECT_H 6 | #define DIALECT_H 7 | 8 | #include 9 | 10 | #define BITS_PER_BYTE 8 11 | 12 | typedef enum lang_features_t { 13 | _C89 = 1U << 0, 14 | _C99 = 1U << 1, 15 | _C11 = 1U << 2, 16 | _CXX = 1U << 3, 17 | _GNUC = 1U << 4, 18 | _MS = 1U << 5, 19 | _ALL = 0xFF 20 | } lang_features_t; 21 | 22 | typedef struct c_dialect_t { 23 | bool freestanding : 1; 24 | bool no_builtins : 1; 25 | bool strict : 1; 26 | bool c89 : 1; 27 | bool c99 : 1; 28 | bool c11 : 1; 29 | bool cpp : 1; 30 | bool gnu : 1; 31 | bool ms : 1; 32 | /** enable hack to add call to __main into the main function (mingw) */ 33 | bool enable_main_collect2_hack : 1; 34 | bool support_fastcall_stdcall : 1; 35 | lang_features_t features; 36 | } c_dialect_t; 37 | 38 | extern c_dialect_t dialect; 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /src/parser/parser.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of cparser. 3 | * Copyright (C) 2012 Matthias Braun 4 | */ 5 | #ifndef PARSER_H 6 | #define PARSER_H 7 | 8 | #include "ast/ast.h" 9 | #include "ast/entity_t.h" 10 | #include "ast/type.h" 11 | 12 | /** 13 | * Initialize parser. Should be called once when the program starts 14 | */ 15 | void init_parser(void); 16 | 17 | /** 18 | * Frees resources occupied by parser. Should be called once before the program 19 | * exits. 20 | */ 21 | void exit_parser(void); 22 | 23 | /** 24 | * Start parsing a new compilation unit 25 | */ 26 | void start_parsing(void); 27 | 28 | /** 29 | * Parse input. The source of the input is determined by the lexer module 30 | */ 31 | void parse(void); 32 | 33 | /** 34 | * Finish parsing a complete compilation unit and return the AST. 35 | */ 36 | translation_unit_t *finish_parsing(void); 37 | 38 | /** set default elf visbility */ 39 | void set_default_visibility(elf_visibility_t visibility); 40 | 41 | /** 42 | * Performs automatic type cast as described in §6.3.2.1. 43 | * 44 | * @param orig_type the original type 45 | */ 46 | type_t *automatic_type_conversion(type_t *orig_type); 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /src/parser/input.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of cparser. 3 | * Copyright (C) 2012 Matthias Braun 4 | */ 5 | #ifndef INPUT_H 6 | #define INPUT_H 7 | 8 | #include 9 | 10 | #include "adt/unicode.h" 11 | 12 | typedef struct input_t input_t; 13 | typedef size_t (input_decoder_t)(input_t *input, utf32 *buffer, size_t buffer_size); 14 | 15 | input_decoder_t *input_get_decoder(const char *encoding); 16 | 17 | input_t *input_from_stream(FILE *stream, input_decoder_t *decoder); 18 | input_t *input_from_string(const char *string, input_decoder_t *decoder); 19 | 20 | input_decoder_t input_decode_utf8; 21 | 22 | /** return underlying FILE* of an input if available, else NULL */ 23 | FILE *input_get_file(const input_t *input); 24 | 25 | /** Type for a function being called on an input (or encoding) errors. */ 26 | typedef void (*input_error_callback_func)(unsigned delta_lines, 27 | unsigned delta_cols, 28 | const char *message); 29 | 30 | void set_input_error_callback(input_error_callback_func func); 31 | 32 | size_t decode(input_t *input, utf32 *buffer, size_t buffer_size); 33 | 34 | void input_free(input_t *input); 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /src/adt/hashset.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of libFirm. 3 | * Copyright (C) 2012 University of Karlsruhe. 4 | */ 5 | 6 | /** 7 | * @file 8 | * @date 16.03.2007 9 | * @brief Generic hashset functions 10 | * @author Matthias Braun 11 | * 12 | * You have to specialize this header by defining HashSet, HashSetIterator and 13 | * ValueType 14 | */ 15 | #ifdef HashSet 16 | 17 | #include 18 | 19 | #ifdef DO_REHASH 20 | #define HashSetEntry ValueType 21 | #else 22 | typedef struct HashSetEntry { 23 | ValueType data; 24 | unsigned hash; 25 | } HashSetEntry; 26 | #endif 27 | 28 | struct HashSet { 29 | HashSetEntry *entries; 30 | size_t num_buckets; 31 | size_t enlarge_threshold; 32 | size_t shrink_threshold; 33 | size_t num_elements; 34 | size_t num_deleted; 35 | int consider_shrink; 36 | #ifndef NDEBUG 37 | unsigned entries_version; 38 | #endif 39 | #ifdef ADDITIONAL_DATA 40 | ADDITIONAL_DATA 41 | #endif 42 | }; 43 | 44 | #ifdef HashSetIterator 45 | struct HashSetIterator { 46 | HashSetEntry *current_bucket; 47 | HashSetEntry *end; 48 | #ifndef NDEBUG 49 | const struct HashSet *set; 50 | unsigned entries_version; 51 | #endif 52 | }; 53 | #endif 54 | 55 | #ifdef DO_REHASH 56 | #undef HashSetEntry 57 | #endif 58 | 59 | #endif 60 | -------------------------------------------------------------------------------- /src/adt/pset_new.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of cparser. 3 | * Copyright (C) 2012 University of Karlsruhe. 4 | */ 5 | 6 | /** 7 | * @file 8 | * @brief implementation of pset_new 9 | * @author Matthias Braun 10 | */ 11 | #include "pset_new.h" 12 | 13 | /** probing method: quadratic probing */ 14 | #define DO_REHASH 15 | #define ID_HASH 16 | #define HashSet pset_new_t 17 | #define HashSetIterator pset_new_iterator_t 18 | #define ValueType void* 19 | #define NullValue NULL 20 | #define DeletedValue ((void*)-1) 21 | #define KeysEqual(this,key1,key2) 1 22 | #define SetRangeEmpty(ptr,size) memset(ptr, 0, (size) * sizeof(HashSetEntry)) 23 | 24 | #define hashset_init pset_new_init 25 | #define hashset_init_size pset_new_init_size 26 | #define hashset_destroy pset_new_destroy 27 | #define hashset_insert pset_new_insert 28 | #define hashset_remove pset_new_remove 29 | #define hashset_find pset_new_contains 30 | #define hashset_size pset_new_size 31 | #define hashset_iterator_init pset_new_iterator_init 32 | #define hashset_iterator_next pset_new_iterator_next 33 | #define hashset_remove_iterator pset_new_remove_iterator 34 | 35 | #include "hashset.c.h" 36 | -------------------------------------------------------------------------------- /include/limits.h: -------------------------------------------------------------------------------- 1 | #ifndef _CPARSER_LIMITS_H____ 2 | #define _CPARSER_LIMITS_H____ 3 | 4 | /* for gcc compatibility */ 5 | #define _GCC_LIMITS_H_ 6 | 7 | #include_next 8 | 9 | /* note: we do not define MB_LEN_MAX */ 10 | #define CHAR_BIT __CHAR_BIT__ 11 | #define SCHAR_MIN (-SCHAR_MAX - 1) 12 | #define SCHAR_MAX __SCHAR_MAX__ 13 | #if __SCHAR_MAX__ == __INT_MAX__ 14 | # define UCHAR_MAX (SCHAR_MAX * 2U + 1U) 15 | #else 16 | # define UCHAR_MAX (SCHAR_MAX * 2 + 1) 17 | #endif 18 | #ifdef __CHAR_UNSIGNED__ 19 | # if __SCHAR_MAX__ == __INT_MAX__ 20 | # define CHAR_MIN 0U 21 | # else 22 | # define CHAR_MIN 0 23 | # endif 24 | # define CHAR_MAX UCHAR_MAX 25 | #else 26 | # define CHAR_MIN SCHAR_MIN 27 | # define CHAR_MAX SCHAR_MAX 28 | #endif 29 | 30 | #define SHRT_MIN (-SHRT_MAX - 1) 31 | #define SHRT_MAX __SHRT_MAX__ 32 | #if __SHRT_MAX__ == __INT_MAX__ 33 | # define USHRT_MAX (SHRT_MAX * 2U + 1U) 34 | #else 35 | # define USHRT_MAX (SHRT_MAX * 2 + 1) 36 | #endif 37 | #define INT_MIN (-INT_MAX - 1) 38 | #define INT_MAX __INT_MAX__ 39 | #define UINT_MAX (INT_MAX * 2U + 1U) 40 | #define LONG_MIN (-LONG_MAX - 1L) 41 | #define LONG_MAX __LONG_MAX__ 42 | #define ULONG_MAX (LONG_MAX * 2UL + 1UL) 43 | #define LLONG_MIN (-LLONG_MAX - 1LL) 44 | #define LLONG_MAX __LONG_LONG_MAX__ 45 | #define ULLONG_MAX (LLONG_MAX * 2ULL + 1ULL) 46 | 47 | #else 48 | 49 | #include_next 50 | 51 | #endif 52 | -------------------------------------------------------------------------------- /src/driver/options.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of cparser. 3 | * Copyright (C) 2013 Matthias Braun 4 | */ 5 | #ifndef OPTIONS_H 6 | #define OPTIONS_H 7 | 8 | #include 9 | 10 | typedef int (*action_func)(const char *argv0); 11 | 12 | typedef struct options_state_t { 13 | int argc; 14 | char **argv; 15 | int i; 16 | bool argument_errors; 17 | bool had_inputs; 18 | action_func action; 19 | } options_state_t; 20 | 21 | bool options_parse_early_target(options_state_t *state); 22 | bool options_parse_early_codegen(options_state_t *state); 23 | bool options_parse_early_sysroot(options_state_t *state); 24 | 25 | bool options_parse_assembler(options_state_t *state); 26 | bool options_parse_c_dialect(options_state_t *state); 27 | bool options_parse_codegen(options_state_t *state); 28 | bool options_parse_diagnostics(options_state_t *state); 29 | bool options_parse_driver(options_state_t *state); 30 | bool options_parse_help(options_state_t *state); 31 | bool options_parse_linker(options_state_t *state); 32 | bool options_parse_preprocessor(options_state_t *state); 33 | 34 | bool action_print_help(const char *argv0); 35 | void setup_target_machine(void); 36 | 37 | char const *spaced_arg(char const *arg, options_state_t *s); 38 | bool simple_arg(const char *arg, options_state_t *s); 39 | 40 | bool parse_target_triple(char const *arg); 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /src/driver/actions.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of cparser. 3 | * Copyright (C) 2013 Matthias Braun 4 | */ 5 | #include "actions.h" 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include "driver.h" 13 | #include "target.h" 14 | #include "version.h" 15 | #include 16 | 17 | int action_version(const char *argv0) 18 | { 19 | (void)argv0; 20 | printf("cparser %s.%s.%s", 21 | CPARSER_MAJOR, CPARSER_MINOR, CPARSER_PATCHLEVEL); 22 | if (cparser_REVISION[0] != '\0') { 23 | printf("(%s)", cparser_REVISION); 24 | } 25 | printf(" using libFirm %u.%u", 26 | ir_get_version_major(), ir_get_version_minor()); 27 | 28 | const char *revision = ir_get_version_revision(); 29 | if (revision[0] != 0) { 30 | printf("(%s)", revision); 31 | } 32 | putchar('\n'); 33 | return EXIT_SUCCESS; 34 | } 35 | 36 | int action_version_short(const char *argv0) 37 | { 38 | (void)argv0; 39 | printf("%s.%s.%s\n", 40 | CPARSER_MAJOR, CPARSER_MINOR, CPARSER_PATCHLEVEL); 41 | return EXIT_SUCCESS; 42 | } 43 | 44 | int action_dumpmachine(const char *argv0) 45 | { 46 | (void)argv0; 47 | ir_machine_triple_t const *const machine = target.machine; 48 | printf("%s-%s-%s\n", ir_triple_get_cpu_type(machine), 49 | ir_triple_get_manufacturer(machine), 50 | ir_triple_get_operating_system(machine)); 51 | return EXIT_SUCCESS; 52 | } 53 | -------------------------------------------------------------------------------- /src/driver/enable_posix.h: -------------------------------------------------------------------------------- 1 | /* make sure we have some posix functions available. Include this file first! */ 2 | 3 | #if defined(_WIN32) && !defined(__CYGWIN__) 4 | #include 5 | #include 6 | 7 | /* no eXecute on Win32 */ 8 | #define X_OK 0 9 | #define W_OK 2 10 | #define R_OK 4 11 | 12 | #define O_RDWR _O_RDWR 13 | #define O_CREAT _O_CREAT 14 | #define O_EXCL _O_EXCL 15 | #define O_BINARY _O_BINARY 16 | 17 | /* remap some names, we are not in the POSIX world */ 18 | #define access(fname, mode) _access(fname, mode) 19 | #define fdopen(fd, mode) _fdopen(fd, mode) 20 | #define isatty(fd) _isatty(fd) 21 | #define mktemp(tmpl) _mktemp(tmpl) 22 | #define mkdir(name, mode) _mkdir(name) 23 | #define open(fname, oflag, mode) _open(fname, oflag, mode) 24 | #define pclose(file) _pclose(file) 25 | #define popen(cmd, mode) _popen(cmd, mode) 26 | #define unlink(filename) _unlink(filename) 27 | 28 | #ifndef STDOUT_FILENO 29 | #define STDOUT_FILENO _fileno(stdout) 30 | #endif 31 | #ifndef STDERR_FILENO 32 | #define STDERR_FILENO _fileno(stderr) 33 | #endif 34 | 35 | #else 36 | # ifdef __APPLE__ 37 | # define _DARWIN_C_SOURCE /* Required for mkdtemp(). */ 38 | # endif 39 | #define _POSIX_C_SOURCE 200809L 40 | #include 41 | #include 42 | #define HAVE_MKDTEMP 43 | #define HAVE_FILENO 44 | #define HAVE_ASCTIME_R 45 | #define HAVE_FSTAT 46 | #endif 47 | -------------------------------------------------------------------------------- /src/driver/diagnostic.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of cparser. 3 | * Copyright (C) 2012 Matthias Braun 4 | */ 5 | #ifndef DIAGNOSTIC_H 6 | #define DIAGNOSTIC_H 7 | 8 | #include 9 | 10 | #include "ast/position.h" 11 | #include "warning.h" 12 | 13 | /** 14 | * Issue a diagnostic message. 15 | * Format types: 16 | * %E expression_t const* 17 | * %K token_t const* 18 | * %k token_kind_t 19 | * %lk va_list* 20 | * %N entity_t const* 21 | * %#N entity_t const* 22 | * %Q unsigned (qualifier) 23 | * %S string_t const* 24 | * %T type_t const* 25 | * %Y symbol_t const* 26 | */ 27 | void errorf(const position_t *pos, const char *fmt, ...); 28 | 29 | /** 30 | * Issue a diagnostic message with the prefix "note:". 31 | */ 32 | void notef(position_t const *pos, char const *fmt, ...); 33 | 34 | /** 35 | * Issue a diagnostic message with the prefix "warning:" and increase the 36 | * warning count, if the given warning is activated. 37 | * 38 | * @return Whether the diagnostic was shown. 39 | */ 40 | bool warningf(warning_t, position_t const *pos, char const *fmt, ...); 41 | 42 | extern unsigned error_count; 43 | extern bool show_column; /**< Show column in diagnostic messages */ 44 | extern bool diagnostics_show_option; /**< Show the switch, which controls a warning. */ 45 | 46 | /** enable color output, allowed values for n_cols are 0, 8 and 256 */ 47 | void diagnostic_enable_color(int n_cols); 48 | 49 | void print_diagnostic_summary(void); 50 | 51 | #endif 52 | -------------------------------------------------------------------------------- /src/ast/printer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of cparser. 3 | * Copyright (C) 2012 Matthias Braun 4 | */ 5 | 6 | /** 7 | * @file 8 | * @brief Abstracts away printing strings to a stream so we can reuse our 9 | * printing routines for printing to files or into memory 10 | */ 11 | #ifndef PRINTER_H 12 | #define PRINTER_H 13 | 14 | #include 15 | #include 16 | 17 | #include "adt/obst.h" 18 | 19 | /** print a string into current output */ 20 | extern void (*print_string)(const char *str); 21 | extern void (*print_vformat)(const char *format, va_list ap); 22 | extern void (*print_char)(const char c); 23 | 24 | /** print a printf style format string to current output */ 25 | static inline void __attribute__((format(printf,1,2))) 26 | print_format(const char *format, ...) 27 | { 28 | va_list ap; 29 | va_start(ap, format); 30 | print_vformat(format, ap); 31 | va_end(ap); 32 | } 33 | 34 | /** Set current output to be a FILE* stream */ 35 | void print_to_file(FILE *out); 36 | 37 | /** Set current output to an obstack (grows an object on the obstack) */ 38 | void print_to_obstack(struct obstack *obst); 39 | 40 | /** Set current output to be a buffer with limited size */ 41 | void print_to_buffer(char *buffer, size_t buffer_size); 42 | 43 | /** Assures that the string in the buffer is 0 terminated */ 44 | void finish_print_to_buffer(void); 45 | 46 | /** push current printer output to the (printer output) stack */ 47 | void printer_push(void); 48 | 49 | /** pop a printer output from the stack */ 50 | void printer_pop(void); 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /src/wrappergen/write_compoundsizes.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of cparser. 3 | * Copyright (C) 2012 Matthias Braun 4 | */ 5 | #include "ast/ast_t.h" 6 | #include "ast/attribute_t.h" 7 | #include "ast/entity_t.h" 8 | #include "ast/type_t.h" 9 | #include "write_compoundsizes.h" 10 | 11 | void write_compoundsizes(FILE *output, const translation_unit_t *unit) 12 | { 13 | for (const entity_t *entity = unit->scope.first_entity; entity != NULL; 14 | entity = entity->base.next) { 15 | if (entity->kind != ENTITY_TYPEDEF) 16 | continue; 17 | 18 | type_t *type = skip_typeref(entity->declaration.type); 19 | if (!is_type_compound(type)) 20 | continue; 21 | 22 | /* see if we have the required attributes */ 23 | const compound_t *compound = type->compound.compound; 24 | bool had_dllexport = false; 25 | const char *string = NULL; 26 | for (const attribute_t *attrib = compound->attributes; 27 | attrib != NULL; attrib = attrib->next) { 28 | if (attrib->kind == ATTRIBUTE_GNU_DLLEXPORT) 29 | had_dllexport = true; 30 | if (attrib->kind == ATTRIBUTE_GNU_DEPRECATED) { 31 | const attribute_argument_t *argument = attrib->a.arguments; 32 | assert(argument != NULL && argument->kind == ATTRIBUTE_ARGUMENT_EXPRESSION); 33 | const expression_t *expr = argument->v.expression; 34 | assert(expr->kind == EXPR_STRING_LITERAL); 35 | string = expr->string_literal.value->begin; 36 | } 37 | } 38 | 39 | if (had_dllexport && string != NULL) { 40 | fprintf(output, "%s %u\n", string, get_ctype_size(type)); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /support/make_release.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -eu 3 | 4 | if ! test -e .git; then 5 | echo "Must be started from toplevel cparser dir" 6 | exit 1 7 | fi 8 | # Check that our git checkout is clean (remember that we use git archive 9 | # which will miss things uncommitted changes) 10 | if [ "$(git status --porcelain)" != "" ]; then 11 | echo "Git checkout not clean!" 12 | exit 1 13 | fi 14 | 15 | WORKDIR="release" 16 | VERSION_MAJOR="1" 17 | VERSION_MINOR="22" 18 | VERSION_MICRO="1" 19 | VERSION="${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_MICRO}" 20 | VERSIONFILE=src/driver/version.h 21 | 22 | # test if versions match 23 | echo "Checking version in $VERSIONFILE" 24 | egrep -q "#define CPARSER_MAJOR\\s*\"$VERSION_MAJOR\"" "$VERSIONFILE" 25 | egrep -q "#define CPARSER_MINOR\\s*\"$VERSION_MINOR\"" "$VERSIONFILE" 26 | egrep -q "#define CPARSER_PATCHLEVEL\\s*\"$VERSION_MICRO\"" "$VERSIONFILE" 27 | echo "Checking version in CMakeLists.txt" 28 | grep -q "set(cparser_VERSION \"${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_MICRO}\")" CMakeLists.txt 29 | echo "Checking version in config.default.mak" 30 | egrep -q "VERSION\\s*=\\s*$VERSION_MAJOR\\.$VERSION_MINOR\\.$VERSION_MICRO" config.default.mak 31 | echo "Checking version in NEWS.md" 32 | egrep -q "$VERSION_MAJOR.$VERSION_MINOR.$VERSION_MICRO" NEWS.md 33 | 34 | RELEASEBZ2="build/cparser-$VERSION.tar.bz2" 35 | echo "creating $RELEASEBZ2" 36 | mkdir -p "$(dirname "$RELEASEBZ2")" 37 | git archive --prefix cparser-$VERSION/ HEAD | bzip2 -9 > "$RELEASEBZ2" 38 | 39 | RELEASEGZ="build/cparser-$VERSION.tar.gz" 40 | echo "creating $RELEASEGZ" 41 | mkdir -p "$(dirname "$RELEASEGZ")" 42 | git archive --prefix cparser-$VERSION/ HEAD | gzip -9 > "$RELEASEGZ" 43 | 44 | RELEASEXZ="build/cparser-$VERSION.tar.xz" 45 | echo "creating $RELEASEXZ" 46 | mkdir -p "$(dirname "$RELEASEXZ")" 47 | git archive --prefix cparser-$VERSION/ HEAD | xz -9 > "$RELEASEXZ" 48 | -------------------------------------------------------------------------------- /src/driver/target.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of cparser. 3 | * Copyright (C) 2014 Matthias Braun 4 | */ 5 | #ifndef TARGET_H 6 | #define TARGET_H 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | #include "adt/util.h" 13 | #include "firm/firm_opt.h" 14 | #include "options.h" 15 | 16 | typedef struct target_t { 17 | char user_label_prefix; 18 | unsigned char biggest_alignment; 19 | bool pic : 1; 20 | bool set_pic : 1; 21 | bool pic_noplt : 1; 22 | bool set_noplt : 1; 23 | bool byte_order_big_endian : 1; 24 | bool set_use_frame_pointer : 1; 25 | bool use_frame_pointer : 1; 26 | /** parsed machine-triple of target machine. Try not to use this if possible 27 | * but create specific variables for language/target features instead. */ 28 | ir_machine_triple_t *machine; 29 | /** target triple as a string */ 30 | const char *triple; 31 | } target_t; 32 | 33 | extern target_t target; 34 | 35 | void init_firm_target(void); 36 | bool target_setup(void); 37 | 38 | void target_adjust_types_and_dialect(void); 39 | 40 | void set_target_option(char const *arg); 41 | 42 | typedef struct codegen_option_t codegen_option_t; 43 | struct codegen_option_t { 44 | codegen_option_t *next; 45 | char option[]; 46 | }; 47 | 48 | extern optimization_level_t opt_level; 49 | extern codegen_option_t *codegen_options; 50 | extern codegen_option_t **codegen_options_anchor; 51 | extern bool profile_generate; 52 | extern bool profile_use; 53 | extern const char *multilib_directory_target_triple; 54 | extern unsigned target_size_override; 55 | extern bool set_wchar; 56 | extern bool short_wchar; 57 | extern bool unsigned_char; 58 | 59 | #endif 60 | -------------------------------------------------------------------------------- /src/firm/jump_target.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of cparser. 3 | * Copyright (C) 2012 Christoph Mallon 4 | */ 5 | #include "jump_target.h" 6 | 7 | #include "adt/util.h" 8 | 9 | void jump_from_block_to_target(jump_target *const tgt, ir_node *const block) 10 | { 11 | if (!tgt->block) { 12 | tgt->block = block; 13 | tgt->first = true; 14 | return; 15 | } else if (tgt->first) { 16 | ir_node *const jmp = new_r_Jmp(tgt->block); 17 | tgt->block = new_immBlock(); 18 | tgt->first = false; 19 | add_immBlock_pred(tgt->block, jmp); 20 | } 21 | ir_node *const jmp = new_r_Jmp(block); 22 | add_immBlock_pred(tgt->block, jmp); 23 | } 24 | 25 | void jump_to_target(jump_target *const tgt) 26 | { 27 | ir_node *const block = get_cur_block(); 28 | if (block) 29 | jump_from_block_to_target(tgt, block); 30 | } 31 | 32 | void add_pred_to_jump_target(jump_target *const tgt, ir_node *const pred) 33 | { 34 | if (!tgt->block) { 35 | tgt->block = new_immBlock(); 36 | } else if (tgt->first) { 37 | ir_node *const jmp = new_r_Jmp(tgt->block); 38 | tgt->block = new_immBlock(); 39 | tgt->first = false; 40 | add_immBlock_pred(tgt->block, jmp); 41 | } 42 | add_immBlock_pred(tgt->block, pred); 43 | } 44 | 45 | ir_node *enter_jump_target(jump_target *const tgt) 46 | { 47 | ir_node *const block = tgt->block; 48 | if (block && !tgt->first) 49 | mature_immBlock(block); 50 | set_cur_block(block); 51 | return block; 52 | } 53 | 54 | void enter_immature_jump_target(jump_target *const tgt) 55 | { 56 | ir_node *jmp; 57 | ir_node *block = tgt->block; 58 | if (!block) { 59 | /* Avoid unreachable loops by adding a Bad entry. */ 60 | jmp = new_Bad(mode_X); 61 | goto new_block; 62 | } else if (tgt->first) { 63 | tgt->first = false; 64 | jmp = new_r_Jmp(block); 65 | new_block: 66 | tgt->block = block = new_immBlock(); 67 | add_immBlock_pred(block, jmp); 68 | } 69 | set_cur_block(block); 70 | } 71 | -------------------------------------------------------------------------------- /src/driver/timing.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of cparser. 3 | * Copyright (C) 2012 Michael Beck 4 | */ 5 | 6 | /** 7 | * @file 8 | * @brief timing for the Firm compiler 9 | */ 10 | #include "timing.h" 11 | 12 | #include 13 | 14 | static int timers_inited; 15 | 16 | typedef struct timer_info_t { 17 | struct timer_info_t *next; 18 | char *description; 19 | ir_timer_t *timer; 20 | } timer_info_t; 21 | 22 | static timer_info_t *infos; 23 | static timer_info_t *last_info; 24 | 25 | void timer_register(ir_timer_t *timer, const char *description) 26 | { 27 | timer_info_t *info = XMALLOCZ(timer_info_t); 28 | 29 | info->description = xstrdup(description); 30 | info->timer = timer; 31 | 32 | if (last_info != NULL) { 33 | last_info->next = info; 34 | } else { 35 | infos = info; 36 | } 37 | last_info = info; 38 | } 39 | 40 | void timer_init(void) 41 | { 42 | timers_inited = 1; 43 | } 44 | 45 | void timer_term(FILE *f) 46 | { 47 | for (timer_info_t *next, *info = infos; info != NULL; info = next) { 48 | next = info->next; 49 | ir_timer_t *timer = info->timer; 50 | if (f != NULL) { 51 | double val = (double)ir_timer_elapsed_usec(timer) / 1000.0; 52 | const char *description = info->description; 53 | fprintf(f, "%-60s %10.3f msec\n", description, val); 54 | } 55 | 56 | ir_timer_free(timer); 57 | free(info->description); 58 | free(info); 59 | } 60 | infos = NULL; 61 | last_info = NULL; 62 | 63 | timers_inited = 0; 64 | } 65 | 66 | void timer_push(ir_timer_t *timer) 67 | { 68 | if (timers_inited) 69 | ir_timer_push(timer); 70 | } 71 | 72 | void timer_pop(ir_timer_t *timer) 73 | { 74 | if (timers_inited) 75 | ir_timer_pop(timer); 76 | } 77 | 78 | void timer_start(ir_timer_t *timer) 79 | { 80 | if (timers_inited) 81 | ir_timer_start(timer); 82 | } 83 | 84 | void timer_stop(ir_timer_t *timer) 85 | { 86 | if (timers_inited) 87 | ir_timer_stop(timer); 88 | } 89 | -------------------------------------------------------------------------------- /src/adt/util.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of cparser. 3 | * Copyright (C) 2012 Matthias Braun 4 | */ 5 | 6 | /** 7 | * @file 8 | * @date 16.03.2007 9 | * @brief Various utility functions that wrap compiler specific extensions 10 | * @author Matthias Braun 11 | */ 12 | #ifndef _FIRM_UTIL_H_ 13 | #define _FIRM_UTIL_H_ 14 | 15 | #include 16 | 17 | /** 18 | * Returns size of a static array. Warning: This returns invalid values for 19 | * dynamically allocated arrays. 20 | * 21 | * @param a static array 22 | */ 23 | #define ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0])) 24 | 25 | /** 26 | * Asserts that the constant expression x is not zero at compiletime. name has 27 | * to be a unique identifier. 28 | * 29 | * @note This uses the fact, that double case labels are not allowed. 30 | */ 31 | #define COMPILETIME_ASSERT(x, name) \ 32 | static __attribute__((unused)) void compiletime_assert_##name (int h) { \ 33 | switch(h) { case 0: case (x): {} } \ 34 | } 35 | 36 | /** 37 | * Indicates to the compiler that the value of x is very likely 1 38 | * @note Only use this in speed critical code and when you are sure x is often 1 39 | */ 40 | #define LIKELY(x) __builtin_expect((x), 1) 41 | /** 42 | * Indicates to the compiler that it's very likely that x is 0 43 | * @note Only use this in speed critical code and when you are sure x is often 0 44 | */ 45 | #define UNLIKELY(x) __builtin_expect((x), 0) 46 | 47 | #ifdef __GNUC__ 48 | #define ENUMBF(type) __extension__ type 49 | #else 50 | #define ENUMBF(type) unsigned 51 | #endif 52 | 53 | #define endof(x) ((x) + ARRAY_SIZE(x)) 54 | 55 | #undef MAX 56 | #undef MIN 57 | #define MAX(a, b) ((a) > (b) ? (a) : (b)) 58 | #define MIN(a, b) ((a) < (b) ? (a) : (b)) 59 | 60 | static inline bool is_alpha(char const c) 61 | { 62 | return ('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z'); 63 | } 64 | 65 | static inline bool is_digit(char const c) 66 | { 67 | return '0' <= c && c <= '9'; 68 | } 69 | 70 | #endif 71 | -------------------------------------------------------------------------------- /config.default.mak: -------------------------------------------------------------------------------- 1 | VERSION = 1.22.1 2 | 3 | # Use libfirm subdir if it exists, otherwise use pkg-config 4 | ifneq ("$(wildcard $(top_srcdir)/libfirm)", "") 5 | FIRM_HOME ?= $(top_srcdir)/libfirm 6 | FIRM_CPPFLAGS ?= -I$(FIRM_HOME)/include -I$(FIRM_HOME)/build/gen/include/libfirm 7 | FIRM_LIBS ?= -lm 8 | LIBFIRM_FILE_BASE ?= build/$(variant)/libfirm.a 9 | LIBFIRM_FILE ?= $(FIRM_HOME)/$(LIBFIRM_FILE_BASE) 10 | LIBFIRM_FILE_DLL_BASE ?= build/$(variant)/libfirm$(DLLEXT) 11 | LIBFIRM_FILE_DLL ?= $(FIRM_HOME)/$(LIBFIRM_FILE_DLL_BASE) 12 | else 13 | PKG_CONFIG ?= pkg-config 14 | FIRM_CPPFLAGS ?= $(shell $(PKG_CONFIG) --cflags libfirm) 15 | FIRM_LIBS ?= $(shell $(PKG_CONFIG) --libs libfirm) 16 | LIBFIRM_FILE = 17 | LIBFIRM_FILE_DLL = 18 | endif 19 | 20 | ifeq ("$(shell uname)", "Darwin") 21 | # Query xcrun if /usr/include does not exist (new darwin versions) 22 | ifeq ("$(wildcard /usr/include)", "") 23 | SYSTEM_INCLUDE_DIR ?= "$(shell xcrun -show-sdk-path)/usr/include" 24 | endif 25 | endif 26 | 27 | # location of the system/libc headers 28 | SYSTEM_INCLUDE_DIR ?= /usr/include 29 | # if MULTILIB_M32_TRIPLE is defined, then we append a directory with the 30 | # machine triple to the system and local directory. i.e. if the target triple 31 | # is i386-linux-gnu we append $SYSTEM_INCLUDE_DIR/i386-linux-gnu and 32 | ifneq ("$(wildcard $(SYSTEM_INCLUDE_DIR)/x86_64-linux-gnu)","") 33 | # $LOCAL_INCLUDE_DIR/i386-linux-gnu. 34 | # -m32 triple: 35 | MULTILIB_M32_TRIPLE ?= i386-linux-gnu 36 | # -m64 triple: 37 | MULTILIB_M64_TRIPLE ?= x86_64-linux-gnu 38 | endif 39 | 40 | # location of additional headers 41 | LOCAL_INCLUDE_DIR ?= /usr/local/include 42 | # location of the compiler provided headers. If PREFIX is not set we assume that 43 | # we have a developer who wants to run cparser from source/builddir without 44 | # installing it. 45 | ifndef PREFIX 46 | COMPILER_INCLUDE_DIR ?= "$(abspath $(srcdir))/include" 47 | else 48 | COMPILER_INCLUDE_DIR ?= $(PREFIX)/lib/cparser/$(VERSION)/include 49 | endif 50 | -------------------------------------------------------------------------------- /support/check_options.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import re 3 | import sys 4 | import collections 5 | 6 | # Search for defined options 7 | optionsfile = open("src/driver/options.c").readlines() + open("src/main.c").readlines() 8 | functions = [ 'simple_arg', 'prefix_arg', 'spaced_arg', 'equals_arg', 9 | 'f_yesno_arg' ] 10 | regex = '(?P' + "|".join(functions) + ')' 11 | regex += '\s*\(\s*"(?P