clang: include/clang/AST/Redeclarable.h Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13#ifndef LLVM_CLANG_AST_REDECLARABLE_H

14#define LLVM_CLANG_AST_REDECLARABLE_H

15

17#include "llvm/ADT/DenseMapInfo.h"

18#include "llvm/ADT/PointerUnion.h"

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

20#include "llvm/Support/Casting.h"

21#include

22#include

23#include

24

26

27class ASTContext;

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83template<typename decl_type>

85protected:

87

88

92

93

94

95

96 using UninitializedLatest = const void *;

97

99

100

101

102

103 using NotKnownLatest = llvm::PointerUnion<Previous, UninitializedLatest>;

104

105 mutable llvm::PointerUnion<NotKnownLatest, KnownLatest> Link;

106

107 public:

110

112 : Link(NotKnownLatest(reinterpret_cast(&Ctx))) {}

114

116 return isa(Link) ||

117

118

119 isa(cast(Link));

120 }

121

123 if (NotKnownLatest NKL = dyn_cast(Link)) {

124 if (auto *Prev = dyn_cast(NKL))

125 return static_cast<decl_type *>(Prev);

126

127

129 cast(NKL)),

130 const_cast<decl_type *>(D));

131 }

132

133 return static_cast<decl_type *>(cast(Link).get(D));

134 }

135

137 assert(isFirst() && "decl became non-canonical unexpectedly");

139 }

140

142 assert(isFirst() && "decl became canonical unexpectedly");

143 if (NotKnownLatest NKL = dyn_cast(Link)) {

145 cast(NKL)),

146 D);

147 } else {

148 auto Latest = cast(Link);

149 Latest.set(D);

150 Link = Latest;

151 }

152 }

153

154 void markIncomplete() { cast(Link).markIncomplete(); }

155

157 assert(isFirst() && "expected a canonical decl");

158 if (isa(Link))

159 return nullptr;

160 return cast(Link).getNotUpdated();

161 }

162 };

163

166 }

167

170 }

171

172

173

174

175

176

177

178

179

180

181

182

184

186

189 }

190

191public:

196

199 First(static_cast<decl_type *>(this)) {}

200

201

202

206 return nullptr;

207 }

209 return const_cast<decl_type *>(

210 static_cast<const decl_type*>(this))->getPreviousDecl();

211 }

212

213

214

216

217

218

220

221

223

224

226 return getFirstDecl()->getNextRedeclaration();

227 }

228

229

231 return getFirstDecl()->getNextRedeclaration();

232 }

233

234

235

237

238

240

241 decl_type *Current = nullptr;

242 decl_type *Starter = nullptr;

243 bool PassedFirst = false;

244

245 public:

251

254

257

259 assert(Current && "Advancing while iterator has reached end");

260

261

262 if (Current->isFirstDecl()) {

263 if (PassedFirst) {

264 assert(0 && "Passed first decl twice, invalid redecl chain!");

265 Current = nullptr;

266 return *this;

267 }

268 PassedFirst = true;

269 }

270

271

272 decl_type *Next = Current->getNextRedeclaration();

273 Current = (Next != Starter) ? Next : nullptr;

274 return *this;

275 }

276

279 ++(*this);

280 return tmp;

281 }

282

284 return x.Current == y.Current;

285 }

287 return x.Current != y.Current;

288 }

289 };

290

291 using redecl_range = llvm::iterator_range<redecl_iterator>;

292

293

294

297 static_cast<const decl_type *>(this))),

299 }

300

303};

304

305

306

308

309

310

311

312template<typename decl_type>

314public:

316

317

318

320 auto *D = static_cast<decl_type *>(this);

321 if (D->isFromASTFile())

322 return D;

324 }

325

326

327

329 const auto *D = static_cast<const decl_type *>(this);

330 if (D->isFromASTFile())

331 return D;

333 }

334

335

337};

338

339

340

341

342

343

344

345

346

347

349public:

355

356 operator decl_type *() { return Ptr; }

357 operator const decl_type *() const { return Ptr; }

358

360 const decl_type *operator->() const { return Ptr; }

361

363 const decl_type &operator*() const { return *Ptr; }

364

366 return LHS.Ptr == RHS.Ptr;

367 }

369 return LHS.Ptr != RHS.Ptr;

370 }

371

372private:

373 friend struct llvm::DenseMapInfo<CanonicalDeclPtr<decl_type>>;

375

376 decl_type *Ptr = nullptr;

377};

378

379}

380

381namespace llvm {

382

383template <typename decl_type>

386 using BaseInfo = DenseMapInfo<decl_type *>;

387

389

390

392 P.Ptr = BaseInfo::getEmptyKey();

393 return P;

394 }

