Meinersbur updated this revision to Diff 230094.
Meinersbur added a comment.

- Address @ABataev's review


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D69088

Files:
  clang/include/clang/Basic/LangOptions.def
  clang/include/clang/Basic/TokenKinds.def
  clang/include/clang/Driver/Options.td
  clang/include/clang/Parse/Parser.h
  clang/lib/Frontend/CompilerInvocation.cpp
  clang/lib/Parse/ParsePragma.cpp
  clang/test/Parser/pragma-no-transform.cpp

Index: clang/test/Parser/pragma-no-transform.cpp
===================================================================
--- /dev/null
+++ clang/test/Parser/pragma-no-transform.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -std=c++11 -fno-experimental-transform-pragma -Wall -verify %s
+
+void pragma_transform(int *List, int Length) {
+/* expected-warning@+1 {{unknown pragma ignored}} */
+#pragma clang transform unroll partial(4)
+  for (int i = 0; i < Length; i+=1)
+      List[i] = i;
+}
+
Index: clang/lib/Parse/ParsePragma.cpp
===================================================================
--- clang/lib/Parse/ParsePragma.cpp
+++ clang/lib/Parse/ParsePragma.cpp
@@ -262,6 +262,12 @@
   ParsedAttributes AttributesForPragmaAttribute;
 };
 
+struct PragmaTransformHandler : public PragmaHandler {
+  PragmaTransformHandler() : PragmaHandler("transform") {}
+  void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
+                    Token &FirstToken) override;
+};
+
 }  // end namespace
 
 void Parser::initializePragmaHandlers() {
@@ -382,6 +388,11 @@
   AttributePragmaHandler =
       std::make_unique<PragmaAttributeHandler>(AttrFactory);
   PP.AddPragmaHandler("clang", AttributePragmaHandler.get());
+
+  if (getLangOpts().ExperimentalTransformPragma) {
+    TransformHandler = std::make_unique<PragmaTransformHandler>();
+    PP.AddPragmaHandler("clang", TransformHandler.get());
+  }
 }
 
 void Parser::resetPragmaHandlers() {
@@ -487,6 +498,11 @@
 
   PP.RemovePragmaHandler("clang", AttributePragmaHandler.get());
   AttributePragmaHandler.reset();
+
+  if (getLangOpts().ExperimentalTransformPragma) {
+    PP.RemovePragmaHandler("clang", TransformHandler.get());
+    TransformHandler.reset();
+  }
 }
 
 /// Handle the annotation token produced for #pragma unused(...)
@@ -3008,6 +3024,65 @@
                       /*DisableMacroExpansion=*/false, /*IsReinject=*/false);
 }
 
+/// Handle
+///   #pragma clang transform ...
+void PragmaTransformHandler::HandlePragma(Preprocessor &PP,
+                                          PragmaIntroducer Introducer,
+                                          Token &FirstTok) {
+  // "clang" token is not passed
+  // "transform" is FirstTok
+  // Everything up until tok::eod (or tok::eof) is wrapped between
+  // tok::annot_pragma_transform and tok::annot_pragma_transform_end, and
+  // pushed-back into the token stream. The tok::eod/eof is consumed as well:
+  //
+  // Token stream before:
+  //   FirstTok:"transform" | <trans> [clauses..] eod   ...
+  //
+  // Token stream after :
+  //            "transform"   <trans> [clauses..] eod | ...
+  // After pushing the annotation tokens:
+  //
+  // | annot_pragma_transform <trans> [clauses..] annot_pragma_transform_end ...
+  //
+  // The symbol | is before the next token returned by PP.Lex()
+  SmallVector<Token, 16> PragmaToks;
+
+  Token StartTok;
+  StartTok.startToken();
+  StartTok.setKind(tok::annot_pragma_transform);
+  StartTok.setLocation(FirstTok.getLocation());
+  PragmaToks.push_back(StartTok);
+
+  SourceLocation EodLoc = FirstTok.getLocation();
+  while (true) {
+    Token Tok;
+    PP.Lex(Tok);
+    assert(!Tok.isAnnotation() &&
+           "It should not be possible to nest annotations");
+
+    if (Tok.is(tok::eod) || Tok.is(tok::eof)) {
+      EodLoc = Tok.getLocation();
+      break;
+    }
+
+    PragmaToks.push_back(Tok);
+  }
+
+  Token EndTok;
+  EndTok.startToken();
+  EndTok.setKind(tok::annot_pragma_transform_end);
+  EndTok.setLocation(EodLoc);
+  PragmaToks.push_back(EndTok);
+
+  // Copy tokens for the preprocessor to own and free.
+  auto Toks = std::make_unique<Token[]>(PragmaToks.size());
+  std::copy(PragmaToks.begin(), PragmaToks.end(), Toks.get());
+
+  // Handle in parser
+  PP.EnterTokenStream(std::move(Toks), PragmaToks.size(),
+                      /*DisableMacroExpansion=*/false, /*IsReinject=*/false);
+}
+
 /// Handle the Microsoft \#pragma intrinsic extension.
 ///
 /// The syntax is:
