From: Steve Naroff Date: Tue, 9 Sep 2008 14:32:20 +0000 (+0000) Subject: Tweak implementation for allowing ObjC builtin type redefinitions. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=2b255c4dabe6a04314e3659a0f8b61e1382ec287;p=clang Tweak implementation for allowing ObjC builtin type redefinitions. - Replace string comparisons with pre-defined idents. - Avoid calling isBuiltinObjCType() to avoid two checks. - Remove isBuiltinObjCType(), since it was only used in Sema::MergeTypeDefDecl(). - Have Sema::MergeTypeDefDecl() set the new type. This is a moidified version of an patch by David Chisnall. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@55990 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index bcda5ffcb5..4757ea98e5 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -1697,8 +1697,6 @@ void ASTContext::setBuiltinVaListType(QualType T) void ASTContext::setObjCIdType(TypedefDecl *TD) { - assert(ObjCIdType.isNull() && "'id' type already set!"); - ObjCIdType = getTypedefType(TD); // typedef struct objc_object *id; @@ -1711,8 +1709,6 @@ void ASTContext::setObjCIdType(TypedefDecl *TD) void ASTContext::setObjCSelType(TypedefDecl *TD) { - assert(ObjCSelType.isNull() && "'SEL' type already set!"); - ObjCSelType = getTypedefType(TD); // typedef struct objc_selector *SEL; @@ -1725,14 +1721,11 @@ void ASTContext::setObjCSelType(TypedefDecl *TD) void ASTContext::setObjCProtoType(QualType QT) { - assert(ObjCProtoType.isNull() && "'Protocol' type already set!"); ObjCProtoType = QT; } void ASTContext::setObjCClassType(TypedefDecl *TD) { - assert(ObjCClassType.isNull() && "'Class' type already set!"); - ObjCClassType = getTypedefType(TD); // typedef struct objc_class *Class; diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp index 9092f83f0a..2b8127b153 100644 --- a/lib/Sema/Sema.cpp +++ b/lib/Sema/Sema.cpp @@ -21,12 +21,6 @@ using namespace clang; -bool Sema::isBuiltinObjCType(TypedefDecl *TD) { - const char *typeName = TD->getIdentifier()->getName(); - return strcmp(typeName, "id") == 0 || strcmp(typeName, "Class") == 0 || - strcmp(typeName, "SEL") == 0 || strcmp(typeName, "Protocol") == 0; -} - static inline RecordDecl *CreateStructDecl(ASTContext &C, const char *Name) { if (C.getLangOptions().CPlusPlus) @@ -107,6 +101,12 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer) SuperID = &IT.get("super"); + // ObjC builtin typedef names. + Ident_id = &IT.get("id"); + Ident_Class = &IT.get("Class"); + Ident_SEL = &IT.get("SEL"); + Ident_Protocol = &IT.get("Protocol"); + TUScope = 0; if (getLangOptions().CPlusPlus) FieldCollector.reset(new CXXFieldCollector()); diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index 96f6e53c61..13977423ee 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -146,6 +146,10 @@ public: /// SuperID - Identifier for "super" used for Objective-C checking. IdentifierInfo* SuperID; + /// Identifiers for builtin ObjC typedef names. + IdentifierInfo *Ident_id, *Ident_Class; // "id", "Class" + IdentifierInfo *Ident_SEL, *Ident_Protocol; // "SEL", "Protocol" + /// Translation Unit Scope - useful to Objective-C actions that need /// to lookup file scope declarations in the "ordinary" C decl namespace. /// For example, user-defined classes, built-in "id" type, etc. @@ -358,10 +362,6 @@ private: bool MatchTwoMethodDeclarations(const ObjCMethodDecl *Method, const ObjCMethodDecl *PrevMethod); - /// isBuiltinObjCType - Returns true of the type is "id", "SEL", "Class" - /// or "Protocol". - bool isBuiltinObjCType(TypedefDecl *TD); - /// AddInstanceMethodToGlobalPool - All instance methods in a translation /// unit are added to a global pool. This allows us to efficiently associate /// a selector with a method declaraation for purposes of typechecking diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index cf84bcc5e1..40008579a9 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -230,6 +230,25 @@ ScopedDecl *Sema::LazilyCreateBuiltin(IdentifierInfo *II, unsigned bid, /// situation, merging decls or emitting diagnostics as appropriate. /// TypedefDecl *Sema::MergeTypeDefDecl(TypedefDecl *New, Decl *OldD) { + // Allow multiple definitions for ObjC built-in typedefs. + // FIXME: Verify the underlying types are equivalent! + if (getLangOptions().ObjC1) { + const IdentifierInfo *typeIdent = New->getIdentifier(); + if (typeIdent == Ident_id) { + Context.setObjCIdType(New); + return New; + } else if (typeIdent == Ident_Class) { + Context.setObjCClassType(New); + return New; + } else if (typeIdent == Ident_SEL) { + Context.setObjCSelType(New); + return New; + } else if (typeIdent == Ident_Protocol) { + Context.setObjCProtoType(New->getUnderlyingType()); + return New; + } + // Fall through - the typedef name was not a builtin type. + } // Verify the old decl was also a typedef. TypedefDecl *Old = dyn_cast(OldD); if (!Old) { @@ -251,11 +270,6 @@ TypedefDecl *Sema::MergeTypeDefDecl(TypedefDecl *New, Decl *OldD) { return Old; } - // Allow multiple definitions for ObjC built-in typedefs. - // FIXME: Verify the underlying types are equivalent! - if (getLangOptions().ObjC1 && isBuiltinObjCType(New)) - return Old; - if (getLangOptions().Microsoft) return New; // Redeclaration of a type is a constraint violation (6.7.2.3p1).