[cfe-commits] r150241 - in /cfe/trunk: include/clang/AST/Type.h include/clang/Sema/Sema.h lib/AST/ASTContext.cpp lib/AST/Type.cpp lib/AST/TypePrinter.cpp lib/Sema/SemaLambda.cpp lib/Sema/SemaTemplateDeduction.cpp lib/Sema/SemaType.cpp lib/Sema/TreeTransform.h lib/Serialization/ASTReader.cpp lib/Serialization/ASTWriter.cpp test/PCH/cxx-trailing-return.cpp test/SemaCXX/trailing-return-0x.cpp test/SemaTemplate/instantiation-order.cpp

Richard Smith richard-llvm at metafoo.co.uk
Fri Feb 10 01:58:53 PST 2012


Author: rsmith
Date: Fri Feb 10 03:58:53 2012
New Revision: 150241

URL: http://llvm.org/viewvc/llvm-project?rev=150241&view=rev
Log:
Track whether a function type has a trailing return type as type sugar. Use this
to pretty-print such function types better, and to fix a case where we were not
instantiating templates in lexical order. In passing, move the Variadic bit from
Type's bitfields to FunctionProtoType to get the Type bitfields down to 32 bits.
Also ensure that we always substitute the return type of a function when
substituting explicitly-specified arguments, since that can cause us to bail
out with a SFINAE error before we hit a hard error in parameter substitution.

Added:
    cfe/trunk/test/PCH/cxx-trailing-return.cpp
    cfe/trunk/test/SemaTemplate/instantiation-order.cpp
Modified:
    cfe/trunk/include/clang/AST/Type.h
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/AST/ASTContext.cpp
    cfe/trunk/lib/AST/Type.cpp
    cfe/trunk/lib/AST/TypePrinter.cpp
    cfe/trunk/lib/Sema/SemaLambda.cpp
    cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
    cfe/trunk/lib/Sema/SemaType.cpp
    cfe/trunk/lib/Sema/TreeTransform.h
    cfe/trunk/lib/Serialization/ASTReader.cpp
    cfe/trunk/lib/Serialization/ASTWriter.cpp
    cfe/trunk/test/SemaCXX/trailing-return-0x.cpp

Modified: cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=150241&r1=150240&r2=150241&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Fri Feb 10 03:58:53 2012
@@ -1197,9 +1197,6 @@
     /// regparm and the calling convention.
     unsigned ExtInfo : 8;
 
-    /// Whether the function is variadic.  Only used by FunctionProtoType.
-    unsigned Variadic : 1;
-
     /// TypeQuals - Used only by FunctionProtoType, put here to pack with the
     /// other bitfields.
     /// The qualifiers are part of FunctionProtoType because...
@@ -2615,7 +2612,7 @@
   };
 
 protected:
