зеркало из https://github.com/microsoft/clang-1.git
In libclang, when visiting preprocessed entities in a source range, use
PreprocessingRecord's getPreprocessedEntitiesInRange. Also remove all the stuff that were added in ASTUnit that are unnecessary now that we do a binary search for preprocessed entities and deserialize only what is necessary. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@140063 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
b6441ef9b7
Коммит
92ddef1bf8
|
@ -68,10 +68,6 @@ class GlobalCodeCompletionAllocator
|
|||
/// \brief Utility class for loading a ASTContext from an AST file.
|
||||
///
|
||||
class ASTUnit : public ModuleLoader {
|
||||
public:
|
||||
typedef std::map<FileID, std::vector<PreprocessedEntity *> >
|
||||
PreprocessedEntitiesByFileMap;
|
||||
|
||||
private:
|
||||
llvm::IntrusiveRefCntPtr<Diagnostic> Diagnostics;
|
||||
llvm::IntrusiveRefCntPtr<FileManager> FileMgr;
|
||||
|
@ -130,14 +126,6 @@ private:
|
|||
// source. In the long term we should make the Index library use efficient and
|
||||
// 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;
|
||||
|
@ -162,15 +150,6 @@ private:
|
|||
/// \brief Temporary files that should be removed when the ASTUnit is
|
||||
/// destroyed.
|
||||
SmallVector<llvm::sys::Path, 4> TemporaryFiles;
|
||||
|
||||
/// \brief A mapping from file IDs to the set of preprocessed entities
|
||||
/// stored in that file.
|
||||
///
|
||||
/// FIXME: This is just an optimization hack to avoid searching through
|
||||
/// many preprocessed entities during cursor traversal in the CIndex library.
|
||||
/// Ideally, we would just be able to perform a binary search within the
|
||||
/// list of preprocessed entities.
|
||||
PreprocessedEntitiesByFileMap PreprocessedEntitiesByFile;
|
||||
|
||||
/// \brief Simple hack to allow us to assert that ASTUnit is not being
|
||||
/// used concurrently, which is not supported.
|
||||
|
@ -270,10 +249,6 @@ private:
|
|||
/// \brief A list of the serialization ID numbers for each of the top-level
|
||||
/// 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;
|
||||
|
@ -418,7 +393,6 @@ private:
|
|||
bool AllowRebuild = true,
|
||||
unsigned MaxLines = 0);
|
||||
void RealizeTopLevelDeclsFromPreamble();
|
||||
void RealizePreprocessedEntitiesFromPreamble();
|
||||
|
||||
public:
|
||||
class ConcurrencyCheck {
|
||||
|
@ -530,23 +504,6 @@ public:
|
|||
///
|
||||
/// Note: This is used internally by the top-level tracking action
|
||||
unsigned &getCurrentTopLevelHashValue() { return CurrentTopLevelHashValue; }
|
||||
|
||||
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() {
|
||||
return PreprocessedEntitiesByFile;
|
||||
}
|
||||
|
||||
/// \brief Get the source location for the given file:line:col triplet.
|
||||
///
|
||||
|
|
|
@ -275,10 +275,6 @@ namespace clang {
|
|||
/// preprocessed entities that \arg Range encompasses.
|
||||
virtual std::pair<unsigned, unsigned>
|
||||
findPreprocessedEntitiesInRange(SourceRange Range) = 0;
|
||||
|
||||
/// \brief Read the preprocessed entity at the given offset.
|
||||
virtual PreprocessedEntity *
|
||||
ReadPreprocessedEntityAtOffset(uint64_t Offset) = 0;
|
||||
};
|
||||
|
||||
/// \brief A record of the steps taken while preprocessing a source file,
|
||||
|
|
|
@ -801,9 +801,6 @@ public:
|
|||
virtual std::pair<unsigned, unsigned>
|
||||
findPreprocessedEntitiesInRange(SourceRange Range);
|
||||
|
||||
/// \brief Read the preprocessed entity at the given offset.
|
||||
virtual PreprocessedEntity *ReadPreprocessedEntityAtOffset(uint64_t Offset);
|
||||
|
||||
/// \brief Read the header file information for the given file entry.
|
||||
virtual HeaderFileInfo GetHeaderFileInfo(const FileEntry *FE);
|
||||
|
||||
|
|
|
@ -1,44 +0,0 @@
|
|||
//===- ASTSerializationListener.h - Decl/Type PCH Write Events -*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines the ASTSerializationListener class, which is notified
|
||||
// by the ASTWriter when an entity is serialized.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
#ifndef LLVM_CLANG_FRONTEND_AST_SERIALIZATION_LISTENER_H
|
||||
#define LLVM_CLANG_FRONTEND_AST_SERIALIZATION_LISTENER_H
|
||||
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
|
||||
namespace clang {
|
||||
|
||||
class PreprocessedEntity;
|
||||
|
||||
/// \brief Listener object that receives callbacks when certain kinds of
|
||||
/// entities are serialized.
|
||||
class ASTSerializationListener {
|
||||
public:
|
||||
virtual ~ASTSerializationListener();
|
||||
|
||||
/// \brief Callback invoked whenever a preprocessed entity is serialized.
|
||||
///
|
||||
/// This callback will only occur when the translation unit was created with
|
||||
/// a detailed preprocessing record.
|
||||
///
|
||||
/// \param Entity The entity that has been serialized.
|
||||
///
|
||||
/// \param Offset The offset (in bits) of this entity in the resulting
|
||||
/// AST file.
|
||||
virtual void SerializedPreprocessedEntity(PreprocessedEntity *Entity,
|
||||
uint64_t Offset) = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -38,7 +38,6 @@ namespace llvm {
|
|||
namespace clang {
|
||||
|
||||
class ASTContext;
|
||||
class ASTSerializationListener;
|
||||
class NestedNameSpecifier;
|
||||
class CXXBaseSpecifier;
|
||||
class CXXCtorInitializer;
|
||||
|
@ -93,10 +92,6 @@ private:
|
|||
|
||||
/// \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 Indicates when the AST writing is actively performing
|
||||
/// serialization, rather than just queueing updates.
|
||||
|
@ -393,12 +388,6 @@ public:
|
|||
/// \brief Create a new precompiled header writer that outputs to
|
||||
/// 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.
|
||||
///
|
||||
|
@ -665,7 +654,6 @@ public:
|
|||
virtual void InitializeSema(Sema &S) { SemaPtr = &S; }
|
||||
virtual void HandleTranslationUnit(ASTContext &Ctx);
|
||||
virtual ASTMutationListener *GetASTMutationListener();
|
||||
virtual ASTSerializationListener *GetASTSerializationListener();
|
||||
virtual ASTDeserializationListener *GetASTDeserializationListener();
|
||||
};
|
||||
|
||||
|
|
|
@ -29,7 +29,6 @@
|
|||
#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"
|
||||
|
@ -775,8 +774,7 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
class PrecompilePreambleConsumer : public PCHGenerator,
|
||||
public ASTSerializationListener {
|
||||
class PrecompilePreambleConsumer : public PCHGenerator {
|
||||
ASTUnit &Unit;
|
||||
unsigned &Hash;
|
||||
std::vector<Decl *> TopLevelDecls;
|
||||
|
@ -815,15 +813,6 @@ public:
|
|||
getWriter().getDeclID(TopLevelDecls[I]));
|
||||
}
|
||||
}
|
||||
|
||||
virtual void SerializedPreprocessedEntity(PreprocessedEntity *Entity,
|
||||
uint64_t Offset) {
|
||||
Unit.addPreprocessedEntityFromPreamble(Offset);
|
||||
}
|
||||
|
||||
virtual ASTSerializationListener *GetASTSerializationListener() {
|
||||
return this;
|
||||
}
|
||||
};
|
||||
|
||||
class PrecompilePreambleAction : public ASTFrontendAction {
|
||||
|
@ -922,16 +911,13 @@ bool ASTUnit::Parse(llvm::MemoryBuffer *OverrideMainBuffer) {
|
|||
|
||||
// Clear out old caches and data.
|
||||
TopLevelDecls.clear();
|
||||
PreprocessedEntities.clear();
|
||||
CleanTemporaryFiles();
|
||||
PreprocessedEntitiesByFile.clear();
|
||||
|
||||
if (!OverrideMainBuffer) {
|
||||
StoredDiagnostics.erase(
|
||||
StoredDiagnostics.begin() + NumStoredDiagnosticsFromDriver,
|
||||
StoredDiagnostics.end());
|
||||
TopLevelDeclsInPreamble.clear();
|
||||
PreprocessedEntitiesInPreamble.clear();
|
||||
}
|
||||
|
||||
// Create a file manager object to provide access to and cache the filesystem.
|
||||
|
@ -1407,8 +1393,6 @@ llvm::MemoryBuffer *ASTUnit::getMainBufferWithPrecompiledPreamble(
|
|||
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()));
|
||||
|
@ -1439,8 +1423,6 @@ llvm::MemoryBuffer *ASTUnit::getMainBufferWithPrecompiledPreamble(
|
|||
llvm::sys::Path(FrontendOpts.OutputFile).eraseFromDisk();
|
||||
Preamble.clear();
|
||||
TopLevelDeclsInPreamble.clear();
|
||||
PreprocessedEntities.clear();
|
||||
PreprocessedEntitiesInPreamble.clear();
|
||||
PreambleRebuildCounter = DefaultPreambleRebuildInterval;
|
||||
PreprocessorOpts.eraseRemappedFile(
|
||||
PreprocessorOpts.remapped_file_buffer_end() - 1);
|
||||
|
@ -1511,48 +1493,6 @@ void ASTUnit::RealizeTopLevelDeclsFromPreamble() {
|
|||
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->ReadPreprocessedEntityAtOffset(
|
||||
PreprocessedEntitiesInPreamble[I]))
|
||||
PreprocessedEntities.push_back(PE);
|
||||
}
|
||||
|
||||
if (PreprocessedEntities.empty())
|
||||
return;
|
||||
|
||||
PreprocessedEntities.insert(PreprocessedEntities.end(),
|
||||
PPRec->local_begin(), PPRec->local_end());
|
||||
}
|
||||
|
||||
ASTUnit::pp_entity_iterator ASTUnit::pp_entity_begin() {
|
||||
if (!PreprocessedEntitiesInPreamble.empty() &&
|
||||
PreprocessedEntities.empty())
|
||||
RealizePreprocessedEntitiesFromPreamble();
|
||||
|
||||
return PreprocessedEntities.begin();
|
||||
}
|
||||
|
||||
ASTUnit::pp_entity_iterator ASTUnit::pp_entity_end() {
|
||||
if (!PreprocessedEntitiesInPreamble.empty() &&
|
||||
PreprocessedEntities.empty())
|
||||
RealizePreprocessedEntitiesFromPreamble();
|
||||
|
||||
return PreprocessedEntities.end();
|
||||
}
|
||||
|
||||
StringRef ASTUnit::getMainFileName() const {
|
||||
return Invocation->getFrontendOpts().Inputs[0].second;
|
||||
}
|
||||
|
|
|
@ -2999,16 +2999,6 @@ std::pair<unsigned, unsigned>
|
|||
return std::make_pair(BeginID, EndID);
|
||||
}
|
||||
|
||||
PreprocessedEntity *ASTReader::ReadPreprocessedEntityAtOffset(uint64_t Offset) {
|
||||
RecordLocation Loc = getLocalBitOffset(Offset);
|
||||
|
||||
// Keep track of where we are in the stream, then jump back there
|
||||
// after reading this entity.
|
||||
SavedStreamPosition SavedPosition(Loc.F->PreprocessorDetailCursor);
|
||||
Loc.F->PreprocessorDetailCursor.JumpToBit(Loc.Offset);
|
||||
return LoadPreprocessedEntity(*Loc.F);
|
||||
}
|
||||
|
||||
namespace {
|
||||
/// \brief Visitor used to search for information about a header file.
|
||||
class HeaderFileInfoVisitor {
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "clang/Serialization/ASTWriter.h"
|
||||
#include "clang/Serialization/ASTSerializationListener.h"
|
||||
#include "ASTCommon.h"
|
||||
#include "clang/Sema/Sema.h"
|
||||
#include "clang/Sema/IdentifierResolver.h"
|
||||
|
@ -1743,7 +1742,6 @@ void ASTWriter::WritePreprocessorDetail(PreprocessingRecord &PPRec) {
|
|||
+ NUM_PREDEF_PP_ENTITY_IDS;
|
||||
unsigned NextPreprocessorEntityID = FirstPreprocessorEntityID;
|
||||
RecordData Record;
|
||||
uint64_t BitsInChain = Chain? Chain->TotalModulesSizeInBits : 0;
|
||||
for (PreprocessingRecord::iterator E = PPRec.local_begin(),
|
||||
EEnd = PPRec.local_end();
|
||||
E != EEnd;
|
||||
|
@ -1757,11 +1755,6 @@ void ASTWriter::WritePreprocessorDetail(PreprocessingRecord &PPRec) {
|
|||
// Record this macro definition's ID.
|
||||
MacroDefinitions[MD] = NextPreprocessorEntityID;
|
||||
|
||||
// Notify the serialization listener that we're serializing this entity.
|
||||
if (SerializationListener)
|
||||
SerializationListener->SerializedPreprocessedEntity(*E,
|
||||
BitsInChain + Stream.GetCurrentBitNo());
|
||||
|
||||
Record.push_back(NextPreprocessorEntityID);
|
||||
AddSourceLocation(MD->getSourceRange().getBegin(), Record);
|
||||
AddSourceLocation(MD->getSourceRange().getEnd(), Record);
|
||||
|
@ -1771,11 +1764,6 @@ void ASTWriter::WritePreprocessorDetail(PreprocessingRecord &PPRec) {
|
|||
continue;
|
||||
}
|
||||
|
||||
// Notify the serialization listener that we're serializing this entity.
|
||||
if (SerializationListener)
|
||||
SerializationListener->SerializedPreprocessedEntity(*E,
|
||||
BitsInChain + Stream.GetCurrentBitNo());
|
||||
|
||||
if (MacroExpansion *ME = dyn_cast<MacroExpansion>(*E)) {
|
||||
Record.push_back(NextPreprocessorEntityID);
|
||||
AddSourceLocation(ME->getSourceRange().getBegin(), Record);
|
||||
|
@ -2719,8 +2707,7 @@ void ASTWriter::SetSelectorOffset(Selector Sel, uint32_t Offset) {
|
|||
}
|
||||
|
||||
ASTWriter::ASTWriter(llvm::BitstreamWriter &Stream)
|
||||
: Stream(Stream), Context(0), Chain(0), SerializationListener(0),
|
||||
WritingAST(false),
|
||||
: Stream(Stream), Context(0), Chain(0), WritingAST(false),
|
||||
FirstDeclID(NUM_PREDEF_DECL_IDS), NextDeclID(FirstDeclID),
|
||||
FirstTypeID(NUM_PREDEF_TYPE_IDS), NextTypeID(FirstTypeID),
|
||||
FirstIdentID(NUM_PREDEF_IDENT_IDS), NextIdentID(FirstIdentID),
|
||||
|
@ -4045,5 +4032,3 @@ void ASTWriter::AddedObjCCategoryToInterface(const ObjCCategoryDecl *CatD,
|
|||
ChainedObjCCategoriesData Data = { IFD, CatD, 0, 0 };
|
||||
LocalChainedObjCCategories.push_back(Data);
|
||||
}
|
||||
|
||||
ASTSerializationListener::~ASTSerializationListener() { }
|
||||
|
|
|
@ -46,9 +46,6 @@ PCHGenerator::~PCHGenerator() {
|
|||
void PCHGenerator::HandleTranslationUnit(ASTContext &Ctx) {
|
||||
if (PP.getDiagnostics().hasErrorOccurred())
|
||||
return;
|
||||
|
||||
// Set up the serialization listener.
|
||||
Writer.SetSerializationListener(GetASTSerializationListener());
|
||||
|
||||
// Emit the PCH file
|
||||
assert(SemaPtr && "No Sema?");
|
||||
|
@ -68,10 +65,6 @@ ASTMutationListener *PCHGenerator::GetASTMutationListener() {
|
|||
return &Writer;
|
||||
}
|
||||
|
||||
ASTSerializationListener *PCHGenerator::GetASTSerializationListener() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ASTDeserializationListener *PCHGenerator::GetASTDeserializationListener() {
|
||||
return &Writer;
|
||||
}
|
||||
|
|
|
@ -262,10 +262,6 @@ public:
|
|||
|
||||
bool visitPreprocessedEntitiesInRegion();
|
||||
|
||||
template<typename InputIterator>
|
||||
bool visitPreprocessedEntitiesInRegion(InputIterator First,
|
||||
InputIterator Last);
|
||||
|
||||
template<typename InputIterator>
|
||||
bool visitPreprocessedEntities(InputIterator First, InputIterator Last);
|
||||
|
||||
|
@ -399,62 +395,19 @@ bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
|
|||
PreprocessingRecord &PPRec
|
||||
= *AU->getPreprocessor().getPreprocessingRecord();
|
||||
|
||||
if (RegionOfInterest.isValid()) {
|
||||
std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
|
||||
Entities = PPRec.getPreprocessedEntitiesInRange(RegionOfInterest);
|
||||
return visitPreprocessedEntities(Entities.first, Entities.second);
|
||||
}
|
||||
|
||||
bool OnlyLocalDecls
|
||||
= !AU->isMainFileAST() && AU->getOnlyLocalDecls();
|
||||
|
||||
if (OnlyLocalDecls && RegionOfInterest.isValid()) {
|
||||
// If we would only look at local declarations but we have a region of
|
||||
// interest, check whether that region of interest is in the main file.
|
||||
// If not, we should traverse all declarations.
|
||||
// FIXME: My kingdom for a proper binary search approach to finding
|
||||
// cursors!
|
||||
std::pair<FileID, unsigned> Location
|
||||
= AU->getSourceManager().getDecomposedExpansionLoc(
|
||||
RegionOfInterest.getBegin());
|
||||
if (Location.first != AU->getSourceManager().getMainFileID())
|
||||
OnlyLocalDecls = false;
|
||||
}
|
||||
|
||||
PreprocessingRecord::iterator StartEntity, EndEntity;
|
||||
if (OnlyLocalDecls && AU->pp_entity_begin() != AU->pp_entity_end())
|
||||
return visitPreprocessedEntitiesInRegion(AU->pp_entity_begin(),
|
||||
AU->pp_entity_end());
|
||||
else
|
||||
return visitPreprocessedEntitiesInRegion(PPRec.begin(), PPRec.end());
|
||||
}
|
||||
if (OnlyLocalDecls)
|
||||
return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end());
|
||||
|
||||
template<typename InputIterator>
|
||||
bool CursorVisitor::visitPreprocessedEntitiesInRegion(InputIterator First,
|
||||
InputIterator Last) {
|
||||
// There is no region of interest; we have to walk everything.
|
||||
if (RegionOfInterest.isInvalid())
|
||||
return visitPreprocessedEntities(First, Last);
|
||||
|
||||
// Find the file in which the region of interest lands.
|
||||
SourceManager &SM = AU->getSourceManager();
|
||||
std::pair<FileID, unsigned> Begin
|
||||
= SM.getDecomposedExpansionLoc(RegionOfInterest.getBegin());
|
||||
std::pair<FileID, unsigned> End
|
||||
= SM.getDecomposedExpansionLoc(RegionOfInterest.getEnd());
|
||||
|
||||
// The region of interest spans files; we have to walk everything.
|
||||
if (Begin.first != End.first)
|
||||
return visitPreprocessedEntities(First, Last);
|
||||
|
||||
ASTUnit::PreprocessedEntitiesByFileMap &ByFileMap
|
||||
= AU->getPreprocessedEntitiesByFile();
|
||||
if (ByFileMap.empty()) {
|
||||
// Build the mapping from files to sets of preprocessed entities.
|
||||
for (; First != Last; ++First) {
|
||||
std::pair<FileID, unsigned> P
|
||||
= SM.getDecomposedExpansionLoc((*First)->getSourceRange().getBegin());
|
||||
|
||||
ByFileMap[P.first].push_back(*First);
|
||||
}
|
||||
}
|
||||
|
||||
return visitPreprocessedEntities(ByFileMap[Begin.first].begin(),
|
||||
ByFileMap[Begin.first].end());
|
||||
return visitPreprocessedEntities(PPRec.begin(), PPRec.end());
|
||||
}
|
||||
|
||||
template<typename InputIterator>
|
||||
|
|
Загрузка…
Ссылка в новой задаче