From: Douglas Gregor Date: Fri, 12 Feb 2010 23:44:20 +0000 (+0000) Subject: Funnel changes to the ImportedDecls list in the ASTImporter through a X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5ce5dab3c30e4255b8f62b148b6a86f09a444aaa;p=clang 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 b1ead16925..f2df1677fb 100644 --- a/include/clang/AST/ASTImporter.h +++ b/include/clang/AST/ASTImporter.h @@ -193,15 +193,17 @@ namespace clang { /// \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 &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 7b00b9f73b..6840c61bed 100644 --- a/lib/AST/ASTImporter.cpp +++ b/lib/AST/ASTImporter.cpp @@ -797,10 +797,8 @@ Decl *ASTNodeImporter::VisitTypedefDecl(TypedefDecl *D) { continue; if (TypedefDecl *FoundTypedef = dyn_cast(*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 @@ Decl *ASTNodeImporter::VisitTypedefDecl(TypedefDecl *D) { Loc, Name.getAsIdentifierInfo(), TInfo); ToTypedef->setLexicalDeclContext(LexicalDC); - Importer.getImportedDecls()[D] = ToTypedef; + Importer.Imported(D, ToTypedef); LexicalDC->addDecl(ToTypedef); return ToTypedef; } @@ -859,11 +857,8 @@ Decl *ASTNodeImporter::VisitEnumDecl(EnumDecl *D) { } if (EnumDecl *FoundEnum = dyn_cast(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 @@ Decl *ASTNodeImporter::VisitEnumDecl(EnumDecl *D) { 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 @@ Decl *ASTNodeImporter::VisitRecordDecl(RecordDecl *D) { 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 @@ Decl *ASTNodeImporter::VisitRecordDecl(RecordDecl *D) { // 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 @@ Decl *ASTNodeImporter::VisitRecordDecl(RecordDecl *D) { ToRecord->setLexicalDeclContext(LexicalDC); LexicalDC->addDecl(ToRecord); } - Importer.getImportedDecls()[D] = ToRecord; + + Importer.Imported(D, ToRecord); if (D->isDefinition()) { ToRecord->startDefinition(); @@ -1085,7 +1082,7 @@ Decl *ASTNodeImporter::VisitEnumConstantDecl(EnumConstantDecl *D) { 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 @@ Decl *ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) { 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 @@ Decl *ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) { 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 @@ Decl *ASTNodeImporter::VisitFieldDecl(FieldDecl *D) { 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 @@ Decl *ASTNodeImporter::VisitVarDecl(VarDecl *D) { 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 @@ Decl *ASTNodeImporter::VisitVarDecl(VarDecl *D) { 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 @@ Decl *ASTNodeImporter::VisitParmVarDecl(ParmVarDecl *D) { 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 @@ DiagnosticBuilder ASTImporter::FromDiag(SourceLocation Loc, unsigned DiagID) { 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 ff8fa0a04a..10c8fce42a 100644 --- a/test/ASTMerge/Inputs/struct1.c +++ b/test/ASTMerge/Inputs/struct1.c @@ -44,3 +44,10 @@ struct S9 { int i; float f; } *x9; // 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 d865eef895..655efd43db 100644 --- a/test/ASTMerge/Inputs/struct2.c +++ b/test/ASTMerge/Inputs/struct2.c @@ -40,3 +40,9 @@ struct S9 *x9; // Incomplete type struct S10 *x10; + +// Matches +struct ListNode { + int value; + struct ListNode *Next; +} xList;