aboutsummaryrefslogtreecommitdiff
path: root/libcpp/internal.h
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@acm.org>2020-01-20 05:39:59 -0800
committerNathan Sidwell <nathan@acm.org>2020-01-20 05:39:59 -0800
commitad1a3914ae8d67c94b0d2428e3f9672e7db491a1 (patch)
tree60f0771d802b20be5b8a827738e48324dcb24d2b /libcpp/internal.h
parente82ba180d6641a1e2bad1ac327234fc1cda658ef (diff)
downloadgcc-ad1a3914ae8d67c94b0d2428e3f9672e7db491a1.zip
gcc-ad1a3914ae8d67c94b0d2428e3f9672e7db491a1.tar.gz
gcc-ad1a3914ae8d67c94b0d2428e3f9672e7db491a1.tar.bz2
[PR 80005] Fix __has_include
__has_include is funky in that it is macro-like from the POV of #ifdef and friends, but lexes its parenthesize argument #include-like. We were failing the second part of that, because we used a forwarding macro to an internal name, and hence always lexed the argument in macro-parameter context. We componded that by not setting the right flag when lexing, so it didn't even know. Mostly users got lucky. This reimplements the handline. 1) Remove the forwarding, but declare object-like macros that expand to themselves. This satisfies the #ifdef requirement 2) Correctly set angled_brackets when lexing the parameter. This tells the lexer (a) <...> is a header name and (b) "..." is too (not a string). 3) Remove the in__has_include lexer state, just tell find_file that that's what's happenning, so it doesn't emit an error. We lose the (undocumented) ability to #undef __has_include. That may well have been an accident of implementation. There are no tests for it. We gain __has_include behaviour for all users of the preprocessors -- not just the C-family ones that defined a forwarding macro. libcpp/ PR preprocessor/80005 * include/cpplib.h (BT_HAS_ATTRIBUTE): Fix comment. * internal.h (struct lexer_state): Delete in__has_include field. (struct spec_nodes): Rename n__has_include{,_next}__ fields. (_cpp_defined_macro_p): New. (_cpp_find_file): Add has_include parm. * directives.c (lex_macro_node): Combine defined, __has_inline{,_next} checking. (do_ifdef, do_ifndef): Use _cpp_defined_macro_p. (_cpp_init_directives): Refactor. * expr.c (parse_defined): Use _cpp_defined_macro_p. (eval_token): Adjust parse_has_include calls. (parse_has_include): Add OP parameter. Reimplement. * files.c (_cpp_find_file): Add HAS_INCLUDE parm. Use it to inhibit error message. (_cpp_stack_include): Adjust _cpp_find_file call. (_cpp_fake_include, _cpp_compare_file_date): Likewise. (open_file_failed): Remove in__has_include check. (_cpp_has_header): Adjust _cpp_find_file call. * identifiers.c (_cpp_init_hashtable): Don't init __has_include{,_next} here ... * init.c (cpp_init_builtins): ... init them here. Define as macros. (cpp_read_main_file): Adjust _cpp_find_file call. * pch.c (cpp_read_state): Adjust __has_include{,_next} access. * traditional.c (_cpp_scan_out_locgical_line): Likewise. gcc/c-family/ PR preprocessor/80005 * c-cppbuiltins.c (c_cpp_builtins): Don't define __has_include{,_next}. gcc/testsuite/ PR preprocessor/80005 * g++.dg/cpp1y/feat-cxx14.C: Adjust. * g++.dg/cpp1z/feat-cxx17.C: Adjust. * g++.dg/cpp2a/feat-cxx2a.C: Adjust. * g++.dg/cpp/pr80005.C: New.
Diffstat (limited to 'libcpp/internal.h')
-rw-r--r--libcpp/internal.h20
1 files changed, 14 insertions, 6 deletions
diff --git a/libcpp/internal.h b/libcpp/internal.h
index 3623baf..5453c3b 100644
--- a/libcpp/internal.h
+++ b/libcpp/internal.h
@@ -268,9 +268,6 @@ struct lexer_state
/* Nonzero when parsing arguments to a function-like macro. */
unsigned char parsing_args;
- /* Nonzero if in a __has_include__ or __has_include_next__ statement. */
- unsigned char in__has_include__;
-
/* Nonzero if prevent_expansion is true only because output is
being discarded. */
unsigned char discarding_output;
@@ -293,8 +290,8 @@ struct spec_nodes
cpp_hashnode *n_false; /* C++ keyword false */
cpp_hashnode *n__VA_ARGS__; /* C99 vararg macros */
cpp_hashnode *n__VA_OPT__; /* C++ vararg macros */
- cpp_hashnode *n__has_include__; /* __has_include__ operator */
- cpp_hashnode *n__has_include_next__; /* __has_include_next__ operator */
+ cpp_hashnode *n__has_include; /* __has_include operator */
+ cpp_hashnode *n__has_include_next; /* __has_include_next operator */
};
typedef struct _cpp_line_note _cpp_line_note;
@@ -641,6 +638,16 @@ cpp_in_primary_file (cpp_reader *pfile)
return pfile->line_table->depth == 1;
}
+/* True if NODE is a macro for the purposes of ifdef, defined etc. */
+inline bool _cpp_defined_macro_p (cpp_hashnode *node)
+{
+ /* Do not treat conditional macros as being defined. This is due to
+ the powerpc port using conditional macros for 'vector', 'bool',
+ and 'pixel' to act as conditional keywords. This messes up tests
+ like #ifndef bool. */
+ return cpp_macro_p (node) && !(node->flags & NODE_CONDITIONAL);
+}
+
/* In macro.c */
extern void _cpp_notify_macro_use (cpp_reader *pfile, cpp_hashnode *node);
inline void _cpp_maybe_notify_macro_use (cpp_reader *pfile, cpp_hashnode *node)
@@ -674,7 +681,8 @@ extern void _cpp_destroy_hashtable (cpp_reader *);
/* In files.c */
typedef struct _cpp_file _cpp_file;
extern _cpp_file *_cpp_find_file (cpp_reader *, const char *, cpp_dir *,
- bool, int, bool, location_t);
+ int angle, bool fake, bool preinclude,
+ bool has_include, location_t);
extern bool _cpp_find_failed (_cpp_file *);
extern void _cpp_mark_file_once_only (cpp_reader *, struct _cpp_file *);
extern void _cpp_fake_include (cpp_reader *, const char *);