From 1a9b9adf6ff83d48a797f20cc607be9c5eb154c6 Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Fri, 22 Jul 2016 23:36:59 +0000 Subject: P0217R3: Parsing support and framework for AST representation of C++1z decomposition declarations. There are a couple of things in the wording that seem strange here: decomposition declarations are permitted at namespace scope (which we partially support here) and they are permitted as the declaration in a template (which we reject). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@276492 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/DeclSpec.cpp | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) (limited to 'lib/Sema/DeclSpec.cpp') diff --git a/lib/Sema/DeclSpec.cpp b/lib/Sema/DeclSpec.cpp index b9d2843b05..c294658c03 100644 --- a/lib/Sema/DeclSpec.cpp +++ b/lib/Sema/DeclSpec.cpp @@ -220,11 +220,11 @@ DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto, // parameter list there (in an effort to avoid new/delete traffic). If it // is already used (consider a function returning a function pointer) or too // small (function with too many parameters), go to the heap. - if (!TheDeclarator.InlineParamsUsed && + if (!TheDeclarator.InlineStorageUsed && NumParams <= llvm::array_lengthof(TheDeclarator.InlineParams)) { I.Fun.Params = TheDeclarator.InlineParams; I.Fun.DeleteParams = false; - TheDeclarator.InlineParamsUsed = true; + TheDeclarator.InlineStorageUsed = true; } else { I.Fun.Params = new DeclaratorChunk::ParamInfo[NumParams]; I.Fun.DeleteParams = true; @@ -258,6 +258,38 @@ DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto, return I; } +void Declarator::setDecompositionBindings( + SourceLocation LSquareLoc, + ArrayRef Bindings, + SourceLocation RSquareLoc) { + assert(!hasName() && "declarator given multiple names!"); + + BindingGroup.LSquareLoc = LSquareLoc; + BindingGroup.RSquareLoc = RSquareLoc; + BindingGroup.NumBindings = Bindings.size(); + Range.setEnd(RSquareLoc); + + // We're now past the identifier. + SetIdentifier(nullptr, LSquareLoc); + Name.EndLocation = RSquareLoc; + + // Allocate storage for bindings and stash them away. + if (Bindings.size()) { + if (!InlineStorageUsed && + Bindings.size() <= llvm::array_lengthof(InlineBindings)) { + BindingGroup.Bindings = InlineBindings; + BindingGroup.DeleteBindings = false; + InlineStorageUsed = true; + } else { + BindingGroup.Bindings = + new DecompositionDeclarator::Binding[Bindings.size()]; + BindingGroup.DeleteBindings = true; + } + std::uninitialized_copy(Bindings.begin(), Bindings.end(), + BindingGroup.Bindings); + } +} + bool Declarator::isDeclarationOfFunction() const { for (unsigned i = 0, i_end = DeclTypeInfo.size(); i < i_end; ++i) { switch (DeclTypeInfo[i].Kind) { -- cgit v1.2.1