Re: [PATCH] cpp: new built-in __EXP_COUNTER__
On 2024-03-21 18:40, Andrew Pinski wrote: On Thu, Mar 21, 2024, 17:20 Kaz Kylheku wrote: For instance, suppose we have a macro that expands to some block of code in which there is an internal goto. If we have it #define MAC(...) { ... goto _label; ... __label: ; } then this cannot be used twice in the same function; labels have function scope. In this case why can't you use gcc's already extension of defining a local label? https://gcc.gnu.org/onlinedocs/gcc-13.2.0/gcc/Local-Labels.html This extension has been around for over 20 years specifically for that use case. Yes. For that case, local labels are a nice solution. It's just an example of the sort of thing for which it may be useful for a macro to be able to invent different identifiers in different invocations. The GNU preprocessor is used for multiple languages, and is also exposed as an independent utility that can be used to process anything that has a sufficiently C-like token structure. Since local labels are intended for macros, they are not subject to diagnosis by -Wshadow. In the ordinary namespace for variables/functions/typedefs, there is no such concession. Macros that reuse identifiers in nested scopes will trigger nuisance warnings from -Wshadow.
Re: [PATCH] cpp: new built-in __EXP_COUNTER__
On Thu, Mar 21, 2024, 17:20 Kaz Kylheku wrote: > On 2024-03-20 16:34, rep.dot@gmail.com wrote: > > On 19 March 2024 18:27:13 CET, Kaz Kylheku wrote: > >>On 2024-03-18 00:30, Jonathan Wakely wrote: > >>> I don't have an opinion on the implementation, or the proposal itself, > >>> except that the implementation seems susprisingly simple, which is > >>> nice. > >> > >>Hi Jonathan, > >> > >>Here is an updated patch. > >> > >>It rebased cleanly over more than newer 16000 commits, suggesting > >>that the area in the cpp code is "still waters", which is good. > >> > >>I made the documentation change not to recommend using #if, but > >>#ifdef. > >> > >>I got rid of the ChangeLog changes, and also tried to pay more > >>attention to the log message format, where the ChangeLog pieces > >>are specified. > >> > >>In the first test case, I had to adjust the expected warning text > >>for two lines. > >> > > > > Please forgive the bike shedding, but __EXP_COUNTER__ would lead me into > thinking about exponents or thereabouts. > > __MACRO_EXPANSION_COUNTER__ is more what your patch is about, IMHO? > Maybe you could come up with a more descriptive name, please? > > > > And, while I can see what could possibly be done with that, I'm not > really convinced that it would be a wise idea to (unilaterally) support > that idea. Don't you think that this would encourage producing more > spaghetti code? > > > > Just curious about real world motivating examples I guess. > > cheers > > Hi, (Bernhard?) > > Concerns about naming are very important; not bike shedding at all. > I changed the patch to use __EXPANSION_NUMBER__. I didn't include MACRO > because I hope it's clear that in preprocessing, we are expanding > macros. The parent symbol is now called __PARENT_EXPANSION_NUMBER__. > > I dropped the COUNTER terminology because the existing __COUNTER__ > is a symbol whose value changes each time it is mentioned, > These symbols are not like that; they capture a fixed value in > a scope and behave like ordinary macros. > > In doing the renaming, I noticed that from the beginning I've already > been calling the internal value in the macro context macro->exp_number, > because it's not a counter. > > The focus of this feature isn't to enable some new "earth-shattering" > techniques, but to improve certain situations in existing macros. > > For instance, suppose we have a macro that expands to some block > of code in which there is an internal goto. If we have it > > #define MAC(...) { ... goto _label; ... __label: ; } > > then this cannot be used twice in the same function; labels have > function scope. In this case why can't you use gcc's already extension of defining a local label? https://gcc.gnu.org/onlinedocs/gcc-13.2.0/gcc/Local-Labels.html This extension has been around for over 20 years specifically for that use case. Thanks, Andrew If we make it > > #define MAC(...) { ... goto CAT(__label, __LINE__); ... CAT(__label, > __LINE__): ; } > > we now can use MAC two or more times in the same function, but not in > the same line of code. > > With __EXPANSION_NUMBER__ it is doable. Given this program: > > #define xcat(A, B) A ## B > #define cat(A, B) xcat(A, B) > #define lab(PREFIX) cat(PREFIX, __PARENT_EXPANSION_NUMBER__) > > #define MAC { goto lab(foo); /*...*/ lab(foo): ; } > > MAC MAC MAC > > We get the preprocessed output (with -E): > > { goto foo3; foo3: ; } { goto foo10; foo10: ; } { goto foo17; foo17: ; } > > There are issues with relying on __LINE__ to produce different values > when it is referenced in code generated by a macro. > > The following program prints the same value 12 three times; even though > PRINT seems to be referenced on different physical lines in the > PRINT3 macro replacement text. __LINE__ references the line where > the top-level expansion of PRINT3 occurs, not where PRINT occurs. > > #include > > #define PRINT (printf("%d\n", __LINE__)) > > #define PRINT3 do { \ > PRINT;\ > PRINT;\ > PRINT;\ > } while (0) > > int main() > { > PRINT3; > return 0; > } >
Re: [PATCH] cpp: new built-in __EXP_COUNTER__
On 2024-03-20 16:34, rep.dot@gmail.com wrote: > On 19 March 2024 18:27:13 CET, Kaz Kylheku wrote: >>On 2024-03-18 00:30, Jonathan Wakely wrote: >>> I don't have an opinion on the implementation, or the proposal itself, >>> except that the implementation seems susprisingly simple, which is >>> nice. >> >>Hi Jonathan, >> >>Here is an updated patch. >> >>It rebased cleanly over more than newer 16000 commits, suggesting >>that the area in the cpp code is "still waters", which is good. >> >>I made the documentation change not to recommend using #if, but >>#ifdef. >> >>I got rid of the ChangeLog changes, and also tried to pay more >>attention to the log message format, where the ChangeLog pieces >>are specified. >> >>In the first test case, I had to adjust the expected warning text >>for two lines. >> > > Please forgive the bike shedding, but __EXP_COUNTER__ would lead me into > thinking about exponents or thereabouts. > __MACRO_EXPANSION_COUNTER__ is more what your patch is about, IMHO? Maybe you > could come up with a more descriptive name, please? > > And, while I can see what could possibly be done with that, I'm not really > convinced that it would be a wise idea to (unilaterally) support that idea. > Don't you think that this would encourage producing more spaghetti code? > > Just curious about real world motivating examples I guess. > cheers Hi, (Bernhard?) Concerns about naming are very important; not bike shedding at all. I changed the patch to use __EXPANSION_NUMBER__. I didn't include MACRO because I hope it's clear that in preprocessing, we are expanding macros. The parent symbol is now called __PARENT_EXPANSION_NUMBER__. I dropped the COUNTER terminology because the existing __COUNTER__ is a symbol whose value changes each time it is mentioned, These symbols are not like that; they capture a fixed value in a scope and behave like ordinary macros. In doing the renaming, I noticed that from the beginning I've already been calling the internal value in the macro context macro->exp_number, because it's not a counter. The focus of this feature isn't to enable some new "earth-shattering" techniques, but to improve certain situations in existing macros. For instance, suppose we have a macro that expands to some block of code in which there is an internal goto. If we have it #define MAC(...) { ... goto _label; ... __label: ; } then this cannot be used twice in the same function; labels have function scope. If we make it #define MAC(...) { ... goto CAT(__label, __LINE__); ... CAT(__label, __LINE__): ; } we now can use MAC two or more times in the same function, but not in the same line of code. With __EXPANSION_NUMBER__ it is doable. Given this program: #define xcat(A, B) A ## B #define cat(A, B) xcat(A, B) #define lab(PREFIX) cat(PREFIX, __PARENT_EXPANSION_NUMBER__) #define MAC { goto lab(foo); /*...*/ lab(foo): ; } MAC MAC MAC We get the preprocessed output (with -E): { goto foo3; foo3: ; } { goto foo10; foo10: ; } { goto foo17; foo17: ; } There are issues with relying on __LINE__ to produce different values when it is referenced in code generated by a macro. The following program prints the same value 12 three times; even though PRINT seems to be referenced on different physical lines in the PRINT3 macro replacement text. __LINE__ references the line where the top-level expansion of PRINT3 occurs, not where PRINT occurs. #include #define PRINT (printf("%d\n", __LINE__)) #define PRINT3 do { \ PRINT;\ PRINT;\ PRINT;\ } while (0) int main() { PRINT3; return 0; } From 4aded10c4171f9a9a361bb8986d721357f1fc2c8 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Wed, 20 Apr 2022 01:15:24 -0700 Subject: [PATCH] cpp: new built-in __EXPANSION_NUMBER__ This change introduces a pair of related macros __EXPANSION_NUMBER__ and __PARENT_EXPANSION_NUMBER__. These macros access integer values which enumerate macro expansions. They can be used for the purposes of obtaining, unique identifiers (within the scope of a translation unit), as a replacement for unreliable hacks based on __LINE__. Outside of macro expansions, these macros epand to 1, so they are easy to test for in portable code that needs to fall back on another approach, perhaps involving __LINE__. libcpp/ChangeLog: * libcpp/include/cpplib.h (struct cpp_macro): New members of type long long: expansion_number and parent_expansion_number. These members are used to attach the current expansion_counter value, and the parent context's copy of it to a new macro expansion. The special macros then just access these. (enum cpp_builtin_type): New enumeration members, BT_EXPANSION_NUMBER and BT_PARENT_EXPANSION_NUMBER. * libcpp/macro.cc (expansion_counter): New static variable for counting expansions. There is an existing one, num_expanded_macros_counter, but that has its own purpose and is incremented in a specific place. Plus it uses a narrower integer
Re: [PATCH] cpp: new built-in __EXP_COUNTER__
On 19 March 2024 18:27:13 CET, Kaz Kylheku wrote: >On 2024-03-18 00:30, Jonathan Wakely wrote: >> I don't have an opinion on the implementation, or the proposal itself, >> except that the implementation seems susprisingly simple, which is >> nice. > >Hi Jonathan, > >Here is an updated patch. > >It rebased cleanly over more than newer 16000 commits, suggesting >that the area in the cpp code is "still waters", which is good. > >I made the documentation change not to recommend using #if, but >#ifdef. > >I got rid of the ChangeLog changes, and also tried to pay more >attention to the log message format, where the ChangeLog pieces >are specified. > >In the first test case, I had to adjust the expected warning text >for two lines. > Please forgive the bike shedding, but __EXP_COUNTER__ would lead me into thinking about exponents or thereabouts. __MACRO_EXPANSION_COUNTER__ is more what your patch is about, IMHO? Maybe you could come up with a more descriptive name, please? And, while I can see what could possibly be done with that, I'm not really convinced that it would be a wise idea to (unilaterally) support that idea. Don't you think that this would encourage producing more spaghetti code? Just curious about real world motivating examples I guess. cheers
Re: [PATCH] cpp: new built-in __EXP_COUNTER__
On 2024-03-18 00:30, Jonathan Wakely wrote: > I don't have an opinion on the implementation, or the proposal itself, > except that the implementation seems susprisingly simple, which is > nice. Hi Jonathan, Here is an updated patch. It rebased cleanly over more than newer 16000 commits, suggesting that the area in the cpp code is "still waters", which is good. I made the documentation change not to recommend using #if, but #ifdef. I got rid of the ChangeLog changes, and also tried to pay more attention to the log message format, where the ChangeLog pieces are specified. In the first test case, I had to adjust the expected warning text for two lines. From 65effbcac172e8bb1a89f0621b3de6cdcb8dbab2 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Wed, 20 Apr 2022 01:15:24 -0700 Subject: [PATCH] cpp: new built-in __EXP_COUNTER__ This change introduces a pair of related macros __EXP_COUNTER__ and __UEXP_COUNTER__. These macros access integer values which enumerate macro expansions. They can be used for the purposes of obtaining, unique identifiers (within the scope of a translation unit), as a replacement for unreliable hacks based on __LINE__. Outside of macro expansions, these macros epand to 1, so they are easy to test for in portable code that needs to fall back on something, like __LINE__. libcpp/ChangeLog: * libcpp/include/cpplib.h (struct cpp_macro): New members of type long long: exp_number and uexp_number. These members are used to attach the current exp_counter value, and the parent context's copy of it to a new macro expansion. The special macros then just access these. (enum cpp_builtin_type): New enumeration members, BT_EXP_COUNTER and BT_UEXP_COUNTER. * libcpp/macro.cc (exp_counter): New static variable for counting expansions. There is an existing one, num_expanded_macros_counter, but that has its own purpose and is incremented in a specific place. Plus it uses a narrower integer type. (_cpp_builtin_number_text): Change the local variable "number" from linenum_type to unsigned long long, so it holds at least 64 bit values. Handle the BT_EXP_COUNTER and BT_UEXP_COUNTER cases. These just have to see if there is a current macro, and retrieve the values from it, otherwise do nothing so that the default 1 is produced. In the case of BT_UEXP_COUNTER, if the value is zero, we don't use it, so 1 emerges. The sprintf of the number is adjusted to use the right conversion specifier for the wider type. Space is already being reserved for a 64 bit decimal. (enter_macro_context): After processing the macro arguments, if any, we increment exp_counter and attach its new value to the macro's context structure in the exp_number member. We also calculate th emacro's uexp_number: the parent context's exp_cnumber. This is tricky: we have to chase the previous macro context. This works if the macro is object-like, or has no parameters. If it has parameters, there is a parameter context, and so we have to climb one more flight of stairs to get to the real context. gcc/ChangeLog: * gcc/doc/cpp.texi (__EXP_COUNTER__, __UEXP_COUNTER__): Special built-in macros documented. gcc/testsuite/ChangeLog: * gcc.dg/cpp/expcounter1.c: New test. * gcc.dg/cpp/expcounter2.c: New test. * gcc.dg/cpp/expcounter3.c: New test. * gcc.dg/cpp/expcounter4.c: New test. * gcc.dg/cpp/expcounter5.c: New test. Signed-off-by: Kaz Kylheku --- gcc/doc/cpp.texi | 81 ++ gcc/testsuite/gcc.dg/cpp/expcounter1.c | 16 + gcc/testsuite/gcc.dg/cpp/expcounter2.c | 21 +++ gcc/testsuite/gcc.dg/cpp/expcounter3.c | 22 +++ gcc/testsuite/gcc.dg/cpp/expcounter4.c | 22 +++ gcc/testsuite/gcc.dg/cpp/expcounter5.c | 28 + libcpp/include/cpplib.h| 8 +++ libcpp/init.cc | 2 + libcpp/macro.cc| 44 +- 9 files changed, 242 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/cpp/expcounter1.c create mode 100644 gcc/testsuite/gcc.dg/cpp/expcounter2.c create mode 100644 gcc/testsuite/gcc.dg/cpp/expcounter3.c create mode 100644 gcc/testsuite/gcc.dg/cpp/expcounter4.c create mode 100644 gcc/testsuite/gcc.dg/cpp/expcounter5.c diff --git a/gcc/doc/cpp.texi b/gcc/doc/cpp.texi index 3de6e7aa737..a21e8b44be1 100644 --- a/gcc/doc/cpp.texi +++ b/gcc/doc/cpp.texi @@ -1942,6 +1942,87 @@ generate unique identifiers. Care must be taken to ensure that @code{__COUNTER__} is not expanded prior to inclusion of precompiled headers which use it. Otherwise, the precompiled headers will not be used. +@item __EXP_COUNTER__ +This macro's name means "(macro) expansion counter". +Outside of macro replacement sequences, it expands to the integer +token @code{1}. This make it possible to easily test for the presence +of this feature using conditional directives such as +@code{#ifdef __EXP_COUNTER__}. +When @code{__E
Re: [PATCH] cpp: new built-in __EXP_COUNTER__
On Mon, 18 Mar 2024 at 16:46, Kaz Kylheku wrote: > > On 2024-03-18 00:30, Jonathan Wakely wrote: > >>+@item __EXP_COUNTER__ > >>+This macro's name means "(macro) expansion counter". > >>+Outside of macro replacement sequences, it expands to the integer > >>+token @code{1}. This make it possible to easily test for the presence > >>+of this feature using conditional directives such as > >>+@code{#if __EXP_COUNTER__}. > > > > It's a macro, so you can just use '#ifdef __EXP_COUNTER__' to test if > > it's supported. Is this additional behaviour necessary? > > Thanks for looking at the patch. > > The macro has to be defined, but it doesn't have to be 1. > > Outside a macro body, it could just appear defined > with an empty value, as if by #define __EXP_COUNTER__. > > When I dump the predefined macros of a nearby GCC installation, I > see very few empty ones: > >$ echo | gcc -dM -E - | awk 'NF == 2' >#define __USER_LABEL_PREFIX__ >#define __REGISTER_PREFIX__ > > The __EXP_COUNTER__ and __UEXP_COUNTER__ symbols are > intended for suffix and infix use, so they are roughly in > a kind of category with those those two. I don't feel strongly about the value, it seems fine to define it as 1 too. I just thought it was a bit strange to explicitly mention testing its value to detect support, when #ifdef seems simpler and more "correct" (as in, it just checks if it's defined, and thevalue is irrelevant). > > I will make that change, and also fix the grammar error > and remove the conflict-promoting ChangeLog changes. >
Re: [PATCH] cpp: new built-in __EXP_COUNTER__
On 2024-03-18 00:30, Jonathan Wakely wrote: >>+@item __EXP_COUNTER__ >>+This macro's name means "(macro) expansion counter". >>+Outside of macro replacement sequences, it expands to the integer >>+token @code{1}. This make it possible to easily test for the presence >>+of this feature using conditional directives such as >>+@code{#if __EXP_COUNTER__}. > > It's a macro, so you can just use '#ifdef __EXP_COUNTER__' to test if > it's supported. Is this additional behaviour necessary? Thanks for looking at the patch. The macro has to be defined, but it doesn't have to be 1. Outside a macro body, it could just appear defined with an empty value, as if by #define __EXP_COUNTER__. When I dump the predefined macros of a nearby GCC installation, I see very few empty ones: $ echo | gcc -dM -E - | awk 'NF == 2' #define __USER_LABEL_PREFIX__ #define __REGISTER_PREFIX__ The __EXP_COUNTER__ and __UEXP_COUNTER__ symbols are intended for suffix and infix use, so they are roughly in a kind of category with those those two. I will make that change, and also fix the grammar error and remove the conflict-promoting ChangeLog changes.
Re: [PATCH] cpp: new built-in __EXP_COUNTER__
On 18/03/24 07:30 +, Jonathan Wakely wrote: On 21/04/22 04:31 -0700, Kaz Kylheku wrote: libcpp/ChangeLog 2022-04-21 Kaz Kylheku This change introduces a pair of related macros __EXP_COUNTER__ and __UEXP_COUNTER__. These macros access integer values which enumerate macro expansions. They can be used for the purposes of obtaining, unique identifiers (within the scope of a translation unit), as a replacement for unreliable hacks based on __LINE__. Outside of macro expansions, these macros expand to 1, so they are easy to test for in portable code that needs to fall back on something, like __LINE__. * gcc/doc/cpp.texi (__EXP_COUNTER__, __UEXP_COUNTER__): Special built-in macros documented. * libcpp/include/cpplib.h (struct cpp_macro): New members of type long long: exp_number and uexp_number. These members are used to attach the current exp_counter value, and the parent context's copy of it to a new macro expansion. The special macros then just access these. (enum cpp_builtin_type): New enumeration members, BT_EXP_COUNTER and BT_UEXP_COUNTER. * libcpp/macro.cc (exp_counter): New static variable for counting expansions. There is an existing one, num_expanded_macros_counter, but that has its own purpose and is incremented in a specific place. Plus it uses a narrower integer type. (_cpp_builtin_number_text): Change the local variable "number" from linenum_type to unsigned long long, so it holds at least 64 bit values. Handle the BT_EXP_COUNTER and BT_UEXP_COUNTER cases. These just have to see if there is a current macro, and retrieve the values from it, otherwise do nothing so that the default 1 is produced. In the case of BT_UEXP_COUNTER, if the value is zero, we don't use it, so 1 emerges. The sprintf of the number is adjusted to use the right conversion specifier for the wider type. Space is already being reserved for a 64 bit decimal. (enter_macro_context): After processing the macro arguments, if any, we increment exp_counter and attach its new value to the macro's context structure in the exp_number member. We also calculate the macro's uexp_number: the parent context's exp_number. This is tricky: we have to chase the previous macro context. This works if the macro is object-like, or has no parameters. If it has parameters, there is a parameter context, and so we have to climb one more flight of stairs to get to the real context. gcc/testsuite/ChangeLog 2022-04-21 Kaz Kylheku * gcc.dg/cpp/expcounter1.c: New test. * gcc.dg/cpp/expcounter2.c: New test. * gcc.dg/cpp/expcounter3.c: New test. * gcc.dg/cpp/expcounter4.c: New test. * gcc.dg/cpp/expcounter5.c: New test. Signed-off-by: Kaz Kylheku --- gcc/doc/cpp.texi | 81 ++ gcc/testsuite/ChangeLog| 8 +++ gcc/testsuite/gcc.dg/cpp/expcounter1.c | 16 + gcc/testsuite/gcc.dg/cpp/expcounter2.c | 21 +++ gcc/testsuite/gcc.dg/cpp/expcounter3.c | 22 +++ gcc/testsuite/gcc.dg/cpp/expcounter4.c | 22 +++ gcc/testsuite/gcc.dg/cpp/expcounter5.c | 28 + libcpp/ChangeLog | 49 libcpp/include/cpplib.h| 8 +++ libcpp/init.cc | 2 + libcpp/macro.cc| 44 +- 11 files changed, 299 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/cpp/expcounter1.c create mode 100644 gcc/testsuite/gcc.dg/cpp/expcounter2.c create mode 100644 gcc/testsuite/gcc.dg/cpp/expcounter3.c create mode 100644 gcc/testsuite/gcc.dg/cpp/expcounter4.c create mode 100644 gcc/testsuite/gcc.dg/cpp/expcounter5.c diff --git a/gcc/doc/cpp.texi b/gcc/doc/cpp.texi index 90b2767e39a..d52450958d7 100644 --- a/gcc/doc/cpp.texi +++ b/gcc/doc/cpp.texi @@ -1941,6 +1941,87 @@ generate unique identifiers. Care must be taken to ensure that @code{__COUNTER__} is not expanded prior to inclusion of precompiled headers which use it. Otherwise, the precompiled headers will not be used. +@item __EXP_COUNTER__ +This macro's name means "(macro) expansion counter". +Outside of macro replacement sequences, it expands to the integer +token @code{1}. This make it possible to easily test for the presence +of this feature using conditional directives such as +@code{#if __EXP_COUNTER__}. It's a macro, so you can just use '#ifdef __EXP_COUNTER__' to test if it's supported. Is this additional behaviour necessary? +When @code{__EXP_COUNTER__} occurs in the replacement token sequence +of a macro, it expands to positive decimal integer token which expands to _a_ positive decimal integer token? +uniquely identifies the
Re: [PATCH] cpp: new built-in __EXP_COUNTER__
On 21/04/22 04:31 -0700, Kaz Kylheku wrote: libcpp/ChangeLog 2022-04-21 Kaz Kylheku This change introduces a pair of related macros __EXP_COUNTER__ and __UEXP_COUNTER__. These macros access integer values which enumerate macro expansions. They can be used for the purposes of obtaining, unique identifiers (within the scope of a translation unit), as a replacement for unreliable hacks based on __LINE__. Outside of macro expansions, these macros expand to 1, so they are easy to test for in portable code that needs to fall back on something, like __LINE__. * gcc/doc/cpp.texi (__EXP_COUNTER__, __UEXP_COUNTER__): Special built-in macros documented. * libcpp/include/cpplib.h (struct cpp_macro): New members of type long long: exp_number and uexp_number. These members are used to attach the current exp_counter value, and the parent context's copy of it to a new macro expansion. The special macros then just access these. (enum cpp_builtin_type): New enumeration members, BT_EXP_COUNTER and BT_UEXP_COUNTER. * libcpp/macro.cc (exp_counter): New static variable for counting expansions. There is an existing one, num_expanded_macros_counter, but that has its own purpose and is incremented in a specific place. Plus it uses a narrower integer type. (_cpp_builtin_number_text): Change the local variable "number" from linenum_type to unsigned long long, so it holds at least 64 bit values. Handle the BT_EXP_COUNTER and BT_UEXP_COUNTER cases. These just have to see if there is a current macro, and retrieve the values from it, otherwise do nothing so that the default 1 is produced. In the case of BT_UEXP_COUNTER, if the value is zero, we don't use it, so 1 emerges. The sprintf of the number is adjusted to use the right conversion specifier for the wider type. Space is already being reserved for a 64 bit decimal. (enter_macro_context): After processing the macro arguments, if any, we increment exp_counter and attach its new value to the macro's context structure in the exp_number member. We also calculate the macro's uexp_number: the parent context's exp_number. This is tricky: we have to chase the previous macro context. This works if the macro is object-like, or has no parameters. If it has parameters, there is a parameter context, and so we have to climb one more flight of stairs to get to the real context. gcc/testsuite/ChangeLog 2022-04-21 Kaz Kylheku * gcc.dg/cpp/expcounter1.c: New test. * gcc.dg/cpp/expcounter2.c: New test. * gcc.dg/cpp/expcounter3.c: New test. * gcc.dg/cpp/expcounter4.c: New test. * gcc.dg/cpp/expcounter5.c: New test. Signed-off-by: Kaz Kylheku --- gcc/doc/cpp.texi | 81 ++ gcc/testsuite/ChangeLog| 8 +++ gcc/testsuite/gcc.dg/cpp/expcounter1.c | 16 + gcc/testsuite/gcc.dg/cpp/expcounter2.c | 21 +++ gcc/testsuite/gcc.dg/cpp/expcounter3.c | 22 +++ gcc/testsuite/gcc.dg/cpp/expcounter4.c | 22 +++ gcc/testsuite/gcc.dg/cpp/expcounter5.c | 28 + libcpp/ChangeLog | 49 libcpp/include/cpplib.h| 8 +++ libcpp/init.cc | 2 + libcpp/macro.cc| 44 +- 11 files changed, 299 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/cpp/expcounter1.c create mode 100644 gcc/testsuite/gcc.dg/cpp/expcounter2.c create mode 100644 gcc/testsuite/gcc.dg/cpp/expcounter3.c create mode 100644 gcc/testsuite/gcc.dg/cpp/expcounter4.c create mode 100644 gcc/testsuite/gcc.dg/cpp/expcounter5.c diff --git a/gcc/doc/cpp.texi b/gcc/doc/cpp.texi index 90b2767e39a..d52450958d7 100644 --- a/gcc/doc/cpp.texi +++ b/gcc/doc/cpp.texi @@ -1941,6 +1941,87 @@ generate unique identifiers. Care must be taken to ensure that @code{__COUNTER__} is not expanded prior to inclusion of precompiled headers which use it. Otherwise, the precompiled headers will not be used. +@item __EXP_COUNTER__ +This macro's name means "(macro) expansion counter". +Outside of macro replacement sequences, it expands to the integer +token @code{1}. This make it possible to easily test for the presence +of this feature using conditional directives such as +@code{#if __EXP_COUNTER__}. It's a macro, so you can just use '#ifdef __EXP_COUNTER__' to test if it's supported. Is this additional behaviour necessary? +When @code{__EXP_COUNTER__} occurs in the replacement token sequence +of a macro, it expands to positive decimal integer token which expands to _a_ positive decimal integer token? +uniquely identifies the expansion, within a translation unit. +Unlike
[PATCH] cpp: new built-in __EXP_COUNTER__
libcpp/ChangeLog 2022-04-21 Kaz Kylheku This change introduces a pair of related macros __EXP_COUNTER__ and __UEXP_COUNTER__. These macros access integer values which enumerate macro expansions. They can be used for the purposes of obtaining, unique identifiers (within the scope of a translation unit), as a replacement for unreliable hacks based on __LINE__. Outside of macro expansions, these macros expand to 1, so they are easy to test for in portable code that needs to fall back on something, like __LINE__. * gcc/doc/cpp.texi (__EXP_COUNTER__, __UEXP_COUNTER__): Special built-in macros documented. * libcpp/include/cpplib.h (struct cpp_macro): New members of type long long: exp_number and uexp_number. These members are used to attach the current exp_counter value, and the parent context's copy of it to a new macro expansion. The special macros then just access these. (enum cpp_builtin_type): New enumeration members, BT_EXP_COUNTER and BT_UEXP_COUNTER. * libcpp/macro.cc (exp_counter): New static variable for counting expansions. There is an existing one, num_expanded_macros_counter, but that has its own purpose and is incremented in a specific place. Plus it uses a narrower integer type. (_cpp_builtin_number_text): Change the local variable "number" from linenum_type to unsigned long long, so it holds at least 64 bit values. Handle the BT_EXP_COUNTER and BT_UEXP_COUNTER cases. These just have to see if there is a current macro, and retrieve the values from it, otherwise do nothing so that the default 1 is produced. In the case of BT_UEXP_COUNTER, if the value is zero, we don't use it, so 1 emerges. The sprintf of the number is adjusted to use the right conversion specifier for the wider type. Space is already being reserved for a 64 bit decimal. (enter_macro_context): After processing the macro arguments, if any, we increment exp_counter and attach its new value to the macro's context structure in the exp_number member. We also calculate the macro's uexp_number: the parent context's exp_number. This is tricky: we have to chase the previous macro context. This works if the macro is object-like, or has no parameters. If it has parameters, there is a parameter context, and so we have to climb one more flight of stairs to get to the real context. gcc/testsuite/ChangeLog 2022-04-21 Kaz Kylheku * gcc.dg/cpp/expcounter1.c: New test. * gcc.dg/cpp/expcounter2.c: New test. * gcc.dg/cpp/expcounter3.c: New test. * gcc.dg/cpp/expcounter4.c: New test. * gcc.dg/cpp/expcounter5.c: New test. Signed-off-by: Kaz Kylheku --- gcc/doc/cpp.texi | 81 ++ gcc/testsuite/ChangeLog| 8 +++ gcc/testsuite/gcc.dg/cpp/expcounter1.c | 16 + gcc/testsuite/gcc.dg/cpp/expcounter2.c | 21 +++ gcc/testsuite/gcc.dg/cpp/expcounter3.c | 22 +++ gcc/testsuite/gcc.dg/cpp/expcounter4.c | 22 +++ gcc/testsuite/gcc.dg/cpp/expcounter5.c | 28 + libcpp/ChangeLog | 49 libcpp/include/cpplib.h| 8 +++ libcpp/init.cc | 2 + libcpp/macro.cc| 44 +- 11 files changed, 299 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/cpp/expcounter1.c create mode 100644 gcc/testsuite/gcc.dg/cpp/expcounter2.c create mode 100644 gcc/testsuite/gcc.dg/cpp/expcounter3.c create mode 100644 gcc/testsuite/gcc.dg/cpp/expcounter4.c create mode 100644 gcc/testsuite/gcc.dg/cpp/expcounter5.c diff --git a/gcc/doc/cpp.texi b/gcc/doc/cpp.texi index 90b2767e39a..d52450958d7 100644 --- a/gcc/doc/cpp.texi +++ b/gcc/doc/cpp.texi @@ -1941,6 +1941,87 @@ generate unique identifiers. Care must be taken to ensure that @code{__COUNTER__} is not expanded prior to inclusion of precompiled headers which use it. Otherwise, the precompiled headers will not be used. +@item __EXP_COUNTER__ +This macro's name means "(macro) expansion counter". +Outside of macro replacement sequences, it expands to the integer +token @code{1}. This make it possible to easily test for the presence +of this feature using conditional directives such as +@code{#if __EXP_COUNTER__}. +When @code{__EXP_COUNTER__} occurs in the replacement token sequence +of a macro, it expands to positive decimal integer token which +uniquely identifies the expansion, within a translation unit. +Unlike @code{__COUNTER__}, @code{__EXP_COUNTER__} does not increment +on each access: all references to it which occur in the same token +replacement sequence of the same instance of a macro being expanded +produce the