[ASTImporter] Fix import of a typedef that has an attribute
authorGabor Marton <gabor.marton@ericsson.com>
Wed, 9 Dec 2020 20:40:53 +0000 (21:40 +0100)
committerGabor Marton <gabor.marton@ericsson.com>
Mon, 14 Dec 2020 17:27:05 +0000 (18:27 +0100)
The import of a typedefs with an attribute uses clang::Decl::setAttrs().
But that needs the ASTContext which we can get only from the
TranslationUnitDecl. But we can get the TUDecl only thourgh the
DeclContext, which is not set by the time of the setAttrs call.

Fix: import the attributes only after the DC is surely imported.
Btw, having the attribute import initiated from GetImportedOrCreateDecl was
fundamentally flawed. Now that is implicitly fixed.

Differential Revision: https://reviews.llvm.org/D92962

clang/lib/AST/ASTImporter.cpp
clang/unittests/AST/ASTImporterTest.cpp

index ea05f2e..10fa699 100644 (file)
@@ -264,16 +264,6 @@ namespace clang {
 
     void InitializeImportedDecl(Decl *FromD, Decl *ToD) {
       ToD->IdentifierNamespace = FromD->IdentifierNamespace;
-      if (FromD->hasAttrs())
-        for (const Attr *FromAttr : FromD->getAttrs()) {
-          // FIXME: Return of the error here is not possible until store of
-          // import errors is implemented.
-          auto ToAttrOrErr = import(FromAttr);
-          if (ToAttrOrErr)
-            ToD->addAttr(*ToAttrOrErr);
-          else
-            llvm::consumeError(ToAttrOrErr.takeError());
-        }
       if (FromD->isUsed())
         ToD->setIsUsed();
       if (FromD->isImplicit())
@@ -8328,6 +8318,15 @@ Expected<Decl *> ASTImporter::Import(Decl *FromD) {
   // Make sure that ImportImpl registered the imported decl.
   assert(ImportedDecls.count(FromD) != 0 && "Missing call to MapImported?");
 
+  if (FromD->hasAttrs())
+    for (const Attr *FromAttr : FromD->getAttrs()) {
+      auto ToAttrOrErr = Import(FromAttr);
+      if (ToAttrOrErr)
+        ToD->addAttr(*ToAttrOrErr);
+      else
+        return ToAttrOrErr.takeError();
+    }
+
   // Notify subclasses.
   Imported(FromD, ToD);
 
index e81e5d0..40340cb 100644 (file)
@@ -6084,6 +6084,24 @@ TEST_P(CTAD, DeductionGuideShouldCopyALocalTypedef) {
 INSTANTIATE_TEST_CASE_P(ParameterizedTests, CTAD,
                         DefaultTestValuesForRunOptions, );
 
+TEST_P(ASTImporterOptionSpecificTestBase, TypedefWithAttribute) {
+  Decl *TU = getTuDecl(
+      R"(
+      namespace N {
+        typedef int X __attribute__((annotate("A")));
+      }
+      )",
+      Lang_CXX17, "input.cc");
+  auto *FromD =
+      FirstDeclMatcher<TypedefDecl>().match(TU, typedefDecl(hasName("X")));
+  auto *ToD = Import(FromD, Lang_CXX17);
+  ASSERT_TRUE(ToD);
+  ASSERT_EQ(ToD->getAttrs().size(), 1);
+  auto *ToAttr = dyn_cast<AnnotateAttr>(ToD->getAttrs()[0]);
+  ASSERT_TRUE(ToAttr);
+  EXPECT_EQ(ToAttr->getAnnotation(), "A");
+}
+
 INSTANTIATE_TEST_CASE_P(ParameterizedTests, ASTImporterLookupTableTest,
                         DefaultTestValuesForRunOptions, );