395

398 P.Ptr = BaseInfo::getTombstoneKey();

399 return P;

400 }

401

403 return BaseInfo::getHashValue(P);

404 }

405

408 return BaseInfo::isEqual(LHS, RHS);

409 }

410};

411

412template <typename decl_type>

415 return P.Ptr;

416 }

420 return C;

421 }

422 static constexpr int NumLowBitsAvailable =

424};

425

426}

427

428#endif

static const Decl * getCanonicalDecl(const Decl *D)

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

A wrapper class around a pointer that always points to its canonical declaration.

CanonicalDeclPtr(const CanonicalDeclPtr &)=default

const decl_type * operator->() const

CanonicalDeclPtr & operator=(const CanonicalDeclPtr &)=default

const decl_type & operator*() const

CanonicalDeclPtr(decl_type *Ptr)

friend bool operator==(CanonicalDeclPtr LHS, CanonicalDeclPtr RHS)

CanonicalDeclPtr()=default

friend bool operator!=(CanonicalDeclPtr LHS, CanonicalDeclPtr RHS)

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

virtual void CompleteRedeclChain(const Decl *D)

Gives the external AST source an opportunity to complete the redeclaration chain for a declaration.

Provides support for incremental compilation.

Provides common interface for the Decls that cannot be redeclared, but can be merged if the same decl...

bool isFirstDecl() const

Returns true if this is the first declaration.

const decl_type * getFirstDecl() const

Return the first declaration of this declaration or itself if this is the only declaration.

decl_type * getFirstDecl()

Return the first declaration of this declaration or itself if this is the only declaration.

DeclLink(LatestTag, const ASTContext &Ctx)

DeclLink(PreviousTag, decl_type *D)

void setPrevious(decl_type *D)

Decl * getLatestNotUpdated() const

void setLatest(decl_type *D)

decl_type * getPrevious(const decl_type *D) const

Iterates through all the redeclarations of the same decl.

friend bool operator!=(const redecl_iterator &x, const redecl_iterator &y)

friend bool operator==(const redecl_iterator &x, const redecl_iterator &y)

redecl_iterator(decl_type *C)

redecl_iterator()=default

std::forward_iterator_tag iterator_category

std::ptrdiff_t difference_type

reference operator*() const

redecl_iterator operator++(int)

redecl_iterator & operator++()

pointer operator->() const

Provides common interface for the Decls that can be redeclared.

decl_type * getFirstDecl()

Return the first declaration of this declaration or itself if this is the only declaration.

const decl_type * getMostRecentDecl() const

Returns the most recent (re)declaration of this declaration.

const decl_type * getFirstDecl() const

Return the first declaration of this declaration or itself if this is the only declaration.

decl_type * getNextRedeclaration() const

Redeclarable(const ASTContext &Ctx)

decl_type * getPreviousDecl()

Return the previous declaration of this declaration or NULL if this is the first declaration.

redecl_iterator redecls_end() const

const decl_type * getPreviousDecl() const

DeclLink RedeclLink

Points to the next redeclaration in the chain.

llvm::iterator_range< redecl_iterator > redecl_range

decl_type * getMostRecentDecl()

Returns the most recent (re)declaration of this declaration.

void setPreviousDecl(decl_type *PrevDecl)

Set the previous declaration.

static DeclLink LatestDeclLink(const ASTContext &Ctx)

bool isFirstDecl() const

True if this is the first declaration in its redeclaration chain.

redecl_iterator redecls_begin() const

redecl_range redecls() const

Returns an iterator range for all the redeclarations of the same decl.

static DeclLink PreviousDeclLink(decl_type *D)

@ Decl

The l-value was an access to a declared entity or something equivalently strong, like the address of ...

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

Decl * getPrimaryMergedDecl(Decl *D)

Get the primary declaration for a declaration from an AST file.

Diagnostic wrappers for TextAPI types for error reporting.

A lazy value (of type T) that is within an AST node of type Owner, where the value might change in la...

static unsigned getHashValue(const CanonicalDeclPtr &P)

static bool isEqual(const CanonicalDeclPtr &LHS, const CanonicalDeclPtr &RHS)

static CanonicalDeclPtr getEmptyKey()

DenseMapInfo< decl_type * > BaseInfo

static CanonicalDeclPtr getTombstoneKey()

static void * getAsVoidPointer(clang::CanonicalDeclPtr< decl_type > P)

static clang::CanonicalDeclPtr< decl_type > getFromVoidPointer(void *P)