aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AST/ASTContext.cpp22
-rw-r--r--AST/Type.cpp3
-rw-r--r--Driver/RewriteTest.cpp23
-rw-r--r--Sema/SemaType.cpp2
-rw-r--r--include/clang/AST/ASTContext.h2
-rw-r--r--include/clang/AST/Type.h11
-rw-r--r--test/Sema/id-test-3.m4
7 files changed, 45 insertions, 22 deletions
diff --git a/AST/ASTContext.cpp b/AST/ASTContext.cpp
index 2501718e0c..4382574c4c 100644
--- a/AST/ASTContext.cpp
+++ b/AST/ASTContext.cpp
@@ -258,6 +258,8 @@ ASTContext::getTypeInfo(QualType T, SourceLocation L) {
}
break;
}
+ case Type::ObjcQualifiedId: Target.getPointerInfo(Size, Align, getFullLoc(L));
+ break;
case Type::Pointer: Target.getPointerInfo(Size, Align, getFullLoc(L)); break;
case Type::Reference:
// "When applied to a reference or a reference type, the result is the size
@@ -721,7 +723,7 @@ QualType ASTContext::getObjcQualifiedInterfaceType(ObjcInterfaceDecl *Decl,
/// getObjcQualifiedIdType - Return a
/// getObjcQualifiedIdType type for the 'id' decl and
/// the conforming protocol list.
-QualType ASTContext::getObjcQualifiedIdType(TypedefDecl *Decl,
+QualType ASTContext::getObjcQualifiedIdType(QualType idType,
ObjcProtocolDecl **Protocols,
unsigned NumProtocols) {
llvm::FoldingSetNodeID ID;
@@ -733,9 +735,17 @@ QualType ASTContext::getObjcQualifiedIdType(TypedefDecl *Decl,
return QualType(QT, 0);
// No Match;
- QualType Canonical = Decl->getUnderlyingType().getCanonicalType();
- ObjcQualifiedIdType *QType =
- new ObjcQualifiedIdType(Decl, Canonical, Protocols, NumProtocols);
+ QualType Canonical;
+ if (!idType->isCanonical()) {
+ Canonical = getObjcQualifiedIdType(idType.getCanonicalType(),
+ Protocols, NumProtocols);
+ ObjcQualifiedIdType *NewQT =
+ ObjcQualifiedIdTypes.FindNodeOrInsertPos(ID, InsertPos);
+ assert(NewQT == 0 && "Shouldn't be in the map!");
+ }
+
+ ObjcQualifiedIdType *QType =
+ new ObjcQualifiedIdType(Canonical, Protocols, NumProtocols);
Types.push_back(QType);
ObjcQualifiedIdTypes.InsertNode(QType, InsertPos);
return QualType(QType, 0);
@@ -1072,9 +1082,9 @@ void ASTContext::getObjcEncodingForType(QualType T, std::string& S) const
S += encoding;
}
- else if (const ObjcQualifiedIdType *QIT = dyn_cast<ObjcQualifiedIdType>(T)) {
+ else if (T->isObjcQualifiedIdType()) {
// Treat id<P...> same as 'id' for encoding purposes.
- return getObjcEncodingForType(QIT->getDecl()->getUnderlyingType(), S);
+ return getObjcEncodingForType(getObjcIdType(), S);
}
else if (const PointerType *PT = T->getAsPointerType()) {
diff --git a/AST/Type.cpp b/AST/Type.cpp
index 04c236c31b..685a193727 100644
--- a/AST/Type.cpp
+++ b/AST/Type.cpp
@@ -433,7 +433,8 @@ bool Type::isScalarType() const {
return false;
}
return isa<PointerType>(CanonicalType) || isa<ComplexType>(CanonicalType) ||
- isa<VectorType>(CanonicalType);
+ isa<VectorType>(CanonicalType) ||
+ isa<ObjcQualifiedIdType>(CanonicalType);
}
bool Type::isAggregateType() const {
diff --git a/Driver/RewriteTest.cpp b/Driver/RewriteTest.cpp
index 30b1e98af0..cb839ba2bd 100644
--- a/Driver/RewriteTest.cpp
+++ b/Driver/RewriteTest.cpp
@@ -490,7 +490,7 @@ void RewriteTest::RewriteForwardProtocolDecl(ObjcForwardProtocolDecl *PDecl) {
void RewriteTest::RewriteObjcMethodDecl(ObjcMethodDecl *OMD,
std::string &ResultStr) {
ResultStr += "\nstatic ";
- if (isa<ObjcQualifiedIdType>(OMD->getResultType()))
+ if (OMD->getResultType()->isObjcQualifiedIdType())
ResultStr += "id";
else
ResultStr += OMD->getResultType().getAsString();
@@ -551,7 +551,7 @@ void RewriteTest::RewriteObjcMethodDecl(ObjcMethodDecl *OMD,
for (int i = 0; i < OMD->getNumParams(); i++) {
ParmVarDecl *PDecl = OMD->getParamDecl(i);
ResultStr += ", ";
- if (isa<ObjcQualifiedIdType>(PDecl->getType()))
+ if (PDecl->getType()->isObjcQualifiedIdType())
ResultStr += "id";
else
ResultStr += PDecl->getType().getAsString();
@@ -999,7 +999,7 @@ bool RewriteTest::needToScanForQualifiers(QualType T) {
if (T == Context->getObjcIdType())
return true;
- if (isa<ObjcQualifiedIdType>(T))
+ if (T->isObjcQualifiedIdType())
return true;
if (const PointerType *pType = T->getAsPointerType()) {
@@ -1321,7 +1321,7 @@ ObjcInterfaceDecl *RewriteTest::isSuperReceiver(Expr *recExpr) {
if (ParmVarDecl *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
if (!strcmp(PVD->getName(), "self")) {
// is this id<P1..> type?
- if (isa<ObjcQualifiedIdType>(CE->getType()))
+ if (CE->getType()->isObjcQualifiedIdType())
return 0;
if (const PointerType *PT = CE->getType()->getAsPointerType()) {
if (ObjcInterfaceType *IT =
@@ -1516,9 +1516,18 @@ Stmt *RewriteTest::RewriteMessageExpr(ObjCMessageExpr *Exp) {
// Make all implicit casts explicit...ICE comes in handy:-)
if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(userExpr)) {
// Reuse the ICE type, it is exactly what the doctor ordered.
- userExpr = new CastExpr(isa<ObjcQualifiedIdType>(ICE->getType())
+ userExpr = new CastExpr(ICE->getType()->isObjcQualifiedIdType()
? Context->getObjcIdType()
: ICE->getType(), userExpr, SourceLocation());
+ }
+ // Make id<P...> cast into an 'id' cast.
+ else if (CastExpr *CE = dyn_cast<CastExpr>(userExpr)) {
+ if (CE->getType()->isObjcQualifiedIdType()) {
+ while ((CE = dyn_cast<CastExpr>(userExpr)))
+ userExpr = CE->getSubExpr();
+ userExpr = new CastExpr(Context->getObjcIdType(),
+ userExpr, SourceLocation());
+ }
}
MsgExprs.push_back(userExpr);
// We've transferred the ownership to MsgExprs. Null out the argument in
@@ -1539,12 +1548,12 @@ Stmt *RewriteTest::RewriteMessageExpr(ObjCMessageExpr *Exp) {
if (ObjcMethodDecl *mDecl = Exp->getMethodDecl()) {
// Push any user argument types.
for (int i = 0; i < mDecl->getNumParams(); i++) {
- QualType t = isa<ObjcQualifiedIdType>(mDecl->getParamDecl(i)->getType())
+ QualType t = mDecl->getParamDecl(i)->getType()->isObjcQualifiedIdType()
? Context->getObjcIdType()
: mDecl->getParamDecl(i)->getType();
ArgTypes.push_back(t);
}
- returnType = isa<ObjcQualifiedIdType>(mDecl->getResultType())
+ returnType = mDecl->getResultType()->isObjcQualifiedIdType()
? Context->getObjcIdType() : mDecl->getResultType();
} else {
returnType = Context->getObjcIdType();
diff --git a/Sema/SemaType.cpp b/Sema/SemaType.cpp
index a9b8066f97..8a5cfaa7db 100644
--- a/Sema/SemaType.cpp
+++ b/Sema/SemaType.cpp
@@ -118,7 +118,7 @@ static QualType ConvertDeclSpecToType(const DeclSpec &DS, ASTContext &Ctx) {
&& DS.getProtocolQualifiers()) {
// id<protocol-list>
Action::DeclTy **PPDecl = &(*DS.getProtocolQualifiers())[0];
- return Ctx.getObjcQualifiedIdType(typeDecl,
+ return Ctx.getObjcQualifiedIdType(typeDecl->getUnderlyingType(),
reinterpret_cast<ObjcProtocolDecl**>(PPDecl),
DS.NumProtocolQualifiers());
}
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index 058127544e..15f2ba9ac7 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -172,7 +172,7 @@ public:
/// getObjcQualifiedIdType - Return an ObjcQualifiedIdType for a
/// given 'id' and conforming protocol list.
- QualType getObjcQualifiedIdType(TypedefDecl *Decl,
+ QualType getObjcQualifiedIdType(QualType idType,
ObjcProtocolDecl **ProtocolList,
unsigned NumProtocols);
diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h
index 24388ea888..ee21d885d4 100644
--- a/include/clang/AST/Type.h
+++ b/include/clang/AST/Type.h
@@ -295,6 +295,7 @@ public:
bool isVectorType() const; // GCC vector type.
bool isOCUVectorType() const; // OCU vector type.
bool isObjcInterfaceType() const; // includes conforming protocol type
+ bool isObjcQualifiedIdType() const; // id includes conforming protocol type
// Type Checking Functions: Check to see if this type is structurally the
// specified type, ignoring typedefs, and return a pointer to the best type
@@ -956,15 +957,14 @@ public:
};
/// ObjcQualifiedIdType - to represent id<protocol-list>
-class ObjcQualifiedIdType : public TypedefType,
+class ObjcQualifiedIdType : public Type,
public llvm::FoldingSetNode {
// List of protocols for this protocol conforming 'id' type
// List is sorted on protocol name. No protocol is enterred more than once.
llvm::SmallVector<ObjcProtocolDecl*, 8> Protocols;
- ObjcQualifiedIdType(TypedefDecl *TD, QualType can,
- ObjcProtocolDecl **Protos, unsigned NumP) :
- TypedefType(ObjcQualifiedId, TD, can),
+ ObjcQualifiedIdType(QualType can, ObjcProtocolDecl **Protos, unsigned NumP)
+ : Type(ObjcQualifiedId, can),
Protocols(Protos, Protos+NumP) { }
friend class ASTContext; // ASTContext creates these.
public:
@@ -1051,6 +1051,9 @@ inline bool Type::isObjcInterfaceType() const {
return isa<ObjcInterfaceType>(CanonicalType)
|| isa<ObjcQualifiedInterfaceType>(CanonicalType);
}
+inline bool Type::isObjcQualifiedIdType() const {
+ return isa<ObjcQualifiedIdType>(CanonicalType);
+}
} // end namespace clang
#endif
diff --git a/test/Sema/id-test-3.m b/test/Sema/id-test-3.m
index 5331888779..a340348de9 100644
--- a/test/Sema/id-test-3.m
+++ b/test/Sema/id-test-3.m
@@ -1,4 +1,4 @@
-// RUN: clang -rewrite-test %s
+// RUN: clang -rewrite-test %s | clang
@protocol P
- (id<P>) Meth: (id<P>) Arg;
@@ -9,6 +9,6 @@
@end
@implementation INTF
-- (id<P>)IMeth { return [(id<P>)self Meth: 0]; }
+- (id<P>)IMeth { return [(id<P>)self Meth: (id<P>)0]; }
- (id<P>) Meth : (id<P>) Arg {}
@end