зеркало из https://github.com/microsoft/clang-1.git
Introduce command line option -error-on-deserialized-decl that is accompanied by a name
and emits an error if a declaration with this name is deserialized from PCH. This is for testing, to make sure that we don't deserialize stuff needlessly. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@116505 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
3b8f610ac9
Коммит
3e78593b1c
|
@ -475,6 +475,8 @@ def fno_validate_pch : Flag<"-fno-validate-pch">,
|
|||
HelpText<"Disable validation of precompiled headers">;
|
||||
def dump_deserialized_pch_decls : Flag<"-dump-deserialized-decls">,
|
||||
HelpText<"Dump declarations that are deserialized from PCH, for testing">;
|
||||
def error_on_deserialized_pch_decl : Separate<"-error-on-deserialized-decl">,
|
||||
HelpText<"Emit error if a specific declaration is deserialized from PCH, for testing">;
|
||||
def fshort_wchar : Flag<"-fshort-wchar">,
|
||||
HelpText<"Force wchar_t to be a short unsigned int">;
|
||||
def fshort_enums : Flag<"-fshort-enums">,
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
|
||||
namespace llvm {
|
||||
class MemoryBuffer;
|
||||
|
@ -50,6 +51,10 @@ public:
|
|||
/// \brief Dump declarations that are deserialized from PCH, for testing.
|
||||
bool DumpDeserializedPCHDecls;
|
||||
|
||||
/// \brief This is a set of names for decls that we do not want to be
|
||||
/// deserialized, and we emit an error if they are; for testing purposes.
|
||||
std::set<std::string> DeserializedPCHDeclsToErrorOn;
|
||||
|
||||
/// \brief If non-zero, the implicit PCH include is actually a precompiled
|
||||
/// preamble that covers this number of bytes in the main source file.
|
||||
///
|
||||
|
|
|
@ -1409,7 +1409,13 @@ static void ParsePreprocessorArgs(PreprocessorOptions &Opts, ArgList &Args,
|
|||
Opts.UsePredefines = !Args.hasArg(OPT_undef);
|
||||
Opts.DetailedRecord = Args.hasArg(OPT_detailed_preprocessing_record);
|
||||
Opts.DisablePCHValidation = Args.hasArg(OPT_fno_validate_pch);
|
||||
|
||||
Opts.DumpDeserializedPCHDecls = Args.hasArg(OPT_dump_deserialized_pch_decls);
|
||||
for (arg_iterator it = Args.filtered_begin(OPT_error_on_deserialized_pch_decl),
|
||||
ie = Args.filtered_end(); it != ie; ++it) {
|
||||
const Arg *A = *it;
|
||||
Opts.DeserializedPCHDeclsToErrorOn.insert(A->getValue(Args));
|
||||
}
|
||||
|
||||
if (const Arg *A = Args.getLastArg(OPT_preamble_bytes_EQ)) {
|
||||
llvm::StringRef Value(A->getValue(Args));
|
||||
|
|
|
@ -51,6 +51,41 @@ public:
|
|||
MacroDefinition *MD) {}
|
||||
};
|
||||
|
||||
/// \brief Checks deserialized declarations and emits error if a name
|
||||
/// matches one given in command-line using -error-on-deserialized-decl.
|
||||
class DeserializedDeclsChecker : public ASTDeserializationListener {
|
||||
ASTContext &Ctx;
|
||||
std::set<std::string> NamesToCheck;
|
||||
ASTDeserializationListener *Previous;
|
||||
|
||||
public:
|
||||
DeserializedDeclsChecker(ASTContext &Ctx,
|
||||
const std::set<std::string> &NamesToCheck,
|
||||
ASTDeserializationListener *Previous)
|
||||
: Ctx(Ctx), NamesToCheck(NamesToCheck), Previous(Previous) { }
|
||||
|
||||
virtual void DeclRead(serialization::DeclID ID, const Decl *D) {
|
||||
if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
|
||||
if (NamesToCheck.find(ND->getNameAsString()) != NamesToCheck.end()) {
|
||||
unsigned DiagID
|
||||
= Ctx.getDiagnostics().getCustomDiagID(Diagnostic::Error,
|
||||
"%0 was deserialized");
|
||||
Ctx.getDiagnostics().Report(Ctx.getFullLoc(D->getLocation()), DiagID)
|
||||
<< ND->getNameAsString();
|
||||
}
|
||||
|
||||
if (Previous)
|
||||
Previous->DeclRead(ID, D);
|
||||
}
|
||||
|
||||
virtual void SetReader(ASTReader *Reader) {}
|
||||
virtual void IdentifierRead(serialization::IdentID ID, IdentifierInfo *II) {}
|
||||
virtual void TypeRead(serialization::TypeIdx Idx, QualType T) {}
|
||||
virtual void SelectorRead(serialization::SelectorID iD, Selector Sel) {}
|
||||
virtual void MacroDefinitionRead(serialization::MacroID,
|
||||
MacroDefinition *MD) {}
|
||||
};
|
||||
|
||||
} // end anonymous namespace
|
||||
|
||||
FrontendAction::FrontendAction() : Instance(0) {}
|
||||
|
@ -154,6 +189,10 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI,
|
|||
Consumer->GetASTDeserializationListener() : 0;
|
||||
if (CI.getPreprocessorOpts().DumpDeserializedPCHDecls)
|
||||
DeserialListener = new DeserializedDeclsDumper(DeserialListener);
|
||||
if (!CI.getPreprocessorOpts().DeserializedPCHDeclsToErrorOn.empty())
|
||||
DeserialListener = new DeserializedDeclsChecker(CI.getASTContext(),
|
||||
CI.getPreprocessorOpts().DeserializedPCHDeclsToErrorOn,
|
||||
DeserialListener);
|
||||
CI.createPCHExternalASTSource(
|
||||
CI.getPreprocessorOpts().ImplicitPCHInclude,
|
||||
CI.getPreprocessorOpts().DisablePCHValidation,
|
||||
|
|
Загрузка…
Ссылка в новой задаче