Skip to content

Commit

Permalink
feat: support concepts and constraints (#649)
Browse files Browse the repository at this point in the history
  • Loading branch information
sdkrystian authored Aug 19, 2024
1 parent e460d86 commit abf42ae
Show file tree
Hide file tree
Showing 37 changed files with 793 additions and 64 deletions.
1 change: 1 addition & 0 deletions include/mrdocs/Metadata.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
// metadata extracted from AST

#include <mrdocs/Metadata/Alias.hpp>
#include <mrdocs/Metadata/Concept.hpp>
#include <mrdocs/Metadata/Enum.hpp>
#include <mrdocs/Metadata/Enumerator.hpp>
#include <mrdocs/Metadata/Expression.hpp>
Expand Down
47 changes: 47 additions & 0 deletions include/mrdocs/Metadata/Concept.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
//
// 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) 2024 Krystian Stasiowski (sdkrystian@gmail.com)
//
// Official repository: https://github.com/cppalliance/mrdocs
//

#ifndef MRDOCS_API_METADATA_CONCEPT_HPP
#define MRDOCS_API_METADATA_CONCEPT_HPP

#include <mrdocs/Platform.hpp>
#include <mrdocs/Metadata/Info.hpp>
#include <mrdocs/Metadata/Expression.hpp>
#include <mrdocs/Metadata/Source.hpp>

namespace clang {
namespace mrdocs {

/** Info for concepts.
*/
struct ConceptInfo
: InfoCommonBase<InfoKind::Concept>
, SourceInfo
{
/** The concepts template parameters
*/
std::unique_ptr<TemplateInfo> Template;

/** The concepts constraint-expression
*/
ExprInfo Constraint;

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

explicit ConceptInfo(SymbolID ID) noexcept
: InfoCommonBase(ID)
{
}
};

} // mrdocs
} // clang

#endif
2 changes: 2 additions & 0 deletions include/mrdocs/Metadata/Function.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,8 @@ struct FunctionInfo

ExplicitInfo Explicit;

ExprInfo Requires;

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

explicit FunctionInfo(SymbolID ID) noexcept
Expand Down
1 change: 1 addition & 0 deletions include/mrdocs/Metadata/InfoNodes.inc
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ INFO(Enumerator, Enumerators, ENUMERATOR, enumerator, enumerator
INFO(Guide, Guides, GUIDE, guide, guides, The symbol is a deduction guide)
INFO(Alias, Aliases, ALIAS, alias, aliases, The symbol is a namespace alias)
INFO(Using, Usings, USING, using, usings, The symbol is a using declaration)
INFO(Concept, Concepts, CONCEPT, concept, concepts, The symbol is a concept)

#ifdef INFO_PASCAL
#undef INFO_PASCAL
Expand Down
7 changes: 7 additions & 0 deletions include/mrdocs/Metadata/Template.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,9 @@ struct TypeTParam
{
/** Keyword (class/typename) the parameter uses */
TParamKeyKind KeyKind = TParamKeyKind::Class;

/** The type-constraint for the parameter, if any. */
std::unique_ptr<NameInfo> Constraint;
};

struct NonTypeTParam
Expand Down Expand Up @@ -284,6 +287,10 @@ struct TemplateInfo
std::vector<std::unique_ptr<TParam>> Params;
std::vector<std::unique_ptr<TArg>> Args;

/** The requires-clause for the template parameter list, if any.
*/
ExprInfo Requires;

/** Primary template ID for partial and explicit specializations.
*/
SymbolID Primary = SymbolID::invalid;
Expand Down
25 changes: 24 additions & 1 deletion include/mrdocs/Metadata/Type.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
namespace clang {
namespace mrdocs {

enum QualifierKind : int
enum QualifierKind
{
None,
Const,
Expand All @@ -39,6 +39,7 @@ enum class TypeKind
{
Named = 1, // for bitstream
Decltype,
Auto,
LValueReference,
RValueReference,
Pointer,
Expand All @@ -49,6 +50,14 @@ enum class TypeKind

MRDOCS_DECL dom::String toString(TypeKind kind) noexcept;

enum class AutoKind
{
Auto,
DecltypeAuto
};

MRDOCS_DECL dom::String toString(AutoKind kind) noexcept;

struct TypeInfo
{
/** The kind of TypeInfo this is
Expand All @@ -63,6 +72,7 @@ struct TypeInfo

constexpr bool isNamed() const noexcept { return Kind == TypeKind::Named; }
constexpr bool isDecltype() const noexcept { return Kind == TypeKind::Decltype; }
constexpr bool isAuto() const noexcept { return Kind == TypeKind::Auto; }
constexpr bool isLValueReference() const noexcept { return Kind == TypeKind::LValueReference; }
constexpr bool isRValueReference() const noexcept { return Kind == TypeKind::RValueReference; }
constexpr bool isPointer() const noexcept { return Kind == TypeKind::Pointer; }
Expand Down Expand Up @@ -100,6 +110,7 @@ struct IsType : TypeInfo

static constexpr bool isNamed() noexcept { return K == TypeKind::Named; }
static constexpr bool isDecltype() noexcept { return K == TypeKind::Decltype; }
static constexpr bool isAuto() noexcept { return K == TypeKind::Auto; }
static constexpr bool isLValueReference() noexcept { return K == TypeKind::LValueReference; }
static constexpr bool isRValueReference() noexcept { return K == TypeKind::RValueReference; }
static constexpr bool isPointer() noexcept { return K == TypeKind::Pointer; }
Expand Down Expand Up @@ -129,6 +140,14 @@ struct DecltypeTypeInfo
ExprInfo Operand;
};

struct AutoTypeInfo
: IsType<TypeKind::Auto>
{
QualifierKind CVQualifiers = QualifierKind::None;
AutoKind Keyword = AutoKind::Auto;
std::unique_ptr<NameInfo> Constraint;
};

struct LValueReferenceTypeInfo
: IsType<TypeKind::LValueReference>
{
Expand Down Expand Up @@ -226,6 +245,10 @@ visit(
return f(static_cast<add_cv_from_t<
TypeTy, DecltypeTypeInfo>&>(II),
std::forward<Args>(args)...);
case TypeKind::Auto:
return f(static_cast<add_cv_from_t<
TypeTy, AutoTypeInfo>&>(II),
std::forward<Args>(args)...);
case TypeKind::LValueReference:
return f(static_cast<add_cv_from_t<
TypeTy, LValueReferenceTypeInfo>&>(II),
Expand Down
20 changes: 20 additions & 0 deletions mrdocs.rnc
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ grammar
attribute class { "constructor"|"destructor"|"conversion" } ?,
attribute exception-spec { text } ?,
attribute explicit-spec { text } ?,
attribute requires { text } ?,
Location *,
(
Attr * |
Expand Down Expand Up @@ -246,6 +247,19 @@ grammar

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

Concept =
element concept
{
Name,
Access ?,
ID,
Location *,
Javadoc ?,
attribute constraint { text }
}

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

Symbol =
(
attribute Tag { text },
Expand All @@ -263,6 +277,7 @@ grammar
element template
{
attribute class { "explicit"|"partial" } ?,
attribute requires { text } ?,
ID ?,
TemplateParam *,
TemplateArg *,
Expand All @@ -272,6 +287,7 @@ grammar
Typedef |
Variable |
Guide |
Concept |
Template
)
}
Expand Down Expand Up @@ -337,6 +353,7 @@ grammar
Template |
Alias |
Using |
Concept |
Specialization
)*

Expand Down Expand Up @@ -436,6 +453,7 @@ grammar
{
"named" |
"decltype" |
"auto" |
"lvalue-reference" |
"rvalue-reference" |
"pointer" |
Expand All @@ -453,6 +471,8 @@ grammar
attribute exception-spec { text } ?,
attribute bounds { text } ?,
attribute operand { text } ?,
attribute constraint { text } ?,
attribute keyword { text } ?,
TypeInfo *
}
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
{{#if element-type~}}{{~>declarator-before element-type nolink=nolink~}}{{/if~}}
{{#if return-type~}}{{~>declarator-before return-type nolink=nolink~}}{{/if~}}
{{#if (eq kind "named")}}{{>name-info name nolink=nolink}}{{/if~}}
{{#if (eq kind "auto")}}{{#if constraint}}{{>name-info constraint nolink=nolink}} {{/if~}}{{keyword}}{{/if~}}
{{#if cv-qualifiers~}}
{{#if pointee-type}} {{cv-qualifiers}}{{else}} {{cv-qualifiers}}{{/if~}}
{{/if~}}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{{>template-head symbol.template}}

concept {{>declarator-id symbol}} = {{symbol.constraint}}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
{{#if symbol.refQualifier}} {{symbol.refQualifier}}{{/if~}}
{{#if symbol.exceptionSpec}} {{symbol.exceptionSpec}}{{/if~}}
{{#if (eq symbol.class "normal")}}{{>declarator-after symbol.return}}{{/if~}}
{{#if symbol.requires}} requires {{symbol.requires}}{{/if~}}
{{#if symbol.hasOverrideAttr}} override{{/if~}}
{{#if symbol.isFinal}} final{{/if~}}
{{#if symbol.isPure}} = 0{{/if~}}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{{!-- concept --}}
= {{>nested-name-specifier symbol=symbol.parent includeNamespace=true}}{{symbol.name}}

{{symbol.doc.brief}}

== Synopsis

{{>source dcl=(primary_location symbol)}}

[source,cpp,subs="verbatim,macros,-callouts"]
----
{{>signature/concept symbol=symbol}};
----
{{#if symbol.doc.description}}
== Description
{{symbol.doc.description}}
{{/if}}
{{#if symbol.doc.see}}
== See Also
{{#each symbol.doc.see}}
{{.}}
{{/each}}
{{/if}}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
template<{{#each params}}{{#unless (and @first @last)}}
{{/unless}}{{>template-param~}}
{{#unless @last}},{{/unless~}}
{{/each~}}>
{{/each}}>{{#if requires}} requires {{requires}}{{/if}}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{{#if (eq kind "type")~}}
{{key}}{{#if is-pack}}...{{/if~}}
{{#if constraint}}{{>name-info constraint}}{{else}}{{key}}{{/if~}}
{{#if is-pack}}...{{/if~}}
{{#if name}} {{name}}{{/if~}}
{{#if default}} = {{>template-arg default~}}{{/if~}}
{{else if (eq kind "non-type")~}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
{{#if is-namespace}}
{{>info-list members=tranche.overloads title="Functions"}}
{{>info-list members=tranche.variables title="Variables"}}
{{>info-list members=tranche.concepts title="Concepts"}}
{{else}}
{{>info-list members=tranche.overloads title=(concat label " " "Member Functions")}}
{{>info-list members=tranche.staticoverloads title=(concat label " " "Static Member Functions")}}
Expand Down
Loading

0 comments on commit abf42ae

Please sign in to comment.