/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/tools/libclang/CXIndexDataConsumer.h
Line | Count | Source (jump to first uncovered line) |
1 | | //===- CXIndexDataConsumer.h - Index data consumer for libclang--*- C++ -*-===// |
2 | | // |
3 | | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | | // See https://llvm.org/LICENSE.txt for license information. |
5 | | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | | // |
7 | | //===----------------------------------------------------------------------===// |
8 | | |
9 | | #ifndef LLVM_CLANG_TOOLS_LIBCLANG_CXINDEXDATACONSUMER_H |
10 | | #define LLVM_CLANG_TOOLS_LIBCLANG_CXINDEXDATACONSUMER_H |
11 | | |
12 | | #include "CXCursor.h" |
13 | | #include "Index_Internal.h" |
14 | | #include "clang/Index/IndexDataConsumer.h" |
15 | | #include "clang/AST/DeclGroup.h" |
16 | | #include "clang/AST/DeclObjC.h" |
17 | | #include "llvm/ADT/DenseSet.h" |
18 | | |
19 | | namespace clang { |
20 | | class FileEntry; |
21 | | class MSPropertyDecl; |
22 | | class ObjCPropertyDecl; |
23 | | class ClassTemplateDecl; |
24 | | class FunctionTemplateDecl; |
25 | | class TypeAliasTemplateDecl; |
26 | | class ClassTemplateSpecializationDecl; |
27 | | |
28 | | namespace cxindex { |
29 | | class CXIndexDataConsumer; |
30 | | class AttrListInfo; |
31 | | |
32 | | class ScratchAlloc { |
33 | | CXIndexDataConsumer &IdxCtx; |
34 | | |
35 | | public: |
36 | | explicit ScratchAlloc(CXIndexDataConsumer &indexCtx); |
37 | | ScratchAlloc(const ScratchAlloc &SA); |
38 | | |
39 | | ~ScratchAlloc(); |
40 | | |
41 | | const char *toCStr(StringRef Str); |
42 | | const char *copyCStr(StringRef Str); |
43 | | |
44 | | template <typename T> |
45 | | T *allocate(); |
46 | | }; |
47 | | |
48 | | struct EntityInfo : public CXIdxEntityInfo { |
49 | | const NamedDecl *Dcl; |
50 | | CXIndexDataConsumer *IndexCtx; |
51 | | IntrusiveRefCntPtr<AttrListInfo> AttrList; |
52 | | |
53 | 4.30k | EntityInfo() { |
54 | 4.30k | name = USR = nullptr; |
55 | 4.30k | attributes = nullptr; |
56 | 4.30k | numAttributes = 0; |
57 | 4.30k | } |
58 | | }; |
59 | | |
60 | | struct ContainerInfo : public CXIdxContainerInfo { |
61 | | const DeclContext *DC; |
62 | | CXIndexDataConsumer *IndexCtx; |
63 | | }; |
64 | | |
65 | | struct DeclInfo : public CXIdxDeclInfo { |
66 | | enum DInfoKind { |
67 | | Info_Decl, |
68 | | |
69 | | Info_ObjCContainer, |
70 | | Info_ObjCInterface, |
71 | | Info_ObjCProtocol, |
72 | | Info_ObjCCategory, |
73 | | |
74 | | Info_ObjCProperty, |
75 | | |
76 | | Info_CXXClass |
77 | | }; |
78 | | |
79 | | DInfoKind Kind; |
80 | | |
81 | | EntityInfo EntInfo; |
82 | | ContainerInfo SemanticContainer; |
83 | | ContainerInfo LexicalContainer; |
84 | | ContainerInfo DeclAsContainer; |
85 | | |
86 | | DeclInfo(bool isRedeclaration, bool isDefinition, bool isContainer) |
87 | 354 | : Kind(Info_Decl) { |
88 | 354 | this->isRedeclaration = isRedeclaration; |
89 | 354 | this->isDefinition = isDefinition; |
90 | 354 | this->isContainer = isContainer; |
91 | 354 | attributes = nullptr; |
92 | 354 | numAttributes = 0; |
93 | 354 | declAsContainer = semanticContainer = lexicalContainer = nullptr; |
94 | 354 | flags = 0; |
95 | 354 | } |
96 | | DeclInfo(DInfoKind K, |
97 | | bool isRedeclaration, bool isDefinition, bool isContainer) |
98 | 89 | : Kind(K) { |
99 | 89 | this->isRedeclaration = isRedeclaration; |
100 | 89 | this->isDefinition = isDefinition; |
101 | 89 | this->isContainer = isContainer; |
102 | 89 | attributes = nullptr; |
103 | 89 | numAttributes = 0; |
104 | 89 | declAsContainer = semanticContainer = lexicalContainer = nullptr; |
105 | 89 | flags = 0; |
106 | 89 | } |
107 | | }; |
108 | | |
109 | | struct ObjCContainerDeclInfo : public DeclInfo { |
110 | | CXIdxObjCContainerDeclInfo ObjCContDeclInfo; |
111 | | |
112 | | ObjCContainerDeclInfo(bool isForwardRef, |
113 | | bool isRedeclaration, |
114 | | bool isImplementation) |
115 | 10 | : DeclInfo(Info_ObjCContainer, isRedeclaration, |
116 | 10 | /*isDefinition=*/!isForwardRef, /*isContainer=*/!isForwardRef) { |
117 | 10 | init(isForwardRef, isImplementation); |
118 | 10 | } |
119 | | ObjCContainerDeclInfo(DInfoKind K, |
120 | | bool isForwardRef, |
121 | | bool isRedeclaration, |
122 | | bool isImplementation) |
123 | 30 | : DeclInfo(K, isRedeclaration, /*isDefinition=*/!isForwardRef, |
124 | 30 | /*isContainer=*/!isForwardRef) { |
125 | 30 | init(isForwardRef, isImplementation); |
126 | 30 | } |
127 | | |
128 | 40 | static bool classof(const DeclInfo *D) { |
129 | 40 | return Info_ObjCContainer <= D->Kind && D->Kind <= Info_ObjCCategory; |
130 | 40 | } |
131 | | |
132 | | private: |
133 | 40 | void init(bool isForwardRef, bool isImplementation) { |
134 | 40 | if (isForwardRef) |
135 | 6 | ObjCContDeclInfo.kind = CXIdxObjCContainer_ForwardRef; |
136 | 34 | else if (isImplementation) |
137 | 4 | ObjCContDeclInfo.kind = CXIdxObjCContainer_Implementation; |
138 | 30 | else |
139 | 30 | ObjCContDeclInfo.kind = CXIdxObjCContainer_Interface; |
140 | 40 | } |
141 | | }; |
142 | | |
143 | | struct ObjCInterfaceDeclInfo : public ObjCContainerDeclInfo { |
144 | | CXIdxObjCInterfaceDeclInfo ObjCInterDeclInfo; |
145 | | CXIdxObjCProtocolRefListInfo ObjCProtoListInfo; |
146 | | |
147 | | ObjCInterfaceDeclInfo(const ObjCInterfaceDecl *D) |
148 | 21 | : ObjCContainerDeclInfo(Info_ObjCInterface, |
149 | 21 | /*isForwardRef=*/false, |
150 | 21 | /*isRedeclaration=*/D->getPreviousDecl() != nullptr, |
151 | 21 | /*isImplementation=*/false) { } |
152 | | |
153 | 886 | static bool classof(const DeclInfo *D) { |
154 | 886 | return D->Kind == Info_ObjCInterface; |
155 | 886 | } |
156 | | }; |
157 | | |
158 | | struct ObjCProtocolDeclInfo : public ObjCContainerDeclInfo { |
159 | | CXIdxObjCProtocolRefListInfo ObjCProtoRefListInfo; |
160 | | |
161 | | ObjCProtocolDeclInfo(const ObjCProtocolDecl *D) |
162 | 4 | : ObjCContainerDeclInfo(Info_ObjCProtocol, |
163 | 4 | /*isForwardRef=*/false, |
164 | 4 | /*isRedeclaration=*/D->getPreviousDecl(), |
165 | 4 | /*isImplementation=*/false) { } |
166 | | |
167 | 422 | static bool classof(const DeclInfo *D) { |
168 | 422 | return D->Kind == Info_ObjCProtocol; |
169 | 422 | } |
170 | | }; |
171 | | |
172 | | struct ObjCCategoryDeclInfo : public ObjCContainerDeclInfo { |
173 | | CXIdxObjCCategoryDeclInfo ObjCCatDeclInfo; |
174 | | CXIdxObjCProtocolRefListInfo ObjCProtoListInfo; |
175 | | |
176 | | explicit ObjCCategoryDeclInfo(bool isImplementation) |
177 | 5 | : ObjCContainerDeclInfo(Info_ObjCCategory, |
178 | 5 | /*isForwardRef=*/false, |
179 | 5 | /*isRedeclaration=*/isImplementation, |
180 | 5 | /*isImplementation=*/isImplementation) { } |
181 | | |
182 | 861 | static bool classof(const DeclInfo *D) { |
183 | 861 | return D->Kind == Info_ObjCCategory; |
184 | 861 | } |
185 | | }; |
186 | | |
187 | | struct ObjCPropertyDeclInfo : public DeclInfo { |
188 | | CXIdxObjCPropertyDeclInfo ObjCPropDeclInfo; |
189 | | |
190 | | ObjCPropertyDeclInfo() |
191 | 8 | : DeclInfo(Info_ObjCProperty, |
192 | 8 | /*isRedeclaration=*/false, /*isDefinition=*/false, |
193 | 8 | /*isContainer=*/false) { } |
194 | | |
195 | 443 | static bool classof(const DeclInfo *D) { |
196 | 443 | return D->Kind == Info_ObjCProperty; |
197 | 443 | } |
198 | | }; |
199 | | |
200 | | struct CXXClassDeclInfo : public DeclInfo { |
201 | | CXIdxCXXClassDeclInfo CXXClassInfo; |
202 | | |
203 | | CXXClassDeclInfo(bool isRedeclaration, bool isDefinition) |
204 | 41 | : DeclInfo(Info_CXXClass, isRedeclaration, isDefinition, isDefinition) { } |
205 | | |
206 | 443 | static bool classof(const DeclInfo *D) { |
207 | 443 | return D->Kind == Info_CXXClass; |
208 | 443 | } |
209 | | }; |
210 | | |
211 | | struct AttrInfo : public CXIdxAttrInfo { |
212 | | const Attr *A; |
213 | | |
214 | 87 | AttrInfo(CXIdxAttrKind Kind, CXCursor C, CXIdxLoc Loc, const Attr *A) { |
215 | 87 | kind = Kind; |
216 | 87 | cursor = C; |
217 | 87 | loc = Loc; |
218 | 87 | this->A = A; |
219 | 87 | } |
220 | | }; |
221 | | |
222 | | struct IBOutletCollectionInfo : public AttrInfo { |
223 | | EntityInfo ClassInfo; |
224 | | CXIdxIBOutletCollectionAttrInfo IBCollInfo; |
225 | | |
226 | | IBOutletCollectionInfo(CXCursor C, CXIdxLoc Loc, const Attr *A) : |
227 | 3 | AttrInfo(CXIdxAttr_IBOutletCollection, C, Loc, A) { |
228 | 3 | assert(C.kind == CXCursor_IBOutletCollectionAttr); |
229 | 3 | IBCollInfo.objcClass = nullptr; |
230 | 3 | } |
231 | | |
232 | | IBOutletCollectionInfo(const IBOutletCollectionInfo &other); |
233 | | |
234 | 0 | static bool classof(const AttrInfo *A) { |
235 | 0 | return A->kind == CXIdxAttr_IBOutletCollection; |
236 | 0 | } |
237 | | }; |
238 | | |
239 | | class AttrListInfo { |
240 | | ScratchAlloc SA; |
241 | | |
242 | | SmallVector<AttrInfo, 2> Attrs; |
243 | | SmallVector<IBOutletCollectionInfo, 2> IBCollAttrs; |
244 | | SmallVector<CXIdxAttrInfo *, 2> CXAttrs; |
245 | | unsigned ref_cnt; |
246 | | |
247 | | AttrListInfo(const AttrListInfo &) = delete; |
248 | | void operator=(const AttrListInfo &) = delete; |
249 | | public: |
250 | | AttrListInfo(const Decl *D, CXIndexDataConsumer &IdxCtx); |
251 | | |
252 | | static IntrusiveRefCntPtr<AttrListInfo> create(const Decl *D, |
253 | | CXIndexDataConsumer &IdxCtx); |
254 | | |
255 | 63 | const CXIdxAttrInfo *const *getAttrs() const { |
256 | 63 | if (CXAttrs.empty()) |
257 | 0 | return nullptr; |
258 | 63 | return CXAttrs.data(); |
259 | 63 | } |
260 | 63 | unsigned getNumAttrs() const { return (unsigned)CXAttrs.size(); } |
261 | | |
262 | | /// Retain/Release only useful when we allocate a AttrListInfo from the |
263 | | /// BumpPtrAllocator, and not from the stack; so that we keep a pointer |
264 | | // in the EntityInfo |
265 | 63 | void Retain() { ++ref_cnt; } |
266 | 63 | void Release() { |
267 | 63 | assert (ref_cnt > 0 && "Reference count is already zero."); |
268 | 63 | if (--ref_cnt == 0) { |
269 | | // Memory is allocated from a BumpPtrAllocator, no need to delete it. |
270 | 63 | this->~AttrListInfo(); |
271 | 63 | } |
272 | 63 | } |
273 | | }; |
274 | | |
275 | | class CXIndexDataConsumer : public index::IndexDataConsumer { |
276 | | ASTContext *Ctx; |
277 | | CXClientData ClientData; |
278 | | IndexerCallbacks &CB; |
279 | | unsigned IndexOptions; |
280 | | CXTranslationUnit CXTU; |
281 | | |
282 | | typedef llvm::DenseMap<const FileEntry *, CXIdxClientFile> FileMapTy; |
283 | | typedef llvm::DenseMap<const DeclContext *, CXIdxClientContainer> |
284 | | ContainerMapTy; |
285 | | typedef llvm::DenseMap<const Decl *, CXIdxClientEntity> EntityMapTy; |
286 | | |
287 | | FileMapTy FileMap; |
288 | | ContainerMapTy ContainerMap; |
289 | | EntityMapTy EntityMap; |
290 | | |
291 | | typedef std::pair<const FileEntry *, const Decl *> RefFileOccurrence; |
292 | | llvm::DenseSet<RefFileOccurrence> RefFileOccurrences; |
293 | | |
294 | | llvm::BumpPtrAllocator StrScratch; |
295 | | unsigned StrAdapterCount; |
296 | | friend class ScratchAlloc; |
297 | | |
298 | | struct ObjCProtocolListInfo { |
299 | | SmallVector<CXIdxObjCProtocolRefInfo, 4> ProtInfos; |
300 | | SmallVector<EntityInfo, 4> ProtEntities; |
301 | | SmallVector<CXIdxObjCProtocolRefInfo *, 4> Prots; |
302 | | |
303 | 30 | CXIdxObjCProtocolRefListInfo getListInfo() const { |
304 | 30 | CXIdxObjCProtocolRefListInfo Info = { Prots.data(), |
305 | 30 | (unsigned)Prots.size() }; |
306 | 30 | return Info; |
307 | 30 | } |
308 | | |
309 | | ObjCProtocolListInfo(const ObjCProtocolList &ProtList, |
310 | | CXIndexDataConsumer &IdxCtx, |
311 | | ScratchAlloc &SA); |
312 | | }; |
313 | | |
314 | | struct CXXBasesListInfo { |
315 | | SmallVector<CXIdxBaseClassInfo, 4> BaseInfos; |
316 | | SmallVector<EntityInfo, 4> BaseEntities; |
317 | | SmallVector<CXIdxBaseClassInfo *, 4> CXBases; |
318 | | |
319 | 43 | const CXIdxBaseClassInfo *const *getBases() const { |
320 | 43 | return CXBases.data(); |
321 | 43 | } |
322 | 44 | unsigned getNumBases() const { return (unsigned)CXBases.size(); } |
323 | | |
324 | | CXXBasesListInfo(const CXXRecordDecl *D, |
325 | | CXIndexDataConsumer &IdxCtx, ScratchAlloc &SA); |
326 | | |
327 | | private: |
328 | | SourceLocation getBaseLoc(const CXXBaseSpecifier &Base) const; |
329 | | }; |
330 | | |
331 | | friend class AttrListInfo; |
332 | | |
333 | | public: |
334 | | CXIndexDataConsumer(CXClientData clientData, IndexerCallbacks &indexCallbacks, |
335 | | unsigned indexOptions, CXTranslationUnit cxTU) |
336 | 54 | : Ctx(nullptr), ClientData(clientData), CB(indexCallbacks), |
337 | 54 | IndexOptions(indexOptions), CXTU(cxTU), StrAdapterCount(0) {} |
338 | | |
339 | 2.36k | ASTContext &getASTContext() const { return *Ctx; } |
340 | 1.88k | CXTranslationUnit getCXTU() const { return CXTU; } |
341 | | |
342 | | void setASTContext(ASTContext &ctx); |
343 | | void setPreprocessor(std::shared_ptr<Preprocessor> PP) override; |
344 | | |
345 | 2.41k | bool shouldSuppressRefs() const { |
346 | 2.41k | return IndexOptions & CXIndexOpt_SuppressRedundantRefs; |
347 | 2.41k | } |
348 | | |
349 | 2.35k | bool shouldIndexFunctionLocalSymbols() const { |
350 | 2.35k | return IndexOptions & CXIndexOpt_IndexFunctionLocalSymbols; |
351 | 2.35k | } |
352 | | |
353 | 135 | bool shouldIndexImplicitTemplateInsts() const { |
354 | 135 | return IndexOptions & CXIndexOpt_IndexImplicitTemplateInstantiations; |
355 | 135 | } |
356 | | |
357 | | static bool isFunctionLocalDecl(const Decl *D); |
358 | | |
359 | | bool shouldAbort(); |
360 | | |
361 | 63 | bool hasDiagnosticCallback() const { return CB.diagnostic; } |
362 | | |
363 | | void enteredMainFile(OptionalFileEntryRef File); |
364 | | |
365 | | void ppIncludedFile(SourceLocation hashLoc, StringRef filename, |
366 | | OptionalFileEntryRef File, bool isImport, bool isAngled, |
367 | | bool isModuleImport); |
368 | | |
369 | | void importedModule(const ImportDecl *ImportD); |
370 | | void importedPCH(FileEntryRef File); |
371 | | |
372 | | void startedTranslationUnit(); |
373 | | |
374 | | void indexDiagnostics(); |
375 | | |
376 | | void handleDiagnosticSet(CXDiagnosticSet CXDiagSet); |
377 | | |
378 | | bool handleFunction(const FunctionDecl *FD); |
379 | | |
380 | | bool handleVar(const VarDecl *D); |
381 | | |
382 | | bool handleField(const FieldDecl *D); |
383 | | |
384 | | bool handleEnumerator(const EnumConstantDecl *D); |
385 | | |
386 | | bool handleTagDecl(const TagDecl *D); |
387 | | |
388 | | bool handleTypedefName(const TypedefNameDecl *D); |
389 | | |
390 | | bool handleObjCInterface(const ObjCInterfaceDecl *D); |
391 | | bool handleObjCImplementation(const ObjCImplementationDecl *D); |
392 | | |
393 | | bool handleObjCProtocol(const ObjCProtocolDecl *D); |
394 | | |
395 | | bool handleObjCCategory(const ObjCCategoryDecl *D); |
396 | | bool handleObjCCategoryImpl(const ObjCCategoryImplDecl *D); |
397 | | |
398 | | bool handleObjCMethod(const ObjCMethodDecl *D, SourceLocation Loc); |
399 | | |
400 | | bool handleSynthesizedObjCProperty(const ObjCPropertyImplDecl *D); |
401 | | bool handleSynthesizedObjCMethod(const ObjCMethodDecl *D, SourceLocation Loc, |
402 | | const DeclContext *LexicalDC); |
403 | | |
404 | | bool handleObjCProperty(const ObjCPropertyDecl *D); |
405 | | |
406 | | bool handleNamespace(const NamespaceDecl *D); |
407 | | |
408 | | bool handleClassTemplate(const ClassTemplateDecl *D); |
409 | | bool handleFunctionTemplate(const FunctionTemplateDecl *D); |
410 | | bool handleTypeAliasTemplate(const TypeAliasTemplateDecl *D); |
411 | | |
412 | | bool handleConcept(const ConceptDecl *D); |
413 | | |
414 | | bool handleReference(const NamedDecl *D, SourceLocation Loc, CXCursor Cursor, |
415 | | const NamedDecl *Parent, |
416 | | const DeclContext *DC, |
417 | | const Expr *E = nullptr, |
418 | | CXIdxEntityRefKind Kind = CXIdxEntityRef_Direct, |
419 | | CXSymbolRole Role = CXSymbolRole_None); |
420 | | |
421 | | bool isNotFromSourceFile(SourceLocation Loc) const; |
422 | | |
423 | | void translateLoc(SourceLocation Loc, CXIdxClientFile *indexFile, CXFile *file, |
424 | | unsigned *line, unsigned *column, unsigned *offset); |
425 | | |
426 | | CXIdxClientContainer getClientContainerForDC(const DeclContext *DC) const; |
427 | | void addContainerInMap(const DeclContext *DC, CXIdxClientContainer container); |
428 | | |
429 | | CXIdxClientEntity getClientEntity(const Decl *D) const; |
430 | | void setClientEntity(const Decl *D, CXIdxClientEntity client); |
431 | | |
432 | | static bool isTemplateImplicitInstantiation(const Decl *D); |
433 | | |
434 | | private: |
435 | | bool handleDeclOccurrence(const Decl *D, index::SymbolRoleSet Roles, |
436 | | ArrayRef<index::SymbolRelation> Relations, |
437 | | SourceLocation Loc, ASTNodeInfo ASTNode) override; |
438 | | |
439 | | bool handleModuleOccurrence(const ImportDecl *ImportD, const Module *Mod, |
440 | | index::SymbolRoleSet Roles, |
441 | | SourceLocation Loc) override; |
442 | | |
443 | | void finish() override; |
444 | | |
445 | | bool handleDecl(const NamedDecl *D, |
446 | | SourceLocation Loc, CXCursor Cursor, |
447 | | DeclInfo &DInfo, |
448 | | const DeclContext *LexicalDC = nullptr, |
449 | | const DeclContext *SemaDC = nullptr); |
450 | | |
451 | | bool handleObjCContainer(const ObjCContainerDecl *D, |
452 | | SourceLocation Loc, CXCursor Cursor, |
453 | | ObjCContainerDeclInfo &ContDInfo); |
454 | | |
455 | | bool handleCXXRecordDecl(const CXXRecordDecl *RD, const NamedDecl *OrigD); |
456 | | |
457 | | bool markEntityOccurrenceInFile(const NamedDecl *D, SourceLocation Loc); |
458 | | |
459 | | const NamedDecl *getEntityDecl(const NamedDecl *D) const; |
460 | | |
461 | | const DeclContext *getEntityContainer(const Decl *D) const; |
462 | | |
463 | | CXIdxClientFile getIndexFile(const FileEntry *File); |
464 | | |
465 | | CXIdxLoc getIndexLoc(SourceLocation Loc) const; |
466 | | |
467 | | void getEntityInfo(const NamedDecl *D, |
468 | | EntityInfo &EntityInfo, |
469 | | ScratchAlloc &SA); |
470 | | |
471 | | void getContainerInfo(const DeclContext *DC, ContainerInfo &ContInfo); |
472 | | |
473 | 7.21k | CXCursor getCursor(const Decl *D) { |
474 | 7.21k | return cxcursor::MakeCXCursor(D, CXTU); |
475 | 7.21k | } |
476 | | |
477 | | CXCursor getRefCursor(const NamedDecl *D, SourceLocation Loc); |
478 | | |
479 | | static bool shouldIgnoreIfImplicit(const Decl *D); |
480 | | }; |
481 | | |
482 | 2.59k | inline ScratchAlloc::ScratchAlloc(CXIndexDataConsumer &idxCtx) : IdxCtx(idxCtx) { |
483 | 2.59k | ++IdxCtx.StrAdapterCount; |
484 | 2.59k | } |
485 | | inline ScratchAlloc::ScratchAlloc(const ScratchAlloc &SA) : IdxCtx(SA.IdxCtx) { |
486 | | ++IdxCtx.StrAdapterCount; |
487 | | } |
488 | | |
489 | 2.59k | inline ScratchAlloc::~ScratchAlloc() { |
490 | 2.59k | --IdxCtx.StrAdapterCount; |
491 | 2.59k | if (IdxCtx.StrAdapterCount == 0) |
492 | 2.39k | IdxCtx.StrScratch.Reset(); |
493 | 2.59k | } |
494 | | |
495 | | template <typename T> |
496 | 63 | inline T *ScratchAlloc::allocate() { |
497 | 63 | return IdxCtx.StrScratch.Allocate<T>(); |
498 | 63 | } |
499 | | |
500 | | }} // end clang::cxindex |
501 | | |
502 | | #endif |