llvm/clang/lib/Frontend/Rewrite/RewriteObjC.cpp

//===--- RewriteObjC.cpp - Playground for the code rewriter ---------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// Hacks and fun related to the code rewriter.
//
//===----------------------------------------------------------------------===//

#include "clang/Rewrite/Frontend/ASTConsumers.h"
#include "clang/AST/AST.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/Attr.h"
#include "clang/AST/ParentMap.h"
#include "clang/Basic/CharInfo.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Config/config.h"
#include "clang/Lex/Lexer.h"
#include "clang/Rewrite/Core/Rewriter.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/raw_ostream.h"
#include <memory>

#if CLANG_ENABLE_OBJC_REWRITER

usingnamespaceclang;
RewriteBuffer;
utostr;

namespace {
  class RewriteObjC : public ASTConsumer {};

  class RewriteObjCFragileABI : public RewriteObjC {};
} // end anonymous namespace

void RewriteObjC::RewriteBlocksInFunctionProtoType(QualType funcType,
                                                   NamedDecl *D) {}

void RewriteObjC::CheckFunctionPointerDecl(QualType funcType, NamedDecl *ND) {}

static bool IsHeaderFile(const std::string &Filename) {}

RewriteObjC::RewriteObjC(std::string inFile, std::unique_ptr<raw_ostream> OS,
                         DiagnosticsEngine &D, const LangOptions &LOpts,
                         bool silenceMacroWarn)
    :{}

std::unique_ptr<ASTConsumer>
clang::CreateObjCRewriter(const std::string &InFile,
                          std::unique_ptr<raw_ostream> OS,
                          DiagnosticsEngine &Diags, const LangOptions &LOpts,
                          bool SilenceRewriteMacroWarning) {}

void RewriteObjC::InitializeCommon(ASTContext &context) {}

//===----------------------------------------------------------------------===//
// Top Level Driver Code
//===----------------------------------------------------------------------===//

void RewriteObjC::HandleTopLevelSingleDecl(Decl *D) {}

//===----------------------------------------------------------------------===//
// Syntactic (non-AST) Rewriting Code
//===----------------------------------------------------------------------===//

void RewriteObjC::RewriteInclude() {}

static std::string getIvarAccessString(ObjCIvarDecl *OID) {}

void RewriteObjC::RewritePropertyImplDecl(ObjCPropertyImplDecl *PID,
                                          ObjCImplementationDecl *IMD,
                                          ObjCCategoryImplDecl *CID) {}

static void RewriteOneForwardClassDecl(ObjCInterfaceDecl *ForwardDecl,
                                       std::string &typedefString) {}

void RewriteObjC::RewriteForwardClassEpilogue(ObjCInterfaceDecl *ClassDecl,
                                              const std::string &typedefString) {}

void RewriteObjC::RewriteForwardClassDecl(DeclGroupRef D) {}

void RewriteObjC::RewriteForwardClassDecl(const SmallVectorImpl<Decl *> &D) {}

void RewriteObjC::RewriteMethodDeclaration(ObjCMethodDecl *Method) {}

void RewriteObjC::RewriteProperty(ObjCPropertyDecl *prop) {}

void RewriteObjC::RewriteCategoryDecl(ObjCCategoryDecl *CatDecl) {}

void RewriteObjC::RewriteProtocolDecl(ObjCProtocolDecl *PDecl) {}

void RewriteObjC::RewriteForwardProtocolDecl(DeclGroupRef D) {}

void
RewriteObjC::RewriteForwardProtocolDecl(const SmallVectorImpl<Decl *> &DG) {}

void RewriteObjC::RewriteTypeIntoString(QualType T, std::string &ResultStr,
                                        const FunctionType *&FPRetType) {}

void RewriteObjC::RewriteObjCMethodDecl(const ObjCInterfaceDecl *IDecl,
                                        ObjCMethodDecl *OMD,
                                        std::string &ResultStr) {}

void RewriteObjC::RewriteImplementationDecl(Decl *OID) {}

void RewriteObjC::RewriteInterfaceDecl(ObjCInterfaceDecl *ClassDecl) {}

Stmt *RewriteObjC::RewritePropertyOrImplicitSetter(PseudoObjectExpr *PseudoOp) {}

