https://github.com/StarOne01 updated 
https://github.com/llvm/llvm-project/pull/123495

>From ea6c9ca9cffbf4327fc7bab85e37e2a3c2c0f0cd Mon Sep 17 00:00:00 2001
From: Prashanth <thestaron...@proton.me>
Date: Sun, 19 Jan 2025 07:28:24 +0530
Subject: [PATCH 01/11] [clang][Sema] Add diagnostic note for function-like
 macros requiring parentheses

---
 clang/include/clang/Basic/DiagnosticSemaKinds.td |  2 ++
 clang/lib/Sema/SemaExpr.cpp                      | 15 ++++++++++++++-
 2 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index bcae9e9f30093..d9c8fcc66acf2 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -5961,6 +5961,8 @@ def err_fold_expression_limit_exceeded: Error<
   "instantiating fold expression with %0 arguments exceeded expression nesting 
"
   "limit of %1">, DefaultFatal, NoSFINAE;
 
+def note_function_like_macro_requires_parens : Note<
+  "'%0' exists, but as a function-like macro; perhaps, did you forget the 
parentheses?">;
 def err_unexpected_typedef : Error<
   "unexpected type name %0: expected expression">;
 def err_unexpected_namespace : Error<
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 3cd4010740d19..dff03ac31ef2a 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -2522,6 +2522,19 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec 
&SS, LookupResult &R,
     DC = DC->getLookupParent();
   }
 
+  // Check whether a similar function-like macro exists and suggest it
+  if (IdentifierInfo *II = Name.getAsIdentifierInfo()) {
+    if (II->hasMacroDefinition()) {
+      MacroInfo *MI = PP.getMacroInfo(II);
+      if (MI && MI->isFunctionLike()) {
+        Diag( R.getNameLoc() ,diag::err_undeclared_var_use) << II->getName();
+        Diag(MI->getDefinitionLoc(), 
diag::note_function_like_macro_requires_parens)
+            << II->getName();
+        return true;
+      }
+    }
+  }
+
   // We didn't find anything, so try to correct for a typo.
   TypoCorrection Corrected;
   if (S && Out) {
@@ -2632,7 +2645,7 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec 
&SS, LookupResult &R,
       << SS.getRange();
     return true;
   }
-
+  
   // Give up, we can't recover.
   Diag(R.getNameLoc(), diagnostic) << Name;
   return true;

>From c274178a0ce3a510eaaa9390b277b860bcc5a2a9 Mon Sep 17 00:00:00 2001
From: Prashanth <thestaron...@proton.me>
Date: Sun, 19 Jan 2025 08:30:39 +0530
Subject: [PATCH 02/11] [clang][Tests] Modify tests for function-like macros
 according to the new behavior and Format the changes

---
 clang/include/clang/Basic/DiagnosticSemaKinds.td        | 5 +++--
 clang/lib/Sema/SemaExpr.cpp                             | 7 ++++---
 clang/test/Preprocessor/macro_with_initializer_list.cpp | 6 ++++--
 3 files changed, 11 insertions(+), 7 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index d9c8fcc66acf2..697b92d325240 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -5961,8 +5961,9 @@ def err_fold_expression_limit_exceeded: Error<
   "instantiating fold expression with %0 arguments exceeded expression nesting 
"
   "limit of %1">, DefaultFatal, NoSFINAE;
 
-def note_function_like_macro_requires_parens : Note<
-  "'%0' exists, but as a function-like macro; perhaps, did you forget the 
parentheses?">;
+def note_function_like_macro_requires_parens
+    : Note<"'%0' exists, but as a function-like macro; perhaps, did you forget 
"
+           "the parentheses?">;
 def err_unexpected_typedef : Error<
   "unexpected type name %0: expected expression">;
 def err_unexpected_namespace : Error<
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index dff03ac31ef2a..da894dd3a6d6a 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -2527,8 +2527,9 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec 
&SS, LookupResult &R,
     if (II->hasMacroDefinition()) {
       MacroInfo *MI = PP.getMacroInfo(II);
       if (MI && MI->isFunctionLike()) {
-        Diag( R.getNameLoc() ,diag::err_undeclared_var_use) << II->getName();
-        Diag(MI->getDefinitionLoc(), 
diag::note_function_like_macro_requires_parens)
+        Diag(R.getNameLoc(), diag::err_undeclared_var_use) << II->getName();
+        Diag(MI->getDefinitionLoc(),
+             diag::note_function_like_macro_requires_parens)
             << II->getName();
         return true;
       }
@@ -2645,7 +2646,7 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec 
&SS, LookupResult &R,
       << SS.getRange();
     return true;
   }
