llvm/clang/lib/Parse/ParseObjc.cpp

//===--- ParseObjC.cpp - Objective C Parsing ------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
//  This file implements the Objective-C portions of the Parser interface.
//
//===----------------------------------------------------------------------===//

#include "clang/AST/ASTContext.h"
#include "clang/AST/ExprObjC.h"
#include "clang/AST/ODRDiagsEmitter.h"
#include "clang/AST/PrettyDeclStackTrace.h"
#include "clang/Basic/CharInfo.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Parse/ParseDiagnostic.h"
#include "clang/Parse/Parser.h"
#include "clang/Parse/RAIIObjectsForParser.h"
#include "clang/Sema/DeclSpec.h"
#include "clang/Sema/Scope.h"
#include "clang/Sema/SemaCodeCompletion.h"
#include "clang/Sema/SemaObjC.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"

usingnamespaceclang;

/// Skips attributes after an Objective-C @ directive. Emits a diagnostic.
void Parser::MaybeSkipAttributes(tok::ObjCKeywordKind Kind) {}

/// ParseObjCAtDirectives - Handle parts of the external-declaration production:
///       external-declaration: [C99 6.9]
/// [OBJC]  objc-class-definition
/// [OBJC]  objc-class-declaration
/// [OBJC]  objc-alias-declaration
/// [OBJC]  objc-protocol-definition
/// [OBJC]  objc-method-definition
/// [OBJC]  '@' 'end'
Parser::DeclGroupPtrTy
Parser::ParseObjCAtDirectives(ParsedAttributes &DeclAttrs,
                              ParsedAttributes &DeclSpecAttrs) {}

/// Class to handle popping type parameters when leaving the scope.
class Parser::ObjCTypeParamListScope {};

///
/// objc-class-declaration:
///    '@' 'class' objc-class-forward-decl (',' objc-class-forward-decl)* ';'
///
/// objc-class-forward-decl:
///   identifier objc-type-parameter-list[opt]
///
Parser::DeclGroupPtrTy
Parser::ParseObjCAtClassDeclaration(SourceLocation atLoc) {}

void Parser::CheckNestedObjCContexts(SourceLocation AtLoc)
{}

///
///   objc-interface:
///     objc-class-interface-attributes[opt] objc-class-interface
///     objc-category-interface
///
///   objc-class-interface:
///     '@' 'interface' identifier objc-type-parameter-list[opt]
///       objc-superclass[opt] objc-protocol-refs[opt]
///       objc-class-instance-variables[opt]
///       objc-interface-decl-list
///     @end
///
///   objc-category-interface:
///     '@' 'interface' identifier objc-type-parameter-list[opt]
///       '(' identifier[opt] ')' objc-protocol-refs[opt]
///       objc-interface-decl-list
///     @end
///
///   objc-superclass:
///     ':' identifier objc-type-arguments[opt]
///
///   objc-class-interface-attributes:
///     __attribute__((visibility("default")))
///     __attribute__((visibility("hidden")))
///     __attribute__((deprecated))
///     __attribute__((unavailable))
///     __attribute__((objc_exception)) - used by NSException on 64-bit
///     __attribute__((objc_root_class))
///
Decl *Parser::ParseObjCAtInterfaceDeclaration(SourceLocation AtLoc,
                                              ParsedAttributes &attrs) {}

/// Add an attribute for a context-sensitive type nullability to the given
/// declarator.
static void addContextSensitiveTypeNullability(Parser &P,
                                               Declarator &D,
                                               NullabilityKind nullability,
                                               SourceLocation nullabilityLoc,
                                               bool &addedToDeclSpec) {}

/// Parse an Objective-C type parameter list, if present, or capture
/// the locations of the protocol identifiers for a list of protocol
/// references.
///
///   objc-type-parameter-list:
///     '<' objc-type-parameter (',' objc-type-parameter)* '>'
///
///   objc-type-parameter:
///     objc-type-parameter-variance? identifier objc-type-parameter-bound[opt]
///
///   objc-type-parameter-bound:
///     ':' type-name
///
///   objc-type-parameter-variance:
///     '__covariant'
///     '__contravariant'
///
/// \param lAngleLoc The location of the starting '<'.
///
/// \param protocolIdents Will capture the list of identifiers, if the
/// angle brackets contain a list of protocol references rather than a
/// type parameter list.
///
/// \param rAngleLoc The location of the ending '>'.
ObjCTypeParamList *Parser::parseObjCTypeParamListOrProtocolRefs(
    ObjCTypeParamListScope &Scope, SourceLocation &lAngleLoc,
    SmallVectorImpl<IdentifierLocPair> &protocolIdents,
    SourceLocation &rAngleLoc, bool mayBeProtocolList) {}

