[cfe-commits] r75808 - in /cfe/trunk: include/clang/AST/ASTContext.h include/clang/AST/Type.h include/clang/Basic/DiagnosticSemaKinds.td include/clang/Frontend/PCHBitCodes.h lib/AST/ASTContext.cpp lib/AST/Type.cpp lib/CodeGen/CodeGenTypes.cpp lib/CodeGen/Mangle.cpp lib/Frontend/PCHReader.cpp lib/Frontend/PCHWriter.cpp lib/Sema/Sema.cpp lib/Sema/SemaExpr.cpp lib/Sema/SemaOverload.cpp test/SemaObjC/comptypes-3.m test/SemaObjC/conditional-expr-3.m
Steve Naroff
snaroff at apple.com
Wed Jul 15 11:40:40 PDT 2009
Author: snaroff
Date: Wed Jul 15 13:40:39 2009
New Revision: 75808
URL: http://llvm.org/viewvc/llvm-project?rev=75808&view=rev
Log:
Implement the ObjC pseudo built-in types as clang "BuiltinType's". I say pseudo built-in types, since Sema still injects a typedef for recognition (i.e. they aren't truly built-ins from a parser perspective).
This removes the static data/methods on ObjCObjectPointerType while preserving the nice API (no need to fiddle with ASTContext:-).
This patch also adds Type::isObjCBuiltinType().
This should be the last fairly large patch related to recrafting the ObjC type system. The follow-on patches should be fairly small.
Modified:
cfe/trunk/include/clang/AST/ASTContext.h
cfe/trunk/include/clang/AST/Type.h
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/include/clang/Frontend/PCHBitCodes.h
cfe/trunk/lib/AST/ASTContext.cpp
cfe/trunk/lib/AST/Type.cpp
cfe/trunk/lib/CodeGen/CodeGenTypes.cpp
cfe/trunk/lib/CodeGen/Mangle.cpp
cfe/trunk/lib/Frontend/PCHReader.cpp
cfe/trunk/lib/Frontend/PCHWriter.cpp
cfe/trunk/lib/Sema/Sema.cpp
cfe/trunk/lib/Sema/SemaExpr.cpp
cfe/trunk/lib/Sema/SemaOverload.cpp
cfe/trunk/test/SemaObjC/comptypes-3.m
cfe/trunk/test/SemaObjC/conditional-expr-3.m
Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=75808&r1=75807&r2=75808&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Wed Jul 15 13:40:39 2009
@@ -106,7 +106,7 @@
QualType BuiltinVaListType;
/// ObjCIdType - a pseudo built-in typedef type (set by Sema).
- QualType ObjCIdType;
+ QualType ObjCIdTypedefType;
/// ObjCSelType - another pseudo built-in typedef type (set by Sema).
QualType ObjCSelType;
@@ -117,7 +117,7 @@
const RecordType *ProtoStructType;
/// ObjCClassType - another pseudo built-in typedef type (set by Sema).
- QualType ObjCClassType;
+ QualType ObjCClassTypedefType;
QualType ObjCConstantStringType;
RecordDecl *CFConstantStringTypeDecl;
@@ -210,6 +210,7 @@
QualType OverloadTy;
QualType DependentTy;
QualType UndeducedAutoTy;
+ QualType ObjCBuiltinIdTy, ObjCBuiltinClassTy;
ASTContext(const LangOptions& LOpts, SourceManager &SM, TargetInfo &t,
IdentifierTable &idents, SelectorTable &sels,
@@ -490,7 +491,7 @@
/// This setter/getter represents the ObjC 'id' type. It is setup lazily, by
/// Sema. id is always a (typedef for a) pointer type, a pointer to a struct.
- QualType getObjCIdType() const { return ObjCIdType; }
+ QualType getObjCIdType() const { return ObjCIdTypedefType; }
void setObjCIdType(QualType T);
void setObjCSelType(QualType T);
@@ -502,7 +503,7 @@
/// This setter/getter repreents the ObjC 'Class' type. It is setup lazily, by
/// Sema. 'Class' is always a (typedef for a) pointer type, a pointer to a
/// struct.
- QualType getObjCClassType() const { return ObjCClassType; }
+ QualType getObjCClassType() const { return ObjCClassTypedefType; }
void setObjCClassType(QualType T);
void setBuiltinVaListType(QualType T);
@@ -768,10 +769,10 @@
bool typesAreCompatible(QualType, QualType); // C99 6.2.7p1
bool isObjCIdType(QualType T) const {
- return T == ObjCIdType;
+ return T == ObjCIdTypedefType;
}
bool isObjCClassType(QualType T) const {
- return T == ObjCClassType;
+ return T == ObjCClassTypedefType;
}
bool isObjCSelType(QualType T) const {
assert(SelStructType && "isObjCSelType used before 'SEL' type is built");
Modified: cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=75808&r1=75807&r2=75808&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Wed Jul 15 13:40:39 2009
@@ -404,6 +404,7 @@
bool isObjCQualifiedIdType() const; // id<foo>
bool isObjCIdType() const; // id
bool isObjCClassType() const; // Class
+ bool isObjCBuiltinType() const; // 'id' or 'Class'
bool isTemplateTypeParmType() const; // C++ template type parameter
bool isNullPtrType() const; // C++0x nullptr_t
@@ -592,8 +593,10 @@
Overload, // This represents the type of an overloaded function declaration.
Dependent, // This represents the type of a type-dependent expression.
- UndeducedAuto // In C++0x, this represents the type of an auto variable
+ UndeducedAuto, // In C++0x, this represents the type of an auto variable
// that has not been deduced yet.
+ ObjCId, // This represents the ObjC 'id' type.
+ ObjCClass // This represents the ObjC 'Class' type.
};
private:
Kind TypeKind;
@@ -1899,7 +1902,7 @@
/// Duplicate protocols are removed and protocol list is canonicalized to be in
/// alphabetical order.
class ObjCObjectPointerType : public Type, public llvm::FoldingSetNode {
- QualType PointeeType; // will always point to an interface type.
+ QualType PointeeType; // A builin or interface type.
// List of protocols for this protocol conforming object type
// List is sorted on protocol name. No protocol is entered more than once.
@@ -1909,20 +1912,10 @@
Type(ObjCObjectPointer, QualType(), /*Dependent=*/false),
PointeeType(T), Protocols(Protos, Protos+NumP) { }
friend class ASTContext; // ASTContext creates these.
- friend class ObjCInterfaceType; // To enable 'id' and 'Class' predicates.
- static ObjCInterfaceType *IdInterfaceT;
- static ObjCInterfaceType *ClassInterfaceT;
- static void setIdInterface(QualType T) {
- IdInterfaceT = dyn_cast<ObjCInterfaceType>(T.getTypePtr());
- }
- static void setClassInterface(QualType T) {
- ClassInterfaceT = dyn_cast<ObjCInterfaceType>(T.getTypePtr());
- }
- static ObjCInterfaceType *getIdInterface() { return IdInterfaceT; }
- static ObjCInterfaceType *getClassInterface() { return ClassInterfaceT; }
public:
- // Get the pointee type. Pointee is required to always be an interface type.
+ // Get the pointee type. Pointee will either be a built-in type (for 'id' and
+ // 'Class') or will be an interface type (for user-defined types).
// Note: Pointee can be a TypedefType whose canonical type is an interface.
// Example: typedef NSObject T; T *var;
QualType getPointeeType() const { return PointeeType; }
@@ -1930,18 +1923,29 @@
const ObjCInterfaceType *getInterfaceType() const {
return PointeeType->getAsObjCInterfaceType();
}
+ /// getInterfaceDecl - returns an interface decl for user-defined types.
ObjCInterfaceDecl *getInterfaceDecl() const {
- return getInterfaceType()->getDecl();
- }
- /// isObjCQualifiedIdType - true for "id <p>".
- bool isObjCQualifiedIdType() const {
- return getInterfaceType() == IdInterfaceT && Protocols.size();
+ return getInterfaceType() ? getInterfaceType()->getDecl() : 0;
}
+ /// isObjCIdType - true for "id".
bool isObjCIdType() const {
- return getInterfaceType() == IdInterfaceT && !Protocols.size();
+ return getPointeeType()->isSpecificBuiltinType(BuiltinType::ObjCId) &&
+ !Protocols.size();
}
+ /// isObjCClassType - true for "Class".
bool isObjCClassType() const {
- return getInterfaceType() == ClassInterfaceT && !Protocols.size();
+ return getPointeeType()->isSpecificBuiltinType(BuiltinType::ObjCClass) &&
+ !Protocols.size();
+ }
+ /// isObjCQualifiedIdType - true for "id <p>".
+ bool isObjCQualifiedIdType() const {
+ return getPointeeType()->isSpecificBuiltinType(BuiltinType::ObjCId) &&
+ Protocols.size();
+ }
+ /// isObjCQualifiedClassType - true for "Class <p>".
+ bool isQualifiedClassType() const {
+ return getPointeeType()->isSpecificBuiltinType(BuiltinType::ObjCClass) &&
+ Protocols.size();
}
/// qual_iterator and friends: this provides access to the (potentially empty)
/// list of protocols qualifying this interface.
@@ -2188,23 +2192,24 @@
return isa<ObjCQualifiedInterfaceType>(CanonicalType.getUnqualifiedType());
}
inline bool Type::isObjCQualifiedIdType() const {
- if (const ObjCObjectPointerType *OPT = getAsObjCObjectPointerType()) {
+ if (const ObjCObjectPointerType *OPT = getAsObjCObjectPointerType())
return OPT->isObjCQualifiedIdType();
- }
return false;
}
inline bool Type::isObjCIdType() const {
- if (const ObjCObjectPointerType *OPT = getAsObjCObjectPointerType()) {
+ if (const ObjCObjectPointerType *OPT = getAsObjCObjectPointerType())
return OPT->isObjCIdType();
- }
return false;
}
inline bool Type::isObjCClassType() const {
- if (const ObjCObjectPointerType *OPT = getAsObjCObjectPointerType()) {
+ if (const ObjCObjectPointerType *OPT = getAsObjCObjectPointerType())
return OPT->isObjCClassType();
- }
return false;
}
+inline bool Type::isObjCBuiltinType() const {
+ return isObjCIdType() || isObjCClassType();
+}
+
inline bool Type::isTemplateTypeParmType() const {
return isa<TemplateTypeParmType>(CanonicalType.getUnqualifiedType());
}
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=75808&r1=75807&r2=75808&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Wed Jul 15 13:40:39 2009
@@ -1457,8 +1457,6 @@
"cannot initialize %0 with an %select{rvalue|lvalue}1 of type %2">;
def warn_incompatible_qualified_id : Warning<
"incompatible type %2 %1, expected %0">;
-def warn_incompatible_qualified_id_operands : Warning<
- "invalid operands to binary expression (%0 and %1)">;
def ext_typecheck_convert_pointer_int : ExtWarn<
"incompatible pointer to integer conversion %2 %1, expected %0">;
def ext_typecheck_convert_int_pointer : ExtWarn<
Modified: cfe/trunk/include/clang/Frontend/PCHBitCodes.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/PCHBitCodes.h?rev=75808&r1=75807&r2=75808&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/PCHBitCodes.h (original)
+++ cfe/trunk/include/clang/Frontend/PCHBitCodes.h Wed Jul 15 13:40:39 2009
@@ -333,7 +333,11 @@
/// \brief The C++ 'char16_t' type.
PREDEF_TYPE_CHAR16_ID = 24,
/// \brief The C++ 'char32_t' type.
- PREDEF_TYPE_CHAR32_ID = 25
+ PREDEF_TYPE_CHAR32_ID = 25,
+ /// \brief The ObjC 'id' type.
+ PREDEF_TYPE_OBJC_ID = 26,
+ /// \brief The ObjC 'Class' type.
+ PREDEF_TYPE_OBJC_CLASS = 27
};
/// \brief The number of predefined type IDs that are reserved for
Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=75808&r1=75807&r2=75808&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Wed Jul 15 13:40:39 2009
@@ -201,8 +201,13 @@
BuiltinVaListType = QualType();
- ObjCIdType = QualType();
- ObjCClassType = QualType();
+ // "Builtin" typedefs set by Sema::ActOnTranslationUnitScope().
+ ObjCIdTypedefType = QualType();
+ ObjCClassTypedefType = QualType();
+
+ // Builtin types for 'id' and 'Class'.
+ InitBuiltinType(ObjCBuiltinIdTy, BuiltinType::ObjCId);
+ InitBuiltinType(ObjCBuiltinClassTy, BuiltinType::ObjCClass);
ObjCConstantStringType = QualType();
@@ -1868,7 +1873,7 @@
ObjCProtocolDecl **Protocols,
unsigned NumProtocols) {
if (InterfaceT.isNull())
- InterfaceT = QualType(ObjCObjectPointerType::getIdInterface(), 0);
+ InterfaceT = ObjCBuiltinIdTy;
// Sort the protocol list alphabetically to canonicalize it.
if (NumProtocols)
@@ -2471,7 +2476,7 @@
QualType FieldTypes[] = {
UnsignedLongTy,
- getPointerType(ObjCIdType),
+ getPointerType(ObjCIdTypedefType),
getPointerType(UnsignedLongTy),
getConstantArrayType(UnsignedLongTy,
llvm::APInt(32, 5), ArrayType::Normal, 0)
@@ -3018,13 +3023,7 @@
}
void ASTContext::setObjCIdType(QualType T) {
- ObjCIdType = T;
- const TypedefType *TT = T->getAsTypedefType();
- assert(TT && "missing 'id' typedef");
- const ObjCObjectPointerType *OPT =
- TT->getDecl()->getUnderlyingType()->getAsObjCObjectPointerType();
- assert(OPT && "missing 'id' type");
- ObjCObjectPointerType::setIdInterface(OPT->getPointeeType());
+ ObjCIdTypedefType = T;
}
void ASTContext::setObjCSelType(QualType T) {
@@ -3050,13 +3049,7 @@
}
void ASTContext::setObjCClassType(QualType T) {
- ObjCClassType = T;
- const TypedefType *TT = T->getAsTypedefType();
- assert(TT && "missing 'Class' typedef");
- const ObjCObjectPointerType *OPT =
- TT->getDecl()->getUnderlyingType()->getAsObjCObjectPointerType();
- assert(OPT && "missing 'Class' type");
- ObjCObjectPointerType::setClassInterface(OPT->getPointeeType());
+ ObjCClassTypedefType = T;
}
void ASTContext::setObjCConstantStringInterface(ObjCInterfaceDecl *Decl) {
@@ -3235,27 +3228,38 @@
/// FIXME: Move the following to ObjCObjectPointerType/ObjCInterfaceType.
bool ASTContext::canAssignObjCInterfaces(const ObjCObjectPointerType *LHSOPT,
const ObjCObjectPointerType *RHSOPT) {
- // If either interface represents the built-in 'id' or 'Class' types,
- // then return true (no need to call canAssignObjCInterfaces()).
- if (LHSOPT->isObjCIdType() || RHSOPT->isObjCIdType() ||
- LHSOPT->isObjCClassType() || RHSOPT->isObjCClassType())
+ // If either type represents the built-in 'id' or 'Class' types, return true.
+ if (LHSOPT->isObjCBuiltinType() || RHSOPT->isObjCBuiltinType())
return true;
const ObjCInterfaceType* LHS = LHSOPT->getInterfaceType();
const ObjCInterfaceType* RHS = RHSOPT->getInterfaceType();
- if (!LHS || !RHS)
- return false;
+ if (!LHS || !RHS) {
+ // We have qualified builtin types.
+ // Both the right and left sides have qualifiers.
+ for (ObjCObjectPointerType::qual_iterator I = LHSOPT->qual_begin(),
+ E = LHSOPT->qual_end(); I != E; ++I) {
+ bool RHSImplementsProtocol = false;
+
+ // when comparing an id<P> on lhs with a static type on rhs,
+ // see if static class implements all of id's protocols, directly or
+ // through its super class and categories.
+ for (ObjCObjectPointerType::qual_iterator J = RHSOPT->qual_begin(),
+ E = RHSOPT->qual_end(); J != E; ++J) {
+ if ((*J)->lookupProtocolNamed((*I)->getIdentifier()))
+ RHSImplementsProtocol = true;
+ }
+ if (!RHSImplementsProtocol)
+ return false;
+ }
+ // The RHS implements all protocols listed on the LHS.
+ return true;
+ }
return canAssignObjCInterfaces(LHS, RHS);
}
bool ASTContext::canAssignObjCInterfaces(const ObjCInterfaceType *LHS,
const ObjCInterfaceType *RHS) {
- // If either interface represents the built-in 'id' or 'Class' types,
- // then return true.
- if (LHS->isObjCIdInterface() || RHS->isObjCIdInterface() ||
- LHS->isObjCClassInterface() || RHS->isObjCClassInterface())
- return true;
-
// Verify that the base decls are compatible: the RHS must be a subclass of
// the LHS.
if (!LHS->getDecl()->isSuperClassOf(RHS->getDecl()))
Modified: cfe/trunk/lib/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=75808&r1=75807&r2=75808&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Type.cpp (original)
+++ cfe/trunk/lib/AST/Type.cpp Wed Jul 15 13:40:39 2009
@@ -22,9 +22,6 @@
#include "llvm/Support/raw_ostream.h"
using namespace clang;
-ObjCInterfaceType *ObjCObjectPointerType::IdInterfaceT;
-ObjCInterfaceType *ObjCObjectPointerType::ClassInterfaceT;
-
bool QualType::isConstant(ASTContext &Ctx) const {
if (isConstQualified())
return true;
@@ -1009,6 +1006,8 @@
case Overload: return "<overloaded function type>";
case Dependent: return "<dependent type>";
case UndeducedAuto: return "auto";
+ case ObjCId: return "id";
+ case ObjCClass: return "Class";
}
}
@@ -1687,14 +1686,6 @@
InnerString = MyString + ' ' + InnerString;
}
-bool ObjCInterfaceType::isObjCIdInterface() const {
- return this == ObjCObjectPointerType::getIdInterface();
-}
-
-bool ObjCInterfaceType::isObjCClassInterface() const {
- return this == ObjCObjectPointerType::getClassInterface();
-}
-
void ObjCInterfaceType::getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const {
if (!InnerString.empty()) // Prefix the basic type, e.g. 'typedefname X'.
InnerString = ' ' + InnerString;
@@ -1703,7 +1694,14 @@
void ObjCObjectPointerType::getAsStringInternal(std::string &InnerString,
const PrintingPolicy &Policy) const {
- std::string ObjCQIString = getInterfaceType()->getDecl()->getNameAsString();
+ std::string ObjCQIString;
+
+ if (isObjCIdType() || isObjCQualifiedIdType())
+ ObjCQIString = "id";
+ else if (isObjCClassType())
+ ObjCQIString = "Class";
+ else
+ ObjCQIString = getInterfaceDecl()->getNameAsString();
if (!qual_empty()) {
ObjCQIString += '<';
Modified: cfe/trunk/lib/CodeGen/CodeGenTypes.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenTypes.cpp?rev=75808&r1=75807&r2=75808&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenTypes.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenTypes.cpp Wed Jul 15 13:40:39 2009
@@ -228,6 +228,8 @@
switch (cast<BuiltinType>(Ty).getKind()) {
default: assert(0 && "Unknown builtin type!");
case BuiltinType::Void:
+ case BuiltinType::ObjCId:
+ case BuiltinType::ObjCClass:
// LLVM void type can only be used as the result of a function call. Just
// map to the same as char.
return llvm::IntegerType::get(8);
Modified: cfe/trunk/lib/CodeGen/Mangle.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/Mangle.cpp?rev=75808&r1=75807&r2=75808&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/Mangle.cpp (original)
+++ cfe/trunk/lib/CodeGen/Mangle.cpp Wed Jul 15 13:40:39 2009
@@ -577,6 +577,8 @@
case BuiltinType::UndeducedAuto:
assert(0 && "Should not see undeduced auto here");
break;
+ case BuiltinType::ObjCId: Out << "2id"; break;
+ case BuiltinType::ObjCClass: Out << "5Class"; break;
}
}
Modified: cfe/trunk/lib/Frontend/PCHReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHReader.cpp?rev=75808&r1=75807&r2=75808&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/PCHReader.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHReader.cpp Wed Jul 15 13:40:39 2009
@@ -1986,6 +1986,8 @@
case pch::PREDEF_TYPE_NULLPTR_ID: T = Context->NullPtrTy; break;
case pch::PREDEF_TYPE_CHAR16_ID: T = Context->Char16Ty; break;
case pch::PREDEF_TYPE_CHAR32_ID: T = Context->Char32Ty; break;
+ case pch::PREDEF_TYPE_OBJC_ID: T = Context->ObjCBuiltinIdTy; break;
+ case pch::PREDEF_TYPE_OBJC_CLASS: T = Context->ObjCBuiltinClassTy; break;
}
assert(!T.isNull() && "Unknown predefined type");
Modified: cfe/trunk/lib/Frontend/PCHWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHWriter.cpp?rev=75808&r1=75807&r2=75808&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/PCHWriter.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHWriter.cpp Wed Jul 15 13:40:39 2009
@@ -2009,6 +2009,8 @@
case BuiltinType::Char32: ID = pch::PREDEF_TYPE_CHAR32_ID; break;
case BuiltinType::Overload: ID = pch::PREDEF_TYPE_OVERLOAD_ID; break;
case BuiltinType::Dependent: ID = pch::PREDEF_TYPE_DEPENDENT_ID; break;
+ case BuiltinType::ObjCId: ID = pch::PREDEF_TYPE_OBJC_ID; break;
+ case BuiltinType::ObjCClass: ID = pch::PREDEF_TYPE_OBJC_CLASS; break;
case BuiltinType::UndeducedAuto:
assert(0 && "Should not see undeduced auto here");
break;
Modified: cfe/trunk/lib/Sema/Sema.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.cpp?rev=75808&r1=75807&r2=75808&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.cpp (original)
+++ cfe/trunk/lib/Sema/Sema.cpp Wed Jul 15 13:40:39 2009
@@ -149,35 +149,23 @@
Context.setObjCProtoType(Context.getObjCInterfaceType(ProtocolDecl));
PushOnScopeChains(ProtocolDecl, TUScope);
}
- // Create the built-in decls/typedefs for 'id' and 'Class'.
+ // Create the built-in typedef for 'id'.
if (Context.getObjCIdType().isNull()) {
- ObjCInterfaceDecl *IdIDecl =
- ObjCInterfaceDecl::Create(Context, CurContext, SourceLocation(),
- &Context.Idents.get("id"),
- SourceLocation(), true);
- QualType IdIType = Context.getObjCInterfaceType(IdIDecl);
- QualType ObjCIdType = Context.getObjCObjectPointerType(IdIType);
-
- TypedefDecl *IdTypedef = TypedefDecl::Create(Context, CurContext,
- SourceLocation(),
- &Context.Idents.get("id"),
- ObjCIdType);
+ TypedefDecl *IdTypedef =
+ TypedefDecl::Create(
+ Context, CurContext, SourceLocation(), &Context.Idents.get("id"),
+ Context.getObjCObjectPointerType(Context.ObjCBuiltinIdTy)
+ );
PushOnScopeChains(IdTypedef, TUScope);
Context.setObjCIdType(Context.getTypeDeclType(IdTypedef));
}
- // Create the built-in decls/typedefs and type for "Class".
+ // Create the built-in typedef for 'Class'.
if (Context.getObjCClassType().isNull()) {
- ObjCInterfaceDecl *ClassIDecl =
- ObjCInterfaceDecl::Create(Context, CurContext, SourceLocation(),
- &Context.Idents.get("Class"),
- SourceLocation(), true);
- QualType ClassIType = Context.getObjCInterfaceType(ClassIDecl);
- QualType ObjCClassType = Context.getObjCObjectPointerType(ClassIType);
-
- TypedefDecl *ClassTypedef = TypedefDecl::Create(Context, CurContext,
- SourceLocation(),
- &Context.Idents.get("Class"),
- ObjCClassType);
+ TypedefDecl *ClassTypedef =
+ TypedefDecl::Create(
+ Context, CurContext, SourceLocation(), &Context.Idents.get("Class"),
+ Context.getObjCObjectPointerType(Context.ObjCBuiltinClassTy)
+ );
PushOnScopeChains(ClassTypedef, TUScope);
Context.setObjCClassType(Context.getTypeDeclType(ClassTypedef));
}
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=75808&r1=75807&r2=75808&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Wed Jul 15 13:40:39 2009
@@ -2338,9 +2338,11 @@
<< IDecl->getDeclName() << &Member
<< BaseExpr->getSourceRange());
}
- // Handle properties on qualified "id" protocols.
- const ObjCObjectPointerType *QIdTy;
- if (OpKind == tok::period && (QIdTy = BaseType->getAsObjCQualifiedIdType())) {
+ // Handle properties on 'id' and qualified "id".
+ if (OpKind == tok::period && (BaseType->isObjCIdType() ||
+ BaseType->isObjCQualifiedIdType())) {
+ const ObjCObjectPointerType *QIdTy = BaseType->getAsObjCObjectPointerType();
+
// Check protocols on qualified interfaces.
Selector Sel = PP.getSelectorTable().getNullarySelector(&Member);
if (Decl *PMDecl = FindGetterNameDecl(QIdTy, Member, Sel, Context)) {
@@ -3531,6 +3533,8 @@
return CheckPointeeTypesForAssignment(lhptee, rhptee);
}
if (rhsType->isObjCObjectPointerType()) {
+ if (lhsType->isObjCBuiltinType() || rhsType->isObjCBuiltinType())
+ return Compatible;
QualType lhptee = lhsType->getAsObjCObjectPointerType()->getPointeeType();
QualType rhptee = rhsType->getAsObjCObjectPointerType()->getPointeeType();
return CheckPointeeTypesForAssignment(lhptee, rhptee);
@@ -4279,11 +4283,6 @@
Diag(Loc, diag::ext_typecheck_comparison_of_distinct_pointers)
<< lType << rType << lex->getSourceRange() << rex->getSourceRange();
}
- if (lType->isObjCQualifiedIdType() && rType->isObjCQualifiedIdType()) {
- if (!ObjCQualifiedIdTypesAreCompatible(lType, rType, true))
- Diag(Loc, diag::warn_incompatible_qualified_id_operands)
- << lType << rType << lex->getSourceRange() << rex->getSourceRange();
- }
ImpCastExprToType(rex, lType);
return ResultTy;
}
Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=75808&r1=75807&r2=75808&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Wed Jul 15 13:40:39 2009
@@ -1011,15 +1011,9 @@
FromType->getAsObjCObjectPointerType();
if (ToObjCPtr && FromObjCPtr) {
- // Objective C++: We're able to convert between "id" and a pointer
- // to any interface (in both directions).
- if (ToObjCPtr->isObjCIdType() && FromObjCPtr->isObjCIdType()) {
- ConvertedType = ToType;
- return true;
- }
- // Objective C++: Allow conversions between the Objective-C "Class" and a
+ // Objective C++: We're able to convert between "id" or "Class" and a
// pointer to any interface (in both directions).
- if (ToObjCPtr->isObjCClassType() || FromObjCPtr->isObjCClassType()) {
+ if (ToObjCPtr->isObjCBuiltinType() && FromObjCPtr->isObjCBuiltinType()) {
ConvertedType = ToType;
return true;
}
@@ -1169,8 +1163,7 @@
// Objective-C++ conversions are always okay.
// FIXME: We should have a different class of conversions for the
// Objective-C++ implicit conversions.
- if (FromPtrType->isObjCIdType() || ToPtrType->isObjCIdType() ||
- FromPtrType->isObjCClassType() || ToPtrType->isObjCClassType())
+ if (FromPtrType->isObjCBuiltinType() || ToPtrType->isObjCBuiltinType())
return false;
}
Modified: cfe/trunk/test/SemaObjC/comptypes-3.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/comptypes-3.m?rev=75808&r1=75807&r2=75808&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/comptypes-3.m (original)
+++ cfe/trunk/test/SemaObjC/comptypes-3.m Wed Jul 15 13:40:39 2009
@@ -42,8 +42,8 @@
obj_ac = obj_b; // expected-warning {{incompatible type assigning 'id<MyProtocolB>', expected 'id<MyProtocolAC>'}}
obj_ac = obj_ab; // expected-warning {{incompatible type assigning 'id<MyProtocolAB>', expected 'id<MyProtocolAC>'}}
- if (obj_a == obj_b) foo (); // expected-warning {{invalid operands to binary expression ('id<MyProtocolA>' and 'id<MyProtocolB>')}}
- if (obj_b == obj_a) foo (); // expected-warning {{invalid operands to binary expression ('id<MyProtocolB>' and 'id<MyProtocolA>')}}
+ if (obj_a == obj_b) foo (); // expected-warning {{comparison of distinct pointer types ('id<MyProtocolA>' and 'id<MyProtocolB>')}}
+ if (obj_b == obj_a) foo (); // expected-warning {{comparison of distinct pointer types ('id<MyProtocolB>' and 'id<MyProtocolA>')}}
if (obj_a == obj_ab) foo (); /* Ok */
if (obj_ab == obj_a) foo (); /* Ok */
@@ -54,11 +54,11 @@
if (obj_b == obj_ab) foo (); /* Ok */
if (obj_ab == obj_b) foo (); /* Ok */
- if (obj_b == obj_ac) foo (); // expected-warning {{invalid operands to binary expression ('id<MyProtocolB>' and 'id<MyProtocolAC>')}}
- if (obj_ac == obj_b) foo (); // expected-warning {{invalid operands to binary expression ('id<MyProtocolAC>' and 'id<MyProtocolB>')}}
+ if (obj_b == obj_ac) foo (); // expected-warning {{comparison of distinct pointer types ('id<MyProtocolB>' and 'id<MyProtocolAC>')}}
+ if (obj_ac == obj_b) foo (); // expected-warning {{comparison of distinct pointer types ('id<MyProtocolAC>' and 'id<MyProtocolB>')}}
- if (obj_ab == obj_ac) foo (); // expected-warning {{invalid operands to binary expression ('id<MyProtocolAB>' and 'id<MyProtocolAC>')}}
- if (obj_ac == obj_ab) foo (); // expected-warning {{invalid operands to binary expression ('id<MyProtocolAC>' and 'id<MyProtocolAB>')}}
+ if (obj_ab == obj_ac) foo (); // expected-warning {{comparison of distinct pointer types ('id<MyProtocolAB>' and 'id<MyProtocolAC>')}}
+ if (obj_ac == obj_ab) foo (); // expected-warning {{comparison of distinct pointer types ('id<MyProtocolAC>' and 'id<MyProtocolAB>')}}
return 0;
}
Modified: cfe/trunk/test/SemaObjC/conditional-expr-3.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/conditional-expr-3.m?rev=75808&r1=75807&r2=75808&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/conditional-expr-3.m (original)
+++ cfe/trunk/test/SemaObjC/conditional-expr-3.m Wed Jul 15 13:40:39 2009
@@ -51,15 +51,15 @@
}
void f8(int cond, id<P0,P1> x0, id<P0,P2> x1) {
- barP0(cond ? x0 : x1);
+ barP0(cond ? x0 : x1); // expected-warning {{incompatible operand types ('id<P0,P1>' and 'id<P0,P2>')}}
}
void f9(int cond, id<P0,P1> x0, id<P0,P2> x1) {
- barP1(cond ? x0 : x1);
+ barP1(cond ? x0 : x1); // expected-warning {{incompatible operand types ('id<P0,P1>' and 'id<P0,P2>')}}
}
void f10(int cond, id<P0,P1> x0, id<P0,P2> x1) {
- barP2(cond ? x0 : x1); // expected-warning {{incompatible type passing 'id<P0,P1>', expected 'id<P2>'}}
+ barP2(cond ? x0 : x1); // expected-warning {{incompatible operand types ('id<P0,P1>' and 'id<P0,P2>')}}
}
int f11(int cond, A* a, B* b) {
More information about the cfe-commits
mailing list