<div dir="ltr">Thanks, should be fixed in r218011.</div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Sep 17, 2014 at 8:19 PM, Bataev, Alexey <span dir="ltr"><<a href="mailto:a.bataev@hotmail.com" target="_blank">a.bataev@hotmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
  
    
  
  <div bgcolor="#FFFFFF" text="#000000">
    <div><span class="">+    for (const auto &E :
      T->exceptions())<br>
      +      TRY_TO(TraverseType(E));<br>
      <br></span>
      You just need to enclose the body of this loop into braces.<br>
      <pre cols="72">Best regards,
Alexey Bataev
=============
Software Engineer
Intel Compiler Team
Intel Corp. </pre>
      18.09.2014 7:10, Reid Kleckner пишет:<br>
    </div><div><div class="h5">
    <blockquote type="cite">
      <div dir="ltr">
        <div>This appears to not compile with MSVC 2013:</div>
        llvm\tools\clang\include\clang/AST/RecursiveASTVisitor.h(2171) :
        error C2059: syntax error : '}'<br>
        <div><a href="http://build.chromium.org/p/chromium.fyi/builders/Cr%20Win%20Clang/builds/395/steps/runhooks/logs/stdio" target="_blank">http://build.chromium.org/p/chromium.fyi/builders/Cr%20Win%20Clang/builds/395/steps/runhooks/logs/stdio</a><br>
        </div>
        <div><br>
        </div>
        <div>I believe it is trying to say that TRY_TO doesn't work
          inside of range-based for loops due to some insanity. This is
          a known issue when updating RAV. =/</div>
      </div>
      <div class="gmail_extra"><br>
        <div class="gmail_quote">On Wed, Sep 17, 2014 at 4:57 PM,
          Richard Smith <span dir="ltr"><<a href="mailto:richard-llvm@metafoo.co.uk" target="_blank">richard-llvm@metafoo.co.uk</a>></span>
          wrote:<br>
          <blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author:
            rsmith<br>
            Date: Wed Sep 17 18:57:05 2014<br>
            New Revision: 217995<br>
            <br>
            URL: <a href="http://llvm.org/viewvc/llvm-project?rev=217995&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=217995&view=rev</a><br>
            Log:<br>
            Instantiate exception specifications when instantiating
            function types (other<br>
            than the type of a function declaration). We previously
            didn't instantiate<br>
            these at all! This also covers the pathological case where
            the only mention of<br>
            a parameter pack is within the exception specification; this
            gives us a second<br>
            way (other than alias templates) to reach the horrible state
            where a type<br>
            contains an unexpanded pack, but its canonical type does
            not.<br>
            <br>
            Modified:<br>
                cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h<br>
                cfe/trunk/include/clang/AST/Expr.h<br>
                cfe/trunk/include/clang/AST/RecursiveASTVisitor.h<br>
                cfe/trunk/include/clang/AST/Type.h<br>
                cfe/trunk/include/clang/Sema/Sema.h<br>
                cfe/trunk/lib/AST/Type.cpp<br>
                cfe/trunk/lib/Sema/SemaDeclCXX.cpp<br>
                cfe/trunk/lib/Sema/SemaExceptionSpec.cpp<br>
                cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp<br>
                cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp<br>
                cfe/trunk/lib/Sema/SemaType.cpp<br>
                cfe/trunk/lib/Sema/TreeTransform.h<br>
                cfe/trunk/test/CXX/except/except.spec/p1.cpp<br>
               
            cfe/trunk/test/SemaTemplate/instantiate-exception-spec-cxx11.cpp<br>
               
            cfe/trunk/test/SemaTemplate/instantiate-exception-spec.cpp<br>
            <br>
            Modified:
            cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h<br>
            URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h?rev=217995&r1=217994&r2=217995&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h?rev=217995&r1=217994&r2=217995&view=diff</a><br>
==============================================================================<br>
            --- cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h
            (original)<br>
            +++ cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h
            Wed Sep 17 18:57:05 2014<br>
            @@ -876,6 +876,9 @@ DEF_TRAVERSE_TYPE(FunctionProtoType, {<br>
               for (const auto &E : T->exceptions()) {<br>
                 TRY_TO(TraverseType(E));<br>
               }<br>
            +<br>
            +  if (Expr *NE = T->getNoexceptExpr())<br>
            +    TRY_TO(TraverseStmt(NE));<br>
             })<br>
            <br>
             DEF_TRAVERSE_TYPE(UnresolvedUsingType, {})<br>
            @@ -1084,6 +1087,9 @@
            DEF_TRAVERSE_TYPELOC(FunctionProtoType,<br>
               for (const auto &E : T->exceptions()) {<br>
                 TRY_TO(TraverseType(E));<br>
               }<br>
            +<br>
            +  if (Expr *NE = T->getNoexceptExpr())<br>
            +    TRY_TO(TraverseStmt(NE));<br>
             })<br>
            <br>
             DEF_TRAVERSE_TYPELOC(UnresolvedUsingType, {})<br>
            @@ -2123,21 +2129,28 @@ bool
            RecursiveASTVisitor<Derived>::Trave<br>
                 TRY_TO(TraverseLambdaCapture(S, C));<br>
               }<br>
            <br>
            -  if (S->hasExplicitParameters() ||
            S->hasExplicitResultType()) {<br>
            -    TypeLoc TL =
            S->getCallOperator()->getTypeSourceInfo()->getTypeLoc();<br>
            -    if (S->hasExplicitParameters() &&
            S->hasExplicitResultType()) {<br>
            -      // Visit the whole type.<br>
            -      TRY_TO(TraverseTypeLoc(TL));<br>
            -    } else if (FunctionProtoTypeLoc Proto =
            TL.getAs<FunctionProtoTypeLoc>()) {<br>
            -      if (S->hasExplicitParameters()) {<br>
            -        // Visit parameters.<br>
            -        for (unsigned I = 0, N = Proto.getNumParams(); I !=
            N; ++I) {<br>
            -          TRY_TO(TraverseDecl(Proto.getParam(I)));<br>
            -        }<br>
            -      } else {<br>
            -        TRY_TO(TraverseTypeLoc(Proto.getReturnLoc()));<br>
            +  TypeLoc TL =
            S->getCallOperator()->getTypeSourceInfo()->getTypeLoc();<br>
            +  FunctionProtoTypeLoc Proto =
            TL.castAs<FunctionProtoTypeLoc>();<br>
            +<br>
            +  if (S->hasExplicitParameters() &&
            S->hasExplicitResultType()) {<br>
            +    // Visit the whole type.<br>
            +    TRY_TO(TraverseTypeLoc(TL));<br>
            +  } else {<br>
            +    if (S->hasExplicitParameters()) {<br>
            +      // Visit parameters.<br>
            +      for (unsigned I = 0, N = Proto.getNumParams(); I !=
            N; ++I) {<br>
            +        TRY_TO(TraverseDecl(Proto.getParam(I)));<br>
                   }<br>
            +    } else if (S->hasExplicitResultType()) {<br>
            +      TRY_TO(TraverseTypeLoc(Proto.getReturnLoc()));<br>
                 }<br>
            +<br>
            +    auto *T = Proto.getTypePtr();<br>
            +    for (const auto &E : T->exceptions())<br>
            +      TRY_TO(TraverseType(E));<br>
            +<br>
            +    if (Expr *NE = T->getNoexceptExpr())<br>
            +      TRY_TO(TraverseStmt(NE));<br>
               }<br>
            <br>
               TRY_TO(TraverseLambdaBody(S));<br>
            <br>
            Modified: cfe/trunk/include/clang/AST/Expr.h<br>
            URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=217995&r1=217994&r2=217995&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=217995&r1=217994&r2=217995&view=diff</a><br>
==============================================================================<br>
            --- cfe/trunk/include/clang/AST/Expr.h (original)<br>
            +++ cfe/trunk/include/clang/AST/Expr.h Wed Sep 17 18:57:05
            2014<br>
            @@ -2673,20 +2673,23 @@ private:<br>
               }<br>
            <br>
             protected:<br>
            -  CastExpr(StmtClass SC, QualType ty, ExprValueKind VK,<br>
            -           const CastKind kind, Expr *op, unsigned
            BasePathSize) :<br>
            -    Expr(SC, ty, VK, OK_Ordinary,<br>
            -         // Cast expressions are type-dependent if the type
            is<br>
            -         // dependent (C++ [temp.dep.expr]p3).<br>
            -         ty->isDependentType(),<br>
            -         // Cast expressions are value-dependent if the
            type is<br>
            -         // dependent or if the subexpression is
            value-dependent.<br>
            -         ty->isDependentType() || (op &&
            op->isValueDependent()),<br>
            -         (ty->isInstantiationDependentType() ||<br>
            -          (op &&
            op->isInstantiationDependent())),<br>
            -         (ty->containsUnexpandedParameterPack() ||<br>
            -          (op &&
            op->containsUnexpandedParameterPack()))),<br>
            -    Op(op) {<br>
            +  CastExpr(StmtClass SC, QualType ty, ExprValueKind VK,
            const CastKind kind,<br>
            +           Expr *op, unsigned BasePathSize)<br>
            +      : Expr(SC, ty, VK, OK_Ordinary,<br>
            +             // Cast expressions are type-dependent if the
            type is<br>
            +             // dependent (C++ [temp.dep.expr]p3).<br>
            +             ty->isDependentType(),<br>
            +             // Cast expressions are value-dependent if the
            type is<br>
            +             // dependent or if the subexpression is
            value-dependent.<br>
            +             ty->isDependentType() || (op &&
            op->isValueDependent()),<br>
            +             (ty->isInstantiationDependentType() ||<br>
            +              (op &&
            op->isInstantiationDependent())),<br>
            +             // An implicit cast expression doesn't
            (lexically) contain an<br>
            +             // unexpanded pack, even if its target type
            does.<br>
            +             ((SC != ImplicitCastExprClass &&<br>
            +               ty->containsUnexpandedParameterPack()) ||<br>
            +              (op &&
            op->containsUnexpandedParameterPack()))),<br>
            +        Op(op) {<br>
                 assert(kind != CK_Invalid && "creating cast
            with invalid cast kind");<br>
                 CastExprBits.Kind = kind;<br>
                 setBasePathSize(BasePathSize);<br>
            <br>
            Modified: cfe/trunk/include/clang/AST/RecursiveASTVisitor.h<br>
            URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/RecursiveASTVisitor.h?rev=217995&r1=217994&r2=217995&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/RecursiveASTVisitor.h?rev=217995&r1=217994&r2=217995&view=diff</a><br>
==============================================================================<br>
            --- cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
            (original)<br>
            +++ cfe/trunk/include/clang/AST/RecursiveASTVisitor.h Wed
            Sep 17 18:57:05 2014<br>
            @@ -941,6 +941,9 @@ DEF_TRAVERSE_TYPE(FunctionProtoType, {<br>
               for (const auto &E : T->exceptions()) {<br>
                 TRY_TO(TraverseType(E));<br>
               }<br>
            +<br>
            +  if (Expr *NE = T->getNoexceptExpr())<br>
            +    TRY_TO(TraverseStmt(NE));<br>
             })<br>
            <br>
             DEF_TRAVERSE_TYPE(UnresolvedUsingType, {})<br>
            @@ -1149,6 +1152,9 @@
            DEF_TRAVERSE_TYPELOC(FunctionProtoType,<br>
               for (const auto &E : T->exceptions()) {<br>
                 TRY_TO(TraverseType(E));<br>
               }<br>
            +<br>
            +  if (Expr *NE = T->getNoexceptExpr())<br>
            +    TRY_TO(TraverseStmt(NE));<br>
             })<br>
            <br>
             DEF_TRAVERSE_TYPELOC(UnresolvedUsingType, {})<br>
            @@ -2145,21 +2151,28 @@ bool
            RecursiveASTVisitor<Derived>::Trave<br>
                 TRY_TO(TraverseLambdaCapture(S, C));<br>
               }<br>
            <br>
            -  if (S->hasExplicitParameters() ||
            S->hasExplicitResultType()) {<br>
            -    TypeLoc TL =
            S->getCallOperator()->getTypeSourceInfo()->getTypeLoc();<br>
            -    if (S->hasExplicitParameters() &&
            S->hasExplicitResultType()) {<br>
            -      // Visit the whole type.<br>
            -      TRY_TO(TraverseTypeLoc(TL));<br>
            -    } else if (FunctionProtoTypeLoc Proto =
            TL.getAs<FunctionProtoTypeLoc>()) {<br>
            -      if (S->hasExplicitParameters()) {<br>
            -        // Visit parameters.<br>
            -        for (unsigned I = 0, N = Proto.getNumParams(); I !=
            N; ++I) {<br>
            -          TRY_TO(TraverseDecl(Proto.getParam(I)));<br>
            -        }<br>
            -      } else {<br>
            -        TRY_TO(TraverseTypeLoc(Proto.getReturnLoc()));<br>
            +  TypeLoc TL =
            S->getCallOperator()->getTypeSourceInfo()->getTypeLoc();<br>
            +  FunctionProtoTypeLoc Proto =
            TL.castAs<FunctionProtoTypeLoc>();<br>
            +<br>
            +  if (S->hasExplicitParameters() &&
            S->hasExplicitResultType()) {<br>
            +    // Visit the whole type.<br>
            +    TRY_TO(TraverseTypeLoc(TL));<br>
            +  } else {<br>
            +    if (S->hasExplicitParameters()) {<br>
            +      // Visit parameters.<br>
            +      for (unsigned I = 0, N = Proto.getNumParams(); I !=
            N; ++I) {<br>
            +        TRY_TO(TraverseDecl(Proto.getParam(I)));<br>
                   }<br>
            +    } else if (S->hasExplicitResultType()) {<br>
            +      TRY_TO(TraverseTypeLoc(Proto.getReturnLoc()));<br>
                 }<br>
            +<br>
            +    auto *T = Proto.getTypePtr();<br>
            +    for (const auto &E : T->exceptions())<br>
            +      TRY_TO(TraverseType(E));<br>
            +<br>
            +    if (Expr *NE = T->getNoexceptExpr())<br>
            +      TRY_TO(TraverseStmt(NE));<br>
               }<br>
            <br>
               TRY_TO(TraverseLambdaBody(S));<br>
            <br>
            Modified: cfe/trunk/include/clang/AST/Type.h<br>
            URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=217995&r1=217994&r2=217995&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=217995&r1=217994&r2=217995&view=diff</a><br>
==============================================================================<br>
            --- cfe/trunk/include/clang/AST/Type.h (original)<br>
            +++ cfe/trunk/include/clang/AST/Type.h Wed Sep 17 18:57:05
            2014<br>
            @@ -3012,6 +3012,8 @@ public:<br>
               bool hasNoexceptExceptionSpec() const {<br>
                 return isNoexceptExceptionSpec(getExceptionSpecType());<br>
               }<br>
            +  /// \brief Return whether this function has a dependent
            exception spec.<br>
            +  bool hasDependentExceptionSpec() const;<br>
               /// \brief Result type of getNoexceptSpec().<br>
               enum NoexceptResult {<br>
                 NR_NoNoexcept,  ///< There is no noexcept specifier.<br>
            @@ -5247,8 +5249,8 @@ template <typename T> const T
            *Type::cas<br>
               ArrayType_cannot_be_used_with_getAs<T> at;<br>
               (void) at;<br>
            <br>
            -  assert(isa<T>(CanonicalType));<br>
               if (const T *ty = dyn_cast<T>(this)) return ty;<br>
            +  assert(isa<T>(CanonicalType));<br>
               return cast<T>(getUnqualifiedDesugaredType());<br>
             }<br>
            <br>
            <br>
            Modified: cfe/trunk/include/clang/Sema/Sema.h<br>
            URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=217995&r1=217994&r2=217995&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=217995&r1=217994&r2=217995&view=diff</a><br>
==============================================================================<br>
            --- cfe/trunk/include/clang/Sema/Sema.h (original)<br>
            +++ cfe/trunk/include/clang/Sema/Sema.h Wed Sep 17 18:57:05
            2014<br>
            @@ -4025,7 +4025,8 @@ public:<br>
            <br>
               /// \brief Check the given exception-specification and
            update the<br>
               /// exception specification information with the results.<br>
            -  void
            checkExceptionSpecification(ExceptionSpecificationType EST,<br>
            +  void checkExceptionSpecification(bool IsTopLevel,<br>
            +                                 
             ExceptionSpecificationType EST,<br>
                                               
            ArrayRef<ParsedType> DynamicExceptions,<br>
                                               
            ArrayRef<SourceRange> DynamicExceptionRanges,<br>
                                                Expr *NoexceptExpr,<br>
            @@ -6652,6 +6653,8 @@ public:<br>
                                                     DeclarationName
            Entity,<br>
                                                     CXXRecordDecl
            *ThisContext,<br>
                                                     unsigned
            ThisTypeQuals);<br>
            +  void SubstExceptionSpec(FunctionDecl *New, const
            FunctionProtoType *Proto,<br>
            +                          const
            MultiLevelTemplateArgumentList &Args);<br>
               ParmVarDecl *SubstParmVarDecl(ParmVarDecl *D,<br>
                                         const
            MultiLevelTemplateArgumentList &TemplateArgs,<br>
                                             int indexAdjustment,<br>
            <br>
            Modified: cfe/trunk/lib/AST/Type.cpp<br>
            URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=217995&r1=217994&r2=217995&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=217995&r1=217994&r2=217995&view=diff</a><br>
==============================================================================<br>
            --- cfe/trunk/lib/AST/Type.cpp (original)<br>
            +++ cfe/trunk/lib/AST/Type.cpp Wed Sep 17 18:57:05 2014<br>
            @@ -1623,9 +1623,9 @@
            FunctionProtoType::FunctionProtoType(Qua<br>
                 QualType *exnSlot = argSlot + NumParams;<br>
                 unsigned I = 0;<br>
                 for (QualType ExceptionType :
            epi.ExceptionSpec.Exceptions) {<br>
            -      if (ExceptionType->isDependentType())<br>
            -        setDependent();<br>
            -      else if
            (ExceptionType->isInstantiationDependentType())<br>
            +      // Note that a dependent exception specification does
            *not* make<br>
            +      // a type dependent; it's not even part of the C++
            type system.<br>
            +      if (ExceptionType->isInstantiationDependentType())<br>
                     setInstantiationDependent();<br>
            <br>
                   if
            (ExceptionType->containsUnexpandedParameterPack())<br>
            @@ -1639,11 +1639,12 @@
            FunctionProtoType::FunctionProtoType(Qua<br>
                 *noexSlot = epi.ExceptionSpec.NoexceptExpr;<br>
            <br>
                 if (epi.ExceptionSpec.NoexceptExpr) {<br>
            -      if
            (epi.ExceptionSpec.NoexceptExpr->isValueDependent()<br>
            -          ||
            epi.ExceptionSpec.NoexceptExpr->isTypeDependent())<br>
            -        setDependent();<br>
            -      else if
            (epi.ExceptionSpec.NoexceptExpr->isInstantiationDependent())<br>
            +      if
            (epi.ExceptionSpec.NoexceptExpr->isValueDependent() ||<br>
            +         
            epi.ExceptionSpec.NoexceptExpr->isInstantiationDependent())<br>
                     setInstantiationDependent();<br>
            +<br>
            +      if
            (epi.ExceptionSpec.NoexceptExpr->containsUnexpandedParameterPack())<br>
            +        setContainsUnexpandedParameterPack();<br>
                 }<br>
               } else if (getExceptionSpecType() == EST_Uninstantiated)
            {<br>
                 // Store the function decl from which we will resolve
            our<br>
            @@ -1669,6 +1670,19 @@
            FunctionProtoType::FunctionProtoType(Qua<br>
               }<br>
             }<br>
            <br>
            +bool FunctionProtoType::hasDependentExceptionSpec() const {<br>
            +  if (Expr *NE = getNoexceptExpr())<br>
            +    return NE->isValueDependent();<br>
            +  for (unsigned I = 0, N = getNumExceptions(); I != N; ++I)<br>
            +    // A pack expansion with a non-dependent pattern is
            still dependent,<br>
            +    // because we don't know whether the pattern is in the
            exception spec<br>
            +    // or not (that depends on whether the pack has 0
            expansions).<br>
            +    if (getExceptionType(I)->isDependentType() ||<br>
            +       
            getExceptionType(I)->getAs<PackExpansionType>())<br>
            +      return true;<br>
            +  return false;<br>
            +}<br>
            +<br>
             FunctionProtoType::NoexceptResult<br>
             FunctionProtoType::getNoexceptSpec(const ASTContext
            &ctx) const {<br>
               ExceptionSpecificationType est = getExceptionSpecType();<br>
            <br>
            Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp<br>
            URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=217995&r1=217994&r2=217995&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=217995&r1=217994&r2=217995&view=diff</a><br>
==============================================================================<br>
            --- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)<br>
            +++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Wed Sep 17 18:57:05
            2014<br>
            @@ -13051,13 +13051,12 @@ bool
            Sema::checkThisInStaticMemberFuncti<br>
               return false;<br>
             }<br>
            <br>
            -void<br>
            -Sema::checkExceptionSpecification(ExceptionSpecificationType
            EST,<br>
            -                                 
            ArrayRef<ParsedType> DynamicExceptions,<br>
            -                                 
            ArrayRef<SourceRange> DynamicExceptionRanges,<br>
            -                                  Expr *NoexceptExpr,<br>
            -                                 
            SmallVectorImpl<QualType> &Exceptions,<br>
            -                                 
            FunctionProtoType::ExceptionSpecInfo &ESI) {<br>
            +void Sema::checkExceptionSpecification(<br>
            +    bool IsTopLevel, ExceptionSpecificationType EST,<br>
            +    ArrayRef<ParsedType> DynamicExceptions,<br>
            +    ArrayRef<SourceRange> DynamicExceptionRanges,
            Expr *NoexceptExpr,<br>
            +    SmallVectorImpl<QualType> &Exceptions,<br>
            +    FunctionProtoType::ExceptionSpecInfo &ESI) {<br>
               Exceptions.clear();<br>
               ESI.Type = EST;<br>
               if (EST == EST_Dynamic) {<br>
            @@ -13066,13 +13065,15 @@
            Sema::checkExceptionSpecification(Except<br>
                   // FIXME: Preserve type source info.<br>
                   QualType ET =
            GetTypeFromParser(DynamicExceptions[ei]);<br>
            <br>
            -      SmallVector<UnexpandedParameterPack, 2>
            Unexpanded;<br>
            -      collectUnexpandedParameterPacks(ET, Unexpanded);<br>
            -      if (!Unexpanded.empty()) {<br>
            -       
            DiagnoseUnexpandedParameterPacks(DynamicExceptionRanges[ei].getBegin(),<br>
            -                                       
             UPPC_ExceptionType,<br>
            -                                         Unexpanded);<br>
            -        continue;<br>
            +      if (IsTopLevel) {<br>
            +        SmallVector<UnexpandedParameterPack, 2>
            Unexpanded;<br>
            +        collectUnexpandedParameterPacks(ET, Unexpanded);<br>
            +        if (!Unexpanded.empty()) {<br>
            +          DiagnoseUnexpandedParameterPacks(<br>
            +              DynamicExceptionRanges[ei].getBegin(),
            UPPC_ExceptionType,<br>
            +              Unexpanded);<br>
            +          continue;<br>
            +        }<br>
                   }<br>
            <br>
                   // Check that the type is valid for an exception
            spec, and<br>
            @@ -13091,7 +13092,8 @@
            Sema::checkExceptionSpecification(Except<br>
                         
             NoexceptExpr->getType()->getCanonicalTypeUnqualified()
            ==<br>
                           Context.BoolTy) &&<br>
                          "Parser should have made sure that the
            expression is boolean");<br>
            -      if (NoexceptExpr &&
            DiagnoseUnexpandedParameterPack(NoexceptExpr)) {<br>
            +      if (IsTopLevel && NoexceptExpr &&<br>
            +          DiagnoseUnexpandedParameterPack(NoexceptExpr)) {<br>
                     ESI.Type = EST_BasicNoexcept;<br>
                     return;<br>
                   }<br>
            <br>
            Modified: cfe/trunk/lib/Sema/SemaExceptionSpec.cpp<br>
            URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExceptionSpec.cpp?rev=217995&r1=217994&r2=217995&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExceptionSpec.cpp?rev=217995&r1=217994&r2=217995&view=diff</a><br>
==============================================================================<br>
            --- cfe/trunk/lib/Sema/SemaExceptionSpec.cpp (original)<br>
            +++ cfe/trunk/lib/Sema/SemaExceptionSpec.cpp Wed Sep 17
            18:57:05 2014<br>
            @@ -720,10 +720,11 @@ static bool
            CheckSpecForTypesEquivalent(<br>
             /// assignment and override compatibility check. We do not
            check the parameters<br>
             /// of parameter function pointers recursively, as no sane
            programmer would<br>
             /// even be able to write such a function type.<br>
            -bool Sema::CheckParamExceptionSpec(const PartialDiagnostic
            & NoteID,<br>
            -    const FunctionProtoType *Target, SourceLocation
            TargetLoc,<br>
            -    const FunctionProtoType *Source, SourceLocation
            SourceLoc)<br>
            -{<br>
            +bool Sema::CheckParamExceptionSpec(const PartialDiagnostic
            &NoteID,<br>
            +                                   const FunctionProtoType
            *Target,<br>
            +                                   SourceLocation
            TargetLoc,<br>
            +                                   const FunctionProtoType
            *Source,<br>
            +                                   SourceLocation
            SourceLoc) {<br>
               if (CheckSpecForTypesEquivalent(<br>
                       *this,
            PDiag(diag::err_deep_exception_specs_differ) << 0,
            PDiag(),<br>
                       Target->getReturnType(), TargetLoc,
            Source->getReturnType(),<br>
            @@ -744,23 +745,30 @@ bool
            Sema::CheckParamExceptionSpec(const<br>
               return false;<br>
             }<br>
            <br>
            -bool Sema::CheckExceptionSpecCompatibility(Expr *From,
            QualType ToType)<br>
            -{<br>
            +bool Sema::CheckExceptionSpecCompatibility(Expr *From,
            QualType ToType) {<br>
               // First we check for applicability.<br>
               // Target type must be a function, function pointer or
            function reference.<br>
               const FunctionProtoType *ToFunc =
            GetUnderlyingFunction(ToType);<br>
            -  if (!ToFunc)<br>
            +  if (!ToFunc || ToFunc->hasDependentExceptionSpec())<br>
                 return false;<br>
            <br>
               // SourceType must be a function or function pointer.<br>
               const FunctionProtoType *FromFunc =
            GetUnderlyingFunction(From->getType());<br>
            -  if (!FromFunc)<br>
            +  if (!FromFunc ||
            FromFunc->hasDependentExceptionSpec())<br>
                 return false;<br>
            <br>
               // Now we've got the correct types on both sides, check
            their compatibility.<br>
               // This means that the source of the conversion can only
            throw a subset of<br>
               // the exceptions of the target, and any exception specs
            on arguments or<br>
               // return types must be equivalent.<br>
            +  //<br>
            +  // FIXME: If there is a nested dependent exception
            specification, we should<br>
            +  // not be checking it here. This is fine:<br>
            +  //   template<typename T> void f() {<br>
            +  //     void (*p)(void (*) throw(T));<br>
            +  //     void (*q)(void (*) throw(int)) = p;<br>
            +  //   }<br>
            +  // ... because it might be instantiated with T=int.<br>
               return
            CheckExceptionSpecSubset(PDiag(diag::err_incompatible_exception_specs),<br>
                                               PDiag(), ToFunc,<br>
                                             
             From->getSourceRange().getBegin(),<br>
            <br>
            Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp<br>
            URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp?rev=217995&r1=217994&r2=217995&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp?rev=217995&r1=217994&r2=217995&view=diff</a><br>
==============================================================================<br>
            --- cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
            (original)<br>
            +++ cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp Wed Sep
            17 18:57:05 2014<br>
            @@ -788,12 +788,14 @@ namespace {<br>
                 /// pack.<br>
                 ExprResult
            TransformFunctionParmPackExpr(FunctionParmPackExpr *E);<br>
            <br>
            -    QualType TransformFunctionProtoType(TypeLocBuilder
            &TLB,<br>
            -                                       
            FunctionProtoTypeLoc TL);<br>
            +    // Pull in the base class overload; it just forwards to
            our function.<br>
            +    using inherited::TransformFunctionProtoType;<br>
            +    template<typename Fn><br>
                 QualType TransformFunctionProtoType(TypeLocBuilder
            &TLB,<br>
                                                   
             FunctionProtoTypeLoc TL,<br>
                                                     CXXRecordDecl
            *ThisContext,<br>
            -                                        unsigned
            ThisTypeQuals);<br>
            +                                        unsigned
            ThisTypeQuals,<br>
            +                                        Fn
            TransformExceptionSpec);<br>
            <br>
                 ParmVarDecl *TransformFunctionTypeParam(ParmVarDecl
            *OldParm,<br>
                                                         int
            indexAdjustment,<br>
            @@ -1307,21 +1309,16 @@ ExprResult
            TemplateInstantiator::Transfo<br>
                                                     E->getParam());<br>
             }<br>
            <br>
            -QualType
            TemplateInstantiator::TransformFunctionProtoType(TypeLocBuilder
            &TLB,<br>
            -                                                     
            FunctionProtoTypeLoc TL) {<br>
            -  // We need a local instantiation scope for this function
            prototype.<br>
            -  LocalInstantiationScope Scope(SemaRef,
            /*CombineWithOuterScope=*/true);<br>
            -  return inherited::TransformFunctionProtoType(TLB, TL);<br>
            -}<br>
            -<br>
            +template<typename Fn><br>
             QualType
            TemplateInstantiator::TransformFunctionProtoType(TypeLocBuilder
            &TLB,<br>
                                              FunctionProtoTypeLoc TL,<br>
                                              CXXRecordDecl
            *ThisContext,<br>
            -                                 unsigned ThisTypeQuals) {<br>
            +                                 unsigned ThisTypeQuals,<br>
            +                                 Fn TransformExceptionSpec)
            {<br>
               // We need a local instantiation scope for this function
            prototype.<br>
               LocalInstantiationScope Scope(SemaRef,
            /*CombineWithOuterScope=*/true);<br>
            -  return inherited::TransformFunctionProtoType(TLB, TL,
            ThisContext,<br>
            -                                             
             ThisTypeQuals);<br>
            +  return inherited::TransformFunctionProtoType(<br>
            +      TLB, TL, ThisContext, ThisTypeQuals,
            TransformExceptionSpec);<br>
             }<br>
            <br>
             ParmVarDecl *<br>
            @@ -1556,7 +1553,8 @@ static bool
            NeedsInstantiationAsFunction<br>
            <br>
             /// A form of SubstType intended specifically for
            instantiating the<br>
             /// type of a FunctionDecl.  Its purpose is solely to force
            the<br>
            -/// instantiation of default-argument expressions.<br>
            +/// instantiation of default-argument expressions and to
            avoid<br>
            +/// instantiating an exception-specification.<br>
             TypeSourceInfo *Sema::SubstFunctionDeclType(TypeSourceInfo
            *T,<br>
                                             const
            MultiLevelTemplateArgumentList &Args,<br>
                                             SourceLocation Loc,<br>
            @@ -1579,9 +1577,17 @@ TypeSourceInfo
            *Sema::SubstFunctionDeclT<br>
            <br>
               QualType Result;<br>
            <br>
            +  // FIXME: What if the function type is parenthesized?<br>
               if (FunctionProtoTypeLoc Proto =
            TL.getAs<FunctionProtoTypeLoc>()) {<br>
            -    Result = Instantiator.TransformFunctionProtoType(TLB,
            Proto, ThisContext,<br>
            -                                                   
             ThisTypeQuals);<br>
            +    // Instantiate the type, other than its exception
            specification. The<br>
            +    // exception specification is instantiated in
            InitFunctionInstantiation<br>
            +    // once we've built the FunctionDecl.<br>
            +    // FIXME: Set the exception specification to
            EST_Uninstantiated here,<br>
            +    // instead of rebuilding the function type again later.<br>
            +    Result = Instantiator.TransformFunctionProtoType(<br>
            +        TLB, Proto, ThisContext, ThisTypeQuals,<br>
            +        [](FunctionProtoType::ExceptionSpecInfo &ESI,<br>
            +           bool &Changed) { return false; });<br>
               } else {<br>
                 Result = Instantiator.TransformType(TLB, TL);<br>
               }<br>
            @@ -1591,6 +1597,26 @@ TypeSourceInfo
            *Sema::SubstFunctionDeclT<br>
               return TLB.getTypeSourceInfo(Context, Result);<br>
             }<br>
            <br>
            +void Sema::SubstExceptionSpec(FunctionDecl *New, const
            FunctionProtoType *Proto,<br>
            +                              const
            MultiLevelTemplateArgumentList &Args) {<br>
            +  FunctionProtoType::ExceptionSpecInfo ESI =<br>
            +      Proto->getExtProtoInfo().ExceptionSpec;<br>
            +  assert(ESI.Type != EST_Uninstantiated);<br>
            +<br>
            +  TemplateInstantiator Instantiator(*this, Args,
            New->getLocation(),<br>
            +                                    New->getDeclName());<br>
            +<br>
            +  SmallVector<QualType, 4> ExceptionStorage;<br>
            +  bool Changed = false;<br>
            +  if (Instantiator.TransformExceptionSpec(<br>
            +         
            New->getTypeSourceInfo()->getTypeLoc().getLocEnd(),
            ESI,<br>
            +          ExceptionStorage, Changed))<br>
            +    // On error, recover by dropping the exception
            specification.<br>
            +    ESI.Type = EST_None;<br>
            +<br>
            +  UpdateExceptionSpec(New, ESI);<br>
            +}<br>
            +<br>
             ParmVarDecl *Sema::SubstParmVarDecl(ParmVarDecl *OldParm,<br>
                                         const
            MultiLevelTemplateArgumentList &TemplateArgs,<br>
                                                 int indexAdjustment,<br>
            <br>
            Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp<br>
            URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=217995&r1=217994&r2=217995&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=217995&r1=217994&r2=217995&view=diff</a><br>
==============================================================================<br>
            --- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
            (original)<br>
            +++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Wed
            Sep 17 18:57:05 2014<br>
            @@ -2988,7 +2988,7 @@
            TemplateDeclInstantiator::SubstFunctionT<br>
             /// Introduce the instantiated function parameters into the
            local<br>
             /// instantiation scope, and set the parameter names to
            those used<br>
             /// in the template.<br>
            -static void addInstantiatedParametersToScope(Sema &S,
            FunctionDecl *Function,<br>
            +static bool addInstantiatedParametersToScope(Sema &S,
            FunctionDecl *Function,<br>
                                                          const
            FunctionDecl *PatternDecl,<br>
                                                         
            LocalInstantiationScope &Scope,<br>
                                        const
            MultiLevelTemplateArgumentList &TemplateArgs) {<br>
            @@ -2999,15 +2999,22 @@ static void
            addInstantiatedParametersToS<br>
                   // Simple case: not a parameter pack.<br>
                   assert(FParamIdx < Function->getNumParams());<br>
                   ParmVarDecl *FunctionParam =
            Function->getParamDecl(FParamIdx);<br>
            +     
            FunctionParam->setDeclName(PatternParam->getDeclName());<br>
                   // If the parameter's type is not dependent, update
            it to match the type<br>
                   // in the pattern. They can differ in top-level
            cv-qualifiers, and we want<br>
                   // the pattern's type here. If the type is dependent,
            they can't differ,<br>
            -      // per core issue 1668.<br>
            +      // per core issue 1668. Substitute into the type from
            the pattern, in case<br>
            +      // it's instantiation-dependent.<br>
                   // FIXME: Updating the type to work around this is at
            best fragile.<br>
            -      if (!PatternDecl->getType()->isDependentType())<br>
            -       
            FunctionParam->setType(PatternParam->getType());<br>
            +      if (!PatternDecl->getType()->isDependentType())
            {<br>
            +        QualType T =
            S.SubstType(PatternParam->getType(), TemplateArgs,<br>
            +                               
             FunctionParam->getLocation(),<br>
            +                               
             FunctionParam->getDeclName());<br>
            +        if (T.isNull())<br>
            +          return true;<br>
            +        FunctionParam->setType(T);<br>
            +      }<br>
            <br>
            -     
            FunctionParam->setDeclName(PatternParam->getDeclName());<br>
                   Scope.InstantiatedLocal(PatternParam, FunctionParam);<br>
                   ++FParamIdx;<br>
                   continue;<br>
            @@ -3019,136 +3026,27 @@ static void
            addInstantiatedParametersToS<br>
                   =
            S.getNumArgumentsInExpansion(PatternParam->getType(),
            TemplateArgs);<br>
                 assert(NumArgumentsInExpansion &&<br>
                        "should only be called when all template
            arguments are known");<br>
            +    QualType PatternType =<br>
            +       
PatternParam->getType()->castAs<PackExpansionType>()->getPattern();<br>
                 for (unsigned Arg = 0; Arg <
            *NumArgumentsInExpansion; ++Arg) {<br>
                   ParmVarDecl *FunctionParam =
            Function->getParamDecl(FParamIdx);<br>
            -      if (!PatternDecl->getType()->isDependentType())<br>
            -       
            FunctionParam->setType(PatternParam->getType());<br>
            -<br>
                 
             FunctionParam->setDeclName(PatternParam->getDeclName());<br>
            -      Scope.InstantiatedLocalPackArg(PatternParam,
            FunctionParam);<br>
            -      ++FParamIdx;<br>
            -    }<br>
            -  }<br>
            -}<br>
            -<br>
            -static void InstantiateExceptionSpec(Sema &SemaRef,
            FunctionDecl *New,<br>
            -                                     const
            FunctionProtoType *Proto,<br>
            -                           const
            MultiLevelTemplateArgumentList &TemplateArgs) {<br>
            -  assert(Proto->getExceptionSpecType() !=
            EST_Uninstantiated);<br>
            -<br>
            -  // C++11 [expr.prim.general]p3:<br>
            -  //   If a declaration declares a member function or
            member function<br>
            -  //   template of a class X, the expression this is a
            prvalue of type<br>
            -  //   "pointer to cv-qualifier-seq X" between the optional
            cv-qualifer-seq<br>
            -  //   and the end of the function-definition,
            member-declarator, or<br>
            -  //   declarator.<br>
            -  CXXRecordDecl *ThisContext = nullptr;<br>
            -  unsigned ThisTypeQuals = 0;<br>
            -  if (CXXMethodDecl *Method =
            dyn_cast<CXXMethodDecl>(New)) {<br>
            -    ThisContext = Method->getParent();<br>
            -    ThisTypeQuals = Method->getTypeQualifiers();<br>
            -  }<br>
            -  Sema::CXXThisScopeRAII ThisScope(SemaRef, ThisContext,
            ThisTypeQuals,<br>
            -                                 
             SemaRef.getLangOpts().CPlusPlus11);<br>
            -<br>
            -  // The function has an exception specification or a
            "noreturn"<br>
            -  // attribute. Substitute into each of the exception
            types.<br>
            -  SmallVector<QualType, 4> Exceptions;<br>
            -  for (unsigned I = 0, N = Proto->getNumExceptions(); I
            != N; ++I) {<br>
            -    // FIXME: Poor location information!<br>
            -    if (const PackExpansionType *PackExpansion<br>
            -          =
            Proto->getExceptionType(I)->getAs<PackExpansionType>())
            {<br>
            -      // We have a pack expansion. Instantiate it.<br>
            -      SmallVector<UnexpandedParameterPack, 2>
            Unexpanded;<br>
            -     
            SemaRef.collectUnexpandedParameterPacks(PackExpansion->getPattern(),<br>
            -                                              Unexpanded);<br>
            -      assert(!Unexpanded.empty() &&<br>
            -             "Pack expansion without parameter packs?");<br>
            -<br>
            -      bool Expand = false;<br>
            -      bool RetainExpansion = false;<br>
            -      Optional<unsigned> NumExpansions =
            PackExpansion->getNumExpansions();<br>
            -      if
            (SemaRef.CheckParameterPacksForExpansion(New->getLocation(),<br>
            -                                                 
            SourceRange(),<br>
            -                                                 
            Unexpanded,<br>
            -                                                 
            TemplateArgs,<br>
            -                                                  Expand,<br>
            -                                                 
            RetainExpansion,<br>
            -                                                 
            NumExpansions))<br>
            -        break;<br>
            -<br>
            -      if (!Expand) {<br>
            -        // We can't expand this pack expansion into
            separate arguments yet;<br>
            -        // just substitute into the pattern and create a
            new pack expansion<br>
            -        // type.<br>
            -        Sema::ArgumentPackSubstitutionIndexRAII
            SubstIndex(SemaRef, -1);<br>
            -        QualType T =
            SemaRef.SubstType(PackExpansion->getPattern(),<br>
            -                                       TemplateArgs,<br>
            -                                     New->getLocation(),
            New->getDeclName());<br>
            +      if (!PatternDecl->getType()->isDependentType())
            {<br>
            +        Sema::ArgumentPackSubstitutionIndexRAII
            SubstIndex(S, Arg);<br>
            +        QualType T = S.SubstType(PatternType, TemplateArgs,<br>
            +                               
             FunctionParam->getLocation(),<br>
            +                               
             FunctionParam->getDeclName());<br>
                     if (T.isNull())<br>
            -          break;<br>
            -<br>
            -        T = SemaRef.Context.getPackExpansionType(T,
            NumExpansions);<br>
            -        Exceptions.push_back(T);<br>
            -        continue;<br>
            -      }<br>
            -<br>
            -      // Substitute into the pack expansion pattern for
            each template<br>
            -      bool Invalid = false;<br>
            -      for (unsigned ArgIdx = 0; ArgIdx != *NumExpansions;
            ++ArgIdx) {<br>
            -        Sema::ArgumentPackSubstitutionIndexRAII
            SubstIndex(SemaRef, ArgIdx);<br>
            -<br>
            -        QualType T =
            SemaRef.SubstType(PackExpansion->getPattern(),<br>
            -                                       TemplateArgs,<br>
            -                                     New->getLocation(),
            New->getDeclName());<br>
            -        if (T.isNull()) {<br>
            -          Invalid = true;<br>
            -          break;<br>
            -        }<br>
            -<br>
            -        Exceptions.push_back(T);<br>
            +          return true;<br>
            +        FunctionParam->setType(T);<br>
                   }<br>
            <br>
            -      if (Invalid)<br>
            -        break;<br>
            -<br>
            -      continue;<br>
            -    }<br>
            -<br>
            -    QualType T<br>
            -      = SemaRef.SubstType(Proto->getExceptionType(I),
            TemplateArgs,<br>
            -                          New->getLocation(),
            New->getDeclName());<br>
            -    if (T.isNull() ||<br>
            -        SemaRef.CheckSpecifiedExceptionType(T,
            New->getLocation()))<br>
            -      continue;<br>
            -<br>
            -    Exceptions.push_back(T);<br>
            -  }<br>
            -  Expr *NoexceptExpr = nullptr;<br>
            -  if (Expr *OldNoexceptExpr = Proto->getNoexceptExpr())
            {<br>
            -    EnterExpressionEvaluationContext Unevaluated(SemaRef,<br>
            -                                               
             Sema::ConstantEvaluated);<br>
            -    ExprResult E = SemaRef.SubstExpr(OldNoexceptExpr,
            TemplateArgs);<br>
            -    if (E.isUsable())<br>
            -      E = SemaRef.CheckBooleanCondition(E.get(),
            E.get()->getLocStart());<br>
            -<br>
            -    if (E.isUsable()) {<br>
            -      NoexceptExpr = E.get();<br>
            -      if (!NoexceptExpr->isTypeDependent() &&<br>
            -          !NoexceptExpr->isValueDependent())<br>
            -        NoexceptExpr<br>
            -          =
            SemaRef.VerifyIntegerConstantExpression(NoexceptExpr,<br>
            -              nullptr,
            diag::err_noexcept_needs_constant_expression,<br>
            -              /*AllowFold*/ false).get();<br>
            +      Scope.InstantiatedLocalPackArg(PatternParam,
            FunctionParam);<br>
            +      ++FParamIdx;<br>
                 }<br>
               }<br>
            <br>
            -  FunctionProtoType::ExceptionSpecInfo ESI;<br>
            -  ESI.Type = Proto->getExceptionSpecType();<br>
            -  ESI.Exceptions = Exceptions;<br>
            -  ESI.NoexceptExpr = NoexceptExpr;<br>
            -<br>
            -  SemaRef.UpdateExceptionSpec(New, ESI);<br>
            +  return false;<br>
             }<br>
            <br>
             void Sema::InstantiateExceptionSpec(SourceLocation
            PointOfInstantiation,<br>
            @@ -3175,11 +3073,14 @@ void
            Sema::InstantiateExceptionSpec(Sour<br>
                 getTemplateInstantiationArgs(Decl, nullptr,
            /*RelativeToPrimary*/true);<br>
            <br>
               FunctionDecl *Template =
            Proto->getExceptionSpecTemplate();<br>
            -  addInstantiatedParametersToScope(*this, Decl, Template,
            Scope, TemplateArgs);<br>
            +  if (addInstantiatedParametersToScope(*this, Decl,
            Template, Scope,<br>
            +                                       TemplateArgs)) {<br>
            +    UpdateExceptionSpec(Decl, EST_None);<br>
            +    return;<br>
            +  }<br>
            <br>
            -  ::InstantiateExceptionSpec(*this, Decl,<br>
            -                           
             Template->getType()->castAs<FunctionProtoType>(),<br>
            -                             TemplateArgs);<br>
            +  SubstExceptionSpec(Decl,
            Template->getType()->castAs<FunctionProtoType>(),<br>
            +                     TemplateArgs);<br>
             }<br>
            <br>
             /// \brief Initializes the common fields of an
            instantiation function<br>
            @@ -3248,7 +3149,7 @@
            TemplateDeclInstantiator::InitFunctionIn<br>
                   New->setType(SemaRef.Context.getFunctionType(<br>
                       NewProto->getReturnType(),
            NewProto->getParamTypes(), EPI));<br>
                 } else {<br>
            -      ::InstantiateExceptionSpec(SemaRef, New, Proto,
            TemplateArgs);<br>
            +      SemaRef.SubstExceptionSpec(New, Proto, TemplateArgs);<br>
                 }<br>
               }<br>
            <br>
            @@ -3438,8 +3339,9 @@ void
            Sema::InstantiateFunctionDefinition<br>
                 MultiLevelTemplateArgumentList TemplateArgs =<br>
                   getTemplateInstantiationArgs(Function, nullptr,
            false, PatternDecl);<br>
            <br>
            -    addInstantiatedParametersToScope(*this, Function,
            PatternDecl, Scope,<br>
            -                                     TemplateArgs);<br>
            +    if (addInstantiatedParametersToScope(*this, Function,
            PatternDecl, Scope,<br>
            +                                         TemplateArgs))<br>
            +      return;<br>
            <br>
                 // If this is a constructor, instantiate the member
            initializers.<br>
                 if (const CXXConstructorDecl *Ctor =<br>
            <br>
            Modified: cfe/trunk/lib/Sema/SemaType.cpp<br>
            URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=217995&r1=217994&r2=217995&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=217995&r1=217994&r2=217995&view=diff</a><br>
==============================================================================<br>
            --- cfe/trunk/lib/Sema/SemaType.cpp (original)<br>
            +++ cfe/trunk/lib/Sema/SemaType.cpp Wed Sep 17 18:57:05 2014<br>
            @@ -2989,7 +2989,8 @@ static TypeSourceInfo
            *GetFullTypeForDec<br>
                       NoexceptExpr = FTI.NoexceptExpr;<br>
                     }<br>
            <br>
            -       
            S.checkExceptionSpecification(FTI.getExceptionSpecType(),<br>
            +       
            S.checkExceptionSpecification(D.isFunctionDeclarationContext(),<br>
            +                                     
            FTI.getExceptionSpecType(),<br>
                                                   DynamicExceptions,<br>
                                                 
             DynamicExceptionRanges,<br>
                                                   NoexceptExpr,<br>
            <br>
            Modified: cfe/trunk/lib/Sema/TreeTransform.h<br>
            URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=217995&r1=217994&r2=217995&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=217995&r1=217994&r2=217995&view=diff</a><br>
==============================================================================<br>
            --- cfe/trunk/lib/Sema/TreeTransform.h (original)<br>
            +++ cfe/trunk/lib/Sema/TreeTransform.h Wed Sep 17 18:57:05
            2014<br>
            @@ -542,10 +542,17 @@ public:<br>
               QualType Transform##CLASS##Type(TypeLocBuilder &TLB,
            CLASS##TypeLoc T);<br>
             #include "clang/AST/TypeLocNodes.def"<br>
            <br>
            +  template<typename Fn><br>
               QualType TransformFunctionProtoType(TypeLocBuilder
            &TLB,<br>
                                                   FunctionProtoTypeLoc
            TL,<br>
                                                   CXXRecordDecl
            *ThisContext,<br>
            -                                      unsigned
            ThisTypeQuals);<br>
            +                                      unsigned
            ThisTypeQuals,<br>
            +                                      Fn
            TransformExceptionSpec);<br>
            +<br>
            +  bool TransformExceptionSpec(SourceLocation Loc,<br>
            +                             
            FunctionProtoType::ExceptionSpecInfo &ESI,<br>
            +                             
            SmallVectorImpl<QualType> &Exceptions,<br>
            +                              bool &Changed);<br>
            <br>
               StmtResult TransformSEHHandler(Stmt *Handler);<br>
            <br>
            @@ -4512,15 +4519,19 @@ template<typename Derived><br>
             QualType<br>
             TreeTransform<Derived>::TransformFunctionProtoType(TypeLocBuilder
            &TLB,<br>
                                                               
            FunctionProtoTypeLoc TL) {<br>
            -  return getDerived().TransformFunctionProtoType(TLB, TL,
            nullptr, 0);<br>
            +  SmallVector<QualType, 4> ExceptionStorage;<br>
            +  return getDerived().TransformFunctionProtoType(<br>
            +      TLB, TL, nullptr, 0,<br>
            +      [&](FunctionProtoType::ExceptionSpecInfo
            &ESI, bool &Changed) {<br>
            +        return TransformExceptionSpec(TL.getBeginLoc(),
            ESI, ExceptionStorage,<br>
            +                                      Changed);<br>
            +      });<br>
             }<br>
            <br>
            -template<typename Derived><br>
            -QualType<br>
            -TreeTransform<Derived>::TransformFunctionProtoType(TypeLocBuilder
            &TLB,<br>
            -                                                 
             FunctionProtoTypeLoc TL,<br>
            -                                                 
             CXXRecordDecl *ThisContext,<br>
            -                                                   unsigned
            ThisTypeQuals) {<br>
            +template<typename Derived> template<typename
            Fn><br>
            +QualType
            TreeTransform<Derived>::TransformFunctionProtoType(<br>
            +    TypeLocBuilder &TLB, FunctionProtoTypeLoc TL,
            CXXRecordDecl *ThisContext,<br>
            +    unsigned ThisTypeQuals, Fn TransformExceptionSpec) {<br>
               // Transform the parameters and return type.<br>
               //<br>
               // We are required to instantiate the params and return
            type in source order.<br>
            @@ -4565,15 +4576,21 @@
            TreeTransform<Derived>::TransformFunctio<br>
                   return QualType();<br>
               }<br>
            <br>
            -  // FIXME: Need to transform the exception-specification
            too.<br>
            +  FunctionProtoType::ExtProtoInfo EPI =
            T->getExtProtoInfo();<br>
            +<br>
            +  bool EPIChanged = false;<br>
            +  if (TransformExceptionSpec(EPI.ExceptionSpec,
            EPIChanged))<br>
            +    return QualType();<br>
            +<br>
            +  // FIXME: Need to transform ConsumedParameters for
            variadic template<br>
            +  // expansion.<br>
            <br>
               QualType Result = TL.getType();<br>
               if (getDerived().AlwaysRebuild() || ResultType !=
            T->getReturnType() ||<br>
                   T->getNumParams() != ParamTypes.size() ||<br>
                   !std::equal(T->param_type_begin(),
            T->param_type_end(),<br>
            -                  ParamTypes.begin())) {<br>
            -    Result =
            getDerived().RebuildFunctionProtoType(ResultType,
            ParamTypes,<br>
            -                                                 
             T->getExtProtoInfo());<br>
            +                  ParamTypes.begin()) || EPIChanged) {<br>
            +    Result =
            getDerived().RebuildFunctionProtoType(ResultType,
            ParamTypes, EPI);<br>
                 if (Result.isNull())<br>
                   return QualType();<br>
               }<br>
            @@ -4590,6 +4607,107 @@
            TreeTransform<Derived>::TransformFunctio<br>
             }<br>
            <br>
             template<typename Derived><br>
            +bool TreeTransform<Derived>::TransformExceptionSpec(<br>
            +    SourceLocation Loc,
            FunctionProtoType::ExceptionSpecInfo &ESI,<br>
            +    SmallVectorImpl<QualType> &Exceptions, bool
            &Changed) {<br>
            +  assert(ESI.Type != EST_Uninstantiated && ESI.Type
            != EST_Unevaluated);<br>
            +<br>
            +  // Instantiate a dynamic noexcept expression, if any.<br>
            +  if (ESI.Type == EST_ComputedNoexcept) {<br>
            +    EnterExpressionEvaluationContext Unevaluated(getSema(),<br>
            +                                               
             Sema::ConstantEvaluated);<br>
            +    ExprResult NoexceptExpr =
            getDerived().TransformExpr(ESI.NoexceptExpr);<br>
            +    if (NoexceptExpr.isInvalid())<br>
            +      return true;<br>
            +<br>
            +    NoexceptExpr = getSema().CheckBooleanCondition(<br>
            +        NoexceptExpr.get(),
            NoexceptExpr.get()->getLocStart());<br>
            +    if (NoexceptExpr.isInvalid())<br>
            +      return true;<br>
            +<br>
            +    if (!NoexceptExpr.get()->isValueDependent()) {<br>
            +      NoexceptExpr =
            getSema().VerifyIntegerConstantExpression(<br>
            +          NoexceptExpr.get(), nullptr,<br>
            +          diag::err_noexcept_needs_constant_expression,<br>
            +          /*AllowFold*/false);<br>
            +      if (NoexceptExpr.isInvalid())<br>
            +        return true;<br>
            +    }<br>
            +<br>
            +    if (ESI.NoexceptExpr != NoexceptExpr.get())<br>
            +      Changed = true;<br>
            +    ESI.NoexceptExpr = NoexceptExpr.get();<br>
            +  }<br>
            +<br>
            +  if (ESI.Type != EST_Dynamic)<br>
            +    return false;<br>
            +<br>
            +  // Instantiate a dynamic exception specification's type.<br>
            +  for (QualType T : ESI.Exceptions) {<br>
            +    if (const PackExpansionType *PackExpansion =<br>
            +            T->getAs<PackExpansionType>()) {<br>
            +      Changed = true;<br>
            +<br>
            +      // We have a pack expansion. Instantiate it.<br>
            +      SmallVector<UnexpandedParameterPack, 2>
            Unexpanded;<br>
            +     
            SemaRef.collectUnexpandedParameterPacks(PackExpansion->getPattern(),<br>
            +                                              Unexpanded);<br>
            +      assert(!Unexpanded.empty() && "Pack expansion
            without parameter packs?");<br>
            +<br>
            +      // Determine whether the set of unexpanded parameter
            packs can and<br>
            +      // should<br>
            +      // be expanded.<br>
            +      bool Expand = false;<br>
            +      bool RetainExpansion = false;<br>
            +      Optional<unsigned> NumExpansions =
            PackExpansion->getNumExpansions();<br>
            +      // FIXME: Track the location of the ellipsis (and
            track source location<br>
            +      // information for the types in the exception
            specification in general).<br>
            +      if (getDerived().TryExpandParameterPacks(<br>
            +              Loc, SourceRange(), Unexpanded, Expand,<br>
            +              RetainExpansion, NumExpansions))<br>
            +        return true;<br>
            +<br>
            +      if (!Expand) {<br>
            +        // We can't expand this pack expansion into
            separate arguments yet;<br>
            +        // just substitute into the pattern and create a
            new pack expansion<br>
            +        // type.<br>
            +        Sema::ArgumentPackSubstitutionIndexRAII
            SubstIndex(getSema(), -1);<br>
            +        QualType U =
            getDerived().TransformType(PackExpansion->getPattern());<br>
            +        if (U.isNull())<br>
            +          return true;<br>
            +<br>
            +        U = SemaRef.Context.getPackExpansionType(U,
            NumExpansions);<br>
            +        Exceptions.push_back(U);<br>
            +        continue;<br>
            +      }<br>
            +<br>
            +      // Substitute into the pack expansion pattern for
            each slice of the<br>
            +      // pack.<br>
            +      for (unsigned ArgIdx = 0; ArgIdx != *NumExpansions;
            ++ArgIdx) {<br>
            +        Sema::ArgumentPackSubstitutionIndexRAII
            SubstIndex(getSema(), ArgIdx);<br>
            +<br>
            +        QualType U =
            getDerived().TransformType(PackExpansion->getPattern());<br>
            +        if (U.isNull() ||
            SemaRef.CheckSpecifiedExceptionType(U, Loc))<br>
            +          return true;<br>
            +<br>
            +        Exceptions.push_back(U);<br>
            +      }<br>
            +    } else {<br>
            +      QualType U = getDerived().TransformType(T);<br>
            +      if (U.isNull() ||
            SemaRef.CheckSpecifiedExceptionType(U, Loc))<br>
            +        return true;<br>
            +      if (T != U)<br>
            +        Changed = true;<br>
            +<br>
            +      Exceptions.push_back(U);<br>
            +    }<br>
            +  }<br>
            +<br>
            +  ESI.Exceptions = Exceptions;<br>
            +  return false;<br>
            +}<br>
            +<br>
            +template<typename Derived><br>
             QualType
            TreeTransform<Derived>::TransformFunctionNoProtoType(<br>
                                                             
            TypeLocBuilder &TLB,<br>
                                                             
            FunctionNoProtoTypeLoc TL) {<br>
            @@ -8895,9 +9013,13 @@
            TreeTransform<Derived>::TransformLambdaE<br>
                 // transformed parameters.<br>
            <br>
                 TypeLocBuilder NewCallOpTLBuilder;<br>
            -    QualType NewCallOpType =
            TransformFunctionProtoType(NewCallOpTLBuilder,<br>
            -                                                       
            OldCallOpFPTL,<br>
            -                                                       
            nullptr, 0);<br>
            +    SmallVector<QualType, 4> ExceptionStorage;<br>
            +    QualType NewCallOpType = TransformFunctionProtoType(<br>
            +        NewCallOpTLBuilder, OldCallOpFPTL, nullptr, 0,<br>
            +        [&](FunctionProtoType::ExceptionSpecInfo
            &ESI, bool &Changed) {<br>
            +          return
            TransformExceptionSpec(OldCallOpFPTL.getBeginLoc(), ESI,<br>
            +                                        ExceptionStorage,
            Changed);<br>
            +        });<br>
                 NewCallOpTSI =
            NewCallOpTLBuilder.getTypeSourceInfo(getSema().Context,<br>
                                                                   
             NewCallOpType);<br>
               }<br>
            <br>
            Modified: cfe/trunk/test/CXX/except/except.spec/p1.cpp<br>
            URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/except/except.spec/p1.cpp?rev=217995&r1=217994&r2=217995&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/except/except.spec/p1.cpp?rev=217995&r1=217994&r2=217995&view=diff</a><br>
==============================================================================<br>
            --- cfe/trunk/test/CXX/except/except.spec/p1.cpp (original)<br>
            +++ cfe/trunk/test/CXX/except/except.spec/p1.cpp Wed Sep 17
            18:57:05 2014<br>
            @@ -77,5 +77,12 @@ namespace PR11084 {<br>
                 static int f() noexcept(1/X) { return 10; }  //
            expected-error{{argument to noexcept specifier must be a
            constant expression}} expected-note{{division by zero}}<br>
               };<br>
            <br>
            -  void g() { A<0>::f(); } // expected-note{{in
            instantiation of exception specification for 'f' requested
            here}}<br>
            +  template<int X> void f() {<br>
            +    int (*p)() noexcept(1/X); // expected-error{{argument
            to noexcept specifier must be a constant expression}}
            expected-note{{division by zero}}<br>
            +  };<br>
            +<br>
            +  void g() {<br>
            +    A<0>::f(); // expected-note{{in instantiation of
            exception specification for 'f'}}<br>
            +    f<0>(); // expected-note{{in instantiation of
            function template specialization}}<br>
            +  }<br>
             }<br>
            <br>
            Modified:
            cfe/trunk/test/SemaTemplate/instantiate-exception-spec-cxx11.cpp<br>
            URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/instantiate-exception-spec-cxx11.cpp?rev=217995&r1=217994&r2=217995&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/instantiate-exception-spec-cxx11.cpp?rev=217995&r1=217994&r2=217995&view=diff</a><br>
==============================================================================<br>
            ---
            cfe/trunk/test/SemaTemplate/instantiate-exception-spec-cxx11.cpp
            (original)<br>
            +++
            cfe/trunk/test/SemaTemplate/instantiate-exception-spec-cxx11.cpp
            Wed Sep 17 18:57:05 2014<br>
            @@ -137,3 +137,37 @@ namespace PR12763 {<br>
               };<br>
               void X::g() {} // expected-note {{in instantiation of}}<br>
             }<br>
            +<br>
            +namespace Variadic {<br>
            +  template<bool B> void check() { static_assert(B,
            ""); }<br>
            +  template<bool B, bool B2, bool ...Bs> void check()
            { static_assert(B, ""); check<B2, Bs...>(); }<br>
            +<br>
            +  template<typename ...T> void consume(T...);<br>
            +<br>
            +  template<typename ...T> void f(void (*...p)() throw
            (T)) {<br>
            +    void (*q[])() = { p... };<br>
            +    consume((p(),0)...);<br>
            +  }<br>
            +  template<bool ...B> void g(void (*...p)() noexcept
            (B)) {<br>
            +    consume((p(),0)...);<br>
            +    check<noexcept(p()) == B ...>();<br>
            +  }<br>
            +  template<typename ...T> void i() {<br>
            +    consume([]() throw(T) {} ...);<br>
            +    consume([]() noexcept(sizeof(T) == 4) {} ...);<br>
            +  }<br>
            +  template<bool ...B> void j() {<br>
            +    consume([](void (*p)() noexcept(B)) {<br>
            +      void (*q)() noexcept = p; // expected-error {{not
            superset of source}}<br>
            +    } ...);<br>
            +  }<br>
            +<br>
            +  void z() {<br>
            +    f<int, char, double>(nullptr, nullptr, nullptr);<br>
            +    g<true, false, true>(nullptr, nullptr, nullptr);<br>
            +    i<int, long, short>();<br>
            +    j<true, true>();<br>
            +    j<true, false>(); // expected-note {{in
            instantiation of}}<br>
            +  }<br>
            +<br>
            +}<br>
            <br>
            Modified:
            cfe/trunk/test/SemaTemplate/instantiate-exception-spec.cpp<br>
            URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/instantiate-exception-spec.cpp?rev=217995&r1=217994&r2=217995&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/instantiate-exception-spec.cpp?rev=217995&r1=217994&r2=217995&view=diff</a><br>
==============================================================================<br>
            ---
            cfe/trunk/test/SemaTemplate/instantiate-exception-spec.cpp
            (original)<br>
            +++
            cfe/trunk/test/SemaTemplate/instantiate-exception-spec.cpp
            Wed Sep 17 18:57:05 2014<br>
            @@ -1,5 +1,7 @@<br>
            -// RUN: %clang_cc1 -fsyntax-only -verify %s<br>
            +// RUN: %clang_cc1 -fexceptions -fcxx-exceptions -verify %s
            -DERRORS<br>
            +// RUN: %clang_cc1 -fexceptions -fcxx-exceptions
            -emit-llvm-only %s<br>
            <br>
            +#ifdef ERRORS<br>
             template<typename T> void f1(T*) throw(T); //
            expected-error{{incomplete type 'Incomplete' is not allowed
            in exception specification}}<br>
             struct Incomplete; // expected-note{{forward}}<br>
            <br>
            @@ -7,3 +9,20 @@ void test_f1(Incomplete *incomplete_p, i<br>
               f1(int_p);<br>
               f1(incomplete_p); // expected-note{{instantiation of}}<br>
             }<br>
            +#endif<br>
            +<br>
            +template<typename T> void f(void (*p)() throw(T)) {<br>
            +#ifdef ERRORS<br>
            +  void (*q)() throw(char) = p; // expected-error {{target
            exception spec}}<br>
            +<br>
            +  extern void (*p2)() throw(T);<br>
            +  void (*q2)() throw(char) = p2; // expected-error {{target
            exception spec}}<br>
            +<br>
            +  extern void (*p3)() throw(char);<br>
            +  void (*q3)() throw(T) = p3; // expected-error {{target
            exception spec}}<br>
            +<br>
            +  void (*q4)() throw(T) = p2; // ok<br>
            +#endif<br>
            +  p();<br>
            +}<br>
            +void g() { f<int>(0); } // expected-note
            {{instantiation of}}<br>
            <br>
            <br>
            _______________________________________________<br>
            cfe-commits mailing list<br>
            <a href="mailto:cfe-commits@cs.uiuc.edu" target="_blank">cfe-commits@cs.uiuc.edu</a><br>
            <a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
          </blockquote>
        </div>
        <br>
      </div>
    </blockquote>
    <br>
  </div></div></div>

</blockquote></div><br></div>