r192531 - Callback support for OpenCL extension pragmas.

Pekka Jaaskelainen pekka.jaaskelainen at tut.fi
Sat Oct 12 02:29:48 PDT 2013


Author: pjaaskel
Date: Sat Oct 12 04:29:48 2013
New Revision: 192531

URL: http://llvm.org/viewvc/llvm-project?rev=192531&view=rev
Log:
Callback support for OpenCL extension pragmas.

Patch from Rami Ylimäki and Mikael Lepistö!


Modified:
    cfe/trunk/include/clang/Lex/PPCallbacks.h
    cfe/trunk/lib/Parse/ParsePragma.cpp
    cfe/trunk/unittests/Lex/CMakeLists.txt
    cfe/trunk/unittests/Lex/Makefile
    cfe/trunk/unittests/Lex/PPCallbacksTest.cpp

Modified: cfe/trunk/include/clang/Lex/PPCallbacks.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/PPCallbacks.h?rev=192531&r1=192530&r2=192531&view=diff
==============================================================================
--- cfe/trunk/include/clang/Lex/PPCallbacks.h (original)
+++ cfe/trunk/include/clang/Lex/PPCallbacks.h Sat Oct 12 04:29:48 2013
@@ -217,6 +217,13 @@ public:
                                 diag::Mapping mapping, StringRef Str) {
   }
 
+  /// \brief Called when an OpenCL extension is either disabled or
+  /// enabled with a pragma.
+  virtual void PragmaOpenCLExtension(SourceLocation NameLoc, 
+                                     const IdentifierInfo *Name,
+                                     SourceLocation StateLoc, unsigned State) {
+  }
+
   /// \brief Callback invoked when a \#pragma warning directive is read.
   virtual void PragmaWarning(SourceLocation Loc, StringRef WarningSpec,
                              ArrayRef<int> Ids) {
@@ -413,6 +420,13 @@ public:
     Second->PragmaDiagnostic(Loc, Namespace, mapping, Str);
   }
 
+  virtual void PragmaOpenCLExtension(SourceLocation NameLoc, 
+                                     const IdentifierInfo *Name,
+                                     SourceLocation StateLoc, unsigned State) {
+    First->PragmaOpenCLExtension(NameLoc, Name, StateLoc, State);
+    Second->PragmaOpenCLExtension(NameLoc, Name, StateLoc, State);
+  }
+
   virtual void PragmaWarning(SourceLocation Loc, StringRef WarningSpec,
                              ArrayRef<int> Ids) {
     First->PragmaWarning(Loc, WarningSpec, Ids);

Modified: cfe/trunk/lib/Parse/ParsePragma.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParsePragma.cpp?rev=192531&r1=192530&r2=192531&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParsePragma.cpp (original)
+++ cfe/trunk/lib/Parse/ParsePragma.cpp Sat Oct 12 04:29:48 2013
@@ -728,6 +728,7 @@ PragmaOpenCLExtensionHandler::HandlePrag
     PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_enable_disable);
     return;
   }
+  SourceLocation StateLoc = Tok.getLocation();
 
   PP.Lex(Tok);
   if (Tok.isNot(tok::eod)) {
@@ -747,6 +748,10 @@ PragmaOpenCLExtensionHandler::HandlePrag
   Toks[0].setAnnotationValue(data.getOpaqueValue());
   PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true,
                       /*OwnsTokens=*/false);
+
+  if (PP.getPPCallbacks())
+    PP.getPPCallbacks()->PragmaOpenCLExtension(NameLoc, ename, 
+                                               StateLoc, state);
 }
 
 /// \brief Handle '#pragma omp ...' when OpenMP is disabled.

Modified: cfe/trunk/unittests/Lex/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Lex/CMakeLists.txt?rev=192531&r1=192530&r2=192531&view=diff
==============================================================================
--- cfe/trunk/unittests/Lex/CMakeLists.txt (original)
+++ cfe/trunk/unittests/Lex/CMakeLists.txt Sat Oct 12 04:29:48 2013
@@ -5,5 +5,5 @@ add_clang_unittest(LexTests
   )
 
 target_link_libraries(LexTests
-  clangLex
+  clangLex clangParse clangSema
   )

Modified: cfe/trunk/unittests/Lex/Makefile
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Lex/Makefile?rev=192531&r1=192530&r2=192531&view=diff
==============================================================================
--- cfe/trunk/unittests/Lex/Makefile (original)
+++ cfe/trunk/unittests/Lex/Makefile Sat Oct 12 04:29:48 2013
@@ -9,7 +9,8 @@
 
 CLANG_LEVEL = ../..
 TESTNAME = Lex
-LINK_COMPONENTS := support mc
-USEDLIBS = clangLex.a clangBasic.a
+LINK_COMPONENTS := mcparser support mc
+USEDLIBS = clangParse.a clangSema.a clangAnalysis.a clangEdit.a \
+	clangAST.a clangLex.a clangBasic.a 
 
 include $(CLANG_LEVEL)/unittests/Makefile

