[cfe-commits] r100871 - in /cfe/trunk: lib/Sema/Sema.h lib/Sema/SemaTemplateInstantiate.cpp lib/Sema/SemaTemplateInstantiateDecl.cpp test/CXX/temp/temp.spec/temp.inst/p11.cpp

John McCall rjmccall at apple.com
Fri Apr 9 10:38:44 PDT 2010


Author: rjmccall
Date: Fri Apr  9 12:38:44 2010
New Revision: 100871

URL: http://llvm.org/viewvc/llvm-project?rev=100871&view=rev
Log:
Instantiate default argument expressions even if their associated parameter
type isn't dependent.  Fixes rdar://problem/7838962.


Added:
    cfe/trunk/test/CXX/temp/temp.spec/temp.inst/p11.cpp
Modified:
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
    cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp

Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=100871&r1=100870&r2=100871&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Fri Apr  9 12:38:44 2010
@@ -3638,6 +3638,11 @@
                      const MultiLevelTemplateArgumentList &TemplateArgs,
                      SourceLocation Loc, DeclarationName Entity);
 
+  TypeSourceInfo *SubstFunctionDeclType(TypeSourceInfo *T,
+                            const MultiLevelTemplateArgumentList &TemplateArgs,
+                                        SourceLocation Loc,
+                                        DeclarationName Entity);
+
   OwningExprResult SubstExpr(Expr *E,
                             const MultiLevelTemplateArgumentList &TemplateArgs);
 

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp?rev=100871&r1=100870&r2=100871&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp Fri Apr  9 12:38:44 2010
@@ -959,6 +959,56 @@
   return Instantiator.TransformType(T);
 }
 
+static bool NeedsInstantiationAsFunctionType(TypeSourceInfo *T) {
+  if (T->getType()->isDependentType())
+    return true;
+
+  TypeLoc TL = T->getTypeLoc();
+  if (!isa<FunctionProtoTypeLoc>(TL))
+    return false;
+
+  FunctionProtoTypeLoc FP = cast<FunctionProtoTypeLoc>(TL);
+  for (unsigned I = 0, E = FP.getNumArgs(); I != E; ++I) {
+    ParmVarDecl *P = FP.getArg(I);
+
+    // TODO: currently we always rebuild expressions.  When we
+    // properly get lazier about this, we should use the same
+    // logic to avoid rebuilding prototypes here.
+    if (P->hasInit())
+      return true;
+  }
+
+  return false;
+}
+
+/// A form of SubstType intended specifically for instantiating the
+/// type of a FunctionDecl.  Its purpose is solely to force the
+/// instantiation of default-argument expressions.
+TypeSourceInfo *Sema::SubstFunctionDeclType(TypeSourceInfo *T,
+                                const MultiLevelTemplateArgumentList &Args,
+                                SourceLocation Loc,
+                                DeclarationName Entity) {
+  assert(!ActiveTemplateInstantiations.empty() &&
+         "Cannot perform an instantiation without some context on the "
+         "instantiation stack");
+  
+  if (!NeedsInstantiationAsFunctionType(T))
+    return T;
+
+  TemplateInstantiator Instantiator(*this, Args, Loc, Entity);
+
+  TypeLocBuilder TLB;
+
+  TypeLoc TL = T->getTypeLoc();
+  TLB.reserve(TL.getFullDataSize());
+
+  QualType Result = Instantiator.TransformType(TLB, TL, QualType());
+  if (Result.isNull())
+    return 0;
+
+  return TLB.getTypeSourceInfo(Context, Result);
+}
+
 /// \brief Perform substitution on the base class specifiers of the
 /// given class template specialization.
 ///

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=100871&r1=100870&r2=100871&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Fri Apr  9 12:38:44 2010
@@ -1826,9 +1826,10 @@
   TypeSourceInfo *OldTInfo = D->getTypeSourceInfo();
   assert(OldTInfo && "substituting function without type source info");
   assert(Params.empty() && "parameter vector is non-empty at start");
-  TypeSourceInfo *NewTInfo = SemaRef.SubstType(OldTInfo, TemplateArgs,
-                                               D->getTypeSpecStartLoc(),
-                                               D->getDeclName());
+  TypeSourceInfo *NewTInfo
+    = SemaRef.SubstFunctionDeclType(OldTInfo, TemplateArgs,
+                                    D->getTypeSpecStartLoc(),
+                                    D->getDeclName());
   if (!NewTInfo)
     return 0;
 

Added: cfe/trunk/test/CXX/temp/temp.spec/temp.inst/p11.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.spec/temp.inst/p11.cpp?rev=100871&view=auto
==============================================================================
--- cfe/trunk/test/CXX/temp/temp.spec/temp.inst/p11.cpp (added)
+++ cfe/trunk/test/CXX/temp/temp.spec/temp.inst/p11.cpp Fri Apr  9 12:38:44 2010
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -verify -emit-llvm-only %s
+
+// rdar://problem/7838962
+namespace test0 {
+  template<typename T> unsigned f0() {
+    return T::MaxSize; // expected-error {{'int' cannot be used prior to '::'}}
+  };
+  template<typename T> class A {
+    void Allocate(unsigned Alignment
+                    = f0<T>()) // expected-note {{in instantiation}}
+    {}
+  };
+  void f1(A<int> x) { x.Allocate(); }
+  
+}





More information about the cfe-commits mailing list