22 #include "llvm/ADT/DenseSet.h"
23 #include "llvm/ADT/StringSwitch.h"
26 using namespace clang;
27 using namespace arcmt;
28 using namespace trans;
33 if (!EnableCFBridgeFns.hasValue())
34 EnableCFBridgeFns = SemaRef.isKnownName(
"CFBridgingRetain") &&
35 SemaRef.isKnownName(
"CFBridgingRelease");
36 return *EnableCFBridgeFns;
44 bool AllowOnUnknownClass) {
54 AllowOnUnknownClass =
true;
60 if (!AllowOnUnknownClass && (!Class || Class->
getName() ==
"NSObject"))
82 E = EWC->getSubExpr();
92 if (FD->hasAttr<CFReturnsRetainedAttr>())
96 FD->getIdentifier() &&
97 FD->getParent()->isTranslationUnit() &&
98 FD->isExternallyVisible() &&
100 FD->getIdentifier()->getName())) {
101 StringRef fname = FD->getIdentifier()->getName();
102 if (fname.endswith(
"Retain") ||
103 fname.find(
"Create") != StringRef::npos ||
104 fname.find(
"Copy") != StringRef::npos) {
113 implCE = dyn_cast<ImplicitCastExpr>(implCE->
getSubExpr());
151 bool invalidTemp =
false;
152 StringRef file = SM.
getBufferData(locInfo.first, &invalidTemp);
156 const char *tokenBegin = file.data() + locInfo.second;
161 file.begin(), tokenBegin, file.end());
163 lexer.LexFromRawLexer(tok);
164 if (tok.isNot(tok::semi)) {
172 return tok.getLocation();
207 return DRE->getDecl()->getDeclContext()->isFileContext() &&
208 DRE->getDecl()->isExternallyVisible();
225 ReferenceClear(
ExprSet &refs) : Refs(refs) { }
226 bool VisitDeclRefExpr(
DeclRefExpr *E) { Refs.erase(E);
return true; }
235 : Dcl(D), Refs(refs) { }
248 RemovablesCollector(
ExprSet &removables)
249 : Removables(removables) { }
251 bool shouldWalkTypesOfTypeLocs()
const {
return false; }
253 bool TraverseStmtExpr(
StmtExpr *E) {
265 for (
auto *I : S->
body())
270 bool VisitIfStmt(
IfStmt *S) {
281 bool VisitDoStmt(
DoStmt *S) {
286 bool VisitForStmt(
ForStmt *S) {
297 while (
LabelStmt *Label = dyn_cast<LabelStmt>(S))
298 S = Label->getSubStmt();
299 S = S->IgnoreImplicit();
300 if (
Expr *E = dyn_cast<Expr>(S))
301 Removables.insert(E);
308 ReferenceClear(refs).TraverseStmt(S);
312 ReferenceCollector(D, refs).TraverseStmt(S);
316 RemovablesCollector(exprs).TraverseStmt(S);
332 bool shouldWalkTypesOfTypeLocs()
const {
return false; }
337 I = MigrateCtx.traversers_begin(),
338 E = MigrateCtx.traversers_end(); I != E; ++I)
339 (*I)->traverseObjCImplementation(ImplCtx);
341 return base::TraverseObjCImplementationDecl(D);
344 bool TraverseStmt(
Stmt *rootS) {
350 I = MigrateCtx.traversers_begin(),
351 E = MigrateCtx.traversers_end(); I != E; ++I)
352 (*I)->traverseBody(BodyCtx);
370 return !AttrT->getModifiedType()->isObjCRetainableType();
398 bool invalidTemp =
false;
399 StringRef file = SM.
getBufferData(locInfo.first, &invalidTemp);
403 const char *tokenBegin = file.data() + locInfo.second;
408 file.begin(), tokenBegin, file.end());
410 lexer.LexFromRawLexer(tok);
411 if (tok.isNot(tok::at))
return false;
412 lexer.LexFromRawLexer(tok);
413 if (tok.isNot(tok::raw_identifier))
return false;
414 if (tok.getRawIdentifier() !=
"property")
416 lexer.LexFromRawLexer(tok);
417 if (tok.isNot(tok::l_paren))
return false;
419 Token BeforeTok = tok;
424 lexer.LexFromRawLexer(tok);
425 if (tok.is(tok::r_paren))
429 if (tok.isNot(tok::raw_identifier))
return false;
430 if (tok.getRawIdentifier() == fromAttr) {
431 if (!toAttr.empty()) {
436 AttrLoc = tok.getLocation();
440 lexer.LexFromRawLexer(tok);
441 if (AttrLoc.
isValid() && AfterTok.
is(tok::unknown))
443 }
while (tok.isNot(tok::comma) && tok.isNot(tok::r_paren));
444 if (tok.is(tok::r_paren))
448 lexer.LexFromRawLexer(tok);
451 if (toAttr.empty() && AttrLoc.
isValid() && AfterTok.
isNot(tok::unknown)) {
453 if (BeforeTok.
is(tok::l_paren) && AfterTok.
is(tok::r_paren)) {
456 }
else if (BeforeTok.
is(tok::l_paren) && AfterTok.
is(tok::comma)) {
479 bool invalidTemp =
false;
480 StringRef file = SM.
getBufferData(locInfo.first, &invalidTemp);
484 const char *tokenBegin = file.data() + locInfo.second;
489 file.begin(), tokenBegin, file.end());
491 lexer.LexFromRawLexer(tok);
492 if (tok.isNot(tok::at))
return false;
493 lexer.LexFromRawLexer(tok);
494 if (tok.isNot(tok::raw_identifier))
return false;
495 if (tok.getRawIdentifier() !=
"property")
497 lexer.LexFromRawLexer(tok);
499 if (tok.isNot(tok::l_paren)) {
500 Pass.
TA.
insert(tok.getLocation(), std::string(
"(") + attr.str() +
") ");
504 lexer.LexFromRawLexer(tok);
505 if (tok.is(tok::r_paren)) {
510 if (tok.isNot(tok::raw_identifier))
return false;
512 Pass.
TA.
insert(tok.getLocation(), std::string(attr) +
", ");
519 (*I)->traverseTU(*
this);
521 ASTTransform(*this).TraverseDecl(TU);
533 for (impl_iterator I = impl_iterator(DC->
decls_begin()),
534 E = impl_iterator(DC->
decls_end()); I != E; ++I) {
535 for (
const auto *MD : I->instance_methods()) {
539 if (MD->isInstanceMethod() && MD->getSelector() == FinalizeSel) {
543 "#if !__has_feature(objc_arc)\n");
548 std::string str =
"\n#endif\n";
551 SM, LangOpts, &Invalid);
591 bool NoFinalizeRemoval) {
592 std::vector<TransformFn> transforms;
The receiver is the instance of the superclass object.
bool hasDefinition() const
Determine whether this class has been defined.
Defines the clang::ASTContext interface.
SourceLocation getEnd() const
CastKind getCastKind() const
The receiver is an object instance.
StringRef getName() const
Smart pointer class that efficiently represents Objective-C method names.
bool isGCOwnedNonObjC(QualType T)
ObjCMethodFamily getMethodFamily() const
CompoundStmt * getSubStmt()
Defines the SourceManager interface.
static CharSourceRange getTokenRange(SourceRange R)
const Stmt * getElse() const
bool isArcWeakrefUnavailable() const
traverser_iterator traversers_begin()
[ARC] Consumes a retainable object pointer that has just been produced, e.g. as the return value of a...
bool HasSideEffects(const ASTContext &Ctx, bool IncludePossibleEffects=true) const
bool rewritePropertyAttribute(StringRef fromAttr, StringRef toAttr, SourceLocation atLoc)
void traverse(TranslationUnitDecl *TU)
SourceLocation findSemiAfterLocation(SourceLocation loc, ASTContext &Ctx, bool IsDecl=false)
'Loc' is the end of a statement range. This returns the location of the semicolon following the state...
void makeAssignARCSafe(MigrationPass &pass)
std::vector< ASTTraverser * >::iterator traverser_iterator
bool isGCMigration() const
decl_iterator decls_end() const
void clearRefsIn(Stmt *S, ExprSet &refs)
StringRef getBufferData(FileID FID, bool *Invalid=nullptr) const
Return a StringRef to the source buffer data for the specified FileID.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
bool isGlobalVar(Expr *E)
SourceLocation findLocationAfterSemi(SourceLocation loc, ASTContext &Ctx, bool IsDecl=false)
'Loc' is the end of a statement range. This returns the location immediately after the semicolon foll...
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Selector getNullarySelector(IdentifierInfo *ID)
const TargetInfo & getTargetInfo() const
SourceLocation getLocWithOffset(int Offset) const
Return a source location with the specified offset from this SourceLocation.
void removeRetainReleaseDeallocFinalize(MigrationPass &pass)
const LangOptions & getLangOpts() const
A builtin binary operation expression such as "x + y" or "x <= y".
Expr * IgnoreParenCasts() LLVM_READONLY
void rewriteUnusedInitDelegate(MigrationPass &pass)
A class that does preorder depth-first traversal on the entire Clang AST and visits each node...
Represents an ObjC class declaration.
bool isPlusOneAssign(const BinaryOperator *E)
decl_iterator decls_begin() const
StringRef getNilString(MigrationPass &Pass)
Returns "nil" or "0" if 'nil' macro is not actually defined.
QualType getPointeeType() const
static StringRef getSourceText(CharSourceRange Range, const SourceManager &SM, const LangOptions &LangOpts, bool *Invalid=nullptr)
Returns a string for the source that the range encompasses.
static bool isAtEndOfMacroExpansion(SourceLocation loc, const SourceManager &SM, const LangOptions &LangOpts, SourceLocation *MacroEnd=nullptr)
Returns true if the given MacroID location points at the last token of the macro expansion.
void collectRemovables(Stmt *S, ExprSet &exprs)
static SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset, const SourceManager &SM, const LangOptions &LangOpts)
Computes the source location just past the end of the token at this source location.
bool CFBridgingFunctionsDefined()
void removeEmptyStatementsAndDeallocFinalize(MigrationPass &pass)
TranslationUnitDecl * getTranslationUnitDecl() const
Defines the clang::Preprocessor interface.
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file. ...
void checkAPIUses(MigrationPass &pass)
bool isNot(tok::TokenKind K) const
An expression that sends a message to the given Objective-C object or class.
bool addPropertyAttribute(StringRef attr, SourceLocation atLoc)
bool canApplyWeak(ASTContext &Ctx, QualType type, bool AllowOnUnknownClass=false)
Determine whether we can add weak to the given type.
void rewriteUnbridgedCasts(MigrationPass &pass)
SelectorTable & Selectors
Encodes a location in the source. The SourceManager can decode this to get at the full include stack...
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
bool isValid() const
Return true if this is a valid SourceLocation object.
traverser_iterator traversers_end()
SourceLocation getBegin() const
bool is(tok::TokenKind K) const
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
void collectRefs(ValueDecl *D, Stmt *S, ExprSet &refs)
void addTraverser(ASTTraverser *traverser)
Expr * getInstanceReceiver()
Returns the object expression (receiver) for an instance message, or null for a message that is not a...
bool isMacroDefined(StringRef Id)
bool isRefType(QualType RetTy, StringRef Prefix, StringRef Name=StringRef())
void rewriteAutoreleasePool(MigrationPass &pass)
bool hasSideEffects(Expr *E, ASTContext &Ctx)
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
std::vector< TransformFn > getAllTransformations(LangOptions::GCMode OrigGCMode, bool NoFinalizeRemoval)
bool isPlusOne(const Expr *E)
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
body_iterator body_begin()
const Stmt * getThen() const
void removeZeroOutPropsInDeallocFinalize(MigrationPass &pass)
SourceManager & getSourceManager()
Defines the clang::TargetInfo interface.
TranslationUnitDecl - The top declaration context.
A reference to a declared variable, function, enum, etc. [C99 6.5.1p2].
SourceLocation getLocForStartOfFile(FileID FID) const
Return the source location corresponding to the first byte of the specified file. ...
A trivial tuple used to represent a source range.
std::pair< FileID, unsigned > getDecomposedLoc(SourceLocation Loc) const
Decompose the specified location into a raw FileID + Offset pair.
bool isNull() const
isNull - Return true if this QualType doesn't point to a type yet.
ReceiverKind getReceiverKind() const
Determine the kind of receiver that this message is being sent to.
This class handles loading and caching of source files into memory.
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
void startToken()
Reset all flags to cleared.