const char *Prefix;
PrintPPOutputPPCallbacks *Callbacks;
- UnknownPragmaHandler(const char *prefix, PrintPPOutputPPCallbacks *callbacks)
- : Prefix(prefix), Callbacks(callbacks) {}
+ // Set to true if tokens should be expanded
+ bool ShouldExpandTokens;
+
+ UnknownPragmaHandler(const char *prefix, PrintPPOutputPPCallbacks *callbacks,
+ bool RequireTokenExpansion)
+ : Prefix(prefix), Callbacks(callbacks),
+ ShouldExpandTokens(RequireTokenExpansion) {}
void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
Token &PragmaTok) override {
// Figure out what line we went to and insert the appropriate number of
Callbacks->startNewLineIfNeeded();
Callbacks->MoveToLine(PragmaTok.getLocation());
Callbacks->OS.write(Prefix, strlen(Prefix));
+
+ Token PrevToken;
+ Token PrevPrevToken;
+ PrevToken.startToken();
+ PrevPrevToken.startToken();
+
// Read and print all of the pragma tokens.
while (PragmaTok.isNot(tok::eod)) {
- if (PragmaTok.hasLeadingSpace())
+ if (PragmaTok.hasLeadingSpace() ||
+ Callbacks->AvoidConcat(PrevPrevToken, PrevToken, PragmaTok))
Callbacks->OS << ' ';
std::string TokSpell = PP.getSpelling(PragmaTok);
Callbacks->OS.write(&TokSpell[0], TokSpell.size());
- // Expand macros in pragmas with -fms-extensions. The assumption is that
- // the majority of pragmas in such a file will be Microsoft pragmas.
- if (PP.getLangOpts().MicrosoftExt)
+ PrevPrevToken = PrevToken;
+ PrevToken = PragmaTok;
+
+ if (ShouldExpandTokens)
PP.Lex(PragmaTok);
else
PP.LexUnexpandedToken(PragmaTok);
PrintPPOutputPPCallbacks *Callbacks = new PrintPPOutputPPCallbacks(
PP, *OS, !Opts.ShowLineMarkers, Opts.ShowMacros, Opts.UseLineDirectives);
- PP.AddPragmaHandler(new UnknownPragmaHandler("#pragma", Callbacks));
- PP.AddPragmaHandler("GCC", new UnknownPragmaHandler("#pragma GCC",Callbacks));
- PP.AddPragmaHandler("clang",
- new UnknownPragmaHandler("#pragma clang", Callbacks));
+
+ // Expand macros in pragmas with -fms-extensions. The assumption is that
+ // the majority of pragmas in such a file will be Microsoft pragmas.
+ PP.AddPragmaHandler(new UnknownPragmaHandler(
+ "#pragma", Callbacks,
+ /*RequireTokenExpansion=*/PP.getLangOpts().MicrosoftExt));
+ PP.AddPragmaHandler(
+ "GCC", new UnknownPragmaHandler(
+ "#pragma GCC", Callbacks,
+ /*RequireTokenExpansion=*/PP.getLangOpts().MicrosoftExt));
+ PP.AddPragmaHandler(
+ "clang", new UnknownPragmaHandler(
+ "#pragma clang", Callbacks,
+ /*RequireTokenExpansion=*/PP.getLangOpts().MicrosoftExt));
+
+ // The tokens after pragma omp need to be expanded.
+ //
+ // OpenMP [2.1, Directive format]
+ // Preprocessing tokens following the #pragma omp are subject to macro
+ // replacement.
+ PP.AddPragmaHandler("omp",
+ new UnknownPragmaHandler("#pragma omp", Callbacks,
+ /*RequireTokenExpansion=*/true));
PP.addPPCallbacks(std::unique_ptr<PPCallbacks>(Callbacks));
--- /dev/null
+// RUN: %clang_cc1 -fopenmp -E -o - %s 2>&1 | FileCheck %s
+
+// This is to make sure the pragma name is not expanded!
+#define omp (0xDEADBEEF)
+
+#define N 2
+#define M 1
+#define E N>
+
+#define map_to_be_expanded(x) map(tofrom:x)
+#define sched_to_be_expanded(x,s) schedule(x,s)
+#define reda_to_be_expanded(x) reduction(+:x)
+#define redb_to_be_expanded(x,op) reduction(op:x)
+
+void foo(int *a, int *b) {
+ //CHECK: omp target map(a[0:2]) map(tofrom:b[0:2*1])
+ #pragma omp target map(a[0:N]) map_to_be_expanded(b[0:2*M])
+ {
+ int reda;
+ int redb;
+ //CHECK: omp parallel for schedule(static,2> >1) reduction(+:reda) reduction(*:redb)
+ #pragma omp parallel for sched_to_be_expanded(static, E>1) \
+ reda_to_be_expanded(reda) redb_to_be_expanded(redb,*)
+ for (int i = 0; i < N; ++i) {
+ reda += a[i];
+ redb += b[i];
+ }
+ a[0] = reda;
+ b[0] = redb;
+ }
+}