Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions include/mrdocs/Corpus.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,19 @@ class MRDOCS_VISIBLE
NamespaceSymbol const&
globalNamespace() const noexcept;

/** Return all preprocessor macros in the corpus.

Macros are stored at the corpus root, not under any
namespace, since they are not in any C++ scope. The
result is sorted by macro name, with source location
as a tiebreaker, so iteration order is stable across
runs.

@return All MacroSymbols in stable iteration order.
*/
std::vector<MacroSymbol const*>
macros() const;

/** Visit the specified Symbol IDs

This function invokes the specified function `f`
Expand Down
1 change: 1 addition & 0 deletions include/mrdocs/Metadata.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include <mrdocs/Metadata/Symbol/Friend.hpp>
#include <mrdocs/Metadata/Symbol/Function.hpp>
#include <mrdocs/Metadata/Symbol/Guide.hpp>
#include <mrdocs/Metadata/Symbol/Macro.hpp>
#include <mrdocs/Metadata/Symbol/Namespace.hpp>
#include <mrdocs/Metadata/Symbol/NamespaceAlias.hpp>
#include <mrdocs/Metadata/Symbol/Overloads.hpp>
Expand Down
82 changes: 82 additions & 0 deletions include/mrdocs/Metadata/Symbol/Macro.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
//
// Licensed 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
//
// Copyright (c) 2026 Gennaro Prota (gennaro.prota@gmail.com)
//
// Official repository: https://github.com/cppalliance/mrdocs
//

#ifndef MRDOCS_API_METADATA_SYMBOL_MACRO_HPP
#define MRDOCS_API_METADATA_SYMBOL_MACRO_HPP

#include <mrdocs/Metadata/Symbol.hpp>
#include <mrdocs/Support/Describe.hpp>
#include <string>
#include <vector>

namespace mrdocs {

/** Info for preprocessor macros.

Covers both object-like and function-like macros.
*/
struct MacroSymbol final
: SymbolCommonBase<SymbolKind::Macro>
{
/** Whether this is a function-like macro.
*/
bool IsFunctionLike = false;

/** The names of the macro's parameters.

Empty for object-like macros. For variadic
function-like macros, this lists only the
named parameters; variadicness is indicated
by @ref IsVariadic.
*/
std::vector<std::string> Parameters;

/** Whether the macro takes a variadic argument list.

True for macros declared with `...`, such as
`#define LOG(fmt, ...) ...`.
*/
bool IsVariadic = false;

/** The full source of the macro definition.

Captured from the start of the line containing
the `#define` directive through the end of the
macro definition, line continuations and all,
with one normalization: whitespace between `#`
and `define` (typically used when the macro
definition is in a `#if`/`#ifdef`/`#ifndef`),
and the matching leading whitespace on
continuation lines, is stripped; so the
definition in the synopsis reads as a
top-level directive without a surrounding
`#if`/`#ifdef`/`#ifndef`.
*/
std::string Source;

//--------------------------------------------

/** Create a macro symbol bound to an ID.
*/
explicit MacroSymbol(SymbolID const& ID) noexcept
: SymbolCommonBase(ID)
{
}
};

MRDOCS_DESCRIBE_STRUCT(
MacroSymbol,
(SymbolCommonBase<SymbolKind::Macro>),
(IsFunctionLike, Parameters, IsVariadic, Source)
)

} // mrdocs

#endif // MRDOCS_API_METADATA_SYMBOL_MACRO_HPP
2 changes: 1 addition & 1 deletion include/mrdocs/Metadata/Symbol/SymbolKind.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ enum class SymbolKind {
MRDOCS_DESCRIBE_ENUM(SymbolKind,
Namespace, Record, Function, Overloads, Enum,
EnumConstant, Typedef, Variable, Guide,
NamespaceAlias, Using, Concept)
NamespaceAlias, Using, Concept, Macro)

