the big refactoring bits of PR3782.

This introduces FunctionType::ExtInfo to hold the calling convention and the
noreturn attribute. The next patch will extend it to include the regparm
attribute and fix the bug.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@99920 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/AnalysisBasedWarnings.cpp b/lib/Sema/AnalysisBasedWarnings.cpp
index 8b79e03..d1f00ca 100644
--- a/lib/Sema/AnalysisBasedWarnings.cpp
+++ b/lib/Sema/AnalysisBasedWarnings.cpp
@@ -154,7 +154,7 @@
         continue;
       }
       Expr *CEE = C->getCallee()->IgnoreParenCasts();
-      if (CEE->getType()->getNoReturnAttr()) {
+      if (getFunctionExtInfo(CEE->getType()).getNoReturn()) {
         NoReturnEdge = true;
         HasFakeEdge = true;
       } else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CEE)) {
@@ -255,7 +255,7 @@
   if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
     ReturnsVoid = FD->getResultType()->isVoidType();
     HasNoReturn = FD->hasAttr<NoReturnAttr>() ||
-                  FD->getType()->getAs<FunctionType>()->getNoReturnAttr();
+       FD->getType()->getAs<FunctionType>()->getNoReturnAttr();
   }
   else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
     ReturnsVoid = MD->getResultType()->isVoidType();
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 9dbe821..b60804a 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -981,25 +981,28 @@
   // other tests to run.
   const FunctionType *OldType = OldQType->getAs<FunctionType>();
   const FunctionType *NewType = New->getType()->getAs<FunctionType>();
-  if (OldType->getCallConv() != CC_Default &&
-      NewType->getCallConv() == CC_Default) {
-    NewQType = Context.getCallConvType(NewQType, OldType->getCallConv());
+  const FunctionType::ExtInfo OldTypeInfo = OldType->getExtInfo();
+  const FunctionType::ExtInfo NewTypeInfo = NewType->getExtInfo();
+  if (OldTypeInfo.getCC() != CC_Default &&
+      NewTypeInfo.getCC() == CC_Default) {
+    NewQType = Context.getCallConvType(NewQType, OldTypeInfo.getCC());
     New->setType(NewQType);
     NewQType = Context.getCanonicalType(NewQType);
-  } else if (!Context.isSameCallConv(OldType->getCallConv(),
-                                     NewType->getCallConv())) {
+  } else if (!Context.isSameCallConv(OldTypeInfo.getCC(),
+                                     NewTypeInfo.getCC())) {
     // Calling conventions really aren't compatible, so complain.
     Diag(New->getLocation(), diag::err_cconv_change)
-      << FunctionType::getNameForCallConv(NewType->getCallConv())
-      << (OldType->getCallConv() == CC_Default)
-      << (OldType->getCallConv() == CC_Default ? "" :
-          FunctionType::getNameForCallConv(OldType->getCallConv()));
+      << FunctionType::getNameForCallConv(NewTypeInfo.getCC())
+      << (OldTypeInfo.getCC() == CC_Default)
+      << (OldTypeInfo.getCC() == CC_Default ? "" :
+          FunctionType::getNameForCallConv(OldTypeInfo.getCC()));
     Diag(Old->getLocation(), diag::note_previous_declaration);
     return true;
   }
 
   // FIXME: diagnose the other way around?
-  if (OldType->getNoReturnAttr() && !NewType->getNoReturnAttr()) {
+  if (OldType->getNoReturnAttr() &&
+      !NewType->getNoReturnAttr()) {
     NewQType = Context.getNoReturnType(NewQType);
     New->setType(NewQType);
     assert(NewQType.isCanonical());
@@ -1093,8 +1096,7 @@
                                          OldProto->isVariadic(),
                                          OldProto->getTypeQuals(),
                                          false, false, 0, 0,
-                                         OldProto->getNoReturnAttr(),
-                                         OldProto->getCallConv());
+                                         OldProto->getExtInfo());
       New->setType(NewQType);
       New->setHasInheritedPrototype();
 
@@ -1175,8 +1177,7 @@
                                            ArgTypes.size(),
                                            OldProto->isVariadic(), 0,
                                            false, false, 0, 0,
-                                           OldProto->getNoReturnAttr(),
-                                           OldProto->getCallConv()));
+                                           OldProto->getExtInfo()));
       return MergeCompatibleFunctionDecls(New, Old);
     }
 
@@ -3351,7 +3352,8 @@
           // Turn this into a variadic function with no parameters.
           QualType R = Context.getFunctionType(
                      NewFD->getType()->getAs<FunctionType>()->getResultType(),
-                     0, 0, true, 0, false, false, 0, 0, false, CC_Default);
+                     0, 0, true, 0, false, false, 0, 0,
+                     FunctionType::ExtInfo());
           NewFD->setType(R);
           return NewFD->setInvalidDecl();
         }
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 6a2a037..49352b5 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -2217,8 +2217,8 @@
                                  Context.getFunctionType(Context.VoidTy,
                                                          0, 0, false, 0,
                                                          /*FIXME*/false, false,
-                                                         0, 0, false,
-                                                         CC_Default),
+                                                         0, 0,
+                                                       FunctionType::ExtInfo()),
                                  /*TInfo=*/0,
                                  /*isExplicit=*/false,
                                  /*isInline=*/true,
