summaryrefslogtreecommitdiffstats
path: root/lib/Sema/SemaTemplateInstantiate.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Sema/SemaTemplateInstantiate.cpp')
-rw-r--r--lib/Sema/SemaTemplateInstantiate.cpp131
1 files changed, 32 insertions, 99 deletions
diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp
index 0d6acd0..d21862b 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();
OpenPOWER on IntegriCloud