summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNico Weber <nicolasweber@gmx.de>2019-02-14 04:13:17 +0000
committerNico Weber <nicolasweber@gmx.de>2019-02-14 04:13:17 +0000
commit5773155aa1b1e219b140ecdb61f207581211edbf (patch)
tree609e1652b8d6beb16940da8dd9b615d9023ef060
parentc17fda9295b4e1e4a16cc5eb73b23cd668b29eba (diff)
downloadclang-5773155aa1b1e219b140ecdb61f207581211edbf.tar.gz
Print a note to the called macro when diagnosing err_embedded_directive
Fixes PR40713, see there for the motivation for this. Differential Revision: https://reviews.llvm.org/D58161 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@354009 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/Basic/DiagnosticLexKinds.td1
-rw-r--r--include/clang/Lex/Preprocessor.h3
-rw-r--r--lib/Lex/PPDirectives.cpp2
-rw-r--r--lib/Lex/PPMacroExpansion.cpp3
-rw-r--r--lib/Lex/Preprocessor.cpp1
-rw-r--r--test/Preprocessor/macro_arg_directive.c4
6 files changed, 12 insertions, 2 deletions
diff --git a/include/clang/Basic/DiagnosticLexKinds.td b/include/clang/Basic/DiagnosticLexKinds.td
index bb85bed94d..da73e62c9d 100644
--- a/include/clang/Basic/DiagnosticLexKinds.td
+++ b/include/clang/Basic/DiagnosticLexKinds.td
@@ -391,6 +391,7 @@ def warn_cxx98_compat_empty_fnmacro_arg : Warning<
"empty macro arguments are incompatible with C++98">,
InGroup<CXX98CompatPedantic>, DefaultIgnore;
def note_macro_here : Note<"macro %0 defined here">;
+def note_macro_expansion_here : Note<"expansion of macro %0 requested here">;
def err_pp_opencl_variadic_macros :
Error<"variadic macros not supported in OpenCL">;
diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h
index e701f14695..29d4250490 100644
--- a/include/clang/Lex/Preprocessor.h
+++ b/include/clang/Lex/Preprocessor.h
@@ -173,6 +173,9 @@ class Preprocessor {
IdentifierInfo *Ident__is_target_os; // __is_target_os
IdentifierInfo *Ident__is_target_environment; // __is_target_environment
+ // Weak, only valid (and set) while InMacroArgs is true.
+ Token* ArgMacro;
+
SourceLocation DATELoc, TIMELoc;
// Next __COUNTER__ value, starts at 0.
diff --git a/lib/Lex/PPDirectives.cpp b/lib/Lex/PPDirectives.cpp
index 5e97d9fb45..3950174529 100644
--- a/lib/Lex/PPDirectives.cpp
+++ b/lib/Lex/PPDirectives.cpp
@@ -886,6 +886,8 @@ void Preprocessor::HandleDirective(Token &Result) {
case tok::pp___include_macros:
case tok::pp_pragma:
Diag(Result, diag::err_embedded_directive) << II->getName();
+ Diag(*ArgMacro, diag::note_macro_expansion_here)
+ << ArgMacro->getIdentifierInfo();
DiscardUntilEndOfDirective();
return;
default:
diff --git a/lib/Lex/PPMacroExpansion.cpp b/lib/Lex/PPMacroExpansion.cpp
index 2e9c686b2a..f33a9a2a9d 100644
--- a/lib/Lex/PPMacroExpansion.cpp
+++ b/lib/Lex/PPMacroExpansion.cpp
@@ -492,10 +492,13 @@ bool Preprocessor::HandleMacroExpandedIdentifier(Token &Identifier,
// Preprocessor directives used inside macro arguments are not portable, and
// this enables the warning.
InMacroArgs = true;
+ ArgMacro = &Identifier;
+
Args = ReadMacroCallArgumentList(Identifier, MI, ExpansionEnd);
// Finished parsing args.
InMacroArgs = false;
+ ArgMacro = nullptr;
// If there was an error parsing the arguments, bail out.
if (!Args) return true;
diff --git a/lib/Lex/Preprocessor.cpp b/lib/Lex/Preprocessor.cpp
index 95193147b1..577abc1086 100644
--- a/lib/Lex/Preprocessor.cpp
+++ b/lib/Lex/Preprocessor.cpp
@@ -102,6 +102,7 @@ Preprocessor::Preprocessor(std::shared_ptr<PreprocessorOptions> PPOpts,
DisableMacroExpansion = false;
MacroExpansionInDirectivesOverride = false;
InMacroArgs = false;
+ ArgMacro = nullptr;
InMacroArgPreExpansion = false;
NumCachedTokenLexers = 0;
PragmasEnabled = true;
diff --git a/test/Preprocessor/macro_arg_directive.c b/test/Preprocessor/macro_arg_directive.c
index 21d1b20acf..929a03d70d 100644
--- a/test/Preprocessor/macro_arg_directive.c
+++ b/test/Preprocessor/macro_arg_directive.c
@@ -8,7 +8,7 @@ a(n =
_Static_assert(n == 5, "");
#define M(A)
-M(
+M( // expected-note {{expansion of macro 'M' requested here}}
#pragma pack(pop) // expected-error {{embedding a #pragma directive within macro arguments is not supported}}
)
@@ -18,7 +18,7 @@ void fail(const char *);
({ int result = 0; __VA_ARGS__; if (!result) { fail(#__VA_ARGS__); }; result })
static inline int f(int k) {
- return MUNCH( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{returning 'void'}}
+ return MUNCH( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{returning 'void'}} expected-note {{expansion of macro 'MUNCH' requested here}}
if (k < 3)
result = 24;
else if (k > 4)