diff options
Diffstat (limited to 'contrib/llvm-project/clang/lib/Sema/SemaExprObjC.cpp')
-rw-r--r-- | contrib/llvm-project/clang/lib/Sema/SemaExprObjC.cpp | 1398 |
1 files changed, 941 insertions, 457 deletions
diff --git a/contrib/llvm-project/clang/lib/Sema/SemaExprObjC.cpp b/contrib/llvm-project/clang/lib/Sema/SemaExprObjC.cpp index a8853f634c9c..7ccecf055fee 100644 --- a/contrib/llvm-project/clang/lib/Sema/SemaExprObjC.cpp +++ b/contrib/llvm-project/clang/lib/Sema/SemaExprObjC.cpp @@ -17,6 +17,7 @@ #include "clang/AST/TypeLoc.h" #include "clang/Analysis/DomainSpecific/CocoaConventions.h" #include "clang/Basic/Builtins.h" +#include "clang/Basic/TargetInfo.h" #include "clang/Edit/Commit.h" #include "clang/Edit/Rewriters.h" #include "clang/Lex/Preprocessor.h" @@ -25,6 +26,7 @@ #include "clang/Sema/Scope.h" #include "clang/Sema/ScopeInfo.h" #include "clang/Sema/SemaInternal.h" +#include "clang/Sema/SemaObjC.h" #include "llvm/ADT/SmallString.h" #include "llvm/Support/ConvertUTF.h" #include <optional> @@ -33,8 +35,9 @@ using namespace clang; using namespace sema; using llvm::ArrayRef; -ExprResult Sema::ParseObjCStringLiteral(SourceLocation *AtLocs, - ArrayRef<Expr *> Strings) { +ExprResult SemaObjC::ParseObjCStringLiteral(SourceLocation *AtLocs, + ArrayRef<Expr *> Strings) { + ASTContext &Context = getASTContext(); // Most ObjC strings are formed out of a single piece. However, we *can* // have strings formed out of multiple @ strings with multiple pptokens in // each one, e.g. @"foo" "bar" @"baz" "qux" which need to be turned into one @@ -79,7 +82,9 @@ ExprResult Sema::ParseObjCStringLiteral(SourceLocation *AtLocs, return BuildObjCStringLiteral(AtLocs[0], S); } -ExprResult Sema::BuildObjCStringLiteral(SourceLocation AtLoc, StringLiteral *S){ +ExprResult SemaObjC::BuildObjCStringLiteral(SourceLocation AtLoc, + StringLiteral *S) { + ASTContext &Context = getASTContext(); // Verify that this composite string is acceptable for ObjC strings. if (CheckObjCString(S)) return true; @@ -100,8 +105,8 @@ ExprResult Sema::BuildObjCStringLiteral(SourceLocation AtLoc, StringLiteral *S){ else NSIdent = &Context.Idents.get(StringClass); - NamedDecl *IF = LookupSingleName(TUScope, NSIdent, AtLoc, - LookupOrdinaryName); + NamedDecl *IF = SemaRef.LookupSingleName(SemaRef.TUScope, NSIdent, AtLoc, + Sema::LookupOrdinaryName); if (ObjCInterfaceDecl *StrIF = dyn_cast_or_null<ObjCInterfaceDecl>(IF)) { Context.setObjCConstantStringInterface(StrIF); Ty = Context.getObjCConstantStringInterface(); @@ -115,8 +120,8 @@ ExprResult Sema::BuildObjCStringLiteral(SourceLocation AtLoc, StringLiteral *S){ } } else { IdentifierInfo *NSIdent = NSAPIObj->getNSClassId(NSAPI::ClassId_NSString); - NamedDecl *IF = LookupSingleName(TUScope, NSIdent, AtLoc, - LookupOrdinaryName); + NamedDecl *IF = SemaRef.LookupSingleName(SemaRef.TUScope, NSIdent, AtLoc, + Sema::LookupOrdinaryName); if (ObjCInterfaceDecl *StrIF = dyn_cast_or_null<ObjCInterfaceDecl>(IF)) { Context.setObjCConstantStringInterface(StrIF); Ty = Context.getObjCConstantStringInterface(); @@ -168,25 +173,25 @@ static bool validateBoxingMethod(Sema &S, SourceLocation Loc, } /// Maps ObjCLiteralKind to NSClassIdKindKind -static NSAPI::NSClassIdKindKind ClassKindFromLiteralKind( - Sema::ObjCLiteralKind LiteralKind) { +static NSAPI::NSClassIdKindKind +ClassKindFromLiteralKind(SemaObjC::ObjCLiteralKind LiteralKind) { switch (LiteralKind) { - case Sema::LK_Array: - return NSAPI::ClassId_NSArray; - case Sema::LK_Dictionary: - return NSAPI::ClassId_NSDictionary; - case Sema::LK_Numeric: - return NSAPI::ClassId_NSNumber; - case Sema::LK_String: - return NSAPI::ClassId_NSString; - case Sema::LK_Boxed: - return NSAPI::ClassId_NSValue; - - // there is no corresponding matching - // between LK_None/LK_Block and NSClassIdKindKind - case Sema::LK_Block: - case Sema::LK_None: - break; + case SemaObjC::LK_Array: + return NSAPI::ClassId_NSArray; + case SemaObjC::LK_Dictionary: + return NSAPI::ClassId_NSDictionary; + case SemaObjC::LK_Numeric: + return NSAPI::ClassId_NSNumber; + case SemaObjC::LK_String: + return NSAPI::ClassId_NSString; + case SemaObjC::LK_Boxed: + return NSAPI::ClassId_NSValue; + + // there is no corresponding matching + // between LK_None/LK_Block and NSClassIdKindKind + case SemaObjC::LK_Block: + case SemaObjC::LK_None: + break; } llvm_unreachable("LiteralKind can't be converted into a ClassKind"); } @@ -194,12 +199,13 @@ static NSAPI::NSClassIdKindKind ClassKindFromLiteralKind( /// Validates ObjCInterfaceDecl availability. /// ObjCInterfaceDecl, used to create ObjC literals, should be defined /// if clang not in a debugger mode. -static bool ValidateObjCLiteralInterfaceDecl(Sema &S, ObjCInterfaceDecl *Decl, - SourceLocation Loc, - Sema::ObjCLiteralKind LiteralKind) { +static bool +ValidateObjCLiteralInterfaceDecl(Sema &S, ObjCInterfaceDecl *Decl, + SourceLocation Loc, + SemaObjC::ObjCLiteralKind LiteralKind) { if (!Decl) { NSAPI::NSClassIdKindKind Kind = ClassKindFromLiteralKind(LiteralKind); - IdentifierInfo *II = S.NSAPIObj->getNSClassId(Kind); + IdentifierInfo *II = S.ObjC().NSAPIObj->getNSClassId(Kind); S.Diag(Loc, diag::err_undeclared_objc_literal_class) << II->getName() << LiteralKind; return false; @@ -216,11 +222,11 @@ static bool ValidateObjCLiteralInterfaceDecl(Sema &S, ObjCInterfaceDecl *Decl, /// Looks up ObjCInterfaceDecl of a given NSClassIdKindKind. /// Used to create ObjC literals, such as NSDictionary (@{}), /// NSArray (@[]) and Boxed Expressions (@()) -static ObjCInterfaceDecl *LookupObjCInterfaceDeclForLiteral(Sema &S, - SourceLocation Loc, - Sema::ObjCLiteralKind LiteralKind) { +static ObjCInterfaceDecl * +LookupObjCInterfaceDeclForLiteral(Sema &S, SourceLocation Loc, + SemaObjC::ObjCLiteralKind LiteralKind) { NSAPI::NSClassIdKindKind ClassKind = ClassKindFromLiteralKind(LiteralKind); - IdentifierInfo *II = S.NSAPIObj->getNSClassId(ClassKind); + IdentifierInfo *II = S.ObjC().NSAPIObj->getNSClassId(ClassKind); NamedDecl *IF = S.LookupSingleName(S.TUScope, II, Loc, Sema::LookupOrdinaryName); ObjCInterfaceDecl *ID = dyn_cast_or_null<ObjCInterfaceDecl>(IF); @@ -240,7 +246,7 @@ static ObjCInterfaceDecl *LookupObjCInterfaceDeclForLiteral(Sema &S, /// Retrieve the NSNumber factory method that should be used to create /// an Objective-C literal for the given type. -static ObjCMethodDecl *getNSNumberFactoryMethod(Sema &S, SourceLocation Loc, +static ObjCMethodDecl *getNSNumberFactoryMethod(SemaObjC &S, SourceLocation Loc, QualType NumberType, bool isLiteral = false, SourceRange R = SourceRange()) { @@ -262,13 +268,13 @@ static ObjCMethodDecl *getNSNumberFactoryMethod(Sema &S, SourceLocation Loc, Selector Sel = S.NSAPIObj->getNSNumberLiteralSelector(*Kind, /*Instance=*/false); - ASTContext &CX = S.Context; + ASTContext &CX = S.SemaRef.Context; // Look up the NSNumber class, if we haven't done so already. It's cached // in the Sema instance. if (!S.NSNumberDecl) { - S.NSNumberDecl = LookupObjCInterfaceDeclForLiteral(S, Loc, - Sema::LK_Numeric); + S.NSNumberDecl = + LookupObjCInterfaceDeclForLiteral(S.SemaRef, Loc, SemaObjC::LK_Numeric); if (!S.NSNumberDecl) { return nullptr; } @@ -294,15 +300,14 @@ static ObjCMethodDecl *getNSNumberFactoryMethod(Sema &S, SourceLocation Loc, /*isImplicitlyDeclared=*/true, /*isDefined=*/false, ObjCImplementationControl::Required, /*HasRelatedResultType=*/false); - ParmVarDecl *value = ParmVarDecl::Create(S.Context, Method, - SourceLocation(), SourceLocation(), - &CX.Idents.get("value"), - NumberType, /*TInfo=*/nullptr, - SC_None, nullptr); - Method->setMethodParams(S.Context, value, std::nullopt); + ParmVarDecl *value = + ParmVarDecl::Create(S.SemaRef.Context, Method, SourceLocation(), + SourceLocation(), &CX.Idents.get("value"), + NumberType, /*TInfo=*/nullptr, SC_None, nullptr); + Method->setMethodParams(S.SemaRef.Context, value, std::nullopt); } - if (!validateBoxingMethod(S, Loc, S.NSNumberDecl, Sel, Method)) + if (!validateBoxingMethod(S.SemaRef, Loc, S.NSNumberDecl, Sel, Method)) return nullptr; // Note: if the parameter type is out-of-line, we'll catch it later in the @@ -314,7 +319,9 @@ static ObjCMethodDecl *getNSNumberFactoryMethod(Sema &S, SourceLocation Loc, /// BuildObjCNumericLiteral - builds an ObjCBoxedExpr AST node for the /// numeric literal expression. Type of the expression will be "NSNumber *". -ExprResult Sema::BuildObjCNumericLiteral(SourceLocation AtLoc, Expr *Number) { +ExprResult SemaObjC::BuildObjCNumericLiteral(SourceLocation AtLoc, + Expr *Number) { + ASTContext &Context = getASTContext(); // Determine the type of the literal. QualType NumberType = Number->getType(); if (CharacterLiteral *Char = dyn_cast<CharacterLiteral>(Number)) { @@ -352,31 +359,30 @@ ExprResult Sema::BuildObjCNumericLiteral(SourceLocation AtLoc, Expr *Number) { ParmVarDecl *ParamDecl = Method->parameters()[0]; InitializedEntity Entity = InitializedEntity::InitializeParameter(Context, ParamDecl); - ExprResult ConvertedNumber = PerformCopyInitialization(Entity, - SourceLocation(), - Number); + ExprResult ConvertedNumber = + SemaRef.PerformCopyInitialization(Entity, SourceLocation(), Number); if (ConvertedNumber.isInvalid()) return ExprError(); Number = ConvertedNumber.get(); // Use the effective source range of the literal, including the leading '@'. - return MaybeBindToTemporary( - new (Context) ObjCBoxedExpr(Number, NSNumberPointer, Method, - SourceRange(AtLoc, NR.getEnd()))); + return SemaRef.MaybeBindToTemporary(new (Context) ObjCBoxedExpr( + Number, NSNumberPointer, Method, SourceRange(AtLoc, NR.getEnd()))); } -ExprResult Sema::ActOnObjCBoolLiteral(SourceLocation AtLoc, - SourceLocation ValueLoc, - bool Value) { +ExprResult SemaObjC::ActOnObjCBoolLiteral(SourceLocation AtLoc, + SourceLocation ValueLoc, bool Value) { + ASTContext &Context = getASTContext(); ExprResult Inner; if (getLangOpts().CPlusPlus) { - Inner = ActOnCXXBoolLiteral(ValueLoc, Value? tok::kw_true : tok::kw_false); + Inner = SemaRef.ActOnCXXBoolLiteral(ValueLoc, + Value ? tok::kw_true : tok::kw_false); } else { // C doesn't actually have a way to represent literal values of type // _Bool. So, we'll use 0/1 and implicit cast to _Bool. - Inner = ActOnIntegerConstant(ValueLoc, Value? 1 : 0); - Inner = ImpCastExprToType(Inner.get(), Context.BoolTy, - CK_IntegralToBoolean); + Inner = SemaRef.ActOnIntegerConstant(ValueLoc, Value ? 1 : 0); + Inner = SemaRef.ImpCastExprToType(Inner.get(), Context.BoolTy, + CK_IntegralToBoolean); } return BuildObjCNumericLiteral(AtLoc, Inner.get()); @@ -428,7 +434,8 @@ static ExprResult CheckObjCCollectionLiteralElement(Sema &S, Expr *Element, isa<FloatingLiteral>(OrigElement) || isa<ObjCBoolLiteralExpr>(OrigElement) || isa<CXXBoolLiteralExpr>(OrigElement)) { - if (S.NSAPIObj->getNSNumberFactoryMethodKind(OrigElement->getType())) { + if (S.ObjC().NSAPIObj->getNSNumberFactoryMethodKind( + OrigElement->getType())) { int Which = isa<CharacterLiteral>(OrigElement) ? 1 : (isa<CXXBoolLiteralExpr>(OrigElement) || isa<ObjCBoolLiteralExpr>(OrigElement)) ? 2 @@ -438,8 +445,8 @@ static ExprResult CheckObjCCollectionLiteralElement(Sema &S, Expr *Element, << Which << OrigElement->getSourceRange() << FixItHint::CreateInsertion(OrigElement->getBeginLoc(), "@"); - Result = - S.BuildObjCNumericLiteral(OrigElement->getBeginLoc(), OrigElement); + Result = S.ObjC().BuildObjCNumericLiteral(OrigElement->getBeginLoc(), + OrigElement); if (Result.isInvalid()) return ExprError(); @@ -454,7 +461,8 @@ static ExprResult CheckObjCCollectionLiteralElement(Sema &S, Expr *Element, << 0 << OrigElement->getSourceRange() << FixItHint::CreateInsertion(OrigElement->getBeginLoc(), "@"); - Result = S.BuildObjCStringLiteral(OrigElement->getBeginLoc(), String); + Result = + S.ObjC().BuildObjCStringLiteral(OrigElement->getBeginLoc(), String); if (Result.isInvalid()) return ExprError(); @@ -498,7 +506,8 @@ static ExprResult CheckObjCCollectionLiteralElement(Sema &S, Expr *Element, Element->getBeginLoc(), Element); } -ExprResult Sema::BuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr) { +ExprResult SemaObjC::BuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr) { + ASTContext &Context = getASTContext(); if (ValueExpr->isTypeDependent()) { ObjCBoxedExpr *BoxedExpr = new (Context) ObjCBoxedExpr(ValueExpr, Context.DependentTy, nullptr, SR); @@ -507,7 +516,7 @@ ExprResult Sema::BuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr) { ObjCMethodDecl *BoxingMethod = nullptr; QualType BoxedType; // Convert the expression to an RValue, so we can check for pointer types... - ExprResult RValue = DefaultFunctionArrayLvalueConversion(ValueExpr); + ExprResult RValue = SemaRef.DefaultFunctionArrayLvalueConversion(ValueExpr); if (RValue.isInvalid()) { return ExprError(); } @@ -519,8 +528,8 @@ ExprResult Sema::BuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr) { if (Context.hasSameUnqualifiedType(PointeeType, Context.CharTy)) { if (!NSStringDecl) { - NSStringDecl = LookupObjCInterfaceDeclForLiteral(*this, Loc, - Sema::LK_String); + NSStringDecl = + LookupObjCInterfaceDeclForLiteral(SemaRef, Loc, LK_String); if (!NSStringDecl) { return ExprError(); } @@ -582,9 +591,9 @@ ExprResult Sema::BuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr) { BoxingMethod = M; } - if (!validateBoxingMethod(*this, Loc, NSStringDecl, + if (!validateBoxingMethod(SemaRef, Loc, NSStringDecl, stringWithUTF8String, BoxingMethod)) - return ExprError(); + return ExprError(); StringWithUTF8StringMethod = BoxingMethod; } @@ -651,8 +660,7 @@ ExprResult Sema::BuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr) { // Look up the NSValue class, if we haven't done so already. It's cached // in the Sema instance. if (!NSValueDecl) { - NSValueDecl = LookupObjCInterfaceDeclForLiteral(*this, Loc, - Sema::LK_Boxed); + NSValueDecl = LookupObjCInterfaceDeclForLiteral(SemaRef, Loc, LK_Boxed); if (!NSValueDecl) { return ExprError(); } @@ -663,10 +671,8 @@ ExprResult Sema::BuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr) { } if (!ValueWithBytesObjCTypeMethod) { - IdentifierInfo *II[] = { - &Context.Idents.get("valueWithBytes"), - &Context.Idents.get("objCType") - }; + const IdentifierInfo *II[] = {&Context.Idents.get("valueWithBytes"), + &Context.Idents.get("objCType")}; Selector ValueWithBytesObjCType = Context.Selectors.getSelector(2, II); // Look for the appropriate method within NSValue. @@ -710,7 +716,7 @@ ExprResult Sema::BuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr) { BoxingMethod = M; } - if (!validateBoxingMethod(*this, Loc, NSValueDecl, + if (!validateBoxingMethod(SemaRef, Loc, NSValueDecl, ValueWithBytesObjCType, BoxingMethod)) return ExprError(); @@ -733,20 +739,20 @@ ExprResult Sema::BuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr) { return ExprError(); } - DiagnoseUseOfDecl(BoxingMethod, Loc); + SemaRef.DiagnoseUseOfDecl(BoxingMethod, Loc); ExprResult ConvertedValueExpr; if (ValueType->isObjCBoxableRecordType()) { InitializedEntity IE = InitializedEntity::InitializeTemporary(ValueType); - ConvertedValueExpr = PerformCopyInitialization(IE, ValueExpr->getExprLoc(), - ValueExpr); + ConvertedValueExpr = SemaRef.PerformCopyInitialization( + IE, ValueExpr->getExprLoc(), ValueExpr); } else { // Convert the expression to the type that the parameter requires. ParmVarDecl *ParamDecl = BoxingMethod->parameters()[0]; InitializedEntity IE = InitializedEntity::InitializeParameter(Context, ParamDecl); - ConvertedValueExpr = PerformCopyInitialization(IE, SourceLocation(), - ValueExpr); + ConvertedValueExpr = + SemaRef.PerformCopyInitialization(IE, SourceLocation(), ValueExpr); } if (ConvertedValueExpr.isInvalid()) @@ -756,16 +762,16 @@ ExprResult Sema::BuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr) { ObjCBoxedExpr *BoxedExpr = new (Context) ObjCBoxedExpr(ValueExpr, BoxedType, BoxingMethod, SR); - return MaybeBindToTemporary(BoxedExpr); + return SemaRef.MaybeBindToTemporary(BoxedExpr); } /// Build an ObjC subscript pseudo-object expression, given that /// that's supported by the runtime. -ExprResult Sema::BuildObjCSubscriptExpression(SourceLocation RB, Expr *BaseExpr, - Expr *IndexExpr, - ObjCMethodDecl *getterMethod, - ObjCMethodDecl *setterMethod) { - assert(!LangOpts.isSubscriptPointerArithmetic()); +ExprResult SemaObjC::BuildObjCSubscriptExpression( + SourceLocation RB, Expr *BaseExpr, Expr *IndexExpr, + ObjCMethodDecl *getterMethod, ObjCMethodDecl *setterMethod) { + assert(!getLangOpts().isSubscriptPointerArithmetic()); + ASTContext &Context = getASTContext(); // We can't get dependent types here; our callers should have // filtered them out. @@ -774,13 +780,13 @@ ExprResult Sema::BuildObjCSubscriptExpression(SourceLocation RB, Expr *BaseExpr, // Filter out placeholders in the index. In theory, overloads could // be preserved here, although that might not actually work correctly. - ExprResult Result = CheckPlaceholderExpr(IndexExpr); + ExprResult Result = SemaRef.CheckPlaceholderExpr(IndexExpr); if (Result.isInvalid()) return ExprError(); IndexExpr = Result.get(); // Perform lvalue-to-rvalue conversion on the base. - Result = DefaultLvalueConversion(BaseExpr); + Result = SemaRef.DefaultLvalueConversion(BaseExpr); if (Result.isInvalid()) return ExprError(); BaseExpr = Result.get(); @@ -791,12 +797,14 @@ ExprResult Sema::BuildObjCSubscriptExpression(SourceLocation RB, Expr *BaseExpr, getterMethod, setterMethod, RB); } -ExprResult Sema::BuildObjCArrayLiteral(SourceRange SR, MultiExprArg Elements) { +ExprResult SemaObjC::BuildObjCArrayLiteral(SourceRange SR, + MultiExprArg Elements) { + ASTContext &Context = getASTContext(); SourceLocation Loc = SR.getBegin(); if (!NSArrayDecl) { - NSArrayDecl = LookupObjCInterfaceDeclForLiteral(*this, Loc, - Sema::LK_Array); + NSArrayDecl = + LookupObjCInterfaceDeclForLiteral(SemaRef, Loc, SemaObjC::LK_Array); if (!NSArrayDecl) { return ExprError(); } @@ -837,7 +845,7 @@ ExprResult Sema::BuildObjCArrayLiteral(SourceRange SR, MultiExprArg Elements) { Method->setMethodParams(Context, Params, std::nullopt); } - if (!validateBoxingMethod(*this, Loc, NSArrayDecl, Sel, Method)) + if (!validateBoxingMethod(SemaRef, Loc, NSArrayDecl, Sel, Method)) return ExprError(); // Dig out the type that all elements should be converted to. @@ -877,9 +885,8 @@ ExprResult Sema::BuildObjCArrayLiteral(SourceRange SR, MultiExprArg Elements) { // performing conversions as necessary. Expr **ElementsBuffer = Elements.data(); for (unsigned I = 0, N = Elements.size(); I != N; ++I) { - ExprResult Converted = CheckObjCCollectionLiteralElement(*this, - ElementsBuffer[I], - RequiredType, true); + ExprResult Converted = CheckObjCCollectionLiteralElement( + SemaRef, ElementsBuffer[I], RequiredType, true); if (Converted.isInvalid()) return ExprError(); @@ -890,9 +897,8 @@ ExprResult Sema::BuildObjCArrayLiteral(SourceRange SR, MultiExprArg Elements) { = Context.getObjCObjectPointerType( Context.getObjCInterfaceType(NSArrayDecl)); - return MaybeBindToTemporary( - ObjCArrayLiteral::Create(Context, Elements, Ty, - ArrayWithObjectsMethod, SR)); + return SemaRef.MaybeBindToTemporary(ObjCArrayLiteral::Create( + Context, Elements, Ty, ArrayWithObjectsMethod, SR)); } /// Check for duplicate keys in an ObjC dictionary literal. For instance: @@ -951,13 +957,14 @@ CheckObjCDictionaryLiteralDuplicateKeys(Sema &S, } } -ExprResult Sema::BuildObjCDictionaryLiteral(SourceRange SR, - MutableArrayRef<ObjCDictionaryElement> Elements) { +ExprResult SemaObjC::BuildObjCDictionaryLiteral( + SourceRange SR, MutableArrayRef<ObjCDictionaryElement> Elements) { + ASTContext &Context = getASTContext(); SourceLocation Loc = SR.getBegin(); if (!NSDictionaryDecl) { - NSDictionaryDecl = LookupObjCInterfaceDeclForLiteral(*this, Loc, - Sema::LK_Dictionary); + NSDictionaryDecl = LookupObjCInterfaceDeclForLiteral( + SemaRef, Loc, SemaObjC::LK_Dictionary); if (!NSDictionaryDecl) { return ExprError(); } @@ -1007,9 +1014,9 @@ ExprResult Sema::BuildObjCDictionaryLiteral(SourceRange SR, Method->setMethodParams(Context, Params, std::nullopt); } - if (!validateBoxingMethod(*this, SR.getBegin(), NSDictionaryDecl, Sel, + if (!validateBoxingMethod(SemaRef, SR.getBegin(), NSDictionaryDecl, Sel, Method)) - return ExprError(); + return ExprError(); // Dig out the type that all values should be converted to. QualType ValueT = Method->parameters()[0]->getType(); @@ -1086,14 +1093,14 @@ ExprResult Sema::BuildObjCDictionaryLiteral(SourceRange SR, bool HasPackExpansions = false; for (ObjCDictionaryElement &Element : Elements) { // Check the key. - ExprResult Key = CheckObjCCollectionLiteralElement(*this, Element.Key, - KeyT); + ExprResult Key = + CheckObjCCollectionLiteralElement(SemaRef, Element.Key, KeyT); if (Key.isInvalid()) return ExprError(); // Check the value. - ExprResult Value - = CheckObjCCollectionLiteralElement(*this, Element.Value, ValueT); + ExprResult Value = + CheckObjCCollectionLiteralElement(SemaRef, Element.Value, ValueT); if (Value.isInvalid()) return ExprError(); @@ -1121,13 +1128,14 @@ ExprResult Sema::BuildObjCDictionaryLiteral(SourceRange SR, auto *Literal = ObjCDictionaryLiteral::Create(Context, Elements, HasPackExpansions, Ty, DictionaryWithObjectsMethod, SR); - CheckObjCDictionaryLiteralDuplicateKeys(*this, Literal); - return MaybeBindToTemporary(Literal); + CheckObjCDictionaryLiteralDuplicateKeys(SemaRef, Literal); + return SemaRef.MaybeBindToTemporary(Literal); } -ExprResult Sema::BuildObjCEncodeExpression(SourceLocation AtLoc, - TypeSourceInfo *EncodedTypeInfo, - SourceLocation RParenLoc) { +ExprResult SemaObjC::BuildObjCEncodeExpression(SourceLocation AtLoc, + TypeSourceInfo *EncodedTypeInfo, + SourceLocation RParenLoc) { + ASTContext &Context = getASTContext(); QualType EncodedType = EncodedTypeInfo->getType(); QualType StrTy; if (EncodedType->isDependentType()) @@ -1135,9 +1143,9 @@ ExprResult Sema::BuildObjCEncodeExpression(SourceLocation AtLoc, else { if (!EncodedType->getAsArrayTypeUnsafe() && //// Incomplete array is handled. !EncodedType->isVoidType()) // void is handled too. - if (RequireCompleteType(AtLoc, EncodedType, - diag::err_incomplete_type_objc_at_encode, - EncodedTypeInfo->getTypeLoc())) + if (SemaRef.RequireCompleteType(AtLoc, EncodedType, + diag::err_incomplete_type_objc_at_encode, + EncodedTypeInfo->getTypeLoc())) return ExprError(); std::string Str; @@ -1155,17 +1163,18 @@ ExprResult Sema::BuildObjCEncodeExpression(SourceLocation AtLoc, return new (Context) ObjCEncodeExpr(StrTy, EncodedTypeInfo, AtLoc, RParenLoc); } -ExprResult Sema::ParseObjCEncodeExpression(SourceLocation AtLoc, - SourceLocation EncodeLoc, - SourceLocation LParenLoc, - ParsedType ty, - SourceLocation RParenLoc) { +ExprResult SemaObjC::ParseObjCEncodeExpression(SourceLocation AtLoc, + SourceLocation EncodeLoc, + SourceLocation LParenLoc, + ParsedType ty, + SourceLocation RParenLoc) { + ASTContext &Context = getASTContext(); // FIXME: Preserve type source info ? TypeSourceInfo *TInfo; - QualType EncodedType = GetTypeFromParser(ty, &TInfo); + QualType EncodedType = SemaRef.GetTypeFromParser(ty, &TInfo); if (!TInfo) - TInfo = Context.getTrivialTypeSourceInfo(EncodedType, - getLocForEndOfToken(LParenLoc)); + TInfo = Context.getTrivialTypeSourceInfo( + EncodedType, SemaRef.getLocForEndOfToken(LParenLoc)); return BuildObjCEncodeExpression(AtLoc, TInfo, RParenLoc); } @@ -1184,8 +1193,8 @@ static bool HelperToDiagnoseMismatchedMethodsInGlobalPool(Sema &S, isa<ObjCImplDecl>(MatchingMethodDecl->getDeclContext()) || MatchingMethodDecl->getSelector() != Method->getSelector()) continue; - if (!S.MatchTwoMethodDeclarations(Method, - MatchingMethodDecl, Sema::MMS_loose)) { + if (!S.ObjC().MatchTwoMethodDeclarations(Method, MatchingMethodDecl, + SemaObjC::MMS_loose)) { if (!Warned) { Warned = true; S.Diag(AtLoc, diag::warn_multiple_selectors) @@ -1210,8 +1219,9 @@ static void DiagnoseMismatchedSelectors(Sema &S, SourceLocation AtLoc, S.Diags.isIgnored(diag::warn_multiple_selectors, SourceLocation())) return; bool Warned = false; - for (Sema::GlobalMethodPool::iterator b = S.MethodPool.begin(), - e = S.MethodPool.end(); b != e; b++) { + for (SemaObjC::GlobalMethodPool::iterator b = S.ObjC().MethodPool.begin(), + e = S.ObjC().MethodPool.end(); + b != e; b++) { // first, instance methods ObjCMethodList &InstMethList = b->second.first; if (HelperToDiagnoseMismatchedMethodsInGlobalPool(S, AtLoc, LParenLoc, RParenLoc, @@ -1255,8 +1265,8 @@ static ObjCMethodDecl *LookupDirectMethodInMethodList(Sema &S, Selector Sel, static ObjCMethodDecl *LookupDirectMethodInGlobalPool(Sema &S, Selector Sel, bool &onlyDirect, bool &anyDirect) { - auto Iter = S.MethodPool.find(Sel); - if (Iter == S.MethodPool.end()) + auto Iter = S.ObjC().MethodPool.find(Sel); + if (Iter == S.ObjC().MethodPool.end()) return nullptr; ObjCMethodDecl *DirectInstance = LookupDirectMethodInMethodList( @@ -1288,12 +1298,13 @@ static ObjCMethodDecl *findMethodInCurrentClass(Sema &S, Selector Sel) { return nullptr; } -ExprResult Sema::ParseObjCSelectorExpression(Selector Sel, - SourceLocation AtLoc, - SourceLocation SelLoc, - SourceLocation LParenLoc, - SourceLocation RParenLoc, - bool WarnMultipleSelectors) { +ExprResult SemaObjC::ParseObjCSelectorExpression(Selector Sel, + SourceLocation AtLoc, + SourceLocation SelLoc, + SourceLocation LParenLoc, + SourceLocation RParenLoc, + bool WarnMultipleSelectors) { + ASTContext &Context = getASTContext(); ObjCMethodDecl *Method = LookupInstanceMethodInGlobalPool(Sel, SourceRange(LParenLoc, RParenLoc)); if (!Method) @@ -1311,13 +1322,13 @@ ExprResult Sema::ParseObjCSelectorExpression(Selector Sel, } else Diag(SelLoc, diag::warn_undeclared_selector) << Sel; } else { - DiagnoseMismatchedSelectors(*this, AtLoc, Method, LParenLoc, RParenLoc, + DiagnoseMismatchedSelectors(SemaRef, AtLoc, Method, LParenLoc, RParenLoc, WarnMultipleSelectors); bool onlyDirect = true; bool anyDirect = false; ObjCMethodDecl *GlobalDirectMethod = - LookupDirectMethodInGlobalPool(*this, Sel, onlyDirect, anyDirect); + LookupDirectMethodInGlobalPool(SemaRef, Sel, onlyDirect, anyDirect); if (onlyDirect) { Diag(AtLoc, diag::err_direct_selector_expression) @@ -1328,7 +1339,8 @@ ExprResult Sema::ParseObjCSelectorExpression(Selector Sel, // If we saw any direct methods, see if we see a direct member of the // current class. If so, the @selector will likely be used to refer to // this direct method. - ObjCMethodDecl *LikelyTargetMethod = findMethodInCurrentClass(*this, Sel); + ObjCMethodDecl *LikelyTargetMethod = + findMethodInCurrentClass(SemaRef, Sel); if (LikelyTargetMethod && LikelyTargetMethod->isDirectMethod()) { Diag(AtLoc, diag::warn_potentially_direct_selector_expression) << Sel; Diag(LikelyTargetMethod->getLocation(), @@ -1349,7 +1361,7 @@ ExprResult Sema::ParseObjCSelectorExpression(Selector Sel, if (Method && Method->getImplementationControl() != ObjCImplementationControl::Optional && - !getSourceManager().isInSystemHeader(Method->getLocation())) + !SemaRef.getSourceManager().isInSystemHeader(Method->getLocation())) ReferencedSelectors.insert(std::make_pair(Sel, AtLoc)); // In ARC, forbid the user from using @selector for @@ -1382,12 +1394,13 @@ ExprResult Sema::ParseObjCSelectorExpression(Selector Sel, return new (Context) ObjCSelectorExpr(Ty, Sel, AtLoc, RParenLoc); } -ExprResult Sema::ParseObjCProtocolExpression(IdentifierInfo *ProtocolId, - SourceLocation AtLoc, - SourceLocation ProtoLoc, - SourceLocation LParenLoc, - SourceLocation ProtoIdLoc, - SourceLocation RParenLoc) { +ExprResult SemaObjC::ParseObjCProtocolExpression(IdentifierInfo *ProtocolId, + SourceLocation AtLoc, + SourceLocation ProtoLoc, + SourceLocation LParenLoc, + SourceLocation ProtoIdLoc, + SourceLocation RParenLoc) { + ASTContext &Context = getASTContext(); ObjCProtocolDecl* PDecl = LookupProtocol(ProtocolId, ProtoIdLoc); if (!PDecl) { Diag(ProtoLoc, diag::err_undeclared_protocol) << ProtocolId; @@ -1411,8 +1424,8 @@ ExprResult Sema::ParseObjCProtocolExpression(IdentifierInfo *ProtocolId, } /// Try to capture an implicit reference to 'self'. -ObjCMethodDecl *Sema::tryCaptureObjCSelf(SourceLocation Loc) { - DeclContext *DC = getFunctionLevelDeclContext(); +ObjCMethodDecl *SemaObjC::tryCaptureObjCSelf(SourceLocation Loc) { + DeclContext *DC = SemaRef.getFunctionLevelDeclContext(); // If we're not in an ObjC method, error out. Note that, unlike the // C++ case, we don't require an instance method --- class methods @@ -1421,7 +1434,7 @@ ObjCMethodDecl *Sema::tryCaptureObjCSelf(SourceLocation Loc) { if (!method) return nullptr; - tryCaptureVariable(method->getSelfDecl(), Loc); + SemaRef.tryCaptureVariable(method->getSelfDecl(), Loc); return method; } @@ -1515,16 +1528,15 @@ static QualType getBaseMessageSendResultType(Sema &S, return transferNullability(ReceiverType); } -QualType Sema::getMessageSendResultType(const Expr *Receiver, - QualType ReceiverType, - ObjCMethodDecl *Method, - bool isClassMessage, - bool isSuperMessage) { +QualType SemaObjC::getMessageSendResultType(const Expr *Receiver, + QualType ReceiverType, + ObjCMethodDecl *Method, + bool isClassMessage, + bool isSuperMessage) { + ASTContext &Context = getASTContext(); // Produce the result type. - QualType resultType = getBaseMessageSendResultType(*this, ReceiverType, - Method, - isClassMessage, - isSuperMessage); + QualType resultType = getBaseMessageSendResultType( + SemaRef, ReceiverType, Method, isClassMessage, isSuperMessage); // If this is a class message, ignore the nullability of the receiver. if (isClassMessage) { @@ -1653,10 +1665,11 @@ findExplicitInstancetypeDeclarer(const ObjCMethodDecl *MD, return nullptr; } -void Sema::EmitRelatedResultTypeNoteForReturn(QualType destType) { +void SemaObjC::EmitRelatedResultTypeNoteForReturn(QualType destType) { + ASTContext &Context = getASTContext(); // Only complain if we're in an ObjC method and the required return // type doesn't match the method's declared return type. - ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(CurContext); + ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(SemaRef.CurContext); if (!MD || !MD->hasRelatedResultType() || Context.hasSameUnqualifiedType(destType, MD->getReturnType())) return; @@ -1682,7 +1695,8 @@ void Sema::EmitRelatedResultTypeNoteForReturn(QualType destType) { << family; } -void Sema::EmitRelatedResultTypeNote(const Expr *E) { +void SemaObjC::EmitRelatedResultTypeNote(const Expr *E) { + ASTContext &Context = getASTContext(); E = E->IgnoreParenImpCasts(); const ObjCMessageExpr *MsgSend = dyn_cast<ObjCMessageExpr>(E); if (!MsgSend) @@ -1708,12 +1722,13 @@ void Sema::EmitRelatedResultTypeNote(const Expr *E) { << MsgSend->getType(); } -bool Sema::CheckMessageArgumentTypes( +bool SemaObjC::CheckMessageArgumentTypes( const Expr *Receiver, QualType ReceiverType, MultiExprArg Args, Selector Sel, ArrayRef<SourceLocation> SelectorLocs, ObjCMethodDecl *Method, bool isClassMessage, bool isSuperMessage, SourceLocation lbrac, SourceLocation rbrac, SourceRange RecRange, QualType &ReturnType, ExprValueKind &VK) { + ASTContext &Context = getASTContext(); SourceLocation SelLoc; if (!SelectorLocs.empty() && SelectorLocs.front().isValid()) SelLoc = SelectorLocs.front(); @@ -1729,9 +1744,9 @@ bool Sema::CheckMessageArgumentTypes( ExprResult result; if (getLangOpts().DebuggerSupport) { QualType paramTy; // ignored - result = checkUnknownAnyArg(SelLoc, Args[i], paramTy); + result = SemaRef.checkUnknownAnyArg(SelLoc, Args[i], paramTy); } else { - result = DefaultArgumentPromotion(Args[i]); + result = SemaRef.DefaultArgumentPromotion(Args[i]); } if (result.isInvalid()) return true; @@ -1837,7 +1852,7 @@ bool Sema::CheckMessageArgumentTypes( // from the argument. if (param->getType() == Context.UnknownAnyTy) { QualType paramType; - ExprResult argE = checkUnknownAnyArg(SelLoc, argExpr, paramType); + ExprResult argE = SemaRef.checkUnknownAnyArg(SelLoc, argExpr, paramType); if (argE.isInvalid()) { IsError = true; } else { @@ -1857,14 +1872,15 @@ bool Sema::CheckMessageArgumentTypes( *typeArgs, ObjCSubstitutionContext::Parameter); - if (RequireCompleteType(argExpr->getSourceRange().getBegin(), - paramType, - diag::err_call_incomplete_argument, argExpr)) + if (SemaRef.RequireCompleteType( + argExpr->getSourceRange().getBegin(), paramType, + diag::err_call_incomplete_argument, argExpr)) return true; InitializedEntity Entity = InitializedEntity::InitializeParameter(Context, param, paramType); - ExprResult ArgE = PerformCopyInitialization(Entity, SourceLocation(), argExpr); + ExprResult ArgE = + SemaRef.PerformCopyInitialization(Entity, SourceLocation(), argExpr); if (ArgE.isInvalid()) IsError = true; else { @@ -1877,7 +1893,7 @@ bool Sema::CheckMessageArgumentTypes( Args[i]->getType()->isBlockPointerType() && origParamType->isObjCObjectPointerType()) { ExprResult arg = Args[i]; - maybeExtendBlockObject(arg); + SemaRef.maybeExtendBlockObject(arg); Args[i] = arg.get(); } } @@ -1889,8 +1905,8 @@ bool Sema::CheckMessageArgumentTypes( if (Args[i]->isTypeDependent()) continue; - ExprResult Arg = DefaultVariadicArgumentPromotion(Args[i], VariadicMethod, - nullptr); + ExprResult Arg = SemaRef.DefaultVariadicArgumentPromotion( + Args[i], Sema::VariadicMethod, nullptr); IsError |= Arg.isInvalid(); Args[i] = Arg.get(); } @@ -1906,7 +1922,7 @@ bool Sema::CheckMessageArgumentTypes( } } - DiagnoseSentinelCalls(Method, SelLoc, Args); + SemaRef.DiagnoseSentinelCalls(Method, SelLoc, Args); // Do additional checkings on method. IsError |= @@ -1915,14 +1931,14 @@ bool Sema::CheckMessageArgumentTypes( return IsError; } -bool Sema::isSelfExpr(Expr *RExpr) { +bool SemaObjC::isSelfExpr(Expr *RExpr) { // 'self' is objc 'self' in an objc method only. - ObjCMethodDecl *Method = - dyn_cast_or_null<ObjCMethodDecl>(CurContext->getNonClosureAncestor()); + ObjCMethodDecl *Method = dyn_cast_or_null<ObjCMethodDecl>( + SemaRef.CurContext->getNonClosureAncestor()); return isSelfExpr(RExpr, Method); } -bool Sema::isSelfExpr(Expr *receiver, const ObjCMethodDecl *method) { +bool SemaObjC::isSelfExpr(Expr *receiver, const ObjCMethodDecl *method) { if (!method) return false; receiver = receiver->IgnoreParenLValueCasts(); @@ -1933,8 +1949,8 @@ bool Sema::isSelfExpr(Expr *receiver, const ObjCMethodDecl *method) { } /// LookupMethodInType - Look up a method in an ObjCObjectType. -ObjCMethodDecl *Sema::LookupMethodInObjectType(Selector sel, QualType type, - bool isInstance) { +ObjCMethodDecl *SemaObjC::LookupMethodInObjectType(Selector sel, QualType type, + bool isInstance) { const ObjCObjectType *objType = type->castAs<ObjCObjectType>(); if (ObjCInterfaceDecl *iface = objType->getInterface()) { // Look it up in the main interface (and categories, etc.) @@ -1957,10 +1973,8 @@ ObjCMethodDecl *Sema::LookupMethodInObjectType(Selector sel, QualType type, /// LookupMethodInQualifiedType - Lookups up a method in protocol qualifier /// list of a qualified objective pointer type. -ObjCMethodDecl *Sema::LookupMethodInQualifiedType(Selector Sel, - const ObjCObjectPointerType *OPT, - bool Instance) -{ +ObjCMethodDecl *SemaObjC::LookupMethodInQualifiedType( + Selector Sel, const ObjCObjectPointerType *OPT, bool Instance) { ObjCMethodDecl *MD = nullptr; for (const auto *PROTO : OPT->quals()) { if ((MD = PROTO->lookupMethod(Sel, Instance))) { @@ -1972,13 +1986,11 @@ ObjCMethodDecl *Sema::LookupMethodInQualifiedType(Selector Sel, /// HandleExprPropertyRefExpr - Handle foo.bar where foo is a pointer to an /// objective C interface. This is a property reference expression. -ExprResult Sema:: -HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT, - Expr *BaseExpr, SourceLocation OpLoc, - DeclarationName MemberName, - SourceLocation MemberLoc, - SourceLocation SuperLoc, QualType SuperType, - bool Super) { +ExprResult SemaObjC::HandleExprPropertyRefExpr( + const ObjCObjectPointerType *OPT, Expr *BaseExpr, SourceLocation OpLoc, + DeclarationName MemberName, SourceLocation MemberLoc, + SourceLocation SuperLoc, QualType SuperType, bool Super) { + ASTContext &Context = getASTContext(); const ObjCInterfaceType *IFaceT = OPT->getInterfaceType(); ObjCInterfaceDecl *IFace = IFaceT->getDecl(); @@ -1992,15 +2004,15 @@ HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT, SourceRange BaseRange = Super? SourceRange(SuperLoc) : BaseExpr->getSourceRange(); - if (RequireCompleteType(MemberLoc, OPT->getPointeeType(), - diag::err_property_not_found_forward_class, - MemberName, BaseRange)) + if (SemaRef.RequireCompleteType(MemberLoc, OPT->getPointeeType(), + diag::err_property_not_found_forward_class, + MemberName, BaseRange)) return ExprError(); if (ObjCPropertyDecl *PD = IFace->FindPropertyDeclaration( Member, ObjCPropertyQueryKind::OBJC_PR_query_instance)) { // Check whether we can reference this property. - if (DiagnoseUseOfDecl(PD, MemberLoc)) + if (SemaRef.DiagnoseUseOfDecl(PD, MemberLoc)) return ExprError(); if (Super) return new (Context) @@ -2016,7 +2028,7 @@ HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT, if (ObjCPropertyDecl *PD = I->FindPropertyDeclaration( Member, ObjCPropertyQueryKind::OBJC_PR_query_instance)) { // Check whether we can reference this property. - if (DiagnoseUseOfDecl(PD, MemberLoc)) + if (SemaRef.DiagnoseUseOfDecl(PD, MemberLoc)) return ExprError(); if (Super) @@ -2034,7 +2046,7 @@ HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT, // FIXME: The logic for looking up nullary and unary selectors should be // shared with the code in ActOnInstanceMessage. - Selector Sel = PP.getSelectorTable().getNullarySelector(Member); + Selector Sel = SemaRef.PP.getSelectorTable().getNullarySelector(Member); ObjCMethodDecl *Getter = IFace->lookupInstanceMethod(Sel); // May be found in property's qualified list. @@ -2047,14 +2059,13 @@ HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT, if (Getter) { // Check if we can reference this property. - if (DiagnoseUseOfDecl(Getter, MemberLoc)) + if (SemaRef.DiagnoseUseOfDecl(Getter, MemberLoc)) return ExprError(); } // If we found a getter then this may be a valid dot-reference, we // will look for the matching setter, in case it is needed. - Selector SetterSel = - SelectorTable::constructSetterSelector(PP.getIdentifierTable(), - PP.getSelectorTable(), Member); + Selector SetterSel = SelectorTable::constructSetterSelector( + SemaRef.PP.getIdentifierTable(), SemaRef.PP.getSelectorTable(), Member); ObjCMethodDecl *Setter = IFace->lookupInstanceMethod(SetterSel); // May be found in property's qualified list. @@ -2067,7 +2078,7 @@ HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT, Setter = IFace->lookupPrivateMethod(SetterSel); } - if (Setter && DiagnoseUseOfDecl(Setter, MemberLoc)) + if (Setter && SemaRef.DiagnoseUseOfDecl(Setter, MemberLoc)) return ExprError(); // Special warning if member name used in a property-dot for a setter accessor @@ -2102,9 +2113,9 @@ HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT, // Attempt to correct for typos in property names. DeclFilterCCC<ObjCPropertyDecl> CCC{}; - if (TypoCorrection Corrected = CorrectTypo( - DeclarationNameInfo(MemberName, MemberLoc), LookupOrdinaryName, - nullptr, nullptr, CCC, CTK_ErrorRecovery, IFace, false, OPT)) { + if (TypoCorrection Corrected = SemaRef.CorrectTypo( + DeclarationNameInfo(MemberName, MemberLoc), Sema::LookupOrdinaryName, + nullptr, nullptr, CCC, Sema::CTK_ErrorRecovery, IFace, false, OPT)) { DeclarationName TypoResult = Corrected.getCorrection(); if (TypoResult.isIdentifier() && TypoResult.getAsIdentifierInfo() == Member) { @@ -2122,8 +2133,9 @@ HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT, return ExprError(); } } else { - diagnoseTypo(Corrected, PDiag(diag::err_property_not_found_suggest) - << MemberName << QualType(OPT, 0)); + SemaRef.diagnoseTypo(Corrected, + PDiag(diag::err_property_not_found_suggest) + << MemberName << QualType(OPT, 0)); return HandleExprPropertyRefExpr(OPT, BaseExpr, OpLoc, TypoResult, MemberLoc, SuperLoc, SuperType, Super); @@ -2135,9 +2147,9 @@ HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT, QualType T = Ivar->getType(); if (const ObjCObjectPointerType * OBJPT = T->getAsObjCInterfacePointerType()) { - if (RequireCompleteType(MemberLoc, OBJPT->getPointeeType(), - diag::err_property_not_as_forward_class, - MemberName, BaseExpr)) + if (SemaRef.RequireCompleteType(MemberLoc, OBJPT->getPointeeType(), + diag::err_property_not_as_forward_class, + MemberName, BaseExpr)) return ExprError(); } Diag(MemberLoc, @@ -2155,13 +2167,11 @@ HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT, return ExprError(); } -ExprResult Sema:: -ActOnClassPropertyRefExpr(IdentifierInfo &receiverName, - IdentifierInfo &propertyName, - SourceLocation receiverNameLoc, - SourceLocation propertyNameLoc) { - - IdentifierInfo *receiverNamePtr = &receiverName; +ExprResult SemaObjC::ActOnClassPropertyRefExpr( + const IdentifierInfo &receiverName, const IdentifierInfo &propertyName, + SourceLocation receiverNameLoc, SourceLocation propertyNameLoc) { + ASTContext &Context = getASTContext(); + const IdentifierInfo *receiverNamePtr = &receiverName; ObjCInterfaceDecl *IFace = getObjCInterfaceDecl(receiverNamePtr, receiverNameLoc); @@ -2211,9 +2221,10 @@ ActOnClassPropertyRefExpr(IdentifierInfo &receiverName, GetterSel = PD->getGetterName(); SetterSel = PD->getSetterName(); } else { - GetterSel = PP.getSelectorTable().getNullarySelector(&propertyName); + GetterSel = SemaRef.PP.getSelectorTable().getNullarySelector(&propertyName); SetterSel = SelectorTable::constructSetterSelector( - PP.getIdentifierTable(), PP.getSelectorTable(), &propertyName); + SemaRef.PP.getIdentifierTable(), SemaRef.PP.getSelectorTable(), + &propertyName); } // Search for a declared property first. @@ -2226,7 +2237,7 @@ ActOnClassPropertyRefExpr(IdentifierInfo &receiverName, if (Getter) { // FIXME: refactor/share with ActOnMemberReference(). // Check if we can reference this property. - if (DiagnoseUseOfDecl(Getter, propertyNameLoc)) + if (SemaRef.DiagnoseUseOfDecl(Getter, propertyNameLoc)) return ExprError(); } @@ -2241,7 +2252,7 @@ ActOnClassPropertyRefExpr(IdentifierInfo &receiverName, if (!Setter) Setter = IFace->getCategoryClassMethod(SetterSel); - if (Setter && DiagnoseUseOfDecl(Setter, propertyNameLoc)) + if (Setter && SemaRef.DiagnoseUseOfDecl(Setter, propertyNameLoc)) return ExprError(); if (Getter || Setter) { @@ -2281,12 +2292,11 @@ class ObjCInterfaceOrSuperCCC final : public CorrectionCandidateCallback { } // end anonymous namespace -Sema::ObjCMessageKind Sema::getObjCMessageKind(Scope *S, - IdentifierInfo *Name, - SourceLocation NameLoc, - bool IsSuper, - bool HasTrailingDot, - ParsedType &ReceiverType) { +SemaObjC::ObjCMessageKind +SemaObjC::getObjCMessageKind(Scope *S, IdentifierInfo *Name, + SourceLocation NameLoc, bool IsSuper, + bool HasTrailingDot, ParsedType &ReceiverType) { + ASTContext &Context = getASTContext(); ReceiverType = nullptr; // If the identifier is "super" and there is no trailing dot, we're @@ -2295,8 +2305,8 @@ Sema::ObjCMessageKind Sema::getObjCMessageKind(Scope *S, if (IsSuper && S->isInObjcMethodScope()) return HasTrailingDot? ObjCInstanceMessage : ObjCSuperMessage; - LookupResult Result(*this, Name, NameLoc, LookupOrdinaryName); - LookupName(Result, S); + LookupResult Result(SemaRef, Name, NameLoc, Sema::LookupOrdinaryName); + SemaRef.LookupName(Result, S); switch (Result.getResultKind()) { case LookupResult::NotFound: @@ -2304,7 +2314,7 @@ Sema::ObjCMessageKind Sema::getObjCMessageKind(Scope *S, // Objective-C method, look for ivars. If we find one, we're done! // FIXME: This is a hack. Ivar lookup should be part of normal // lookup. - if (ObjCMethodDecl *Method = getCurMethodDecl()) { + if (ObjCMethodDecl *Method = SemaRef.getCurMethodDecl()) { if (!Method->getClassInterface()) { // Fall back: let the parser try to parse it as an instance message. return ObjCInstanceMessage; @@ -2339,7 +2349,7 @@ Sema::ObjCMessageKind Sema::getObjCMessageKind(Scope *S, T = Context.getObjCInterfaceType(Class); else if (TypeDecl *Type = dyn_cast<TypeDecl>(ND)) { T = Context.getTypeDeclType(Type); - DiagnoseUseOfDecl(Type, NameLoc); + SemaRef.DiagnoseUseOfDecl(Type, NameLoc); } else return ObjCInstanceMessage; @@ -2347,30 +2357,30 @@ Sema::ObjCMessageKind Sema::getObjCMessageKind(Scope *S, // We have a class message, and T is the type we're // messaging. Build source-location information for it. TypeSourceInfo *TSInfo = Context.getTrivialTypeSourceInfo(T, NameLoc); - ReceiverType = CreateParsedType(T, TSInfo); + ReceiverType = SemaRef.CreateParsedType(T, TSInfo); return ObjCClassMessage; } } - ObjCInterfaceOrSuperCCC CCC(getCurMethodDecl()); - if (TypoCorrection Corrected = CorrectTypo( + ObjCInterfaceOrSuperCCC CCC(SemaRef.getCurMethodDecl()); + if (TypoCorrection Corrected = SemaRef.CorrectTypo( Result.getLookupNameInfo(), Result.getLookupKind(), S, nullptr, CCC, - CTK_ErrorRecovery, nullptr, false, nullptr, false)) { + Sema::CTK_ErrorRecovery, nullptr, false, nullptr, false)) { if (Corrected.isKeyword()) { // If we've found the keyword "super" (the only keyword that would be // returned by CorrectTypo), this is a send to super. - diagnoseTypo(Corrected, - PDiag(diag::err_unknown_receiver_suggest) << Name); + SemaRef.diagnoseTypo(Corrected, PDiag(diag::err_unknown_receiver_suggest) + << Name); return ObjCSuperMessage; } else if (ObjCInterfaceDecl *Class = Corrected.getCorrectionDeclAs<ObjCInterfaceDecl>()) { // If we found a declaration, correct when it refers to an Objective-C // class. - diagnoseTypo(Corrected, - PDiag(diag::err_unknown_receiver_suggest) << Name); + SemaRef.diagnoseTypo(Corrected, PDiag(diag::err_unknown_receiver_suggest) + << Name); QualType T = Context.getObjCInterfaceType(Class); TypeSourceInfo *TSInfo = Context.getTrivialTypeSourceInfo(T, NameLoc); - ReceiverType = CreateParsedType(T, TSInfo); + ReceiverType = SemaRef.CreateParsedType(T, TSInfo); return ObjCClassMessage; } } @@ -2379,13 +2389,12 @@ Sema::ObjCMessageKind Sema::getObjCMessageKind(Scope *S, return ObjCInstanceMessage; } -ExprResult Sema::ActOnSuperMessage(Scope *S, - SourceLocation SuperLoc, - Selector Sel, - SourceLocation LBracLoc, - ArrayRef<SourceLocation> SelectorLocs, - SourceLocation RBracLoc, - MultiExprArg Args) { +ExprResult SemaObjC::ActOnSuperMessage(Scope *S, SourceLocation SuperLoc, + Selector Sel, SourceLocation LBracLoc, + ArrayRef<SourceLocation> SelectorLocs, + SourceLocation RBracLoc, + MultiExprArg Args) { + ASTContext &Context = getASTContext(); // Determine whether we are inside a method or not. ObjCMethodDecl *Method = tryCaptureObjCSelf(SuperLoc); if (!Method) { @@ -2411,7 +2420,7 @@ ExprResult Sema::ActOnSuperMessage(Scope *S, // We are in a method whose class has a superclass, so 'super' // is acting as a keyword. if (Method->getSelector() == Sel) - getCurFunction()->ObjCShouldCallSuper = false; + SemaRef.getCurFunction()->ObjCShouldCallSuper = false; if (Method->isInstanceMethod()) { // Since we are in an instance method, this is an instance @@ -2430,12 +2439,12 @@ ExprResult Sema::ActOnSuperMessage(Scope *S, LBracLoc, SelectorLocs, RBracLoc, Args); } -ExprResult Sema::BuildClassMessageImplicit(QualType ReceiverType, - bool isSuperReceiver, - SourceLocation Loc, - Selector Sel, - ObjCMethodDecl *Method, - MultiExprArg Args) { +ExprResult SemaObjC::BuildClassMessageImplicit(QualType ReceiverType, + bool isSuperReceiver, + SourceLocation Loc, Selector Sel, + ObjCMethodDecl *Method, + MultiExprArg Args) { + ASTContext &Context = getASTContext(); TypeSourceInfo *receiverTypeInfo = nullptr; if (!ReceiverType.isNull()) receiverTypeInfo = Context.getTrivialTypeSourceInfo(ReceiverType); @@ -2459,7 +2468,7 @@ static void applyCocoaAPICheck(Sema &S, const ObjCMessageExpr *Msg, SourceManager &SM = S.SourceMgr; edit::Commit ECommit(SM, S.LangOpts); - if (refactor(Msg,*S.NSAPIObj, ECommit)) { + if (refactor(Msg, *S.ObjC().NSAPIObj, ECommit)) { auto Builder = S.Diag(MsgLoc, DiagID) << Msg->getSelector() << Msg->getSourceRange(); // FIXME: Don't emit diagnostic at all if fixits are non-commitable. @@ -2555,7 +2564,7 @@ DiagnoseCStringFormatDirectiveInObjCAPI(Sema &S, } else if (Method) { for (const auto *I : Method->specific_attrs<FormatAttr>()) { - if (S.GetFormatNSStringIdx(I, Idx)) { + if (S.ObjC().GetFormatNSStringIdx(I, Idx)) { Format = true; break; } @@ -2606,16 +2615,12 @@ DiagnoseCStringFormatDirectiveInObjCAPI(Sema &S, /// \param RBracLoc The location of the closing square bracket ']'. /// /// \param ArgsIn The message arguments. -ExprResult Sema::BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo, - QualType ReceiverType, - SourceLocation SuperLoc, - Selector Sel, - ObjCMethodDecl *Method, - SourceLocation LBracLoc, - ArrayRef<SourceLocation> SelectorLocs, - SourceLocation RBracLoc, - MultiExprArg ArgsIn, - bool isImplicit) { +ExprResult SemaObjC::BuildClassMessage( + TypeSourceInfo *ReceiverTypeInfo, QualType ReceiverType, + SourceLocation SuperLoc, Selector Sel, ObjCMethodDecl *Method, + SourceLocation LBracLoc, ArrayRef<SourceLocation> SelectorLocs, + SourceLocation RBracLoc, MultiExprArg ArgsIn, bool isImplicit) { + ASTContext &Context = getASTContext(); SourceLocation Loc = SuperLoc.isValid()? SuperLoc : ReceiverTypeInfo->getTypeLoc().getSourceRange().getBegin(); if (LBracLoc.isInvalid()) { @@ -2653,17 +2658,17 @@ ExprResult Sema::BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo, assert(Class && "We don't know which class we're messaging?"); // objc++ diagnoses during typename annotation. if (!getLangOpts().CPlusPlus) - (void)DiagnoseUseOfDecl(Class, SelectorSlotLocs); + (void)SemaRef.DiagnoseUseOfDecl(Class, SelectorSlotLocs); // Find the method we are messaging. if (!Method) { SourceRange TypeRange = SuperLoc.isValid()? SourceRange(SuperLoc) : ReceiverTypeInfo->getTypeLoc().getSourceRange(); - if (RequireCompleteType(Loc, Context.getObjCInterfaceType(Class), - (getLangOpts().ObjCAutoRefCount - ? diag::err_arc_receiver_forward_class - : diag::warn_receiver_forward_class), - TypeRange)) { + if (SemaRef.RequireCompleteType(Loc, Context.getObjCInterfaceType(Class), + (getLangOpts().ObjCAutoRefCount + ? diag::err_arc_receiver_forward_class + : diag::warn_receiver_forward_class), + TypeRange)) { // A forward class used in messaging is treated as a 'Class' Method = LookupFactoryMethodInGlobalPool(Sel, SourceRange(LBracLoc, RBracLoc)); @@ -2678,8 +2683,8 @@ ExprResult Sema::BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo, if (!Method) Method = Class->lookupPrivateClassMethod(Sel); - if (Method && DiagnoseUseOfDecl(Method, SelectorSlotLocs, - nullptr, false, false, Class)) + if (Method && SemaRef.DiagnoseUseOfDecl(Method, SelectorSlotLocs, nullptr, + false, false, Class)) return ExprError(); } @@ -2696,8 +2701,9 @@ ExprResult Sema::BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo, return ExprError(); if (Method && !Method->getReturnType()->isVoidType() && - RequireCompleteType(LBracLoc, Method->getReturnType(), - diag::err_illegal_message_expr_incomplete_type)) + SemaRef.RequireCompleteType( + LBracLoc, Method->getReturnType(), + diag::err_illegal_message_expr_incomplete_type)) return ExprError(); if (Method && Method->isDirectMethod() && SuperLoc.isValid()) { @@ -2720,8 +2726,7 @@ ExprResult Sema::BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo, Diag(Method->getLocation(), diag::note_method_declared_at) << Method->getDeclName(); } - } - else if (ObjCMethodDecl *CurMeth = getCurMethodDecl()) { + } else if (ObjCMethodDecl *CurMeth = SemaRef.getCurMethodDecl()) { // [super initialize] is allowed only within an +initialize implementation if (CurMeth->getMethodFamily() != OMF_initialize) { Diag(Loc, diag::warn_direct_super_initialize_call); @@ -2733,7 +2738,7 @@ ExprResult Sema::BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo, } } - DiagnoseCStringFormatDirectiveInObjCAPI(*this, Method, Sel, Args, NumArgs); + DiagnoseCStringFormatDirectiveInObjCAPI(SemaRef, Method, Sel, Args, NumArgs); // Construct the appropriate ObjCMessageExpr. ObjCMessageExpr *Result; @@ -2747,26 +2752,26 @@ ExprResult Sema::BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo, Context, ReturnType, VK, LBracLoc, ReceiverTypeInfo, Sel, SelectorLocs, Method, ArrayRef(Args, NumArgs), RBracLoc, isImplicit); if (!isImplicit) - checkCocoaAPI(*this, Result); + checkCocoaAPI(SemaRef, Result); } if (Method) - checkFoundationAPI(*this, SelLoc, Method, ArrayRef(Args, NumArgs), + checkFoundationAPI(SemaRef, SelLoc, Method, ArrayRef(Args, NumArgs), ReceiverType, /*IsClassObjectCall=*/true); - return MaybeBindToTemporary(Result); + return SemaRef.MaybeBindToTemporary(Result); } // ActOnClassMessage - used for both unary and keyword messages. // ArgExprs is optional - if it is present, the number of expressions // is obtained from Sel.getNumArgs(). -ExprResult Sema::ActOnClassMessage(Scope *S, - ParsedType Receiver, - Selector Sel, - SourceLocation LBracLoc, - ArrayRef<SourceLocation> SelectorLocs, - SourceLocation RBracLoc, - MultiExprArg Args) { +ExprResult SemaObjC::ActOnClassMessage(Scope *S, ParsedType Receiver, + Selector Sel, SourceLocation LBracLoc, + ArrayRef<SourceLocation> SelectorLocs, + SourceLocation RBracLoc, + MultiExprArg Args) { + ASTContext &Context = getASTContext(); TypeSourceInfo *ReceiverTypeInfo; - QualType ReceiverType = GetTypeFromParser(Receiver, &ReceiverTypeInfo); + QualType ReceiverType = + SemaRef.GetTypeFromParser(Receiver, &ReceiverTypeInfo); if (ReceiverType.isNull()) return ExprError(); @@ -2779,12 +2784,9 @@ ExprResult Sema::ActOnClassMessage(Scope *S, Args); } -ExprResult Sema::BuildInstanceMessageImplicit(Expr *Receiver, - QualType ReceiverType, - SourceLocation Loc, - Selector Sel, - ObjCMethodDecl *Method, - MultiExprArg Args) { +ExprResult SemaObjC::BuildInstanceMessageImplicit( + Expr *Receiver, QualType ReceiverType, SourceLocation Loc, Selector Sel, + ObjCMethodDecl *Method, MultiExprArg Args) { return BuildInstanceMessage(Receiver, ReceiverType, /*SuperLoc=*/!Receiver ? Loc : SourceLocation(), Sel, Method, Loc, Loc, Loc, Args, @@ -2792,12 +2794,13 @@ ExprResult Sema::BuildInstanceMessageImplicit(Expr *Receiver, } static bool isMethodDeclaredInRootProtocol(Sema &S, const ObjCMethodDecl *M) { - if (!S.NSAPIObj) + if (!S.ObjC().NSAPIObj) return false; const auto *Protocol = dyn_cast<ObjCProtocolDecl>(M->getDeclContext()); if (!Protocol) return false; - const IdentifierInfo *II = S.NSAPIObj->getNSClassId(NSAPI::ClassId_NSObject); + const IdentifierInfo *II = + S.ObjC().NSAPIObj->getNSClassId(NSAPI::ClassId_NSObject); if (const auto *RootClass = dyn_cast_or_null<ObjCInterfaceDecl>( S.LookupSingleName(S.TUScope, II, Protocol->getBeginLoc(), Sema::LookupOrdinaryName))) { @@ -2837,19 +2840,15 @@ static bool isMethodDeclaredInRootProtocol(Sema &S, const ObjCMethodDecl *M) { /// \param RBracLoc The location of the closing square bracket ']'. /// /// \param ArgsIn The message arguments. -ExprResult Sema::BuildInstanceMessage(Expr *Receiver, - QualType ReceiverType, - SourceLocation SuperLoc, - Selector Sel, - ObjCMethodDecl *Method, - SourceLocation LBracLoc, - ArrayRef<SourceLocation> SelectorLocs, - SourceLocation RBracLoc, - MultiExprArg ArgsIn, - bool isImplicit) { +ExprResult SemaObjC::BuildInstanceMessage( + Expr *Receiver, QualType ReceiverType, SourceLocation SuperLoc, + Selector Sel, ObjCMethodDecl *Method, SourceLocation LBracLoc, + ArrayRef<SourceLocation> SelectorLocs, SourceLocation RBracLoc, + MultiExprArg ArgsIn, bool isImplicit) { assert((Receiver || SuperLoc.isValid()) && "If the Receiver is null, the " "SuperLoc must be valid so we can " "use it instead."); + ASTContext &Context = getASTContext(); // The location of the receiver. SourceLocation Loc = SuperLoc.isValid() ? SuperLoc : Receiver->getBeginLoc(); @@ -2874,9 +2873,10 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver, if (Receiver->hasPlaceholderType()) { ExprResult Result; if (Receiver->getType() == Context.UnknownAnyTy) - Result = forceUnknownAnyToType(Receiver, Context.getObjCIdType()); + Result = + SemaRef.forceUnknownAnyToType(Receiver, Context.getObjCIdType()); else - Result = CheckPlaceholderExpr(Receiver); + Result = SemaRef.CheckPlaceholderExpr(Receiver); if (Result.isInvalid()) return ExprError(); Receiver = Result.get(); } @@ -2895,7 +2895,7 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver, // If necessary, apply function/array conversion to the receiver. // C99 6.7.5.3p[7,8]. - ExprResult Result = DefaultFunctionArrayLvalueConversion(Receiver); + ExprResult Result = SemaRef.DefaultFunctionArrayLvalueConversion(Receiver); if (Result.isInvalid()) return ExprError(); Receiver = Result.get(); @@ -2914,24 +2914,28 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver, // But not in ARC. Diag(Loc, diag::warn_bad_receiver_type) << ReceiverType << RecRange; if (ReceiverType->isPointerType()) { - Receiver = ImpCastExprToType(Receiver, Context.getObjCIdType(), - CK_CPointerToObjCPointerCast).get(); + Receiver = SemaRef + .ImpCastExprToType(Receiver, Context.getObjCIdType(), + CK_CPointerToObjCPointerCast) + .get(); } else { // TODO: specialized warning on null receivers? bool IsNull = Receiver->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull); CastKind Kind = IsNull ? CK_NullToPointer : CK_IntegralToPointer; - Receiver = ImpCastExprToType(Receiver, Context.getObjCIdType(), - Kind).get(); + Receiver = + SemaRef.ImpCastExprToType(Receiver, Context.getObjCIdType(), Kind) + .get(); } ReceiverType = Receiver->getType(); } else if (getLangOpts().CPlusPlus) { // The receiver must be a complete type. - if (RequireCompleteType(Loc, Receiver->getType(), - diag::err_incomplete_receiver_type)) + if (SemaRef.RequireCompleteType(Loc, Receiver->getType(), + diag::err_incomplete_receiver_type)) return ExprError(); - ExprResult result = PerformContextuallyConvertToObjCPointer(Receiver); + ExprResult result = + SemaRef.PerformContextuallyConvertToObjCPointer(Receiver); if (result.isUsable()) { Receiver = result.get(); ReceiverType = Receiver->getType(); @@ -2960,14 +2964,14 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver, // select a better one. Method = Methods[0]; - if (ObjCMethodDecl *BestMethod = - SelectBestMethod(Sel, ArgsIn, Method->isInstanceMethod(), Methods)) + if (ObjCMethodDecl *BestMethod = SemaRef.SelectBestMethod( + Sel, ArgsIn, Method->isInstanceMethod(), Methods)) Method = BestMethod; if (!AreMultipleMethodsInGlobalPool(Sel, Method, SourceRange(LBracLoc, RBracLoc), receiverIsIdLike, Methods)) - DiagnoseUseOfDecl(Method, SelectorSlotLocs); + SemaRef.DiagnoseUseOfDecl(Method, SelectorSlotLocs); } } else if (ReceiverType->isObjCClassOrClassKindOfType() || ReceiverType->isObjCQualifiedClassType()) { @@ -2983,7 +2987,7 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver, if (!Method) { Method = LookupMethodInQualifiedType(Sel, QClassTy, true); // warn if instance method found for a Class message. - if (Method && !isMethodDeclaredInRootProtocol(*this, Method)) { + if (Method && !isMethodDeclaredInRootProtocol(SemaRef, Method)) { Diag(SelLoc, diag::warn_instance_method_on_class_found) << Method->getSelector() << Sel; Diag(Method->getLocation(), diag::note_method_declared_at) @@ -2991,7 +2995,7 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver, } } } else { - if (ObjCMethodDecl *CurMeth = getCurMethodDecl()) { + if (ObjCMethodDecl *CurMeth = SemaRef.getCurMethodDecl()) { if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface()) { // As a guess, try looking for the method in the current interface. // This very well may not produce the "right" method. @@ -3002,7 +3006,7 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver, if (!Method) Method = ClassDecl->lookupPrivateClassMethod(Sel); - if (Method && DiagnoseUseOfDecl(Method, SelectorSlotLocs)) + if (Method && SemaRef.DiagnoseUseOfDecl(Method, SelectorSlotLocs)) return ExprError(); } } @@ -3030,10 +3034,9 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver, } } - if (ObjCMethodDecl *BestMethod = - SelectBestMethod(Sel, ArgsIn, Method->isInstanceMethod(), - Methods)) - Method = BestMethod; + if (ObjCMethodDecl *BestMethod = SemaRef.SelectBestMethod( + Sel, ArgsIn, Method->isInstanceMethod(), Methods)) + Method = BestMethod; } } } @@ -3050,7 +3053,7 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver, Method = LookupMethodInQualifiedType(Sel, QIdTy, true); if (!Method) Method = LookupMethodInQualifiedType(Sel, QIdTy, false); - if (Method && DiagnoseUseOfDecl(Method, SelectorSlotLocs)) + if (Method && SemaRef.DiagnoseUseOfDecl(Method, SelectorSlotLocs)) return ExprError(); } else if (const ObjCObjectPointerType *OCIType = ReceiverType->getAsObjCInterfacePointerType()) { @@ -3062,11 +3065,12 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver, // FIXME: In the non-ARC case, this will still be a hard error if the // definition is found in a module that's not visible. const ObjCInterfaceDecl *forwardClass = nullptr; - if (RequireCompleteType(Loc, OCIType->getPointeeType(), - getLangOpts().ObjCAutoRefCount - ? diag::err_arc_receiver_forward_instance - : diag::warn_receiver_forward_instance, - RecRange)) { + if (SemaRef.RequireCompleteType( + Loc, OCIType->getPointeeType(), + getLangOpts().ObjCAutoRefCount + ? diag::err_arc_receiver_forward_instance + : diag::warn_receiver_forward_instance, + RecRange)) { if (getLangOpts().ObjCAutoRefCount) return ExprError(); @@ -3107,9 +3111,8 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver, // to select a better one. Method = Methods[0]; - if (ObjCMethodDecl *BestMethod = - SelectBestMethod(Sel, ArgsIn, Method->isInstanceMethod(), - Methods)) + if (ObjCMethodDecl *BestMethod = SemaRef.SelectBestMethod( + Sel, ArgsIn, Method->isInstanceMethod(), Methods)) Method = BestMethod; AreMultipleMethodsInGlobalPool(Sel, Method, @@ -3124,7 +3127,8 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver, } } } - if (Method && DiagnoseUseOfDecl(Method, SelectorSlotLocs, forwardClass)) + if (Method && + SemaRef.DiagnoseUseOfDecl(Method, SelectorSlotLocs, forwardClass)) return ExprError(); } else { // Reject other random receiver types (e.g. structs). @@ -3135,8 +3139,9 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver, } FunctionScopeInfo *DIFunctionScopeInfo = - (Method && Method->getMethodFamily() == OMF_init) - ? getEnclosingFunction() : nullptr; + (Method && Method->getMethodFamily() == OMF_init) + ? SemaRef.getEnclosingFunction() + : nullptr; if (Method && Method->isDirectMethod()) { if (ReceiverType->isObjCIdType() && !isImplicit) { @@ -3202,7 +3207,8 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver, if (!isDesignatedInitChain) { const ObjCMethodDecl *InitMethod = nullptr; bool isDesignated = - getCurMethodDecl()->isDesignatedInitializerForTheInterface(&InitMethod); + SemaRef.getCurMethodDecl()->isDesignatedInitializerForTheInterface( + &InitMethod); assert(isDesignated && InitMethod); (void)isDesignated; Diag(SelLoc, SuperLoc.isValid() ? @@ -3237,8 +3243,9 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver, return ExprError(); if (Method && !Method->getReturnType()->isVoidType() && - RequireCompleteType(LBracLoc, Method->getReturnType(), - diag::err_illegal_message_expr_incomplete_type)) + SemaRef.RequireCompleteType( + LBracLoc, Method->getReturnType(), + diag::err_illegal_message_expr_incomplete_type)) return ExprError(); // In ARC, forbid the user from sending messages to @@ -3322,7 +3329,7 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver, } } - DiagnoseCStringFormatDirectiveInObjCAPI(*this, Method, Sel, Args, NumArgs); + DiagnoseCStringFormatDirectiveInObjCAPI(SemaRef, Method, Sel, Args, NumArgs); // Construct the appropriate ObjCMessageExpr instance. ObjCMessageExpr *Result; @@ -3336,7 +3343,7 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver, Context, ReturnType, VK, LBracLoc, Receiver, Sel, SelectorLocs, Method, ArrayRef(Args, NumArgs), RBracLoc, isImplicit); if (!isImplicit) - checkCocoaAPI(*this, Result); + checkCocoaAPI(SemaRef, Result); } if (Method) { bool IsClassObjectCall = ClassMessage; @@ -3347,7 +3354,7 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver, if (Receiver && isSelfExpr(Receiver)) { if (const auto *OPT = ReceiverType->getAs<ObjCObjectPointerType>()) { if (OPT->getObjectType()->isObjCClass()) { - if (const auto *CurMeth = getCurMethodDecl()) { + if (const auto *CurMeth = SemaRef.getCurMethodDecl()) { IsClassObjectCall = true; ReceiverType = Context.getObjCInterfaceType(CurMeth->getClassInterface()); @@ -3355,7 +3362,7 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver, } } } - checkFoundationAPI(*this, SelLoc, Method, ArrayRef(Args, NumArgs), + checkFoundationAPI(SemaRef, SelLoc, Method, ArrayRef(Args, NumArgs), ReceiverType, IsClassObjectCall); } @@ -3365,7 +3372,7 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver, (SuperLoc.isValid() || isSelfExpr(Receiver))) { // Only consider init calls *directly* in init implementations, // not within blocks. - ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(CurContext); + ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(SemaRef.CurContext); if (method && method->getMethodFamily() == OMF_init) { // The implicit assignment to self means we also don't want to // consume the result. @@ -3386,19 +3393,20 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver, Prop->getPropertyAttributes() & ObjCPropertyAttribute::kind_weak; if (!IsWeak && Sel.isUnarySelector()) IsWeak = ReturnType.getObjCLifetime() & Qualifiers::OCL_Weak; - if (IsWeak && !isUnevaluatedContext() && - !Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, LBracLoc)) - getCurFunction()->recordUseOfWeak(Result, Prop); + if (IsWeak && !SemaRef.isUnevaluatedContext() && + !getDiagnostics().isIgnored(diag::warn_arc_repeated_use_of_weak, + LBracLoc)) + SemaRef.getCurFunction()->recordUseOfWeak(Result, Prop); } } } CheckObjCCircularContainer(Result); - return MaybeBindToTemporary(Result); + return SemaRef.MaybeBindToTemporary(Result); } -static void RemoveSelectorFromWarningCache(Sema &S, Expr* Arg) { +static void RemoveSelectorFromWarningCache(SemaObjC &S, Expr *Arg) { if (ObjCSelectorExpr *OSE = dyn_cast<ObjCSelectorExpr>(Arg->IgnoreParenCasts())) { Selector Sel = OSE->getSelector(); @@ -3412,19 +3420,19 @@ static void RemoveSelectorFromWarningCache(Sema &S, Expr* Arg) { // ActOnInstanceMessage - used for both unary and keyword messages. // ArgExprs is optional - if it is present, the number of expressions // is obtained from Sel.getNumArgs(). -ExprResult Sema::ActOnInstanceMessage(Scope *S, - Expr *Receiver, - Selector Sel, - SourceLocation LBracLoc, - ArrayRef<SourceLocation> SelectorLocs, - SourceLocation RBracLoc, - MultiExprArg Args) { +ExprResult SemaObjC::ActOnInstanceMessage(Scope *S, Expr *Receiver, + Selector Sel, SourceLocation LBracLoc, + ArrayRef<SourceLocation> SelectorLocs, + SourceLocation RBracLoc, + MultiExprArg Args) { + ASTContext &Context = getASTContext(); if (!Receiver) return ExprError(); // A ParenListExpr can show up while doing error recovery with invalid code. if (isa<ParenListExpr>(Receiver)) { - ExprResult Result = MaybeConvertParenListExprToParenExpr(S, Receiver); + ExprResult Result = + SemaRef.MaybeConvertParenListExprToParenExpr(S, Receiver); if (Result.isInvalid()) return ExprError(); Receiver = Result.get(); } @@ -3738,32 +3746,33 @@ namespace { }; } // end anonymous namespace -bool Sema::isKnownName(StringRef name) { +bool SemaObjC::isKnownName(StringRef name) { + ASTContext &Context = getASTContext(); if (name.empty()) return false; - LookupResult R(*this, &Context.Idents.get(name), SourceLocation(), + LookupResult R(SemaRef, &Context.Idents.get(name), SourceLocation(), Sema::LookupOrdinaryName); - return LookupName(R, TUScope, false); + return SemaRef.LookupName(R, SemaRef.TUScope, false); } template <typename DiagBuilderT> static void addFixitForObjCARCConversion( - Sema &S, DiagBuilderT &DiagB, Sema::CheckedConversionKind CCK, + Sema &S, DiagBuilderT &DiagB, CheckedConversionKind CCK, SourceLocation afterLParen, QualType castType, Expr *castExpr, Expr *realCast, const char *bridgeKeyword, const char *CFBridgeName) { // We handle C-style and implicit casts here. switch (CCK) { - case Sema::CCK_ImplicitConversion: - case Sema::CCK_ForBuiltinOverloadedOp: - case Sema::CCK_CStyleCast: - case Sema::CCK_OtherCast: + case CheckedConversionKind::Implicit: + case CheckedConversionKind::ForBuiltinOverloadedOp: + case CheckedConversionKind::CStyleCast: + case CheckedConversionKind::OtherCast: break; - case Sema::CCK_FunctionalCast: + case CheckedConversionKind::FunctionalCast: return; } if (CFBridgeName) { - if (CCK == Sema::CCK_OtherCast) { + if (CCK == CheckedConversionKind::OtherCast) { if (const CXXNamedCastExpr *NCE = dyn_cast<CXXNamedCastExpr>(realCast)) { SourceRange range(NCE->getOperatorLoc(), NCE->getAngleBrackets().getEnd()); @@ -3808,9 +3817,9 @@ static void addFixitForObjCARCConversion( return; } - if (CCK == Sema::CCK_CStyleCast) { + if (CCK == CheckedConversionKind::CStyleCast) { DiagB.AddFixItHint(FixItHint::CreateInsertion(afterLParen, bridgeKeyword)); - } else if (CCK == Sema::CCK_OtherCast) { + } else if (CCK == CheckedConversionKind::OtherCast) { if (const CXXNamedCastExpr *NCE = dyn_cast<CXXNamedCastExpr>(realCast)) { std::string castCode = "("; castCode += bridgeKeyword; @@ -3869,12 +3878,12 @@ static ObjCBridgeRelatedAttr *ObjCBridgeRelatedAttrFromType(QualType T, return nullptr; } -static void -diagnoseObjCARCConversion(Sema &S, SourceRange castRange, - QualType castType, ARCConversionTypeClass castACTC, - Expr *castExpr, Expr *realCast, - ARCConversionTypeClass exprACTC, - Sema::CheckedConversionKind CCK) { +static void diagnoseObjCARCConversion(Sema &S, SourceRange castRange, + QualType castType, + ARCConversionTypeClass castACTC, + Expr *castExpr, Expr *realCast, + ARCConversionTypeClass exprACTC, + CheckedConversionKind CCK) { SourceLocation loc = (castRange.isValid() ? castRange.getBegin() : castExpr->getExprLoc()); @@ -3924,13 +3933,13 @@ diagnoseObjCARCConversion(Sema &S, SourceRange castRange, << castType << castRange << castExpr->getSourceRange(); - bool br = S.isKnownName("CFBridgingRelease"); + bool br = S.ObjC().isKnownName("CFBridgingRelease"); ACCResult CreateRule = ARCCastChecker(S.Context, exprACTC, castACTC, true).Visit(castExpr); assert(CreateRule != ACC_bottom && "This cast should already be accepted."); if (CreateRule != ACC_plusOne) { - auto DiagB = (CCK != Sema::CCK_OtherCast) + auto DiagB = (CCK != CheckedConversionKind::OtherCast) ? S.Diag(noteLoc, diag::note_arc_bridge) : S.Diag(noteLoc, diag::note_arc_cstyle_bridge); @@ -3940,7 +3949,7 @@ diagnoseObjCARCConversion(Sema &S, SourceRange castRange, } if (CreateRule != ACC_plusZero) { - auto DiagB = (CCK == Sema::CCK_OtherCast && !br) + auto DiagB = (CCK == CheckedConversionKind::OtherCast && !br) ? S.Diag(noteLoc, diag::note_arc_cstyle_bridge_transfer) << castExprType : S.Diag(br ? castExpr->getExprLoc() : noteLoc, @@ -3957,7 +3966,7 @@ diagnoseObjCARCConversion(Sema &S, SourceRange castRange, // Bridge from a CF type to an ARC type. if (exprACTC == ACTC_retainable && isAnyRetainable(castACTC)) { - bool br = S.isKnownName("CFBridgingRetain"); + bool br = S.ObjC().isKnownName("CFBridgingRetain"); S.Diag(loc, diag::err_arc_cast_requires_bridge) << convKindForDiag << unsigned(castExprType->isBlockPointerType()) // of ObjC|block type @@ -3971,7 +3980,7 @@ diagnoseObjCARCConversion(Sema &S, SourceRange castRange, assert(CreateRule != ACC_bottom && "This cast should already be accepted."); if (CreateRule != ACC_plusOne) { - auto DiagB = (CCK != Sema::CCK_OtherCast) + auto DiagB = (CCK != CheckedConversionKind::OtherCast) ? S.Diag(noteLoc, diag::note_arc_bridge) : S.Diag(noteLoc, diag::note_arc_cstyle_bridge); addFixitForObjCARCConversion(S, DiagB, CCK, afterLParen, @@ -3980,7 +3989,7 @@ diagnoseObjCARCConversion(Sema &S, SourceRange castRange, } if (CreateRule != ACC_plusZero) { - auto DiagB = (CCK == Sema::CCK_OtherCast && !br) + auto DiagB = (CCK == CheckedConversionKind::OtherCast && !br) ? S.Diag(noteLoc, diag::note_arc_cstyle_bridge_retained) << castType : S.Diag(br ? castExpr->getExprLoc() : noteLoc, @@ -4133,7 +4142,7 @@ static bool CheckObjCBridgeCFCast(Sema &S, QualType castType, Expr *castExpr, return true; } -void Sema::CheckTollFreeBridgeCast(QualType castType, Expr *castExpr) { +void SemaObjC::CheckTollFreeBridgeCast(QualType castType, Expr *castExpr) { if (!getLangOpts().ObjC) return; // warn in presence of __bridge casting to or from a toll free bridge cast. @@ -4141,49 +4150,47 @@ void Sema::CheckTollFreeBridgeCast(QualType castType, Expr *castExpr) { ARCConversionTypeClass castACTC = classifyTypeForARCConversion(castType); if (castACTC == ACTC_retainable && exprACTC == ACTC_coreFoundation) { bool HasObjCBridgeAttr; - bool ObjCBridgeAttrWillNotWarn = - CheckObjCBridgeNSCast<ObjCBridgeAttr>(*this, castType, castExpr, HasObjCBridgeAttr, - false); + bool ObjCBridgeAttrWillNotWarn = CheckObjCBridgeNSCast<ObjCBridgeAttr>( + SemaRef, castType, castExpr, HasObjCBridgeAttr, false); if (ObjCBridgeAttrWillNotWarn && HasObjCBridgeAttr) return; bool HasObjCBridgeMutableAttr; bool ObjCBridgeMutableAttrWillNotWarn = - CheckObjCBridgeNSCast<ObjCBridgeMutableAttr>(*this, castType, castExpr, - HasObjCBridgeMutableAttr, false); + CheckObjCBridgeNSCast<ObjCBridgeMutableAttr>( + SemaRef, castType, castExpr, HasObjCBridgeMutableAttr, false); if (ObjCBridgeMutableAttrWillNotWarn && HasObjCBridgeMutableAttr) return; if (HasObjCBridgeAttr) - CheckObjCBridgeNSCast<ObjCBridgeAttr>(*this, castType, castExpr, HasObjCBridgeAttr, - true); + CheckObjCBridgeNSCast<ObjCBridgeAttr>(SemaRef, castType, castExpr, + HasObjCBridgeAttr, true); else if (HasObjCBridgeMutableAttr) - CheckObjCBridgeNSCast<ObjCBridgeMutableAttr>(*this, castType, castExpr, - HasObjCBridgeMutableAttr, true); + CheckObjCBridgeNSCast<ObjCBridgeMutableAttr>( + SemaRef, castType, castExpr, HasObjCBridgeMutableAttr, true); } else if (castACTC == ACTC_coreFoundation && exprACTC == ACTC_retainable) { bool HasObjCBridgeAttr; - bool ObjCBridgeAttrWillNotWarn = - CheckObjCBridgeCFCast<ObjCBridgeAttr>(*this, castType, castExpr, HasObjCBridgeAttr, - false); + bool ObjCBridgeAttrWillNotWarn = CheckObjCBridgeCFCast<ObjCBridgeAttr>( + SemaRef, castType, castExpr, HasObjCBridgeAttr, false); if (ObjCBridgeAttrWillNotWarn && HasObjCBridgeAttr) return; bool HasObjCBridgeMutableAttr; bool ObjCBridgeMutableAttrWillNotWarn = - CheckObjCBridgeCFCast<ObjCBridgeMutableAttr>(*this, castType, castExpr, - HasObjCBridgeMutableAttr, false); + CheckObjCBridgeCFCast<ObjCBridgeMutableAttr>( + SemaRef, castType, castExpr, HasObjCBridgeMutableAttr, false); if (ObjCBridgeMutableAttrWillNotWarn && HasObjCBridgeMutableAttr) return; if (HasObjCBridgeAttr) - CheckObjCBridgeCFCast<ObjCBridgeAttr>(*this, castType, castExpr, HasObjCBridgeAttr, - true); + CheckObjCBridgeCFCast<ObjCBridgeAttr>(SemaRef, castType, castExpr, + HasObjCBridgeAttr, true); else if (HasObjCBridgeMutableAttr) - CheckObjCBridgeCFCast<ObjCBridgeMutableAttr>(*this, castType, castExpr, - HasObjCBridgeMutableAttr, true); + CheckObjCBridgeCFCast<ObjCBridgeMutableAttr>( + SemaRef, castType, castExpr, HasObjCBridgeMutableAttr, true); } } -void Sema::CheckObjCBridgeRelatedCast(QualType castType, Expr *castExpr) { +void SemaObjC::CheckObjCBridgeRelatedCast(QualType castType, Expr *castExpr) { QualType SrcType = castExpr->getType(); if (ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(castExpr)) { if (PRE->isExplicitProperty()) { @@ -4204,8 +4211,8 @@ void Sema::CheckObjCBridgeRelatedCast(QualType castType, Expr *castExpr) { castExpr); } -bool Sema::CheckTollFreeBridgeStaticCast(QualType castType, Expr *castExpr, - CastKind &Kind) { +bool SemaObjC::CheckTollFreeBridgeStaticCast(QualType castType, Expr *castExpr, + CastKind &Kind) { if (!getLangOpts().ObjC) return false; ARCConversionTypeClass exprACTC = @@ -4221,13 +4228,12 @@ bool Sema::CheckTollFreeBridgeStaticCast(QualType castType, Expr *castExpr, return false; } -bool Sema::checkObjCBridgeRelatedComponents(SourceLocation Loc, - QualType DestType, QualType SrcType, - ObjCInterfaceDecl *&RelatedClass, - ObjCMethodDecl *&ClassMethod, - ObjCMethodDecl *&InstanceMethod, - TypedefNameDecl *&TDNDecl, - bool CfToNs, bool Diagnose) { +bool SemaObjC::checkObjCBridgeRelatedComponents( + SourceLocation Loc, QualType DestType, QualType SrcType, + ObjCInterfaceDecl *&RelatedClass, ObjCMethodDecl *&ClassMethod, + ObjCMethodDecl *&InstanceMethod, TypedefNameDecl *&TDNDecl, bool CfToNs, + bool Diagnose) { + ASTContext &Context = getASTContext(); QualType T = CfToNs ? SrcType : DestType; ObjCBridgeRelatedAttr *ObjCBAttr = ObjCBridgeRelatedAttrFromType(T, TDNDecl); if (!ObjCBAttr) @@ -4240,9 +4246,9 @@ bool Sema::checkObjCBridgeRelatedComponents(SourceLocation Loc, return false; NamedDecl *Target = nullptr; // Check for an existing type with this name. - LookupResult R(*this, DeclarationName(RCId), SourceLocation(), + LookupResult R(SemaRef, DeclarationName(RCId), SourceLocation(), Sema::LookupOrdinaryName); - if (!LookupName(R, TUScope)) { + if (!SemaRef.LookupName(R, SemaRef.TUScope)) { if (Diagnose) { Diag(Loc, diag::err_objc_bridged_related_invalid_class) << RCId << SrcType << DestType; @@ -4294,10 +4300,12 @@ bool Sema::checkObjCBridgeRelatedComponents(SourceLocation Loc, return true; } -bool -Sema::CheckObjCBridgeRelatedConversions(SourceLocation Loc, - QualType DestType, QualType SrcType, - Expr *&SrcExpr, bool Diagnose) { +bool SemaObjC::CheckObjCBridgeRelatedConversions(SourceLocation Loc, + QualType DestType, + QualType SrcType, + Expr *&SrcExpr, + bool Diagnose) { + ASTContext &Context = getASTContext(); ARCConversionTypeClass rhsExprACTC = classifyTypeForARCConversion(SrcType); ARCConversionTypeClass lhsExprACTC = classifyTypeForARCConversion(DestType); bool CfToNs = (rhsExprACTC == ACTC_coreFoundation && lhsExprACTC == ACTC_retainable); @@ -4323,7 +4331,7 @@ Sema::CheckObjCBridgeRelatedConversions(SourceLocation Loc, ExpressionString += " "; ExpressionString += ClassMethod->getSelector().getAsString(); SourceLocation SrcExprEndLoc = - getLocForEndOfToken(SrcExpr->getEndLoc()); + SemaRef.getLocForEndOfToken(SrcExpr->getEndLoc()); // Provide a fixit: [RelatedClass ClassMethod SrcExpr] Diag(Loc, diag::err_objc_bridged_related_known_method) << SrcType << DestType << ClassMethod->getSelector() << false @@ -4351,7 +4359,7 @@ Sema::CheckObjCBridgeRelatedConversions(SourceLocation Loc, if (Diagnose) { std::string ExpressionString; SourceLocation SrcExprEndLoc = - getLocForEndOfToken(SrcExpr->getEndLoc()); + SemaRef.getLocForEndOfToken(SrcExpr->getEndLoc()); if (InstanceMethod->isPropertyAccessor()) if (const ObjCPropertyDecl *PDecl = InstanceMethod->findPropertyDecl()) { @@ -4387,11 +4395,12 @@ Sema::CheckObjCBridgeRelatedConversions(SourceLocation Loc, return false; } -Sema::ARCConversionResult -Sema::CheckObjCConversion(SourceRange castRange, QualType castType, - Expr *&castExpr, CheckedConversionKind CCK, - bool Diagnose, bool DiagnoseCFAudited, - BinaryOperatorKind Opc) { +SemaObjC::ARCConversionResult +SemaObjC::CheckObjCConversion(SourceRange castRange, QualType castType, + Expr *&castExpr, CheckedConversionKind CCK, + bool Diagnose, bool DiagnoseCFAudited, + BinaryOperatorKind Opc) { + ASTContext &Context = getASTContext(); QualType castExprType = castExpr->getType(); // For the purposes of the classification, we assume reference types @@ -4406,7 +4415,8 @@ Sema::CheckObjCConversion(SourceRange castRange, QualType castType, // Check for viability and report error if casting an rvalue to a // life-time qualifier. if (castACTC == ACTC_retainable && - (CCK == CCK_CStyleCast || CCK == CCK_OtherCast) && + (CCK == CheckedConversionKind::CStyleCast || + CCK == CheckedConversionKind::OtherCast) && castType != castExprType) { const Type *DT = castType.getTypePtr(); QualType QDT = castType; @@ -4451,11 +4461,11 @@ Sema::CheckObjCConversion(SourceRange castRange, QualType castType, // pointers too, but only when the conversions are explicit. if (exprACTC == ACTC_indirectRetainable && (castACTC == ACTC_voidPtr || - (castACTC == ACTC_coreFoundation && isCast(CCK)))) + (castACTC == ACTC_coreFoundation && SemaRef.isCast(CCK)))) return ACR_okay; if (castACTC == ACTC_indirectRetainable && (exprACTC == ACTC_voidPtr || exprACTC == ACTC_coreFoundation) && - isCast(CCK)) + SemaRef.isCast(CCK)) return ACR_okay; switch (ARCCastChecker(Context, exprACTC, castACTC, false).Visit(castExpr)) { @@ -4473,14 +4483,15 @@ Sema::CheckObjCConversion(SourceRange castRange, QualType castType, castExpr = ImplicitCastExpr::Create(Context, castExpr->getType(), CK_ARCConsumeObject, castExpr, nullptr, VK_PRValue, FPOptionsOverride()); - Cleanup.setExprNeedsCleanups(true); + SemaRef.Cleanup.setExprNeedsCleanups(true); return ACR_okay; } // If this is a non-implicit cast from id or block type to a // CoreFoundation type, delay complaining in case the cast is used // in an acceptable context. - if (exprACTC == ACTC_retainable && isAnyRetainable(castACTC) && isCast(CCK)) + if (exprACTC == ACTC_retainable && isAnyRetainable(castACTC) && + SemaRef.isCast(CCK)) return ACR_unbridged; // Issue a diagnostic about a missing @-sign when implicit casting a cstring @@ -4499,8 +4510,8 @@ Sema::CheckObjCConversion(SourceRange castRange, QualType castType, !(exprACTC == ACTC_voidPtr && castACTC == ACTC_retainable && (Opc == BO_NE || Opc == BO_EQ))) { if (Diagnose) - diagnoseObjCARCConversion(*this, castRange, castType, castACTC, castExpr, - castExpr, exprACTC, CCK); + diagnoseObjCARCConversion(SemaRef, castRange, castType, castACTC, + castExpr, castExpr, exprACTC, CCK); return ACR_error; } return ACR_okay; @@ -4508,7 +4519,7 @@ Sema::CheckObjCConversion(SourceRange castRange, QualType castType, /// Given that we saw an expression with the ARCUnbridgedCastTy /// placeholder type, complain bitterly. -void Sema::diagnoseARCUnbridgedCast(Expr *e) { +void SemaObjC::diagnoseARCUnbridgedCast(Expr *e) { // We expect the spurious ImplicitCastExpr to already have been stripped. assert(!e->hasPlaceholderType(BuiltinType::ARCUnbridgedCast)); CastExpr *realCast = cast<CastExpr>(e->IgnoreParens()); @@ -4520,11 +4531,11 @@ void Sema::diagnoseARCUnbridgedCast(Expr *e) { if (CStyleCastExpr *cast = dyn_cast<CStyleCastExpr>(realCast)) { castRange = SourceRange(cast->getLParenLoc(), cast->getRParenLoc()); castType = cast->getTypeAsWritten(); - CCK = CCK_CStyleCast; + CCK = CheckedConversionKind::CStyleCast; } else if (ExplicitCastExpr *cast = dyn_cast<ExplicitCastExpr>(realCast)) { castRange = cast->getTypeInfoAsWritten()->getTypeLoc().getSourceRange(); castType = cast->getTypeAsWritten(); - CCK = CCK_OtherCast; + CCK = CheckedConversionKind::OtherCast; } else { llvm_unreachable("Unexpected ImplicitCastExpr"); } @@ -4535,14 +4546,15 @@ void Sema::diagnoseARCUnbridgedCast(Expr *e) { Expr *castExpr = realCast->getSubExpr(); assert(classifyTypeForARCConversion(castExpr->getType()) == ACTC_retainable); - diagnoseObjCARCConversion(*this, castRange, castType, castACTC, - castExpr, realCast, ACTC_retainable, CCK); + diagnoseObjCARCConversion(SemaRef, castRange, castType, castACTC, castExpr, + realCast, ACTC_retainable, CCK); } /// stripARCUnbridgedCast - Given an expression of ARCUnbridgedCast /// type, remove the placeholder cast. -Expr *Sema::stripARCUnbridgedCast(Expr *e) { +Expr *SemaObjC::stripARCUnbridgedCast(Expr *e) { assert(e->hasPlaceholderType(BuiltinType::ARCUnbridgedCast)); + ASTContext &Context = getASTContext(); if (ParenExpr *pe = dyn_cast<ParenExpr>(e)) { Expr *sub = stripARCUnbridgedCast(pe->getSubExpr()); @@ -4553,7 +4565,7 @@ Expr *Sema::stripARCUnbridgedCast(Expr *e) { return UnaryOperator::Create(Context, sub, UO_Extension, sub->getType(), sub->getValueKind(), sub->getObjectKind(), uo->getOperatorLoc(), false, - CurFPFeatureOverrides()); + SemaRef.CurFPFeatureOverrides()); } else if (GenericSelectionExpr *gse = dyn_cast<GenericSelectionExpr>(e)) { assert(!gse->isResultDependent()); assert(!gse->isTypePredicate()); @@ -4581,8 +4593,9 @@ Expr *Sema::stripARCUnbridgedCast(Expr *e) { } } -bool Sema::CheckObjCARCUnavailableWeakConversion(QualType castType, - QualType exprType) { +bool SemaObjC::CheckObjCARCUnavailableWeakConversion(QualType castType, + QualType exprType) { + ASTContext &Context = getASTContext(); QualType canCastType = Context.getCanonicalType(castType).getUnqualifiedType(); QualType canExprType = @@ -4635,12 +4648,13 @@ static Expr *maybeUndoReclaimObject(Expr *e) { return e; } -ExprResult Sema::BuildObjCBridgedCast(SourceLocation LParenLoc, - ObjCBridgeCastKind Kind, - SourceLocation BridgeKeywordLoc, - TypeSourceInfo *TSInfo, - Expr *SubExpr) { - ExprResult SubResult = UsualUnaryConversions(SubExpr); +ExprResult SemaObjC::BuildObjCBridgedCast(SourceLocation LParenLoc, + ObjCBridgeCastKind Kind, + SourceLocation BridgeKeywordLoc, + TypeSourceInfo *TSInfo, + Expr *SubExpr) { + ASTContext &Context = getASTContext(); + ExprResult SubResult = SemaRef.UsualUnaryConversions(SubExpr); if (SubResult.isInvalid()) return ExprError(); SubExpr = SubResult.get(); @@ -4738,7 +4752,7 @@ ExprResult Sema::BuildObjCBridgedCast(SourceLocation LParenLoc, TSInfo, SubExpr); if (MustConsume) { - Cleanup.setExprNeedsCleanups(true); + SemaRef.Cleanup.setExprNeedsCleanups(true); Result = ImplicitCastExpr::Create(Context, T, CK_ARCConsumeObject, Result, nullptr, VK_PRValue, FPOptionsOverride()); } @@ -4746,15 +4760,15 @@ ExprResult Sema::BuildObjCBridgedCast(SourceLocation LParenLoc, return Result; } -ExprResult Sema::ActOnObjCBridgedCast(Scope *S, - SourceLocation LParenLoc, - ObjCBridgeCastKind Kind, - SourceLocation BridgeKeywordLoc, - ParsedType Type, - SourceLocation RParenLoc, - Expr *SubExpr) { +ExprResult SemaObjC::ActOnObjCBridgedCast(Scope *S, SourceLocation LParenLoc, + ObjCBridgeCastKind Kind, + SourceLocation BridgeKeywordLoc, + ParsedType Type, + SourceLocation RParenLoc, + Expr *SubExpr) { + ASTContext &Context = getASTContext(); TypeSourceInfo *TSInfo = nullptr; - QualType T = GetTypeFromParser(Type, &TSInfo); + QualType T = SemaRef.GetTypeFromParser(Type, &TSInfo); if (Kind == OBC_Bridge) CheckTollFreeBridgeCast(T, SubExpr); if (!TSInfo) @@ -4762,3 +4776,473 @@ ExprResult Sema::ActOnObjCBridgedCast(Scope *S, return BuildObjCBridgedCast(LParenLoc, Kind, BridgeKeywordLoc, TSInfo, SubExpr); } + +DeclResult SemaObjC::LookupIvarInObjCMethod(LookupResult &Lookup, Scope *S, + IdentifierInfo *II) { + SourceLocation Loc = Lookup.getNameLoc(); + ObjCMethodDecl *CurMethod = SemaRef.getCurMethodDecl(); + + // Check for error condition which is already reported. + if (!CurMethod) + return DeclResult(true); + + // There are two cases to handle here. 1) scoped lookup could have failed, + // in which case we should look for an ivar. 2) scoped lookup could have + // found a decl, but that decl is outside the current instance method (i.e. + // a global variable). In these two cases, we do a lookup for an ivar with + // this name, if the lookup sucedes, we replace it our current decl. + + // If we're in a class method, we don't normally want to look for + // ivars. But if we don't find anything else, and there's an + // ivar, that's an error. + bool IsClassMethod = CurMethod->isClassMethod(); + + bool LookForIvars; + if (Lookup.empty()) + LookForIvars = true; + else if (IsClassMethod) + LookForIvars = false; + else + LookForIvars = (Lookup.isSingleResult() && + Lookup.getFoundDecl()->isDefinedOutsideFunctionOrMethod()); + ObjCInterfaceDecl *IFace = nullptr; + if (LookForIvars) { + IFace = CurMethod->getClassInterface(); + ObjCInterfaceDecl *ClassDeclared; + ObjCIvarDecl *IV = nullptr; + if (IFace && (IV = IFace->lookupInstanceVariable(II, ClassDeclared))) { + // Diagnose using an ivar in a class method. + if (IsClassMethod) { + Diag(Loc, diag::err_ivar_use_in_class_method) << IV->getDeclName(); + return DeclResult(true); + } + + // Diagnose the use of an ivar outside of the declaring class. + if (IV->getAccessControl() == ObjCIvarDecl::Private && + !declaresSameEntity(ClassDeclared, IFace) && + !getLangOpts().DebuggerSupport) + Diag(Loc, diag::err_private_ivar_access) << IV->getDeclName(); + + // Success. + return IV; + } + } else if (CurMethod->isInstanceMethod()) { + // We should warn if a local variable hides an ivar. + if (ObjCInterfaceDecl *IFace = CurMethod->getClassInterface()) { + ObjCInterfaceDecl *ClassDeclared; + if (ObjCIvarDecl *IV = IFace->lookupInstanceVariable(II, ClassDeclared)) { + if (IV->getAccessControl() != ObjCIvarDecl::Private || + declaresSameEntity(IFace, ClassDeclared)) + Diag(Loc, diag::warn_ivar_use_hidden) << IV->getDeclName(); + } + } + } else if (Lookup.isSingleResult() && + Lookup.getFoundDecl()->isDefinedOutsideFunctionOrMethod()) { + // If accessing a stand-alone ivar in a class method, this is an error. + if (const ObjCIvarDecl *IV = + dyn_cast<ObjCIvarDecl>(Lookup.getFoundDecl())) { + Diag(Loc, diag::err_ivar_use_in_class_method) << IV->getDeclName(); + return DeclResult(true); + } + } + + // Didn't encounter an error, didn't find an ivar. + return DeclResult(false); +} + +ExprResult SemaObjC::LookupInObjCMethod(LookupResult &Lookup, Scope *S, + IdentifierInfo *II, + bool AllowBuiltinCreation) { + // FIXME: Integrate this lookup step into LookupParsedName. + DeclResult Ivar = LookupIvarInObjCMethod(Lookup, S, II); + if (Ivar.isInvalid()) + return ExprError(); + if (Ivar.isUsable()) + return BuildIvarRefExpr(S, Lookup.getNameLoc(), + cast<ObjCIvarDecl>(Ivar.get())); + + if (Lookup.empty() && II && AllowBuiltinCreation) + SemaRef.LookupBuiltin(Lookup); + + // Sentinel value saying that we didn't do anything special. + return ExprResult(false); +} + +ExprResult SemaObjC::BuildIvarRefExpr(Scope *S, SourceLocation Loc, + ObjCIvarDecl *IV) { + ASTContext &Context = getASTContext(); + ObjCMethodDecl *CurMethod = SemaRef.getCurMethodDecl(); + assert(CurMethod && CurMethod->isInstanceMethod() && + "should not reference ivar from this context"); + + ObjCInterfaceDecl *IFace = CurMethod->getClassInterface(); + assert(IFace && "should not reference ivar from this context"); + + // If we're referencing an invalid decl, just return this as a silent + // error node. The error diagnostic was already emitted on the decl. + if (IV->isInvalidDecl()) + return ExprError(); + + // Check if referencing a field with __attribute__((deprecated)). + if (SemaRef.DiagnoseUseOfDecl(IV, Loc)) + return ExprError(); + + // FIXME: This should use a new expr for a direct reference, don't + // turn this into Self->ivar, just return a BareIVarExpr or something. + IdentifierInfo &II = Context.Idents.get("self"); + UnqualifiedId SelfName; + SelfName.setImplicitSelfParam(&II); + CXXScopeSpec SelfScopeSpec; + SourceLocation TemplateKWLoc; + ExprResult SelfExpr = + SemaRef.ActOnIdExpression(S, SelfScopeSpec, TemplateKWLoc, SelfName, + /*HasTrailingLParen=*/false, + /*IsAddressOfOperand=*/false); + if (SelfExpr.isInvalid()) + return ExprError(); + + SelfExpr = SemaRef.DefaultLvalueConversion(SelfExpr.get()); + if (SelfExpr.isInvalid()) + return ExprError(); + + SemaRef.MarkAnyDeclReferenced(Loc, IV, true); + + ObjCMethodFamily MF = CurMethod->getMethodFamily(); + if (MF != OMF_init && MF != OMF_dealloc && MF != OMF_finalize && + !IvarBacksCurrentMethodAccessor(IFace, CurMethod, IV)) + Diag(Loc, diag::warn_direct_ivar_access) << IV->getDeclName(); + + ObjCIvarRefExpr *Result = new (Context) + ObjCIvarRefExpr(IV, IV->getUsageType(SelfExpr.get()->getType()), Loc, + IV->getLocation(), SelfExpr.get(), true, true); + + if (IV->getType().getObjCLifetime() == Qualifiers::OCL_Weak) { + if (!SemaRef.isUnevaluatedContext() && + !getDiagnostics().isIgnored(diag::warn_arc_repeated_use_of_weak, Loc)) + SemaRef.getCurFunction()->recordUseOfWeak(Result); + } + if (getLangOpts().ObjCAutoRefCount && !SemaRef.isUnevaluatedContext()) + if (const BlockDecl *BD = SemaRef.CurContext->getInnermostBlockDecl()) + SemaRef.ImplicitlyRetainedSelfLocs.push_back({Loc, BD}); + + return Result; +} + +QualType SemaObjC::FindCompositeObjCPointerType(ExprResult &LHS, + ExprResult &RHS, + SourceLocation QuestionLoc) { + ASTContext &Context = getASTContext(); + QualType LHSTy = LHS.get()->getType(); + QualType RHSTy = RHS.get()->getType(); + + // Handle things like Class and struct objc_class*. Here we case the result + // to the pseudo-builtin, because that will be implicitly cast back to the + // redefinition type if an attempt is made to access its fields. + if (LHSTy->isObjCClassType() && + (Context.hasSameType(RHSTy, Context.getObjCClassRedefinitionType()))) { + RHS = SemaRef.ImpCastExprToType(RHS.get(), LHSTy, + CK_CPointerToObjCPointerCast); + return LHSTy; + } + if (RHSTy->isObjCClassType() && + (Context.hasSameType(LHSTy, Context.getObjCClassRedefinitionType()))) { + LHS = SemaRef.ImpCastExprToType(LHS.get(), RHSTy, + CK_CPointerToObjCPointerCast); + return RHSTy; + } + // And the same for struct objc_object* / id + if (LHSTy->isObjCIdType() && + (Context.hasSameType(RHSTy, Context.getObjCIdRedefinitionType()))) { + RHS = SemaRef.ImpCastExprToType(RHS.get(), LHSTy, + CK_CPointerToObjCPointerCast); + return LHSTy; + } + if (RHSTy->isObjCIdType() && + (Context.hasSameType(LHSTy, Context.getObjCIdRedefinitionType()))) { + LHS = SemaRef.ImpCastExprToType(LHS.get(), RHSTy, + CK_CPointerToObjCPointerCast); + return RHSTy; + } + // And the same for struct objc_selector* / SEL + if (Context.isObjCSelType(LHSTy) && + (Context.hasSameType(RHSTy, Context.getObjCSelRedefinitionType()))) { + RHS = SemaRef.ImpCastExprToType(RHS.get(), LHSTy, CK_BitCast); + return LHSTy; + } + if (Context.isObjCSelType(RHSTy) && + (Context.hasSameType(LHSTy, Context.getObjCSelRedefinitionType()))) { + LHS = SemaRef.ImpCastExprToType(LHS.get(), RHSTy, CK_BitCast); + return RHSTy; + } + // Check constraints for Objective-C object pointers types. + if (LHSTy->isObjCObjectPointerType() && RHSTy->isObjCObjectPointerType()) { + + if (Context.getCanonicalType(LHSTy) == Context.getCanonicalType(RHSTy)) { + // Two identical object pointer types are always compatible. + return LHSTy; + } + const ObjCObjectPointerType *LHSOPT = + LHSTy->castAs<ObjCObjectPointerType>(); + const ObjCObjectPointerType *RHSOPT = + RHSTy->castAs<ObjCObjectPointerType>(); + QualType compositeType = LHSTy; + + // If both operands are interfaces and either operand can be + // assigned to the other, use that type as the composite + // type. This allows + // xxx ? (A*) a : (B*) b + // where B is a subclass of A. + // + // Additionally, as for assignment, if either type is 'id' + // allow silent coercion. Finally, if the types are + // incompatible then make sure to use 'id' as the composite + // type so the result is acceptable for sending messages to. + + // FIXME: Consider unifying with 'areComparableObjCPointerTypes'. + // It could return the composite type. + if (!(compositeType = Context.areCommonBaseCompatible(LHSOPT, RHSOPT)) + .isNull()) { + // Nothing more to do. + } else if (Context.canAssignObjCInterfaces(LHSOPT, RHSOPT)) { + compositeType = RHSOPT->isObjCBuiltinType() ? RHSTy : LHSTy; + } else if (Context.canAssignObjCInterfaces(RHSOPT, LHSOPT)) { + compositeType = LHSOPT->isObjCBuiltinType() ? LHSTy : RHSTy; + } else if ((LHSOPT->isObjCQualifiedIdType() || + RHSOPT->isObjCQualifiedIdType()) && + Context.ObjCQualifiedIdTypesAreCompatible(LHSOPT, RHSOPT, + true)) { + // Need to handle "id<xx>" explicitly. + // GCC allows qualified id and any Objective-C type to devolve to + // id. Currently localizing to here until clear this should be + // part of ObjCQualifiedIdTypesAreCompatible. + compositeType = Context.getObjCIdType(); + } else if (LHSTy->isObjCIdType() || RHSTy->isObjCIdType()) { + compositeType = Context.getObjCIdType(); + } else { + Diag(QuestionLoc, diag::ext_typecheck_cond_incompatible_operands) + << LHSTy << RHSTy << LHS.get()->getSourceRange() + << RHS.get()->getSourceRange(); + QualType incompatTy = Context.getObjCIdType(); + LHS = SemaRef.ImpCastExprToType(LHS.get(), incompatTy, CK_BitCast); + RHS = SemaRef.ImpCastExprToType(RHS.get(), incompatTy, CK_BitCast); + return incompatTy; + } + // The object pointer types are compatible. + LHS = SemaRef.ImpCastExprToType(LHS.get(), compositeType, CK_BitCast); + RHS = SemaRef.ImpCastExprToType(RHS.get(), compositeType, CK_BitCast); + return compositeType; + } + // Check Objective-C object pointer types and 'void *' + if (LHSTy->isVoidPointerType() && RHSTy->isObjCObjectPointerType()) { + if (getLangOpts().ObjCAutoRefCount) { + // ARC forbids the implicit conversion of object pointers to 'void *', + // so these types are not compatible. + Diag(QuestionLoc, diag::err_cond_voidptr_arc) + << LHSTy << RHSTy << LHS.get()->getSourceRange() + << RHS.get()->getSourceRange(); + LHS = RHS = true; + return QualType(); + } + QualType lhptee = LHSTy->castAs<PointerType>()->getPointeeType(); + QualType rhptee = RHSTy->castAs<ObjCObjectPointerType>()->getPointeeType(); + QualType destPointee = + Context.getQualifiedType(lhptee, rhptee.getQualifiers()); + QualType destType = Context.getPointerType(destPointee); + // Add qualifiers if necessary. + LHS = SemaRef.ImpCastExprToType(LHS.get(), destType, CK_NoOp); + // Promote to void*. + RHS = SemaRef.ImpCastExprToType(RHS.get(), destType, CK_BitCast); + return destType; + } + if (LHSTy->isObjCObjectPointerType() && RHSTy->isVoidPointerType()) { + if (getLangOpts().ObjCAutoRefCount) { + // ARC forbids the implicit conversion of object pointers to 'void *', + // so these types are not compatible. + Diag(QuestionLoc, diag::err_cond_voidptr_arc) + << LHSTy << RHSTy << LHS.get()->getSourceRange() + << RHS.get()->getSourceRange(); + LHS = RHS = true; + return QualType(); + } + QualType lhptee = LHSTy->castAs<ObjCObjectPointerType>()->getPointeeType(); + QualType rhptee = RHSTy->castAs<PointerType>()->getPointeeType(); + QualType destPointee = + Context.getQualifiedType(rhptee, lhptee.getQualifiers()); + QualType destType = Context.getPointerType(destPointee); + // Add qualifiers if necessary. + RHS = SemaRef.ImpCastExprToType(RHS.get(), destType, CK_NoOp); + // Promote to void*. + LHS = SemaRef.ImpCastExprToType(LHS.get(), destType, CK_BitCast); + return destType; + } + return QualType(); +} + +bool SemaObjC::CheckConversionToObjCLiteral(QualType DstType, Expr *&Exp, + bool Diagnose) { + if (!getLangOpts().ObjC) + return false; + + const ObjCObjectPointerType *PT = DstType->getAs<ObjCObjectPointerType>(); + if (!PT) + return false; + const ObjCInterfaceDecl *ID = PT->getInterfaceDecl(); + + // Ignore any parens, implicit casts (should only be + // array-to-pointer decays), and not-so-opaque values. The last is + // important for making this trigger for property assignments. + Expr *SrcExpr = Exp->IgnoreParenImpCasts(); + if (OpaqueValueExpr *OV = dyn_cast<OpaqueValueExpr>(SrcExpr)) + if (OV->getSourceExpr()) + SrcExpr = OV->getSourceExpr()->IgnoreParenImpCasts(); + + if (auto *SL = dyn_cast<StringLiteral>(SrcExpr)) { + if (!PT->isObjCIdType() && !(ID && ID->getIdentifier()->isStr("NSString"))) + return false; + if (!SL->isOrdinary()) + return false; + + if (Diagnose) { + Diag(SL->getBeginLoc(), diag::err_missing_atsign_prefix) + << /*string*/ 0 << FixItHint::CreateInsertion(SL->getBeginLoc(), "@"); + Exp = BuildObjCStringLiteral(SL->getBeginLoc(), SL).get(); + } + return true; + } + + if ((isa<IntegerLiteral>(SrcExpr) || isa<CharacterLiteral>(SrcExpr) || + isa<FloatingLiteral>(SrcExpr) || isa<ObjCBoolLiteralExpr>(SrcExpr) || + isa<CXXBoolLiteralExpr>(SrcExpr)) && + !SrcExpr->isNullPointerConstant(getASTContext(), + Expr::NPC_NeverValueDependent)) { + if (!ID || !ID->getIdentifier()->isStr("NSNumber")) + return false; + if (Diagnose) { + Diag(SrcExpr->getBeginLoc(), diag::err_missing_atsign_prefix) + << /*number*/ 1 + << FixItHint::CreateInsertion(SrcExpr->getBeginLoc(), "@"); + Expr *NumLit = + BuildObjCNumericLiteral(SrcExpr->getBeginLoc(), SrcExpr).get(); + if (NumLit) + Exp = NumLit; + } + return true; + } + + return false; +} + +/// ActOnObjCBoolLiteral - Parse {__objc_yes,__objc_no} literals. +ExprResult SemaObjC::ActOnObjCBoolLiteral(SourceLocation OpLoc, + tok::TokenKind Kind) { + assert((Kind == tok::kw___objc_yes || Kind == tok::kw___objc_no) && + "Unknown Objective-C Boolean value!"); + ASTContext &Context = getASTContext(); + QualType BoolT = Context.ObjCBuiltinBoolTy; + if (!Context.getBOOLDecl()) { + LookupResult Result(SemaRef, &Context.Idents.get("BOOL"), OpLoc, + Sema::LookupOrdinaryName); + if (SemaRef.LookupName(Result, SemaRef.getCurScope()) && + Result.isSingleResult()) { + NamedDecl *ND = Result.getFoundDecl(); + if (TypedefDecl *TD = dyn_cast<TypedefDecl>(ND)) + Context.setBOOLDecl(TD); + } + } + if (Context.getBOOLDecl()) + BoolT = Context.getBOOLType(); + return new (Context) + ObjCBoolLiteralExpr(Kind == tok::kw___objc_yes, BoolT, OpLoc); +} + +ExprResult SemaObjC::ActOnObjCAvailabilityCheckExpr( + llvm::ArrayRef<AvailabilitySpec> AvailSpecs, SourceLocation AtLoc, + SourceLocation RParen) { + ASTContext &Context = getASTContext(); + auto FindSpecVersion = + [&](StringRef Platform) -> std::optional<VersionTuple> { + auto Spec = llvm::find_if(AvailSpecs, [&](const AvailabilitySpec &Spec) { + return Spec.getPlatform() == Platform; + }); + // Transcribe the "ios" availability check to "maccatalyst" when compiling + // for "maccatalyst" if "maccatalyst" is not specified. + if (Spec == AvailSpecs.end() && Platform == "maccatalyst") { + Spec = llvm::find_if(AvailSpecs, [&](const AvailabilitySpec &Spec) { + return Spec.getPlatform() == "ios"; + }); + } + if (Spec == AvailSpecs.end()) + return std::nullopt; + return Spec->getVersion(); + }; + + VersionTuple Version; + if (auto MaybeVersion = + FindSpecVersion(Context.getTargetInfo().getPlatformName())) + Version = *MaybeVersion; + + // The use of `@available` in the enclosing context should be analyzed to + // warn when it's used inappropriately (i.e. not if(@available)). + if (FunctionScopeInfo *Context = SemaRef.getCurFunctionAvailabilityContext()) + Context->HasPotentialAvailabilityViolations = true; + + return new (Context) + ObjCAvailabilityCheckExpr(Version, AtLoc, RParen, Context.BoolTy); +} + +/// Prepare a conversion of the given expression to an ObjC object +/// pointer type. +CastKind SemaObjC::PrepareCastToObjCObjectPointer(ExprResult &E) { + QualType type = E.get()->getType(); + if (type->isObjCObjectPointerType()) { + return CK_BitCast; + } else if (type->isBlockPointerType()) { + SemaRef.maybeExtendBlockObject(E); + return CK_BlockPointerToObjCPointerCast; + } else { + assert(type->isPointerType()); + return CK_CPointerToObjCPointerCast; + } +} + +SemaObjC::ObjCLiteralKind SemaObjC::CheckLiteralKind(Expr *FromE) { + FromE = FromE->IgnoreParenImpCasts(); + switch (FromE->getStmtClass()) { + default: + break; + case Stmt::ObjCStringLiteralClass: + // "string literal" + return LK_String; + case Stmt::ObjCArrayLiteralClass: + // "array literal" + return LK_Array; + case Stmt::ObjCDictionaryLiteralClass: + // "dictionary literal" + return LK_Dictionary; + case Stmt::BlockExprClass: + return LK_Block; + case Stmt::ObjCBoxedExprClass: { + Expr *Inner = cast<ObjCBoxedExpr>(FromE)->getSubExpr()->IgnoreParens(); + switch (Inner->getStmtClass()) { + case Stmt::IntegerLiteralClass: + case Stmt::FloatingLiteralClass: + case Stmt::CharacterLiteralClass: + case Stmt::ObjCBoolLiteralExprClass: + case Stmt::CXXBoolLiteralExprClass: + // "numeric literal" + return LK_Numeric; + case Stmt::ImplicitCastExprClass: { + CastKind CK = cast<CastExpr>(Inner)->getCastKind(); + // Boolean literals can be represented by implicit casts. + if (CK == CK_IntegralToBoolean || CK == CK_IntegralCast) + return LK_Numeric; + break; + } + default: + break; + } + return LK_Boxed; + } + } + return LK_None; +} |