Skip to content

Commit 8e012c8

Browse files
committed
Substitute type parameters with type aliases
Enable customization of the template instantiation process in unit tests.
1 parent c66a8c6 commit 8e012c8

File tree

10 files changed

+121
-122
lines changed

10 files changed

+121
-122
lines changed

src/parser/cxx/ast_rewriter.cc

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3457,6 +3457,18 @@ auto ASTRewriter::SpecifierVisitor::operator()(NamedTypeSpecifierAST* ast)
34573457
copy->isTemplateIntroduced = ast->isTemplateIntroduced;
34583458
copy->symbol = ast->symbol;
34593459

3460+
if (auto typeParameter = symbol_cast<TypeParameterSymbol>(copy->symbol)) {
3461+
const auto& args = rewrite.templateArguments_;
3462+
if (typeParameter && typeParameter->depth() == 0 &&
3463+
typeParameter->index() < args.size()) {
3464+
auto index = typeParameter->index();
3465+
3466+
if (auto sym = std::get_if<Symbol*>(&args[index])) {
3467+
copy->symbol = *sym;
3468+
}
3469+
}
3470+
}
3471+
34603472
return copy;
34613473
}
34623474

src/parser/cxx/binder.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -661,6 +661,8 @@ auto Binder::resolve(NestedNameSpecifierAST* nestedNameSpecifier,
661661
}
662662

