[clang] Ast importer visitors (PR #138838)
via cfe-commits
cfe-commits at lists.llvm.org
Thu May 15 05:33:11 PDT 2025
https://github.com/ganenkokb-yandex updated https://github.com/llvm/llvm-project/pull/138838
>From 4f46c654d7efcffc143f73cbc9083116ffbe8af6 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/3] 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 b481ad5df667e..3e0188d047bef 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())
@@ -7322,6 +7490,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());
@@ -10547,4 +10830,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 fb02c1b61617573d71b73db0d2c59864852da233 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/3] 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 3e0188d047bef..cff0050208784 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;
@@ -7539,38 +7546,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 822471f292fd31b0c506c5cbf4d57834a5122bb8 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/3] 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 cff0050208784..4eb65c48b5ccf 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());
@@ -7508,11 +7509,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);
@@ -7520,32 +7521,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();
@@ -7557,34 +7557,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) {
@@ -7607,8 +7612,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)
More information about the cfe-commits
mailing list