forked from OSchip/llvm-project
Introduce PreprocessingRecord::getPreprocessedEntitiesInRange()
which will do a binary search and return a pair of iterators for preprocessed entities in the given source range. Source ranges of preprocessed entities are stored twice currently in the PCH/Module file but this will be fixed in a subsequent commit. llvm-svn: 140058
This commit is contained in:
parent
e6e67deeed
commit
64f6381097
|
@ -271,6 +271,11 @@ namespace clang {
|
|||
/// entity from being loaded.
|
||||
virtual PreprocessedEntity *ReadPreprocessedEntity(unsigned Index) = 0;
|
||||
|
||||
/// \brief Returns a pair of [Begin, End) indices of preallocated
|
||||
/// 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;
|
||||
|
@ -280,6 +285,8 @@ namespace clang {
|
|||
/// including the various preprocessing directives processed, macros
|
||||
/// expanded, etc.
|
||||
class PreprocessingRecord : public PPCallbacks {
|
||||
SourceManager &SourceMgr;
|
||||
|
||||
/// \brief Whether we should include nested macro expansions in
|
||||
/// the preprocessing record.
|
||||
bool IncludeNestedMacroExpansions;
|
||||
|
@ -329,7 +336,14 @@ namespace clang {
|
|||
unsigned getNumLoadedPreprocessedEntities() const {
|
||||
return LoadedPreprocessedEntities.size();
|
||||
}
|
||||
|
||||
|
||||
/// \brief Returns a pair of [Begin, End) indices of local preprocessed
|
||||
/// entities that \arg Range encompasses.
|
||||
std::pair<unsigned, unsigned>
|
||||
findLocalPreprocessedEntitiesInRange(SourceRange Range) const;
|
||||
unsigned findBeginLocalPreprocessedEntity(SourceLocation Loc) const;
|
||||
unsigned findEndLocalPreprocessedEntity(SourceLocation Loc) const;
|
||||
|
||||
/// \brief Allocate space for a new set of loaded preprocessed entities.
|
||||
///
|
||||
/// \returns The index into the set of loaded preprocessed entities, which
|
||||
|
@ -341,7 +355,7 @@ namespace clang {
|
|||
|
||||
public:
|
||||
/// \brief Construct a new preprocessing record.
|
||||
explicit PreprocessingRecord(bool IncludeNestedMacroExpansions);
|
||||
PreprocessingRecord(SourceManager &SM, bool IncludeNestedMacroExpansions);
|
||||
|
||||
/// \brief Allocate memory in the preprocessing record.
|
||||
void *Allocate(unsigned Size, unsigned Align = 8) {
|
||||
|
@ -353,6 +367,8 @@ namespace clang {
|
|||
|
||||
size_t getTotalMemory() const;
|
||||
|
||||
SourceManager &getSourceManager() const { return SourceMgr; }
|
||||
|
||||
// Iteration over the preprocessed entities.
|
||||
class iterator {
|
||||
PreprocessingRecord *Self;
|
||||
|
@ -471,6 +487,10 @@ namespace clang {
|
|||
iterator begin(bool OnlyLocalEntities = false);
|
||||
iterator end(bool OnlyLocalEntities = false);
|
||||
|
||||
/// \brief Returns a pair of [Begin, End) iterators of preprocessed entities
|
||||
/// that source range \arg R encompasses.
|
||||
std::pair<iterator, iterator> getPreprocessedEntitiesInRange(SourceRange R);
|
||||
|
||||
/// \brief Add a new preprocessed entity to this record.
|
||||
void addPreprocessedEntity(PreprocessedEntity *Entity);
|
||||
|
||||
|
|
|
@ -141,6 +141,21 @@ namespace clang {
|
|||
/// preprocessing record.
|
||||
typedef uint32_t PreprocessedEntityID;
|
||||
|
||||
/// \brief Source range/offset of a preprocessed entity.
|
||||
struct PPEntityOffset {
|
||||
/// \brief Raw source location of beginning of range.
|
||||
unsigned Begin;
|
||||
/// \brief Raw source location of end of range.
|
||||
unsigned End;
|
||||
/// \brief Offset in the AST file.
|
||||
uint32_t BitOffset;
|
||||
|
||||
PPEntityOffset(SourceRange R, uint32_t BitOffset)
|
||||
: Begin(R.getBegin().getRawEncoding()),
|
||||
End(R.getEnd().getRawEncoding()),
|
||||
BitOffset(BitOffset) { }
|
||||
};
|
||||
|
||||
/// \brief The number of predefined preprocessed entity IDs.
|
||||
const unsigned int NUM_PREDEF_PP_ENTITY_IDS = 1;
|
||||
|
||||
|
|
|
@ -248,6 +248,12 @@ private:
|
|||
/// \brief A map of negated SLocEntryIDs to the modules containing them.
|
||||
ContinuousRangeMap<unsigned, Module*, 64> GlobalSLocEntryMap;
|
||||
|
||||
typedef ContinuousRangeMap<int, Module*, 64> GlobalSLocOffsetMapType;
|
||||
|
||||
/// \brief A map of negated SourceLocation offsets to the modules containing
|
||||
/// them.
|
||||
GlobalSLocOffsetMapType GlobalSLocOffsetMap;
|
||||
|
||||
/// \brief Types that have already been loaded from the chain.
|
||||
///
|
||||
/// When the pointer at index I is non-NULL, the type with
|
||||
|
@ -680,7 +686,23 @@ private:
|
|||
|
||||
RecordLocation getLocalBitOffset(uint64_t GlobalOffset);
|
||||
uint64_t getGlobalBitOffset(Module &M, uint32_t LocalOffset);
|
||||
|
||||
|
||||
/// \brief Returns the first preprocessed entity ID that ends after \arg BLoc.
|
||||
serialization::PreprocessedEntityID
|
||||
findBeginPreprocessedEntity(SourceLocation BLoc) const;
|
||||
|
||||
/// \brief Returns the first preprocessed entity ID that begins after \arg ELoc.
|
||||
serialization::PreprocessedEntityID
|
||||
findEndPreprocessedEntity(SourceLocation ELoc) const;
|
||||
|
||||
/// \brief \arg SLocMapI points at a chunk of a module that contains no
|
||||
/// preprocessed entities or the entities it contains are not the ones we are
|
||||
/// looking for. Find the next module that contains entities and return the ID
|
||||
/// of the first entry.
|
||||
serialization::PreprocessedEntityID
|
||||
findNextPreprocessedEntity(
|
||||
GlobalSLocOffsetMapType::const_iterator SLocMapI) const;
|
||||
|
||||
void PassInterestingDeclsToConsumer();
|
||||
|
||||
/// \brief Produce an error diagnostic and return true.
|
||||
|
@ -723,6 +745,8 @@ public:
|
|||
|
||||
~ASTReader();
|
||||
|
||||
SourceManager &getSourceManager() const { return SourceMgr; }
|
||||
|
||||
/// \brief Load the AST file designated by the given file name.
|
||||
ASTReadResult ReadAST(const std::string &FileName, ModuleKind Type);
|
||||
|
||||
|
@ -772,6 +796,11 @@ public:
|
|||
/// entity from being loaded.
|
||||
virtual PreprocessedEntity *ReadPreprocessedEntity(unsigned Index);
|
||||
|
||||
/// \brief Returns a pair of [Begin, End) indices of preallocated
|
||||
/// preprocessed entities that \arg Range encompasses.
|
||||
virtual std::pair<unsigned, unsigned>
|
||||
findPreprocessedEntitiesInRange(SourceRange Range);
|
||||
|
||||
/// \brief Read the preprocessed entity at the given offset.
|
||||
virtual PreprocessedEntity *ReadPreprocessedEntityAtOffset(uint64_t Offset);
|
||||
|
||||
|
|
|
@ -177,7 +177,7 @@ public:
|
|||
/// \brief Remapping table for preprocessed entity IDs in this module.
|
||||
ContinuousRangeMap<uint32_t, int, 2> PreprocessedEntityRemap;
|
||||
|
||||
const uint32_t *PreprocessedEntityOffsets;
|
||||
const PPEntityOffset *PreprocessedEntityOffsets;
|
||||
unsigned NumPreprocessedEntities;
|
||||
|
||||
// === Header search information ===
|
||||
|
|
|
@ -37,8 +37,9 @@ InclusionDirective::InclusionDirective(PreprocessingRecord &PPRec,
|
|||
this->FileName = StringRef(Memory, FileName.size());
|
||||
}
|
||||
|
||||
PreprocessingRecord::PreprocessingRecord(bool IncludeNestedMacroExpansions)
|
||||
: IncludeNestedMacroExpansions(IncludeNestedMacroExpansions),
|
||||
PreprocessingRecord::PreprocessingRecord(SourceManager &SM,
|
||||
bool IncludeNestedMacroExpansions)
|
||||
: SourceMgr(SM), IncludeNestedMacroExpansions(IncludeNestedMacroExpansions),
|
||||
ExternalSource(0)
|
||||
{
|
||||
}
|
||||
|
@ -55,7 +56,111 @@ PreprocessingRecord::iterator PreprocessingRecord::end(bool OnlyLocalEntities) {
|
|||
return iterator(this, PreprocessedEntities.size());
|
||||
}
|
||||
|
||||
/// \brief Returns a pair of [Begin, End) iterators of preprocessed entities
|
||||
/// that source range \arg R encompasses.
|
||||
std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
|
||||
PreprocessingRecord::getPreprocessedEntitiesInRange(SourceRange Range) {
|
||||
if (Range.isInvalid())
|
||||
return std::make_pair(iterator(this, 0), iterator(this, 0));
|
||||
assert(!SourceMgr.isBeforeInTranslationUnit(Range.getEnd(),Range.getBegin()));
|
||||
|
||||
std::pair<unsigned, unsigned>
|
||||
Local = findLocalPreprocessedEntitiesInRange(Range);
|
||||
|
||||
// Check if range spans local entities.
|
||||
if (!ExternalSource || SourceMgr.isLocalSourceLocation(Range.getBegin()))
|
||||
return std::make_pair(iterator(this, Local.first),
|
||||
iterator(this, Local.second));
|
||||
|
||||
std::pair<unsigned, unsigned>
|
||||
Loaded = ExternalSource->findPreprocessedEntitiesInRange(Range);
|
||||
|
||||
// Check if range spans local entities.
|
||||
if (Loaded.first == Loaded.second)
|
||||
return std::make_pair(iterator(this, Local.first),
|
||||
iterator(this, Local.second));
|
||||
|
||||
unsigned TotalLoaded = LoadedPreprocessedEntities.size();
|
||||
|
||||
// Check if range spans loaded entities.
|
||||
if (Local.first == Local.second)
|
||||
return std::make_pair(iterator(this, int(Loaded.first)-TotalLoaded),
|
||||
iterator(this, int(Loaded.second)-TotalLoaded));
|
||||
|
||||
// Range spands loaded and local entities.
|
||||
return std::make_pair(iterator(this, int(Loaded.first)-TotalLoaded),
|
||||
iterator(this, Local.second));
|
||||
}
|
||||
|
||||
std::pair<unsigned, unsigned>
|
||||
PreprocessingRecord::findLocalPreprocessedEntitiesInRange(
|
||||
SourceRange Range) const {
|
||||
if (Range.isInvalid())
|
||||
return std::make_pair(0,0);
|
||||
assert(!SourceMgr.isBeforeInTranslationUnit(Range.getEnd(),Range.getBegin()));
|
||||
|
||||
unsigned Begin = findBeginLocalPreprocessedEntity(Range.getBegin());
|
||||
unsigned End = findEndLocalPreprocessedEntity(Range.getEnd());
|
||||
return std::make_pair(Begin, End);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
template <SourceLocation (SourceRange::*getRangeLoc)() const>
|
||||
struct PPEntityComp {
|
||||
const SourceManager &SM;
|
||||
|
||||
explicit PPEntityComp(const SourceManager &SM) : SM(SM) { }
|
||||
|
||||
bool operator()(PreprocessedEntity *L, SourceLocation RHS) {
|
||||
SourceLocation LHS = getLoc(L);
|
||||
return SM.isBeforeInTranslationUnit(LHS, RHS);
|
||||
}
|
||||
|
||||
bool operator()(SourceLocation LHS, PreprocessedEntity *R) {
|
||||
SourceLocation RHS = getLoc(R);
|
||||
return SM.isBeforeInTranslationUnit(LHS, RHS);
|
||||
}
|
||||
|
||||
SourceLocation getLoc(PreprocessedEntity *PPE) const {
|
||||
return (PPE->getSourceRange().*getRangeLoc)();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
unsigned PreprocessingRecord::findBeginLocalPreprocessedEntity(
|
||||
SourceLocation Loc) const {
|
||||
if (SourceMgr.isLoadedSourceLocation(Loc))
|
||||
return 0;
|
||||
|
||||
std::vector<PreprocessedEntity *>::const_iterator
|
||||
I = std::lower_bound(PreprocessedEntities.begin(),
|
||||
PreprocessedEntities.end(),
|
||||
Loc,
|
||||
PPEntityComp<&SourceRange::getEnd>(SourceMgr));
|
||||
return I - PreprocessedEntities.begin();
|
||||
}
|
||||
|
||||
unsigned PreprocessingRecord::findEndLocalPreprocessedEntity(
|
||||
SourceLocation Loc) const {
|
||||
if (SourceMgr.isLoadedSourceLocation(Loc))
|
||||
return 0;
|
||||
|
||||
std::vector<PreprocessedEntity *>::const_iterator
|
||||
I = std::upper_bound(PreprocessedEntities.begin(),
|
||||
PreprocessedEntities.end(),
|
||||
Loc,
|
||||
PPEntityComp<&SourceRange::getBegin>(SourceMgr));
|
||||
return I - PreprocessedEntities.begin();
|
||||
}
|
||||
|
||||
void PreprocessingRecord::addPreprocessedEntity(PreprocessedEntity *Entity) {
|
||||
SourceLocation Loc = Entity->getSourceRange().getBegin();
|
||||
assert((PreprocessedEntities.empty() ||
|
||||
!SourceMgr.isBeforeInTranslationUnit(Loc,
|
||||
PreprocessedEntities.back()->getSourceRange().getEnd())) &&
|
||||
"Adding a preprocessed entity that is before the previous one in TU");
|
||||
PreprocessedEntities.push_back(Entity);
|
||||
}
|
||||
|
||||
|
@ -124,10 +229,10 @@ void PreprocessingRecord::MacroExpands(const Token &Id, const MacroInfo* MI,
|
|||
return;
|
||||
|
||||
if (MI->isBuiltinMacro())
|
||||
PreprocessedEntities.push_back(
|
||||
addPreprocessedEntity(
|
||||
new (*this) MacroExpansion(Id.getIdentifierInfo(),Range));
|
||||
else if (MacroDefinition *Def = findMacroDefinition(MI))
|
||||
PreprocessedEntities.push_back(
|
||||
addPreprocessedEntity(
|
||||
new (*this) MacroExpansion(Def, Range));
|
||||
}
|
||||
|
||||
|
@ -138,7 +243,7 @@ void PreprocessingRecord::MacroDefined(const Token &Id,
|
|||
= new (*this) MacroDefinition(Id.getIdentifierInfo(),
|
||||
MI->getDefinitionLoc(),
|
||||
R);
|
||||
PreprocessedEntities.push_back(Def);
|
||||
addPreprocessedEntity(Def);
|
||||
MacroDefinitions[MI] = getPPEntityID(PreprocessedEntities.size()-1,
|
||||
/*isLoaded=*/false);
|
||||
}
|
||||
|
@ -187,7 +292,7 @@ void PreprocessingRecord::InclusionDirective(
|
|||
clang::InclusionDirective *ID
|
||||
= new (*this) clang::InclusionDirective(*this, Kind, FileName, !IsAngled,
|
||||
File, SourceRange(HashLoc, EndLoc));
|
||||
PreprocessedEntities.push_back(ID);
|
||||
addPreprocessedEntity(ID);
|
||||
}
|
||||
|
||||
size_t PreprocessingRecord::getTotalMemory() const {
|
||||
|
|
|
@ -602,6 +602,7 @@ void Preprocessor::createPreprocessingRecord(
|
|||
if (Record)
|
||||
return;
|
||||
|
||||
Record = new PreprocessingRecord(IncludeNestedMacroExpansions);
|
||||
Record = new PreprocessingRecord(getSourceManager(),
|
||||
IncludeNestedMacroExpansions);
|
||||
addPPCallbacks(Record);
|
||||
}
|
||||
|
|
|
@ -2011,8 +2011,10 @@ ASTReader::ReadASTBlock(Module &F) {
|
|||
case SOURCE_LOCATION_OFFSETS: {
|
||||
F.SLocEntryOffsets = (const uint32_t *)BlobStart;
|
||||
F.LocalNumSLocEntries = Record[0];
|
||||
unsigned SLocSpaceSize = Record[1];
|
||||
llvm::tie(F.SLocEntryBaseID, F.SLocEntryBaseOffset) =
|
||||
SourceMgr.AllocateLoadedSLocEntries(F.LocalNumSLocEntries, Record[1]);
|
||||
SourceMgr.AllocateLoadedSLocEntries(F.LocalNumSLocEntries,
|
||||
SLocSpaceSize);
|
||||
// Make our entry in the range map. BaseID is negative and growing, so
|
||||
// we invert it. Because we invert it, though, we need the other end of
|
||||
// the range.
|
||||
|
@ -2021,6 +2023,12 @@ ASTReader::ReadASTBlock(Module &F) {
|
|||
GlobalSLocEntryMap.insert(std::make_pair(RangeStart, &F));
|
||||
F.FirstLoc = SourceLocation::getFromRawEncoding(F.SLocEntryBaseOffset);
|
||||
|
||||
// SLocEntryBaseOffset is lower than MaxLoadedOffset and decreasing.
|
||||
assert((F.SLocEntryBaseOffset & (1U << 31U)) == 0);
|
||||
GlobalSLocOffsetMap.insert(
|
||||
std::make_pair(SourceManager::MaxLoadedOffset - F.SLocEntryBaseOffset
|
||||
- SLocSpaceSize,&F));
|
||||
|
||||
// Initialize the remapping table.
|
||||
// Invalid stays invalid.
|
||||
F.SLocRemap.insert(std::make_pair(0U, 0));
|
||||
|
@ -2201,9 +2209,9 @@ ASTReader::ReadASTBlock(Module &F) {
|
|||
}
|
||||
|
||||
case PPD_ENTITIES_OFFSETS: {
|
||||
F.PreprocessedEntityOffsets = (const uint32_t *)BlobStart;
|
||||
assert(BlobLen % sizeof(uint32_t) == 0);
|
||||
F.NumPreprocessedEntities = BlobLen / sizeof(uint32_t);
|
||||
F.PreprocessedEntityOffsets = (const PPEntityOffset *)BlobStart;
|
||||
assert(BlobLen % sizeof(PPEntityOffset) == 0);
|
||||
F.NumPreprocessedEntities = BlobLen / sizeof(PPEntityOffset);
|
||||
|
||||
unsigned LocalBasePreprocessedEntityID = Record[0];
|
||||
|
||||
|
@ -2878,10 +2886,127 @@ PreprocessedEntity *ASTReader::ReadPreprocessedEntity(unsigned Index) {
|
|||
unsigned LocalIndex = Index - M.BasePreprocessedEntityID;
|
||||
|
||||
SavedStreamPosition SavedPosition(M.PreprocessorDetailCursor);
|
||||
M.PreprocessorDetailCursor.JumpToBit(M.PreprocessedEntityOffsets[LocalIndex]);
|
||||
M.PreprocessorDetailCursor.JumpToBit(
|
||||
M.PreprocessedEntityOffsets[LocalIndex].BitOffset);
|
||||
return LoadPreprocessedEntity(M);
|
||||
}
|
||||
|
||||
/// \brief \arg SLocMapI points at a chunk of a module that contains no
|
||||
/// preprocessed entities or the entities it contains are not the ones we are
|
||||
/// looking for. Find the next module that contains entities and return the ID
|
||||
/// of the first entry.
|
||||
PreprocessedEntityID ASTReader::findNextPreprocessedEntity(
|
||||
GlobalSLocOffsetMapType::const_iterator SLocMapI) const {
|
||||
++SLocMapI;
|
||||
for (GlobalSLocOffsetMapType::const_iterator
|
||||
EndI = GlobalSLocOffsetMap.end(); SLocMapI != EndI; ++SLocMapI) {
|
||||
Module &M = *SLocMapI->second;
|
||||
if (M.NumPreprocessedEntities)
|
||||
return getGlobalPreprocessedEntityID(M, M.BasePreprocessedEntityID);
|
||||
}
|
||||
|
||||
return getTotalNumPreprocessedEntities();
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
template <unsigned PPEntityOffset::*PPLoc>
|
||||
struct PPEntityComp {
|
||||
const ASTReader &Reader;
|
||||
Module &M;
|
||||
|
||||
PPEntityComp(const ASTReader &Reader, Module &M) : Reader(Reader), M(M) { }
|
||||
|
||||
bool operator()(const PPEntityOffset &L, SourceLocation RHS) {
|
||||
SourceLocation LHS = getLoc(L);
|
||||
return Reader.getSourceManager().isBeforeInTranslationUnit(LHS, RHS);
|
||||
}
|
||||
|
||||
bool operator()(SourceLocation LHS, const PPEntityOffset &R) {
|
||||
SourceLocation RHS = getLoc(R);
|
||||
return Reader.getSourceManager().isBeforeInTranslationUnit(LHS, RHS);
|
||||
}
|
||||
|
||||
SourceLocation getLoc(const PPEntityOffset &PPE) const {
|
||||
return Reader.ReadSourceLocation(M, PPE.*PPLoc);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
/// \brief Returns the first preprocessed entity ID that ends after \arg BLoc.
|
||||
PreprocessedEntityID
|
||||
ASTReader::findBeginPreprocessedEntity(SourceLocation BLoc) const {
|
||||
if (SourceMgr.isLocalSourceLocation(BLoc))
|
||||
return getTotalNumPreprocessedEntities();
|
||||
|
||||
GlobalSLocOffsetMapType::const_iterator
|
||||
SLocMapI = GlobalSLocOffsetMap.find(SourceManager::MaxLoadedOffset -
|
||||
BLoc.getOffset());
|
||||
assert(SLocMapI != GlobalSLocOffsetMap.end() &&
|
||||
"Corrupted global sloc offset map");
|
||||
|
||||
if (SLocMapI->second->NumPreprocessedEntities == 0)
|
||||
return findNextPreprocessedEntity(SLocMapI);
|
||||
|
||||
Module &M = *SLocMapI->second;
|
||||
typedef const PPEntityOffset *pp_iterator;
|
||||
pp_iterator pp_begin = M.PreprocessedEntityOffsets;
|
||||
pp_iterator pp_end = pp_begin + M.NumPreprocessedEntities;
|
||||
pp_iterator PPI =
|
||||
std::lower_bound(pp_begin, pp_end, BLoc,
|
||||
PPEntityComp<&PPEntityOffset::End>(*this, M));
|
||||
|
||||
if (PPI == pp_end)
|
||||
return findNextPreprocessedEntity(SLocMapI);
|
||||
|
||||
return getGlobalPreprocessedEntityID(M,
|
||||
M.BasePreprocessedEntityID + (PPI - pp_begin));
|
||||
}
|
||||
|
||||
/// \brief Returns the first preprocessed entity ID that begins after \arg ELoc.
|
||||
PreprocessedEntityID
|
||||
ASTReader::findEndPreprocessedEntity(SourceLocation ELoc) const {
|
||||
if (SourceMgr.isLocalSourceLocation(ELoc))
|
||||
return getTotalNumPreprocessedEntities();
|
||||
|
||||
GlobalSLocOffsetMapType::const_iterator
|
||||
SLocMapI = GlobalSLocOffsetMap.find(SourceManager::MaxLoadedOffset -
|
||||
ELoc.getOffset());
|
||||
assert(SLocMapI != GlobalSLocOffsetMap.end() &&
|
||||
"Corrupted global sloc offset map");
|
||||
|
||||
if (SLocMapI->second->NumPreprocessedEntities == 0)
|
||||
return findNextPreprocessedEntity(SLocMapI);
|
||||
|
||||
Module &M = *SLocMapI->second;
|
||||
typedef const PPEntityOffset *pp_iterator;
|
||||
pp_iterator pp_begin = M.PreprocessedEntityOffsets;
|
||||
pp_iterator pp_end = pp_begin + M.NumPreprocessedEntities;
|
||||
pp_iterator PPI =
|
||||
std::upper_bound(pp_begin, pp_end, ELoc,
|
||||
PPEntityComp<&PPEntityOffset::Begin>(*this, M));
|
||||
|
||||
if (PPI == pp_end)
|
||||
return findNextPreprocessedEntity(SLocMapI);
|
||||
|
||||
return getGlobalPreprocessedEntityID(M,
|
||||
M.BasePreprocessedEntityID + (PPI - pp_begin));
|
||||
}
|
||||
|
||||
/// \brief Returns a pair of [Begin, End) indices of preallocated
|
||||
/// preprocessed entities that \arg Range encompasses.
|
||||
std::pair<unsigned, unsigned>
|
||||
ASTReader::findPreprocessedEntitiesInRange(SourceRange Range) {
|
||||
if (Range.isInvalid())
|
||||
return std::make_pair(0,0);
|
||||
assert(!SourceMgr.isBeforeInTranslationUnit(Range.getEnd(),Range.getBegin()));
|
||||
|
||||
PreprocessedEntityID BeginID = findBeginPreprocessedEntity(Range.getBegin());
|
||||
PreprocessedEntityID EndID = findEndPreprocessedEntity(Range.getEnd());
|
||||
return std::make_pair(BeginID, EndID);
|
||||
}
|
||||
|
||||
PreprocessedEntity *ASTReader::ReadPreprocessedEntityAtOffset(uint64_t Offset) {
|
||||
RecordLocation Loc = getLocalBitOffset(Offset);
|
||||
|
||||
|
|
|
@ -1714,7 +1714,7 @@ void ASTWriter::WritePreprocessorDetail(PreprocessingRecord &PPRec) {
|
|||
if (PPRec.begin(Chain) == PPRec.end(Chain))
|
||||
return;
|
||||
|
||||
SmallVector<uint32_t, 64> PreprocessedEntityOffsets;
|
||||
SmallVector<PPEntityOffset, 64> PreprocessedEntityOffsets;
|
||||
|
||||
// Enter the preprocessor block.
|
||||
Stream.EnterSubblock(PREPROCESSOR_DETAIL_BLOCK_ID, 3);
|
||||
|
@ -1750,7 +1750,8 @@ void ASTWriter::WritePreprocessorDetail(PreprocessingRecord &PPRec) {
|
|||
(void)++E, ++NumPreprocessingRecords, ++NextPreprocessorEntityID) {
|
||||
Record.clear();
|
||||
|
||||
PreprocessedEntityOffsets.push_back(Stream.GetCurrentBitNo());
|
||||
PreprocessedEntityOffsets.push_back(PPEntityOffset((*E)->getSourceRange(),
|
||||
Stream.GetCurrentBitNo()));
|
||||
|
||||
if (MacroDefinition *MD = dyn_cast<MacroDefinition>(*E)) {
|
||||
// Record this macro definition's ID.
|
||||
|
|
Loading…
Reference in New Issue