clang  14.0.0git
TransAPIUses.cpp
Go to the documentation of this file.
1 //===--- TransAPIUses.cpp - Transformations to ARC mode -------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // checkAPIUses:
10 //
11 // Emits error/fix with some API uses that are obsolete or not safe in ARC mode:
12 //
13 // - NSInvocation's [get/set]ReturnValue and [get/set]Argument are only safe
14 // with __unsafe_unretained objects.
15 // - Calling -zone gets replaced with 'nil'.
16 //
17 //===----------------------------------------------------------------------===//
18 
19 #include "Transforms.h"
20 #include "Internals.h"
21 #include "clang/AST/ASTContext.h"
23 
24 using namespace clang;
25 using namespace arcmt;
26 using namespace trans;
27 
28 namespace {
29 
30 class APIChecker : public RecursiveASTVisitor<APIChecker> {
31  MigrationPass &Pass;
32 
33  Selector getReturnValueSel, setReturnValueSel;
34  Selector getArgumentSel, setArgumentSel;
35 
36  Selector zoneSel;
37 public:
38  APIChecker(MigrationPass &pass) : Pass(pass) {
39  SelectorTable &sels = Pass.Ctx.Selectors;
40  IdentifierTable &ids = Pass.Ctx.Idents;
41  getReturnValueSel = sels.getUnarySelector(&ids.get("getReturnValue"));
42  setReturnValueSel = sels.getUnarySelector(&ids.get("setReturnValue"));
43 
44  IdentifierInfo *selIds[2];
45  selIds[0] = &ids.get("getArgument");
46  selIds[1] = &ids.get("atIndex");
47  getArgumentSel = sels.getSelector(2, selIds);
48  selIds[0] = &ids.get("setArgument");
49  setArgumentSel = sels.getSelector(2, selIds);
50 
51  zoneSel = sels.getNullarySelector(&ids.get("zone"));
52  }
53 
54  bool VisitObjCMessageExpr(ObjCMessageExpr *E) {
55  // NSInvocation.
56  if (E->isInstanceMessage() &&
57  E->getReceiverInterface() &&
58  E->getReceiverInterface()->getName() == "NSInvocation") {
59  StringRef selName;
60  if (E->getSelector() == getReturnValueSel)
61  selName = "getReturnValue";
62  else if (E->getSelector() == setReturnValueSel)
63  selName = "setReturnValue";
64  else if (E->getSelector() == getArgumentSel)
65  selName = "getArgument";
66  else if (E->getSelector() == setArgumentSel)
67  selName = "setArgument";
68  else
69  return true;
70 
71  Expr *parm = E->getArg(0)->IgnoreParenCasts();
72  QualType pointee = parm->getType()->getPointeeType();
73  if (pointee.isNull())
74  return true;
75 
77  Pass.TA.report(parm->getBeginLoc(),
78  diag::err_arcmt_nsinvocation_ownership,
79  parm->getSourceRange())
80  << selName;
81 
82  return true;
83  }
84 
85  // -zone.
86  if (E->isInstanceMessage() &&
87  E->getInstanceReceiver() &&
88  E->getSelector() == zoneSel &&
89  Pass.TA.hasDiagnostic(diag::err_unavailable,
90  diag::err_unavailable_message,
91  E->getSelectorLoc(0))) {
92  // Calling -zone is meaningless in ARC, change it to nil.
93  Transaction Trans(Pass.TA);
94  Pass.TA.clearDiagnostic(diag::err_unavailable,
95  diag::err_unavailable_message,
96  E->getSelectorLoc(0));
97  Pass.TA.replace(E->getSourceRange(), getNilString(Pass));
98  }
99  return true;
100  }
101 };
102 
103 } // anonymous namespace
104 
106  APIChecker(pass).TraverseDecl(pass.Ctx.getTranslationUnitDecl());
107 }
clang::ObjCMessageExpr::isInstanceMessage
bool isInstanceMessage() const
Determine whether this is an instance message to either a computed object or to super.
Definition: ExprObjC.h:1238
clang::ObjCMessageExpr::getReceiverInterface
ObjCInterfaceDecl * getReceiverInterface() const
Retrieve the Objective-C interface to which this message is being directed, if known.
Definition: ExprObjC.cpp:314
clang::QualType::getObjCLifetime
Qualifiers::ObjCLifetime getObjCLifetime() const
Returns lifetime attribute of this type.
Definition: Type.h:1120
clang::arcmt::MigrationPass
Definition: Internals.h:146
clang::ObjCMessageExpr::getSelector
Selector getSelector() const
Definition: ExprObjC.cpp:293
Transforms.h
clang::IdentifierTable::get
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
Definition: IdentifierTable.h:592
clang::ObjCMessageExpr::getSelectorLoc
SourceLocation getSelectorLoc(unsigned Index) const
Definition: ExprObjC.h:1415
clang::Stmt::getSourceRange
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Definition: Stmt.cpp:324
clang::QualType
A (possibly-)qualified type.
Definition: Type.h:673
clang::ObjCMessageExpr::getInstanceReceiver
Expr * getInstanceReceiver()
Returns the object expression (receiver) for an instance message, or null for a message that is not a...
Definition: ExprObjC.h:1250
Internals.h
clang::Qualifiers::OCL_ExplicitNone
@ OCL_ExplicitNone
This object can be modified without requiring retains or releases.
Definition: Type.h:166
clang::arcmt::MigrationPass::TA
TransformActions & TA
Definition: Internals.h:152
clang::ASTContext::getTranslationUnitDecl
TranslationUnitDecl * getTranslationUnitDecl() const
Definition: ASTContext.h:1057
clang::ObjCMessageExpr::getArg
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
Definition: ExprObjC.h:1385
clang::arcmt::Transaction
Definition: Internals.h:124
clang::SelectorTable::getSelector
Selector getSelector(unsigned NumArgs, IdentifierInfo **IIV)
Can create any sort of selector.
Definition: IdentifierTable.cpp:701
clang::ASTContext::Selectors
SelectorTable & Selectors
Definition: ASTContext.h:649
clang::arcmt::TransformActions::replace
void replace(SourceRange range, StringRef text)
Definition: TransformActions.cpp:646
clang::RecursiveASTVisitor
A class that does preorder or postorder depth-first traversal on the entire Clang AST and visits each...
Definition: RecursiveASTVisitor.h:164
clang::SelectorTable
This table allows us to fully hide how we implement multi-keyword caching.
Definition: IdentifierTable.h:893
ASTContext.h
clang::Type::getPointeeType
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Definition: Type.cpp:625
clang::arcmt::MigrationPass::Ctx
ASTContext & Ctx
Definition: Internals.h:148
clang::ObjCMessageExpr
An expression that sends a message to the given Objective-C object or class.
Definition: ExprObjC.h:940
clang::arcmt::TransformActions::hasDiagnostic
bool hasDiagnostic(unsigned ID, SourceRange range)
Definition: Internals.h:89
clang::Expr::IgnoreParenCasts
Expr * IgnoreParenCasts() LLVM_READONLY
Skip past any parentheses and casts which might surround this expression until reaching a fixed point...
Definition: Expr.cpp:2921
clang::arcmt::trans::checkAPIUses
void checkAPIUses(MigrationPass &pass)
Definition: TransAPIUses.cpp:105
SemaDiagnostic.h
clang::ASTContext::Idents
IdentifierTable & Idents
Definition: ASTContext.h:648
clang::QualType::isNull
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition: Type.h:738
clang::arcmt::TransformActions::report
DiagnosticBuilder report(SourceLocation loc, unsigned diagId, SourceRange range=SourceRange())
Definition: TransformActions.cpp:680
clang::IdentifierInfo
One of these records is kept for each identifier that is lexed.
Definition: IdentifierTable.h:84
clang::SelectorTable::getNullarySelector
Selector getNullarySelector(IdentifierInfo *ID)
Definition: IdentifierTable.h:913
clang::SelectorTable::getUnarySelector
Selector getUnarySelector(IdentifierInfo *ID)
Definition: IdentifierTable.h:909
clang
Definition: CalledOnceCheck.h:17
clang::Selector
Smart pointer class that efficiently represents Objective-C method names.
Definition: IdentifierTable.h:748
clang::Expr::getType
QualType getType() const
Definition: Expr.h:141
clang::IdentifierTable
Implements an efficient mapping from strings to IdentifierInfo nodes.
Definition: IdentifierTable.h:559
clang::Stmt::getBeginLoc
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: Stmt.cpp:336
clang::arcmt::TransformActions::clearDiagnostic
bool clearDiagnostic(ArrayRef< unsigned > IDs, SourceRange range)
Definition: TransformActions.cpp:671
clang::Expr
This represents one expression.
Definition: Expr.h:109
clang::arcmt::trans::getNilString
StringRef getNilString(MigrationPass &Pass)
Returns "nil" or "0" if 'nil' macro is not actually defined.
Definition: Transforms.cpp:207
clang::NamedDecl::getName
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Definition: Decl.h:276