[cfe-commits] r65668 - in /cfe/trunk: lib/Sema/Sema.h lib/Sema/SemaTemplateInstantiate.cpp lib/Sema/SemaType.cpp test/SemaTemplate/instantiation-default-1.cpp
Douglas Gregor
dgregor at apple.com
Fri Feb 27 17:04:19 PST 2009
Author: dgregor
Date: Fri Feb 27 19:04:19 2009
New Revision: 65668
URL: http://llvm.org/viewvc/llvm-project?rev=65668&view=rev
Log:
Template instantiation for function types
Modified:
cfe/trunk/lib/Sema/Sema.h
cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
cfe/trunk/lib/Sema/SemaType.cpp
cfe/trunk/test/SemaTemplate/instantiation-default-1.cpp
Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=65668&r1=65667&r2=65668&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Fri Feb 27 19:04:19 2009
@@ -239,6 +239,10 @@
QualType BuildArrayType(QualType T, ArrayType::ArraySizeModifier ASM,
Expr *ArraySize, unsigned Quals,
SourceLocation Loc, DeclarationName Entity);
+ QualType BuildFunctionType(QualType T,
+ QualType *ParamTypes, unsigned NumParamTypes,
+ bool Variadic, unsigned Quals,
+ SourceLocation Loc, DeclarationName Entity);
QualType GetTypeForDeclarator(Declarator &D, Scope *S, unsigned Skip = 0);
DeclarationName GetNameForDeclarator(Declarator &D);
Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp?rev=65668&r1=65667&r2=65668&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp Fri Feb 27 19:04:19 2009
@@ -65,7 +65,7 @@
QualType
TemplateTypeInstantiator::InstantiateBuiltinType(const BuiltinType *T,
unsigned Quals) const {
- assert(false && "BuiltinType is never dependent and cannot be instantiated");
+ assert(false && "Builtin types are not dependent and cannot be instantiated");
return QualType(T, Quals);
}
@@ -191,17 +191,32 @@
TemplateTypeInstantiator::
InstantiateFunctionProtoType(const FunctionProtoType *T,
unsigned Quals) const {
- // FIXME: Implement this
- assert(false && "Cannot instantiate FunctionProtoType yet");
- return QualType();
+ QualType ResultType = Instantiate(T->getResultType());
+ if (ResultType.isNull())
+ return ResultType;
+
+ llvm::SmallVector<QualType, 16> ParamTypes;
+ for (FunctionProtoType::arg_type_iterator Param = T->arg_type_begin(),
+ ParamEnd = T->arg_type_end();
+ Param != ParamEnd; ++Param) {
+ QualType P = Instantiate(*Param);
+ if (P.isNull())
+ return P;
+
+ ParamTypes.push_back(P);
+ }
+
+ return SemaRef.BuildFunctionType(ResultType, &ParamTypes[0],
+ ParamTypes.size(),
+ T->isVariadic(), T->getTypeQuals(),
+ Loc, Entity);
}
QualType
TemplateTypeInstantiator::
InstantiateFunctionNoProtoType(const FunctionNoProtoType *T,
unsigned Quals) const {
- // FIXME: Implement this
- assert(false && "Cannot instantiate FunctionNoProtoType yet");
+ assert(false && "Functions without prototypes cannot be dependent.");
return QualType();
}
Modified: cfe/trunk/lib/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=65668&r1=65667&r2=65668&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaType.cpp (original)
+++ cfe/trunk/lib/Sema/SemaType.cpp Fri Feb 27 19:04:19 2009
@@ -468,7 +468,67 @@
return T;
}
+/// \brief Build a function type.
+///
+/// This routine checks the function type according to C++ rules and
+/// under the assumption that the result type and parameter types have
+/// just been instantiated from a template. It therefore duplicates
+/// some of the behavior of GetTypeForDeclaration, but in a much
+/// simpler form that is only suitable for this narrow use case.
+///
+/// \param T The return type of the function.
+///
+/// \param ParamTypes The parameter types of the function. This array
+/// will be modified to account for adjustments to the types of the
+/// function parameters.
+///
+/// \param NumParamTypes The number of parameter types in ParamTypes.
+///
+/// \param Variadic Whether this is a variadic function type.
+///
+/// \param Quals The cvr-qualifiers to be applied to the function type.
+///
+/// \param Loc The location of the entity whose type involves this
+/// function type or, if there is no such entity, the location of the
+/// type that will have function type.
+///
+/// \param Entity The name of the entity that involves the function
+/// type, if known.
+///
+/// \returns A suitable function type, if there are no
+/// errors. Otherwise, returns a NULL type.
+QualType Sema::BuildFunctionType(QualType T,
+ QualType *ParamTypes,
+ unsigned NumParamTypes,
+ bool Variadic, unsigned Quals,
+ SourceLocation Loc, DeclarationName Entity) {
+ if (T->isArrayType() || T->isFunctionType()) {
+ Diag(Loc, diag::err_func_returning_array_function) << T;
+ return QualType();
+ }
+
+ bool Invalid = false;
+ for (unsigned Idx = 0; Idx < NumParamTypes; ++Idx) {
+ QualType ParamType = ParamTypes[Idx];
+ if (ParamType->isArrayType())
+ ParamType = Context.getArrayDecayedType(ParamType);
+ else if (ParamType->isFunctionType())
+ ParamType = Context.getPointerType(ParamType);
+ else if (ParamType->isVoidType()) {
+ Diag(Loc, diag::err_param_with_void_type);
+ Invalid = true;
+ }
+ ParamTypes[Idx] = ParamType;
+ }
+
+ if (Invalid)
+ return QualType();
+
+ return Context.getFunctionType(T, ParamTypes, NumParamTypes, Variadic,
+ Quals);
+}
+
/// GetTypeForDeclarator - Convert the type for the specified
/// declarator to Type instances. Skip the outermost Skip type
/// objects.
Modified: cfe/trunk/test/SemaTemplate/instantiation-default-1.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/instantiation-default-1.cpp?rev=65668&r1=65667&r2=65668&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/instantiation-default-1.cpp (original)
+++ cfe/trunk/test/SemaTemplate/instantiation-default-1.cpp Fri Feb 27 19:04:19 2009
@@ -78,3 +78,24 @@
d5b->bar();
}
+template<typename R, typename Arg1, typename Arg2 = Arg1,
+ typename FuncType = R (*)(Arg1, Arg2)>
+ struct Def6;
+
+template<> struct Def6<int, float> {
+ void foo();
+};
+
+template<> struct Def6<bool, int[5], float(double, double)> {
+ void bar();
+};
+
+bool test_Def6(Def6<int, float, float> *d6a,
+ Def6<int, float, float, int (*)(float, float)> *d6b,
+ Def6<bool, int[5], float(double, double),
+ bool(*)(int*, float(*)(double, double))> *d6c) {
+ d6a->foo();
+ d6b->foo();
+ d6c->bar();
+ return d6a == d6b;
+}
More information about the cfe-commits
mailing list