Skip to content

Commit e523e38

Browse files
committed
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
1 parent 8c4b716 commit e523e38

File tree

2 files changed

+45
-8
lines changed

2 files changed

+45
-8
lines changed

clang/lib/Lex/PreprocessingRecord.cpp

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -129,12 +129,30 @@ unsigned PreprocessingRecord::findBeginLocalPreprocessedEntity(
129129
if (SourceMgr.isLoadedSourceLocation(Loc))
130130
return 0;
131131

132+
size_t Count = PreprocessedEntities.size();
133+
size_t Half;
132134
std::vector<PreprocessedEntity *>::const_iterator
133-
I = std::lower_bound(PreprocessedEntities.begin(),
134-
PreprocessedEntities.end(),
135-
Loc,
136-
PPEntityComp<&SourceRange::getEnd>(SourceMgr));
137-
return I - PreprocessedEntities.begin();
135+
First = PreprocessedEntities.begin();
136+
std::vector<PreprocessedEntity *>::const_iterator I;
137+
138+
// Do a binary search manually instead of using std::lower_bound because
139+
// The end locations of entities may be unordered (when a macro expansion
140+
// is inside another macro argument), but for this case it is not important
141+
// whether we get the first macro expansion or its containing macro.
142+
while (Count > 0) {
143+
Half = Count/2;
144+
I = First;
145+
std::advance(I, Half);
146+
if (SourceMgr.isBeforeInTranslationUnit((*I)->getSourceRange().getEnd(),
147+
Loc)){
148+
First = I;
149+
++First;
150+
Count = Count - Half - 1;
151+
} else
152+
Count = Half;
153+
}
154+
155+
return First - PreprocessedEntities.begin();
138156
}
139157

140158
unsigned PreprocessingRecord::findEndLocalPreprocessedEntity(

clang/lib/Serialization/ASTReader.cpp

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2947,9 +2947,28 @@ ASTReader::findBeginPreprocessedEntity(SourceLocation BLoc) const {
29472947
typedef const PPEntityOffset *pp_iterator;
29482948
pp_iterator pp_begin = M.PreprocessedEntityOffsets;
29492949
pp_iterator pp_end = pp_begin + M.NumPreprocessedEntities;
2950-
pp_iterator PPI =
2951-
std::lower_bound(pp_begin, pp_end, BLoc,
2952-
PPEntityComp<&PPEntityOffset::End>(*this, M));
2950+
2951+
size_t Count = M.NumPreprocessedEntities;
2952+
size_t Half;
2953+
pp_iterator First = pp_begin;
2954+
pp_iterator PPI;
2955+
2956+
// Do a binary search manually instead of using std::lower_bound because
2957+
// The end locations of entities may be unordered (when a macro expansion
2958+
// is inside another macro argument), but for this case it is not important
2959+
// whether we get the first macro expansion or its containing macro.
2960+
while (Count > 0) {
2961+
Half = Count/2;
2962+
PPI = First;
2963+
std::advance(PPI, Half);
2964+
if (SourceMgr.isBeforeInTranslationUnit(ReadSourceLocation(M, PPI->End),
2965+
BLoc)){
2966+
First = PPI;
2967+
++First;
2968+
Count = Count - Half - 1;
2969+
} else
2970+
Count = Half;
2971+
}
29532972

29542973
if (PPI == pp_end)
29552974
return findNextPreprocessedEntity(SLocMapI);

0 commit comments

Comments
 (0)