]> granicus.if.org Git - clang/commitdiff
Tweak implementation for allowing ObjC builtin type redefinitions.
authorSteve Naroff <snaroff@apple.com>
Tue, 9 Sep 2008 14:32:20 +0000 (14:32 +0000)
committerSteve Naroff <snaroff@apple.com>
Tue, 9 Sep 2008 14:32:20 +0000 (14:32 +0000)
- 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

lib/AST/ASTContext.cpp
lib/Sema/Sema.cpp
lib/Sema/Sema.h
lib/Sema/SemaDecl.cpp

index bcda5ffcb535c037cbf7126d500b705a580bacf7..4757ea98e5b13a05f100fd87d18d714106c3bd21 100644 (file)
@@ -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;
index 9092f83f0a45897467dc5b6a551abe0a82e461b5..2b8127b153babee93c9c9cdd483b1e8ebdab9b11 100644 (file)
 
 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());
index 96f6e53c618b926a23df31c5284bb918a19e6b1a..13977423ee850fbca2c6a9eed6545d450acc57b1 100644 (file)
@@ -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
index cf84bcc5e1e87f12c38dc7787a4c226b1b47aafe..40008579a9af7380eedd4c8b875a0775ccc2171f 100644 (file)
@@ -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<TypedefDecl>(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).