diff options
-rw-r--r-- | include/clang/AST/ASTContext.h | 8 | ||||
-rw-r--r-- | include/clang/Basic/Builtins.def | 10 | ||||
-rw-r--r-- | lib/AST/ASTContext.cpp | 17 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 20 | ||||
-rw-r--r-- | test/SemaObjC/builtin_objc_lib_functions.m | 2 | ||||
-rw-r--r-- | test/SemaObjC/builtin_objc_msgSend.m | 16 |
6 files changed, 65 insertions, 8 deletions
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index d750ba948d..fcea6fb292 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -233,6 +233,8 @@ class ASTContext : public RefCountedBase<ASTContext> { QualType ObjCConstantStringType; mutable RecordDecl *CFConstantStringTypeDecl; + mutable QualType ObjCSuperType; + QualType ObjCNSStringType; /// \brief The typedef declaration for the Objective-C "instancetype" type. @@ -1115,7 +1117,11 @@ public: /// \brief Return the C structure type used to represent constant CFStrings. QualType getCFConstantStringType() const; - + + /// \brief Returns the C struct type for objc_super + QualType getObjCSuperType() const; + void setObjCSuperType(QualType ST) { ObjCSuperType = ST; } + /// Get the structure type used to representation CFStrings, or NULL /// if it hasn't yet been built. QualType getRawCFConstantStringType() const { diff --git a/include/clang/Basic/Builtins.def b/include/clang/Basic/Builtins.def index 3f1c27616a..b5f1c860d4 100644 --- a/include/clang/Basic/Builtins.def +++ b/include/clang/Basic/Builtins.def @@ -31,6 +31,7 @@ // F -> constant CFString // G -> id // H -> SEL +// M -> struct objc_super // a -> __builtin_va_list // A -> "reference" to __builtin_va_list // V -> Vector, followed by the number of elements and the base type. @@ -760,17 +761,16 @@ LIBBUILTIN(strlcpy, "zc*cC*z", "f", "string.h", ALL_LANGUAGES) LIBBUILTIN(strlcat, "zc*cC*z", "f", "string.h", ALL_LANGUAGES) // id objc_msgSend(id, SEL, ...) LIBBUILTIN(objc_msgSend, "GGH.", "f", "objc/message.h", OBJC_LANG) - // long double objc_msgSend_fpret(id self, SEL op, ...) LIBBUILTIN(objc_msgSend_fpret, "LdGH.", "f", "objc/message.h", OBJC_LANG) // _Complex long double objc_msgSend_fp2ret(id self, SEL op, ...) LIBBUILTIN(objc_msgSend_fp2ret, "XLdGH.", "f", "objc/message.h", OBJC_LANG) -// id objc_msgSend_stret (id, SEL, ...) -LIBBUILTIN(objc_msgSend_stret, "GGH.", "f", "objc/message.h", OBJC_LANG) +// void objc_msgSend_stret (id, SEL, ...) +LIBBUILTIN(objc_msgSend_stret, "vGH.", "f", "objc/message.h", OBJC_LANG) // id objc_msgSendSuper(struct objc_super *super, SEL op, ...) -LIBBUILTIN(objc_msgSendSuper, "Gv*H.", "f", "objc/message.h", OBJC_LANG) +LIBBUILTIN(objc_msgSendSuper, "GM*H.", "f", "objc/message.h", OBJC_LANG) // void objc_msgSendSuper_stret(struct objc_super *super, SEL op, ...) -LIBBUILTIN(objc_msgSendSuper_stret, "vv*H.", "f", "objc/message.h", OBJC_LANG) +LIBBUILTIN(objc_msgSendSuper_stret, "vM*H.", "f", "objc/message.h", OBJC_LANG) // id objc_getClass(const char *name) LIBBUILTIN(objc_getClass, "GcC*", "f", "objc/runtime.h", OBJC_LANG) // id objc_getMetaClass(const char *name) diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 1e23ef7995..426e67cc79 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -633,7 +633,7 @@ ASTContext::ASTContext(LangOptions& LOpts, SourceManager &SM, Comments(SM), CommentsLoaded(false), CommentCommandTraits(BumpAlloc), LastSDM(0, 0), - UniqueBlockByRefTypeID(0) + UniqueBlockByRefTypeID(0) { if (size_reserve > 0) Types.reserve(size_reserve); TUDecl = TranslationUnitDecl::Create(*this); @@ -889,6 +889,8 @@ void ASTContext::InitBuiltinTypes(const TargetInfo &Target) { SignedCharTy : BoolTy); ObjCConstantStringType = QualType(); + + ObjCSuperType = QualType(); // void * type VoidPtrTy = getPointerType(VoidTy); @@ -4294,6 +4296,16 @@ QualType ASTContext::getCFConstantStringType() const { return getTagDeclType(CFConstantStringTypeDecl); } +QualType ASTContext::getObjCSuperType() const { + if (ObjCSuperType.isNull()) { + RecordDecl *ObjCSuperTypeDecl = + CreateRecordDecl(*this, TTK_Struct, TUDecl, &Idents.get("objc_super")); + TUDecl->addDecl(ObjCSuperTypeDecl); + ObjCSuperType = getTagDeclType(ObjCSuperTypeDecl); + } + return ObjCSuperType; +} + void ASTContext::setCFConstantStringType(QualType T) { const RecordType *Rec = T->getAs<RecordType>(); assert(Rec && "Invalid CFConstantStringType"); @@ -7205,6 +7217,9 @@ static QualType DecodeTypeFromStr(const char *&Str, const ASTContext &Context, case 'H': Type = Context.getObjCSelType(); break; + case 'M': + Type = Context.getObjCSuperType(); + break; case 'a': Type = Context.getBuiltinVaListType(); assert(!Type.isNull() && "builtin va list type not initialized!"); diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 61791b2aa5..3bbb9a4cfd 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -1464,6 +1464,24 @@ Scope *Sema::getNonFieldDeclScope(Scope *S) { return S; } +/// \brief Looks up the declaration of "struct objc_super" and +/// saves it for later use in building builtin declaration of +/// objc_msgSendSuper and objc_msgSendSuper_stret. If no such +/// pre-existing declaration exists no action takes place. +static void LookupPredefedObjCSuperType(Sema &ThisSema, Scope *S, + IdentifierInfo *II) { + if (!II->isStr("objc_msgSendSuper")) + return; + ASTContext &Context = ThisSema.Context; + + LookupResult Result(ThisSema, &Context.Idents.get("objc_super"), + SourceLocation(), Sema::LookupTagName); + ThisSema.LookupName(Result, S); + if (Result.getResultKind() == LookupResult::Found) + if (const TagDecl *TD = Result.getAsSingle<TagDecl>()) + Context.setObjCSuperType(Context.getTagDeclType(TD)); +} + /// LazilyCreateBuiltin - The specified Builtin-ID was first used at /// file scope. lazily create a decl for it. ForRedeclaration is true /// if we're creating this built-in in anticipation of redeclaring the @@ -1471,6 +1489,8 @@ Scope *Sema::getNonFieldDeclScope(Scope *S) { NamedDecl *Sema::LazilyCreateBuiltin(IdentifierInfo *II, unsigned bid, Scope *S, bool ForRedeclaration, SourceLocation Loc) { + LookupPredefedObjCSuperType(*this, S, II); + Builtin::ID BID = (Builtin::ID)bid; ASTContext::GetBuiltinTypeError Error; diff --git a/test/SemaObjC/builtin_objc_lib_functions.m b/test/SemaObjC/builtin_objc_lib_functions.m index 956ee12573..d8713ddfb4 100644 --- a/test/SemaObjC/builtin_objc_lib_functions.m +++ b/test/SemaObjC/builtin_objc_lib_functions.m @@ -14,7 +14,7 @@ long double f3(id self, SEL op) { return objc_msgSend_fpret(self, op); } // expe // expected-note {{please include the header <objc/message.h> or explicitly provide a declaration for 'objc_msgSend_fpret'}} id f4(struct objc_super *super, SEL op) { // expected-warning {{declaration of 'struct objc_super' will not be visible outside of this function}} - return objc_msgSendSuper(super, op); // expected-warning {{implicitly declaring library function 'objc_msgSendSuper' with type 'id (void *, SEL, ...)'}} \ + return objc_msgSendSuper(super, op); // expected-warning {{implicitly declaring library function 'objc_msgSendSuper' with type 'id (struct objc_super *, SEL, ...)'}} \ // expected-note {{please include the header <objc/message.h> or explicitly provide a declaration for 'objc_msgSendSuper'}} } diff --git a/test/SemaObjC/builtin_objc_msgSend.m b/test/SemaObjC/builtin_objc_msgSend.m index bfa09d9f6c..ffa16e70bf 100644 --- a/test/SemaObjC/builtin_objc_msgSend.m +++ b/test/SemaObjC/builtin_objc_msgSend.m @@ -2,3 +2,19 @@ // expected-no-diagnostics // rdar://8632525 extern id objc_msgSend(id self, SEL op, ...); + +// rdar://12489098 +struct objc_super { + id receiver; + Class super_class; +}; + +extern __attribute__((visibility("default"))) id objc_msgSendSuper(struct objc_super *super, SEL op, ...) + __attribute__((availability(macosx,introduced=10.0))); + +extern __attribute__((visibility("default"))) void objc_msgSendSuper_stret(struct objc_super *super, SEL op, ...) + __attribute__((availability(macosx,introduced=10.0))); + +extern __attribute__((visibility("default"))) void objc_msgSend_stret(id self, SEL op, ...) + __attribute__((availability(macosx,introduced=10.0))); + |