diff options
Diffstat (limited to 'lib/Sema/SemaTemplateInstantiate.cpp')
-rw-r--r-- | lib/Sema/SemaTemplateInstantiate.cpp | 131 |
1 files changed, 32 insertions, 99 deletions
diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp index 0d6acd0e81c8..d21862b71e89 100644 --- a/lib/Sema/SemaTemplateInstantiate.cpp +++ b/lib/Sema/SemaTemplateInstantiate.cpp @@ -394,7 +394,11 @@ void Sema::PrintInstantiationStack() { = cast<FunctionTemplateDecl>((Decl *)Active->Entity); Diags.Report(FullSourceLoc(Active->PointOfInstantiation, SourceMgr), diag::note_explicit_template_arg_substitution_here) - << FnTmpl << Active->InstantiationRange; + << FnTmpl + << getTemplateArgumentBindingsText(FnTmpl->getTemplateParameters(), + Active->TemplateArgs, + Active->NumTemplateArgs) + << Active->InstantiationRange; break; } @@ -405,13 +409,21 @@ void Sema::PrintInstantiationStack() { Diags.Report(FullSourceLoc(Active->PointOfInstantiation, SourceMgr), diag::note_partial_spec_deduct_instantiation_here) << Context.getTypeDeclType(PartialSpec) + << getTemplateArgumentBindingsText( + PartialSpec->getTemplateParameters(), + Active->TemplateArgs, + Active->NumTemplateArgs) << Active->InstantiationRange; } else { FunctionTemplateDecl *FnTmpl = cast<FunctionTemplateDecl>((Decl *)Active->Entity); Diags.Report(FullSourceLoc(Active->PointOfInstantiation, SourceMgr), diag::note_function_template_deduction_instantiation_here) - << FnTmpl << Active->InstantiationRange; + << FnTmpl + << getTemplateArgumentBindingsText(FnTmpl->getTemplateParameters(), + Active->TemplateArgs, + Active->NumTemplateArgs) + << Active->InstantiationRange; } break; @@ -677,8 +689,8 @@ TemplateInstantiator::RebuildElaboratedType(QualType T, if (!SemaRef.isAcceptableTagRedeclaration(TD, Tag, TagLocation, *Id)) { SemaRef.Diag(TagLocation, diag::err_use_with_wrong_tag) << Id - << CodeModificationHint::CreateReplacement(SourceRange(TagLocation), - TD->getKindName()); + << FixItHint::CreateReplacement(SourceRange(TagLocation), + TD->getKindName()); SemaRef.Diag(TD->getLocation(), diag::note_previous_use); } } @@ -745,101 +757,13 @@ TemplateInstantiator::TransformTemplateParmRefExpr(DeclRefExpr *E, DeclarationName()); assert(!TargetType.isNull() && "type substitution failed for param type"); assert(!TargetType->isDependentType() && "param type still dependent"); - - if (VD->getDeclContext()->isRecord() && - (isa<CXXMethodDecl>(VD) || isa<FieldDecl>(VD))) { - // If the value is a class member, we might have a pointer-to-member. - // Determine whether the non-type template template parameter is of - // pointer-to-member type. If so, we need to build an appropriate - // expression for a pointer-to-member, since a "normal" DeclRefExpr - // would refer to the member itself. - if (TargetType->isMemberPointerType()) { - QualType ClassType - = SemaRef.Context.getTypeDeclType( - cast<RecordDecl>(VD->getDeclContext())); - NestedNameSpecifier *Qualifier - = NestedNameSpecifier::Create(SemaRef.Context, 0, false, - ClassType.getTypePtr()); - CXXScopeSpec SS; - SS.setScopeRep(Qualifier); - OwningExprResult RefExpr - = SemaRef.BuildDeclRefExpr(VD, - VD->getType().getNonReferenceType(), - E->getLocation(), - &SS); - if (RefExpr.isInvalid()) - return SemaRef.ExprError(); - - RefExpr = SemaRef.CreateBuiltinUnaryOp(E->getLocation(), - UnaryOperator::AddrOf, - move(RefExpr)); - assert(!RefExpr.isInvalid() && - SemaRef.Context.hasSameType(((Expr*) RefExpr.get())->getType(), - TargetType)); - return move(RefExpr); - } - } - - QualType T = VD->getType().getNonReferenceType(); - - if (TargetType->isPointerType()) { - // C++03 [temp.arg.nontype]p5: - // - For a non-type template-parameter of type pointer to - // object, qualification conversions and the array-to-pointer - // conversion are applied. - // - For a non-type template-parameter of type pointer to - // function, only the function-to-pointer conversion is - // applied. - - OwningExprResult RefExpr - = SemaRef.BuildDeclRefExpr(VD, T, E->getLocation()); - if (RefExpr.isInvalid()) - return SemaRef.ExprError(); - - // Decay functions and arrays. - Expr *RefE = (Expr *)RefExpr.get(); - SemaRef.DefaultFunctionArrayConversion(RefE); - if (RefE != RefExpr.get()) { - RefExpr.release(); - RefExpr = SemaRef.Owned(RefE); - } - - // Qualification conversions. - RefExpr.release(); - SemaRef.ImpCastExprToType(RefE, TargetType.getUnqualifiedType(), - CastExpr::CK_NoOp); - return SemaRef.Owned(RefE); - } - - // If the non-type template parameter has reference type, qualify the - // resulting declaration reference with the extra qualifiers on the - // type that the reference refers to. - if (const ReferenceType *TargetRef = TargetType->getAs<ReferenceType>()) - T = SemaRef.Context.getQualifiedType(T, - TargetRef->getPointeeType().getQualifiers()); - - return SemaRef.BuildDeclRefExpr(VD, T, E->getLocation()); + return SemaRef.BuildExpressionFromDeclTemplateArgument(Arg, + TargetType, + E->getLocation()); } - assert(Arg.getKind() == TemplateArgument::Integral); - QualType T = Arg.getIntegralType(); - if (T->isCharType() || T->isWideCharType()) - return SemaRef.Owned(new (SemaRef.Context) CharacterLiteral( - Arg.getAsIntegral()->getZExtValue(), - T->isWideCharType(), - T, - E->getSourceRange().getBegin())); - if (T->isBooleanType()) - return SemaRef.Owned(new (SemaRef.Context) CXXBoolLiteralExpr( - Arg.getAsIntegral()->getBoolValue(), - T, - E->getSourceRange().getBegin())); - - assert(Arg.getAsIntegral()->getBitWidth() == SemaRef.Context.getIntWidth(T)); - return SemaRef.Owned(new (SemaRef.Context) IntegerLiteral( - *Arg.getAsIntegral(), - T, - E->getSourceRange().getBegin())); + return SemaRef.BuildExpressionFromIntegralTemplateArgument(Arg, + E->getSourceRange().getBegin()); } @@ -873,8 +797,11 @@ TemplateInstantiator::TransformFunctionTypeParams(FunctionProtoTypeLoc TL, llvm::SmallVectorImpl<QualType> &PTypes, llvm::SmallVectorImpl<ParmVarDecl*> &PVars) { // Create a local instantiation scope for the parameters. - Sema::LocalInstantiationScope - Scope(SemaRef, SemaRef.CurrentInstantiationScope != 0); + // FIXME: When we implement the C++0x late-specified return type, + // we will need to move this scope out to the function type itself. + bool IsTemporaryScope = (SemaRef.CurrentInstantiationScope != 0); + Sema::LocalInstantiationScope Scope(SemaRef, IsTemporaryScope, + IsTemporaryScope); if (TreeTransform<TemplateInstantiator>:: TransformFunctionTypeParams(TL, PTypes, PVars)) @@ -1159,6 +1086,12 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation, DeclContext *PreviousContext = CurContext; CurContext = Instantiation; + // If this is an instantiation of a local class, merge this local + // instantiation scope with the enclosing scope. Otherwise, every + // instantiation of a class has its own local instantiation scope. + bool MergeWithParentScope = !Instantiation->isDefinedOutsideFunctionOrMethod(); + Sema::LocalInstantiationScope Scope(*this, MergeWithParentScope); + // Start the definition of this instantiation. Instantiation->startDefinition(); |