Re: [PATCH] cpp: new built-in __EXP_COUNTER__

2024-03-22 Thread Kaz Kylheku
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__

2024-03-21 Thread Andrew Pinski
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__

2024-03-21 Thread Kaz Kylheku
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__

2024-03-20 Thread rep . dot . nop
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__

2024-03-19 Thread Kaz Kylheku
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__

2024-03-18 Thread Jonathan Wakely
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__

2024-03-18 Thread Kaz Kylheku
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__

2024-03-18 Thread Jonathan Wakely

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__

2024-03-18 Thread Jonathan Wakely

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__

2022-04-21 Thread Kaz Kylheku via Gcc-patches

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