ken-matsui updated this revision to Diff 428358.
ken-matsui added a comment.

Update the code as reviewed


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D125178/new/

https://reviews.llvm.org/D125178

Files:
  clang/include/clang/Basic/DiagnosticLexKinds.td
  clang/lib/Lex/PPDirectives.cpp
  clang/test/Preprocessor/ext-c2x-pp-directive.c
  clang/test/Preprocessor/ext-cpp2b-pp-directive.cpp

Index: clang/test/Preprocessor/ext-cpp2b-pp-directive.cpp
===================================================================
--- /dev/null
+++ clang/test/Preprocessor/ext-cpp2b-pp-directive.cpp
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -x c++ -fsyntax-only -verify=pre-cpp2b-pedantic -pedantic %s
+// RUN: %clang_cc1 -x c++ -std=c++2b -fsyntax-only -verify=pre-cpp2b-compat -Wpre-c++2b-compat %s
+// RUN: not %clang_cc1 -x c++ -fsyntax-only -verify %s
+// RUN: not %clang_cc1 -x c++ -std=c++2b -fsyntax-only -verify -pedantic %s
+// RUN: not %clang_cc1 -x c++ -std=c++2b -fsyntax-only -verify %s
+
+int x;
+
+#if 1
+#elifdef A // #1
+#endif
+// pre-cpp2b-pedantic-warning@#1 {{use of a '#elifdef' directive is a C++2b extension}}
+// pre-cpp2b-compat-warning@#1 {{use of a '#elifdef' directive is incompatible with C++ standards before C++2b}}
+
+#if 1
+#elifndef B // #2
+#endif
+// pre-cpp2b-pedantic-warning@#2 {{use of a '#elifndef' directive is a C++2b extension}}
+// pre-cpp2b-compat-warning@#2 {{use of a '#elifndef' directive is incompatible with C++ standards before C++2b}}
+
+#if 0
+#elifdef C
+#endif
+// pre-cpp2b-pedantic-warning@-2 {{use of a '#elifdef' directive is a C++2b extension}}
+// pre-cpp2b-compat-warning@-3 {{use of a '#elifdef' directive is incompatible with C++ standards before C++2b}}
+
+#if 0
+#elifndef D
+#endif
+// pre-cpp2b-pedantic-warning@-2 {{use of a '#elifndef' directive is a C++2b extension}}
+// pre-cpp2b-compat-warning@-3 {{use of a '#elifndef' directive is incompatible with C++ standards before C++2b}}
Index: clang/test/Preprocessor/ext-c2x-pp-directive.c
===================================================================
--- /dev/null
+++ clang/test/Preprocessor/ext-c2x-pp-directive.c
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -std=c99 -fsyntax-only -verify=c99-pedantic -pedantic %s
+// RUN: %clang_cc1 -std=c2x -fsyntax-only -verify=pre-c2x-compat -Wpre-c2x-compat %s
+// RUN: not %clang_cc1 -std=c99 -fsyntax-only -verify %s
+// RUN: not %clang_cc1 -std=c2x -fsyntax-only -verify -pedantic %s
+// RUN: not %clang_cc1 -std=c2x -fsyntax-only -verify %s
+
+int x;
+
+#if 1
+#elifdef A // #1
+#endif
+// c99-pedantic-warning@#1 {{use of a '#elifdef' directive is a C2x extension}}
+// pre-c2x-compat-warning@#1 {{use of a '#elifdef' directive is incompatible with C standards before C2x}}
+
+#if 1
+#elifndef B // #2
+#endif
+// c99-pedantic-warning@#2 {{use of a '#elifndef' directive is a C2x extension}}
+// pre-c2x-compat-warning@#2 {{use of a '#elifndef' directive is incompatible with C standards before C2x}}
+
+#if 0
+#elifdef C
+#endif
+// c99-pedantic-warning@-2 {{use of a '#elifdef' directive is a C2x extension}}
+// pre-c2x-compat-warning@-3 {{use of a '#elifdef' directive is incompatible with C standards before C2x}}
+
+#if 0
+#elifndef D
+#endif
+// c99-pedantic-warning@-2 {{use of a '#elifndef' directive is a C2x extension}}
+// pre-c2x-compat-warning@-3 {{use of a '#elifndef' directive is incompatible with C standards before C2x}}
Index: clang/lib/Lex/PPDirectives.cpp
===================================================================
--- clang/lib/Lex/PPDirectives.cpp
+++ clang/lib/Lex/PPDirectives.cpp
@@ -652,6 +652,16 @@
         PPConditionalInfo &CondInfo = CurPPLexer->peekConditionalLevel();
         Token DirectiveToken = Tok;
 
+        unsigned DiagID;
+        if (LangOpts.CPlusPlus)
+          DiagID = LangOpts.CPlusPlus2b ? diag::warn_cxx2b_compat_pp_directive
+                                        : diag::ext_cxx2b_pp_directive;
+        else
+          DiagID = LangOpts.C2x ? diag::warn_c2x_compat_pp_directive
+                                : diag::ext_c2x_pp_directive;
+
+        Diag(Tok, DiagID) << (IsElifDef ? PED_Elifdef : PED_Elifndef) - 1;
+
         // If this is a #elif with a #else before it, report the error.
         if (CondInfo.FoundElse)
           Diag(Tok, diag::pp_err_elif_after_else)
@@ -3255,6 +3265,24 @@
                                                  : PED_Elifndef;
   ++NumElse;
 
+  // Warn if using `#elifdef` & `#elifndef` in not C2x mode.
+  switch (DirKind) {
+  case PED_Elifdef:
+  case PED_Elifndef:
+    unsigned DiagID;
+    if (LangOpts.CPlusPlus)
+      DiagID = LangOpts.CPlusPlus2b ? diag::warn_cxx2b_compat_pp_directive
+                                    : diag::ext_cxx2b_pp_directive;
+    else
+      DiagID = LangOpts.C2x ? diag::warn_c2x_compat_pp_directive
+                            : diag::ext_c2x_pp_directive;
+
+    Diag(ElifToken, DiagID) << DirKind - 1;
+    break;
+  default:
+    break;
+  }
+
   // #elif directive in a non-skipping conditional... start skipping.
   // We don't care what the condition is, because we will always skip it (since
   // the block immediately before it was included).
Index: clang/include/clang/Basic/DiagnosticLexKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticLexKinds.td
+++ clang/include/clang/Basic/DiagnosticLexKinds.td
@@ -694,6 +694,19 @@
   "#line number greater than 32767 is incompatible with C++98">,
   InGroup<CXX98CompatPedantic>, DefaultIgnore;
 
+def warn_c2x_compat_pp_directive : Warning<
+  "use of a '#%select{elifdef|elifndef}0' directive is incompatible with C standards before C2x">,
+  InGroup<CPre2xCompat>, DefaultIgnore;
+def ext_c2x_pp_directive : ExtWarn<
+  "use of a '#%select{elifdef|elifndef}0' directive is a C2x extension">,
+  InGroup<C2x>;
+def warn_cxx2b_compat_pp_directive : Warning<
+  "use of a '#%select{elifdef|elifndef}0' directive is incompatible with C++ standards before C++2b">,
+  InGroup<CXXPre2bCompat>, DefaultIgnore;
+def ext_cxx2b_pp_directive : ExtWarn<
+  "use of a '#%select{elifdef|elifndef}0' directive is a C++2b extension">,
+  InGroup<CXX2b>;
+
 def err_pp_visibility_non_macro : Error<"no macro named %0">;
 
 def err_pp_arc_cf_code_audited_syntax : Error<"expected 'begin' or 'end'">;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to