]> granicus.if.org Git - clang/commitdiff
Move type compatibility predicates from Type to ASTContext. In addition, the predicat...
authorSteve Naroff <snaroff@apple.com>
Mon, 15 Oct 2007 20:41:53 +0000 (20:41 +0000)
committerSteve Naroff <snaroff@apple.com>
Mon, 15 Oct 2007 20:41:53 +0000 (20:41 +0000)
This allowed me to fix the following hack from this weekend...

// FIXME: Devise a way to do this without using strcmp.
// Would like to say..."return getAsStructureType() == IdStructType;", but
// we don't have a pointer to ASTContext.
bool Type::isObjcIdType() const {
  if (const RecordType *RT = getAsStructureType())
    return !strcmp(RT->getDecl()->getName(), "objc_object");
  return false;
}

...which is now...

bool isObjcIdType(QualType T) const {
  return T->getAsStructureType() == IdStructType;
}

Side notes:

- I had to remove a convenience function from the TypesCompatibleExpr class.

int typesAreCompatible() const {return Type::typesAreCompatible(Type1,Type2);}

Which required a couple clients get a little more verbose...

-    Result = TCE->typesAreCompatible();
+    Result = Ctx.typesAreCompatible(TCE->getArgType1(), TCE->getArgType2());

Overall, I think this change also makes sense for a couple reasons...

1) Since ASTContext vends types, it makes sense for the type compatibility API to be there.
2) This allows the type compatibility predeciates to refer to data not strictly present in the AST (which I have found problematic on several occasions).

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@43009 91177308-0d34-0410-b5e6-96231b3b80d8

AST/ASTContext.cpp
AST/Expr.cpp
AST/Type.cpp
CodeGen/CGExprScalar.cpp
Sema/SemaExpr.cpp
clang.xcodeproj/project.pbxproj
include/clang/AST/ASTContext.h
include/clang/AST/Expr.h
include/clang/AST/Type.h

index 93446824b1eda75dc70aaa478ea3fee187ebd097..86cf13c4f6e1236ee1c9ce9cc558cb845b2afeb5 100644 (file)
@@ -855,3 +855,166 @@ void ASTContext::setObjcIdType(TypedefDecl *TD)
   IdStructType = rec;
 }
 
