diff options
author | Douglas Gregor <dgregor@apple.com> | 2010-12-23 22:44:42 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2010-12-23 22:44:42 +0000 |
commit | a8bc8c9e9ba5bffebde00340786fe8542469c435 (patch) | |
tree | 75be85d4dd770d5f44b6c43b54d38747e8de8e8b /lib/Sema/SemaTemplateVariadic.cpp | |
parent | c32647d111e516593b9ba242cad7b8ff4016c155 (diff) |
Implement parsing of function parameter packs and non-type template
parameter packs (C++0x [dcl.fct]p13), including disambiguation between
unnamed function parameter packs and varargs (C++0x [dcl.fct]p14) for
cases like
void f(T...)
where T may or may not contain unexpanded parameter packs.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@122520 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaTemplateVariadic.cpp')
-rw-r--r-- | lib/Sema/SemaTemplateVariadic.cpp | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/lib/Sema/SemaTemplateVariadic.cpp b/lib/Sema/SemaTemplateVariadic.cpp index bb9c01afad..d9c7e72a86 100644 --- a/lib/Sema/SemaTemplateVariadic.cpp +++ b/lib/Sema/SemaTemplateVariadic.cpp @@ -413,3 +413,72 @@ bool Sema::CheckParameterPacksForExpansion(SourceLocation EllipsisLoc, return false; } + +bool Sema::containsUnexpandedParameterPacks(Declarator &D) { + const DeclSpec &DS = D.getDeclSpec(); + switch (DS.getTypeSpecType()) { + case TST_typename: + case TST_typeofType: { + QualType T = DS.getRepAsType().get(); + if (!T.isNull() && T->containsUnexpandedParameterPack()) + return true; + break; + } + + case TST_typeofExpr: + case TST_decltype: + if (DS.getRepAsExpr() && + DS.getRepAsExpr()->containsUnexpandedParameterPack()) + return true; + break; + + case TST_unspecified: + case TST_void: + case TST_char: + case TST_wchar: + case TST_char16: + case TST_char32: + case TST_int: + case TST_float: + case TST_double: + case TST_bool: + case TST_decimal32: + case TST_decimal64: + case TST_decimal128: + case TST_enum: + case TST_union: + case TST_struct: + case TST_class: + case TST_auto: + case TST_error: + break; + } + + for (unsigned I = 0, N = D.getNumTypeObjects(); I != N; ++I) { + const DeclaratorChunk &Chunk = D.getTypeObject(I); + switch (Chunk.Kind) { + case DeclaratorChunk::Pointer: + case DeclaratorChunk::Reference: + case DeclaratorChunk::Paren: + // These declarator chunks cannot contain any parameter packs. + break; + + case DeclaratorChunk::Array: + case DeclaratorChunk::Function: + case DeclaratorChunk::BlockPointer: + // Syntactically, these kinds of declarator chunks all come after the + // declarator-id (conceptually), so the parser should not invoke this + // routine at this time. + llvm_unreachable("Could not have seen this kind of declarator chunk"); + break; + + case DeclaratorChunk::MemberPointer: + if (Chunk.Mem.Scope().getScopeRep() && + Chunk.Mem.Scope().getScopeRep()->containsUnexpandedParameterPack()) + return true; + break; + } + } + + return false; +} |