-  
+
   // Give up, we can't recover.
   Diag(R.getNameLoc(), diagnostic) << Name;
   return true;
diff --git a/clang/test/Preprocessor/macro_with_initializer_list.cpp 
b/clang/test/Preprocessor/macro_with_initializer_list.cpp
index 40f53164b263d..cc7dae0b5a3e0 100644
--- a/clang/test/Preprocessor/macro_with_initializer_list.cpp
+++ b/clang/test/Preprocessor/macro_with_initializer_list.cpp
@@ -134,6 +134,7 @@ void test_NE() {
 // CHECK: fix-it:"{{.*}}macro_with_initializer_list.cpp":{110:32-110:32}:")"
 
 #define INIT(var, init) Foo var = init; // expected-note 3{{defined here}}
+// expected-note@-1 2{{'INIT' exists, but as a function-like macro; perhaps, 
did you forget the parentheses?}}
 // Can't use an initializer list as a macro argument.  The commas in the list
 // will be interpretted as argument separaters and adding parenthesis will
 // make it no longer an initializer list.
@@ -159,12 +160,13 @@ void test() {
   // expected-note@-3 {{cannot use initializer list at the beginning of a 
macro argument}}
 }
 
-// CHECK: fix-it:"{{.*}}macro_with_initializer_list.cpp":{145:11-145:11}:"("
-// CHECK: fix-it:"{{.*}}macro_with_initializer_list.cpp":{145:23-145:23}:")"
+// CHECK: fix-it:"{{.*}}macro_with_initializer_list.cpp":{146:11-146:11}:"("
+// CHECK: fix-it:"{{.*}}macro_with_initializer_list.cpp":{146:23-146:23}:")"
 
 #define M(name,a,b,c,d,e,f,g,h,i,j,k,l) \
   Foo name = a + b + c + d + e + f + g + h + i + j + k + l;
 // expected-note@-2 2{{defined here}}
+// expected-note@-3 {{'M' exists, but as a function-like macro; perhaps, did 
you forget the parentheses?}}
 void test2() {
   M(F1, Foo(), Foo(), Foo(), Foo(), Foo(), Foo(),
         Foo(), Foo(), Foo(), Foo(), Foo(), Foo());

>From 33e001ee6e852f630fd1b69bea424c6e7166078b Mon Sep 17 00:00:00 2001
From: Prashanth <thestaron...@proton.me>
Date: Mon, 20 Jan 2025 13:34:48 +0530
Subject: [PATCH 03/11] Change the note for reference of function-like macros
 requiring without parentheses

Co-authored-by: Sirraide <aeternalm...@gmail.com>
---
 clang/include/clang/Basic/DiagnosticSemaKinds.td | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 697b92d325240..6d3a065077d4b 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -5962,8 +5962,7 @@ def err_fold_expression_limit_exceeded: Error<
   "limit of %1">, DefaultFatal, NoSFINAE;
 
 def note_function_like_macro_requires_parens
-    : Note<"'%0' exists, but as a function-like macro; perhaps, did you forget 
"
-           "the parentheses?">;
+    : Note<"'%0' is defined here as a function-like macro; did you mean to 
write '%0(...)'">;
 def err_unexpected_typedef : Error<
   "unexpected type name %0: expected expression">;
 def err_unexpected_namespace : Error<

>From 5aa4654ffe3f7499faf6f8abc7dbdf3468a8dcb9 Mon Sep 17 00:00:00 2001
From: Prashanth <thestaron...@proton.me>
Date: Tue, 21 Jan 2025 16:20:10 +0530
Subject: [PATCH 04/11] [clang][Tests] Update diagnostic tests for
 function-like macros to clarify usage and improve error messages

---
 .../Preprocessor/macro_with_initializer_list.cpp   | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/clang/test/Preprocessor/macro_with_initializer_list.cpp 
b/clang/test/Preprocessor/macro_with_initializer_list.cpp
index cc7dae0b5a3e0..f7f645cce1180 100644
--- a/clang/test/Preprocessor/macro_with_initializer_list.cpp
+++ b/clang/test/Preprocessor/macro_with_initializer_list.cpp
@@ -133,8 +133,8 @@ void test_NE() {
 // CHECK: fix-it:"{{.*}}macro_with_initializer_list.cpp":{110:9-110:9}:"("
 // CHECK: fix-it:"{{.*}}macro_with_initializer_list.cpp":{110:32-110:32}:")"
 
-#define INIT(var, init) Foo var = init; // expected-note 3{{defined here}}
-// expected-note@-1 2{{'INIT' exists, but as a function-like macro; perhaps, 
did you forget the parentheses?}}
+#define INIT(var, init) Foo var = init; // expected-note 3{{macro 'INIT' 
defined here}}
+// expected-note@-1 2{{'INIT' is defined here as a function-like macro; did 
you mean to write 'INIT(...)'}}
 // Can't use an initializer list as a macro argument.  The commas in the list
 // will be interpretted as argument separaters and adding parenthesis will
 // make it no longer an initializer list.
