diff options
Diffstat (limited to 'lib/Sema/SemaExpr.cpp')
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 1704 |
1 files changed, 861 insertions, 843 deletions
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 5f46a97..80b4652 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -11,10 +11,10 @@ // //===----------------------------------------------------------------------===// -#include "Sema.h" -#include "SemaInit.h" -#include "Lookup.h" -#include "AnalysisBasedWarnings.h" +#include "clang/Sema/SemaInternal.h" +#include "clang/Sema/Initialization.h" +#include "clang/Sema/Lookup.h" +#include "clang/Sema/AnalysisBasedWarnings.h" #include "clang/AST/ASTContext.h" #include "clang/AST/CXXInheritance.h" #include "clang/AST/DeclObjC.h" @@ -29,11 +29,14 @@ #include "clang/Basic/TargetInfo.h" #include "clang/Lex/LiteralSupport.h" #include "clang/Lex/Preprocessor.h" -#include "clang/Parse/DeclSpec.h" -#include "clang/Parse/Designator.h" -#include "clang/Parse/Scope.h" -#include "clang/Parse/Template.h" +#include "clang/Sema/DeclSpec.h" +#include "clang/Sema/Designator.h" +#include "clang/Sema/Scope.h" +#include "clang/Sema/ScopeInfo.h" +#include "clang/Sema/ParsedTemplate.h" +#include "clang/Sema/Template.h" using namespace clang; +using namespace sema; /// \brief Determine whether the use of this declaration is valid, and @@ -59,7 +62,7 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc) { // See if the decl is unavailable if (D->getAttr<UnavailableAttr>()) { - Diag(Loc, diag::warn_unavailable) << D->getDeclName(); + Diag(Loc, diag::err_unavailable) << D->getDeclName(); Diag(D->getLocation(), diag::note_unavailable_here) << 0; } @@ -192,7 +195,7 @@ void Sema::DefaultFunctionArrayConversion(Expr *&E) { if (Ty->isFunctionType()) ImpCastExprToType(E, Context.getPointerType(Ty), - CastExpr::CK_FunctionToPointerDecay); + CK_FunctionToPointerDecay); else if (Ty->isArrayType()) { // In C90 mode, arrays only promote to pointers if the array expression is // an lvalue. The relevant legalese is C90 6.2.2.1p3: "an lvalue that has @@ -208,7 +211,7 @@ void Sema::DefaultFunctionArrayConversion(Expr *&E) { if (getLangOptions().C99 || getLangOptions().CPlusPlus || E->isLvalue(Context) == Expr::LV_Valid) ImpCastExprToType(E, Context.getArrayDecayedType(Ty), - CastExpr::CK_ArrayToPointerDecay); + CK_ArrayToPointerDecay); } } @@ -229,7 +232,7 @@ void Sema::DefaultFunctionArrayLvalueConversion(Expr *&E) { // If the lvalue has qualified type, the value has the unqualified // version of the type of the lvalue; otherwise, the value has the // type of the lvalue. - ImpCastExprToType(E, Ty.getUnqualifiedType(), CastExpr::CK_NoOp); + ImpCastExprToType(E, Ty.getUnqualifiedType(), CK_NoOp); } } @@ -258,12 +261,12 @@ Expr *Sema::UsualUnaryConversions(Expr *&Expr) { // other types are unchanged by the integer promotions. QualType PTy = Context.isPromotableBitField(Expr); if (!PTy.isNull()) { - ImpCastExprToType(Expr, PTy, CastExpr::CK_IntegralCast); + ImpCastExprToType(Expr, PTy, CK_IntegralCast); return Expr; } if (Ty->isPromotableIntegerType()) { QualType PT = Context.getPromotedIntegerType(Ty); - ImpCastExprToType(Expr, PT, CastExpr::CK_IntegralCast); + ImpCastExprToType(Expr, PT, CK_IntegralCast); return Expr; } @@ -281,7 +284,7 @@ void Sema::DefaultArgumentPromotion(Expr *&Expr) { // If this is a 'float' (CVR qualified or typedef) promote to double. if (Ty->isSpecificBuiltinType(BuiltinType::Float)) return ImpCastExprToType(Expr, Context.DoubleTy, - CastExpr::CK_FloatingCast); + CK_FloatingCast); UsualUnaryConversions(Expr); } @@ -355,8 +358,8 @@ QualType Sema::UsualArithmeticConversions(Expr *&lhsExpr, Expr *&rhsExpr, QualType destType = Context.UsualArithmeticConversionsType(lhs, rhs); if (!isCompAssign) - ImpCastExprToType(lhsExpr, destType, CastExpr::CK_Unknown); - ImpCastExprToType(rhsExpr, destType, CastExpr::CK_Unknown); + ImpCastExprToType(lhsExpr, destType, CK_Unknown); + ImpCastExprToType(rhsExpr, destType, CK_Unknown); return destType; } @@ -371,7 +374,7 @@ QualType Sema::UsualArithmeticConversions(Expr *&lhsExpr, Expr *&rhsExpr, /// multiple tokens. However, the common case is that StringToks points to one /// string. /// -Action::OwningExprResult +ExprResult Sema::ActOnStringLiteral(const Token *StringToks, unsigned NumStringToks) { assert(NumStringToks && "Must have at least one string!"); @@ -459,13 +462,20 @@ static bool ShouldSnapshotBlockValueReference(Sema &S, BlockScopeInfo *CurBlock, } +ExprResult +Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty, SourceLocation Loc, + const CXXScopeSpec *SS) { + DeclarationNameInfo NameInfo(D->getDeclName(), Loc); + return BuildDeclRefExpr(D, Ty, NameInfo, SS); +} /// BuildDeclRefExpr - Build a DeclRefExpr. -Sema::OwningExprResult -Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty, SourceLocation Loc, +ExprResult +Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty, + const DeclarationNameInfo &NameInfo, const CXXScopeSpec *SS) { if (Context.getCanonicalType(Ty) == Context.UndeducedAutoTy) { - Diag(Loc, + Diag(NameInfo.getLoc(), diag::err_auto_variable_cannot_appear_in_own_initializer) << D->getDeclName(); return ExprError(); @@ -479,7 +489,8 @@ Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty, SourceLocation Loc, } else if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(CurContext)) { if (const FunctionDecl *FD = MD->getParent()->isLocalClass()) { if (VD->hasLocalStorage() && VD->getDeclContext() != CurContext) { - Diag(Loc, diag::err_reference_to_local_var_in_enclosing_function) + Diag(NameInfo.getLoc(), + diag::err_reference_to_local_var_in_enclosing_function) << D->getIdentifier() << FD->getDeclName(); Diag(D->getLocation(), diag::note_local_variable_declared_here) << D->getIdentifier(); @@ -489,12 +500,12 @@ Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty, SourceLocation Loc, } } - MarkDeclarationReferenced(Loc, D); + MarkDeclarationReferenced(NameInfo.getLoc(), D); return Owned(DeclRefExpr::Create(Context, SS? (NestedNameSpecifier *)SS->getScopeRep() : 0, SS? SS->getRange() : SourceRange(), - D, Loc, Ty)); + D, NameInfo, Ty)); } /// \brief Given a field that represents a member of an anonymous @@ -535,7 +546,7 @@ VarDecl *Sema::BuildAnonymousStructUnionMemberPath(FieldDecl *Field, return BaseObject; } -Sema::OwningExprResult +ExprResult Sema::BuildAnonymousStructUnionMemberReference(SourceLocation Loc, FieldDecl *Field, Expr *BaseObjectExpr, @@ -553,7 +564,6 @@ Sema::BuildAnonymousStructUnionMemberReference(SourceLocation Loc, if (BaseObject) { // BaseObject is an anonymous struct/union variable (and is, // therefore, not part of another non-anonymous record). - if (BaseObjectExpr) BaseObjectExpr->Destroy(Context); MarkDeclarationReferenced(Loc, BaseObject); BaseObjectExpr = new (Context) DeclRefExpr(BaseObject,BaseObject->getType(), SourceLocation()); @@ -640,7 +650,7 @@ Sema::BuildAnonymousStructUnionMemberReference(SourceLocation Loc, return Owned(Result); } -/// Decomposes the given name into a DeclarationName, its location, and +/// Decomposes the given name into a DeclarationNameInfo, its location, and /// possibly a list of template arguments. /// /// If this produces template arguments, it is permitted to call @@ -652,8 +662,7 @@ Sema::BuildAnonymousStructUnionMemberReference(SourceLocation Loc, static void DecomposeUnqualifiedId(Sema &SemaRef, const UnqualifiedId &Id, TemplateArgumentListInfo &Buffer, - DeclarationName &Name, - SourceLocation &NameLoc, + DeclarationNameInfo &NameInfo, const TemplateArgumentListInfo *&TemplateArgs) { if (Id.getKind() == UnqualifiedId::IK_TemplateId) { Buffer.setLAngleLoc(Id.TemplateId->LAngleLoc); @@ -665,15 +674,12 @@ static void DecomposeUnqualifiedId(Sema &SemaRef, SemaRef.translateTemplateArguments(TemplateArgsPtr, Buffer); TemplateArgsPtr.release(); - TemplateName TName = - Sema::TemplateTy::make(Id.TemplateId->Template).getAsVal<TemplateName>(); - - Name = SemaRef.Context.getNameForTemplate(TName); - NameLoc = Id.TemplateId->TemplateNameLoc; + TemplateName TName = Id.TemplateId->Template.get(); + SourceLocation TNameLoc = Id.TemplateId->TemplateNameLoc; + NameInfo = SemaRef.Context.getNameForTemplate(TName, TNameLoc); TemplateArgs = &Buffer; } else { - Name = SemaRef.GetNameFromUnqualifiedId(Id); - NameLoc = Id.StartLocation; + NameInfo = SemaRef.GetNameFromUnqualifiedId(Id); TemplateArgs = 0; } } @@ -700,23 +706,6 @@ static bool IsFullyFormedScope(Sema &SemaRef, CXXRecordDecl *Record) { return true; } -/// Determines whether we can lookup this id-expression now or whether -/// we have to wait until template instantiation is complete. -static bool IsDependentIdExpression(Sema &SemaRef, const CXXScopeSpec &SS) { - DeclContext *DC = SemaRef.computeDeclContext(SS, false); - - // If the qualifier scope isn't computable, it's definitely dependent. - if (!DC) return true; - - // If the qualifier scope doesn't name a record, we can always look into it. - if (!isa<CXXRecordDecl>(DC)) return false; - - // We can't look into record types unless they're fully-formed. - if (!IsFullyFormedScope(SemaRef, cast<CXXRecordDecl>(DC))) return true; - - return false; -} - /// Determines if the given class is provably not derived from all of /// the prospective base classes. static bool IsProvablyNotDerivedFrom(Sema &SemaRef, @@ -905,25 +894,30 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R, // TODO: fixit for inserting 'Base<T>::' in the other cases. // Actually quite difficult! if (isInstance) { - Diag(R.getNameLoc(), diagnostic) << Name - << FixItHint::CreateInsertion(R.getNameLoc(), "this->"); - UnresolvedLookupExpr *ULE = cast<UnresolvedLookupExpr>( CallsUndergoingInstantiation.back()->getCallee()); - CXXMethodDecl *DepMethod = cast<CXXMethodDecl>( + CXXMethodDecl *DepMethod = cast_or_null<CXXMethodDecl>( CurMethod->getInstantiatedFromMemberFunction()); - QualType DepThisType = DepMethod->getThisType(Context); - CXXThisExpr *DepThis = new (Context) CXXThisExpr(R.getNameLoc(), - DepThisType, false); - TemplateArgumentListInfo TList; - if (ULE->hasExplicitTemplateArgs()) - ULE->copyTemplateArgumentsInto(TList); - CXXDependentScopeMemberExpr *DepExpr = - CXXDependentScopeMemberExpr::Create( - Context, DepThis, DepThisType, true, SourceLocation(), - ULE->getQualifier(), ULE->getQualifierRange(), NULL, Name, - R.getNameLoc(), &TList); - CallsUndergoingInstantiation.back()->setCallee(DepExpr); + if (DepMethod) { + Diag(R.getNameLoc(), diagnostic) << Name + << FixItHint::CreateInsertion(R.getNameLoc(), "this->"); + QualType DepThisType = DepMethod->getThisType(Context); + CXXThisExpr *DepThis = new (Context) CXXThisExpr( + R.getNameLoc(), DepThisType, false); + TemplateArgumentListInfo TList; + if (ULE->hasExplicitTemplateArgs()) + ULE->copyTemplateArgumentsInto(TList); + CXXDependentScopeMemberExpr *DepExpr = + CXXDependentScopeMemberExpr::Create( + Context, DepThis, DepThisType, true, SourceLocation(), + ULE->getQualifier(), ULE->getQualifierRange(), NULL, + R.getLookupNameInfo(), &TList); + CallsUndergoingInstantiation.back()->setCallee(DepExpr); + } else { + // FIXME: we should be able to handle this case too. It is correct + // to add this-> here. This is a workaround for PR7947. + Diag(R.getNameLoc(), diagnostic) << Name; + } } else { Diag(R.getNameLoc(), diagnostic) << Name; } @@ -935,6 +929,8 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R, // Tell the callee to try to recover. return false; } + + R.clear(); } } @@ -1005,11 +1001,74 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R, return true; } -Sema::OwningExprResult Sema::ActOnIdExpression(Scope *S, - CXXScopeSpec &SS, - UnqualifiedId &Id, - bool HasTrailingLParen, - bool isAddressOfOperand) { +static ObjCPropertyDecl *OkToSynthesizeProvisionalIvar(Sema &SemaRef, + IdentifierInfo *II, + SourceLocation NameLoc) { + ObjCMethodDecl *CurMeth = SemaRef.getCurMethodDecl(); + ObjCInterfaceDecl *IDecl = CurMeth->getClassInterface(); + if (!IDecl) + return 0; + ObjCImplementationDecl *ClassImpDecl = IDecl->getImplementation(); + if (!ClassImpDecl) + return 0; + ObjCPropertyDecl *property = SemaRef.LookupPropertyDecl(IDecl, II); + if (!property) + return 0; + if (ObjCPropertyImplDecl *PIDecl = ClassImpDecl->FindPropertyImplDecl(II)) + if (PIDecl->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic) + return 0; + return property; +} + +static ObjCIvarDecl *SynthesizeProvisionalIvar(Sema &SemaRef, + LookupResult &Lookup, + IdentifierInfo *II, + SourceLocation NameLoc) { + ObjCMethodDecl *CurMeth = SemaRef.getCurMethodDecl(); + bool LookForIvars; + if (Lookup.empty()) + LookForIvars = true; + else if (CurMeth->isClassMethod()) + LookForIvars = false; + else + LookForIvars = (Lookup.isSingleResult() && + Lookup.getFoundDecl()->isDefinedOutsideFunctionOrMethod()); + if (!LookForIvars) + return 0; + + ObjCInterfaceDecl *IDecl = CurMeth->getClassInterface(); + if (!IDecl) + return 0; + ObjCImplementationDecl *ClassImpDecl = IDecl->getImplementation(); + if (!ClassImpDecl) + return 0; + bool DynamicImplSeen = false; + ObjCPropertyDecl *property = SemaRef.LookupPropertyDecl(IDecl, II); + if (!property) + return 0; + if (ObjCPropertyImplDecl *PIDecl = ClassImpDecl->FindPropertyImplDecl(II)) + DynamicImplSeen = + (PIDecl->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic); + if (!DynamicImplSeen) { + QualType PropType = SemaRef.Context.getCanonicalType(property->getType()); + ObjCIvarDecl *Ivar = ObjCIvarDecl::Create(SemaRef.Context, ClassImpDecl, + NameLoc, + II, PropType, /*Dinfo=*/0, + ObjCIvarDecl::Protected, + (Expr *)0, true); + ClassImpDecl->addDecl(Ivar); + IDecl->makeDeclVisibleInContext(Ivar, false); + property->setPropertyIvarDecl(Ivar); + return Ivar; + } + return 0; +} + +ExprResult Sema::ActOnIdExpression(Scope *S, + CXXScopeSpec &SS, + UnqualifiedId &Id, + bool HasTrailingLParen, + bool isAddressOfOperand) { assert(!(isAddressOfOperand && HasTrailingLParen) && "cannot be direct & operand and have a trailing lparen"); @@ -1019,13 +1078,13 @@ Sema::OwningExprResult Sema::ActOnIdExpression(Scope *S, TemplateArgumentListInfo TemplateArgsBuffer; // Decompose the UnqualifiedId into the following data. - DeclarationName Name; - SourceLocation NameLoc; + DeclarationNameInfo NameInfo; const TemplateArgumentListInfo *TemplateArgs; - DecomposeUnqualifiedId(*this, Id, TemplateArgsBuffer, - Name, NameLoc, TemplateArgs); + DecomposeUnqualifiedId(*this, Id, TemplateArgsBuffer, NameInfo, TemplateArgs); + DeclarationName Name = NameInfo.getName(); IdentifierInfo *II = Name.getAsIdentifierInfo(); + SourceLocation NameLoc = NameInfo.getLoc(); // C++ [temp.dep.expr]p3: // An id-expression is type-dependent if it contains: @@ -1038,16 +1097,30 @@ Sema::OwningExprResult Sema::ActOnIdExpression(Scope *S, // names a dependent type. // Determine whether this is a member of an unknown specialization; // we need to handle these differently. - if ((Name.getNameKind() == DeclarationName::CXXConversionFunctionName && - Name.getCXXNameType()->isDependentType()) || - (SS.isSet() && IsDependentIdExpression(*this, SS))) { - return ActOnDependentIdExpression(SS, Name, NameLoc, - isAddressOfOperand, - TemplateArgs); + bool DependentID = false; + if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName && + Name.getCXXNameType()->isDependentType()) { + DependentID = true; + } else if (SS.isSet()) { + DeclContext *DC = computeDeclContext(SS, false); + if (DC) { + if (RequireCompleteDeclContext(SS, DC)) + return ExprError(); + // FIXME: We should be checking whether DC is the current instantiation. + if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(DC)) + DependentID = !IsFullyFormedScope(*this, RD); + } else { + DependentID = true; + } } + if (DependentID) { + return ActOnDependentIdExpression(SS, NameInfo, isAddressOfOperand, + TemplateArgs); + } + bool IvarLookupFollowUp = false; // Perform the required lookup. - LookupResult R(*this, Name, NameLoc, LookupOrdinaryName); + LookupResult R(*this, NameInfo, LookupOrdinaryName); if (TemplateArgs) { // Lookup the template name again to correctly establish the context in // which it was found. This is really unfortunate as we already did the @@ -1058,18 +1131,26 @@ Sema::OwningExprResult Sema::ActOnIdExpression(Scope *S, LookupTemplateName(R, S, SS, QualType(), /*EnteringContext=*/false, MemberOfUnknownSpecialization); } else { - bool IvarLookupFollowUp = (!SS.isSet() && II && getCurMethodDecl()); + IvarLookupFollowUp = (!SS.isSet() && II && getCurMethodDecl()); LookupParsedName(R, S, &SS, !IvarLookupFollowUp); // If this reference is in an Objective-C method, then we need to do // some special Objective-C lookup, too. if (IvarLookupFollowUp) { - OwningExprResult E(LookupInObjCMethod(R, S, II, true)); + ExprResult E(LookupInObjCMethod(R, S, II, true)); if (E.isInvalid()) return ExprError(); Expr *Ex = E.takeAs<Expr>(); if (Ex) return Owned(Ex); + // Synthesize ivars lazily + if (getLangOptions().ObjCNonFragileABI2) { + if (SynthesizeProvisionalIvar(*this, R, II, NameLoc)) + return ActOnIdExpression(S, SS, Id, HasTrailingLParen, + isAddressOfOperand); + } + // for further use, this must be set to false if in class method. + IvarLookupFollowUp = getCurMethodDecl()->isInstanceMethod(); } } @@ -1102,7 +1183,7 @@ Sema::OwningExprResult Sema::ActOnIdExpression(Scope *S, // reference the ivar. if (ObjCIvarDecl *Ivar = R.getAsSingle<ObjCIvarDecl>()) { R.clear(); - OwningExprResult E(LookupInObjCMethod(R, S, Ivar->getIdentifier())); + ExprResult E(LookupInObjCMethod(R, S, Ivar->getIdentifier())); assert(E.isInvalid() || E.get()); return move(E); } @@ -1113,23 +1194,15 @@ Sema::OwningExprResult Sema::ActOnIdExpression(Scope *S, assert(!R.empty() || ADL); if (VarDecl *Var = R.getAsSingle<VarDecl>()) { - // Warn about constructs like: - // if (void *X = foo()) { ... } else { X }. - // In the else block, the pointer is always false. - if (Var->isDeclaredInCondition() && Var->getType()->isScalarType()) { - Scope *CheckS = S; - while (CheckS && CheckS->getControlParent()) { - if ((CheckS->getFlags() & Scope::ElseScope) && - CheckS->getControlParent()->isDeclScope(DeclPtrTy::make(Var))) { - ExprError(Diag(NameLoc, diag::warn_value_always_zero) - << Var->getDeclName() - << (Var->getType()->isPointerType() ? 2 : - Var->getType()->isBooleanType() ? 1 : 0)); - break; - } - - // Move to the parent of this scope. - CheckS = CheckS->getParent(); + if (getLangOptions().ObjCNonFragileABI && IvarLookupFollowUp && + !getLangOptions().ObjCNonFragileABI2 && + Var->isFileVarDecl()) { + ObjCPropertyDecl *Property = + OkToSynthesizeProvisionalIvar(*this, II, NameLoc); + if (Property) { + Diag(NameLoc, diag::warn_ivar_variable_conflict) << Var->getDeclName(); + Diag(Property->getLocation(), diag::note_property_declare); + Diag(Var->getLocation(), diag::note_global_declared_at); } } } else if (FunctionDecl *Func = R.getAsSingle<FunctionDecl>()) { @@ -1152,15 +1225,43 @@ Sema::OwningExprResult Sema::ActOnIdExpression(Scope *S, } // Check whether this might be a C++ implicit instance member access. - // C++ [expr.prim.general]p6: - // Within the definition of a non-static member function, an - // identifier that names a non-static member is transformed to a - // class member access expression. - // But note that &SomeClass::foo is grammatically distinct, even - // though we don't parse it that way. + // C++ [class.mfct.non-static]p3: + // When an id-expression that is not part of a class member access + // syntax and not used to form a pointer to member is used in the + // body of a non-static member function of class X, if name lookup + // resolves the name in the id-expression to a non-static non-type + // member of some class C, the id-expression is transformed into a + // class member access expression using (*this) as the + // postfix-expression to the left of the . operator. + // + // But we don't actually need to do this for '&' operands if R + // resolved to a function or overloaded function set, because the + // expression is ill-formed if it actually works out to be a + // non-static member function: + // + // C++ [expr.ref]p4: + // Otherwise, if E1.E2 refers to a non-static member function. . . + // [t]he expression can be used only as the left-hand operand of a + // member function call. + // + // There are other safeguards against such uses, but it's important + // to get this right here so that we don't end up making a + // spuriously dependent expression if we're inside a dependent + // instance method. if (!R.empty() && (*R.begin())->isCXXClassMember()) { - bool isAbstractMemberPointer = (isAddressOfOperand && !SS.isEmpty()); - if (!isAbstractMemberPointer) + bool MightBeImplicitMember; + if (!isAddressOfOperand) + MightBeImplicitMember = true; + else if (!SS.isEmpty()) + MightBeImplicitMember = false; + else if (R.isOverloadedResult()) + MightBeImplicitMember = false; + else if (R.isUnresolvableResult()) + MightBeImplicitMember = true; + else + MightBeImplicitMember = isa<FieldDecl>(R.getFoundDecl()); + + if (MightBeImplicitMember) return BuildPossibleImplicitMemberExpr(SS, R, TemplateArgs); } @@ -1171,7 +1272,7 @@ Sema::OwningExprResult Sema::ActOnIdExpression(Scope *S, } /// Builds an expression which might be an implicit member expression. -Sema::OwningExprResult +ExprResult Sema::BuildPossibleImplicitMemberExpr(const CXXScopeSpec &SS, LookupResult &R, const TemplateArgumentListInfo *TemplateArgs) { @@ -1210,25 +1311,25 @@ Sema::BuildPossibleImplicitMemberExpr(const CXXScopeSpec &SS, /// declaration name, generally during template instantiation. /// There's a large number of things which don't need to be done along /// this path. -Sema::OwningExprResult +ExprResult Sema::BuildQualifiedDeclarationNameExpr(CXXScopeSpec &SS, - DeclarationName Name, - SourceLocation NameLoc) { + const DeclarationNameInfo &NameInfo) { DeclContext *DC; if (!(DC = computeDeclContext(SS, false)) || DC->isDependentContext()) - return BuildDependentDeclRefExpr(SS, Name, NameLoc, 0); + return BuildDependentDeclRefExpr(SS, NameInfo, 0); if (RequireCompleteDeclContext(SS, DC)) return ExprError(); - LookupResult R(*this, Name, NameLoc, LookupOrdinaryName); + LookupResult R(*this, NameInfo, LookupOrdinaryName); LookupQualifiedName(R, DC); if (R.isAmbiguous()) return ExprError(); if (R.empty()) { - Diag(NameLoc, diag::err_no_member) << Name << DC << SS.getRange(); + Diag(NameInfo.getLoc(), diag::err_no_member) + << NameInfo.getName() << DC << SS.getRange(); return ExprError(); } @@ -1243,7 +1344,7 @@ Sema::BuildQualifiedDeclarationNameExpr(CXXScopeSpec &SS, /// actually quite a lot of extra work involved. /// /// Returns a null sentinel to indicate trivial success. -Sema::OwningExprResult +ExprResult Sema::LookupInObjCMethod(LookupResult &Lookup, Scope *S, IdentifierInfo *II, bool AllowBuiltinCreation) { SourceLocation Loc = Lookup.getNameLoc(); @@ -1298,7 +1399,7 @@ Sema::LookupInObjCMethod(LookupResult &Lookup, Scope *S, UnqualifiedId SelfName; SelfName.setIdentifier(&II, SourceLocation()); CXXScopeSpec SelfScopeSpec; - OwningExprResult SelfExpr = ActOnIdExpression(S, SelfScopeSpec, + ExprResult SelfExpr = ActOnIdExpression(S, SelfScopeSpec, SelfName, false, false); MarkDeclarationReferenced(Loc, IV); return Owned(new (Context) @@ -1403,9 +1504,8 @@ Sema::PerformObjectMemberConversion(Expr *&From, SourceRange FromRange = From->getSourceRange(); SourceLocation FromLoc = FromRange.getBegin(); - bool isLvalue - = (From->isLvalue(Context) == Expr::LV_Valid) && !PointerConversions; - + ExprValueKind VK = CastCategory(From); + // C++ [class.member.lookup]p8: // [...] Ambiguities can often be resolved by qualifying a name with its // class name. @@ -1435,15 +1535,15 @@ Sema::PerformObjectMemberConversion(Expr *&From, // type of the object type, in which case we just ignore it. // Otherwise build the appropriate casts. if (IsDerivedFrom(FromRecordType, QRecordType)) { - CXXBaseSpecifierArray BasePath; + CXXCastPath BasePath; if (CheckDerivedToBaseConversion(FromRecordType, QRecordType, FromLoc, FromRange, &BasePath)) return true; if (PointerConversions) QType = Context.getPointerType(QType); - ImpCastExprToType(From, QType, CastExpr::CK_UncheckedDerivedToBase, - isLvalue, BasePath); + ImpCastExprToType(From, QType, CK_UncheckedDerivedToBase, + VK, &BasePath); FromType = QType; FromRecordType = QRecordType; @@ -1471,7 +1571,7 @@ Sema::PerformObjectMemberConversion(Expr *&From, // conversion is non-trivial. if (!Context.hasSameUnqualifiedType(FromRecordType, URecordType)) { assert(IsDerivedFrom(FromRecordType, URecordType)); - CXXBaseSpecifierArray BasePath; + CXXCastPath BasePath; if (CheckDerivedToBaseConversion(FromRecordType, URecordType, FromLoc, FromRange, &BasePath)) return true; @@ -1479,8 +1579,8 @@ Sema::PerformObjectMemberConversion(Expr *&From, QualType UType = URecordType; if (PointerConversions) UType = Context.getPointerType(UType); - ImpCastExprToType(From, UType, CastExpr::CK_UncheckedDerivedToBase, - isLvalue, BasePath); + ImpCastExprToType(From, UType, CK_UncheckedDerivedToBase, + VK, &BasePath); FromType = UType; FromRecordType = URecordType; } @@ -1490,14 +1590,14 @@ Sema::PerformObjectMemberConversion(Expr *&From, IgnoreAccess = true; } - CXXBaseSpecifierArray BasePath; + CXXCastPath BasePath; if (CheckDerivedToBaseConversion(FromRecordType, DestRecordType, FromLoc, FromRange, &BasePath, IgnoreAccess)) return true; - ImpCastExprToType(From, DestType, CastExpr::CK_UncheckedDerivedToBase, - isLvalue, BasePath); + ImpCastExprToType(From, DestType, CK_UncheckedDerivedToBase, + VK, &BasePath); return false; } @@ -1505,7 +1605,8 @@ Sema::PerformObjectMemberConversion(Expr *&From, static MemberExpr *BuildMemberExpr(ASTContext &C, Expr *Base, bool isArrow, const CXXScopeSpec &SS, ValueDecl *Member, DeclAccessPair FoundDecl, - SourceLocation Loc, QualType Ty, + const DeclarationNameInfo &MemberNameInfo, + QualType Ty, const TemplateArgumentListInfo *TemplateArgs = 0) { NestedNameSpecifier *Qualifier = 0; SourceRange QualifierRange; @@ -1515,14 +1616,15 @@ static MemberExpr *BuildMemberExpr(ASTContext &C, Expr *Base, bool isArrow, } return MemberExpr::Create(C, Base, isArrow, Qualifier, QualifierRange, - Member, FoundDecl, Loc, TemplateArgs, Ty); + Member, FoundDecl, MemberNameInfo, + TemplateArgs, Ty); } /// Builds an implicit member access expression. The current context /// is known to be an instance method, and the given unqualified lookup /// set is known to contain only instance members, at least one of which /// is from an appropriate type. -Sema::OwningExprResult +ExprResult Sema::BuildImplicitMemberExpr(const CXXScopeSpec &SS, LookupResult &R, const TemplateArgumentListInfo *TemplateArgs, @@ -1551,7 +1653,7 @@ Sema::BuildImplicitMemberExpr(const CXXScopeSpec &SS, This = new (Context) CXXThisExpr(Loc, ThisType, /*isImplicit=*/true); } - return BuildMemberReferenceExpr(ExprArg(*this, This), ThisType, + return BuildMemberReferenceExpr(This, ThisType, /*OpLoc*/ SourceLocation(), /*IsArrow*/ true, SS, @@ -1638,14 +1740,15 @@ static bool CheckDeclInExpr(Sema &S, SourceLocation Loc, NamedDecl *D) { return false; } -Sema::OwningExprResult +ExprResult Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS, LookupResult &R, bool NeedsADL) { // If this is a single, fully-resolved result and we don't need ADL, // just build an ordinary singleton decl ref. if (!NeedsADL && R.isSingleResult() && !R.getAsSingle<FunctionTemplateDecl>()) - return BuildDeclarationNameExpr(SS, R.getNameLoc(), R.getFoundDecl()); + return BuildDeclarationNameExpr(SS, R.getLookupNameInfo(), + R.getFoundDecl()); // We only need to check the declaration if there's exactly one // result, because in the overloaded case the results can only be @@ -1664,8 +1767,7 @@ Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS, UnresolvedLookupExpr *ULE = UnresolvedLookupExpr::Create(Context, Dependent, R.getNamingClass(), (NestedNameSpecifier*) SS.getScopeRep(), - SS.getRange(), - R.getLookupName(), R.getNameLoc(), + SS.getRange(), R.getLookupNameInfo(), NeedsADL, R.isOverloadedResult(), R.begin(), R.end()); @@ -1674,13 +1776,15 @@ Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS, /// \brief Complete semantic analysis for a reference to the given declaration. -Sema::OwningExprResult +ExprResult Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS, - SourceLocation Loc, NamedDecl *D) { + const DeclarationNameInfo &NameInfo, + NamedDecl *D) { assert(D && "Cannot refer to a NULL declaration"); assert(!isa<FunctionTemplateDecl>(D) && "Cannot refer unambiguously to a function template"); + SourceLocation Loc = NameInfo.getLoc(); if (CheckDeclInExpr(*this, Loc, D)) return ExprError(); @@ -1755,13 +1859,13 @@ Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS, DeclRefExpr(const_cast<ValueDecl*>(BDRE->getDecl()), T, SourceLocation()); - OwningExprResult Res = PerformCopyInitialization( + ExprResult Res = PerformCopyInitialization( InitializedEntity::InitializeBlock(VD->getLocation(), T, false), SourceLocation(), Owned(E)); if (!Res.isInvalid()) { - Res = MaybeCreateCXXExprWithTemporaries(move(Res)); + Res = MaybeCreateCXXExprWithTemporaries(Res.get()); Expr *Init = Res.takeAs<Expr>(); BDRE->setCopyConstructorExpr(Init); } @@ -1772,10 +1876,11 @@ Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS, // If this reference is not in a block or if the referenced variable is // within the block, create a normal DeclRefExpr. - return BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), Loc, &SS); + return BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), + NameInfo, &SS); } -Sema::OwningExprResult Sema::ActOnPredefinedExpr(SourceLocation Loc, +ExprResult Sema::ActOnPredefinedExpr(SourceLocation Loc, tok::TokenKind Kind) { PredefinedExpr::IdentType IT; @@ -1790,6 +1895,8 @@ Sema::OwningExprResult Sema::ActOnPredefinedExpr(SourceLocation Loc, // string. Decl *currentDecl = getCurFunctionOrMethodDecl(); + if (!currentDecl && getCurBlock()) + currentDecl = getCurBlock()->TheDecl; if (!currentDecl) { Diag(Loc, diag::ext_predef_outside_function); currentDecl = Context.getTranslationUnitDecl(); @@ -1808,7 +1915,7 @@ Sema::OwningExprResult Sema::ActOnPredefinedExpr(SourceLocation Loc, return Owned(new (Context) PredefinedExpr(Loc, ResTy, IT)); } -Sema::OwningExprResult Sema::ActOnCharacterConstant(const Token &Tok) { +ExprResult Sema::ActOnCharacterConstant(const Token &Tok) { llvm::SmallString<16> CharBuffer; bool Invalid = false; llvm::StringRef ThisTok = PP.getSpelling(Tok, CharBuffer, &Invalid); @@ -1835,13 +1942,13 @@ Sema::OwningExprResult Sema::ActOnCharacterConstant(const Token &Tok) { Ty, Tok.getLocation())); } -Action::OwningExprResult Sema::ActOnNumericConstant(const Token &Tok) { +ExprResult Sema::ActOnNumericConstant(const Token &Tok) { // Fast path for a single digit (which is quite common). A single digit // cannot have a trigraph, escaped newline, radix prefix, or type suffix. if (Tok.getLength() == 1) { const char Val = PP.getSpellingOfSingleCharacterNumericConstant(Tok); unsigned IntSize = Context.Target.getIntWidth(); - return Owned(new (Context) IntegerLiteral(llvm::APInt(IntSize, Val-'0'), + return Owned(IntegerLiteral::Create(Context, llvm::APInt(IntSize, Val-'0'), Context.IntTy, Tok.getLocation())); } @@ -1899,7 +2006,7 @@ Action::OwningExprResult Sema::ActOnNumericConstant(const Token &Tok) { } bool isExact = (result == APFloat::opOK); - Res = new (Context) FloatingLiteral(Val, isExact, Ty, Tok.getLocation()); + Res = FloatingLiteral::Create(Context, Val, isExact, Ty, Tok.getLocation()); } else if (!Literal.isIntegerLiteral()) { return ExprError(); @@ -1986,7 +2093,7 @@ Action::OwningExprResult Sema::ActOnNumericConstant(const Token &Tok) { if (ResultVal.getBitWidth() != Width) ResultVal.trunc(Width); } - Res = new (Context) IntegerLiteral(ResultVal, Ty, Tok.getLocation()); + Res = IntegerLiteral::Create(Context, ResultVal, Ty, Tok.getLocation()); } // If this is an imaginary literal, create the ImaginaryLiteral wrapper. @@ -1997,9 +2104,8 @@ Action::OwningExprResult Sema::ActOnNumericConstant(const Token &Tok) { return Owned(Res); } -Action::OwningExprResult Sema::ActOnParenExpr(SourceLocation L, - SourceLocation R, ExprArg Val) { - Expr *E = Val.takeAs<Expr>(); +ExprResult Sema::ActOnParenExpr(SourceLocation L, + SourceLocation R, Expr *E) { assert((E != 0) && "ActOnParenExpr() missing expr"); return Owned(new (Context) ParenExpr(L, R, E)); } @@ -2083,7 +2189,7 @@ bool Sema::CheckAlignOfExpr(Expr *E, SourceLocation OpLoc, } /// \brief Build a sizeof or alignof expression given a type operand. -Action::OwningExprResult +ExprResult Sema::CreateSizeOfAlignOfExpr(TypeSourceInfo *TInfo, SourceLocation OpLoc, bool isSizeOf, SourceRange R) { @@ -2104,7 +2210,7 @@ Sema::CreateSizeOfAlignOfExpr(TypeSourceInfo *TInfo, /// \brief Build a sizeof or alignof expression given an expression /// operand. -Action::OwningExprResult +ExprResult Sema::CreateSizeOfAlignOfExpr(Expr *E, SourceLocation OpLoc, bool isSizeOf, SourceRange R) { // Verify that the operand is valid. @@ -2132,7 +2238,7 @@ Sema::CreateSizeOfAlignOfExpr(Expr *E, SourceLocation OpLoc, /// ActOnSizeOfAlignOfExpr - Handle @c sizeof(type) and @c sizeof @c expr and /// the same for @c alignof and @c __alignof /// Note that the ArgRange is invalid if isType is false. -Action::OwningExprResult +ExprResult Sema::ActOnSizeOfAlignOfExpr(SourceLocation OpLoc, bool isSizeof, bool isType, void *TyOrEx, const SourceRange &ArgRange) { // If error parsing type, ignore. @@ -2140,17 +2246,14 @@ Sema::ActOnSizeOfAlignOfExpr(SourceLocation OpLoc, bool isSizeof, bool isType, if (isType) { TypeSourceInfo *TInfo; - (void) GetTypeFromParser(TyOrEx, &TInfo); + (void) GetTypeFromParser(ParsedType::getFromOpaquePtr(TyOrEx), &TInfo); return CreateSizeOfAlignOfExpr(TInfo, OpLoc, isSizeof, ArgRange); } Expr *ArgEx = (Expr *)TyOrEx; - Action::OwningExprResult Result + ExprResult Result = CreateSizeOfAlignOfExpr(ArgEx, OpLoc, isSizeof, ArgEx->getSourceRange()); - if (Result.isInvalid()) - DeleteExpr(ArgEx); - return move(Result); } @@ -2174,32 +2277,31 @@ QualType Sema::CheckRealImagOperand(Expr *&V, SourceLocation Loc, bool isReal) { -Action::OwningExprResult +ExprResult Sema::ActOnPostfixUnaryOp(Scope *S, SourceLocation OpLoc, - tok::TokenKind Kind, ExprArg Input) { - UnaryOperator::Opcode Opc; + tok::TokenKind Kind, Expr *Input) { + UnaryOperatorKind Opc; switch (Kind) { default: assert(0 && "Unknown unary op!"); - case tok::plusplus: Opc = UnaryOperator::PostInc; break; - case tok::minusminus: Opc = UnaryOperator::PostDec; break; + case tok::plusplus: Opc = UO_PostInc; break; + case tok::minusminus: Opc = UO_PostDec; break; } - return BuildUnaryOp(S, OpLoc, Opc, move(Input)); + return BuildUnaryOp(S, OpLoc, Opc, Input); } -Action::OwningExprResult -Sema::ActOnArraySubscriptExpr(Scope *S, ExprArg Base, SourceLocation LLoc, - ExprArg Idx, SourceLocation RLoc) { +ExprResult +Sema::ActOnArraySubscriptExpr(Scope *S, Expr *Base, SourceLocation LLoc, + Expr *Idx, SourceLocation RLoc) { // Since this might be a postfix expression, get rid of ParenListExprs. - Base = MaybeConvertParenListExprToParenExpr(S, move(Base)); + ExprResult Result = MaybeConvertParenListExprToParenExpr(S, Base); + if (Result.isInvalid()) return ExprError(); + Base = Result.take(); - Expr *LHSExp = static_cast<Expr*>(Base.get()), - *RHSExp = static_cast<Expr*>(Idx.get()); + Expr *LHSExp = Base, *RHSExp = Idx; if (getLangOptions().CPlusPlus && (LHSExp->isTypeDependent() || RHSExp->isTypeDependent())) { - Base.release(); - Idx.release(); return Owned(new (Context) ArraySubscriptExpr(LHSExp, RHSExp, Context.DependentTy, RLoc)); } @@ -2209,18 +2311,18 @@ Sema::ActOnArraySubscriptExpr(Scope *S, ExprArg Base, SourceLocation LLoc, LHSExp->getType()->isEnumeralType() || RHSExp->getType()->isRecordType() || RHSExp->getType()->isEnumeralType())) { - return CreateOverloadedArraySubscriptExpr(LLoc, RLoc, move(Base),move(Idx)); + return CreateOverloadedArraySubscriptExpr(LLoc, RLoc, Base, Idx); } - return CreateBuiltinArraySubscriptExpr(move(Base), LLoc, move(Idx), RLoc); + return CreateBuiltinArraySubscriptExpr(Base, LLoc, Idx, RLoc); } -Action::OwningExprResult -Sema::CreateBuiltinArraySubscriptExpr(ExprArg Base, SourceLocation LLoc, - ExprArg Idx, SourceLocation RLoc) { - Expr *LHSExp = static_cast<Expr*>(Base.get()); - Expr *RHSExp = static_cast<Expr*>(Idx.get()); +ExprResult +Sema::CreateBuiltinArraySubscriptExpr(Expr *Base, SourceLocation LLoc, + Expr *Idx, SourceLocation RLoc) { + Expr *LHSExp = Base; + Expr *RHSExp = Idx; // Perform default conversions. if (!LHSExp->getType()->getAs<VectorType>()) @@ -2274,7 +2376,7 @@ Sema::CreateBuiltinArraySubscriptExpr(ExprArg Base, SourceLocation LLoc, Diag(LHSExp->getLocStart(), diag::ext_subscript_non_lvalue) << LHSExp->getSourceRange(); ImpCastExprToType(LHSExp, Context.getArrayDecayedType(LHSTy), - CastExpr::CK_ArrayToPointerDecay); + CK_ArrayToPointerDecay); LHSTy = LHSExp->getType(); BaseExpr = LHSExp; @@ -2285,7 +2387,7 @@ Sema::CreateBuiltinArraySubscriptExpr(ExprArg Base, SourceLocation LLoc, Diag(RHSExp->getLocStart(), diag::ext_subscript_non_lvalue) << RHSExp->getSourceRange(); ImpCastExprToType(RHSExp, Context.getArrayDecayedType(RHSTy), - CastExpr::CK_ArrayToPointerDecay); + CK_ArrayToPointerDecay); RHSTy = RHSExp->getType(); BaseExpr = RHSExp; @@ -2296,8 +2398,7 @@ Sema::CreateBuiltinArraySubscriptExpr(ExprArg Base, SourceLocation LLoc, << LHSExp->getSourceRange() << RHSExp->getSourceRange()); } // C99 6.5.2.1p1 - if (!(IndexExpr->getType()->isIntegerType() && - IndexExpr->getType()->isScalarType()) && !IndexExpr->isTypeDependent()) + if (!IndexExpr->getType()->isIntegerType() && !IndexExpr->isTypeDependent()) return ExprError(Diag(LLoc, diag::err_typecheck_subscript_not_integer) << IndexExpr->getSourceRange()); @@ -2329,8 +2430,6 @@ Sema::CreateBuiltinArraySubscriptExpr(ExprArg Base, SourceLocation LLoc, return ExprError(); } - Base.release(); - Idx.release(); return Owned(new (Context) ArraySubscriptExpr(LHSExp, RHSExp, ResultType, RLoc)); } @@ -2377,7 +2476,7 @@ CheckExtVectorComponent(QualType baseType, SourceLocation OpLoc, // We didn't get to the end of the string. This means the component names // didn't come from the same set *or* we encountered an illegal name. Diag(OpLoc, diag::err_ext_vector_component_name_illegal) - << std::string(compStr,compStr+1) << SourceRange(CompLoc); + << llvm::StringRef(compStr, 1) << SourceRange(CompLoc); return QualType(); } @@ -2470,15 +2569,13 @@ static Decl *FindGetterNameDecl(const ObjCObjectPointerType *QIdTy, return GDecl; } -Sema::OwningExprResult -Sema::ActOnDependentMemberExpr(ExprArg Base, QualType BaseType, +ExprResult +Sema::ActOnDependentMemberExpr(Expr *BaseExpr, QualType BaseType, bool IsArrow, SourceLocation OpLoc, const CXXScopeSpec &SS, NamedDecl *FirstQualifierInScope, - DeclarationName Name, SourceLocation NameLoc, + const DeclarationNameInfo &NameInfo, const TemplateArgumentListInfo *TemplateArgs) { - Expr *BaseExpr = Base.takeAs<Expr>(); - // Even in dependent contexts, try to diagnose base expressions with // obviously wrong types, e.g.: // @@ -2493,24 +2590,24 @@ Sema::ActOnDependentMemberExpr(ExprArg Base, QualType BaseType, if (PT && (!getLangOptions().ObjC1 || PT->getPointeeType()->isRecordType())) { assert(BaseExpr && "cannot happen with implicit member accesses"); - Diag(NameLoc, diag::err_typecheck_member_reference_struct_union) + Diag(NameInfo.getLoc(), diag::err_typecheck_member_reference_struct_union) << BaseType << BaseExpr->getSourceRange(); return ExprError(); } } - assert(BaseType->isDependentType() || Name.isDependentName() || + assert(BaseType->isDependentType() || + NameInfo.getName().isDependentName() || isDependentScopeSpecifier(SS)); // Get the type being accessed in BaseType. If this is an arrow, the BaseExpr // must have pointer type, and the accessed type is the pointee. return Owned(CXXDependentScopeMemberExpr::Create(Context, BaseExpr, BaseType, IsArrow, OpLoc, - static_cast<NestedNameSpecifier*>(SS.getScopeRep()), + SS.getScopeRep(), SS.getRange(), FirstQualifierInScope, - Name, NameLoc, - TemplateArgs)); + NameInfo, TemplateArgs)); } /// We know that the given qualified member reference points only to @@ -2562,12 +2659,15 @@ bool Sema::CheckQualifiedMemberReference(Expr *BaseExpr, return false; // Note that we use the DC of the decl, not the underlying decl. - CXXRecordDecl *RecordD = cast<CXXRecordDecl>((*I)->getDeclContext()); - while (RecordD->isAnonymousStructOrUnion()) - RecordD = cast<CXXRecordDecl>(RecordD->getParent()); + DeclContext *DC = (*I)->getDeclContext(); + while (DC->isTransparentContext()) + DC = DC->getParent(); + if (!DC->isRecord()) + continue; + llvm::SmallPtrSet<CXXRecordDecl*,4> MemberRecord; - MemberRecord.insert(RecordD->getCanonicalDecl()); + MemberRecord.insert(cast<CXXRecordDecl>(DC)->getCanonicalDecl()); if (!IsProvablyNotDerivedFrom(*this, BaseRecord, MemberRecord)) return false; @@ -2646,24 +2746,21 @@ LookupMemberExprInRecord(Sema &SemaRef, LookupResult &R, return false; } -Sema::OwningExprResult -Sema::BuildMemberReferenceExpr(ExprArg BaseArg, QualType BaseType, +ExprResult +Sema::BuildMemberReferenceExpr(Expr *Base, QualType BaseType, SourceLocation OpLoc, bool IsArrow, CXXScopeSpec &SS, NamedDecl *FirstQualifierInScope, - DeclarationName Name, SourceLocation NameLoc, + const DeclarationNameInfo &NameInfo, const TemplateArgumentListInfo *TemplateArgs) { - Expr *Base = BaseArg.takeAs<Expr>(); - if (BaseType->isDependentType() || (SS.isSet() && isDependentScopeSpecifier(SS))) - return ActOnDependentMemberExpr(ExprArg(*this, Base), BaseType, + return ActOnDependentMemberExpr(Base, BaseType, IsArrow, OpLoc, SS, FirstQualifierInScope, - Name, NameLoc, - TemplateArgs); + NameInfo, TemplateArgs); - LookupResult R(*this, Name, NameLoc, LookupMemberName); + LookupResult R(*this, NameInfo, LookupMemberName); // Implicit member accesses. if (!Base) { @@ -2676,9 +2773,9 @@ Sema::BuildMemberReferenceExpr(ExprArg BaseArg, QualType BaseType, // Explicit member accesses. } else { - OwningExprResult Result = + ExprResult Result = LookupMemberExpr(R, Base, IsArrow, OpLoc, - SS, /*ObjCImpDecl*/ DeclPtrTy(), TemplateArgs != 0); + SS, /*ObjCImpDecl*/ 0, TemplateArgs != 0); if (Result.isInvalid()) { Owned(Base); @@ -2692,20 +2789,19 @@ Sema::BuildMemberReferenceExpr(ExprArg BaseArg, QualType BaseType, BaseType = Base->getType(); } - return BuildMemberReferenceExpr(ExprArg(*this, Base), BaseType, + return BuildMemberReferenceExpr(Base, BaseType, OpLoc, IsArrow, SS, FirstQualifierInScope, R, TemplateArgs); } -Sema::OwningExprResult -Sema::BuildMemberReferenceExpr(ExprArg Base, QualType BaseExprType, +ExprResult +Sema::BuildMemberReferenceExpr(Expr *BaseExpr, QualType BaseExprType, SourceLocation OpLoc, bool IsArrow, const CXXScopeSpec &SS, NamedDecl *FirstQualifierInScope, LookupResult &R, const TemplateArgumentListInfo *TemplateArgs, bool SuppressQualifierCheck) { - Expr *BaseExpr = Base.takeAs<Expr>(); QualType BaseType = BaseExprType; if (IsArrow) { assert(BaseType->isPointerType()); @@ -2713,10 +2809,10 @@ Sema::BuildMemberReferenceExpr(ExprArg Base, QualType BaseExprType, } R.setBaseObjectType(BaseType); - NestedNameSpecifier *Qualifier = - static_cast<NestedNameSpecifier*>(SS.getScopeRep()); - DeclarationName MemberName = R.getLookupName(); - SourceLocation MemberLoc = R.getNameLoc(); + NestedNameSpecifier *Qualifier = SS.getScopeRep(); + const DeclarationNameInfo &MemberNameInfo = R.getLookupNameInfo(); + DeclarationName MemberName = MemberNameInfo.getName(); + SourceLocation MemberLoc = MemberNameInfo.getLoc(); if (R.isAmbiguous()) return ExprError(); @@ -2765,7 +2861,7 @@ Sema::BuildMemberReferenceExpr(ExprArg Base, QualType BaseExprType, BaseExpr, BaseExprType, IsArrow, OpLoc, Qualifier, SS.getRange(), - MemberName, MemberLoc, + MemberNameInfo, TemplateArgs, R.begin(), R.end()); return Owned(MemExpr); @@ -2787,7 +2883,7 @@ Sema::BuildMemberReferenceExpr(ExprArg Base, QualType BaseExprType, if (!BaseExpr) { // If this is not an instance member, convert to a non-member access. if (!MemberDecl->isCXXInstanceMember()) - return BuildDeclarationNameExpr(SS, R.getNameLoc(), MemberDecl); + return BuildDeclarationNameExpr(SS, R.getLookupNameInfo(), MemberDecl); SourceLocation Loc = R.getNameLoc(); if (SS.getRange().isValid()) @@ -2838,34 +2934,36 @@ Sema::BuildMemberReferenceExpr(ExprArg Base, QualType BaseExprType, if (PerformObjectMemberConversion(BaseExpr, Qualifier, FoundDecl, FD)) return ExprError(); return Owned(BuildMemberExpr(Context, BaseExpr, IsArrow, SS, - FD, FoundDecl, MemberLoc, MemberType)); + FD, FoundDecl, MemberNameInfo, + MemberType)); } if (VarDecl *Var = dyn_cast<VarDecl>(MemberDecl)) { MarkDeclarationReferenced(MemberLoc, Var); return Owned(BuildMemberExpr(Context, BaseExpr, IsArrow, SS, - Var, FoundDecl, MemberLoc, + Var, FoundDecl, MemberNameInfo, Var->getType().getNonReferenceType())); } if (FunctionDecl *MemberFn = dyn_cast<FunctionDecl>(MemberDecl)) { MarkDeclarationReferenced(MemberLoc, MemberDecl); return Owned(BuildMemberExpr(Context, BaseExpr, IsArrow, SS, - MemberFn, FoundDecl, MemberLoc, + MemberFn, FoundDecl, MemberNameInfo, MemberFn->getType())); } if (EnumConstantDecl *Enum = dyn_cast<EnumConstantDecl>(MemberDecl)) { MarkDeclarationReferenced(MemberLoc, MemberDecl); return Owned(BuildMemberExpr(Context, BaseExpr, IsArrow, SS, - Enum, FoundDecl, MemberLoc, Enum->getType())); + Enum, FoundDecl, MemberNameInfo, + Enum->getType())); } Owned(BaseExpr); // We found something that we didn't expect. Complain. if (isa<TypeDecl>(MemberDecl)) - Diag(MemberLoc,diag::err_typecheck_member_reference_type) + Diag(MemberLoc, diag::err_typecheck_member_reference_type) << MemberName << BaseType << int(IsArrow); else Diag(MemberLoc, diag::err_typecheck_member_reference_unknown) @@ -2887,11 +2985,11 @@ Sema::BuildMemberReferenceExpr(ExprArg Base, QualType BaseExprType, /// /// The ObjCImpDecl bit is a gross hack that will need to be properly /// fixed for ObjC++. -Sema::OwningExprResult +ExprResult Sema::LookupMemberExpr(LookupResult &R, Expr *&BaseExpr, bool &IsArrow, SourceLocation OpLoc, CXXScopeSpec &SS, - DeclPtrTy ObjCImpDecl, bool HasTemplateArgs) { + Decl *ObjCImpDecl, bool HasTemplateArgs) { assert(BaseExpr && "no base expression"); // Perform default conversions. @@ -2921,8 +3019,8 @@ Sema::LookupMemberExpr(LookupResult &R, Expr *&BaseExpr, << QualType(Fun, 0) << FixItHint::CreateInsertion(Loc, "()"); - OwningExprResult NewBase - = ActOnCallExpr(0, ExprArg(*this, BaseExpr), Loc, + ExprResult NewBase + = ActOnCallExpr(0, BaseExpr, Loc, MultiExprArg(*this, 0, 0), 0, Loc); BaseExpr = 0; if (NewBase.isInvalid()) @@ -2952,7 +3050,7 @@ Sema::LookupMemberExpr(LookupResult &R, Expr *&BaseExpr, // is a reference to 'isa'. if (BaseType != Context.ObjCIdRedefinitionType) { BaseType = Context.ObjCIdRedefinitionType; - ImpCastExprToType(BaseExpr, BaseType, CastExpr::CK_BitCast); + ImpCastExprToType(BaseExpr, BaseType, CK_BitCast); } } @@ -2963,7 +3061,7 @@ Sema::LookupMemberExpr(LookupResult &R, Expr *&BaseExpr, // is a reference to 'sel_id'. if (BaseType != Context.ObjCSelRedefinitionType) { BaseType = Context.ObjCSelRedefinitionType; - ImpCastExprToType(BaseExpr, BaseType, CastExpr::CK_BitCast); + ImpCastExprToType(BaseExpr, BaseType, CK_BitCast); } } @@ -3022,7 +3120,7 @@ Sema::LookupMemberExpr(LookupResult &R, Expr *&BaseExpr, if (BaseType->isObjCClassType() && BaseType != Context.ObjCClassRedefinitionType) { BaseType = Context.ObjCClassRedefinitionType; - ImpCastExprToType(BaseExpr, BaseType, CastExpr::CK_BitCast); + ImpCastExprToType(BaseExpr, BaseType, CK_BitCast); } if (IsArrow) { @@ -3129,12 +3227,11 @@ Sema::LookupMemberExpr(LookupResult &R, Expr *&BaseExpr, // down the context as argument to this routine. Ideally, this context // need be passed down in the AST node and somehow calculated from the // AST for a function decl. - Decl *ImplDecl = ObjCImpDecl.getAs<Decl>(); if (ObjCImplementationDecl *IMPD = - dyn_cast<ObjCImplementationDecl>(ImplDecl)) + dyn_cast<ObjCImplementationDecl>(ObjCImpDecl)) ClassOfMethodDecl = IMPD->getClassInterface(); else if (ObjCCategoryImplDecl* CatImplClass = - dyn_cast<ObjCCategoryImplDecl>(ImplDecl)) + dyn_cast<ObjCCategoryImplDecl>(ObjCImpDecl)) ClassOfMethodDecl = CatImplClass->getClassInterface(); } @@ -3235,12 +3332,12 @@ Sema::LookupMemberExpr(LookupResult &R, Expr *&BaseExpr, /// \param ObjCImpDecl the current ObjC @implementation decl; /// this is an ugly hack around the fact that ObjC @implementations /// aren't properly put in the context chain -Sema::OwningExprResult Sema::ActOnMemberAccessExpr(Scope *S, ExprArg BaseArg, +ExprResult Sema::ActOnMemberAccessExpr(Scope *S, Expr *Base, SourceLocation OpLoc, tok::TokenKind OpKind, CXXScopeSpec &SS, UnqualifiedId &Id, - DeclPtrTy ObjCImpDecl, + Decl *ObjCImpDecl, bool HasTrailingLParen) { if (SS.isSet() && SS.isInvalid()) return ExprError(); @@ -3248,12 +3345,12 @@ Sema::OwningExprResult Sema::ActOnMemberAccessExpr(Scope *S, ExprArg BaseArg, TemplateArgumentListInfo TemplateArgsBuffer; // Decompose the name into its component parts. - DeclarationName Name; - SourceLocation NameLoc; + DeclarationNameInfo NameInfo; const TemplateArgumentListInfo *TemplateArgs; DecomposeUnqualifiedId(*this, Id, TemplateArgsBuffer, - Name, NameLoc, TemplateArgs); + NameInfo, TemplateArgs); + DeclarationName Name = NameInfo.getName(); bool IsArrow = (OpKind == tok::arrow); NamedDecl *FirstQualifierInScope @@ -3261,19 +3358,18 @@ Sema::OwningExprResult Sema::ActOnMemberAccessExpr(Scope *S, ExprArg BaseArg, static_cast<NestedNameSpecifier*>(SS.getScopeRep()))); // This is a postfix expression, so get rid of ParenListExprs. - BaseArg = MaybeConvertParenListExprToParenExpr(S, move(BaseArg)); + ExprResult Result = MaybeConvertParenListExprToParenExpr(S, Base); + if (Result.isInvalid()) return ExprError(); + Base = Result.take(); - Expr *Base = BaseArg.takeAs<Expr>(); - OwningExprResult Result(*this); if (Base->getType()->isDependentType() || Name.isDependentName() || isDependentScopeSpecifier(SS)) { - Result = ActOnDependentMemberExpr(ExprArg(*this, Base), Base->getType(), + Result = ActOnDependentMemberExpr(Base, Base->getType(), IsArrow, OpLoc, SS, FirstQualifierInScope, - Name, NameLoc, - TemplateArgs); + NameInfo, TemplateArgs); } else { - LookupResult R(*this, Name, NameLoc, LookupMemberName); + LookupResult R(*this, NameInfo, LookupMemberName); Result = LookupMemberExpr(R, Base, IsArrow, OpLoc, SS, ObjCImpDecl, TemplateArgs != 0); @@ -3289,12 +3385,12 @@ Sema::OwningExprResult Sema::ActOnMemberAccessExpr(Scope *S, ExprArg BaseArg, // call now. if (!HasTrailingLParen && Id.getKind() == UnqualifiedId::IK_DestructorName) - return DiagnoseDtorReference(NameLoc, move(Result)); + return DiagnoseDtorReference(NameInfo.getLoc(), Result.get()); return move(Result); } - Result = BuildMemberReferenceExpr(ExprArg(*this, Base), Base->getType(), + Result = BuildMemberReferenceExpr(Base, Base->getType(), OpLoc, IsArrow, SS, FirstQualifierInScope, R, TemplateArgs); } @@ -3302,7 +3398,7 @@ Sema::OwningExprResult Sema::ActOnMemberAccessExpr(Scope *S, ExprArg BaseArg, return move(Result); } -Sema::OwningExprResult Sema::BuildCXXDefaultArgExpr(SourceLocation CallLoc, +ExprResult Sema::BuildCXXDefaultArgExpr(SourceLocation CallLoc, FunctionDecl *FD, ParmVarDecl *Param) { if (Param->hasUnparsedDefaultArg()) { @@ -3324,7 +3420,7 @@ Sema::OwningExprResult Sema::BuildCXXDefaultArgExpr(SourceLocation CallLoc, InstantiatingTemplate Inst(*this, CallLoc, Param, Innermost.first, Innermost.second); - OwningExprResult Result = SubstExpr(UninstExpr, ArgList); + ExprResult Result = SubstExpr(UninstExpr, ArgList); if (Result.isInvalid()) return ExprError(); @@ -3338,7 +3434,7 @@ Sema::OwningExprResult Sema::BuildCXXDefaultArgExpr(SourceLocation CallLoc, InitializationSequence InitSeq(*this, Entity, Kind, &ResultE, 1); Result = InitSeq.Perform(*this, Entity, Kind, - MultiExprArg(*this, (void**)&ResultE, 1)); + MultiExprArg(*this, &ResultE, 1)); if (Result.isInvalid()) return ExprError(); @@ -3457,7 +3553,7 @@ bool Sema::GatherArgumentsForCall(SourceLocation CallLoc, InitializedEntity Entity = Param? InitializedEntity::InitializeParameter(Param) : InitializedEntity::InitializeParameter(ProtoArgType); - OwningExprResult ArgE = PerformCopyInitialization(Entity, + ExprResult ArgE = PerformCopyInitialization(Entity, SourceLocation(), Owned(Arg)); if (ArgE.isInvalid()) @@ -3467,7 +3563,7 @@ bool Sema::GatherArgumentsForCall(SourceLocation CallLoc, } else { ParmVarDecl *Param = FDecl->getParamDecl(i); - OwningExprResult ArgExpr = + ExprResult ArgExpr = BuildCXXDefaultArgExpr(CallLoc, FDecl, Param); if (ArgExpr.isInvalid()) return true; @@ -3492,18 +3588,18 @@ bool Sema::GatherArgumentsForCall(SourceLocation CallLoc, /// ActOnCallExpr - Handle a call to Fn with the specified array of arguments. /// This provides the location of the left/right parens and a list of comma /// locations. -Action::OwningExprResult -Sema::ActOnCallExpr(Scope *S, ExprArg fn, SourceLocation LParenLoc, +ExprResult +Sema::ActOnCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc, MultiExprArg args, SourceLocation *CommaLocs, SourceLocation RParenLoc) { unsigned NumArgs = args.size(); // Since this might be a postfix expression, get rid of ParenListExprs. - fn = MaybeConvertParenListExprToParenExpr(S, move(fn)); + ExprResult Result = MaybeConvertParenListExprToParenExpr(S, Fn); + if (Result.isInvalid()) return ExprError(); + Fn = Result.take(); - Expr *Fn = fn.takeAs<Expr>(); - Expr **Args = reinterpret_cast<Expr**>(args.release()); - assert(Fn && "no function call expression"); + Expr **Args = args.release(); if (getLangOptions().CPlusPlus) { // If this is a pseudo-destructor expression, build the call immediately. @@ -3515,9 +3611,6 @@ Sema::ActOnCallExpr(Scope *S, ExprArg fn, SourceLocation LParenLoc, SourceRange(Args[0]->getLocStart(), Args[NumArgs-1]->getLocEnd())); - for (unsigned I = 0; I != NumArgs; ++I) - Args[I]->Destroy(Context); - NumArgs = 0; } @@ -3572,27 +3665,27 @@ Sema::ActOnCallExpr(Scope *S, ExprArg fn, SourceLocation LParenLoc, // Determine whether this is a call to a pointer-to-member function. if (BinaryOperator *BO = dyn_cast<BinaryOperator>(NakedFn)) { - if (BO->getOpcode() == BinaryOperator::PtrMemD || - BO->getOpcode() == BinaryOperator::PtrMemI) { + if (BO->getOpcode() == BO_PtrMemD || + BO->getOpcode() == BO_PtrMemI) { if (const FunctionProtoType *FPT = BO->getType()->getAs<FunctionProtoType>()) { QualType ResultTy = FPT->getCallResultType(Context); - ExprOwningPtr<CXXMemberCallExpr> - TheCall(this, new (Context) CXXMemberCallExpr(Context, BO, Args, - NumArgs, ResultTy, - RParenLoc)); + CXXMemberCallExpr *TheCall + = new (Context) CXXMemberCallExpr(Context, BO, Args, + NumArgs, ResultTy, + RParenLoc); if (CheckCallReturnType(FPT->getResultType(), BO->getRHS()->getSourceRange().getBegin(), - TheCall.get(), 0)) + TheCall, 0)) return ExprError(); - if (ConvertArgumentsForCall(&*TheCall, BO, 0, FPT, Args, NumArgs, + if (ConvertArgumentsForCall(TheCall, BO, 0, FPT, Args, NumArgs, RParenLoc)) return ExprError(); - return Owned(MaybeBindToTemporary(TheCall.release()).release()); + return MaybeBindToTemporary(TheCall); } return ExprError(Diag(Fn->getLocStart(), diag::err_typecheck_call_not_function) @@ -3625,7 +3718,7 @@ Sema::ActOnCallExpr(Scope *S, ExprArg fn, SourceLocation LParenLoc, /// block-pointer type. /// /// \param NDecl the declaration being called, if available -Sema::OwningExprResult +ExprResult Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl, SourceLocation LParenLoc, Expr **Args, unsigned NumArgs, @@ -3637,10 +3730,10 @@ Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl, // Make the call expr early, before semantic checks. This guarantees cleanup // of arguments and function on error. - ExprOwningPtr<CallExpr> TheCall(this, new (Context) CallExpr(Context, Fn, - Args, NumArgs, - Context.BoolTy, - RParenLoc)); + CallExpr *TheCall = new (Context) CallExpr(Context, Fn, + Args, NumArgs, + Context.BoolTy, + RParenLoc); const FunctionType *FuncT; if (!Fn->getType()->isBlockPointerType()) { @@ -3661,7 +3754,7 @@ Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl, // Check for a valid return type if (CheckCallReturnType(FuncT->getResultType(), - Fn->getSourceRange().getBegin(), TheCall.get(), + Fn->getSourceRange().getBegin(), TheCall, FDecl)) return ExprError(); @@ -3669,7 +3762,7 @@ Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl, TheCall->setType(FuncT->getCallResultType(Context)); if (const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FuncT)) { - if (ConvertArgumentsForCall(&*TheCall, Fn, FDecl, Proto, Args, NumArgs, + if (ConvertArgumentsForCall(TheCall, Fn, FDecl, Proto, Args, NumArgs, RParenLoc)) return ExprError(); } else { @@ -3713,22 +3806,22 @@ Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl, // Do special checking on direct calls to functions. if (FDecl) { - if (CheckFunctionCall(FDecl, TheCall.get())) + if (CheckFunctionCall(FDecl, TheCall)) return ExprError(); if (unsigned BuiltinID = FDecl->getBuiltinID()) - return CheckBuiltinFunctionCall(BuiltinID, TheCall.take()); + return CheckBuiltinFunctionCall(BuiltinID, TheCall); } else if (NDecl) { - if (CheckBlockCall(NDecl, TheCall.get())) + if (CheckBlockCall(NDecl, TheCall)) return ExprError(); } - return MaybeBindToTemporary(TheCall.take()); + return MaybeBindToTemporary(TheCall); } -Action::OwningExprResult -Sema::ActOnCompoundLiteral(SourceLocation LParenLoc, TypeTy *Ty, - SourceLocation RParenLoc, ExprArg InitExpr) { +ExprResult +Sema::ActOnCompoundLiteral(SourceLocation LParenLoc, ParsedType Ty, + SourceLocation RParenLoc, Expr *InitExpr) { assert((Ty != 0) && "ActOnCompoundLiteral(): missing type"); // FIXME: put back this assert when initializers are worked out. //assert((InitExpr != 0) && "ActOnCompoundLiteral(): missing expression"); @@ -3738,14 +3831,13 @@ Sema::ActOnCompoundLiteral(SourceLocation LParenLoc, TypeTy *Ty, if (!TInfo) TInfo = Context.getTrivialTypeSourceInfo(literalType); - return BuildCompoundLiteralExpr(LParenLoc, TInfo, RParenLoc, move(InitExpr)); + return BuildCompoundLiteralExpr(LParenLoc, TInfo, RParenLoc, InitExpr); } -Action::OwningExprResult +ExprResult Sema::BuildCompoundLiteralExpr(SourceLocation LParenLoc, TypeSourceInfo *TInfo, - SourceLocation RParenLoc, ExprArg InitExpr) { + SourceLocation RParenLoc, Expr *literalExpr) { QualType literalType = TInfo->getType(); - Expr *literalExpr = static_cast<Expr*>(InitExpr.get()); if (literalType->isArrayType()) { if (literalType->isVariableArrayType()) @@ -3764,13 +3856,12 @@ Sema::BuildCompoundLiteralExpr(SourceLocation LParenLoc, TypeSourceInfo *TInfo, = InitializationKind::CreateCast(SourceRange(LParenLoc, RParenLoc), /*IsCStyleCast=*/true); InitializationSequence InitSeq(*this, Entity, Kind, &literalExpr, 1); - OwningExprResult Result = InitSeq.Perform(*this, Entity, Kind, - MultiExprArg(*this, (void**)&literalExpr, 1), + ExprResult Result = InitSeq.Perform(*this, Entity, Kind, + MultiExprArg(*this, &literalExpr, 1), &literalType); if (Result.isInvalid()) return ExprError(); - InitExpr.release(); - literalExpr = static_cast<Expr*>(Result.get()); + literalExpr = Result.get(); bool isFileScope = getCurFunctionOrMethodDecl() == 0; if (isFileScope) { // 6.5.2.5p3 @@ -3778,17 +3869,15 @@ Sema::BuildCompoundLiteralExpr(SourceLocation LParenLoc, TypeSourceInfo *TInfo, return ExprError(); } - Result.release(); - return Owned(new (Context) CompoundLiteralExpr(LParenLoc, TInfo, literalType, literalExpr, isFileScope)); } -Action::OwningExprResult +ExprResult Sema::ActOnInitList(SourceLocation LBraceLoc, MultiExprArg initlist, SourceLocation RBraceLoc) { unsigned NumInit = initlist.size(); - Expr **InitList = reinterpret_cast<Expr**>(initlist.release()); + Expr **InitList = initlist.release(); // Semantic analysis for initializers is done by ActOnDeclarator() and // CheckInitializer() - it requires knowledge of the object being intialized. @@ -3799,45 +3888,45 @@ Sema::ActOnInitList(SourceLocation LBraceLoc, MultiExprArg initlist, return Owned(E); } -static CastExpr::CastKind getScalarCastKind(ASTContext &Context, +static CastKind getScalarCastKind(ASTContext &Context, QualType SrcTy, QualType DestTy) { if (Context.hasSameUnqualifiedType(SrcTy, DestTy)) - return CastExpr::CK_NoOp; + return CK_NoOp; if (SrcTy->hasPointerRepresentation()) { if (DestTy->hasPointerRepresentation()) return DestTy->isObjCObjectPointerType() ? - CastExpr::CK_AnyPointerToObjCPointerCast : - CastExpr::CK_BitCast; + CK_AnyPointerToObjCPointerCast : + CK_BitCast; if (DestTy->isIntegerType()) - return CastExpr::CK_PointerToIntegral; + return CK_PointerToIntegral; } if (SrcTy->isIntegerType()) { if (DestTy->isIntegerType()) - return CastExpr::CK_IntegralCast; + return CK_IntegralCast; if (DestTy->hasPointerRepresentation()) - return CastExpr::CK_IntegralToPointer; + return CK_IntegralToPointer; if (DestTy->isRealFloatingType()) - return CastExpr::CK_IntegralToFloating; + return CK_IntegralToFloating; } if (SrcTy->isRealFloatingType()) { if (DestTy->isRealFloatingType()) - return CastExpr::CK_FloatingCast; + return CK_FloatingCast; if (DestTy->isIntegerType()) - return CastExpr::CK_FloatingToIntegral; + return CK_FloatingToIntegral; } // FIXME: Assert here. // assert(false && "Unhandled cast combination!"); - return CastExpr::CK_Unknown; + return CK_Unknown; } /// CheckCastTypes - Check type constraints for casting between types. bool Sema::CheckCastTypes(SourceRange TyR, QualType castType, Expr *&castExpr, - CastExpr::CastKind& Kind, - CXXBaseSpecifierArray &BasePath, + CastKind& Kind, + CXXCastPath &BasePath, bool FunctionalStyle) { if (getLangOptions().CPlusPlus) return CXXCheckCStyleCast(TyR, castType, castExpr, Kind, BasePath, @@ -3849,10 +3938,14 @@ bool Sema::CheckCastTypes(SourceRange TyR, QualType castType, Expr *&castExpr, // type needs to be scalar. if (castType->isVoidType()) { // Cast to void allows any expr type. - Kind = CastExpr::CK_ToVoid; + Kind = CK_ToVoid; return false; } + if (RequireCompleteType(TyR.getBegin(), castType, + diag::err_typecheck_cast_to_incomplete)) + return true; + if (!castType->isScalarType() && !castType->isVectorType()) { if (Context.hasSameUnqualifiedType(castType, castExpr->getType()) && (castType->isStructureType() || castType->isUnionType())) { @@ -3860,7 +3953,7 @@ bool Sema::CheckCastTypes(SourceRange TyR, QualType castType, Expr *&castExpr, // FIXME: Check that the cast destination type is complete. Diag(TyR.getBegin(), diag::ext_typecheck_cast_nonscalar) << castType << castExpr->getSourceRange(); - Kind = CastExpr::CK_NoOp; + Kind = CK_NoOp; return false; } @@ -3880,7 +3973,7 @@ bool Sema::CheckCastTypes(SourceRange TyR, QualType castType, Expr *&castExpr, if (Field == FieldEnd) return Diag(TyR.getBegin(), diag::err_typecheck_cast_to_union_no_type) << castExpr->getType() << castExpr->getSourceRange(); - Kind = CastExpr::CK_ToUnion; + Kind = CK_ToUnion; return false; } @@ -3922,11 +4015,15 @@ bool Sema::CheckCastTypes(SourceRange TyR, QualType castType, Expr *&castExpr, } Kind = getScalarCastKind(Context, castExpr->getType(), castType); + + if (Kind == CK_Unknown || Kind == CK_BitCast) + CheckCastAlign(castExpr, castType, TyR); + return false; } bool Sema::CheckVectorCast(SourceRange R, QualType VectorTy, QualType Ty, - CastExpr::CastKind &Kind) { + CastKind &Kind) { assert(VectorTy->isVectorType() && "Not a vector type!"); if (Ty->isVectorType() || Ty->isIntegerType()) { @@ -3941,12 +4038,12 @@ bool Sema::CheckVectorCast(SourceRange R, QualType VectorTy, QualType Ty, diag::err_invalid_conversion_between_vector_and_scalar) << VectorTy << Ty << R; - Kind = CastExpr::CK_BitCast; + Kind = CK_BitCast; return false; } bool Sema::CheckExtVectorCast(SourceRange R, QualType DestTy, Expr *&CastExpr, - CastExpr::CastKind &Kind) { + CastKind &Kind) { assert(DestTy->isExtVectorType() && "Not an extended vector type!"); QualType SrcTy = CastExpr->getType(); @@ -3957,7 +4054,7 @@ bool Sema::CheckExtVectorCast(SourceRange R, QualType DestTy, Expr *&CastExpr, if (Context.getTypeSize(DestTy) != Context.getTypeSize(SrcTy)) return Diag(R.getBegin(),diag::err_invalid_conversion_between_ext_vectors) << DestTy << SrcTy << R; - Kind = CastExpr::CK_BitCast; + Kind = CK_BitCast; return false; } @@ -3973,14 +4070,14 @@ bool Sema::CheckExtVectorCast(SourceRange R, QualType DestTy, Expr *&CastExpr, ImpCastExprToType(CastExpr, DestElemTy, getScalarCastKind(Context, SrcTy, DestElemTy)); - Kind = CastExpr::CK_VectorSplat; + Kind = CK_VectorSplat; return false; } -Action::OwningExprResult -Sema::ActOnCastExpr(Scope *S, SourceLocation LParenLoc, TypeTy *Ty, - SourceLocation RParenLoc, ExprArg Op) { - assert((Ty != 0) && (Op.get() != 0) && +ExprResult +Sema::ActOnCastExpr(Scope *S, SourceLocation LParenLoc, ParsedType Ty, + SourceLocation RParenLoc, Expr *castExpr) { + assert((Ty != 0) && (castExpr != 0) && "ActOnCastExpr(): missing type or expr"); TypeSourceInfo *castTInfo; @@ -3989,55 +4086,52 @@ Sema::ActOnCastExpr(Scope *S, SourceLocation LParenLoc, TypeTy *Ty, castTInfo = Context.getTrivialTypeSourceInfo(castType); // If the Expr being casted is a ParenListExpr, handle it specially. - Expr *castExpr = (Expr *)Op.get(); if (isa<ParenListExpr>(castExpr)) - return ActOnCastOfParenListExpr(S, LParenLoc, RParenLoc, move(Op), + return ActOnCastOfParenListExpr(S, LParenLoc, RParenLoc, castExpr, castTInfo); - return BuildCStyleCastExpr(LParenLoc, castTInfo, RParenLoc, move(Op)); + return BuildCStyleCastExpr(LParenLoc, castTInfo, RParenLoc, castExpr); } -Action::OwningExprResult +ExprResult Sema::BuildCStyleCastExpr(SourceLocation LParenLoc, TypeSourceInfo *Ty, - SourceLocation RParenLoc, ExprArg Op) { - Expr *castExpr = static_cast<Expr*>(Op.get()); - - CastExpr::CastKind Kind = CastExpr::CK_Unknown; - CXXBaseSpecifierArray BasePath; + SourceLocation RParenLoc, Expr *castExpr) { + CastKind Kind = CK_Unknown; + CXXCastPath BasePath; if (CheckCastTypes(SourceRange(LParenLoc, RParenLoc), Ty->getType(), castExpr, Kind, BasePath)) return ExprError(); - Op.release(); - return Owned(new (Context) CStyleCastExpr( + return Owned(CStyleCastExpr::Create(Context, Ty->getType().getNonLValueExprType(Context), - Kind, castExpr, BasePath, Ty, - LParenLoc, RParenLoc)); + Kind, castExpr, &BasePath, Ty, + LParenLoc, RParenLoc)); } /// This is not an AltiVec-style cast, so turn the ParenListExpr into a sequence /// of comma binary operators. -Action::OwningExprResult -Sema::MaybeConvertParenListExprToParenExpr(Scope *S, ExprArg EA) { - Expr *expr = EA.takeAs<Expr>(); +ExprResult +Sema::MaybeConvertParenListExprToParenExpr(Scope *S, Expr *expr) { ParenListExpr *E = dyn_cast<ParenListExpr>(expr); if (!E) return Owned(expr); - OwningExprResult Result(*this, E->getExpr(0)); + ExprResult Result(E->getExpr(0)); for (unsigned i = 1, e = E->getNumExprs(); i != e && !Result.isInvalid(); ++i) - Result = ActOnBinOp(S, E->getExprLoc(), tok::comma, move(Result), - Owned(E->getExpr(i))); + Result = ActOnBinOp(S, E->getExprLoc(), tok::comma, Result.get(), + E->getExpr(i)); - return ActOnParenExpr(E->getLParenLoc(), E->getRParenLoc(), move(Result)); + if (Result.isInvalid()) return ExprError(); + + return ActOnParenExpr(E->getLParenLoc(), E->getRParenLoc(), Result.get()); } -Action::OwningExprResult +ExprResult Sema::ActOnCastOfParenListExpr(Scope *S, SourceLocation LParenLoc, - SourceLocation RParenLoc, ExprArg Op, + SourceLocation RParenLoc, Expr *Op, TypeSourceInfo *TInfo) { - ParenListExpr *PE = (ParenListExpr *)Op.get(); + ParenListExpr *PE = cast<ParenListExpr>(Op); QualType Ty = TInfo->getType(); bool isAltiVecLiteral = false; @@ -4065,24 +4159,24 @@ Sema::ActOnCastOfParenListExpr(Scope *S, SourceLocation LParenLoc, // FIXME: This means that pretty-printing the final AST will produce curly // braces instead of the original commas. - Op.release(); InitListExpr *E = new (Context) InitListExpr(Context, LParenLoc, &initExprs[0], initExprs.size(), RParenLoc); E->setType(Ty); - return BuildCompoundLiteralExpr(LParenLoc, TInfo, RParenLoc, Owned(E)); + return BuildCompoundLiteralExpr(LParenLoc, TInfo, RParenLoc, E); } else { // This is not an AltiVec-style cast, so turn the ParenListExpr into a // sequence of BinOp comma operators. - Op = MaybeConvertParenListExprToParenExpr(S, move(Op)); - return BuildCStyleCastExpr(LParenLoc, TInfo, RParenLoc, move(Op)); + ExprResult Result = MaybeConvertParenListExprToParenExpr(S, Op); + if (Result.isInvalid()) return ExprError(); + return BuildCStyleCastExpr(LParenLoc, TInfo, RParenLoc, Result.take()); } } -Action::OwningExprResult Sema::ActOnParenOrParenListExpr(SourceLocation L, +ExprResult Sema::ActOnParenOrParenListExpr(SourceLocation L, SourceLocation R, MultiExprArg Val, - TypeTy *TypeOfCast) { + ParsedType TypeOfCast) { unsigned nexprs = Val.size(); Expr **exprs = reinterpret_cast<Expr**>(Val.release()); assert((exprs != 0) && "ActOnParenOrParenListExpr() missing expr list"); @@ -4148,8 +4242,8 @@ QualType Sema::CheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS, if (!RHSTy->isVoidType()) Diag(LHS->getLocStart(), diag::ext_typecheck_cond_one_void) << LHS->getSourceRange(); - ImpCastExprToType(LHS, Context.VoidTy, CastExpr::CK_ToVoid); - ImpCastExprToType(RHS, Context.VoidTy, CastExpr::CK_ToVoid); + ImpCastExprToType(LHS, Context.VoidTy, CK_ToVoid); + ImpCastExprToType(RHS, Context.VoidTy, CK_ToVoid); return Context.VoidTy; } // C99 6.5.15p6 - "if one operand is a null pointer constant, the result has @@ -4157,12 +4251,12 @@ QualType Sema::CheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS, if ((LHSTy->isAnyPointerType() || LHSTy->isBlockPointerType()) && RHS->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) { // promote the null to a pointer. - ImpCastExprToType(RHS, LHSTy, CastExpr::CK_Unknown); + ImpCastExprToType(RHS, LHSTy, CK_Unknown); return LHSTy; } if ((RHSTy->isAnyPointerType() || RHSTy->isBlockPointerType()) && LHS->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) { - ImpCastExprToType(LHS, RHSTy, CastExpr::CK_Unknown); + ImpCastExprToType(LHS, RHSTy, CK_Unknown); return RHSTy; } @@ -4178,8 +4272,8 @@ QualType Sema::CheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS, if (!LHSTy->isBlockPointerType() || !RHSTy->isBlockPointerType()) { if (LHSTy->isVoidPointerType() || RHSTy->isVoidPointerType()) { QualType destType = Context.getPointerType(Context.VoidTy); - ImpCastExprToType(LHS, destType, CastExpr::CK_BitCast); - ImpCastExprToType(RHS, destType, CastExpr::CK_BitCast); + ImpCastExprToType(LHS, destType, CK_BitCast); + ImpCastExprToType(RHS, destType, CK_BitCast); return destType; } Diag(QuestionLoc, diag::err_typecheck_cond_incompatible_operands) @@ -4203,13 +4297,13 @@ QualType Sema::CheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS, // reason, but this is what gcc does, and we do have to pick // to get a consistent AST. QualType incompatTy = Context.getPointerType(Context.VoidTy); - ImpCastExprToType(LHS, incompatTy, CastExpr::CK_BitCast); - ImpCastExprToType(RHS, incompatTy, CastExpr::CK_BitCast); + ImpCastExprToType(LHS, incompatTy, CK_BitCast); + ImpCastExprToType(RHS, incompatTy, CK_BitCast); return incompatTy; } // The block pointer types are compatible. - ImpCastExprToType(LHS, LHSTy, CastExpr::CK_BitCast); - ImpCastExprToType(RHS, LHSTy, CastExpr::CK_BitCast); + ImpCastExprToType(LHS, LHSTy, CK_BitCast); + ImpCastExprToType(RHS, LHSTy, CK_BitCast); return LHSTy; } @@ -4226,9 +4320,9 @@ QualType Sema::CheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS, = Context.getQualifiedType(lhptee, rhptee.getQualifiers()); QualType destType = Context.getPointerType(destPointee); // Add qualifiers if necessary. - ImpCastExprToType(LHS, destType, CastExpr::CK_NoOp); + ImpCastExprToType(LHS, destType, CK_NoOp); // Promote to void*. - ImpCastExprToType(RHS, destType, CastExpr::CK_BitCast); + ImpCastExprToType(RHS, destType, CK_BitCast); return destType; } if (rhptee->isVoidType() && lhptee->isIncompleteOrObjectType()) { @@ -4236,9 +4330,9 @@ QualType Sema::CheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS, = Context.getQualifiedType(rhptee, lhptee.getQualifiers()); QualType destType = Context.getPointerType(destPointee); // Add qualifiers if necessary. - ImpCastExprToType(RHS, destType, CastExpr::CK_NoOp); + ImpCastExprToType(RHS, destType, CK_NoOp); // Promote to void*. - ImpCastExprToType(LHS, destType, CastExpr::CK_BitCast); + ImpCastExprToType(LHS, destType, CK_BitCast); return destType; } @@ -4254,8 +4348,8 @@ QualType Sema::CheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS, // reason, but this is what gcc does, and we do have to pick // to get a consistent AST. QualType incompatTy = Context.getPointerType(Context.VoidTy); - ImpCastExprToType(LHS, incompatTy, CastExpr::CK_BitCast); - ImpCastExprToType(RHS, incompatTy, CastExpr::CK_BitCast); + ImpCastExprToType(LHS, incompatTy, CK_BitCast); + ImpCastExprToType(RHS, incompatTy, CK_BitCast); return incompatTy; } // The pointer types are compatible. @@ -4265,8 +4359,8 @@ QualType Sema::CheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS, // type. // FIXME: Need to calculate the composite type. // FIXME: Need to add qualifiers - ImpCastExprToType(LHS, LHSTy, CastExpr::CK_BitCast); - ImpCastExprToType(RHS, LHSTy, CastExpr::CK_BitCast); + ImpCastExprToType(LHS, LHSTy, CK_BitCast); + ImpCastExprToType(RHS, LHSTy, CK_BitCast); return LHSTy; } @@ -4274,13 +4368,13 @@ QualType Sema::CheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS, if (RHSTy->isPointerType() && LHSTy->isIntegerType()) { Diag(QuestionLoc, diag::warn_typecheck_cond_pointer_integer_mismatch) << LHSTy << RHSTy << LHS->getSourceRange() << RHS->getSourceRange(); - ImpCastExprToType(LHS, RHSTy, CastExpr::CK_IntegralToPointer); + ImpCastExprToType(LHS, RHSTy, CK_IntegralToPointer); return RHSTy; } if (LHSTy->isPointerType() && RHSTy->isIntegerType()) { Diag(QuestionLoc, diag::warn_typecheck_cond_pointer_integer_mismatch) << LHSTy << RHSTy << LHS->getSourceRange() << RHS->getSourceRange(); - ImpCastExprToType(RHS, LHSTy, CastExpr::CK_IntegralToPointer); + ImpCastExprToType(RHS, LHSTy, CK_IntegralToPointer); return LHSTy; } @@ -4302,34 +4396,34 @@ QualType Sema::FindCompositeObjCPointerType(Expr *&LHS, Expr *&RHS, // redefinition type if an attempt is made to access its fields. if (LHSTy->isObjCClassType() && (RHSTy.getDesugaredType() == Context.ObjCClassRedefinitionType)) { - ImpCastExprToType(RHS, LHSTy, CastExpr::CK_BitCast); + ImpCastExprToType(RHS, LHSTy, CK_BitCast); return LHSTy; } if (RHSTy->isObjCClassType() && (LHSTy.getDesugaredType() == Context.ObjCClassRedefinitionType)) { - ImpCastExprToType(LHS, RHSTy, CastExpr::CK_BitCast); + ImpCastExprToType(LHS, RHSTy, CK_BitCast); return RHSTy; } // And the same for struct objc_object* / id if (LHSTy->isObjCIdType() && (RHSTy.getDesugaredType() == Context.ObjCIdRedefinitionType)) { - ImpCastExprToType(RHS, LHSTy, CastExpr::CK_BitCast); + ImpCastExprToType(RHS, LHSTy, CK_BitCast); return LHSTy; } if (RHSTy->isObjCIdType() && (LHSTy.getDesugaredType() == Context.ObjCIdRedefinitionType)) { - ImpCastExprToType(LHS, RHSTy, CastExpr::CK_BitCast); + ImpCastExprToType(LHS, RHSTy, CK_BitCast); return RHSTy; } // And the same for struct objc_selector* / SEL if (Context.isObjCSelType(LHSTy) && (RHSTy.getDesugaredType() == Context.ObjCSelRedefinitionType)) { - ImpCastExprToType(RHS, LHSTy, CastExpr::CK_BitCast); + ImpCastExprToType(RHS, LHSTy, CK_BitCast); return LHSTy; } if (Context.isObjCSelType(RHSTy) && (LHSTy.getDesugaredType() == Context.ObjCSelRedefinitionType)) { - ImpCastExprToType(LHS, RHSTy, CastExpr::CK_BitCast); + ImpCastExprToType(LHS, RHSTy, CK_BitCast); return RHSTy; } // Check constraints for Objective-C object pointers types. @@ -4378,13 +4472,13 @@ QualType Sema::FindCompositeObjCPointerType(Expr *&LHS, Expr *&RHS, << LHSTy << RHSTy << LHS->getSourceRange() << RHS->getSourceRange(); QualType incompatTy = Context.getObjCIdType(); - ImpCastExprToType(LHS, incompatTy, CastExpr::CK_BitCast); - ImpCastExprToType(RHS, incompatTy, CastExpr::CK_BitCast); + ImpCastExprToType(LHS, incompatTy, CK_BitCast); + ImpCastExprToType(RHS, incompatTy, CK_BitCast); return incompatTy; } // The object pointer types are compatible. - ImpCastExprToType(LHS, compositeType, CastExpr::CK_BitCast); - ImpCastExprToType(RHS, compositeType, CastExpr::CK_BitCast); + ImpCastExprToType(LHS, compositeType, CK_BitCast); + ImpCastExprToType(RHS, compositeType, CK_BitCast); return compositeType; } // Check Objective-C object pointer types and 'void *' @@ -4395,9 +4489,9 @@ QualType Sema::FindCompositeObjCPointerType(Expr *&LHS, Expr *&RHS, = Context.getQualifiedType(lhptee, rhptee.getQualifiers()); QualType destType = Context.getPointerType(destPointee); // Add qualifiers if necessary. - ImpCastExprToType(LHS, destType, CastExpr::CK_NoOp); + ImpCastExprToType(LHS, destType, CK_NoOp); // Promote to void*. - ImpCastExprToType(RHS, destType, CastExpr::CK_BitCast); + ImpCastExprToType(RHS, destType, CK_BitCast); return destType; } if (LHSTy->isObjCObjectPointerType() && RHSTy->isVoidPointerType()) { @@ -4407,9 +4501,9 @@ QualType Sema::FindCompositeObjCPointerType(Expr *&LHS, Expr *&RHS, = Context.getQualifiedType(rhptee, lhptee.getQualifiers()); QualType destType = Context.getPointerType(destPointee); // Add qualifiers if necessary. - ImpCastExprToType(RHS, destType, CastExpr::CK_NoOp); + ImpCastExprToType(RHS, destType, CK_NoOp); // Promote to void*. - ImpCastExprToType(LHS, destType, CastExpr::CK_BitCast); + ImpCastExprToType(LHS, destType, CK_BitCast); return destType; } return QualType(); @@ -4417,30 +4511,27 @@ QualType Sema::FindCompositeObjCPointerType(Expr *&LHS, Expr *&RHS, /// ActOnConditionalOp - Parse a ?: operation. Note that 'LHS' may be null /// in the case of a the GNU conditional expr extension. -Action::OwningExprResult Sema::ActOnConditionalOp(SourceLocation QuestionLoc, +ExprResult Sema::ActOnConditionalOp(SourceLocation QuestionLoc, SourceLocation ColonLoc, - ExprArg Cond, ExprArg LHS, - ExprArg RHS) { - Expr *CondExpr = (Expr *) Cond.get(); - Expr *LHSExpr = (Expr *) LHS.get(), *RHSExpr = (Expr *) RHS.get(); - + Expr *CondExpr, Expr *LHSExpr, + Expr *RHSExpr) { // If this is the gnu "x ?: y" extension, analyze the types as though the LHS // was the condition. bool isLHSNull = LHSExpr == 0; - if (isLHSNull) - LHSExpr = CondExpr; + Expr *SAVEExpr = 0; + if (isLHSNull) { + LHSExpr = SAVEExpr = CondExpr; + } QualType result = CheckConditionalOperands(CondExpr, LHSExpr, RHSExpr, QuestionLoc); if (result.isNull()) return ExprError(); - Cond.release(); - LHS.release(); - RHS.release(); return Owned(new (Context) ConditionalOperator(CondExpr, QuestionLoc, - isLHSNull ? 0 : LHSExpr, - ColonLoc, RHSExpr, result)); + LHSExpr, ColonLoc, + RHSExpr, SAVEExpr, + result)); } // CheckPointerTypesForAssignment - This is a very tricky routine (despite @@ -4506,12 +4597,12 @@ Sema::CheckPointerTypesForAssignment(QualType lhsType, QualType rhsType) { // "unsigned char" on systems where "char" is unsigned. if (lhptee->isCharType()) lhptee = Context.UnsignedCharTy; - else if (lhptee->isSignedIntegerType()) + else if (lhptee->hasSignedIntegerRepresentation()) lhptee = Context.getCorrespondingUnsignedType(lhptee); if (rhptee->isCharType()) rhptee = Context.UnsignedCharTy; - else if (rhptee->isSignedIntegerType()) + else if (rhptee->hasSignedIntegerRepresentation()) rhptee = Context.getCorrespondingUnsignedType(rhptee); if (lhptee == rhptee) { @@ -4668,13 +4759,18 @@ Sema::CheckAssignmentConstraints(QualType lhsType, QualType rhsType) { } if (lhsType->isVectorType() || rhsType->isVectorType()) { - // If we are allowing lax vector conversions, and LHS and RHS are both - // vectors, the total size only needs to be the same. This is a bitcast; - // no bits are changed but the result type is different. - if (getLangOptions().LaxVectorConversions && - lhsType->isVectorType() && rhsType->isVectorType()) { - if (Context.getTypeSize(lhsType) == Context.getTypeSize(rhsType)) + if (lhsType->isVectorType() && rhsType->isVectorType()) { + // If we are allowing lax vector conversions, and LHS and RHS are both + // vectors, the total size only needs to be the same. This is a bitcast; + // no bits are changed but the result type is different. + if (getLangOptions().LaxVectorConversions && + (Context.getTypeSize(lhsType) == Context.getTypeSize(rhsType))) return IncompatibleVectors; + + // Allow assignments of an AltiVec vector type to an equivalent GCC + // vector type and vice versa + if (Context.areCompatibleVectorTypes(lhsType, rhsType)) + return Compatible; } return Incompatible; } @@ -4832,14 +4928,14 @@ Sema::CheckTransparentUnionArgumentConstraints(QualType ArgType, Expr *&rExpr) { // 2) null pointer constant if (FromType->isPointerType()) if (FromType->getAs<PointerType>()->getPointeeType()->isVoidType()) { - ImpCastExprToType(rExpr, it->getType(), CastExpr::CK_BitCast); + ImpCastExprToType(rExpr, it->getType(), CK_BitCast); InitField = *it; break; } if (rExpr->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) { - ImpCastExprToType(rExpr, it->getType(), CastExpr::CK_IntegralToPointer); + ImpCastExprToType(rExpr, it->getType(), CK_IntegralToPointer); InitField = *it; break; } @@ -4883,14 +4979,14 @@ Sema::CheckSingleAssignmentConstraints(QualType lhsType, Expr *&rExpr) { lhsType->isBlockPointerType()) && rExpr->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) { - ImpCastExprToType(rExpr, lhsType, CastExpr::CK_Unknown); + ImpCastExprToType(rExpr, lhsType, CK_Unknown); return Compatible; } // This check seems unnatural, however it is necessary to ensure the proper // conversion of functions/arrays. If the conversion were done for all // DeclExpr's (created by ActOnIdExpression), it would mess up the unary - // expressions that surpress this implicit conversion (&, sizeof). + // expressions that suppress this implicit conversion (&, sizeof). // // Suppress this for references: C++ 8.5.3p5. if (!lhsType->isReferenceType()) @@ -4907,7 +5003,7 @@ Sema::CheckSingleAssignmentConstraints(QualType lhsType, Expr *&rExpr) { // does not have reference type. if (result != Incompatible && rExpr->getType() != lhsType) ImpCastExprToType(rExpr, lhsType.getNonLValueExprType(Context), - CastExpr::CK_Unknown); + CK_Unknown); return result; } @@ -4933,22 +5029,35 @@ QualType Sema::CheckVectorOperands(SourceLocation Loc, Expr *&lex, Expr *&rex) { // Handle the case of a vector & extvector type of the same size and element // type. It would be nice if we only had one vector type someday. if (getLangOptions().LaxVectorConversions) { - // FIXME: Should we warn here? if (const VectorType *LV = lhsType->getAs<VectorType>()) { - if (const VectorType *RV = rhsType->getAs<VectorType>()) + if (const VectorType *RV = rhsType->getAs<VectorType>()) { if (LV->getElementType() == RV->getElementType() && LV->getNumElements() == RV->getNumElements()) { if (lhsType->isExtVectorType()) { - ImpCastExprToType(rex, lhsType, CastExpr::CK_BitCast); + ImpCastExprToType(rex, lhsType, CK_BitCast); return lhsType; } - ImpCastExprToType(lex, rhsType, CastExpr::CK_BitCast); + ImpCastExprToType(lex, rhsType, CK_BitCast); return rhsType; + } else if (Context.getTypeSize(lhsType) ==Context.getTypeSize(rhsType)){ + // If we are allowing lax vector conversions, and LHS and RHS are both + // vectors, the total size only needs to be the same. This is a + // bitcast; no bits are changed but the result type is different. + ImpCastExprToType(rex, lhsType, CK_BitCast); + return lhsType; } + } } } + // Handle the case of equivalent AltiVec and GCC vector types + if (lhsType->isVectorType() && rhsType->isVectorType() && + Context.areCompatibleVectorTypes(lhsType, rhsType)) { + ImpCastExprToType(lex, rhsType, CK_BitCast); + return rhsType; + } + // Canonicalize the ExtVector to the LHS, remember if we swapped so we can // swap back (so that we don't reverse the inputs to a subtract, for instance. bool swapped = false; @@ -4963,7 +5072,7 @@ QualType Sema::CheckVectorOperands(SourceLocation Loc, Expr *&lex, Expr *&rex) { QualType EltTy = LV->getElementType(); if (EltTy->isIntegralType(Context) && rhsType->isIntegralType(Context)) { if (Context.getIntegerTypeOrder(EltTy, rhsType) >= 0) { - ImpCastExprToType(rex, lhsType, CastExpr::CK_IntegralCast); + ImpCastExprToType(rex, lhsType, CK_IntegralCast); if (swapped) std::swap(rex, lex); return lhsType; } @@ -4971,7 +5080,7 @@ QualType Sema::CheckVectorOperands(SourceLocation Loc, Expr *&lex, Expr *&rex) { if (EltTy->isRealFloatingType() && rhsType->isScalarType() && rhsType->isRealFloatingType()) { if (Context.getFloatingTypeOrder(EltTy, rhsType) >= 0) { - ImpCastExprToType(rex, lhsType, CastExpr::CK_FloatingCast); + ImpCastExprToType(rex, lhsType, CK_FloatingCast); if (swapped) std::swap(rex, lex); return lhsType; } @@ -5008,7 +5117,8 @@ QualType Sema::CheckMultiplyDivideOperands( QualType Sema::CheckRemainderOperands( Expr *&lex, Expr *&rex, SourceLocation Loc, bool isCompAssign) { if (lex->getType()->isVectorType() || rex->getType()->isVectorType()) { - if (lex->getType()->isIntegerType() && rex->getType()->isIntegerType()) + if (lex->getType()->hasIntegerRepresentation() && + rex->getType()->hasIntegerRepresentation()) return CheckVectorOperands(Loc, lex, rex); return InvalidOperands(Loc, lex, rex); } @@ -5253,7 +5363,8 @@ QualType Sema::CheckSubtractionOperands(Expr *&lex, Expr *&rex, QualType Sema::CheckShiftOperands(Expr *&lex, Expr *&rex, SourceLocation Loc, bool isCompAssign) { // C99 6.5.7p2: Each of the operands shall have integer type. - if (!lex->getType()->isIntegerType() || !rex->getType()->isIntegerType()) + if (!lex->getType()->hasIntegerRepresentation() || + !rex->getType()->hasIntegerRepresentation()) return InvalidOperands(Loc, lex, rex); // Vector shifts promote their scalar inputs to vector type. @@ -5269,7 +5380,7 @@ QualType Sema::CheckShiftOperands(Expr *&lex, Expr *&rex, SourceLocation Loc, LHSTy = Context.getPromotedIntegerType(LHSTy); } if (!isCompAssign) - ImpCastExprToType(lex, LHSTy, CastExpr::CK_IntegralCast); + ImpCastExprToType(lex, LHSTy, CK_IntegralCast); UsualUnaryConversions(rex); @@ -5305,7 +5416,7 @@ static bool IsWithinTemplateSpecialization(Decl *D) { // C99 6.5.8, C++ [expr.rel] QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc, unsigned OpaqueOpc, bool isRelational) { - BinaryOperator::Opcode Opc = (BinaryOperator::Opcode)OpaqueOpc; + BinaryOperatorKind Opc = (BinaryOperatorKind) OpaqueOpc; // Handle vector comparisons separately. if (lex->getType()->isVectorType() || rex->getType()->isVectorType()) @@ -5334,19 +5445,19 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc, !IsWithinTemplateSpecialization(DRL->getDecl())) { DiagRuntimeBehavior(Loc, PDiag(diag::warn_comparison_always) << 0 // self- - << (Opc == BinaryOperator::EQ - || Opc == BinaryOperator::LE - || Opc == BinaryOperator::GE)); + << (Opc == BO_EQ + || Opc == BO_LE + || Opc == BO_GE)); } else if (lType->isArrayType() && rType->isArrayType() && !DRL->getDecl()->getType()->isReferenceType() && !DRR->getDecl()->getType()->isReferenceType()) { // what is it always going to eval to? char always_evals_to; switch(Opc) { - case BinaryOperator::EQ: // e.g. array1 == array2 + case BO_EQ: // e.g. array1 == array2 always_evals_to = 0; // false break; - case BinaryOperator::NE: // e.g. array1 != array2 + case BO_NE: // e.g. array1 != array2 always_evals_to = 1; // true break; default: @@ -5386,12 +5497,12 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc, if (literalString) { std::string resultComparison; switch (Opc) { - case BinaryOperator::LT: resultComparison = ") < 0"; break; - case BinaryOperator::GT: resultComparison = ") > 0"; break; - case BinaryOperator::LE: resultComparison = ") <= 0"; break; - case BinaryOperator::GE: resultComparison = ") >= 0"; break; - case BinaryOperator::EQ: resultComparison = ") == 0"; break; - case BinaryOperator::NE: resultComparison = ") != 0"; break; + case BO_LT: resultComparison = ") < 0"; break; + case BO_GT: resultComparison = ") > 0"; break; + case BO_LE: resultComparison = ") <= 0"; break; + case BO_GE: resultComparison = ") >= 0"; break; + case BO_EQ: resultComparison = ") == 0"; break; + case BO_NE: resultComparison = ") != 0"; break; default: assert(false && "Invalid comparison operator"); } @@ -5461,7 +5572,7 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc, if (isSFINAEContext()) return QualType(); - ImpCastExprToType(rex, lType, CastExpr::CK_BitCast); + ImpCastExprToType(rex, lType, CK_BitCast); return ResultTy; } } @@ -5487,8 +5598,8 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc, << lex->getSourceRange() << rex->getSourceRange(); } - ImpCastExprToType(lex, T, CastExpr::CK_BitCast); - ImpCastExprToType(rex, T, CastExpr::CK_BitCast); + ImpCastExprToType(lex, T, CK_BitCast); + ImpCastExprToType(rex, T, CK_BitCast); return ResultTy; } // C99 6.5.9p2 and C99 6.5.8p2 @@ -5513,7 +5624,7 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc, << lType << rType << lex->getSourceRange() << rex->getSourceRange(); } if (LCanPointeeTy != RCanPointeeTy) - ImpCastExprToType(rex, lType, CastExpr::CK_BitCast); + ImpCastExprToType(rex, lType, CK_BitCast); return ResultTy; } @@ -5523,13 +5634,19 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc, if (RHSIsNull && (lType->isPointerType() || (!isRelational && lType->isMemberPointerType()))) { - ImpCastExprToType(rex, lType, CastExpr::CK_NullToMemberPointer); + ImpCastExprToType(rex, lType, + lType->isMemberPointerType() + ? CK_NullToMemberPointer + : CK_IntegralToPointer); return ResultTy; } if (LHSIsNull && (rType->isPointerType() || (!isRelational && rType->isMemberPointerType()))) { - ImpCastExprToType(lex, rType, CastExpr::CK_NullToMemberPointer); + ImpCastExprToType(lex, rType, + rType->isMemberPointerType() + ? CK_NullToMemberPointer + : CK_IntegralToPointer); return ResultTy; } @@ -5560,8 +5677,8 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc, << lex->getSourceRange() << rex->getSourceRange(); } - ImpCastExprToType(lex, T, CastExpr::CK_BitCast); - ImpCastExprToType(rex, T, CastExpr::CK_BitCast); + ImpCastExprToType(lex, T, CK_BitCast); + ImpCastExprToType(rex, T, CK_BitCast); return ResultTy; } @@ -5580,7 +5697,7 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc, Diag(Loc, diag::err_typecheck_comparison_of_distinct_blocks) << lType << rType << lex->getSourceRange() << rex->getSourceRange(); } - ImpCastExprToType(rex, lType, CastExpr::CK_BitCast); + ImpCastExprToType(rex, lType, CK_BitCast); return ResultTy; } // Allow block pointers to be compared with null pointer constants. @@ -5595,7 +5712,7 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc, Diag(Loc, diag::err_typecheck_comparison_of_distinct_blocks) << lType << rType << lex->getSourceRange() << rex->getSourceRange(); } - ImpCastExprToType(rex, lType, CastExpr::CK_BitCast); + ImpCastExprToType(rex, lType, CK_BitCast); return ResultTy; } @@ -5613,14 +5730,14 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc, Diag(Loc, diag::ext_typecheck_comparison_of_distinct_pointers) << lType << rType << lex->getSourceRange() << rex->getSourceRange(); } - ImpCastExprToType(rex, lType, CastExpr::CK_BitCast); + ImpCastExprToType(rex, lType, CK_BitCast); return ResultTy; } if (lType->isObjCObjectPointerType() && rType->isObjCObjectPointerType()) { if (!Context.areComparableObjCPointerTypes(lType, rType)) Diag(Loc, diag::ext_typecheck_comparison_of_distinct_pointers) << lType << rType << lex->getSourceRange() << rex->getSourceRange(); - ImpCastExprToType(rex, lType, CastExpr::CK_BitCast); + ImpCastExprToType(rex, lType, CK_BitCast); return ResultTy; } } @@ -5648,21 +5765,21 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc, } if (lType->isIntegerType()) - ImpCastExprToType(lex, rType, CastExpr::CK_IntegralToPointer); + ImpCastExprToType(lex, rType, CK_IntegralToPointer); else - ImpCastExprToType(rex, lType, CastExpr::CK_IntegralToPointer); + ImpCastExprToType(rex, lType, CK_IntegralToPointer); return ResultTy; } // Handle block pointers. if (!isRelational && RHSIsNull && lType->isBlockPointerType() && rType->isIntegerType()) { - ImpCastExprToType(rex, lType, CastExpr::CK_IntegralToPointer); + ImpCastExprToType(rex, lType, CK_IntegralToPointer); return ResultTy; } if (!isRelational && LHSIsNull && lType->isIntegerType() && rType->isBlockPointerType()) { - ImpCastExprToType(lex, rType, CastExpr::CK_IntegralToPointer); + ImpCastExprToType(lex, rType, CK_IntegralToPointer); return ResultTy; } return InvalidOperands(Loc, lex, rex); @@ -5707,7 +5824,7 @@ QualType Sema::CheckVectorCompareOperands(Expr *&lex, Expr *&rex, // Return the type for the comparison, which is the same as vector type for // integer vectors, or an integer type of identical size and number of // elements for floating point vectors. - if (lType->isIntegerType()) + if (lType->hasIntegerRepresentation()) return lType; const VectorType *VTy = lType->getAs<VectorType>(); @@ -5724,8 +5841,13 @@ QualType Sema::CheckVectorCompareOperands(Expr *&lex, Expr *&rex, inline QualType Sema::CheckBitwiseOperands( Expr *&lex, Expr *&rex, SourceLocation Loc, bool isCompAssign) { - if (lex->getType()->isVectorType() || rex->getType()->isVectorType()) - return CheckVectorOperands(Loc, lex, rex); + if (lex->getType()->isVectorType() || rex->getType()->isVectorType()) { + if (lex->getType()->hasIntegerRepresentation() && + rex->getType()->hasIntegerRepresentation()) + return CheckVectorOperands(Loc, lex, rex); + + return InvalidOperands(Loc, lex, rex); + } QualType compType = UsualArithmeticConversions(lex, rex, isCompAssign); @@ -5741,18 +5863,21 @@ inline QualType Sema::CheckLogicalOperands( // C99 6.5.[13,14] // bitwise one. We do this when the LHS is a non-bool integer and the RHS // is a constant. if (lex->getType()->isIntegerType() && !lex->getType()->isBooleanType() && - rex->getType()->isIntegerType() && rex->isEvaluatable(Context) && - // Don't warn if the RHS is a (constant folded) boolean expression like - // "sizeof(int) == 4". - !rex->isKnownToHaveBooleanValue() && + rex->getType()->isIntegerType() && !rex->isValueDependent() && // Don't warn in macros. - !Loc.isMacroID()) - Diag(Loc, diag::warn_logical_instead_of_bitwise) - << rex->getSourceRange() - << (Opc == BinaryOperator::LAnd ? "&&" : "||") - << (Opc == BinaryOperator::LAnd ? "&" : "|"); - - + !Loc.isMacroID()) { + // If the RHS can be constant folded, and if it constant folds to something + // that isn't 0 or 1 (which indicate a potential logical operation that + // happened to fold to true/false) then warn. + Expr::EvalResult Result; + if (rex->Evaluate(Result, Context) && !Result.HasSideEffects && + Result.Val.getInt() != 0 && Result.Val.getInt() != 1) { + Diag(Loc, diag::warn_logical_instead_of_bitwise) + << rex->getSourceRange() + << (Opc == BO_LAnd ? "&&" : "||") + << (Opc == BO_LAnd ? "&" : "|"); + } + } if (!Context.getLangOptions().CPlusPlus) { UsualUnaryConversions(lex); @@ -5907,8 +6032,8 @@ QualType Sema::CheckAssignmentOperands(Expr *LHS, Expr *&RHS, if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(RHSCheck)) RHSCheck = ICE->getSubExpr(); if (UnaryOperator *UO = dyn_cast<UnaryOperator>(RHSCheck)) { - if ((UO->getOpcode() == UnaryOperator::Plus || - UO->getOpcode() == UnaryOperator::Minus) && + if ((UO->getOpcode() == UO_Plus || + UO->getOpcode() == UO_Minus) && Loc.isFileID() && UO->getOperatorLoc().isFileID() && // Only if the two operators are exactly adjacent. Loc.getFileLocWithOffset(1) == UO->getOperatorLoc() && @@ -5917,7 +6042,7 @@ QualType Sema::CheckAssignmentOperands(Expr *LHS, Expr *&RHS, Loc.getFileLocWithOffset(2) != UO->getSubExpr()->getLocStart() && UO->getSubExpr()->getLocStart().isFileID()) { Diag(Loc, diag::warn_not_compound_assign) - << (UO->getOpcode() == UnaryOperator::Plus ? "+" : "-") + << (UO->getOpcode() == UO_Plus ? "+" : "-") << SourceRange(UO->getOperatorLoc(), UO->getOperatorLoc()); } } @@ -5938,7 +6063,7 @@ QualType Sema::CheckAssignmentOperands(Expr *LHS, Expr *&RHS, // only handles the pattern "*null = whatever", which is a very syntactic // check. if (UnaryOperator *UO = dyn_cast<UnaryOperator>(LHS->IgnoreParenCasts())) - if (UO->getOpcode() == UnaryOperator::Deref && + if (UO->getOpcode() == UO_Deref && UO->getSubExpr()->IgnoreParenCasts()-> isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNotNull) && !UO->getType().isVolatileQualified()) { @@ -6083,9 +6208,9 @@ static NamedDecl *getPrimaryDecl(Expr *E) { UnaryOperator *UO = cast<UnaryOperator>(E); switch(UO->getOpcode()) { - case UnaryOperator::Real: - case UnaryOperator::Imag: - case UnaryOperator::Extension: + case UO_Real: + case UO_Imag: + case UO_Extension: return getPrimaryDecl(UO->getSubExpr()); default: return 0; @@ -6109,17 +6234,19 @@ static NamedDecl *getPrimaryDecl(Expr *E) { /// operator (C99 6.3.2.1p[2-4]), and its result is never an lvalue. /// In C++, the operand might be an overloaded function name, in which case /// we allow the '&' but retain the overloaded-function type. -QualType Sema::CheckAddressOfOperand(Expr *op, SourceLocation OpLoc) { - // Make sure to ignore parentheses in subsequent checks - op = op->IgnoreParens(); - - if (op->isTypeDependent()) +QualType Sema::CheckAddressOfOperand(Expr *OrigOp, SourceLocation OpLoc) { + if (OrigOp->isTypeDependent()) return Context.DependentTy; + if (OrigOp->getType() == Context.OverloadTy) + return Context.OverloadTy; + + // Make sure to ignore parentheses in subsequent checks + Expr *op = OrigOp->IgnoreParens(); if (getLangOptions().C99) { // Implement C99-only parts of addressof rules. if (UnaryOperator* uOp = dyn_cast<UnaryOperator>(op)) { - if (uOp->getOpcode() == UnaryOperator::Deref) + if (uOp->getOpcode() == UO_Deref) // Per C99 6.5.3.2, the address of a deref always returns a valid result // (assuming the deref expression is valid). return uOp->getSubExpr()->getType(); @@ -6130,32 +6257,41 @@ QualType Sema::CheckAddressOfOperand(Expr *op, SourceLocation OpLoc) { NamedDecl *dcl = getPrimaryDecl(op); Expr::isLvalueResult lval = op->isLvalue(Context); - MemberExpr *ME = dyn_cast<MemberExpr>(op); - if (lval == Expr::LV_MemberFunction && ME && - isa<CXXMethodDecl>(ME->getMemberDecl())) { - ValueDecl *dcl = cast<MemberExpr>(op)->getMemberDecl(); - // &f where f is a member of the current object, or &o.f, or &p->f - // All these are not allowed, and we need to catch them before the dcl - // branch of the if, below. - Diag(OpLoc, diag::err_unqualified_pointer_member_function) - << dcl; - // FIXME: Improve this diagnostic and provide a fixit. - - // Now recover by acting as if the function had been accessed qualified. - return Context.getMemberPointerType(op->getType(), - Context.getTypeDeclType(cast<RecordDecl>(dcl->getDeclContext())) - .getTypePtr()); - } - if (lval == Expr::LV_ClassTemporary) { Diag(OpLoc, isSFINAEContext()? diag::err_typecheck_addrof_class_temporary : diag::ext_typecheck_addrof_class_temporary) << op->getType() << op->getSourceRange(); if (isSFINAEContext()) return QualType(); - } else if (isa<ObjCSelectorExpr>(op)) + } else if (isa<ObjCSelectorExpr>(op)) { return Context.getPointerType(op->getType()); - else if (lval != Expr::LV_Valid && lval != Expr::LV_IncompleteVoidType) { + } else if (lval == Expr::LV_MemberFunction) { + // If it's an instance method, make a member pointer. + // The expression must have exactly the form &A::foo. + + // If the underlying expression isn't a decl ref, give up. + if (!isa<DeclRefExpr>(op)) { + Diag(OpLoc, diag::err_invalid_form_pointer_member_function) + << OrigOp->getSourceRange(); + return QualType(); + } + DeclRefExpr *DRE = cast<DeclRefExpr>(op); + CXXMethodDecl *MD = cast<CXXMethodDecl>(DRE->getDecl()); + + // The id-expression was parenthesized. + if (OrigOp != DRE) { + Diag(OpLoc, diag::err_parens_pointer_member_function) + << OrigOp->getSourceRange(); + + // The method was named without a qualifier. + } else if (!DRE->getQualifier()) { + Diag(OpLoc, diag::err_unqualified_pointer_member_function) + << op->getSourceRange(); + } + + return Context.getMemberPointerType(op->getType(), + Context.getTypeDeclType(MD->getParent()).getTypePtr()); + } else if (lval != Expr::LV_Valid && lval != Expr::LV_IncompleteVoidType) { // C99 6.5.3.2p1 // The operand must be either an l-value or a function designator if (!op->getType()->isFunctionType()) { @@ -6183,13 +6319,14 @@ QualType Sema::CheckAddressOfOperand(Expr *op, SourceLocation OpLoc) { // FIXME: Can LHS ever be null here? if (!CheckAddressOfOperand(CO->getTrueExpr(), OpLoc).isNull()) return CheckAddressOfOperand(CO->getFalseExpr(), OpLoc); - } else if (isa<UnresolvedLookupExpr>(op)) { - return Context.OverloadTy; } else if (dcl) { // C99 6.5.3.2p1 // We have an lvalue with a decl. Make sure the decl is not declared // with the register storage-class specifier. if (const VarDecl *vd = dyn_cast<VarDecl>(dcl)) { - if (vd->getStorageClass() == VarDecl::Register) { + // in C++ it is not error to take address of a register + // variable (c++03 7.1.1P3) + if (vd->getStorageClass() == SC_Register && + !getLangOptions().CPlusPlus) { Diag(OpLoc, diag::err_typecheck_address_of) << "register variable" << op->getSourceRange(); return QualType(); @@ -6214,13 +6351,6 @@ QualType Sema::CheckAddressOfOperand(Expr *op, SourceLocation OpLoc) { Context.getTypeDeclType(cast<RecordDecl>(Ctx)).getTypePtr()); } } - } else if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(dcl)) { - // Okay: we can take the address of a function. - // As above. - if (isa<DeclRefExpr>(op) && cast<DeclRefExpr>(op)->getQualifier() && - MD->isInstance()) - return Context.getMemberPointerType(op->getType(), - Context.getTypeDeclType(MD->getParent()).getTypePtr()); } else if (!isa<FunctionDecl>(dcl)) assert(0 && "Unknown/unexpected decl type"); } @@ -6233,6 +6363,8 @@ QualType Sema::CheckAddressOfOperand(Expr *op, SourceLocation OpLoc) { } // If the operand has type "type", the result has type "pointer to type". + if (op->getType()->isObjCObjectType()) + return Context.getObjCObjectPointerType(op->getType()); return Context.getPointerType(op->getType()); } @@ -6264,63 +6396,63 @@ QualType Sema::CheckIndirectionOperand(Expr *Op, SourceLocation OpLoc) { return Result; } -static inline BinaryOperator::Opcode ConvertTokenKindToBinaryOpcode( +static inline BinaryOperatorKind ConvertTokenKindToBinaryOpcode( tok::TokenKind Kind) { - BinaryOperator::Opcode Opc; + BinaryOperatorKind Opc; switch (Kind) { default: assert(0 && "Unknown binop!"); - case tok::periodstar: Opc = BinaryOperator::PtrMemD; break; - case tok::arrowstar: Opc = BinaryOperator::PtrMemI; break; - case tok::star: Opc = BinaryOperator::Mul; break; - case tok::slash: Opc = BinaryOperator::Div; break; - case tok::percent: Opc = BinaryOperator::Rem; break; - case tok::plus: Opc = BinaryOperator::Add; break; - case tok::minus: Opc = BinaryOperator::Sub; break; - case tok::lessless: Opc = BinaryOperator::Shl; break; - case tok::greatergreater: Opc = BinaryOperator::Shr; break; - case tok::lessequal: Opc = BinaryOperator::LE; break; - case tok::less: Opc = BinaryOperator::LT; break; - case tok::greaterequal: Opc = BinaryOperator::GE; break; - case tok::greater: Opc = BinaryOperator::GT; break; - case tok::exclaimequal: Opc = BinaryOperator::NE; break; - case tok::equalequal: Opc = BinaryOperator::EQ; break; - case tok::amp: Opc = BinaryOperator::And; break; - case tok::caret: Opc = BinaryOperator::Xor; break; - case tok::pipe: Opc = BinaryOperator::Or; break; - case tok::ampamp: Opc = BinaryOperator::LAnd; break; - case tok::pipepipe: Opc = BinaryOperator::LOr; break; - case tok::equal: Opc = BinaryOperator::Assign; break; - case tok::starequal: Opc = BinaryOperator::MulAssign; break; - case tok::slashequal: Opc = BinaryOperator::DivAssign; break; - case tok::percentequal: Opc = BinaryOperator::RemAssign; break; - case tok::plusequal: Opc = BinaryOperator::AddAssign; break; - case tok::minusequal: Opc = BinaryOperator::SubAssign; break; - case tok::lesslessequal: Opc = BinaryOperator::ShlAssign; break; - case tok::greatergreaterequal: Opc = BinaryOperator::ShrAssign; break; - case tok::ampequal: Opc = BinaryOperator::AndAssign; break; - case tok::caretequal: Opc = BinaryOperator::XorAssign; break; - case tok::pipeequal: Opc = BinaryOperator::OrAssign; break; - case tok::comma: Opc = BinaryOperator::Comma; break; + case tok::periodstar: Opc = BO_PtrMemD; break; + case tok::arrowstar: Opc = BO_PtrMemI; break; + case tok::star: Opc = BO_Mul; break; + case tok::slash: Opc = BO_Div; break; + case tok::percent: Opc = BO_Rem; break; + case tok::plus: Opc = BO_Add; break; + case tok::minus: Opc = BO_Sub; break; + case tok::lessless: Opc = BO_Shl; break; + case tok::greatergreater: Opc = BO_Shr; break; + case tok::lessequal: Opc = BO_LE; break; + case tok::less: Opc = BO_LT; break; + case tok::greaterequal: Opc = BO_GE; break; + case tok::greater: Opc = BO_GT; break; + case tok::exclaimequal: Opc = BO_NE; break; + case tok::equalequal: Opc = BO_EQ; break; + case tok::amp: Opc = BO_And; break; + case tok::caret: Opc = BO_Xor; break; + case tok::pipe: Opc = BO_Or; break; + case tok::ampamp: Opc = BO_LAnd; break; + case tok::pipepipe: Opc = BO_LOr; break; + case tok::equal: Opc = BO_Assign; break; + case tok::starequal: Opc = BO_MulAssign; break; + case tok::slashequal: Opc = BO_DivAssign; break; + case tok::percentequal: Opc = BO_RemAssign; break; + case tok::plusequal: Opc = BO_AddAssign; break; + case tok::minusequal: Opc = BO_SubAssign; break; + case tok::lesslessequal: Opc = BO_ShlAssign; break; + case tok::greatergreaterequal: Opc = BO_ShrAssign; break; + case tok::ampequal: Opc = BO_AndAssign; break; + case tok::caretequal: Opc = BO_XorAssign; break; + case tok::pipeequal: Opc = BO_OrAssign; break; + case tok::comma: Opc = BO_Comma; break; } return Opc; } -static inline UnaryOperator::Opcode ConvertTokenKindToUnaryOpcode( +static inline UnaryOperatorKind ConvertTokenKindToUnaryOpcode( tok::TokenKind Kind) { - UnaryOperator::Opcode Opc; + UnaryOperatorKind Opc; switch (Kind) { default: assert(0 && "Unknown unary op!"); - case tok::plusplus: Opc = UnaryOperator::PreInc; break; - case tok::minusminus: Opc = UnaryOperator::PreDec; break; - case tok::amp: Opc = UnaryOperator::AddrOf; break; - case tok::star: Opc = UnaryOperator::Deref; break; - case tok::plus: Opc = UnaryOperator::Plus; break; - case tok::minus: Opc = UnaryOperator::Minus; break; - case tok::tilde: Opc = UnaryOperator::Not; break; - case tok::exclaim: Opc = UnaryOperator::LNot; break; - case tok::kw___real: Opc = UnaryOperator::Real; break; - case tok::kw___imag: Opc = UnaryOperator::Imag; break; - case tok::kw___extension__: Opc = UnaryOperator::Extension; break; + case tok::plusplus: Opc = UO_PreInc; break; + case tok::minusminus: Opc = UO_PreDec; break; + case tok::amp: Opc = UO_AddrOf; break; + case tok::star: Opc = UO_Deref; break; + case tok::plus: Opc = UO_Plus; break; + case tok::minus: Opc = UO_Minus; break; + case tok::tilde: Opc = UO_Not; break; + case tok::exclaim: Opc = UO_LNot; break; + case tok::kw___real: Opc = UO_Real; break; + case tok::kw___imag: Opc = UO_Imag; break; + case tok::kw___extension__: Opc = UO_Extension; break; } return Opc; } @@ -6328,106 +6460,111 @@ static inline UnaryOperator::Opcode ConvertTokenKindToUnaryOpcode( /// CreateBuiltinBinOp - Creates a new built-in binary operation with /// operator @p Opc at location @c TokLoc. This routine only supports /// built-in operations; ActOnBinOp handles overloaded operators. -Action::OwningExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc, - unsigned Op, - Expr *lhs, Expr *rhs) { +ExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc, + unsigned Op, + Expr *lhs, Expr *rhs) { QualType ResultTy; // Result type of the binary operator. - BinaryOperator::Opcode Opc = (BinaryOperator::Opcode)Op; + BinaryOperatorKind Opc = (BinaryOperatorKind) Op; // The following two variables are used for compound assignment operators QualType CompLHSTy; // Type of LHS after promotions for computation QualType CompResultTy; // Type of computation result switch (Opc) { - case BinaryOperator::Assign: + case BO_Assign: ResultTy = CheckAssignmentOperands(lhs, rhs, OpLoc, QualType()); break; - case BinaryOperator::PtrMemD: - case BinaryOperator::PtrMemI: + case BO_PtrMemD: + case BO_PtrMemI: ResultTy = CheckPointerToMemberOperands(lhs, rhs, OpLoc, - Opc == BinaryOperator::PtrMemI); + Opc == BO_PtrMemI); break; - case BinaryOperator::Mul: - case BinaryOperator::Div: + case BO_Mul: + case BO_Div: ResultTy = CheckMultiplyDivideOperands(lhs, rhs, OpLoc, false, - Opc == BinaryOperator::Div); + Opc == BO_Div); break; - case BinaryOperator::Rem: + case BO_Rem: ResultTy = CheckRemainderOperands(lhs, rhs, OpLoc); break; - case BinaryOperator::Add: + case BO_Add: ResultTy = CheckAdditionOperands(lhs, rhs, OpLoc); break; - case BinaryOperator::Sub: + case BO_Sub: ResultTy = CheckSubtractionOperands(lhs, rhs, OpLoc); break; - case BinaryOperator::Shl: - case BinaryOperator::Shr: + case BO_Shl: + case BO_Shr: ResultTy = CheckShiftOperands(lhs, rhs, OpLoc); break; - case BinaryOperator::LE: - case BinaryOperator::LT: - case BinaryOperator::GE: - case BinaryOperator::GT: + case BO_LE: + case BO_LT: + case BO_GE: + case BO_GT: ResultTy = CheckCompareOperands(lhs, rhs, OpLoc, Opc, true); break; - case BinaryOperator::EQ: - case BinaryOperator::NE: + case BO_EQ: + case BO_NE: ResultTy = CheckCompareOperands(lhs, rhs, OpLoc, Opc, false); break; - case BinaryOperator::And: - case BinaryOperator::Xor: - case BinaryOperator::Or: + case BO_And: + case BO_Xor: + case BO_Or: ResultTy = CheckBitwiseOperands(lhs, rhs, OpLoc); break; - case BinaryOperator::LAnd: - case BinaryOperator::LOr: + case BO_LAnd: + case BO_LOr: ResultTy = CheckLogicalOperands(lhs, rhs, OpLoc, Opc); break; - case BinaryOperator::MulAssign: - case BinaryOperator::DivAssign: + case BO_MulAssign: + case BO_DivAssign: CompResultTy = CheckMultiplyDivideOperands(lhs, rhs, OpLoc, true, - Opc == BinaryOperator::DivAssign); + Opc == BO_DivAssign); CompLHSTy = CompResultTy; if (!CompResultTy.isNull()) ResultTy = CheckAssignmentOperands(lhs, rhs, OpLoc, CompResultTy); break; - case BinaryOperator::RemAssign: + case BO_RemAssign: CompResultTy = CheckRemainderOperands(lhs, rhs, OpLoc, true); CompLHSTy = CompResultTy; if (!CompResultTy.isNull()) ResultTy = CheckAssignmentOperands(lhs, rhs, OpLoc, CompResultTy); break; - case BinaryOperator::AddAssign: + case BO_AddAssign: CompResultTy = CheckAdditionOperands(lhs, rhs, OpLoc, &CompLHSTy); if (!CompResultTy.isNull()) ResultTy = CheckAssignmentOperands(lhs, rhs, OpLoc, CompResultTy); break; - case BinaryOperator::SubAssign: + case BO_SubAssign: CompResultTy = CheckSubtractionOperands(lhs, rhs, OpLoc, &CompLHSTy); if (!CompResultTy.isNull()) ResultTy = CheckAssignmentOperands(lhs, rhs, OpLoc, CompResultTy); break; - case BinaryOperator::ShlAssign: - case BinaryOperator::ShrAssign: + case BO_ShlAssign: + case BO_ShrAssign: CompResultTy = CheckShiftOperands(lhs, rhs, OpLoc, true); CompLHSTy = CompResultTy; if (!CompResultTy.isNull()) ResultTy = CheckAssignmentOperands(lhs, rhs, OpLoc, CompResultTy); break; - case BinaryOperator::AndAssign: - case BinaryOperator::XorAssign: - case BinaryOperator::OrAssign: + case BO_AndAssign: + case BO_XorAssign: + case BO_OrAssign: CompResultTy = CheckBitwiseOperands(lhs, rhs, OpLoc, true); CompLHSTy = CompResultTy; if (!CompResultTy.isNull()) ResultTy = CheckAssignmentOperands(lhs, rhs, OpLoc, CompResultTy); break; - case BinaryOperator::Comma: + case BO_Comma: ResultTy = CheckCommaOperands(lhs, rhs, OpLoc); break; } if (ResultTy.isNull()) return ExprError(); + if (ResultTy->isObjCObjectType() && LangOpts.ObjCNonFragileABI) { + if (Opc >= BO_Assign && Opc <= BO_OrAssign) + Diag(OpLoc, diag::err_assignment_requires_nonfragile_object) + << ResultTy; + } if (CompResultTy.isNull()) return Owned(new (Context) BinaryOperator(lhs, rhs, Opc, ResultTy, OpLoc)); else @@ -6479,7 +6616,7 @@ static void SuggestParentheses(Sema &Self, SourceLocation Loc, /// operators are mixed in a way that suggests that the programmer forgot that /// comparison operators have higher precedence. The most typical example of /// such code is "flags & 0x0020 != 0", which is equivalent to "flags & 1". -static void DiagnoseBitwisePrecedence(Sema &Self, BinaryOperator::Opcode Opc, +static void DiagnoseBitwisePrecedence(Sema &Self, BinaryOperatorKind Opc, SourceLocation OpLoc,Expr *lhs,Expr *rhs){ typedef BinaryOperator BinOp; BinOp::Opcode lhsopc = static_cast<BinOp::Opcode>(-1), @@ -6526,19 +6663,17 @@ static void DiagnoseBitwisePrecedence(Sema &Self, BinaryOperator::Opcode Opc, /// DiagnoseBinOpPrecedence - Emit warnings for expressions with tricky /// precedence. This currently diagnoses only "arg1 'bitwise' arg2 'eq' arg3". /// But it could also warn about arg1 && arg2 || arg3, as GCC 4.3+ does. -static void DiagnoseBinOpPrecedence(Sema &Self, BinaryOperator::Opcode Opc, +static void DiagnoseBinOpPrecedence(Sema &Self, BinaryOperatorKind Opc, SourceLocation OpLoc, Expr *lhs, Expr *rhs){ if (BinaryOperator::isBitwiseOp(Opc)) DiagnoseBitwisePrecedence(Self, Opc, OpLoc, lhs, rhs); } // Binary Operators. 'Tok' is the token for the operator. -Action::OwningExprResult Sema::ActOnBinOp(Scope *S, SourceLocation TokLoc, - tok::TokenKind Kind, - ExprArg LHS, ExprArg RHS) { - BinaryOperator::Opcode Opc = ConvertTokenKindToBinaryOpcode(Kind); - Expr *lhs = LHS.takeAs<Expr>(), *rhs = RHS.takeAs<Expr>(); - +ExprResult Sema::ActOnBinOp(Scope *S, SourceLocation TokLoc, + tok::TokenKind Kind, + Expr *lhs, Expr *rhs) { + BinaryOperatorKind Opc = ConvertTokenKindToBinaryOpcode(Kind); assert((lhs != 0) && "ActOnBinOp(): missing left expression"); assert((rhs != 0) && "ActOnBinOp(): missing right expression"); @@ -6548,9 +6683,9 @@ Action::OwningExprResult Sema::ActOnBinOp(Scope *S, SourceLocation TokLoc, return BuildBinOp(S, TokLoc, Opc, lhs, rhs); } -Action::OwningExprResult Sema::BuildBinOp(Scope *S, SourceLocation OpLoc, - BinaryOperator::Opcode Opc, - Expr *lhs, Expr *rhs) { +ExprResult Sema::BuildBinOp(Scope *S, SourceLocation OpLoc, + BinaryOperatorKind Opc, + Expr *lhs, Expr *rhs) { if (getLangOptions().CPlusPlus && (lhs->getType()->isOverloadableType() || rhs->getType()->isOverloadableType())) { @@ -6573,38 +6708,32 @@ Action::OwningExprResult Sema::BuildBinOp(Scope *S, SourceLocation OpLoc, return CreateBuiltinBinOp(OpLoc, Opc, lhs, rhs); } -Action::OwningExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc, +ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc, unsigned OpcIn, - ExprArg InputArg) { - UnaryOperator::Opcode Opc = static_cast<UnaryOperator::Opcode>(OpcIn); + Expr *Input) { + UnaryOperatorKind Opc = static_cast<UnaryOperatorKind>(OpcIn); - // FIXME: Input is modified below, but InputArg is not updated appropriately. - Expr *Input = (Expr *)InputArg.get(); QualType resultType; switch (Opc) { - case UnaryOperator::OffsetOf: - assert(false && "Invalid unary operator"); - break; - - case UnaryOperator::PreInc: - case UnaryOperator::PreDec: - case UnaryOperator::PostInc: - case UnaryOperator::PostDec: + case UO_PreInc: + case UO_PreDec: + case UO_PostInc: + case UO_PostDec: resultType = CheckIncrementDecrementOperand(Input, OpLoc, - Opc == UnaryOperator::PreInc || - Opc == UnaryOperator::PostInc, - Opc == UnaryOperator::PreInc || - Opc == UnaryOperator::PreDec); + Opc == UO_PreInc || + Opc == UO_PostInc, + Opc == UO_PreInc || + Opc == UO_PreDec); break; - case UnaryOperator::AddrOf: + case UO_AddrOf: resultType = CheckAddressOfOperand(Input, OpLoc); break; - case UnaryOperator::Deref: + case UO_Deref: DefaultFunctionArrayLvalueConversion(Input); resultType = CheckIndirectionOperand(Input, OpLoc); break; - case UnaryOperator::Plus: - case UnaryOperator::Minus: + case UO_Plus: + case UO_Minus: UsualUnaryConversions(Input); resultType = Input->getType(); if (resultType->isDependentType()) @@ -6616,13 +6745,13 @@ Action::OwningExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc, resultType->isEnumeralType()) break; else if (getLangOptions().CPlusPlus && // C++ [expr.unary.op]p6 - Opc == UnaryOperator::Plus && + Opc == UO_Plus && resultType->isPointerType()) break; return ExprError(Diag(OpLoc, diag::err_typecheck_unary_expr) << resultType << Input->getSourceRange()); - case UnaryOperator::Not: // bitwise complement + case UO_Not: // bitwise complement UsualUnaryConversions(Input); resultType = Input->getType(); if (resultType->isDependentType()) @@ -6632,11 +6761,11 @@ Action::OwningExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc, // C99 does not support '~' for complex conjugation. Diag(OpLoc, diag::ext_integer_complement_complex) << resultType << Input->getSourceRange(); - else if (!resultType->isIntegerType()) + else if (!resultType->hasIntegerRepresentation()) return ExprError(Diag(OpLoc, diag::err_typecheck_unary_expr) << resultType << Input->getSourceRange()); break; - case UnaryOperator::LNot: // logical negation + case UO_LNot: // logical negation // Unlike +/-/~, integer promotions aren't done here (C99 6.5.3.3p5). DefaultFunctionArrayLvalueConversion(Input); resultType = Input->getType(); @@ -6649,27 +6778,25 @@ Action::OwningExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc, // In C++, it's bool. C++ 5.3.1p8 resultType = getLangOptions().CPlusPlus ? Context.BoolTy : Context.IntTy; break; - case UnaryOperator::Real: - case UnaryOperator::Imag: - resultType = CheckRealImagOperand(Input, OpLoc, Opc == UnaryOperator::Real); + case UO_Real: + case UO_Imag: + resultType = CheckRealImagOperand(Input, OpLoc, Opc == UO_Real); break; - case UnaryOperator::Extension: + case UO_Extension: resultType = Input->getType(); break; } if (resultType.isNull()) return ExprError(); - InputArg.release(); return Owned(new (Context) UnaryOperator(Input, Opc, resultType, OpLoc)); } -Action::OwningExprResult Sema::BuildUnaryOp(Scope *S, SourceLocation OpLoc, - UnaryOperator::Opcode Opc, - ExprArg input) { - Expr *Input = (Expr*)input.get(); +ExprResult Sema::BuildUnaryOp(Scope *S, SourceLocation OpLoc, + UnaryOperatorKind Opc, + Expr *Input) { if (getLangOptions().CPlusPlus && Input->getType()->isOverloadableType() && - Opc != UnaryOperator::Extension) { + UnaryOperator::getOverloadedOperator(Opc) != OO_None) { // Find all of the overloaded operators visible from this // point. We perform both an operator-name lookup from the local // scope and an argument-dependent lookup based on the types of @@ -6680,24 +6807,24 @@ Action::OwningExprResult Sema::BuildUnaryOp(Scope *S, SourceLocation OpLoc, LookupOverloadedOperatorName(OverOp, S, Input->getType(), QualType(), Functions); - return CreateOverloadedUnaryOp(OpLoc, Opc, Functions, move(input)); + return CreateOverloadedUnaryOp(OpLoc, Opc, Functions, Input); } - return CreateBuiltinUnaryOp(OpLoc, Opc, move(input)); + return CreateBuiltinUnaryOp(OpLoc, Opc, Input); } // Unary Operators. 'Tok' is the token for the operator. -Action::OwningExprResult Sema::ActOnUnaryOp(Scope *S, SourceLocation OpLoc, - tok::TokenKind Op, ExprArg input) { - return BuildUnaryOp(S, OpLoc, ConvertTokenKindToUnaryOpcode(Op), move(input)); +ExprResult Sema::ActOnUnaryOp(Scope *S, SourceLocation OpLoc, + tok::TokenKind Op, Expr *Input) { + return BuildUnaryOp(S, OpLoc, ConvertTokenKindToUnaryOpcode(Op), Input); } /// ActOnAddrLabel - Parse the GNU address of label extension: "&&foo". -Sema::OwningExprResult Sema::ActOnAddrLabel(SourceLocation OpLoc, +ExprResult Sema::ActOnAddrLabel(SourceLocation OpLoc, SourceLocation LabLoc, IdentifierInfo *LabelII) { // Look up the record for this label identifier. - LabelStmt *&LabelDecl = getLabelMap()[LabelII]; + LabelStmt *&LabelDecl = getCurFunction()->LabelMap[LabelII]; // If we haven't seen this label yet, create a forward reference. It // will be validated and/or cleaned up in ActOnFinishFunctionBody. @@ -6709,10 +6836,9 @@ Sema::OwningExprResult Sema::ActOnAddrLabel(SourceLocation OpLoc, Context.getPointerType(Context.VoidTy))); } -Sema::OwningExprResult -Sema::ActOnStmtExpr(SourceLocation LPLoc, StmtArg substmt, +ExprResult +Sema::ActOnStmtExpr(SourceLocation LPLoc, Stmt *SubStmt, SourceLocation RPLoc) { // "({..})" - Stmt *SubStmt = static_cast<Stmt*>(substmt.get()); assert(SubStmt && isa<CompoundStmt>(SubStmt) && "Invalid action invocation!"); CompoundStmt *Compound = cast<CompoundStmt>(SubStmt); @@ -6742,11 +6868,10 @@ Sema::ActOnStmtExpr(SourceLocation LPLoc, StmtArg substmt, // FIXME: Check that expression type is complete/non-abstract; statement // expressions are not lvalues. - substmt.release(); return Owned(new (Context) StmtExpr(Compound, Ty, LPLoc, RPLoc)); } -Sema::OwningExprResult Sema::BuildBuiltinOffsetOf(SourceLocation BuiltinLoc, +ExprResult Sema::BuildBuiltinOffsetOf(SourceLocation BuiltinLoc, TypeSourceInfo *TInfo, OffsetOfComponent *CompPtr, unsigned NumComponents, @@ -6865,22 +6990,27 @@ Sema::OwningExprResult Sema::BuildBuiltinOffsetOf(SourceLocation BuiltinLoc, Diag(MemberDecl->getLocation(), diag::note_bitfield_decl); return ExprError(); } - + + RecordDecl *Parent = MemberDecl->getParent(); + bool AnonStructUnion = Parent->isAnonymousStructOrUnion(); + if (AnonStructUnion) { + do { + Parent = cast<RecordDecl>(Parent->getParent()); + } while (Parent->isAnonymousStructOrUnion()); + } + // If the member was found in a base class, introduce OffsetOfNodes for // the base class indirections. CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, /*DetectVirtual=*/false); - if (IsDerivedFrom(CurrentType, - Context.getTypeDeclType(MemberDecl->getParent()), - Paths)) { + if (IsDerivedFrom(CurrentType, Context.getTypeDeclType(Parent), Paths)) { CXXBasePath &Path = Paths.front(); for (CXXBasePath::iterator B = Path.begin(), BEnd = Path.end(); B != BEnd; ++B) Comps.push_back(OffsetOfNode(B->Base)); } - - if (cast<RecordDecl>(MemberDecl->getDeclContext())-> - isAnonymousStructOrUnion()) { + + if (AnonStructUnion) { llvm::SmallVector<FieldDecl*, 4> Path; BuildAnonymousStructUnionMemberPath(MemberDecl, Path); unsigned n = Path.size(); @@ -6897,10 +7027,10 @@ Sema::OwningExprResult Sema::BuildBuiltinOffsetOf(SourceLocation BuiltinLoc, Exprs.data(), Exprs.size(), RParenLoc)); } -Sema::OwningExprResult Sema::ActOnBuiltinOffsetOf(Scope *S, +ExprResult Sema::ActOnBuiltinOffsetOf(Scope *S, SourceLocation BuiltinLoc, SourceLocation TypeLoc, - TypeTy *argty, + ParsedType argty, OffsetOfComponent *CompPtr, unsigned NumComponents, SourceLocation RPLoc) { @@ -6910,151 +7040,32 @@ Sema::OwningExprResult Sema::ActOnBuiltinOffsetOf(Scope *S, if (ArgTy.isNull()) return ExprError(); - if (getLangOptions().CPlusPlus) { - if (!ArgTInfo) - ArgTInfo = Context.getTrivialTypeSourceInfo(ArgTy, TypeLoc); - - return BuildBuiltinOffsetOf(BuiltinLoc, ArgTInfo, CompPtr, NumComponents, - RPLoc); - } - - // FIXME: The code below is marked for death, once we have proper CodeGen - // support for non-constant OffsetOf expressions. - - bool Dependent = ArgTy->isDependentType(); - - // We must have at least one component that refers to the type, and the first - // one is known to be a field designator. Verify that the ArgTy represents - // a struct/union/class. - if (!Dependent && !ArgTy->isRecordType()) - return ExprError(Diag(TypeLoc, diag::err_offsetof_record_type) << ArgTy); - - // FIXME: Type must be complete per C99 7.17p3 because a declaring a variable - // with an incomplete type would be illegal. - - // Otherwise, create a null pointer as the base, and iteratively process - // the offsetof designators. - QualType ArgTyPtr = Context.getPointerType(ArgTy); - Expr* Res = new (Context) ImplicitValueInitExpr(ArgTyPtr); - Res = new (Context) UnaryOperator(Res, UnaryOperator::Deref, - ArgTy, SourceLocation()); - - // offsetof with non-identifier designators (e.g. "offsetof(x, a.b[c])") are a - // GCC extension, diagnose them. - // FIXME: This diagnostic isn't actually visible because the location is in - // a system header! - if (NumComponents != 1) - Diag(BuiltinLoc, diag::ext_offsetof_extended_field_designator) - << SourceRange(CompPtr[1].LocStart, CompPtr[NumComponents-1].LocEnd); - - if (!Dependent) { - bool DidWarnAboutNonPOD = false; - - if (RequireCompleteType(TypeLoc, Res->getType(), - diag::err_offsetof_incomplete_type)) - return ExprError(); - - // FIXME: Dependent case loses a lot of information here. And probably - // leaks like a sieve. - for (unsigned i = 0; i != NumComponents; ++i) { - const OffsetOfComponent &OC = CompPtr[i]; - if (OC.isBrackets) { - // Offset of an array sub-field. TODO: Should we allow vector elements? - const ArrayType *AT = Context.getAsArrayType(Res->getType()); - if (!AT) { - Res->Destroy(Context); - return ExprError(Diag(OC.LocEnd, diag::err_offsetof_array_type) - << Res->getType()); - } - - // FIXME: C++: Verify that operator[] isn't overloaded. - - // Promote the array so it looks more like a normal array subscript - // expression. - DefaultFunctionArrayLvalueConversion(Res); - - // C99 6.5.2.1p1 - Expr *Idx = static_cast<Expr*>(OC.U.E); - // FIXME: Leaks Res - if (!Idx->isTypeDependent() && !Idx->getType()->isIntegerType()) - return ExprError(Diag(Idx->getLocStart(), - diag::err_typecheck_subscript_not_integer) - << Idx->getSourceRange()); - - Res = new (Context) ArraySubscriptExpr(Res, Idx, AT->getElementType(), - OC.LocEnd); - continue; - } - - const RecordType *RC = Res->getType()->getAs<RecordType>(); - if (!RC) { - Res->Destroy(Context); - return ExprError(Diag(OC.LocEnd, diag::err_offsetof_record_type) - << Res->getType()); - } - - // Get the decl corresponding to this. - RecordDecl *RD = RC->getDecl(); - if (CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(RD)) { - if (!CRD->isPOD() && !DidWarnAboutNonPOD && - DiagRuntimeBehavior(BuiltinLoc, - PDiag(diag::warn_offsetof_non_pod_type) - << SourceRange(CompPtr[0].LocStart, OC.LocEnd) - << Res->getType())) - DidWarnAboutNonPOD = true; - } - - LookupResult R(*this, OC.U.IdentInfo, OC.LocStart, LookupMemberName); - LookupQualifiedName(R, RD); - - FieldDecl *MemberDecl = R.getAsSingle<FieldDecl>(); - // FIXME: Leaks Res - if (!MemberDecl) - return ExprError(Diag(BuiltinLoc, diag::err_no_member) - << OC.U.IdentInfo << RD << SourceRange(OC.LocStart, OC.LocEnd)); - - // C99 7.17p3: - // (If the specified member is a bit-field, the behavior is undefined.) - // - // We diagnose this as an error. - if (MemberDecl->getBitWidth()) { - Diag(OC.LocEnd, diag::err_offsetof_bitfield) - << MemberDecl->getDeclName() - << SourceRange(BuiltinLoc, RPLoc); - Diag(MemberDecl->getLocation(), diag::note_bitfield_decl); - return ExprError(); - } - - // FIXME: C++: Verify that MemberDecl isn't a static field. - // FIXME: Verify that MemberDecl isn't a bitfield. - if (cast<RecordDecl>(MemberDecl->getDeclContext())->isAnonymousStructOrUnion()) { - Res = BuildAnonymousStructUnionMemberReference( - OC.LocEnd, MemberDecl, Res, OC.LocEnd).takeAs<Expr>(); - } else { - PerformObjectMemberConversion(Res, /*Qualifier=*/0, - *R.begin(), MemberDecl); - // MemberDecl->getType() doesn't get the right qualifiers, but it - // doesn't matter here. - Res = new (Context) MemberExpr(Res, false, MemberDecl, OC.LocEnd, - MemberDecl->getType().getNonReferenceType()); - } - } - } - - return Owned(new (Context) UnaryOperator(Res, UnaryOperator::OffsetOf, - Context.getSizeType(), BuiltinLoc)); + if (!ArgTInfo) + ArgTInfo = Context.getTrivialTypeSourceInfo(ArgTy, TypeLoc); + + return BuildBuiltinOffsetOf(BuiltinLoc, ArgTInfo, CompPtr, NumComponents, + RPLoc); } -Sema::OwningExprResult Sema::ActOnTypesCompatibleExpr(SourceLocation BuiltinLoc, - TypeTy *arg1,TypeTy *arg2, +ExprResult Sema::ActOnTypesCompatibleExpr(SourceLocation BuiltinLoc, + ParsedType arg1,ParsedType arg2, SourceLocation RPLoc) { - // FIXME: Preserve type source info. - QualType argT1 = GetTypeFromParser(arg1); - QualType argT2 = GetTypeFromParser(arg2); + TypeSourceInfo *argTInfo1; + QualType argT1 = GetTypeFromParser(arg1, &argTInfo1); + TypeSourceInfo *argTInfo2; + QualType argT2 = GetTypeFromParser(arg2, &argTInfo2); assert((!argT1.isNull() && !argT2.isNull()) && "Missing type argument(s)"); + return BuildTypesCompatibleExpr(BuiltinLoc, argTInfo1, argTInfo2, RPLoc); +} + +ExprResult +Sema::BuildTypesCompatibleExpr(SourceLocation BuiltinLoc, + TypeSourceInfo *argTInfo1, + TypeSourceInfo *argTInfo2, + SourceLocation RPLoc) { if (getLangOptions().CPlusPlus) { Diag(BuiltinLoc, diag::err_types_compatible_p_in_cplusplus) << SourceRange(BuiltinLoc, RPLoc); @@ -7062,17 +7073,14 @@ Sema::OwningExprResult Sema::ActOnTypesCompatibleExpr(SourceLocation BuiltinLoc, } return Owned(new (Context) TypesCompatibleExpr(Context.IntTy, BuiltinLoc, - argT1, argT2, RPLoc)); + argTInfo1, argTInfo2, RPLoc)); } -Sema::OwningExprResult Sema::ActOnChooseExpr(SourceLocation BuiltinLoc, - ExprArg cond, - ExprArg expr1, ExprArg expr2, - SourceLocation RPLoc) { - Expr *CondExpr = static_cast<Expr*>(cond.get()); - Expr *LHSExpr = static_cast<Expr*>(expr1.get()); - Expr *RHSExpr = static_cast<Expr*>(expr2.get()); +ExprResult Sema::ActOnChooseExpr(SourceLocation BuiltinLoc, + Expr *CondExpr, + Expr *LHSExpr, Expr *RHSExpr, + SourceLocation RPLoc) { assert((CondExpr && LHSExpr && RHSExpr) && "Missing type argument(s)"); QualType resType; @@ -7095,7 +7103,6 @@ Sema::OwningExprResult Sema::ActOnChooseExpr(SourceLocation BuiltinLoc, : RHSExpr->isValueDependent(); } - cond.release(); expr1.release(); expr2.release(); return Owned(new (Context) ChooseExpr(BuiltinLoc, CondExpr, LHSExpr, RHSExpr, resType, RPLoc, resType->isDependentType(), @@ -7232,8 +7239,8 @@ void Sema::ActOnBlockError(SourceLocation CaretLoc, Scope *CurScope) { /// ActOnBlockStmtExpr - This is called when the body of a block statement /// literal was successfully completed. ^(int x){...} -Sema::OwningExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc, - StmtArg body, Scope *CurScope) { +ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc, + Stmt *Body, Scope *CurScope) { // If blocks are disabled, emit an error. if (!LangOpts.Blocks) Diag(CaretLoc, diag::err_blocks_disable); @@ -7295,10 +7302,10 @@ Sema::OwningExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc, BlockTy = Context.getBlockPointerType(BlockTy); // If needed, diagnose invalid gotos and switches in the block. - if (FunctionNeedsScopeChecking() && !hasAnyErrorsInThisFunction()) - DiagnoseInvalidJumps(static_cast<CompoundStmt*>(body.get())); + if (getCurFunction()->NeedsScopeChecking() && !hasAnyErrorsInThisFunction()) + DiagnoseInvalidJumps(cast<CompoundStmt>(Body)); - BSI->TheDecl->setBody(body.takeAs<CompoundStmt>()); + BSI->TheDecl->setBody(cast<CompoundStmt>(Body)); bool Good = true; // Check goto/label use. @@ -7320,22 +7327,29 @@ Sema::OwningExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc, return ExprError(); } + BlockExpr *Result = new (Context) BlockExpr(BSI->TheDecl, BlockTy, + BSI->hasBlockDeclRefExprs); + // Issue any analysis-based warnings. const sema::AnalysisBasedWarnings::Policy &WP = AnalysisWarnings.getDefaultPolicy(); - AnalysisWarnings.IssueWarnings(WP, BSI->TheDecl, BlockTy); + AnalysisWarnings.IssueWarnings(WP, Result); - Expr *Result = new (Context) BlockExpr(BSI->TheDecl, BlockTy, - BSI->hasBlockDeclRefExprs); PopFunctionOrBlockScope(); return Owned(Result); } -Sema::OwningExprResult Sema::ActOnVAArg(SourceLocation BuiltinLoc, - ExprArg expr, TypeTy *type, +ExprResult Sema::ActOnVAArg(SourceLocation BuiltinLoc, + Expr *expr, ParsedType type, SourceLocation RPLoc) { - QualType T = GetTypeFromParser(type); - Expr *E = static_cast<Expr*>(expr.get()); + TypeSourceInfo *TInfo; + QualType T = GetTypeFromParser(type, &TInfo); + return BuildVAArgExpr(BuiltinLoc, expr, TInfo, RPLoc); +} + +ExprResult Sema::BuildVAArgExpr(SourceLocation BuiltinLoc, + Expr *E, TypeSourceInfo *TInfo, + SourceLocation RPLoc) { Expr *OrigExpr = E; InitBuiltinVaListType(); @@ -7367,13 +7381,11 @@ Sema::OwningExprResult Sema::ActOnVAArg(SourceLocation BuiltinLoc, // FIXME: Check that type is complete/non-abstract // FIXME: Warn if a non-POD type is passed in. - expr.release(); - return Owned(new (Context) VAArgExpr(BuiltinLoc, E, - T.getNonLValueExprType(Context), - RPLoc)); + QualType T = TInfo->getType().getNonLValueExprType(Context); + return Owned(new (Context) VAArgExpr(BuiltinLoc, E, TInfo, RPLoc, T)); } -Sema::OwningExprResult Sema::ActOnGNUNullExpr(SourceLocation TokenLoc) { +ExprResult Sema::ActOnGNUNullExpr(SourceLocation TokenLoc) { // The type of __null will be int or long, depending on the size of // pointers on the target. QualType Ty; @@ -7647,8 +7659,10 @@ void Sema::MarkDeclarationReferenced(SourceLocation Loc, Decl *D) { if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(D)) { unsigned TypeQuals; if (Constructor->isImplicit() && Constructor->isDefaultConstructor()) { - if (!Constructor->isUsed(false)) - DefineImplicitDefaultConstructor(Loc, Constructor); + if (Constructor->getParent()->hasTrivialConstructor()) + return; + if (!Constructor->isUsed(false)) + DefineImplicitDefaultConstructor(Loc, Constructor); } else if (Constructor->isImplicit() && Constructor->isCopyConstructor(TypeQuals)) { if (!Constructor->isUsed(false)) @@ -7696,13 +7710,20 @@ void Sema::MarkDeclarationReferenced(SourceLocation Loc, Decl *D) { PendingLocalImplicitInstantiations.push_back(std::make_pair(Function, Loc)); else - PendingImplicitInstantiations.push_back(std::make_pair(Function, - Loc)); + PendingInstantiations.push_back(std::make_pair(Function, Loc)); + } + } else // Walk redefinitions, as some of them may be instantiable. + for (FunctionDecl::redecl_iterator i(Function->redecls_begin()), + e(Function->redecls_end()); i != e; ++i) { + if (!i->isUsed(false) && i->isImplicitlyInstantiable()) + MarkDeclarationReferenced(Loc, *i); } - } // FIXME: keep track of references to static functions - Function->setUsed(true); + + // Recursive functions should be marked when used from another function. + if (CurContext != Function) + Function->setUsed(true); return; } @@ -7716,7 +7737,7 @@ void Sema::MarkDeclarationReferenced(SourceLocation Loc, Decl *D) { if (MSInfo->getPointOfInstantiation().isInvalid() && MSInfo->getTemplateSpecializationKind()== TSK_ImplicitInstantiation) { MSInfo->setPointOfInstantiation(Loc); - PendingImplicitInstantiations.push_back(std::make_pair(Var, Loc)); + PendingInstantiations.push_back(std::make_pair(Var, Loc)); } } @@ -7836,7 +7857,7 @@ void Sema::DiagnoseAssignmentAsCondition(Expr *E) { if (isa<BinaryOperator>(E)) { BinaryOperator *Op = cast<BinaryOperator>(E); - if (Op->getOpcode() != BinaryOperator::Assign) + if (Op->getOpcode() != BO_Assign) return; // Greylist some idioms by putting them into a warning subcategory. @@ -7899,16 +7920,13 @@ bool Sema::CheckBooleanCondition(Expr *&E, SourceLocation Loc) { return false; } -Sema::OwningExprResult Sema::ActOnBooleanCondition(Scope *S, SourceLocation Loc, - ExprArg SubExpr) { - Expr *Sub = SubExpr.takeAs<Expr>(); +ExprResult Sema::ActOnBooleanCondition(Scope *S, SourceLocation Loc, + Expr *Sub) { if (!Sub) return ExprError(); - if (CheckBooleanCondition(Sub, Loc)) { - Sub->Destroy(Context); + if (CheckBooleanCondition(Sub, Loc)) return ExprError(); - } return Owned(Sub); } |