[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