@@ -166,7 +166,7 @@ void test() {
 #define M(name,a,b,c,d,e,f,g,h,i,j,k,l) \
   Foo name = a + b + c + d + e + f + g + h + i + j + k + l;
 // expected-note@-2 2{{defined here}}
-// expected-note@-3 {{'M' exists, but as a function-like macro; perhaps, did 
you forget the parentheses?}}
+// expected-note@-3 {{'M' is defined here as a function-like macro; did you 
mean to write 'M(...)'}}
 void test2() {
   M(F1, Foo(), Foo(), Foo(), Foo(), Foo(), Foo(),
         Foo(), Foo(), Foo(), Foo(), Foo(), Foo());
@@ -182,3 +182,11 @@ void test2() {
   // expected-error@-3 {{use of undeclared identifier}}
   // expected-note@-4 {{cannot use initializer list at the beginning of a 
macro argument}}
 }
+
+#define LIM() 10 
+// expected-note@-1 {{'LIM' is defined here as a function-like macro; did you 
mean to write 'LIM(...)'}}
+
+void test3() {
+  int iter = LIM;
+  // expected-error@-1 {{use of undeclared identifier LIM}}
+}
\ No newline at end of file

>From bd0848786ffb70e6f06b2b93b1b2fae46478484c Mon Sep 17 00:00:00 2001
From: Prashanth <thestaron...@proton.me>
Date: Tue, 21 Jan 2025 16:22:39 +0530
Subject: [PATCH 05/11] Change the note for reference of function-like macros
 requiring without parentheses

Co-authored-by: Mariya Podchishchaeva <mariya.podchishcha...@intel.com>
---
 clang/include/clang/Basic/DiagnosticSemaKinds.td | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 6d3a065077d4b..34ed18e518773 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -5962,7 +5962,7 @@ def err_fold_expression_limit_exceeded: Error<
   "limit of %1">, DefaultFatal, NoSFINAE;
 
 def note_function_like_macro_requires_parens
-    : Note<"'%0' is defined here as a function-like macro; did you mean to 
write '%0(...)'">;
+    : Note<"'%0' is defined here as a function-like macro; did you mean 
'%0(...)'">;
 def err_unexpected_typedef : Error<
   "unexpected type name %0: expected expression">;
 def err_unexpected_namespace : Error<

>From 6ef338ab4c2dd123397327fb3de7f1057643fa49 Mon Sep 17 00:00:00 2001
From: Prashanth <thestaron...@proton.me>
Date: Tue, 21 Jan 2025 17:03:21 +0530
Subject: [PATCH 06/11] [clang][Tests] Update diagnostic tests for
 function-like macros for the updated note

---
 clang/test/Preprocessor/macro_with_initializer_list.cpp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/clang/test/Preprocessor/macro_with_initializer_list.cpp 
b/clang/test/Preprocessor/macro_with_initializer_list.cpp
index f7f645cce1180..cf1d137eadcbe 100644
--- a/clang/test/Preprocessor/macro_with_initializer_list.cpp
+++ b/clang/test/Preprocessor/macro_with_initializer_list.cpp
@@ -134,7 +134,7 @@ void test_NE() {
 // CHECK: fix-it:"{{.*}}macro_with_initializer_list.cpp":{110:32-110:32}:")"
 
 #define INIT(var, init) Foo var = init; // expected-note 3{{macro 'INIT' 
defined here}}
-// expected-note@-1 2{{'INIT' is defined here as a function-like macro; did 
you mean to write 'INIT(...)'}}
+// expected-note@-1 2{{'INIT' is defined here as a function-like macro; did 
you mean 'INIT(...)'}}
 // Can't use an initializer list as a macro argument.  The commas in the list
 // will be interpretted as argument separaters and adding parenthesis will
 // make it no longer an initializer list.
