Skip to content

Commit 3c81c5b

Browse files
committed
[Clang][P1061] stuctured binding packs
1 parent 6e8a1a4 commit 3c81c5b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+728
-111
lines changed

clang/include/clang/AST/Decl.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -698,6 +698,10 @@ class ValueDecl : public NamedDecl {
698698
return const_cast<ValueDecl *>(this)->getPotentiallyDecomposedVarDecl();
699699
}
700700

701+
/// Determine whether this value is actually a function parameter pack,
702+
/// init-capture pack, or structured binding pack
703+
bool isParameterPack() const;
704+
701705
// Implement isa/cast/dyncast/etc.
702706
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
703707
static bool classofKind(Kind K) { return K >= firstValue && K <= lastValue; }
@@ -1527,10 +1531,6 @@ class VarDecl : public DeclaratorDecl, public Redeclarable<VarDecl> {
15271531
NonParmVarDeclBits.IsInitCapture = IC;
15281532
}
15291533

1530-
/// Determine whether this variable is actually a function parameter pack or
1531-
/// init-capture pack.
1532-
bool isParameterPack() const;
1533-
15341534
/// Whether this local extern variable declaration's previous declaration
15351535
/// was declared in the same block scope. Only correct in C++.
15361536
bool isPreviousDeclInSameBlockScope() const {

clang/include/clang/AST/DeclCXX.h

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4131,16 +4131,18 @@ class BindingDecl : public ValueDecl {
41314131
/// binding).
41324132
Expr *Binding = nullptr;
41334133

4134-
BindingDecl(DeclContext *DC, SourceLocation IdLoc, IdentifierInfo *Id)
4135-
: ValueDecl(Decl::Binding, DC, IdLoc, Id, QualType()) {}
4134+
BindingDecl(DeclContext *DC, SourceLocation IdLoc, IdentifierInfo *Id,
4135+
QualType T)
4136+
: ValueDecl(Decl::Binding, DC, IdLoc, Id, T) {}
41364137

41374138
void anchor() override;
41384139

41394140
public:
41404141
friend class ASTDeclReader;
41414142

41424143
static BindingDecl *Create(ASTContext &C, DeclContext *DC,
4143-
SourceLocation IdLoc, IdentifierInfo *Id);
4144+
SourceLocation IdLoc, IdentifierInfo *Id,
4145+
QualType T);
41444146
static BindingDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);
41454147

41464148
/// Get the expression to which this declaration is bound. This may be null
@@ -4152,10 +4154,6 @@ class BindingDecl : public ValueDecl {
41524154
/// decomposition of.
41534155
ValueDecl *getDecomposedDecl() const { return Decomp; }
41544156

4155-
/// Get the variable (if any) that holds the value of evaluating the binding.
4156-
/// Only present for user-defined bindings for tuple-like types.
4157-
VarDecl *getHoldingVar() const;
4158-
41594157
/// Set the binding for this BindingDecl, along with its declared type (which
41604158
/// should be a possibly-cv-qualified form of the type of the binding, or a
41614159
/// reference to such a type).
@@ -4167,6 +4165,9 @@ class BindingDecl : public ValueDecl {
41674165
/// Set the decomposed variable for this BindingDecl.
41684166
void setDecomposedDecl(ValueDecl *Decomposed) { Decomp = Decomposed; }
41694167

4168+
VarDecl *getHoldingVar() const;
4169+
static VarDecl *getHoldingVar(Expr *E);
4170+
41704171
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
41714172
static bool classofKind(Kind K) { return K == Decl::Binding; }
41724173
};
@@ -4219,6 +4220,13 @@ class DecompositionDecl final
42194220

42204221
void printName(raw_ostream &OS, const PrintingPolicy &Policy) const override;
42214222

4223+
/// Visit the variables (if any) that hold the values of evaluating the
4224+
/// binding. Only present for user-defined bindings for tuple-like types.
4225+
void VisitHoldingVars(llvm::function_ref<void(VarDecl *)> F) const;
4226+
4227+
// Visit the concrete bindings. (workaround)
4228+
void VisitBindings(llvm::function_ref<void(BindingDecl *)> F) const;
4229+
42224230
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
42234231
static bool classofKind(Kind K) { return K == Decomposition; }
42244232
};

