From 0903f8dac5d7a46d0219a196bc367449d1d81597 Mon Sep 17 00:00:00 2001 From: Argyrios Kyrtzidis Date: Fri, 19 Apr 2013 23:24:25 +0000 Subject: [PATCH] [libclang] Make sure the preable does not truncate comments. rdar://13647445 llvm-svn: 179907 --- clang/lib/Lex/Lexer.cpp | 17 +++++++++++++++-- clang/test/Index/comment-with-preamble.c | 13 +++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 clang/test/Index/comment-with-preamble.c diff --git a/clang/lib/Lex/Lexer.cpp b/clang/lib/Lex/Lexer.cpp index ed4666aa2117..9958287ba474 100644 --- a/clang/lib/Lex/Lexer.cpp +++ b/clang/lib/Lex/Lexer.cpp @@ -557,6 +557,7 @@ Lexer::ComputePreamble(const llvm::MemoryBuffer *Buffer, SourceLocation FileLoc = SourceLocation::getFromRawEncoding(StartOffset); Lexer TheLexer(FileLoc, LangOpts, Buffer->getBufferStart(), Buffer->getBufferStart(), Buffer->getBufferEnd()); + TheLexer.SetCommentRetentionState(true); // StartLoc will differ from FileLoc if there is a BOM that was skipped. SourceLocation StartLoc = TheLexer.getSourceLocation(); @@ -565,6 +566,7 @@ Lexer::ComputePreamble(const llvm::MemoryBuffer *Buffer, Token TheTok; Token IfStartTok; unsigned IfCount = 0; + SourceLocation ActiveCommentLoc; unsigned MaxLineOffset = 0; if (MaxLines) { @@ -612,13 +614,17 @@ Lexer::ComputePreamble(const llvm::MemoryBuffer *Buffer, } // Comments are okay; skip over them. - if (TheTok.getKind() == tok::comment) + if (TheTok.getKind() == tok::comment) { + if (ActiveCommentLoc.isInvalid()) + ActiveCommentLoc = TheTok.getLocation(); continue; + } if (TheTok.isAtStartOfLine() && TheTok.getKind() == tok::hash) { // This is the start of a preprocessor directive. Token HashTok = TheTok; InPreprocessorDirective = true; + ActiveCommentLoc = SourceLocation(); // Figure out which directive this is. Since we're lexing raw tokens, // we don't have an identifier table available. Instead, just look at @@ -689,7 +695,14 @@ Lexer::ComputePreamble(const llvm::MemoryBuffer *Buffer, break; } while (true); - SourceLocation End = IfCount? IfStartTok.getLocation() : TheTok.getLocation(); + SourceLocation End; + if (IfCount) + End = IfStartTok.getLocation(); + else if (ActiveCommentLoc.isValid()) + End = ActiveCommentLoc; // don't truncate a decl comment. + else + End = TheTok.getLocation(); + return std::make_pair(End.getRawEncoding() - StartLoc.getRawEncoding(), IfCount? IfStartTok.isAtStartOfLine() : TheTok.isAtStartOfLine()); diff --git a/clang/test/Index/comment-with-preamble.c b/clang/test/Index/comment-with-preamble.c new file mode 100644 index 000000000000..72e6140d129f --- /dev/null +++ b/clang/test/Index/comment-with-preamble.c @@ -0,0 +1,13 @@ +// Make sure the preable does not truncate comments. + +#ifndef BAZ +#define BAZ 3 +#endif + +//! Foo’s description. +void Foo(); + +// RUN: c-index-test -test-load-source-reparse 1 local %s | FileCheck %s +// RUN: env CINDEXTEST_EDITING=1 c-index-test -test-load-source-reparse 1 local %s | FileCheck %s + +// CHECK: FunctionDecl=Foo:8:6 RawComment=[//! Foo’s description.] RawCommentRange=[7:1 - 7:25] BriefComment=[Foo’s description.]