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
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits