Add a new libclang completion API to get brief documentation comment that is
attached to a declaration in the completion string.

Since extracting comments isn't free, a new code completion option is
introduced.

A new code completion option that enables including brief comments
into CodeCompletionString should be a, err, code completion option.
But because ASTUnit caches global declarations during parsing before
even completion consumer is created, the option is duplicated as a
translation unit option (in both libclang and ASTUnit, like the option
to cache code completion results).



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@159539 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h
index fd04877..b34918f 100644
--- a/include/clang-c/Index.h
+++ b/include/clang-c/Index.h
@@ -1058,7 +1058,14 @@
    * This option can be used to search for declarations/definitions while
    * ignoring the usages.
    */
-  CXTranslationUnit_SkipFunctionBodies = 0x40
+  CXTranslationUnit_SkipFunctionBodies = 0x40,
+
+  /**
+   * \brief Used to indicate that brief documentation comments should be
+   * included into the set of code completions returned from this translation
+   * unit.
+   */
+  CXTranslationUnit_IncludeBriefCommentsInCodeCompletion = 0x80
 };
 
 /**
@@ -3786,6 +3793,14 @@
 CINDEX_LINKAGE CXString
 clang_getCompletionParent(CXCompletionString completion_string,
                           enum CXCursorKind *kind);
+
+/**
+ * \brief Retrieve the brief documentation comment attached to the declaration
+ * that corresponds to the given completion string.
+ */
+CINDEX_LINKAGE CXString
+clang_getCompletionBriefComment(CXCompletionString completion_string);
+
 /**
  * \brief Retrieve a completion string for an arbitrary declaration or macro
  * definition cursor.
@@ -3836,7 +3851,13 @@
    * \brief Whether to include code patterns for language constructs
    * within the set of code completions, e.g., for loops.
    */
