Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support concepts and constraints #649

Merged
merged 1 commit into from
Aug 19, 2024
Merged
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
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 ([email protected])
//
// 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
Loading