diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Sema/SemaTemplateInstantiate.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/Sema/SemaTemplateInstantiate.cpp | 269 |
1 files changed, 144 insertions, 125 deletions
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaTemplateInstantiate.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaTemplateInstantiate.cpp index 128dc2f..20e755f 100644 --- a/contrib/llvm/tools/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/contrib/llvm/tools/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -156,11 +156,11 @@ bool Sema::ActiveTemplateInstantiation::isInstantiationRecord() const { case ExceptionSpecInstantiation: case DefaultTemplateArgumentInstantiation: case DefaultFunctionArgumentInstantiation: - return true; - case ExplicitTemplateArgumentSubstitution: case DeducedTemplateArgumentSubstitution: case PriorTemplateArgumentSubstitution: + return true; + case DefaultTemplateArgumentChecking: return false; } @@ -214,12 +214,11 @@ InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, } } -Sema::InstantiatingTemplate::InstantiatingTemplate(Sema &SemaRef, - SourceLocation PointOfInstantiation, - TemplateDecl *Template, - const TemplateArgument *TemplateArgs, - unsigned NumTemplateArgs, - SourceRange InstantiationRange) +Sema::InstantiatingTemplate:: +InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, + TemplateDecl *Template, + ArrayRef<TemplateArgument> TemplateArgs, + SourceRange InstantiationRange) : SemaRef(SemaRef), SavedInNonInstantiationSFINAEContext( SemaRef.InNonInstantiationSFINAEContext) @@ -232,35 +231,33 @@ Sema::InstantiatingTemplate::InstantiatingTemplate(Sema &SemaRef, = ActiveTemplateInstantiation::DefaultTemplateArgumentInstantiation; Inst.PointOfInstantiation = PointOfInstantiation; Inst.Entity = reinterpret_cast<uintptr_t>(Template); - Inst.TemplateArgs = TemplateArgs; - Inst.NumTemplateArgs = NumTemplateArgs; + Inst.TemplateArgs = TemplateArgs.data(); + Inst.NumTemplateArgs = TemplateArgs.size(); Inst.InstantiationRange = InstantiationRange; SemaRef.InNonInstantiationSFINAEContext = false; SemaRef.ActiveTemplateInstantiations.push_back(Inst); } } -Sema::InstantiatingTemplate::InstantiatingTemplate(Sema &SemaRef, - SourceLocation PointOfInstantiation, - FunctionTemplateDecl *FunctionTemplate, - const TemplateArgument *TemplateArgs, - unsigned NumTemplateArgs, - ActiveTemplateInstantiation::InstantiationKind Kind, - sema::TemplateDeductionInfo &DeductionInfo, - SourceRange InstantiationRange) +Sema::InstantiatingTemplate:: +InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, + FunctionTemplateDecl *FunctionTemplate, + ArrayRef<TemplateArgument> TemplateArgs, + ActiveTemplateInstantiation::InstantiationKind Kind, + sema::TemplateDeductionInfo &DeductionInfo, + SourceRange InstantiationRange) : SemaRef(SemaRef), SavedInNonInstantiationSFINAEContext( SemaRef.InNonInstantiationSFINAEContext) { - Invalid = CheckInstantiationDepth(PointOfInstantiation, - InstantiationRange); + Invalid = CheckInstantiationDepth(PointOfInstantiation, InstantiationRange); if (!Invalid) { ActiveTemplateInstantiation Inst; Inst.Kind = Kind; Inst.PointOfInstantiation = PointOfInstantiation; Inst.Entity = reinterpret_cast<uintptr_t>(FunctionTemplate); - Inst.TemplateArgs = TemplateArgs; - Inst.NumTemplateArgs = NumTemplateArgs; + Inst.TemplateArgs = TemplateArgs.data(); + Inst.NumTemplateArgs = TemplateArgs.size(); Inst.DeductionInfo = &DeductionInfo; Inst.InstantiationRange = InstantiationRange; SemaRef.InNonInstantiationSFINAEContext = false; @@ -271,54 +268,49 @@ Sema::InstantiatingTemplate::InstantiatingTemplate(Sema &SemaRef, } } -Sema::InstantiatingTemplate::InstantiatingTemplate(Sema &SemaRef, - SourceLocation PointOfInstantiation, - ClassTemplatePartialSpecializationDecl *PartialSpec, - const TemplateArgument *TemplateArgs, - unsigned NumTemplateArgs, - sema::TemplateDeductionInfo &DeductionInfo, - SourceRange InstantiationRange) +Sema::InstantiatingTemplate:: +InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, + ClassTemplatePartialSpecializationDecl *PartialSpec, + ArrayRef<TemplateArgument> TemplateArgs, + sema::TemplateDeductionInfo &DeductionInfo, + SourceRange InstantiationRange) : SemaRef(SemaRef), SavedInNonInstantiationSFINAEContext( SemaRef.InNonInstantiationSFINAEContext) { - Invalid = false; - - ActiveTemplateInstantiation Inst; - Inst.Kind = ActiveTemplateInstantiation::DeducedTemplateArgumentSubstitution; - Inst.PointOfInstantiation = PointOfInstantiation; - Inst.Entity = reinterpret_cast<uintptr_t>(PartialSpec); - Inst.TemplateArgs = TemplateArgs; - Inst.NumTemplateArgs = NumTemplateArgs; - Inst.DeductionInfo = &DeductionInfo; - Inst.InstantiationRange = InstantiationRange; - SemaRef.InNonInstantiationSFINAEContext = false; - SemaRef.ActiveTemplateInstantiations.push_back(Inst); - - assert(!Inst.isInstantiationRecord()); - ++SemaRef.NonInstantiationEntries; + Invalid = CheckInstantiationDepth(PointOfInstantiation, InstantiationRange); + if (!Invalid) { + ActiveTemplateInstantiation Inst; + Inst.Kind = ActiveTemplateInstantiation::DeducedTemplateArgumentSubstitution; + Inst.PointOfInstantiation = PointOfInstantiation; + Inst.Entity = reinterpret_cast<uintptr_t>(PartialSpec); + Inst.TemplateArgs = TemplateArgs.data(); + Inst.NumTemplateArgs = TemplateArgs.size(); + Inst.DeductionInfo = &DeductionInfo; + Inst.InstantiationRange = InstantiationRange; + SemaRef.InNonInstantiationSFINAEContext = false; + SemaRef.ActiveTemplateInstantiations.push_back(Inst); + } } -Sema::InstantiatingTemplate::InstantiatingTemplate(Sema &SemaRef, - SourceLocation PointOfInstantiation, - ParmVarDecl *Param, - const TemplateArgument *TemplateArgs, - unsigned NumTemplateArgs, - SourceRange InstantiationRange) +Sema::InstantiatingTemplate:: +InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, + ParmVarDecl *Param, + ArrayRef<TemplateArgument> TemplateArgs, + SourceRange InstantiationRange) : SemaRef(SemaRef), SavedInNonInstantiationSFINAEContext( SemaRef.InNonInstantiationSFINAEContext) { Invalid = CheckInstantiationDepth(PointOfInstantiation, InstantiationRange); - if (!Invalid) { ActiveTemplateInstantiation Inst; Inst.Kind = ActiveTemplateInstantiation::DefaultFunctionArgumentInstantiation; Inst.PointOfInstantiation = PointOfInstantiation; Inst.Entity = reinterpret_cast<uintptr_t>(Param); - Inst.TemplateArgs = TemplateArgs; - Inst.NumTemplateArgs = NumTemplateArgs; + Inst.TemplateArgs = TemplateArgs.data(); + Inst.NumTemplateArgs = TemplateArgs.size(); Inst.InstantiationRange = InstantiationRange; SemaRef.InNonInstantiationSFINAEContext = false; SemaRef.ActiveTemplateInstantiations.push_back(Inst); @@ -327,66 +319,57 @@ Sema::InstantiatingTemplate::InstantiatingTemplate(Sema &SemaRef, Sema::InstantiatingTemplate:: InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, - NamedDecl *Template, - NonTypeTemplateParmDecl *Param, - const TemplateArgument *TemplateArgs, - unsigned NumTemplateArgs, - SourceRange InstantiationRange) + NamedDecl *Template, NonTypeTemplateParmDecl *Param, + ArrayRef<TemplateArgument> TemplateArgs, + SourceRange InstantiationRange) : SemaRef(SemaRef), SavedInNonInstantiationSFINAEContext( SemaRef.InNonInstantiationSFINAEContext) { - Invalid = false; - - ActiveTemplateInstantiation Inst; - Inst.Kind = ActiveTemplateInstantiation::PriorTemplateArgumentSubstitution; - Inst.PointOfInstantiation = PointOfInstantiation; - Inst.Template = Template; - Inst.Entity = reinterpret_cast<uintptr_t>(Param); - Inst.TemplateArgs = TemplateArgs; - Inst.NumTemplateArgs = NumTemplateArgs; - Inst.InstantiationRange = InstantiationRange; - SemaRef.InNonInstantiationSFINAEContext = false; - SemaRef.ActiveTemplateInstantiations.push_back(Inst); - - assert(!Inst.isInstantiationRecord()); - ++SemaRef.NonInstantiationEntries; + Invalid = CheckInstantiationDepth(PointOfInstantiation, InstantiationRange); + if (!Invalid) { + ActiveTemplateInstantiation Inst; + Inst.Kind = ActiveTemplateInstantiation::PriorTemplateArgumentSubstitution; + Inst.PointOfInstantiation = PointOfInstantiation; + Inst.Template = Template; + Inst.Entity = reinterpret_cast<uintptr_t>(Param); + Inst.TemplateArgs = TemplateArgs.data(); + Inst.NumTemplateArgs = TemplateArgs.size(); + Inst.InstantiationRange = InstantiationRange; + SemaRef.InNonInstantiationSFINAEContext = false; + SemaRef.ActiveTemplateInstantiations.push_back(Inst); + } } Sema::InstantiatingTemplate:: InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, - NamedDecl *Template, - TemplateTemplateParmDecl *Param, - const TemplateArgument *TemplateArgs, - unsigned NumTemplateArgs, - SourceRange InstantiationRange) + NamedDecl *Template, TemplateTemplateParmDecl *Param, + ArrayRef<TemplateArgument> TemplateArgs, + SourceRange InstantiationRange) : SemaRef(SemaRef), SavedInNonInstantiationSFINAEContext( SemaRef.InNonInstantiationSFINAEContext) { - Invalid = false; - ActiveTemplateInstantiation Inst; - Inst.Kind = ActiveTemplateInstantiation::PriorTemplateArgumentSubstitution; - Inst.PointOfInstantiation = PointOfInstantiation; - Inst.Template = Template; - Inst.Entity = reinterpret_cast<uintptr_t>(Param); - Inst.TemplateArgs = TemplateArgs; - Inst.NumTemplateArgs = NumTemplateArgs; - Inst.InstantiationRange = InstantiationRange; - SemaRef.InNonInstantiationSFINAEContext = false; - SemaRef.ActiveTemplateInstantiations.push_back(Inst); - - assert(!Inst.isInstantiationRecord()); - ++SemaRef.NonInstantiationEntries; + Invalid = CheckInstantiationDepth(PointOfInstantiation, InstantiationRange); + if (!Invalid) { + ActiveTemplateInstantiation Inst; + Inst.Kind = ActiveTemplateInstantiation::PriorTemplateArgumentSubstitution; + Inst.PointOfInstantiation = PointOfInstantiation; + Inst.Template = Template; + Inst.Entity = reinterpret_cast<uintptr_t>(Param); + Inst.TemplateArgs = TemplateArgs.data(); + Inst.NumTemplateArgs = TemplateArgs.size(); + Inst.InstantiationRange = InstantiationRange; + SemaRef.InNonInstantiationSFINAEContext = false; + SemaRef.ActiveTemplateInstantiations.push_back(Inst); + } } Sema::InstantiatingTemplate:: InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, - TemplateDecl *Template, - NamedDecl *Param, - const TemplateArgument *TemplateArgs, - unsigned NumTemplateArgs, - SourceRange InstantiationRange) + TemplateDecl *Template, NamedDecl *Param, + ArrayRef<TemplateArgument> TemplateArgs, + SourceRange InstantiationRange) : SemaRef(SemaRef), SavedInNonInstantiationSFINAEContext( SemaRef.InNonInstantiationSFINAEContext) @@ -398,8 +381,8 @@ InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, Inst.PointOfInstantiation = PointOfInstantiation; Inst.Template = Template; Inst.Entity = reinterpret_cast<uintptr_t>(Param); - Inst.TemplateArgs = TemplateArgs; - Inst.NumTemplateArgs = NumTemplateArgs; + Inst.TemplateArgs = TemplateArgs.data(); + Inst.NumTemplateArgs = TemplateArgs.size(); Inst.InstantiationRange = InstantiationRange; SemaRef.InNonInstantiationSFINAEContext = false; SemaRef.ActiveTemplateInstantiations.push_back(Inst); @@ -638,8 +621,13 @@ llvm::Optional<TemplateDeductionInfo *> Sema::isSFINAEContext() const { ++Active) { switch(Active->Kind) { - case ActiveTemplateInstantiation::DefaultFunctionArgumentInstantiation: case ActiveTemplateInstantiation::TemplateInstantiation: + // An instantiation of an alias template may or may not be a SFINAE + // context, depending on what else is on the stack. + if (isa<TypeAliasTemplateDecl>(reinterpret_cast<Decl *>(Active->Entity))) + break; + // Fall through. + case ActiveTemplateInstantiation::DefaultFunctionArgumentInstantiation: case ActiveTemplateInstantiation::ExceptionSpecInstantiation: // This is a template instantiation, so there is no SFINAE. return llvm::Optional<TemplateDeductionInfo *>(); @@ -850,10 +838,23 @@ namespace { return move(Result); } + ExprResult TransformLambdaExpr(LambdaExpr *E) { + LocalInstantiationScope Scope(SemaRef, /*CombineWithOuterScope=*/true); + return TreeTransform<TemplateInstantiator>::TransformLambdaExpr(E); + } + + ExprResult TransformLambdaScope(LambdaExpr *E, + CXXMethodDecl *CallOperator) { + CallOperator->setInstantiationOfMemberFunction(E->getCallOperator(), + TSK_ImplicitInstantiation); + return TreeTransform<TemplateInstantiator>:: + TransformLambdaScope(E, CallOperator); + } + private: ExprResult transformNonTypeTemplateParmRef(NonTypeTemplateParmDecl *parm, SourceLocation loc, - const TemplateArgument &arg); + TemplateArgument arg); }; } @@ -987,12 +988,11 @@ TemplateInstantiator::RebuildElaboratedType(SourceLocation KeywordLoc, SourceLocation TagLocation = KeywordLoc; - // FIXME: type might be anonymous. IdentifierInfo *Id = TD->getIdentifier(); // TODO: should we even warn on struct/class mismatches for this? Seems // like it's likely to produce a lot of spurious errors. - if (Keyword != ETK_None && Keyword != ETK_Typename) { + if (Id && Keyword != ETK_None && Keyword != ETK_Typename) { TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForKeyword(Keyword); if (!SemaRef.isAcceptableTagRedeclaration(TD, Kind, /*isDefinition*/false, TagLocation, *Id)) { @@ -1088,7 +1088,11 @@ TemplateInstantiator::TransformPredefinedExpr(PredefinedExpr *E) { unsigned Length = PredefinedExpr::ComputeName(IT, currentDecl).length(); llvm::APInt LengthI(32, Length + 1); - QualType ResTy = getSema().Context.CharTy.withConst(); + QualType ResTy; + if (IT == PredefinedExpr::LFunction) + ResTy = getSema().Context.WCharTy.withConst(); + else + ResTy = getSema().Context.CharTy.withConst(); ResTy = getSema().Context.getConstantArrayType(ResTy, LengthI, ArrayType::Normal, 0); PredefinedExpr *PE = @@ -1138,10 +1142,18 @@ TemplateInstantiator::TransformTemplateParmRefExpr(DeclRefExpr *E, ExprResult TemplateInstantiator::transformNonTypeTemplateParmRef( NonTypeTemplateParmDecl *parm, SourceLocation loc, - const TemplateArgument &arg) { + TemplateArgument arg) { ExprResult result; QualType type; + // If the argument is a pack expansion, the parameter must actually be a + // parameter pack, and we should substitute the pattern itself, producing + // an expression which contains an unexpanded parameter pack. + if (arg.isPackExpansion()) { + assert(parm->isParameterPack() && "pack expansion for non-pack"); + arg = arg.getPackExpansionPattern(); + } + // The template argument itself might be an expression, in which // case we just return that expression. if (arg.getKind() == TemplateArgument::Expression) { @@ -1378,7 +1390,7 @@ TemplateInstantiator::TransformSubstTemplateTypeParmPackType( /// substituted. If this type is not dependent, it will be returned /// immediately. /// -/// \param TemplateArgs the template arguments that will be +/// \param Args the template arguments that will be /// substituted for the top-level template parameters within T. /// /// \param Loc the location in the source code where this substitution @@ -1590,6 +1602,9 @@ ParmVarDecl *Sema::SubstParmVarDecl(ParmVarDecl *OldParm, NewParm->setUnparsedDefaultArg(); UnparsedDefaultArgInstantiations[OldParm].push_back(NewParm); } else if (Expr *Arg = OldParm->getDefaultArg()) + // FIXME: if we non-lazily instantiated non-dependent default args for + // non-dependent parameter types we could remove a bunch of duplicate + // conversion warnings for such arguments. NewParm->setUninstantiatedDefaultArg(Arg); NewParm->setHasInheritedDefaultArg(OldParm->hasInheritedDefaultArg()); @@ -1820,8 +1835,6 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation, const MultiLevelTemplateArgumentList &TemplateArgs, TemplateSpecializationKind TSK, bool Complain) { - bool Invalid = false; - CXXRecordDecl *PatternDef = cast_or_null<CXXRecordDecl>(Pattern->getDefinition()); if (DiagnoseUninstantiableTemplate(*this, PointOfInstantiation, Instantiation, @@ -1867,7 +1880,7 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation, // Do substitution on the base class specifiers. if (SubstBaseSpecifiers(Instantiation, Pattern, TemplateArgs)) - Invalid = true; + Instantiation->setInvalidDecl(); TemplateDeclInstantiator Instantiator(*this, Instantiation, TemplateArgs); SmallVector<Decl*, 4> Fields; @@ -1893,7 +1906,7 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation, continue; if ((*Member)->isInvalidDecl()) { - Invalid = true; + Instantiation->setInvalidDecl(); continue; } @@ -1917,14 +1930,22 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation, MSInfo->setTemplateSpecializationKind(TSK_ImplicitInstantiation); MSInfo->setPointOfInstantiation(PointOfInstantiation); } + } else if (StaticAssertDecl *SA = dyn_cast<StaticAssertDecl>(NewMember)) { + if (SA->isFailed()) { + // A static_assert failed. Bail out; instantiating this + // class is probably not meaningful. + Instantiation->setInvalidDecl(); + break; + } } if (NewMember->isInvalidDecl()) - Invalid = true; + Instantiation->setInvalidDecl(); } else { // FIXME: Eventually, a NULL return will mean that one of the - // instantiations was a semantic disaster, and we'll want to set Invalid = - // true. For now, we expect to skip some members that we can't yet handle. + // instantiations was a semantic disaster, and we'll want to mark the + // declaration invalid. + // For now, we expect to skip some members that we can't yet handle. } } @@ -1934,7 +1955,7 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation, CheckCompletedCXXClass(Instantiation); // Attach any in-class member initializers now the class is complete. - { + if (!FieldsWithMemberInitializers.empty()) { // C++11 [expr.prim.general]p4: // Otherwise, if a member-declarator declares a non-static data member // (9.2) of a class X, the expression this is a prvalue of type "pointer @@ -1955,9 +1976,7 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation, Expr *Init = NewInit.take(); assert(Init && "no-argument initializer in class"); assert(!isa<ParenListExpr>(Init) && "call-style init in class"); - ActOnCXXInClassMemberInitializer(NewField, - Init->getSourceRange().getBegin(), - Init); + ActOnCXXInClassMemberInitializer(NewField, Init->getLocStart(), Init); } } } @@ -1976,8 +1995,7 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation, Instantiator.disableLateAttributeInstantiation(); LateAttrs.clear(); - if (!FieldsWithMemberInitializers.empty()) - ActOnFinishDelayedMemberInitializers(Instantiation); + ActOnFinishDelayedMemberInitializers(Instantiation); if (TSK == TSK_ImplicitInstantiation) { Instantiation->setLocation(Pattern->getLocation()); @@ -1985,9 +2003,10 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation, Instantiation->setRBraceLoc(Pattern->getRBraceLoc()); } - if (Instantiation->isInvalidDecl()) - Invalid = true; - else { + if (!Instantiation->isInvalidDecl()) { + // Perform any dependent diagnostics from the pattern. + PerformDependentDiagnostics(Pattern, TemplateArgs); + // Instantiate any out-of-line class template partial // specializations now. for (TemplateDeclInstantiator::delayed_partial_spec_iterator @@ -1997,7 +2016,7 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation, if (!Instantiator.InstantiateClassTemplatePartialSpecialization( P->first, P->second)) { - Invalid = true; + Instantiation->setInvalidDecl(); break; } } @@ -2006,7 +2025,7 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation, // Exit the scope of this instantiation. SavedContext.pop(); - if (!Invalid) { + if (!Instantiation->isInvalidDecl()) { Consumer.HandleTagDeclDefinition(Instantiation); // Always emit the vtable for an explicit instantiation definition @@ -2015,7 +2034,7 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation, MarkVTableUsed(PointOfInstantiation, Instantiation, true); } - return Invalid; + return Instantiation->isInvalidDecl(); } /// \brief Instantiate the definition of an enum from a given pattern. |