From 4095080aff204008eefb26b100906c6ca2bc4bb6 Mon Sep 17 00:00:00 2001
From: Daniel Dunbar <daniel@zuster.org>
Date: Sat, 4 Oct 2008 19:17:46 +0000
Subject: [PATCH] Add Preprocessor::RemovePragmaHandler.  - No functionality
 change.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@57065 91177308-0d34-0410-b5e6-96231b3b80d8
---
 include/clang/Lex/Pragma.h       |  8 +++++++
 include/clang/Lex/Preprocessor.h |  6 ++++++
 lib/Lex/Pragma.cpp               | 37 ++++++++++++++++++++++++++++++++
 3 files changed, 51 insertions(+)

diff --git a/include/clang/Lex/Pragma.h b/include/clang/Lex/Pragma.h
index 20c5c5872eb..136dc6fabfb 100644
--- a/include/clang/Lex/Pragma.h
+++ b/include/clang/Lex/Pragma.h
@@ -71,6 +71,14 @@ public:
     Handlers.push_back(Handler);
   }
 
+  /// RemovePragmaHandler - Remove the given handler from the
+  /// namespace.
+  void RemovePragmaHandler(PragmaHandler *Handler);
+
+  bool IsEmpty() { 
+    return Handlers.empty(); 
+  }
+
   virtual void HandlePragma(Preprocessor &PP, Token &FirstToken);
   
   virtual PragmaNamespace *getIfNamespace() { return this; }
diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h
index 96a4153acfa..4c8fa67e943 100644
--- a/include/clang/Lex/Preprocessor.h
+++ b/include/clang/Lex/Preprocessor.h
@@ -242,6 +242,12 @@ public:
   /// pragma line before the pragma string starts, e.g. "STDC" or "GCC".
   void AddPragmaHandler(const char *Namespace, PragmaHandler *Handler);
 
+  /// RemovePragmaHandler - Remove the specific pragma handler from
+  /// the preprocessor. If \arg Namespace is non-null, then it should
+  /// be the namespace that \arg Handler was added to. It is an error
+  /// to remove a handler that has not been registered.
+  void RemovePragmaHandler(const char *Namespace, PragmaHandler *Handler);
+
   /// EnterMainSourceFile - Enter the specified FileID as the main source file,
   /// which implicitly adds the builtin defines etc.
   void EnterMainSourceFile();  
diff --git a/lib/Lex/Pragma.cpp b/lib/Lex/Pragma.cpp
index b6f5ac49360..6d8e047056d 100644
--- a/lib/Lex/Pragma.cpp
+++ b/lib/Lex/Pragma.cpp
@@ -51,6 +51,17 @@ PragmaHandler *PragmaNamespace::FindHandler(const IdentifierInfo *Name,
   return IgnoreNull ? 0 : NullHandler;
 }
 
+void PragmaNamespace::RemovePragmaHandler(PragmaHandler *Handler) {
+  for (unsigned i = 0, e = Handlers.size(); i != e; ++i) {
+    if (Handlers[i] == Handler) {
+      Handlers[i] = Handlers.back();
+      Handlers.pop_back();
+      return;
+    }
+  }
+  assert(0 && "Handler not registered in this namespace");
+}
+
 void PragmaNamespace::HandlePragma(Preprocessor &PP, Token &Tok) {
   // Read the 'namespace' that the directive is in, e.g. STDC.  Do not macro
   // expand it, the user can have a STDC #define, that should not affect this.
@@ -325,6 +336,32 @@ void Preprocessor::AddPragmaHandler(const char *Namespace,
   InsertNS->AddPragma(Handler);
 }
 
+/// RemovePragmaHandler - Remove the specific pragma handler from the
+/// preprocessor. If \arg Namespace is non-null, then it should be the
+/// namespace that \arg Handler was added to. It is an error to remove
+/// a handler that has not been registered.
+void Preprocessor::RemovePragmaHandler(const char *Namespace,
+                                       PragmaHandler *Handler) {
+  PragmaNamespace *NS = PragmaHandlers;
+  
+  // If this is specified to be in a namespace, step down into it.
+  if (Namespace) {
+    IdentifierInfo *NSID = getIdentifierInfo(Namespace);
+    PragmaHandler *Existing = PragmaHandlers->FindHandler(NSID);
+    assert(Existing && "Namespace containing handler does not exist!");
+
+    NS = Existing->getIfNamespace();
+    assert(NS && "Invalid namespace, registered as a regular pragma handler!");
+  }
+
+  NS->RemovePragmaHandler(Handler);
+  
+  // If this is a non-default namespace and it is now empty, remove
+  // it.
+  if (NS != PragmaHandlers && NS->IsEmpty())
+    PragmaHandlers->RemovePragmaHandler(NS);
+}
+
 namespace {
 /// PragmaOnceHandler - "#pragma once" marks the file as atomically included.
 struct PragmaOnceHandler : public PragmaHandler {
-- 
GitLab