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 | 27b4c16fefde48966b65f878799e9a7792275675 (patch) | |
tree | 720bde9e2688238bfbd9fee94671d1d4b4af93f4 /clang/lib/Sema/SemaTemplateVariadic.cpp | |
parent | 1d56c9eed77fe703f389bfa82f79b155a30168d4 (diff) | |
download | bcm5719-llvm-27b4c16fefde48966b65f878799e9a7792275675.tar.gz bcm5719-llvm-27b4c16fefde48966b65f878799e9a7792275675.zip |
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.
llvm-svn: 122520
Diffstat (limited to 'clang/lib/Sema/SemaTemplateVariadic.cpp')
-rw-r--r-- | clang/lib/Sema/SemaTemplateVariadic.cpp | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaTemplateVariadic.cpp b/clang/lib/Sema/SemaTemplateVariadic.cpp index bb9c01afad2..d9c7e72a867 100644 --- a/clang/lib/Sema/SemaTemplateVariadic.cpp +++ b/clang/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; +} |