diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2013-10-07 19:57:58 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2013-10-07 19:57:58 +0000 |
commit | b8b41d3ea4445c9d3d4e0cd7c9b6a11c6ce1640a (patch) | |
tree | e748182e1c2360a8249f84b772b7b27680d50c01 /clang/lib/Sema/SemaDeclCXX.cpp | |
parent | d29406233b051f3dcc9dc5316d204401016bef6b (diff) | |
download | bcm5719-llvm-b8b41d3ea4445c9d3d4e0cd7c9b6a11c6ce1640a.tar.gz bcm5719-llvm-b8b41d3ea4445c9d3d4e0cd7c9b6a11c6ce1640a.zip |
Add support for WG21 N3599 (literal operator template for strings) as a GNU
extension. The GCC folks have decided to support this even though the standard
committee have not yet approved this feature.
Patch by Hristo Venev!
llvm-svn: 192128
Diffstat (limited to 'clang/lib/Sema/SemaDeclCXX.cpp')
-rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 28 |
1 files changed, 25 insertions, 3 deletions
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 518f3156a9f..6d357e7be05 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -10917,11 +10917,12 @@ bool Sema::CheckLiteralOperatorDeclaration(FunctionDecl *FnDecl) { if (!TpDecl) TpDecl = FnDecl->getPrimaryTemplate(); - // template <char...> type operator "" name() is the only valid template - // signature, and the only valid signature with no parameters. + // template <char...> type operator "" name() and + // template <class T, T...> type operator "" name() are the only valid + // template signatures, and the only valid signatures with no parameters. if (TpDecl) { if (FnDecl->param_size() == 0) { - // Must have only one template parameter + // Must have one or two template parameters TemplateParameterList *Params = TpDecl->getTemplateParameters(); if (Params->size() == 1) { NonTypeTemplateParmDecl *PmDecl = @@ -10931,6 +10932,27 @@ bool Sema::CheckLiteralOperatorDeclaration(FunctionDecl *FnDecl) { if (PmDecl && PmDecl->isTemplateParameterPack() && Context.hasSameType(PmDecl->getType(), Context.CharTy)) Valid = true; + } else if (Params->size() == 2) { + TemplateTypeParmDecl *PmType = + dyn_cast<TemplateTypeParmDecl>(Params->getParam(0)); + NonTypeTemplateParmDecl *PmArgs = + dyn_cast<NonTypeTemplateParmDecl>(Params->getParam(1)); + + // The second template parameter must be a parameter pack with the + // first template parameter as its type. + if (PmType && PmArgs && + !PmType->isTemplateParameterPack() && + PmArgs->isTemplateParameterPack()) { + const TemplateTypeParmType *TArgs = + PmArgs->getType()->getAs<TemplateTypeParmType>(); + if (TArgs && TArgs->getDepth() == PmType->getDepth() && + TArgs->getIndex() == PmType->getIndex()) { + Valid = true; + if (ActiveTemplateInstantiations.empty()) + Diag(FnDecl->getLocation(), + diag::ext_string_literal_operator_template); + } + } } } } else if (FnDecl->param_size()) { |