From ff8677d4e4ba4df7a0b420b1af22664b373148e8 Mon Sep 17 00:00:00 2001 From: Vlad Serebrennikov Date: Wed, 17 Apr 2024 18:15:26 +0300 Subject: [PATCH 1/3] [clang] Introduce `SemaObjC` --- clang/include/clang/Parse/Parser.h | 9 +- clang/include/clang/Sema/Sema.h | 1002 +---------- clang/include/clang/Sema/SemaObjC.h | 1015 +++++++++++ clang/lib/ARCMigrate/Transforms.cpp | 5 +- clang/lib/Parse/ParseDecl.cpp | 5 +- clang/lib/Parse/ParseExpr.cpp | 9 +- clang/lib/Parse/ParseInit.cpp | 9 +- clang/lib/Parse/ParseObjc.cpp | 139 +- clang/lib/Parse/ParseStmt.cpp | 5 +- clang/lib/Sema/CMakeLists.txt | 1 + clang/lib/Sema/Sema.cpp | 14 +- clang/lib/Sema/SemaAPINotes.cpp | 3 +- clang/lib/Sema/SemaAttr.cpp | 16 - clang/lib/Sema/SemaAvailability.cpp | 7 +- clang/lib/Sema/SemaCast.cpp | 11 +- clang/lib/Sema/SemaChecking.cpp | 524 +----- clang/lib/Sema/SemaCodeComplete.cpp | 37 +- clang/lib/Sema/SemaDecl.cpp | 291 +--- clang/lib/Sema/SemaDeclAttr.cpp | 11 +- clang/lib/Sema/SemaDeclCXX.cpp | 58 +- clang/lib/Sema/SemaDeclObjC.cpp | 975 +++++++---- clang/lib/Sema/SemaExpr.cpp | 532 +----- clang/lib/Sema/SemaExprCXX.cpp | 13 +- clang/lib/Sema/SemaExprMember.cpp | 5 +- clang/lib/Sema/SemaExprObjC.cpp | 955 ++++++++--- clang/lib/Sema/SemaInit.cpp | 11 +- clang/lib/Sema/SemaLookup.cpp | 9 - clang/lib/Sema/SemaObjC.cpp | 1501 +++++++++++++++++ clang/lib/Sema/SemaObjCProperty.cpp | 139 +- clang/lib/Sema/SemaOverload.cpp | 76 +- clang/lib/Sema/SemaPseudoObject.cpp | 133 +- clang/lib/Sema/SemaStmt.cpp | 307 +--- .../lib/Sema/SemaTemplateInstantiateDecl.cpp | 3 +- clang/lib/Sema/SemaType.cpp | 464 +---- clang/lib/Sema/TreeTransform.h | 47 +- clang/lib/Serialization/ASTCommon.cpp | 2 +- clang/lib/Serialization/ASTReader.cpp | 13 +- clang/lib/Serialization/ASTWriter.cpp | 13 +- 38 files changed, 4290 insertions(+), 4079 deletions(-) create mode 100644 clang/include/clang/Sema/SemaObjC.h create mode 100644 clang/lib/Sema/SemaObjC.cpp diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index 23b268126de4e..2ba33bcc273d2 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -18,6 +18,7 @@ #include "clang/Lex/CodeCompletionHandler.h" #include "clang/Lex/Preprocessor.h" #include "clang/Sema/Sema.h" +#include "clang/Sema/SemaObjC.h" #include "clang/Sema/SemaOpenMP.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Frontend/OpenMP/OMPContext.h" @@ -421,7 +422,7 @@ class Parser : public CodeCompletionHandler { /// True if we are within an Objective-C container while parsing C-like decls. /// /// This is necessary because Sema thinks we have left the container - /// to parse the C-like decls, meaning Actions.getObjCDeclContext() will + /// to parse the C-like decls, meaning Actions.ObjC().getObjCDeclContext() will /// be NULL. bool ParsingInObjCContainer; @@ -473,7 +474,7 @@ class Parser : public CodeCompletionHandler { } ObjCContainerDecl *getObjCDeclContext() const { - return Actions.getObjCDeclContext(); + return Actions.ObjC().getObjCDeclContext(); } // Type forwarding. All of these are statically 'void*', but they may all be @@ -1059,11 +1060,11 @@ class Parser : public CodeCompletionHandler { : P(p), DC(p.getObjCDeclContext()), WithinObjCContainer(P.ParsingInObjCContainer, DC != nullptr) { if (DC) - P.Actions.ActOnObjCTemporaryExitContainerContext(DC); + P.Actions.ObjC().ActOnObjCTemporaryExitContainerContext(DC); } ~ObjCDeclContextSwitch() { if (DC) - P.Actions.ActOnObjCReenterContainerContext(DC); + P.Actions.ObjC().ActOnObjCReenterContainerContext(DC); } }; diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 1e89dfc58d92b..936fbffd3891e 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -152,18 +152,9 @@ typedef ArrayRef> ModuleIdPath; class ModuleLoader; class MultiLevelTemplateArgumentList; class NamedDecl; -class ObjCCategoryDecl; -class ObjCCategoryImplDecl; -class ObjCCompatibleAliasDecl; -class ObjCContainerDecl; -class ObjCImplDecl; class ObjCImplementationDecl; class ObjCInterfaceDecl; -class ObjCIvarDecl; -template class ObjCList; -class ObjCMessageExpr; class ObjCMethodDecl; -class ObjCPropertyDecl; class ObjCProtocolDecl; struct OverloadCandidate; enum class OverloadCandidateParamOrder : char; @@ -178,6 +169,7 @@ class PseudoObjectExpr; class QualType; class SemaCUDA; class SemaHLSL; +class SemaObjC; class SemaOpenACC; class SemaOpenMP; class SemaSYCL; @@ -489,12 +481,9 @@ class Sema final : public SemaBase { // 29. C++ Variadic Templates (SemaTemplateVariadic.cpp) // 30. Constraints and Concepts (SemaConcept.cpp) // 31. Types (SemaType.cpp) - // 32. ObjC Declarations (SemaDeclObjC.cpp) - // 33. ObjC Expressions (SemaExprObjC.cpp) - // 34. ObjC @property and @synthesize (SemaObjCProperty.cpp) - // 35. Code Completion (SemaCodeComplete.cpp) - // 36. FixIt Helpers (SemaFixItUtils.cpp) - // 37. Name Lookup for RISC-V Vector Intrinsic (SemaRISCVVectorLookup.cpp) + // 32. Code Completion (SemaCodeComplete.cpp) + // 33. FixIt Helpers (SemaFixItUtils.cpp) + // 34. Name Lookup for RISC-V Vector Intrinsic (SemaRISCVVectorLookup.cpp) /// \name Semantic Analysis /// Implementations are in Sema.cpp @@ -1005,6 +994,11 @@ class Sema final : public SemaBase { return *HLSLPtr; } + SemaObjC &ObjC() { + assert(ObjCPtr); + return *ObjCPtr; + } + SemaOpenACC &OpenACC() { assert(OpenACCPtr); return *OpenACCPtr; @@ -1020,6 +1014,9 @@ class Sema final : public SemaBase { return *SYCLPtr; } + /// Source of additional semantic information. + IntrusiveRefCntPtr ExternalSource; + protected: friend class Parser; friend class InitializationSequence; @@ -1034,9 +1031,6 @@ class Sema final : public SemaBase { Sema(const Sema &) = delete; void operator=(const Sema &) = delete; - /// Source of additional semantic information. - IntrusiveRefCntPtr ExternalSource; - /// The handler for the FileChanged preprocessor events. /// /// Used for diagnostics that implement custom semantic analysis for #include @@ -1052,6 +1046,7 @@ class Sema final : public SemaBase { std::unique_ptr CUDAPtr; std::unique_ptr HLSLPtr; + std::unique_ptr ObjCPtr; std::unique_ptr OpenACCPtr; std::unique_ptr OpenMPPtr; std::unique_ptr SYCLPtr; @@ -1634,11 +1629,6 @@ class Sema final : public SemaBase { void ActOnPragmaUnused(const Token &Identifier, Scope *curScope, SourceLocation PragmaLoc); - /// AddCFAuditedAttribute - Check whether we're currently within - /// '\#pragma clang arc_cf_code_audited' and, if so, consider adding - /// the appropriate attribute. - void AddCFAuditedAttribute(Decl *D); - void ActOnPragmaAttributeAttribute(ParsedAttr &Attribute, SourceLocation PragmaLoc, attr::ParsedSubjectMatchRuleSet Rules); @@ -1978,12 +1968,6 @@ class Sema final : public SemaBase { void CheckCastAlign(Expr *Op, QualType T, SourceRange TRange); - /// checkRetainCycles - Check whether an Objective-C message send - /// might create an obvious retain cycle. - void checkRetainCycles(ObjCMessageExpr *msg); - void checkRetainCycles(Expr *receiver, Expr *argument); - void checkRetainCycles(VarDecl *Var, Expr *Init); - /// checkUnsafeAssigns - Check whether +1 expr is being assigned /// to weak/__unsafe_unretained type. bool checkUnsafeAssigns(SourceLocation Loc, QualType LHS, Expr *RHS); @@ -2030,14 +2014,20 @@ class Sema final : public SemaBase { bool CheckHLSLBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); + void checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto, + const Expr *ThisArg, ArrayRef Args, + bool IsMemberFunction, SourceLocation Loc, SourceRange Range, + VariadicCallType CallType); + + void CheckTCBEnforcement(const SourceLocation CallExprLoc, + const NamedDecl *Callee); + private: void CheckArrayAccess(const Expr *BaseExpr, const Expr *IndexExpr, const ArraySubscriptExpr *ASE = nullptr, bool AllowOnePastEnd = true, bool IndexNegated = false); void CheckArrayAccess(const Expr *E); - bool CheckObjCMethodCall(ObjCMethodDecl *Method, SourceLocation loc, - ArrayRef Args); bool CheckPointerCall(NamedDecl *NDecl, CallExpr *TheCall, const FunctionProtoType *Proto); bool CheckOtherCall(CallExpr *TheCall, const FunctionProtoType *Proto); @@ -2050,12 +2040,6 @@ class Sema final : public SemaBase { void CheckArgAlignment(SourceLocation Loc, NamedDecl *FDecl, StringRef ParamName, QualType ArgTy, QualType ParamTy); - void checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto, - const Expr *ThisArg, ArrayRef Args, - bool IsMemberFunction, SourceLocation Loc, SourceRange Range, - VariadicCallType CallType); - - bool CheckObjCString(Expr *Arg); ExprResult CheckOSLogFormatStringArg(Expr *Arg); ExprResult CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID, @@ -2228,12 +2212,6 @@ class Sema final : public SemaBase { void CheckBitFieldInitialization(SourceLocation InitLoc, FieldDecl *Field, Expr *Init); - /// Check whether receiver is mutable ObjC container which - /// attempts to add itself into the container - void CheckObjCCircularContainer(ObjCMessageExpr *Message); - - void CheckTCBEnforcement(const SourceLocation CallExprLoc, - const NamedDecl *Callee); /// A map from magic value to type information. std::unique_ptr> @@ -2636,7 +2614,7 @@ class Sema final : public SemaBase { SmallVector ExternalDeclarations; /// Generally null except when we temporarily switch decl contexts, - /// like in \see ActOnObjCTemporaryExitContainerContext. + /// like in \see SemaObjC::ActOnObjCTemporaryExitContainerContext. DeclContext *OriginalLexicalContext; /// Is the module scope we are in a C++ Header Unit? @@ -2985,9 +2963,6 @@ class Sema final : public SemaBase { SourceLocation ExplicitThisLoc = {}); ParmVarDecl *BuildParmVarDeclForTypedef(DeclContext *DC, SourceLocation Loc, QualType T); - QualType AdjustParameterTypeForObjCAutoRefCount(QualType T, - SourceLocation NameLoc, - TypeSourceInfo *TSInfo); ParmVarDecl *CheckParameter(DeclContext *DC, SourceLocation StartLoc, SourceLocation NameLoc, const IdentifierInfo *Name, QualType T, @@ -3224,8 +3199,6 @@ class Sema final : public SemaBase { void ActOnLastBitfield(SourceLocation DeclStart, SmallVectorImpl &AllIvarDecls); - Decl *ActOnIvar(Scope *S, SourceLocation DeclStart, Declarator &D, - Expr *BitWidth, tok::ObjCKeywordKind visibility); // This is used for both record definitions and ObjC interface declarations. void ActOnFields(Scope *S, SourceLocation RecLoc, Decl *TagDecl, @@ -3247,8 +3220,6 @@ class Sema final : public SemaBase { /// Invoked when we enter a tag definition that we're skipping. SkippedDefinitionContext ActOnTagStartSkippedDefinition(Scope *S, Decl *TD); - void ActOnObjCContainerStartDefinition(ObjCContainerDecl *IDecl); - /// ActOnStartCXXMemberDeclarations - Invoked when we have parsed a /// C++ record definition's base-specifiers clause and are starting its /// member declarations. @@ -3265,15 +3236,6 @@ class Sema final : public SemaBase { void ActOnTagFinishSkippedDefinition(SkippedDefinitionContext Context); - void ActOnObjCContainerFinishDefinition(); - - /// Invoked when we must temporarily exit the objective-c container - /// scope for parsing/looking-up C constructs. - /// - /// Must be followed by a call to \see ActOnObjCReenterContainerContext - void ActOnObjCTemporaryExitContainerContext(ObjCContainerDecl *ObjCCtx); - void ActOnObjCReenterContainerContext(ObjCContainerDecl *ObjCCtx); - /// ActOnTagDefinitionError - Invoked when there was an unrecoverable /// error parsing the definition of a tag. void ActOnTagDefinitionError(Scope *S, Decl *TagDecl); @@ -3400,10 +3362,6 @@ class Sema final : public SemaBase { /// variable. void DiagnoseUnusedButSetDecl(const VarDecl *VD, DiagReceiverTy DiagReceiver); - ObjCInterfaceDecl *getObjCInterfaceDecl(const IdentifierInfo *&Id, - SourceLocation IdLoc, - bool TypoCorrection = false); - Scope *getNonFieldDeclScope(Scope *S); FunctionDecl *CreateBuiltin(IdentifierInfo *II, QualType Type, unsigned ID, @@ -3425,8 +3383,6 @@ class Sema final : public SemaBase { /// Look for a locally scoped extern "C" declaration by the given name. NamedDecl *findLocallyScopedExternCDecl(DeclarationName Name); - bool inferObjCARCLifetime(ValueDecl *decl); - void deduceOpenCLAddressSpace(ValueDecl *decl); static bool adjustContextForLocalExternDecl(DeclContext *&DC); @@ -3498,8 +3454,6 @@ class Sema final : public SemaBase { SourceLocation WeakNameLoc, SourceLocation AliasNameLoc); - ObjCContainerDecl *getObjCDeclContext() const; - /// Status of the function emission on the CUDA/HIP/OpenMP host/device attrs. enum class FunctionEmissionStatus { Emitted, @@ -4338,8 +4292,6 @@ class Sema final : public SemaBase { CXXConstructorDecl *Constructor, bool AnyErrors, ArrayRef Initializers = std::nullopt); - void SetIvarInitializers(ObjCImplementationDecl *ObjCImplementation); - /// MarkBaseAndMemberDestructorsReferenced - Given a record decl, /// mark all the non-trivial destructors of its members and bases as /// referenced. @@ -5389,14 +5341,6 @@ class Sema final : public SemaBase { DeclContext *LookupCtx = nullptr, TypoExpr **Out = nullptr); - DeclResult LookupIvarInObjCMethod(LookupResult &Lookup, Scope *S, - IdentifierInfo *II); - ExprResult BuildIvarRefExpr(Scope *S, SourceLocation Loc, ObjCIvarDecl *IV); - - ExprResult LookupInObjCMethod(LookupResult &LookUp, Scope *S, - IdentifierInfo *II, - bool AllowBuiltinCreation = false); - /// If \p D cannot be odr-used in the current expression evaluation context, /// return a reason explaining why. Otherwise, return NOUR_None. NonOdrUseReason getNonOdrUseReasonInCurrentContext(ValueDecl *D); @@ -5714,19 +5658,6 @@ class Sema final : public SemaBase { ArrayRef SubExprs, QualType T = QualType()); - // Note that LK_String is intentionally after the other literals, as - // this is used for diagnostics logic. - enum ObjCLiteralKind { - LK_Array, - LK_Dictionary, - LK_Numeric, - LK_Boxed, - LK_String, - LK_Block, - LK_None - }; - ObjCLiteralKind CheckLiteralKind(Expr *FromE); - ExprResult PerformObjectMemberConversion(Expr *From, NestedNameSpecifier *Qualifier, NamedDecl *FoundDecl, @@ -5762,14 +5693,6 @@ class Sema final : public SemaBase { bool IsInvalidSMECallConversion(QualType FromType, QualType ToType); - const DeclContext *getCurObjCLexicalContext() const { - const DeclContext *DC = getCurLexicalContext(); - // A category implicitly has the attribute of the interface. - if (const ObjCCategoryDecl *CatD = dyn_cast(DC)) - DC = CatD->getClassInterface(); - return DC; - } - /// Abstract base class used for diagnosing integer constant /// expression violations. class VerifyICEDiagnoser { @@ -5907,9 +5830,6 @@ class Sema final : public SemaBase { ExprResult &Cond, ExprResult &LHS, ExprResult &RHS, ExprValueKind &VK, ExprObjectKind &OK, SourceLocation QuestionLoc); - QualType FindCompositeObjCPointerType(ExprResult &LHS, ExprResult &RHS, - SourceLocation QuestionLoc); - bool DiagnoseConditionalForNull(const Expr *LHSExpr, const Expr *RHSExpr, SourceLocation QuestionLoc); @@ -6257,9 +6177,6 @@ class Sema final : public SemaBase { Expr *LHSExpr, ExprResult &RHS, SourceLocation Loc, QualType CompoundType, BinaryOperatorKind Opc); - bool CheckConversionToObjCLiteral(QualType DstType, Expr *&SrcExpr, - bool Diagnose = true); - /// To be used for checking whether the arguments being passed to /// function exceeds the number of parameters expected for it. static bool TooManyArguments(size_t NumParams, size_t NumArgs, @@ -6589,13 +6506,6 @@ class Sema final : public SemaBase { /// ActOnCXXBoolLiteral - Parse {true,false} literals. ExprResult ActOnCXXBoolLiteral(SourceLocation OpLoc, tok::TokenKind Kind); - /// ActOnObjCBoolLiteral - Parse {__objc_yes,__objc_no} literals. - ExprResult ActOnObjCBoolLiteral(SourceLocation OpLoc, tok::TokenKind Kind); - - ExprResult - ActOnObjCAvailabilityCheckExpr(llvm::ArrayRef AvailSpecs, - SourceLocation AtLoc, SourceLocation RParen); - /// ActOnCXXNullPtrLiteral - Parse 'nullptr'. ExprResult ActOnCXXNullPtrLiteral(SourceLocation Loc); @@ -7466,9 +7376,6 @@ class Sema final : public SemaBase { bool LookupParsedName(LookupResult &R, Scope *S, CXXScopeSpec *SS, bool AllowBuiltinCreation = false, bool EnteringContext = false); - ObjCProtocolDecl *LookupProtocol( - IdentifierInfo *II, SourceLocation IdLoc, - RedeclarationKind Redecl = RedeclarationKind::NotForRedeclaration); bool LookupInSuper(LookupResult &R, CXXRecordDecl *Class); void LookupOverloadedOperatorName(OverloadedOperatorKind Op, Scope *S, @@ -7497,6 +7404,20 @@ class Sema final : public SemaBase { /// visible at the specified location. void makeMergedDefinitionVisible(NamedDecl *ND); + /// Check ODR hashes for C/ObjC when merging types from modules. + /// Differently from C++, actually parse the body and reject in case + /// of a mismatch. + template ::value>> + bool ActOnDuplicateODRHashDefinition(T *Duplicate, T *Previous) { + if (Duplicate->getODRHash() != Previous->getODRHash()) + return false; + + // Make the previous decl visible. + makeMergedDefinitionVisible(Previous); + return true; + } + /// Get the set of additional modules that should be checked during /// name lookup. A module and its imports become visible when instanting a /// template defined within it. @@ -7962,8 +7883,6 @@ class Sema final : public SemaBase { bool &IncompatibleObjC); bool isObjCPointerConversion(QualType FromType, QualType ToType, QualType &ConvertedType, bool &IncompatibleObjC); - bool isObjCWritebackConversion(QualType FromType, QualType ToType, - QualType &ConvertedType); bool IsBlockPointerConversion(QualType FromType, QualType ToType, QualType &ConvertedType); @@ -8425,7 +8344,6 @@ class Sema final : public SemaBase { DeclAccessPair FoundDecl, FunctionDecl *Fn); -private: /// - Returns a selector which best matches given argument list or /// nullptr if none could be found ObjCMethodDecl *SelectBestMethod(Selector Sel, MultiExprArg Args, @@ -8446,10 +8364,6 @@ class Sema final : public SemaBase { public: void maybeExtendBlockObject(ExprResult &E); - CastKind PrepareCastToObjCObjectPointer(ExprResult &E); - - enum ObjCSubscriptKind { OS_Array, OS_Dictionary, OS_Error }; - ObjCSubscriptKind CheckSubscriptingKind(Expr *FromE); ExprResult checkPseudoObjectIncDec(Scope *S, SourceLocation OpLoc, UnaryOperatorKind Opcode, Expr *Op); @@ -8557,13 +8471,6 @@ class Sema final : public SemaBase { StmtResult ActOnForEachLValueExpr(Expr *E); - ExprResult CheckObjCForCollectionOperand(SourceLocation forLoc, - Expr *collection); - StmtResult ActOnObjCForCollectionStmt(SourceLocation ForColLoc, Stmt *First, - Expr *collection, - SourceLocation RParenLoc); - StmtResult FinishObjCForCollectionStmt(Stmt *ForCollection, Stmt *Body); - enum BuildForRangeKind { /// Initial building of a for-range statement. BFRK_Build, @@ -8630,24 +8537,6 @@ class Sema final : public SemaBase { NamedReturnInfo &NRInfo, bool SupressSimplerImplicitMoves); - StmtResult ActOnObjCAtCatchStmt(SourceLocation AtLoc, SourceLocation RParen, - Decl *Parm, Stmt *Body); - - StmtResult ActOnObjCAtFinallyStmt(SourceLocation AtLoc, Stmt *Body); - - StmtResult ActOnObjCAtTryStmt(SourceLocation AtLoc, Stmt *Try, - MultiStmtArg Catch, Stmt *Finally); - - StmtResult BuildObjCAtThrowStmt(SourceLocation AtLoc, Expr *Throw); - StmtResult ActOnObjCAtThrowStmt(SourceLocation AtLoc, Expr *Throw, - Scope *CurScope); - ExprResult ActOnObjCAtSynchronizedOperand(SourceLocation atLoc, - Expr *operand); - StmtResult ActOnObjCAtSynchronizedStmt(SourceLocation AtLoc, Expr *SynchExpr, - Stmt *SynchBody); - - StmtResult ActOnObjCAutoreleasePoolStmt(SourceLocation AtLoc, Stmt *Body); - StmtResult ActOnCXXCatchBlock(SourceLocation CatchLoc, Decl *ExDecl, Stmt *HandlerBlock); StmtResult ActOnCXXTryBlock(SourceLocation TryLoc, Stmt *TryBlock, @@ -11454,36 +11343,6 @@ class Sema final : public SemaBase { Default = AcceptSizeless }; - /// Build a an Objective-C protocol-qualified 'id' type where no - /// base type was specified. - TypeResult actOnObjCProtocolQualifierType( - SourceLocation lAngleLoc, ArrayRef protocols, - ArrayRef protocolLocs, SourceLocation rAngleLoc); - - /// Build a specialized and/or protocol-qualified Objective-C type. - TypeResult actOnObjCTypeArgsAndProtocolQualifiers( - Scope *S, SourceLocation Loc, ParsedType BaseType, - SourceLocation TypeArgsLAngleLoc, ArrayRef TypeArgs, - SourceLocation TypeArgsRAngleLoc, SourceLocation ProtocolLAngleLoc, - ArrayRef Protocols, ArrayRef ProtocolLocs, - SourceLocation ProtocolRAngleLoc); - - /// Build an Objective-C type parameter type. - QualType BuildObjCTypeParamType(const ObjCTypeParamDecl *Decl, - SourceLocation ProtocolLAngleLoc, - ArrayRef Protocols, - ArrayRef ProtocolLocs, - SourceLocation ProtocolRAngleLoc, - bool FailOnError = false); - - /// Build an Objective-C object pointer type. - QualType BuildObjCObjectType( - QualType BaseType, SourceLocation Loc, SourceLocation TypeArgsLAngleLoc, - ArrayRef TypeArgs, SourceLocation TypeArgsRAngleLoc, - SourceLocation ProtocolLAngleLoc, ArrayRef Protocols, - ArrayRef ProtocolLocs, SourceLocation ProtocolRAngleLoc, - bool FailOnError, bool Rebuilding); - QualType BuildQualifiedType(QualType T, SourceLocation Loc, Qualifiers Qs, const DeclSpec *DS = nullptr); QualType BuildQualifiedType(QualType T, SourceLocation Loc, unsigned CVRA, @@ -11565,10 +11424,6 @@ class Sema final : public SemaBase { TypeResult ActOnTypeName(Declarator &D); - /// The parser has parsed the context-sensitive type 'instancetype' - /// in an Objective-C message declaration. Return the appropriate type. - ParsedType ActOnObjCInstanceType(SourceLocation Loc); - // Check whether the size of array element of type \p EltTy is a multiple of // its alignment and return false if it isn't. bool checkArrayElementAlignment(QualType EltTy, SourceLocation Loc); @@ -11585,13 +11440,6 @@ class Sema final : public SemaBase { /// Retrieve the keyword associated IdentifierInfo *getNullabilityKeyword(NullabilityKind nullability); - /// The struct behind the CFErrorRef pointer. - RecordDecl *CFError = nullptr; - bool isCFError(RecordDecl *D); - - /// Retrieve the identifier "NSError". - IdentifierInfo *getNSErrorIdent(); - /// Adjust the calling convention of a method to be the ABI default if it /// wasn't specified explicitly. This handles method types formed from /// function type typedefs and typename template arguments. @@ -11778,784 +11626,6 @@ class Sema final : public SemaBase { IdentifierInfo *Ident__Nullable_result = nullptr; IdentifierInfo *Ident__Null_unspecified = nullptr; - IdentifierInfo *Ident_NSError = nullptr; - - ///@} - - // - // - // ------------------------------------------------------------------------- - // - // - - /// \name ObjC Declarations - /// Implementations are in SemaDeclObjC.cpp - ///@{ - -public: - enum ObjCSpecialMethodKind { - OSMK_None, - OSMK_Alloc, - OSMK_New, - OSMK_Copy, - OSMK_RetainingInit, - OSMK_NonRetainingInit - }; - - /// Method selectors used in a \@selector expression. Used for implementation - /// of -Wselector. - llvm::MapVector ReferencedSelectors; - - class GlobalMethodPool { - public: - using Lists = std::pair; - using iterator = llvm::DenseMap::iterator; - iterator begin() { return Methods.begin(); } - iterator end() { return Methods.end(); } - iterator find(Selector Sel) { return Methods.find(Sel); } - std::pair insert(std::pair &&Val) { - return Methods.insert(Val); - } - int count(Selector Sel) const { return Methods.count(Sel); } - bool empty() const { return Methods.empty(); } - - private: - llvm::DenseMap Methods; - }; - - /// Method Pool - allows efficient lookup when typechecking messages to "id". - /// We need to maintain a list, since selectors can have differing signatures - /// across classes. In Cocoa, this happens to be extremely uncommon (only 1% - /// of selectors are "overloaded"). - /// At the head of the list it is recorded whether there were 0, 1, or >= 2 - /// methods inside categories with a particular selector. - GlobalMethodPool MethodPool; - - /// Check ODR hashes for C/ObjC when merging types from modules. - /// Differently from C++, actually parse the body and reject in case - /// of a mismatch. - template ::value>> - bool ActOnDuplicateODRHashDefinition(T *Duplicate, T *Previous) { - if (Duplicate->getODRHash() != Previous->getODRHash()) - return false; - - // Make the previous decl visible. - makeMergedDefinitionVisible(Previous); - return true; - } - - typedef llvm::SmallPtrSet SelectorSet; - - enum MethodMatchStrategy { MMS_loose, MMS_strict }; - - enum ObjCContainerKind { - OCK_None = -1, - OCK_Interface = 0, - OCK_Protocol, - OCK_Category, - OCK_ClassExtension, - OCK_Implementation, - OCK_CategoryImplementation - }; - ObjCContainerKind getObjCContainerKind() const; - - DeclResult actOnObjCTypeParam(Scope *S, ObjCTypeParamVariance variance, - SourceLocation varianceLoc, unsigned index, - IdentifierInfo *paramName, - SourceLocation paramLoc, - SourceLocation colonLoc, ParsedType typeBound); - - ObjCTypeParamList *actOnObjCTypeParamList(Scope *S, SourceLocation lAngleLoc, - ArrayRef typeParams, - SourceLocation rAngleLoc); - void popObjCTypeParamList(Scope *S, ObjCTypeParamList *typeParamList); - - ObjCInterfaceDecl *ActOnStartClassInterface( - Scope *S, SourceLocation AtInterfaceLoc, IdentifierInfo *ClassName, - SourceLocation ClassLoc, ObjCTypeParamList *typeParamList, - IdentifierInfo *SuperName, SourceLocation SuperLoc, - ArrayRef SuperTypeArgs, SourceRange SuperTypeArgsRange, - Decl *const *ProtoRefs, unsigned NumProtoRefs, - const SourceLocation *ProtoLocs, SourceLocation EndProtoLoc, - const ParsedAttributesView &AttrList, SkipBodyInfo *SkipBody); - - void ActOnSuperClassOfClassInterface( - Scope *S, SourceLocation AtInterfaceLoc, ObjCInterfaceDecl *IDecl, - IdentifierInfo *ClassName, SourceLocation ClassLoc, - IdentifierInfo *SuperName, SourceLocation SuperLoc, - ArrayRef SuperTypeArgs, SourceRange SuperTypeArgsRange); - - void ActOnTypedefedProtocols(SmallVectorImpl &ProtocolRefs, - SmallVectorImpl &ProtocolLocs, - IdentifierInfo *SuperName, - SourceLocation SuperLoc); - - Decl *ActOnCompatibilityAlias(SourceLocation AtCompatibilityAliasLoc, - IdentifierInfo *AliasName, - SourceLocation AliasLocation, - IdentifierInfo *ClassName, - SourceLocation ClassLocation); - - bool CheckForwardProtocolDeclarationForCircularDependency( - IdentifierInfo *PName, SourceLocation &PLoc, SourceLocation PrevLoc, - const ObjCList &PList); - - ObjCProtocolDecl *ActOnStartProtocolInterface( - SourceLocation AtProtoInterfaceLoc, IdentifierInfo *ProtocolName, - SourceLocation ProtocolLoc, Decl *const *ProtoRefNames, - unsigned NumProtoRefs, const SourceLocation *ProtoLocs, - SourceLocation EndProtoLoc, const ParsedAttributesView &AttrList, - SkipBodyInfo *SkipBody); - - ObjCCategoryDecl *ActOnStartCategoryInterface( - SourceLocation AtInterfaceLoc, const IdentifierInfo *ClassName, - SourceLocation ClassLoc, ObjCTypeParamList *typeParamList, - const IdentifierInfo *CategoryName, SourceLocation CategoryLoc, - Decl *const *ProtoRefs, unsigned NumProtoRefs, - const SourceLocation *ProtoLocs, SourceLocation EndProtoLoc, - const ParsedAttributesView &AttrList); - - ObjCImplementationDecl *ActOnStartClassImplementation( - SourceLocation AtClassImplLoc, const IdentifierInfo *ClassName, - SourceLocation ClassLoc, const IdentifierInfo *SuperClassname, - SourceLocation SuperClassLoc, const ParsedAttributesView &AttrList); - - ObjCCategoryImplDecl *ActOnStartCategoryImplementation( - SourceLocation AtCatImplLoc, const IdentifierInfo *ClassName, - SourceLocation ClassLoc, const IdentifierInfo *CatName, - SourceLocation CatLoc, const ParsedAttributesView &AttrList); - - DeclGroupPtrTy ActOnFinishObjCImplementation(Decl *ObjCImpDecl, - ArrayRef Decls); - - DeclGroupPtrTy - ActOnForwardProtocolDeclaration(SourceLocation AtProtoclLoc, - ArrayRef IdentList, - const ParsedAttributesView &attrList); - - void FindProtocolDeclaration(bool WarnOnDeclarations, bool ForObjCContainer, - ArrayRef ProtocolId, - SmallVectorImpl &Protocols); - - void DiagnoseTypeArgsAndProtocols(IdentifierInfo *ProtocolId, - SourceLocation ProtocolLoc, - IdentifierInfo *TypeArgId, - SourceLocation TypeArgLoc, - bool SelectProtocolFirst = false); - - /// Given a list of identifiers (and their locations), resolve the - /// names to either Objective-C protocol qualifiers or type - /// arguments, as appropriate. - void actOnObjCTypeArgsOrProtocolQualifiers( - Scope *S, ParsedType baseType, SourceLocation lAngleLoc, - ArrayRef identifiers, - ArrayRef identifierLocs, SourceLocation rAngleLoc, - SourceLocation &typeArgsLAngleLoc, SmallVectorImpl &typeArgs, - SourceLocation &typeArgsRAngleLoc, SourceLocation &protocolLAngleLoc, - SmallVectorImpl &protocols, SourceLocation &protocolRAngleLoc, - bool warnOnIncompleteProtocols); - - void DiagnoseClassExtensionDupMethods(ObjCCategoryDecl *CAT, - ObjCInterfaceDecl *ID); - - Decl *ActOnAtEnd(Scope *S, SourceRange AtEnd, - ArrayRef allMethods = std::nullopt, - ArrayRef allTUVars = std::nullopt); - - struct ObjCArgInfo { - IdentifierInfo *Name; - SourceLocation NameLoc; - // The Type is null if no type was specified, and the DeclSpec is invalid - // in this case. - ParsedType Type; - ObjCDeclSpec DeclSpec; - - /// ArgAttrs - Attribute list for this argument. - ParsedAttributesView ArgAttrs; - }; - - Decl *ActOnMethodDeclaration( - Scope *S, - SourceLocation BeginLoc, // location of the + or -. - SourceLocation EndLoc, // location of the ; or {. - tok::TokenKind MethodType, ObjCDeclSpec &ReturnQT, ParsedType ReturnType, - ArrayRef SelectorLocs, Selector Sel, - // optional arguments. The number of types/arguments is obtained - // from the Sel.getNumArgs(). - ObjCArgInfo *ArgInfo, DeclaratorChunk::ParamInfo *CParamInfo, - unsigned CNumArgs, // c-style args - const ParsedAttributesView &AttrList, tok::ObjCKeywordKind MethodImplKind, - bool isVariadic, bool MethodDefinition); - - bool CheckARCMethodDecl(ObjCMethodDecl *method); - - bool checkInitMethod(ObjCMethodDecl *method, QualType receiverTypeIfCall); - - /// Check whether the given new method is a valid override of the - /// given overridden method, and set any properties that should be inherited. - void CheckObjCMethodOverride(ObjCMethodDecl *NewMethod, - const ObjCMethodDecl *Overridden); - - /// Describes the compatibility of a result type with its method. - enum ResultTypeCompatibilityKind { - RTC_Compatible, - RTC_Incompatible, - RTC_Unknown - }; - - void CheckObjCMethodDirectOverrides(ObjCMethodDecl *method, - ObjCMethodDecl *overridden); - - void CheckObjCMethodOverrides(ObjCMethodDecl *ObjCMethod, - ObjCInterfaceDecl *CurrentClass, - ResultTypeCompatibilityKind RTC); - - /// AddAnyMethodToGlobalPool - Add any method, instance or factory to global - /// pool. - void AddAnyMethodToGlobalPool(Decl *D); - - void ActOnStartOfObjCMethodDef(Scope *S, Decl *D); - bool isObjCMethodDecl(Decl *D) { return D && isa(D); } - - /// CheckImplementationIvars - This routine checks if the instance variables - /// listed in the implelementation match those listed in the interface. - void CheckImplementationIvars(ObjCImplementationDecl *ImpDecl, - ObjCIvarDecl **Fields, unsigned nIvars, - SourceLocation Loc); - - void WarnConflictingTypedMethods(ObjCMethodDecl *Method, - ObjCMethodDecl *MethodDecl, - bool IsProtocolMethodDecl); - - void CheckConflictingOverridingMethod(ObjCMethodDecl *Method, - ObjCMethodDecl *Overridden, - bool IsProtocolMethodDecl); - - /// WarnExactTypedMethods - This routine issues a warning if method - /// implementation declaration matches exactly that of its declaration. - void WarnExactTypedMethods(ObjCMethodDecl *Method, ObjCMethodDecl *MethodDecl, - bool IsProtocolMethodDecl); - - /// MatchAllMethodDeclarations - Check methods declaraed in interface or - /// or protocol against those declared in their implementations. - void MatchAllMethodDeclarations( - const SelectorSet &InsMap, const SelectorSet &ClsMap, - SelectorSet &InsMapSeen, SelectorSet &ClsMapSeen, ObjCImplDecl *IMPDecl, - ObjCContainerDecl *IDecl, bool &IncompleteImpl, bool ImmediateClass, - bool WarnCategoryMethodImpl = false); - - /// CheckCategoryVsClassMethodMatches - Checks that methods implemented in - /// category matches with those implemented in its primary class and - /// warns each time an exact match is found. - void CheckCategoryVsClassMethodMatches(ObjCCategoryImplDecl *CatIMP); - - /// ImplMethodsVsClassMethods - This is main routine to warn if any method - /// remains unimplemented in the class or category \@implementation. - void ImplMethodsVsClassMethods(Scope *S, ObjCImplDecl *IMPDecl, - ObjCContainerDecl *IDecl, - bool IncompleteImpl = false); - - DeclGroupPtrTy ActOnForwardClassDeclaration( - SourceLocation Loc, IdentifierInfo **IdentList, SourceLocation *IdentLocs, - ArrayRef TypeParamLists, unsigned NumElts); - - /// MatchTwoMethodDeclarations - Checks if two methods' type match and returns - /// true, or false, accordingly. - bool MatchTwoMethodDeclarations(const ObjCMethodDecl *Method, - const ObjCMethodDecl *PrevMethod, - MethodMatchStrategy strategy = MMS_strict); - - /// Add the given method to the list of globally-known methods. - void addMethodToGlobalList(ObjCMethodList *List, ObjCMethodDecl *Method); - - void ReadMethodPool(Selector Sel); - void updateOutOfDateSelector(Selector Sel); - - /// - Returns instance or factory methods in global method pool for - /// given selector. It checks the desired kind first, if none is found, and - /// parameter checkTheOther is set, it then checks the other kind. If no such - /// method or only one method is found, function returns false; otherwise, it - /// returns true. - bool - CollectMultipleMethodsInGlobalPool(Selector Sel, - SmallVectorImpl &Methods, - bool InstanceFirst, bool CheckTheOther, - const ObjCObjectType *TypeBound = nullptr); - - bool - AreMultipleMethodsInGlobalPool(Selector Sel, ObjCMethodDecl *BestMethod, - SourceRange R, bool receiverIdOrClass, - SmallVectorImpl &Methods); - - void - DiagnoseMultipleMethodInGlobalPool(SmallVectorImpl &Methods, - Selector Sel, SourceRange R, - bool receiverIdOrClass); - - const ObjCMethodDecl * - SelectorsForTypoCorrection(Selector Sel, QualType ObjectType = QualType()); - /// LookupImplementedMethodInGlobalPool - Returns the method which has an - /// implementation. - ObjCMethodDecl *LookupImplementedMethodInGlobalPool(Selector Sel); - - void DiagnoseDuplicateIvars(ObjCInterfaceDecl *ID, ObjCInterfaceDecl *SID); - - /// Checks that the Objective-C declaration is declared in the global scope. - /// Emits an error and marks the declaration as invalid if it's not declared - /// in the global scope. - bool CheckObjCDeclScope(Decl *D); - - void ActOnDefs(Scope *S, Decl *TagD, SourceLocation DeclStart, - const IdentifierInfo *ClassName, - SmallVectorImpl &Decls); - - VarDecl *BuildObjCExceptionDecl(TypeSourceInfo *TInfo, QualType ExceptionType, - SourceLocation StartLoc, SourceLocation IdLoc, - const IdentifierInfo *Id, - bool Invalid = false); - - Decl *ActOnObjCExceptionDecl(Scope *S, Declarator &D); - - /// CollectIvarsToConstructOrDestruct - Collect those ivars which require - /// initialization. - void - CollectIvarsToConstructOrDestruct(ObjCInterfaceDecl *OI, - SmallVectorImpl &Ivars); - - void DiagnoseUseOfUnimplementedSelectors(); - - /// DiagnoseUnusedBackingIvarInAccessor - Issue an 'unused' warning if ivar - /// which backs the property is not used in the property's accessor. - void DiagnoseUnusedBackingIvarInAccessor(Scope *S, - const ObjCImplementationDecl *ImplD); - - /// GetIvarBackingPropertyAccessor - If method is a property setter/getter and - /// it property has a backing ivar, returns this ivar; otherwise, returns - /// NULL. It also returns ivar's property on success. - ObjCIvarDecl * - GetIvarBackingPropertyAccessor(const ObjCMethodDecl *Method, - const ObjCPropertyDecl *&PDecl) const; - - /// AddInstanceMethodToGlobalPool - All instance methods in a translation - /// unit are added to a global pool. This allows us to efficiently associate - /// a selector with a method declaraation for purposes of typechecking - /// messages sent to "id" (where the class of the object is unknown). - void AddInstanceMethodToGlobalPool(ObjCMethodDecl *Method, - bool impl = false) { - AddMethodToGlobalPool(Method, impl, /*instance*/ true); - } - - /// AddFactoryMethodToGlobalPool - Same as above, but for factory methods. - void AddFactoryMethodToGlobalPool(ObjCMethodDecl *Method, bool impl = false) { - AddMethodToGlobalPool(Method, impl, /*instance*/ false); - } - -private: - /// AddMethodToGlobalPool - Add an instance or factory method to the global - /// pool. See descriptoin of AddInstanceMethodToGlobalPool. - void AddMethodToGlobalPool(ObjCMethodDecl *Method, bool impl, bool instance); - - /// LookupMethodInGlobalPool - Returns the instance or factory method and - /// optionally warns if there are multiple signatures. - ObjCMethodDecl *LookupMethodInGlobalPool(Selector Sel, SourceRange R, - bool receiverIdOrClass, - bool instance); - - ///@} - - // - // - // ------------------------------------------------------------------------- - // - // - - /// \name ObjC Expressions - /// Implementations are in SemaExprObjC.cpp - ///@{ - -public: - /// Caches identifiers/selectors for NSFoundation APIs. - std::unique_ptr NSAPIObj; - - /// The declaration of the Objective-C NSNumber class. - ObjCInterfaceDecl *NSNumberDecl; - - /// The declaration of the Objective-C NSValue class. - ObjCInterfaceDecl *NSValueDecl; - - /// Pointer to NSNumber type (NSNumber *). - QualType NSNumberPointer; - - /// Pointer to NSValue type (NSValue *). - QualType NSValuePointer; - - /// The Objective-C NSNumber methods used to create NSNumber literals. - ObjCMethodDecl *NSNumberLiteralMethods[NSAPI::NumNSNumberLiteralMethods]; - - /// The declaration of the Objective-C NSString class. - ObjCInterfaceDecl *NSStringDecl; - - /// Pointer to NSString type (NSString *). - QualType NSStringPointer; - - /// The declaration of the stringWithUTF8String: method. - ObjCMethodDecl *StringWithUTF8StringMethod; - - /// The declaration of the valueWithBytes:objCType: method. - ObjCMethodDecl *ValueWithBytesObjCTypeMethod; - - /// The declaration of the Objective-C NSArray class. - ObjCInterfaceDecl *NSArrayDecl; - - /// The declaration of the arrayWithObjects:count: method. - ObjCMethodDecl *ArrayWithObjectsMethod; - - /// The declaration of the Objective-C NSDictionary class. - ObjCInterfaceDecl *NSDictionaryDecl; - - /// The declaration of the dictionaryWithObjects:forKeys:count: method. - ObjCMethodDecl *DictionaryWithObjectsMethod; - - /// id type. - QualType QIDNSCopying; - - /// will hold 'respondsToSelector:' - Selector RespondsToSelectorSel; - - ExprResult HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT, - Expr *BaseExpr, SourceLocation OpLoc, - DeclarationName MemberName, - SourceLocation MemberLoc, - SourceLocation SuperLoc, - QualType SuperType, bool Super); - - ExprResult ActOnClassPropertyRefExpr(const IdentifierInfo &receiverName, - const IdentifierInfo &propertyName, - SourceLocation receiverNameLoc, - SourceLocation propertyNameLoc); - - // ParseObjCStringLiteral - Parse Objective-C string literals. - ExprResult ParseObjCStringLiteral(SourceLocation *AtLocs, - ArrayRef Strings); - - ExprResult BuildObjCStringLiteral(SourceLocation AtLoc, StringLiteral *S); - - /// BuildObjCNumericLiteral - builds an ObjCBoxedExpr AST node for the - /// numeric literal expression. Type of the expression will be "NSNumber *" - /// or "id" if NSNumber is unavailable. - ExprResult BuildObjCNumericLiteral(SourceLocation AtLoc, Expr *Number); - ExprResult ActOnObjCBoolLiteral(SourceLocation AtLoc, SourceLocation ValueLoc, - bool Value); - ExprResult BuildObjCArrayLiteral(SourceRange SR, MultiExprArg Elements); - - /// BuildObjCBoxedExpr - builds an ObjCBoxedExpr AST node for the - /// '@' prefixed parenthesized expression. The type of the expression will - /// either be "NSNumber *", "NSString *" or "NSValue *" depending on the type - /// of ValueType, which is allowed to be a built-in numeric type, "char *", - /// "const char *" or C structure with attribute 'objc_boxable'. - ExprResult BuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr); - - ExprResult BuildObjCSubscriptExpression(SourceLocation RB, Expr *BaseExpr, - Expr *IndexExpr, - ObjCMethodDecl *getterMethod, - ObjCMethodDecl *setterMethod); - - ExprResult - BuildObjCDictionaryLiteral(SourceRange SR, - MutableArrayRef Elements); - - ExprResult BuildObjCEncodeExpression(SourceLocation AtLoc, - TypeSourceInfo *EncodedTypeInfo, - SourceLocation RParenLoc); - - ExprResult ParseObjCEncodeExpression(SourceLocation AtLoc, - SourceLocation EncodeLoc, - SourceLocation LParenLoc, ParsedType Ty, - SourceLocation RParenLoc); - - /// ParseObjCSelectorExpression - Build selector expression for \@selector - ExprResult ParseObjCSelectorExpression(Selector Sel, SourceLocation AtLoc, - SourceLocation SelLoc, - SourceLocation LParenLoc, - SourceLocation RParenLoc, - bool WarnMultipleSelectors); - - /// ParseObjCProtocolExpression - Build protocol expression for \@protocol - ExprResult ParseObjCProtocolExpression(IdentifierInfo *ProtocolName, - SourceLocation AtLoc, - SourceLocation ProtoLoc, - SourceLocation LParenLoc, - SourceLocation ProtoIdLoc, - SourceLocation RParenLoc); - - ObjCMethodDecl *tryCaptureObjCSelf(SourceLocation Loc); - - /// Describes the kind of message expression indicated by a message - /// send that starts with an identifier. - enum ObjCMessageKind { - /// The message is sent to 'super'. - ObjCSuperMessage, - /// The message is an instance message. - ObjCInstanceMessage, - /// The message is a class message, and the identifier is a type - /// name. - ObjCClassMessage - }; - - ObjCMessageKind getObjCMessageKind(Scope *S, IdentifierInfo *Name, - SourceLocation NameLoc, bool IsSuper, - bool HasTrailingDot, - ParsedType &ReceiverType); - - ExprResult ActOnSuperMessage(Scope *S, SourceLocation SuperLoc, Selector Sel, - SourceLocation LBracLoc, - ArrayRef SelectorLocs, - SourceLocation RBracLoc, MultiExprArg Args); - - ExprResult BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo, - QualType ReceiverType, SourceLocation SuperLoc, - Selector Sel, ObjCMethodDecl *Method, - SourceLocation LBracLoc, - ArrayRef SelectorLocs, - SourceLocation RBracLoc, MultiExprArg Args, - bool isImplicit = false); - - ExprResult BuildClassMessageImplicit(QualType ReceiverType, - bool isSuperReceiver, SourceLocation Loc, - Selector Sel, ObjCMethodDecl *Method, - MultiExprArg Args); - - ExprResult ActOnClassMessage(Scope *S, ParsedType Receiver, Selector Sel, - SourceLocation LBracLoc, - ArrayRef SelectorLocs, - SourceLocation RBracLoc, MultiExprArg Args); - - ExprResult BuildInstanceMessage(Expr *Receiver, QualType ReceiverType, - SourceLocation SuperLoc, Selector Sel, - ObjCMethodDecl *Method, - SourceLocation LBracLoc, - ArrayRef SelectorLocs, - SourceLocation RBracLoc, MultiExprArg Args, - bool isImplicit = false); - - ExprResult BuildInstanceMessageImplicit(Expr *Receiver, QualType ReceiverType, - SourceLocation Loc, Selector Sel, - ObjCMethodDecl *Method, - MultiExprArg Args); - - ExprResult ActOnInstanceMessage(Scope *S, Expr *Receiver, Selector Sel, - SourceLocation LBracLoc, - ArrayRef SelectorLocs, - SourceLocation RBracLoc, MultiExprArg Args); - - ExprResult BuildObjCBridgedCast(SourceLocation LParenLoc, - ObjCBridgeCastKind Kind, - SourceLocation BridgeKeywordLoc, - TypeSourceInfo *TSInfo, Expr *SubExpr); - - ExprResult ActOnObjCBridgedCast(Scope *S, SourceLocation LParenLoc, - ObjCBridgeCastKind Kind, - SourceLocation BridgeKeywordLoc, - ParsedType Type, SourceLocation RParenLoc, - Expr *SubExpr); - - void CheckTollFreeBridgeCast(QualType castType, Expr *castExpr); - - void CheckObjCBridgeRelatedCast(QualType castType, Expr *castExpr); - - bool CheckTollFreeBridgeStaticCast(QualType castType, Expr *castExpr, - CastKind &Kind); - - bool checkObjCBridgeRelatedComponents(SourceLocation Loc, QualType DestType, - QualType SrcType, - ObjCInterfaceDecl *&RelatedClass, - ObjCMethodDecl *&ClassMethod, - ObjCMethodDecl *&InstanceMethod, - TypedefNameDecl *&TDNDecl, bool CfToNs, - bool Diagnose = true); - - bool CheckObjCBridgeRelatedConversions(SourceLocation Loc, QualType DestType, - QualType SrcType, Expr *&SrcExpr, - bool Diagnose = true); - - /// Private Helper predicate to check for 'self'. - bool isSelfExpr(Expr *RExpr); - bool isSelfExpr(Expr *RExpr, const ObjCMethodDecl *Method); - - ObjCMethodDecl *LookupMethodInQualifiedType(Selector Sel, - const ObjCObjectPointerType *OPT, - bool IsInstance); - ObjCMethodDecl *LookupMethodInObjectType(Selector Sel, QualType Ty, - bool IsInstance); - - bool isKnownName(StringRef name); - - enum ARCConversionResult { ACR_okay, ACR_unbridged, ACR_error }; - - /// Checks for invalid conversions and casts between - /// retainable pointers and other pointer kinds for ARC and Weak. - ARCConversionResult CheckObjCConversion(SourceRange castRange, - QualType castType, Expr *&op, - CheckedConversionKind CCK, - bool Diagnose = true, - bool DiagnoseCFAudited = false, - BinaryOperatorKind Opc = BO_PtrMemD); - - Expr *stripARCUnbridgedCast(Expr *e); - void diagnoseARCUnbridgedCast(Expr *e); - - bool CheckObjCARCUnavailableWeakConversion(QualType castType, - QualType ExprType); - - /// CheckMessageArgumentTypes - Check types in an Obj-C message send. - /// \param Method - May be null. - /// \param [out] ReturnType - The return type of the send. - /// \return true iff there were any incompatible types. - bool CheckMessageArgumentTypes(const Expr *Receiver, QualType ReceiverType, - MultiExprArg Args, Selector Sel, - ArrayRef SelectorLocs, - ObjCMethodDecl *Method, bool isClassMessage, - bool isSuperMessage, SourceLocation lbrac, - SourceLocation rbrac, SourceRange RecRange, - QualType &ReturnType, ExprValueKind &VK); - - /// Determine the result of a message send expression based on - /// the type of the receiver, the method expected to receive the message, - /// and the form of the message send. - QualType getMessageSendResultType(const Expr *Receiver, QualType ReceiverType, - ObjCMethodDecl *Method, bool isClassMessage, - bool isSuperMessage); - - /// If the given expression involves a message send to a method - /// with a related result type, emit a note describing what happened. - void EmitRelatedResultTypeNote(const Expr *E); - - /// Given that we had incompatible pointer types in a return - /// statement, check whether we're in a method with a related result - /// type, and if so, emit a note describing what happened. - void EmitRelatedResultTypeNoteForReturn(QualType destType); - - /// LookupInstanceMethodInGlobalPool - Returns the method and warns if - /// there are multiple signatures. - ObjCMethodDecl * - LookupInstanceMethodInGlobalPool(Selector Sel, SourceRange R, - bool receiverIdOrClass = false) { - return LookupMethodInGlobalPool(Sel, R, receiverIdOrClass, - /*instance*/ true); - } - - /// LookupFactoryMethodInGlobalPool - Returns the method and warns if - /// there are multiple signatures. - ObjCMethodDecl * - LookupFactoryMethodInGlobalPool(Selector Sel, SourceRange R, - bool receiverIdOrClass = false) { - return LookupMethodInGlobalPool(Sel, R, receiverIdOrClass, - /*instance*/ false); - } - - ///@} - - // - // - // ------------------------------------------------------------------------- - // - // - - /// \name ObjC @property and @synthesize - /// Implementations are in SemaObjCProperty.cpp - ///@{ - -public: - /// Ensure attributes are consistent with type. - /// \param [in, out] Attributes The attributes to check; they will - /// be modified to be consistent with \p PropertyTy. - void CheckObjCPropertyAttributes(Decl *PropertyPtrTy, SourceLocation Loc, - unsigned &Attributes, - bool propertyInPrimaryClass); - - /// Process the specified property declaration and create decls for the - /// setters and getters as needed. - /// \param property The property declaration being processed - void ProcessPropertyDecl(ObjCPropertyDecl *property); - - Decl *ActOnProperty(Scope *S, SourceLocation AtLoc, SourceLocation LParenLoc, - FieldDeclarator &FD, ObjCDeclSpec &ODS, - Selector GetterSel, Selector SetterSel, - tok::ObjCKeywordKind MethodImplKind, - DeclContext *lexicalDC = nullptr); - - Decl *ActOnPropertyImplDecl(Scope *S, SourceLocation AtLoc, - SourceLocation PropertyLoc, bool ImplKind, - IdentifierInfo *PropertyId, - IdentifierInfo *PropertyIvar, - SourceLocation PropertyIvarLoc, - ObjCPropertyQueryKind QueryKind); - - /// Called by ActOnProperty to handle \@property declarations in - /// class extensions. - ObjCPropertyDecl *HandlePropertyInClassExtension( - Scope *S, SourceLocation AtLoc, SourceLocation LParenLoc, - FieldDeclarator &FD, Selector GetterSel, SourceLocation GetterNameLoc, - Selector SetterSel, SourceLocation SetterNameLoc, const bool isReadWrite, - unsigned &Attributes, const unsigned AttributesAsWritten, QualType T, - TypeSourceInfo *TSI, tok::ObjCKeywordKind MethodImplKind); - - /// Called by ActOnProperty and HandlePropertyInClassExtension to - /// handle creating the ObjcPropertyDecl for a category or \@interface. - ObjCPropertyDecl * - CreatePropertyDecl(Scope *S, ObjCContainerDecl *CDecl, SourceLocation AtLoc, - SourceLocation LParenLoc, FieldDeclarator &FD, - Selector GetterSel, SourceLocation GetterNameLoc, - Selector SetterSel, SourceLocation SetterNameLoc, - const bool isReadWrite, const unsigned Attributes, - const unsigned AttributesAsWritten, QualType T, - TypeSourceInfo *TSI, tok::ObjCKeywordKind MethodImplKind, - DeclContext *lexicalDC = nullptr); - - void DiagnosePropertyMismatch(ObjCPropertyDecl *Property, - ObjCPropertyDecl *SuperProperty, - const IdentifierInfo *Name, - bool OverridingProtocolProperty); - - bool DiagnosePropertyAccessorMismatch(ObjCPropertyDecl *PD, - ObjCMethodDecl *Getter, - SourceLocation Loc); - - /// DiagnoseUnimplementedProperties - This routine warns on those properties - /// which must be implemented by this implementation. - void DiagnoseUnimplementedProperties(Scope *S, ObjCImplDecl *IMPDecl, - ObjCContainerDecl *CDecl, - bool SynthesizeProperties); - - /// Diagnose any null-resettable synthesized setters. - void diagnoseNullResettableSynthesizedSetters(const ObjCImplDecl *impDecl); - - /// DefaultSynthesizeProperties - This routine default synthesizes all - /// properties which must be synthesized in the class's \@implementation. - void DefaultSynthesizeProperties(Scope *S, ObjCImplDecl *IMPDecl, - ObjCInterfaceDecl *IDecl, - SourceLocation AtEnd); - void DefaultSynthesizeProperties(Scope *S, Decl *D, SourceLocation AtEnd); - - /// IvarBacksCurrentMethodAccessor - This routine returns 'true' if 'IV' is - /// an ivar synthesized for 'Method' and 'Method' is a property accessor - /// declared in class 'IFace'. - bool IvarBacksCurrentMethodAccessor(ObjCInterfaceDecl *IFace, - ObjCMethodDecl *Method, ObjCIvarDecl *IV); - - void DiagnoseOwningPropertyGetterSynthesis(const ObjCImplementationDecl *D); - - void - DiagnoseMissingDesignatedInitOverrides(const ObjCImplementationDecl *ImplD, - const ObjCInterfaceDecl *IFD); - - /// AtomicPropertySetterGetterRules - This routine enforces the rule (via - /// warning) when atomic property has one but not the other user-declared - /// setter or getter. - void AtomicPropertySetterGetterRules(ObjCImplDecl *IMPDecl, - ObjCInterfaceDecl *IDecl); - ///@} // diff --git a/clang/include/clang/Sema/SemaObjC.h b/clang/include/clang/Sema/SemaObjC.h new file mode 100644 index 0000000000000..7884af42365a3 --- /dev/null +++ b/clang/include/clang/Sema/SemaObjC.h @@ -0,0 +1,1015 @@ +//===----- SemaObjC.h ------ Semantic Analysis for Objective-C ------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// \file +/// This file declares semantic analysis for Objective-C. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_SEMA_SEMAOBJC_H +#define LLVM_CLANG_SEMA_SEMAOBJC_H + +#include "clang/AST/Decl.h" +#include "clang/AST/DeclBase.h" +#include "clang/AST/DeclObjC.h" +#include "clang/AST/Expr.h" +#include "clang/AST/ExprObjC.h" +#include "clang/AST/NSAPI.h" +#include "clang/AST/OperationKinds.h" +#include "clang/AST/Type.h" +#include "clang/Basic/IdentifierTable.h" +#include "clang/Basic/LLVM.h" +#include "clang/Basic/SourceLocation.h" +#include "clang/Basic/Specifiers.h" +#include "clang/Basic/TokenKinds.h" +#include "clang/Sema/DeclSpec.h" +#include "clang/Sema/Lookup.h" +#include "clang/Sema/ObjCMethodList.h" +#include "clang/Sema/Ownership.h" +#include "clang/Sema/ParsedAttr.h" +#include "clang/Sema/Redeclaration.h" +#include "clang/Sema/Scope.h" +#include "clang/Sema/SemaBase.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/MapVector.h" +#include "llvm/ADT/SmallPtrSet.h" +#include +#include +#include +#include + +namespace clang { + +enum class CheckedConversionKind; +struct SkipBodyInfo; + +class SemaObjC : public SemaBase { +public: + SemaObjC(Sema &S); + + ExprResult CheckObjCForCollectionOperand(SourceLocation forLoc, + Expr *collection); + StmtResult ActOnObjCForCollectionStmt(SourceLocation ForColLoc, Stmt *First, + Expr *collection, + SourceLocation RParenLoc); + /// FinishObjCForCollectionStmt - Attach the body to a objective-C foreach + /// statement. + StmtResult FinishObjCForCollectionStmt(Stmt *ForCollection, Stmt *Body); + + StmtResult ActOnObjCAtCatchStmt(SourceLocation AtLoc, SourceLocation RParen, + Decl *Parm, Stmt *Body); + + StmtResult ActOnObjCAtFinallyStmt(SourceLocation AtLoc, Stmt *Body); + + StmtResult ActOnObjCAtTryStmt(SourceLocation AtLoc, Stmt *Try, + MultiStmtArg Catch, Stmt *Finally); + + StmtResult BuildObjCAtThrowStmt(SourceLocation AtLoc, Expr *Throw); + StmtResult ActOnObjCAtThrowStmt(SourceLocation AtLoc, Expr *Throw, + Scope *CurScope); + ExprResult ActOnObjCAtSynchronizedOperand(SourceLocation atLoc, + Expr *operand); + StmtResult ActOnObjCAtSynchronizedStmt(SourceLocation AtLoc, Expr *SynchExpr, + Stmt *SynchBody); + + StmtResult ActOnObjCAutoreleasePoolStmt(SourceLocation AtLoc, Stmt *Body); + + /// Build a an Objective-C protocol-qualified 'id' type where no + /// base type was specified. + TypeResult actOnObjCProtocolQualifierType( + SourceLocation lAngleLoc, ArrayRef protocols, + ArrayRef protocolLocs, SourceLocation rAngleLoc); + + /// Build a specialized and/or protocol-qualified Objective-C type. + TypeResult actOnObjCTypeArgsAndProtocolQualifiers( + Scope *S, SourceLocation Loc, ParsedType BaseType, + SourceLocation TypeArgsLAngleLoc, ArrayRef TypeArgs, + SourceLocation TypeArgsRAngleLoc, SourceLocation ProtocolLAngleLoc, + ArrayRef Protocols, ArrayRef ProtocolLocs, + SourceLocation ProtocolRAngleLoc); + + /// Build an Objective-C type parameter type. + QualType BuildObjCTypeParamType(const ObjCTypeParamDecl *Decl, + SourceLocation ProtocolLAngleLoc, + ArrayRef Protocols, + ArrayRef ProtocolLocs, + SourceLocation ProtocolRAngleLoc, + bool FailOnError = false); + + /// Build an Objective-C object pointer type. + QualType BuildObjCObjectType( + QualType BaseType, SourceLocation Loc, SourceLocation TypeArgsLAngleLoc, + ArrayRef TypeArgs, SourceLocation TypeArgsRAngleLoc, + SourceLocation ProtocolLAngleLoc, ArrayRef Protocols, + ArrayRef ProtocolLocs, SourceLocation ProtocolRAngleLoc, + bool FailOnError, bool Rebuilding); + + /// The parser has parsed the context-sensitive type 'instancetype' + /// in an Objective-C message declaration. Return the appropriate type. + ParsedType ActOnObjCInstanceType(SourceLocation Loc); + + /// checkRetainCycles - Check whether an Objective-C message send + /// might create an obvious retain cycle. + void checkRetainCycles(ObjCMessageExpr *msg); + void checkRetainCycles(Expr *receiver, Expr *argument); + void checkRetainCycles(VarDecl *Var, Expr *Init); + + bool CheckObjCString(Expr *Arg); + bool CheckObjCMethodCall(ObjCMethodDecl *Method, SourceLocation loc, + ArrayRef Args); + /// Check whether receiver is mutable ObjC container which + /// attempts to add itself into the container + void CheckObjCCircularContainer(ObjCMessageExpr *Message); + + void ActOnObjCContainerStartDefinition(ObjCContainerDecl *IDecl); + void ActOnObjCContainerFinishDefinition(); + + /// Invoked when we must temporarily exit the objective-c container + /// scope for parsing/looking-up C constructs. + /// + /// Must be followed by a call to \see ActOnObjCReenterContainerContext + void ActOnObjCTemporaryExitContainerContext(ObjCContainerDecl *ObjCCtx); + void ActOnObjCReenterContainerContext(ObjCContainerDecl *ObjCCtx); + + const DeclContext *getCurObjCLexicalContext() const; + + ObjCProtocolDecl * + LookupProtocol(IdentifierInfo *II, SourceLocation IdLoc, + RedeclarationKind Redecl = RedeclarationKind::NotForRedeclaration); + + bool isObjCWritebackConversion(QualType FromType, QualType ToType, + QualType &ConvertedType); + + enum ObjCSubscriptKind { OS_Array, OS_Dictionary, OS_Error }; + ObjCSubscriptKind CheckSubscriptingKind(Expr *FromE); + + /// AddCFAuditedAttribute - Check whether we're currently within + /// '\#pragma clang arc_cf_code_audited' and, if so, consider adding + /// the appropriate attribute. + void AddCFAuditedAttribute(Decl *D); + + /// The struct behind the CFErrorRef pointer. + RecordDecl *CFError = nullptr; + bool isCFError(RecordDecl *D); + + IdentifierInfo *getNSErrorIdent(); + +private: + IdentifierInfo *Ident_NSError = nullptr; + + // + // + // ------------------------------------------------------------------------- + // + // + + /// \name ObjC Declarations + /// Implementations are in SemaDeclObjC.cpp + ///@{ + +public: + enum ObjCSpecialMethodKind { + OSMK_None, + OSMK_Alloc, + OSMK_New, + OSMK_Copy, + OSMK_RetainingInit, + OSMK_NonRetainingInit + }; + + /// Method selectors used in a \@selector expression. Used for implementation + /// of -Wselector. + llvm::MapVector ReferencedSelectors; + + class GlobalMethodPool { + public: + using Lists = std::pair; + using iterator = llvm::DenseMap::iterator; + iterator begin() { return Methods.begin(); } + iterator end() { return Methods.end(); } + iterator find(Selector Sel) { return Methods.find(Sel); } + std::pair insert(std::pair &&Val) { + return Methods.insert(Val); + } + int count(Selector Sel) const { return Methods.count(Sel); } + bool empty() const { return Methods.empty(); } + + private: + llvm::DenseMap Methods; + }; + + /// Method Pool - allows efficient lookup when typechecking messages to "id". + /// We need to maintain a list, since selectors can have differing signatures + /// across classes. In Cocoa, this happens to be extremely uncommon (only 1% + /// of selectors are "overloaded"). + /// At the head of the list it is recorded whether there were 0, 1, or >= 2 + /// methods inside categories with a particular selector. + GlobalMethodPool MethodPool; + + typedef llvm::SmallPtrSet SelectorSet; + + enum MethodMatchStrategy { MMS_loose, MMS_strict }; + + enum ObjCContainerKind { + OCK_None = -1, + OCK_Interface = 0, + OCK_Protocol, + OCK_Category, + OCK_ClassExtension, + OCK_Implementation, + OCK_CategoryImplementation + }; + ObjCContainerKind getObjCContainerKind() const; + + DeclResult actOnObjCTypeParam(Scope *S, ObjCTypeParamVariance variance, + SourceLocation varianceLoc, unsigned index, + IdentifierInfo *paramName, + SourceLocation paramLoc, + SourceLocation colonLoc, ParsedType typeBound); + + ObjCTypeParamList *actOnObjCTypeParamList(Scope *S, SourceLocation lAngleLoc, + ArrayRef typeParams, + SourceLocation rAngleLoc); + void popObjCTypeParamList(Scope *S, ObjCTypeParamList *typeParamList); + + ObjCInterfaceDecl *ActOnStartClassInterface( + Scope *S, SourceLocation AtInterfaceLoc, IdentifierInfo *ClassName, + SourceLocation ClassLoc, ObjCTypeParamList *typeParamList, + IdentifierInfo *SuperName, SourceLocation SuperLoc, + ArrayRef SuperTypeArgs, SourceRange SuperTypeArgsRange, + Decl *const *ProtoRefs, unsigned NumProtoRefs, + const SourceLocation *ProtoLocs, SourceLocation EndProtoLoc, + const ParsedAttributesView &AttrList, SkipBodyInfo *SkipBody); + + void ActOnSuperClassOfClassInterface( + Scope *S, SourceLocation AtInterfaceLoc, ObjCInterfaceDecl *IDecl, + IdentifierInfo *ClassName, SourceLocation ClassLoc, + IdentifierInfo *SuperName, SourceLocation SuperLoc, + ArrayRef SuperTypeArgs, SourceRange SuperTypeArgsRange); + + void ActOnTypedefedProtocols(SmallVectorImpl &ProtocolRefs, + SmallVectorImpl &ProtocolLocs, + IdentifierInfo *SuperName, + SourceLocation SuperLoc); + + Decl *ActOnCompatibilityAlias(SourceLocation AtCompatibilityAliasLoc, + IdentifierInfo *AliasName, + SourceLocation AliasLocation, + IdentifierInfo *ClassName, + SourceLocation ClassLocation); + + bool CheckForwardProtocolDeclarationForCircularDependency( + IdentifierInfo *PName, SourceLocation &PLoc, SourceLocation PrevLoc, + const ObjCList &PList); + + ObjCProtocolDecl *ActOnStartProtocolInterface( + SourceLocation AtProtoInterfaceLoc, IdentifierInfo *ProtocolName, + SourceLocation ProtocolLoc, Decl *const *ProtoRefNames, + unsigned NumProtoRefs, const SourceLocation *ProtoLocs, + SourceLocation EndProtoLoc, const ParsedAttributesView &AttrList, + SkipBodyInfo *SkipBody); + + ObjCCategoryDecl *ActOnStartCategoryInterface( + SourceLocation AtInterfaceLoc, const IdentifierInfo *ClassName, + SourceLocation ClassLoc, ObjCTypeParamList *typeParamList, + const IdentifierInfo *CategoryName, SourceLocation CategoryLoc, + Decl *const *ProtoRefs, unsigned NumProtoRefs, + const SourceLocation *ProtoLocs, SourceLocation EndProtoLoc, + const ParsedAttributesView &AttrList); + + ObjCImplementationDecl *ActOnStartClassImplementation( + SourceLocation AtClassImplLoc, const IdentifierInfo *ClassName, + SourceLocation ClassLoc, const IdentifierInfo *SuperClassname, + SourceLocation SuperClassLoc, const ParsedAttributesView &AttrList); + + ObjCCategoryImplDecl *ActOnStartCategoryImplementation( + SourceLocation AtCatImplLoc, const IdentifierInfo *ClassName, + SourceLocation ClassLoc, const IdentifierInfo *CatName, + SourceLocation CatLoc, const ParsedAttributesView &AttrList); + + using DeclGroupPtrTy = OpaquePtr; + + DeclGroupPtrTy ActOnFinishObjCImplementation(Decl *ObjCImpDecl, + ArrayRef Decls); + + DeclGroupPtrTy + ActOnForwardProtocolDeclaration(SourceLocation AtProtoclLoc, + ArrayRef IdentList, + const ParsedAttributesView &attrList); + + void FindProtocolDeclaration(bool WarnOnDeclarations, bool ForObjCContainer, + ArrayRef ProtocolId, + SmallVectorImpl &Protocols); + + void DiagnoseTypeArgsAndProtocols(IdentifierInfo *ProtocolId, + SourceLocation ProtocolLoc, + IdentifierInfo *TypeArgId, + SourceLocation TypeArgLoc, + bool SelectProtocolFirst = false); + + /// Given a list of identifiers (and their locations), resolve the + /// names to either Objective-C protocol qualifiers or type + /// arguments, as appropriate. + void actOnObjCTypeArgsOrProtocolQualifiers( + Scope *S, ParsedType baseType, SourceLocation lAngleLoc, + ArrayRef identifiers, + ArrayRef identifierLocs, SourceLocation rAngleLoc, + SourceLocation &typeArgsLAngleLoc, SmallVectorImpl &typeArgs, + SourceLocation &typeArgsRAngleLoc, SourceLocation &protocolLAngleLoc, + SmallVectorImpl &protocols, SourceLocation &protocolRAngleLoc, + bool warnOnIncompleteProtocols); + + void DiagnoseClassExtensionDupMethods(ObjCCategoryDecl *CAT, + ObjCInterfaceDecl *ID); + + Decl *ActOnAtEnd(Scope *S, SourceRange AtEnd, + ArrayRef allMethods = std::nullopt, + ArrayRef allTUVars = std::nullopt); + + struct ObjCArgInfo { + IdentifierInfo *Name; + SourceLocation NameLoc; + // The Type is null if no type was specified, and the DeclSpec is invalid + // in this case. + ParsedType Type; + ObjCDeclSpec DeclSpec; + + /// ArgAttrs - Attribute list for this argument. + ParsedAttributesView ArgAttrs; + }; + + Decl *ActOnMethodDeclaration( + Scope *S, + SourceLocation BeginLoc, // location of the + or -. + SourceLocation EndLoc, // location of the ; or {. + tok::TokenKind MethodType, ObjCDeclSpec &ReturnQT, ParsedType ReturnType, + ArrayRef SelectorLocs, Selector Sel, + // optional arguments. The number of types/arguments is obtained + // from the Sel.getNumArgs(). + ObjCArgInfo *ArgInfo, DeclaratorChunk::ParamInfo *CParamInfo, + unsigned CNumArgs, // c-style args + const ParsedAttributesView &AttrList, tok::ObjCKeywordKind MethodImplKind, + bool isVariadic, bool MethodDefinition); + + bool CheckARCMethodDecl(ObjCMethodDecl *method); + + bool checkInitMethod(ObjCMethodDecl *method, QualType receiverTypeIfCall); + + /// Check whether the given new method is a valid override of the + /// given overridden method, and set any properties that should be inherited. + void CheckObjCMethodOverride(ObjCMethodDecl *NewMethod, + const ObjCMethodDecl *Overridden); + + /// Describes the compatibility of a result type with its method. + enum ResultTypeCompatibilityKind { + RTC_Compatible, + RTC_Incompatible, + RTC_Unknown + }; + + void CheckObjCMethodDirectOverrides(ObjCMethodDecl *method, + ObjCMethodDecl *overridden); + + void CheckObjCMethodOverrides(ObjCMethodDecl *ObjCMethod, + ObjCInterfaceDecl *CurrentClass, + ResultTypeCompatibilityKind RTC); + + /// AddAnyMethodToGlobalPool - Add any method, instance or factory to global + /// pool. + void AddAnyMethodToGlobalPool(Decl *D); + + void ActOnStartOfObjCMethodDef(Scope *S, Decl *D); + bool isObjCMethodDecl(Decl *D) { return D && isa(D); } + + /// CheckImplementationIvars - This routine checks if the instance variables + /// listed in the implelementation match those listed in the interface. + void CheckImplementationIvars(ObjCImplementationDecl *ImpDecl, + ObjCIvarDecl **Fields, unsigned nIvars, + SourceLocation Loc); + + void WarnConflictingTypedMethods(ObjCMethodDecl *Method, + ObjCMethodDecl *MethodDecl, + bool IsProtocolMethodDecl); + + void CheckConflictingOverridingMethod(ObjCMethodDecl *Method, + ObjCMethodDecl *Overridden, + bool IsProtocolMethodDecl); + + /// WarnExactTypedMethods - This routine issues a warning if method + /// implementation declaration matches exactly that of its declaration. + void WarnExactTypedMethods(ObjCMethodDecl *Method, ObjCMethodDecl *MethodDecl, + bool IsProtocolMethodDecl); + + /// MatchAllMethodDeclarations - Check methods declaraed in interface or + /// or protocol against those declared in their implementations. + void MatchAllMethodDeclarations( + const SelectorSet &InsMap, const SelectorSet &ClsMap, + SelectorSet &InsMapSeen, SelectorSet &ClsMapSeen, ObjCImplDecl *IMPDecl, + ObjCContainerDecl *IDecl, bool &IncompleteImpl, bool ImmediateClass, + bool WarnCategoryMethodImpl = false); + + /// CheckCategoryVsClassMethodMatches - Checks that methods implemented in + /// category matches with those implemented in its primary class and + /// warns each time an exact match is found. + void CheckCategoryVsClassMethodMatches(ObjCCategoryImplDecl *CatIMP); + + /// ImplMethodsVsClassMethods - This is main routine to warn if any method + /// remains unimplemented in the class or category \@implementation. + void ImplMethodsVsClassMethods(Scope *S, ObjCImplDecl *IMPDecl, + ObjCContainerDecl *IDecl, + bool IncompleteImpl = false); + + DeclGroupPtrTy ActOnForwardClassDeclaration( + SourceLocation Loc, IdentifierInfo **IdentList, SourceLocation *IdentLocs, + ArrayRef TypeParamLists, unsigned NumElts); + + /// MatchTwoMethodDeclarations - Checks if two methods' type match and returns + /// true, or false, accordingly. + bool MatchTwoMethodDeclarations(const ObjCMethodDecl *Method, + const ObjCMethodDecl *PrevMethod, + MethodMatchStrategy strategy = MMS_strict); + + /// Add the given method to the list of globally-known methods. + void addMethodToGlobalList(ObjCMethodList *List, ObjCMethodDecl *Method); + + void ReadMethodPool(Selector Sel); + void updateOutOfDateSelector(Selector Sel); + + /// - Returns instance or factory methods in global method pool for + /// given selector. It checks the desired kind first, if none is found, and + /// parameter checkTheOther is set, it then checks the other kind. If no such + /// method or only one method is found, function returns false; otherwise, it + /// returns true. + bool + CollectMultipleMethodsInGlobalPool(Selector Sel, + SmallVectorImpl &Methods, + bool InstanceFirst, bool CheckTheOther, + const ObjCObjectType *TypeBound = nullptr); + + bool + AreMultipleMethodsInGlobalPool(Selector Sel, ObjCMethodDecl *BestMethod, + SourceRange R, bool receiverIdOrClass, + SmallVectorImpl &Methods); + + void + DiagnoseMultipleMethodInGlobalPool(SmallVectorImpl &Methods, + Selector Sel, SourceRange R, + bool receiverIdOrClass); + + const ObjCMethodDecl * + SelectorsForTypoCorrection(Selector Sel, QualType ObjectType = QualType()); + /// LookupImplementedMethodInGlobalPool - Returns the method which has an + /// implementation. + ObjCMethodDecl *LookupImplementedMethodInGlobalPool(Selector Sel); + + void DiagnoseDuplicateIvars(ObjCInterfaceDecl *ID, ObjCInterfaceDecl *SID); + + /// Checks that the Objective-C declaration is declared in the global scope. + /// Emits an error and marks the declaration as invalid if it's not declared + /// in the global scope. + bool CheckObjCDeclScope(Decl *D); + + void ActOnDefs(Scope *S, Decl *TagD, SourceLocation DeclStart, + const IdentifierInfo *ClassName, + SmallVectorImpl &Decls); + + VarDecl *BuildObjCExceptionDecl(TypeSourceInfo *TInfo, QualType ExceptionType, + SourceLocation StartLoc, SourceLocation IdLoc, + const IdentifierInfo *Id, + bool Invalid = false); + + Decl *ActOnObjCExceptionDecl(Scope *S, Declarator &D); + + /// CollectIvarsToConstructOrDestruct - Collect those ivars which require + /// initialization. + void + CollectIvarsToConstructOrDestruct(ObjCInterfaceDecl *OI, + SmallVectorImpl &Ivars); + + void DiagnoseUseOfUnimplementedSelectors(); + + /// DiagnoseUnusedBackingIvarInAccessor - Issue an 'unused' warning if ivar + /// which backs the property is not used in the property's accessor. + void DiagnoseUnusedBackingIvarInAccessor(Scope *S, + const ObjCImplementationDecl *ImplD); + + /// GetIvarBackingPropertyAccessor - If method is a property setter/getter and + /// it property has a backing ivar, returns this ivar; otherwise, returns + /// NULL. It also returns ivar's property on success. + ObjCIvarDecl * + GetIvarBackingPropertyAccessor(const ObjCMethodDecl *Method, + const ObjCPropertyDecl *&PDecl) const; + + /// AddInstanceMethodToGlobalPool - All instance methods in a translation + /// unit are added to a global pool. This allows us to efficiently associate + /// a selector with a method declaraation for purposes of typechecking + /// messages sent to "id" (where the class of the object is unknown). + void AddInstanceMethodToGlobalPool(ObjCMethodDecl *Method, + bool impl = false) { + AddMethodToGlobalPool(Method, impl, /*instance*/ true); + } + + /// AddFactoryMethodToGlobalPool - Same as above, but for factory methods. + void AddFactoryMethodToGlobalPool(ObjCMethodDecl *Method, bool impl = false) { + AddMethodToGlobalPool(Method, impl, /*instance*/ false); + } + + QualType AdjustParameterTypeForObjCAutoRefCount(QualType T, + SourceLocation NameLoc, + TypeSourceInfo *TSInfo); + + /// Look for an Objective-C class in the translation unit. + /// + /// \param Id The name of the Objective-C class we're looking for. If + /// typo-correction fixes this name, the Id will be updated + /// to the fixed name. + /// + /// \param IdLoc The location of the name in the translation unit. + /// + /// \param DoTypoCorrection If true, this routine will attempt typo correction + /// if there is no class with the given name. + /// + /// \returns The declaration of the named Objective-C class, or NULL if the + /// class could not be found. + ObjCInterfaceDecl *getObjCInterfaceDecl(const IdentifierInfo *&Id, + SourceLocation IdLoc, + bool TypoCorrection = false); + + bool inferObjCARCLifetime(ValueDecl *decl); + + /// SetIvarInitializers - This routine builds initialization ASTs for the + /// Objective-C implementation whose ivars need be initialized. + void SetIvarInitializers(ObjCImplementationDecl *ObjCImplementation); + + Decl *ActOnIvar(Scope *S, SourceLocation DeclStart, Declarator &D, + Expr *BitWidth, tok::ObjCKeywordKind visibility); + + ObjCContainerDecl *getObjCDeclContext() const; + +private: + /// AddMethodToGlobalPool - Add an instance or factory method to the global + /// pool. See descriptoin of AddInstanceMethodToGlobalPool. + void AddMethodToGlobalPool(ObjCMethodDecl *Method, bool impl, bool instance); + + /// LookupMethodInGlobalPool - Returns the instance or factory method and + /// optionally warns if there are multiple signatures. + ObjCMethodDecl *LookupMethodInGlobalPool(Selector Sel, SourceRange R, + bool receiverIdOrClass, + bool instance); + + ///@} + + // + // + // ------------------------------------------------------------------------- + // + // + + /// \name ObjC Expressions + /// Implementations are in SemaExprObjC.cpp + ///@{ + +public: + /// Caches identifiers/selectors for NSFoundation APIs. + std::unique_ptr NSAPIObj; + + /// The declaration of the Objective-C NSNumber class. + ObjCInterfaceDecl *NSNumberDecl; + + /// The declaration of the Objective-C NSValue class. + ObjCInterfaceDecl *NSValueDecl; + + /// Pointer to NSNumber type (NSNumber *). + QualType NSNumberPointer; + + /// Pointer to NSValue type (NSValue *). + QualType NSValuePointer; + + /// The Objective-C NSNumber methods used to create NSNumber literals. + ObjCMethodDecl *NSNumberLiteralMethods[NSAPI::NumNSNumberLiteralMethods]; + + /// The declaration of the Objective-C NSString class. + ObjCInterfaceDecl *NSStringDecl; + + /// Pointer to NSString type (NSString *). + QualType NSStringPointer; + + /// The declaration of the stringWithUTF8String: method. + ObjCMethodDecl *StringWithUTF8StringMethod; + + /// The declaration of the valueWithBytes:objCType: method. + ObjCMethodDecl *ValueWithBytesObjCTypeMethod; + + /// The declaration of the Objective-C NSArray class. + ObjCInterfaceDecl *NSArrayDecl; + + /// The declaration of the arrayWithObjects:count: method. + ObjCMethodDecl *ArrayWithObjectsMethod; + + /// The declaration of the Objective-C NSDictionary class. + ObjCInterfaceDecl *NSDictionaryDecl; + + /// The declaration of the dictionaryWithObjects:forKeys:count: method. + ObjCMethodDecl *DictionaryWithObjectsMethod; + + /// id type. + QualType QIDNSCopying; + + /// will hold 'respondsToSelector:' + Selector RespondsToSelectorSel; + + ExprResult HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT, + Expr *BaseExpr, SourceLocation OpLoc, + DeclarationName MemberName, + SourceLocation MemberLoc, + SourceLocation SuperLoc, + QualType SuperType, bool Super); + + ExprResult ActOnClassPropertyRefExpr(const IdentifierInfo &receiverName, + const IdentifierInfo &propertyName, + SourceLocation receiverNameLoc, + SourceLocation propertyNameLoc); + + // ParseObjCStringLiteral - Parse Objective-C string literals. + ExprResult ParseObjCStringLiteral(SourceLocation *AtLocs, + ArrayRef Strings); + + ExprResult BuildObjCStringLiteral(SourceLocation AtLoc, StringLiteral *S); + + /// BuildObjCNumericLiteral - builds an ObjCBoxedExpr AST node for the + /// numeric literal expression. Type of the expression will be "NSNumber *" + /// or "id" if NSNumber is unavailable. + ExprResult BuildObjCNumericLiteral(SourceLocation AtLoc, Expr *Number); + ExprResult ActOnObjCBoolLiteral(SourceLocation AtLoc, SourceLocation ValueLoc, + bool Value); + ExprResult BuildObjCArrayLiteral(SourceRange SR, MultiExprArg Elements); + + /// BuildObjCBoxedExpr - builds an ObjCBoxedExpr AST node for the + /// '@' prefixed parenthesized expression. The type of the expression will + /// either be "NSNumber *", "NSString *" or "NSValue *" depending on the type + /// of ValueType, which is allowed to be a built-in numeric type, "char *", + /// "const char *" or C structure with attribute 'objc_boxable'. + ExprResult BuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr); + + ExprResult BuildObjCSubscriptExpression(SourceLocation RB, Expr *BaseExpr, + Expr *IndexExpr, + ObjCMethodDecl *getterMethod, + ObjCMethodDecl *setterMethod); + + ExprResult + BuildObjCDictionaryLiteral(SourceRange SR, + MutableArrayRef Elements); + + ExprResult BuildObjCEncodeExpression(SourceLocation AtLoc, + TypeSourceInfo *EncodedTypeInfo, + SourceLocation RParenLoc); + + ExprResult ParseObjCEncodeExpression(SourceLocation AtLoc, + SourceLocation EncodeLoc, + SourceLocation LParenLoc, ParsedType Ty, + SourceLocation RParenLoc); + + /// ParseObjCSelectorExpression - Build selector expression for \@selector + ExprResult ParseObjCSelectorExpression(Selector Sel, SourceLocation AtLoc, + SourceLocation SelLoc, + SourceLocation LParenLoc, + SourceLocation RParenLoc, + bool WarnMultipleSelectors); + + /// ParseObjCProtocolExpression - Build protocol expression for \@protocol + ExprResult ParseObjCProtocolExpression(IdentifierInfo *ProtocolName, + SourceLocation AtLoc, + SourceLocation ProtoLoc, + SourceLocation LParenLoc, + SourceLocation ProtoIdLoc, + SourceLocation RParenLoc); + + ObjCMethodDecl *tryCaptureObjCSelf(SourceLocation Loc); + + /// Describes the kind of message expression indicated by a message + /// send that starts with an identifier. + enum ObjCMessageKind { + /// The message is sent to 'super'. + ObjCSuperMessage, + /// The message is an instance message. + ObjCInstanceMessage, + /// The message is a class message, and the identifier is a type + /// name. + ObjCClassMessage + }; + + ObjCMessageKind getObjCMessageKind(Scope *S, IdentifierInfo *Name, + SourceLocation NameLoc, bool IsSuper, + bool HasTrailingDot, + ParsedType &ReceiverType); + + ExprResult ActOnSuperMessage(Scope *S, SourceLocation SuperLoc, Selector Sel, + SourceLocation LBracLoc, + ArrayRef SelectorLocs, + SourceLocation RBracLoc, MultiExprArg Args); + + ExprResult BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo, + QualType ReceiverType, SourceLocation SuperLoc, + Selector Sel, ObjCMethodDecl *Method, + SourceLocation LBracLoc, + ArrayRef SelectorLocs, + SourceLocation RBracLoc, MultiExprArg Args, + bool isImplicit = false); + + ExprResult BuildClassMessageImplicit(QualType ReceiverType, + bool isSuperReceiver, SourceLocation Loc, + Selector Sel, ObjCMethodDecl *Method, + MultiExprArg Args); + + ExprResult ActOnClassMessage(Scope *S, ParsedType Receiver, Selector Sel, + SourceLocation LBracLoc, + ArrayRef SelectorLocs, + SourceLocation RBracLoc, MultiExprArg Args); + + ExprResult BuildInstanceMessage(Expr *Receiver, QualType ReceiverType, + SourceLocation SuperLoc, Selector Sel, + ObjCMethodDecl *Method, + SourceLocation LBracLoc, + ArrayRef SelectorLocs, + SourceLocation RBracLoc, MultiExprArg Args, + bool isImplicit = false); + + ExprResult BuildInstanceMessageImplicit(Expr *Receiver, QualType ReceiverType, + SourceLocation Loc, Selector Sel, + ObjCMethodDecl *Method, + MultiExprArg Args); + + ExprResult ActOnInstanceMessage(Scope *S, Expr *Receiver, Selector Sel, + SourceLocation LBracLoc, + ArrayRef SelectorLocs, + SourceLocation RBracLoc, MultiExprArg Args); + + ExprResult BuildObjCBridgedCast(SourceLocation LParenLoc, + ObjCBridgeCastKind Kind, + SourceLocation BridgeKeywordLoc, + TypeSourceInfo *TSInfo, Expr *SubExpr); + + ExprResult ActOnObjCBridgedCast(Scope *S, SourceLocation LParenLoc, + ObjCBridgeCastKind Kind, + SourceLocation BridgeKeywordLoc, + ParsedType Type, SourceLocation RParenLoc, + Expr *SubExpr); + + void CheckTollFreeBridgeCast(QualType castType, Expr *castExpr); + + void CheckObjCBridgeRelatedCast(QualType castType, Expr *castExpr); + + bool CheckTollFreeBridgeStaticCast(QualType castType, Expr *castExpr, + CastKind &Kind); + + bool checkObjCBridgeRelatedComponents(SourceLocation Loc, QualType DestType, + QualType SrcType, + ObjCInterfaceDecl *&RelatedClass, + ObjCMethodDecl *&ClassMethod, + ObjCMethodDecl *&InstanceMethod, + TypedefNameDecl *&TDNDecl, bool CfToNs, + bool Diagnose = true); + + bool CheckObjCBridgeRelatedConversions(SourceLocation Loc, QualType DestType, + QualType SrcType, Expr *&SrcExpr, + bool Diagnose = true); + + /// Private Helper predicate to check for 'self'. + bool isSelfExpr(Expr *RExpr); + bool isSelfExpr(Expr *RExpr, const ObjCMethodDecl *Method); + + ObjCMethodDecl *LookupMethodInQualifiedType(Selector Sel, + const ObjCObjectPointerType *OPT, + bool IsInstance); + ObjCMethodDecl *LookupMethodInObjectType(Selector Sel, QualType Ty, + bool IsInstance); + + bool isKnownName(StringRef name); + + enum ARCConversionResult { ACR_okay, ACR_unbridged, ACR_error }; + + /// Checks for invalid conversions and casts between + /// retainable pointers and other pointer kinds for ARC and Weak. + ARCConversionResult CheckObjCConversion(SourceRange castRange, + QualType castType, Expr *&op, + CheckedConversionKind CCK, + bool Diagnose = true, + bool DiagnoseCFAudited = false, + BinaryOperatorKind Opc = BO_PtrMemD); + + Expr *stripARCUnbridgedCast(Expr *e); + void diagnoseARCUnbridgedCast(Expr *e); + + bool CheckObjCARCUnavailableWeakConversion(QualType castType, + QualType ExprType); + + /// CheckMessageArgumentTypes - Check types in an Obj-C message send. + /// \param Method - May be null. + /// \param [out] ReturnType - The return type of the send. + /// \return true iff there were any incompatible types. + bool CheckMessageArgumentTypes(const Expr *Receiver, QualType ReceiverType, + MultiExprArg Args, Selector Sel, + ArrayRef SelectorLocs, + ObjCMethodDecl *Method, bool isClassMessage, + bool isSuperMessage, SourceLocation lbrac, + SourceLocation rbrac, SourceRange RecRange, + QualType &ReturnType, ExprValueKind &VK); + + /// Determine the result of a message send expression based on + /// the type of the receiver, the method expected to receive the message, + /// and the form of the message send. + QualType getMessageSendResultType(const Expr *Receiver, QualType ReceiverType, + ObjCMethodDecl *Method, bool isClassMessage, + bool isSuperMessage); + + /// If the given expression involves a message send to a method + /// with a related result type, emit a note describing what happened. + void EmitRelatedResultTypeNote(const Expr *E); + + /// Given that we had incompatible pointer types in a return + /// statement, check whether we're in a method with a related result + /// type, and if so, emit a note describing what happened. + void EmitRelatedResultTypeNoteForReturn(QualType destType); + + /// LookupInstanceMethodInGlobalPool - Returns the method and warns if + /// there are multiple signatures. + ObjCMethodDecl * + LookupInstanceMethodInGlobalPool(Selector Sel, SourceRange R, + bool receiverIdOrClass = false) { + return LookupMethodInGlobalPool(Sel, R, receiverIdOrClass, + /*instance*/ true); + } + + /// LookupFactoryMethodInGlobalPool - Returns the method and warns if + /// there are multiple signatures. + ObjCMethodDecl * + LookupFactoryMethodInGlobalPool(Selector Sel, SourceRange R, + bool receiverIdOrClass = false) { + return LookupMethodInGlobalPool(Sel, R, receiverIdOrClass, + /*instance*/ false); + } + + /// The parser has read a name in, and Sema has detected that we're currently + /// inside an ObjC method. Perform some additional checks and determine if we + /// should form a reference to an ivar. + /// + /// Ideally, most of this would be done by lookup, but there's + /// actually quite a lot of extra work involved. + DeclResult LookupIvarInObjCMethod(LookupResult &Lookup, Scope *S, + IdentifierInfo *II); + + /// The parser has read a name in, and Sema has detected that we're currently + /// inside an ObjC method. Perform some additional checks and determine if we + /// should form a reference to an ivar. If so, build an expression referencing + /// that ivar. + ExprResult LookupInObjCMethod(LookupResult &LookUp, Scope *S, + IdentifierInfo *II, + bool AllowBuiltinCreation = false); + + ExprResult BuildIvarRefExpr(Scope *S, SourceLocation Loc, ObjCIvarDecl *IV); + + /// FindCompositeObjCPointerType - Helper method to find composite type of + /// two objective-c pointer types of the two input expressions. + QualType FindCompositeObjCPointerType(ExprResult &LHS, ExprResult &RHS, + SourceLocation QuestionLoc); + + bool CheckConversionToObjCLiteral(QualType DstType, Expr *&SrcExpr, + bool Diagnose = true); + + /// ActOnObjCBoolLiteral - Parse {__objc_yes,__objc_no} literals. + ExprResult ActOnObjCBoolLiteral(SourceLocation OpLoc, tok::TokenKind Kind); + + ExprResult + ActOnObjCAvailabilityCheckExpr(llvm::ArrayRef AvailSpecs, + SourceLocation AtLoc, SourceLocation RParen); + + /// Prepare a conversion of the given expression to an ObjC object + /// pointer type. + CastKind PrepareCastToObjCObjectPointer(ExprResult &E); + + // Note that LK_String is intentionally after the other literals, as + // this is used for diagnostics logic. + enum ObjCLiteralKind { + LK_Array, + LK_Dictionary, + LK_Numeric, + LK_Boxed, + LK_String, + LK_Block, + LK_None + }; + ObjCLiteralKind CheckLiteralKind(Expr *FromE); + + ///@} + + // + // + // ------------------------------------------------------------------------- + // + // + + /// \name ObjC @property and @synthesize + /// Implementations are in SemaObjCProperty.cpp + ///@{ + +public: + /// Ensure attributes are consistent with type. + /// \param [in, out] Attributes The attributes to check; they will + /// be modified to be consistent with \p PropertyTy. + void CheckObjCPropertyAttributes(Decl *PropertyPtrTy, SourceLocation Loc, + unsigned &Attributes, + bool propertyInPrimaryClass); + + /// Process the specified property declaration and create decls for the + /// setters and getters as needed. + /// \param property The property declaration being processed + void ProcessPropertyDecl(ObjCPropertyDecl *property); + + Decl *ActOnProperty(Scope *S, SourceLocation AtLoc, SourceLocation LParenLoc, + FieldDeclarator &FD, ObjCDeclSpec &ODS, + Selector GetterSel, Selector SetterSel, + tok::ObjCKeywordKind MethodImplKind, + DeclContext *lexicalDC = nullptr); + + Decl *ActOnPropertyImplDecl(Scope *S, SourceLocation AtLoc, + SourceLocation PropertyLoc, bool ImplKind, + IdentifierInfo *PropertyId, + IdentifierInfo *PropertyIvar, + SourceLocation PropertyIvarLoc, + ObjCPropertyQueryKind QueryKind); + + /// Called by ActOnProperty to handle \@property declarations in + /// class extensions. + ObjCPropertyDecl *HandlePropertyInClassExtension( + Scope *S, SourceLocation AtLoc, SourceLocation LParenLoc, + FieldDeclarator &FD, Selector GetterSel, SourceLocation GetterNameLoc, + Selector SetterSel, SourceLocation SetterNameLoc, const bool isReadWrite, + unsigned &Attributes, const unsigned AttributesAsWritten, QualType T, + TypeSourceInfo *TSI, tok::ObjCKeywordKind MethodImplKind); + + /// Called by ActOnProperty and HandlePropertyInClassExtension to + /// handle creating the ObjcPropertyDecl for a category or \@interface. + ObjCPropertyDecl * + CreatePropertyDecl(Scope *S, ObjCContainerDecl *CDecl, SourceLocation AtLoc, + SourceLocation LParenLoc, FieldDeclarator &FD, + Selector GetterSel, SourceLocation GetterNameLoc, + Selector SetterSel, SourceLocation SetterNameLoc, + const bool isReadWrite, const unsigned Attributes, + const unsigned AttributesAsWritten, QualType T, + TypeSourceInfo *TSI, tok::ObjCKeywordKind MethodImplKind, + DeclContext *lexicalDC = nullptr); + + void DiagnosePropertyMismatch(ObjCPropertyDecl *Property, + ObjCPropertyDecl *SuperProperty, + const IdentifierInfo *Name, + bool OverridingProtocolProperty); + + bool DiagnosePropertyAccessorMismatch(ObjCPropertyDecl *PD, + ObjCMethodDecl *Getter, + SourceLocation Loc); + + /// DiagnoseUnimplementedProperties - This routine warns on those properties + /// which must be implemented by this implementation. + void DiagnoseUnimplementedProperties(Scope *S, ObjCImplDecl *IMPDecl, + ObjCContainerDecl *CDecl, + bool SynthesizeProperties); + + /// Diagnose any null-resettable synthesized setters. + void diagnoseNullResettableSynthesizedSetters(const ObjCImplDecl *impDecl); + + /// DefaultSynthesizeProperties - This routine default synthesizes all + /// properties which must be synthesized in the class's \@implementation. + void DefaultSynthesizeProperties(Scope *S, ObjCImplDecl *IMPDecl, + ObjCInterfaceDecl *IDecl, + SourceLocation AtEnd); + void DefaultSynthesizeProperties(Scope *S, Decl *D, SourceLocation AtEnd); + + /// IvarBacksCurrentMethodAccessor - This routine returns 'true' if 'IV' is + /// an ivar synthesized for 'Method' and 'Method' is a property accessor + /// declared in class 'IFace'. + bool IvarBacksCurrentMethodAccessor(ObjCInterfaceDecl *IFace, + ObjCMethodDecl *Method, ObjCIvarDecl *IV); + + void DiagnoseOwningPropertyGetterSynthesis(const ObjCImplementationDecl *D); + + void + DiagnoseMissingDesignatedInitOverrides(const ObjCImplementationDecl *ImplD, + const ObjCInterfaceDecl *IFD); + + /// AtomicPropertySetterGetterRules - This routine enforces the rule (via + /// warning) when atomic property has one but not the other user-declared + /// setter or getter. + void AtomicPropertySetterGetterRules(ObjCImplDecl *IMPDecl, + ObjCInterfaceDecl *IDecl); + + ///@} + +}; + +} // namespace clang + +#endif // LLVM_CLANG_SEMA_SEMAOBJC_H diff --git a/clang/lib/ARCMigrate/Transforms.cpp b/clang/lib/ARCMigrate/Transforms.cpp index 2808e35135dc3..fda0e1c932fc0 100644 --- a/clang/lib/ARCMigrate/Transforms.cpp +++ b/clang/lib/ARCMigrate/Transforms.cpp @@ -17,6 +17,7 @@ #include "clang/Lex/Lexer.h" #include "clang/Lex/Preprocessor.h" #include "clang/Sema/Sema.h" +#include "clang/Sema/SemaObjC.h" using namespace clang; using namespace arcmt; @@ -26,8 +27,8 @@ ASTTraverser::~ASTTraverser() { } bool MigrationPass::CFBridgingFunctionsDefined() { if (!EnableCFBridgeFns) - EnableCFBridgeFns = SemaRef.isKnownName("CFBridgingRetain") && - SemaRef.isKnownName("CFBridgingRelease"); + EnableCFBridgeFns = SemaRef.ObjC().isKnownName("CFBridgingRetain") && + SemaRef.ObjC().isKnownName("CFBridgingRelease"); return *EnableCFBridgeFns; } diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index 274ee7b10c178..b678c67032b42 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -28,6 +28,7 @@ #include "clang/Sema/Scope.h" #include "clang/Sema/SemaCUDA.h" #include "clang/Sema/SemaDiagnostic.h" +#include "clang/Sema/SemaObjC.h" #include "clang/Sema/SemaOpenMP.h" #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/SmallString.h" @@ -3918,7 +3919,7 @@ void Parser::ParseDeclarationSpecifiers( if (DSContext == DeclSpecContext::DSC_objc_method_result && isObjCInstancetype()) { - ParsedType TypeRep = Actions.ActOnObjCInstanceType(Loc); + ParsedType TypeRep = Actions.ObjC().ActOnObjCInstanceType(Loc); assert(TypeRep); isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, DiagID, TypeRep, Policy); @@ -4972,7 +4973,7 @@ void Parser::ParseStructUnionBody(SourceLocation RecordLoc, continue; } SmallVector Fields; - Actions.ActOnDefs(getCurScope(), TagDecl, Tok.getLocation(), + Actions.ObjC().ActOnDefs(getCurScope(), TagDecl, Tok.getLocation(), Tok.getIdentifierInfo(), Fields); ConsumeToken(); ExpectAndConsume(tok::r_paren); diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp index 32d96f81c4c8d..ec0c560f0b627 100644 --- a/clang/lib/Parse/ParseExpr.cpp +++ b/clang/lib/Parse/ParseExpr.cpp @@ -31,6 +31,7 @@ #include "clang/Sema/ParsedTemplate.h" #include "clang/Sema/Scope.h" #include "clang/Sema/SemaCUDA.h" +#include "clang/Sema/SemaObjC.h" #include "clang/Sema/SemaOpenMP.h" #include "clang/Sema/SemaSYCL.h" #include "clang/Sema/TypoCorrection.h" @@ -1227,7 +1228,7 @@ ExprResult Parser::ParseCastExpression(CastParseKind ParseKind, IdentifierInfo &PropertyName = *Tok.getIdentifierInfo(); SourceLocation PropertyLoc = ConsumeToken(); - Res = Actions.ActOnClassPropertyRefExpr(II, PropertyName, + Res = Actions.ObjC().ActOnClassPropertyRefExpr(II, PropertyName, ILoc, PropertyLoc); break; } @@ -3085,7 +3086,7 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr, if (Ty.isInvalid() || SubExpr.isInvalid()) return ExprError(); - return Actions.ActOnObjCBridgedCast(getCurScope(), OpenLoc, Kind, + return Actions.ObjC().ActOnObjCBridgedCast(getCurScope(), OpenLoc, Kind, BridgeKeywordLoc, Ty.get(), RParenLoc, SubExpr.get()); } else if (ExprType >= CompoundLiteral && @@ -3803,7 +3804,7 @@ ExprResult Parser::ParseBlockLiteralExpression() { /// '__objc_no' ExprResult Parser::ParseObjCBoolLiteral() { tok::TokenKind Kind = Tok.getKind(); - return Actions.ActOnObjCBoolLiteral(ConsumeToken(), Kind); + return Actions.ObjC().ActOnObjCBoolLiteral(ConsumeToken(), Kind); } /// Validate availability spec list, emitting diagnostics if necessary. Returns @@ -3924,6 +3925,6 @@ ExprResult Parser::ParseAvailabilityCheckExpr(SourceLocation BeginLoc) { if (Parens.consumeClose()) return ExprError(); - return Actions.ActOnObjCAvailabilityCheckExpr(AvailSpecs, BeginLoc, + return Actions.ObjC().ActOnObjCAvailabilityCheckExpr(AvailSpecs, BeginLoc, Parens.getCloseLocation()); } diff --git a/clang/lib/Parse/ParseInit.cpp b/clang/lib/Parse/ParseInit.cpp index 423497bfcb662..04e4419f4d459 100644 --- a/clang/lib/Parse/ParseInit.cpp +++ b/clang/lib/Parse/ParseInit.cpp @@ -18,6 +18,7 @@ #include "clang/Sema/EnterExpressionEvaluationContext.h" #include "clang/Sema/Ownership.h" #include "clang/Sema/Scope.h" +#include "clang/Sema/SemaObjC.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallString.h" using namespace clang; @@ -290,15 +291,15 @@ ExprResult Parser::ParseInitializerWithPotentialDesignator( // Three cases. This is a message send to a type: [type foo] // This is a message send to super: [super foo] // This is a message sent to an expr: [super.bar foo] - switch (Actions.getObjCMessageKind( + switch (Actions.ObjC().getObjCMessageKind( getCurScope(), II, IILoc, II == Ident_super, NextToken().is(tok::period), ReceiverType)) { - case Sema::ObjCSuperMessage: + case SemaObjC::ObjCSuperMessage: CheckArrayDesignatorSyntax(*this, StartLoc, Desig); return ParseAssignmentExprWithObjCMessageExprStart( StartLoc, ConsumeToken(), nullptr, nullptr); - case Sema::ObjCClassMessage: + case SemaObjC::ObjCClassMessage: CheckArrayDesignatorSyntax(*this, StartLoc, Desig); ConsumeToken(); // the identifier if (!ReceiverType) { @@ -326,7 +327,7 @@ ExprResult Parser::ParseInitializerWithPotentialDesignator( ReceiverType, nullptr); - case Sema::ObjCInstanceMessage: + case SemaObjC::ObjCInstanceMessage: // Fall through; we'll just parse the expression and // (possibly) treat this like an Objective-C message send // later. diff --git a/clang/lib/Parse/ParseObjc.cpp b/clang/lib/Parse/ParseObjc.cpp index 671dcb71e51a3..8d28311b3d7b2 100644 --- a/clang/lib/Parse/ParseObjc.cpp +++ b/clang/lib/Parse/ParseObjc.cpp @@ -19,6 +19,7 @@ #include "clang/Parse/Parser.h" #include "clang/Parse/RAIIObjectsForParser.h" #include "clang/Sema/DeclSpec.h" +#include "clang/Sema/SemaObjC.h" #include "clang/Sema/Scope.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringExtras.h" @@ -132,7 +133,7 @@ class Parser::ObjCTypeParamListScope { void leave() { if (Params) - Actions.popObjCTypeParamList(S, Params); + Actions.ObjC().popObjCTypeParamList(S, Params); Params = nullptr; } }; @@ -179,7 +180,7 @@ Parser::ParseObjCAtClassDeclaration(SourceLocation atLoc) { if (ExpectAndConsume(tok::semi, diag::err_expected_after, "@class")) return Actions.ConvertDeclToDeclGroup(nullptr); - return Actions.ActOnForwardClassDeclaration(atLoc, ClassNames.data(), + return Actions.ObjC().ActOnForwardClassDeclaration(atLoc, ClassNames.data(), ClassLocs.data(), ClassTypeParams, ClassNames.size()); @@ -187,15 +188,15 @@ Parser::ParseObjCAtClassDeclaration(SourceLocation atLoc) { void Parser::CheckNestedObjCContexts(SourceLocation AtLoc) { - Sema::ObjCContainerKind ock = Actions.getObjCContainerKind(); - if (ock == Sema::OCK_None) + SemaObjC::ObjCContainerKind ock = Actions.ObjC().getObjCContainerKind(); + if (ock == SemaObjC::OCK_None) return; - Decl *Decl = Actions.getObjCDeclContext(); + Decl *Decl = Actions.ObjC().getObjCDeclContext(); if (CurParsedObjCImpl) { CurParsedObjCImpl->finish(AtLoc); } else { - Actions.ActOnAtEnd(getCurScope(), AtLoc); + Actions.ObjC().ActOnAtEnd(getCurScope(), AtLoc); } Diag(AtLoc, diag::err_objc_missing_end) << FixItHint::CreateInsertion(AtLoc, "@end\n"); @@ -305,7 +306,7 @@ Decl *Parser::ParseObjCAtInterfaceDeclaration(SourceLocation AtLoc, /*consumeLastToken=*/true)) return nullptr; - ObjCCategoryDecl *CategoryType = Actions.ActOnStartCategoryInterface( + ObjCCategoryDecl *CategoryType = Actions.ObjC().ActOnStartCategoryInterface( AtLoc, nameId, nameLoc, typeParameterList, categoryId, categoryLoc, ProtocolRefs.data(), ProtocolRefs.size(), ProtocolLocs.data(), EndProtoLoc, attrs); @@ -360,7 +361,7 @@ Decl *Parser::ParseObjCAtInterfaceDeclaration(SourceLocation AtLoc, for (const auto &pair : ProtocolIdents) { protocolLocs.push_back(pair.second); } - Actions.FindProtocolDeclaration(/*WarnOnDeclarations=*/true, + Actions.ObjC().FindProtocolDeclaration(/*WarnOnDeclarations=*/true, /*ForObjCContainer=*/true, ProtocolIdents, protocols); } @@ -372,11 +373,11 @@ Decl *Parser::ParseObjCAtInterfaceDeclaration(SourceLocation AtLoc, } if (Tok.isNot(tok::less)) - Actions.ActOnTypedefedProtocols(protocols, protocolLocs, + Actions.ObjC().ActOnTypedefedProtocols(protocols, protocolLocs, superClassId, superClassLoc); SkipBodyInfo SkipBody; - ObjCInterfaceDecl *ClsType = Actions.ActOnStartClassInterface( + ObjCInterfaceDecl *ClsType = Actions.ObjC().ActOnStartClassInterface( getCurScope(), AtLoc, nameId, nameLoc, typeParameterList, superClassId, superClassLoc, typeArgs, SourceRange(typeArgsLAngleLoc, typeArgsRAngleLoc), protocols.data(), @@ -468,7 +469,7 @@ ObjCTypeParamList *Parser::parseObjCTypeParamListOrProtocolRefs( auto makeProtocolIdentsIntoTypeParameters = [&]() { unsigned index = 0; for (const auto &pair : protocolIdents) { - DeclResult typeParam = Actions.actOnObjCTypeParam( + DeclResult typeParam = Actions.ObjC().actOnObjCTypeParam( getCurScope(), ObjCTypeParamVariance::Invariant, SourceLocation(), index++, pair.first, pair.second, SourceLocation(), nullptr); if (typeParam.isUsable()) @@ -546,7 +547,7 @@ ObjCTypeParamList *Parser::parseObjCTypeParamListOrProtocolRefs( } // Create the type parameter. - DeclResult typeParam = Actions.actOnObjCTypeParam( + DeclResult typeParam = Actions.ObjC().actOnObjCTypeParam( getCurScope(), variance, varianceLoc, typeParams.size(), paramName, paramLoc, colonLoc, boundType.isUsable() ? boundType.get() : nullptr); if (typeParam.isUsable()) @@ -587,7 +588,7 @@ ObjCTypeParamList *Parser::parseObjCTypeParamListOrProtocolRefs( } // Form the type parameter list and enter its scope. - ObjCTypeParamList *list = Actions.actOnObjCTypeParamList( + ObjCTypeParamList *list = Actions.ObjC().actOnObjCTypeParamList( getCurScope(), lAngleLoc, typeParams, @@ -811,7 +812,7 @@ void Parser::ParseObjCInterfaceDeclList(tok::ObjCKeywordKind contextKey, SetterSel = SelectorTable::constructSetterSelector( PP.getIdentifierTable(), PP.getSelectorTable(), FD.D.getIdentifier()); - Decl *Property = Actions.ActOnProperty( + Decl *Property = Actions.ObjC().ActOnProperty( getCurScope(), AtLoc, LParenLoc, FD, OCDS, GetterSel, SetterSel, MethodImplKind); @@ -836,14 +837,14 @@ void Parser::ParseObjCInterfaceDeclList(tok::ObjCKeywordKind contextKey, Diag(Tok, diag::err_objc_missing_end) << FixItHint::CreateInsertion(Tok.getLocation(), "\n@end\n"); Diag(CDecl->getBeginLoc(), diag::note_objc_container_start) - << (int)Actions.getObjCContainerKind(); + << (int)Actions.ObjC().getObjCContainerKind(); AtEnd.setBegin(Tok.getLocation()); AtEnd.setEnd(Tok.getLocation()); } // Insert collected methods declarations into the @interface object. // This passes in an invalid SourceLocation for AtEndLoc when EOF is hit. - Actions.ActOnAtEnd(getCurScope(), AtEnd, allMethods, allTUVariables); + Actions.ObjC().ActOnAtEnd(getCurScope(), AtEnd, allMethods, allTUVariables); } /// Diagnose redundant or conflicting nullability information. @@ -1437,7 +1438,7 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc, methodAttrs); Selector Sel = PP.getSelectorTable().getNullarySelector(SelIdent); - Decl *Result = Actions.ActOnMethodDeclaration( + Decl *Result = Actions.ObjC().ActOnMethodDeclaration( getCurScope(), mLoc, Tok.getLocation(), mType, DSRet, ReturnType, selLoc, Sel, nullptr, CParamInfo.data(), CParamInfo.size(), methodAttrs, MethodImplKind, false, MethodDefinition); @@ -1447,14 +1448,14 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc, SmallVector KeyIdents; SmallVector KeyLocs; - SmallVector ArgInfos; + SmallVector ArgInfos; ParseScope PrototypeScope(this, Scope::FunctionPrototypeScope | Scope::FunctionDeclarationScope | Scope::DeclScope); AttributePool allParamAttrs(AttrFactory); while (true) { ParsedAttributes paramAttrs(AttrFactory); - Sema::ObjCArgInfo ArgInfo; + SemaObjC::ObjCArgInfo ArgInfo; // Each iteration parses a single keyword argument. if (ExpectAndConsume(tok::colon)) @@ -1559,7 +1560,7 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc, Selector Sel = PP.getSelectorTable().getSelector(KeyIdents.size(), &KeyIdents[0]); - Decl *Result = Actions.ActOnMethodDeclaration( + Decl *Result = Actions.ObjC().ActOnMethodDeclaration( getCurScope(), mLoc, Tok.getLocation(), mType, DSRet, ReturnType, KeyLocs, Sel, &ArgInfos[0], CParamInfo.data(), CParamInfo.size(), methodAttrs, MethodImplKind, isVariadic, MethodDefinition); @@ -1609,7 +1610,7 @@ ParseObjCProtocolReferences(SmallVectorImpl &Protocols, return true; // Convert the list of protocols identifiers into a list of protocol decls. - Actions.FindProtocolDeclaration(WarnOnDeclarations, ForObjCContainer, + Actions.ObjC().FindProtocolDeclaration(WarnOnDeclarations, ForObjCContainer, ProtocolIdents, Protocols); return false; } @@ -1624,7 +1625,7 @@ TypeResult Parser::parseObjCProtocolQualifierType(SourceLocation &rAngleLoc) { (void)ParseObjCProtocolReferences(protocols, protocolLocs, false, false, lAngleLoc, rAngleLoc, /*consumeLastToken=*/true); - TypeResult result = Actions.actOnObjCProtocolQualifierType(lAngleLoc, + TypeResult result = Actions.ObjC().actOnObjCProtocolQualifierType(lAngleLoc, protocols, protocolLocs, rAngleLoc); @@ -1706,7 +1707,7 @@ void Parser::parseObjCTypeArgsOrProtocolQualifiers( /*ObjCGenericList=*/true); // Let Sema figure out what we parsed. - Actions.actOnObjCTypeArgsOrProtocolQualifiers(getCurScope(), + Actions.ObjC().actOnObjCTypeArgsOrProtocolQualifiers(getCurScope(), baseType, lAngleLoc, identifiers, @@ -1761,7 +1762,7 @@ void Parser::parseObjCTypeArgsOrProtocolQualifiers( } } else { invalid = true; - if (!Actions.LookupProtocol(identifiers[i], identifierLocs[i])) { + if (!Actions.ObjC().LookupProtocol(identifiers[i], identifierLocs[i])) { unknownTypeArgs.push_back(identifiers[i]); unknownTypeArgsLoc.push_back(identifierLocs[i]); } else if (!foundProtocolId) { @@ -1796,7 +1797,7 @@ void Parser::parseObjCTypeArgsOrProtocolQualifiers( // Diagnose the mix between type args and protocols. if (foundProtocolId && foundValidTypeId) - Actions.DiagnoseTypeArgsAndProtocols(foundProtocolId, foundProtocolSrcLoc, + Actions.ObjC().DiagnoseTypeArgsAndProtocols(foundProtocolId, foundProtocolSrcLoc, foundValidTypeId, foundValidTypeSrcLoc); @@ -1904,7 +1905,7 @@ TypeResult Parser::parseObjCTypeArgsAndProtocolQualifiers( else endLoc = Tok.getLocation(); - return Actions.actOnObjCTypeArgsAndProtocolQualifiers( + return Actions.ObjC().actOnObjCTypeArgsAndProtocolQualifiers( getCurScope(), loc, type, @@ -2029,7 +2030,7 @@ void Parser::ParseObjCClassInstanceVariables(ObjCContainerDecl *interfaceDecl, "Ivar should have interfaceDecl as its decl context"); // Install the declarator into the interface decl. FD.D.setObjCIvar(true); - Decl *Field = Actions.ActOnIvar( + Decl *Field = Actions.ObjC().ActOnIvar( getCurScope(), FD.D.getDeclSpec().getSourceRange().getBegin(), FD.D, FD.BitfieldSize, visibility); if (Field) @@ -2092,7 +2093,7 @@ Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc, if (TryConsumeToken(tok::semi)) { // forward declaration of one protocol. IdentifierLocPair ProtoInfo(protocolName, nameLoc); - return Actions.ActOnForwardProtocolDeclaration(AtLoc, ProtoInfo, attrs); + return Actions.ObjC().ActOnForwardProtocolDeclaration(AtLoc, ProtoInfo, attrs); } CheckNestedObjCContexts(AtLoc); @@ -2119,7 +2120,7 @@ Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc, if (ExpectAndConsume(tok::semi, diag::err_expected_after, "@protocol")) return nullptr; - return Actions.ActOnForwardProtocolDeclaration(AtLoc, ProtocolRefs, attrs); + return Actions.ObjC().ActOnForwardProtocolDeclaration(AtLoc, ProtocolRefs, attrs); } // Last, and definitely not least, parse a protocol declaration. @@ -2134,7 +2135,7 @@ Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc, return nullptr; SkipBodyInfo SkipBody; - ObjCProtocolDecl *ProtoType = Actions.ActOnStartProtocolInterface( + ObjCProtocolDecl *ProtoType = Actions.ObjC().ActOnStartProtocolInterface( AtLoc, protocolName, nameLoc, ProtocolRefs.data(), ProtocolRefs.size(), ProtocolLocs.data(), EndProtoLoc, attrs, &SkipBody); @@ -2241,7 +2242,7 @@ Parser::ParseObjCAtImplementationDeclaration(SourceLocation AtLoc, protocolLAngleLoc, protocolRAngleLoc, /*consumeLastToken=*/true); } - ObjCImpDecl = Actions.ActOnStartCategoryImplementation( + ObjCImpDecl = Actions.ObjC().ActOnStartCategoryImplementation( AtLoc, nameId, nameLoc, categoryId, categoryLoc, Attrs); } else { @@ -2255,7 +2256,7 @@ Parser::ParseObjCAtImplementationDeclaration(SourceLocation AtLoc, superClassId = Tok.getIdentifierInfo(); superClassLoc = ConsumeToken(); // Consume super class name } - ObjCImpDecl = Actions.ActOnStartClassImplementation( + ObjCImpDecl = Actions.ObjC().ActOnStartClassImplementation( AtLoc, nameId, nameLoc, superClassId, superClassLoc, Attrs); if (Tok.is(tok::l_brace)) // we have ivars @@ -2291,7 +2292,7 @@ Parser::ParseObjCAtImplementationDeclaration(SourceLocation AtLoc, } } - return Actions.ActOnFinishObjCImplementation(ObjCImpDecl, DeclsInGroup); + return Actions.ObjC().ActOnFinishObjCImplementation(ObjCImpDecl, DeclsInGroup); } Parser::DeclGroupPtrTy @@ -2314,7 +2315,7 @@ Parser::ObjCImplParsingDataRAII::~ObjCImplParsingDataRAII() { P.Diag(P.Tok, diag::err_objc_missing_end) << FixItHint::CreateInsertion(P.Tok.getLocation(), "\n@end\n"); P.Diag(Dcl->getBeginLoc(), diag::note_objc_container_start) - << Sema::OCK_Implementation; + << SemaObjC::OCK_Implementation; } } P.CurParsedObjCImpl = nullptr; @@ -2323,12 +2324,12 @@ Parser::ObjCImplParsingDataRAII::~ObjCImplParsingDataRAII() { void Parser::ObjCImplParsingDataRAII::finish(SourceRange AtEnd) { assert(!Finished); - P.Actions.DefaultSynthesizeProperties(P.getCurScope(), Dcl, AtEnd.getBegin()); + P.Actions.ObjC().DefaultSynthesizeProperties(P.getCurScope(), Dcl, AtEnd.getBegin()); for (size_t i = 0; i < LateParsedObjCMethods.size(); ++i) P.ParseLexedObjCMethodDefs(*LateParsedObjCMethods[i], true/*Methods*/); - P.Actions.ActOnAtEnd(P.getCurScope(), AtEnd); + P.Actions.ObjC().ActOnAtEnd(P.getCurScope(), AtEnd); if (HasCFunction) for (size_t i = 0; i < LateParsedObjCMethods.size(); ++i) @@ -2361,7 +2362,7 @@ Decl *Parser::ParseObjCAtAliasDeclaration(SourceLocation atLoc) { IdentifierInfo *classId = Tok.getIdentifierInfo(); SourceLocation classLoc = ConsumeToken(); // consume class-name; ExpectAndConsume(tok::semi, diag::err_expected_after, "@compatibility_alias"); - return Actions.ActOnCompatibilityAlias(atLoc, aliasId, aliasLoc, + return Actions.ObjC().ActOnCompatibilityAlias(atLoc, aliasId, aliasLoc, classId, classLoc); } @@ -2411,7 +2412,7 @@ Decl *Parser::ParseObjCPropertySynthesize(SourceLocation atLoc) { propertyIvar = Tok.getIdentifierInfo(); propertyIvarLoc = ConsumeToken(); // consume ivar-name } - Actions.ActOnPropertyImplDecl( + Actions.ObjC().ActOnPropertyImplDecl( getCurScope(), atLoc, propertyLoc, true, propertyId, propertyIvar, propertyIvarLoc, ObjCPropertyQueryKind::OBJC_PR_query_unknown); @@ -2473,7 +2474,7 @@ Decl *Parser::ParseObjCPropertyDynamic(SourceLocation atLoc) { IdentifierInfo *propertyId = Tok.getIdentifierInfo(); SourceLocation propertyLoc = ConsumeToken(); // consume property name - Actions.ActOnPropertyImplDecl( + Actions.ObjC().ActOnPropertyImplDecl( getCurScope(), atLoc, propertyLoc, false, propertyId, nullptr, SourceLocation(), isClassProperty ? ObjCPropertyQueryKind::OBJC_PR_query_class : @@ -2502,7 +2503,7 @@ StmtResult Parser::ParseObjCThrowStmt(SourceLocation atLoc) { } // consume ';' ExpectAndConsume(tok::semi, diag::err_expected_after, "@throw"); - return Actions.ActOnObjCAtThrowStmt(atLoc, Res.get(), getCurScope()); + return Actions.ObjC().ActOnObjCAtThrowStmt(atLoc, Res.get(), getCurScope()); } /// objc-synchronized-statement: @@ -2539,7 +2540,7 @@ Parser::ParseObjCSynchronizedStmt(SourceLocation atLoc) { // Check the @synchronized operand now. if (!operand.isInvalid()) - operand = Actions.ActOnObjCAtSynchronizedOperand(atLoc, operand.get()); + operand = Actions.ObjC().ActOnObjCAtSynchronizedOperand(atLoc, operand.get()); // Parse the compound statement within a new scope. ParseScope bodyScope(this, Scope::DeclScope | Scope::CompoundStmtScope); @@ -2554,7 +2555,7 @@ Parser::ParseObjCSynchronizedStmt(SourceLocation atLoc) { if (body.isInvalid()) body = Actions.ActOnNullStmt(Tok.getLocation()); - return Actions.ActOnObjCAtSynchronizedStmt(atLoc, operand.get(), body.get()); + return Actions.ObjC().ActOnObjCAtSynchronizedStmt(atLoc, operand.get(), body.get()); } /// objc-try-catch-statement: @@ -2611,7 +2612,7 @@ StmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) { // Inform the actions module about the declarator, so it // gets added to the current scope. - FirstPart = Actions.ActOnObjCExceptionDecl(getCurScope(), ParmDecl); + FirstPart = Actions.ObjC().ActOnObjCExceptionDecl(getCurScope(), ParmDecl); } else ConsumeToken(); // consume '...' @@ -2630,7 +2631,7 @@ StmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) { if (CatchBody.isInvalid()) CatchBody = Actions.ActOnNullStmt(Tok.getLocation()); - StmtResult Catch = Actions.ActOnObjCAtCatchStmt(AtCatchFinallyLoc, + StmtResult Catch = Actions.ObjC().ActOnObjCAtCatchStmt(AtCatchFinallyLoc, RParenLoc, FirstPart, CatchBody.get()); @@ -2669,7 +2670,7 @@ StmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) { FinallyBody = Actions.ActOnCapturedRegionEnd(FinallyBody.get()); } - FinallyStmt = Actions.ActOnObjCAtFinallyStmt(AtCatchFinallyLoc, + FinallyStmt = Actions.ObjC().ActOnObjCAtFinallyStmt(AtCatchFinallyLoc, FinallyBody.get()); catch_or_finally_seen = true; break; @@ -2680,7 +2681,7 @@ StmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) { return StmtError(); } - return Actions.ActOnObjCAtTryStmt(atLoc, TryBody.get(), + return Actions.ObjC().ActOnObjCAtTryStmt(atLoc, TryBody.get(), CatchStmts, FinallyStmt.get()); } @@ -2704,7 +2705,7 @@ Parser::ParseObjCAutoreleasePoolStmt(SourceLocation atLoc) { BodyScope.Exit(); if (AutoreleasePoolBody.isInvalid()) AutoreleasePoolBody = Actions.ActOnNullStmt(Tok.getLocation()); - return Actions.ActOnObjCAutoreleasePoolStmt(atLoc, + return Actions.ObjC().ActOnObjCAutoreleasePoolStmt(atLoc, AutoreleasePoolBody.get()); } @@ -2788,7 +2789,7 @@ Decl *Parser::ParseObjCMethodDefinition() { } // Allow the rest of sema to find private method decl implementations. - Actions.AddAnyMethodToGlobalPool(MDecl); + Actions.ObjC().AddAnyMethodToGlobalPool(MDecl); assert (CurParsedObjCImpl && "ParseObjCMethodDefinition - Method out of @implementation"); // Consume the tokens and store them for later parsing. @@ -2872,7 +2873,7 @@ ExprResult Parser::ParseObjCAtExpression(SourceLocation AtLoc) { return Lit; return ParsePostfixExpressionSuffix( - Actions.BuildObjCNumericLiteral(AtLoc, Lit.get())); + Actions.ObjC().BuildObjCNumericLiteral(AtLoc, Lit.get())); } case tok::string_literal: // primary-expression: string-literal @@ -3128,15 +3129,15 @@ ExprResult Parser::ParseObjCMessageExpression() { IdentifierInfo *Name = Tok.getIdentifierInfo(); SourceLocation NameLoc = Tok.getLocation(); ParsedType ReceiverType; - switch (Actions.getObjCMessageKind(getCurScope(), Name, NameLoc, + switch (Actions.ObjC().getObjCMessageKind(getCurScope(), Name, NameLoc, Name == Ident_super, NextToken().is(tok::period), ReceiverType)) { - case Sema::ObjCSuperMessage: + case SemaObjC::ObjCSuperMessage: return ParseObjCMessageExpressionBody(LBracLoc, ConsumeToken(), nullptr, nullptr); - case Sema::ObjCClassMessage: + case SemaObjC::ObjCClassMessage: if (!ReceiverType) { SkipUntil(tok::r_square, StopAtSemi); return ExprError(); @@ -3162,7 +3163,7 @@ ExprResult Parser::ParseObjCMessageExpression() { return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(), ReceiverType, nullptr); - case Sema::ObjCInstanceMessage: + case SemaObjC::ObjCInstanceMessage: // Fall through to parse an expression. break; } @@ -3375,12 +3376,12 @@ Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc, Selector Sel = PP.getSelectorTable().getSelector(nKeys, &KeyIdents[0]); if (SuperLoc.isValid()) - return Actions.ActOnSuperMessage(getCurScope(), SuperLoc, Sel, + return Actions.ObjC().ActOnSuperMessage(getCurScope(), SuperLoc, Sel, LBracLoc, KeyLocs, RBracLoc, KeyExprs); else if (ReceiverType) - return Actions.ActOnClassMessage(getCurScope(), ReceiverType, Sel, + return Actions.ObjC().ActOnClassMessage(getCurScope(), ReceiverType, Sel, LBracLoc, KeyLocs, RBracLoc, KeyExprs); - return Actions.ActOnInstanceMessage(getCurScope(), ReceiverExpr, Sel, + return Actions.ObjC().ActOnInstanceMessage(getCurScope(), ReceiverExpr, Sel, LBracLoc, KeyLocs, RBracLoc, KeyExprs); } @@ -3410,7 +3411,7 @@ ExprResult Parser::ParseObjCStringLiteral(SourceLocation AtLoc) { AtStrings.push_back(Lit.get()); } - return Actions.ParseObjCStringLiteral(AtLocs.data(), AtStrings); + return Actions.ObjC().ParseObjCStringLiteral(AtLocs.data(), AtStrings); } /// ParseObjCBooleanLiteral - @@ -3421,7 +3422,7 @@ ExprResult Parser::ParseObjCStringLiteral(SourceLocation AtLoc) { ExprResult Parser::ParseObjCBooleanLiteral(SourceLocation AtLoc, bool ArgValue) { SourceLocation EndLoc = ConsumeToken(); // consume the keyword. - return Actions.ActOnObjCBoolLiteral(AtLoc, EndLoc, ArgValue); + return Actions.ObjC().ActOnObjCBoolLiteral(AtLoc, EndLoc, ArgValue); } /// ParseObjCCharacterLiteral - @@ -3433,7 +3434,7 @@ ExprResult Parser::ParseObjCCharacterLiteral(SourceLocation AtLoc) { return Lit; } ConsumeToken(); // Consume the literal token. - return Actions.BuildObjCNumericLiteral(AtLoc, Lit.get()); + return Actions.ObjC().BuildObjCNumericLiteral(AtLoc, Lit.get()); } /// ParseObjCNumericLiteral - @@ -3447,7 +3448,7 @@ ExprResult Parser::ParseObjCNumericLiteral(SourceLocation AtLoc) { return Lit; } ConsumeToken(); // Consume the literal token. - return Actions.BuildObjCNumericLiteral(AtLoc, Lit.get()); + return Actions.ObjC().BuildObjCNumericLiteral(AtLoc, Lit.get()); } /// ParseObjCBoxedExpr - @@ -3471,7 +3472,7 @@ Parser::ParseObjCBoxedExpr(SourceLocation AtLoc) { // a boxed expression from a literal. SourceLocation LPLoc = T.getOpenLocation(), RPLoc = T.getCloseLocation(); ValueExpr = Actions.ActOnParenExpr(LPLoc, RPLoc, ValueExpr.get()); - return Actions.BuildObjCBoxedExpr(SourceRange(AtLoc, RPLoc), + return Actions.ObjC().BuildObjCBoxedExpr(SourceRange(AtLoc, RPLoc), ValueExpr.get()); } @@ -3515,7 +3516,7 @@ ExprResult Parser::ParseObjCArrayLiteral(SourceLocation AtLoc) { return ExprError(); MultiExprArg Args(ElementExprs); - return Actions.BuildObjCArrayLiteral(SourceRange(AtLoc, EndLoc), Args); + return Actions.ObjC().BuildObjCArrayLiteral(SourceRange(AtLoc, EndLoc), Args); } ExprResult Parser::ParseObjCDictionaryLiteral(SourceLocation AtLoc) { @@ -3580,7 +3581,7 @@ ExprResult Parser::ParseObjCDictionaryLiteral(SourceLocation AtLoc) { return ExprError(); // Create the ObjCDictionaryLiteral. - return Actions.BuildObjCDictionaryLiteral(SourceRange(AtLoc, EndLoc), + return Actions.ObjC().BuildObjCDictionaryLiteral(SourceRange(AtLoc, EndLoc), Elements); } @@ -3605,7 +3606,7 @@ Parser::ParseObjCEncodeExpression(SourceLocation AtLoc) { if (Ty.isInvalid()) return ExprError(); - return Actions.ParseObjCEncodeExpression(AtLoc, EncLoc, T.getOpenLocation(), + return Actions.ObjC().ParseObjCEncodeExpression(AtLoc, EncLoc, T.getOpenLocation(), Ty.get(), T.getCloseLocation()); } @@ -3629,7 +3630,7 @@ Parser::ParseObjCProtocolExpression(SourceLocation AtLoc) { T.consumeClose(); - return Actions.ParseObjCProtocolExpression(protocolId, AtLoc, ProtoLoc, + return Actions.ObjC().ParseObjCProtocolExpression(protocolId, AtLoc, ProtoLoc, T.getOpenLocation(), ProtoIdLoc, T.getCloseLocation()); } @@ -3695,7 +3696,7 @@ ExprResult Parser::ParseObjCSelectorExpression(SourceLocation AtLoc) { ConsumeParen(); // ')' T.consumeClose(); Selector Sel = PP.getSelectorTable().getSelector(nColons, &KeyIdents[0]); - return Actions.ParseObjCSelectorExpression(Sel, AtLoc, SelectorLoc, + return Actions.ObjC().ParseObjCSelectorExpression(Sel, AtLoc, SelectorLoc, T.getOpenLocation(), T.getCloseLocation(), !HasOptionalParen); @@ -3705,8 +3706,8 @@ void Parser::ParseLexedObjCMethodDefs(LexedMethod &LM, bool parseMethod) { // MCDecl might be null due to error in method or c-function prototype, etc. Decl *MCDecl = LM.D; bool skip = MCDecl && - ((parseMethod && !Actions.isObjCMethodDecl(MCDecl)) || - (!parseMethod && Actions.isObjCMethodDecl(MCDecl))); + ((parseMethod && !Actions.ObjC().isObjCMethodDecl(MCDecl)) || + (!parseMethod && Actions.ObjC().isObjCMethodDecl(MCDecl))); if (skip) return; @@ -3740,7 +3741,7 @@ void Parser::ParseLexedObjCMethodDefs(LexedMethod &LM, bool parseMethod) { // Tell the actions module that we have entered a method or c-function definition // with the specified Declarator for the method/function. if (parseMethod) - Actions.ActOnStartOfObjCMethodDef(getCurScope(), MCDecl); + Actions.ObjC().ActOnStartOfObjCMethodDef(getCurScope(), MCDecl); else Actions.ActOnStartOfFunctionDef(getCurScope(), MCDecl); if (Tok.is(tok::kw_try)) diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp index 629421c01d17d..478ae59fdd5f0 100644 --- a/clang/lib/Parse/ParseStmt.cpp +++ b/clang/lib/Parse/ParseStmt.cpp @@ -22,6 +22,7 @@ #include "clang/Sema/DeclSpec.h" #include "clang/Sema/EnterExpressionEvaluationContext.h" #include "clang/Sema/Scope.h" +#include "clang/Sema/SemaObjC.h" #include "clang/Sema/SemaOpenMP.h" #include "clang/Sema/TypoCorrection.h" #include "llvm/ADT/STLExtras.h" @@ -2294,7 +2295,7 @@ StmtResult Parser::ParseForStatement(SourceLocation *TrailingElseLoc) { } else if (ForEach) { // Similarly, we need to do the semantic analysis for a for-range // statement immediately in order to close over temporaries correctly. - ForEachStmt = Actions.ActOnObjCForCollectionStmt(ForLoc, + ForEachStmt = Actions.ObjC().ActOnObjCForCollectionStmt(ForLoc, FirstPart.get(), Collection.get(), T.getCloseLocation()); @@ -2345,7 +2346,7 @@ StmtResult Parser::ParseForStatement(SourceLocation *TrailingElseLoc) { return StmtError(); if (ForEach) - return Actions.FinishObjCForCollectionStmt(ForEachStmt.get(), + return Actions.ObjC().FinishObjCForCollectionStmt(ForEachStmt.get(), Body.get()); if (ForRangeInfo.ParsedForRangeDecl()) diff --git a/clang/lib/Sema/CMakeLists.txt b/clang/lib/Sema/CMakeLists.txt index a96439df66422..58e0a3b9679b7 100644 --- a/clang/lib/Sema/CMakeLists.txt +++ b/clang/lib/Sema/CMakeLists.txt @@ -54,6 +54,7 @@ add_clang_library(clangSema SemaLambda.cpp SemaLookup.cpp SemaModule.cpp + SemaObjC.cpp SemaObjCProperty.cpp SemaOpenACC.cpp SemaOpenMP.cpp diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp index a1e32d391ed0c..7585f1c367be1 100644 --- a/clang/lib/Sema/Sema.cpp +++ b/clang/lib/Sema/Sema.cpp @@ -45,6 +45,7 @@ #include "clang/Sema/SemaConsumer.h" #include "clang/Sema/SemaHLSL.h" #include "clang/Sema/SemaInternal.h" +#include "clang/Sema/SemaObjC.h" #include "clang/Sema/SemaOpenACC.h" #include "clang/Sema/SemaOpenMP.h" #include "clang/Sema/SemaSYCL.h" @@ -203,6 +204,7 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer, CurScope(nullptr), Ident_super(nullptr), CUDAPtr(std::make_unique(*this)), HLSLPtr(std::make_unique(*this)), + ObjCPtr(std::make_unique(*this)), OpenACCPtr(std::make_unique(*this)), OpenMPPtr(std::make_unique(*this)), SYCLPtr(std::make_unique(*this)), @@ -224,20 +226,16 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer, AccessCheckingSFINAE(false), CurrentInstantiationScope(nullptr), InNonInstantiationSFINAEContext(false), NonInstantiationEntries(0), ArgumentPackSubstitutionIndex(-1), SatisfactionCache(Context), - NSNumberDecl(nullptr), NSValueDecl(nullptr), NSStringDecl(nullptr), - StringWithUTF8StringMethod(nullptr), - ValueWithBytesObjCTypeMethod(nullptr), NSArrayDecl(nullptr), - ArrayWithObjectsMethod(nullptr), NSDictionaryDecl(nullptr), - DictionaryWithObjectsMethod(nullptr), CodeCompleter(CodeCompleter) { + CodeCompleter(CodeCompleter) { assert(pp.TUKind == TUKind); TUScope = nullptr; LoadedExternalKnownNamespaces = false; for (unsigned I = 0; I != NSAPI::NumNSNumberLiteralMethods; ++I) - NSNumberLiteralMethods[I] = nullptr; + ObjC().NSNumberLiteralMethods[I] = nullptr; if (getLangOpts().ObjC) - NSAPIObj.reset(new NSAPI(Context)); + ObjC().NSAPIObj.reset(new NSAPI(Context)); if (getLangOpts().CPlusPlus) FieldCollector.reset(new CXXFieldCollector()); @@ -1129,7 +1127,7 @@ void Sema::ActOnEndOfTranslationUnit() { // Complete translation units and modules define vtables and perform implicit // instantiations. PCH files do not. if (TUKind != TU_Prefix) { - DiagnoseUseOfUnimplementedSelectors(); + ObjC().DiagnoseUseOfUnimplementedSelectors(); ActOnEndOfTranslationUnitFragment( !ModuleScopes.empty() && ModuleScopes.back().Module->Kind == diff --git a/clang/lib/Sema/SemaAPINotes.cpp b/clang/lib/Sema/SemaAPINotes.cpp index 4c445f28bba8c..17ee7b6e8c8dc 100644 --- a/clang/lib/Sema/SemaAPINotes.cpp +++ b/clang/lib/Sema/SemaAPINotes.cpp @@ -16,6 +16,7 @@ #include "clang/Basic/SourceLocation.h" #include "clang/Lex/Lexer.h" #include "clang/Sema/SemaInternal.h" +#include "clang/Sema/SemaObjC.h" using namespace clang; @@ -372,7 +373,7 @@ static void ProcessAPINotes(Sema &S, Decl *D, if (auto Var = dyn_cast(D)) { // Make adjustments to parameter types. if (isa(Var)) { - Type = S.AdjustParameterTypeForObjCAutoRefCount( + Type = S.ObjC().AdjustParameterTypeForObjCAutoRefCount( Type, D->getLocation(), TypeInfo); Type = S.Context.getAdjustedParameterType(Type); } diff --git a/clang/lib/Sema/SemaAttr.cpp b/clang/lib/Sema/SemaAttr.cpp index a5dd158808f26..1e2341a785a4f 100644 --- a/clang/lib/Sema/SemaAttr.cpp +++ b/clang/lib/Sema/SemaAttr.cpp @@ -860,22 +860,6 @@ void Sema::ActOnPragmaUnused(const Token &IdTok, Scope *curScope, UnusedAttr::GNU_unused)); } -void Sema::AddCFAuditedAttribute(Decl *D) { - IdentifierInfo *Ident; - SourceLocation Loc; - std::tie(Ident, Loc) = PP.getPragmaARCCFCodeAuditedInfo(); - if (!Loc.isValid()) return; - - // Don't add a redundant or conflicting attribute. - if (D->hasAttr() || - D->hasAttr()) - return; - - AttributeCommonInfo Info(Ident, SourceRange(Loc), - AttributeCommonInfo::Form::Pragma()); - D->addAttr(CFAuditedTransferAttr::CreateImplicit(Context, Info)); -} - namespace { std::optional diff --git a/clang/lib/Sema/SemaAvailability.cpp b/clang/lib/Sema/SemaAvailability.cpp index 846a31a796730..5ebc25317bf37 100644 --- a/clang/lib/Sema/SemaAvailability.cpp +++ b/clang/lib/Sema/SemaAvailability.cpp @@ -19,6 +19,7 @@ #include "clang/Sema/DelayedDiagnostic.h" #include "clang/Sema/ScopeInfo.h" #include "clang/Sema/Sema.h" +#include "clang/Sema/SemaObjC.h" #include using namespace clang; @@ -98,11 +99,11 @@ ShouldDiagnoseAvailabilityOfDecl(Sema &S, const NamedDecl *D, // For +new, infer availability from -init. if (const auto *MD = dyn_cast(D)) { - if (S.NSAPIObj && ClassReceiver) { + if (S.ObjC().NSAPIObj && ClassReceiver) { ObjCMethodDecl *Init = ClassReceiver->lookupInstanceMethod( - S.NSAPIObj->getInitSelector()); + S.ObjC().NSAPIObj->getInitSelector()); if (Init && Result == AR_Available && MD->isClassMethod() && - MD->getSelector() == S.NSAPIObj->getNewSelector() && + MD->getSelector() == S.ObjC().NSAPIObj->getNewSelector() && MD->definedInNSObject(S.getASTContext())) { Result = Init->getAvailability(Message); D = Init; diff --git a/clang/lib/Sema/SemaCast.cpp b/clang/lib/Sema/SemaCast.cpp index 126fd3797417c..4bd5f56a36706 100644 --- a/clang/lib/Sema/SemaCast.cpp +++ b/clang/lib/Sema/SemaCast.cpp @@ -24,6 +24,7 @@ #include "clang/Lex/Preprocessor.h" #include "clang/Sema/Initialization.h" #include "clang/Sema/SemaInternal.h" +#include "clang/Sema/SemaObjC.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringExtras.h" #include @@ -159,8 +160,8 @@ namespace { assert(Self.getLangOpts().allowsNonTrivialObjCLifetimeQualifiers()); Expr *src = SrcExpr.get(); - if (Self.CheckObjCConversion(OpRange, DestType, src, CCK) == - Sema::ACR_unbridged) + if (Self.ObjC().CheckObjCConversion(OpRange, DestType, src, CCK) == + SemaObjC::ACR_unbridged) IsARCUnbridgedCast = true; SrcExpr = src; } @@ -1499,7 +1500,7 @@ static TryCastResult TryStaticCast(Sema &Self, ExprResult &SrcExpr, // Allow ns-pointer to cf-pointer conversion in either direction // with static casts. if (!CStyle && - Self.CheckTollFreeBridgeStaticCast(DestType, SrcExpr.get(), Kind)) + Self.ObjC().CheckTollFreeBridgeStaticCast(DestType, SrcExpr.get(), Kind)) return TC_Success; // See if it looks like the user is trying to convert between @@ -2524,7 +2525,7 @@ static TryCastResult TryReinterpretCast(Sema &Self, ExprResult &SrcExpr, } else if (IsLValueCast) { Kind = CK_LValueBitCast; } else if (DestType->isObjCObjectPointerType()) { - Kind = Self.PrepareCastToObjCObjectPointer(SrcExpr); + Kind = Self.ObjC().PrepareCastToObjCObjectPointer(SrcExpr); } else if (DestType->isBlockPointerType()) { if (!SrcType->isBlockPointerType()) { Kind = CK_AnyPointerToBlockPointerCast; @@ -3218,7 +3219,7 @@ void CastOperation::CheckCStyleCast() { } } } - else if (!Self.CheckObjCARCUnavailableWeakConversion(DestType, SrcType)) { + else if (!Self.ObjC().CheckObjCARCUnavailableWeakConversion(DestType, SrcType)) { Self.Diag(SrcExpr.get()->getBeginLoc(), diag::err_arc_convesion_of_weak_unavailable) << 1 << SrcType << DestType << SrcExpr.get()->getSourceRange(); diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 99b0a00083535..e4eddd20c2ab7 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -62,6 +62,7 @@ #include "clang/Sema/ScopeInfo.h" #include "clang/Sema/Sema.h" #include "clang/Sema/SemaInternal.h" +#include "clang/Sema/SemaObjC.h" #include "llvm/ADT/APFloat.h" #include "llvm/ADT/APInt.h" #include "llvm/ADT/APSInt.h" @@ -2490,7 +2491,7 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID, return ExprError(); assert(TheCall->getNumArgs() == 1 && "Wrong # arguments to builtin CFStringMakeConstantString"); - if (CheckObjCString(TheCall->getArg(0))) + if (ObjC().CheckObjCString(TheCall->getArg(0))) return ExprError(); break; case Builtin::BI__builtin_ms_va_start: @@ -8168,20 +8169,6 @@ bool Sema::CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall, return false; } -bool Sema::CheckObjCMethodCall(ObjCMethodDecl *Method, SourceLocation lbrac, - ArrayRef Args) { - VariadicCallType CallType = - Method->isVariadic() ? VariadicMethod : VariadicDoesNotApply; - - checkCall(Method, nullptr, /*ThisArg=*/nullptr, Args, - /*IsMemberFunction=*/false, lbrac, Method->getSourceRange(), - CallType); - - CheckTCBEnforcement(lbrac, Method); - - return false; -} - bool Sema::CheckPointerCall(NamedDecl *NDecl, CallExpr *TheCall, const FunctionProtoType *Proto) { QualType Ty; @@ -9335,38 +9322,6 @@ ExprResult Sema::BuiltinNontemporalOverloaded(ExprResult TheCallResult) { return TheCallResult; } -/// CheckObjCString - Checks that the argument to the builtin -/// CFString constructor is correct -/// Note: It might also make sense to do the UTF-16 conversion here (would -/// simplify the backend). -bool Sema::CheckObjCString(Expr *Arg) { - Arg = Arg->IgnoreParenCasts(); - StringLiteral *Literal = dyn_cast(Arg); - - if (!Literal || !Literal->isOrdinary()) { - Diag(Arg->getBeginLoc(), diag::err_cfstring_literal_not_string_constant) - << Arg->getSourceRange(); - return true; - } - - if (Literal->containsNonAsciiOrNull()) { - StringRef String = Literal->getString(); - unsigned NumBytes = String.size(); - SmallVector ToBuf(NumBytes); - const llvm::UTF8 *FromPtr = (const llvm::UTF8 *)String.data(); - llvm::UTF16 *ToPtr = &ToBuf[0]; - - llvm::ConversionResult Result = - llvm::ConvertUTF8toUTF16(&FromPtr, FromPtr + NumBytes, &ToPtr, - ToPtr + NumBytes, llvm::strictConversion); - // Check for conversion failure. - if (Result != llvm::conversionOK) - Diag(Arg->getBeginLoc(), diag::warn_cfstring_truncated) - << Arg->getSourceRange(); - } - return false; -} - /// CheckObjCString - Checks that the format string argument to the os_log() /// and os_trace() functions is correct, and converts it to const char *. ExprResult Sema::CheckOSLogFormatStringArg(Expr *Arg) { @@ -15236,7 +15191,7 @@ static bool CheckTautologicalComparison(Sema &S, BinaryOperator *E, // Special case for ObjC BOOL on targets where its a typedef for a signed char // (Namely, macOS). FIXME: IntRange::forValueOfType should do this. bool IsObjCSignedCharBool = S.getLangOpts().ObjC && - S.NSAPIObj->isObjCBOOLType(OtherT) && + S.ObjC().NSAPIObj->isObjCBOOLType(OtherT) && OtherT->isSpecificBuiltinType(BuiltinType::SChar); // Whether we're treating Other as being a bool because of the form of @@ -15666,7 +15621,7 @@ static void DiagnoseImpCast(Sema &S, Expr *E, QualType T, static bool isObjCSignedCharBool(Sema &S, QualType Ty) { return Ty->isSpecificBuiltinType(BuiltinType::SChar) && - S.getLangOpts().ObjC && S.NSAPIObj->isObjCBOOLType(Ty); + S.getLangOpts().ObjC && S.ObjC().NSAPIObj->isObjCBOOLType(Ty); } static void adornObjCBoolConversionDiagWithTernaryFixit( @@ -15978,7 +15933,7 @@ static void checkObjCCollectionLiteralElement(Sema &S, /// target type. static void checkObjCArrayLiteral(Sema &S, QualType TargetType, ObjCArrayLiteral *ArrayLiteral) { - if (!S.NSArrayDecl) + if (!S.ObjC().NSArrayDecl) return; const auto *TargetObjCPtr = TargetType->getAs(); @@ -15987,7 +15942,7 @@ static void checkObjCArrayLiteral(Sema &S, QualType TargetType, if (TargetObjCPtr->isUnspecialized() || TargetObjCPtr->getInterfaceDecl()->getCanonicalDecl() - != S.NSArrayDecl->getCanonicalDecl()) + != S.ObjC().NSArrayDecl->getCanonicalDecl()) return; auto TypeArgs = TargetObjCPtr->getTypeArgs(); @@ -16007,7 +15962,7 @@ static void checkObjCArrayLiteral(Sema &S, QualType TargetType, static void checkObjCDictionaryLiteral(Sema &S, QualType TargetType, ObjCDictionaryLiteral *DictionaryLiteral) { - if (!S.NSDictionaryDecl) + if (!S.ObjC().NSDictionaryDecl) return; const auto *TargetObjCPtr = TargetType->getAs(); @@ -16016,7 +15971,7 @@ checkObjCDictionaryLiteral(Sema &S, QualType TargetType, if (TargetObjCPtr->isUnspecialized() || TargetObjCPtr->getInterfaceDecl()->getCanonicalDecl() - != S.NSDictionaryDecl->getCanonicalDecl()) + != S.ObjC().NSDictionaryDecl->getCanonicalDecl()) return; auto TypeArgs = TargetObjCPtr->getTypeArgs(); @@ -18750,465 +18705,6 @@ void Sema::CheckArrayAccess(const Expr *expr) { } } -//===--- CHECK: Objective-C retain cycles ----------------------------------// - -namespace { - -struct RetainCycleOwner { - VarDecl *Variable = nullptr; - SourceRange Range; - SourceLocation Loc; - bool Indirect = false; - - RetainCycleOwner() = default; - - void setLocsFrom(Expr *e) { - Loc = e->getExprLoc(); - Range = e->getSourceRange(); - } -}; - -} // namespace - -/// Consider whether capturing the given variable can possibly lead to -/// a retain cycle. -static bool considerVariable(VarDecl *var, Expr *ref, RetainCycleOwner &owner) { - // In ARC, it's captured strongly iff the variable has __strong - // lifetime. In MRR, it's captured strongly if the variable is - // __block and has an appropriate type. - if (var->getType().getObjCLifetime() != Qualifiers::OCL_Strong) - return false; - - owner.Variable = var; - if (ref) - owner.setLocsFrom(ref); - return true; -} - -static bool findRetainCycleOwner(Sema &S, Expr *e, RetainCycleOwner &owner) { - while (true) { - e = e->IgnoreParens(); - if (CastExpr *cast = dyn_cast(e)) { - switch (cast->getCastKind()) { - case CK_BitCast: - case CK_LValueBitCast: - case CK_LValueToRValue: - case CK_ARCReclaimReturnedObject: - e = cast->getSubExpr(); - continue; - - default: - return false; - } - } - - if (ObjCIvarRefExpr *ref = dyn_cast(e)) { - ObjCIvarDecl *ivar = ref->getDecl(); - if (ivar->getType().getObjCLifetime() != Qualifiers::OCL_Strong) - return false; - - // Try to find a retain cycle in the base. - if (!findRetainCycleOwner(S, ref->getBase(), owner)) - return false; - - if (ref->isFreeIvar()) owner.setLocsFrom(ref); - owner.Indirect = true; - return true; - } - - if (DeclRefExpr *ref = dyn_cast(e)) { - VarDecl *var = dyn_cast(ref->getDecl()); - if (!var) return false; - return considerVariable(var, ref, owner); - } - - if (MemberExpr *member = dyn_cast(e)) { - if (member->isArrow()) return false; - - // Don't count this as an indirect ownership. - e = member->getBase(); - continue; - } - - if (PseudoObjectExpr *pseudo = dyn_cast(e)) { - // Only pay attention to pseudo-objects on property references. - ObjCPropertyRefExpr *pre - = dyn_cast(pseudo->getSyntacticForm() - ->IgnoreParens()); - if (!pre) return false; - if (pre->isImplicitProperty()) return false; - ObjCPropertyDecl *property = pre->getExplicitProperty(); - if (!property->isRetaining() && - !(property->getPropertyIvarDecl() && - property->getPropertyIvarDecl()->getType() - .getObjCLifetime() == Qualifiers::OCL_Strong)) - return false; - - owner.Indirect = true; - if (pre->isSuperReceiver()) { - owner.Variable = S.getCurMethodDecl()->getSelfDecl(); - if (!owner.Variable) - return false; - owner.Loc = pre->getLocation(); - owner.Range = pre->getSourceRange(); - return true; - } - e = const_cast(cast(pre->getBase()) - ->getSourceExpr()); - continue; - } - - // Array ivars? - - return false; - } -} - -namespace { - - struct FindCaptureVisitor : EvaluatedExprVisitor { - VarDecl *Variable; - Expr *Capturer = nullptr; - bool VarWillBeReased = false; - - FindCaptureVisitor(ASTContext &Context, VarDecl *variable) - : EvaluatedExprVisitor(Context), - Variable(variable) {} - - void VisitDeclRefExpr(DeclRefExpr *ref) { - if (ref->getDecl() == Variable && !Capturer) - Capturer = ref; - } - - void VisitObjCIvarRefExpr(ObjCIvarRefExpr *ref) { - if (Capturer) return; - Visit(ref->getBase()); - if (Capturer && ref->isFreeIvar()) - Capturer = ref; - } - - void VisitBlockExpr(BlockExpr *block) { - // Look inside nested blocks - if (block->getBlockDecl()->capturesVariable(Variable)) - Visit(block->getBlockDecl()->getBody()); - } - - void VisitOpaqueValueExpr(OpaqueValueExpr *OVE) { - if (Capturer) return; - if (OVE->getSourceExpr()) - Visit(OVE->getSourceExpr()); - } - - void VisitBinaryOperator(BinaryOperator *BinOp) { - if (!Variable || VarWillBeReased || BinOp->getOpcode() != BO_Assign) - return; - Expr *LHS = BinOp->getLHS(); - if (const DeclRefExpr *DRE = dyn_cast_or_null(LHS)) { - if (DRE->getDecl() != Variable) - return; - if (Expr *RHS = BinOp->getRHS()) { - RHS = RHS->IgnoreParenCasts(); - std::optional Value; - VarWillBeReased = - (RHS && (Value = RHS->getIntegerConstantExpr(Context)) && - *Value == 0); - } - } - } - }; - -} // namespace - -/// Check whether the given argument is a block which captures a -/// variable. -static Expr *findCapturingExpr(Sema &S, Expr *e, RetainCycleOwner &owner) { - assert(owner.Variable && owner.Loc.isValid()); - - e = e->IgnoreParenCasts(); - - // Look through [^{...} copy] and Block_copy(^{...}). - if (ObjCMessageExpr *ME = dyn_cast(e)) { - Selector Cmd = ME->getSelector(); - if (Cmd.isUnarySelector() && Cmd.getNameForSlot(0) == "copy") { - e = ME->getInstanceReceiver(); - if (!e) - return nullptr; - e = e->IgnoreParenCasts(); - } - } else if (CallExpr *CE = dyn_cast(e)) { - if (CE->getNumArgs() == 1) { - FunctionDecl *Fn = dyn_cast_or_null(CE->getCalleeDecl()); - if (Fn) { - const IdentifierInfo *FnI = Fn->getIdentifier(); - if (FnI && FnI->isStr("_Block_copy")) { - e = CE->getArg(0)->IgnoreParenCasts(); - } - } - } - } - - BlockExpr *block = dyn_cast(e); - if (!block || !block->getBlockDecl()->capturesVariable(owner.Variable)) - return nullptr; - - FindCaptureVisitor visitor(S.Context, owner.Variable); - visitor.Visit(block->getBlockDecl()->getBody()); - return visitor.VarWillBeReased ? nullptr : visitor.Capturer; -} - -static void diagnoseRetainCycle(Sema &S, Expr *capturer, - RetainCycleOwner &owner) { - assert(capturer); - assert(owner.Variable && owner.Loc.isValid()); - - S.Diag(capturer->getExprLoc(), diag::warn_arc_retain_cycle) - << owner.Variable << capturer->getSourceRange(); - S.Diag(owner.Loc, diag::note_arc_retain_cycle_owner) - << owner.Indirect << owner.Range; -} - -/// Check for a keyword selector that starts with the word 'add' or -/// 'set'. -static bool isSetterLikeSelector(Selector sel) { - if (sel.isUnarySelector()) return false; - - StringRef str = sel.getNameForSlot(0); - str = str.ltrim('_'); - if (str.starts_with("set")) - str = str.substr(3); - else if (str.starts_with("add")) { - // Specially allow 'addOperationWithBlock:'. - if (sel.getNumArgs() == 1 && str.starts_with("addOperationWithBlock")) - return false; - str = str.substr(3); - } else - return false; - - if (str.empty()) return true; - return !isLowercase(str.front()); -} - -static std::optional -GetNSMutableArrayArgumentIndex(Sema &S, ObjCMessageExpr *Message) { - bool IsMutableArray = S.NSAPIObj->isSubclassOfNSClass( - Message->getReceiverInterface(), - NSAPI::ClassId_NSMutableArray); - if (!IsMutableArray) { - return std::nullopt; - } - - Selector Sel = Message->getSelector(); - - std::optional MKOpt = - S.NSAPIObj->getNSArrayMethodKind(Sel); - if (!MKOpt) { - return std::nullopt; - } - - NSAPI::NSArrayMethodKind MK = *MKOpt; - - switch (MK) { - case NSAPI::NSMutableArr_addObject: - case NSAPI::NSMutableArr_insertObjectAtIndex: - case NSAPI::NSMutableArr_setObjectAtIndexedSubscript: - return 0; - case NSAPI::NSMutableArr_replaceObjectAtIndex: - return 1; - - default: - return std::nullopt; - } - - return std::nullopt; -} - -static std::optional -GetNSMutableDictionaryArgumentIndex(Sema &S, ObjCMessageExpr *Message) { - bool IsMutableDictionary = S.NSAPIObj->isSubclassOfNSClass( - Message->getReceiverInterface(), - NSAPI::ClassId_NSMutableDictionary); - if (!IsMutableDictionary) { - return std::nullopt; - } - - Selector Sel = Message->getSelector(); - - std::optional MKOpt = - S.NSAPIObj->getNSDictionaryMethodKind(Sel); - if (!MKOpt) { - return std::nullopt; - } - - NSAPI::NSDictionaryMethodKind MK = *MKOpt; - - switch (MK) { - case NSAPI::NSMutableDict_setObjectForKey: - case NSAPI::NSMutableDict_setValueForKey: - case NSAPI::NSMutableDict_setObjectForKeyedSubscript: - return 0; - - default: - return std::nullopt; - } - - return std::nullopt; -} - -static std::optional GetNSSetArgumentIndex(Sema &S, - ObjCMessageExpr *Message) { - bool IsMutableSet = S.NSAPIObj->isSubclassOfNSClass( - Message->getReceiverInterface(), - NSAPI::ClassId_NSMutableSet); - - bool IsMutableOrderedSet = S.NSAPIObj->isSubclassOfNSClass( - Message->getReceiverInterface(), - NSAPI::ClassId_NSMutableOrderedSet); - if (!IsMutableSet && !IsMutableOrderedSet) { - return std::nullopt; - } - - Selector Sel = Message->getSelector(); - - std::optional MKOpt = - S.NSAPIObj->getNSSetMethodKind(Sel); - if (!MKOpt) { - return std::nullopt; - } - - NSAPI::NSSetMethodKind MK = *MKOpt; - - switch (MK) { - case NSAPI::NSMutableSet_addObject: - case NSAPI::NSOrderedSet_setObjectAtIndex: - case NSAPI::NSOrderedSet_setObjectAtIndexedSubscript: - case NSAPI::NSOrderedSet_insertObjectAtIndex: - return 0; - case NSAPI::NSOrderedSet_replaceObjectAtIndexWithObject: - return 1; - } - - return std::nullopt; -} - -void Sema::CheckObjCCircularContainer(ObjCMessageExpr *Message) { - if (!Message->isInstanceMessage()) { - return; - } - - std::optional ArgOpt; - - if (!(ArgOpt = GetNSMutableArrayArgumentIndex(*this, Message)) && - !(ArgOpt = GetNSMutableDictionaryArgumentIndex(*this, Message)) && - !(ArgOpt = GetNSSetArgumentIndex(*this, Message))) { - return; - } - - int ArgIndex = *ArgOpt; - - Expr *Arg = Message->getArg(ArgIndex)->IgnoreImpCasts(); - if (OpaqueValueExpr *OE = dyn_cast(Arg)) { - Arg = OE->getSourceExpr()->IgnoreImpCasts(); - } - - if (Message->getReceiverKind() == ObjCMessageExpr::SuperInstance) { - if (DeclRefExpr *ArgRE = dyn_cast(Arg)) { - if (ArgRE->isObjCSelfExpr()) { - Diag(Message->getSourceRange().getBegin(), - diag::warn_objc_circular_container) - << ArgRE->getDecl() << StringRef("'super'"); - } - } - } else { - Expr *Receiver = Message->getInstanceReceiver()->IgnoreImpCasts(); - - if (OpaqueValueExpr *OE = dyn_cast(Receiver)) { - Receiver = OE->getSourceExpr()->IgnoreImpCasts(); - } - - if (DeclRefExpr *ReceiverRE = dyn_cast(Receiver)) { - if (DeclRefExpr *ArgRE = dyn_cast(Arg)) { - if (ReceiverRE->getDecl() == ArgRE->getDecl()) { - ValueDecl *Decl = ReceiverRE->getDecl(); - Diag(Message->getSourceRange().getBegin(), - diag::warn_objc_circular_container) - << Decl << Decl; - if (!ArgRE->isObjCSelfExpr()) { - Diag(Decl->getLocation(), - diag::note_objc_circular_container_declared_here) - << Decl; - } - } - } - } else if (ObjCIvarRefExpr *IvarRE = dyn_cast(Receiver)) { - if (ObjCIvarRefExpr *IvarArgRE = dyn_cast(Arg)) { - if (IvarRE->getDecl() == IvarArgRE->getDecl()) { - ObjCIvarDecl *Decl = IvarRE->getDecl(); - Diag(Message->getSourceRange().getBegin(), - diag::warn_objc_circular_container) - << Decl << Decl; - Diag(Decl->getLocation(), - diag::note_objc_circular_container_declared_here) - << Decl; - } - } - } - } -} - -/// Check a message send to see if it's likely to cause a retain cycle. -void Sema::checkRetainCycles(ObjCMessageExpr *msg) { - // Only check instance methods whose selector looks like a setter. - if (!msg->isInstanceMessage() || !isSetterLikeSelector(msg->getSelector())) - return; - - // Try to find a variable that the receiver is strongly owned by. - RetainCycleOwner owner; - if (msg->getReceiverKind() == ObjCMessageExpr::Instance) { - if (!findRetainCycleOwner(*this, msg->getInstanceReceiver(), owner)) - return; - } else { - assert(msg->getReceiverKind() == ObjCMessageExpr::SuperInstance); - owner.Variable = getCurMethodDecl()->getSelfDecl(); - owner.Loc = msg->getSuperLoc(); - owner.Range = msg->getSuperLoc(); - } - - // Check whether the receiver is captured by any of the arguments. - const ObjCMethodDecl *MD = msg->getMethodDecl(); - for (unsigned i = 0, e = msg->getNumArgs(); i != e; ++i) { - if (Expr *capturer = findCapturingExpr(*this, msg->getArg(i), owner)) { - // noescape blocks should not be retained by the method. - if (MD && MD->parameters()[i]->hasAttr()) - continue; - return diagnoseRetainCycle(*this, capturer, owner); - } - } -} - -/// Check a property assign to see if it's likely to cause a retain cycle. -void Sema::checkRetainCycles(Expr *receiver, Expr *argument) { - RetainCycleOwner owner; - if (!findRetainCycleOwner(*this, receiver, owner)) - return; - - if (Expr *capturer = findCapturingExpr(*this, argument, owner)) - diagnoseRetainCycle(*this, capturer, owner); -} - -void Sema::checkRetainCycles(VarDecl *Var, Expr *Init) { - RetainCycleOwner Owner; - if (!considerVariable(Var, /*DeclRefExpr=*/nullptr, Owner)) - return; - - // Because we don't have an expression for the variable, we have to set the - // location explicitly here. - Owner.Loc = Var->getLocation(); - Owner.Range = Var->getSourceRange(); - - if (Expr *Capturer = findCapturingExpr(*this, Init, Owner)) - diagnoseRetainCycle(*this, Capturer, Owner); -} - static bool checkUnsafeAssignLiteral(Sema &S, SourceLocation Loc, Expr *RHS, bool isProperty) { // Check if RHS is an Objective-C object literal, which also can get @@ -19218,8 +18714,8 @@ static bool checkUnsafeAssignLiteral(Sema &S, SourceLocation Loc, // This enum needs to match with the 'select' in // warn_objc_arc_literal_assign (off-by-1). - Sema::ObjCLiteralKind Kind = S.CheckLiteralKind(RHS); - if (Kind == Sema::LK_String || Kind == Sema::LK_None) + SemaObjC::ObjCLiteralKind Kind = S.ObjC().CheckLiteralKind(RHS); + if (Kind == SemaObjC::LK_String || Kind == SemaObjC::LK_None) return false; S.Diag(Loc, diag::warn_arc_literal_assign) diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp index c335017f243eb..35d639314dcd5 100644 --- a/clang/lib/Sema/SemaCodeComplete.cpp +++ b/clang/lib/Sema/SemaCodeComplete.cpp @@ -42,6 +42,7 @@ #include "clang/Sema/ScopeInfo.h" #include "clang/Sema/Sema.h" #include "clang/Sema/SemaInternal.h" +#include "clang/Sema/SemaObjC.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/SmallBitVector.h" @@ -5863,7 +5864,7 @@ void Sema::CodeCompleteObjCClassPropertyRefExpr(Scope *S, SourceLocation ClassNameLoc, bool IsBaseExprStatement) { const IdentifierInfo *ClassNamePtr = &ClassName; - ObjCInterfaceDecl *IFace = getObjCInterfaceDecl(ClassNamePtr, ClassNameLoc); + ObjCInterfaceDecl *IFace = ObjC().getObjCInterfaceDecl(ClassNamePtr, ClassNameLoc); if (!IFace) return; CodeCompletionContext CCContext( @@ -8175,15 +8176,15 @@ AddClassMessageCompletions(Sema &SemaRef, Scope *S, ParsedType Receiver, N = SemaRef.getExternalSource()->GetNumExternalSelectors(); I != N; ++I) { Selector Sel = SemaRef.getExternalSource()->GetExternalSelector(I); - if (Sel.isNull() || SemaRef.MethodPool.count(Sel)) + if (Sel.isNull() || SemaRef.ObjC().MethodPool.count(Sel)) continue; - SemaRef.ReadMethodPool(Sel); + SemaRef.ObjC().ReadMethodPool(Sel); } } - for (Sema::GlobalMethodPool::iterator M = SemaRef.MethodPool.begin(), - MEnd = SemaRef.MethodPool.end(); + for (SemaObjC::GlobalMethodPool::iterator M = SemaRef.ObjC().MethodPool.begin(), + MEnd = SemaRef.ObjC().MethodPool.end(); M != MEnd; ++M) { for (ObjCMethodList *MethList = &M->second.second; MethList && MethList->getMethod(); MethList = MethList->getNext()) { @@ -8345,15 +8346,15 @@ void Sema::CodeCompleteObjCInstanceMessage( for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors(); I != N; ++I) { Selector Sel = ExternalSource->GetExternalSelector(I); - if (Sel.isNull() || MethodPool.count(Sel)) + if (Sel.isNull() || ObjC().MethodPool.count(Sel)) continue; - ReadMethodPool(Sel); + ObjC().ReadMethodPool(Sel); } } - for (GlobalMethodPool::iterator M = MethodPool.begin(), - MEnd = MethodPool.end(); + for (SemaObjC::GlobalMethodPool::iterator M = ObjC().MethodPool.begin(), + MEnd = ObjC().MethodPool.end(); M != MEnd; ++M) { for (ObjCMethodList *MethList = &M->second.first; MethList && MethList->getMethod(); MethList = MethList->getNext()) { @@ -8416,10 +8417,10 @@ void Sema::CodeCompleteObjCSelector( for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors(); I != N; ++I) { Selector Sel = ExternalSource->GetExternalSelector(I); - if (Sel.isNull() || MethodPool.count(Sel)) + if (Sel.isNull() || ObjC().MethodPool.count(Sel)) continue; - ReadMethodPool(Sel); + ObjC().ReadMethodPool(Sel); } } @@ -8427,8 +8428,8 @@ void Sema::CodeCompleteObjCSelector( CodeCompleter->getCodeCompletionTUInfo(), CodeCompletionContext::CCC_SelectorName); Results.EnterNewScope(); - for (GlobalMethodPool::iterator M = MethodPool.begin(), - MEnd = MethodPool.end(); + for (SemaObjC::GlobalMethodPool::iterator M = ObjC().MethodPool.begin(), + MEnd = ObjC().MethodPool.end(); M != MEnd; ++M) { Selector Sel = M->first; @@ -8496,7 +8497,7 @@ void Sema::CodeCompleteObjCProtocolReferences( // already seen. // FIXME: This doesn't work when caching code-completion results. for (const IdentifierLocPair &Pair : Protocols) - if (ObjCProtocolDecl *Protocol = LookupProtocol(Pair.first, Pair.second)) + if (ObjCProtocolDecl *Protocol = ObjC().LookupProtocol(Pair.first, Pair.second)) Results.Ignore(Protocol); // Add all protocols. @@ -9754,10 +9755,10 @@ void Sema::CodeCompleteObjCMethodDeclSelector( for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors(); I != N; ++I) { Selector Sel = ExternalSource->GetExternalSelector(I); - if (Sel.isNull() || MethodPool.count(Sel)) + if (Sel.isNull() || ObjC().MethodPool.count(Sel)) continue; - ReadMethodPool(Sel); + ObjC().ReadMethodPool(Sel); } } @@ -9771,8 +9772,8 @@ void Sema::CodeCompleteObjCMethodDeclSelector( Results.setPreferredType(GetTypeFromParser(ReturnTy).getNonReferenceType()); Results.EnterNewScope(); - for (GlobalMethodPool::iterator M = MethodPool.begin(), - MEnd = MethodPool.end(); + for (SemaObjC::GlobalMethodPool::iterator M = ObjC().MethodPool.begin(), + MEnd = ObjC().MethodPool.end(); M != MEnd; ++M) { for (ObjCMethodList *MethList = IsInstanceMethod ? &M->second.first : &M->second.second; diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 455ccb45b4068..b32a3819ee8b1 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -48,6 +48,7 @@ #include "clang/Sema/SemaCUDA.h" #include "clang/Sema/SemaHLSL.h" #include "clang/Sema/SemaInternal.h" +#include "clang/Sema/SemaObjC.h" #include "clang/Sema/SemaOpenMP.h" #include "clang/Sema/Template.h" #include "llvm/ADT/STLForwardCompat.h" @@ -914,7 +915,7 @@ Sema::NameClassification Sema::ClassifyName(Scope *S, CXXScopeSpec &SS, // FIXME: This lookup really, really needs to be folded in to the normal // unqualified lookup mechanism. if (SS.isEmpty() && CurMethod && !isResultTypeOrTemplate(Result, NextToken)) { - DeclResult Ivar = LookupIvarInObjCMethod(Result, S, Name); + DeclResult Ivar = ObjC().LookupIvarInObjCMethod(Result, S, Name); if (Ivar.isInvalid()) return NameClassification::Error(); if (Ivar.isUsable()) @@ -1032,7 +1033,7 @@ Sema::NameClassification Sema::ClassifyName(Scope *S, CXXScopeSpec &SS, // FIXME: This is a gross hack. if (ObjCIvarDecl *Ivar = Result.getAsSingle()) { DeclResult R = - LookupIvarInObjCMethod(Result, S, Ivar->getIdentifier()); + ObjC().LookupIvarInObjCMethod(Result, S, Ivar->getIdentifier()); if (R.isInvalid()) return NameClassification::Error(); if (R.isUsable()) @@ -1270,7 +1271,7 @@ ExprResult Sema::ActOnNameClassifiedAsNonType(Scope *S, const CXXScopeSpec &SS, const Token &NextToken) { if (getCurMethodDecl() && SS.isEmpty()) if (auto *Ivar = dyn_cast(Found->getUnderlyingDecl())) - return BuildIvarRefExpr(S, NameLoc, Ivar); + return ObjC().BuildIvarRefExpr(S, NameLoc, Ivar); // Reconstruct the lookup result. LookupResult Result(*this, Found->getDeclName(), NameLoc, LookupOrdinaryName); @@ -2309,45 +2310,6 @@ void Sema::ActOnPopScope(SourceLocation Loc, Scope *S) { } } -/// Look for an Objective-C class in the translation unit. -/// -/// \param Id The name of the Objective-C class we're looking for. If -/// typo-correction fixes this name, the Id will be updated -/// to the fixed name. -/// -/// \param IdLoc The location of the name in the translation unit. -/// -/// \param DoTypoCorrection If true, this routine will attempt typo correction -/// if there is no class with the given name. -/// -/// \returns The declaration of the named Objective-C class, or NULL if the -/// class could not be found. -ObjCInterfaceDecl *Sema::getObjCInterfaceDecl(const IdentifierInfo *&Id, - SourceLocation IdLoc, - bool DoTypoCorrection) { - // The third "scope" argument is 0 since we aren't enabling lazy built-in - // creation from this context. - NamedDecl *IDecl = LookupSingleName(TUScope, Id, IdLoc, LookupOrdinaryName); - - if (!IDecl && DoTypoCorrection) { - // Perform typo correction at the given location, but only if we - // find an Objective-C class name. - DeclFilterCCC CCC{}; - if (TypoCorrection C = - CorrectTypo(DeclarationNameInfo(Id, IdLoc), LookupOrdinaryName, - TUScope, nullptr, CCC, CTK_ErrorRecovery)) { - diagnoseTypo(C, PDiag(diag::err_undef_interface_suggest) << Id); - IDecl = C.getCorrectionDeclAs(); - Id = IDecl->getIdentifier(); - } - } - ObjCInterfaceDecl *Def = dyn_cast_or_null(IDecl); - // This routine must always return a class definition, if any. - if (Def && Def->getDefinition()) - Def = Def->getDefinition(); - return Def; -} - /// getNonFieldDeclScope - Retrieves the innermost scope, starting /// from S, where a non-field would be declared. This routine copes /// with the difference between C and C++ scoping rules in structs and @@ -4414,7 +4376,7 @@ void Sema::mergeObjCMethodDecls(ObjCMethodDecl *newMethod, ni != ne && oi != oe; ++ni, ++oi) mergeParamDeclAttributes(*ni, *oi, *this); - CheckObjCMethodOverride(newMethod, oldMethod); + ObjC().CheckObjCMethodOverride(newMethod, oldMethod); } static void diagnoseVarDeclTypeMismatch(Sema &S, VarDecl *New, VarDecl* Old) { @@ -6978,50 +6940,6 @@ static void SetNestedNameSpecifier(Sema &S, DeclaratorDecl *DD, Declarator &D) { DD->setQualifierInfo(SS.getWithLocInContext(S.Context)); } -bool Sema::inferObjCARCLifetime(ValueDecl *decl) { - QualType type = decl->getType(); - Qualifiers::ObjCLifetime lifetime = type.getObjCLifetime(); - if (lifetime == Qualifiers::OCL_Autoreleasing) { - // Various kinds of declaration aren't allowed to be __autoreleasing. - unsigned kind = -1U; - if (VarDecl *var = dyn_cast(decl)) { - if (var->hasAttr()) - kind = 0; // __block - else if (!var->hasLocalStorage()) - kind = 1; // global - } else if (isa(decl)) { - kind = 3; // ivar - } else if (isa(decl)) { - kind = 2; // field - } - - if (kind != -1U) { - Diag(decl->getLocation(), diag::err_arc_autoreleasing_var) - << kind; - } - } else if (lifetime == Qualifiers::OCL_None) { - // Try to infer lifetime. - if (!type->isObjCLifetimeType()) - return false; - - lifetime = type->getObjCARCImplicitLifetime(); - type = Context.getLifetimeQualifiedType(type, lifetime); - decl->setType(type); - } - - if (VarDecl *var = dyn_cast(decl)) { - // Thread-local variables cannot have lifetime. - if (lifetime && lifetime != Qualifiers::OCL_ExplicitNone && - var->getTLSKind()) { - Diag(var->getLocation(), diag::err_arc_thread_ownership) - << var->getType(); - return true; - } - } - - return false; -} - void Sema::deduceOpenCLAddressSpace(ValueDecl *Decl) { if (Decl->getType().hasAddressSpace()) return; @@ -8060,7 +7978,7 @@ NamedDecl *Sema::ActOnVariableDeclarator( // In auto-retain/release, infer strong retension for variables of // retainable type. - if (getLangOpts().ObjCAutoRefCount && inferObjCARCLifetime(NewVD)) + if (getLangOpts().ObjCAutoRefCount && ObjC().inferObjCARCLifetime(NewVD)) NewVD->setInvalidDecl(); // Handle GNU asm-label extension (encoded as an attribute). @@ -10874,7 +10792,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, // If there's a #pragma clang arc_cf_code_audited in scope, consider // marking the function. - AddCFAuditedAttribute(NewFD); + ObjC().AddCFAuditedAttribute(NewFD); // If this is a function definition, check if we have to apply any // attributes (i.e. optnone and no_builtin) due to a pragma. @@ -13200,7 +13118,7 @@ bool Sema::DeduceVariableDeclarationType(VarDecl *VDecl, bool DirectInit, assert(VDecl->isLinkageValid()); // In ARC, infer lifetime. - if (getLangOpts().ObjCAutoRefCount && inferObjCARCLifetime(VDecl)) + if (getLangOpts().ObjCAutoRefCount && ObjC().inferObjCARCLifetime(VDecl)) VDecl->setInvalidDecl(); if (getLangOpts().OpenCL) @@ -13761,7 +13679,7 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) { checkUnsafeAssigns(VDecl->getLocation(), VDecl->getType(), Init); if (VDecl->hasAttr()) - checkRetainCycles(VDecl, Init); + ObjC().checkRetainCycles(VDecl, Init); // It is safe to assign a weak reference into a strong variable. // Although this code can still have problems: @@ -15315,37 +15233,6 @@ void Sema::DiagnoseSizeOfParametersAndReturnValue( } } -QualType Sema::AdjustParameterTypeForObjCAutoRefCount(QualType T, - SourceLocation NameLoc, - TypeSourceInfo *TSInfo) { - // In ARC, infer a lifetime qualifier for appropriate parameter types. - if (!getLangOpts().ObjCAutoRefCount || - T.getObjCLifetime() != Qualifiers::OCL_None || !T->isObjCLifetimeType()) - return T; - - Qualifiers::ObjCLifetime Lifetime; - - // Special cases for arrays: - // - if it's const, use __unsafe_unretained - // - otherwise, it's an error - if (T->isArrayType()) { - if (!T.isConstQualified()) { - if (DelayedDiagnostics.shouldDelayDiagnostics()) - DelayedDiagnostics.add(sema::DelayedDiagnostic::makeForbiddenType( - NameLoc, diag::err_arc_array_param_no_ownership, T, false)); - else - Diag(NameLoc, diag::err_arc_array_param_no_ownership) - << TSInfo->getTypeLoc().getSourceRange(); - } - Lifetime = Qualifiers::OCL_ExplicitNone; - } else { - Lifetime = T->getObjCARCImplicitLifetime(); - } - T = Context.getLifetimeQualifiedType(T, Lifetime); - - return T; -} - ParmVarDecl *Sema::CheckParameter(DeclContext *DC, SourceLocation StartLoc, SourceLocation NameLoc, const IdentifierInfo *Name, QualType T, @@ -16360,7 +16247,7 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body, if (!SuperD) return false; return SuperD->getIdentifier() == - NSAPIObj->getNSClassId(NSAPI::ClassId_NSObject); + ObjC().NSAPIObj->getNSClassId(NSAPI::ClassId_NSObject); }; // Don't issue this warning for unavailable inits or direct subclasses // of NSObject. @@ -18307,12 +18194,6 @@ bool Sema::ActOnDuplicateDefinition(Decl *Prev, SkipBodyInfo &SkipBody) { return true; } -void Sema::ActOnObjCContainerStartDefinition(ObjCContainerDecl *IDecl) { - assert(IDecl->getLexicalParent() == CurContext && - "The next DeclContext should be lexically contained in the current one."); - CurContext = IDecl; -} - void Sema::ActOnStartCXXMemberDeclarations(Scope *S, Decl *TagD, SourceLocation FinalLoc, bool IsFinalSpelledSealed, @@ -18414,22 +18295,6 @@ void Sema::ActOnTagFinishDefinition(Scope *S, Decl *TagD, } } -void Sema::ActOnObjCContainerFinishDefinition() { - // Exit this scope of this interface definition. - PopDeclContext(); -} - -void Sema::ActOnObjCTemporaryExitContainerContext(ObjCContainerDecl *ObjCCtx) { - assert(ObjCCtx == CurContext && "Mismatch of container contexts"); - OriginalLexicalContext = ObjCCtx; - ActOnObjCContainerFinishDefinition(); -} - -void Sema::ActOnObjCReenterContainerContext(ObjCContainerDecl *ObjCCtx) { - ActOnObjCContainerStartDefinition(ObjCCtx); - OriginalLexicalContext = nullptr; -} - void Sema::ActOnTagDefinitionError(Scope *S, Decl *TagD) { AdjustDeclIfTemplate(TagD); TagDecl *Tag = cast(TagD); @@ -18829,7 +18694,7 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T, // In auto-retain/release, infer strong retension for fields of // retainable type. - if (getLangOpts().ObjCAutoRefCount && inferObjCARCLifetime(NewFD)) + if (getLangOpts().ObjCAutoRefCount && ObjC().inferObjCARCLifetime(NewFD)) NewFD->setInvalidDecl(); if (T.isObjCGCWeak()) @@ -18907,132 +18772,6 @@ bool Sema::CheckNontrivialField(FieldDecl *FD) { return false; } -/// TranslateIvarVisibility - Translate visibility from a token ID to an -/// AST enum value. -static ObjCIvarDecl::AccessControl -TranslateIvarVisibility(tok::ObjCKeywordKind ivarVisibility) { - switch (ivarVisibility) { - default: llvm_unreachable("Unknown visitibility kind"); - case tok::objc_private: return ObjCIvarDecl::Private; - case tok::objc_public: return ObjCIvarDecl::Public; - case tok::objc_protected: return ObjCIvarDecl::Protected; - case tok::objc_package: return ObjCIvarDecl::Package; - } -} - -/// ActOnIvar - Each ivar field of an objective-c class is passed into this -/// in order to create an IvarDecl object for it. -Decl *Sema::ActOnIvar(Scope *S, SourceLocation DeclStart, Declarator &D, - Expr *BitWidth, tok::ObjCKeywordKind Visibility) { - - const IdentifierInfo *II = D.getIdentifier(); - SourceLocation Loc = DeclStart; - if (II) Loc = D.getIdentifierLoc(); - - // FIXME: Unnamed fields can be handled in various different ways, for - // example, unnamed unions inject all members into the struct namespace! - - TypeSourceInfo *TInfo = GetTypeForDeclarator(D); - QualType T = TInfo->getType(); - - if (BitWidth) { - // 6.7.2.1p3, 6.7.2.1p4 - BitWidth = VerifyBitField(Loc, II, T, /*IsMsStruct*/false, BitWidth).get(); - if (!BitWidth) - D.setInvalidType(); - } else { - // Not a bitfield. - - // validate II. - - } - if (T->isReferenceType()) { - Diag(Loc, diag::err_ivar_reference_type); - D.setInvalidType(); - } - // C99 6.7.2.1p8: A member of a structure or union may have any type other - // than a variably modified type. - else if (T->isVariablyModifiedType()) { - if (!tryToFixVariablyModifiedVarType( - TInfo, T, Loc, diag::err_typecheck_ivar_variable_size)) - D.setInvalidType(); - } - - // Get the visibility (access control) for this ivar. - ObjCIvarDecl::AccessControl ac = - Visibility != tok::objc_not_keyword ? TranslateIvarVisibility(Visibility) - : ObjCIvarDecl::None; - // Must set ivar's DeclContext to its enclosing interface. - ObjCContainerDecl *EnclosingDecl = cast(CurContext); - if (!EnclosingDecl || EnclosingDecl->isInvalidDecl()) - return nullptr; - ObjCContainerDecl *EnclosingContext; - if (ObjCImplementationDecl *IMPDecl = - dyn_cast(EnclosingDecl)) { - if (LangOpts.ObjCRuntime.isFragile()) { - // Case of ivar declared in an implementation. Context is that of its class. - EnclosingContext = IMPDecl->getClassInterface(); - assert(EnclosingContext && "Implementation has no class interface!"); - } - else - EnclosingContext = EnclosingDecl; - } else { - if (ObjCCategoryDecl *CDecl = - dyn_cast(EnclosingDecl)) { - if (LangOpts.ObjCRuntime.isFragile() || !CDecl->IsClassExtension()) { - Diag(Loc, diag::err_misplaced_ivar) << CDecl->IsClassExtension(); - return nullptr; - } - } - EnclosingContext = EnclosingDecl; - } - - // Construct the decl. - ObjCIvarDecl *NewID = ObjCIvarDecl::Create( - Context, EnclosingContext, DeclStart, Loc, II, T, TInfo, ac, BitWidth); - - if (T->containsErrors()) - NewID->setInvalidDecl(); - - if (II) { - NamedDecl *PrevDecl = - LookupSingleName(S, II, Loc, LookupMemberName, - RedeclarationKind::ForVisibleRedeclaration); - if (PrevDecl && isDeclInScope(PrevDecl, EnclosingContext, S) - && !isa(PrevDecl)) { - Diag(Loc, diag::err_duplicate_member) << II; - Diag(PrevDecl->getLocation(), diag::note_previous_declaration); - NewID->setInvalidDecl(); - } - } - - // Process attributes attached to the ivar. - ProcessDeclAttributes(S, NewID, D); - - if (D.isInvalidType()) - NewID->setInvalidDecl(); - - // In ARC, infer 'retaining' for ivars of retainable type. - if (getLangOpts().ObjCAutoRefCount && inferObjCARCLifetime(NewID)) - NewID->setInvalidDecl(); - - if (D.getDeclSpec().isModulePrivateSpecified()) - NewID->setModulePrivate(); - - if (II) { - // FIXME: When interfaces are DeclContexts, we'll need to add - // these to the interface. - S->AddDecl(NewID); - IdResolver.AddDecl(NewID); - } - - if (LangOpts.ObjCRuntime.isNonFragile() && - !NewID->isInvalidDecl() && isa(EnclosingDecl)) - Diag(Loc, diag::warn_ivars_in_interface); - - return NewID; -} - /// ActOnLastBitfield - This routine handles synthesized bitfields rules for /// class and class extensions. For every class \@interface and class /// extension \@interface, if the last ivar is a bitfield of any type, @@ -19729,7 +19468,7 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl, // Must enforce the rule that ivars in the base classes may not be // duplicates. if (ID->getSuperClass()) - DiagnoseDuplicateIvars(ID, ID->getSuperClass()); + ObjC().DiagnoseDuplicateIvars(ID, ID->getSuperClass()); } else if (ObjCImplementationDecl *IMPDecl = dyn_cast(EnclosingDecl)) { assert(IMPDecl && "ActOnFields - missing ObjCImplementationDecl"); @@ -19737,7 +19476,7 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl, // Ivar declared in @implementation never belongs to the implementation. // Only it is in implementation's lexical context. ClsFields[I]->setLexicalDeclContext(IMPDecl); - CheckImplementationIvars(IMPDecl, ClsFields, RecFields.size(), RBrac); + ObjC().CheckImplementationIvars(IMPDecl, ClsFields, RecFields.size(), RBrac); IMPDecl->setIvarLBraceLoc(LBrac); IMPDecl->setIvarRBraceLoc(RBrac); } else if (ObjCCategoryDecl *CDecl = @@ -20611,10 +20350,6 @@ void Sema::ActOnPragmaWeakAlias(IdentifierInfo* Name, } } -ObjCContainerDecl *Sema::getObjCDeclContext() const { - return (dyn_cast_or_null(CurContext)); -} - Sema::FunctionEmissionStatus Sema::getEmissionStatus(const FunctionDecl *FD, bool Final) { assert(FD && "Expected non-null FunctionDecl"); diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index c3bf18a3f79e2..c5db5d7715235 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -42,6 +42,7 @@ #include "clang/Sema/SemaCUDA.h" #include "clang/Sema/SemaHLSL.h" #include "clang/Sema/SemaInternal.h" +#include "clang/Sema/SemaObjC.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/STLForwardCompat.h" #include "llvm/ADT/StringExtras.h" @@ -6550,13 +6551,13 @@ static bool isErrorParameter(Sema &S, QualType QT) { // Check for NSError**. if (const auto *OPT = Pointee->getAs()) if (const auto *ID = OPT->getInterfaceDecl()) - if (ID->getIdentifier() == S.getNSErrorIdent()) + if (ID->getIdentifier() == S.ObjC().getNSErrorIdent()) return true; // Check for CFError**. if (const auto *PT = Pointee->getAs()) if (const auto *RT = PT->getPointeeType()->getAs()) - if (S.isCFError(RT->getDecl())) + if (S.ObjC().isCFError(RT->getDecl())) return true; return false; @@ -6687,7 +6688,7 @@ static void checkSwiftAsyncErrorBlock(Sema &S, Decl *D, // Check for NSError *. if (const auto *ObjCPtrTy = Param->getAs()) { if (const auto *ID = ObjCPtrTy->getInterfaceDecl()) { - if (ID->getIdentifier() == S.getNSErrorIdent()) { + if (ID->getIdentifier() == S.ObjC().getNSErrorIdent()) { AnyErrorParams = true; break; } @@ -6696,7 +6697,7 @@ static void checkSwiftAsyncErrorBlock(Sema &S, Decl *D, // Check for CFError *. if (const auto *PtrTy = Param->getAs()) { if (const auto *RT = PtrTy->getPointeeType()->getAs()) { - if (S.isCFError(RT->getDecl())) { + if (S.ObjC().isCFError(RT->getDecl())) { AnyErrorParams = true; break; } @@ -8778,7 +8779,7 @@ static bool tryMakeVariablePseudoStrong(Sema &S, VarDecl *VD, Qualifiers::ObjCLifetime LifetimeQual = Ty.getQualifiers().getObjCLifetime(); - // Sema::inferObjCARCLifetime must run after processing decl attributes + // SemaObjC::inferObjCARCLifetime must run after processing decl attributes // (because __block lowers to an attribute), so if the lifetime hasn't been // explicitly specified, infer it locally now. if (LifetimeQual == Qualifiers::OCL_None) diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 591016243b0ac..b21fed3803e9d 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -44,6 +44,7 @@ #include "clang/Sema/ScopeInfo.h" #include "clang/Sema/SemaCUDA.h" #include "clang/Sema/SemaInternal.h" +#include "clang/Sema/SemaObjC.h" #include "clang/Sema/SemaOpenMP.h" #include "clang/Sema/Template.h" #include "llvm/ADT/ArrayRef.h" @@ -17046,7 +17047,7 @@ VarDecl *Sema::BuildExceptionDeclaration(Scope *S, TypeSourceInfo *TInfo, ExDecl->setExceptionVariable(true); // In ARC, infer 'retaining' for variables of retainable type. - if (getLangOpts().ObjCAutoRefCount && inferObjCARCLifetime(ExDecl)) + if (getLangOpts().ObjCAutoRefCount && ObjC().inferObjCARCLifetime(ExDecl)) Invalid = true; if (!Invalid && !ExDeclType->isDependentType()) { @@ -18840,61 +18841,6 @@ void Sema::MarkVirtualMembersReferenced(SourceLocation Loc, } } -/// SetIvarInitializers - This routine builds initialization ASTs for the -/// Objective-C implementation whose ivars need be initialized. -void Sema::SetIvarInitializers(ObjCImplementationDecl *ObjCImplementation) { - if (!getLangOpts().CPlusPlus) - return; - if (ObjCInterfaceDecl *OID = ObjCImplementation->getClassInterface()) { - SmallVector ivars; - CollectIvarsToConstructOrDestruct(OID, ivars); - if (ivars.empty()) - return; - SmallVector AllToInit; - for (unsigned i = 0; i < ivars.size(); i++) { - FieldDecl *Field = ivars[i]; - if (Field->isInvalidDecl()) - continue; - - CXXCtorInitializer *Member; - InitializedEntity InitEntity = InitializedEntity::InitializeMember(Field); - InitializationKind InitKind = - InitializationKind::CreateDefault(ObjCImplementation->getLocation()); - - InitializationSequence InitSeq(*this, InitEntity, InitKind, std::nullopt); - ExprResult MemberInit = - InitSeq.Perform(*this, InitEntity, InitKind, std::nullopt); - MemberInit = MaybeCreateExprWithCleanups(MemberInit); - // Note, MemberInit could actually come back empty if no initialization - // is required (e.g., because it would call a trivial default constructor) - if (!MemberInit.get() || MemberInit.isInvalid()) - continue; - - Member = - new (Context) CXXCtorInitializer(Context, Field, SourceLocation(), - SourceLocation(), - MemberInit.getAs(), - SourceLocation()); - AllToInit.push_back(Member); - - // Be sure that the destructor is accessible and is marked as referenced. - if (const RecordType *RecordTy = - Context.getBaseElementType(Field->getType()) - ->getAs()) { - CXXRecordDecl *RD = cast(RecordTy->getDecl()); - if (CXXDestructorDecl *Destructor = LookupDestructor(RD)) { - MarkFunctionReferenced(Field->getLocation(), Destructor); - CheckDestructorAccess(Field->getLocation(), Destructor, - PDiag(diag::err_access_dtor_ivar) - << Context.getBaseElementType(Field->getType())); - } - } - } - ObjCImplementation->setIvarInitializers(Context, - AllToInit.data(), AllToInit.size()); - } -} - static void DelegatingCycleHelper(CXXConstructorDecl* Ctor, llvm::SmallPtrSet &Valid, diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp index 74d6f0700b0e4..893cc1a731210 100644 --- a/clang/lib/Sema/SemaDeclObjC.cpp +++ b/clang/lib/Sema/SemaDeclObjC.cpp @@ -10,6 +10,7 @@ // //===----------------------------------------------------------------------===// +#include "clang/Sema/SemaObjC.h" #include "TypeLocBuilder.h" #include "clang/AST/ASTConsumer.h" #include "clang/AST/ASTContext.h" @@ -21,6 +22,8 @@ #include "clang/Basic/SourceManager.h" #include "clang/Basic/TargetInfo.h" #include "clang/Sema/DeclSpec.h" +#include "clang/Sema/DelayedDiagnostic.h" +#include "clang/Sema/Initialization.h" #include "clang/Sema/Lookup.h" #include "clang/Sema/Scope.h" #include "clang/Sema/ScopeInfo.h" @@ -39,8 +42,9 @@ using namespace clang; /// /// \return true to indicate that there was an error and appropriate /// actions were taken -bool Sema::checkInitMethod(ObjCMethodDecl *method, +bool SemaObjC::checkInitMethod(ObjCMethodDecl *method, QualType receiverTypeIfCall) { + ASTContext &Context = getASTContext(); if (method->isInvalidDecl()) return true; // This castAs is safe: methods that don't return an object @@ -97,7 +101,7 @@ bool Sema::checkInitMethod(ObjCMethodDecl *method, // If we're in a system header, and this is not a call, just make // the method unusable. - if (receiverTypeIfCall.isNull() && getSourceManager().isInSystemHeader(loc)) { + if (receiverTypeIfCall.isNull() && SemaRef.getSourceManager().isInSystemHeader(loc)) { method->addAttr(UnavailableAttr::CreateImplicit(Context, "", UnavailableAttr::IR_ARCInitReturnsUnrelated, loc)); return true; @@ -133,8 +137,9 @@ static void diagnoseNoescape(const ParmVarDecl *NewD, const ParmVarDecl *OldD, << cast(NewD->getDeclContext()); } -void Sema::CheckObjCMethodOverride(ObjCMethodDecl *NewMethod, +void SemaObjC::CheckObjCMethodOverride(ObjCMethodDecl *NewMethod, const ObjCMethodDecl *Overridden) { + ASTContext &Context = getASTContext(); if (Overridden->hasRelatedResultType() && !NewMethod->hasRelatedResultType()) { // This can only happen when the method follows a naming convention that @@ -216,13 +221,14 @@ void Sema::CheckObjCMethodOverride(ObjCMethodDecl *NewMethod, Diag(oldDecl->getLocation(), diag::note_previous_decl) << "parameter"; } - diagnoseNoescape(newDecl, oldDecl, *this); + diagnoseNoescape(newDecl, oldDecl, SemaRef); } } /// Check a method declaration for compatibility with the Objective-C /// ARC conventions. -bool Sema::CheckARCMethodDecl(ObjCMethodDecl *method) { +bool SemaObjC::CheckARCMethodDecl(ObjCMethodDecl *method) { + ASTContext &Context = getASTContext(); ObjCMethodFamily family = method->getMethodFamily(); switch (family) { case OMF_None: @@ -326,7 +332,7 @@ static void DiagnoseObjCImplementedDeprecations(Sema &S, const NamedDecl *ND, /// AddAnyMethodToGlobalPool - Add any method, instance or factory to global /// pool. -void Sema::AddAnyMethodToGlobalPool(Decl *D) { +void SemaObjC::AddAnyMethodToGlobalPool(Decl *D) { ObjCMethodDecl *MDecl = dyn_cast_or_null(D); // If we don't have a valid method decl, simply return. @@ -359,12 +365,13 @@ HasExplicitOwnershipAttr(Sema &S, ParmVarDecl *Param) { /// ActOnStartOfObjCMethodDef - This routine sets up parameters; invisible /// and user declared, in the method definition's AST. -void Sema::ActOnStartOfObjCMethodDef(Scope *FnBodyScope, Decl *D) { - ImplicitlyRetainedSelfLocs.clear(); - assert((getCurMethodDecl() == nullptr) && "Methodparsing confused"); +void SemaObjC::ActOnStartOfObjCMethodDef(Scope *FnBodyScope, Decl *D) { + ASTContext &Context = getASTContext(); + SemaRef.ImplicitlyRetainedSelfLocs.clear(); + assert((SemaRef.getCurMethodDecl() == nullptr) && "Methodparsing confused"); ObjCMethodDecl *MDecl = dyn_cast_or_null(D); - PushExpressionEvaluationContext(ExprEvalContexts.back().Context); + SemaRef.PushExpressionEvaluationContext(SemaRef.ExprEvalContexts.back().Context); // If we don't have a valid method decl, simply return. if (!MDecl) @@ -373,13 +380,13 @@ void Sema::ActOnStartOfObjCMethodDef(Scope *FnBodyScope, Decl *D) { QualType ResultType = MDecl->getReturnType(); if (!ResultType->isDependentType() && !ResultType->isVoidType() && !MDecl->isInvalidDecl() && - RequireCompleteType(MDecl->getLocation(), ResultType, + SemaRef.RequireCompleteType(MDecl->getLocation(), ResultType, diag::err_func_def_incomplete_result)) MDecl->setInvalidDecl(); // Allow all of Sema to see that we are entering a method definition. - PushDeclContext(FnBodyScope, MDecl); - PushFunctionScope(); + SemaRef.PushDeclContext(FnBodyScope, MDecl); + SemaRef.PushFunctionScope(); // Create Decl objects for each parameter, entrring them in the scope for // binding to their use. @@ -387,23 +394,23 @@ void Sema::ActOnStartOfObjCMethodDef(Scope *FnBodyScope, Decl *D) { // Insert the invisible arguments, self and _cmd! MDecl->createImplicitParams(Context, MDecl->getClassInterface()); - PushOnScopeChains(MDecl->getSelfDecl(), FnBodyScope); - PushOnScopeChains(MDecl->getCmdDecl(), FnBodyScope); + SemaRef.PushOnScopeChains(MDecl->getSelfDecl(), FnBodyScope); + SemaRef.PushOnScopeChains(MDecl->getCmdDecl(), FnBodyScope); // The ObjC parser requires parameter names so there's no need to check. - CheckParmsForFunctionDef(MDecl->parameters(), + SemaRef.CheckParmsForFunctionDef(MDecl->parameters(), /*CheckParameterNames=*/false); // Introduce all of the other parameters into this scope. for (auto *Param : MDecl->parameters()) { if (!Param->isInvalidDecl() && getLangOpts().ObjCAutoRefCount && - !HasExplicitOwnershipAttr(*this, Param)) + !HasExplicitOwnershipAttr(SemaRef, Param)) Diag(Param->getLocation(), diag::warn_arc_strong_pointer_objc_pointer) << Param->getType(); if (Param->getIdentifier()) - PushOnScopeChains(Param, FnBodyScope); + SemaRef.PushOnScopeChains(Param, FnBodyScope); } // In ARC, disallow definition of retain/release/autorelease/retainCount @@ -456,17 +463,17 @@ void Sema::ActOnStartOfObjCMethodDef(Scope *FnBodyScope, Decl *D) { // No need to issue deprecated warning if deprecated mehod in class/category // is being implemented in its own implementation (no overriding is involved). if (!ImplDeclOfMethodDecl || ImplDeclOfMethodDecl != ImplDeclOfMethodDef) - DiagnoseObjCImplementedDeprecations(*this, IMD, MDecl->getLocation()); + DiagnoseObjCImplementedDeprecations(SemaRef, IMD, MDecl->getLocation()); } if (MDecl->getMethodFamily() == OMF_init) { if (MDecl->isDesignatedInitializerForTheInterface()) { - getCurFunction()->ObjCIsDesignatedInit = true; - getCurFunction()->ObjCWarnForNoDesignatedInitChain = + SemaRef.getCurFunction()->ObjCIsDesignatedInit = true; + SemaRef.getCurFunction()->ObjCWarnForNoDesignatedInitChain = IC->getSuperClass() != nullptr; } else if (IC->hasDesignatedInitializers()) { - getCurFunction()->ObjCIsSecondaryInit = true; - getCurFunction()->ObjCWarnForNoInitDelegation = true; + SemaRef.getCurFunction()->ObjCIsSecondaryInit = true; + SemaRef.getCurFunction()->ObjCWarnForNoInitDelegation = true; } } @@ -479,17 +486,17 @@ void Sema::ActOnStartOfObjCMethodDef(Scope *FnBodyScope, Decl *D) { if (Family == OMF_dealloc) { if (!(getLangOpts().ObjCAutoRefCount || getLangOpts().getGC() == LangOptions::GCOnly)) - getCurFunction()->ObjCShouldCallSuper = true; + SemaRef.getCurFunction()->ObjCShouldCallSuper = true; } else if (Family == OMF_finalize) { if (Context.getLangOpts().getGC() != LangOptions::NonGC) - getCurFunction()->ObjCShouldCallSuper = true; + SemaRef.getCurFunction()->ObjCShouldCallSuper = true; } else { const ObjCMethodDecl *SuperMethod = SuperClass->lookupMethod(MDecl->getSelector(), MDecl->isInstanceMethod()); - getCurFunction()->ObjCShouldCallSuper = + SemaRef.getCurFunction()->ObjCShouldCallSuper = (SuperMethod && SuperMethod->hasAttr()); } } @@ -538,7 +545,7 @@ static void diagnoseUseOfProtocols(Sema &TheSema, } } -void Sema:: +void SemaObjC:: ActOnSuperClassOfClassInterface(Scope *S, SourceLocation AtInterfaceLoc, ObjCInterfaceDecl *IDecl, @@ -548,18 +555,19 @@ ActOnSuperClassOfClassInterface(Scope *S, SourceLocation SuperLoc, ArrayRef SuperTypeArgs, SourceRange SuperTypeArgsRange) { + ASTContext &Context = getASTContext(); // Check if a different kind of symbol declared in this scope. - NamedDecl *PrevDecl = LookupSingleName(TUScope, SuperName, SuperLoc, - LookupOrdinaryName); + NamedDecl *PrevDecl = SemaRef.LookupSingleName(SemaRef.TUScope, SuperName, SuperLoc, + Sema::LookupOrdinaryName); if (!PrevDecl) { // Try to correct for a typo in the superclass name without correcting // to the class we're defining. ObjCInterfaceValidatorCCC CCC(IDecl); - if (TypoCorrection Corrected = CorrectTypo( - DeclarationNameInfo(SuperName, SuperLoc), LookupOrdinaryName, - TUScope, nullptr, CCC, CTK_ErrorRecovery)) { - diagnoseTypo(Corrected, PDiag(diag::err_undef_superclass_suggest) + if (TypoCorrection Corrected = SemaRef.CorrectTypo( + DeclarationNameInfo(SuperName, SuperLoc), Sema::LookupOrdinaryName, + SemaRef.TUScope, nullptr, CCC, Sema::CTK_ErrorRecovery)) { + SemaRef.diagnoseTypo(Corrected, SemaRef.PDiag(diag::err_undef_superclass_suggest) << SuperName << ClassName); PrevDecl = Corrected.getCorrectionDeclAs(); } @@ -576,7 +584,7 @@ ActOnSuperClassOfClassInterface(Scope *S, // Diagnose classes that inherit from deprecated classes. if (SuperClassDecl) { - (void)DiagnoseUseOfDecl(SuperClassDecl, SuperLoc); + (void)SemaRef.DiagnoseUseOfDecl(SuperClassDecl, SuperLoc); SuperClassType = Context.getObjCInterfaceType(SuperClassDecl); } @@ -595,7 +603,7 @@ ActOnSuperClassOfClassInterface(Scope *S, // @interface NewI @end // typedef NewI DeprI __attribute__((deprecated("blah"))) // @interface SI : DeprI /* warn here */ @end - (void)DiagnoseUseOfDecl(const_cast(TDecl), SuperLoc); + (void)SemaRef.DiagnoseUseOfDecl(const_cast(TDecl), SuperLoc); } } } @@ -615,7 +623,7 @@ ActOnSuperClassOfClassInterface(Scope *S, if (!SuperClassDecl) Diag(SuperLoc, diag::err_undef_superclass) << SuperName << ClassName << SourceRange(AtInterfaceLoc, ClassLoc); - else if (RequireCompleteType(SuperLoc, + else if (SemaRef.RequireCompleteType(SuperLoc, SuperClassType, diag::err_forward_superclass, SuperClassDecl->getDeclName(), @@ -637,7 +645,7 @@ ActOnSuperClassOfClassInterface(Scope *S, TypeResult fullSuperClassType = actOnObjCTypeArgsAndProtocolQualifiers( S, SuperLoc, - CreateParsedType(SuperClassType, + SemaRef.CreateParsedType(SuperClassType, nullptr), SuperTypeArgsRange.getBegin(), SuperTypeArgs, @@ -649,7 +657,7 @@ ActOnSuperClassOfClassInterface(Scope *S, if (!fullSuperClassType.isUsable()) return; - SuperClassType = GetTypeFromParser(fullSuperClassType.get(), + SuperClassType = SemaRef.GetTypeFromParser(fullSuperClassType.get(), &SuperClassTInfo); } @@ -663,7 +671,7 @@ ActOnSuperClassOfClassInterface(Scope *S, } } -DeclResult Sema::actOnObjCTypeParam(Scope *S, +DeclResult SemaObjC::actOnObjCTypeParam(Scope *S, ObjCTypeParamVariance variance, SourceLocation varianceLoc, unsigned index, @@ -671,17 +679,18 @@ DeclResult Sema::actOnObjCTypeParam(Scope *S, SourceLocation paramLoc, SourceLocation colonLoc, ParsedType parsedTypeBound) { + ASTContext &Context = getASTContext(); // If there was an explicitly-provided type bound, check it. TypeSourceInfo *typeBoundInfo = nullptr; if (parsedTypeBound) { // The type bound can be any Objective-C pointer type. - QualType typeBound = GetTypeFromParser(parsedTypeBound, &typeBoundInfo); + QualType typeBound = SemaRef.GetTypeFromParser(parsedTypeBound, &typeBoundInfo); if (typeBound->isObjCObjectPointerType()) { // okay } else if (typeBound->isObjCObjectType()) { // The user forgot the * on an Objective-C pointer type, e.g., // "T : NSView". - SourceLocation starLoc = getLocForEndOfToken( + SourceLocation starLoc = SemaRef.getLocForEndOfToken( typeBoundInfo->getTypeLoc().getEndLoc()); Diag(typeBoundInfo->getTypeLoc().getBeginLoc(), diag::err_objc_type_param_bound_missing_pointer) @@ -762,15 +771,16 @@ DeclResult Sema::actOnObjCTypeParam(Scope *S, } // Create the type parameter. - return ObjCTypeParamDecl::Create(Context, CurContext, variance, varianceLoc, + return ObjCTypeParamDecl::Create(Context, SemaRef.CurContext, variance, varianceLoc, index, paramLoc, paramName, colonLoc, typeBoundInfo); } -ObjCTypeParamList *Sema::actOnObjCTypeParamList(Scope *S, +ObjCTypeParamList *SemaObjC::actOnObjCTypeParamList(Scope *S, SourceLocation lAngleLoc, ArrayRef typeParamsIn, SourceLocation rAngleLoc) { + ASTContext &Context = getASTContext(); // We know that the array only contains Objective-C type parameters. ArrayRef typeParams( @@ -794,7 +804,7 @@ ObjCTypeParamList *Sema::actOnObjCTypeParamList(Scope *S, knownParams.insert(std::make_pair(typeParam->getIdentifier(), typeParam)); // Push the type parameter into scope. - PushOnScopeChains(typeParam, S, /*AddToContext=*/false); + SemaRef.PushOnScopeChains(typeParam, S, /*AddToContext=*/false); } } @@ -802,11 +812,11 @@ ObjCTypeParamList *Sema::actOnObjCTypeParamList(Scope *S, return ObjCTypeParamList::create(Context, lAngleLoc, typeParams, rAngleLoc); } -void Sema::popObjCTypeParamList(Scope *S, ObjCTypeParamList *typeParamList) { +void SemaObjC::popObjCTypeParamList(Scope *S, ObjCTypeParamList *typeParamList) { for (auto *typeParam : *typeParamList) { if (!typeParam->isInvalidDecl()) { S->RemoveDecl(typeParam); - IdResolver.RemoveDecl(typeParam); + SemaRef.IdResolver.RemoveDecl(typeParam); } } } @@ -971,7 +981,7 @@ static bool checkTypeParamListConsistency(Sema &S, return false; } -ObjCInterfaceDecl *Sema::ActOnStartClassInterface( +ObjCInterfaceDecl *SemaObjC::ActOnStartClassInterface( Scope *S, SourceLocation AtInterfaceLoc, IdentifierInfo *ClassName, SourceLocation ClassLoc, ObjCTypeParamList *typeParamList, IdentifierInfo *SuperName, SourceLocation SuperLoc, @@ -980,11 +990,12 @@ ObjCInterfaceDecl *Sema::ActOnStartClassInterface( const SourceLocation *ProtoLocs, SourceLocation EndProtoLoc, const ParsedAttributesView &AttrList, SkipBodyInfo *SkipBody) { assert(ClassName && "Missing class identifier"); - + + ASTContext &Context = getASTContext(); // Check for another declaration kind with the same name. NamedDecl *PrevDecl = - LookupSingleName(TUScope, ClassName, ClassLoc, LookupOrdinaryName, - forRedeclarationInCurContext()); + SemaRef.LookupSingleName(SemaRef.TUScope, ClassName, ClassLoc, Sema::LookupOrdinaryName, + SemaRef.forRedeclarationInCurContext()); if (PrevDecl && !isa(PrevDecl)) { Diag(ClassLoc, diag::err_redefinition_different_kind) << ClassName; @@ -1016,7 +1027,7 @@ ObjCInterfaceDecl *Sema::ActOnStartClassInterface( if (ObjCTypeParamList *prevTypeParamList = PrevIDecl->getTypeParamList()) { if (typeParamList) { // Both have type parameter lists; check for consistency. - if (checkTypeParamListConsistency(*this, prevTypeParamList, + if (checkTypeParamListConsistency(SemaRef, prevTypeParamList, typeParamList, TypeParamListContext::Definition)) { typeParamList = nullptr; @@ -1033,7 +1044,7 @@ ObjCInterfaceDecl *Sema::ActOnStartClassInterface( clonedTypeParams.push_back( ObjCTypeParamDecl::Create( Context, - CurContext, + SemaRef.CurContext, typeParam->getVariance(), SourceLocation(), typeParam->getIndex(), @@ -1052,12 +1063,12 @@ ObjCInterfaceDecl *Sema::ActOnStartClassInterface( } ObjCInterfaceDecl *IDecl - = ObjCInterfaceDecl::Create(Context, CurContext, AtInterfaceLoc, ClassName, + = ObjCInterfaceDecl::Create(Context, SemaRef.CurContext, AtInterfaceLoc, ClassName, typeParamList, PrevIDecl, ClassLoc); if (PrevIDecl) { // Class already seen. Was it a definition? if (ObjCInterfaceDecl *Def = PrevIDecl->getDefinition()) { - if (SkipBody && !hasVisibleDefinition(Def)) { + if (SkipBody && !SemaRef.hasVisibleDefinition(Def)) { SkipBody->CheckSameAsPrevious = true; SkipBody->New = IDecl; SkipBody->Previous = Def; @@ -1070,15 +1081,15 @@ ObjCInterfaceDecl *Sema::ActOnStartClassInterface( } } - ProcessDeclAttributeList(TUScope, IDecl, AttrList); - AddPragmaAttributes(TUScope, IDecl); - ProcessAPINotes(IDecl); + SemaRef.ProcessDeclAttributeList(SemaRef.TUScope, IDecl, AttrList); + SemaRef.AddPragmaAttributes(SemaRef.TUScope, IDecl); + SemaRef.ProcessAPINotes(IDecl); // Merge attributes from previous declarations. if (PrevIDecl) - mergeDeclAttributes(IDecl, PrevIDecl); + SemaRef.mergeDeclAttributes(IDecl, PrevIDecl); - PushOnScopeChains(IDecl, TUScope); + SemaRef.PushOnScopeChains(IDecl, SemaRef.TUScope); // Start the definition of this class. If we're in a redefinition case, there // may already be a definition, so we'll end up adding to it. @@ -1089,7 +1100,7 @@ ObjCInterfaceDecl *Sema::ActOnStartClassInterface( if (SuperName) { // Diagnose availability in the context of the @interface. - ContextRAII SavedContext(*this, IDecl); + Sema::ContextRAII SavedContext(SemaRef, IDecl); ActOnSuperClassOfClassInterface(S, AtInterfaceLoc, IDecl, ClassName, ClassLoc, @@ -1101,7 +1112,7 @@ ObjCInterfaceDecl *Sema::ActOnStartClassInterface( // Check then save referenced protocols. if (NumProtoRefs) { - diagnoseUseOfProtocols(*this, IDecl, (ObjCProtocolDecl*const*)ProtoRefs, + diagnoseUseOfProtocols(SemaRef, IDecl, (ObjCProtocolDecl*const*)ProtoRefs, NumProtoRefs, ProtoLocs); IDecl->setProtocolList((ObjCProtocolDecl*const*)ProtoRefs, NumProtoRefs, ProtoLocs, Context); @@ -1116,14 +1127,14 @@ ObjCInterfaceDecl *Sema::ActOnStartClassInterface( /// ActOnTypedefedProtocols - this action finds protocol list as part of the /// typedef'ed use for a qualified super class and adds them to the list /// of the protocols. -void Sema::ActOnTypedefedProtocols(SmallVectorImpl &ProtocolRefs, +void SemaObjC::ActOnTypedefedProtocols(SmallVectorImpl &ProtocolRefs, SmallVectorImpl &ProtocolLocs, IdentifierInfo *SuperName, SourceLocation SuperLoc) { if (!SuperName) return; - NamedDecl* IDecl = LookupSingleName(TUScope, SuperName, SuperLoc, - LookupOrdinaryName); + NamedDecl* IDecl = SemaRef.LookupSingleName(SemaRef.TUScope, SuperName, SuperLoc, + Sema::LookupOrdinaryName); if (!IDecl) return; @@ -1143,15 +1154,16 @@ void Sema::ActOnTypedefedProtocols(SmallVectorImpl &ProtocolRefs, /// ActOnCompatibilityAlias - this action is called after complete parsing of /// a \@compatibility_alias declaration. It sets up the alias relationships. -Decl *Sema::ActOnCompatibilityAlias(SourceLocation AtLoc, +Decl *SemaObjC::ActOnCompatibilityAlias(SourceLocation AtLoc, IdentifierInfo *AliasName, SourceLocation AliasLocation, IdentifierInfo *ClassName, SourceLocation ClassLocation) { + ASTContext &Context = getASTContext(); // Look for previous declaration of alias name NamedDecl *ADecl = - LookupSingleName(TUScope, AliasName, AliasLocation, LookupOrdinaryName, - forRedeclarationInCurContext()); + SemaRef.LookupSingleName(SemaRef.TUScope, AliasName, AliasLocation, Sema::LookupOrdinaryName, + SemaRef.forRedeclarationInCurContext()); if (ADecl) { Diag(AliasLocation, diag::err_conflicting_aliasing_type) << AliasName; Diag(ADecl->getLocation(), diag::note_previous_declaration); @@ -1159,17 +1171,17 @@ Decl *Sema::ActOnCompatibilityAlias(SourceLocation AtLoc, } // Check for class declaration NamedDecl *CDeclU = - LookupSingleName(TUScope, ClassName, ClassLocation, LookupOrdinaryName, - forRedeclarationInCurContext()); + SemaRef.LookupSingleName(SemaRef.TUScope, ClassName, ClassLocation, Sema::LookupOrdinaryName, + SemaRef.forRedeclarationInCurContext()); if (const TypedefNameDecl *TDecl = dyn_cast_or_null(CDeclU)) { QualType T = TDecl->getUnderlyingType(); if (T->isObjCObjectType()) { if (NamedDecl *IDecl = T->castAs()->getInterface()) { ClassName = IDecl->getIdentifier(); - CDeclU = LookupSingleName(TUScope, ClassName, ClassLocation, - LookupOrdinaryName, - forRedeclarationInCurContext()); + CDeclU = SemaRef.LookupSingleName(SemaRef.TUScope, ClassName, ClassLocation, + Sema::LookupOrdinaryName, + SemaRef.forRedeclarationInCurContext()); } } } @@ -1183,15 +1195,15 @@ Decl *Sema::ActOnCompatibilityAlias(SourceLocation AtLoc, // Everything checked out, instantiate a new alias declaration AST. ObjCCompatibleAliasDecl *AliasDecl = - ObjCCompatibleAliasDecl::Create(Context, CurContext, AtLoc, AliasName, CDecl); + ObjCCompatibleAliasDecl::Create(Context, SemaRef.CurContext, AtLoc, AliasName, CDecl); if (!CheckObjCDeclScope(AliasDecl)) - PushOnScopeChains(AliasDecl, TUScope); + SemaRef.PushOnScopeChains(AliasDecl, SemaRef.TUScope); return AliasDecl; } -bool Sema::CheckForwardProtocolDeclarationForCircularDependency( +bool SemaObjC::CheckForwardProtocolDeclarationForCircularDependency( IdentifierInfo *PName, SourceLocation &Ploc, SourceLocation PrevLoc, const ObjCList &PList) { @@ -1199,7 +1211,7 @@ bool Sema::CheckForwardProtocolDeclarationForCircularDependency( bool res = false; for (ObjCList::iterator I = PList.begin(), E = PList.end(); I != E; ++I) { - if (ObjCProtocolDecl *PDecl = LookupProtocol((*I)->getIdentifier(), + if (ObjCProtocolDecl *PDecl =LookupProtocol((*I)->getIdentifier(), Ploc)) { if (PDecl->getIdentifier() == PName) { Diag(Ploc, diag::err_protocol_has_circular_dependency); @@ -1218,27 +1230,28 @@ bool Sema::CheckForwardProtocolDeclarationForCircularDependency( return res; } -ObjCProtocolDecl *Sema::ActOnStartProtocolInterface( +ObjCProtocolDecl *SemaObjC::ActOnStartProtocolInterface( SourceLocation AtProtoInterfaceLoc, IdentifierInfo *ProtocolName, SourceLocation ProtocolLoc, Decl *const *ProtoRefs, unsigned NumProtoRefs, const SourceLocation *ProtoLocs, SourceLocation EndProtoLoc, const ParsedAttributesView &AttrList, SkipBodyInfo *SkipBody) { + ASTContext &Context = getASTContext(); bool err = false; // FIXME: Deal with AttrList. assert(ProtocolName && "Missing protocol identifier"); ObjCProtocolDecl *PrevDecl = LookupProtocol(ProtocolName, ProtocolLoc, - forRedeclarationInCurContext()); + SemaRef.forRedeclarationInCurContext()); ObjCProtocolDecl *PDecl = nullptr; if (ObjCProtocolDecl *Def = PrevDecl? PrevDecl->getDefinition() : nullptr) { // Create a new protocol that is completely distinct from previous // declarations, and do not make this protocol available for name lookup. // That way, we'll end up completely ignoring the duplicate. // FIXME: Can we turn this into an error? - PDecl = ObjCProtocolDecl::Create(Context, CurContext, ProtocolName, + PDecl = ObjCProtocolDecl::Create(Context, SemaRef.CurContext, ProtocolName, ProtocolLoc, AtProtoInterfaceLoc, /*PrevDecl=*/Def); - if (SkipBody && !hasVisibleDefinition(Def)) { + if (SkipBody && !SemaRef.hasVisibleDefinition(Def)) { SkipBody->CheckSameAsPrevious = true; SkipBody->New = PDecl; SkipBody->Previous = Def; @@ -1251,7 +1264,7 @@ ObjCProtocolDecl *Sema::ActOnStartProtocolInterface( // If we are using modules, add the decl to the context in order to // serialize something meaningful. if (getLangOpts().Modules) - PushOnScopeChains(PDecl, TUScope); + SemaRef.PushOnScopeChains(PDecl, SemaRef.TUScope); PDecl->startDuplicateDefinitionForComparison(); } else { if (PrevDecl) { @@ -1264,25 +1277,25 @@ ObjCProtocolDecl *Sema::ActOnStartProtocolInterface( } // Create the new declaration. - PDecl = ObjCProtocolDecl::Create(Context, CurContext, ProtocolName, + PDecl = ObjCProtocolDecl::Create(Context, SemaRef.CurContext, ProtocolName, ProtocolLoc, AtProtoInterfaceLoc, /*PrevDecl=*/PrevDecl); - PushOnScopeChains(PDecl, TUScope); + SemaRef.PushOnScopeChains(PDecl, SemaRef.TUScope); PDecl->startDefinition(); } - ProcessDeclAttributeList(TUScope, PDecl, AttrList); - AddPragmaAttributes(TUScope, PDecl); - ProcessAPINotes(PDecl); + SemaRef.ProcessDeclAttributeList(SemaRef.TUScope, PDecl, AttrList); + SemaRef.AddPragmaAttributes(SemaRef.TUScope, PDecl); + SemaRef.ProcessAPINotes(PDecl); // Merge attributes from previous declarations. if (PrevDecl) - mergeDeclAttributes(PDecl, PrevDecl); + SemaRef.mergeDeclAttributes(PDecl, PrevDecl); if (!err && NumProtoRefs ) { /// Check then save referenced protocols. - diagnoseUseOfProtocols(*this, PDecl, (ObjCProtocolDecl*const*)ProtoRefs, + diagnoseUseOfProtocols(SemaRef, PDecl, (ObjCProtocolDecl*const*)ProtoRefs, NumProtoRefs, ProtoLocs); PDecl->setProtocolList((ObjCProtocolDecl*const*)ProtoRefs, NumProtoRefs, ProtoLocs, Context); @@ -1313,18 +1326,18 @@ static bool NestedProtocolHasNoDefinition(ObjCProtocolDecl *PDecl, /// issues an error if they are not declared. It returns list of /// protocol declarations in its 'Protocols' argument. void -Sema::FindProtocolDeclaration(bool WarnOnDeclarations, bool ForObjCContainer, +SemaObjC::FindProtocolDeclaration(bool WarnOnDeclarations, bool ForObjCContainer, ArrayRef ProtocolId, SmallVectorImpl &Protocols) { for (const IdentifierLocPair &Pair : ProtocolId) { ObjCProtocolDecl *PDecl = LookupProtocol(Pair.first, Pair.second); if (!PDecl) { DeclFilterCCC CCC{}; - TypoCorrection Corrected = CorrectTypo( - DeclarationNameInfo(Pair.first, Pair.second), LookupObjCProtocolName, - TUScope, nullptr, CCC, CTK_ErrorRecovery); + TypoCorrection Corrected = SemaRef.CorrectTypo( + DeclarationNameInfo(Pair.first, Pair.second), Sema::LookupObjCProtocolName, + SemaRef.TUScope, nullptr, CCC, Sema::CTK_ErrorRecovery); if ((PDecl = Corrected.getCorrectionDeclAs())) - diagnoseTypo(Corrected, PDiag(diag::err_undeclared_protocol_suggest) + SemaRef.diagnoseTypo(Corrected, SemaRef.PDiag(diag::err_undeclared_protocol_suggest) << Pair.first); } @@ -1339,7 +1352,7 @@ Sema::FindProtocolDeclaration(bool WarnOnDeclarations, bool ForObjCContainer, // For an objc container, delay protocol reference checking until after we // can set the objc decl as the availability context, otherwise check now. if (!ForObjCContainer) { - (void)DiagnoseUseOfDecl(PDecl, Pair.second); + (void)SemaRef.DiagnoseUseOfDecl(PDecl, Pair.second); } // If this is a forward declaration and we are supposed to warn in this @@ -1415,7 +1428,7 @@ class ObjCTypeArgOrProtocolValidatorCCC final }; } // end anonymous namespace -void Sema::DiagnoseTypeArgsAndProtocols(IdentifierInfo *ProtocolId, +void SemaObjC::DiagnoseTypeArgsAndProtocols(IdentifierInfo *ProtocolId, SourceLocation ProtocolLoc, IdentifierInfo *TypeArgId, SourceLocation TypeArgLoc, @@ -1425,7 +1438,7 @@ void Sema::DiagnoseTypeArgsAndProtocols(IdentifierInfo *ProtocolId, << SourceRange(ProtocolLoc); } -void Sema::actOnObjCTypeArgsOrProtocolQualifiers( +void SemaObjC::actOnObjCTypeArgsOrProtocolQualifiers( Scope *S, ParsedType baseType, SourceLocation lAngleLoc, @@ -1439,6 +1452,7 @@ void Sema::actOnObjCTypeArgsOrProtocolQualifiers( SmallVectorImpl &protocols, SourceLocation &protocolRAngleLoc, bool warnOnIncompleteProtocols) { + ASTContext &Context = getASTContext(); // Local function that updates the declaration specifiers with // protocol information. unsigned numProtocolsResolved = 0; @@ -1449,7 +1463,7 @@ void Sema::actOnObjCTypeArgsOrProtocolQualifiers( // which case we want to warn about typos such as // "NSArray" (that should be NSArray). ObjCInterfaceDecl *baseClass = nullptr; - QualType base = GetTypeFromParser(baseType, nullptr); + QualType base = SemaRef.GetTypeFromParser(baseType, nullptr); bool allAreTypeNames = false; SourceLocation firstClassNameLoc; if (!base.isNull()) { @@ -1472,7 +1486,7 @@ void Sema::actOnObjCTypeArgsOrProtocolQualifiers( // For an objc container, delay protocol reference checking until after we // can set the objc decl as the availability context, otherwise check now. if (!warnOnIncompleteProtocols) { - (void)DiagnoseUseOfDecl(proto, identifierLocs[i]); + (void)SemaRef.DiagnoseUseOfDecl(proto, identifierLocs[i]); } // If this is a forward protocol declaration, get its definition. @@ -1495,8 +1509,8 @@ void Sema::actOnObjCTypeArgsOrProtocolQualifiers( // about such things), check whether this name refers to a type // as well. if (allAreTypeNames) { - if (auto *decl = LookupSingleName(S, identifiers[i], identifierLocs[i], - LookupOrdinaryName)) { + if (auto *decl = SemaRef.LookupSingleName(S, identifiers[i], identifierLocs[i], + Sema::LookupOrdinaryName)) { if (isa(decl)) { if (firstClassNameLoc.isInvalid()) firstClassNameLoc = identifierLocs[i]; @@ -1528,7 +1542,7 @@ void Sema::actOnObjCTypeArgsOrProtocolQualifiers( if (allProtocolsDeclared) { Diag(firstClassNameLoc, diag::warn_objc_redundant_qualified_class_type) << baseClass->getDeclName() << SourceRange(lAngleLoc, rAngleLoc) - << FixItHint::CreateInsertion(getLocForEndOfToken(firstClassNameLoc), + << FixItHint::CreateInsertion(SemaRef.getLocForEndOfToken(firstClassNameLoc), " *"); } } @@ -1558,8 +1572,8 @@ void Sema::actOnObjCTypeArgsOrProtocolQualifiers( SmallVector typeDecls; unsigned numTypeDeclsResolved = 0; for (unsigned i = 0, n = identifiers.size(); i != n; ++i) { - NamedDecl *decl = LookupSingleName(S, identifiers[i], identifierLocs[i], - LookupOrdinaryName); + NamedDecl *decl = SemaRef.LookupSingleName(S, identifiers[i], identifierLocs[i], + Sema::LookupOrdinaryName); if (!decl) { typeDecls.push_back(TypeOrClassDecl()); continue; @@ -1596,7 +1610,7 @@ void Sema::actOnObjCTypeArgsOrProtocolQualifiers( else type = Context.getObjCInterfaceType(typeDecl.get()); TypeSourceInfo *parsedTSInfo = Context.getTrivialTypeSourceInfo(type, loc); - ParsedType parsedType = CreateParsedType(type, parsedTSInfo); + ParsedType parsedType = SemaRef.CreateParsedType(type, parsedTSInfo); DS.SetTypeSpecType(DeclSpec::TST_typename, loc, prevSpec, diagID, parsedType, Context.getPrintingPolicy()); // Use the identifier location for the type source range. @@ -1609,7 +1623,7 @@ void Sema::actOnObjCTypeArgsOrProtocolQualifiers( // If we have a typedef of an Objective-C class type that is missing a '*', // add the '*'. if (type->getAs()) { - SourceLocation starLoc = getLocForEndOfToken(loc); + SourceLocation starLoc = SemaRef.getLocForEndOfToken(loc); D.AddTypeInfo(DeclaratorChunk::getPointer(/*TypeQuals=*/0, starLoc, SourceLocation(), SourceLocation(), @@ -1625,7 +1639,7 @@ void Sema::actOnObjCTypeArgsOrProtocolQualifiers( } // Convert this to a type. - return ActOnTypeName(D); + return SemaRef.ActOnTypeName(D); }; // Local function that updates the declaration specifiers with @@ -1659,14 +1673,14 @@ void Sema::actOnObjCTypeArgsOrProtocolQualifiers( // Error recovery: some names weren't found, or we have a mix of // type and protocol names. Go resolve all of the unresolved names // and complain if we can't find a consistent answer. - LookupNameKind lookupKind = LookupAnyName; + Sema::LookupNameKind lookupKind = Sema::LookupAnyName; for (unsigned i = 0, n = identifiers.size(); i != n; ++i) { // If we already have a protocol or type. Check whether it is the // right thing. if (protocols[i] || typeDecls[i]) { // If we haven't figured out whether we want types or protocols // yet, try to figure it out from this name. - if (lookupKind == LookupAnyName) { + if (lookupKind == Sema::LookupAnyName) { // If this name refers to both a protocol and a type (e.g., \c // NSObject), don't conclude anything yet. if (protocols[i] && typeDecls[i]) @@ -1674,19 +1688,19 @@ void Sema::actOnObjCTypeArgsOrProtocolQualifiers( // Otherwise, let this name decide whether we'll be correcting // toward types or protocols. - lookupKind = protocols[i] ? LookupObjCProtocolName - : LookupOrdinaryName; + lookupKind = protocols[i] ? Sema::LookupObjCProtocolName + : Sema::LookupOrdinaryName; continue; } // If we want protocols and we have a protocol, there's nothing // more to do. - if (lookupKind == LookupObjCProtocolName && protocols[i]) + if (lookupKind == Sema::LookupObjCProtocolName && protocols[i]) continue; // If we want types and we have a type declaration, there's // nothing more to do. - if (lookupKind == LookupOrdinaryName && typeDecls[i]) + if (lookupKind == Sema::LookupOrdinaryName && typeDecls[i]) continue; // We have a conflict: some names refer to protocols and others @@ -1703,15 +1717,15 @@ void Sema::actOnObjCTypeArgsOrProtocolQualifiers( // Perform typo correction on the name. ObjCTypeArgOrProtocolValidatorCCC CCC(Context, lookupKind); TypoCorrection corrected = - CorrectTypo(DeclarationNameInfo(identifiers[i], identifierLocs[i]), - lookupKind, S, nullptr, CCC, CTK_ErrorRecovery); + SemaRef.CorrectTypo(DeclarationNameInfo(identifiers[i], identifierLocs[i]), + lookupKind, S, nullptr, CCC, Sema::CTK_ErrorRecovery); if (corrected) { // Did we find a protocol? if (auto proto = corrected.getCorrectionDeclAs()) { - diagnoseTypo(corrected, - PDiag(diag::err_undeclared_protocol_suggest) + SemaRef.diagnoseTypo(corrected, + SemaRef.PDiag(diag::err_undeclared_protocol_suggest) << identifiers[i]); - lookupKind = LookupObjCProtocolName; + lookupKind = Sema::LookupObjCProtocolName; protocols[i] = proto; ++numProtocolsResolved; continue; @@ -1719,10 +1733,10 @@ void Sema::actOnObjCTypeArgsOrProtocolQualifiers( // Did we find a type? if (auto typeDecl = corrected.getCorrectionDeclAs()) { - diagnoseTypo(corrected, - PDiag(diag::err_unknown_typename_suggest) + SemaRef.diagnoseTypo(corrected, + SemaRef.PDiag(diag::err_unknown_typename_suggest) << identifiers[i]); - lookupKind = LookupOrdinaryName; + lookupKind = Sema::LookupOrdinaryName; typeDecls[i] = typeDecl; ++numTypeDeclsResolved; continue; @@ -1730,10 +1744,10 @@ void Sema::actOnObjCTypeArgsOrProtocolQualifiers( // Did we find an Objective-C class? if (auto objcClass = corrected.getCorrectionDeclAs()) { - diagnoseTypo(corrected, - PDiag(diag::err_unknown_type_or_class_name_suggest) + SemaRef.diagnoseTypo(corrected, + SemaRef.PDiag(diag::err_unknown_type_or_class_name_suggest) << identifiers[i] << true); - lookupKind = LookupOrdinaryName; + lookupKind = Sema::LookupOrdinaryName; typeDecls[i] = objcClass; ++numTypeDeclsResolved; continue; @@ -1742,8 +1756,8 @@ void Sema::actOnObjCTypeArgsOrProtocolQualifiers( // We couldn't find anything. Diag(identifierLocs[i], - (lookupKind == LookupAnyName ? diag::err_objc_type_arg_missing - : lookupKind == LookupObjCProtocolName ? diag::err_undeclared_protocol + (lookupKind == Sema::LookupAnyName ? diag::err_objc_type_arg_missing + : lookupKind == Sema::LookupObjCProtocolName ? diag::err_undeclared_protocol : diag::err_unknown_typename)) << identifiers[i]; protocols.clear(); @@ -1764,7 +1778,7 @@ void Sema::actOnObjCTypeArgsOrProtocolQualifiers( /// DiagnoseClassExtensionDupMethods - Check for duplicate declaration of /// a class method in its extension. /// -void Sema::DiagnoseClassExtensionDupMethods(ObjCCategoryDecl *CAT, +void SemaObjC::DiagnoseClassExtensionDupMethods(ObjCCategoryDecl *CAT, ObjCInterfaceDecl *ID) { if (!ID) return; // Possibly due to previous error @@ -1788,59 +1802,61 @@ void Sema::DiagnoseClassExtensionDupMethods(ObjCCategoryDecl *CAT, } /// ActOnForwardProtocolDeclaration - Handle \@protocol foo; -Sema::DeclGroupPtrTy -Sema::ActOnForwardProtocolDeclaration(SourceLocation AtProtocolLoc, +SemaObjC::DeclGroupPtrTy +SemaObjC::ActOnForwardProtocolDeclaration(SourceLocation AtProtocolLoc, ArrayRef IdentList, const ParsedAttributesView &attrList) { + ASTContext &Context = getASTContext(); SmallVector DeclsInGroup; for (const IdentifierLocPair &IdentPair : IdentList) { IdentifierInfo *Ident = IdentPair.first; ObjCProtocolDecl *PrevDecl = LookupProtocol(Ident, IdentPair.second, - forRedeclarationInCurContext()); + SemaRef.forRedeclarationInCurContext()); ObjCProtocolDecl *PDecl - = ObjCProtocolDecl::Create(Context, CurContext, Ident, + = ObjCProtocolDecl::Create(Context, SemaRef.CurContext, Ident, IdentPair.second, AtProtocolLoc, PrevDecl); - PushOnScopeChains(PDecl, TUScope); + SemaRef.PushOnScopeChains(PDecl, SemaRef.TUScope); CheckObjCDeclScope(PDecl); - ProcessDeclAttributeList(TUScope, PDecl, attrList); - AddPragmaAttributes(TUScope, PDecl); + SemaRef.ProcessDeclAttributeList(SemaRef.TUScope, PDecl, attrList); + SemaRef.AddPragmaAttributes(SemaRef.TUScope, PDecl); if (PrevDecl) - mergeDeclAttributes(PDecl, PrevDecl); + SemaRef.mergeDeclAttributes(PDecl, PrevDecl); DeclsInGroup.push_back(PDecl); } - return BuildDeclaratorGroup(DeclsInGroup); + return SemaRef.BuildDeclaratorGroup(DeclsInGroup); } -ObjCCategoryDecl *Sema::ActOnStartCategoryInterface( +ObjCCategoryDecl *SemaObjC::ActOnStartCategoryInterface( SourceLocation AtInterfaceLoc, const IdentifierInfo *ClassName, SourceLocation ClassLoc, ObjCTypeParamList *typeParamList, const IdentifierInfo *CategoryName, SourceLocation CategoryLoc, Decl *const *ProtoRefs, unsigned NumProtoRefs, const SourceLocation *ProtoLocs, SourceLocation EndProtoLoc, const ParsedAttributesView &AttrList) { + ASTContext &Context = getASTContext(); ObjCCategoryDecl *CDecl; ObjCInterfaceDecl *IDecl = getObjCInterfaceDecl(ClassName, ClassLoc, true); /// Check that class of this category is already completely declared. if (!IDecl - || RequireCompleteType(ClassLoc, Context.getObjCInterfaceType(IDecl), + || SemaRef.RequireCompleteType(ClassLoc, Context.getObjCInterfaceType(IDecl), diag::err_category_forward_interface, CategoryName == nullptr)) { // Create an invalid ObjCCategoryDecl to serve as context for // the enclosing method declarations. We mark the decl invalid // to make it clear that this isn't a valid AST. - CDecl = ObjCCategoryDecl::Create(Context, CurContext, AtInterfaceLoc, + CDecl = ObjCCategoryDecl::Create(Context, SemaRef.CurContext, AtInterfaceLoc, ClassLoc, CategoryLoc, CategoryName, IDecl, typeParamList); CDecl->setInvalidDecl(); - CurContext->addDecl(CDecl); + SemaRef.CurContext->addDecl(CDecl); if (!IDecl) Diag(ClassLoc, diag::err_undef_interface) << ClassName; @@ -1868,7 +1884,7 @@ ObjCCategoryDecl *Sema::ActOnStartCategoryInterface( // If we have a type parameter list, check it. if (typeParamList) { if (auto prevTypeParamList = IDecl->getTypeParamList()) { - if (checkTypeParamListConsistency(*this, prevTypeParamList, typeParamList, + if (checkTypeParamListConsistency(SemaRef, prevTypeParamList, typeParamList, CategoryName ? TypeParamListContext::Category : TypeParamListContext::Extension)) @@ -1884,20 +1900,20 @@ ObjCCategoryDecl *Sema::ActOnStartCategoryInterface( } } - CDecl = ObjCCategoryDecl::Create(Context, CurContext, AtInterfaceLoc, + CDecl = ObjCCategoryDecl::Create(Context, SemaRef.CurContext, AtInterfaceLoc, ClassLoc, CategoryLoc, CategoryName, IDecl, typeParamList); // FIXME: PushOnScopeChains? - CurContext->addDecl(CDecl); + SemaRef.CurContext->addDecl(CDecl); // Process the attributes before looking at protocols to ensure that the // availability attribute is attached to the category to provide availability // checking for protocol uses. - ProcessDeclAttributeList(TUScope, CDecl, AttrList); - AddPragmaAttributes(TUScope, CDecl); + SemaRef.ProcessDeclAttributeList(SemaRef.TUScope, CDecl, AttrList); + SemaRef.AddPragmaAttributes(SemaRef.TUScope, CDecl); if (NumProtoRefs) { - diagnoseUseOfProtocols(*this, CDecl, (ObjCProtocolDecl*const*)ProtoRefs, + diagnoseUseOfProtocols(SemaRef, CDecl, (ObjCProtocolDecl*const*)ProtoRefs, NumProtoRefs, ProtoLocs); CDecl->setProtocolList((ObjCProtocolDecl*const*)ProtoRefs, NumProtoRefs, ProtoLocs, Context); @@ -1915,10 +1931,11 @@ ObjCCategoryDecl *Sema::ActOnStartCategoryInterface( /// ActOnStartCategoryImplementation - Perform semantic checks on the /// category implementation declaration and build an ObjCCategoryImplDecl /// object. -ObjCCategoryImplDecl *Sema::ActOnStartCategoryImplementation( +ObjCCategoryImplDecl *SemaObjC::ActOnStartCategoryImplementation( SourceLocation AtCatImplLoc, const IdentifierInfo *ClassName, SourceLocation ClassLoc, const IdentifierInfo *CatName, SourceLocation CatLoc, const ParsedAttributesView &Attrs) { + ASTContext &Context = getASTContext(); ObjCInterfaceDecl *IDecl = getObjCInterfaceDecl(ClassName, ClassLoc, true); ObjCCategoryDecl *CatIDecl = nullptr; if (IDecl && IDecl->hasDefinition()) { @@ -1926,7 +1943,7 @@ ObjCCategoryImplDecl *Sema::ActOnStartCategoryImplementation( if (!CatIDecl) { // Category @implementation with no corresponding @interface. // Create and install one. - CatIDecl = ObjCCategoryDecl::Create(Context, CurContext, AtCatImplLoc, + CatIDecl = ObjCCategoryDecl::Create(Context, SemaRef.CurContext, AtCatImplLoc, ClassLoc, CatLoc, CatName, IDecl, /*typeParamList=*/nullptr); @@ -1935,22 +1952,22 @@ ObjCCategoryImplDecl *Sema::ActOnStartCategoryImplementation( } ObjCCategoryImplDecl *CDecl = - ObjCCategoryImplDecl::Create(Context, CurContext, CatName, IDecl, + ObjCCategoryImplDecl::Create(Context, SemaRef.CurContext, CatName, IDecl, ClassLoc, AtCatImplLoc, CatLoc); /// Check that class of this category is already completely declared. if (!IDecl) { Diag(ClassLoc, diag::err_undef_interface) << ClassName; CDecl->setInvalidDecl(); - } else if (RequireCompleteType(ClassLoc, Context.getObjCInterfaceType(IDecl), + } else if (SemaRef.RequireCompleteType(ClassLoc, Context.getObjCInterfaceType(IDecl), diag::err_undef_interface)) { CDecl->setInvalidDecl(); } - ProcessDeclAttributeList(TUScope, CDecl, Attrs); - AddPragmaAttributes(TUScope, CDecl); + SemaRef.ProcessDeclAttributeList(SemaRef.TUScope, CDecl, Attrs); + SemaRef.AddPragmaAttributes(SemaRef.TUScope, CDecl); // FIXME: PushOnScopeChains? - CurContext->addDecl(CDecl); + SemaRef.CurContext->addDecl(CDecl); // If the interface has the objc_runtime_visible attribute, we // cannot implement a category for it. @@ -1971,7 +1988,7 @@ ObjCCategoryImplDecl *Sema::ActOnStartCategoryImplementation( CatIDecl->setImplementation(CDecl); // Warn on implementating category of deprecated class under // -Wdeprecated-implementations flag. - DiagnoseObjCImplementedDeprecations(*this, CatIDecl, + DiagnoseObjCImplementedDeprecations(SemaRef, CatIDecl, CDecl->getLocation()); } } @@ -1981,36 +1998,37 @@ ObjCCategoryImplDecl *Sema::ActOnStartCategoryImplementation( return CDecl; } -ObjCImplementationDecl *Sema::ActOnStartClassImplementation( +ObjCImplementationDecl *SemaObjC::ActOnStartClassImplementation( SourceLocation AtClassImplLoc, const IdentifierInfo *ClassName, SourceLocation ClassLoc, const IdentifierInfo *SuperClassname, SourceLocation SuperClassLoc, const ParsedAttributesView &Attrs) { + ASTContext &Context = getASTContext(); ObjCInterfaceDecl *IDecl = nullptr; // Check for another declaration kind with the same name. NamedDecl *PrevDecl - = LookupSingleName(TUScope, ClassName, ClassLoc, LookupOrdinaryName, - forRedeclarationInCurContext()); + = SemaRef.LookupSingleName(SemaRef.TUScope, ClassName, ClassLoc, Sema::LookupOrdinaryName, + SemaRef.forRedeclarationInCurContext()); if (PrevDecl && !isa(PrevDecl)) { Diag(ClassLoc, diag::err_redefinition_different_kind) << ClassName; Diag(PrevDecl->getLocation(), diag::note_previous_definition); } else if ((IDecl = dyn_cast_or_null(PrevDecl))) { // FIXME: This will produce an error if the definition of the interface has // been imported from a module but is not visible. - RequireCompleteType(ClassLoc, Context.getObjCInterfaceType(IDecl), + SemaRef.RequireCompleteType(ClassLoc, Context.getObjCInterfaceType(IDecl), diag::warn_undef_interface); } else { // We did not find anything with the name ClassName; try to correct for // typos in the class name. ObjCInterfaceValidatorCCC CCC{}; TypoCorrection Corrected = - CorrectTypo(DeclarationNameInfo(ClassName, ClassLoc), - LookupOrdinaryName, TUScope, nullptr, CCC, CTK_NonError); + SemaRef.CorrectTypo(DeclarationNameInfo(ClassName, ClassLoc), + Sema::LookupOrdinaryName, SemaRef.TUScope, nullptr, CCC, Sema::CTK_NonError); if (Corrected.getCorrectionDeclAs()) { // Suggest the (potentially) correct interface name. Don't provide a // code-modification hint or use the typo name for recovery, because // this is just a warning. The program may actually be correct. - diagnoseTypo(Corrected, - PDiag(diag::warn_undef_interface_suggest) << ClassName, + SemaRef.diagnoseTypo(Corrected, + SemaRef.PDiag(diag::warn_undef_interface_suggest) << ClassName, /*ErrorRecovery*/false); } else { Diag(ClassLoc, diag::warn_undef_interface) << ClassName; @@ -2021,8 +2039,8 @@ ObjCImplementationDecl *Sema::ActOnStartClassImplementation( ObjCInterfaceDecl *SDecl = nullptr; if (SuperClassname) { // Check if a different kind of symbol declared in this scope. - PrevDecl = LookupSingleName(TUScope, SuperClassname, SuperClassLoc, - LookupOrdinaryName); + PrevDecl = SemaRef.LookupSingleName(SemaRef.TUScope, SuperClassname, SuperClassLoc, + Sema::LookupOrdinaryName); if (PrevDecl && !isa(PrevDecl)) { Diag(SuperClassLoc, diag::err_redefinition_different_kind) << SuperClassname; @@ -2050,11 +2068,11 @@ ObjCImplementationDecl *Sema::ActOnStartClassImplementation( // FIXME: Do we support attributes on the @implementation? If so we should // copy them over. - IDecl = ObjCInterfaceDecl::Create(Context, CurContext, AtClassImplLoc, + IDecl = ObjCInterfaceDecl::Create(Context, SemaRef.CurContext, AtClassImplLoc, ClassName, /*typeParamList=*/nullptr, /*PrevDecl=*/nullptr, ClassLoc, true); - AddPragmaAttributes(TUScope, IDecl); + SemaRef.AddPragmaAttributes(SemaRef.TUScope, IDecl); IDecl->startDefinition(); if (SDecl) { IDecl->setSuperClass(Context.getTrivialTypeSourceInfo( @@ -2065,7 +2083,7 @@ ObjCImplementationDecl *Sema::ActOnStartClassImplementation( IDecl->setEndOfDefinitionLoc(ClassLoc); } - PushOnScopeChains(IDecl, TUScope); + SemaRef.PushOnScopeChains(IDecl, SemaRef.TUScope); } else { // Mark the interface as being completed, even if it was just as // @class ....; @@ -2075,11 +2093,11 @@ ObjCImplementationDecl *Sema::ActOnStartClassImplementation( } ObjCImplementationDecl* IMPDecl = - ObjCImplementationDecl::Create(Context, CurContext, IDecl, SDecl, + ObjCImplementationDecl::Create(Context, SemaRef.CurContext, IDecl, SDecl, ClassLoc, AtClassImplLoc, SuperClassLoc); - ProcessDeclAttributeList(TUScope, IMPDecl, Attrs); - AddPragmaAttributes(TUScope, IMPDecl); + SemaRef.ProcessDeclAttributeList(SemaRef.TUScope, IMPDecl, Attrs); + SemaRef.AddPragmaAttributes(SemaRef.TUScope, IMPDecl); if (CheckObjCDeclScope(IMPDecl)) { ActOnObjCContainerStartDefinition(IMPDecl); @@ -2095,10 +2113,10 @@ ObjCImplementationDecl *Sema::ActOnStartClassImplementation( IMPDecl->setInvalidDecl(); } else { // add it to the list. IDecl->setImplementation(IMPDecl); - PushOnScopeChains(IMPDecl, TUScope); + SemaRef.PushOnScopeChains(IMPDecl, SemaRef.TUScope); // Warn on implementating deprecated class under // -Wdeprecated-implementations flag. - DiagnoseObjCImplementedDeprecations(*this, IDecl, IMPDecl->getLocation()); + DiagnoseObjCImplementedDeprecations(SemaRef, IDecl, IMPDecl->getLocation()); } // If the superclass has the objc_runtime_visible attribute, we @@ -2114,8 +2132,8 @@ ObjCImplementationDecl *Sema::ActOnStartClassImplementation( return IMPDecl; } -Sema::DeclGroupPtrTy -Sema::ActOnFinishObjCImplementation(Decl *ObjCImpDecl, ArrayRef Decls) { +SemaObjC::DeclGroupPtrTy +SemaObjC::ActOnFinishObjCImplementation(Decl *ObjCImpDecl, ArrayRef Decls) { SmallVector DeclsInGroup; DeclsInGroup.reserve(Decls.size() + 1); @@ -2130,13 +2148,14 @@ Sema::ActOnFinishObjCImplementation(Decl *ObjCImpDecl, ArrayRef Decls) { DeclsInGroup.push_back(ObjCImpDecl); - return BuildDeclaratorGroup(DeclsInGroup); + return SemaRef.BuildDeclaratorGroup(DeclsInGroup); } -void Sema::CheckImplementationIvars(ObjCImplementationDecl *ImpDecl, +void SemaObjC::CheckImplementationIvars(ObjCImplementationDecl *ImpDecl, ObjCIvarDecl **ivars, unsigned numIvars, SourceLocation RBrace) { assert(ImpDecl && "missing implementation decl"); + ASTContext &Context = getASTContext(); ObjCInterfaceDecl* IDecl = ImpDecl->getClassInterface(); if (!IDecl) return; @@ -2152,7 +2171,7 @@ void Sema::CheckImplementationIvars(ObjCImplementationDecl *ImpDecl, // ObjCInterfaceDecl while in a 'non-fragile' runtime the ivar is // only in the ObjCImplementationDecl. In the non-fragile case the ivar // therefore also needs to be propagated to the ObjCInterfaceDecl. - if (!LangOpts.ObjCRuntime.isFragile()) + if (!getLangOpts().ObjCRuntime.isFragile()) IDecl->makeDeclVisibleInContext(ivars[i]); ImpDecl->addDecl(ivars[i]); } @@ -2164,7 +2183,7 @@ void Sema::CheckImplementationIvars(ObjCImplementationDecl *ImpDecl, return; assert(ivars && "missing @implementation ivars"); - if (LangOpts.ObjCRuntime.isNonFragile()) { + if (getLangOpts().ObjCRuntime.isNonFragile()) { if (ImpDecl->getSuperClass()) Diag(ImpDecl->getLocation(), diag::warn_on_superclass_use); for (unsigned i = 0; i < numIvars; i++) { @@ -2251,7 +2270,7 @@ static void WarnUndefinedMethod(Sema &S, ObjCImplDecl *Impl, // separate warnings. We will give that approach a try, as that // matches what we do with protocols. { - const Sema::SemaDiagnosticBuilder &B = S.Diag(Impl->getLocation(), DiagID); + const SemaBase::SemaDiagnosticBuilder &B = S.Diag(Impl->getLocation(), DiagID); B << method; if (NeededFor) B << NeededFor; @@ -2581,14 +2600,14 @@ static bool checkMethodFamilyMismatch(Sema &S, ObjCMethodDecl *impl, return true; } -void Sema::WarnConflictingTypedMethods(ObjCMethodDecl *ImpMethodDecl, +void SemaObjC::WarnConflictingTypedMethods(ObjCMethodDecl *ImpMethodDecl, ObjCMethodDecl *MethodDecl, bool IsProtocolMethodDecl) { if (getLangOpts().ObjCAutoRefCount && - checkMethodFamilyMismatch(*this, ImpMethodDecl, MethodDecl)) + checkMethodFamilyMismatch(SemaRef, ImpMethodDecl, MethodDecl)) return; - CheckMethodOverrideReturn(*this, ImpMethodDecl, MethodDecl, + CheckMethodOverrideReturn(SemaRef, ImpMethodDecl, MethodDecl, IsProtocolMethodDecl, false, true); @@ -2596,7 +2615,7 @@ void Sema::WarnConflictingTypedMethods(ObjCMethodDecl *ImpMethodDecl, IF = MethodDecl->param_begin(), EM = ImpMethodDecl->param_end(), EF = MethodDecl->param_end(); IM != EM && IF != EF; ++IM, ++IF) { - CheckMethodOverrideParam(*this, ImpMethodDecl, MethodDecl, *IM, *IF, + CheckMethodOverrideParam(SemaRef, ImpMethodDecl, MethodDecl, *IM, *IF, IsProtocolMethodDecl, false, true); } @@ -2607,11 +2626,11 @@ void Sema::WarnConflictingTypedMethods(ObjCMethodDecl *ImpMethodDecl, } } -void Sema::CheckConflictingOverridingMethod(ObjCMethodDecl *Method, +void SemaObjC::CheckConflictingOverridingMethod(ObjCMethodDecl *Method, ObjCMethodDecl *Overridden, bool IsProtocolMethodDecl) { - CheckMethodOverrideReturn(*this, Method, Overridden, + CheckMethodOverrideReturn(SemaRef, Method, Overridden, IsProtocolMethodDecl, true, true); @@ -2619,7 +2638,7 @@ void Sema::CheckConflictingOverridingMethod(ObjCMethodDecl *Method, IF = Overridden->param_begin(), EM = Method->param_end(), EF = Overridden->param_end(); IM != EM && IF != EF; ++IM, ++IF) { - CheckMethodOverrideParam(*this, Method, Overridden, *IM, *IF, + CheckMethodOverrideParam(SemaRef, Method, Overridden, *IM, *IF, IsProtocolMethodDecl, true, true); } @@ -2632,9 +2651,10 @@ void Sema::CheckConflictingOverridingMethod(ObjCMethodDecl *Method, /// WarnExactTypedMethods - This routine issues a warning if method /// implementation declaration matches exactly that of its declaration. -void Sema::WarnExactTypedMethods(ObjCMethodDecl *ImpMethodDecl, +void SemaObjC::WarnExactTypedMethods(ObjCMethodDecl *ImpMethodDecl, ObjCMethodDecl *MethodDecl, bool IsProtocolMethodDecl) { + ASTContext &Context = getASTContext(); // don't issue warning when protocol method is optional because primary // class is not required to implement it and it is safe for protocol // to implement it. @@ -2647,14 +2667,14 @@ void Sema::WarnExactTypedMethods(ObjCMethodDecl *ImpMethodDecl, MethodDecl->hasAttr()) return; - bool match = CheckMethodOverrideReturn(*this, ImpMethodDecl, MethodDecl, + bool match = CheckMethodOverrideReturn(SemaRef, ImpMethodDecl, MethodDecl, IsProtocolMethodDecl, false, false); if (match) for (ObjCMethodDecl::param_iterator IM = ImpMethodDecl->param_begin(), IF = MethodDecl->param_begin(), EM = ImpMethodDecl->param_end(), EF = MethodDecl->param_end(); IM != EM && IF != EF; ++IM, ++IF) { - match = CheckMethodOverrideParam(*this, ImpMethodDecl, MethodDecl, + match = CheckMethodOverrideParam(SemaRef, ImpMethodDecl, MethodDecl, *IM, *IF, IsProtocolMethodDecl, false, false); if (!match) @@ -2709,7 +2729,7 @@ static void findProtocolsWithExplicitImpls(const ObjCInterfaceDecl *Super, /// Declared in protocol, and those referenced by it. static void CheckProtocolMethodDefs( Sema &S, ObjCImplDecl *Impl, ObjCProtocolDecl *PDecl, bool &IncompleteImpl, - const Sema::SelectorSet &InsMap, const Sema::SelectorSet &ClsMap, + const SemaObjC::SelectorSet &InsMap, const SemaObjC::SelectorSet &ClsMap, ObjCContainerDecl *CDecl, LazyProtocolNameSet &ProtocolsExplictImpl) { ObjCCategoryDecl *C = dyn_cast(CDecl); ObjCInterfaceDecl *IDecl = C ? C->getClassInterface() @@ -2831,7 +2851,7 @@ static void CheckProtocolMethodDefs( /// MatchAllMethodDeclarations - Check methods declared in interface /// or protocol against those declared in their implementations. /// -void Sema::MatchAllMethodDeclarations(const SelectorSet &InsMap, +void SemaObjC::MatchAllMethodDeclarations(const SelectorSet &InsMap, const SelectorSet &ClsMap, SelectorSet &InsMapSeen, SelectorSet &ClsMapSeen, @@ -2848,7 +2868,7 @@ void Sema::MatchAllMethodDeclarations(const SelectorSet &InsMap, if (!I->isPropertyAccessor() && !InsMap.count(I->getSelector())) { if (ImmediateClass) - WarnUndefinedMethod(*this, IMPDecl, I, IncompleteImpl, + WarnUndefinedMethod(SemaRef, IMPDecl, I, IncompleteImpl, diag::warn_undef_method_impl); continue; } else { @@ -2878,7 +2898,7 @@ void Sema::MatchAllMethodDeclarations(const SelectorSet &InsMap, if (!I->isPropertyAccessor() && !ClsMap.count(I->getSelector())) { if (ImmediateClass) - WarnUndefinedMethod(*this, IMPDecl, I, IncompleteImpl, + WarnUndefinedMethod(SemaRef, IMPDecl, I, IncompleteImpl, diag::warn_undef_method_impl); } else { ObjCMethodDecl *ImpMethodDecl = @@ -2944,7 +2964,7 @@ void Sema::MatchAllMethodDeclarations(const SelectorSet &InsMap, /// CheckCategoryVsClassMethodMatches - Checks that methods implemented in /// category matches with those implemented in its primary class and /// warns each time an exact match is found. -void Sema::CheckCategoryVsClassMethodMatches( +void SemaObjC::CheckCategoryVsClassMethodMatches( ObjCCategoryImplDecl *CatIMPDecl) { // Get category's primary class. ObjCCategoryDecl *CatDecl = CatIMPDecl->getCategoryDecl(); @@ -2983,7 +3003,7 @@ void Sema::CheckCategoryVsClassMethodMatches( true /*WarnCategoryMethodImpl*/); } -void Sema::ImplMethodsVsClassMethods(Scope *S, ObjCImplDecl* IMPDecl, +void SemaObjC::ImplMethodsVsClassMethods(Scope *S, ObjCImplDecl* IMPDecl, ObjCContainerDecl* CDecl, bool IncompleteImpl) { SelectorSet InsMap; @@ -3010,8 +3030,8 @@ void Sema::ImplMethodsVsClassMethods(Scope *S, ObjCImplDecl* IMPDecl, // an implementation or 2) there is a @synthesize/@dynamic implementation // of the property in the @implementation. if (const ObjCInterfaceDecl *IDecl = dyn_cast(CDecl)) { - bool SynthesizeProperties = LangOpts.ObjCDefaultSynthProperties && - LangOpts.ObjCRuntime.isNonFragile() && + bool SynthesizeProperties = getLangOpts().ObjCDefaultSynthProperties && + getLangOpts().ObjCRuntime.isNonFragile() && !IDecl->isObjCRequiresPropertyDefs(); DiagnoseUnimplementedProperties(S, IMPDecl, CDecl, SynthesizeProperties); } @@ -3045,14 +3065,14 @@ void Sema::ImplMethodsVsClassMethods(Scope *S, ObjCImplDecl* IMPDecl, if (ObjCInterfaceDecl *I = dyn_cast (CDecl)) { for (auto *PI : I->all_referenced_protocols()) - CheckProtocolMethodDefs(*this, IMPDecl, PI, IncompleteImpl, InsMap, + CheckProtocolMethodDefs(SemaRef, IMPDecl, PI, IncompleteImpl, InsMap, ClsMap, I, ExplicitImplProtocols); } else if (ObjCCategoryDecl *C = dyn_cast(CDecl)) { // For extended class, unimplemented methods in its protocols will // be reported in the primary class. if (!C->IsClassExtension()) { for (auto *P : C->protocols()) - CheckProtocolMethodDefs(*this, IMPDecl, P, IncompleteImpl, InsMap, + CheckProtocolMethodDefs(SemaRef, IMPDecl, P, IncompleteImpl, InsMap, ClsMap, CDecl, ExplicitImplProtocols); DiagnoseUnimplementedProperties(S, IMPDecl, CDecl, /*SynthesizeProperties=*/false); @@ -3061,18 +3081,19 @@ void Sema::ImplMethodsVsClassMethods(Scope *S, ObjCImplDecl* IMPDecl, llvm_unreachable("invalid ObjCContainerDecl type."); } -Sema::DeclGroupPtrTy -Sema::ActOnForwardClassDeclaration(SourceLocation AtClassLoc, +SemaObjC::DeclGroupPtrTy +SemaObjC::ActOnForwardClassDeclaration(SourceLocation AtClassLoc, IdentifierInfo **IdentList, SourceLocation *IdentLocs, ArrayRef TypeParamLists, unsigned NumElts) { + ASTContext &Context = getASTContext(); SmallVector DeclsInGroup; for (unsigned i = 0; i != NumElts; ++i) { // Check for another declaration kind with the same name. NamedDecl *PrevDecl - = LookupSingleName(TUScope, IdentList[i], IdentLocs[i], - LookupOrdinaryName, forRedeclarationInCurContext()); + = SemaRef.LookupSingleName(SemaRef.TUScope, IdentList[i], IdentLocs[i], + Sema::LookupOrdinaryName, SemaRef.forRedeclarationInCurContext()); if (PrevDecl && !isa(PrevDecl)) { // GCC apparently allows the following idiom: // @@ -3127,7 +3148,7 @@ Sema::ActOnForwardClassDeclaration(SourceLocation AtClassLoc, if (ObjCTypeParamList *PrevTypeParams = PrevIDecl->getTypeParamList()) { // Check for consistency with the previous declaration. if (checkTypeParamListConsistency( - *this, PrevTypeParams, TypeParams, + SemaRef, PrevTypeParams, TypeParams, TypeParamListContext::ForwardDeclaration)) { TypeParams = nullptr; } @@ -3144,27 +3165,27 @@ Sema::ActOnForwardClassDeclaration(SourceLocation AtClassLoc, } ObjCInterfaceDecl *IDecl - = ObjCInterfaceDecl::Create(Context, CurContext, AtClassLoc, + = ObjCInterfaceDecl::Create(Context, SemaRef.CurContext, AtClassLoc, ClassName, TypeParams, PrevIDecl, IdentLocs[i]); IDecl->setAtEndRange(IdentLocs[i]); if (PrevIDecl) - mergeDeclAttributes(IDecl, PrevIDecl); + SemaRef.mergeDeclAttributes(IDecl, PrevIDecl); - PushOnScopeChains(IDecl, TUScope); + SemaRef.PushOnScopeChains(IDecl, SemaRef.TUScope); CheckObjCDeclScope(IDecl); DeclsInGroup.push_back(IDecl); } - return BuildDeclaratorGroup(DeclsInGroup); + return SemaRef.BuildDeclaratorGroup(DeclsInGroup); } static bool tryMatchRecordTypes(ASTContext &Context, - Sema::MethodMatchStrategy strategy, + SemaObjC::MethodMatchStrategy strategy, const Type *left, const Type *right); -static bool matchTypes(ASTContext &Context, Sema::MethodMatchStrategy strategy, +static bool matchTypes(ASTContext &Context, SemaObjC::MethodMatchStrategy strategy, QualType leftQT, QualType rightQT) { const Type *left = Context.getCanonicalType(leftQT).getUnqualifiedType().getTypePtr(); @@ -3174,7 +3195,7 @@ static bool matchTypes(ASTContext &Context, Sema::MethodMatchStrategy strategy, if (left == right) return true; // If we're doing a strict match, the types have to match exactly. - if (strategy == Sema::MMS_strict) return false; + if (strategy == SemaObjC::MMS_strict) return false; if (left->isIncompleteType() || right->isIncompleteType()) return false; @@ -3222,7 +3243,7 @@ static bool matchTypes(ASTContext &Context, Sema::MethodMatchStrategy strategy, } static bool tryMatchRecordTypes(ASTContext &Context, - Sema::MethodMatchStrategy strategy, + SemaObjC::MethodMatchStrategy strategy, const Type *lt, const Type *rt) { assert(lt && rt && lt != rt); @@ -3260,9 +3281,10 @@ static bool tryMatchRecordTypes(ASTContext &Context, /// MatchTwoMethodDeclarations - Checks that two methods have matching type and /// returns true, or false, accordingly. /// TODO: Handle protocol list; such as id in type comparisons -bool Sema::MatchTwoMethodDeclarations(const ObjCMethodDecl *left, +bool SemaObjC::MatchTwoMethodDeclarations(const ObjCMethodDecl *left, const ObjCMethodDecl *right, MethodMatchStrategy strategy) { + ASTContext &Context = getASTContext(); if (!matchTypes(Context, strategy, left->getReturnType(), right->getReturnType())) return false; @@ -3319,7 +3341,7 @@ static bool isMethodContextSameForKindofLookup(ObjCMethodDecl *Method, return MethodInterface == MethodInListInterface; } -void Sema::addMethodToGlobalList(ObjCMethodList *List, +void SemaObjC::addMethodToGlobalList(ObjCMethodList *List, ObjCMethodDecl *Method) { // Record at the head of the list whether there were 0, 1, or >= 2 methods // inside categories. @@ -3408,7 +3430,7 @@ void Sema::addMethodToGlobalList(ObjCMethodList *List, // We have a new signature for an existing method - add it. // This is extremely rare. Only 1% of Cocoa selectors are "overloaded". - ObjCMethodList *Mem = BumpAlloc.Allocate(); + ObjCMethodList *Mem = SemaRef.BumpAlloc.Allocate(); // We insert it right before ListWithSameDeclaration. if (ListWithSameDeclaration) { @@ -3424,24 +3446,24 @@ void Sema::addMethodToGlobalList(ObjCMethodList *List, /// Read the contents of the method pool for a given selector from /// external storage. -void Sema::ReadMethodPool(Selector Sel) { - assert(ExternalSource && "We need an external AST source"); - ExternalSource->ReadMethodPool(Sel); +void SemaObjC::ReadMethodPool(Selector Sel) { + assert(SemaRef.ExternalSource && "We need an external AST source"); + SemaRef.ExternalSource->ReadMethodPool(Sel); } -void Sema::updateOutOfDateSelector(Selector Sel) { - if (!ExternalSource) +void SemaObjC::updateOutOfDateSelector(Selector Sel) { + if (!SemaRef.ExternalSource) return; - ExternalSource->updateOutOfDateSelector(Sel); + SemaRef.ExternalSource->updateOutOfDateSelector(Sel); } -void Sema::AddMethodToGlobalPool(ObjCMethodDecl *Method, bool impl, +void SemaObjC::AddMethodToGlobalPool(ObjCMethodDecl *Method, bool impl, bool instance) { // Ignore methods of invalid containers. if (cast(Method->getDeclContext())->isInvalidDecl()) return; - if (ExternalSource) + if (SemaRef.ExternalSource) ReadMethodPool(Method->getSelector()); GlobalMethodPool::iterator Pos = MethodPool.find(Method->getSelector()); @@ -3514,11 +3536,11 @@ static bool FilterMethodsByTypeBound(ObjCMethodDecl *Method, /// We first select the type of the method: Instance or Factory, then collect /// all methods with that type. -bool Sema::CollectMultipleMethodsInGlobalPool( +bool SemaObjC::CollectMultipleMethodsInGlobalPool( Selector Sel, SmallVectorImpl &Methods, bool InstanceFirst, bool CheckTheOther, const ObjCObjectType *TypeBound) { - if (ExternalSource) + if (SemaRef.ExternalSource) ReadMethodPool(Sel); GlobalMethodPool::iterator Pos = MethodPool.find(Sel); @@ -3553,7 +3575,7 @@ bool Sema::CollectMultipleMethodsInGlobalPool( return Methods.size() > 1; } -bool Sema::AreMultipleMethodsInGlobalPool( +bool SemaObjC::AreMultipleMethodsInGlobalPool( Selector Sel, ObjCMethodDecl *BestMethod, SourceRange R, bool receiverIdOrClass, SmallVectorImpl &Methods) { // Diagnose finding more than one method in global pool. @@ -3578,10 +3600,10 @@ bool Sema::AreMultipleMethodsInGlobalPool( return MethList.hasMoreThanOneDecl(); } -ObjCMethodDecl *Sema::LookupMethodInGlobalPool(Selector Sel, SourceRange R, +ObjCMethodDecl *SemaObjC::LookupMethodInGlobalPool(Selector Sel, SourceRange R, bool receiverIdOrClass, bool instance) { - if (ExternalSource) + if (SemaRef.ExternalSource) ReadMethodPool(Sel); GlobalMethodPool::iterator Pos = MethodPool.find(Sel); @@ -3598,7 +3620,7 @@ ObjCMethodDecl *Sema::LookupMethodInGlobalPool(Selector Sel, SourceRange R, return nullptr; } -void Sema::DiagnoseMultipleMethodInGlobalPool(SmallVectorImpl &Methods, +void SemaObjC::DiagnoseMultipleMethodInGlobalPool(SmallVectorImpl &Methods, Selector Sel, SourceRange R, bool receiverIdOrClass) { // We found multiple methods, so we may have to complain. @@ -3608,7 +3630,7 @@ void Sema::DiagnoseMultipleMethodInGlobalPool(SmallVectorImpl & // method signature. bool strictSelectorMatch = receiverIdOrClass && - !Diags.isIgnored(diag::warn_strict_multiple_method_decl, R.getBegin()); + !getDiagnostics().isIgnored(diag::warn_strict_multiple_method_decl, R.getBegin()); if (strictSelectorMatch) { for (unsigned I = 1, N = Methods.size(); I != N; ++I) { if (!MatchTwoMethodDeclarations(Methods[0], Methods[I], MMS_strict)) { @@ -3652,7 +3674,7 @@ void Sema::DiagnoseMultipleMethodInGlobalPool(SmallVectorImpl & } } -ObjCMethodDecl *Sema::LookupImplementedMethodInGlobalPool(Selector Sel) { +ObjCMethodDecl *SemaObjC::LookupImplementedMethodInGlobalPool(Selector Sel) { GlobalMethodPool::iterator Pos = MethodPool.find(Sel); if (Pos == MethodPool.end()) return nullptr; @@ -3701,14 +3723,14 @@ static bool HelperIsMethodInObjCType(Sema &S, Selector Sel, QualType ObjectType) { if (ObjectType.isNull()) return true; - if (S.LookupMethodInObjectType(Sel, ObjectType, true/*Instance method*/)) + if (S.ObjC().LookupMethodInObjectType(Sel, ObjectType, true/*Instance method*/)) return true; - return S.LookupMethodInObjectType(Sel, ObjectType, false/*Class method*/) != + return S.ObjC().LookupMethodInObjectType(Sel, ObjectType, false/*Class method*/) != nullptr; } const ObjCMethodDecl * -Sema::SelectorsForTypoCorrection(Selector Sel, +SemaObjC::SelectorsForTypoCorrection(Selector Sel, QualType ObjectType) { unsigned NumArgs = Sel.getNumArgs(); SmallVector Methods; @@ -3739,7 +3761,7 @@ Sema::SelectorsForTypoCorrection(Selector Sel, if (ObjectIsId) Methods.push_back(M->getMethod()); else if (!ObjectIsClass && - HelperIsMethodInObjCType(*this, M->getMethod()->getSelector(), + HelperIsMethodInObjCType(SemaRef, M->getMethod()->getSelector(), ObjectType)) Methods.push_back(M->getMethod()); } @@ -3751,7 +3773,7 @@ Sema::SelectorsForTypoCorrection(Selector Sel, if (ObjectIsClass) Methods.push_back(M->getMethod()); else if (!ObjectIsId && - HelperIsMethodInObjCType(*this, M->getMethod()->getSelector(), + HelperIsMethodInObjCType(SemaRef, M->getMethod()->getSelector(), ObjectType)) Methods.push_back(M->getMethod()); } @@ -3770,7 +3792,7 @@ Sema::SelectorsForTypoCorrection(Selector Sel, /// \@implementation. This becomes necessary because class extension can /// add ivars to a class in random order which will not be known until /// class's \@implementation is seen. -void Sema::DiagnoseDuplicateIvars(ObjCInterfaceDecl *ID, +void SemaObjC::DiagnoseDuplicateIvars(ObjCInterfaceDecl *ID, ObjCInterfaceDecl *SID) { for (auto *Ivar : ID->ivars()) { if (Ivar->isInvalidDecl()) @@ -3823,23 +3845,23 @@ static void DiagnoseRetainableFlexibleArrayMember(Sema &S, } } -Sema::ObjCContainerKind Sema::getObjCContainerKind() const { - switch (CurContext->getDeclKind()) { +SemaObjC::ObjCContainerKind SemaObjC::getObjCContainerKind() const { + switch (SemaRef.CurContext->getDeclKind()) { case Decl::ObjCInterface: - return Sema::OCK_Interface; + return SemaObjC::OCK_Interface; case Decl::ObjCProtocol: - return Sema::OCK_Protocol; + return SemaObjC::OCK_Protocol; case Decl::ObjCCategory: - if (cast(CurContext)->IsClassExtension()) - return Sema::OCK_ClassExtension; - return Sema::OCK_Category; + if (cast(SemaRef.CurContext)->IsClassExtension()) + return SemaObjC::OCK_ClassExtension; + return SemaObjC::OCK_Category; case Decl::ObjCImplementation: - return Sema::OCK_Implementation; + return SemaObjC::OCK_Implementation; case Decl::ObjCCategoryImpl: - return Sema::OCK_CategoryImplementation; + return SemaObjC::OCK_CategoryImplementation; default: - return Sema::OCK_None; + return SemaObjC::OCK_None; } } @@ -3983,14 +4005,15 @@ static void DiagnoseCategoryDirectMembersProtocolConformance( } // Note: For class/category implementations, allMethods is always null. -Decl *Sema::ActOnAtEnd(Scope *S, SourceRange AtEnd, ArrayRef allMethods, +Decl *SemaObjC::ActOnAtEnd(Scope *S, SourceRange AtEnd, ArrayRef allMethods, ArrayRef allTUVars) { - if (getObjCContainerKind() == Sema::OCK_None) + ASTContext &Context = getASTContext(); + if (getObjCContainerKind() == SemaObjC::OCK_None) return nullptr; assert(AtEnd.isValid() && "Invalid location for '@end'"); - auto *OCD = cast(CurContext); + auto *OCD = cast(SemaRef.CurContext); Decl *ClassDecl = OCD; bool isInterfaceDeclKind = @@ -4002,7 +4025,7 @@ Decl *Sema::ActOnAtEnd(Scope *S, SourceRange AtEnd, ArrayRef allMethods, // ActOnPropertyImplDecl() creates them as not visible in case // they are overridden by an explicit method that is encountered // later. - if (auto *OID = dyn_cast(CurContext)) { + if (auto *OID = dyn_cast(SemaRef.CurContext)) { for (auto *PropImpl : OID->property_impls()) { if (auto *Getter = PropImpl->getGetterMethodDecl()) if (Getter->isSynthesizedAccessorStub()) @@ -4083,7 +4106,7 @@ Decl *Sema::ActOnAtEnd(Scope *S, SourceRange AtEnd, ArrayRef allMethods, DiagnoseClassExtensionDupMethods(C, CCPrimary); } - DiagnoseCategoryDirectMembersProtocolConformance(*this, C, C->protocols()); + DiagnoseCategoryDirectMembersProtocolConformance(SemaRef, C, C->protocols()); } if (ObjCContainerDecl *CDecl = dyn_cast(ClassDecl)) { if (CDecl->getIdentifier()) @@ -4129,8 +4152,8 @@ Decl *Sema::ActOnAtEnd(Scope *S, SourceRange AtEnd, ArrayRef allMethods, DiagnoseUnusedBackingIvarInAccessor(S, IC); if (IDecl->hasDesignatedInitializers()) DiagnoseMissingDesignatedInitOverrides(IC, IDecl); - DiagnoseWeakIvars(*this, IC); - DiagnoseRetainableFlexibleArrayMember(*this, IDecl); + DiagnoseWeakIvars(SemaRef, IC); + DiagnoseRetainableFlexibleArrayMember(SemaRef, IDecl); bool HasRootClassAttr = IDecl->hasAttr(); if (IDecl->getSuperClass() == nullptr) { @@ -4138,14 +4161,14 @@ Decl *Sema::ActOnAtEnd(Scope *S, SourceRange AtEnd, ArrayRef allMethods, // __attribute((objc_root_class)). if (!HasRootClassAttr) { SourceLocation DeclLoc(IDecl->getLocation()); - SourceLocation SuperClassLoc(getLocForEndOfToken(DeclLoc)); + SourceLocation SuperClassLoc(SemaRef.getLocForEndOfToken(DeclLoc)); Diag(DeclLoc, diag::warn_objc_root_class_missing) << IDecl->getIdentifier(); // See if NSObject is in the current scope, and if it is, suggest // adding " : NSObject " to the class declaration. - NamedDecl *IF = LookupSingleName(TUScope, + NamedDecl *IF = SemaRef.LookupSingleName(SemaRef.TUScope, NSAPIObj->getNSClassId(NSAPI::ClassId_NSObject), - DeclLoc, LookupOrdinaryName); + DeclLoc, Sema::LookupOrdinaryName); ObjCInterfaceDecl *NSObjectDecl = dyn_cast_or_null(IF); if (NSObjectDecl && NSObjectDecl->getDefinition()) { Diag(SuperClassLoc, diag::note_objc_needs_superclass) @@ -4174,7 +4197,7 @@ Decl *Sema::ActOnAtEnd(Scope *S, SourceRange AtEnd, ArrayRef allMethods, if (IDecl->hasAttr()) Diag(IC->getLocation(), diag::err_implementation_of_class_stub); - if (LangOpts.ObjCRuntime.isNonFragile()) { + if (getLangOpts().ObjCRuntime.isNonFragile()) { while (IDecl->getSuperClass()) { DiagnoseDuplicateIvars(IDecl, IDecl->getSuperClass()); IDecl = IDecl->getSuperClass(); @@ -4207,7 +4230,7 @@ Decl *Sema::ActOnAtEnd(Scope *S, SourceRange AtEnd, ArrayRef allMethods, !IntfDecl->hasAttr()) Diag(IntfDecl->getLocation(), diag::err_class_stub_subclassing_mismatch); } - DiagnoseVariableSizedIvars(*this, OCD); + DiagnoseVariableSizedIvars(SemaRef, OCD); if (isInterfaceDeclKind) { // Reject invalid vardecls. for (unsigned i = 0, e = allTUVars.size(); i != e; i++) { @@ -4225,10 +4248,10 @@ Decl *Sema::ActOnAtEnd(Scope *S, SourceRange AtEnd, ArrayRef allMethods, DeclGroupRef DG = allTUVars[i].get(); for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I) (*I)->setTopLevelDeclInObjCContainer(); - Consumer.HandleTopLevelDeclInObjCContainer(DG); + SemaRef.Consumer.HandleTopLevelDeclInObjCContainer(DG); } - ActOnDocumentableDecl(ClassDecl); + SemaRef.ActOnDocumentableDecl(ClassDecl); return ClassDecl; } @@ -4242,7 +4265,7 @@ CvtQTToAstBitMask(ObjCDeclSpec::ObjCDeclQualifier PQTVal) { /// Check whether the declared result type of the given Objective-C /// method declaration is compatible with the method's class. /// -static Sema::ResultTypeCompatibilityKind +static SemaObjC::ResultTypeCompatibilityKind CheckRelatedResultTypeCompatibility(Sema &S, ObjCMethodDecl *Method, ObjCInterfaceDecl *CurrentClass) { QualType ResultType = Method->getReturnType(); @@ -4255,27 +4278,27 @@ CheckRelatedResultTypeCompatibility(Sema &S, ObjCMethodDecl *Method, // - it is id or qualified id, or if (ResultObjectType->isObjCIdType() || ResultObjectType->isObjCQualifiedIdType()) - return Sema::RTC_Compatible; + return SemaObjC::RTC_Compatible; if (CurrentClass) { if (ObjCInterfaceDecl *ResultClass = ResultObjectType->getInterfaceDecl()) { // - it is the same as the method's class type, or if (declaresSameEntity(CurrentClass, ResultClass)) - return Sema::RTC_Compatible; + return SemaObjC::RTC_Compatible; // - it is a superclass of the method's class type if (ResultClass->isSuperClassOf(CurrentClass)) - return Sema::RTC_Compatible; + return SemaObjC::RTC_Compatible; } } else { // Any Objective-C pointer type might be acceptable for a protocol // method; we just don't know. - return Sema::RTC_Unknown; + return SemaObjC::RTC_Unknown; } } - return Sema::RTC_Incompatible; + return SemaObjC::RTC_Incompatible; } namespace { @@ -4293,13 +4316,13 @@ class OverrideSearch { // Bypass this search if we've never seen an instance/class method // with this selector before. - Sema::GlobalMethodPool::iterator it = S.MethodPool.find(selector); - if (it == S.MethodPool.end()) { + SemaObjC::GlobalMethodPool::iterator it = S.ObjC().MethodPool.find(selector); + if (it == S.ObjC().MethodPool.end()) { if (!S.getExternalSource()) return; - S.ReadMethodPool(selector); + S.ObjC().ReadMethodPool(selector); - it = S.MethodPool.find(selector); - if (it == S.MethodPool.end()) + it = S.ObjC().MethodPool.find(selector); + if (it == S.ObjC().MethodPool.end()) return; } const ObjCMethodList &list = @@ -4426,7 +4449,7 @@ class OverrideSearch { }; } // end anonymous namespace -void Sema::CheckObjCMethodDirectOverrides(ObjCMethodDecl *method, +void SemaObjC::CheckObjCMethodDirectOverrides(ObjCMethodDecl *method, ObjCMethodDecl *overridden) { if (overridden->isDirectMethod()) { const auto *attr = overridden->getAttr(); @@ -4440,9 +4463,10 @@ void Sema::CheckObjCMethodDirectOverrides(ObjCMethodDecl *method, } } -void Sema::CheckObjCMethodOverrides(ObjCMethodDecl *ObjCMethod, +void SemaObjC::CheckObjCMethodOverrides(ObjCMethodDecl *ObjCMethod, ObjCInterfaceDecl *CurrentClass, ResultTypeCompatibilityKind RTC) { + ASTContext &Context = getASTContext(); if (!ObjCMethod) return; auto IsMethodInCurrentClass = [CurrentClass](const ObjCMethodDecl *M) { @@ -4451,7 +4475,7 @@ void Sema::CheckObjCMethodOverrides(ObjCMethodDecl *ObjCMethod, CurrentClass->getCanonicalDecl(); }; // Search for overridden methods and merge information down from them. - OverrideSearch overrides(*this, ObjCMethod); + OverrideSearch overrides(SemaRef, ObjCMethod); // Keep track if the method overrides any method in the class's base classes, // its protocols, or its categories' protocols; we will keep that info // in the ObjCMethodDecl. @@ -4483,7 +4507,7 @@ void Sema::CheckObjCMethodOverrides(ObjCMethodDecl *ObjCMethod, // least 2 category methods recorded, otherwise only one will do. if (CategCount > 1 || !isa(overridden->getDeclContext())) { - OverrideSearch overrides(*this, overridden); + OverrideSearch overrides(SemaRef, overridden); for (ObjCMethodDecl *SuperOverridden : overrides) { if (isa(SuperOverridden->getDeclContext()) || !IsMethodInCurrentClass(SuperOverridden)) { @@ -4500,11 +4524,11 @@ void Sema::CheckObjCMethodOverrides(ObjCMethodDecl *ObjCMethod, } // Propagate down the 'related result type' bit from overridden methods. - if (RTC != Sema::RTC_Incompatible && overridden->hasRelatedResultType()) + if (RTC != SemaObjC::RTC_Incompatible && overridden->hasRelatedResultType()) ObjCMethod->setRelatedResultType(); // Then merge the declarations. - mergeObjCMethodDecls(ObjCMethod, overridden); + SemaRef.mergeObjCMethodDecls(ObjCMethod, overridden); if (ObjCMethod->isImplicit() && overridden->isImplicit()) continue; // Conflicting properties are detected elsewhere. @@ -4723,7 +4747,7 @@ static void checkObjCDirectMethodClashes(Sema &S, ObjCInterfaceDecl *IDecl, diagClash(IMD); } -Decl *Sema::ActOnMethodDeclaration( +Decl *SemaObjC::ActOnMethodDeclaration( Scope *S, SourceLocation MethodLoc, SourceLocation EndLoc, tok::TokenKind MethodType, ObjCDeclSpec &ReturnQT, ParsedType ReturnType, ArrayRef SelectorLocs, Selector Sel, @@ -4733,21 +4757,22 @@ Decl *Sema::ActOnMethodDeclaration( unsigned CNumArgs, // c-style args const ParsedAttributesView &AttrList, tok::ObjCKeywordKind MethodDeclKind, bool isVariadic, bool MethodDefinition) { + ASTContext &Context = getASTContext(); // Make sure we can establish a context for the method. - if (!CurContext->isObjCContainer()) { + if (!SemaRef.CurContext->isObjCContainer()) { Diag(MethodLoc, diag::err_missing_method_context); return nullptr; } - Decl *ClassDecl = cast(CurContext); + Decl *ClassDecl = cast(SemaRef.CurContext); QualType resultDeclType; bool HasRelatedResultType = false; TypeSourceInfo *ReturnTInfo = nullptr; if (ReturnType) { - resultDeclType = GetTypeFromParser(ReturnType, &ReturnTInfo); + resultDeclType = SemaRef.GetTypeFromParser(ReturnType, &ReturnTInfo); - if (CheckFunctionReturnType(resultDeclType, MethodLoc)) + if (SemaRef.CheckFunctionReturnType(resultDeclType, MethodLoc)) return nullptr; QualType bareResultType = resultDeclType; @@ -4760,7 +4785,7 @@ Decl *Sema::ActOnMethodDeclaration( } ObjCMethodDecl *ObjCMethod = ObjCMethodDecl::Create( - Context, MethodLoc, EndLoc, Sel, resultDeclType, ReturnTInfo, CurContext, + Context, MethodLoc, EndLoc, Sel, resultDeclType, ReturnTInfo, SemaRef.CurContext, MethodType == tok::minus, isVariadic, /*isPropertyAccessor=*/false, /*isSynthesizedAccessorStub=*/false, /*isImplicitlyDeclared=*/false, /*isDefined=*/false, @@ -4779,12 +4804,12 @@ Decl *Sema::ActOnMethodDeclaration( ArgType = Context.getObjCIdType(); DI = nullptr; } else { - ArgType = GetTypeFromParser(ArgInfo[i].Type, &DI); + ArgType = SemaRef.GetTypeFromParser(ArgInfo[i].Type, &DI); } - LookupResult R(*this, ArgInfo[i].Name, ArgInfo[i].NameLoc, - LookupOrdinaryName, forRedeclarationInCurContext()); - LookupName(R, S); + LookupResult R(SemaRef, ArgInfo[i].Name, ArgInfo[i].NameLoc, + Sema::LookupOrdinaryName, SemaRef.forRedeclarationInCurContext()); + SemaRef.LookupName(R, S); if (R.isSingleResult()) { NamedDecl *PrevDecl = R.getFoundDecl(); if (S->isDeclScope(PrevDecl)) { @@ -4801,7 +4826,7 @@ Decl *Sema::ActOnMethodDeclaration( ? DI->getTypeLoc().getBeginLoc() : ArgInfo[i].NameLoc; - ParmVarDecl* Param = CheckParameter(ObjCMethod, StartLoc, + ParmVarDecl* Param = SemaRef.CheckParameter(ObjCMethod, StartLoc, ArgInfo[i].NameLoc, ArgInfo[i].Name, ArgType, DI, SC_None); @@ -4811,16 +4836,16 @@ Decl *Sema::ActOnMethodDeclaration( CvtQTToAstBitMask(ArgInfo[i].DeclSpec.getObjCDeclQualifier())); // Apply the attributes to the parameter. - ProcessDeclAttributeList(TUScope, Param, ArgInfo[i].ArgAttrs); - AddPragmaAttributes(TUScope, Param); - ProcessAPINotes(Param); + SemaRef.ProcessDeclAttributeList(SemaRef.TUScope, Param, ArgInfo[i].ArgAttrs); + SemaRef.AddPragmaAttributes(SemaRef.TUScope, Param); + SemaRef.ProcessAPINotes(Param); if (Param->hasAttr()) { Diag(Param->getLocation(), diag::err_block_on_nonlocal); Param->setInvalidDecl(); } S->AddDecl(Param); - IdResolver.AddDecl(Param); + SemaRef.IdResolver.AddDecl(Param); Params.push_back(Param); } @@ -4842,9 +4867,9 @@ Decl *Sema::ActOnMethodDeclaration( ObjCMethod->setObjCDeclQualifier( CvtQTToAstBitMask(ReturnQT.getObjCDeclQualifier())); - ProcessDeclAttributeList(TUScope, ObjCMethod, AttrList); - AddPragmaAttributes(TUScope, ObjCMethod); - ProcessAPINotes(ObjCMethod); + SemaRef.ProcessDeclAttributeList(SemaRef.TUScope, ObjCMethod, AttrList); + SemaRef.AddPragmaAttributes(SemaRef.TUScope, ObjCMethod); + SemaRef.ProcessAPINotes(ObjCMethod); // Add the method now. const ObjCMethodDecl *PrevMethod = nullptr; @@ -4898,7 +4923,7 @@ Decl *Sema::ActOnMethodDeclaration( if (ObjCInterfaceDecl *IDecl = ImpDecl->getClassInterface()) { if (auto *IMD = IDecl->lookupMethod(ObjCMethod->getSelector(), ObjCMethod->isInstanceMethod())) { - mergeInterfaceMethodToImpl(*this, ObjCMethod, IMD); + mergeInterfaceMethodToImpl(SemaRef, ObjCMethod, IMD); // The Idecl->lookupMethod() above will find declarations for ObjCMethod // in one of these places: @@ -4958,8 +4983,8 @@ Decl *Sema::ActOnMethodDeclaration( << ObjCMethod->getDeclName(); } } else { - mergeObjCDirectMembers(*this, ClassDecl, ObjCMethod); - checkObjCDirectMethodClashes(*this, IDecl, ObjCMethod, ImpDecl); + mergeObjCDirectMembers(SemaRef, ClassDecl, ObjCMethod); + checkObjCDirectMethodClashes(SemaRef, IDecl, ObjCMethod, ImpDecl); } // Warn if a method declared in a protocol to which a category or @@ -4975,12 +5000,12 @@ Decl *Sema::ActOnMethodDeclaration( auto OI = IMD->param_begin(), OE = IMD->param_end(); auto NI = ObjCMethod->param_begin(); for (; OI != OE; ++OI, ++NI) - diagnoseNoescape(*NI, *OI, C, P, *this); + diagnoseNoescape(*NI, *OI, C, P, SemaRef); } } } else { if (!isa(ClassDecl)) { - mergeObjCDirectMembers(*this, ClassDecl, ObjCMethod); + mergeObjCDirectMembers(SemaRef, ClassDecl, ObjCMethod); ObjCInterfaceDecl *IDecl = dyn_cast(ClassDecl); if (!IDecl) @@ -4989,7 +5014,7 @@ Decl *Sema::ActOnMethodDeclaration( // declaration by now, however for invalid code we'll keep parsing // but we won't find the primary interface and IDecl will be nil. if (IDecl) - checkObjCDirectMethodClashes(*this, IDecl, ObjCMethod); + checkObjCDirectMethodClashes(SemaRef, IDecl, ObjCMethod); } cast(ClassDecl)->addDecl(ObjCMethod); @@ -5019,7 +5044,7 @@ Decl *Sema::ActOnMethodDeclaration( } ResultTypeCompatibilityKind RTC - = CheckRelatedResultTypeCompatibility(*this, ObjCMethod, CurrentClass); + = CheckRelatedResultTypeCompatibility(SemaRef, ObjCMethod, CurrentClass); CheckObjCMethodOverrides(ObjCMethod, CurrentClass, RTC); @@ -5028,9 +5053,9 @@ Decl *Sema::ActOnMethodDeclaration( ARCError = CheckARCMethodDecl(ObjCMethod); // Infer the related result type when possible. - if (!ARCError && RTC == Sema::RTC_Compatible && + if (!ARCError && RTC == SemaObjC::RTC_Compatible && !ObjCMethod->hasRelatedResultType() && - LangOpts.ObjCInferRelatedResultType) { + getLangOpts().ObjCInferRelatedResultType) { bool InferRelatedResultType = false; switch (ObjCMethod->getMethodFamily()) { case OMF_None: @@ -5064,7 +5089,7 @@ Decl *Sema::ActOnMethodDeclaration( if (MethodDefinition && Context.getTargetInfo().getTriple().getArch() == llvm::Triple::x86) - checkObjCMethodX86VectorTypes(*this, ObjCMethod); + checkObjCMethodX86VectorTypes(SemaRef, ObjCMethod); // + load method cannot have availability attributes. It get called on // startup, so it has to have the availability of the deployment target. @@ -5080,20 +5105,20 @@ Decl *Sema::ActOnMethodDeclaration( // Insert the invisible arguments, self and _cmd! ObjCMethod->createImplicitParams(Context, ObjCMethod->getClassInterface()); - ActOnDocumentableDecl(ObjCMethod); + SemaRef.ActOnDocumentableDecl(ObjCMethod); return ObjCMethod; } -bool Sema::CheckObjCDeclScope(Decl *D) { +bool SemaObjC::CheckObjCDeclScope(Decl *D) { // Following is also an error. But it is caused by a missing @end // and diagnostic is issued elsewhere. - if (isa(CurContext->getRedeclContext())) + if (isa(SemaRef.CurContext->getRedeclContext())) return false; // If we switched context to translation unit while we are still lexically in // an objc container, it means the parser missed emitting an error. - if (isa(getCurLexicalContext()->getRedeclContext())) + if (isa(SemaRef.getCurLexicalContext()->getRedeclContext())) return false; Diag(D->getLocation(), diag::err_objc_decls_may_only_appear_in_global_scope); @@ -5104,16 +5129,17 @@ bool Sema::CheckObjCDeclScope(Decl *D) { /// Called whenever \@defs(ClassName) is encountered in the source. Inserts the /// instance variables of ClassName into Decls. -void Sema::ActOnDefs(Scope *S, Decl *TagD, SourceLocation DeclStart, +void SemaObjC::ActOnDefs(Scope *S, Decl *TagD, SourceLocation DeclStart, const IdentifierInfo *ClassName, SmallVectorImpl &Decls) { + ASTContext &Context = getASTContext(); // Check that ClassName is a valid class ObjCInterfaceDecl *Class = getObjCInterfaceDecl(ClassName, DeclStart); if (!Class) { Diag(DeclStart, diag::err_undef_interface) << ClassName; return; } - if (LangOpts.ObjCRuntime.isNonFragile()) { + if (getLangOpts().ObjCRuntime.isNonFragile()) { Diag(DeclStart, diag::err_atdef_nonfragile_interface); return; } @@ -5138,17 +5164,18 @@ void Sema::ActOnDefs(Scope *S, Decl *TagD, SourceLocation DeclStart, D != Decls.end(); ++D) { FieldDecl *FD = cast(*D); if (getLangOpts().CPlusPlus) - PushOnScopeChains(FD, S); + SemaRef.PushOnScopeChains(FD, S); else if (RecordDecl *Record = dyn_cast(TagD)) Record->addDecl(FD); } } /// Build a type-check a new Objective-C exception variable declaration. -VarDecl *Sema::BuildObjCExceptionDecl(TypeSourceInfo *TInfo, QualType T, +VarDecl *SemaObjC::BuildObjCExceptionDecl(TypeSourceInfo *TInfo, QualType T, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, bool Invalid) { + ASTContext &Context = getASTContext(); // ISO/IEC TR 18037 S6.7.3: "The type of an object with automatic storage // duration shall not be qualified by an address-space qualifier." // Since all parameters have automatic store duration, they can not have @@ -5177,7 +5204,7 @@ VarDecl *Sema::BuildObjCExceptionDecl(TypeSourceInfo *TInfo, QualType T, Diag(IdLoc, diag::err_catch_param_not_objc_type); } - VarDecl *New = VarDecl::Create(Context, CurContext, StartLoc, IdLoc, Id, + VarDecl *New = VarDecl::Create(Context, SemaRef.CurContext, StartLoc, IdLoc, Id, T, TInfo, SC_None); New->setExceptionVariable(true); @@ -5190,7 +5217,7 @@ VarDecl *Sema::BuildObjCExceptionDecl(TypeSourceInfo *TInfo, QualType T, return New; } -Decl *Sema::ActOnObjCExceptionDecl(Scope *S, Declarator &D) { +Decl *SemaObjC::ActOnObjCExceptionDecl(Scope *S, Declarator &D) { const DeclSpec &DS = D.getDeclSpec(); // We allow the "register" storage class on exception variables because @@ -5211,14 +5238,14 @@ Decl *Sema::ActOnObjCExceptionDecl(Scope *S, Declarator &D) { << DeclSpec::getSpecifierName(TSCS); D.getMutableDeclSpec().ClearStorageClassSpecs(); - DiagnoseFunctionSpecifiers(D.getDeclSpec()); + SemaRef.DiagnoseFunctionSpecifiers(D.getDeclSpec()); // Check that there are no default arguments inside the type of this // exception object (C++ only). if (getLangOpts().CPlusPlus) - CheckExtraCXXDefaultArguments(D); + SemaRef.CheckExtraCXXDefaultArguments(D); - TypeSourceInfo *TInfo = GetTypeForDeclarator(D); + TypeSourceInfo *TInfo = SemaRef.GetTypeForDeclarator(D); QualType ExceptionType = TInfo->getType(); VarDecl *New = BuildObjCExceptionDecl(TInfo, ExceptionType, @@ -5237,9 +5264,9 @@ Decl *Sema::ActOnObjCExceptionDecl(Scope *S, Declarator &D) { // Add the parameter declaration into this scope. S->AddDecl(New); if (D.getIdentifier()) - IdResolver.AddDecl(New); + SemaRef.IdResolver.AddDecl(New); - ProcessDeclAttributes(S, New, D); + SemaRef.ProcessDeclAttributes(S, New, D); if (New->hasAttr()) Diag(New->getLocation(), diag::err_block_on_nonlocal); @@ -5248,8 +5275,9 @@ Decl *Sema::ActOnObjCExceptionDecl(Scope *S, Declarator &D) { /// CollectIvarsToConstructOrDestruct - Collect those ivars which require /// initialization. -void Sema::CollectIvarsToConstructOrDestruct(ObjCInterfaceDecl *OI, +void SemaObjC::CollectIvarsToConstructOrDestruct(ObjCInterfaceDecl *OI, SmallVectorImpl &Ivars) { + ASTContext &Context = getASTContext(); for (ObjCIvarDecl *Iv = OI->all_declared_ivar_begin(); Iv; Iv= Iv->getNextIvar()) { QualType QT = Context.getBaseElementType(Iv->getType()); @@ -5258,11 +5286,12 @@ void Sema::CollectIvarsToConstructOrDestruct(ObjCInterfaceDecl *OI, } } -void Sema::DiagnoseUseOfUnimplementedSelectors() { +void SemaObjC::DiagnoseUseOfUnimplementedSelectors() { + ASTContext &Context = getASTContext(); // Load referenced selectors from the external source. - if (ExternalSource) { + if (SemaRef.ExternalSource) { SmallVector, 4> Sels; - ExternalSource->ReadReferencedSelectors(Sels); + SemaRef.ExternalSource->ReadReferencedSelectors(Sels); for (unsigned I = 0, N = Sels.size(); I != N; ++I) ReferencedSelectors[Sels[I].first] = Sels[I].second; } @@ -5282,7 +5311,7 @@ void Sema::DiagnoseUseOfUnimplementedSelectors() { } ObjCIvarDecl * -Sema::GetIvarBackingPropertyAccessor(const ObjCMethodDecl *Method, +SemaObjC::GetIvarBackingPropertyAccessor(const ObjCMethodDecl *Method, const ObjCPropertyDecl *&PDecl) const { if (Method->isClassMethod()) return nullptr; @@ -5307,7 +5336,7 @@ Sema::GetIvarBackingPropertyAccessor(const ObjCMethodDecl *Method, } namespace { - /// Used by Sema::DiagnoseUnusedBackingIvarInAccessor to check if a property + /// Used by SemaObjC::DiagnoseUnusedBackingIvarInAccessor to check if a property /// accessor references the backing ivar. class UnusedBackingIvarChecker : public RecursiveASTVisitor { @@ -5335,7 +5364,7 @@ namespace { bool VisitObjCMessageExpr(ObjCMessageExpr *E) { if (E->getReceiverKind() == ObjCMessageExpr::Instance && - S.isSelfExpr(E->getInstanceReceiver(), Method)) { + S.ObjC().isSelfExpr(E->getInstanceReceiver(), Method)) { InvokedSelfMethod = true; } return true; @@ -5343,7 +5372,7 @@ namespace { }; } // end anonymous namespace -void Sema::DiagnoseUnusedBackingIvarInAccessor(Scope *S, +void SemaObjC::DiagnoseUnusedBackingIvarInAccessor(Scope *S, const ObjCImplementationDecl *ImplD) { if (S->hasUnrecoverableErrorOccurred()) return; @@ -5351,7 +5380,7 @@ void Sema::DiagnoseUnusedBackingIvarInAccessor(Scope *S, for (const auto *CurMethod : ImplD->instance_methods()) { unsigned DIAG = diag::warn_unused_property_backing_ivar; SourceLocation Loc = CurMethod->getLocation(); - if (Diags.isIgnored(DIAG, Loc)) + if (getDiagnostics().isIgnored(DIAG, Loc)) continue; const ObjCPropertyDecl *PDecl; @@ -5362,7 +5391,7 @@ void Sema::DiagnoseUnusedBackingIvarInAccessor(Scope *S, if (CurMethod->isSynthesizedAccessorStub()) continue; - UnusedBackingIvarChecker Checker(*this, CurMethod, IV); + UnusedBackingIvarChecker Checker(SemaRef, CurMethod, IV); Checker.TraverseStmt(CurMethod->getBody()); if (Checker.AccessedIvar) continue; @@ -5377,3 +5406,289 @@ void Sema::DiagnoseUnusedBackingIvarInAccessor(Scope *S, } } } + +QualType SemaObjC::AdjustParameterTypeForObjCAutoRefCount(QualType T, + SourceLocation NameLoc, + TypeSourceInfo *TSInfo) { + ASTContext &Context = getASTContext(); + // In ARC, infer a lifetime qualifier for appropriate parameter types. + if (!getLangOpts().ObjCAutoRefCount || + T.getObjCLifetime() != Qualifiers::OCL_None || !T->isObjCLifetimeType()) + return T; + + Qualifiers::ObjCLifetime Lifetime; + + // Special cases for arrays: + // - if it's const, use __unsafe_unretained + // - otherwise, it's an error + if (T->isArrayType()) { + if (!T.isConstQualified()) { + if (SemaRef.DelayedDiagnostics.shouldDelayDiagnostics()) + SemaRef.DelayedDiagnostics.add(sema::DelayedDiagnostic::makeForbiddenType( + NameLoc, diag::err_arc_array_param_no_ownership, T, false)); + else + Diag(NameLoc, diag::err_arc_array_param_no_ownership) + << TSInfo->getTypeLoc().getSourceRange(); + } + Lifetime = Qualifiers::OCL_ExplicitNone; + } else { + Lifetime = T->getObjCARCImplicitLifetime(); + } + T = Context.getLifetimeQualifiedType(T, Lifetime); + + return T; +} + +ObjCInterfaceDecl *SemaObjC::getObjCInterfaceDecl(const IdentifierInfo *&Id, + SourceLocation IdLoc, + bool DoTypoCorrection) { + // The third "scope" argument is 0 since we aren't enabling lazy built-in + // creation from this context. + NamedDecl *IDecl = SemaRef.LookupSingleName(SemaRef.TUScope, Id, IdLoc, Sema::LookupOrdinaryName); + + if (!IDecl && DoTypoCorrection) { + // Perform typo correction at the given location, but only if we + // find an Objective-C class name. + DeclFilterCCC CCC{}; + if (TypoCorrection C = + SemaRef.CorrectTypo(DeclarationNameInfo(Id, IdLoc), Sema::LookupOrdinaryName, + SemaRef.TUScope, nullptr, CCC, Sema::CTK_ErrorRecovery)) { + SemaRef.diagnoseTypo(C, SemaRef.PDiag(diag::err_undef_interface_suggest) << Id); + IDecl = C.getCorrectionDeclAs(); + Id = IDecl->getIdentifier(); + } + } + ObjCInterfaceDecl *Def = dyn_cast_or_null(IDecl); + // This routine must always return a class definition, if any. + if (Def && Def->getDefinition()) + Def = Def->getDefinition(); + return Def; +} + +bool SemaObjC::inferObjCARCLifetime(ValueDecl *decl) { + ASTContext &Context = getASTContext(); + QualType type = decl->getType(); + Qualifiers::ObjCLifetime lifetime = type.getObjCLifetime(); + if (lifetime == Qualifiers::OCL_Autoreleasing) { + // Various kinds of declaration aren't allowed to be __autoreleasing. + unsigned kind = -1U; + if (VarDecl *var = dyn_cast(decl)) { + if (var->hasAttr()) + kind = 0; // __block + else if (!var->hasLocalStorage()) + kind = 1; // global + } else if (isa(decl)) { + kind = 3; // ivar + } else if (isa(decl)) { + kind = 2; // field + } + + if (kind != -1U) { + Diag(decl->getLocation(), diag::err_arc_autoreleasing_var) + << kind; + } + } else if (lifetime == Qualifiers::OCL_None) { + // Try to infer lifetime. + if (!type->isObjCLifetimeType()) + return false; + + lifetime = type->getObjCARCImplicitLifetime(); + type = Context.getLifetimeQualifiedType(type, lifetime); + decl->setType(type); + } + + if (VarDecl *var = dyn_cast(decl)) { + // Thread-local variables cannot have lifetime. + if (lifetime && lifetime != Qualifiers::OCL_ExplicitNone && + var->getTLSKind()) { + Diag(var->getLocation(), diag::err_arc_thread_ownership) + << var->getType(); + return true; + } + } + + return false; +} + +ObjCContainerDecl *SemaObjC::getObjCDeclContext() const { + return (dyn_cast_or_null(SemaRef.CurContext)); +} + +void SemaObjC::SetIvarInitializers(ObjCImplementationDecl *ObjCImplementation) { + if (!getLangOpts().CPlusPlus) + return; + if (ObjCInterfaceDecl *OID = ObjCImplementation->getClassInterface()) { + ASTContext &Context = getASTContext(); + SmallVector ivars; + CollectIvarsToConstructOrDestruct(OID, ivars); + if (ivars.empty()) + return; + SmallVector AllToInit; + for (unsigned i = 0; i < ivars.size(); i++) { + FieldDecl *Field = ivars[i]; + if (Field->isInvalidDecl()) + continue; + + CXXCtorInitializer *Member; + InitializedEntity InitEntity = InitializedEntity::InitializeMember(Field); + InitializationKind InitKind = + InitializationKind::CreateDefault(ObjCImplementation->getLocation()); + + InitializationSequence InitSeq(SemaRef, InitEntity, InitKind, std::nullopt); + ExprResult MemberInit = + InitSeq.Perform(SemaRef, InitEntity, InitKind, std::nullopt); + MemberInit = SemaRef.MaybeCreateExprWithCleanups(MemberInit); + // Note, MemberInit could actually come back empty if no initialization + // is required (e.g., because it would call a trivial default constructor) + if (!MemberInit.get() || MemberInit.isInvalid()) + continue; + + Member = + new (Context) CXXCtorInitializer(Context, Field, SourceLocation(), + SourceLocation(), + MemberInit.getAs(), + SourceLocation()); + AllToInit.push_back(Member); + + // Be sure that the destructor is accessible and is marked as referenced. + if (const RecordType *RecordTy = + Context.getBaseElementType(Field->getType()) + ->getAs()) { + CXXRecordDecl *RD = cast(RecordTy->getDecl()); + if (CXXDestructorDecl *Destructor = SemaRef.LookupDestructor(RD)) { + SemaRef.MarkFunctionReferenced(Field->getLocation(), Destructor); + SemaRef.CheckDestructorAccess(Field->getLocation(), Destructor, + SemaRef.PDiag(diag::err_access_dtor_ivar) + << Context.getBaseElementType(Field->getType())); + } + } + } + ObjCImplementation->setIvarInitializers(Context, + AllToInit.data(), AllToInit.size()); + } +} + +/// TranslateIvarVisibility - Translate visibility from a token ID to an +/// AST enum value. +static ObjCIvarDecl::AccessControl +TranslateIvarVisibility(tok::ObjCKeywordKind ivarVisibility) { + switch (ivarVisibility) { + default: llvm_unreachable("Unknown visitibility kind"); + case tok::objc_private: return ObjCIvarDecl::Private; + case tok::objc_public: return ObjCIvarDecl::Public; + case tok::objc_protected: return ObjCIvarDecl::Protected; + case tok::objc_package: return ObjCIvarDecl::Package; + } +} + +/// ActOnIvar - Each ivar field of an objective-c class is passed into this +/// in order to create an IvarDecl object for it. +Decl *SemaObjC::ActOnIvar(Scope *S, SourceLocation DeclStart, Declarator &D, + Expr *BitWidth, tok::ObjCKeywordKind Visibility) { + + const IdentifierInfo *II = D.getIdentifier(); + SourceLocation Loc = DeclStart; + if (II) Loc = D.getIdentifierLoc(); + + // FIXME: Unnamed fields can be handled in various different ways, for + // example, unnamed unions inject all members into the struct namespace! + + TypeSourceInfo *TInfo = SemaRef.GetTypeForDeclarator(D); + QualType T = TInfo->getType(); + + if (BitWidth) { + // 6.7.2.1p3, 6.7.2.1p4 + BitWidth = SemaRef.VerifyBitField(Loc, II, T, /*IsMsStruct*/false, BitWidth).get(); + if (!BitWidth) + D.setInvalidType(); + } else { + // Not a bitfield. + + // validate II. + + } + if (T->isReferenceType()) { + Diag(Loc, diag::err_ivar_reference_type); + D.setInvalidType(); + } + // C99 6.7.2.1p8: A member of a structure or union may have any type other + // than a variably modified type. + else if (T->isVariablyModifiedType()) { + if (!SemaRef.tryToFixVariablyModifiedVarType( + TInfo, T, Loc, diag::err_typecheck_ivar_variable_size)) + D.setInvalidType(); + } + + // Get the visibility (access control) for this ivar. + ObjCIvarDecl::AccessControl ac = + Visibility != tok::objc_not_keyword ? TranslateIvarVisibility(Visibility) + : ObjCIvarDecl::None; + // Must set ivar's DeclContext to its enclosing interface. + ObjCContainerDecl *EnclosingDecl = cast(SemaRef.CurContext); + if (!EnclosingDecl || EnclosingDecl->isInvalidDecl()) + return nullptr; + ObjCContainerDecl *EnclosingContext; + if (ObjCImplementationDecl *IMPDecl = + dyn_cast(EnclosingDecl)) { + if (getLangOpts().ObjCRuntime.isFragile()) { + // Case of ivar declared in an implementation. Context is that of its class. + EnclosingContext = IMPDecl->getClassInterface(); + assert(EnclosingContext && "Implementation has no class interface!"); + } + else + EnclosingContext = EnclosingDecl; + } else { + if (ObjCCategoryDecl *CDecl = + dyn_cast(EnclosingDecl)) { + if (getLangOpts().ObjCRuntime.isFragile() || !CDecl->IsClassExtension()) { + Diag(Loc, diag::err_misplaced_ivar) << CDecl->IsClassExtension(); + return nullptr; + } + } + EnclosingContext = EnclosingDecl; + } + + // Construct the decl. + ObjCIvarDecl *NewID = ObjCIvarDecl::Create( + getASTContext(), EnclosingContext, DeclStart, Loc, II, T, TInfo, ac, BitWidth); + + if (T->containsErrors()) + NewID->setInvalidDecl(); + + if (II) { + NamedDecl *PrevDecl = SemaRef.LookupSingleName(S, II, Loc, Sema::LookupMemberName, + RedeclarationKind::ForVisibleRedeclaration); + if (PrevDecl && SemaRef.isDeclInScope(PrevDecl, EnclosingContext, S) + && !isa(PrevDecl)) { + Diag(Loc, diag::err_duplicate_member) << II; + Diag(PrevDecl->getLocation(), diag::note_previous_declaration); + NewID->setInvalidDecl(); + } + } + + // Process attributes attached to the ivar. + SemaRef.ProcessDeclAttributes(S, NewID, D); + + if (D.isInvalidType()) + NewID->setInvalidDecl(); + + // In ARC, infer 'retaining' for ivars of retainable type. + if (getLangOpts().ObjCAutoRefCount && inferObjCARCLifetime(NewID)) + NewID->setInvalidDecl(); + + if (D.getDeclSpec().isModulePrivateSpecified()) + NewID->setModulePrivate(); + + if (II) { + // FIXME: When interfaces are DeclContexts, we'll need to add + // these to the interface. + S->AddDecl(NewID); + SemaRef.IdResolver.AddDecl(NewID); + } + + if (getLangOpts().ObjCRuntime.isNonFragile() && + !NewID->isInvalidDecl() && isa(EnclosingDecl)) + Diag(Loc, diag::warn_ivars_in_interface); + + return NewID; +} diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index d2c77ad61644f..91732645662b3 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -52,6 +52,7 @@ #include "clang/Sema/SemaCUDA.h" #include "clang/Sema/SemaFixItUtils.h" #include "clang/Sema/SemaInternal.h" +#include "clang/Sema/SemaObjC.h" #include "clang/Sema/SemaOpenMP.h" #include "clang/Sema/Template.h" #include "llvm/ADT/STLExtras.h" @@ -109,7 +110,7 @@ static void DiagnoseUnusedOfDecl(Sema &S, NamedDecl *D, SourceLocation Loc) { // should diagnose them. if (A->getSemanticSpelling() != UnusedAttr::CXX11_maybe_unused && A->getSemanticSpelling() != UnusedAttr::C23_maybe_unused) { - const Decl *DC = cast_or_null(S.getCurObjCLexicalContext()); + const Decl *DC = cast_or_null(S.ObjC().getCurObjCLexicalContext()); if (DC && !DC->hasAttr()) S.Diag(Loc, diag::warn_used_but_marked_unused) << D; } @@ -1050,7 +1051,7 @@ ExprResult Sema::DefaultVariadicArgumentPromotion(Expr *E, VariadicCallType CT, if (PlaceholderTy->getKind() == BuiltinType::ARCUnbridgedCast && (CT == VariadicMethod || (FDecl && FDecl->hasAttr()))) { - E = stripARCUnbridgedCast(E); + E = ObjC().stripARCUnbridgedCast(E); // Otherwise, do normal placeholder checking. } else { @@ -2797,7 +2798,7 @@ Sema::ActOnIdExpression(Scope *S, CXXScopeSpec &SS, // If this reference is in an Objective-C method, then we need to do // some special Objective-C lookup, too. if (IvarLookupFollowUp) { - ExprResult E(LookupInObjCMethod(R, S, II, true)); + ExprResult E(ObjC().LookupInObjCMethod(R, S, II, true)); if (E.isInvalid()) return ExprError(); @@ -2882,7 +2883,7 @@ Sema::ActOnIdExpression(Scope *S, CXXScopeSpec &SS, // reference the ivar. if (ObjCIvarDecl *Ivar = R.getAsSingle()) { R.clear(); - ExprResult E(LookupInObjCMethod(R, S, Ivar->getIdentifier())); + ExprResult E(ObjC().LookupInObjCMethod(R, S, Ivar->getIdentifier())); // In a hopelessly buggy code, Objective-C instance variable // lookup fails and no expression will be built to reference it. if (!E.isInvalid() && !E.get()) @@ -3045,166 +3046,6 @@ ExprResult Sema::BuildQualifiedDeclarationNameExpr( return BuildDeclarationNameExpr(SS, R, /* ADL */ false); } -/// The parser has read a name in, and Sema has detected that we're currently -/// inside an ObjC method. Perform some additional checks and determine if we -/// should form a reference to an ivar. -/// -/// Ideally, most of this would be done by lookup, but there's -/// actually quite a lot of extra work involved. -DeclResult Sema::LookupIvarInObjCMethod(LookupResult &Lookup, Scope *S, - IdentifierInfo *II) { - SourceLocation Loc = Lookup.getNameLoc(); - ObjCMethodDecl *CurMethod = 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(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 Sema::BuildIvarRefExpr(Scope *S, SourceLocation Loc, - ObjCIvarDecl *IV) { - ObjCMethodDecl *CurMethod = 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 (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 = - ActOnIdExpression(S, SelfScopeSpec, TemplateKWLoc, SelfName, - /*HasTrailingLParen=*/false, - /*IsAddressOfOperand=*/false); - if (SelfExpr.isInvalid()) - return ExprError(); - - SelfExpr = DefaultLvalueConversion(SelfExpr.get()); - if (SelfExpr.isInvalid()) - return ExprError(); - - 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 (!isUnevaluatedContext() && - !Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, Loc)) - getCurFunction()->recordUseOfWeak(Result); - } - if (getLangOpts().ObjCAutoRefCount && !isUnevaluatedContext()) - if (const BlockDecl *BD = CurContext->getInnermostBlockDecl()) - ImplicitlyRetainedSelfLocs.push_back({Loc, BD}); - - return Result; -} - -/// The parser has read a name in, and Sema has detected that we're currently -/// inside an ObjC method. Perform some additional checks and determine if we -/// should form a reference to an ivar. If so, build an expression referencing -/// that ivar. -ExprResult -Sema::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(Ivar.get())); - - if (Lookup.empty() && II && AllowBuiltinCreation) - LookupBuiltin(Lookup); - - // Sentinel value saying that we didn't do anything special. - return ExprResult(false); -} - /// Cast a base object to a member's actual type. /// /// There are two relevant checks: @@ -5412,7 +5253,7 @@ Sema::CreateBuiltinArraySubscriptExpr(Expr *Base, SourceLocation LLoc, // Use custom logic if this should be the pseudo-object subscript // expression. if (!LangOpts.isSubscriptPointerArithmetic()) - return BuildObjCSubscriptExpression(RLoc, BaseExpr, IndexExpr, nullptr, + return ObjC().BuildObjCSubscriptExpression(RLoc, BaseExpr, IndexExpr, nullptr, nullptr); ResultType = PTy->getPointeeType(); @@ -6166,7 +6007,7 @@ bool Sema::GatherArgumentsForCall(SourceLocation CallLoc, FunctionDecl *FDecl, if (Arg->getType() == Context.ARCUnbridgedCastTy && FDecl && FDecl->hasAttr() && (!Param || !Param->hasAttr())) - Arg = stripARCUnbridgedCast(Arg); + Arg = ObjC().stripARCUnbridgedCast(Arg); else if (getLangOpts().ObjCAutoRefCount && FDecl && FDecl->hasAttr() && (!Param || !Param->hasAttr())) @@ -7477,21 +7318,6 @@ void Sema::maybeExtendBlockObject(ExprResult &E) { Cleanup.setExprNeedsCleanups(true); } -/// Prepare a conversion of the given expression to an ObjC object -/// pointer type. -CastKind Sema::PrepareCastToObjCObjectPointer(ExprResult &E) { - QualType type = E.get()->getType(); - if (type->isObjCObjectPointerType()) { - return CK_BitCast; - } else if (type->isBlockPointerType()) { - maybeExtendBlockObject(E); - return CK_BlockPointerToObjCPointerCast; - } else { - assert(type->isPointerType()); - return CK_CPointerToObjCPointerCast; - } -} - /// Prepares for a scalar cast, performing all the necessary stages /// except the final cast and returning the kind required. CastKind Sema::PrepareScalarCast(ExprResult &Src, QualType DestTy) { @@ -8042,9 +7868,9 @@ Sema::ActOnCastExpr(Scope *S, SourceLocation LParenLoc, if (getLangOpts().CPlusPlus && !castType->isVoidType()) Diag(LParenLoc, diag::warn_old_style_cast) << CastExpr->getSourceRange(); - CheckTollFreeBridgeCast(castType, CastExpr); + ObjC().CheckTollFreeBridgeCast(castType, CastExpr); - CheckObjCBridgeRelatedCast(castType, CastExpr); + ObjC().CheckObjCBridgeRelatedCast(castType, CastExpr); DiscardMisalignedMemberAddress(castType.getTypePtr(), CastExpr); @@ -8794,7 +8620,7 @@ QualType Sema::CheckConditionalOperands(ExprResult &Cond, ExprResult &LHS, if (!checkConditionalNullPointer(*this, LHS, RHSTy)) return RHSTy; // All objective-c pointer type analysis is done here. - QualType compositeType = FindCompositeObjCPointerType(LHS, RHS, + QualType compositeType = ObjC().FindCompositeObjCPointerType(LHS, RHS, QuestionLoc); if (LHS.isInvalid() || RHS.isInvalid()) return QualType(); @@ -8839,148 +8665,6 @@ QualType Sema::CheckConditionalOperands(ExprResult &Cond, ExprResult &LHS, return QualType(); } -/// FindCompositeObjCPointerType - Helper method to find composite type of -/// two objective-c pointer types of the two input expressions. -QualType Sema::FindCompositeObjCPointerType(ExprResult &LHS, ExprResult &RHS, - SourceLocation QuestionLoc) { - 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 = ImpCastExprToType(RHS.get(), LHSTy, CK_CPointerToObjCPointerCast); - return LHSTy; - } - if (RHSTy->isObjCClassType() && - (Context.hasSameType(LHSTy, Context.getObjCClassRedefinitionType()))) { - LHS = 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 = ImpCastExprToType(RHS.get(), LHSTy, CK_CPointerToObjCPointerCast); - return LHSTy; - } - if (RHSTy->isObjCIdType() && - (Context.hasSameType(LHSTy, Context.getObjCIdRedefinitionType()))) { - LHS = 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 = ImpCastExprToType(RHS.get(), LHSTy, CK_BitCast); - return LHSTy; - } - if (Context.isObjCSelType(RHSTy) && - (Context.hasSameType(LHSTy, Context.getObjCSelRedefinitionType()))) { - LHS = 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(); - const ObjCObjectPointerType *RHSOPT = RHSTy->castAs(); - 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" 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 = ImpCastExprToType(LHS.get(), incompatTy, CK_BitCast); - RHS = ImpCastExprToType(RHS.get(), incompatTy, CK_BitCast); - return incompatTy; - } - // The object pointer types are compatible. - LHS = ImpCastExprToType(LHS.get(), compositeType, CK_BitCast); - RHS = 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()->getPointeeType(); - QualType rhptee = RHSTy->castAs()->getPointeeType(); - QualType destPointee - = Context.getQualifiedType(lhptee, rhptee.getQualifiers()); - QualType destType = Context.getPointerType(destPointee); - // Add qualifiers if necessary. - LHS = ImpCastExprToType(LHS.get(), destType, CK_NoOp); - // Promote to void*. - RHS = 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()->getPointeeType(); - QualType rhptee = RHSTy->castAs()->getPointeeType(); - QualType destPointee - = Context.getQualifiedType(rhptee, lhptee.getQualifiers()); - QualType destType = Context.getPointerType(destPointee); - // Add qualifiers if necessary. - RHS = ImpCastExprToType(RHS.get(), destType, CK_NoOp); - // Promote to void*. - LHS = ImpCastExprToType(LHS.get(), destType, CK_BitCast); - return destType; - } - return QualType(); -} - /// SuggestParentheses - Emit a note with a fixit hint that wraps /// ParenRange in parentheses. static void SuggestParentheses(Sema &Self, SourceLocation Loc, @@ -9845,7 +9529,7 @@ Sema::CheckAssignmentConstraints(QualType LHSType, ExprResult &RHS, checkObjCPointerTypesForAssignment(*this, LHSType, RHSType); if (getLangOpts().allowsNonTrivialObjCLifetimeQualifiers() && result == Compatible && - !CheckObjCARCUnavailableWeakConversion(OrigLHSType, RHSType)) + !ObjC().CheckObjCARCUnavailableWeakConversion(OrigLHSType, RHSType)) result = IncompatibleObjCWeakRef; return result; } @@ -10071,7 +9755,7 @@ Sema::CheckSingleAssignmentConstraints(QualType LHSType, ExprResult &CallerRHS, return Incompatible; Sema::AssignConvertType result = Compatible; if (getLangOpts().allowsNonTrivialObjCLifetimeQualifiers() && - !CheckObjCARCUnavailableWeakConversion(LHSType, RHSType)) + !ObjC().CheckObjCARCUnavailableWeakConversion(LHSType, RHSType)) result = IncompatibleObjCWeakRef; return result; } @@ -10177,16 +9861,16 @@ Sema::CheckSingleAssignmentConstraints(QualType LHSType, ExprResult &CallerRHS, // diagnostics and just checking for errors, e.g., during overload // resolution, return Incompatible to indicate the failure. if (getLangOpts().allowsNonTrivialObjCLifetimeQualifiers() && - CheckObjCConversion(SourceRange(), Ty, E, + ObjC().CheckObjCConversion(SourceRange(), Ty, E, CheckedConversionKind::Implicit, Diagnose, - DiagnoseCFAudited) != ACR_okay) { + DiagnoseCFAudited) != SemaObjC::ACR_okay) { if (!Diagnose) return Incompatible; } if (getLangOpts().ObjC && - (CheckObjCBridgeRelatedConversions(E->getBeginLoc(), LHSType, + (ObjC().CheckObjCBridgeRelatedConversions(E->getBeginLoc(), LHSType, E->getType(), E, Diagnose) || - CheckConversionToObjCLiteral(LHSType, E, Diagnose))) { + ObjC().CheckConversionToObjCLiteral(LHSType, E, Diagnose))) { if (!Diagnose) return Incompatible; // Replace the expression with a corrected version and continue so we @@ -12003,18 +11687,18 @@ static bool hasIsEqualMethod(Sema &S, const Expr *LHS, const Expr *RHS) { return false; // Try to find the -isEqual: method. - Selector IsEqualSel = S.NSAPIObj->getIsEqualSelector(); - ObjCMethodDecl *Method = S.LookupMethodInObjectType(IsEqualSel, + Selector IsEqualSel = S.ObjC().NSAPIObj->getIsEqualSelector(); + ObjCMethodDecl *Method = S.ObjC().LookupMethodInObjectType(IsEqualSel, InterfaceType, /*IsInstance=*/true); if (!Method) { if (Type->isObjCIdType()) { // For 'id', just check the global pool. - Method = S.LookupInstanceMethodInGlobalPool(IsEqualSel, SourceRange(), + Method = S.ObjC().LookupInstanceMethodInGlobalPool(IsEqualSel, SourceRange(), /*receiverId=*/true); } else { // Check protocols. - Method = S.LookupMethodInQualifiedType(IsEqualSel, Type, + Method = S.ObjC().LookupMethodInQualifiedType(IsEqualSel, Type, /*IsInstance=*/true); } } @@ -12033,48 +11717,6 @@ static bool hasIsEqualMethod(Sema &S, const Expr *LHS, const Expr *RHS) { return true; } -Sema::ObjCLiteralKind Sema::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(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(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; -} - static void diagnoseObjCLiteralComparison(Sema &S, SourceLocation Loc, ExprResult &LHS, ExprResult &RHS, BinaryOperator::Opcode Opc){ @@ -12097,13 +11739,13 @@ static void diagnoseObjCLiteralComparison(Sema &S, SourceLocation Loc, // This should be kept in sync with warn_objc_literal_comparison. // LK_String should always be after the other literals, since it has its own // warning flag. - Sema::ObjCLiteralKind LiteralKind = S.CheckLiteralKind(Literal); - assert(LiteralKind != Sema::LK_Block); - if (LiteralKind == Sema::LK_None) { + SemaObjC::ObjCLiteralKind LiteralKind = S.ObjC().CheckLiteralKind(Literal); + assert(LiteralKind != SemaObjC::LK_Block); + if (LiteralKind == SemaObjC::LK_None) { llvm_unreachable("Unknown Objective-C object literal kind"); } - if (LiteralKind == Sema::LK_String) + if (LiteralKind == SemaObjC::LK_String) S.Diag(Loc, diag::warn_objc_string_literal_comparison) << Literal->getSourceRange(); else @@ -12899,7 +12541,7 @@ QualType Sema::CheckCompareOperands(ExprResult &LHS, ExprResult &RHS, if (LHSIsNull && !RHSIsNull) { Expr *E = LHS.get(); if (getLangOpts().ObjCAutoRefCount) - CheckObjCConversion(SourceRange(), RHSType, E, + ObjC().CheckObjCConversion(SourceRange(), RHSType, E, CheckedConversionKind::Implicit); LHS = ImpCastExprToType(E, RHSType, RPT ? CK_BitCast :CK_CPointerToObjCPointerCast); @@ -12907,7 +12549,7 @@ QualType Sema::CheckCompareOperands(ExprResult &LHS, ExprResult &RHS, else { Expr *E = RHS.get(); if (getLangOpts().ObjCAutoRefCount) - CheckObjCConversion(SourceRange(), LHSType, E, + ObjC().CheckObjCConversion(SourceRange(), LHSType, E, CheckedConversionKind::Implicit, /*Diagnose=*/true, /*DiagnoseCFAudited=*/false, Opc); @@ -14121,7 +13763,7 @@ QualType Sema::CheckAssignmentOperands(Expr *LHSExpr, ExprResult &RHS, const Expr *InnerLHS = LHSExpr->IgnoreParenCasts(); const DeclRefExpr *DRE = dyn_cast(InnerLHS); if (!DRE || DRE->getDecl()->hasAttr()) - checkRetainCycles(LHSExpr, RHS.get()); + ObjC().checkRetainCycles(LHSExpr, RHS.get()); } if (LHSType.getObjCLifetime() == Qualifiers::OCL_Strong || @@ -17052,61 +16694,6 @@ ExprResult Sema::BuildSourceLocExpr(SourceLocIdentKind Kind, QualType ResultTy, SourceLocExpr(Context, Kind, ResultTy, BuiltinLoc, RPLoc, ParentContext); } -bool Sema::CheckConversionToObjCLiteral(QualType DstType, Expr *&Exp, - bool Diagnose) { - if (!getLangOpts().ObjC) - return false; - - const ObjCObjectPointerType *PT = DstType->getAs(); - 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(SrcExpr)) - if (OV->getSourceExpr()) - SrcExpr = OV->getSourceExpr()->IgnoreParenImpCasts(); - - if (auto *SL = dyn_cast(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(SrcExpr) || isa(SrcExpr) || - isa(SrcExpr) || isa(SrcExpr) || - isa(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; -} - static bool maybeDiagnoseAssignmentToFunction(Sema &S, QualType DstType, const Expr *SrcExpr) { if (!DstType->isFunctionPointerType() || @@ -17400,10 +16987,10 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy, FirstType, /*TakingAddress=*/true); if (CheckInferredResultType) - EmitRelatedResultTypeNote(SrcExpr); + ObjC().EmitRelatedResultTypeNote(SrcExpr); if (Action == AA_Returning && ConvTy == IncompatiblePointer) - EmitRelatedResultTypeNoteForReturn(DstType); + ObjC().EmitRelatedResultTypeNoteForReturn(DstType); if (Complained) *Complained = true; @@ -20567,7 +20154,7 @@ void Sema::DiagnoseAssignmentAsCondition(Expr *E) { Selector Sel = ME->getSelector(); // self = [ init...] - if (isSelfExpr(Op->getLHS()) && ME->getMethodFamily() == OMF_init) + if (ObjC().isSelfExpr(Op->getLHS()) && ME->getMethodFamily() == OMF_init) diagnostic = diag::warn_condition_is_idiomatic_assignment; // = [ nextObject] @@ -21277,8 +20864,8 @@ ExprResult Sema::CheckPlaceholderExpr(Expr *E) { // ARC unbridged casts. case BuiltinType::ARCUnbridgedCast: { - Expr *realCast = stripARCUnbridgedCast(E); - diagnoseARCUnbridgedCast(realCast); + Expr *realCast = ObjC().stripARCUnbridgedCast(E); + ObjC().diagnoseARCUnbridgedCast(realCast); return realCast; } @@ -21393,61 +20980,6 @@ bool Sema::CheckCaseExpression(Expr *E) { return false; } -/// ActOnObjCBoolLiteral - Parse {__objc_yes,__objc_no} literals. -ExprResult -Sema::ActOnObjCBoolLiteral(SourceLocation OpLoc, tok::TokenKind Kind) { - assert((Kind == tok::kw___objc_yes || Kind == tok::kw___objc_no) && - "Unknown Objective-C Boolean value!"); - QualType BoolT = Context.ObjCBuiltinBoolTy; - if (!Context.getBOOLDecl()) { - LookupResult Result(*this, &Context.Idents.get("BOOL"), OpLoc, - Sema::LookupOrdinaryName); - if (LookupName(Result, getCurScope()) && Result.isSingleResult()) { - NamedDecl *ND = Result.getFoundDecl(); - if (TypedefDecl *TD = dyn_cast(ND)) - Context.setBOOLDecl(TD); - } - } - if (Context.getBOOLDecl()) - BoolT = Context.getBOOLType(); - return new (Context) - ObjCBoolLiteralExpr(Kind == tok::kw___objc_yes, BoolT, OpLoc); -} - -ExprResult Sema::ActOnObjCAvailabilityCheckExpr( - llvm::ArrayRef AvailSpecs, SourceLocation AtLoc, - SourceLocation RParen) { - auto FindSpecVersion = - [&](StringRef Platform) -> std::optional { - 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 = getCurFunctionAvailabilityContext()) - Context->HasPotentialAvailabilityViolations = true; - - return new (Context) - ObjCAvailabilityCheckExpr(Version, AtLoc, RParen, Context.BoolTy); -} - ExprResult Sema::CreateRecoveryExpr(SourceLocation Begin, SourceLocation End, ArrayRef SubExprs, QualType T) { if (!Context.getLangOpts().RecoveryAST) diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 7582cbd75fec0..74be45bfc3643 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -41,6 +41,7 @@ #include "clang/Sema/SemaCUDA.h" #include "clang/Sema/SemaInternal.h" #include "clang/Sema/SemaLambda.h" +#include "clang/Sema/SemaObjC.h" #include "clang/Sema/Template.h" #include "clang/Sema/TemplateDeduction.h" #include "llvm/ADT/APInt.h" @@ -4603,9 +4604,9 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType, if (From->getType()->isObjCObjectPointerType() && ToType->isObjCObjectPointerType()) - EmitRelatedResultTypeNote(From); + ObjC().EmitRelatedResultTypeNote(From); } else if (getLangOpts().allowsNonTrivialObjCLifetimeQualifiers() && - !CheckObjCARCUnavailableWeakConversion(ToType, + !ObjC().CheckObjCARCUnavailableWeakConversion(ToType, From->getType())) { if (Action == AA_Initializing) Diag(From->getBeginLoc(), diag::err_arc_weak_unavailable_assign); @@ -4641,11 +4642,11 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType, // FIXME: doing this here is really ugly. if (Kind == CK_BlockPointerToObjCPointerCast) { ExprResult E = From; - (void) PrepareCastToObjCObjectPointer(E); + (void) ObjC().PrepareCastToObjCObjectPointer(E); From = E.get(); } if (getLangOpts().allowsNonTrivialObjCLifetimeQualifiers()) - CheckObjCConversion(SourceRange(), NewToType, From, CCK); + ObjC().CheckObjCConversion(SourceRange(), NewToType, From, CCK); From = ImpCastExprToType(From, NewToType, Kind, VK_PRValue, &BasePath, CCK) .get(); break; @@ -7057,7 +7058,7 @@ QualType Sema::CXXCheckConditionalOperands(ExprResult &Cond, ExprResult &LHS, return Composite; // Similarly, attempt to find composite type of two objective-c pointers. - Composite = FindCompositeObjCPointerType(LHS, RHS, QuestionLoc); + Composite = ObjC().FindCompositeObjCPointerType(LHS, RHS, QuestionLoc); if (LHS.isInvalid() || RHS.isInvalid()) return QualType(); if (!Composite.isNull()) @@ -8663,7 +8664,7 @@ static ExprResult attemptRecovery(Sema &SemaRef, NewSS, /*TemplateKWLoc*/ SourceLocation(), R, /*TemplateArgs*/ nullptr, /*S*/ nullptr); } else if (auto *Ivar = dyn_cast(ND)) { - return SemaRef.LookupInObjCMethod(R, Consumer.getScope(), + return SemaRef.ObjC().LookupInObjCMethod(R, Consumer.getScope(), Ivar->getIdentifier()); } } diff --git a/clang/lib/Sema/SemaExprMember.cpp b/clang/lib/Sema/SemaExprMember.cpp index c79128bc8f39e..dc3bb2f12fa5e 100644 --- a/clang/lib/Sema/SemaExprMember.cpp +++ b/clang/lib/Sema/SemaExprMember.cpp @@ -21,6 +21,7 @@ #include "clang/Sema/Scope.h" #include "clang/Sema/ScopeInfo.h" #include "clang/Sema/SemaInternal.h" +#include "clang/Sema/SemaObjC.h" #include "clang/Sema/SemaOpenMP.h" using namespace clang; @@ -1498,7 +1499,7 @@ static ExprResult LookupMemberExpr(Sema &S, LookupResult &R, ObjCMethodFamily MF = MD->getMethodFamily(); warn = (MF != OMF_init && MF != OMF_dealloc && MF != OMF_finalize && - !S.IvarBacksCurrentMethodAccessor(IDecl, MD, IV)); + !S.ObjC().IvarBacksCurrentMethodAccessor(IDecl, MD, IV)); } if (warn) S.Diag(MemberLoc, diag::warn_direct_ivar_access) << IV->getDeclName(); @@ -1636,7 +1637,7 @@ static ExprResult LookupMemberExpr(Sema &S, LookupResult &R, } // Normal property access. - return S.HandleExprPropertyRefExpr(OPT, BaseExpr.get(), OpLoc, MemberName, + return S.ObjC().HandleExprPropertyRefExpr(OPT, BaseExpr.get(), OpLoc, MemberName, MemberLoc, SourceLocation(), QualType(), false); } diff --git a/clang/lib/Sema/SemaExprObjC.cpp b/clang/lib/Sema/SemaExprObjC.cpp index b13a9d426983b..1ae3f9096bbd0 100644 --- a/clang/lib/Sema/SemaExprObjC.cpp +++ b/clang/lib/Sema/SemaExprObjC.cpp @@ -10,6 +10,8 @@ // //===----------------------------------------------------------------------===// +#include "clang/Basic/TargetInfo.h" +#include "clang/Sema/SemaObjC.h" #include "clang/AST/ASTContext.h" #include "clang/AST/DeclObjC.h" #include "clang/AST/ExprObjC.h" @@ -33,8 +35,9 @@ using namespace clang; using namespace sema; using llvm::ArrayRef; -ExprResult Sema::ParseObjCStringLiteral(SourceLocation *AtLocs, - ArrayRef Strings) { +ExprResult SemaObjC::ParseObjCStringLiteral(SourceLocation *AtLocs, + ArrayRef 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,8 @@ 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 +104,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(IF)) { Context.setObjCConstantStringInterface(StrIF); Ty = Context.getObjCConstantStringInterface(); @@ -115,8 +119,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(IF)) { Context.setObjCConstantStringInterface(StrIF); Ty = Context.getObjCConstantStringInterface(); @@ -169,23 +173,23 @@ static bool validateBoxingMethod(Sema &S, SourceLocation Loc, /// Maps ObjCLiteralKind to NSClassIdKindKind static NSAPI::NSClassIdKindKind ClassKindFromLiteralKind( - Sema::ObjCLiteralKind LiteralKind) { + SemaObjC::ObjCLiteralKind LiteralKind) { switch (LiteralKind) { - case Sema::LK_Array: + case SemaObjC::LK_Array: return NSAPI::ClassId_NSArray; - case Sema::LK_Dictionary: + case SemaObjC::LK_Dictionary: return NSAPI::ClassId_NSDictionary; - case Sema::LK_Numeric: + case SemaObjC::LK_Numeric: return NSAPI::ClassId_NSNumber; - case Sema::LK_String: + case SemaObjC::LK_String: return NSAPI::ClassId_NSString; - case Sema::LK_Boxed: + case SemaObjC::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: + case SemaObjC::LK_Block: + case SemaObjC::LK_None: break; } llvm_unreachable("LiteralKind can't be converted into a ClassKind"); @@ -196,10 +200,10 @@ static NSAPI::NSClassIdKindKind ClassKindFromLiteralKind( /// if clang not in a debugger mode. static bool ValidateObjCLiteralInterfaceDecl(Sema &S, ObjCInterfaceDecl *Decl, SourceLocation Loc, - Sema::ObjCLiteralKind LiteralKind) { + 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; @@ -218,9 +222,9 @@ static bool ValidateObjCLiteralInterfaceDecl(Sema &S, ObjCInterfaceDecl *Decl, /// NSArray (@[]) and Boxed Expressions (@()) static ObjCInterfaceDecl *LookupObjCInterfaceDeclForLiteral(Sema &S, SourceLocation Loc, - Sema::ObjCLiteralKind LiteralKind) { + 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(IF); @@ -240,7 +244,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 +266,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 +298,15 @@ static ObjCMethodDecl *getNSNumberFactoryMethod(Sema &S, SourceLocation Loc, /*isImplicitlyDeclared=*/true, /*isDefined=*/false, ObjCImplementationControl::Required, /*HasRelatedResultType=*/false); - ParmVarDecl *value = ParmVarDecl::Create(S.Context, Method, + ParmVarDecl *value = ParmVarDecl::Create(S.SemaRef.Context, Method, SourceLocation(), SourceLocation(), &CX.Idents.get("value"), NumberType, /*TInfo=*/nullptr, SC_None, nullptr); - Method->setMethodParams(S.Context, value, std::nullopt); + 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 +318,8 @@ 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(Number)) { @@ -352,7 +357,7 @@ ExprResult Sema::BuildObjCNumericLiteral(SourceLocation AtLoc, Expr *Number) { ParmVarDecl *ParamDecl = Method->parameters()[0]; InitializedEntity Entity = InitializedEntity::InitializeParameter(Context, ParamDecl); - ExprResult ConvertedNumber = PerformCopyInitialization(Entity, + ExprResult ConvertedNumber = SemaRef.PerformCopyInitialization(Entity, SourceLocation(), Number); if (ConvertedNumber.isInvalid()) @@ -360,22 +365,23 @@ ExprResult Sema::BuildObjCNumericLiteral(SourceLocation AtLoc, Expr *Number) { Number = ConvertedNumber.get(); // Use the effective source range of the literal, including the leading '@'. - return MaybeBindToTemporary( + return SemaRef.MaybeBindToTemporary( new (Context) ObjCBoxedExpr(Number, NSNumberPointer, Method, SourceRange(AtLoc, NR.getEnd()))); } -ExprResult Sema::ActOnObjCBoolLiteral(SourceLocation AtLoc, +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, + Inner = SemaRef.ActOnIntegerConstant(ValueLoc, Value? 1 : 0); + Inner = SemaRef.ImpCastExprToType(Inner.get(), Context.BoolTy, CK_IntegralToBoolean); } @@ -428,7 +434,7 @@ static ExprResult CheckObjCCollectionLiteralElement(Sema &S, Expr *Element, isa(OrigElement) || isa(OrigElement) || isa(OrigElement)) { - if (S.NSAPIObj->getNSNumberFactoryMethodKind(OrigElement->getType())) { + if (S.ObjC().NSAPIObj->getNSNumberFactoryMethodKind(OrigElement->getType())) { int Which = isa(OrigElement) ? 1 : (isa(OrigElement) || isa(OrigElement)) ? 2 @@ -439,7 +445,7 @@ static ExprResult CheckObjCCollectionLiteralElement(Sema &S, Expr *Element, << FixItHint::CreateInsertion(OrigElement->getBeginLoc(), "@"); Result = - S.BuildObjCNumericLiteral(OrigElement->getBeginLoc(), OrigElement); + S.ObjC().BuildObjCNumericLiteral(OrigElement->getBeginLoc(), OrigElement); if (Result.isInvalid()) return ExprError(); @@ -454,7 +460,7 @@ 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 +504,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 +514,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 +526,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,7 +589,7 @@ ExprResult Sema::BuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr) { BoxingMethod = M; } - if (!validateBoxingMethod(*this, Loc, NSStringDecl, + if (!validateBoxingMethod(SemaRef, Loc, NSStringDecl, stringWithUTF8String, BoxingMethod)) return ExprError(); @@ -651,8 +658,8 @@ 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(); } @@ -708,7 +715,7 @@ ExprResult Sema::BuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr) { BoxingMethod = M; } - if (!validateBoxingMethod(*this, Loc, NSValueDecl, + if (!validateBoxingMethod(SemaRef, Loc, NSValueDecl, ValueWithBytesObjCType, BoxingMethod)) return ExprError(); @@ -731,19 +738,19 @@ 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(), + 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(), + ConvertedValueExpr = SemaRef.PerformCopyInitialization(IE, SourceLocation(), ValueExpr); } @@ -754,16 +761,17 @@ 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, +ExprResult SemaObjC::BuildObjCSubscriptExpression(SourceLocation RB, Expr *BaseExpr, Expr *IndexExpr, ObjCMethodDecl *getterMethod, ObjCMethodDecl *setterMethod) { - assert(!LangOpts.isSubscriptPointerArithmetic()); + assert(!getLangOpts().isSubscriptPointerArithmetic()); + ASTContext &Context = getASTContext(); // We can't get dependent types here; our callers should have // filtered them out. @@ -772,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(); @@ -789,12 +797,13 @@ 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(); } @@ -835,7 +844,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. @@ -875,7 +884,7 @@ 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, + ExprResult Converted = CheckObjCCollectionLiteralElement(SemaRef, ElementsBuffer[I], RequiredType, true); if (Converted.isInvalid()) @@ -888,7 +897,7 @@ ExprResult Sema::BuildObjCArrayLiteral(SourceRange SR, MultiExprArg Elements) { = Context.getObjCObjectPointerType( Context.getObjCInterfaceType(NSArrayDecl)); - return MaybeBindToTemporary( + return SemaRef.MaybeBindToTemporary( ObjCArrayLiteral::Create(Context, Elements, Ty, ArrayWithObjectsMethod, SR)); } @@ -949,13 +958,14 @@ CheckObjCDictionaryLiteralDuplicateKeys(Sema &S, } } -ExprResult Sema::BuildObjCDictionaryLiteral(SourceRange SR, +ExprResult SemaObjC::BuildObjCDictionaryLiteral(SourceRange SR, MutableArrayRef 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(); } @@ -1005,7 +1015,7 @@ 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(); @@ -1084,14 +1094,14 @@ ExprResult Sema::BuildObjCDictionaryLiteral(SourceRange SR, bool HasPackExpansions = false; for (ObjCDictionaryElement &Element : Elements) { // Check the key. - ExprResult Key = CheckObjCCollectionLiteralElement(*this, Element.Key, + ExprResult Key = CheckObjCCollectionLiteralElement(SemaRef, Element.Key, KeyT); if (Key.isInvalid()) return ExprError(); // Check the value. ExprResult Value - = CheckObjCCollectionLiteralElement(*this, Element.Value, ValueT); + = CheckObjCCollectionLiteralElement(SemaRef, Element.Value, ValueT); if (Value.isInvalid()) return ExprError(); @@ -1119,13 +1129,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, +ExprResult SemaObjC::BuildObjCEncodeExpression(SourceLocation AtLoc, TypeSourceInfo *EncodedTypeInfo, SourceLocation RParenLoc) { + ASTContext &Context = getASTContext(); QualType EncodedType = EncodedTypeInfo->getType(); QualType StrTy; if (EncodedType->isDependentType()) @@ -1133,7 +1144,7 @@ ExprResult Sema::BuildObjCEncodeExpression(SourceLocation AtLoc, else { if (!EncodedType->getAsArrayTypeUnsafe() && //// Incomplete array is handled. !EncodedType->isVoidType()) // void is handled too. - if (RequireCompleteType(AtLoc, EncodedType, + if (SemaRef.RequireCompleteType(AtLoc, EncodedType, diag::err_incomplete_type_objc_at_encode, EncodedTypeInfo->getTypeLoc())) return ExprError(); @@ -1153,17 +1164,18 @@ ExprResult Sema::BuildObjCEncodeExpression(SourceLocation AtLoc, return new (Context) ObjCEncodeExpr(StrTy, EncodedTypeInfo, AtLoc, RParenLoc); } -ExprResult Sema::ParseObjCEncodeExpression(SourceLocation AtLoc, +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)); + SemaRef.getLocForEndOfToken(LParenLoc)); return BuildObjCEncodeExpression(AtLoc, TInfo, RParenLoc); } @@ -1182,8 +1194,8 @@ static bool HelperToDiagnoseMismatchedMethodsInGlobalPool(Sema &S, isa(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) @@ -1208,8 +1220,8 @@ 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, @@ -1253,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( @@ -1286,12 +1298,13 @@ static ObjCMethodDecl *findMethodInCurrentClass(Sema &S, Selector Sel) { return nullptr; } -ExprResult Sema::ParseObjCSelectorExpression(Selector Sel, +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) @@ -1309,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) @@ -1326,7 +1339,7 @@ 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(), @@ -1347,7 +1360,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 @@ -1380,12 +1393,13 @@ ExprResult Sema::ParseObjCSelectorExpression(Selector Sel, return new (Context) ObjCSelectorExpr(Ty, Sel, AtLoc, RParenLoc); } -ExprResult Sema::ParseObjCProtocolExpression(IdentifierInfo *ProtocolId, +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; @@ -1409,8 +1423,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 @@ -1419,7 +1433,7 @@ ObjCMethodDecl *Sema::tryCaptureObjCSelf(SourceLocation Loc) { if (!method) return nullptr; - tryCaptureVariable(method->getSelfDecl(), Loc); + SemaRef.tryCaptureVariable(method->getSelfDecl(), Loc); return method; } @@ -1513,13 +1527,14 @@ static QualType getBaseMessageSendResultType(Sema &S, return transferNullability(ReceiverType); } -QualType Sema::getMessageSendResultType(const Expr *Receiver, +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, + QualType resultType = getBaseMessageSendResultType(SemaRef, ReceiverType, Method, isClassMessage, isSuperMessage); @@ -1651,10 +1666,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(CurContext); + ObjCMethodDecl *MD = dyn_cast(SemaRef.CurContext); if (!MD || !MD->hasRelatedResultType() || Context.hasSameUnqualifiedType(destType, MD->getReturnType())) return; @@ -1680,7 +1696,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(E); if (!MsgSend) @@ -1706,12 +1723,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 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(); @@ -1727,9 +1745,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; @@ -1835,7 +1853,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 { @@ -1855,14 +1873,14 @@ bool Sema::CheckMessageArgumentTypes( *typeArgs, ObjCSubstitutionContext::Parameter); - if (RequireCompleteType(argExpr->getSourceRange().getBegin(), + 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 { @@ -1875,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(); } } @@ -1887,7 +1905,7 @@ bool Sema::CheckMessageArgumentTypes( if (Args[i]->isTypeDependent()) continue; - ExprResult Arg = DefaultVariadicArgumentPromotion(Args[i], VariadicMethod, + ExprResult Arg = SemaRef.DefaultVariadicArgumentPromotion(Args[i], Sema::VariadicMethod, nullptr); IsError |= Arg.isInvalid(); Args[i] = Arg.get(); @@ -1904,7 +1922,7 @@ bool Sema::CheckMessageArgumentTypes( } } - DiagnoseSentinelCalls(Method, SelLoc, Args); + SemaRef.DiagnoseSentinelCalls(Method, SelLoc, Args); // Do additional checkings on method. IsError |= @@ -1913,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(CurContext->getNonClosureAncestor()); + dyn_cast_or_null(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(); @@ -1931,7 +1949,7 @@ bool Sema::isSelfExpr(Expr *receiver, const ObjCMethodDecl *method) { } /// LookupMethodInType - Look up a method in an ObjCObjectType. -ObjCMethodDecl *Sema::LookupMethodInObjectType(Selector sel, QualType type, +ObjCMethodDecl *SemaObjC::LookupMethodInObjectType(Selector sel, QualType type, bool isInstance) { const ObjCObjectType *objType = type->castAs(); if (ObjCInterfaceDecl *iface = objType->getInterface()) { @@ -1955,7 +1973,7 @@ 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, +ObjCMethodDecl *SemaObjC::LookupMethodInQualifiedType(Selector Sel, const ObjCObjectPointerType *OPT, bool Instance) { @@ -1970,13 +1988,14 @@ 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:: +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(); @@ -1990,7 +2009,7 @@ HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT, SourceRange BaseRange = Super? SourceRange(SuperLoc) : BaseExpr->getSourceRange(); - if (RequireCompleteType(MemberLoc, OPT->getPointeeType(), + if (SemaRef.RequireCompleteType(MemberLoc, OPT->getPointeeType(), diag::err_property_not_found_forward_class, MemberName, BaseRange)) return ExprError(); @@ -1998,7 +2017,7 @@ HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT, 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) @@ -2014,7 +2033,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) @@ -2032,7 +2051,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. @@ -2045,14 +2064,14 @@ 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); + SelectorTable::constructSetterSelector(SemaRef.PP.getIdentifierTable(), + SemaRef.PP.getSelectorTable(), Member); ObjCMethodDecl *Setter = IFace->lookupInstanceMethod(SetterSel); // May be found in property's qualified list. @@ -2065,7 +2084,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 @@ -2100,9 +2119,9 @@ HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT, // Attempt to correct for typos in property names. DeclFilterCCC 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) { @@ -2120,7 +2139,7 @@ HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT, return ExprError(); } } else { - diagnoseTypo(Corrected, PDiag(diag::err_property_not_found_suggest) + SemaRef.diagnoseTypo(Corrected, SemaRef.PDiag(diag::err_property_not_found_suggest) << MemberName << QualType(OPT, 0)); return HandleExprPropertyRefExpr(OPT, BaseExpr, OpLoc, TypoResult, MemberLoc, @@ -2133,7 +2152,7 @@ HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT, QualType T = Ivar->getType(); if (const ObjCObjectPointerType * OBJPT = T->getAsObjCInterfacePointerType()) { - if (RequireCompleteType(MemberLoc, OBJPT->getPointeeType(), + if (SemaRef.RequireCompleteType(MemberLoc, OBJPT->getPointeeType(), diag::err_property_not_as_forward_class, MemberName, BaseExpr)) return ExprError(); @@ -2153,11 +2172,11 @@ HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT, return ExprError(); } -ExprResult Sema::ActOnClassPropertyRefExpr(const IdentifierInfo &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); @@ -2208,9 +2227,9 @@ ExprResult Sema::ActOnClassPropertyRefExpr(const 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. @@ -2223,7 +2242,7 @@ ExprResult Sema::ActOnClassPropertyRefExpr(const 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(); } @@ -2238,7 +2257,7 @@ ExprResult Sema::ActOnClassPropertyRefExpr(const IdentifierInfo &receiverName, if (!Setter) Setter = IFace->getCategoryClassMethod(SetterSel); - if (Setter && DiagnoseUseOfDecl(Setter, propertyNameLoc)) + if (Setter && SemaRef.DiagnoseUseOfDecl(Setter, propertyNameLoc)) return ExprError(); if (Getter || Setter) { @@ -2278,12 +2297,13 @@ class ObjCInterfaceOrSuperCCC final : public CorrectionCandidateCallback { } // end anonymous namespace -Sema::ObjCMessageKind Sema::getObjCMessageKind(Scope *S, +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 @@ -2292,8 +2312,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: @@ -2301,7 +2321,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; @@ -2336,7 +2356,7 @@ Sema::ObjCMessageKind Sema::getObjCMessageKind(Scope *S, T = Context.getObjCInterfaceType(Class); else if (TypeDecl *Type = dyn_cast(ND)) { T = Context.getTypeDeclType(Type); - DiagnoseUseOfDecl(Type, NameLoc); + SemaRef.DiagnoseUseOfDecl(Type, NameLoc); } else return ObjCInstanceMessage; @@ -2344,30 +2364,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, + SemaRef.PDiag(diag::err_unknown_receiver_suggest) << Name); return ObjCSuperMessage; } else if (ObjCInterfaceDecl *Class = Corrected.getCorrectionDeclAs()) { // 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, + SemaRef.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; } } @@ -2376,13 +2396,14 @@ Sema::ObjCMessageKind Sema::getObjCMessageKind(Scope *S, return ObjCInstanceMessage; } -ExprResult Sema::ActOnSuperMessage(Scope *S, +ExprResult SemaObjC::ActOnSuperMessage(Scope *S, SourceLocation SuperLoc, Selector Sel, SourceLocation LBracLoc, ArrayRef SelectorLocs, SourceLocation RBracLoc, MultiExprArg Args) { + ASTContext &Context = getASTContext(); // Determine whether we are inside a method or not. ObjCMethodDecl *Method = tryCaptureObjCSelf(SuperLoc); if (!Method) { @@ -2408,7 +2429,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 @@ -2427,12 +2448,13 @@ ExprResult Sema::ActOnSuperMessage(Scope *S, LBracLoc, SelectorLocs, RBracLoc, Args); } -ExprResult Sema::BuildClassMessageImplicit(QualType ReceiverType, +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); @@ -2456,7 +2478,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. @@ -2603,7 +2625,7 @@ DiagnoseCStringFormatDirectiveInObjCAPI(Sema &S, /// \param RBracLoc The location of the closing square bracket ']'. /// /// \param ArgsIn The message arguments. -ExprResult Sema::BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo, +ExprResult SemaObjC::BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo, QualType ReceiverType, SourceLocation SuperLoc, Selector Sel, @@ -2613,6 +2635,7 @@ ExprResult Sema::BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo, SourceLocation RBracLoc, MultiExprArg ArgsIn, bool isImplicit) { + ASTContext &Context = getASTContext(); SourceLocation Loc = SuperLoc.isValid()? SuperLoc : ReceiverTypeInfo->getTypeLoc().getSourceRange().getBegin(); if (LBracLoc.isInvalid()) { @@ -2650,13 +2673,13 @@ 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), + if (SemaRef.RequireCompleteType(Loc, Context.getObjCInterfaceType(Class), (getLangOpts().ObjCAutoRefCount ? diag::err_arc_receiver_forward_class : diag::warn_receiver_forward_class), @@ -2675,7 +2698,7 @@ ExprResult Sema::BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo, if (!Method) Method = Class->lookupPrivateClassMethod(Sel); - if (Method && DiagnoseUseOfDecl(Method, SelectorSlotLocs, + if (Method && SemaRef.DiagnoseUseOfDecl(Method, SelectorSlotLocs, nullptr, false, false, Class)) return ExprError(); } @@ -2693,7 +2716,7 @@ ExprResult Sema::BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo, return ExprError(); if (Method && !Method->getReturnType()->isVoidType() && - RequireCompleteType(LBracLoc, Method->getReturnType(), + SemaRef.RequireCompleteType(LBracLoc, Method->getReturnType(), diag::err_illegal_message_expr_incomplete_type)) return ExprError(); @@ -2718,7 +2741,7 @@ ExprResult Sema::BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo, << 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); @@ -2730,7 +2753,7 @@ ExprResult Sema::BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo, } } - DiagnoseCStringFormatDirectiveInObjCAPI(*this, Method, Sel, Args, NumArgs); + DiagnoseCStringFormatDirectiveInObjCAPI(SemaRef, Method, Sel, Args, NumArgs); // Construct the appropriate ObjCMessageExpr. ObjCMessageExpr *Result; @@ -2744,26 +2767,27 @@ 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, +ExprResult SemaObjC::ActOnClassMessage(Scope *S, ParsedType Receiver, Selector Sel, SourceLocation LBracLoc, ArrayRef 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(); @@ -2776,7 +2800,7 @@ ExprResult Sema::ActOnClassMessage(Scope *S, Args); } -ExprResult Sema::BuildInstanceMessageImplicit(Expr *Receiver, +ExprResult SemaObjC::BuildInstanceMessageImplicit(Expr *Receiver, QualType ReceiverType, SourceLocation Loc, Selector Sel, @@ -2789,12 +2813,12 @@ 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(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( S.LookupSingleName(S.TUScope, II, Protocol->getBeginLoc(), Sema::LookupOrdinaryName))) { @@ -2834,7 +2858,7 @@ 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, +ExprResult SemaObjC::BuildInstanceMessage(Expr *Receiver, QualType ReceiverType, SourceLocation SuperLoc, Selector Sel, @@ -2847,6 +2871,7 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver, 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(); @@ -2871,9 +2896,9 @@ 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(); } @@ -2892,7 +2917,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(); @@ -2911,24 +2936,24 @@ 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(), + 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(), + 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(), + 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(); @@ -2958,13 +2983,13 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver, Method = Methods[0]; if (ObjCMethodDecl *BestMethod = - SelectBestMethod(Sel, ArgsIn, Method->isInstanceMethod(), Methods)) + 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()) { @@ -2980,7 +3005,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) @@ -2988,7 +3013,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. @@ -2999,7 +3024,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(); } } @@ -3028,7 +3053,7 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver, } if (ObjCMethodDecl *BestMethod = - SelectBestMethod(Sel, ArgsIn, Method->isInstanceMethod(), + SemaRef.SelectBestMethod(Sel, ArgsIn, Method->isInstanceMethod(), Methods)) Method = BestMethod; } @@ -3047,7 +3072,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()) { @@ -3059,7 +3084,7 @@ 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(), + if (SemaRef.RequireCompleteType(Loc, OCIType->getPointeeType(), getLangOpts().ObjCAutoRefCount ? diag::err_arc_receiver_forward_instance : diag::warn_receiver_forward_instance, @@ -3105,7 +3130,7 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver, Method = Methods[0]; if (ObjCMethodDecl *BestMethod = - SelectBestMethod(Sel, ArgsIn, Method->isInstanceMethod(), + SemaRef.SelectBestMethod(Sel, ArgsIn, Method->isInstanceMethod(), Methods)) Method = BestMethod; @@ -3121,7 +3146,7 @@ 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). @@ -3133,7 +3158,7 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver, FunctionScopeInfo *DIFunctionScopeInfo = (Method && Method->getMethodFamily() == OMF_init) - ? getEnclosingFunction() : nullptr; + ? SemaRef.getEnclosingFunction() : nullptr; if (Method && Method->isDirectMethod()) { if (ReceiverType->isObjCIdType() && !isImplicit) { @@ -3199,7 +3224,7 @@ 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() ? @@ -3234,7 +3259,7 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver, return ExprError(); if (Method && !Method->getReturnType()->isVoidType() && - RequireCompleteType(LBracLoc, Method->getReturnType(), + SemaRef.RequireCompleteType(LBracLoc, Method->getReturnType(), diag::err_illegal_message_expr_incomplete_type)) return ExprError(); @@ -3319,7 +3344,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; @@ -3333,7 +3358,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; @@ -3344,7 +3369,7 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver, if (Receiver && isSelfExpr(Receiver)) { if (const auto *OPT = ReceiverType->getAs()) { if (OPT->getObjectType()->isObjCClass()) { - if (const auto *CurMeth = getCurMethodDecl()) { + if (const auto *CurMeth = SemaRef.getCurMethodDecl()) { IsClassObjectCall = true; ReceiverType = Context.getObjCInterfaceType(CurMeth->getClassInterface()); @@ -3352,7 +3377,7 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver, } } } - checkFoundationAPI(*this, SelLoc, Method, ArrayRef(Args, NumArgs), + checkFoundationAPI(SemaRef, SelLoc, Method, ArrayRef(Args, NumArgs), ReceiverType, IsClassObjectCall); } @@ -3362,7 +3387,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(CurContext); + ObjCMethodDecl *method = dyn_cast(SemaRef.CurContext); if (method && method->getMethodFamily() == OMF_init) { // The implicit assignment to self means we also don't want to // consume the result. @@ -3383,19 +3408,19 @@ 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(Arg->IgnoreParenCasts())) { Selector Sel = OSE->getSelector(); @@ -3409,19 +3434,20 @@ 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, +ExprResult SemaObjC::ActOnInstanceMessage(Scope *S, Expr *Receiver, Selector Sel, SourceLocation LBracLoc, ArrayRef 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(Receiver)) { - ExprResult Result = MaybeConvertParenListExprToParenExpr(S, Receiver); + ExprResult Result = SemaRef.MaybeConvertParenListExprToParenExpr(S, Receiver); if (Result.isInvalid()) return ExprError(); Receiver = Result.get(); } @@ -3735,12 +3761,13 @@ 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 @@ -3921,7 +3948,7 @@ static void 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."); @@ -3954,7 +3981,7 @@ static void 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 @@ -4130,7 +4157,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. @@ -4139,48 +4166,48 @@ void Sema::CheckTollFreeBridgeCast(QualType castType, Expr *castExpr) { if (castACTC == ACTC_retainable && exprACTC == ACTC_coreFoundation) { bool HasObjCBridgeAttr; bool ObjCBridgeAttrWillNotWarn = - CheckObjCBridgeNSCast(*this, castType, castExpr, HasObjCBridgeAttr, + CheckObjCBridgeNSCast(SemaRef, castType, castExpr, HasObjCBridgeAttr, false); if (ObjCBridgeAttrWillNotWarn && HasObjCBridgeAttr) return; bool HasObjCBridgeMutableAttr; bool ObjCBridgeMutableAttrWillNotWarn = - CheckObjCBridgeNSCast(*this, castType, castExpr, + CheckObjCBridgeNSCast(SemaRef, castType, castExpr, HasObjCBridgeMutableAttr, false); if (ObjCBridgeMutableAttrWillNotWarn && HasObjCBridgeMutableAttr) return; if (HasObjCBridgeAttr) - CheckObjCBridgeNSCast(*this, castType, castExpr, HasObjCBridgeAttr, + CheckObjCBridgeNSCast(SemaRef, castType, castExpr, HasObjCBridgeAttr, true); else if (HasObjCBridgeMutableAttr) - CheckObjCBridgeNSCast(*this, castType, castExpr, + CheckObjCBridgeNSCast(SemaRef, castType, castExpr, HasObjCBridgeMutableAttr, true); } else if (castACTC == ACTC_coreFoundation && exprACTC == ACTC_retainable) { bool HasObjCBridgeAttr; bool ObjCBridgeAttrWillNotWarn = - CheckObjCBridgeCFCast(*this, castType, castExpr, HasObjCBridgeAttr, + CheckObjCBridgeCFCast(SemaRef, castType, castExpr, HasObjCBridgeAttr, false); if (ObjCBridgeAttrWillNotWarn && HasObjCBridgeAttr) return; bool HasObjCBridgeMutableAttr; bool ObjCBridgeMutableAttrWillNotWarn = - CheckObjCBridgeCFCast(*this, castType, castExpr, + CheckObjCBridgeCFCast(SemaRef, castType, castExpr, HasObjCBridgeMutableAttr, false); if (ObjCBridgeMutableAttrWillNotWarn && HasObjCBridgeMutableAttr) return; if (HasObjCBridgeAttr) - CheckObjCBridgeCFCast(*this, castType, castExpr, HasObjCBridgeAttr, + CheckObjCBridgeCFCast(SemaRef, castType, castExpr, HasObjCBridgeAttr, true); else if (HasObjCBridgeMutableAttr) - CheckObjCBridgeCFCast(*this, castType, castExpr, + CheckObjCBridgeCFCast(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(castExpr)) { if (PRE->isExplicitProperty()) { @@ -4201,7 +4228,7 @@ void Sema::CheckObjCBridgeRelatedCast(QualType castType, Expr *castExpr) { castExpr); } -bool Sema::CheckTollFreeBridgeStaticCast(QualType castType, Expr *castExpr, +bool SemaObjC::CheckTollFreeBridgeStaticCast(QualType castType, Expr *castExpr, CastKind &Kind) { if (!getLangOpts().ObjC) return false; @@ -4218,13 +4245,14 @@ bool Sema::CheckTollFreeBridgeStaticCast(QualType castType, Expr *castExpr, return false; } -bool Sema::checkObjCBridgeRelatedComponents(SourceLocation Loc, +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) @@ -4237,9 +4265,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; @@ -4292,9 +4320,10 @@ bool Sema::checkObjCBridgeRelatedComponents(SourceLocation Loc, } bool -Sema::CheckObjCBridgeRelatedConversions(SourceLocation Loc, +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); @@ -4320,7 +4349,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 @@ -4348,7 +4377,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()) { @@ -4384,11 +4413,12 @@ Sema::CheckObjCBridgeRelatedConversions(SourceLocation Loc, return false; } -Sema::ARCConversionResult -Sema::CheckObjCConversion(SourceRange castRange, QualType castType, +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 @@ -4449,11 +4479,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)) { @@ -4471,14 +4501,14 @@ 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 @@ -4497,7 +4527,7 @@ 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, + diagnoseObjCARCConversion(SemaRef, castRange, castType, castACTC, castExpr, castExpr, exprACTC, CCK); return ACR_error; } @@ -4506,7 +4536,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(e->IgnoreParens()); @@ -4533,14 +4563,15 @@ void Sema::diagnoseARCUnbridgedCast(Expr *e) { Expr *castExpr = realCast->getSubExpr(); assert(classifyTypeForARCConversion(castExpr->getType()) == ACTC_retainable); - diagnoseObjCARCConversion(*this, castRange, castType, castACTC, + 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(e)) { Expr *sub = stripARCUnbridgedCast(pe->getSubExpr()); @@ -4551,7 +4582,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(e)) { assert(!gse->isResultDependent()); assert(!gse->isTypePredicate()); @@ -4579,8 +4610,9 @@ Expr *Sema::stripARCUnbridgedCast(Expr *e) { } } -bool Sema::CheckObjCARCUnavailableWeakConversion(QualType castType, +bool SemaObjC::CheckObjCARCUnavailableWeakConversion(QualType castType, QualType exprType) { + ASTContext &Context = getASTContext(); QualType canCastType = Context.getCanonicalType(castType).getUnqualifiedType(); QualType canExprType = @@ -4633,12 +4665,13 @@ static Expr *maybeUndoReclaimObject(Expr *e) { return e; } -ExprResult Sema::BuildObjCBridgedCast(SourceLocation LParenLoc, +ExprResult SemaObjC::BuildObjCBridgedCast(SourceLocation LParenLoc, ObjCBridgeCastKind Kind, SourceLocation BridgeKeywordLoc, TypeSourceInfo *TSInfo, Expr *SubExpr) { - ExprResult SubResult = UsualUnaryConversions(SubExpr); + ASTContext &Context = getASTContext(); + ExprResult SubResult = SemaRef.UsualUnaryConversions(SubExpr); if (SubResult.isInvalid()) return ExprError(); SubExpr = SubResult.get(); @@ -4736,7 +4769,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()); } @@ -4744,15 +4777,16 @@ ExprResult Sema::BuildObjCBridgedCast(SourceLocation LParenLoc, return Result; } -ExprResult Sema::ActOnObjCBridgedCast(Scope *S, +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) @@ -4760,3 +4794,464 @@ 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(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(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(); + const ObjCObjectPointerType *RHSOPT = RHSTy->castAs(); + 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" 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()->getPointeeType(); + QualType rhptee = RHSTy->castAs()->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()->getPointeeType(); + QualType rhptee = RHSTy->castAs()->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(); + 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(SrcExpr)) + if (OV->getSourceExpr()) + SrcExpr = OV->getSourceExpr()->IgnoreParenImpCasts(); + + if (auto *SL = dyn_cast(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(SrcExpr) || isa(SrcExpr) || + isa(SrcExpr) || isa(SrcExpr) || + isa(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(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 AvailSpecs, SourceLocation AtLoc, + SourceLocation RParen) { + ASTContext &Context = getASTContext(); + auto FindSpecVersion = + [&](StringRef Platform) -> std::optional { + 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(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(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; +} diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index e86f7578ff0c0..4050c34036e66 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -28,6 +28,7 @@ #include "clang/Sema/Lookup.h" #include "clang/Sema/Ownership.h" #include "clang/Sema/SemaInternal.h" +#include "clang/Sema/SemaObjC.h" #include "llvm/ADT/APInt.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/PointerIntPair.h" @@ -6018,7 +6019,7 @@ static bool tryObjCWritebackConversion(Sema &S, // Handle write-back conversion. QualType ConvertedArgType; - if (!S.isObjCWritebackConversion(ArgType, Entity.getType(), + if (!S.ObjC().isObjCWritebackConversion(ArgType, Entity.getType(), ConvertedArgType)) return false; @@ -6211,10 +6212,10 @@ void InitializationSequence::InitializeFrom(Sema &S, if (Args.size() == 1) { Initializer = Args[0]; if (S.getLangOpts().ObjC) { - if (S.CheckObjCBridgeRelatedConversions(Initializer->getBeginLoc(), + if (S.ObjC().CheckObjCBridgeRelatedConversions(Initializer->getBeginLoc(), DestType, Initializer->getType(), Initializer) || - S.CheckConversionToObjCLiteral(DestType, Initializer)) + S.ObjC().CheckConversionToObjCLiteral(DestType, Initializer)) Args[0] = Initializer; } if (!isa(Initializer)) @@ -9566,12 +9567,12 @@ static void emitBadConversionNotes(Sema &S, const InitializedEntity &entity, // Emit a possible note about the conversion failing because the // operand is a message send with a related result type. - S.EmitRelatedResultTypeNote(op); + S.ObjC().EmitRelatedResultTypeNote(op); // Emit a possible note about a return failing because we're // expecting a related result type. if (entity.getKind() == InitializedEntity::EK_Result) - S.EmitRelatedResultTypeNoteForReturn(destType); + S.ObjC().EmitRelatedResultTypeNoteForReturn(destType); } QualType fromType = op->getType(); QualType fromPointeeType = fromType.getCanonicalType()->getPointeeType(); diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp index 55af414df39f5..b96567b570561 100644 --- a/clang/lib/Sema/SemaLookup.cpp +++ b/clang/lib/Sema/SemaLookup.cpp @@ -3317,15 +3317,6 @@ NamedDecl *Sema::LookupSingleName(Scope *S, DeclarationName Name, return R.getAsSingle(); } -/// Find the protocol with the given name, if any. -ObjCProtocolDecl *Sema::LookupProtocol(IdentifierInfo *II, - SourceLocation IdLoc, - RedeclarationKind Redecl) { - Decl *D = LookupSingleName(TUScope, II, IdLoc, - LookupObjCProtocolName, Redecl); - return cast_or_null(D); -} - void Sema::LookupOverloadedOperatorName(OverloadedOperatorKind Op, Scope *S, UnresolvedSetImpl &Functions) { // C++ [over.match.oper]p3: diff --git a/clang/lib/Sema/SemaObjC.cpp b/clang/lib/Sema/SemaObjC.cpp new file mode 100644 index 0000000000000..4322f985be1ba --- /dev/null +++ b/clang/lib/Sema/SemaObjC.cpp @@ -0,0 +1,1501 @@ +//===----- SemaObjC.cpp ---- Semantic Analysis for Objective-C ------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// \file +/// This file implements semantic analysis for Objective-C. +/// +//===----------------------------------------------------------------------===// + +#include "clang/Sema/SemaObjC.h" +#include "clang/AST/EvaluatedExprVisitor.h" +#include "clang/AST/StmtObjC.h" +#include "clang/Basic/DiagnosticSema.h" +#include "clang/Lex/Preprocessor.h" +#include "clang/Sema/ScopeInfo.h" +#include "clang/Sema/Sema.h" +#include "clang/Sema/TemplateDeduction.h" +#include "llvm/Support/ConvertUTF.h" + +namespace clang { + +SemaObjC::SemaObjC(Sema &S) : SemaBase(S), NSNumberDecl(nullptr), NSValueDecl(nullptr), NSStringDecl(nullptr), + StringWithUTF8StringMethod(nullptr), + ValueWithBytesObjCTypeMethod(nullptr), NSArrayDecl(nullptr), + ArrayWithObjectsMethod(nullptr), NSDictionaryDecl(nullptr), + DictionaryWithObjectsMethod(nullptr) {} + +StmtResult +SemaObjC::ActOnObjCForCollectionStmt(SourceLocation ForLoc, + Stmt *First, Expr *collection, + SourceLocation RParenLoc) { + ASTContext &Context = getASTContext(); + SemaRef.setFunctionHasBranchProtectedScope(); + + ExprResult CollectionExprResult = + CheckObjCForCollectionOperand(ForLoc, collection); + + if (First) { + QualType FirstType; + if (DeclStmt *DS = dyn_cast(First)) { + if (!DS->isSingleDecl()) + return StmtError(Diag((*DS->decl_begin())->getLocation(), + diag::err_toomany_element_decls)); + + VarDecl *D = dyn_cast(DS->getSingleDecl()); + if (!D || D->isInvalidDecl()) + return StmtError(); + + FirstType = D->getType(); + // C99 6.8.5p3: The declaration part of a 'for' statement shall only + // declare identifiers for objects having storage class 'auto' or + // 'register'. + if (!D->hasLocalStorage()) + return StmtError(Diag(D->getLocation(), + diag::err_non_local_variable_decl_in_for)); + + // If the type contained 'auto', deduce the 'auto' to 'id'. + if (FirstType->getContainedAutoType()) { + SourceLocation Loc = D->getLocation(); + OpaqueValueExpr OpaqueId(Loc, Context.getObjCIdType(), VK_PRValue); + Expr *DeducedInit = &OpaqueId; + sema::TemplateDeductionInfo Info(Loc); + FirstType = QualType(); + TemplateDeductionResult Result = SemaRef.DeduceAutoType( + D->getTypeSourceInfo()->getTypeLoc(), DeducedInit, FirstType, Info); + if (Result != TemplateDeductionResult::Success && + Result != TemplateDeductionResult::AlreadyDiagnosed) + SemaRef.DiagnoseAutoDeductionFailure(D, DeducedInit); + if (FirstType.isNull()) { + D->setInvalidDecl(); + return StmtError(); + } + + D->setType(FirstType); + + if (!SemaRef.inTemplateInstantiation()) { + SourceLocation Loc = + D->getTypeSourceInfo()->getTypeLoc().getBeginLoc(); + Diag(Loc, diag::warn_auto_var_is_id) + << D->getDeclName(); + } + } + + } else { + Expr *FirstE = cast(First); + if (!FirstE->isTypeDependent() && !FirstE->isLValue()) + return StmtError( + Diag(First->getBeginLoc(), diag::err_selector_element_not_lvalue) + << First->getSourceRange()); + + FirstType = static_cast(First)->getType(); + if (FirstType.isConstQualified()) + Diag(ForLoc, diag::err_selector_element_const_type) + << FirstType << First->getSourceRange(); + } + if (!FirstType->isDependentType() && + !FirstType->isObjCObjectPointerType() && + !FirstType->isBlockPointerType()) + return StmtError(Diag(ForLoc, diag::err_selector_element_type) + << FirstType << First->getSourceRange()); + } + + if (CollectionExprResult.isInvalid()) + return StmtError(); + + CollectionExprResult = + SemaRef.ActOnFinishFullExpr(CollectionExprResult.get(), /*DiscardedValue*/ false); + if (CollectionExprResult.isInvalid()) + return StmtError(); + + return new (Context) ObjCForCollectionStmt(First, CollectionExprResult.get(), + nullptr, ForLoc, RParenLoc); +} + +ExprResult +SemaObjC::CheckObjCForCollectionOperand(SourceLocation forLoc, Expr *collection) { + ASTContext &Context = getASTContext(); + if (!collection) + return ExprError(); + + ExprResult result = SemaRef.CorrectDelayedTyposInExpr(collection); + if (!result.isUsable()) + return ExprError(); + collection = result.get(); + + // Bail out early if we've got a type-dependent expression. + if (collection->isTypeDependent()) return collection; + + // Perform normal l-value conversion. + result = SemaRef.DefaultFunctionArrayLvalueConversion(collection); + if (result.isInvalid()) + return ExprError(); + collection = result.get(); + + // The operand needs to have object-pointer type. + // TODO: should we do a contextual conversion? + const ObjCObjectPointerType *pointerType = + collection->getType()->getAs(); + if (!pointerType) + return Diag(forLoc, diag::err_collection_expr_type) + << collection->getType() << collection->getSourceRange(); + + // Check that the operand provides + // - countByEnumeratingWithState:objects:count: + const ObjCObjectType *objectType = pointerType->getObjectType(); + ObjCInterfaceDecl *iface = objectType->getInterface(); + + // If we have a forward-declared type, we can't do this check. + // Under ARC, it is an error not to have a forward-declared class. + if (iface && + (getLangOpts().ObjCAutoRefCount + ? SemaRef.RequireCompleteType(forLoc, QualType(objectType, 0), + diag::err_arc_collection_forward, collection) + : !SemaRef.isCompleteType(forLoc, QualType(objectType, 0)))) { + // Otherwise, if we have any useful type information, check that + // the type declares the appropriate method. + } else if (iface || !objectType->qual_empty()) { + const IdentifierInfo *selectorIdents[] = { + &Context.Idents.get("countByEnumeratingWithState"), + &Context.Idents.get("objects"), &Context.Idents.get("count")}; + Selector selector = Context.Selectors.getSelector(3, &selectorIdents[0]); + + ObjCMethodDecl *method = nullptr; + + // If there's an interface, look in both the public and private APIs. + if (iface) { + method = iface->lookupInstanceMethod(selector); + if (!method) method = iface->lookupPrivateMethod(selector); + } + + // Also check protocol qualifiers. + if (!method) + method = LookupMethodInQualifiedType(selector, pointerType, + /*instance*/ true); + + // If we didn't find it anywhere, give up. + if (!method) { + Diag(forLoc, diag::warn_collection_expr_type) + << collection->getType() << selector << collection->getSourceRange(); + } + + // TODO: check for an incompatible signature? + } + + // Wrap up any cleanups in the expression. + return collection; +} + +StmtResult SemaObjC::FinishObjCForCollectionStmt(Stmt *S, Stmt *B) { + if (!S || !B) + return StmtError(); + ObjCForCollectionStmt * ForStmt = cast(S); + + ForStmt->setBody(B); + return S; +} + +StmtResult +SemaObjC::ActOnObjCAtCatchStmt(SourceLocation AtLoc, + SourceLocation RParen, Decl *Parm, + Stmt *Body) { + ASTContext &Context = getASTContext(); + VarDecl *Var = cast_or_null(Parm); + if (Var && Var->isInvalidDecl()) + return StmtError(); + + return new (Context) ObjCAtCatchStmt(AtLoc, RParen, Var, Body); +} + +StmtResult +SemaObjC::ActOnObjCAtFinallyStmt(SourceLocation AtLoc, Stmt *Body) { + ASTContext &Context = getASTContext(); + return new (Context) ObjCAtFinallyStmt(AtLoc, Body); +} + +StmtResult +SemaObjC::ActOnObjCAtTryStmt(SourceLocation AtLoc, Stmt *Try, + MultiStmtArg CatchStmts, Stmt *Finally) { + ASTContext &Context = getASTContext(); + if (!getLangOpts().ObjCExceptions) + Diag(AtLoc, diag::err_objc_exceptions_disabled) << "@try"; + + // Objective-C try is incompatible with SEH __try. + sema::FunctionScopeInfo *FSI = SemaRef.getCurFunction(); + if (FSI->FirstSEHTryLoc.isValid()) { + Diag(AtLoc, diag::err_mixing_cxx_try_seh_try) << 1; + Diag(FSI->FirstSEHTryLoc, diag::note_conflicting_try_here) << "'__try'"; + } + + FSI->setHasObjCTry(AtLoc); + unsigned NumCatchStmts = CatchStmts.size(); + return ObjCAtTryStmt::Create(Context, AtLoc, Try, CatchStmts.data(), + NumCatchStmts, Finally); +} + +StmtResult SemaObjC::BuildObjCAtThrowStmt(SourceLocation AtLoc, Expr *Throw) { + ASTContext &Context = getASTContext(); + if (Throw) { + ExprResult Result = SemaRef.DefaultLvalueConversion(Throw); + if (Result.isInvalid()) + return StmtError(); + + Result = SemaRef.ActOnFinishFullExpr(Result.get(), /*DiscardedValue*/ false); + if (Result.isInvalid()) + return StmtError(); + Throw = Result.get(); + + QualType ThrowType = Throw->getType(); + // Make sure the expression type is an ObjC pointer or "void *". + if (!ThrowType->isDependentType() && + !ThrowType->isObjCObjectPointerType()) { + const PointerType *PT = ThrowType->getAs(); + if (!PT || !PT->getPointeeType()->isVoidType()) + return StmtError(Diag(AtLoc, diag::err_objc_throw_expects_object) + << Throw->getType() << Throw->getSourceRange()); + } + } + + return new (Context) ObjCAtThrowStmt(AtLoc, Throw); +} + +StmtResult +SemaObjC::ActOnObjCAtThrowStmt(SourceLocation AtLoc, Expr *Throw, + Scope *CurScope) { + if (!getLangOpts().ObjCExceptions) + Diag(AtLoc, diag::err_objc_exceptions_disabled) << "@throw"; + + if (!Throw) { + // @throw without an expression designates a rethrow (which must occur + // in the context of an @catch clause). + Scope *AtCatchParent = CurScope; + while (AtCatchParent && !AtCatchParent->isAtCatchScope()) + AtCatchParent = AtCatchParent->getParent(); + if (!AtCatchParent) + return StmtError(Diag(AtLoc, diag::err_rethrow_used_outside_catch)); + } + return BuildObjCAtThrowStmt(AtLoc, Throw); +} + +ExprResult +SemaObjC::ActOnObjCAtSynchronizedOperand(SourceLocation atLoc, Expr *operand) { + ExprResult result = SemaRef.DefaultLvalueConversion(operand); + if (result.isInvalid()) + return ExprError(); + operand = result.get(); + + // Make sure the expression type is an ObjC pointer or "void *". + QualType type = operand->getType(); + if (!type->isDependentType() && + !type->isObjCObjectPointerType()) { + const PointerType *pointerType = type->getAs(); + if (!pointerType || !pointerType->getPointeeType()->isVoidType()) { + if (getLangOpts().CPlusPlus) { + if (SemaRef.RequireCompleteType(atLoc, type, + diag::err_incomplete_receiver_type)) + return Diag(atLoc, diag::err_objc_synchronized_expects_object) + << type << operand->getSourceRange(); + + ExprResult result = SemaRef.PerformContextuallyConvertToObjCPointer(operand); + if (result.isInvalid()) + return ExprError(); + if (!result.isUsable()) + return Diag(atLoc, diag::err_objc_synchronized_expects_object) + << type << operand->getSourceRange(); + + operand = result.get(); + } else { + return Diag(atLoc, diag::err_objc_synchronized_expects_object) + << type << operand->getSourceRange(); + } + } + } + + // The operand to @synchronized is a full-expression. + return SemaRef.ActOnFinishFullExpr(operand, /*DiscardedValue*/ false); +} + +StmtResult +SemaObjC::ActOnObjCAtSynchronizedStmt(SourceLocation AtLoc, Expr *SyncExpr, + Stmt *SyncBody) { + ASTContext &Context = getASTContext(); + // We can't jump into or indirect-jump out of a @synchronized block. + SemaRef.setFunctionHasBranchProtectedScope(); + return new (Context) ObjCAtSynchronizedStmt(AtLoc, SyncExpr, SyncBody); +} + +StmtResult +SemaObjC::ActOnObjCAutoreleasePoolStmt(SourceLocation AtLoc, Stmt *Body) { + ASTContext &Context = getASTContext(); + SemaRef.setFunctionHasBranchProtectedScope(); + return new (Context) ObjCAutoreleasePoolStmt(AtLoc, Body); +} + +TypeResult SemaObjC::actOnObjCProtocolQualifierType( + SourceLocation lAngleLoc, + ArrayRef protocols, + ArrayRef protocolLocs, + SourceLocation rAngleLoc) { + ASTContext &Context = getASTContext(); + // Form id. + QualType Result = Context.getObjCObjectType( + Context.ObjCBuiltinIdTy, {}, + llvm::ArrayRef((ObjCProtocolDecl *const *)protocols.data(), + protocols.size()), + false); + Result = Context.getObjCObjectPointerType(Result); + + TypeSourceInfo *ResultTInfo = Context.CreateTypeSourceInfo(Result); + TypeLoc ResultTL = ResultTInfo->getTypeLoc(); + + auto ObjCObjectPointerTL = ResultTL.castAs(); + ObjCObjectPointerTL.setStarLoc(SourceLocation()); // implicit + + auto ObjCObjectTL = ObjCObjectPointerTL.getPointeeLoc() + .castAs(); + ObjCObjectTL.setHasBaseTypeAsWritten(false); + ObjCObjectTL.getBaseLoc().initialize(Context, SourceLocation()); + + // No type arguments. + ObjCObjectTL.setTypeArgsLAngleLoc(SourceLocation()); + ObjCObjectTL.setTypeArgsRAngleLoc(SourceLocation()); + + // Fill in protocol qualifiers. + ObjCObjectTL.setProtocolLAngleLoc(lAngleLoc); + ObjCObjectTL.setProtocolRAngleLoc(rAngleLoc); + for (unsigned i = 0, n = protocols.size(); i != n; ++i) + ObjCObjectTL.setProtocolLoc(i, protocolLocs[i]); + + // We're done. Return the completed type to the parser. + return SemaRef.CreateParsedType(Result, ResultTInfo); +} + +TypeResult SemaObjC::actOnObjCTypeArgsAndProtocolQualifiers( + Scope *S, + SourceLocation Loc, + ParsedType BaseType, + SourceLocation TypeArgsLAngleLoc, + ArrayRef TypeArgs, + SourceLocation TypeArgsRAngleLoc, + SourceLocation ProtocolLAngleLoc, + ArrayRef Protocols, + ArrayRef ProtocolLocs, + SourceLocation ProtocolRAngleLoc) { + ASTContext &Context = getASTContext(); + TypeSourceInfo *BaseTypeInfo = nullptr; + QualType T = SemaRef.GetTypeFromParser(BaseType, &BaseTypeInfo); + if (T.isNull()) + return true; + + // Handle missing type-source info. + if (!BaseTypeInfo) + BaseTypeInfo = Context.getTrivialTypeSourceInfo(T, Loc); + + // Extract type arguments. + SmallVector ActualTypeArgInfos; + for (unsigned i = 0, n = TypeArgs.size(); i != n; ++i) { + TypeSourceInfo *TypeArgInfo = nullptr; + QualType TypeArg = SemaRef.GetTypeFromParser(TypeArgs[i], &TypeArgInfo); + if (TypeArg.isNull()) { + ActualTypeArgInfos.clear(); + break; + } + + assert(TypeArgInfo && "No type source info?"); + ActualTypeArgInfos.push_back(TypeArgInfo); + } + + // Build the object type. + QualType Result = BuildObjCObjectType( + T, BaseTypeInfo->getTypeLoc().getSourceRange().getBegin(), + TypeArgsLAngleLoc, ActualTypeArgInfos, TypeArgsRAngleLoc, + ProtocolLAngleLoc, + llvm::ArrayRef((ObjCProtocolDecl *const *)Protocols.data(), + Protocols.size()), + ProtocolLocs, ProtocolRAngleLoc, + /*FailOnError=*/false, + /*Rebuilding=*/false); + + if (Result == T) + return BaseType; + + // Create source information for this type. + TypeSourceInfo *ResultTInfo = Context.CreateTypeSourceInfo(Result); + TypeLoc ResultTL = ResultTInfo->getTypeLoc(); + + // For id or Class, we'll have an + // object pointer type. Fill in source information for it. + if (auto ObjCObjectPointerTL = ResultTL.getAs()) { + // The '*' is implicit. + ObjCObjectPointerTL.setStarLoc(SourceLocation()); + ResultTL = ObjCObjectPointerTL.getPointeeLoc(); + } + + if (auto OTPTL = ResultTL.getAs()) { + // Protocol qualifier information. + if (OTPTL.getNumProtocols() > 0) { + assert(OTPTL.getNumProtocols() == Protocols.size()); + OTPTL.setProtocolLAngleLoc(ProtocolLAngleLoc); + OTPTL.setProtocolRAngleLoc(ProtocolRAngleLoc); + for (unsigned i = 0, n = Protocols.size(); i != n; ++i) + OTPTL.setProtocolLoc(i, ProtocolLocs[i]); + } + + // We're done. Return the completed type to the parser. + return SemaRef.CreateParsedType(Result, ResultTInfo); + } + + auto ObjCObjectTL = ResultTL.castAs(); + + // Type argument information. + if (ObjCObjectTL.getNumTypeArgs() > 0) { + assert(ObjCObjectTL.getNumTypeArgs() == ActualTypeArgInfos.size()); + ObjCObjectTL.setTypeArgsLAngleLoc(TypeArgsLAngleLoc); + ObjCObjectTL.setTypeArgsRAngleLoc(TypeArgsRAngleLoc); + for (unsigned i = 0, n = ActualTypeArgInfos.size(); i != n; ++i) + ObjCObjectTL.setTypeArgTInfo(i, ActualTypeArgInfos[i]); + } else { + ObjCObjectTL.setTypeArgsLAngleLoc(SourceLocation()); + ObjCObjectTL.setTypeArgsRAngleLoc(SourceLocation()); + } + + // Protocol qualifier information. + if (ObjCObjectTL.getNumProtocols() > 0) { + assert(ObjCObjectTL.getNumProtocols() == Protocols.size()); + ObjCObjectTL.setProtocolLAngleLoc(ProtocolLAngleLoc); + ObjCObjectTL.setProtocolRAngleLoc(ProtocolRAngleLoc); + for (unsigned i = 0, n = Protocols.size(); i != n; ++i) + ObjCObjectTL.setProtocolLoc(i, ProtocolLocs[i]); + } else { + ObjCObjectTL.setProtocolLAngleLoc(SourceLocation()); + ObjCObjectTL.setProtocolRAngleLoc(SourceLocation()); + } + + // Base type. + ObjCObjectTL.setHasBaseTypeAsWritten(true); + if (ObjCObjectTL.getType() == T) + ObjCObjectTL.getBaseLoc().initializeFullCopy(BaseTypeInfo->getTypeLoc()); + else + ObjCObjectTL.getBaseLoc().initialize(Context, Loc); + + // We're done. Return the completed type to the parser. + return SemaRef.CreateParsedType(Result, ResultTInfo); +} + +QualType SemaObjC::BuildObjCTypeParamType(const ObjCTypeParamDecl *Decl, + SourceLocation ProtocolLAngleLoc, + ArrayRef Protocols, + ArrayRef ProtocolLocs, + SourceLocation ProtocolRAngleLoc, + bool FailOnError) { + ASTContext &Context = getASTContext(); + QualType Result = QualType(Decl->getTypeForDecl(), 0); + if (!Protocols.empty()) { + bool HasError; + Result = Context.applyObjCProtocolQualifiers(Result, Protocols, + HasError); + if (HasError) { + Diag(SourceLocation(), diag::err_invalid_protocol_qualifiers) + << SourceRange(ProtocolLAngleLoc, ProtocolRAngleLoc); + if (FailOnError) Result = QualType(); + } + if (FailOnError && Result.isNull()) + return QualType(); + } + + return Result; +} + +/// Apply Objective-C type arguments to the given type. +static QualType applyObjCTypeArgs(Sema &S, SourceLocation loc, QualType type, + ArrayRef typeArgs, + SourceRange typeArgsRange, bool failOnError, + bool rebuilding) { + // We can only apply type arguments to an Objective-C class type. + const auto *objcObjectType = type->getAs(); + if (!objcObjectType || !objcObjectType->getInterface()) { + S.Diag(loc, diag::err_objc_type_args_non_class) + << type + << typeArgsRange; + + if (failOnError) + return QualType(); + return type; + } + + // The class type must be parameterized. + ObjCInterfaceDecl *objcClass = objcObjectType->getInterface(); + ObjCTypeParamList *typeParams = objcClass->getTypeParamList(); + if (!typeParams) { + S.Diag(loc, diag::err_objc_type_args_non_parameterized_class) + << objcClass->getDeclName() + << FixItHint::CreateRemoval(typeArgsRange); + + if (failOnError) + return QualType(); + + return type; + } + + // The type must not already be specialized. + if (objcObjectType->isSpecialized()) { + S.Diag(loc, diag::err_objc_type_args_specialized_class) + << type + << FixItHint::CreateRemoval(typeArgsRange); + + if (failOnError) + return QualType(); + + return type; + } + + // Check the type arguments. + SmallVector finalTypeArgs; + unsigned numTypeParams = typeParams->size(); + bool anyPackExpansions = false; + for (unsigned i = 0, n = typeArgs.size(); i != n; ++i) { + TypeSourceInfo *typeArgInfo = typeArgs[i]; + QualType typeArg = typeArgInfo->getType(); + + // Type arguments cannot have explicit qualifiers or nullability. + // We ignore indirect sources of these, e.g. behind typedefs or + // template arguments. + if (TypeLoc qual = typeArgInfo->getTypeLoc().findExplicitQualifierLoc()) { + bool diagnosed = false; + SourceRange rangeToRemove; + if (auto attr = qual.getAs()) { + rangeToRemove = attr.getLocalSourceRange(); + if (attr.getTypePtr()->getImmediateNullability()) { + typeArg = attr.getTypePtr()->getModifiedType(); + S.Diag(attr.getBeginLoc(), + diag::err_objc_type_arg_explicit_nullability) + << typeArg << FixItHint::CreateRemoval(rangeToRemove); + diagnosed = true; + } + } + + // When rebuilding, qualifiers might have gotten here through a + // final substitution. + if (!rebuilding && !diagnosed) { + S.Diag(qual.getBeginLoc(), diag::err_objc_type_arg_qualified) + << typeArg << typeArg.getQualifiers().getAsString() + << FixItHint::CreateRemoval(rangeToRemove); + } + } + + // Remove qualifiers even if they're non-local. + typeArg = typeArg.getUnqualifiedType(); + + finalTypeArgs.push_back(typeArg); + + if (typeArg->getAs()) + anyPackExpansions = true; + + // Find the corresponding type parameter, if there is one. + ObjCTypeParamDecl *typeParam = nullptr; + if (!anyPackExpansions) { + if (i < numTypeParams) { + typeParam = typeParams->begin()[i]; + } else { + // Too many arguments. + S.Diag(loc, diag::err_objc_type_args_wrong_arity) + << false + << objcClass->getDeclName() + << (unsigned)typeArgs.size() + << numTypeParams; + S.Diag(objcClass->getLocation(), diag::note_previous_decl) + << objcClass; + + if (failOnError) + return QualType(); + + return type; + } + } + + // Objective-C object pointer types must be substitutable for the bounds. + if (const auto *typeArgObjC = typeArg->getAs()) { + // If we don't have a type parameter to match against, assume + // everything is fine. There was a prior pack expansion that + // means we won't be able to match anything. + if (!typeParam) { + assert(anyPackExpansions && "Too many arguments?"); + continue; + } + + // Retrieve the bound. + QualType bound = typeParam->getUnderlyingType(); + const auto *boundObjC = bound->castAs(); + + // Determine whether the type argument is substitutable for the bound. + if (typeArgObjC->isObjCIdType()) { + // When the type argument is 'id', the only acceptable type + // parameter bound is 'id'. + if (boundObjC->isObjCIdType()) + continue; + } else if (S.Context.canAssignObjCInterfaces(boundObjC, typeArgObjC)) { + // Otherwise, we follow the assignability rules. + continue; + } + + // Diagnose the mismatch. + S.Diag(typeArgInfo->getTypeLoc().getBeginLoc(), + diag::err_objc_type_arg_does_not_match_bound) + << typeArg << bound << typeParam->getDeclName(); + S.Diag(typeParam->getLocation(), diag::note_objc_type_param_here) + << typeParam->getDeclName(); + + if (failOnError) + return QualType(); + + return type; + } + + // Block pointer types are permitted for unqualified 'id' bounds. + if (typeArg->isBlockPointerType()) { + // If we don't have a type parameter to match against, assume + // everything is fine. There was a prior pack expansion that + // means we won't be able to match anything. + if (!typeParam) { + assert(anyPackExpansions && "Too many arguments?"); + continue; + } + + // Retrieve the bound. + QualType bound = typeParam->getUnderlyingType(); + if (bound->isBlockCompatibleObjCPointerType(S.Context)) + continue; + + // Diagnose the mismatch. + S.Diag(typeArgInfo->getTypeLoc().getBeginLoc(), + diag::err_objc_type_arg_does_not_match_bound) + << typeArg << bound << typeParam->getDeclName(); + S.Diag(typeParam->getLocation(), diag::note_objc_type_param_here) + << typeParam->getDeclName(); + + if (failOnError) + return QualType(); + + return type; + } + + // Types that have __attribute__((NSObject)) are permitted. + if (typeArg->isObjCNSObjectType()) { + continue; + } + + // Dependent types will be checked at instantiation time. + if (typeArg->isDependentType()) { + continue; + } + + // Diagnose non-id-compatible type arguments. + S.Diag(typeArgInfo->getTypeLoc().getBeginLoc(), + diag::err_objc_type_arg_not_id_compatible) + << typeArg << typeArgInfo->getTypeLoc().getSourceRange(); + + if (failOnError) + return QualType(); + + return type; + } + + // Make sure we didn't have the wrong number of arguments. + if (!anyPackExpansions && finalTypeArgs.size() != numTypeParams) { + S.Diag(loc, diag::err_objc_type_args_wrong_arity) + << (typeArgs.size() < typeParams->size()) + << objcClass->getDeclName() + << (unsigned)finalTypeArgs.size() + << (unsigned)numTypeParams; + S.Diag(objcClass->getLocation(), diag::note_previous_decl) + << objcClass; + + if (failOnError) + return QualType(); + + return type; + } + + // Success. Form the specialized type. + return S.Context.getObjCObjectType(type, finalTypeArgs, { }, false); +} + +QualType SemaObjC::BuildObjCObjectType( + QualType BaseType, SourceLocation Loc, SourceLocation TypeArgsLAngleLoc, + ArrayRef TypeArgs, SourceLocation TypeArgsRAngleLoc, + SourceLocation ProtocolLAngleLoc, ArrayRef Protocols, + ArrayRef ProtocolLocs, SourceLocation ProtocolRAngleLoc, + bool FailOnError, bool Rebuilding) { + ASTContext &Context = getASTContext(); + QualType Result = BaseType; + if (!TypeArgs.empty()) { + Result = + applyObjCTypeArgs(SemaRef, Loc, Result, TypeArgs, + SourceRange(TypeArgsLAngleLoc, TypeArgsRAngleLoc), + FailOnError, Rebuilding); + if (FailOnError && Result.isNull()) + return QualType(); + } + + if (!Protocols.empty()) { + bool HasError; + Result = Context.applyObjCProtocolQualifiers(Result, Protocols, + HasError); + if (HasError) { + Diag(Loc, diag::err_invalid_protocol_qualifiers) + << SourceRange(ProtocolLAngleLoc, ProtocolRAngleLoc); + if (FailOnError) Result = QualType(); + } + if (FailOnError && Result.isNull()) + return QualType(); + } + + return Result; +} + +ParsedType SemaObjC::ActOnObjCInstanceType(SourceLocation Loc) { + ASTContext &Context = getASTContext(); + QualType T = Context.getObjCInstanceType(); + TypeSourceInfo *TInfo = Context.getTrivialTypeSourceInfo(T, Loc); + return SemaRef.CreateParsedType(T, TInfo); +} + +//===--- CHECK: Objective-C retain cycles ----------------------------------// + +namespace { + +struct RetainCycleOwner { + VarDecl *Variable = nullptr; + SourceRange Range; + SourceLocation Loc; + bool Indirect = false; + + RetainCycleOwner() = default; + + void setLocsFrom(Expr *e) { + Loc = e->getExprLoc(); + Range = e->getSourceRange(); + } +}; + +} // namespace + +/// Consider whether capturing the given variable can possibly lead to +/// a retain cycle. +static bool considerVariable(VarDecl *var, Expr *ref, RetainCycleOwner &owner) { + // In ARC, it's captured strongly iff the variable has __strong + // lifetime. In MRR, it's captured strongly if the variable is + // __block and has an appropriate type. + if (var->getType().getObjCLifetime() != Qualifiers::OCL_Strong) + return false; + + owner.Variable = var; + if (ref) + owner.setLocsFrom(ref); + return true; +} + +static bool findRetainCycleOwner(Sema &S, Expr *e, RetainCycleOwner &owner) { + while (true) { + e = e->IgnoreParens(); + if (CastExpr *cast = dyn_cast(e)) { + switch (cast->getCastKind()) { + case CK_BitCast: + case CK_LValueBitCast: + case CK_LValueToRValue: + case CK_ARCReclaimReturnedObject: + e = cast->getSubExpr(); + continue; + + default: + return false; + } + } + + if (ObjCIvarRefExpr *ref = dyn_cast(e)) { + ObjCIvarDecl *ivar = ref->getDecl(); + if (ivar->getType().getObjCLifetime() != Qualifiers::OCL_Strong) + return false; + + // Try to find a retain cycle in the base. + if (!findRetainCycleOwner(S, ref->getBase(), owner)) + return false; + + if (ref->isFreeIvar()) owner.setLocsFrom(ref); + owner.Indirect = true; + return true; + } + + if (DeclRefExpr *ref = dyn_cast(e)) { + VarDecl *var = dyn_cast(ref->getDecl()); + if (!var) return false; + return considerVariable(var, ref, owner); + } + + if (MemberExpr *member = dyn_cast(e)) { + if (member->isArrow()) return false; + + // Don't count this as an indirect ownership. + e = member->getBase(); + continue; + } + + if (PseudoObjectExpr *pseudo = dyn_cast(e)) { + // Only pay attention to pseudo-objects on property references. + ObjCPropertyRefExpr *pre + = dyn_cast(pseudo->getSyntacticForm() + ->IgnoreParens()); + if (!pre) return false; + if (pre->isImplicitProperty()) return false; + ObjCPropertyDecl *property = pre->getExplicitProperty(); + if (!property->isRetaining() && + !(property->getPropertyIvarDecl() && + property->getPropertyIvarDecl()->getType() + .getObjCLifetime() == Qualifiers::OCL_Strong)) + return false; + + owner.Indirect = true; + if (pre->isSuperReceiver()) { + owner.Variable = S.getCurMethodDecl()->getSelfDecl(); + if (!owner.Variable) + return false; + owner.Loc = pre->getLocation(); + owner.Range = pre->getSourceRange(); + return true; + } + e = const_cast(cast(pre->getBase()) + ->getSourceExpr()); + continue; + } + + // Array ivars? + + return false; + } +} + +namespace { + + struct FindCaptureVisitor : EvaluatedExprVisitor { + VarDecl *Variable; + Expr *Capturer = nullptr; + bool VarWillBeReased = false; + + FindCaptureVisitor(ASTContext &Context, VarDecl *variable) + : EvaluatedExprVisitor(Context), + Variable(variable) {} + + void VisitDeclRefExpr(DeclRefExpr *ref) { + if (ref->getDecl() == Variable && !Capturer) + Capturer = ref; + } + + void VisitObjCIvarRefExpr(ObjCIvarRefExpr *ref) { + if (Capturer) return; + Visit(ref->getBase()); + if (Capturer && ref->isFreeIvar()) + Capturer = ref; + } + + void VisitBlockExpr(BlockExpr *block) { + // Look inside nested blocks + if (block->getBlockDecl()->capturesVariable(Variable)) + Visit(block->getBlockDecl()->getBody()); + } + + void VisitOpaqueValueExpr(OpaqueValueExpr *OVE) { + if (Capturer) return; + if (OVE->getSourceExpr()) + Visit(OVE->getSourceExpr()); + } + + void VisitBinaryOperator(BinaryOperator *BinOp) { + if (!Variable || VarWillBeReased || BinOp->getOpcode() != BO_Assign) + return; + Expr *LHS = BinOp->getLHS(); + if (const DeclRefExpr *DRE = dyn_cast_or_null(LHS)) { + if (DRE->getDecl() != Variable) + return; + if (Expr *RHS = BinOp->getRHS()) { + RHS = RHS->IgnoreParenCasts(); + std::optional Value; + VarWillBeReased = + (RHS && (Value = RHS->getIntegerConstantExpr(Context)) && + *Value == 0); + } + } + } + }; + +} // namespace + +/// Check whether the given argument is a block which captures a +/// variable. +static Expr *findCapturingExpr(Sema &S, Expr *e, RetainCycleOwner &owner) { + assert(owner.Variable && owner.Loc.isValid()); + + e = e->IgnoreParenCasts(); + + // Look through [^{...} copy] and Block_copy(^{...}). + if (ObjCMessageExpr *ME = dyn_cast(e)) { + Selector Cmd = ME->getSelector(); + if (Cmd.isUnarySelector() && Cmd.getNameForSlot(0) == "copy") { + e = ME->getInstanceReceiver(); + if (!e) + return nullptr; + e = e->IgnoreParenCasts(); + } + } else if (CallExpr *CE = dyn_cast(e)) { + if (CE->getNumArgs() == 1) { + FunctionDecl *Fn = dyn_cast_or_null(CE->getCalleeDecl()); + if (Fn) { + const IdentifierInfo *FnI = Fn->getIdentifier(); + if (FnI && FnI->isStr("_Block_copy")) { + e = CE->getArg(0)->IgnoreParenCasts(); + } + } + } + } + + BlockExpr *block = dyn_cast(e); + if (!block || !block->getBlockDecl()->capturesVariable(owner.Variable)) + return nullptr; + + FindCaptureVisitor visitor(S.Context, owner.Variable); + visitor.Visit(block->getBlockDecl()->getBody()); + return visitor.VarWillBeReased ? nullptr : visitor.Capturer; +} + +static void diagnoseRetainCycle(Sema &S, Expr *capturer, + RetainCycleOwner &owner) { + assert(capturer); + assert(owner.Variable && owner.Loc.isValid()); + + S.Diag(capturer->getExprLoc(), diag::warn_arc_retain_cycle) + << owner.Variable << capturer->getSourceRange(); + S.Diag(owner.Loc, diag::note_arc_retain_cycle_owner) + << owner.Indirect << owner.Range; +} + +/// Check for a keyword selector that starts with the word 'add' or +/// 'set'. +static bool isSetterLikeSelector(Selector sel) { + if (sel.isUnarySelector()) return false; + + StringRef str = sel.getNameForSlot(0); + str = str.ltrim('_'); + if (str.starts_with("set")) + str = str.substr(3); + else if (str.starts_with("add")) { + // Specially allow 'addOperationWithBlock:'. + if (sel.getNumArgs() == 1 && str.starts_with("addOperationWithBlock")) + return false; + str = str.substr(3); + } else + return false; + + if (str.empty()) return true; + return !isLowercase(str.front()); +} + +static std::optional +GetNSMutableArrayArgumentIndex(SemaObjC &S, ObjCMessageExpr *Message) { + bool IsMutableArray = S.NSAPIObj->isSubclassOfNSClass( + Message->getReceiverInterface(), + NSAPI::ClassId_NSMutableArray); + if (!IsMutableArray) { + return std::nullopt; + } + + Selector Sel = Message->getSelector(); + + std::optional MKOpt = + S.NSAPIObj->getNSArrayMethodKind(Sel); + if (!MKOpt) { + return std::nullopt; + } + + NSAPI::NSArrayMethodKind MK = *MKOpt; + + switch (MK) { + case NSAPI::NSMutableArr_addObject: + case NSAPI::NSMutableArr_insertObjectAtIndex: + case NSAPI::NSMutableArr_setObjectAtIndexedSubscript: + return 0; + case NSAPI::NSMutableArr_replaceObjectAtIndex: + return 1; + + default: + return std::nullopt; + } + + return std::nullopt; +} + +static std::optional +GetNSMutableDictionaryArgumentIndex(SemaObjC &S, ObjCMessageExpr *Message) { + bool IsMutableDictionary = S.NSAPIObj->isSubclassOfNSClass( + Message->getReceiverInterface(), + NSAPI::ClassId_NSMutableDictionary); + if (!IsMutableDictionary) { + return std::nullopt; + } + + Selector Sel = Message->getSelector(); + + std::optional MKOpt = + S.NSAPIObj->getNSDictionaryMethodKind(Sel); + if (!MKOpt) { + return std::nullopt; + } + + NSAPI::NSDictionaryMethodKind MK = *MKOpt; + + switch (MK) { + case NSAPI::NSMutableDict_setObjectForKey: + case NSAPI::NSMutableDict_setValueForKey: + case NSAPI::NSMutableDict_setObjectForKeyedSubscript: + return 0; + + default: + return std::nullopt; + } + + return std::nullopt; +} + +static std::optional GetNSSetArgumentIndex(SemaObjC &S, + ObjCMessageExpr *Message) { + bool IsMutableSet = S.NSAPIObj->isSubclassOfNSClass( + Message->getReceiverInterface(), + NSAPI::ClassId_NSMutableSet); + + bool IsMutableOrderedSet = S.NSAPIObj->isSubclassOfNSClass( + Message->getReceiverInterface(), + NSAPI::ClassId_NSMutableOrderedSet); + if (!IsMutableSet && !IsMutableOrderedSet) { + return std::nullopt; + } + + Selector Sel = Message->getSelector(); + + std::optional MKOpt = + S.NSAPIObj->getNSSetMethodKind(Sel); + if (!MKOpt) { + return std::nullopt; + } + + NSAPI::NSSetMethodKind MK = *MKOpt; + + switch (MK) { + case NSAPI::NSMutableSet_addObject: + case NSAPI::NSOrderedSet_setObjectAtIndex: + case NSAPI::NSOrderedSet_setObjectAtIndexedSubscript: + case NSAPI::NSOrderedSet_insertObjectAtIndex: + return 0; + case NSAPI::NSOrderedSet_replaceObjectAtIndexWithObject: + return 1; + } + + return std::nullopt; +} + +void SemaObjC::CheckObjCCircularContainer(ObjCMessageExpr *Message) { + if (!Message->isInstanceMessage()) { + return; + } + + std::optional ArgOpt; + + if (!(ArgOpt = GetNSMutableArrayArgumentIndex(*this, Message)) && + !(ArgOpt = GetNSMutableDictionaryArgumentIndex(*this, Message)) && + !(ArgOpt = GetNSSetArgumentIndex(*this, Message))) { + return; + } + + int ArgIndex = *ArgOpt; + + Expr *Arg = Message->getArg(ArgIndex)->IgnoreImpCasts(); + if (OpaqueValueExpr *OE = dyn_cast(Arg)) { + Arg = OE->getSourceExpr()->IgnoreImpCasts(); + } + + if (Message->getReceiverKind() == ObjCMessageExpr::SuperInstance) { + if (DeclRefExpr *ArgRE = dyn_cast(Arg)) { + if (ArgRE->isObjCSelfExpr()) { + Diag(Message->getSourceRange().getBegin(), + diag::warn_objc_circular_container) + << ArgRE->getDecl() << StringRef("'super'"); + } + } + } else { + Expr *Receiver = Message->getInstanceReceiver()->IgnoreImpCasts(); + + if (OpaqueValueExpr *OE = dyn_cast(Receiver)) { + Receiver = OE->getSourceExpr()->IgnoreImpCasts(); + } + + if (DeclRefExpr *ReceiverRE = dyn_cast(Receiver)) { + if (DeclRefExpr *ArgRE = dyn_cast(Arg)) { + if (ReceiverRE->getDecl() == ArgRE->getDecl()) { + ValueDecl *Decl = ReceiverRE->getDecl(); + Diag(Message->getSourceRange().getBegin(), + diag::warn_objc_circular_container) + << Decl << Decl; + if (!ArgRE->isObjCSelfExpr()) { + Diag(Decl->getLocation(), + diag::note_objc_circular_container_declared_here) + << Decl; + } + } + } + } else if (ObjCIvarRefExpr *IvarRE = dyn_cast(Receiver)) { + if (ObjCIvarRefExpr *IvarArgRE = dyn_cast(Arg)) { + if (IvarRE->getDecl() == IvarArgRE->getDecl()) { + ObjCIvarDecl *Decl = IvarRE->getDecl(); + Diag(Message->getSourceRange().getBegin(), + diag::warn_objc_circular_container) + << Decl << Decl; + Diag(Decl->getLocation(), + diag::note_objc_circular_container_declared_here) + << Decl; + } + } + } + } +} + +/// Check a message send to see if it's likely to cause a retain cycle. +void SemaObjC::checkRetainCycles(ObjCMessageExpr *msg) { + // Only check instance methods whose selector looks like a setter. + if (!msg->isInstanceMessage() || !isSetterLikeSelector(msg->getSelector())) + return; + + // Try to find a variable that the receiver is strongly owned by. + RetainCycleOwner owner; + if (msg->getReceiverKind() == ObjCMessageExpr::Instance) { + if (!findRetainCycleOwner(SemaRef, msg->getInstanceReceiver(), owner)) + return; + } else { + assert(msg->getReceiverKind() == ObjCMessageExpr::SuperInstance); + owner.Variable = SemaRef.getCurMethodDecl()->getSelfDecl(); + owner.Loc = msg->getSuperLoc(); + owner.Range = msg->getSuperLoc(); + } + + // Check whether the receiver is captured by any of the arguments. + const ObjCMethodDecl *MD = msg->getMethodDecl(); + for (unsigned i = 0, e = msg->getNumArgs(); i != e; ++i) { + if (Expr *capturer = findCapturingExpr(SemaRef, msg->getArg(i), owner)) { + // noescape blocks should not be retained by the method. + if (MD && MD->parameters()[i]->hasAttr()) + continue; + return diagnoseRetainCycle(SemaRef, capturer, owner); + } + } +} + +/// Check a property assign to see if it's likely to cause a retain cycle. +void SemaObjC::checkRetainCycles(Expr *receiver, Expr *argument) { + RetainCycleOwner owner; + if (!findRetainCycleOwner(SemaRef, receiver, owner)) + return; + + if (Expr *capturer = findCapturingExpr(SemaRef, argument, owner)) + diagnoseRetainCycle(SemaRef, capturer, owner); +} + +void SemaObjC::checkRetainCycles(VarDecl *Var, Expr *Init) { + RetainCycleOwner Owner; + if (!considerVariable(Var, /*DeclRefExpr=*/nullptr, Owner)) + return; + + // Because we don't have an expression for the variable, we have to set the + // location explicitly here. + Owner.Loc = Var->getLocation(); + Owner.Range = Var->getSourceRange(); + + if (Expr *Capturer = findCapturingExpr(SemaRef, Init, Owner)) + diagnoseRetainCycle(SemaRef, Capturer, Owner); +} + +/// CheckObjCString - Checks that the argument to the builtin +/// CFString constructor is correct +/// Note: It might also make sense to do the UTF-16 conversion here (would +/// simplify the backend). +bool SemaObjC::CheckObjCString(Expr *Arg) { + Arg = Arg->IgnoreParenCasts(); + StringLiteral *Literal = dyn_cast(Arg); + + if (!Literal || !Literal->isOrdinary()) { + Diag(Arg->getBeginLoc(), diag::err_cfstring_literal_not_string_constant) + << Arg->getSourceRange(); + return true; + } + + if (Literal->containsNonAsciiOrNull()) { + StringRef String = Literal->getString(); + unsigned NumBytes = String.size(); + SmallVector ToBuf(NumBytes); + const llvm::UTF8 *FromPtr = (const llvm::UTF8 *)String.data(); + llvm::UTF16 *ToPtr = &ToBuf[0]; + + llvm::ConversionResult Result = + llvm::ConvertUTF8toUTF16(&FromPtr, FromPtr + NumBytes, &ToPtr, + ToPtr + NumBytes, llvm::strictConversion); + // Check for conversion failure. + if (Result != llvm::conversionOK) + Diag(Arg->getBeginLoc(), diag::warn_cfstring_truncated) + << Arg->getSourceRange(); + } + return false; +} + +bool SemaObjC::CheckObjCMethodCall(ObjCMethodDecl *Method, SourceLocation lbrac, + ArrayRef Args) { + Sema::VariadicCallType CallType = + Method->isVariadic() ? Sema::VariadicMethod : Sema::VariadicDoesNotApply; + + SemaRef.checkCall(Method, nullptr, /*ThisArg=*/nullptr, Args, + /*IsMemberFunction=*/false, lbrac, Method->getSourceRange(), + CallType); + + SemaRef.CheckTCBEnforcement(lbrac, Method); + + return false; +} + +const DeclContext *SemaObjC::getCurObjCLexicalContext() const { + const DeclContext *DC = SemaRef.getCurLexicalContext(); + // A category implicitly has the attribute of the interface. + if (const ObjCCategoryDecl *CatD = dyn_cast(DC)) + DC = CatD->getClassInterface(); + return DC; +} + +/// Retrieve the identifier "NSError". +IdentifierInfo *SemaObjC::getNSErrorIdent() { + if (!Ident_NSError) + Ident_NSError = SemaRef.PP.getIdentifierInfo("NSError"); + + return Ident_NSError; +} + +void SemaObjC::ActOnObjCContainerStartDefinition(ObjCContainerDecl *IDecl) { + assert(IDecl->getLexicalParent() == SemaRef.CurContext && + "The next DeclContext should be lexically contained in the current one."); + SemaRef.CurContext = IDecl; +} + +void SemaObjC::ActOnObjCContainerFinishDefinition() { + // Exit this scope of this interface definition. + SemaRef.PopDeclContext(); +} + +void SemaObjC::ActOnObjCTemporaryExitContainerContext(ObjCContainerDecl *ObjCCtx) { + assert(ObjCCtx == SemaRef.CurContext && "Mismatch of container contexts"); + SemaRef.OriginalLexicalContext = ObjCCtx; + ActOnObjCContainerFinishDefinition(); +} + +void SemaObjC::ActOnObjCReenterContainerContext(ObjCContainerDecl *ObjCCtx) { + ActOnObjCContainerStartDefinition(ObjCCtx); + SemaRef.OriginalLexicalContext = nullptr; +} + +/// Find the protocol with the given name, if any. +ObjCProtocolDecl *SemaObjC::LookupProtocol(IdentifierInfo *II, + SourceLocation IdLoc, + RedeclarationKind Redecl) { + Decl *D = SemaRef.LookupSingleName(SemaRef.TUScope, II, IdLoc, + Sema::LookupObjCProtocolName, Redecl); + return cast_or_null(D); +} + +/// Determine whether this is an Objective-C writeback conversion, +/// used for parameter passing when performing automatic reference counting. +/// +/// \param FromType The type we're converting form. +/// +/// \param ToType The type we're converting to. +/// +/// \param ConvertedType The type that will be produced after applying +/// this conversion. +bool SemaObjC::isObjCWritebackConversion(QualType FromType, QualType ToType, + QualType &ConvertedType) { + ASTContext &Context = getASTContext(); + if (!getLangOpts().ObjCAutoRefCount || + Context.hasSameUnqualifiedType(FromType, ToType)) + return false; + + // Parameter must be a pointer to __autoreleasing (with no other qualifiers). + QualType ToPointee; + if (const PointerType *ToPointer = ToType->getAs()) + ToPointee = ToPointer->getPointeeType(); + else + return false; + + Qualifiers ToQuals = ToPointee.getQualifiers(); + if (!ToPointee->isObjCLifetimeType() || + ToQuals.getObjCLifetime() != Qualifiers::OCL_Autoreleasing || + !ToQuals.withoutObjCLifetime().empty()) + return false; + + // Argument must be a pointer to __strong to __weak. + QualType FromPointee; + if (const PointerType *FromPointer = FromType->getAs()) + FromPointee = FromPointer->getPointeeType(); + else + return false; + + Qualifiers FromQuals = FromPointee.getQualifiers(); + if (!FromPointee->isObjCLifetimeType() || + (FromQuals.getObjCLifetime() != Qualifiers::OCL_Strong && + FromQuals.getObjCLifetime() != Qualifiers::OCL_Weak)) + return false; + + // Make sure that we have compatible qualifiers. + FromQuals.setObjCLifetime(Qualifiers::OCL_Autoreleasing); + if (!ToQuals.compatiblyIncludes(FromQuals)) + return false; + + // Remove qualifiers from the pointee type we're converting from; they + // aren't used in the compatibility check belong, and we'll be adding back + // qualifiers (with __autoreleasing) if the compatibility check succeeds. + FromPointee = FromPointee.getUnqualifiedType(); + + // The unqualified form of the pointee types must be compatible. + ToPointee = ToPointee.getUnqualifiedType(); + bool IncompatibleObjC; + if (Context.typesAreCompatible(FromPointee, ToPointee)) + FromPointee = ToPointee; + else if (!SemaRef.isObjCPointerConversion(FromPointee, ToPointee, FromPointee, + IncompatibleObjC)) + return false; + + /// Construct the type we're converting to, which is a pointer to + /// __autoreleasing pointee. + FromPointee = Context.getQualifiedType(FromPointee, FromQuals); + ConvertedType = Context.getPointerType(FromPointee); + return true; +} + +/// CheckSubscriptingKind - This routine decide what type +/// of indexing represented by "FromE" is being done. +SemaObjC::ObjCSubscriptKind SemaObjC::CheckSubscriptingKind(Expr *FromE) { + // If the expression already has integral or enumeration type, we're golden. + QualType T = FromE->getType(); + if (T->isIntegralOrEnumerationType()) + return SemaObjC::OS_Array; + + // If we don't have a class type in C++, there's no way we can get an + // expression of integral or enumeration type. + const RecordType *RecordTy = T->getAs(); + if (!RecordTy && + (T->isObjCObjectPointerType() || T->isVoidPointerType())) + // All other scalar cases are assumed to be dictionary indexing which + // caller handles, with diagnostics if needed. + return SemaObjC::OS_Dictionary; + if (!getLangOpts().CPlusPlus || + !RecordTy || RecordTy->isIncompleteType()) { + // No indexing can be done. Issue diagnostics and quit. + const Expr *IndexExpr = FromE->IgnoreParenImpCasts(); + if (isa(IndexExpr)) + Diag(FromE->getExprLoc(), diag::err_objc_subscript_pointer) + << T << FixItHint::CreateInsertion(FromE->getExprLoc(), "@"); + else + Diag(FromE->getExprLoc(), diag::err_objc_subscript_type_conversion) + << T; + return SemaObjC::OS_Error; + } + + // We must have a complete class type. + if (SemaRef.RequireCompleteType(FromE->getExprLoc(), T, + diag::err_objc_index_incomplete_class_type, FromE)) + return SemaObjC::OS_Error; + + // Look for a conversion to an integral, enumeration type, or + // objective-C pointer type. + int NoIntegrals=0, NoObjCIdPointers=0; + SmallVector ConversionDecls; + + for (NamedDecl *D : cast(RecordTy->getDecl()) + ->getVisibleConversionFunctions()) { + if (CXXConversionDecl *Conversion = + dyn_cast(D->getUnderlyingDecl())) { + QualType CT = Conversion->getConversionType().getNonReferenceType(); + if (CT->isIntegralOrEnumerationType()) { + ++NoIntegrals; + ConversionDecls.push_back(Conversion); + } + else if (CT->isObjCIdType() ||CT->isBlockPointerType()) { + ++NoObjCIdPointers; + ConversionDecls.push_back(Conversion); + } + } + } + if (NoIntegrals ==1 && NoObjCIdPointers == 0) + return SemaObjC::OS_Array; + if (NoIntegrals == 0 && NoObjCIdPointers == 1) + return SemaObjC::OS_Dictionary; + if (NoIntegrals == 0 && NoObjCIdPointers == 0) { + // No conversion function was found. Issue diagnostic and return. + Diag(FromE->getExprLoc(), diag::err_objc_subscript_type_conversion) + << FromE->getType(); + return SemaObjC::OS_Error; + } + Diag(FromE->getExprLoc(), diag::err_objc_multiple_subscript_type_conversion) + << FromE->getType(); + for (unsigned int i = 0; i < ConversionDecls.size(); i++) + Diag(ConversionDecls[i]->getLocation(), + diag::note_conv_function_declared_at); + + return SemaObjC::OS_Error; +} + +void SemaObjC::AddCFAuditedAttribute(Decl *D) { + ASTContext &Context = getASTContext(); + IdentifierInfo *Ident; + SourceLocation Loc; + std::tie(Ident, Loc) = SemaRef.PP.getPragmaARCCFCodeAuditedInfo(); + if (!Loc.isValid()) return; + + // Don't add a redundant or conflicting attribute. + if (D->hasAttr() || + D->hasAttr()) + return; + + AttributeCommonInfo Info(Ident, SourceRange(Loc), + AttributeCommonInfo::Form::Pragma()); + D->addAttr(CFAuditedTransferAttr::CreateImplicit(Context, Info)); +} + +bool SemaObjC::isCFError(RecordDecl *RD) { + // If we already know about CFError, test it directly. + if (CFError) + return CFError == RD; + + // Check whether this is CFError, which we identify based on its bridge to + // NSError. CFErrorRef used to be declared with "objc_bridge" but is now + // declared with "objc_bridge_mutable", so look for either one of the two + // attributes. + if (RD->getTagKind() == TagTypeKind::Struct) { + IdentifierInfo *bridgedType = nullptr; + if (auto bridgeAttr = RD->getAttr()) + bridgedType = bridgeAttr->getBridgedType(); + else if (auto bridgeAttr = RD->getAttr()) + bridgedType = bridgeAttr->getBridgedType(); + + if (bridgedType == getNSErrorIdent()) { + CFError = RD; + return true; + } + } + + return false; +} + +} // namespace clang diff --git a/clang/lib/Sema/SemaObjCProperty.cpp b/clang/lib/Sema/SemaObjCProperty.cpp index 222a65a13dd0b..c0ae904dfb9fe 100644 --- a/clang/lib/Sema/SemaObjCProperty.cpp +++ b/clang/lib/Sema/SemaObjCProperty.cpp @@ -11,7 +11,7 @@ // //===----------------------------------------------------------------------===// -#include "clang/Sema/SemaInternal.h" +#include "clang/Sema/SemaObjC.h" #include "clang/AST/ASTMutationListener.h" #include "clang/AST/DeclObjC.h" #include "clang/AST/ExprCXX.h" @@ -20,6 +20,7 @@ #include "clang/Lex/Lexer.h" #include "clang/Lex/Preprocessor.h" #include "clang/Sema/Initialization.h" +#include "clang/Sema/SemaInternal.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/SmallString.h" @@ -114,7 +115,7 @@ CheckPropertyAgainstProtocol(Sema &S, ObjCPropertyDecl *Prop, // Look for a property with the same name. if (ObjCPropertyDecl *ProtoProp = Proto->getProperty( Prop->getIdentifier(), Prop->isInstanceProperty())) { - S.DiagnosePropertyMismatch(Prop, ProtoProp, Proto->getIdentifier(), true); + S.ObjC().DiagnosePropertyMismatch(Prop, ProtoProp, Proto->getIdentifier(), true); return; } @@ -169,7 +170,7 @@ static unsigned getOwnershipRule(unsigned attr) { return result; } -Decl *Sema::ActOnProperty(Scope *S, SourceLocation AtLoc, +Decl *SemaObjC::ActOnProperty(Scope *S, SourceLocation AtLoc, SourceLocation LParenLoc, FieldDeclarator &FD, ObjCDeclSpec &ODS, @@ -180,17 +181,17 @@ Decl *Sema::ActOnProperty(Scope *S, SourceLocation AtLoc, unsigned Attributes = ODS.getPropertyAttributes(); FD.D.setObjCWeakProperty((Attributes & ObjCPropertyAttribute::kind_weak) != 0); - TypeSourceInfo *TSI = GetTypeForDeclarator(FD.D); + TypeSourceInfo *TSI = SemaRef.GetTypeForDeclarator(FD.D); QualType T = TSI->getType(); if (!getOwnershipRule(Attributes)) { - Attributes |= deducePropertyOwnershipFromType(*this, T); + Attributes |= deducePropertyOwnershipFromType(SemaRef, T); } bool isReadWrite = ((Attributes & ObjCPropertyAttribute::kind_readwrite) || // default is readwrite! !(Attributes & ObjCPropertyAttribute::kind_readonly)); // Proceed with constructing the ObjCPropertyDecls. - ObjCContainerDecl *ClassDecl = cast(CurContext); + ObjCContainerDecl *ClassDecl = cast(SemaRef.CurContext); ObjCPropertyDecl *Res = nullptr; if (ObjCCategoryDecl *CDecl = dyn_cast(ClassDecl)) { if (CDecl->IsClassExtension()) { @@ -223,7 +224,7 @@ Decl *Sema::ActOnProperty(Scope *S, SourceLocation AtLoc, // Check consistency if the type has explicit ownership qualification. if (Res->getType().getObjCLifetime()) - checkPropertyDeclWithOwnership(*this, Res); + checkPropertyDeclWithOwnership(SemaRef, Res); llvm::SmallPtrSet KnownProtos; if (ObjCInterfaceDecl *IFace = dyn_cast(ClassDecl)) { @@ -243,12 +244,12 @@ Decl *Sema::ActOnProperty(Scope *S, SourceLocation AtLoc, if (FoundInSuper) { // Also compare the property against a property in our protocols. for (auto *P : CurrentInterfaceDecl->protocols()) { - CheckPropertyAgainstProtocol(*this, Res, P, KnownProtos); + CheckPropertyAgainstProtocol(SemaRef, Res, P, KnownProtos); } } else { // Slower path: look in all protocols we referenced. for (auto *P : IFace->all_referenced_protocols()) { - CheckPropertyAgainstProtocol(*this, Res, P, KnownProtos); + CheckPropertyAgainstProtocol(SemaRef, Res, P, KnownProtos); } } } else if (ObjCCategoryDecl *Cat = dyn_cast(ClassDecl)) { @@ -257,14 +258,14 @@ Decl *Sema::ActOnProperty(Scope *S, SourceLocation AtLoc, // when property in class extension is constructed. if (!Cat->IsClassExtension()) for (auto *P : Cat->protocols()) - CheckPropertyAgainstProtocol(*this, Res, P, KnownProtos); + CheckPropertyAgainstProtocol(SemaRef, Res, P, KnownProtos); } else { ObjCProtocolDecl *Proto = cast(ClassDecl); for (auto *P : Proto->protocols()) - CheckPropertyAgainstProtocol(*this, Res, P, KnownProtos); + CheckPropertyAgainstProtocol(SemaRef, Res, P, KnownProtos); } - ActOnDocumentableDecl(Res); + SemaRef.ActOnDocumentableDecl(Res); return Res; } @@ -402,7 +403,7 @@ static void checkAtomicPropertyMismatch(Sema &S, } ObjCPropertyDecl * -Sema::HandlePropertyInClassExtension(Scope *S, +SemaObjC::HandlePropertyInClassExtension(Scope *S, SourceLocation AtLoc, SourceLocation LParenLoc, FieldDeclarator &FD, @@ -416,9 +417,9 @@ Sema::HandlePropertyInClassExtension(Scope *S, QualType T, TypeSourceInfo *TSI, tok::ObjCKeywordKind MethodImplKind) { - ObjCCategoryDecl *CDecl = cast(CurContext); + ObjCCategoryDecl *CDecl = cast(SemaRef.CurContext); // Diagnose if this property is already in continuation class. - DeclContext *DC = CurContext; + DeclContext *DC = SemaRef.CurContext; const IdentifierInfo *PropertyId = FD.D.getIdentifier(); ObjCInterfaceDecl *CCPrimary = CDecl->getClassInterface(); @@ -515,7 +516,7 @@ Sema::HandlePropertyInClassExtension(Scope *S, isReadWrite, Attributes, AttributesAsWritten, T, TSI, MethodImplKind, DC); - + ASTContext &Context = getASTContext(); // If there was no declaration of a property with the same name in // the primary class, we're done. if (!PIDecl) { @@ -536,7 +537,7 @@ Sema::HandlePropertyInClassExtension(Scope *S, QualType ClassExtPropertyT = Context.getCanonicalType(PDecl->getType()); if (!isa(PrimaryClassPropertyT) || !isa(ClassExtPropertyT) || - (!isObjCPointerConversion(ClassExtPropertyT, PrimaryClassPropertyT, + (!SemaRef.isObjCPointerConversion(ClassExtPropertyT, PrimaryClassPropertyT, ConvertedType, IncompatibleObjC)) || IncompatibleObjC) { Diag(AtLoc, @@ -548,14 +549,14 @@ Sema::HandlePropertyInClassExtension(Scope *S, // Check that atomicity of property in class extension matches the previous // declaration. - checkAtomicPropertyMismatch(*this, PIDecl, PDecl, true); + checkAtomicPropertyMismatch(SemaRef, PIDecl, PDecl, true); // Make sure getter/setter are appropriately synthesized. ProcessPropertyDecl(PDecl); return PDecl; } -ObjCPropertyDecl *Sema::CreatePropertyDecl(Scope *S, +ObjCPropertyDecl *SemaObjC::CreatePropertyDecl(Scope *S, ObjCContainerDecl *CDecl, SourceLocation AtLoc, SourceLocation LParenLoc, @@ -571,6 +572,7 @@ ObjCPropertyDecl *Sema::CreatePropertyDecl(Scope *S, TypeSourceInfo *TInfo, tok::ObjCKeywordKind MethodImplKind, DeclContext *lexicalDC){ + ASTContext &Context = getASTContext(); const IdentifierInfo *PropertyId = FD.D.getIdentifier(); // Property defaults to 'assign' if it is readwrite, unless this is ARC @@ -603,7 +605,7 @@ ObjCPropertyDecl *Sema::CreatePropertyDecl(Scope *S, if (T->isObjCObjectType()) { SourceLocation StarLoc = TInfo->getTypeLoc().getEndLoc(); - StarLoc = getLocForEndOfToken(StarLoc); + StarLoc = SemaRef.getLocForEndOfToken(StarLoc); Diag(FD.D.getIdentifierLoc(), diag::err_statically_allocated_object) << FixItHint::CreateInsertion(StarLoc, "*"); T = Context.getObjCObjectPointerType(T); @@ -645,7 +647,7 @@ ObjCPropertyDecl *Sema::CreatePropertyDecl(Scope *S, PDecl->setPropertyAttributesAsWritten( makePropertyAttributesAsWritten(AttributesAsWritten)); - ProcessDeclAttributes(S, PDecl, FD.D); + SemaRef.ProcessDeclAttributes(S, PDecl, FD.D); if (Attributes & ObjCPropertyAttribute::kind_readonly) PDecl->setPropertyAttributes(ObjCPropertyAttribute::kind_readonly); @@ -1074,7 +1076,7 @@ RedeclarePropertyAccessor(ASTContext &Context, ObjCImplementationDecl *Impl, /// builds the AST node for a property implementation declaration; declared /// as \@synthesize or \@dynamic. /// -Decl *Sema::ActOnPropertyImplDecl(Scope *S, +Decl *SemaObjC::ActOnPropertyImplDecl(Scope *S, SourceLocation AtLoc, SourceLocation PropertyLoc, bool Synthesize, @@ -1082,8 +1084,9 @@ Decl *Sema::ActOnPropertyImplDecl(Scope *S, IdentifierInfo *PropertyIvar, SourceLocation PropertyIvarLoc, ObjCPropertyQueryKind QueryKind) { + ASTContext &Context = getASTContext(); ObjCContainerDecl *ClassImpDecl = - dyn_cast(CurContext); + dyn_cast(SemaRef.CurContext); // Make sure we have a context for the property implementation declaration. if (!ClassImpDecl) { Diag(AtLoc, diag::err_missing_property_context); @@ -1167,7 +1170,7 @@ Decl *Sema::ActOnPropertyImplDecl(Scope *S, } } if (Synthesize && isa(property->getDeclContext())) - property = SelectPropertyForSynthesisFromProtocols(*this, AtLoc, IDecl, + property = SelectPropertyForSynthesisFromProtocols(SemaRef, AtLoc, IDecl, property); } else if ((CatImplClass = dyn_cast(ClassImpDecl))) { @@ -1212,7 +1215,7 @@ Decl *Sema::ActOnPropertyImplDecl(Scope *S, QualType PropType = property->getType(); QualType PropertyIvarType = PropType.getNonReferenceType(); - if (RequireCompleteType(PropertyDiagLoc, PropertyIvarType, + if (SemaRef.RequireCompleteType(PropertyDiagLoc, PropertyIvarType, diag::err_incomplete_synthesized_property, property->getDeclName())) { Diag(property->getLocation(), diag::note_property_declare); @@ -1320,10 +1323,10 @@ Decl *Sema::ActOnPropertyImplDecl(Scope *S, PropertyIvarType, /*TInfo=*/nullptr, ObjCIvarDecl::Private, (Expr *)nullptr, true); - if (RequireNonAbstractType(PropertyIvarLoc, + if (SemaRef.RequireNonAbstractType(PropertyIvarLoc, PropertyIvarType, diag::err_abstract_type_in_decl, - AbstractSynthesizedIvarType)) { + Sema::AbstractSynthesizedIvarType)) { Diag(property->getLocation(), diag::note_property_declare); // An abstract type is as bad as an incomplete type. CompleteTypeErr = true; @@ -1367,9 +1370,9 @@ Decl *Sema::ActOnPropertyImplDecl(Scope *S, PropertyIvarType->castAs(), IvarType->castAs()); else { - compat = (CheckAssignmentConstraints(PropertyIvarLoc, PropertyIvarType, + compat = (SemaRef.CheckAssignmentConstraints(PropertyIvarLoc, PropertyIvarType, IvarType) - == Compatible); + == Sema::Compatible); } if (!compat) { Diag(PropertyDiagLoc, diag::err_property_ivar_type) @@ -1413,14 +1416,14 @@ Decl *Sema::ActOnPropertyImplDecl(Scope *S, } if (getLangOpts().ObjCAutoRefCount || isARCWeak || Ivar->getType().getObjCLifetime()) - checkARCPropertyImpl(*this, PropertyLoc, property, Ivar); + checkARCPropertyImpl(SemaRef, PropertyLoc, property, Ivar); } else if (PropertyIvar) // @dynamic Diag(PropertyDiagLoc, diag::err_dynamic_property_ivar_decl); assert (property && "ActOnPropertyImplDecl - property declaration missing"); ObjCPropertyImplDecl *PIDecl = - ObjCPropertyImplDecl::Create(Context, CurContext, AtLoc, PropertyLoc, + ObjCPropertyImplDecl::Create(Context, SemaRef.CurContext, AtLoc, PropertyLoc, property, (Synthesize ? ObjCPropertyImplDecl::Synthesize @@ -1449,12 +1452,12 @@ Decl *Sema::ActOnPropertyImplDecl(Scope *S, // For Objective-C++, need to synthesize the AST for the IVAR object to be // returned by the getter as it must conform to C++'s copy-return rules. // FIXME. Eventually we want to do this for Objective-C as well. - SynthesizedFunctionScope Scope(*this, getterMethod); + Sema::SynthesizedFunctionScope Scope(SemaRef, getterMethod); ImplicitParamDecl *SelfDecl = getterMethod->getSelfDecl(); DeclRefExpr *SelfExpr = new (Context) DeclRefExpr(Context, SelfDecl, false, SelfDecl->getType(), VK_LValue, PropertyDiagLoc); - MarkDeclRefReferenced(SelfExpr); + SemaRef.MarkDeclRefReferenced(SelfExpr); Expr *LoadSelfExpr = ImplicitCastExpr::Create( Context, SelfDecl->getType(), CK_LValueToRValue, SelfExpr, nullptr, VK_PRValue, FPOptionsOverride()); @@ -1464,14 +1467,14 @@ Decl *Sema::ActOnPropertyImplDecl(Scope *S, PropertyDiagLoc, Ivar->getLocation(), LoadSelfExpr, true, true); - ExprResult Res = PerformCopyInitialization( + ExprResult Res = SemaRef.PerformCopyInitialization( InitializedEntity::InitializeResult(PropertyDiagLoc, getterMethod->getReturnType()), PropertyDiagLoc, IvarRefExpr); if (!Res.isInvalid()) { Expr *ResExpr = Res.getAs(); if (ResExpr) - ResExpr = MaybeCreateExprWithCleanups(ResExpr); + ResExpr = SemaRef.MaybeCreateExprWithCleanups(ResExpr); PIDecl->setGetterCXXConstructor(ResExpr); } } @@ -1511,12 +1514,12 @@ Decl *Sema::ActOnPropertyImplDecl(Scope *S, if (getLangOpts().CPlusPlus && Synthesize && !CompleteTypeErr && Ivar->getType()->isRecordType()) { // FIXME. Eventually we want to do this for Objective-C as well. - SynthesizedFunctionScope Scope(*this, setterMethod); + Sema::SynthesizedFunctionScope Scope(SemaRef, setterMethod); ImplicitParamDecl *SelfDecl = setterMethod->getSelfDecl(); DeclRefExpr *SelfExpr = new (Context) DeclRefExpr(Context, SelfDecl, false, SelfDecl->getType(), VK_LValue, PropertyDiagLoc); - MarkDeclRefReferenced(SelfExpr); + SemaRef.MarkDeclRefReferenced(SelfExpr); Expr *LoadSelfExpr = ImplicitCastExpr::Create( Context, SelfDecl->getType(), CK_LValueToRValue, SelfExpr, nullptr, VK_PRValue, FPOptionsOverride()); @@ -1531,8 +1534,8 @@ Decl *Sema::ActOnPropertyImplDecl(Scope *S, QualType T = Param->getType().getNonReferenceType(); DeclRefExpr *rhs = new (Context) DeclRefExpr(Context, Param, false, T, VK_LValue, PropertyDiagLoc); - MarkDeclRefReferenced(rhs); - ExprResult Res = BuildBinOp(S, PropertyDiagLoc, + SemaRef.MarkDeclRefReferenced(rhs); + ExprResult Res = SemaRef.BuildBinOp(S, PropertyDiagLoc, BO_Assign, lhs, rhs); if (property->getPropertyAttributes() & ObjCPropertyAttribute::kind_atomic) { @@ -1631,10 +1634,11 @@ Decl *Sema::ActOnPropertyImplDecl(Scope *S, /// attributes and types and warns on a variety of inconsistencies. /// void -Sema::DiagnosePropertyMismatch(ObjCPropertyDecl *Property, +SemaObjC::DiagnosePropertyMismatch(ObjCPropertyDecl *Property, ObjCPropertyDecl *SuperProperty, const IdentifierInfo *inheritedName, bool OverridingProtocolProperty) { + ASTContext &Context = getASTContext(); ObjCPropertyAttribute::Kind CAttr = Property->getPropertyAttributes(); ObjCPropertyAttribute::Kind SAttr = SuperProperty->getPropertyAttributes(); @@ -1669,7 +1673,7 @@ Sema::DiagnosePropertyMismatch(ObjCPropertyDecl *Property, // Check for nonatomic; note that nonatomic is effectively // meaningless for readonly properties, so don't diagnose if the // atomic property is 'readonly'. - checkAtomicPropertyMismatch(*this, SuperProperty, Property, false); + checkAtomicPropertyMismatch(SemaRef, SuperProperty, Property, false); // Readonly properties from protocols can be implemented as "readwrite" // with a custom setter name. if (Property->getSetterName() != SuperProperty->getSetterName() && @@ -1695,7 +1699,7 @@ Sema::DiagnosePropertyMismatch(ObjCPropertyDecl *Property, // FIXME. For future support of covariant property types, revisit this. bool IncompatibleObjC = false; QualType ConvertedType; - if (!isObjCPointerConversion(RHSType, LHSType, + if (!SemaRef.isObjCPointerConversion(RHSType, LHSType, ConvertedType, IncompatibleObjC) || IncompatibleObjC) { Diag(Property->getLocation(), diag::warn_property_types_are_incompatible) @@ -1705,9 +1709,10 @@ Sema::DiagnosePropertyMismatch(ObjCPropertyDecl *Property, } } -bool Sema::DiagnosePropertyAccessorMismatch(ObjCPropertyDecl *property, +bool SemaObjC::DiagnosePropertyAccessorMismatch(ObjCPropertyDecl *property, ObjCMethodDecl *GetterMethod, SourceLocation Loc) { + ASTContext &Context = getASTContext(); if (!GetterMethod) return false; QualType GetterType = GetterMethod->getReturnType().getNonReferenceType(); @@ -1721,8 +1726,8 @@ bool Sema::DiagnosePropertyAccessorMismatch(ObjCPropertyDecl *property, PropertyRValueType->getAs()) && (getterObjCPtr = GetterType->getAs())) compat = Context.canAssignObjCInterfaces(getterObjCPtr, propertyObjCPtr); - else if (CheckAssignmentConstraints(Loc, GetterType, PropertyRValueType) - != Compatible) { + else if (SemaRef.CheckAssignmentConstraints(Loc, GetterType, PropertyRValueType) + != Sema::Compatible) { Diag(Loc, diag::err_property_accessor_type) << property->getDeclName() << PropertyRValueType << GetterMethod->getSelector() << GetterType; @@ -1832,7 +1837,7 @@ static void CollectSuperClassPropertyImplementations(ObjCInterfaceDecl *CDecl, /// an ivar synthesized for 'Method' and 'Method' is a property accessor /// declared in class 'IFace'. bool -Sema::IvarBacksCurrentMethodAccessor(ObjCInterfaceDecl *IFace, +SemaObjC::IvarBacksCurrentMethodAccessor(ObjCInterfaceDecl *IFace, ObjCMethodDecl *Method, ObjCIvarDecl *IV) { if (!IV->getSynthesize()) return false; @@ -1883,9 +1888,10 @@ static bool SuperClassImplementsProperty(ObjCInterfaceDecl *IDecl, /// Default synthesizes all properties which must be synthesized /// in class's \@implementation. -void Sema::DefaultSynthesizeProperties(Scope *S, ObjCImplDecl *IMPDecl, +void SemaObjC::DefaultSynthesizeProperties(Scope *S, ObjCImplDecl *IMPDecl, ObjCInterfaceDecl *IDecl, SourceLocation AtEnd) { + ASTContext &Context = getASTContext(); ObjCInterfaceDecl::PropertyMap PropMap; IDecl->collectPropertiesToImplement(PropMap); if (PropMap.empty()) @@ -1977,9 +1983,9 @@ void Sema::DefaultSynthesizeProperties(Scope *S, ObjCImplDecl *IMPDecl, } } -void Sema::DefaultSynthesizeProperties(Scope *S, Decl *D, +void SemaObjC::DefaultSynthesizeProperties(Scope *S, Decl *D, SourceLocation AtEnd) { - if (!LangOpts.ObjCDefaultSynthProperties || LangOpts.ObjCRuntime.isFragile()) + if (!getLangOpts().ObjCDefaultSynthProperties || getLangOpts().ObjCRuntime.isFragile()) return; ObjCImplementationDecl *IC=dyn_cast_or_null(D); if (!IC) @@ -2026,7 +2032,7 @@ static void DiagnoseUnimplementedAccessor( } } -void Sema::DiagnoseUnimplementedProperties(Scope *S, ObjCImplDecl* IMPDecl, +void SemaObjC::DiagnoseUnimplementedProperties(Scope *S, ObjCImplDecl* IMPDecl, ObjCContainerDecl *CDecl, bool SynthesizeProperties) { ObjCContainerDecl::PropertyMap PropMap; @@ -2124,16 +2130,16 @@ void Sema::DiagnoseUnimplementedProperties(Scope *S, ObjCImplDecl* IMPDecl, continue; // Diagnose unimplemented getters and setters. - DiagnoseUnimplementedAccessor(*this, + DiagnoseUnimplementedAccessor(SemaRef, PrimaryClass, Prop->getGetterName(), IMPDecl, CDecl, C, Prop, InsMap); if (!Prop->isReadOnly()) - DiagnoseUnimplementedAccessor(*this, + DiagnoseUnimplementedAccessor(SemaRef, PrimaryClass, Prop->getSetterName(), IMPDecl, CDecl, C, Prop, InsMap); } } -void Sema::diagnoseNullResettableSynthesizedSetters(const ObjCImplDecl *impDecl) { +void SemaObjC::diagnoseNullResettableSynthesizedSetters(const ObjCImplDecl *impDecl) { for (const auto *propertyImpl : impDecl->property_impls()) { const auto *property = propertyImpl->getPropertyDecl(); // Warn about null_resettable properties with synthesized setters, @@ -2159,7 +2165,7 @@ void Sema::diagnoseNullResettableSynthesizedSetters(const ObjCImplDecl *impDecl) } void -Sema::AtomicPropertySetterGetterRules (ObjCImplDecl* IMPDecl, +SemaObjC::AtomicPropertySetterGetterRules (ObjCImplDecl* IMPDecl, ObjCInterfaceDecl* IDecl) { // Rules apply in non-GC mode only if (getLangOpts().getGC() != LangOptions::NonGC) @@ -2232,7 +2238,7 @@ Sema::AtomicPropertySetterGetterRules (ObjCImplDecl* IMPDecl, !(AttributesAsWritten & ObjCPropertyAttribute::kind_atomic)) { // @property () ... case. SourceLocation AfterLParen = - getLocForEndOfToken(Property->getLParenLoc()); + SemaRef.getLocForEndOfToken(Property->getLParenLoc()); StringRef NonatomicStr = AttributesAsWritten? "nonatomic, " : "nonatomic"; Diag(Property->getLocation(), @@ -2253,7 +2259,7 @@ Sema::AtomicPropertySetterGetterRules (ObjCImplDecl* IMPDecl, } } -void Sema::DiagnoseOwningPropertyGetterSynthesis(const ObjCImplementationDecl *D) { +void SemaObjC::DiagnoseOwningPropertyGetterSynthesis(const ObjCImplementationDecl *D) { if (getLangOpts().getGC() == LangOptions::GCOnly) return; @@ -2288,7 +2294,7 @@ void Sema::DiagnoseOwningPropertyGetterSynthesis(const ObjCImplementationDecl *D fixItLoc = getterRedecl->getEndLoc(); } - Preprocessor &PP = getPreprocessor(); + Preprocessor &PP = SemaRef.getPreprocessor(); TokenValue tokens[] = { tok::kw___attribute, tok::l_paren, tok::l_paren, PP.getIdentifierInfo("objc_method_family"), tok::l_paren, @@ -2312,7 +2318,7 @@ void Sema::DiagnoseOwningPropertyGetterSynthesis(const ObjCImplementationDecl *D } } -void Sema::DiagnoseMissingDesignatedInitOverrides( +void SemaObjC::DiagnoseMissingDesignatedInitOverrides( const ObjCImplementationDecl *ImplD, const ObjCInterfaceDecl *IFD) { assert(IFD->hasDesignatedInitializers()); @@ -2371,7 +2377,8 @@ static void AddPropertyAttrs(Sema &S, ObjCMethodDecl *PropertyMethod, /// have the property type and issue diagnostics if they don't. /// Also synthesize a getter/setter method if none exist (and update the /// appropriate lookup tables. -void Sema::ProcessPropertyDecl(ObjCPropertyDecl *property) { +void SemaObjC::ProcessPropertyDecl(ObjCPropertyDecl *property) { + ASTContext &Context = getASTContext(); ObjCMethodDecl *GetterMethod, *SetterMethod; ObjCContainerDecl *CD = cast(property->getDeclContext()); if (CD->isInvalidDecl()) @@ -2492,7 +2499,7 @@ void Sema::ProcessPropertyDecl(ObjCPropertyDecl *property) { : ObjCImplementationControl::Required); CD->addDecl(GetterMethod); - AddPropertyAttrs(*this, GetterMethod, property); + AddPropertyAttrs(SemaRef, GetterMethod, property); if (property->isDirectProperty()) GetterMethod->addAttr(ObjCDirectAttr::CreateImplicit(Context, Loc)); @@ -2509,7 +2516,7 @@ void Sema::ProcessPropertyDecl(ObjCPropertyDecl *property) { GetterMethod->addAttr(SectionAttr::CreateImplicit( Context, SA->getName(), Loc, SectionAttr::GNU_section)); - ProcessAPINotes(GetterMethod); + SemaRef.ProcessAPINotes(GetterMethod); if (getLangOpts().ObjCAutoRefCount) CheckARCMethodDecl(GetterMethod); @@ -2571,7 +2578,7 @@ void Sema::ProcessPropertyDecl(ObjCPropertyDecl *property) { nullptr); SetterMethod->setMethodParams(Context, Argument, std::nullopt); - AddPropertyAttrs(*this, SetterMethod, property); + AddPropertyAttrs(SemaRef, SetterMethod, property); if (property->isDirectProperty()) SetterMethod->addAttr(ObjCDirectAttr::CreateImplicit(Context, Loc)); @@ -2581,7 +2588,7 @@ void Sema::ProcessPropertyDecl(ObjCPropertyDecl *property) { SetterMethod->addAttr(SectionAttr::CreateImplicit( Context, SA->getName(), Loc, SectionAttr::GNU_section)); - ProcessAPINotes(SetterMethod); + SemaRef.ProcessAPINotes(SetterMethod); // It's possible for the user to have set a very odd custom // setter selector that causes it to have a method family. @@ -2628,12 +2635,12 @@ void Sema::ProcessPropertyDecl(ObjCPropertyDecl *property) { CurrentClass = Impl->getClassInterface(); } if (GetterMethod) - CheckObjCMethodOverrides(GetterMethod, CurrentClass, Sema::RTC_Unknown); + CheckObjCMethodOverrides(GetterMethod, CurrentClass, SemaObjC::RTC_Unknown); if (SetterMethod) - CheckObjCMethodOverrides(SetterMethod, CurrentClass, Sema::RTC_Unknown); + CheckObjCMethodOverrides(SetterMethod, CurrentClass, SemaObjC::RTC_Unknown); } -void Sema::CheckObjCPropertyAttributes(Decl *PDecl, +void SemaObjC::CheckObjCPropertyAttributes(Decl *PDecl, SourceLocation Loc, unsigned &Attributes, bool propertyInPrimaryClass) { diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index adc319e97b762..d77f5235eacb8 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -33,6 +33,7 @@ #include "clang/Sema/Overload.h" #include "clang/Sema/SemaCUDA.h" #include "clang/Sema/SemaInternal.h" +#include "clang/Sema/SemaObjC.h" #include "clang/Sema/Template.h" #include "clang/Sema/TemplateDeduction.h" #include "llvm/ADT/DenseSet.h" @@ -1086,7 +1087,7 @@ namespace { assert(E->hasPlaceholderType(BuiltinType::ARCUnbridgedCast)); Entry entry = { &E, E }; Entries.push_back(entry); - E = S.stripARCUnbridgedCast(E); + E = S.ObjC().stripARCUnbridgedCast(E); } void restore() { @@ -1773,7 +1774,7 @@ ExprResult Sema::PerformImplicitConversion(Expr *From, QualType ToType, = getLangOpts().ObjCAutoRefCount && (Action == AA_Passing || Action == AA_Sending); if (getLangOpts().ObjC) - CheckObjCBridgeRelatedConversions(From->getBeginLoc(), ToType, + ObjC().CheckObjCBridgeRelatedConversions(From->getBeginLoc(), ToType, From->getType(), From); ImplicitConversionSequence ICS = ::TryImplicitConversion( *this, From, ToType, @@ -2267,7 +2268,7 @@ static bool IsStandardConversion(Sema &S, Expr* From, QualType ToType, } else if (S.IsBlockPointerConversion(FromType, ToType, FromType)) { SCS.Second = ICK_Block_Pointer_Conversion; } else if (AllowObjCWritebackConversion && - S.isObjCWritebackConversion(FromType, ToType, FromType)) { + S.ObjC().isObjCWritebackConversion(FromType, ToType, FromType)) { SCS.Second = ICK_Writeback_Conversion; } else if (S.IsPointerConversion(From, FromType, ToType, InOverloadResolution, FromType, IncompatibleObjC)) { @@ -3047,73 +3048,6 @@ bool Sema::isObjCPointerConversion(QualType FromType, QualType ToType, return false; } -/// Determine whether this is an Objective-C writeback conversion, -/// used for parameter passing when performing automatic reference counting. -/// -/// \param FromType The type we're converting form. -/// -/// \param ToType The type we're converting to. -/// -/// \param ConvertedType The type that will be produced after applying -/// this conversion. -bool Sema::isObjCWritebackConversion(QualType FromType, QualType ToType, - QualType &ConvertedType) { - if (!getLangOpts().ObjCAutoRefCount || - Context.hasSameUnqualifiedType(FromType, ToType)) - return false; - - // Parameter must be a pointer to __autoreleasing (with no other qualifiers). - QualType ToPointee; - if (const PointerType *ToPointer = ToType->getAs()) - ToPointee = ToPointer->getPointeeType(); - else - return false; - - Qualifiers ToQuals = ToPointee.getQualifiers(); - if (!ToPointee->isObjCLifetimeType() || - ToQuals.getObjCLifetime() != Qualifiers::OCL_Autoreleasing || - !ToQuals.withoutObjCLifetime().empty()) - return false; - - // Argument must be a pointer to __strong to __weak. - QualType FromPointee; - if (const PointerType *FromPointer = FromType->getAs()) - FromPointee = FromPointer->getPointeeType(); - else - return false; - - Qualifiers FromQuals = FromPointee.getQualifiers(); - if (!FromPointee->isObjCLifetimeType() || - (FromQuals.getObjCLifetime() != Qualifiers::OCL_Strong && - FromQuals.getObjCLifetime() != Qualifiers::OCL_Weak)) - return false; - - // Make sure that we have compatible qualifiers. - FromQuals.setObjCLifetime(Qualifiers::OCL_Autoreleasing); - if (!ToQuals.compatiblyIncludes(FromQuals)) - return false; - - // Remove qualifiers from the pointee type we're converting from; they - // aren't used in the compatibility check belong, and we'll be adding back - // qualifiers (with __autoreleasing) if the compatibility check succeeds. - FromPointee = FromPointee.getUnqualifiedType(); - - // The unqualified form of the pointee types must be compatible. - ToPointee = ToPointee.getUnqualifiedType(); - bool IncompatibleObjC; - if (Context.typesAreCompatible(FromPointee, ToPointee)) - FromPointee = ToPointee; - else if (!isObjCPointerConversion(FromPointee, ToPointee, FromPointee, - IncompatibleObjC)) - return false; - - /// Construct the type we're converting to, which is a pointer to - /// __autoreleasing pointee. - FromPointee = Context.getQualifiedType(FromPointee, FromQuals); - ConvertedType = Context.getPointerType(FromPointee); - return true; -} - bool Sema::IsBlockPointerConversion(QualType FromType, QualType ToType, QualType& ConvertedType) { QualType ToPointeeType; @@ -7192,7 +7126,7 @@ Sema::SelectBestMethod(Selector Sel, MultiExprArg Args, bool IsInstance, // a consumed argument. if (argExpr->hasPlaceholderType(BuiltinType::ARCUnbridgedCast) && !param->hasAttr()) - argExpr = stripARCUnbridgedCast(argExpr); + argExpr = ObjC().stripARCUnbridgedCast(argExpr); // If the parameter is __unknown_anytype, move on to the next method. if (param->getType() == Context.UnknownAnyTy) { diff --git a/clang/lib/Sema/SemaPseudoObject.cpp b/clang/lib/Sema/SemaPseudoObject.cpp index c6a0a182d3583..8195e708b79dc 100644 --- a/clang/lib/Sema/SemaPseudoObject.cpp +++ b/clang/lib/Sema/SemaPseudoObject.cpp @@ -35,6 +35,7 @@ #include "clang/Basic/CharInfo.h" #include "clang/Lex/Preprocessor.h" #include "clang/Sema/Initialization.h" +#include "clang/Sema/SemaObjC.h" #include "clang/Sema/ScopeInfo.h" #include "llvm/ADT/SmallString.h" @@ -557,30 +558,30 @@ static ObjCMethodDecl *LookupMethodInReceiverType(Sema &S, Selector sel, // Special case for 'self' in class method implementations. if (PT->isObjCClassType() && - S.isSelfExpr(const_cast(PRE->getBase()))) { + S.ObjC().isSelfExpr(const_cast(PRE->getBase()))) { // This cast is safe because isSelfExpr is only true within // methods. ObjCMethodDecl *method = cast(S.CurContext->getNonClosureAncestor()); - return S.LookupMethodInObjectType(sel, + return S.ObjC().LookupMethodInObjectType(sel, S.Context.getObjCInterfaceType(method->getClassInterface()), /*instance*/ false); } - return S.LookupMethodInObjectType(sel, PT->getPointeeType(), true); + return S.ObjC().LookupMethodInObjectType(sel, PT->getPointeeType(), true); } if (PRE->isSuperReceiver()) { if (const ObjCObjectPointerType *PT = PRE->getSuperReceiverType()->getAs()) - return S.LookupMethodInObjectType(sel, PT->getPointeeType(), true); + return S.ObjC().LookupMethodInObjectType(sel, PT->getPointeeType(), true); - return S.LookupMethodInObjectType(sel, PRE->getSuperReceiverType(), false); + return S.ObjC().LookupMethodInObjectType(sel, PRE->getSuperReceiverType(), false); } assert(PRE->isClassReceiver() && "Invalid expression"); QualType IT = S.Context.getObjCInterfaceType(PRE->getClassReceiver()); - return S.LookupMethodInObjectType(sel, IT, false); + return S.ObjC().LookupMethodInObjectType(sel, IT, false); } bool ObjCPropertyOpBuilder::isWeakProperty() const { @@ -741,11 +742,11 @@ ExprResult ObjCPropertyOpBuilder::buildGet() { if ((Getter->isInstanceMethod() && !RefExpr->isClassReceiver()) || RefExpr->isObjectReceiver()) { assert(InstanceReceiver || RefExpr->isSuperReceiver()); - msg = S.BuildInstanceMessageImplicit(InstanceReceiver, receiverType, + msg = S.ObjC().BuildInstanceMessageImplicit(InstanceReceiver, receiverType, GenericLoc, Getter->getSelector(), Getter, std::nullopt); } else { - msg = S.BuildClassMessageImplicit(receiverType, RefExpr->isSuperReceiver(), + msg = S.ObjC().BuildClassMessageImplicit(receiverType, RefExpr->isSuperReceiver(), GenericLoc, Getter->getSelector(), Getter, std::nullopt); } @@ -801,11 +802,11 @@ ExprResult ObjCPropertyOpBuilder::buildSet(Expr *op, SourceLocation opcLoc, S.DiagnoseUseOfDecl(Setter, GenericLoc, nullptr, true); if ((Setter->isInstanceMethod() && !RefExpr->isClassReceiver()) || RefExpr->isObjectReceiver()) { - msg = S.BuildInstanceMessageImplicit(InstanceReceiver, receiverType, + msg = S.ObjC().BuildInstanceMessageImplicit(InstanceReceiver, receiverType, GenericLoc, SetterSelector, Setter, MultiExprArg(args, 1)); } else { - msg = S.BuildClassMessageImplicit(receiverType, RefExpr->isSuperReceiver(), + msg = S.ObjC().BuildClassMessageImplicit(receiverType, RefExpr->isSuperReceiver(), GenericLoc, SetterSelector, Setter, MultiExprArg(args, 1)); @@ -836,7 +837,7 @@ ExprResult ObjCPropertyOpBuilder::buildRValueOperation(Expr *op) { if (result.isInvalid()) return ExprError(); if (RefExpr->isExplicitProperty() && !Getter->hasRelatedResultType()) - S.DiagnosePropertyAccessorMismatch(RefExpr->getExplicitProperty(), + S.ObjC().DiagnosePropertyAccessorMismatch(RefExpr->getExplicitProperty(), Getter, RefExpr->getLocation()); // As a special case, if the method returns 'id', try to get @@ -925,7 +926,7 @@ ObjCPropertyOpBuilder::buildAssignmentOperation(Scope *Sc, // Various warnings about property assignments in ARC. if (S.getLangOpts().ObjCAutoRefCount && InstanceReceiver) { - S.checkRetainCycles(InstanceReceiver->getSourceExpr(), RHS); + S.ObjC().checkRetainCycles(InstanceReceiver->getSourceExpr(), RHS); S.checkUnsafeExprAssigns(opcLoc, LHS, RHS); } @@ -1014,7 +1015,7 @@ ObjCSubscriptOpBuilder::buildAssignmentOperation(Scope *Sc, // Various warnings about objc Index'ed assignments in ARC. if (S.getLangOpts().ObjCAutoRefCount && InstanceBase) { - S.checkRetainCycles(InstanceBase->getSourceExpr(), RHS); + S.ObjC().checkRetainCycles(InstanceBase->getSourceExpr(), RHS); S.checkUnsafeExprAssigns(opcLoc, LHS, RHS); } @@ -1045,80 +1046,6 @@ Expr *ObjCSubscriptOpBuilder::rebuildAndCaptureObject(Expr *syntacticBase) { return syntacticBase; } -/// CheckSubscriptingKind - This routine decide what type -/// of indexing represented by "FromE" is being done. -Sema::ObjCSubscriptKind - Sema::CheckSubscriptingKind(Expr *FromE) { - // If the expression already has integral or enumeration type, we're golden. - QualType T = FromE->getType(); - if (T->isIntegralOrEnumerationType()) - return OS_Array; - - // If we don't have a class type in C++, there's no way we can get an - // expression of integral or enumeration type. - const RecordType *RecordTy = T->getAs(); - if (!RecordTy && - (T->isObjCObjectPointerType() || T->isVoidPointerType())) - // All other scalar cases are assumed to be dictionary indexing which - // caller handles, with diagnostics if needed. - return OS_Dictionary; - if (!getLangOpts().CPlusPlus || - !RecordTy || RecordTy->isIncompleteType()) { - // No indexing can be done. Issue diagnostics and quit. - const Expr *IndexExpr = FromE->IgnoreParenImpCasts(); - if (isa(IndexExpr)) - Diag(FromE->getExprLoc(), diag::err_objc_subscript_pointer) - << T << FixItHint::CreateInsertion(FromE->getExprLoc(), "@"); - else - Diag(FromE->getExprLoc(), diag::err_objc_subscript_type_conversion) - << T; - return OS_Error; - } - - // We must have a complete class type. - if (RequireCompleteType(FromE->getExprLoc(), T, - diag::err_objc_index_incomplete_class_type, FromE)) - return OS_Error; - - // Look for a conversion to an integral, enumeration type, or - // objective-C pointer type. - int NoIntegrals=0, NoObjCIdPointers=0; - SmallVector ConversionDecls; - - for (NamedDecl *D : cast(RecordTy->getDecl()) - ->getVisibleConversionFunctions()) { - if (CXXConversionDecl *Conversion = - dyn_cast(D->getUnderlyingDecl())) { - QualType CT = Conversion->getConversionType().getNonReferenceType(); - if (CT->isIntegralOrEnumerationType()) { - ++NoIntegrals; - ConversionDecls.push_back(Conversion); - } - else if (CT->isObjCIdType() ||CT->isBlockPointerType()) { - ++NoObjCIdPointers; - ConversionDecls.push_back(Conversion); - } - } - } - if (NoIntegrals ==1 && NoObjCIdPointers == 0) - return OS_Array; - if (NoIntegrals == 0 && NoObjCIdPointers == 1) - return OS_Dictionary; - if (NoIntegrals == 0 && NoObjCIdPointers == 0) { - // No conversion function was found. Issue diagnostic and return. - Diag(FromE->getExprLoc(), diag::err_objc_subscript_type_conversion) - << FromE->getType(); - return OS_Error; - } - Diag(FromE->getExprLoc(), diag::err_objc_multiple_subscript_type_conversion) - << FromE->getType(); - for (unsigned int i = 0; i < ConversionDecls.size(); i++) - Diag(ConversionDecls[i]->getLocation(), - diag::note_conv_function_declared_at); - - return OS_Error; -} - /// CheckKeyForObjCARCConversion - This routine suggests bridge casting of CF /// objects used as dictionary subscript key objects. static void CheckKeyForObjCARCConversion(Sema &S, QualType ContainerT, @@ -1130,12 +1057,12 @@ static void CheckKeyForObjCARCConversion(Sema &S, QualType ContainerT, const IdentifierInfo *KeyIdents[] = { &S.Context.Idents.get("objectForKeyedSubscript")}; Selector GetterSelector = S.Context.Selectors.getSelector(1, KeyIdents); - ObjCMethodDecl *Getter = S.LookupMethodInObjectType(GetterSelector, ContainerT, + ObjCMethodDecl *Getter = S.ObjC().LookupMethodInObjectType(GetterSelector, ContainerT, true /*instance*/); if (!Getter) return; QualType T = Getter->parameters()[0]->getType(); - S.CheckObjCConversion(Key->getSourceRange(), T, Key, + S.ObjC().CheckObjCConversion(Key->getSourceRange(), T, Key, CheckedConversionKind::Implicit); } @@ -1151,15 +1078,15 @@ bool ObjCSubscriptOpBuilder::findAtIndexGetter() { BaseT->getAs()) { ResultType = PTy->getPointeeType(); } - Sema::ObjCSubscriptKind Res = - S.CheckSubscriptingKind(RefExpr->getKeyExpr()); - if (Res == Sema::OS_Error) { + SemaObjC::ObjCSubscriptKind Res = + S.ObjC().CheckSubscriptingKind(RefExpr->getKeyExpr()); + if (Res == SemaObjC::OS_Error) { if (S.getLangOpts().ObjCAutoRefCount) CheckKeyForObjCARCConversion(S, ResultType, RefExpr->getKeyExpr()); return false; } - bool arrayRef = (Res == Sema::OS_Array); + bool arrayRef = (Res == SemaObjC::OS_Array); if (ResultType.isNull()) { S.Diag(BaseExpr->getExprLoc(), diag::err_objc_subscript_base_type) @@ -1181,7 +1108,7 @@ bool ObjCSubscriptOpBuilder::findAtIndexGetter() { AtIndexGetterSelector = S.Context.Selectors.getSelector(1, KeyIdents); } - AtIndexGetter = S.LookupMethodInObjectType(AtIndexGetterSelector, ResultType, + AtIndexGetter = S.ObjC().LookupMethodInObjectType(AtIndexGetterSelector, ResultType, true /*instance*/); if (!AtIndexGetter && S.getLangOpts().DebuggerObjCLiteral) { @@ -1213,7 +1140,7 @@ bool ObjCSubscriptOpBuilder::findAtIndexGetter() { return false; } AtIndexGetter = - S.LookupInstanceMethodInGlobalPool(AtIndexGetterSelector, + S.ObjC().LookupInstanceMethodInGlobalPool(AtIndexGetterSelector, RefExpr->getSourceRange(), true); } @@ -1253,15 +1180,15 @@ bool ObjCSubscriptOpBuilder::findAtIndexSetter() { ResultType = PTy->getPointeeType(); } - Sema::ObjCSubscriptKind Res = - S.CheckSubscriptingKind(RefExpr->getKeyExpr()); - if (Res == Sema::OS_Error) { + SemaObjC::ObjCSubscriptKind Res = + S.ObjC().CheckSubscriptingKind(RefExpr->getKeyExpr()); + if (Res == SemaObjC::OS_Error) { if (S.getLangOpts().ObjCAutoRefCount) CheckKeyForObjCARCConversion(S, ResultType, RefExpr->getKeyExpr()); return false; } - bool arrayRef = (Res == Sema::OS_Array); + bool arrayRef = (Res == SemaObjC::OS_Array); if (ResultType.isNull()) { S.Diag(BaseExpr->getExprLoc(), diag::err_objc_subscript_base_type) @@ -1284,7 +1211,7 @@ bool ObjCSubscriptOpBuilder::findAtIndexSetter() { &S.Context.Idents.get("atIndexedSubscript")}; AtIndexSetterSelector = S.Context.Selectors.getSelector(2, KeyIdents); } - AtIndexSetter = S.LookupMethodInObjectType(AtIndexSetterSelector, ResultType, + AtIndexSetter = S.ObjC().LookupMethodInObjectType(AtIndexSetterSelector, ResultType, true /*instance*/); if (!AtIndexSetter && S.getLangOpts().DebuggerObjCLiteral) { @@ -1328,7 +1255,7 @@ bool ObjCSubscriptOpBuilder::findAtIndexSetter() { return false; } AtIndexSetter = - S.LookupInstanceMethodInGlobalPool(AtIndexSetterSelector, + S.ObjC().LookupInstanceMethodInGlobalPool(AtIndexSetterSelector, RefExpr->getSourceRange(), true); } @@ -1388,7 +1315,7 @@ ExprResult ObjCSubscriptOpBuilder::buildGet() { assert(InstanceBase); if (AtIndexGetter) S.DiagnoseUseOfDecl(AtIndexGetter, GenericLoc); - msg = S.BuildInstanceMessageImplicit(InstanceBase, receiverType, + msg = S.ObjC().BuildInstanceMessageImplicit(InstanceBase, receiverType, GenericLoc, AtIndexGetterSelector, AtIndexGetter, MultiExprArg(args, 1)); @@ -1413,7 +1340,7 @@ ExprResult ObjCSubscriptOpBuilder::buildSet(Expr *op, SourceLocation opcLoc, Expr *args[] = { op, Index }; // Build a message-send. - ExprResult msg = S.BuildInstanceMessageImplicit(InstanceBase, receiverType, + ExprResult msg = S.ObjC().BuildInstanceMessageImplicit(InstanceBase, receiverType, GenericLoc, AtIndexSetterSelector, AtIndexSetter, diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index a7b33f0db047e..57465d4a77ac2 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -35,6 +35,7 @@ #include "clang/Sema/ScopeInfo.h" #include "clang/Sema/SemaCUDA.h" #include "clang/Sema/SemaInternal.h" +#include "clang/Sema/SemaObjC.h" #include "clang/Sema/SemaOpenMP.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" @@ -2236,165 +2237,6 @@ StmtResult Sema::ActOnForEachLValueExpr(Expr *E) { return StmtResult(static_cast(FullExpr.get())); } -ExprResult -Sema::CheckObjCForCollectionOperand(SourceLocation forLoc, Expr *collection) { - if (!collection) - return ExprError(); - - ExprResult result = CorrectDelayedTyposInExpr(collection); - if (!result.isUsable()) - return ExprError(); - collection = result.get(); - - // Bail out early if we've got a type-dependent expression. - if (collection->isTypeDependent()) return collection; - - // Perform normal l-value conversion. - result = DefaultFunctionArrayLvalueConversion(collection); - if (result.isInvalid()) - return ExprError(); - collection = result.get(); - - // The operand needs to have object-pointer type. - // TODO: should we do a contextual conversion? - const ObjCObjectPointerType *pointerType = - collection->getType()->getAs(); - if (!pointerType) - return Diag(forLoc, diag::err_collection_expr_type) - << collection->getType() << collection->getSourceRange(); - - // Check that the operand provides - // - countByEnumeratingWithState:objects:count: - const ObjCObjectType *objectType = pointerType->getObjectType(); - ObjCInterfaceDecl *iface = objectType->getInterface(); - - // If we have a forward-declared type, we can't do this check. - // Under ARC, it is an error not to have a forward-declared class. - if (iface && - (getLangOpts().ObjCAutoRefCount - ? RequireCompleteType(forLoc, QualType(objectType, 0), - diag::err_arc_collection_forward, collection) - : !isCompleteType(forLoc, QualType(objectType, 0)))) { - // Otherwise, if we have any useful type information, check that - // the type declares the appropriate method. - } else if (iface || !objectType->qual_empty()) { - const IdentifierInfo *selectorIdents[] = { - &Context.Idents.get("countByEnumeratingWithState"), - &Context.Idents.get("objects"), &Context.Idents.get("count")}; - Selector selector = Context.Selectors.getSelector(3, &selectorIdents[0]); - - ObjCMethodDecl *method = nullptr; - - // If there's an interface, look in both the public and private APIs. - if (iface) { - method = iface->lookupInstanceMethod(selector); - if (!method) method = iface->lookupPrivateMethod(selector); - } - - // Also check protocol qualifiers. - if (!method) - method = LookupMethodInQualifiedType(selector, pointerType, - /*instance*/ true); - - // If we didn't find it anywhere, give up. - if (!method) { - Diag(forLoc, diag::warn_collection_expr_type) - << collection->getType() << selector << collection->getSourceRange(); - } - - // TODO: check for an incompatible signature? - } - - // Wrap up any cleanups in the expression. - return collection; -} - -StmtResult -Sema::ActOnObjCForCollectionStmt(SourceLocation ForLoc, - Stmt *First, Expr *collection, - SourceLocation RParenLoc) { - setFunctionHasBranchProtectedScope(); - - ExprResult CollectionExprResult = - CheckObjCForCollectionOperand(ForLoc, collection); - - if (First) { - QualType FirstType; - if (DeclStmt *DS = dyn_cast(First)) { - if (!DS->isSingleDecl()) - return StmtError(Diag((*DS->decl_begin())->getLocation(), - diag::err_toomany_element_decls)); - - VarDecl *D = dyn_cast(DS->getSingleDecl()); - if (!D || D->isInvalidDecl()) - return StmtError(); - - FirstType = D->getType(); - // C99 6.8.5p3: The declaration part of a 'for' statement shall only - // declare identifiers for objects having storage class 'auto' or - // 'register'. - if (!D->hasLocalStorage()) - return StmtError(Diag(D->getLocation(), - diag::err_non_local_variable_decl_in_for)); - - // If the type contained 'auto', deduce the 'auto' to 'id'. - if (FirstType->getContainedAutoType()) { - SourceLocation Loc = D->getLocation(); - OpaqueValueExpr OpaqueId(Loc, Context.getObjCIdType(), VK_PRValue); - Expr *DeducedInit = &OpaqueId; - TemplateDeductionInfo Info(Loc); - FirstType = QualType(); - TemplateDeductionResult Result = DeduceAutoType( - D->getTypeSourceInfo()->getTypeLoc(), DeducedInit, FirstType, Info); - if (Result != TemplateDeductionResult::Success && - Result != TemplateDeductionResult::AlreadyDiagnosed) - DiagnoseAutoDeductionFailure(D, DeducedInit); - if (FirstType.isNull()) { - D->setInvalidDecl(); - return StmtError(); - } - - D->setType(FirstType); - - if (!inTemplateInstantiation()) { - SourceLocation Loc = - D->getTypeSourceInfo()->getTypeLoc().getBeginLoc(); - Diag(Loc, diag::warn_auto_var_is_id) - << D->getDeclName(); - } - } - - } else { - Expr *FirstE = cast(First); - if (!FirstE->isTypeDependent() && !FirstE->isLValue()) - return StmtError( - Diag(First->getBeginLoc(), diag::err_selector_element_not_lvalue) - << First->getSourceRange()); - - FirstType = static_cast(First)->getType(); - if (FirstType.isConstQualified()) - Diag(ForLoc, diag::err_selector_element_const_type) - << FirstType << First->getSourceRange(); - } - if (!FirstType->isDependentType() && - !FirstType->isObjCObjectPointerType() && - !FirstType->isBlockPointerType()) - return StmtError(Diag(ForLoc, diag::err_selector_element_type) - << FirstType << First->getSourceRange()); - } - - if (CollectionExprResult.isInvalid()) - return StmtError(); - - CollectionExprResult = - ActOnFinishFullExpr(CollectionExprResult.get(), /*DiscardedValue*/ false); - if (CollectionExprResult.isInvalid()) - return StmtError(); - - return new (Context) ObjCForCollectionStmt(First, CollectionExprResult.get(), - nullptr, ForLoc, RParenLoc); -} - /// Finish building a variable declaration for a for-range statement. /// \return true if an error occurs. static bool FinishForRangeVarDecl(Sema &SemaRef, VarDecl *Decl, Expr *Init, @@ -2432,7 +2274,7 @@ static bool FinishForRangeVarDecl(Sema &SemaRef, VarDecl *Decl, Expr *Init, // FIXME: ARC may want to turn this into 'const __unsafe_unretained' if // we're doing the equivalent of fast iteration. if (SemaRef.getLangOpts().ObjCAutoRefCount && - SemaRef.inferObjCARCLifetime(Decl)) + SemaRef.ObjC().inferObjCARCLifetime(Decl)) Decl->setInvalidDecl(); SemaRef.AddInitializerToDecl(Decl, Init, /*DirectInit=*/false); @@ -2526,7 +2368,7 @@ StmtResult Sema::ActOnCXXForRangeStmt( if (InitStmt) return Diag(InitStmt->getBeginLoc(), diag::err_objc_for_range_init_stmt) << InitStmt->getSourceRange(); - return ActOnObjCForCollectionStmt(ForLoc, First, Range, RParenLoc); + return ObjC().ActOnObjCForCollectionStmt(ForLoc, First, Range, RParenLoc); } DeclStmt *DS = dyn_cast(First); @@ -3107,17 +2949,6 @@ StmtResult Sema::BuildCXXForRangeStmt( ColonLoc, RParenLoc); } -/// FinishObjCForCollectionStmt - Attach the body to a objective-C foreach -/// statement. -StmtResult Sema::FinishObjCForCollectionStmt(Stmt *S, Stmt *B) { - if (!S || !B) - return StmtError(); - ObjCForCollectionStmt * ForStmt = cast(S); - - ForStmt->setBody(B); - return S; -} - // Warn when the loop variable is a const reference that creates a copy. // Suggest using the non-reference type for copies. If a copy can be prevented // suggest the const reference type that would do so. @@ -3307,7 +3138,7 @@ StmtResult Sema::FinishCXXForRangeStmt(Stmt *S, Stmt *B) { return StmtError(); if (isa(S)) - return FinishObjCForCollectionStmt(S, B); + return ObjC().FinishObjCForCollectionStmt(S, B); CXXForRangeStmt *ForStmt = cast(S); ForStmt->setBody(B); @@ -4301,130 +4132,6 @@ StmtResult Sema::BuildReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp, return Result; } -StmtResult -Sema::ActOnObjCAtCatchStmt(SourceLocation AtLoc, - SourceLocation RParen, Decl *Parm, - Stmt *Body) { - VarDecl *Var = cast_or_null(Parm); - if (Var && Var->isInvalidDecl()) - return StmtError(); - - return new (Context) ObjCAtCatchStmt(AtLoc, RParen, Var, Body); -} - -StmtResult -Sema::ActOnObjCAtFinallyStmt(SourceLocation AtLoc, Stmt *Body) { - return new (Context) ObjCAtFinallyStmt(AtLoc, Body); -} - -StmtResult -Sema::ActOnObjCAtTryStmt(SourceLocation AtLoc, Stmt *Try, - MultiStmtArg CatchStmts, Stmt *Finally) { - if (!getLangOpts().ObjCExceptions) - Diag(AtLoc, diag::err_objc_exceptions_disabled) << "@try"; - - // Objective-C try is incompatible with SEH __try. - sema::FunctionScopeInfo *FSI = getCurFunction(); - if (FSI->FirstSEHTryLoc.isValid()) { - Diag(AtLoc, diag::err_mixing_cxx_try_seh_try) << 1; - Diag(FSI->FirstSEHTryLoc, diag::note_conflicting_try_here) << "'__try'"; - } - - FSI->setHasObjCTry(AtLoc); - unsigned NumCatchStmts = CatchStmts.size(); - return ObjCAtTryStmt::Create(Context, AtLoc, Try, CatchStmts.data(), - NumCatchStmts, Finally); -} - -StmtResult Sema::BuildObjCAtThrowStmt(SourceLocation AtLoc, Expr *Throw) { - if (Throw) { - ExprResult Result = DefaultLvalueConversion(Throw); - if (Result.isInvalid()) - return StmtError(); - - Result = ActOnFinishFullExpr(Result.get(), /*DiscardedValue*/ false); - if (Result.isInvalid()) - return StmtError(); - Throw = Result.get(); - - QualType ThrowType = Throw->getType(); - // Make sure the expression type is an ObjC pointer or "void *". - if (!ThrowType->isDependentType() && - !ThrowType->isObjCObjectPointerType()) { - const PointerType *PT = ThrowType->getAs(); - if (!PT || !PT->getPointeeType()->isVoidType()) - return StmtError(Diag(AtLoc, diag::err_objc_throw_expects_object) - << Throw->getType() << Throw->getSourceRange()); - } - } - - return new (Context) ObjCAtThrowStmt(AtLoc, Throw); -} - -StmtResult -Sema::ActOnObjCAtThrowStmt(SourceLocation AtLoc, Expr *Throw, - Scope *CurScope) { - if (!getLangOpts().ObjCExceptions) - Diag(AtLoc, diag::err_objc_exceptions_disabled) << "@throw"; - - if (!Throw) { - // @throw without an expression designates a rethrow (which must occur - // in the context of an @catch clause). - Scope *AtCatchParent = CurScope; - while (AtCatchParent && !AtCatchParent->isAtCatchScope()) - AtCatchParent = AtCatchParent->getParent(); - if (!AtCatchParent) - return StmtError(Diag(AtLoc, diag::err_rethrow_used_outside_catch)); - } - return BuildObjCAtThrowStmt(AtLoc, Throw); -} - -ExprResult -Sema::ActOnObjCAtSynchronizedOperand(SourceLocation atLoc, Expr *operand) { - ExprResult result = DefaultLvalueConversion(operand); - if (result.isInvalid()) - return ExprError(); - operand = result.get(); - - // Make sure the expression type is an ObjC pointer or "void *". - QualType type = operand->getType(); - if (!type->isDependentType() && - !type->isObjCObjectPointerType()) { - const PointerType *pointerType = type->getAs(); - if (!pointerType || !pointerType->getPointeeType()->isVoidType()) { - if (getLangOpts().CPlusPlus) { - if (RequireCompleteType(atLoc, type, - diag::err_incomplete_receiver_type)) - return Diag(atLoc, diag::err_objc_synchronized_expects_object) - << type << operand->getSourceRange(); - - ExprResult result = PerformContextuallyConvertToObjCPointer(operand); - if (result.isInvalid()) - return ExprError(); - if (!result.isUsable()) - return Diag(atLoc, diag::err_objc_synchronized_expects_object) - << type << operand->getSourceRange(); - - operand = result.get(); - } else { - return Diag(atLoc, diag::err_objc_synchronized_expects_object) - << type << operand->getSourceRange(); - } - } - } - - // The operand to @synchronized is a full-expression. - return ActOnFinishFullExpr(operand, /*DiscardedValue*/ false); -} - -StmtResult -Sema::ActOnObjCAtSynchronizedStmt(SourceLocation AtLoc, Expr *SyncExpr, - Stmt *SyncBody) { - // We can't jump into or indirect-jump out of a @synchronized block. - setFunctionHasBranchProtectedScope(); - return new (Context) ObjCAtSynchronizedStmt(AtLoc, SyncExpr, SyncBody); -} - /// ActOnCXXCatchBlock - Takes an exception declaration and a handler block /// and creates a proper catch handler from them. StmtResult @@ -4435,12 +4142,6 @@ Sema::ActOnCXXCatchBlock(SourceLocation CatchLoc, Decl *ExDecl, CXXCatchStmt(CatchLoc, cast_or_null(ExDecl), HandlerBlock); } -StmtResult -Sema::ActOnObjCAutoreleasePoolStmt(SourceLocation AtLoc, Stmt *Body) { - setFunctionHasBranchProtectedScope(); - return new (Context) ObjCAutoreleasePoolStmt(AtLoc, Body); -} - namespace { class CatchHandlerType { QualType QT; diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index caa07abb61fe3..842c9a8de7c03 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -28,6 +28,7 @@ #include "clang/Sema/ScopeInfo.h" #include "clang/Sema/SemaCUDA.h" #include "clang/Sema/SemaInternal.h" +#include "clang/Sema/SemaObjC.h" #include "clang/Sema/SemaOpenMP.h" #include "clang/Sema/Template.h" #include "clang/Sema/TemplateInstCallback.h" @@ -1217,7 +1218,7 @@ Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D, // In ARC, infer 'retaining' for variables of retainable type. if (SemaRef.getLangOpts().ObjCAutoRefCount && - SemaRef.inferObjCARCLifetime(Var)) + SemaRef.ObjC().inferObjCARCLifetime(Var)) Var->setInvalidDecl(); if (SemaRef.getLangOpts().OpenCL) diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 1b31df8d97fba..f9d9e52b2300b 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -35,6 +35,7 @@ #include "clang/Sema/ScopeInfo.h" #include "clang/Sema/SemaCUDA.h" #include "clang/Sema/SemaInternal.h" +#include "clang/Sema/SemaObjC.h" #include "clang/Sema/SemaOpenMP.h" #include "clang/Sema/Template.h" #include "clang/Sema/TemplateInstCallback.h" @@ -849,424 +850,6 @@ static bool checkOmittedBlockReturnType(Sema &S, Declarator &declarator, return true; } -/// Apply Objective-C type arguments to the given type. -static QualType applyObjCTypeArgs(Sema &S, SourceLocation loc, QualType type, - ArrayRef typeArgs, - SourceRange typeArgsRange, bool failOnError, - bool rebuilding) { - // We can only apply type arguments to an Objective-C class type. - const auto *objcObjectType = type->getAs(); - if (!objcObjectType || !objcObjectType->getInterface()) { - S.Diag(loc, diag::err_objc_type_args_non_class) - << type - << typeArgsRange; - - if (failOnError) - return QualType(); - return type; - } - - // The class type must be parameterized. - ObjCInterfaceDecl *objcClass = objcObjectType->getInterface(); - ObjCTypeParamList *typeParams = objcClass->getTypeParamList(); - if (!typeParams) { - S.Diag(loc, diag::err_objc_type_args_non_parameterized_class) - << objcClass->getDeclName() - << FixItHint::CreateRemoval(typeArgsRange); - - if (failOnError) - return QualType(); - - return type; - } - - // The type must not already be specialized. - if (objcObjectType->isSpecialized()) { - S.Diag(loc, diag::err_objc_type_args_specialized_class) - << type - << FixItHint::CreateRemoval(typeArgsRange); - - if (failOnError) - return QualType(); - - return type; - } - - // Check the type arguments. - SmallVector finalTypeArgs; - unsigned numTypeParams = typeParams->size(); - bool anyPackExpansions = false; - for (unsigned i = 0, n = typeArgs.size(); i != n; ++i) { - TypeSourceInfo *typeArgInfo = typeArgs[i]; - QualType typeArg = typeArgInfo->getType(); - - // Type arguments cannot have explicit qualifiers or nullability. - // We ignore indirect sources of these, e.g. behind typedefs or - // template arguments. - if (TypeLoc qual = typeArgInfo->getTypeLoc().findExplicitQualifierLoc()) { - bool diagnosed = false; - SourceRange rangeToRemove; - if (auto attr = qual.getAs()) { - rangeToRemove = attr.getLocalSourceRange(); - if (attr.getTypePtr()->getImmediateNullability()) { - typeArg = attr.getTypePtr()->getModifiedType(); - S.Diag(attr.getBeginLoc(), - diag::err_objc_type_arg_explicit_nullability) - << typeArg << FixItHint::CreateRemoval(rangeToRemove); - diagnosed = true; - } - } - - // When rebuilding, qualifiers might have gotten here through a - // final substitution. - if (!rebuilding && !diagnosed) { - S.Diag(qual.getBeginLoc(), diag::err_objc_type_arg_qualified) - << typeArg << typeArg.getQualifiers().getAsString() - << FixItHint::CreateRemoval(rangeToRemove); - } - } - - // Remove qualifiers even if they're non-local. - typeArg = typeArg.getUnqualifiedType(); - - finalTypeArgs.push_back(typeArg); - - if (typeArg->getAs()) - anyPackExpansions = true; - - // Find the corresponding type parameter, if there is one. - ObjCTypeParamDecl *typeParam = nullptr; - if (!anyPackExpansions) { - if (i < numTypeParams) { - typeParam = typeParams->begin()[i]; - } else { - // Too many arguments. - S.Diag(loc, diag::err_objc_type_args_wrong_arity) - << false - << objcClass->getDeclName() - << (unsigned)typeArgs.size() - << numTypeParams; - S.Diag(objcClass->getLocation(), diag::note_previous_decl) - << objcClass; - - if (failOnError) - return QualType(); - - return type; - } - } - - // Objective-C object pointer types must be substitutable for the bounds. - if (const auto *typeArgObjC = typeArg->getAs()) { - // If we don't have a type parameter to match against, assume - // everything is fine. There was a prior pack expansion that - // means we won't be able to match anything. - if (!typeParam) { - assert(anyPackExpansions && "Too many arguments?"); - continue; - } - - // Retrieve the bound. - QualType bound = typeParam->getUnderlyingType(); - const auto *boundObjC = bound->castAs(); - - // Determine whether the type argument is substitutable for the bound. - if (typeArgObjC->isObjCIdType()) { - // When the type argument is 'id', the only acceptable type - // parameter bound is 'id'. - if (boundObjC->isObjCIdType()) - continue; - } else if (S.Context.canAssignObjCInterfaces(boundObjC, typeArgObjC)) { - // Otherwise, we follow the assignability rules. - continue; - } - - // Diagnose the mismatch. - S.Diag(typeArgInfo->getTypeLoc().getBeginLoc(), - diag::err_objc_type_arg_does_not_match_bound) - << typeArg << bound << typeParam->getDeclName(); - S.Diag(typeParam->getLocation(), diag::note_objc_type_param_here) - << typeParam->getDeclName(); - - if (failOnError) - return QualType(); - - return type; - } - - // Block pointer types are permitted for unqualified 'id' bounds. - if (typeArg->isBlockPointerType()) { - // If we don't have a type parameter to match against, assume - // everything is fine. There was a prior pack expansion that - // means we won't be able to match anything. - if (!typeParam) { - assert(anyPackExpansions && "Too many arguments?"); - continue; - } - - // Retrieve the bound. - QualType bound = typeParam->getUnderlyingType(); - if (bound->isBlockCompatibleObjCPointerType(S.Context)) - continue; - - // Diagnose the mismatch. - S.Diag(typeArgInfo->getTypeLoc().getBeginLoc(), - diag::err_objc_type_arg_does_not_match_bound) - << typeArg << bound << typeParam->getDeclName(); - S.Diag(typeParam->getLocation(), diag::note_objc_type_param_here) - << typeParam->getDeclName(); - - if (failOnError) - return QualType(); - - return type; - } - - // Types that have __attribute__((NSObject)) are permitted. - if (typeArg->isObjCNSObjectType()) { - continue; - } - - // Dependent types will be checked at instantiation time. - if (typeArg->isDependentType()) { - continue; - } - - // Diagnose non-id-compatible type arguments. - S.Diag(typeArgInfo->getTypeLoc().getBeginLoc(), - diag::err_objc_type_arg_not_id_compatible) - << typeArg << typeArgInfo->getTypeLoc().getSourceRange(); - - if (failOnError) - return QualType(); - - return type; - } - - // Make sure we didn't have the wrong number of arguments. - if (!anyPackExpansions && finalTypeArgs.size() != numTypeParams) { - S.Diag(loc, diag::err_objc_type_args_wrong_arity) - << (typeArgs.size() < typeParams->size()) - << objcClass->getDeclName() - << (unsigned)finalTypeArgs.size() - << (unsigned)numTypeParams; - S.Diag(objcClass->getLocation(), diag::note_previous_decl) - << objcClass; - - if (failOnError) - return QualType(); - - return type; - } - - // Success. Form the specialized type. - return S.Context.getObjCObjectType(type, finalTypeArgs, { }, false); -} - -QualType Sema::BuildObjCTypeParamType(const ObjCTypeParamDecl *Decl, - SourceLocation ProtocolLAngleLoc, - ArrayRef Protocols, - ArrayRef ProtocolLocs, - SourceLocation ProtocolRAngleLoc, - bool FailOnError) { - QualType Result = QualType(Decl->getTypeForDecl(), 0); - if (!Protocols.empty()) { - bool HasError; - Result = Context.applyObjCProtocolQualifiers(Result, Protocols, - HasError); - if (HasError) { - Diag(SourceLocation(), diag::err_invalid_protocol_qualifiers) - << SourceRange(ProtocolLAngleLoc, ProtocolRAngleLoc); - if (FailOnError) Result = QualType(); - } - if (FailOnError && Result.isNull()) - return QualType(); - } - - return Result; -} - -QualType Sema::BuildObjCObjectType( - QualType BaseType, SourceLocation Loc, SourceLocation TypeArgsLAngleLoc, - ArrayRef TypeArgs, SourceLocation TypeArgsRAngleLoc, - SourceLocation ProtocolLAngleLoc, ArrayRef Protocols, - ArrayRef ProtocolLocs, SourceLocation ProtocolRAngleLoc, - bool FailOnError, bool Rebuilding) { - QualType Result = BaseType; - if (!TypeArgs.empty()) { - Result = - applyObjCTypeArgs(*this, Loc, Result, TypeArgs, - SourceRange(TypeArgsLAngleLoc, TypeArgsRAngleLoc), - FailOnError, Rebuilding); - if (FailOnError && Result.isNull()) - return QualType(); - } - - if (!Protocols.empty()) { - bool HasError; - Result = Context.applyObjCProtocolQualifiers(Result, Protocols, - HasError); - if (HasError) { - Diag(Loc, diag::err_invalid_protocol_qualifiers) - << SourceRange(ProtocolLAngleLoc, ProtocolRAngleLoc); - if (FailOnError) Result = QualType(); - } - if (FailOnError && Result.isNull()) - return QualType(); - } - - return Result; -} - -TypeResult Sema::actOnObjCProtocolQualifierType( - SourceLocation lAngleLoc, - ArrayRef protocols, - ArrayRef protocolLocs, - SourceLocation rAngleLoc) { - // Form id. - QualType Result = Context.getObjCObjectType( - Context.ObjCBuiltinIdTy, {}, - llvm::ArrayRef((ObjCProtocolDecl *const *)protocols.data(), - protocols.size()), - false); - Result = Context.getObjCObjectPointerType(Result); - - TypeSourceInfo *ResultTInfo = Context.CreateTypeSourceInfo(Result); - TypeLoc ResultTL = ResultTInfo->getTypeLoc(); - - auto ObjCObjectPointerTL = ResultTL.castAs(); - ObjCObjectPointerTL.setStarLoc(SourceLocation()); // implicit - - auto ObjCObjectTL = ObjCObjectPointerTL.getPointeeLoc() - .castAs(); - ObjCObjectTL.setHasBaseTypeAsWritten(false); - ObjCObjectTL.getBaseLoc().initialize(Context, SourceLocation()); - - // No type arguments. - ObjCObjectTL.setTypeArgsLAngleLoc(SourceLocation()); - ObjCObjectTL.setTypeArgsRAngleLoc(SourceLocation()); - - // Fill in protocol qualifiers. - ObjCObjectTL.setProtocolLAngleLoc(lAngleLoc); - ObjCObjectTL.setProtocolRAngleLoc(rAngleLoc); - for (unsigned i = 0, n = protocols.size(); i != n; ++i) - ObjCObjectTL.setProtocolLoc(i, protocolLocs[i]); - - // We're done. Return the completed type to the parser. - return CreateParsedType(Result, ResultTInfo); -} - -TypeResult Sema::actOnObjCTypeArgsAndProtocolQualifiers( - Scope *S, - SourceLocation Loc, - ParsedType BaseType, - SourceLocation TypeArgsLAngleLoc, - ArrayRef TypeArgs, - SourceLocation TypeArgsRAngleLoc, - SourceLocation ProtocolLAngleLoc, - ArrayRef Protocols, - ArrayRef ProtocolLocs, - SourceLocation ProtocolRAngleLoc) { - TypeSourceInfo *BaseTypeInfo = nullptr; - QualType T = GetTypeFromParser(BaseType, &BaseTypeInfo); - if (T.isNull()) - return true; - - // Handle missing type-source info. - if (!BaseTypeInfo) - BaseTypeInfo = Context.getTrivialTypeSourceInfo(T, Loc); - - // Extract type arguments. - SmallVector ActualTypeArgInfos; - for (unsigned i = 0, n = TypeArgs.size(); i != n; ++i) { - TypeSourceInfo *TypeArgInfo = nullptr; - QualType TypeArg = GetTypeFromParser(TypeArgs[i], &TypeArgInfo); - if (TypeArg.isNull()) { - ActualTypeArgInfos.clear(); - break; - } - - assert(TypeArgInfo && "No type source info?"); - ActualTypeArgInfos.push_back(TypeArgInfo); - } - - // Build the object type. - QualType Result = BuildObjCObjectType( - T, BaseTypeInfo->getTypeLoc().getSourceRange().getBegin(), - TypeArgsLAngleLoc, ActualTypeArgInfos, TypeArgsRAngleLoc, - ProtocolLAngleLoc, - llvm::ArrayRef((ObjCProtocolDecl *const *)Protocols.data(), - Protocols.size()), - ProtocolLocs, ProtocolRAngleLoc, - /*FailOnError=*/false, - /*Rebuilding=*/false); - - if (Result == T) - return BaseType; - - // Create source information for this type. - TypeSourceInfo *ResultTInfo = Context.CreateTypeSourceInfo(Result); - TypeLoc ResultTL = ResultTInfo->getTypeLoc(); - - // For id or Class, we'll have an - // object pointer type. Fill in source information for it. - if (auto ObjCObjectPointerTL = ResultTL.getAs()) { - // The '*' is implicit. - ObjCObjectPointerTL.setStarLoc(SourceLocation()); - ResultTL = ObjCObjectPointerTL.getPointeeLoc(); - } - - if (auto OTPTL = ResultTL.getAs()) { - // Protocol qualifier information. - if (OTPTL.getNumProtocols() > 0) { - assert(OTPTL.getNumProtocols() == Protocols.size()); - OTPTL.setProtocolLAngleLoc(ProtocolLAngleLoc); - OTPTL.setProtocolRAngleLoc(ProtocolRAngleLoc); - for (unsigned i = 0, n = Protocols.size(); i != n; ++i) - OTPTL.setProtocolLoc(i, ProtocolLocs[i]); - } - - // We're done. Return the completed type to the parser. - return CreateParsedType(Result, ResultTInfo); - } - - auto ObjCObjectTL = ResultTL.castAs(); - - // Type argument information. - if (ObjCObjectTL.getNumTypeArgs() > 0) { - assert(ObjCObjectTL.getNumTypeArgs() == ActualTypeArgInfos.size()); - ObjCObjectTL.setTypeArgsLAngleLoc(TypeArgsLAngleLoc); - ObjCObjectTL.setTypeArgsRAngleLoc(TypeArgsRAngleLoc); - for (unsigned i = 0, n = ActualTypeArgInfos.size(); i != n; ++i) - ObjCObjectTL.setTypeArgTInfo(i, ActualTypeArgInfos[i]); - } else { - ObjCObjectTL.setTypeArgsLAngleLoc(SourceLocation()); - ObjCObjectTL.setTypeArgsRAngleLoc(SourceLocation()); - } - - // Protocol qualifier information. - if (ObjCObjectTL.getNumProtocols() > 0) { - assert(ObjCObjectTL.getNumProtocols() == Protocols.size()); - ObjCObjectTL.setProtocolLAngleLoc(ProtocolLAngleLoc); - ObjCObjectTL.setProtocolRAngleLoc(ProtocolRAngleLoc); - for (unsigned i = 0, n = Protocols.size(); i != n; ++i) - ObjCObjectTL.setProtocolLoc(i, ProtocolLocs[i]); - } else { - ObjCObjectTL.setProtocolLAngleLoc(SourceLocation()); - ObjCObjectTL.setProtocolRAngleLoc(SourceLocation()); - } - - // Base type. - ObjCObjectTL.setHasBaseTypeAsWritten(true); - if (ObjCObjectTL.getType() == T) - ObjCObjectTL.getBaseLoc().initializeFullCopy(BaseTypeInfo->getTypeLoc()); - else - ObjCObjectTL.getBaseLoc().initialize(Context, Loc); - - // We're done. Return the completed type to the parser. - return CreateParsedType(Result, ResultTInfo); -} - static OpenCLAccessAttr::Spelling getImageAccess(const ParsedAttributesView &Attrs) { for (const ParsedAttr &AL : Attrs) @@ -4259,14 +3842,6 @@ IdentifierInfo *Sema::getNullabilityKeyword(NullabilityKind nullability) { llvm_unreachable("Unknown nullability kind."); } -/// Retrieve the identifier "NSError". -IdentifierInfo *Sema::getNSErrorIdent() { - if (!Ident_NSError) - Ident_NSError = PP.getIdentifierInfo("NSError"); - - return Ident_NSError; -} - /// Check whether there is a nullability attribute of any kind in the given /// attribute list. static bool hasNullabilityAttr(const ParsedAttributesView &attrs) { @@ -4392,7 +3967,7 @@ classifyPointerDeclarator(Sema &S, QualType type, Declarator &declarator, // If this is NSError**, report that. if (auto objcClassDecl = objcObjectPtr->getInterfaceDecl()) { - if (objcClassDecl->getIdentifier() == S.getNSErrorIdent() && + if (objcClassDecl->getIdentifier() == S.ObjC().getNSErrorIdent() && numNormalPointers == 2 && numTypeSpecifierPointers < 2) { return PointerDeclaratorKind::NSErrorPointerPointer; } @@ -4403,7 +3978,7 @@ classifyPointerDeclarator(Sema &S, QualType type, Declarator &declarator, // Look at Objective-C class types. if (auto objcClass = type->getAs()) { - if (objcClass->getInterface()->getIdentifier() == S.getNSErrorIdent()) { + if (objcClass->getInterface()->getIdentifier() == S.ObjC().getNSErrorIdent()) { if (numNormalPointers == 2 && numTypeSpecifierPointers < 2) return PointerDeclaratorKind::NSErrorPointerPointer; } @@ -4420,7 +3995,7 @@ classifyPointerDeclarator(Sema &S, QualType type, Declarator &declarator, // If this is CFErrorRef*, report it as such. if (numNormalPointers == 2 && numTypeSpecifierPointers < 2 && - S.isCFError(recordDecl)) { + S.ObjC().isCFError(recordDecl)) { return PointerDeclaratorKind::CFErrorRefPointer; } break; @@ -4444,31 +4019,6 @@ classifyPointerDeclarator(Sema &S, QualType type, Declarator &declarator, } } -bool Sema::isCFError(RecordDecl *RD) { - // If we already know about CFError, test it directly. - if (CFError) - return CFError == RD; - - // Check whether this is CFError, which we identify based on its bridge to - // NSError. CFErrorRef used to be declared with "objc_bridge" but is now - // declared with "objc_bridge_mutable", so look for either one of the two - // attributes. - if (RD->getTagKind() == TagTypeKind::Struct) { - IdentifierInfo *bridgedType = nullptr; - if (auto bridgeAttr = RD->getAttr()) - bridgedType = bridgeAttr->getBridgedType(); - else if (auto bridgeAttr = RD->getAttr()) - bridgedType = bridgeAttr->getBridgedType(); - - if (bridgedType == getNSErrorIdent()) { - CFError = RD; - return true; - } - } - - return false; -} - static FileID getNullabilityCompletenessCheckFileID(Sema &S, SourceLocation loc) { // If we're anywhere in a function, method, or closure context, don't perform @@ -6838,12 +6388,6 @@ TypeResult Sema::ActOnTypeName(Declarator &D) { return CreateParsedType(T, TInfo); } -ParsedType Sema::ActOnObjCInstanceType(SourceLocation Loc) { - QualType T = Context.getObjCInstanceType(); - TypeSourceInfo *TInfo = Context.getTrivialTypeSourceInfo(T, Loc); - return CreateParsedType(T, TInfo); -} - //===----------------------------------------------------------------------===// // Type Attribute Processing //===----------------------------------------------------------------------===// diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index eb05783a6219d..55454a63cc9eb 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -39,6 +39,7 @@ #include "clang/Sema/ScopeInfo.h" #include "clang/Sema/SemaDiagnostic.h" #include "clang/Sema/SemaInternal.h" +#include "clang/Sema/SemaObjC.h" #include "clang/Sema/SemaOpenACC.h" #include "clang/Sema/SemaOpenMP.h" #include "clang/Sema/SemaSYCL.h" @@ -1606,7 +1607,7 @@ class TreeTransform { Stmt *TryBody, MultiStmtArg CatchStmts, Stmt *Finally) { - return getSema().ActOnObjCAtTryStmt(AtLoc, TryBody, CatchStmts, + return getSema().ObjC().ActOnObjCAtTryStmt(AtLoc, TryBody, CatchStmts, Finally); } @@ -1616,7 +1617,7 @@ class TreeTransform { /// Subclasses may override this routine to provide different behavior. VarDecl *RebuildObjCExceptionDecl(VarDecl *ExceptionDecl, TypeSourceInfo *TInfo, QualType T) { - return getSema().BuildObjCExceptionDecl(TInfo, T, + return getSema().ObjC().BuildObjCExceptionDecl(TInfo, T, ExceptionDecl->getInnerLocStart(), ExceptionDecl->getLocation(), ExceptionDecl->getIdentifier()); @@ -1630,7 +1631,7 @@ class TreeTransform { SourceLocation RParenLoc, VarDecl *Var, Stmt *Body) { - return getSema().ActOnObjCAtCatchStmt(AtLoc, RParenLoc, + return getSema().ObjC().ActOnObjCAtCatchStmt(AtLoc, RParenLoc, Var, Body); } @@ -1640,7 +1641,7 @@ class TreeTransform { /// Subclasses may override this routine to provide different behavior. StmtResult RebuildObjCAtFinallyStmt(SourceLocation AtLoc, Stmt *Body) { - return getSema().ActOnObjCAtFinallyStmt(AtLoc, Body); + return getSema().ObjC().ActOnObjCAtFinallyStmt(AtLoc, Body); } /// Build a new Objective-C \@throw statement. @@ -1649,7 +1650,7 @@ class TreeTransform { /// Subclasses may override this routine to provide different behavior. StmtResult RebuildObjCAtThrowStmt(SourceLocation AtLoc, Expr *Operand) { - return getSema().BuildObjCAtThrowStmt(AtLoc, Operand); + return getSema().ObjC().BuildObjCAtThrowStmt(AtLoc, Operand); } /// Build a new OpenMP Canonical loop. @@ -2489,7 +2490,7 @@ class TreeTransform { /// Subclasses may override this routine to provide different behavior. ExprResult RebuildObjCAtSynchronizedOperand(SourceLocation atLoc, Expr *object) { - return getSema().ActOnObjCAtSynchronizedOperand(atLoc, object); + return getSema().ObjC().ActOnObjCAtSynchronizedOperand(atLoc, object); } /// Build a new Objective-C \@synchronized statement. @@ -2498,7 +2499,7 @@ class TreeTransform { /// Subclasses may override this routine to provide different behavior. StmtResult RebuildObjCAtSynchronizedStmt(SourceLocation AtLoc, Expr *Object, Stmt *Body) { - return getSema().ActOnObjCAtSynchronizedStmt(AtLoc, Object, Body); + return getSema().ObjC().ActOnObjCAtSynchronizedStmt(AtLoc, Object, Body); } /// Build a new Objective-C \@autoreleasepool statement. @@ -2507,7 +2508,7 @@ class TreeTransform { /// Subclasses may override this routine to provide different behavior. StmtResult RebuildObjCAutoreleasePoolStmt(SourceLocation AtLoc, Stmt *Body) { - return getSema().ActOnObjCAutoreleasePoolStmt(AtLoc, Body); + return getSema().ObjC().ActOnObjCAutoreleasePoolStmt(AtLoc, Body); } /// Build a new Objective-C fast enumeration statement. @@ -2519,14 +2520,14 @@ class TreeTransform { Expr *Collection, SourceLocation RParenLoc, Stmt *Body) { - StmtResult ForEachStmt = getSema().ActOnObjCForCollectionStmt(ForLoc, + StmtResult ForEachStmt = getSema().ObjC().ActOnObjCForCollectionStmt(ForLoc, Element, Collection, RParenLoc); if (ForEachStmt.isInvalid()) return StmtError(); - return getSema().FinishObjCForCollectionStmt(ForEachStmt.get(), Body); + return getSema().ObjC().FinishObjCForCollectionStmt(ForEachStmt.get(), Body); } /// Build a new C++ exception declaration. @@ -2592,7 +2593,7 @@ class TreeTransform { diag::err_objc_for_range_init_stmt) << Init->getSourceRange(); } - return getSema().ActOnObjCForCollectionStmt(ForLoc, LoopVar, + return getSema().ObjC().ActOnObjCForCollectionStmt(ForLoc, LoopVar, RangeExpr, RParenLoc); } } @@ -3708,7 +3709,7 @@ class TreeTransform { /// By default, performs semantic analysis to build the new expression. /// Subclasses may override this routine to provide different behavior. ExprResult RebuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr) { - return getSema().BuildObjCBoxedExpr(SR, ValueExpr); + return getSema().ObjC().BuildObjCBoxedExpr(SR, ValueExpr); } /// Build a new Objective-C array literal. @@ -3717,7 +3718,7 @@ class TreeTransform { /// Subclasses may override this routine to provide different behavior. ExprResult RebuildObjCArrayLiteral(SourceRange Range, Expr **Elements, unsigned NumElements) { - return getSema().BuildObjCArrayLiteral(Range, + return getSema().ObjC().BuildObjCArrayLiteral(Range, MultiExprArg(Elements, NumElements)); } @@ -3725,7 +3726,7 @@ class TreeTransform { Expr *Base, Expr *Key, ObjCMethodDecl *getterMethod, ObjCMethodDecl *setterMethod) { - return getSema().BuildObjCSubscriptExpression(RB, Base, Key, + return getSema().ObjC().BuildObjCSubscriptExpression(RB, Base, Key, getterMethod, setterMethod); } @@ -3735,7 +3736,7 @@ class TreeTransform { /// Subclasses may override this routine to provide different behavior. ExprResult RebuildObjCDictionaryLiteral(SourceRange Range, MutableArrayRef Elements) { - return getSema().BuildObjCDictionaryLiteral(Range, Elements); + return getSema().ObjC().BuildObjCDictionaryLiteral(Range, Elements); } /// Build a new Objective-C \@encode expression. @@ -3745,7 +3746,7 @@ class TreeTransform { ExprResult RebuildObjCEncodeExpr(SourceLocation AtLoc, TypeSourceInfo *EncodeTypeInfo, SourceLocation RParenLoc) { - return SemaRef.BuildObjCEncodeExpression(AtLoc, EncodeTypeInfo, RParenLoc); + return SemaRef.ObjC().BuildObjCEncodeExpression(AtLoc, EncodeTypeInfo, RParenLoc); } /// Build a new Objective-C class message. @@ -3756,7 +3757,7 @@ class TreeTransform { SourceLocation LBracLoc, MultiExprArg Args, SourceLocation RBracLoc) { - return SemaRef.BuildClassMessage(ReceiverTypeInfo, + return SemaRef.ObjC().BuildClassMessage(ReceiverTypeInfo, ReceiverTypeInfo->getType(), /*SuperLoc=*/SourceLocation(), Sel, Method, LBracLoc, SelectorLocs, @@ -3771,7 +3772,7 @@ class TreeTransform { SourceLocation LBracLoc, MultiExprArg Args, SourceLocation RBracLoc) { - return SemaRef.BuildInstanceMessage(Receiver, + return SemaRef.ObjC().BuildInstanceMessage(Receiver, Receiver->getType(), /*SuperLoc=*/SourceLocation(), Sel, Method, LBracLoc, SelectorLocs, @@ -3787,12 +3788,12 @@ class TreeTransform { SourceLocation LBracLoc, MultiExprArg Args, SourceLocation RBracLoc) { - return Method->isInstanceMethod() ? SemaRef.BuildInstanceMessage(nullptr, + return Method->isInstanceMethod() ? SemaRef.ObjC().BuildInstanceMessage(nullptr, SuperType, SuperLoc, Sel, Method, LBracLoc, SelectorLocs, RBracLoc, Args) - : SemaRef.BuildClassMessage(nullptr, + : SemaRef.ObjC().BuildClassMessage(nullptr, SuperType, SuperLoc, Sel, Method, LBracLoc, SelectorLocs, @@ -15081,7 +15082,7 @@ TransformObjCBridgedCastExpr(ObjCBridgedCastExpr *E) { Result.get() == E->getSubExpr()) return E; - return SemaRef.BuildObjCBridgedCast(E->getLParenLoc(), E->getBridgeKind(), + return SemaRef.ObjC().BuildObjCBridgedCast(E->getLParenLoc(), E->getBridgeKind(), E->getBridgeKeywordLoc(), TSInfo, Result.get()); } @@ -15471,7 +15472,7 @@ QualType TreeTransform::RebuildObjCTypeParamType( ArrayRef Protocols, ArrayRef ProtocolLocs, SourceLocation ProtocolRAngleLoc) { - return SemaRef.BuildObjCTypeParamType(Decl, + return SemaRef.ObjC().BuildObjCTypeParamType(Decl, ProtocolLAngleLoc, Protocols, ProtocolLocs, ProtocolRAngleLoc, /*FailOnError=*/true); @@ -15488,7 +15489,7 @@ QualType TreeTransform::RebuildObjCObjectType( ArrayRef Protocols, ArrayRef ProtocolLocs, SourceLocation ProtocolRAngleLoc) { - return SemaRef.BuildObjCObjectType(BaseType, Loc, TypeArgsLAngleLoc, TypeArgs, + return SemaRef.ObjC().BuildObjCObjectType(BaseType, Loc, TypeArgsLAngleLoc, TypeArgs, TypeArgsRAngleLoc, ProtocolLAngleLoc, Protocols, ProtocolLocs, ProtocolRAngleLoc, /*FailOnError=*/true, diff --git a/clang/lib/Serialization/ASTCommon.cpp b/clang/lib/Serialization/ASTCommon.cpp index f8d54c0c39890..91152e351d830 100644 --- a/clang/lib/Serialization/ASTCommon.cpp +++ b/clang/lib/Serialization/ASTCommon.cpp @@ -338,7 +338,7 @@ serialization::getDefinitiveDeclContext(const DeclContext *DC) { // FIXME: These are defined in one place, but properties in class extensions // end up being back-patched into the main interface. See - // Sema::HandlePropertyInClassExtension for the offending code. + // SemaObjC::HandlePropertyInClassExtension for the offending code. case Decl::ObjCInterface: return nullptr; diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index b28df03b4a95e..88e06842d9db8 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -78,6 +78,7 @@ #include "clang/Sema/Scope.h" #include "clang/Sema/Sema.h" #include "clang/Sema/SemaCUDA.h" +#include "clang/Sema/SemaObjC.h" #include "clang/Sema/Weak.h" #include "clang/Serialization/ASTBitCodes.h" #include "clang/Serialization/ASTDeserializationListener.h" @@ -4244,9 +4245,9 @@ ASTReader::ReadModuleMapFileBlock(RecordData &Record, ModuleFile &F, /// Move the given method to the back of the global list of methods. static void moveMethodToBackOfGlobalList(Sema &S, ObjCMethodDecl *Method) { // Find the entry for this selector in the method pool. - Sema::GlobalMethodPool::iterator Known - = S.MethodPool.find(Method->getSelector()); - if (Known == S.MethodPool.end()) + SemaObjC::GlobalMethodPool::iterator Known + = S.ObjC().MethodPool.find(Method->getSelector()); + if (Known == S.ObjC().MethodPool.end()) return; // Retrieve the appropriate method list. @@ -8557,7 +8558,7 @@ namespace serialization { static void addMethodsToPool(Sema &S, ArrayRef Methods, ObjCMethodList &List) { for (ObjCMethodDecl *M : llvm::reverse(Methods)) - S.addMethodToGlobalList(&List, M); + S.ObjC().addMethodToGlobalList(&List, M); } void ASTReader::ReadMethodPool(Selector Sel) { @@ -8582,8 +8583,8 @@ void ASTReader::ReadMethodPool(Selector Sel) { return; Sema &S = *getSema(); - Sema::GlobalMethodPool::iterator Pos = - S.MethodPool.insert(std::make_pair(Sel, Sema::GlobalMethodPool::Lists())) + SemaObjC::GlobalMethodPool::iterator Pos = + S.ObjC().MethodPool.insert(std::make_pair(Sel, SemaObjC::GlobalMethodPool::Lists())) .first; Pos->second.first.setBits(Visitor.getInstanceBits()); diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index b2a078b6d80f4..3dfb8fc116d89 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -66,6 +66,7 @@ #include "clang/Sema/ObjCMethodList.h" #include "clang/Sema/Sema.h" #include "clang/Sema/SemaCUDA.h" +#include "clang/Sema/SemaObjC.h" #include "clang/Sema/Weak.h" #include "clang/Serialization/ASTBitCodes.h" #include "clang/Serialization/ASTReader.h" @@ -3436,7 +3437,7 @@ void ASTWriter::WriteSelectors(Sema &SemaRef) { using namespace llvm; // Do we have to do anything at all? - if (SemaRef.MethodPool.empty() && SelectorIDs.empty()) + if (SemaRef.ObjC().MethodPool.empty() && SelectorIDs.empty()) return; unsigned NumTableEntries = 0; // Create and write out the blob that contains selectors and the method pool. @@ -3450,13 +3451,13 @@ void ASTWriter::WriteSelectors(Sema &SemaRef) { for (auto &SelectorAndID : SelectorIDs) { Selector S = SelectorAndID.first; SelectorID ID = SelectorAndID.second; - Sema::GlobalMethodPool::iterator F = SemaRef.MethodPool.find(S); + SemaObjC::GlobalMethodPool::iterator F = SemaRef.ObjC().MethodPool.find(S); ASTMethodPoolTrait::data_type Data = { ID, ObjCMethodList(), ObjCMethodList() }; - if (F != SemaRef.MethodPool.end()) { + if (F != SemaRef.ObjC().MethodPool.end()) { Data.Instance = F->second.first; Data.Factory = F->second.second; } @@ -3541,7 +3542,7 @@ void ASTWriter::WriteSelectors(Sema &SemaRef) { void ASTWriter::WriteReferencedSelectorsPool(Sema &SemaRef) { using namespace llvm; - if (SemaRef.ReferencedSelectors.empty()) + if (SemaRef.ObjC().ReferencedSelectors.empty()) return; RecordData Record; @@ -3550,7 +3551,7 @@ void ASTWriter::WriteReferencedSelectorsPool(Sema &SemaRef) { // Note: this writes out all references even for a dependent AST. But it is // very tricky to fix, and given that @selector shouldn't really appear in // headers, probably not worth it. It's not a correctness issue. - for (auto &SelectorAndLocation : SemaRef.ReferencedSelectors) { + for (auto &SelectorAndLocation : SemaRef.ObjC().ReferencedSelectors) { Selector Sel = SelectorAndLocation.first; SourceLocation Loc = SelectorAndLocation.second; Writer.AddSelectorRef(Sel); @@ -5081,7 +5082,7 @@ ASTFileSignature ASTWriter::WriteASTCore(Sema &SemaRef, StringRef isysroot, for (auto &SelectorAndID : SelectorIDs) AllSelectors.push_back(SelectorAndID.first); for (auto &Selector : AllSelectors) - SemaRef.updateOutOfDateSelector(Selector); + SemaRef.ObjC().updateOutOfDateSelector(Selector); // Form the record of special types. RecordData SpecialTypes; From 520b7fe2990ab92169e718647181499577410ac4 Mon Sep 17 00:00:00 2001 From: Vlad Serebrennikov Date: Wed, 17 Apr 2024 18:18:15 +0300 Subject: [PATCH 2/3] Run clang-format --- clang/include/clang/Parse/Parser.h | 4 +- clang/include/clang/Sema/SemaObjC.h | 7 +- clang/lib/Parse/ParseDecl.cpp | 2 +- clang/lib/Parse/ParseExpr.cpp | 12 +- clang/lib/Parse/ParseObjc.cpp | 162 +++-- clang/lib/Parse/ParseStmt.cpp | 10 +- clang/lib/Sema/SemaCast.cpp | 4 +- clang/lib/Sema/SemaChecking.cpp | 10 +- clang/lib/Sema/SemaCodeComplete.cpp | 17 +- clang/lib/Sema/SemaDecl.cpp | 3 +- clang/lib/Sema/SemaDeclObjC.cpp | 819 +++++++++++++------------- clang/lib/Sema/SemaExpr.cpp | 37 +- clang/lib/Sema/SemaExprCXX.cpp | 6 +- clang/lib/Sema/SemaExprMember.cpp | 9 +- clang/lib/Sema/SemaExprObjC.cpp | 743 ++++++++++++----------- clang/lib/Sema/SemaInit.cpp | 8 +- clang/lib/Sema/SemaObjC.cpp | 433 +++++++------- clang/lib/Sema/SemaObjCProperty.cpp | 205 +++---- clang/lib/Sema/SemaOverload.cpp | 2 +- clang/lib/Sema/SemaPseudoObject.cpp | 85 ++- clang/lib/Sema/SemaType.cpp | 3 +- clang/lib/Sema/TreeTransform.h | 96 ++- clang/lib/Serialization/ASTReader.cpp | 8 +- clang/lib/Serialization/ASTWriter.cpp | 3 +- 24 files changed, 1299 insertions(+), 1389 deletions(-) diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index 2ba33bcc273d2..9e30b5f74a3dd 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -422,8 +422,8 @@ class Parser : public CodeCompletionHandler { /// True if we are within an Objective-C container while parsing C-like decls. /// /// This is necessary because Sema thinks we have left the container - /// to parse the C-like decls, meaning Actions.ObjC().getObjCDeclContext() will - /// be NULL. + /// to parse the C-like decls, meaning Actions.ObjC().getObjCDeclContext() + /// will be NULL. bool ParsingInObjCContainer; /// Whether to skip parsing of function bodies. diff --git a/clang/include/clang/Sema/SemaObjC.h b/clang/include/clang/Sema/SemaObjC.h index 7884af42365a3..a9a0d16780956 100644 --- a/clang/include/clang/Sema/SemaObjC.h +++ b/clang/include/clang/Sema/SemaObjC.h @@ -137,9 +137,9 @@ class SemaObjC : public SemaBase { const DeclContext *getCurObjCLexicalContext() const; - ObjCProtocolDecl * - LookupProtocol(IdentifierInfo *II, SourceLocation IdLoc, - RedeclarationKind Redecl = RedeclarationKind::NotForRedeclaration); + ObjCProtocolDecl *LookupProtocol( + IdentifierInfo *II, SourceLocation IdLoc, + RedeclarationKind Redecl = RedeclarationKind::NotForRedeclaration); bool isObjCWritebackConversion(QualType FromType, QualType ToType, QualType &ConvertedType); @@ -1007,7 +1007,6 @@ class SemaObjC : public SemaBase { ObjCInterfaceDecl *IDecl); ///@} - }; } // namespace clang diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index b678c67032b42..817e72de84825 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -4974,7 +4974,7 @@ void Parser::ParseStructUnionBody(SourceLocation RecordLoc, } SmallVector Fields; Actions.ObjC().ActOnDefs(getCurScope(), TagDecl, Tok.getLocation(), - Tok.getIdentifierInfo(), Fields); + Tok.getIdentifierInfo(), Fields); ConsumeToken(); ExpectAndConsume(tok::r_paren); } diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp index ec0c560f0b627..a01521b55d8e2 100644 --- a/clang/lib/Parse/ParseExpr.cpp +++ b/clang/lib/Parse/ParseExpr.cpp @@ -1228,8 +1228,8 @@ ExprResult Parser::ParseCastExpression(CastParseKind ParseKind, IdentifierInfo &PropertyName = *Tok.getIdentifierInfo(); SourceLocation PropertyLoc = ConsumeToken(); - Res = Actions.ObjC().ActOnClassPropertyRefExpr(II, PropertyName, - ILoc, PropertyLoc); + Res = Actions.ObjC().ActOnClassPropertyRefExpr(II, PropertyName, ILoc, + PropertyLoc); break; } @@ -3087,8 +3087,8 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr, return ExprError(); return Actions.ObjC().ActOnObjCBridgedCast(getCurScope(), OpenLoc, Kind, - BridgeKeywordLoc, Ty.get(), - RParenLoc, SubExpr.get()); + BridgeKeywordLoc, Ty.get(), + RParenLoc, SubExpr.get()); } else if (ExprType >= CompoundLiteral && isTypeIdInParens(isAmbiguousTypeId)) { @@ -3925,6 +3925,6 @@ ExprResult Parser::ParseAvailabilityCheckExpr(SourceLocation BeginLoc) { if (Parens.consumeClose()) return ExprError(); - return Actions.ObjC().ActOnObjCAvailabilityCheckExpr(AvailSpecs, BeginLoc, - Parens.getCloseLocation()); + return Actions.ObjC().ActOnObjCAvailabilityCheckExpr( + AvailSpecs, BeginLoc, Parens.getCloseLocation()); } diff --git a/clang/lib/Parse/ParseObjc.cpp b/clang/lib/Parse/ParseObjc.cpp index 8d28311b3d7b2..3e3d47a31ba0c 100644 --- a/clang/lib/Parse/ParseObjc.cpp +++ b/clang/lib/Parse/ParseObjc.cpp @@ -19,8 +19,8 @@ #include "clang/Parse/Parser.h" #include "clang/Parse/RAIIObjectsForParser.h" #include "clang/Sema/DeclSpec.h" -#include "clang/Sema/SemaObjC.h" #include "clang/Sema/Scope.h" +#include "clang/Sema/SemaObjC.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringExtras.h" @@ -180,10 +180,9 @@ Parser::ParseObjCAtClassDeclaration(SourceLocation atLoc) { if (ExpectAndConsume(tok::semi, diag::err_expected_after, "@class")) return Actions.ConvertDeclToDeclGroup(nullptr); - return Actions.ObjC().ActOnForwardClassDeclaration(atLoc, ClassNames.data(), - ClassLocs.data(), - ClassTypeParams, - ClassNames.size()); + return Actions.ObjC().ActOnForwardClassDeclaration( + atLoc, ClassNames.data(), ClassLocs.data(), ClassTypeParams, + ClassNames.size()); } void Parser::CheckNestedObjCContexts(SourceLocation AtLoc) @@ -362,8 +361,8 @@ Decl *Parser::ParseObjCAtInterfaceDeclaration(SourceLocation AtLoc, protocolLocs.push_back(pair.second); } Actions.ObjC().FindProtocolDeclaration(/*WarnOnDeclarations=*/true, - /*ForObjCContainer=*/true, - ProtocolIdents, protocols); + /*ForObjCContainer=*/true, + ProtocolIdents, protocols); } } else if (protocols.empty() && Tok.is(tok::less) && ParseObjCProtocolReferences(protocols, protocolLocs, true, true, @@ -374,7 +373,7 @@ Decl *Parser::ParseObjCAtInterfaceDeclaration(SourceLocation AtLoc, if (Tok.isNot(tok::less)) Actions.ObjC().ActOnTypedefedProtocols(protocols, protocolLocs, - superClassId, superClassLoc); + superClassId, superClassLoc); SkipBodyInfo SkipBody; ObjCInterfaceDecl *ClsType = Actions.ObjC().ActOnStartClassInterface( @@ -589,10 +588,7 @@ ObjCTypeParamList *Parser::parseObjCTypeParamListOrProtocolRefs( // Form the type parameter list and enter its scope. ObjCTypeParamList *list = Actions.ObjC().actOnObjCTypeParamList( - getCurScope(), - lAngleLoc, - typeParams, - rAngleLoc); + getCurScope(), lAngleLoc, typeParams, rAngleLoc); Scope.enter(list); // Clear out the angle locations; they're used by the caller to indicate @@ -1611,7 +1607,7 @@ ParseObjCProtocolReferences(SmallVectorImpl &Protocols, // Convert the list of protocols identifiers into a list of protocol decls. Actions.ObjC().FindProtocolDeclaration(WarnOnDeclarations, ForObjCContainer, - ProtocolIdents, Protocols); + ProtocolIdents, Protocols); return false; } @@ -1625,10 +1621,8 @@ TypeResult Parser::parseObjCProtocolQualifierType(SourceLocation &rAngleLoc) { (void)ParseObjCProtocolReferences(protocols, protocolLocs, false, false, lAngleLoc, rAngleLoc, /*consumeLastToken=*/true); - TypeResult result = Actions.ObjC().actOnObjCProtocolQualifierType(lAngleLoc, - protocols, - protocolLocs, - rAngleLoc); + TypeResult result = Actions.ObjC().actOnObjCProtocolQualifierType( + lAngleLoc, protocols, protocolLocs, rAngleLoc); if (result.isUsable()) { Diag(lAngleLoc, diag::warn_objc_protocol_qualifier_missing_id) << FixItHint::CreateInsertion(lAngleLoc, "id") @@ -1707,19 +1701,11 @@ void Parser::parseObjCTypeArgsOrProtocolQualifiers( /*ObjCGenericList=*/true); // Let Sema figure out what we parsed. - Actions.ObjC().actOnObjCTypeArgsOrProtocolQualifiers(getCurScope(), - baseType, - lAngleLoc, - identifiers, - identifierLocs, - rAngleLoc, - typeArgsLAngleLoc, - typeArgs, - typeArgsRAngleLoc, - protocolLAngleLoc, - protocols, - protocolRAngleLoc, - warnOnIncompleteProtocols); + Actions.ObjC().actOnObjCTypeArgsOrProtocolQualifiers( + getCurScope(), baseType, lAngleLoc, identifiers, identifierLocs, + rAngleLoc, typeArgsLAngleLoc, typeArgs, typeArgsRAngleLoc, + protocolLAngleLoc, protocols, protocolRAngleLoc, + warnOnIncompleteProtocols); return; } @@ -1797,9 +1783,9 @@ void Parser::parseObjCTypeArgsOrProtocolQualifiers( // Diagnose the mix between type args and protocols. if (foundProtocolId && foundValidTypeId) - Actions.ObjC().DiagnoseTypeArgsAndProtocols(foundProtocolId, foundProtocolSrcLoc, - foundValidTypeId, - foundValidTypeSrcLoc); + Actions.ObjC().DiagnoseTypeArgsAndProtocols( + foundProtocolId, foundProtocolSrcLoc, foundValidTypeId, + foundValidTypeSrcLoc); // Diagnose unknown arg types. ParsedType T; @@ -1906,16 +1892,8 @@ TypeResult Parser::parseObjCTypeArgsAndProtocolQualifiers( endLoc = Tok.getLocation(); return Actions.ObjC().actOnObjCTypeArgsAndProtocolQualifiers( - getCurScope(), - loc, - type, - typeArgsLAngleLoc, - typeArgs, - typeArgsRAngleLoc, - protocolLAngleLoc, - protocols, - protocolLocs, - protocolRAngleLoc); + getCurScope(), loc, type, typeArgsLAngleLoc, typeArgs, typeArgsRAngleLoc, + protocolLAngleLoc, protocols, protocolLocs, protocolRAngleLoc); } void Parser::HelperActionsForIvarDeclarations( @@ -2093,7 +2071,8 @@ Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc, if (TryConsumeToken(tok::semi)) { // forward declaration of one protocol. IdentifierLocPair ProtoInfo(protocolName, nameLoc); - return Actions.ObjC().ActOnForwardProtocolDeclaration(AtLoc, ProtoInfo, attrs); + return Actions.ObjC().ActOnForwardProtocolDeclaration(AtLoc, ProtoInfo, + attrs); } CheckNestedObjCContexts(AtLoc); @@ -2120,7 +2099,8 @@ Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc, if (ExpectAndConsume(tok::semi, diag::err_expected_after, "@protocol")) return nullptr; - return Actions.ObjC().ActOnForwardProtocolDeclaration(AtLoc, ProtocolRefs, attrs); + return Actions.ObjC().ActOnForwardProtocolDeclaration(AtLoc, ProtocolRefs, + attrs); } // Last, and definitely not least, parse a protocol declaration. @@ -2292,7 +2272,8 @@ Parser::ParseObjCAtImplementationDeclaration(SourceLocation AtLoc, } } - return Actions.ObjC().ActOnFinishObjCImplementation(ObjCImpDecl, DeclsInGroup); + return Actions.ObjC().ActOnFinishObjCImplementation(ObjCImpDecl, + DeclsInGroup); } Parser::DeclGroupPtrTy @@ -2324,7 +2305,8 @@ Parser::ObjCImplParsingDataRAII::~ObjCImplParsingDataRAII() { void Parser::ObjCImplParsingDataRAII::finish(SourceRange AtEnd) { assert(!Finished); - P.Actions.ObjC().DefaultSynthesizeProperties(P.getCurScope(), Dcl, AtEnd.getBegin()); + P.Actions.ObjC().DefaultSynthesizeProperties(P.getCurScope(), Dcl, + AtEnd.getBegin()); for (size_t i = 0; i < LateParsedObjCMethods.size(); ++i) P.ParseLexedObjCMethodDefs(*LateParsedObjCMethods[i], true/*Methods*/); @@ -2363,7 +2345,7 @@ Decl *Parser::ParseObjCAtAliasDeclaration(SourceLocation atLoc) { SourceLocation classLoc = ConsumeToken(); // consume class-name; ExpectAndConsume(tok::semi, diag::err_expected_after, "@compatibility_alias"); return Actions.ObjC().ActOnCompatibilityAlias(atLoc, aliasId, aliasLoc, - classId, classLoc); + classId, classLoc); } /// property-synthesis: @@ -2413,9 +2395,8 @@ Decl *Parser::ParseObjCPropertySynthesize(SourceLocation atLoc) { propertyIvarLoc = ConsumeToken(); // consume ivar-name } Actions.ObjC().ActOnPropertyImplDecl( - getCurScope(), atLoc, propertyLoc, true, - propertyId, propertyIvar, propertyIvarLoc, - ObjCPropertyQueryKind::OBJC_PR_query_unknown); + getCurScope(), atLoc, propertyLoc, true, propertyId, propertyIvar, + propertyIvarLoc, ObjCPropertyQueryKind::OBJC_PR_query_unknown); if (Tok.isNot(tok::comma)) break; ConsumeToken(); // consume ',' @@ -2475,10 +2456,10 @@ Decl *Parser::ParseObjCPropertyDynamic(SourceLocation atLoc) { IdentifierInfo *propertyId = Tok.getIdentifierInfo(); SourceLocation propertyLoc = ConsumeToken(); // consume property name Actions.ObjC().ActOnPropertyImplDecl( - getCurScope(), atLoc, propertyLoc, false, - propertyId, nullptr, SourceLocation(), - isClassProperty ? ObjCPropertyQueryKind::OBJC_PR_query_class : - ObjCPropertyQueryKind::OBJC_PR_query_unknown); + getCurScope(), atLoc, propertyLoc, false, propertyId, nullptr, + SourceLocation(), + isClassProperty ? ObjCPropertyQueryKind::OBJC_PR_query_class + : ObjCPropertyQueryKind::OBJC_PR_query_unknown); if (Tok.isNot(tok::comma)) break; @@ -2540,7 +2521,8 @@ Parser::ParseObjCSynchronizedStmt(SourceLocation atLoc) { // Check the @synchronized operand now. if (!operand.isInvalid()) - operand = Actions.ObjC().ActOnObjCAtSynchronizedOperand(atLoc, operand.get()); + operand = + Actions.ObjC().ActOnObjCAtSynchronizedOperand(atLoc, operand.get()); // Parse the compound statement within a new scope. ParseScope bodyScope(this, Scope::DeclScope | Scope::CompoundStmtScope); @@ -2555,7 +2537,8 @@ Parser::ParseObjCSynchronizedStmt(SourceLocation atLoc) { if (body.isInvalid()) body = Actions.ActOnNullStmt(Tok.getLocation()); - return Actions.ObjC().ActOnObjCAtSynchronizedStmt(atLoc, operand.get(), body.get()); + return Actions.ObjC().ActOnObjCAtSynchronizedStmt(atLoc, operand.get(), + body.get()); } /// objc-try-catch-statement: @@ -2612,7 +2595,8 @@ StmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) { // Inform the actions module about the declarator, so it // gets added to the current scope. - FirstPart = Actions.ObjC().ActOnObjCExceptionDecl(getCurScope(), ParmDecl); + FirstPart = + Actions.ObjC().ActOnObjCExceptionDecl(getCurScope(), ParmDecl); } else ConsumeToken(); // consume '...' @@ -2631,10 +2615,8 @@ StmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) { if (CatchBody.isInvalid()) CatchBody = Actions.ActOnNullStmt(Tok.getLocation()); - StmtResult Catch = Actions.ObjC().ActOnObjCAtCatchStmt(AtCatchFinallyLoc, - RParenLoc, - FirstPart, - CatchBody.get()); + StmtResult Catch = Actions.ObjC().ActOnObjCAtCatchStmt( + AtCatchFinallyLoc, RParenLoc, FirstPart, CatchBody.get()); if (!Catch.isInvalid()) CatchStmts.push_back(Catch.get()); @@ -2671,7 +2653,7 @@ StmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) { } FinallyStmt = Actions.ObjC().ActOnObjCAtFinallyStmt(AtCatchFinallyLoc, - FinallyBody.get()); + FinallyBody.get()); catch_or_finally_seen = true; break; } @@ -2681,9 +2663,8 @@ StmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) { return StmtError(); } - return Actions.ObjC().ActOnObjCAtTryStmt(atLoc, TryBody.get(), - CatchStmts, - FinallyStmt.get()); + return Actions.ObjC().ActOnObjCAtTryStmt(atLoc, TryBody.get(), CatchStmts, + FinallyStmt.get()); } /// objc-autoreleasepool-statement: @@ -2706,7 +2687,7 @@ Parser::ParseObjCAutoreleasePoolStmt(SourceLocation atLoc) { if (AutoreleasePoolBody.isInvalid()) AutoreleasePoolBody = Actions.ActOnNullStmt(Tok.getLocation()); return Actions.ObjC().ActOnObjCAutoreleasePoolStmt(atLoc, - AutoreleasePoolBody.get()); + AutoreleasePoolBody.get()); } /// StashAwayMethodOrFunctionBodyTokens - Consume the tokens and store them @@ -2873,7 +2854,7 @@ ExprResult Parser::ParseObjCAtExpression(SourceLocation AtLoc) { return Lit; return ParsePostfixExpressionSuffix( - Actions.ObjC().BuildObjCNumericLiteral(AtLoc, Lit.get())); + Actions.ObjC().BuildObjCNumericLiteral(AtLoc, Lit.get())); } case tok::string_literal: // primary-expression: string-literal @@ -3129,10 +3110,9 @@ ExprResult Parser::ParseObjCMessageExpression() { IdentifierInfo *Name = Tok.getIdentifierInfo(); SourceLocation NameLoc = Tok.getLocation(); ParsedType ReceiverType; - switch (Actions.ObjC().getObjCMessageKind(getCurScope(), Name, NameLoc, - Name == Ident_super, - NextToken().is(tok::period), - ReceiverType)) { + switch (Actions.ObjC().getObjCMessageKind( + getCurScope(), Name, NameLoc, Name == Ident_super, + NextToken().is(tok::period), ReceiverType)) { case SemaObjC::ObjCSuperMessage: return ParseObjCMessageExpressionBody(LBracLoc, ConsumeToken(), nullptr, nullptr); @@ -3376,13 +3356,14 @@ Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc, Selector Sel = PP.getSelectorTable().getSelector(nKeys, &KeyIdents[0]); if (SuperLoc.isValid()) - return Actions.ObjC().ActOnSuperMessage(getCurScope(), SuperLoc, Sel, - LBracLoc, KeyLocs, RBracLoc, KeyExprs); + return Actions.ObjC().ActOnSuperMessage( + getCurScope(), SuperLoc, Sel, LBracLoc, KeyLocs, RBracLoc, KeyExprs); else if (ReceiverType) return Actions.ObjC().ActOnClassMessage(getCurScope(), ReceiverType, Sel, - LBracLoc, KeyLocs, RBracLoc, KeyExprs); - return Actions.ObjC().ActOnInstanceMessage(getCurScope(), ReceiverExpr, Sel, - LBracLoc, KeyLocs, RBracLoc, KeyExprs); + LBracLoc, KeyLocs, RBracLoc, + KeyExprs); + return Actions.ObjC().ActOnInstanceMessage( + getCurScope(), ReceiverExpr, Sel, LBracLoc, KeyLocs, RBracLoc, KeyExprs); } ExprResult Parser::ParseObjCStringLiteral(SourceLocation AtLoc) { @@ -3473,7 +3454,7 @@ Parser::ParseObjCBoxedExpr(SourceLocation AtLoc) { SourceLocation LPLoc = T.getOpenLocation(), RPLoc = T.getCloseLocation(); ValueExpr = Actions.ActOnParenExpr(LPLoc, RPLoc, ValueExpr.get()); return Actions.ObjC().BuildObjCBoxedExpr(SourceRange(AtLoc, RPLoc), - ValueExpr.get()); + ValueExpr.get()); } ExprResult Parser::ParseObjCArrayLiteral(SourceLocation AtLoc) { @@ -3582,7 +3563,7 @@ ExprResult Parser::ParseObjCDictionaryLiteral(SourceLocation AtLoc) { // Create the ObjCDictionaryLiteral. return Actions.ObjC().BuildObjCDictionaryLiteral(SourceRange(AtLoc, EndLoc), - Elements); + Elements); } /// objc-encode-expression: @@ -3606,8 +3587,8 @@ Parser::ParseObjCEncodeExpression(SourceLocation AtLoc) { if (Ty.isInvalid()) return ExprError(); - return Actions.ObjC().ParseObjCEncodeExpression(AtLoc, EncLoc, T.getOpenLocation(), - Ty.get(), T.getCloseLocation()); + return Actions.ObjC().ParseObjCEncodeExpression( + AtLoc, EncLoc, T.getOpenLocation(), Ty.get(), T.getCloseLocation()); } /// objc-protocol-expression @@ -3630,9 +3611,9 @@ Parser::ParseObjCProtocolExpression(SourceLocation AtLoc) { T.consumeClose(); - return Actions.ObjC().ParseObjCProtocolExpression(protocolId, AtLoc, ProtoLoc, - T.getOpenLocation(), ProtoIdLoc, - T.getCloseLocation()); + return Actions.ObjC().ParseObjCProtocolExpression( + protocolId, AtLoc, ProtoLoc, T.getOpenLocation(), ProtoIdLoc, + T.getCloseLocation()); } /// objc-selector-expression @@ -3696,18 +3677,17 @@ ExprResult Parser::ParseObjCSelectorExpression(SourceLocation AtLoc) { ConsumeParen(); // ')' T.consumeClose(); Selector Sel = PP.getSelectorTable().getSelector(nColons, &KeyIdents[0]); - return Actions.ObjC().ParseObjCSelectorExpression(Sel, AtLoc, SelectorLoc, - T.getOpenLocation(), - T.getCloseLocation(), - !HasOptionalParen); + return Actions.ObjC().ParseObjCSelectorExpression( + Sel, AtLoc, SelectorLoc, T.getOpenLocation(), T.getCloseLocation(), + !HasOptionalParen); } void Parser::ParseLexedObjCMethodDefs(LexedMethod &LM, bool parseMethod) { // MCDecl might be null due to error in method or c-function prototype, etc. Decl *MCDecl = LM.D; - bool skip = MCDecl && - ((parseMethod && !Actions.ObjC().isObjCMethodDecl(MCDecl)) || - (!parseMethod && Actions.ObjC().isObjCMethodDecl(MCDecl))); + bool skip = + MCDecl && ((parseMethod && !Actions.ObjC().isObjCMethodDecl(MCDecl)) || + (!parseMethod && Actions.ObjC().isObjCMethodDecl(MCDecl))); if (skip) return; diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp index 478ae59fdd5f0..e0116d3003100 100644 --- a/clang/lib/Parse/ParseStmt.cpp +++ b/clang/lib/Parse/ParseStmt.cpp @@ -2295,10 +2295,8 @@ StmtResult Parser::ParseForStatement(SourceLocation *TrailingElseLoc) { } else if (ForEach) { // Similarly, we need to do the semantic analysis for a for-range // statement immediately in order to close over temporaries correctly. - ForEachStmt = Actions.ObjC().ActOnObjCForCollectionStmt(ForLoc, - FirstPart.get(), - Collection.get(), - T.getCloseLocation()); + ForEachStmt = Actions.ObjC().ActOnObjCForCollectionStmt( + ForLoc, FirstPart.get(), Collection.get(), T.getCloseLocation()); } else { // In OpenMP loop region loop control variable must be captured and be // private. Perform analysis of first part (if any). @@ -2346,8 +2344,8 @@ StmtResult Parser::ParseForStatement(SourceLocation *TrailingElseLoc) { return StmtError(); if (ForEach) - return Actions.ObjC().FinishObjCForCollectionStmt(ForEachStmt.get(), - Body.get()); + return Actions.ObjC().FinishObjCForCollectionStmt(ForEachStmt.get(), + Body.get()); if (ForRangeInfo.ParsedForRangeDecl()) return Actions.FinishCXXForRangeStmt(ForRangeStmt.get(), Body.get()); diff --git a/clang/lib/Sema/SemaCast.cpp b/clang/lib/Sema/SemaCast.cpp index 4bd5f56a36706..483ec7e36eaed 100644 --- a/clang/lib/Sema/SemaCast.cpp +++ b/clang/lib/Sema/SemaCast.cpp @@ -3218,8 +3218,8 @@ void CastOperation::CheckCStyleCast() { return; } } - } - else if (!Self.ObjC().CheckObjCARCUnavailableWeakConversion(DestType, SrcType)) { + } else if (!Self.ObjC().CheckObjCARCUnavailableWeakConversion(DestType, + SrcType)) { Self.Diag(SrcExpr.get()->getBeginLoc(), diag::err_arc_convesion_of_weak_unavailable) << 1 << SrcType << DestType << SrcExpr.get()->getSourceRange(); diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index e4eddd20c2ab7..6bbe8b3b75558 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -15621,7 +15621,7 @@ static void DiagnoseImpCast(Sema &S, Expr *E, QualType T, static bool isObjCSignedCharBool(Sema &S, QualType Ty) { return Ty->isSpecificBuiltinType(BuiltinType::SChar) && - S.getLangOpts().ObjC && S.ObjC().NSAPIObj->isObjCBOOLType(Ty); + S.getLangOpts().ObjC && S.ObjC().NSAPIObj->isObjCBOOLType(Ty); } static void adornObjCBoolConversionDiagWithTernaryFixit( @@ -15941,8 +15941,8 @@ static void checkObjCArrayLiteral(Sema &S, QualType TargetType, return; if (TargetObjCPtr->isUnspecialized() || - TargetObjCPtr->getInterfaceDecl()->getCanonicalDecl() - != S.ObjC().NSArrayDecl->getCanonicalDecl()) + TargetObjCPtr->getInterfaceDecl()->getCanonicalDecl() != + S.ObjC().NSArrayDecl->getCanonicalDecl()) return; auto TypeArgs = TargetObjCPtr->getTypeArgs(); @@ -15970,8 +15970,8 @@ checkObjCDictionaryLiteral(Sema &S, QualType TargetType, return; if (TargetObjCPtr->isUnspecialized() || - TargetObjCPtr->getInterfaceDecl()->getCanonicalDecl() - != S.ObjC().NSDictionaryDecl->getCanonicalDecl()) + TargetObjCPtr->getInterfaceDecl()->getCanonicalDecl() != + S.ObjC().NSDictionaryDecl->getCanonicalDecl()) return; auto TypeArgs = TargetObjCPtr->getTypeArgs(); diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp index 35d639314dcd5..95fca993e56eb 100644 --- a/clang/lib/Sema/SemaCodeComplete.cpp +++ b/clang/lib/Sema/SemaCodeComplete.cpp @@ -5864,7 +5864,8 @@ void Sema::CodeCompleteObjCClassPropertyRefExpr(Scope *S, SourceLocation ClassNameLoc, bool IsBaseExprStatement) { const IdentifierInfo *ClassNamePtr = &ClassName; - ObjCInterfaceDecl *IFace = ObjC().getObjCInterfaceDecl(ClassNamePtr, ClassNameLoc); + ObjCInterfaceDecl *IFace = + ObjC().getObjCInterfaceDecl(ClassNamePtr, ClassNameLoc); if (!IFace) return; CodeCompletionContext CCContext( @@ -8183,8 +8184,9 @@ AddClassMessageCompletions(Sema &SemaRef, Scope *S, ParsedType Receiver, } } - for (SemaObjC::GlobalMethodPool::iterator M = SemaRef.ObjC().MethodPool.begin(), - MEnd = SemaRef.ObjC().MethodPool.end(); + for (SemaObjC::GlobalMethodPool::iterator + M = SemaRef.ObjC().MethodPool.begin(), + MEnd = SemaRef.ObjC().MethodPool.end(); M != MEnd; ++M) { for (ObjCMethodList *MethList = &M->second.second; MethList && MethList->getMethod(); MethList = MethList->getNext()) { @@ -8354,7 +8356,7 @@ void Sema::CodeCompleteObjCInstanceMessage( } for (SemaObjC::GlobalMethodPool::iterator M = ObjC().MethodPool.begin(), - MEnd = ObjC().MethodPool.end(); + MEnd = ObjC().MethodPool.end(); M != MEnd; ++M) { for (ObjCMethodList *MethList = &M->second.first; MethList && MethList->getMethod(); MethList = MethList->getNext()) { @@ -8429,7 +8431,7 @@ void Sema::CodeCompleteObjCSelector( CodeCompletionContext::CCC_SelectorName); Results.EnterNewScope(); for (SemaObjC::GlobalMethodPool::iterator M = ObjC().MethodPool.begin(), - MEnd = ObjC().MethodPool.end(); + MEnd = ObjC().MethodPool.end(); M != MEnd; ++M) { Selector Sel = M->first; @@ -8497,7 +8499,8 @@ void Sema::CodeCompleteObjCProtocolReferences( // already seen. // FIXME: This doesn't work when caching code-completion results. for (const IdentifierLocPair &Pair : Protocols) - if (ObjCProtocolDecl *Protocol = ObjC().LookupProtocol(Pair.first, Pair.second)) + if (ObjCProtocolDecl *Protocol = + ObjC().LookupProtocol(Pair.first, Pair.second)) Results.Ignore(Protocol); // Add all protocols. @@ -9773,7 +9776,7 @@ void Sema::CodeCompleteObjCMethodDeclSelector( Results.EnterNewScope(); for (SemaObjC::GlobalMethodPool::iterator M = ObjC().MethodPool.begin(), - MEnd = ObjC().MethodPool.end(); + MEnd = ObjC().MethodPool.end(); M != MEnd; ++M) { for (ObjCMethodList *MethList = IsInstanceMethod ? &M->second.first : &M->second.second; diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index b32a3819ee8b1..436c1ce892d23 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -19476,7 +19476,8 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl, // Ivar declared in @implementation never belongs to the implementation. // Only it is in implementation's lexical context. ClsFields[I]->setLexicalDeclContext(IMPDecl); - ObjC().CheckImplementationIvars(IMPDecl, ClsFields, RecFields.size(), RBrac); + ObjC().CheckImplementationIvars(IMPDecl, ClsFields, RecFields.size(), + RBrac); IMPDecl->setIvarLBraceLoc(LBrac); IMPDecl->setIvarRBraceLoc(RBrac); } else if (ObjCCategoryDecl *CDecl = diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp index 893cc1a731210..885eeb126d486 100644 --- a/clang/lib/Sema/SemaDeclObjC.cpp +++ b/clang/lib/Sema/SemaDeclObjC.cpp @@ -10,7 +10,6 @@ // //===----------------------------------------------------------------------===// -#include "clang/Sema/SemaObjC.h" #include "TypeLocBuilder.h" #include "clang/AST/ASTConsumer.h" #include "clang/AST/ASTContext.h" @@ -28,6 +27,7 @@ #include "clang/Sema/Scope.h" #include "clang/Sema/ScopeInfo.h" #include "clang/Sema/SemaInternal.h" +#include "clang/Sema/SemaObjC.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseSet.h" @@ -43,7 +43,7 @@ using namespace clang; /// \return true to indicate that there was an error and appropriate /// actions were taken bool SemaObjC::checkInitMethod(ObjCMethodDecl *method, - QualType receiverTypeIfCall) { + QualType receiverTypeIfCall) { ASTContext &Context = getASTContext(); if (method->isInvalidDecl()) return true; @@ -101,7 +101,8 @@ bool SemaObjC::checkInitMethod(ObjCMethodDecl *method, // If we're in a system header, and this is not a call, just make // the method unusable. - if (receiverTypeIfCall.isNull() && SemaRef.getSourceManager().isInSystemHeader(loc)) { + if (receiverTypeIfCall.isNull() && + SemaRef.getSourceManager().isInSystemHeader(loc)) { method->addAttr(UnavailableAttr::CreateImplicit(Context, "", UnavailableAttr::IR_ARCInitReturnsUnrelated, loc)); return true; @@ -138,7 +139,7 @@ static void diagnoseNoescape(const ParmVarDecl *NewD, const ParmVarDecl *OldD, } void SemaObjC::CheckObjCMethodOverride(ObjCMethodDecl *NewMethod, - const ObjCMethodDecl *Overridden) { + const ObjCMethodDecl *Overridden) { ASTContext &Context = getASTContext(); if (Overridden->hasRelatedResultType() && !NewMethod->hasRelatedResultType()) { @@ -371,7 +372,8 @@ void SemaObjC::ActOnStartOfObjCMethodDef(Scope *FnBodyScope, Decl *D) { assert((SemaRef.getCurMethodDecl() == nullptr) && "Methodparsing confused"); ObjCMethodDecl *MDecl = dyn_cast_or_null(D); - SemaRef.PushExpressionEvaluationContext(SemaRef.ExprEvalContexts.back().Context); + SemaRef.PushExpressionEvaluationContext( + SemaRef.ExprEvalContexts.back().Context); // If we don't have a valid method decl, simply return. if (!MDecl) @@ -381,7 +383,7 @@ void SemaObjC::ActOnStartOfObjCMethodDef(Scope *FnBodyScope, Decl *D) { if (!ResultType->isDependentType() && !ResultType->isVoidType() && !MDecl->isInvalidDecl() && SemaRef.RequireCompleteType(MDecl->getLocation(), ResultType, - diag::err_func_def_incomplete_result)) + diag::err_func_def_incomplete_result)) MDecl->setInvalidDecl(); // Allow all of Sema to see that we are entering a method definition. @@ -399,12 +401,11 @@ void SemaObjC::ActOnStartOfObjCMethodDef(Scope *FnBodyScope, Decl *D) { // The ObjC parser requires parameter names so there's no need to check. SemaRef.CheckParmsForFunctionDef(MDecl->parameters(), - /*CheckParameterNames=*/false); + /*CheckParameterNames=*/false); // Introduce all of the other parameters into this scope. for (auto *Param : MDecl->parameters()) { - if (!Param->isInvalidDecl() && - getLangOpts().ObjCAutoRefCount && + if (!Param->isInvalidDecl() && getLangOpts().ObjCAutoRefCount && !HasExplicitOwnershipAttr(SemaRef, Param)) Diag(Param->getLocation(), diag::warn_arc_strong_pointer_objc_pointer) << Param->getType(); @@ -497,7 +498,7 @@ void SemaObjC::ActOnStartOfObjCMethodDef(Scope *FnBodyScope, Decl *D) { SuperClass->lookupMethod(MDecl->getSelector(), MDecl->isInstanceMethod()); SemaRef.getCurFunction()->ObjCShouldCallSuper = - (SuperMethod && SuperMethod->hasAttr()); + (SuperMethod && SuperMethod->hasAttr()); } } } @@ -545,20 +546,15 @@ static void diagnoseUseOfProtocols(Sema &TheSema, } } -void SemaObjC:: -ActOnSuperClassOfClassInterface(Scope *S, - SourceLocation AtInterfaceLoc, - ObjCInterfaceDecl *IDecl, - IdentifierInfo *ClassName, - SourceLocation ClassLoc, - IdentifierInfo *SuperName, - SourceLocation SuperLoc, - ArrayRef SuperTypeArgs, - SourceRange SuperTypeArgsRange) { +void SemaObjC::ActOnSuperClassOfClassInterface( + Scope *S, SourceLocation AtInterfaceLoc, ObjCInterfaceDecl *IDecl, + IdentifierInfo *ClassName, SourceLocation ClassLoc, + IdentifierInfo *SuperName, SourceLocation SuperLoc, + ArrayRef SuperTypeArgs, SourceRange SuperTypeArgsRange) { ASTContext &Context = getASTContext(); // Check if a different kind of symbol declared in this scope. - NamedDecl *PrevDecl = SemaRef.LookupSingleName(SemaRef.TUScope, SuperName, SuperLoc, - Sema::LookupOrdinaryName); + NamedDecl *PrevDecl = SemaRef.LookupSingleName( + SemaRef.TUScope, SuperName, SuperLoc, Sema::LookupOrdinaryName); if (!PrevDecl) { // Try to correct for a typo in the superclass name without correcting @@ -567,8 +563,9 @@ ActOnSuperClassOfClassInterface(Scope *S, if (TypoCorrection Corrected = SemaRef.CorrectTypo( DeclarationNameInfo(SuperName, SuperLoc), Sema::LookupOrdinaryName, SemaRef.TUScope, nullptr, CCC, Sema::CTK_ErrorRecovery)) { - SemaRef.diagnoseTypo(Corrected, SemaRef.PDiag(diag::err_undef_superclass_suggest) - << SuperName << ClassName); + SemaRef.diagnoseTypo(Corrected, + SemaRef.PDiag(diag::err_undef_superclass_suggest) + << SuperName << ClassName); PrevDecl = Corrected.getCorrectionDeclAs(); } } @@ -603,7 +600,8 @@ ActOnSuperClassOfClassInterface(Scope *S, // @interface NewI @end // typedef NewI DeprI __attribute__((deprecated("blah"))) // @interface SI : DeprI /* warn here */ @end - (void)SemaRef.DiagnoseUseOfDecl(const_cast(TDecl), SuperLoc); + (void)SemaRef.DiagnoseUseOfDecl( + const_cast(TDecl), SuperLoc); } } } @@ -623,12 +621,10 @@ ActOnSuperClassOfClassInterface(Scope *S, if (!SuperClassDecl) Diag(SuperLoc, diag::err_undef_superclass) << SuperName << ClassName << SourceRange(AtInterfaceLoc, ClassLoc); - else if (SemaRef.RequireCompleteType(SuperLoc, - SuperClassType, - diag::err_forward_superclass, - SuperClassDecl->getDeclName(), - ClassName, - SourceRange(AtInterfaceLoc, ClassLoc))) { + else if (SemaRef.RequireCompleteType( + SuperLoc, SuperClassType, diag::err_forward_superclass, + SuperClassDecl->getDeclName(), ClassName, + SourceRange(AtInterfaceLoc, ClassLoc))) { SuperClassDecl = nullptr; SuperClassType = QualType(); } @@ -643,22 +639,15 @@ ActOnSuperClassOfClassInterface(Scope *S, TypeSourceInfo *SuperClassTInfo = nullptr; if (!SuperTypeArgs.empty()) { TypeResult fullSuperClassType = actOnObjCTypeArgsAndProtocolQualifiers( - S, - SuperLoc, - SemaRef.CreateParsedType(SuperClassType, - nullptr), - SuperTypeArgsRange.getBegin(), - SuperTypeArgs, - SuperTypeArgsRange.getEnd(), - SourceLocation(), - { }, - { }, - SourceLocation()); + S, SuperLoc, SemaRef.CreateParsedType(SuperClassType, nullptr), + SuperTypeArgsRange.getBegin(), SuperTypeArgs, + SuperTypeArgsRange.getEnd(), SourceLocation(), {}, {}, + SourceLocation()); if (!fullSuperClassType.isUsable()) return; - SuperClassType = SemaRef.GetTypeFromParser(fullSuperClassType.get(), - &SuperClassTInfo); + SuperClassType = + SemaRef.GetTypeFromParser(fullSuperClassType.get(), &SuperClassTInfo); } if (!SuperClassTInfo) { @@ -671,27 +660,24 @@ ActOnSuperClassOfClassInterface(Scope *S, } } -DeclResult SemaObjC::actOnObjCTypeParam(Scope *S, - ObjCTypeParamVariance variance, - SourceLocation varianceLoc, - unsigned index, - IdentifierInfo *paramName, - SourceLocation paramLoc, - SourceLocation colonLoc, - ParsedType parsedTypeBound) { +DeclResult SemaObjC::actOnObjCTypeParam( + Scope *S, ObjCTypeParamVariance variance, SourceLocation varianceLoc, + unsigned index, IdentifierInfo *paramName, SourceLocation paramLoc, + SourceLocation colonLoc, ParsedType parsedTypeBound) { ASTContext &Context = getASTContext(); // If there was an explicitly-provided type bound, check it. TypeSourceInfo *typeBoundInfo = nullptr; if (parsedTypeBound) { // The type bound can be any Objective-C pointer type. - QualType typeBound = SemaRef.GetTypeFromParser(parsedTypeBound, &typeBoundInfo); + QualType typeBound = + SemaRef.GetTypeFromParser(parsedTypeBound, &typeBoundInfo); if (typeBound->isObjCObjectPointerType()) { // okay } else if (typeBound->isObjCObjectType()) { // The user forgot the * on an Objective-C pointer type, e.g., // "T : NSView". - SourceLocation starLoc = SemaRef.getLocForEndOfToken( - typeBoundInfo->getTypeLoc().getEndLoc()); + SourceLocation starLoc = + SemaRef.getLocForEndOfToken(typeBoundInfo->getTypeLoc().getEndLoc()); Diag(typeBoundInfo->getTypeLoc().getBeginLoc(), diag::err_objc_type_param_bound_missing_pointer) << typeBound << paramName @@ -771,15 +757,15 @@ DeclResult SemaObjC::actOnObjCTypeParam(Scope *S, } // Create the type parameter. - return ObjCTypeParamDecl::Create(Context, SemaRef.CurContext, variance, varianceLoc, - index, paramLoc, paramName, colonLoc, - typeBoundInfo); + return ObjCTypeParamDecl::Create(Context, SemaRef.CurContext, variance, + varianceLoc, index, paramLoc, paramName, + colonLoc, typeBoundInfo); } -ObjCTypeParamList *SemaObjC::actOnObjCTypeParamList(Scope *S, - SourceLocation lAngleLoc, - ArrayRef typeParamsIn, - SourceLocation rAngleLoc) { +ObjCTypeParamList * +SemaObjC::actOnObjCTypeParamList(Scope *S, SourceLocation lAngleLoc, + ArrayRef typeParamsIn, + SourceLocation rAngleLoc) { ASTContext &Context = getASTContext(); // We know that the array only contains Objective-C type parameters. ArrayRef @@ -812,7 +798,8 @@ ObjCTypeParamList *SemaObjC::actOnObjCTypeParamList(Scope *S, return ObjCTypeParamList::create(Context, lAngleLoc, typeParams, rAngleLoc); } -void SemaObjC::popObjCTypeParamList(Scope *S, ObjCTypeParamList *typeParamList) { +void SemaObjC::popObjCTypeParamList(Scope *S, + ObjCTypeParamList *typeParamList) { for (auto *typeParam : *typeParamList) { if (!typeParam->isInvalidDecl()) { S->RemoveDecl(typeParam); @@ -990,12 +977,12 @@ ObjCInterfaceDecl *SemaObjC::ActOnStartClassInterface( const SourceLocation *ProtoLocs, SourceLocation EndProtoLoc, const ParsedAttributesView &AttrList, SkipBodyInfo *SkipBody) { assert(ClassName && "Missing class identifier"); - + ASTContext &Context = getASTContext(); // Check for another declaration kind with the same name. - NamedDecl *PrevDecl = - SemaRef.LookupSingleName(SemaRef.TUScope, ClassName, ClassLoc, Sema::LookupOrdinaryName, - SemaRef.forRedeclarationInCurContext()); + NamedDecl *PrevDecl = SemaRef.LookupSingleName( + SemaRef.TUScope, ClassName, ClassLoc, Sema::LookupOrdinaryName, + SemaRef.forRedeclarationInCurContext()); if (PrevDecl && !isa(PrevDecl)) { Diag(ClassLoc, diag::err_redefinition_different_kind) << ClassName; @@ -1041,17 +1028,12 @@ ObjCInterfaceDecl *SemaObjC::ActOnStartClassInterface( // Clone the type parameter list. SmallVector clonedTypeParams; for (auto *typeParam : *prevTypeParamList) { - clonedTypeParams.push_back( - ObjCTypeParamDecl::Create( - Context, - SemaRef.CurContext, - typeParam->getVariance(), - SourceLocation(), - typeParam->getIndex(), - SourceLocation(), - typeParam->getIdentifier(), - SourceLocation(), - Context.getTrivialTypeSourceInfo(typeParam->getUnderlyingType()))); + clonedTypeParams.push_back(ObjCTypeParamDecl::Create( + Context, SemaRef.CurContext, typeParam->getVariance(), + SourceLocation(), typeParam->getIndex(), SourceLocation(), + typeParam->getIdentifier(), SourceLocation(), + Context.getTrivialTypeSourceInfo( + typeParam->getUnderlyingType()))); } typeParamList = ObjCTypeParamList::create(Context, @@ -1062,9 +1044,9 @@ ObjCInterfaceDecl *SemaObjC::ActOnStartClassInterface( } } - ObjCInterfaceDecl *IDecl - = ObjCInterfaceDecl::Create(Context, SemaRef.CurContext, AtInterfaceLoc, ClassName, - typeParamList, PrevIDecl, ClassLoc); + ObjCInterfaceDecl *IDecl = + ObjCInterfaceDecl::Create(Context, SemaRef.CurContext, AtInterfaceLoc, + ClassName, typeParamList, PrevIDecl, ClassLoc); if (PrevIDecl) { // Class already seen. Was it a definition? if (ObjCInterfaceDecl *Def = PrevIDecl->getDefinition()) { @@ -1112,7 +1094,7 @@ ObjCInterfaceDecl *SemaObjC::ActOnStartClassInterface( // Check then save referenced protocols. if (NumProtoRefs) { - diagnoseUseOfProtocols(SemaRef, IDecl, (ObjCProtocolDecl*const*)ProtoRefs, + diagnoseUseOfProtocols(SemaRef, IDecl, (ObjCProtocolDecl *const *)ProtoRefs, NumProtoRefs, ProtoLocs); IDecl->setProtocolList((ObjCProtocolDecl*const*)ProtoRefs, NumProtoRefs, ProtoLocs, Context); @@ -1127,14 +1109,14 @@ ObjCInterfaceDecl *SemaObjC::ActOnStartClassInterface( /// ActOnTypedefedProtocols - this action finds protocol list as part of the /// typedef'ed use for a qualified super class and adds them to the list /// of the protocols. -void SemaObjC::ActOnTypedefedProtocols(SmallVectorImpl &ProtocolRefs, - SmallVectorImpl &ProtocolLocs, - IdentifierInfo *SuperName, - SourceLocation SuperLoc) { +void SemaObjC::ActOnTypedefedProtocols( + SmallVectorImpl &ProtocolRefs, + SmallVectorImpl &ProtocolLocs, IdentifierInfo *SuperName, + SourceLocation SuperLoc) { if (!SuperName) return; - NamedDecl* IDecl = SemaRef.LookupSingleName(SemaRef.TUScope, SuperName, SuperLoc, - Sema::LookupOrdinaryName); + NamedDecl *IDecl = SemaRef.LookupSingleName( + SemaRef.TUScope, SuperName, SuperLoc, Sema::LookupOrdinaryName); if (!IDecl) return; @@ -1155,33 +1137,33 @@ void SemaObjC::ActOnTypedefedProtocols(SmallVectorImpl &ProtocolRefs, /// ActOnCompatibilityAlias - this action is called after complete parsing of /// a \@compatibility_alias declaration. It sets up the alias relationships. Decl *SemaObjC::ActOnCompatibilityAlias(SourceLocation AtLoc, - IdentifierInfo *AliasName, - SourceLocation AliasLocation, - IdentifierInfo *ClassName, - SourceLocation ClassLocation) { + IdentifierInfo *AliasName, + SourceLocation AliasLocation, + IdentifierInfo *ClassName, + SourceLocation ClassLocation) { ASTContext &Context = getASTContext(); // Look for previous declaration of alias name - NamedDecl *ADecl = - SemaRef.LookupSingleName(SemaRef.TUScope, AliasName, AliasLocation, Sema::LookupOrdinaryName, - SemaRef.forRedeclarationInCurContext()); + NamedDecl *ADecl = SemaRef.LookupSingleName( + SemaRef.TUScope, AliasName, AliasLocation, Sema::LookupOrdinaryName, + SemaRef.forRedeclarationInCurContext()); if (ADecl) { Diag(AliasLocation, diag::err_conflicting_aliasing_type) << AliasName; Diag(ADecl->getLocation(), diag::note_previous_declaration); return nullptr; } // Check for class declaration - NamedDecl *CDeclU = - SemaRef.LookupSingleName(SemaRef.TUScope, ClassName, ClassLocation, Sema::LookupOrdinaryName, - SemaRef.forRedeclarationInCurContext()); + NamedDecl *CDeclU = SemaRef.LookupSingleName( + SemaRef.TUScope, ClassName, ClassLocation, Sema::LookupOrdinaryName, + SemaRef.forRedeclarationInCurContext()); if (const TypedefNameDecl *TDecl = dyn_cast_or_null(CDeclU)) { QualType T = TDecl->getUnderlyingType(); if (T->isObjCObjectType()) { if (NamedDecl *IDecl = T->castAs()->getInterface()) { ClassName = IDecl->getIdentifier(); - CDeclU = SemaRef.LookupSingleName(SemaRef.TUScope, ClassName, ClassLocation, - Sema::LookupOrdinaryName, - SemaRef.forRedeclarationInCurContext()); + CDeclU = SemaRef.LookupSingleName( + SemaRef.TUScope, ClassName, ClassLocation, Sema::LookupOrdinaryName, + SemaRef.forRedeclarationInCurContext()); } } } @@ -1194,8 +1176,8 @@ Decl *SemaObjC::ActOnCompatibilityAlias(SourceLocation AtLoc, } // Everything checked out, instantiate a new alias declaration AST. - ObjCCompatibleAliasDecl *AliasDecl = - ObjCCompatibleAliasDecl::Create(Context, SemaRef.CurContext, AtLoc, AliasName, CDecl); + ObjCCompatibleAliasDecl *AliasDecl = ObjCCompatibleAliasDecl::Create( + Context, SemaRef.CurContext, AtLoc, AliasName, CDecl); if (!CheckObjCDeclScope(AliasDecl)) SemaRef.PushOnScopeChains(AliasDecl, SemaRef.TUScope); @@ -1204,15 +1186,13 @@ Decl *SemaObjC::ActOnCompatibilityAlias(SourceLocation AtLoc, } bool SemaObjC::CheckForwardProtocolDeclarationForCircularDependency( - IdentifierInfo *PName, - SourceLocation &Ploc, SourceLocation PrevLoc, - const ObjCList &PList) { + IdentifierInfo *PName, SourceLocation &Ploc, SourceLocation PrevLoc, + const ObjCList &PList) { bool res = false; for (ObjCList::iterator I = PList.begin(), E = PList.end(); I != E; ++I) { - if (ObjCProtocolDecl *PDecl =LookupProtocol((*I)->getIdentifier(), - Ploc)) { + if (ObjCProtocolDecl *PDecl = LookupProtocol((*I)->getIdentifier(), Ploc)) { if (PDecl->getIdentifier() == PName) { Diag(Ploc, diag::err_protocol_has_circular_dependency); Diag(PrevLoc, diag::note_previous_definition); @@ -1239,8 +1219,8 @@ ObjCProtocolDecl *SemaObjC::ActOnStartProtocolInterface( bool err = false; // FIXME: Deal with AttrList. assert(ProtocolName && "Missing protocol identifier"); - ObjCProtocolDecl *PrevDecl = LookupProtocol(ProtocolName, ProtocolLoc, - SemaRef.forRedeclarationInCurContext()); + ObjCProtocolDecl *PrevDecl = LookupProtocol( + ProtocolName, ProtocolLoc, SemaRef.forRedeclarationInCurContext()); ObjCProtocolDecl *PDecl = nullptr; if (ObjCProtocolDecl *Def = PrevDecl? PrevDecl->getDefinition() : nullptr) { // Create a new protocol that is completely distinct from previous @@ -1295,7 +1275,7 @@ ObjCProtocolDecl *SemaObjC::ActOnStartProtocolInterface( if (!err && NumProtoRefs ) { /// Check then save referenced protocols. - diagnoseUseOfProtocols(SemaRef, PDecl, (ObjCProtocolDecl*const*)ProtoRefs, + diagnoseUseOfProtocols(SemaRef, PDecl, (ObjCProtocolDecl *const *)ProtoRefs, NumProtoRefs, ProtoLocs); PDecl->setProtocolList((ObjCProtocolDecl*const*)ProtoRefs, NumProtoRefs, ProtoLocs, Context); @@ -1325,20 +1305,22 @@ static bool NestedProtocolHasNoDefinition(ObjCProtocolDecl *PDecl, /// FindProtocolDeclaration - This routine looks up protocols and /// issues an error if they are not declared. It returns list of /// protocol declarations in its 'Protocols' argument. -void -SemaObjC::FindProtocolDeclaration(bool WarnOnDeclarations, bool ForObjCContainer, - ArrayRef ProtocolId, - SmallVectorImpl &Protocols) { +void SemaObjC::FindProtocolDeclaration(bool WarnOnDeclarations, + bool ForObjCContainer, + ArrayRef ProtocolId, + SmallVectorImpl &Protocols) { for (const IdentifierLocPair &Pair : ProtocolId) { ObjCProtocolDecl *PDecl = LookupProtocol(Pair.first, Pair.second); if (!PDecl) { DeclFilterCCC CCC{}; - TypoCorrection Corrected = SemaRef.CorrectTypo( - DeclarationNameInfo(Pair.first, Pair.second), Sema::LookupObjCProtocolName, - SemaRef.TUScope, nullptr, CCC, Sema::CTK_ErrorRecovery); + TypoCorrection Corrected = + SemaRef.CorrectTypo(DeclarationNameInfo(Pair.first, Pair.second), + Sema::LookupObjCProtocolName, SemaRef.TUScope, + nullptr, CCC, Sema::CTK_ErrorRecovery); if ((PDecl = Corrected.getCorrectionDeclAs())) - SemaRef.diagnoseTypo(Corrected, SemaRef.PDiag(diag::err_undeclared_protocol_suggest) - << Pair.first); + SemaRef.diagnoseTypo( + Corrected, SemaRef.PDiag(diag::err_undeclared_protocol_suggest) + << Pair.first); } if (!PDecl) { @@ -1429,29 +1411,23 @@ class ObjCTypeArgOrProtocolValidatorCCC final } // end anonymous namespace void SemaObjC::DiagnoseTypeArgsAndProtocols(IdentifierInfo *ProtocolId, - SourceLocation ProtocolLoc, - IdentifierInfo *TypeArgId, - SourceLocation TypeArgLoc, - bool SelectProtocolFirst) { + SourceLocation ProtocolLoc, + IdentifierInfo *TypeArgId, + SourceLocation TypeArgLoc, + bool SelectProtocolFirst) { Diag(TypeArgLoc, diag::err_objc_type_args_and_protocols) << SelectProtocolFirst << TypeArgId << ProtocolId << SourceRange(ProtocolLoc); } void SemaObjC::actOnObjCTypeArgsOrProtocolQualifiers( - Scope *S, - ParsedType baseType, - SourceLocation lAngleLoc, - ArrayRef identifiers, - ArrayRef identifierLocs, - SourceLocation rAngleLoc, - SourceLocation &typeArgsLAngleLoc, - SmallVectorImpl &typeArgs, - SourceLocation &typeArgsRAngleLoc, - SourceLocation &protocolLAngleLoc, - SmallVectorImpl &protocols, - SourceLocation &protocolRAngleLoc, - bool warnOnIncompleteProtocols) { + Scope *S, ParsedType baseType, SourceLocation lAngleLoc, + ArrayRef identifiers, + ArrayRef identifierLocs, SourceLocation rAngleLoc, + SourceLocation &typeArgsLAngleLoc, SmallVectorImpl &typeArgs, + SourceLocation &typeArgsRAngleLoc, SourceLocation &protocolLAngleLoc, + SmallVectorImpl &protocols, SourceLocation &protocolRAngleLoc, + bool warnOnIncompleteProtocols) { ASTContext &Context = getASTContext(); // Local function that updates the declaration specifiers with // protocol information. @@ -1509,8 +1485,9 @@ void SemaObjC::actOnObjCTypeArgsOrProtocolQualifiers( // about such things), check whether this name refers to a type // as well. if (allAreTypeNames) { - if (auto *decl = SemaRef.LookupSingleName(S, identifiers[i], identifierLocs[i], - Sema::LookupOrdinaryName)) { + if (auto *decl = + SemaRef.LookupSingleName(S, identifiers[i], identifierLocs[i], + Sema::LookupOrdinaryName)) { if (isa(decl)) { if (firstClassNameLoc.isInvalid()) firstClassNameLoc = identifierLocs[i]; @@ -1541,9 +1518,9 @@ void SemaObjC::actOnObjCTypeArgsOrProtocolQualifiers( if (allProtocolsDeclared) { Diag(firstClassNameLoc, diag::warn_objc_redundant_qualified_class_type) - << baseClass->getDeclName() << SourceRange(lAngleLoc, rAngleLoc) - << FixItHint::CreateInsertion(SemaRef.getLocForEndOfToken(firstClassNameLoc), - " *"); + << baseClass->getDeclName() << SourceRange(lAngleLoc, rAngleLoc) + << FixItHint::CreateInsertion( + SemaRef.getLocForEndOfToken(firstClassNameLoc), " *"); } } @@ -1572,8 +1549,8 @@ void SemaObjC::actOnObjCTypeArgsOrProtocolQualifiers( SmallVector typeDecls; unsigned numTypeDeclsResolved = 0; for (unsigned i = 0, n = identifiers.size(); i != n; ++i) { - NamedDecl *decl = SemaRef.LookupSingleName(S, identifiers[i], identifierLocs[i], - Sema::LookupOrdinaryName); + NamedDecl *decl = SemaRef.LookupSingleName( + S, identifiers[i], identifierLocs[i], Sema::LookupOrdinaryName); if (!decl) { typeDecls.push_back(TypeOrClassDecl()); continue; @@ -1716,15 +1693,15 @@ void SemaObjC::actOnObjCTypeArgsOrProtocolQualifiers( // Perform typo correction on the name. ObjCTypeArgOrProtocolValidatorCCC CCC(Context, lookupKind); - TypoCorrection corrected = - SemaRef.CorrectTypo(DeclarationNameInfo(identifiers[i], identifierLocs[i]), - lookupKind, S, nullptr, CCC, Sema::CTK_ErrorRecovery); + TypoCorrection corrected = SemaRef.CorrectTypo( + DeclarationNameInfo(identifiers[i], identifierLocs[i]), lookupKind, S, + nullptr, CCC, Sema::CTK_ErrorRecovery); if (corrected) { // Did we find a protocol? if (auto proto = corrected.getCorrectionDeclAs()) { - SemaRef.diagnoseTypo(corrected, - SemaRef.PDiag(diag::err_undeclared_protocol_suggest) - << identifiers[i]); + SemaRef.diagnoseTypo( + corrected, SemaRef.PDiag(diag::err_undeclared_protocol_suggest) + << identifiers[i]); lookupKind = Sema::LookupObjCProtocolName; protocols[i] = proto; ++numProtocolsResolved; @@ -1734,8 +1711,8 @@ void SemaObjC::actOnObjCTypeArgsOrProtocolQualifiers( // Did we find a type? if (auto typeDecl = corrected.getCorrectionDeclAs()) { SemaRef.diagnoseTypo(corrected, - SemaRef.PDiag(diag::err_unknown_typename_suggest) - << identifiers[i]); + SemaRef.PDiag(diag::err_unknown_typename_suggest) + << identifiers[i]); lookupKind = Sema::LookupOrdinaryName; typeDecls[i] = typeDecl; ++numTypeDeclsResolved; @@ -1744,9 +1721,10 @@ void SemaObjC::actOnObjCTypeArgsOrProtocolQualifiers( // Did we find an Objective-C class? if (auto objcClass = corrected.getCorrectionDeclAs()) { - SemaRef.diagnoseTypo(corrected, - SemaRef.PDiag(diag::err_unknown_type_or_class_name_suggest) - << identifiers[i] << true); + SemaRef.diagnoseTypo( + corrected, + SemaRef.PDiag(diag::err_unknown_type_or_class_name_suggest) + << identifiers[i] << true); lookupKind = Sema::LookupOrdinaryName; typeDecls[i] = objcClass; ++numTypeDeclsResolved; @@ -1757,9 +1735,10 @@ void SemaObjC::actOnObjCTypeArgsOrProtocolQualifiers( // We couldn't find anything. Diag(identifierLocs[i], (lookupKind == Sema::LookupAnyName ? diag::err_objc_type_arg_missing - : lookupKind == Sema::LookupObjCProtocolName ? diag::err_undeclared_protocol - : diag::err_unknown_typename)) - << identifiers[i]; + : lookupKind == Sema::LookupObjCProtocolName + ? diag::err_undeclared_protocol + : diag::err_unknown_typename)) + << identifiers[i]; protocols.clear(); typeArgs.clear(); return; @@ -1779,7 +1758,7 @@ void SemaObjC::actOnObjCTypeArgsOrProtocolQualifiers( /// a class method in its extension. /// void SemaObjC::DiagnoseClassExtensionDupMethods(ObjCCategoryDecl *CAT, - ObjCInterfaceDecl *ID) { + ObjCInterfaceDecl *ID) { if (!ID) return; // Possibly due to previous error @@ -1802,20 +1781,18 @@ void SemaObjC::DiagnoseClassExtensionDupMethods(ObjCCategoryDecl *CAT, } /// ActOnForwardProtocolDeclaration - Handle \@protocol foo; -SemaObjC::DeclGroupPtrTy -SemaObjC::ActOnForwardProtocolDeclaration(SourceLocation AtProtocolLoc, - ArrayRef IdentList, - const ParsedAttributesView &attrList) { +SemaObjC::DeclGroupPtrTy SemaObjC::ActOnForwardProtocolDeclaration( + SourceLocation AtProtocolLoc, ArrayRef IdentList, + const ParsedAttributesView &attrList) { ASTContext &Context = getASTContext(); SmallVector DeclsInGroup; for (const IdentifierLocPair &IdentPair : IdentList) { IdentifierInfo *Ident = IdentPair.first; - ObjCProtocolDecl *PrevDecl = LookupProtocol(Ident, IdentPair.second, - SemaRef.forRedeclarationInCurContext()); - ObjCProtocolDecl *PDecl - = ObjCProtocolDecl::Create(Context, SemaRef.CurContext, Ident, - IdentPair.second, AtProtocolLoc, - PrevDecl); + ObjCProtocolDecl *PrevDecl = LookupProtocol( + Ident, IdentPair.second, SemaRef.forRedeclarationInCurContext()); + ObjCProtocolDecl *PDecl = + ObjCProtocolDecl::Create(Context, SemaRef.CurContext, Ident, + IdentPair.second, AtProtocolLoc, PrevDecl); SemaRef.PushOnScopeChains(PDecl, SemaRef.TUScope); CheckObjCDeclScope(PDecl); @@ -1845,16 +1822,16 @@ ObjCCategoryDecl *SemaObjC::ActOnStartCategoryInterface( /// Check that class of this category is already completely declared. - if (!IDecl - || SemaRef.RequireCompleteType(ClassLoc, Context.getObjCInterfaceType(IDecl), - diag::err_category_forward_interface, - CategoryName == nullptr)) { + if (!IDecl || + SemaRef.RequireCompleteType(ClassLoc, Context.getObjCInterfaceType(IDecl), + diag::err_category_forward_interface, + CategoryName == nullptr)) { // Create an invalid ObjCCategoryDecl to serve as context for // the enclosing method declarations. We mark the decl invalid // to make it clear that this isn't a valid AST. - CDecl = ObjCCategoryDecl::Create(Context, SemaRef.CurContext, AtInterfaceLoc, - ClassLoc, CategoryLoc, CategoryName, - IDecl, typeParamList); + CDecl = ObjCCategoryDecl::Create(Context, SemaRef.CurContext, + AtInterfaceLoc, ClassLoc, CategoryLoc, + CategoryName, IDecl, typeParamList); CDecl->setInvalidDecl(); SemaRef.CurContext->addDecl(CDecl); @@ -1884,10 +1861,10 @@ ObjCCategoryDecl *SemaObjC::ActOnStartCategoryInterface( // If we have a type parameter list, check it. if (typeParamList) { if (auto prevTypeParamList = IDecl->getTypeParamList()) { - if (checkTypeParamListConsistency(SemaRef, prevTypeParamList, typeParamList, - CategoryName - ? TypeParamListContext::Category - : TypeParamListContext::Extension)) + if (checkTypeParamListConsistency( + SemaRef, prevTypeParamList, typeParamList, + CategoryName ? TypeParamListContext::Category + : TypeParamListContext::Extension)) typeParamList = nullptr; } else { Diag(typeParamList->getLAngleLoc(), @@ -1913,7 +1890,7 @@ ObjCCategoryDecl *SemaObjC::ActOnStartCategoryInterface( SemaRef.AddPragmaAttributes(SemaRef.TUScope, CDecl); if (NumProtoRefs) { - diagnoseUseOfProtocols(SemaRef, CDecl, (ObjCProtocolDecl*const*)ProtoRefs, + diagnoseUseOfProtocols(SemaRef, CDecl, (ObjCProtocolDecl *const *)ProtoRefs, NumProtoRefs, ProtoLocs); CDecl->setProtocolList((ObjCProtocolDecl*const*)ProtoRefs, NumProtoRefs, ProtoLocs, Context); @@ -1943,23 +1920,24 @@ ObjCCategoryImplDecl *SemaObjC::ActOnStartCategoryImplementation( if (!CatIDecl) { // Category @implementation with no corresponding @interface. // Create and install one. - CatIDecl = ObjCCategoryDecl::Create(Context, SemaRef.CurContext, AtCatImplLoc, - ClassLoc, CatLoc, - CatName, IDecl, - /*typeParamList=*/nullptr); + CatIDecl = + ObjCCategoryDecl::Create(Context, SemaRef.CurContext, AtCatImplLoc, + ClassLoc, CatLoc, CatName, IDecl, + /*typeParamList=*/nullptr); CatIDecl->setImplicit(); } } ObjCCategoryImplDecl *CDecl = - ObjCCategoryImplDecl::Create(Context, SemaRef.CurContext, CatName, IDecl, - ClassLoc, AtCatImplLoc, CatLoc); + ObjCCategoryImplDecl::Create(Context, SemaRef.CurContext, CatName, IDecl, + ClassLoc, AtCatImplLoc, CatLoc); /// Check that class of this category is already completely declared. if (!IDecl) { Diag(ClassLoc, diag::err_undef_interface) << ClassName; CDecl->setInvalidDecl(); - } else if (SemaRef.RequireCompleteType(ClassLoc, Context.getObjCInterfaceType(IDecl), - diag::err_undef_interface)) { + } else if (SemaRef.RequireCompleteType(ClassLoc, + Context.getObjCInterfaceType(IDecl), + diag::err_undef_interface)) { CDecl->setInvalidDecl(); } @@ -2005,9 +1983,9 @@ ObjCImplementationDecl *SemaObjC::ActOnStartClassImplementation( ASTContext &Context = getASTContext(); ObjCInterfaceDecl *IDecl = nullptr; // Check for another declaration kind with the same name. - NamedDecl *PrevDecl - = SemaRef.LookupSingleName(SemaRef.TUScope, ClassName, ClassLoc, Sema::LookupOrdinaryName, - SemaRef.forRedeclarationInCurContext()); + NamedDecl *PrevDecl = SemaRef.LookupSingleName( + SemaRef.TUScope, ClassName, ClassLoc, Sema::LookupOrdinaryName, + SemaRef.forRedeclarationInCurContext()); if (PrevDecl && !isa(PrevDecl)) { Diag(ClassLoc, diag::err_redefinition_different_kind) << ClassName; Diag(PrevDecl->getLocation(), diag::note_previous_definition); @@ -2015,21 +1993,22 @@ ObjCImplementationDecl *SemaObjC::ActOnStartClassImplementation( // FIXME: This will produce an error if the definition of the interface has // been imported from a module but is not visible. SemaRef.RequireCompleteType(ClassLoc, Context.getObjCInterfaceType(IDecl), - diag::warn_undef_interface); + diag::warn_undef_interface); } else { // We did not find anything with the name ClassName; try to correct for // typos in the class name. ObjCInterfaceValidatorCCC CCC{}; - TypoCorrection Corrected = - SemaRef.CorrectTypo(DeclarationNameInfo(ClassName, ClassLoc), - Sema::LookupOrdinaryName, SemaRef.TUScope, nullptr, CCC, Sema::CTK_NonError); + TypoCorrection Corrected = SemaRef.CorrectTypo( + DeclarationNameInfo(ClassName, ClassLoc), Sema::LookupOrdinaryName, + SemaRef.TUScope, nullptr, CCC, Sema::CTK_NonError); if (Corrected.getCorrectionDeclAs()) { // Suggest the (potentially) correct interface name. Don't provide a // code-modification hint or use the typo name for recovery, because // this is just a warning. The program may actually be correct. SemaRef.diagnoseTypo(Corrected, - SemaRef.PDiag(diag::warn_undef_interface_suggest) << ClassName, - /*ErrorRecovery*/false); + SemaRef.PDiag(diag::warn_undef_interface_suggest) + << ClassName, + /*ErrorRecovery*/ false); } else { Diag(ClassLoc, diag::warn_undef_interface) << ClassName; } @@ -2039,8 +2018,9 @@ ObjCImplementationDecl *SemaObjC::ActOnStartClassImplementation( ObjCInterfaceDecl *SDecl = nullptr; if (SuperClassname) { // Check if a different kind of symbol declared in this scope. - PrevDecl = SemaRef.LookupSingleName(SemaRef.TUScope, SuperClassname, SuperClassLoc, - Sema::LookupOrdinaryName); + PrevDecl = + SemaRef.LookupSingleName(SemaRef.TUScope, SuperClassname, SuperClassLoc, + Sema::LookupOrdinaryName); if (PrevDecl && !isa(PrevDecl)) { Diag(SuperClassLoc, diag::err_redefinition_different_kind) << SuperClassname; @@ -2068,10 +2048,10 @@ ObjCImplementationDecl *SemaObjC::ActOnStartClassImplementation( // FIXME: Do we support attributes on the @implementation? If so we should // copy them over. - IDecl = ObjCInterfaceDecl::Create(Context, SemaRef.CurContext, AtClassImplLoc, - ClassName, /*typeParamList=*/nullptr, - /*PrevDecl=*/nullptr, ClassLoc, - true); + IDecl = + ObjCInterfaceDecl::Create(Context, SemaRef.CurContext, AtClassImplLoc, + ClassName, /*typeParamList=*/nullptr, + /*PrevDecl=*/nullptr, ClassLoc, true); SemaRef.AddPragmaAttributes(SemaRef.TUScope, IDecl); IDecl->startDefinition(); if (SDecl) { @@ -2092,9 +2072,9 @@ ObjCImplementationDecl *SemaObjC::ActOnStartClassImplementation( IDecl->startDefinition(); } - ObjCImplementationDecl* IMPDecl = - ObjCImplementationDecl::Create(Context, SemaRef.CurContext, IDecl, SDecl, - ClassLoc, AtClassImplLoc, SuperClassLoc); + ObjCImplementationDecl *IMPDecl = + ObjCImplementationDecl::Create(Context, SemaRef.CurContext, IDecl, SDecl, + ClassLoc, AtClassImplLoc, SuperClassLoc); SemaRef.ProcessDeclAttributeList(SemaRef.TUScope, IMPDecl, Attrs); SemaRef.AddPragmaAttributes(SemaRef.TUScope, IMPDecl); @@ -2133,7 +2113,8 @@ ObjCImplementationDecl *SemaObjC::ActOnStartClassImplementation( } SemaObjC::DeclGroupPtrTy -SemaObjC::ActOnFinishObjCImplementation(Decl *ObjCImpDecl, ArrayRef Decls) { +SemaObjC::ActOnFinishObjCImplementation(Decl *ObjCImpDecl, + ArrayRef Decls) { SmallVector DeclsInGroup; DeclsInGroup.reserve(Decls.size() + 1); @@ -2152,8 +2133,8 @@ SemaObjC::ActOnFinishObjCImplementation(Decl *ObjCImpDecl, ArrayRef Decl } void SemaObjC::CheckImplementationIvars(ObjCImplementationDecl *ImpDecl, - ObjCIvarDecl **ivars, unsigned numIvars, - SourceLocation RBrace) { + ObjCIvarDecl **ivars, unsigned numIvars, + SourceLocation RBrace) { assert(ImpDecl && "missing implementation decl"); ASTContext &Context = getASTContext(); ObjCInterfaceDecl* IDecl = ImpDecl->getClassInterface(); @@ -2270,7 +2251,8 @@ static void WarnUndefinedMethod(Sema &S, ObjCImplDecl *Impl, // separate warnings. We will give that approach a try, as that // matches what we do with protocols. { - const SemaBase::SemaDiagnosticBuilder &B = S.Diag(Impl->getLocation(), DiagID); + const SemaBase::SemaDiagnosticBuilder &B = + S.Diag(Impl->getLocation(), DiagID); B << method; if (NeededFor) B << NeededFor; @@ -2601,15 +2583,14 @@ static bool checkMethodFamilyMismatch(Sema &S, ObjCMethodDecl *impl, } void SemaObjC::WarnConflictingTypedMethods(ObjCMethodDecl *ImpMethodDecl, - ObjCMethodDecl *MethodDecl, - bool IsProtocolMethodDecl) { + ObjCMethodDecl *MethodDecl, + bool IsProtocolMethodDecl) { if (getLangOpts().ObjCAutoRefCount && checkMethodFamilyMismatch(SemaRef, ImpMethodDecl, MethodDecl)) return; CheckMethodOverrideReturn(SemaRef, ImpMethodDecl, MethodDecl, - IsProtocolMethodDecl, false, - true); + IsProtocolMethodDecl, false, true); for (ObjCMethodDecl::param_iterator IM = ImpMethodDecl->param_begin(), IF = MethodDecl->param_begin(), EM = ImpMethodDecl->param_end(), @@ -2627,12 +2608,11 @@ void SemaObjC::WarnConflictingTypedMethods(ObjCMethodDecl *ImpMethodDecl, } void SemaObjC::CheckConflictingOverridingMethod(ObjCMethodDecl *Method, - ObjCMethodDecl *Overridden, - bool IsProtocolMethodDecl) { + ObjCMethodDecl *Overridden, + bool IsProtocolMethodDecl) { - CheckMethodOverrideReturn(SemaRef, Method, Overridden, - IsProtocolMethodDecl, true, - true); + CheckMethodOverrideReturn(SemaRef, Method, Overridden, IsProtocolMethodDecl, + true, true); for (ObjCMethodDecl::param_iterator IM = Method->param_begin(), IF = Overridden->param_begin(), EM = Method->param_end(), @@ -2652,8 +2632,8 @@ void SemaObjC::CheckConflictingOverridingMethod(ObjCMethodDecl *Method, /// WarnExactTypedMethods - This routine issues a warning if method /// implementation declaration matches exactly that of its declaration. void SemaObjC::WarnExactTypedMethods(ObjCMethodDecl *ImpMethodDecl, - ObjCMethodDecl *MethodDecl, - bool IsProtocolMethodDecl) { + ObjCMethodDecl *MethodDecl, + bool IsProtocolMethodDecl) { ASTContext &Context = getASTContext(); // don't issue warning when protocol method is optional because primary // class is not required to implement it and it is safe for protocol @@ -2668,15 +2648,14 @@ void SemaObjC::WarnExactTypedMethods(ObjCMethodDecl *ImpMethodDecl, return; bool match = CheckMethodOverrideReturn(SemaRef, ImpMethodDecl, MethodDecl, - IsProtocolMethodDecl, false, false); + IsProtocolMethodDecl, false, false); if (match) for (ObjCMethodDecl::param_iterator IM = ImpMethodDecl->param_begin(), IF = MethodDecl->param_begin(), EM = ImpMethodDecl->param_end(), EF = MethodDecl->param_end(); IM != EM && IF != EF; ++IM, ++IF) { - match = CheckMethodOverrideParam(SemaRef, ImpMethodDecl, MethodDecl, - *IM, *IF, - IsProtocolMethodDecl, false, false); + match = CheckMethodOverrideParam(SemaRef, ImpMethodDecl, MethodDecl, *IM, + *IF, IsProtocolMethodDecl, false, false); if (!match) break; } @@ -2851,15 +2830,11 @@ static void CheckProtocolMethodDefs( /// MatchAllMethodDeclarations - Check methods declared in interface /// or protocol against those declared in their implementations. /// -void SemaObjC::MatchAllMethodDeclarations(const SelectorSet &InsMap, - const SelectorSet &ClsMap, - SelectorSet &InsMapSeen, - SelectorSet &ClsMapSeen, - ObjCImplDecl* IMPDecl, - ObjCContainerDecl* CDecl, - bool &IncompleteImpl, - bool ImmediateClass, - bool WarnCategoryMethodImpl) { +void SemaObjC::MatchAllMethodDeclarations( + const SelectorSet &InsMap, const SelectorSet &ClsMap, + SelectorSet &InsMapSeen, SelectorSet &ClsMapSeen, ObjCImplDecl *IMPDecl, + ObjCContainerDecl *CDecl, bool &IncompleteImpl, bool ImmediateClass, + bool WarnCategoryMethodImpl) { // Check and see if instance methods in class interface have been // implemented in the implementation class. If so, their types match. for (auto *I : CDecl->instance_methods()) { @@ -2965,7 +2940,7 @@ void SemaObjC::MatchAllMethodDeclarations(const SelectorSet &InsMap, /// category matches with those implemented in its primary class and /// warns each time an exact match is found. void SemaObjC::CheckCategoryVsClassMethodMatches( - ObjCCategoryImplDecl *CatIMPDecl) { + ObjCCategoryImplDecl *CatIMPDecl) { // Get category's primary class. ObjCCategoryDecl *CatDecl = CatIMPDecl->getCategoryDecl(); if (!CatDecl) @@ -3003,9 +2978,9 @@ void SemaObjC::CheckCategoryVsClassMethodMatches( true /*WarnCategoryMethodImpl*/); } -void SemaObjC::ImplMethodsVsClassMethods(Scope *S, ObjCImplDecl* IMPDecl, - ObjCContainerDecl* CDecl, - bool IncompleteImpl) { +void SemaObjC::ImplMethodsVsClassMethods(Scope *S, ObjCImplDecl *IMPDecl, + ObjCContainerDecl *CDecl, + bool IncompleteImpl) { SelectorSet InsMap; // Check and see if instance methods in class interface have been // implemented in the implementation class. @@ -3081,19 +3056,17 @@ void SemaObjC::ImplMethodsVsClassMethods(Scope *S, ObjCImplDecl* IMPDecl, llvm_unreachable("invalid ObjCContainerDecl type."); } -SemaObjC::DeclGroupPtrTy -SemaObjC::ActOnForwardClassDeclaration(SourceLocation AtClassLoc, - IdentifierInfo **IdentList, - SourceLocation *IdentLocs, - ArrayRef TypeParamLists, - unsigned NumElts) { +SemaObjC::DeclGroupPtrTy SemaObjC::ActOnForwardClassDeclaration( + SourceLocation AtClassLoc, IdentifierInfo **IdentList, + SourceLocation *IdentLocs, ArrayRef TypeParamLists, + unsigned NumElts) { ASTContext &Context = getASTContext(); SmallVector DeclsInGroup; for (unsigned i = 0; i != NumElts; ++i) { // Check for another declaration kind with the same name. - NamedDecl *PrevDecl - = SemaRef.LookupSingleName(SemaRef.TUScope, IdentList[i], IdentLocs[i], - Sema::LookupOrdinaryName, SemaRef.forRedeclarationInCurContext()); + NamedDecl *PrevDecl = SemaRef.LookupSingleName( + SemaRef.TUScope, IdentList[i], IdentLocs[i], Sema::LookupOrdinaryName, + SemaRef.forRedeclarationInCurContext()); if (PrevDecl && !isa(PrevDecl)) { // GCC apparently allows the following idiom: // @@ -3148,8 +3121,8 @@ SemaObjC::ActOnForwardClassDeclaration(SourceLocation AtClassLoc, if (ObjCTypeParamList *PrevTypeParams = PrevIDecl->getTypeParamList()) { // Check for consistency with the previous declaration. if (checkTypeParamListConsistency( - SemaRef, PrevTypeParams, TypeParams, - TypeParamListContext::ForwardDeclaration)) { + SemaRef, PrevTypeParams, TypeParams, + TypeParamListContext::ForwardDeclaration)) { TypeParams = nullptr; } } else if (ObjCInterfaceDecl *Def = PrevIDecl->getDefinition()) { @@ -3164,10 +3137,9 @@ SemaObjC::ActOnForwardClassDeclaration(SourceLocation AtClassLoc, } } - ObjCInterfaceDecl *IDecl - = ObjCInterfaceDecl::Create(Context, SemaRef.CurContext, AtClassLoc, - ClassName, TypeParams, PrevIDecl, - IdentLocs[i]); + ObjCInterfaceDecl *IDecl = ObjCInterfaceDecl::Create( + Context, SemaRef.CurContext, AtClassLoc, ClassName, TypeParams, + PrevIDecl, IdentLocs[i]); IDecl->setAtEndRange(IdentLocs[i]); if (PrevIDecl) @@ -3185,8 +3157,9 @@ static bool tryMatchRecordTypes(ASTContext &Context, SemaObjC::MethodMatchStrategy strategy, const Type *left, const Type *right); -static bool matchTypes(ASTContext &Context, SemaObjC::MethodMatchStrategy strategy, - QualType leftQT, QualType rightQT) { +static bool matchTypes(ASTContext &Context, + SemaObjC::MethodMatchStrategy strategy, QualType leftQT, + QualType rightQT) { const Type *left = Context.getCanonicalType(leftQT).getUnqualifiedType().getTypePtr(); const Type *right = @@ -3195,7 +3168,8 @@ static bool matchTypes(ASTContext &Context, SemaObjC::MethodMatchStrategy strate if (left == right) return true; // If we're doing a strict match, the types have to match exactly. - if (strategy == SemaObjC::MMS_strict) return false; + if (strategy == SemaObjC::MMS_strict) + return false; if (left->isIncompleteType() || right->isIncompleteType()) return false; @@ -3282,8 +3256,8 @@ static bool tryMatchRecordTypes(ASTContext &Context, /// returns true, or false, accordingly. /// TODO: Handle protocol list; such as id in type comparisons bool SemaObjC::MatchTwoMethodDeclarations(const ObjCMethodDecl *left, - const ObjCMethodDecl *right, - MethodMatchStrategy strategy) { + const ObjCMethodDecl *right, + MethodMatchStrategy strategy) { ASTContext &Context = getASTContext(); if (!matchTypes(Context, strategy, left->getReturnType(), right->getReturnType())) @@ -3342,7 +3316,7 @@ static bool isMethodContextSameForKindofLookup(ObjCMethodDecl *Method, } void SemaObjC::addMethodToGlobalList(ObjCMethodList *List, - ObjCMethodDecl *Method) { + ObjCMethodDecl *Method) { // Record at the head of the list whether there were 0, 1, or >= 2 methods // inside categories. if (ObjCCategoryDecl *CD = @@ -3458,7 +3432,7 @@ void SemaObjC::updateOutOfDateSelector(Selector Sel) { } void SemaObjC::AddMethodToGlobalPool(ObjCMethodDecl *Method, bool impl, - bool instance) { + bool instance) { // Ignore methods of invalid containers. if (cast(Method->getDeclContext())->isInvalidDecl()) return; @@ -3538,8 +3512,7 @@ static bool FilterMethodsByTypeBound(ObjCMethodDecl *Method, /// all methods with that type. bool SemaObjC::CollectMultipleMethodsInGlobalPool( Selector Sel, SmallVectorImpl &Methods, - bool InstanceFirst, bool CheckTheOther, - const ObjCObjectType *TypeBound) { + bool InstanceFirst, bool CheckTheOther, const ObjCObjectType *TypeBound) { if (SemaRef.ExternalSource) ReadMethodPool(Sel); @@ -3601,8 +3574,8 @@ bool SemaObjC::AreMultipleMethodsInGlobalPool( } ObjCMethodDecl *SemaObjC::LookupMethodInGlobalPool(Selector Sel, SourceRange R, - bool receiverIdOrClass, - bool instance) { + bool receiverIdOrClass, + bool instance) { if (SemaRef.ExternalSource) ReadMethodPool(Sel); @@ -3620,17 +3593,18 @@ ObjCMethodDecl *SemaObjC::LookupMethodInGlobalPool(Selector Sel, SourceRange R, return nullptr; } -void SemaObjC::DiagnoseMultipleMethodInGlobalPool(SmallVectorImpl &Methods, - Selector Sel, SourceRange R, - bool receiverIdOrClass) { +void SemaObjC::DiagnoseMultipleMethodInGlobalPool( + SmallVectorImpl &Methods, Selector Sel, SourceRange R, + bool receiverIdOrClass) { // We found multiple methods, so we may have to complain. bool issueDiagnostic = false, issueError = false; // We support a warning which complains about *any* difference in // method signature. bool strictSelectorMatch = - receiverIdOrClass && - !getDiagnostics().isIgnored(diag::warn_strict_multiple_method_decl, R.getBegin()); + receiverIdOrClass && + !getDiagnostics().isIgnored(diag::warn_strict_multiple_method_decl, + R.getBegin()); if (strictSelectorMatch) { for (unsigned I = 1, N = Methods.size(); I != N; ++I) { if (!MatchTwoMethodDeclarations(Methods[0], Methods[I], MMS_strict)) { @@ -3723,15 +3697,15 @@ static bool HelperIsMethodInObjCType(Sema &S, Selector Sel, QualType ObjectType) { if (ObjectType.isNull()) return true; - if (S.ObjC().LookupMethodInObjectType(Sel, ObjectType, true/*Instance method*/)) + if (S.ObjC().LookupMethodInObjectType(Sel, ObjectType, + true /*Instance method*/)) return true; - return S.ObjC().LookupMethodInObjectType(Sel, ObjectType, false/*Class method*/) != - nullptr; + return S.ObjC().LookupMethodInObjectType(Sel, ObjectType, + false /*Class method*/) != nullptr; } const ObjCMethodDecl * -SemaObjC::SelectorsForTypoCorrection(Selector Sel, - QualType ObjectType) { +SemaObjC::SelectorsForTypoCorrection(Selector Sel, QualType ObjectType) { unsigned NumArgs = Sel.getNumArgs(); SmallVector Methods; bool ObjectIsId = true, ObjectIsClass = true; @@ -3761,8 +3735,8 @@ SemaObjC::SelectorsForTypoCorrection(Selector Sel, if (ObjectIsId) Methods.push_back(M->getMethod()); else if (!ObjectIsClass && - HelperIsMethodInObjCType(SemaRef, M->getMethod()->getSelector(), - ObjectType)) + HelperIsMethodInObjCType( + SemaRef, M->getMethod()->getSelector(), ObjectType)) Methods.push_back(M->getMethod()); } // class methods @@ -3773,8 +3747,8 @@ SemaObjC::SelectorsForTypoCorrection(Selector Sel, if (ObjectIsClass) Methods.push_back(M->getMethod()); else if (!ObjectIsId && - HelperIsMethodInObjCType(SemaRef, M->getMethod()->getSelector(), - ObjectType)) + HelperIsMethodInObjCType( + SemaRef, M->getMethod()->getSelector(), ObjectType)) Methods.push_back(M->getMethod()); } } @@ -3793,7 +3767,7 @@ SemaObjC::SelectorsForTypoCorrection(Selector Sel, /// add ivars to a class in random order which will not be known until /// class's \@implementation is seen. void SemaObjC::DiagnoseDuplicateIvars(ObjCInterfaceDecl *ID, - ObjCInterfaceDecl *SID) { + ObjCInterfaceDecl *SID) { for (auto *Ivar : ID->ivars()) { if (Ivar->isInvalidDecl()) continue; @@ -3847,21 +3821,21 @@ static void DiagnoseRetainableFlexibleArrayMember(Sema &S, SemaObjC::ObjCContainerKind SemaObjC::getObjCContainerKind() const { switch (SemaRef.CurContext->getDeclKind()) { - case Decl::ObjCInterface: - return SemaObjC::OCK_Interface; - case Decl::ObjCProtocol: - return SemaObjC::OCK_Protocol; - case Decl::ObjCCategory: - if (cast(SemaRef.CurContext)->IsClassExtension()) - return SemaObjC::OCK_ClassExtension; - return SemaObjC::OCK_Category; - case Decl::ObjCImplementation: - return SemaObjC::OCK_Implementation; - case Decl::ObjCCategoryImpl: - return SemaObjC::OCK_CategoryImplementation; - - default: - return SemaObjC::OCK_None; + case Decl::ObjCInterface: + return SemaObjC::OCK_Interface; + case Decl::ObjCProtocol: + return SemaObjC::OCK_Protocol; + case Decl::ObjCCategory: + if (cast(SemaRef.CurContext)->IsClassExtension()) + return SemaObjC::OCK_ClassExtension; + return SemaObjC::OCK_Category; + case Decl::ObjCImplementation: + return SemaObjC::OCK_Implementation; + case Decl::ObjCCategoryImpl: + return SemaObjC::OCK_CategoryImplementation; + + default: + return SemaObjC::OCK_None; } } @@ -4005,8 +3979,9 @@ static void DiagnoseCategoryDirectMembersProtocolConformance( } // Note: For class/category implementations, allMethods is always null. -Decl *SemaObjC::ActOnAtEnd(Scope *S, SourceRange AtEnd, ArrayRef allMethods, - ArrayRef allTUVars) { +Decl *SemaObjC::ActOnAtEnd(Scope *S, SourceRange AtEnd, + ArrayRef allMethods, + ArrayRef allTUVars) { ASTContext &Context = getASTContext(); if (getObjCContainerKind() == SemaObjC::OCK_None) return nullptr; @@ -4106,7 +4081,8 @@ Decl *SemaObjC::ActOnAtEnd(Scope *S, SourceRange AtEnd, ArrayRef allMeth DiagnoseClassExtensionDupMethods(C, CCPrimary); } - DiagnoseCategoryDirectMembersProtocolConformance(SemaRef, C, C->protocols()); + DiagnoseCategoryDirectMembersProtocolConformance(SemaRef, C, + C->protocols()); } if (ObjCContainerDecl *CDecl = dyn_cast(ClassDecl)) { if (CDecl->getIdentifier()) @@ -4166,9 +4142,9 @@ Decl *SemaObjC::ActOnAtEnd(Scope *S, SourceRange AtEnd, ArrayRef allMeth << IDecl->getIdentifier(); // See if NSObject is in the current scope, and if it is, suggest // adding " : NSObject " to the class declaration. - NamedDecl *IF = SemaRef.LookupSingleName(SemaRef.TUScope, - NSAPIObj->getNSClassId(NSAPI::ClassId_NSObject), - DeclLoc, Sema::LookupOrdinaryName); + NamedDecl *IF = SemaRef.LookupSingleName( + SemaRef.TUScope, NSAPIObj->getNSClassId(NSAPI::ClassId_NSObject), + DeclLoc, Sema::LookupOrdinaryName); ObjCInterfaceDecl *NSObjectDecl = dyn_cast_or_null(IF); if (NSObjectDecl && NSObjectDecl->getDefinition()) { Diag(SuperClassLoc, diag::note_objc_needs_superclass) @@ -4316,7 +4292,8 @@ class OverrideSearch { // Bypass this search if we've never seen an instance/class method // with this selector before. - SemaObjC::GlobalMethodPool::iterator it = S.ObjC().MethodPool.find(selector); + SemaObjC::GlobalMethodPool::iterator it = + S.ObjC().MethodPool.find(selector); if (it == S.ObjC().MethodPool.end()) { if (!S.getExternalSource()) return; S.ObjC().ReadMethodPool(selector); @@ -4450,7 +4427,7 @@ class OverrideSearch { } // end anonymous namespace void SemaObjC::CheckObjCMethodDirectOverrides(ObjCMethodDecl *method, - ObjCMethodDecl *overridden) { + ObjCMethodDecl *overridden) { if (overridden->isDirectMethod()) { const auto *attr = overridden->getAttr(); Diag(method->getLocation(), diag::err_objc_override_direct_method); @@ -4464,8 +4441,8 @@ void SemaObjC::CheckObjCMethodDirectOverrides(ObjCMethodDecl *method, } void SemaObjC::CheckObjCMethodOverrides(ObjCMethodDecl *ObjCMethod, - ObjCInterfaceDecl *CurrentClass, - ResultTypeCompatibilityKind RTC) { + ObjCInterfaceDecl *CurrentClass, + ResultTypeCompatibilityKind RTC) { ASTContext &Context = getASTContext(); if (!ObjCMethod) return; @@ -4785,8 +4762,8 @@ Decl *SemaObjC::ActOnMethodDeclaration( } ObjCMethodDecl *ObjCMethod = ObjCMethodDecl::Create( - Context, MethodLoc, EndLoc, Sel, resultDeclType, ReturnTInfo, SemaRef.CurContext, - MethodType == tok::minus, isVariadic, + Context, MethodLoc, EndLoc, Sel, resultDeclType, ReturnTInfo, + SemaRef.CurContext, MethodType == tok::minus, isVariadic, /*isPropertyAccessor=*/false, /*isSynthesizedAccessorStub=*/false, /*isImplicitlyDeclared=*/false, /*isDefined=*/false, MethodDeclKind == tok::objc_optional @@ -4808,7 +4785,8 @@ Decl *SemaObjC::ActOnMethodDeclaration( } LookupResult R(SemaRef, ArgInfo[i].Name, ArgInfo[i].NameLoc, - Sema::LookupOrdinaryName, SemaRef.forRedeclarationInCurContext()); + Sema::LookupOrdinaryName, + SemaRef.forRedeclarationInCurContext()); SemaRef.LookupName(R, S); if (R.isSingleResult()) { NamedDecl *PrevDecl = R.getFoundDecl(); @@ -4826,9 +4804,9 @@ Decl *SemaObjC::ActOnMethodDeclaration( ? DI->getTypeLoc().getBeginLoc() : ArgInfo[i].NameLoc; - ParmVarDecl* Param = SemaRef.CheckParameter(ObjCMethod, StartLoc, - ArgInfo[i].NameLoc, ArgInfo[i].Name, - ArgType, DI, SC_None); + ParmVarDecl *Param = + SemaRef.CheckParameter(ObjCMethod, StartLoc, ArgInfo[i].NameLoc, + ArgInfo[i].Name, ArgType, DI, SC_None); Param->setObjCMethodScopeInfo(i); @@ -4836,7 +4814,8 @@ Decl *SemaObjC::ActOnMethodDeclaration( CvtQTToAstBitMask(ArgInfo[i].DeclSpec.getObjCDeclQualifier())); // Apply the attributes to the parameter. - SemaRef.ProcessDeclAttributeList(SemaRef.TUScope, Param, ArgInfo[i].ArgAttrs); + SemaRef.ProcessDeclAttributeList(SemaRef.TUScope, Param, + ArgInfo[i].ArgAttrs); SemaRef.AddPragmaAttributes(SemaRef.TUScope, Param); SemaRef.ProcessAPINotes(Param); @@ -5043,8 +5022,8 @@ Decl *SemaObjC::ActOnMethodDeclaration( CurrentClass = CatImpl->getClassInterface(); } - ResultTypeCompatibilityKind RTC - = CheckRelatedResultTypeCompatibility(SemaRef, ObjCMethod, CurrentClass); + ResultTypeCompatibilityKind RTC = + CheckRelatedResultTypeCompatibility(SemaRef, ObjCMethod, CurrentClass); CheckObjCMethodOverrides(ObjCMethod, CurrentClass, RTC); @@ -5118,7 +5097,8 @@ bool SemaObjC::CheckObjCDeclScope(Decl *D) { // If we switched context to translation unit while we are still lexically in // an objc container, it means the parser missed emitting an error. - if (isa(SemaRef.getCurLexicalContext()->getRedeclContext())) + if (isa( + SemaRef.getCurLexicalContext()->getRedeclContext())) return false; Diag(D->getLocation(), diag::err_objc_decls_may_only_appear_in_global_scope); @@ -5130,8 +5110,8 @@ bool SemaObjC::CheckObjCDeclScope(Decl *D) { /// Called whenever \@defs(ClassName) is encountered in the source. Inserts the /// instance variables of ClassName into Decls. void SemaObjC::ActOnDefs(Scope *S, Decl *TagD, SourceLocation DeclStart, - const IdentifierInfo *ClassName, - SmallVectorImpl &Decls) { + const IdentifierInfo *ClassName, + SmallVectorImpl &Decls) { ASTContext &Context = getASTContext(); // Check that ClassName is a valid class ObjCInterfaceDecl *Class = getObjCInterfaceDecl(ClassName, DeclStart); @@ -5172,9 +5152,10 @@ void SemaObjC::ActOnDefs(Scope *S, Decl *TagD, SourceLocation DeclStart, /// Build a type-check a new Objective-C exception variable declaration. VarDecl *SemaObjC::BuildObjCExceptionDecl(TypeSourceInfo *TInfo, QualType T, - SourceLocation StartLoc, - SourceLocation IdLoc, - const IdentifierInfo *Id, bool Invalid) { + SourceLocation StartLoc, + SourceLocation IdLoc, + const IdentifierInfo *Id, + bool Invalid) { ASTContext &Context = getASTContext(); // ISO/IEC TR 18037 S6.7.3: "The type of an object with automatic storage // duration shall not be qualified by an address-space qualifier." @@ -5204,8 +5185,8 @@ VarDecl *SemaObjC::BuildObjCExceptionDecl(TypeSourceInfo *TInfo, QualType T, Diag(IdLoc, diag::err_catch_param_not_objc_type); } - VarDecl *New = VarDecl::Create(Context, SemaRef.CurContext, StartLoc, IdLoc, Id, - T, TInfo, SC_None); + VarDecl *New = VarDecl::Create(Context, SemaRef.CurContext, StartLoc, IdLoc, + Id, T, TInfo, SC_None); New->setExceptionVariable(true); // In ARC, infer 'retaining' for variables of retainable type. @@ -5275,8 +5256,8 @@ Decl *SemaObjC::ActOnObjCExceptionDecl(Scope *S, Declarator &D) { /// CollectIvarsToConstructOrDestruct - Collect those ivars which require /// initialization. -void SemaObjC::CollectIvarsToConstructOrDestruct(ObjCInterfaceDecl *OI, - SmallVectorImpl &Ivars) { +void SemaObjC::CollectIvarsToConstructOrDestruct( + ObjCInterfaceDecl *OI, SmallVectorImpl &Ivars) { ASTContext &Context = getASTContext(); for (ObjCIvarDecl *Iv = OI->all_declared_ivar_begin(); Iv; Iv= Iv->getNextIvar()) { @@ -5312,7 +5293,7 @@ void SemaObjC::DiagnoseUseOfUnimplementedSelectors() { ObjCIvarDecl * SemaObjC::GetIvarBackingPropertyAccessor(const ObjCMethodDecl *Method, - const ObjCPropertyDecl *&PDecl) const { + const ObjCPropertyDecl *&PDecl) const { if (Method->isClassMethod()) return nullptr; const ObjCInterfaceDecl *IDecl = Method->getClassInterface(); @@ -5336,44 +5317,44 @@ SemaObjC::GetIvarBackingPropertyAccessor(const ObjCMethodDecl *Method, } namespace { - /// Used by SemaObjC::DiagnoseUnusedBackingIvarInAccessor to check if a property - /// accessor references the backing ivar. - class UnusedBackingIvarChecker : - public RecursiveASTVisitor { - public: - Sema &S; - const ObjCMethodDecl *Method; - const ObjCIvarDecl *IvarD; - bool AccessedIvar; - bool InvokedSelfMethod; - - UnusedBackingIvarChecker(Sema &S, const ObjCMethodDecl *Method, - const ObjCIvarDecl *IvarD) - : S(S), Method(Method), IvarD(IvarD), - AccessedIvar(false), InvokedSelfMethod(false) { - assert(IvarD); - } - - bool VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) { - if (E->getDecl() == IvarD) { - AccessedIvar = true; - return false; - } - return true; +/// Used by SemaObjC::DiagnoseUnusedBackingIvarInAccessor to check if a property +/// accessor references the backing ivar. +class UnusedBackingIvarChecker + : public RecursiveASTVisitor { +public: + Sema &S; + const ObjCMethodDecl *Method; + const ObjCIvarDecl *IvarD; + bool AccessedIvar; + bool InvokedSelfMethod; + + UnusedBackingIvarChecker(Sema &S, const ObjCMethodDecl *Method, + const ObjCIvarDecl *IvarD) + : S(S), Method(Method), IvarD(IvarD), AccessedIvar(false), + InvokedSelfMethod(false) { + assert(IvarD); + } + + bool VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) { + if (E->getDecl() == IvarD) { + AccessedIvar = true; + return false; } + return true; + } - bool VisitObjCMessageExpr(ObjCMessageExpr *E) { - if (E->getReceiverKind() == ObjCMessageExpr::Instance && - S.ObjC().isSelfExpr(E->getInstanceReceiver(), Method)) { - InvokedSelfMethod = true; - } - return true; + bool VisitObjCMessageExpr(ObjCMessageExpr *E) { + if (E->getReceiverKind() == ObjCMessageExpr::Instance && + S.ObjC().isSelfExpr(E->getInstanceReceiver(), Method)) { + InvokedSelfMethod = true; } + return true; + } }; } // end anonymous namespace -void SemaObjC::DiagnoseUnusedBackingIvarInAccessor(Scope *S, - const ObjCImplementationDecl *ImplD) { +void SemaObjC::DiagnoseUnusedBackingIvarInAccessor( + Scope *S, const ObjCImplementationDecl *ImplD) { if (S->hasUnrecoverableErrorOccurred()) return; @@ -5407,9 +5388,8 @@ void SemaObjC::DiagnoseUnusedBackingIvarInAccessor(Scope *S, } } -QualType SemaObjC::AdjustParameterTypeForObjCAutoRefCount(QualType T, - SourceLocation NameLoc, - TypeSourceInfo *TSInfo) { +QualType SemaObjC::AdjustParameterTypeForObjCAutoRefCount( + QualType T, SourceLocation NameLoc, TypeSourceInfo *TSInfo) { ASTContext &Context = getASTContext(); // In ARC, infer a lifetime qualifier for appropriate parameter types. if (!getLangOpts().ObjCAutoRefCount || @@ -5424,8 +5404,9 @@ QualType SemaObjC::AdjustParameterTypeForObjCAutoRefCount(QualType T, if (T->isArrayType()) { if (!T.isConstQualified()) { if (SemaRef.DelayedDiagnostics.shouldDelayDiagnostics()) - SemaRef.DelayedDiagnostics.add(sema::DelayedDiagnostic::makeForbiddenType( - NameLoc, diag::err_arc_array_param_no_ownership, T, false)); + SemaRef.DelayedDiagnostics.add( + sema::DelayedDiagnostic::makeForbiddenType( + NameLoc, diag::err_arc_array_param_no_ownership, T, false)); else Diag(NameLoc, diag::err_arc_array_param_no_ownership) << TSInfo->getTypeLoc().getSourceRange(); @@ -5440,20 +5421,22 @@ QualType SemaObjC::AdjustParameterTypeForObjCAutoRefCount(QualType T, } ObjCInterfaceDecl *SemaObjC::getObjCInterfaceDecl(const IdentifierInfo *&Id, - SourceLocation IdLoc, - bool DoTypoCorrection) { + SourceLocation IdLoc, + bool DoTypoCorrection) { // The third "scope" argument is 0 since we aren't enabling lazy built-in // creation from this context. - NamedDecl *IDecl = SemaRef.LookupSingleName(SemaRef.TUScope, Id, IdLoc, Sema::LookupOrdinaryName); + NamedDecl *IDecl = SemaRef.LookupSingleName(SemaRef.TUScope, Id, IdLoc, + Sema::LookupOrdinaryName); if (!IDecl && DoTypoCorrection) { // Perform typo correction at the given location, but only if we // find an Objective-C class name. DeclFilterCCC CCC{}; - if (TypoCorrection C = - SemaRef.CorrectTypo(DeclarationNameInfo(Id, IdLoc), Sema::LookupOrdinaryName, - SemaRef.TUScope, nullptr, CCC, Sema::CTK_ErrorRecovery)) { - SemaRef.diagnoseTypo(C, SemaRef.PDiag(diag::err_undef_interface_suggest) << Id); + if (TypoCorrection C = SemaRef.CorrectTypo( + DeclarationNameInfo(Id, IdLoc), Sema::LookupOrdinaryName, + SemaRef.TUScope, nullptr, CCC, Sema::CTK_ErrorRecovery)) { + SemaRef.diagnoseTypo(C, SemaRef.PDiag(diag::err_undef_interface_suggest) + << Id); IDecl = C.getCorrectionDeclAs(); Id = IDecl->getIdentifier(); } @@ -5461,7 +5444,7 @@ ObjCInterfaceDecl *SemaObjC::getObjCInterfaceDecl(const IdentifierInfo *&Id, ObjCInterfaceDecl *Def = dyn_cast_or_null(IDecl); // This routine must always return a class definition, if any. if (Def && Def->getDefinition()) - Def = Def->getDefinition(); + Def = Def->getDefinition(); return Def; } @@ -5484,8 +5467,7 @@ bool SemaObjC::inferObjCARCLifetime(ValueDecl *decl) { } if (kind != -1U) { - Diag(decl->getLocation(), diag::err_arc_autoreleasing_var) - << kind; + Diag(decl->getLocation(), diag::err_arc_autoreleasing_var) << kind; } } else if (lifetime == Qualifiers::OCL_None) { // Try to infer lifetime. @@ -5502,7 +5484,7 @@ bool SemaObjC::inferObjCARCLifetime(ValueDecl *decl) { if (lifetime && lifetime != Qualifiers::OCL_ExplicitNone && var->getTLSKind()) { Diag(var->getLocation(), diag::err_arc_thread_ownership) - << var->getType(); + << var->getType(); return true; } } @@ -5519,11 +5501,11 @@ void SemaObjC::SetIvarInitializers(ObjCImplementationDecl *ObjCImplementation) { return; if (ObjCInterfaceDecl *OID = ObjCImplementation->getClassInterface()) { ASTContext &Context = getASTContext(); - SmallVector ivars; + SmallVector ivars; CollectIvarsToConstructOrDestruct(OID, ivars); if (ivars.empty()) return; - SmallVector AllToInit; + SmallVector AllToInit; for (unsigned i = 0; i < ivars.size(); i++) { FieldDecl *Field = ivars[i]; if (Field->isInvalidDecl()) @@ -5532,9 +5514,10 @@ void SemaObjC::SetIvarInitializers(ObjCImplementationDecl *ObjCImplementation) { CXXCtorInitializer *Member; InitializedEntity InitEntity = InitializedEntity::InitializeMember(Field); InitializationKind InitKind = - InitializationKind::CreateDefault(ObjCImplementation->getLocation()); + InitializationKind::CreateDefault(ObjCImplementation->getLocation()); - InitializationSequence InitSeq(SemaRef, InitEntity, InitKind, std::nullopt); + InitializationSequence InitSeq(SemaRef, InitEntity, InitKind, + std::nullopt); ExprResult MemberInit = InitSeq.Perform(SemaRef, InitEntity, InitKind, std::nullopt); MemberInit = SemaRef.MaybeCreateExprWithCleanups(MemberInit); @@ -5543,11 +5526,9 @@ void SemaObjC::SetIvarInitializers(ObjCImplementationDecl *ObjCImplementation) { if (!MemberInit.get() || MemberInit.isInvalid()) continue; - Member = - new (Context) CXXCtorInitializer(Context, Field, SourceLocation(), - SourceLocation(), - MemberInit.getAs(), - SourceLocation()); + Member = new (Context) + CXXCtorInitializer(Context, Field, SourceLocation(), SourceLocation(), + MemberInit.getAs(), SourceLocation()); AllToInit.push_back(Member); // Be sure that the destructor is accessible and is marked as referenced. @@ -5557,14 +5538,15 @@ void SemaObjC::SetIvarInitializers(ObjCImplementationDecl *ObjCImplementation) { CXXRecordDecl *RD = cast(RecordTy->getDecl()); if (CXXDestructorDecl *Destructor = SemaRef.LookupDestructor(RD)) { SemaRef.MarkFunctionReferenced(Field->getLocation(), Destructor); - SemaRef.CheckDestructorAccess(Field->getLocation(), Destructor, - SemaRef.PDiag(diag::err_access_dtor_ivar) - << Context.getBaseElementType(Field->getType())); + SemaRef.CheckDestructorAccess( + Field->getLocation(), Destructor, + SemaRef.PDiag(diag::err_access_dtor_ivar) + << Context.getBaseElementType(Field->getType())); } } } - ObjCImplementation->setIvarInitializers(Context, - AllToInit.data(), AllToInit.size()); + ObjCImplementation->setIvarInitializers(Context, AllToInit.data(), + AllToInit.size()); } } @@ -5573,22 +5555,28 @@ void SemaObjC::SetIvarInitializers(ObjCImplementationDecl *ObjCImplementation) { static ObjCIvarDecl::AccessControl TranslateIvarVisibility(tok::ObjCKeywordKind ivarVisibility) { switch (ivarVisibility) { - default: llvm_unreachable("Unknown visitibility kind"); - case tok::objc_private: return ObjCIvarDecl::Private; - case tok::objc_public: return ObjCIvarDecl::Public; - case tok::objc_protected: return ObjCIvarDecl::Protected; - case tok::objc_package: return ObjCIvarDecl::Package; + default: + llvm_unreachable("Unknown visitibility kind"); + case tok::objc_private: + return ObjCIvarDecl::Private; + case tok::objc_public: + return ObjCIvarDecl::Public; + case tok::objc_protected: + return ObjCIvarDecl::Protected; + case tok::objc_package: + return ObjCIvarDecl::Package; } } /// ActOnIvar - Each ivar field of an objective-c class is passed into this /// in order to create an IvarDecl object for it. Decl *SemaObjC::ActOnIvar(Scope *S, SourceLocation DeclStart, Declarator &D, - Expr *BitWidth, tok::ObjCKeywordKind Visibility) { + Expr *BitWidth, tok::ObjCKeywordKind Visibility) { const IdentifierInfo *II = D.getIdentifier(); SourceLocation Loc = DeclStart; - if (II) Loc = D.getIdentifierLoc(); + if (II) + Loc = D.getIdentifierLoc(); // FIXME: Unnamed fields can be handled in various different ways, for // example, unnamed unions inject all members into the struct namespace! @@ -5598,14 +5586,15 @@ Decl *SemaObjC::ActOnIvar(Scope *S, SourceLocation DeclStart, Declarator &D, if (BitWidth) { // 6.7.2.1p3, 6.7.2.1p4 - BitWidth = SemaRef.VerifyBitField(Loc, II, T, /*IsMsStruct*/false, BitWidth).get(); + BitWidth = + SemaRef.VerifyBitField(Loc, II, T, /*IsMsStruct*/ false, BitWidth) + .get(); if (!BitWidth) D.setInvalidType(); } else { // Not a bitfield. // validate II. - } if (T->isReferenceType()) { Diag(Loc, diag::err_ivar_reference_type); @@ -5620,26 +5609,26 @@ Decl *SemaObjC::ActOnIvar(Scope *S, SourceLocation DeclStart, Declarator &D, } // Get the visibility (access control) for this ivar. - ObjCIvarDecl::AccessControl ac = - Visibility != tok::objc_not_keyword ? TranslateIvarVisibility(Visibility) - : ObjCIvarDecl::None; + ObjCIvarDecl::AccessControl ac = Visibility != tok::objc_not_keyword + ? TranslateIvarVisibility(Visibility) + : ObjCIvarDecl::None; // Must set ivar's DeclContext to its enclosing interface. - ObjCContainerDecl *EnclosingDecl = cast(SemaRef.CurContext); + ObjCContainerDecl *EnclosingDecl = + cast(SemaRef.CurContext); if (!EnclosingDecl || EnclosingDecl->isInvalidDecl()) return nullptr; ObjCContainerDecl *EnclosingContext; if (ObjCImplementationDecl *IMPDecl = - dyn_cast(EnclosingDecl)) { + dyn_cast(EnclosingDecl)) { if (getLangOpts().ObjCRuntime.isFragile()) { - // Case of ivar declared in an implementation. Context is that of its class. + // Case of ivar declared in an implementation. Context is that of its + // class. EnclosingContext = IMPDecl->getClassInterface(); assert(EnclosingContext && "Implementation has no class interface!"); - } - else + } else EnclosingContext = EnclosingDecl; } else { - if (ObjCCategoryDecl *CDecl = - dyn_cast(EnclosingDecl)) { + if (ObjCCategoryDecl *CDecl = dyn_cast(EnclosingDecl)) { if (getLangOpts().ObjCRuntime.isFragile() || !CDecl->IsClassExtension()) { Diag(Loc, diag::err_misplaced_ivar) << CDecl->IsClassExtension(); return nullptr; @@ -5649,17 +5638,19 @@ Decl *SemaObjC::ActOnIvar(Scope *S, SourceLocation DeclStart, Declarator &D, } // Construct the decl. - ObjCIvarDecl *NewID = ObjCIvarDecl::Create( - getASTContext(), EnclosingContext, DeclStart, Loc, II, T, TInfo, ac, BitWidth); + ObjCIvarDecl *NewID = + ObjCIvarDecl::Create(getASTContext(), EnclosingContext, DeclStart, Loc, + II, T, TInfo, ac, BitWidth); if (T->containsErrors()) NewID->setInvalidDecl(); if (II) { - NamedDecl *PrevDecl = SemaRef.LookupSingleName(S, II, Loc, Sema::LookupMemberName, - RedeclarationKind::ForVisibleRedeclaration); - if (PrevDecl && SemaRef.isDeclInScope(PrevDecl, EnclosingContext, S) - && !isa(PrevDecl)) { + NamedDecl *PrevDecl = + SemaRef.LookupSingleName(S, II, Loc, Sema::LookupMemberName, + RedeclarationKind::ForVisibleRedeclaration); + if (PrevDecl && SemaRef.isDeclInScope(PrevDecl, EnclosingContext, S) && + !isa(PrevDecl)) { Diag(Loc, diag::err_duplicate_member) << II; Diag(PrevDecl->getLocation(), diag::note_previous_declaration); NewID->setInvalidDecl(); @@ -5686,8 +5677,8 @@ Decl *SemaObjC::ActOnIvar(Scope *S, SourceLocation DeclStart, Declarator &D, SemaRef.IdResolver.AddDecl(NewID); } - if (getLangOpts().ObjCRuntime.isNonFragile() && - !NewID->isInvalidDecl() && isa(EnclosingDecl)) + if (getLangOpts().ObjCRuntime.isNonFragile() && !NewID->isInvalidDecl() && + isa(EnclosingDecl)) Diag(Loc, diag::warn_ivars_in_interface); return NewID; diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 91732645662b3..c40f5ad304f24 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -1053,7 +1053,7 @@ ExprResult Sema::DefaultVariadicArgumentPromotion(Expr *E, VariadicCallType CT, (FDecl && FDecl->hasAttr()))) { E = ObjC().stripARCUnbridgedCast(E); - // Otherwise, do normal placeholder checking. + // Otherwise, do normal placeholder checking. } else { ExprResult ExprRes = CheckPlaceholderExpr(E); if (ExprRes.isInvalid()) @@ -5253,8 +5253,8 @@ Sema::CreateBuiltinArraySubscriptExpr(Expr *Base, SourceLocation LLoc, // Use custom logic if this should be the pseudo-object subscript // expression. if (!LangOpts.isSubscriptPointerArithmetic()) - return ObjC().BuildObjCSubscriptExpression(RLoc, BaseExpr, IndexExpr, nullptr, - nullptr); + return ObjC().BuildObjCSubscriptExpression(RLoc, BaseExpr, IndexExpr, + nullptr, nullptr); ResultType = PTy->getPointeeType(); } else if (const PointerType *PTy = RHSTy->getAs()) { @@ -8620,8 +8620,8 @@ QualType Sema::CheckConditionalOperands(ExprResult &Cond, ExprResult &LHS, if (!checkConditionalNullPointer(*this, LHS, RHSTy)) return RHSTy; // All objective-c pointer type analysis is done here. - QualType compositeType = ObjC().FindCompositeObjCPointerType(LHS, RHS, - QuestionLoc); + QualType compositeType = + ObjC().FindCompositeObjCPointerType(LHS, RHS, QuestionLoc); if (LHS.isInvalid() || RHS.isInvalid()) return QualType(); if (!compositeType.isNull()) @@ -9862,14 +9862,14 @@ Sema::CheckSingleAssignmentConstraints(QualType LHSType, ExprResult &CallerRHS, // resolution, return Incompatible to indicate the failure. if (getLangOpts().allowsNonTrivialObjCLifetimeQualifiers() && ObjC().CheckObjCConversion(SourceRange(), Ty, E, - CheckedConversionKind::Implicit, Diagnose, - DiagnoseCFAudited) != SemaObjC::ACR_okay) { + CheckedConversionKind::Implicit, Diagnose, + DiagnoseCFAudited) != SemaObjC::ACR_okay) { if (!Diagnose) return Incompatible; } if (getLangOpts().ObjC && (ObjC().CheckObjCBridgeRelatedConversions(E->getBeginLoc(), LHSType, - E->getType(), E, Diagnose) || + E->getType(), E, Diagnose) || ObjC().CheckConversionToObjCLiteral(LHSType, E, Diagnose))) { if (!Diagnose) return Incompatible; @@ -11688,18 +11688,19 @@ static bool hasIsEqualMethod(Sema &S, const Expr *LHS, const Expr *RHS) { // Try to find the -isEqual: method. Selector IsEqualSel = S.ObjC().NSAPIObj->getIsEqualSelector(); - ObjCMethodDecl *Method = S.ObjC().LookupMethodInObjectType(IsEqualSel, - InterfaceType, - /*IsInstance=*/true); + ObjCMethodDecl *Method = + S.ObjC().LookupMethodInObjectType(IsEqualSel, InterfaceType, + /*IsInstance=*/true); if (!Method) { if (Type->isObjCIdType()) { // For 'id', just check the global pool. - Method = S.ObjC().LookupInstanceMethodInGlobalPool(IsEqualSel, SourceRange(), - /*receiverId=*/true); + Method = + S.ObjC().LookupInstanceMethodInGlobalPool(IsEqualSel, SourceRange(), + /*receiverId=*/true); } else { // Check protocols. Method = S.ObjC().LookupMethodInQualifiedType(IsEqualSel, Type, - /*IsInstance=*/true); + /*IsInstance=*/true); } } @@ -12542,7 +12543,7 @@ QualType Sema::CheckCompareOperands(ExprResult &LHS, ExprResult &RHS, Expr *E = LHS.get(); if (getLangOpts().ObjCAutoRefCount) ObjC().CheckObjCConversion(SourceRange(), RHSType, E, - CheckedConversionKind::Implicit); + CheckedConversionKind::Implicit); LHS = ImpCastExprToType(E, RHSType, RPT ? CK_BitCast :CK_CPointerToObjCPointerCast); } @@ -12550,9 +12551,9 @@ QualType Sema::CheckCompareOperands(ExprResult &LHS, ExprResult &RHS, Expr *E = RHS.get(); if (getLangOpts().ObjCAutoRefCount) ObjC().CheckObjCConversion(SourceRange(), LHSType, E, - CheckedConversionKind::Implicit, - /*Diagnose=*/true, - /*DiagnoseCFAudited=*/false, Opc); + CheckedConversionKind::Implicit, + /*Diagnose=*/true, + /*DiagnoseCFAudited=*/false, Opc); RHS = ImpCastExprToType(E, LHSType, LPT ? CK_BitCast :CK_CPointerToObjCPointerCast); } diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 74be45bfc3643..7c3c551d2a224 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -4607,7 +4607,7 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType, ObjC().EmitRelatedResultTypeNote(From); } else if (getLangOpts().allowsNonTrivialObjCLifetimeQualifiers() && !ObjC().CheckObjCARCUnavailableWeakConversion(ToType, - From->getType())) { + From->getType())) { if (Action == AA_Initializing) Diag(From->getBeginLoc(), diag::err_arc_weak_unavailable_assign); else @@ -4642,7 +4642,7 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType, // FIXME: doing this here is really ugly. if (Kind == CK_BlockPointerToObjCPointerCast) { ExprResult E = From; - (void) ObjC().PrepareCastToObjCObjectPointer(E); + (void)ObjC().PrepareCastToObjCObjectPointer(E); From = E.get(); } if (getLangOpts().allowsNonTrivialObjCLifetimeQualifiers()) @@ -8665,7 +8665,7 @@ static ExprResult attemptRecovery(Sema &SemaRef, /*TemplateArgs*/ nullptr, /*S*/ nullptr); } else if (auto *Ivar = dyn_cast(ND)) { return SemaRef.ObjC().LookupInObjCMethod(R, Consumer.getScope(), - Ivar->getIdentifier()); + Ivar->getIdentifier()); } } diff --git a/clang/lib/Sema/SemaExprMember.cpp b/clang/lib/Sema/SemaExprMember.cpp index dc3bb2f12fa5e..88b2644477fee 100644 --- a/clang/lib/Sema/SemaExprMember.cpp +++ b/clang/lib/Sema/SemaExprMember.cpp @@ -1497,8 +1497,7 @@ static ExprResult LookupMemberExpr(Sema &S, LookupResult &R, if (warn) { if (ObjCMethodDecl *MD = S.getCurMethodDecl()) { ObjCMethodFamily MF = MD->getMethodFamily(); - warn = (MF != OMF_init && MF != OMF_dealloc && - MF != OMF_finalize && + warn = (MF != OMF_init && MF != OMF_dealloc && MF != OMF_finalize && !S.ObjC().IvarBacksCurrentMethodAccessor(IDecl, MD, IV)); } if (warn) @@ -1637,9 +1636,9 @@ static ExprResult LookupMemberExpr(Sema &S, LookupResult &R, } // Normal property access. - return S.ObjC().HandleExprPropertyRefExpr(OPT, BaseExpr.get(), OpLoc, MemberName, - MemberLoc, SourceLocation(), QualType(), - false); + return S.ObjC().HandleExprPropertyRefExpr( + OPT, BaseExpr.get(), OpLoc, MemberName, MemberLoc, SourceLocation(), + QualType(), false); } if (BaseType->isExtVectorBoolType()) { diff --git a/clang/lib/Sema/SemaExprObjC.cpp b/clang/lib/Sema/SemaExprObjC.cpp index 1ae3f9096bbd0..462ab2c952b67 100644 --- a/clang/lib/Sema/SemaExprObjC.cpp +++ b/clang/lib/Sema/SemaExprObjC.cpp @@ -10,8 +10,6 @@ // //===----------------------------------------------------------------------===// -#include "clang/Basic/TargetInfo.h" -#include "clang/Sema/SemaObjC.h" #include "clang/AST/ASTContext.h" #include "clang/AST/DeclObjC.h" #include "clang/AST/ExprObjC.h" @@ -19,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" @@ -27,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 @@ -36,7 +36,7 @@ using namespace sema; using llvm::ArrayRef; ExprResult SemaObjC::ParseObjCStringLiteral(SourceLocation *AtLocs, - ArrayRef Strings) { + ArrayRef 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 @@ -82,7 +82,8 @@ ExprResult SemaObjC::ParseObjCStringLiteral(SourceLocation *AtLocs, return BuildObjCStringLiteral(AtLocs[0], S); } -ExprResult SemaObjC::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)) @@ -105,7 +106,7 @@ ExprResult SemaObjC::BuildObjCStringLiteral(SourceLocation AtLoc, StringLiteral NSIdent = &Context.Idents.get(StringClass); NamedDecl *IF = SemaRef.LookupSingleName(SemaRef.TUScope, NSIdent, AtLoc, - Sema::LookupOrdinaryName); + Sema::LookupOrdinaryName); if (ObjCInterfaceDecl *StrIF = dyn_cast_or_null(IF)) { Context.setObjCConstantStringInterface(StrIF); Ty = Context.getObjCConstantStringInterface(); @@ -120,7 +121,7 @@ ExprResult SemaObjC::BuildObjCStringLiteral(SourceLocation AtLoc, StringLiteral } else { IdentifierInfo *NSIdent = NSAPIObj->getNSClassId(NSAPI::ClassId_NSString); NamedDecl *IF = SemaRef.LookupSingleName(SemaRef.TUScope, NSIdent, AtLoc, - Sema::LookupOrdinaryName); + Sema::LookupOrdinaryName); if (ObjCInterfaceDecl *StrIF = dyn_cast_or_null(IF)) { Context.setObjCConstantStringInterface(StrIF); Ty = Context.getObjCConstantStringInterface(); @@ -172,25 +173,25 @@ static bool validateBoxingMethod(Sema &S, SourceLocation Loc, } /// Maps ObjCLiteralKind to NSClassIdKindKind -static NSAPI::NSClassIdKindKind ClassKindFromLiteralKind( - SemaObjC::ObjCLiteralKind LiteralKind) { +static NSAPI::NSClassIdKindKind +ClassKindFromLiteralKind(SemaObjC::ObjCLiteralKind LiteralKind) { switch (LiteralKind) { - 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; + 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"); } @@ -198,9 +199,10 @@ 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, - SemaObjC::ObjCLiteralKind LiteralKind) { +static bool +ValidateObjCLiteralInterfaceDecl(Sema &S, ObjCInterfaceDecl *Decl, + SourceLocation Loc, + SemaObjC::ObjCLiteralKind LiteralKind) { if (!Decl) { NSAPI::NSClassIdKindKind Kind = ClassKindFromLiteralKind(LiteralKind); IdentifierInfo *II = S.ObjC().NSAPIObj->getNSClassId(Kind); @@ -220,9 +222,9 @@ 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, - SemaObjC::ObjCLiteralKind LiteralKind) { +static ObjCInterfaceDecl * +LookupObjCInterfaceDeclForLiteral(Sema &S, SourceLocation Loc, + SemaObjC::ObjCLiteralKind LiteralKind) { NSAPI::NSClassIdKindKind ClassKind = ClassKindFromLiteralKind(LiteralKind); IdentifierInfo *II = S.ObjC().NSAPIObj->getNSClassId(ClassKind); NamedDecl *IF = S.LookupSingleName(S.TUScope, II, Loc, @@ -271,8 +273,8 @@ static ObjCMethodDecl *getNSNumberFactoryMethod(SemaObjC &S, SourceLocation Loc, // 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.SemaRef, Loc, - SemaObjC::LK_Numeric); + S.NSNumberDecl = + LookupObjCInterfaceDeclForLiteral(S.SemaRef, Loc, SemaObjC::LK_Numeric); if (!S.NSNumberDecl) { return nullptr; } @@ -298,11 +300,10 @@ static ObjCMethodDecl *getNSNumberFactoryMethod(SemaObjC &S, SourceLocation Loc, /*isImplicitlyDeclared=*/true, /*isDefined=*/false, ObjCImplementationControl::Required, /*HasRelatedResultType=*/false); - ParmVarDecl *value = ParmVarDecl::Create(S.SemaRef.Context, Method, - SourceLocation(), SourceLocation(), - &CX.Idents.get("value"), - NumberType, /*TInfo=*/nullptr, - SC_None, nullptr); + 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); } @@ -318,7 +319,8 @@ static ObjCMethodDecl *getNSNumberFactoryMethod(SemaObjC &S, SourceLocation Loc, /// BuildObjCNumericLiteral - builds an ObjCBoxedExpr AST node for the /// numeric literal expression. Type of the expression will be "NSNumber *". -ExprResult SemaObjC::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(); @@ -357,32 +359,30 @@ ExprResult SemaObjC::BuildObjCNumericLiteral(SourceLocation AtLoc, Expr *Number) ParmVarDecl *ParamDecl = Method->parameters()[0]; InitializedEntity Entity = InitializedEntity::InitializeParameter(Context, ParamDecl); - ExprResult ConvertedNumber = SemaRef.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 SemaRef.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 SemaObjC::ActOnObjCBoolLiteral(SourceLocation AtLoc, - SourceLocation ValueLoc, - bool Value) { + SourceLocation ValueLoc, bool Value) { ASTContext &Context = getASTContext(); ExprResult Inner; if (getLangOpts().CPlusPlus) { - Inner = SemaRef.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 = SemaRef.ActOnIntegerConstant(ValueLoc, Value? 1 : 0); + Inner = SemaRef.ActOnIntegerConstant(ValueLoc, Value ? 1 : 0); Inner = SemaRef.ImpCastExprToType(Inner.get(), Context.BoolTy, - CK_IntegralToBoolean); + CK_IntegralToBoolean); } return BuildObjCNumericLiteral(AtLoc, Inner.get()); @@ -434,7 +434,8 @@ static ExprResult CheckObjCCollectionLiteralElement(Sema &S, Expr *Element, isa(OrigElement) || isa(OrigElement) || isa(OrigElement)) { - if (S.ObjC().NSAPIObj->getNSNumberFactoryMethodKind(OrigElement->getType())) { + if (S.ObjC().NSAPIObj->getNSNumberFactoryMethodKind( + OrigElement->getType())) { int Which = isa(OrigElement) ? 1 : (isa(OrigElement) || isa(OrigElement)) ? 2 @@ -444,8 +445,8 @@ static ExprResult CheckObjCCollectionLiteralElement(Sema &S, Expr *Element, << Which << OrigElement->getSourceRange() << FixItHint::CreateInsertion(OrigElement->getBeginLoc(), "@"); - Result = - S.ObjC().BuildObjCNumericLiteral(OrigElement->getBeginLoc(), OrigElement); + Result = S.ObjC().BuildObjCNumericLiteral(OrigElement->getBeginLoc(), + OrigElement); if (Result.isInvalid()) return ExprError(); @@ -460,7 +461,8 @@ static ExprResult CheckObjCCollectionLiteralElement(Sema &S, Expr *Element, << 0 << OrigElement->getSourceRange() << FixItHint::CreateInsertion(OrigElement->getBeginLoc(), "@"); - Result = S.ObjC().BuildObjCStringLiteral(OrigElement->getBeginLoc(), String); + Result = + S.ObjC().BuildObjCStringLiteral(OrigElement->getBeginLoc(), String); if (Result.isInvalid()) return ExprError(); @@ -526,8 +528,8 @@ ExprResult SemaObjC::BuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr) { if (Context.hasSameUnqualifiedType(PointeeType, Context.CharTy)) { if (!NSStringDecl) { - NSStringDecl = LookupObjCInterfaceDeclForLiteral(SemaRef, Loc, - LK_String); + NSStringDecl = + LookupObjCInterfaceDeclForLiteral(SemaRef, Loc, LK_String); if (!NSStringDecl) { return ExprError(); } @@ -591,7 +593,7 @@ ExprResult SemaObjC::BuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr) { if (!validateBoxingMethod(SemaRef, Loc, NSStringDecl, stringWithUTF8String, BoxingMethod)) - return ExprError(); + return ExprError(); StringWithUTF8StringMethod = BoxingMethod; } @@ -658,8 +660,7 @@ ExprResult SemaObjC::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(SemaRef, Loc, - LK_Boxed); + NSValueDecl = LookupObjCInterfaceDeclForLiteral(SemaRef, Loc, LK_Boxed); if (!NSValueDecl) { return ExprError(); } @@ -743,15 +744,15 @@ ExprResult SemaObjC::BuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr) { ExprResult ConvertedValueExpr; if (ValueType->isObjCBoxableRecordType()) { InitializedEntity IE = InitializedEntity::InitializeTemporary(ValueType); - ConvertedValueExpr = SemaRef.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 = SemaRef.PerformCopyInitialization(IE, SourceLocation(), - ValueExpr); + ConvertedValueExpr = + SemaRef.PerformCopyInitialization(IE, SourceLocation(), ValueExpr); } if (ConvertedValueExpr.isInvalid()) @@ -766,10 +767,9 @@ ExprResult SemaObjC::BuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr) { /// Build an ObjC subscript pseudo-object expression, given that /// that's supported by the runtime. -ExprResult SemaObjC::BuildObjCSubscriptExpression(SourceLocation RB, Expr *BaseExpr, - Expr *IndexExpr, - ObjCMethodDecl *getterMethod, - ObjCMethodDecl *setterMethod) { +ExprResult SemaObjC::BuildObjCSubscriptExpression( + SourceLocation RB, Expr *BaseExpr, Expr *IndexExpr, + ObjCMethodDecl *getterMethod, ObjCMethodDecl *setterMethod) { assert(!getLangOpts().isSubscriptPointerArithmetic()); ASTContext &Context = getASTContext(); @@ -797,13 +797,14 @@ ExprResult SemaObjC::BuildObjCSubscriptExpression(SourceLocation RB, Expr *BaseE getterMethod, setterMethod, RB); } -ExprResult SemaObjC::BuildObjCArrayLiteral(SourceRange SR, MultiExprArg Elements) { +ExprResult SemaObjC::BuildObjCArrayLiteral(SourceRange SR, + MultiExprArg Elements) { ASTContext &Context = getASTContext(); SourceLocation Loc = SR.getBegin(); if (!NSArrayDecl) { - NSArrayDecl = LookupObjCInterfaceDeclForLiteral(SemaRef, Loc, - SemaObjC::LK_Array); + NSArrayDecl = + LookupObjCInterfaceDeclForLiteral(SemaRef, Loc, SemaObjC::LK_Array); if (!NSArrayDecl) { return ExprError(); } @@ -884,9 +885,8 @@ ExprResult SemaObjC::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(SemaRef, - ElementsBuffer[I], - RequiredType, true); + ExprResult Converted = CheckObjCCollectionLiteralElement( + SemaRef, ElementsBuffer[I], RequiredType, true); if (Converted.isInvalid()) return ExprError(); @@ -897,9 +897,8 @@ ExprResult SemaObjC::BuildObjCArrayLiteral(SourceRange SR, MultiExprArg Elements = Context.getObjCObjectPointerType( Context.getObjCInterfaceType(NSArrayDecl)); - return SemaRef.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: @@ -958,14 +957,14 @@ CheckObjCDictionaryLiteralDuplicateKeys(Sema &S, } } -ExprResult SemaObjC::BuildObjCDictionaryLiteral(SourceRange SR, - MutableArrayRef Elements) { +ExprResult SemaObjC::BuildObjCDictionaryLiteral( + SourceRange SR, MutableArrayRef Elements) { ASTContext &Context = getASTContext(); SourceLocation Loc = SR.getBegin(); if (!NSDictionaryDecl) { - NSDictionaryDecl = LookupObjCInterfaceDeclForLiteral(SemaRef, Loc, - SemaObjC::LK_Dictionary); + NSDictionaryDecl = LookupObjCInterfaceDeclForLiteral( + SemaRef, Loc, SemaObjC::LK_Dictionary); if (!NSDictionaryDecl) { return ExprError(); } @@ -1017,7 +1016,7 @@ ExprResult SemaObjC::BuildObjCDictionaryLiteral(SourceRange SR, 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(); @@ -1094,14 +1093,14 @@ ExprResult SemaObjC::BuildObjCDictionaryLiteral(SourceRange SR, bool HasPackExpansions = false; for (ObjCDictionaryElement &Element : Elements) { // Check the key. - ExprResult Key = CheckObjCCollectionLiteralElement(SemaRef, Element.Key, - KeyT); + ExprResult Key = + CheckObjCCollectionLiteralElement(SemaRef, Element.Key, KeyT); if (Key.isInvalid()) return ExprError(); // Check the value. - ExprResult Value - = CheckObjCCollectionLiteralElement(SemaRef, Element.Value, ValueT); + ExprResult Value = + CheckObjCCollectionLiteralElement(SemaRef, Element.Value, ValueT); if (Value.isInvalid()) return ExprError(); @@ -1134,8 +1133,8 @@ ExprResult SemaObjC::BuildObjCDictionaryLiteral(SourceRange SR, } ExprResult SemaObjC::BuildObjCEncodeExpression(SourceLocation AtLoc, - TypeSourceInfo *EncodedTypeInfo, - SourceLocation RParenLoc) { + TypeSourceInfo *EncodedTypeInfo, + SourceLocation RParenLoc) { ASTContext &Context = getASTContext(); QualType EncodedType = EncodedTypeInfo->getType(); QualType StrTy; @@ -1145,8 +1144,8 @@ ExprResult SemaObjC::BuildObjCEncodeExpression(SourceLocation AtLoc, if (!EncodedType->getAsArrayTypeUnsafe() && //// Incomplete array is handled. !EncodedType->isVoidType()) // void is handled too. if (SemaRef.RequireCompleteType(AtLoc, EncodedType, - diag::err_incomplete_type_objc_at_encode, - EncodedTypeInfo->getTypeLoc())) + diag::err_incomplete_type_objc_at_encode, + EncodedTypeInfo->getTypeLoc())) return ExprError(); std::string Str; @@ -1165,17 +1164,17 @@ ExprResult SemaObjC::BuildObjCEncodeExpression(SourceLocation AtLoc, } ExprResult SemaObjC::ParseObjCEncodeExpression(SourceLocation AtLoc, - SourceLocation EncodeLoc, - SourceLocation LParenLoc, - ParsedType ty, - SourceLocation RParenLoc) { + SourceLocation EncodeLoc, + SourceLocation LParenLoc, + ParsedType ty, + SourceLocation RParenLoc) { ASTContext &Context = getASTContext(); // FIXME: Preserve type source info ? TypeSourceInfo *TInfo; QualType EncodedType = SemaRef.GetTypeFromParser(ty, &TInfo); if (!TInfo) - TInfo = Context.getTrivialTypeSourceInfo(EncodedType, - SemaRef.getLocForEndOfToken(LParenLoc)); + TInfo = Context.getTrivialTypeSourceInfo( + EncodedType, SemaRef.getLocForEndOfToken(LParenLoc)); return BuildObjCEncodeExpression(AtLoc, TInfo, RParenLoc); } @@ -1194,8 +1193,8 @@ static bool HelperToDiagnoseMismatchedMethodsInGlobalPool(Sema &S, isa(MatchingMethodDecl->getDeclContext()) || MatchingMethodDecl->getSelector() != Method->getSelector()) continue; - if (!S.ObjC().MatchTwoMethodDeclarations(Method, - MatchingMethodDecl, SemaObjC::MMS_loose)) { + if (!S.ObjC().MatchTwoMethodDeclarations(Method, MatchingMethodDecl, + SemaObjC::MMS_loose)) { if (!Warned) { Warned = true; S.Diag(AtLoc, diag::warn_multiple_selectors) @@ -1221,7 +1220,8 @@ static void DiagnoseMismatchedSelectors(Sema &S, SourceLocation AtLoc, return; bool Warned = false; for (SemaObjC::GlobalMethodPool::iterator b = S.ObjC().MethodPool.begin(), - e = S.ObjC().MethodPool.end(); b != e; b++) { + e = S.ObjC().MethodPool.end(); + b != e; b++) { // first, instance methods ObjCMethodList &InstMethList = b->second.first; if (HelperToDiagnoseMismatchedMethodsInGlobalPool(S, AtLoc, LParenLoc, RParenLoc, @@ -1299,11 +1299,11 @@ static ObjCMethodDecl *findMethodInCurrentClass(Sema &S, Selector Sel) { } ExprResult SemaObjC::ParseObjCSelectorExpression(Selector Sel, - SourceLocation AtLoc, - SourceLocation SelLoc, - SourceLocation LParenLoc, - SourceLocation RParenLoc, - bool WarnMultipleSelectors) { + SourceLocation AtLoc, + SourceLocation SelLoc, + SourceLocation LParenLoc, + SourceLocation RParenLoc, + bool WarnMultipleSelectors) { ASTContext &Context = getASTContext(); ObjCMethodDecl *Method = LookupInstanceMethodInGlobalPool(Sel, SourceRange(LParenLoc, RParenLoc)); @@ -1339,7 +1339,8 @@ ExprResult SemaObjC::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(SemaRef, Sel); + ObjCMethodDecl *LikelyTargetMethod = + findMethodInCurrentClass(SemaRef, Sel); if (LikelyTargetMethod && LikelyTargetMethod->isDirectMethod()) { Diag(AtLoc, diag::warn_potentially_direct_selector_expression) << Sel; Diag(LikelyTargetMethod->getLocation(), @@ -1394,11 +1395,11 @@ ExprResult SemaObjC::ParseObjCSelectorExpression(Selector Sel, } ExprResult SemaObjC::ParseObjCProtocolExpression(IdentifierInfo *ProtocolId, - SourceLocation AtLoc, - SourceLocation ProtoLoc, - SourceLocation LParenLoc, - SourceLocation ProtoIdLoc, - SourceLocation RParenLoc) { + SourceLocation AtLoc, + SourceLocation ProtoLoc, + SourceLocation LParenLoc, + SourceLocation ProtoIdLoc, + SourceLocation RParenLoc) { ASTContext &Context = getASTContext(); ObjCProtocolDecl* PDecl = LookupProtocol(ProtocolId, ProtoIdLoc); if (!PDecl) { @@ -1528,16 +1529,14 @@ static QualType getBaseMessageSendResultType(Sema &S, } QualType SemaObjC::getMessageSendResultType(const Expr *Receiver, - QualType ReceiverType, - ObjCMethodDecl *Method, - bool isClassMessage, - bool isSuperMessage) { + QualType ReceiverType, + ObjCMethodDecl *Method, + bool isClassMessage, + bool isSuperMessage) { ASTContext &Context = getASTContext(); // Produce the result type. - QualType resultType = getBaseMessageSendResultType(SemaRef, 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) { @@ -1873,14 +1872,15 @@ bool SemaObjC::CheckMessageArgumentTypes( *typeArgs, ObjCSubstitutionContext::Parameter); - if (SemaRef.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 = SemaRef.PerformCopyInitialization(Entity, SourceLocation(), argExpr); + ExprResult ArgE = + SemaRef.PerformCopyInitialization(Entity, SourceLocation(), argExpr); if (ArgE.isInvalid()) IsError = true; else { @@ -1905,8 +1905,8 @@ bool SemaObjC::CheckMessageArgumentTypes( if (Args[i]->isTypeDependent()) continue; - ExprResult Arg = SemaRef.DefaultVariadicArgumentPromotion(Args[i], Sema::VariadicMethod, - nullptr); + ExprResult Arg = SemaRef.DefaultVariadicArgumentPromotion( + Args[i], Sema::VariadicMethod, nullptr); IsError |= Arg.isInvalid(); Args[i] = Arg.get(); } @@ -1933,8 +1933,8 @@ bool SemaObjC::CheckMessageArgumentTypes( bool SemaObjC::isSelfExpr(Expr *RExpr) { // 'self' is objc 'self' in an objc method only. - ObjCMethodDecl *Method = - dyn_cast_or_null(SemaRef.CurContext->getNonClosureAncestor()); + ObjCMethodDecl *Method = dyn_cast_or_null( + SemaRef.CurContext->getNonClosureAncestor()); return isSelfExpr(RExpr, Method); } @@ -1950,7 +1950,7 @@ bool SemaObjC::isSelfExpr(Expr *receiver, const ObjCMethodDecl *method) { /// LookupMethodInType - Look up a method in an ObjCObjectType. ObjCMethodDecl *SemaObjC::LookupMethodInObjectType(Selector sel, QualType type, - bool isInstance) { + bool isInstance) { const ObjCObjectType *objType = type->castAs(); if (ObjCInterfaceDecl *iface = objType->getInterface()) { // Look it up in the main interface (and categories, etc.) @@ -1973,10 +1973,8 @@ ObjCMethodDecl *SemaObjC::LookupMethodInObjectType(Selector sel, QualType type, /// LookupMethodInQualifiedType - Lookups up a method in protocol qualifier /// list of a qualified objective pointer type. -ObjCMethodDecl *SemaObjC::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))) { @@ -1988,13 +1986,10 @@ ObjCMethodDecl *SemaObjC::LookupMethodInQualifiedType(Selector Sel, /// HandleExprPropertyRefExpr - Handle foo.bar where foo is a pointer to an /// objective C interface. This is a property reference expression. -ExprResult SemaObjC:: -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(); @@ -2010,8 +2005,8 @@ HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT, SourceRange BaseRange = Super? SourceRange(SuperLoc) : BaseExpr->getSourceRange(); if (SemaRef.RequireCompleteType(MemberLoc, OPT->getPointeeType(), - diag::err_property_not_found_forward_class, - MemberName, BaseRange)) + diag::err_property_not_found_forward_class, + MemberName, BaseRange)) return ExprError(); if (ObjCPropertyDecl *PD = IFace->FindPropertyDeclaration( @@ -2069,9 +2064,8 @@ HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT, } // 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(SemaRef.PP.getIdentifierTable(), - SemaRef.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. @@ -2139,8 +2133,9 @@ HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT, return ExprError(); } } else { - SemaRef.diagnoseTypo(Corrected, SemaRef.PDiag(diag::err_property_not_found_suggest) - << MemberName << QualType(OPT, 0)); + SemaRef.diagnoseTypo(Corrected, + SemaRef.PDiag(diag::err_property_not_found_suggest) + << MemberName << QualType(OPT, 0)); return HandleExprPropertyRefExpr(OPT, BaseExpr, OpLoc, TypoResult, MemberLoc, SuperLoc, SuperType, Super); @@ -2153,8 +2148,8 @@ HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT, if (const ObjCObjectPointerType * OBJPT = T->getAsObjCInterfacePointerType()) { if (SemaRef.RequireCompleteType(MemberLoc, OBJPT->getPointeeType(), - diag::err_property_not_as_forward_class, - MemberName, BaseExpr)) + diag::err_property_not_as_forward_class, + MemberName, BaseExpr)) return ExprError(); } Diag(MemberLoc, @@ -2172,10 +2167,9 @@ HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT, return ExprError(); } -ExprResult SemaObjC::ActOnClassPropertyRefExpr(const IdentifierInfo &receiverName, - const IdentifierInfo &propertyName, - SourceLocation receiverNameLoc, - SourceLocation propertyNameLoc) { +ExprResult SemaObjC::ActOnClassPropertyRefExpr( + const IdentifierInfo &receiverName, const IdentifierInfo &propertyName, + SourceLocation receiverNameLoc, SourceLocation propertyNameLoc) { ASTContext &Context = getASTContext(); const IdentifierInfo *receiverNamePtr = &receiverName; ObjCInterfaceDecl *IFace = getObjCInterfaceDecl(receiverNamePtr, @@ -2229,7 +2223,8 @@ ExprResult SemaObjC::ActOnClassPropertyRefExpr(const IdentifierInfo &receiverNam } else { GetterSel = SemaRef.PP.getSelectorTable().getNullarySelector(&propertyName); SetterSel = SelectorTable::constructSetterSelector( - SemaRef.PP.getIdentifierTable(), SemaRef.PP.getSelectorTable(), &propertyName); + SemaRef.PP.getIdentifierTable(), SemaRef.PP.getSelectorTable(), + &propertyName); } // Search for a declared property first. @@ -2297,12 +2292,10 @@ class ObjCInterfaceOrSuperCCC final : public CorrectionCandidateCallback { } // end anonymous namespace -SemaObjC::ObjCMessageKind SemaObjC::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; @@ -2376,15 +2369,15 @@ SemaObjC::ObjCMessageKind SemaObjC::getObjCMessageKind(Scope *S, 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. - SemaRef.diagnoseTypo(Corrected, - SemaRef.PDiag(diag::err_unknown_receiver_suggest) << Name); + SemaRef.diagnoseTypo( + Corrected, SemaRef.PDiag(diag::err_unknown_receiver_suggest) << Name); return ObjCSuperMessage; } else if (ObjCInterfaceDecl *Class = Corrected.getCorrectionDeclAs()) { // If we found a declaration, correct when it refers to an Objective-C // class. - SemaRef.diagnoseTypo(Corrected, - SemaRef.PDiag(diag::err_unknown_receiver_suggest) << Name); + SemaRef.diagnoseTypo( + Corrected, SemaRef.PDiag(diag::err_unknown_receiver_suggest) << Name); QualType T = Context.getObjCInterfaceType(Class); TypeSourceInfo *TSInfo = Context.getTrivialTypeSourceInfo(T, NameLoc); ReceiverType = SemaRef.CreateParsedType(T, TSInfo); @@ -2396,13 +2389,11 @@ SemaObjC::ObjCMessageKind SemaObjC::getObjCMessageKind(Scope *S, return ObjCInstanceMessage; } -ExprResult SemaObjC::ActOnSuperMessage(Scope *S, - SourceLocation SuperLoc, - Selector Sel, - SourceLocation LBracLoc, - ArrayRef SelectorLocs, - SourceLocation RBracLoc, - MultiExprArg Args) { +ExprResult SemaObjC::ActOnSuperMessage(Scope *S, SourceLocation SuperLoc, + Selector Sel, SourceLocation LBracLoc, + ArrayRef SelectorLocs, + SourceLocation RBracLoc, + MultiExprArg Args) { ASTContext &Context = getASTContext(); // Determine whether we are inside a method or not. ObjCMethodDecl *Method = tryCaptureObjCSelf(SuperLoc); @@ -2449,11 +2440,10 @@ ExprResult SemaObjC::ActOnSuperMessage(Scope *S, } ExprResult SemaObjC::BuildClassMessageImplicit(QualType ReceiverType, - bool isSuperReceiver, - SourceLocation Loc, - Selector Sel, - ObjCMethodDecl *Method, - MultiExprArg Args) { + bool isSuperReceiver, + SourceLocation Loc, Selector Sel, + ObjCMethodDecl *Method, + MultiExprArg Args) { ASTContext &Context = getASTContext(); TypeSourceInfo *receiverTypeInfo = nullptr; if (!ReceiverType.isNull()) @@ -2478,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.ObjC().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. @@ -2625,16 +2615,11 @@ DiagnoseCStringFormatDirectiveInObjCAPI(Sema &S, /// \param RBracLoc The location of the closing square bracket ']'. /// /// \param ArgsIn The message arguments. -ExprResult SemaObjC::BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo, - QualType ReceiverType, - SourceLocation SuperLoc, - Selector Sel, - ObjCMethodDecl *Method, - SourceLocation LBracLoc, - ArrayRef SelectorLocs, - SourceLocation RBracLoc, - MultiExprArg ArgsIn, - bool isImplicit) { +ExprResult SemaObjC::BuildClassMessage( + TypeSourceInfo *ReceiverTypeInfo, QualType ReceiverType, + SourceLocation SuperLoc, Selector Sel, ObjCMethodDecl *Method, + SourceLocation LBracLoc, ArrayRef SelectorLocs, + SourceLocation RBracLoc, MultiExprArg ArgsIn, bool isImplicit) { ASTContext &Context = getASTContext(); SourceLocation Loc = SuperLoc.isValid()? SuperLoc : ReceiverTypeInfo->getTypeLoc().getSourceRange().getBegin(); @@ -2680,10 +2665,10 @@ ExprResult SemaObjC::BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo, = SuperLoc.isValid()? SourceRange(SuperLoc) : ReceiverTypeInfo->getTypeLoc().getSourceRange(); if (SemaRef.RequireCompleteType(Loc, Context.getObjCInterfaceType(Class), - (getLangOpts().ObjCAutoRefCount - ? diag::err_arc_receiver_forward_class - : diag::warn_receiver_forward_class), - TypeRange)) { + (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)); @@ -2698,8 +2683,8 @@ ExprResult SemaObjC::BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo, if (!Method) Method = Class->lookupPrivateClassMethod(Sel); - if (Method && SemaRef.DiagnoseUseOfDecl(Method, SelectorSlotLocs, - nullptr, false, false, Class)) + if (Method && SemaRef.DiagnoseUseOfDecl(Method, SelectorSlotLocs, nullptr, + false, false, Class)) return ExprError(); } @@ -2716,8 +2701,9 @@ ExprResult SemaObjC::BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo, return ExprError(); if (Method && !Method->getReturnType()->isVoidType() && - SemaRef.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()) { @@ -2740,8 +2726,7 @@ ExprResult SemaObjC::BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo, Diag(Method->getLocation(), diag::note_method_declared_at) << Method->getDeclName(); } - } - else if (ObjCMethodDecl *CurMeth = SemaRef.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); @@ -2778,16 +2763,15 @@ ExprResult SemaObjC::BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo, // 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 SemaObjC::ActOnClassMessage(Scope *S, - ParsedType Receiver, - Selector Sel, - SourceLocation LBracLoc, - ArrayRef SelectorLocs, - SourceLocation RBracLoc, - MultiExprArg Args) { +ExprResult SemaObjC::ActOnClassMessage(Scope *S, ParsedType Receiver, + Selector Sel, SourceLocation LBracLoc, + ArrayRef SelectorLocs, + SourceLocation RBracLoc, + MultiExprArg Args) { ASTContext &Context = getASTContext(); TypeSourceInfo *ReceiverTypeInfo; - QualType ReceiverType = SemaRef.GetTypeFromParser(Receiver, &ReceiverTypeInfo); + QualType ReceiverType = + SemaRef.GetTypeFromParser(Receiver, &ReceiverTypeInfo); if (ReceiverType.isNull()) return ExprError(); @@ -2800,12 +2784,9 @@ ExprResult SemaObjC::ActOnClassMessage(Scope *S, Args); } -ExprResult SemaObjC::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, @@ -2818,7 +2799,8 @@ static bool isMethodDeclaredInRootProtocol(Sema &S, const ObjCMethodDecl *M) { const auto *Protocol = dyn_cast(M->getDeclContext()); if (!Protocol) return false; - const IdentifierInfo *II = S.ObjC().NSAPIObj->getNSClassId(NSAPI::ClassId_NSObject); + const IdentifierInfo *II = + S.ObjC().NSAPIObj->getNSClassId(NSAPI::ClassId_NSObject); if (const auto *RootClass = dyn_cast_or_null( S.LookupSingleName(S.TUScope, II, Protocol->getBeginLoc(), Sema::LookupOrdinaryName))) { @@ -2858,16 +2840,11 @@ static bool isMethodDeclaredInRootProtocol(Sema &S, const ObjCMethodDecl *M) { /// \param RBracLoc The location of the closing square bracket ']'. /// /// \param ArgsIn The message arguments. -ExprResult SemaObjC::BuildInstanceMessage(Expr *Receiver, - QualType ReceiverType, - SourceLocation SuperLoc, - Selector Sel, - ObjCMethodDecl *Method, - SourceLocation LBracLoc, - ArrayRef SelectorLocs, - SourceLocation RBracLoc, - MultiExprArg ArgsIn, - bool isImplicit) { +ExprResult SemaObjC::BuildInstanceMessage( + Expr *Receiver, QualType ReceiverType, SourceLocation SuperLoc, + Selector Sel, ObjCMethodDecl *Method, SourceLocation LBracLoc, + ArrayRef 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."); @@ -2896,7 +2873,8 @@ ExprResult SemaObjC::BuildInstanceMessage(Expr *Receiver, if (Receiver->hasPlaceholderType()) { ExprResult Result; if (Receiver->getType() == Context.UnknownAnyTy) - Result = SemaRef.forceUnknownAnyToType(Receiver, Context.getObjCIdType()); + Result = + SemaRef.forceUnknownAnyToType(Receiver, Context.getObjCIdType()); else Result = SemaRef.CheckPlaceholderExpr(Receiver); if (Result.isInvalid()) return ExprError(); @@ -2936,24 +2914,28 @@ ExprResult SemaObjC::BuildInstanceMessage(Expr *Receiver, // But not in ARC. Diag(Loc, diag::warn_bad_receiver_type) << ReceiverType << RecRange; if (ReceiverType->isPointerType()) { - Receiver = SemaRef.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 = SemaRef.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 (SemaRef.RequireCompleteType(Loc, Receiver->getType(), - diag::err_incomplete_receiver_type)) + diag::err_incomplete_receiver_type)) return ExprError(); - ExprResult result = SemaRef.PerformContextuallyConvertToObjCPointer(Receiver); + ExprResult result = + SemaRef.PerformContextuallyConvertToObjCPointer(Receiver); if (result.isUsable()) { Receiver = result.get(); ReceiverType = Receiver->getType(); @@ -2982,8 +2964,8 @@ ExprResult SemaObjC::BuildInstanceMessage(Expr *Receiver, // select a better one. Method = Methods[0]; - if (ObjCMethodDecl *BestMethod = - SemaRef.SelectBestMethod(Sel, ArgsIn, Method->isInstanceMethod(), Methods)) + if (ObjCMethodDecl *BestMethod = SemaRef.SelectBestMethod( + Sel, ArgsIn, Method->isInstanceMethod(), Methods)) Method = BestMethod; if (!AreMultipleMethodsInGlobalPool(Sel, Method, @@ -3052,10 +3034,9 @@ ExprResult SemaObjC::BuildInstanceMessage(Expr *Receiver, } } - if (ObjCMethodDecl *BestMethod = - SemaRef.SelectBestMethod(Sel, ArgsIn, Method->isInstanceMethod(), - Methods)) - Method = BestMethod; + if (ObjCMethodDecl *BestMethod = SemaRef.SelectBestMethod( + Sel, ArgsIn, Method->isInstanceMethod(), Methods)) + Method = BestMethod; } } } @@ -3084,11 +3065,12 @@ ExprResult SemaObjC::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 (SemaRef.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(); @@ -3129,9 +3111,8 @@ ExprResult SemaObjC::BuildInstanceMessage(Expr *Receiver, // to select a better one. Method = Methods[0]; - if (ObjCMethodDecl *BestMethod = - SemaRef.SelectBestMethod(Sel, ArgsIn, Method->isInstanceMethod(), - Methods)) + if (ObjCMethodDecl *BestMethod = SemaRef.SelectBestMethod( + Sel, ArgsIn, Method->isInstanceMethod(), Methods)) Method = BestMethod; AreMultipleMethodsInGlobalPool(Sel, Method, @@ -3146,7 +3127,8 @@ ExprResult SemaObjC::BuildInstanceMessage(Expr *Receiver, } } } - if (Method && SemaRef.DiagnoseUseOfDecl(Method, SelectorSlotLocs, forwardClass)) + if (Method && + SemaRef.DiagnoseUseOfDecl(Method, SelectorSlotLocs, forwardClass)) return ExprError(); } else { // Reject other random receiver types (e.g. structs). @@ -3157,8 +3139,9 @@ ExprResult SemaObjC::BuildInstanceMessage(Expr *Receiver, } FunctionScopeInfo *DIFunctionScopeInfo = - (Method && Method->getMethodFamily() == OMF_init) - ? SemaRef.getEnclosingFunction() : nullptr; + (Method && Method->getMethodFamily() == OMF_init) + ? SemaRef.getEnclosingFunction() + : nullptr; if (Method && Method->isDirectMethod()) { if (ReceiverType->isObjCIdType() && !isImplicit) { @@ -3224,7 +3207,8 @@ ExprResult SemaObjC::BuildInstanceMessage(Expr *Receiver, if (!isDesignatedInitChain) { const ObjCMethodDecl *InitMethod = nullptr; bool isDesignated = - SemaRef.getCurMethodDecl()->isDesignatedInitializerForTheInterface(&InitMethod); + SemaRef.getCurMethodDecl()->isDesignatedInitializerForTheInterface( + &InitMethod); assert(isDesignated && InitMethod); (void)isDesignated; Diag(SelLoc, SuperLoc.isValid() ? @@ -3259,8 +3243,9 @@ ExprResult SemaObjC::BuildInstanceMessage(Expr *Receiver, return ExprError(); if (Method && !Method->getReturnType()->isVoidType() && - SemaRef.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 @@ -3409,7 +3394,8 @@ ExprResult SemaObjC::BuildInstanceMessage(Expr *Receiver, if (!IsWeak && Sel.isUnarySelector()) IsWeak = ReturnType.getObjCLifetime() & Qualifiers::OCL_Weak; if (IsWeak && !SemaRef.isUnevaluatedContext() && - !getDiagnostics().isIgnored(diag::warn_arc_repeated_use_of_weak, LBracLoc)) + !getDiagnostics().isIgnored(diag::warn_arc_repeated_use_of_weak, + LBracLoc)) SemaRef.getCurFunction()->recordUseOfWeak(Result, Prop); } } @@ -3420,7 +3406,7 @@ ExprResult SemaObjC::BuildInstanceMessage(Expr *Receiver, return SemaRef.MaybeBindToTemporary(Result); } -static void RemoveSelectorFromWarningCache(SemaObjC &S, Expr* Arg) { +static void RemoveSelectorFromWarningCache(SemaObjC &S, Expr *Arg) { if (ObjCSelectorExpr *OSE = dyn_cast(Arg->IgnoreParenCasts())) { Selector Sel = OSE->getSelector(); @@ -3434,20 +3420,19 @@ static void RemoveSelectorFromWarningCache(SemaObjC &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 SemaObjC::ActOnInstanceMessage(Scope *S, - Expr *Receiver, - Selector Sel, - SourceLocation LBracLoc, - ArrayRef SelectorLocs, - SourceLocation RBracLoc, - MultiExprArg Args) { +ExprResult SemaObjC::ActOnInstanceMessage(Scope *S, Expr *Receiver, + Selector Sel, SourceLocation LBracLoc, + ArrayRef 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(Receiver)) { - ExprResult Result = SemaRef.MaybeConvertParenListExprToParenExpr(S, Receiver); + ExprResult Result = + SemaRef.MaybeConvertParenListExprToParenExpr(S, Receiver); if (Result.isInvalid()) return ExprError(); Receiver = Result.get(); } @@ -4165,45 +4150,43 @@ void SemaObjC::CheckTollFreeBridgeCast(QualType castType, Expr *castExpr) { ARCConversionTypeClass castACTC = classifyTypeForARCConversion(castType); if (castACTC == ACTC_retainable && exprACTC == ACTC_coreFoundation) { bool HasObjCBridgeAttr; - bool ObjCBridgeAttrWillNotWarn = - CheckObjCBridgeNSCast(SemaRef, castType, castExpr, HasObjCBridgeAttr, - false); + bool ObjCBridgeAttrWillNotWarn = CheckObjCBridgeNSCast( + SemaRef, castType, castExpr, HasObjCBridgeAttr, false); if (ObjCBridgeAttrWillNotWarn && HasObjCBridgeAttr) return; bool HasObjCBridgeMutableAttr; bool ObjCBridgeMutableAttrWillNotWarn = - CheckObjCBridgeNSCast(SemaRef, castType, castExpr, - HasObjCBridgeMutableAttr, false); + CheckObjCBridgeNSCast( + SemaRef, castType, castExpr, HasObjCBridgeMutableAttr, false); if (ObjCBridgeMutableAttrWillNotWarn && HasObjCBridgeMutableAttr) return; if (HasObjCBridgeAttr) - CheckObjCBridgeNSCast(SemaRef, castType, castExpr, HasObjCBridgeAttr, - true); + CheckObjCBridgeNSCast(SemaRef, castType, castExpr, + HasObjCBridgeAttr, true); else if (HasObjCBridgeMutableAttr) - CheckObjCBridgeNSCast(SemaRef, castType, castExpr, - HasObjCBridgeMutableAttr, true); + CheckObjCBridgeNSCast( + SemaRef, castType, castExpr, HasObjCBridgeMutableAttr, true); } else if (castACTC == ACTC_coreFoundation && exprACTC == ACTC_retainable) { bool HasObjCBridgeAttr; - bool ObjCBridgeAttrWillNotWarn = - CheckObjCBridgeCFCast(SemaRef, castType, castExpr, HasObjCBridgeAttr, - false); + bool ObjCBridgeAttrWillNotWarn = CheckObjCBridgeCFCast( + SemaRef, castType, castExpr, HasObjCBridgeAttr, false); if (ObjCBridgeAttrWillNotWarn && HasObjCBridgeAttr) return; bool HasObjCBridgeMutableAttr; bool ObjCBridgeMutableAttrWillNotWarn = - CheckObjCBridgeCFCast(SemaRef, castType, castExpr, - HasObjCBridgeMutableAttr, false); + CheckObjCBridgeCFCast( + SemaRef, castType, castExpr, HasObjCBridgeMutableAttr, false); if (ObjCBridgeMutableAttrWillNotWarn && HasObjCBridgeMutableAttr) return; if (HasObjCBridgeAttr) - CheckObjCBridgeCFCast(SemaRef, castType, castExpr, HasObjCBridgeAttr, - true); + CheckObjCBridgeCFCast(SemaRef, castType, castExpr, + HasObjCBridgeAttr, true); else if (HasObjCBridgeMutableAttr) - CheckObjCBridgeCFCast(SemaRef, castType, castExpr, - HasObjCBridgeMutableAttr, true); + CheckObjCBridgeCFCast( + SemaRef, castType, castExpr, HasObjCBridgeMutableAttr, true); } } @@ -4229,7 +4212,7 @@ void SemaObjC::CheckObjCBridgeRelatedCast(QualType castType, Expr *castExpr) { } bool SemaObjC::CheckTollFreeBridgeStaticCast(QualType castType, Expr *castExpr, - CastKind &Kind) { + CastKind &Kind) { if (!getLangOpts().ObjC) return false; ARCConversionTypeClass exprACTC = @@ -4245,13 +4228,11 @@ bool SemaObjC::CheckTollFreeBridgeStaticCast(QualType castType, Expr *castExpr, return false; } -bool SemaObjC::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); @@ -4319,10 +4300,11 @@ bool SemaObjC::checkObjCBridgeRelatedComponents(SourceLocation Loc, return true; } -bool -SemaObjC::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); @@ -4415,9 +4397,9 @@ SemaObjC::CheckObjCBridgeRelatedConversions(SourceLocation Loc, SemaObjC::ARCConversionResult SemaObjC::CheckObjCConversion(SourceRange castRange, QualType castType, - Expr *&castExpr, CheckedConversionKind CCK, - bool Diagnose, bool DiagnoseCFAudited, - BinaryOperatorKind Opc) { + Expr *&castExpr, CheckedConversionKind CCK, + bool Diagnose, bool DiagnoseCFAudited, + BinaryOperatorKind Opc) { ASTContext &Context = getASTContext(); QualType castExprType = castExpr->getType(); @@ -4508,7 +4490,8 @@ SemaObjC::CheckObjCConversion(SourceRange castRange, QualType castType, // 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) && SemaRef.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 @@ -4527,8 +4510,8 @@ SemaObjC::CheckObjCConversion(SourceRange castRange, QualType castType, !(exprACTC == ACTC_voidPtr && castACTC == ACTC_retainable && (Opc == BO_NE || Opc == BO_EQ))) { if (Diagnose) - diagnoseObjCARCConversion(SemaRef, castRange, castType, castACTC, castExpr, - castExpr, exprACTC, CCK); + diagnoseObjCARCConversion(SemaRef, castRange, castType, castACTC, + castExpr, castExpr, exprACTC, CCK); return ACR_error; } return ACR_okay; @@ -4563,8 +4546,8 @@ void SemaObjC::diagnoseARCUnbridgedCast(Expr *e) { Expr *castExpr = realCast->getSubExpr(); assert(classifyTypeForARCConversion(castExpr->getType()) == ACTC_retainable); - diagnoseObjCARCConversion(SemaRef, castRange, castType, castACTC, - castExpr, realCast, ACTC_retainable, CCK); + diagnoseObjCARCConversion(SemaRef, castRange, castType, castACTC, castExpr, + realCast, ACTC_retainable, CCK); } /// stripARCUnbridgedCast - Given an expression of ARCUnbridgedCast @@ -4611,7 +4594,7 @@ Expr *SemaObjC::stripARCUnbridgedCast(Expr *e) { } bool SemaObjC::CheckObjCARCUnavailableWeakConversion(QualType castType, - QualType exprType) { + QualType exprType) { ASTContext &Context = getASTContext(); QualType canCastType = Context.getCanonicalType(castType).getUnqualifiedType(); @@ -4666,10 +4649,10 @@ static Expr *maybeUndoReclaimObject(Expr *e) { } ExprResult SemaObjC::BuildObjCBridgedCast(SourceLocation LParenLoc, - ObjCBridgeCastKind Kind, - SourceLocation BridgeKeywordLoc, - TypeSourceInfo *TSInfo, - Expr *SubExpr) { + ObjCBridgeCastKind Kind, + SourceLocation BridgeKeywordLoc, + TypeSourceInfo *TSInfo, + Expr *SubExpr) { ASTContext &Context = getASTContext(); ExprResult SubResult = SemaRef.UsualUnaryConversions(SubExpr); if (SubResult.isInvalid()) return ExprError(); @@ -4777,13 +4760,12 @@ ExprResult SemaObjC::BuildObjCBridgedCast(SourceLocation LParenLoc, return Result; } -ExprResult SemaObjC::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 = SemaRef.GetTypeFromParser(Type, &TSInfo); @@ -4796,7 +4778,7 @@ ExprResult SemaObjC::ActOnObjCBridgedCast(Scope *S, } DeclResult SemaObjC::LookupIvarInObjCMethod(LookupResult &Lookup, Scope *S, - IdentifierInfo *II) { + IdentifierInfo *II) { SourceLocation Loc = Lookup.getNameLoc(); ObjCMethodDecl *CurMethod = SemaRef.getCurMethodDecl(); @@ -4868,9 +4850,9 @@ DeclResult SemaObjC::LookupIvarInObjCMethod(LookupResult &Lookup, Scope *S, return DeclResult(false); } -ExprResult -SemaObjC::LookupInObjCMethod(LookupResult &Lookup, Scope *S, - IdentifierInfo *II, bool AllowBuiltinCreation) { +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()) @@ -4887,7 +4869,7 @@ SemaObjC::LookupInObjCMethod(LookupResult &Lookup, Scope *S, } ExprResult SemaObjC::BuildIvarRefExpr(Scope *S, SourceLocation Loc, - ObjCIvarDecl *IV) { + ObjCIvarDecl *IV) { ASTContext &Context = getASTContext(); ObjCMethodDecl *CurMethod = SemaRef.getCurMethodDecl(); assert(CurMethod && CurMethod->isInstanceMethod() && @@ -4914,8 +4896,8 @@ ExprResult SemaObjC::BuildIvarRefExpr(Scope *S, SourceLocation Loc, SourceLocation TemplateKWLoc; ExprResult SelfExpr = SemaRef.ActOnIdExpression(S, SelfScopeSpec, TemplateKWLoc, SelfName, - /*HasTrailingLParen=*/false, - /*IsAddressOfOperand=*/false); + /*HasTrailingLParen=*/false, + /*IsAddressOfOperand=*/false); if (SelfExpr.isInvalid()) return ExprError(); @@ -4946,8 +4928,9 @@ ExprResult SemaObjC::BuildIvarRefExpr(Scope *S, SourceLocation Loc, return Result; } -QualType SemaObjC::FindCompositeObjCPointerType(ExprResult &LHS, ExprResult &RHS, - SourceLocation QuestionLoc) { +QualType SemaObjC::FindCompositeObjCPointerType(ExprResult &LHS, + ExprResult &RHS, + SourceLocation QuestionLoc) { ASTContext &Context = getASTContext(); QualType LHSTy = LHS.get()->getType(); QualType RHSTy = RHS.get()->getType(); @@ -4957,23 +4940,27 @@ QualType SemaObjC::FindCompositeObjCPointerType(ExprResult &LHS, ExprResult &RHS // 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); + 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); + 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); + 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); + LHS = SemaRef.ImpCastExprToType(LHS.get(), RHSTy, + CK_CPointerToObjCPointerCast); return RHSTy; } // And the same for struct objc_selector* / SEL @@ -4994,8 +4981,10 @@ QualType SemaObjC::FindCompositeObjCPointerType(ExprResult &LHS, ExprResult &RHS // Two identical object pointer types are always compatible. return LHSTy; } - const ObjCObjectPointerType *LHSOPT = LHSTy->castAs(); - const ObjCObjectPointerType *RHSOPT = RHSTy->castAs(); + const ObjCObjectPointerType *LHSOPT = + LHSTy->castAs(); + const ObjCObjectPointerType *RHSOPT = + RHSTy->castAs(); QualType compositeType = LHSTy; // If both operands are interfaces and either operand can be @@ -5011,8 +5000,8 @@ QualType SemaObjC::FindCompositeObjCPointerType(ExprResult &LHS, ExprResult &RHS // FIXME: Consider unifying with 'areComparableObjCPointerTypes'. // It could return the composite type. - if (!(compositeType = - Context.areCommonBaseCompatible(LHSOPT, RHSOPT)).isNull()) { + if (!(compositeType = Context.areCommonBaseCompatible(LHSOPT, RHSOPT)) + .isNull()) { // Nothing more to do. } else if (Context.canAssignObjCInterfaces(LHSOPT, RHSOPT)) { compositeType = RHSOPT->isObjCBuiltinType() ? RHSTy : LHSTy; @@ -5031,8 +5020,8 @@ QualType SemaObjC::FindCompositeObjCPointerType(ExprResult &LHS, ExprResult &RHS compositeType = Context.getObjCIdType(); } else { Diag(QuestionLoc, diag::ext_typecheck_cond_incompatible_operands) - << LHSTy << RHSTy - << LHS.get()->getSourceRange() << RHS.get()->getSourceRange(); + << 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); @@ -5048,15 +5037,16 @@ QualType SemaObjC::FindCompositeObjCPointerType(ExprResult &LHS, ExprResult &RHS 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(); + Diag(QuestionLoc, diag::err_cond_voidptr_arc) + << LHSTy << RHSTy << LHS.get()->getSourceRange() + << RHS.get()->getSourceRange(); LHS = RHS = true; return QualType(); } QualType lhptee = LHSTy->castAs()->getPointeeType(); QualType rhptee = RHSTy->castAs()->getPointeeType(); - QualType destPointee - = Context.getQualifiedType(lhptee, rhptee.getQualifiers()); + QualType destPointee = + Context.getQualifiedType(lhptee, rhptee.getQualifiers()); QualType destType = Context.getPointerType(destPointee); // Add qualifiers if necessary. LHS = SemaRef.ImpCastExprToType(LHS.get(), destType, CK_NoOp); @@ -5068,15 +5058,16 @@ QualType SemaObjC::FindCompositeObjCPointerType(ExprResult &LHS, ExprResult &RHS 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(); + Diag(QuestionLoc, diag::err_cond_voidptr_arc) + << LHSTy << RHSTy << LHS.get()->getSourceRange() + << RHS.get()->getSourceRange(); LHS = RHS = true; return QualType(); } QualType lhptee = LHSTy->castAs()->getPointeeType(); QualType rhptee = RHSTy->castAs()->getPointeeType(); - QualType destPointee - = Context.getQualifiedType(rhptee, lhptee.getQualifiers()); + QualType destPointee = + Context.getQualifiedType(rhptee, lhptee.getQualifiers()); QualType destType = Context.getPointerType(destPointee); // Add qualifiers if necessary. RHS = SemaRef.ImpCastExprToType(RHS.get(), destType, CK_NoOp); @@ -5088,7 +5079,7 @@ QualType SemaObjC::FindCompositeObjCPointerType(ExprResult &LHS, ExprResult &RHS } bool SemaObjC::CheckConversionToObjCLiteral(QualType DstType, Expr *&Exp, - bool Diagnose) { + bool Diagnose) { if (!getLangOpts().ObjC) return false; @@ -5106,30 +5097,29 @@ bool SemaObjC::CheckConversionToObjCLiteral(QualType DstType, Expr *&Exp, SrcExpr = OV->getSourceExpr()->IgnoreParenImpCasts(); if (auto *SL = dyn_cast(SrcExpr)) { - if (!PT->isObjCIdType() && - !(ID && ID->getIdentifier()->isStr("NSString"))) + 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(), "@"); + << /*string*/ 0 << FixItHint::CreateInsertion(SL->getBeginLoc(), "@"); Exp = BuildObjCStringLiteral(SL->getBeginLoc(), SL).get(); } return true; } if ((isa(SrcExpr) || isa(SrcExpr) || - isa(SrcExpr) || isa(SrcExpr) || - isa(SrcExpr)) && - !SrcExpr->isNullPointerConstant( - getASTContext(), Expr::NPC_NeverValueDependent)) { + isa(SrcExpr) || isa(SrcExpr) || + isa(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 + << /*number*/ 1 << FixItHint::CreateInsertion(SrcExpr->getBeginLoc(), "@"); Expr *NumLit = BuildObjCNumericLiteral(SrcExpr->getBeginLoc(), SrcExpr).get(); @@ -5143,8 +5133,8 @@ bool SemaObjC::CheckConversionToObjCLiteral(QualType DstType, Expr *&Exp, } /// ActOnObjCBoolLiteral - Parse {__objc_yes,__objc_no} literals. -ExprResult -SemaObjC::ActOnObjCBoolLiteral(SourceLocation OpLoc, tok::TokenKind Kind) { +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(); @@ -5152,7 +5142,8 @@ SemaObjC::ActOnObjCBoolLiteral(SourceLocation OpLoc, tok::TokenKind Kind) { if (!Context.getBOOLDecl()) { LookupResult Result(SemaRef, &Context.Idents.get("BOOL"), OpLoc, Sema::LookupOrdinaryName); - if (SemaRef.LookupName(Result, SemaRef.getCurScope()) && Result.isSingleResult()) { + if (SemaRef.LookupName(Result, SemaRef.getCurScope()) && + Result.isSingleResult()) { NamedDecl *ND = Result.getFoundDecl(); if (TypedefDecl *TD = dyn_cast(ND)) Context.setBOOLDecl(TD); @@ -5217,41 +5208,41 @@ CastKind SemaObjC::PrepareCastToObjCObjectPointer(ExprResult &E) { 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(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(Inner)->getCastKind(); + // Boolean literals can be represented by implicit casts. + if (CK == CK_IntegralToBoolean || CK == CK_IntegralCast) + return LK_Numeric; + break; + } 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(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(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_Boxed; + } } return LK_None; } diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index 4050c34036e66..a20f5ac651857 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -6020,7 +6020,7 @@ static bool tryObjCWritebackConversion(Sema &S, // Handle write-back conversion. QualType ConvertedArgType; if (!S.ObjC().isObjCWritebackConversion(ArgType, Entity.getType(), - ConvertedArgType)) + ConvertedArgType)) return false; // We should copy unless we're passing to an argument explicitly @@ -6212,9 +6212,9 @@ void InitializationSequence::InitializeFrom(Sema &S, if (Args.size() == 1) { Initializer = Args[0]; if (S.getLangOpts().ObjC) { - if (S.ObjC().CheckObjCBridgeRelatedConversions(Initializer->getBeginLoc(), - DestType, Initializer->getType(), - Initializer) || + if (S.ObjC().CheckObjCBridgeRelatedConversions( + Initializer->getBeginLoc(), DestType, Initializer->getType(), + Initializer) || S.ObjC().CheckConversionToObjCLiteral(DestType, Initializer)) Args[0] = Initializer; } diff --git a/clang/lib/Sema/SemaObjC.cpp b/clang/lib/Sema/SemaObjC.cpp index 4322f985be1ba..1e6cc21a48704 100644 --- a/clang/lib/Sema/SemaObjC.cpp +++ b/clang/lib/Sema/SemaObjC.cpp @@ -22,28 +22,28 @@ namespace clang { -SemaObjC::SemaObjC(Sema &S) : SemaBase(S), NSNumberDecl(nullptr), NSValueDecl(nullptr), NSStringDecl(nullptr), - StringWithUTF8StringMethod(nullptr), +SemaObjC::SemaObjC(Sema &S) + : SemaBase(S), NSNumberDecl(nullptr), NSValueDecl(nullptr), + NSStringDecl(nullptr), StringWithUTF8StringMethod(nullptr), ValueWithBytesObjCTypeMethod(nullptr), NSArrayDecl(nullptr), ArrayWithObjectsMethod(nullptr), NSDictionaryDecl(nullptr), DictionaryWithObjectsMethod(nullptr) {} -StmtResult -SemaObjC::ActOnObjCForCollectionStmt(SourceLocation ForLoc, - Stmt *First, Expr *collection, - SourceLocation RParenLoc) { +StmtResult SemaObjC::ActOnObjCForCollectionStmt(SourceLocation ForLoc, + Stmt *First, Expr *collection, + SourceLocation RParenLoc) { ASTContext &Context = getASTContext(); SemaRef.setFunctionHasBranchProtectedScope(); ExprResult CollectionExprResult = - CheckObjCForCollectionOperand(ForLoc, collection); + CheckObjCForCollectionOperand(ForLoc, collection); if (First) { QualType FirstType; if (DeclStmt *DS = dyn_cast(First)) { if (!DS->isSingleDecl()) return StmtError(Diag((*DS->decl_begin())->getLocation(), - diag::err_toomany_element_decls)); + diag::err_toomany_element_decls)); VarDecl *D = dyn_cast(DS->getSingleDecl()); if (!D || D->isInvalidDecl()) @@ -54,8 +54,8 @@ SemaObjC::ActOnObjCForCollectionStmt(SourceLocation ForLoc, // declare identifiers for objects having storage class 'auto' or // 'register'. if (!D->hasLocalStorage()) - return StmtError(Diag(D->getLocation(), - diag::err_non_local_variable_decl_in_for)); + return StmtError( + Diag(D->getLocation(), diag::err_non_local_variable_decl_in_for)); // If the type contained 'auto', deduce the 'auto' to 'id'. if (FirstType->getContainedAutoType()) { @@ -79,8 +79,7 @@ SemaObjC::ActOnObjCForCollectionStmt(SourceLocation ForLoc, if (!SemaRef.inTemplateInstantiation()) { SourceLocation Loc = D->getTypeSourceInfo()->getTypeLoc().getBeginLoc(); - Diag(Loc, diag::warn_auto_var_is_id) - << D->getDeclName(); + Diag(Loc, diag::warn_auto_var_is_id) << D->getDeclName(); } } @@ -91,23 +90,23 @@ SemaObjC::ActOnObjCForCollectionStmt(SourceLocation ForLoc, Diag(First->getBeginLoc(), diag::err_selector_element_not_lvalue) << First->getSourceRange()); - FirstType = static_cast(First)->getType(); + FirstType = static_cast(First)->getType(); if (FirstType.isConstQualified()) Diag(ForLoc, diag::err_selector_element_const_type) - << FirstType << First->getSourceRange(); + << FirstType << First->getSourceRange(); } if (!FirstType->isDependentType() && !FirstType->isObjCObjectPointerType() && !FirstType->isBlockPointerType()) - return StmtError(Diag(ForLoc, diag::err_selector_element_type) - << FirstType << First->getSourceRange()); + return StmtError(Diag(ForLoc, diag::err_selector_element_type) + << FirstType << First->getSourceRange()); } if (CollectionExprResult.isInvalid()) return StmtError(); - CollectionExprResult = - SemaRef.ActOnFinishFullExpr(CollectionExprResult.get(), /*DiscardedValue*/ false); + CollectionExprResult = SemaRef.ActOnFinishFullExpr(CollectionExprResult.get(), + /*DiscardedValue*/ false); if (CollectionExprResult.isInvalid()) return StmtError(); @@ -115,8 +114,8 @@ SemaObjC::ActOnObjCForCollectionStmt(SourceLocation ForLoc, nullptr, ForLoc, RParenLoc); } -ExprResult -SemaObjC::CheckObjCForCollectionOperand(SourceLocation forLoc, Expr *collection) { +ExprResult SemaObjC::CheckObjCForCollectionOperand(SourceLocation forLoc, + Expr *collection) { ASTContext &Context = getASTContext(); if (!collection) return ExprError(); @@ -127,7 +126,8 @@ SemaObjC::CheckObjCForCollectionOperand(SourceLocation forLoc, Expr *collection) collection = result.get(); // Bail out early if we've got a type-dependent expression. - if (collection->isTypeDependent()) return collection; + if (collection->isTypeDependent()) + return collection; // Perform normal l-value conversion. result = SemaRef.DefaultFunctionArrayLvalueConversion(collection); @@ -138,10 +138,10 @@ SemaObjC::CheckObjCForCollectionOperand(SourceLocation forLoc, Expr *collection) // The operand needs to have object-pointer type. // TODO: should we do a contextual conversion? const ObjCObjectPointerType *pointerType = - collection->getType()->getAs(); + collection->getType()->getAs(); if (!pointerType) return Diag(forLoc, diag::err_collection_expr_type) - << collection->getType() << collection->getSourceRange(); + << collection->getType() << collection->getSourceRange(); // Check that the operand provides // - countByEnumeratingWithState:objects:count: @@ -153,7 +153,8 @@ SemaObjC::CheckObjCForCollectionOperand(SourceLocation forLoc, Expr *collection) if (iface && (getLangOpts().ObjCAutoRefCount ? SemaRef.RequireCompleteType(forLoc, QualType(objectType, 0), - diag::err_arc_collection_forward, collection) + diag::err_arc_collection_forward, + collection) : !SemaRef.isCompleteType(forLoc, QualType(objectType, 0)))) { // Otherwise, if we have any useful type information, check that // the type declares the appropriate method. @@ -168,7 +169,8 @@ SemaObjC::CheckObjCForCollectionOperand(SourceLocation forLoc, Expr *collection) // If there's an interface, look in both the public and private APIs. if (iface) { method = iface->lookupInstanceMethod(selector); - if (!method) method = iface->lookupPrivateMethod(selector); + if (!method) + method = iface->lookupPrivateMethod(selector); } // Also check protocol qualifiers. @@ -179,7 +181,7 @@ SemaObjC::CheckObjCForCollectionOperand(SourceLocation forLoc, Expr *collection) // If we didn't find it anywhere, give up. if (!method) { Diag(forLoc, diag::warn_collection_expr_type) - << collection->getType() << selector << collection->getSourceRange(); + << collection->getType() << selector << collection->getSourceRange(); } // TODO: check for an incompatible signature? @@ -192,16 +194,15 @@ SemaObjC::CheckObjCForCollectionOperand(SourceLocation forLoc, Expr *collection) StmtResult SemaObjC::FinishObjCForCollectionStmt(Stmt *S, Stmt *B) { if (!S || !B) return StmtError(); - ObjCForCollectionStmt * ForStmt = cast(S); + ObjCForCollectionStmt *ForStmt = cast(S); ForStmt->setBody(B); return S; } -StmtResult -SemaObjC::ActOnObjCAtCatchStmt(SourceLocation AtLoc, - SourceLocation RParen, Decl *Parm, - Stmt *Body) { +StmtResult SemaObjC::ActOnObjCAtCatchStmt(SourceLocation AtLoc, + SourceLocation RParen, Decl *Parm, + Stmt *Body) { ASTContext &Context = getASTContext(); VarDecl *Var = cast_or_null(Parm); if (Var && Var->isInvalidDecl()) @@ -210,15 +211,14 @@ SemaObjC::ActOnObjCAtCatchStmt(SourceLocation AtLoc, return new (Context) ObjCAtCatchStmt(AtLoc, RParen, Var, Body); } -StmtResult -SemaObjC::ActOnObjCAtFinallyStmt(SourceLocation AtLoc, Stmt *Body) { +StmtResult SemaObjC::ActOnObjCAtFinallyStmt(SourceLocation AtLoc, Stmt *Body) { ASTContext &Context = getASTContext(); return new (Context) ObjCAtFinallyStmt(AtLoc, Body); } -StmtResult -SemaObjC::ActOnObjCAtTryStmt(SourceLocation AtLoc, Stmt *Try, - MultiStmtArg CatchStmts, Stmt *Finally) { +StmtResult SemaObjC::ActOnObjCAtTryStmt(SourceLocation AtLoc, Stmt *Try, + MultiStmtArg CatchStmts, + Stmt *Finally) { ASTContext &Context = getASTContext(); if (!getLangOpts().ObjCExceptions) Diag(AtLoc, diag::err_objc_exceptions_disabled) << "@try"; @@ -243,7 +243,8 @@ StmtResult SemaObjC::BuildObjCAtThrowStmt(SourceLocation AtLoc, Expr *Throw) { if (Result.isInvalid()) return StmtError(); - Result = SemaRef.ActOnFinishFullExpr(Result.get(), /*DiscardedValue*/ false); + Result = + SemaRef.ActOnFinishFullExpr(Result.get(), /*DiscardedValue*/ false); if (Result.isInvalid()) return StmtError(); Throw = Result.get(); @@ -262,9 +263,8 @@ StmtResult SemaObjC::BuildObjCAtThrowStmt(SourceLocation AtLoc, Expr *Throw) { return new (Context) ObjCAtThrowStmt(AtLoc, Throw); } -StmtResult -SemaObjC::ActOnObjCAtThrowStmt(SourceLocation AtLoc, Expr *Throw, - Scope *CurScope) { +StmtResult SemaObjC::ActOnObjCAtThrowStmt(SourceLocation AtLoc, Expr *Throw, + Scope *CurScope) { if (!getLangOpts().ObjCExceptions) Diag(AtLoc, diag::err_objc_exceptions_disabled) << "@throw"; @@ -280,8 +280,8 @@ SemaObjC::ActOnObjCAtThrowStmt(SourceLocation AtLoc, Expr *Throw, return BuildObjCAtThrowStmt(AtLoc, Throw); } -ExprResult -SemaObjC::ActOnObjCAtSynchronizedOperand(SourceLocation atLoc, Expr *operand) { +ExprResult SemaObjC::ActOnObjCAtSynchronizedOperand(SourceLocation atLoc, + Expr *operand) { ExprResult result = SemaRef.DefaultLvalueConversion(operand); if (result.isInvalid()) return ExprError(); @@ -289,27 +289,27 @@ SemaObjC::ActOnObjCAtSynchronizedOperand(SourceLocation atLoc, Expr *operand) { // Make sure the expression type is an ObjC pointer or "void *". QualType type = operand->getType(); - if (!type->isDependentType() && - !type->isObjCObjectPointerType()) { + if (!type->isDependentType() && !type->isObjCObjectPointerType()) { const PointerType *pointerType = type->getAs(); if (!pointerType || !pointerType->getPointeeType()->isVoidType()) { if (getLangOpts().CPlusPlus) { if (SemaRef.RequireCompleteType(atLoc, type, - diag::err_incomplete_receiver_type)) + diag::err_incomplete_receiver_type)) return Diag(atLoc, diag::err_objc_synchronized_expects_object) - << type << operand->getSourceRange(); + << type << operand->getSourceRange(); - ExprResult result = SemaRef.PerformContextuallyConvertToObjCPointer(operand); + ExprResult result = + SemaRef.PerformContextuallyConvertToObjCPointer(operand); if (result.isInvalid()) return ExprError(); if (!result.isUsable()) return Diag(atLoc, diag::err_objc_synchronized_expects_object) - << type << operand->getSourceRange(); + << type << operand->getSourceRange(); operand = result.get(); } else { - return Diag(atLoc, diag::err_objc_synchronized_expects_object) - << type << operand->getSourceRange(); + return Diag(atLoc, diag::err_objc_synchronized_expects_object) + << type << operand->getSourceRange(); } } } @@ -318,27 +318,25 @@ SemaObjC::ActOnObjCAtSynchronizedOperand(SourceLocation atLoc, Expr *operand) { return SemaRef.ActOnFinishFullExpr(operand, /*DiscardedValue*/ false); } -StmtResult -SemaObjC::ActOnObjCAtSynchronizedStmt(SourceLocation AtLoc, Expr *SyncExpr, - Stmt *SyncBody) { +StmtResult SemaObjC::ActOnObjCAtSynchronizedStmt(SourceLocation AtLoc, + Expr *SyncExpr, + Stmt *SyncBody) { ASTContext &Context = getASTContext(); // We can't jump into or indirect-jump out of a @synchronized block. SemaRef.setFunctionHasBranchProtectedScope(); return new (Context) ObjCAtSynchronizedStmt(AtLoc, SyncExpr, SyncBody); } -StmtResult -SemaObjC::ActOnObjCAutoreleasePoolStmt(SourceLocation AtLoc, Stmt *Body) { +StmtResult SemaObjC::ActOnObjCAutoreleasePoolStmt(SourceLocation AtLoc, + Stmt *Body) { ASTContext &Context = getASTContext(); SemaRef.setFunctionHasBranchProtectedScope(); return new (Context) ObjCAutoreleasePoolStmt(AtLoc, Body); } TypeResult SemaObjC::actOnObjCProtocolQualifierType( - SourceLocation lAngleLoc, - ArrayRef protocols, - ArrayRef protocolLocs, - SourceLocation rAngleLoc) { + SourceLocation lAngleLoc, ArrayRef protocols, + ArrayRef protocolLocs, SourceLocation rAngleLoc) { ASTContext &Context = getASTContext(); // Form id. QualType Result = Context.getObjCObjectType( @@ -354,8 +352,8 @@ TypeResult SemaObjC::actOnObjCProtocolQualifierType( auto ObjCObjectPointerTL = ResultTL.castAs(); ObjCObjectPointerTL.setStarLoc(SourceLocation()); // implicit - auto ObjCObjectTL = ObjCObjectPointerTL.getPointeeLoc() - .castAs(); + auto ObjCObjectTL = + ObjCObjectPointerTL.getPointeeLoc().castAs(); ObjCObjectTL.setHasBaseTypeAsWritten(false); ObjCObjectTL.getBaseLoc().initialize(Context, SourceLocation()); @@ -374,16 +372,11 @@ TypeResult SemaObjC::actOnObjCProtocolQualifierType( } TypeResult SemaObjC::actOnObjCTypeArgsAndProtocolQualifiers( - Scope *S, - SourceLocation Loc, - ParsedType BaseType, - SourceLocation TypeArgsLAngleLoc, - ArrayRef TypeArgs, - SourceLocation TypeArgsRAngleLoc, - SourceLocation ProtocolLAngleLoc, - ArrayRef Protocols, - ArrayRef ProtocolLocs, - SourceLocation ProtocolRAngleLoc) { + Scope *S, SourceLocation Loc, ParsedType BaseType, + SourceLocation TypeArgsLAngleLoc, ArrayRef TypeArgs, + SourceLocation TypeArgsRAngleLoc, SourceLocation ProtocolLAngleLoc, + ArrayRef Protocols, ArrayRef ProtocolLocs, + SourceLocation ProtocolRAngleLoc) { ASTContext &Context = getASTContext(); TypeSourceInfo *BaseTypeInfo = nullptr; QualType T = SemaRef.GetTypeFromParser(BaseType, &BaseTypeInfo); @@ -485,22 +478,21 @@ TypeResult SemaObjC::actOnObjCTypeArgsAndProtocolQualifiers( return SemaRef.CreateParsedType(Result, ResultTInfo); } -QualType SemaObjC::BuildObjCTypeParamType(const ObjCTypeParamDecl *Decl, - SourceLocation ProtocolLAngleLoc, - ArrayRef Protocols, - ArrayRef ProtocolLocs, - SourceLocation ProtocolRAngleLoc, - bool FailOnError) { +QualType SemaObjC::BuildObjCTypeParamType( + const ObjCTypeParamDecl *Decl, SourceLocation ProtocolLAngleLoc, + ArrayRef Protocols, + ArrayRef ProtocolLocs, SourceLocation ProtocolRAngleLoc, + bool FailOnError) { ASTContext &Context = getASTContext(); QualType Result = QualType(Decl->getTypeForDecl(), 0); if (!Protocols.empty()) { bool HasError; - Result = Context.applyObjCProtocolQualifiers(Result, Protocols, - HasError); + Result = Context.applyObjCProtocolQualifiers(Result, Protocols, HasError); if (HasError) { Diag(SourceLocation(), diag::err_invalid_protocol_qualifiers) - << SourceRange(ProtocolLAngleLoc, ProtocolRAngleLoc); - if (FailOnError) Result = QualType(); + << SourceRange(ProtocolLAngleLoc, ProtocolRAngleLoc); + if (FailOnError) + Result = QualType(); } if (FailOnError && Result.isNull()) return QualType(); @@ -517,9 +509,7 @@ static QualType applyObjCTypeArgs(Sema &S, SourceLocation loc, QualType type, // We can only apply type arguments to an Objective-C class type. const auto *objcObjectType = type->getAs(); if (!objcObjectType || !objcObjectType->getInterface()) { - S.Diag(loc, diag::err_objc_type_args_non_class) - << type - << typeArgsRange; + S.Diag(loc, diag::err_objc_type_args_non_class) << type << typeArgsRange; if (failOnError) return QualType(); @@ -531,8 +521,7 @@ static QualType applyObjCTypeArgs(Sema &S, SourceLocation loc, QualType type, ObjCTypeParamList *typeParams = objcClass->getTypeParamList(); if (!typeParams) { S.Diag(loc, diag::err_objc_type_args_non_parameterized_class) - << objcClass->getDeclName() - << FixItHint::CreateRemoval(typeArgsRange); + << objcClass->getDeclName() << FixItHint::CreateRemoval(typeArgsRange); if (failOnError) return QualType(); @@ -543,8 +532,7 @@ static QualType applyObjCTypeArgs(Sema &S, SourceLocation loc, QualType type, // The type must not already be specialized. if (objcObjectType->isSpecialized()) { S.Diag(loc, diag::err_objc_type_args_specialized_class) - << type - << FixItHint::CreateRemoval(typeArgsRange); + << type << FixItHint::CreateRemoval(typeArgsRange); if (failOnError) return QualType(); @@ -602,12 +590,9 @@ static QualType applyObjCTypeArgs(Sema &S, SourceLocation loc, QualType type, } else { // Too many arguments. S.Diag(loc, diag::err_objc_type_args_wrong_arity) - << false - << objcClass->getDeclName() - << (unsigned)typeArgs.size() - << numTypeParams; - S.Diag(objcClass->getLocation(), diag::note_previous_decl) - << objcClass; + << false << objcClass->getDeclName() << (unsigned)typeArgs.size() + << numTypeParams; + S.Diag(objcClass->getLocation(), diag::note_previous_decl) << objcClass; if (failOnError) return QualType(); @@ -646,7 +631,7 @@ static QualType applyObjCTypeArgs(Sema &S, SourceLocation loc, QualType type, diag::err_objc_type_arg_does_not_match_bound) << typeArg << bound << typeParam->getDeclName(); S.Diag(typeParam->getLocation(), diag::note_objc_type_param_here) - << typeParam->getDeclName(); + << typeParam->getDeclName(); if (failOnError) return QualType(); @@ -674,7 +659,7 @@ static QualType applyObjCTypeArgs(Sema &S, SourceLocation loc, QualType type, diag::err_objc_type_arg_does_not_match_bound) << typeArg << bound << typeParam->getDeclName(); S.Diag(typeParam->getLocation(), diag::note_objc_type_param_here) - << typeParam->getDeclName(); + << typeParam->getDeclName(); if (failOnError) return QualType(); @@ -706,12 +691,9 @@ static QualType applyObjCTypeArgs(Sema &S, SourceLocation loc, QualType type, // Make sure we didn't have the wrong number of arguments. if (!anyPackExpansions && finalTypeArgs.size() != numTypeParams) { S.Diag(loc, diag::err_objc_type_args_wrong_arity) - << (typeArgs.size() < typeParams->size()) - << objcClass->getDeclName() - << (unsigned)finalTypeArgs.size() - << (unsigned)numTypeParams; - S.Diag(objcClass->getLocation(), diag::note_previous_decl) - << objcClass; + << (typeArgs.size() < typeParams->size()) << objcClass->getDeclName() + << (unsigned)finalTypeArgs.size() << (unsigned)numTypeParams; + S.Diag(objcClass->getLocation(), diag::note_previous_decl) << objcClass; if (failOnError) return QualType(); @@ -720,7 +702,7 @@ static QualType applyObjCTypeArgs(Sema &S, SourceLocation loc, QualType type, } // Success. Form the specialized type. - return S.Context.getObjCObjectType(type, finalTypeArgs, { }, false); + return S.Context.getObjCObjectType(type, finalTypeArgs, {}, false); } QualType SemaObjC::BuildObjCObjectType( @@ -742,12 +724,12 @@ QualType SemaObjC::BuildObjCObjectType( if (!Protocols.empty()) { bool HasError; - Result = Context.applyObjCProtocolQualifiers(Result, Protocols, - HasError); + Result = Context.applyObjCProtocolQualifiers(Result, Protocols, HasError); if (HasError) { Diag(Loc, diag::err_invalid_protocol_qualifiers) - << SourceRange(ProtocolLAngleLoc, ProtocolRAngleLoc); - if (FailOnError) Result = QualType(); + << SourceRange(ProtocolLAngleLoc, ProtocolRAngleLoc); + if (FailOnError) + Result = QualType(); } if (FailOnError && Result.isNull()) return QualType(); @@ -824,19 +806,22 @@ static bool findRetainCycleOwner(Sema &S, Expr *e, RetainCycleOwner &owner) { if (!findRetainCycleOwner(S, ref->getBase(), owner)) return false; - if (ref->isFreeIvar()) owner.setLocsFrom(ref); + if (ref->isFreeIvar()) + owner.setLocsFrom(ref); owner.Indirect = true; return true; } if (DeclRefExpr *ref = dyn_cast(e)) { VarDecl *var = dyn_cast(ref->getDecl()); - if (!var) return false; + if (!var) + return false; return considerVariable(var, ref, owner); } if (MemberExpr *member = dyn_cast(e)) { - if (member->isArrow()) return false; + if (member->isArrow()) + return false; // Don't count this as an indirect ownership. e = member->getBase(); @@ -845,17 +830,18 @@ static bool findRetainCycleOwner(Sema &S, Expr *e, RetainCycleOwner &owner) { if (PseudoObjectExpr *pseudo = dyn_cast(e)) { // Only pay attention to pseudo-objects on property references. - ObjCPropertyRefExpr *pre - = dyn_cast(pseudo->getSyntacticForm() - ->IgnoreParens()); - if (!pre) return false; - if (pre->isImplicitProperty()) return false; + ObjCPropertyRefExpr *pre = dyn_cast( + pseudo->getSyntacticForm()->IgnoreParens()); + if (!pre) + return false; + if (pre->isImplicitProperty()) + return false; ObjCPropertyDecl *property = pre->getExplicitProperty(); if (!property->isRetaining() && !(property->getPropertyIvarDecl() && - property->getPropertyIvarDecl()->getType() - .getObjCLifetime() == Qualifiers::OCL_Strong)) - return false; + property->getPropertyIvarDecl()->getType().getObjCLifetime() == + Qualifiers::OCL_Strong)) + return false; owner.Indirect = true; if (pre->isSuperReceiver()) { @@ -866,8 +852,8 @@ static bool findRetainCycleOwner(Sema &S, Expr *e, RetainCycleOwner &owner) { owner.Range = pre->getSourceRange(); return true; } - e = const_cast(cast(pre->getBase()) - ->getSourceExpr()); + e = const_cast( + cast(pre->getBase())->getSourceExpr()); continue; } @@ -879,56 +865,57 @@ static bool findRetainCycleOwner(Sema &S, Expr *e, RetainCycleOwner &owner) { namespace { - struct FindCaptureVisitor : EvaluatedExprVisitor { - VarDecl *Variable; - Expr *Capturer = nullptr; - bool VarWillBeReased = false; +struct FindCaptureVisitor : EvaluatedExprVisitor { + VarDecl *Variable; + Expr *Capturer = nullptr; + bool VarWillBeReased = false; - FindCaptureVisitor(ASTContext &Context, VarDecl *variable) - : EvaluatedExprVisitor(Context), - Variable(variable) {} + FindCaptureVisitor(ASTContext &Context, VarDecl *variable) + : EvaluatedExprVisitor(Context), Variable(variable) {} - void VisitDeclRefExpr(DeclRefExpr *ref) { - if (ref->getDecl() == Variable && !Capturer) - Capturer = ref; - } + void VisitDeclRefExpr(DeclRefExpr *ref) { + if (ref->getDecl() == Variable && !Capturer) + Capturer = ref; + } - void VisitObjCIvarRefExpr(ObjCIvarRefExpr *ref) { - if (Capturer) return; - Visit(ref->getBase()); - if (Capturer && ref->isFreeIvar()) - Capturer = ref; - } + void VisitObjCIvarRefExpr(ObjCIvarRefExpr *ref) { + if (Capturer) + return; + Visit(ref->getBase()); + if (Capturer && ref->isFreeIvar()) + Capturer = ref; + } - void VisitBlockExpr(BlockExpr *block) { - // Look inside nested blocks - if (block->getBlockDecl()->capturesVariable(Variable)) - Visit(block->getBlockDecl()->getBody()); - } + void VisitBlockExpr(BlockExpr *block) { + // Look inside nested blocks + if (block->getBlockDecl()->capturesVariable(Variable)) + Visit(block->getBlockDecl()->getBody()); + } - void VisitOpaqueValueExpr(OpaqueValueExpr *OVE) { - if (Capturer) return; - if (OVE->getSourceExpr()) - Visit(OVE->getSourceExpr()); - } + void VisitOpaqueValueExpr(OpaqueValueExpr *OVE) { + if (Capturer) + return; + if (OVE->getSourceExpr()) + Visit(OVE->getSourceExpr()); + } - void VisitBinaryOperator(BinaryOperator *BinOp) { - if (!Variable || VarWillBeReased || BinOp->getOpcode() != BO_Assign) + void VisitBinaryOperator(BinaryOperator *BinOp) { + if (!Variable || VarWillBeReased || BinOp->getOpcode() != BO_Assign) + return; + Expr *LHS = BinOp->getLHS(); + if (const DeclRefExpr *DRE = dyn_cast_or_null(LHS)) { + if (DRE->getDecl() != Variable) return; - Expr *LHS = BinOp->getLHS(); - if (const DeclRefExpr *DRE = dyn_cast_or_null(LHS)) { - if (DRE->getDecl() != Variable) - return; - if (Expr *RHS = BinOp->getRHS()) { - RHS = RHS->IgnoreParenCasts(); - std::optional Value; - VarWillBeReased = - (RHS && (Value = RHS->getIntegerConstantExpr(Context)) && - *Value == 0); - } + if (Expr *RHS = BinOp->getRHS()) { + RHS = RHS->IgnoreParenCasts(); + std::optional Value; + VarWillBeReased = + (RHS && (Value = RHS->getIntegerConstantExpr(Context)) && + *Value == 0); } } - }; + } +}; } // namespace @@ -975,15 +962,16 @@ static void diagnoseRetainCycle(Sema &S, Expr *capturer, assert(owner.Variable && owner.Loc.isValid()); S.Diag(capturer->getExprLoc(), diag::warn_arc_retain_cycle) - << owner.Variable << capturer->getSourceRange(); + << owner.Variable << capturer->getSourceRange(); S.Diag(owner.Loc, diag::note_arc_retain_cycle_owner) - << owner.Indirect << owner.Range; + << owner.Indirect << owner.Range; } /// Check for a keyword selector that starts with the word 'add' or /// 'set'. static bool isSetterLikeSelector(Selector sel) { - if (sel.isUnarySelector()) return false; + if (sel.isUnarySelector()) + return false; StringRef str = sel.getNameForSlot(0); str = str.ltrim('_'); @@ -997,15 +985,15 @@ static bool isSetterLikeSelector(Selector sel) { } else return false; - if (str.empty()) return true; + if (str.empty()) + return true; return !isLowercase(str.front()); } static std::optional GetNSMutableArrayArgumentIndex(SemaObjC &S, ObjCMessageExpr *Message) { bool IsMutableArray = S.NSAPIObj->isSubclassOfNSClass( - Message->getReceiverInterface(), - NSAPI::ClassId_NSMutableArray); + Message->getReceiverInterface(), NSAPI::ClassId_NSMutableArray); if (!IsMutableArray) { return std::nullopt; } @@ -1021,15 +1009,15 @@ GetNSMutableArrayArgumentIndex(SemaObjC &S, ObjCMessageExpr *Message) { NSAPI::NSArrayMethodKind MK = *MKOpt; switch (MK) { - case NSAPI::NSMutableArr_addObject: - case NSAPI::NSMutableArr_insertObjectAtIndex: - case NSAPI::NSMutableArr_setObjectAtIndexedSubscript: - return 0; - case NSAPI::NSMutableArr_replaceObjectAtIndex: - return 1; - - default: - return std::nullopt; + case NSAPI::NSMutableArr_addObject: + case NSAPI::NSMutableArr_insertObjectAtIndex: + case NSAPI::NSMutableArr_setObjectAtIndexedSubscript: + return 0; + case NSAPI::NSMutableArr_replaceObjectAtIndex: + return 1; + + default: + return std::nullopt; } return std::nullopt; @@ -1038,8 +1026,7 @@ GetNSMutableArrayArgumentIndex(SemaObjC &S, ObjCMessageExpr *Message) { static std::optional GetNSMutableDictionaryArgumentIndex(SemaObjC &S, ObjCMessageExpr *Message) { bool IsMutableDictionary = S.NSAPIObj->isSubclassOfNSClass( - Message->getReceiverInterface(), - NSAPI::ClassId_NSMutableDictionary); + Message->getReceiverInterface(), NSAPI::ClassId_NSMutableDictionary); if (!IsMutableDictionary) { return std::nullopt; } @@ -1055,13 +1042,13 @@ GetNSMutableDictionaryArgumentIndex(SemaObjC &S, ObjCMessageExpr *Message) { NSAPI::NSDictionaryMethodKind MK = *MKOpt; switch (MK) { - case NSAPI::NSMutableDict_setObjectForKey: - case NSAPI::NSMutableDict_setValueForKey: - case NSAPI::NSMutableDict_setObjectForKeyedSubscript: - return 0; + case NSAPI::NSMutableDict_setObjectForKey: + case NSAPI::NSMutableDict_setValueForKey: + case NSAPI::NSMutableDict_setObjectForKeyedSubscript: + return 0; - default: - return std::nullopt; + default: + return std::nullopt; } return std::nullopt; @@ -1070,12 +1057,10 @@ GetNSMutableDictionaryArgumentIndex(SemaObjC &S, ObjCMessageExpr *Message) { static std::optional GetNSSetArgumentIndex(SemaObjC &S, ObjCMessageExpr *Message) { bool IsMutableSet = S.NSAPIObj->isSubclassOfNSClass( - Message->getReceiverInterface(), - NSAPI::ClassId_NSMutableSet); + Message->getReceiverInterface(), NSAPI::ClassId_NSMutableSet); bool IsMutableOrderedSet = S.NSAPIObj->isSubclassOfNSClass( - Message->getReceiverInterface(), - NSAPI::ClassId_NSMutableOrderedSet); + Message->getReceiverInterface(), NSAPI::ClassId_NSMutableOrderedSet); if (!IsMutableSet && !IsMutableOrderedSet) { return std::nullopt; } @@ -1091,13 +1076,13 @@ static std::optional GetNSSetArgumentIndex(SemaObjC &S, NSAPI::NSSetMethodKind MK = *MKOpt; switch (MK) { - case NSAPI::NSMutableSet_addObject: - case NSAPI::NSOrderedSet_setObjectAtIndex: - case NSAPI::NSOrderedSet_setObjectAtIndexedSubscript: - case NSAPI::NSOrderedSet_insertObjectAtIndex: - return 0; - case NSAPI::NSOrderedSet_replaceObjectAtIndexWithObject: - return 1; + case NSAPI::NSMutableSet_addObject: + case NSAPI::NSOrderedSet_setObjectAtIndex: + case NSAPI::NSOrderedSet_setObjectAtIndexedSubscript: + case NSAPI::NSOrderedSet_insertObjectAtIndex: + return 0; + case NSAPI::NSOrderedSet_replaceObjectAtIndexWithObject: + return 1; } return std::nullopt; @@ -1128,7 +1113,7 @@ void SemaObjC::CheckObjCCircularContainer(ObjCMessageExpr *Message) { if (ArgRE->isObjCSelfExpr()) { Diag(Message->getSourceRange().getBegin(), diag::warn_objc_circular_container) - << ArgRE->getDecl() << StringRef("'super'"); + << ArgRE->getDecl() << StringRef("'super'"); } } } else { @@ -1144,11 +1129,11 @@ void SemaObjC::CheckObjCCircularContainer(ObjCMessageExpr *Message) { ValueDecl *Decl = ReceiverRE->getDecl(); Diag(Message->getSourceRange().getBegin(), diag::warn_objc_circular_container) - << Decl << Decl; + << Decl << Decl; if (!ArgRE->isObjCSelfExpr()) { Diag(Decl->getLocation(), diag::note_objc_circular_container_declared_here) - << Decl; + << Decl; } } } @@ -1158,10 +1143,10 @@ void SemaObjC::CheckObjCCircularContainer(ObjCMessageExpr *Message) { ObjCIvarDecl *Decl = IvarRE->getDecl(); Diag(Message->getSourceRange().getBegin(), diag::warn_objc_circular_container) - << Decl << Decl; + << Decl << Decl; Diag(Decl->getLocation(), diag::note_objc_circular_container_declared_here) - << Decl; + << Decl; } } } @@ -1255,13 +1240,13 @@ bool SemaObjC::CheckObjCString(Expr *Arg) { } bool SemaObjC::CheckObjCMethodCall(ObjCMethodDecl *Method, SourceLocation lbrac, - ArrayRef Args) { + ArrayRef Args) { Sema::VariadicCallType CallType = Method->isVariadic() ? Sema::VariadicMethod : Sema::VariadicDoesNotApply; SemaRef.checkCall(Method, nullptr, /*ThisArg=*/nullptr, Args, - /*IsMemberFunction=*/false, lbrac, Method->getSourceRange(), - CallType); + /*IsMemberFunction=*/false, lbrac, Method->getSourceRange(), + CallType); SemaRef.CheckTCBEnforcement(lbrac, Method); @@ -1285,7 +1270,8 @@ IdentifierInfo *SemaObjC::getNSErrorIdent() { } void SemaObjC::ActOnObjCContainerStartDefinition(ObjCContainerDecl *IDecl) { - assert(IDecl->getLexicalParent() == SemaRef.CurContext && + assert( + IDecl->getLexicalParent() == SemaRef.CurContext && "The next DeclContext should be lexically contained in the current one."); SemaRef.CurContext = IDecl; } @@ -1295,7 +1281,8 @@ void SemaObjC::ActOnObjCContainerFinishDefinition() { SemaRef.PopDeclContext(); } -void SemaObjC::ActOnObjCTemporaryExitContainerContext(ObjCContainerDecl *ObjCCtx) { +void SemaObjC::ActOnObjCTemporaryExitContainerContext( + ObjCContainerDecl *ObjCCtx) { assert(ObjCCtx == SemaRef.CurContext && "Mismatch of container contexts"); SemaRef.OriginalLexicalContext = ObjCCtx; ActOnObjCContainerFinishDefinition(); @@ -1308,10 +1295,10 @@ void SemaObjC::ActOnObjCReenterContainerContext(ObjCContainerDecl *ObjCCtx) { /// Find the protocol with the given name, if any. ObjCProtocolDecl *SemaObjC::LookupProtocol(IdentifierInfo *II, - SourceLocation IdLoc, - RedeclarationKind Redecl) { + SourceLocation IdLoc, + RedeclarationKind Redecl) { Decl *D = SemaRef.LookupSingleName(SemaRef.TUScope, II, IdLoc, - Sema::LookupObjCProtocolName, Redecl); + Sema::LookupObjCProtocolName, Redecl); return cast_or_null(D); } @@ -1325,7 +1312,7 @@ ObjCProtocolDecl *SemaObjC::LookupProtocol(IdentifierInfo *II, /// \param ConvertedType The type that will be produced after applying /// this conversion. bool SemaObjC::isObjCWritebackConversion(QualType FromType, QualType ToType, - QualType &ConvertedType) { + QualType &ConvertedType) { ASTContext &Context = getASTContext(); if (!getLangOpts().ObjCAutoRefCount || Context.hasSameUnqualifiedType(FromType, ToType)) @@ -1373,7 +1360,7 @@ bool SemaObjC::isObjCWritebackConversion(QualType FromType, QualType ToType, if (Context.typesAreCompatible(FromPointee, ToPointee)) FromPointee = ToPointee; else if (!SemaRef.isObjCPointerConversion(FromPointee, ToPointee, FromPointee, - IncompatibleObjC)) + IncompatibleObjC)) return false; /// Construct the type we're converting to, which is a pointer to @@ -1394,32 +1381,30 @@ SemaObjC::ObjCSubscriptKind SemaObjC::CheckSubscriptingKind(Expr *FromE) { // If we don't have a class type in C++, there's no way we can get an // expression of integral or enumeration type. const RecordType *RecordTy = T->getAs(); - if (!RecordTy && - (T->isObjCObjectPointerType() || T->isVoidPointerType())) + if (!RecordTy && (T->isObjCObjectPointerType() || T->isVoidPointerType())) // All other scalar cases are assumed to be dictionary indexing which // caller handles, with diagnostics if needed. return SemaObjC::OS_Dictionary; - if (!getLangOpts().CPlusPlus || - !RecordTy || RecordTy->isIncompleteType()) { + if (!getLangOpts().CPlusPlus || !RecordTy || RecordTy->isIncompleteType()) { // No indexing can be done. Issue diagnostics and quit. const Expr *IndexExpr = FromE->IgnoreParenImpCasts(); if (isa(IndexExpr)) Diag(FromE->getExprLoc(), diag::err_objc_subscript_pointer) - << T << FixItHint::CreateInsertion(FromE->getExprLoc(), "@"); + << T << FixItHint::CreateInsertion(FromE->getExprLoc(), "@"); else - Diag(FromE->getExprLoc(), diag::err_objc_subscript_type_conversion) - << T; + Diag(FromE->getExprLoc(), diag::err_objc_subscript_type_conversion) << T; return SemaObjC::OS_Error; } // We must have a complete class type. if (SemaRef.RequireCompleteType(FromE->getExprLoc(), T, - diag::err_objc_index_incomplete_class_type, FromE)) + diag::err_objc_index_incomplete_class_type, + FromE)) return SemaObjC::OS_Error; // Look for a conversion to an integral, enumeration type, or // objective-C pointer type. - int NoIntegrals=0, NoObjCIdPointers=0; + int NoIntegrals = 0, NoObjCIdPointers = 0; SmallVector ConversionDecls; for (NamedDecl *D : cast(RecordTy->getDecl()) @@ -1430,21 +1415,20 @@ SemaObjC::ObjCSubscriptKind SemaObjC::CheckSubscriptingKind(Expr *FromE) { if (CT->isIntegralOrEnumerationType()) { ++NoIntegrals; ConversionDecls.push_back(Conversion); - } - else if (CT->isObjCIdType() ||CT->isBlockPointerType()) { + } else if (CT->isObjCIdType() || CT->isBlockPointerType()) { ++NoObjCIdPointers; ConversionDecls.push_back(Conversion); } } } - if (NoIntegrals ==1 && NoObjCIdPointers == 0) + if (NoIntegrals == 1 && NoObjCIdPointers == 0) return SemaObjC::OS_Array; if (NoIntegrals == 0 && NoObjCIdPointers == 1) return SemaObjC::OS_Dictionary; if (NoIntegrals == 0 && NoObjCIdPointers == 0) { // No conversion function was found. Issue diagnostic and return. Diag(FromE->getExprLoc(), diag::err_objc_subscript_type_conversion) - << FromE->getType(); + << FromE->getType(); return SemaObjC::OS_Error; } Diag(FromE->getExprLoc(), diag::err_objc_multiple_subscript_type_conversion) @@ -1461,7 +1445,8 @@ void SemaObjC::AddCFAuditedAttribute(Decl *D) { IdentifierInfo *Ident; SourceLocation Loc; std::tie(Ident, Loc) = SemaRef.PP.getPragmaARCCFCodeAuditedInfo(); - if (!Loc.isValid()) return; + if (!Loc.isValid()) + return; // Don't add a redundant or conflicting attribute. if (D->hasAttr() || diff --git a/clang/lib/Sema/SemaObjCProperty.cpp b/clang/lib/Sema/SemaObjCProperty.cpp index c0ae904dfb9fe..031f2a6af8774 100644 --- a/clang/lib/Sema/SemaObjCProperty.cpp +++ b/clang/lib/Sema/SemaObjCProperty.cpp @@ -11,7 +11,6 @@ // //===----------------------------------------------------------------------===// -#include "clang/Sema/SemaObjC.h" #include "clang/AST/ASTMutationListener.h" #include "clang/AST/DeclObjC.h" #include "clang/AST/ExprCXX.h" @@ -21,6 +20,7 @@ #include "clang/Lex/Preprocessor.h" #include "clang/Sema/Initialization.h" #include "clang/Sema/SemaInternal.h" +#include "clang/Sema/SemaObjC.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/SmallString.h" @@ -115,7 +115,8 @@ CheckPropertyAgainstProtocol(Sema &S, ObjCPropertyDecl *Prop, // Look for a property with the same name. if (ObjCPropertyDecl *ProtoProp = Proto->getProperty( Prop->getIdentifier(), Prop->isInstanceProperty())) { - S.ObjC().DiagnosePropertyMismatch(Prop, ProtoProp, Proto->getIdentifier(), true); + S.ObjC().DiagnosePropertyMismatch(Prop, ProtoProp, Proto->getIdentifier(), + true); return; } @@ -171,13 +172,11 @@ static unsigned getOwnershipRule(unsigned attr) { } Decl *SemaObjC::ActOnProperty(Scope *S, SourceLocation AtLoc, - SourceLocation LParenLoc, - FieldDeclarator &FD, - ObjCDeclSpec &ODS, - Selector GetterSel, - Selector SetterSel, - tok::ObjCKeywordKind MethodImplKind, - DeclContext *lexicalDC) { + SourceLocation LParenLoc, FieldDeclarator &FD, + ObjCDeclSpec &ODS, Selector GetterSel, + Selector SetterSel, + tok::ObjCKeywordKind MethodImplKind, + DeclContext *lexicalDC) { unsigned Attributes = ODS.getPropertyAttributes(); FD.D.setObjCWeakProperty((Attributes & ObjCPropertyAttribute::kind_weak) != 0); @@ -402,21 +401,12 @@ static void checkAtomicPropertyMismatch(Sema &S, S.Diag(OldProperty->getLocation(), diag::note_property_declare); } -ObjCPropertyDecl * -SemaObjC::HandlePropertyInClassExtension(Scope *S, - SourceLocation AtLoc, - SourceLocation LParenLoc, - FieldDeclarator &FD, - Selector GetterSel, - SourceLocation GetterNameLoc, - Selector SetterSel, - SourceLocation SetterNameLoc, - const bool isReadWrite, - unsigned &Attributes, - const unsigned AttributesAsWritten, - QualType T, - TypeSourceInfo *TSI, - tok::ObjCKeywordKind MethodImplKind) { +ObjCPropertyDecl *SemaObjC::HandlePropertyInClassExtension( + Scope *S, SourceLocation AtLoc, SourceLocation LParenLoc, + FieldDeclarator &FD, Selector GetterSel, SourceLocation GetterNameLoc, + Selector SetterSel, SourceLocation SetterNameLoc, const bool isReadWrite, + unsigned &Attributes, const unsigned AttributesAsWritten, QualType T, + TypeSourceInfo *TSI, tok::ObjCKeywordKind MethodImplKind) { ObjCCategoryDecl *CDecl = cast(SemaRef.CurContext); // Diagnose if this property is already in continuation class. DeclContext *DC = SemaRef.CurContext; @@ -537,9 +527,10 @@ SemaObjC::HandlePropertyInClassExtension(Scope *S, QualType ClassExtPropertyT = Context.getCanonicalType(PDecl->getType()); if (!isa(PrimaryClassPropertyT) || !isa(ClassExtPropertyT) || - (!SemaRef.isObjCPointerConversion(ClassExtPropertyT, PrimaryClassPropertyT, - ConvertedType, IncompatibleObjC)) - || IncompatibleObjC) { + (!SemaRef.isObjCPointerConversion(ClassExtPropertyT, + PrimaryClassPropertyT, ConvertedType, + IncompatibleObjC)) || + IncompatibleObjC) { Diag(AtLoc, diag::err_type_mismatch_continuation_class) << PDecl->getType(); Diag(PIDecl->getLocation(), diag::note_property_declare); @@ -556,22 +547,14 @@ SemaObjC::HandlePropertyInClassExtension(Scope *S, return PDecl; } -ObjCPropertyDecl *SemaObjC::CreatePropertyDecl(Scope *S, - ObjCContainerDecl *CDecl, - SourceLocation AtLoc, - SourceLocation LParenLoc, - FieldDeclarator &FD, - Selector GetterSel, - SourceLocation GetterNameLoc, - Selector SetterSel, - SourceLocation SetterNameLoc, - const bool isReadWrite, - const unsigned Attributes, - const unsigned AttributesAsWritten, - QualType T, - TypeSourceInfo *TInfo, - tok::ObjCKeywordKind MethodImplKind, - DeclContext *lexicalDC){ +ObjCPropertyDecl *SemaObjC::CreatePropertyDecl( + Scope *S, ObjCContainerDecl *CDecl, SourceLocation AtLoc, + SourceLocation LParenLoc, FieldDeclarator &FD, Selector GetterSel, + SourceLocation GetterNameLoc, Selector SetterSel, + SourceLocation SetterNameLoc, const bool isReadWrite, + const unsigned Attributes, const unsigned AttributesAsWritten, QualType T, + TypeSourceInfo *TInfo, tok::ObjCKeywordKind MethodImplKind, + DeclContext *lexicalDC) { ASTContext &Context = getASTContext(); const IdentifierInfo *PropertyId = FD.D.getIdentifier(); @@ -1076,17 +1059,13 @@ RedeclarePropertyAccessor(ASTContext &Context, ObjCImplementationDecl *Impl, /// builds the AST node for a property implementation declaration; declared /// as \@synthesize or \@dynamic. /// -Decl *SemaObjC::ActOnPropertyImplDecl(Scope *S, - SourceLocation AtLoc, - SourceLocation PropertyLoc, - bool Synthesize, - IdentifierInfo *PropertyId, - IdentifierInfo *PropertyIvar, - SourceLocation PropertyIvarLoc, - ObjCPropertyQueryKind QueryKind) { +Decl *SemaObjC::ActOnPropertyImplDecl( + Scope *S, SourceLocation AtLoc, SourceLocation PropertyLoc, bool Synthesize, + IdentifierInfo *PropertyId, IdentifierInfo *PropertyIvar, + SourceLocation PropertyIvarLoc, ObjCPropertyQueryKind QueryKind) { ASTContext &Context = getASTContext(); ObjCContainerDecl *ClassImpDecl = - dyn_cast(SemaRef.CurContext); + dyn_cast(SemaRef.CurContext); // Make sure we have a context for the property implementation declaration. if (!ClassImpDecl) { Diag(AtLoc, diag::err_missing_property_context); @@ -1216,8 +1195,8 @@ Decl *SemaObjC::ActOnPropertyImplDecl(Scope *S, QualType PropertyIvarType = PropType.getNonReferenceType(); if (SemaRef.RequireCompleteType(PropertyDiagLoc, PropertyIvarType, - diag::err_incomplete_synthesized_property, - property->getDeclName())) { + diag::err_incomplete_synthesized_property, + property->getDeclName())) { Diag(property->getLocation(), diag::note_property_declare); CompleteTypeErr = true; } @@ -1323,10 +1302,9 @@ Decl *SemaObjC::ActOnPropertyImplDecl(Scope *S, PropertyIvarType, /*TInfo=*/nullptr, ObjCIvarDecl::Private, (Expr *)nullptr, true); - if (SemaRef.RequireNonAbstractType(PropertyIvarLoc, - PropertyIvarType, - diag::err_abstract_type_in_decl, - Sema::AbstractSynthesizedIvarType)) { + if (SemaRef.RequireNonAbstractType(PropertyIvarLoc, PropertyIvarType, + diag::err_abstract_type_in_decl, + Sema::AbstractSynthesizedIvarType)) { Diag(property->getLocation(), diag::note_property_declare); // An abstract type is as bad as an incomplete type. CompleteTypeErr = true; @@ -1370,9 +1348,9 @@ Decl *SemaObjC::ActOnPropertyImplDecl(Scope *S, PropertyIvarType->castAs(), IvarType->castAs()); else { - compat = (SemaRef.CheckAssignmentConstraints(PropertyIvarLoc, PropertyIvarType, - IvarType) - == Sema::Compatible); + compat = (SemaRef.CheckAssignmentConstraints( + PropertyIvarLoc, PropertyIvarType, IvarType) == + Sema::Compatible); } if (!compat) { Diag(PropertyDiagLoc, diag::err_property_ivar_type) @@ -1422,13 +1400,11 @@ Decl *SemaObjC::ActOnPropertyImplDecl(Scope *S, Diag(PropertyDiagLoc, diag::err_dynamic_property_ivar_decl); assert (property && "ActOnPropertyImplDecl - property declaration missing"); - ObjCPropertyImplDecl *PIDecl = - ObjCPropertyImplDecl::Create(Context, SemaRef.CurContext, AtLoc, PropertyLoc, - property, - (Synthesize ? - ObjCPropertyImplDecl::Synthesize - : ObjCPropertyImplDecl::Dynamic), - Ivar, PropertyIvarLoc); + ObjCPropertyImplDecl *PIDecl = ObjCPropertyImplDecl::Create( + Context, SemaRef.CurContext, AtLoc, PropertyLoc, property, + (Synthesize ? ObjCPropertyImplDecl::Synthesize + : ObjCPropertyImplDecl::Dynamic), + Ivar, PropertyIvarLoc); if (CompleteTypeErr || !compat) PIDecl->setInvalidDecl(); @@ -1535,8 +1511,8 @@ Decl *SemaObjC::ActOnPropertyImplDecl(Scope *S, DeclRefExpr *rhs = new (Context) DeclRefExpr(Context, Param, false, T, VK_LValue, PropertyDiagLoc); SemaRef.MarkDeclRefReferenced(rhs); - ExprResult Res = SemaRef.BuildBinOp(S, PropertyDiagLoc, - BO_Assign, lhs, rhs); + ExprResult Res = + SemaRef.BuildBinOp(S, PropertyDiagLoc, BO_Assign, lhs, rhs); if (property->getPropertyAttributes() & ObjCPropertyAttribute::kind_atomic) { Expr *callExpr = Res.getAs(); @@ -1633,11 +1609,10 @@ Decl *SemaObjC::ActOnPropertyImplDecl(Scope *S, /// DiagnosePropertyMismatch - Compares two properties for their /// attributes and types and warns on a variety of inconsistencies. /// -void -SemaObjC::DiagnosePropertyMismatch(ObjCPropertyDecl *Property, - ObjCPropertyDecl *SuperProperty, - const IdentifierInfo *inheritedName, - bool OverridingProtocolProperty) { +void SemaObjC::DiagnosePropertyMismatch(ObjCPropertyDecl *Property, + ObjCPropertyDecl *SuperProperty, + const IdentifierInfo *inheritedName, + bool OverridingProtocolProperty) { ASTContext &Context = getASTContext(); ObjCPropertyAttribute::Kind CAttr = Property->getPropertyAttributes(); ObjCPropertyAttribute::Kind SAttr = SuperProperty->getPropertyAttributes(); @@ -1699,19 +1674,19 @@ SemaObjC::DiagnosePropertyMismatch(ObjCPropertyDecl *Property, // FIXME. For future support of covariant property types, revisit this. bool IncompatibleObjC = false; QualType ConvertedType; - if (!SemaRef.isObjCPointerConversion(RHSType, LHSType, - ConvertedType, IncompatibleObjC) || + if (!SemaRef.isObjCPointerConversion(RHSType, LHSType, ConvertedType, + IncompatibleObjC) || IncompatibleObjC) { - Diag(Property->getLocation(), diag::warn_property_types_are_incompatible) - << Property->getType() << SuperProperty->getType() << inheritedName; + Diag(Property->getLocation(), diag::warn_property_types_are_incompatible) + << Property->getType() << SuperProperty->getType() << inheritedName; Diag(SuperProperty->getLocation(), diag::note_property_declare); } } } bool SemaObjC::DiagnosePropertyAccessorMismatch(ObjCPropertyDecl *property, - ObjCMethodDecl *GetterMethod, - SourceLocation Loc) { + ObjCMethodDecl *GetterMethod, + SourceLocation Loc) { ASTContext &Context = getASTContext(); if (!GetterMethod) return false; @@ -1726,13 +1701,13 @@ bool SemaObjC::DiagnosePropertyAccessorMismatch(ObjCPropertyDecl *property, PropertyRValueType->getAs()) && (getterObjCPtr = GetterType->getAs())) compat = Context.canAssignObjCInterfaces(getterObjCPtr, propertyObjCPtr); - else if (SemaRef.CheckAssignmentConstraints(Loc, GetterType, PropertyRValueType) - != Sema::Compatible) { - Diag(Loc, diag::err_property_accessor_type) - << property->getDeclName() << PropertyRValueType - << GetterMethod->getSelector() << GetterType; - Diag(GetterMethod->getLocation(), diag::note_declared_at); - return true; + else if (SemaRef.CheckAssignmentConstraints( + Loc, GetterType, PropertyRValueType) != Sema::Compatible) { + Diag(Loc, diag::err_property_accessor_type) + << property->getDeclName() << PropertyRValueType + << GetterMethod->getSelector() << GetterType; + Diag(GetterMethod->getLocation(), diag::note_declared_at); + return true; } else { compat = true; QualType lhsType = Context.getCanonicalType(PropertyRValueType); @@ -1836,9 +1811,9 @@ static void CollectSuperClassPropertyImplementations(ObjCInterfaceDecl *CDecl, /// IvarBacksCurrentMethodAccessor - This routine returns 'true' if 'IV' is /// an ivar synthesized for 'Method' and 'Method' is a property accessor /// declared in class 'IFace'. -bool -SemaObjC::IvarBacksCurrentMethodAccessor(ObjCInterfaceDecl *IFace, - ObjCMethodDecl *Method, ObjCIvarDecl *IV) { +bool SemaObjC::IvarBacksCurrentMethodAccessor(ObjCInterfaceDecl *IFace, + ObjCMethodDecl *Method, + ObjCIvarDecl *IV) { if (!IV->getSynthesize()) return false; ObjCMethodDecl *IMD = IFace->lookupMethod(Method->getSelector(), @@ -1889,8 +1864,8 @@ static bool SuperClassImplementsProperty(ObjCInterfaceDecl *IDecl, /// Default synthesizes all properties which must be synthesized /// in class's \@implementation. void SemaObjC::DefaultSynthesizeProperties(Scope *S, ObjCImplDecl *IMPDecl, - ObjCInterfaceDecl *IDecl, - SourceLocation AtEnd) { + ObjCInterfaceDecl *IDecl, + SourceLocation AtEnd) { ASTContext &Context = getASTContext(); ObjCInterfaceDecl::PropertyMap PropMap; IDecl->collectPropertiesToImplement(PropMap); @@ -1984,8 +1959,9 @@ void SemaObjC::DefaultSynthesizeProperties(Scope *S, ObjCImplDecl *IMPDecl, } void SemaObjC::DefaultSynthesizeProperties(Scope *S, Decl *D, - SourceLocation AtEnd) { - if (!getLangOpts().ObjCDefaultSynthProperties || getLangOpts().ObjCRuntime.isFragile()) + SourceLocation AtEnd) { + if (!getLangOpts().ObjCDefaultSynthProperties || + getLangOpts().ObjCRuntime.isFragile()) return; ObjCImplementationDecl *IC=dyn_cast_or_null(D); if (!IC) @@ -2032,9 +2008,9 @@ static void DiagnoseUnimplementedAccessor( } } -void SemaObjC::DiagnoseUnimplementedProperties(Scope *S, ObjCImplDecl* IMPDecl, - ObjCContainerDecl *CDecl, - bool SynthesizeProperties) { +void SemaObjC::DiagnoseUnimplementedProperties(Scope *S, ObjCImplDecl *IMPDecl, + ObjCContainerDecl *CDecl, + bool SynthesizeProperties) { ObjCContainerDecl::PropertyMap PropMap; ObjCInterfaceDecl *IDecl = dyn_cast(CDecl); @@ -2130,16 +2106,17 @@ void SemaObjC::DiagnoseUnimplementedProperties(Scope *S, ObjCImplDecl* IMPDecl, continue; // Diagnose unimplemented getters and setters. - DiagnoseUnimplementedAccessor(SemaRef, - PrimaryClass, Prop->getGetterName(), IMPDecl, CDecl, C, Prop, InsMap); + DiagnoseUnimplementedAccessor(SemaRef, PrimaryClass, Prop->getGetterName(), + IMPDecl, CDecl, C, Prop, InsMap); if (!Prop->isReadOnly()) - DiagnoseUnimplementedAccessor(SemaRef, - PrimaryClass, Prop->getSetterName(), - IMPDecl, CDecl, C, Prop, InsMap); + DiagnoseUnimplementedAccessor(SemaRef, PrimaryClass, + Prop->getSetterName(), IMPDecl, CDecl, C, + Prop, InsMap); } } -void SemaObjC::diagnoseNullResettableSynthesizedSetters(const ObjCImplDecl *impDecl) { +void SemaObjC::diagnoseNullResettableSynthesizedSetters( + const ObjCImplDecl *impDecl) { for (const auto *propertyImpl : impDecl->property_impls()) { const auto *property = propertyImpl->getPropertyDecl(); // Warn about null_resettable properties with synthesized setters, @@ -2164,9 +2141,8 @@ void SemaObjC::diagnoseNullResettableSynthesizedSetters(const ObjCImplDecl *impD } } -void -SemaObjC::AtomicPropertySetterGetterRules (ObjCImplDecl* IMPDecl, - ObjCInterfaceDecl* IDecl) { +void SemaObjC::AtomicPropertySetterGetterRules(ObjCImplDecl *IMPDecl, + ObjCInterfaceDecl *IDecl) { // Rules apply in non-GC mode only if (getLangOpts().getGC() != LangOptions::NonGC) return; @@ -2238,7 +2214,7 @@ SemaObjC::AtomicPropertySetterGetterRules (ObjCImplDecl* IMPDecl, !(AttributesAsWritten & ObjCPropertyAttribute::kind_atomic)) { // @property () ... case. SourceLocation AfterLParen = - SemaRef.getLocForEndOfToken(Property->getLParenLoc()); + SemaRef.getLocForEndOfToken(Property->getLParenLoc()); StringRef NonatomicStr = AttributesAsWritten? "nonatomic, " : "nonatomic"; Diag(Property->getLocation(), @@ -2259,7 +2235,8 @@ SemaObjC::AtomicPropertySetterGetterRules (ObjCImplDecl* IMPDecl, } } -void SemaObjC::DiagnoseOwningPropertyGetterSynthesis(const ObjCImplementationDecl *D) { +void SemaObjC::DiagnoseOwningPropertyGetterSynthesis( + const ObjCImplementationDecl *D) { if (getLangOpts().getGC() == LangOptions::GCOnly) return; @@ -2319,8 +2296,7 @@ void SemaObjC::DiagnoseOwningPropertyGetterSynthesis(const ObjCImplementationDec } void SemaObjC::DiagnoseMissingDesignatedInitOverrides( - const ObjCImplementationDecl *ImplD, - const ObjCInterfaceDecl *IFD) { + const ObjCImplementationDecl *ImplD, const ObjCInterfaceDecl *IFD) { assert(IFD->hasDesignatedInitializers()); const ObjCInterfaceDecl *SuperD = IFD->getSuperClass(); if (!SuperD) @@ -2640,10 +2616,9 @@ void SemaObjC::ProcessPropertyDecl(ObjCPropertyDecl *property) { CheckObjCMethodOverrides(SetterMethod, CurrentClass, SemaObjC::RTC_Unknown); } -void SemaObjC::CheckObjCPropertyAttributes(Decl *PDecl, - SourceLocation Loc, - unsigned &Attributes, - bool propertyInPrimaryClass) { +void SemaObjC::CheckObjCPropertyAttributes(Decl *PDecl, SourceLocation Loc, + unsigned &Attributes, + bool propertyInPrimaryClass) { // FIXME: Improve the reported location. if (!PDecl || PDecl->isInvalidDecl()) return; diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index d77f5235eacb8..fac9693e459cb 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -1775,7 +1775,7 @@ ExprResult Sema::PerformImplicitConversion(Expr *From, QualType ToType, (Action == AA_Passing || Action == AA_Sending); if (getLangOpts().ObjC) ObjC().CheckObjCBridgeRelatedConversions(From->getBeginLoc(), ToType, - From->getType(), From); + From->getType(), From); ImplicitConversionSequence ICS = ::TryImplicitConversion( *this, From, ToType, /*SuppressUserConversions=*/false, diff --git a/clang/lib/Sema/SemaPseudoObject.cpp b/clang/lib/Sema/SemaPseudoObject.cpp index 8195e708b79dc..14ed9590afc6c 100644 --- a/clang/lib/Sema/SemaPseudoObject.cpp +++ b/clang/lib/Sema/SemaPseudoObject.cpp @@ -29,14 +29,14 @@ // //===----------------------------------------------------------------------===// -#include "clang/Sema/SemaInternal.h" #include "clang/AST/ExprCXX.h" #include "clang/AST/ExprObjC.h" #include "clang/Basic/CharInfo.h" #include "clang/Lex/Preprocessor.h" #include "clang/Sema/Initialization.h" -#include "clang/Sema/SemaObjC.h" #include "clang/Sema/ScopeInfo.h" +#include "clang/Sema/SemaInternal.h" +#include "clang/Sema/SemaObjC.h" #include "llvm/ADT/SmallString.h" using namespace clang; @@ -558,14 +558,14 @@ static ObjCMethodDecl *LookupMethodInReceiverType(Sema &S, Selector sel, // Special case for 'self' in class method implementations. if (PT->isObjCClassType() && - S.ObjC().isSelfExpr(const_cast(PRE->getBase()))) { + S.ObjC().isSelfExpr(const_cast(PRE->getBase()))) { // This cast is safe because isSelfExpr is only true within // methods. ObjCMethodDecl *method = cast(S.CurContext->getNonClosureAncestor()); - return S.ObjC().LookupMethodInObjectType(sel, - S.Context.getObjCInterfaceType(method->getClassInterface()), - /*instance*/ false); + return S.ObjC().LookupMethodInObjectType( + sel, S.Context.getObjCInterfaceType(method->getClassInterface()), + /*instance*/ false); } return S.ObjC().LookupMethodInObjectType(sel, PT->getPointeeType(), true); @@ -576,7 +576,8 @@ static ObjCMethodDecl *LookupMethodInReceiverType(Sema &S, Selector sel, PRE->getSuperReceiverType()->getAs()) return S.ObjC().LookupMethodInObjectType(sel, PT->getPointeeType(), true); - return S.ObjC().LookupMethodInObjectType(sel, PRE->getSuperReceiverType(), false); + return S.ObjC().LookupMethodInObjectType(sel, PRE->getSuperReceiverType(), + false); } assert(PRE->isClassReceiver() && "Invalid expression"); @@ -742,13 +743,13 @@ ExprResult ObjCPropertyOpBuilder::buildGet() { if ((Getter->isInstanceMethod() && !RefExpr->isClassReceiver()) || RefExpr->isObjectReceiver()) { assert(InstanceReceiver || RefExpr->isSuperReceiver()); - msg = S.ObjC().BuildInstanceMessageImplicit(InstanceReceiver, receiverType, - GenericLoc, Getter->getSelector(), - Getter, std::nullopt); + msg = S.ObjC().BuildInstanceMessageImplicit( + InstanceReceiver, receiverType, GenericLoc, Getter->getSelector(), + Getter, std::nullopt); } else { - msg = S.ObjC().BuildClassMessageImplicit(receiverType, RefExpr->isSuperReceiver(), - GenericLoc, Getter->getSelector(), Getter, - std::nullopt); + msg = S.ObjC().BuildClassMessageImplicit( + receiverType, RefExpr->isSuperReceiver(), GenericLoc, + Getter->getSelector(), Getter, std::nullopt); } return msg; } @@ -803,13 +804,12 @@ ExprResult ObjCPropertyOpBuilder::buildSet(Expr *op, SourceLocation opcLoc, if ((Setter->isInstanceMethod() && !RefExpr->isClassReceiver()) || RefExpr->isObjectReceiver()) { msg = S.ObjC().BuildInstanceMessageImplicit(InstanceReceiver, receiverType, - GenericLoc, SetterSelector, Setter, - MultiExprArg(args, 1)); + GenericLoc, SetterSelector, + Setter, MultiExprArg(args, 1)); } else { - msg = S.ObjC().BuildClassMessageImplicit(receiverType, RefExpr->isSuperReceiver(), - GenericLoc, - SetterSelector, Setter, - MultiExprArg(args, 1)); + msg = S.ObjC().BuildClassMessageImplicit( + receiverType, RefExpr->isSuperReceiver(), GenericLoc, SetterSelector, + Setter, MultiExprArg(args, 1)); } if (!msg.isInvalid() && captureSetValueAsResult) { @@ -838,7 +838,7 @@ ExprResult ObjCPropertyOpBuilder::buildRValueOperation(Expr *op) { if (RefExpr->isExplicitProperty() && !Getter->hasRelatedResultType()) S.ObjC().DiagnosePropertyAccessorMismatch(RefExpr->getExplicitProperty(), - Getter, RefExpr->getLocation()); + Getter, RefExpr->getLocation()); // As a special case, if the method returns 'id', try to get // a better type from the property. @@ -1057,13 +1057,13 @@ static void CheckKeyForObjCARCConversion(Sema &S, QualType ContainerT, const IdentifierInfo *KeyIdents[] = { &S.Context.Idents.get("objectForKeyedSubscript")}; Selector GetterSelector = S.Context.Selectors.getSelector(1, KeyIdents); - ObjCMethodDecl *Getter = S.ObjC().LookupMethodInObjectType(GetterSelector, ContainerT, - true /*instance*/); + ObjCMethodDecl *Getter = S.ObjC().LookupMethodInObjectType( + GetterSelector, ContainerT, true /*instance*/); if (!Getter) return; QualType T = Getter->parameters()[0]->getType(); S.ObjC().CheckObjCConversion(Key->getSourceRange(), T, Key, - CheckedConversionKind::Implicit); + CheckedConversionKind::Implicit); } bool ObjCSubscriptOpBuilder::findAtIndexGetter() { @@ -1079,7 +1079,7 @@ bool ObjCSubscriptOpBuilder::findAtIndexGetter() { ResultType = PTy->getPointeeType(); } SemaObjC::ObjCSubscriptKind Res = - S.ObjC().CheckSubscriptingKind(RefExpr->getKeyExpr()); + S.ObjC().CheckSubscriptingKind(RefExpr->getKeyExpr()); if (Res == SemaObjC::OS_Error) { if (S.getLangOpts().ObjCAutoRefCount) CheckKeyForObjCARCConversion(S, ResultType, @@ -1108,8 +1108,8 @@ bool ObjCSubscriptOpBuilder::findAtIndexGetter() { AtIndexGetterSelector = S.Context.Selectors.getSelector(1, KeyIdents); } - AtIndexGetter = S.ObjC().LookupMethodInObjectType(AtIndexGetterSelector, ResultType, - true /*instance*/); + AtIndexGetter = S.ObjC().LookupMethodInObjectType( + AtIndexGetterSelector, ResultType, true /*instance*/); if (!AtIndexGetter && S.getLangOpts().DebuggerObjCLiteral) { AtIndexGetter = ObjCMethodDecl::Create( @@ -1139,10 +1139,8 @@ bool ObjCSubscriptOpBuilder::findAtIndexGetter() { << BaseExpr->getType() << 0 << arrayRef; return false; } - AtIndexGetter = - S.ObjC().LookupInstanceMethodInGlobalPool(AtIndexGetterSelector, - RefExpr->getSourceRange(), - true); + AtIndexGetter = S.ObjC().LookupInstanceMethodInGlobalPool( + AtIndexGetterSelector, RefExpr->getSourceRange(), true); } if (AtIndexGetter) { @@ -1181,7 +1179,7 @@ bool ObjCSubscriptOpBuilder::findAtIndexSetter() { } SemaObjC::ObjCSubscriptKind Res = - S.ObjC().CheckSubscriptingKind(RefExpr->getKeyExpr()); + S.ObjC().CheckSubscriptingKind(RefExpr->getKeyExpr()); if (Res == SemaObjC::OS_Error) { if (S.getLangOpts().ObjCAutoRefCount) CheckKeyForObjCARCConversion(S, ResultType, @@ -1211,8 +1209,8 @@ bool ObjCSubscriptOpBuilder::findAtIndexSetter() { &S.Context.Idents.get("atIndexedSubscript")}; AtIndexSetterSelector = S.Context.Selectors.getSelector(2, KeyIdents); } - AtIndexSetter = S.ObjC().LookupMethodInObjectType(AtIndexSetterSelector, ResultType, - true /*instance*/); + AtIndexSetter = S.ObjC().LookupMethodInObjectType( + AtIndexSetterSelector, ResultType, true /*instance*/); if (!AtIndexSetter && S.getLangOpts().DebuggerObjCLiteral) { TypeSourceInfo *ReturnTInfo = nullptr; @@ -1254,10 +1252,8 @@ bool ObjCSubscriptOpBuilder::findAtIndexSetter() { << BaseExpr->getType() << 1 << arrayRef; return false; } - AtIndexSetter = - S.ObjC().LookupInstanceMethodInGlobalPool(AtIndexSetterSelector, - RefExpr->getSourceRange(), - true); + AtIndexSetter = S.ObjC().LookupInstanceMethodInGlobalPool( + AtIndexSetterSelector, RefExpr->getSourceRange(), true); } bool err = false; @@ -1315,10 +1311,9 @@ ExprResult ObjCSubscriptOpBuilder::buildGet() { assert(InstanceBase); if (AtIndexGetter) S.DiagnoseUseOfDecl(AtIndexGetter, GenericLoc); - msg = S.ObjC().BuildInstanceMessageImplicit(InstanceBase, receiverType, - GenericLoc, - AtIndexGetterSelector, AtIndexGetter, - MultiExprArg(args, 1)); + msg = S.ObjC().BuildInstanceMessageImplicit( + InstanceBase, receiverType, GenericLoc, AtIndexGetterSelector, + AtIndexGetter, MultiExprArg(args, 1)); return msg; } @@ -1340,11 +1335,9 @@ ExprResult ObjCSubscriptOpBuilder::buildSet(Expr *op, SourceLocation opcLoc, Expr *args[] = { op, Index }; // Build a message-send. - ExprResult msg = S.ObjC().BuildInstanceMessageImplicit(InstanceBase, receiverType, - GenericLoc, - AtIndexSetterSelector, - AtIndexSetter, - MultiExprArg(args, 2)); + ExprResult msg = S.ObjC().BuildInstanceMessageImplicit( + InstanceBase, receiverType, GenericLoc, AtIndexSetterSelector, + AtIndexSetter, MultiExprArg(args, 2)); if (!msg.isInvalid() && captureSetValueAsResult) { ObjCMessageExpr *msgExpr = diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index f9d9e52b2300b..d1ccfad1bd550 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -3978,7 +3978,8 @@ classifyPointerDeclarator(Sema &S, QualType type, Declarator &declarator, // Look at Objective-C class types. if (auto objcClass = type->getAs()) { - if (objcClass->getInterface()->getIdentifier() == S.ObjC().getNSErrorIdent()) { + if (objcClass->getInterface()->getIdentifier() == + S.ObjC().getNSErrorIdent()) { if (numNormalPointers == 2 && numTypeSpecifierPointers < 2) return PointerDeclaratorKind::NSErrorPointerPointer; } diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 55454a63cc9eb..ef610c8242adc 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -1608,7 +1608,7 @@ class TreeTransform { MultiStmtArg CatchStmts, Stmt *Finally) { return getSema().ObjC().ActOnObjCAtTryStmt(AtLoc, TryBody, CatchStmts, - Finally); + Finally); } /// Rebuild an Objective-C exception declaration. @@ -1617,10 +1617,9 @@ class TreeTransform { /// Subclasses may override this routine to provide different behavior. VarDecl *RebuildObjCExceptionDecl(VarDecl *ExceptionDecl, TypeSourceInfo *TInfo, QualType T) { - return getSema().ObjC().BuildObjCExceptionDecl(TInfo, T, - ExceptionDecl->getInnerLocStart(), - ExceptionDecl->getLocation(), - ExceptionDecl->getIdentifier()); + return getSema().ObjC().BuildObjCExceptionDecl( + TInfo, T, ExceptionDecl->getInnerLocStart(), + ExceptionDecl->getLocation(), ExceptionDecl->getIdentifier()); } /// Build a new Objective-C \@catch statement. @@ -1631,8 +1630,7 @@ class TreeTransform { SourceLocation RParenLoc, VarDecl *Var, Stmt *Body) { - return getSema().ObjC().ActOnObjCAtCatchStmt(AtLoc, RParenLoc, - Var, Body); + return getSema().ObjC().ActOnObjCAtCatchStmt(AtLoc, RParenLoc, Var, Body); } /// Build a new Objective-C \@finally statement. @@ -2520,14 +2518,13 @@ class TreeTransform { Expr *Collection, SourceLocation RParenLoc, Stmt *Body) { - StmtResult ForEachStmt = getSema().ObjC().ActOnObjCForCollectionStmt(ForLoc, - Element, - Collection, - RParenLoc); + StmtResult ForEachStmt = getSema().ObjC().ActOnObjCForCollectionStmt( + ForLoc, Element, Collection, RParenLoc); if (ForEachStmt.isInvalid()) return StmtError(); - return getSema().ObjC().FinishObjCForCollectionStmt(ForEachStmt.get(), Body); + return getSema().ObjC().FinishObjCForCollectionStmt(ForEachStmt.get(), + Body); } /// Build a new C++ exception declaration. @@ -2593,8 +2590,8 @@ class TreeTransform { diag::err_objc_for_range_init_stmt) << Init->getSourceRange(); } - return getSema().ObjC().ActOnObjCForCollectionStmt(ForLoc, LoopVar, - RangeExpr, RParenLoc); + return getSema().ObjC().ActOnObjCForCollectionStmt( + ForLoc, LoopVar, RangeExpr, RParenLoc); } } } @@ -3718,16 +3715,16 @@ class TreeTransform { /// Subclasses may override this routine to provide different behavior. ExprResult RebuildObjCArrayLiteral(SourceRange Range, Expr **Elements, unsigned NumElements) { - return getSema().ObjC().BuildObjCArrayLiteral(Range, - MultiExprArg(Elements, NumElements)); + return getSema().ObjC().BuildObjCArrayLiteral( + Range, MultiExprArg(Elements, NumElements)); } ExprResult RebuildObjCSubscriptRefExpr(SourceLocation RB, Expr *Base, Expr *Key, ObjCMethodDecl *getterMethod, ObjCMethodDecl *setterMethod) { - return getSema().ObjC().BuildObjCSubscriptExpression(RB, Base, Key, - getterMethod, setterMethod); + return getSema().ObjC().BuildObjCSubscriptExpression( + RB, Base, Key, getterMethod, setterMethod); } /// Build a new Objective-C dictionary literal. @@ -3746,7 +3743,8 @@ class TreeTransform { ExprResult RebuildObjCEncodeExpr(SourceLocation AtLoc, TypeSourceInfo *EncodeTypeInfo, SourceLocation RParenLoc) { - return SemaRef.ObjC().BuildObjCEncodeExpression(AtLoc, EncodeTypeInfo, RParenLoc); + return SemaRef.ObjC().BuildObjCEncodeExpression(AtLoc, EncodeTypeInfo, + RParenLoc); } /// Build a new Objective-C class message. @@ -3757,11 +3755,10 @@ class TreeTransform { SourceLocation LBracLoc, MultiExprArg Args, SourceLocation RBracLoc) { - return SemaRef.ObjC().BuildClassMessage(ReceiverTypeInfo, - ReceiverTypeInfo->getType(), - /*SuperLoc=*/SourceLocation(), - Sel, Method, LBracLoc, SelectorLocs, - RBracLoc, Args); + return SemaRef.ObjC().BuildClassMessage( + ReceiverTypeInfo, ReceiverTypeInfo->getType(), + /*SuperLoc=*/SourceLocation(), Sel, Method, LBracLoc, SelectorLocs, + RBracLoc, Args); } /// Build a new Objective-C instance message. @@ -3772,11 +3769,10 @@ class TreeTransform { SourceLocation LBracLoc, MultiExprArg Args, SourceLocation RBracLoc) { - return SemaRef.ObjC().BuildInstanceMessage(Receiver, - Receiver->getType(), - /*SuperLoc=*/SourceLocation(), - Sel, Method, LBracLoc, SelectorLocs, - RBracLoc, Args); + return SemaRef.ObjC().BuildInstanceMessage(Receiver, Receiver->getType(), + /*SuperLoc=*/SourceLocation(), + Sel, Method, LBracLoc, + SelectorLocs, RBracLoc, Args); } /// Build a new Objective-C instance/class message to 'super'. @@ -3788,18 +3784,13 @@ class TreeTransform { SourceLocation LBracLoc, MultiExprArg Args, SourceLocation RBracLoc) { - return Method->isInstanceMethod() ? SemaRef.ObjC().BuildInstanceMessage(nullptr, - SuperType, - SuperLoc, - Sel, Method, LBracLoc, SelectorLocs, - RBracLoc, Args) - : SemaRef.ObjC().BuildClassMessage(nullptr, - SuperType, - SuperLoc, - Sel, Method, LBracLoc, SelectorLocs, - RBracLoc, Args); - - + return Method->isInstanceMethod() + ? SemaRef.ObjC().BuildInstanceMessage( + nullptr, SuperType, SuperLoc, Sel, Method, LBracLoc, + SelectorLocs, RBracLoc, Args) + : SemaRef.ObjC().BuildClassMessage(nullptr, SuperType, SuperLoc, + Sel, Method, LBracLoc, + SelectorLocs, RBracLoc, Args); } /// Build a new Objective-C ivar reference expression. @@ -15082,9 +15073,9 @@ TransformObjCBridgedCastExpr(ObjCBridgedCastExpr *E) { Result.get() == E->getSubExpr()) return E; - return SemaRef.ObjC().BuildObjCBridgedCast(E->getLParenLoc(), E->getBridgeKind(), - E->getBridgeKeywordLoc(), TSInfo, - Result.get()); + return SemaRef.ObjC().BuildObjCBridgedCast( + E->getLParenLoc(), E->getBridgeKind(), E->getBridgeKeywordLoc(), TSInfo, + Result.get()); } template @@ -15472,10 +15463,9 @@ QualType TreeTransform::RebuildObjCTypeParamType( ArrayRef Protocols, ArrayRef ProtocolLocs, SourceLocation ProtocolRAngleLoc) { - return SemaRef.ObjC().BuildObjCTypeParamType(Decl, - ProtocolLAngleLoc, Protocols, - ProtocolLocs, ProtocolRAngleLoc, - /*FailOnError=*/true); + return SemaRef.ObjC().BuildObjCTypeParamType( + Decl, ProtocolLAngleLoc, Protocols, ProtocolLocs, ProtocolRAngleLoc, + /*FailOnError=*/true); } template @@ -15489,11 +15479,11 @@ QualType TreeTransform::RebuildObjCObjectType( ArrayRef Protocols, ArrayRef ProtocolLocs, SourceLocation ProtocolRAngleLoc) { - return SemaRef.ObjC().BuildObjCObjectType(BaseType, Loc, TypeArgsLAngleLoc, TypeArgs, - TypeArgsRAngleLoc, ProtocolLAngleLoc, - Protocols, ProtocolLocs, ProtocolRAngleLoc, - /*FailOnError=*/true, - /*Rebuilding=*/true); + return SemaRef.ObjC().BuildObjCObjectType( + BaseType, Loc, TypeArgsLAngleLoc, TypeArgs, TypeArgsRAngleLoc, + ProtocolLAngleLoc, Protocols, ProtocolLocs, ProtocolRAngleLoc, + /*FailOnError=*/true, + /*Rebuilding=*/true); } template diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 88e06842d9db8..50bf2ccaf4b87 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -4245,8 +4245,8 @@ ASTReader::ReadModuleMapFileBlock(RecordData &Record, ModuleFile &F, /// Move the given method to the back of the global list of methods. static void moveMethodToBackOfGlobalList(Sema &S, ObjCMethodDecl *Method) { // Find the entry for this selector in the method pool. - SemaObjC::GlobalMethodPool::iterator Known - = S.ObjC().MethodPool.find(Method->getSelector()); + SemaObjC::GlobalMethodPool::iterator Known = + S.ObjC().MethodPool.find(Method->getSelector()); if (Known == S.ObjC().MethodPool.end()) return; @@ -8584,7 +8584,9 @@ void ASTReader::ReadMethodPool(Selector Sel) { Sema &S = *getSema(); SemaObjC::GlobalMethodPool::iterator Pos = - S.ObjC().MethodPool.insert(std::make_pair(Sel, SemaObjC::GlobalMethodPool::Lists())) + S.ObjC() + .MethodPool + .insert(std::make_pair(Sel, SemaObjC::GlobalMethodPool::Lists())) .first; Pos->second.first.setBits(Visitor.getInstanceBits()); diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index 3dfb8fc116d89..f51e0e87b51af 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -3451,7 +3451,8 @@ void ASTWriter::WriteSelectors(Sema &SemaRef) { for (auto &SelectorAndID : SelectorIDs) { Selector S = SelectorAndID.first; SelectorID ID = SelectorAndID.second; - SemaObjC::GlobalMethodPool::iterator F = SemaRef.ObjC().MethodPool.find(S); + SemaObjC::GlobalMethodPool::iterator F = + SemaRef.ObjC().MethodPool.find(S); ASTMethodPoolTrait::data_type Data = { ID, ObjCMethodList(), From db81a5d6b977c575894bdaf718118fdcc0647366 Mon Sep 17 00:00:00 2001 From: Vlad Serebrennikov Date: Mon, 13 May 2024 16:39:45 +0300 Subject: [PATCH 3/3] Fix formatting --- clang/lib/Sema/SemaDeclObjC.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp index 3a3a9a881d381..6d4379283f198 100644 --- a/clang/lib/Sema/SemaDeclObjC.cpp +++ b/clang/lib/Sema/SemaDeclObjC.cpp @@ -5354,7 +5354,7 @@ class UnusedBackingIvarChecker } return true; } - }; +}; } // end anonymous namespace void SemaObjC::DiagnoseUnusedBackingIvarInAccessor(