teemperor created this revision.
teemperor added a reviewer: martong.
Herald added subscribers: cfe-commits, rnkovacs.
Herald added a reviewer: a.sidorin.
Herald added a reviewer: shafik.
Herald added a project: clang.

When Sema encounters a ObjCMethodDecl definition it declares the implicit 
parameters for the ObjCMethodDecl.
When importing such a method with the ASTImporter we need to do the same for 
the imported method
otherwise we will crash when generating code (where CodeGen expects that this 
was called by Sema).

Note I had to implement Objective-C[++] support in Language.cpp as this is the 
first test for Objective-C and this
would otherwise just hit this 'not implemented' assert when running the unit 
test.


Repository:
  rC Clang

https://reviews.llvm.org/D71112

Files:
  clang/lib/AST/ASTImporter.cpp
  clang/unittests/AST/ASTImporterTest.cpp
  clang/unittests/AST/Language.cpp


Index: clang/unittests/AST/Language.cpp
===================================================================
--- clang/unittests/AST/Language.cpp
+++ clang/unittests/AST/Language.cpp
@@ -37,9 +37,11 @@
   case Lang_CXX2a:
     BasicArgs = {"-std=c++2a", "-frtti"};
     break;
-  case Lang_OpenCL:
   case Lang_OBJCXX:
-    llvm_unreachable("Not implemented yet!");
+    BasicArgs = {"-x", "objective-c++", "-frtti"};
+    break;
+  case Lang_OpenCL:
+    llvm_unreachable("-std=objc++");
   }
   return BasicArgs;
 }
Index: clang/unittests/AST/ASTImporterTest.cpp
===================================================================
--- clang/unittests/AST/ASTImporterTest.cpp
+++ clang/unittests/AST/ASTImporterTest.cpp
@@ -5599,6 +5599,28 @@
             2u);
 }
 
+TEST_P(ASTImporterOptionSpecificTestBase, ImplicitlyDeclareSelf) {
+  Decl *FromTU = getTuDecl("__attribute__((objc_root_class))\n"
+                           "@interface Root\n"
+                           "@end\n"
+                           "@interface C : Root\n"
+                           "-(void)method;\n"
+                           "@end\n"
+                           "@implementation C\n"
+                           "-(void)method {}\n"
+                           "@end\n",
+                           Lang_OBJCXX, "input.mm");
+  auto *FromMethod = LastDeclMatcher<ObjCMethodDecl>().match(
+      FromTU, namedDecl(hasName("method")));
+  ASSERT_TRUE(FromMethod);
+  auto ToMethod = Import(FromMethod, Lang_OBJCXX);
+  ASSERT_TRUE(ToMethod);
+
+  // Both methods should have their implicit parameters.
+  EXPECT_TRUE(FromMethod->getSelfDecl() != nullptr);
+  EXPECT_TRUE(ToMethod->getSelfDecl() != nullptr);
+}
+
 INSTANTIATE_TEST_CASE_P(ParameterizedTests, ASTImporterLookupTableTest,
                         DefaultTestValuesForRunOptions, );
 
Index: clang/lib/AST/ASTImporter.cpp
===================================================================
--- clang/lib/AST/ASTImporter.cpp
+++ clang/lib/AST/ASTImporter.cpp
@@ -4010,6 +4010,14 @@
 
   ToMethod->setLexicalDeclContext(LexicalDC);
   LexicalDC->addDeclInternal(ToMethod);
+
+  // Implicit params are declared when Sema encounters the definition but this
+  // never happens when the method is imported. Manually declare the implicit
+  // params now that the MethodDecl knows its class interface.
+  if (D->getSelfDecl())
+    ToMethod->createImplicitParams(Importer.getToContext(),
+                                   ToMethod->getClassInterface());
+
   return ToMethod;
 }
 


Index: clang/unittests/AST/Language.cpp
===================================================================
--- clang/unittests/AST/Language.cpp
+++ clang/unittests/AST/Language.cpp
@@ -37,9 +37,11 @@
   case Lang_CXX2a:
     BasicArgs = {"-std=c++2a", "-frtti"};
     break;
-  case Lang_OpenCL:
   case Lang_OBJCXX:
-    llvm_unreachable("Not implemented yet!");
+    BasicArgs = {"-x", "objective-c++", "-frtti"};
+    break;
+  case Lang_OpenCL:
+    llvm_unreachable("-std=objc++");
   }
   return BasicArgs;
 }
Index: clang/unittests/AST/ASTImporterTest.cpp
===================================================================
--- clang/unittests/AST/ASTImporterTest.cpp
+++ clang/unittests/AST/ASTImporterTest.cpp
@@ -5599,6 +5599,28 @@
             2u);
 }
 
+TEST_P(ASTImporterOptionSpecificTestBase, ImplicitlyDeclareSelf) {
+  Decl *FromTU = getTuDecl("__attribute__((objc_root_class))\n"
+                           "@interface Root\n"
+                           "@end\n"
+                           "@interface C : Root\n"
+                           "-(void)method;\n"
+                           "@end\n"
+                           "@implementation C\n"
+                           "-(void)method {}\n"
+                           "@end\n",
+                           Lang_OBJCXX, "input.mm");
+  auto *FromMethod = LastDeclMatcher<ObjCMethodDecl>().match(
+      FromTU, namedDecl(hasName("method")));
+  ASSERT_TRUE(FromMethod);
+  auto ToMethod = Import(FromMethod, Lang_OBJCXX);
+  ASSERT_TRUE(ToMethod);
+
+  // Both methods should have their implicit parameters.
+  EXPECT_TRUE(FromMethod->getSelfDecl() != nullptr);
+  EXPECT_TRUE(ToMethod->getSelfDecl() != nullptr);
+}
+
 INSTANTIATE_TEST_CASE_P(ParameterizedTests, ASTImporterLookupTableTest,
                         DefaultTestValuesForRunOptions, );
 
Index: clang/lib/AST/ASTImporter.cpp
===================================================================
--- clang/lib/AST/ASTImporter.cpp
+++ clang/lib/AST/ASTImporter.cpp
@@ -4010,6 +4010,14 @@
 
   ToMethod->setLexicalDeclContext(LexicalDC);
   LexicalDC->addDeclInternal(ToMethod);
+
+  // Implicit params are declared when Sema encounters the definition but this
+  // never happens when the method is imported. Manually declare the implicit
+  // params now that the MethodDecl knows its class interface.
+  if (D->getSelfDecl())
+    ToMethod->createImplicitParams(Importer.getToContext(),
+                                   ToMethod->getClassInterface());
+
   return ToMethod;
 }
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to