aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/clang/lib/Sema/SemaExprObjC.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/clang/lib/Sema/SemaExprObjC.cpp')
-rw-r--r--contrib/llvm-project/clang/lib/Sema/SemaExprObjC.cpp1398
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;
+}