diff options
author | Ismail Pazarbasi <ismail.pazarbasi@gmail.com> | 2013-10-12 23:17:37 +0000 |
---|---|---|
committer | Ismail Pazarbasi <ismail.pazarbasi@gmail.com> | 2013-10-12 23:17:37 +0000 |
commit | 8d0f2f3ae3bc24a7847ce0984612653e60dcfb09 (patch) | |
tree | 4003a5400c97b102d0c78c350fc8c7cd2e0f7f0c /clang/lib/Lex | |
parent | 96bb15f464cfe957bdf816c76de3059eefc5d572 (diff) | |
download | bcm5719-llvm-8d0f2f3ae3bc24a7847ce0984612653e60dcfb09.tar.gz bcm5719-llvm-8d0f2f3ae3bc24a7847ce0984612653e60dcfb09.zip |
Relax header guard mismatch warning with edit distance heuristic.
If the edit distance between the two macros is more than 50%, DefinedMacro may not be header guard or can be header guard of another header file or it might be defining something completely different set by the build environment.
llvm-svn: 192547
Diffstat (limited to 'clang/lib/Lex')
-rw-r--r-- | clang/lib/Lex/PPLexerChange.cpp | 39 |
1 files changed, 26 insertions, 13 deletions
diff --git a/clang/lib/Lex/PPLexerChange.cpp b/clang/lib/Lex/PPLexerChange.cpp index 1193c3ce4ec..1f970a4450d 100644 --- a/clang/lib/Lex/PPLexerChange.cpp +++ b/clang/lib/Lex/PPLexerChange.cpp @@ -264,19 +264,32 @@ bool Preprocessor::HandleEndOfFile(Token &Result, bool isEndOfMacro) { if (!ControllingMacro->hasMacroDefinition() && DefinedMacro != ControllingMacro && HeaderInfo.FirstTimeLexingFile(FE)) { - // Emit a warning for a bad header guard. - Diag(CurPPLexer->MIOpt.GetMacroLocation(), - diag::warn_header_guard) - << CurPPLexer->MIOpt.GetMacroLocation() - << ControllingMacro; - Diag(CurPPLexer->MIOpt.GetDefinedLocation(), - diag::note_header_guard) - << CurPPLexer->MIOpt.GetDefinedLocation() - << DefinedMacro - << ControllingMacro - << FixItHint::CreateReplacement( - CurPPLexer->MIOpt.GetDefinedLocation(), - ControllingMacro->getName()); + + // If the edit distance between the two macros is more than 50%, + // DefinedMacro may not be header guard, or can be header guard of + // another header file. Therefore, it maybe defining something + // completely different. This can be observed in the wild when + // handling feature macros or header guards in different files. + + const StringRef ControllingMacroName = ControllingMacro->getName(); + const StringRef DefinedMacroName = DefinedMacro->getName(); + const size_t MaxHalfLength = std::max(ControllingMacroName.size(), + DefinedMacroName.size()) / 2; + const unsigned ED = ControllingMacroName.edit_distance( + DefinedMacroName, true, MaxHalfLength); + if (ED <= MaxHalfLength) { + // Emit a warning for a bad header guard. + Diag(CurPPLexer->MIOpt.GetMacroLocation(), + diag::warn_header_guard) + << CurPPLexer->MIOpt.GetMacroLocation() << ControllingMacro; + Diag(CurPPLexer->MIOpt.GetDefinedLocation(), + diag::note_header_guard) + << CurPPLexer->MIOpt.GetDefinedLocation() << DefinedMacro + << ControllingMacro + << FixItHint::CreateReplacement( + CurPPLexer->MIOpt.GetDefinedLocation(), + ControllingMacro->getName()); + } } } } |