[clang-tools-extra] [llvm] [clang-doc] Add standalone Markdown parsing library (PR #202991)
Paul Kirth via llvm-commits
llvm-commits at lists.llvm.org
Tue Jun 23 08:21:51 PDT 2026
================
@@ -0,0 +1,70 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 a libFuzzer harness for parseMarkdown(). It feeds
+/// arbitrary bytes to the parser and recursively walks the returned node tree,
+/// so every node and its children are exercised, not just the top-level nodes.
+///
+//===----------------------------------------------------------------------===//
+
+#include "support/Markdown.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/Casting.h"
+#include <cstddef>
+#include <cstdint>
+
+using namespace clang::doc::markdown;
+
+static void visit(const MDNode *Node);
+
+static void visitAll(llvm::ArrayRef<MDNode *> Nodes) {
+ for (const MDNode *N : Nodes)
+ visit(N);
+}
+
+// Recurses into a node's children so the whole tree is walked.
+static void visit(const MDNode *Node) {
+ if (!Node)
+ return;
+ if (const auto *P = llvm::dyn_cast<ParagraphNode>(Node))
+ visitAll(P->Children);
+ else if (const auto *H = llvm::dyn_cast<HeadingNode>(Node))
+ visitAll(H->Children);
+ else if (const auto *E = llvm::dyn_cast<EmphasisNode>(Node))
+ visitAll(E->Children);
+ else if (const auto *S = llvm::dyn_cast<StrongNode>(Node))
+ visitAll(S->Children);
+ else if (const auto *Q = llvm::dyn_cast<BlockQuoteNode>(Node))
+ visitAll(Q->Children);
+ else if (const auto *LI = llvm::dyn_cast<ListItemNode>(Node))
+ visitAll(LI->Children);
+ else if (const auto *UL = llvm::dyn_cast<UnorderedListNode>(Node))
+ for (const ListItemNode *Item : UL->Items)
+ visit(Item);
+ else if (const auto *OL = llvm::dyn_cast<OrderedListNode>(Node))
+ for (const ListItemNode *Item : OL->Items)
+ visit(Item);
+ else if (const auto *T = llvm::dyn_cast<TableNode>(Node)) {
+ for (const TableCell &Cell : T->Header.Cells)
+ visitAll(Cell.Children);
+ for (const TableRow &Row : T->Body)
----------------
ilovepi wrote:
I'd prefer the concrete type, but that's me. if you switch to auto do make sure you're keeping `const &`, so we avoid copies.
https://github.com/llvm/llvm-project/pull/202991
More information about the llvm-commits
mailing list