Remove leaking UnknownPragmaHandlers right after we are done with them.

The UnknownPragmaHandlers added by 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.

Patch by Raphael Isemann (D32486)!

llvm-svn: 301563
diff --git a/clang/lib/Frontend/PrintPreprocessedOutput.cpp b/clang/lib/Frontend/PrintPreprocessedOutput.cpp
index 3168b3d..42d609c 100644
--- a/clang/lib/Frontend/PrintPreprocessedOutput.cpp
+++ b/clang/lib/Frontend/PrintPreprocessedOutput.cpp
@@ -775,26 +775,33 @@
 
   // 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,
+  // Remember the handlers we will add so that we can remove them later.
+  std::unique_ptr<UnknownPragmaHandler> MicrosoftExtHandler(
+      new UnknownPragmaHandler(
+          "#pragma", Callbacks,
+          /*RequireTokenExpansion=*/PP.getLangOpts().MicrosoftExt));
+
+  std::unique_ptr<UnknownPragmaHandler> GCCHandler(new UnknownPragmaHandler(
+      "#pragma GCC", 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));
+
+  std::unique_ptr<UnknownPragmaHandler> ClangHandler(new UnknownPragmaHandler(
+      "#pragma clang", Callbacks,
+      /*RequireTokenExpansion=*/PP.getLangOpts().MicrosoftExt));
+
+  PP.AddPragmaHandler(MicrosoftExtHandler.get());
+  PP.AddPragmaHandler("GCC", GCCHandler.get());
+  PP.AddPragmaHandler("clang", ClangHandler.get());
 
   // 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));
+  std::unique_ptr<UnknownPragmaHandler> OpenMPHandler(
+      new UnknownPragmaHandler("#pragma omp", Callbacks,
+                               /*RequireTokenExpansion=*/true));
+  PP.AddPragmaHandler("omp", OpenMPHandler.get());
 
   PP.addPPCallbacks(std::unique_ptr<PPCallbacks>(Callbacks));
 
@@ -822,4 +829,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.get());
+  PP.RemovePragmaHandler("GCC", GCCHandler.get());
+  PP.RemovePragmaHandler("clang", ClangHandler.get());
+  PP.RemovePragmaHandler("omp", OpenMPHandler.get());
 }