Add noreturn as a type attribute, handle printing for them and handle
calls to noreturn function pointers when CFG building.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@77089 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 91de998..07e1ce7 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -1084,7 +1084,10 @@
     bool NoReturnEdge = false;
     if (CallExpr *C = dyn_cast<CallExpr>(S)) {
       Expr *CEE = C->getCallee()->IgnoreParenCasts();
-      if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CEE)) {
+      if (CEE->getType().getNoReturnAttr()) {
+        NoReturnEdge = true;
+        HasFakeEdge = true;
+      } else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CEE)) {
         if (FunctionDecl *FD = dyn_cast<FunctionDecl>(DRE->getDecl())) {
           if (FD->hasAttr<NoReturnAttr>()) {
             NoReturnEdge = true;
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index a686e1d..226f214 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -1506,6 +1506,22 @@
   Type = S.Context.getObjCGCQualType(Type, GCAttr);
 }
 
+/// HandleNoReturnTypeAttribute - Process the noreturn attribute on the
+/// specified type.  The attribute contains 0 arguments.
+static void HandleNoReturnTypeAttribute(QualType &Type, 
+                                        const AttributeList &Attr, Sema &S) {
+  if (Attr.getNumArgs() != 0)
+    return;
+
+  // We only apply this to a pointer to function or a pointer to block.
+  if (!Type->isFunctionPointerType()
+      && !Type->isBlockPointerType()
+      && !Type->isFunctionType())
+    return;
+
+  Type = S.Context.getNoReturnType(Type);
+}
+
 void Sema::ProcessTypeAttributeList(QualType &Result, const AttributeList *AL) {
   // Scan through and apply attributes to this type where it makes sense.  Some
   // attributes (such as __address_space__, __vector_size__, etc) apply to the
@@ -1522,6 +1538,9 @@
     case AttributeList::AT_objc_gc:
       HandleObjCGCTypeAttribute(Result, *AL, *this);
       break;
+    case AttributeList::AT_noreturn:
+      HandleNoReturnTypeAttribute(Result, *AL, *this);
+      break;
     }
   }
 }