forked from OSchip/llvm-project
P0217R3: serialization/deserialization support for c++17 decomposition declarations.
llvm-svn: 278460
This commit is contained in:
parent
e43e263957
commit
7b76d81bdf
|
@ -3414,6 +3414,8 @@ public:
|
|||
|
||||
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
|
||||
static bool classofKind(Kind K) { return K == Decl::Binding; }
|
||||
|
||||
friend class ASTDeclReader;
|
||||
};
|
||||
|
||||
/// A decomposition declaration. For instance, given:
|
||||
|
@ -3463,6 +3465,7 @@ public:
|
|||
static bool classofKind(Kind K) { return K == Decomposition; }
|
||||
|
||||
friend TrailingObjects;
|
||||
friend class ASTDeclReader;
|
||||
};
|
||||
|
||||
/// An instance of this class represents the declaration of a property
|
||||
|
|
|
@ -1056,6 +1056,10 @@ namespace clang {
|
|||
DECL_IMPLICIT_PARAM,
|
||||
/// \brief A ParmVarDecl record.
|
||||
DECL_PARM_VAR,
|
||||
/// \brief A DecompositionDecl record.
|
||||
DECL_DECOMPOSITION,
|
||||
/// \brief A BindingDecl record.
|
||||
DECL_BINDING,
|
||||
/// \brief A FileScopeAsmDecl record.
|
||||
DECL_FILE_SCOPE_ASM,
|
||||
/// \brief A BlockDecl record.
|
||||
|
|
|
@ -2334,8 +2334,9 @@ DecompositionDecl *DecompositionDecl::CreateDeserialized(ASTContext &C,
|
|||
unsigned ID,
|
||||
unsigned NumBindings) {
|
||||
size_t Extra = additionalSizeToAlloc<BindingDecl *>(NumBindings);
|
||||
auto *Result = new (C, ID, Extra) DecompositionDecl(
|
||||
C, nullptr, SourceLocation(), SourceLocation(), QualType(), nullptr, StorageClass(), None);
|
||||
auto *Result = new (C, ID, Extra)
|
||||
DecompositionDecl(C, nullptr, SourceLocation(), SourceLocation(),
|
||||
QualType(), nullptr, StorageClass(), None);
|
||||
// Set up and clean out the bindings array.
|
||||
Result->NumBindings = NumBindings;
|
||||
auto *Trail = Result->getTrailingObjects<BindingDecl *>();
|
||||
|
|
|
@ -312,6 +312,8 @@ namespace clang {
|
|||
void VisitVarDecl(VarDecl *VD) { VisitVarDeclImpl(VD); }
|
||||
void VisitImplicitParamDecl(ImplicitParamDecl *PD);
|
||||
void VisitParmVarDecl(ParmVarDecl *PD);
|
||||
void VisitDecompositionDecl(DecompositionDecl *DD);
|
||||
void VisitBindingDecl(BindingDecl *BD);
|
||||
void VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D);
|
||||
DeclID VisitTemplateDecl(TemplateDecl *D);
|
||||
RedeclarableResult VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D);
|
||||
|
@ -1295,6 +1297,18 @@ void ASTDeclReader::VisitParmVarDecl(ParmVarDecl *PD) {
|
|||
// inheritance of default arguments.
|
||||
}
|
||||
|
||||
void ASTDeclReader::VisitDecompositionDecl(DecompositionDecl *DD) {
|
||||
VisitVarDecl(DD);
|
||||
BindingDecl **BDs = DD->getTrailingObjects<BindingDecl*>();
|
||||
for (unsigned I = 0; I != DD->NumBindings; ++I)
|
||||
BDs[I] = ReadDeclAs<BindingDecl>(Record, Idx);
|
||||
}
|
||||
|
||||
void ASTDeclReader::VisitBindingDecl(BindingDecl *BD) {
|
||||
VisitValueDecl(BD);
|
||||
BD->Binding = Reader.ReadExpr(F);
|
||||
}
|
||||
|
||||
void ASTDeclReader::VisitFileScopeAsmDecl(FileScopeAsmDecl *AD) {
|
||||
VisitDecl(AD);
|
||||
AD->setAsmString(cast<StringLiteral>(Reader.ReadExpr(F)));
|
||||
|
@ -3400,6 +3414,12 @@ Decl *ASTReader::ReadDeclRecord(DeclID ID) {
|
|||
case DECL_PARM_VAR:
|
||||
D = ParmVarDecl::CreateDeserialized(Context, ID);
|
||||
break;
|
||||
case DECL_DECOMPOSITION:
|
||||
D = DecompositionDecl::CreateDeserialized(Context, ID, Record[Idx++]);
|
||||
break;
|
||||
case DECL_BINDING:
|
||||
D = BindingDecl::CreateDeserialized(Context, ID);
|
||||
break;
|
||||
case DECL_FILE_SCOPE_ASM:
|
||||
D = FileScopeAsmDecl::CreateDeserialized(Context, ID);
|
||||
break;
|
||||
|
|
|
@ -96,6 +96,8 @@ namespace clang {
|
|||
void VisitVarDecl(VarDecl *D);
|
||||
void VisitImplicitParamDecl(ImplicitParamDecl *D);
|
||||
void VisitParmVarDecl(ParmVarDecl *D);
|
||||
void VisitDecompositionDecl(DecompositionDecl *D);
|
||||
void VisitBindingDecl(BindingDecl *D);
|
||||
void VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D);
|
||||
void VisitTemplateDecl(TemplateDecl *D);
|
||||
void VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D);
|
||||
|
@ -941,8 +943,7 @@ void ASTDeclWriter::VisitVarDecl(VarDecl *D) {
|
|||
D->getFirstDecl() == D->getMostRecentDecl() &&
|
||||
D->getInitStyle() == VarDecl::CInit &&
|
||||
D->getInit() == nullptr &&
|
||||
!isa<ParmVarDecl>(D) &&
|
||||
!isa<VarTemplateSpecializationDecl>(D) &&
|
||||
D->getKind() == Decl::Var &&
|
||||
!D->isInline() &&
|
||||
!D->isConstexpr() &&
|
||||
!D->isInitCapture() &&
|
||||
|
@ -1005,6 +1006,22 @@ void ASTDeclWriter::VisitParmVarDecl(ParmVarDecl *D) {
|
|||
"PARM_VAR_DECL can't be static data member");
|
||||
}
|
||||
|
||||
void ASTDeclWriter::VisitDecompositionDecl(DecompositionDecl *D) {
|
||||
// Record the number of bindings first to simplify deserialization.
|
||||
Record.push_back(D->bindings().size());
|
||||
|
||||
VisitVarDecl(D);
|
||||
for (auto *B : D->bindings())
|
||||
Record.AddDeclRef(B);
|
||||
Code = serialization::DECL_DECOMPOSITION;
|
||||
}
|
||||
|
||||
void ASTDeclWriter::VisitBindingDecl(BindingDecl *D) {
|
||||
VisitValueDecl(D);
|
||||
Record.AddStmt(D->getBinding());
|
||||
Code = serialization::DECL_BINDING;
|
||||
}
|
||||
|
||||
void ASTDeclWriter::VisitFileScopeAsmDecl(FileScopeAsmDecl *D) {
|
||||
VisitDecl(D);
|
||||
Record.AddStmt(D->getAsmString());
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
// No PCH:
|
||||
// RUN: %clang_cc1 -pedantic -std=c++1z -include %s -verify %s
|
||||
//
|
||||
// With PCH:
|
||||
// RUN: %clang_cc1 -pedantic -std=c++1z -emit-pch %s -o %t
|
||||
// RUN: %clang_cc1 -pedantic -std=c++1z -include-pch %t -verify %s
|
||||
|
||||
#ifndef HEADER
|
||||
#define HEADER
|
||||
|
||||
template<typename T> auto decomp(const T &t) {
|
||||
auto &[a, b] = t;
|
||||
return a + b;
|
||||
}
|
||||
|
||||
struct Q { int a, b; };
|
||||
constexpr int foo(Q &&q) {
|
||||
auto &[a, b] = q;
|
||||
return a * 10 + b;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
int arr[2];
|
||||
int k = decomp(arr);
|
||||
|
||||
static_assert(foo({1, 2}) == 12);
|
||||
|
||||
// expected-error@12 {{cannot decompose non-class, non-array type 'const int'}}
|
||||
int z = decomp(10); // expected-note {{instantiation of}}
|
||||
|
||||
#endif
|
|
@ -38,5 +38,4 @@ constexpr bool g(S &&s) {
|
|||
static_assert(g({1, 2}));
|
||||
|
||||
// FIXME: by-value array copies
|
||||
// FIXME: ast file support
|
||||
// FIXME: code generation
|
||||
|
|
Loading…
Reference in New Issue