Stmt *RewriteObjC::RewritePropertyOrImplicitGetter(PseudoObjectExpr *PseudoOp) {}

/// SynthCountByEnumWithState - To print:
/// ((unsigned int (*)
///  (id, SEL, struct __objcFastEnumerationState *, id *, unsigned int))
///  (void *)objc_msgSend)((id)l_collection,
///                        sel_registerName(
///                          "countByEnumeratingWithState:objects:count:"),
///                        &enumState,
///                        (id *)__rw_items, (unsigned int)16)
///
void RewriteObjC::SynthCountByEnumWithState(std::string &buf) {}

/// RewriteBreakStmt - Rewrite for a break-stmt inside an ObjC2's foreach
/// statement to exit to its outer synthesized loop.
///
Stmt *RewriteObjC::RewriteBreakStmt(BreakStmt *S) {}

/// RewriteContinueStmt - Rewrite for a continue-stmt inside an ObjC2's foreach
/// statement to continue with its inner synthesized loop.
///
Stmt *RewriteObjC::RewriteContinueStmt(ContinueStmt *S) {}

/// RewriteObjCForCollectionStmt - Rewriter for ObjC2's foreach statement.
///  It rewrites:
/// for ( type elem in collection) { stmts; }

/// Into:
/// {
///   type elem;
///   struct __objcFastEnumerationState enumState = { 0 };
///   id __rw_items[16];
///   id l_collection = (id)collection;
///   unsigned long limit = [l_collection countByEnumeratingWithState:&enumState
///                                       objects:__rw_items count:16];
/// if (limit) {
///   unsigned long startMutations = *enumState.mutationsPtr;
///   do {
///        unsigned long counter = 0;
///        do {
///             if (startMutations != *enumState.mutationsPtr)
///               objc_enumerationMutation(l_collection);
///             elem = (type)enumState.itemsPtr[counter++];
///             stmts;
///             __continue_label: ;
///        } while (counter < limit);
///   } while (limit = [l_collection countByEnumeratingWithState:&enumState
///                                  objects:__rw_items count:16]);
///   elem = nil;
///   __break_label: ;
///  }
///  else
///       elem = nil;
///  }
///
Stmt *RewriteObjC::RewriteObjCForCollectionStmt(ObjCForCollectionStmt *S,
                                                SourceLocation OrigEnd) {}

/// RewriteObjCSynchronizedStmt -
/// This routine rewrites @synchronized(expr) stmt;
/// into:
/// objc_sync_enter(expr);
/// @try stmt @finally { objc_sync_exit(expr); }
///
Stmt *RewriteObjC::RewriteObjCSynchronizedStmt(ObjCAtSynchronizedStmt *S) {}

void RewriteObjC::WarnAboutReturnGotoStmts(Stmt *S)
{}

void RewriteObjC::HasReturnStmts(Stmt *S, bool &hasReturns)
{}

void RewriteObjC::RewriteTryReturnStmts(Stmt *S) {}

void RewriteObjC::RewriteSyncReturnStmts(Stmt *S, std::string syncExitBuf) {}

Stmt *RewriteObjC::RewriteObjCTryStmt(ObjCAtTryStmt *S) {}

// This can't be done with ReplaceStmt(S, ThrowExpr), since
// the throw expression is typically a message expression that's already
// been rewritten! (which implies the SourceLocation's are invalid).
Stmt *RewriteObjC::RewriteObjCThrowStmt(ObjCAtThrowStmt *S) {}

Stmt *RewriteObjC::RewriteAtEncode(ObjCEncodeExpr *Exp) {}

Stmt *RewriteObjC::RewriteAtSelector(ObjCSelectorExpr *Exp) {}

CallExpr *
RewriteObjC::SynthesizeCallToFunctionDecl(FunctionDecl *FD,
                                          ArrayRef<Expr *> Args,
                                          SourceLocation StartLoc,
                                          SourceLocation EndLoc) {}

static bool scanForProtocolRefs(const char *startBuf, const char *endBuf,
                                const char *&startRef, const char *&endRef) {}

static void scanToNextArgument(const char *&argRef) {}

bool RewriteObjC::needToScanForQualifiers(QualType T) {}

