diff options
-rw-r--r-- | libcpp/files.c | 31 | ||||
-rw-r--r-- | libcpp/include/cpplib.h | 15 | ||||
-rw-r--r-- | libcpp/init.c | 21 | ||||
-rw-r--r-- | libcpp/internal.h | 7 |
4 files changed, 70 insertions, 4 deletions
diff --git a/libcpp/files.c b/libcpp/files.c index ba52d2b..301b237 100644 --- a/libcpp/files.c +++ b/libcpp/files.c @@ -1131,6 +1131,37 @@ cpp_find_header_unit (cpp_reader *pfile, const char *name, bool angle, return file->path; } +/* Retrofit the just-entered main file asif it was an include. This + will permit correct include_next use, and mark it as a system + header if that's where it resides. We use filesystem-appropriate + prefix matching of the include path to locate the main file. */ +void +cpp_retrofit_as_include (cpp_reader *pfile) +{ + /* We should be the outermost. */ + gcc_assert (!pfile->buffer->prev); + + if (const char *name = pfile->main_file->name) + { + /* Locate name on the include dir path, using a prefix match. */ + size_t name_len = strlen (name); + for (cpp_dir *dir = pfile->quote_include; dir; dir = dir->next) + if (dir->len < name_len + && IS_DIR_SEPARATOR (name[dir->len]) + && !filename_ncmp (name, dir->name, dir->len)) + { + pfile->main_file->dir = dir; + if (dir->sysp) + cpp_make_system_header (pfile, 1, 0); + break; + } + } + + /* Initialize controlling macro state. */ + pfile->mi_valid = true; + pfile->mi_cmacro = 0; +} + /* Could not open FILE. The complication is dependency output. */ static void open_file_failed (cpp_reader *pfile, _cpp_file *file, int angle_brackets, diff --git a/libcpp/include/cpplib.h b/libcpp/include/cpplib.h index 630f2e0..91226cf 100644 --- a/libcpp/include/cpplib.h +++ b/libcpp/include/cpplib.h @@ -308,6 +308,15 @@ enum cpp_normalize_level { normalized_none }; +enum cpp_main_search +{ + CMS_none, /* A regular source file. */ + CMS_header, /* Is a directly-specified header file (eg PCH or + header-unit). */ + CMS_user, /* Search the user INCLUDE path. */ + CMS_system, /* Search the system INCLUDE path. */ +}; + /* This structure is nested inside struct cpp_reader, and carries all the options visible to the command line. */ struct cpp_options @@ -566,6 +575,8 @@ struct cpp_options /* The maximum depth of the nested #include. */ unsigned int max_include_depth; + + cpp_main_search main_search : 8; }; /* Diagnostic levels. To get a diagnostic without associating a @@ -997,6 +1008,10 @@ extern const char *cpp_find_header_unit (cpp_reader *, const char *file, too. If there was an error opening the file, it returns NULL. */ extern const char *cpp_read_main_file (cpp_reader *, const char *, bool injecting = false); +extern location_t cpp_main_loc (const cpp_reader *); + +/* Adjust for the main file to be an include. */ +extern void cpp_retrofit_as_include (cpp_reader *); /* Set up built-ins with special behavior. Use cpp_init_builtins() instead unless your know what you are doing. */ diff --git a/libcpp/init.c b/libcpp/init.c index fc82658..f77dc26 100644 --- a/libcpp/init.c +++ b/libcpp/init.c @@ -675,8 +675,14 @@ cpp_read_main_file (cpp_reader *pfile, const char *fname, bool injecting) deps_add_default_target (deps, fname); pfile->main_file - = _cpp_find_file (pfile, fname, &pfile->no_search_path, /*angle=*/0, - _cpp_FFK_NORMAL, 0); + = _cpp_find_file (pfile, fname, + CPP_OPTION (pfile, preprocessed) ? &pfile->no_search_path + : CPP_OPTION (pfile, main_search) == CMS_user + ? pfile->quote_include + : CPP_OPTION (pfile, main_search) == CMS_system + ? pfile->bracket_include : &pfile->no_search_path, + /*angle=*/0, _cpp_FFK_NORMAL, 0); + if (_cpp_find_failed (pfile->main_file)) return NULL; @@ -698,7 +704,16 @@ cpp_read_main_file (cpp_reader *pfile, const char *fname, bool injecting) LINEMAP_LINE (last), LINEMAP_SYSP (last)); } - return ORDINARY_MAP_FILE_NAME (LINEMAPS_LAST_ORDINARY_MAP (pfile->line_table)); + auto *map = LINEMAPS_LAST_ORDINARY_MAP (pfile->line_table); + pfile->main_loc = MAP_START_LOCATION (map); + + return ORDINARY_MAP_FILE_NAME (map); +} + +location_t +cpp_main_loc (const cpp_reader *pfile) +{ + return pfile->main_loc; } /* For preprocessed files, if the very first characters are diff --git a/libcpp/internal.h b/libcpp/internal.h index e629cbc..697fef0 100644 --- a/libcpp/internal.h +++ b/libcpp/internal.h @@ -591,6 +591,10 @@ struct cpp_reader /* If non-zero, the lexer will use this location for the next token instead of getting a location from the linemap. */ location_t forced_token_location; + + /* Location identifying the main source file -- intended to be line + zero of said file. */ + location_t main_loc; }; /* Character classes. Based on the more primitive macros in safe-ctype.h. @@ -643,7 +647,8 @@ _cpp_in_system_header (cpp_reader *pfile) inline int _cpp_in_main_source_file (cpp_reader *pfile) { - return pfile->buffer->file == pfile->main_file; + return (!CPP_OPTION (pfile, main_search) + && pfile->buffer->file == pfile->main_file); } /* True if NODE is a macro for the purposes of ifdef, defined etc. */ |