zixuw updated this revision to Diff 417132.
zixuw marked 11 inline comments as done.
zixuw added a comment.

Address review issues.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D122160/new/

https://reviews.llvm.org/D122160

Files:
  clang/include/clang/ExtractAPI/API.h
  clang/include/clang/ExtractAPI/AvailabilityInfo.h
  clang/include/clang/ExtractAPI/DeclarationFragments.h
  clang/include/clang/ExtractAPI/FrontendActions.h
  clang/include/clang/ExtractAPI/Serialization/SerializerBase.h
  clang/include/clang/ExtractAPI/Serialization/SymbolGraphSerializer.h
  clang/include/clang/SymbolGraph/API.h
  clang/include/clang/SymbolGraph/AvailabilityInfo.h
  clang/include/clang/SymbolGraph/DeclarationFragments.h
  clang/include/clang/SymbolGraph/FrontendActions.h
  clang/include/clang/SymbolGraph/Serialization.h
  clang/lib/CMakeLists.txt
  clang/lib/ExtractAPI/API.cpp
  clang/lib/ExtractAPI/CMakeLists.txt
  clang/lib/ExtractAPI/DeclarationFragments.cpp
  clang/lib/ExtractAPI/ExtractAPIConsumer.cpp
  clang/lib/ExtractAPI/Serialization/SerializerBase.cpp
  clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp
  clang/lib/FrontendTool/CMakeLists.txt
  clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
  clang/lib/SymbolGraph/API.cpp
  clang/lib/SymbolGraph/CMakeLists.txt
  clang/lib/SymbolGraph/DeclarationFragments.cpp
  clang/lib/SymbolGraph/ExtractAPIConsumer.cpp
  clang/lib/SymbolGraph/Serialization.cpp

Index: clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
===================================================================
--- clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
+++ clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
@@ -15,6 +15,7 @@
 #include "clang/CodeGen/CodeGenAction.h"
 #include "clang/Config/config.h"
 #include "clang/Driver/Options.h"
+#include "clang/ExtractAPI/FrontendActions.h"
 #include "clang/Frontend/CompilerInstance.h"
 #include "clang/Frontend/CompilerInvocation.h"
 #include "clang/Frontend/FrontendActions.h"
@@ -25,7 +26,6 @@
 #include "clang/Rewrite/Frontend/FrontendActions.h"
 #include "clang/StaticAnalyzer/Frontend/AnalyzerHelpFlags.h"
 #include "clang/StaticAnalyzer/Frontend/FrontendActions.h"
-#include "clang/SymbolGraph/FrontendActions.h"
 #include "llvm/Option/OptTable.h"
 #include "llvm/Option/Option.h"
 #include "llvm/Support/BuryPointer.h"
Index: clang/lib/FrontendTool/CMakeLists.txt
===================================================================
--- clang/lib/FrontendTool/CMakeLists.txt
+++ clang/lib/FrontendTool/CMakeLists.txt
@@ -7,9 +7,9 @@
   clangBasic
   clangCodeGen
   clangDriver
+  clangExtractAPI
   clangFrontend
   clangRewriteFrontend
-  clangSymbolGraph
   )
 
 if(CLANG_ENABLE_ARCMT)
Index: clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp
===================================================================
--- clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp
+++ clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp
@@ -1,4 +1,4 @@
-//===- SymbolGraph/Serialization.cpp ----------------------------*- C++ -*-===//
+//===- ExtractAPI/Serialization/SymbolGraphSerializer.cpp -------*- C++ -*-===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -7,38 +7,56 @@
 //===----------------------------------------------------------------------===//
 ///
 /// \file
-/// \brief Defines the SymbolGraph serializer and parser.
+/// This file implements the SymbolGraphSerializer.
 ///
 //===----------------------------------------------------------------------===//
 
-#include "clang/SymbolGraph/Serialization.h"
+#include "clang/ExtractAPI/Serialization/SymbolGraphSerializer.h"
 #include "clang/Basic/Version.h"
-#include "clang/SymbolGraph/API.h"
+#include "clang/ExtractAPI/API.h"
 #include "llvm/Support/JSON.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/VersionTuple.h"
-#include "llvm/Support/raw_ostream.h"
 
 using namespace clang;
