clang: lib/Analysis/AnalysisDeclContext.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

37#include "llvm/ADT/DenseMap.h"

38#include "llvm/ADT/FoldingSet.h"

39#include "llvm/ADT/SmallPtrSet.h"

40#include "llvm/ADT/iterator_range.h"

41#include "llvm/Support/Allocator.h"

42#include "llvm/Support/Compiler.h"

43#include "llvm/Support/ErrorHandling.h"

44#include "llvm/Support/SaveAndRestore.h"

45#include "llvm/Support/raw_ostream.h"

46#include

47#include

48

49using namespace clang;

50

51using ManagedAnalysisMap = llvm::DenseMap<const void *, std::unique_ptr>;

52

54 const Decl *D,

56 : ADCMgr(ADCMgr), D(D), cfgBuildOptions(Options) {

57 cfgBuildOptions.forcedBlkExprs = &forcedBlkExprs;

58}

59

61 const Decl *D)

62 : ADCMgr(ADCMgr), D(D) {

63 cfgBuildOptions.forcedBlkExprs = &forcedBlkExprs;

64}

65

67 ASTContext &ASTCtx, bool useUnoptimizedCFG, bool addImplicitDtors,

68 bool addInitializers, bool addTemporaryDtors, bool addLifetime,

70 bool addStaticInitBranch, bool addCXXNewAllocator,

71 bool addRichCXXConstructors, bool markElidedCXXConstructors,

72 bool addVirtualBaseBranches, std::unique_ptr injector)

73 : Injector(std::move(injector)), FunctionBodyFarm(ASTCtx, Injector.get()),

75 cfgBuildOptions.PruneTriviallyFalseEdges = !useUnoptimizedCFG;

76 cfgBuildOptions.AddImplicitDtors = addImplicitDtors;

77 cfgBuildOptions.AddInitializers = addInitializers;

78 cfgBuildOptions.AddTemporaryDtors = addTemporaryDtors;

79 cfgBuildOptions.AddLifetime = addLifetime;

80 cfgBuildOptions.AddLoopExit = addLoopExit;

81 cfgBuildOptions.AddScopes = addScopes;

82 cfgBuildOptions.AddStaticInitBranches = addStaticInitBranch;

83 cfgBuildOptions.AddCXXNewAllocator = addCXXNewAllocator;

84 cfgBuildOptions.AddRichCXXConstructors = addRichCXXConstructors;

85 cfgBuildOptions.MarkElidedCXXConstructors = markElidedCXXConstructors;

86 cfgBuildOptions.AddVirtualBaseBranches = addVirtualBaseBranches;

87}

88

90

92 IsAutosynthesized = false;

93 if (const auto *FD = dyn_cast(D)) {

94 Stmt *Body = FD->getBody();

95 if (auto *CoroBody = dyn_cast_or_null(Body))

96 Body = CoroBody->getBody();

97 if (ADCMgr && ADCMgr->synthesizeBodies()) {

98 Stmt *SynthesizedBody = ADCMgr->getBodyFarm().getBody(FD);

99 if (SynthesizedBody) {

100 Body = SynthesizedBody;

101 IsAutosynthesized = true;

102 }

103 }

104 return Body;

105 }

106 else if (const auto *MD = dyn_cast(D)) {

107 Stmt *Body = MD->getBody();

108 if (ADCMgr && ADCMgr->synthesizeBodies()) {

109 Stmt *SynthesizedBody = ADCMgr->getBodyFarm().getBody(MD);

110 if (SynthesizedBody) {

111 Body = SynthesizedBody;

112 IsAutosynthesized = true;

113 }

114 }

115 return Body;

116 } else if (const auto *BD = dyn_cast(D))

117 return BD->getBody();

118 else if (const auto *FunTmpl = dyn_cast_or_null(D))

119 return FunTmpl->getTemplatedDecl()->getBody();

120 else if (const auto *VD = dyn_cast_or_null(D)) {

121 if (VD->isFileVarDecl()) {

122 return const_cast<Stmt *>(dyn_cast_or_null(VD->getInit()));

123 }

124 }

125

126 llvm_unreachable("unknown code decl");

127}

128

133

135 bool Tmp;

137 return Tmp;

138}

139

145

146

148 return isa_and_nonnull(VD) && VD->getName() == "self";

149}

150

152 if (const auto *MD = dyn_cast(D))

