================ @@ -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 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits