Create a new TypeNodes.def file that enumerates all of the types,
giving them rough classifications (normal types, never-canonical
types, always-dependent types, abstract type representations) and
making it far easier to make sure that we've hit all of the cases when
decoding types. 

Switched some switch() statements on the type class over to using this
mechanism, and filtering out those things we don't care about. For
example, CodeGen should never see always-dependent or non-canonical
types, while debug info generation should never see always-dependent
types. More switch() statements on the type class need to be moved 
over to using this approach, so that we'll get warnings when we add a
new type then fail to account for it somewhere in the compiler.

As part of this, some types have been renamed:

  TypeOfExpr -> TypeOfExprType
  FunctionTypeProto -> FunctionProtoType
  FunctionTypeNoProto -> FunctionNoProtoType

There shouldn't be any functionality change...


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@65591 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index d059201..53aaf51 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -91,7 +91,7 @@
   unsigned NumTagStruct = 0, NumTagUnion = 0, NumTagEnum = 0, NumTagClass = 0;
   unsigned NumObjCInterfaces = 0, NumObjCQualifiedInterfaces = 0;
   unsigned NumObjCQualifiedIds = 0;
-  unsigned NumTypeOfTypes = 0, NumTypeOfExprs = 0;
+  unsigned NumTypeOfTypes = 0, NumTypeOfExprTypes = 0;
   
   for (unsigned i = 0, e = Types.size(); i != e; ++i) {
     Type *T = Types[i];
@@ -111,9 +111,9 @@
       ++NumArray;
     else if (isa<VectorType>(T))
       ++NumVector;
-    else if (isa<FunctionTypeNoProto>(T))
+    else if (isa<FunctionNoProtoType>(T))
       ++NumFunctionNP;
-    else if (isa<FunctionTypeProto>(T))
+    else if (isa<FunctionProtoType>(T))
       ++NumFunctionP;
     else if (isa<TypedefType>(T))
       ++NumTypeName;
@@ -134,8 +134,8 @@
       ++NumObjCQualifiedIds;
     else if (isa<TypeOfType>(T))
       ++NumTypeOfTypes;
-    else if (isa<TypeOfExpr>(T))
-      ++NumTypeOfExprs;
+    else if (isa<TypeOfExprType>(T))
+      ++NumTypeOfExprTypes;
     else {
       QualType(T, 0).dump();
       assert(0 && "Unknown type!");
@@ -164,16 +164,16 @@
   fprintf(stderr, "    %d protocol qualified id types\n",
           NumObjCQualifiedIds);
   fprintf(stderr, "    %d typeof types\n", NumTypeOfTypes);
-  fprintf(stderr, "    %d typeof exprs\n", NumTypeOfExprs);
+  fprintf(stderr, "    %d typeof exprs\n", NumTypeOfExprTypes);
   
   fprintf(stderr, "Total bytes = %d\n", int(NumBuiltin*sizeof(BuiltinType)+
     NumPointer*sizeof(PointerType)+NumArray*sizeof(ArrayType)+
     NumComplex*sizeof(ComplexType)+NumVector*sizeof(VectorType)+
     NumMemberPointer*sizeof(MemberPointerType)+
-    NumFunctionP*sizeof(FunctionTypeProto)+
-    NumFunctionNP*sizeof(FunctionTypeNoProto)+
+    NumFunctionP*sizeof(FunctionProtoType)+
+    NumFunctionNP*sizeof(FunctionNoProtoType)+
     NumTypeName*sizeof(TypedefType)+NumTagged*sizeof(TagType)+
-    NumTypeOfTypes*sizeof(TypeOfType)+NumTypeOfExprs*sizeof(TypeOfExpr)));
+    NumTypeOfTypes*sizeof(TypeOfType)+NumTypeOfExprTypes*sizeof(TypeOfExprType)));
 }
 
 
