diff --git a/lib/Lex/PreprocessingRecord.cpp b/lib/Lex/PreprocessingRecord.cpp index 438eba00ba..0f5577520d 100644 --- a/lib/Lex/PreprocessingRecord.cpp +++ b/lib/Lex/PreprocessingRecord.cpp @@ -129,12 +129,30 @@ unsigned PreprocessingRecord::findBeginLocalPreprocessedEntity( if (SourceMgr.isLoadedSourceLocation(Loc)) return 0; + size_t Count = PreprocessedEntities.size(); + size_t Half; std::vector::const_iterator - I = std::lower_bound(PreprocessedEntities.begin(), - PreprocessedEntities.end(), - Loc, - PPEntityComp<&SourceRange::getEnd>(SourceMgr)); - return I - PreprocessedEntities.begin(); + First = PreprocessedEntities.begin(); + std::vector::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( diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index 5f489d4067..f83f709ebe 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/lib/Serialization/ASTReader.cpp @@ -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);