[clang] Ast importer visitors (PR #138838)
Balázs Kéri via cfe-commits
cfe-commits at lists.llvm.org
Fri Jun 6 08:24:52 PDT 2025
================
@@ -1063,6 +1100,146 @@ 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;
+ }
+ }
+}
+
----------------
balazske wrote:
This function looks too long and can be split into 3 parts for the different types (case branches).
https://github.com/llvm/llvm-project/pull/138838
More information about the cfe-commits
mailing list