Implement a lexer for structured comments.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@159223 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/tools/c-index-test/c-index-test.c b/tools/c-index-test/c-index-test.c
index 4c9723d..73e3e58 100644
--- a/tools/c-index-test/c-index-test.c
+++ b/tools/c-index-test/c-index-test.c
@@ -162,6 +162,24 @@
 /* Pretty-printing.                                                           */
 /******************************************************************************/
 
+static void PrintCString(const char *Prefix, const char *CStr) {
+  printf(" %s=[", Prefix);
+  if (CStr != NULL && CStr[0] != '\0') {
+    for ( ; *CStr; ++CStr) {
+      const char C = *CStr;
+      switch (C) {
+        case '\n': printf("\\n"); break;
+        case '\r': printf("\\r"); break;
+        case '\t': printf("\\t"); break;
+        case '\v': printf("\\v"); break;
+        case '\f': printf("\\f"); break;
+        default:   putchar(C);    break;
+      }
+    }
+  }
+  printf("]");
+}
+
 static void PrintRange(CXSourceRange R, const char *str) {
   CXFile begin_file, end_file;
   unsigned begin_line, begin_column, end_line, end_column;
@@ -218,8 +236,10 @@
     CXPlatformAvailability PlatformAvailability[2];
     int NumPlatformAvailability;
     int I;
-    CXString Comment;
-    const char *CommentCString;
+    CXString RawComment;
+    const char *RawCommentCString;
+    CXString BriefComment;
+    const char *BriefCommentCString;
 
     ks = clang_getCursorKindSpelling(Cursor.kind);
     string = want_display_name? clang_getCursorDisplayName(Cursor) 
@@ -401,21 +421,19 @@
         PrintRange(RefNameRange, "RefName");
     }
 
-    Comment = clang_Cursor_getRawCommentText(Cursor);
-    CommentCString = clang_getCString(Comment);
-    if (CommentCString != NULL && CommentCString[0] != '\0') {
-      printf(" Comment=[");
-      for ( ; *CommentCString; ++CommentCString) {
-        if (*CommentCString != '\n')
-          putchar(*CommentCString);
-        else
-          printf("\\n");
-      }
-      printf("]");
+    RawComment = clang_Cursor_getRawCommentText(Cursor);
+    RawCommentCString = clang_getCString(RawComment);
+    if (RawCommentCString != NULL && RawCommentCString[0] != '\0') {
+      PrintCString("RawComment", RawCommentCString);
+      PrintRange(clang_Cursor_getCommentRange(Cursor), "RawCommentRange");
 
-      PrintRange(clang_Cursor_getCommentRange(Cursor), "CommentRange");
+      BriefComment = clang_Cursor_getBriefCommentText(Cursor);
+      BriefCommentCString = clang_getCString(BriefComment);
+      if (BriefCommentCString != NULL && BriefCommentCString[0] != '\0')
+        PrintCString("BriefComment", BriefCommentCString);
+      clang_disposeString(BriefComment);
     }
-    clang_disposeString(Comment);
+    clang_disposeString(RawComment);
   }
 }
 
diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp
index df8adb4..250e9e7 100644
--- a/tools/libclang/CIndex.cpp
+++ b/tools/libclang/CIndex.cpp
@@ -5707,6 +5707,24 @@
 
 } // end: extern "C"
 
+CXString clang_Cursor_getBriefCommentText(CXCursor C) {
+  if (!clang_isDeclaration(C.kind))
+    return createCXString((const char *) NULL);
+
+  const Decl *D = getCursorDecl(C);
+  const ASTContext &Context = getCursorContext(C);
+  const RawComment *RC = Context.getRawCommentForDecl(D);
+
+  if (RC && RC->isDocumentation()) {
+    StringRef BriefText = RC->getBriefText(Context);
+
+    // Don't duplicate the string because RawComment ensures that this memory
+    // will not go away.
+    return createCXString(BriefText, false);
+  }
+
+  return createCXString((const char *) NULL);
+}
 
 //===----------------------------------------------------------------------===//
 // C++ AST instrospection.
diff --git a/tools/libclang/libclang.exports b/tools/libclang/libclang.exports
index d24960b..c28b3b4 100644
--- a/tools/libclang/libclang.exports
+++ b/tools/libclang/libclang.exports
@@ -5,6 +5,7 @@
 clang_CXXMethod_isStatic
 clang_CXXMethod_isVirtual
 clang_Cursor_getArgument
+clang_Cursor_getBriefCommentText
 clang_Cursor_getCommentRange
 clang_Cursor_getRawCommentText
 clang_Cursor_getNumArguments