balazske created this revision. Herald added subscribers: steakhal, whisperity, martong, teemperor, gamesh411, Szelethus, dkrupp. Herald added a reviewer: a.sidorin. Herald added a reviewer: shafik. balazske requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
Attributes of "C/C++ Thread safety attributes" section in Attr.td are added to ASTImporter. The not added attributes from this section do not need special import handling. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D110528 Files: clang/lib/AST/ASTImporter.cpp clang/unittests/AST/ASTImporterTest.cpp
Index: clang/unittests/AST/ASTImporterTest.cpp =================================================================== --- clang/unittests/AST/ASTImporterTest.cpp +++ clang/unittests/AST/ASTImporterTest.cpp @@ -6545,6 +6545,31 @@ EXPECT_EQ(FromAttr->getType()->getName(), ToAttr->getType()->getName()); } +TEST_P(ImportAttributes, ImportGuardedVar) { + GuardedVarAttr *FromAttr, *ToAttr; + importAttr<VarDecl>("int test __attribute__((guarded_var));", FromAttr, + ToAttr); +} + +TEST_P(ImportAttributes, ImportPtGuardedVar) { + PtGuardedVarAttr *FromAttr, *ToAttr; + importAttr<VarDecl>("int *test __attribute__((pt_guarded_var));", FromAttr, + ToAttr); +} + +TEST_P(ImportAttributes, ImportScopedLockable) { + ScopedLockableAttr *FromAttr, *ToAttr; + importAttr<CXXRecordDecl>("struct __attribute__((scoped_lockable)) test {};", + FromAttr, ToAttr); +} + +TEST_P(ImportAttributes, ImportCapability) { + CapabilityAttr *FromAttr, *ToAttr; + importAttr<CXXRecordDecl>( + "struct __attribute__((capability(\"cap\"))) test {};", FromAttr, ToAttr); + EXPECT_EQ(FromAttr->getName(), ToAttr->getName()); +} + TEST_P(ImportAttributes, ImportAssertCapability) { AssertCapabilityAttr *FromAttr, *ToAttr; importAttr<FunctionDecl>( @@ -6553,6 +6578,147 @@ checkImportVariadicArg(FromAttr->args(), ToAttr->args()); } +TEST_P(ImportAttributes, ImportAcquireCapability) { + AcquireCapabilityAttr *FromAttr, *ToAttr; + importAttr<FunctionDecl>( + "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<FunctionDecl>( + "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<FunctionDecl>( + "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<FunctionDecl>( + "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<FunctionDecl>( + "void test() __attribute__((no_thread_safety_analysis));", FromAttr, + ToAttr); +} + +TEST_P(ImportAttributes, ImportGuardedBy) { + GuardedByAttr *FromAttr, *ToAttr; + importAttr<VarDecl>( + R"( + int G; + int test __attribute__((guarded_by(G))); + )", + FromAttr, ToAttr); + checkImported(FromAttr->getArg(), ToAttr->getArg()); +} + +TEST_P(ImportAttributes, ImportPtGuardedBy) { + PtGuardedByAttr *FromAttr, *ToAttr; + importAttr<VarDecl>( + 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<VarDecl>( + 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<VarDecl>( + 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<FunctionDecl>("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<FunctionDecl>( + "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<FunctionDecl>( + "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<FunctionDecl>( + "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<FunctionDecl>( + "void test(int A1) __attribute__((lock_returned(A1)));", FromAttr, + ToAttr); + checkImported(FromAttr->getArg(), ToAttr->getArg()); +} + +TEST_P(ImportAttributes, ImportLocksExcluded) { + LocksExcludedAttr *FromAttr, *ToAttr; + importAttr<FunctionDecl>( + "void test(int A1, int A2) __attribute__((locks_excluded(A1, A2)));", + FromAttr, ToAttr); + checkImportVariadicArg(FromAttr->args(), ToAttr->args()); +} + template <typename T> auto ExtendWithOptions(const T &Values, const std::vector<std::string> &Args) { auto Copy = Values; Index: clang/lib/AST/ASTImporter.cpp =================================================================== --- clang/lib/AST/ASTImporter.cpp +++ clang/lib/AST/ASTImporter.cpp @@ -8574,6 +8574,174 @@ return ToAttrOrErr.takeError(); break; } + case attr::AcquireCapability: { + const auto *From = cast<AcquireCapabilityAttr>(FromAttr); + AttrImporter AI(*this); + Expected<Attr *> 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<TryAcquireCapabilityAttr>(FromAttr); + AttrImporter AI(*this); + Expected<Attr *> 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<ReleaseCapabilityAttr>(FromAttr); + AttrImporter AI(*this); + Expected<Attr *> 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<RequiresCapabilityAttr>(FromAttr); + AttrImporter AI(*this); + Expected<Attr *> 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<GuardedByAttr>(FromAttr); + AttrImporter AI(*this); + Expected<Attr *> 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<PtGuardedByAttr>(FromAttr); + AttrImporter AI(*this); + Expected<Attr *> 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<AcquiredAfterAttr>(FromAttr); + AttrImporter AI(*this); + Expected<Attr *> 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<AcquiredBeforeAttr>(FromAttr); + AttrImporter AI(*this); + Expected<Attr *> 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<AssertExclusiveLockAttr>(FromAttr); + AttrImporter AI(*this); + Expected<Attr *> 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<AssertSharedLockAttr>(FromAttr); + AttrImporter AI(*this); + Expected<Attr *> 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<ExclusiveTrylockFunctionAttr>(FromAttr); + AttrImporter AI(*this); + Expected<Attr *> 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<SharedTrylockFunctionAttr>(FromAttr); + AttrImporter AI(*this); + Expected<Attr *> 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<LockReturnedAttr>(FromAttr); + AttrImporter AI(*this); + Expected<Attr *> 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<LocksExcludedAttr>(FromAttr); + AttrImporter AI(*this); + Expected<Attr *> 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.
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits