--- /dev/null
+/* Origin PR preprocessor/64803
+
+ This test ensures that the value the __LINE__ macro expands to is
+ constant and corresponds to the line of the closing parenthesis of
+ the top-most function-like macro expansion it's part of.
+
+ { dg-do run }
+ { do-options -no-integrated-cpp } */
+
+#include <assert.h>
+
+#define C(a, b) a ## b
+#define L(x) C(L, x)
+#define M(a) int L(__LINE__) = __LINE__; assert(L(__LINE__) == __LINE__);
+
+int
+main()
+{
+ M(a
+ );
+
+ assert(L20 == 20); /* 20 is the line number of the
+ closing parenthesis of the
+ invocation of the M macro. Please
+ adjust in case the layout of this
+ file changes. */
+ return 0;
+}
+2015-02-03 <dodji@redhat.com>
+
+ PR preprocessor/64803
+ * internal.h (cpp_reader::top_most_macro_node): New data member.
+ * macro.c (enter_macro_context): Pass the location of the end of
+ the top-most invocation of the function-like macro, or the
+ location of the expansion point of the top-most object-like macro.
+ (cpp_get_token_1): Store the top-most macro node in the new
+ pfile->top_most_macro_node data member.
+ (_cpp_pop_context): Clear the new cpp_reader::top_most_macro_node
+ data member.
+
2015-01-30 Szabolcs Nagy <szabolcs.nagy@arm.com>
* lex.c (search_line_fast): Change __ARM_NEON__ to __ARM_NEON.
macro invocation. */
source_location invocation_location;
+ /* This is the node representing the macro being expanded at
+ top-level. The value of this data member is valid iff
+ in_macro_expansion_p() returns TRUE. */
+ cpp_hashnode *top_most_macro_node;
+
/* Nonzero if we are about to expand a macro. Note that if we are
really expanding a macro, the function macro_of_context returns
the macro being expanded and this flag is set to false. Client
pfile->about_to_expand_macro_p = false;
/* Handle built-in macros and the _Pragma operator. */
- return builtin_macro (pfile, node, location);
+ {
+ source_location loc;
+ if (/* The top-level macro invocation that triggered the expansion
+ we are looking at is with a standard macro ...*/
+ !(pfile->top_most_macro_node->flags & NODE_BUILTIN)
+ /* ... and it's a function-like macro invocation. */
+ && pfile->top_most_macro_node->value.macro->fun_like)
+ /* Then the location of the end of the macro invocation is the
+ location of the closing parenthesis. */
+ loc = pfile->cur_token[-1].src_loc;
+ else
+ /* Otherwise, the location of the end of the macro invocation is
+ the location of the expansion point of that top-level macro
+ invocation. */
+ loc = location;
+
+ return builtin_macro (pfile, node, loc);
+ }
}
/* De-allocate the memory used by BUFF which is an array of instances
macro expansion. */
&& macro_of_context (context->prev) != macro)
macro->flags &= ~NODE_DISABLED;
+
+ if (macro == pfile->top_most_macro_node && context->prev == NULL)
+ /* We are popping the context of the top-most macro node. */
+ pfile->top_most_macro_node = NULL;
}
if (context->buff)
{
int ret = 0;
/* If not in a macro context, and we're going to start an
- expansion, record the location. */
+ expansion, record the location and the top level macro
+ about to be expanded. */
if (!in_macro_expansion_p (pfile))
- pfile->invocation_location = result->src_loc;
+ {
+ pfile->invocation_location = result->src_loc;
+ pfile->top_most_macro_node = node;
+ }
if (pfile->state.prevent_expansion)
break;