clang/include/clang/AST/ExprCXX.h

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5321,6 +5321,54 @@ class BuiltinBitCastExpr final
53215321
}
53225322
};
53235323

5324+
class ResolvedUnexpandedPackExpr final
5325+
: public Expr,
5326+
private llvm::TrailingObjects<ResolvedUnexpandedPackExpr, Stmt *> {
5327+
friend TrailingObjects;
5328+
5329+
SourceLocation BeginLoc;
5330+
unsigned NumExprs;
5331+
5332+
ResolvedUnexpandedPackExpr(SourceLocation BL, QualType QT, unsigned NumExprs);
5333+
5334+
public:
5335+
static ResolvedUnexpandedPackExpr *CreateDeserialized(ASTContext &C,
5336+
unsigned NumExprs);
5337+
static ResolvedUnexpandedPackExpr *
5338+
Create(ASTContext &C, SourceLocation BeginLoc, QualType T, unsigned NumExprs);
5339+
static ResolvedUnexpandedPackExpr *Create(ASTContext &C,
5340+
SourceLocation BeginLoc, QualType T,
5341+
llvm::ArrayRef<Expr *> Exprs);
5342+
5343+
unsigned getNumExprs() const { return NumExprs; }
5344+
5345+
Expr **getExprs() {
5346+
return reinterpret_cast<Expr **>(getTrailingObjects<Stmt *>());
5347+
}
5348+
Expr *const *getExprs() const {
5349+
return reinterpret_cast<Expr *const *>(getTrailingObjects<Stmt *>());
5350+
}
5351+
5352+
Expr *getExpansion(unsigned Idx) { return getExprs()[Idx]; }
5353+
Expr *getExpansion(unsigned Idx) const { return getExprs()[Idx]; }
5354+
5355+
// Iterators
5356+
child_range children() {
5357+
return child_range(getTrailingObjects<Stmt *>(),
5358+
getTrailingObjects<Stmt *>() + getNumExprs());
5359+
}
5360+
5361+
SourceLocation getBeginLoc() const LLVM_READONLY { return BeginLoc; }
5362+
SourceLocation getEndLoc() const LLVM_READONLY { return BeginLoc; }
5363+
5364+
// Returns the resolved pack of a decl or nullptr
5365+
static ResolvedUnexpandedPackExpr *getFromDecl(Decl *);
5366+
5367+
static bool classof(const Stmt *T) {
5368+
return T->getStmtClass() == ResolvedUnexpandedPackExprClass;
5369+
}
5370+
};
5371+
53245372
} // namespace clang
53255373

53265374
#endif // LLVM_CLANG_AST_EXPRCXX_H

clang/include/clang/AST/RecursiveASTVisitor.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2936,6 +2936,7 @@ DEF_TRAVERSE_STMT(FunctionParmPackExpr, {})
29362936
DEF_TRAVERSE_STMT(CXXFoldExpr, {})
29372937
DEF_TRAVERSE_STMT(AtomicExpr, {})
29382938
DEF_TRAVERSE_STMT(CXXParenListInitExpr, {})
2939+
DEF_TRAVERSE_STMT(ResolvedUnexpandedPackExpr, {})
29392940

