diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -8634,6 +8634,174 @@ return ToAttrOrErr.takeError(); break; } + case attr::AcquireCapability: { + const auto *From = cast(FromAttr); + AttrImporter AI(*this); + Expected ToAttrOrErr = AI.createImportedAttr( + From, AI.importArrayArg(From->args(), From->args_size()).value(), + From->args_size()); + if (ToAttrOrErr) + ToAttr = *ToAttrOrErr; + else + return ToAttrOrErr.takeError(); + break; + } + case attr::TryAcquireCapability: { + const auto *From = cast(FromAttr); + AttrImporter AI(*this); + Expected ToAttrOrErr = AI.createImportedAttr( + From, AI.importArg(From->getSuccessValue()).value(), + AI.importArrayArg(From->args(), From->args_size()).value(), + From->args_size()); + if (ToAttrOrErr) + ToAttr = *ToAttrOrErr; + else + return ToAttrOrErr.takeError(); + break; + } + case attr::ReleaseCapability: { + const auto *From = cast(FromAttr); + AttrImporter AI(*this); + Expected ToAttrOrErr = AI.createImportedAttr( + From, AI.importArrayArg(From->args(), From->args_size()).value(), + From->args_size()); + if (ToAttrOrErr) + ToAttr = *ToAttrOrErr; + else + return ToAttrOrErr.takeError(); + break; + } + case attr::RequiresCapability: { + const auto *From = cast(FromAttr); + AttrImporter AI(*this); + Expected ToAttrOrErr = AI.createImportedAttr( + From, AI.importArrayArg(From->args(), From->args_size()).value(), + From->args_size()); + if (ToAttrOrErr) + ToAttr = *ToAttrOrErr; + else + return ToAttrOrErr.takeError(); + break; + } + case attr::GuardedBy: { + const auto *From = cast(FromAttr); + AttrImporter AI(*this); + Expected ToAttrOrErr = + AI.createImportedAttr(From, AI.importArg(From->getArg()).value()); + if (ToAttrOrErr) + ToAttr = *ToAttrOrErr; + else + return ToAttrOrErr.takeError(); + break; + } + case attr::PtGuardedBy: { + const auto *From = cast(FromAttr); + AttrImporter AI(*this); + Expected ToAttrOrErr = + AI.createImportedAttr(From, AI.importArg(From->getArg()).value()); + if (ToAttrOrErr) + ToAttr = *ToAttrOrErr; + else + return ToAttrOrErr.takeError(); + break; + } + case attr::AcquiredAfter: { + const auto *From = cast(FromAttr); + AttrImporter AI(*this); + Expected ToAttrOrErr = AI.createImportedAttr( + From, AI.importArrayArg(From->args(), From->args_size()).value(), + From->args_size()); + if (ToAttrOrErr) + ToAttr = *ToAttrOrErr; + else + return ToAttrOrErr.takeError(); + break; + } + case attr::AcquiredBefore: { + const auto *From = cast(FromAttr); + AttrImporter AI(*this); + Expected ToAttrOrErr = AI.createImportedAttr( + From, AI.importArrayArg(From->args(), From->args_size()).value(), + From->args_size()); + if (ToAttrOrErr) + ToAttr = *ToAttrOrErr; + else + return ToAttrOrErr.takeError(); + break; + } + case attr::AssertExclusiveLock: { + const auto *From = cast(FromAttr); + AttrImporter AI(*this); + Expected ToAttrOrErr = AI.createImportedAttr( + From, AI.importArrayArg(From->args(), From->args_size()).value(), + From->args_size()); + if (ToAttrOrErr) + ToAttr = *ToAttrOrErr; + else + return ToAttrOrErr.takeError(); + break; + } + case attr::AssertSharedLock: { + const auto *From = cast(FromAttr); + AttrImporter AI(*this); + Expected ToAttrOrErr = AI.createImportedAttr( + From, AI.importArrayArg(From->args(), From->args_size()).value(), + From->args_size()); + if (ToAttrOrErr) + ToAttr = *ToAttrOrErr; + else + return ToAttrOrErr.takeError(); + break; + } + case attr::ExclusiveTrylockFunction: { + const auto *From = cast(FromAttr); + AttrImporter AI(*this); + Expected ToAttrOrErr = AI.createImportedAttr( + From, AI.importArg(From->getSuccessValue()).value(), + AI.importArrayArg(From->args(), From->args_size()).value(), + From->args_size()); + if (ToAttrOrErr) + ToAttr = *ToAttrOrErr; + else + return ToAttrOrErr.takeError(); + break; + } + case attr::SharedTrylockFunction: { + const auto *From = cast(FromAttr); + AttrImporter AI(*this); + Expected ToAttrOrErr = AI.createImportedAttr( + From, AI.importArg(From->getSuccessValue()).value(), + AI.importArrayArg(From->args(), From->args_size()).value(), + From->args_size()); + if (ToAttrOrErr) + ToAttr = *ToAttrOrErr; + else + return ToAttrOrErr.takeError(); + break; + } + case attr::LockReturned: { + const auto *From = cast(FromAttr); + AttrImporter AI(*this); + Expected ToAttrOrErr = + AI.createImportedAttr(From, AI.importArg(From->getArg()).value()); + if (ToAttrOrErr) + ToAttr = *ToAttrOrErr; + else + return ToAttrOrErr.takeError(); + break; + } + case attr::LocksExcluded: { + const auto *From = cast(FromAttr); + AttrImporter AI(*this); + Expected ToAttrOrErr = AI.createImportedAttr( + From, AI.importArrayArg(From->args(), From->args_size()).value(), + From->args_size()); + if (ToAttrOrErr) + ToAttr = *ToAttrOrErr; + else + return ToAttrOrErr.takeError(); + break; + } default: // FIXME: 'clone' copies every member but some of them should be imported. diff --git a/clang/unittests/AST/ASTImporterTest.cpp b/clang/unittests/AST/ASTImporterTest.cpp --- a/clang/unittests/AST/ASTImporterTest.cpp +++ b/clang/unittests/AST/ASTImporterTest.cpp @@ -6564,6 +6564,31 @@ EXPECT_EQ(FromAttr->getType()->getName(), ToAttr->getType()->getName()); } +TEST_P(ImportAttributes, ImportGuardedVar) { + GuardedVarAttr *FromAttr, *ToAttr; + importAttr("int test __attribute__((guarded_var));", FromAttr, + ToAttr); +} + +TEST_P(ImportAttributes, ImportPtGuardedVar) { + PtGuardedVarAttr *FromAttr, *ToAttr; + importAttr("int *test __attribute__((pt_guarded_var));", FromAttr, + ToAttr); +} + +TEST_P(ImportAttributes, ImportScopedLockable) { + ScopedLockableAttr *FromAttr, *ToAttr; + importAttr("struct __attribute__((scoped_lockable)) test {};", + FromAttr, ToAttr); +} + +TEST_P(ImportAttributes, ImportCapability) { + CapabilityAttr *FromAttr, *ToAttr; + importAttr( + "struct __attribute__((capability(\"cap\"))) test {};", FromAttr, ToAttr); + EXPECT_EQ(FromAttr->getName(), ToAttr->getName()); +} + TEST_P(ImportAttributes, ImportAssertCapability) { AssertCapabilityAttr *FromAttr, *ToAttr; importAttr( @@ -6572,6 +6597,147 @@ checkImportVariadicArg(FromAttr->args(), ToAttr->args()); } +TEST_P(ImportAttributes, ImportAcquireCapability) { + AcquireCapabilityAttr *FromAttr, *ToAttr; + importAttr( + "void test(int A1, int A2) __attribute__((acquire_capability(A1, A2)));", + FromAttr, ToAttr); + checkImportVariadicArg(FromAttr->args(), ToAttr->args()); +} + +TEST_P(ImportAttributes, ImportTryAcquireCapability) { + TryAcquireCapabilityAttr *FromAttr, *ToAttr; + importAttr( + "void test(int A1, int A2) __attribute__((try_acquire_capability(1, A1, " + "A2)));", + FromAttr, ToAttr); + checkImported(FromAttr->getSuccessValue(), ToAttr->getSuccessValue()); + checkImportVariadicArg(FromAttr->args(), ToAttr->args()); +} + +TEST_P(ImportAttributes, ImportReleaseCapability) { + ReleaseCapabilityAttr *FromAttr, *ToAttr; + importAttr( + "void test(int A1, int A2) __attribute__((release_capability(A1, A2)));", + FromAttr, ToAttr); + checkImportVariadicArg(FromAttr->args(), ToAttr->args()); +} + +TEST_P(ImportAttributes, ImportRequiresCapability) { + RequiresCapabilityAttr *FromAttr, *ToAttr; + importAttr( + "void test(int A1, int A2) __attribute__((requires_capability(A1, A2)));", + FromAttr, ToAttr); + checkImportVariadicArg(FromAttr->args(), ToAttr->args()); +} + +TEST_P(ImportAttributes, ImportNoThreadSafetyAnalysis) { + NoThreadSafetyAnalysisAttr *FromAttr, *ToAttr; + importAttr( + "void test() __attribute__((no_thread_safety_analysis));", FromAttr, + ToAttr); +} + +TEST_P(ImportAttributes, ImportGuardedBy) { + GuardedByAttr *FromAttr, *ToAttr; + importAttr( + R"( + int G; + int test __attribute__((guarded_by(G))); + )", + FromAttr, ToAttr); + checkImported(FromAttr->getArg(), ToAttr->getArg()); +} + +TEST_P(ImportAttributes, ImportPtGuardedBy) { + PtGuardedByAttr *FromAttr, *ToAttr; + importAttr( + R"( + int G; + int *test __attribute__((pt_guarded_by(G))); + )", + FromAttr, ToAttr); + checkImported(FromAttr->getArg(), ToAttr->getArg()); +} + +TEST_P(ImportAttributes, ImportAcquiredAfter) { + AcquiredAfterAttr *FromAttr, *ToAttr; + importAttr( + R"( + struct __attribute__((lockable)) L {}; + L A1; + L A2; + L test __attribute__((acquired_after(A1, A2))); + )", + FromAttr, ToAttr); + checkImportVariadicArg(FromAttr->args(), ToAttr->args()); +} + +TEST_P(ImportAttributes, ImportAcquiredBefore) { + AcquiredBeforeAttr *FromAttr, *ToAttr; + importAttr( + R"( + struct __attribute__((lockable)) L {}; + L A1; + L A2; + L test __attribute__((acquired_before(A1, A2))); + )", + FromAttr, ToAttr); + checkImportVariadicArg(FromAttr->args(), ToAttr->args()); +} + +TEST_P(ImportAttributes, ImportAssertExclusiveLock) { + AssertExclusiveLockAttr *FromAttr, *ToAttr; + importAttr("void test(int A1, int A2) " + "__attribute__((assert_exclusive_lock(A1, A2)));", + FromAttr, ToAttr); + checkImportVariadicArg(FromAttr->args(), ToAttr->args()); +} + +TEST_P(ImportAttributes, ImportAssertSharedLock) { + AssertSharedLockAttr *FromAttr, *ToAttr; + importAttr( + "void test(int A1, int A2) __attribute__((assert_shared_lock(A1, A2)));", + FromAttr, ToAttr); + checkImportVariadicArg(FromAttr->args(), ToAttr->args()); +} + +TEST_P(ImportAttributes, ImportExclusiveTrylockFunction) { + ExclusiveTrylockFunctionAttr *FromAttr, *ToAttr; + importAttr( + "void test(int A1, int A2) __attribute__((exclusive_trylock_function(1, " + "A1, A2)));", + FromAttr, ToAttr); + checkImported(FromAttr->getSuccessValue(), ToAttr->getSuccessValue()); + checkImportVariadicArg(FromAttr->args(), ToAttr->args()); +} + +TEST_P(ImportAttributes, ImportSharedTrylockFunction) { + SharedTrylockFunctionAttr *FromAttr, *ToAttr; + importAttr( + "void test(int A1, int A2) __attribute__((shared_trylock_function(1, A1, " + "A2)));", + FromAttr, ToAttr); + checkImported(FromAttr->getSuccessValue(), ToAttr->getSuccessValue()); + checkImportVariadicArg(FromAttr->args(), ToAttr->args()); +} + +TEST_P(ImportAttributes, ImportLockReturned) { + LockReturnedAttr *FromAttr, *ToAttr; + importAttr( + "void test(int A1) __attribute__((lock_returned(A1)));", FromAttr, + ToAttr); + checkImported(FromAttr->getArg(), ToAttr->getArg()); +} + +TEST_P(ImportAttributes, ImportLocksExcluded) { + LocksExcludedAttr *FromAttr, *ToAttr; + importAttr( + "void test(int A1, int A2) __attribute__((locks_excluded(A1, A2)));", + FromAttr, ToAttr); + checkImportVariadicArg(FromAttr->args(), ToAttr->args()); +} + template auto ExtendWithOptions(const T &Values, const std::vector &Args) { auto Copy = Values;