-  FunctionType(TypeClass tc, QualType res, bool variadic,
+  FunctionType(TypeClass tc, QualType res,
                unsigned typeQuals, RefQualifierKind RefQualifier,
                QualType Canonical, bool Dependent,
                bool InstantiationDependent,
@@ -2625,11 +2622,9 @@
            ContainsUnexpandedParameterPack),
       ResultType(res) {
     FunctionTypeBits.ExtInfo = Info.Bits;
-    FunctionTypeBits.Variadic = variadic;
     FunctionTypeBits.TypeQuals = typeQuals;
     FunctionTypeBits.RefQualifier = static_cast<unsigned>(RefQualifier);
   }
-  bool isVariadic() const { return FunctionTypeBits.Variadic; }
   unsigned getTypeQuals() const { return FunctionTypeBits.TypeQuals; }
 
   RefQualifierKind getRefQualifier() const {
@@ -2665,7 +2660,7 @@
 /// no information available about its arguments.
 class FunctionNoProtoType : public FunctionType, public llvm::FoldingSetNode {
   FunctionNoProtoType(QualType Result, QualType Canonical, ExtInfo Info)
-    : FunctionType(FunctionNoProto, Result, false, 0, RQ_None, Canonical,
+    : FunctionType(FunctionNoProto, Result, 0, RQ_None, Canonical,
                    /*Dependent=*/false, /*InstantiationDependent=*/false,
                    Result->isVariablyModifiedType(),
                    /*ContainsUnexpandedParameterPack=*/false, Info) {}
@@ -2703,12 +2698,13 @@
   /// ExtProtoInfo - Extra information about a function prototype.
   struct ExtProtoInfo {
     ExtProtoInfo() :
-      Variadic(false), ExceptionSpecType(EST_None), TypeQuals(0),
-      RefQualifier(RQ_None), NumExceptions(0), Exceptions(0), NoexceptExpr(0),
-      ConsumedArguments(0) {}
+      Variadic(false), HasTrailingReturn(false), ExceptionSpecType(EST_None),
+      TypeQuals(0), RefQualifier(RQ_None), NumExceptions(0), Exceptions(0),
+      NoexceptExpr(0), ConsumedArguments(0) {}
 
     FunctionType::ExtInfo ExtInfo;
     bool Variadic;
+    bool HasTrailingReturn;
     ExceptionSpecificationType ExceptionSpecType;
     unsigned char TypeQuals;
     RefQualifierKind RefQualifier;
@@ -2734,7 +2730,7 @@
                     QualType canonical, const ExtProtoInfo &epi);
 
   /// NumArgs - The number of arguments this function has, not counting '...'.
-  unsigned NumArgs : 19;
+  unsigned NumArgs : 17;
 
   /// NumExceptions - The number of types in the exception spec, if any.
   unsigned NumExceptions : 9;
@@ -2745,6 +2741,12 @@
   /// HasAnyConsumedArgs - Whether this function has any consumed arguments.
   unsigned HasAnyConsumedArgs : 1;
 
+  /// Variadic - Whether the function is variadic.
+  unsigned Variadic : 1;
+
+  /// HasTrailingReturn - Whether this function has a trailing return type.
+  unsigned HasTrailingReturn : 1;
+
   // ArgInfo - There is an variable size array after the class in memory that
   // holds the argument types.
 
@@ -2784,6 +2786,7 @@
     ExtProtoInfo EPI;
     EPI.ExtInfo = getExtInfo();
     EPI.Variadic = isVariadic();
+    EPI.HasTrailingReturn = hasTrailingReturn();
     EPI.ExceptionSpecType = getExceptionSpecType();
     EPI.TypeQuals = static_cast<unsigned char>(getTypeQuals());
     EPI.RefQualifier = getRefQualifier();
@@ -2845,16 +2848,18 @@
     return getNoexceptSpec(Ctx) == NR_Nothrow;
   }
 
-  using FunctionType::isVariadic;
+  bool isVariadic() const { return Variadic; }
 
   /// \brief Determines whether this function prototype contains a
   /// parameter pack at the end.
   ///
   /// A function template whose last parameter is a parameter pack can be
   /// called with an arbitrary number of arguments, much like a variadic
-  /// function. However,
+  /// function.
   bool isTemplateVariadic() const;
 
+  bool hasTrailingReturn() const { return HasTrailingReturn; }
+
   unsigned getTypeQuals() const { return FunctionType::getTypeQuals(); }
 
 

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=150241&r1=150240&r2=150241&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Fri Feb 10 03:58:53 2012
@@ -775,8 +775,8 @@
                               SourceLocation AttrLoc);
   QualType BuildFunctionType(QualType T,
                              QualType *ParamTypes, unsigned NumParamTypes,
-                             bool Variadic, unsigned Quals,
-                             RefQualifierKind RefQualifier,
+                             bool Variadic, bool HasTrailingReturn,
+                             unsigned Quals, RefQualifierKind RefQualifier,
                              SourceLocation Loc, DeclarationName Entity,
                              FunctionType::ExtInfo Info);
   QualType BuildMemberPointerType(QualType T, QualType Class,

Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=150241&r1=150240&r2=150241&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Fri Feb 10 03:58:53 2012
@@ -2132,7 +2132,9 @@
     return QualType(FTP, 0);
 
   // Determine whether the type being created is already canonical or not.
-  bool isCanonical= EPI.ExceptionSpecType == EST_None && ResultTy.isCanonical();
+  bool isCanonical =
+    EPI.ExceptionSpecType == EST_None && ResultTy.isCanonical() &&
+    !EPI.HasTrailingReturn;
   for (unsigned i = 0; i != NumArgs && isCanonical; ++i)
     if (!ArgArray[i].isCanonicalAsParam())
       isCanonical = false;
@@ -2151,6 +2153,7 @@
       CanonicalArgs.push_back(getCanonicalParamType(ArgArray[i]));
 
     FunctionProtoType::ExtProtoInfo CanonicalEPI = EPI;
+    CanonicalEPI.HasTrailingReturn = false;
     CanonicalEPI.ExceptionSpecType = EST_None;
     CanonicalEPI.NumExceptions = 0;
     CanonicalEPI.ExtInfo

Modified: cfe/trunk/lib/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=150241&r1=150240&r2=150241&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Type.cpp (original)
+++ cfe/trunk/lib/AST/Type.cpp Fri Feb 10 03:58:53 2012
@@ -1557,8 +1557,8 @@
 FunctionProtoType::FunctionProtoType(QualType result, const QualType *args,
                                      unsigned numArgs, QualType canonical,
                                      const ExtProtoInfo &epi)
-  : FunctionType(FunctionProto, result, epi.Variadic, epi.TypeQuals, 
-                 epi.RefQualifier, canonical,
+  : FunctionType(FunctionProto, result, epi.TypeQuals, epi.RefQualifier,
+                 canonical,
                  result->isDependentType(),
                  result->isInstantiationDependentType(),
                  result->isVariablyModifiedType(),
@@ -1566,7 +1566,8 @@
                  epi.ExtInfo),
     NumArgs(numArgs), NumExceptions(epi.NumExceptions),
     ExceptionSpecType(epi.ExceptionSpecType),
-    HasAnyConsumedArgs(epi.ConsumedArguments != 0)
+    HasAnyConsumedArgs(epi.ConsumedArguments != 0),
+    Variadic(epi.Variadic), HasTrailingReturn(epi.HasTrailingReturn)
 {
   // Fill in the trailing argument array.
   QualType *argSlot = reinterpret_cast<QualType*>(this+1);
@@ -1664,8 +1665,8 @@
   // This is followed by an optional "consumed argument" section of the
   // same length as the first type sequence:
   //      bool*
-  // Finally, we have the ext info:
-  //      int
+  // Finally, we have the ext info and trailing return type flag:
+  //      int bool
   // 
   // There is no ambiguity between the consumed arguments and an empty EH
   // spec because of the leading 'bool' which unambiguously indicates
@@ -1697,6 +1698,7 @@
       ID.AddBoolean(epi.ConsumedArguments[i]);
   }
   epi.ExtInfo.Profile(ID);
+  ID.AddBoolean(epi.HasTrailingReturn);
 }
 
 void FunctionProtoType::Profile(llvm::FoldingSetNodeID &ID,

Modified: cfe/trunk/lib/AST/TypePrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/TypePrinter.cpp?rev=150241&r1=150240&r2=150241&view=diff
==============================================================================
--- cfe/trunk/lib/AST/TypePrinter.cpp (original)
+++ cfe/trunk/lib/AST/TypePrinter.cpp Fri Feb 10 03:58:53 2012
@@ -500,7 +500,12 @@
     break;
   }
   T->printExceptionSpecification(S, Policy);
-  print(T->getResultType(), S);
+  if (T->hasTrailingReturn()) {
+    std::string ResultS;
+    print(T->getResultType(), ResultS);
+    S = "auto " + S + " -> " + ResultS;
+  } else
+    print(T->getResultType(), S);
 }
 
 void TypePrinter::printFunctionNoProto(const FunctionNoProtoType *T, 

Modified: cfe/trunk/lib/Sema/SemaLambda.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLambda.cpp?rev=150241&r1=150240&r2=150241&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaLambda.cpp (original)
+++ cfe/trunk/lib/Sema/SemaLambda.cpp Fri Feb 10 03:58:53 2012
@@ -46,6 +46,7 @@
     //   If a lambda-expression does not include a lambda-declarator, it is as 
     //   if the lambda-declarator were ().
     FunctionProtoType::ExtProtoInfo EPI;
+    EPI.HasTrailingReturn = true;
     EPI.TypeQuals |= DeclSpec::TQ_const;
     MethodTy = Context.getFunctionType(Context.DependentTy,
                                        /*Args=*/0, /*NumArgs=*/0, EPI);

Modified: cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp?rev=150241&r1=150240&r2=150241&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp Fri Feb 10 03:58:53 2012
@@ -2291,33 +2291,45 @@
     }
   }
 
+  const FunctionProtoType *Proto
+    = Function->getType()->getAs<FunctionProtoType>();
+  assert(Proto && "Function template does not have a prototype?");
+
   // Instantiate the types of each of the function parameters given the
-  // explicitly-specified template arguments.
-  if (SubstParmTypes(Function->getLocation(),
+  // explicitly-specified template arguments. If the function has a trailing
+  // return type, substitute it after the arguments to ensure we substitute
+  // in lexical order.
+  if (Proto->hasTrailingReturn() &&
+      SubstParmTypes(Function->getLocation(),
                      Function->param_begin(), Function->getNumParams(),
                      MultiLevelTemplateArgumentList(*ExplicitArgumentList),
                      ParamTypes))
     return TDK_SubstitutionFailure;
 
-  // If the caller wants a full function type back, instantiate the return
-  // type and form that function type.
-  if (FunctionType) {
-    // FIXME: exception-specifications?
-    const FunctionProtoType *Proto
-      = Function->getType()->getAs<FunctionProtoType>();
-    assert(Proto && "Function template does not have a prototype?");
+  // Instantiate the return type.
+  // FIXME: exception-specifications?
+  QualType ResultType
+    = SubstType(Proto->getResultType(),
+                MultiLevelTemplateArgumentList(*ExplicitArgumentList),
+                Function->getTypeSpecStartLoc(),
+                Function->getDeclName());
+  if (ResultType.isNull() || Trap.hasErrorOccurred())
+    return TDK_SubstitutionFailure;
 
-    QualType ResultType
-      = SubstType(Proto->getResultType(),
-                  MultiLevelTemplateArgumentList(*ExplicitArgumentList),
-                  Function->getTypeSpecStartLoc(),
-                  Function->getDeclName());
-    if (ResultType.isNull() || Trap.hasErrorOccurred())
-      return TDK_SubstitutionFailure;
+  // Instantiate the types of each of the function parameters given the
+  // explicitly-specified template arguments if we didn't do so earlier.
+  if (!Proto->hasTrailingReturn() &&
+      SubstParmTypes(Function->getLocation(),
+                     Function->param_begin(), Function->getNumParams(),
+                     MultiLevelTemplateArgumentList(*ExplicitArgumentList),
+                     ParamTypes))
+    return TDK_SubstitutionFailure;
 
+  if (FunctionType) {
     *FunctionType = BuildFunctionType(ResultType,
                                       ParamTypes.data(), ParamTypes.size(),
                                       Proto->isVariadic(),
+                                      Proto->hasTrailingReturn(),
                                       Proto->getTypeQuals(),
                                       Proto->getRefQualifier(),
                                       Function->getLocation(),

Modified: cfe/trunk/lib/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=150241&r1=150240&r2=150241&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaType.cpp (original)
+++ cfe/trunk/lib/Sema/SemaType.cpp Fri Feb 10 03:58:53 2012
@@ -1434,6 +1434,8 @@
 ///
 /// \param Variadic Whether this is a variadic function type.
 ///
+/// \param HasTrailingReturn Whether this function has a trailing return type.
+///
 /// \param Quals The cvr-qualifiers to be applied to the function type.
 ///
 /// \param Loc The location of the entity whose type involves this
@@ -1448,7 +1450,8 @@
 QualType Sema::BuildFunctionType(QualType T,
                                  QualType *ParamTypes,
                                  unsigned NumParamTypes,
-                                 bool Variadic, unsigned Quals,
+                                 bool Variadic, bool HasTrailingReturn,
+                                 unsigned Quals,
                                  RefQualifierKind RefQualifier,
                                  SourceLocation Loc, DeclarationName Entity,
                                  FunctionType::ExtInfo Info) {
@@ -1487,6 +1490,7 @@
 
   FunctionProtoType::ExtProtoInfo EPI;
   EPI.Variadic = Variadic;
+  EPI.HasTrailingReturn = HasTrailingReturn;
   EPI.TypeQuals = Quals;
   EPI.RefQualifier = RefQualifier;
   EPI.ExtInfo = Info;
@@ -1498,7 +1502,6 @@
 ///
 /// \param T the type to which the member pointer refers.
 /// \param Class the class type into which the member pointer points.
-/// \param CVR Qualifiers applied to the member pointer type
 /// \param Loc the location where this type begins
 /// \param Entity the name of the entity that will have this member pointer type
 ///
@@ -2185,6 +2188,7 @@
 
         FunctionProtoType::ExtProtoInfo EPI;
         EPI.Variadic = FTI.isVariadic;
+        EPI.HasTrailingReturn = FTI.TrailingReturnType;
         EPI.TypeQuals = FTI.TypeQuals;
         EPI.RefQualifier = !FTI.hasRefQualifier()? RQ_None
                     : FTI.RefQualifierIsLValueRef? RQ_LValue

Modified: cfe/trunk/lib/Sema/TreeTransform.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=150241&r1=150240&r2=150241&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/TreeTransform.h (original)
+++ cfe/trunk/lib/Sema/TreeTransform.h Fri Feb 10 03:58:53 2012
@@ -666,7 +666,8 @@
   QualType RebuildFunctionProtoType(QualType T,
                                     QualType *ParamTypes,
                                     unsigned NumParamTypes,
-                                    bool Variadic, unsigned Quals,
+                                    bool Variadic, bool HasTrailingReturn,
+                                    unsigned Quals,
                                     RefQualifierKind RefQualifier,
                                     const FunctionType::ExtInfo &Info);
 
@@ -4137,6 +4138,7 @@
                                                    ParamTypes.data(),
                                                    ParamTypes.size(),
                                                    T->isVariadic(),
+                                                   T->hasTrailingReturn(),
                                                    T->getTypeQuals(),
                                                    T->getRefQualifier(),
                                                    T->getExtInfo());
@@ -8209,7 +8211,7 @@
                                                         paramTypes.data(),
                                                         paramTypes.size(),
                                                         oldBlock->isVariadic(),
-                                                        0, RQ_None,
+                                                        false, 0, RQ_None,
                                                exprFunctionType->getExtInfo());
   blockScope->FunctionType = functionType;
 
@@ -8452,11 +8454,12 @@
                                                           QualType *ParamTypes,
                                                         unsigned NumParamTypes,
                                                           bool Variadic,
+                                                         bool HasTrailingReturn,
                                                           unsigned Quals,
                                                   RefQualifierKind RefQualifier,
                                             const FunctionType::ExtInfo &Info) {
   return SemaRef.BuildFunctionType(T, ParamTypes, NumParamTypes, Variadic,
-                                   Quals, RefQualifier,
+                                   HasTrailingReturn, Quals, RefQualifier,
                                    getDerived().getBaseLocation(),
                                    getDerived().getBaseEntity(),
                                    Info);

Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=150241&r1=150240&r2=150241&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Fri Feb 10 03:58:53 2012
@@ -3878,6 +3878,7 @@
       ParamTypes.push_back(readType(*Loc.F, Record, Idx));
 
     EPI.Variadic = Record[Idx++];
+    EPI.HasTrailingReturn = Record[Idx++];
     EPI.TypeQuals = Record[Idx++];
     EPI.RefQualifier = static_cast<RefQualifierKind>(Record[Idx++]);
     ExceptionSpecificationType EST =

Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=150241&r1=150240&r2=150241&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriter.cpp Fri Feb 10 03:58:53 2012
@@ -185,6 +185,7 @@
   for (unsigned I = 0, N = T->getNumArgs(); I != N; ++I)
     Writer.AddTypeRef(T->getArgType(I), Record);
   Record.push_back(T->isVariadic());
+  Record.push_back(T->hasTrailingReturn());
   Record.push_back(T->getTypeQuals());
   Record.push_back(static_cast<unsigned>(T->getRefQualifier()));
   Record.push_back(T->getExceptionSpecType());
@@ -4500,4 +4501,3 @@
 
   RewriteDecl(D);
 }
-

Added: cfe/trunk/test/PCH/cxx-trailing-return.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/cxx-trailing-return.cpp?rev=150241&view=auto
==============================================================================
--- cfe/trunk/test/PCH/cxx-trailing-return.cpp (added)
+++ cfe/trunk/test/PCH/cxx-trailing-return.cpp Fri Feb 10 03:58:53 2012
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -pedantic-errors -std=c++11 -emit-pch %s -o %t-cxx11
+// RUN: %clang_cc1 -pedantic-errors -std=c++11 -include-pch %t-cxx11 -verify %s
+
+#ifndef HEADER_INCLUDED
+
+#define HEADER_INCLUDED
+typedef auto f() -> int; // expected-note {{here}}
+typedef int g(); // expected-note {{here}}
+
+#else
+
+typedef void f; // expected-error {{typedef redefinition with different types ('void' vs 'auto () -> int')}}
+typedef void g; // expected-error {{typedef redefinition with different types ('void' vs 'int ()')}}
+
+#endif

Modified: cfe/trunk/test/SemaCXX/trailing-return-0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/trailing-return-0x.cpp?rev=150241&r1=150240&r2=150241&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/trailing-return-0x.cpp (original)
+++ cfe/trunk/test/SemaCXX/trailing-return-0x.cpp Fri Feb 10 03:58:53 2012
@@ -21,6 +21,16 @@
 
 int h() -> int; // expected-error{{trailing return type must specify return type 'auto', not 'int'}}
 
+int i();
+auto i() -> int;
+int i() {}
+
+using T = auto (int) -> auto (*)(char) -> void; // expected-note {{previous}}
+using T = void; // expected-error {{type alias redefinition with different types ('void' vs 'auto (int) -> auto (*)(char) -> void')}}
+
+using U = auto (int) -> auto (*)(char) -> void;
+using U = void (*(int))(char); // ok
+
 int x;
 
 template <class T>

Added: cfe/trunk/test/SemaTemplate/instantiation-order.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/instantiation-order.cpp?rev=150241&view=auto
==============================================================================
--- cfe/trunk/test/SemaTemplate/instantiation-order.cpp (added)
+++ cfe/trunk/test/SemaTemplate/instantiation-order.cpp Fri Feb 10 03:58:53 2012
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -std=c++11 -verify %s
+
+// From core issue 1227.
+
+template <class T> struct A { using X = typename T::X; }; // expected-error {{no members}}
+template <class T> typename T::X f(typename A<T>::X);
+template <class T> void f(...) {}
+template <class T> auto g(typename A<T>::X) -> typename T::X; // expected-note {{here}} expected-note {{substituting}}
+template <class T> void g(...) {}
+
+void h()
+{
+  f<int>(0); // ok, SFINAE in return type
+  g<int>(0); // not ok, substitution inside A<int> is a hard error
+}





More information about the cfe-commits mailing list