cpp.h 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. #ifndef __c_cpp_h__
  2. #define __c_cpp_h__
  3. #include "lexer.h"
  4. #include "sti/sti.h"
  5. typedef struct cpp_error {
  6. long line;
  7. long col;
  8. } cpp_error_t;
  9. typedef struct cpp_token_list {
  10. VEC(lexer_token_t*) tokens;
  11. } cpp_token_list_t;
  12. typedef struct cpp_macro_def {
  13. char* name;
  14. unsigned int obj_like : 1;
  15. unsigned int fn_like : 1;
  16. unsigned int special : 1;
  17. unsigned int variadic : 1;
  18. VEC(char*) args;
  19. cpp_token_list_t body;
  20. } cpp_macro_def_t;
  21. typedef struct cpp_macro_invocation {
  22. cpp_macro_def_t* def;
  23. VEC(cpp_token_list_t*) in_args;
  24. VEC(cpp_token_list_t*) in_args_expanded;
  25. cpp_token_list_t* replaced; // after arg exansion and replacement, before re-scan
  26. cpp_token_list_t* output; // final fully-expanded token list
  27. } cpp_macro_invocation_t;
  28. typedef struct cpp_macro_name {
  29. VEC(cpp_macro_def_t*) defs;
  30. int invoked;
  31. } cpp_macro_name_t;
  32. typedef struct cpp_macro_if {
  33. cpp_token_list_t* raw;
  34. cpp_token_list_t* expanded;
  35. long result; // final result of the controlling expression
  36. char disabled_higher; // flag for if a higher layer has already disabled output
  37. char net_enabled; // whether this block is enabled all things considered
  38. char type; // 'i' = if, d = ifdef, n = ifndef, e = else, 'l' = elif
  39. int decl_line; // first line with this block's #if/#else on it
  40. int first_controlled_line; // first and last line of the interior block
  41. int last_controlled_line;
  42. struct cpp_macro_if* parent; // for nested conditionals
  43. struct cpp_macro_if* first; // the first #if in the chain
  44. struct cpp_macro_if* prev, *next; // the chain of #elif/#elses
  45. } cpp_macro_if_t;
  46. typedef struct cpp_stack_token {
  47. char type;
  48. char arity;
  49. char prec;
  50. char assoc;
  51. } cpp_stack_token_t;
  52. typedef struct cpp_file {
  53. char* name;
  54. char* dir;
  55. char* full_path;
  56. cpp_token_list_t* raw_tokens; // used for unguarded files
  57. cpp_token_list_t* expanded_tokens; // used for guarded files
  58. unsigned int is_system_header : 1;
  59. unsigned int is_guarded : 1;
  60. unsigned int already_included : 1;
  61. VEC(struct cpp_tile_t*) includes;
  62. VEC(struct cpp_tile_t*) included_by;
  63. } cpp_file_t;
  64. typedef struct cpp_context {
  65. cpp_file_t* file;
  66. cpp_token_list_t* tokens;
  67. cpp_token_list_t* out;
  68. int cur_index;
  69. // for expressions in if's
  70. VEC(int) oper_stack;
  71. VEC(lexer_token_t*) value_stack;
  72. cpp_token_list_t exp_buffer;
  73. struct cpp_context* parent;
  74. VEC(struct cpp_context*) children;
  75. VEC(struct cpp_error_t*) errors;
  76. } cpp_context_t;
  77. #define CPP_STRING_CACHE_LIST \
  78. X(_comma, ",") \
  79. X(_concat, "##") \
  80. X(_define, "define") \
  81. X(_dquote, "\"") \
  82. X(_elipsis, "...") \
  83. X(_else, "else") \
  84. X(_elif, "elif") \
  85. X(_endif, "endif") \
  86. X(_error, "error") \
  87. X(_gt, ">") \
  88. X(_hash, "#") \
  89. X(_ident, "ident") \
  90. X(_if, "if") \
  91. X(_ifdef, "ifdef") \
  92. X(_ifndef, "ifndef") \
  93. X(_include, "include") \
  94. X(_line, "line") \
  95. X(_lparen, "(") \
  96. X(_lt, "<") \
  97. X(_pragma, "pragma") \
  98. X(_rparen, ")") \
  99. X(_space, " ") \
  100. X(_undef, "undef") \
  101. X(_va_args, "__VA_ARGS__") \
  102. X(_va_narg, "__VA_NARG__") \
  103. X(_va_opt, "__VA_OPTS__") \
  104. X(_warning, "warning")
  105. typedef struct cpp_tu {
  106. char initialized;
  107. HT(cpp_macro_name_t*) macros; // very mutable
  108. VEC(cpp_macro_def_t*) all_defs; // used for reference later
  109. VEC(cpp_macro_if_t*) ifs; // temp, just for info
  110. cpp_context_t* root_ctx;
  111. HT(cpp_file_t*) files;
  112. VEC(char*) system_inc_dirs;
  113. VEC(char*) local_inc_dirs;
  114. struct string_internment_table* str_table;
  115. #define X(a, ...) char* a;
  116. CPP_STRING_CACHE_LIST
  117. #undef X
  118. long fn_buf_len;
  119. long fn_buf_alloc;
  120. char* filename_buffer;
  121. } cpp_tu_t;
  122. cpp_token_list_t* lex_file(cpp_tu_t* tu, cpp_file_t* file);
  123. void preprocess_file(cpp_tu_t* tu, cpp_context_t* parent, char* path, char is_system);
  124. void preprocess_token_list(cpp_tu_t* tu, cpp_context_t* ctx, cpp_token_list_t* tokens);
  125. cpp_macro_def_t* get_macro_def(cpp_tu_t* tu, lexer_token_t* query);
  126. void expand_fnlike_macro(cpp_tu_t* tu, cpp_context_t* ctx, cpp_macro_invocation_t* inv);
  127. cpp_token_list_t* expand_token_list(cpp_tu_t* tu, cpp_context_t* ctx, cpp_token_list_t* in);
  128. lexer_token_t* next_real_token(cpp_token_list_t* list, size_t* cursor);
  129. void expand_token(cpp_tu_t* tu, cpp_context_t* ctx, cpp_token_list_t* out, cpp_token_list_t* in, size_t* cursor);
  130. #endif