21 using namespace clang;
22 using namespace arcmt;
23 using namespace trans;
28 if (!EnableCFBridgeFns.hasValue())
29 EnableCFBridgeFns = SemaRef.isKnownName(
"CFBridgingRetain") &&
30 SemaRef.isKnownName(
"CFBridgingRelease");
31 return *EnableCFBridgeFns;
39 bool AllowOnUnknownClass) {
50 AllowOnUnknownClass =
true;
56 if (!AllowOnUnknownClass && (!Class || Class->
getName() ==
"NSObject"))
77 if (
const FullExpr *FE = dyn_cast<FullExpr>(E))
88 if (FD->hasAttr<CFReturnsRetainedAttr>())
92 FD->getIdentifier() &&
93 FD->getParent()->isTranslationUnit() &&
94 FD->isExternallyVisible() &&
96 FD->getIdentifier()->getName())) {
97 StringRef fname = FD->getIdentifier()->getName();
98 if (fname.endswith(
"Retain") ||
99 fname.find(
"Create") != StringRef::npos ||
100 fname.find(
"Copy") != StringRef::npos) {
108 while (implCE && implCE->
getCastKind() == CK_BitCast)
109 implCE = dyn_cast<ImplicitCastExpr>(implCE->
getSubExpr());
111 return implCE && implCE->
getCastKind() == CK_ARCConsumeObject;
144 bool invalidTemp =
false;
145 StringRef file = SM.
getBufferData(locInfo.first, &invalidTemp);
149 const char *tokenBegin = file.data() + locInfo.second;
154 file.begin(), tokenBegin, file.end());
156 lexer.LexFromRawLexer(tok);
157 if (tok.isNot(tok::semi)) {
165 return tok.getLocation();
200 return DRE->getDecl()->getDeclContext()->isFileContext() &&
201 DRE->getDecl()->isExternallyVisible();
218 ReferenceClear(
ExprSet &refs) : Refs(refs) { }
219 bool VisitDeclRefExpr(
DeclRefExpr *E) { Refs.erase(E);
return true; }
228 : Dcl(D), Refs(refs) { }
241 RemovablesCollector(
ExprSet &removables)
242 : Removables(removables) { }
244 bool shouldWalkTypesOfTypeLocs()
const {
return false; }
246 bool TraverseStmtExpr(
StmtExpr *E) {
258 for (
auto *I : S->
body())
263 bool VisitIfStmt(
IfStmt *S) {
274 bool VisitDoStmt(
DoStmt *S) {
279 bool VisitForStmt(
ForStmt *S) {
291 S =
Label->getSubStmt();
293 if (
Expr *E = dyn_cast<Expr>(S))
294 Removables.insert(E);
301 ReferenceClear(refs).TraverseStmt(S);
305 ReferenceCollector(D, refs).TraverseStmt(S);
309 RemovablesCollector(exprs).TraverseStmt(S);
325 bool shouldWalkTypesOfTypeLocs()
const {
return false; }
332 (*I)->traverseObjCImplementation(ImplCtx);
334 return base::TraverseObjCImplementationDecl(D);
337 bool TraverseStmt(
Stmt *rootS) {
345 (*I)->traverseBody(BodyCtx);
355 I = traversers_begin(), E = traversers_end(); I != E; ++I)
362 if (AttrT->getAttrKind() == attr::ObjCOwnership)
363 return !AttrT->getModifiedType()->isObjCRetainableType();
367 T = Pass.Ctx.getBaseElementType(T);
391 bool invalidTemp =
false;
392 StringRef file = SM.
getBufferData(locInfo.first, &invalidTemp);
396 const char *tokenBegin = file.data() + locInfo.second;
400 Pass.Ctx.getLangOpts(),
401 file.begin(), tokenBegin, file.end());
403 lexer.LexFromRawLexer(tok);
404 if (tok.isNot(tok::at))
return false;
405 lexer.LexFromRawLexer(tok);
406 if (tok.isNot(tok::raw_identifier))
return false;
407 if (tok.getRawIdentifier() !=
"property")
409 lexer.LexFromRawLexer(tok);
410 if (tok.isNot(tok::l_paren))
return false;
412 Token BeforeTok = tok;
417 lexer.LexFromRawLexer(tok);
418 if (tok.is(tok::r_paren))
422 if (tok.isNot(tok::raw_identifier))
return false;
423 if (tok.getRawIdentifier() == fromAttr) {
424 if (!toAttr.empty()) {
425 Pass.TA.replaceText(tok.getLocation(), fromAttr, toAttr);
429 AttrLoc = tok.getLocation();
433 lexer.LexFromRawLexer(tok);
434 if (AttrLoc.
isValid() && AfterTok.
is(tok::unknown))
436 }
while (tok.isNot(tok::comma) && tok.isNot(tok::r_paren));
437 if (tok.is(tok::r_paren))
441 lexer.LexFromRawLexer(tok);
444 if (toAttr.empty() && AttrLoc.
isValid() && AfterTok.
isNot(tok::unknown)) {
446 if (BeforeTok.
is(tok::l_paren) && AfterTok.
is(tok::r_paren)) {
449 }
else if (BeforeTok.
is(tok::l_paren) && AfterTok.
is(tok::comma)) {
472 bool invalidTemp =
false;
473 StringRef file = SM.
getBufferData(locInfo.first, &invalidTemp);
477 const char *tokenBegin = file.data() + locInfo.second;
481 Pass.Ctx.getLangOpts(),
482 file.begin(), tokenBegin, file.end());
484 lexer.LexFromRawLexer(tok);
485 if (tok.isNot(tok::at))
return false;
486 lexer.LexFromRawLexer(tok);
487 if (tok.isNot(tok::raw_identifier))
return false;
488 if (tok.getRawIdentifier() !=
"property")
490 lexer.LexFromRawLexer(tok);
492 if (tok.isNot(tok::l_paren)) {
493 Pass.TA.insert(tok.getLocation(), std::string(
"(") + attr.str() +
") ");
497 lexer.LexFromRawLexer(tok);
498 if (tok.is(tok::r_paren)) {
499 Pass.TA.insert(tok.getLocation(), attr);
503 if (tok.isNot(tok::raw_identifier))
return false;
505 Pass.TA.insert(tok.getLocation(), std::string(attr) +
", ");
511 I = traversers_begin(), E = traversers_end(); I != E; ++I)
512 (*I)->traverseTU(*
this);
514 ASTTransform(*this).TraverseDecl(TU);
526 for (impl_iterator I = impl_iterator(DC->
decls_begin()),
527 E = impl_iterator(DC->
decls_end()); I != E; ++I) {
528 for (
const auto *MD : I->instance_methods()) {
532 if (MD->isInstanceMethod() && MD->getSelector() == FinalizeSel) {
536 "#if !__has_feature(objc_arc)\n");
541 std::string
str =
"\n#endif\n";
544 SM, LangOpts, &Invalid);
584 bool NoFinalizeRemoval) {
585 std::vector<TransformFn> transforms;
SourceLocation getLocForStartOfFile(FileID FID) const
Return the source location corresponding to the first byte of the specified file. ...
The receiver is the instance of the superclass object.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
Defines the clang::ASTContext interface.
bool hasDefinition() const
Determine whether this class has been defined.
Represents a function declaration or definition.
The receiver is an object instance.
Lexer - This provides a simple interface that turns a text buffer into a stream of tokens...
SourceLocation getLocWithOffset(int Offset) const
Return a source location with the specified offset from this SourceLocation.
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)
CompoundStmt * getSubStmt()
Stmt - This represents one statement.
IfStmt - This represents an if/then/else.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
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)) {...
Defines the SourceManager interface.
static CharSourceRange getTokenRange(SourceRange R)
const TargetInfo & getTargetInfo() const
Stmt * IgnoreImplicit()
Skip past any implicit AST nodes which might surround this statement, such as ExprWithCleanups or Imp...
traverser_iterator traversers_begin()
StringRef getBufferData(FileID FID, bool *Invalid=nullptr) const
Return a StringRef to the source buffer data for the specified FileID.
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.
const T * getAs() const
Member-template getAs<specific type>'.
void makeAssignARCSafe(MigrationPass &pass)
std::vector< ASTTraverser * >::iterator traverser_iterator
ObjCMethodDecl - Represents an instance or class method declaration.
void clearRefsIn(Stmt *S, ExprSet &refs)
LabelStmt - Represents a label, which has a substatement.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
FullExpr - Represents a "full-expression" node.
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.
void removeRetainReleaseDeallocFinalize(MigrationPass &pass)
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 preorder or postorder depth-first traversal on the entire Clang AST and visits each...
Represents an ObjC class declaration.
bool isPlusOneAssign(const BinaryOperator *E)
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 }.
static StringRef getSourceText(CharSourceRange Range, const SourceManager &SM, const LangOptions &LangOpts, bool *Invalid=nullptr)
Returns a string for the source that the range encompasses.
bool HasSideEffects(const ASTContext &Ctx, bool IncludePossibleEffects=true) const
HasSideEffects - This routine returns true for all those expressions which have any effect other than...
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)
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
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)
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file. ...
Defines the clang::Preprocessor interface.
void checkAPIUses(MigrationPass &pass)
An expression that sends a message to the given Objective-C object or class.
SourceLocation getEnd() const
ReceiverKind getReceiverKind() const
Determine the kind of receiver that this message is being sent to.
bool addPropertyAttribute(StringRef attr, SourceLocation atLoc)
bool isNull() const
Return true if this QualType doesn't point to a type yet.
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.
decl_iterator decls_begin() const
CastKind getCastKind() const
ObjCMethodFamily getMethodFamily() const
traverser_iterator traversers_end()
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
StmtExpr - This is the GNU Statement Expression extension: ({int X=4; X;}).
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 isNot(tok::TokenKind K) const
Dataflow Directional Tag Classes.
bool isRefType(QualType RetTy, StringRef Prefix, StringRef Name=StringRef())
bool isValid() const
Return true if this is a valid SourceLocation object.
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)
std::vector< TransformFn > getAllTransformations(LangOptions::GCMode OrigGCMode, bool NoFinalizeRemoval)
bool isPlusOne(const Expr *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).
Represents a pointer to an Objective C object.
ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...
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.
TranslationUnitDecl * getTranslationUnitDecl() const
WhileStmt - This represents a 'while' stmt.
Defines the clang::TargetInfo interface.
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
bool isArcWeakrefUnavailable() const
isArcWeakrefUnavailable - Checks for a class or one of its super classes to be incompatible with __we...
The top declaration context.
bool isGCMigration() const
A reference to a declared variable, function, enum, etc.
A trivial tuple used to represent a source range.
SourceLocation getBegin() const
const LangOptions & getLangOpts() const
This class handles loading and caching of source files into memory.
void startToken()
Reset all flags to cleared.
std::pair< FileID, unsigned > getDecomposedLoc(SourceLocation Loc) const
Decompose the specified location into a raw FileID + Offset pair.
decl_iterator decls_end() const