r187762 - Started implementing variable templates. Top level declarations should be fully supported, up to some limitations documented as FIXMEs or TODO. Static data member templates work very partially. Static data member templates of class templates need particular attention...

Nick Lewycky nlewycky at google.com
Mon Aug 5 22:39:47 PDT 2013


On 5 August 2013 18:03, Larisse Voufo <lvoufo at google.com> wrote:

> Author: lvoufo
> Date: Mon Aug  5 20:03:05 2013
> New Revision: 187762
>
> URL: http://llvm.org/viewvc/llvm-project?rev=187762&view=rev
> Log:
> Started implementing variable templates. Top level declarations should be
> fully supported, up to some limitations documented as FIXMEs or TODO.
> Static data member templates work very partially. Static data member
> templates of class templates need particular attention...


Nice!!

[...]


> Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
>
URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=187762&r1=187761&r2=187762&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
> +++ cfe/trunk/lib/Parse/ParseDecl.cpp Mon Aug  5 20:03:05 2013
> @@ -1797,24 +1797,69 @@ Decl *Parser::ParseDeclarationAfterDecla
>      break;
>
>    case ParsedTemplateInfo::Template:
> -  case ParsedTemplateInfo::ExplicitSpecialization:
> +  case ParsedTemplateInfo::ExplicitSpecialization: {
>      ThisDecl = Actions.ActOnTemplateDeclarator(getCurScope(),
>
> *TemplateInfo.TemplateParams,
>                                                 D);
> -    break;
>
> -  case ParsedTemplateInfo::ExplicitInstantiation: {
> -    DeclResult ThisRes
> -      = Actions.ActOnExplicitInstantiation(getCurScope(),
> -                                           TemplateInfo.ExternLoc,
> -                                           TemplateInfo.TemplateLoc,
> -                                           D);
> -    if (ThisRes.isInvalid()) {
> +    // If this is a forward declaration of a variable template or variable
> +    // template partial specialization with nested name specifier,
> complain.
> +    // FIXME: Move to Sema.
> +    CXXScopeSpec &SS = D.getCXXScopeSpec();
> +    if (Tok.is(tok::semi) && ThisDecl && SS.isNotEmpty() &&
> +        (isa<VarTemplateDecl>(ThisDecl) ||
> +         isa<VarTemplatePartialSpecializationDecl>(ThisDecl))) {
> +      Diag(SS.getBeginLoc(), diag::err_forward_var_nested_name_specifier)
> +          << isa<VarTemplatePartialSpecializationDecl>(ThisDecl)
> +          << SS.getRange();
>        SkipUntil(tok::semi, true, true);
>        return 0;
>      }
>
> -    ThisDecl = ThisRes.get();
> +    if (VarTemplateDecl *VT =
> +            ThisDecl ? dyn_cast<VarTemplateDecl>(ThisDecl) : 0)
>

You can use dyn_cast_or_null here.


> +static TemplateSpecializationKind getTemplateSpecializationKind(Decl *D);
> +/*
> +/// \brief Check the new variable specialization against the parsed input.
> +///
> +/// FIXME: Model this against function specializations where
> +/// a new function declaration is checked against the specialization
> +/// as candidate for redefinition... (?)
> +static bool CheckVariableTemplateSpecializationType() {
> +
> +  if (ExpectedType is undeduced &&  ParsedType is not undeduced)
> +    ExpectedType = dedudeType();
> +
> +  if (both types are undeduced)
> +    ???;
> +
> +  bool CheckType = !ExpectedType()->
> +
> +  if (!Context.hasSameType(DI->getType(), ExpectedDI->getType())) {
> +    unsigned ErrStr = IsPartialSpecialization ? 2 : 1;
> +    Diag(D.getIdentifierLoc(), diag::err_invalid_var_template_spec_type)
> +        << ErrStr << VarTemplate << DI->getType() <<
> ExpectedDI->getType();
> +    Diag(VarTemplate->getLocation(), diag::note_template_declared_here)
> +        << 2 << VarTemplate->getDeclName();
> +    return true;
> +  }
> +}
> +*/
>

Please don't comment commented out or #if 0'd out code.


> Modified: cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp?rev=187762&r1=187761&r2=187762&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp Mon Aug  5 20:03:05 2013
> @@ -2246,7 +2246,7 @@ FinishTemplateArgumentDeduction(Sema &S,
>  }
>
>  /// \brief Perform template argument deduction to determine whether
> -/// the given template arguments match the given class template
> +/// the given template arguments match the given variable template
>  /// partial specialization per C++ [temp.class.spec.match].
>  Sema::TemplateDeductionResult
>  Sema::DeduceTemplateArguments(ClassTemplatePartialSpecializationDecl
> *Partial,
>

Hm? This is still about classes not variables.


> +/// \brief Perform template argument deduction to determine whether
> +/// the given template arguments match the given variable template
> +/// partial specialization per C++ [temp.class.spec.match].
> +/// TODO: Unify with ClassTemplatePartialSpecializationDecl version.
> +Sema::TemplateDeductionResult
> +Sema::DeduceTemplateArguments(VarTemplatePartialSpecializationDecl
> *Partial,
> +                              const TemplateArgumentList &TemplateArgs,
> +                              TemplateDeductionInfo &Info) {
> +  if (Partial->isInvalidDecl())
> +    return TDK_Invalid;
> +
> +  // C++ [temp.class.spec.match]p2:
> +  //   A partial specialization matches a given actual template
> +  //   argument list if the template arguments of the partial
> +  //   specialization can be deduced from the actual template argument
> +  //   list (14.8.2).
> +
> +  // Unevaluated SFINAE context.
> +  EnterExpressionEvaluationContext Unevaluated(*this, Sema::Unevaluated);
> +  SFINAETrap Trap(*this);
> +
> +  SmallVector<DeducedTemplateArgument, 4> Deduced;
> +  Deduced.resize(Partial->getTemplateParameters()->size());
> +  if (TemplateDeductionResult Result = ::DeduceTemplateArguments(
> +          *this, Partial->getTemplateParameters(),
> Partial->getTemplateArgs(),
> +          TemplateArgs, Info, Deduced))
> +    return Result;
>

What's up with the leading :: on the function call?

+
> +  SmallVector<TemplateArgument, 4> DeducedArgs(Deduced.begin(),
> Deduced.end());
> +  InstantiatingTemplate Inst(*this, Partial->getLocation(), Partial,
> +                             DeducedArgs, Info);
> +  if (Inst)
> +    return TDK_InstantiationDepth;
> +
> +  if (Trap.hasErrorOccurred())
> +    return Sema::TDK_SubstitutionFailure;
> +
> +  return ::FinishTemplateArgumentDeduction(*this, Partial, TemplateArgs,
> +                                           Deduced, Info);
>

And again here?

Nick
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130805/965cb4f5/attachment.html>


More information about the cfe-commits mailing list