Here's the changes to starting the main file. I have added the ability
to search the user or system include paths for the main file. That's
real helpful to users attempting to build header-units. I'll discuss
the CLI with the options patch.
Also recording the location at which the main file starts is helpful for
whole-file diagnostics.
--
Nathan Sidwell
diff --git c/libcpp/include/cpplib.h w/libcpp/include/cpplib.h
index 8e398863cf6..81be6457951 100644
--- c/libcpp/include/cpplib.h
+++ w/libcpp/include/cpplib.h
@@ -308,6 +308,13 @@ enum cpp_normalize_level {
normalized_none
};
+enum cpp_main_search
+{
+ CMS_none,
+ CMS_user,
+ CMS_system
+};
+
/* This structure is nested inside struct cpp_reader, and
carries all the options visible to the command line. */
struct cpp_options
@@ -560,6 +573,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
@@ -978,6 +1012,10 @@ extern class mkdeps *cpp_get_deps (cpp_reader *) ATTRIBUTE_PURE;
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 c/libcpp/init.c w/libcpp/init.c
index 6c52f50de39..96ade569457 100644
--- c/libcpp/init.c
+++ w/libcpp/init.c
@@ -672,8 +672,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;
@@ -695,7 +701,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 c/libcpp/internal.h w/libcpp/internal.h
index 4759961a33a..17b65601b66 100644
--- c/libcpp/internal.h
+++ w/libcpp/internal.h
@@ -357,6 +366,9 @@ struct cpp_buffer
token from the enclosing buffer is returned. */
bool return_at_eof : 1;
+ /* Is from main file. */
+ bool main_file : 1;
+
/* One for a system header, two for a C system header file that therefore
needs to be extern "C" protected in C++, and zero otherwise. */
unsigned char sysp;
@@ -583,6 +595,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.
@@ -635,7 +651,7 @@ static inline int cpp_in_primary_file (cpp_reader *);
static inline int
cpp_in_primary_file (cpp_reader *pfile)
{
- return pfile->line_table->depth == 1;
+ return pfile->buffer->main_file;
}
/* True if NODE is a macro for the purposes of ifdef, defined etc. */