@@ -166,7 +166,7 @@ void test() {
 #define M(name,a,b,c,d,e,f,g,h,i,j,k,l) \
   Foo name = a + b + c + d + e + f + g + h + i + j + k + l;
 // expected-note@-2 2{{defined here}}
-// expected-note@-3 {{'M' is defined here as a function-like macro; did you 
mean to write 'M(...)'}}
+// expected-note@-3 {{'M' is defined here as a function-like macro; did you 
mean 'M(...)'}}
 void test2() {
   M(F1, Foo(), Foo(), Foo(), Foo(), Foo(), Foo(),
         Foo(), Foo(), Foo(), Foo(), Foo(), Foo());
@@ -184,7 +184,7 @@ void test2() {
 }
 
 #define LIM() 10 
-// expected-note@-1 {{'LIM' is defined here as a function-like macro; did you 
mean to write 'LIM(...)'}}
+// expected-note@-1 {{'LIM' is defined here as a function-like macro; did you 
mean 'LIM(...)'}}
 
 void test3() {
   int iter = LIM;

>From 094887dbe3a521ad4733cd37cbfb5313bbb0dc4e Mon Sep 17 00:00:00 2001
From: Prashanth <thestaron...@proton.me>
Date: Sun, 9 Feb 2025 14:20:36 +0530
Subject: [PATCH 07/11] [clang][Sema] Improve diagnostics for undeclared
 function-like macros

---
 .../clang/Basic/DiagnosticSemaKinds.td        |  4 +-
 clang/lib/Sema/SemaExpr.cpp                   | 43 ++++++++++++-------
 .../macro_with_initializer_list.cpp           | 14 +-----
 clang/test/Sema/typo-correction.c             | 22 ++++++++++
 4 files changed, 55 insertions(+), 28 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 34ed18e518773..33a3bfe4ff646 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -5962,7 +5962,7 @@ def err_fold_expression_limit_exceeded: Error<
   "limit of %1">, DefaultFatal, NoSFINAE;
 
 def note_function_like_macro_requires_parens
-    : Note<"'%0' is defined here as a function-like macro; did you mean 
'%0(...)'">;
+    : Note<"'%0' defined here as a function-like macro">;
 def err_unexpected_typedef : Error<
   "unexpected type name %0: expected expression">;
 def err_unexpected_namespace : Error<
@@ -10857,6 +10857,8 @@ def err_undeclared_use_suggest : Error<
   "use of undeclared %0; did you mean %1?">;
 def err_undeclared_var_use_suggest : Error<
   "use of undeclared identifier %0; did you mean %1?">;
+def err_undeclared_var_use_suggest_func_like_macro
+    : Error<"use of undeclared identifier %0; did you mean %0(...)?">;
 def err_no_template : Error<"no template named %0">;
 def err_no_template_suggest : Error<"no template named %0; did you mean %1?">;
 def err_no_member_template : Error<"no template named %0 in %1">;
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index da894dd3a6d6a..27c2cf65762e3 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -2347,6 +2347,27 @@ Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty, 
ExprValueKind VK,
   return E;
 }
 
+// Check whether a similar function-like macro exists and suggest it
+static bool isFunctionLikeMacro(const DeclarationName &Name, Sema &SemaRef,
+                                const SourceLocation &TypoLoc) {
+
+  if (IdentifierInfo *II = Name.getAsIdentifierInfo()) {
+    if (II->hasMacroDefinition()) {
+      MacroInfo *MI = SemaRef.PP.getMacroInfo(II);
+      if (MI && MI->isFunctionLike()) {
+        SemaRef.Diag(TypoLoc,
+                     diag::err_undeclared_var_use_suggest_func_like_macro)
+            << II->getName();
+        SemaRef.Diag(MI->getDefinitionLoc(),
+                     diag::note_function_like_macro_requires_parens)
+            << II->getName();
+        return true;
+      }
+    }
+  }
+  return false;
+}
+
 void
 Sema::DecomposeUnqualifiedId(const UnqualifiedId &Id,
                              TemplateArgumentListInfo &Buffer,
@@ -2382,8 +2403,11 @@ static void emitEmptyLookupTypoDiagnostic(
     if (Ctx)
       SemaRef.Diag(TypoLoc, diag::err_no_member) << Typo << Ctx
                                                  << SS.getRange();
-    else
+    else {
+      if (isFunctionLikeMacro(Typo, SemaRef, TypoLoc))
+        return;
       SemaRef.Diag(TypoLoc, DiagnosticID) << Typo;
+    }
     return;
   }
 
@@ -2522,20 +2546,6 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec 
&SS, LookupResult &R,
     DC = DC->getLookupParent();
   }
 
