/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/include/clang/AST/ASTImporter.h
Line | Count | Source (jump to first uncovered line) |
1 | | //===- ASTImporter.h - Importing ASTs from other Contexts -------*- 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 | | // This file defines the ASTImporter class which imports AST nodes from one |
10 | | // context into another context. |
11 | | // |
12 | | //===----------------------------------------------------------------------===// |
13 | | |
14 | | #ifndef LLVM_CLANG_AST_ASTIMPORTER_H |
15 | | #define LLVM_CLANG_AST_ASTIMPORTER_H |
16 | | |
17 | | #include "clang/AST/ASTImportError.h" |
18 | | #include "clang/AST/DeclBase.h" |
19 | | #include "clang/AST/DeclarationName.h" |
20 | | #include "clang/AST/ExprCXX.h" |
21 | | #include "clang/AST/NestedNameSpecifier.h" |
22 | | #include "clang/AST/TemplateName.h" |
23 | | #include "clang/AST/Type.h" |
24 | | #include "clang/Basic/Diagnostic.h" |
25 | | #include "clang/Basic/IdentifierTable.h" |
26 | | #include "clang/Basic/LLVM.h" |
27 | | #include "clang/Basic/SourceLocation.h" |
28 | | #include "llvm/ADT/DenseMap.h" |
29 | | #include "llvm/ADT/DenseSet.h" |
30 | | #include "llvm/ADT/Optional.h" |
31 | | #include "llvm/ADT/SmallVector.h" |
32 | | #include <utility> |
33 | | |
34 | | namespace clang { |
35 | | |
36 | | class ASTContext; |
37 | | class ASTImporterSharedState; |
38 | | class Attr; |
39 | | class CXXBaseSpecifier; |
40 | | class CXXCtorInitializer; |
41 | | class Decl; |
42 | | class DeclContext; |
43 | | class Expr; |
44 | | class FileManager; |
45 | | class NamedDecl; |
46 | | class Stmt; |
47 | | class TagDecl; |
48 | | class TranslationUnitDecl; |
49 | | class TypeSourceInfo; |
50 | | |
51 | | // \brief Returns with a list of declarations started from the canonical decl |
52 | | // then followed by subsequent decls in the translation unit. |
53 | | // This gives a canonical list for each entry in the redecl chain. |
54 | | // `Decl::redecls()` gives a list of decls which always start from the |
55 | | // previous decl and the next item is actually the previous item in the order |
56 | | // of source locations. Thus, `Decl::redecls()` gives different lists for |
57 | | // the different entries in a given redecl chain. |
58 | | llvm::SmallVector<Decl*, 2> getCanonicalForwardRedeclChain(Decl* D); |
59 | | |
60 | | /// Imports selected nodes from one AST context into another context, |
61 | | /// merging AST nodes where appropriate. |
62 | | class ASTImporter { |
63 | | friend class ASTNodeImporter; |
64 | | public: |
65 | | using NonEquivalentDeclSet = llvm::DenseSet<std::pair<Decl *, Decl *>>; |
66 | | using ImportedCXXBaseSpecifierMap = |
67 | | llvm::DenseMap<const CXXBaseSpecifier *, CXXBaseSpecifier *>; |
68 | | |
69 | | enum class ODRHandlingType { Conservative, Liberal }; |
70 | | |
71 | | // An ImportPath is the list of the AST nodes which we visit during an |
72 | | // Import call. |
73 | | // If node `A` depends on node `B` then the path contains an `A`->`B` edge. |
74 | | // From the call stack of the import functions we can read the very same |
75 | | // path. |
76 | | // |
77 | | // Now imagine the following AST, where the `->` represents dependency in |
78 | | // therms of the import. |
79 | | // ``` |
80 | | // A->B->C->D |
81 | | // `->E |
82 | | // ``` |
83 | | // We would like to import A. |
84 | | // The import behaves like a DFS, so we will visit the nodes in this order: |
85 | | // ABCDE. |
86 | | // During the visitation we will have the following ImportPaths: |
87 | | // ``` |
88 | | // A |
89 | | // AB |
90 | | // ABC |
91 | | // ABCD |
92 | | // ABC |
93 | | // AB |
94 | | // ABE |
95 | | // AB |
96 | | // A |
97 | | // ``` |
98 | | // If during the visit of E there is an error then we set an error for E, |
99 | | // then as the call stack shrinks for B, then for A: |
100 | | // ``` |
101 | | // A |
102 | | // AB |
103 | | // ABC |
104 | | // ABCD |
105 | | // ABC |
106 | | // AB |
107 | | // ABE // Error! Set an error to E |
108 | | // AB // Set an error to B |
109 | | // A // Set an error to A |
110 | | // ``` |
111 | | // However, during the import we could import C and D without any error and |
112 | | // they are independent from A,B and E. |
113 | | // We must not set up an error for C and D. |
114 | | // So, at the end of the import we have an entry in `ImportDeclErrors` for |
115 | | // A,B,E but not for C,D. |
116 | | // |
117 | | // Now what happens if there is a cycle in the import path? |
118 | | // Let's consider this AST: |
119 | | // ``` |
120 | | // A->B->C->A |
121 | | // `->E |
122 | | // ``` |
123 | | // During the visitation we will have the below ImportPaths and if during |
124 | | // the visit of E there is an error then we will set up an error for E,B,A. |
125 | | // But what's up with C? |
126 | | // ``` |
127 | | // A |
128 | | // AB |
129 | | // ABC |
130 | | // ABCA |
131 | | // ABC |
132 | | // AB |
133 | | // ABE // Error! Set an error to E |
134 | | // AB // Set an error to B |
135 | | // A // Set an error to A |
136 | | // ``` |
137 | | // This time we know that both B and C are dependent on A. |
138 | | // This means we must set up an error for C too. |
139 | | // As the call stack reverses back we get to A and we must set up an error |
140 | | // to all nodes which depend on A (this includes C). |
141 | | // But C is no longer on the import path, it just had been previously. |
142 | | // Such situation can happen only if during the visitation we had a cycle. |
143 | | // If we didn't have any cycle, then the normal way of passing an Error |
144 | | // object through the call stack could handle the situation. |
145 | | // This is why we must track cycles during the import process for each |
146 | | // visited declaration. |
147 | | class ImportPathTy { |
148 | | public: |
149 | | using VecTy = llvm::SmallVector<Decl *, 32>; |
150 | | |
151 | 22.3M | void push(Decl *D) { |
152 | 22.3M | Nodes.push_back(D); |
153 | 22.3M | ++Aux[D]; |
154 | 22.3M | } |
155 | | |
156 | 22.3M | void pop() { |
157 | 22.3M | if (Nodes.empty()) |
158 | 0 | return; |
159 | 22.3M | --Aux[Nodes.back()]; |
160 | 22.3M | Nodes.pop_back(); |
161 | 22.3M | } |
162 | | |
163 | | /// Returns true if the last element can be found earlier in the path. |
164 | 17.2M | bool hasCycleAtBack() const { |
165 | 17.2M | auto Pos = Aux.find(Nodes.back()); |
166 | 17.2M | return Pos != Aux.end() && Pos->second > 1; |
167 | 17.2M | } |
168 | | |
169 | | using Cycle = llvm::iterator_range<VecTy::const_reverse_iterator>; |
170 | 1.04M | Cycle getCycleAtBack() const { |
171 | 1.04M | assert(Nodes.size() >= 2); |
172 | 0 | return Cycle(Nodes.rbegin(), |
173 | 1.04M | std::find(Nodes.rbegin() + 1, Nodes.rend(), Nodes.back()) + |
174 | 1.04M | 1); |
175 | 1.04M | } |
176 | | |
177 | | /// Returns the copy of the cycle. |
178 | 1.04M | VecTy copyCycleAtBack() const { |
179 | 1.04M | auto R = getCycleAtBack(); |
180 | 1.04M | return VecTy(R.begin(), R.end()); |
181 | 1.04M | } |
182 | | |
183 | | private: |
184 | | // All nodes of the path. |
185 | | VecTy Nodes; |
186 | | // Auxiliary container to be able to answer "Do we have a cycle ending |
187 | | // at last element?" as fast as possible. |
188 | | // We count each Decl's occurrence over the path. |
189 | | llvm::SmallDenseMap<Decl *, int, 32> Aux; |
190 | | }; |
191 | | |
192 | | private: |
193 | | std::shared_ptr<ASTImporterSharedState> SharedState = nullptr; |
194 | | |
195 | | /// The path which we go through during the import of a given AST node. |
196 | | ImportPathTy ImportPath; |
197 | | /// Sometimes we have to save some part of an import path, so later we can |
198 | | /// set up properties to the saved nodes. |
199 | | /// We may have several of these import paths associated to one Decl. |
200 | | using SavedImportPathsForOneDecl = |
201 | | llvm::SmallVector<ImportPathTy::VecTy, 32>; |
202 | | using SavedImportPathsTy = |
203 | | llvm::SmallDenseMap<Decl *, SavedImportPathsForOneDecl, 32>; |
204 | | SavedImportPathsTy SavedImportPaths; |
205 | | |
206 | | /// The contexts we're importing to and from. |
207 | | ASTContext &ToContext, &FromContext; |
208 | | |
209 | | /// The file managers we're importing to and from. |
210 | | FileManager &ToFileManager, &FromFileManager; |
211 | | |
212 | | /// Whether to perform a minimal import. |
213 | | bool Minimal; |
214 | | |
215 | | ODRHandlingType ODRHandling; |
216 | | |
217 | | /// Whether the last diagnostic came from the "from" context. |
218 | | bool LastDiagFromFrom = false; |
219 | | |
220 | | /// Mapping from the already-imported types in the "from" context |
221 | | /// to the corresponding types in the "to" context. |
222 | | llvm::DenseMap<const Type *, const Type *> ImportedTypes; |
223 | | |
224 | | /// Mapping from the already-imported declarations in the "from" |
225 | | /// context to the corresponding declarations in the "to" context. |
226 | | llvm::DenseMap<Decl *, Decl *> ImportedDecls; |
227 | | |
228 | | /// Mapping from the already-imported declarations in the "from" |
229 | | /// context to the error status of the import of that declaration. |
230 | | /// This map contains only the declarations that were not correctly |
231 | | /// imported. The same declaration may or may not be included in |
232 | | /// ImportedDecls. This map is updated continuously during imports and never |
233 | | /// cleared (like ImportedDecls). |
234 | | llvm::DenseMap<Decl *, ASTImportError> ImportDeclErrors; |
235 | | |
236 | | /// Mapping from the already-imported declarations in the "to" |
237 | | /// context to the corresponding declarations in the "from" context. |
238 | | llvm::DenseMap<Decl *, Decl *> ImportedFromDecls; |
239 | | |
240 | | /// Mapping from the already-imported statements in the "from" |
241 | | /// context to the corresponding statements in the "to" context. |
242 | | llvm::DenseMap<Stmt *, Stmt *> ImportedStmts; |
243 | | |
244 | | /// Mapping from the already-imported FileIDs in the "from" source |
245 | | /// manager to the corresponding FileIDs in the "to" source manager. |
246 | | llvm::DenseMap<FileID, FileID> ImportedFileIDs; |
247 | | |
248 | | /// Mapping from the already-imported CXXBasesSpecifier in |
249 | | /// the "from" source manager to the corresponding CXXBasesSpecifier |
250 | | /// in the "to" source manager. |
251 | | ImportedCXXBaseSpecifierMap ImportedCXXBaseSpecifiers; |
252 | | |
253 | | /// Declaration (from, to) pairs that are known not to be equivalent |
254 | | /// (which we have already complained about). |
255 | | NonEquivalentDeclSet NonEquivalentDecls; |
256 | | |
257 | | using FoundDeclsTy = SmallVector<NamedDecl *, 2>; |
258 | | FoundDeclsTy findDeclsInToCtx(DeclContext *DC, DeclarationName Name); |
259 | | |
260 | | void AddToLookupTable(Decl *ToD); |
261 | | |
262 | | protected: |
263 | | /// Can be overwritten by subclasses to implement their own import logic. |
264 | | /// The overwritten method should call this method if it didn't import the |
265 | | /// decl on its own. |
266 | | virtual Expected<Decl *> ImportImpl(Decl *From); |
267 | | |
268 | | /// Used only in unittests to verify the behaviour of the error handling. |
269 | 4 | virtual bool returnWithErrorInTest() { return false; }; |
270 | | |
271 | | public: |
272 | | |
273 | | /// \param ToContext The context we'll be importing into. |
274 | | /// |
275 | | /// \param ToFileManager The file manager we'll be importing into. |
276 | | /// |
277 | | /// \param FromContext The context we'll be importing from. |
278 | | /// |
279 | | /// \param FromFileManager The file manager we'll be importing into. |
280 | | /// |
281 | | /// \param MinimalImport If true, the importer will attempt to import |
282 | | /// as little as it can, e.g., by importing declarations as forward |
283 | | /// declarations that can be completed at a later point. |
284 | | /// |
285 | | /// \param SharedState The importer specific lookup table which may be |
286 | | /// shared amongst several ASTImporter objects. |
287 | | /// If not set then the original C/C++ lookup is used. |
288 | | ASTImporter(ASTContext &ToContext, FileManager &ToFileManager, |
289 | | ASTContext &FromContext, FileManager &FromFileManager, |
290 | | bool MinimalImport, |
291 | | std::shared_ptr<ASTImporterSharedState> SharedState = nullptr); |
292 | | |
293 | | virtual ~ASTImporter(); |
294 | | |
295 | | /// Whether the importer will perform a minimal import, creating |
296 | | /// to-be-completed forward declarations when possible. |
297 | 6.76M | bool isMinimalImport() const { return Minimal; } |
298 | | |
299 | 22.1k | void setODRHandling(ODRHandlingType T) { ODRHandling = T; } |
300 | | |
301 | | /// \brief Import the given object, returns the result. |
302 | | /// |
303 | | /// \param To Import the object into this variable. |
304 | | /// \param From Object to import. |
305 | | /// \return Error information (success or error). |
306 | | template <typename ImportT> |
307 | 14.5M | LLVM_NODISCARD llvm::Error importInto(ImportT &To, const ImportT &From) { |
308 | 14.5M | auto ToOrErr = Import(From); |
309 | 14.5M | if (ToOrErr) |
310 | 14.5M | To = *ToOrErr; |
311 | 14.5M | return ToOrErr.takeError(); |
312 | 14.5M | } llvm::Error clang::ASTImporter::importInto<clang::DeclarationName>(clang::DeclarationName&, clang::DeclarationName const&) Line | Count | Source | 307 | 2.74M | LLVM_NODISCARD llvm::Error importInto(ImportT &To, const ImportT &From) { | 308 | 2.74M | auto ToOrErr = Import(From); | 309 | 2.74M | if (ToOrErr) | 310 | 2.74M | To = *ToOrErr; | 311 | 2.74M | return ToOrErr.takeError(); | 312 | 2.74M | } |
llvm::Error clang::ASTImporter::importInto<clang::Type const*>(clang::Type const*&, clang::Type const* const&) Line | Count | Source | 307 | 81.5k | LLVM_NODISCARD llvm::Error importInto(ImportT &To, const ImportT &From) { | 308 | 81.5k | auto ToOrErr = Import(From); | 309 | 81.5k | if (ToOrErr) | 310 | 81.5k | To = *ToOrErr; | 311 | 81.5k | return ToOrErr.takeError(); | 312 | 81.5k | } |
llvm::Error clang::ASTImporter::importInto<clang::QualType>(clang::QualType&, clang::QualType const&) Line | Count | Source | 307 | 1.30k | LLVM_NODISCARD llvm::Error importInto(ImportT &To, const ImportT &From) { | 308 | 1.30k | auto ToOrErr = Import(From); | 309 | 1.30k | if (ToOrErr) | 310 | 1.30k | To = *ToOrErr; | 311 | 1.30k | return ToOrErr.takeError(); | 312 | 1.30k | } |
llvm::Error clang::ASTImporter::importInto<clang::NestedNameSpecifier*>(clang::NestedNameSpecifier*&, clang::NestedNameSpecifier* const&) Line | Count | Source | 307 | 1.76M | LLVM_NODISCARD llvm::Error importInto(ImportT &To, const ImportT &From) { | 308 | 1.76M | auto ToOrErr = Import(From); | 309 | 1.76M | if (ToOrErr) | 310 | 1.76M | To = *ToOrErr; | 311 | 1.76M | return ToOrErr.takeError(); | 312 | 1.76M | } |
llvm::Error clang::ASTImporter::importInto<clang::SourceLocation>(clang::SourceLocation&, clang::SourceLocation const&) Line | Count | Source | 307 | 10.0M | LLVM_NODISCARD llvm::Error importInto(ImportT &To, const ImportT &From) { | 308 | 10.0M | auto ToOrErr = Import(From); | 309 | 10.0M | if (ToOrErr) | 310 | 10.0M | To = *ToOrErr; | 311 | 10.0M | return ToOrErr.takeError(); | 312 | 10.0M | } |
|
313 | | |
314 | | /// Import cleanup objects owned by ExprWithCleanup. |
315 | | llvm::Expected<ExprWithCleanups::CleanupObject> |
316 | | Import(ExprWithCleanups::CleanupObject From); |
317 | | |
318 | | /// Import the given type from the "from" context into the "to" |
319 | | /// context. |
320 | | /// |
321 | | /// \returns The equivalent type in the "to" context, or the import error. |
322 | | llvm::Expected<const Type *> Import(const Type *FromT); |
323 | | |
324 | | /// Import the given qualified type from the "from" context into the "to" |
325 | | /// context. A null type is imported as a null type (no error). |
326 | | /// |
327 | | /// \returns The equivalent type in the "to" context, or the import error. |
328 | | llvm::Expected<QualType> Import(QualType FromT); |
329 | | |
330 | | /// Import the given type source information from the |
331 | | /// "from" context into the "to" context. |
332 | | /// |
333 | | /// \returns The equivalent type source information in the "to" |
334 | | /// context, or the import error. |
335 | | llvm::Expected<TypeSourceInfo *> Import(TypeSourceInfo *FromTSI); |
336 | | |
337 | | /// Import the given attribute from the "from" context into the |
338 | | /// "to" context. |
339 | | /// |
340 | | /// \returns The equivalent attribute in the "to" context, or the import |
341 | | /// error. |
342 | | llvm::Expected<Attr *> Import(const Attr *FromAttr); |
343 | | |
344 | | /// Import the given declaration from the "from" context into the |
345 | | /// "to" context. |
346 | | /// |
347 | | /// \returns The equivalent declaration in the "to" context, or the import |
348 | | /// error. |
349 | | llvm::Expected<Decl *> Import(Decl *FromD); |
350 | 1.29k | llvm::Expected<const Decl *> Import(const Decl *FromD) { |
351 | 1.29k | return Import(const_cast<Decl *>(FromD)); |
352 | 1.29k | } |
353 | | |
354 | | llvm::Expected<InheritedConstructor> |
355 | | Import(const InheritedConstructor &From); |
356 | | |
357 | | /// Return the copy of the given declaration in the "to" context if |
358 | | /// it has already been imported from the "from" context. Otherwise return |
359 | | /// nullptr. |
360 | | Decl *GetAlreadyImportedOrNull(const Decl *FromD) const; |
361 | | |
362 | | /// Return the translation unit from where the declaration was |
363 | | /// imported. If it does not exist nullptr is returned. |
364 | | TranslationUnitDecl *GetFromTU(Decl *ToD); |
365 | | |
366 | | /// Return the declaration in the "from" context from which the declaration |
367 | | /// in the "to" context was imported. If it was not imported or of the wrong |
368 | | /// type a null value is returned. |
369 | | template <typename DeclT> |
370 | 3 | llvm::Optional<DeclT *> getImportedFromDecl(const DeclT *ToD) const { |
371 | 3 | auto FromI = ImportedFromDecls.find(ToD); |
372 | 3 | if (FromI == ImportedFromDecls.end()) |
373 | 0 | return {}; |
374 | 3 | auto *FromD = dyn_cast<DeclT>(FromI->second); |
375 | 3 | if (!FromD) |
376 | 0 | return {}; |
377 | 3 | return FromD; |
378 | 3 | } |
379 | | |
380 | | /// Import the given declaration context from the "from" |
381 | | /// AST context into the "to" AST context. |
382 | | /// |
383 | | /// \returns the equivalent declaration context in the "to" |
384 | | /// context, or error value. |
385 | | llvm::Expected<DeclContext *> ImportContext(DeclContext *FromDC); |
386 | | |
387 | | /// Import the given expression from the "from" context into the |
388 | | /// "to" context. |
389 | | /// |
390 | | /// \returns The equivalent expression in the "to" context, or the import |
391 | | /// error. |
392 | | llvm::Expected<Expr *> Import(Expr *FromE); |
393 | | |
394 | | /// Import the given statement from the "from" context into the |
395 | | /// "to" context. |
396 | | /// |
397 | | /// \returns The equivalent statement in the "to" context, or the import |
398 | | /// error. |
399 | | llvm::Expected<Stmt *> Import(Stmt *FromS); |
400 | | |
401 | | /// Import the given nested-name-specifier from the "from" |
402 | | /// context into the "to" context. |
403 | | /// |
404 | | /// \returns The equivalent nested-name-specifier in the "to" |
405 | | /// context, or the import error. |
406 | | llvm::Expected<NestedNameSpecifier *> Import(NestedNameSpecifier *FromNNS); |
407 | | |
408 | | /// Import the given nested-name-specifier-loc from the "from" |
409 | | /// context into the "to" context. |
410 | | /// |
411 | | /// \returns The equivalent nested-name-specifier-loc in the "to" |
412 | | /// context, or the import error. |
413 | | llvm::Expected<NestedNameSpecifierLoc> |
414 | | Import(NestedNameSpecifierLoc FromNNS); |
415 | | |
416 | | /// Import the given template name from the "from" context into the |
417 | | /// "to" context, or the import error. |
418 | | llvm::Expected<TemplateName> Import(TemplateName From); |
419 | | |
420 | | /// Import the given source location from the "from" context into |
421 | | /// the "to" context. |
422 | | /// |
423 | | /// \returns The equivalent source location in the "to" context, or the |
424 | | /// import error. |
425 | | llvm::Expected<SourceLocation> Import(SourceLocation FromLoc); |
426 | | |
427 | | /// Import the given source range from the "from" context into |
428 | | /// the "to" context. |
429 | | /// |
430 | | /// \returns The equivalent source range in the "to" context, or the import |
431 | | /// error. |
432 | | llvm::Expected<SourceRange> Import(SourceRange FromRange); |
433 | | |
434 | | /// Import the given declaration name from the "from" |
435 | | /// context into the "to" context. |
436 | | /// |
437 | | /// \returns The equivalent declaration name in the "to" context, or the |
438 | | /// import error. |
439 | | llvm::Expected<DeclarationName> Import(DeclarationName FromName); |
440 | | |
441 | | /// Import the given identifier from the "from" context |
442 | | /// into the "to" context. |
443 | | /// |
444 | | /// \returns The equivalent identifier in the "to" context. Note: It |
445 | | /// returns nullptr only if the FromId was nullptr. |
446 | | IdentifierInfo *Import(const IdentifierInfo *FromId); |
447 | | |
448 | | /// Import the given Objective-C selector from the "from" |
449 | | /// context into the "to" context. |
450 | | /// |
451 | | /// \returns The equivalent selector in the "to" context, or the import |
452 | | /// error. |
453 | | llvm::Expected<Selector> Import(Selector FromSel); |
454 | | |
455 | | /// Import the given file ID from the "from" context into the |
456 | | /// "to" context. |
457 | | /// |
458 | | /// \returns The equivalent file ID in the source manager of the "to" |
459 | | /// context, or the import error. |
460 | | llvm::Expected<FileID> Import(FileID, bool IsBuiltin = false); |
461 | | |
462 | | /// Import the given C++ constructor initializer from the "from" |
463 | | /// context into the "to" context. |
464 | | /// |
465 | | /// \returns The equivalent initializer in the "to" context, or the import |
466 | | /// error. |
467 | | llvm::Expected<CXXCtorInitializer *> Import(CXXCtorInitializer *FromInit); |
468 | | |
469 | | /// Import the given CXXBaseSpecifier from the "from" context into |
470 | | /// the "to" context. |
471 | | /// |
472 | | /// \returns The equivalent CXXBaseSpecifier in the source manager of the |
473 | | /// "to" context, or the import error. |
474 | | llvm::Expected<CXXBaseSpecifier *> Import(const CXXBaseSpecifier *FromSpec); |
475 | | |
476 | | /// Import the given APValue from the "from" context into |
477 | | /// the "to" context. |
478 | | /// |
479 | | /// \return the equivalent APValue in the "to" context or the import |
480 | | /// error. |
481 | | llvm::Expected<APValue> Import(const APValue &FromValue); |
482 | | |
483 | | /// Import the definition of the given declaration, including all of |
484 | | /// the declarations it contains. |
485 | | LLVM_NODISCARD llvm::Error ImportDefinition(Decl *From); |
486 | | |
487 | | /// Cope with a name conflict when importing a declaration into the |
488 | | /// given context. |
489 | | /// |
490 | | /// This routine is invoked whenever there is a name conflict while |
491 | | /// importing a declaration. The returned name will become the name of the |
492 | | /// imported declaration. By default, the returned name is the same as the |
493 | | /// original name, leaving the conflict unresolve such that name lookup |
494 | | /// for this name is likely to find an ambiguity later. |
495 | | /// |
496 | | /// Subclasses may override this routine to resolve the conflict, e.g., by |
497 | | /// renaming the declaration being imported. |
498 | | /// |
499 | | /// \param Name the name of the declaration being imported, which conflicts |
500 | | /// with other declarations. |
501 | | /// |
502 | | /// \param DC the declaration context (in the "to" AST context) in which |
503 | | /// the name is being imported. |
504 | | /// |
505 | | /// \param IDNS the identifier namespace in which the name will be found. |
506 | | /// |
507 | | /// \param Decls the set of declarations with the same name as the |
508 | | /// declaration being imported. |
509 | | /// |
510 | | /// \param NumDecls the number of conflicting declarations in \p Decls. |
511 | | /// |
512 | | /// \returns the name that the newly-imported declaration should have. Or |
513 | | /// an error if we can't handle the name conflict. |
514 | | virtual Expected<DeclarationName> |
515 | | HandleNameConflict(DeclarationName Name, DeclContext *DC, unsigned IDNS, |
516 | | NamedDecl **Decls, unsigned NumDecls); |
517 | | |
518 | | /// Retrieve the context that AST nodes are being imported into. |
519 | 40.2M | ASTContext &getToContext() const { return ToContext; } |
520 | | |
521 | | /// Retrieve the context that AST nodes are being imported from. |
522 | 13.1M | ASTContext &getFromContext() const { return FromContext; } |
523 | | |
524 | | /// Retrieve the file manager that AST nodes are being imported into. |
525 | 0 | FileManager &getToFileManager() const { return ToFileManager; } |
526 | | |
527 | | /// Retrieve the file manager that AST nodes are being imported from. |
528 | 0 | FileManager &getFromFileManager() const { return FromFileManager; } |
529 | | |
530 | | /// Report a diagnostic in the "to" context. |
531 | | DiagnosticBuilder ToDiag(SourceLocation Loc, unsigned DiagID); |
532 | | |
533 | | /// Report a diagnostic in the "from" context. |
534 | | DiagnosticBuilder FromDiag(SourceLocation Loc, unsigned DiagID); |
535 | | |
536 | | /// Return the set of declarations that we know are not equivalent. |
537 | 4.60M | NonEquivalentDeclSet &getNonEquivalentDecls() { return NonEquivalentDecls; } |
538 | | |
539 | | /// Called for ObjCInterfaceDecl, ObjCProtocolDecl, and TagDecl. |
540 | | /// Mark the Decl as complete, filling it in as much as possible. |
541 | | /// |
542 | | /// \param D A declaration in the "to" context. |
543 | | virtual void CompleteDecl(Decl* D); |
544 | | |
545 | | /// Subclasses can override this function to observe all of the \c From -> |
546 | | /// \c To declaration mappings as they are imported. |
547 | 138k | virtual void Imported(Decl *From, Decl *To) {} |
548 | | |
549 | | void RegisterImportedDecl(Decl *FromD, Decl *ToD); |
550 | | |
551 | | /// Store and assign the imported declaration to its counterpart. |
552 | | /// It may happen that several decls from the 'from' context are mapped to |
553 | | /// the same decl in the 'to' context. |
554 | | Decl *MapImported(Decl *From, Decl *To); |
555 | | |
556 | | /// Called by StructuralEquivalenceContext. If a RecordDecl is |
557 | | /// being compared to another RecordDecl as part of import, completing the |
558 | | /// other RecordDecl may trigger importation of the first RecordDecl. This |
559 | | /// happens especially for anonymous structs. If the original of the second |
560 | | /// RecordDecl can be found, we can complete it without the need for |
561 | | /// importation, eliminating this loop. |
562 | 3.45k | virtual Decl *GetOriginalDecl(Decl *To) { return nullptr; } |
563 | | |
564 | | /// Return if import of the given declaration has failed and if yes |
565 | | /// the kind of the problem. This gives the first error encountered with |
566 | | /// the node. |
567 | | llvm::Optional<ASTImportError> getImportDeclErrorIfAny(Decl *FromD) const; |
568 | | |
569 | | /// Mark (newly) imported declaration with error. |
570 | | void setImportDeclError(Decl *From, ASTImportError Error); |
571 | | |
572 | | /// Determine whether the given types are structurally |
573 | | /// equivalent. |
574 | | bool IsStructurallyEquivalent(QualType From, QualType To, |
575 | | bool Complain = true); |
576 | | |
577 | | /// Determine the index of a field in its parent record. |
578 | | /// F should be a field (or indirect field) declaration. |
579 | | /// \returns The index of the field in its parent context (starting from 0). |
580 | | /// On error `None` is returned (parent context is non-record). |
581 | | static llvm::Optional<unsigned> getFieldIndex(Decl *F); |
582 | | }; |
583 | | |
584 | | } // namespace clang |
585 | | |
586 | | #endif // LLVM_CLANG_AST_ASTIMPORTER_H |