@@ -2292,8 +2292,8 @@
                                                            &ArgType, 1,
                                                            false, 0,
                                                            /*FIXME:*/false,
-                                                           false, 0, 0, false,
-                                                           CC_Default),
+                                                           false, 0, 0,
+                                                       FunctionType::ExtInfo()),
                                    /*TInfo=*/0,
                                    /*isExplicit=*/false,
                                    /*isInline=*/true,
@@ -2381,8 +2381,8 @@
                             Context.getFunctionType(RetType, &ArgType, 1,
                                                     false, 0,
                                                     /*FIXME:*/false,
-                                                    false, 0, 0, false,
-                                                    CC_Default),
+                                                    false, 0, 0,
+                                                    FunctionType::ExtInfo()),
                             /*TInfo=*/0, /*isStatic=*/false, /*isInline=*/true);
     CopyAssignment->setAccess(AS_public);
     CopyAssignment->setImplicit();
@@ -2411,8 +2411,7 @@
     QualType Ty = Context.getFunctionType(Context.VoidTy,
                                           0, 0, false, 0,
                                           /*FIXME:*/false,
-                                          false, 0, 0, false,
-                                          CC_Default);
+                                          false, 0, 0, FunctionType::ExtInfo());
 
     DeclarationName Name
       = Context.DeclarationNames.getCXXDestructorName(ClassType);
@@ -2585,8 +2584,7 @@
                                  Proto->hasAnyExceptionSpec(),
                                  Proto->getNumExceptions(),
                                  Proto->exception_begin(),
-                                 Proto->getNoReturnAttr(),
-                                 Proto->getCallConv());
+                                 Proto->getExtInfo());
 }
 
 /// CheckConstructor - Checks a fully-formed constructor for
@@ -2745,7 +2743,7 @@
   // will put in a result type of "int" when none was specified.
   // FIXME: Exceptions!
   return Context.getFunctionType(Context.VoidTy, 0, 0, false, 0,
-                                 false, false, 0, 0, false, CC_Default);
+                                 false, false, 0, 0, FunctionType::ExtInfo());
 }
 
 /// CheckConversionDeclarator - Called by ActOnDeclarator to check the
@@ -2821,8 +2819,7 @@
                               Proto->hasAnyExceptionSpec(),
                               Proto->getNumExceptions(),
                               Proto->exception_begin(),
-                              Proto->getNoReturnAttr(),
-                              Proto->getCallConv());
+                              Proto->getExtInfo());
 
   // C++0x explicit conversion operators.
   if (D.getDeclSpec().isExplicitSpecified() && !getLangOptions().CPlusPlus0x)
diff --git a/lib/Sema/SemaExceptionSpec.cpp b/lib/Sema/SemaExceptionSpec.cpp
index eae30dc..fab94df 100644
--- a/lib/Sema/SemaExceptionSpec.cpp
+++ b/lib/Sema/SemaExceptionSpec.cpp
@@ -134,8 +134,7 @@
                                                NewProto->isVariadic(),
                                                NewProto->getTypeQuals(),
                                                true, false, 0, 0,
-                                               NewProto->getNoReturnAttr(),
-                                               NewProto->getCallConv());
+                                               NewProto->getExtInfo());
     New->setType(NewType);
     return false;
   }
@@ -157,8 +156,7 @@
                                                OldProto->hasAnyExceptionSpec(),
                                                OldProto->getNumExceptions(),
                                                OldProto->exception_begin(),
-                                               NewProto->getNoReturnAttr(),
-                                               NewProto->getCallConv());
+                                               NewProto->getExtInfo());
     New->setType(NewType);
 
     // If exceptions are disabled, suppress the warning about missing
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 4bf26a5..0c9b3bd 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -6851,8 +6851,8 @@
 
     // The parameter list is optional, if there was none, assume ().
     if (!T->isFunctionType())
-      T = Context.getFunctionType(T, 0, 0, false, 0, false, false, 0, 0, false,
-                                  CC_Default);
+      T = Context.getFunctionType(T, 0, 0, false, 0, false, false, 0, 0,
+                                  FunctionType::ExtInfo());
 
     CurBlock->hasPrototype = true;
     CurBlock->isVariadic = false;
