[cfe-commits] r166869 - in /cfe/trunk: include/clang/Basic/DiagnosticGroups.td include/clang/Basic/DiagnosticParseKinds.td include/clang/Basic/TokenKinds.def include/clang/Parse/Parser.h lib/Parse/Parser.cpp test/Preprocessor/pragma_omp.c test/Preprocessor/pragma_omp_ignored_warning.c
Mahesha S
mahesha.llvm at gmail.com
Sat Oct 27 02:05:45 PDT 2012
Author: mahesha
Date: Sat Oct 27 04:05:45 2012
New Revision: 166869
URL: http://llvm.org/viewvc/llvm-project?rev=166869&view=rev
Log:
Feature:
OpenMP support.
Sub-Feature:
Support for "#pragma omp ..." registration with
Preprocessor.
Files Changed/Added:
* include/clang/Basic/DiagnosticGroups.td (C)
* include/clang/Basic/DiagnosticParseKinds.td (C)
* include/clang/Basic/TokenKinds.def (C)
* include/clang/Parse/Parser.h (C)
* lib/Parse/Parser.cpp (C)
Test Cases Changed/Added:
* test/Preprocessor/pragma_omp.c (A)
* test/Preprocessor/pragma_omp_ignored_warning.c (A)
Added:
cfe/trunk/test/Preprocessor/pragma_omp.c
cfe/trunk/test/Preprocessor/pragma_omp_ignored_warning.c
Modified:
cfe/trunk/include/clang/Basic/DiagnosticGroups.td
cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
cfe/trunk/include/clang/Basic/TokenKinds.def
cfe/trunk/include/clang/Parse/Parser.h
cfe/trunk/lib/Parse/Parser.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticGroups.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticGroups.td?rev=166869&r1=166868&r2=166869&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticGroups.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticGroups.td Sat Oct 27 04:05:45 2012
@@ -251,6 +251,7 @@
def UninitializedSometimes : DiagGroup<"sometimes-uninitialized">;
def Uninitialized : DiagGroup<"uninitialized", [UninitializedSometimes]>;
def UnknownPragmas : DiagGroup<"unknown-pragmas">;
+def OpenMPPragmas : DiagGroup<"openmp-pragmas">;
def NSobjectAttribute : DiagGroup<"NSObject-attribute">;
def UnknownAttributes : DiagGroup<"attributes">;
def IgnoredAttributes : DiagGroup<"ignored-attributes">;
Modified: cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td?rev=166869&r1=166868&r2=166869&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td Sat Oct 27 04:05:45 2012
@@ -734,6 +734,11 @@
"'#pragma fp_contract' should only appear at file scope or at the start of a "
"compound expression">;
+// OpenMP
+def warn_pragma_omp_ignored : Warning<
+ "pragma omp ignored; did you forget to add '-fopenmp' flag?">,
+ InGroup<OpenMPPragmas>;
+
// OpenCL Section 6.8.g
def err_not_opencl_storage_class_specifier : Error<
"OpenCL does not support the '%0' storage class specifier">;
Modified: cfe/trunk/include/clang/Basic/TokenKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/TokenKinds.def?rev=166869&r1=166868&r2=166869&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/TokenKinds.def (original)
+++ cfe/trunk/include/clang/Basic/TokenKinds.def Sat Oct 27 04:05:45 2012
@@ -637,6 +637,42 @@
// handles them.
ANNOTATION(pragma_opencl_extension)
+// Annotations for OpenMP pragma directive statements - "\#pragam omp ..."
+// The lexer produces these so that they only take effect when the parser
+// handles them.
+//
+// Note that OpenMP pragma annotations below are listed in the same order
+// as listed in the OpenMP 3.1 standard specification document. Please do
+// *adhere* to the same order.
+
+// OpenMP parallel constructs.
+ANNOTATION(pragma_omp_parallel)
+
+// OpenMP work sharing constructs.
+ANNOTATION(pragma_omp_for)
+ANNOTATION(pragma_omp_sections)
+ANNOTATION(pragma_omp_single)
+ANNOTATION(pragma_omp_section)
+
+// OpenMP combined parallel work sharing constructs.
+// TODO
+
+// OpenMP tasking constructs.
+ANNOTATION(pragma_omp_task)
+ANNOTATION(pragma_omp_taskyield)
+
+// OpenMP master and synchronization constructs.
+ANNOTATION(pragma_omp_master)
+ANNOTATION(pragma_omp_critical)
+ANNOTATION(pragma_omp_barrier)
+ANNOTATION(pragma_omp_taskwait)
+ANNOTATION(pragma_omp_atomic)
+ANNOTATION(pragma_omp_flush)
+ANNOTATION(pragma_omp_ordered)
+
+// OpenMP data environment related constructs.
+ANNOTATION(pragma_omp_threadprivate)
+
#undef ANNOTATION
#undef TESTING_KEYWORD
#undef OBJC2_AT_KEYWORD
Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=166869&r1=166868&r2=166869&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Sat Oct 27 04:05:45 2012
@@ -43,6 +43,7 @@
class InMessageExpressionRAIIObject;
class PoisonSEHIdentifiersRAIIObject;
class VersionTuple;
+ class OpenMP;
/// PrettyStackTraceParserEntry - If a crash happens while the parser is active,
/// an entry is printed for it.
@@ -180,6 +181,8 @@
OwningPtr<PragmaHandler> OpenCLExtensionHandler;
OwningPtr<CommentHandler> CommentSemaHandler;
+ OwningPtr<OpenMP> OpenMPHandler;
+
/// Whether the '>' token acts as an operator or not. This will be
/// true except when we are parsing an expression within a C++
/// template argument list, where the '>' closes the template
Modified: cfe/trunk/lib/Parse/Parser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/Parser.cpp?rev=166869&r1=166868&r2=166869&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/Parser.cpp (original)
+++ cfe/trunk/lib/Parse/Parser.cpp Sat Oct 27 04:05:45 2012
@@ -23,6 +23,237 @@
#include "clang/AST/ASTConsumer.h"
using namespace clang;
+
+namespace clang {
+
+/// \brief An instance of this interface is defined to initiate OpenMP parsing,
+/// and to help Parser during subsequent parsing of OpenMP constrcuts.
+class OpenMP {
+ // Private Member Objects.
+private:
+ // \brief The member object reference to the Preprocessor.
+ Preprocessor &PP;
+
+ // \brief Handler objects which handle different OpenMP pragma directive
+ // statements.
+ OwningPtr<PragmaHandler> ParallelHandler;
+ OwningPtr<PragmaHandler> ForHandler;
+ OwningPtr<PragmaHandler> SectionsHandler;
+ OwningPtr<PragmaHandler> SectionHandler;
+ OwningPtr<PragmaHandler> SingleHandler;
+ OwningPtr<PragmaHandler> TaskHandler;
+ OwningPtr<PragmaHandler> MasterHandler;
+ OwningPtr<PragmaHandler> CriticalHandler;
+ OwningPtr<PragmaHandler> BarrierHandler;
+ OwningPtr<PragmaHandler> TaskwaitHandler;
+ OwningPtr<PragmaHandler> TaskyieldHandler;
+ OwningPtr<PragmaHandler> AtomicHandler;
+ OwningPtr<PragmaHandler> FlushHandler;
+ OwningPtr<PragmaHandler> OrderedHandler;
+ OwningPtr<PragmaHandler> ThreadPrivateHandler;
+
+ // \brief When an OpenMP pragma is ignored, we emit a warning message
+ // saying so, but only once per translation unit irrespective of the
+ // number of OpenMP pragmas appeared in the translation unit. This flag
+ // keeps track of whether the unkown pragma warning message is emitted
+ // or not for the current translation unit.
+ bool OmpUnknownWarned;
+
+ // Private Member Methods.
+private:
+ // \brief When source contains omp pragmas, but user does not pass the
+ // '-fopenmp' flag, we emit a warning message saying so, but only once per
+ // source file.
+ void SetPragmaOmpUnknownWarned() { OmpUnknownWarned = true; }
+ void ResetPragmaOmpUnknownWarned() { OmpUnknownWarned = false; }
+ bool PragmaOmpUnknownWarned() { return OmpUnknownWarned; }
+
+ // \brief Handles "\#pragma omp ...".
+ // It Checks if the user has passed the flag, '-fopenmp', if so,
+ // it enters the *token* which is *representing* the current OpenMP
+ // pragma *directive* into the TokenStream, so that the Parser can
+ // recognizes it and can parse the respective OpenMP pragma directive
+ // statement. Otherwise, it reports a warning that the current OpenMP
+ // directive statement will be ignored. However, note that only
+ // *one* warning message per translation unit is reported
+ // irrespective of the number of OpenMP directive statments which
+ // appear in the translation unit.
+ void HandlePragma(Token &OmpTok, tok::TokenKind TKind) {
+ if (!PP.getLangOpts().OpenMP) {
+ if (!PragmaOmpUnknownWarned()) {
+ PP.Diag(OmpTok, diag::warn_pragma_omp_ignored);
+ SetPragmaOmpUnknownWarned();
+ }
+ } else {
+ Token *Toks = new Token[1];
+ Toks[0].startToken();
+ Toks[0].setKind(TKind);
+ Toks[0].setLocation(OmpTok.getLocation());
+ PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true,
+ /*OwnsTokens=*/false);
+ }
+ }
+
+ // Constructors and Destructors.
+public:
+ OpenMP(Preprocessor &pp);
+ ~OpenMP();
+
+private:
+ // \brief An OpenMP pragma handler interface. It acts as an intermediate
+ // between the Preprocessor class and the OpenMP (this) class. It by passes
+ // the omp pragma handling call to OpenMP class upon requested by the
+ // Preprocessor.
+ struct PragmaOmpHandler : public PragmaHandler {
+ friend class OpenMP;
+ tok::TokenKind TKind;
+ OpenMP *Omp;
+ PragmaOmpHandler(tok::TokenKind Kind, StringRef Name, OpenMP *omp)
+ : PragmaHandler(Name), TKind(Kind), Omp(omp) {}
+ virtual ~PragmaOmpHandler() { Omp = 0; }
+ virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
+ Token &OmpTok) {
+ Omp->HandlePragma(OmpTok, TKind);
+ }
+ };
+};
+
+} // end of namespace clang
+
+OpenMP::OpenMP(Preprocessor &pp)
+ : PP(pp) {
+
+ // Add "#pragma omp ..." handlers. These are removed and destroyed
+ // in the destructor.
+ //
+ // Note that OpenMP pragma annotations below are listed in the same order
+ // as listed in the OpenMP 3.1 standard specification document. Please
+ // do *adhere* to the same order.
+
+ // OpenMP parallel constructs.
+ ParallelHandler.reset(new PragmaOmpHandler(
+ tok::annot_pragma_omp_parallel, "parallel", this));
+ PP.AddPragmaHandler("omp", ParallelHandler.get());
+
+ // OpenMP work sharing constructs.
+ ForHandler.reset(new PragmaOmpHandler(
+ tok::annot_pragma_omp_for, "for", this));
+ PP.AddPragmaHandler("omp", ForHandler.get());
+
+ SectionsHandler.reset(new PragmaOmpHandler(
+ tok::annot_pragma_omp_sections, "sections", this));
+ PP.AddPragmaHandler("omp", SectionsHandler.get());
+
+ SingleHandler.reset(new PragmaOmpHandler(
+ tok::annot_pragma_omp_single, "single", this));
+ PP.AddPragmaHandler("omp", SingleHandler.get());
+
+ SectionHandler.reset(new PragmaOmpHandler(
+ tok::annot_pragma_omp_section, "section", this));
+ PP.AddPragmaHandler("omp", SectionHandler.get());
+
+ // OpenMP combined parallel work sharing constructs.
+ // FIXME: not supported yet.
+
+ // OpenMP tasking constructs.
+ TaskHandler.reset(new PragmaOmpHandler(
+ tok::annot_pragma_omp_task, "task", this));
+ PP.AddPragmaHandler("omp", TaskHandler.get());
+
+ TaskyieldHandler.reset(new PragmaOmpHandler(
+ tok::annot_pragma_omp_taskyield, "taskyield", this));
+ PP.AddPragmaHandler("omp", TaskyieldHandler.get());
+
+ // OpenMP master and synchronization constructs.
+ MasterHandler.reset(new PragmaOmpHandler(
+ tok::annot_pragma_omp_master, "master", this));
+ PP.AddPragmaHandler("omp", MasterHandler.get());
+
+ CriticalHandler.reset(new PragmaOmpHandler(
+ tok::annot_pragma_omp_critical, "critical", this));
+ PP.AddPragmaHandler("omp", CriticalHandler.get());
+
+ BarrierHandler.reset(new PragmaOmpHandler(
+ tok::annot_pragma_omp_barrier, "barrier", this));
+ PP.AddPragmaHandler("omp", BarrierHandler.get());
+
+ TaskwaitHandler.reset(new PragmaOmpHandler(
+ tok::annot_pragma_omp_taskwait, "taskwait", this));
+ PP.AddPragmaHandler("omp", TaskwaitHandler.get());
+
+ AtomicHandler.reset(new PragmaOmpHandler(
+ tok::annot_pragma_omp_atomic, "atomic", this));
+ PP.AddPragmaHandler("omp", AtomicHandler.get());
+
+ FlushHandler.reset(new PragmaOmpHandler(
+ tok::annot_pragma_omp_flush, "flush", this));
+ PP.AddPragmaHandler("omp", FlushHandler.get());
+
+ OrderedHandler.reset(new PragmaOmpHandler(
+ tok::annot_pragma_omp_ordered, "ordered", this));
+ PP.AddPragmaHandler("omp", OrderedHandler.get());
+
+ // OpenMP data environment related constructs.
+ ThreadPrivateHandler.reset(new PragmaOmpHandler(
+ tok::annot_pragma_omp_threadprivate, "threadprivate", this));
+ PP.AddPragmaHandler("omp", ThreadPrivateHandler.get());
+
+ // We have not yet reported the unknown OpenMP pragma *warning* message
+ // as we have not yet started the processing of translation unit.
+ ResetPragmaOmpUnknownWarned();
+}
+
+OpenMP::~OpenMP() {
+ // Remove the "#pragma omp ..." handlers we installed.
+ //
+ // Note that OpenMP pragma annotations below are listed in the same order
+ // as listed in the OpenMP 3.1 standard specification document. Please
+ // do *adhere* to the same order.
+
+ // OpenMP parallel constructs.
+ PP.RemovePragmaHandler("omp", ParallelHandler.get());
+ ParallelHandler.reset();
+
+ // OpenMP work sharing constructs.
+ PP.RemovePragmaHandler("omp", ForHandler.get());
+ ForHandler.reset();
+ PP.RemovePragmaHandler("omp", SectionsHandler.get());
+ SectionsHandler.reset();
+ PP.RemovePragmaHandler("omp", SingleHandler.get());
+ SingleHandler.reset();
+ PP.RemovePragmaHandler("omp", SectionHandler.get());
+ SectionHandler.reset();
+
+ // OpenMP combined parallel work sharing constructs.
+ // FIXME: Yet to support.
+
+ // OpenMP tasking constructs.
+ PP.RemovePragmaHandler("omp", TaskHandler.get());
+ TaskHandler.reset();
+ PP.RemovePragmaHandler("omp", TaskyieldHandler.get());
+ TaskyieldHandler.reset();
+
+ // OpenMP master and synchronization constructs.
+ PP.RemovePragmaHandler("omp", MasterHandler.get());
+ MasterHandler.reset();
+ PP.RemovePragmaHandler("omp", CriticalHandler.get());
+ CriticalHandler.reset();
+ PP.RemovePragmaHandler("omp", BarrierHandler.get());
+ BarrierHandler.reset();
+ PP.RemovePragmaHandler("omp", TaskwaitHandler.get());
+ TaskwaitHandler.reset();
+ PP.RemovePragmaHandler("omp", AtomicHandler.get());
+ AtomicHandler.reset();
+ PP.RemovePragmaHandler("omp", FlushHandler.get());
+ FlushHandler.reset();
+ PP.RemovePragmaHandler("omp", OrderedHandler.get());
+ OrderedHandler.reset();
+
+ // OpenMP data environment related constructs.
+ PP.RemovePragmaHandler("omp", ThreadPrivateHandler.get());
+ ThreadPrivateHandler.reset();
+}
+
namespace {
/// \brief A comment handler that passes comments found by the preprocessor
/// to the parser action.
@@ -98,6 +329,8 @@
PP.addCommentHandler(CommentSemaHandler.get());
PP.setCodeCompletionHandler(*this);
+
+ OpenMPHandler.reset(new OpenMP(pp));
}
/// If a crash happens while the parser is active, print out a line indicating
@@ -456,6 +689,8 @@
PP.clearCodeCompletionHandler();
+ OpenMPHandler.reset();
+
assert(TemplateIds.empty() && "Still alive TemplateIdAnnotations around?");
}
Added: cfe/trunk/test/Preprocessor/pragma_omp.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Preprocessor/pragma_omp.c?rev=166869&view=auto
==============================================================================
--- cfe/trunk/test/Preprocessor/pragma_omp.c (added)
+++ cfe/trunk/test/Preprocessor/pragma_omp.c Sat Oct 27 04:05:45 2012
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -E -verify %s
+// RUN: %clang_cc1 -E -verify -fopenmp %s
+// RUN: %clang_cc1 -Eonly -verify %s
+// RUN: %clang_cc1 -Eonly -verify -fopenmp %s
+// RUN: %clang_cc1 -E -P -verify %s
+// RUN: %clang_cc1 -E -P -verify -fopenmp %s
+
+int pragma_omp_test() {
+ int i, VarA;
+ #pragma omp parallel // expected-no-diagnostics
+ {
+ #pragma omp for // expected-no-diagnostics
+ for(i=0; i<10; i++) {
+ VarA = 29;
+ }
+ }
+ return VarA;
+}
Added: cfe/trunk/test/Preprocessor/pragma_omp_ignored_warning.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Preprocessor/pragma_omp_ignored_warning.c?rev=166869&view=auto
==============================================================================
--- cfe/trunk/test/Preprocessor/pragma_omp_ignored_warning.c (added)
+++ cfe/trunk/test/Preprocessor/pragma_omp_ignored_warning.c Sat Oct 27 04:05:45 2012
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+int pragma_omp_ignored_warning_test() {
+ int i, VarA;
+ #pragma omp parallel // expected-warning {{pragma omp ignored; did you forget to add '-fopenmp' flag?}}
+ {
+ #pragma omp for
+ for(i=0; i<10; i++) {
+ VarA = 29;
+ }
+ }
+ return VarA;
+}
More information about the cfe-commits
mailing list