Skip to content

Commit

Permalink
[ASTImporter] Refactor Decl creation
Browse files Browse the repository at this point in the history
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
  • Loading branch information
martong committed Jul 12, 2018
1 parent 860a3bf commit 26f72a9
Show file tree
Hide file tree
Showing 9 changed files with 594 additions and 460 deletions.
10 changes: 5 additions & 5 deletions clang/include/clang/AST/ASTImporter.h
Expand Up @@ -314,13 +314,13 @@ class Attr;
/// \param D A declaration in the "to" context.
virtual void CompleteDecl(Decl* D);

/// Note that we have imported the "from" declaration by mapping it
/// to the (potentially-newly-created) "to" declaration.
///
/// Subclasses can override this function to observe all of the \c From ->
/// \c To declaration mappings as they are imported.
virtual Decl *Imported(Decl *From, Decl *To);

virtual Decl *Imported(Decl *From, Decl *To) { return To; }

/// Store and assign the imported declaration to its counterpart.
Decl *MapImported(Decl *From, Decl *To);

/// Called by StructuralEquivalenceContext. If a RecordDecl is
/// being compared to another RecordDecl as part of import, completing the
/// other RecordDecl may trigger importation of the first RecordDecl. This
Expand Down
13 changes: 12 additions & 1 deletion clang/include/clang/AST/ASTStructuralEquivalence.h
Expand Up @@ -30,6 +30,14 @@ class QualType;
class RecordDecl;
class SourceLocation;

/// \brief Whether to perform a normal or minimal equivalence check.
/// In case of `Minimal`, we do not perform a recursive check of decls with
/// external storage.
enum class StructuralEquivalenceKind {
Default,
Minimal,
};

struct StructuralEquivalenceContext {
/// AST contexts for which we are checking structural equivalence.
ASTContext &FromCtx, &ToCtx;
Expand All @@ -47,6 +55,8 @@ struct StructuralEquivalenceContext {
/// (which we have already complained about).
llvm::DenseSet<std::pair<Decl *, Decl *>> &NonEquivalentDecls;

StructuralEquivalenceKind EqKind;

/// Whether we're being strict about the spelling of types when
/// unifying two types.
bool StrictTypeSpelling;
Expand All @@ -63,10 +73,11 @@ struct StructuralEquivalenceContext {
StructuralEquivalenceContext(
ASTContext &FromCtx, ASTContext &ToCtx,
llvm::DenseSet<std::pair<Decl *, Decl *>> &NonEquivalentDecls,
StructuralEquivalenceKind EqKind,
bool StrictTypeSpelling = false, bool Complain = true,
bool ErrorOnTagTypeMismatch = false)
: FromCtx(FromCtx), ToCtx(ToCtx), NonEquivalentDecls(NonEquivalentDecls),
StrictTypeSpelling(StrictTypeSpelling),
EqKind(EqKind), StrictTypeSpelling(StrictTypeSpelling),
ErrorOnTagTypeMismatch(ErrorOnTagTypeMismatch), Complain(Complain) {}

DiagnosticBuilder Diag1(SourceLocation Loc, unsigned DiagID);
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/AST/DeclBase.h
Expand Up @@ -309,7 +309,7 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) Decl {
protected:
friend class ASTDeclReader;
friend class ASTDeclWriter;
friend class ASTImporter;
friend class ASTNodeImporter;
friend class ASTReader;
friend class CXXClassMemberWrapper;
friend class LinkageComputer;
Expand Down

0 comments on commit 26f72a9

Please sign in to comment.