Funnel changes to the ImportedDecls list in the ASTImporter through a
single Imported function, in preparation for fixing a serious design
flaw.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@96044 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/AST/ASTImporter.h b/include/clang/AST/ASTImporter.h
index b1ead16..f2df167 100644
--- a/include/clang/AST/ASTImporter.h
+++ b/include/clang/AST/ASTImporter.h
@@ -193,15 +193,17 @@
/// \brief Retrieve the file manager that AST nodes are being imported from.
FileManager &getFromFileManager() const { return FromFileManager; }
- /// \brief Retrieve the mapping from declarations in the "from" context
- /// to the already-imported declarations in the "to" context.
- llvm::DenseMap<Decl *, Decl *> &getImportedDecls() { return ImportedDecls; }
-
/// \brief Report a diagnostic in the "to" context.
DiagnosticBuilder ToDiag(SourceLocation Loc, unsigned DiagID);
/// \brief Report a diagnostic in the "from" context.
DiagnosticBuilder FromDiag(SourceLocation Loc, unsigned DiagID);
+
+ /// \brief Note that we have imported the "from" declaration by mapping it
+ /// to the (potentially-newly-created) "to" declaration.
+ ///
+ /// \returns \p To
+ Decl *Imported(Decl *From, Decl *To);
};
}
diff --git a/lib/AST/ASTImporter.cpp b/lib/AST/ASTImporter.cpp
index 7b00b9f..6840c61 100644
--- a/lib/AST/ASTImporter.cpp
+++ b/lib/AST/ASTImporter.cpp
@@ -797,10 +797,8 @@
continue;
if (TypedefDecl *FoundTypedef = dyn_cast<TypedefDecl>(*Lookup.first)) {
if (Importer.getToContext().typesAreCompatible(T,
- FoundTypedef->getUnderlyingType())) {
- Importer.getImportedDecls()[D] = FoundTypedef;
- return FoundTypedef;
- }
+ FoundTypedef->getUnderlyingType()))
+ return Importer.Imported(D, FoundTypedef);
}
ConflictingDecls.push_back(*Lookup.first);
@@ -821,7 +819,7 @@
Loc, Name.getAsIdentifierInfo(),
TInfo);
ToTypedef->setLexicalDeclContext(LexicalDC);
- Importer.getImportedDecls()[D] = ToTypedef;
+ Importer.Imported(D, ToTypedef);
LexicalDC->addDecl(ToTypedef);
return ToTypedef;
}
@@ -859,11 +857,8 @@
}
if (EnumDecl *FoundEnum = dyn_cast<EnumDecl>(Found)) {
- if (IsStructuralMatch(D, FoundEnum)) {
- // The enum types structurally match.
- Importer.getImportedDecls()[D] = FoundEnum;
- return FoundEnum;
- }
+ if (IsStructuralMatch(D, FoundEnum))
+ return Importer.Imported(D, FoundEnum);
}
ConflictingDecls.push_back(*Lookup.first);
@@ -882,7 +877,7 @@
Importer.Import(D->getTagKeywordLoc()),
0);
ToEnum->setLexicalDeclContext(LexicalDC);
- Importer.getImportedDecls()[D] = ToEnum;
+ Importer.Imported(D, ToEnum);
LexicalDC->addDecl(ToEnum);
// Import the integer type.
@@ -921,8 +916,10 @@
TagDecl *Definition = D->getDefinition();
if (Definition && Definition != D) {
Decl *ImportedDef = Importer.Import(Definition);
- Importer.getImportedDecls()[D] = ImportedDef;
- return ImportedDef;
+ if (!ImportedDef)
+ return 0;
+
+ return Importer.Imported(D, ImportedDef);
}
// Import the major distinguishing characteristics of this record.
@@ -964,8 +961,7 @@
// unit only had a forward declaration anyway; call it the same
// function.
// FIXME: For C++, we should also merge methods here.
- Importer.getImportedDecls()[D] = FoundDef;
- return FoundDef;
+ return Importer.Imported(D, FoundDef);
}
} else {
// We have a forward declaration of this type, so adopt that forward
@@ -1028,7 +1024,8 @@
ToRecord->setLexicalDeclContext(LexicalDC);
LexicalDC->addDecl(ToRecord);
}
- Importer.getImportedDecls()[D] = ToRecord;
+
+ Importer.Imported(D, ToRecord);
if (D->isDefinition()) {
ToRecord->startDefinition();
@@ -1085,7 +1082,7 @@
Name.getAsIdentifierInfo(), T,
Init, D->getInitVal());
ToEnumerator->setLexicalDeclContext(LexicalDC);
- Importer.getImportedDecls()[D] = ToEnumerator;
+ Importer.Imported(D, ToEnumerator);
LexicalDC->addDecl(ToEnumerator);
return ToEnumerator;
}
@@ -1116,8 +1113,7 @@
if (Importer.getToContext().typesAreCompatible(T,
FoundFunction->getType())) {
// FIXME: Actually try to merge the body and other attributes.
- Importer.getImportedDecls()[D] = FoundFunction;
- return FoundFunction;
+ return Importer.Imported(D, FoundFunction);
}
// FIXME: Check for overloading more carefully, e.g., by boosting
@@ -1167,7 +1163,7 @@
D->isInlineSpecified(),
D->hasWrittenPrototype());
ToEnumerator->setLexicalDeclContext(LexicalDC);
- Importer.getImportedDecls()[D] = ToEnumerator;
+ Importer.Imported(D, ToEnumerator);
LexicalDC->addDecl(ToEnumerator);
// Set the parameters.
@@ -1200,7 +1196,7 @@
Loc, Name.getAsIdentifierInfo(),
T, TInfo, BitWidth, D->isMutable());
ToField->setLexicalDeclContext(LexicalDC);
- Importer.getImportedDecls()[D] = ToField;
+ Importer.Imported(D, ToField);
LexicalDC->addDecl(ToField);
return ToField;
}
@@ -1266,7 +1262,7 @@
if (MergeWithVar) {
// An equivalent variable with external linkage has been found. Link
// the two declarations, then merge them.
- Importer.getImportedDecls()[D] = MergeWithVar;
+ Importer.Imported(D, MergeWithVar);
if (VarDecl *DDef = D->getDefinition()) {
if (VarDecl *ExistingDef = MergeWithVar->getDefinition()) {
@@ -1298,7 +1294,7 @@
Name.getAsIdentifierInfo(), T, TInfo,
D->getStorageClass());
ToVar->setLexicalDeclContext(LexicalDC);
- Importer.getImportedDecls()[D] = ToVar;
+ Importer.Imported(D, ToVar);
LexicalDC->addDecl(ToVar);
// Merge the initializer.
@@ -1336,8 +1332,7 @@
Loc, Name.getAsIdentifierInfo(),
T, TInfo, D->getStorageClass(),
/*FIXME: Default argument*/ 0);
- Importer.getImportedDecls()[D] = ToParm;
- return ToParm;
+ return Importer.Imported(D, ToParm);
}
//----------------------------------------------------------------------------
@@ -1634,3 +1629,8 @@
return Diags.Report(FullSourceLoc(Loc, FromContext.getSourceManager()),
DiagID);
}
+
+Decl *ASTImporter::Imported(Decl *From, Decl *To) {
+ ImportedDecls[From] = To;
+ return To;
+}
\ No newline at end of file
diff --git a/test/ASTMerge/Inputs/struct1.c b/test/ASTMerge/Inputs/struct1.c
index ff8fa0a..10c8fce 100644
--- a/test/ASTMerge/Inputs/struct1.c
+++ b/test/ASTMerge/Inputs/struct1.c
@@ -44,3 +44,10 @@
// Incomplete type
struct S10 *x10;
+// FIXME: Matches, but crashes the importer
+#if 0
+struct ListNode {
+ int value;
+ struct ListNode *Next;
+} xList;
+#endif
diff --git a/test/ASTMerge/Inputs/struct2.c b/test/ASTMerge/Inputs/struct2.c
index d865eef..655efd4 100644
--- a/test/ASTMerge/Inputs/struct2.c
+++ b/test/ASTMerge/Inputs/struct2.c
@@ -40,3 +40,9 @@
// Incomplete type
struct S10 *x10;
+
+// Matches
+struct ListNode {
+ int value;
+ struct ListNode *Next;
+} xList;