/// Parse an objc-type-parameter-list.
ObjCTypeParamList *Parser::parseObjCTypeParamList() {}

static bool isTopLevelObjCKeyword(tok::ObjCKeywordKind DirectiveKind) {}

///   objc-interface-decl-list:
///     empty
///     objc-interface-decl-list objc-property-decl [OBJC2]
///     objc-interface-decl-list objc-method-requirement [OBJC2]
///     objc-interface-decl-list objc-method-proto ';'
///     objc-interface-decl-list declaration
///     objc-interface-decl-list ';'
///
///   objc-method-requirement: [OBJC2]
///     @required
///     @optional
///
void Parser::ParseObjCInterfaceDeclList(tok::ObjCKeywordKind contextKey,
                                        Decl *CDecl) {}

/// Diagnose redundant or conflicting nullability information.
static void diagnoseRedundantPropertyNullability(Parser &P,
                                                 ObjCDeclSpec &DS,
                                                 NullabilityKind nullability,
                                                 SourceLocation nullabilityLoc){}

///   Parse property attribute declarations.
///
///   property-attr-decl: '(' property-attrlist ')'
///   property-attrlist:
///     property-attribute
///     property-attrlist ',' property-attribute
///   property-attribute:
///     getter '=' identifier
///     setter '=' identifier ':'
///     direct
///     readonly
///     readwrite
///     assign
///     retain
///     copy
///     nonatomic
///     atomic
///     strong
///     weak
///     unsafe_unretained
///     nonnull
///     nullable
///     null_unspecified
///     null_resettable
///     class
///
void Parser::ParseObjCPropertyAttribute(ObjCDeclSpec &DS) {}

///   objc-method-proto:
///     objc-instance-method objc-method-decl objc-method-attributes[opt]
///     objc-class-method objc-method-decl objc-method-attributes[opt]
///
///   objc-instance-method: '-'
///   objc-class-method: '+'
///
///   objc-method-attributes:         [OBJC2]
///     __attribute__((deprecated))
///
Decl *Parser::ParseObjCMethodPrototype(tok::ObjCKeywordKind MethodImplKind,
                                       bool MethodDefinition) {}

///   objc-selector:
///     identifier
///     one of
///       enum struct union if else while do for switch case default
///       break continue return goto asm sizeof typeof __alignof
///       unsigned long const short volatile signed restrict _Complex
///       in out inout bycopy byref oneway int char float double void _Bool
///
IdentifierInfo *Parser::ParseObjCSelectorPiece(SourceLocation &SelectorLoc) {}

///  objc-for-collection-in: 'in'
///
bool Parser::isTokIdentifier_in() const {}

/// ParseObjCTypeQualifierList - This routine parses the objective-c's type
/// qualifier list and builds their bitmask representation in the input
/// argument.
///
///   objc-type-qualifiers:
///     objc-type-qualifier
///     objc-type-qualifiers objc-type-qualifier
///
///   objc-type-qualifier:
///     'in'
///     'out'
///     'inout'
///     'oneway'
///     'bycopy'
///     'byref'
///     'nonnull'
///     'nullable'
///     'null_unspecified'
///
void Parser::ParseObjCTypeQualifierList(ObjCDeclSpec &DS,
                                        DeclaratorContext Context) {}

/// Take all the decl attributes out of the given list and add
/// them to the given attribute set.
static void takeDeclAttributes(ParsedAttributesView &attrs,
                               ParsedAttributesView &from) {}

/// takeDeclAttributes - Take all the decl attributes from the given
/// declarator and add them to the given list.
static void takeDeclAttributes(ParsedAttributes &attrs,
                               Declarator &D) {}

///   objc-type-name:
///     '(' objc-type-qualifiers[opt] type-name ')'
///     '(' objc-type-qualifiers[opt] ')'
///
ParsedType Parser::ParseObjCTypeName(ObjCDeclSpec &DS,
                                     DeclaratorContext context,
                                     ParsedAttributes *paramAttrs) {}

