clang: lib/Sema/IdentifierResolver.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

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

24#include

25#include

26

27using namespace clang;

28

29

30

31

32

33

34

35

37 static const unsigned int POOL_SIZE = 512;

38

39

40

41

42 struct IdDeclInfoPool {

43 IdDeclInfoPool *Next;

44 IdDeclInfo Pool[POOL_SIZE];

45

46 IdDeclInfoPool(IdDeclInfoPool *Next) : Next(Next) {}

47 };

48

49 IdDeclInfoPool *CurPool = nullptr;

50 unsigned int CurIndex = POOL_SIZE;

51

52public:

54

56 IdDeclInfoPool *Cur = CurPool;

57 while (IdDeclInfoPool *P = Cur) {

58 Cur = Cur->Next;

59 delete P;

60 }

61 }

62

65

66

67

69};

70

71

72

73

74

75

76

77void IdentifierResolver::IdDeclInfo::RemoveDecl(NamedDecl *D) {

78 for (DeclsTy::iterator I = Decls.end(); I != Decls.begin(); --I) {

79 if (D == *(I-1)) {

80 Decls.erase(I-1);

81 return;

82 }

83 }

84

85 llvm_unreachable("Didn't find this decl on its identifier's chain!");

86}

87

88

89

90

91

93 : LangOpt(PP.getLangOpts()), PP(PP), IdDeclInfos(new IdDeclInfoMap) {}

94

96 delete IdDeclInfos;

97}

98

99

100

101

103 bool AllowInlineNamespace) const {

104 Ctx = Ctx->getRedeclContext();

105

106

107

108 if (LangOpt.HLSL && isa(D))

109 return false;

110 if (Ctx->isFunctionOrMethod() || (S && S->isFunctionPrototypeScope())) {

111

112 while (S->getEntity() &&

113 (S->getEntity()->isTransparentContext() ||

114 (!LangOpt.CPlusPlus && isa(S->getEntity()))))

115 S = S->getParent();

116

117 if (S->isDeclScope(D))

118 return true;

119 if (LangOpt.CPlusPlus) {

120

121

122

123

124

125

126

127

128

129

130

131

132 assert(S->getParent() && "No TUScope?");

133

134

135 if (S->getParent()->isControlScope() && !S->isFunctionScope()) {

136 S = S->getParent();

137 if (S->isDeclScope(D))

138 return true;

139 }

140 if (S->isFnTryCatchScope())

141 return S->getParent()->isDeclScope(D);

142 }

143 return false;

144 }

145

146

147

148

150 return AllowInlineNamespace ? Ctx->InEnclosingNamespaceSetOf(DCtx)

151 : Ctx->Equals(DCtx);

152}

153

154

158 updatingIdentifier(*II);

159

160 void *Ptr = Name.getFETokenInfo();

161

162 if (!Ptr) {

163 Name.setFETokenInfo(D);

164 return;

165 }

166

167 IdDeclInfo *IDI;

168

169 if (isDeclPtr(Ptr)) {

170 Name.setFETokenInfo(nullptr);

171 IDI = &(*IdDeclInfos)[Name];

173 IDI->AddDecl(PrevD);

174 } else

175 IDI = toIdDeclInfo(Ptr);

176

177 IDI->AddDecl(D);

178}

179

183 updatingIdentifier(*II);

184

185 void *Ptr = Name.getFETokenInfo();

186

187 if (!Ptr) {

189 return;

190 }

191

192 if (isDeclPtr(Ptr)) {

193

194

196

201 } else {

202

204 }

205

206 return;

207 }

208

209

210

211 IdDeclInfo *IDI = toIdDeclInfo(Ptr);

214 } else

215 IDI->InsertDecl(IDI->decls_begin(), D);

216}

217

218

219

221 assert(D && "null param passed");

224 updatingIdentifier(*II);

225

226 void *Ptr = Name.getFETokenInfo();

227

228 assert(Ptr && "Didn't find this decl on its identifier's chain!");

229

230 if (isDeclPtr(Ptr)) {

231 assert(D == Ptr && "Didn't find this decl on its identifier's chain!");

232 Name.setFETokenInfo(nullptr);

233 return;

234 }

235

236 return toIdDeclInfo(Ptr)->RemoveDecl(D);

237}

238

239llvm::iterator_rangeIdentifierResolver::iterator

242}

243

246 readingIdentifier(*II);

247

248 void *Ptr = Name.getFETokenInfo();

249 if (!Ptr) return end();

250

251 if (isDeclPtr(Ptr))

253

254 IdDeclInfo *IDI = toIdDeclInfo(Ptr);

255

256 IdDeclInfo::DeclsTy::iterator I = IDI->decls_end();

257 if (I != IDI->decls_begin())

259

260 return end();

261}

262

263namespace {

264

265enum DeclMatchKind {

266 DMK_Different,

267 DMK_Replace,

268 DMK_Ignore

269};

270

271}

272

273

274

275

277

278 if (Existing == New)

279 return DMK_Ignore;

280

281

283 return DMK_Different;

284

285

287

288

290 return DMK_Different;

291

292

294 if (Existing == MostRecent)

295 return DMK_Ignore;

296

297 if (New == MostRecent)

298 return DMK_Replace;

299

300

301

302 for (auto *RD : New->redecls()) {

303 if (RD == Existing)

304 return DMK_Replace;

305

306 if (RD->isCanonicalDecl())

307 break;

308 }

309

310 return DMK_Ignore;

311 }

312

313 return DMK_Different;

314}

315

318 readingIdentifier(*II);

319

320 void *Ptr = Name.getFETokenInfo();

321

322 if (!Ptr) {

323 Name.setFETokenInfo(D);

324 return true;

325 }

