1f08c3bdfSopenharmony_ci/* 2f08c3bdfSopenharmony_ci * 'sparse' library helper routines. 3f08c3bdfSopenharmony_ci * 4f08c3bdfSopenharmony_ci * Copyright (C) 2003 Transmeta Corp. 5f08c3bdfSopenharmony_ci * 2003-2004 Linus Torvalds 6f08c3bdfSopenharmony_ci * 7f08c3bdfSopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a copy 8f08c3bdfSopenharmony_ci * of this software and associated documentation files (the "Software"), to deal 9f08c3bdfSopenharmony_ci * in the Software without restriction, including without limitation the rights 10f08c3bdfSopenharmony_ci * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11f08c3bdfSopenharmony_ci * copies of the Software, and to permit persons to whom the Software is 12f08c3bdfSopenharmony_ci * furnished to do so, subject to the following conditions: 13f08c3bdfSopenharmony_ci * 14f08c3bdfSopenharmony_ci * The above copyright notice and this permission notice shall be included in 15f08c3bdfSopenharmony_ci * all copies or substantial portions of the Software. 16f08c3bdfSopenharmony_ci * 17f08c3bdfSopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18f08c3bdfSopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19f08c3bdfSopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20f08c3bdfSopenharmony_ci * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21f08c3bdfSopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22f08c3bdfSopenharmony_ci * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23f08c3bdfSopenharmony_ci * THE SOFTWARE. 24f08c3bdfSopenharmony_ci */ 25f08c3bdfSopenharmony_ci#include <ctype.h> 26f08c3bdfSopenharmony_ci#include <errno.h> 27f08c3bdfSopenharmony_ci#include <fcntl.h> 28f08c3bdfSopenharmony_ci#include <stdarg.h> 29f08c3bdfSopenharmony_ci#include <stddef.h> 30f08c3bdfSopenharmony_ci#include <stdio.h> 31f08c3bdfSopenharmony_ci#include <stdlib.h> 32f08c3bdfSopenharmony_ci#include <string.h> 33f08c3bdfSopenharmony_ci#include <unistd.h> 34f08c3bdfSopenharmony_ci#include <assert.h> 35f08c3bdfSopenharmony_ci 36f08c3bdfSopenharmony_ci#include <sys/types.h> 37f08c3bdfSopenharmony_ci 38f08c3bdfSopenharmony_ci#include "lib.h" 39f08c3bdfSopenharmony_ci#include "allocate.h" 40f08c3bdfSopenharmony_ci#include "token.h" 41f08c3bdfSopenharmony_ci#include "parse.h" 42f08c3bdfSopenharmony_ci#include "symbol.h" 43f08c3bdfSopenharmony_ci#include "expression.h" 44f08c3bdfSopenharmony_ci#include "evaluate.h" 45f08c3bdfSopenharmony_ci#include "scope.h" 46f08c3bdfSopenharmony_ci#include "linearize.h" 47f08c3bdfSopenharmony_ci#include "target.h" 48f08c3bdfSopenharmony_ci#include "machine.h" 49f08c3bdfSopenharmony_ci#include "bits.h" 50f08c3bdfSopenharmony_ci 51f08c3bdfSopenharmony_cistatic int prettify(const char **fnamep) 52f08c3bdfSopenharmony_ci{ 53f08c3bdfSopenharmony_ci const char *name = *fnamep; 54f08c3bdfSopenharmony_ci int len = strlen(name); 55f08c3bdfSopenharmony_ci 56f08c3bdfSopenharmony_ci if (len > 2 && !memcmp(name, "./", 2)) { 57f08c3bdfSopenharmony_ci name += 2; 58f08c3bdfSopenharmony_ci len -= 2; 59f08c3bdfSopenharmony_ci } 60f08c3bdfSopenharmony_ci 61f08c3bdfSopenharmony_ci *fnamep = name; 62f08c3bdfSopenharmony_ci return len; 63f08c3bdfSopenharmony_ci} 64f08c3bdfSopenharmony_ci 65f08c3bdfSopenharmony_cistatic const char *show_include_chain(int stream, const char *base) 66f08c3bdfSopenharmony_ci{ 67f08c3bdfSopenharmony_ci static char buffer[200]; 68f08c3bdfSopenharmony_ci int len = 0; 69f08c3bdfSopenharmony_ci 70f08c3bdfSopenharmony_ci while ((stream = stream_prev(stream)) >= 0) { 71f08c3bdfSopenharmony_ci const char *p = stream_name(stream); 72f08c3bdfSopenharmony_ci int pretty_len; 73f08c3bdfSopenharmony_ci 74f08c3bdfSopenharmony_ci if (p == base) 75f08c3bdfSopenharmony_ci break; 76f08c3bdfSopenharmony_ci 77f08c3bdfSopenharmony_ci pretty_len = prettify(&p); 78f08c3bdfSopenharmony_ci if (pretty_len <= 0) 79f08c3bdfSopenharmony_ci break; 80f08c3bdfSopenharmony_ci 81f08c3bdfSopenharmony_ci /* 82f08c3bdfSopenharmony_ci * At worst, we'll need " (through %s, ...)" in addition to the 83f08c3bdfSopenharmony_ci * new filename 84f08c3bdfSopenharmony_ci */ 85f08c3bdfSopenharmony_ci if (pretty_len + len + 20 > sizeof(buffer)) { 86f08c3bdfSopenharmony_ci if (!len) 87f08c3bdfSopenharmony_ci return ""; 88f08c3bdfSopenharmony_ci memcpy(buffer+len, ", ...", 5); 89f08c3bdfSopenharmony_ci len += 5; 90f08c3bdfSopenharmony_ci break; 91f08c3bdfSopenharmony_ci } 92f08c3bdfSopenharmony_ci 93f08c3bdfSopenharmony_ci if (!len) { 94f08c3bdfSopenharmony_ci memcpy(buffer, " (through ", 10); 95f08c3bdfSopenharmony_ci len = 10; 96f08c3bdfSopenharmony_ci } else { 97f08c3bdfSopenharmony_ci buffer[len++] = ','; 98f08c3bdfSopenharmony_ci buffer[len++] = ' '; 99f08c3bdfSopenharmony_ci } 100f08c3bdfSopenharmony_ci 101f08c3bdfSopenharmony_ci memcpy(buffer+len, p, pretty_len); 102f08c3bdfSopenharmony_ci len += pretty_len; 103f08c3bdfSopenharmony_ci } 104f08c3bdfSopenharmony_ci if (!len) 105f08c3bdfSopenharmony_ci return ""; 106f08c3bdfSopenharmony_ci 107f08c3bdfSopenharmony_ci buffer[len] = ')'; 108f08c3bdfSopenharmony_ci buffer[len+1] = 0; 109f08c3bdfSopenharmony_ci return buffer; 110f08c3bdfSopenharmony_ci} 111f08c3bdfSopenharmony_ci 112f08c3bdfSopenharmony_cistatic const char *show_stream_name(struct position pos) 113f08c3bdfSopenharmony_ci{ 114f08c3bdfSopenharmony_ci const char *name = stream_name(pos.stream); 115f08c3bdfSopenharmony_ci static const char *last; 116f08c3bdfSopenharmony_ci 117f08c3bdfSopenharmony_ci if (name == base_filename) 118f08c3bdfSopenharmony_ci return name; 119f08c3bdfSopenharmony_ci if (name == last) 120f08c3bdfSopenharmony_ci return name; 121f08c3bdfSopenharmony_ci last = name; 122f08c3bdfSopenharmony_ci 123f08c3bdfSopenharmony_ci fprintf(stderr, "%s: note: in included file%s:\n", 124f08c3bdfSopenharmony_ci base_filename, 125f08c3bdfSopenharmony_ci show_include_chain(pos.stream, base_filename)); 126f08c3bdfSopenharmony_ci return name; 127f08c3bdfSopenharmony_ci} 128f08c3bdfSopenharmony_ci 129f08c3bdfSopenharmony_cistatic void do_warn(const char *type, struct position pos, const char * fmt, va_list args) 130f08c3bdfSopenharmony_ci{ 131f08c3bdfSopenharmony_ci static char buffer[512]; 132f08c3bdfSopenharmony_ci 133f08c3bdfSopenharmony_ci /* Shut up warnings if position is bad_token.pos */ 134f08c3bdfSopenharmony_ci if (pos.type == TOKEN_BAD) 135f08c3bdfSopenharmony_ci return; 136f08c3bdfSopenharmony_ci 137f08c3bdfSopenharmony_ci vsprintf(buffer, fmt, args); 138f08c3bdfSopenharmony_ci 139f08c3bdfSopenharmony_ci fflush(stdout); 140f08c3bdfSopenharmony_ci fprintf(stderr, "%s:%d:%d: %s%s%s\n", 141f08c3bdfSopenharmony_ci show_stream_name(pos), pos.line, pos.pos, 142f08c3bdfSopenharmony_ci diag_prefix, type, buffer); 143f08c3bdfSopenharmony_ci} 144f08c3bdfSopenharmony_ci 145f08c3bdfSopenharmony_cistatic int show_info = 1; 146f08c3bdfSopenharmony_ci 147f08c3bdfSopenharmony_civoid info(struct position pos, const char * fmt, ...) 148f08c3bdfSopenharmony_ci{ 149f08c3bdfSopenharmony_ci va_list args; 150f08c3bdfSopenharmony_ci 151f08c3bdfSopenharmony_ci if (!show_info) 152f08c3bdfSopenharmony_ci return; 153f08c3bdfSopenharmony_ci va_start(args, fmt); 154f08c3bdfSopenharmony_ci do_warn("", pos, fmt, args); 155f08c3bdfSopenharmony_ci va_end(args); 156f08c3bdfSopenharmony_ci} 157f08c3bdfSopenharmony_ci 158f08c3bdfSopenharmony_cistatic void do_error(struct position pos, const char * fmt, va_list args) 159f08c3bdfSopenharmony_ci{ 160f08c3bdfSopenharmony_ci static int errors = 0; 161f08c3bdfSopenharmony_ci die_if_error = 1; 162f08c3bdfSopenharmony_ci show_info = 1; 163f08c3bdfSopenharmony_ci /* Shut up warnings if position is bad_token.pos */ 164f08c3bdfSopenharmony_ci if (pos.type == TOKEN_BAD) 165f08c3bdfSopenharmony_ci return; 166f08c3bdfSopenharmony_ci /* Shut up warnings after an error */ 167f08c3bdfSopenharmony_ci has_error |= ERROR_CURR_PHASE; 168f08c3bdfSopenharmony_ci if (errors > fmax_errors) { 169f08c3bdfSopenharmony_ci static int once = 0; 170f08c3bdfSopenharmony_ci show_info = 0; 171f08c3bdfSopenharmony_ci if (once) 172f08c3bdfSopenharmony_ci return; 173f08c3bdfSopenharmony_ci fmt = "too many errors"; 174f08c3bdfSopenharmony_ci once = 1; 175f08c3bdfSopenharmony_ci } 176f08c3bdfSopenharmony_ci 177f08c3bdfSopenharmony_ci do_warn("error: ", pos, fmt, args); 178f08c3bdfSopenharmony_ci errors++; 179f08c3bdfSopenharmony_ci} 180f08c3bdfSopenharmony_ci 181f08c3bdfSopenharmony_civoid warning(struct position pos, const char * fmt, ...) 182f08c3bdfSopenharmony_ci{ 183f08c3bdfSopenharmony_ci va_list args; 184f08c3bdfSopenharmony_ci 185f08c3bdfSopenharmony_ci if (Wsparse_error) { 186f08c3bdfSopenharmony_ci va_start(args, fmt); 187f08c3bdfSopenharmony_ci do_error(pos, fmt, args); 188f08c3bdfSopenharmony_ci va_end(args); 189f08c3bdfSopenharmony_ci return; 190f08c3bdfSopenharmony_ci } 191f08c3bdfSopenharmony_ci 192f08c3bdfSopenharmony_ci if (!fmax_warnings || has_error) { 193f08c3bdfSopenharmony_ci show_info = 0; 194f08c3bdfSopenharmony_ci return; 195f08c3bdfSopenharmony_ci } 196f08c3bdfSopenharmony_ci 197f08c3bdfSopenharmony_ci if (!--fmax_warnings) { 198f08c3bdfSopenharmony_ci show_info = 0; 199f08c3bdfSopenharmony_ci fmt = "too many warnings"; 200f08c3bdfSopenharmony_ci } 201f08c3bdfSopenharmony_ci 202f08c3bdfSopenharmony_ci va_start(args, fmt); 203f08c3bdfSopenharmony_ci do_warn("warning: ", pos, fmt, args); 204f08c3bdfSopenharmony_ci va_end(args); 205f08c3bdfSopenharmony_ci} 206f08c3bdfSopenharmony_ci 207f08c3bdfSopenharmony_civoid sparse_error(struct position pos, const char * fmt, ...) 208f08c3bdfSopenharmony_ci{ 209f08c3bdfSopenharmony_ci va_list args; 210f08c3bdfSopenharmony_ci va_start(args, fmt); 211f08c3bdfSopenharmony_ci do_error(pos, fmt, args); 212f08c3bdfSopenharmony_ci va_end(args); 213f08c3bdfSopenharmony_ci} 214f08c3bdfSopenharmony_ci 215f08c3bdfSopenharmony_civoid expression_error(struct expression *expr, const char *fmt, ...) 216f08c3bdfSopenharmony_ci{ 217f08c3bdfSopenharmony_ci va_list args; 218f08c3bdfSopenharmony_ci va_start(args, fmt); 219f08c3bdfSopenharmony_ci do_error(expr->pos, fmt, args); 220f08c3bdfSopenharmony_ci va_end(args); 221f08c3bdfSopenharmony_ci expr->ctype = &bad_ctype; 222f08c3bdfSopenharmony_ci} 223f08c3bdfSopenharmony_ci 224f08c3bdfSopenharmony_ciNORETURN_ATTR 225f08c3bdfSopenharmony_civoid error_die(struct position pos, const char * fmt, ...) 226f08c3bdfSopenharmony_ci{ 227f08c3bdfSopenharmony_ci va_list args; 228f08c3bdfSopenharmony_ci va_start(args, fmt); 229f08c3bdfSopenharmony_ci do_warn("error: ", pos, fmt, args); 230f08c3bdfSopenharmony_ci va_end(args); 231f08c3bdfSopenharmony_ci exit(1); 232f08c3bdfSopenharmony_ci} 233f08c3bdfSopenharmony_ci 234f08c3bdfSopenharmony_ciNORETURN_ATTR 235f08c3bdfSopenharmony_civoid die(const char *fmt, ...) 236f08c3bdfSopenharmony_ci{ 237f08c3bdfSopenharmony_ci va_list args; 238f08c3bdfSopenharmony_ci static char buffer[512]; 239f08c3bdfSopenharmony_ci 240f08c3bdfSopenharmony_ci va_start(args, fmt); 241f08c3bdfSopenharmony_ci vsnprintf(buffer, sizeof(buffer), fmt, args); 242f08c3bdfSopenharmony_ci va_end(args); 243f08c3bdfSopenharmony_ci 244f08c3bdfSopenharmony_ci fprintf(stderr, "%s%s\n", diag_prefix, buffer); 245f08c3bdfSopenharmony_ci exit(1); 246f08c3bdfSopenharmony_ci} 247f08c3bdfSopenharmony_ci 248f08c3bdfSopenharmony_ci//////////////////////////////////////////////////////////////////////////////// 249f08c3bdfSopenharmony_ci 250f08c3bdfSopenharmony_cistatic struct token *pre_buffer_begin = NULL; 251f08c3bdfSopenharmony_cistatic struct token **pre_buffer_next = &pre_buffer_begin; 252f08c3bdfSopenharmony_ci 253f08c3bdfSopenharmony_civoid add_pre_buffer(const char *fmt, ...) 254f08c3bdfSopenharmony_ci{ 255f08c3bdfSopenharmony_ci va_list args; 256f08c3bdfSopenharmony_ci unsigned int size; 257f08c3bdfSopenharmony_ci struct token *begin, *end; 258f08c3bdfSopenharmony_ci char buffer[4096]; 259f08c3bdfSopenharmony_ci 260f08c3bdfSopenharmony_ci va_start(args, fmt); 261f08c3bdfSopenharmony_ci size = vsnprintf(buffer, sizeof(buffer), fmt, args); 262f08c3bdfSopenharmony_ci va_end(args); 263f08c3bdfSopenharmony_ci begin = tokenize_buffer(buffer, size, &end); 264f08c3bdfSopenharmony_ci *pre_buffer_next = begin; 265f08c3bdfSopenharmony_ci pre_buffer_next = &end->next; 266f08c3bdfSopenharmony_ci} 267f08c3bdfSopenharmony_ci 268f08c3bdfSopenharmony_cistatic void create_builtin_stream(void) 269f08c3bdfSopenharmony_ci{ 270f08c3bdfSopenharmony_ci // Temporary hack 271f08c3bdfSopenharmony_ci add_pre_buffer("#define _Pragma(x)\n"); 272f08c3bdfSopenharmony_ci 273f08c3bdfSopenharmony_ci /* add the multiarch include directories, if any */ 274f08c3bdfSopenharmony_ci if (multiarch_dir && *multiarch_dir) { 275f08c3bdfSopenharmony_ci add_pre_buffer("#add_system \"/usr/include/%s\"\n", multiarch_dir); 276f08c3bdfSopenharmony_ci add_pre_buffer("#add_system \"/usr/local/include/%s\"\n", multiarch_dir); 277f08c3bdfSopenharmony_ci } 278f08c3bdfSopenharmony_ci 279f08c3bdfSopenharmony_ci /* We add compiler headers path here because we have to parse 280f08c3bdfSopenharmony_ci * the arguments to get it, falling back to default. */ 281f08c3bdfSopenharmony_ci add_pre_buffer("#add_system \"%s/include\"\n", gcc_base_dir); 282f08c3bdfSopenharmony_ci add_pre_buffer("#add_system \"%s/include-fixed\"\n", gcc_base_dir); 283f08c3bdfSopenharmony_ci 284f08c3bdfSopenharmony_ci add_pre_buffer("#define __builtin_stdarg_start(a,b) ((a) = (__builtin_va_list)(&(b)))\n"); 285f08c3bdfSopenharmony_ci add_pre_buffer("#define __builtin_va_start(a,b) ((a) = (__builtin_va_list)(&(b)))\n"); 286f08c3bdfSopenharmony_ci add_pre_buffer("#define __builtin_ms_va_start(a,b) ((a) = (__builtin_ms_va_list)(&(b)))\n"); 287f08c3bdfSopenharmony_ci add_pre_buffer("#define __builtin_va_arg(arg,type) ({ type __va_arg_ret = *(type *)(arg); arg += sizeof(type); __va_arg_ret; })\n"); 288f08c3bdfSopenharmony_ci add_pre_buffer("#define __builtin_va_alist (*(void *)0)\n"); 289f08c3bdfSopenharmony_ci add_pre_buffer("#define __builtin_va_arg_incr(x) ((x) + 1)\n"); 290f08c3bdfSopenharmony_ci add_pre_buffer("#define __builtin_va_copy(dest, src) ({ dest = src; (void)0; })\n"); 291f08c3bdfSopenharmony_ci add_pre_buffer("#define __builtin_ms_va_copy(dest, src) ({ dest = src; (void)0; })\n"); 292f08c3bdfSopenharmony_ci add_pre_buffer("#define __builtin_va_end(arg)\n"); 293f08c3bdfSopenharmony_ci add_pre_buffer("#define __builtin_ms_va_end(arg)\n"); 294f08c3bdfSopenharmony_ci add_pre_buffer("#define __builtin_va_arg_pack()\n"); 295f08c3bdfSopenharmony_ci} 296f08c3bdfSopenharmony_ci 297f08c3bdfSopenharmony_cistatic struct symbol_list *sparse_tokenstream(struct token *token) 298f08c3bdfSopenharmony_ci{ 299f08c3bdfSopenharmony_ci int builtin = token && !token->pos.stream; 300f08c3bdfSopenharmony_ci 301f08c3bdfSopenharmony_ci // Preprocess the stream 302f08c3bdfSopenharmony_ci token = preprocess(token); 303f08c3bdfSopenharmony_ci 304f08c3bdfSopenharmony_ci if (dump_macro_defs || dump_macros_only) { 305f08c3bdfSopenharmony_ci if (!builtin) 306f08c3bdfSopenharmony_ci dump_macro_definitions(); 307f08c3bdfSopenharmony_ci if (dump_macros_only) 308f08c3bdfSopenharmony_ci return NULL; 309f08c3bdfSopenharmony_ci } 310f08c3bdfSopenharmony_ci 311f08c3bdfSopenharmony_ci if (preprocess_only) { 312f08c3bdfSopenharmony_ci while (!eof_token(token)) { 313f08c3bdfSopenharmony_ci int prec = 1; 314f08c3bdfSopenharmony_ci struct token *next = token->next; 315f08c3bdfSopenharmony_ci const char *separator = ""; 316f08c3bdfSopenharmony_ci if (next->pos.whitespace) 317f08c3bdfSopenharmony_ci separator = " "; 318f08c3bdfSopenharmony_ci if (next->pos.newline) { 319f08c3bdfSopenharmony_ci separator = "\n\t\t\t\t\t"; 320f08c3bdfSopenharmony_ci prec = next->pos.pos; 321f08c3bdfSopenharmony_ci if (prec > 4) 322f08c3bdfSopenharmony_ci prec = 4; 323f08c3bdfSopenharmony_ci } 324f08c3bdfSopenharmony_ci printf("%s%.*s", show_token(token), prec, separator); 325f08c3bdfSopenharmony_ci token = next; 326f08c3bdfSopenharmony_ci } 327f08c3bdfSopenharmony_ci putchar('\n'); 328f08c3bdfSopenharmony_ci 329f08c3bdfSopenharmony_ci return NULL; 330f08c3bdfSopenharmony_ci } 331f08c3bdfSopenharmony_ci 332f08c3bdfSopenharmony_ci // Parse the resulting C code 333f08c3bdfSopenharmony_ci while (!eof_token(token)) 334f08c3bdfSopenharmony_ci token = external_declaration(token, &translation_unit_used_list, NULL); 335f08c3bdfSopenharmony_ci return translation_unit_used_list; 336f08c3bdfSopenharmony_ci} 337f08c3bdfSopenharmony_ci 338f08c3bdfSopenharmony_cistatic struct symbol_list *sparse_file(const char *filename) 339f08c3bdfSopenharmony_ci{ 340f08c3bdfSopenharmony_ci int fd; 341f08c3bdfSopenharmony_ci struct token *token; 342f08c3bdfSopenharmony_ci 343f08c3bdfSopenharmony_ci if (strcmp(filename, "-") == 0) { 344f08c3bdfSopenharmony_ci fd = 0; 345f08c3bdfSopenharmony_ci } else { 346f08c3bdfSopenharmony_ci fd = open(filename, O_RDONLY); 347f08c3bdfSopenharmony_ci if (fd < 0) 348f08c3bdfSopenharmony_ci die("No such file: %s", filename); 349f08c3bdfSopenharmony_ci } 350f08c3bdfSopenharmony_ci base_filename = filename; 351f08c3bdfSopenharmony_ci 352f08c3bdfSopenharmony_ci // Tokenize the input stream 353f08c3bdfSopenharmony_ci token = tokenize(NULL, filename, fd, NULL, includepath); 354f08c3bdfSopenharmony_ci close(fd); 355f08c3bdfSopenharmony_ci 356f08c3bdfSopenharmony_ci return sparse_tokenstream(token); 357f08c3bdfSopenharmony_ci} 358f08c3bdfSopenharmony_ci 359f08c3bdfSopenharmony_ci/* 360f08c3bdfSopenharmony_ci * This handles the "-include" directive etc: we're in global 361f08c3bdfSopenharmony_ci * scope, and all types/macros etc will affect all the following 362f08c3bdfSopenharmony_ci * files. 363f08c3bdfSopenharmony_ci * 364f08c3bdfSopenharmony_ci * NOTE NOTE NOTE! "#undef" of anything in this stage will 365f08c3bdfSopenharmony_ci * affect all subsequent files too, i.e. we can have non-local 366f08c3bdfSopenharmony_ci * behaviour between files! 367f08c3bdfSopenharmony_ci */ 368f08c3bdfSopenharmony_cistatic struct symbol_list *sparse_initial(void) 369f08c3bdfSopenharmony_ci{ 370f08c3bdfSopenharmony_ci int i; 371f08c3bdfSopenharmony_ci 372f08c3bdfSopenharmony_ci // Prepend any "include" file to the stream. 373f08c3bdfSopenharmony_ci // We're in global scope, it will affect all files! 374f08c3bdfSopenharmony_ci for (i = 0; i < cmdline_include_nr; i++) 375f08c3bdfSopenharmony_ci add_pre_buffer("#argv_include \"%s\"\n", cmdline_include[i]); 376f08c3bdfSopenharmony_ci 377f08c3bdfSopenharmony_ci return sparse_tokenstream(pre_buffer_begin); 378f08c3bdfSopenharmony_ci} 379f08c3bdfSopenharmony_ci 380f08c3bdfSopenharmony_cistruct symbol_list *sparse_initialize(int argc, char **argv, struct string_list **filelist) 381f08c3bdfSopenharmony_ci{ 382f08c3bdfSopenharmony_ci char **args; 383f08c3bdfSopenharmony_ci struct symbol_list *list; 384f08c3bdfSopenharmony_ci 385f08c3bdfSopenharmony_ci base_filename = "command-line"; 386f08c3bdfSopenharmony_ci 387f08c3bdfSopenharmony_ci // Initialize symbol stream first, so that we can add defines etc 388f08c3bdfSopenharmony_ci init_symbols(); 389f08c3bdfSopenharmony_ci 390f08c3bdfSopenharmony_ci // initialize the default target to the native 'machine' 391f08c3bdfSopenharmony_ci target_config(MACH_NATIVE); 392f08c3bdfSopenharmony_ci 393f08c3bdfSopenharmony_ci args = argv; 394f08c3bdfSopenharmony_ci for (;;) { 395f08c3bdfSopenharmony_ci char *arg = *++args; 396f08c3bdfSopenharmony_ci if (!arg) 397f08c3bdfSopenharmony_ci break; 398f08c3bdfSopenharmony_ci 399f08c3bdfSopenharmony_ci if (arg[0] == '-' && arg[1]) { 400f08c3bdfSopenharmony_ci args = handle_switch(arg+1, args); 401f08c3bdfSopenharmony_ci continue; 402f08c3bdfSopenharmony_ci } 403f08c3bdfSopenharmony_ci add_ptr_list(filelist, arg); 404f08c3bdfSopenharmony_ci } 405f08c3bdfSopenharmony_ci handle_switch_finalize(); 406f08c3bdfSopenharmony_ci 407f08c3bdfSopenharmony_ci // Redirect stdout if needed 408f08c3bdfSopenharmony_ci if (dump_macro_defs || preprocess_only) 409f08c3bdfSopenharmony_ci do_output = 1; 410f08c3bdfSopenharmony_ci if (do_output && outfile && strcmp(outfile, "-")) { 411f08c3bdfSopenharmony_ci if (!freopen(outfile, "w", stdout)) 412f08c3bdfSopenharmony_ci die("error: cannot open %s: %s", outfile, strerror(errno)); 413f08c3bdfSopenharmony_ci } 414f08c3bdfSopenharmony_ci 415f08c3bdfSopenharmony_ci if (fdump_ir == 0) 416f08c3bdfSopenharmony_ci fdump_ir = PASS_FINAL; 417f08c3bdfSopenharmony_ci 418f08c3bdfSopenharmony_ci list = NULL; 419f08c3bdfSopenharmony_ci if (filelist) { 420f08c3bdfSopenharmony_ci // Initialize type system 421f08c3bdfSopenharmony_ci target_init(); 422f08c3bdfSopenharmony_ci init_ctype(); 423f08c3bdfSopenharmony_ci 424f08c3bdfSopenharmony_ci predefined_macros(); 425f08c3bdfSopenharmony_ci create_builtin_stream(); 426f08c3bdfSopenharmony_ci init_builtins(0); 427f08c3bdfSopenharmony_ci 428f08c3bdfSopenharmony_ci list = sparse_initial(); 429f08c3bdfSopenharmony_ci 430f08c3bdfSopenharmony_ci /* 431f08c3bdfSopenharmony_ci * Protect the initial token allocations, since 432f08c3bdfSopenharmony_ci * they need to survive all the others 433f08c3bdfSopenharmony_ci */ 434f08c3bdfSopenharmony_ci protect_token_alloc(); 435f08c3bdfSopenharmony_ci } 436f08c3bdfSopenharmony_ci /* 437f08c3bdfSopenharmony_ci * Evaluate the complete symbol list 438f08c3bdfSopenharmony_ci * Note: This is not needed for normal cases. 439f08c3bdfSopenharmony_ci * These symbols should only be predefined defines and 440f08c3bdfSopenharmony_ci * declaratons which will be evaluated later, when needed. 441f08c3bdfSopenharmony_ci * This is also the case when a file is directly included via 442f08c3bdfSopenharmony_ci * '-include <file>' on the command line *AND* the file only 443f08c3bdfSopenharmony_ci * contains defines, declarations and inline definitions. 444f08c3bdfSopenharmony_ci * However, in the rare cases where the given file should 445f08c3bdfSopenharmony_ci * contain some definitions, these will never be evaluated 446f08c3bdfSopenharmony_ci * and thus won't be able to be linearized correctly. 447f08c3bdfSopenharmony_ci * Hence the evaluate_symbol_list() here under. 448f08c3bdfSopenharmony_ci */ 449f08c3bdfSopenharmony_ci evaluate_symbol_list(list); 450f08c3bdfSopenharmony_ci return list; 451f08c3bdfSopenharmony_ci} 452f08c3bdfSopenharmony_ci 453f08c3bdfSopenharmony_cistruct symbol_list * sparse_keep_tokens(char *filename) 454f08c3bdfSopenharmony_ci{ 455f08c3bdfSopenharmony_ci struct symbol_list *res; 456f08c3bdfSopenharmony_ci 457f08c3bdfSopenharmony_ci /* Clear previous symbol list */ 458f08c3bdfSopenharmony_ci translation_unit_used_list = NULL; 459f08c3bdfSopenharmony_ci 460f08c3bdfSopenharmony_ci new_file_scope(); 461f08c3bdfSopenharmony_ci res = sparse_file(filename); 462f08c3bdfSopenharmony_ci 463f08c3bdfSopenharmony_ci /* And return it */ 464f08c3bdfSopenharmony_ci return res; 465f08c3bdfSopenharmony_ci} 466f08c3bdfSopenharmony_ci 467f08c3bdfSopenharmony_ci 468f08c3bdfSopenharmony_cistruct symbol_list * __sparse(char *filename) 469f08c3bdfSopenharmony_ci{ 470f08c3bdfSopenharmony_ci struct symbol_list *res; 471f08c3bdfSopenharmony_ci 472f08c3bdfSopenharmony_ci res = sparse_keep_tokens(filename); 473f08c3bdfSopenharmony_ci 474f08c3bdfSopenharmony_ci /* Drop the tokens for this file after parsing */ 475f08c3bdfSopenharmony_ci clear_token_alloc(); 476f08c3bdfSopenharmony_ci 477f08c3bdfSopenharmony_ci /* And return it */ 478f08c3bdfSopenharmony_ci return res; 479f08c3bdfSopenharmony_ci} 480f08c3bdfSopenharmony_ci 481f08c3bdfSopenharmony_cistruct symbol_list * sparse(char *filename) 482f08c3bdfSopenharmony_ci{ 483f08c3bdfSopenharmony_ci struct symbol_list *res = __sparse(filename); 484f08c3bdfSopenharmony_ci 485f08c3bdfSopenharmony_ci if (has_error & ERROR_CURR_PHASE) 486f08c3bdfSopenharmony_ci has_error = ERROR_PREV_PHASE; 487f08c3bdfSopenharmony_ci /* Evaluate the complete symbol list */ 488f08c3bdfSopenharmony_ci evaluate_symbol_list(res); 489f08c3bdfSopenharmony_ci 490f08c3bdfSopenharmony_ci return res; 491f08c3bdfSopenharmony_ci} 492