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.  */

Reply via email to