Skip to content

Commit d9efa40

Browse files
committed
Improved parsing of templates
closes #167
1 parent 564d9ef commit d9efa40

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+1937
-286
lines changed

include/mrdox/Metadata/Symbols.hpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,13 @@ class OptionalSymbolID
8080
{
8181
return ID_ != EmptySID;
8282
}
83+
84+
template<typename... Args>
85+
constexpr value_type& emplace(Args&&... args)
86+
{
87+
return *::new (&ID_) SymbolID(
88+
std::forward<Args>(args)...);
89+
}
8390
};
8491

8592
/** The ID of the global namespace.

include/mrdox/Metadata/Template.hpp

Lines changed: 33 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
66
//
77
// Copyright (c) 2023 Vinnie Falco ([email protected])
8+
// Copyright (c) 2023 Krystian Stasiowski ([email protected])
89
//
910
// Official repository: https://github.com/cppalliance/mrdox
1011
//
@@ -13,30 +14,49 @@
1314
#define MRDOX_METADATA_TEMPLATE_HPP
1415

1516
#include <mrdox/Platform.hpp>
17+
#include <mrdox/Metadata/TemplateArg.hpp>
1618
#include <mrdox/Metadata/TemplateParam.hpp>
17-
#include <llvm/ADT/Optional.h>
1819

1920
namespace clang {
2021
namespace mrdox {
2122

22-
struct TemplateSpecializationInfo
23+
enum class TemplateSpecKind
2324
{
24-
// Indicates the declaration that this specializes.
25-
SymbolID SpecializationOf;
26-
27-
// Template parameters applying to the specialized record/function.
28-
std::vector<TemplateParamInfo> Params;
25+
Primary = 0, // for bitstream
26+
Explicit,
27+
Partial
2928
};
3029

31-
// Records the template information for a struct or function that is a template
32-
// or an explicit template specialization.
30+
// stores information pertaining to primary template and
31+
// partial/explicit specialization declarations
3332
struct TemplateInfo
3433
{
35-
// May be empty for non-partial specializations.
36-
std::vector<TemplateParamInfo> Params;
34+
// for primary templates:
35+
// - Params will be non-empty
36+
// - Args will be empty
37+
// for explicit specializations:
38+
// - Params will be empty
39+
// for partial specializations:
40+
// - Params will be non-empty
41+
// - each template parameter will appear at least
42+
// once in Args outside of a non-deduced context
43+
std::vector<TParam> Params;
44+
std::vector<TArg> Args;
45+
46+
// stores the ID of the corresponding primary template
47+
// for partial and explicit specializations
48+
OptionalSymbolID Primary;
3749

38-
// Set when this is a specialization of another record/function.
39-
llvm::Optional<TemplateSpecializationInfo> Specialization;
50+
// KRYSTIAN NOTE: using the presence of args/params
51+
// to determine the specialization kind *should* work.
52+
// emphasis on should.
53+
TemplateSpecKind specializationKind() const noexcept
54+
{
55+
if(Params.empty())
56+
return TemplateSpecKind::Explicit;
57+
return Args.empty() ? TemplateSpecKind::Primary :
58+
TemplateSpecKind::Partial;
59+
}
4060
};
4161

4262
} // mrdox
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
//
2+
// Licensed under the Apache License v2.0 with LLVM Exceptions.
3+
// See https://llvm.org/LICENSE.txt for license information.
4+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
5+
//
6+
// Copyright (c) 2023 Krystian Stasiowski ([email protected])
7+
//
8+
// Official repository: https://github.com/cppalliance/mrdox
9+
//
10+
11+
#ifndef MRDOX_METADATA_TEMPLATEARG_HPP
12+
#define MRDOX_METADATA_TEMPLATEARG_HPP
13+
14+
#include <mrdox/Platform.hpp>
15+
#include <string>
16+
17+
namespace clang {
18+
namespace mrdox {
19+
20+
struct TArg
21+
{
22+
std::string Value;
23+
24+
TArg() = default;
25+
26+
MRDOX_DECL
27+
TArg(std::string&& value);
28+
};
29+
30+
} // mrdox
31+
} // clang
32+
33+
#endif

include/mrdox/Metadata/TemplateParam.hpp

Lines changed: 148 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
66
//
77
// Copyright (c) 2023 Vinnie Falco ([email protected])
8+
// Copyright (c) 2023 Krystian Stasiowski ([email protected])
89
//
910
// Official repository: https://github.com/cppalliance/mrdox
1011
//
@@ -13,45 +14,164 @@
1314
#define MRDOX_METADATA_TEMPLATEPARAM_HPP
1415

1516
#include <mrdox/Platform.hpp>
16-
#include <clang/AST/Decl.h>
17-
#include <clang/AST/Type.h>
18-
#include <llvm/ADT/SmallString.h>
19-
#include <llvm/ADT/StringRef.h>
17+
#include <mrdox/Metadata/Type.hpp>
2018

2119
namespace clang {
2220
namespace mrdox {
2321

24-
// Represents one template parameter.
25-
//
26-
// This is a very simple serialization of the text of the source code of the
27-
// template parameter. It is saved in a struct so there is a place to add the
28-
// name and default values in the future if needed.
29-
//
30-
/** A template parameter.
31-
*/
32-
struct TemplateParamInfo
22+
enum class TemplateParamKind : int
23+
{
24+
None = 0, // for bitstream
25+
// template type parameter, e.g. "typename T" or "class T"
26+
Type,
27+
// template non-type parameter, e.g. "int N" or "auto N"
28+
NonType,
29+
// template template parameter, e.g. "template<typename> typename T"
30+
Template,
31+
};
32+
33+
struct TParam;
34+
35+
struct TypeTParam
36+
{
37+
// default type for the type template parameter
38+
std::optional<TypeInfo> Default;
39+
};
40+
41+
struct NonTypeTParam
42+
{
43+
// type of the non-type template parameter
44+
TypeInfo Type;
45+
// non-type template parameter default value (if any)
46+
std::optional<std::string> Default;
47+
};
48+
49+
struct TemplateTParam
50+
{
51+
// template parameters for the template template parameter
52+
std::vector<TParam> Params;
53+
// non-type template parameter default value (if any)
54+
std::optional<std::string> Default;
55+
};
56+
57+
58+
struct TParam
3359
{
34-
// The literal contents of the code for that specifies this template parameter
35-
// for this declaration. Typical values will be "class T" and
36-
// "typename T = int".
37-
llvm::SmallString<16> Contents;
60+
private:
61+
union Variant
62+
{
63+
Variant() { }
64+
~Variant() { }
65+
66+
TypeTParam Type;
67+
NonTypeTParam NonType;
68+
TemplateTParam Template;
69+
} Variant_;
70+
71+
void destroy() const noexcept;
72+
73+
template<typename T>
74+
void
75+
construct(T&& other)
76+
{
77+
switch(other.Kind)
78+
{
79+
case TemplateParamKind::Type:
80+
emplace<TypeTParam>(
81+
std::forward<T>(other).Variant_.Type);
82+
break;
83+
case TemplateParamKind::NonType:
84+
emplace<NonTypeTParam>(
85+
std::forward<T>(other).Variant_.NonType);
86+
break;
87+
case TemplateParamKind::Template:
88+
emplace<TemplateTParam>(
89+
std::forward<T>(other).Variant_.Template);
90+
break;
91+
default:
92+
break;
93+
}
94+
}
95+
96+
public:
97+
// The kind of template parameter this is.
98+
TemplateParamKind Kind = TemplateParamKind::None;
99+
// The template parameters name, if any
100+
std::string Name;
101+
// Whether this template parameter is a parameter pack.
102+
bool IsParameterPack = false;
103+
38104

39-
//--------------------------------------------
105+
TParam() = default;
40106

41-
TemplateParamInfo() = default;
107+
MRDOX_DECL
108+
TParam(
109+
TParam&& other) noexcept;
110+
111+
MRDOX_DECL
112+
TParam(
113+
const TParam& other);
42114

43-
explicit
44-
TemplateParamInfo(
45-
NamedDecl const& ND);
115+
MRDOX_DECL
116+
TParam(
117+
std::string&& name,
118+
bool is_pack);
46119

47-
TemplateParamInfo(
48-
Decl const& D,
49-
TemplateArgument const &Arg);
120+
MRDOX_DECL ~TParam();
121+
122+
MRDOX_DECL
123+
TParam&
124+
operator=(
125+
const TParam& other);
126+
127+
MRDOX_DECL
128+
TParam&
129+
operator=(
130+
TParam&& other) noexcept;
131+
132+
template<typename T, typename... Args>
133+
auto&
134+
emplace(Args&&... args)
135+
{
136+
using U = std::remove_cvref_t<T>;
137+
if constexpr(std::is_same_v<U, TypeTParam>)
138+
Kind = TemplateParamKind::Type;
139+
else if constexpr(std::is_same_v<U, NonTypeTParam>)
140+
Kind = TemplateParamKind::NonType;
141+
else if constexpr(std::is_same_v<U, TemplateTParam>)
142+
Kind = TemplateParamKind::Template;
143+
else
144+
assert(! "invalid template parameter kind");
145+
return *::new (static_cast<void*>(&Variant_)) T(
146+
std::forward<Args>(args)...);
147+
}
148+
149+
template<typename T>
150+
auto& get() noexcept
151+
{
152+
using U = std::remove_cvref_t<T>;
153+
if constexpr(std::is_same_v<U, TypeTParam>)
154+
return Variant_.Type;
155+
else if constexpr(std::is_same_v<U, NonTypeTParam>)
156+
return Variant_.NonType;
157+
else if constexpr(std::is_same_v<U, TemplateTParam>)
158+
return Variant_.Template;
159+
else
160+
assert(! "invalid template parameter kind");
161+
}
50162

51-
TemplateParamInfo(
52-
llvm::StringRef Contents)
53-
: Contents(Contents)
163+
template<typename T>
164+
const auto& get() const noexcept
54165
{
166+
using U = std::remove_cvref_t<T>;
167+
if constexpr(std::is_same_v<U, TypeTParam>)
168+
return Variant_.Type;
169+
else if constexpr(std::is_same_v<U, NonTypeTParam>)
170+
return Variant_.NonType;
171+
else if constexpr(std::is_same_v<U, TemplateTParam>)
172+
return Variant_.Template;
173+
else
174+
assert(! "invalid template parameter kind");
55175
}
56176
};
57177

include/mrdox/MetadataFwd.hpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,18 @@ struct RefWithAccess;
4141
struct Reference;
4242
struct Scope;
4343
struct SymbolInfo;
44-
struct TemplateInfo;
45-
struct TemplateParamInfo;
46-
struct TemplateSpecializationInfo;
4744
struct TypeInfo;
4845
struct TypedefInfo;
4946
struct VarInfo;
5047
struct VerbatimBlock;
5148

49+
struct TemplateInfo;
50+
struct TArg;
51+
struct TParam;
52+
struct TypeTParam;
53+
struct NonTypeTParam;
54+
struct TemplateTParam;
55+
5256
struct DataMember;
5357
struct MemberEnum;
5458
struct MemberFunction;

0 commit comments

Comments
 (0)