summaryrefslogtreecommitdiffstats
path: root/clang/lib/Serialization/ASTReader.cpp
diff options
context:
space:
mode:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>2011-09-19 20:40:25 +0000
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>2011-09-19 20:40:25 +0000
commit64f6381097aeeac4891d985ee9bf0a3208112334 (patch)
treef21c50b861beb63a99a65f90814e59e0a7241d5f /clang/lib/Serialization/ASTReader.cpp
parente6e67deeed359c86ad74bd5525df676d7914faef (diff)
downloadbcm5719-llvm-64f6381097aeeac4891d985ee9bf0a3208112334.tar.gz
bcm5719-llvm-64f6381097aeeac4891d985ee9bf0a3208112334.zip
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
Diffstat (limited to 'clang/lib/Serialization/ASTReader.cpp')
-rw-r--r--clang/lib/Serialization/ASTReader.cpp135
1 files changed, 130 insertions, 5 deletions
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index 0c23431b940..0f3cad55139 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -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);
OpenPOWER on IntegriCloud