forked from OSchip/llvm-project
[clang][ASTImporter] Add import of thread safety attributes.
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. Reviewed By: martong Differential Revision: https://reviews.llvm.org/D110528
This commit is contained in:
parent
471b25e217
commit
bcefea80a4
|
@ -8634,6 +8634,174 @@ Expected<Attr *> ASTImporter::Import(const Attr *FromAttr) {
|
|||
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.
|
||||
|
|
|
@ -6564,6 +6564,31 @@ TEST_P(ASTImporterOptionSpecificTestBase, ImportFormatAttr) {
|
|||
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>(
|
||||
|
@ -6572,6 +6597,147 @@ TEST_P(ImportAttributes, ImportAssertCapability) {
|
|||
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;
|
||||
|
|
Loading…
Reference in New Issue