-  CXCodeComplete_IncludeCodePatterns = 0x02
+  CXCodeComplete_IncludeCodePatterns = 0x02,
+
+  /**
+   * \brief Whether to include brief documentation within the set of code
+   * completions returned.
+   */
+  CXCodeComplete_IncludeBriefComments = 0x04
 };
 
 /**
diff --git a/include/clang/AST/RawCommentList.h b/include/clang/AST/RawCommentList.h
index 73816b7..dc8bbad 100644
--- a/include/clang/AST/RawCommentList.h
+++ b/include/clang/AST/RawCommentList.h
@@ -92,7 +92,7 @@
   unsigned getBeginLine(const SourceManager &SM) const;
   unsigned getEndLine(const SourceManager &SM) const;
 
-  StringRef getBriefText(const ASTContext &Context) const {
+  const char *getBriefText(const ASTContext &Context) const {
     if (BriefTextValid)
       return BriefText;
 
@@ -103,7 +103,7 @@
   SourceRange Range;
 
   mutable StringRef RawText;
-  mutable StringRef BriefText;
+  mutable const char *BriefText;
 
   mutable bool RawTextValid : 1;   ///< True if RawText is valid
   mutable bool BriefTextValid : 1; ///< True if BriefText is valid
@@ -129,7 +129,7 @@
 
   StringRef getRawTextSlow(const SourceManager &SourceMgr) const;
 
-  StringRef extractBriefText(const ASTContext &Context) const;
+  const char *extractBriefText(const ASTContext &Context) const;
 
   friend class ASTReader;
 };
diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td
index da22046..436aed4 100644
--- a/include/clang/Driver/CC1Options.td
+++ b/include/clang/Driver/CC1Options.td
@@ -269,6 +269,8 @@
   HelpText<"Include code patterns in code-completion results">;
 def no_code_completion_globals : Flag<"-no-code-completion-globals">,
   HelpText<"Do not include global declarations in code-completion results.">;
+def code_completion_brief_comments : Flag<"-code-completion-brief-comments">,
+  HelpText<"Include brief documentation comments in code-completion results.">;
 def disable_free : Flag<"-disable-free">,
   HelpText<"Disable freeing of memory on exit">;
 def load : Separate<"-load">, MetaVarName<"<dsopath>">,
diff --git a/include/clang/Frontend/ASTUnit.h b/include/clang/Frontend/ASTUnit.h
index c22a18b..cc503bc 100644
--- a/include/clang/Frontend/ASTUnit.h
+++ b/include/clang/Frontend/ASTUnit.h
@@ -248,7 +248,11 @@
   std::vector<serialization::DeclID> TopLevelDeclsInPreamble;
   
   /// \brief Whether we should be caching code-completion results.
-  bool ShouldCacheCodeCompletionResults;
+  bool ShouldCacheCodeCompletionResults : 1;
+
+  /// \brief Whether to include brief documentation within the set of code
+  /// completions cached.
+  bool IncludeBriefCommentsInCodeCompletion : 1;
  
   /// \brief The language options used when we load an AST file.
   LangOptions ASTFileLangOpts;
@@ -681,6 +685,7 @@
                                              bool CaptureDiagnostics = false,
                                              bool PrecompilePreamble = false,
                                        bool CacheCodeCompletionResults = false,
+                              bool IncludeBriefCommentsInCodeCompletion = false,
                                        OwningPtr<ASTUnit> *ErrAST = 0);
 
   /// LoadFromCompilerInvocation - Create an ASTUnit from a source file, via a
@@ -700,7 +705,8 @@
                                              bool CaptureDiagnostics = false,
                                              bool PrecompilePreamble = false,
                                       TranslationUnitKind TUKind = TU_Complete,
-                                       bool CacheCodeCompletionResults = false);
+                                       bool CacheCodeCompletionResults = false,
+                            bool IncludeBriefCommentsInCodeCompletion = false);
 
   /// LoadFromCommandLine - Create an ASTUnit from a vector of command line
   /// arguments, which must specify exactly one source file.
@@ -732,6 +738,7 @@
                                       bool PrecompilePreamble = false,
                                       TranslationUnitKind TUKind = TU_Complete,
                                       bool CacheCodeCompletionResults = false,
+                            bool IncludeBriefCommentsInCodeCompletion = false,
                                       bool AllowPCHWithCompilerErrors = false,
                                       bool SkipFunctionBodies = false,
                                       OwningPtr<ASTUnit> *ErrAST = 0);
@@ -759,11 +766,15 @@
   /// \param IncludeCodePatterns Whether to include code patterns (such as a 
   /// for loop) in the code-completion results.
   ///
+  /// \param IncludeBriefComments Whether to include brief documentation within
+  /// the set of code completions returned.
+  ///
   /// FIXME: The Diag, LangOpts, SourceMgr, FileMgr, StoredDiagnostics, and
   /// OwnedBuffers parameters are all disgusting hacks. They will go away.
   void CodeComplete(StringRef File, unsigned Line, unsigned Column,
                     RemappedFile *RemappedFiles, unsigned NumRemappedFiles,
                     bool IncludeMacros, bool IncludeCodePatterns,
+                    bool IncludeBriefComments,
                     CodeCompleteConsumer &Consumer,
                     DiagnosticsEngine &Diag, LangOptions &LangOpts,
                     SourceManager &SourceMgr, FileManager &FileMgr,
diff --git a/include/clang/Frontend/CompilerInstance.h b/include/clang/Frontend/CompilerInstance.h
index 1bb7695..b28e103 100644
--- a/include/clang/Frontend/CompilerInstance.h
+++ b/include/clang/Frontend/CompilerInstance.h
@@ -560,8 +560,7 @@
   static CodeCompleteConsumer *
   createCodeCompletionConsumer(Preprocessor &PP, const std::string &Filename,
                                unsigned Line, unsigned Column,
-                               bool ShowMacros,
-                               bool ShowCodePatterns, bool ShowGlobals,
+                               const CodeCompleteOptions &Opts,
                                raw_ostream &OS);
 
   /// \brief Create the Sema object to be used for parsing.
diff --git a/include/clang/Frontend/FrontendOptions.h b/include/clang/Frontend/FrontendOptions.h
index 48cd317..22cce9c 100644
--- a/include/clang/Frontend/FrontendOptions.h
+++ b/include/clang/Frontend/FrontendOptions.h
@@ -11,6 +11,7 @@
 #define LLVM_CLANG_FRONTEND_FRONTENDOPTIONS_H
 
 #include "clang/Frontend/CommandLineSourceLoc.h"
+#include "clang/Sema/CodeCompleteOptions.h"
 #include "llvm/ADT/StringRef.h"
 #include <string>
 #include <vector>
@@ -84,7 +85,7 @@
   FrontendInputFile(StringRef File, InputKind Kind, bool IsSystem = false)
     : File(File.str()), Kind(Kind), IsSystem(IsSystem) { }
 };
-  
+
 /// FrontendOptions - Options for controlling the behavior of the frontend.
 class FrontendOptions {
 public:
@@ -93,12 +94,6 @@
                                            /// instruct the AST writer to create
                                            /// relocatable PCH files.
   unsigned ShowHelp : 1;                   ///< Show the -help text.
-  unsigned ShowMacrosInCodeCompletion : 1; ///< Show macros in code completion
-                                           /// results.
-  unsigned ShowCodePatternsInCodeCompletion : 1; ///< Show code patterns in code
-                                                 /// completion results.
-  unsigned ShowGlobalSymbolsInCodeCompletion : 1; ///< Show top-level decls in
-                                                  /// code completion results.
   unsigned ShowStats : 1;                  ///< Show frontend performance
                                            /// metrics and statistics.
   unsigned ShowTimers : 1;                 ///< Show timers for individual
@@ -116,6 +111,8 @@
                                            /// not need them (e.g. with code
                                            /// completion).
 
+  CodeCompleteOptions CodeCompleteOpts;
+
   enum {
     ARCMT_None,
     ARCMT_Check,
@@ -183,9 +180,6 @@
     ActionName = "";
     RelocatablePCH = 0;
     ShowHelp = 0;
-    ShowMacrosInCodeCompletion = 0;
-    ShowCodePatternsInCodeCompletion = 0;
-    ShowGlobalSymbolsInCodeCompletion = 1;
     ShowStats = 0;
     ShowTimers = 0;
     ShowVersion = 0;
diff --git a/include/clang/Sema/CodeCompleteConsumer.h b/include/clang/Sema/CodeCompleteConsumer.h
index f7c7586..d43aaaf 100644
--- a/include/clang/Sema/CodeCompleteConsumer.h
+++ b/include/clang/Sema/CodeCompleteConsumer.h
@@ -15,6 +15,7 @@
 
 #include "clang/AST/Type.h"
 #include "clang/AST/CanonicalType.h"
+#include "clang/Sema/CodeCompleteOptions.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/Allocator.h"
@@ -444,6 +445,10 @@
   
   /// \brief The name of the parent context.
   StringRef ParentName;
+
+  /// \brief A brief documentation comment attached to the declaration of
+  /// entity being completed by this result.
+  const char *BriefComment;
   
   CodeCompletionString(const CodeCompletionString &); // DO NOT IMPLEMENT
   CodeCompletionString &operator=(const CodeCompletionString &); // DITTO
@@ -451,7 +456,8 @@
   CodeCompletionString(const Chunk *Chunks, unsigned NumChunks,
                        unsigned Priority, CXAvailabilityKind Availability,
                        const char **Annotations, unsigned NumAnnotations,
-                       CXCursorKind ParentKind, StringRef ParentName);
+                       CXCursorKind ParentKind, StringRef ParentName,
+                       const char *BriefComment);
   ~CodeCompletionString() { }
 
   friend class CodeCompletionBuilder;
@@ -493,6 +499,10 @@
   StringRef getParentContextName() const {
     return ParentName;
   }
+
+  const char *getBriefComment() const {
+    return BriefComment;
+  }
   
   /// \brief Retrieve a string representation of the code completion string,
   /// which is mainly useful for debugging.
@@ -569,6 +579,7 @@
   CXAvailabilityKind Availability;
   CXCursorKind ParentKind;
   StringRef ParentName;
+  const char *BriefComment;
   
   /// \brief The chunks stored in this string.
   SmallVector<Chunk, 4> Chunks;
@@ -580,14 +591,14 @@
                         CodeCompletionTUInfo &CCTUInfo)
     : Allocator(Allocator), CCTUInfo(CCTUInfo),
       Priority(0), Availability(CXAvailability_Available),
-      ParentKind(CXCursor_NotImplemented) { }
+      ParentKind(CXCursor_NotImplemented), BriefComment(NULL) { }
 
   CodeCompletionBuilder(CodeCompletionAllocator &Allocator,
                         CodeCompletionTUInfo &CCTUInfo,
                         unsigned Priority, CXAvailabilityKind Availability)
     : Allocator(Allocator), CCTUInfo(CCTUInfo),
       Priority(Priority), Availability(Availability),
-      ParentKind(CXCursor_NotImplemented) { }
+      ParentKind(CXCursor_NotImplemented), BriefComment(NULL) { }
 
   /// \brief Retrieve the allocator into which the code completion
   /// strings should be allocated.
@@ -628,6 +639,8 @@
 
   /// \brief Add the parent context information to this code completion.
   void addParentContext(DeclContext *DC);
+
+  void addBriefComment(StringRef Comment);
   
   CXCursorKind getParentKind() const { return ParentKind; }
   StringRef getParentName() const { return ParentName; }
@@ -780,11 +793,13 @@
   /// string itself.
   CodeCompletionString *CreateCodeCompletionString(Sema &S,
                                            CodeCompletionAllocator &Allocator,
-                                           CodeCompletionTUInfo &CCTUInfo);
+                                           CodeCompletionTUInfo &CCTUInfo,
+                                           bool IncludeBriefComments);
   CodeCompletionString *CreateCodeCompletionString(ASTContext &Ctx,
                                                    Preprocessor &PP,
                                            CodeCompletionAllocator &Allocator,
-                                           CodeCompletionTUInfo &CCTUInfo);
+                                           CodeCompletionTUInfo &CCTUInfo,
+                                           bool IncludeBriefComments);
 
   /// \brief Determine a base priority for the given declaration.
   static unsigned getPriorityFromDecl(NamedDecl *ND);
@@ -818,16 +833,7 @@
 /// information.
 class CodeCompleteConsumer {
 protected:
-  /// \brief Whether to include macros in the code-completion results.
-  bool IncludeMacros;
-
-  /// \brief Whether to include code patterns (such as for loops) within
-  /// the completion results.
-  bool IncludeCodePatterns;
-
-  /// \brief Whether to include global (top-level) declarations and names in
-  /// the completion results.
-  bool IncludeGlobals;
+  const CodeCompleteOptions CodeCompleteOpts;
 
   /// \brief Whether the output format for the code-completion consumer is
   /// binary.
@@ -900,22 +906,31 @@
                                       CodeCompletionTUInfo &CCTUInfo) const;
   };
 
-  CodeCompleteConsumer() : IncludeMacros(false), IncludeCodePatterns(false),
-                           IncludeGlobals(true), OutputIsBinary(false) { }
-
-  CodeCompleteConsumer(bool IncludeMacros, bool IncludeCodePatterns,
-                       bool IncludeGlobals, bool OutputIsBinary)
-    : IncludeMacros(IncludeMacros), IncludeCodePatterns(IncludeCodePatterns),
-      IncludeGlobals(IncludeGlobals), OutputIsBinary(OutputIsBinary) { }
+  CodeCompleteConsumer(const CodeCompleteOptions &CodeCompleteOpts,
+                       bool OutputIsBinary)
+    : CodeCompleteOpts(CodeCompleteOpts), OutputIsBinary(OutputIsBinary)
+  { }
 
   /// \brief Whether the code-completion consumer wants to see macros.
-  bool includeMacros() const { return IncludeMacros; }
+  bool includeMacros() const {
+    return CodeCompleteOpts.IncludeMacros;
+  }
 
   /// \brief Whether the code-completion consumer wants to see code patterns.
-  bool includeCodePatterns() const { return IncludeCodePatterns; }
+  bool includeCodePatterns() const {
+    return CodeCompleteOpts.IncludeCodePatterns;
+  }
 
   /// \brief Whether to include global (top-level) declaration results.
-  bool includeGlobals() const { return IncludeGlobals; }
+  bool includeGlobals() const {
+    return CodeCompleteOpts.IncludeGlobals;
+  }
+
+  /// \brief Whether to include brief documentation comments within the set of
+  /// code completions returned.
+  bool includeBriefComments() const {
+    return CodeCompleteOpts.IncludeBriefComments;
+  }
 
   /// \brief Determine whether the output of this consumer is binary.
   bool isOutputBinary() const { return OutputIsBinary; }
@@ -962,11 +977,9 @@
 public:
   /// \brief Create a new printing code-completion consumer that prints its
   /// results to the given raw output stream.
-  PrintingCodeCompleteConsumer(bool IncludeMacros, bool IncludeCodePatterns,
-                               bool IncludeGlobals,
+  PrintingCodeCompleteConsumer(const CodeCompleteOptions &CodeCompleteOpts,
                                raw_ostream &OS)
-    : CodeCompleteConsumer(IncludeMacros, IncludeCodePatterns, IncludeGlobals,
-                           false), OS(OS),
+    : CodeCompleteConsumer(CodeCompleteOpts, false), OS(OS),
       CCTUInfo(new GlobalCodeCompletionAllocator) {}
 
   /// \brief Prints the finalized code-completion results.
diff --git a/include/clang/Sema/CodeCompleteOptions.h b/include/clang/Sema/CodeCompleteOptions.h
new file mode 100644
index 0000000..30712db
--- /dev/null
+++ b/include/clang/Sema/CodeCompleteOptions.h
@@ -0,0 +1,37 @@
+//===---- CodeCompleteOptions.h - Code Completion Options -------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SEMA_CODECOMPLETEOPTIONS_H
+#define LLVM_CLANG_SEMA_CODECOMPLETEOPTIONS_H
+
+/// Options controlling the behavior of code completion.
+class CodeCompleteOptions {
+public:
+  ///< Show macros in code completion results.
+  unsigned IncludeMacros : 1;
+
+  ///< Show code patterns in code completion results.
+  unsigned IncludeCodePatterns : 1;
+
+  ///< Show top-level decls in code completion results.
+  unsigned IncludeGlobals : 1;
+
+  ///< Show brief documentation comments in code completion results.
+  unsigned IncludeBriefComments : 1;
+
+  CodeCompleteOptions() :
+      IncludeMacros(0),
+      IncludeCodePatterns(0),
+      IncludeGlobals(1),
+      IncludeBriefComments(0)
+  { }
+};
+
+#endif
+
diff --git a/lib/AST/RawCommentList.cpp b/lib/AST/RawCommentList.cpp
index b2b0c43..e7b86df 100644
--- a/lib/AST/RawCommentList.cpp
+++ b/lib/AST/RawCommentList.cpp
@@ -130,7 +130,7 @@
   return StringRef(BufferStart + BeginOffset, Length);
 }
 
-StringRef RawComment::extractBriefText(const ASTContext &Context) const {
+const char *RawComment::extractBriefText(const ASTContext &Context) const {
   // Make sure that RawText is valid.
   getRawText(Context.getSourceManager());
 
@@ -142,10 +142,10 @@
   const unsigned BriefTextLength = Result.size();
   char *BriefTextPtr = new (Context) char[BriefTextLength + 1];
   memcpy(BriefTextPtr, Result.c_str(), BriefTextLength + 1);
-  BriefText = StringRef(BriefTextPtr, BriefTextLength);
+  BriefText = BriefTextPtr;
   BriefTextValid = true;
 
-  return BriefText;
+  return BriefTextPtr;
 }
 
 namespace {
diff --git a/lib/Frontend/ASTUnit.cpp b/lib/Frontend/ASTUnit.cpp
index 1ef5ba8..d2f63a8 100644
--- a/lib/Frontend/ASTUnit.cpp
+++ b/lib/Frontend/ASTUnit.cpp
@@ -214,6 +214,7 @@
     PreambleRebuildCounter(0), SavedMainFileBuffer(0), PreambleBuffer(0),
     NumWarningsInPreamble(0),
     ShouldCacheCodeCompletionResults(false),
+    IncludeBriefCommentsInCodeCompletion(false),
     CompletionCacheTopLevelHashValue(0),
     PreambleTopLevelHashValue(0),
     CurrentTopLevelHashValue(0),
@@ -358,7 +359,8 @@
       CachedCodeCompletionResult CachedResult;
       CachedResult.Completion = Results[I].CreateCodeCompletionString(*TheSema,
                                                     *CachedCompletionAllocator,
-                                                    getCodeCompletionTUInfo());
+                                                    getCodeCompletionTUInfo(),
+                                          IncludeBriefCommentsInCodeCompletion);
       CachedResult.ShowInContexts = getDeclShowContexts(Results[I].Declaration,
                                                         Ctx->getLangOpts(),
                                                         IsNestedNameSpecifier);
@@ -423,7 +425,8 @@
           CachedResult.Completion 
             = Results[I].CreateCodeCompletionString(*TheSema,
                                                     *CachedCompletionAllocator,
-                                                    getCodeCompletionTUInfo());
+                                                    getCodeCompletionTUInfo(),
+                                        IncludeBriefCommentsInCodeCompletion);
           CachedResult.ShowInContexts = RemainingContexts;
           CachedResult.Priority = CCP_NestedNameSpecifier;
           CachedResult.TypeClass = STC_Void;
@@ -445,7 +448,8 @@
       CachedResult.Completion 
         = Results[I].CreateCodeCompletionString(*TheSema,
                                                 *CachedCompletionAllocator,
-                                                getCodeCompletionTUInfo());
+                                                getCodeCompletionTUInfo(),
+                                          IncludeBriefCommentsInCodeCompletion);
       CachedResult.ShowInContexts
         = (1 << (CodeCompletionContext::CCC_TopLevel - 1))
         | (1 << (CodeCompletionContext::CCC_ObjCInterface - 1))
@@ -1683,6 +1687,7 @@
                                              bool CaptureDiagnostics,
                                              bool PrecompilePreamble,
                                              bool CacheCodeCompletionResults,
+                                    bool IncludeBriefCommentsInCodeCompletion,
                                              OwningPtr<ASTUnit> *ErrAST) {
   assert(CI && "A CompilerInvocation is required");
 
@@ -1704,6 +1709,8 @@
     AST->PreambleRebuildCounter = 2;
   AST->TUKind = Action ? Action->getTranslationUnitKind() : TU_Complete;
   AST->ShouldCacheCodeCompletionResults = CacheCodeCompletionResults;
+  AST->IncludeBriefCommentsInCodeCompletion
+    = IncludeBriefCommentsInCodeCompletion;
 
   // Recover resources if we crash before exiting this method.
   llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit>
@@ -1850,7 +1857,8 @@
                                              bool CaptureDiagnostics,
                                              bool PrecompilePreamble,
                                              TranslationUnitKind TUKind,
-                                             bool CacheCodeCompletionResults) {  
+                                             bool CacheCodeCompletionResults,
+                                    bool IncludeBriefCommentsInCodeCompletion) {
   // Create the AST unit.
   OwningPtr<ASTUnit> AST;
   AST.reset(new ASTUnit(false));
@@ -1860,6 +1868,8 @@
   AST->CaptureDiagnostics = CaptureDiagnostics;
   AST->TUKind = TUKind;
   AST->ShouldCacheCodeCompletionResults = CacheCodeCompletionResults;
+  AST->IncludeBriefCommentsInCodeCompletion
+    = IncludeBriefCommentsInCodeCompletion;
   AST->Invocation = CI;
   
   // Recover resources if we crash before exiting this method.
@@ -1884,6 +1894,7 @@
                                       bool PrecompilePreamble,
                                       TranslationUnitKind TUKind,
                                       bool CacheCodeCompletionResults,
+                                      bool IncludeBriefCommentsInCodeCompletion,
                                       bool AllowPCHWithCompilerErrors,
                                       bool SkipFunctionBodies,
                                       OwningPtr<ASTUnit> *ErrAST) {
@@ -1943,6 +1954,8 @@
   AST->CaptureDiagnostics = CaptureDiagnostics;
   AST->TUKind = TUKind;
   AST->ShouldCacheCodeCompletionResults = CacheCodeCompletionResults;
+  AST->IncludeBriefCommentsInCodeCompletion
+    = IncludeBriefCommentsInCodeCompletion;
   AST->NumStoredDiagnosticsFromDriver = StoredDiagnostics.size();
   AST->StoredDiagnostics.swap(StoredDiagnostics);
   AST->Invocation = CI;
@@ -2041,10 +2054,9 @@
     
   public:
     AugmentedCodeCompleteConsumer(ASTUnit &AST, CodeCompleteConsumer &Next,
-                                  bool IncludeMacros, bool IncludeCodePatterns,
-                                  bool IncludeGlobals)
-      : CodeCompleteConsumer(IncludeMacros, IncludeCodePatterns, IncludeGlobals,
-                             Next.isOutputBinary()), AST(AST), Next(Next) 
+                                  const CodeCompleteOptions &CodeCompleteOpts)
+      : CodeCompleteConsumer(CodeCompleteOpts, Next.isOutputBinary()),
+        AST(AST), Next(Next)
     { 
       // Compute the set of contexts in which we will look when we don't have
       // any information about the specific context.
@@ -2274,6 +2286,7 @@
                            unsigned NumRemappedFiles,
                            bool IncludeMacros, 
                            bool IncludeCodePatterns,
+                           bool IncludeBriefComments,
                            CodeCompleteConsumer &Consumer,
                            DiagnosticsEngine &Diag, LangOptions &LangOpts,
                            SourceManager &SourceMgr, FileManager &FileMgr,
@@ -2290,13 +2303,17 @@
     CCInvocation(new CompilerInvocation(*Invocation));
 
   FrontendOptions &FrontendOpts = CCInvocation->getFrontendOpts();
+  CodeCompleteOptions &CodeCompleteOpts = FrontendOpts.CodeCompleteOpts;
   PreprocessorOptions &PreprocessorOpts = CCInvocation->getPreprocessorOpts();
 
-  FrontendOpts.ShowMacrosInCodeCompletion
-    = IncludeMacros && CachedCompletionResults.empty();
-  FrontendOpts.ShowCodePatternsInCodeCompletion = IncludeCodePatterns;
-  FrontendOpts.ShowGlobalSymbolsInCodeCompletion
-    = CachedCompletionResults.empty();
+  CodeCompleteOpts.IncludeMacros = IncludeMacros &&
+                                   CachedCompletionResults.empty();
+  CodeCompleteOpts.IncludeCodePatterns = IncludeCodePatterns;
+  CodeCompleteOpts.IncludeGlobals = CachedCompletionResults.empty();
+  CodeCompleteOpts.IncludeBriefComments = IncludeBriefComments;
+
+  assert(IncludeBriefComments == this->IncludeBriefCommentsInCodeCompletion);
+
   FrontendOpts.CodeCompletionAt.FileName = File;
   FrontendOpts.CodeCompletionAt.Line = Line;
   FrontendOpts.CodeCompletionAt.Column = Column;
@@ -2365,10 +2382,7 @@
   // Use the code completion consumer we were given, but adding any cached
   // code-completion results.
   AugmentedCodeCompleteConsumer *AugmentedConsumer
-    = new AugmentedCodeCompleteConsumer(*this, Consumer, 
-                                        FrontendOpts.ShowMacrosInCodeCompletion,
-                                FrontendOpts.ShowCodePatternsInCodeCompletion,
-                                FrontendOpts.ShowGlobalSymbolsInCodeCompletion);
+    = new AugmentedCodeCompleteConsumer(*this, Consumer, CodeCompleteOpts);
   Clang->setCodeCompletionConsumer(AugmentedConsumer);
 
   Clang->getFrontendOpts().SkipFunctionBodies = true;
diff --git a/lib/Frontend/CompilerInstance.cpp b/lib/Frontend/CompilerInstance.cpp
index cd24a69..6de1531 100644
--- a/lib/Frontend/CompilerInstance.cpp
+++ b/lib/Frontend/CompilerInstance.cpp
@@ -387,9 +387,7 @@
     setCodeCompletionConsumer(
       createCodeCompletionConsumer(getPreprocessor(),
                                    Loc.FileName, Loc.Line, Loc.Column,
-                                   getFrontendOpts().ShowMacrosInCodeCompletion,
-                             getFrontendOpts().ShowCodePatternsInCodeCompletion,
-                           getFrontendOpts().ShowGlobalSymbolsInCodeCompletion,
+                                   getFrontendOpts().CodeCompleteOpts,
                                    llvm::outs()));
     if (!CompletionConsumer)
       return;
@@ -415,16 +413,13 @@
                                                const std::string &Filename,
                                                unsigned Line,
                                                unsigned Column,
-                                               bool ShowMacros,
-                                               bool ShowCodePatterns,
-                                               bool ShowGlobals,
+                                               const CodeCompleteOptions &Opts,
                                                raw_ostream &OS) {
   if (EnableCodeCompletion(PP, Filename, Line, Column))
     return 0;
 
   // Set up the creation routine for code-completion.
-  return new PrintingCodeCompleteConsumer(ShowMacros, ShowCodePatterns,
-                                          ShowGlobals, OS);
+  return new PrintingCodeCompleteConsumer(Opts, OS);
 }
 
 void CompilerInstance::createSema(TranslationUnitKind TUKind,
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index 4100dea..391c2d2 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -470,6 +470,18 @@
     Res.push_back("-working-directory", Opts.WorkingDir);
 }
 
+static void CodeCompleteOptionsToArgs(const CodeCompleteOptions &Opts,
+                                      ToArgsList &Res) {
+  if (Opts.IncludeMacros)
+    Res.push_back("-code-completion-macros");
+  if (Opts.IncludeCodePatterns)
+    Res.push_back("-code-completion-patterns");
+  if (!Opts.IncludeGlobals)
+    Res.push_back("-no-code-completion-globals");
+  if (Opts.IncludeBriefComments)
+    Res.push_back("-code-completion-brief-comments");
+}
+
 static void FrontendOptsToArgs(const FrontendOptions &Opts, ToArgsList &Res) {
   if (Opts.DisableFree)
     Res.push_back("-disable-free");
@@ -477,12 +489,6 @@
     Res.push_back("-relocatable-pch");
   if (Opts.ShowHelp)
     Res.push_back("-help");
-  if (Opts.ShowMacrosInCodeCompletion)
-    Res.push_back("-code-completion-macros");
-  if (Opts.ShowCodePatternsInCodeCompletion)
-    Res.push_back("-code-completion-patterns");
-  if (!Opts.ShowGlobalSymbolsInCodeCompletion)
-    Res.push_back("-no-code-completion-globals");
   if (Opts.ShowStats)
     Res.push_back("-print-stats");
   if (Opts.ShowTimers)
@@ -510,6 +516,7 @@
     Res.push_back("-arcmt-migrate");
     break;
   }
+  CodeCompleteOptionsToArgs(Opts.CodeCompleteOpts, Res);
   if (!Opts.MTMigrateDir.empty())
     Res.push_back("-mt-migrate-directory", Opts.MTMigrateDir);
   if (!Opts.ARCMTMigrateReportOut.empty())
@@ -1517,11 +1524,6 @@
   Opts.Plugins = Args.getAllArgValues(OPT_load);
   Opts.RelocatablePCH = Args.hasArg(OPT_relocatable_pch);
   Opts.ShowHelp = Args.hasArg(OPT_help);
-  Opts.ShowMacrosInCodeCompletion = Args.hasArg(OPT_code_completion_macros);
-  Opts.ShowCodePatternsInCodeCompletion
-    = Args.hasArg(OPT_code_completion_patterns);
-  Opts.ShowGlobalSymbolsInCodeCompletion
-    = !Args.hasArg(OPT_no_code_completion_globals);
   Opts.ShowStats = Args.hasArg(OPT_print_stats);
   Opts.ShowTimers = Args.hasArg(OPT_ftime_report);
   Opts.ShowVersion = Args.hasArg(OPT_version);
@@ -1531,6 +1533,16 @@
   Opts.FixOnlyWarnings = Args.hasArg(OPT_fix_only_warnings);
   Opts.FixAndRecompile = Args.hasArg(OPT_fixit_recompile);
   Opts.FixToTemporaries = Args.hasArg(OPT_fixit_to_temp);
+
+  Opts.CodeCompleteOpts.IncludeMacros
+    = Args.hasArg(OPT_code_completion_macros);
+  Opts.CodeCompleteOpts.IncludeCodePatterns
+    = Args.hasArg(OPT_code_completion_patterns);
+  Opts.CodeCompleteOpts.IncludeGlobals
+    = !Args.hasArg(OPT_no_code_completion_globals);
+  Opts.CodeCompleteOpts.IncludeBriefComments
+    = Args.hasArg(OPT_code_completion_brief_comments);
+
   Opts.OverrideRecordLayoutsFile
     = Args.getLastArgValue(OPT_foverride_record_layout_EQ);
   if (const Arg *A = Args.getLastArg(OPT_arcmt_check,
diff --git a/lib/Sema/CodeCompleteConsumer.cpp b/lib/Sema/CodeCompleteConsumer.cpp
index dfbc98f..a835725 100644
--- a/lib/Sema/CodeCompleteConsumer.cpp
+++ b/lib/Sema/CodeCompleteConsumer.cpp
@@ -194,10 +194,11 @@
                                            const char **Annotations,
                                            unsigned NumAnnotations,
                                            CXCursorKind ParentKind,
-                                           StringRef ParentName)
+                                           StringRef ParentName,
+                                           const char *BriefComment)
   : NumChunks(NumChunks), NumAnnotations(NumAnnotations),
     Priority(Priority), Availability(Availability), ParentKind(ParentKind),
-    ParentName(ParentName)
+    ParentName(ParentName), BriefComment(BriefComment)
 { 
   assert(NumChunks <= 0xffff);
   assert(NumAnnotations <= 0xffff);
@@ -338,7 +339,7 @@
     = new (Mem) CodeCompletionString(Chunks.data(), Chunks.size(),
                                      Priority, Availability,
                                      Annotations.data(), Annotations.size(),
-                                     ParentKind, ParentName);
+                                     ParentKind, ParentName, BriefComment);
   Chunks.clear();
   return Result;
 }
@@ -394,6 +395,10 @@
   ParentName = getCodeCompletionTUInfo().getParentName(DC);
 }
 
+void CodeCompletionBuilder::addBriefComment(StringRef Comment) {
+  BriefComment = Allocator.CopyString(Comment);
+}
+
 unsigned CodeCompletionResult::getPriorityFromDecl(NamedDecl *ND) {
   if (!ND)
     return CCP_Unlikely;
@@ -474,8 +479,11 @@
         OS << " (Hidden)";
       if (CodeCompletionString *CCS 
             = Results[I].CreateCodeCompletionString(SemaRef, getAllocator(),
-                                                    CCTUInfo)) {
+                                                    CCTUInfo,
+                                                    includeBriefComments())) {
         OS << " : " << CCS->getAsString();
+        if (const char *BriefComment = CCS->getBriefComment())
+          OS << " : " << BriefComment;
       }
         
       OS << '\n';
@@ -489,7 +497,8 @@
       OS << Results[I].Macro->getName();
       if (CodeCompletionString *CCS 
             = Results[I].CreateCodeCompletionString(SemaRef, getAllocator(),
-                                                    CCTUInfo)) {
+                                                    CCTUInfo,
+                                                    includeBriefComments())) {
         OS << " : " << CCS->getAsString();
       }
       OS << '\n';
diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp
index ff83324..d428974 100644
--- a/lib/Sema/SemaCodeComplete.cpp
+++ b/lib/Sema/SemaCodeComplete.cpp
@@ -2453,8 +2453,10 @@
 
 CodeCompletionString *CodeCompletionResult::CreateCodeCompletionString(Sema &S,
                                          CodeCompletionAllocator &Allocator,
-                                         CodeCompletionTUInfo &CCTUInfo) {
-  return CreateCodeCompletionString(S.Context, S.PP, Allocator, CCTUInfo);
+                                         CodeCompletionTUInfo &CCTUInfo,
+                                         bool IncludeBriefComments) {
+  return CreateCodeCompletionString(S.Context, S.PP, Allocator, CCTUInfo,
+                                    IncludeBriefComments);
 }
 
 /// \brief If possible, create a new code completion string for the given
@@ -2467,7 +2469,8 @@
 CodeCompletionResult::CreateCodeCompletionString(ASTContext &Ctx,
                                                  Preprocessor &PP,
                                            CodeCompletionAllocator &Allocator,
-                                           CodeCompletionTUInfo &CCTUInfo) {
+                                           CodeCompletionTUInfo &CCTUInfo,
+                                           bool IncludeBriefComments) {
   CodeCompletionBuilder Result(Allocator, CCTUInfo, Priority, Availability);
   
   PrintingPolicy Policy = getCompletionPrintingPolicy(Ctx, PP);
@@ -2537,7 +2540,14 @@
   assert(Kind == RK_Declaration && "Missed a result kind?");
   NamedDecl *ND = Declaration;
   Result.addParentContext(ND->getDeclContext());
-                          
+
+  if (IncludeBriefComments) {
+    // Add documentation comment, if it exists.
+    if (const RawComment *RC = Ctx.getRawCommentForDecl(ND)) {
+      Result.addBriefComment(RC->getBriefText(Ctx));
+    }
+  }
+
   if (StartsNestedNameSpecifier) {
     Result.AddTypedTextChunk(
                       Result.getAllocator().CopyString(ND->getNameAsString()));
diff --git a/test/CodeCompletion/documentation.cpp b/test/CodeCompletion/documentation.cpp
new file mode 100644
index 0000000..c049ae3
--- /dev/null
+++ b/test/CodeCompletion/documentation.cpp
@@ -0,0 +1,33 @@
+// Note: the run lines follow their respective tests, since line/column
+// matter in this test.
+
+/// Aaa.
+void T1(float x, float y);
+
+/// Bbb.
+class T2 {
+public:
+  /// Ccc.
+  void T3();
+
+  int T4; ///< Ddd.
+};
+
+/// Eee.
+namespace T5 {
+}
+
+void test() {
+
+  T2 t2;
+  t2.
+}
+
+// RUN: %clang_cc1 -fsyntax-only -code-completion-brief-comments -code-completion-at=%s:21:1 %s -o - | FileCheck -check-prefix=CC1 %s
+// CHECK-CC1: COMPLETION: T1 : [#void#]T1(<#float x#>, <#float y#>) : Aaa.
+// CHECK-CC1: COMPLETION: T2 : T2 : Bbb.
+// CHECK-CC1: COMPLETION: T5 : T5:: : Eee.
+
+// RUN: %clang_cc1 -fsyntax-only -code-completion-brief-comments -code-completion-at=%s:23:6 %s -o - | FileCheck -check-prefix=CC2 %s
+// CHECK-CC2: COMPLETION: T3 : [#void#]T3() : Ccc.
+// CHECK-CC2: COMPLETION: T4 : [#int#]T4 : Ddd.
diff --git a/test/Index/complete-documentation.cpp b/test/Index/complete-documentation.cpp
new file mode 100644
index 0000000..6cb7ca6
--- /dev/null
+++ b/test/Index/complete-documentation.cpp
@@ -0,0 +1,33 @@
+// Note: the run lines follow their respective tests, since line/column
+// matter in this test.
+
+/// Aaa.
+void T1(float x, float y);
+
+/// Bbb.
+class T2 {
+public:
+  /// Ccc.
+  void T3();
+
+  int T4; ///< Ddd.
+};
+
+/// Eee.
+namespace T5 {
+}
+
+void test() {
+
+  T2 t2;
+  t2.
+}
+
+// RUN: env CINDEXTEST_COMPLETION_BRIEF_COMMENTS=1 c-index-test -code-completion-at=%s:21:1 %s | FileCheck -check-prefix=CC1 %s
+// CHECK-CC1: FunctionDecl:{ResultType void}{TypedText T1}{{.*}}(brief comment: Aaa.)
+// CHECK-CC1: ClassDecl:{TypedText T2}{{.*}}(brief comment: Bbb.)
+// CHECK-CC1: Namespace:{TypedText T5}{{.*}}(brief comment: Eee.)
+
+// RUN: env CINDEXTEST_COMPLETION_BRIEF_COMMENTS=1 c-index-test -code-completion-at=%s:23:6 %s | FileCheck -check-prefix=CC2 %s
+// CHECK-CC2: CXXMethod:{ResultType void}{TypedText T3}{{.*}}(brief comment: Ccc.)
+// CHECK-CC2: FieldDecl:{ResultType int}{TypedText T4}{{.*}}(brief comment: Ddd.)
diff --git a/tools/c-index-test/c-index-test.c b/tools/c-index-test/c-index-test.c
index 787671f..43229fd 100644
--- a/tools/c-index-test/c-index-test.c
+++ b/tools/c-index-test/c-index-test.c
@@ -59,6 +59,8 @@
     options &= ~CXTranslationUnit_CacheCompletionResults;
   if (getenv("CINDEXTEST_SKIP_FUNCTION_BODIES"))
     options |= CXTranslationUnit_SkipFunctionBodies;
+  if (getenv("CINDEXTEST_COMPLETION_BRIEF_COMMENTS"))
+    options |= CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
   
   return options;
 }
@@ -1220,6 +1222,8 @@
   unsigned annotationCount;
   enum CXCursorKind ParentKind;
   CXString ParentName;
+  CXString BriefComment;
+  const char *BriefCommentCString;
   
   fprintf(file, "%s:", clang_getCString(ks));
   clang_disposeString(ks);
@@ -1271,6 +1275,14 @@
     }
     clang_disposeString(ParentName);
   }
+
+  BriefComment = clang_getCompletionBriefComment(
+                                        completion_result->CompletionString);
+  BriefCommentCString = clang_getCString(BriefComment);
+  if (BriefCommentCString && *BriefCommentCString != '\0') {
+    fprintf(file, "(brief comment: %s)", BriefCommentCString);
+  }
+  clang_disposeString(BriefComment);
   
   fprintf(file, "\n");
 }
@@ -1383,6 +1395,8 @@
   
   if (getenv("CINDEXTEST_CODE_COMPLETE_PATTERNS"))
     completionOptions |= CXCodeComplete_IncludeCodePatterns;
+  if (getenv("CINDEXTEST_COMPLETION_BRIEF_COMMENTS"))
+    completionOptions |= CXCodeComplete_IncludeBriefComments;
   
   if (timing_only)
     input += strlen("-code-completion-timing=");
diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp
index c7d1523..2233a11 100644
--- a/tools/libclang/CIndex.cpp
+++ b/tools/libclang/CIndex.cpp
@@ -2523,6 +2523,8 @@
     = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
   bool CacheCodeCompetionResults
     = options & CXTranslationUnit_CacheCompletionResults;
+  bool IncludeBriefCommentsInCodeCompletion
+    = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
   bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
 
   // Configure the diagnostics.
@@ -2607,6 +2609,7 @@
                                  PrecompilePreamble,
                                  TUKind,
                                  CacheCodeCompetionResults,
+                                 IncludeBriefCommentsInCodeCompletion,
                                  /*AllowPCHWithCompilerErrors=*/true,
                                  SkipFunctionBodies,
                                  &ErrUnit));
