clang: lib/Analysis/BodyFarm.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
25#include "llvm/ADT/StringSwitch.h"
26#include "llvm/Support/Debug.h"
27#include
28
29#define DEBUG_TYPE "body-farm"
30
31using namespace clang;
32
33
34
35
36
38
40 if (!BPT)
41 return false;
42
43
44
48}
49
50namespace {
51class ASTMaker {
52public:
54
55
57
58
61
62
64
65
67 bool RefersToEnclosingVariableOrCapture = false);
68
69
71
72
74
75
77
78
80
81
82
85 bool RefersToEnclosingVariableOrCapture = false);
86
87
89 CastKind CK = CK_LValueToRValue);
90
91
93
94
96
97
99
100
102
103
105
106
108 bool IsArrow = false,
110
111
112
114
115private:
117};
118}
119
123 C, const_cast<Expr *>(LHS), const_cast<Expr *>(RHS), BO_Assign, Ty,
125}
126
132 C, const_cast<Expr *>(LHS), const_cast<Expr *>(RHS), Op,
135}
136
140}
141
144 bool RefersToEnclosingVariableOrCapture) {
145 QualType Type = D->getType().getNonReferenceType();
146
150 return DR;
151}
152
157}
158
160 return makeImplicitCast(Arg, Ty, CK_LValueToRValue);
161}
162
164ASTMaker::makeLvalueToRvalue(const VarDecl *Arg,
165 bool RefersToEnclosingVariableOrCapture) {
167 return makeLvalueToRvalue(makeDeclRefExpr(Arg,
168 RefersToEnclosingVariableOrCapture),
170}
171
175 CK,
176 const_cast<Expr *>(Arg),
177 nullptr,
180}
181
187 const_cast<Expr *>(Arg), nullptr,
190}
191
192Expr *ASTMaker::makeIntegralCast(const Expr *Arg, QualType Ty) {
193 if (Arg->getType() == Ty)
194 return const_cast<Expr*>(Arg);
195 return makeImplicitCast(Arg, Ty, CK_IntegralCast);
196}
197
199 return makeImplicitCast(Arg, C.BoolTy, CK_IntegralToBoolean);
200}
201
203 QualType Ty = C.getBOOLDecl() ? C.getBOOLType() : C.ObjCBuiltinBoolTy;
205}
206
212 true, false);
213}
214
215ReturnStmt *ASTMaker::makeReturn(const Expr *RetVal) {
217 nullptr);
218}
219
221 llvm::APInt APValue = llvm::APInt(C.getTypeSize(Ty), Value);
223}
224
226 bool IsArrow,
228
234 nullptr, MemberDecl->getType(), ValueKind,
236}
237
238ValueDecl *ASTMaker::findMemberField(const RecordDecl *RD, StringRef Name) {
239
241 false,
242 false,
243 false);
245 DeclarationName DeclName = C.DeclarationNames.getIdentifier(&II);
246
248 for (NamedDecl *FoundDecl : Decls)
250 return cast(FoundDecl);
251
252 return nullptr;
253}
254
255
256
257
258
260
264
265 QualType Ty = Callback->getType();
267 Expr *SubExpr;
269 SubExpr = M.makeImplicitCast(
272 Call->getType()->isFunctionType()) {
274 SubExpr = M.makeImplicitCast(Call, Ty, CK_FunctionToPointerDecay);
276 && Call->getType()->isPointerType()
277 && Call->getType()->getPointeeType()->isFunctionType()){
278 SubExpr = Call;
279 } else {
280 llvm_unreachable("Unexpected state");
281 }
282
285}
286
291 assert(CallbackDecl != nullptr);
292 assert(CallbackDecl->isLambda());
294 assert(callOperatorDecl != nullptr);
295
300 const_cast<FunctionDecl *>(callOperatorDecl),
301 false,
303 callOperatorDecl->getType(),
305
307 C, OO_Call, callOperatorDeclRef,
308 CallArgs,
309 C.VoidTy,
313}
314
315
316
317
318
319
321 LLVM_DEBUG(llvm::dbgs() << "Generating body for std::move / std::forward\n");
322
323 ASTMaker M(C);
324
326 Expr *Param = M.makeDeclRefExpr(D->getParamDecl(0));
327 Expr *Cast = M.makeReferenceCast(Param, ReturnType);
328 return M.makeReturn(Cast);
329}
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
347 LLVM_DEBUG(llvm::dbgs() << "Generating body for call_once\n");
348
349
350 if (D->param_size() < 2)
351 return nullptr;
352
353 ASTMaker M(C);
354
355 const ParmVarDecl *Flag = D->getParamDecl(0);
356 const ParmVarDecl *Callback = D->getParamDecl(1);
357
358 if (!Callback->getType()->isReferenceType()) {
359 llvm::dbgs() << "libcxx03 std::call_once implementation, skipping.\n";
360 return nullptr;
361 }
363 llvm::dbgs() << "unknown std::call_once implementation, skipping.\n";
364 return nullptr;
365 }
366
367 QualType CallbackType = Callback->getType().getNonReferenceType();
368
369
373
374 if (!FlagRecordDecl) {
375 LLVM_DEBUG(llvm::dbgs() << "Flag field is not a record: "
376 << "unknown std::call_once implementation, "
377 << "ignoring the call.\n");
378 return nullptr;
379 }
380
381
382
383 ValueDecl *FlagFieldDecl = M.findMemberField(FlagRecordDecl, "__state_");
384
385
386
387 if (!FlagFieldDecl) {
388 FlagFieldDecl = M.findMemberField(FlagRecordDecl, "_M_once");
389 }
390
391 if (!FlagFieldDecl) {
392 LLVM_DEBUG(llvm::dbgs() << "No field _M_once or __state_ found on "
393 << "std::once_flag struct: unknown std::call_once "
394 << "implementation, ignoring the call.");
395 return nullptr;
396 }
397
398 bool isLambdaCall = CallbackRecordDecl && CallbackRecordDecl->isLambda();
399 if (CallbackRecordDecl && !isLambdaCall) {
400 LLVM_DEBUG(llvm::dbgs()
401 << "Not supported: synthesizing body for functors when "
402 << "body farming std::call_once, ignoring the call.");
403 return nullptr;
404 }
405
408 if (isLambdaCall) {
409
410
411 CallArgs.push_back(
412 M.makeDeclRefExpr(Callback,
413 true));
418 CallbackFunctionType =
420 } else {
422 }
423
424 if (!CallbackFunctionType)
425 return nullptr;
426
427
428 if (D->getNumParams() != CallbackFunctionType->getNumParams() + 2) {
429 LLVM_DEBUG(llvm::dbgs() << "Types of params of the callback do not match "
430 << "params passed to std::call_once, "
431 << "ignoring the call\n");
432 return nullptr;
433 }
434
435
436
437
440 assert(PDecl);
445 LLVM_DEBUG(llvm::dbgs() << "Types of params of the callback do not match "
446 << "params passed to std::call_once, "
447 << "ignoring the call\n");
448 return nullptr;
449 }
450 Expr *ParamExpr = M.makeDeclRefExpr(PDecl);
453 ParamExpr = M.makeLvalueToRvalue(ParamExpr, PTy);
454 }
455 CallArgs.push_back(ParamExpr);
456 }
457
459 if (isLambdaCall) {
460
462 CallbackRecordDecl, CallArgs);
463 } else {
464
465
467 }
468
470 M.makeDeclRefExpr(Flag,
471 true);
472
473
474 MemberExpr *Deref = M.makeMemberExpression(FlagDecl, FlagFieldDecl);
475 assert(Deref->isLValue());
476 QualType DerefType = Deref->getType();
477
478
480 C,
481
482 M.makeImplicitCast(M.makeLvalueToRvalue(Deref, DerefType), DerefType,
483 CK_IntegralToBoolean),
484 UO_LNot,
485 C.IntTy,
489
490
492 Deref, M.makeIntegralCast(M.makeIntegerLiteral(1, C.IntTy), DerefType),
493 DerefType);
494
495 auto *Out =
497 nullptr,
498 nullptr,
499 FlagCheck,
502 M.makeCompound({CallbackCall, FlagAssignment}));
503
504 return Out;
505}
506
507
509
510 if (D->param_size() != 2)
511 return nullptr;
512
513
514 const ParmVarDecl *Predicate = D->getParamDecl(0);
517 if (!PredicatePtrTy)
518 return nullptr;
521 return nullptr;
522
523
527 return nullptr;
528
529
530
531
532
533
534
535
536
537
538
539 ASTMaker M(C);
540
541
543 C,
544 M.makeLvalueToRvalue(Block),
545 {},
546 C.VoidTy,
549
550
551 Expr *DoneValue =
555
557 M.makeAssignment(
558 M.makeDereference(
559 M.makeLvalueToRvalue(
560 M.makeDeclRefExpr(Predicate), PredicateQPtrTy),
561 PredicateTy),
562 M.makeIntegralCast(DoneValue, PredicateTy),
563 PredicateTy);
564
565
566 Stmt *Stmts[] = { B, CE };
568
569
571 M.makeLvalueToRvalue(
572 M.makeDereference(
573 M.makeLvalueToRvalue(
574 M.makeDeclRefExpr(Predicate),
575 PredicateQPtrTy),
576 PredicateTy),
577 PredicateTy);
578
579 Expr *GuardCondition = M.makeComparison(LValToRval, DoneValue, BO_NE);
580
582 nullptr,
583 nullptr,
584 GuardCondition,
587 CS);
588 return If;
589}
590
591
593
594 if (D->param_size() != 2)
595 return nullptr;
596
597
601 return nullptr;
602
603
604
605
606
607
608
609
610 ASTMaker M(C);
615 return CE;
616}
617
619{
620
621 if (D->param_size() != 3)
622 return nullptr;
623
624
625
626
627
628
629
630
631
632
633
634
635 QualType ResultTy = D->getReturnType();
638 return nullptr;
639
640 const ParmVarDecl *OldValue = D->getParamDecl(0);
642
643 const ParmVarDecl *NewValue = D->getParamDecl(1);
645
646 assert(OldValueTy == NewValueTy);
647
648 const ParmVarDecl *TheValue = D->getParamDecl(2);
651 if (!PT)
652 return nullptr;
654
655 ASTMaker M(C);
656
657 Expr *Comparison =
658 M.makeComparison(
659 M.makeLvalueToRvalue(M.makeDeclRefExpr(OldValue), OldValueTy),
660 M.makeLvalueToRvalue(
661 M.makeDereference(
662 M.makeLvalueToRvalue(M.makeDeclRefExpr(TheValue), TheValueTy),
663 PointeeTy),
664 PointeeTy),
665 BO_EQ);
666
667
668 Stmt *Stmts[2];
669 Stmts[0] =
670 M.makeAssignment(
671 M.makeDereference(
672 M.makeLvalueToRvalue(M.makeDeclRefExpr(TheValue), TheValueTy),
673 PointeeTy),
674 M.makeLvalueToRvalue(M.makeDeclRefExpr(NewValue), NewValueTy),
675 NewValueTy);
676
677 Expr *BoolVal = M.makeObjCBool(true);
678 Expr *RetVal = isBoolean ? M.makeIntegralCastToBoolean(BoolVal)
679 : M.makeIntegralCast(BoolVal, ResultTy);
680 Stmts[1] = M.makeReturn(RetVal);
682
683
684 BoolVal = M.makeObjCBool(false);
685 RetVal = isBoolean ? M.makeIntegralCastToBoolean(BoolVal)
686 : M.makeIntegralCast(BoolVal, ResultTy);
687 Stmt *Else = M.makeReturn(RetVal);
688
689
690 auto *If =
692 nullptr,
693 nullptr, Comparison,
696
697 return If;
698}
699
701 std::optional<Stmt *> &Val = Bodies[D];
702 if (Val)
703 return *Val;
704
705 Val = nullptr;
706
707 if (D->getIdentifier() == nullptr)
708 return nullptr;
709
710 StringRef Name = D->getName();
711 if (Name.empty())
712 return nullptr;
713
715
716 if (unsigned BuiltinID = D->getBuiltinID()) {
717 switch (BuiltinID) {
718 case Builtin::BIas_const:
719 case Builtin::BIforward:
720 case Builtin::BIforward_like:
721 case Builtin::BImove:
722 case Builtin::BImove_if_noexcept:
724 break;
725 default:
726 FF = nullptr;
727 break;
728 }
729 } else if (Name.starts_with("OSAtomicCompareAndSwap") ||
730 Name.starts_with("objc_atomicCompareAndSwap")) {
734 } else {
735 FF = llvm::StringSwitch(Name)
738 .Default(nullptr);
739 }
740
741 if (FF) { Val = FF(C, D); }
742 else if (Injector) { Val = Injector->getBody(D); }
743 return *Val;
744}
745
748
749 if (IVar)
750 return IVar;
751
752
753
754
755
756
757
759 return nullptr;
760
761 auto *Container = cast(Prop->getDeclContext());
763 if (auto *InterfaceDecl = dyn_cast(Container)) {
764 PrimaryInterface = InterfaceDecl;
765 } else if (auto *CategoryDecl = dyn_cast(Container)) {
766 PrimaryInterface = CategoryDecl->getClassInterface();
767 } else if (auto *ImplDecl = dyn_cast(Container)) {
768 PrimaryInterface = ImplDecl->getClassInterface();
769 } else {
770 return nullptr;
771 }
772
773
774
775
778 if (ShadowingProp && ShadowingProp != Prop) {
779 IVar = ShadowingProp->getPropertyIvarDecl();
780 }
781
782 return IVar;
783}
784
787
790
791
792
793
798 if (const ObjCPropertyDecl *Candidate = PI->getPropertyDecl()) {
799 if (Candidate->getGetterName() == MD->getSelector()) {
800 Prop = Candidate;
802 }
803 }
804 }
805 }
806
807 if (!IVar) {
810 }
811
812 if (!IVar || !Prop)
813 return nullptr;
814
815
817 return nullptr;
818
819
820
821
822
823
826 if (ImplDecl) {
828 if (I->getPropertyDecl() != Prop)
829 continue;
830
831 if (I->getGetterCXXConstructor()) {
832 ASTMaker M(Ctx);
833 return M.makeReturn(I->getGetterCXXConstructor());
834 }
835 }
836 }
837
838
839
842 return nullptr;
845 return nullptr;
846
847
848
849 ASTMaker M(Ctx);
850
852 if (!selfVar)
853 return nullptr;
854
855 Expr *loadedIVar = M.makeObjCIvarRef(
856 M.makeLvalueToRvalue(M.makeDeclRefExpr(selfVar), selfVar->getType()),
857 IVar);
858
860 loadedIVar = M.makeLvalueToRvalue(loadedIVar, IVar->getType());
861
862 return M.makeReturn(loadedIVar);
863}
864
866
867 if (->isPropertyAccessor())
868 return nullptr;
869
871
872
873
875 return nullptr;
876
877 std::optional<Stmt *> &Val = Bodies[D];
878 if (Val)
879 return *Val;
880 Val = nullptr;
881
882
883
884
885
886
887
888
889
890
891 if (D->param_size() != 0)
892 return nullptr;
893
894
895
897 if (dyn_cast(D->getParent()) != OID)
899 auto *OMD = Ext->getInstanceMethod(D->getSelector());
900 if (OMD && !OMD->isImplicit())
901 return nullptr;
902 }
903
905
906 return *Val;
907}
Defines the clang::ASTContext interface.
static Stmt * create_call_once(ASTContext &C, const FunctionDecl *D)
Create a fake body for std::call_once.
static Stmt * create_dispatch_once(ASTContext &C, const FunctionDecl *D)
Create a fake body for dispatch_once.
static Stmt * create_OSAtomicCompareAndSwap(ASTContext &C, const FunctionDecl *D)
static Stmt * create_dispatch_sync(ASTContext &C, const FunctionDecl *D)
Create a fake body for dispatch_sync.
static Stmt * createObjCPropertyGetter(ASTContext &Ctx, const ObjCMethodDecl *MD)
static Stmt * create_std_move_forward(ASTContext &C, const FunctionDecl *D)
Create a fake body for 'std::move' or 'std::forward'.
static CallExpr * create_call_once_lambda_call(ASTContext &C, ASTMaker M, const ParmVarDecl *Callback, CXXRecordDecl *CallbackDecl, ArrayRef< Expr * > CallArgs)
static CallExpr * create_call_once_funcptr_call(ASTContext &C, ASTMaker M, const ParmVarDecl *Callback, ArrayRef< Expr * > CallArgs)
static bool isDispatchBlock(QualType Ty)
Stmt *(* FunctionFarmer)(ASTContext &C, const FunctionDecl *D)
static const ObjCIvarDecl * findBackingIvar(const ObjCPropertyDecl *Prop)
Defines enum values for all the target-independent builtin functions.
Defines the clang::CodeInjector interface which is responsible for injecting AST of function definiti...
Defines the clang::Expr interface and subclasses for C++ expressions.
Defines an enumeration for C++ overloaded operators.
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
bool hasSameUnqualifiedType(QualType T1, QualType T2) const
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
A builtin binary operation expression such as "x + y" or "x <= y".
bool isComparisonOp() const
static BinaryOperator * Create(const ASTContext &C, Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy, ExprValueKind VK, ExprObjectKind OK, SourceLocation opLoc, FPOptionsOverride FPFeatures)
QualType getPointeeType() const
Stmt * getBody(const FunctionDecl *D)
Factory method for creating bodies for ordinary functions.
BasePaths - Represents the set of paths from a derived class to one of its (direct or indirect) bases...
static CXXOperatorCallExpr * Create(const ASTContext &Ctx, OverloadedOperatorKind OpKind, Expr *Fn, ArrayRef< Expr * > Args, QualType Ty, ExprValueKind VK, SourceLocation OperatorLoc, FPOptionsOverride FPFeatures, ADLCallKind UsesADL=NotADL)
Represents a C++ struct/union/class.
bool isLambda() const
Determine whether this class describes a lambda function object.
CXXMethodDecl * getLambdaCallOperator() const
Retrieve the lambda call operator of the closure type if this is a closure type.
static CXXStaticCastExpr * Create(const ASTContext &Context, QualType T, ExprValueKind VK, CastKind K, Expr *Op, const CXXCastPath *Path, TypeSourceInfo *Written, FPOptionsOverride FPO, SourceLocation L, SourceLocation RParenLoc, SourceRange AngleBrackets)
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
static CallExpr * Create(const ASTContext &Ctx, Expr *Fn, ArrayRef< Expr * > Args, QualType Ty, ExprValueKind VK, SourceLocation RParenLoc, FPOptionsOverride FPFeatures, unsigned MinNumArgs=0, ADLCallKind UsesADL=NotADL)
Create a call expression.
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
virtual Stmt * getBody(const FunctionDecl *D)=0
CompoundStmt - This represents a group of statements like { stmt stmt }.
static CompoundStmt * Create(const ASTContext &C, ArrayRef< Stmt * > Stmts, FPOptionsOverride FPFeatures, SourceLocation LB, SourceLocation RB)
A POD class for pairing a NamedDecl* with an access specifier.
static DeclAccessPair make(NamedDecl *D, AccessSpecifier AS)
The results of name lookup within a DeclContext.
lookup_result lookup(DeclarationName Name) const
lookup - Find the declarations (if any) with the given Name in this context.
bool isStdNamespace() const
bool isFunctionOrMethod() const
A reference to a declared variable, function, enum, etc.
static DeclRefExpr * Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, ValueDecl *D, bool RefersToEnclosingVariableOrCapture, SourceLocation NameLoc, QualType T, ExprValueKind VK, NamedDecl *FoundD=nullptr, const TemplateArgumentListInfo *TemplateArgs=nullptr, NonOdrUseReason NOUR=NOUR_None)
Decl - This represents one declaration (or definition), e.g.
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
DeclContext * getDeclContext()
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
The name of a declaration.
This represents one expression.
Represents difference between two FPOptions values.
Represents a function declaration or definition.
Represents a prototype with parameter type info, e.g.
unsigned getNumParams() const
QualType getParamType(unsigned i) const
FunctionType - C99 6.7.5.3 - Function Declarators.
QualType getReturnType() const
One of these records is kept for each identifier that is lexed.
static IfStmt * Create(const ASTContext &Ctx, SourceLocation IL, IfStatementKind Kind, Stmt *Init, VarDecl *Var, Expr *Cond, SourceLocation LPL, SourceLocation RPL, Stmt *Then, SourceLocation EL=SourceLocation(), Stmt *Else=nullptr)
Create an IfStmt.
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
static ImplicitCastExpr * Create(const ASTContext &Context, QualType T, CastKind Kind, Expr *Operand, const CXXCastPath *BasePath, ExprValueKind Cat, FPOptionsOverride FPO)
static IntegerLiteral * Create(const ASTContext &C, const llvm::APInt &V, QualType type, SourceLocation l)
Returns a new integer literal with value 'V' and type 'type'.
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
static MemberExpr * Create(const ASTContext &C, Expr *Base, bool IsArrow, SourceLocation OperatorLoc, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, ValueDecl *MemberDecl, DeclAccessPair FoundDecl, DeclarationNameInfo MemberNameInfo, const TemplateArgumentListInfo *TemplateArgs, QualType T, ExprValueKind VK, ExprObjectKind OK, NonOdrUseReason NOUR)
This represents a decl that may have a name.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
A C++ nested-name-specifier augmented with source location information.
ObjCBoolLiteralExpr - Objective-C Boolean Literal.
propimpl_range property_impls() const
ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...
Represents an ObjC class declaration.
ObjCPropertyDecl * FindPropertyVisibleInPrimaryClass(const IdentifierInfo *PropertyId, ObjCPropertyQueryKind QueryKind) const
FindPropertyVisibleInPrimaryClass - Finds declaration of the property with name 'PropertyId' in the p...
ObjCImplementationDecl * getImplementation() const
known_extensions_range known_extensions() const
ObjCIvarDecl - Represents an ObjC instance variable.
ObjCInterfaceDecl * getContainingInterface()
Return the class interface that this ivar is logically contained in; this is either the interface whe...
ObjCIvarRefExpr - A reference to an ObjC instance variable.
ObjCMethodDecl - Represents an instance or class method declaration.
ImplicitParamDecl * getSelfDecl() const
const ObjCPropertyDecl * findPropertyDecl(bool CheckOverrides=true) const
Returns the property associated with this method's selector.
bool isSynthesizedAccessorStub() const
Selector getSelector() const
QualType getReturnType() const
ObjCInterfaceDecl * getClassInterface()
Represents one property declaration in an Objective-C interface.
ObjCPropertyQueryKind getQueryKind() const
bool isReadOnly() const
isReadOnly - Return true iff the property has a setter.
ObjCIvarDecl * getPropertyIvarDecl() const
ObjCPropertyAttribute::Kind getPropertyAttributes() const
A single parameter index whose accessors require each use to make explicit the parameter index encodi...
Represents a parameter to a function.
PointerType - C99 6.7.5.1 - Pointer Declarators.
QualType getPointeeType() const
A (possibly-)qualified type.
bool isTriviallyCopyableType(const ASTContext &Context) const
Return true if this is a trivially copyable type (C++0x [basic.types]p9)
bool isNull() const
Return true if this QualType doesn't point to a type yet.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
QualType getCanonicalType() const
Represents a struct/union/class.
ReturnStmt - This represents a return, optionally of an expression: return; return 4;.
static ReturnStmt * Create(const ASTContext &Ctx, SourceLocation RL, Expr *E, const VarDecl *NRVOCandidate)
Create a return statement.
Encodes a location in the source.
A trivial tuple used to represent a source range.
Stmt - This represents one statement.
The base class of the type hierarchy.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isBooleanType() const
bool isRValueReferenceType() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
bool isReferenceType() const
bool isIntegralType(const ASTContext &Ctx) const
Determine whether this type is an integral type.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isLValueReferenceType() const
bool isObjCLifetimeType() const
Returns true if objects of this type have lifetime semantics under ARC.
const T * getAs() const
Member-template getAs'.
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
static UnaryOperator * Create(const ASTContext &C, Expr *input, Opcode opc, QualType type, ExprValueKind VK, ExprObjectKind OK, SourceLocation l, bool CanOverflow, FPOptionsOverride FPFeatures)
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Represents a variable declaration or definition.
The JSON file list parser is used to communicate input to InstallAPI.
@ OK_Ordinary
An ordinary object is located at an address in memory.
@ If
'if' clause, allowed on all the Compute Constructs, Data Constructs, Executable Constructs,...
CastKind
CastKind - The kind of operation required for a conversion.
ExprValueKind
The categorization of expression values, currently following the C++11 scheme.
@ VK_PRValue
A pr-value expression (in the C++11 taxonomy) produces a temporary value.
@ VK_XValue
An x-value expression is a reference to an object with independent storage but which can be "moved",...
@ VK_LValue
An l-value expression is a reference to an object with independent storage.
@ NOUR_None
This is an odr-use.
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspon...