[cfe-commits] r120396 - in /cfe/trunk: include/clang/Frontend/ASTUnit.h include/clang/Lex/PreprocessingRecord.h include/clang/Serialization/ASTReader.h include/clang/Serialization/ASTWriter.h lib/Frontend/ASTUnit.cpp lib/Serialization/ASTReader.c
Francois Pichet
pichet2000 at gmail.com
Wed Jul 20 23:33:00 PDT 2011
On Tue, Nov 30, 2010 at 1:16 AM, Douglas Gregor <dgregor at apple.com> wrote:
> Author: dgregor
> Date: Tue Nov 30 00:16:57 2010
> New Revision: 120396
>
> URL: http://llvm.org/viewvc/llvm-project?rev=120396&view=rev
> Log:
> When using a precompiled preamble with detailed preprocessing records,
> trap the serialized preprocessing records (macro definitions, macro
> instantiations, macro definitions) from the generation of the
> precompiled preamble, then replay those when walking the list of
> preprocessed entities. This eliminates a bug where clang_getCursor()
> wasn't able to find preprocessed-entity cursors in the preamble.
>
> Modified:
> cfe/trunk/include/clang/Frontend/ASTUnit.h
> cfe/trunk/include/clang/Lex/PreprocessingRecord.h
> cfe/trunk/include/clang/Serialization/ASTReader.h
> cfe/trunk/include/clang/Serialization/ASTWriter.h
> cfe/trunk/lib/Frontend/ASTUnit.cpp
> cfe/trunk/lib/Serialization/ASTReader.cpp
> cfe/trunk/lib/Serialization/ASTWriter.cpp
> cfe/trunk/lib/Serialization/GeneratePCH.cpp
> cfe/trunk/test/Index/c-index-getCursor-pp.c
> cfe/trunk/tools/libclang/CIndex.cpp
>
> Modified: cfe/trunk/include/clang/Frontend/ASTUnit.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/ASTUnit.h?rev=120396&r1=120395&r2=120396&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Frontend/ASTUnit.h (original)
> +++ cfe/trunk/include/clang/Frontend/ASTUnit.h Tue Nov 30 00:16:57 2010
> @@ -110,6 +110,14 @@
> // more scalable search mechanisms.
> std::vector<Decl*> TopLevelDecls;
>
> + /// \brief The list of preprocessed entities which appeared when the ASTUnit
> + /// was loaded.
> + ///
> + /// FIXME: This is just an optimization hack to avoid deserializing large
> + /// parts of a PCH file while performing a walk or search. In the long term,
> + /// we should provide more scalable search mechanisms.
> + std::vector<PreprocessedEntity *> PreprocessedEntities;
> +
> /// The name of the original source file used to generate this ASTUnit.
> std::string OriginalSourceFile;
>
> @@ -215,6 +223,10 @@
> /// declarations parsed within the precompiled preamble.
> std::vector<serialization::DeclID> TopLevelDeclsInPreamble;
>
> + /// \brief A list of the offsets into the precompiled preamble which
> + /// correspond to preprocessed entities.
> + std::vector<uint64_t> PreprocessedEntitiesInPreamble;
> +
> /// \brief Whether we should be caching code-completion results.
> bool ShouldCacheCodeCompletionResults;
>
> @@ -317,7 +329,8 @@
> bool AllowRebuild = true,
> unsigned MaxLines = 0);
> void RealizeTopLevelDeclsFromPreamble();
> -
> + void RealizePreprocessedEntitiesFromPreamble();
> +
> public:
> class ConcurrencyCheck {
> volatile ASTUnit &Self;
> @@ -426,6 +439,17 @@
> TopLevelDeclsInPreamble.push_back(D);
> }
>
> + typedef std::vector<PreprocessedEntity *>::iterator pp_entity_iterator;
> +
> + pp_entity_iterator pp_entity_begin();
> + pp_entity_iterator pp_entity_end();
> +
> + /// \brief Add a new preprocessed entity that's stored at the given offset
> + /// in the precompiled preamble.
> + void addPreprocessedEntityFromPreamble(uint64_t Offset) {
> + PreprocessedEntitiesInPreamble.push_back(Offset);
> + }
> +
> /// \brief Retrieve the mapping from File IDs to the preprocessed entities
> /// within that file.
> PreprocessedEntitiesByFileMap &getPreprocessedEntitiesByFile() {
>
> Modified: cfe/trunk/include/clang/Lex/PreprocessingRecord.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/PreprocessingRecord.h?rev=120396&r1=120395&r2=120396&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Lex/PreprocessingRecord.h (original)
> +++ cfe/trunk/include/clang/Lex/PreprocessingRecord.h Tue Nov 30 00:16:57 2010
> @@ -248,6 +248,9 @@
> /// \brief Read any preallocated preprocessed entities from the external
> /// source.
> virtual void ReadPreprocessedEntities() = 0;
> +
> + /// \brief Read the preprocessed entity at the given offset.
> + virtual PreprocessedEntity *ReadPreprocessedEntity(uint64_t Offset) = 0;
> };
>
> /// \brief A record of the steps taken while preprocessing a source file,
> @@ -302,6 +305,11 @@
> void SetExternalSource(ExternalPreprocessingRecordSource &Source,
> unsigned NumPreallocatedEntities);
>
> + /// \brief Retrieve the external source for preprocessed entities.
> + ExternalPreprocessingRecordSource *getExternalSource() const {
> + return ExternalSource;
> + }
> +
> unsigned getNumPreallocatedEntities() const {
> return NumPreallocatedEntities;
> }
>
> Modified: cfe/trunk/include/clang/Serialization/ASTReader.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTReader.h?rev=120396&r1=120395&r2=120396&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Serialization/ASTReader.h (original)
> +++ cfe/trunk/include/clang/Serialization/ASTReader.h Tue Nov 30 00:16:57 2010
> @@ -845,9 +845,12 @@
> /// build prior to including the precompiled header.
> const std::string &getSuggestedPredefines() { return SuggestedPredefines; }
>
> - /// \brief Read preprocessed entities into the
> + /// \brief Read preprocessed entities into the preprocessing record.
> virtual void ReadPreprocessedEntities();
>
> + /// \brief Read the preprocessed entity at the given offset.
> + virtual PreprocessedEntity *ReadPreprocessedEntity(uint64_t Offset);
> +
> void ReadUserDiagnosticMappings(Diagnostic &Diag);
>
> /// \brief Returns the number of source locations found in the chain.
> @@ -1154,7 +1157,7 @@
> Expr *ReadSubExpr();
>
> /// \brief Reads the macro record located at the given offset.
> - void ReadMacroRecord(PerFileData &F, uint64_t Offset);
> + PreprocessedEntity *ReadMacroRecord(PerFileData &F, uint64_t Offset);
>
> /// \brief Note that the identifier is a macro whose record will be loaded
> /// from the given AST file at the given (file-local) offset.
>
> Modified: cfe/trunk/include/clang/Serialization/ASTWriter.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTWriter.h?rev=120396&r1=120395&r2=120396&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Serialization/ASTWriter.h (original)
> +++ cfe/trunk/include/clang/Serialization/ASTWriter.h Tue Nov 30 00:16:57 2010
> @@ -23,6 +23,7 @@
> #include "clang/Sema/SemaConsumer.h"
> #include "llvm/ADT/SmallPtrSet.h"
> #include "llvm/ADT/SmallVector.h"
> +#include "llvm/ADT/DenseMap.h"
> #include "llvm/Bitcode/BitstreamWriter.h"
> #include <map>
> #include <queue>
> @@ -37,6 +38,7 @@
> namespace clang {
>
> class ASTContext;
> +class ASTSerializationListener;
> class NestedNameSpecifier;
> class CXXBaseSpecifier;
> class CXXBaseOrMemberInitializer;
> @@ -44,6 +46,7 @@
> class MacroDefinition;
> class MemorizeStatCalls;
> class ASTReader;
> +class PreprocessedEntity;
> class Preprocessor;
> class Sema;
> class SourceManager;
> @@ -70,6 +73,10 @@
> /// \brief The reader of existing AST files, if we're chaining.
> ASTReader *Chain;
>
> + /// \brief A listener object that receives notifications when certain
> + /// entities are serialized.
> + ASTSerializationListener *SerializationListener;
> +
> /// \brief Stores a declaration or a type to be written to the AST file.
> class DeclOrType {
> public:
> @@ -334,6 +341,12 @@
> /// the given bitstream.
> ASTWriter(llvm::BitstreamWriter &Stream);
>
> + /// \brief Set the listener that will receive notification of serialization
> + /// events.
> + void SetSerializationListener(ASTSerializationListener *Listener) {
> + SerializationListener = Listener;
> + }
> +
> /// \brief Write a precompiled header for the given semantic analysis.
> ///
> /// \param SemaRef a reference to the semantic analysis object that processed
> @@ -573,6 +586,7 @@
> virtual void InitializeSema(Sema &S) { SemaPtr = &S; }
> virtual void HandleTranslationUnit(ASTContext &Ctx);
> virtual ASTMutationListener *GetASTMutationListener();
> + virtual ASTSerializationListener *GetASTSerializationListener();
> virtual ASTDeserializationListener *GetASTDeserializationListener();
> };
>
>
> Modified: cfe/trunk/lib/Frontend/ASTUnit.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/ASTUnit.cpp?rev=120396&r1=120395&r2=120396&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Frontend/ASTUnit.cpp (original)
> +++ cfe/trunk/lib/Frontend/ASTUnit.cpp Tue Nov 30 00:16:57 2010
> @@ -27,6 +27,7 @@
> #include "clang/Frontend/FrontendOptions.h"
> #include "clang/Frontend/Utils.h"
> #include "clang/Serialization/ASTReader.h"
> +#include "clang/Serialization/ASTSerializationListener.h"
> #include "clang/Serialization/ASTWriter.h"
> #include "clang/Lex/HeaderSearch.h"
> #include "clang/Lex/Preprocessor.h"
> @@ -637,10 +638,11 @@
> }
> };
>
> -class PrecompilePreambleConsumer : public PCHGenerator {
> +class PrecompilePreambleConsumer : public PCHGenerator,
> + public ASTSerializationListener {
> ASTUnit &Unit;
> std::vector<Decl *> TopLevelDecls;
> -
> +
> public:
> PrecompilePreambleConsumer(ASTUnit &Unit,
> const Preprocessor &PP, bool Chaining,
> @@ -672,6 +674,15 @@
> getWriter().getDeclID(TopLevelDecls[I]));
> }
> }
> +
> + virtual void SerializedPreprocessedEntity(PreprocessedEntity *Entity,
> + uint64_t Offset) {
> + Unit.addPreprocessedEntityFromPreamble(Offset);
> + }
> +
> + virtual ASTSerializationListener *GetASTSerializationListener() {
> + return this;
> + }
> };
>
> class PrecompilePreambleAction : public ASTFrontendAction {
> @@ -757,6 +768,7 @@
>
> // Clear out old caches and data.
> TopLevelDecls.clear();
> + PreprocessedEntities.clear();
> CleanTemporaryFiles();
> PreprocessedEntitiesByFile.clear();
>
> @@ -765,6 +777,7 @@
> StoredDiagnostics.begin() + NumStoredDiagnosticsFromDriver,
> StoredDiagnostics.end());
> TopLevelDeclsInPreamble.clear();
> + PreprocessedEntitiesInPreamble.clear();
> }
>
> // Create a file manager object to provide access to and cache the filesystem.
> @@ -1237,6 +1250,8 @@
> StoredDiagnostics.end());
> TopLevelDecls.clear();
> TopLevelDeclsInPreamble.clear();
> + PreprocessedEntities.clear();
> + PreprocessedEntitiesInPreamble.clear();
>
> // Create a file manager object to provide access to and cache the filesystem.
> Clang.setFileManager(new FileManager(Clang.getFileSystemOpts()));
> @@ -1269,6 +1284,8 @@
> llvm::sys::Path(FrontendOpts.OutputFile).eraseFromDisk();
> Preamble.clear();
> TopLevelDeclsInPreamble.clear();
> + PreprocessedEntities.clear();
> + PreprocessedEntitiesInPreamble.clear();
> PreambleRebuildCounter = DefaultPreambleRebuildInterval;
> PreprocessorOpts.eraseRemappedFile(
> PreprocessorOpts.remapped_file_buffer_end() - 1);
> @@ -1321,6 +1338,55 @@
> TopLevelDecls.insert(TopLevelDecls.begin(), Resolved.begin(), Resolved.end());
> }
>
> +void ASTUnit::RealizePreprocessedEntitiesFromPreamble() {
> + if (!PP)
> + return;
> +
> + PreprocessingRecord *PPRec = PP->getPreprocessingRecord();
> + if (!PPRec)
> + return;
> +
> + ExternalPreprocessingRecordSource *External = PPRec->getExternalSource();
> + if (!External)
> + return;
> +
> + for (unsigned I = 0, N = PreprocessedEntitiesInPreamble.size(); I != N; ++I) {
> + if (PreprocessedEntity *PE
> + = External->ReadPreprocessedEntity(PreprocessedEntitiesInPreamble[I]))
> + PreprocessedEntities.push_back(PE);
> + }
> +
> + if (PreprocessedEntities.empty())
> + return;
> +
> + PreprocessedEntities.insert(PreprocessedEntities.end(),
> + PPRec->begin(true), PPRec->end(true));
Hi, I added a operator< to PreprocessingRecord::iterator otherwise
MSVC will refuse to compile the insert line in DEBUG mode.
see r135670
More information about the cfe-commits
mailing list