@@ -6977,11 +6977,11 @@
   QualType BlockTy;
   if (!BSI->hasPrototype)
     BlockTy = Context.getFunctionType(RetTy, 0, 0, false, 0, false, false, 0, 0,
-                                      NoReturn, CC_Default);
+                                  FunctionType::ExtInfo(NoReturn, CC_Default));
   else
     BlockTy = Context.getFunctionType(RetTy, ArgTypes.data(), ArgTypes.size(),
                                       BSI->isVariadic, 0, false, false, 0, 0,
-                                      NoReturn, CC_Default);
+                                   FunctionType::ExtInfo(NoReturn, CC_Default));
 
   // FIXME: Check that return/parameter types are complete/non-abstract
   DiagnoseUnusedParameters(BSI->Params.begin(), BSI->Params.end());
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index 23c3069..c31d934 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -948,7 +948,8 @@
         = Context.getFunctionType(Context.VoidTy, ArgTypes.data(),
                                   ArgTypes.size(),
                                   Proto->isVariadic(),
-                                  0, false, false, 0, 0, false, CC_Default);
+                                  0, false, false, 0, 0,
+                                  FunctionType::ExtInfo());
     }
 
     for (LookupResult::iterator D = FoundDelete.begin(), 
@@ -1209,7 +1210,8 @@
   QualType FnType = Context.getFunctionType(Return, &Argument, 1, false, 0,
                                             true, false,
                                             HasBadAllocExceptionSpec? 1 : 0,
-                                            &BadAllocType, false, CC_Default);
+                                            &BadAllocType,
+                                            FunctionType::ExtInfo());
   FunctionDecl *Alloc =
     FunctionDecl::Create(Context, GlobalCtx, SourceLocation(), Name,
                          FnType, /*TInfo=*/0, FunctionDecl::None, false, true);
diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp
index f1bf885..a29c4d4 100644
--- a/lib/Sema/SemaLookup.cpp
+++ b/lib/Sema/SemaLookup.cpp
@@ -556,13 +556,13 @@
     // Compute the type of the function that we would expect the conversion
     // function to have, if it were to match the name given.
     // FIXME: Calling convention!
+    FunctionType::ExtInfo ConvProtoInfo = ConvProto->getExtInfo();
     QualType ExpectedType
       = R.getSema().Context.getFunctionType(R.getLookupName().getCXXNameType(),
                                             0, 0, ConvProto->isVariadic(),
                                             ConvProto->getTypeQuals(),
                                             false, false, 0, 0,
-                                            ConvProto->getNoReturnAttr(),
-                                            CC_Default);
+                                    ConvProtoInfo.withCallingConv(CC_Default));
  
     // Perform template argument deduction against the type that we would
     // expect the function to have.
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 81c036b..9777569 100644
--- a/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -1844,8 +1844,7 @@
                                                  Proto->hasAnyExceptionSpec(),
                                                  Exceptions.size(),
                                                  Exceptions.data(),
-                                                 Proto->getNoReturnAttr(),
-                                                 Proto->getCallConv()));
+                                                 Proto->getExtInfo()));
   }
 
   return false;
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index 660718f..099d30a 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -801,7 +801,8 @@
     return QualType();
 
   return Context.getFunctionType(T, ParamTypes, NumParamTypes, Variadic,
-                                 Quals, false, false, 0, 0, false, CC_Default);
+                                 Quals, false, false, 0, 0,
+                                 FunctionType::ExtInfo());
 }
 
 /// \brief Build a member pointer type \c T Class::*.
@@ -1138,7 +1139,7 @@
                                       FTI.hasExceptionSpec,
                                       FTI.hasAnyExceptionSpec,
                                       Exceptions.size(), Exceptions.data(),
-                                      false, CC_Default);
+                                      FunctionType::ExtInfo());
         } else if (FTI.isVariadic) {
           // We allow a zero-parameter variadic function in C if the
           // function is marked with the "overloadable"
@@ -1155,7 +1156,8 @@
           if (!Overloadable)
             Diag(FTI.getEllipsisLoc(), diag::err_ellipsis_first_arg);
           T = Context.getFunctionType(T, NULL, 0, FTI.isVariadic, 0, 
-                                      false, false, 0, 0, false, CC_Default);
+                                      false, false, 0, 0,
+                                      FunctionType::ExtInfo());
         } else {
           // Simple void foo(), where the incoming T is the result type.
           T = Context.getFunctionNoProtoType(T);
@@ -1231,7 +1233,7 @@
                                     FTI.hasExceptionSpec,
                                     FTI.hasAnyExceptionSpec,
                                     Exceptions.size(), Exceptions.data(),
-                                    false, CC_Default);
+                                    FunctionType::ExtInfo());
       }
 
       // For GCC compatibility, we allow attributes that apply only to
@@ -1329,7 +1331,7 @@
       // Strip the cv-quals from the type.
       T = Context.getFunctionType(FnTy->getResultType(), FnTy->arg_type_begin(),
                                   FnTy->getNumArgs(), FnTy->isVariadic(), 0, 
-                                  false, false, 0, 0, false, CC_Default);
+                                  false, false, 0, 0, FunctionType::ExtInfo());
     }
   }