153 return MD->getSelfDecl();

154 if (const auto *BD = dyn_cast(D)) {

155

156 for (const auto &I : BD->captures()) {

157 const VarDecl *VD = I.getVariable();

159 return dyn_cast(VD);

160 }

161 }

162

163 auto *CXXMethod = dyn_cast(D);

164 if (!CXXMethod)

165 return nullptr;

166

169 return nullptr;

170

171 for (const auto &LC : parent->captures()) {

172 if (!LC.capturesVariable())

173 continue;

174

175 ValueDecl *VD = LC.getCapturedVar();

176 if (isSelfDecl(dyn_cast(VD)))

177 return dyn_cast(VD);

178 }

179

180 return nullptr;

181}

182

184 if (!forcedBlkExprs)

186

187 if (const auto *e = dyn_cast(stmt))

188 stmt = e->IgnoreParens();

189 (void) (*forcedBlkExprs)[stmt];

190}

191

194 assert(forcedBlkExprs);

195 if (const auto *e = dyn_cast(stmt))

196 stmt = e->IgnoreParens();

197 CFG::BuildOptions::ForcedBlkExprs::const_iterator itr =

198 forcedBlkExprs->find(stmt);

199 assert(itr != forcedBlkExprs->end());

200 return itr->second;

201}

202

203

204

206 if (!TheCFG)

207 return;

208

211 I != E; ++I) {

213 }

214}

215

217 if (!cfgBuildOptions.PruneTriviallyFalseEdges)

219

220 if (!builtCFG) {

222

223

224 builtCFG = true;

225

226 if (PM)

228

229

231 }

232 return cfg.get();

233}

234

236 if (!builtCompleteCFG) {

237 SaveAndRestore NotPrune(cfgBuildOptions.PruneTriviallyFalseEdges, false);

238 completeCFG =

240

241

242 builtCompleteCFG = true;

243

244 if (PM)

246

247

249 }

250 return completeCFG.get();

251}

252

254 if (cfgStmtMap)

255 return cfgStmtMap.get();

256

259 return cfgStmtMap.get();

260 }

261

262 return nullptr;

263}

264

266 if (CFA)

267 return CFA.get();

268

271 return CFA.get();

272 }

273

274 return nullptr;

275}

276

280

282 if (!PM) {

284 if (const auto *C = dyn_cast(getDecl())) {

285 for (const auto *I : C->inits()) {

286 PM->addStmt(I->getInit());

287 }

288 }

289 if (builtCFG)

291 if (builtCompleteCFG)

293 }

294 return *PM;

295}

296

298 if (const auto *FD = dyn_cast(D)) {

299

300

301 FD->hasBody(FD);

302 D = FD;

303 }

304

305 std::unique_ptr &AC = Contexts[D];

306 if (!AC)

307 AC = std::make_unique(this, D, cfgBuildOptions);

308 return AC.get();

309}

310

312

316 unsigned BlockCount, unsigned Index) {

317 return getLocationContextManager().getStackFrame(this, ParentLC, S, Blk,

318 BlockCount, Index);

319}

320

323 return getLocationContextManager().getBlockInvocationContext(this, ParentLC,

325}

326

329 const auto *ND = dyn_cast(DC);

330 if (!ND)

331 return false;

332

335 break;

337 }

338

339 return ND->isStdNamespace();

340}

341

343 std::string Str;

344 llvm::raw_string_ostream OS(Str);

345 const ASTContext &Ctx = D->getASTContext();

346

347 if (const FunctionDecl *FD = dyn_cast(D)) {

348 OS << FD->getQualifiedNameAsString();

349

350

351

353 OS << '(';

354 for (const auto &P : FD->parameters()) {

355 if (P != *FD->param_begin())

356 OS << ", ";

357 OS << P->getType();

358 }

359 OS << ')';

360 }

361

364

366 OS << "block (line: " << Loc.getLine() << ", col: " << Loc.getColumn()

367 << ')';

368 }

369