+bool ASTContext::builtinTypesAreCompatible(QualType lhs, QualType rhs) {
+  const BuiltinType *lBuiltin = lhs->getAsBuiltinType();
+  const BuiltinType *rBuiltin = rhs->getAsBuiltinType();
+  
+  return lBuiltin->getKind() == rBuiltin->getKind();
+}
+
+
+bool ASTContext::objcTypesAreCompatible(QualType lhs, QualType rhs) {
+  if (lhs->isObjcInterfaceType() && isObjcIdType(rhs))
+    return true;
+  else if (isObjcIdType(lhs) && rhs->isObjcInterfaceType())
+    return true;
+  return false;
+}
+
+bool ASTContext::interfaceTypesAreCompatible(QualType lhs, QualType rhs) {
+  return true; // FIXME: IMPLEMENT.
+}
+
+// C99 6.2.7p1: If both are complete types, then the following additional
+// requirements apply...FIXME (handle compatibility across source files).
+bool ASTContext::tagTypesAreCompatible(QualType lhs, QualType rhs) {
+  TagDecl *ldecl = cast<TagType>(lhs.getCanonicalType())->getDecl();
+  TagDecl *rdecl = cast<TagType>(rhs.getCanonicalType())->getDecl();
+  
+  if (ldecl->getKind() == Decl::Struct && rdecl->getKind() == Decl::Struct) {
+    if (ldecl->getIdentifier() == rdecl->getIdentifier())
+      return true;
+  }
+  if (ldecl->getKind() == Decl::Union && rdecl->getKind() == Decl::Union) {
+    if (ldecl->getIdentifier() == rdecl->getIdentifier())
+      return true;
+  }
+  return false;
+}
+
+bool ASTContext::pointerTypesAreCompatible(QualType lhs, QualType rhs) {
+  // C99 6.7.5.1p2: For two pointer types to be compatible, both shall be 
+  // identically qualified and both shall be pointers to compatible types.
+  if (lhs.getQualifiers() != rhs.getQualifiers())
+    return false;
+    
+  QualType ltype = cast<PointerType>(lhs.getCanonicalType())->getPointeeType();
+  QualType rtype = cast<PointerType>(rhs.getCanonicalType())->getPointeeType();
+  
+  return typesAreCompatible(ltype, rtype);
+}
+
+// C++ 5.17p6: When the left opperand of an assignment operator denotes a
+// reference to T, the operation assigns to the object of type T denoted by the
+// reference.
+bool ASTContext::referenceTypesAreCompatible(QualType lhs, QualType rhs) {
+  QualType ltype = lhs;
+
+  if (lhs->isReferenceType())
+    ltype = cast<ReferenceType>(lhs.getCanonicalType())->getReferenceeType();
+
+  QualType rtype = rhs;
+
+  if (rhs->isReferenceType())
+    rtype = cast<ReferenceType>(rhs.getCanonicalType())->getReferenceeType();
+
+  return typesAreCompatible(ltype, rtype);
+}
+
+bool ASTContext::functionTypesAreCompatible(QualType lhs, QualType rhs) {
+  const FunctionType *lbase = cast<FunctionType>(lhs.getCanonicalType());
+  const FunctionType *rbase = cast<FunctionType>(rhs.getCanonicalType());
+  const FunctionTypeProto *lproto = dyn_cast<FunctionTypeProto>(lbase);
+  const FunctionTypeProto *rproto = dyn_cast<FunctionTypeProto>(rbase);
+
+  // first check the return types (common between C99 and K&R).
+  if (!typesAreCompatible(lbase->getResultType(), rbase->getResultType()))
+    return false;
+
+  if (lproto && rproto) { // two C99 style function prototypes
+    unsigned lproto_nargs = lproto->getNumArgs();
+    unsigned rproto_nargs = rproto->getNumArgs();
+    
+    if (lproto_nargs != rproto_nargs)
+      return false;
+      
+    // both prototypes have the same number of arguments.
+    if ((lproto->isVariadic() && !rproto->isVariadic()) ||
+        (rproto->isVariadic() && !lproto->isVariadic()))
+      return false;
+      
+    // The use of ellipsis agree...now check the argument types.
+    for (unsigned i = 0; i < lproto_nargs; i++)
+      if (!typesAreCompatible(lproto->getArgType(i), rproto->getArgType(i)))
+        return false;
+    return true;
+  }
+  if (!lproto && !rproto) // two K&R style function decls, nothing to do.
+    return true;
+
+  // we have a mixture of K&R style with C99 prototypes
+  const FunctionTypeProto *proto = lproto ? lproto : rproto;
+  
+  if (proto->isVariadic())
+    return false;
+    
+  // FIXME: Each parameter type T in the prototype must be compatible with the
+  // type resulting from applying the usual argument conversions to T.
+  return true;
+}
+
+bool ASTContext::arrayTypesAreCompatible(QualType lhs, QualType rhs) {
+  QualType ltype = cast<ArrayType>(lhs.getCanonicalType())->getElementType();
+  QualType rtype = cast<ArrayType>(rhs.getCanonicalType())->getElementType();
+  
+  if (!typesAreCompatible(ltype, rtype))
+    return false;
+    
+  // FIXME: If both types specify constant sizes, then the sizes must also be 
+  // the same. Even if the sizes are the same, GCC produces an error.
+  return true;
+}
+
+/// typesAreCompatible - C99 6.7.3p9: For two qualified types to be compatible, 
+/// both shall have the identically qualified version of a compatible type.
+/// C99 6.2.7p1: Two types have compatible types if their types are the 
+/// same. See 6.7.[2,3,5] for additional rules.
+bool ASTContext::typesAreCompatible(QualType lhs, QualType rhs) {
+  QualType lcanon = lhs.getCanonicalType();
+  QualType rcanon = rhs.getCanonicalType();
+
+  // If two types are identical, they are are compatible
+  if (lcanon == rcanon)
+    return true;
+  
+  // If the canonical type classes don't match, they can't be compatible
+  if (lcanon->getTypeClass() != rcanon->getTypeClass()) {
+    // For Objective-C, it is possible for two types to be compatible
+    // when their classes don't match (when dealing with "id"). If either type
+    // is an interface, we defer to objcTypesAreCompatible(). 
+    if (lcanon->isObjcInterfaceType() || rcanon->isObjcInterfaceType())
+      return objcTypesAreCompatible(lcanon, rcanon);
+    return false;
+  }
+  switch (lcanon->getTypeClass()) {
+    case Type::Pointer:
+      return pointerTypesAreCompatible(lcanon, rcanon);
+    case Type::Reference:
+      return referenceTypesAreCompatible(lcanon, rcanon);
+    case Type::ConstantArray:
+    case Type::VariableArray:
+      return arrayTypesAreCompatible(lcanon, rcanon);
+    case Type::FunctionNoProto:
+    case Type::FunctionProto:
+      return functionTypesAreCompatible(lcanon, rcanon);
+    case Type::Tagged: // handle structures, unions
+      return tagTypesAreCompatible(lcanon, rcanon);
+    case Type::Builtin:
+      return builtinTypesAreCompatible(lcanon, rcanon); 
+    case Type::ObjcInterface:
+      return interfaceTypesAreCompatible(lcanon, rcanon); 
+    default:
+      assert(0 && "unexpected type");
+  }
+  return true; // should never get here...
+}
index eefd8fafe688564af4a90078c8e6028efcf10a99..f2e351a177d623e1accdcb47706b316b9b6473ed 100644 (file)
@@ -512,7 +512,7 @@ bool Expr::isIntegerConstantExpr(llvm::APSInt &Result, ASTContext &Ctx,
     const TypesCompatibleExpr *TCE = cast<TypesCompatibleExpr>(this);
     Result.zextOrTrunc(
       static_cast<uint32_t>(Ctx.getTypeSize(getType(), TCE->getLocStart())));
-    Result = TCE->typesAreCompatible();
+    Result = Ctx.typesAreCompatible(TCE->getArgType1(), TCE->getArgType2());
     break;
   }
   case CallExprClass: {
index 70dce2c4958de6d035c13f872b199d167f431254..284841810eefacf8dbcf7efe3a50f3863e8cf899 100644 (file)
@@ -260,178 +260,6 @@ const OCUVectorType *Type::getAsOCUVectorType() const {
   return 0;
 }
 
-bool Type::builtinTypesAreCompatible(QualType lhs, QualType rhs) {
-  const BuiltinType *lBuiltin = lhs->getAsBuiltinType();
-  const BuiltinType *rBuiltin = rhs->getAsBuiltinType();
-  
-  return lBuiltin->getKind() == rBuiltin->getKind();
-}
-
-// FIXME: Devise a way to do this without using strcmp.
-// Would like to say..."return getAsStructureType() == IdStructType;", but
-// we don't have a pointer to ASTContext.
-bool Type::isObjcIdType() const {
-  if (const RecordType *RT = getAsStructureType())
-    return !strcmp(RT->getDecl()->getName(), "objc_object");
-  return false;
-}
-
-bool Type::objcTypesAreCompatible(QualType lhs, QualType rhs) {
-  if (lhs->isObjcInterfaceType() && rhs->isObjcIdType())
-    return true;
-  else if (lhs->isObjcIdType() && rhs->isObjcInterfaceType())
-    return true;
-  return false;
-}
-
-bool Type::interfaceTypesAreCompatible(QualType lhs, QualType rhs) {
-  return true; // FIXME: IMPLEMENT.
-}
-
-// C99 6.2.7p1: If both are complete types, then the following additional
-// requirements apply...FIXME (handle compatibility across source files).
-bool Type::tagTypesAreCompatible(QualType lhs, QualType rhs) {
-  TagDecl *ldecl = cast<TagType>(lhs.getCanonicalType())->getDecl();
-  TagDecl *rdecl = cast<TagType>(rhs.getCanonicalType())->getDecl();
-  
-  if (ldecl->getKind() == Decl::Struct && rdecl->getKind() == Decl::Struct) {
-    if (ldecl->getIdentifier() == rdecl->getIdentifier())
-      return true;
-  }
-  if (ldecl->getKind() == Decl::Union && rdecl->getKind() == Decl::Union) {
-    if (ldecl->getIdentifier() == rdecl->getIdentifier())
-      return true;
-  }
-  return false;
-}
-
-bool Type::pointerTypesAreCompatible(QualType lhs, QualType rhs) {
-  // C99 6.7.5.1p2: For two pointer types to be compatible, both shall be 
-  // identically qualified and both shall be pointers to compatible types.
-  if (lhs.getQualifiers() != rhs.getQualifiers())
-    return false;
-    
-  QualType ltype = cast<PointerType>(lhs.getCanonicalType())->getPointeeType();
-  QualType rtype = cast<PointerType>(rhs.getCanonicalType())->getPointeeType();
-  
-  return typesAreCompatible(ltype, rtype);
-}
-
-// C++ 5.17p6: When the left opperand of an assignment operator denotes a
-// reference to T, the operation assigns to the object of type T denoted by the
-// reference.
-bool Type::referenceTypesAreCompatible(QualType lhs, QualType rhs) {
-  QualType ltype = lhs;
-
-  if (lhs->isReferenceType())
-    ltype = cast<ReferenceType>(lhs.getCanonicalType())->getReferenceeType();
-
-  QualType rtype = rhs;
-
-  if (rhs->isReferenceType())
-    rtype = cast<ReferenceType>(rhs.getCanonicalType())->getReferenceeType();
-
-  return typesAreCompatible(ltype, rtype);
-}
-
-bool Type::functionTypesAreCompatible(QualType lhs, QualType rhs) {
-  const FunctionType *lbase = cast<FunctionType>(lhs.getCanonicalType());
-  const FunctionType *rbase = cast<FunctionType>(rhs.getCanonicalType());
-  const FunctionTypeProto *lproto = dyn_cast<FunctionTypeProto>(lbase);
-  const FunctionTypeProto *rproto = dyn_cast<FunctionTypeProto>(rbase);
-
-  // first check the return types (common between C99 and K&R).
-  if (!typesAreCompatible(lbase->getResultType(), rbase->getResultType()))
-    return false;
-
-  if (lproto && rproto) { // two C99 style function prototypes
-    unsigned lproto_nargs = lproto->getNumArgs();
-    unsigned rproto_nargs = rproto->getNumArgs();
-    
-    if (lproto_nargs != rproto_nargs)
-      return false;
-      
-    // both prototypes have the same number of arguments.
-    if ((lproto->isVariadic() && !rproto->isVariadic()) ||
-        (rproto->isVariadic() && !lproto->isVariadic()))
-      return false;
-      
-    // The use of ellipsis agree...now check the argument types.
-    for (unsigned i = 0; i < lproto_nargs; i++)
-      if (!typesAreCompatible(lproto->getArgType(i), rproto->getArgType(i)))
-        return false;
-    return true;
-  }
-  if (!lproto && !rproto) // two K&R style function decls, nothing to do.
-    return true;
-
-  // we have a mixture of K&R style with C99 prototypes
-  const FunctionTypeProto *proto = lproto ? lproto : rproto;
-  
-  if (proto->isVariadic())
-    return false;
-    
-  // FIXME: Each parameter type T in the prototype must be compatible with the
-  // type resulting from applying the usual argument conversions to T.
-  return true;
-}
-
-bool Type::arrayTypesAreCompatible(QualType lhs, QualType rhs) {
-  QualType ltype = cast<ArrayType>(lhs.getCanonicalType())->getElementType();
-  QualType rtype = cast<ArrayType>(rhs.getCanonicalType())->getElementType();
-  
-  if (!typesAreCompatible(ltype, rtype))
-    return false;
-    
-  // FIXME: If both types specify constant sizes, then the sizes must also be 
-  // the same. Even if the sizes are the same, GCC produces an error.
-  return true;
-}
-
-/// typesAreCompatible - C99 6.7.3p9: For two qualified types to be compatible, 
-/// both shall have the identically qualified version of a compatible type.
-/// C99 6.2.7p1: Two types have compatible types if their types are the 
-/// same. See 6.7.[2,3,5] for additional rules.
-bool Type::typesAreCompatible(QualType lhs, QualType rhs) {
-  QualType lcanon = lhs.getCanonicalType();
-  QualType rcanon = rhs.getCanonicalType();
-
-  // If two types are identical, they are are compatible
-  if (lcanon == rcanon)
-    return true;
-  
-  // If the canonical type classes don't match, they can't be compatible
-  if (lcanon->getTypeClass() != rcanon->getTypeClass()) {
-    // For Objective-C, it is possible for two types to be compatible
-    // when their classes don't match (when dealing with "id"). If either type
-    // is an interface, we defer to objcTypesAreCompatible(). 
-    if (lcanon->isObjcInterfaceType() || rcanon->isObjcInterfaceType())
-      return objcTypesAreCompatible(lcanon, rcanon);
-    return false;
-  }
-  switch (lcanon->getTypeClass()) {
-    case Type::Pointer:
-      return pointerTypesAreCompatible(lcanon, rcanon);
-    case Type::Reference:
-      return referenceTypesAreCompatible(lcanon, rcanon);
-    case Type::ConstantArray:
-    case Type::VariableArray:
-      return arrayTypesAreCompatible(lcanon, rcanon);
-    case Type::FunctionNoProto:
-    case Type::FunctionProto:
-      return functionTypesAreCompatible(lcanon, rcanon);
-    case Type::Tagged: // handle structures, unions
-      return tagTypesAreCompatible(lcanon, rcanon);
-    case Type::Builtin:
-      return builtinTypesAreCompatible(lcanon, rcanon); 
-    case Type::ObjcInterface:
-      return interfaceTypesAreCompatible(lcanon, rcanon); 
-    default:
-      assert(0 && "unexpected type");
-  }
-  return true; // should never get here...
-}
-
 bool Type::isIntegerType() const {
   if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
     return BT->getKind() >= BuiltinType::Bool &&
index e73ce616683d992983230c1101a11a0797cd6755..a72a4e98cfbaf3153d9206d9c8d33250f42cfc91 100644 (file)
@@ -101,7 +101,8 @@ public:
   }
   Value *VisitTypesCompatibleExpr(const TypesCompatibleExpr *E) {
     return llvm::ConstantInt::get(ConvertType(E->getType()),
-                                  E->typesAreCompatible());
+                                  CGF.getContext().typesAreCompatible(
+                                    E->getArgType1(), E->getArgType2()));
   }
   Value *VisitSizeOfAlignOfTypeExpr(const SizeOfAlignOfTypeExpr *E) {
     return EmitSizeAlignOf(E->getArgumentType(), E->getType(), E->isSizeOf());
index 9142a257f44b3665a27984d8e882227b1fbfc0d2..c7d74e99ad78c34fb4ada185953fb9d63c287aba 100644 (file)
@@ -757,8 +757,8 @@ inline QualType Sema::CheckConditionalOperands( // C99 6.5.15
           (lhptee->isObjectType() || lhptee->isIncompleteType()))
         return rexT;
 
-      if (!Type::typesAreCompatible(lhptee.getUnqualifiedType(), 
-                                    rhptee.getUnqualifiedType())) {
+      if (!Context.typesAreCompatible(lhptee.getUnqualifiedType(), 
+                                      rhptee.getUnqualifiedType())) {
         Diag(questionLoc, diag::ext_typecheck_cond_incompatible_pointers,
              lexT.getAsString(), rexT.getAsString(),
              lex->getSourceRange(), rex->getSourceRange());
@@ -997,8 +997,8 @@ Sema::CheckPointerTypesForAssignment(QualType lhsType, QualType rhsType) {
     ;
   // C99 6.5.16.1p1 (constraint 3): both operands are pointers to qualified or 
   // unqualified versions of compatible types, ...
-  else if (!Type::typesAreCompatible(lhptee.getUnqualifiedType(), 
-                                     rhptee.getUnqualifiedType()))
+  else if (!Context.typesAreCompatible(lhptee.getUnqualifiedType(), 
+                                       rhptee.getUnqualifiedType()))
     r = IncompatiblePointer; // this "trumps" PointerAssignDiscardsQualifiers
   return r;
 }
@@ -1026,7 +1026,7 @@ Sema::CheckAssignmentConstraints(QualType lhsType, QualType rhsType) {
     return Compatible;
 
   if (lhsType->isReferenceType() || rhsType->isReferenceType()) {
-    if (Type::referenceTypesAreCompatible(lhsType, rhsType))
+    if (Context.referenceTypesAreCompatible(lhsType, rhsType))
       return Compatible;
   } else if (lhsType->isArithmeticType() && rhsType->isArithmeticType()) {
     if (lhsType->isVectorType() || rhsType->isVectorType()) {
@@ -1048,7 +1048,7 @@ Sema::CheckAssignmentConstraints(QualType lhsType, QualType rhsType) {
     if (lhsType->isPointerType()) 
       return CheckPointerTypesForAssignment(lhsType, rhsType);
   } else if (isa<TagType>(lhsType) && isa<TagType>(rhsType)) {
-    if (Type::tagTypesAreCompatible(lhsType, rhsType))
+    if (Context.tagTypesAreCompatible(lhsType, rhsType))
       return Compatible;
   }
   return Incompatible;
@@ -1213,8 +1213,8 @@ inline QualType Sema::CheckCompareOperands( // C99 6.5.8
   // errors (when -pedantic-errors is enabled).
   if (lType->isPointerType() && rType->isPointerType()) { // C99 6.5.8p2
     if (!LHSIsNull && !RHSIsNull &&
-        !Type::pointerTypesAreCompatible(lType.getUnqualifiedType(),
-                                         rType.getUnqualifiedType())) {
+        !Context.pointerTypesAreCompatible(lType.getUnqualifiedType(),
+                                           rType.getUnqualifiedType())) {
       Diag(loc, diag::ext_typecheck_comparison_of_distinct_pointers,
            lType.getAsString(), rType.getAsString(),
            lex->getSourceRange(), rex->getSourceRange());
index 75d938806b0068e9faf478a9935977559b88f772..b88c381faa0b21298a15082c3f3667bb0e3dacc7 100644 (file)
                08FB7793FE84155DC02AAC07 /* Project object */ = {
                        isa = PBXProject;
                        buildConfigurationList = 1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "clang" */;
-                       compatibilityVersion = "Xcode 2.4";
                        hasScannedForEncodings = 1;
                        mainGroup = 08FB7794FE84155DC02AAC07 /* clang */;
                        projectDirPath = "";
index dfe503627992d51fc661af917872f1d4bd73f724..e84c423d5e7f528f8f22b9815cae45f8ab45a28b 100644 (file)
@@ -204,6 +204,26 @@ public:
   /// 'typeSize' is a real floating point or complex type.
   QualType getFloatingTypeOfSizeWithinDomain(QualType typeSize, 
                                              QualType typeDomain) const;
+
+  //===--------------------------------------------------------------------===//
+  //                    Type Compatibility Predicates
+  //===--------------------------------------------------------------------===//
+                                             
+  /// Compatibility predicates used to check assignment expressions.
+  bool typesAreCompatible(QualType, QualType); // C99 6.2.7p1
+  bool tagTypesAreCompatible(QualType, QualType); // C99 6.2.7p1
+  bool pointerTypesAreCompatible(QualType, QualType);  // C99 6.7.5.1p2
+  bool referenceTypesAreCompatible(QualType, QualType); // C++ 5.17p6
+  bool functionTypesAreCompatible(QualType, QualType); // C99 6.7.5.3p15
+  bool arrayTypesAreCompatible(QualType, QualType); // C99 6.7.5.2p6
+  bool builtinTypesAreCompatible(QualType, QualType);
+  
+  /// Objective-C specific type checking.
+  bool interfaceTypesAreCompatible(QualType, QualType);
+  bool objcTypesAreCompatible(QualType, QualType);
+  bool isObjcIdType(QualType T) const {
+    return T->getAsStructureType() == IdStructType;
+  }
 private:
   ASTContext(const ASTContext&); // DO NOT IMPLEMENT
   void operator=(const ASTContext&); // DO NOT IMPLEMENT
index 26771d66421634f0a3181ab67bffa70d3f29de75..5496508cd7929472591720776d0d7eec2dfcca17 100644 (file)
@@ -923,9 +923,7 @@ public:
 
   QualType getArgType1() const { return Type1; }
   QualType getArgType2() const { return Type2; }
-  
-  int typesAreCompatible() const {return Type::typesAreCompatible(Type1,Type2);}
-  
+    
   virtual SourceRange getSourceRange() const {
     return SourceRange(BuiltinLoc, RParenLoc);
   }
index 2b1138c4f64f8b50581c839a1d49a1b7a9b470a4..8e57185f702eda99622795057ad9cbdf5be787b4 100644 (file)
@@ -276,7 +276,6 @@ public:
   bool isVectorType() const; // GCC vector type.
   bool isOCUVectorType() const; // OCU vector type.
   bool isObjcInterfaceType() const; // includes conforming protocol type
-  bool isObjcIdType() const;
   
   // Type Checking Functions: Check to see if this type is structurally the
   // specified type, ignoring typedefs, and return a pointer to the best type
@@ -316,17 +315,6 @@ public:
   /// the location of the subexpression that makes it a vla type.  It is not
   /// legal to call this on incomplete types.
   bool isConstantSizeType(ASTContext &Ctx, SourceLocation *Loc = 0) const;
-
-  /// Compatibility predicates used to check assignment expressions.
-  static bool typesAreCompatible(QualType, QualType); // C99 6.2.7p1
-  static bool tagTypesAreCompatible(QualType, QualType); // C99 6.2.7p1
-  static bool pointerTypesAreCompatible(QualType, QualType);  // C99 6.7.5.1p2
-  static bool referenceTypesAreCompatible(QualType, QualType); // C++ 5.17p6
-  static bool functionTypesAreCompatible(QualType, QualType); // C99 6.7.5.3p15
-  static bool arrayTypesAreCompatible(QualType, QualType); // C99 6.7.5.2p6
-  static bool builtinTypesAreCompatible(QualType, QualType);
-  static bool interfaceTypesAreCompatible(QualType, QualType);
-  static bool objcTypesAreCompatible(QualType, QualType);
 private:  
   QualType getCanonicalTypeInternal() const { return CanonicalType; }
   friend class QualType;