-  // Check whether a similar function-like macro exists and suggest it
-  if (IdentifierInfo *II = Name.getAsIdentifierInfo()) {
-    if (II->hasMacroDefinition()) {
-      MacroInfo *MI = PP.getMacroInfo(II);
-      if (MI && MI->isFunctionLike()) {
-        Diag(R.getNameLoc(), diag::err_undeclared_var_use) << II->getName();
-        Diag(MI->getDefinitionLoc(),
-             diag::note_function_like_macro_requires_parens)
-            << II->getName();
-        return true;
-      }
-    }
-  }
-
   // We didn't find anything, so try to correct for a typo.
   TypoCorrection Corrected;
   if (S && Out) {
@@ -2638,6 +2648,9 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec 
&SS, LookupResult &R,
   }
   R.clear();
 
+  if (isFunctionLikeMacro(Name, SemaRef, R.getNameLoc()))
+    return true;
+
   // Emit a special diagnostic for failed member lookups.
   // FIXME: computing the declaration context might fail here (?)
   if (!SS.isEmpty()) {
diff --git a/clang/test/Preprocessor/macro_with_initializer_list.cpp 
b/clang/test/Preprocessor/macro_with_initializer_list.cpp
index cf1d137eadcbe..5f66971622ce7 100644
--- a/clang/test/Preprocessor/macro_with_initializer_list.cpp
+++ b/clang/test/Preprocessor/macro_with_initializer_list.cpp
@@ -134,7 +134,6 @@ void test_NE() {
 // CHECK: fix-it:"{{.*}}macro_with_initializer_list.cpp":{110:32-110:32}:")"
 
 #define INIT(var, init) Foo var = init; // expected-note 3{{macro 'INIT' 
defined here}}
-// expected-note@-1 2{{'INIT' is defined here as a function-like macro; did 
you mean 'INIT(...)'}}
 // Can't use an initializer list as a macro argument.  The commas in the list
 // will be interpretted as argument separaters and adding parenthesis will
 // make it no longer an initializer list.
@@ -160,13 +159,12 @@ void test() {
   // expected-note@-3 {{cannot use initializer list at the beginning of a 
macro argument}}
 }
 
-// CHECK: fix-it:"{{.*}}macro_with_initializer_list.cpp":{146:11-146:11}:"("
-// CHECK: fix-it:"{{.*}}macro_with_initializer_list.cpp":{146:23-146:23}:")"
+// CHECK: fix-it:"{{.*}}macro_with_initializer_list.cpp":{145:11-145:11}:"("
+// CHECK: fix-it:"{{.*}}macro_with_initializer_list.cpp":{145:23-145:23}:")"
 
 #define M(name,a,b,c,d,e,f,g,h,i,j,k,l) \
   Foo name = a + b + c + d + e + f + g + h + i + j + k + l;
 // expected-note@-2 2{{defined here}}
-// expected-note@-3 {{'M' is defined here as a function-like macro; did you 
mean 'M(...)'}}
 void test2() {
   M(F1, Foo(), Foo(), Foo(), Foo(), Foo(), Foo(),
         Foo(), Foo(), Foo(), Foo(), Foo(), Foo());
@@ -181,12 +179,4 @@ void test2() {
   // expected-error@-2 {{too many arguments provided}}
   // expected-error@-3 {{use of undeclared identifier}}
   // expected-note@-4 {{cannot use initializer list at the beginning of a 
macro argument}}
-}
-
-#define LIM() 10 
-// expected-note@-1 {{'LIM' is defined here as a function-like macro; did you 
mean 'LIM(...)'}}
-
-void test3() {
-  int iter = LIM;
-  // expected-error@-1 {{use of undeclared identifier LIM}}
 }
\ No newline at end of file
diff --git a/clang/test/Sema/typo-correction.c 
b/clang/test/Sema/typo-correction.c
index 4157207a9ac42..3efd35538dd58 100644
--- a/clang/test/Sema/typo-correction.c
+++ b/clang/test/Sema/typo-correction.c
@@ -114,3 +114,25 @@ void PR40286_3(int the_value) {
 void PR40286_4(int the_value) { // expected-note {{'the_value' declared here}}
   PR40286_h(the_value, the_value, the_walue); // expected-error {{use of 
undeclared identifier 'the_walue'; did you mean 'the_value'?}}
 }
