aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/Lex/Preprocessor.h6
-rw-r--r--lib/Lex/Pragma.cpp3
-rw-r--r--lib/Lex/Preprocessor.cpp3
-rw-r--r--lib/Rewrite/HTMLRewrite.cpp8
-rw-r--r--test/Misc/emit-html.c8
5 files changed, 26 insertions, 2 deletions
diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h
index 6589f84c93..0dd9477e92 100644
--- a/include/clang/Lex/Preprocessor.h
+++ b/include/clang/Lex/Preprocessor.h
@@ -131,6 +131,9 @@ class Preprocessor : public RefCountedBase<Preprocessor> {
/// \brief Whether we have already loaded macros from the external source.
mutable bool ReadMacrosFromExternalSource : 1;
+ /// \brief True if pragmas are enabled.
+ bool PragmasEnabled : 1;
+
/// \brief True if we are pre-expanding macro arguments.
bool InMacroArgPreExpansion;
@@ -416,6 +419,9 @@ public:
bool getCommentRetentionState() const { return KeepComments; }
+ void setPragmasEnabled(bool Enabled) { PragmasEnabled = Enabled; }
+ bool getPragmasEnabled() const { return PragmasEnabled; }
+
void SetSuppressIncludeNotFoundError(bool Suppress) {
SuppressIncludeNotFoundError = Suppress;
}
diff --git a/lib/Lex/Pragma.cpp b/lib/Lex/Pragma.cpp
index e2a192b01f..d678ce5d7f 100644
--- a/lib/Lex/Pragma.cpp
+++ b/lib/Lex/Pragma.cpp
@@ -103,6 +103,9 @@ void PragmaNamespace::HandlePragma(Preprocessor &PP,
/// HandlePragmaDirective - The "#pragma" directive has been parsed. Lex the
/// rest of the pragma, passing it to the registered pragma handlers.
void Preprocessor::HandlePragmaDirective(unsigned Introducer) {
+ if (!PragmasEnabled)
+ return;
+
++NumPragma;
// Invoke the first level of pragma handlers which reads the namespace id.
diff --git a/lib/Lex/Preprocessor.cpp b/lib/Lex/Preprocessor.cpp
index 4be59c65f7..b420c6cd1d 100644
--- a/lib/Lex/Preprocessor.cpp
+++ b/lib/Lex/Preprocessor.cpp
@@ -90,7 +90,8 @@ Preprocessor::Preprocessor(DiagnosticsEngine &diags, LangOptions &opts,
InMacroArgs = false;
InMacroArgPreExpansion = false;
NumCachedTokenLexers = 0;
-
+ PragmasEnabled = true;
+
CachedLexPos = 0;
// We haven't read anything from the external source.
diff --git a/lib/Rewrite/HTMLRewrite.cpp b/lib/Rewrite/HTMLRewrite.cpp
index dc39dde7ff..e2da26fc80 100644
--- a/lib/Rewrite/HTMLRewrite.cpp
+++ b/lib/Rewrite/HTMLRewrite.cpp
@@ -495,6 +495,11 @@ void html::HighlightMacros(Rewriter &R, FileID FID, const Preprocessor& PP) {
// Inform the preprocessor that we don't want comments.
TmpPP.SetCommentRetentionState(false, false);
+ // We don't want pragmas either. Although we filtered out #pragma, removing
+ // _Pragma and __pragma is much harder.
+ bool PragmasPreviouslyEnabled = TmpPP.getPragmasEnabled();
+ TmpPP.setPragmasEnabled(false);
+
// Enter the tokens we just lexed. This will cause them to be macro expanded
// but won't enter sub-files (because we removed #'s).
TmpPP.EnterTokenStream(&TokenStream[0], TokenStream.size(), false, false);
@@ -571,6 +576,7 @@ void html::HighlightMacros(Rewriter &R, FileID FID, const Preprocessor& PP) {
"<span class='macro'>", Expansion.c_str());
}
- // Restore diagnostics object back to its own thing.
+ // Restore the preprocessor's old state.
TmpPP.setDiagnostics(*OldDiags);
+ TmpPP.setPragmasEnabled(PragmasPreviouslyEnabled);
}
diff --git a/test/Misc/emit-html.c b/test/Misc/emit-html.c
index 48c8b61b38..ec07a60a60 100644
--- a/test/Misc/emit-html.c
+++ b/test/Misc/emit-html.c
@@ -16,3 +16,11 @@ int main(int argc, char **argv) {
FOR_ALL_FILES(f) { }
#endif
+// <rdar://problem/11625964>
+// -emit-html filters out # directives, but not _Pragma (or MS __pragma)
+// Diagnostic push/pop is stateful, so re-lexing a file can cause problems
+// if these pragmas are interpreted normally.
+_Pragma("clang diagnostic push")
+_Pragma("clang diagnostic ignored \"-Wformat-extra-args\"")
+_Pragma("clang diagnostic pop")
+