Do manual binary search for preprocessing entities because their end locations

may be unordered and MSVC's debug-mode doesn't like it.

llvm-svn: 140337
This commit is contained in:
Argyrios Kyrtzidis 2011-09-22 21:17:02 +00:00
parent 8c4b716352
commit e523e389b2
2 changed files with 45 additions and 8 deletions

View File

@ -129,12 +129,30 @@ unsigned PreprocessingRecord::findBeginLocalPreprocessedEntity(
if (SourceMgr.isLoadedSourceLocation(Loc))
return 0;
size_t Count = PreprocessedEntities.size();
size_t Half;
std::vector<PreprocessedEntity *>::const_iterator
I = std::lower_bound(PreprocessedEntities.begin(),
PreprocessedEntities.end(),
Loc,
PPEntityComp<&SourceRange::getEnd>(SourceMgr));
return I - PreprocessedEntities.begin();
First = PreprocessedEntities.begin();
std::vector<PreprocessedEntity *>::const_iterator I;
// Do a binary search manually instead of using std::lower_bound because
// The end locations of entities may be unordered (when a macro expansion
// is inside another macro argument), but for this case it is not important
// whether we get the first macro expansion or its containing macro.
while (Count > 0) {
Half = Count/2;
I = First;
std::advance(I, Half);
if (SourceMgr.isBeforeInTranslationUnit((*I)->getSourceRange().getEnd(),
Loc)){
First = I;
++First;
Count = Count - Half - 1;
} else
Count = Half;
}
return First - PreprocessedEntities.begin();
}
unsigned PreprocessingRecord::findEndLocalPreprocessedEntity(

View File

@ -2947,9 +2947,28 @@ ASTReader::findBeginPreprocessedEntity(SourceLocation BLoc) const {
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));
size_t Count = M.NumPreprocessedEntities;
size_t Half;
pp_iterator First = pp_begin;
pp_iterator PPI;
// Do a binary search manually instead of using std::lower_bound because
// The end locations of entities may be unordered (when a macro expansion
// is inside another macro argument), but for this case it is not important
// whether we get the first macro expansion or its containing macro.
while (Count > 0) {
Half = Count/2;
PPI = First;
std::advance(PPI, Half);
if (SourceMgr.isBeforeInTranslationUnit(ReadSourceLocation(M, PPI->End),
BLoc)){
First = PPI;
++First;
Count = Count - Half - 1;
} else
Count = Half;
}
if (PPI == pp_end)
return findNextPreprocessedEntity(SLocMapI);