]> granicus.if.org Git - clang/commitdiff
[libclang] Make sure the preable does not truncate comments.
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>
Fri, 19 Apr 2013 23:24:25 +0000 (23:24 +0000)
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>
Fri, 19 Apr 2013 23:24:25 +0000 (23:24 +0000)
rdar://13647445

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@179907 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Lex/Lexer.cpp
test/Index/comment-with-preamble.c [new file with mode: 0644]

index ed4666aa2117ff08b71182eb24ee5de403207a0c..9958287ba4744f49ae085e9b8ceb7c9337e124ed 100644 (file)
@@ -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/test/Index/comment-with-preamble.c b/test/Index/comment-with-preamble.c
new file mode 100644 (file)
index 0000000..72e6140
--- /dev/null
@@ -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.]