///   objc-method-decl:
///     objc-selector
///     objc-keyword-selector objc-parmlist[opt]
///     objc-type-name objc-selector
///     objc-type-name objc-keyword-selector objc-parmlist[opt]
///
///   objc-keyword-selector:
///     objc-keyword-decl
///     objc-keyword-selector objc-keyword-decl
///
///   objc-keyword-decl:
///     objc-selector ':' objc-type-name objc-keyword-attributes[opt] identifier
///     objc-selector ':' objc-keyword-attributes[opt] identifier
///     ':' objc-type-name objc-keyword-attributes[opt] identifier
///     ':' objc-keyword-attributes[opt] identifier
///
///   objc-parmlist:
///     objc-parms objc-ellipsis[opt]
///
///   objc-parms:
///     objc-parms , parameter-declaration
///
///   objc-ellipsis:
///     , ...
///
///   objc-keyword-attributes:         [OBJC2]
///     __attribute__((unused))
///
Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
                                  tok::TokenKind mType,
                                  tok::ObjCKeywordKind MethodImplKind,
                                  bool MethodDefinition) {}

///   objc-protocol-refs:
///     '<' identifier-list '>'
///
bool Parser::
ParseObjCProtocolReferences(SmallVectorImpl<Decl *> &Protocols,
                            SmallVectorImpl<SourceLocation> &ProtocolLocs,
                            bool WarnOnDeclarations, bool ForObjCContainer,
                            SourceLocation &LAngleLoc, SourceLocation &EndLoc,
                            bool consumeLastToken) {}

TypeResult Parser::parseObjCProtocolQualifierType(SourceLocation &rAngleLoc) {}

/// Parse Objective-C type arguments or protocol qualifiers.
///
///   objc-type-arguments:
///     '<' type-name '...'[opt] (',' type-name '...'[opt])* '>'
///
void Parser::parseObjCTypeArgsOrProtocolQualifiers(
       ParsedType baseType,
       SourceLocation &typeArgsLAngleLoc,
       SmallVectorImpl<ParsedType> &typeArgs,
       SourceLocation &typeArgsRAngleLoc,
       SourceLocation &protocolLAngleLoc,
       SmallVectorImpl<Decl *> &protocols,
       SmallVectorImpl<SourceLocation> &protocolLocs,
       SourceLocation &protocolRAngleLoc,
       bool consumeLastToken,
       bool warnOnIncompleteProtocols) {}

void Parser::parseObjCTypeArgsAndProtocolQualifiers(
       ParsedType baseType,
       SourceLocation &typeArgsLAngleLoc,
       SmallVectorImpl<ParsedType> &typeArgs,
       SourceLocation &typeArgsRAngleLoc,
       SourceLocation &protocolLAngleLoc,
       SmallVectorImpl<Decl *> &protocols,
       SmallVectorImpl<SourceLocation> &protocolLocs,
       SourceLocation &protocolRAngleLoc,
       bool consumeLastToken) {}

TypeResult Parser::parseObjCTypeArgsAndProtocolQualifiers(
             SourceLocation loc,
             ParsedType type,
             bool consumeLastToken,
             SourceLocation &endLoc) {}

void Parser::HelperActionsForIvarDeclarations(
    ObjCContainerDecl *interfaceDecl, SourceLocation atLoc,
    BalancedDelimiterTracker &T, SmallVectorImpl<Decl *> &AllIvarDecls,
    bool RBraceMissing) {}

///   objc-class-instance-variables:
///     '{' objc-instance-variable-decl-list[opt] '}'
///
///   objc-instance-variable-decl-list:
///     objc-visibility-spec
///     objc-instance-variable-decl ';'
///     ';'
///     objc-instance-variable-decl-list objc-visibility-spec
///     objc-instance-variable-decl-list objc-instance-variable-decl ';'
///     objc-instance-variable-decl-list static_assert-declaration
///     objc-instance-variable-decl-list ';'
///
///   objc-visibility-spec:
///     @private
///     @protected
///     @public
///     @package [OBJC2]
///
///   objc-instance-variable-decl:
///     struct-declaration
///
void Parser::ParseObjCClassInstanceVariables(ObjCContainerDecl *interfaceDecl,
                                             tok::ObjCKeywordKind visibility,
                                             SourceLocation atLoc) {}

