clang  7.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->getLocStart())) {
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,
229  E->getLocStart());
230  if (Kind == OBC_Bridge || !Pass.CFBridgingFunctionsDefined()) {
231  if (CStyleCastExpr *CCE = dyn_cast<CStyleCastExpr>(E)) {
232  TA.insertAfterToken(CCE->getLParenLoc(), bridge);
233  } else {
234  SourceLocation insertLoc = E->getSubExpr()->getLocStart();
235  SmallString<128> newCast;
236  newCast += '(';
237  newCast += bridge;
238  newCast += E->getType().getAsString(Pass.Ctx.getPrintingPolicy());
239  newCast += ')';
240 
241  if (isa<ParenExpr>(E->getSubExpr())) {
242  TA.insert(insertLoc, newCast.str());
243  } else {
244  newCast += '(';
245  TA.insert(insertLoc, newCast.str());
246  TA.insertAfterToken(E->getLocEnd(), ")");
247  }
248  }
249  } else {
250  assert(Kind == OBC_BridgeTransfer || Kind == OBC_BridgeRetained);
251  SmallString<32> BridgeCall;
252 
253  Expr *WrapE = E->getSubExpr();
254  SourceLocation InsertLoc = WrapE->getLocStart();
255 
257  char PrevChar = *SM.getCharacterData(InsertLoc.getLocWithOffset(-1));
258  if (Lexer::isIdentifierBodyChar(PrevChar, Pass.Ctx.getLangOpts()))
259  BridgeCall += ' ';
260 
261  if (Kind == OBC_BridgeTransfer)
262  BridgeCall += "CFBridgingRelease";
263  else
264  BridgeCall += "CFBridgingRetain";
265 
266  if (isa<ParenExpr>(WrapE)) {
267  TA.insert(InsertLoc, BridgeCall);
268  } else {
269  BridgeCall += '(';
270  TA.insert(InsertLoc, BridgeCall);
271  TA.insertAfterToken(WrapE->getLocEnd(), ")");
272  }
273  }
274  }
275 
276  void rewriteCastForCFRetain(CastExpr *castE, CallExpr *callE) {
277  Transaction Trans(Pass.TA);
278  Pass.TA.replace(callE->getSourceRange(), callE->getArg(0)->getSourceRange());
279  rewriteToBridgedCast(castE, OBC_BridgeRetained, Trans);
280  }
281 
282  void getBlockMacroRanges(CastExpr *E, SourceRange &Outer, SourceRange &Inner) {
283  SourceManager &SM = Pass.Ctx.getSourceManager();
284  SourceLocation Loc = E->getExprLoc();
285  assert(Loc.isMacroID());
286  CharSourceRange MacroRange = SM.getImmediateExpansionRange(Loc);
288  SourceLocation InnerBegin = SM.getImmediateMacroCallerLoc(SubRange.getBegin());
289  SourceLocation InnerEnd = SM.getImmediateMacroCallerLoc(SubRange.getEnd());
290 
291  Outer = MacroRange.getAsRange();
292  Inner = SourceRange(InnerBegin, InnerEnd);
293  }
294 
295  void rewriteBlockCopyMacro(CastExpr *E) {
296  SourceRange OuterRange, InnerRange;
297  getBlockMacroRanges(E, OuterRange, InnerRange);
298 
299  Transaction Trans(Pass.TA);
300  Pass.TA.replace(OuterRange, InnerRange);
301  Pass.TA.insert(InnerRange.getBegin(), "[");
302  Pass.TA.insertAfterToken(InnerRange.getEnd(), " copy]");
303  Pass.TA.clearDiagnostic(diag::err_arc_mismatched_cast,
304  diag::err_arc_cast_requires_bridge,
305  OuterRange);
306  }
307 
308  void removeBlockReleaseMacro(CastExpr *E) {
309  SourceRange OuterRange, InnerRange;
310  getBlockMacroRanges(E, OuterRange, InnerRange);
311 
312  Transaction Trans(Pass.TA);
313  Pass.TA.clearDiagnostic(diag::err_arc_mismatched_cast,
314  diag::err_arc_cast_requires_bridge,
315  OuterRange);
316  if (!hasSideEffects(E, Pass.Ctx)) {
317  if (tryRemoving(cast<Expr>(StmtMap->getParentIgnoreParenCasts(E))))
318  return;
319  }
320  Pass.TA.replace(OuterRange, InnerRange);
321  }
322 
323  bool tryRemoving(Expr *E) const {
324  if (!Removables) {
325  Removables.reset(new ExprSet);
326  collectRemovables(Body, *Removables);
327  }
328 
329  if (Removables->count(E)) {
330  Pass.TA.removeStmt(E);
331  return true;
332  }
333 
334  return false;
335  }
336 
337  void transformObjCToNonObjCCast(CastExpr *E) {
338  SourceLocation CastLoc = E->getExprLoc();
339  if (CastLoc.isMacroID()) {
340  StringRef MacroName = Lexer::getImmediateMacroName(CastLoc,
341  Pass.Ctx.getSourceManager(),
342  Pass.Ctx.getLangOpts());
343  if (MacroName == "Block_copy") {
344  rewriteBlockCopyMacro(E);
345  return;
346  }
347  if (MacroName == "Block_release") {
348  removeBlockReleaseMacro(E);
349  return;
350  }
351  }
352 
353  if (isSelf(E->getSubExpr()))
354  return rewriteToBridgedCast(E, OBC_Bridge);
355 
356  CallExpr *callE;
357  if (isPassedToCFRetain(E, callE))
358  return rewriteCastForCFRetain(E, callE);
359 
360  ObjCMethodFamily family = getFamilyOfMessage(E->getSubExpr());
361  if (family == OMF_retain)
362  return rewriteToBridgedCast(E, OBC_BridgeRetained);
363 
364  if (family == OMF_autorelease || family == OMF_release) {
365  std::string err = "it is not safe to cast to '";
366  err += E->getType().getAsString(Pass.Ctx.getPrintingPolicy());
367  err += "' the result of '";
368  err += family == OMF_autorelease ? "autorelease" : "release";
369  err += "' message; a __bridge cast may result in a pointer to a "
370  "destroyed object and a __bridge_retained may leak the object";
371  Pass.TA.reportError(err, E->getLocStart(),
372  E->getSubExpr()->getSourceRange());
373  Stmt *parent = E;
374  do {
375  parent = StmtMap->getParentIgnoreParenImpCasts(parent);
376  } while (parent && isa<ExprWithCleanups>(parent));
377 
378  if (ReturnStmt *retS = dyn_cast_or_null<ReturnStmt>(parent)) {
379  std::string note = "remove the cast and change return type of function "
380  "to '";
381  note += E->getSubExpr()->getType().getAsString(Pass.Ctx.getPrintingPolicy());
382  note += "' to have the object automatically autoreleased";
383  Pass.TA.reportNote(note, retS->getLocStart());
384  }
385  }
386 
387  Expr *subExpr = E->getSubExpr();
388 
389  // Look through pseudo-object expressions.
390  if (PseudoObjectExpr *pseudo = dyn_cast<PseudoObjectExpr>(subExpr)) {
391  subExpr = pseudo->getResultExpr();
392  assert(subExpr && "no result for pseudo-object of non-void type?");
393  }
394 
395  if (ImplicitCastExpr *implCE = dyn_cast<ImplicitCastExpr>(subExpr)) {
396  if (implCE->getCastKind() == CK_ARCConsumeObject)
397  return rewriteToBridgedCast(E, OBC_BridgeRetained);
398  if (implCE->getCastKind() == CK_ARCReclaimReturnedObject)
399  return rewriteToBridgedCast(E, OBC_Bridge);
400  }
401 
402  bool isConsumed = false;
403  if (isPassedToCParamWithKnownOwnership(E, isConsumed))
404  return rewriteToBridgedCast(E, isConsumed ? OBC_BridgeRetained
405  : OBC_Bridge);
406  }
407 
408  static ObjCMethodFamily getFamilyOfMessage(Expr *E) {
409  E = E->IgnoreParenCasts();
410  if (ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(E))
411  return ME->getMethodFamily();
412 
413  return OMF_None;
414  }
415 
416  bool isPassedToCFRetain(Expr *E, CallExpr *&callE) const {
417  if ((callE = dyn_cast_or_null<CallExpr>(
418  StmtMap->getParentIgnoreParenImpCasts(E))))
419  if (FunctionDecl *
420  FD = dyn_cast_or_null<FunctionDecl>(callE->getCalleeDecl()))
421  if (FD->getName() == "CFRetain" && FD->getNumParams() == 1 &&
422  FD->getParent()->isTranslationUnit() &&
423  FD->isExternallyVisible())
424  return true;
425 
426  return false;
427  }
428 
429  bool isPassedToCParamWithKnownOwnership(Expr *E, bool &isConsumed) const {
430  if (CallExpr *callE = dyn_cast_or_null<CallExpr>(
431  StmtMap->getParentIgnoreParenImpCasts(E)))
432  if (FunctionDecl *
433  FD = dyn_cast_or_null<FunctionDecl>(callE->getCalleeDecl())) {
434  unsigned i = 0;
435  for (unsigned e = callE->getNumArgs(); i != e; ++i) {
436  Expr *arg = callE->getArg(i);
437  if (arg == E || arg->IgnoreParenImpCasts() == E)
438  break;
439  }
440  if (i < callE->getNumArgs() && i < FD->getNumParams()) {
441  ParmVarDecl *PD = FD->getParamDecl(i);
442  if (PD->hasAttr<CFConsumedAttr>()) {
443  isConsumed = true;
444  return true;
445  }
446  }
447  }
448 
449  return false;
450  }
451 
452  bool isSelf(Expr *E) const {
453  E = E->IgnoreParenLValueCasts();
454  if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
455  if (ImplicitParamDecl *IPD = dyn_cast<ImplicitParamDecl>(DRE->getDecl()))
456  if (IPD->getIdentifier() == SelfII)
457  return true;
458 
459  return false;
460  }
461 };
462 
463 } // end anonymous namespace
464 
468 }
Defines the clang::ASTContext interface.
Represents a function declaration or definition.
Definition: Decl.h:1714
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:654
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
Definition: Expr.h:2311
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:2299
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:86
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:1533
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.
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:3920
Expr * getSubExpr()
Definition: Expr.h:2800
IdentifierTable & Idents
Definition: ASTContext.h:538
const clang::PrintingPolicy & getPrintingPolicy() const
Definition: ASTContext.h:636
Expr * IgnoreParenCasts() LLVM_READONLY
IgnoreParenCasts - Ignore parentheses and casts.
Definition: Expr.cpp:2470
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
Definition: Expr.h:2747
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:536
bool clearDiagnostic(ArrayRef< unsigned > IDs, SourceRange range)
SourceLocation getLocEnd() const LLVM_READONLY
Definition: Stmt.cpp:291
void collectRemovables(Stmt *S, ExprSet &exprs)
Definition: Transforms.cpp:308
Pepresents a block literal declaration, which is like an unnamed FunctionDecl.
Definition: Decl.h:3838
Expr - This represents one expression.
Definition: Expr.h:106
Represents a character-granular source range.
bool isInSystemHeader(SourceLocation Loc) const
Returns if a SourceLocation is in a system header.
const FunctionProtoType * T
void insertAfterToken(SourceLocation loc, StringRef text)
bool isObjCRetainableType() const
Definition: Type.cpp:3894
Specifies that a value-dependent expression of integral or dependent type should be considered a null...
Definition: Expr.h:709
QualType getType() const
Definition: Expr.h:128
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:1433
An expression that sends a message to the given Objective-C object or class.
Definition: ExprObjC.h:903
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:2961
const SourceManager & SM
Definition: Format.cpp:1468
void rewriteUnbridgedCasts(MigrationPass &pass)
Kind
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
Definition: Expr.h:5008
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:3293
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:2794
bool isObjCObjectPointerType() const
Definition: Type.h:6145
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
Definition: Expr.h:2861
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:980
bool isObjCIndirectLifetimeType() const
Definition: Type.cpp:3900
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:2557
Decl * getCalleeDecl()
Definition: Expr.cpp:1221
Expr * IgnoreParenLValueCasts() LLVM_READONLY
Ignore parentheses and lvalue casts.
Definition: Expr.cpp:2517
SourceManager & getSourceManager()
Definition: ASTContext.h:644
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:990
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:266
void insert(SourceLocation loc, StringRef text)
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition: Expr.h:2242
A reference to a declared variable, function, enum, etc.
Definition: Expr.h:972
bool isPointerType() const
Definition: Type.h:6048
A trivial tuple used to represent a source range.
SourceLocation getLocStart() const LLVM_READONLY
Definition: Stmt.cpp:278
bool hasDiagnostic(unsigned ID, SourceRange range)
Definition: Internals.h:88
SourceLocation getBegin() const
const LangOptions & getLangOpts() const
Definition: ASTContext.h:689
This class handles loading and caching of source files into memory.