[libcxx-commits] [llvm] [libc] [compiler-rt] [clang] [libcxx] [clang-tools-extra] [flang] [clang] Remove `CXXNewInitializationStyle::Implicit` (PR #78793)
Vlad Serebrennikov via libcxx-commits
libcxx-commits at lists.llvm.org
Sun Jan 21 01:46:52 PST 2024
https://github.com/Endilll updated https://github.com/llvm/llvm-project/pull/78793
>From f6a599d6e662121f19529f59ffa44cc6177c0835 Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov <serebrennikov.vladislav at gmail.com>
Date: Sat, 20 Jan 2024 00:58:06 +0300
Subject: [PATCH] [clang] Remove `CXXNewInitializationStyle::Implicit`
This is a follow up to https://github.com/llvm/llvm-project/pull/71417 , which aims to resolve concerns brought up there. Namely, this patch replaces `CXXNewInitializationStyle::Implicit` with a dedicated `HasInitializer` flag. This makes `CXXNewInitializationStyle` to model syntax again. This patch also renames `Call` and `List` to less confusing `Parens` and `Braces`.
---
.../modernize/MakeSmartPtrCheck.cpp | 7 +++--
clang/include/clang/AST/ExprCXX.h | 19 +++-----------
clang/include/clang/AST/Stmt.h | 8 +++---
clang/lib/AST/ExprCXX.cpp | 10 +++----
clang/lib/AST/ItaniumMangle.cpp | 4 +--
clang/lib/AST/JSONNodeDumper.cpp | 5 ++--
clang/lib/AST/StmtPrinter.cpp | 5 ++--
clang/lib/Sema/SemaExprCXX.cpp | 26 ++++++-------------
clang/lib/Serialization/ASTReaderStmt.cpp | 1 +
clang/lib/Serialization/ASTWriterStmt.cpp | 1 +
10 files changed, 32 insertions(+), 54 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp b/clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp
index 616e57efa76ded..d1d7e9dcfa9c0d 100644
--- a/clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp
@@ -323,8 +323,7 @@ bool MakeSmartPtrCheck::replaceNew(DiagnosticBuilder &Diag,
return false;
};
switch (New->getInitializationStyle()) {
- case CXXNewInitializationStyle::None:
- case CXXNewInitializationStyle::Implicit: {
+ case CXXNewInitializationStyle::None: {
if (ArraySizeExpr.empty()) {
Diag << FixItHint::CreateRemoval(SourceRange(NewStart, NewEnd));
} else {
@@ -335,7 +334,7 @@ bool MakeSmartPtrCheck::replaceNew(DiagnosticBuilder &Diag,
}
break;
}
- case CXXNewInitializationStyle::Call: {
+ case CXXNewInitializationStyle::Parens: {
// FIXME: Add fixes for constructors with parameters that can be created
// with a C++11 braced-init-list (e.g. std::vector, std::map).
// Unlike ordinal cases, braced list can not be deduced in
@@ -372,7 +371,7 @@ bool MakeSmartPtrCheck::replaceNew(DiagnosticBuilder &Diag,
}
break;
}
- case CXXNewInitializationStyle::List: {
+ case CXXNewInitializationStyle::Braces: {
// Range of the substring that we do not want to remove.
SourceRange InitRange;
if (const auto *NewConstruct = New->getConstructExpr()) {
diff --git a/clang/include/clang/AST/ExprCXX.h b/clang/include/clang/AST/ExprCXX.h
index 24278016431837..9a7c632c36c5e8 100644
--- a/clang/include/clang/AST/ExprCXX.h
+++ b/clang/include/clang/AST/ExprCXX.h
@@ -2210,14 +2210,11 @@ enum class CXXNewInitializationStyle {
/// New-expression has no initializer as written.
None,
- /// New-expression has no written initializer, but has an implicit one.
- Implicit,
-
/// New-expression has a C++98 paren-delimited initializer.
- Call,
+ Parens,
/// New-expression has a C++11 list-initializer.
- List
+ Braces
};
/// Represents a new-expression for memory allocation and constructor
@@ -2388,17 +2385,7 @@ class CXXNewExpr final
bool isGlobalNew() const { return CXXNewExprBits.IsGlobalNew; }
/// Whether this new-expression has any initializer at all.
- bool hasInitializer() const {
- switch (getInitializationStyle()) {
- case CXXNewInitializationStyle::None:
- return false;
- case CXXNewInitializationStyle::Implicit:
- case CXXNewInitializationStyle::Call:
- case CXXNewInitializationStyle::List:
- return true;
- }
- llvm_unreachable("Unknown initializer");
- }
+ bool hasInitializer() const { return CXXNewExprBits.HasInitializer; }
/// The kind of initializer this new-expression has.
CXXNewInitializationStyle getInitializationStyle() const {
diff --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h
index e1fde24e647789..55eca4007d17ea 100644
--- a/clang/include/clang/AST/Stmt.h
+++ b/clang/include/clang/AST/Stmt.h
@@ -868,9 +868,11 @@ class alignas(void *) Stmt {
LLVM_PREFERRED_TYPE(bool)
unsigned UsualArrayDeleteWantsSize : 1;
- /// What kind of initializer do we have? Could be none, parens, or braces.
- /// In storage, we distinguish between "none, and no initializer expr", and
- /// "none, but an implicit initializer expr".
+ // Is initializer expr present?
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned HasInitializer : 1;
+
+ /// What kind of initializer syntax used? Could be none, parens, or braces.
LLVM_PREFERRED_TYPE(CXXNewInitializationStyle)
unsigned StoredInitializationStyle : 2;
diff --git a/clang/lib/AST/ExprCXX.cpp b/clang/lib/AST/ExprCXX.cpp
index 83af7998f68338..e61c11dffd8841 100644
--- a/clang/lib/AST/ExprCXX.cpp
+++ b/clang/lib/AST/ExprCXX.cpp
@@ -194,14 +194,14 @@ CXXNewExpr::CXXNewExpr(bool IsGlobalNew, FunctionDecl *OperatorNew,
DirectInitRange(DirectInitRange) {
assert((Initializer != nullptr ||
- InitializationStyle == CXXNewInitializationStyle::None ||
- InitializationStyle == CXXNewInitializationStyle::Implicit) &&
- "Only NoInit can have no initializer!");
+ InitializationStyle == CXXNewInitializationStyle::None) &&
+ "Only CXXNewInitializationStyle::None can have no initializer!");
CXXNewExprBits.IsGlobalNew = IsGlobalNew;
CXXNewExprBits.IsArray = ArraySize.has_value();
CXXNewExprBits.ShouldPassAlignment = ShouldPassAlignment;
CXXNewExprBits.UsualArrayDeleteWantsSize = UsualArrayDeleteWantsSize;
+ CXXNewExprBits.HasInitializer = Initializer != nullptr;
CXXNewExprBits.StoredInitializationStyle =
llvm::to_underlying(InitializationStyle);
bool IsParenTypeId = TypeIdParens.isValid();
@@ -219,10 +219,10 @@ CXXNewExpr::CXXNewExpr(bool IsGlobalNew, FunctionDecl *OperatorNew,
getTrailingObjects<SourceRange>()[0] = TypeIdParens;
switch (getInitializationStyle()) {
- case CXXNewInitializationStyle::Call:
+ case CXXNewInitializationStyle::Parens:
this->Range.setEnd(DirectInitRange.getEnd());
break;
- case CXXNewInitializationStyle::List:
+ case CXXNewInitializationStyle::Braces:
this->Range.setEnd(getInitializer()->getSourceRange().getEnd());
break;
default:
diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index b1678479888eb7..f78265df0713f5 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -4883,7 +4883,7 @@ void CXXNameMangler::mangleExpression(const Expr *E, unsigned Arity,
Out << '_';
mangleType(New->getAllocatedType());
if (New->hasInitializer()) {
- if (New->getInitializationStyle() == CXXNewInitializationStyle::List)
+ if (New->getInitializationStyle() == CXXNewInitializationStyle::Braces)
Out << "il";
else
Out << "pi";
@@ -4898,7 +4898,7 @@ void CXXNameMangler::mangleExpression(const Expr *E, unsigned Arity,
for (unsigned i = 0, e = PLE->getNumExprs(); i != e; ++i)
mangleExpression(PLE->getExpr(i));
} else if (New->getInitializationStyle() ==
- CXXNewInitializationStyle::List &&
+ CXXNewInitializationStyle::Braces &&
isa<InitListExpr>(Init)) {
// Only take InitListExprs apart for list-initialization.
mangleInitListElements(cast<InitListExpr>(Init));
diff --git a/clang/lib/AST/JSONNodeDumper.cpp b/clang/lib/AST/JSONNodeDumper.cpp
index cb3d3b0df1ee34..3daba13d0fce7b 100644
--- a/clang/lib/AST/JSONNodeDumper.cpp
+++ b/clang/lib/AST/JSONNodeDumper.cpp
@@ -1356,12 +1356,11 @@ void JSONNodeDumper::VisitCXXNewExpr(const CXXNewExpr *NE) {
attributeOnlyIfTrue("isPlacement", NE->getNumPlacementArgs() != 0);
switch (NE->getInitializationStyle()) {
case CXXNewInitializationStyle::None:
- case CXXNewInitializationStyle::Implicit:
break;
- case CXXNewInitializationStyle::Call:
+ case CXXNewInitializationStyle::Parens:
JOS.attribute("initStyle", "call");
break;
- case CXXNewInitializationStyle::List:
+ case CXXNewInitializationStyle::Braces:
JOS.attribute("initStyle", "list");
break;
}
diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp
index c04cb313c3387a..9d4aa07ec4da74 100644
--- a/clang/lib/AST/StmtPrinter.cpp
+++ b/clang/lib/AST/StmtPrinter.cpp
@@ -2300,9 +2300,8 @@ void StmtPrinter::VisitCXXNewExpr(CXXNewExpr *E) {
OS << ")";
CXXNewInitializationStyle InitStyle = E->getInitializationStyle();
- if (InitStyle != CXXNewInitializationStyle::None &&
- InitStyle != CXXNewInitializationStyle::Implicit) {
- bool Bare = InitStyle == CXXNewInitializationStyle::Call &&
+ if (InitStyle != CXXNewInitializationStyle::None) {
+ bool Bare = InitStyle == CXXNewInitializationStyle::Parens &&
!isa<ParenListExpr>(E->getInitializer());
if (Bare)
OS << "(";
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 8b6a80b45b27b1..482afb5a677ec5 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -1957,7 +1957,7 @@ static bool isLegalArrayNewInitializer(CXXNewInitializationStyle Style,
else if (CXXConstructExpr *CCE = dyn_cast<CXXConstructExpr>(Init))
return !CCE->isListInitialization() &&
CCE->getConstructor()->isDefaultConstructor();
- else if (Style == CXXNewInitializationStyle::List) {
+ else if (Style == CXXNewInitializationStyle::Braces) {
assert(isa<InitListExpr>(Init) &&
"Shouldn't create list CXXConstructExprs for arrays.");
return true;
@@ -2011,9 +2011,9 @@ ExprResult Sema::BuildCXXNew(SourceRange Range, bool UseGlobal,
CXXNewInitializationStyle InitStyle;
if (DirectInitRange.isValid()) {
assert(Initializer && "Have parens but no initializer.");
- InitStyle = CXXNewInitializationStyle::Call;
+ InitStyle = CXXNewInitializationStyle::Parens;
} else if (Initializer && isa<InitListExpr>(Initializer))
- InitStyle = CXXNewInitializationStyle::List;
+ InitStyle = CXXNewInitializationStyle::Braces;
else {
assert((!Initializer || isa<ImplicitValueInitExpr>(Initializer) ||
isa<CXXConstructExpr>(Initializer)) &&
@@ -2023,7 +2023,7 @@ ExprResult Sema::BuildCXXNew(SourceRange Range, bool UseGlobal,
MultiExprArg Exprs(&Initializer, Initializer ? 1 : 0);
if (ParenListExpr *List = dyn_cast_or_null<ParenListExpr>(Initializer)) {
- assert(InitStyle == CXXNewInitializationStyle::Call &&
+ assert(InitStyle == CXXNewInitializationStyle::Parens &&
"paren init for non-call init");
Exprs = MultiExprArg(List->getExprs(), List->getNumExprs());
}
@@ -2037,15 +2037,14 @@ ExprResult Sema::BuildCXXNew(SourceRange Range, bool UseGlobal,
// initialized (8.5); if no initialization is performed,
// the object has indeterminate value
case CXXNewInitializationStyle::None:
- case CXXNewInitializationStyle::Implicit:
return InitializationKind::CreateDefault(TypeRange.getBegin());
// - Otherwise, the new-initializer is interpreted according to the
// initialization rules of 8.5 for direct-initialization.
- case CXXNewInitializationStyle::Call:
+ case CXXNewInitializationStyle::Parens:
return InitializationKind::CreateDirect(TypeRange.getBegin(),
DirectInitRange.getBegin(),
DirectInitRange.getEnd());
- case CXXNewInitializationStyle::List:
+ case CXXNewInitializationStyle::Braces:
return InitializationKind::CreateDirectList(TypeRange.getBegin(),
Initializer->getBeginLoc(),
Initializer->getEndLoc());
@@ -2072,14 +2071,13 @@ ExprResult Sema::BuildCXXNew(SourceRange Range, bool UseGlobal,
return ExprError();
} else if (Deduced && !Deduced->isDeduced()) {
MultiExprArg Inits = Exprs;
- bool Braced = (InitStyle == CXXNewInitializationStyle::List);
+ bool Braced = (InitStyle == CXXNewInitializationStyle::Braces);
if (Braced) {
auto *ILE = cast<InitListExpr>(Exprs[0]);
Inits = MultiExprArg(ILE->getInits(), ILE->getNumInits());
}
- if (InitStyle == CXXNewInitializationStyle::None ||
- InitStyle == CXXNewInitializationStyle::Implicit || Inits.empty())
+ if (InitStyle == CXXNewInitializationStyle::None || Inits.empty())
return ExprError(Diag(StartLoc, diag::err_auto_new_requires_ctor_arg)
<< AllocType << TypeRange);
if (Inits.size() > 1) {
@@ -2447,14 +2445,6 @@ ExprResult Sema::BuildCXXNew(SourceRange Range, bool UseGlobal,
FullInit = Binder->getSubExpr();
Initializer = FullInit.get();
- // We don't know that we're generating an implicit initializer until now, so
- // we have to update the initialization style as well.
- //
- // FIXME: it would be nice to determine the correct initialization style
- // earlier so InitStyle doesn't need adjusting.
- if (InitStyle == CXXNewInitializationStyle::None && Initializer) {
- InitStyle = CXXNewInitializationStyle::Implicit;
- }
// FIXME: If we have a KnownArraySize, check that the array bound of the
// initializer is no greater than that constant value.
diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp
index 21aed570ba26ce..85ecfa1a1a0bf2 100644
--- a/clang/lib/Serialization/ASTReaderStmt.cpp
+++ b/clang/lib/Serialization/ASTReaderStmt.cpp
@@ -1901,6 +1901,7 @@ void ASTStmtReader::VisitCXXNewExpr(CXXNewExpr *E) {
E->CXXNewExprBits.IsGlobalNew = Record.readInt();
E->CXXNewExprBits.ShouldPassAlignment = Record.readInt();
E->CXXNewExprBits.UsualArrayDeleteWantsSize = Record.readInt();
+ E->CXXNewExprBits.HasInitializer = Record.readInt();
E->CXXNewExprBits.StoredInitializationStyle = Record.readInt();
assert((IsArray == E->isArray()) && "Wrong IsArray!");
diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp
index 7f888e44dde1e0..e5836f5dcbe955 100644
--- a/clang/lib/Serialization/ASTWriterStmt.cpp
+++ b/clang/lib/Serialization/ASTWriterStmt.cpp
@@ -1901,6 +1901,7 @@ void ASTStmtWriter::VisitCXXNewExpr(CXXNewExpr *E) {
Record.push_back(E->isGlobalNew());
Record.push_back(E->passAlignment());
Record.push_back(E->doesUsualArrayDeleteWantSize());
+ Record.push_back(E->CXXNewExprBits.HasInitializer);
Record.push_back(E->CXXNewExprBits.StoredInitializationStyle);
Record.AddDeclRef(E->getOperatorNew());
More information about the libcxx-commits
mailing list