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