libcpp: Implement clang -Wheader-guard warning [PR96842]
The following patch implements the clang -Wheader-guard warning, which warns if a valid multiple inclusion header guard's #ifndef/#if !defined directive is immediately (no other non-line directives nor other (non-comment) tokens in between) followed by #define directive for some different macro, which in get_suggestion rules is close enough to the actual header guard macro (i.e. likely misspelling), the #define is object-like with empty definition (I've followed what clang implements) and the macro isn't defined later on (at least not on the final #endif at the end of a header). In this case it emits a warning, so that #ifndef STDIO_H #define STDOI_H ... #endif or similar misspellings can be caught. clang enables this warning by default, but I've put it into -Wall instead as it still seems to be a style warning, nothing more severe; if a header doesn't survive multiple inclusion because of the misspelling, users will get different diagnostics. 2024-10-02 Jakub Jelinek <jakub@redhat.com> PR preprocessor/96842 libcpp/ * include/cpplib.h (struct cpp_options): Add warn_header_guard member. (enum cpp_warning_reason): Add CPP_W_HEADER_GUARD enumerator. * internal.h (struct cpp_reader): Add mi_def_cmacro, mi_loc and mi_def_loc members. (_cpp_defined_macro_p): Constify type pointed by argument type. Formatting fix. * init.cc (cpp_create_reader): Clear CPP_OPTION (pfile, warn_header_guard). * directives.cc (struct if_stack): Add def_loc and mi_def_cmacro members. (DIRECTIVE_TABLE): Add IF_COND flag to define. (do_define): Set ifs->mi_def_cmacro on a define immediately following #ifndef directive for the guard. Clear pfile->mi_valid. Formatting fix. (do_endif): Copy over pfile->mi_def_cmacro and pfile->mi_def_loc if ifs->mi_def_cmacro is set and pfile->mi_cmacro isn't a defined macro. (push_conditional): Clear mi_def_cmacro and mi_def_loc members. * files.cc (_cpp_pop_file_buffer): Emit -Wheader-guard diagnostics. gcc/ * doc/invoke.texi (Wheader-guard): Document. gcc/c-family/ * c.opt (Wheader-guard): New option. * c.opt.urls: Regenerated. * c-ppoutput.cc (init_pp_output): Initialize also cb->get_suggestion. gcc/testsuite/ * c-c++-common/cpp/Wheader-guard-1.c: New test. * c-c++-common/cpp/Wheader-guard-1-1.h: New test. * c-c++-common/cpp/Wheader-guard-1-2.h: New test. * c-c++-common/cpp/Wheader-guard-1-3.h: New test. * c-c++-common/cpp/Wheader-guard-1-4.h: New test. * c-c++-common/cpp/Wheader-guard-1-5.h: New test. * c-c++-common/cpp/Wheader-guard-1-6.h: New test. * c-c++-common/cpp/Wheader-guard-1-7.h: New test. * c-c++-common/cpp/Wheader-guard-1-8.h: New test. * c-c++-common/cpp/Wheader-guard-1-9.h: New test. * c-c++-common/cpp/Wheader-guard-1-10.h: New test. * c-c++-common/cpp/Wheader-guard-1-11.h: New test. * c-c++-common/cpp/Wheader-guard-1-12.h: New test. * c-c++-common/cpp/Wheader-guard-2.c: New test. * c-c++-common/cpp/Wheader-guard-2.h: New test. * c-c++-common/cpp/Wheader-guard-3.c: New test. * c-c++-common/cpp/Wheader-guard-3.h: New test.
This commit is contained in:
parent
ba53ccad55
commit
5943a2fa1b
26 changed files with 197 additions and 9 deletions
|
@ -164,6 +164,7 @@ init_pp_output (FILE *out_stream)
|
|||
cb->has_builtin = c_common_has_builtin;
|
||||
cb->has_feature = c_common_has_feature;
|
||||
cb->get_source_date_epoch = cb_get_source_date_epoch;
|
||||
cb->get_suggestion = cb_get_suggestion;
|
||||
cb->remap_filename = remap_macro_filename;
|
||||
|
||||
/* Initialize the print structure. */
|
||||
|
|
|
@ -828,6 +828,10 @@ Wglobal-module
|
|||
C++ ObjC++ Var(warn_global_module) Warning Init(1)
|
||||
Warn about the global module fragment not containing only preprocessing directives.
|
||||
|
||||
Wheader-guard
|
||||
C ObjC C++ ObjC++ CPP(warn_header_guard) CppReason(CPP_W_HEADER_GUARD) Var(cpp_warn_header_guard) Init(0) Warning LangEnabledBy(C ObjC C++ ObjC++,Wall)
|
||||
Warn when #ifndef of a header guard is followed by #define of a different macro with the header guard macro not defined at the end of header.
|
||||
|
||||
Wif-not-aligned
|
||||
C ObjC C++ ObjC++ Var(warn_if_not_aligned) Init(1) Warning
|
||||
Warn when the field in a struct is not aligned.
|
||||
|
|
|
@ -415,6 +415,9 @@ UrlSuffix(gcc/Warning-Options.html#index-Wframe-address)
|
|||
Wglobal-module
|
||||
UrlSuffix(gcc/C_002b_002b-Dialect-Options.html#index-Wglobal-module)
|
||||
|
||||
Wheader-guard
|
||||
UrlSuffix(gcc/Warning-Options.html#index-Wheader-guard)
|
||||
|
||||
Wif-not-aligned
|
||||
UrlSuffix(gcc/Warning-Options.html#index-Wif-not-aligned)
|
||||
|
||||
|
|
|
@ -372,7 +372,7 @@ Objective-C and Objective-C++ Dialects}.
|
|||
-Wformat-security -Wformat-signedness -Wformat-truncation=@var{n}
|
||||
-Wformat-y2k -Wframe-address
|
||||
-Wframe-larger-than=@var{byte-size} -Wno-free-nonheap-object
|
||||
-Wno-if-not-aligned -Wno-ignored-attributes
|
||||
-Wheader-guard -Wno-if-not-aligned -Wno-ignored-attributes
|
||||
-Wignored-qualifiers -Wno-incompatible-pointer-types -Whardened
|
||||
-Wimplicit -Wimplicit-fallthrough -Wimplicit-fallthrough=@var{n}
|
||||
-Wno-implicit-function-declaration -Wno-implicit-int
|
||||
|
@ -10115,6 +10115,19 @@ Do not warn if certain built-in macros are redefined. This suppresses
|
|||
warnings for redefinition of @code{__TIMESTAMP__}, @code{__TIME__},
|
||||
@code{__DATE__}, @code{__FILE__}, and @code{__BASE_FILE__}.
|
||||
|
||||
@opindex Wheader-guard
|
||||
@item -Wheader-guard
|
||||
Warn if a valid preprocessor header multiple inclusion guard has
|
||||
a @code{#define} directive right after @code{#ifndef} or @code{#if !defined}
|
||||
directive for the multiple inclusion guard, which defines a different macro
|
||||
from the guard macro with a similar name, the actual multiple inclusion guard
|
||||
macro isn't defined at the corresponding @code{#ifndef} directive at the end
|
||||
of the header, and the @code{#define} directive defines an object-like macro
|
||||
with empty definition. In such case, it often is just a misspelled guard
|
||||
name, either in the @code{#ifndef} or @code{#if !defined} directive or in the
|
||||
subsequent @code{#define} directive. This warning is enabled
|
||||
by @option{-Wall}.
|
||||
|
||||
@opindex Wstrict-prototypes
|
||||
@opindex Wno-strict-prototypes
|
||||
@item -Wstrict-prototypes @r{(C and Objective-C only)}
|
||||
|
|
5
gcc/testsuite/c-c++-common/cpp/Wheader-guard-1-1.h
Normal file
5
gcc/testsuite/c-c++-common/cpp/Wheader-guard-1-1.h
Normal file
|
@ -0,0 +1,5 @@
|
|||
#ifndef WHEADER_GUARD_1
|
||||
#define WHEADER_GUARD_1
|
||||
/* This is what header guards should look like. */
|
||||
#define SOMETHING1 123
|
||||
#endif
|
5
gcc/testsuite/c-c++-common/cpp/Wheader-guard-1-10.h
Normal file
5
gcc/testsuite/c-c++-common/cpp/Wheader-guard-1-10.h
Normal file
|
@ -0,0 +1,5 @@
|
|||
#ifndef WHEADER_GUARD_10
|
||||
#define WHEADERGUARD10
|
||||
/* Don't warn if it actually isn't a valid header guard. */
|
||||
#else
|
||||
#endif
|
5
gcc/testsuite/c-c++-common/cpp/Wheader-guard-1-11.h
Normal file
5
gcc/testsuite/c-c++-common/cpp/Wheader-guard-1-11.h
Normal file
|
@ -0,0 +1,5 @@
|
|||
#ifndef WHEADER_GUARD_11
|
||||
#define WHEADERGUARD11
|
||||
/* Don't warn if it actually isn't a valid header guard. */
|
||||
#elif 1
|
||||
#endif
|
5
gcc/testsuite/c-c++-common/cpp/Wheader-guard-1-12.h
Normal file
5
gcc/testsuite/c-c++-common/cpp/Wheader-guard-1-12.h
Normal file
|
@ -0,0 +1,5 @@
|
|||
#ifndef WHEADER_GUARD_12
|
||||
#define WHEADERGUARD12
|
||||
/* Don't warn if it actually isn't a valid header guard. */
|
||||
#endif
|
||||
#define ASOMETHING12
|
4
gcc/testsuite/c-c++-common/cpp/Wheader-guard-1-2.h
Normal file
4
gcc/testsuite/c-c++-common/cpp/Wheader-guard-1-2.h
Normal file
|
@ -0,0 +1,4 @@
|
|||
#ifndef WHEADER_GUARD_2
|
||||
#define WHEADERGUARD2 1
|
||||
/* Don't warn if the different macro defines some tokens. */
|
||||
#endif
|
4
gcc/testsuite/c-c++-common/cpp/Wheader-guard-1-3.h
Normal file
4
gcc/testsuite/c-c++-common/cpp/Wheader-guard-1-3.h
Normal file
|
@ -0,0 +1,4 @@
|
|||
#ifndef WHEADER_GUARD_3
|
||||
#define WHEADERGUARD3()
|
||||
/* Won't warn if it is a function-like macro. */
|
||||
#endif
|
3
gcc/testsuite/c-c++-common/cpp/Wheader-guard-1-4.h
Normal file
3
gcc/testsuite/c-c++-common/cpp/Wheader-guard-1-4.h
Normal file
|
@ -0,0 +1,3 @@
|
|||
#ifndef WHEADER_GUARD_4
|
||||
/* Don't warn if there is no define after #ifndef. */
|
||||
#endif
|
5
gcc/testsuite/c-c++-common/cpp/Wheader-guard-1-5.h
Normal file
5
gcc/testsuite/c-c++-common/cpp/Wheader-guard-1-5.h
Normal file
|
@ -0,0 +1,5 @@
|
|||
#ifndef WHEADER_GUARD_5
|
||||
int guard5;
|
||||
#define WHEADERGUARD5
|
||||
/* Don't warn if there are tokens in between #ifndef and #define. */
|
||||
#endif
|
8
gcc/testsuite/c-c++-common/cpp/Wheader-guard-1-6.h
Normal file
8
gcc/testsuite/c-c++-common/cpp/Wheader-guard-1-6.h
Normal file
|
@ -0,0 +1,8 @@
|
|||
#ifndef WHEADER_GUARD_6
|
||||
#define WHEADERGUARD6
|
||||
/* Don't warn if WHEADER_GUARD_6 is eventually defined later. */
|
||||
#if 0
|
||||
#else
|
||||
#define WHEADER_GUARD_6
|
||||
#endif
|
||||
#endif
|
4
gcc/testsuite/c-c++-common/cpp/Wheader-guard-1-7.h
Normal file
4
gcc/testsuite/c-c++-common/cpp/Wheader-guard-1-7.h
Normal file
|
@ -0,0 +1,4 @@
|
|||
#ifndef WHEADER_GUARD_7
|
||||
#define SOMETHING7
|
||||
/* Don't warn if the two macros don't have similar names. */
|
||||
#endif
|
5
gcc/testsuite/c-c++-common/cpp/Wheader-guard-1-8.h
Normal file
5
gcc/testsuite/c-c++-common/cpp/Wheader-guard-1-8.h
Normal file
|
@ -0,0 +1,5 @@
|
|||
#ifndef WHEADER_GUARD_8
|
||||
#define WHEADERGUARD8
|
||||
/* Don't warn if the guard macro is already defined before
|
||||
including the header. */
|
||||
#endif
|
5
gcc/testsuite/c-c++-common/cpp/Wheader-guard-1-9.h
Normal file
5
gcc/testsuite/c-c++-common/cpp/Wheader-guard-1-9.h
Normal file
|
@ -0,0 +1,5 @@
|
|||
int guard9;
|
||||
#ifndef WHEADER_GUARD_9
|
||||
#define WHEADERGUARD9
|
||||
/* Don't warn if it actually isn't a valid header guard. */
|
||||
#endif
|
19
gcc/testsuite/c-c++-common/cpp/Wheader-guard-1.c
Normal file
19
gcc/testsuite/c-c++-common/cpp/Wheader-guard-1.c
Normal file
|
@ -0,0 +1,19 @@
|
|||
/* PR preprocessor/96842 */
|
||||
/* { dg-do preprocess } */
|
||||
/* { dg-options "-Wall" } */
|
||||
|
||||
#include "Wheader-guard-1-1.h"
|
||||
#include "Wheader-guard-1-2.h"
|
||||
#include "Wheader-guard-1-3.h"
|
||||
#include "Wheader-guard-1-4.h"
|
||||
#include "Wheader-guard-1-5.h"
|
||||
#include "Wheader-guard-1-6.h"
|
||||
#include "Wheader-guard-1-7.h"
|
||||
#define WHEADER_GUARD_8
|
||||
#include "Wheader-guard-1-8.h"
|
||||
#include "Wheader-guard-1-9.h"
|
||||
#include "Wheader-guard-1-10.h"
|
||||
#include "Wheader-guard-1-11.h"
|
||||
#include "Wheader-guard-1-12.h"
|
||||
|
||||
int i;
|
10
gcc/testsuite/c-c++-common/cpp/Wheader-guard-2.c
Normal file
10
gcc/testsuite/c-c++-common/cpp/Wheader-guard-2.c
Normal file
|
@ -0,0 +1,10 @@
|
|||
/* PR preprocessor/96842 */
|
||||
/* { dg-do preprocess } */
|
||||
/* { dg-options "-Wheader-guard" } */
|
||||
|
||||
#include "Wheader-guard-2.h"
|
||||
|
||||
int i;
|
||||
|
||||
/* { dg-warning "header guard \"WHEADER_GUARD_2\" followed by \"#define\" of a different macro" "" { target *-*-* } 0 } */
|
||||
/* { dg-message "\"WHEADERGUARD2\" is defined here; did you mean \"WHEADER_GUARD_2\"\\\?" "" { target *-*-* } 0 } */
|
4
gcc/testsuite/c-c++-common/cpp/Wheader-guard-2.h
Normal file
4
gcc/testsuite/c-c++-common/cpp/Wheader-guard-2.h
Normal file
|
@ -0,0 +1,4 @@
|
|||
#ifndef WHEADER_GUARD_2
|
||||
#define WHEADERGUARD2
|
||||
#define SOMETHING2 123
|
||||
#endif
|
10
gcc/testsuite/c-c++-common/cpp/Wheader-guard-3.c
Normal file
10
gcc/testsuite/c-c++-common/cpp/Wheader-guard-3.c
Normal file
|
@ -0,0 +1,10 @@
|
|||
/* PR preprocessor/96842 */
|
||||
/* { dg-do preprocess } */
|
||||
/* { dg-options "-Wall" } */
|
||||
|
||||
#include "Wheader-guard-3.h"
|
||||
|
||||
int i;
|
||||
|
||||
/* { dg-warning "header guard \"WHEADER_GUARD_3\" followed by \"#define\" of a different macro" "" { target *-*-* } 0 } */
|
||||
/* { dg-message "\"WHEADERGUARD3\" is defined here; did you mean \"WHEADER_GUARD_3\"\\\?" "" { target *-*-* } 0 } */
|
4
gcc/testsuite/c-c++-common/cpp/Wheader-guard-3.h
Normal file
4
gcc/testsuite/c-c++-common/cpp/Wheader-guard-3.h
Normal file
|
@ -0,0 +1,4 @@
|
|||
#if !defined(WHEADER_GUARD_3)
|
||||
#define WHEADERGUARD3
|
||||
#define SOMETHING3 123
|
||||
#endif
|
|
@ -31,7 +31,11 @@ struct if_stack
|
|||
{
|
||||
struct if_stack *next;
|
||||
location_t line; /* Line where condition started. */
|
||||
const cpp_hashnode *mi_cmacro;/* macro name for #ifndef around entire file */
|
||||
location_t def_loc; /* Locus of the following #define if any. */
|
||||
const cpp_hashnode *mi_cmacro;/* Macro name for #ifndef around entire
|
||||
file. */
|
||||
const cpp_hashnode *mi_def_cmacro; /* Macro name in the following
|
||||
#define. */
|
||||
bool skip_elses; /* Can future #else / #elif be skipped? */
|
||||
bool was_skipping; /* If were skipping on entry. */
|
||||
int type; /* Most recent conditional for diagnostics. */
|
||||
|
@ -144,7 +148,7 @@ static void cpp_pop_definition (cpp_reader *, struct def_pragma_macro *);
|
|||
where the extension appears to have come from. */
|
||||
|
||||
#define DIRECTIVE_TABLE \
|
||||
D(define, T_DEFINE = 0, KANDR, IN_I) \
|
||||
D(define, T_DEFINE = 0, KANDR, IN_I | IF_COND) \
|
||||
D(include, T_INCLUDE, KANDR, INCL | EXPAND) \
|
||||
D(endif, T_ENDIF, KANDR, COND) \
|
||||
D(ifdef, T_IFDEF, KANDR, COND | IF_COND) \
|
||||
|
@ -680,8 +684,8 @@ do_define (cpp_reader *pfile)
|
|||
|
||||
/* If we have been requested to expand comments into macros,
|
||||
then re-enable saving of comments. */
|
||||
pfile->state.save_comments =
|
||||
! CPP_OPTION (pfile, discard_comments_in_macro_exp);
|
||||
pfile->state.save_comments
|
||||
= ! CPP_OPTION (pfile, discard_comments_in_macro_exp);
|
||||
|
||||
if (pfile->cb.before_define)
|
||||
pfile->cb.before_define (pfile);
|
||||
|
@ -691,7 +695,28 @@ do_define (cpp_reader *pfile)
|
|||
pfile->cb.define (pfile, pfile->directive_line, node);
|
||||
|
||||
node->flags &= ~NODE_USED;
|
||||
|
||||
if (pfile->mi_valid
|
||||
&& !pfile->mi_cmacro
|
||||
&& CPP_OPTION (pfile, warn_header_guard)
|
||||
&& node->type == NT_USER_MACRO
|
||||
&& node->value.macro
|
||||
&& node->value.macro->count == 0
|
||||
&& !node->value.macro->fun_like)
|
||||
{
|
||||
cpp_buffer *buffer = pfile->buffer;
|
||||
struct if_stack *ifs = buffer->if_stack;
|
||||
if (ifs
|
||||
&& !ifs->next
|
||||
&& ifs->mi_cmacro
|
||||
&& node != ifs->mi_cmacro)
|
||||
{
|
||||
ifs->mi_def_cmacro = node;
|
||||
ifs->def_loc = pfile->directive_line;
|
||||
}
|
||||
}
|
||||
}
|
||||
pfile->mi_valid = false;
|
||||
}
|
||||
|
||||
/* Handle #undef. Mark the identifier NT_VOID in the hash table. */
|
||||
|
@ -2711,6 +2736,13 @@ do_endif (cpp_reader *pfile)
|
|||
{
|
||||
pfile->mi_valid = true;
|
||||
pfile->mi_cmacro = ifs->mi_cmacro;
|
||||
pfile->mi_loc = ifs->line;
|
||||
pfile->mi_def_cmacro = nullptr;
|
||||
if (ifs->mi_def_cmacro && !_cpp_defined_macro_p (pfile->mi_cmacro))
|
||||
{
|
||||
pfile->mi_def_cmacro = ifs->mi_def_cmacro;
|
||||
pfile->mi_def_loc = ifs->def_loc;
|
||||
}
|
||||
}
|
||||
|
||||
buffer->if_stack = ifs->next;
|
||||
|
@ -2732,6 +2764,7 @@ push_conditional (cpp_reader *pfile, int skip, int type,
|
|||
|
||||
ifs = XOBNEW (&pfile->buffer_ob, struct if_stack);
|
||||
ifs->line = pfile->directive_line;
|
||||
ifs->def_loc = 0;
|
||||
ifs->next = buffer->if_stack;
|
||||
ifs->skip_elses = pfile->state.skipping || !skip;
|
||||
ifs->was_skipping = pfile->state.skipping;
|
||||
|
@ -2741,6 +2774,7 @@ push_conditional (cpp_reader *pfile, int skip, int type,
|
|||
ifs->mi_cmacro = cmacro;
|
||||
else
|
||||
ifs->mi_cmacro = 0;
|
||||
ifs->mi_def_cmacro = nullptr;
|
||||
|
||||
pfile->state.skipping = skip;
|
||||
buffer->if_stack = ifs;
|
||||
|
|
|
@ -2253,7 +2253,26 @@ _cpp_pop_file_buffer (cpp_reader *pfile, _cpp_file *file,
|
|||
/* Record the inclusion-preventing macro, which could be NULL
|
||||
meaning no controlling macro. */
|
||||
if (pfile->mi_valid && file->cmacro == NULL)
|
||||
file->cmacro = pfile->mi_cmacro;
|
||||
{
|
||||
file->cmacro = pfile->mi_cmacro;
|
||||
if (pfile->mi_cmacro
|
||||
&& pfile->mi_def_cmacro
|
||||
&& pfile->cb.get_suggestion)
|
||||
{
|
||||
auto mi_cmacro = (const char *) NODE_NAME (pfile->mi_cmacro);
|
||||
auto mi_def_cmacro = (const char *) NODE_NAME (pfile->mi_def_cmacro);
|
||||
const char *names[] = { mi_def_cmacro, NULL };
|
||||
if (pfile->cb.get_suggestion (pfile, mi_cmacro, names)
|
||||
&& cpp_warning_with_line (pfile, CPP_W_HEADER_GUARD,
|
||||
pfile->mi_loc, 0,
|
||||
"header guard \"%s\" followed by "
|
||||
"\"#define\" of a different macro",
|
||||
mi_cmacro))
|
||||
cpp_error_at (pfile, CPP_DL_NOTE, pfile->mi_def_loc,
|
||||
"\"%s\" is defined here; did you mean \"%s\"?",
|
||||
mi_def_cmacro, mi_cmacro);
|
||||
}
|
||||
}
|
||||
|
||||
/* Invalidate control macros in the #including file. */
|
||||
pfile->mi_valid = false;
|
||||
|
|
|
@ -435,6 +435,10 @@ struct cpp_options
|
|||
/* Different -Wimplicit-fallthrough= levels. */
|
||||
unsigned char cpp_warn_implicit_fallthrough;
|
||||
|
||||
/* Nonzero means warn about a define of a different macro right after
|
||||
#ifndef/#if !defined header guard directive. */
|
||||
unsigned char warn_header_guard;
|
||||
|
||||
/* Nonzero means we should look for header.gcc files that remap file
|
||||
names. */
|
||||
unsigned char remap;
|
||||
|
@ -709,7 +713,8 @@ enum cpp_warning_reason {
|
|||
CPP_W_EXPANSION_TO_DEFINED,
|
||||
CPP_W_BIDIRECTIONAL,
|
||||
CPP_W_INVALID_UTF8,
|
||||
CPP_W_UNICODE
|
||||
CPP_W_UNICODE,
|
||||
CPP_W_HEADER_GUARD
|
||||
};
|
||||
|
||||
/* Callback for header lookup for HEADER, which is the name of a
|
||||
|
|
|
@ -230,6 +230,7 @@ cpp_create_reader (enum c_lang lang, cpp_hash_table *table,
|
|||
CPP_OPTION (pfile, warn_variadic_macros) = 1;
|
||||
CPP_OPTION (pfile, warn_builtin_macro_redefined) = 1;
|
||||
CPP_OPTION (pfile, cpp_warn_implicit_fallthrough) = 0;
|
||||
CPP_OPTION (pfile, warn_header_guard) = 0;
|
||||
/* By default, track locations of tokens resulting from macro
|
||||
expansion. The '2' means, track the locations with the highest
|
||||
accuracy. Read the comments for struct
|
||||
|
|
|
@ -495,9 +495,11 @@ struct cpp_reader
|
|||
been used. */
|
||||
bool seen_once_only;
|
||||
|
||||
/* Multiple include optimization. */
|
||||
/* Multiple include optimization and -Wheader-guard warning. */
|
||||
const cpp_hashnode *mi_cmacro;
|
||||
const cpp_hashnode *mi_ind_cmacro;
|
||||
const cpp_hashnode *mi_def_cmacro;
|
||||
location_t mi_loc, mi_def_loc;
|
||||
bool mi_valid;
|
||||
|
||||
/* Lexing. */
|
||||
|
@ -696,7 +698,8 @@ _cpp_in_main_source_file (cpp_reader *pfile)
|
|||
}
|
||||
|
||||
/* True if NODE is a macro for the purposes of ifdef, defined etc. */
|
||||
inline bool _cpp_defined_macro_p (cpp_hashnode *node)
|
||||
inline bool
|
||||
_cpp_defined_macro_p (const cpp_hashnode *node)
|
||||
{
|
||||
/* Do not treat conditional macros as being defined. This is due to
|
||||
the powerpc port using conditional macros for 'vector', 'bool',
|
||||
|
|
Loading…
Add table
Reference in a new issue