[cfe-commits] r80446 - in /cfe/trunk: lib/AST/DeclCXX.cpp lib/Sema/SemaTemplateInstantiateDecl.cpp test/SemaTemplate/instantiate-member-initializers.cpp

Fariborz Jahanian fjahanian at apple.com
Sat Aug 29 15:53:08 PDT 2009


On Aug 29, 2009, at 3:22 PM, Eli Friedman wrote:

> Author: efriedma
> Date: Sat Aug 29 17:22:07 2009
> New Revision: 80446
>
> URL: http://llvm.org/viewvc/llvm-project?rev=80446&view=rev
> Log:
> Make instantiating initializers for classes with a dependent base type
> work correctly.

> The change in lib/AST/DeclCXX.cpp is mostly a large reindentation; I
> couldn't figure out a good way to avoid it.
>
>
> Modified:
>    cfe/trunk/lib/AST/DeclCXX.cpp
>    cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
>    cfe/trunk/test/SemaTemplate/instantiate-member-initializers.cpp
>
> Modified: cfe/trunk/lib/AST/DeclCXX.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclCXX.cpp?rev=80446&r1=80445&r2=80446&view=diff
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- cfe/trunk/lib/AST/DeclCXX.cpp (original)
> +++ cfe/trunk/lib/AST/DeclCXX.cpp Sat Aug 29 17:22:07 2009
> @@ -595,66 +595,81 @@
>   CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(getDeclContext());
>   llvm::SmallVector<CXXBaseOrMemberInitializer*, 32> AllToInit;
>   llvm::DenseMap<const void *, CXXBaseOrMemberInitializer*>  
> AllBaseFields;
> +  bool HasDependentBaseInit = false;
>
>   for (unsigned i = 0; i < NumInitializers; i++) {
>     CXXBaseOrMemberInitializer *Member = Initializers[i];
> -    if (Member->isBaseInitializer())
> +    if (Member->isBaseInitializer()) {
> +      if (Member->getBaseClass()->isDependentType())
> +        HasDependentBaseInit = true;
>       AllBaseFields[Member->getBaseClass()->getAs<RecordType>()] =  
> Member;
> -    else
> +    } else {
>       AllBaseFields[Member->getMember()] = Member;
> +    }
>   }
> +
> +  if (HasDependentBaseInit) {
> +    // If we have a dependent base initialization, we can't  
> determine the
> +    // association between initializers and bases; just dump the  
> known
> +    // initializers into the list, and don't try to deal with other  
> bases.
Not knowing enough about instantiation, I assume that at instantiation  
time,
the base initializer list is rescanned with actual types and the AST  
for the initializer
list is built from scratch. So, I am wondering why this change was  
necessary? Unless it
caused a crash and this patch is avoiding it!

- fariborz


>
> +    for (unsigned i = 0; i < NumInitializers; i++) {
> +      CXXBaseOrMemberInitializer *Member = Initializers[i];
> +      if (Member->isBaseInitializer())
> +        AllToInit.push_back(Member);
> +    }
> +  } else {
> +    // Push virtual bases before others.
> +    for (CXXRecordDecl::base_class_iterator VBase =
> +         ClassDecl->vbases_begin(),
> +         E = ClassDecl->vbases_end(); VBase != E; ++VBase) {
> +      if (VBase->getType()->isDependentType())
> +        continue;
> +      if (CXXBaseOrMemberInitializer *Value =
> +          AllBaseFields.lookup(VBase->getType()- 
> >getAs<RecordType>()))
> +        AllToInit.push_back(Value);
> +      else {
> +        CXXRecordDecl *VBaseDecl =
> +          cast<CXXRecordDecl>(VBase->getType()->getAs<RecordType>()- 
> >getDecl());
> +        assert(VBaseDecl && "setBaseOrMemberInitializers -  
> VBaseDecl null");
> +        if (!VBaseDecl->getDefaultConstructor(C))
> +          Bases.push_back(VBase);
> +        CXXBaseOrMemberInitializer *Member =
> +          new (C) CXXBaseOrMemberInitializer(VBase->getType(), 0, 0,
> +                                            VBaseDecl- 
> >getDefaultConstructor(C),
> +                                             SourceLocation(),
> +                                             SourceLocation());
> +        AllToInit.push_back(Member);
> +      }
> +    }
>
> -  // Push virtual bases before others.
> -  for (CXXRecordDecl::base_class_iterator VBase =
> -       ClassDecl->vbases_begin(),
> -       E = ClassDecl->vbases_end(); VBase != E; ++VBase) {
> -    if (VBase->getType()->isDependentType())
> -      continue;
> -    if (CXXBaseOrMemberInitializer *Value =
> -        AllBaseFields.lookup(VBase->getType()->getAs<RecordType>()))
> -      AllToInit.push_back(Value);
> -    else {
> -      CXXRecordDecl *VBaseDecl =
> -        cast<CXXRecordDecl>(VBase->getType()->getAs<RecordType>()- 
> >getDecl());
> -      assert(VBaseDecl && "setBaseOrMemberInitializers - VBaseDecl  
> null");
> -      if (!VBaseDecl->getDefaultConstructor(C))
> -        Bases.push_back(VBase);
> -      CXXBaseOrMemberInitializer *Member =
> -        new (C) CXXBaseOrMemberInitializer(VBase->getType(), 0, 0,
> -                                           VBaseDecl- 
> >getDefaultConstructor(C),
> +    for (CXXRecordDecl::base_class_iterator Base =
> +         ClassDecl->bases_begin(),
> +         E = ClassDecl->bases_end(); Base != E; ++Base) {
> +      // Virtuals are in the virtual base list and already  
> constructed.
> +      if (Base->isVirtual())
> +        continue;
> +      // Skip dependent types.
> +      if (Base->getType()->isDependentType())
> +        continue;
> +      if (CXXBaseOrMemberInitializer *Value =
> +          AllBaseFields.lookup(Base->getType()->getAs<RecordType>()))
> +        AllToInit.push_back(Value);
> +      else {
> +        CXXRecordDecl *BaseDecl =
> +          cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()- 
> >getDecl());
> +        assert(BaseDecl && "setBaseOrMemberInitializers - BaseDecl  
> null");
> +        if (!BaseDecl->getDefaultConstructor(C))
> +          Bases.push_back(Base);
> +        CXXBaseOrMemberInitializer *Member =
> +        new (C) CXXBaseOrMemberInitializer(Base->getType(), 0, 0,
> +                                           BaseDecl- 
> >getDefaultConstructor(C),
>                                            SourceLocation(),
>                                            SourceLocation());
> -      AllToInit.push_back(Member);
> -    }
> -  }
> -
> -  for (CXXRecordDecl::base_class_iterator Base =
> -       ClassDecl->bases_begin(),
> -       E = ClassDecl->bases_end(); Base != E; ++Base) {
> -    // Virtuals are in the virtual base list and already constructed.
> -    if (Base->isVirtual())
> -      continue;
> -    // Skip dependent types.
> -    if (Base->getType()->isDependentType())
> -      continue;
> -    if (CXXBaseOrMemberInitializer *Value =
> -        AllBaseFields.lookup(Base->getType()->getAs<RecordType>()))
> -      AllToInit.push_back(Value);
> -    else {
> -      CXXRecordDecl *BaseDecl =
> -        cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()- 
> >getDecl());
> -      assert(BaseDecl && "setBaseOrMemberInitializers - BaseDecl  
> null");
> -      if (!BaseDecl->getDefaultConstructor(C))
> -        Bases.push_back(Base);
> -      CXXBaseOrMemberInitializer *Member =
> -      new (C) CXXBaseOrMemberInitializer(Base->getType(), 0, 0,
> -                                         BaseDecl- 
> >getDefaultConstructor(C),
> -                                         SourceLocation(),
> -                                         SourceLocation());
> -      AllToInit.push_back(Member);
> +        AllToInit.push_back(Member);
> +      }
>     }
>   }
> -
> +
>   // non-static data members.
>   for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
>        E = ClassDecl->field_end(); Field != E; ++Field) {
>
> Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=80446&r1=80445&r2=80446&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Sat Aug 29  
> 17:22:07 2009
> @@ -1134,9 +1134,9 @@
>     MemInitResult NewInit;
>
>     if (Init->isBaseInitializer()) {
> -      // FIXME: Type needs to be instantiated.
> -      QualType BaseType =
> -        Context.getCanonicalType(QualType(Init->getBaseClass(), 0));
> +      QualType BaseType(Init->getBaseClass(), 0);
> +      BaseType = SubstType(BaseType, TemplateArgs, Init- 
> >getSourceLocation(),
> +                           New->getDeclName());
>
>       NewInit = BuildBaseInitializer(BaseType,
>                                      (Expr **)NewArgs.data(),
>
> Modified: cfe/trunk/test/SemaTemplate/instantiate-member- 
> initializers.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/instantiate-member-initializers.cpp?rev=80446&r1=80445&r2=80446&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- cfe/trunk/test/SemaTemplate/instantiate-member-initializers.cpp  
> (original)
> +++ cfe/trunk/test/SemaTemplate/instantiate-member-initializers.cpp  
> Sat Aug 29 17:22:07 2009
> @@ -18,3 +18,9 @@
> };
>
> B<int> b0;
> +
> +template <class T> struct AA { AA(int); };
> +template <class T> class BB : public AA<T> {
> +  BB() : AA<T>(1) {}
> +};
> +BB<int> x;
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits




More information about the cfe-commits mailing list