mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-02-13 22:00:14 +00:00
![Chandler Carruth](/assets/img/avatar_default.png)
to reflect the new license. We understand that people may be surprised that we're moving the header entirely to discuss the new license. We checked this carefully with the Foundation's lawyer and we believe this is the correct approach. Essentially, all code in the project is now made available by the LLVM project under our new license, so you will see that the license headers include that license only. Some of our contributors have contributed code under our old license, and accordingly, we have retained a copy of our old license notice in the top-level files in each project and repository. llvm-svn: 351636
225 lines
6.7 KiB
C++
225 lines
6.7 KiB
C++
//===-- Transforms.h - Transformations to ARC mode --------------*- 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef LLVM_CLANG_LIB_ARCMIGRATE_TRANSFORMS_H
|
|
#define LLVM_CLANG_LIB_ARCMIGRATE_TRANSFORMS_H
|
|
|
|
#include "clang/AST/ParentMap.h"
|
|
#include "clang/AST/RecursiveASTVisitor.h"
|
|
#include "llvm/ADT/DenseSet.h"
|
|
#include "llvm/Support/SaveAndRestore.h"
|
|
|
|
namespace clang {
|
|
class Decl;
|
|
class Stmt;
|
|
class BlockDecl;
|
|
class ObjCMethodDecl;
|
|
class FunctionDecl;
|
|
|
|
namespace arcmt {
|
|
class MigrationPass;
|
|
|
|
namespace trans {
|
|
|
|
class MigrationContext;
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Transformations.
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
void rewriteAutoreleasePool(MigrationPass &pass);
|
|
void rewriteUnbridgedCasts(MigrationPass &pass);
|
|
void makeAssignARCSafe(MigrationPass &pass);
|
|
void removeRetainReleaseDeallocFinalize(MigrationPass &pass);
|
|
void removeZeroOutPropsInDeallocFinalize(MigrationPass &pass);
|
|
void rewriteUnusedInitDelegate(MigrationPass &pass);
|
|
void checkAPIUses(MigrationPass &pass);
|
|
|
|
void removeEmptyStatementsAndDeallocFinalize(MigrationPass &pass);
|
|
|
|
class BodyContext {
|
|
MigrationContext &MigrateCtx;
|
|
ParentMap PMap;
|
|
Stmt *TopStmt;
|
|
|
|
public:
|
|
BodyContext(MigrationContext &MigrateCtx, Stmt *S)
|
|
: MigrateCtx(MigrateCtx), PMap(S), TopStmt(S) {}
|
|
|
|
MigrationContext &getMigrationContext() { return MigrateCtx; }
|
|
ParentMap &getParentMap() { return PMap; }
|
|
Stmt *getTopStmt() { return TopStmt; }
|
|
};
|
|
|
|
class ObjCImplementationContext {
|
|
MigrationContext &MigrateCtx;
|
|
ObjCImplementationDecl *ImpD;
|
|
|
|
public:
|
|
ObjCImplementationContext(MigrationContext &MigrateCtx,
|
|
ObjCImplementationDecl *D)
|
|
: MigrateCtx(MigrateCtx), ImpD(D) {}
|
|
|
|
MigrationContext &getMigrationContext() { return MigrateCtx; }
|
|
ObjCImplementationDecl *getImplementationDecl() { return ImpD; }
|
|
};
|
|
|
|
class ASTTraverser {
|
|
public:
|
|
virtual ~ASTTraverser();
|
|
virtual void traverseTU(MigrationContext &MigrateCtx) { }
|
|
virtual void traverseBody(BodyContext &BodyCtx) { }
|
|
virtual void traverseObjCImplementation(ObjCImplementationContext &ImplCtx) {}
|
|
};
|
|
|
|
class MigrationContext {
|
|
std::vector<ASTTraverser *> Traversers;
|
|
|
|
public:
|
|
MigrationPass &Pass;
|
|
|
|
struct GCAttrOccurrence {
|
|
enum AttrKind { Weak, Strong } Kind;
|
|
SourceLocation Loc;
|
|
QualType ModifiedType;
|
|
Decl *Dcl;
|
|
/// true if the attribute is owned, e.g. it is in a body and not just
|
|
/// in an interface.
|
|
bool FullyMigratable;
|
|
};
|
|
std::vector<GCAttrOccurrence> GCAttrs;
|
|
llvm::DenseSet<unsigned> AttrSet;
|
|
llvm::DenseSet<unsigned> RemovedAttrSet;
|
|
|
|
/// Set of raw '@' locations for 'assign' properties group that contain
|
|
/// GC __weak.
|
|
llvm::DenseSet<unsigned> AtPropsWeak;
|
|
|
|
explicit MigrationContext(MigrationPass &pass) : Pass(pass) {}
|
|
~MigrationContext();
|
|
|
|
typedef std::vector<ASTTraverser *>::iterator traverser_iterator;
|
|
traverser_iterator traversers_begin() { return Traversers.begin(); }
|
|
traverser_iterator traversers_end() { return Traversers.end(); }
|
|
|
|
void addTraverser(ASTTraverser *traverser) {
|
|
Traversers.push_back(traverser);
|
|
}
|
|
|
|
bool isGCOwnedNonObjC(QualType T);
|
|
bool removePropertyAttribute(StringRef fromAttr, SourceLocation atLoc) {
|
|
return rewritePropertyAttribute(fromAttr, StringRef(), atLoc);
|
|
}
|
|
bool rewritePropertyAttribute(StringRef fromAttr, StringRef toAttr,
|
|
SourceLocation atLoc);
|
|
bool addPropertyAttribute(StringRef attr, SourceLocation atLoc);
|
|
|
|
void traverse(TranslationUnitDecl *TU);
|
|
|
|
void dumpGCAttrs();
|
|
};
|
|
|
|
class PropertyRewriteTraverser : public ASTTraverser {
|
|
public:
|
|
void traverseObjCImplementation(ObjCImplementationContext &ImplCtx) override;
|
|
};
|
|
|
|
class BlockObjCVariableTraverser : public ASTTraverser {
|
|
public:
|
|
void traverseBody(BodyContext &BodyCtx) override;
|
|
};
|
|
|
|
class ProtectedScopeTraverser : public ASTTraverser {
|
|
public:
|
|
void traverseBody(BodyContext &BodyCtx) override;
|
|
};
|
|
|
|
// GC transformations
|
|
|
|
class GCAttrsTraverser : public ASTTraverser {
|
|
public:
|
|
void traverseTU(MigrationContext &MigrateCtx) override;
|
|
};
|
|
|
|
class GCCollectableCallsTraverser : public ASTTraverser {
|
|
public:
|
|
void traverseBody(BodyContext &BodyCtx) override;
|
|
};
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Helpers.
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
/// Determine whether we can add weak to the given type.
|
|
bool canApplyWeak(ASTContext &Ctx, QualType type,
|
|
bool AllowOnUnknownClass = false);
|
|
|
|
bool isPlusOneAssign(const BinaryOperator *E);
|
|
bool isPlusOne(const Expr *E);
|
|
|
|
/// 'Loc' is the end of a statement range. This returns the location
|
|
/// immediately after the semicolon following the statement.
|
|
/// If no semicolon is found or the location is inside a macro, the returned
|
|
/// source location will be invalid.
|
|
SourceLocation findLocationAfterSemi(SourceLocation loc, ASTContext &Ctx,
|
|
bool IsDecl = false);
|
|
|
|
/// 'Loc' is the end of a statement range. This returns the location
|
|
/// of the semicolon following the statement.
|
|
/// If no semicolon is found or the location is inside a macro, the returned
|
|
/// source location will be invalid.
|
|
SourceLocation findSemiAfterLocation(SourceLocation loc, ASTContext &Ctx,
|
|
bool IsDecl = false);
|
|
|
|
bool hasSideEffects(Expr *E, ASTContext &Ctx);
|
|
bool isGlobalVar(Expr *E);
|
|
/// Returns "nil" or "0" if 'nil' macro is not actually defined.
|
|
StringRef getNilString(MigrationPass &Pass);
|
|
|
|
template <typename BODY_TRANS>
|
|
class BodyTransform : public RecursiveASTVisitor<BodyTransform<BODY_TRANS> > {
|
|
MigrationPass &Pass;
|
|
Decl *ParentD;
|
|
|
|
typedef RecursiveASTVisitor<BodyTransform<BODY_TRANS> > base;
|
|
public:
|
|
BodyTransform(MigrationPass &pass) : Pass(pass), ParentD(nullptr) { }
|
|
|
|
bool TraverseStmt(Stmt *rootS) {
|
|
if (rootS)
|
|
BODY_TRANS(Pass).transformBody(rootS, ParentD);
|
|
return true;
|
|
}
|
|
|
|
bool TraverseObjCMethodDecl(ObjCMethodDecl *D) {
|
|
SaveAndRestore<Decl *> SetParent(ParentD, D);
|
|
return base::TraverseObjCMethodDecl(D);
|
|
}
|
|
};
|
|
|
|
typedef llvm::DenseSet<Expr *> ExprSet;
|
|
|
|
void clearRefsIn(Stmt *S, ExprSet &refs);
|
|
template <typename iterator>
|
|
void clearRefsIn(iterator begin, iterator end, ExprSet &refs) {
|
|
for (; begin != end; ++begin)
|
|
clearRefsIn(*begin, refs);
|
|
}
|
|
|
|
void collectRefs(ValueDecl *D, Stmt *S, ExprSet &refs);
|
|
|
|
void collectRemovables(Stmt *S, ExprSet &exprs);
|
|
|
|
} // end namespace trans
|
|
|
|
} // end namespace arcmt
|
|
|
|
} // end namespace clang
|
|
|
|
#endif
|