///   objc-protocol-declaration:
///     objc-protocol-definition
///     objc-protocol-forward-reference
///
///   objc-protocol-definition:
///     \@protocol identifier
///       objc-protocol-refs[opt]
///       objc-interface-decl-list
///     \@end
///
///   objc-protocol-forward-reference:
///     \@protocol identifier-list ';'
///
///   "\@protocol identifier ;" should be resolved as "\@protocol
///   identifier-list ;": objc-interface-decl-list may not start with a
///   semicolon in the first alternative if objc-protocol-refs are omitted.
Parser::DeclGroupPtrTy
Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc,
                                       ParsedAttributes &attrs) {}

///   objc-implementation:
///     objc-class-implementation-prologue
///     objc-category-implementation-prologue
///
///   objc-class-implementation-prologue:
///     @implementation identifier objc-superclass[opt]
///       objc-class-instance-variables[opt]
///
///   objc-category-implementation-prologue:
///     @implementation identifier ( identifier )
Parser::DeclGroupPtrTy
Parser::ParseObjCAtImplementationDeclaration(SourceLocation AtLoc,
                                             ParsedAttributes &Attrs) {}

Parser::DeclGroupPtrTy
Parser::ParseObjCAtEndDeclaration(SourceRange atEnd) {}

Parser::ObjCImplParsingDataRAII::~ObjCImplParsingDataRAII() {}

void Parser::ObjCImplParsingDataRAII::finish(SourceRange AtEnd) {}

///   compatibility-alias-decl:
///     @compatibility_alias alias-name  class-name ';'
///
Decl *Parser::ParseObjCAtAliasDeclaration(SourceLocation atLoc) {}

///   property-synthesis:
///     @synthesize property-ivar-list ';'
///
///   property-ivar-list:
///     property-ivar
///     property-ivar-list ',' property-ivar
///
///   property-ivar:
///     identifier
///     identifier '=' identifier
///
Decl *Parser::ParseObjCPropertySynthesize(SourceLocation atLoc) {}

///   property-dynamic:
///     @dynamic  property-list
///
///   property-list:
///     identifier
///     property-list ',' identifier
///
Decl *Parser::ParseObjCPropertyDynamic(SourceLocation atLoc) {}

///  objc-throw-statement:
///    throw expression[opt];
///
StmtResult Parser::ParseObjCThrowStmt(SourceLocation atLoc) {}

/// objc-synchronized-statement:
///   @synchronized '(' expression ')' compound-statement
///
StmtResult
Parser::ParseObjCSynchronizedStmt(SourceLocation atLoc) {}

///  objc-try-catch-statement:
///    @try compound-statement objc-catch-list[opt]
///    @try compound-statement objc-catch-list[opt] @finally compound-statement
///
///  objc-catch-list:
///    @catch ( parameter-declaration ) compound-statement
///    objc-catch-list @catch ( catch-parameter-declaration ) compound-statement
///  catch-parameter-declaration:
///     parameter-declaration
///     '...' [OBJC2]
///
StmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) {}

/// objc-autoreleasepool-statement:
///   @autoreleasepool compound-statement
///
StmtResult
Parser::ParseObjCAutoreleasePoolStmt(SourceLocation atLoc) {}

/// StashAwayMethodOrFunctionBodyTokens -  Consume the tokens and store them
/// for later parsing.
void Parser::StashAwayMethodOrFunctionBodyTokens(Decl *MDecl) {}

///   objc-method-def: objc-method-proto ';'[opt] '{' body '}'
///
Decl *Parser::ParseObjCMethodDefinition() {}

StmtResult Parser::ParseObjCAtStatement(SourceLocation AtLoc,
                                        ParsedStmtContext StmtCtx) {}

ExprResult Parser::ParseObjCAtExpression(SourceLocation AtLoc) {}

/// Parse the receiver of an Objective-C++ message send.
///
/// This routine parses the receiver of a message send in
/// Objective-C++ either as a type or as an expression. Note that this
/// routine must not be called to parse a send to 'super', since it
/// has no way to return such a result.
///
/// \param IsExpr Whether the receiver was parsed as an expression.
///
/// \param TypeOrExpr If the receiver was parsed as an expression (\c
/// IsExpr is true), the parsed expression. If the receiver was parsed
/// as a type (\c IsExpr is false), the parsed type.
///
/// \returns True if an error occurred during parsing or semantic
/// analysis, in which case the arguments do not have valid
/// values. Otherwise, returns false for a successful parse.
///
///   objc-receiver: [C++]
///     'super' [not parsed here]
///     expression
///     simple-type-specifier
///     typename-specifier
bool Parser::ParseObjCXXMessageReceiver(bool &IsExpr, void *&TypeOrExpr) {}

