Reintroduce the home for exception specs, and make Sema fill it. However, keep the spec out of the canonical type this time. Net effect is currently nothing, because the spec isn't checked anywhere.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@72498 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index d592cf6..7b36b13 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -729,6 +729,7 @@
         (OldProto = dyn_cast<FunctionProtoType>(OldFuncType))) {
       // The old declaration provided a function prototype, but the
       // new declaration does not. Merge in the prototype.
+      assert(!OldProto->hasExceptionSpec() && "Exception spec in C");
       llvm::SmallVector<QualType, 16> ParamTypes(OldProto->arg_type_begin(),
                                                  OldProto->arg_type_end());
       NewQType = Context.getFunctionType(NewFuncType->getResultType(),
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index ebe3406..6edb290 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -999,6 +999,9 @@
   QualType ClassType = Context.getTypeDeclType(ClassDecl);
   ClassType = Context.getCanonicalType(ClassType);
 
+  // FIXME: Implicit declarations have exception specifications, which are
+  // the union of the specifications of the implicitly called functions.
+
   if (!ClassDecl->hasUserDeclaredConstructor()) {
     // C++ [class.ctor]p5:
     //   A default constructor for a class X is a constructor of class X
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index 19ff9bb..298a6cd 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -716,12 +716,20 @@
         T = Context.IntTy;
         D.setInvalidType(true);
       }
-        
+
       if (FTI.NumArgs == 0) {
         if (getLangOptions().CPlusPlus) {
           // C++ 8.3.5p2: If the parameter-declaration-clause is empty, the
           // function takes no arguments.
-          T = Context.getFunctionType(T, NULL, 0, FTI.isVariadic,FTI.TypeQuals);
+          llvm::SmallVector<QualType, 4> Exceptions;
+          Exceptions.reserve(FTI.NumExceptions);
+          for(unsigned ei = 0, ee = FTI.NumExceptions; ei != ee; ++ei)
+            Exceptions.push_back(
+              QualType::getFromOpaquePtr(FTI.Exceptions[ei]));
+          T = Context.getFunctionType(T, NULL, 0, FTI.isVariadic, FTI.TypeQuals,
+                                      FTI.hasExceptionSpec,
+                                      FTI.hasAnyExceptionSpec,
+                                      FTI.NumExceptions, Exceptions.data());
         } else if (FTI.isVariadic) {
           // We allow a zero-parameter variadic function in C if the
           // function is marked with the "overloadable"
@@ -795,8 +803,17 @@
           
           ArgTys.push_back(ArgTy);
         }
+
+        llvm::SmallVector<QualType, 4> Exceptions;
+        Exceptions.reserve(FTI.NumExceptions);
+        for(unsigned ei = 0, ee = FTI.NumExceptions; ei != ee; ++ei)
+          Exceptions.push_back(QualType::getFromOpaquePtr(FTI.Exceptions[ei]));
+
         T = Context.getFunctionType(T, ArgTys.data(), ArgTys.size(),
-                                    FTI.isVariadic, FTI.TypeQuals);
+                                    FTI.isVariadic, FTI.TypeQuals,
+                                    FTI.hasExceptionSpec,
+                                    FTI.hasAnyExceptionSpec,
+                                    FTI.NumExceptions, Exceptions.data());
       }
       break;
     }