663663
auto Binder::instantiate(SimpleTemplateIdAST* templateId) -> Symbol* {
664+
if (!translationUnit()->config().templateInstantiation) return nullptr;
665+
664666
std::vector<TemplateArgument> args;
665667
for (auto it = templateId->templateArgumentList; it; it = it->next) {
666668
if (auto arg = ast_cast<TypeTemplateArgumentAST>(it->value)) {

src/parser/cxx/decl_specs.cc

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -256,21 +256,6 @@ void DeclSpecs::Visitor::operator()(ComplexTypeSpecifierAST* ast) {
256256
void DeclSpecs::Visitor::operator()(NamedTypeSpecifierAST* ast) {
257257
specs.typeSpecifier = ast;
258258

259-
if (specs.rewriter) {
260-
auto typeParameter = symbol_cast<TypeParameterSymbol>(ast->symbol);
261-
const auto& args = specs.rewriter->templateArguments();
262-
263-
if (typeParameter && typeParameter->depth() == 0 &&
264-
typeParameter->index() < args.size()) {
265-
auto index = typeParameter->index();
266-
267-
if (auto ty = std::get_if<const Type*>(&args[index])) {
268-
specs.type = *ty;
269-
return;
270-
}
271-
}
272-
}
273-
274259
if (ast->symbol)
275260
specs.type = ast->symbol->type();
276261
else

src/parser/cxx/parser.cc

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -268,10 +268,8 @@ auto Parser::expect(TokenKind tk, SourceLocation& location) -> bool {
268268

269269
void Parser::operator()(UnitAST*& ast) { parse(ast); }
270270

271-
auto Parser::config() const -> const ParserConfiguration& { return config_; }
272-
273-
void Parser::setConfig(ParserConfiguration config) {
274-
config_ = std::move(config);
271+
auto Parser::config() const -> const ParserConfiguration& {
272+
return unit->config();
275273
}
276274

277275
void Parser::parse(UnitAST*& ast) { parse_translation_unit(ast); }
@@ -676,7 +674,7 @@ auto Parser::parse_completion(SourceLocation& loc) -> bool {
676674
if (didAcceptCompletionToken_) return false;
677675

678676
// if there is no completer, return false
679-
if (!config_.complete) return false;
677+
if (!config().complete) return false;
680678

681679
if (!match(TokenKind::T_CODE_COMPLETION, loc)) return false;
682680

@@ -709,7 +707,7 @@ auto Parser::parse_primary_expression(ExpressionAST*& yyast,
709707
}
710708

711709
auto Parser::parse_splicer(SplicerAST*& yyast) -> bool {
712-
if (!config_.reflect) return false;
710+
if (!config().reflect) return false;
713711

714712
if (!lookat(TokenKind::T_LBRACKET, TokenKind::T_COLON)) return false;
715713

@@ -729,7 +727,7 @@ auto Parser::parse_splicer(SplicerAST*& yyast) -> bool {
729727

730728
auto Parser::parse_splicer_expression(ExpressionAST*& yyast,
731729
const ExprContext& ctx) -> bool {
732-
if (!config_.reflect) return false;
730+
if (!config().reflect) return false;
733731

734732
SplicerAST* splicer = nullptr;
735733
if (!parse_splicer(splicer)) return false;
@@ -741,7 +739,7 @@ auto Parser::parse_splicer_expression(ExpressionAST*& yyast,
741739

742740
auto Parser::parse_reflect_expression(ExpressionAST*& yyast,
743741
const ExprContext& ctx) -> bool {
744-
if (!config_.reflect) return false;
742+
if (!config().reflect) return false;
745743

746744
SourceLocation caretLoc;
747745

@@ -1054,7 +1052,7 @@ auto Parser::parse_template_nested_name_specifier(
10541052
}
10551053
}
10561054

1057-
if (!ast->symbol && config_.checkTypes) {
1055+
if (!ast->symbol && config().checkTypes) {
10581056
ast->symbol = binder_.instantiate(templateId);
10591057
}
10601058

@@ -1859,7 +1857,7 @@ auto Parser::parse_member_expression(ExpressionAST*& yyast) -> bool {
18591857
auto objectType = ast->baseExpression->type;
18601858

18611859
// trigger the completion
1862-
config_.complete(MemberCompletionContext{
1860+
config().complete(MemberCompletionContext{
18631861
.objectType = objectType,
18641862
.accessOp = ast->accessOp,
18651863
});
@@ -4082,7 +4080,7 @@ auto Parser::parse_simple_declaration(
40824080

40834081
if (auto scope = decl.getScope()) {
40844082
setScope(scope);
4085-
} else if (q && config_.checkTypes) {
4083+
} else if (q && config().checkTypes) {
40864084
parse_error(q->firstSourceLocation(),
40874085
std::format("unresolved class or namespace"));
40884086
}
@@ -4091,7 +4089,7 @@ auto Parser::parse_simple_declaration(
40914089
auto functionSymbol = getFunction(scope(), functionName, functionType);
40924090

40934091
if (!functionSymbol) {
4094-
if (q && config_.checkTypes) {
4092+
if (q && config().checkTypes) {
40954093
parse_error(q->firstSourceLocation(),
40964094
std::format("class or namespace has no member named '{}'",
40974095
to_string(functionName)));
@@ -4196,7 +4194,7 @@ auto Parser::parse_notypespec_function_definition(
41964194
if (auto scope = decl.getScope()) {
41974195
setScope(scope);
41984196
} else if (auto q = decl.getNestedNameSpecifier()) {
4199-
if (config_.checkTypes) {
4197+
if (config().checkTypes) {
42004198
parse_error(q->firstSourceLocation(),
42014199
std::format("unresolved class or namespace"));
42024200
}
@@ -4325,7 +4323,7 @@ auto Parser::parse_static_assert_declaration(DeclarationAST*& yyast) -> bool {
43254323
value = visit(to_bool, *constValue);
43264324
}
43274325

4328-
if (!value && config_.checkTypes) {
4326+
if (!value && config().checkTypes) {
43294327
SourceLocation loc = ast->firstSourceLocation();
43304328

43314329
if (!ast->expression || !constValue.has_value()) {
@@ -4847,12 +4845,12 @@ auto Parser::parse_named_type_specifier(SpecifierAST*& yyast, DeclSpecs& specs)
48474845
if (conceptSymbol && !lookat(TokenKind::T_AUTO)) return false;
48484846
}
48494847

4850-
const auto canInstantiate = config_.checkTypes;
4848+
const auto canInstantiate = config().checkTypes;
48514849

48524850
auto symbol =
48534851
binder_.resolve(nestedNameSpecifier, unqualifiedId, canInstantiate);
48544852

4855-
if (config_.checkTypes && !symbol && ast_cast<NameIdAST>(unqualifiedId)) {
4853+
if (config().checkTypes && !symbol && ast_cast<NameIdAST>(unqualifiedId)) {
48564854
return false;
48574855
}
48584856

@@ -4987,14 +4985,14 @@ auto Parser::parse_primitive_type_specifier(SpecifierAST*& yyast,
49874985
}
49884986

49894987
auto Parser::maybe_template_name(const Identifier* id) -> bool {
4990-
if (!config_.fuzzyTemplateResolution) return true;
4988+
if (!config().fuzzyTemplateResolution) return true;
49914989
if (template_names_.contains(id)) return true;
49924990
if (concept_names_.contains(id)) return true;
49934991
return false;
49944992
}
49954993

49964994
void Parser::mark_maybe_template_name(const Identifier* id) {
4997-
if (!config_.fuzzyTemplateResolution) return;
4995+
if (!config().fuzzyTemplateResolution) return;
49984996
if (!id) return;
49994997
template_names_.insert(id);
50004998
}
@@ -5314,7 +5312,7 @@ auto Parser::parse_declarator(DeclaratorAST*& yyast, Decl& decl,
53145312

53155313
if (auto scope = decl.getScope()) {
53165314
setScope(scope);
5317-
} else if (q && config_.checkTypes) {
5315+
} else if (q && config().checkTypes) {
53185316
parse_error(q->firstSourceLocation(),
53195317
std::format("unresolved class or namespace"));
53205318
}
@@ -9041,7 +9039,7 @@ auto Parser::parse_concept_definition(DeclarationAST*& yyast) -> bool {
90419039

90429040
auto Parser::parse_splicer_specifier(SpecifierAST*& yyast, DeclSpecs& specs)
90439041
-> bool {
9044-
if (!config_.reflect) return false;
9042+
if (!config().reflect) return false;
90459043
if (specs.typeSpecifier) return false;
90469044
LookaheadParser lookahead{this};
90479045
SourceLocation typenameLoc;
@@ -9391,7 +9389,7 @@ void Parser::check(ExpressionAST* ast) {
93919389
if (binder_.inTemplate()) return;
93929390
TypeChecker check{unit};
93939391
check.setScope(scope());
9394-
check.setReportErrors(config_.checkTypes);
9392+
check.setReportErrors(config().checkTypes);
93959393
check(ast);
93969394
}
93979395

src/parser/cxx/parser.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,6 @@ class Parser final {
6969
void operator()(UnitAST*& ast);
7070

7171
[[nodiscard]] auto config() const -> const ParserConfiguration&;
72-
void setConfig(ParserConfiguration config);
7372

7473
private:
7574
struct TemplateHeadContext;
@@ -111,7 +110,7 @@ class Parser final {
111110

112111
[[nodiscard]] auto shouldStopParsing() const -> bool {
113112
if (didAcceptCompletionToken_) return true;
114-
if (config_.stopParsingPredicate) return config_.stopParsingPredicate();
113+
if (config().stopParsingPredicate) return config().stopParsingPredicate();
115114
return false;
116115
}
117116

@@ -804,7 +803,6 @@ class Parser final {
804803
DiagnosticsClient* diagnosticClient_ = nullptr;
805804
Scope* globalScope_ = nullptr;
806805
Binder binder_;
807-
ParserConfiguration config_{};
808806
bool skipFunctionBody_ = false;
809807
bool moduleUnit_ = false;
810808
const Identifier* moduleId_ = nullptr;

src/parser/cxx/parser_fwd.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ using CodeCompletionContext =
4747
struct ParserConfiguration {
4848
bool checkTypes = false;
4949
bool fuzzyTemplateResolution = false;
50+
bool templateInstantiation = true;
5051
bool reflect = true;
5152
std::function<bool()> stopParsingPredicate;
5253
std::function<void(const CodeCompletionContext&)> complete;

src/parser/cxx/translation_unit.cc

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,12 +167,18 @@ void TranslationUnit::parse(ParserConfiguration config) {
167167
if (ast_) {
168168
cxx_runtime_error("translation unit already parsed");
169169
}
170+
171+
config_ = std::move(config);
172+
170173
preprocessor_->squeeze();
171174
Parser parse(this);
172-
parse.setConfig(std::move(config));
173175
parse(ast_);
174176
}
175177

178+
auto TranslationUnit::config() const -> const ParserConfiguration& {
179+
return config_;
180+
}
181+
176182
auto TranslationUnit::globalScope() const -> Scope* {
177183
if (!globalNamespace_) return nullptr;
178184
return globalNamespace_->scope();

src/parser/cxx/translation_unit.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ class TranslationUnit {
6868

6969
void parse(ParserConfiguration config = {});
7070

71+
[[nodiscard]] auto config() const -> const ParserConfiguration&;
72+
7173
// set source and preprocess, deprecated.
7274
void setSource(std::string source, std::string fileName);
7375

@@ -137,6 +139,7 @@ class TranslationUnit {
137139
const char* yyptr = nullptr;
138140
DiagnosticsClient* diagnosticsClient_ = nullptr;
139141
NamespaceSymbol* globalNamespace_ = nullptr;
142+
ParserConfiguration config_;
140143
};
141144

142145
} // namespace cxx

0 commit comments

Comments
 (0)