diff --git a/tools/libclang/CIndexCodeCompletion.cpp b/tools/libclang/CIndexCodeCompletion.cpp
index 303fb1f..0073b50 100644
--- a/tools/libclang/CIndexCodeCompletion.cpp
+++ b/tools/libclang/CIndexCodeCompletion.cpp
@@ -227,6 +227,17 @@
     *kind = CCStr->getParentContextKind();
   return createCXString(CCStr->getParentContextName(), /*DupString=*/false);
 }
+
+CXString
+clang_getCompletionBriefComment(CXCompletionString completion_string) {
+  CodeCompletionString *CCStr = (CodeCompletionString *)completion_string;
+
+  if (!CCStr)
+    return createCXString((const char *) NULL);
+
+  return createCXString(CCStr->getBriefComment(), /*DupString=*/false);
+}
+
   
 /// \brief The CXCodeCompleteResults structure we allocate internally;
 /// the client only sees the initial CXCodeCompleteResults structure.
@@ -509,9 +520,10 @@
     SmallVector<CXCompletionResult, 16> StoredResults;
     CXTranslationUnit *TU;
   public:
-    CaptureCompletionResults(AllocatedCXCodeCompleteResults &Results,
+    CaptureCompletionResults(const CodeCompleteOptions &Opts,
+                             AllocatedCXCodeCompleteResults &Results,
                              CXTranslationUnit *TranslationUnit)
-      : CodeCompleteConsumer(true, false, true, false), 
+      : CodeCompleteConsumer(Opts, false), 
         AllocatedResults(Results), CCTUInfo(Results.CodeCompletionAllocator),
         TU(TranslationUnit) { }
     ~CaptureCompletionResults() { Finish(); }
@@ -524,7 +536,8 @@
       for (unsigned I = 0; I != NumResults; ++I) {
         CodeCompletionString *StoredCompletion        
           = Results[I].CreateCodeCompletionString(S, getAllocator(),
-                                                  getCodeCompletionTUInfo());
+                                                  getCodeCompletionTUInfo(),
+                                                  includeBriefComments());
         
         CXCompletionResult R;
         R.CursorKind = Results[I].CursorKind;
@@ -658,6 +671,7 @@
   struct CXUnsavedFile *unsaved_files = CCAI->unsaved_files;
   unsigned num_unsaved_files = CCAI->num_unsaved_files;
   unsigned options = CCAI->options;
+  bool IncludeBriefComments = options & CXCodeComplete_IncludeBriefComments;
   CCAI->result = 0;
 
 #ifdef UDP_CODE_COMPLETION_LOGGER
@@ -699,13 +713,16 @@
   Results->NumResults = 0;
   
   // Create a code-completion consumer to capture the results.
-  CaptureCompletionResults Capture(*Results, &TU);
+  CodeCompleteOptions Opts;
+  Opts.IncludeBriefComments = IncludeBriefComments;
+  CaptureCompletionResults Capture(Opts, *Results, &TU);
 
   // Perform completion.
   AST->CodeComplete(complete_filename, complete_line, complete_column,
                     RemappedFiles.data(), RemappedFiles.size(), 
                     (options & CXCodeComplete_IncludeMacros),
                     (options & CXCodeComplete_IncludeCodePatterns),
+                    IncludeBriefComments,
                     Capture,
                     *Results->Diag, Results->LangOpts, *Results->SourceMgr,
                     *Results->FileMgr, Results->Diagnostics,
diff --git a/tools/libclang/CXCursor.cpp b/tools/libclang/CXCursor.cpp
index 08c4de3..ae7d806 100644
--- a/tools/libclang/CXCursor.cpp
+++ b/tools/libclang/CXCursor.cpp
@@ -1198,7 +1198,8 @@
         = Result.CreateCodeCompletionString(unit->getASTContext(),
                                             unit->getPreprocessor(),
                                  unit->getCodeCompletionTUInfo().getAllocator(),
-                                 unit->getCodeCompletionTUInfo());
+                                 unit->getCodeCompletionTUInfo(),
+                                 true);
       return String;
     }
   }
@@ -1211,7 +1212,8 @@
       = Result.CreateCodeCompletionString(unit->getASTContext(),
                                           unit->getPreprocessor(),
                                  unit->getCodeCompletionTUInfo().getAllocator(),
-                                 unit->getCodeCompletionTUInfo());
+                                 unit->getCodeCompletionTUInfo(),
+                                 false);
     return String;
   }
   return NULL;
diff --git a/tools/libclang/libclang.exports b/tools/libclang/libclang.exports
index bba883f..1272a02 100644
--- a/tools/libclang/libclang.exports
+++ b/tools/libclang/libclang.exports
@@ -71,6 +71,7 @@
 clang_getClangVersion
 clang_getCompletionAnnotation
 clang_getCompletionAvailability
+clang_getCompletionBriefComment
 clang_getCompletionChunkCompletionString
 clang_getCompletionChunkKind
 clang_getCompletionChunkText