326

327 IdDeclInfo *IDI;

328

329 if (isDeclPtr(Ptr)) {

331

333 case DMK_Different:

334 break;

335

336 case DMK_Ignore:

337 return false;

338

339 case DMK_Replace:

340 Name.setFETokenInfo(D);

341 return true;

342 }

343

344 Name.setFETokenInfo(nullptr);

345 IDI = &(*IdDeclInfos)[Name];

346

347

348

350 IDI->AddDecl(D);

351 IDI->AddDecl(PrevD);

352 } else {

353 IDI->AddDecl(PrevD);

354 IDI->AddDecl(D);

355 }

356 return true;

357 }

358

359 IDI = toIdDeclInfo(Ptr);

360

361

362

363 for (IdDeclInfo::DeclsTy::iterator I = IDI->decls_begin(),

364 IEnd = IDI->decls_end();

365 I != IEnd; ++I) {

366

368 case DMK_Different:

369 break;

370

371 case DMK_Ignore:

372 return false;

373

374 case DMK_Replace:

375 *I = D;

376 return true;

377 }

378

379 if (!(*I)->getDeclContext()->getRedeclContext()->isTranslationUnit()) {

380

381

382 IDI->InsertDecl(I, D);

383 return true;

384 }

385 }

386

387

388 IDI->AddDecl(D);

389 return true;

390}

391

392void IdentifierResolver::readingIdentifier(IdentifierInfo &II) {

395}

396

397void IdentifierResolver::updatingIdentifier(IdentifierInfo &II) {

400

403}

404

405

406

407

408

409

410

411IdentifierResolver::IdDeclInfo &

413 void *Ptr = Name.getFETokenInfo();

414

415 if (Ptr) return *toIdDeclInfo(Ptr);

416

417 if (CurIndex == POOL_SIZE) {

418 CurPool = new IdDeclInfoPool(CurPool);

419 CurIndex = 0;

420 }

421 IdDeclInfo *IDI = &CurPool->Pool[CurIndex];

422 Name.setFETokenInfo(reinterpret_cast<void*>(

423 reinterpret_cast<uintptr_t>(IDI) | 0x1)

424 );

425 ++CurIndex;

426 return *IDI;

427}

428

431 void *InfoPtr = D->getDeclName().getFETokenInfo();

432 assert(!isDeclPtr(InfoPtr) && "Decl with wrong id ?");

433 IdDeclInfo *Info = toIdDeclInfo(InfoPtr);

434

436 if (I != Info->decls_begin())

438 else

440}

static DeclMatchKind compareDeclarations(NamedDecl *Existing, NamedDecl *New)

Compare two declarations to see whether they are different or, if they are the same,...

Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.

Defines the clang::LangOptions interface.

Defines the clang::Preprocessor interface.

IdDeclInfoMap - Associates IdDeclInfos with declaration names.

IdDeclInfoMap(const IdDeclInfoMap &)=delete

IdDeclInfoMap & operator=(const IdDeclInfoMap &)=delete

IdDeclInfo & operator[](DeclarationName Name)

Returns the IdDeclInfo associated to the DeclarationName.

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

bool isTranslationUnit() const

DeclContext * getRedeclContext()

getRedeclContext - Retrieve the context in which an entity conflicts with other entities of the same ...

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

bool isFromASTFile() const

Determine whether this declaration came from an AST file (such as a precompiled header or module) rat...

redecl_range redecls() const

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

DeclContext * getDeclContext()

virtual Decl * getCanonicalDecl()

Retrieves the "canonical" declaration of the given declaration.

The name of a declaration.

virtual void updateOutOfDateIdentifier(const IdentifierInfo &II)=0

Update an out-of-date identifier.

One of these records is kept for each identifier that is lexed.

bool isFromAST() const

Return true if the identifier in its current state was loaded from an AST file.

void setFETokenInfoChangedSinceDeserialization()

Note that the frontend token information for this identifier has changed since it was loaded from an ...

bool isOutOfDate() const

Determine whether the information for this identifier is out of date with respect to the external sou...

iterator - Iterate over the decls of a specified declaration name.

IdDeclInfo::DeclsTy::iterator BaseIter

BaseIter getIterator() const

iterator begin(DeclarationName Name)

Returns an iterator over decls with the name 'Name'.

void RemoveDecl(NamedDecl *D)

RemoveDecl - Unlink the decl from its shadowed decl chain.

IdentifierResolver(Preprocessor &PP)

void InsertDeclAfter(iterator Pos, NamedDecl *D)

Insert the given declaration after the given iterator position.

bool tryAddTopLevelDecl(NamedDecl *D, DeclarationName Name)

Try to add the given declaration to the top level scope, if it (or a redeclaration of it) hasn't alre...

iterator end()

Returns the end iterator.

void AddDecl(NamedDecl *D)

AddDecl - Link the decl to its shadowed decl chain.

llvm::iterator_range< iterator > decls(DeclarationName Name)

Returns a range of decls with the name 'Name'.

bool isDeclInScope(Decl *D, DeclContext *Ctx, Scope *S=nullptr, bool AllowInlineNamespace=false) const

isDeclInScope - If 'Ctx' is a function/method, isDeclInScope returns true if 'D' is in Scope 'S',...

This represents a decl that may have a name.

NamedDecl * getMostRecentDecl()

Engages in a tight little dance with the lexer to efficiently preprocess tokens.

ExternalPreprocessorSource * getExternalSource() const

Scope - A scope is a transient data structure that is used while parsing the program.

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

__UINTPTR_TYPE__ uintptr_t

An unsigned integer type with the property that any valid pointer to void can be converted to this ty...