diff options
| author | Fariborz Jahanian <fjahanian@apple.com> | 2010-04-28 16:11:27 +0000 | 
|---|---|---|
| committer | Fariborz Jahanian <fjahanian@apple.com> | 2010-04-28 16:11:27 +0000 | 
| commit | c83726e64ef657e49bdfe9b75f5e41bdfbd6a962 (patch) | |
| tree | 47258479c4808fefb91ea9b3dacef1d827a72368 /clang/lib/Sema | |
| parent | 9c05bf46d197fbb2ce80c5cba17ad4ccf6358045 (diff) | |
| download | bcm5719-llvm-c83726e64ef657e49bdfe9b75f5e41bdfbd6a962.tar.gz bcm5719-llvm-c83726e64ef657e49bdfe9b75f5e41bdfbd6a962.zip | |
More of Sema to implement initialization of
ivar of c++ object types.
llvm-svn: 102500
Diffstat (limited to 'clang/lib/Sema')
| -rw-r--r-- | clang/lib/Sema/Sema.h | 8 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 41 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDeclObjC.cpp | 47 | 
3 files changed, 69 insertions, 27 deletions
| diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index f22c1ad8527..fb65862fe4b 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/lib/Sema/Sema.h @@ -1592,10 +1592,9 @@ public:    void AddFactoryMethodToGlobalPool(ObjCMethodDecl *Method);    /// CollectIvarsToConstructOrDestruct - Collect those ivars which require -  /// construction (construct=true) or destruction (construct=false) +  /// initialization.    void CollectIvarsToConstructOrDestruct(const ObjCInterfaceDecl *OI, -                                    llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars, -                                    bool construct=true); +                                  llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars);    //===--------------------------------------------------------------------===//    // Statement Parsing Callbacks: SemaStmt.cpp.  public: @@ -2510,6 +2509,9 @@ public:    bool SetBaseOrMemberInitializers(CXXConstructorDecl *Constructor,                                     CXXBaseOrMemberInitializer **Initializers,                                     unsigned NumInitializers, bool AnyErrors); +   +  void SetIvarInitializers(ObjCImplementationDecl *ObjCImplementation); +                               /// MarkBaseAndMemberDestructorsReferenced - Given a record decl,    /// mark all the non-trivial destructors of its members and bases as diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index f6ff40010ce..854f204ab06 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -5699,3 +5699,44 @@ void Sema::MarkVirtualMembersReferenced(SourceLocation Loc,      MarkVirtualMembersReferenced(Loc, Base);    }  } + +/// SetIvarInitializers - This routine builds initialization ASTs for the +/// Objective-C implementation whose ivars need be initialized. +void Sema::SetIvarInitializers(ObjCImplementationDecl *ObjCImplementation) { +  if (!getLangOptions().CPlusPlus) +    return; +  if (const ObjCInterfaceDecl *OID = ObjCImplementation->getClassInterface()) { +    llvm::SmallVector<ObjCIvarDecl*, 8> ivars; +    CollectIvarsToConstructOrDestruct(OID, ivars); +    if (ivars.empty()) +      return; +    llvm::SmallVector<CXXBaseOrMemberInitializer*, 32> AllToInit; +    for (unsigned i = 0; i < ivars.size(); i++) { +      FieldDecl *Field = ivars[i]; +      CXXBaseOrMemberInitializer *Member; +      InitializedEntity InitEntity = InitializedEntity::InitializeMember(Field); +      InitializationKind InitKind =  +        InitializationKind::CreateDefault(ObjCImplementation->getLocation()); +       +      InitializationSequence InitSeq(*this, InitEntity, InitKind, 0, 0); +      Sema::OwningExprResult MemberInit =  +        InitSeq.Perform(*this, InitEntity, InitKind,  +                        Sema::MultiExprArg(*this, 0, 0)); +      MemberInit = MaybeCreateCXXExprWithTemporaries(move(MemberInit)); +      // Note, MemberInit could actually come back empty if no initialization  +      // is required (e.g., because it would call a trivial default constructor) +      if (!MemberInit.get() || MemberInit.isInvalid()) +        continue; +       +      Member = +        new (Context) CXXBaseOrMemberInitializer(Context, +                                                 Field, SourceLocation(), +                                                 SourceLocation(), +                                                 MemberInit.takeAs<Expr>(), +                                                 SourceLocation()); +      AllToInit.push_back(Member); +    } +    ObjCImplementation->setIvarInitializers(Context,  +                                            AllToInit.data(), AllToInit.size()); +  } +} diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp index 1324e05b6d9..8032030cf0d 100644 --- a/clang/lib/Sema/SemaDeclObjC.cpp +++ b/clang/lib/Sema/SemaDeclObjC.cpp @@ -1441,6 +1441,7 @@ void Sema::ActOnAtEnd(SourceRange AtEnd,            IDecl = IDecl->getSuperClass();          }      } +    SetIvarInitializers(IC);    } else if (ObjCCategoryImplDecl* CatImplClass =                                     dyn_cast<ObjCCategoryImplDecl>(ClassDecl)) {      CatImplClass->setAtEndRange(AtEnd); @@ -1800,23 +1801,15 @@ Sema::DeclPtrTy Sema::ActOnObjCExceptionDecl(Scope *S, Declarator &D) {  }  /// CollectIvarsToConstructOrDestruct - Collect those ivars which require -/// construction (construct=true) or destruction (construct=false) -/// +/// initialization.  void Sema::CollectIvarsToConstructOrDestruct(const ObjCInterfaceDecl *OI, -                                    llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars, -                                    bool construct) { -  if (!getLangOptions().CPlusPlus) -    return; +                                llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars) {    for (ObjCInterfaceDecl::ivar_iterator I = OI->ivar_begin(),         E = OI->ivar_end(); I != E; ++I) {      ObjCIvarDecl *Iv = (*I);      QualType QT = Context.getBaseElementType(Iv->getType()); -    if (const RecordType *RT = QT->getAs<RecordType>()) { -      if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl())) -        if (construct && !RD->hasTrivialConstructor() || -            !construct && !RD->hasTrivialDestructor()) -          Ivars.push_back(*I); -    } +    if (isa<RecordType>(QT)) +      Ivars.push_back(*I);    }    // Find ivars to construct/destruct in class extension. @@ -1825,12 +1818,8 @@ void Sema::CollectIvarsToConstructOrDestruct(const ObjCInterfaceDecl *OI,           E = CDecl->ivar_end(); I != E; ++I) {        ObjCIvarDecl *Iv = (*I);        QualType QT = Context.getBaseElementType(Iv->getType()); -      if (const RecordType *RT = QT->getAs<RecordType>()) { -        if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl())) -          if (construct && !RD->hasTrivialConstructor() || -              !construct && !RD->hasTrivialDestructor()) -            Ivars.push_back(*I); -      } +      if (isa<RecordType>(QT)) +        Ivars.push_back(*I);      }    } @@ -1841,12 +1830,22 @@ void Sema::CollectIvarsToConstructOrDestruct(const ObjCInterfaceDecl *OI,           E = ImplDecl->ivar_end(); I != E; ++I) {        ObjCIvarDecl *Iv = (*I);        QualType QT = Context.getBaseElementType(Iv->getType()); -      if (const RecordType *RT = QT->getAs<RecordType>()) { -        if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl())) -          if (construct && !RD->hasTrivialConstructor() || -              !construct && !RD->hasTrivialDestructor()) -            Ivars.push_back(*I); -      } +      if (isa<RecordType>(QT)) +        Ivars.push_back(*I);      }    }  } + +void ObjCImplementationDecl::setIvarInitializers(ASTContext &C, +                                    CXXBaseOrMemberInitializer ** initializers, +                                                 unsigned numInitializers) { +  if (numInitializers > 0) { +    NumIvarInitializers = numInitializers; +    CXXBaseOrMemberInitializer **ivarInitializers = +    new (C) CXXBaseOrMemberInitializer*[NumIvarInitializers]; +    memcpy(ivarInitializers, initializers, +           numInitializers * sizeof(CXXBaseOrMemberInitializer*)); +    IvarInitializers = ivarInitializers; +  } +} + | 

