aboutsummaryrefslogtreecommitdiff
path: root/include/clang/AST/ASTImporter.h
diff options
context:
space:
mode:
authorSean Callanan <scallanan@apple.com>2013-10-09 21:45:11 +0000
committerSean Callanan <scallanan@apple.com>2013-10-09 21:45:11 +0000
commit8f2cb42e1aa5dbdd6fa651a5da7ab8a3a0d4dece (patch)
treedada4b110ac0b44a24e996fa191de7d3430b031c /include/clang/AST/ASTImporter.h
parentc6d680003196028ed0a05e8da29ab269d6f79651 (diff)
This patch addresses a problem encountered by the
ASTImporter when importing the following types: typedef struct { } A; typedef struct { A a; } B; Suppose we have imported B, but we did not at that time need to complete it. Then later we want to import A. The struct is anonymous, so the first thing we want to do is make sure no other anonymous struct already matches it. So we set up an StructuralEquivalenceContext and compare B with A. This happens at ASTImporter.cpp:2179. Now, in this scenario, B is not complete. So we go and import its fields, including a, which causes A to be imported. The ASTImporter doesn’t yet have A in its list of already-imported things, so we import A. After the StructuralEquivalenceContext is finished determining that A and B are different, the ASTImporter concludes that A must be imported because no equivalent exists, so it imports a second copy of A. Now we have two different structs representing A. This is really bad news. The patch allows the StructuralEquivalenceContext to use the original version of B when making its comparison, obviating the need for an import and cutting this loop. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@192324 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/clang/AST/ASTImporter.h')
-rw-r--r--include/clang/AST/ASTImporter.h8
1 files changed, 8 insertions, 0 deletions
diff --git a/include/clang/AST/ASTImporter.h b/include/clang/AST/ASTImporter.h
index 1672ab22a3..b74c8ee1bf 100644
--- a/include/clang/AST/ASTImporter.h
+++ b/include/clang/AST/ASTImporter.h
@@ -271,6 +271,14 @@ namespace clang {
/// 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);
+
+ /// \brief 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
+ /// happens especially for anonymous structs. If the original of the second
+ /// RecordDecl can be found, we can complete it without the need for
+ /// importation, eliminating this loop.
+ virtual Decl *GetOriginalDecl(Decl *To) { return NULL; }
/// \brief Determine whether the given types are structurally
/// equivalent.