//===--- Pragma.cpp - Pragma registration and handling --------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the PragmaHandler/PragmaTable interfaces and implements
// pragma related methods of the Preprocessor class.
//
//===----------------------------------------------------------------------===//
#include "clang/Lex/Pragma.h"
#include "clang/Lex/HeaderSearch.h"
#include "clang/Lex/LiteralSupport.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Lex/MacroInfo.h"
#include "clang/Lex/LexDiagnostic.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/SourceManager.h"
#include "llvm/Support/CrashRecoveryContext.h"
#include "llvm/Support/ErrorHandling.h"
#include <algorithm>
using namespace clang;
// Out-of-line destructor to provide a home for the class.
PragmaHandler::~PragmaHandler() {
}
//===----------------------------------------------------------------------===//
// EmptyPragmaHandler Implementation.
//===----------------------------------------------------------------------===//
EmptyPragmaHandler::EmptyPragmaHandler() {}
void EmptyPragmaHandler::HandlePragma(Preprocessor &PP,
PragmaIntroducerKind Introducer,
Token &FirstToken) {}
//===----------------------------------------------------------------------===//
// PragmaNamespace Implementation.
//===----------------------------------------------------------------------===//
PragmaNamespace::~PragmaNamespace() {
for (llvm::StringMap<PragmaHandler*>::iterator
I = Handlers.begin(), E = Handlers.end(); I != E; ++I)
delete I->second;
}
/// 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 ? 0 : Handlers.lookup(StringRef());
}
void PragmaNamespace::AddPragma(PragmaHandler *Handler) {
assert(!Handlers.lookup(Handler->getName()) &&
"A handler with this name is already registered in this namespace");
llvm::StringMapEntry<PragmaHandler *> &Entry =
Handlers.GetOrCreateValue(Handler->getName());
Entry.setValue(Handler);
}
void PragmaNamespace::RemovePragmaHandler(PragmaHandler *Handler) {
assert(Handlers.lookup(Handler->getName()) &&
"Handler not registered in this namespace");
Handlers.erase(Handler->getName());
}
void PragmaNamespace::HandlePragma(Preprocessor &PP,
PragmaIntroducerKind Introducer,
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.
PP.LexUnexpandedToken(Tok);
// Get the handler for this token. If there is no handler, ignore the pragma.
PragmaHandler *Handler
= FindHandler(Tok.getIdentifierInfo() ? Tok.getIdentifierInfo()->getName()
: StringRef(),
/*IgnoreNull=*/false);
if (Handler == 0) {
PP.Diag(Tok, diag::warn_pragma_ignored);
return;
}
// Otherwise, pass it down.
Handler->HandlePragma(PP, Introducer, Tok);
}
//===----------------------------------------------------------------------===//
// Preprocessor Pragma Directive Handling.
//===----------------------------------------------------------------------===//
/// HandlePragmaDirective - The "#pragma" directive has been parsed. Lex the
/// rest of the pragma, passing it to the registered pragma handlers.
void Preprocessor