+
+#define FOO1() 10
+// expected-note@-1 4 {{'FOO1' defined here as a function-like macro}}
+
+int x = FOO1; // expected-error {{use of undeclared identifier FOO1; did you 
mean FOO1(...)?}}
+
+void test3() {
+  int iter = FOO1;
+  // expected-error@-1 {{use of undeclared identifier FOO1; did you mean 
FOO1(...)?}}
+}
+
+void bar(int);
+
+void test4() {
+    int FOO; // expected-note {{'FOO' declared here}}
+    int x = FOO1; // expected-error {{use of undeclared identifier 'FOO1'; did 
you mean 'FOO'?}}
+}
+
+void test5() {
+    FOO1 + 1; // expected-error {{use of undeclared identifier FOO1; did you 
mean FOO1(...)?}}
+    bar(FOO1); // expected-error {{use of undeclared identifier FOO1; did you 
mean FOO1(...)?}}
+}

>From eac145ae3c3de06573cc7cbef40fe5436606e089 Mon Sep 17 00:00:00 2001
From: Prashanth <thestaron...@proton.me>
Date: Sun, 9 Feb 2025 14:50:49 +0530
Subject: [PATCH 08/11] [clang][Tests] Enhance diagnostic notes for
 function-like macros in initializer list tests

---
 clang/test/Preprocessor/macro_with_initializer_list.cpp | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/clang/test/Preprocessor/macro_with_initializer_list.cpp 
b/clang/test/Preprocessor/macro_with_initializer_list.cpp
index 5f66971622ce7..dab60e60b14a1 100644
--- a/clang/test/Preprocessor/macro_with_initializer_list.cpp
+++ b/clang/test/Preprocessor/macro_with_initializer_list.cpp
@@ -134,6 +134,7 @@ void test_NE() {
 // CHECK: fix-it:"{{.*}}macro_with_initializer_list.cpp":{110:32-110:32}:")"
 
 #define INIT(var, init) Foo var = init; // expected-note 3{{macro 'INIT' 
defined here}}
+// expected-note@-1 2{{'INIT' defined here as a function-like macro}}
 // Can't use an initializer list as a macro argument.  The commas in the list
 // will be interpretted as argument separaters and adding parenthesis will
 // make it no longer an initializer list.
@@ -159,12 +160,13 @@ void test() {
   // expected-note@-3 {{cannot use initializer list at the beginning of a 
macro argument}}
 }
 
-// CHECK: fix-it:"{{.*}}macro_with_initializer_list.cpp":{145:11-145:11}:"("
-// CHECK: fix-it:"{{.*}}macro_with_initializer_list.cpp":{145:23-145:23}:")"
+// CHECK: fix-it:"{{.*}}macro_with_initializer_list.cpp":{146:11-146:11}:"("
+// CHECK: fix-it:"{{.*}}macro_with_initializer_list.cpp":{146:23-146:23}:")"
 
 #define M(name,a,b,c,d,e,f,g,h,i,j,k,l) \
   Foo name = a + b + c + d + e + f + g + h + i + j + k + l;
 // expected-note@-2 2{{defined here}}
+// expected-note@-3 {{'M' defined here as a function-like macro}}
 void test2() {
   M(F1, Foo(), Foo(), Foo(), Foo(), Foo(), Foo(),
         Foo(), Foo(), Foo(), Foo(), Foo(), Foo());
@@ -179,4 +181,4 @@ void test2() {
   // expected-error@-2 {{too many arguments provided}}
   // expected-error@-3 {{use of undeclared identifier}}
   // expected-note@-4 {{cannot use initializer list at the beginning of a 
macro argument}}
-}
\ No newline at end of file
+}

>From e7404fb8509f7b2e80782cea27986ee610b69b20 Mon Sep 17 00:00:00 2001
From: Prashanth <thestaron...@proton.me>
Date: Sun, 9 Feb 2025 20:28:12 +0530
Subject: [PATCH 09/11] [clang][Docs] Add release note for diagnosing missing
 parentheses in function-like macros

---
 clang/docs/ReleaseNotes.rst | 1 +
 1 file changed, 1 insertion(+)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 50d3bbbc97e91..a469e5a97a4ac 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -128,6 +128,7 @@ Improvements to Clang's diagnostics
   which are supposed to only exist once per program, but may get duplicated 
when
   built into a shared library.
 - Fixed a bug where Clang's Analysis did not correctly model the destructor 
