Skip to content

Commit ace4489

Browse files
authored
[clang][NFC] Refactor CXXNewExpr::InitializationStyle (#71322)
This patch converts `CXXNewExpr::InitializationStyle` into a scoped enum at namespace scope. It also affirms the status quo by adding a new enumerator to represent implicit initializer.
1 parent e96889d commit ace4489

File tree

8 files changed

+96
-74
lines changed

8 files changed

+96
-74
lines changed

clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,8 @@ bool MakeSmartPtrCheck::replaceNew(DiagnosticBuilder &Diag,
323323
return false;
324324
};
325325
switch (New->getInitializationStyle()) {
326-
case CXXNewExpr::NoInit: {
326+
case CXXNewInitializationStyle::None:
327+
case CXXNewInitializationStyle::Implicit: {
327328
if (ArraySizeExpr.empty()) {
328329
Diag << FixItHint::CreateRemoval(SourceRange(NewStart, NewEnd));
329330
} else {
@@ -334,7 +335,7 @@ bool MakeSmartPtrCheck::replaceNew(DiagnosticBuilder &Diag,
334335
}
335336
break;
336337
}
337-
case CXXNewExpr::CallInit: {
338+
case CXXNewInitializationStyle::Call: {
338339
// FIXME: Add fixes for constructors with parameters that can be created
339340
// with a C++11 braced-init-list (e.g. std::vector, std::map).
340341
// Unlike ordinal cases, braced list can not be deduced in
@@ -371,7 +372,7 @@ bool MakeSmartPtrCheck::replaceNew(DiagnosticBuilder &Diag,
371372
}
372373
break;
373374
}
374-
case CXXNewExpr::ListInit: {
375+
case CXXNewInitializationStyle::List: {
375376
// Range of the substring that we do not want to remove.
376377
SourceRange InitRange;
377378
if (const auto *NewConstruct = New->getConstructExpr()) {

clang/include/clang/AST/ExprCXX.h

Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2206,6 +2206,20 @@ class CXXScalarValueInitExpr : public Expr {
22062206
}
22072207
};
22082208

2209+
enum class CXXNewInitializationStyle {
2210+
/// New-expression has no initializer as written.
2211+
None,
2212+
2213+
/// New-expression has no written initializer, but has an implicit one.
2214+
Implicit,
2215+
2216+
/// New-expression has a C++98 paren-delimited initializer.
2217+
Call,
2218+
2219+
/// New-expression has a C++11 list-initializer.
2220+
List
2221+
};
2222+
22092223
/// Represents a new-expression for memory allocation and constructor
22102224
/// calls, e.g: "new CXXNewExpr(foo)".
22112225
class CXXNewExpr final
@@ -2259,25 +2273,12 @@ class CXXNewExpr final
22592273
return isParenTypeId();
22602274
}
22612275

2262-
public:
2263-
enum InitializationStyle {
2264-
/// New-expression has no initializer as written.
2265-
NoInit,
2266-
2267-
/// New-expression has a C++98 paren-delimited initializer.
2268-
CallInit,
2269-
2270-
/// New-expression has a C++11 list-initializer.
2271-
ListInit
2272-
};
2273-
2274-
private:
22752276
/// Build a c++ new expression.
22762277
CXXNewExpr(bool IsGlobalNew, FunctionDecl *OperatorNew,
22772278
FunctionDecl *OperatorDelete, bool ShouldPassAlignment,
22782279
bool UsualArrayDeleteWantsSize, ArrayRef<Expr *> PlacementArgs,
22792280
SourceRange TypeIdParens, std::optional<Expr *> ArraySize,
2280-
InitializationStyle InitializationStyle, Expr *Initializer,
2281+
CXXNewInitializationStyle InitializationStyle, Expr *Initializer,
22812282
QualType Ty, TypeSourceInfo *AllocatedTypeInfo, SourceRange Range,
22822283
SourceRange DirectInitRange);
22832284

@@ -2292,7 +2293,7 @@ class CXXNewExpr final
22922293
FunctionDecl *OperatorDelete, bool ShouldPassAlignment,
22932294
bool UsualArrayDeleteWantsSize, ArrayRef<Expr *> PlacementArgs,
22942295
SourceRange TypeIdParens, std::optional<Expr *> ArraySize,
2295-
InitializationStyle InitializationStyle, Expr *Initializer,
2296+
CXXNewInitializationStyle InitializationStyle, Expr *Initializer,
22962297
QualType Ty, TypeSourceInfo *AllocatedTypeInfo, SourceRange Range,
22972298
SourceRange DirectInitRange);
22982299

@@ -2388,15 +2389,20 @@ class CXXNewExpr final
23882389

23892390
/// Whether this new-expression has any initializer at all.
23902391
bool hasInitializer() const {
2391-
return CXXNewExprBits.StoredInitializationStyle > 0;
2392+
switch (getInitializationStyle()) {
2393+
case CXXNewInitializationStyle::None:
2394+
return false;
2395+
case CXXNewInitializationStyle::Implicit:
2396+
case CXXNewInitializationStyle::Call:
2397+
case CXXNewInitializationStyle::List:
2398+
return true;
2399+
}
23922400
}
23932401

23942402
/// The kind of initializer this new-expression has.
2395-
InitializationStyle getInitializationStyle() const {
2396-
if (CXXNewExprBits.StoredInitializationStyle == 0)
2397-
return NoInit;
2398-
return static_cast<InitializationStyle>(
2399-
CXXNewExprBits.StoredInitializationStyle - 1);
2403+
CXXNewInitializationStyle getInitializationStyle() const {
2404+
return static_cast<CXXNewInitializationStyle>(
2405+
CXXNewExprBits.StoredInitializationStyle);
24002406
}
24012407

24022408
/// The initializer of this new-expression.

clang/lib/AST/ExprCXX.cpp

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ CXXNewExpr::CXXNewExpr(bool IsGlobalNew, FunctionDecl *OperatorNew,
184184
bool UsualArrayDeleteWantsSize,
185185
ArrayRef<Expr *> PlacementArgs, SourceRange TypeIdParens,
186186
std::optional<Expr *> ArraySize,
187-
InitializationStyle InitializationStyle,
187+
CXXNewInitializationStyle InitializationStyle,
188188
Expr *Initializer, QualType Ty,
189189
TypeSourceInfo *AllocatedTypeInfo, SourceRange Range,
190190
SourceRange DirectInitRange)
@@ -193,15 +193,17 @@ CXXNewExpr::CXXNewExpr(bool IsGlobalNew, FunctionDecl *OperatorNew,
193193
AllocatedTypeInfo(AllocatedTypeInfo), Range(Range),
194194
DirectInitRange(DirectInitRange) {
195195

196-
assert((Initializer != nullptr || InitializationStyle == NoInit) &&
196+
assert((Initializer != nullptr ||
197+
InitializationStyle == CXXNewInitializationStyle::None ||
198+
InitializationStyle == CXXNewInitializationStyle::Implicit) &&
197199
"Only NoInit can have no initializer!");
198200

199201
CXXNewExprBits.IsGlobalNew = IsGlobalNew;
200202
CXXNewExprBits.IsArray = ArraySize.has_value();
201203
CXXNewExprBits.ShouldPassAlignment = ShouldPassAlignment;
202204
CXXNewExprBits.UsualArrayDeleteWantsSize = UsualArrayDeleteWantsSize;
203205
CXXNewExprBits.StoredInitializationStyle =
204-
Initializer ? InitializationStyle + 1 : 0;
206+
llvm::to_underlying(InitializationStyle);
205207
bool IsParenTypeId = TypeIdParens.isValid();
206208
CXXNewExprBits.IsParenTypeId = IsParenTypeId;
207209
CXXNewExprBits.NumPlacementArgs = PlacementArgs.size();
@@ -217,10 +219,10 @@ CXXNewExpr::CXXNewExpr(bool IsGlobalNew, FunctionDecl *OperatorNew,
217219
getTrailingObjects<SourceRange>()[0] = TypeIdParens;
218220

219221
switch (getInitializationStyle()) {
220-
case CallInit:
222+
case CXXNewInitializationStyle::Call:
221223
this->Range.setEnd(DirectInitRange.getEnd());
222224
break;
223-
case ListInit:
225+
case CXXNewInitializationStyle::List:
224226
this->Range.setEnd(getInitializer()->getSourceRange().getEnd());
225227
break;
226228
default:
@@ -240,15 +242,14 @@ CXXNewExpr::CXXNewExpr(EmptyShell Empty, bool IsArray,
240242
CXXNewExprBits.IsParenTypeId = IsParenTypeId;
241243
}
242244

243-
CXXNewExpr *
244-
CXXNewExpr::Create(const ASTContext &Ctx, bool IsGlobalNew,
245-
FunctionDecl *OperatorNew, FunctionDecl *OperatorDelete,
246-
bool ShouldPassAlignment, bool UsualArrayDeleteWantsSize,
247-
ArrayRef<Expr *> PlacementArgs, SourceRange TypeIdParens,
248-
std::optional<Expr *> ArraySize,
249-
InitializationStyle InitializationStyle, Expr *Initializer,
250-
QualType Ty, TypeSourceInfo *AllocatedTypeInfo,
251-
SourceRange Range, SourceRange DirectInitRange) {
245+
CXXNewExpr *CXXNewExpr::Create(
246+
const ASTContext &Ctx, bool IsGlobalNew, FunctionDecl *OperatorNew,
247+
FunctionDecl *OperatorDelete, bool ShouldPassAlignment,
248+
bool UsualArrayDeleteWantsSize, ArrayRef<Expr *> PlacementArgs,
249+
SourceRange TypeIdParens, std::optional<Expr *> ArraySize,
250+
CXXNewInitializationStyle InitializationStyle, Expr *Initializer,
251+
QualType Ty, TypeSourceInfo *AllocatedTypeInfo, SourceRange Range,
252+
SourceRange DirectInitRange) {
252253
bool IsArray = ArraySize.has_value();
253254
bool HasInit = Initializer != nullptr;
254255
unsigned NumPlacementArgs = PlacementArgs.size();

clang/lib/AST/ItaniumMangle.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4826,7 +4826,7 @@ void CXXNameMangler::mangleExpression(const Expr *E, unsigned Arity,
48264826
Out << '_';
48274827
mangleType(New->getAllocatedType());
48284828
if (New->hasInitializer()) {
4829-
if (New->getInitializationStyle() == CXXNewExpr::ListInit)
4829+
if (New->getInitializationStyle() == CXXNewInitializationStyle::List)
48304830
Out << "il";
48314831
else
48324832
Out << "pi";
@@ -4840,7 +4840,8 @@ void CXXNameMangler::mangleExpression(const Expr *E, unsigned Arity,
48404840
} else if (const ParenListExpr *PLE = dyn_cast<ParenListExpr>(Init)) {
48414841
for (unsigned i = 0, e = PLE->getNumExprs(); i != e; ++i)
48424842
mangleExpression(PLE->getExpr(i));
4843-
} else if (New->getInitializationStyle() == CXXNewExpr::ListInit &&
4843+
} else if (New->getInitializationStyle() ==
4844+
CXXNewInitializationStyle::List &&
48444845
isa<InitListExpr>(Init)) {
48454846
// Only take InitListExprs apart for list-initialization.
48464847
mangleInitListElements(cast<InitListExpr>(Init));

clang/lib/AST/JSONNodeDumper.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1351,9 +1351,15 @@ void JSONNodeDumper::VisitCXXNewExpr(const CXXNewExpr *NE) {
13511351
attributeOnlyIfTrue("isArray", NE->isArray());
13521352
attributeOnlyIfTrue("isPlacement", NE->getNumPlacementArgs() != 0);
13531353
switch (NE->getInitializationStyle()) {
1354-
case CXXNewExpr::NoInit: break;
1355-
case CXXNewExpr::CallInit: JOS.attribute("initStyle", "call"); break;
1356-
case CXXNewExpr::ListInit: JOS.attribute("initStyle", "list"); break;
1354+
case CXXNewInitializationStyle::None:
1355+
case CXXNewInitializationStyle::Implicit:
1356+
break;
1357+
case CXXNewInitializationStyle::Call:
1358+
JOS.attribute("initStyle", "call");
1359+
break;
1360+
case CXXNewInitializationStyle::List:
1361+
JOS.attribute("initStyle", "list");
1362+
break;
13571363
}
13581364
if (const FunctionDecl *FD = NE->getOperatorNew())
13591365
JOS.attribute("operatorNewDecl", createBareDeclRef(FD));

clang/lib/AST/StmtPrinter.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2298,9 +2298,10 @@ void StmtPrinter::VisitCXXNewExpr(CXXNewExpr *E) {
22982298
if (E->isParenTypeId())
22992299
OS << ")";
23002300

2301-
CXXNewExpr::InitializationStyle InitStyle = E->getInitializationStyle();
2302-
if (InitStyle != CXXNewExpr::NoInit) {
2303-
bool Bare = InitStyle == CXXNewExpr::CallInit &&
2301+
CXXNewInitializationStyle InitStyle = E->getInitializationStyle();
2302+
if (InitStyle != CXXNewInitializationStyle::None &&
2303+
InitStyle != CXXNewInitializationStyle::Implicit) {
2304+
bool Bare = InitStyle == CXXNewInitializationStyle::Call &&
23042305
!isa<ParenListExpr>(E->getInitializer());
23052306
if (Bare)
23062307
OS << "(";

clang/lib/AST/StmtProfile.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2096,7 +2096,7 @@ void StmtProfiler::VisitCXXNewExpr(const CXXNewExpr *S) {
20962096
ID.AddInteger(S->getNumPlacementArgs());
20972097
ID.AddBoolean(S->isGlobalNew());
20982098
ID.AddBoolean(S->isParenTypeId());
2099-
ID.AddInteger(S->getInitializationStyle());
2099+
ID.AddInteger(llvm::to_underlying(S->getInitializationStyle()));
21002100
}
21012101

21022102
void

clang/lib/Sema/SemaExprCXX.cpp

Lines changed: 33 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1946,7 +1946,7 @@ Sema::ActOnCXXNew(SourceLocation StartLoc, bool UseGlobal,
19461946
Initializer);
19471947
}
19481948

1949-
static bool isLegalArrayNewInitializer(CXXNewExpr::InitializationStyle Style,
1949+
static bool isLegalArrayNewInitializer(CXXNewInitializationStyle Style,
19501950
Expr *Init) {
19511951
if (!Init)
19521952
return true;
@@ -1957,7 +1957,7 @@ static bool isLegalArrayNewInitializer(CXXNewExpr::InitializationStyle Style,
19571957
else if (CXXConstructExpr *CCE = dyn_cast<CXXConstructExpr>(Init))
19581958
return !CCE->isListInitialization() &&
19591959
CCE->getConstructor()->isDefaultConstructor();
1960-
else if (Style == CXXNewExpr::ListInit) {
1960+
else if (Style == CXXNewInitializationStyle::List) {
19611961
assert(isa<InitListExpr>(Init) &&
19621962
"Shouldn't create list CXXConstructExprs for arrays.");
19631963
return true;
@@ -2008,44 +2008,49 @@ ExprResult Sema::BuildCXXNew(SourceRange Range, bool UseGlobal,
20082008
SourceRange TypeRange = AllocTypeInfo->getTypeLoc().getSourceRange();
20092009
SourceLocation StartLoc = Range.getBegin();
20102010

2011-
CXXNewExpr::InitializationStyle initStyle;
2011+
CXXNewInitializationStyle InitStyle;
20122012
if (DirectInitRange.isValid()) {
20132013
assert(Initializer && "Have parens but no initializer.");
2014-
initStyle = CXXNewExpr::CallInit;
2014+
InitStyle = CXXNewInitializationStyle::Call;
20152015
} else if (Initializer && isa<InitListExpr>(Initializer))
2016-
initStyle = CXXNewExpr::ListInit;
2016+
InitStyle = CXXNewInitializationStyle::List;
20172017
else {
20182018
assert((!Initializer || isa<ImplicitValueInitExpr>(Initializer) ||
20192019
isa<CXXConstructExpr>(Initializer)) &&
20202020
"Initializer expression that cannot have been implicitly created.");
2021-
initStyle = CXXNewExpr::NoInit;
2021+
InitStyle = CXXNewInitializationStyle::None;
20222022
}
20232023

20242024
MultiExprArg Exprs(&Initializer, Initializer ? 1 : 0);
20252025
if (ParenListExpr *List = dyn_cast_or_null<ParenListExpr>(Initializer)) {
2026-
assert(initStyle == CXXNewExpr::CallInit && "paren init for non-call init");
2026+
assert(InitStyle == CXXNewInitializationStyle::Call &&
2027+
"paren init for non-call init");
20272028
Exprs = MultiExprArg(List->getExprs(), List->getNumExprs());
20282029
}
20292030

20302031
// C++11 [expr.new]p15:
20312032
// A new-expression that creates an object of type T initializes that
20322033
// object as follows:
2033-
InitializationKind Kind
2034-
// - If the new-initializer is omitted, the object is default-
2035-
// initialized (8.5); if no initialization is performed,
2036-
// the object has indeterminate value
2037-
= initStyle == CXXNewExpr::NoInit
2038-
? InitializationKind::CreateDefault(TypeRange.getBegin())
2039-
// - Otherwise, the new-initializer is interpreted according to
2040-
// the
2041-
// initialization rules of 8.5 for direct-initialization.
2042-
: initStyle == CXXNewExpr::ListInit
2043-
? InitializationKind::CreateDirectList(
2044-
TypeRange.getBegin(), Initializer->getBeginLoc(),
2045-
Initializer->getEndLoc())
2046-
: InitializationKind::CreateDirect(TypeRange.getBegin(),
2047-
DirectInitRange.getBegin(),
2048-
DirectInitRange.getEnd());
2034+
InitializationKind Kind = [&] {
2035+
switch (InitStyle) {
2036+
// - If the new-initializer is omitted, the object is default-
2037+
// initialized (8.5); if no initialization is performed,
2038+
// the object has indeterminate value
2039+
case CXXNewInitializationStyle::None:
2040+
case CXXNewInitializationStyle::Implicit:
2041+
return InitializationKind::CreateDefault(TypeRange.getBegin());
2042+
// - Otherwise, the new-initializer is interpreted according to the
2043+
// initialization rules of 8.5 for direct-initialization.
2044+
case CXXNewInitializationStyle::Call:
2045+
return InitializationKind::CreateDirect(TypeRange.getBegin(),
2046+
DirectInitRange.getBegin(),
2047+
DirectInitRange.getEnd());
2048+
case CXXNewInitializationStyle::List:
2049+
return InitializationKind::CreateDirectList(TypeRange.getBegin(),
2050+
Initializer->getBeginLoc(),
2051+
Initializer->getEndLoc());
2052+
}
2053+
}();
20492054

20502055
// C++11 [dcl.spec.auto]p6. Deduce the type which 'auto' stands in for.
20512056
auto *Deduced = AllocType->getContainedDeducedType();
@@ -2066,13 +2071,14 @@ ExprResult Sema::BuildCXXNew(SourceRange Range, bool UseGlobal,
20662071
return ExprError();
20672072
} else if (Deduced && !Deduced->isDeduced()) {
20682073
MultiExprArg Inits = Exprs;
2069-
bool Braced = (initStyle == CXXNewExpr::ListInit);
2074+
bool Braced = (InitStyle == CXXNewInitializationStyle::List);
20702075
if (Braced) {
20712076
auto *ILE = cast<InitListExpr>(Exprs[0]);
20722077
Inits = MultiExprArg(ILE->getInits(), ILE->getNumInits());
20732078
}
20742079

2075-
if (initStyle == CXXNewExpr::NoInit || Inits.empty())
2080+
if (InitStyle == CXXNewInitializationStyle::None ||
2081+
InitStyle == CXXNewInitializationStyle::Implicit || Inits.empty())
20762082
return ExprError(Diag(StartLoc, diag::err_auto_new_requires_ctor_arg)
20772083
<< AllocType << TypeRange);
20782084
if (Inits.size() > 1) {
@@ -2396,7 +2402,7 @@ ExprResult Sema::BuildCXXNew(SourceRange Range, bool UseGlobal,
23962402
// Array 'new' can't have any initializers except empty parentheses.
23972403
// Initializer lists are also allowed, in C++11. Rely on the parser for the
23982404
// dialect distinction.
2399-
if (ArraySize && !isLegalArrayNewInitializer(initStyle, Initializer)) {
2405+
if (ArraySize && !isLegalArrayNewInitializer(InitStyle, Initializer)) {
24002406
SourceRange InitRange(Exprs.front()->getBeginLoc(),
24012407
Exprs.back()->getEndLoc());
24022408
Diag(StartLoc, diag::err_new_array_init_args) << InitRange;
@@ -2468,7 +2474,7 @@ ExprResult Sema::BuildCXXNew(SourceRange Range, bool UseGlobal,
24682474

24692475
return CXXNewExpr::Create(Context, UseGlobal, OperatorNew, OperatorDelete,
24702476
PassAlignment, UsualArrayDeleteWantsSize,
2471-
PlacementArgs, TypeIdParens, ArraySize, initStyle,
2477+
PlacementArgs, TypeIdParens, ArraySize, InitStyle,
24722478
Initializer, ResultType, AllocTypeInfo, Range,
24732479
DirectInitRange);
24742480
}

0 commit comments

Comments
 (0)