Index: include/clang/Lex/Preprocessor.h
===================================================================
--- include/clang/Lex/Preprocessor.h	(revision 166176)
+++ include/clang/Lex/Preprocessor.h	(working copy)
@@ -161,6 +161,13 @@
   /// \brief True if we are pre-expanding macro arguments.
   bool InMacroArgPreExpansion;
 
+  /// \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 PragmaOmpUnknownWarning;
+
   /// Identifiers - This is mapping/lookup information for all identifiers in
   /// the program, including program keywords.
   mutable IdentifierTable Identifiers;
@@ -1387,6 +1394,7 @@
   void HandlePragmaPushMacro(Token &Tok);
   void HandlePragmaPopMacro(Token &Tok);
   void HandlePragmaIncludeAlias(Token &Tok);
+  void HandlePragmaOmp(Token &Tok, tok::TokenKind TKind);
   IdentifierInfo *ParsePragmaPushOrPopMacro(Token &Tok);
 
   // Return true and store the first token only if any CommentHandler
@@ -1396,6 +1404,14 @@
   /// \brief A macro is used, update information about macros that need unused
   /// warnings.
   void markMacroAsUsed(MacroInfo *MI);
+
+  /// \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 SetPragmaOmpUnknownWarning() { PragmaOmpUnknownWarning = true; }
+  void ResetPragmaOmpUnknownWarning() { PragmaOmpUnknownWarning = false; }
+  bool GetPragmaOmpUnknownWarning() { return PragmaOmpUnknownWarning; }
+
 };
 
 /// \brief Abstract base class that describes a handler that will receive
Index: lib/Lex/Preprocessor.cpp
===================================================================
--- lib/Lex/Preprocessor.cpp	(revision 166176)
+++ lib/Lex/Preprocessor.cpp	(working copy)
@@ -103,6 +103,10 @@
   // This gets unpoisoned where it is allowed.
   (Ident__VA_ARGS__ = getIdentifierInfo("__VA_ARGS__"))->setIsPoisoned();
   SetPoisonReason(Ident__VA_ARGS__,diag::ext_pp_bad_vaargs_use);
+
+  // We have not yet reported the unknown OpenMP pragma *warning* message as we
+  // have not yet started the processing of translation unit.
+  ResetPragmaOmpUnknownWarning();
   
   // Initialize the pragma handlers.
   PragmaHandlers = new PragmaNamespace(StringRef());
Index: lib/Lex/Pragma.cpp
===================================================================
--- lib/Lex/Pragma.cpp	(revision 166176)
+++ lib/Lex/Pragma.cpp	(working copy)
@@ -865,6 +865,32 @@
   getHeaderSearchInfo().AddIncludeAlias(OriginalSource, ReplaceFileName);
 }
 
+/// Handle "\#pragma omp ...".
+///
+/// \brief Check if user has passed the flag, '-fopenmp', if so, enter 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, report 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 Preprocessor::HandlePragmaOmp(Token &Tok, tok::TokenKind TKind) {
+  if (!getLangOpts().OpenMP) {
+    if (!GetPragmaOmpUnknownWarning()) {
+      Diag(Tok, diag::omp_pragma_ignored);
+      SetPragmaOmpUnknownWarning();
+    }
+  } else {
+    Token *Toks = new Token[1];
+    Toks[0].startToken();
+    Toks[0].setKind(TKind);
+    Toks[0].setLocation(Tok.getLocation());
+    EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true,
+                     /*OwnsTokens=*/false);
+  }
+}
+
 /// AddPragmaHandler - Add the specified pragma handler to the preprocessor.
 /// If 'Namespace' is non-null, then it is a token required to exist on the
 /// pragma line before the pragma string starts, e.g. "STDC" or "GCC".
@@ -1278,6 +1304,76 @@
   }
 };
 
