[clang] [clang-tools-extra] [clang] Make `InitListExpr::isExplicit()` work (PR #195175)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Apr 30 13:47:29 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-hlsl
@llvm/pr-subscribers-clang-modules
Author: Andrey Ali Khan Bolshakov (bolshakov-a)
<details>
<summary>Changes</summary>
The main goal of this change is to be able to use `isExplicit()` check in the IWYU tool. Consider the following:
```cpp
struct Inner {};
struct Outer {
Inner inner;
};
const Outer& refOuter = {};
```
Here, Clang generates `InitListExpr` child node for the implicit `Inner` initialization under the `InitListExpr` node corresponding to the initializer of `refOuter`. IWYU should require the header containing `Outer` definition for the initializer, but not the header for `Inner` because it should be already provided by `Outer`.
'IsExplicit' flag is copied from a template instantiation pattern into its instantiations although they are implicit because it makes sense for IWYU at least. (After all, instantiated declarations refer to the pattern explicitly written in the source.)
This is an NFC from the point of view of users of the Clang standalone executable (except the change in AST dumping), but a functional change for those who use Clang as a library.
---
Patch is 63.80 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/195175.diff
29 Files Affected:
- (modified) clang-tools-extra/clang-tidy/utils/DesignatedInitializers.cpp (+6-20)
- (modified) clang/docs/LibASTMatchersReference.html (+1-1)
- (modified) clang/include/clang/AST/Expr.h (+3-6)
- (modified) clang/include/clang/AST/Stmt.h (+4)
- (modified) clang/include/clang/ASTMatchers/ASTMatchers.h (+2-2)
- (modified) clang/include/clang/Sema/Sema.h (+1-1)
- (modified) clang/lib/AST/ASTImporter.cpp (+2-2)
- (modified) clang/lib/AST/Expr.cpp (+5-2)
- (modified) clang/lib/AST/TextNodeDumper.cpp (+1)
- (modified) clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp (+4-4)
- (modified) clang/lib/Frontend/Rewrite/RewriteObjC.cpp (+4-4)
- (modified) clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp (+2-2)
- (modified) clang/lib/Sema/SemaExpr.cpp (+11-10)
- (modified) clang/lib/Sema/SemaHLSL.cpp (+6-4)
- (modified) clang/lib/Sema/SemaInit.cpp (+23-17)
- (modified) clang/lib/Sema/SemaOpenACC.cpp (+9-6)
- (modified) clang/lib/Sema/SemaOverload.cpp (+1-1)
- (modified) clang/lib/Sema/SemaTemplate.cpp (+2-1)
- (modified) clang/lib/Sema/TreeTransform.h (+8-7)
- (modified) clang/lib/Serialization/ASTReaderStmt.cpp (+1)
- (modified) clang/lib/Serialization/ASTWriterStmt.cpp (+1)
- (modified) clang/test/AST/HLSL/matrix-constructors.hlsl (+28-11)
- (modified) clang/test/AST/ast-dump-decl.cpp (+6-6)
- (modified) clang/test/AST/ast-dump-stmt.cpp (+3-3)
- (modified) clang/test/CXX/drs/cwg2149.cpp (+6-6)
- (modified) clang/test/SemaCXX/compound-literal.cpp (+3-3)
- (modified) clang/test/SemaHLSL/Language/InitListAST.hlsl (+11-11)
- (modified) clang/unittests/AST/ASTExprTest.cpp (+245-2)
- (modified) clang/unittests/AST/ASTImporterTest.cpp (+15-13)
``````````diff
diff --git a/clang-tools-extra/clang-tidy/utils/DesignatedInitializers.cpp b/clang-tools-extra/clang-tidy/utils/DesignatedInitializers.cpp
index 908a1b5ec4e09..7efcd614cd2ac 100644
--- a/clang-tools-extra/clang-tidy/utils/DesignatedInitializers.cpp
+++ b/clang-tools-extra/clang-tidy/utils/DesignatedInitializers.cpp
@@ -14,7 +14,6 @@
#include "DesignatedInitializers.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/Type.h"
-#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/ScopeExit.h"
namespace clang::tidy::utils {
@@ -129,9 +128,9 @@ class AggregateDesignatorNames {
// '.a:' is produced directly without recursing into the written sublist.
// (The written sublist will have a separate collectDesignators() call later).
// Recursion with Prefix='.b' and Sem = {3, ImplicitValue} produces '.b.x:'.
-static void collectDesignators(
- const InitListExpr *Sem, llvm::DenseMap<SourceLocation, std::string> &Out,
- const llvm::DenseSet<SourceLocation> &NestedBraces, std::string &Prefix) {
+static void collectDesignators(const InitListExpr *Sem,
+ llvm::DenseMap<SourceLocation, std::string> &Out,
+ std::string &Prefix) {
if (!Sem || Sem->isTransparent())
return;
assert(Sem->isSemanticForm());
@@ -152,8 +151,7 @@ static void collectDesignators(
continue;
const auto *BraceElidedSubobject = dyn_cast<InitListExpr>(Init);
- if (BraceElidedSubobject &&
- NestedBraces.contains(BraceElidedSubobject->getLBraceLoc()))
+ if (BraceElidedSubobject && BraceElidedSubobject->isExplicit())
BraceElidedSubobject = nullptr; // there were braces!
if (!Fields.append(Prefix, BraceElidedSubobject != nullptr))
@@ -162,9 +160,7 @@ static void collectDesignators(
// If the braces were elided, this aggregate subobject is initialized
// inline in the same syntactic list.
// Descend into the semantic list describing the subobject.
- // (NestedBraces are still correct, they're from the same syntactic
- // list).
- collectDesignators(BraceElidedSubobject, Out, NestedBraces, Prefix);
+ collectDesignators(BraceElidedSubobject, Out, Prefix);
continue;
}
Out.try_emplace(Init->getBeginLoc(), Prefix);
@@ -173,22 +169,12 @@ static void collectDesignators(
llvm::DenseMap<SourceLocation, std::string>
getUnwrittenDesignators(const InitListExpr *Syn) {
- assert(Syn->isSyntacticForm());
-
- // collectDesignators needs to know which InitListExprs in the semantic tree
- // were actually written, but InitListExpr::isExplicit() lies.
- // Instead, record where braces of sub-init-lists occur in the syntactic form.
- llvm::DenseSet<SourceLocation> NestedBraces;
- for (const Expr *Init : Syn->inits())
- if (auto *Nested = dyn_cast<InitListExpr>(Init))
- NestedBraces.insert(Nested->getLBraceLoc());
-
// Traverse the semantic form to find the designators.
// We use their SourceLocation to correlate with the syntactic form later.
llvm::DenseMap<SourceLocation, std::string> Designators;
std::string EmptyPrefix;
collectDesignators(Syn->isSemanticForm() ? Syn : Syn->getSemanticForm(),
- Designators, NestedBraces, EmptyPrefix);
+ Designators, EmptyPrefix);
return Designators;
}
diff --git a/clang/docs/LibASTMatchersReference.html b/clang/docs/LibASTMatchersReference.html
index 9f9d4223bb50a..b13eec72f9e3b 100644
--- a/clang/docs/LibASTMatchersReference.html
+++ b/clang/docs/LibASTMatchersReference.html
@@ -3322,7 +3322,7 @@ <h2 id="narrowing-matchers">Narrowing Matchers</h2>
<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXConstructorDecl.html">CXXConstructorDecl</a>></td><td class="name" onclick="toggle('isExplicit0')"><a name="isExplicit0Anchor">isExplicit</a></td><td></td></tr>
<tr><td colspan="4" class="doc" id="isExplicit0"><pre>Matches constructor, conversion function, and deduction guide declarations
that have an explicit specifier if this explicit specifier is resolved to
-true.
+true. Also matches explicitly written initializer list expressions.
Given
template<bool b>
diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h
index a0ab599fa82d2..7ef7b3d030d43 100644
--- a/clang/include/clang/AST/Expr.h
+++ b/clang/include/clang/AST/Expr.h
@@ -5323,7 +5323,8 @@ class InitListExpr : public Expr {
public:
InitListExpr(const ASTContext &C, SourceLocation lbraceloc,
- ArrayRef<Expr*> initExprs, SourceLocation rbraceloc);
+ ArrayRef<Expr *> initExprs, SourceLocation rbraceloc,
+ bool isExplicit);
/// Build an empty initializer list.
explicit InitListExpr(EmptyShell Empty)
@@ -5441,11 +5442,7 @@ class InitListExpr : public Expr {
// Explicit InitListExpr's originate from source code (and have valid source
// locations). Implicit InitListExpr's are created by the semantic analyzer.
- // FIXME: This is wrong; InitListExprs created by semantic analysis have
- // valid source locations too!
- bool isExplicit() const {
- return LBraceLoc.isValid() && RBraceLoc.isValid();
- }
+ bool isExplicit() const { return InitListExprBits.IsExplicit; }
/// Is this an initializer for an array of characters, initialized by a string
/// literal or an @encode?
diff --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h
index d940aa6562c4c..f07ba9205661b 100644
--- a/clang/include/clang/AST/Stmt.h
+++ b/clang/include/clang/AST/Stmt.h
@@ -670,6 +670,7 @@ class alignas(void *) Stmt {
};
class InitListExprBitfields {
+ friend class ASTStmtReader;
friend class InitListExpr;
LLVM_PREFERRED_TYPE(ExprBitfields)
@@ -679,6 +680,9 @@ class alignas(void *) Stmt {
/// designator in it. This is a temporary marker used by CodeGen.
LLVM_PREFERRED_TYPE(bool)
unsigned HadArrayRangeDesignator : 1;
+ // Whether this list is explicitly written in the source (with braces).
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned IsExplicit : 1;
};
class ParenListExprBitfields {
diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h
index e7e70e59dfedd..ffceb9269fc6e 100644
--- a/clang/include/clang/ASTMatchers/ASTMatchers.h
+++ b/clang/include/clang/ASTMatchers/ASTMatchers.h
@@ -8122,7 +8122,7 @@ AST_MATCHER(CXXConstructorDecl, isDelegatingConstructor) {
/// Matches constructor, conversion function, and deduction guide declarations
/// that have an explicit specifier if this explicit specifier is resolved to
-/// true.
+/// true. Also matches explicitly written initializer list expressions.
///
/// Given
/// \code
@@ -8144,7 +8144,7 @@ AST_MATCHER(CXXConstructorDecl, isDelegatingConstructor) {
/// cxxDeductionGuideDecl(isExplicit()) will match #6, but not #5.
AST_POLYMORPHIC_MATCHER(isExplicit, AST_POLYMORPHIC_SUPPORTED_TYPES(
CXXConstructorDecl, CXXConversionDecl,
- CXXDeductionGuideDecl)) {
+ CXXDeductionGuideDecl, InitListExpr)) {
return Node.isExplicit();
}
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index f9bf3e4de0a5e..b24ddd0e1ca6b 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -7595,7 +7595,7 @@ class Sema final : public SemaBase {
SourceLocation RBraceLoc);
ExprResult BuildInitList(SourceLocation LBraceLoc, MultiExprArg InitArgList,
- SourceLocation RBraceLoc);
+ SourceLocation RBraceLoc, bool IsExplicit);
/// Binary Operators. 'Tok' is the token for the operator.
ExprResult ActOnBinOp(Scope *S, SourceLocation TokLoc, tok::TokenKind Kind,
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index 4c8cc31421200..3001f18c98605 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -9028,8 +9028,8 @@ ExpectedStmt ASTNodeImporter::VisitInitListExpr(InitListExpr *E) {
return std::move(Err);
ASTContext &ToCtx = Importer.getToContext();
- InitListExpr *To = new (ToCtx) InitListExpr(
- ToCtx, ToLBraceLoc, ToExprs, ToRBraceLoc);
+ InitListExpr *To = new (ToCtx)
+ InitListExpr(ToCtx, ToLBraceLoc, ToExprs, ToRBraceLoc, E->isExplicit());
To->setType(ToType);
if (E->hasArrayFiller()) {
diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp
index 64d61dbc3d128..d5048f7aecad0 100644
--- a/clang/lib/AST/Expr.cpp
+++ b/clang/lib/AST/Expr.cpp
@@ -2404,12 +2404,14 @@ EmbedExpr::EmbedExpr(const ASTContext &Ctx, SourceLocation Loc,
}
InitListExpr::InitListExpr(const ASTContext &C, SourceLocation lbraceloc,
- ArrayRef<Expr *> initExprs, SourceLocation rbraceloc)
+ ArrayRef<Expr *> initExprs, SourceLocation rbraceloc,
+ bool isExplicit)
: Expr(InitListExprClass, QualType(), VK_PRValue, OK_Ordinary),
InitExprs(C, initExprs.size()), LBraceLoc(lbraceloc),
RBraceLoc(rbraceloc), AltForm(nullptr, true) {
sawArrayRangeDesignator(false);
InitExprs.insert(C, InitExprs.end(), initExprs.begin(), initExprs.end());
+ InitListExprBits.IsExplicit = isExplicit;
setDependence(computeDependence(this));
}
@@ -4933,7 +4935,8 @@ DesignatedInitUpdateExpr::DesignatedInitUpdateExpr(const ASTContext &C,
OK_Ordinary) {
BaseAndUpdaterExprs[0] = baseExpr;
- InitListExpr *ILE = new (C) InitListExpr(C, lBraceLoc, {}, rBraceLoc);
+ InitListExpr *ILE =
+ new (C) InitListExpr(C, lBraceLoc, {}, rBraceLoc, /*isExplicit=*/false);
ILE->setType(baseExpr->getType());
BaseAndUpdaterExprs[1] = ILE;
diff --git a/clang/lib/AST/TextNodeDumper.cpp b/clang/lib/AST/TextNodeDumper.cpp
index 53982025dfd4d..ed2c1d72a9fa2 100644
--- a/clang/lib/AST/TextNodeDumper.cpp
+++ b/clang/lib/AST/TextNodeDumper.cpp
@@ -1648,6 +1648,7 @@ void TextNodeDumper::VisitInitListExpr(const InitListExpr *ILE) {
OS << " field ";
dumpBareDeclRef(Field);
}
+ OS << ' ' << (ILE->isExplicit() ? "explicit" : "implicit");
}
void TextNodeDumper::VisitGenericSelectionExpr(const GenericSelectionExpr *E) {
diff --git a/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp b/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp
index dee29fe004f42..12442040b13bb 100644
--- a/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp
+++ b/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp
@@ -3294,8 +3294,8 @@ Stmt *RewriteModernObjC::SynthMessageExpr(ObjCMessageExpr *Exp,
} else {
// (struct __rw_objc_super) { <exprs from above> }
InitListExpr *ILE =
- new (Context) InitListExpr(*Context, SourceLocation(), InitExprs,
- SourceLocation());
+ new (Context) InitListExpr(*Context, SourceLocation(), InitExprs,
+ SourceLocation(), /*isExplicit=*/true);
TypeSourceInfo *superTInfo
= Context->getTrivialTypeSourceInfo(superType);
SuperRep = new (Context) CompoundLiteralExpr(SourceLocation(), superTInfo,
@@ -3386,8 +3386,8 @@ Stmt *RewriteModernObjC::SynthMessageExpr(ObjCMessageExpr *Exp,
} else {
// (struct __rw_objc_super) { <exprs from above> }
InitListExpr *ILE =
- new (Context) InitListExpr(*Context, SourceLocation(), InitExprs,
- SourceLocation());
+ new (Context) InitListExpr(*Context, SourceLocation(), InitExprs,
+ SourceLocation(), /*isExplicit=*/true);
TypeSourceInfo *superTInfo
= Context->getTrivialTypeSourceInfo(superType);
SuperRep = new (Context) CompoundLiteralExpr(
diff --git a/clang/lib/Frontend/Rewrite/RewriteObjC.cpp b/clang/lib/Frontend/Rewrite/RewriteObjC.cpp
index b9c025de87739..6b8753e29b8fe 100644
--- a/clang/lib/Frontend/Rewrite/RewriteObjC.cpp
+++ b/clang/lib/Frontend/Rewrite/RewriteObjC.cpp
@@ -2722,8 +2722,8 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp,
} else {
// (struct objc_super) { <exprs from above> }
InitListExpr *ILE =
- new (Context) InitListExpr(*Context, SourceLocation(), InitExprs,
- SourceLocation());
+ new (Context) InitListExpr(*Context, SourceLocation(), InitExprs,
+ SourceLocation(), /*isExplicit=*/true);
TypeSourceInfo *superTInfo
= Context->getTrivialTypeSourceInfo(superType);
SuperRep = new (Context) CompoundLiteralExpr(SourceLocation(), superTInfo,
@@ -2814,8 +2814,8 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp,
} else {
// (struct objc_super) { <exprs from above> }
InitListExpr *ILE =
- new (Context) InitListExpr(*Context, SourceLocation(), InitExprs,
- SourceLocation());
+ new (Context) InitListExpr(*Context, SourceLocation(), InitExprs,
+ SourceLocation(), /*isExplicit=*/true);
TypeSourceInfo *superTInfo
= Context->getTrivialTypeSourceInfo(superType);
SuperRep = new (Context) CompoundLiteralExpr(
diff --git a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp
index ba8e63f01527a..af9c7de2d855d 100644
--- a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp
+++ b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp
@@ -649,8 +649,8 @@ BuiltinTypeMethodBuilder &BuiltinTypeMethodBuilder::concat(V Vec, S Scalar,
}
Elts.push_back(ScalarExpr);
- auto *InitList =
- new (AST) InitListExpr(AST, SourceLocation(), Elts, SourceLocation());
+ auto *InitList = new (AST) InitListExpr(
+ AST, SourceLocation(), Elts, SourceLocation(), /*isExplicit=*/false);
InitList->setType(ResultTy);
ExprResult Cast = DeclBuilder.SemaRef.BuildCStyleCastExpr(
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index c494669420282..0fe296e3f8a91 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -7594,12 +7594,12 @@ Sema::ActOnInitList(SourceLocation LBraceLoc, MultiExprArg InitArgList,
}
}
- return BuildInitList(LBraceLoc, InitArgList, RBraceLoc);
+ return BuildInitList(LBraceLoc, InitArgList, RBraceLoc, /*IsExplicit=*/true);
}
-ExprResult
-Sema::BuildInitList(SourceLocation LBraceLoc, MultiExprArg InitArgList,
- SourceLocation RBraceLoc) {
+ExprResult Sema::BuildInitList(SourceLocation LBraceLoc,
+ MultiExprArg InitArgList,
+ SourceLocation RBraceLoc, bool IsExplicit) {
// Semantic analysis for initializers is done by ActOnDeclarator() and
// CheckInitializer() - it requires knowledge of the object being initialized.
@@ -7617,8 +7617,8 @@ Sema::BuildInitList(SourceLocation LBraceLoc, MultiExprArg InitArgList,
}
}
- InitListExpr *E =
- new (Context) InitListExpr(Context, LBraceLoc, InitArgList, RBraceLoc);
+ InitListExpr *E = new (Context)
+ InitListExpr(Context, LBraceLoc, InitArgList, RBraceLoc, IsExplicit);
E->setType(Context.VoidTy); // FIXME: just a place holder for now.
return E;
}
@@ -8287,8 +8287,9 @@ ExprResult Sema::BuildVectorLiteral(SourceLocation LParenLoc,
}
// FIXME: This means that pretty-printing the final AST will produce curly
// braces instead of the original commas.
- InitListExpr *initE = new (Context) InitListExpr(Context, LiteralLParenLoc,
- initExprs, LiteralRParenLoc);
+ InitListExpr *initE =
+ new (Context) InitListExpr(Context, LiteralLParenLoc, initExprs,
+ LiteralRParenLoc, /*isExplicit=*/false);
initE->setType(Ty);
return BuildCompoundLiteralExpr(LParenLoc, TInfo, RParenLoc, initE);
}
@@ -10045,8 +10046,8 @@ static void ConstructTransparentUnion(Sema &S, ASTContext &C,
// Build an initializer list that designates the appropriate member
// of the transparent union.
Expr *E = EResult.get();
- InitListExpr *Initializer = new (C) InitListExpr(C, SourceLocation(),
- E, SourceLocation());
+ InitListExpr *Initializer = new (C) InitListExpr(
+ C, SourceLocation(), E, SourceLocation(), /*isExplicit=*/false);
Initializer->setType(UnionType);
Initializer->setInitializedFieldInUnion(Field);
diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index aba1c5072a5fc..1541c0954f764 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -5933,8 +5933,9 @@ class InitListTransformer {
Inits.push_back(generateInitListsImpl(FD->getType()));
}
}
- auto *NewInit = new (Ctx) InitListExpr(Ctx, Inits.front()->getBeginLoc(),
- Inits, Inits.back()->getEndLoc());
+ auto *NewInit =
+ new (Ctx) InitListExpr(Ctx, Inits.front()->getBeginLoc(), Inits,
+ Inits.back()->getEndLoc(), /*isExplicit=*/false);
NewInit->setType(Ty);
return NewInit;
}
@@ -5970,8 +5971,9 @@ class InitListTransformer {
while (ArgIt != ArgExprs.end())
Inits.push_back(generateInitListsImpl(InitTy));
- auto *NewInit = new (Ctx) InitListExpr(Ctx, Inits.front()->getBeginLoc(),
- Inits, Inits.back()->getEndLoc());
+ auto *NewInit =
+ new (Ctx) InitListExpr(Ctx, Inits.front()->getBeginLoc(), Inits,
+ Inits.back()->getEndLoc(), /*isExplicit=*/false);
llvm::APInt ArySize(64, Inits.size());
NewInit->setType(Ctx.getConstantArrayType(InitTy, ArySize, nullptr,
ArraySizeModifier::Normal, 0));
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index e54a25405c816..2521684212b91 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -449,7 +449,7 @@ class InitListChecker {
Expr *expr);
InitListExpr *createInitListExpr(QualType CurrentObjectType,
SourceRange InitRange,
- unsigned ExpectedNumInits);
+ unsigned ExpectedNumInits, bool IsExplicit);
int numArrayElements(QualType DeclType);
int numStructUnionElements(QualType DeclType);
@@ -619,7 +619,8 @@ ExprResult InitListChecker::PerformEmptyInit(SourceLocation Loc,
true);
MultiExprArg SubInit;
Expr *InitExpr;
- InitListExpr DummyInitList(SemaRef.Context, Loc, {}, Loc);
+ InitListExpr DummyInitList(SemaRef.Context, Loc, {}, Loc,
+ /*isExplicit=*/false);
// C++ [dcl.init.aggr]p7:
// If there are fewer initializer-clauses in the list than there are
@@ -640,7 +641,8 @@ ExprResult InitListChecker::PerformEmptyInit(SourceLocation Loc,
// the initializer list where possible.
InitExpr = VerifyOnly ? &DummyInitList
: new (SemaRef.Context)
- InitListExpr(SemaRef.Context, Loc, {}, Loc);
+ InitListExpr(SemaRef.Context, Loc, {}, Loc,
+ /*isExplicit=*/false);
InitExpr->setType(SemaRef.Context.VoidTy);
SubInit = InitExpr;
Kind = InitializationKind::CreateCopy(Loc, Loc);
@@ -1098,8 +1100,8 @@ InitListChecker::InitListChecker(
InOverloadResolution(InOverloadResolution),
AggrDeductionCandidateParamTypes(AggrDeductionCandidateParamTypes) {
if (!VerifyOnly || hasAnyDesignatedInits(IL)) {
- FullyStructuredList =
- createInitListExpr(T, IL->getSourceRange(), IL->getNumInits());
+ FullyStructuredList = createInitListExpr(
+ T, IL->getSourceRange(), IL->getNumInits(), IL->isExplicit());
// FIXME: Check that IL isn't already the semantic form of some other
// InitListExpr. If it is, we'd create a broken AST.
@@ -3550,8 +3552,8 @@ InitListChecker::getStructuredSubobjectInit(InitListExpr *IList, unsigned Index,
ExpectedNumInits = IList->getNumInits() - Index;
}
- InitListExpr *Result =
- createInitListExpr(CurrentO...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/195175
More information about the cfe-commits
mailing list