@@ -296,57 +296,54 @@ static bool IsNOLINTFound(StringRef NolintDirectiveText, StringRef Line,
296
296
return true ;
297
297
}
298
298
299
+ llvm::Optional<StringRef> getBuffer (const SourceManager &SM, FileID File,
300
+ bool AllowIO) {
301
+ // This is similar to the implementation of SourceManager::getBufferData(),
302
+ // but uses ContentCache::getRawBuffer() rather than getBuffer() if
303
+ // AllowIO=false, to avoid triggering file I/O if the file contents aren't
304
+ // already mapped.
305
+ bool CharDataInvalid = false ;
306
+ const SrcMgr::SLocEntry &Entry = SM.getSLocEntry (File, &CharDataInvalid);
307
+ if (CharDataInvalid || !Entry.isFile ())
308
+ return llvm::None;
309
+ const SrcMgr::ContentCache *Cache = Entry.getFile ().getContentCache ();
310
+ const llvm::MemoryBuffer *Buffer =
311
+ AllowIO ? Cache->getBuffer (SM.getDiagnostics (), SM.getFileManager (),
312
+ SourceLocation (), &CharDataInvalid)
313
+ : Cache->getRawBuffer ();
314
+ if (!Buffer || CharDataInvalid)
315
+ return llvm::None;
316
+ return Buffer->getBuffer ();
317
+ }
318
+
299
319
static bool LineIsMarkedWithNOLINT (const SourceManager &SM, SourceLocation Loc,
300
320
unsigned DiagID,
301
- const ClangTidyContext &Context) {
302
- bool Invalid;
303
- const char *CharacterData = SM.getCharacterData (Loc, &Invalid);
304
- if (Invalid)
321
+ const ClangTidyContext &Context,
322
+ bool AllowIO) {
323
+ FileID File;
324
+ unsigned Offset;
325
+ std::tie (File, Offset) = SM.getDecomposedSpellingLoc (Loc);
326
+ llvm::Optional<StringRef> Buffer = getBuffer (SM, File, AllowIO);
327
+ if (!Buffer)
305
328
return false ;
306
329
307
330
// Check if there's a NOLINT on this line.
308
- const char *P = CharacterData;
309
- while (*P != ' \0 ' && *P != ' \r ' && *P != ' \n ' )
310
- ++P;
311
- StringRef RestOfLine (CharacterData, P - CharacterData + 1 );
331
+ StringRef RestOfLine = Buffer->substr (Offset).split (' \n ' ).first ;
312
332
if (IsNOLINTFound (" NOLINT" , RestOfLine, DiagID, Context))
313
333
return true ;
314
334
315
335
// Check if there's a NOLINTNEXTLINE on the previous line.
316
- const char *BufBegin =
317
- SM.getCharacterData (SM.getLocForStartOfFile (SM.getFileID (Loc)), &Invalid);
318
- if (Invalid || P == BufBegin)
319
- return false ;
320
-
321
- // Scan backwards over the current line.
322
- P = CharacterData;
323
- while (P != BufBegin && *P != ' \n ' )
324
- --P;
325
-
326
- // If we reached the begin of the file there is no line before it.
327
- if (P == BufBegin)
328
- return false ;
329
-
330
- // Skip over the newline.
331
- --P;
332
- const char *LineEnd = P;
333
-
334
- // Now we're on the previous line. Skip to the beginning of it.
335
- while (P != BufBegin && *P != ' \n ' )
336
- --P;
337
-
338
- RestOfLine = StringRef (P, LineEnd - P + 1 );
339
- if (IsNOLINTFound (" NOLINTNEXTLINE" , RestOfLine, DiagID, Context))
340
- return true ;
341
-
342
- return false ;
336
+ StringRef PrevLine =
337
+ Buffer->substr (0 , Offset).rsplit (' \n ' ).first .rsplit (' \n ' ).second ;
338
+ return IsNOLINTFound (" NOLINTNEXTLINE" , PrevLine, DiagID, Context);
343
339
}
344
340
345
341
static bool LineIsMarkedWithNOLINTinMacro (const SourceManager &SM,
346
342
SourceLocation Loc, unsigned DiagID,
347
- const ClangTidyContext &Context) {
343
+ const ClangTidyContext &Context,
344
+ bool AllowIO) {
348
345
while (true ) {
349
- if (LineIsMarkedWithNOLINT (SM, Loc, DiagID, Context))
346
+ if (LineIsMarkedWithNOLINT (SM, Loc, DiagID, Context, AllowIO ))
350
347
return true ;
351
348
if (!Loc.isMacroID ())
352
349
return false ;
@@ -360,14 +357,13 @@ namespace tidy {
360
357
361
358
bool shouldSuppressDiagnostic (DiagnosticsEngine::Level DiagLevel,
362
359
const Diagnostic &Info, ClangTidyContext &Context,
363
- bool CheckMacroExpansion ) {
360
+ bool AllowIO ) {
364
361
return Info.getLocation ().isValid () &&
365
362
DiagLevel != DiagnosticsEngine::Error &&
366
363
DiagLevel != DiagnosticsEngine::Fatal &&
367
- (CheckMacroExpansion ? LineIsMarkedWithNOLINTinMacro
368
- : LineIsMarkedWithNOLINT)(Info.getSourceManager (),
369
- Info.getLocation (),
370
- Info.getID (), Context);
364
+ LineIsMarkedWithNOLINTinMacro (Info.getSourceManager (),
365
+ Info.getLocation (), Info.getID (),
366
+ Context, AllowIO);
371
367
}
372
368
373
369
} // namespace tidy
0 commit comments