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) {
55 AllowOnUnknownClass =
true;
61 if (!AllowOnUnknownClass && (!Class || Class->
getName() ==
"NSObject"))
83 E = EWC->getSubExpr();
93 if (FD->hasAttr<CFReturnsRetainedAttr>())
97 FD->getIdentifier() &&
98 FD->getParent()->isTranslationUnit() &&
99 FD->isExternallyVisible() &&
101 FD->getIdentifier()->getName())) {
102 StringRef fname = FD->getIdentifier()->getName();
103 if (fname.endswith(
"Retain") ||
104 fname.find(
"Create") != StringRef::npos ||
105 fname.find(
"Copy") != StringRef::npos) {
113 while (implCE && implCE->
getCastKind() == CK_BitCast)
114 implCE = dyn_cast<ImplicitCastExpr>(implCE->
getSubExpr());
116 return implCE && implCE->
getCastKind() == CK_ARCConsumeObject;
149 bool invalidTemp =
false;
150 StringRef file = SM.
getBufferData(locInfo.first, &invalidTemp);
154 const char *tokenBegin = file.data() + locInfo.second;
159 file.begin(), tokenBegin, file.end());
161 lexer.LexFromRawLexer(tok);
162 if (tok.isNot(tok::semi)) {
170 return tok.getLocation();
205 return DRE->getDecl()->getDeclContext()->isFileContext() &&
206 DRE->getDecl()->isExternallyVisible();
223 ReferenceClear(
ExprSet &refs) : Refs(refs) { }
224 bool VisitDeclRefExpr(
DeclRefExpr *
E) { Refs.erase(E);
return true; }
233 : Dcl(D), Refs(refs) { }
246 RemovablesCollector(
ExprSet &removables)
247 : Removables(removables) { }
249 bool shouldWalkTypesOfTypeLocs()
const {
return false; }
263 for (
auto *
I : S->
body())
268 bool VisitIfStmt(
IfStmt *S) {
279 bool VisitDoStmt(
DoStmt *S) {
284 bool VisitForStmt(
ForStmt *S) {
295 while (
LabelStmt *Label = dyn_cast<LabelStmt>(S))
296 S = Label->getSubStmt();
297 S = S->IgnoreImplicit();
298 if (
Expr *E = dyn_cast<Expr>(S))
299 Removables.insert(E);
306 ReferenceClear(refs).TraverseStmt(S);
310 ReferenceCollector(D, refs).TraverseStmt(S);
314 RemovablesCollector(exprs).TraverseStmt(S);
330 bool shouldWalkTypesOfTypeLocs()
const {
return false; }
335 I = MigrateCtx.traversers_begin(),
336 E = MigrateCtx.traversers_end();
I !=
E; ++
I)
337 (*I)->traverseObjCImplementation(ImplCtx);
339 return base::TraverseObjCImplementationDecl(D);
342 bool TraverseStmt(
Stmt *rootS) {
348 I = MigrateCtx.traversers_begin(),
349 E = MigrateCtx.traversers_end();
I !=
E; ++
I)
350 (*I)->traverseBody(BodyCtx);
368 return !AttrT->getModifiedType()->isObjCRetainableType();
396 bool invalidTemp =
false;
397 StringRef file = SM.
getBufferData(locInfo.first, &invalidTemp);
401 const char *tokenBegin = file.data() + locInfo.second;
406 file.begin(), tokenBegin, file.end());
408 lexer.LexFromRawLexer(tok);
409 if (tok.isNot(tok::at))
return false;
410 lexer.LexFromRawLexer(tok);
411 if (tok.isNot(tok::raw_identifier))
return false;
412 if (tok.getRawIdentifier() !=
"property")
414 lexer.LexFromRawLexer(tok);
415 if (tok.isNot(tok::l_paren))
return false;
417 Token BeforeTok = tok;
422 lexer.LexFromRawLexer(tok);
423 if (tok.is(tok::r_paren))
427 if (tok.isNot(tok::raw_identifier))
return false;
428 if (tok.getRawIdentifier() == fromAttr) {
429 if (!toAttr.empty()) {
434 AttrLoc = tok.getLocation();
438 lexer.LexFromRawLexer(tok);
439 if (AttrLoc.
isValid() && AfterTok.
is(tok::unknown))
441 }
while (tok.isNot(tok::comma) && tok.isNot(tok::r_paren));
442 if (tok.is(tok::r_paren))
446 lexer.LexFromRawLexer(tok);
449 if (toAttr.empty() && AttrLoc.
isValid() && AfterTok.
isNot(tok::unknown)) {
451 if (BeforeTok.
is(tok::l_paren) && AfterTok.
is(tok::r_paren)) {
454 }
else if (BeforeTok.
is(tok::l_paren) && AfterTok.
is(tok::comma)) {
477 bool invalidTemp =
false;
478 StringRef file = SM.
getBufferData(locInfo.first, &invalidTemp);
482 const char *tokenBegin = file.data() + locInfo.second;
487 file.begin(), tokenBegin, file.end());
489 lexer.LexFromRawLexer(tok);
490 if (tok.isNot(tok::at))
return false;
491 lexer.LexFromRawLexer(tok);
492 if (tok.isNot(tok::raw_identifier))
return false;
493 if (tok.getRawIdentifier() !=
"property")
495 lexer.LexFromRawLexer(tok);
497 if (tok.isNot(tok::l_paren)) {
498 Pass.
TA.
insert(tok.getLocation(), std::string(
"(") + attr.str() +
") ");
502 lexer.LexFromRawLexer(tok);
503 if (tok.is(tok::r_paren)) {
508 if (tok.isNot(tok::raw_identifier))
return false;
510 Pass.
TA.
insert(tok.getLocation(), std::string(attr) +
", ");
517 (*I)->traverseTU(*
this);
519 ASTTransform(*this).TraverseDecl(TU);
531 for (impl_iterator
I = impl_iterator(DC->
decls_begin()),
533 for (
const auto *MD :
I->instance_methods()) {
537 if (MD->isInstanceMethod() && MD->getSelector() == FinalizeSel) {
541 "#if !__has_feature(objc_arc)\n");
546 std::string str =
"\n#endif\n";
549 SM, LangOpts, &Invalid);
589 bool NoFinalizeRemoval) {
590 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
FunctionDecl - An instance of this class is created to represent a function declaration or definition...
The receiver is an object instance.
StringRef getName() const
getName - Get the name of identifier for this declaration as a StringRef.
Lexer - This provides a simple interface that turns a text buffer into a stream of tokens...
Smart pointer class that efficiently represents Objective-C method names.
PointerType - C99 6.7.5.1 - Pointer Declarators.
A (possibly-)qualified type.
bool isGCOwnedNonObjC(QualType T)
ObjCMethodFamily getMethodFamily() const
CompoundStmt * getSubStmt()
IfStmt - This represents an if/then/else.
Defines the SourceManager interface.
static CharSourceRange getTokenRange(SourceRange R)
const Stmt * getElse() const
bool isArcWeakrefUnavailable() const
isArcWeakrefUnavailable - Checks for a class or one of its super classes to be incompatible with __we...
traverser_iterator traversers_begin()
bool HasSideEffects(const ASTContext &Ctx, bool IncludePossibleEffects=true) const
HasSideEffects - This routine returns true for all those expressions which have any effect other than...
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.
void makeAssignARCSafe(MigrationPass &pass)
std::vector< ASTTraverser * >::iterator traverser_iterator
ObjCMethodDecl - Represents an instance or class method declaration.
bool isGCMigration() const
decl_iterator decls_end() const
Represents an expression – generally a full-expression – that introduces cleanups to be run at the en...
void clearRefsIn(Stmt *S, ExprSet &refs)
LabelStmt - Represents a label, which has a substatement.
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)
Token - This structure provides full information about a lexed token.
SourceLocation findLocationAfterSemi(SourceLocation loc, ASTContext &Ctx, bool IsDecl=false)
'Loc' is the end of a statement range.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Selector getNullarySelector(IdentifierInfo *ID)
ForStmt - This represents a 'for (init;cond;inc)' stmt.
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
IgnoreParenCasts - Ignore parentheses and casts.
void rewriteUnusedInitDelegate(MigrationPass &pass)
A class that does preordor or postorder depth-first traversal on the entire Clang AST and visits each...
Represents an ObjC class declaration.
bool isPlusOneAssign(const BinaryOperator *E)
decl_iterator decls_begin() const
detail::InMemoryDirectory::const_iterator I
ConditionalOperator - The ?: ternary operator.
StringRef getNilString(MigrationPass &Pass)
Returns "nil" or "0" if 'nil' macro is not actually defined.
CompoundStmt - This represents a group of statements like { stmt stmt }.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
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)
ValueDecl - Represent the declaration of a variable (in which case it is an lvalue) a function (in wh...
Expr - This represents one expression.
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.
DoStmt - This represents a 'do/while' stmt.
void rewriteUnbridgedCasts(MigrationPass &pass)
SelectorTable & Selectors
Encodes a location in the source.
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()
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
SourceLocation getBegin() const
bool is(tok::TokenKind K) const
is/isNot - Predicates to check if this token is a specific kind, as in "if (Tok.is(tok::l_brace)) {...
StmtExpr - This is the GNU Statement Expression extension: ({int X=4; X;}).
SourceRange getSourceRange() const override LLVM_READONLY
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())
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
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.
detail::InMemoryDirectory::const_iterator E
body_iterator body_begin()
specific_decl_iterator - Iterates over a subrange of declarations stored in a DeclContext, providing only those that are of type SpecificDecl (or a class derived from it).
const Stmt * getThen() const
Represents a pointer to an Objective C object.
ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...
const T * getAs() const
Member-template getAs<specific type>'.
Base for LValueReferenceType and RValueReferenceType.
void removeZeroOutPropsInDeallocFinalize(MigrationPass &pass)
SourceManager & getSourceManager()
An attributed type is a type to which a type attribute has been applied.
WhileStmt - This represents a 'while' stmt.
Defines the clang::TargetInfo interface.
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
TranslationUnitDecl - The top declaration context.
A reference to a declared variable, function, enum, etc.
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
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.