diff options
author | Steve Naroff <snaroff@apple.com> | 2009-07-10 23:34:53 +0000 |
---|---|---|
committer | Steve Naroff <snaroff@apple.com> | 2009-07-10 23:34:53 +0000 |
commit | 14108da7f7fc059772711e4ffee1322a27b152a7 (patch) | |
tree | 5461a189505985c1c245c3f63a48030f0cd5e929 /lib/AST/Type.cpp | |
parent | 7ecbfbcddd278eede10bd38fa03a95a2110b191a (diff) |
This patch includes a conceptually simple, but very intrusive/pervasive change.
The idea is to segregate Objective-C "object" pointers from general C pointers (utilizing the recently added ObjCObjectPointerType). The fun starts in Sema::GetTypeForDeclarator(), where "SomeInterface *" is now represented by a single AST node (rather than a PointerType whose Pointee is an ObjCInterfaceType). Since a significant amount of code assumed ObjC object pointers where based on C pointers/structs, this patch is very tedious. It should also explain why it is hard to accomplish this in smaller, self-contained patches.
This patch does most of the "heavy lifting" related to moving from PointerType->ObjCObjectPointerType. It doesn't include all potential "cleanups". The good news is additional cleanups can be done later (some are noted in the code). This patch is so large that I didn't want to include any changes that are purely aesthetic.
By making the ObjC types truly built-in, they are much easier to work with (and require fewer "hacks"). For example, there is no need for ASTContext::isObjCIdStructType() or ASTContext::isObjCClassStructType()! We believe this change (and the follow-up cleanups) will pay dividends over time.
Given the amount of code change, I do expect some fallout from this change (though it does pass all of the clang tests). If you notice any problems, please let us know asap! Thanks.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@75314 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/Type.cpp')
-rw-r--r-- | lib/AST/Type.cpp | 53 |
1 files changed, 40 insertions, 13 deletions
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp index 78c3b78977..fd368c4815 100644 --- a/lib/AST/Type.cpp +++ b/lib/AST/Type.cpp @@ -22,6 +22,9 @@ #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; @@ -295,6 +298,15 @@ const FunctionProtoType *Type::getAsFunctionProtoType() const { return dyn_cast_or_null<FunctionProtoType>(getAsFunctionType()); } +QualType Type::getPointeeType() const { + if (const PointerType *PT = getAsPointerType()) + return PT->getPointeeType(); + if (const ObjCObjectPointerType *OPT = getAsObjCObjectPointerType()) + return OPT->getPointeeType(); + if (const BlockPointerType *BPT = getAsBlockPointerType()) + return BPT->getPointeeType(); + return QualType(); +} const PointerType *Type::getAsPointerType() const { // If this is directly a pointer type, return it. @@ -609,6 +621,14 @@ const ObjCObjectPointerType *Type::getAsObjCQualifiedIdType() const { return 0; } +const ObjCObjectPointerType *Type::getAsObjCInterfacePointerType() const { + if (const ObjCObjectPointerType *OPT = getAsObjCObjectPointerType()) { + if (OPT->getInterfaceType()) + return OPT; + } + return 0; +} + const TemplateTypeParmType *Type::getAsTemplateTypeParmType() const { // There is no sugar for template type parameters, so just return // the canonical type pointer if it is the right class. @@ -1016,16 +1036,18 @@ void FunctionProtoType::Profile(llvm::FoldingSetNodeID &ID) { } void ObjCObjectPointerType::Profile(llvm::FoldingSetNodeID &ID, - const ObjCInterfaceDecl *Decl, - ObjCProtocolDecl **protocols, + QualType OIT, ObjCProtocolDecl **protocols, unsigned NumProtocols) { - ID.AddPointer(Decl); + ID.AddPointer(OIT.getAsOpaquePtr()); for (unsigned i = 0; i != NumProtocols; i++) ID.AddPointer(protocols[i]); } void ObjCObjectPointerType::Profile(llvm::FoldingSetNodeID &ID) { - Profile(ID, getDecl(), &Protocols[0], getNumProtocols()); + if (getNumProtocols()) + Profile(ID, getPointeeType(), &Protocols[0], getNumProtocols()); + else + Profile(ID, getPointeeType(), 0, 0); } void ObjCQualifiedInterfaceType::Profile(llvm::FoldingSetNodeID &ID, @@ -1663,6 +1685,14 @@ void TypenameType::getAsStringInternal(std::string &InnerString, const PrintingP 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; @@ -1671,15 +1701,7 @@ void ObjCInterfaceType::getAsStringInternal(std::string &InnerString, const Prin void ObjCObjectPointerType::getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const { - if (!InnerString.empty()) // Prefix the basic type, e.g. 'typedefname X'. - InnerString = ' ' + InnerString; - - std::string ObjCQIString; - - if (getDecl()) - ObjCQIString = getDecl()->getNameAsString(); - else - ObjCQIString = "id"; + std::string ObjCQIString = getInterfaceType()->getDecl()->getNameAsString(); if (!qual_empty()) { ObjCQIString += '<'; @@ -1690,6 +1712,11 @@ void ObjCObjectPointerType::getAsStringInternal(std::string &InnerString, } ObjCQIString += '>'; } + if (!isObjCIdType() && !isObjCQualifiedIdType()) + ObjCQIString += " *"; // Don't forget the implicit pointer. + else if (!InnerString.empty()) // Prefix the basic type, e.g. 'typedefname X'. + InnerString = ' ' + InnerString; + InnerString = ObjCQIString + InnerString; } |