Skip to content

Commit 26f72a9

Browse files
committed
[ASTImporter] Refactor Decl creation
Summary: Generalize the creation of Decl nodes during Import. With this patch we do the same things after and before a new AST node is created (::Create) The import logic should be really simple, we create the node, then we mark that as imported, then we recursively import the parts for that node and then set them on that node. However, the AST is actually a graph, so we have to handle circles. If we mark something as imported (`MapImported()`) then we return with the corresponding `To` decl whenever we want to import that node again, this way circles are handled. In order to make this algorithm work we must ensure things, which are handled in the generic CreateDecl<> template: * There are no `Import()` calls in between any node creation (::Create) and the `MapImported()` call. * Before actually creating an AST node (::Create), we must check if the Node had been imported already, if yes then return with that one. One very important case for this is connected to templates: we may start an import both from the templated decl of a template and from the template itself. Now, the virtual `Imported` function is called in `ASTImporter::Impor(Decl *)`, but only once, when the `Decl` is imported. One point of this refactor is to separate responsibilities. The original `Imported()` had 3 responsibilities: - notify subclasses when an import happened - register the decl into `ImportedDecls` - initialise the Decl (set attributes, etc) Now all of these are in separate functions: - `Imported` - `MapImported` - `InitializeImportedDecl` I tried to check all the clients, I executed tests for `ExternalASTMerger.cpp` and some unittests for lldb. Reviewers: a.sidorin, balazske, xazax.hun, r.stahl Subscribers: rnkovacs, dkrupp, cfe-commits Differential Revision: https://reviews.llvm.org/D47632 llvm-svn: 336896
1 parent 860a3bf commit 26f72a9

File tree

9 files changed

+594
-460
lines changed

9 files changed

+594
-460
lines changed

clang/include/clang/AST/ASTImporter.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -314,13 +314,13 @@ class Attr;
314314
/// \param D A declaration in the "to" context.
315315
virtual void CompleteDecl(Decl* D);
316316

317-
/// Note that we have imported the "from" declaration by mapping it
318-
/// to the (potentially-newly-created) "to" declaration.
319-
///
320317
/// Subclasses can override this function to observe all of the \c From ->
321318
/// \c To declaration mappings as they are imported.
322-
virtual Decl *Imported(Decl *From, Decl *To);
323-
319+
virtual Decl *Imported(Decl *From, Decl *To) { return To; }
320+
321+
/// Store and assign the imported declaration to its counterpart.
322+
Decl *MapImported(Decl *From, Decl *To);
323+
324324
/// Called by StructuralEquivalenceContext. If a RecordDecl is
325325
/// being compared to another RecordDecl as part of import, completing the
326326
/// other RecordDecl may trigger importation of the first RecordDecl. This

clang/include/clang/AST/ASTStructuralEquivalence.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,14 @@ class QualType;
3030
class RecordDecl;
3131
class SourceLocation;
3232

33+
/// \brief Whether to perform a normal or minimal equivalence check.
34+
/// In case of `Minimal`, we do not perform a recursive check of decls with
35+
/// external storage.
36+
enum class StructuralEquivalenceKind {
37+
Default,
38+
Minimal,
39+
};
40+
3341
struct StructuralEquivalenceContext {
3442
/// AST contexts for which we are checking structural equivalence.
3543
ASTContext &FromCtx, &ToCtx;
@@ -47,6 +55,8 @@ struct StructuralEquivalenceContext {
4755
/// (which we have already complained about).
4856
llvm::DenseSet<std::pair<Decl *, Decl *>> &NonEquivalentDecls;
4957

58+
StructuralEquivalenceKind EqKind;
59+
5060
/// Whether we're being strict about the spelling of types when
5161
/// unifying two types.
5262
bool StrictTypeSpelling;
@@ -63,10 +73,11 @@ struct StructuralEquivalenceContext {
6373
StructuralEquivalenceContext(
6474
ASTContext &FromCtx, ASTContext &ToCtx,
6575
llvm::DenseSet<std::pair<Decl *, Decl *>> &NonEquivalentDecls,
76+
StructuralEquivalenceKind EqKind,
6677
bool StrictTypeSpelling = false, bool Complain = true,
6778
bool ErrorOnTagTypeMismatch = false)
6879
: FromCtx(FromCtx), ToCtx(ToCtx), NonEquivalentDecls(NonEquivalentDecls),
69-
StrictTypeSpelling(StrictTypeSpelling),
80+
EqKind(EqKind), StrictTypeSpelling(StrictTypeSpelling),
7081
ErrorOnTagTypeMismatch(ErrorOnTagTypeMismatch), Complain(Complain) {}
7182

7283
DiagnosticBuilder Diag1(SourceLocation Loc, unsigned DiagID);

clang/include/clang/AST/DeclBase.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,7 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) Decl {
309309
protected:
310310
friend class ASTDeclReader;
311311
friend class ASTDeclWriter;
312-
friend class ASTImporter;
312+
friend class ASTNodeImporter;
313313
friend class ASTReader;
314314
friend class CXXClassMemberWrapper;
315315
friend class LinkageComputer;

0 commit comments

Comments
 (0)