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