P0217R3: serialization/deserialization support for c++17 decomposition declarations.

llvm-svn: 278460
This commit is contained in:
Richard Smith 2016-08-12 02:21:25 +00:00
parent e43e263957
commit 7b76d81bdf
7 changed files with 81 additions and 5 deletions

View File

@ -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

View File

@ -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.

View File

@ -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 *>();

View File

@ -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;

View File

@ -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());

View File

@ -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

View File

@ -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