According to the OpenMP spec, all the preprocessor macros should be

expanded in OpenMP pragmas. This patch adds support for that in -E.

llvm-svn: 239784
This commit is contained in:
Samuel Antao 2015-06-15 23:44:27 +00:00
parent 72bfb8e234
commit eab747b9f5
2 changed files with 73 additions and 10 deletions

View File

@ -562,8 +562,13 @@ struct UnknownPragmaHandler : public PragmaHandler {
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
@ -571,16 +576,24 @@ struct UnknownPragmaHandler : public PragmaHandler {
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);
@ -718,10 +731,29 @@ void clang::DoPrintPreprocessedInput(Preprocessor &PP, raw_ostream *OS,
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));

View File

@ -0,0 +1,31 @@
// 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;
}
}