clang  3.7.0
Transforms.cpp
Go to the documentation of this file.
1 //===--- Transforms.cpp - Transformations to ARC mode ---------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "Transforms.h"
11 #include "Internals.h"
12 #include "clang/AST/ASTContext.h"
14 #include "clang/AST/StmtVisitor.h"
17 #include "clang/Basic/TargetInfo.h"
18 #include "clang/Lex/Lexer.h"
19 #include "clang/Lex/Preprocessor.h"
20 #include "clang/Sema/Sema.h"
22 #include "llvm/ADT/DenseSet.h"
23 #include "llvm/ADT/StringSwitch.h"
24 #include <map>
25 
26 using namespace clang;
27 using namespace arcmt;
28 using namespace trans;
29 
31 
33  if (!EnableCFBridgeFns.hasValue())
34  EnableCFBridgeFns = SemaRef.isKnownName("CFBridgingRetain") &&
35  SemaRef.isKnownName("CFBridgingRelease");
36  return *EnableCFBridgeFns;
37 }
38 
39 //===----------------------------------------------------------------------===//
40 // Helpers.
41 //===----------------------------------------------------------------------===//
42 
44  bool AllowOnUnknownClass) {
45  if (!Ctx.getLangOpts().ObjCARCWeak)
46  return false;
47 
48  QualType T = type;
49  if (T.isNull())
50  return false;
51 
52  // iOS is always safe to use 'weak'.
53  if (Ctx.getTargetInfo().getTriple().isiOS())
54  AllowOnUnknownClass = true;
55 
56  while (const PointerType *ptr = T->getAs<PointerType>())
57  T = ptr->getPointeeType();
58  if (const ObjCObjectPointerType *ObjT = T->getAs<ObjCObjectPointerType>()) {
59  ObjCInterfaceDecl *Class = ObjT->getInterfaceDecl();
60  if (!AllowOnUnknownClass && (!Class || Class->getName() == "NSObject"))
61  return false; // id/NSObject is not safe for weak.
62  if (!AllowOnUnknownClass && !Class->hasDefinition())
63  return false; // forward classes are not verifiable, therefore not safe.
64  if (Class && Class->isArcWeakrefUnavailable())
65  return false;
66  }
67 
68  return true;
69 }
70 
72  if (E->getOpcode() != BO_Assign)
73  return false;
74 
75  return isPlusOne(E->getRHS());
76 }
77 
78 bool trans::isPlusOne(const Expr *E) {
79  if (!E)
80  return false;
81  if (const ExprWithCleanups *EWC = dyn_cast<ExprWithCleanups>(E))
82  E = EWC->getSubExpr();
83 
84  if (const ObjCMessageExpr *
85  ME = dyn_cast<ObjCMessageExpr>(E->IgnoreParenCasts()))
86  if (ME->getMethodFamily() == OMF_retain)
87  return true;
88 
89  if (const CallExpr *
90  callE = dyn_cast<CallExpr>(E->IgnoreParenCasts())) {
91  if (const FunctionDecl *FD = callE->getDirectCallee()) {
92  if (FD->hasAttr<CFReturnsRetainedAttr>())
93  return true;
94 
95  if (FD->isGlobal() &&
96  FD->getIdentifier() &&
97  FD->getParent()->isTranslationUnit() &&
98  FD->isExternallyVisible() &&
99  ento::cocoa::isRefType(callE->getType(), "CF",
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) {
105  return true;
106  }
107  }
108  }
109  }
110 
111  const ImplicitCastExpr *implCE = dyn_cast<ImplicitCastExpr>(E);
112  while (implCE && implCE->getCastKind() == CK_BitCast)
113  implCE = dyn_cast<ImplicitCastExpr>(implCE->getSubExpr());
114 
115  if (implCE && implCE->getCastKind() == CK_ARCConsumeObject)
116  return true;
117 
118  return false;
119 }
120 
121 /// \brief 'Loc' is the end of a statement range. This returns the location
122 /// immediately after the semicolon following the statement.
123 /// If no semicolon is found or the location is inside a macro, the returned
124 /// source location will be invalid.
126  ASTContext &Ctx, bool IsDecl) {
127  SourceLocation SemiLoc = findSemiAfterLocation(loc, Ctx, IsDecl);
128  if (SemiLoc.isInvalid())
129  return SourceLocation();
130  return SemiLoc.getLocWithOffset(1);
131 }
132 
133 /// \brief \arg Loc is the end of a statement range. This returns the location
134 /// of the semicolon following the statement.
135 /// If no semicolon is found or the location is inside a macro, the returned
136 /// source location will be invalid.
138  ASTContext &Ctx,
139  bool IsDecl) {
141  if (loc.isMacroID()) {
142  if (!Lexer::isAtEndOfMacroExpansion(loc, SM, Ctx.getLangOpts(), &loc))
143  return SourceLocation();
144  }
145  loc = Lexer::getLocForEndOfToken(loc, /*Offset=*/0, SM, Ctx.getLangOpts());
146 
147  // Break down the source location.
148  std::pair<FileID, unsigned> locInfo = SM.getDecomposedLoc(loc);
149 
150  // Try to load the file buffer.
151  bool invalidTemp = false;
152  StringRef file = SM.getBufferData(locInfo.first, &invalidTemp);
153  if (invalidTemp)
154  return SourceLocation();
155 
156  const char *tokenBegin = file.data() + locInfo.second;
157 
158  // Lex from the start of the given location.
159  Lexer lexer(SM.getLocForStartOfFile(locInfo.first),
160  Ctx.getLangOpts(),
161  file.begin(), tokenBegin, file.end());
162  Token tok;
163  lexer.LexFromRawLexer(tok);
164  if (tok.isNot(tok::semi)) {
165  if (!IsDecl)
166  return SourceLocation();
167  // Declaration may be followed with other tokens; such as an __attribute,
168  // before ending with a semicolon.
169  return findSemiAfterLocation(tok.getLocation(), Ctx, /*IsDecl*/true);
170  }
171 
172  return tok.getLocation();
173 }
174 
176  if (!E || !E->HasSideEffects(Ctx))
177  return false;
178 
179  E = E->IgnoreParenCasts();
180  ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(E);
181  if (!ME)
182  return true;
183  switch (ME->getMethodFamily()) {
184  case OMF_autorelease:
185  case OMF_dealloc:
186  case OMF_release:
187  case OMF_retain:
188  switch (ME->getReceiverKind()) {
190  return false;
192  return hasSideEffects(ME->getInstanceReceiver(), Ctx);
193  default:
194  break;
195  }
196  break;
197  default:
198  break;
199  }
200 
201  return true;
202 }
203 
205  E = E->IgnoreParenCasts();
206  if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
207  return DRE->getDecl()->getDeclContext()->isFileContext() &&
208  DRE->getDecl()->isExternallyVisible();
209  if (ConditionalOperator *condOp = dyn_cast<ConditionalOperator>(E))
210  return isGlobalVar(condOp->getTrueExpr()) &&
211  isGlobalVar(condOp->getFalseExpr());
212 
213  return false;
214 }
215 
217  return Pass.SemaRef.PP.isMacroDefined("nil") ? "nil" : "0";
218 }
219 
220 namespace {
221 
222 class ReferenceClear : public RecursiveASTVisitor<ReferenceClear> {
223  ExprSet &Refs;
224 public:
225  ReferenceClear(ExprSet &refs) : Refs(refs) { }
226  bool VisitDeclRefExpr(DeclRefExpr *E) { Refs.erase(E); return true; }
227 };
228 
229 class ReferenceCollector : public RecursiveASTVisitor<ReferenceCollector> {
230  ValueDecl *Dcl;
231  ExprSet &Refs;
232 
233 public:
234  ReferenceCollector(ValueDecl *D, ExprSet &refs)
235  : Dcl(D), Refs(refs) { }
236 
237  bool VisitDeclRefExpr(DeclRefExpr *E) {
238  if (E->getDecl() == Dcl)
239  Refs.insert(E);
240  return true;
241  }
242 };
243 
244 class RemovablesCollector : public RecursiveASTVisitor<RemovablesCollector> {
245  ExprSet &Removables;
246 
247 public:
248  RemovablesCollector(ExprSet &removables)
249  : Removables(removables) { }
250 
251  bool shouldWalkTypesOfTypeLocs() const { return false; }
252 
253  bool TraverseStmtExpr(StmtExpr *E) {
254  CompoundStmt *S = E->getSubStmt();
256  I = S->body_begin(), E = S->body_end(); I != E; ++I) {
257  if (I != E - 1)
258  mark(*I);
259  TraverseStmt(*I);
260  }
261  return true;
262  }
263 
264  bool VisitCompoundStmt(CompoundStmt *S) {
265  for (auto *I : S->body())
266  mark(I);
267  return true;
268  }
269 
270  bool VisitIfStmt(IfStmt *S) {
271  mark(S->getThen());
272  mark(S->getElse());
273  return true;
274  }
275 
276  bool VisitWhileStmt(WhileStmt *S) {
277  mark(S->getBody());
278  return true;
279  }
280 
281  bool VisitDoStmt(DoStmt *S) {
282  mark(S->getBody());
283  return true;
284  }
285 
286  bool VisitForStmt(ForStmt *S) {
287  mark(S->getInit());
288  mark(S->getInc());
289  mark(S->getBody());
290  return true;
291  }
292 
293 private:
294  void mark(Stmt *S) {
295  if (!S) return;
296 
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);
302  }
303 };
304 
305 } // end anonymous namespace
306 
307 void trans::clearRefsIn(Stmt *S, ExprSet &refs) {
308  ReferenceClear(refs).TraverseStmt(S);
309 }
310 
312  ReferenceCollector(D, refs).TraverseStmt(S);
313 }
314 
316  RemovablesCollector(exprs).TraverseStmt(S);
317 }
318 
319 //===----------------------------------------------------------------------===//
320 // MigrationContext
321 //===----------------------------------------------------------------------===//
322 
323 namespace {
324 
325 class ASTTransform : public RecursiveASTVisitor<ASTTransform> {
326  MigrationContext &MigrateCtx;
328 
329 public:
330  ASTTransform(MigrationContext &MigrateCtx) : MigrateCtx(MigrateCtx) { }
331 
332  bool shouldWalkTypesOfTypeLocs() const { return false; }
333 
334  bool TraverseObjCImplementationDecl(ObjCImplementationDecl *D) {
335  ObjCImplementationContext ImplCtx(MigrateCtx, D);
337  I = MigrateCtx.traversers_begin(),
338  E = MigrateCtx.traversers_end(); I != E; ++I)
339  (*I)->traverseObjCImplementation(ImplCtx);
340 
341  return base::TraverseObjCImplementationDecl(D);
342  }
343 
344  bool TraverseStmt(Stmt *rootS) {
345  if (!rootS)
346  return true;
347 
348  BodyContext BodyCtx(MigrateCtx, rootS);
350  I = MigrateCtx.traversers_begin(),
351  E = MigrateCtx.traversers_end(); I != E; ++I)
352  (*I)->traverseBody(BodyCtx);
353 
354  return true;
355  }
356 };
357 
358 }
359 
361  for (traverser_iterator
362  I = traversers_begin(), E = traversers_end(); I != E; ++I)
363  delete *I;
364 }
365 
367  while (!T.isNull()) {
368  if (const AttributedType *AttrT = T->getAs<AttributedType>()) {
369  if (AttrT->getAttrKind() == AttributedType::attr_objc_ownership)
370  return !AttrT->getModifiedType()->isObjCRetainableType();
371  }
372 
373  if (T->isArrayType())
374  T = Pass.Ctx.getBaseElementType(T);
375  else if (const PointerType *PT = T->getAs<PointerType>())
376  T = PT->getPointeeType();
377  else if (const ReferenceType *RT = T->getAs<ReferenceType>())
378  T = RT->getPointeeType();
379  else
380  break;
381  }
382 
383  return false;
384 }
385 
387  StringRef toAttr,
388  SourceLocation atLoc) {
389  if (atLoc.isMacroID())
390  return false;
391 
393 
394  // Break down the source location.
395  std::pair<FileID, unsigned> locInfo = SM.getDecomposedLoc(atLoc);
396 
397  // Try to load the file buffer.
398  bool invalidTemp = false;
399  StringRef file = SM.getBufferData(locInfo.first, &invalidTemp);
400  if (invalidTemp)
401  return false;
402 
403  const char *tokenBegin = file.data() + locInfo.second;
404 
405  // Lex from the start of the given location.
406  Lexer lexer(SM.getLocForStartOfFile(locInfo.first),
407  Pass.Ctx.getLangOpts(),
408  file.begin(), tokenBegin, file.end());
409  Token tok;
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")
415  return false;
416  lexer.LexFromRawLexer(tok);
417  if (tok.isNot(tok::l_paren)) return false;
418 
419  Token BeforeTok = tok;
420  Token AfterTok;
421  AfterTok.startToken();
422  SourceLocation AttrLoc;
423 
424  lexer.LexFromRawLexer(tok);
425  if (tok.is(tok::r_paren))
426  return false;
427 
428  while (1) {
429  if (tok.isNot(tok::raw_identifier)) return false;
430  if (tok.getRawIdentifier() == fromAttr) {
431  if (!toAttr.empty()) {
432  Pass.TA.replaceText(tok.getLocation(), fromAttr, toAttr);
433  return true;
434  }
435  // We want to remove the attribute.
436  AttrLoc = tok.getLocation();
437  }
438 
439  do {
440  lexer.LexFromRawLexer(tok);
441  if (AttrLoc.isValid() && AfterTok.is(tok::unknown))
442  AfterTok = tok;
443  } while (tok.isNot(tok::comma) && tok.isNot(tok::r_paren));
444  if (tok.is(tok::r_paren))
445  break;
446  if (AttrLoc.isInvalid())
447  BeforeTok = tok;
448  lexer.LexFromRawLexer(tok);
449  }
450 
451  if (toAttr.empty() && AttrLoc.isValid() && AfterTok.isNot(tok::unknown)) {
452  // We want to remove the attribute.
453  if (BeforeTok.is(tok::l_paren) && AfterTok.is(tok::r_paren)) {
454  Pass.TA.remove(SourceRange(BeforeTok.getLocation(),
455  AfterTok.getLocation()));
456  } else if (BeforeTok.is(tok::l_paren) && AfterTok.is(tok::comma)) {
457  Pass.TA.remove(SourceRange(AttrLoc, AfterTok.getLocation()));
458  } else {
459  Pass.TA.remove(SourceRange(BeforeTok.getLocation(), AttrLoc));
460  }
461 
462  return true;
463  }
464 
465  return false;
466 }
467 
469  SourceLocation atLoc) {
470  if (atLoc.isMacroID())
471  return false;
472 
474 
475  // Break down the source location.
476  std::pair<FileID, unsigned> locInfo = SM.getDecomposedLoc(atLoc);
477 
478  // Try to load the file buffer.
479  bool invalidTemp = false;
480  StringRef file = SM.getBufferData(locInfo.first, &invalidTemp);
481  if (invalidTemp)
482  return false;
483 
484  const char *tokenBegin = file.data() + locInfo.second;
485 
486  // Lex from the start of the given location.
487  Lexer lexer(SM.getLocForStartOfFile(locInfo.first),
488  Pass.Ctx.getLangOpts(),
489  file.begin(), tokenBegin, file.end());
490  Token tok;
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")
496  return false;
497  lexer.LexFromRawLexer(tok);
498 
499  if (tok.isNot(tok::l_paren)) {
500  Pass.TA.insert(tok.getLocation(), std::string("(") + attr.str() + ") ");
501  return true;
502  }
503 
504  lexer.LexFromRawLexer(tok);
505  if (tok.is(tok::r_paren)) {
506  Pass.TA.insert(tok.getLocation(), attr);
507  return true;
508  }
509 
510  if (tok.isNot(tok::raw_identifier)) return false;
511 
512  Pass.TA.insert(tok.getLocation(), std::string(attr) + ", ");
513  return true;
514 }
515 
517  for (traverser_iterator
518  I = traversers_begin(), E = traversers_end(); I != E; ++I)
519  (*I)->traverseTU(*this);
520 
521  ASTTransform(*this).TraverseDecl(TU);
522 }
523 
524 static void GCRewriteFinalize(MigrationPass &pass) {
525  ASTContext &Ctx = pass.Ctx;
526  TransformActions &TA = pass.TA;
528  Selector FinalizeSel =
529  Ctx.Selectors.getNullarySelector(&pass.Ctx.Idents.get("finalize"));
530 
532  impl_iterator;
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()) {
536  if (!MD->hasBody())
537  continue;
538 
539  if (MD->isInstanceMethod() && MD->getSelector() == FinalizeSel) {
540  const ObjCMethodDecl *FinalizeM = MD;
541  Transaction Trans(TA);
542  TA.insert(FinalizeM->getSourceRange().getBegin(),
543  "#if !__has_feature(objc_arc)\n");
545  const SourceManager &SM = pass.Ctx.getSourceManager();
546  const LangOptions &LangOpts = pass.Ctx.getLangOpts();
547  bool Invalid;
548  std::string str = "\n#endif\n";
549  str += Lexer::getSourceText(
551  SM, LangOpts, &Invalid);
552  TA.insertAfterToken(FinalizeM->getSourceRange().getEnd(), str);
553 
554  break;
555  }
556  }
557  }
558 }
559 
560 //===----------------------------------------------------------------------===//
561 // getAllTransformations.
562 //===----------------------------------------------------------------------===//
563 
564 static void traverseAST(MigrationPass &pass) {
565  MigrationContext MigrateCtx(pass);
566 
567  if (pass.isGCMigration()) {
569  MigrateCtx.addTraverser(new GCAttrsTraverser());
570  }
571  MigrateCtx.addTraverser(new PropertyRewriteTraverser());
572  MigrateCtx.addTraverser(new BlockObjCVariableTraverser());
573  MigrateCtx.addTraverser(new ProtectedScopeTraverser());
574 
575  MigrateCtx.traverse(pass.Ctx.getTranslationUnitDecl());
576 }
577 
583  makeAssignARCSafe(pass);
584  rewriteUnbridgedCasts(pass);
585  checkAPIUses(pass);
586  traverseAST(pass);
587 }
588 
589 std::vector<TransformFn> arcmt::getAllTransformations(
590  LangOptions::GCMode OrigGCMode,
591  bool NoFinalizeRemoval) {
592  std::vector<TransformFn> transforms;
593 
594  if (OrigGCMode == LangOptions::GCOnly && NoFinalizeRemoval)
595  transforms.push_back(GCRewriteFinalize);
596  transforms.push_back(independentTransforms);
597  // This depends on previous transformations removing various expressions.
598  transforms.push_back(removeEmptyStatementsAndDeallocFinalize);
599 
600  return transforms;
601 }
Expr * getInc()
Definition: Stmt.h:1178
The receiver is the instance of the superclass object.
Definition: ExprObjC.h:1006
static void independentTransforms(MigrationPass &pass)
Definition: Transforms.cpp:578
bool hasDefinition() const
Determine whether this class has been defined.
Definition: DeclObjC.h:1200
Defines the clang::ASTContext interface.
SourceLocation getEnd() const
CastKind getCastKind() const
Definition: Expr.h:2709
The receiver is an object instance.
Definition: ExprObjC.h:1002
body_iterator body_end()
Definition: Stmt.h:587
StringRef getName() const
Definition: Decl.h:168
Smart pointer class that efficiently represents Objective-C method names.
bool isMacroID() const
ObjCMethodFamily getMethodFamily() const
Definition: ExprObjC.h:1267
CompoundStmt * getSubStmt()
Definition: Expr.h:3412
Defines the SourceManager interface.
static CharSourceRange getTokenRange(SourceRange R)
const Stmt * getElse() const
Definition: Stmt.h:918
bool isArcWeakrefUnavailable() const
Definition: DeclObjC.cpp:337
traverser_iterator traversers_begin()
Definition: Transforms.h:108
[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
Definition: Expr.cpp:2912
bool rewritePropertyAttribute(StringRef fromAttr, StringRef toAttr, SourceLocation atLoc)
Definition: Transforms.cpp:386
void traverse(TranslationUnitDecl *TU)
Definition: Transforms.cpp:516
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...
Definition: Transforms.cpp:137
void makeAssignARCSafe(MigrationPass &pass)
std::vector< ASTTraverser * >::iterator traverser_iterator
Definition: Transforms.h:107
bool isGCMigration() const
Definition: Internals.h:166
decl_iterator decls_end() const
Definition: DeclBase.h:1415
void clearRefsIn(Stmt *S, ExprSet &refs)
Definition: Transforms.cpp:307
Stmt * getBody()
Definition: Stmt.h:1114
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 ...
Definition: ASTContext.h:89
bool isGlobalVar(Expr *E)
Definition: Transforms.cpp:204
Expr * getSubExpr()
Definition: Expr.h:2713
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...
Definition: Transforms.cpp:125
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:48
IdentifierTable & Idents
Definition: ASTContext.h:439
Selector getNullarySelector(IdentifierInfo *ID)
const TargetInfo & getTargetInfo() const
Definition: ASTContext.h:518
SourceLocation getLocWithOffset(int Offset) const
Return a source location with the specified offset from this SourceLocation.
void removeRetainReleaseDeallocFinalize(MigrationPass &pass)
const LangOptions & getLangOpts() const
Definition: ASTContext.h:533
Stmt * getBody()
Definition: Stmt.h:1179
A builtin binary operation expression such as "x + y" or "x <= y".
Definition: Expr.h:2918
Stmt * getInit()
Definition: Stmt.h:1158
Expr * IgnoreParenCasts() LLVM_READONLY
Definition: Expr.cpp:2439
void rewriteUnusedInitDelegate(MigrationPass &pass)
Preprocessor & PP
Definition: Sema.h:294
A class that does preorder depth-first traversal on the entire Clang AST and visits each node...
Represents an ObjC class declaration.
Definition: DeclObjC.h:851
bool isPlusOneAssign(const BinaryOperator *E)
Definition: Transforms.cpp:71
decl_iterator decls_begin() const
Definition: DeclBase.cpp:1141
bool isInvalid() const
StringRef getNilString(MigrationPass &Pass)
Returns "nil" or "0" if 'nil' macro is not actually defined.
Definition: Transforms.cpp:216
QualType getPointeeType() const
Definition: Type.cpp:414
SourceManager & SM
static StringRef getSourceText(CharSourceRange Range, const SourceManager &SM, const LangOptions &LangOpts, bool *Invalid=nullptr)
Returns a string for the source that the range encompasses.
Definition: Lexer.cpp:920
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.
Definition: Lexer.cpp:803
void collectRemovables(Stmt *S, ExprSet &exprs)
Definition: Transforms.cpp:315
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.
Definition: Lexer.cpp:759
void insertAfterToken(SourceLocation loc, StringRef text)
void removeEmptyStatementsAndDeallocFinalize(MigrationPass &pass)
TranslationUnitDecl * getTranslationUnitDecl() const
Definition: ASTContext.h:812
Defines the clang::Preprocessor interface.
Stmt * getBody()
Definition: Stmt.h:1069
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file. ...
Definition: Token.h:124
void checkAPIUses(MigrationPass &pass)
bool isNot(tok::TokenKind K) const
Definition: Token.h:96
An expression that sends a message to the given Objective-C object or class.
Definition: ExprObjC.h:858
bool addPropertyAttribute(StringRef attr, SourceLocation atLoc)
Definition: Transforms.cpp:468
ValueDecl * getDecl()
Definition: Expr.h:994
bool canApplyWeak(ASTContext &Ctx, QualType type, bool AllowOnUnknownClass=false)
Determine whether we can add weak to the given type.
Definition: Transforms.cpp:43
void rewriteUnbridgedCasts(MigrationPass &pass)
SelectorTable & Selectors
Definition: ASTContext.h:440
Encodes a location in the source. The SourceManager can decode this to get at the full include stack...
body_range body()
Definition: Stmt.h:585
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()
Definition: Transforms.h:109
SourceLocation getBegin() const
bool is(tok::TokenKind K) const
Definition: Token.h:95
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition: DeclObjC.h:293
void collectRefs(ValueDecl *D, Stmt *S, ExprSet &refs)
Definition: Transforms.cpp:311
void addTraverser(ASTTraverser *traverser)
Definition: Transforms.h:111
Expr * getInstanceReceiver()
Returns the object expression (receiver) for an instance message, or null for a message that is not a...
Definition: ExprObjC.h:1152
bool isMacroDefined(StringRef Id)
Definition: Preprocessor.h:781
static void traverseAST(MigrationPass &pass)
Definition: Transforms.cpp:564
bool isRefType(QualType RetTy, StringRef Prefix, StringRef Name=StringRef())
void rewriteAutoreleasePool(MigrationPass &pass)
bool hasSideEffects(Expr *E, ASTContext &Ctx)
Definition: Transforms.cpp:175
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
Definition: ASTMatchers.h:1639
std::vector< TransformFn > getAllTransformations(LangOptions::GCMode OrigGCMode, bool NoFinalizeRemoval)
Definition: Transforms.cpp:589
static void GCRewriteFinalize(MigrationPass &pass)
Definition: Transforms.cpp:524
bool isPlusOne(const Expr *E)
Definition: Transforms.cpp:78
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
void replaceText(SourceLocation loc, StringRef text, StringRef replacementText)
body_iterator body_begin()
Definition: Stmt.h:586
const Stmt * getThen() const
Definition: Stmt.h:916
const T * getAs() const
Definition: Type.h:5555
void removeZeroOutPropsInDeallocFinalize(MigrationPass &pass)
SourceManager & getSourceManager()
Definition: ASTContext.h:494
TransformActions & TA
Definition: Internals.h:151
void remove(SourceRange range)
Opcode getOpcode() const
Definition: Expr.h:2961
bool isArrayType() const
Definition: Type.h:5271
void insert(SourceLocation loc, StringRef text)
Defines the clang::TargetInfo interface.
Expr * getRHS() const
Definition: Expr.h:2966
TranslationUnitDecl - The top declaration context.
Definition: Decl.h:78
A reference to a declared variable, function, enum, etc. [C99 6.5.1p2].
Definition: Expr.h:899
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.
Definition: Type.h:633
ReceiverKind getReceiverKind() const
Determine the kind of receiver that this message is being sent to.
Definition: ExprObjC.h:1133
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.
Definition: Token.h:169