summaryrefslogtreecommitdiffstats
path: root/lib/Sema/SemaTemplateInstantiate.cpp
diff options
context:
space:
mode:
authored <ed@FreeBSD.org>2009-06-27 10:45:02 +0000
committered <ed@FreeBSD.org>2009-06-27 10:45:02 +0000
commitc1ff020ff2d3e7ba86f7ab986ac7569c34f2ab1a (patch)
tree2c5a83521a20c02e7805581a174008aa9bc23579 /lib/Sema/SemaTemplateInstantiate.cpp
parent14660dbe9881f68a6cc2b9f014e1fb7b7228bca4 (diff)
downloadFreeBSD-src-c1ff020ff2d3e7ba86f7ab986ac7569c34f2ab1a.zip
FreeBSD-src-c1ff020ff2d3e7ba86f7ab986ac7569c34f2ab1a.tar.gz
Import Clang r74383.
Diffstat (limited to 'lib/Sema/SemaTemplateInstantiate.cpp')
-rw-r--r--lib/Sema/SemaTemplateInstantiate.cpp176
1 files changed, 89 insertions, 87 deletions
diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp
index 1c4e907..aed3489 100644
--- a/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/lib/Sema/SemaTemplateInstantiate.cpp
@@ -29,10 +29,18 @@ using namespace clang;
/// instantiate the given declaration.
const TemplateArgumentList &
Sema::getTemplateInstantiationArgs(NamedDecl *D) {
+ // Template arguments for a class template specialization.
if (ClassTemplateSpecializationDecl *Spec
= dyn_cast<ClassTemplateSpecializationDecl>(D))
return Spec->getTemplateArgs();
+ // Template arguments for a function template specialization.
+ if (FunctionDecl *Function = dyn_cast<FunctionDecl>(D))
+ if (const TemplateArgumentList *TemplateArgs
+ = Function->getTemplateSpecializationArgs())
+ return *TemplateArgs;
+
+ // Template arguments for a member of a class template specialization.
DeclContext *EnclosingTemplateCtx = D->getDeclContext();
while (!isa<ClassTemplateSpecializationDecl>(EnclosingTemplateCtx)) {
assert(!EnclosingTemplateCtx->isFileContext() &&
@@ -158,8 +166,11 @@ void Sema::PrintInstantiationStack() {
<< Active->InstantiationRange;
} else {
FunctionDecl *Function = cast<FunctionDecl>(D);
- unsigned DiagID = diag::note_template_member_function_here;
- // FIXME: check for a function template
+ unsigned DiagID;
+ if (Function->getPrimaryTemplate())
+ DiagID = diag::note_function_template_spec_here;
+ else
+ DiagID = diag::note_template_member_function_here;
Diags.Report(FullSourceLoc(Active->PointOfInstantiation, SourceMgr),
DiagID)
<< Function
@@ -251,88 +262,82 @@ namespace {
// Declare instantiate functions for each type.
#define TYPE(Class, Base) \
- QualType Instantiate##Class##Type(const Class##Type *T, \
- unsigned Quals) const;
+ QualType Instantiate##Class##Type(const Class##Type *T) const;
#define ABSTRACT_TYPE(Class, Base)
#include "clang/AST/TypeNodes.def"
};
}
QualType
-TemplateTypeInstantiator::InstantiateExtQualType(const ExtQualType *T,
- unsigned Quals) const {
+TemplateTypeInstantiator::InstantiateExtQualType(const ExtQualType *T) const {
// FIXME: Implement this
assert(false && "Cannot instantiate ExtQualType yet");
return QualType();
}
QualType
-TemplateTypeInstantiator::InstantiateBuiltinType(const BuiltinType *T,
- unsigned Quals) const {
+TemplateTypeInstantiator::InstantiateBuiltinType(const BuiltinType *T) const {
assert(false && "Builtin types are not dependent and cannot be instantiated");
- return QualType(T, Quals);
+ return QualType(T, 0);
}
QualType
TemplateTypeInstantiator::
-InstantiateFixedWidthIntType(const FixedWidthIntType *T, unsigned Quals) const {
+InstantiateFixedWidthIntType(const FixedWidthIntType *T) const {
// FIXME: Implement this
assert(false && "Cannot instantiate FixedWidthIntType yet");
return QualType();
}
QualType
-TemplateTypeInstantiator::InstantiateComplexType(const ComplexType *T,
- unsigned Quals) const {
+TemplateTypeInstantiator::InstantiateComplexType(const ComplexType *T) const {
// FIXME: Implement this
assert(false && "Cannot instantiate ComplexType yet");
return QualType();
}
QualType
-TemplateTypeInstantiator::InstantiatePointerType(const PointerType *T,
- unsigned Quals) const {
+TemplateTypeInstantiator::InstantiatePointerType(const PointerType *T) const {
QualType PointeeType = Instantiate(T->getPointeeType());
if (PointeeType.isNull())
return QualType();
- return SemaRef.BuildPointerType(PointeeType, Quals, Loc, Entity);
+ return SemaRef.BuildPointerType(PointeeType, 0, Loc, Entity);
}
QualType
-TemplateTypeInstantiator::InstantiateBlockPointerType(const BlockPointerType *T,
- unsigned Quals) const {
+TemplateTypeInstantiator::InstantiateBlockPointerType(
+ const BlockPointerType *T) const {
QualType PointeeType = Instantiate(T->getPointeeType());
if (PointeeType.isNull())
return QualType();
- return SemaRef.BuildBlockPointerType(PointeeType, Quals, Loc, Entity);
+ return SemaRef.BuildBlockPointerType(PointeeType, 0, Loc, Entity);
}
QualType
TemplateTypeInstantiator::InstantiateLValueReferenceType(
- const LValueReferenceType *T, unsigned Quals) const {
+ const LValueReferenceType *T) const {
QualType ReferentType = Instantiate(T->getPointeeType());
if (ReferentType.isNull())
return QualType();
- return SemaRef.BuildReferenceType(ReferentType, true, Quals, Loc, Entity);
+ return SemaRef.BuildReferenceType(ReferentType, true, 0, Loc, Entity);
}
QualType
TemplateTypeInstantiator::InstantiateRValueReferenceType(
- const RValueReferenceType *T, unsigned Quals) const {
+ const RValueReferenceType *T) const {
QualType ReferentType = Instantiate(T->getPointeeType());
if (ReferentType.isNull())
return QualType();
- return SemaRef.BuildReferenceType(ReferentType, false, Quals, Loc, Entity);
+ return SemaRef.BuildReferenceType(ReferentType, false, 0, Loc, Entity);
}
QualType
TemplateTypeInstantiator::
-InstantiateMemberPointerType(const MemberPointerType *T,
- unsigned Quals) const {
+InstantiateMemberPointerType(const MemberPointerType *T) const {
QualType PointeeType = Instantiate(T->getPointeeType());
if (PointeeType.isNull())
return QualType();
@@ -341,14 +346,13 @@ InstantiateMemberPointerType(const MemberPointerType *T,
if (ClassType.isNull())
return QualType();
- return SemaRef.BuildMemberPointerType(PointeeType, ClassType, Quals, Loc,
+ return SemaRef.BuildMemberPointerType(PointeeType, ClassType, 0, Loc,
Entity);
}
QualType
TemplateTypeInstantiator::
-InstantiateConstantArrayType(const ConstantArrayType *T,
- unsigned Quals) const {
+InstantiateConstantArrayType(const ConstantArrayType *T) const {
QualType ElementType = Instantiate(T->getElementType());
if (ElementType.isNull())
return ElementType;
@@ -383,8 +387,7 @@ InstantiateConstantArrayType(const ConstantArrayType *T,
QualType
TemplateTypeInstantiator::
-InstantiateIncompleteArrayType(const IncompleteArrayType *T,
- unsigned Quals) const {
+InstantiateIncompleteArrayType(const IncompleteArrayType *T) const {
QualType ElementType = Instantiate(T->getElementType());
if (ElementType.isNull())
return ElementType;
@@ -396,8 +399,7 @@ InstantiateIncompleteArrayType(const IncompleteArrayType *T,
QualType
TemplateTypeInstantiator::
-InstantiateVariableArrayType(const VariableArrayType *T,
- unsigned Quals) const {
+InstantiateVariableArrayType(const VariableArrayType *T) const {
// FIXME: Implement this
assert(false && "Cannot instantiate VariableArrayType yet");
return QualType();
@@ -405,8 +407,7 @@ InstantiateVariableArrayType(const VariableArrayType *T,
QualType
TemplateTypeInstantiator::
-InstantiateDependentSizedArrayType(const DependentSizedArrayType *T,
- unsigned Quals) const {
+InstantiateDependentSizedArrayType(const DependentSizedArrayType *T) const {
Expr *ArraySize = T->getSizeExpr();
assert(ArraySize->isValueDependent() &&
"dependent sized array types must have value dependent size expr");
@@ -433,8 +434,8 @@ InstantiateDependentSizedArrayType(const DependentSizedArrayType *T,
QualType
TemplateTypeInstantiator::
-InstantiateDependentSizedExtVectorType(const DependentSizedExtVectorType *T,
- unsigned Quals) const {
+InstantiateDependentSizedExtVectorType(
+ const DependentSizedExtVectorType *T) const {
// Instantiate the element type if needed.
QualType ElementType = T->getElementType();
@@ -462,16 +463,15 @@ InstantiateDependentSizedExtVectorType(const DependentSizedExtVectorType *T,
}
QualType
-TemplateTypeInstantiator::InstantiateVectorType(const VectorType *T,
- unsigned Quals) const {
+TemplateTypeInstantiator::InstantiateVectorType(const VectorType *T) const {
// FIXME: Implement this
assert(false && "Cannot instantiate VectorType yet");
return QualType();
}
QualType
-TemplateTypeInstantiator::InstantiateExtVectorType(const ExtVectorType *T,
- unsigned Quals) const {
+TemplateTypeInstantiator::InstantiateExtVectorType(
+ const ExtVectorType *T) const {
// FIXME: Implement this
assert(false && "Cannot instantiate ExtVectorType yet");
return QualType();
@@ -479,8 +479,7 @@ TemplateTypeInstantiator::InstantiateExtVectorType(const ExtVectorType *T,
QualType
TemplateTypeInstantiator::
-InstantiateFunctionProtoType(const FunctionProtoType *T,
- unsigned Quals) const {
+InstantiateFunctionProtoType(const FunctionProtoType *T) const {
QualType ResultType = Instantiate(T->getResultType());
if (ResultType.isNull())
return ResultType;
@@ -504,15 +503,13 @@ InstantiateFunctionProtoType(const FunctionProtoType *T,
QualType
TemplateTypeInstantiator::
-InstantiateFunctionNoProtoType(const FunctionNoProtoType *T,
- unsigned Quals) const {
+InstantiateFunctionNoProtoType(const FunctionNoProtoType *T) const {
assert(false && "Functions without prototypes cannot be dependent.");
return QualType();
}
QualType
-TemplateTypeInstantiator::InstantiateTypedefType(const TypedefType *T,
- unsigned Quals) const {
+TemplateTypeInstantiator::InstantiateTypedefType(const TypedefType *T) const {
TypedefDecl *Typedef
= cast_or_null<TypedefDecl>(
SemaRef.InstantiateCurrentDeclRef(T->getDecl()));
@@ -523,8 +520,8 @@ TemplateTypeInstantiator::InstantiateTypedefType(const TypedefType *T,
}
QualType
-TemplateTypeInstantiator::InstantiateTypeOfExprType(const TypeOfExprType *T,
- unsigned Quals) const {
+TemplateTypeInstantiator::InstantiateTypeOfExprType(
+ const TypeOfExprType *T) const {
// The expression in a typeof is not potentially evaluated.
EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
@@ -537,8 +534,7 @@ TemplateTypeInstantiator::InstantiateTypeOfExprType(const TypeOfExprType *T,
}
QualType
-TemplateTypeInstantiator::InstantiateTypeOfType(const TypeOfType *T,
- unsigned Quals) const {
+TemplateTypeInstantiator::InstantiateTypeOfType(const TypeOfType *T) const {
QualType Underlying = Instantiate(T->getUnderlyingType());
if (Underlying.isNull())
return QualType();
@@ -546,9 +542,24 @@ TemplateTypeInstantiator::InstantiateTypeOfType(const TypeOfType *T,
return SemaRef.Context.getTypeOfType(Underlying);
}
+QualType
+TemplateTypeInstantiator::InstantiateDecltypeType(const DecltypeType *T) const {
+ // C++0x [dcl.type.simple]p4:
+ // The operand of the decltype specifier is an unevaluated operand.
+ EnterExpressionEvaluationContext Unevaluated(SemaRef,
+ Action::Unevaluated);
+
+ Sema::OwningExprResult E
+ = SemaRef.InstantiateExpr(T->getUnderlyingExpr(), TemplateArgs);
+
+ if (E.isInvalid())
+ return QualType();
+
+ return SemaRef.Context.getDecltypeType(E.takeAs<Expr>());
+}
+
QualType
-TemplateTypeInstantiator::InstantiateRecordType(const RecordType *T,
- unsigned Quals) const {
+TemplateTypeInstantiator::InstantiateRecordType(const RecordType *T) const {
RecordDecl *Record
= cast_or_null<RecordDecl>(SemaRef.InstantiateCurrentDeclRef(T->getDecl()));
if (!Record)
@@ -558,8 +569,7 @@ TemplateTypeInstantiator::InstantiateRecordType(const RecordType *T,
}
QualType
-TemplateTypeInstantiator::InstantiateEnumType(const EnumType *T,
- unsigned Quals) const {
+TemplateTypeInstantiator::InstantiateEnumType(const EnumType *T) const {
EnumDecl *Enum
= cast_or_null<EnumDecl>(SemaRef.InstantiateCurrentDeclRef(T->getDecl()));
if (!Enum)
@@ -570,26 +580,13 @@ TemplateTypeInstantiator::InstantiateEnumType(const EnumType *T,
QualType
TemplateTypeInstantiator::
-InstantiateTemplateTypeParmType(const TemplateTypeParmType *T,
- unsigned Quals) const {
+InstantiateTemplateTypeParmType(const TemplateTypeParmType *T) const {
if (T->getDepth() == 0) {
// Replace the template type parameter with its corresponding
// template argument.
assert(TemplateArgs[T->getIndex()].getKind() == TemplateArgument::Type &&
"Template argument kind mismatch");
- QualType Result = TemplateArgs[T->getIndex()].getAsType();
- if (Result.isNull() || !Quals)
- return Result;
-
- // C++ [dcl.ref]p1:
- // [...] Cv-qualified references are ill-formed except when
- // the cv-qualifiers are introduced through the use of a
- // typedef (7.1.3) or of a template type argument (14.3), in
- // which case the cv-qualifiers are ignored.
- if (Quals && Result->isReferenceType())
- Quals = 0;
-
- return QualType(Result.getTypePtr(), Quals | Result.getCVRQualifiers());
+ return TemplateArgs[T->getIndex()].getAsType();
}
// The template type parameter comes from an inner template (e.g.,
@@ -599,15 +596,13 @@ InstantiateTemplateTypeParmType(const TemplateTypeParmType *T,
return SemaRef.Context.getTemplateTypeParmType(T->getDepth() - 1,
T->getIndex(),
T->isParameterPack(),
- T->getName())
- .getQualifiedType(Quals);
+ T->getName());
}
QualType
TemplateTypeInstantiator::
InstantiateTemplateSpecializationType(
- const TemplateSpecializationType *T,
- unsigned Quals) const {
+ const TemplateSpecializationType *T) const {
llvm::SmallVector<TemplateArgument, 4> InstantiatedTemplateArgs;
InstantiatedTemplateArgs.reserve(T->getNumArgs());
for (TemplateSpecializationType::iterator Arg = T->begin(), ArgEnd = T->end();
@@ -633,8 +628,7 @@ InstantiateTemplateSpecializationType(
QualType
TemplateTypeInstantiator::
-InstantiateQualifiedNameType(const QualifiedNameType *T,
- unsigned Quals) const {
+InstantiateQualifiedNameType(const QualifiedNameType *T) const {
// When we instantiated a qualified name type, there's no point in
// keeping the qualification around in the instantiated result. So,
// just instantiate the named type.
@@ -643,14 +637,14 @@ InstantiateQualifiedNameType(const QualifiedNameType *T,
QualType
TemplateTypeInstantiator::
-InstantiateTypenameType(const TypenameType *T, unsigned Quals) const {
+InstantiateTypenameType(const TypenameType *T) const {
if (const TemplateSpecializationType *TemplateId = T->getTemplateId()) {
// When the typename type refers to a template-id, the template-id
// is dependent and has enough information to instantiate the
// result of the typename type. Since we don't care about keeping
// the spelling of the typename type in template instantiations,
// we just instantiate the template-id.
- return InstantiateTemplateSpecializationType(TemplateId, Quals);
+ return InstantiateTemplateSpecializationType(TemplateId);
}
NestedNameSpecifier *NNS
@@ -665,24 +659,22 @@ InstantiateTypenameType(const TypenameType *T, unsigned Quals) const {
QualType
TemplateTypeInstantiator::
-InstantiateObjCObjectPointerType(const ObjCObjectPointerType *T,
- unsigned Quals) const {
+InstantiateObjCObjectPointerType(const ObjCObjectPointerType *T) const {
assert(false && "Objective-C types cannot be dependent");
return QualType();
}
QualType
TemplateTypeInstantiator::
-InstantiateObjCInterfaceType(const ObjCInterfaceType *T,
- unsigned Quals) const {
+InstantiateObjCInterfaceType(const ObjCInterfaceType *T) const {
assert(false && "Objective-C types cannot be dependent");
return QualType();
}
QualType
TemplateTypeInstantiator::
-InstantiateObjCQualifiedInterfaceType(const ObjCQualifiedInterfaceType *T,
- unsigned Quals) const {
+InstantiateObjCQualifiedInterfaceType(
+ const ObjCQualifiedInterfaceType *T) const {
assert(false && "Objective-C types cannot be dependent");
return QualType();
}
@@ -693,17 +685,27 @@ QualType TemplateTypeInstantiator::Instantiate(QualType T) const {
if (!T->isDependentType())
return T;
+ QualType Result;
switch (T->getTypeClass()) {
#define TYPE(Class, Base) \
case Type::Class: \
- return Instantiate##Class##Type(cast<Class##Type>(T.getTypePtr()), \
- T.getCVRQualifiers());
+ Result = Instantiate##Class##Type(cast<Class##Type>(T.getTypePtr())); \
+ break;
#define ABSTRACT_TYPE(Class, Base)
#include "clang/AST/TypeNodes.def"
}
-
- assert(false && "Not all types have been decoded for instantiation");
- return QualType();
+
+ // C++ [dcl.ref]p1:
+ // [...] Cv-qualified references are ill-formed except when
+ // the cv-qualifiers are introduced through the use of a
+ // typedef (7.1.3) or of a template type argument (14.3), in
+ // which case the cv-qualifiers are ignored.
+ //
+ // The same rule applies to function types.
+ if (!Result.isNull() && T.getCVRQualifiers() &&
+ !Result->isFunctionType() && !Result->isReferenceType())
+ Result = Result.getWithAdditionalQualifiers(T.getCVRQualifiers());
+ return Result;
}
/// \brief Instantiate the type T with a given set of template arguments.
OpenPOWER on IntegriCloud