Reintroduce r127617: "Code generation for noexcept." with fixes.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@127685 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CGException.cpp b/lib/CodeGen/CGException.cpp
index f05bc70..7fdfe70 100644
--- a/lib/CodeGen/CGException.cpp
+++ b/lib/CodeGen/CGException.cpp
@@ -449,19 +449,23 @@
   if (Proto == 0)
     return;
 
-  // FIXME: What about noexcept?
-  if (!Proto->hasDynamicExceptionSpec())
-    return;
+  ExceptionSpecificationType EST = Proto->getExceptionSpecType();
+  if (isNoexceptExceptionSpec(EST)) {
+    if (Proto->getNoexceptSpec(getContext()) == FunctionProtoType::NR_Nothrow) {
+      // noexcept functions are simple terminate scopes.
+      EHStack.pushTerminate();
+    }
+  } else if (EST == EST_Dynamic || EST == EST_DynamicNone) {
+    unsigned NumExceptions = Proto->getNumExceptions();
+    EHFilterScope *Filter = EHStack.pushFilter(NumExceptions);
 
-  unsigned NumExceptions = Proto->getNumExceptions();
-  EHFilterScope *Filter = EHStack.pushFilter(NumExceptions);
-
-  for (unsigned I = 0; I != NumExceptions; ++I) {
-    QualType Ty = Proto->getExceptionType(I);
-    QualType ExceptType = Ty.getNonReferenceType().getUnqualifiedType();
-    llvm::Value *EHType = CGM.GetAddrOfRTTIDescriptor(ExceptType,
-                                                      /*ForEH=*/true);
-    Filter->setFilter(I, EHType);
+    for (unsigned I = 0; I != NumExceptions; ++I) {
+      QualType Ty = Proto->getExceptionType(I);
+      QualType ExceptType = Ty.getNonReferenceType().getUnqualifiedType();
+      llvm::Value *EHType = CGM.GetAddrOfRTTIDescriptor(ExceptType,
+                                                        /*ForEH=*/true);
+      Filter->setFilter(I, EHType);
+    }
   }
 }
 
@@ -476,10 +480,14 @@
   if (Proto == 0)
     return;
 
-  if (!Proto->hasDynamicExceptionSpec())
-    return;
-
-  EHStack.popFilter();
+  ExceptionSpecificationType EST = Proto->getExceptionSpecType();
+  if (isNoexceptExceptionSpec(EST)) {
+    if (Proto->getNoexceptSpec(getContext()) == FunctionProtoType::NR_Nothrow) {
+      EHStack.popTerminate();
+    }
+  } else if (EST == EST_Dynamic || EST == EST_DynamicNone) {
+    EHStack.popFilter();
+  }
 }
 
 void CodeGenFunction::EmitCXXTryStmt(const CXXTryStmt &S) {