clang  9.0.0svn
TransUnbridgedCasts.cpp
Go to the documentation of this file.
1 //===--- TransUnbridgedCasts.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 // rewriteUnbridgedCasts:
10 //
11 // A cast of non-objc pointer to an objc one is checked. If the non-objc pointer
12 // is from a file-level variable, __bridge cast is used to convert it.
13 // For the result of a function call that we know is +1/+0,
14 // __bridge/CFBridgingRelease is used.
15 //
16 // NSString *str = (NSString *)kUTTypePlainText;
17 // str = b ? kUTTypeRTF : kUTTypePlainText;
18 // NSString *_uuidString = (NSString *)CFUUIDCreateString(kCFAllocatorDefault,
19 // _uuid);
20 // ---->
21 // NSString *str = (__bridge NSString *)kUTTypePlainText;
22 // str = (__bridge NSString *)(b ? kUTTypeRTF : kUTTypePlainText);
23 // NSString *_uuidString = (NSString *)
24 // CFBridgingRelease(CFUUIDCreateString(kCFAllocatorDefault, _uuid));
25 //
26 // For a C pointer to ObjC, for casting 'self', __bridge is used.
27 //
28 // CFStringRef str = (CFStringRef)self;
29 // ---->
30 // CFStringRef str = (__bridge CFStringRef)self;
31 //
32 // Uses of Block_copy/Block_release macros are rewritten:
33 //
34 // c = Block_copy(b);
35 // Block_release(c);
36 // ---->
37 // c = [b copy];
38 // <removed>
39 //
40 //===----------------------------------------------------------------------===//
41 
42 #include "Transforms.h"
43 #include "Internals.h"
44 #include "clang/AST/ASTContext.h"
45 #include "clang/AST/Attr.h"
46 #include "clang/AST/ParentMap.h"
49 #include "clang/Lex/Lexer.h"
51 #include "llvm/ADT/SmallString.h"
52 
53 using namespace clang;
54 using namespace arcmt;
55 using namespace trans;
56 
57 namespace {
58 
59 class UnbridgedCastRewriter : public RecursiveASTVisitor<UnbridgedCastRewriter>{
60  MigrationPass &Pass;
61  IdentifierInfo *SelfII;
62  std::unique_ptr<ParentMap> StmtMap;
63  Decl *ParentD;
64  Stmt *Body;
65  mutable std::unique_ptr<ExprSet> Removables;
66 
67 public:
68  UnbridgedCastRewriter(MigrationPass &pass)
69  : Pass(pass), ParentD(nullptr), Body(nullptr) {
70  SelfII = &Pass.Ctx.Idents.get("self");
71  }
72 
73  void transformBody(Stmt *body, Decl *ParentD) {
74  this->ParentD = ParentD;
75  Body = body;
76  StmtMap.reset(new ParentMap(body));
77  TraverseStmt(body);
78  }
79 
80  bool TraverseBlockDecl(BlockDecl *D) {
81  // ParentMap does not enter into a BlockDecl to record its stmts, so use a
82  // new UnbridgedCastRewriter to handle the block.
83  UnbridgedCastRewriter(Pass).transformBody(D->getBody(), D);
84  return true;
85  }
86 
87  bool VisitCastExpr(CastExpr *E) {
88  if (E->getCastKind() != CK_CPointerToObjCPointerCast &&
89  E->getCastKind() != CK_BitCast &&
90  E->getCastKind() != CK_AnyPointerToBlockPointerCast)
91  return true;
92 
93  QualType castType = E->getType();
94  Expr *castExpr = E->getSubExpr();
95  QualType castExprType = castExpr->getType();
96 
97  if (castType->isObjCRetainableType() == castExprType->isObjCRetainableType())
98  return true;
99 
100  bool exprRetainable = castExprType->isObjCIndirectLifetimeType();
101  bool castRetainable = castType->isObjCIndirectLifetimeType();
102  if (exprRetainable == castRetainable) return true;
103 
104  if (castExpr->isNullPointerConstant(Pass.Ctx,
106  return true;
107 
108  SourceLocation loc = castExpr->getExprLoc();
109  if (loc.isValid() && Pass.Ctx.getSourceManager().isInSystemHeader(loc))
110  return true;
111 
112  if (castType->isObjCRetainableType())
113  transformNonObjCToObjCCast(E);
114  else
115  transformObjCToNonObjCCast(E);
116 
117  return true;
118  }
119 
120 private:
121  void transformNonObjCToObjCCast(CastExpr *E) {
122  if (!E) return;
123 
124  // Global vars are assumed that are cast as unretained.
125  if (isGlobalVar(E))
126  if (E->getSubExpr()->getType()->isPointerType()) {
127  castToObjCObject(E, /*retained=*/false);
128  return;
129  }
130 
131  // If the cast is directly over the result of a Core Foundation function
132  // try to figure out whether it should be cast as retained or unretained.
133  Expr *inner = E->IgnoreParenCasts();
134  if (CallExpr *callE = dyn_cast<CallExpr>(inner)) {
135  if (FunctionDecl *FD = callE->getDirectCallee()) {
136  if (FD->hasAttr<CFReturnsRetainedAttr>()) {
137  castToObjCObject(E, /*retained=*/true);
138  return;
139  }
140  if (FD->hasAttr<CFReturnsNotRetainedAttr>()) {
141  castToObjCObject(E, /*retained=*/false);
142  return;
143  }
144  if (FD->isGlobal() &&
145  FD->getIdentifier() &&
147  FD->getIdentifier()->getName())) {
148  StringRef fname = FD->getIdentifier()->getName();
149  if (fname.endswith("Retain") ||
150  fname.find("Create") != StringRef::npos ||
151  fname.find("Copy") != StringRef::npos) {
152  // Do not migrate to couple of bridge transfer casts which
153  // cancel each other out. Leave it unchanged so error gets user
154  // attention instead.
155  if (FD->getName() == "CFRetain" &&
156  FD->getNumParams() == 1 &&
157  FD->getParent()->isTranslationUnit() &&
158  FD->isExternallyVisible()) {
159  Expr *Arg = callE->getArg(0);
160  if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Arg)) {
161  const Expr *sub = ICE->getSubExpr();
162  QualType T = sub->getType();
163  if (T->isObjCObjectPointerType())
164  return;
165  }
166  }
167  castToObjCObject(E, /*retained=*/true);
168  return;
169  }
170 
171  if (fname.find("Get") != StringRef::npos) {
172  castToObjCObject(E, /*retained=*/false);
173  return;
174  }
175  }
176  }
177  }
178 
179  // If returning an ivar or a member of an ivar from a +0 method, use
180  // a __bridge cast.
181  Expr *base = inner->IgnoreParenImpCasts();
182  while (isa<MemberExpr>(base))
183  base = cast<MemberExpr>(base)->getBase()->IgnoreParenImpCasts();
184  if (isa<ObjCIvarRefExpr>(base) &&
185  isa<ReturnStmt>(StmtMap->getParentIgnoreParenCasts(E))) {
186  if (ObjCMethodDecl *method = dyn_cast_or_null<ObjCMethodDecl>(ParentD)) {
187  if (!method->hasAttr<NSReturnsRetainedAttr>()) {
188  castToObjCObject(E, /*retained=*/false);
189  return;
190  }
191  }
192  }
193  }
194 
195  void castToObjCObject(CastExpr *E, bool retained) {
196  rewriteToBridgedCast(E, retained ? OBC_BridgeTransfer : OBC_Bridge);
197  }
198 
199  void rewriteToBridgedCast(CastExpr *E, ObjCBridgeCastKind Kind) {
200  Transaction Trans(Pass.TA);
201  rewriteToBridgedCast(E, Kind, Trans);
202  }
203 
204  void rewriteToBridgedCast(CastExpr *E, ObjCBridgeCastKind Kind,
205  Transaction &Trans) {
206  TransformActions &TA = Pass.TA;
207 
208  // We will remove the compiler diagnostic.
209  if (!TA.hasDiagnostic(diag::err_arc_mismatched_cast,
210  diag::err_arc_cast_requires_bridge,
211  E->getBeginLoc())) {
212  Trans.abort();
213  return;
214  }
215 
216  StringRef bridge;
217  switch(Kind) {
218  case OBC_Bridge:
219  bridge = "__bridge "; break;
220  case OBC_BridgeTransfer:
221  bridge = "__bridge_transfer "; break;
222  case OBC_BridgeRetained:
223  bridge = "__bridge_retained "; break;
224  }
225 
226  TA.clearDiagnostic(diag::err_arc_mismatched_cast,
227  diag::err_arc_cast_requires_bridge, E->getBeginLoc());
228  if (Kind == OBC_Bridge || !Pass.CFBridgingFunctionsDefined()) {
229  if (CStyleCastExpr *CCE = dyn_cast<CStyleCastExpr>(E)) {
230  TA.insertAfterToken(CCE->getLParenLoc(), bridge);
231  } else {
232  SourceLocation insertLoc = E->getSubExpr()->getBeginLoc();
233  SmallString<128> newCast;
234  newCast += '(';
235  newCast += bridge;
236  newCast += E->getType().getAsString(Pass.Ctx.getPrintingPolicy());
237  newCast += ')';
238 
239  if (isa<ParenExpr>(E->getSubExpr())) {
240  TA.insert(insertLoc, newCast.str());
241  } else {
242  newCast += '(';
243  TA.insert(insertLoc, newCast.str());
244  TA.insertAfterToken(E->getEndLoc(), ")");
245  }
246  }
247  } else {
248  assert(Kind == OBC_BridgeTransfer || Kind == OBC_BridgeRetained);
249  SmallString<32> BridgeCall;
250 
251  Expr *WrapE = E->getSubExpr();
252  SourceLocation InsertLoc = WrapE->getBeginLoc();
253 
255  char PrevChar = *SM.getCharacterData(InsertLoc.getLocWithOffset(-1));
256  if (Lexer::isIdentifierBodyChar(PrevChar, Pass.Ctx.getLangOpts()))
257  BridgeCall += ' ';
258 
259  if (Kind == OBC_BridgeTransfer)
260  BridgeCall += "CFBridgingRelease";
261  else
262  BridgeCall += "CFBridgingRetain";
263 
264  if (isa<ParenExpr>(WrapE)) {
265  TA.insert(InsertLoc, BridgeCall);
266  } else {
267  BridgeCall += '(';
268  TA.insert(InsertLoc, BridgeCall);
269  TA.insertAfterToken(WrapE->getEndLoc(), ")");
270  }
271  }
272  }
273 
274  void rewriteCastForCFRetain(CastExpr *castE, CallExpr *callE) {
275  Transaction Trans(Pass.TA);
276  Pass.TA.replace(callE->getSourceRange(), callE->getArg(0)->getSourceRange());
277  rewriteToBridgedCast(castE, OBC_BridgeRetained, Trans);
278  }
279 
280  void getBlockMacroRanges(CastExpr *E, SourceRange &Outer, SourceRange &Inner) {
281  SourceManager &SM = Pass.Ctx.getSourceManager();
282  SourceLocation Loc = E->getExprLoc();
283  assert(Loc.isMacroID());
284  CharSourceRange MacroRange = SM.getImmediateExpansionRange(Loc);
286  SourceLocation InnerBegin = SM.getImmediateMacroCallerLoc(SubRange.getBegin());
287  SourceLocation InnerEnd = SM.getImmediateMacroCallerLoc(SubRange.getEnd());
288 
289  Outer = MacroRange.getAsRange();
290  Inner = SourceRange(InnerBegin, InnerEnd);
291  }
292 
293  void rewriteBlockCopyMacro(CastExpr *E) {
294  SourceRange OuterRange, InnerRange;
295  getBlockMacroRanges(E, OuterRange, InnerRange);
296 
297  Transaction Trans(Pass.TA);
298  Pass.TA.replace(OuterRange, InnerRange);
299  Pass.TA.insert(InnerRange.getBegin(), "[");
300  Pass.TA.insertAfterToken(InnerRange.getEnd(), " copy]");
301  Pass.TA.clearDiagnostic(diag::err_arc_mismatched_cast,
302  diag::err_arc_cast_requires_bridge,
303  OuterRange);
304  }
305 
306  void removeBlockReleaseMacro(CastExpr *E) {
307  SourceRange OuterRange, InnerRange;
308  getBlockMacroRanges(E, OuterRange, InnerRange);
309 
310  Transaction Trans(Pass.TA);
311  Pass.TA.clearDiagnostic(diag::err_arc_mismatched_cast,
312  diag::err_arc_cast_requires_bridge,
313  OuterRange);
314  if (!hasSideEffects(E, Pass.Ctx)) {
315  if (tryRemoving(cast<Expr>(StmtMap->getParentIgnoreParenCasts(E))))
316  return;
317  }
318  Pass.TA.replace(OuterRange, InnerRange);
319  }
320 
321  bool tryRemoving(Expr *E) const {
322  if (!Removables) {
323  Removables.reset(new ExprSet);
324  collectRemovables(Body, *Removables);
325  }
326 
327  if (Removables->count(E)) {
328  Pass.TA.removeStmt(E);
329  return true;
330  }
331 
332  return false;
333  }
334 
335  void transformObjCToNonObjCCast(CastExpr *E) {
336  SourceLocation CastLoc = E->getExprLoc();
337  if (CastLoc.isMacroID()) {
338  StringRef MacroName = Lexer::getImmediateMacroName(CastLoc,
339  Pass.Ctx.getSourceManager(),
340  Pass.Ctx.getLangOpts());
341  if (MacroName == "Block_copy") {
342  rewriteBlockCopyMacro(E);
343  return;
344  }
345  if (MacroName == "Block_release") {
346  removeBlockReleaseMacro(E);
347  return;
348  }
349  }
350 
351  if (isSelf(E->getSubExpr()))
352  return rewriteToBridgedCast(E, OBC_Bridge);
353 
354  CallExpr *callE;
355  if (isPassedToCFRetain(E, callE))
356  return rewriteCastForCFRetain(E, callE);
357 
358  ObjCMethodFamily family = getFamilyOfMessage(E->getSubExpr());
359  if (family == OMF_retain)
360  return rewriteToBridgedCast(E, OBC_BridgeRetained);
361 
362  if (family == OMF_autorelease || family == OMF_release) {
363  std::string err = "it is not safe to cast to '";
364  err += E->getType().getAsString(Pass.Ctx.getPrintingPolicy());
365  err += "' the result of '";
366  err += family == OMF_autorelease ? "autorelease" : "release";
367  err += "' message; a __bridge cast may result in a pointer to a "
368  "destroyed object and a __bridge_retained may leak the object";
369  Pass.TA.reportError(err, E->getBeginLoc(),
370  E->getSubExpr()->getSourceRange());
371  Stmt *parent = E;
372  do {
373  parent = StmtMap->getParentIgnoreParenImpCasts(parent);
374  } while (parent && isa<FullExpr>(parent));
375 
376  if (ReturnStmt *retS = dyn_cast_or_null<ReturnStmt>(parent)) {
377  std::string note = "remove the cast and change return type of function "
378  "to '";
379  note += E->getSubExpr()->getType().getAsString(Pass.Ctx.getPrintingPolicy());
380  note += "' to have the object automatically autoreleased";
381  Pass.TA.reportNote(note, retS->getBeginLoc());
382  }
383  }
384 
385  Expr *subExpr = E->getSubExpr();
386 
387  // Look through pseudo-object expressions.
388  if (PseudoObjectExpr *pseudo = dyn_cast<PseudoObjectExpr>(subExpr)) {
389  subExpr = pseudo->getResultExpr();
390  assert(subExpr && "no result for pseudo-object of non-void type?");
391  }
392 
393  if (ImplicitCastExpr *implCE = dyn_cast<ImplicitCastExpr>(subExpr)) {
394  if (implCE->getCastKind() == CK_ARCConsumeObject)
395  return rewriteToBridgedCast(E, OBC_BridgeRetained);
396  if (implCE->getCastKind() == CK_ARCReclaimReturnedObject)
397  return rewriteToBridgedCast(E, OBC_Bridge);
398  }
399 
400  bool isConsumed = false;
401  if (isPassedToCParamWithKnownOwnership(E, isConsumed))
402  return rewriteToBridgedCast(E, isConsumed ? OBC_BridgeRetained
403  : OBC_Bridge);
404  }
405 
406  static ObjCMethodFamily getFamilyOfMessage(Expr *E) {
407  E = E->IgnoreParenCasts();
408  if (ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(E))
409  return ME->getMethodFamily();
410 
411  return OMF_None;
412  }
413 
414  bool isPassedToCFRetain(Expr *E, CallExpr *&callE) const {
415  if ((callE = dyn_cast_or_null<CallExpr>(
416  StmtMap->getParentIgnoreParenImpCasts(E))))
417  if (FunctionDecl *
418  FD = dyn_cast_or_null<FunctionDecl>(callE->getCalleeDecl()))
419  if (FD->getName() == "CFRetain" && FD->getNumParams() == 1 &&
420  FD->getParent()->isTranslationUnit() &&
421  FD->isExternallyVisible())
422  return true;
423 
424  return false;
425  }
426 
427  bool isPassedToCParamWithKnownOwnership(Expr *E, bool &isConsumed) const {
428  if (CallExpr *callE = dyn_cast_or_null<CallExpr>(
429  StmtMap->getParentIgnoreParenImpCasts(E)))
430  if (FunctionDecl *
431  FD = dyn_cast_or_null<FunctionDecl>(callE->getCalleeDecl())) {
432  unsigned i = 0;
433  for (unsigned e = callE->getNumArgs(); i != e; ++i) {
434  Expr *arg = callE->getArg(i);
435  if (arg == E || arg->IgnoreParenImpCasts() == E)
436  break;
437  }
438  if (i < callE->getNumArgs() && i < FD->getNumParams()) {
439  ParmVarDecl *PD = FD->getParamDecl(i);
440  if (PD->hasAttr<CFConsumedAttr>()) {
441  isConsumed = true;
442  return true;
443  }
444  }
445  }
446 
447  return false;
448  }
449 
450  bool isSelf(Expr *E) const {
451  E = E->IgnoreParenLValueCasts();
452  if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
453  if (ImplicitParamDecl *IPD = dyn_cast<ImplicitParamDecl>(DRE->getDecl()))
454  if (IPD->getIdentifier() == SelfII)
455  return true;
456 
457  return false;
458  }
459 };
460 
461 } // end anonymous namespace
462 
466 }
Defines the clang::ASTContext interface.
Represents a function declaration or definition.
Definition: Decl.h:1748
void reportNote(StringRef note, SourceLocation loc, SourceRange range=SourceRange())
SourceLocation getLocWithOffset(int Offset) const
Return a source location with the specified offset from this SourceLocation.
A (possibly-)qualified type.
Definition: Type.h:643
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
Definition: Expr.h:2673
ObjCBridgeCastKind
The kind of bridging performed by the Objective-C bridge cast.
Stmt - This represents one statement.
Definition: Stmt.h:66
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this call.
Definition: Expr.h:2660
Bridging via __bridge, which does nothing but reinterpret the bits.
Defines the SourceManager interface.
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:88
const char * getCharacterData(SourceLocation SL, bool *Invalid=nullptr) const
Return a pointer to the start of the specified location in the appropriate spelling MemoryBuffer...
SourceLocation getImmediateMacroCallerLoc(SourceLocation Loc) const
Gets the location of the immediate macro caller, one level up the stack toward the initial macro type...
ObjCMethodDecl - Represents an instance or class method declaration.
Definition: DeclObjC.h:138
Represents a parameter to a function.
Definition: Decl.h:1564
long i
Definition: xmmintrin.h:1456
bool TraverseDecl(Decl *D)
Recursively visit a declaration, by dispatching to Traverse*Decl() based on the argument&#39;s dynamic ty...
One of these records is kept for each identifier that is lexed.
ObjCMethodFamily
A family of Objective-C methods.
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: Stmt.cpp:263
bool isGlobalVar(Expr *E)
Definition: Transforms.cpp:196
void reportError(StringRef error, SourceLocation loc, SourceRange range=SourceRange())
Stmt * getBody() const override
getBody - If this Decl represents a declaration for a body of code, such as a function or method defi...
Definition: Decl.h:3994
Expr * getSubExpr()
Definition: Expr.h:3173
IdentifierTable & Idents
Definition: ASTContext.h:569
const clang::PrintingPolicy & getPrintingPolicy() const
Definition: ASTContext.h:657
Expr * IgnoreParenCasts() LLVM_READONLY
Skip past any parentheses and casts which might surround this expression until reaching a fixed point...
Definition: Expr.cpp:2947
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
Definition: Expr.h:3121
const internal::VariadicDynCastAllOfMatcher< Stmt, CastExpr > castExpr
Matches any cast nodes of Clang&#39;s AST.
A class that does preorder or postorder depth-first traversal on the entire Clang AST and visits each...
Bridging via __bridge_transfer, which transfers ownership of an Objective-C pointer into ARC...
bool hasAttr() const
Definition: DeclBase.h:542
bool clearDiagnostic(ArrayRef< unsigned > IDs, SourceRange range)
void collectRemovables(Stmt *S, ExprSet &exprs)
Definition: Transforms.cpp:308
Represents a block literal declaration, which is like an unnamed FunctionDecl.
Definition: Decl.h:3915
This represents one expression.
Definition: Expr.h:108
Represents a character-granular source range.
bool isInSystemHeader(SourceLocation Loc) const
Returns if a SourceLocation is in a system header.
void insertAfterToken(SourceLocation loc, StringRef text)
bool isObjCRetainableType() const
Definition: Type.cpp:3984
Specifies that a value-dependent expression of integral or dependent type should be considered a null...
Definition: Expr.h:733
QualType getType() const
Definition: Expr.h:137
CharSourceRange getImmediateExpansionRange(SourceLocation Loc) const
Return the start/end of the expansion information for an expansion location.
ReturnStmt - This represents a return, optionally of an expression: return; return 4;...
Definition: Stmt.h:2610
An expression that sends a message to the given Objective-C object or class.
Definition: ExprObjC.h:950
SourceLocation getEnd() const
CStyleCastExpr - An explicit cast in C (C99 6.5.4) or a C-style cast in C++ (C++ [expr.cast]), which uses the syntax (Type)expr.
Definition: Expr.h:3342
const SourceManager & SM
Definition: Format.cpp:1572
SourceLocation getEndLoc() const LLVM_READONLY
Definition: Stmt.cpp:276
void rewriteUnbridgedCasts(MigrationPass &pass)
Kind
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
Definition: Expr.h:5663
NullPointerConstantKind isNullPointerConstant(ASTContext &Ctx, NullPointerConstantValueDependence NPC) const
isNullPointerConstant - C99 6.3.2.3p3 - Test if this reduces down to a Null pointer constant...
Definition: Expr.cpp:3658
Encodes a location in the source.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
CastKind getCastKind() const
Definition: Expr.h:3167
bool isObjCObjectPointerType() const
Definition: Type.h:6488
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
Definition: Expr.h:3245
static StringRef getImmediateMacroName(SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts)
Retrieve the name of the immediate macro expansion.
Definition: Lexer.cpp:966
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
Definition: Expr.cpp:215
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.
bool hasSideEffects(Expr *E, ASTContext &Ctx)
Definition: Transforms.cpp:167
static std::string getAsString(SplitQualType split, const PrintingPolicy &Policy)
Definition: Type.h:976
bool isObjCIndirectLifetimeType() const
Definition: Type.cpp:3990
Bridging via __bridge_retain, which makes an ARC object available as a +1 C pointer.
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
Definition: Expr.cpp:2942
bool isMacroID() const
Expr * IgnoreParenLValueCasts() LLVM_READONLY
Skip past any parentheses and lvalue casts which might surround this expression until reaching a fixe...
Definition: Expr.cpp:2959
SourceManager & getSourceManager()
Definition: ASTContext.h:665
static bool isIdentifierBodyChar(char c, const LangOptions &LangOpts)
Returns true if the given character could appear in an identifier.
Definition: Lexer.cpp:1038
No particular method family.
TranslationUnitDecl * getTranslationUnitDecl() const
Definition: ASTContext.h:1007
void replace(SourceRange range, StringRef text)
TransformActions & TA
Definition: Internals.h:150
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Definition: Stmt.cpp:251
void insert(SourceLocation loc, StringRef text)
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition: Expr.h:2516
A reference to a declared variable, function, enum, etc.
Definition: Expr.h:1141
bool isPointerType() const
Definition: Type.h:6384
A trivial tuple used to represent a source range.
Decl * getCalleeDecl()
Definition: Expr.h:2646
bool hasDiagnostic(unsigned ID, SourceRange range)
Definition: Internals.h:87
SourceLocation getBegin() const
const LangOptions & getLangOpts() const
Definition: ASTContext.h:710
This class handles loading and caching of source files into memory.