/// Determine whether the parser is currently referring to a an
/// Objective-C message send, using a simplified heuristic to avoid overhead.
///
/// This routine will only return true for a subset of valid message-send
/// expressions.
bool Parser::isSimpleObjCMessageExpression() {}

bool Parser::isStartOfObjCClassMessageMissingOpenBracket() {}

///   objc-message-expr:
///     '[' objc-receiver objc-message-args ']'
///
///   objc-receiver: [C]
///     'super'
///     expression
///     class-name
///     type-name
///
ExprResult Parser::ParseObjCMessageExpression() {}

/// Parse the remainder of an Objective-C message following the
/// '[' objc-receiver.
///
/// This routine handles sends to super, class messages (sent to a
/// class name), and instance messages (sent to an object), and the
/// target is represented by \p SuperLoc, \p ReceiverType, or \p
/// ReceiverExpr, respectively. Only one of these parameters may have
/// a valid value.
///
/// \param LBracLoc The location of the opening '['.
///
/// \param SuperLoc If this is a send to 'super', the location of the
/// 'super' keyword that indicates a send to the superclass.
///
/// \param ReceiverType If this is a class message, the type of the
/// class we are sending a message to.
///
/// \param ReceiverExpr If this is an instance message, the expression
/// used to compute the receiver object.
///
///   objc-message-args:
///     objc-selector
///     objc-keywordarg-list
///
///   objc-keywordarg-list:
///     objc-keywordarg
///     objc-keywordarg-list objc-keywordarg
///
///   objc-keywordarg:
///     selector-name[opt] ':' objc-keywordexpr
///
///   objc-keywordexpr:
///     nonempty-expr-list
///
///   nonempty-expr-list:
///     assignment-expression
///     nonempty-expr-list , assignment-expression
///
ExprResult
Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc,
                                       SourceLocation SuperLoc,
                                       ParsedType ReceiverType,
                                       Expr *ReceiverExpr) {}

ExprResult Parser::ParseObjCStringLiteral(SourceLocation AtLoc) {}

/// ParseObjCBooleanLiteral -
/// objc-scalar-literal : '@' boolean-keyword
///                        ;
/// boolean-keyword: 'true' | 'false' | '__objc_yes' | '__objc_no'
///                        ;
ExprResult Parser::ParseObjCBooleanLiteral(SourceLocation AtLoc,
                                           bool ArgValue) {}

/// ParseObjCCharacterLiteral -
/// objc-scalar-literal : '@' character-literal
///                        ;
ExprResult Parser::ParseObjCCharacterLiteral(SourceLocation AtLoc) {}

/// ParseObjCNumericLiteral -
/// objc-scalar-literal : '@' scalar-literal
///                        ;
/// scalar-literal : | numeric-constant			/* any numeric constant. */
///                    ;
ExprResult Parser::ParseObjCNumericLiteral(SourceLocation AtLoc) {}

/// ParseObjCBoxedExpr -
/// objc-box-expression:
///       @( assignment-expression )
ExprResult
Parser::ParseObjCBoxedExpr(SourceLocation AtLoc) {}

ExprResult Parser::ParseObjCArrayLiteral(SourceLocation AtLoc) {}

ExprResult Parser::ParseObjCDictionaryLiteral(SourceLocation AtLoc) {}

///    objc-encode-expression:
///      \@encode ( type-name )
ExprResult
Parser::ParseObjCEncodeExpression(SourceLocation AtLoc) {}

///     objc-protocol-expression
///       \@protocol ( protocol-name )
ExprResult
Parser::ParseObjCProtocolExpression(SourceLocation AtLoc) {}

///     objc-selector-expression
///       @selector '(' '('[opt] objc-keyword-selector ')'[opt] ')'
ExprResult Parser::ParseObjCSelectorExpression(SourceLocation AtLoc) {}

void Parser::ParseLexedObjCMethodDefs(LexedMethod &LM, bool parseMethod) {}