teemperor created this revision.

The UnknownPragmaHandlers added by t`DoPrintPreprocessedInput` conflict with 
the real PragmaHandlers from clang::Parser because they try to handle the same 
`#pragma` directives. This makes it impossible to use a Preprocessor (that was 
previously passed to DoPrintPreprocessedInput), as an Preprocessor for a 
`clang::Parser` instance which is what we currently do in cling. This patch 
removes the added UnknownPragmaHandler to avoid conflicts these conflicts and 
leave the PragmaHandlers of the Preprocessors in a the same state as before 
calling `DoPrintPreprocessedInput`.


https://reviews.llvm.org/D32486

Files:
  lib/Frontend/PrintPreprocessedOutput.cpp


Index: lib/Frontend/PrintPreprocessedOutput.cpp
===================================================================
--- lib/Frontend/PrintPreprocessedOutput.cpp
+++ lib/Frontend/PrintPreprocessedOutput.cpp
@@ -771,27 +771,37 @@
       PP, *OS, !Opts.ShowLineMarkers, Opts.ShowMacros,
       Opts.ShowIncludeDirectives, Opts.UseLineDirectives);
 
+  // Remember the handlers we will add so that we can remove them later.
+  UnknownPragmaHandler *MicrosoftExtHandler;
+  UnknownPragmaHandler *GCCHandler;
+  UnknownPragmaHandler *ClangHandler;
+  UnknownPragmaHandler *OpenMPHandler;
+
   // 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));
+      MicrosoftExtHandler = new UnknownPragmaHandler(
+          "#pragma", Callbacks,
+          /*RequireTokenExpansion=*/PP.getLangOpts().MicrosoftExt));
+  PP.AddPragmaHandler(
+      "GCC",
+      GCCHandler = new UnknownPragmaHandler(
+          "#pragma GCC", Callbacks,
+          /*RequireTokenExpansion=*/PP.getLangOpts().MicrosoftExt));
   PP.AddPragmaHandler(
-      "clang", new UnknownPragmaHandler(
-                   "#pragma clang", Callbacks,
-                   /*RequireTokenExpansion=*/PP.getLangOpts().MicrosoftExt));
+      "clang",
+      ClangHandler = 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,
+  PP.AddPragmaHandler(
+      "omp",
+      OpenMPHandler = new UnknownPragmaHandler("#pragma omp", Callbacks,
                                                
/*RequireTokenExpansion=*/true));
 
   PP.addPPCallbacks(std::unique_ptr<PPCallbacks>(Callbacks));
@@ -820,4 +830,11 @@
   // Read all the preprocessed tokens, printing them out to the stream.
   PrintPreprocessedTokens(PP, Tok, Callbacks, *OS);
   *OS << '\n';
+
+  // Remove the handlers we just added to leave the preprocessor in a sane 
state
+  // so that it can be reused (for example by a clang::Parser instance).
+  PP.RemovePragmaHandler(MicrosoftExtHandler);
+  PP.RemovePragmaHandler("GCC", GCCHandler);
+  PP.RemovePragmaHandler("clang", ClangHandler);
+  PP.RemovePragmaHandler("omp", OpenMPHandler);
 }


Index: lib/Frontend/PrintPreprocessedOutput.cpp
===================================================================
--- lib/Frontend/PrintPreprocessedOutput.cpp
+++ lib/Frontend/PrintPreprocessedOutput.cpp
@@ -771,27 +771,37 @@
       PP, *OS, !Opts.ShowLineMarkers, Opts.ShowMacros,
       Opts.ShowIncludeDirectives, Opts.UseLineDirectives);
 
+  // Remember the handlers we will add so that we can remove them later.
+  UnknownPragmaHandler *MicrosoftExtHandler;
+  UnknownPragmaHandler *GCCHandler;
+  UnknownPragmaHandler *ClangHandler;
+  UnknownPragmaHandler *OpenMPHandler;
+
   // 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));
+      MicrosoftExtHandler = new UnknownPragmaHandler(
+          "#pragma", Callbacks,
+          /*RequireTokenExpansion=*/PP.getLangOpts().MicrosoftExt));
+  PP.AddPragmaHandler(
+      "GCC",
+      GCCHandler = new UnknownPragmaHandler(
+          "#pragma GCC", Callbacks,
+          /*RequireTokenExpansion=*/PP.getLangOpts().MicrosoftExt));
   PP.AddPragmaHandler(
-      "clang", new UnknownPragmaHandler(
-                   "#pragma clang", Callbacks,
-                   /*RequireTokenExpansion=*/PP.getLangOpts().MicrosoftExt));
+      "clang",
+      ClangHandler = 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,
+  PP.AddPragmaHandler(
+      "omp",
+      OpenMPHandler = new UnknownPragmaHandler("#pragma omp", Callbacks,
                                                /*RequireTokenExpansion=*/true));
 
   PP.addPPCallbacks(std::unique_ptr<PPCallbacks>(Callbacks));
@@ -820,4 +830,11 @@
   // Read all the preprocessed tokens, printing them out to the stream.
   PrintPreprocessedTokens(PP, Tok, Callbacks, *OS);
   *OS << '\n';
+
+  // Remove the handlers we just added to leave the preprocessor in a sane state
+  // so that it can be reused (for example by a clang::Parser instance).
+  PP.RemovePragmaHandler(MicrosoftExtHandler);
+  PP.RemovePragmaHandler("GCC", GCCHandler);
+  PP.RemovePragmaHandler("clang", ClangHandler);
+  PP.RemovePragmaHandler("omp", OpenMPHandler);
 }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to