diff options
Diffstat (limited to 'lib/Sema/SemaDeclCXX.cpp')
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 803 |
1 files changed, 400 insertions, 403 deletions
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 1c7157c2c0..64dc41e31a 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -38,13 +38,13 @@ namespace { /// contains any ill-formed subexpressions. For example, this will /// diagnose the use of local variables or parameters within the /// default argument expression. - class VISIBILITY_HIDDEN CheckDefaultArgumentVisitor + class VISIBILITY_HIDDEN CheckDefaultArgumentVisitor : public StmtVisitor<CheckDefaultArgumentVisitor, bool> { Expr *DefaultArg; Sema *S; public: - CheckDefaultArgumentVisitor(Expr *defarg, Sema *s) + CheckDefaultArgumentVisitor(Expr *defarg, Sema *s) : DefaultArg(defarg), S(s) {} bool VisitExpr(Expr *Node); @@ -55,7 +55,7 @@ namespace { /// VisitExpr - Visit all of the children of this expression. bool CheckDefaultArgumentVisitor::VisitExpr(Expr *Node) { bool IsInvalid = false; - for (Stmt::child_iterator I = Node->child_begin(), + for (Stmt::child_iterator I = Node->child_begin(), E = Node->child_end(); I != E; ++I) IsInvalid |= Visit(*I); return IsInvalid; @@ -75,7 +75,7 @@ namespace { // evaluated. Parameters of a function declared before a default // argument expression are in scope and can hide namespace and // class member names. - return S->Diag(DRE->getSourceRange().getBegin(), + return S->Diag(DRE->getSourceRange().getBegin(), diag::err_param_default_argument_references_param) << Param->getDeclName() << DefaultArg->getSourceRange(); } else if (VarDecl *VDecl = dyn_cast<VarDecl>(Decl)) { @@ -83,7 +83,7 @@ namespace { // Local variables shall not be used in default argument // expressions. if (VDecl->isBlockVarDecl()) - return S->Diag(DRE->getSourceRange().getBegin(), + return S->Diag(DRE->getSourceRange().getBegin(), diag::err_param_default_argument_references_local) << VDecl->getDeclName() << DefaultArg->getSourceRange(); } @@ -104,8 +104,7 @@ namespace { bool Sema::SetParamDefaultArgument(ParmVarDecl *Param, ExprArg DefaultArg, - SourceLocation EqualLoc) -{ + SourceLocation EqualLoc) { QualType ParamType = Param->getType(); if (RequireCompleteType(Param->getLocation(), Param->getType(), @@ -115,24 +114,24 @@ Sema::SetParamDefaultArgument(ParmVarDecl *Param, ExprArg DefaultArg, } Expr *Arg = (Expr *)DefaultArg.get(); - + // C++ [dcl.fct.default]p5 // A default argument expression is implicitly converted (clause // 4) to the parameter type. The default argument expression has // the same semantic constraints as the initializer expression in // a declaration of a variable of the parameter type, using the // copy-initialization semantics (8.5). - if (CheckInitializerTypes(Arg, ParamType, EqualLoc, + if (CheckInitializerTypes(Arg, ParamType, EqualLoc, Param->getDeclName(), /*DirectInit=*/false)) return true; Arg = MaybeCreateCXXExprWithTemporaries(Arg, /*DestroyTemps=*/false); - + // Okay: add the default argument to the parameter Param->setDefaultArg(Arg); - + DefaultArg.release(); - + return false; } @@ -140,11 +139,11 @@ Sema::SetParamDefaultArgument(ParmVarDecl *Param, ExprArg DefaultArg, /// provided for a function parameter is well-formed. If so, attach it /// to the parameter declaration. void -Sema::ActOnParamDefaultArgument(DeclPtrTy param, SourceLocation EqualLoc, +Sema::ActOnParamDefaultArgument(DeclPtrTy param, SourceLocation EqualLoc, ExprArg defarg) { if (!param || !defarg.get()) return; - + ParmVarDecl *Param = cast<ParmVarDecl>(param.getAs<Decl>()); UnparsedDefaultArgLocs.erase(Param); @@ -165,7 +164,7 @@ Sema::ActOnParamDefaultArgument(DeclPtrTy param, SourceLocation EqualLoc, Param->setInvalidDecl(); return; } - + SetParamDefaultArgument(Param, move(DefaultArg), EqualLoc); } @@ -173,16 +172,16 @@ Sema::ActOnParamDefaultArgument(DeclPtrTy param, SourceLocation EqualLoc, /// argument for a function parameter, but we can't parse it yet /// because we're inside a class definition. Note that this default /// argument will be parsed later. -void Sema::ActOnParamUnparsedDefaultArgument(DeclPtrTy param, +void Sema::ActOnParamUnparsedDefaultArgument(DeclPtrTy param, SourceLocation EqualLoc, SourceLocation ArgLoc) { if (!param) return; - + ParmVarDecl *Param = cast<ParmVarDecl>(param.getAs<Decl>()); if (Param) Param->setUnparsedDefaultArg(); - + UnparsedDefaultArgLocs[Param] = ArgLoc; } @@ -191,11 +190,11 @@ void Sema::ActOnParamUnparsedDefaultArgument(DeclPtrTy param, void Sema::ActOnParamDefaultArgumentError(DeclPtrTy param) { if (!param) return; - + ParmVarDecl *Param = cast<ParmVarDecl>(param.getAs<Decl>()); - + Param->setInvalidDecl(); - + UnparsedDefaultArgLocs.erase(Param); } @@ -258,8 +257,8 @@ bool Sema::MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old) { ParmVarDecl *OldParam = Old->getParamDecl(p); ParmVarDecl *NewParam = New->getParamDecl(p); - if(OldParam->getDefaultArg() && NewParam->getDefaultArg()) { - Diag(NewParam->getLocation(), + if (OldParam->getDefaultArg() && NewParam->getDefaultArg()) { + Diag(NewParam->getLocation(), diag::err_param_default_argument_redefinition) << NewParam->getDefaultArg()->getSourceRange(); Diag(OldParam->getLocation(), diag::note_previous_definition); @@ -300,19 +299,19 @@ void Sema::CheckCXXDefaultArguments(FunctionDecl *FD) { // declarations. A default argument shall not be redefined // by a later declaration (not even to the same value). unsigned LastMissingDefaultArg = 0; - for(; p < NumParams; ++p) { + for (; p < NumParams; ++p) { ParmVarDecl *Param = FD->getParamDecl(p); if (!Param->hasDefaultArg()) { if (Param->isInvalidDecl()) /* We already complained about this parameter. */; else if (Param->getIdentifier()) - Diag(Param->getLocation(), + Diag(Param->getLocation(), diag::err_param_default_argument_missing_name) << Param->getIdentifier(); else - Diag(Param->getLocation(), + Diag(Param->getLocation(), diag::err_param_default_argument_missing); - + LastMissingDefaultArg = p; } } @@ -352,7 +351,7 @@ bool Sema::isCurrentClassName(const IdentifierInfo &II, Scope *, return false; } -/// \brief Check the validity of a C++ base class specifier. +/// \brief Check the validity of a C++ base class specifier. /// /// \returns a new CXXBaseSpecifier if well-formed, emits diagnostics /// and returns NULL otherwise. @@ -360,7 +359,7 @@ CXXBaseSpecifier * Sema::CheckBaseSpecifier(CXXRecordDecl *Class, SourceRange SpecifierRange, bool Virtual, AccessSpecifier Access, - QualType BaseType, + QualType BaseType, SourceLocation BaseLoc) { // C++ [class.union]p1: // A union shall not have base classes. @@ -371,7 +370,7 @@ Sema::CheckBaseSpecifier(CXXRecordDecl *Class, } if (BaseType->isDependentType()) - return new (Context) CXXBaseSpecifier(SpecifierRange, Virtual, + return new (Context) CXXBaseSpecifier(SpecifierRange, Virtual, Class->getTagKind() == RecordDecl::TK_class, Access, BaseType); @@ -391,7 +390,7 @@ Sema::CheckBaseSpecifier(CXXRecordDecl *Class, // C++ [class.derived]p2: // The class-name in a base-specifier shall not be an incompletely // defined class. - if (RequireCompleteType(BaseLoc, BaseType, + if (RequireCompleteType(BaseLoc, BaseType, PDiag(diag::err_incomplete_base_class) << SpecifierRange)) return 0; @@ -433,7 +432,7 @@ Sema::CheckBaseSpecifier(CXXRecordDecl *Class, Class->setEmpty(false); } else { // C++ [class.ctor]p5: - // A constructor is trivial if all the direct base classes of its + // A constructor is trivial if all the direct base classes of its // class have trivial constructors. if (!cast<CXXRecordDecl>(BaseDecl)->hasTrivialConstructor()) Class->setHasTrivialConstructor(false); @@ -456,20 +455,20 @@ Sema::CheckBaseSpecifier(CXXRecordDecl *Class, // have trivial destructors. if (!cast<CXXRecordDecl>(BaseDecl)->hasTrivialDestructor()) Class->setHasTrivialDestructor(false); - + // Create the base specifier. // FIXME: Allocate via ASTContext? - return new (Context) CXXBaseSpecifier(SpecifierRange, Virtual, - Class->getTagKind() == RecordDecl::TK_class, + return new (Context) CXXBaseSpecifier(SpecifierRange, Virtual, + Class->getTagKind() == RecordDecl::TK_class, Access, BaseType); } /// ActOnBaseSpecifier - Parsed a base specifier. A base specifier is /// one entry in the base class list of a class specifier, for -/// example: -/// class foo : public bar, virtual private baz { +/// example: +/// class foo : public bar, virtual private baz { /// 'public bar' and 'virtual private baz' are each base-specifiers. -Sema::BaseResult +Sema::BaseResult Sema::ActOnBaseSpecifier(DeclPtrTy classdecl, SourceRange SpecifierRange, bool Virtual, AccessSpecifier Access, TypeTy *basetype, SourceLocation BaseLoc) { @@ -483,7 +482,7 @@ Sema::ActOnBaseSpecifier(DeclPtrTy classdecl, SourceRange SpecifierRange, Virtual, Access, BaseType, BaseLoc)) return BaseSpec; - + return true; } @@ -504,7 +503,7 @@ bool Sema::AttachBaseSpecifiers(CXXRecordDecl *Class, CXXBaseSpecifier **Bases, unsigned NumGoodBases = 0; bool Invalid = false; for (unsigned idx = 0; idx < NumBases; ++idx) { - QualType NewBaseType + QualType NewBaseType = Context.getCanonicalType(Bases[idx]->getType()); NewBaseType = NewBaseType.getUnqualifiedType(); @@ -543,7 +542,7 @@ bool Sema::AttachBaseSpecifiers(CXXRecordDecl *Class, CXXBaseSpecifier **Bases, /// ActOnBaseSpecifiers - Attach the given base specifiers to the /// class, after checking whether there are any duplicate base /// classes. -void Sema::ActOnBaseSpecifiers(DeclPtrTy ClassDecl, BaseTy **Bases, +void Sema::ActOnBaseSpecifiers(DeclPtrTy ClassDecl, BaseTy **Bases, unsigned NumBases) { if (!ClassDecl || !Bases || !NumBases) return; @@ -592,7 +591,7 @@ Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D, Diag(DS.getStorageClassSpecLoc(), diag::err_mutable_function); else Diag(DS.getThreadSpecLoc(), diag::err_mutable_function); - + // FIXME: It would be nicer if the keyword was ignored only for this // declarator. Otherwise we could get follow-up errors. D.getMutableDeclSpec().ClearStorageClassSpecs(); @@ -670,17 +669,17 @@ Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D, // A function typedef ("typedef int f(); f a;"). // C++ 9.6p3: A bit-field shall have integral or enumeration type. Diag(Loc, diag::err_not_integral_type_bitfield) - << Name << cast<ValueDecl>(Member)->getType() + << Name << cast<ValueDecl>(Member)->getType() << BitWidth->getSourceRange(); } - + DeleteExpr(BitWidth); BitWidth = 0; Member->setInvalidDecl(); } Member->setAccess(AS); - + // If we have declared a member function template, set the access of the // templated declaration as well. if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(Member)) @@ -702,7 +701,7 @@ Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D, } /// ActOnMemInitializer - Handle a C++ member initializer. -Sema::MemInitResult +Sema::MemInitResult Sema::ActOnMemInitializer(DeclPtrTy ConstructorD, Scope *S, const CXXScopeSpec &SS, @@ -715,10 +714,10 @@ Sema::ActOnMemInitializer(DeclPtrTy ConstructorD, SourceLocation RParenLoc) { if (!ConstructorD) return true; - + AdjustDeclIfTemplate(ConstructorD); - - CXXConstructorDecl *Constructor + + CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ConstructorD.getAs<Decl>()); if (!Constructor) { // The user wrote a constructor initializer on a function that is @@ -743,7 +742,7 @@ Sema::ActOnMemInitializer(DeclPtrTy ConstructorD, if (!SS.getScopeRep() && !TemplateTypeTy) { // Look for a member, first. FieldDecl *Member = 0; - DeclContext::lookup_result Result + DeclContext::lookup_result Result = ClassDecl->lookup(MemberOrBase); if (Result.first != Result.second) Member = dyn_cast<FieldDecl>(*Result.first); @@ -755,12 +754,12 @@ Sema::ActOnMemInitializer(DeclPtrTy ConstructorD, RParenLoc); } // It didn't name a member, so see if it names a class. - TypeTy *BaseTy = TemplateTypeTy ? TemplateTypeTy + TypeTy *BaseTy = TemplateTypeTy ? TemplateTypeTy : getTypeName(*MemberOrBase, IdLoc, S, &SS); if (!BaseTy) return Diag(IdLoc, diag::err_mem_init_not_member_or_class) << MemberOrBase << SourceRange(IdLoc, RParenLoc); - + QualType BaseType = GetTypeFromParser(BaseTy); return BuildBaseInitializer(BaseType, (Expr **)Args, NumArgs, IdLoc, @@ -784,10 +783,10 @@ Sema::BuildMemberInitializer(FieldDecl *Member, Expr **Args, } else if (FieldType->getAs<RecordType>()) { if (!HasDependentArg) C = PerformInitializationByConstructor( - FieldType, (Expr **)Args, NumArgs, IdLoc, + FieldType, (Expr **)Args, NumArgs, IdLoc, SourceRange(IdLoc, RParenLoc), Member->getDeclName(), IK_Direct); } else if (NumArgs != 1 && NumArgs != 0) { - return Diag(IdLoc, diag::err_mem_initializer_mismatch) + return Diag(IdLoc, diag::err_mem_initializer_mismatch) << Member->getDeclName() << SourceRange(IdLoc, RParenLoc); } else if (!HasDependentArg) { Expr *NewExp; @@ -807,7 +806,7 @@ Sema::BuildMemberInitializer(FieldDecl *Member, Expr **Args, Args[0] = NewExp; } // FIXME: Perform direct initialization of the member. - return new (Context) CXXBaseOrMemberInitializer(Member, (Expr **)Args, + return new (Context) CXXBaseOrMemberInitializer(Member, (Expr **)Args, NumArgs, C, IdLoc, RParenLoc); } @@ -830,12 +829,12 @@ Sema::BuildBaseInitializer(QualType BaseType, Expr **Args, // of that class, the mem-initializer is ill-formed. A // mem-initializer-list can initialize a base class using any // name that denotes that base class type. - + // First, check for a direct base class. const CXXBaseSpecifier *DirectBaseSpec = 0; for (CXXRecordDecl::base_class_const_iterator Base = ClassDecl->bases_begin(); Base != ClassDecl->bases_end(); ++Base) { - if (Context.getCanonicalType(BaseType).getUnqualifiedType() == + if (Context.getCanonicalType(BaseType).getUnqualifiedType() == Context.getCanonicalType(Base->getType()).getUnqualifiedType()) { // We found a direct base of this type. That's what we're // initializing. @@ -843,7 +842,7 @@ Sema::BuildBaseInitializer(QualType BaseType, Expr **Args, break; } } - + // Check for a virtual base class. // FIXME: We might be able to short-circuit this if we know in advance that // there are no virtual bases. @@ -854,7 +853,7 @@ Sema::BuildBaseInitializer(QualType BaseType, Expr **Args, BasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, /*DetectVirtual=*/false); if (IsDerivedFrom(Context.getTypeDeclType(ClassDecl), BaseType, Paths)) { - for (BasePaths::paths_iterator Path = Paths.begin(); + for (BasePaths::paths_iterator Path = Paths.begin(); Path != Paths.end(); ++Path) { if (Path->back().Base->isVirtual()) { VirtualBaseSpec = Path->back().Base; @@ -886,11 +885,11 @@ Sema::BuildBaseInitializer(QualType BaseType, Expr **Args, DeclarationName Name = Context.DeclarationNames.getCXXConstructorName( Context.getCanonicalType(BaseType)); C = PerformInitializationByConstructor(BaseType, (Expr **)Args, NumArgs, - IdLoc, SourceRange(IdLoc, RParenLoc), + IdLoc, SourceRange(IdLoc, RParenLoc), Name, IK_Direct); } - return new (Context) CXXBaseOrMemberInitializer(BaseType, (Expr **)Args, + return new (Context) CXXBaseOrMemberInitializer(BaseType, (Expr **)Args, NumArgs, C, IdLoc, RParenLoc); } @@ -898,7 +897,7 @@ void Sema::setBaseOrMemberInitializers(CXXConstructorDecl *Constructor, CXXBaseOrMemberInitializer **Initializers, unsigned NumInitializers, - llvm::SmallVectorImpl<CXXBaseSpecifier *>& Bases, + llvm::SmallVectorImpl<CXXBaseSpecifier *>& Bases, llvm::SmallVectorImpl<FieldDecl *>&Fields) { // We need to build the initializer AST according to order of construction // and not what user specified in the Initializers list. @@ -906,7 +905,7 @@ Sema::setBaseOrMemberInitializers(CXXConstructorDecl *Constructor, 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()) { @@ -917,13 +916,13 @@ Sema::setBaseOrMemberInitializers(CXXConstructorDecl *Constructor, AllBaseFields[Member->getMember()] = Member; } } - + if (HasDependentBaseInit) { // FIXME. This does not preserve the ordering of the initializers. // Try (with -Wreorder) // template<class X> struct A {}; - // template<class X> struct B : A<X> { - // B() : x1(10), A<X>() {} + // template<class X> struct B : A<X> { + // B() : x1(10), A<X>() {} // int x1; // }; // B<int> x; @@ -931,7 +930,7 @@ Sema::setBaseOrMemberInitializers(CXXConstructorDecl *Constructor, // while preserving user-declared initializer list. When this routine is // called during instantiatiation process, this routine will rebuild the // oderdered initializer list correctly. - + // 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. @@ -947,9 +946,9 @@ Sema::setBaseOrMemberInitializers(CXXConstructorDecl *Constructor, E = ClassDecl->vbases_end(); VBase != E; ++VBase) { if (VBase->getType()->isDependentType()) continue; - if (CXXBaseOrMemberInitializer *Value = + if (CXXBaseOrMemberInitializer *Value = AllBaseFields.lookup(VBase->getType()->getAs<RecordType>())) { - CXXRecordDecl *BaseDecl = + CXXRecordDecl *BaseDecl = cast<CXXRecordDecl>(VBase->getType()->getAs<RecordType>()->getDecl()); assert(BaseDecl && "setBaseOrMemberInitializers - BaseDecl null"); if (CXXConstructorDecl *Ctor = BaseDecl->getDefaultConstructor(Context)) @@ -957,7 +956,7 @@ Sema::setBaseOrMemberInitializers(CXXConstructorDecl *Constructor, AllToInit.push_back(Value); } else { - CXXRecordDecl *VBaseDecl = + CXXRecordDecl *VBaseDecl = cast<CXXRecordDecl>(VBase->getType()->getAs<RecordType>()->getDecl()); assert(VBaseDecl && "setBaseOrMemberInitializers - VBaseDecl null"); CXXConstructorDecl *Ctor = VBaseDecl->getDefaultConstructor(Context); @@ -966,7 +965,7 @@ Sema::setBaseOrMemberInitializers(CXXConstructorDecl *Constructor, else MarkDeclarationReferenced(Constructor->getLocation(), Ctor); - CXXBaseOrMemberInitializer *Member = + CXXBaseOrMemberInitializer *Member = new (Context) CXXBaseOrMemberInitializer(VBase->getType(), 0, 0, Ctor, SourceLocation(), @@ -974,7 +973,7 @@ Sema::setBaseOrMemberInitializers(CXXConstructorDecl *Constructor, AllToInit.push_back(Member); } } - + for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin(), E = ClassDecl->bases_end(); Base != E; ++Base) { @@ -984,9 +983,9 @@ Sema::setBaseOrMemberInitializers(CXXConstructorDecl *Constructor, // Skip dependent types. if (Base->getType()->isDependentType()) continue; - if (CXXBaseOrMemberInitializer *Value = + if (CXXBaseOrMemberInitializer *Value = AllBaseFields.lookup(Base->getType()->getAs<RecordType>())) { - CXXRecordDecl *BaseDecl = + CXXRecordDecl *BaseDecl = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl()); assert(BaseDecl && "setBaseOrMemberInitializers - BaseDecl null"); if (CXXConstructorDecl *Ctor = BaseDecl->getDefaultConstructor(Context)) @@ -994,7 +993,7 @@ Sema::setBaseOrMemberInitializers(CXXConstructorDecl *Constructor, AllToInit.push_back(Value); } else { - CXXRecordDecl *BaseDecl = + CXXRecordDecl *BaseDecl = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl()); assert(BaseDecl && "setBaseOrMemberInitializers - BaseDecl null"); CXXConstructorDecl *Ctor = BaseDecl->getDefaultConstructor(Context); @@ -1003,7 +1002,7 @@ Sema::setBaseOrMemberInitializers(CXXConstructorDecl *Constructor, else MarkDeclarationReferenced(Constructor->getLocation(), Ctor); - CXXBaseOrMemberInitializer *Member = + CXXBaseOrMemberInitializer *Member = new (Context) CXXBaseOrMemberInitializer(Base->getType(), 0, 0, BaseDecl->getDefaultConstructor(Context), SourceLocation(), @@ -1012,16 +1011,16 @@ Sema::setBaseOrMemberInitializers(CXXConstructorDecl *Constructor, } } } - + // non-static data members. for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(), E = ClassDecl->field_end(); Field != E; ++Field) { if ((*Field)->isAnonymousStructOrUnion()) { - if (const RecordType *FieldClassType = + if (const RecordType *FieldClassType = Field->getType()->getAs<RecordType>()) { CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(FieldClassType->getDecl()); - for(RecordDecl::field_iterator FA = FieldClassDecl->field_begin(), + for (RecordDecl::field_iterator FA = FieldClassDecl->field_begin(), EA = FieldClassDecl->field_end(); FA != EA; FA++) { if (CXXBaseOrMemberInitializer *Value = AllBaseFields.lookup(*FA)) { // 'Member' is the anonymous union field and 'AnonUnionMember' is @@ -1041,21 +1040,21 @@ Sema::setBaseOrMemberInitializers(CXXConstructorDecl *Constructor, if (const RecordType* RT = FT->getAs<RecordType>()) { CXXRecordDecl *FieldRecDecl = cast<CXXRecordDecl>(RT->getDecl()); assert(FieldRecDecl && "setBaseOrMemberInitializers - BaseDecl null"); - if (CXXConstructorDecl *Ctor = + if (CXXConstructorDecl *Ctor = FieldRecDecl->getDefaultConstructor(Context)) MarkDeclarationReferenced(Value->getSourceLocation(), Ctor); } AllToInit.push_back(Value); continue; } - + QualType FT = Context.getBaseElementType((*Field)->getType()); if (const RecordType* RT = FT->getAs<RecordType>()) { CXXConstructorDecl *Ctor = cast<CXXRecordDecl>(RT->getDecl())->getDefaultConstructor(Context); if (!Ctor && !FT->isDependentType()) Fields.push_back(*Field); - CXXBaseOrMemberInitializer *Member = + CXXBaseOrMemberInitializer *Member = new (Context) CXXBaseOrMemberInitializer((*Field), 0, 0, Ctor, SourceLocation(), @@ -1080,13 +1079,13 @@ Sema::setBaseOrMemberInitializers(CXXConstructorDecl *Constructor, Diag((*Field)->getLocation(), diag::note_declared_at); } } - + NumInitializers = AllToInit.size(); if (NumInitializers > 0) { Constructor->setNumBaseOrMemberInitializers(NumInitializers); CXXBaseOrMemberInitializer **baseOrMemberInitializers = new (Context) CXXBaseOrMemberInitializer*[NumInitializers]; - + Constructor->setBaseOrMemberInitializers(baseOrMemberInitializers); for (unsigned Idx = 0; Idx < NumInitializers; ++Idx) baseOrMemberInitializers[Idx] = AllToInit[Idx]; @@ -1101,14 +1100,14 @@ Sema::BuildBaseOrMemberInitializers(ASTContext &C, ) { llvm::SmallVector<CXXBaseSpecifier *, 4>Bases; llvm::SmallVector<FieldDecl *, 4>Members; - - setBaseOrMemberInitializers(Constructor, + + setBaseOrMemberInitializers(Constructor, Initializers, NumInitializers, Bases, Members); for (unsigned int i = 0; i < Bases.size(); i++) - Diag(Bases[i]->getSourceRange().getBegin(), + Diag(Bases[i]->getSourceRange().getBegin(), diag::err_missing_default_constructor) << 0 << Bases[i]->getType(); for (unsigned int i = 0; i < Members.size(); i++) - Diag(Members[i]->getLocation(), diag::err_missing_default_constructor) + Diag(Members[i]->getLocation(), diag::err_missing_default_constructor) << 1 << Members[i]->getType(); } @@ -1124,20 +1123,20 @@ static void *GetKeyForTopLevelField(FieldDecl *Field) { static void *GetKeyForBase(QualType BaseType) { if (const RecordType *RT = BaseType->getAs<RecordType>()) return (void *)RT; - + assert(0 && "Unexpected base type!"); return 0; } -static void *GetKeyForMember(CXXBaseOrMemberInitializer *Member, +static void *GetKeyForMember(CXXBaseOrMemberInitializer *Member, bool MemberMaybeAnon = false) { // For fields injected into the class via declaration of an anonymous union, // use its anonymous union class declaration as the unique key. if (Member->isMemberInitializer()) { FieldDecl *Field = Member->getMember(); - + // After BuildBaseOrMemberInitializers call, Field is the anonymous union - // data member of the class. Data member used in the initializer list is + // data member of the class. Data member used in the initializer list is // in AnonUnionMember field. if (MemberMaybeAnon && Field->isAnonymousStructOrUnion()) Field = Member->getAnonUnionMember(); @@ -1148,31 +1147,31 @@ static void *GetKeyForMember(CXXBaseOrMemberInitializer *Member, } return static_cast<void *>(Field); } - + return GetKeyForBase(QualType(Member->getBaseClass(), 0)); } -void Sema::ActOnMemInitializers(DeclPtrTy ConstructorDecl, +void Sema::ActOnMemInitializers(DeclPtrTy ConstructorDecl, SourceLocation ColonLoc, MemInitTy **MemInits, unsigned NumMemInits) { if (!ConstructorDecl) return; AdjustDeclIfTemplate(ConstructorDecl); - - CXXConstructorDecl *Constructor + + CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ConstructorDecl.getAs<Decl>()); - + if (!Constructor) { Diag(ColonLoc, diag::err_only_constructors_take_base_inits); return; } - + if (!Constructor->isDependentContext()) { llvm::DenseMap<void*, CXXBaseOrMemberInitializer *>Members; bool err = false; for (unsigned i = 0; i < NumMemInits; i++) { - CXXBaseOrMemberInitializer *Member = + CXXBaseOrMemberInitializer *Member = static_cast<CXXBaseOrMemberInitializer*>(MemInits[i]); void *KeyToMember = GetKeyForMember(Member); CXXBaseOrMemberInitializer *&PrevMember = Members[KeyToMember]; @@ -1181,13 +1180,13 @@ void Sema::ActOnMemInitializers(DeclPtrTy ConstructorDecl, continue; } if (FieldDecl *Field = Member->getMember()) - Diag(Member->getSourceLocation(), + Diag(Member->getSourceLocation(), diag::error_multiple_mem_initialization) << Field->getNameAsString(); else { Type *BaseClass = Member->getBaseClass(); assert(BaseClass && "ActOnMemInitializers - neither field or base"); - Diag(Member->getSourceLocation(), + Diag(Member->getSourceLocation(), diag::error_multiple_base_initialization) << BaseClass->getDesugaredType(true); } @@ -1195,28 +1194,28 @@ void Sema::ActOnMemInitializers(DeclPtrTy ConstructorDecl, << 0; err = true; } - + if (err) return; } - + BuildBaseOrMemberInitializers(Context, Constructor, - reinterpret_cast<CXXBaseOrMemberInitializer **>(MemInits), + reinterpret_cast<CXXBaseOrMemberInitializer **>(MemInits), NumMemInits); - + if (Constructor->isDependentContext()) return; - - if (Diags.getDiagnosticLevel(diag::warn_base_initialized) == + + if (Diags.getDiagnosticLevel(diag::warn_base_initialized) == Diagnostic::Ignored && - Diags.getDiagnosticLevel(diag::warn_field_initialized) == + Diags.getDiagnosticLevel(diag::warn_field_initialized) == Diagnostic::Ignored) return; - + // Also issue warning if order of ctor-initializer list does not match order // of 1) base class declarations and 2) order of non-static data members. llvm::SmallVector<const void*, 32> AllBaseOrMembers; - + CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(Constructor->getDeclContext()); // Push virtual bases before others. @@ -1224,7 +1223,7 @@ void Sema::ActOnMemInitializers(DeclPtrTy ConstructorDecl, ClassDecl->vbases_begin(), E = ClassDecl->vbases_end(); VBase != E; ++VBase) AllBaseOrMembers.push_back(GetKeyForBase(VBase->getType())); - + for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin(), E = ClassDecl->bases_end(); Base != E; ++Base) { // Virtuals are alread in the virtual base list and are constructed @@ -1233,16 +1232,16 @@ void Sema::ActOnMemInitializers(DeclPtrTy ConstructorDecl, continue; AllBaseOrMembers.push_back(GetKeyForBase(Base->getType())); } - + for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(), E = ClassDecl->field_end(); Field != E; ++Field) AllBaseOrMembers.push_back(GetKeyForTopLevelField(*Field)); - + int Last = AllBaseOrMembers.size(); int curIndex = 0; CXXBaseOrMemberInitializer *PrevMember = 0; for (unsigned i = 0; i < NumMemInits; i++) { - CXXBaseOrMemberInitializer *Member = + CXXBaseOrMemberInitializer *Member = static_cast<CXXBaseOrMemberInitializer*>(MemInits[i]); void *MemberInCtorList = GetKeyForMember(Member, true); @@ -1257,27 +1256,27 @@ void Sema::ActOnMemInitializers(DeclPtrTy ConstructorDecl, // Diagnostics is for an initialized base class. Type *BaseClass = PrevMember->getBaseClass(); Diag(PrevMember->getSourceLocation(), - diag::warn_base_initialized) + diag::warn_base_initialized) << BaseClass->getDesugaredType(true); } else { FieldDecl *Field = PrevMember->getMember(); Diag(PrevMember->getSourceLocation(), - diag::warn_field_initialized) + diag::warn_field_initialized) << Field->getNameAsString(); } // Also the note! if (FieldDecl *Field = Member->getMember()) - Diag(Member->getSourceLocation(), + Diag(Member->getSourceLocation(), diag::note_fieldorbase_initialized_here) << 0 << Field->getNameAsString(); else { Type *BaseClass = Member->getBaseClass(); - Diag(Member->getSourceLocation(), + Diag(Member->getSourceLocation(), diag::note_fieldorbase_initialized_here) << 1 << BaseClass->getDesugaredType(true); } for (curIndex = 0; curIndex < Last; curIndex++) - if (MemberInCtorList == AllBaseOrMembers[curIndex]) + if (MemberInCtorList == AllBaseOrMembers[curIndex]) break; } PrevMember = Member; @@ -1288,7 +1287,7 @@ void Sema::computeBaseOrMembersToDestroy(CXXDestructorDecl *Destructor) { CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(Destructor->getDeclContext()); llvm::SmallVector<uintptr_t, 32> AllToDestruct; - + for (CXXRecordDecl::base_class_iterator VBase = ClassDecl->vbases_begin(), E = ClassDecl->vbases_end(); VBase != E; ++VBase) { if (VBase->getType()->isDependentType()) @@ -1299,11 +1298,11 @@ Sema::computeBaseOrMembersToDestroy(CXXDestructorDecl *Destructor) { if (BaseClassDecl->hasTrivialDestructor()) continue; if (const CXXDestructorDecl *Dtor = BaseClassDecl->getDestructor(Context)) - MarkDeclarationReferenced(Destructor->getLocation(), + MarkDeclarationReferenced(Destructor->getLocation(), const_cast<CXXDestructorDecl*>(Dtor)); - - uintptr_t Member = - reinterpret_cast<uintptr_t>(VBase->getType().getTypePtr()) + + uintptr_t Member = + reinterpret_cast<uintptr_t>(VBase->getType().getTypePtr()) | CXXDestructorDecl::VBASE; AllToDestruct.push_back(Member); } @@ -1320,37 +1319,37 @@ Sema::computeBaseOrMembersToDestroy(CXXDestructorDecl *Destructor) { if (BaseClassDecl->hasTrivialDestructor()) continue; if (const CXXDestructorDecl *Dtor = BaseClassDecl->getDestructor(Context)) - MarkDeclarationReferenced(Destructor->getLocation(), + MarkDeclarationReferenced(Destructor->getLocation(), const_cast<CXXDestructorDecl*>(Dtor)); - uintptr_t Member = - reinterpret_cast<uintptr_t>(Base->getType().getTypePtr()) + uintptr_t Member = + reinterpret_cast<uintptr_t>(Base->getType().getTypePtr()) | CXXDestructorDecl::DRCTNONVBASE; AllToDestruct.push_back(Member); } - + // non-static data members. for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(), E = ClassDecl->field_end(); Field != E; ++Field) { QualType FieldType = Context.getBaseElementType((*Field)->getType()); - + if (const RecordType* RT = FieldType->getAs<RecordType>()) { // Skip over virtual bases which have trivial destructors. CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl()); if (FieldClassDecl->hasTrivialDestructor()) continue; - if (const CXXDestructorDecl *Dtor = + if (const CXXDestructorDecl *Dtor = FieldClassDecl->getDestructor(Context)) - MarkDeclarationReferenced(Destructor->getLocation(), + MarkDeclarationReferenced(Destructor->getLocation(), const_cast<CXXDestructorDecl*>(Dtor)); uintptr_t Member = reinterpret_cast<uintptr_t>(*Field); AllToDestruct.push_back(Member); } } - + unsigned NumDestructions = AllToDestruct.size(); if (NumDestructions > 0) { Destructor->setNumBaseOrMemberDestructions(NumDestructions); - uintptr_t *BaseOrMemberDestructions = + uintptr_t *BaseOrMemberDestructions = new (Context) uintptr_t [NumDestructions]; // Insert in reverse order. for (int Idx = NumDestructions-1, i=0 ; Idx >= 0; --Idx) @@ -1362,10 +1361,10 @@ Sema::computeBaseOrMembersToDestroy(CXXDestructorDecl *Destructor) { void Sema::ActOnDefaultCtorInitializers(DeclPtrTy CDtorDecl) { if (!CDtorDecl) return; - + AdjustDeclIfTemplate(CDtorDecl); - - if (CXXConstructorDecl *Constructor + + if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(CDtorDecl.getAs<Decl>())) BuildBaseOrMemberInitializers(Context, Constructor, @@ -1383,31 +1382,31 @@ namespace { private: MethodList Methods; - + void Collect(const CXXRecordDecl* RD, MethodList& Methods); - + public: - PureVirtualMethodCollector(ASTContext &Ctx, const CXXRecordDecl* RD) + PureVirtualMethodCollector(ASTContext &Ctx, const CXXRecordDecl* RD) : Context(Ctx) { - + MethodList List; Collect(RD, List); - + // Copy the temporary list to methods, and make sure to ignore any // null entries. for (size_t i = 0, e = List.size(); i != e; ++i) { if (List[i]) Methods.push_back(List[i]); - } + } } - + bool empty() const { return Methods.empty(); } - + MethodList::const_iterator methods_begin() { return Methods.begin(); } MethodList::const_iterator methods_end() { return Methods.end(); } }; - - void PureVirtualMethodCollector::Collect(const CXXRecordDecl* RD, + + void PureVirtualMethodCollector::Collect(const CXXRecordDecl* RD, |