[cfe-commits] r121930 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td include/clang/Sema/Sema.h lib/Sema/SemaDecl.cpp lib/Sema/SemaDeclCXX.cpp lib/Sema/SemaTemplateVariadic.cpp test/CXX/temp/temp.decls/temp.variadic/p5.cpp
Douglas Gregor
dgregor at apple.com
Wed Dec 15 16:46:58 PST 2010
Author: dgregor
Date: Wed Dec 15 18:46:58 2010
New Revision: 121930
URL: http://llvm.org/viewvc/llvm-project?rev=121930&view=rev
Log:
Check for unexpanded parameter packs in using declarations. As a
drive-by, make sure to check for unexpanded parameter packs within the
name of a declaration.
Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/lib/Sema/SemaDeclCXX.cpp
cfe/trunk/lib/Sema/SemaTemplateVariadic.cpp
cfe/trunk/test/CXX/temp/temp.decls/temp.variadic/p5.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=121930&r1=121929&r2=121930&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Wed Dec 15 18:46:58 2010
@@ -1823,19 +1823,23 @@
def err_unexpanded_parameter_pack_0 : Error<
"%select{expression|base type|declaration type|data member type|bit-field "
- "size|static assertion|fixed underlying type|enumerator value}0 "
+ "size|static assertion|fixed underlying type|enumerator value|"
+ "using declaration}0 "
"contains an unexpanded parameter pack">;
def err_unexpanded_parameter_pack_1 : Error<
"%select{expression|base type|declaration type|data member type|bit-field "
- "size|static assertion|fixed underlying type|enumerator value}0 "
+ "size|static assertion|fixed underlying type|enumerator value|"
+ "using declaration}0 "
"contains unexpanded parameter pack %1">;
def err_unexpanded_parameter_pack_2 : Error<
"%select{expression|base type|declaration type|data member type|bit-field "
- "size|static assertion|fixed underlying type|enumerator value}0 "
+ "size|static assertion|fixed underlying type|enumerator value|"
+ "using declaration}0 "
"contains unexpanded parameter packs %1 and %2">;
def err_unexpanded_parameter_pack_3_or_more : Error<
"%select{expression|base type|declaration type|data member type|bit-field "
- "size|static assertion|fixed underlying type|enumerator value}0 "
+ "size|static assertion|fixed underlying type|enumerator value|"
+ "using declaration}0 "
"contains unexpanded parameter packs %1, %2, ...">;
def err_unexpected_typedef : Error<
Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=121930&r1=121929&r2=121930&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Wed Dec 15 18:46:58 2010
@@ -3157,7 +3157,10 @@
UPPC_FixedUnderlyingType,
/// \brief The enumerator value.
- UPPC_EnumeratorValue
+ UPPC_EnumeratorValue,
+
+ /// \brief A using declaration.
+ UPPC_UsingDeclaration
};
/// \brief If the given type contains an unexpanded parameter pack,
@@ -3182,6 +3185,26 @@
bool DiagnoseUnexpandedParameterPack(Expr *E,
UnexpandedParameterPackContext UPPC = UPPC_Expression);
+ /// \brief If the given nested-name-specifier contains an unexpanded
+ /// parameter pack, diagnose the error.
+ ///
+ /// \param SS The nested-name-specifier that is being checked for
+ /// unexpanded parameter packs.
+ ///
+ /// \returns true if an error ocurred, false otherwise.
+ bool DiagnoseUnexpandedParameterPack(const CXXScopeSpec &SS,
+ UnexpandedParameterPackContext UPPC);
+
+ /// \brief If the given name contains an unexpanded parameter pack,
+ /// diagnose the error.
+ ///
+ /// \param NameInfo The name (with source location information) that
+ /// is being checked for unexpanded parameter packs.
+ ///
+ /// \returns true if an error ocurred, false otherwise.
+ bool DiagnoseUnexpandedParameterPack(const DeclarationNameInfo &NameInfo,
+ UnexpandedParameterPackContext UPPC);
+
/// \brief Describes the result of template argument deduction.
///
/// The TemplateDeductionResult enumeration describes the result of
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=121930&r1=121929&r2=121930&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Wed Dec 15 18:46:58 2010
@@ -2319,7 +2319,8 @@
diag::err_declarator_need_ident)
<< D.getDeclSpec().getSourceRange() << D.getSourceRange();
return 0;
- }
+ } else if (DiagnoseUnexpandedParameterPack(NameInfo, UPPC_DeclarationType))
+ return 0;
// The scope passed in may not be a decl scope. Zip up the scope tree until
// we find one that is.
Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=121930&r1=121929&r2=121930&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Wed Dec 15 18:46:58 2010
@@ -928,6 +928,7 @@
}
// FIXME: Check for template parameters!
+ // FIXME: Check that the name is an identifier!
Member = HandleField(S, cast<CXXRecordDecl>(CurContext), Loc, D, BitWidth,
AS);
assert(Member && "HandleField never returns null");
@@ -3547,6 +3548,10 @@
<< FixItHint::CreateInsertion(SS.getRange().getBegin(), "using ");
}
+ if (DiagnoseUnexpandedParameterPack(SS, UPPC_UsingDeclaration) ||
+ DiagnoseUnexpandedParameterPack(TargetNameInfo, UPPC_UsingDeclaration))
+ return 0;
+
NamedDecl *UD = BuildUsingDeclaration(S, AS, UsingLoc, SS,
TargetNameInfo, AttrList,
/* IsInstantiation */ false,
Modified: cfe/trunk/lib/Sema/SemaTemplateVariadic.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateVariadic.cpp?rev=121930&r1=121929&r2=121930&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateVariadic.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateVariadic.cpp Wed Dec 15 18:46:58 2010
@@ -171,7 +171,7 @@
}
bool Sema::DiagnoseUnexpandedParameterPack(Expr *E,
- UnexpandedParameterPackContext UPPC) {
+ UnexpandedParameterPackContext UPPC) {
// C++0x [temp.variadic]p5:
// An appearance of a name of a parameter pack that is not expanded is
// ill-formed.
@@ -184,3 +184,53 @@
DiagnoseUnexpandedParameterPacks(*this, E->getLocStart(), UPPC, Unexpanded);
return true;
}
+
+bool Sema::DiagnoseUnexpandedParameterPack(const CXXScopeSpec &SS,
+ UnexpandedParameterPackContext UPPC) {
+ // C++0x [temp.variadic]p5:
+ // An appearance of a name of a parameter pack that is not expanded is
+ // ill-formed.
+ if (!SS.getScopeRep() ||
+ !SS.getScopeRep()->containsUnexpandedParameterPack())
+ return false;
+
+ llvm::SmallVector<UnexpandedParameterPack, 2> Unexpanded;
+ CollectUnexpandedParameterPacksVisitor(Unexpanded)
+ .TraverseNestedNameSpecifier(SS.getScopeRep());
+ assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
+ DiagnoseUnexpandedParameterPacks(*this, SS.getRange().getBegin(),
+ UPPC, Unexpanded);
+ return true;
+}
+
+bool Sema::DiagnoseUnexpandedParameterPack(const DeclarationNameInfo &NameInfo,
+ UnexpandedParameterPackContext UPPC) {
+ // C++0x [temp.variadic]p5:
+ // An appearance of a name of a parameter pack that is not expanded is
+ // ill-formed.
+ switch (NameInfo.getName().getNameKind()) {
+ case DeclarationName::Identifier:
+ case DeclarationName::ObjCZeroArgSelector:
+ case DeclarationName::ObjCOneArgSelector:
+ case DeclarationName::ObjCMultiArgSelector:
+ case DeclarationName::CXXOperatorName:
+ case DeclarationName::CXXLiteralOperatorName:
+ case DeclarationName::CXXUsingDirective:
+ return false;
+
+ case DeclarationName::CXXConstructorName:
+ case DeclarationName::CXXDestructorName:
+ case DeclarationName::CXXConversionFunctionName:
+ if (!NameInfo.getNamedTypeInfo()->getType()
+ ->containsUnexpandedParameterPack())
+ return false;
+ break;
+ }
+
+ llvm::SmallVector<UnexpandedParameterPack, 2> Unexpanded;
+ CollectUnexpandedParameterPacksVisitor(Unexpanded)
+ .TraverseTypeLoc(NameInfo.getNamedTypeInfo()->getTypeLoc());
+ assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
+ DiagnoseUnexpandedParameterPacks(*this, NameInfo.getLoc(), UPPC, Unexpanded);
+ return true;
+}
Modified: cfe/trunk/test/CXX/temp/temp.decls/temp.variadic/p5.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.decls/temp.variadic/p5.cpp?rev=121930&r1=121929&r2=121930&view=diff
==============================================================================
--- cfe/trunk/test/CXX/temp/temp.decls/temp.variadic/p5.cpp (original)
+++ cfe/trunk/test/CXX/temp/temp.decls/temp.variadic/p5.cpp Wed Dec 15 18:46:58 2010
@@ -104,10 +104,11 @@
}
// FIXME: Test for unexpanded parameter packs in declarations.
-template<typename... Types>
-struct TestUnexpandedDecls {
+template<typename T, typename... Types>
+struct TestUnexpandedDecls : T{
void member_function(Types); // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
void member_function () throw(Types); // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
+ operator Types() const; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
Types data_member; // expected-error{{data member type contains unexpanded parameter pack 'Types'}}
static Types static_data_member; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
unsigned bit_field : static_cast<Types>(0); // expected-error{{bit-field size contains unexpanded parameter pack 'Types'}}
@@ -116,6 +117,10 @@
enum E0 : Types { // expected-error{{fixed underlying type contains unexpanded parameter pack 'Types'}}
EnumValue = static_cast<Types>(0) // expected-error{{enumerator value contains unexpanded parameter pack 'Types'}}
};
+
+ using typename Types::type; // expected-error{{using declaration contains unexpanded parameter pack 'Types'}}
+ using Types::value; // expected-error{{using declaration contains unexpanded parameter pack 'Types'}}
+ using T::operator Types; // expected-error{{using declaration contains unexpanded parameter pack 'Types'}}
};
// Test for diagnostics in the presence of multiple unexpanded
More information about the cfe-commits
mailing list