diff options
| author | Fariborz Jahanian <fjahanian@apple.com> | 2008-12-19 23:34:38 +0000 | 
|---|---|---|
| committer | Fariborz Jahanian <fjahanian@apple.com> | 2008-12-19 23:34:38 +0000 | 
| commit | 1d35f12e6b571fd1a4c5a86a8631ae50a86a3b75 (patch) | |
| tree | 63222f9b6ffabd23d40268e434cee47b74cdc7f9 | |
| parent | 7be667c075cf5194a85f3829bc4e31acb40b5c5d (diff) | |
| download | bcm5719-llvm-1d35f12e6b571fd1a4c5a86a8631ae50a86a3b75.tar.gz bcm5719-llvm-1d35f12e6b571fd1a4c5a86a8631ae50a86a3b75.zip | |
More encoding support. This time for
@encode of classes and bitfields.
llvm-svn: 61268
| -rw-r--r-- | clang/include/clang/AST/ASTContext.h | 4 | ||||
| -rw-r--r-- | clang/lib/AST/ASTContext.cpp | 100 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CGObjCMac.cpp | 2 | ||||
| -rw-r--r-- | clang/test/CodeGenObjC/encode-test.m | 40 | 
4 files changed, 104 insertions, 42 deletions
| diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index 2c7b6fdf415..4a1992a914f 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -299,7 +299,7 @@ public:    /// given type into \arg S. If \arg NameFields is specified then    /// record field names are also encoded.    void getObjCEncodingForType(QualType t, std::string &S,  -                              bool NameFields=false) const; +                              FieldDecl *Field=NULL) const;    // Put the string version of type qualifiers into S.    void getObjCEncodingForTypeQualifier(Decl::ObjCDeclQualifier QT,  @@ -542,7 +542,7 @@ private:    void getObjCEncodingForTypeImpl(QualType t, std::string &S,                                     bool ExpandPointedToStructures,                                    bool ExpandStructures, -                                  bool NameFields) const; +                                  FieldDecl *Field) const;  }; diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index a91679e5949..c50a0210282 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -1734,48 +1734,58 @@ void ASTContext::getObjCEncodingForPropertyDecl(const ObjCPropertyDecl *PD,  }  void ASTContext::getObjCEncodingForType(QualType T, std::string& S, -                                        bool NameFields) const { +                                        FieldDecl *Field) const {    // We follow the behavior of gcc, expanding structures which are    // directly pointed to, and expanding embedded structures. Note that    // these rules are sufficient to prevent recursive encoding of the    // same type. -  getObjCEncodingForTypeImpl(T, S, true, true, NameFields); +  getObjCEncodingForTypeImpl(T, S, true, true, Field);  }  void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,                                              bool ExpandPointedToStructures,                                              bool ExpandStructures, -                                            bool NameFields) const { +                                            FieldDecl *FD) const {    if (const BuiltinType *BT = T->getAsBuiltinType()) { -    char encoding; -    switch (BT->getKind()) { -    default: assert(0 && "Unhandled builtin type kind");           -    case BuiltinType::Void:       encoding = 'v'; break; -    case BuiltinType::Bool:       encoding = 'B'; break; -    case BuiltinType::Char_U: -    case BuiltinType::UChar:      encoding = 'C'; break; -    case BuiltinType::UShort:     encoding = 'S'; break; -    case BuiltinType::UInt:       encoding = 'I'; break; -    case BuiltinType::ULong:      encoding = 'L'; break; -    case BuiltinType::ULongLong:  encoding = 'Q'; break; -    case BuiltinType::Char_S: -    case BuiltinType::SChar:      encoding = 'c'; break; -    case BuiltinType::Short:      encoding = 's'; break; -    case BuiltinType::Int:        encoding = 'i'; break; -    case BuiltinType::Long:       encoding = 'l'; break; -    case BuiltinType::LongLong:   encoding = 'q'; break; -    case BuiltinType::Float:      encoding = 'f'; break; -    case BuiltinType::Double:     encoding = 'd'; break; -    case BuiltinType::LongDouble: encoding = 'd'; break; +    if (FD && FD->isBitField()) { +      const Expr *E = FD->getBitWidth(); +      assert(E && "bitfield width not there - getObjCEncodingForTypeImpl"); +      ASTContext *Ctx = const_cast<ASTContext*>(this); +      unsigned N = E->getIntegerConstantExprValue(*Ctx).getZExtValue(); +      S += 'b'; +      S += llvm::utostr(N);      } +    else { +      char encoding; +      switch (BT->getKind()) { +      default: assert(0 && "Unhandled builtin type kind");           +      case BuiltinType::Void:       encoding = 'v'; break; +      case BuiltinType::Bool:       encoding = 'B'; break; +      case BuiltinType::Char_U: +      case BuiltinType::UChar:      encoding = 'C'; break; +      case BuiltinType::UShort:     encoding = 'S'; break; +      case BuiltinType::UInt:       encoding = 'I'; break; +      case BuiltinType::ULong:      encoding = 'L'; break; +      case BuiltinType::ULongLong:  encoding = 'Q'; break; +      case BuiltinType::Char_S: +      case BuiltinType::SChar:      encoding = 'c'; break; +      case BuiltinType::Short:      encoding = 's'; break; +      case BuiltinType::Int:        encoding = 'i'; break; +      case BuiltinType::Long:       encoding = 'l'; break; +      case BuiltinType::LongLong:   encoding = 'q'; break; +      case BuiltinType::Float:      encoding = 'f'; break; +      case BuiltinType::Double:     encoding = 'd'; break; +      case BuiltinType::LongDouble: encoding = 'd'; break; +      } -    S += encoding; +      S += encoding; +    }    }    else if (T->isObjCQualifiedIdType()) {      // Treat id<P...> same as 'id' for encoding purposes.      return getObjCEncodingForTypeImpl(getObjCIdType(), S,                                         ExpandPointedToStructures, -                                      ExpandStructures, NameFields);     +                                      ExpandStructures, FD);        }    else if (const PointerType *PT = T->getAsPointerType()) {      QualType PointeeTy = PT->getPointeeType(); @@ -1810,7 +1820,7 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,      S += '^';      getObjCEncodingForTypeImpl(PT->getPointeeType(), S,                                  false, ExpandPointedToStructures,  -                               false); +                               NULL);    } else if (const ArrayType *AT =                 // Ignore type qualifiers etc.                 dyn_cast<ArrayType>(T->getCanonicalTypeInternal())) { @@ -1822,7 +1832,7 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,        assert(0 && "Unhandled array type!");      getObjCEncodingForTypeImpl(AT->getElementType(), S,  -                               false, ExpandStructures, NameFields); +                               false, ExpandStructures, FD);      S += ']';    } else if (T->getAsFunctionType()) {      S += '?'; @@ -1840,24 +1850,19 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,        for (RecordDecl::field_iterator Field = RDecl->field_begin(),                                     FieldEnd = RDecl->field_end();             Field != FieldEnd; ++Field) { -        if (NameFields) { +        if (FD) {            S += '"';            S += Field->getNameAsString();            S += '"';          }          // Special case bit-fields. -        if (const Expr *E = Field->getBitWidth()) { -          // FIXME: Fix constness. -          ASTContext *Ctx = const_cast<ASTContext*>(this); -          unsigned N = E->getIntegerConstantExprValue(*Ctx).getZExtValue(); -          // FIXME: Obj-C is losing information about the type size -          // here. Investigate if this is a problem. -          S += 'b'; -          S += llvm::utostr(N); +        if (Field->isBitField()) { +          getObjCEncodingForTypeImpl(Field->getType(), S, false, true,  +                                     (*Field));          } else {            getObjCEncodingForTypeImpl(Field->getType(), S, false, true,  -                                     NameFields); +                                     FD);          }        }      } @@ -1866,7 +1871,26 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,      S += 'i';    } else if (T->isBlockPointerType()) {      S += '^'; // This type string is the same as general pointers. -  } else +  } else if (T->isObjCInterfaceType()) { +    // @encode(class_name) +    ObjCInterfaceDecl *OI = T->getAsObjCInterfaceType()->getDecl(); +    S += '{'; +    const IdentifierInfo *II = OI->getIdentifier(); +    S += II->getName(); +    S += '='; +    std::vector<FieldDecl*> RecFields; +    CollectObjCIvars(OI, RecFields); +    for (unsigned int i = 0; i != RecFields.size(); i++) { +      if (RecFields[i]->isBitField()) +        getObjCEncodingForTypeImpl(RecFields[i]->getType(), S, false, true,  +                                   RecFields[i]); +      else +        getObjCEncodingForTypeImpl(RecFields[i]->getType(), S, false, true,  +                                   FD); +    } +    S += '}'; +  } +  else      assert(0 && "@encode for type not implemented!");  } diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp index 33dfff10302..dd722458aaa 100644 --- a/clang/lib/CodeGen/CGObjCMac.cpp +++ b/clang/lib/CodeGen/CGObjCMac.cpp @@ -1336,7 +1336,7 @@ llvm::Constant *CGObjCMac::EmitIvarList(const ObjCImplementationDecl *ID,        Layout->getElementOffset(CGM.getTypes().getLLVMFieldNo(Field));      std::string TypeStr;      Ivar[0] = GetMethodVarName(V->getIdentifier()); -    CGM.getContext().getObjCEncodingForType(V->getType(), TypeStr, true); +    CGM.getContext().getObjCEncodingForType(V->getType(), TypeStr, Field);      Ivar[1] = GetMethodVarType(TypeStr);      Ivar[2] = llvm::ConstantInt::get(ObjCTypes.IntTy, Offset);      Ivars.push_back(llvm::ConstantStruct::get(ObjCTypes.IvarTy, Ivar)); diff --git a/clang/test/CodeGenObjC/encode-test.m b/clang/test/CodeGenObjC/encode-test.m index f5b6b920711..982faf03bad 100644 --- a/clang/test/CodeGenObjC/encode-test.m +++ b/clang/test/CodeGenObjC/encode-test.m @@ -1,5 +1,6 @@  // RUN: clang -fnext-runtime -emit-llvm -o %t %s && -// RUN: grep -e "\^{Innermost=CC}" %t | count 1 +// RUN: grep -e "\^{Innermost=CC}" %t | count 1 && +// RUN: grep -e "{Derived=#ib32b8b3b8sb16b8b8b2b8ccb6}" %t | count 1  @class Int1; @@ -15,3 +16,40 @@ struct Innermost {  @implementation Int1  @end + +@interface Base +{ +    struct objc_class *isa; +    int full; +    int full2: 32; +    int _refs: 8; +    int field2: 3; +    unsigned f3: 8; +    short cc; +    unsigned g: 16; +    int r2: 8; +    int r3: 8; +    int r4: 2; +    int r5: 8; +    char c; +} +@end + +@interface Derived: Base +{ +    char d; +    int _field3: 6; +} +@end + +@implementation Base +@end + +@implementation Derived +@end + +int main() +{ +	const char *en = @encode(Derived); +} + | 