370 } else if (const ObjCMethodDecl *OMD = dyn_cast(D)) {

371

372

373 OS << (OMD->isInstanceMethod() ? '-' : '+') << '[';

374 const DeclContext *DC = OMD->getDeclContext();

375 if (const auto *OID = dyn_cast(DC)) {

376 OS << OID->getName();

377 } else if (const auto *OID = dyn_cast(DC)) {

378 OS << OID->getName();

379 } else if (const auto *OC = dyn_cast(DC)) {

380 if (OC->IsClassExtension()) {

381 OS << OC->getClassInterface()->getName();

382 } else {

383 OS << OC->getIdentifier()->getNameStart() << '('

384 << OC->getIdentifier()->getNameStart() << ')';

385 }

386 } else if (const auto *OCD = dyn_cast(DC)) {

387 OS << OCD->getClassInterface()->getName() << '(' << OCD->getName() << ')';

388 }

389 OS << ' ' << OMD->getSelector().getAsString() << ']';

390 }

391

392 return Str;

393}

394

396 assert(

397 ADCMgr &&

398 "Cannot create LocationContexts without an AnalysisDeclContextManager!");

399 return ADCMgr->getLocationContextManager();

400}

401

402

403

404

405

410 const void *data) {

411 ID.AddInteger(ck);

412 ID.AddPointer(ctx);

413 ID.AddPointer(parent);

414 ID.AddPointer(data);

415}

416

419 BlockCount, Index);

420}

421

425

426

427

428

429

432 const CFGBlock *blk, unsigned blockCount, unsigned idx) {

433 llvm::FoldingSetNodeID ID;

435 void *InsertPos;

436 auto *L =

437 cast_or_null(Contexts.FindNodeOrInsertPos(ID, InsertPos));

438 if (!L) {

439 L = new StackFrameContext(ctx, parent, s, blk, blockCount, idx, ++NewID);

440 Contexts.InsertNode(L, InsertPos);

441 }

442 return L;

443}

444

448 llvm::FoldingSetNodeID ID;

450 void *InsertPos;

451 auto *L =

452 cast_or_null(Contexts.FindNodeOrInsertPos(ID,

453 InsertPos));

454 if (!L) {

456 Contexts.InsertNode(L, InsertPos);

457 }

458 return L;

459}

460

461

462

463

464

467 while (LC) {

468 if (const auto *SFC = dyn_cast(LC))

469 return SFC;

471 }

472 return nullptr;

473}

474

478

480 do {

482 if (Parent == this)

483 return true;

484 else

485 LC = Parent;

486 } while (LC);

487

488 return false;

489}

490

493 if (Loc.isFileID() && SM.isInMainFile(Loc))

494 Out << SM.getExpansionLineNumber(Loc);

495 else

497}

498

503

506

507 unsigned Frame = 0;

508 for (const LocationContext *LCtx = this; LCtx; LCtx = LCtx->getParent()) {

509 switch (LCtx->getKind()) {

511 Out << "\t#" << Frame << ' ';

512 ++Frame;

513 if (const auto *D = dyn_cast(LCtx->getDecl()))

515 else

516 Out << "Calling anonymous code";

518 Out << " at line ";

520 }

521 break;

523 Out << "Invoking block";

525 Out << " defined at line ";

527 }

528 break;

529 }

530 Out << '\n';

531 }

532}

533

535 unsigned int Space, bool IsDot,

537 printMoreInfoPerContext) const {

541

544

545 unsigned Frame = 0;

546 for (const LocationContext *LCtx = this; LCtx; LCtx = LCtx->getParent()) {

547 Indent(Out, Space, IsDot)

548 << "{ \"lctx_id\": " << LCtx->getID() << ", \"location_context\": \"";

549 switch (LCtx->getKind()) {

551 Out << '#' << Frame << " Call\", \"calling\": \"";

552 ++Frame;

553 if (const auto *D = dyn_cast(LCtx->getDecl()))

554 Out << D->getQualifiedNameAsString();

555 else

556 Out << "anonymous code";

557

558 Out << "\", \"location\": ";

561 } else {

562 Out << "null";

563 }

564

565 Out << ", \"items\": ";

566 break;

568 Out << "Invoking block\" ";

570 Out << ", \"location\": ";

572 Out << ' ';

573 }

574 break;

575 }

576

577 printMoreInfoPerContext(LCtx);

578

579 Out << '}';

580 if (LCtx->getParent())

581 Out << ',';

582 Out << NL;

583 }

584}

585

587

588

589

590

591

