Skip to content

Commit 0bc88b6

Browse files
committed
extract SFINAE constraints
#feat
1 parent 37d9b93 commit 0bc88b6

File tree

6 files changed

+62
-25
lines changed

6 files changed

+62
-25
lines changed

include/mrdocs/Metadata/Type.hpp

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,18 @@ struct TypeInfo
106106
*/
107107
bool IsPackExpansion = false;
108108

109+
/** The constraints associated with the type
110+
111+
This represents the constraints associated with the type,
112+
such as SFINAE constraints.
113+
114+
For instance, if SFINAE detection is enabled, the
115+
expression `std::enable_if_t<std::is_integral_v<T>, T>`
116+
will have type `T` (NamedType) and constraints
117+
`{std::is_integral_v<T>}`.
118+
*/
119+
std::vector<ExprInfo> Constraints;
120+
109121
constexpr virtual ~TypeInfo() = default;
110122

111123
constexpr bool isNamed() const noexcept { return Kind == TypeKind::Named; }
@@ -123,14 +135,17 @@ struct TypeInfo
123135
The inner type is the type which is modified
124136
by a specifier (e.g. "int" in "pointer to int".
125137
*/
126-
virtual TypeInfo* innerType() const noexcept
138+
virtual
139+
TypeInfo*
140+
innerType() const noexcept
127141
{
128142
return nullptr;
129143
}
130144

131145
/** Return the symbol named by this type.
132146
*/
133-
SymbolID namedSymbol() const noexcept;
147+
SymbolID
148+
namedSymbol() const noexcept;
134149

135150
protected:
136151
constexpr

src/lib/AST/ASTVisitor.cpp

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1884,25 +1884,32 @@ extractSFINAEInfo(QualType const T)
18841884
// Find the parameter that represents the SFINAE result
18851885
auto const Args = templateInfo->Arguments;
18861886
MRDOCS_SYMBOL_TRACE(Args, context_);
1887-
auto const param_arg = tryGetTemplateArgument(
1887+
auto const resultType = tryGetTemplateArgument(
18881888
SFINAEControl->Parameters, Args, SFINAEControl->ParamIdx);
1889-
MRDOCS_CHECK_OR(param_arg, std::nullopt);
1890-
MRDOCS_SYMBOL_TRACE(*param_arg, context_);
1889+
MRDOCS_CHECK_OR(resultType, std::nullopt);
1890+
MRDOCS_SYMBOL_TRACE(*resultType, context_);
18911891

18921892
// Create a vector of template arguments that represent the
18931893
// controlling parameters of the SFINAE template
1894-
std::vector<TemplateArgument> ControllingArgs;
1894+
SFINAEInfo Result;
1895+
Result.Type = resultType->getAsType();
18951896
for (std::size_t I = 0; I < Args.size(); ++I)
18961897
{
18971898
if (SFINAEControl->ControllingParams[I])
18981899
{
18991900
MRDOCS_SYMBOL_TRACE(Args[I], context_);
1900-
ControllingArgs.emplace_back(Args[I]);
1901+
Expr* E = Args[I].getAsExpr();
1902+
if (!E)
1903+
{
1904+
continue;
1905+
}
1906+
Result.Constraints.emplace_back();
1907+
populate(Result.Constraints.back(), E);
19011908
}
19021909
}
19031910

19041911
// Return the main type and controlling types
1905-
return SFINAEInfo{param_arg->getAsType(), std::move(ControllingArgs)};
1912+
return Result;
19061913
}
19071914

19081915
std::optional<ASTVisitor::SFINAEControlParams>
@@ -1963,16 +1970,16 @@ getSFINAEControlParams(
19631970

19641971
// Find the index of the parameter that represents the SFINAE result
19651972
// in the underlying template arguments
1966-
auto param_arg = tryGetTemplateArgument(
1973+
auto resultType = tryGetTemplateArgument(
19671974
sfinaeControl->Parameters,
19681975
underlyingTemplateInfo->Arguments,
19691976
sfinaeControl->ParamIdx);
1970-
MRDOCS_CHECK_OR(param_arg, std::nullopt);
1971-
MRDOCS_SYMBOL_TRACE(*param_arg, context_);
1977+
MRDOCS_CHECK_OR(resultType, std::nullopt);
1978+
MRDOCS_SYMBOL_TRACE(*resultType, context_);
19721979

19731980
// Find the index of the parameter that represents the SFINAE result
19741981
// in the primary template arguments
1975-
unsigned ParamIdx = FindParam(ATD->getInjectedTemplateArgs(context_), *param_arg);
1982+
unsigned ParamIdx = FindParam(ATD->getInjectedTemplateArgs(context_), *resultType);
19761983

19771984
// Return the controlling parameters with values corresponding to
19781985
// the primary template arguments
@@ -2060,11 +2067,11 @@ getSFINAEControlParams(
20602067
}
20612068

20622069
auto [template_params, controlling_params, param_idx] = *sfinae_result;
2063-
auto param_arg = tryGetTemplateArgument(
2070+
auto resultType = tryGetTemplateArgument(
20642071
template_params, sfinae_info->Arguments, param_idx);
2065-
if(! param_arg)
2072+
if(! resultType)
20662073
return true;
2067-
auto CurrentTypeFromBase = param_arg->getAsType();
2074+
auto CurrentTypeFromBase = resultType->getAsType();
20682075
if (CurrentType.isNull())
20692076
{
20702077
CurrentType = CurrentTypeFromBase;

src/lib/AST/ASTVisitor.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -734,7 +734,7 @@ class ASTVisitor
734734
QualType Type;
735735

736736
// The template arguments used in the SFINAE context.
737-
std::vector<TemplateArgument> Arguments;
737+
std::vector<ExprInfo> Constraints;
738738
};
739739

740740
/* Get the underlying type result of a SFINAE type

src/lib/AST/TerminalTypeVisitor.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,10 @@ class TerminalTypeVisitor
8787
// The optional NestedNameSpecifier.
8888
const NestedNameSpecifier* NNS_ = nullptr;
8989

90+
protected:
91+
// Constraints associated with the type (e.g., SFINAE)
92+
std::vector<ExprInfo> Constraints;
93+
9094
public:
9195
/** Constructor for TerminalTypeVisitor.
9296
@@ -571,6 +575,7 @@ class TerminalTypeVisitor
571575
if (auto SFINAE = getASTVisitor().extractSFINAEInfo(T))
572576
{
573577
NNS_ = nullptr;
578+
Constraints = SFINAE->Constraints;
574579
return getDerived().Visit(SFINAE->Type);
575580
}
576581

@@ -606,6 +611,7 @@ class TerminalTypeVisitor
606611
if (auto SFINAE = getASTVisitor().extractSFINAEInfo(T))
607612
{
608613
NNS_ = nullptr;
614+
Constraints = SFINAE->Constraints;
609615
return getDerived().Visit(SFINAE->Type);
610616
}
611617

src/lib/AST/TypeInfoBuilder.cpp

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ buildDecltype(
102102
getASTVisitor().populate(
103103
I->Operand, T->getUnderlyingExpr());
104104
I->CVQualifiers = toQualifierKind(quals);
105+
I->Constraints = this->Constraints;
105106
*Inner = std::move(I);
106107
Result->IsPackExpansion = pack;
107108
}
@@ -129,6 +130,7 @@ buildAuto(
129130
// Constraint->Prefix = getASTVisitor().buildNameInfo(
130131
// cast<Decl>(CD->getDeclContext()));
131132
}
133+
I->Constraints = this->Constraints;
132134
*Inner = std::move(I);
133135
Result->IsPackExpansion = pack;
134136
}
@@ -145,12 +147,12 @@ buildTerminal(
145147
{
146148
auto TI = std::make_unique<NamedTypeInfo>();
147149
TI->CVQualifiers = toQualifierKind(quals);
148-
149-
auto Name = std::make_unique<NameInfo>();
150-
Name->Name = getASTVisitor().toString(T);
151-
Name->Prefix = getASTVisitor().toNameInfo(NNS);
152-
TI->Name = std::move(Name);
150+
TI->Name = std::make_unique<NameInfo>();
151+
TI->Name->Name = getASTVisitor().toString(T);
152+
TI->Name->Prefix = getASTVisitor().toNameInfo(NNS);
153+
TI->Constraints = this->Constraints;
153154
*Inner = std::move(TI);
155+
Result->Constraints = this->Constraints;
154156
Result->IsPackExpansion = pack;
155157
}
156158

@@ -187,7 +189,9 @@ buildTerminal(
187189
Name->Prefix = getASTVisitor().toNameInfo(NNS);
188190
I->Name = std::move(Name);
189191
}
192+
I->Constraints = this->Constraints;
190193
*Inner = std::move(I);
194+
Result->Constraints = this->Constraints;
191195
Result->IsPackExpansion = pack;
192196
}
193197

@@ -240,7 +244,9 @@ buildTerminal(
240244
getASTVisitor().populate(Name->TemplateArgs, *TArgs);
241245
TI->Name = std::move(Name);
242246
}
247+
TI->Constraints = this->Constraints;
243248
*Inner = std::move(TI);
249+
Result->Constraints = this->Constraints;
244250
Result->IsPackExpansion = pack;
245251
}
246252

src/lib/Metadata/Type.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,12 +83,15 @@ SymbolID
8383
TypeInfo::
8484
namedSymbol() const noexcept
8585
{
86-
if(! isNamed())
86+
if (!isNamed())
87+
{
8788
return SymbolID::invalid;
88-
const auto* NT = static_cast<
89-
const NamedTypeInfo*>(this);
90-
if(! NT->Name)
89+
}
90+
auto const* NT = static_cast<NamedTypeInfo const*>(this);
91+
if (!NT->Name)
92+
{
9193
return SymbolID::invalid;
94+
}
9295
return NT->Name->id;
9396
}
9497

0 commit comments

Comments
 (0)