]> granicus.if.org Git - clang/commitdiff
Encode Class, SEL and Objective-C objects.
authorAnders Carlsson <andersca@mac.com>
Wed, 31 Oct 2007 02:53:19 +0000 (02:53 +0000)
committerAnders Carlsson <andersca@mac.com>
Wed, 31 Oct 2007 02:53:19 +0000 (02:53 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@43540 91177308-0d34-0410-b5e6-96231b3b80d8

AST/ASTContext.cpp
Sema/Sema.cpp
Sema/Sema.h
Sema/SemaExpr.cpp
include/clang/AST/ASTContext.h
include/clang/Basic/DiagnosticKinds.def

index 93ec288270e43ab5271c2aa25149836cb38af8b9..ec7cd7b558838ab6daaadeaa83179c687843ef62 100644 (file)
@@ -152,6 +152,9 @@ void ASTContext::InitBuiltinTypes() {
   BuiltinVaListType = QualType();
   ObjcIdType = QualType();
   IdStructType = 0;
+  ObjcClassType = QualType();
+  ClassStructType = 0;
+  
   ObjcConstantStringType = QualType();
   
   // void * type
@@ -1008,9 +1011,15 @@ void ASTContext::getObjcEncodingForType(QualType T, std::string& S) const
     S += encoding;
   } else if (const PointerType *PT = T->getAsPointerType()) {
     QualType PointeeTy = PT->getPointeeType();
-    if (isObjcIdType(PointeeTy)) {
+    if (isObjcIdType(PointeeTy) || PointeeTy->isObjcInterfaceType()) {
       S += '@';
       return;
+    } else if (isObjcClassType(PointeeTy)) {
+      S += '#';
+      return;
+    } else if (isObjcSelType(PointeeTy)) {
+      S += ':';
+      return;
     }
     
     if (PointeeTy->isCharType()) {
@@ -1086,6 +1095,20 @@ void ASTContext::setObjcProtoType(TypedefDecl *TD)
   ProtoStructType = TD->getUnderlyingType()->getAsStructureType();
 }
 
+void ASTContext::setObjcClassType(TypedefDecl *TD)
+{
+  assert(ObjcClassType.isNull() && "'Class' type already set!");
+    
+  ObjcClassType = getTypedefType(TD);
+
+  // typedef struct objc_class *Class;
+  const PointerType *ptr = TD->getUnderlyingType()->getAsPointerType();
+  assert(ptr && "'Class' incorrectly typed");
+  const RecordType *rec = ptr->getPointeeType()->getAsStructureType();
+  assert(rec && "'Class' incorrectly typed");
+  ClassStructType = rec;
+}
+
 void ASTContext::setObjcConstantStringInterface(ObjcInterfaceDecl *Decl) {
   assert(ObjcConstantStringType.isNull() && 
          "'NSConstantString' type already set!");
index 2be198de43be7b9d4f8880dbe222c129e1b159c9..92d17e1e99bd5f953d2f65f850c47fe7881441e3 100644 (file)
@@ -82,6 +82,25 @@ QualType Sema::GetObjcProtoType(SourceLocation Loc) {
   return Context.getObjcProtoType();
 }
 
+/// GetObjcClassType - See comments for Sema::GetObjcIdType above; replace "id"
+/// with "Protocol".
+QualType Sema::GetObjcClassType(SourceLocation Loc) {
+  assert(TUScope && "GetObjcClassType(): Top-level scope is null");
+  if (!Context.getObjcClassType().isNull())
+    return Context.getObjcClassType();
+    
+  IdentifierInfo *ClassIdent = &Context.Idents.get("Class");
+  ScopedDecl *ClassDecl = LookupScopedDecl(ClassIdent, Decl::IDNS_Ordinary, 
+                                        SourceLocation(), TUScope);
+  TypedefDecl *ObjcClassTypedef = dyn_cast_or_null<TypedefDecl>(ClassDecl);
+  if (!ObjcClassTypedef) {
+    Diag(Loc, diag::err_missing_class_definition);
+    return QualType();
+  }
+  Context.setObjcClassType(ObjcClassTypedef);
+  return Context.getObjcClassType();
+}
+
 Sema::Sema(Preprocessor &pp, ASTContext &ctxt, std::vector<Decl*> &prevInGroup)
   : PP(pp), Context(ctxt), CurFunctionDecl(0), LastInGroupList(prevInGroup) {
   
index 9db00fb1c2abb81d82b6565342c08cf3d23a16b0..13ba636d5293c4701561329e41d022a6deb2ed0b 100644 (file)
@@ -284,6 +284,9 @@ private:
   /// GetObjcSelType - Getter for the build-in "Protocol *" type.
   QualType GetObjcProtoType(SourceLocation Loc = SourceLocation());
   
+  // GetObjcClassType - Getter for the built-in "Class" type.
+  QualType GetObjcClassType(SourceLocation Loc = SourceLocation());
+
   /// 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 ee3510785b819b564fa4dfba5c9425c09c4fd040..aac6ca321871b7491cb1644a5d31ee71e1f3267d 100644 (file)
@@ -1959,6 +1959,17 @@ Sema::ExprResult Sema::ParseObjCEncodeExpression(SourceLocation AtLoc,
                                                  SourceLocation RParenLoc) {
   QualType EncodedType = QualType::getFromOpaquePtr(Ty);
 
+  // We cannot build type 'id' lazily. It is needed when checking if a 
+  // type is an 'id' (via call to isObjcIdType) even if there is no
+  // need for the default 'id' type.
+  // FIXME: Depending on the need to compare to 'id', this may have to go
+  // somewhere else. At this time, this is a good enough place to do type
+  // encoding of methods and ivars for the rewrite client.
+  // The same is true for the 'Class' and 'SEL' types.
+  GetObjcIdType(EncodeLoc);
+  GetObjcClassType(EncodeLoc);
+  GetObjcSelType(EncodeLoc);
+  
   QualType t = Context.getPointerType(Context.CharTy);
   return new ObjCEncodeExpr(t, EncodedType, AtLoc, RParenLoc);
 }
index dda0490f24ea36bcefc641b97d0d078f505a4ddf..043ffb30c9b9b4a15e5fa620e86a94aa1132e893 100644 (file)
@@ -59,6 +59,10 @@ class ASTContext {
   /// ObjcProtoType - another psuedo built-in typedef type (set by Sema).
   QualType ObjcProtoType;
   const RecordType *ProtoStructType;
+
+  /// ObjcClassType - another psuedo built-in typedef type (set by Sema).
+  QualType ObjcClassType;
+  const RecordType *ClassStructType;
   
   QualType ObjcConstantStringType;
   RecordDecl *CFConstantStringTypeDecl;
@@ -196,6 +200,9 @@ public:
   void setObjcProtoType(TypedefDecl *Decl);
   QualType getObjcProtoType() const { return ObjcProtoType; }
   
+  void setObjcClassType(TypedefDecl *Decl);
+  QualType getObjcClassType() const { return ObjcClassType; }
+  
   void setBuiltinVaListType(QualType T);
   QualType getBuiltinVaListType() const { return BuiltinVaListType; }
     
@@ -264,6 +271,15 @@ public:
     assert(IdStructType && "isObjcIdType used before 'id' type is built");
     return T->getAsStructureType() == IdStructType;
   }
+  bool isObjcClassType(QualType T) const {
+    assert(ClassStructType && "isObjcClassType used before 'Class' type is built");
+    return T->getAsStructureType() == ClassStructType;
+  }
+  bool isObjcSelType(QualType T) const {
+    assert(SelStructType && "isObjcSelType used before 'SEL' type is built");
+    return T->getAsStructureType() == SelStructType;
+  }
+
 private:
   ASTContext(const ASTContext&); // DO NOT IMPLEMENT
   void operator=(const ASTContext&); // DO NOT IMPLEMENT
index bbdb6bc51730738031766dbdfcc5ae2b1797bf22..8a65b7310e5b6e18bbd85cb99c470dbc064ab6c7 100644 (file)
@@ -450,6 +450,8 @@ DIAG(err_missing_id_definition, ERROR,
      "cannot find definition of 'id'")
 DIAG(err_missing_proto_definition, ERROR,
      "cannot find definition of 'Protocol'")
+DIAG(err_missing_class_definition, ERROR,
+     "cannot find definition of 'Class'")
 DIAG(warn_previous_alias_decl, WARNING,
      "previously declared alias is ignored")
 DIAG(warn_previous_declaration, WARNING,