Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions clang/include/clang/AST/ASTContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -738,6 +738,12 @@ class ASTContext : public RefCountedBase<ASTContext> {
}
void Deallocate(void *Ptr) const {}

llvm::StringRef backupStr(llvm::StringRef S) const {
char *Buf = new (*this) char[S.size()];
std::copy(S.begin(), S.end(), Buf);
return llvm::StringRef(Buf, S.size());
}

/// Allocates a \c DeclListNode or returns one from the \c ListNodeFreeList
/// pool.
DeclListNode *AllocateDeclListNode(clang::NamedDecl *ND) {
Expand Down
6 changes: 2 additions & 4 deletions clang/lib/AST/ASTConcept.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,9 @@ CreateUnsatisfiedConstraintRecord(const ASTContext &C,
else {
auto &SubstitutionDiagnostic =
*Detail.get<std::pair<SourceLocation, StringRef> *>();
unsigned MessageSize = SubstitutionDiagnostic.second.size();
char *Mem = new (C) char[MessageSize];
memcpy(Mem, SubstitutionDiagnostic.second.data(), MessageSize);
StringRef Message = C.backupStr(SubstitutionDiagnostic.second);
auto *NewSubstDiag = new (C) std::pair<SourceLocation, StringRef>(
SubstitutionDiagnostic.first, StringRef(Mem, MessageSize));
SubstitutionDiagnostic.first, Message);
new (TrailingObject) UnsatisfiedConstraintRecord(NewSubstDiag);
}
}
Expand Down
31 changes: 12 additions & 19 deletions clang/lib/Sema/SemaTemplateInstantiate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2576,16 +2576,12 @@ createSubstDiag(Sema &S, TemplateDeductionInfo &Info,
} else {
ErrorLoc = Info.getLocation();
}
char *MessageBuf = new (S.Context) char[Message.size()];
std::copy(Message.begin(), Message.end(), MessageBuf);
SmallString<128> Entity;
llvm::raw_svector_ostream OS(Entity);
Printer(OS);
char *EntityBuf = new (S.Context) char[Entity.size()];
std::copy(Entity.begin(), Entity.end(), EntityBuf);
return new (S.Context) concepts::Requirement::SubstitutionDiagnostic{
StringRef(EntityBuf, Entity.size()), ErrorLoc,
StringRef(MessageBuf, Message.size())};
const ASTContext &C = S.Context;
return new (C) concepts::Requirement::SubstitutionDiagnostic{
C.backupStr(Entity), ErrorLoc, C.backupStr(Message)};
}

concepts::Requirement::SubstitutionDiagnostic *
Expand All @@ -2594,10 +2590,9 @@ concepts::createSubstDiagAt(Sema &S, SourceLocation Location,
SmallString<128> Entity;
llvm::raw_svector_ostream OS(Entity);
Printer(OS);
char *EntityBuf = new (S.Context) char[Entity.size()];
llvm::copy(Entity, EntityBuf);
return new (S.Context) concepts::Requirement::SubstitutionDiagnostic{
/*SubstitutedEntity=*/StringRef(EntityBuf, Entity.size()),
const ASTContext &C = S.Context;
return new (C) concepts::Requirement::SubstitutionDiagnostic{
/*SubstitutedEntity=*/C.backupStr(Entity),
/*DiagLoc=*/Location, /*DiagMessage=*/StringRef()};
}

Expand Down Expand Up @@ -2773,23 +2768,21 @@ TemplateInstantiator::TransformNestedRequirement(
assert(!Trap.hasErrorOccurred() && "Substitution failures must be handled "
"by CheckConstraintSatisfaction.");
}
ASTContext &C = SemaRef.Context;
if (TransConstraint.isUsable() &&
TransConstraint.get()->isInstantiationDependent())
return new (SemaRef.Context)
concepts::NestedRequirement(TransConstraint.get());
return new (C) concepts::NestedRequirement(TransConstraint.get());
if (TransConstraint.isInvalid() || !TransConstraint.get() ||
Satisfaction.HasSubstitutionFailure()) {
SmallString<128> Entity;
llvm::raw_svector_ostream OS(Entity);
Req->getConstraintExpr()->printPretty(OS, nullptr,
SemaRef.getPrintingPolicy());
char *EntityBuf = new (SemaRef.Context) char[Entity.size()];
std::copy(Entity.begin(), Entity.end(), EntityBuf);
return new (SemaRef.Context) concepts::NestedRequirement(
SemaRef.Context, StringRef(EntityBuf, Entity.size()), Satisfaction);
return new (C) concepts::NestedRequirement(
SemaRef.Context, C.backupStr(Entity), Satisfaction);
}
return new (SemaRef.Context) concepts::NestedRequirement(
SemaRef.Context, TransConstraint.get(), Satisfaction);
return new (C)
concepts::NestedRequirement(C, TransConstraint.get(), Satisfaction);
}