Index: clang/lib/Frontend/CompilerInvocation.cpp
===================================================================
--- clang/lib/Frontend/CompilerInvocation.cpp
+++ clang/lib/Frontend/CompilerInvocation.cpp
@@ -3229,6 +3229,11 @@
 
   Opts.CompleteMemberPointers = Args.hasArg(OPT_fcomplete_member_pointers);
   Opts.BuildingPCHWithObjectFile = Args.hasArg(OPT_building_pch_with_obj);
+
+  // Enable or disable support for #pragma clang transform.
+  Opts.ExperimentalTransformPragma =
+      Args.hasFlag(options::OPT_fexperimental_transform_pragma,
+                   options::OPT_fno_experimental_transform_pragma, false);
 }
 
 static bool isStrictlyPreprocessorAction(frontend::ActionKind Action) {
Index: clang/include/clang/Parse/Parser.h
===================================================================
--- clang/include/clang/Parse/Parser.h
+++ clang/include/clang/Parse/Parser.h
@@ -200,6 +200,7 @@
   std::unique_ptr<PragmaHandler> STDCCXLIMITHandler;
   std::unique_ptr<PragmaHandler> STDCUnknownHandler;
   std::unique_ptr<PragmaHandler> AttributePragmaHandler;
+  std::unique_ptr<PragmaHandler> TransformHandler;
 
   std::unique_ptr<CommentHandler> CommentSemaHandler;
 
Index: clang/include/clang/Driver/Options.td
===================================================================
--- clang/include/clang/Driver/Options.td
+++ clang/include/clang/Driver/Options.td
@@ -1667,6 +1667,10 @@
   Flags<[NoArgumentUnused, HelpHidden]>;
 def static_openmp: Flag<["-"], "static-openmp">,
   HelpText<"Use the static host OpenMP runtime while linking.">;
+def fexperimental_transform_pragma : Flag<["-"], "fexperimental-transform-pragma">, Group<f_Group>,
+  Flags<[CC1Option, HelpHidden]>, HelpText<"Parse #pragma clang transform directives.">;
+def fno_experimental_transform_pragma : Flag<["-"], "fno-experimental-transform-pragma">, Group<f_Group>,
+  Flags<[CC1Option, HelpHidden]>, HelpText<"Disable #pragma clang transform directives.">;
 def fno_optimize_sibling_calls : Flag<["-"], "fno-optimize-sibling-calls">, Group<f_Group>;
 def foptimize_sibling_calls : Flag<["-"], "foptimize-sibling-calls">, Group<f_Group>;
 def fno_escaping_block_tail_calls : Flag<["-"], "fno-escaping-block-tail-calls">, Group<f_Group>, Flags<[CC1Option]>;
Index: clang/include/clang/Basic/TokenKinds.def
===================================================================
--- clang/include/clang/Basic/TokenKinds.def
+++ clang/include/clang/Basic/TokenKinds.def
@@ -830,6 +830,11 @@
 PRAGMA_ANNOTATION(pragma_openmp)
 PRAGMA_ANNOTATION(pragma_openmp_end)
 
+// Annotations for code transformation pragmas
+// #pragma clang transform ...
+PRAGMA_ANNOTATION(pragma_transform)
+PRAGMA_ANNOTATION(pragma_transform_end)
+
 // Annotations for loop pragma directives #pragma clang loop ...
 // The lexer produces these so that they only take effect when the parser
 // handles #pragma loop ... directives.
Index: clang/include/clang/Basic/LangOptions.def
===================================================================
--- clang/include/clang/Basic/LangOptions.def
+++ clang/include/clang/Basic/LangOptions.def
@@ -230,6 +230,8 @@
 
 LANGOPT(HIPUseNewLaunchAPI, 1, 0, "Use new kernel launching API for HIP")
 
+LANGOPT(ExperimentalTransformPragma, 1, 0, "Enable #pragma clang transform")
+
 LANGOPT(SizedDeallocation , 1, 0, "sized deallocation")
 LANGOPT(AlignedAllocation , 1, 0, "aligned allocation")
 LANGOPT(AlignedAllocationUnavailable, 1, 0, "aligned allocation functions are unavailable")
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to