Skip to content

Commit 37d40fb

Browse files
committed
Make synthetic rule template instantiation compliant with LLVM 23
1 parent 7b5d4c5 commit 37d40fb

1 file changed

Lines changed: 90 additions & 76 deletions

File tree

cpp2rust/converter/translation_rule.cpp

Lines changed: 90 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,11 @@ class Callback : public clang::ast_matchers::MatchFinder::MatchCallback {
8282
public:
8383
explicit Callback(RuleMap &out) : out_(out) {}
8484

85-
void setSema(clang::Sema &sema) { sema_ = &sema; }
85+
void init(clang::Sema &sema) {
86+
sema_ = &sema;
87+
clang::SourceManager &sm = sema.Context.getSourceManager();
88+
loc_ = sm.getLocForStartOfFile(sm.getMainFileID());
89+
}
8690

8791
void run(const clang::ast_matchers::MatchFinder::MatchResult &R) override {
8892
assert(sema_);
@@ -182,6 +186,7 @@ class Callback : public clang::ast_matchers::MatchFinder::MatchCallback {
182186
private:
183187
RuleMap &out_;
184188
clang::Sema *sema_ = nullptr;
189+
clang::SourceLocation loc_;
185190

186191
void forceCompleteDefinition(clang::QualType type) {
187192
type = type.getCanonicalType();
@@ -193,7 +198,7 @@ class Callback : public clang::ast_matchers::MatchFinder::MatchCallback {
193198
return;
194199
}
195200

196-
sema_->RequireCompleteType(clang::SourceLocation(), type,
201+
sema_->RequireCompleteType(loc_, type,
197202
clang::Sema::CompleteTypeKind::Normal,
198203
clang::diag::err_incomplete_type);
199204

@@ -220,7 +225,7 @@ class Callback : public clang::ast_matchers::MatchFinder::MatchCallback {
220225
clang::QualType obj_t, clang::Expr::Classification exprClass,
221226
clang::TemplateArgumentListInfo *explicitArgs = nullptr) {
222227
clang::FunctionDecl *spec = nullptr;
223-
clang::sema::TemplateDeductionInfo info((clang::SourceLocation()));
228+
clang::sema::TemplateDeductionInfo info((loc_));
224229
auto check = [](llvm::ArrayRef<clang::QualType>, bool) -> bool {
225230
return false;
226231
};
@@ -238,18 +243,17 @@ class Callback : public clang::ast_matchers::MatchFinder::MatchCallback {
238243
clang::TemplateArgumentListInfo targsInfo;
239244
for (const auto &arg : deduced->asArray()) {
240245
targsInfo.addArgument(
241-
sema_->getTrivialTemplateArgumentLoc(arg, {}, {}, nullptr));
246+
sema_->getTrivialTemplateArgumentLoc(arg, {}, loc_));
242247
}
243248

244249
clang::DefaultArguments defaultArgs;
245250
clang::Sema::CheckTemplateArgumentInfo ctai;
246251
auto invalid = sema_->CheckTemplateArgumentList(
247-
decl, decl->getTemplateParameters(), clang::SourceLocation(),
248-
targsInfo, defaultArgs, true, ctai);
252+
decl, decl->getTemplateParameters(), loc_, targsInfo, defaultArgs,
253+
true, ctai);
249254

250255
if (!invalid) {
251-
return sema_->InstantiateFunctionDeclaration(decl, deduced,
252-
clang::SourceLocation());
256+
return sema_->InstantiateFunctionDeclaration(decl, deduced, loc_);
253257
}
254258
}
255259
}
@@ -260,9 +264,8 @@ class Callback : public clang::ast_matchers::MatchFinder::MatchCallback {
260264
clang::NamespaceDecl *createNamespaceDecl() {
261265
auto &ctx = sema_->getASTContext();
262266
auto *tu = ctx.getTranslationUnitDecl();
263-
auto *ns = clang::NamespaceDecl::Create(
264-
ctx, tu, false, clang::SourceLocation(), clang::SourceLocation(),
265-
nullptr, nullptr, false);
267+
auto *ns = clang::NamespaceDecl::Create(ctx, tu, false, loc_, loc_, nullptr,
268+
nullptr, false);
266269
tu->addDecl(ns);
267270
return ns;
268271
}
@@ -274,12 +277,10 @@ class Callback : public clang::ast_matchers::MatchFinder::MatchCallback {
274277
clang::MultiTemplateParamsArg args;
275278
auto decl = sema_->ActOnTag(
276279
sema_->getCurScope(), clang::DeclSpec::TST_struct,
277-
clang::TagUseKind::Definition, clang::SourceLocation(), scope,
278-
&sema_->Context.Idents.get(name), clang::SourceLocation(),
279-
clang::ParsedAttributesView(), clang::AS_none, clang::SourceLocation(),
280-
args, owned, dependent, clang::SourceLocation(), false,
281-
clang::TypeResult(), false, false, clang::OffsetOfKind::Outside,
282-
nullptr);
280+
clang::TagUseKind::Definition, loc_, scope,
281+
&sema_->Context.Idents.get(name), loc_, clang::ParsedAttributesView(),
282+
clang::AS_none, loc_, args, owned, dependent, loc_, false,
283+
clang::TypeResult(), false, false, clang::OffsetOfKind::Outside);
283284
assert(decl.isUsable() && "Record decl creation failed");
284285
auto *rdecl = decl.getAs<clang::RecordDecl>();
285286
rdecl->startDefinition();
@@ -290,20 +291,18 @@ class Callback : public clang::ast_matchers::MatchFinder::MatchCallback {
290291
clang::VarDecl *createVarDecl(clang::QualType type, llvm::StringRef name,
291292
clang::StorageClass sclass = clang::SC_None) {
292293
clang::ASTContext &ctx = sema_->Context;
293-
clang::VarDecl *decl =
294-
clang::VarDecl::Create(ctx, sema_->CurContext, clang::SourceLocation(),
295-
clang::SourceLocation(), &ctx.Idents.get(name),
296-
type.getNonReferenceType(), nullptr, sclass);
294+
clang::VarDecl *decl = clang::VarDecl::Create(
295+
ctx, sema_->CurContext, loc_, loc_, &ctx.Idents.get(name),
296+
type.getNonReferenceType(), nullptr, sclass);
297297
sema_->CurContext->addDecl(decl);
298298
decl->markUsed(ctx);
299299
return decl;
300300
}
301301

302302
clang::DeclRefExpr *createDeclRefExpr(clang::VarDecl *decl) {
303-
return clang::DeclRefExpr::Create(
304-
sema_->Context, clang::NestedNameSpecifierLoc(),
305-
clang::SourceLocation(), decl, false, clang::SourceLocation(),
306-
decl->getType().getCanonicalType(), clang::VK_LValue);
303+
const clang::DeclarationNameInfo nameInfo(decl->getDeclName(), loc_);
304+
return sema_->BuildDeclRefExpr(decl, decl->getType(), clang::VK_LValue,
305+
nameInfo, decl->getQualifierLoc());
307306
}
308307

309308
clang::DeclRefExpr *createConstexprDeclRefExpr(clang::QualType type,
@@ -314,7 +313,8 @@ class Callback : public clang::ast_matchers::MatchFinder::MatchCallback {
314313
clang::Expr *init;
315314
clang::ASTContext &ctx = sema_->Context;
316315
if (type->isIntegerType()) {
317-
init = clang::IntegerLiteral::Create(ctx, llvm::APInt(1, 1), type, {});
316+
init = clang::IntegerLiteral::Create(
317+
ctx, llvm::APInt(ctx.getIntWidth(type), 1), type, loc_);
318318
} else {
319319
init = new (ctx) clang::ImplicitValueInitExpr(type);
320320
}
@@ -324,7 +324,7 @@ class Callback : public clang::ast_matchers::MatchFinder::MatchCallback {
324324

325325
clang::OpaqueValueExpr *createOpaqueValueExpr(clang::QualType type) {
326326
return new (sema_->Context) clang::OpaqueValueExpr(
327-
{}, type.getNonReferenceType(),
327+
loc_, type.getNonReferenceType(),
328328
type->isRValueReferenceType() ? clang::VK_XValue : clang::VK_LValue);
329329
}
330330

@@ -334,8 +334,9 @@ class Callback : public clang::ast_matchers::MatchFinder::MatchCallback {
334334
for (clang::NamedDecl *param : *decl->getTemplateParameters()) {
335335
if (llvm::isa<clang::TemplateTypeParmDecl>(param)) {
336336
clang::RecordDecl *rdecl = createRecordDecl(param->getName());
337-
clang::QualType type = sema_->Context.getTagType(
338-
clang::ElaboratedTypeKeyword::None, {}, rdecl, false);
337+
clang::QualType type =
338+
sema_->Context.getTagType(clang::ElaboratedTypeKeyword::None,
339+
rdecl->getQualifier(), rdecl, false);
339340
out.emplace_back(type);
340341
} else if (const auto *nttp =
341342
llvm::dyn_cast<clang::NonTypeTemplateParmDecl>(param)) {
@@ -354,7 +355,7 @@ class Callback : public clang::ast_matchers::MatchFinder::MatchCallback {
354355
createTemplateArguments(decl, args);
355356
return sema_->InstantiateFunctionDeclaration(
356357
decl, clang::TemplateArgumentList::CreateCopy(sema_->Context, args),
357-
clang::SourceLocation());
358+
loc_);
358359
}
359360

360361
clang::FunctionDecl *createCandidate(
@@ -374,8 +375,8 @@ class Callback : public clang::ast_matchers::MatchFinder::MatchCallback {
374375

375376
clang::CXXRecordDecl *resolveCXXRecordDecl(clang::QualType obj_t) {
376377
obj_t = obj_t.getCanonicalType();
377-
if (obj_t->isReferenceType()) {
378-
obj_t = obj_t.getNonReferenceType();
378+
while (obj_t->isPointerOrReferenceType()) {
379+
obj_t = obj_t->getPointeeType();
379380
}
380381

381382
forceCompleteDefinition(obj_t);
@@ -389,7 +390,7 @@ class Callback : public clang::ast_matchers::MatchFinder::MatchCallback {
389390
clang::TemplateArgumentListInfo *explicitTArgs,
390391
clang::DeclarationName &name,
391392
clang::OverloadCandidateSet &candidates) {
392-
clang::LookupResult decls(*sema_, name, clang::SourceLocation(),
393+
clang::LookupResult decls(*sema_, name, loc_,
393394
clang::Sema::LookupOrdinaryName);
394395
sema_->LookupQualifiedName(decls, sema_->getStdNamespace());
395396
for (auto *ndecl : decls) {
@@ -430,7 +431,7 @@ class Callback : public clang::ast_matchers::MatchFinder::MatchCallback {
430431
clang::OverloadCandidateSet &candidates) {
431432
clang::CXXRecordDecl *rdecl = resolveCXXRecordDecl(obj_t);
432433
assert(rdecl && "Failed fetching record decl");
433-
clang::LookupResult members(*sema_, name, clang::SourceLocation(),
434+
clang::LookupResult members(*sema_, name, loc_,
434435
clang::Sema::LookupMemberName);
435436
sema_->LookupQualifiedName(members, rdecl);
436437

@@ -465,7 +466,7 @@ class Callback : public clang::ast_matchers::MatchFinder::MatchCallback {
465466
clang::DeclarationName &name,
466467
clang::OverloadCandidateSet &candidates) {
467468
clang::ADLResult adl;
468-
sema_->ArgumentDependentLookup(name, {}, callArgs, adl);
469+
sema_->ArgumentDependentLookup(name, loc_, callArgs, adl);
469470

470471
for (auto *ndecl : adl) {
471472
if (auto *candidate = createCandidate(ndecl, callArgs)) {
@@ -497,42 +498,50 @@ class Callback : public clang::ast_matchers::MatchFinder::MatchCallback {
497498
llvm::ArrayRef<clang::TemplateArgument> ruleTArgs =
498499
rule->getTemplateSpecializationArgs()->asArray();
499500
clang::TemplateArgumentListInfo explicitTArgs;
500-
for (const auto &argloc : lookup.explicitArgs) {
501-
const auto &arg = argloc.getArgument();
502-
if (!arg.isDependent()) {
503-
explicitTArgs.addArgument(argloc);
504-
continue;
505-
}
506501

507-
clang::TemplateArgument inst;
508-
if (arg.getKind() == clang::TemplateArgument::Type) {
509-
clang::QualType type = arg.getAsType();
510-
clang::MultiLevelTemplateArgumentList mtal(nullptr, ruleTArgs, false);
511-
mtal.setKind(clang::TemplateSubstitutionKind::Rewrite);
512-
clang::TypeSourceInfo *tsi =
513-
sema_->SubstType(sema_->Context.getTrivialTypeSourceInfo(type),
514-
mtal, {}, clang::DeclarationName());
515-
assert(tsi && "Template argument type instantiation failed");
516-
inst = clang::TemplateArgument(tsi->getType());
517-
} else if (arg.getKind() == clang::TemplateArgument::Expression) {
518-
if (auto *expr = llvm::dyn_cast<clang::DeclRefExpr>(arg.getAsExpr())) {
519-
const auto *nttp =
520-
llvm::dyn_cast<clang::NonTypeTemplateParmDecl>(expr->getDecl());
521-
assert(nttp && "Unexpected decl in expr");
522-
inst = ruleTArgs[nttp->getIndex()];
502+
{
503+
clang::Sema::InstantiatingTemplate Inst(*sema_, loc_, decl);
504+
assert(!Inst.isInvalid() && "Invalid instantiation context");
505+
for (const auto &argloc : lookup.explicitArgs) {
506+
const auto &arg = argloc.getArgument();
507+
if (!arg.isDependent()) {
508+
explicitTArgs.addArgument(argloc);
509+
continue;
510+
}
511+
512+
clang::TemplateArgument inst;
513+
if (arg.getKind() == clang::TemplateArgument::Type) {
514+
clang::QualType type = arg.getAsType();
515+
clang::MultiLevelTemplateArgumentList mtal;
516+
mtal.setKind(clang::TemplateSubstitutionKind::Rewrite);
517+
mtal.addOuterTemplateArguments(ruleTArgs);
518+
519+
clang::TypeSourceInfo *tsi =
520+
sema_->SubstType(sema_->Context.getTrivialTypeSourceInfo(type),
521+
mtal, loc_, clang::DeclarationName());
522+
assert(tsi && "Template argument type instantiation failed");
523+
inst = clang::TemplateArgument(tsi->getType());
524+
} else if (arg.getKind() == clang::TemplateArgument::Expression) {
525+
if (auto *expr =
526+
llvm::dyn_cast<clang::DeclRefExpr>(arg.getAsExpr())) {
527+
const auto *nttp =
528+
llvm::dyn_cast<clang::NonTypeTemplateParmDecl>(expr->getDecl());
529+
assert(nttp && "Unexpected decl in expr");
530+
inst = ruleTArgs[nttp->getIndex()];
531+
} else {
532+
assert(0 && "Unsupported explicit template argument expression");
533+
}
523534
} else {
524-
assert(0 && "Unsupported explicit template argument expression");
535+
assert(0 && "Unsupported explicit template argument kind");
525536
}
526-
} else {
527-
assert(0 && "Unsupported explicit template argument kind");
528-
}
529537

530-
explicitTArgs.addArgument(
531-
sema_->getTrivialTemplateArgumentLoc(inst, {}, {}, nullptr));
538+
explicitTArgs.addArgument(
539+
sema_->getTrivialTemplateArgumentLoc(inst, {}, loc_));
540+
}
532541
}
533542

534543
clang::DeclarationName &name = lookup.name;
535-
clang::OverloadCandidateSet candidates(clang::SourceLocation(), csk);
544+
clang::OverloadCandidateSet candidates(loc_, csk);
536545
switch (lookup.kind) {
537546
case LookupKind::RegularName:
538547
regularNameLookup(callArgs, &explicitTArgs, name, candidates);
@@ -552,8 +561,7 @@ class Callback : public clang::ast_matchers::MatchFinder::MatchCallback {
552561
}
553562

554563
clang::OverloadCandidateSet::iterator best;
555-
switch (
556-
candidates.BestViableFunction(*sema_, clang::SourceLocation(), best)) {
564+
switch (candidates.BestViableFunction(*sema_, loc_, best)) {
557565
case clang::OverloadingResult::OR_Success:
558566
return best->Function;
559567
case clang::OverloadingResult::OR_Ambiguous:
@@ -583,7 +591,7 @@ class Callback : public clang::ast_matchers::MatchFinder::MatchCallback {
583591
clang::CXXRecordDecl *rdecl =
584592
resolveCXXRecordDecl(rule->getParamDecl(0)->getType());
585593
assert(rdecl && "Failed fetching record decl");
586-
clang::LookupResult members(*sema_, name, clang::SourceLocation(),
594+
clang::LookupResult members(*sema_, name, loc_,
587595
clang::Sema::LookupMemberName);
588596
sema_->LookupQualifiedName(members, rdecl);
589597
assert(!members.empty() && "Rule resolution failed");
@@ -600,8 +608,8 @@ class Callback : public clang::ast_matchers::MatchFinder::MatchCallback {
600608

601609
clang::Expr *obj = createOpaqueValueExpr(
602610
rule->getParamDecl(0)->getType().getNonReferenceType());
603-
auto arrow = sema_->BuildOverloadedArrowExpr(sema_->getCurScope(), obj,
604-
clang::SourceLocation());
611+
auto arrow =
612+
sema_->BuildOverloadedArrowExpr(sema_->getCurScope(), obj, loc_);
605613
assert(arrow.isUsable() && "Overloaded arrow operator not found");
606614

607615
auto *base = arrow.getAs<clang::CXXOperatorCallExpr>();
@@ -611,15 +619,14 @@ class Callback : public clang::ast_matchers::MatchFinder::MatchCallback {
611619
resolveCXXRecordDecl(base->getType()->getPointeeType());
612620
assert(rdecl && "Failed fetching record decl");
613621

614-
clang::LookupResult members(*sema_, nameInfo.getName(),
615-
clang::SourceLocation(),
622+
clang::LookupResult members(*sema_, nameInfo.getName(), loc_,
616623
clang::Sema::LookupMemberName);
617624
sema_->LookupQualifiedName(members, rdecl);
618625
for (auto *ndecl : members) {
619626
if (auto *vdecl = llvm::dyn_cast<clang::ValueDecl>(ndecl)) {
620627
clang::MemberExpr *access = sema_->BuildMemberExpr(
621-
base, true, clang::SourceLocation(), nns, clang::SourceLocation(),
622-
vdecl, clang::DeclAccessPair::make(vdecl, clang::AS_public), false,
628+
base, true, loc_, nns, loc_, vdecl,
629+
clang::DeclAccessPair::make(vdecl, clang::AS_public), false,
623630
nameInfo, vdecl->getType(), clang::VK_LValue, clang::OK_Ordinary);
624631
assert(access && "Rule resolution failed");
625632
return access;
@@ -632,13 +639,20 @@ class Callback : public clang::ast_matchers::MatchFinder::MatchCallback {
632639
clang::QualType lookupType(clang::TypeAliasTemplateDecl *decl) {
633640
clang::NamespaceDecl *ns = createNamespaceDecl();
634641
clang::Sema::ContextRAII savedContext(*sema_, ns);
642+
635643
llvm::SmallVector<clang::TemplateArgument, 4> args;
636644
createTemplateArguments(decl, args);
637645

638-
clang::MultiLevelTemplateArgumentList mtal(nullptr, args, false);
646+
clang::MultiLevelTemplateArgumentList mtal;
647+
mtal.setKind(clang::TemplateSubstitutionKind::Rewrite);
648+
mtal.addOuterTemplateArguments(args);
649+
650+
clang::Sema::InstantiatingTemplate TypeInst(*sema_, loc_, decl, args);
651+
assert(!TypeInst.isInvalid() && "Invalid instantiation context");
652+
639653
clang::TypeSourceInfo *tsi =
640654
sema_->SubstType(decl->getTemplatedDecl()->getTypeSourceInfo(), mtal,
641-
{}, clang::DeclarationName());
655+
loc_, clang::DeclarationName());
642656
assert(tsi && "Rule resolution failed");
643657
return tsi->getType();
644658
}
@@ -688,7 +702,7 @@ class ActionFactory : public clang::tooling::FrontendActionFactory {
688702
auto &DE = CI_->getDiagnostics();
689703
DE.setSuppressAllDiagnostics(true);
690704
DE.setClient(new clang::IgnoringDiagConsumer(), true);
691-
CB_->setSema(CI_->getSema());
705+
CB_->init(CI_->getSema());
692706
AC_->HandleTranslationUnit(ctx);
693707
}
694708

0 commit comments

Comments
 (0)