/** Count the number of SymbolKind enumerators.
@return Number of `SymbolKind` values generated from SymbolNodes.inc.
Expand Down
1 change: 1 addition & 0 deletions include/mrdocs/Metadata/Symbol/SymbolNodes.inc
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ INFO(Guide)
INFO(NamespaceAlias)
INFO(Using)
INFO(Concept)
INFO(Macro)

#undef INFO

13 changes: 13 additions & 0 deletions mrdocs.rnc
Original file line number Diff line number Diff line change
Expand Up @@ -555,6 +555,18 @@ grammar

#---------------------------------------------

Macro =
element macro
{
SymbolBase,
element is-function-like { Bool }?,
element parameters { text }*,
element is-variadic { Bool }?,
element source { text }?
}

#---------------------------------------------

Overloads =
element overloads
{
Expand Down Expand Up @@ -582,6 +594,7 @@ grammar
NamespaceAlias |
Using |
Concept |
Macro |
Overloads
)

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{{!--
Layout for the corpus-level Macros index page (multipage mode).
The wrapper template handles the title, footer, etc.; this
template only emits the page contents.
--}}
{{>symbol/detail/members-table-impl members=corpusMacros isName=false includeBrief=true title=""}}
6 changes: 6 additions & 0 deletions share/mrdocs/addons/generator/adoc/partials/symbol.adoc.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,12 @@
{{! Namespace members }}
{{else if (eq symbol.kind "namespace")}}
{{>symbol/tranche tranche=symbol.members label="" is-namespace=true}}
{{! Navigation hint: macros live on their own page since they
are not in any C++ scope. }}
{{#if (and @root.config.multipage (not symbol.parent) @root.corpusMacros)}}

See also: <<macros#,Macros>>
{{/if}}
{{! Enum members }}
{{else if (eq symbol.kind "enum")}}
{{>symbol/members-table members=symbol.constants title="Members"}}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{{!--
Render the synopsis for a preprocessor macro.

For regular macros, the synopsis is the normalized
source of the `#define` directive.

For see-below macros, the body is replaced by a
`/* see-below */` marker. Implementation-defined
macros are not rendered at all (see
`shouldGenerate` in VisitorHelpers.cpp).

Expected Context: {Symbol Object} (kind == "macro")
--}}
{{#isSeeBelow~}}
#define {{name}}{{#if isFunctionLike}}({{#each parameters}}{{this}}{{#unless @last}}, {{/unless}}{{/each}}{{#if isVariadic}}{{#if parameters}}, {{/if}}...{{/if}}){{/if}} /* see-below */
{{~else~}}
{{ source }}
{{~/isSeeBelow}}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{{!--
Layout for the corpus-level Macros index page (multipage mode).
The wrapper template handles <html>, <head>, footer, etc.; this
template only emits the page contents.
--}}
{{>symbol/detail/members-table-impl members=corpusMacros isName=false includeBrief=true title=""}}
5 changes: 5 additions & 0 deletions share/mrdocs/addons/generator/html/partials/symbol.html.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,11 @@
{{! Namespace members }}
{{else if (eq symbol.kind "namespace")}}
{{>symbol/tranche tranche=symbol.members label="" is-namespace=true}}
{{! Navigation hint: macros live on their own page since they
are not in any C++ scope. }}
{{#if (and @root.config.multipage (not symbol.parent) @root.corpusMacros)}}
<p>See also: <a href="macros.html">Macros</a></p>
{{/if}}
{{! Enum members }}
{{else if (eq symbol.kind "enum")}}
{{>symbol/members-table members=symbol.constants title="Members"}}
Expand Down
13 changes: 12 additions & 1 deletion src/lib/AST/ASTAction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,20 @@
// Copyright (c) 2023 Vinnie Falco (vinnie.falco@gmail.com)
// Copyright (c) 2023 Krystian Stasiowski (sdkrystian@gmail.com)
// Copyright (c) 2024 Alan de Freitas (alandefreitas@gmail.com)
// Copyright (c) 2026 Gennaro Prota (gennaro.prota@gmail.com)
//
// Official repository: https://github.com/cppalliance/mrdocs
//

#include <lib/AST/ASTAction.hpp>
#include <lib/AST/ASTVisitorConsumer.hpp>
#include <lib/AST/MacroCollector.hpp>
#include <lib/AST/MrDocsFileSystem.hpp>
#include <clang/Frontend/CompilerInstance.h>
#include <clang/Lex/Preprocessor.h>
#include <clang/Lex/PreprocessorOptions.h>
#include <clang/Parse/ParseAST.h>
#include <memory>


namespace mrdocs {
Expand All @@ -31,6 +35,13 @@ ExecuteAction()
return;
}

// Register the macro collector before parsing begins.
// The preprocessor takes ownership; the records are
// pushed into `macroDefs_`, owned by this action.
CI.getPreprocessor().addPPCallbacks(
std::make_unique<MacroCollector>(
macroDefs_, CI.getPreprocessor()));

// Ensure comments in system headers are retained.
// We may want them if, e.g., a declaration was extracted
// as a dependency
Expand Down Expand Up @@ -96,7 +107,7 @@ CreateASTConsumer(
llvm::StringRef)
{
return std::make_unique<ASTVisitorConsumer>(
config_, ex_, Compiler);
config_, ex_, Compiler, macroDefs_);
}

} // mrdocs
Expand Down
4 changes: 4 additions & 0 deletions src/lib/AST/ASTAction.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
// Copyright (c) 2023 Vinnie Falco (vinnie.falco@gmail.com)
// Copyright (c) 2023 Krystian Stasiowski (sdkrystian@gmail.com)
// Copyright (c) 2024 Alan de Freitas (alandefreitas@gmail.com)
// Copyright (c) 2026 Gennaro Prota (gennaro.prota@gmail.com)
//
// Official repository: https://github.com/cppalliance/mrdocs
//
Expand All @@ -15,10 +16,12 @@
#define MRDOCS_LIB_AST_ASTACTION_HPP

#include <mrdocs/Platform.hpp>
#include <lib/AST/MacroCollector.hpp>
#include <lib/AST/MissingSymbolSink.hpp>
#include <lib/ConfigImpl.hpp>
#include <lib/Support/ExecutionContext.hpp>
#include <clang/Tooling/Tooling.h>
#include <vector>


namespace mrdocs {
Expand All @@ -43,6 +46,7 @@ class ASTAction
ExecutionContext& ex_;
ConfigImpl const& config_;
MissingSymbolSink* missingSink_ = nullptr;
std::vector<MacroDefinition> macroDefs_;

public:
ASTAction(
Expand Down
Loading
Loading