592namespace {

593

594class FindBlockDeclRefExprsVals : public StmtVisitor{

599

600public:

603 : BEVals(bevals), BC(bc) {}

604

605 void VisitStmt(Stmt *S) {

606 for (auto *Child : S->children())

607 if (Child)

608 Visit(Child);

609 }

610

611 void VisitDeclRefExpr(DeclRefExpr *DR) {

612

613 if (const auto *VD = dyn_cast(DR->getDecl())) {

614 if (!VD->hasLocalStorage()) {

615 if (Visited.insert(VD).second)

617 }

618 }

619 }

620

621 void VisitBlockExpr(BlockExpr *BR) {

622

625 }

626

627 void VisitPseudoObjectExpr(PseudoObjectExpr *PE) {

630 Expr *Semantic = *it;

631 if (auto *OVE = dyn_cast(Semantic))

632 Semantic = OVE->getSourceExpr();

633 Visit(Semantic);

634 }

635 }

636};

637

638}

639

641

643 void *&Vec,

644 llvm::BumpPtrAllocator &A) {

645 if (Vec)

647

650 new (BV) DeclVec(BC, 10);

651

652

653 for (const auto &CI : BD->captures()) {

654 BV->push_back(CI.getVariable(), BC);

655 }

656

657

658 FindBlockDeclRefExprsVals F(*BV, BC);

660

661 Vec = BV;

662 return BV;

663}

664

665llvm::iterator_rangeAnalysisDeclContext::referenced\_decls\_iterator

667 if (!ReferencedBlockVars)

668 ReferencedBlockVars = new llvm::DenseMap<const BlockDecl*,void*>();

669

672 return llvm::make_range(V->begin(), V->end());

673}

674

675std::unique_ptr &AnalysisDeclContext::getAnalysisImpl(const void *tag) {

676 if (!ManagedAnalyses)

679 return (*M)[tag];

680}

681

682

683

684

685

687

689 delete forcedBlkExprs;

690 delete ReferencedBlockVars;

692}

693

695

699

701 for (llvm::FoldingSet::iterator I = Contexts.begin(),

702 E = Contexts.end(); I != E; ) {

704 ++I;

705 delete LC;

706 }

707 Contexts.clear();

708}

Defines the clang::ASTContext interface.

static DeclVec * LazyInitializeReferencedDecls(const BlockDecl *BD, void *&Vec, llvm::BumpPtrAllocator &A)

Definition AnalysisDeclContext.cpp:642

static bool isSelfDecl(const VarDecl *VD)

Returns true if.

Definition AnalysisDeclContext.cpp:147

static void addParentsForSyntheticStmts(const CFG *TheCFG, ParentMap &PM)

Add each synthetic statement in the CFG to the parent map, using the source statement's parent.

Definition AnalysisDeclContext.cpp:205

static void printLocation(raw_ostream &Out, const SourceManager &SM, SourceLocation Loc)

Definition AnalysisDeclContext.cpp:491

llvm::DenseMap< const void *, std::unique_ptr< ManagedAnalysis > > ManagedAnalysisMap

Definition AnalysisDeclContext.cpp:51

BumpVector< const VarDecl * > DeclVec

Definition AnalysisDeclContext.cpp:640

This file defines AnalysisDeclContext, a class that manages the analysis context data for context sen...

Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....

Defines the C++ template declaration subclasses.

Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.

Defines the LambdaCapture class.

Defines the clang::SourceLocation class and associated facilities.

Defines the SourceManager interface.

__device__ __2f16 float __ockl_bool s

__device__ __2f16 float c

Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...

SourceManager & getSourceManager()

const LangOptions & getLangOpts() const

AnalysisDeclContextManager(ASTContext &ASTCtx, bool useUnoptimizedCFG=false, bool addImplicitDtors=false, bool addInitializers=false, bool addTemporaryDtors=false, bool addLifetime=false, bool addLoopExit=false, bool addScopes=false, bool synthesizeBodies=false, bool addStaticInitBranches=false, bool addCXXNewAllocator=true, bool addRichCXXConstructors=true, bool markElidedCXXConstructors=true, bool addVirtualBaseBranches=true, std::unique_ptr< CodeInjector > injector=nullptr)

Definition AnalysisDeclContext.cpp:66

friend class AnalysisDeclContext

bool synthesizeBodies() const

void clear()

Discard all previously created AnalysisDeclContexts.

Definition AnalysisDeclContext.cpp:89

AnalysisDeclContext * getContext(const Decl *D)

Definition AnalysisDeclContext.cpp:297

