Author: Samarth Narang
Date: 2025-06-07T08:04:56-07:00
New Revision: d5704097fcc2128bb8c97867e090543024a936d0

URL: 
https://github.com/llvm/llvm-project/commit/d5704097fcc2128bb8c97867e090543024a936d0
DIFF: 
https://github.com/llvm/llvm-project/commit/d5704097fcc2128bb8c97867e090543024a936d0.diff

LOG: Refactor clang doc comment structure (#142273)

This patch refactors CommentKind handling in clang-doc by introducing a
strongly typed enum class for better type safety and clarity. It updates
all relevant places, including YAML traits and serialization, to work
with the new enum. Additionally, it enhances the Mustache-based HTML
generation by fully supporting all comment kinds, ensuring accurate
structured rendering of comment blocks. The changes simplify future
maintenance, improve robustness by eliminating unchecked defaults, and
ensure consistency between generators.

Fixes https://github.com/llvm/llvm-project/issues/142083

Added: 
    

Modified: 
    clang-tools-extra/clang-doc/BitcodeReader.cpp
    clang-tools-extra/clang-doc/BitcodeWriter.cpp
    clang-tools-extra/clang-doc/HTMLGenerator.cpp
    clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp
    clang-tools-extra/clang-doc/MDGenerator.cpp
    clang-tools-extra/clang-doc/Representation.cpp
    clang-tools-extra/clang-doc/Representation.h
    clang-tools-extra/clang-doc/Serialize.cpp
    clang-tools-extra/clang-doc/YAMLGenerator.cpp
    clang-tools-extra/test/clang-doc/templates.cpp
    clang-tools-extra/unittests/clang-doc/BitcodeTest.cpp
    clang-tools-extra/unittests/clang-doc/HTMLGeneratorTest.cpp
    clang-tools-extra/unittests/clang-doc/MDGeneratorTest.cpp
    clang-tools-extra/unittests/clang-doc/MergeTest.cpp
    clang-tools-extra/unittests/clang-doc/YAMLGeneratorTest.cpp

Removed: 
    


################################################################################
diff  --git a/clang-tools-extra/clang-doc/BitcodeReader.cpp 
b/clang-tools-extra/clang-doc/BitcodeReader.cpp
index 546dd0254ec01..57dd514b90a2b 100644
--- a/clang-tools-extra/clang-doc/BitcodeReader.cpp
+++ b/clang-tools-extra/clang-doc/BitcodeReader.cpp
@@ -315,9 +315,13 @@ static llvm::Error parseRecord(const Record &R, unsigned 
ID,
 
 static llvm::Error parseRecord(const Record &R, unsigned ID,
                                llvm::StringRef Blob, CommentInfo *I) {
+  llvm::SmallString<16> KindStr;
   switch (ID) {
   case COMMENT_KIND:
-    return decodeRecord(R, I->Kind, Blob);
+    if (llvm::Error Err = decodeRecord(R, KindStr, Blob))
+      return Err;
+    I->Kind = stringToCommentKind(KindStr);
+    return llvm::Error::success();
   case COMMENT_TEXT:
     return decodeRecord(R, I->Text, Blob);
   case COMMENT_NAME:

diff  --git a/clang-tools-extra/clang-doc/BitcodeWriter.cpp 
b/clang-tools-extra/clang-doc/BitcodeWriter.cpp
index f0a445e606bff..708ce09d9e5b2 100644
--- a/clang-tools-extra/clang-doc/BitcodeWriter.cpp
+++ b/clang-tools-extra/clang-doc/BitcodeWriter.cpp
@@ -484,8 +484,9 @@ void ClangDocBitcodeWriter::emitBlock(const MemberTypeInfo 
&T) {
 
 void ClangDocBitcodeWriter::emitBlock(const CommentInfo &I) {
   StreamSubBlockGuard Block(Stream, BI_COMMENT_BLOCK_ID);
+  // Handle Kind (enum) separately, since it is not a string.
+  emitRecord(commentKindToString(I.Kind), COMMENT_KIND);
   for (const auto &L : std::vector<std::pair<llvm::StringRef, RecordId>>{
-           {I.Kind, COMMENT_KIND},
            {I.Text, COMMENT_TEXT},
            {I.Name, COMMENT_NAME},
            {I.Direction, COMMENT_DIRECTION},

diff  --git a/clang-tools-extra/clang-doc/HTMLGenerator.cpp 
b/clang-tools-extra/clang-doc/HTMLGenerator.cpp
index 93b9279462a89..7293a129177c9 100644
--- a/clang-tools-extra/clang-doc/HTMLGenerator.cpp
+++ b/clang-tools-extra/clang-doc/HTMLGenerator.cpp
@@ -635,7 +635,8 @@ genHTML(const Index &Index, StringRef InfoPath, bool 
IsOutermostList) {
 }
 
 static std::unique_ptr<HTMLNode> genHTML(const CommentInfo &I) {
-  if (I.Kind == "FullComment") {
+  switch (I.Kind) {
+  case CommentKind::CK_FullComment: {
     auto FullComment = std::make_unique<TagNode>(HTMLTag::TAG_DIV);
     for (const auto &Child : I.Children) {
       std::unique_ptr<HTMLNode> Node = genHTML(*Child);
@@ -645,7 +646,7 @@ static std::unique_ptr<HTMLNode> genHTML(const CommentInfo 
&I) {
     return std::move(FullComment);
   }
 
-  if (I.Kind == "ParagraphComment") {
+  case CommentKind::CK_ParagraphComment: {
     auto ParagraphComment = std::make_unique<TagNode>(HTMLTag::TAG_P);
     for (const auto &Child : I.Children) {
       std::unique_ptr<HTMLNode> Node = genHTML(*Child);
@@ -657,7 +658,7 @@ static std::unique_ptr<HTMLNode> genHTML(const CommentInfo 
&I) {
     return std::move(ParagraphComment);
   }
 
-  if (I.Kind == "BlockCommandComment") {
+  case CommentKind::CK_BlockCommandComment: {
     auto BlockComment = std::make_unique<TagNode>(HTMLTag::TAG_DIV);
     BlockComment->Children.emplace_back(
         std::make_unique<TagNode>(HTMLTag::TAG_DIV, I.Name));
@@ -670,12 +671,26 @@ static std::unique_ptr<HTMLNode> genHTML(const 
CommentInfo &I) {
       return nullptr;
     return std::move(BlockComment);
   }
-  if (I.Kind == "TextComment") {
-    if (I.Text == "")
+
+  case CommentKind::CK_TextComment: {
+    if (I.Text.empty())
       return nullptr;
     return std::make_unique<TextNode>(I.Text);
   }
-  return nullptr;
+
+  // For now, return nullptr for unsupported comment kinds
+  case CommentKind::CK_InlineCommandComment:
+  case CommentKind::CK_HTMLStartTagComment:
+  case CommentKind::CK_HTMLEndTagComment:
+  case CommentKind::CK_ParamCommandComment:
+  case CommentKind::CK_TParamCommandComment:
+  case CommentKind::CK_VerbatimBlockComment:
+  case CommentKind::CK_VerbatimBlockLineComment:
+  case CommentKind::CK_VerbatimLineComment:
+  case CommentKind::CK_Unknown:
+    return nullptr;
+  }
+  llvm_unreachable("Unhandled CommentKind");
 }
 
 static std::unique_ptr<TagNode> genHTML(const std::vector<CommentInfo> &C) {

diff  --git a/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp 
b/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp
index 8b7e4896c9fde..2dc18e98fd8bb 100644
--- a/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp
+++ b/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp
@@ -208,37 +208,110 @@ static json::Value extractValue(const TypedefInfo &I) {
 }
 
 static json::Value extractValue(const CommentInfo &I) {
-  assert((I.Kind == "BlockCommandComment" || I.Kind == "FullComment" ||
-          I.Kind == "ParagraphComment" || I.Kind == "TextComment") &&
-         "Unknown Comment type in CommentInfo.");
-
   Object Obj = Object();
-  json::Value Child = Object();
 
-  // TextComment has no children, so return it.
-  if (I.Kind == "TextComment") {
-    Obj.insert({"TextComment", I.Text});
-    return Obj;
-  }
+  json::Value ChildVal = Object();
+  Object &Child = *ChildVal.getAsObject();
 
-  // BlockCommandComment needs to generate a Command key.
-  if (I.Kind == "BlockCommandComment")
-    Child.getAsObject()->insert({"Command", I.Name});
-
-  // Use the same handling for everything else.
-  // Only valid for:
-  //  - BlockCommandComment
-  //  - FullComment
-  //  - ParagraphComment
   json::Value ChildArr = Array();
   auto &CARef = *ChildArr.getAsArray();
   CARef.reserve(I.Children.size());
   for (const auto &C : I.Children)
     CARef.emplace_back(extractValue(*C));
-  Child.getAsObject()->insert({"Children", ChildArr});
-  Obj.insert({I.Kind, Child});
 
-  return Obj;
+  switch (I.Kind) {
+  case CommentKind::CK_TextComment: {
+    Obj.insert({commentKindToString(I.Kind), I.Text});
+    return Obj;
+  }
+
+  case CommentKind::CK_BlockCommandComment: {
+    Child.insert({"Command", I.Name});
+    Child.insert({"Children", ChildArr});
+    Obj.insert({commentKindToString(I.Kind), ChildVal});
+    return Obj;
+  }
+
+  case CommentKind::CK_InlineCommandComment: {
+    json::Value ArgsArr = Array();
+    auto &ARef = *ArgsArr.getAsArray();
+    ARef.reserve(I.Args.size());
+    for (const auto &Arg : I.Args)
+      ARef.emplace_back(Arg);
+    Child.insert({"Command", I.Name});
+    Child.insert({"Args", ArgsArr});
+    Child.insert({"Children", ChildArr});
+    Obj.insert({commentKindToString(I.Kind), ChildVal});
+    return Obj;
+  }
+
+  case CommentKind::CK_ParamCommandComment:
+  case CommentKind::CK_TParamCommandComment: {
+    Child.insert({"ParamName", I.ParamName});
+    Child.insert({"Direction", I.Direction});
+    Child.insert({"Explicit", I.Explicit});
+    Child.insert({"Children", ChildArr});
+    Obj.insert({commentKindToString(I.Kind), ChildVal});
+    return Obj;
+  }
+
+  case CommentKind::CK_VerbatimBlockComment: {
+    Child.insert({"Text", I.Text});
+    if (!I.CloseName.empty())
+      Child.insert({"CloseName", I.CloseName});
+    Child.insert({"Children", ChildArr});
+    Obj.insert({commentKindToString(I.Kind), ChildVal});
+    return Obj;
+  }
+
+  case CommentKind::CK_VerbatimBlockLineComment:
+  case CommentKind::CK_VerbatimLineComment: {
+    Child.insert({"Text", I.Text});
+    Child.insert({"Children", ChildArr});
+    Obj.insert({commentKindToString(I.Kind), ChildVal});
+    return Obj;
+  }
+
+  case CommentKind::CK_HTMLStartTagComment: {
+    json::Value AttrKeysArray = json::Array();
+    json::Value AttrValuesArray = json::Array();
+    auto &KeyArr = *AttrKeysArray.getAsArray();
+    auto &ValArr = *AttrValuesArray.getAsArray();
+    KeyArr.reserve(I.AttrKeys.size());
+    ValArr.reserve(I.AttrValues.size());
+    for (const auto &K : I.AttrKeys)
+      KeyArr.emplace_back(K);
+    for (const auto &V : I.AttrValues)
+      ValArr.emplace_back(V);
+    Child.insert({"Name", I.Name});
+    Child.insert({"SelfClosing", I.SelfClosing});
+    Child.insert({"AttrKeys", AttrKeysArray});
+    Child.insert({"AttrValues", AttrValuesArray});
+    Child.insert({"Children", ChildArr});
+    Obj.insert({commentKindToString(I.Kind), ChildVal});
+    return Obj;
+  }
+
+  case CommentKind::CK_HTMLEndTagComment: {
+    Child.insert({"Name", I.Name});
+    Child.insert({"Children", ChildArr});
+    Obj.insert({commentKindToString(I.Kind), ChildVal});
+    return Obj;
+  }
+
+  case CommentKind::CK_FullComment:
+  case CommentKind::CK_ParagraphComment: {
+    Child.insert({"Children", ChildArr});
+    Obj.insert({commentKindToString(I.Kind), ChildVal});
+    return Obj;
+  }
+
+  case CommentKind::CK_Unknown: {
+    Obj.insert({commentKindToString(I.Kind), I.Text});
+    return Obj;
+  }
+  }
+  llvm_unreachable("Unknown comment kind encountered.");
 }
 
 static void maybeInsertLocation(std::optional<Location> Loc,
@@ -255,6 +328,7 @@ static void 
extractDescriptionFromInfo(ArrayRef<CommentInfo> Descriptions,
     return;
   json::Value DescArr = Array();
   json::Array &DescARef = *DescArr.getAsArray();
+  DescARef.reserve(Descriptions.size());
   for (const CommentInfo &Child : Descriptions)
     DescARef.emplace_back(extractValue(Child));
   EnumValObj.insert({"EnumValueComments", DescArr});
@@ -270,6 +344,7 @@ static json::Value extractValue(const FunctionInfo &I, 
StringRef ParentInfoDir,
 
   json::Value ParamArr = Array();
   json::Array &ParamARef = *ParamArr.getAsArray();
+  ParamARef.reserve(I.Params.size());
   for (const auto Val : enumerate(I.Params)) {
     json::Value V = Object();
     auto &VRef = *V.getAsObject();
@@ -297,6 +372,7 @@ static json::Value extractValue(const EnumInfo &I,
   Obj.insert({"ID", toHex(toStringRef(I.USR))});
   json::Value EnumArr = Array();
   json::Array &EnumARef = *EnumArr.getAsArray();
+  EnumARef.reserve(I.Members.size());
   for (const EnumValueInfo &M : I.Members) {
     json::Value EnumValue = Object();
     auto &EnumValObj = *EnumValue.getAsObject();
@@ -322,6 +398,7 @@ static void extractScopeChildren(const ScopeChildren &S, 
Object &Obj,
                                  const ClangDocContext &CDCtx) {
   json::Value NamespaceArr = Array();
   json::Array &NamespaceARef = *NamespaceArr.getAsArray();
+  NamespaceARef.reserve(S.Namespaces.size());
   for (const Reference &Child : S.Namespaces)
     NamespaceARef.emplace_back(extractValue(Child, ParentInfoDir));
 
@@ -330,6 +407,7 @@ static void extractScopeChildren(const ScopeChildren &S, 
Object &Obj,
 
   json::Value RecordArr = Array();
   json::Array &RecordARef = *RecordArr.getAsArray();
+  RecordARef.reserve(S.Records.size());
   for (const Reference &Child : S.Records)
     RecordARef.emplace_back(extractValue(Child, ParentInfoDir));
 
@@ -338,12 +416,15 @@ static void extractScopeChildren(const ScopeChildren &S, 
Object &Obj,
 
   json::Value FunctionArr = Array();
   json::Array &FunctionARef = *FunctionArr.getAsArray();
+  FunctionARef.reserve(S.Functions.size());
 
   json::Value PublicFunctionArr = Array();
   json::Array &PublicFunctionARef = *PublicFunctionArr.getAsArray();
+  PublicFunctionARef.reserve(S.Functions.size());
 
   json::Value ProtectedFunctionArr = Array();
   json::Array &ProtectedFunctionARef = *ProtectedFunctionArr.getAsArray();
+  ProtectedFunctionARef.reserve(S.Functions.size());
 
   for (const FunctionInfo &Child : S.Functions) {
     json::Value F = extractValue(Child, ParentInfoDir, CDCtx);
@@ -367,6 +448,7 @@ static void extractScopeChildren(const ScopeChildren &S, 
Object &Obj,
 
   json::Value EnumArr = Array();
   auto &EnumARef = *EnumArr.getAsArray();
+  EnumARef.reserve(S.Enums.size());
   for (const EnumInfo &Child : S.Enums)
     EnumARef.emplace_back(extractValue(Child, CDCtx));
 
@@ -375,6 +457,7 @@ static void extractScopeChildren(const ScopeChildren &S, 
Object &Obj,
 
   json::Value TypedefArr = Array();
   auto &TypedefARef = *TypedefArr.getAsArray();
+  TypedefARef.reserve(S.Typedefs.size());
   for (const TypedefInfo &Child : S.Typedefs)
     TypedefARef.emplace_back(extractValue(Child));
 
@@ -411,10 +494,13 @@ static json::Value extractValue(const RecordInfo &I,
   extractScopeChildren(I.Children, RecordValue, BasePath, CDCtx);
   json::Value PublicMembers = Array();
   json::Array &PubMemberRef = *PublicMembers.getAsArray();
+  PubMemberRef.reserve(I.Members.size());
   json::Value ProtectedMembers = Array();
   json::Array &ProtMemberRef = *ProtectedMembers.getAsArray();
+  ProtMemberRef.reserve(I.Members.size());
   json::Value PrivateMembers = Array();
   json::Array &PrivMemberRef = *PrivateMembers.getAsArray();
+  PrivMemberRef.reserve(I.Members.size());
   for (const MemberTypeInfo &Member : I.Members) {
     json::Value MemberValue = Object();
     auto &MVRef = *MemberValue.getAsObject();
@@ -446,20 +532,25 @@ static Error setupTemplateValue(const ClangDocContext 
&CDCtx, json::Value &V,
   auto InfoPath = I->getRelativeFilePath("");
   SmallString<128> RelativePath = computeRelativePath("", InfoPath);
   sys::path::native(RelativePath, sys::path::Style::posix);
+
+  auto *SSA = StylesheetArr.getAsArray();
+  SSA->reserve(CDCtx.UserStylesheets.size());
   for (const auto &FilePath : CDCtx.UserStylesheets) {
     SmallString<128> StylesheetPath = RelativePath;
     sys::path::append(StylesheetPath, sys::path::Style::posix,
                       sys::path::filename(FilePath));
-    StylesheetArr.getAsArray()->emplace_back(StylesheetPath);
+    SSA->emplace_back(StylesheetPath);
   }
   V.getAsObject()->insert({"Stylesheets", StylesheetArr});
 
   json::Value ScriptArr = Array();
+  auto *SCA = ScriptArr.getAsArray();
+  SCA->reserve(CDCtx.JsScripts.size());
   for (auto Script : CDCtx.JsScripts) {
     SmallString<128> JsPath = RelativePath;
     sys::path::append(JsPath, sys::path::Style::posix,
                       sys::path::filename(Script));
-    ScriptArr.getAsArray()->emplace_back(JsPath);
+    SCA->emplace_back(JsPath);
   }
   V.getAsObject()->insert({"Scripts", ScriptArr});
   return Error::success();

diff  --git a/clang-tools-extra/clang-doc/MDGenerator.cpp 
b/clang-tools-extra/clang-doc/MDGenerator.cpp
index ccd6175c96cb8..2becccf8b07da 100644
--- a/clang-tools-extra/clang-doc/MDGenerator.cpp
+++ b/clang-tools-extra/clang-doc/MDGenerator.cpp
@@ -75,39 +75,49 @@ static void maybeWriteSourceFileRef(llvm::raw_ostream &OS,
 }
 
 static void writeDescription(const CommentInfo &I, raw_ostream &OS) {
-  if (I.Kind == "FullComment") {
+  switch (I.Kind) {
+  case CommentKind::CK_FullComment:
     for (const auto &Child : I.Children)
       writeDescription(*Child, OS);
-  } else if (I.Kind == "ParagraphComment") {
+    break;
+
+  case CommentKind::CK_ParagraphComment:
     for (const auto &Child : I.Children)
       writeDescription(*Child, OS);
     writeNewLine(OS);
-  } else if (I.Kind == "BlockCommandComment") {
+    break;
+
+  case CommentKind::CK_BlockCommandComment:
     OS << genEmphasis(I.Name);
     for (const auto &Child : I.Children)
       writeDescription(*Child, OS);
-  } else if (I.Kind == "InlineCommandComment") {
+    break;
+
+  case CommentKind::CK_InlineCommandComment:
     OS << genEmphasis(I.Name) << " " << I.Text;
-  } else if (I.Kind == "ParamCommandComment") {
-    std::string Direction = I.Explicit ? (" " + I.Direction).str() : "";
-    OS << genEmphasis(I.ParamName) << I.Text << Direction;
-    for (const auto &Child : I.Children)
-      writeDescription(*Child, OS);
-  } else if (I.Kind == "TParamCommandComment") {
+    break;
+
+  case CommentKind::CK_ParamCommandComment:
+  case CommentKind::CK_TParamCommandComment: {
     std::string Direction = I.Explicit ? (" " + I.Direction).str() : "";
     OS << genEmphasis(I.ParamName) << I.Text << Direction;
     for (const auto &Child : I.Children)
       writeDescription(*Child, OS);
-  } else if (I.Kind == "VerbatimBlockComment") {
+    break;
+  }
+
+  case CommentKind::CK_VerbatimBlockComment:
     for (const auto &Child : I.Children)
       writeDescription(*Child, OS);
-  } else if (I.Kind == "VerbatimBlockLineComment") {
-    OS << I.Text;
-    writeNewLine(OS);
-  } else if (I.Kind == "VerbatimLineComment") {
+    break;
+
+  case CommentKind::CK_VerbatimBlockLineComment:
+  case CommentKind::CK_VerbatimLineComment:
     OS << I.Text;
     writeNewLine(OS);
-  } else if (I.Kind == "HTMLStartTagComment") {
+    break;
+
+  case CommentKind::CK_HTMLStartTagComment: {
     if (I.AttrKeys.size() != I.AttrValues.size())
       return;
     std::string Buffer;
@@ -117,12 +127,20 @@ static void writeDescription(const CommentInfo &I, 
raw_ostream &OS) {
 
     std::string CloseTag = I.SelfClosing ? "/>" : ">";
     writeLine("<" + I.Name + Attrs.str() + CloseTag, OS);
-  } else if (I.Kind == "HTMLEndTagComment") {
+    break;
+  }
+
+  case CommentKind::CK_HTMLEndTagComment:
     writeLine("</" + I.Name + ">", OS);
-  } else if (I.Kind == "TextComment") {
+    break;
+
+  case CommentKind::CK_TextComment:
     OS << I.Text;
-  } else {
-    OS << "Unknown comment kind: " << I.Kind << ".\n\n";
+    break;
+
+  case CommentKind::CK_Unknown:
+    OS << "Unknown comment kind: " << static_cast<int>(I.Kind) << ".\n\n";
+    break;
   }
 }
 

diff  --git a/clang-tools-extra/clang-doc/Representation.cpp 
b/clang-tools-extra/clang-doc/Representation.cpp
index ad93ed66b86a1..3ce930c6965db 100644
--- a/clang-tools-extra/clang-doc/Representation.cpp
+++ b/clang-tools-extra/clang-doc/Representation.cpp
@@ -20,12 +20,68 @@
 //
 
//===----------------------------------------------------------------------===//
 #include "Representation.h"
+#include "llvm/ADT/StringMap.h"
 #include "llvm/Support/Error.h"
 #include "llvm/Support/Path.h"
 
 namespace clang {
 namespace doc {
 
+CommentKind stringToCommentKind(llvm::StringRef KindStr) {
+  static const llvm::StringMap<CommentKind> KindMap = {
+      {"FullComment", CommentKind::CK_FullComment},
+      {"ParagraphComment", CommentKind::CK_ParagraphComment},
+      {"TextComment", CommentKind::CK_TextComment},
+      {"InlineCommandComment", CommentKind::CK_InlineCommandComment},
+      {"HTMLStartTagComment", CommentKind::CK_HTMLStartTagComment},
+      {"HTMLEndTagComment", CommentKind::CK_HTMLEndTagComment},
+      {"BlockCommandComment", CommentKind::CK_BlockCommandComment},
+      {"ParamCommandComment", CommentKind::CK_ParamCommandComment},
+      {"TParamCommandComment", CommentKind::CK_TParamCommandComment},
+      {"VerbatimBlockComment", CommentKind::CK_VerbatimBlockComment},
+      {"VerbatimBlockLineComment", CommentKind::CK_VerbatimBlockLineComment},
+      {"VerbatimLineComment", CommentKind::CK_VerbatimLineComment},
+  };
+
+  auto It = KindMap.find(KindStr);
+  if (It != KindMap.end()) {
+    return It->second;
+  }
+  return CommentKind::CK_Unknown;
+}
+
+llvm::StringRef commentKindToString(CommentKind Kind) {
+  switch (Kind) {
+  case CommentKind::CK_FullComment:
+    return "FullComment";
+  case CommentKind::CK_ParagraphComment:
+    return "ParagraphComment";
+  case CommentKind::CK_TextComment:
+    return "TextComment";
+  case CommentKind::CK_InlineCommandComment:
+    return "InlineCommandComment";
+  case CommentKind::CK_HTMLStartTagComment:
+    return "HTMLStartTagComment";
+  case CommentKind::CK_HTMLEndTagComment:
+    return "HTMLEndTagComment";
+  case CommentKind::CK_BlockCommandComment:
+    return "BlockCommandComment";
+  case CommentKind::CK_ParamCommandComment:
+    return "ParamCommandComment";
+  case CommentKind::CK_TParamCommandComment:
+    return "TParamCommandComment";
+  case CommentKind::CK_VerbatimBlockComment:
+    return "VerbatimBlockComment";
+  case CommentKind::CK_VerbatimBlockLineComment:
+    return "VerbatimBlockLineComment";
+  case CommentKind::CK_VerbatimLineComment:
+    return "VerbatimLineComment";
+  case CommentKind::CK_Unknown:
+    return "Unknown";
+  }
+  llvm_unreachable("Unhandled CommentKind");
+}
+
 namespace {
 
 const SymbolID EmptySID = SymbolID();

diff  --git a/clang-tools-extra/clang-doc/Representation.h 
b/clang-tools-extra/clang-doc/Representation.h
index 0dbf73452fed6..75da500645819 100644
--- a/clang-tools-extra/clang-doc/Representation.h
+++ b/clang-tools-extra/clang-doc/Representation.h
@@ -45,6 +45,25 @@ enum class InfoType {
   IT_typedef
 };
 
+enum class CommentKind {
+  CK_FullComment,
+  CK_ParagraphComment,
+  CK_TextComment,
+  CK_InlineCommandComment,
+  CK_HTMLStartTagComment,
+  CK_HTMLEndTagComment,
+  CK_BlockCommandComment,
+  CK_ParamCommandComment,
+  CK_TParamCommandComment,
+  CK_VerbatimBlockComment,
+  CK_VerbatimBlockLineComment,
+  CK_VerbatimLineComment,
+  CK_Unknown
+};
+
+CommentKind stringToCommentKind(llvm::StringRef KindStr);
+llvm::StringRef commentKindToString(CommentKind Kind);
+
 // A representation of a parsed comment.
 struct CommentInfo {
   CommentInfo() = default;
@@ -60,13 +79,13 @@ struct CommentInfo {
   // the vector.
   bool operator<(const CommentInfo &Other) const;
 
-  // TODO: The Kind field should be an enum, so we can switch on it easily.
-  SmallString<16>
-      Kind; // Kind of comment (FullComment, ParagraphComment, TextComment,
-            // InlineCommandComment, HTMLStartTagComment, HTMLEndTagComment,
-            // BlockCommandComment, ParamCommandComment,
-            // TParamCommandComment, VerbatimBlockComment,
-            // VerbatimBlockLineComment, VerbatimLineComment).
+  CommentKind Kind = CommentKind::
+      CK_Unknown; // Kind of comment (FullComment, ParagraphComment,
+                  // TextComment, InlineCommandComment, HTMLStartTagComment,
+                  // HTMLEndTagComment, BlockCommandComment,
+                  // ParamCommandComment, TParamCommandComment,
+                  // VerbatimBlockComment, VerbatimBlockLineComment,
+                  // VerbatimLineComment).
   SmallString<64> Text;      // Text of the comment.
   SmallString<16> Name;      // Name of the comment (for Verbatim and HTML).
   SmallString<8> Direction;  // Parameter direction (for (T)ParamCommand).

diff  --git a/clang-tools-extra/clang-doc/Serialize.cpp 
b/clang-tools-extra/clang-doc/Serialize.cpp
index 3932a939de973..462001b3f3027 100644
--- a/clang-tools-extra/clang-doc/Serialize.cpp
+++ b/clang-tools-extra/clang-doc/Serialize.cpp
@@ -270,7 +270,7 @@ class ClangDocCommentVisitor
 };
 
 void ClangDocCommentVisitor::parseComment(const comments::Comment *C) {
-  CurrentCI.Kind = C->getCommentKindName();
+  CurrentCI.Kind = stringToCommentKind(C->getCommentKindName());
   ConstCommentVisitor<ClangDocCommentVisitor>::visit(C);
   for (comments::Comment *Child :
        llvm::make_range(C->child_begin(), C->child_end())) {

diff  --git a/clang-tools-extra/clang-doc/YAMLGenerator.cpp 
b/clang-tools-extra/clang-doc/YAMLGenerator.cpp
index 8c110b34e8e20..897b5d5ae4c98 100644
--- a/clang-tools-extra/clang-doc/YAMLGenerator.cpp
+++ b/clang-tools-extra/clang-doc/YAMLGenerator.cpp
@@ -65,6 +65,34 @@ template <> struct ScalarEnumerationTraits<InfoType> {
   }
 };
 
+template <> struct ScalarEnumerationTraits<clang::doc::CommentKind> {
+  static void enumeration(IO &IO, clang::doc::CommentKind &Value) {
+    IO.enumCase(Value, "FullComment", clang::doc::CommentKind::CK_FullComment);
+    IO.enumCase(Value, "ParagraphComment",
+                clang::doc::CommentKind::CK_ParagraphComment);
+    IO.enumCase(Value, "TextComment", clang::doc::CommentKind::CK_TextComment);
+    IO.enumCase(Value, "InlineCommandComment",
+                clang::doc::CommentKind::CK_InlineCommandComment);
+    IO.enumCase(Value, "HTMLStartTagComment",
+                clang::doc::CommentKind::CK_HTMLStartTagComment);
+    IO.enumCase(Value, "HTMLEndTagComment",
+                clang::doc::CommentKind::CK_HTMLEndTagComment);
+    IO.enumCase(Value, "BlockCommandComment",
+                clang::doc::CommentKind::CK_BlockCommandComment);
+    IO.enumCase(Value, "ParamCommandComment",
+                clang::doc::CommentKind::CK_ParamCommandComment);
+    IO.enumCase(Value, "TParamCommandComment",
+                clang::doc::CommentKind::CK_TParamCommandComment);
+    IO.enumCase(Value, "VerbatimBlockComment",
+                clang::doc::CommentKind::CK_VerbatimBlockComment);
+    IO.enumCase(Value, "VerbatimBlockLineComment",
+                clang::doc::CommentKind::CK_VerbatimBlockLineComment);
+    IO.enumCase(Value, "VerbatimLineComment",
+                clang::doc::CommentKind::CK_VerbatimLineComment);
+    IO.enumCase(Value, "Unknown", clang::doc::CommentKind::CK_Unknown);
+  }
+};
+
 // Scalars to YAML output.
 template <unsigned U> struct ScalarTraits<SmallString<U>> {
 
@@ -149,7 +177,7 @@ static void recordInfoMapping(IO &IO, RecordInfo &I) {
 }
 
 static void commentInfoMapping(IO &IO, CommentInfo &I) {
-  IO.mapOptional("Kind", I.Kind, SmallString<16>());
+  IO.mapOptional("Kind", I.Kind, CommentKind::CK_Unknown);
   IO.mapOptional("Text", I.Text, SmallString<64>());
   IO.mapOptional("Name", I.Name, SmallString<16>());
   IO.mapOptional("Direction", I.Direction, SmallString<8>());

diff  --git a/clang-tools-extra/test/clang-doc/templates.cpp 
b/clang-tools-extra/test/clang-doc/templates.cpp
index 426a0b16befd4..abe03a7d2d0ea 100644
--- a/clang-tools-extra/test/clang-doc/templates.cpp
+++ b/clang-tools-extra/test/clang-doc/templates.cpp
@@ -112,22 +112,22 @@ tuple<int, int, bool> func_with_tuple_param(tuple<int, 
int, bool> t) { return t;
 // YAML-NEXT:   - USR:             '{{([0-9A-F]{40})}}'
 // YAML-NEXT:    Name:            'func_with_tuple_param'
 // YAML-NEXT:    Description:
-// YAML-NEXT:      - Kind:            'FullComment'
+// YAML-NEXT:      - Kind:            FullComment
 // YAML-NEXT:        Children:
-// YAML-NEXT:          - Kind:            'ParagraphComment'
+// YAML-NEXT:          - Kind:            ParagraphComment
 // YAML-NEXT:            Children:
-// YAML-NEXT:              - Kind:            'TextComment'
+// YAML-NEXT:              - Kind:            TextComment
 // YAML-NEXT:                Text:            ' A function with a tuple 
parameter'
-// YAML-NEXT:          - Kind:            'ParagraphComment'
+// YAML-NEXT:          - Kind:            ParagraphComment
 // YAML-NEXT:            Children:
-// YAML-NEXT:              - Kind:            'TextComment'
-// YAML-NEXT:          - Kind:            'ParamCommandComment'
+// YAML-NEXT:              - Kind:            TextComment
+// YAML-NEXT:          - Kind:            ParamCommandComment
 // YAML-NEXT:            Direction:       '[in]'
 // YAML-NEXT:            ParamName:       't'
 // YAML-NEXT:            Children:
-// YAML-NEXT:              - Kind:            'ParagraphComment'
+// YAML-NEXT:              - Kind:            ParagraphComment
 // YAML-NEXT:                Children:
-// YAML-NEXT:                  - Kind:            'TextComment'
+// YAML-NEXT:                  - Kind:            TextComment
 // YAML-NEXT:                    Text:            ' The input to 
func_with_tuple_param'
 // YAML-NEXT:    DefLocation:
 // YAML-NEXT:      LineNumber:      [[# @LINE - 23]]

diff  --git a/clang-tools-extra/unittests/clang-doc/BitcodeTest.cpp 
b/clang-tools-extra/unittests/clang-doc/BitcodeTest.cpp
index 4f2466af9a6bd..bbe158ed50e28 100644
--- a/clang-tools-extra/unittests/clang-doc/BitcodeTest.cpp
+++ b/clang-tools-extra/unittests/clang-doc/BitcodeTest.cpp
@@ -93,12 +93,12 @@ TEST(BitcodeTest, emitRecordInfoBitcode) {
 
   // Documentation for the data member.
   CommentInfo TopComment;
-  TopComment.Kind = "FullComment";
+  TopComment.Kind = CommentKind::CK_FullComment;
   TopComment.Children.emplace_back(std::make_unique<CommentInfo>());
   CommentInfo *Brief = TopComment.Children.back().get();
-  Brief->Kind = "ParagraphComment";
+  Brief->Kind = CommentKind::CK_ParagraphComment;
   Brief->Children.emplace_back(std::make_unique<CommentInfo>());
-  Brief->Children.back()->Kind = "TextComment";
+  Brief->Children.back()->Kind = CommentKind::CK_TextComment;
   Brief->Children.back()->Name = "ParagraphComment";
   Brief->Children.back()->Text = "Value of the thing.";
   
I.Bases.back().Members.back().Description.emplace_back(std::move(TopComment));
@@ -184,13 +184,13 @@ TEST(BitcodeTest, emitTypedefInfoBitcode) {
   I.IsUsing = true;
 
   CommentInfo Top;
-  Top.Kind = "FullComment";
+  Top.Kind = CommentKind::CK_FullComment;
 
   Top.Children.emplace_back(std::make_unique<CommentInfo>());
   CommentInfo *BlankLine = Top.Children.back().get();
-  BlankLine->Kind = "ParagraphComment";
+  BlankLine->Kind = CommentKind::CK_ParagraphComment;
   BlankLine->Children.emplace_back(std::make_unique<CommentInfo>());
-  BlankLine->Children.back()->Kind = "TextComment";
+  BlankLine->Children.back()->Kind = CommentKind::CK_TextComment;
 
   I.Description.emplace_back(std::move(Top));
 
@@ -220,103 +220,105 @@ TEST(SerializeTest, emitInfoWithCommentBitcode) {
   F.Params.emplace_back(TypeInfo("int"), "I");
 
   CommentInfo Top;
-  Top.Kind = "FullComment";
+  Top.Kind = CommentKind::CK_FullComment;
 
   Top.Children.emplace_back(std::make_unique<CommentInfo>());
   CommentInfo *BlankLine = Top.Children.back().get();
-  BlankLine->Kind = "ParagraphComment";
+  BlankLine->Kind = CommentKind::CK_ParagraphComment;
   BlankLine->Children.emplace_back(std::make_unique<CommentInfo>());
-  BlankLine->Children.back()->Kind = "TextComment";
+  BlankLine->Children.back()->Kind = CommentKind::CK_TextComment;
 
   Top.Children.emplace_back(std::make_unique<CommentInfo>());
   CommentInfo *Brief = Top.Children.back().get();
-  Brief->Kind = "ParagraphComment";
+  Brief->Kind = CommentKind::CK_ParagraphComment;
   Brief->Children.emplace_back(std::make_unique<CommentInfo>());
-  Brief->Children.back()->Kind = "TextComment";
+  Brief->Children.back()->Kind = CommentKind::CK_TextComment;
   Brief->Children.back()->Name = "ParagraphComment";
   Brief->Children.back()->Text = " Brief description.";
 
   Top.Children.emplace_back(std::make_unique<CommentInfo>());
   CommentInfo *Extended = Top.Children.back().get();
-  Extended->Kind = "ParagraphComment";
+  Extended->Kind = CommentKind::CK_ParagraphComment;
   Extended->Children.emplace_back(std::make_unique<CommentInfo>());
-  Extended->Children.back()->Kind = "TextComment";
+  Extended->Children.back()->Kind = CommentKind::CK_TextComment;
   Extended->Children.back()->Text = " Extended description that";
   Extended->Children.emplace_back(std::make_unique<CommentInfo>());
-  Extended->Children.back()->Kind = "TextComment";
+  Extended->Children.back()->Kind = CommentKind::CK_TextComment;
   Extended->Children.back()->Text = " continues onto the next line.";
 
   Top.Children.emplace_back(std::make_unique<CommentInfo>());
   CommentInfo *HTML = Top.Children.back().get();
-  HTML->Kind = "ParagraphComment";
+  HTML->Kind = CommentKind::CK_ParagraphComment;
   HTML->Children.emplace_back(std::make_unique<CommentInfo>());
-  HTML->Children.back()->Kind = "TextComment";
+  HTML->Children.back()->Kind = CommentKind::CK_TextComment;
   HTML->Children.emplace_back(std::make_unique<CommentInfo>());
-  HTML->Children.back()->Kind = "HTMLStartTagComment";
+  HTML->Children.back()->Kind = CommentKind::CK_HTMLStartTagComment;
   HTML->Children.back()->Name = "ul";
   HTML->Children.back()->AttrKeys.emplace_back("class");
   HTML->Children.back()->AttrValues.emplace_back("test");
   HTML->Children.emplace_back(std::make_unique<CommentInfo>());
-  HTML->Children.back()->Kind = "HTMLStartTagComment";
+  HTML->Children.back()->Kind = CommentKind::CK_HTMLStartTagComment;
   HTML->Children.back()->Name = "li";
   HTML->Children.emplace_back(std::make_unique<CommentInfo>());
-  HTML->Children.back()->Kind = "TextComment";
+  HTML->Children.back()->Kind = CommentKind::CK_TextComment;
   HTML->Children.back()->Text = " Testing.";
   HTML->Children.emplace_back(std::make_unique<CommentInfo>());
-  HTML->Children.back()->Kind = "HTMLEndTagComment";
+  HTML->Children.back()->Kind = CommentKind::CK_HTMLEndTagComment;
   HTML->Children.back()->Name = "ul";
   HTML->Children.back()->SelfClosing = true;
 
   Top.Children.emplace_back(std::make_unique<CommentInfo>());
   CommentInfo *Verbatim = Top.Children.back().get();
-  Verbatim->Kind = "VerbatimBlockComment";
+  Verbatim->Kind = CommentKind::CK_VerbatimBlockComment;
   Verbatim->Name = "verbatim";
   Verbatim->CloseName = "endverbatim";
   Verbatim->Children.emplace_back(std::make_unique<CommentInfo>());
-  Verbatim->Children.back()->Kind = "VerbatimBlockLineComment";
+  Verbatim->Children.back()->Kind = CommentKind::CK_VerbatimBlockLineComment;
   Verbatim->Children.back()->Text = " The description continues.";
 
   Top.Children.emplace_back(std::make_unique<CommentInfo>());
   CommentInfo *ParamOut = Top.Children.back().get();
-  ParamOut->Kind = "ParamCommandComment";
+  ParamOut->Kind = CommentKind::CK_ParamCommandComment;
   ParamOut->Direction = "[out]";
   ParamOut->ParamName = "I";
   ParamOut->Explicit = true;
   ParamOut->Children.emplace_back(std::make_unique<CommentInfo>());
-  ParamOut->Children.back()->Kind = "ParagraphComment";
+  ParamOut->Children.back()->Kind = CommentKind::CK_ParagraphComment;
   ParamOut->Children.back()->Children.emplace_back(
       std::make_unique<CommentInfo>());
-  ParamOut->Children.back()->Children.back()->Kind = "TextComment";
+  ParamOut->Children.back()->Children.back()->Kind =
+      CommentKind::CK_TextComment;
   ParamOut->Children.back()->Children.emplace_back(
       std::make_unique<CommentInfo>());
-  ParamOut->Children.back()->Children.back()->Kind = "TextComment";
+  ParamOut->Children.back()->Children.back()->Kind =
+      CommentKind::CK_TextComment;
   ParamOut->Children.back()->Children.back()->Text = " is a parameter.";
 
   Top.Children.emplace_back(std::make_unique<CommentInfo>());
   CommentInfo *ParamIn = Top.Children.back().get();
-  ParamIn->Kind = "ParamCommandComment";
+  ParamIn->Kind = CommentKind::CK_ParamCommandComment;
   ParamIn->Direction = "[in]";
   ParamIn->ParamName = "J";
   ParamIn->Children.emplace_back(std::make_unique<CommentInfo>());
-  ParamIn->Children.back()->Kind = "ParagraphComment";
+  ParamIn->Children.back()->Kind = CommentKind::CK_ParagraphComment;
   ParamIn->Children.back()->Children.emplace_back(
       std::make_unique<CommentInfo>());
-  ParamIn->Children.back()->Children.back()->Kind = "TextComment";
+  ParamIn->Children.back()->Children.back()->Kind = 
CommentKind::CK_TextComment;
   ParamIn->Children.back()->Children.back()->Text = " is a parameter.";
   ParamIn->Children.back()->Children.emplace_back(
       std::make_unique<CommentInfo>());
-  ParamIn->Children.back()->Children.back()->Kind = "TextComment";
+  ParamIn->Children.back()->Children.back()->Kind = 
CommentKind::CK_TextComment;
 
   Top.Children.emplace_back(std::make_unique<CommentInfo>());
   CommentInfo *Return = Top.Children.back().get();
-  Return->Kind = "BlockCommandComment";
+  Return->Kind = CommentKind::CK_BlockCommandComment;
   Return->Name = "return";
   Return->Explicit = true;
   Return->Children.emplace_back(std::make_unique<CommentInfo>());
-  Return->Children.back()->Kind = "ParagraphComment";
+  Return->Children.back()->Kind = CommentKind::CK_ParagraphComment;
   Return->Children.back()->Children.emplace_back(
       std::make_unique<CommentInfo>());
-  Return->Children.back()->Children.back()->Kind = "TextComment";
+  Return->Children.back()->Children.back()->Kind = CommentKind::CK_TextComment;
   Return->Children.back()->Children.back()->Text = "void";
 
   F.Description.emplace_back(std::move(Top));

diff  --git a/clang-tools-extra/unittests/clang-doc/HTMLGeneratorTest.cpp 
b/clang-tools-extra/unittests/clang-doc/HTMLGeneratorTest.cpp
index edf502475b511..143414354d36c 100644
--- a/clang-tools-extra/unittests/clang-doc/HTMLGeneratorTest.cpp
+++ b/clang-tools-extra/unittests/clang-doc/HTMLGeneratorTest.cpp
@@ -407,37 +407,37 @@ TEST(HTMLGeneratorTest, emitCommentHTML) {
   I.Access = AccessSpecifier::AS_none;
 
   CommentInfo Top;
-  Top.Kind = "FullComment";
+  Top.Kind = CommentKind::CK_FullComment;
 
   Top.Children.emplace_back(std::make_unique<CommentInfo>());
   CommentInfo *BlankLine = Top.Children.back().get();
-  BlankLine->Kind = "ParagraphComment";
+  BlankLine->Kind = CommentKind::CK_ParagraphComment;
   BlankLine->Children.emplace_back(std::make_unique<CommentInfo>());
-  BlankLine->Children.back()->Kind = "TextComment";
+  BlankLine->Children.back()->Kind = CommentKind::CK_TextComment;
 
   Top.Children.emplace_back(std::make_unique<CommentInfo>());
   CommentInfo *Brief = Top.Children.back().get();
-  Brief->Kind = "ParagraphComment";
+  Brief->Kind = CommentKind::CK_ParagraphComment;
   Brief->Children.emplace_back(std::make_unique<CommentInfo>());
-  Brief->Children.back()->Kind = "TextComment";
+  Brief->Children.back()->Kind = CommentKind::CK_TextComment;
   Brief->Children.back()->Name = "ParagraphComment";
   Brief->Children.back()->Text = " Brief description.";
 
   Top.Children.emplace_back(std::make_unique<CommentInfo>());
   CommentInfo *Extended = Top.Children.back().get();
-  Extended->Kind = "ParagraphComment";
+  Extended->Kind = CommentKind::CK_ParagraphComment;
   Extended->Children.emplace_back(std::make_unique<CommentInfo>());
-  Extended->Children.back()->Kind = "TextComment";
+  Extended->Children.back()->Kind = CommentKind::CK_TextComment;
   Extended->Children.back()->Text = " Extended description that";
   Extended->Children.emplace_back(std::make_unique<CommentInfo>());
-  Extended->Children.back()->Kind = "TextComment";
+  Extended->Children.back()->Kind = CommentKind::CK_TextComment;
   Extended->Children.back()->Text = " continues onto the next line.";
 
   Top.Children.emplace_back(std::make_unique<CommentInfo>());
   CommentInfo *Entities = Top.Children.back().get();
-  Entities->Kind = "ParagraphComment";
+  Entities->Kind = CommentKind::CK_ParagraphComment;
   Entities->Children.emplace_back(std::make_unique<CommentInfo>());
-  Entities->Children.back()->Kind = "TextComment";
+  Entities->Children.back()->Kind = CommentKind::CK_TextComment;
   Entities->Children.back()->Name = "ParagraphComment";
   Entities->Children.back()->Text =
       " Comment with html entities: &, <, >, \", \'.";

diff  --git a/clang-tools-extra/unittests/clang-doc/MDGeneratorTest.cpp 
b/clang-tools-extra/unittests/clang-doc/MDGeneratorTest.cpp
index 1795ef5a46c3a..f4c69cf868a1f 100644
--- a/clang-tools-extra/unittests/clang-doc/MDGeneratorTest.cpp
+++ b/clang-tools-extra/unittests/clang-doc/MDGeneratorTest.cpp
@@ -218,103 +218,105 @@ TEST(MDGeneratorTest, emitCommentMD) {
   I.Access = AccessSpecifier::AS_none;
 
   CommentInfo Top;
-  Top.Kind = "FullComment";
+  Top.Kind = CommentKind::CK_FullComment;
 
   Top.Children.emplace_back(std::make_unique<CommentInfo>());
   CommentInfo *BlankLine = Top.Children.back().get();
-  BlankLine->Kind = "ParagraphComment";
+  BlankLine->Kind = CommentKind::CK_ParagraphComment;
   BlankLine->Children.emplace_back(std::make_unique<CommentInfo>());
-  BlankLine->Children.back()->Kind = "TextComment";
+  BlankLine->Children.back()->Kind = CommentKind::CK_TextComment;
 
   Top.Children.emplace_back(std::make_unique<CommentInfo>());
   CommentInfo *Brief = Top.Children.back().get();
-  Brief->Kind = "ParagraphComment";
+  Brief->Kind = CommentKind::CK_ParagraphComment;
   Brief->Children.emplace_back(std::make_unique<CommentInfo>());
-  Brief->Children.back()->Kind = "TextComment";
+  Brief->Children.back()->Kind = CommentKind::CK_TextComment;
   Brief->Children.back()->Name = "ParagraphComment";
   Brief->Children.back()->Text = " Brief description.";
 
   Top.Children.emplace_back(std::make_unique<CommentInfo>());
   CommentInfo *Extended = Top.Children.back().get();
-  Extended->Kind = "ParagraphComment";
+  Extended->Kind = CommentKind::CK_ParagraphComment;
   Extended->Children.emplace_back(std::make_unique<CommentInfo>());
-  Extended->Children.back()->Kind = "TextComment";
+  Extended->Children.back()->Kind = CommentKind::CK_TextComment;
   Extended->Children.back()->Text = " Extended description that";
   Extended->Children.emplace_back(std::make_unique<CommentInfo>());
-  Extended->Children.back()->Kind = "TextComment";
+  Extended->Children.back()->Kind = CommentKind::CK_TextComment;
   Extended->Children.back()->Text = " continues onto the next line.";
 
   Top.Children.emplace_back(std::make_unique<CommentInfo>());
   CommentInfo *HTML = Top.Children.back().get();
-  HTML->Kind = "ParagraphComment";
+  HTML->Kind = CommentKind::CK_ParagraphComment;
   HTML->Children.emplace_back(std::make_unique<CommentInfo>());
-  HTML->Children.back()->Kind = "TextComment";
+  HTML->Children.back()->Kind = CommentKind::CK_TextComment;
   HTML->Children.emplace_back(std::make_unique<CommentInfo>());
-  HTML->Children.back()->Kind = "HTMLStartTagComment";
+  HTML->Children.back()->Kind = CommentKind::CK_HTMLStartTagComment;
   HTML->Children.back()->Name = "ul";
   HTML->Children.back()->AttrKeys.emplace_back("class");
   HTML->Children.back()->AttrValues.emplace_back("test");
   HTML->Children.emplace_back(std::make_unique<CommentInfo>());
-  HTML->Children.back()->Kind = "HTMLStartTagComment";
+  HTML->Children.back()->Kind = CommentKind::CK_HTMLStartTagComment;
   HTML->Children.back()->Name = "li";
   HTML->Children.emplace_back(std::make_unique<CommentInfo>());
-  HTML->Children.back()->Kind = "TextComment";
+  HTML->Children.back()->Kind = CommentKind::CK_TextComment;
   HTML->Children.back()->Text = " Testing.";
   HTML->Children.emplace_back(std::make_unique<CommentInfo>());
-  HTML->Children.back()->Kind = "HTMLEndTagComment";
+  HTML->Children.back()->Kind = CommentKind::CK_HTMLEndTagComment;
   HTML->Children.back()->Name = "ul";
   HTML->Children.back()->SelfClosing = true;
 
   Top.Children.emplace_back(std::make_unique<CommentInfo>());
   CommentInfo *Verbatim = Top.Children.back().get();
-  Verbatim->Kind = "VerbatimBlockComment";
+  Verbatim->Kind = CommentKind::CK_VerbatimBlockComment;
   Verbatim->Name = "verbatim";
   Verbatim->CloseName = "endverbatim";
   Verbatim->Children.emplace_back(std::make_unique<CommentInfo>());
-  Verbatim->Children.back()->Kind = "VerbatimBlockLineComment";
+  Verbatim->Children.back()->Kind = CommentKind::CK_VerbatimBlockLineComment;
   Verbatim->Children.back()->Text = " The description continues.";
 
   Top.Children.emplace_back(std::make_unique<CommentInfo>());
   CommentInfo *ParamOut = Top.Children.back().get();
-  ParamOut->Kind = "ParamCommandComment";
+  ParamOut->Kind = CommentKind::CK_ParamCommandComment;
   ParamOut->Direction = "[out]";
   ParamOut->ParamName = "I";
   ParamOut->Explicit = true;
   ParamOut->Children.emplace_back(std::make_unique<CommentInfo>());
-  ParamOut->Children.back()->Kind = "ParagraphComment";
+  ParamOut->Children.back()->Kind = CommentKind::CK_ParagraphComment;
   ParamOut->Children.back()->Children.emplace_back(
       std::make_unique<CommentInfo>());
-  ParamOut->Children.back()->Children.back()->Kind = "TextComment";
+  ParamOut->Children.back()->Children.back()->Kind =
+      CommentKind::CK_TextComment;
   ParamOut->Children.back()->Children.emplace_back(
       std::make_unique<CommentInfo>());
-  ParamOut->Children.back()->Children.back()->Kind = "TextComment";
+  ParamOut->Children.back()->Children.back()->Kind =
+      CommentKind::CK_TextComment;
   ParamOut->Children.back()->Children.back()->Text = " is a parameter.";
 
   Top.Children.emplace_back(std::make_unique<CommentInfo>());
   CommentInfo *ParamIn = Top.Children.back().get();
-  ParamIn->Kind = "ParamCommandComment";
+  ParamIn->Kind = CommentKind::CK_ParamCommandComment;
   ParamIn->Direction = "[in]";
   ParamIn->ParamName = "J";
   ParamIn->Children.emplace_back(std::make_unique<CommentInfo>());
-  ParamIn->Children.back()->Kind = "ParagraphComment";
+  ParamIn->Children.back()->Kind = CommentKind::CK_ParagraphComment;
   ParamIn->Children.back()->Children.emplace_back(
       std::make_unique<CommentInfo>());
-  ParamIn->Children.back()->Children.back()->Kind = "TextComment";
+  ParamIn->Children.back()->Children.back()->Kind = 
CommentKind::CK_TextComment;
   ParamIn->Children.back()->Children.back()->Text = " is a parameter.";
   ParamIn->Children.back()->Children.emplace_back(
       std::make_unique<CommentInfo>());
-  ParamIn->Children.back()->Children.back()->Kind = "TextComment";
+  ParamIn->Children.back()->Children.back()->Kind = 
CommentKind::CK_TextComment;
 
   Top.Children.emplace_back(std::make_unique<CommentInfo>());
   CommentInfo *Return = Top.Children.back().get();
-  Return->Kind = "BlockCommandComment";
+  Return->Kind = CommentKind::CK_BlockCommandComment;
   Return->Name = "return";
   Return->Explicit = true;
   Return->Children.emplace_back(std::make_unique<CommentInfo>());
-  Return->Children.back()->Kind = "ParagraphComment";
+  Return->Children.back()->Kind = CommentKind::CK_ParagraphComment;
   Return->Children.back()->Children.emplace_back(
       std::make_unique<CommentInfo>());
-  Return->Children.back()->Children.back()->Kind = "TextComment";
+  Return->Children.back()->Children.back()->Kind = CommentKind::CK_TextComment;
   Return->Children.back()->Children.back()->Text = "void";
 
   I.Description.emplace_back(std::move(Top));

diff  --git a/clang-tools-extra/unittests/clang-doc/MergeTest.cpp 
b/clang-tools-extra/unittests/clang-doc/MergeTest.cpp
index f99748fdf347a..ade744e58ab0d 100644
--- a/clang-tools-extra/unittests/clang-doc/MergeTest.cpp
+++ b/clang-tools-extra/unittests/clang-doc/MergeTest.cpp
@@ -166,11 +166,11 @@ TEST(MergeTest, mergeFunctionInfos) {
 
   One.Description.emplace_back();
   auto *OneFullComment = &One.Description.back();
-  OneFullComment->Kind = "FullComment";
+  OneFullComment->Kind = CommentKind::CK_FullComment;
   auto OneParagraphComment = std::make_unique<CommentInfo>();
-  OneParagraphComment->Kind = "ParagraphComment";
+  OneParagraphComment->Kind = CommentKind::CK_ParagraphComment;
   auto OneTextComment = std::make_unique<CommentInfo>();
-  OneTextComment->Kind = "TextComment";
+  OneTextComment->Kind = CommentKind::CK_TextComment;
   OneTextComment->Text = "This is a text comment.";
   OneParagraphComment->Children.push_back(std::move(OneTextComment));
   OneFullComment->Children.push_back(std::move(OneParagraphComment));
@@ -186,11 +186,11 @@ TEST(MergeTest, mergeFunctionInfos) {
 
   Two.Description.emplace_back();
   auto *TwoFullComment = &Two.Description.back();
-  TwoFullComment->Kind = "FullComment";
+  TwoFullComment->Kind = CommentKind::CK_FullComment;
   auto TwoParagraphComment = std::make_unique<CommentInfo>();
-  TwoParagraphComment->Kind = "ParagraphComment";
+  TwoParagraphComment->Kind = CommentKind::CK_ParagraphComment;
   auto TwoTextComment = std::make_unique<CommentInfo>();
-  TwoTextComment->Kind = "TextComment";
+  TwoTextComment->Kind = CommentKind::CK_TextComment;
   TwoTextComment->Text = "This is a text comment.";
   TwoParagraphComment->Children.push_back(std::move(TwoTextComment));
   TwoFullComment->Children.push_back(std::move(TwoParagraphComment));
@@ -213,11 +213,11 @@ TEST(MergeTest, mergeFunctionInfos) {
 
   Expected->Description.emplace_back();
   auto *ExpectedFullComment = &Expected->Description.back();
-  ExpectedFullComment->Kind = "FullComment";
+  ExpectedFullComment->Kind = CommentKind::CK_FullComment;
   auto ExpectedParagraphComment = std::make_unique<CommentInfo>();
-  ExpectedParagraphComment->Kind = "ParagraphComment";
+  ExpectedParagraphComment->Kind = CommentKind::CK_ParagraphComment;
   auto ExpectedTextComment = std::make_unique<CommentInfo>();
-  ExpectedTextComment->Kind = "TextComment";
+  ExpectedTextComment->Kind = CommentKind::CK_TextComment;
   ExpectedTextComment->Text = "This is a text comment.";
   ExpectedParagraphComment->Children.push_back(std::move(ExpectedTextComment));
   ExpectedFullComment->Children.push_back(std::move(ExpectedParagraphComment));

diff  --git a/clang-tools-extra/unittests/clang-doc/YAMLGeneratorTest.cpp 
b/clang-tools-extra/unittests/clang-doc/YAMLGeneratorTest.cpp
index 407a503e2d43a..a9e7c6413cf13 100644
--- a/clang-tools-extra/unittests/clang-doc/YAMLGeneratorTest.cpp
+++ b/clang-tools-extra/unittests/clang-doc/YAMLGeneratorTest.cpp
@@ -91,12 +91,12 @@ TEST(YAMLGeneratorTest, emitRecordYAML) {
 
   // Member documentation.
   CommentInfo TopComment;
-  TopComment.Kind = "FullComment";
+  TopComment.Kind = CommentKind::CK_FullComment;
   TopComment.Children.emplace_back(std::make_unique<CommentInfo>());
   CommentInfo *Brief = TopComment.Children.back().get();
-  Brief->Kind = "ParagraphComment";
+  Brief->Kind = CommentKind::CK_ParagraphComment;
   Brief->Children.emplace_back(std::make_unique<CommentInfo>());
-  Brief->Children.back()->Kind = "TextComment";
+  Brief->Children.back()->Kind = CommentKind::CK_TextComment;
   Brief->Children.back()->Name = "ParagraphComment";
   Brief->Children.back()->Text = "Value of the thing.";
   I.Members.back().Description.push_back(std::move(TopComment));
@@ -150,11 +150,11 @@ IsTypeDef:       true
     Name:            'X'
     Access:          Private
     Description:
-      - Kind:            'FullComment'
+      - Kind:            FullComment
         Children:
-          - Kind:            'ParagraphComment'
+          - Kind:            ParagraphComment
             Children:
-              - Kind:            'TextComment'
+              - Kind:            TextComment
                 Text:            'Value of the thing.'
                 Name:            'ParagraphComment'
 Bases:
@@ -375,103 +375,105 @@ TEST(YAMLGeneratorTest, emitCommentYAML) {
   I.Access = AccessSpecifier::AS_none;
 
   CommentInfo Top;
-  Top.Kind = "FullComment";
+  Top.Kind = CommentKind::CK_FullComment;
 
   Top.Children.emplace_back(std::make_unique<CommentInfo>());
   CommentInfo *BlankLine = Top.Children.back().get();
-  BlankLine->Kind = "ParagraphComment";
+  BlankLine->Kind = CommentKind::CK_ParagraphComment;
   BlankLine->Children.emplace_back(std::make_unique<CommentInfo>());
-  BlankLine->Children.back()->Kind = "TextComment";
+  BlankLine->Children.back()->Kind = CommentKind::CK_TextComment;
 
   Top.Children.emplace_back(std::make_unique<CommentInfo>());
   CommentInfo *Brief = Top.Children.back().get();
-  Brief->Kind = "ParagraphComment";
+  Brief->Kind = CommentKind::CK_ParagraphComment;
   Brief->Children.emplace_back(std::make_unique<CommentInfo>());
-  Brief->Children.back()->Kind = "TextComment";
+  Brief->Children.back()->Kind = CommentKind::CK_TextComment;
   Brief->Children.back()->Name = "ParagraphComment";
   Brief->Children.back()->Text = " Brief description.";
 
   Top.Children.emplace_back(std::make_unique<CommentInfo>());
   CommentInfo *Extended = Top.Children.back().get();
-  Extended->Kind = "ParagraphComment";
+  Extended->Kind = CommentKind::CK_ParagraphComment;
   Extended->Children.emplace_back(std::make_unique<CommentInfo>());
-  Extended->Children.back()->Kind = "TextComment";
+  Extended->Children.back()->Kind = CommentKind::CK_TextComment;
   Extended->Children.back()->Text = " Extended description that";
   Extended->Children.emplace_back(std::make_unique<CommentInfo>());
-  Extended->Children.back()->Kind = "TextComment";
+  Extended->Children.back()->Kind = CommentKind::CK_TextComment;
   Extended->Children.back()->Text = " continues onto the next line.";
 
   Top.Children.emplace_back(std::make_unique<CommentInfo>());
   CommentInfo *HTML = Top.Children.back().get();
-  HTML->Kind = "ParagraphComment";
+  HTML->Kind = CommentKind::CK_ParagraphComment;
   HTML->Children.emplace_back(std::make_unique<CommentInfo>());
-  HTML->Children.back()->Kind = "TextComment";
+  HTML->Children.back()->Kind = CommentKind::CK_TextComment;
   HTML->Children.emplace_back(std::make_unique<CommentInfo>());
-  HTML->Children.back()->Kind = "HTMLStartTagComment";
+  HTML->Children.back()->Kind = CommentKind::CK_HTMLStartTagComment;
   HTML->Children.back()->Name = "ul";
   HTML->Children.back()->AttrKeys.emplace_back("class");
   HTML->Children.back()->AttrValues.emplace_back("test");
   HTML->Children.emplace_back(std::make_unique<CommentInfo>());
-  HTML->Children.back()->Kind = "HTMLStartTagComment";
+  HTML->Children.back()->Kind = CommentKind::CK_HTMLStartTagComment;
   HTML->Children.back()->Name = "li";
   HTML->Children.emplace_back(std::make_unique<CommentInfo>());
-  HTML->Children.back()->Kind = "TextComment";
+  HTML->Children.back()->Kind = CommentKind::CK_TextComment;
   HTML->Children.back()->Text = " Testing.";
   HTML->Children.emplace_back(std::make_unique<CommentInfo>());
-  HTML->Children.back()->Kind = "HTMLEndTagComment";
+  HTML->Children.back()->Kind = CommentKind::CK_HTMLEndTagComment;
   HTML->Children.back()->Name = "ul";
   HTML->Children.back()->SelfClosing = true;
 
   Top.Children.emplace_back(std::make_unique<CommentInfo>());
   CommentInfo *Verbatim = Top.Children.back().get();
-  Verbatim->Kind = "VerbatimBlockComment";
+  Verbatim->Kind = CommentKind::CK_VerbatimBlockComment;
   Verbatim->Name = "verbatim";
   Verbatim->CloseName = "endverbatim";
   Verbatim->Children.emplace_back(std::make_unique<CommentInfo>());
-  Verbatim->Children.back()->Kind = "VerbatimBlockLineComment";
+  Verbatim->Children.back()->Kind = CommentKind::CK_VerbatimBlockLineComment;
   Verbatim->Children.back()->Text = " The description continues.";
 
   Top.Children.emplace_back(std::make_unique<CommentInfo>());
   CommentInfo *ParamOut = Top.Children.back().get();
-  ParamOut->Kind = "ParamCommandComment";
+  ParamOut->Kind = CommentKind::CK_ParamCommandComment;
   ParamOut->Direction = "[out]";
   ParamOut->ParamName = "I";
   ParamOut->Explicit = true;
   ParamOut->Children.emplace_back(std::make_unique<CommentInfo>());
-  ParamOut->Children.back()->Kind = "ParagraphComment";
+  ParamOut->Children.back()->Kind = CommentKind::CK_ParagraphComment;
   ParamOut->Children.back()->Children.emplace_back(
       std::make_unique<CommentInfo>());
-  ParamOut->Children.back()->Children.back()->Kind = "TextComment";
+  ParamOut->Children.back()->Children.back()->Kind =
+      CommentKind::CK_TextComment;
   ParamOut->Children.back()->Children.emplace_back(
       std::make_unique<CommentInfo>());
-  ParamOut->Children.back()->Children.back()->Kind = "TextComment";
+  ParamOut->Children.back()->Children.back()->Kind =
+      CommentKind::CK_TextComment;
   ParamOut->Children.back()->Children.back()->Text = " is a parameter.";
 
   Top.Children.emplace_back(std::make_unique<CommentInfo>());
   CommentInfo *ParamIn = Top.Children.back().get();
-  ParamIn->Kind = "ParamCommandComment";
+  ParamIn->Kind = CommentKind::CK_ParamCommandComment;
   ParamIn->Direction = "[in]";
   ParamIn->ParamName = "J";
   ParamIn->Children.emplace_back(std::make_unique<CommentInfo>());
-  ParamIn->Children.back()->Kind = "ParagraphComment";
+  ParamIn->Children.back()->Kind = CommentKind::CK_ParagraphComment;
   ParamIn->Children.back()->Children.emplace_back(
       std::make_unique<CommentInfo>());
-  ParamIn->Children.back()->Children.back()->Kind = "TextComment";
+  ParamIn->Children.back()->Children.back()->Kind = 
CommentKind::CK_TextComment;
   ParamIn->Children.back()->Children.back()->Text = " is a parameter.";
   ParamIn->Children.back()->Children.emplace_back(
       std::make_unique<CommentInfo>());
-  ParamIn->Children.back()->Children.back()->Kind = "TextComment";
+  ParamIn->Children.back()->Children.back()->Kind = 
CommentKind::CK_TextComment;
 
   Top.Children.emplace_back(std::make_unique<CommentInfo>());
   CommentInfo *Return = Top.Children.back().get();
-  Return->Kind = "BlockCommandComment";
+  Return->Kind = CommentKind::CK_BlockCommandComment;
   Return->Name = "return";
   Return->Explicit = true;
   Return->Children.emplace_back(std::make_unique<CommentInfo>());
-  Return->Children.back()->Kind = "ParagraphComment";
+  Return->Children.back()->Kind = CommentKind::CK_ParagraphComment;
   Return->Children.back()->Children.emplace_back(
       std::make_unique<CommentInfo>());
-  Return->Children.back()->Children.back()->Kind = "TextComment";
+  Return->Children.back()->Children.back()->Kind = CommentKind::CK_TextComment;
   Return->Children.back()->Children.back()->Text = "void";
 
   I.Description.emplace_back(std::move(Top));
@@ -487,70 +489,70 @@ TEST(YAMLGeneratorTest, emitCommentYAML) {
 USR:             '0000000000000000000000000000000000000000'
 Name:            'f'
 Description:
-  - Kind:            'FullComment'
+  - Kind:            FullComment
     Children:
-      - Kind:            'ParagraphComment'
+      - Kind:            ParagraphComment
         Children:
-          - Kind:            'TextComment'
-      - Kind:            'ParagraphComment'
+          - Kind:            TextComment
+      - Kind:            ParagraphComment
         Children:
-          - Kind:            'TextComment'
+          - Kind:            TextComment
             Text:            ' Brief description.'
             Name:            'ParagraphComment'
-      - Kind:            'ParagraphComment'
+      - Kind:            ParagraphComment
         Children:
-          - Kind:            'TextComment'
+          - Kind:            TextComment
             Text:            ' Extended description that'
-          - Kind:            'TextComment'
+          - Kind:            TextComment
             Text:            ' continues onto the next line.'
-      - Kind:            'ParagraphComment'
+      - Kind:            ParagraphComment
         Children:
-          - Kind:            'TextComment'
-          - Kind:            'HTMLStartTagComment'
+          - Kind:            TextComment
+          - Kind:            HTMLStartTagComment
             Name:            'ul'
             AttrKeys:
               - 'class'
             AttrValues:
               - 'test'
-          - Kind:            'HTMLStartTagComment'
+          - Kind:            HTMLStartTagComment
             Name:            'li'
-          - Kind:            'TextComment'
+          - Kind:            TextComment
             Text:            ' Testing.'
-          - Kind:            'HTMLEndTagComment'
+          - Kind:            HTMLEndTagComment
             Name:            'ul'
             SelfClosing:     true
-      - Kind:            'VerbatimBlockComment'
+      - Kind:            VerbatimBlockComment
         Name:            'verbatim'
         CloseName:       'endverbatim'
         Children:
-          - Kind:            'VerbatimBlockLineComment'
+          - Kind:            VerbatimBlockLineComment
             Text:            ' The description continues.'
-      - Kind:            'ParamCommandComment'
+      - Kind:            ParamCommandComment
         Direction:       '[out]'
         ParamName:       'I'
         Explicit:        true
         Children:
-          - Kind:            'ParagraphComment'
+          - Kind:            ParagraphComment
             Children:
-              - Kind:            'TextComment'
-              - Kind:            'TextComment'
+              - Kind:            TextComment
+              - Kind:            TextComment
                 Text:            ' is a parameter.'
-      - Kind:            'ParamCommandComment'
+      - Kind:            ParamCommandComment
         Direction:       '[in]'
         ParamName:       'J'
         Children:
-          - Kind:            'ParagraphComment'
+          - Kind:            ParagraphComment
             Children:
-              - Kind:            'TextComment'
+              - Kind:            TextComment
                 Text:            ' is a parameter.'
-              - Kind:            'TextComment'
-      - Kind:            'BlockCommandComment'
+              - Kind:            TextComment
+      - Kind:            BlockCommandComment
         Name:            'return'
         Explicit:        true
         Children:
-          - Kind:            'ParagraphComment'
+          - Kind:            ParagraphComment
             Children:
-              - Kind:            'TextComment'
+              - Kind:            TextComment
                 Text:            'void'
 DefLocation:
   LineNumber:      10


        
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to