behavior of ``union`` members (#GH119415).
+- Clang now provides a diagnostic note for ``function-like macros`` that are 
missing the required parentheses.
 
 Improvements to Clang's time-trace
 ----------------------------------

>From e4d2186162e5383d787450c07d81f08d527a429d Mon Sep 17 00:00:00 2001
From: Prashanth <thestaron...@proton.me>
Date: Wed, 12 Feb 2025 09:52:23 +0530
Subject: [PATCH 10/11] [clang][Sema] Improve diagnostics for function-like
 macros and update related notes

---
 clang/docs/ReleaseNotes.rst                    |  5 +++--
 .../include/clang/Basic/DiagnosticSemaKinds.td |  4 ++--
 clang/lib/Sema/SemaExpr.cpp                    | 18 +++++++++---------
 3 files changed, 14 insertions(+), 13 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index a469e5a97a4ac..c37c3d586de7b 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -128,8 +128,9 @@ Improvements to Clang's diagnostics
   which are supposed to only exist once per program, but may get duplicated 
when
   built into a shared library.
 - Fixed a bug where Clang's Analysis did not correctly model the destructor 
behavior of ``union`` members (#GH119415).
-- Clang now provides a diagnostic note for ``function-like macros`` that are 
missing the required parentheses.
-
+- Clang now provides a diagnostic note for function-like macros that are
+  missing the required parentheses (#GH123038).
+  
 Improvements to Clang's time-trace
 ----------------------------------
 
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 33a3bfe4ff646..e74020f8c8a0e 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10857,8 +10857,8 @@ def err_undeclared_use_suggest : Error<
   "use of undeclared %0; did you mean %1?">;
 def err_undeclared_var_use_suggest : Error<
   "use of undeclared identifier %0; did you mean %1?">;
-def err_undeclared_var_use_suggest_func_like_macro
-    : Error<"use of undeclared identifier %0; did you mean %0(...)?">;
+def err_undeclared_var_use_suggest_func_like_macro : Error<
+  "%0 is defined as an object-like macro; did you mean '%0(...)'?">;
 def err_no_template : Error<"no template named %0">;
 def err_no_template_suggest : Error<"no template named %0; did you mean %1?">;
 def err_no_member_template : Error<"no template named %0 in %1">;
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 27c2cf65762e3..26150bcb34967 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -2347,9 +2347,10 @@ Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty, 
ExprValueKind VK,
   return E;
 }
 
-// Check whether a similar function-like macro exists and suggest it
-static bool isFunctionLikeMacro(const DeclarationName &Name, Sema &SemaRef,
-                                const SourceLocation &TypoLoc) {
+// Diagnose when a macro cannot be expanded because it's a function-like macro
+// being used as an object-like macro. Returns true if a diagnostic is emitted.
+static bool diagnoseFunctionLikeMacro(Sema &SemaRef, DeclarationName Name,
+                                      SourceLocation TypoLoc) {
 
   if (IdentifierInfo *II = Name.getAsIdentifierInfo()) {
     if (II->hasMacroDefinition()) {
@@ -2357,7 +2358,7 @@ static bool isFunctionLikeMacro(const DeclarationName 
&Name, Sema &SemaRef,
       if (MI && MI->isFunctionLike()) {
         SemaRef.Diag(TypoLoc,
                      diag::err_undeclared_var_use_suggest_func_like_macro)
-            << II->getName();
+            << II;
         SemaRef.Diag(MI->getDefinitionLoc(),
                      diag::note_function_like_macro_requires_parens)
             << II->getName();
@@ -2403,11 +2404,10 @@ static void emitEmptyLookupTypoDiagnostic(
     if (Ctx)
       SemaRef.Diag(TypoLoc, diag::err_no_member) << Typo << Ctx
                                                  << SS.getRange();
-    else {
-      if (isFunctionLikeMacro(Typo, SemaRef, TypoLoc))
-        return;
+    else if (diagnoseFunctionLikeMacro(SemaRef, Typo, TypoLoc))
+      return;
+    else
       SemaRef.Diag(TypoLoc, DiagnosticID) << Typo;
-    }
     return;
   }
 
@@ -2648,7 +2648,7 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec 
&SS, LookupResult &R,
   }
   R.clear();
 
-  if (isFunctionLikeMacro(Name, SemaRef, R.getNameLoc()))
+  if (diagnoseFunctionLikeMacro(SemaRef, Name, R.getNameLoc()))
     return true;
 
   // Emit a special diagnostic for failed member lookups.

>From d4630860b0e01957a840f7a8d552957b697c4ba1 Mon Sep 17 00:00:00 2001
From: Prashanth <thestaron...@proton.me>
Date: Wed, 12 Feb 2025 16:17:08 +0530
Subject: [PATCH 11/11] [clang][Sema] Update diagnostic tests for object-like
 macros in initializer list tests

---
 clang/lib/Sema/SemaExpr.cpp                             | 2 +-
 clang/test/Preprocessor/macro_with_initializer_list.cpp | 6 +++---
 clang/test/Sema/typo-correction.c                       | 8 ++++----
 3 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 26150bcb34967..c3b5c705178a1 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -2358,7 +2358,7 @@ static bool diagnoseFunctionLikeMacro(Sema &SemaRef, 
DeclarationName Name,
       if (MI && MI->isFunctionLike()) {
         SemaRef.Diag(TypoLoc,
                      diag::err_undeclared_var_use_suggest_func_like_macro)
-            << II;
+            << II ->getName();
         SemaRef.Diag(MI->getDefinitionLoc(),
                      diag::note_function_like_macro_requires_parens)
             << II->getName();
diff --git a/clang/test/Preprocessor/macro_with_initializer_list.cpp 
b/clang/test/Preprocessor/macro_with_initializer_list.cpp
index dab60e60b14a1..92938a85e9bd4 100644
--- a/clang/test/Preprocessor/macro_with_initializer_list.cpp
+++ b/clang/test/Preprocessor/macro_with_initializer_list.cpp
@@ -150,13 +150,13 @@ void test() {
   // Can't be fixed by parentheses.
   INIT(e, {1, 2, 3});
   // expected-error@-1 {{too many arguments provided}}
-  // expected-error@-2 {{use of undeclared identifier}}
+  // expected-error@-2 {{'INIT' is defined as an object-like macro; did you 
mean ''INIT'(...)'?}}
   // expected-note@-3 {{cannot use initializer list at the beginning of a 
macro argument}}
 
   // Can't be fixed by parentheses.
   INIT(e, {1, 2, 3} + {1, 2, 3});
   // expected-error@-1 {{too many arguments provided}}
-  // expected-error@-2 {{use of undeclared identifier}}
+  // expected-error@-2 {{'INIT' is defined as an object-like macro; did you 
mean ''INIT'(...)'?}}
   // expected-note@-3 {{cannot use initializer list at the beginning of a 
macro argument}}
 }
 
@@ -179,6 +179,6 @@ void test2() {
   M(F3, {1,2,3}, {1,2,3}, {1,2,3}, {1,2,3}, {1,2,3}, {1,2,3},
         {1,2,3}, {1,2,3}, {1,2,3}, {1,2,3}, {1,2,3}, {1,2,3});
   // expected-error@-2 {{too many arguments provided}}
-  // expected-error@-3 {{use of undeclared identifier}}
+  // expected-error@-3 {{'M' is defined as an object-like macro; did you mean 
''M'(...)'?}}
   // expected-note@-4 {{cannot use initializer list at the beginning of a 
