diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2017-04-16 16:31:20 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2017-04-16 16:31:20 +0000 | 
| commit | 20e90f04ad65d84361f769ef539883f75e3ef80d (patch) | |
| tree | 6f84b34d122575877ff298feeb61ee7bd0b66f78 /contrib/llvm/tools/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | |
| parent | 7a7e6055035bfd93ab507051819373a6f171258b (diff) | |
| parent | 7442d6faa2719e4e7d33a7021c406c5a4facd74d (diff) | |
Notes
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp')
| -rw-r--r-- | contrib/llvm/tools/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 208 | 
1 files changed, 140 insertions, 68 deletions
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 200775756d3a..9a71a17561c7 100644 --- a/contrib/llvm/tools/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/contrib/llvm/tools/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -81,7 +81,8 @@ static void instantiateDependentAlignedAttr(      const AlignedAttr *Aligned, Decl *New, bool IsPackExpansion) {    if (Aligned->isAlignmentExpr()) {      // The alignment expression is a constant expression. -    EnterExpressionEvaluationContext Unevaluated(S, Sema::ConstantEvaluated); +    EnterExpressionEvaluationContext Unevaluated( +        S, Sema::ExpressionEvaluationContext::ConstantEvaluated);      ExprResult Result = S.SubstExpr(Aligned->getAlignmentExpr(), TemplateArgs);      if (!Result.isInvalid())        S.AddAlignedAttr(Aligned->getLocation(), New, Result.getAs<Expr>(), @@ -138,7 +139,8 @@ static void instantiateDependentAssumeAlignedAttr(      Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs,      const AssumeAlignedAttr *Aligned, Decl *New) {    // The alignment expression is a constant expression. -  EnterExpressionEvaluationContext Unevaluated(S, Sema::ConstantEvaluated); +  EnterExpressionEvaluationContext Unevaluated( +      S, Sema::ExpressionEvaluationContext::ConstantEvaluated);    Expr *E, *OE = nullptr;    ExprResult Result = S.SubstExpr(Aligned->getAlignment(), TemplateArgs); @@ -161,20 +163,32 @@ static void instantiateDependentAlignValueAttr(      Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs,      const AlignValueAttr *Aligned, Decl *New) {    // The alignment expression is a constant expression. -  EnterExpressionEvaluationContext Unevaluated(S, Sema::ConstantEvaluated); +  EnterExpressionEvaluationContext Unevaluated( +      S, Sema::ExpressionEvaluationContext::ConstantEvaluated);    ExprResult Result = S.SubstExpr(Aligned->getAlignment(), TemplateArgs);    if (!Result.isInvalid())      S.AddAlignValueAttr(Aligned->getLocation(), New, Result.getAs<Expr>(),                          Aligned->getSpellingListIndex());  } +static void instantiateDependentAllocAlignAttr( +    Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs, +    const AllocAlignAttr *Align, Decl *New) { +  Expr *Param = IntegerLiteral::Create( +      S.getASTContext(), llvm::APInt(64, Align->getParamIndex()), +      S.getASTContext().UnsignedLongLongTy, Align->getLocation()); +  S.AddAllocAlignAttr(Align->getLocation(), New, Param, +                      Align->getSpellingListIndex()); +} +  static Expr *instantiateDependentFunctionAttrCondition(      Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs,      const Attr *A, Expr *OldCond, const Decl *Tmpl, FunctionDecl *New) {    Expr *Cond = nullptr;    {      Sema::ContextRAII SwitchContext(S, New); -    EnterExpressionEvaluationContext Unevaluated(S, Sema::ConstantEvaluated); +    EnterExpressionEvaluationContext Unevaluated( +        S, Sema::ExpressionEvaluationContext::ConstantEvaluated);      ExprResult Result = S.SubstExpr(OldCond, TemplateArgs);      if (Result.isInvalid())        return nullptr; @@ -229,7 +243,8 @@ static void instantiateDependentCUDALaunchBoundsAttr(      Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs,      const CUDALaunchBoundsAttr &Attr, Decl *New) {    // The alignment expression is a constant expression. -  EnterExpressionEvaluationContext Unevaluated(S, Sema::ConstantEvaluated); +  EnterExpressionEvaluationContext Unevaluated( +      S, Sema::ExpressionEvaluationContext::ConstantEvaluated);    ExprResult Result = S.SubstExpr(Attr.getMaxThreads(), TemplateArgs);    if (Result.isInvalid()) @@ -328,6 +343,34 @@ static void instantiateOMPDeclareSimdDeclAttr(        Attr.getRange());  } +static bool DeclContainsAttr(const Decl *D, const Attr *NewAttr) { +  if (!D->hasAttrs() || NewAttr->duplicatesAllowed()) +    return false; +  return llvm::find_if(D->getAttrs(), [NewAttr](const Attr *Attr) { +           return Attr->getKind() == NewAttr->getKind(); +         }) != D->getAttrs().end(); +} + +void Sema::InstantiateAttrsForDecl( +    const MultiLevelTemplateArgumentList &TemplateArgs, const Decl *Tmpl, +    Decl *New, LateInstantiatedAttrVec *LateAttrs, +    LocalInstantiationScope *OuterMostScope) { +  if (NamedDecl *ND = dyn_cast<NamedDecl>(New)) { +    for (const auto *TmplAttr : Tmpl->attrs()) { +      // FIXME: If any of the special case versions from InstantiateAttrs become +      // applicable to template declaration, we'll need to add them here. +      CXXThisScopeRAII ThisScope( +          *this, dyn_cast_or_null<CXXRecordDecl>(ND->getDeclContext()), +          /*TypeQuals*/ 0, ND->isCXXInstanceMember()); + +      Attr *NewAttr = sema::instantiateTemplateAttributeForDecl( +          TmplAttr, Context, *this, TemplateArgs); +      if (NewAttr && !DeclContainsAttr(New, NewAttr)) +        New->addAttr(NewAttr); +    } +  } +} +  void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs,                              const Decl *Tmpl, Decl *New,                              LateInstantiatedAttrVec *LateAttrs, @@ -352,6 +395,12 @@ void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs,        continue;      } +    if (const auto *AllocAlign = dyn_cast<AllocAlignAttr>(TmplAttr)) { +      instantiateDependentAllocAlignAttr(*this, TemplateArgs, AllocAlign, New); +      continue; +    } + +      if (const auto *EnableIf = dyn_cast<EnableIfAttr>(TmplAttr)) {        instantiateDependentEnableIfAttr(*this, TemplateArgs, EnableIf, Tmpl,                                         cast<FunctionDecl>(New)); @@ -421,7 +470,8 @@ void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs,        Attr *NewAttr = sema::instantiateTemplateAttribute(TmplAttr, Context,                                                           *this, TemplateArgs); -      if (NewAttr) + +      if (NewAttr && !DeclContainsAttr(New, NewAttr))          New->addAttr(NewAttr);      }    } @@ -657,10 +707,9 @@ Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D,                                               ArrayRef<BindingDecl*> *Bindings) {    // Do substitution on the type of the declaration -  TypeSourceInfo *DI = SemaRef.SubstType(D->getTypeSourceInfo(), -                                         TemplateArgs, -                                         D->getTypeSpecStartLoc(), -                                         D->getDeclName()); +  TypeSourceInfo *DI = SemaRef.SubstType( +      D->getTypeSourceInfo(), TemplateArgs, D->getTypeSpecStartLoc(), +      D->getDeclName(), /*AllowDeducedTST*/true);    if (!DI)      return nullptr; @@ -746,8 +795,8 @@ Decl *TemplateDeclInstantiator::VisitFieldDecl(FieldDecl *D) {      BitWidth = nullptr;    else if (BitWidth) {      // The bit-width expression is a constant expression. -    EnterExpressionEvaluationContext Unevaluated(SemaRef, -                                                 Sema::ConstantEvaluated); +    EnterExpressionEvaluationContext Unevaluated( +        SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);      ExprResult InstantiatedBitWidth        = SemaRef.SubstExpr(BitWidth, TemplateArgs); @@ -923,8 +972,8 @@ Decl *TemplateDeclInstantiator::VisitStaticAssertDecl(StaticAssertDecl *D) {    Expr *AssertExpr = D->getAssertExpr();    // The expression in a static assertion is a constant expression. -  EnterExpressionEvaluationContext Unevaluated(SemaRef, -                                               Sema::ConstantEvaluated); +  EnterExpressionEvaluationContext Unevaluated( +      SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);    ExprResult InstantiatedAssertExpr      = SemaRef.SubstExpr(AssertExpr, TemplateArgs); @@ -1034,8 +1083,8 @@ void TemplateDeclInstantiator::InstantiateEnumDefinition(      ExprResult Value((Expr *)nullptr);      if (Expr *UninstValue = EC->getInitExpr()) {        // The enumerator's value expression is a constant expression. -      EnterExpressionEvaluationContext Unevaluated(SemaRef, -                                                   Sema::ConstantEvaluated); +      EnterExpressionEvaluationContext Unevaluated( +          SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);        Value = SemaRef.SubstExpr(UninstValue, TemplateArgs);      } @@ -1600,13 +1649,18 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D,                                           TemplateArgs);    } -  FunctionDecl *Function = -      FunctionDecl::Create(SemaRef.Context, DC, D->getInnerLocStart(), -                           D->getNameInfo(), T, TInfo, -                           D->getCanonicalDecl()->getStorageClass(), -                           D->isInlineSpecified(), D->hasWrittenPrototype(), -                           D->isConstexpr()); -  Function->setRangeEnd(D->getSourceRange().getEnd()); +  FunctionDecl *Function; +  if (auto *DGuide = dyn_cast<CXXDeductionGuideDecl>(D)) +    Function = CXXDeductionGuideDecl::Create( +        SemaRef.Context, DC, D->getInnerLocStart(), DGuide->isExplicit(), +        D->getNameInfo(), T, TInfo, D->getSourceRange().getEnd()); +  else { +    Function = FunctionDecl::Create( +        SemaRef.Context, DC, D->getInnerLocStart(), D->getNameInfo(), T, TInfo, +        D->getCanonicalDecl()->getStorageClass(), D->isInlineSpecified(), +        D->hasWrittenPrototype(), D->isConstexpr()); +    Function->setRangeEnd(D->getSourceRange().getEnd()); +  }    if (D->isInlined())      Function->setImplicitlyInline(); @@ -1656,8 +1710,6 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D,      FunctionTemplate->setLexicalDeclContext(LexicalDC);      if (isFriend && D->isThisDeclarationADefinition()) { -      // TODO: should we remember this connection regardless of whether -      // the friend declaration provided a body?        FunctionTemplate->setInstantiatedFromMemberTemplate(                                             D->getDescribedFunctionTemplate());      } @@ -1668,13 +1720,10 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D,                              TemplateArgumentList::CreateCopy(SemaRef.Context,                                                               Innermost),                                                  /*InsertPos=*/nullptr); -  } else if (isFriend) { -    // Note, we need this connection even if the friend doesn't have a body. -    // Its body may exist but not have been attached yet due to deferred -    // parsing. -    // FIXME: It might be cleaner to set this when attaching the body to the -    // friend function declaration, however that would require finding all the -    // instantiations and modifying them. +  } else if (isFriend && D->isThisDeclarationADefinition()) { +    // Do not connect the friend to the template unless it's actually a +    // definition. We don't want non-template functions to be marked as being +    // template instantiations.      Function->setInstantiationOfMemberFunction(D, TSK_ImplicitInstantiation);    } @@ -2075,13 +2124,10 @@ Decl *TemplateDeclInstantiator::VisitTemplateTypeParmDecl(    // TODO: don't always clone when decls are refcounted.    assert(D->getTypeForDecl()->isTemplateTypeParmType()); -  TemplateTypeParmDecl *Inst = -    TemplateTypeParmDecl::Create(SemaRef.Context, Owner, -                                 D->getLocStart(), D->getLocation(), -                                 D->getDepth() - TemplateArgs.getNumLevels(), -                                 D->getIndex(), D->getIdentifier(), -                                 D->wasDeclaredWithTypename(), -                                 D->isParameterPack()); +  TemplateTypeParmDecl *Inst = TemplateTypeParmDecl::Create( +      SemaRef.Context, Owner, D->getLocStart(), D->getLocation(), +      D->getDepth() - TemplateArgs.getNumSubstitutedLevels(), D->getIndex(), +      D->getIdentifier(), D->wasDeclaredWithTypename(), D->isParameterPack());    Inst->setAccess(AS_public);    if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited()) { @@ -2219,25 +2265,22 @@ Decl *TemplateDeclInstantiator::VisitNonTypeTemplateParmDecl(    if (IsExpandedParameterPack)      Param = NonTypeTemplateParmDecl::Create(          SemaRef.Context, Owner, D->getInnerLocStart(), D->getLocation(), -        D->getDepth() - TemplateArgs.getNumLevels(), D->getPosition(), -        D->getIdentifier(), T, DI, ExpandedParameterPackTypes, +        D->getDepth() - TemplateArgs.getNumSubstitutedLevels(), +        D->getPosition(), D->getIdentifier(), T, DI, ExpandedParameterPackTypes,          ExpandedParameterPackTypesAsWritten);    else -    Param = NonTypeTemplateParmDecl::Create(SemaRef.Context, Owner, -                                            D->getInnerLocStart(), -                                            D->getLocation(), -                                    D->getDepth() - TemplateArgs.getNumLevels(), -                                            D->getPosition(), -                                            D->getIdentifier(), T, -                                            D->isParameterPack(), DI); +    Param = NonTypeTemplateParmDecl::Create( +        SemaRef.Context, Owner, D->getInnerLocStart(), D->getLocation(), +        D->getDepth() - TemplateArgs.getNumSubstitutedLevels(), +        D->getPosition(), D->getIdentifier(), T, D->isParameterPack(), DI);    Param->setAccess(AS_public);    if (Invalid)      Param->setInvalidDecl();    if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited()) { -    EnterExpressionEvaluationContext ConstantEvaluated(SemaRef, -                                                       Sema::ConstantEvaluated); +    EnterExpressionEvaluationContext ConstantEvaluated( +        SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);      ExprResult Value = SemaRef.SubstExpr(D->getDefaultArgument(), TemplateArgs);      if (!Value.isInvalid())        Param->setDefaultArgument(Value.get()); @@ -2350,19 +2393,15 @@ TemplateDeclInstantiator::VisitTemplateTemplateParmDecl(    // Build the template template parameter.    TemplateTemplateParmDecl *Param;    if (IsExpandedParameterPack) -    Param = TemplateTemplateParmDecl::Create(SemaRef.Context, Owner, -                                             D->getLocation(), -                                   D->getDepth() - TemplateArgs.getNumLevels(), -                                             D->getPosition(), -                                             D->getIdentifier(), InstParams, -                                             ExpandedParams); +    Param = TemplateTemplateParmDecl::Create( +        SemaRef.Context, Owner, D->getLocation(), +        D->getDepth() - TemplateArgs.getNumSubstitutedLevels(), +        D->getPosition(), D->getIdentifier(), InstParams, ExpandedParams);    else -    Param = TemplateTemplateParmDecl::Create(SemaRef.Context, Owner, -                                             D->getLocation(), -                                   D->getDepth() - TemplateArgs.getNumLevels(), -                                             D->getPosition(), -                                             D->isParameterPack(), -                                             D->getIdentifier(), InstParams); +    Param = TemplateTemplateParmDecl::Create( +        SemaRef.Context, Owner, D->getLocation(), +        D->getDepth() - TemplateArgs.getNumSubstitutedLevels(), +        D->getPosition(), D->isParameterPack(), D->getIdentifier(), InstParams);    if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited()) {      NestedNameSpecifierLoc QualifierLoc =          D->getDefaultArgument().getTemplateQualifierLoc(); @@ -2783,6 +2822,11 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D) {    return VisitFunctionDecl(D, nullptr);  } +Decl * +TemplateDeclInstantiator::VisitCXXDeductionGuideDecl(CXXDeductionGuideDecl *D) { +  return VisitFunctionDecl(D, nullptr); +} +  Decl *TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D) {    return VisitCXXMethodDecl(D, nullptr);  } @@ -3555,6 +3599,8 @@ TemplateDeclInstantiator::InitFunctionInstantiation(FunctionDecl *New,    if (Tmpl->isDeleted())      New->setDeletedAsWritten(); +  New->setImplicit(Tmpl->isImplicit()); +    // Forward the mangling number from the template to the instantiated decl.    SemaRef.Context.setManglingNumber(New,                                      SemaRef.Context.getManglingNumber(Tmpl)); @@ -3567,8 +3613,8 @@ TemplateDeclInstantiator::InitFunctionInstantiation(FunctionDecl *New,    // into a template instantiation for this specific function template    // specialization, which is not a SFINAE context, so that we diagnose any    // further errors in the declaration itself. -  typedef Sema::ActiveTemplateInstantiation ActiveInstType; -  ActiveInstType &ActiveInst = SemaRef.ActiveTemplateInstantiations.back(); +  typedef Sema::CodeSynthesisContext ActiveInstType; +  ActiveInstType &ActiveInst = SemaRef.CodeSynthesisContexts.back();    if (ActiveInst.Kind == ActiveInstType::ExplicitTemplateArgumentSubstitution ||        ActiveInst.Kind == ActiveInstType::DeducedTemplateArgumentSubstitution) {      if (FunctionTemplateDecl *FunTmpl @@ -3810,8 +3856,8 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,    // Copy the inner loc start from the pattern.    Function->setInnerLocStart(PatternDecl->getInnerLocStart()); -  EnterExpressionEvaluationContext EvalContext(*this, -                                               Sema::PotentiallyEvaluated); +  EnterExpressionEvaluationContext EvalContext( +      *this, Sema::ExpressionEvaluationContext::PotentiallyEvaluated);    // Introduce a new scope where local variable instantiations will be    // recorded, unless we're actually a member function within a local @@ -3864,6 +3910,8 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,      if (Body.isInvalid())        Function->setInvalidDecl(); +    // FIXME: finishing the function body while in an expression evaluation +    // context seems wrong. Investigate more.      ActOnFinishFunctionBody(Function, Body.get(),                              /*IsInstantiation=*/true); @@ -4073,9 +4121,11 @@ void Sema::InstantiateVariableInitializer(    if (OldVar->getInit()) {      if (Var->isStaticDataMember() && !OldVar->isOutOfLine()) -      PushExpressionEvaluationContext(Sema::ConstantEvaluated, OldVar); +      PushExpressionEvaluationContext( +          Sema::ExpressionEvaluationContext::ConstantEvaluated, OldVar);      else -      PushExpressionEvaluationContext(Sema::PotentiallyEvaluated, OldVar); +      PushExpressionEvaluationContext( +          Sema::ExpressionEvaluationContext::PotentiallyEvaluated, OldVar);      // Instantiate the initializer.      ExprResult Init; @@ -4954,6 +5004,28 @@ NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D,            DC = FD->getLexicalDeclContext();            continue;          } +        // An implicit deduction guide acts as if it's within the class template +        // specialization described by its name and first N template params. +        auto *Guide = dyn_cast<CXXDeductionGuideDecl>(FD); +        if (Guide && Guide->isImplicit()) { +          TemplateDecl *TD = Guide->getDeducedTemplate(); +          // Convert the arguments to an "as-written" list. +          TemplateArgumentListInfo Args(Loc, Loc); +          for (TemplateArgument Arg : TemplateArgs.getInnermost().take_front( +                                        TD->getTemplateParameters()->size())) { +            ArrayRef<TemplateArgument> Unpacked(Arg); +            if (Arg.getKind() == TemplateArgument::Pack) +              Unpacked = Arg.pack_elements(); +            for (TemplateArgument UnpackedArg : Unpacked) +              Args.addArgument( +                  getTrivialTemplateArgumentLoc(UnpackedArg, QualType(), Loc)); +          } +          QualType T = CheckTemplateIdType(TemplateName(TD), Loc, Args); +          if (T.isNull()) +            return nullptr; +          DC = T->getAsCXXRecordDecl(); +          continue; +        }        }        DC = DC->getParent();  | 