TypeSourceInfo *Sema::SubstType(TypeSourceInfo *T,
Expand Down
36 changes: 13 additions & 23 deletions clang/lib/Serialization/ASTReaderStmt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -785,29 +785,22 @@ void ASTStmtReader::VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E) {
E->setRParenLoc(readSourceLocation());
}

static StringRef saveStrToCtx(const std::string &S, ASTContext &Ctx) {
char *Buf = new (Ctx) char[S.size()];
std::copy(S.begin(), S.end(), Buf);
return StringRef(Buf, S.size());
}

static ConstraintSatisfaction
readConstraintSatisfaction(ASTRecordReader &Record) {
ConstraintSatisfaction Satisfaction;
Satisfaction.IsSatisfied = Record.readInt();
Satisfaction.ContainsErrors = Record.readInt();
const ASTContext &C = Record.getContext();
if (!Satisfaction.IsSatisfied) {
unsigned NumDetailRecords = Record.readInt();
for (unsigned i = 0; i != NumDetailRecords; ++i) {
if (/* IsDiagnostic */Record.readInt()) {
SourceLocation DiagLocation = Record.readSourceLocation();
StringRef DiagMessage =
saveStrToCtx(Record.readString(), Record.getContext());
StringRef DiagMessage = C.backupStr(Record.readString());

Satisfaction.Details.emplace_back(
new (Record.getContext())
ConstraintSatisfaction::SubstitutionDiagnostic(DiagLocation,
DiagMessage));
new (C) ConstraintSatisfaction::SubstitutionDiagnostic(
DiagLocation, DiagMessage));
} else
Satisfaction.Details.emplace_back(Record.readExpr());
}
Expand All @@ -828,12 +821,10 @@ void ASTStmtReader::VisitConceptSpecializationExpr(

static concepts::Requirement::SubstitutionDiagnostic *
readSubstitutionDiagnostic(ASTRecordReader &Record) {
StringRef SubstitutedEntity =
saveStrToCtx(Record.readString(), Record.getContext());

const ASTContext &C = Record.getContext();
StringRef SubstitutedEntity = C.backupStr(Record.readString());
SourceLocation DiagLoc = Record.readSourceLocation();
StringRef DiagMessage =
saveStrToCtx(Record.readString(), Record.getContext());
StringRef DiagMessage = C.backupStr(Record.readString());

return new (Record.getContext())
concepts::Requirement::SubstitutionDiagnostic{SubstitutedEntity, DiagLoc,
Expand Down Expand Up @@ -919,22 +910,21 @@ void ASTStmtReader::VisitRequiresExpr(RequiresExpr *E) {
std::move(*Req));
} break;
case concepts::Requirement::RK_Nested: {
ASTContext &C = Record.getContext();
bool HasInvalidConstraint = Record.readInt();
if (HasInvalidConstraint) {
StringRef InvalidConstraint =
saveStrToCtx(Record.readString(), Record.getContext());
R = new (Record.getContext()) concepts::NestedRequirement(
StringRef InvalidConstraint = C.backupStr(Record.readString());
R = new (C) concepts::NestedRequirement(
Record.getContext(), InvalidConstraint,
readConstraintSatisfaction(Record));
break;
}
Expr *E = Record.readExpr();
if (E->isInstantiationDependent())
R = new (Record.getContext()) concepts::NestedRequirement(E);
R = new (C) concepts::NestedRequirement(E);
else
R = new (Record.getContext())
concepts::NestedRequirement(Record.getContext(), E,
readConstraintSatisfaction(Record));
R = new (C) concepts::NestedRequirement(
C, E, readConstraintSatisfaction(Record));
} break;
}
if (!R)
Expand Down