aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libcpp/files.c31
-rw-r--r--libcpp/include/cpplib.h15
-rw-r--r--libcpp/init.c21
-rw-r--r--libcpp/internal.h7
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. */