-using namespace clang::symbolgraph;
+using namespace clang::extractapi;
 using namespace llvm;
 using namespace llvm::json;
 
 namespace {
 
+/// Helper function to inject a JSON object \p Obj into another object \p Paren
+/// at position \p Key.
 static void serializeObject(Object &Paren, StringRef Key,
                             Optional<Object> Obj) {
   if (Obj)
     Paren[Key] = std::move(Obj.getValue());
 }
 
+/// Helper function to inject a JSON array \p Array into object \p Paren at
+/// position \p Key.
 static void serializeArray(Object &Paren, StringRef Key,
                            Optional<Array> Array) {
   if (Array)
     Paren[Key] = std::move(Array.getValue());
 }
 
-// SymbolGraph: SemanticVersion
+/// Serialize a \c VersionTuple \p V with the Symbol Graph semantic version
+/// format.
+///
+/// A semantic version object contains three numeric fields, representing the
+/// \c major, \c minor, and \c patch parts of the version tuple.
+/// For example version tuple 1.0.3 is serialized as:
+/// \code
+///   {
+///     "major" : 1,
+///     "minor" : 0,
+///     "patch" : 3
+///   }
+/// \endcode
+///
+/// \returns \c None if the version \p V is empty, or an \c Object containing
+/// the semantic version representation of \p V.
 static Optional<Object> serializeSemanticVersion(const VersionTuple &V) {
   if (V.empty())
     return None;
@@ -50,6 +68,10 @@
   return Version;
 }
 
+/// Serialize the OS information in the Symbol Graph platform property.
+///
+/// The OS information in Symbol Graph contains the \c name of the OS, and an
+/// optional \c minimumVersion semantic version field.
 static Object serializeOperatingSystem(const Triple &T) {
   Object OS;
   OS["name"] = T.getOSTypeName(T.getOS());
@@ -58,7 +80,10 @@
   return OS;
 }
 
-// SymbolGraph: Platform
+/// Serialize the platform information in the Symbol Graph module section.
+///
+/// The platform object describes a target platform triple in corresponding
+/// three fields: \c architecture, \c vendor, and \c operatingSystem.
 static Object serializePlatform(const Triple &T) {
   Object Platform;
   Platform["architecture"] = T.getArchName();
@@ -67,7 +92,11 @@
   return Platform;
 }
 
-// SymbolGraph: SourcePosition
+/// Serialize a source location in file.
+///
+/// \param Loc The presumed location to serialize.
+/// \param IncludeFileURI If true, include the file path of \p Loc as a URI.
+/// Defaults to false.
 static Object serializeSourcePosition(const PresumedLoc &Loc,
                                       bool IncludeFileURI = false) {
   assert(Loc.isValid() && "invalid source position");
@@ -78,6 +107,7 @@
 
   if (IncludeFileURI) {
     std::string FileURI = "file://";
+    // Normalize file path to use forward slashes for the URI.
     FileURI += sys::path::convert_to_slash(Loc.getFilename());
     SourcePosition["uri"] = FileURI;
   }
@@ -85,7 +115,7 @@
   return SourcePosition;
 }
 
-// SymbolGraph: SourceRange
+/// Serialize a source range with begin and end locations.
 static Object serializeSourceRange(const PresumedLoc &BeginLoc,
                                    const PresumedLoc &EndLoc) {
   Object SourceRange;
@@ -94,7 +124,16 @@
   return SourceRange;
 }
 
-// SymbolGraph: AvailabilityItem
+/// Serialize the availability attributes of a symbol.
+///
+/// Availability information contains the introduced, deprecated, and obsoleted
+/// versions of the symbol as semantic versions, if not default.
+/// Availability information also contains flags to indicate if the symbol is
+/// unconditionally unavailable or deprecated,
+/// i.e. \c __attribute__((unavailable)) and \c __attribute__((deprecated)).
+///
+/// \returns \c None if the symbol has default availability attributes, or
+/// an \c Object containing the formatted availability information.
 static Optional<Object> serializeAvailability(const AvailabilityInfo &Avail) {
   if (Avail.isDefault())
     return None;
@@ -114,6 +153,7 @@
   return Availbility;
 }
 
+/// Get the short language name string for interface language references.
 static StringRef getLanguageName(const LangOptions &LangOpts) {
   auto Language =
       LangStandard::getLangStandardForKind(LangOpts.LangStd).getLanguage();
@@ -142,7 +182,10 @@
   llvm_unreachable("Unhandled language kind");
 }
 
-// SymbolGraph: Symbol::identifier
+/// Serialize the identifier object as specified by the Symbol Graph format.
+///
+/// The identifier property of a symbol contains the USR for precise and unique
+/// references, and the interface language name.
 static Object serializeIdentifier(const APIRecord &Record,
                                   const LangOptions &LangOpts) {
   Object Identifier;
@@ -152,7 +195,22 @@
   return Identifier;
 }
 
-// SymbolGraph: DocComment
+/// Serialize the documentation comments attached to a symbol, as specified by
+/// the Symbol Graph format.
+///
+/// The Symbol Graph \c docComment object contains an array of lines. Each line
+/// represents one line of striped documentation comment, with source range
+/// information.
+/// e.g.
+/// \code
+///   /// This is a documentation comment
+///       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'  First line.
+///   ///     with multiple lines.
+///       ^~~~~~~~~~~~~~~~~~~~~~~'         Second line.
+/// \endcode
+///
+/// \returns \c None if \p Comment is empty, or an \c Object containing the
+/// formatted lines.
 static Optional<Object> serializeDocComment(const DocComment &Comment) {
   if (Comment.empty())
     return None;
@@ -171,6 +229,40 @@
   return DocComment;
 }
 
+/// Serialize the declaration fragments of a symbol.
+///
+/// The Symbol Graph declaration fragments is an array of tagged important
+/// parts of a symbol's declaration. The fragments sequence can be joined to
+/// form spans of declaration text, with attached information useful for
+/// purposes like syntax-highlighting etc. For example:
+/// \code
+///   const int pi; -> "declarationFragments" : [
+///                      {
+///                        "kind" : "keyword",
+///                        "spelling" : "const"
+///                      },
+///                      {
+///                        "kind" : "text",
+///                        "spelling" : " "
+///                      },
+///                      {
+///                        "kind" : "typeIdentifier",
+///                        "preciseIdentifier" : "c:I",
+///                        "spelling" : "int"
+///                      },
+///                      {
+///                        "kind" : "text",
+///                        "spelling" : " "
+///                      },
+///                      {
+///                        "kind" : "identifier",
+///                        "spelling" : "pi"
+///                      }
+///                    ]
+/// \endcode
+///
+/// \returns \c None if \p DF is empty, or an \c Array containing the formatted
+/// declaration fragments array.
 static Optional<Array>
 serializeDeclarationFragments(const DeclarationFragments &DF) {
   if (DF.getFragments().empty())
@@ -189,6 +281,16 @@
   return Fragments;
 }
 
+/// Serialize the function signature field of a function, as specified by the
+/// Symbol Graph format.
+///
+/// The Symbol Graph function signature property contains two arrays.
+///   - The \c returns array is the declaration fragments of the return type;
+///   - The \c parameters array contains names and declaration fragments of the
+///     parameters.
+///
+/// \returns \c None if \p FS is empty, or an \c Object containing the
+/// formatted function signature.
 static Optional<Object>
 serializeFunctionSignature(const FunctionSignature &FS) {
   if (FS.empty())
@@ -213,6 +315,15 @@
   return Signature;
 }
 
+/// Serialize the \c names field of a symbol as specified by the Symbol Graph
+/// format.
+///
+/// The Symbol Graph names field contains multiple representations of a symbol
+/// that can be used for different applications:
+///   - \c title : The simple declared name of the symbol;
+///   - \c subHeading : An array of declaration fragments that provides tags,
+///     and potentially more tokens (for example the \c +/- symbol for
+///     Objective-C methods). Can be used as sub-headings for documentation.
 static Object serializeNames(const APIRecord &Record) {
   Object Names;
   Names["title"] = Record.Name;
@@ -222,7 +333,11 @@
   return Names;
 }
 
-// SymbolGraph: Symbol::kind
+/// Serialize the symbol kind information.
+///
+/// The Symbol Graph symbol kind property contains a shorthand \c identifier
+/// which is prefixed by the source language name, useful for tooling to parse
+/// the kind, and a \c displayName for rendering human-readable names.
 static Object serializeSymbolKind(const APIRecord &Record,
                                   const LangOptions &LangOpts) {
   Object Kind;
@@ -250,9 +365,12 @@
 
 } // namespace
 
-const VersionTuple Serializer::FormatVersion{0, 5, 3};
+void SymbolGraphSerializer::anchor() {}
+
+/// Defines the format version emitted by SymbolGraphSerializer.
+const VersionTuple SymbolGraphSerializer::FormatVersion{0, 5, 3};
 
-Object Serializer::serializeMetadata() const {
+Object SymbolGraphSerializer::serializeMetadata() const {
   Object Metadata;
   serializeObject(Metadata, "formatVersion",
                   serializeSemanticVersion(FormatVersion));
@@ -260,15 +378,17 @@
   return Metadata;
 }
 
-Object Serializer::serializeModule() const {
+Object SymbolGraphSerializer::serializeModule() const {
   Object Module;
-  // FIXME: What to put in here?
+  // FIXME: We might not be building a module, some Clang-based languages might
+  // not have a "module" concept. Figure out a way to provide a name to
+  // describe the API set.
   Module["name"] = "";
   serializeObject(Module, "platform", serializePlatform(API.getTarget()));
   return Module;
 }
 
-bool Serializer::shouldSkip(const APIRecord &Record) const {
+bool SymbolGraphSerializer::shouldSkip(const APIRecord &Record) const {
   // Skip unconditionally unavailable symbols
   if (Record.Availability.isUnconditionallyUnavailable())
     return true;
@@ -276,7 +396,8 @@
   return false;
 }
 
-Optional<Object> Serializer::serializeAPIRecord(const APIRecord &Record) const {
+Optional<Object>
+SymbolGraphSerializer::serializeAPIRecord(const APIRecord &Record) const {
   if (shouldSkip(Record))
     return None;
 
@@ -297,7 +418,7 @@
   return Obj;
 }
 
-void Serializer::serializeGlobalRecord(const GlobalRecord &Record) {
+void SymbolGraphSerializer::serializeGlobalRecord(const GlobalRecord &Record) {
   auto Obj = serializeAPIRecord(Record);
   if (!Obj)
     return;
@@ -309,11 +430,12 @@
   Symbols.emplace_back(std::move(*Obj));
 }
 
-Object Serializer::serialize() {
+Object SymbolGraphSerializer::serialize() {
   Object Root;
   serializeObject(Root, "metadata", serializeMetadata());
   serializeObject(Root, "module", serializeModule());
 
+  // Serialize global records in the API set.
   for (const auto &Global : API.getGlobals())
     serializeGlobalRecord(*Global.second);
 
@@ -323,7 +445,7 @@
   return Root;
 }
 
-void Serializer::serialize(raw_ostream &os) {
+void SymbolGraphSerializer::serialize(raw_ostream &os) {
   Object root = serialize();
   if (Options.Compact)
     os << formatv("{0}", Value(std::move(root))) << "\n";
Index: clang/lib/ExtractAPI/Serialization/SerializerBase.cpp
===================================================================
--- /dev/null
+++ clang/lib/ExtractAPI/Serialization/SerializerBase.cpp
@@ -0,0 +1,19 @@
+//===- ExtractAPI/Serialization/SerializerBase.cpp --------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file implements the APISerializer interface.
+///
+//===----------------------------------------------------------------------===//
+
+#include "clang/ExtractAPI/Serialization/SerializerBase.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace clang::extractapi;
+
+void APISerializer::serialize(llvm::raw_ostream &os) {}
Index: clang/lib/ExtractAPI/ExtractAPIConsumer.cpp
===================================================================
--- clang/lib/ExtractAPI/ExtractAPIConsumer.cpp
+++ clang/lib/ExtractAPI/ExtractAPIConsumer.cpp
@@ -1,4 +1,4 @@
-//===- ExtractAPIConsumer.cpp -----------------------------------*- C++ -*-===//
+//===- ExtractAPI/ExtractAPIConsumer.cpp ------------------------*- C++ -*-===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -7,10 +7,10 @@
 //===----------------------------------------------------------------------===//
 ///
 /// \file
-/// \brief Defines the ExtractAPI AST visitor to collect API information.
+/// This file implements the ExtractAPIAction, and ASTVisitor/Consumer to
+/// collect API information.
 ///
 //===----------------------------------------------------------------------===//
-//
 
 #include "clang/AST/ASTConsumer.h"
 #include "clang/AST/ASTContext.h"
@@ -20,19 +20,22 @@
 #include "clang/AST/RawCommentList.h"
 #include "clang/AST/RecursiveASTVisitor.h"
 #include "clang/Basic/TargetInfo.h"
+#include "clang/ExtractAPI/API.h"
+#include "clang/ExtractAPI/AvailabilityInfo.h"
+#include "clang/ExtractAPI/DeclarationFragments.h"
+#include "clang/ExtractAPI/FrontendActions.h"
+#include "clang/ExtractAPI/Serialization/SymbolGraphSerializer.h"
 #include "clang/Frontend/ASTConsumers.h"
 #include "clang/Frontend/CompilerInstance.h"
-#include "clang/SymbolGraph/API.h"
-#include "clang/SymbolGraph/AvailabilityInfo.h"
-#include "clang/SymbolGraph/DeclarationFragments.h"
-#include "clang/SymbolGraph/FrontendActions.h"
-#include "clang/SymbolGraph/Serialization.h"
 #include "llvm/Support/raw_ostream.h"
 
 using namespace clang;
-using namespace symbolgraph;
+using namespace extractapi;
 
 namespace {
+
+/// The RecursiveASTVisitor to traverse symbol declarations and collect API
+/// information.
 class ExtractAPIVisitor : public RecursiveASTVisitor<ExtractAPIVisitor> {
 public:
   explicit ExtractAPIVisitor(ASTContext &Context)
@@ -59,6 +62,7 @@
         Decl->getTemplateSpecializationKind() == TSK_Undeclared)
       return true;
 
+    // Collect symbol information.
     StringRef Name = Decl->getName();
     StringRef USR = API.recordUSR(Decl);
     PresumedLoc Loc =
@@ -69,11 +73,14 @@
     if (auto *RawComment = Context.getRawCommentForDeclNoCache(Decl))
       Comment = RawComment->getFormattedLines(Context.getSourceManager(),
                                               Context.getDiagnostics());
+
+    // Build declaration fragments and sub-heading for the variable.
     DeclarationFragments Declaration =
         DeclarationFragmentsBuilder::getFragmentsForVar(Decl);
     DeclarationFragments SubHeading =
         DeclarationFragmentsBuilder::getSubHeading(Decl);
 
+    // Add the global variable record to the API set.
     API.addGlobalVar(Name, USR, Loc, Availability, Linkage, Comment,
                      Declaration, SubHeading);
     return true;
@@ -112,6 +119,7 @@
       return true;
     }
 
+    // Collect symbol information.
     StringRef Name = Decl->getName();
     StringRef USR = API.recordUSR(Decl);
     PresumedLoc Loc =
@@ -122,6 +130,8 @@
     if (auto *RawComment = Context.getRawCommentForDeclNoCache(Decl))
       Comment = RawComment->getFormattedLines(Context.getSourceManager(),
                                               Context.getDiagnostics());
+
+    // Build declaration fragments, sub-heading, and signature of the function.
     DeclarationFragments Declaration =
         DeclarationFragmentsBuilder::getFragmentsForFunction(Decl);
     DeclarationFragments SubHeading =
@@ -129,16 +139,19 @@
     FunctionSignature Signature =
         DeclarationFragmentsBuilder::getFunctionSignature(Decl);
 
+    // Add the function record to the API set.
     API.addFunction(Name, USR, Loc, Availability, Linkage, Comment, Declaration,
                     SubHeading, Signature);
     return true;
   }
 
 private:
+  /// Get availability information of the declaration \p D.
   AvailabilityInfo getAvailability(const Decl *D) const {
     StringRef PlatformName = Context.getTargetInfo().getPlatformName();
 
     AvailabilityInfo Availability;
+    // Collect availability attributes from all redeclarations.
     for (const auto *RD : D->redecls()) {
       for (const auto *A : RD->specific_attrs<AvailabilityAttr>()) {
         if (A->getPlatform()->getName() != PlatformName)
@@ -174,15 +187,21 @@
       : Visitor(Context), OS(std::move(OS)) {}
 
   void HandleTranslationUnit(ASTContext &Context) override {
+    // Use ExtractAPIVisitor to traverse symbol declarations in the context.
     Visitor.TraverseDecl(Context.getTranslationUnitDecl());
-    Serializer Serializer(Visitor.getAPI());
-    Serializer.serialize(*OS);
+
+    // Setup a SymbolGraphSerializer to write out collected API information in
+    // the Symbol Graph format.
+    // FIXME: Make the kind of APISerializer configurable.
+    SymbolGraphSerializer SGSerializer(Visitor.getAPI());
+    SGSerializer.serialize(*OS);
   }
 
 private:
   ExtractAPIVisitor Visitor;
   std::unique_ptr<raw_pwrite_stream> OS;
 };
+
 } // namespace
 
 std::unique_ptr<ASTConsumer>
Index: clang/lib/ExtractAPI/DeclarationFragments.cpp
===================================================================
--- clang/lib/ExtractAPI/DeclarationFragments.cpp
+++ clang/lib/ExtractAPI/DeclarationFragments.cpp
@@ -1,4 +1,4 @@
-//===- SymbolGraph/DeclarationFragments.cpp ---------------------*- C++ -*-===//
+//===- ExtractAPI/DeclarationFragments.cpp ----------------------*- C++ -*-===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -7,22 +7,24 @@
 //===----------------------------------------------------------------------===//
 ///
 /// \file
-/// \brief Defines SymbolGraph Declaration Fragments related classes.
+/// This file implements Declaration Fragments related classes.
 ///
 //===----------------------------------------------------------------------===//
 
-#include "clang/SymbolGraph/DeclarationFragments.h"
+#include "clang/ExtractAPI/DeclarationFragments.h"
 #include "clang/Index/USRGeneration.h"
 #include "llvm/ADT/StringSwitch.h"
 
-namespace clang {
-namespace symbolgraph {
+using namespace clang::extractapi;
+using namespace llvm;
 
 DeclarationFragments &DeclarationFragments::appendSpace() {
   if (!Fragments.empty()) {
     Fragment Last = Fragments.back();
     if (Last.Kind == FragmentKind::Text) {
-      if (Last.Spelling.back() != ' ') {
+      // Merge the extra space into the last fragment if the last fragment is
+      // also text.
+      if (Last.Spelling.back() != ' ') { // avoid extra trailing spaces.
         Last.Spelling.push_back(' ');
       }
     } else {
@@ -429,6 +431,3 @@
                      DeclarationFragments::FragmentKind::Identifier);
   return Fragments;
 }
-
-} // namespace symbolgraph
-} // namespace clang
Index: clang/lib/ExtractAPI/CMakeLists.txt
===================================================================
--- clang/lib/ExtractAPI/CMakeLists.txt
+++ clang/lib/ExtractAPI/CMakeLists.txt
@@ -2,11 +2,12 @@
   Support
   )
 
-add_clang_library(clangSymbolGraph
+add_clang_library(clangExtractAPI
   API.cpp
   ExtractAPIConsumer.cpp
   DeclarationFragments.cpp
-  Serialization.cpp
+  Serialization/SerializerBase.cpp
+  Serialization/SymbolGraphSerializer.cpp
 
   LINK_LIBS
   clangAST
Index: clang/lib/ExtractAPI/API.cpp
===================================================================
--- clang/lib/ExtractAPI/API.cpp
+++ clang/lib/ExtractAPI/API.cpp
@@ -1,4 +1,4 @@
-//===- SymbolGraph/API.cpp --------------------------------------*- C++ -*-===//
+//===- ExtractAPI/API.cpp ---------------------------------------*- C++ -*-===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -7,21 +7,20 @@
 //===----------------------------------------------------------------------===//
 ///
 /// \file
-/// \brief Defines SymbolGraph API records.
+/// This file implements the APIRecord and derived record structs,
+/// and the APISet class.
 ///
 //===----------------------------------------------------------------------===//
 
-#include "clang/SymbolGraph/API.h"
+#include "clang/ExtractAPI/API.h"
 #include "clang/AST/CommentCommandTraits.h"
 #include "clang/AST/CommentLexer.h"
 #include "clang/AST/RawCommentList.h"
 #include "clang/Index/USRGeneration.h"
 #include "llvm/Support/Allocator.h"
 
-namespace clang {
-namespace symbolgraph {
-
-APIRecord::~APIRecord() {}
+using namespace clang::extractapi;
+using namespace llvm;
 
 GlobalRecord *APISet::addGlobal(GVKind Kind, StringRef Name, StringRef USR,
                                 PresumedLoc Loc,
@@ -32,6 +31,7 @@
                                 FunctionSignature Signature) {
   auto Result = Globals.insert({Name, nullptr});
   if (Result.second) {
+    // Create the record if it does not already exist.
     auto Record = APIRecordUniquePtr<GlobalRecord>(new (Allocator) GlobalRecord{
         Kind, Name, USR, Loc, Availability, Linkage, Comment, Fragments,
         SubHeading, Signature});
@@ -70,6 +70,7 @@
   if (String.empty())
     return {};
 
+  // No need to allocate memory and copy if the string has already been stored.
   if (Allocator.identifyObject(String.data()))
     return String;
 
@@ -82,5 +83,6 @@
   return copyString(String, Allocator);
 }
 
-} // namespace symbolgraph
-} // namespace clang
+APIRecord::~APIRecord() {}
+
+void GlobalRecord::anchor() {}
Index: clang/lib/CMakeLists.txt
===================================================================
--- clang/lib/CMakeLists.txt
+++ clang/lib/CMakeLists.txt
@@ -10,6 +10,7 @@
 add_subdirectory(CodeGen)
 add_subdirectory(Analysis)
 add_subdirectory(Edit)
+add_subdirectory(ExtractAPI)
 add_subdirectory(Rewrite)
 if(CLANG_ENABLE_ARCMT)
   add_subdirectory(ARCMigrate)
@@ -23,7 +24,6 @@
 add_subdirectory(Index)
 add_subdirectory(IndexSerialization)
 add_subdirectory(StaticAnalyzer)
-add_subdirectory(SymbolGraph)
 add_subdirectory(Format)
 add_subdirectory(Testing)
 add_subdirectory(Interpreter)
Index: clang/include/clang/SymbolGraph/Serialization.h
===================================================================
--- clang/include/clang/SymbolGraph/Serialization.h
+++ /dev/null
@@ -1,58 +0,0 @@
-//===- SymbolGraph/Serialization.h ------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// \brief Defines the SymbolGraph serializer and parser.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_SYMBOLGRAPH_SERIALIZATION_H
-#define LLVM_CLANG_SYMBOLGRAPH_SERIALIZATION_H
-
-#include "clang/SymbolGraph/API.h"
-#include "llvm/Support/JSON.h"
-#include "llvm/Support/VersionTuple.h"
-#include "llvm/Support/raw_ostream.h"
-
-namespace clang {
-namespace symbolgraph {
-
-using namespace llvm::json;
-
-struct SerializerOption {
-  bool Compact;
-};
-
-class Serializer {
-public:
-  Serializer(const APISet &API, SerializerOption Options = {})
-      : API(API), Options(Options) {}
-
-  Object serialize();
-  void serialize(raw_ostream &os);
-
-private:
-  Object serializeMetadata() const;
-  Object serializeModule() const;
-  Optional<Object> serializeAPIRecord(const APIRecord &Record) const;
-  void serializeGlobalRecord(const GlobalRecord &Record);
-
-  bool shouldSkip(const APIRecord &Record) const;
-
-  const APISet &API;
-  SerializerOption Options;
-  Array Symbols;
-  Array Relationships;
-
-  static const VersionTuple FormatVersion;
-};
-
-} // namespace symbolgraph
-} // namespace clang
-
-#endif // LLVM_CLANG_SYMBOLGRAPH_SERIALIZATION_H
Index: clang/include/clang/ExtractAPI/Serialization/SymbolGraphSerializer.h
===================================================================
--- /dev/null
+++ clang/include/clang/ExtractAPI/Serialization/SymbolGraphSerializer.h
@@ -0,0 +1,100 @@
+//===- ExtractAPI/Serialization/SymbolGraphSerializer.h ---------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file defines the SymbolGraphSerializer class.
+///
+/// Implement an APISerializer for the Symbol Graph format for ExtractAPI.
+/// See https://github.com/apple/swift-docc-symbolkit.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_EXTRACTAPI_SERIALIZATION_SYMBOLGRAPHSERIALIZER_H
+#define LLVM_CLANG_EXTRACTAPI_SERIALIZATION_SYMBOLGRAPHSERIALIZER_H
+
+#include "clang/ExtractAPI/API.h"
+#include "clang/ExtractAPI/Serialization/SerializerBase.h"
+#include "llvm/Support/JSON.h"
+#include "llvm/Support/VersionTuple.h"
+#include "llvm/Support/raw_ostream.h"
+
+namespace clang {
+namespace extractapi {
+
+using namespace llvm::json;
+
+/// The serializer that organizes API information in the Symbol Graph format.
+///
+/// The Symbol Graph format (https://github.com/apple/swift-docc-symbolkit)
+/// models an API set as a directed graph, where nodes are symbol declarations,
+/// and edges are relationships between the connected symbols.
+class SymbolGraphSerializer : public APISerializer {
+  virtual void anchor();
+
+  /// A JSON array of formatted symbols in \c APISet.
+  Array Symbols;
+
+  /// A JSON array of formatted symbol relationships in \c APISet.
+  Array Relationships;
+
+  /// The Symbol Graph format version used by this serializer.
+  static const VersionTuple FormatVersion;
+
+public:
+  /// Serialize the APIs in \c APISet in the Symbol Graph format.
+  ///
+  /// \returns a JSON object that contains the root of the formatted
+  /// Symbol Graph.
+  Object serialize();
+
+  /// Implement the APISerializer::serialize interface. Wrap serialize(void) and
+  /// write out the serialized JSON object to \p os.
+  void serialize(raw_ostream &os) override;
+
+private:
+  /// Synthesize the metadata section of the Symbol Graph format.
+  ///
+  /// The metadata section describes information about the Symbol Graph itself,
+  /// including the format version and the generator information.
+  Object serializeMetadata() const;
+
+  /// Synthesize the module section of the Symbol Graph format.
+  ///
+  /// The module section contains information about the product that is defined
+  /// by the given API set.
+  /// Note that "module" here is not to be confused with the Clang/C++ module
+  /// concept.
+  Object serializeModule() const;
+
+  /// Determine if the given \p Record should be skipped during serialization.
+  bool shouldSkip(const APIRecord &Record) const;
+
+  /// Format the common API information for \p Record.
+  ///
+  /// This handles the shared information of all kinds of API records,
+  /// for example identifier and source location. The resulting object is then
+  /// augmented with kind-specific symbol information by the caller.
+  /// This method also checks if the given \p Record should be skipped during
+  /// serialization.
+  ///
+  /// \returns \c None if this \p Record should be skipped, or a JSON object
+  /// containing common symbol information of \p Record.
+  Optional<Object> serializeAPIRecord(const APIRecord &Record) const;
+
+  /// Serialize a global record.
+  void serializeGlobalRecord(const GlobalRecord &Record);
+
+public:
+  SymbolGraphSerializer(const APISet &API, APISerializerOption Options = {})
+      : APISerializer(API, Options) {}
+};
+
+} // namespace extractapi
+} // namespace clang
+
+#endif // LLVM_CLANG_EXTRACTAPI_SERIALIZATION_SYMBOLGRAPHSERIALIZER_H
Index: clang/include/clang/ExtractAPI/Serialization/SerializerBase.h
===================================================================
--- /dev/null
+++ clang/include/clang/ExtractAPI/Serialization/SerializerBase.h
@@ -0,0 +1,56 @@
+//===- ExtractAPI/Serialization/SerializerBase.h ----------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file defines the ExtractAPI APISerializer interface.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_EXTRACTAPI_SERIALIZATION_SERIALIZERBASE_H
+#define LLVM_CLANG_EXTRACTAPI_SERIALIZATION_SERIALIZERBASE_H
+
+#include "clang/ExtractAPI/API.h"
+#include "llvm/Support/raw_ostream.h"
+
+namespace clang {
+namespace extractapi {
+
+/// Common options to customize the serializer output.
+struct APISerializerOption {
+  /// Do not include unnecessary whitespaces to save space.
+  bool Compact;
+};
+
+/// The base interface of serializers for API information.
+class APISerializer {
+public:
+  /// Serialize the API information to \p os.
+  virtual void serialize(raw_ostream &os) = 0;
+
+protected:
+  const APISet &API;
+  APISerializerOption Options;
+
+public:
+  APISerializer() = delete;
+  APISerializer(const APISerializer &) = delete;
+  APISerializer(APISerializer &&) = delete;
+  APISerializer &operator=(const APISerializer &) = delete;
+  APISerializer &operator=(APISerializer &&) = delete;
+
+protected:
+  APISerializer(const APISet &API, APISerializerOption Options = {})
+      : API(API), Options(Options) {}
+
+  virtual ~APISerializer() = default;
+};
+
+} // namespace extractapi
+} // namespace clang
+
+#endif // LLVM_CLANG_EXTRACTAPI_SERIALIZATION_SERIALIZERBASE_H
Index: clang/include/clang/ExtractAPI/FrontendActions.h
===================================================================
--- clang/include/clang/ExtractAPI/FrontendActions.h
+++ clang/include/clang/ExtractAPI/FrontendActions.h
@@ -1,4 +1,4 @@
-//===- SymbolGraph/FrontendActions.h -----------------------*- C++ -*-===//
+//===- ExtractAPI/FrontendActions.h -----------------------------*- C++ -*-===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -7,17 +7,18 @@
 //===----------------------------------------------------------------------===//
 ///
 /// \file
-/// \brief Defines SymbolGraph frontend actions.
+/// This file defines the ExtractAPIAction frontend action.
 ///
 //===----------------------------------------------------------------------===//
 
-#ifndef LLVM_CLANG_SYMBOLGRAPH_FRONTEND_ACTIONS_H
-#define LLVM_CLANG_SYMBOLGRAPH_FRONTEND_ACTIONS_H
+#ifndef LLVM_CLANG_EXTRACTAPI_FRONTEND_ACTIONS_H
+#define LLVM_CLANG_EXTRACTAPI_FRONTEND_ACTIONS_H
 
 #include "clang/Frontend/FrontendAction.h"
 
 namespace clang {
 
+/// ExtractAPIAction sets up the output file and creates the ExtractAPIVisitor.
 class ExtractAPIAction : public ASTFrontendAction {
 protected:
   std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
@@ -30,4 +31,4 @@
 
 } // namespace clang
 
-#endif // LLVM_CLANG_SYMBOLGRAPH_FRONTEND_ACTIONS_H
+#endif // LLVM_CLANG_EXTRACTAPI_FRONTEND_ACTIONS_H
Index: clang/include/clang/ExtractAPI/DeclarationFragments.h
===================================================================
--- clang/include/clang/ExtractAPI/DeclarationFragments.h
+++ clang/include/clang/ExtractAPI/DeclarationFragments.h
@@ -1,4 +1,4 @@
-//===- SymbolGraph/DeclarationFragments.h -----------------------*- C++ -*-===//
+//===- ExtractAPI/DeclarationFragments.h ------------------------*- C++ -*-===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -7,12 +7,16 @@
 //===----------------------------------------------------------------------===//
 ///
 /// \file
-/// \brief Defines SymbolGraph Declaration Fragments related classes.
+/// This file defines the Declaration Fragments related classes.
+///
+/// Declaration Fragments represent parts of a symbol declaration tagged with
+/// syntactic/semantic information.
+/// See https://github.com/apple/swift-docc-symbolkit
 ///
 //===----------------------------------------------------------------------===//
 
-#ifndef LLVM_CLANG_SYMBOLGRAPH_DECLARATION_FRAGMENTS_H
-#define LLVM_CLANG_SYMBOLGRAPH_DECLARATION_FRAGMENTS_H
+#ifndef LLVM_CLANG_EXTRACTAPI_DECLARATION_FRAGMENTS_H
+#define LLVM_CLANG_EXTRACTAPI_DECLARATION_FRAGMENTS_H
 
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Decl.h"
@@ -21,29 +25,64 @@
 #include <vector>
 
 namespace clang {
-namespace symbolgraph {
+namespace extractapi {
 
+/// DeclarationFragments is a vector of tagged important parts of a symbol's
+/// declaration.
+///
+/// The fragments sequence can be joined to form spans of declaration text, with
+/// attached information useful for purposes like syntax-highlighting etc.
+/// For example:
+/// \code
+///   const -> keyword    "const"
+///   int   -> type       "int"
+///   pi;   -> identifier "pi"
+/// \endcode
 class DeclarationFragments {
 public:
   DeclarationFragments() = default;
 
+  /// The kind of a fragment.
   enum class FragmentKind {
+    /// Unknown fragment kind.
     None,
+
     Keyword,
     Attribute,
     NumberLiteral,
     StringLiteral,
     Identifier,
+
+    /// Identifier that refers to a type in the context.
     TypeIdentifier,
+
+    /// Parameter that's used as generics in the context. For example template
+    /// parameters.
     GenericParameter,
+
+    /// External parameters in Objective-C methods.
+    /// For example, \c forKey in
+    /// \code{.m}
+    ///   - (void) setValue:(Value)value forKey(Key)key
+    /// \endcode
     ExternalParam,
+
+    /// Internal/local parameters in Objective-C methods.
+    /// For example, \c key in
+    /// \code{.m}
+    ///   - (void) setValue:(Value)value forKey(Key)key
+    /// \endcode
     InternalParam,
+
     Text,
   };
 
+  /// Fragment holds information of a single fragment.
   struct Fragment {
     std::string Spelling;
     FragmentKind Kind;
+
+    /// The USR of the fragment symbol, if applicable.
     std::string PreciseIdentifier;
 
     Fragment(StringRef Spelling, FragmentKind Kind, StringRef PreciseIdentifier)
@@ -53,10 +92,16 @@
 
   const std::vector<Fragment> &getFragments() const { return Fragments; }
 
+  /// Append a new Fragment to the end of the Fragments.
+  ///
+  /// \returns a reference to the DeclarationFragments object itself after
+  /// appending to chain up consecutive appends.
   DeclarationFragments &append(StringRef Spelling, FragmentKind Kind,
                                StringRef PreciseIdentifier = "") {
     if (Kind == FragmentKind::Text && !Fragments.empty() &&
         Fragments.back().Kind == FragmentKind::Text) {
+      // If appending a text fragment, and the last fragment is also text,
+      // merge into the last fragment.
       Fragments.back().Spelling.append(Spelling.data(), Spelling.size());
     } else {
       Fragments.emplace_back(Spelling, Kind, PreciseIdentifier);
@@ -64,6 +109,13 @@
     return *this;
   }
 
+  /// Append another DeclarationFragments to the end.
+  ///
+  /// Note: \p Other is moved from and cannot be used after a call to this
+  /// method.
+  ///
+  /// \returns a reference to the DeclarationFragments object itself after
+  /// appending to chain up consecutive appends.
   DeclarationFragments &append(DeclarationFragments &&Other) {
     Fragments.insert(Fragments.end(),
                      std::make_move_iterator(Other.Fragments.begin()),
@@ -72,19 +124,29 @@
     return *this;
   }
 
+  /// Append a text Fragment of a space character.
+  ///
+  /// \returns a reference to the DeclarationFragments object itself after
+  /// appending to chain up consecutive appends.
   DeclarationFragments &appendSpace();
 
+  /// Get the string description of a FragmentKind \p Kind.
   static StringRef getFragmentKindString(FragmentKind Kind);
+
+  /// Get the corresponding FragmentKind from string \p S.
   static FragmentKind parseFragmentKindFromString(StringRef S);
 
 private:
   std::vector<Fragment> Fragments;
 };
 
+/// Store function signature information with DeclarationFragments of the
+/// return type and parameters.
 class FunctionSignature {
 public:
   FunctionSignature() = default;
 
+  /// Parameter holds the name and DeclarationFragments of a single parameter.
   struct Parameter {
     std::string Name;
     DeclarationFragments Fragments;
@@ -104,6 +166,10 @@
 
   void setReturnType(DeclarationFragments RT) { ReturnType = RT; }
 
+  /// Determine if the FunctionSignature is empty.
+  ///
+  /// \returns true if the return type DeclarationFragments is empty and there
+  /// is no parameter, otherwise false.
   bool empty() const {
     return Parameters.empty() && ReturnType.getFragments().empty();
   }
@@ -113,28 +179,46 @@
   DeclarationFragments ReturnType;
 };
 
+/// A factory class to build DeclarationFragments for different kinds of Decl.
 class DeclarationFragmentsBuilder {
 public:
+  /// Build DeclarationFragments for a variable declaration VarDecl.
   static DeclarationFragments getFragmentsForVar(const VarDecl *);
+
+  /// Build DeclarationFragments for a function declaration FunctionDecl.
   static DeclarationFragments getFragmentsForFunction(const FunctionDecl *);
+
+  /// Build sub-heading fragments for a NamedDecl.
   static DeclarationFragments getSubHeading(const NamedDecl *);
+
+  /// Build FunctionSignature for a function declaration FunctionDecl.
   static FunctionSignature getFunctionSignature(const FunctionDecl *);
 
 private:
   DeclarationFragmentsBuilder() = delete;
 
+  /// Build DeclarationFragments for a QualType.
   static DeclarationFragments getFragmentsForType(const QualType, ASTContext &,
                                                   DeclarationFragments &);
+
+  /// Build DeclarationFragments for a Type.
   static DeclarationFragments getFragmentsForType(const Type *, ASTContext &,
                                                   DeclarationFragments &);
+
+  /// Build DeclarationFragments for a NestedNameSpecifier.
   static DeclarationFragments getFragmentsForNNS(const NestedNameSpecifier *,
                                                  ASTContext &,
                                                  DeclarationFragments &);
+
+  /// Build DeclarationFragments for Qualifiers.
   static DeclarationFragments getFragmentsForQualifiers(const Qualifiers quals);
+
+  /// Build DeclarationFragments for a parameter variable declaration
+  /// ParmVarDecl.
   static DeclarationFragments getFragmentsForParam(const ParmVarDecl *);
 };
 
-} // namespace symbolgraph
+} // namespace extractapi
 } // namespace clang
 
-#endif // LLVM_CLANG_SYMBOLGRAPH_DECLARATION_FRAGMENTS_H
+#endif // LLVM_CLANG_EXTRACTAPI_DECLARATION_FRAGMENTS_H
Index: clang/include/clang/ExtractAPI/AvailabilityInfo.h
===================================================================
--- clang/include/clang/ExtractAPI/AvailabilityInfo.h
+++ clang/include/clang/ExtractAPI/AvailabilityInfo.h
@@ -1,4 +1,4 @@
-//===- SymbolGraph/AvailabilityInfo.h - Availability Info -------*- C++ -*-===//
+//===- ExtractAPI/AvailabilityInfo.h - Availability Info --------*- C++ -*-===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -7,12 +7,13 @@
 //===----------------------------------------------------------------------===//
 ///
 /// \file
-/// \brief Defines the Availability Info for a declaration.
+/// This file defines the AvailabilityInfo struct that collects availability
+/// attributes of a symbol.
 ///
 //===----------------------------------------------------------------------===//
 
-#ifndef LLVM_CLANG_SYMBOLGRAPH_AVAILABILITY_INFO_H
-#define LLVM_CLANG_SYMBOLGRAPH_AVAILABILITY_INFO_H
+#ifndef LLVM_CLANG_EXTRACTAPI_AVAILABILITY_INFO_H
+#define LLVM_CLANG_EXTRACTAPI_AVAILABILITY_INFO_H
 
 #include "llvm/Support/Error.h"
 #include "llvm/Support/VersionTuple.h"
@@ -21,8 +22,9 @@
 using llvm::VersionTuple;
 
 namespace clang {
-namespace symbolgraph {
+namespace extractapi {
 
+/// Stores availability attributes of a symbol.
 struct AvailabilityInfo {
   VersionTuple Introduced;
   VersionTuple Deprecated;
@@ -31,21 +33,31 @@
   bool UnconditionallyDeprecated{false};
   bool UnconditionallyUnavailable{false};
 
-  explicit AvailabilityInfo(bool Unavailable = false)
-      : Unavailable(Unavailable) {}
-
-  AvailabilityInfo(VersionTuple I, VersionTuple D, VersionTuple O, bool U,
-                   bool UD, bool UU)
-      : Introduced(I), Deprecated(D), Obsoleted(O), Unavailable(U),
-        UnconditionallyDeprecated(UD), UnconditionallyUnavailable(UU) {}
-
+  /// Determine if this AvailabilityInfo represents the default availability.
   bool isDefault() const { return *this == AvailabilityInfo(); }
+
+  /// Check if the symbol is unavailable.
   bool isUnavailable() const { return Unavailable; }
+
+  /// Check if the symbol is unconditionally deprecated.
+  ///
+  /// i.e. \code __attribute__((deprecated)) \endcode
   bool isUnconditionallyDeprecated() const { return UnconditionallyDeprecated; }
+
+  /// Check if the symbol is unconditionally unavailable.
+  ///
+  /// i.e. \code __attribute__((unavailable)) \endcode
   bool isUnconditionallyUnavailable() const {
     return UnconditionallyUnavailable;
   }
 
+  AvailabilityInfo() = default;
+
+  AvailabilityInfo(VersionTuple I, VersionTuple D, VersionTuple O, bool U,
+                   bool UD, bool UU)
+      : Introduced(I), Deprecated(D), Obsoleted(O), Unavailable(U),
+        UnconditionallyDeprecated(UD), UnconditionallyUnavailable(UU) {}
+
   friend bool operator==(const AvailabilityInfo &Lhs,
                          const AvailabilityInfo &Rhs);
 };
@@ -60,7 +72,7 @@
                   Rhs.UnconditionallyUnavailable);
 }
 
-} // namespace symbolgraph
+} // namespace extractapi
 } // namespace clang
 
-#endif // LLVM_CLANG_SYMBOLGRAPH_AVAILABILITY_INFO_H
+#endif // LLVM_CLANG_EXTRACTAPI_AVAILABILITY_INFO_H
Index: clang/include/clang/ExtractAPI/API.h
===================================================================
--- clang/include/clang/ExtractAPI/API.h
+++ clang/include/clang/ExtractAPI/API.h
@@ -1,4 +1,4 @@
-//===- SymbolGraph/API.h ----------------------------------------*- C++ -*-===//
+//===- ExtractAPI/API.h -----------------------------------------*- C++ -*-===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -7,18 +7,22 @@
 //===----------------------------------------------------------------------===//
 ///
 /// \file
-/// \brief Defines SymbolGraph API records.
+/// This file defines the APIRecord-based structs and the APISet class.
+///
+/// Clang ExtractAPI is a tool to collect API information from a given set of
+/// header files. The structures in this file describe data representations of
+/// the API information collected for various kinds of symbols.
 ///
 //===----------------------------------------------------------------------===//
 
-#ifndef LLVM_CLANG_SYMBOLGRAPH_API_H
-#define LLVM_CLANG_SYMBOLGRAPH_API_H
+#ifndef LLVM_CLANG_EXTRACTAPI_API_H
+#define LLVM_CLANG_EXTRACTAPI_API_H
 
 #include "clang/AST/Decl.h"
 #include "clang/AST/RawCommentList.h"
 #include "clang/Basic/SourceLocation.h"
-#include "clang/SymbolGraph/AvailabilityInfo.h"
-#include "clang/SymbolGraph/DeclarationFragments.h"
+#include "clang/ExtractAPI/AvailabilityInfo.h"
+#include "clang/ExtractAPI/DeclarationFragments.h"
 #include "llvm/ADT/MapVector.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/Triple.h"
@@ -27,18 +31,43 @@
 #include <memory>
 
 namespace clang {
-namespace symbolgraph {
+namespace extractapi {
 
+/// DocComment is a vector of RawComment::CommentLine.
+///
+/// Each line represents one line of striped documentation comment,
+/// with source range information. This simplifies calculating the source
+/// location of a character in the doc comment for pointing back to the source
+/// file.
+/// e.g.
+/// \code
+///   /// This is a documentation comment
+///       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'  First line.
+///   ///     with multiple lines.
+///       ^~~~~~~~~~~~~~~~~~~~~~~'         Second line.
+/// \endcode
 using DocComment = std::vector<RawComment::CommentLine>;
 
+/// The base representation of an API record. Holds common symbol information.
 struct APIRecord {
   StringRef Name;
   StringRef USR;
   PresumedLoc Location;
   AvailabilityInfo Availability;
   LinkageInfo Linkage;
+
+  /// Documentation comment lines attached to this symbol declaration.
   DocComment Comment;
+
+  /// Declaration fragments of this symbol declaration.
   DeclarationFragments Declaration;
+
+  /// SubHeading provides a more detailed representation than the plain
+  /// declaration name.
+  ///
+  /// SubHeading is an array of declaration fragments of tagged declaration
+  /// name, with potentially more tokens (for example the \c +/- symbol for
+  /// Objective-C class/instance methods).
   DeclarationFragments SubHeading;
 
   /// Discriminator for LLVM-style RTTI (dyn_cast<> et al.)
@@ -66,14 +95,18 @@
   virtual ~APIRecord() = 0;
 };
 
+/// The kind of a global record.
 enum class GVKind : uint8_t {
   Unknown = 0,
   Variable = 1,
   Function = 2,
 };
 
+/// This holds information associated with global variables or functions.
 struct GlobalRecord : APIRecord {
   GVKind GlobalKind;
+
+  /// The function signature of the record if it is a function.
   FunctionSignature Signature;
 
   GlobalRecord(GVKind Kind, StringRef Name, StringRef USR, PresumedLoc Loc,
@@ -87,16 +120,15 @@
   static bool classof(const APIRecord *Record) {
     return Record->getKind() == RK_Global;
   }
+
+private:
+  virtual void anchor();
 };
 
+/// APISet holds the set of API records collected from given inputs.
 class APISet {
 public:
-  APISet(const llvm::Triple &Target, const LangOptions &LangOpts)
-      : Target(Target), LangOpts(LangOpts) {}
-
-  const llvm::Triple &getTarget() const { return Target; }
-  const LangOptions &getLangOpts() const { return LangOpts; }
-
+  /// Create and add a GlobalRecord of kind \p Kind into the API set.
   GlobalRecord *addGlobal(GVKind Kind, StringRef Name, StringRef USR,
                           PresumedLoc Loc, const AvailabilityInfo &Availability,
                           LinkageInfo Linkage, const DocComment &Comment,
@@ -104,12 +136,14 @@
                           DeclarationFragments SubHeading,
                           FunctionSignature Signature);
 
+  /// Create and add a global variable record into the API set.
   GlobalRecord *addGlobalVar(StringRef Name, StringRef USR, PresumedLoc Loc,
                              const AvailabilityInfo &Availability,
                              LinkageInfo Linkage, const DocComment &Comment,
                              DeclarationFragments Declaration,
                              DeclarationFragments SubHeading);
 
+  /// Create and add a function record into the API set.
   GlobalRecord *addFunction(StringRef Name, StringRef USR, PresumedLoc Loc,
                             const AvailabilityInfo &Availability,
                             LinkageInfo Linkage, const DocComment &Comment,
@@ -117,10 +151,6 @@
                             DeclarationFragments SubHeading,
                             FunctionSignature Signature);
 
-  StringRef recordUSR(const Decl *D);
-  StringRef copyString(StringRef String, llvm::BumpPtrAllocator &Allocator);
-  StringRef copyString(StringRef String);
-
 private:
   /// \brief A custom deleter used for ``std::unique_ptr`` to APIRecords stored
   /// in the BumpPtrAllocator.
@@ -138,20 +168,50 @@
   using APIRecordUniquePtr =
       std::unique_ptr<T, UniquePtrBumpPtrAllocatorDeleter<T>>;
 
+  /// A map to store the set of GlobalRecords with the declaration name as the
+  /// key.
   using GlobalRecordMap =
       llvm::MapVector<StringRef, APIRecordUniquePtr<GlobalRecord>>;
 
+  /// Get the target triple for the ExtractAPI invocation.
+  const llvm::Triple &getTarget() const { return Target; }
+
+  /// Get the language options used to parse the APIs.
+  const LangOptions &getLangOpts() const { return LangOpts; }
+
   const GlobalRecordMap &getGlobals() const { return Globals; }
 
+  /// Generate and store the USR of declaration \p D.
+  ///
+  /// Note: The USR string is stored in and owned by Allocator.
+  ///
+  /// \returns a StringRef of the generated USR string.
+  StringRef recordUSR(const Decl *D);
+
+  /// Copy \p String into \p Allocator to keep it alive.
+  ///
+  /// \returns a StringRef of the copied string in the \p Allocator.
+  StringRef copyString(StringRef String, llvm::BumpPtrAllocator &Allocator);
+
+  /// Copy \p String into the Allocator in this APISet.
+  ///
+  /// \returns a StringRef of the copied string in the Allocator.
+  StringRef copyString(StringRef String);
+
+  APISet(const llvm::Triple &Target, const LangOptions &LangOpts)
+      : Target(Target), LangOpts(LangOpts) {}
+
 private:
+  /// BumpPtrAllocator to store APIRecords and generated/copied strings.
   llvm::BumpPtrAllocator Allocator;
+
   const llvm::Triple Target;
   const LangOptions LangOpts;
 
   GlobalRecordMap Globals;
 };
 
-} // namespace symbolgraph
+} // namespace extractapi
 } // namespace clang
 
-#endif // LLVM_CLANG_SYMBOLGRAPH_API_H
+#endif // LLVM_CLANG_EXTRACTAPI_API_H
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to