diff options
Diffstat (limited to 'clang/lib/Lex/Pragma.cpp')
-rw-r--r-- | clang/lib/Lex/Pragma.cpp | 70 |
1 files changed, 40 insertions, 30 deletions
diff --git a/clang/lib/Lex/Pragma.cpp b/clang/lib/Lex/Pragma.cpp index e4636265a72bb..b512a547de7df 100644 --- a/clang/lib/Lex/Pragma.cpp +++ b/clang/lib/Lex/Pragma.cpp @@ -30,6 +30,7 @@ #include "clang/Lex/PPCallbacks.h" #include "clang/Lex/Preprocessor.h" #include "clang/Lex/PreprocessorLexer.h" +#include "clang/Lex/PreprocessorOptions.h" #include "clang/Lex/Token.h" #include "clang/Lex/TokenLexer.h" #include "llvm/ADT/ArrayRef.h" @@ -39,9 +40,9 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/ADT/StringRef.h" -#include "llvm/Support/CrashRecoveryContext.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/Timer.h" #include <algorithm> #include <cassert> #include <cstddef> @@ -70,31 +71,36 @@ void EmptyPragmaHandler::HandlePragma(Preprocessor &PP, // PragmaNamespace Implementation. //===----------------------------------------------------------------------===// -PragmaNamespace::~PragmaNamespace() { - llvm::DeleteContainerSeconds(Handlers); -} - /// FindHandler - Check to see if there is already a handler for the /// specified name. If not, return the handler for the null identifier if it /// exists, otherwise return null. If IgnoreNull is true (the default) then /// the null handler isn't returned on failure to match. PragmaHandler *PragmaNamespace::FindHandler(StringRef Name, bool IgnoreNull) const { - if (PragmaHandler *Handler = Handlers.lookup(Name)) - return Handler; - return IgnoreNull ? nullptr : Handlers.lookup(StringRef()); + auto I = Handlers.find(Name); + if (I != Handlers.end()) + return I->getValue().get(); + if (IgnoreNull) + return nullptr; + I = Handlers.find(StringRef()); + if (I != Handlers.end()) + return I->getValue().get(); + return nullptr; } void PragmaNamespace::AddPragma(PragmaHandler *Handler) { - assert(!Handlers.lookup(Handler->getName()) && + assert(!Handlers.count(Handler->getName()) && "A handler with this name is already registered in this namespace"); - Handlers[Handler->getName()] = Handler; + Handlers[Handler->getName()].reset(Handler); } void PragmaNamespace::RemovePragmaHandler(PragmaHandler *Handler) { - assert(Handlers.lookup(Handler->getName()) && + auto I = Handlers.find(Handler->getName()); + assert(I != Handlers.end() && "Handler not registered in this namespace"); - Handlers.erase(Handler->getName()); + // Release ownership back to the caller. + I->getValue().release(); + Handlers.erase(I); } void PragmaNamespace::HandlePragma(Preprocessor &PP, @@ -1035,15 +1041,21 @@ struct PragmaDebugHandler : public PragmaHandler { IdentifierInfo *II = Tok.getIdentifierInfo(); if (II->isStr("assert")) { - llvm_unreachable("This is an assertion!"); + if (!PP.getPreprocessorOpts().DisablePragmaDebugCrash) + llvm_unreachable("This is an assertion!"); } else if (II->isStr("crash")) { - LLVM_BUILTIN_TRAP; + llvm::Timer T("crash", "pragma crash"); + llvm::TimeRegion R(&T); + if (!PP.getPreprocessorOpts().DisablePragmaDebugCrash) + LLVM_BUILTIN_TRAP; } else if (II->isStr("parser_crash")) { - Token Crasher; - Crasher.startToken(); - Crasher.setKind(tok::annot_pragma_parser_crash); - Crasher.setAnnotationRange(SourceRange(Tok.getLocation())); - PP.EnterToken(Crasher, /*IsReinject*/false); + if (!PP.getPreprocessorOpts().DisablePragmaDebugCrash) { + Token Crasher; + Crasher.startToken(); + Crasher.setKind(tok::annot_pragma_parser_crash); + Crasher.setAnnotationRange(SourceRange(Tok.getLocation())); + PP.EnterToken(Crasher, /*IsReinject*/ false); + } } else if (II->isStr("dump")) { Token Identifier; PP.LexUnexpandedToken(Identifier); @@ -1075,9 +1087,11 @@ struct PragmaDebugHandler : public PragmaHandler { << II->getName(); } } else if (II->isStr("llvm_fatal_error")) { - llvm::report_fatal_error("#pragma clang __debug llvm_fatal_error"); + if (!PP.getPreprocessorOpts().DisablePragmaDebugCrash) + llvm::report_fatal_error("#pragma clang __debug llvm_fatal_error"); } else if (II->isStr("llvm_unreachable")) { - llvm_unreachable("#pragma clang __debug llvm_unreachable"); + if (!PP.getPreprocessorOpts().DisablePragmaDebugCrash) + llvm_unreachable("#pragma clang __debug llvm_unreachable"); } else if (II->isStr("macro")) { Token MacroName; PP.LexUnexpandedToken(MacroName); @@ -1104,11 +1118,8 @@ struct PragmaDebugHandler : public PragmaHandler { } M->dump(); } else if (II->isStr("overflow_stack")) { - DebugOverflowStack(); - } else if (II->isStr("handle_crash")) { - llvm::CrashRecoveryContext *CRC =llvm::CrashRecoveryContext::GetCurrent(); - if (CRC) - CRC->HandleCrash(); + if (!PP.getPreprocessorOpts().DisablePragmaDebugCrash) + DebugOverflowStack(); } else if (II->isStr("captured")) { HandleCaptured(PP); } else { @@ -1896,10 +1907,9 @@ void Preprocessor::RegisterBuiltinPragmas() { } // Pragmas added by plugins - for (PragmaHandlerRegistry::iterator it = PragmaHandlerRegistry::begin(), - ie = PragmaHandlerRegistry::end(); - it != ie; ++it) { - AddPragmaHandler(it->instantiate().release()); + for (const PragmaHandlerRegistry::entry &handler : + PragmaHandlerRegistry::entries()) { + AddPragmaHandler(handler.instantiate().release()); } } |