void RewriteObjC::RewriteObjCQualifiedInterfaceTypes(Expr *E) {}

void RewriteObjC::RewriteObjCQualifiedInterfaceTypes(Decl *Dcl) {}

void RewriteObjC::RewriteTypeOfDecl(VarDecl *ND) {}

// SynthSelGetUidFunctionDecl - SEL sel_registerName(const char *str);
void RewriteObjC::SynthSelGetUidFunctionDecl() {}

void RewriteObjC::RewriteFunctionDecl(FunctionDecl *FD) {}

void RewriteObjC::RewriteBlockPointerType(std::string& Str, QualType Type) {}

// FIXME. Consolidate this routine with RewriteBlockPointerType.
void RewriteObjC::RewriteBlockPointerTypeVariable(std::string& Str,
                                                  ValueDecl *VD) {}

void RewriteObjC::RewriteBlockLiteralFunctionDecl(FunctionDecl *FD) {}

// SynthSuperConstructorFunctionDecl - id objc_super(id obj, id super);
void RewriteObjC::SynthSuperConstructorFunctionDecl() {}

// SynthMsgSendFunctionDecl - id objc_msgSend(id self, SEL op, ...);
void RewriteObjC::SynthMsgSendFunctionDecl() {}

// SynthMsgSendSuperFunctionDecl - id objc_msgSendSuper(struct objc_super *, SEL op, ...);
void RewriteObjC::SynthMsgSendSuperFunctionDecl() {}

// SynthMsgSendStretFunctionDecl - id objc_msgSend_stret(id self, SEL op, ...);
void RewriteObjC::SynthMsgSendStretFunctionDecl() {}

// SynthMsgSendSuperStretFunctionDecl -
// id objc_msgSendSuper_stret(struct objc_super *, SEL op, ...);
void RewriteObjC::SynthMsgSendSuperStretFunctionDecl() {}

// SynthMsgSendFpretFunctionDecl - double objc_msgSend_fpret(id self, SEL op, ...);
void RewriteObjC::SynthMsgSendFpretFunctionDecl() {}

// SynthGetClassFunctionDecl - id objc_getClass(const char *name);
void RewriteObjC::SynthGetClassFunctionDecl() {}

// SynthGetSuperClassFunctionDecl - Class class_getSuperclass(Class cls);
void RewriteObjC::SynthGetSuperClassFunctionDecl() {}

// SynthGetMetaClassFunctionDecl - id objc_getMetaClass(const char *name);
void RewriteObjC::SynthGetMetaClassFunctionDecl() {}

Stmt *RewriteObjC::RewriteObjCStringLiteral(ObjCStringLiteral *Exp) {}

// struct objc_super { struct objc_object *receiver; struct objc_class *super; };
QualType RewriteObjC::getSuperStructType() {}

QualType RewriteObjC::getConstantStringStructType() {}

CallExpr *RewriteObjC::SynthMsgSendStretCallExpr(FunctionDecl *MsgSendStretFlavor,
                                                QualType msgSendType,
                                                QualType returnType,
                                                SmallVectorImpl<QualType> &ArgTypes,
                                                SmallVectorImpl<Expr*> &MsgExprs,
                                                ObjCMethodDecl *Method) {}

Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp,
                                    SourceLocation StartLoc,
                                    SourceLocation EndLoc) {}

Stmt *RewriteObjC::RewriteMessageExpr(ObjCMessageExpr *Exp) {}

// typedef struct objc_object Protocol;
QualType RewriteObjC::getProtocolType() {}

/// RewriteObjCProtocolExpr - Rewrite a protocol expression into
/// a synthesized/forward data reference (to the protocol's metadata).
/// The forward references (and metadata) are generated in
/// RewriteObjC::HandleTranslationUnit().
Stmt *RewriteObjC::RewriteObjCProtocolExpr(ObjCProtocolExpr *Exp) {}

bool RewriteObjC::BufferContainsPPDirectives(const char *startBuf,
                                             const char *endBuf) {}

/// RewriteObjCInternalStruct - Rewrite one internal struct corresponding to
/// an objective-c class with ivars.
void RewriteObjC::RewriteObjCInternalStruct(ObjCInterfaceDecl *CDecl,
                                               std::string &Result) {}