macro argument}}
 }
diff --git a/clang/test/Sema/typo-correction.c 
b/clang/test/Sema/typo-correction.c
index 3efd35538dd58..e16ad78583223 100644
--- a/clang/test/Sema/typo-correction.c
+++ b/clang/test/Sema/typo-correction.c
@@ -118,11 +118,11 @@ void PR40286_4(int the_value) { // expected-note 
{{'the_value' declared here}}
 #define FOO1() 10
 // expected-note@-1 4 {{'FOO1' defined here as a function-like macro}}
 
-int x = FOO1; // expected-error {{use of undeclared identifier FOO1; did you 
mean FOO1(...)?}}
+int x = FOO1; // expected-error {{'FOO1' is defined as an object-like macro; 
did you mean 'FOO1(...)'?}}
 
 void test3() {
   int iter = FOO1;
-  // expected-error@-1 {{use of undeclared identifier FOO1; did you mean 
FOO1(...)?}}
+  // expected-error@-1 {{'FOO1' is defined as an object-like macro; did you 
mean 'FOO1(...)'?}}
 }
 
 void bar(int);
@@ -133,6 +133,6 @@ void test4() {
 }
 
 void test5() {
-    FOO1 + 1; // expected-error {{use of undeclared identifier FOO1; did you 
mean FOO1(...)?}}
-    bar(FOO1); // expected-error {{use of undeclared identifier FOO1; did you 
mean FOO1(...)?}}
+    FOO1 + 1; // expected-error {{'FOO1' is defined as an object-like macro; 
did you mean 'FOO1(...)'?}}
+    bar(FOO1); // expected-error {{'FOO1' is defined as an object-like macro; 
did you mean 'FOO1'(...)'?}}
 }

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to