BodyFarm & getBodyFarm()

Definition AnalysisDeclContext.cpp:311

AnalysisDeclContext contains the context data for the function, method or block under analysis.

static std::string getFunctionName(const Decl *D)

Definition AnalysisDeclContext.cpp:342

void registerForcedBlockExpression(const Stmt *stmt)

Definition AnalysisDeclContext.cpp:183

const BlockInvocationContext * getBlockInvocationContext(const LocationContext *ParentLC, const BlockDecl *BD, const void *Data)

Obtain a context of the block invocation using its parent context.

Definition AnalysisDeclContext.cpp:321

CFGStmtMap * getCFGStmtMap()

Definition AnalysisDeclContext.cpp:253

const CFGBlock * getBlockForRegisteredExpression(const Stmt *stmt)

Definition AnalysisDeclContext.cpp:193

ParentMap & getParentMap()

Definition AnalysisDeclContext.cpp:281

~AnalysisDeclContext()

Definition AnalysisDeclContext.cpp:688

const Decl * getDecl() const

Stmt * getBody() const

Definition AnalysisDeclContext.cpp:129

CFG * getCFG()

Definition AnalysisDeclContext.cpp:216

static bool isInStdNamespace(const Decl *D)

Definition AnalysisDeclContext.cpp:327

CFGReverseBlockReachabilityAnalysis * getCFGReachablityAnalysis()

Definition AnalysisDeclContext.cpp:265

const ImplicitParamDecl * getSelfDecl() const

Definition AnalysisDeclContext.cpp:151

const StackFrameContext * getStackFrame(LocationContext const *ParentLC, const Stmt *S, const CFGBlock *Blk, unsigned BlockCount, unsigned Index)

Obtain a context of the call stack using its parent context.

Definition AnalysisDeclContext.cpp:314

ASTContext & getASTContext() const

llvm::iterator_range< referenced_decls_iterator > getReferencedBlockVars(const BlockDecl *BD)

Definition AnalysisDeclContext.cpp:666

bool isBodyAutosynthesized() const

Definition AnalysisDeclContext.cpp:134

CFG * getUnoptimizedCFG()

Definition AnalysisDeclContext.cpp:235

AnalysisDeclContext(AnalysisDeclContextManager *Mgr, const Decl *D)

Definition AnalysisDeclContext.cpp:60

void dumpCFG(bool ShowColors)

Definition AnalysisDeclContext.cpp:277

CFG::BuildOptions & getCFGBuildOptions()

bool isBodyAutosynthesizedFromModelFile() const

Definition AnalysisDeclContext.cpp:140

Represents a block literal declaration, which is like an unnamed FunctionDecl.

Stmt * getBody() const override

getBody - If this Decl represents a declaration for a body of code, such as a function or method defi...

ArrayRef< Capture > captures() const

const BlockDecl * getBlockDecl() const

It represents a block invocation (based on BlockCall).

void Profile(llvm::FoldingSetNodeID &ID) override

Definition AnalysisDeclContext.cpp:422

void push_back(const_reference Elt, BumpVectorContext &C)

Represents a single basic block in a source-level CFG.

static CFGStmtMap * Build(CFG *C, ParentMap *PM)

Returns a new CFGMap for the given CFG.

llvm::DenseMap< const Stmt *, const CFGBlock * > ForcedBlkExprs

Represents a source-level, intra-procedural CFG that represents the control-flow of a Stmt.

static std::unique_ptr< CFG > buildCFG(const Decl *D, Stmt *AST, ASTContext *C, const BuildOptions &BO)

Builds a CFG from an AST.

synthetic_stmt_iterator synthetic_stmt_end() const

void dump(const LangOptions &LO, bool ShowColors) const

dump - A simple pretty printer of a CFG that outputs to stderr.

synthetic_stmt_iterator synthetic_stmt_begin() const

Iterates over synthetic DeclStmts in the CFG.

llvm::DenseMap< const DeclStmt *, const DeclStmt * >::const_iterator synthetic_stmt_iterator

Represents a C++ struct/union/class.

bool isLambda() const

Determine whether this class describes a lambda function object.

capture_const_range captures() const

DeclContext - This is used only as base class of specific decl types that can act as declaration cont...

DeclContext * getParent()

getParent - Returns the containing DeclContext.

DeclContext * getEnclosingNamespaceContext()

