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