diff options
| author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2010-10-14 20:14:25 +0000 | 
|---|---|---|
| committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2010-10-14 20:14:25 +0000 | 
| commit | 0427be938efb8c4f2c11fafcc145cdac092d838e (patch) | |
| tree | def01597198c6190fddbaad8d92c4939444ec291 | |
| parent | 470c454a6176ef31474553e408c90f5ee630df89 (diff) | |
| download | bcm5719-llvm-0427be938efb8c4f2c11fafcc145cdac092d838e.tar.gz bcm5719-llvm-0427be938efb8c4f2c11fafcc145cdac092d838e.zip  | |
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.
llvm-svn: 116505
| -rw-r--r-- | clang/include/clang/Driver/CC1Options.td | 2 | ||||
| -rw-r--r-- | clang/include/clang/Frontend/PreprocessorOptions.h | 5 | ||||
| -rw-r--r-- | clang/lib/Frontend/CompilerInvocation.cpp | 6 | ||||
| -rw-r--r-- | clang/lib/Frontend/FrontendAction.cpp | 39 | 
4 files changed, 52 insertions, 0 deletions
diff --git a/clang/include/clang/Driver/CC1Options.td b/clang/include/clang/Driver/CC1Options.td index 79dc441075b..a175ce5fb47 100644 --- a/clang/include/clang/Driver/CC1Options.td +++ b/clang/include/clang/Driver/CC1Options.td @@ -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">, diff --git a/clang/include/clang/Frontend/PreprocessorOptions.h b/clang/include/clang/Frontend/PreprocessorOptions.h index 34b49e1fac1..2a540b61df7 100644 --- a/clang/include/clang/Frontend/PreprocessorOptions.h +++ b/clang/include/clang/Frontend/PreprocessorOptions.h @@ -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.    /// diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 8f0cb089ee6..3a928a520da 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -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)); diff --git a/clang/lib/Frontend/FrontendAction.cpp b/clang/lib/Frontend/FrontendAction.cpp index 429b0093332..819aa52a508 100644 --- a/clang/lib/Frontend/FrontendAction.cpp +++ b/clang/lib/Frontend/FrontendAction.cpp @@ -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,  | 