Retrieve the nearest enclosing namespace context.

Decl - This represents one declaration (or definition), e.g.

Represents a function declaration or definition.

~LocationContextManager()

Definition AnalysisDeclContext.cpp:696

const StackFrameContext * getStackFrame(AnalysisDeclContext *ADC, const LocationContext *ParentLC, const Stmt *S, const CFGBlock *Block, unsigned BlockCount, unsigned Index)

Obtain a context of the call stack using its parent context.

Definition AnalysisDeclContext.cpp:430

void clear()

Discard all previously created LocationContext objects.

Definition AnalysisDeclContext.cpp:700

const BlockInvocationContext * getBlockInvocationContext(AnalysisDeclContext *ADC, const LocationContext *ParentLC, const BlockDecl *BD, const void *Data)

Obtain a context of the block invocation using its parent context.

Definition AnalysisDeclContext.cpp:445

It wraps the AnalysisDeclContext to represent both the call stack with the help of StackFrameContext ...

bool isParentOf(const LocationContext *LC) const

Definition AnalysisDeclContext.cpp:479

const Decl * getDecl() const

LocationContext(ContextKind k, AnalysisDeclContext *ctx, const LocationContext *parent, int64_t ID)

LLVM_ATTRIBUTE_RETURNS_NONNULL AnalysisDeclContext * getAnalysisDeclContext() const

static void ProfileCommon(llvm::FoldingSetNodeID &ID, ContextKind ck, AnalysisDeclContext *ctx, const LocationContext *parent, const void *data)

Definition AnalysisDeclContext.cpp:406

const LocationContext * getParent() const

It might return null.

LLVM_DUMP_METHOD void dumpStack(raw_ostream &Out) const

Prints out the call stack.

Definition AnalysisDeclContext.cpp:499

LLVM_DUMP_METHOD void dump() const

Definition AnalysisDeclContext.cpp:586

const StackFrameContext * getStackFrame() const

Definition AnalysisDeclContext.cpp:465

virtual bool inTopFrame() const

Definition AnalysisDeclContext.cpp:475

virtual ~LocationContext()

void printJson(raw_ostream &Out, const char *NL="\n", unsigned int Space=0, bool IsDot=false, std::function< void(const LocationContext *)> printMoreInfoPerContext=[](const LocationContext *) {}) const

Prints out the call stack in json format.

Definition AnalysisDeclContext.cpp:534

virtual ~ManagedAnalysis()

StringRef getName() const

Get the name of identifier for this declaration as a StringRef.

ObjCMethodDecl - Represents an instance or class method declaration.

void setParent(const Stmt *S, const Stmt *Parent)

Manually sets the parent of S to Parent.

Stmt * getParent(Stmt *) const

Represents an unpacked "presumed" location which can be presented to the user.

unsigned getColumn() const

Return the presumed column number of this location.

unsigned getLine() const

Return the presumed line number of this location.

semantics_iterator semantics_end()

semantics_iterator semantics_begin()

Expr *const * semantics_iterator

Encodes a location in the source.

bool isValid() const

Return true if this is a valid SourceLocation object.

void print(raw_ostream &OS, const SourceManager &SM) const

This class handles loading and caching of source files into memory.

PresumedLoc getPresumedLoc(SourceLocation Loc, bool UseLineDirectives=true) const

Returns the "presumed" location of a SourceLocation specifies.

It represents a stack frame of the call stack (based on CallEvent).

void Profile(llvm::FoldingSetNodeID &ID) override

Definition AnalysisDeclContext.cpp:417

bool inTopFrame() const override

StmtVisitor - This class implements a simple visitor for Stmt subclasses.

Stmt - This represents one statement.

SourceLocation getBeginLoc() const LLVM_READONLY

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.

const internal::VariadicAllOfMatcher< Stmt > stmt

Matches statements.

The JSON file list parser is used to communicate input to InstallAPI.

bool isa(CodeGen::Address addr)

raw_ostream & Indent(raw_ostream &Out, const unsigned int Space, bool IsDot)

void printSourceLocationAsJson(raw_ostream &Out, SourceLocation Loc, const SourceManager &SM, bool AddBraces=true)

U cast(CodeGen::Address addr)

int const char * function

Describes how types, statements, expressions, and declarations should be printed.

unsigned TerseOutput

Provide a 'terse' output.