aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/clang16/include/clang/AST/ExprObjC.h
diff options
context:
space:
mode:
authorvitalyisaev <vitalyisaev@yandex-team.com>2023-06-29 10:00:50 +0300
committervitalyisaev <vitalyisaev@yandex-team.com>2023-06-29 10:00:50 +0300
commit6ffe9e53658409f212834330e13564e4952558f6 (patch)
tree85b1e00183517648b228aafa7c8fb07f5276f419 /contrib/libs/clang16/include/clang/AST/ExprObjC.h
parent726057070f9c5a91fc10fde0d5024913d10f1ab9 (diff)
downloadydb-6ffe9e53658409f212834330e13564e4952558f6.tar.gz
YQ Connector: support managed ClickHouse
Со стороны dqrun можно обратиться к инстансу коннектора, который работает на streaming стенде, и извлечь данные из облачного CH.
Diffstat (limited to 'contrib/libs/clang16/include/clang/AST/ExprObjC.h')
-rw-r--r--contrib/libs/clang16/include/clang/AST/ExprObjC.h1736
1 files changed, 1736 insertions, 0 deletions
diff --git a/contrib/libs/clang16/include/clang/AST/ExprObjC.h b/contrib/libs/clang16/include/clang/AST/ExprObjC.h
new file mode 100644
index 0000000000..b85b3d931d
--- /dev/null
+++ b/contrib/libs/clang16/include/clang/AST/ExprObjC.h
@@ -0,0 +1,1736 @@
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- ExprObjC.h - Classes for representing ObjC expressions ---*- 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
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the ExprObjC interface and subclasses.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_EXPROBJC_H
+#define LLVM_CLANG_AST_EXPROBJC_H
+
+#include "clang/AST/ComputeDependence.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DependenceFlags.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/OperationKinds.h"
+#include "clang/AST/SelectorLocationsKind.h"
+#include "clang/AST/Stmt.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 "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/PointerUnion.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/TrailingObjects.h"
+#include "llvm/Support/VersionTuple.h"
+#include "llvm/Support/type_traits.h"
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
+#include <optional>
+
+namespace clang {
+
+class ASTContext;
+class CXXBaseSpecifier;
+
+/// ObjCStringLiteral, used for Objective-C string literals
+/// i.e. @"foo".
+class ObjCStringLiteral : public Expr {
+ Stmt *String;
+ SourceLocation AtLoc;
+
+public:
+ ObjCStringLiteral(StringLiteral *SL, QualType T, SourceLocation L)
+ : Expr(ObjCStringLiteralClass, T, VK_PRValue, OK_Ordinary), String(SL),
+ AtLoc(L) {
+ setDependence(ExprDependence::None);
+ }
+ explicit ObjCStringLiteral(EmptyShell Empty)
+ : Expr(ObjCStringLiteralClass, Empty) {}
+
+ StringLiteral *getString() { return cast<StringLiteral>(String); }
+ const StringLiteral *getString() const { return cast<StringLiteral>(String); }
+ void setString(StringLiteral *S) { String = S; }
+
+ SourceLocation getAtLoc() const { return AtLoc; }
+ void setAtLoc(SourceLocation L) { AtLoc = L; }
+
+ SourceLocation getBeginLoc() const LLVM_READONLY { return AtLoc; }
+ SourceLocation getEndLoc() const LLVM_READONLY { return String->getEndLoc(); }
+
+ // Iterators
+ child_range children() { return child_range(&String, &String+1); }
+
+ const_child_range children() const {
+ return const_child_range(&String, &String + 1);
+ }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == ObjCStringLiteralClass;
+ }
+};
+
+/// ObjCBoolLiteralExpr - Objective-C Boolean Literal.
+class ObjCBoolLiteralExpr : public Expr {
+ bool Value;
+ SourceLocation Loc;
+
+public:
+ ObjCBoolLiteralExpr(bool val, QualType Ty, SourceLocation l)
+ : Expr(ObjCBoolLiteralExprClass, Ty, VK_PRValue, OK_Ordinary), Value(val),
+ Loc(l) {
+ setDependence(ExprDependence::None);
+ }
+ explicit ObjCBoolLiteralExpr(EmptyShell Empty)
+ : Expr(ObjCBoolLiteralExprClass, Empty) {}
+
+ bool getValue() const { return Value; }
+ void setValue(bool V) { Value = V; }
+
+ SourceLocation getBeginLoc() const LLVM_READONLY { return Loc; }
+ SourceLocation getEndLoc() const LLVM_READONLY { return Loc; }
+
+ SourceLocation getLocation() const { return Loc; }
+ void setLocation(SourceLocation L) { Loc = L; }
+
+ // Iterators
+ child_range children() {
+ return child_range(child_iterator(), child_iterator());
+ }
+
+ const_child_range children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == ObjCBoolLiteralExprClass;
+ }
+};
+
+/// ObjCBoxedExpr - used for generalized expression boxing.
+/// as in: @(strdup("hello world")), @(random()) or @(view.frame)
+/// Also used for boxing non-parenthesized numeric literals;
+/// as in: @42 or \@true (c++/objc++) or \@__objc_yes (c/objc).
+class ObjCBoxedExpr : public Expr {
+ Stmt *SubExpr;
+ ObjCMethodDecl *BoxingMethod;
+ SourceRange Range;
+
+public:
+ friend class ASTStmtReader;
+
+ ObjCBoxedExpr(Expr *E, QualType T, ObjCMethodDecl *method, SourceRange R)
+ : Expr(ObjCBoxedExprClass, T, VK_PRValue, OK_Ordinary), SubExpr(E),
+ BoxingMethod(method), Range(R) {
+ setDependence(computeDependence(this));
+ }
+ explicit ObjCBoxedExpr(EmptyShell Empty)
+ : Expr(ObjCBoxedExprClass, Empty) {}
+
+ Expr *getSubExpr() { return cast<Expr>(SubExpr); }
+ const Expr *getSubExpr() const { return cast<Expr>(SubExpr); }
+
+ ObjCMethodDecl *getBoxingMethod() const {
+ return BoxingMethod;
+ }
+
+ // Indicates whether this boxed expression can be emitted as a compile-time
+ // constant.
+ bool isExpressibleAsConstantInitializer() const {
+ return !BoxingMethod && SubExpr;
+ }
+
+ SourceLocation getAtLoc() const { return Range.getBegin(); }
+
+ SourceLocation getBeginLoc() const LLVM_READONLY { return Range.getBegin(); }
+ SourceLocation getEndLoc() const LLVM_READONLY { return Range.getEnd(); }
+
+ SourceRange getSourceRange() const LLVM_READONLY {
+ return Range;
+ }
+
+ // Iterators
+ child_range children() { return child_range(&SubExpr, &SubExpr+1); }
+
+ const_child_range children() const {
+ return const_child_range(&SubExpr, &SubExpr + 1);
+ }
+
+ using const_arg_iterator = ConstExprIterator;
+
+ const_arg_iterator arg_begin() const {
+ return reinterpret_cast<Stmt const * const*>(&SubExpr);
+ }
+
+ const_arg_iterator arg_end() const {
+ return reinterpret_cast<Stmt const * const*>(&SubExpr + 1);
+ }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == ObjCBoxedExprClass;
+ }
+};
+
+/// ObjCArrayLiteral - used for objective-c array containers; as in:
+/// @[@"Hello", NSApp, [NSNumber numberWithInt:42]];
+class ObjCArrayLiteral final
+ : public Expr,
+ private llvm::TrailingObjects<ObjCArrayLiteral, Expr *> {
+ unsigned NumElements;
+ SourceRange Range;
+ ObjCMethodDecl *ArrayWithObjectsMethod;
+
+ ObjCArrayLiteral(ArrayRef<Expr *> Elements,
+ QualType T, ObjCMethodDecl * Method,
+ SourceRange SR);
+
+ explicit ObjCArrayLiteral(EmptyShell Empty, unsigned NumElements)
+ : Expr(ObjCArrayLiteralClass, Empty), NumElements(NumElements) {}
+
+public:
+ friend class ASTStmtReader;
+ friend TrailingObjects;
+
+ static ObjCArrayLiteral *Create(const ASTContext &C,
+ ArrayRef<Expr *> Elements,
+ QualType T, ObjCMethodDecl * Method,
+ SourceRange SR);
+
+ static ObjCArrayLiteral *CreateEmpty(const ASTContext &C,
+ unsigned NumElements);
+
+ SourceLocation getBeginLoc() const LLVM_READONLY { return Range.getBegin(); }
+ SourceLocation getEndLoc() const LLVM_READONLY { return Range.getEnd(); }
+ SourceRange getSourceRange() const LLVM_READONLY { return Range; }
+
+ /// Retrieve elements of array of literals.
+ Expr **getElements() { return getTrailingObjects<Expr *>(); }
+
+ /// Retrieve elements of array of literals.
+ const Expr * const *getElements() const {
+ return getTrailingObjects<Expr *>();
+ }
+
+ /// getNumElements - Return number of elements of objective-c array literal.
+ unsigned getNumElements() const { return NumElements; }
+
+ /// getElement - Return the Element at the specified index.
+ Expr *getElement(unsigned Index) {
+ assert((Index < NumElements) && "Arg access out of range!");
+ return getElements()[Index];
+ }
+ const Expr *getElement(unsigned Index) const {
+ assert((Index < NumElements) && "Arg access out of range!");
+ return getElements()[Index];
+ }
+
+ ObjCMethodDecl *getArrayWithObjectsMethod() const {
+ return ArrayWithObjectsMethod;
+ }
+
+ // Iterators
+ child_range children() {
+ return child_range(reinterpret_cast<Stmt **>(getElements()),
+ reinterpret_cast<Stmt **>(getElements()) + NumElements);
+ }
+
+ const_child_range children() const {
+ auto Children = const_cast<ObjCArrayLiteral *>(this)->children();
+ return const_child_range(Children.begin(), Children.end());
+ }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == ObjCArrayLiteralClass;
+ }
+};
+
+/// An element in an Objective-C dictionary literal.
+///
+struct ObjCDictionaryElement {
+ /// The key for the dictionary element.
+ Expr *Key;
+
+ /// The value of the dictionary element.
+ Expr *Value;
+
+ /// The location of the ellipsis, if this is a pack expansion.
+ SourceLocation EllipsisLoc;
+
+ /// The number of elements this pack expansion will expand to, if
+ /// this is a pack expansion and is known.
+ std::optional<unsigned> NumExpansions;
+
+ /// Determines whether this dictionary element is a pack expansion.
+ bool isPackExpansion() const { return EllipsisLoc.isValid(); }
+};
+
+} // namespace clang
+
+namespace clang {
+
+/// Internal struct for storing Key/value pair.
+struct ObjCDictionaryLiteral_KeyValuePair {
+ Expr *Key;
+ Expr *Value;
+};
+
+/// Internal struct to describes an element that is a pack
+/// expansion, used if any of the elements in the dictionary literal
+/// are pack expansions.
+struct ObjCDictionaryLiteral_ExpansionData {
+ /// The location of the ellipsis, if this element is a pack
+ /// expansion.
+ SourceLocation EllipsisLoc;
+
+ /// If non-zero, the number of elements that this pack
+ /// expansion will expand to (+1).
+ unsigned NumExpansionsPlusOne;
+};
+
+/// ObjCDictionaryLiteral - AST node to represent objective-c dictionary
+/// literals; as in: @{@"name" : NSUserName(), @"date" : [NSDate date] };
+class ObjCDictionaryLiteral final
+ : public Expr,
+ private llvm::TrailingObjects<ObjCDictionaryLiteral,
+ ObjCDictionaryLiteral_KeyValuePair,
+ ObjCDictionaryLiteral_ExpansionData> {
+ /// The number of elements in this dictionary literal.
+ unsigned NumElements : 31;
+
+ /// Determine whether this dictionary literal has any pack expansions.
+ ///
+ /// If the dictionary literal has pack expansions, then there will
+ /// be an array of pack expansion data following the array of
+ /// key/value pairs, which provide the locations of the ellipses (if
+ /// any) and number of elements in the expansion (if known). If
+ /// there are no pack expansions, we optimize away this storage.
+ unsigned HasPackExpansions : 1;
+
+ SourceRange Range;
+ ObjCMethodDecl *DictWithObjectsMethod;
+
+ using KeyValuePair = ObjCDictionaryLiteral_KeyValuePair;
+ using ExpansionData = ObjCDictionaryLiteral_ExpansionData;
+
+ ObjCDictionaryLiteral(ArrayRef<ObjCDictionaryElement> VK,
+ bool HasPackExpansions,
+ QualType T, ObjCMethodDecl *method,
+ SourceRange SR);
+
+ explicit ObjCDictionaryLiteral(EmptyShell Empty, unsigned NumElements,
+ bool HasPackExpansions)
+ : Expr(ObjCDictionaryLiteralClass, Empty), NumElements(NumElements),
+ HasPackExpansions(HasPackExpansions) {}
+
+ size_t numTrailingObjects(OverloadToken<KeyValuePair>) const {
+ return NumElements;
+ }
+
+public:
+ friend class ASTStmtReader;
+ friend class ASTStmtWriter;
+ friend TrailingObjects;
+
+ static ObjCDictionaryLiteral *Create(const ASTContext &C,
+ ArrayRef<ObjCDictionaryElement> VK,
+ bool HasPackExpansions,
+ QualType T, ObjCMethodDecl *method,
+ SourceRange SR);
+
+ static ObjCDictionaryLiteral *CreateEmpty(const ASTContext &C,
+ unsigned NumElements,
+ bool HasPackExpansions);
+
+ /// getNumElements - Return number of elements of objective-c dictionary
+ /// literal.
+ unsigned getNumElements() const { return NumElements; }
+
+ ObjCDictionaryElement getKeyValueElement(unsigned Index) const {
+ assert((Index < NumElements) && "Arg access out of range!");
+ const KeyValuePair &KV = getTrailingObjects<KeyValuePair>()[Index];
+ ObjCDictionaryElement Result = {KV.Key, KV.Value, SourceLocation(),
+ std::nullopt};
+ if (HasPackExpansions) {
+ const ExpansionData &Expansion =
+ getTrailingObjects<ExpansionData>()[Index];
+ Result.EllipsisLoc = Expansion.EllipsisLoc;
+ if (Expansion.NumExpansionsPlusOne > 0)
+ Result.NumExpansions = Expansion.NumExpansionsPlusOne - 1;
+ }
+ return Result;
+ }
+
+ ObjCMethodDecl *getDictWithObjectsMethod() const {
+ return DictWithObjectsMethod;
+ }
+
+ SourceLocation getBeginLoc() const LLVM_READONLY { return Range.getBegin(); }
+ SourceLocation getEndLoc() const LLVM_READONLY { return Range.getEnd(); }
+ SourceRange getSourceRange() const LLVM_READONLY { return Range; }
+
+ // Iterators
+ child_range children() {
+ // Note: we're taking advantage of the layout of the KeyValuePair struct
+ // here. If that struct changes, this code will need to change as well.
+ static_assert(sizeof(KeyValuePair) == sizeof(Stmt *) * 2,
+ "KeyValuePair is expected size");
+ return child_range(
+ reinterpret_cast<Stmt **>(getTrailingObjects<KeyValuePair>()),
+ reinterpret_cast<Stmt **>(getTrailingObjects<KeyValuePair>()) +
+ NumElements * 2);
+ }
+
+ const_child_range children() const {
+ auto Children = const_cast<ObjCDictionaryLiteral *>(this)->children();
+ return const_child_range(Children.begin(), Children.end());
+ }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == ObjCDictionaryLiteralClass;
+ }
+};
+
+/// ObjCEncodeExpr, used for \@encode in Objective-C. \@encode has the same
+/// type and behavior as StringLiteral except that the string initializer is
+/// obtained from ASTContext with the encoding type as an argument.
+class ObjCEncodeExpr : public Expr {
+ TypeSourceInfo *EncodedType;
+ SourceLocation AtLoc, RParenLoc;
+
+public:
+ ObjCEncodeExpr(QualType T, TypeSourceInfo *EncodedType, SourceLocation at,
+ SourceLocation rp)
+ : Expr(ObjCEncodeExprClass, T, VK_LValue, OK_Ordinary),
+ EncodedType(EncodedType), AtLoc(at), RParenLoc(rp) {
+ setDependence(computeDependence(this));
+ }
+
+ explicit ObjCEncodeExpr(EmptyShell Empty) : Expr(ObjCEncodeExprClass, Empty){}
+
+ SourceLocation getAtLoc() const { return AtLoc; }
+ void setAtLoc(SourceLocation L) { AtLoc = L; }
+ SourceLocation getRParenLoc() const { return RParenLoc; }
+ void setRParenLoc(SourceLocation L) { RParenLoc = L; }
+
+ QualType getEncodedType() const { return EncodedType->getType(); }
+
+ TypeSourceInfo *getEncodedTypeSourceInfo() const { return EncodedType; }
+
+ void setEncodedTypeSourceInfo(TypeSourceInfo *EncType) {
+ EncodedType = EncType;
+ }
+
+ SourceLocation getBeginLoc() const LLVM_READONLY { return AtLoc; }
+ SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }
+
+ // Iterators
+ child_range children() {
+ return child_range(child_iterator(), child_iterator());
+ }
+
+ const_child_range children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == ObjCEncodeExprClass;
+ }
+};
+
+/// ObjCSelectorExpr used for \@selector in Objective-C.
+class ObjCSelectorExpr : public Expr {
+ Selector SelName;
+ SourceLocation AtLoc, RParenLoc;
+
+public:
+ ObjCSelectorExpr(QualType T, Selector selInfo, SourceLocation at,
+ SourceLocation rp)
+ : Expr(ObjCSelectorExprClass, T, VK_PRValue, OK_Ordinary),
+ SelName(selInfo), AtLoc(at), RParenLoc(rp) {
+ setDependence(ExprDependence::None);
+ }
+ explicit ObjCSelectorExpr(EmptyShell Empty)
+ : Expr(ObjCSelectorExprClass, Empty) {}
+
+ Selector getSelector() const { return SelName; }
+ void setSelector(Selector S) { SelName = S; }
+
+ SourceLocation getAtLoc() const { return AtLoc; }
+ SourceLocation getRParenLoc() const { return RParenLoc; }
+ void setAtLoc(SourceLocation L) { AtLoc = L; }
+ void setRParenLoc(SourceLocation L) { RParenLoc = L; }
+
+ SourceLocation getBeginLoc() const LLVM_READONLY { return AtLoc; }
+ SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }
+
+ /// getNumArgs - Return the number of actual arguments to this call.
+ unsigned getNumArgs() const { return SelName.getNumArgs(); }
+
+ // Iterators
+ child_range children() {
+ return child_range(child_iterator(), child_iterator());
+ }
+
+ const_child_range children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == ObjCSelectorExprClass;
+ }
+};
+
+/// ObjCProtocolExpr used for protocol expression in Objective-C.
+///
+/// This is used as: \@protocol(foo), as in:
+/// \code
+/// [obj conformsToProtocol:@protocol(foo)]
+/// \endcode
+///
+/// The return type is "Protocol*".
+class ObjCProtocolExpr : public Expr {
+ ObjCProtocolDecl *TheProtocol;
+ SourceLocation AtLoc, ProtoLoc, RParenLoc;
+
+public:
+ friend class ASTStmtReader;
+ friend class ASTStmtWriter;
+
+ ObjCProtocolExpr(QualType T, ObjCProtocolDecl *protocol, SourceLocation at,
+ SourceLocation protoLoc, SourceLocation rp)
+ : Expr(ObjCProtocolExprClass, T, VK_PRValue, OK_Ordinary),
+ TheProtocol(protocol), AtLoc(at), ProtoLoc(protoLoc), RParenLoc(rp) {
+ setDependence(ExprDependence::None);
+ }
+ explicit ObjCProtocolExpr(EmptyShell Empty)
+ : Expr(ObjCProtocolExprClass, Empty) {}
+
+ ObjCProtocolDecl *getProtocol() const { return TheProtocol; }
+ void setProtocol(ObjCProtocolDecl *P) { TheProtocol = P; }
+
+ SourceLocation getProtocolIdLoc() const { return ProtoLoc; }
+ SourceLocation getAtLoc() const { return AtLoc; }
+ SourceLocation getRParenLoc() const { return RParenLoc; }
+ void setAtLoc(SourceLocation L) { AtLoc = L; }
+ void setRParenLoc(SourceLocation L) { RParenLoc = L; }
+
+ SourceLocation getBeginLoc() const LLVM_READONLY { return AtLoc; }
+ SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }
+
+ // Iterators
+ child_range children() {
+ return child_range(child_iterator(), child_iterator());
+ }
+
+ const_child_range children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == ObjCProtocolExprClass;
+ }
+};
+
+/// ObjCIvarRefExpr - A reference to an ObjC instance variable.
+class ObjCIvarRefExpr : public Expr {
+ ObjCIvarDecl *D;
+ Stmt *Base;
+ SourceLocation Loc;
+
+ /// OpLoc - This is the location of '.' or '->'
+ SourceLocation OpLoc;
+
+ // True if this is "X->F", false if this is "X.F".
+ bool IsArrow : 1;
+
+ // True if ivar reference has no base (self assumed).
+ bool IsFreeIvar : 1;
+
+public:
+ ObjCIvarRefExpr(ObjCIvarDecl *d, QualType t, SourceLocation l,
+ SourceLocation oploc, Expr *base, bool arrow = false,
+ bool freeIvar = false)
+ : Expr(ObjCIvarRefExprClass, t, VK_LValue,
+ d->isBitField() ? OK_BitField : OK_Ordinary),
+ D(d), Base(base), Loc(l), OpLoc(oploc), IsArrow(arrow),
+ IsFreeIvar(freeIvar) {
+ setDependence(computeDependence(this));
+ }
+
+ explicit ObjCIvarRefExpr(EmptyShell Empty)
+ : Expr(ObjCIvarRefExprClass, Empty) {}
+
+ ObjCIvarDecl *getDecl() { return D; }
+ const ObjCIvarDecl *getDecl() const { return D; }
+ void setDecl(ObjCIvarDecl *d) { D = d; }
+
+ const Expr *getBase() const { return cast<Expr>(Base); }
+ Expr *getBase() { return cast<Expr>(Base); }
+ void setBase(Expr * base) { Base = base; }
+
+ bool isArrow() const { return IsArrow; }
+ bool isFreeIvar() const { return IsFreeIvar; }
+ void setIsArrow(bool A) { IsArrow = A; }
+ void setIsFreeIvar(bool A) { IsFreeIvar = A; }
+
+ SourceLocation getLocation() const { return Loc; }
+ void setLocation(SourceLocation L) { Loc = L; }
+
+ SourceLocation getBeginLoc() const LLVM_READONLY {
+ return isFreeIvar() ? Loc : getBase()->getBeginLoc();
+ }
+ SourceLocation getEndLoc() const LLVM_READONLY { return Loc; }
+
+ SourceLocation getOpLoc() const { return OpLoc; }
+ void setOpLoc(SourceLocation L) { OpLoc = L; }
+
+ // Iterators
+ child_range children() { return child_range(&Base, &Base+1); }
+
+ const_child_range children() const {
+ return const_child_range(&Base, &Base + 1);
+ }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == ObjCIvarRefExprClass;
+ }
+};
+
+/// ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC
+/// property.
+class ObjCPropertyRefExpr : public Expr {
+private:
+ /// If the bool is true, this is an implicit property reference; the
+ /// pointer is an (optional) ObjCMethodDecl and Setter may be set.
+ /// if the bool is false, this is an explicit property reference;
+ /// the pointer is an ObjCPropertyDecl and Setter is always null.
+ llvm::PointerIntPair<NamedDecl *, 1, bool> PropertyOrGetter;
+
+ /// Indicates whether the property reference will result in a message
+ /// to the getter, the setter, or both.
+ /// This applies to both implicit and explicit property references.
+ enum MethodRefFlags {
+ MethodRef_None = 0,
+ MethodRef_Getter = 0x1,
+ MethodRef_Setter = 0x2
+ };
+
+ /// Contains the Setter method pointer and MethodRefFlags bit flags.
+ llvm::PointerIntPair<ObjCMethodDecl *, 2, unsigned> SetterAndMethodRefFlags;
+
+ // FIXME: Maybe we should store the property identifier here,
+ // because it's not rederivable from the other data when there's an
+ // implicit property with no getter (because the 'foo' -> 'setFoo:'
+ // transformation is lossy on the first character).
+
+ SourceLocation IdLoc;
+
+ /// When the receiver in property access is 'super', this is
+ /// the location of the 'super' keyword. When it's an interface,
+ /// this is that interface.
+ SourceLocation ReceiverLoc;
+ llvm::PointerUnion<Stmt *, const Type *, ObjCInterfaceDecl *> Receiver;
+
+public:
+ ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t, ExprValueKind VK,
+ ExprObjectKind OK, SourceLocation l, Expr *base)
+ : Expr(ObjCPropertyRefExprClass, t, VK, OK), PropertyOrGetter(PD, false),
+ IdLoc(l), Receiver(base) {
+ assert(t->isSpecificPlaceholderType(BuiltinType::PseudoObject));
+ setDependence(computeDependence(this));
+ }
+
+ ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t, ExprValueKind VK,
+ ExprObjectKind OK, SourceLocation l, SourceLocation sl,
+ QualType st)
+ : Expr(ObjCPropertyRefExprClass, t, VK, OK), PropertyOrGetter(PD, false),
+ IdLoc(l), ReceiverLoc(sl), Receiver(st.getTypePtr()) {
+ assert(t->isSpecificPlaceholderType(BuiltinType::PseudoObject));
+ setDependence(computeDependence(this));
+ }
+
+ ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter,
+ QualType T, ExprValueKind VK, ExprObjectKind OK,
+ SourceLocation IdLoc, Expr *Base)
+ : Expr(ObjCPropertyRefExprClass, T, VK, OK),
+ PropertyOrGetter(Getter, true), SetterAndMethodRefFlags(Setter, 0),
+ IdLoc(IdLoc), Receiver(Base) {
+ assert(T->isSpecificPlaceholderType(BuiltinType::PseudoObject));
+ setDependence(computeDependence(this));
+ }
+
+ ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter,
+ QualType T, ExprValueKind VK, ExprObjectKind OK,
+ SourceLocation IdLoc, SourceLocation SuperLoc,
+ QualType SuperTy)
+ : Expr(ObjCPropertyRefExprClass, T, VK, OK),
+ PropertyOrGetter(Getter, true), SetterAndMethodRefFlags(Setter, 0),
+ IdLoc(IdLoc), ReceiverLoc(SuperLoc), Receiver(SuperTy.getTypePtr()) {
+ assert(T->isSpecificPlaceholderType(BuiltinType::PseudoObject));
+ setDependence(computeDependence(this));
+ }
+
+ ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter,
+ QualType T, ExprValueKind VK, ExprObjectKind OK,
+ SourceLocation IdLoc, SourceLocation ReceiverLoc,
+ ObjCInterfaceDecl *Receiver)
+ : Expr(ObjCPropertyRefExprClass, T, VK, OK),
+ PropertyOrGetter(Getter, true), SetterAndMethodRefFlags(Setter, 0),
+ IdLoc(IdLoc), ReceiverLoc(ReceiverLoc), Receiver(Receiver) {
+ assert(T->isSpecificPlaceholderType(BuiltinType::PseudoObject));
+ setDependence(computeDependence(this));
+ }
+
+ explicit ObjCPropertyRefExpr(EmptyShell Empty)
+ : Expr(ObjCPropertyRefExprClass, Empty) {}
+
+ bool isImplicitProperty() const { return PropertyOrGetter.getInt(); }
+ bool isExplicitProperty() const { return !PropertyOrGetter.getInt(); }
+
+ ObjCPropertyDecl *getExplicitProperty() const {
+ assert(!isImplicitProperty());
+ return cast<ObjCPropertyDecl>(PropertyOrGetter.getPointer());
+ }
+
+ ObjCMethodDecl *getImplicitPropertyGetter() const {
+ assert(isImplicitProperty());
+ return cast_or_null<ObjCMethodDecl>(PropertyOrGetter.getPointer());
+ }
+
+ ObjCMethodDecl *getImplicitPropertySetter() const {
+ assert(isImplicitProperty());
+ return SetterAndMethodRefFlags.getPointer();
+ }
+
+ Selector getGetterSelector() const {
+ if (isImplicitProperty())
+ return getImplicitPropertyGetter()->getSelector();
+ return getExplicitProperty()->getGetterName();
+ }
+
+ Selector getSetterSelector() const {
+ if (isImplicitProperty())
+ return getImplicitPropertySetter()->getSelector();
+ return getExplicitProperty()->getSetterName();
+ }
+
+ /// True if the property reference will result in a message to the
+ /// getter.
+ /// This applies to both implicit and explicit property references.
+ bool isMessagingGetter() const {
+ return SetterAndMethodRefFlags.getInt() & MethodRef_Getter;
+ }
+
+ /// True if the property reference will result in a message to the
+ /// setter.
+ /// This applies to both implicit and explicit property references.
+ bool isMessagingSetter() const {
+ return SetterAndMethodRefFlags.getInt() & MethodRef_Setter;
+ }
+
+ void setIsMessagingGetter(bool val = true) {
+ setMethodRefFlag(MethodRef_Getter, val);
+ }
+
+ void setIsMessagingSetter(bool val = true) {
+ setMethodRefFlag(MethodRef_Setter, val);
+ }
+
+ const Expr *getBase() const {
+ return cast<Expr>(Receiver.get<Stmt*>());
+ }
+ Expr *getBase() {
+ return cast<Expr>(Receiver.get<Stmt*>());
+ }
+
+ SourceLocation getLocation() const { return IdLoc; }
+
+ SourceLocation getReceiverLocation() const { return ReceiverLoc; }
+
+ QualType getSuperReceiverType() const {
+ return QualType(Receiver.get<const Type*>(), 0);
+ }
+
+ ObjCInterfaceDecl *getClassReceiver() const {
+ return Receiver.get<ObjCInterfaceDecl*>();
+ }
+
+ bool isObjectReceiver() const { return Receiver.is<Stmt*>(); }
+ bool isSuperReceiver() const { return Receiver.is<const Type*>(); }
+ bool isClassReceiver() const { return Receiver.is<ObjCInterfaceDecl*>(); }
+
+ /// Determine the type of the base, regardless of the kind of receiver.
+ QualType getReceiverType(const ASTContext &ctx) const;
+
+ SourceLocation getBeginLoc() const LLVM_READONLY {
+ return isObjectReceiver() ? getBase()->getBeginLoc()
+ : getReceiverLocation();
+ }
+
+ SourceLocation getEndLoc() const LLVM_READONLY { return IdLoc; }
+
+ // Iterators
+ child_range children() {
+ if (Receiver.is<Stmt*>()) {
+ Stmt **begin = reinterpret_cast<Stmt**>(&Receiver); // hack!
+ return child_range(begin, begin+1);
+ }
+ return child_range(child_iterator(), child_iterator());
+ }
+
+ const_child_range children() const {
+ auto Children = const_cast<ObjCPropertyRefExpr *>(this)->children();
+ return const_child_range(Children.begin(), Children.end());
+ }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == ObjCPropertyRefExprClass;
+ }
+
+private:
+ friend class ASTStmtReader;
+ friend class ASTStmtWriter;
+
+ void setExplicitProperty(ObjCPropertyDecl *D, unsigned methRefFlags) {
+ PropertyOrGetter.setPointer(D);
+ PropertyOrGetter.setInt(false);
+ SetterAndMethodRefFlags.setPointer(nullptr);
+ SetterAndMethodRefFlags.setInt(methRefFlags);
+ }
+
+ void setImplicitProperty(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter,
+ unsigned methRefFlags) {
+ PropertyOrGetter.setPointer(Getter);
+ PropertyOrGetter.setInt(true);
+ SetterAndMethodRefFlags.setPointer(Setter);
+ SetterAndMethodRefFlags.setInt(methRefFlags);
+ }
+
+ void setBase(Expr *Base) { Receiver = Base; }
+ void setSuperReceiver(QualType T) { Receiver = T.getTypePtr(); }
+ void setClassReceiver(ObjCInterfaceDecl *D) { Receiver = D; }
+
+ void setLocation(SourceLocation L) { IdLoc = L; }
+ void setReceiverLocation(SourceLocation Loc) { ReceiverLoc = Loc; }
+
+ void setMethodRefFlag(MethodRefFlags flag, bool val) {
+ unsigned f = SetterAndMethodRefFlags.getInt();
+ if (val)
+ f |= flag;
+ else
+ f &= ~flag;
+ SetterAndMethodRefFlags.setInt(f);
+ }
+};
+
+/// ObjCSubscriptRefExpr - used for array and dictionary subscripting.
+/// array[4] = array[3]; dictionary[key] = dictionary[alt_key];
+class ObjCSubscriptRefExpr : public Expr {
+ // Location of ']' in an indexing expression.
+ SourceLocation RBracket;
+
+ // array/dictionary base expression.
+ // for arrays, this is a numeric expression. For dictionaries, this is
+ // an objective-c object pointer expression.
+ enum { BASE, KEY, END_EXPR };
+ Stmt* SubExprs[END_EXPR];
+
+ ObjCMethodDecl *GetAtIndexMethodDecl;
+
+ // For immutable objects this is null. When ObjCSubscriptRefExpr is to read
+ // an indexed object this is null too.
+ ObjCMethodDecl *SetAtIndexMethodDecl;
+
+public:
+ ObjCSubscriptRefExpr(Expr *base, Expr *key, QualType T, ExprValueKind VK,
+ ExprObjectKind OK, ObjCMethodDecl *getMethod,
+ ObjCMethodDecl *setMethod, SourceLocation RB)
+ : Expr(ObjCSubscriptRefExprClass, T, VK, OK), RBracket(RB),
+ GetAtIndexMethodDecl(getMethod), SetAtIndexMethodDecl(setMethod) {
+ SubExprs[BASE] = base;
+ SubExprs[KEY] = key;
+ setDependence(computeDependence(this));
+ }
+
+ explicit ObjCSubscriptRefExpr(EmptyShell Empty)
+ : Expr(ObjCSubscriptRefExprClass, Empty) {}
+
+ SourceLocation getRBracket() const { return RBracket; }
+ void setRBracket(SourceLocation RB) { RBracket = RB; }
+
+ SourceLocation getBeginLoc() const LLVM_READONLY {
+ return SubExprs[BASE]->getBeginLoc();
+ }
+
+ SourceLocation getEndLoc() const LLVM_READONLY { return RBracket; }
+
+ Expr *getBaseExpr() const { return cast<Expr>(SubExprs[BASE]); }
+ void setBaseExpr(Stmt *S) { SubExprs[BASE] = S; }
+
+ Expr *getKeyExpr() const { return cast<Expr>(SubExprs[KEY]); }
+ void setKeyExpr(Stmt *S) { SubExprs[KEY] = S; }
+
+ ObjCMethodDecl *getAtIndexMethodDecl() const {
+ return GetAtIndexMethodDecl;
+ }
+
+ ObjCMethodDecl *setAtIndexMethodDecl() const {
+ return SetAtIndexMethodDecl;
+ }
+
+ bool isArraySubscriptRefExpr() const {
+ return getKeyExpr()->getType()->isIntegralOrEnumerationType();
+ }
+
+ child_range children() {
+ return child_range(SubExprs, SubExprs+END_EXPR);
+ }
+
+ const_child_range children() const {
+ return const_child_range(SubExprs, SubExprs + END_EXPR);
+ }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == ObjCSubscriptRefExprClass;
+ }
+
+private:
+ friend class ASTStmtReader;
+};
+
+/// An expression that sends a message to the given Objective-C
+/// object or class.
+///
+/// The following contains two message send expressions:
+///
+/// \code
+/// [[NSString alloc] initWithString:@"Hello"]
+/// \endcode
+///
+/// The innermost message send invokes the "alloc" class method on the
+/// NSString class, while the outermost message send invokes the
+/// "initWithString" instance method on the object returned from
+/// NSString's "alloc". In all, an Objective-C message send can take
+/// on four different (although related) forms:
+///
+/// 1. Send to an object instance.
+/// 2. Send to a class.
+/// 3. Send to the superclass instance of the current class.
+/// 4. Send to the superclass of the current class.
+///
+/// All four kinds of message sends are modeled by the ObjCMessageExpr
+/// class, and can be distinguished via \c getReceiverKind(). Example:
+///
+/// The "void *" trailing objects are actually ONE void * (the
+/// receiver pointer), and NumArgs Expr *. But due to the
+/// implementation of children(), these must be together contiguously.
+class ObjCMessageExpr final
+ : public Expr,
+ private llvm::TrailingObjects<ObjCMessageExpr, void *, SourceLocation> {
+ /// Stores either the selector that this message is sending
+ /// to (when \c HasMethod is zero) or an \c ObjCMethodDecl pointer
+ /// referring to the method that we type-checked against.
+ uintptr_t SelectorOrMethod = 0;
+
+ enum { NumArgsBitWidth = 16 };
+
+ /// The number of arguments in the message send, not
+ /// including the receiver.
+ unsigned NumArgs : NumArgsBitWidth;
+
+ /// The kind of message send this is, which is one of the
+ /// ReceiverKind values.
+ ///
+ /// We pad this out to a byte to avoid excessive masking and shifting.
+ unsigned Kind : 8;
+
+ /// Whether we have an actual method prototype in \c
+ /// SelectorOrMethod.
+ ///
+ /// When non-zero, we have a method declaration; otherwise, we just
+ /// have a selector.
+ unsigned HasMethod : 1;
+
+ /// Whether this message send is a "delegate init call",
+ /// i.e. a call of an init method on self from within an init method.
+ unsigned IsDelegateInitCall : 1;
+
+ /// Whether this message send was implicitly generated by
+ /// the implementation rather than explicitly written by the user.
+ unsigned IsImplicit : 1;
+
+ /// Whether the locations of the selector identifiers are in a
+ /// "standard" position, a enum SelectorLocationsKind.
+ unsigned SelLocsKind : 2;
+
+ /// When the message expression is a send to 'super', this is
+ /// the location of the 'super' keyword.
+ SourceLocation SuperLoc;
+
+ /// The source locations of the open and close square
+ /// brackets ('[' and ']', respectively).
+ SourceLocation LBracLoc, RBracLoc;
+
+ ObjCMessageExpr(EmptyShell Empty, unsigned NumArgs)
+ : Expr(ObjCMessageExprClass, Empty), Kind(0), HasMethod(false),
+ IsDelegateInitCall(false), IsImplicit(false), SelLocsKind(0) {
+ setNumArgs(NumArgs);
+ }
+
+ ObjCMessageExpr(QualType T, ExprValueKind VK,
+ SourceLocation LBracLoc,
+ SourceLocation SuperLoc,
+ bool IsInstanceSuper,
+ QualType SuperType,
+ Selector Sel,
+ ArrayRef<SourceLocation> SelLocs,
+ SelectorLocationsKind SelLocsK,
+ ObjCMethodDecl *Method,
+ ArrayRef<Expr *> Args,
+ SourceLocation RBracLoc,
+ bool isImplicit);
+ ObjCMessageExpr(QualType T, ExprValueKind VK,
+ SourceLocation LBracLoc,
+ TypeSourceInfo *Receiver,
+ Selector Sel,
+ ArrayRef<SourceLocation> SelLocs,
+ SelectorLocationsKind SelLocsK,
+ ObjCMethodDecl *Method,
+ ArrayRef<Expr *> Args,
+ SourceLocation RBracLoc,
+ bool isImplicit);
+ ObjCMessageExpr(QualType T, ExprValueKind VK,
+ SourceLocation LBracLoc,
+ Expr *Receiver,
+ Selector Sel,
+ ArrayRef<SourceLocation> SelLocs,
+ SelectorLocationsKind SelLocsK,
+ ObjCMethodDecl *Method,
+ ArrayRef<Expr *> Args,
+ SourceLocation RBracLoc,
+ bool isImplicit);
+
+ size_t numTrailingObjects(OverloadToken<void *>) const { return NumArgs + 1; }
+
+ void setNumArgs(unsigned Num) {
+ assert((Num >> NumArgsBitWidth) == 0 && "Num of args is out of range!");
+ NumArgs = Num;
+ }
+
+ void initArgsAndSelLocs(ArrayRef<Expr *> Args,
+ ArrayRef<SourceLocation> SelLocs,
+ SelectorLocationsKind SelLocsK);
+
+ /// Retrieve the pointer value of the message receiver.
+ void *getReceiverPointer() const { return *getTrailingObjects<void *>(); }
+
+ /// Set the pointer value of the message receiver.
+ void setReceiverPointer(void *Value) {
+ *getTrailingObjects<void *>() = Value;
+ }
+
+ SelectorLocationsKind getSelLocsKind() const {
+ return (SelectorLocationsKind)SelLocsKind;
+ }
+
+ bool hasStandardSelLocs() const {
+ return getSelLocsKind() != SelLoc_NonStandard;
+ }
+
+ /// Get a pointer to the stored selector identifiers locations array.
+ /// No locations will be stored if HasStandardSelLocs is true.
+ SourceLocation *getStoredSelLocs() {
+ return getTrailingObjects<SourceLocation>();
+ }
+ const SourceLocation *getStoredSelLocs() const {
+ return getTrailingObjects<SourceLocation>();
+ }
+
+ /// Get the number of stored selector identifiers locations.
+ /// No locations will be stored if HasStandardSelLocs is true.
+ unsigned getNumStoredSelLocs() const {
+ if (hasStandardSelLocs())
+ return 0;
+ return getNumSelectorLocs();
+ }
+
+ static ObjCMessageExpr *alloc(const ASTContext &C,
+ ArrayRef<Expr *> Args,
+ SourceLocation RBraceLoc,
+ ArrayRef<SourceLocation> SelLocs,
+ Selector Sel,
+ SelectorLocationsKind &SelLocsK);
+ static ObjCMessageExpr *alloc(const ASTContext &C,
+ unsigned NumArgs,
+ unsigned NumStoredSelLocs);
+
+public:
+ friend class ASTStmtReader;
+ friend class ASTStmtWriter;
+ friend TrailingObjects;
+
+ /// The kind of receiver this message is sending to.
+ enum ReceiverKind {
+ /// The receiver is a class.
+ Class = 0,
+
+ /// The receiver is an object instance.
+ Instance,
+
+ /// The receiver is a superclass.
+ SuperClass,
+
+ /// The receiver is the instance of the superclass object.
+ SuperInstance
+ };
+
+ /// Create a message send to super.
+ ///
+ /// \param Context The ASTContext in which this expression will be created.
+ ///
+ /// \param T The result type of this message.
+ ///
+ /// \param VK The value kind of this message. A message returning
+ /// a l-value or r-value reference will be an l-value or x-value,
+ /// respectively.
+ ///
+ /// \param LBracLoc The location of the open square bracket '['.
+ ///
+ /// \param SuperLoc The location of the "super" keyword.
+ ///
+ /// \param IsInstanceSuper Whether this is an instance "super"
+ /// message (otherwise, it's a class "super" message).
+ ///
+ /// \param Sel The selector used to determine which method gets called.
+ ///
+ /// \param Method The Objective-C method against which this message
+ /// send was type-checked. May be nullptr.
+ ///
+ /// \param Args The message send arguments.
+ ///
+ /// \param RBracLoc The location of the closing square bracket ']'.
+ static ObjCMessageExpr *Create(const ASTContext &Context, QualType T,
+ ExprValueKind VK,
+ SourceLocation LBracLoc,
+ SourceLocation SuperLoc,
+ bool IsInstanceSuper,
+ QualType SuperType,
+ Selector Sel,
+ ArrayRef<SourceLocation> SelLocs,
+ ObjCMethodDecl *Method,
+ ArrayRef<Expr *> Args,
+ SourceLocation RBracLoc,
+ bool isImplicit);
+
+ /// Create a class message send.
+ ///
+ /// \param Context The ASTContext in which this expression will be created.
+ ///
+ /// \param T The result type of this message.
+ ///
+ /// \param VK The value kind of this message. A message returning
+ /// a l-value or r-value reference will be an l-value or x-value,
+ /// respectively.
+ ///
+ /// \param LBracLoc The location of the open square bracket '['.
+ ///
+ /// \param Receiver The type of the receiver, including
+ /// source-location information.
+ ///
+ /// \param Sel The selector used to determine which method gets called.
+ ///
+ /// \param Method The Objective-C method against which this message
+ /// send was type-checked. May be nullptr.
+ ///
+ /// \param Args The message send arguments.
+ ///
+ /// \param RBracLoc The location of the closing square bracket ']'.
+ static ObjCMessageExpr *Create(const ASTContext &Context, QualType T,
+ ExprValueKind VK,
+ SourceLocation LBracLoc,
+ TypeSourceInfo *Receiver,
+ Selector Sel,
+ ArrayRef<SourceLocation> SelLocs,
+ ObjCMethodDecl *Method,
+ ArrayRef<Expr *> Args,
+ SourceLocation RBracLoc,
+ bool isImplicit);
+
+ /// Create an instance message send.
+ ///
+ /// \param Context The ASTContext in which this expression will be created.
+ ///
+ /// \param T The result type of this message.
+ ///
+ /// \param VK The value kind of this message. A message returning
+ /// a l-value or r-value reference will be an l-value or x-value,
+ /// respectively.
+ ///
+ /// \param LBracLoc The location of the open square bracket '['.
+ ///
+ /// \param Receiver The expression used to produce the object that
+ /// will receive this message.
+ ///
+ /// \param Sel The selector used to determine which method gets called.
+ ///
+ /// \param Method The Objective-C method against which this message
+ /// send was type-checked. May be nullptr.
+ ///
+ /// \param Args The message send arguments.
+ ///
+ /// \param RBracLoc The location of the closing square bracket ']'.
+ static ObjCMessageExpr *Create(const ASTContext &Context, QualType T,
+ ExprValueKind VK,
+ SourceLocation LBracLoc,
+ Expr *Receiver,
+ Selector Sel,
+ ArrayRef<SourceLocation> SeLocs,
+ ObjCMethodDecl *Method,
+ ArrayRef<Expr *> Args,
+ SourceLocation RBracLoc,
+ bool isImplicit);
+
+ /// Create an empty Objective-C message expression, to be
+ /// filled in by subsequent calls.
+ ///
+ /// \param Context The context in which the message send will be created.
+ ///
+ /// \param NumArgs The number of message arguments, not including
+ /// the receiver.
+ static ObjCMessageExpr *CreateEmpty(const ASTContext &Context,
+ unsigned NumArgs,
+ unsigned NumStoredSelLocs);
+
+ /// Indicates whether the message send was implicitly
+ /// generated by the implementation. If false, it was written explicitly
+ /// in the source code.
+ bool isImplicit() const { return IsImplicit; }
+
+ /// Determine the kind of receiver that this message is being
+ /// sent to.
+ ReceiverKind getReceiverKind() const { return (ReceiverKind)Kind; }
+
+ /// \return the return type of the message being sent.
+ /// This is not always the type of the message expression itself because
+ /// of references (the expression would not have a reference type).
+ /// It is also not always the declared return type of the method because
+ /// of `instancetype` (in that case it's an expression type).
+ QualType getCallReturnType(ASTContext &Ctx) const;
+
+ /// Source range of the receiver.
+ SourceRange getReceiverRange() const;
+
+ /// Determine whether this is an instance message to either a
+ /// computed object or to super.
+ bool isInstanceMessage() const {
+ return getReceiverKind() == Instance || getReceiverKind() == SuperInstance;
+ }
+
+ /// Determine whether this is an class message to either a
+ /// specified class or to super.
+ bool isClassMessage() const {
+ return getReceiverKind() == Class || getReceiverKind() == SuperClass;
+ }
+
+ /// Returns the object expression (receiver) for an instance message,
+ /// or null for a message that is not an instance message.
+ Expr *getInstanceReceiver() {
+ if (getReceiverKind() == Instance)
+ return static_cast<Expr *>(getReceiverPointer());
+
+ return nullptr;
+ }
+ const Expr *getInstanceReceiver() const {
+ return const_cast<ObjCMessageExpr*>(this)->getInstanceReceiver();
+ }
+
+ /// Turn this message send into an instance message that
+ /// computes the receiver object with the given expression.
+ void setInstanceReceiver(Expr *rec) {
+ Kind = Instance;
+ setReceiverPointer(rec);
+ }
+
+ /// Returns the type of a class message send, or NULL if the
+ /// message is not a class message.
+ QualType getClassReceiver() const {
+ if (TypeSourceInfo *TSInfo = getClassReceiverTypeInfo())
+ return TSInfo->getType();
+
+ return {};
+ }
+
+ /// Returns a type-source information of a class message
+ /// send, or nullptr if the message is not a class message.
+ TypeSourceInfo *getClassReceiverTypeInfo() const {
+ if (getReceiverKind() == Class)
+ return reinterpret_cast<TypeSourceInfo *>(getReceiverPointer());
+ return nullptr;
+ }
+
+ void setClassReceiver(TypeSourceInfo *TSInfo) {
+ Kind = Class;
+ setReceiverPointer(TSInfo);
+ }
+
+ /// Retrieve the location of the 'super' keyword for a class
+ /// or instance message to 'super', otherwise an invalid source location.
+ SourceLocation getSuperLoc() const {
+ if (getReceiverKind() == SuperInstance || getReceiverKind() == SuperClass)
+ return SuperLoc;
+
+ return SourceLocation();
+ }
+
+ /// Retrieve the receiver type to which this message is being directed.
+ ///
+ /// This routine cross-cuts all of the different kinds of message
+ /// sends to determine what the underlying (statically known) type
+ /// of the receiver will be; use \c getReceiverKind() to determine
+ /// whether the message is a class or an instance method, whether it
+ /// is a send to super or not, etc.
+ ///
+ /// \returns The type of the receiver.
+ QualType getReceiverType() const;
+
+ /// Retrieve the Objective-C interface to which this message
+ /// is being directed, if known.
+ ///
+ /// This routine cross-cuts all of the different kinds of message
+ /// sends to determine what the underlying (statically known) type
+ /// of the receiver will be; use \c getReceiverKind() to determine
+ /// whether the message is a class or an instance method, whether it
+ /// is a send to super or not, etc.
+ ///
+ /// \returns The Objective-C interface if known, otherwise nullptr.
+ ObjCInterfaceDecl *getReceiverInterface() const;
+
+ /// Retrieve the type referred to by 'super'.
+ ///
+ /// The returned type will either be an ObjCInterfaceType (for an
+ /// class message to super) or an ObjCObjectPointerType that refers
+ /// to a class (for an instance message to super);
+ QualType getSuperType() const {
+ if (getReceiverKind() == SuperInstance || getReceiverKind() == SuperClass)
+ return QualType::getFromOpaquePtr(getReceiverPointer());
+
+ return QualType();
+ }
+
+ void setSuper(SourceLocation Loc, QualType T, bool IsInstanceSuper) {
+ Kind = IsInstanceSuper? SuperInstance : SuperClass;
+ SuperLoc = Loc;
+ setReceiverPointer(T.getAsOpaquePtr());
+ }
+
+ Selector getSelector() const;
+
+ void setSelector(Selector S) {
+ HasMethod = false;
+ SelectorOrMethod = reinterpret_cast<uintptr_t>(S.getAsOpaquePtr());
+ }
+
+ const ObjCMethodDecl *getMethodDecl() const {
+ if (HasMethod)
+ return reinterpret_cast<const ObjCMethodDecl *>(SelectorOrMethod);
+
+ return nullptr;
+ }
+
+ ObjCMethodDecl *getMethodDecl() {
+ if (HasMethod)
+ return reinterpret_cast<ObjCMethodDecl *>(SelectorOrMethod);
+
+ return nullptr;
+ }
+
+ void setMethodDecl(ObjCMethodDecl *MD) {
+ HasMethod = true;
+ SelectorOrMethod = reinterpret_cast<uintptr_t>(MD);
+ }
+
+ ObjCMethodFamily getMethodFamily() const {
+ if (HasMethod) return getMethodDecl()->getMethodFamily();
+ return getSelector().getMethodFamily();
+ }
+
+ /// Return the number of actual arguments in this message,
+ /// not counting the receiver.
+ unsigned getNumArgs() const { return NumArgs; }
+
+ /// Retrieve the arguments to this message, not including the
+ /// receiver.
+ Expr **getArgs() {
+ return reinterpret_cast<Expr **>(getTrailingObjects<void *>() + 1);
+ }
+ const Expr * const *getArgs() const {
+ return reinterpret_cast<const Expr *const *>(getTrailingObjects<void *>() +
+ 1);
+ }
+
+ /// getArg - Return the specified argument.
+ Expr *getArg(unsigned Arg) {
+ assert(Arg < NumArgs && "Arg access out of range!");
+ return getArgs()[Arg];
+ }
+ const Expr *getArg(unsigned Arg) const {
+ assert(Arg < NumArgs && "Arg access out of range!");
+ return getArgs()[Arg];
+ }
+
+ /// setArg - Set the specified argument.
+ void setArg(unsigned Arg, Expr *ArgExpr) {
+ assert(Arg < NumArgs && "Arg access out of range!");
+ getArgs()[Arg] = ArgExpr;
+ }
+
+ /// isDelegateInitCall - Answers whether this message send has been
+ /// tagged as a "delegate init call", i.e. a call to a method in the
+ /// -init family on self from within an -init method implementation.
+ bool isDelegateInitCall() const { return IsDelegateInitCall; }
+ void setDelegateInitCall(bool isDelegate) { IsDelegateInitCall = isDelegate; }
+
+ SourceLocation getLeftLoc() const { return LBracLoc; }
+ SourceLocation getRightLoc() const { return RBracLoc; }
+
+ SourceLocation getSelectorStartLoc() const {
+ if (isImplicit())
+ return getBeginLoc();
+ return getSelectorLoc(0);
+ }
+
+ SourceLocation getSelectorLoc(unsigned Index) const {
+ assert(Index < getNumSelectorLocs() && "Index out of range!");
+ if (hasStandardSelLocs())
+ return getStandardSelectorLoc(
+ Index, getSelector(), getSelLocsKind() == SelLoc_StandardWithSpace,
+ llvm::ArrayRef(const_cast<Expr **>(getArgs()), getNumArgs()),
+ RBracLoc);
+ return getStoredSelLocs()[Index];
+ }
+
+ void getSelectorLocs(SmallVectorImpl<SourceLocation> &SelLocs) const;
+
+ unsigned getNumSelectorLocs() const {
+ if (isImplicit())
+ return 0;
+ Selector Sel = getSelector();
+ if (Sel.isUnarySelector())
+ return 1;
+ return Sel.getNumArgs();
+ }
+
+ void setSourceRange(SourceRange R) {
+ LBracLoc = R.getBegin();
+ RBracLoc = R.getEnd();
+ }
+
+ SourceLocation getBeginLoc() const LLVM_READONLY { return LBracLoc; }
+ SourceLocation getEndLoc() const LLVM_READONLY { return RBracLoc; }
+
+ // Iterators
+ child_range children();
+
+ const_child_range children() const;
+
+ using arg_iterator = ExprIterator;
+ using const_arg_iterator = ConstExprIterator;
+
+ llvm::iterator_range<arg_iterator> arguments() {
+ return llvm::make_range(arg_begin(), arg_end());
+ }
+
+ llvm::iterator_range<const_arg_iterator> arguments() const {
+ return llvm::make_range(arg_begin(), arg_end());
+ }
+
+ arg_iterator arg_begin() { return reinterpret_cast<Stmt **>(getArgs()); }
+
+ arg_iterator arg_end() {
+ return reinterpret_cast<Stmt **>(getArgs() + NumArgs);
+ }
+
+ const_arg_iterator arg_begin() const {
+ return reinterpret_cast<Stmt const * const*>(getArgs());
+ }
+
+ const_arg_iterator arg_end() const {
+ return reinterpret_cast<Stmt const * const*>(getArgs() + NumArgs);
+ }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == ObjCMessageExprClass;
+ }
+};
+
+/// ObjCIsaExpr - Represent X->isa and X.isa when X is an ObjC 'id' type.
+/// (similar in spirit to MemberExpr).
+class ObjCIsaExpr : public Expr {
+ /// Base - the expression for the base object pointer.
+ Stmt *Base;
+
+ /// IsaMemberLoc - This is the location of the 'isa'.
+ SourceLocation IsaMemberLoc;
+
+ /// OpLoc - This is the location of '.' or '->'
+ SourceLocation OpLoc;
+
+ /// IsArrow - True if this is "X->F", false if this is "X.F".
+ bool IsArrow;
+
+public:
+ ObjCIsaExpr(Expr *base, bool isarrow, SourceLocation l, SourceLocation oploc,
+ QualType ty)
+ : Expr(ObjCIsaExprClass, ty, VK_LValue, OK_Ordinary), Base(base),
+ IsaMemberLoc(l), OpLoc(oploc), IsArrow(isarrow) {
+ setDependence(computeDependence(this));
+ }
+
+ /// Build an empty expression.
+ explicit ObjCIsaExpr(EmptyShell Empty) : Expr(ObjCIsaExprClass, Empty) {}
+
+ void setBase(Expr *E) { Base = E; }
+ Expr *getBase() const { return cast<Expr>(Base); }
+
+ bool isArrow() const { return IsArrow; }
+ void setArrow(bool A) { IsArrow = A; }
+
+ /// getMemberLoc - Return the location of the "member", in X->F, it is the
+ /// location of 'F'.
+ SourceLocation getIsaMemberLoc() const { return IsaMemberLoc; }
+ void setIsaMemberLoc(SourceLocation L) { IsaMemberLoc = L; }
+
+ SourceLocation getOpLoc() const { return OpLoc; }
+ void setOpLoc(SourceLocation L) { OpLoc = L; }
+
+ SourceLocation getBeginLoc() const LLVM_READONLY {
+ return getBase()->getBeginLoc();
+ }
+
+ SourceLocation getBaseLocEnd() const LLVM_READONLY {
+ return getBase()->getEndLoc();
+ }
+
+ SourceLocation getEndLoc() const LLVM_READONLY { return IsaMemberLoc; }
+
+ SourceLocation getExprLoc() const LLVM_READONLY { return IsaMemberLoc; }
+
+ // Iterators
+ child_range children() { return child_range(&Base, &Base+1); }
+
+ const_child_range children() const {
+ return const_child_range(&Base, &Base + 1);
+ }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == ObjCIsaExprClass;
+ }
+};
+
+/// ObjCIndirectCopyRestoreExpr - Represents the passing of a function
+/// argument by indirect copy-restore in ARC. This is used to support
+/// passing indirect arguments with the wrong lifetime, e.g. when
+/// passing the address of a __strong local variable to an 'out'
+/// parameter. This expression kind is only valid in an "argument"
+/// position to some sort of call expression.
+///
+/// The parameter must have type 'pointer to T', and the argument must
+/// have type 'pointer to U', where T and U agree except possibly in
+/// qualification. If the argument value is null, then a null pointer
+/// is passed; otherwise it points to an object A, and:
+/// 1. A temporary object B of type T is initialized, either by
+/// zero-initialization (used when initializing an 'out' parameter)
+/// or copy-initialization (used when initializing an 'inout'
+/// parameter).
+/// 2. The address of the temporary is passed to the function.
+/// 3. If the call completes normally, A is move-assigned from B.
+/// 4. Finally, A is destroyed immediately.
+///
+/// Currently 'T' must be a retainable object lifetime and must be
+/// __autoreleasing; this qualifier is ignored when initializing
+/// the value.
+class ObjCIndirectCopyRestoreExpr : public Expr {
+ friend class ASTReader;
+ friend class ASTStmtReader;
+
+ Stmt *Operand;
+
+ // unsigned ObjCIndirectCopyRestoreBits.ShouldCopy : 1;
+
+ explicit ObjCIndirectCopyRestoreExpr(EmptyShell Empty)
+ : Expr(ObjCIndirectCopyRestoreExprClass, Empty) {}
+
+ void setShouldCopy(bool shouldCopy) {
+ ObjCIndirectCopyRestoreExprBits.ShouldCopy = shouldCopy;
+ }
+
+public:
+ ObjCIndirectCopyRestoreExpr(Expr *operand, QualType type, bool shouldCopy)
+ : Expr(ObjCIndirectCopyRestoreExprClass, type, VK_LValue, OK_Ordinary),
+ Operand(operand) {
+ setShouldCopy(shouldCopy);
+ setDependence(computeDependence(this));
+ }
+
+ Expr *getSubExpr() { return cast<Expr>(Operand); }
+ const Expr *getSubExpr() const { return cast<Expr>(Operand); }
+
+ /// shouldCopy - True if we should do the 'copy' part of the
+ /// copy-restore. If false, the temporary will be zero-initialized.
+ bool shouldCopy() const { return ObjCIndirectCopyRestoreExprBits.ShouldCopy; }
+
+ child_range children() { return child_range(&Operand, &Operand+1); }
+
+ const_child_range children() const {
+ return const_child_range(&Operand, &Operand + 1);
+ }
+
+ // Source locations are determined by the subexpression.
+ SourceLocation getBeginLoc() const LLVM_READONLY {
+ return Operand->getBeginLoc();
+ }
+ SourceLocation getEndLoc() const LLVM_READONLY {
+ return Operand->getEndLoc();
+ }
+
+ SourceLocation getExprLoc() const LLVM_READONLY {
+ return getSubExpr()->getExprLoc();
+ }
+
+ static bool classof(const Stmt *s) {
+ return s->getStmtClass() == ObjCIndirectCopyRestoreExprClass;
+ }
+};
+
+/// An Objective-C "bridged" cast expression, which casts between
+/// Objective-C pointers and C pointers, transferring ownership in the process.
+///
+/// \code
+/// NSString *str = (__bridge_transfer NSString *)CFCreateString();
+/// \endcode
+class ObjCBridgedCastExpr final
+ : public ExplicitCastExpr,
+ private llvm::TrailingObjects<ObjCBridgedCastExpr, CXXBaseSpecifier *> {
+ friend class ASTStmtReader;
+ friend class ASTStmtWriter;
+ friend class CastExpr;
+ friend TrailingObjects;
+
+ SourceLocation LParenLoc;
+ SourceLocation BridgeKeywordLoc;
+ unsigned Kind : 2;
+
+public:
+ ObjCBridgedCastExpr(SourceLocation LParenLoc, ObjCBridgeCastKind Kind,
+ CastKind CK, SourceLocation BridgeKeywordLoc,
+ TypeSourceInfo *TSInfo, Expr *Operand)
+ : ExplicitCastExpr(ObjCBridgedCastExprClass, TSInfo->getType(),
+ VK_PRValue, CK, Operand, 0, false, TSInfo),
+ LParenLoc(LParenLoc), BridgeKeywordLoc(BridgeKeywordLoc), Kind(Kind) {}
+
+ /// Construct an empty Objective-C bridged cast.
+ explicit ObjCBridgedCastExpr(EmptyShell Shell)
+ : ExplicitCastExpr(ObjCBridgedCastExprClass, Shell, 0, false) {}
+
+ SourceLocation getLParenLoc() const { return LParenLoc; }
+
+ /// Determine which kind of bridge is being performed via this cast.
+ ObjCBridgeCastKind getBridgeKind() const {
+ return static_cast<ObjCBridgeCastKind>(Kind);
+ }
+
+ /// Retrieve the kind of bridge being performed as a string.
+ StringRef getBridgeKindName() const;
+
+ /// The location of the bridge keyword.
+ SourceLocation getBridgeKeywordLoc() const { return BridgeKeywordLoc; }
+
+ SourceLocation getBeginLoc() const LLVM_READONLY { return LParenLoc; }
+
+ SourceLocation getEndLoc() const LLVM_READONLY {
+ return getSubExpr()->getEndLoc();
+ }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == ObjCBridgedCastExprClass;
+ }
+};
+
+/// A runtime availability query.
+///
+/// There are 2 ways to spell this node:
+/// \code
+/// @available(macos 10.10, ios 8, *); // Objective-C
+/// __builtin_available(macos 10.10, ios 8, *); // C, C++, and Objective-C
+/// \endcode
+///
+/// Note that we only need to keep track of one \c VersionTuple here, which is
+/// the one that corresponds to the current deployment target. This is meant to
+/// be used in the condition of an \c if, but it is also usable as top level
+/// expressions.
+///
+class ObjCAvailabilityCheckExpr : public Expr {
+ friend class ASTStmtReader;
+
+ VersionTuple VersionToCheck;
+ SourceLocation AtLoc, RParen;
+
+public:
+ ObjCAvailabilityCheckExpr(VersionTuple VersionToCheck, SourceLocation AtLoc,
+ SourceLocation RParen, QualType Ty)
+ : Expr(ObjCAvailabilityCheckExprClass, Ty, VK_PRValue, OK_Ordinary),
+ VersionToCheck(VersionToCheck), AtLoc(AtLoc), RParen(RParen) {
+ setDependence(ExprDependence::None);
+ }
+
+ explicit ObjCAvailabilityCheckExpr(EmptyShell Shell)
+ : Expr(ObjCAvailabilityCheckExprClass, Shell) {}
+
+ SourceLocation getBeginLoc() const { return AtLoc; }
+ SourceLocation getEndLoc() const { return RParen; }
+ SourceRange getSourceRange() const { return {AtLoc, RParen}; }
+
+ /// This may be '*', in which case this should fold to true.
+ bool hasVersion() const { return !VersionToCheck.empty(); }
+ VersionTuple getVersion() const { return VersionToCheck; }
+
+ child_range children() {
+ return child_range(child_iterator(), child_iterator());
+ }
+
+ const_child_range children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == ObjCAvailabilityCheckExprClass;
+ }
+};
+
+} // namespace clang
+
+#endif // LLVM_CLANG_AST_EXPROBJC_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif