From 9844497a935d5e89dc92539128edccb6bb408bb1 Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Thu, 19 Nov 2020 07:00:51 -0800 Subject: preprocessor: main file searching This adds the capability to locate the main file on the user or system include paths. That's extremely useful to users building header units. Searching has to be requiested (plain header-unit compilation will not search). Also, to make include_next work as expected when building a header unit, we add a mechanism to retrofit a non-searched source file as one on the include path. libcpp/ * include/cpplib.h (enum cpp_main_search): New. (struct cpp_options): Add main_search field. (cpp_main_loc): Declare. (cpp_retrofit_as_include): Declare. * internal.h (struct cpp_reader): Add main_loc field. (_cpp_in_main_source_file): Not main if main is a header. * init.c (cpp_read_main_file): Use main_search option to locate main file. Set main_loc * files.c (cpp_retrofit_as_include): New. --- libcpp/files.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'libcpp/files.c') 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, -- cgit v1.1