+/// OmpParallel - "\#pragma omp parallel ...".
+struct OmpParallel { static const char* Name; };
+const char* OmpParallel::Name = "parallel";
+
+/// OmpFor - "\#pragam omp for ...".
+struct OmpFor { static const char* Name; };
+const char* OmpFor::Name = "for";
+
+/// OmpSections - "\#pragma omp sections ...".
+struct OmpSections { static const char* Name; };
+const char* OmpSections::Name = "sections";
+
+/// OmpSection - "\#pragma omp section".
+struct OmpSection { static const char* Name; };
+const char* OmpSection::Name = "section";
+
+/// OmpSingle - "\#pragma omp single ...".
+struct OmpSingle { static const char* Name; };
+const char* OmpSingle::Name = "single";
+
+/// OmpTask - "\#pragma omp task ...".
+struct OmpTask { static const char* Name; };
+const char* OmpTask::Name = "task";
+
+/// OmpMaster - "\#pragma omp master".
+struct OmpMaster { static const char* Name; };
+const char* OmpMaster::Name = "master";
+
+/// OmpCritical - "\#pragma omp critical ...".
+struct OmpCritical { static const char* Name; };
+const char* OmpCritical::Name = "critical";
+
+/// OmpBarrier - "\#pragma omp barrier".
+struct OmpBarrier { static const char* Name; };
+const char* OmpBarrier::Name = "barrier";
+
+/// OmpTaskwait - "\#pragma omp taskwait".
+struct OmpTaskwait { static const char* Name; };
+const char* OmpTaskwait::Name = "taskwait";
+
+/// OmpTaskyield - "\#pragma omp taskyield".
+struct OmpTaskyield { static const char* Name; };
+const char* OmpTaskyield::Name = "taskyield";
+
+/// OmpAtomic - "\#pragma omp atomic ...".
+struct OmpAtomic { static const char* Name; };
+const char* OmpAtomic::Name = "atomic";
+
+/// OmpFlush - "\#pragma omp flush ...".
+struct OmpFlush { static const char* Name; };
+const char* OmpFlush::Name = "flush";
+
+/// OmpOrdered - "\#pragma omp ordered".
+struct OmpOrdered { static const char* Name; };
+const char* OmpOrdered::Name = "ordered";
+
+/// OmpThreadprivate - "\#pragma omp threadprivate ...".
+struct OmpThreadprivate { static const char* Name; };
+const char* OmpThreadprivate::Name = "threadprivate";
+
+/// PragmaOmpHandler - "\#pragma omp ...".
+template<class T, tok::TokenKind TKind>
+struct PragmaOmpHandler : public PragmaHandler {
+  PragmaOmpHandler() : PragmaHandler(T::Name) {}
+  virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
+                            Token &OmpTok) {
+    PP.HandlePragmaOmp(OmpTok, TKind);
+  }
+};
+
 }  // end anonymous namespace
 
 
@@ -1312,4 +1408,36 @@
     AddPragmaHandler(new PragmaCommentHandler());
     AddPragmaHandler(new PragmaIncludeAliasHandler());
   }
+
+  // \#pragma omp ...
+  AddPragmaHandler("omp", new PragmaOmpHandler<
+                    OmpParallel, tok::pragma_omp_parallel>());
+  AddPragmaHandler("omp", new PragmaOmpHandler<
+                    OmpFor, tok::pragma_omp_for>());
+  AddPragmaHandler("omp", new PragmaOmpHandler<
+                    OmpSections, tok::pragma_omp_sections >());
+  AddPragmaHandler("omp", new PragmaOmpHandler<
+                    OmpSection, tok::pragma_omp_section>());
+  AddPragmaHandler("omp", new PragmaOmpHandler<
+                    OmpSingle, tok::pragma_omp_single>());
+  AddPragmaHandler("omp", new PragmaOmpHandler<
+                    OmpTask, tok::pragma_omp_task>());
+  AddPragmaHandler("omp", new PragmaOmpHandler<
+                    OmpMaster, tok::pragma_omp_master>());
+  AddPragmaHandler("omp", new PragmaOmpHandler<
+                    OmpCritical, tok::pragma_omp_critical>());
+  AddPragmaHandler("omp", new PragmaOmpHandler<
+                    OmpBarrier, tok::pragma_omp_barrier>());
+  AddPragmaHandler("omp", new PragmaOmpHandler<
+                    OmpTaskwait, tok::pragma_omp_taskwait>());
+  AddPragmaHandler("omp", new PragmaOmpHandler<
+                    OmpTaskyield, tok::pragma_omp_taskyield>());
+  AddPragmaHandler("omp", new PragmaOmpHandler<
+                    OmpAtomic, tok::pragma_omp_atomic>());
+  AddPragmaHandler("omp", new PragmaOmpHandler<
+                    OmpFlush, tok::pragma_omp_flush>());
+  AddPragmaHandler("omp", new PragmaOmpHandler<
+                    OmpOrdered, tok::pragma_omp_ordered>());
+  AddPragmaHandler("omp", new PragmaOmpHandler<
+                    OmpThreadprivate, tok::pragma_omp_threadprivate>());
 }
Index: include/clang/Basic/DiagnosticLexKinds.td
===================================================================
--- include/clang/Basic/DiagnosticLexKinds.td	(revision 166176)
+++ include/clang/Basic/DiagnosticLexKinds.td	(working copy)
@@ -518,4 +518,7 @@
 def err_expected_id_building_module : Error<
   "expected a module name in '__building_module' expression">;
   
+def omp_pragma_ignored : Warning<
+  "omp pragma ignored; did you forget to add '-fopenmp' flag?">,
+   InGroup<UnknownPragmas>;
 }
Index: test/Preprocessor/pragma_omp_ignored_warning.c
===================================================================
--- test/Preprocessor/pragma_omp_ignored_warning.c	(revision 0)
+++ test/Preprocessor/pragma_omp_ignored_warning.c	(revision 0)
@@ -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 {{omp pragma ignored; did you forget to add '-fopenmp' flag?}}
+  {
+    #pragma omp for  // no warning will be emitted here as it is already emitted.
+    for(i=0; i<10; i++) {
+      VarA = 29;
+    }
+  }
+  return VarA;
+}
