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 (D->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...