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(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); }