@@ -293,15 +293,20 @@
   uint64_t Width;
   unsigned Align;
   switch (T->getTypeClass()) {
-  case Type::TypeName: assert(0 && "Not a canonical type!");
+#define TYPE(Class, Base)
+#define ABSTRACT_TYPE(Class, Base)
+#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
+#define DEPENDENT_TYPE(Class, Base) case Type::Class:
+#include "clang/AST/TypeNodes.def"
+    assert(false && "Should not see non-canonical or dependent types");
+    break;
+
   case Type::FunctionNoProto:
   case Type::FunctionProto:
-  default:
+  case Type::IncompleteArray:
     assert(0 && "Incomplete types have no size!");
   case Type::VariableArray:
     assert(0 && "VLAs not implemented yet!");
-  case Type::DependentSizedArray:
-    assert(0 && "Dependently-sized arrays don't have a known size");
   case Type::ConstantArray: {
     const ConstantArrayType *CAT = cast<ConstantArrayType>(T);
     
@@ -390,6 +395,7 @@
     return getTypeInfo(QualType(cast<ExtQualType>(T)->getBaseType(), 0));
   case Type::ObjCQualifiedId:
   case Type::ObjCQualifiedClass:
+  case Type::ObjCQualifiedInterface:
     Width = Target.getPointerWidth(0);
     Align = Target.getPointerAlign(0);
     break;
@@ -441,7 +447,9 @@
     Align = Layout.getAlignment();
     break;
   }
-  case Type::Tagged: {
+  case Type::Record:
+  case Type::CXXRecord:
+  case Type::Enum: {
     const TagType *TT = cast<TagType>(T);
 
     if (TT->getDecl()->isInvalidDecl()) {
@@ -1127,32 +1135,32 @@
   return QualType(New, 0);
 }
 
-/// getFunctionTypeNoProto - Return a K&R style C function type like 'int()'.
+/// getFunctionNoProtoType - Return a K&R style C function type like 'int()'.
 ///
-QualType ASTContext::getFunctionTypeNoProto(QualType ResultTy) {
+QualType ASTContext::getFunctionNoProtoType(QualType ResultTy) {
   // Unique functions, to guarantee there is only one function of a particular
   // structure.
   llvm::FoldingSetNodeID ID;
-  FunctionTypeNoProto::Profile(ID, ResultTy);
+  FunctionNoProtoType::Profile(ID, ResultTy);
   
   void *InsertPos = 0;
-  if (FunctionTypeNoProto *FT = 
-        FunctionTypeNoProtos.FindNodeOrInsertPos(ID, InsertPos))
+  if (FunctionNoProtoType *FT = 
+        FunctionNoProtoTypes.FindNodeOrInsertPos(ID, InsertPos))
     return QualType(FT, 0);
   
   QualType Canonical;
   if (!ResultTy->isCanonical()) {
-    Canonical = getFunctionTypeNoProto(getCanonicalType(ResultTy));
+    Canonical = getFunctionNoProtoType(getCanonicalType(ResultTy));
     
     // Get the new insert position for the node we care about.
-    FunctionTypeNoProto *NewIP =
-      FunctionTypeNoProtos.FindNodeOrInsertPos(ID, InsertPos);
+    FunctionNoProtoType *NewIP =
+      FunctionNoProtoTypes.FindNodeOrInsertPos(ID, InsertPos);
     assert(NewIP == 0 && "Shouldn't be in the map!"); NewIP = NewIP;
   }
   
-  FunctionTypeNoProto *New =new(*this,8)FunctionTypeNoProto(ResultTy,Canonical);
+  FunctionNoProtoType *New =new(*this,8)FunctionNoProtoType(ResultTy,Canonical);
   Types.push_back(New);
-  FunctionTypeNoProtos.InsertNode(New, InsertPos);
+  FunctionNoProtoTypes.InsertNode(New, InsertPos);
   return QualType(New, 0);
 }
 
@@ -1164,12 +1172,12 @@
   // Unique functions, to guarantee there is only one function of a particular
   // structure.
   llvm::FoldingSetNodeID ID;
-  FunctionTypeProto::Profile(ID, ResultTy, ArgArray, NumArgs, isVariadic,
+  FunctionProtoType::Profile(ID, ResultTy, ArgArray, NumArgs, isVariadic,
                              TypeQuals);
 
   void *InsertPos = 0;
-  if (FunctionTypeProto *FTP = 
-        FunctionTypeProtos.FindNodeOrInsertPos(ID, InsertPos))
+  if (FunctionProtoType *FTP = 
+        FunctionProtoTypes.FindNodeOrInsertPos(ID, InsertPos))
     return QualType(FTP, 0);
     
   // Determine whether the type being created is already canonical or not.  
@@ -1191,20 +1199,20 @@
                                 isVariadic, TypeQuals);
     
     // Get the new insert position for the node we care about.
-    FunctionTypeProto *NewIP =
-      FunctionTypeProtos.FindNodeOrInsertPos(ID, InsertPos);
+    FunctionProtoType *NewIP =
+      FunctionProtoTypes.FindNodeOrInsertPos(ID, InsertPos);
     assert(NewIP == 0 && "Shouldn't be in the map!"); NewIP = NewIP;
   }
   
-  // FunctionTypeProto objects are allocated with extra bytes after them
+  // FunctionProtoType objects are allocated with extra bytes after them
   // for a variable size array (for parameter types) at the end of them.
-  FunctionTypeProto *FTP = 
-    (FunctionTypeProto*)Allocate(sizeof(FunctionTypeProto) + 
+  FunctionProtoType *FTP = 
+    (FunctionProtoType*)Allocate(sizeof(FunctionProtoType) + 
                                  NumArgs*sizeof(QualType), 8);
-  new (FTP) FunctionTypeProto(ResultTy, ArgArray, NumArgs, isVariadic,
+  new (FTP) FunctionProtoType(ResultTy, ArgArray, NumArgs, isVariadic,
                               TypeQuals, Canonical);
   Types.push_back(FTP);
-  FunctionTypeProtos.InsertNode(FTP, InsertPos);
+  FunctionProtoTypes.InsertNode(FTP, InsertPos);
   return QualType(FTP, 0);
 }
 
@@ -1252,7 +1260,7 @@
   if (Decl->TypeForDecl) return QualType(Decl->TypeForDecl, 0);
   
   QualType Canonical = getCanonicalType(Decl->getUnderlyingType());
-  Decl->TypeForDecl = new(*this,8) TypedefType(Type::TypeName, Decl, Canonical);
+  Decl->TypeForDecl = new(*this,8) TypedefType(Type::Typedef, Decl, Canonical);
   Types.push_back(Decl->TypeForDecl);
   return QualType(Decl->TypeForDecl, 0);
 }
@@ -1401,14 +1409,14 @@
   return QualType(QType, 0);
 }
 
-/// getTypeOfExpr - Unlike many "get<Type>" functions, we can't unique
-/// TypeOfExpr AST's (since expression's are never shared). For example,
+/// getTypeOfExprType - Unlike many "get<Type>" functions, we can't unique
+/// TypeOfExprType AST's (since expression's are never shared). For example,
 /// multiple declarations that refer to "typeof(x)" all contain different
 /// DeclRefExpr's. This doesn't effect the type checker, since it operates 
 /// on canonical type's (which are always unique).
-QualType ASTContext::getTypeOfExpr(Expr *tofExpr) {
+QualType ASTContext::getTypeOfExprType(Expr *tofExpr) {
   QualType Canonical = getCanonicalType(tofExpr->getType());
-  TypeOfExpr *toe = new (*this,8) TypeOfExpr(tofExpr, Canonical);
+  TypeOfExprType *toe = new (*this,8) TypeOfExprType(tofExpr, Canonical);
   Types.push_back(toe);
   return QualType(toe, 0);
 }
@@ -2458,8 +2466,8 @@
 bool ASTContext::typesAreBlockCompatible(QualType lhs, QualType rhs) {
   const FunctionType *lbase = lhs->getAsFunctionType();
   const FunctionType *rbase = rhs->getAsFunctionType();
-  const FunctionTypeProto *lproto = dyn_cast<FunctionTypeProto>(lbase);
-  const FunctionTypeProto *rproto = dyn_cast<FunctionTypeProto>(rbase);
+  const FunctionProtoType *lproto = dyn_cast<FunctionProtoType>(lbase);
+  const FunctionProtoType *rproto = dyn_cast<FunctionProtoType>(rbase);
   if (lproto && rproto)
     return !mergeTypes(lhs, rhs).isNull();
   return false;
@@ -2561,8 +2569,8 @@
 QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs) {
   const FunctionType *lbase = lhs->getAsFunctionType();
   const FunctionType *rbase = rhs->getAsFunctionType();
-  const FunctionTypeProto *lproto = dyn_cast<FunctionTypeProto>(lbase);
-  const FunctionTypeProto *rproto = dyn_cast<FunctionTypeProto>(rbase);
+  const FunctionProtoType *lproto = dyn_cast<FunctionProtoType>(lbase);
+  const FunctionProtoType *rproto = dyn_cast<FunctionProtoType>(rbase);
   bool allLTypes = true;
   bool allRTypes = true;
 
@@ -2611,7 +2619,7 @@
   if (lproto) allRTypes = false;
   if (rproto) allLTypes = false;
 
-  const FunctionTypeProto *proto = lproto ? lproto : rproto;
+  const FunctionProtoType *proto = lproto ? lproto : rproto;
   if (proto) {
     if (proto->isVariadic()) return QualType();
     // Check that the types are compatible with the types that
@@ -2636,7 +2644,7 @@
 
   if (allLTypes) return lhs;
   if (allRTypes) return rhs;
-  return getFunctionTypeNoProto(retType);
+  return getFunctionNoProtoType(retType);
 }
 
 QualType ASTContext::mergeTypes(QualType LHS, QualType RHS) {
@@ -2739,6 +2747,27 @@
 
   // The canonical type classes match.
   switch (LHSClass) {
+#define TYPE(Class, Base)
+#define ABSTRACT_TYPE(Class, Base)
+#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
+#define DEPENDENT_TYPE(Class, Base) case Type::Class:
+#include "clang/AST/TypeNodes.def"
+    assert(false && "Non-canonical and dependent types shouldn't get here");
+    return QualType();
+
+  case Type::Reference:
+  case Type::MemberPointer:
+    assert(false && "C++ should never be in mergeTypes");
+    return QualType();
+
+  case Type::IncompleteArray:
+  case Type::VariableArray:
+  case Type::FunctionProto:
+  case Type::ExtVector:
+  case Type::ObjCQualifiedInterface:
+    assert(false && "Types are eliminated above");
+    return QualType();
+
   case Type::Pointer:
   {
     // Merge two pointer types, while trying to preserve typedef info
@@ -2808,7 +2837,9 @@
   }
   case Type::FunctionNoProto:
     return mergeFunctionTypes(LHS, RHS);
-  case Type::Tagged:
+  case Type::Record:
+  case Type::CXXRecord:
+  case Type::Enum:
     // FIXME: Why are these compatible?
     if (isObjCIdStructType(LHS) && isObjCClassStructType(RHS)) return LHS;
     if (isObjCClassStructType(LHS) && isObjCIdStructType(RHS)) return LHS;
@@ -2836,10 +2867,9 @@
   case Type::ObjCQualifiedId:
     // Distinct qualified id's are not compatible.
     return QualType();
-  default:
-    assert(0 && "unexpected type");
-    return QualType();
   }
+
+  return QualType();
 }
 
 //===----------------------------------------------------------------------===//
diff --git a/lib/AST/Builtins.cpp b/lib/AST/Builtins.cpp
index b572e8e..46b0346 100644
--- a/lib/AST/Builtins.cpp
+++ b/lib/AST/Builtins.cpp
@@ -264,7 +264,7 @@
 
   // handle untyped/variadic arguments "T c99Style();" or "T cppStyle(...);".
   if (ArgTypes.size() == 0 && TypeStr[0] == '.')
-    return Context.getFunctionTypeNoProto(ResType);
+    return Context.getFunctionNoProtoType(ResType);
   return Context.getFunctionType(ResType, &ArgTypes[0], ArgTypes.size(),
                                  TypeStr[0] == '.', 0);
 }
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index ab65492..b30b869 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -320,9 +320,9 @@
 // Helper function for FunctionDecl::getNumParams and FunctionDecl::setParams()
 static unsigned getNumTypeParams(QualType T) {
   const FunctionType *FT = T->getAsFunctionType();
-  if (isa<FunctionTypeNoProto>(FT))
+  if (isa<FunctionNoProtoType>(FT))
     return 0;
-  return cast<FunctionTypeProto>(FT)->getNumArgs();
+  return cast<FunctionProtoType>(FT)->getNumArgs();
 }
 
 unsigned FunctionDecl::getNumParams() const {
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp
index 294e94f..b1394fe 100644
--- a/lib/AST/DeclCXX.cpp
+++ b/lib/AST/DeclCXX.cpp
@@ -92,8 +92,8 @@
     if (Method->isStatic())
       continue;
     // TODO: Skip templates? Or is this implicitly done due to parameter types?
-    const FunctionTypeProto *FnType =
-      Method->getType()->getAsFunctionTypeProto();
+    const FunctionProtoType *FnType =
+      Method->getType()->getAsFunctionProtoType();
     assert(FnType && "Overloaded operator has no prototype.");
     // Don't assert on this; an invalid decl might have been left in the AST.
     if (FnType->getNumArgs() != 1 || FnType->isVariadic())
@@ -146,7 +146,7 @@
   // We're interested specifically in copy assignment operators.
   // Unlike addedConstructor, this method is not called for implicit
   // declarations.
-  const FunctionTypeProto *FnType = OpDecl->getType()->getAsFunctionTypeProto();
+  const FunctionProtoType *FnType = OpDecl->getType()->getAsFunctionProtoType();
   assert(FnType && "Overloaded operator has no proto function type.");
   assert(FnType->getNumArgs() == 1 && !FnType->isVariadic());
   QualType ArgType = FnType->getArgType(0);
@@ -290,7 +290,7 @@
     return false;
 
   return (getNumParams() == 0 && 
-          getType()->getAsFunctionTypeProto()->isVariadic()) ||
+          getType()->getAsFunctionProtoType()->isVariadic()) ||
          (getNumParams() == 1) ||
          (getNumParams() > 1 && getParamDecl(1)->getDefaultArg() != 0);
 }
diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp
index 1d563e2..4468c79 100644
--- a/lib/AST/StmtPrinter.cpp
+++ b/lib/AST/StmtPrinter.cpp
@@ -1193,9 +1193,9 @@
   
   const FunctionType *AFT = Node->getFunctionType();
   
-  if (isa<FunctionTypeNoProto>(AFT)) {
+  if (isa<FunctionNoProtoType>(AFT)) {
     OS << "()";
-  } else if (!BD->param_empty() || cast<FunctionTypeProto>(AFT)->isVariadic()) {
+  } else if (!BD->param_empty() || cast<FunctionProtoType>(AFT)->isVariadic()) {
     OS << '(';
     std::string ParamStr;
     for (BlockDecl::param_iterator AI = BD->param_begin(),
@@ -1206,7 +1206,7 @@
       OS << ParamStr;
     }
     
-    const FunctionTypeProto *FT = cast<FunctionTypeProto>(AFT);
+    const FunctionProtoType *FT = cast<FunctionProtoType>(AFT);
     if (FT->isVariadic()) {
       if (!BD->param_empty()) OS << ", ";
       OS << "...";
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index 3156508..06ae9eb 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -78,7 +78,7 @@
 QualType Type::getDesugaredType() const {
   if (const TypedefType *TDT = dyn_cast<TypedefType>(this))
     return TDT->LookThroughTypedefs();
-  if (const TypeOfExpr *TOE = dyn_cast<TypeOfExpr>(this))
+  if (const TypeOfExprType *TOE = dyn_cast<TypeOfExprType>(this))
     return TOE->getUnderlyingExpr()->getType();
   if (const TypeOfType *TOT = dyn_cast<TypeOfType>(this))
     return TOT->getUnderlyingType();
@@ -118,9 +118,9 @@
   case FunctionProto:
   case FunctionNoProto:
   case Reference:
+  case Record:
+  case CXXRecord:
     return true;
-  case Tagged:
-    return !cast<TagType>(CanonicalType)->getDecl()->isEnum();
   default:
     return false;
   }
@@ -216,12 +216,12 @@
   return getDesugaredType()->getAsFunctionType();
 }
 
-const FunctionTypeNoProto *Type::getAsFunctionTypeNoProto() const {
-  return dyn_cast_or_null<FunctionTypeNoProto>(getAsFunctionType());
+const FunctionNoProtoType *Type::getAsFunctionNoProtoType() const {
+  return dyn_cast_or_null<FunctionNoProtoType>(getAsFunctionType());
 }
 
-const FunctionTypeProto *Type::getAsFunctionTypeProto() const {
-  return dyn_cast_or_null<FunctionTypeProto>(getAsFunctionType());
+const FunctionProtoType *Type::getAsFunctionProtoType() const {
+  return dyn_cast_or_null<FunctionProtoType>(getAsFunctionType());
 }
 
 
@@ -742,7 +742,9 @@
     // Void is the only incomplete builtin type.  Per C99 6.2.5p19, it can never
     // be completed.
     return isVoidType();
-  case Tagged:
+  case Record:
+  case CXXRecord:
+  case Enum:
     // A tagged type (struct/union/enum/class) is incomplete if the decl is a
     // forward declaration, but not a full definition (C99 6.2.5p22).
     return !cast<TagType>(CanonicalType)->getDecl()->isDefinition();
@@ -778,14 +780,15 @@
   case ObjCQualifiedId:
     return true;
 
-  case Tagged:
-    if (isEnumeralType())
-      return true;
-    if (CXXRecordDecl *RDecl = dyn_cast<CXXRecordDecl>(
-          cast<TagType>(CanonicalType)->getDecl()))
-      return RDecl->isPOD();
+  case Enum:
+    return true;
+
+  case Record:
     // C struct/union is POD.
     return true;
+
+  case CXXRecord:
+    return cast<CXXRecordType>(CanonicalType)->getDecl()->isPOD();
   }
 }
 
@@ -832,7 +835,7 @@
   }
 }
 
-void FunctionTypeProto::Profile(llvm::FoldingSetNodeID &ID, QualType Result,
+void FunctionProtoType::Profile(llvm::FoldingSetNodeID &ID, QualType Result,
                                 arg_type_iterator ArgTys,
                                 unsigned NumArgs, bool isVariadic,
                                 unsigned TypeQuals) {
@@ -843,7 +846,7 @@
   ID.AddInteger(TypeQuals);
 }
 
-void FunctionTypeProto::Profile(llvm::FoldingSetNodeID &ID) {
+void FunctionProtoType::Profile(llvm::FoldingSetNodeID &ID) {
   Profile(ID, getResultType(), arg_type_begin(), NumArgs, isVariadic(),
           getTypeQuals());
 }
@@ -903,8 +906,8 @@
   }
 }
 
-TypeOfExpr::TypeOfExpr(Expr *E, QualType can)
-  : Type(TypeOfExp, can, E->isTypeDependent()), TOExpr(E) {
+TypeOfExprType::TypeOfExprType(Expr *E, QualType can)
+  : Type(TypeOfExpr, can, E->isTypeDependent()), TOExpr(E) {
   assert(!isa<TypedefType>(can) && "Invalid canonical type");
 }
 
@@ -1197,7 +1200,7 @@
   ElementType.getAsStringInternal(S);
 }
 
-void TypeOfExpr::getAsStringInternal(std::string &InnerString) const {
+void TypeOfExprType::getAsStringInternal(std::string &InnerString) const {
   if (!InnerString.empty())    // Prefix the basic type, e.g. 'typeof(e) X'.
     InnerString = ' ' + InnerString;
   std::string Str;
@@ -1214,7 +1217,7 @@
   InnerString = "typeof(" + Tmp + ")" + InnerString;
 }
 
-void FunctionTypeNoProto::getAsStringInternal(std::string &S) const {
+void FunctionNoProtoType::getAsStringInternal(std::string &S) const {
   // If needed for precedence reasons, wrap the inner part in grouping parens.
   if (!S.empty())
     S = "(" + S + ")";
@@ -1223,7 +1226,7 @@
   getResultType().getAsStringInternal(S);
 }
 
-void FunctionTypeProto::getAsStringInternal(std::string &S) const {
+void FunctionProtoType::getAsStringInternal(std::string &S) const {
   // If needed for precedence reasons, wrap the inner part in grouping parens.
   if (!S.empty())
     S = "(" + S + ")";
diff --git a/lib/AST/TypeSerialization.cpp b/lib/AST/TypeSerialization.cpp
index a8580b0..2d052aa 100644
--- a/lib/AST/TypeSerialization.cpp
+++ b/lib/AST/TypeSerialization.cpp
@@ -84,11 +84,11 @@
       break;
       
     case Type::FunctionNoProto:
-      D.RegisterPtr(PtrID,FunctionTypeNoProto::CreateImpl(Context,D));
+      D.RegisterPtr(PtrID,FunctionNoProtoType::CreateImpl(Context,D));
       break;
       
     case Type::FunctionProto:
-      D.RegisterPtr(PtrID,FunctionTypeProto::CreateImpl(Context,D));
+      D.RegisterPtr(PtrID,FunctionProtoType::CreateImpl(Context,D));
       break;
       
     case Type::IncompleteArray:
@@ -111,19 +111,22 @@
       D.RegisterPtr(PtrID, ReferenceType::CreateImpl(Context, D));
       break;
 
-    case Type::Tagged:
-      D.RegisterPtr(PtrID, TagType::CreateImpl(Context, D));
+    case Type::Record:
+    case Type::CXXRecord:
+    case Type::Enum:
+      // FIXME: Implement this!
+      assert(false && "Can't deserialize tag types!");
       break;
 
-    case Type::TypeName:
+    case Type::Typedef:
       D.RegisterPtr(PtrID, TypedefType::CreateImpl(Context, D));
       break;
 
-    case Type::TypeOfExp:
-      D.RegisterPtr(PtrID, TypeOfExpr::CreateImpl(Context, D));
+    case Type::TypeOfExpr:
+      D.RegisterPtr(PtrID, TypeOfExprType::CreateImpl(Context, D));
       break;
 
-    case Type::TypeOfTyp:
+    case Type::TypeOf:
       D.RegisterPtr(PtrID, TypeOfType::CreateImpl(Context, D));
       break;
 
@@ -199,22 +202,22 @@
 }
 
 //===----------------------------------------------------------------------===//
-// FunctionTypeNoProto
+// FunctionNoProtoType
 //===----------------------------------------------------------------------===//
 
-void FunctionTypeNoProto::EmitImpl(Serializer& S) const {
+void FunctionNoProtoType::EmitImpl(Serializer& S) const {
   S.Emit(getResultType());
 }
 
-Type* FunctionTypeNoProto::CreateImpl(ASTContext& Context, Deserializer& D) {
-  return Context.getFunctionTypeNoProto(QualType::ReadVal(D)).getTypePtr();
+Type* FunctionNoProtoType::CreateImpl(ASTContext& Context, Deserializer& D) {
+  return Context.getFunctionNoProtoType(QualType::ReadVal(D)).getTypePtr();
 }
 
 //===----------------------------------------------------------------------===//
-// FunctionTypeProto
+// FunctionProtoType
 //===----------------------------------------------------------------------===//
 
-void FunctionTypeProto::EmitImpl(Serializer& S) const {
+void FunctionProtoType::EmitImpl(Serializer& S) const {
   S.Emit(getResultType());
   S.EmitBool(isVariadic());
   S.EmitInt(getTypeQuals());
@@ -224,7 +227,7 @@
     S.Emit(*I);
 }
 
-Type* FunctionTypeProto::CreateImpl(ASTContext& Context, Deserializer& D) {
+Type* FunctionProtoType::CreateImpl(ASTContext& Context, Deserializer& D) {
   QualType ResultType = QualType::ReadVal(D);
   bool isVariadic = D.ReadBool();
   unsigned TypeQuals = D.ReadInt();
@@ -290,7 +293,9 @@
   std::vector<Type*>& Types = 
     const_cast<std::vector<Type*>&>(Context.getTypes());
   
-  TagType* T = new TagType(NULL,QualType());
+  // FIXME: This is wrong: we need the subclasses to do the
+  // (de-)serialization.
+  TagType* T = new TagType(Record, NULL,QualType());
   Types.push_back(T);
   
   // Deserialize the decl.
@@ -313,7 +318,7 @@
   std::vector<Type*>& Types = 
     const_cast<std::vector<Type*>&>(Context.getTypes());
   
-  TypedefType* T = new TypedefType(Type::TypeName, NULL, QualType::ReadVal(D));
+  TypedefType* T = new TypedefType(Type::Typedef, NULL, QualType::ReadVal(D));
   Types.push_back(T);
   
   D.ReadPtr(T->Decl); // May be backpatched.
@@ -321,20 +326,21 @@
 }
 
 //===----------------------------------------------------------------------===//
-// TypeOfExpr
+// TypeOfExprType
 //===----------------------------------------------------------------------===//
 
-void TypeOfExpr::EmitImpl(llvm::Serializer& S) const {
+void TypeOfExprType::EmitImpl(llvm::Serializer& S) const {
   S.EmitOwnedPtr(TOExpr);
 }
 
-Type* TypeOfExpr::CreateImpl(ASTContext& Context, Deserializer& D) {
+Type* TypeOfExprType::CreateImpl(ASTContext& Context, Deserializer& D) {
   Expr* E = D.ReadOwnedPtr<Expr>(Context);
   
   std::vector<Type*>& Types = 
     const_cast<std::vector<Type*>&>(Context.getTypes());
 
-  TypeOfExpr* T = new TypeOfExpr(E, Context.getCanonicalType(E->getType()));
+  TypeOfExprType* T 
+    = new TypeOfExprType(E, Context.getCanonicalType(E->getType()));
   Types.push_back(T);
 
   return T;
diff --git a/lib/Analysis/CFRefCount.cpp b/lib/Analysis/CFRefCount.cpp
index 8f694fa..d42a936 100644
--- a/lib/Analysis/CFRefCount.cpp
+++ b/lib/Analysis/CFRefCount.cpp
@@ -956,7 +956,7 @@
 
   // Sanity check that this is *really* a unary function.  This can
   // happen if people do weird things.
-  const FunctionTypeProto* FTP = dyn_cast<FunctionTypeProto>(FT);
+  const FunctionProtoType* FTP = dyn_cast<FunctionProtoType>(FT);
   if (!FTP || FTP->getNumArgs() != 1)
     return getPersistentStopSummary();
   
diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp
index 25cd4f7..8f7b674 100644
--- a/lib/Analysis/GRExprEngine.cpp
+++ b/lib/Analysis/GRExprEngine.cpp
@@ -1127,10 +1127,10 @@
                              NodeSet& Dst)
 {
   // Determine the type of function we're calling (if available).
-  const FunctionTypeProto *Proto = NULL;
+  const FunctionProtoType *Proto = NULL;
   QualType FnType = CE->getCallee()->IgnoreParens()->getType();
   if (const PointerType *FnTypePtr = FnType->getAsPointerType())
-    Proto = FnTypePtr->getPointeeType()->getAsFunctionTypeProto();
+    Proto = FnTypePtr->getPointeeType()->getAsFunctionProtoType();
 
   VisitCallRec(CE, Pred, AI, AE, Dst, Proto, /*ParamIdx=*/0);
 }
@@ -1138,7 +1138,7 @@
 void GRExprEngine::VisitCallRec(CallExpr* CE, NodeTy* Pred,
                                 CallExpr::arg_iterator AI,
                                 CallExpr::arg_iterator AE,
-                                NodeSet& Dst, const FunctionTypeProto *Proto,
+                                NodeSet& Dst, const FunctionProtoType *Proto,
                                 unsigned ParamIdx) {
   
   // Process the arguments.
diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp
index 65f6cb1..276c46f 100644
--- a/lib/CodeGen/CGBlocks.cpp
+++ b/lib/CodeGen/CGBlocks.cpp
@@ -321,12 +321,12 @@
 /// function type for the block, including the first block literal argument.
 static QualType getBlockFunctionType(ASTContext &Ctx,
                                      const BlockPointerType *BPT) {
-  const FunctionTypeProto *FTy = cast<FunctionTypeProto>(BPT->getPointeeType());
+  const FunctionProtoType *FTy = cast<FunctionProtoType>(BPT->getPointeeType());
 
   llvm::SmallVector<QualType, 8> Types;
   Types.push_back(Ctx.getPointerType(Ctx.VoidTy));
 
-  for (FunctionTypeProto::arg_type_iterator i = FTy->arg_type_begin(),
+  for (FunctionProtoType::arg_type_iterator i = FTy->arg_type_begin(),
        e = FTy->arg_type_end(); i != e; ++i)
     Types.push_back(*i);
 
@@ -455,9 +455,9 @@
                                                        const BlockInfo& Info,
                                                        uint64_t &Size,
                                                        uint64_t &Align,
-                                                       llvm::SmallVector<ValueDecl *, 8> &subBlockDeclRefDecls) {
-  const FunctionTypeProto *FTy =
-    cast<FunctionTypeProto>(Expr->getFunctionType());
+                    llvm::SmallVector<ValueDecl *, 8> &subBlockDeclRefDecls) {
+  const FunctionProtoType *FTy =
+    cast<FunctionProtoType>(Expr->getFunctionType());
 
   FunctionArgList Args;
 
diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp
index 7a98b0c..38f6e96 100644
--- a/lib/CodeGen/CGCall.cpp
+++ b/lib/CodeGen/CGCall.cpp
@@ -37,13 +37,13 @@
 // FIXME: Use iterator and sidestep silly type array creation.
 
 const 
-CGFunctionInfo &CodeGenTypes::getFunctionInfo(const FunctionTypeNoProto *FTNP) {
+CGFunctionInfo &CodeGenTypes::getFunctionInfo(const FunctionNoProtoType *FTNP) {
   return getFunctionInfo(FTNP->getResultType(), 
                          llvm::SmallVector<QualType, 16>());
 }
 
 const 
-CGFunctionInfo &CodeGenTypes::getFunctionInfo(const FunctionTypeProto *FTP) {
+CGFunctionInfo &CodeGenTypes::getFunctionInfo(const FunctionProtoType *FTP) {
   llvm::SmallVector<QualType, 16> ArgTys;
   // FIXME: Kill copy.
   for (unsigned i = 0, e = FTP->getNumArgs(); i != e; ++i)
@@ -53,9 +53,9 @@
 
 const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const FunctionDecl *FD) {
   const FunctionType *FTy = FD->getType()->getAsFunctionType();
-  if (const FunctionTypeProto *FTP = dyn_cast<FunctionTypeProto>(FTy))
+  if (const FunctionProtoType *FTP = dyn_cast<FunctionProtoType>(FTy))
     return getFunctionInfo(FTP);
-  return getFunctionInfo(cast<FunctionTypeNoProto>(FTy));
+  return getFunctionInfo(cast<FunctionNoProtoType>(FTy));
 }
 
 const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const ObjCMethodDecl *MD) {
diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp
index 5e78c58..6c67ba5 100644
--- a/lib/CodeGen/CGDebugInfo.cpp
+++ b/lib/CodeGen/CGDebugInfo.cpp
@@ -179,7 +179,7 @@
   
   // Set up remainder of arguments if there is a prototype.
   // FIXME: IF NOT, HOW IS THIS REPRESENTED?  llvm-gcc doesn't represent '...'!
-  if (const FunctionTypeProto *FTP = dyn_cast<FunctionTypeProto>(Ty)) {
+  if (const FunctionProtoType *FTP = dyn_cast<FunctionProtoType>(Ty)) {
     for (unsigned i = 0, e = FTP->getNumArgs(); i != e; ++i)
       EltTys.push_back(getOrCreateType(FTP->getArgType(i), Unit));
   } else {
@@ -481,6 +481,13 @@
 
   // Work out details of type.
   switch (Ty->getTypeClass()) {
+#define TYPE(Class, Base)
+#define ABSTRACT_TYPE(Class, Base)
+#define NON_CANONICAL_TYPE(Class, Base)
+#define DEPENDENT_TYPE(Class, Base) case Type::Class:
+#include "clang/AST/TypeNodes.def"
+    assert(false && "Dependent types cannot show up in debug information");
+    
   case Type::Complex:
   case Type::Reference:
   case Type::Vector:
@@ -489,13 +496,16 @@
   case Type::ObjCInterface:
   case Type::ObjCQualifiedInterface:
   case Type::ObjCQualifiedId:
-  default:
     return llvm::DIType();
 
   case Type::Builtin: Slot = CreateType(cast<BuiltinType>(Ty), Unit); break;
   case Type::Pointer: Slot = CreateType(cast<PointerType>(Ty), Unit); break;
-  case Type::TypeName: Slot = CreateType(cast<TypedefType>(Ty), Unit); break;
-  case Type::Tagged: Slot = CreateType(cast<TagType>(Ty), Unit); break;
+  case Type::Typedef: Slot = CreateType(cast<TypedefType>(Ty), Unit); break;
+  case Type::Record:
+  case Type::CXXRecord:
+  case Type::Enum:
+    Slot = CreateType(cast<TagType>(Ty), Unit); 
+    break;
   case Type::FunctionProto:
   case Type::FunctionNoProto:
     return Slot = CreateType(cast<FunctionType>(Ty), Unit);
@@ -504,10 +514,10 @@
   case Type::VariableArray:
   case Type::IncompleteArray:
     return Slot = CreateType(cast<ArrayType>(Ty), Unit);
-  case Type::TypeOfExp:
-    return Slot = getOrCreateType(cast<TypeOfExpr>(Ty)->getUnderlyingExpr()
+  case Type::TypeOfExpr:
+    return Slot = getOrCreateType(cast<TypeOfExprType>(Ty)->getUnderlyingExpr()
                                   ->getType(), Unit);
-  case Type::TypeOfTyp:
+  case Type::TypeOf:
     return Slot = getOrCreateType(cast<TypeOfType>(Ty)->getUnderlyingType(),
                                   Unit);
   }
diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp
index 81fd387..d6e3394 100644
--- a/lib/CodeGen/CodeGenFunction.cpp
+++ b/lib/CodeGen/CodeGenFunction.cpp
@@ -209,7 +209,7 @@
   
   FunctionArgList Args;
   if (FD->getNumParams()) {
-    const FunctionTypeProto* FProto = FD->getType()->getAsFunctionTypeProto();
+    const FunctionProtoType* FProto = FD->getType()->getAsFunctionProtoType();
     assert(FProto && "Function def must have prototype!");
 
     for (unsigned i = 0, e = FD->getNumParams(); i != e; ++i)
diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h
index 918646f..057f554 100644
--- a/lib/CodeGen/CodeGenFunction.h
+++ b/lib/CodeGen/CodeGenFunction.h
@@ -41,7 +41,7 @@
   class Decl;
   class EnumConstantDecl;
   class FunctionDecl;
-  class FunctionTypeProto;
+  class FunctionProtoType;
   class LabelStmt;
   class ObjCContainerDecl;
   class ObjCInterfaceDecl;
diff --git a/lib/CodeGen/CodeGenTypes.cpp b/lib/CodeGen/CodeGenTypes.cpp
index 1458ccd..0912183 100644
--- a/lib/CodeGen/CodeGenTypes.cpp
+++ b/lib/CodeGen/CodeGenTypes.cpp
@@ -174,13 +174,14 @@
   const clang::Type &Ty = *Context.getCanonicalType(T);
   
   switch (Ty.getTypeClass()) {
-  case Type::TypeName:        // typedef isn't canonical.
-  case Type::TemplateTypeParm:// template type parameters never generated
-  case Type::ClassTemplateSpecialization: // these types are always sugar
-  case Type::DependentSizedArray: // dependent types are never generated
-  case Type::TypeOfExp:       // typeof isn't canonical.
-  case Type::TypeOfTyp:       // typeof isn't canonical.
-    assert(0 && "Non-canonical type, shouldn't happen");
+#define TYPE(Class, Base)
+#define ABSTRACT_TYPE(Class, Base)
+#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
+#define DEPENDENT_TYPE(Class, Base) case Type::Class:
+#include "clang/AST/TypeNodes.def"
+    assert(false && "Non-canonical or dependent types aren't possible.");
+    break;
+
   case Type::Builtin: {
     switch (cast<BuiltinType>(Ty).getKind()) {
     default: assert(0 && "Unknown builtin type!");
@@ -265,10 +266,10 @@
                                  VT.getNumElements());
   }
   case Type::FunctionNoProto:
-    return GetFunctionType(getFunctionInfo(cast<FunctionTypeNoProto>(&Ty)), 
+    return GetFunctionType(getFunctionInfo(cast<FunctionNoProtoType>(&Ty)), 
                            true);
   case Type::FunctionProto: {
-    const FunctionTypeProto *FTP = cast<FunctionTypeProto>(&Ty);
+    const FunctionProtoType *FTP = cast<FunctionProtoType>(&Ty);
     return GetFunctionType(getFunctionInfo(FTP), FTP->isVariadic());
   }
   
@@ -300,7 +301,9 @@
     // Protocols don't influence the LLVM type.
     return ConvertTypeRecursive(Context.getObjCIdType());
 
-  case Type::Tagged: {
+  case Type::Record:
+  case Type::CXXRecord:
+  case Type::Enum: {
     const TagDecl *TD = cast<TagType>(Ty).getDecl();
     const llvm::Type *Res = ConvertTagDeclType(TD);
     
diff --git a/lib/CodeGen/CodeGenTypes.h b/lib/CodeGen/CodeGenTypes.h
index 228502d..e5dbd84 100644
--- a/lib/CodeGen/CodeGenTypes.h
+++ b/lib/CodeGen/CodeGenTypes.h
@@ -33,7 +33,7 @@
   class ABIInfo;
   class ASTContext;
   class FieldDecl;
-  class FunctionTypeProto;
+  class FunctionProtoType;
   class ObjCInterfaceDecl;
   class ObjCIvarDecl;
   class PointerType;
@@ -166,8 +166,8 @@
                                         const llvm::SmallVector<QualType,16> 
                                         &ArgTys);
 
-  const CGFunctionInfo &getFunctionInfo(const FunctionTypeNoProto *FTNP);
-  const CGFunctionInfo &getFunctionInfo(const FunctionTypeProto *FTP);
+  const CGFunctionInfo &getFunctionInfo(const FunctionNoProtoType *FTNP);
+  const CGFunctionInfo &getFunctionInfo(const FunctionProtoType *FTP);
   const CGFunctionInfo &getFunctionInfo(const FunctionDecl *FD);
   const CGFunctionInfo &getFunctionInfo(const ObjCMethodDecl *MD);
   const CGFunctionInfo &getFunctionInfo(QualType ResTy, 
diff --git a/lib/CodeGen/Mangle.cpp b/lib/CodeGen/Mangle.cpp
index c802966..525f0fe 100644
--- a/lib/CodeGen/Mangle.cpp
+++ b/lib/CodeGen/Mangle.cpp
@@ -454,10 +454,10 @@
   if (MangleReturnType)
     mangleType(T->getResultType());
 
-  const FunctionTypeProto *Proto = dyn_cast<FunctionTypeProto>(T);
+  const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(T);
   assert(Proto && "Can't mangle K&R function prototypes");
 
-  for (FunctionTypeProto::arg_type_iterator Arg = Proto->arg_type_begin(),
+  for (FunctionProtoType::arg_type_iterator Arg = Proto->arg_type_begin(),
                                          ArgEnd = Proto->arg_type_end(); 
        Arg != ArgEnd; ++Arg)
     mangleType(*Arg);
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index 68e0ce8..22bfee4 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -458,7 +458,7 @@
                               Expr *From, QualType ToType,
                               OverloadCandidateSet& CandidateSet);
   void AddSurrogateCandidate(CXXConversionDecl *Conversion,
-                             const FunctionTypeProto *Proto,
+                             const FunctionProtoType *Proto,
                              Expr *Object, Expr **Args, unsigned NumArgs,
                              OverloadCandidateSet& CandidateSet);
   bool AddOperatorCandidates(OverloadedOperatorKind Op, Scope *S,
@@ -1107,7 +1107,7 @@
                                                     IdentifierInfo &Member);
   bool ConvertArgumentsForCall(CallExpr *Call, Expr *Fn,
                                FunctionDecl *FDecl,
-                               const FunctionTypeProto *Proto,
+                               const FunctionProtoType *Proto,
                                Expr **Args, unsigned NumArgs,
                                SourceLocation RParenLoc);
 
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp
index fdd22fa..3e6bd5a 100644
--- a/lib/Sema/SemaChecking.cpp
+++ b/lib/Sema/SemaChecking.cpp
@@ -144,8 +144,8 @@
   if (const FormatAttr *Format = FDecl->getAttr<FormatAttr>()) {
     if (Format->getType() == "printf") {
       bool HasVAListArg = false;
-      if (const FunctionTypeProto *Proto 
-          = FDecl->getType()->getAsFunctionTypeProto())
+      if (const FunctionProtoType *Proto 
+          = FDecl->getType()->getAsFunctionProtoType())
         HasVAListArg = !Proto->isVariadic();
       CheckPrintfArguments(TheCall, HasVAListArg, Format->getFormatIdx() - 1,
                            Format->getFirstArg() - 1);
@@ -210,8 +210,8 @@
   // Determine whether the current function is variadic or not.
   bool isVariadic;
   if (getCurFunctionDecl()) {
-    if (FunctionTypeProto* FTP =
-            dyn_cast<FunctionTypeProto>(getCurFunctionDecl()->getType()))
+    if (FunctionProtoType* FTP =
+            dyn_cast<FunctionProtoType>(getCurFunctionDecl()->getType()))
       isVariadic = FTP->isVariadic();
     else
       isVariadic = false;
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 0ad3839..b3f2500 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -340,7 +340,7 @@
 
   // Create Decl objects for each parameter, adding them to the
   // FunctionDecl.
-  if (FunctionTypeProto *FT = dyn_cast<FunctionTypeProto>(R)) {
+  if (FunctionProtoType *FT = dyn_cast<FunctionProtoType>(R)) {
     llvm::SmallVector<ParmVarDecl*, 16> Params;
     for (unsigned i = 0, e = FT->getNumArgs(); i != e; ++i)
       Params.push_back(ParmVarDecl::Create(Context, New, SourceLocation(), 0,
@@ -609,9 +609,9 @@
   if (!getLangOptions().CPlusPlus &&
       Context.typesAreCompatible(OldQType, NewQType)) {
     const FunctionType *NewFuncType = NewQType->getAsFunctionType();
-    const FunctionTypeProto *OldProto = 0;
-    if (isa<FunctionTypeNoProto>(NewFuncType) &&
-        (OldProto = OldQType->getAsFunctionTypeProto())) {
+    const FunctionProtoType *OldProto = 0;
+    if (isa<FunctionNoProtoType>(NewFuncType) &&
+        (OldProto = OldQType->getAsFunctionProtoType())) {
       // The old declaration provided a function prototype, but the
       // new declaration does not. Merge in the prototype.
       llvm::SmallVector<QualType, 16> ParamTypes(OldProto->arg_type_begin(),
@@ -625,7 +625,7 @@
 
       // Synthesize a parameter for each argument type.
       llvm::SmallVector<ParmVarDecl*, 16> Params;
-      for (FunctionTypeProto::arg_type_iterator 
+      for (FunctionProtoType::arg_type_iterator 
              ParamType = OldProto->arg_type_begin(), 
              ParamEnd = OldProto->arg_type_end();
            ParamType != ParamEnd; ++ParamType) {
@@ -1834,7 +1834,7 @@
     // typedef void fn(int);
     // fn f;
     // @endcode
-    const FunctionTypeProto *FT = R->getAsFunctionTypeProto();
+    const FunctionProtoType *FT = R->getAsFunctionProtoType();
     if (!FT) {
       // This is a typedef of a function with no prototype, so we
       // don't need to do anything.
@@ -1845,7 +1845,7 @@
     } else {
       // Synthesize a parameter for each argument type.
       llvm::SmallVector<ParmVarDecl*, 16> Params;
-      for (FunctionTypeProto::arg_type_iterator ArgType = FT->arg_type_begin();
+      for (FunctionProtoType::arg_type_iterator ArgType = FT->arg_type_begin();
            ArgType != FT->arg_type_end(); ++ArgType) {
         ParmVarDecl *Param = ParmVarDecl::Create(Context, DC,
                                                  SourceLocation(), 0,
@@ -1900,7 +1900,7 @@
 
       // Functions marked "overloadable" must have a prototype (that
       // we can't get through declaration merging).
-      if (!R->getAsFunctionTypeProto()) {
+      if (!R->getAsFunctionProtoType()) {
         Diag(NewFD->getLocation(), diag::err_attribute_overloadable_no_prototype)
           << NewFD;
         InvalidDecl = true;
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index fb8b795..8757005 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -56,7 +56,7 @@
 /// isFunctionOrMethod.
 static bool hasFunctionProto(Decl *d) {
   if (const FunctionType *FnTy = getFunctionType(d)) {
-    return isa<FunctionTypeProto>(FnTy);
+    return isa<FunctionProtoType>(FnTy);
   } else {
     assert(isa<ObjCMethodDecl>(d));
     return true;
@@ -68,20 +68,20 @@
 /// hasFunctionProto first).
 static unsigned getFunctionOrMethodNumArgs(Decl *d) {
   if (const FunctionType *FnTy = getFunctionType(d))
-    return cast<FunctionTypeProto>(FnTy)->getNumArgs();
+    return cast<FunctionProtoType>(FnTy)->getNumArgs();
   return cast<ObjCMethodDecl>(d)->param_size();
 }
 
 static QualType getFunctionOrMethodArgType(Decl *d, unsigned Idx) {
   if (const FunctionType *FnTy = getFunctionType(d))
-    return cast<FunctionTypeProto>(FnTy)->getArgType(Idx);
+    return cast<FunctionProtoType>(FnTy)->getArgType(Idx);
   
   return cast<ObjCMethodDecl>(d)->param_begin()[Idx]->getType();
 }
 
 static bool isFunctionOrMethodVariadic(Decl *d) {
   if (const FunctionType *FnTy = getFunctionType(d)) {
-    const FunctionTypeProto *proto = cast<FunctionTypeProto>(FnTy);
+    const FunctionProtoType *proto = cast<FunctionProtoType>(FnTy);
     return proto->isVariadic();
   } else {
     return cast<ObjCMethodDecl>(d)->isVariadic();
@@ -688,7 +688,7 @@
 
   if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) {
     QualType FT = FD->getType();
-    if (!FT->getAsFunctionTypeProto()->isVariadic()) {
+    if (!FT->getAsFunctionProtoType()->isVariadic()) {
       S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic);
       return;
     }    
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 8dd409b..1c98529 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -1077,7 +1077,7 @@
       << SourceRange(D.getDeclSpec().getTypeSpecTypeLoc())
       << SourceRange(D.getIdentifierLoc());
   } 
-  if (R->getAsFunctionTypeProto()->getTypeQuals() != 0) {
+  if (R->getAsFunctionProtoType()->getTypeQuals() != 0) {
     DeclaratorChunk::FunctionTypeInfo &FTI = D.getTypeObject(0).Fun;
     if (FTI.TypeQuals & QualType::Const)
       Diag(D.getIdentifierLoc(), diag::err_invalid_qualified_constructor)
@@ -1095,7 +1095,7 @@
   // return type, since constructors don't have return types. We
   // *always* have to do this, because GetTypeForDeclarator will
   // put in a result type of "int" when none was specified.
-  const FunctionTypeProto *Proto = R->getAsFunctionTypeProto();
+  const FunctionProtoType *Proto = R->getAsFunctionProtoType();
   R = Context.getFunctionType(Context.VoidTy, Proto->arg_type_begin(),
                               Proto->getNumArgs(),
                               Proto->isVariadic(),
@@ -1187,7 +1187,7 @@
       << SourceRange(D.getDeclSpec().getTypeSpecTypeLoc())
       << SourceRange(D.getIdentifierLoc());
   }
-  if (R->getAsFunctionTypeProto()->getTypeQuals() != 0) {
+  if (R->getAsFunctionProtoType()->getTypeQuals() != 0) {
     DeclaratorChunk::FunctionTypeInfo &FTI = D.getTypeObject(0).Fun;
     if (FTI.TypeQuals & QualType::Const)
       Diag(D.getIdentifierLoc(), diag::err_invalid_qualified_destructor)
@@ -1201,7 +1201,7 @@
   }
 
   // Make sure we don't have any parameters.
-  if (R->getAsFunctionTypeProto()->getNumArgs() > 0) {
+  if (R->getAsFunctionProtoType()->getNumArgs() > 0) {
     Diag(D.getIdentifierLoc(), diag::err_destructor_with_params);
 
     // Delete the parameters.
@@ -1209,7 +1209,7 @@
   }
 
   // Make sure the destructor isn't variadic.  
-  if (R->getAsFunctionTypeProto()->isVariadic())
+  if (R->getAsFunctionProtoType()->isVariadic())
     Diag(D.getIdentifierLoc(), diag::err_destructor_variadic);
 
   // Rebuild the function type "R" without any type qualifiers or
@@ -1258,7 +1258,7 @@
   }
 
   // Make sure we don't have any parameters.
-  if (R->getAsFunctionTypeProto()->getNumArgs() > 0) {
+  if (R->getAsFunctionProtoType()->getNumArgs() > 0) {
     Diag(D.getIdentifierLoc(), diag::err_conv_function_with_params);
 
     // Delete the parameters.
@@ -1266,7 +1266,7 @@
   }
 
   // Make sure the conversion function isn't variadic.  
-  if (R->getAsFunctionTypeProto()->isVariadic())
+  if (R->getAsFunctionProtoType()->isVariadic())
     Diag(D.getIdentifierLoc(), diag::err_conv_function_variadic);
 
   // C++ [class.conv.fct]p4:
@@ -1285,7 +1285,7 @@
   // of the errors above fired) and with the conversion type as the
   // return type. 
   R = Context.getFunctionType(ConvType, 0, 0, false, 
-                              R->getAsFunctionTypeProto()->getTypeQuals());
+                              R->getAsFunctionProtoType()->getTypeQuals());
 
   // C++0x explicit conversion operators.
   if (D.getDeclSpec().isExplicitSpecified() && !getLangOptions().CPlusPlus0x)
@@ -2122,7 +2122,7 @@
 
   // Overloaded operators other than operator() cannot be variadic.
   if (Op != OO_Call &&
-      FnDecl->getType()->getAsFunctionTypeProto()->isVariadic()) {
+      FnDecl->getType()->getAsFunctionProtoType()->isVariadic()) {
     return Diag(FnDecl->getLocation(), diag::err_operator_overload_variadic)
       << FnDecl->getDeclName();
   }
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 01be6b2..29d5f59 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -887,8 +887,8 @@
       // type.
       QualType T = Func->getType();
       QualType NoProtoType = T;
-      if (const FunctionTypeProto *Proto = T->getAsFunctionTypeProto())
-        NoProtoType = Context.getFunctionTypeNoProto(Proto->getResultType());
+      if (const FunctionProtoType *Proto = T->getAsFunctionProtoType())
+        NoProtoType = Context.getFunctionNoProtoType(Proto->getResultType());
       return Owned(BuildDeclRefExpr(VD, NoProtoType, Loc, false, false, SS));
     }
   }
@@ -1949,7 +1949,7 @@
 bool
 Sema::ConvertArgumentsForCall(CallExpr *Call, Expr *Fn,
                               FunctionDecl *FDecl,
-                              const FunctionTypeProto *Proto,
+                              const FunctionProtoType *Proto,
                               Expr **Args, unsigned NumArgs,
                               SourceLocation RParenLoc) {
   // C99 6.5.2.2p7 - the arguments are implicitly converted, as if by
@@ -2164,12 +2164,12 @@
   // We know the result type of the call, set it.
   TheCall->setType(FuncT->getResultType().getNonReferenceType());
 
-  if (const FunctionTypeProto *Proto = dyn_cast<FunctionTypeProto>(FuncT)) {
+  if (const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FuncT)) {
     if (ConvertArgumentsForCall(&*TheCall, Fn, FDecl, Proto, Args, NumArgs,
                                 RParenLoc))
       return ExprError();
   } else {
-    assert(isa<FunctionTypeNoProto>(FuncT) && "Unknown FunctionType!");
+    assert(isa<FunctionNoProtoType>(FuncT) && "Unknown FunctionType!");
 
     // Promote the arguments (C99 6.5.2.2p6).
     for (unsigned i = 0; i != NumArgs; i++) {
@@ -4501,7 +4501,7 @@
 
   QualType BlockTy;
   if (!BSI->hasPrototype)
-    BlockTy = Context.getFunctionTypeNoProto(RetTy);
+    BlockTy = Context.getFunctionNoProtoType(RetTy);
   else
     BlockTy = Context.getFunctionType(RetTy, &ArgTypes[0], ArgTypes.size(),
                                       BSI->isVariadic, 0);
diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp
index 7c5464a..00849a6 100644
--- a/lib/Sema/SemaLookup.cpp
+++ b/lib/Sema/SemaLookup.cpp
@@ -1269,12 +1269,12 @@
                                       Context,
                                       AssociatedNamespaces, AssociatedClasses);
 
-    const FunctionTypeProto *Proto = dyn_cast<FunctionTypeProto>(FunctionType);
+    const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FunctionType);
     if (!Proto)
       return;
 
     // Argument types
-    for (FunctionTypeProto::arg_type_iterator Arg = Proto->arg_type_begin(),
+    for (FunctionProtoType::arg_type_iterator Arg = Proto->arg_type_begin(),
                                            ArgEnd = Proto->arg_type_end(); 
          Arg != ArgEnd; ++Arg)
       addAssociatedClassesAndNamespaces(*Arg, Context,
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index 5392af4..c33389e 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -310,12 +310,12 @@
 
     // If either of these functions is a K&R-style function (no
     // prototype), then we consider them to have matching signatures.
-    if (isa<FunctionTypeNoProto>(OldQType.getTypePtr()) ||
-        isa<FunctionTypeNoProto>(NewQType.getTypePtr()))
+    if (isa<FunctionNoProtoType>(OldQType.getTypePtr()) ||
+        isa<FunctionNoProtoType>(NewQType.getTypePtr()))
       return false;
 
-    FunctionTypeProto* OldType = cast<FunctionTypeProto>(OldQType.getTypePtr());
-    FunctionTypeProto* NewType = cast<FunctionTypeProto>(NewQType.getTypePtr());
+    FunctionProtoType* OldType = cast<FunctionProtoType>(OldQType.getTypePtr());
+    FunctionProtoType* NewType = cast<FunctionProtoType>(NewQType.getTypePtr());
 
     // The signature of a function includes the types of its
     // parameters (C++ 1.3.10), which includes the presence or absence
@@ -1052,10 +1052,10 @@
   // differences in the argument and result types are in Objective-C
   // pointer conversions. If so, we permit the conversion (but
   // complain about it).
-  const FunctionTypeProto *FromFunctionType 
-    = FromPointeeType->getAsFunctionTypeProto();
-  const FunctionTypeProto *ToFunctionType
-    = ToPointeeType->getAsFunctionTypeProto();
+  const FunctionProtoType *FromFunctionType 
+    = FromPointeeType->getAsFunctionProtoType();
+  const FunctionProtoType *ToFunctionType
+    = ToPointeeType->getAsFunctionProtoType();
   if (FromFunctionType && ToFunctionType) {
     // If the function types are exactly the same, this isn't an
     // Objective-C pointer conversion.
@@ -1985,8 +1985,8 @@
                            OverloadCandidateSet& CandidateSet,
                            bool SuppressUserConversions)
 {
-  const FunctionTypeProto* Proto 
-    = dyn_cast<FunctionTypeProto>(Function->getType()->getAsFunctionType());
+  const FunctionProtoType* Proto 
+    = dyn_cast<FunctionProtoType>(Function->getType()->getAsFunctionType());
   assert(Proto && "Functions without a prototype cannot be overloaded");
   assert(!isa<CXXConversionDecl>(Function) && 
          "Use AddConversionCandidate for conversion functions");
@@ -2075,8 +2075,8 @@
                          OverloadCandidateSet& CandidateSet,
                          bool SuppressUserConversions)
 {
-  const FunctionTypeProto* Proto 
-    = dyn_cast<FunctionTypeProto>(Method->getType()->getAsFunctionType());
+  const FunctionProtoType* Proto 
+    = dyn_cast<FunctionProtoType>(Method->getType()->getAsFunctionType());
   assert(Proto && "Methods without a prototype cannot be overloaded");
   assert(!isa<CXXConversionDecl>(Method) && 
          "Use AddConversionCandidate for conversion functions");
@@ -2228,7 +2228,7 @@
 /// with the given arguments (C++ [over.call.object]p2-4). Proto is
 /// the type of function that we'll eventually be calling.
 void Sema::AddSurrogateCandidate(CXXConversionDecl *Conversion,
-                                 const FunctionTypeProto *Proto,
+                                 const FunctionProtoType *Proto,
                                  Expr *Object, Expr **Args, unsigned NumArgs,
                                  OverloadCandidateSet& CandidateSet) {
   CandidateSet.push_back(OverloadCandidate());
@@ -2318,7 +2318,7 @@
   if (T1->isRecordType() || (!T2.isNull() && T2->isRecordType()))
     return true;
 
-  const FunctionTypeProto *Proto = Fn->getType()->getAsFunctionTypeProto();
+  const FunctionProtoType *Proto = Fn->getType()->getAsFunctionProtoType();
   if (Proto->getNumArgs() < 1)
     return false;
 
@@ -3773,7 +3773,7 @@
   MemExpr->setBase(ObjectArg);
 
   // Convert the rest of the arguments
-  const FunctionTypeProto *Proto = cast<FunctionTypeProto>(Method->getType());
+  const FunctionProtoType *Proto = cast<FunctionProtoType>(Method->getType());
   if (ConvertArgumentsForCall(&*TheCall, MemExpr, Method, Proto, Args, NumArgs, 
                               RParenLoc))
     return true;
@@ -3842,7 +3842,7 @@
     if (const PointerType *ConvPtrType = ConvType->getAsPointerType())
       ConvType = ConvPtrType->getPointeeType();
 
-    if (const FunctionTypeProto *Proto = ConvType->getAsFunctionTypeProto())
+    if (const FunctionProtoType *Proto = ConvType->getAsFunctionProtoType())
       AddSurrogateCandidate(Conv, Proto, Object, Args, NumArgs, CandidateSet);
   }
 
@@ -3909,7 +3909,7 @@
   // that calls this method, using Object for the implicit object
   // parameter and passing along the remaining arguments.
   CXXMethodDecl *Method = cast<CXXMethodDecl>(Best->Function);
-  const FunctionTypeProto *Proto = Method->getType()->getAsFunctionTypeProto();
+  const FunctionProtoType *Proto = Method->getType()->getAsFunctionProtoType();
 
   unsigned NumArgsInProto = Proto->getNumArgs();
   unsigned NumArgsToCheck = NumArgs;
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index 47cf8e5..d1dcca6 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -172,7 +172,7 @@
     Expr *E = static_cast<Expr *>(DS.getTypeRep());
     assert(E && "Didn't get an expression for typeof?");
     // TypeQuals handled by caller.
-    Result = Context.getTypeOfExpr(E);
+    Result = Context.getTypeOfExprType(E);
     break;
   }
   case DeclSpec::TST_error:
@@ -505,7 +505,7 @@
           T = Context.getFunctionType(T, NULL, 0, FTI.isVariadic, 0);
         } else {
           // Simple void foo(), where the incoming T is the result type.
-          T = Context.getFunctionTypeNoProto(T);
+          T = Context.getFunctionNoProtoType(T);
         }
       } else if (FTI.ArgInfo[0].Param == 0) {
         // C99 6.7.5.3p3: Reject int(x,y,z) when it's not a function definition.
@@ -540,7 +540,7 @@
           
           // Look for 'void'.  void is allowed only as a single argument to a
           // function with no other parameters (C99 6.7.5.3p10).  We record
-          // int(void) as a FunctionTypeProto with an empty argument list.
+          // int(void) as a FunctionProtoType with an empty argument list.
           else if (ArgTy->isVoidType()) {
             // If this is something like 'float(int, void)', reject it.  'void'
             // is an incomplete type (C99 6.2.5p19) and function decls cannot
@@ -634,8 +634,8 @@
   }
 
   if (getLangOptions().CPlusPlus && T->isFunctionType()) {
-    const FunctionTypeProto *FnTy = T->getAsFunctionTypeProto();
-    assert(FnTy && "Why oh why is there not a FunctionTypeProto here ?");
+    const FunctionProtoType *FnTy = T->getAsFunctionProtoType();
+    assert(FnTy && "Why oh why is there not a FunctionProtoType here ?");
 
     // C++ 8.3.5p4: A cv-qualifier-seq shall only be part of the function type
     // for a nonstatic member function, the function type to which a pointer