aboutsummaryrefslogtreecommitdiff
path: root/libcpp
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@acm.org>2021-02-18 12:46:25 -0800
committerNathan Sidwell <nathan@acm.org>2021-02-18 13:22:48 -0800
commit1f9db6929d926222aee0628b93f77cd20cf3adc4 (patch)
treed00d2d912c714d8f13253ed49331aed0b66aed86 /libcpp
parentd82f829905cfe6cb47d073825f680900274ce764 (diff)
downloadgcc-1f9db6929d926222aee0628b93f77cd20cf3adc4.zip
gcc-1f9db6929d926222aee0628b93f77cd20cf3adc4.tar.gz
gcc-1f9db6929d926222aee0628b93f77cd20cf3adc4.tar.bz2
c++: header-unit build capability [PR 99023]
This defect really required building header-units and include translation of pieces of the standard library. This adds smarts to the modules test harness to do that -- accept .X files as the source file, but provide '-x c++-system-header $HDR' in the options. The .X file will be considered by the driver to be a linker script and ignored (with a warning). Using this we can add 2 tests that end up building list_initializer and iostream, along with a test that iostream's build include-translates list_initializer's #include. That discovered a set of issues with the -flang-info-include-translate=HDR handling, also fixed and documented here. PR c++/99023 gcc/cp/ * module.cc (canonicalize_header_name): Use cpp_probe_header_unit. (maybe_translate_include): Fix note_includes comparison. (init_modules): Fix note_includes string termination. libcpp/ * include/cpplib.h (cpp_find_header_unit): Rename to ... (cpp_probe_header_unit): ... this. * internal.h (_cp_find_header_unit): Declare. * files.c (cpp_find_header_unit): Break apart to .. (test_header_unit): ... this, and ... (_cpp_find_header_unit): ... and, or and ... (cpp_probe_header_unit): ... this. * macro.c (cpp_get_token_1): Call _cpp_find_header_unit. gcc/ * doc/invoke.texi (flang-info-include-translate): Document header lookup behaviour. gcc/testsuite/ * g++.dg/modules/modules.exp: Bail on cross-testing. Add support for .X files. * g++.dg/modules/pr99023_a.X: New. * g++.dg/modules/pr99023_b.X: New.
Diffstat (limited to 'libcpp')
-rw-r--r--libcpp/files.c59
-rw-r--r--libcpp/include/cpplib.h4
-rw-r--r--libcpp/internal.h2
-rw-r--r--libcpp/macro.c2
4 files changed, 46 insertions, 21 deletions
diff --git a/libcpp/files.c b/libcpp/files.c
index 3a35f7c..6e20fc5 100644
--- a/libcpp/files.c
+++ b/libcpp/files.c
@@ -1108,31 +1108,54 @@ _cpp_stack_include (cpp_reader *pfile, const char *fname, int angle_brackets,
return _cpp_stack_file (pfile, file, type, loc);
}
-/* NAME is a header file name, find the path we'll use to open it. */
+/* NAME is a header file name, find the _cpp_file, if any. */
-const char *
-cpp_find_header_unit (cpp_reader *pfile, const char *name, bool angle,
- location_t loc)
+static _cpp_file *
+test_header_unit (cpp_reader *pfile, const char *name, bool angle,
+ location_t loc)
{
- cpp_dir *dir = search_path_head (pfile, name, angle, IT_INCLUDE);
- if (!dir)
- return NULL;
+ if (cpp_dir *dir = search_path_head (pfile, name, angle, IT_INCLUDE))
+ return _cpp_find_file (pfile, name, dir, angle, _cpp_FFK_NORMAL, loc);
+
+ return nullptr;
+}
- _cpp_file *file = _cpp_find_file (pfile, name, dir, angle,
- _cpp_FFK_NORMAL, loc);
- if (!file)
- return NULL;
+/* NAME is a header file name, find the path we'll use to open it and infer that
+ it is a header-unit. */
- if (file->fd > 0)
+const char *
+_cpp_find_header_unit (cpp_reader *pfile, const char *name, bool angle,
+ location_t loc)
+{
+ if (_cpp_file *file = test_header_unit (pfile, name, angle, loc))
{
- /* Don't leave it open. */
- close (file->fd);
- file->fd = 0;
+ if (file->fd > 0)
+ {
+ /* Don't leave it open. */
+ close (file->fd);
+ file->fd = 0;
+ }
+
+ file->header_unit = +1;
+ _cpp_mark_file_once_only (pfile, file);
+
+ return file->path;
}
- file->header_unit = +1;
- _cpp_mark_file_once_only (pfile, file);
- return file->path;
+ return nullptr;
+}
+
+/* NAME is a header file name, find the path we'll use to open it. But do not
+ infer it is a header unit. */
+
+const char *
+cpp_probe_header_unit (cpp_reader *pfile, const char *name, bool angle,
+ location_t loc)
+{
+ if (_cpp_file *file = test_header_unit (pfile, name, angle, loc))
+ return file->path;
+
+ return nullptr;
}
/* Retrofit the just-entered main file asif it was an include. This
diff --git a/libcpp/include/cpplib.h b/libcpp/include/cpplib.h
index 17feb64..41d75d9 100644
--- a/libcpp/include/cpplib.h
+++ b/libcpp/include/cpplib.h
@@ -1012,8 +1012,8 @@ extern cpp_callbacks *cpp_get_callbacks (cpp_reader *) ATTRIBUTE_PURE;
extern void cpp_set_callbacks (cpp_reader *, cpp_callbacks *);
extern class mkdeps *cpp_get_deps (cpp_reader *) ATTRIBUTE_PURE;
-extern const char *cpp_find_header_unit (cpp_reader *, const char *file,
- bool angle_p, location_t);
+extern const char *cpp_probe_header_unit (cpp_reader *, const char *file,
+ bool angle_p, location_t);
/* Call these to get name data about the various compile-time
charsets. */
diff --git a/libcpp/internal.h b/libcpp/internal.h
index 32f9f50..fd44de6 100644
--- a/libcpp/internal.h
+++ b/libcpp/internal.h
@@ -703,6 +703,8 @@ extern _cpp_file *_cpp_find_file (cpp_reader *, const char *, cpp_dir *,
int angle, _cpp_find_file_kind, location_t);
extern bool _cpp_find_failed (_cpp_file *);
extern void _cpp_mark_file_once_only (cpp_reader *, struct _cpp_file *);
+extern const char *_cpp_find_header_unit (cpp_reader *, const char *file,
+ bool angle_p, location_t);
extern void _cpp_fake_include (cpp_reader *, const char *);
extern bool _cpp_stack_file (cpp_reader *, _cpp_file*, include_type, location_t);
extern bool _cpp_stack_include (cpp_reader *, const char *, int,
diff --git a/libcpp/macro.c b/libcpp/macro.c
index fa6acff..dff7c98 100644
--- a/libcpp/macro.c
+++ b/libcpp/macro.c
@@ -3010,7 +3010,7 @@ cpp_get_token_1 (cpp_reader *pfile, location_t *location)
if (need_search)
{
- found = cpp_find_header_unit (pfile, fname, angle, tmp->src_loc);
+ found = _cpp_find_header_unit (pfile, fname, angle, tmp->src_loc);
if (!found)
found = "";
len = strlen (found);