[clang] [llvm] Ast importer visitors (PR #138838)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 9 01:41:20 PDT 2025
https://github.com/ganenkokb-yandex updated https://github.com/llvm/llvm-project/pull/138838
>From 0a5beb71cb46ad5ef2df753098a6742ffeef3a71 Mon Sep 17 00:00:00 2001
From: Evianaive <153540933 at qq.com>
Date: Tue, 25 Mar 2025 01:54:06 +0800
Subject: [PATCH 1/8] Implement missing visit function
---
clang/lib/AST/ASTImporter.cpp | 285 +++++++++++++++++++++++++++++++++-
1 file changed, 284 insertions(+), 1 deletion(-)
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index 003bad225e30c..775e9b83d1fb1 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -68,6 +68,7 @@
#include <optional>
#include <type_traits>
#include <utility>
+#include "ExprConcepts.h"
namespace clang {
@@ -564,6 +565,9 @@ namespace clang {
ExpectedDecl VisitVarTemplateDecl(VarTemplateDecl *D);
ExpectedDecl VisitVarTemplateSpecializationDecl(VarTemplateSpecializationDecl *D);
ExpectedDecl VisitFunctionTemplateDecl(FunctionTemplateDecl *D);
+ ExpectedDecl VisitConceptDecl(ConceptDecl* D);
+ ExpectedDecl VisitRequiresExprBodyDecl(RequiresExprBodyDecl* E);
+ ExpectedDecl VisitImplicitConceptSpecializationDecl(ImplicitConceptSpecializationDecl* D);
// Importing statements
ExpectedStmt VisitStmt(Stmt *S);
@@ -680,6 +684,8 @@ namespace clang {
ExpectedStmt VisitTypeTraitExpr(TypeTraitExpr *E);
ExpectedStmt VisitCXXTypeidExpr(CXXTypeidExpr *E);
ExpectedStmt VisitCXXFoldExpr(CXXFoldExpr *E);
+ ExpectedStmt VisitRequiresExpr(RequiresExpr* E);
+ ExpectedStmt VisitConceptSpecializationExpr(ConceptSpecializationExpr* E);
// Helper for chaining together multiple imports. If an error is detected,
// subsequent imports will return default constructed nodes, so that failure
@@ -1063,6 +1069,168 @@ Expected<LambdaCapture> ASTNodeImporter::import(const LambdaCapture &From) {
EllipsisLoc);
}
+template<>
+Expected<concepts::Requirement*> ASTNodeImporter::import(concepts::Requirement* FromRequire) {
+ auto ImportStringRef = [this](const StringRef& FromString) {
+ char* ToDiagMessage = new (Importer.getToContext()) char[FromString.size()];
+ std::copy(FromString.begin(),FromString.end(),ToDiagMessage);
+ return StringRef(ToDiagMessage,FromString.size());
+ };
+
+ auto ImportSubstitutionDiagnos = [this, &ImportStringRef]
+ (concepts::Requirement::SubstitutionDiagnostic* FromDiagnos, Error& Err)->concepts::Requirement::SubstitutionDiagnostic* {
+ const auto& ToEntity = ImportStringRef(FromDiagnos->SubstitutedEntity);
+ Expected<SourceLocation> ToLoc = import(FromDiagnos->DiagLoc);
+ if(!ToLoc) {
+ Err = ToLoc.takeError();
+ return nullptr;
+ }
+ const auto& ToDiagMessage = ImportStringRef(FromDiagnos->DiagMessage);
+ return new (Importer.getToContext()) concepts::Requirement::SubstitutionDiagnostic{
+ ToEntity,
+ ToLoc.get(),
+ ToDiagMessage};
+ };
+ switch (FromRequire->getKind()) {
+ case concepts::Requirement::RequirementKind::RK_Type: {
+ auto *From = cast<concepts::TypeRequirement>(FromRequire);
+ if(From->isSubstitutionFailure())
+ {
+ // Should we return Error directly if TypeRequirement isSubstitutionFailure?
+ Error Err = Error::success();
+ auto Diagnos = ImportSubstitutionDiagnos(From->getSubstitutionDiagnostic(),Err);
+ if (Err)
+ return std::move(Err);
+ return new (Importer.getToContext()) concepts::TypeRequirement(Diagnos);
+ }
+ else {
+ Expected<TypeSourceInfo *> ToType = import(From->getType());
+ if(!ToType)
+ return ToType.takeError();
+ return new (Importer.getToContext()) concepts::TypeRequirement(ToType.get());
+ }
+ break;
+ }
+ case concepts::Requirement::RequirementKind::RK_Compound:
+ case concepts::Requirement::RequirementKind::RK_Simple: {
+ const auto *From = cast<concepts::ExprRequirement>(FromRequire);
+
+ auto Status = From->getSatisfactionStatus();
+ llvm::PointerUnion<concepts::Requirement::SubstitutionDiagnostic *, Expr *> E;
+ if (Status == concepts::ExprRequirement::SS_ExprSubstitutionFailure) {
+ Error Err = Error::success();
+ E = ImportSubstitutionDiagnos(From->getExprSubstitutionDiagnostic(),Err);
+ if (Err)
+ return std::move(Err);
+ } else {
+ auto ExpectE = import(From->getExpr());
+ if (!ExpectE)
+ return ExpectE.takeError();
+ E = ExpectE.get();
+ }
+
+ std::optional<concepts::ExprRequirement::ReturnTypeRequirement> Req;
+ ConceptSpecializationExpr *SubstitutedConstraintExpr = nullptr;
+ SourceLocation NoexceptLoc;
+ bool IsRKSimple = FromRequire->getKind() == concepts::Requirement::RK_Simple;
+ if (IsRKSimple) {
+ Req.emplace();
+ } else {
+ auto NoexceptLoc = import(From->getNoexceptLoc());
+ if(!NoexceptLoc)
+ return NoexceptLoc.takeError();
+ auto& FromTypeRequirement = From->getReturnTypeRequirement();
+
+ if(FromTypeRequirement.isTypeConstraint()) {
+ auto ParamsOrErr = import(FromTypeRequirement.getTypeConstraintTemplateParameterList());
+ if (!ParamsOrErr)
+ return ParamsOrErr.takeError();
+ if (Status >=
+ concepts::ExprRequirement::SS_ConstraintsNotSatisfied) {
+ auto ExpectSubstitutedConstraintExpr = import(From->getReturnTypeRequirementSubstitutedConstraintExpr());
+ if (!ExpectSubstitutedConstraintExpr)
+ return ExpectSubstitutedConstraintExpr.takeError();
+ SubstitutedConstraintExpr = ExpectSubstitutedConstraintExpr.get();
+ }
+ Req.emplace(ParamsOrErr.get());
+ }
+ else if(FromTypeRequirement.isSubstitutionFailure()) {
+ Error Err = Error::success();
+ concepts::Requirement::SubstitutionDiagnostic *ToDiagnos =
+ ImportSubstitutionDiagnos(
+ FromTypeRequirement.getSubstitutionDiagnostic(), Err);
+ if (Err)
+ return std::move(Err);
+ Req.emplace(ToDiagnos);
+ }
+ else {
+ Req.emplace();
+ }
+ }
+ if (Expr *Ex = E.dyn_cast<Expr *>())
+ return new (Importer.getToContext()) concepts::ExprRequirement(
+ Ex, IsRKSimple, NoexceptLoc,
+ std::move(*Req), Status, SubstitutedConstraintExpr);
+ else
+ return new (Importer.getToContext()) concepts::ExprRequirement(
+ E.get<concepts::Requirement::SubstitutionDiagnostic *>(),
+ IsRKSimple, NoexceptLoc,
+ std::move(*Req));
+ break;
+ }
+ case concepts::Requirement::RequirementKind::RK_Nested: {
+ auto *From = cast<concepts::NestedRequirement>(FromRequire);
+ const auto& FromSatisfaction = From->getConstraintSatisfaction();
+ if(From->hasInvalidConstraint()) {
+ const auto& ToConstraintEntity = ImportStringRef(From->getInvalidConstraintEntity());
+ auto ToSatisfaction = ASTConstraintSatisfaction::Rebuild(Importer.getToContext(),FromSatisfaction);
+ return new (Importer.getToContext()) concepts::NestedRequirement(ToConstraintEntity,ToSatisfaction);
+ } else {
+ Expected<Expr *> ToExpr = import(From->getConstraintExpr());
+ if(!ToExpr)
+ return ToExpr.takeError();
+ // FromSatisfaction.IsSatisfied;
+ if(ToExpr.get()->isInstantiationDependent())
+ return new (Importer.getToContext()) concepts::NestedRequirement(ToExpr.get());
+ else {
+ ConstraintSatisfaction Satisfaction;
+ Satisfaction.IsSatisfied = FromSatisfaction.IsSatisfied;
+ Satisfaction.ContainsErrors = FromSatisfaction.ContainsErrors;
+ if (!Satisfaction.IsSatisfied) {
+ for (auto Record = FromSatisfaction.begin(); Record != FromSatisfaction.end(); ++Record) {
+ const Expr *ConstraintExpr = Record->first;
+ Expected<Expr *> ToConstraintExpr = import(ConstraintExpr);
+ if(!ToConstraintExpr)
+ return ToConstraintExpr.takeError();
+ if(Record->second.is<Expr*>()) {
+ Expected<Expr *> ToSecondExpr = import(Record->second.get<Expr*>());
+ if(!ToSecondExpr)
+ return ToSecondExpr.takeError();
+ Satisfaction.Details.emplace_back(ToConstraintExpr.get(),ToSecondExpr.get());
+ } else {
+ std::pair<SourceLocation, StringRef> *pair = Record->second.get<
+ std::pair<SourceLocation, StringRef> *>();
+ Error Err = Error::success();
+
+ auto ToPairFirst = import(pair->first);
+ if(!ToPairFirst)
+ return ToPairFirst.takeError();
+ StringRef ToPairSecond = ImportStringRef(pair->second);
+ Satisfaction.Details.emplace_back(
+ ToConstraintExpr.get(), new (Importer.getToContext())
+ ConstraintSatisfaction::SubstitutionDiagnostic{
+ ToPairFirst.get(), ToPairSecond});
+ }
+ }
+ }
+ return new (Importer.getToContext()) concepts::NestedRequirement(Importer.getToContext(),ToExpr.get(),Satisfaction);
+ }
+ }
+ break;
+ }
+ }
+}
+
template <typename T>
bool ASTNodeImporter::hasSameVisibilityContextAndLinkage(T *Found, T *From) {
if (Found->getLinkageInternal() != From->getLinkageInternal())
@@ -7359,6 +7527,121 @@ ExpectedStmt ASTNodeImporter::VisitExpr(Expr *E) {
return make_error<ASTImportError>(ASTImportError::UnsupportedConstruct);
}
+ExpectedStmt ASTNodeImporter::VisitRequiresExpr(RequiresExpr* E) {
+ Error Err = Error::success();
+ // auto ToType = importChecked(Err, E->getType());
+ auto RequiresKWLoc = importChecked(Err,E->getRequiresKWLoc());
+ auto RParenLoc = importChecked(Err,E->getRParenLoc());
+ auto RBraceLoc = importChecked(Err,E->getRBraceLoc());
+
+ auto Body = importChecked(Err,E->getBody());
+ auto LParenLoc = importChecked(Err,E->getLParenLoc());
+ if(Err)
+ return std::move(Err);
+ SmallVector<ParmVarDecl*, 4> LocalParameters;
+ if (Error Err = ImportArrayChecked(E->getLocalParameters(),LocalParameters.begin()))
+ return std::move(Err);
+ SmallVector<concepts::Requirement*, 4> Requirements;
+ if (Error Err = ImportArrayChecked(E->getRequirements(),Requirements.begin()))
+ return std::move(Err);
+ return RequiresExpr::Create(Importer.getToContext(),RequiresKWLoc, Body, LParenLoc,
+ LocalParameters, RParenLoc, Requirements, RBraceLoc);
+}
+
+ExpectedDecl ASTNodeImporter::VisitRequiresExprBodyDecl(RequiresExprBodyDecl* D) {
+ DeclContext *DC, *LexicalDC;
+ Error Err = Error::success();
+ Err = ImportDeclContext(D, DC, LexicalDC);
+ auto RequiresLoc = importChecked(Err,D->getLocation());
+ return RequiresExprBodyDecl::Create(Importer.getToContext(),DC,RequiresLoc);
+}
+
+ExpectedStmt ASTNodeImporter::VisitConceptSpecializationExpr(ConceptSpecializationExpr* E) {
+ Error Err = Error::success();
+
+ auto CL = importChecked(Err,E->getConceptReference());
+ auto CSD = importChecked(Err,E->getSpecializationDecl());
+ // auto Satisfaction = importChecked(Err,E->getSatisfaction());
+ if (Err)
+ return std::move(Err);
+ // E->getDependence();
+ if(E->isValueDependent()) {
+ return ConceptSpecializationExpr::Create(
+ Importer.getToContext(), CL,
+ const_cast<ImplicitConceptSpecializationDecl *>(CSD), nullptr);
+ }
+ const auto& FromSatisfaction = E->getSatisfaction();
+ auto ImportStringRef = [this](const StringRef& FromString) {
+ char* ToDiagMessage = new (Importer.getToContext()) char[FromString.size()];
+ std::copy(FromString.begin(),FromString.end(),ToDiagMessage);
+ return StringRef(ToDiagMessage,FromString.size());
+ };
+ ConstraintSatisfaction Satisfaction;
+ Satisfaction.IsSatisfied = FromSatisfaction.IsSatisfied;
+ Satisfaction.ContainsErrors = FromSatisfaction.ContainsErrors;
+ if (!Satisfaction.IsSatisfied) {
+ for (auto Record = FromSatisfaction.begin(); Record != FromSatisfaction.end(); ++Record) {
+ const Expr *ConstraintExpr = Record->first;
+ Expected<Expr *> ToConstraintExpr = import(ConstraintExpr);
+ if(!ToConstraintExpr)
+ return ToConstraintExpr.takeError();
+ if(Record->second.is<Expr*>()) {
+ Expected<Expr *> ToSecondExpr = import(Record->second.get<Expr*>());
+ if(!ToSecondExpr)
+ return ToSecondExpr.takeError();
+ Satisfaction.Details.emplace_back(ToConstraintExpr.get(),ToSecondExpr.get());
+ } else {
+ std::pair<SourceLocation, StringRef> *pair = Record->second.get<
+ std::pair<SourceLocation, StringRef> *>();
+ Error Err = Error::success();
+
+ auto ToPairFirst = import(pair->first);
+ if(!ToPairFirst)
+ return ToPairFirst.takeError();
+ StringRef ToPairSecond = ImportStringRef(pair->second);
+ Satisfaction.Details.emplace_back(
+ ToConstraintExpr.get(), new(Importer.getToContext()) ConstraintSatisfaction::SubstitutionDiagnostic{
+ ToPairFirst.get(), ToPairSecond});
+ }
+ }
+ }
+ return ConceptSpecializationExpr::Create(
+ Importer.getToContext(), CL,
+ const_cast<ImplicitConceptSpecializationDecl *>(CSD), &Satisfaction);
+}
+
+ExpectedDecl ASTNodeImporter::VisitConceptDecl(ConceptDecl* D) {
+ // Import the context of this declaration.
+ DeclContext *DC, *LexicalDC;
+ Error Err = Error::success();
+ Err = ImportDeclContext(D, DC, LexicalDC);
+ auto BeginLocOrErr = importChecked(Err, D->getBeginLoc());
+ auto LocationOrErr = importChecked(Err, D->getLocation());
+ auto NameDeclOrErr = importChecked(Err,D->getDeclName());
+ auto ToTemplateParameters = importChecked(Err, D->getTemplateParameters());
+ auto ConstraintExpr = importChecked(Err, D->getConstraintExpr());
+ if(Err)
+ return std::move(Err);
+ return ConceptDecl::Create(
+ Importer.getToContext(),DC,
+ LocationOrErr,NameDeclOrErr,
+ ToTemplateParameters,ConstraintExpr);
+}
+
+ExpectedDecl ASTNodeImporter::VisitImplicitConceptSpecializationDecl(ImplicitConceptSpecializationDecl* D) {
+ DeclContext *DC, *LexicalDC;
+ Error Err = Error::success();
+ Err = ImportDeclContext(D, DC, LexicalDC);
+ auto ToSL = importChecked(Err,D->getLocation());
+ if(Err)
+ return std::move(Err);
+ SmallVector<TemplateArgument,2> ToArgs;
+ if(Error Err = ImportTemplateArguments(D->getTemplateArguments(),ToArgs))
+ return std::move(Err);
+
+ return ImplicitConceptSpecializationDecl::Create(Importer.getToContext(),DC,ToSL,ToArgs);
+}
+
ExpectedStmt ASTNodeImporter::VisitSourceLocExpr(SourceLocExpr *E) {
Error Err = Error::success();
auto ToType = importChecked(Err, E->getType());
@@ -10584,4 +10867,4 @@ bool ASTImporter::IsStructurallyEquivalent(QualType From, QualType To,
getToContext().getLangOpts(), FromContext, ToContext, NonEquivalentDecls,
getStructuralEquivalenceKind(*this), false, Complain);
return Ctx.IsEquivalent(From, To);
-}
+}
\ No newline at end of file
>From 9cb45bbaf96f15531efbed443d46d28846f53e0f Mon Sep 17 00:00:00 2001
From: Konstantin Ganenko <ganenkokb at yandex-team.ru>
Date: Tue, 6 May 2025 18:36:49 +0300
Subject: [PATCH 2/8] Fix patch compilation
---
clang/lib/AST/ASTImporter.cpp | 102 ++++++++++++++--------------------
1 file changed, 42 insertions(+), 60 deletions(-)
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index 775e9b83d1fb1..ec1bd5737f9a0 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -68,7 +68,6 @@
#include <optional>
#include <type_traits>
#include <utility>
-#include "ExprConcepts.h"
namespace clang {
@@ -741,6 +740,40 @@ namespace clang {
// that type is declared inside the body of the function.
// E.g. auto f() { struct X{}; return X(); }
bool hasReturnTypeDeclaredInside(FunctionDecl *D);
+
+ Expected<ConstraintSatisfaction> FillConstraintSatisfaction(const ASTConstraintSatisfaction& from) {
+ auto ImportStringRef = [this](const StringRef& FromString) {
+ char* ToDiagMessage = new (Importer.getToContext()) char[FromString.size()];
+ std::copy(FromString.begin(),FromString.end(),ToDiagMessage);
+ return StringRef(ToDiagMessage,FromString.size());
+ };
+ ConstraintSatisfaction Satisfaction;
+ Satisfaction.IsSatisfied = from.IsSatisfied;
+ Satisfaction.ContainsErrors = from.ContainsErrors;
+ if (!Satisfaction.IsSatisfied) {
+ using SubstitutionDiagnostic = std::pair<SourceLocation, StringRef>;
+ for (auto &Record : from) {
+ if (auto *SubstDiag = Record.dyn_cast<SubstitutionDiagnostic *>()) {
+ Error Err = Error::success();
+
+ auto ToPairFirst = import(SubstDiag->first);
+ if(!ToPairFirst)
+ return ToPairFirst.takeError();
+ StringRef ToPairSecond = ImportStringRef(SubstDiag->second);
+ Satisfaction.Details.emplace_back(new (Importer.getToContext())
+ ConstraintSatisfaction::SubstitutionDiagnostic{
+ ToPairFirst.get(), ToPairSecond});
+ } else {
+ const Expr *ConstraintExpr = Record.dyn_cast<Expr *>();
+ Expected<Expr *> ToConstraintExpr = import(ConstraintExpr);
+ if(!ToConstraintExpr)
+ return ToConstraintExpr.takeError();
+ Satisfaction.Details.emplace_back(ToConstraintExpr.get());
+ }
+ }
+ }
+ return Satisfaction;
+ }
};
template <typename InContainerTy>
@@ -1193,37 +1226,11 @@ Expected<concepts::Requirement*> ASTNodeImporter::import(concepts::Requirement*
if(ToExpr.get()->isInstantiationDependent())
return new (Importer.getToContext()) concepts::NestedRequirement(ToExpr.get());
else {
- ConstraintSatisfaction Satisfaction;
- Satisfaction.IsSatisfied = FromSatisfaction.IsSatisfied;
- Satisfaction.ContainsErrors = FromSatisfaction.ContainsErrors;
- if (!Satisfaction.IsSatisfied) {
- for (auto Record = FromSatisfaction.begin(); Record != FromSatisfaction.end(); ++Record) {
- const Expr *ConstraintExpr = Record->first;
- Expected<Expr *> ToConstraintExpr = import(ConstraintExpr);
- if(!ToConstraintExpr)
- return ToConstraintExpr.takeError();
- if(Record->second.is<Expr*>()) {
- Expected<Expr *> ToSecondExpr = import(Record->second.get<Expr*>());
- if(!ToSecondExpr)
- return ToSecondExpr.takeError();
- Satisfaction.Details.emplace_back(ToConstraintExpr.get(),ToSecondExpr.get());
- } else {
- std::pair<SourceLocation, StringRef> *pair = Record->second.get<
- std::pair<SourceLocation, StringRef> *>();
- Error Err = Error::success();
-
- auto ToPairFirst = import(pair->first);
- if(!ToPairFirst)
- return ToPairFirst.takeError();
- StringRef ToPairSecond = ImportStringRef(pair->second);
- Satisfaction.Details.emplace_back(
- ToConstraintExpr.get(), new (Importer.getToContext())
- ConstraintSatisfaction::SubstitutionDiagnostic{
- ToPairFirst.get(), ToPairSecond});
- }
- }
+ auto expected_satisfaction = FillConstraintSatisfaction(FromSatisfaction);
+ if (!expected_satisfaction) {
+ return expected_satisfaction.takeError();
}
- return new (Importer.getToContext()) concepts::NestedRequirement(Importer.getToContext(),ToExpr.get(),Satisfaction);
+ return new (Importer.getToContext()) concepts::NestedRequirement(Importer.getToContext(),ToExpr.get(), *expected_satisfaction);
}
}
break;
@@ -7576,38 +7583,13 @@ ExpectedStmt ASTNodeImporter::VisitConceptSpecializationExpr(ConceptSpecializati
std::copy(FromString.begin(),FromString.end(),ToDiagMessage);
return StringRef(ToDiagMessage,FromString.size());
};
- ConstraintSatisfaction Satisfaction;
- Satisfaction.IsSatisfied = FromSatisfaction.IsSatisfied;
- Satisfaction.ContainsErrors = FromSatisfaction.ContainsErrors;
- if (!Satisfaction.IsSatisfied) {
- for (auto Record = FromSatisfaction.begin(); Record != FromSatisfaction.end(); ++Record) {
- const Expr *ConstraintExpr = Record->first;
- Expected<Expr *> ToConstraintExpr = import(ConstraintExpr);
- if(!ToConstraintExpr)
- return ToConstraintExpr.takeError();
- if(Record->second.is<Expr*>()) {
- Expected<Expr *> ToSecondExpr = import(Record->second.get<Expr*>());
- if(!ToSecondExpr)
- return ToSecondExpr.takeError();
- Satisfaction.Details.emplace_back(ToConstraintExpr.get(),ToSecondExpr.get());
- } else {
- std::pair<SourceLocation, StringRef> *pair = Record->second.get<
- std::pair<SourceLocation, StringRef> *>();
- Error Err = Error::success();
-
- auto ToPairFirst = import(pair->first);
- if(!ToPairFirst)
- return ToPairFirst.takeError();
- StringRef ToPairSecond = ImportStringRef(pair->second);
- Satisfaction.Details.emplace_back(
- ToConstraintExpr.get(), new(Importer.getToContext()) ConstraintSatisfaction::SubstitutionDiagnostic{
- ToPairFirst.get(), ToPairSecond});
- }
- }
+ auto expected_satisfaction = FillConstraintSatisfaction(FromSatisfaction);
+ if (!expected_satisfaction) {
+ return expected_satisfaction.takeError();
}
return ConceptSpecializationExpr::Create(
Importer.getToContext(), CL,
- const_cast<ImplicitConceptSpecializationDecl *>(CSD), &Satisfaction);
+ const_cast<ImplicitConceptSpecializationDecl *>(CSD), &*expected_satisfaction);
}
ExpectedDecl ASTNodeImporter::VisitConceptDecl(ConceptDecl* D) {
>From cab401278030eb6d77ef58f3e70d761856e1091d Mon Sep 17 00:00:00 2001
From: Konstantin Ganenko <ganenkokb at yandex-team.ru>
Date: Thu, 15 May 2025 15:31:32 +0300
Subject: [PATCH 3/8] Fix non working code:
- unchecked errors
- changes Decls were not mapped with helper GetImportedOrCreateDecl
- SmallVectors were non initialized
---
clang/lib/AST/ASTImporter.cpp | 83 +++++++++++++++++++----------------
1 file changed, 44 insertions(+), 39 deletions(-)
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index ec1bd5737f9a0..7e090b582386e 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -754,8 +754,6 @@ namespace clang {
using SubstitutionDiagnostic = std::pair<SourceLocation, StringRef>;
for (auto &Record : from) {
if (auto *SubstDiag = Record.dyn_cast<SubstitutionDiagnostic *>()) {
- Error Err = Error::success();
-
auto ToPairFirst = import(SubstDiag->first);
if(!ToPairFirst)
return ToPairFirst.takeError();
@@ -1112,6 +1110,9 @@ Expected<concepts::Requirement*> ASTNodeImporter::import(concepts::Requirement*
auto ImportSubstitutionDiagnos = [this, &ImportStringRef]
(concepts::Requirement::SubstitutionDiagnostic* FromDiagnos, Error& Err)->concepts::Requirement::SubstitutionDiagnostic* {
+ if (Err) {
+ return nullptr;
+ }
const auto& ToEntity = ImportStringRef(FromDiagnos->SubstitutedEntity);
Expected<SourceLocation> ToLoc = import(FromDiagnos->DiagLoc);
if(!ToLoc) {
@@ -1216,7 +1217,7 @@ Expected<concepts::Requirement*> ASTNodeImporter::import(concepts::Requirement*
const auto& FromSatisfaction = From->getConstraintSatisfaction();
if(From->hasInvalidConstraint()) {
const auto& ToConstraintEntity = ImportStringRef(From->getInvalidConstraintEntity());
- auto ToSatisfaction = ASTConstraintSatisfaction::Rebuild(Importer.getToContext(),FromSatisfaction);
+ auto* ToSatisfaction = ASTConstraintSatisfaction::Rebuild(Importer.getToContext(),FromSatisfaction);
return new (Importer.getToContext()) concepts::NestedRequirement(ToConstraintEntity,ToSatisfaction);
} else {
Expected<Expr *> ToExpr = import(From->getConstraintExpr());
@@ -7545,11 +7546,11 @@ ExpectedStmt ASTNodeImporter::VisitRequiresExpr(RequiresExpr* E) {
auto LParenLoc = importChecked(Err,E->getLParenLoc());
if(Err)
return std::move(Err);
- SmallVector<ParmVarDecl*, 4> LocalParameters;
- if (Error Err = ImportArrayChecked(E->getLocalParameters(),LocalParameters.begin()))
+ SmallVector<ParmVarDecl*, 4> LocalParameters(E->getLocalParameters().size());
+ if (Error Err = ImportArrayChecked(E->getLocalParameters(), LocalParameters.begin()))
return std::move(Err);
- SmallVector<concepts::Requirement*, 4> Requirements;
- if (Error Err = ImportArrayChecked(E->getRequirements(),Requirements.begin()))
+ SmallVector<concepts::Requirement*, 4> Requirements(E->getRequirements().size());
+ if (Error Err = ImportArrayChecked(E->getRequirements(), Requirements.begin()))
return std::move(Err);
return RequiresExpr::Create(Importer.getToContext(),RequiresKWLoc, Body, LParenLoc,
LocalParameters, RParenLoc, Requirements, RBraceLoc);
@@ -7557,32 +7558,31 @@ ExpectedStmt ASTNodeImporter::VisitRequiresExpr(RequiresExpr* E) {
ExpectedDecl ASTNodeImporter::VisitRequiresExprBodyDecl(RequiresExprBodyDecl* D) {
DeclContext *DC, *LexicalDC;
- Error Err = Error::success();
- Err = ImportDeclContext(D, DC, LexicalDC);
- auto RequiresLoc = importChecked(Err,D->getLocation());
- return RequiresExprBodyDecl::Create(Importer.getToContext(),DC,RequiresLoc);
+ Error Err = ImportDeclContext(D, DC, LexicalDC);
+ auto RequiresLoc = importChecked(Err, D->getLocation());
+ if (Err) {
+ return std::move(Err);
+ }
+ RequiresExprBodyDecl *To;
+ if (GetImportedOrCreateDecl(To, D, Importer.getToContext(), DC, RequiresLoc))
+ return To;
+ To->setLexicalDeclContext(LexicalDC);
+ LexicalDC->addDeclInternal(To);
+ return To;
}
ExpectedStmt ASTNodeImporter::VisitConceptSpecializationExpr(ConceptSpecializationExpr* E) {
Error Err = Error::success();
-
auto CL = importChecked(Err,E->getConceptReference());
auto CSD = importChecked(Err,E->getSpecializationDecl());
- // auto Satisfaction = importChecked(Err,E->getSatisfaction());
if (Err)
return std::move(Err);
- // E->getDependence();
if(E->isValueDependent()) {
return ConceptSpecializationExpr::Create(
Importer.getToContext(), CL,
const_cast<ImplicitConceptSpecializationDecl *>(CSD), nullptr);
}
const auto& FromSatisfaction = E->getSatisfaction();
- auto ImportStringRef = [this](const StringRef& FromString) {
- char* ToDiagMessage = new (Importer.getToContext()) char[FromString.size()];
- std::copy(FromString.begin(),FromString.end(),ToDiagMessage);
- return StringRef(ToDiagMessage,FromString.size());
- };
auto expected_satisfaction = FillConstraintSatisfaction(FromSatisfaction);
if (!expected_satisfaction) {
return expected_satisfaction.takeError();
@@ -7594,34 +7594,39 @@ ExpectedStmt ASTNodeImporter::VisitConceptSpecializationExpr(ConceptSpecializati
ExpectedDecl ASTNodeImporter::VisitConceptDecl(ConceptDecl* D) {
// Import the context of this declaration.
- DeclContext *DC, *LexicalDC;
- Error Err = Error::success();
- Err = ImportDeclContext(D, DC, LexicalDC);
- auto BeginLocOrErr = importChecked(Err, D->getBeginLoc());
+ DeclContext *DC = nullptr;
+ DeclContext *LexicalDC = nullptr;
+ Error Err = ImportDeclContext(D, DC, LexicalDC);
auto LocationOrErr = importChecked(Err, D->getLocation());
auto NameDeclOrErr = importChecked(Err,D->getDeclName());
- auto ToTemplateParameters = importChecked(Err, D->getTemplateParameters());
- auto ConstraintExpr = importChecked(Err, D->getConstraintExpr());
- if(Err)
+ auto* ToTemplateParameters = importChecked(Err, D->getTemplateParameters());
+ auto* ConstraintExpr = importChecked(Err, D->getConstraintExpr());
+ if(Err) {
return std::move(Err);
- return ConceptDecl::Create(
- Importer.getToContext(),DC,
- LocationOrErr,NameDeclOrErr,
- ToTemplateParameters,ConstraintExpr);
+ }
+ ConceptDecl *To;
+ if (GetImportedOrCreateDecl(To, D, Importer.getToContext(), DC, LocationOrErr, NameDeclOrErr, ToTemplateParameters, ConstraintExpr))
+ return To;
+ To->setLexicalDeclContext(LexicalDC);
+ LexicalDC->addDeclInternal(To);
+ return To;
}
ExpectedDecl ASTNodeImporter::VisitImplicitConceptSpecializationDecl(ImplicitConceptSpecializationDecl* D) {
DeclContext *DC, *LexicalDC;
- Error Err = Error::success();
- Err = ImportDeclContext(D, DC, LexicalDC);
- auto ToSL = importChecked(Err,D->getLocation());
+ Error Err = ImportDeclContext(D, DC, LexicalDC);
+ auto ToSL = importChecked(Err, D->getLocation());
if(Err)
return std::move(Err);
- SmallVector<TemplateArgument,2> ToArgs;
- if(Error Err = ImportTemplateArguments(D->getTemplateArguments(),ToArgs))
+ SmallVector<TemplateArgument,2> ToArgs(D->getTemplateArguments().size());
+ if(Error Err = ImportTemplateArguments(D->getTemplateArguments(), ToArgs))
return std::move(Err);
-
- return ImplicitConceptSpecializationDecl::Create(Importer.getToContext(),DC,ToSL,ToArgs);
+ ImplicitConceptSpecializationDecl *To;
+ if (GetImportedOrCreateDecl(To, D, Importer.getToContext(), DC, ToSL, ToArgs))
+ return To;
+ To->setLexicalDeclContext(LexicalDC);
+ LexicalDC->addDeclInternal(To);
+ return To;
}
ExpectedStmt ASTNodeImporter::VisitSourceLocExpr(SourceLocExpr *E) {
@@ -7644,8 +7649,8 @@ ExpectedStmt ASTNodeImporter::VisitVAArgExpr(VAArgExpr *E) {
Error Err = Error::success();
auto ToBuiltinLoc = importChecked(Err, E->getBuiltinLoc());
- auto ToSubExpr = importChecked(Err, E->getSubExpr());
- auto ToWrittenTypeInfo = importChecked(Err, E->getWrittenTypeInfo());
+ auto* ToSubExpr = importChecked(Err, E->getSubExpr());
+ auto* ToWrittenTypeInfo = importChecked(Err, E->getWrittenTypeInfo());
auto ToRParenLoc = importChecked(Err, E->getRParenLoc());
auto ToType = importChecked(Err, E->getType());
if (Err)
>From 4492084b3e536fdbbe9ee01dad097d706ac42d67 Mon Sep 17 00:00:00 2001
From: Konstantin Ganenko <ganenkokb at yandex-team.ru>
Date: Wed, 4 Jun 2025 16:08:00 +0300
Subject: [PATCH 4/8] Fix isDependent calculation in ReturnTypeRequirement
ctor.
---
clang/include/clang/AST/ExprConcepts.h | 1 +
clang/lib/AST/ASTConcept.cpp | 4 ++++
clang/lib/AST/ASTImporter.cpp | 3 ++-
3 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/clang/include/clang/AST/ExprConcepts.h b/clang/include/clang/AST/ExprConcepts.h
index f988d40cf73c3..319c9cb0eee96 100644
--- a/clang/include/clang/AST/ExprConcepts.h
+++ b/clang/include/clang/AST/ExprConcepts.h
@@ -310,6 +310,7 @@ class ExprRequirement : public Requirement {
// TODO: Can we maybe not save the whole template parameter list and just
// the type constraint? Saving the whole TPL makes it easier to handle in
// serialization but is less elegant.
+ ReturnTypeRequirement(TemplateParameterList *TPL, bool IsDependent);
ReturnTypeRequirement(TemplateParameterList *TPL);
bool isDependent() const {
diff --git a/clang/lib/AST/ASTConcept.cpp b/clang/lib/AST/ASTConcept.cpp
index c9cfec6bd64b5..91ab66f4639fc 100644
--- a/clang/lib/AST/ASTConcept.cpp
+++ b/clang/lib/AST/ASTConcept.cpp
@@ -156,6 +156,10 @@ concepts::ExprRequirement::ReturnTypeRequirement::ReturnTypeRequirement(
TypeConstraintInfo.setInt(Dependent ? true : false);
}
+concepts::ExprRequirement::ReturnTypeRequirement::ReturnTypeRequirement(
+ TemplateParameterList *TPL, bool IsDependent)
+ : TypeConstraintInfo(TPL, IsDependent) {}
+
concepts::TypeRequirement::TypeRequirement(TypeSourceInfo *T)
: Requirement(RK_Type, T->getType()->isInstantiationDependentType(),
T->getType()->containsUnexpandedParameterPack(),
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index 7e090b582386e..6f73132d8e9c3 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -1176,6 +1176,7 @@ Expected<concepts::Requirement*> ASTNodeImporter::import(concepts::Requirement*
auto& FromTypeRequirement = From->getReturnTypeRequirement();
if(FromTypeRequirement.isTypeConstraint()) {
+ const bool IsDependent = FromTypeRequirement.isDependent();
auto ParamsOrErr = import(FromTypeRequirement.getTypeConstraintTemplateParameterList());
if (!ParamsOrErr)
return ParamsOrErr.takeError();
@@ -1186,7 +1187,7 @@ Expected<concepts::Requirement*> ASTNodeImporter::import(concepts::Requirement*
return ExpectSubstitutedConstraintExpr.takeError();
SubstitutedConstraintExpr = ExpectSubstitutedConstraintExpr.get();
}
- Req.emplace(ParamsOrErr.get());
+ Req.emplace(ParamsOrErr.get(), IsDependent);
}
else if(FromTypeRequirement.isSubstitutionFailure()) {
Error Err = Error::success();
>From 3380e263eb06287e8c36ca88c60b1c38ec1ad0ae Mon Sep 17 00:00:00 2001
From: Konstantin Ganenko <ganenkokb at yandex-team.ru>
Date: Wed, 4 Jun 2025 16:11:16 +0300
Subject: [PATCH 5/8] Add newly imported declarations into imported cache
---
clang/lib/AST/ASTImporter.cpp | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index 6f73132d8e9c3..0a1e39e484f84 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -7569,7 +7569,7 @@ ExpectedDecl ASTNodeImporter::VisitRequiresExprBodyDecl(RequiresExprBodyDecl* D)
return To;
To->setLexicalDeclContext(LexicalDC);
LexicalDC->addDeclInternal(To);
- return To;
+ return Importer.MapImported(D, To);
}
ExpectedStmt ASTNodeImporter::VisitConceptSpecializationExpr(ConceptSpecializationExpr* E) {
@@ -7610,7 +7610,7 @@ ExpectedDecl ASTNodeImporter::VisitConceptDecl(ConceptDecl* D) {
return To;
To->setLexicalDeclContext(LexicalDC);
LexicalDC->addDeclInternal(To);
- return To;
+ return Importer.MapImported(D, To);
}
ExpectedDecl ASTNodeImporter::VisitImplicitConceptSpecializationDecl(ImplicitConceptSpecializationDecl* D) {
@@ -7627,7 +7627,7 @@ ExpectedDecl ASTNodeImporter::VisitImplicitConceptSpecializationDecl(ImplicitCon
return To;
To->setLexicalDeclContext(LexicalDC);
LexicalDC->addDeclInternal(To);
- return To;
+ return Importer.MapImported(D, To);
}
ExpectedStmt ASTNodeImporter::VisitSourceLocExpr(SourceLocExpr *E) {
>From 8ba5bcf522cc7d01b36613c1e0c6f54e2019c84c Mon Sep 17 00:00:00 2001
From: Konstantin Ganenko <ganenkokb at yandex-team.ru>
Date: Mon, 9 Jun 2025 10:04:44 +0300
Subject: [PATCH 6/8] Add debug build folder to ignore
---
.gitignore | 1 +
1 file changed, 1 insertion(+)
diff --git a/.gitignore b/.gitignore
index a84268a7f6863..1f4a07d4b9e50 100644
--- a/.gitignore
+++ b/.gitignore
@@ -28,6 +28,7 @@
# Nested build directory
/build*
+/debug*
#==============================================================================#
# Explicit files to ignore (only matches one).
>From 0839d38c3a227aa4d46f751ba97b0f57a6fb27f4 Mon Sep 17 00:00:00 2001
From: Konstantin Ganenko <ganenkokb at yandex-team.ru>
Date: Mon, 9 Jun 2025 10:05:13 +0300
Subject: [PATCH 7/8] Revert "Add newly imported declarations into imported
cache"
This reverts commit 3380e263eb06287e8c36ca88c60b1c38ec1ad0ae.
---
clang/lib/AST/ASTImporter.cpp | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index 0a1e39e484f84..6f73132d8e9c3 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -7569,7 +7569,7 @@ ExpectedDecl ASTNodeImporter::VisitRequiresExprBodyDecl(RequiresExprBodyDecl* D)
return To;
To->setLexicalDeclContext(LexicalDC);
LexicalDC->addDeclInternal(To);
- return Importer.MapImported(D, To);
+ return To;
}
ExpectedStmt ASTNodeImporter::VisitConceptSpecializationExpr(ConceptSpecializationExpr* E) {
@@ -7610,7 +7610,7 @@ ExpectedDecl ASTNodeImporter::VisitConceptDecl(ConceptDecl* D) {
return To;
To->setLexicalDeclContext(LexicalDC);
LexicalDC->addDeclInternal(To);
- return Importer.MapImported(D, To);
+ return To;
}
ExpectedDecl ASTNodeImporter::VisitImplicitConceptSpecializationDecl(ImplicitConceptSpecializationDecl* D) {
@@ -7627,7 +7627,7 @@ ExpectedDecl ASTNodeImporter::VisitImplicitConceptSpecializationDecl(ImplicitCon
return To;
To->setLexicalDeclContext(LexicalDC);
LexicalDC->addDeclInternal(To);
- return Importer.MapImported(D, To);
+ return To;
}
ExpectedStmt ASTNodeImporter::VisitSourceLocExpr(SourceLocExpr *E) {
>From d5164739f9a968d8a569350d3332d1be41b7421f Mon Sep 17 00:00:00 2001
From: Konstantin Ganenko <ganenkokb at yandex-team.ru>
Date: Mon, 9 Jun 2025 11:40:08 +0300
Subject: [PATCH 8/8] Reformat changes.
---
clang/lib/AST/ASTImporter.cpp | 434 +++++++++++++++++-----------------
1 file changed, 214 insertions(+), 220 deletions(-)
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index 6f73132d8e9c3..87d6475e1b9ce 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -495,6 +495,16 @@ namespace clang {
Expected<InheritedConstructor>
ImportInheritedConstructor(const InheritedConstructor &From);
+ StringRef ImportASTStringRef(StringRef FromStr);
+ Error ImportConstraintSatisfaction(const ASTConstraintSatisfaction &FromSat,
+ ConstraintSatisfaction &ToSat);
+ Expected<concepts::Requirement *>
+ ImportTypeRequirement(concepts::TypeRequirement *From);
+ Expected<concepts::Requirement *>
+ ImportExprRequirement(concepts::ExprRequirement *From);
+ Expected<concepts::Requirement *>
+ ImportNestedRequirement(concepts::NestedRequirement *From);
+
template <typename T>
bool hasSameVisibilityContextAndLinkage(T *Found, T *From);
@@ -740,38 +750,6 @@ namespace clang {
// that type is declared inside the body of the function.
// E.g. auto f() { struct X{}; return X(); }
bool hasReturnTypeDeclaredInside(FunctionDecl *D);
-
- Expected<ConstraintSatisfaction> FillConstraintSatisfaction(const ASTConstraintSatisfaction& from) {
- auto ImportStringRef = [this](const StringRef& FromString) {
- char* ToDiagMessage = new (Importer.getToContext()) char[FromString.size()];
- std::copy(FromString.begin(),FromString.end(),ToDiagMessage);
- return StringRef(ToDiagMessage,FromString.size());
- };
- ConstraintSatisfaction Satisfaction;
- Satisfaction.IsSatisfied = from.IsSatisfied;
- Satisfaction.ContainsErrors = from.ContainsErrors;
- if (!Satisfaction.IsSatisfied) {
- using SubstitutionDiagnostic = std::pair<SourceLocation, StringRef>;
- for (auto &Record : from) {
- if (auto *SubstDiag = Record.dyn_cast<SubstitutionDiagnostic *>()) {
- auto ToPairFirst = import(SubstDiag->first);
- if(!ToPairFirst)
- return ToPairFirst.takeError();
- StringRef ToPairSecond = ImportStringRef(SubstDiag->second);
- Satisfaction.Details.emplace_back(new (Importer.getToContext())
- ConstraintSatisfaction::SubstitutionDiagnostic{
- ToPairFirst.get(), ToPairSecond});
- } else {
- const Expr *ConstraintExpr = Record.dyn_cast<Expr *>();
- Expected<Expr *> ToConstraintExpr = import(ConstraintExpr);
- if(!ToConstraintExpr)
- return ToConstraintExpr.takeError();
- Satisfaction.Details.emplace_back(ToConstraintExpr.get());
- }
- }
- }
- return Satisfaction;
- }
};
template <typename InContainerTy>
@@ -1076,6 +1054,177 @@ Expected<ConceptReference *> ASTNodeImporter::import(ConceptReference *From) {
return ConceptRef;
}
+StringRef ASTNodeImporter::ImportASTStringRef(StringRef FromStr) {
+ char *ToStore = new (Importer.getToContext()) char[FromStr.size()];
+ std::copy(FromStr.begin(), FromStr.end(), ToStore);
+ return StringRef(ToStore, FromStr.size());
+}
+
+Error ASTNodeImporter::ImportConstraintSatisfaction(
+ const ASTConstraintSatisfaction &FromSat, ConstraintSatisfaction &ToSat) {
+ ToSat.IsSatisfied = FromSat.IsSatisfied;
+ ToSat.ContainsErrors = FromSat.ContainsErrors;
+ if (!ToSat.IsSatisfied) {
+ for (auto Record = FromSat.begin(); Record != FromSat.end(); ++Record) {
+ if (Expr *E = Record->dyn_cast<Expr *>()) {
+ ExpectedExpr ToSecondExpr = import(E);
+ if (!ToSecondExpr)
+ return ToSecondExpr.takeError();
+ ToSat.Details.emplace_back(ToSecondExpr.get());
+ } else {
+ auto Pair = Record->dyn_cast<std::pair<SourceLocation, StringRef> *>();
+
+ ExpectedSLoc ToPairFirst = import(Pair->first);
+ if (!ToPairFirst)
+ return ToPairFirst.takeError();
+ StringRef ToPairSecond = ImportASTStringRef(Pair->second);
+ ToSat.Details.emplace_back(
+ new (Importer.getToContext())
+ ConstraintSatisfaction::SubstitutionDiagnostic{
+ ToPairFirst.get(), ToPairSecond});
+ }
+ }
+ }
+ return Error::success();
+}
+
+template <>
+Expected<concepts::Requirement::SubstitutionDiagnostic *>
+ASTNodeImporter::import(
+ concepts::Requirement::SubstitutionDiagnostic *FromDiag) {
+ StringRef ToEntity = ImportASTStringRef(FromDiag->SubstitutedEntity);
+ ExpectedSLoc ToLoc = import(FromDiag->DiagLoc);
+ if (!ToLoc)
+ return ToLoc.takeError();
+ StringRef ToDiagMessage = ImportASTStringRef(FromDiag->DiagMessage);
+ return new (Importer.getToContext())
+ concepts::Requirement::SubstitutionDiagnostic{ToEntity, ToLoc.get(),
+ ToDiagMessage};
+}
+
+Expected<concepts::Requirement *>
+ASTNodeImporter::ImportTypeRequirement(concepts::TypeRequirement *From) {
+ using namespace concepts;
+
+ if (From->isSubstitutionFailure()) {
+ auto DiagOrErr = import(From->getSubstitutionDiagnostic());
+ if (!DiagOrErr)
+ return DiagOrErr.takeError();
+ return new (Importer.getToContext()) TypeRequirement(*DiagOrErr);
+ } else {
+ Expected<TypeSourceInfo *> ToType = import(From->getType());
+ if (!ToType)
+ return ToType.takeError();
+ return new (Importer.getToContext()) TypeRequirement(*ToType);
+ }
+}
+
+Expected<concepts::Requirement *>
+ASTNodeImporter::ImportExprRequirement(concepts::ExprRequirement *From) {
+ using namespace concepts;
+
+ bool IsRKSimple = From->getKind() == Requirement::RK_Simple;
+ ExprRequirement::SatisfactionStatus Status = From->getSatisfactionStatus();
+
+ std::optional<ExprRequirement::ReturnTypeRequirement> Req;
+ ConceptSpecializationExpr *SubstitutedConstraintExpr = nullptr;
+
+ if (IsRKSimple) {
+ Req.emplace();
+ } else {
+ const ExprRequirement::ReturnTypeRequirement &FromTypeRequirement =
+ From->getReturnTypeRequirement();
+
+ if (FromTypeRequirement.isTypeConstraint()) {
+ const bool IsDependent = FromTypeRequirement.isDependent();
+ auto ParamsOrErr =
+ import(FromTypeRequirement.getTypeConstraintTemplateParameterList());
+ if (!ParamsOrErr)
+ return ParamsOrErr.takeError();
+ if (Status >= ExprRequirement::SS_ConstraintsNotSatisfied) {
+ auto SubstConstraintExprOrErr =
+ import(From->getReturnTypeRequirementSubstitutedConstraintExpr());
+ if (!SubstConstraintExprOrErr)
+ return SubstConstraintExprOrErr.takeError();
+ SubstitutedConstraintExpr = SubstConstraintExprOrErr.get();
+ }
+ Req.emplace(ParamsOrErr.get(), IsDependent);
+ } else if (FromTypeRequirement.isSubstitutionFailure()) {
+ auto DiagOrErr = import(FromTypeRequirement.getSubstitutionDiagnostic());
+ if (DiagOrErr)
+ return DiagOrErr.takeError();
+ Req.emplace(DiagOrErr.get());
+ } else {
+ Req.emplace();
+ }
+ }
+
+ ExpectedSLoc NoexceptLocOrErr = import(From->getNoexceptLoc());
+ if (!NoexceptLocOrErr)
+ return NoexceptLocOrErr.takeError();
+
+ if (Status == ExprRequirement::SS_ExprSubstitutionFailure) {
+ auto DiagOrErr = import(From->getExprSubstitutionDiagnostic());
+ if (!DiagOrErr)
+ return DiagOrErr.takeError();
+ return new (Importer.getToContext()) ExprRequirement(
+ *DiagOrErr, IsRKSimple, *NoexceptLocOrErr, std::move(*Req));
+ } else {
+ Expected<Expr *> ExprOrErr = import(From->getExpr());
+ if (!ExprOrErr)
+ return ExprOrErr.takeError();
+ return new (Importer.getToContext()) concepts::ExprRequirement(
+ *ExprOrErr, IsRKSimple, *NoexceptLocOrErr, std::move(*Req), Status,
+ SubstitutedConstraintExpr);
+ }
+}
+
+Expected<concepts::Requirement *>
+ASTNodeImporter::ImportNestedRequirement(concepts::NestedRequirement *From) {
+ using namespace concepts;
+
+ const ASTConstraintSatisfaction &FromSatisfaction =
+ From->getConstraintSatisfaction();
+ if (From->hasInvalidConstraint()) {
+ StringRef ToEntity = ImportASTStringRef(From->getInvalidConstraintEntity());
+ ASTConstraintSatisfaction *ToSatisfaction =
+ ASTConstraintSatisfaction::Rebuild(Importer.getToContext(),
+ FromSatisfaction);
+ return new (Importer.getToContext())
+ NestedRequirement(ToEntity, ToSatisfaction);
+ } else {
+ ExpectedExpr ToExpr = import(From->getConstraintExpr());
+ if (!ToExpr)
+ return ToExpr.takeError();
+ if (ToExpr.get()->isInstantiationDependent()) {
+ return new (Importer.getToContext()) NestedRequirement(ToExpr.get());
+ } else {
+ ConstraintSatisfaction Satisfaction;
+ if (Error Err =
+ ImportConstraintSatisfaction(FromSatisfaction, Satisfaction))
+ return std::move(Err);
+ return new (Importer.getToContext()) NestedRequirement(
+ Importer.getToContext(), ToExpr.get(), Satisfaction);
+ }
+ }
+}
+
+template <>
+Expected<concepts::Requirement *>
+ASTNodeImporter::import(concepts::Requirement *FromRequire) {
+ switch (FromRequire->getKind()) {
+ case concepts::Requirement::RequirementKind::RK_Type:
+ return ImportTypeRequirement(cast<concepts::TypeRequirement>(FromRequire));
+ case concepts::Requirement::RequirementKind::RK_Compound:
+ case concepts::Requirement::RequirementKind::RK_Simple:
+ return ImportExprRequirement(cast<concepts::ExprRequirement>(FromRequire));
+ case concepts::Requirement::RequirementKind::RK_Nested:
+ return ImportNestedRequirement(
+ cast<concepts::NestedRequirement>(FromRequire));
+ }
+ llvm_unreachable("Unhandled requirement kind");
+}
+
template <>
Expected<LambdaCapture> ASTNodeImporter::import(const LambdaCapture &From) {
ValueDecl *Var = nullptr;
@@ -1100,146 +1249,6 @@ Expected<LambdaCapture> ASTNodeImporter::import(const LambdaCapture &From) {
EllipsisLoc);
}
-template<>
-Expected<concepts::Requirement*> ASTNodeImporter::import(concepts::Requirement* FromRequire) {
- auto ImportStringRef = [this](const StringRef& FromString) {
- char* ToDiagMessage = new (Importer.getToContext()) char[FromString.size()];
- std::copy(FromString.begin(),FromString.end(),ToDiagMessage);
- return StringRef(ToDiagMessage,FromString.size());
- };
-
- auto ImportSubstitutionDiagnos = [this, &ImportStringRef]
- (concepts::Requirement::SubstitutionDiagnostic* FromDiagnos, Error& Err)->concepts::Requirement::SubstitutionDiagnostic* {
- if (Err) {
- return nullptr;
- }
- const auto& ToEntity = ImportStringRef(FromDiagnos->SubstitutedEntity);
- Expected<SourceLocation> ToLoc = import(FromDiagnos->DiagLoc);
- if(!ToLoc) {
- Err = ToLoc.takeError();
- return nullptr;
- }
- const auto& ToDiagMessage = ImportStringRef(FromDiagnos->DiagMessage);
- return new (Importer.getToContext()) concepts::Requirement::SubstitutionDiagnostic{
- ToEntity,
- ToLoc.get(),
- ToDiagMessage};
- };
- switch (FromRequire->getKind()) {
- case concepts::Requirement::RequirementKind::RK_Type: {
- auto *From = cast<concepts::TypeRequirement>(FromRequire);
- if(From->isSubstitutionFailure())
- {
- // Should we return Error directly if TypeRequirement isSubstitutionFailure?
- Error Err = Error::success();
- auto Diagnos = ImportSubstitutionDiagnos(From->getSubstitutionDiagnostic(),Err);
- if (Err)
- return std::move(Err);
- return new (Importer.getToContext()) concepts::TypeRequirement(Diagnos);
- }
- else {
- Expected<TypeSourceInfo *> ToType = import(From->getType());
- if(!ToType)
- return ToType.takeError();
- return new (Importer.getToContext()) concepts::TypeRequirement(ToType.get());
- }
- break;
- }
- case concepts::Requirement::RequirementKind::RK_Compound:
- case concepts::Requirement::RequirementKind::RK_Simple: {
- const auto *From = cast<concepts::ExprRequirement>(FromRequire);
-
- auto Status = From->getSatisfactionStatus();
- llvm::PointerUnion<concepts::Requirement::SubstitutionDiagnostic *, Expr *> E;
- if (Status == concepts::ExprRequirement::SS_ExprSubstitutionFailure) {
- Error Err = Error::success();
- E = ImportSubstitutionDiagnos(From->getExprSubstitutionDiagnostic(),Err);
- if (Err)
- return std::move(Err);
- } else {
- auto ExpectE = import(From->getExpr());
- if (!ExpectE)
- return ExpectE.takeError();
- E = ExpectE.get();
- }
-
- std::optional<concepts::ExprRequirement::ReturnTypeRequirement> Req;
- ConceptSpecializationExpr *SubstitutedConstraintExpr = nullptr;
- SourceLocation NoexceptLoc;
- bool IsRKSimple = FromRequire->getKind() == concepts::Requirement::RK_Simple;
- if (IsRKSimple) {
- Req.emplace();
- } else {
- auto NoexceptLoc = import(From->getNoexceptLoc());
- if(!NoexceptLoc)
- return NoexceptLoc.takeError();
- auto& FromTypeRequirement = From->getReturnTypeRequirement();
-
- if(FromTypeRequirement.isTypeConstraint()) {
- const bool IsDependent = FromTypeRequirement.isDependent();
- auto ParamsOrErr = import(FromTypeRequirement.getTypeConstraintTemplateParameterList());
- if (!ParamsOrErr)
- return ParamsOrErr.takeError();
- if (Status >=
- concepts::ExprRequirement::SS_ConstraintsNotSatisfied) {
- auto ExpectSubstitutedConstraintExpr = import(From->getReturnTypeRequirementSubstitutedConstraintExpr());
- if (!ExpectSubstitutedConstraintExpr)
- return ExpectSubstitutedConstraintExpr.takeError();
- SubstitutedConstraintExpr = ExpectSubstitutedConstraintExpr.get();
- }
- Req.emplace(ParamsOrErr.get(), IsDependent);
- }
- else if(FromTypeRequirement.isSubstitutionFailure()) {
- Error Err = Error::success();
- concepts::Requirement::SubstitutionDiagnostic *ToDiagnos =
- ImportSubstitutionDiagnos(
- FromTypeRequirement.getSubstitutionDiagnostic(), Err);
- if (Err)
- return std::move(Err);
- Req.emplace(ToDiagnos);
- }
- else {
- Req.emplace();
- }
- }
- if (Expr *Ex = E.dyn_cast<Expr *>())
- return new (Importer.getToContext()) concepts::ExprRequirement(
- Ex, IsRKSimple, NoexceptLoc,
- std::move(*Req), Status, SubstitutedConstraintExpr);
- else
- return new (Importer.getToContext()) concepts::ExprRequirement(
- E.get<concepts::Requirement::SubstitutionDiagnostic *>(),
- IsRKSimple, NoexceptLoc,
- std::move(*Req));
- break;
- }
- case concepts::Requirement::RequirementKind::RK_Nested: {
- auto *From = cast<concepts::NestedRequirement>(FromRequire);
- const auto& FromSatisfaction = From->getConstraintSatisfaction();
- if(From->hasInvalidConstraint()) {
- const auto& ToConstraintEntity = ImportStringRef(From->getInvalidConstraintEntity());
- auto* ToSatisfaction = ASTConstraintSatisfaction::Rebuild(Importer.getToContext(),FromSatisfaction);
- return new (Importer.getToContext()) concepts::NestedRequirement(ToConstraintEntity,ToSatisfaction);
- } else {
- Expected<Expr *> ToExpr = import(From->getConstraintExpr());
- if(!ToExpr)
- return ToExpr.takeError();
- // FromSatisfaction.IsSatisfied;
- if(ToExpr.get()->isInstantiationDependent())
- return new (Importer.getToContext()) concepts::NestedRequirement(ToExpr.get());
- else {
- auto expected_satisfaction = FillConstraintSatisfaction(FromSatisfaction);
- if (!expected_satisfaction) {
- return expected_satisfaction.takeError();
- }
- return new (Importer.getToContext()) concepts::NestedRequirement(Importer.getToContext(),ToExpr.get(), *expected_satisfaction);
- }
- }
- break;
- }
- }
-}
-
template <typename T>
bool ASTNodeImporter::hasSameVisibilityContextAndLinkage(T *Found, T *From) {
if (Found->getLinkageInternal() != From->getLinkageInternal())
@@ -7538,38 +7547,33 @@ ExpectedStmt ASTNodeImporter::VisitExpr(Expr *E) {
ExpectedStmt ASTNodeImporter::VisitRequiresExpr(RequiresExpr* E) {
Error Err = Error::success();
- // auto ToType = importChecked(Err, E->getType());
- auto RequiresKWLoc = importChecked(Err,E->getRequiresKWLoc());
- auto RParenLoc = importChecked(Err,E->getRParenLoc());
- auto RBraceLoc = importChecked(Err,E->getRBraceLoc());
+ auto RequiresKWLoc = importChecked(Err, E->getRequiresKWLoc());
+ auto RParenLoc = importChecked(Err, E->getRParenLoc());
+ auto RBraceLoc = importChecked(Err, E->getRBraceLoc());
- auto Body = importChecked(Err,E->getBody());
- auto LParenLoc = importChecked(Err,E->getLParenLoc());
- if(Err)
+ auto Body = importChecked(Err, E->getBody());
+ auto LParenLoc = importChecked(Err, E->getLParenLoc());
+ if (Err)
return std::move(Err);
SmallVector<ParmVarDecl*, 4> LocalParameters(E->getLocalParameters().size());
if (Error Err = ImportArrayChecked(E->getLocalParameters(), LocalParameters.begin()))
return std::move(Err);
- SmallVector<concepts::Requirement*, 4> Requirements(E->getRequirements().size());
+ SmallVector<concepts::Requirement *, 4> Requirements(
+ E->getRequirements().size());
if (Error Err = ImportArrayChecked(E->getRequirements(), Requirements.begin()))
return std::move(Err);
- return RequiresExpr::Create(Importer.getToContext(),RequiresKWLoc, Body, LParenLoc,
- LocalParameters, RParenLoc, Requirements, RBraceLoc);
+ return RequiresExpr::Create(Importer.getToContext(), RequiresKWLoc, Body,
+ LParenLoc, LocalParameters, RParenLoc,
+ Requirements, RBraceLoc);
}
ExpectedDecl ASTNodeImporter::VisitRequiresExprBodyDecl(RequiresExprBodyDecl* D) {
DeclContext *DC, *LexicalDC;
Error Err = ImportDeclContext(D, DC, LexicalDC);
auto RequiresLoc = importChecked(Err, D->getLocation());
- if (Err) {
+ if (Err)
return std::move(Err);
- }
- RequiresExprBodyDecl *To;
- if (GetImportedOrCreateDecl(To, D, Importer.getToContext(), DC, RequiresLoc))
- return To;
- To->setLexicalDeclContext(LexicalDC);
- LexicalDC->addDeclInternal(To);
- return To;
+ return RequiresExprBodyDecl::Create(Importer.getToContext(), DC, RequiresLoc);
}
ExpectedStmt ASTNodeImporter::VisitConceptSpecializationExpr(ConceptSpecializationExpr* E) {
@@ -7578,56 +7582,46 @@ ExpectedStmt ASTNodeImporter::VisitConceptSpecializationExpr(ConceptSpecializati
auto CSD = importChecked(Err,E->getSpecializationDecl());
if (Err)
return std::move(Err);
- if(E->isValueDependent()) {
+ if (E->isValueDependent())
return ConceptSpecializationExpr::Create(
Importer.getToContext(), CL,
const_cast<ImplicitConceptSpecializationDecl *>(CSD), nullptr);
- }
- const auto& FromSatisfaction = E->getSatisfaction();
- auto expected_satisfaction = FillConstraintSatisfaction(FromSatisfaction);
- if (!expected_satisfaction) {
- return expected_satisfaction.takeError();
- }
+ ConstraintSatisfaction Satisfaction;
+ if (Error Err =
+ ImportConstraintSatisfaction(E->getSatisfaction(), Satisfaction))
+ return std::move(Err);
return ConceptSpecializationExpr::Create(
- Importer.getToContext(), CL,
- const_cast<ImplicitConceptSpecializationDecl *>(CSD), &*expected_satisfaction);
+ Importer.getToContext(), CL,
+ const_cast<ImplicitConceptSpecializationDecl *>(CSD), &Satisfaction);
}
ExpectedDecl ASTNodeImporter::VisitConceptDecl(ConceptDecl* D) {
- // Import the context of this declaration.
- DeclContext *DC = nullptr;
- DeclContext *LexicalDC = nullptr;
+ DeclContext *DC, *LexicalDC;
Error Err = ImportDeclContext(D, DC, LexicalDC);
auto LocationOrErr = importChecked(Err, D->getLocation());
auto NameDeclOrErr = importChecked(Err,D->getDeclName());
- auto* ToTemplateParameters = importChecked(Err, D->getTemplateParameters());
- auto* ConstraintExpr = importChecked(Err, D->getConstraintExpr());
- if(Err) {
+ auto ToTemplateParameters = importChecked(Err, D->getTemplateParameters());
+ auto ConstraintExpr = importChecked(Err, D->getConstraintExpr());
+ if (Err)
return std::move(Err);
- }
- ConceptDecl *To;
- if (GetImportedOrCreateDecl(To, D, Importer.getToContext(), DC, LocationOrErr, NameDeclOrErr, ToTemplateParameters, ConstraintExpr))
- return To;
- To->setLexicalDeclContext(LexicalDC);
- LexicalDC->addDeclInternal(To);
- return To;
+
+ return ConceptDecl::Create(Importer.getToContext(), DC, LocationOrErr,
+ NameDeclOrErr, ToTemplateParameters,
+ ConstraintExpr);
}
ExpectedDecl ASTNodeImporter::VisitImplicitConceptSpecializationDecl(ImplicitConceptSpecializationDecl* D) {
DeclContext *DC, *LexicalDC;
Error Err = ImportDeclContext(D, DC, LexicalDC);
auto ToSL = importChecked(Err, D->getLocation());
- if(Err)
+ if (Err)
return std::move(Err);
+
SmallVector<TemplateArgument,2> ToArgs(D->getTemplateArguments().size());
- if(Error Err = ImportTemplateArguments(D->getTemplateArguments(), ToArgs))
+ if (Error Err = ImportTemplateArguments(D->getTemplateArguments(), ToArgs))
return std::move(Err);
- ImplicitConceptSpecializationDecl *To;
- if (GetImportedOrCreateDecl(To, D, Importer.getToContext(), DC, ToSL, ToArgs))
- return To;
- To->setLexicalDeclContext(LexicalDC);
- LexicalDC->addDeclInternal(To);
- return To;
+ return ImplicitConceptSpecializationDecl::Create(Importer.getToContext(), DC,
+ ToSL, ToArgs);
}
ExpectedStmt ASTNodeImporter::VisitSourceLocExpr(SourceLocExpr *E) {
More information about the llvm-commits
mailing list