summaryrefslogtreecommitdiffstats
path: root/clang/lib/AST/ASTImporter.cpp
diff options
context:
space:
mode:
authorAleksei Sidorin <a.sidorin@samsung.com>2018-04-24 10:11:53 +0000
committerAleksei Sidorin <a.sidorin@samsung.com>2018-04-24 10:11:53 +0000
commit04fbffcc52fab45c62bc9ce14ff26e1ffbef9b2e (patch)
tree11170ace6befe649c18b0ee34f3e16e239c36a29 /clang/lib/AST/ASTImporter.cpp
parentef507cb47c64835d5fa3e0873a2970bc6ad40dfa (diff)
downloadbcm5719-llvm-04fbffcc52fab45c62bc9ce14ff26e1ffbef9b2e.tar.gz
bcm5719-llvm-04fbffcc52fab45c62bc9ce14ff26e1ffbef9b2e.zip
[ASTImporter] Allow testing of import sequences; fix import of typedefs for anonymous decls
This patch introduces the ability to test an arbitrary sequence of imports between a given set of virtual source files. This should finally allow us to write simple tests and fix annoying issues inside ASTImporter that cause failures in CSA CTU. This is done by refactoring ASTImporterTest functions and introducing `testImportSequence` facility. As a side effect, `testImport` facility was generalized a bit more. It should now allow import of non-decl AST nodes; however, there is still no test using this ability. As a "test for test", there is also a fix for import anonymous TagDecls referred by typedef. Before this patch, the setting of typedef for anonymous structure was delayed; however, this approach misses the corner case if an enum constant is imported directly. In this patch, typedefs for anonymous declarations are imported right after the anonymous declaration is imported, without any delay. Thanks to Adam Balogh for suggestions included into this patch. Differential Revision: https://reviews.llvm.org/D44079 llvm-svn: 330704
Diffstat (limited to 'clang/lib/AST/ASTImporter.cpp')
-rw-r--r--clang/lib/AST/ASTImporter.cpp44
1 files changed, 21 insertions, 23 deletions
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index 9d87157e271..a2e6c01dc29 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -1088,6 +1088,17 @@ void ASTNodeImporter::ImportDeclContext(DeclContext *FromDC, bool ForceImport) {
Importer.Import(From);
}
+static void setTypedefNameForAnonDecl(TagDecl *From, TagDecl *To,
+ ASTImporter &Importer) {
+ if (TypedefNameDecl *FromTypedef = From->getTypedefNameForAnonDecl()) {
+ auto *ToTypedef =
+ cast_or_null<TypedefNameDecl>(Importer.Import(FromTypedef));
+ assert (ToTypedef && "Failed to import typedef of an anonymous structure");
+
+ To->setTypedefNameForAnonDecl(ToTypedef);
+ }
+}
+
bool ASTNodeImporter::ImportDefinition(RecordDecl *From, RecordDecl *To,
ImportDefinitionKind Kind) {
if (To->getDefinition() || To->isBeingDefined()) {
@@ -1098,6 +1109,8 @@ bool ASTNodeImporter::ImportDefinition(RecordDecl *From, RecordDecl *To,
}
To->startDefinition();
+
+ setTypedefNameForAnonDecl(From, To, Importer);
// Add base classes.
if (auto *ToCXX = dyn_cast<CXXRecordDecl>(To)) {
@@ -1229,6 +1242,8 @@ bool ASTNodeImporter::ImportDefinition(EnumDecl *From, EnumDecl *To,
To->startDefinition();
+ setTypedefNameForAnonDecl(From, To, Importer);
+
QualType T = Importer.Import(Importer.getFromContext().getTypeDeclType(From));
if (T.isNull())
return true;
@@ -1707,6 +1722,11 @@ Decl *ASTNodeImporter::VisitTypedefNameDecl(TypedefNameDecl *D, bool IsAlias) {
if (T.isNull())
return nullptr;
+ // Some nodes (like anonymous tags referred by typedefs) are allowed to
+ // import their enclosing typedef directly. Check if this is the case.
+ if (Decl *AlreadyImported = Importer.GetAlreadyImportedOrNull(D))
+ return AlreadyImported;
+
// Create the new typedef node.
TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
SourceLocation StartL = Importer.Import(D->getLocStart());
@@ -6576,29 +6596,7 @@ Decl *ASTImporter::Import(Decl *FromD) {
// Record the imported declaration.
ImportedDecls[FromD] = ToD;
-
- if (auto *FromTag = dyn_cast<TagDecl>(FromD)) {
- // Keep track of anonymous tags that have an associated typedef.
- if (FromTag->getTypedefNameForAnonDecl())
- AnonTagsWithPendingTypedefs.push_back(FromTag);
- } else if (auto *FromTypedef = dyn_cast<TypedefNameDecl>(FromD)) {
- // When we've finished transforming a typedef, see whether it was the
- // typedef for an anonymous tag.
- for (SmallVectorImpl<TagDecl *>::iterator
- FromTag = AnonTagsWithPendingTypedefs.begin(),
- FromTagEnd = AnonTagsWithPendingTypedefs.end();
- FromTag != FromTagEnd; ++FromTag) {
- if ((*FromTag)->getTypedefNameForAnonDecl() == FromTypedef) {
- if (auto *ToTag = cast_or_null<TagDecl>(Import(*FromTag))) {
- // We found the typedef for an anonymous tag; link them.
- ToTag->setTypedefNameForAnonDecl(cast<TypedefNameDecl>(ToD));
- AnonTagsWithPendingTypedefs.erase(FromTag);
- break;
- }
- }
- }
- }
-
+
return ToD;
}
OpenPOWER on IntegriCloud