//===----------------------------------------------------------------------===//
// Meta Data Emission
//===----------------------------------------------------------------------===//

/// RewriteImplementations - This routine rewrites all method implementations
/// and emits meta-data.

void RewriteObjC::RewriteImplementations() {}

void RewriteObjC::RewriteByRefString(std::string &ResultStr,
                                     const std::string &Name,
                                     ValueDecl *VD, bool def) {}

static bool HasLocalVariableExternalStorage(ValueDecl *VD) {}

std::string RewriteObjC::SynthesizeBlockFunc(BlockExpr *CE, int i,
                                                   StringRef funcName,
                                                   std::string Tag) {}

std::string RewriteObjC::SynthesizeBlockHelperFuncs(BlockExpr *CE, int i,
                                                   StringRef funcName,
                                                   std::string Tag) {}

std::string RewriteObjC::SynthesizeBlockImpl(BlockExpr *CE, std::string Tag,
                                             std::string Desc) {}

std::string RewriteObjC::SynthesizeBlockDescriptor(std::string DescTag,
                                                   std::string ImplTag, int i,
                                                   StringRef FunName,
                                                   unsigned hasCopy) {}

void RewriteObjC::SynthesizeBlockLiterals(SourceLocation FunLocStart,
                                          StringRef FunName) {}

void RewriteObjC::InsertBlockLiteralsWithinFunction(FunctionDecl *FD) {}

static void BuildUniqueMethodName(std::string &Name,
                                  ObjCMethodDecl *MD) {}

void RewriteObjC::InsertBlockLiteralsWithinMethod(ObjCMethodDecl *MD) {}

void RewriteObjC::GetBlockDeclRefExprs(Stmt *S) {}

void RewriteObjC::GetInnerBlockDeclRefExprs(Stmt *S,
                SmallVectorImpl<DeclRefExpr *> &InnerBlockDeclRefs,
                llvm::SmallPtrSetImpl<const DeclContext *> &InnerContexts) {}

/// convertFunctionTypeOfBlocks - This routine converts a function type
/// whose result type may be a block pointer or whose argument type(s)
/// might be block pointers to an equivalent function type replacing
/// all block pointers to function pointers.
QualType RewriteObjC::convertFunctionTypeOfBlocks(const FunctionType *FT) {}

Stmt *RewriteObjC::SynthesizeBlockCall(CallExpr *Exp, const Expr *BlockExp) {}

// We need to return the rewritten expression to handle cases where the
// BlockDeclRefExpr is embedded in another expression being rewritten.
// For example:
//
// int main() {
//    __block Foo *f;
//    __block int i;
//
//    void (^myblock)() = ^() {
//        [f test]; // f is a BlockDeclRefExpr embedded in a message (which is being rewritten).
//        i = 77;
//    };
//}
Stmt *RewriteObjC::RewriteBlockDeclRefExpr(DeclRefExpr *DeclRefExp) {}

// Rewrites the imported local variable V with external storage
// (static, extern, etc.) as *V
//
Stmt *RewriteObjC::RewriteLocalVariableExternalStorage(DeclRefExpr *DRE) {}

void RewriteObjC::RewriteCastExpr(CStyleCastExpr *CE) {}

void RewriteObjC::RewriteBlockPointerFunctionArgs(FunctionDecl *FD) {}

bool RewriteObjC::PointerTypeTakesAnyBlockArguments(QualType QT) {}

bool RewriteObjC::PointerTypeTakesAnyObjCQualifiedType(QualType QT) {}

void RewriteObjC::GetExtentOfArgList(const char *Name, const char *&LParen,
                                     const char *&RParen) {}

void RewriteObjC::RewriteBlockPointerDecl(NamedDecl *ND) {}

/// SynthesizeByrefCopyDestroyHelper - This routine synthesizes:
/// void __Block_byref_id_object_copy(struct Block_byref_id_object *dst,
///                    struct Block_byref_id_object *src) {
///  _Block_object_assign (&_dest->object, _src->object,
///                        BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_OBJECT
///                        [|BLOCK_FIELD_IS_WEAK]) // object
///  _Block_object_assign(&_dest->object, _src->object,
///                       BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_BLOCK
///                       [|BLOCK_FIELD_IS_WEAK]) // block
/// }
/// And:
/// void __Block_byref_id_object_dispose(struct Block_byref_id_object *_src) {
///  _Block_object_dispose(_src->object,
///                        BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_OBJECT
///                        [|BLOCK_FIELD_IS_WEAK]) // object
///  _Block_object_dispose(_src->object,
///                         BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_BLOCK
///                         [|BLOCK_FIELD_IS_WEAK]) // block
/// }