Modified: cfe/trunk/unittests/Lex/PPCallbacksTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Lex/PPCallbacksTest.cpp?rev=192531&r1=192530&r2=192531&view=diff
==============================================================================
--- cfe/trunk/unittests/Lex/PPCallbacksTest.cpp (original)
+++ cfe/trunk/unittests/Lex/PPCallbacksTest.cpp Sat Oct 12 04:29:48 2013
@@ -18,6 +18,10 @@
 #include "clang/Lex/HeaderSearchOptions.h"
 #include "clang/Lex/ModuleLoader.h"
 #include "clang/Lex/PreprocessorOptions.h"
+#include "clang/Parse/Parser.h"
+#include "clang/Sema/Sema.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/ASTConsumer.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/Support/Path.h"
 #include "gtest/gtest.h"
@@ -77,6 +81,31 @@ public:
   const Module* Imported;
 };
 
+// Stub to collect data from PragmaOpenCLExtension callbacks.
+class PragmaOpenCLExtensionCallbacks : public PPCallbacks {
+public:
+  typedef struct {
+    StringRef Name;
+    unsigned State;
+  } CallbackParameters;
+
+  PragmaOpenCLExtensionCallbacks() : Name("Not called."), State(99) {};
+
+  void PragmaOpenCLExtension(
+    clang::SourceLocation NameLoc, const clang::IdentifierInfo *Name,
+    clang::SourceLocation StateLoc, unsigned State) {
+      this->NameLoc = NameLoc;
+      this->Name = Name->getName().str();
+      this->StateLoc = StateLoc;
+      this->State = State;
+  };
+
+  SourceLocation NameLoc;
+  StringRef Name;
+  SourceLocation StateLoc;
+  unsigned State;
+};
+
 // PPCallbacks test fixture.
 class PPCallbacksTest : public ::testing::Test {
 protected:
@@ -159,6 +188,53 @@ protected:
     // Callbacks have been executed at this point -- return filename range.
     return Callbacks->FilenameRange;
   }
+
+  PragmaOpenCLExtensionCallbacks::CallbackParameters 
+  PragmaOpenCLExtensionCall(const char* SourceText) {
+    LangOptions OpenCLLangOpts;
+    OpenCLLangOpts.OpenCL = 1;
+
+    MemoryBuffer* sourceBuf = MemoryBuffer::getMemBuffer(SourceText, "test.cl");
+    (void)SourceMgr.createMainFileIDForMemBuffer(sourceBuf);
+
+    VoidModuleLoader ModLoader;
+    HeaderSearch HeaderInfo(new HeaderSearchOptions, FileMgr, Diags, 
+                            OpenCLLangOpts, Target.getPtr());
+
+    Preprocessor PP(new PreprocessorOptions(), Diags, OpenCLLangOpts, 
+                    Target.getPtr(),
+                    SourceMgr, HeaderInfo, ModLoader,
+                   /*IILookup =*/ 0,
+                    /*OwnsHeaderSearch =*/false,
+                    /*DelayInitialization =*/ false);
+
+    // parser actually sets correct pragma handlers for preprocessor
+    // according to LangOptions, so we init Parser to register opencl
+    // pragma handlers
+    ASTContext Context(OpenCLLangOpts, SourceMgr, Target.getPtr(), 
+                       PP.getIdentifierTable(), PP.getSelectorTable(), 
+                       PP.getBuiltinInfo(), 0);    
+    ASTConsumer Consumer;
+    Sema S(PP, Context, Consumer);
+    Parser P(PP, S, false);
+    PragmaOpenCLExtensionCallbacks* Callbacks = new PragmaOpenCLExtensionCallbacks;
+    PP.addPPCallbacks(Callbacks); // Takes ownership.
+
+    // Lex source text.
+    PP.EnterMainSourceFile();
+    while (true) {
+      Token Tok;
+      PP.Lex(Tok);
+      if (Tok.is(tok::eof))
+        break;
+    }
+
+    PragmaOpenCLExtensionCallbacks::CallbackParameters RetVal = {
+      Callbacks->Name.str(),
+      Callbacks->State
+    };
+    return RetVal;    
+  }
 };
 
 TEST_F(PPCallbacksTest, QuotedFilename) {
@@ -247,4 +323,28 @@ TEST_F(PPCallbacksTest, TrigraphInMacro)
   ASSERT_EQ("\"tri\?\?-graph.h\"", GetSourceString(Range));
 }
 
+TEST_F(PPCallbacksTest, OpenCLExtensionPragmaEnabled) {
+  const char* Source =
+    "#pragma OPENCL EXTENSION cl_khr_fp64 : enable\n";
+
+  PragmaOpenCLExtensionCallbacks::CallbackParameters Parameters =
+    PragmaOpenCLExtensionCall(Source);
+
+  ASSERT_EQ("cl_khr_fp64", Parameters.Name);
+  unsigned ExpectedState = 1;
+  ASSERT_EQ(ExpectedState, Parameters.State);
+}
+
+TEST_F(PPCallbacksTest, OpenCLExtensionPragmaDisabled) {
+  const char* Source =
+    "#pragma OPENCL EXTENSION cl_khr_fp16 : disable\n";
+
+  PragmaOpenCLExtensionCallbacks::CallbackParameters Parameters =
+    PragmaOpenCLExtensionCall(Source);
+
+  ASSERT_EQ("cl_khr_fp16", Parameters.Name);
+  unsigned ExpectedState = 0;
+  ASSERT_EQ(ExpectedState, Parameters.State);
+}
+
 } // anonoymous namespace





More information about the cfe-commits mailing list