diff options
| author | Eric Liu <ioeric@google.com> | 2016-06-03 12:52:59 +0000 |
|---|---|---|
| committer | Eric Liu <ioeric@google.com> | 2016-06-03 12:52:59 +0000 |
| commit | 303baf53b1d5e355254f007d6ec17e461941bc77 (patch) | |
| tree | 1eab3d6bd965fd2973ffc95e696d3e5b478b291f /clang/lib/Format | |
| parent | 0f7e949a4276b0c65877ce954565f915a915513e (diff) | |
| download | bcm5719-llvm-303baf53b1d5e355254f007d6ec17e461941bc77.tar.gz bcm5719-llvm-303baf53b1d5e355254f007d6ec17e461941bc77.zip | |
[clang-format] skip empty lines and comments in the top of the code when inserting new headers.
Summary:
[clang-format] skip empty lines and comments in the top of the code when inserting new headers.
Pair-programmed with @hokein
Reviewers: djasper
Subscribers: ioeric, cfe-commits, hokein, klimek
Differential Revision: http://reviews.llvm.org/D20898
llvm-svn: 271664
Diffstat (limited to 'clang/lib/Format')
| -rw-r--r-- | clang/lib/Format/Format.cpp | 31 |
1 files changed, 23 insertions, 8 deletions
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index 794a3ce6b81..c1b31823acd 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -1469,6 +1469,20 @@ fixCppIncludeInsertions(StringRef Code, const tooling::Replacements &Replaces, StringRef FileName = Replaces.begin()->getFilePath(); IncludeCategoryManager Categories(Style, FileName); + std::unique_ptr<Environment> Env = + Environment::CreateVirtualEnvironment(Code, FileName, /*Ranges=*/{}); + const SourceManager &SourceMgr = Env->getSourceManager(); + Lexer Lex(Env->getFileID(), SourceMgr.getBuffer(Env->getFileID()), SourceMgr, + getFormattingLangOpts(Style)); + Token Tok; + // All new headers should be inserted after this offset. + int MinInsertOffset = Code.size(); + while (!Lex.LexFromRawLexer(Tok)) { + if (Tok.isNot(tok::comment)) { + MinInsertOffset = SourceMgr.getFileOffset(Tok.getLocation()); + break; + } + } // Record the offset of the end of the last include in each category. std::map<int, int> CategoryEndOffsets; // All possible priorities. @@ -1477,10 +1491,11 @@ fixCppIncludeInsertions(StringRef Code, const tooling::Replacements &Replaces, for (const auto &Category : Style.IncludeCategories) Priorities.insert(Category.Priority); int FirstIncludeOffset = -1; - int Offset = 0; - int AfterHeaderGuard = 0; + bool HeaderGuardFound = false; + StringRef TrimmedCode = Code.drop_front(MinInsertOffset); SmallVector<StringRef, 32> Lines; - Code.split(Lines, '\n'); + TrimmedCode.split(Lines, '\n'); + int Offset = MinInsertOffset; for (auto Line : Lines) { if (IncludeRegex.match(Line, &Matches)) { StringRef IncludeName = Matches[2]; @@ -1492,22 +1507,22 @@ fixCppIncludeInsertions(StringRef Code, const tooling::Replacements &Replaces, } Offset += Line.size() + 1; // FIXME: make header guard matching stricter, e.g. consider #ifndef. - if (AfterHeaderGuard == 0 && DefineRegex.match(Line)) - AfterHeaderGuard = Offset; + if (!HeaderGuardFound && DefineRegex.match(Line)) { + HeaderGuardFound = true; + MinInsertOffset = Offset; + } } // Populate CategoryEndOfssets: // - Ensure that CategoryEndOffset[Highest] is always populated. // - If CategoryEndOffset[Priority] isn't set, use the next higher value that // is set, up to CategoryEndOffset[Highest]. - // FIXME: skip comment section in the beginning of the code if there is no - // existing #include and #define. auto Highest = Priorities.begin(); if (CategoryEndOffsets.find(*Highest) == CategoryEndOffsets.end()) { if (FirstIncludeOffset >= 0) CategoryEndOffsets[*Highest] = FirstIncludeOffset; else - CategoryEndOffsets[*Highest] = AfterHeaderGuard; + CategoryEndOffsets[*Highest] = MinInsertOffset; } // By this point, CategoryEndOffset[Highest] is always set appropriately: // - to an appropriate location before/after existing #includes, or |