std::string RewriteObjC::SynthesizeByrefCopyDestroyHelper(VarDecl *VD,
                                                          int flag) {}

/// RewriteByRefVar - For each __block typex ND variable this routine transforms
/// the declaration into:
/// struct __Block_byref_ND {
/// void *__isa;                  // NULL for everything except __weak pointers
/// struct __Block_byref_ND *__forwarding;
/// int32_t __flags;
/// int32_t __size;
/// void *__Block_byref_id_object_copy; // If variable is __block ObjC object
/// void *__Block_byref_id_object_dispose; // If variable is __block ObjC object
/// typex ND;
/// };
///
/// It then replaces declaration of ND variable with:
/// struct __Block_byref_ND ND = {__isa=0B, __forwarding=&ND, __flags=some_flag,
///                               __size=sizeof(struct __Block_byref_ND),
///                               ND=initializer-if-any};
///
///
void RewriteObjC::RewriteByRefVar(VarDecl *ND) {}

void RewriteObjC::CollectBlockDeclRefInfo(BlockExpr *Exp) {}

FunctionDecl *RewriteObjC::SynthBlockInitFunctionDecl(StringRef name) {}

Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp,
                     const SmallVectorImpl<DeclRefExpr *> &InnerBlockDeclRefs) {}

bool RewriteObjC::IsDeclStmtInForeachHeader(DeclStmt *DS) {}

//===----------------------------------------------------------------------===//
// Function Body / Expression rewriting
//===----------------------------------------------------------------------===//

Stmt *RewriteObjC::RewriteFunctionBodyOrGlobalInitializer(Stmt *S) {}

void RewriteObjC::RewriteRecordBody(RecordDecl *RD) {}

/// HandleDeclInMainFile - This is called for each top-level decl defined in the
/// main file of the input.
void RewriteObjC::HandleDeclInMainFile(Decl *D) {}

void RewriteObjC::HandleTranslationUnit(ASTContext &C) {}

void RewriteObjCFragileABI::Initialize(ASTContext &context) {}

/// RewriteIvarOffsetComputation - This routine synthesizes computation of
/// ivar offset.
void RewriteObjCFragileABI::RewriteIvarOffsetComputation(ObjCIvarDecl *ivar,
                                                         std::string &Result) {}

/// RewriteObjCProtocolMetaData - Rewrite protocols meta-data.
void RewriteObjCFragileABI::RewriteObjCProtocolMetaData(
                            ObjCProtocolDecl *PDecl, StringRef prefix,
                            StringRef ClassName, std::string &Result) {}

void RewriteObjCFragileABI::RewriteObjCProtocolListMetaData(
                                const ObjCList<ObjCProtocolDecl> &Protocols,
                                StringRef prefix, StringRef ClassName,
                                std::string &Result) {}

void RewriteObjCFragileABI::RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl,
                                           std::string &Result) {}

void RewriteObjCFragileABI::RewriteMetaDataIntoBuffer(std::string &Result) {}

/// RewriteObjCCategoryImplDecl - Rewrite metadata for each category
/// implementation.
void RewriteObjCFragileABI::RewriteObjCCategoryImplDecl(ObjCCategoryImplDecl *IDecl,
                                              std::string &Result) {}

// RewriteObjCMethodsMetaData - Rewrite methods metadata for instance or
/// class methods.
template<typename MethodIterator>
void RewriteObjCFragileABI::RewriteObjCMethodsMetaData(MethodIterator MethodBegin,
                                             MethodIterator MethodEnd,
                                             bool IsInstanceMethod,
                                             StringRef prefix,
                                             StringRef ClassName,
                                             std::string &Result) {}

Stmt *RewriteObjCFragileABI::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV) {}

#endif // CLANG_ENABLE_OBJC_REWRITER