diff options
author | rdivacky <rdivacky@FreeBSD.org> | 2010-03-06 09:23:02 +0000 |
---|---|---|
committer | rdivacky <rdivacky@FreeBSD.org> | 2010-03-06 09:23:02 +0000 |
commit | d2e6cf1d1c6468396ec057119c32aa58b1ee5ac9 (patch) | |
tree | 7e0a88c3c6cb70271946aaa95a231b3da55d9f91 /lib/Sema | |
parent | df90325d4c0a65ee64d2dae3ed9b5b34f7418533 (diff) | |
download | FreeBSD-src-d2e6cf1d1c6468396ec057119c32aa58b1ee5ac9.zip FreeBSD-src-d2e6cf1d1c6468396ec057119c32aa58b1ee5ac9.tar.gz |
Update clang to r97873.
Diffstat (limited to 'lib/Sema')
-rw-r--r-- | lib/Sema/Sema.h | 8 | ||||
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 31 | ||||
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 134 | ||||
-rw-r--r-- | lib/Sema/SemaExprCXX.cpp | 2 | ||||
-rw-r--r-- | lib/Sema/SemaInit.cpp | 3 | ||||
-rw-r--r-- | lib/Sema/SemaOverload.cpp | 41 | ||||
-rw-r--r-- | lib/Sema/SemaType.cpp | 3 | ||||
-rw-r--r-- | lib/Sema/TreeTransform.h | 2 |
8 files changed, 169 insertions, 55 deletions
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index efd04e8..a94d07a 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -1097,12 +1097,16 @@ public: ImplicitConversionSequence TryObjectArgumentInitialization(QualType FromType, CXXMethodDecl *Method, CXXRecordDecl *ActingContext); - bool PerformObjectArgumentInitialization(Expr *&From, CXXMethodDecl *Method); + bool PerformObjectArgumentInitialization(Expr *&From, + NestedNameSpecifier *Qualifier, + CXXMethodDecl *Method); ImplicitConversionSequence TryContextuallyConvertToBool(Expr *From); bool PerformContextuallyConvertToBool(Expr *&From); - bool PerformObjectMemberConversion(Expr *&From, NamedDecl *Member); + bool PerformObjectMemberConversion(Expr *&From, + NestedNameSpecifier *Qualifier, + NamedDecl *Member); // Members have to be NamespaceDecl* or TranslationUnitDecl*. // TODO: make this is a typesafe union. diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 574b225..0708d41 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -5212,14 +5212,35 @@ VarDecl *Sema::BuildExceptionDeclaration(Scope *S, QualType ExDeclType, AbstractVariableType)) Invalid = true; - // FIXME: Need to test for ability to copy-construct and destroy the - // exception variable. - - // FIXME: Need to check for abstract classes. - VarDecl *ExDecl = VarDecl::Create(Context, CurContext, Loc, Name, ExDeclType, TInfo, VarDecl::None); + if (!Invalid) { + if (const RecordType *RecordTy = ExDeclType->getAs<RecordType>()) { + // C++ [except.handle]p16: + // The object declared in an exception-declaration or, if the + // exception-declaration does not specify a name, a temporary (12.2) is + // copy-initialized (8.5) from the exception object. [...] + // The object is destroyed when the handler exits, after the destruction + // of any automatic objects initialized within the handler. + // + // We just pretend to initialize the object with itself, then make sure + // it can be destroyed later. + InitializedEntity Entity = InitializedEntity::InitializeVariable(ExDecl); + Expr *ExDeclRef = DeclRefExpr::Create(Context, 0, SourceRange(), ExDecl, + Loc, ExDeclType, 0); + InitializationKind Kind = InitializationKind::CreateCopy(Loc, + SourceLocation()); + InitializationSequence InitSeq(*this, Entity, Kind, &ExDeclRef, 1); + OwningExprResult Result = InitSeq.Perform(*this, Entity, Kind, + MultiExprArg(*this, (void**)&ExDeclRef, 1)); + if (Result.isInvalid()) + Invalid = true; + else + FinalizeVarWithDestructor(ExDecl, RecordTy); + } + } + if (Invalid) ExDecl->setInvalidDecl(); diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index d9464ad..10001c3 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -635,7 +635,7 @@ Sema::BuildAnonymousStructUnionMemberReference(SourceLocation Loc, MemberType = Context.getQualifiedType(MemberType, NewQuals); MarkDeclarationReferenced(Loc, *FI); - PerformObjectMemberConversion(Result, *FI); + PerformObjectMemberConversion(Result, /*FIXME:Qualifier=*/0, *FI); // FIXME: Might this end up being a qualified name? Result = new (Context) MemberExpr(Result, BaseObjectIsPointer, *FI, OpLoc, MemberType); @@ -1357,29 +1357,111 @@ Sema::LookupInObjCMethod(LookupResult &Lookup, Scope *S, /// \brief Cast member's object to its own class if necessary. bool -Sema::PerformObjectMemberConversion(Expr *&From, NamedDecl *Member) { - if (FieldDecl *FD = dyn_cast<FieldDecl>(Member)) - if (CXXRecordDecl *RD = - dyn_cast<CXXRecordDecl>(FD->getDeclContext())) { - QualType DestType = - Context.getCanonicalType(Context.getTypeDeclType(RD)); - if (DestType->isDependentType() || From->getType()->isDependentType()) - return false; - QualType FromRecordType = From->getType(); - QualType DestRecordType = DestType; - if (FromRecordType->getAs<PointerType>()) { - DestType = Context.getPointerType(DestType); - FromRecordType = FromRecordType->getPointeeType(); - } - if (!Context.hasSameUnqualifiedType(FromRecordType, DestRecordType) && - CheckDerivedToBaseConversion(FromRecordType, - DestRecordType, - From->getSourceRange().getBegin(), - From->getSourceRange())) - return true; - ImpCastExprToType(From, DestType, CastExpr::CK_DerivedToBase, - /*isLvalue=*/true); +Sema::PerformObjectMemberConversion(Expr *&From, + NestedNameSpecifier *Qualifier, + NamedDecl *Member) { + CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(Member->getDeclContext()); + if (!RD) + return false; + + QualType DestRecordType; + QualType DestType; + QualType FromRecordType; + QualType FromType = From->getType(); + bool PointerConversions = false; + if (isa<FieldDecl>(Member)) { + DestRecordType = Context.getCanonicalType(Context.getTypeDeclType(RD)); + + if (FromType->getAs<PointerType>()) { + DestType = Context.getPointerType(DestRecordType); + FromRecordType = FromType->getPointeeType(); + PointerConversions = true; + } else { + DestType = DestRecordType; + FromRecordType = FromType; } + } else if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Member)) { + if (Method->isStatic()) + return false; + + DestType = Method->getThisType(Context); + DestRecordType = DestType->getPointeeType(); + + if (FromType->getAs<PointerType>()) { + FromRecordType = FromType->getPointeeType(); + PointerConversions = true; + } else { + FromRecordType = FromType; + DestType = DestRecordType; + } + } else { + // No conversion necessary. + return false; + } + + if (DestType->isDependentType() || FromType->isDependentType()) + return false; + + // If the unqualified types are the same, no conversion is necessary. + if (Context.hasSameUnqualifiedType(FromRecordType, DestRecordType)) + return false; + + // C++ [class.member.lookup]p8: + // [...] Ambiguities can often be resolved by qualifying a name with its + // class name. + // + // If the member was a qualified name and the qualified referred to a + // specific base subobject type, we'll cast to that intermediate type + // first and then to the object in which the member is declared. That allows + // one to resolve ambiguities in, e.g., a diamond-shaped hierarchy such as: + // + // class Base { public: int x; }; + // class Derived1 : public Base { }; + // class Derived2 : public Base { }; + // class VeryDerived : public Derived1, public Derived2 { void f(); }; + // + // void VeryDerived::f() { + // x = 17; // error: ambiguous base subobjects + // Derived1::x = 17; // okay, pick the Base subobject of Derived1 + // } + QualType IntermediateRecordType; + QualType IntermediateType; + if (Qualifier) { + if (const RecordType *IntermediateRecord + = Qualifier->getAsType()->getAs<RecordType>()) { + IntermediateRecordType = QualType(IntermediateRecord, 0); + IntermediateType = IntermediateRecordType; + if (PointerConversions) + IntermediateType = Context.getPointerType(IntermediateType); + } + } + + if (!IntermediateType.isNull() && + IsDerivedFrom(FromRecordType, IntermediateRecordType) && + IsDerivedFrom(IntermediateRecordType, DestRecordType)) { + if (CheckDerivedToBaseConversion(FromRecordType, IntermediateRecordType, + From->getSourceRange().getBegin(), + From->getSourceRange()) || + CheckDerivedToBaseConversion(IntermediateRecordType, DestRecordType, + From->getSourceRange().getBegin(), + From->getSourceRange())) + return true; + + ImpCastExprToType(From, IntermediateType, CastExpr::CK_DerivedToBase, + /*isLvalue=*/!PointerConversions); + ImpCastExprToType(From, DestType, CastExpr::CK_DerivedToBase, + /*isLvalue=*/!PointerConversions); + return false; + } + + if (CheckDerivedToBaseConversion(FromRecordType, + DestRecordType, + From->getSourceRange().getBegin(), + From->getSourceRange())) + return true; + + ImpCastExprToType(From, DestType, CastExpr::CK_DerivedToBase, + /*isLvalue=*/true); return false; } @@ -1609,7 +1691,7 @@ Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS, return ExprError(); } - if (VD->getType()->isArrayType()) { + if (VD->getType()->isArrayType() && !VD->hasAttr<BlocksAttr>()) { Diag(Loc, diag::err_ref_array_type); Diag(D->getLocation(), diag::note_declared_at); return ExprError(); @@ -2666,7 +2748,7 @@ Sema::BuildMemberReferenceExpr(ExprArg Base, QualType BaseExprType, } MarkDeclarationReferenced(MemberLoc, FD); - if (PerformObjectMemberConversion(BaseExpr, FD)) + if (PerformObjectMemberConversion(BaseExpr, Qualifier, FD)) return ExprError(); return Owned(BuildMemberExpr(Context, BaseExpr, IsArrow, SS, FD, MemberLoc, MemberType)); @@ -6651,7 +6733,7 @@ Sema::OwningExprResult Sema::ActOnBuiltinOffsetOf(Scope *S, Res = BuildAnonymousStructUnionMemberReference( OC.LocEnd, MemberDecl, Res, OC.LocEnd).takeAs<Expr>(); } else { - PerformObjectMemberConversion(Res, MemberDecl); + PerformObjectMemberConversion(Res, /*Qualifier=*/0, MemberDecl); // MemberDecl->getType() doesn't get the right qualifiers, but it // doesn't matter here. Res = new (Context) MemberExpr(Res, false, MemberDecl, OC.LocEnd, diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 5f46019..309da29 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -2881,7 +2881,7 @@ Sema::OwningExprResult Sema::ActOnPseudoDestructorExpr(Scope *S, ExprArg Base, CXXMemberCallExpr *Sema::BuildCXXMemberCallExpr(Expr *Exp, CXXMethodDecl *Method) { - if (PerformObjectArgumentInitialization(Exp, Method)) + if (PerformObjectArgumentInitialization(Exp, /*Qualifier=*/0, Method)) assert(0 && "Calling BuildCXXMemberCallExpr with invalid call?"); MemberExpr *ME = diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp index 0f8107a..bf9f73c 100644 --- a/lib/Sema/SemaInit.cpp +++ b/lib/Sema/SemaInit.cpp @@ -3365,7 +3365,8 @@ InitializationSequence::Perform(Sema &S, // FIXME: Should we move this initialization into a separate // derived-to-base conversion? I believe the answer is "no", because // we don't want to turn off access control here for c-style casts. - if (S.PerformObjectArgumentInitialization(CurInitExpr, Conversion)) + if (S.PerformObjectArgumentInitialization(CurInitExpr, /*Qualifier=*/0, + Conversion)) return S.ExprError(); // Do a little dance to make sure that CurInit has the proper diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index ed0d137..ff59fc3 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -1282,8 +1282,8 @@ bool Sema::CheckPointerConversion(Expr *From, QualType ToType, QualType FromPointeeType = FromPtrType->getPointeeType(), ToPointeeType = ToPtrType->getPointeeType(); - if (FromPointeeType->isRecordType() && - ToPointeeType->isRecordType()) { + if (FromPointeeType->isRecordType() && ToPointeeType->isRecordType() && + !Context.hasSameUnqualifiedType(FromPointeeType, ToPointeeType)) { // We must have a derived-to-base conversion. Check an // ambiguous or inaccessible conversion. if (CheckDerivedToBaseConversion(FromPointeeType, ToPointeeType, @@ -2304,7 +2304,9 @@ Sema::TryObjectArgumentInitialization(QualType OrigFromType, /// the implicit object parameter for the given Method with the given /// expression. bool -Sema::PerformObjectArgumentInitialization(Expr *&From, CXXMethodDecl *Method) { +Sema::PerformObjectArgumentInitialization(Expr *&From, + NestedNameSpecifier *Qualifier, + CXXMethodDecl *Method) { QualType FromRecordType, DestType; QualType ImplicitParamRecordType = Method->getThisType(Context)->getAs<PointerType>()->getPointeeType(); @@ -2327,15 +2329,12 @@ Sema::PerformObjectArgumentInitialization(Expr *&From, CXXMethodDecl *Method) { diag::err_implicit_object_parameter_init) << ImplicitParamRecordType << FromRecordType << From->getSourceRange(); - if (ICS.Standard.Second == ICK_Derived_To_Base && - CheckDerivedToBaseConversion(FromRecordType, - ImplicitParamRecordType, - From->getSourceRange().getBegin(), - From->getSourceRange())) - return true; + if (ICS.Standard.Second == ICK_Derived_To_Base) + return PerformObjectMemberConversion(From, Qualifier, Method); - ImpCastExprToType(From, DestType, CastExpr::CK_DerivedToBase, - /*isLvalue=*/true); + if (!Context.hasSameType(From->getType(), DestType)) + ImpCastExprToType(From, DestType, CastExpr::CK_NoOp, + /*isLvalue=*/!From->getType()->getAs<PointerType>()); return false; } @@ -5545,7 +5544,7 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, unsigned OpcIn, if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(FnDecl)) { CheckMemberOperatorAccess(OpLoc, Args[0], Method, Best->getAccess()); - if (PerformObjectArgumentInitialization(Input, Method)) + if (PerformObjectArgumentInitialization(Input, /*Qualifier=*/0, Method)) return ExprError(); } else { // Convert the arguments. @@ -5738,7 +5737,8 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc, if (Arg1.isInvalid()) return ExprError(); - if (PerformObjectArgumentInitialization(Args[0], Method)) + if (PerformObjectArgumentInitialization(Args[0], /*Qualifier=*/0, + Method)) return ExprError(); Args[1] = RHS = Arg1.takeAs<Expr>(); @@ -5904,7 +5904,8 @@ Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc, // Convert the arguments. CXXMethodDecl *Method = cast<CXXMethodDecl>(FnDecl); - if (PerformObjectArgumentInitialization(Args[0], Method)) + if (PerformObjectArgumentInitialization(Args[0], /*Qualifier=*/0, + Method)) return ExprError(); // Convert the arguments. @@ -6009,12 +6010,15 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE, MemberExpr *MemExpr; CXXMethodDecl *Method = 0; + NestedNameSpecifier *Qualifier = 0; if (isa<MemberExpr>(NakedMemExpr)) { MemExpr = cast<MemberExpr>(NakedMemExpr); Method = cast<CXXMethodDecl>(MemExpr->getMemberDecl()); + Qualifier = MemExpr->getQualifier(); } else { UnresolvedMemberExpr *UnresExpr = cast<UnresolvedMemberExpr>(NakedMemExpr); - + Qualifier = UnresExpr->getQualifier(); + QualType ObjectType = UnresExpr->getBaseType(); // Add overload candidates @@ -6113,7 +6117,7 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE, // Convert the object argument (for a non-static member function call). Expr *ObjectArg = MemExpr->getBase(); if (!Method->isStatic() && - PerformObjectArgumentInitialization(ObjectArg, Method)) + PerformObjectArgumentInitialization(ObjectArg, Qualifier, Method)) return ExprError(); MemExpr->setBase(ObjectArg); @@ -6333,7 +6337,8 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object, bool IsError = false; // Initialize the implicit object parameter. - IsError |= PerformObjectArgumentInitialization(Object, Method); + IsError |= PerformObjectArgumentInitialization(Object, /*Qualifier=*/0, + Method); TheCall->setArg(0, Object); @@ -6458,7 +6463,7 @@ Sema::BuildOverloadedArrowExpr(Scope *S, ExprArg BaseIn, SourceLocation OpLoc) { // Convert the object parameter. CXXMethodDecl *Method = cast<CXXMethodDecl>(Best->Function); - if (PerformObjectArgumentInitialization(Base, Method)) + if (PerformObjectArgumentInitialization(Base, /*Qualifier=*/0, Method)) return ExprError(); // No concerns about early exits now. diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index 2fb5c84..a79853a 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -1034,7 +1034,8 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, const ObjCInterfaceType *OIT = T->getAs<ObjCInterfaceType>(); T = Context.getObjCObjectPointerType(T, (ObjCProtocolDecl **)OIT->qual_begin(), - OIT->getNumProtocols()); + OIT->getNumProtocols(), + DeclType.Ptr.TypeQuals); break; } T = BuildPointerType(T, DeclType.Ptr.TypeQuals, DeclType.Loc, Name); diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index 2f3c482..24ea62c 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -969,7 +969,7 @@ public: assert(!Qualifier && "Can't have an unnamed field with a qualifier!"); Expr *BaseExpr = Base.takeAs<Expr>(); - if (getSema().PerformObjectMemberConversion(BaseExpr, Member)) + if (getSema().PerformObjectMemberConversion(BaseExpr, Qualifier, Member)) return getSema().ExprError(); MemberExpr *ME = |