29402941
DEF_TRAVERSE_STMT(MaterializeTemporaryExpr, {
29412942
if (S->getLifetimeExtendedTemporaryDecl()) {

clang/include/clang/Basic/DiagnosticParseKinds.td

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1099,6 +1099,11 @@ def err_lambda_capture_misplaced_ellipsis : Error<
10991099
"the name of the capture">;
11001100
def err_lambda_capture_multiple_ellipses : Error<
11011101
"multiple ellipses in pack capture">;
1102+
def err_binding_multiple_ellipses : Error<
1103+
"multiple ellipses in structured binding declaration">;
1104+
def warn_cxx2c_binding_pack : Warning<
1105+
"structured binding pack is incompatible with C++ standards before C++2c">,
1106+
DefaultIgnore, InGroup<CXXPre26Compat>;
11021107
def err_capture_default_first : Error<
11031108
"capture default must be first">;
11041109
def ext_decl_attrs_on_lambda : ExtWarn<

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5906,6 +5906,9 @@ def warn_cxx23_pack_indexing : Warning<
59065906
"pack indexing is incompatible with C++ standards before C++2c">,
59075907
DefaultIgnore, InGroup<CXXPre26Compat>;
59085908

5909+
def err_pack_outside_template : Error<
5910+
"pack declaration outside of template">;
5911+
59095912
def err_fold_expression_packs_both_sides : Error<
59105913
"binary fold expression has unexpanded parameter packs in both operands">;
59115914
def err_fold_expression_empty : Error<

clang/include/clang/Basic/StmtNodes.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ def MaterializeTemporaryExpr : StmtNode<Expr>;
162162
def LambdaExpr : StmtNode<Expr>;
163163
def CXXFoldExpr : StmtNode<Expr>;
164164
def CXXParenListInitExpr: StmtNode<Expr>;
165+
def ResolvedUnexpandedPackExpr : StmtNode<Expr>;
165166

166167
// C++ Coroutines expressions
167168
def CoroutineSuspendExpr : StmtNode<Expr, 1>;

clang/include/clang/Sema/DeclSpec.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1795,6 +1795,7 @@ class DecompositionDeclarator {
17951795
IdentifierInfo *Name;
17961796
SourceLocation NameLoc;
17971797
std::optional<ParsedAttributes> Attrs;
1798+
SourceLocation EllipsisLoc;
17981799
};
17991800

18001801
private:

clang/include/clang/Sema/Sema.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,8 @@ void threadSafetyCleanup(BeforeSet *Cache);
230230

231231
// FIXME: No way to easily map from TemplateTypeParmTypes to
232232
// TemplateTypeParmDecls, so we have this horrible PointerUnion.
233-
typedef std::pair<llvm::PointerUnion<const TemplateTypeParmType *, NamedDecl *>,
233+
typedef std::pair<llvm::PointerUnion<const TemplateTypeParmType *, NamedDecl *,
234+
ResolvedUnexpandedPackExpr *>,
234235
SourceLocation>
235236
UnexpandedParameterPack;
236237

@@ -6012,6 +6013,7 @@ class Sema final : public SemaBase {
60126013
RecordDecl *ClassDecl,
60136014
const IdentifierInfo *Name);
60146015

6016+
unsigned GetDecompositionElementCount(QualType DecompType);
60156017
void CheckCompleteDecompositionDeclaration(DecompositionDecl *DD);
60166018

60176019
/// Stack containing information needed when in C++2a an 'auto' is encountered

clang/include/clang/Serialization/ASTBitCodes.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1890,6 +1890,7 @@ enum StmtCode {
18901890
EXPR_PACK_EXPANSION, // PackExpansionExpr
18911891
EXPR_PACK_INDEXING, // PackIndexingExpr
18921892
EXPR_SIZEOF_PACK, // SizeOfPackExpr
1893+
EXPR_RESOLVED_UNEXPANDED_PACK, // ResolvedUnexpandedPackExpr
18931894
EXPR_SUBST_NON_TYPE_TEMPLATE_PARM, // SubstNonTypeTemplateParmExpr
18941895
EXPR_SUBST_NON_TYPE_TEMPLATE_PARM_PACK, // SubstNonTypeTemplateParmPackExpr
18951896
EXPR_FUNCTION_PARM_PACK, // FunctionParmPackExpr

0 commit comments

Comments
 (0)