diff --git a/clang/lib/Sema/SemaSYCLDeclAttr.cpp b/clang/lib/Sema/SemaSYCLDeclAttr.cpp index 58ee6e81534be..22b72b89133d5 100644 --- a/clang/lib/Sema/SemaSYCLDeclAttr.cpp +++ b/clang/lib/Sema/SemaSYCLDeclAttr.cpp @@ -1537,6 +1537,20 @@ void SemaSYCL::addSYCLAddIRAttributesFunctionAttr( if (evaluateAddIRAttributesArgs(Attr->args_begin(), Attr->args_size(), *this, CI)) return; + + // There could be multiple of the same attribute applied to the same + // declaration. If so, we want to merge them. + // If there are still dependent expressions in the attribute, we delay merging + // till after instantiation. + if (!hasDependentExpr(Attr->args_begin(), Attr->args_size()) && + D->hasAttr()) { + Attr = mergeSYCLAddIRAttributesFunctionAttr(D, *Attr); + + // If null is returned, the attribute did not change after merge and we can + // exit. + if (!Attr) + return; + } D->addAttr(Attr); // There are compile-time SYCL properties which we would like to turn into @@ -1574,6 +1588,20 @@ void SemaSYCL::addSYCLAddIRAttributesKernelParameterAttr( if (evaluateAddIRAttributesArgs(Attr->args_begin(), Attr->args_size(), *this, CI)) return; + + // There could be multiple of the same attribute applied to the same argument. + // If so, we want to merge them. + // If there are still dependent expressions in the attribute, we delay merging + // till after instantiation. + if (!hasDependentExpr(Attr->args_begin(), Attr->args_size()) && + D->hasAttr()) { + Attr = mergeSYCLAddIRAttributesKernelParameterAttr(D, *Attr); + + // If null is returned, the attribute did not change after merge and we can + // exit. + if (!Attr) + return; + } D->addAttr(Attr); } @@ -1585,6 +1613,20 @@ void SemaSYCL::addSYCLAddIRAttributesGlobalVariableAttr( if (evaluateAddIRAttributesArgs(Attr->args_begin(), Attr->args_size(), *this, CI)) return; + + // There could be multiple of the same attribute applied to the same global + // variable. If so, we want to merge them. + // If there are still dependent expressions in the attribute, we delay merging + // till after instantiation. + if (!hasDependentExpr(Attr->args_begin(), Attr->args_size()) && + D->hasAttr()) { + Attr = mergeSYCLAddIRAttributesGlobalVariableAttr(D, *Attr); + + // If null is returned, the attribute did not change after merge and we can + // exit. + if (!Attr) + return; + } D->addAttr(Attr); } @@ -2559,14 +2601,19 @@ void SemaSYCL::handleSYCLAddIRAttributesFunctionAttr(Decl *D, addSYCLAddIRAttributesFunctionAttr(D, A, Args); } -static bool hasSameSYCLAddIRAttributes( +static bool hasConflictingSYCLAddIRAttributes( const SmallVector, 4> &LAttrs, const SmallVector, 4> &RAttrs) { - std::set> LNameValSet{LAttrs.begin(), - LAttrs.end()}; - std::set> RNameValSet{RAttrs.begin(), - RAttrs.end()}; - return LNameValSet == RNameValSet; + std::unordered_map LNameValMap; + for (const std::pair &NameValuePair : LAttrs) + LNameValMap[NameValuePair.first] = NameValuePair.second; + + return std::any_of( + RAttrs.begin(), RAttrs.end(), + [&](const std::pair &NameValuePair) { + auto It = LNameValMap.find(NameValuePair.first); + return It != LNameValMap.end() && NameValuePair.second != It->second; + }); } template @@ -2574,15 +2621,19 @@ static bool checkSYCLAddIRAttributesMergeability(const AddIRAttrT &NewAttr, const AddIRAttrT &ExistingAttr, SemaSYCL &S) { ASTContext &Context = S.getASTContext(); - // If there are no dependent argument expressions and the filters or the - // attributes are different, then fail due to differing duplicates. - if (!S.hasDependentExpr(NewAttr.args_begin(), NewAttr.args_size()) && - !S.hasDependentExpr(ExistingAttr.args_begin(), - ExistingAttr.args_size()) && - (NewAttr.getAttributeFilter() != ExistingAttr.getAttributeFilter() || - !hasSameSYCLAddIRAttributes( - NewAttr.getAttributeNameValuePairs(Context), - ExistingAttr.getAttributeNameValuePairs(Context)))) { + + // If there are dependent argument expressions, then merging cannot be done + // yet. In that case, it is deferred till after instantiation. + if (S.hasDependentExpr(NewAttr.args_begin(), NewAttr.args_size()) || + S.hasDependentExpr(ExistingAttr.args_begin(), ExistingAttr.args_size())) + return true; + + // If the filters differ or the attributes are conflicting, then fail due to + // differing duplicates. + if (NewAttr.getAttributeFilter() != ExistingAttr.getAttributeFilter() || + hasConflictingSYCLAddIRAttributes( + NewAttr.getAttributeNameValuePairs(Context), + ExistingAttr.getAttributeNameValuePairs(Context))) { S.Diag(ExistingAttr.getLoc(), diag::err_duplicate_attribute) << &NewAttr; S.Diag(NewAttr.getLoc(), diag::note_conflicting_attribute); return true; @@ -2590,12 +2641,58 @@ static bool checkSYCLAddIRAttributesMergeability(const AddIRAttrT &NewAttr, return false; } +template +static AddIRAttrT *getMergedSYCLAddIRAttribute(const AddIRAttrT &Attr1, + const AddIRAttrT &Attr2, + SemaSYCL &S) { + ASTContext &Context = S.getASTContext(); + bool AttrHasFilterList = Attr1.hasFilterList(); + + // Get the vectors of name-value-pairs here so we can create string references + // to them for the map. + llvm::SmallVector, 4> Attr1NVPairs = + Attr1.getAttributeNameValuePairs(Context); + llvm::SmallVector, 4> Attr2NVPairs = + Attr2.getAttributeNameValuePairs(Context); + + // Collect all the unique attribute names and their corresponding values. This + // relies on the uniqueness having been confirmed first and that the + // attributes appear in the same order as in the name-value-pairs. + llvm::SmallMapVector, 4> AttrExprByName; + for (const auto &[Attr, NVPairs] : {std::make_pair(Attr1, Attr1NVPairs), + std::make_pair(Attr2, Attr2NVPairs)}) { + for (size_t I = 0; I < NVPairs.size(); ++I) { + AttrExprByName[NVPairs[I].first] = std::make_pair( + (Attr.args_begin() + AttrHasFilterList)[I], + (Attr.args_begin() + AttrHasFilterList + (Attr.args_size() / 2))[I]); + } + } + + // Create a list of new arguments, starting with the filter if present. + llvm::SmallVector NewArgs; + NewArgs.resize(AttrExprByName.size() * 2 + AttrHasFilterList); + if (AttrHasFilterList) + NewArgs[0] = *Attr1.args_begin(); + + // Then insert all the unique attributes found previously. + for (size_t I = 0; I < AttrExprByName.size(); ++I) { + const std::pair &Exprs = AttrExprByName.begin()[I].second; + NewArgs[I + AttrHasFilterList] = Exprs.first; + NewArgs[I + AttrExprByName.size() + AttrHasFilterList] = Exprs.second; + } + + return AddIRAttrT::Create(Context, NewArgs.data(), NewArgs.size(), Attr1); +} + SYCLAddIRAttributesFunctionAttr *SemaSYCL::mergeSYCLAddIRAttributesFunctionAttr( Decl *D, const SYCLAddIRAttributesFunctionAttr &A) { if (const auto *ExistingAttr = D->getAttr()) { - checkSYCLAddIRAttributesMergeability(A, *ExistingAttr, *this); - return nullptr; + if (checkSYCLAddIRAttributesMergeability(A, *ExistingAttr, *this)) + return nullptr; + + D->dropAttr(); + return getMergedSYCLAddIRAttribute(A, *ExistingAttr, *this); } ASTContext &Context = getASTContext(); return A.clone(Context); @@ -2618,8 +2715,11 @@ SemaSYCL::mergeSYCLAddIRAttributesKernelParameterAttr( Decl *D, const SYCLAddIRAttributesKernelParameterAttr &A) { if (const auto *ExistingAttr = D->getAttr()) { - checkSYCLAddIRAttributesMergeability(A, *ExistingAttr, *this); - return nullptr; + if (checkSYCLAddIRAttributesMergeability(A, *ExistingAttr, *this)) + return nullptr; + + D->dropAttr(); + return getMergedSYCLAddIRAttribute(A, *ExistingAttr, *this); } ASTContext &Context = getASTContext(); return A.clone(Context); @@ -2642,8 +2742,11 @@ SemaSYCL::mergeSYCLAddIRAttributesGlobalVariableAttr( Decl *D, const SYCLAddIRAttributesGlobalVariableAttr &A) { if (const auto *ExistingAttr = D->getAttr()) { - checkSYCLAddIRAttributesMergeability(A, *ExistingAttr, *this); - return nullptr; + if (checkSYCLAddIRAttributesMergeability(A, *ExistingAttr, *this)) + return nullptr; + + D->dropAttr(); + return getMergedSYCLAddIRAttribute(A, *ExistingAttr, *this); } ASTContext &Context = getASTContext(); return A.clone(Context); diff --git a/clang/test/AST/ast-attr-add-ir-attributes-merge.cpp b/clang/test/AST/ast-attr-add-ir-attributes-merge.cpp index 2773a30e1e20e..5211295138e9d 100644 --- a/clang/test/AST/ast-attr-add-ir-attributes-merge.cpp +++ b/clang/test/AST/ast-attr-add-ir-attributes-merge.cpp @@ -33,6 +33,289 @@ [[__sycl_detail__::add_ir_attributes_function("Attr1", "Attr2", 1, true)]] void FunctionRedecl1(); void FunctionRedecl1(); +// CHECK: FunctionDecl [[FunctionRedecl2ID1:0x[0-9a-f]+]] {{.*}} FunctionRedecl2 'void ()' +// CHECK-NEXT: FunctionDecl [[FunctionRedecl2ID2:0x[0-9a-f]+]] prev [[FunctionRedecl2ID1]] {{.*}} FunctionRedecl2 'void ()' +// CHECK-NEXT: SYCLAddIRAttributesFunctionAttr +// CHECK-NEXT: ConstantExpr {{.*}} 'const char[6]' lvalue +// CHECK-NEXT: value: LValue +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr1" +// CHECK-NEXT: ConstantExpr {{.*}} 'const char[6]' lvalue +// CHECK-NEXT: value: LValue +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr2" +// CHECK-NEXT: ConstantExpr {{.*}} 'int' +// CHECK-NEXT: value: Int 1 +// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 1 +// CHECK-NEXT: ConstantExpr {{.*}} 'bool' +// CHECK-NEXT: value: Int 1 +// CHECK-NEXT: CXXBoolLiteralExpr {{.*}} 'bool' true +// CHECK-NEXT: FunctionDecl [[FunctionRedecl2ID3:0x[0-9a-f]+]] prev [[FunctionRedecl2ID2]] {{.*}} FunctionRedecl2 'void ()' +// CHECK-NEXT: SYCLAddIRAttributesFunctionAttr +// CHECK-NEXT: ConstantExpr {{.*}} 'const char[6]' lvalue +// CHECK-NEXT: value: LValue +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr1" +// CHECK-NEXT: ConstantExpr {{.*}} 'const char[6]' lvalue +// CHECK-NEXT: value: LValue +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr2" +// CHECK-NEXT: ConstantExpr {{.*}} 'int' +// CHECK-NEXT: value: Int 1 +// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 1 +// CHECK-NEXT: ConstantExpr {{.*}} 'bool' +// CHECK-NEXT: value: Int 1 +// CHECK-NEXT: CXXBoolLiteralExpr {{.*}} 'bool' true +// CHECK-NEXT: FunctionDecl [[FunctionRedecl2ID4:0x[0-9a-f]+]] prev [[FunctionRedecl2ID3]] {{.*}} FunctionRedecl2 'void ()' +// CHECK-NEXT: SYCLAddIRAttributesFunctionAttr +// CHECK-NEXT: ConstantExpr {{.*}} 'const char[6]' lvalue +// CHECK-NEXT: value: LValue +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr1" +// CHECK-NEXT: ConstantExpr {{.*}} 'const char[6]' lvalue +// CHECK-NEXT: value: LValue +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr2" +// CHECK-NEXT: ConstantExpr {{.*}} 'int' +// CHECK-NEXT: value: Int 1 +// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 1 +// CHECK-NEXT: ConstantExpr {{.*}} 'bool' +// CHECK-NEXT: value: Int 1 +// CHECK-NEXT: CXXBoolLiteralExpr {{.*}} 'bool' true +// CHECK-NEXT: FunctionDecl {{.*}} prev [[FunctionRedecl2ID4]] {{.*}} FunctionRedecl2 'void ()' +// CHECK-NEXT: CompoundStmt +// CHECK-NEXT: SYCLAddIRAttributesFunctionAttr +// CHECK-NEXT: ConstantExpr {{.*}} 'const char[6]' lvalue +// CHECK-NEXT: value: LValue +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr1" +// CHECK-NEXT: ConstantExpr {{.*}} 'const char[6]' lvalue +// CHECK-NEXT: value: LValue +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr2" +// CHECK-NEXT: ConstantExpr {{.*}} 'const char[6]' lvalue +// CHECK-NEXT: value: LValue +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr3" +// CHECK-NEXT: ConstantExpr {{.*}} 'int' +// CHECK-NEXT: value: Int 1 +// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 1 +// CHECK-NEXT: ConstantExpr {{.*}} 'bool' +// CHECK-NEXT: value: Int 1 +// CHECK-NEXT: CXXBoolLiteralExpr {{.*}} 'bool' true +// CHECK-NEXT: ConstantExpr {{.*}} 'bool' +// CHECK-NEXT: value: Int 0 +// CHECK-NEXT: CXXBoolLiteralExpr {{.*}} 'bool' false +void FunctionRedecl2(); +[[__sycl_detail__::add_ir_attributes_function("Attr1", "Attr2", 1, true)]] void FunctionRedecl2(); +[[__sycl_detail__::add_ir_attributes_function("Attr1", "Attr2", 1, true)]] void FunctionRedecl2(); +[[__sycl_detail__::add_ir_attributes_function("Attr2", "Attr1", true, 1)]] void FunctionRedecl2(); +[[__sycl_detail__::add_ir_attributes_function("Attr3", false)]] void FunctionRedecl2(){}; + +// CHECK: FunctionDecl [[FunctionRedecl3ID1:0x[0-9a-f]+]] {{.*}} FunctionRedecl3 'void ()' +// CHECK-NEXT: SYCLAddIRAttributesFunctionAttr +// CHECK-NEXT: InitListExpr {{.*}} 'void' +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr3" +// CHECK-NEXT: ConstantExpr {{.*}} 'const char[6]' lvalue +// CHECK-NEXT: value: LValue +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr1" +// CHECK-NEXT: ConstantExpr {{.*}} 'const char[6]' lvalue +// CHECK-NEXT: value: LValue +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr2" +// CHECK-NEXT: ConstantExpr {{.*}} 'int' +// CHECK-NEXT: value: Int 1 +// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 1 +// CHECK-NEXT: ConstantExpr {{.*}} 'bool' +// CHECK-NEXT: value: Int 1 +// CHECK-NEXT: CXXBoolLiteralExpr {{.*}} 'bool' true +// CHECK-NEXT: FunctionDecl {{.*}} prev [[FunctionRedecl3ID1]] {{.*}} FunctionRedecl3 'void ()' +// CHECK-NEXT: SYCLAddIRAttributesFunctionAttr {{.*}} Inherited +// CHECK-NEXT: InitListExpr {{.*}} 'void' +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr3" +// CHECK-NEXT: ConstantExpr {{.*}} 'const char[6]' lvalue +// CHECK-NEXT: value: LValue +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr1" +// CHECK-NEXT: ConstantExpr {{.*}} 'const char[6]' lvalue +// CHECK-NEXT: value: LValue +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr2" +// CHECK-NEXT: ConstantExpr {{.*}} 'int' +// CHECK-NEXT: value: Int 1 +// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 1 +// CHECK-NEXT: ConstantExpr {{.*}} 'bool' +// CHECK-NEXT: value: Int 1 +// CHECK-NEXT: CXXBoolLiteralExpr {{.*}} 'bool' true +[[__sycl_detail__::add_ir_attributes_function({"Attr3"}, "Attr1", "Attr2", 1, true)]] void FunctionRedecl3(); +void FunctionRedecl3(); + +// CHECK: FunctionDecl [[FunctionRedecl4ID1:0x[0-9a-f]+]] {{.*}} FunctionRedecl4 'void ()' +// CHECK-NEXT: FunctionDecl [[FunctionRedecl4ID2:0x[0-9a-f]+]] prev [[FunctionRedecl4ID1]] {{.*}} FunctionRedecl4 'void ()' +// CHECK-NEXT: SYCLAddIRAttributesFunctionAttr +// CHECK-NEXT: InitListExpr {{.*}} 'void' +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr1" +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr3" +// CHECK-NEXT: ConstantExpr {{.*}} 'const char[6]' lvalue +// CHECK-NEXT: value: LValue +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr1" +// CHECK-NEXT: ConstantExpr {{.*}} 'const char[6]' lvalue +// CHECK-NEXT: value: LValue +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr2" +// CHECK-NEXT: ConstantExpr {{.*}} 'int' +// CHECK-NEXT: value: Int 1 +// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 1 +// CHECK-NEXT: ConstantExpr {{.*}} 'bool' +// CHECK-NEXT: value: Int 1 +// CHECK-NEXT: CXXBoolLiteralExpr {{.*}} 'bool' true +// CHECK-NEXT: FunctionDecl [[FunctionRedecl4ID3:0x[0-9a-f]+]] prev [[FunctionRedecl4ID2]] {{.*}} FunctionRedecl4 'void ()' +// CHECK-NEXT: SYCLAddIRAttributesFunctionAttr {{.*}} Inherited +// CHECK-NEXT: InitListExpr {{.*}} 'void' +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr1" +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr3" +// CHECK-NEXT: ConstantExpr {{.*}} 'const char[6]' lvalue +// CHECK-NEXT: value: LValue +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr1" +// CHECK-NEXT: ConstantExpr {{.*}} 'const char[6]' lvalue +// CHECK-NEXT: value: LValue +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr2" +// CHECK-NEXT: ConstantExpr {{.*}} 'int' +// CHECK-NEXT: value: Int 1 +// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 1 +// CHECK-NEXT: ConstantExpr {{.*}} 'bool' +// CHECK-NEXT: value: Int 1 +// CHECK-NEXT: CXXBoolLiteralExpr {{.*}} 'bool' true +// CHECK-NEXT: FunctionDecl [[FunctionRedecl4ID4:0x[0-9a-f]+]] prev [[FunctionRedecl4ID3]] {{.*}} FunctionRedecl4 'void ()' +// CHECK-NEXT: SYCLAddIRAttributesFunctionAttr {{.*}} Inherited +// CHECK-NEXT: InitListExpr {{.*}} 'void' +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr1" +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr3" +// CHECK-NEXT: ConstantExpr {{.*}} 'const char[6]' lvalue +// CHECK-NEXT: value: LValue +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr1" +// CHECK-NEXT: ConstantExpr {{.*}} 'const char[6]' lvalue +// CHECK-NEXT: value: LValue +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr2" +// CHECK-NEXT: ConstantExpr {{.*}} 'int' +// CHECK-NEXT: value: Int 1 +// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 1 +// CHECK-NEXT: ConstantExpr {{.*}} 'bool' +// CHECK-NEXT: value: Int 1 +// CHECK-NEXT: CXXBoolLiteralExpr {{.*}} 'bool' true +// CHECK-NEXT: FunctionDecl [[FunctionRedecl4ID5:0x[0-9a-f]+]] prev [[FunctionRedecl4ID4]] {{.*}} FunctionRedecl4 'void ()' +// CHECK-NEXT: SYCLAddIRAttributesFunctionAttr {{.*}} Inherited +// CHECK-NEXT: InitListExpr {{.*}} 'void' +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr1" +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr3" +// CHECK-NEXT: ConstantExpr {{.*}} 'const char[6]' lvalue +// CHECK-NEXT: value: LValue +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr1" +// CHECK-NEXT: ConstantExpr {{.*}} 'const char[6]' lvalue +// CHECK-NEXT: value: LValue +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr2" +// CHECK-NEXT: ConstantExpr {{.*}} 'int' +// CHECK-NEXT: value: Int 1 +// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 1 +// CHECK-NEXT: ConstantExpr {{.*}} 'bool' +// CHECK-NEXT: value: Int 1 +// CHECK-NEXT: CXXBoolLiteralExpr {{.*}} 'bool' true +// CHECK-NEXT: FunctionDecl {{.*}} prev [[FunctionRedecl4ID5]] {{.*}} FunctionRedecl4 'void ()' +// CHECK-NEXT: CompoundStmt +// CHECK-NEXT: SYCLAddIRAttributesFunctionAttr {{.*}} Inherited +// CHECK-NEXT: InitListExpr {{.*}} 'void' +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr1" +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr3" +// CHECK-NEXT: ConstantExpr {{.*}} 'const char[6]' lvalue +// CHECK-NEXT: value: LValue +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr1" +// CHECK-NEXT: ConstantExpr {{.*}} 'const char[6]' lvalue +// CHECK-NEXT: value: LValue +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr2" +// CHECK-NEXT: ConstantExpr {{.*}} 'const char[6]' lvalue +// CHECK-NEXT: value: LValue +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr3" +// CHECK-NEXT: ConstantExpr {{.*}} 'int' +// CHECK-NEXT: value: Int 1 +// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 1 +// CHECK-NEXT: ConstantExpr {{.*}} 'bool' +// CHECK-NEXT: value: Int 1 +// CHECK-NEXT: CXXBoolLiteralExpr {{.*}} 'bool' true +// CHECK-NEXT: ConstantExpr {{.*}} 'bool' +// CHECK-NEXT: value: Int 0 +// CHECK-NEXT: CXXBoolLiteralExpr {{.*}} 'bool' false +void FunctionRedecl4(); +[[__sycl_detail__::add_ir_attributes_function({"Attr1", "Attr3"}, "Attr1", "Attr2", 1, true)]] void FunctionRedecl4(); +[[__sycl_detail__::add_ir_attributes_function({"Attr1", "Attr3"}, "Attr1", "Attr2", 1, true)]] void FunctionRedecl4(); +[[__sycl_detail__::add_ir_attributes_function({"Attr1", "Attr3"}, "Attr2", "Attr1", true, 1)]] void FunctionRedecl4(); +[[__sycl_detail__::add_ir_attributes_function({"Attr3", "Attr1"}, "Attr1", "Attr2", 1, true)]] void FunctionRedecl4(); +[[__sycl_detail__::add_ir_attributes_function({"Attr1", "Attr3"}, "Attr3", false)]] void FunctionRedecl4(){}; + +// CHECK: FunctionDecl {{.*}} FunctionDecl2 'void ()' +// CHECK-NEXT: CompoundStmt +// CHECK-NEXT: SYCLAddIRAttributesFunctionAttr +// CHECK-NEXT: ConstantExpr {{.*}} 'const char[6]' lvalue +// CHECK-NEXT: value: LValue +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr3" +// CHECK-NEXT: ConstantExpr {{.*}} 'const char[6]' lvalue +// CHECK-NEXT: value: LValue +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr2" +// CHECK-NEXT: ConstantExpr {{.*}} 'const char[6]' lvalue +// CHECK-NEXT: value: LValue +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr1" +// CHECK-NEXT: ConstantExpr {{.*}} 'bool' +// CHECK-NEXT: value: Int 0 +// CHECK-NEXT: CXXBoolLiteralExpr {{.*}} 'bool' false +// CHECK-NEXT: ConstantExpr {{.*}} 'bool' +// CHECK-NEXT: value: Int 1 +// CHECK-NEXT: CXXBoolLiteralExpr {{.*}} 'bool' true +// CHECK-NEXT: ConstantExpr {{.*}} 'int' +// CHECK-NEXT: value: Int 1 +// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 1 +[[__sycl_detail__::add_ir_attributes_function("Attr1", "Attr2", 1, true)]] +[[__sycl_detail__::add_ir_attributes_function("Attr1", "Attr2", 1, true)]] +[[__sycl_detail__::add_ir_attributes_function("Attr2", "Attr1", true, 1)]] +[[__sycl_detail__::add_ir_attributes_function("Attr3", false)]] +void FunctionDecl2(){}; + +// CHECK: FunctionDecl {{.*}} FunctionDecl3 'void ()' +// CHECK-NEXT: CompoundStmt {{.*}} +// CHECK-NEXT: SYCLAddIRAttributesFunctionAttr {{.*}} +// CHECK-NEXT: InitListExpr {{.*}} 'void' +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr3" +// CHECK-NEXT: ConstantExpr {{.*}} 'const char[6]' lvalue +// CHECK-NEXT: value: LValue +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr1" +// CHECK-NEXT: ConstantExpr {{.*}} 'const char[6]' lvalue +// CHECK-NEXT: value: LValue +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr2" +// CHECK-NEXT: ConstantExpr {{.*}} 'int' +// CHECK-NEXT: value: Int 1 +// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 1 +// CHECK-NEXT: ConstantExpr {{.*}} 'bool' +// CHECK-NEXT: value: Int 1 +// CHECK-NEXT: CXXBoolLiteralExpr {{.*}} 'bool' true +[[__sycl_detail__::add_ir_attributes_function({"Attr3"}, "Attr1", "Attr2", 1, true)]] +void FunctionDecl3(){}; + +// CHECK: FunctionDecl {{.*}} FunctionDecl4 'void ()' +// CHECK-NEXT: CompoundStmt {{.*}} +// CHECK-NEXT: SYCLAddIRAttributesFunctionAttr +// CHECK-NEXT: InitListExpr {{.*}} 'void' +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr1" +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr3" +// CHECK-NEXT: ConstantExpr {{.*}} 'const char[6]' lvalue +// CHECK-NEXT: value: LValue +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr3" +// CHECK-NEXT: ConstantExpr {{.*}} 'const char[6]' lvalue +// CHECK-NEXT: value: LValue +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr1" +// CHECK-NEXT: ConstantExpr {{.*}} 'const char[6]' lvalue +// CHECK-NEXT: value: LValue +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr2" +// CHECK-NEXT: ConstantExpr {{.*}} 'bool' +// CHECK-NEXT: value: Int 0 +// CHECK-NEXT: CXXBoolLiteralExpr {{.*}} 'bool' false +// CHECK-NEXT: ConstantExpr {{.*}} 'int' +// CHECK-NEXT: value: Int 1 +// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 1 +// CHECK-NEXT: ConstantExpr {{.*}} 'bool' +// CHECK-NEXT: value: Int 1 +// CHECK-NEXT: CXXBoolLiteralExpr {{.*}} 'bool' true +[[__sycl_detail__::add_ir_attributes_function({"Attr1", "Attr3"}, "Attr1", "Attr2", 1, true)]] +[[__sycl_detail__::add_ir_attributes_function({"Attr1", "Attr3"}, "Attr1", "Attr2", 1, true)]] +[[__sycl_detail__::add_ir_attributes_function({"Attr1", "Attr3"}, "Attr2", "Attr1", true, 1)]] +[[__sycl_detail__::add_ir_attributes_function({"Attr3", "Attr1"}, "Attr1", "Attr2", 1, true)]] +[[__sycl_detail__::add_ir_attributes_function({"Attr1", "Attr3"}, "Attr3", false)]] +void FunctionDecl4(){}; + // CHECK: CXXRecordDecl [[GlobalVarStructRedecl1ID1:0x[0-9a-f]+]] {{.*}} struct GlobalVarStructRedecl1 // CHECK-NEXT: SYCLAddIRAttributesGlobalVariableAttr // CHECK-NEXT: ConstantExpr {{.*}} 'const char[6]' lvalue @@ -47,7 +330,74 @@ void FunctionRedecl1(); // CHECK-NEXT: ConstantExpr {{.*}} 'bool' // CHECK-NEXT: value: Int 1 // CHECK-NEXT: CXXBoolLiteralExpr {{.*}} 'bool' true -// CHECK-NEXT: CXXRecordDecl {{.*}} prev [[GlobalVarStructRedecl1ID1]] {{.*}} struct GlobalVarStructRedecl1 +// CHECK-NEXT: CXXRecordDecl {{.*}} prev [[GlobalVarStructRedecl1ID1]] {{.*}} struct GlobalVarStructRedecl1 +// CHECK-NEXT: SYCLAddIRAttributesGlobalVariableAttr +// CHECK-NEXT: ConstantExpr {{.*}} 'const char[6]' lvalue +// CHECK-NEXT: value: LValue +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr1" +// CHECK-NEXT: ConstantExpr {{.*}} 'const char[6]' lvalue +// CHECK-NEXT: value: LValue +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr2" +// CHECK-NEXT: ConstantExpr {{.*}} 'int' +// CHECK-NEXT: value: Int 1 +// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 1 +// CHECK-NEXT: ConstantExpr {{.*}} 'bool' +// CHECK-NEXT: value: Int 1 +// CHECK-NEXT: CXXBoolLiteralExpr {{.*}} 'bool' true +struct [[__sycl_detail__::add_ir_attributes_global_variable("Attr1", "Attr2", 1, true)]] GlobalVarStructRedecl1; +struct GlobalVarStructRedecl1; + +// CHECK: CXXRecordDecl [[GlobalVarStructRedecl2ID1:0x[0-9a-f]+]] {{.*}} struct GlobalVarStructRedecl2 +// CHECK-NEXT: CXXRecordDecl [[GlobalVarStructRedecl2ID2:0x[0-9a-f]+]] prev [[GlobalVarStructRedecl2ID1]] {{.*}} struct GlobalVarStructRedecl2 +// CHECK-NEXT: SYCLAddIRAttributesGlobalVariableAttr +// CHECK-NEXT: ConstantExpr {{.*}} 'const char[6]' lvalue +// CHECK-NEXT: value: LValue +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr1" +// CHECK-NEXT: ConstantExpr {{.*}} 'const char[6]' lvalue +// CHECK-NEXT: value: LValue +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr2" +// CHECK-NEXT: ConstantExpr {{.*}} 'int' +// CHECK-NEXT: value: Int 1 +// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 1 +// CHECK-NEXT: ConstantExpr {{.*}} 'bool' +// CHECK-NEXT: value: Int 1 +// CHECK-NEXT: CXXBoolLiteralExpr {{.*}} 'bool' true +// CHECK-NEXT: CXXRecordDecl [[GlobalVarStructRedecl2ID3:0x[0-9a-f]+]] prev [[GlobalVarStructRedecl2ID2]] {{.*}} struct GlobalVarStructRedecl2 +// CHECK-NEXT: SYCLAddIRAttributesGlobalVariableAttr +// CHECK-NEXT: ConstantExpr {{.*}} 'const char[6]' lvalue +// CHECK-NEXT: value: LValue +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr1" +// CHECK-NEXT: ConstantExpr {{.*}} 'const char[6]' lvalue +// CHECK-NEXT: value: LValue +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr2" +// CHECK-NEXT: ConstantExpr {{.*}} 'int' +// CHECK-NEXT: value: Int 1 +// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 1 +// CHECK-NEXT: ConstantExpr {{.*}} 'bool' +// CHECK-NEXT: value: Int 1 +// CHECK-NEXT: CXXBoolLiteralExpr {{.*}} 'bool' true +// CHECK-NEXT: CXXRecordDecl [[GlobalVarStructRedecl2ID4:0x[0-9a-f]+]] prev [[GlobalVarStructRedecl2ID3]] {{.*}} struct GlobalVarStructRedecl2 +// CHECK-NEXT: SYCLAddIRAttributesGlobalVariableAttr +// CHECK-NEXT: ConstantExpr {{.*}} 'const char[6]' lvalue +// CHECK-NEXT: value: LValue +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr1" +// CHECK-NEXT: ConstantExpr {{.*}} 'const char[6]' lvalue +// CHECK-NEXT: value: LValue +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr2" +// CHECK-NEXT: ConstantExpr {{.*}} 'int' +// CHECK-NEXT: value: Int 1 +// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 1 +// CHECK-NEXT: ConstantExpr {{.*}} 'bool' +// CHECK-NEXT: value: Int 1 +// CHECK-NEXT: CXXBoolLiteralExpr {{.*}} 'bool' true +// CHECK-NEXT: CXXRecordDecl {{.*}} prev [[GlobalVarStructRedecl2ID4]] {{.*}} struct GlobalVarStructRedecl2 definition +// CHECK-NEXT: DefinitionData +// CHECK-NEXT: DefaultConstructor +// CHECK-NEXT: CopyConstructor +// CHECK-NEXT: MoveConstructor +// CHECK-NEXT: CopyAssignment +// CHECK-NEXT: MoveAssignment +// CHECK-NEXT: Destructor // CHECK-NEXT: SYCLAddIRAttributesGlobalVariableAttr // CHECK-NEXT: ConstantExpr {{.*}} 'const char[6]' lvalue // CHECK-NEXT: value: LValue @@ -55,14 +405,246 @@ void FunctionRedecl1(); // CHECK-NEXT: ConstantExpr {{.*}} 'const char[6]' lvalue // CHECK-NEXT: value: LValue // CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr2" +// CHECK-NEXT: ConstantExpr {{.*}} 'const char[6]' lvalue +// CHECK-NEXT: value: LValue +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr3" // CHECK-NEXT: ConstantExpr {{.*}} 'int' // CHECK-NEXT: value: Int 1 // CHECK-NEXT: IntegerLiteral {{.*}} 'int' 1 // CHECK-NEXT: ConstantExpr {{.*}} 'bool' // CHECK-NEXT: value: Int 1 // CHECK-NEXT: CXXBoolLiteralExpr {{.*}} 'bool' true -struct [[__sycl_detail__::add_ir_attributes_global_variable("Attr1", "Attr2", 1, true)]] GlobalVarStructRedecl1; -struct GlobalVarStructRedecl1; +// CHECK-NEXT: ConstantExpr {{.*}} 'bool' +// CHECK-NEXT: value: Int 0 +// CHECK-NEXT: CXXBoolLiteralExpr {{.*}} 'bool' false +// CHECK-NEXT: CXXRecordDecl {{.*}} implicit struct GlobalVarStructRedecl2 +struct GlobalVarStructRedecl2; +struct [[__sycl_detail__::add_ir_attributes_global_variable("Attr1", "Attr2", 1, true)]] GlobalVarStructRedecl2; +struct [[__sycl_detail__::add_ir_attributes_global_variable("Attr1", "Attr2", 1, true)]] GlobalVarStructRedecl2; +struct [[__sycl_detail__::add_ir_attributes_global_variable("Attr2", "Attr1", true, 1)]] GlobalVarStructRedecl2; +struct [[__sycl_detail__::add_ir_attributes_global_variable("Attr3", false)]] GlobalVarStructRedecl2{}; + +// CHECK: CXXRecordDecl [[GlobalVarStructRedecl3ID1:0x[0-9a-f]+]] {{.*}} struct GlobalVarStructRedecl3 +// CHECK-NEXT: CXXRecordDecl [[GlobalVarStructRedecl3ID2:0x[0-9a-f]+]] prev [[GlobalVarStructRedecl3ID1]] {{.*}} struct GlobalVarStructRedecl3 +// CHECK-NEXT: SYCLAddIRAttributesGlobalVariableAttr +// CHECK-NEXT: ConstantExpr {{.*}} 'const char[6]' lvalue +// CHECK-NEXT: value: LValue +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr1" +// CHECK-NEXT: ConstantExpr {{.*}} 'const char[6]' lvalue +// CHECK-NEXT: value: LValue +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr2" +// CHECK-NEXT: ConstantExpr {{.*}} 'int' +// CHECK-NEXT: value: Int 1 +// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 1 +// CHECK-NEXT: ConstantExpr {{.*}} 'bool' +// CHECK-NEXT: value: Int 1 +// CHECK-NEXT: CXXBoolLiteralExpr {{.*}} 'bool' true +// CHECK-NEXT: CXXRecordDecl [[GlobalVarStructRedecl3ID3:0x[0-9a-f]+]] prev [[GlobalVarStructRedecl3ID2]] {{.*}} struct GlobalVarStructRedecl3 +// CHECK-NEXT: SYCLAddIRAttributesGlobalVariableAttr {{.*}} Inherited +// CHECK-NEXT: ConstantExpr {{.*}} 'const char[6]' lvalue +// CHECK-NEXT: value: LValue +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr1" +// CHECK-NEXT: ConstantExpr {{.*}} 'const char[6]' lvalue +// CHECK-NEXT: value: LValue +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr2" +// CHECK-NEXT: ConstantExpr {{.*}} 'int' +// CHECK-NEXT: value: Int 1 +// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 1 +// CHECK-NEXT: ConstantExpr {{.*}} 'bool' +// CHECK-NEXT: value: Int 1 +// CHECK-NEXT: CXXBoolLiteralExpr {{.*}} 'bool' true +// CHECK-NEXT: CXXRecordDecl [[GlobalVarStructRedecl3ID4:0x[0-9a-f]+]] prev [[GlobalVarStructRedecl3ID3]] {{.*}} struct GlobalVarStructRedecl3 +// CHECK-NEXT: SYCLAddIRAttributesGlobalVariableAttr {{.*}} Inherited +// CHECK-NEXT: ConstantExpr {{.*}} 'const char[6]' lvalue +// CHECK-NEXT: value: LValue +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr1" +// CHECK-NEXT: ConstantExpr {{.*}} 'const char[6]' lvalue +// CHECK-NEXT: value: LValue +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr2" +// CHECK-NEXT: ConstantExpr {{.*}} 'int' +// CHECK-NEXT: value: Int 1 +// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 1 +// CHECK-NEXT: ConstantExpr {{.*}} 'bool' +// CHECK-NEXT: value: Int 1 +// CHECK-NEXT: CXXBoolLiteralExpr {{.*}} 'bool' true +// CHECK-NEXT: CXXRecordDecl {{.*}} prev [[GlobalVarStructRedecl3ID4]] {{.*}} struct GlobalVarStructRedecl3 definition +// CHECK-NEXT: DefinitionData +// CHECK-NEXT: DefaultConstructor +// CHECK-NEXT: CopyConstructor +// CHECK-NEXT: MoveConstructor +// CHECK-NEXT: CopyAssignment +// CHECK-NEXT: MoveAssignment +// CHECK-NEXT: Destructor +// CHECK-NEXT: SYCLAddIRAttributesGlobalVariableAttr {{.*}} Inherited +// CHECK-NEXT: ConstantExpr {{.*}} 'const char[6]' lvalue +// CHECK-NEXT: value: LValue +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr1" +// CHECK-NEXT: ConstantExpr {{.*}} 'const char[6]' lvalue +// CHECK-NEXT: value: LValue +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr2" +// CHECK-NEXT: ConstantExpr {{.*}} 'const char[6]' lvalue +// CHECK-NEXT: value: LValue +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr3" +// CHECK-NEXT: ConstantExpr {{.*}} 'int' +// CHECK-NEXT: value: Int 1 +// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 1 +// CHECK-NEXT: ConstantExpr {{.*}} 'bool' +// CHECK-NEXT: value: Int 1 +// CHECK-NEXT: CXXBoolLiteralExpr {{.*}} 'bool' true +// CHECK-NEXT: ConstantExpr {{.*}} 'bool' +// CHECK-NEXT: value: Int 0 +// CHECK-NEXT: CXXBoolLiteralExpr {{.*}} 'bool' false +// CHECK-NEXT: CXXRecordDecl {{.*}} implicit struct GlobalVarStructRedecl3 +struct GlobalVarStructRedecl3; +struct [[__sycl_detail__::add_ir_attributes_global_variable("Attr1", "Attr2", 1, true)]] GlobalVarStructRedecl3; +struct [[__sycl_detail__::add_ir_attributes_global_variable("Attr1", "Attr2", 1, true)]] GlobalVarStructRedecl3; +struct [[__sycl_detail__::add_ir_attributes_global_variable("Attr2", "Attr1", true, 1)]] GlobalVarStructRedecl3; +struct [[__sycl_detail__::add_ir_attributes_global_variable("Attr3", false)]] GlobalVarStructRedecl3{}; + +// CHECK: CXXRecordDecl [[GlobalVarStructRedecl4ID1:0x[0-9a-f]+]] {{.*}} struct GlobalVarStructRedecl4 +// CHECK-NEXT: SYCLAddIRAttributesGlobalVariableAttr +// CHECK-NEXT: InitListExpr {{.*}} 'void' +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr3" +// CHECK-NEXT: ConstantExpr {{.*}} 'const char[6]' lvalue +// CHECK-NEXT: value: LValue +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr1" +// CHECK-NEXT: ConstantExpr {{.*}} 'const char[6]' lvalue +// CHECK-NEXT: value: LValue +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr2" +// CHECK-NEXT: ConstantExpr {{.*}} 'int' +// CHECK-NEXT: value: Int 1 +// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 1 +// CHECK-NEXT: ConstantExpr {{.*}} 'bool' +// CHECK-NEXT: value: Int 1 +// CHECK-NEXT: CXXBoolLiteralExpr {{.*}} 'bool' true +// CHECK-NEXT: CXXRecordDecl {{.*}} prev [[GlobalVarStructRedecl4ID1]] {{.*}} struct GlobalVarStructRedecl4 definition +// CHECK-NEXT: DefinitionData +// CHECK-NEXT: DefaultConstructor +// CHECK-NEXT: CopyConstructor +// CHECK-NEXT: MoveConstructor +// CHECK-NEXT: CopyAssignment +// CHECK-NEXT: MoveAssignment +// CHECK-NEXT: Destructor +// CHECK-NEXT: SYCLAddIRAttributesGlobalVariableAttr {{.*}} Inherited +// CHECK-NEXT: InitListExpr {{.*}} 'void' +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr3" +// CHECK-NEXT: ConstantExpr {{.*}} 'const char[6]' lvalue +// CHECK-NEXT: value: LValue +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr1" +// CHECK-NEXT: ConstantExpr {{.*}} 'const char[6]' lvalue +// CHECK-NEXT: value: LValue +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr2" +// CHECK-NEXT: ConstantExpr {{.*}} 'int' +// CHECK-NEXT: value: Int 1 +// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 1 +// CHECK-NEXT: ConstantExpr {{.*}} 'bool' +// CHECK-NEXT: value: Int 1 +// CHECK-NEXT: CXXBoolLiteralExpr {{.*}} 'bool' true +// CHECK-NEXT: CXXRecordDecl {{.*}} implicit struct GlobalVarStructRedecl4 +struct [[__sycl_detail__::add_ir_attributes_global_variable({"Attr3"}, "Attr1", "Attr2", 1, true)]] GlobalVarStructRedecl4; +struct GlobalVarStructRedecl4{}; + +// CHECK: CXXRecordDecl {{.*}} struct GlobalVarStructDecl1 definition +// CHECK-NEXT: DefinitionData +// CHECK-NEXT: DefaultConstructor +// CHECK-NEXT: CopyConstructor +// CHECK-NEXT: MoveConstructor +// CHECK-NEXT: CopyAssignment +// CHECK-NEXT: MoveAssignment +// CHECK-NEXT: Destructor +// CHECK-NEXT: SYCLAddIRAttributesGlobalVariableAttr +// CHECK-NEXT: ConstantExpr {{.*}} 'const char[6]' lvalue +// CHECK-NEXT: value: LValue +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr3" +// CHECK-NEXT: ConstantExpr {{.*}} 'const char[6]' lvalue +// CHECK-NEXT: value: LValue +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr2" +// CHECK-NEXT: ConstantExpr {{.*}} 'const char[6]' lvalue +// CHECK-NEXT: value: LValue +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr1" +// CHECK-NEXT: ConstantExpr {{.*}} 'bool' +// CHECK-NEXT: value: Int 0 +// CHECK-NEXT: CXXBoolLiteralExpr {{.*}} 'bool' false +// CHECK-NEXT: ConstantExpr {{.*}} 'bool' +// CHECK-NEXT: value: Int 1 +// CHECK-NEXT: CXXBoolLiteralExpr {{.*}} 'bool' true +// CHECK-NEXT: ConstantExpr {{.*}} 'int' +// CHECK-NEXT: value: Int 1 +// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 1 +// CHECK-NEXT: CXXRecordDecl {{.*}} implicit struct GlobalVarStructDecl1 +struct +[[__sycl_detail__::add_ir_attributes_global_variable("Attr1", "Attr2", 1, true)]] +[[__sycl_detail__::add_ir_attributes_global_variable("Attr1", "Attr2", 1, true)]] +[[__sycl_detail__::add_ir_attributes_global_variable("Attr2", "Attr1", true, 1)]] +[[__sycl_detail__::add_ir_attributes_global_variable("Attr3", false)]] +GlobalVarStructDecl1{}; + +// CHECK: CXXRecordDecl {{.*}} struct GlobalVarStructDecl2 definition +// CHECK-NEXT: DefinitionData +// CHECK-NEXT: DefaultConstructor +// CHECK-NEXT: CopyConstructor +// CHECK-NEXT: MoveConstructor +// CHECK-NEXT: CopyAssignment +// CHECK-NEXT: MoveAssignment +// CHECK-NEXT: Destructor +// CHECK-NEXT: SYCLAddIRAttributesGlobalVariableAttr +// CHECK-NEXT: InitListExpr {{.*}} 'void' +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr3" +// CHECK-NEXT: ConstantExpr {{.*}} 'const char[6]' lvalue +// CHECK-NEXT: value: LValue +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr1" +// CHECK-NEXT: ConstantExpr {{.*}} 'const char[6]' lvalue +// CHECK-NEXT: value: LValue +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr2" +// CHECK-NEXT: ConstantExpr {{.*}} 'int' +// CHECK-NEXT: value: Int 1 +// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 1 +// CHECK-NEXT: ConstantExpr {{.*}} 'bool' +// CHECK-NEXT: value: Int 1 +// CHECK-NEXT: CXXBoolLiteralExpr {{.*}} 'bool' true +// CHECK-NEXT: CXXRecordDecl {{.*}} implicit struct GlobalVarStructDecl2 +struct +[[__sycl_detail__::add_ir_attributes_global_variable({"Attr3"}, "Attr1", "Attr2", 1, true)]] +GlobalVarStructDecl2{}; + +// CHECK: CXXRecordDecl {{.*}} struct GlobalVarStructDecl3 definition +// CHECK-NEXT: DefinitionData +// CHECK-NEXT: DefaultConstructor +// CHECK-NEXT: CopyConstructor +// CHECK-NEXT: MoveConstructor +// CHECK-NEXT: CopyAssignment +// CHECK-NEXT: MoveAssignment +// CHECK-NEXT: Destructor +// CHECK-NEXT: SYCLAddIRAttributesGlobalVariableAttr +// CHECK-NEXT: InitListExpr {{.*}} 'void' +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr1" +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr3" +// CHECK-NEXT: ConstantExpr {{.*}} 'const char[6]' lvalue +// CHECK-NEXT: value: LValue +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr3" +// CHECK-NEXT: ConstantExpr {{.*}} 'const char[6]' lvalue +// CHECK-NEXT: value: LValue +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr1" +// CHECK-NEXT: ConstantExpr {{.*}} 'const char[6]' lvalue +// CHECK-NEXT: value: LValue +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr2" +// CHECK-NEXT: ConstantExpr {{.*}} 'bool' +// CHECK-NEXT: value: Int 0 +// CHECK-NEXT: CXXBoolLiteralExpr {{.*}} 'bool' false +// CHECK-NEXT: ConstantExpr {{.*}} 'int' +// CHECK-NEXT: value: Int 1 +// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 1 +// CHECK-NEXT: ConstantExpr {{.*}} 'bool' +// CHECK-NEXT: value: Int 1 +// CHECK-NEXT: CXXBoolLiteralExpr {{.*}} 'bool' true +// CHECK-NEXT: CXXRecordDecl {{.*}} implicit struct GlobalVarStructDecl3 +struct +[[__sycl_detail__::add_ir_attributes_global_variable({"Attr1", "Attr3"}, "Attr1", "Attr2", 1, true)]] +[[__sycl_detail__::add_ir_attributes_global_variable({"Attr1", "Attr3"}, "Attr1", "Attr2", 1, true)]] +[[__sycl_detail__::add_ir_attributes_global_variable({"Attr1", "Attr3"}, "Attr2", "Attr1", true, 1)]] +[[__sycl_detail__::add_ir_attributes_global_variable({"Attr3", "Attr1"}, "Attr1", "Attr2", 1, true)]] +[[__sycl_detail__::add_ir_attributes_global_variable({"Attr1", "Attr3"}, "Attr3", false)]] +GlobalVarStructDecl3{}; // CHECK: CXXRecordDecl {{.*}} referenced struct GlobalVarStructBase definition // CHECK-NEXT: DefinitionData @@ -217,3 +799,96 @@ struct __attribute__((sycl_special_class)) SpecialClassStructInherit1 : SpecialC struct __attribute__((sycl_special_class)) SpecialClassStructInherit2 : SpecialClassStructInherit1 { void __init([[__sycl_detail__::add_ir_attributes_kernel_parameter("Attr3", false)]] int x) override {} }; + +// CHECK: CXXRecordDecl {{.*}} struct SpecialClassStruct1 definition +// CHECK-NEXT: DefinitionData +// CHECK-NEXT: DefaultConstructor +// CHECK-NEXT: CopyConstructor +// CHECK-NEXT: MoveConstructor +// CHECK-NEXT: CopyAssignment +// CHECK-NEXT: MoveAssignment +// CHECK-NEXT: Destructor +// CHECK-NEXT: SYCLSpecialClassAttr +// CHECK-NEXT: CXXRecordDecl {{.*}} implicit struct SpecialClassStruct1 +// CHECK-NEXT: CXXMethodDecl {{.*}} __init 'void (int)' +// CHECK-NEXT: ParmVarDecl {{.*}} x 'int' +// CHECK-NEXT: SYCLAddIRAttributesKernelParameterAttr +// CHECK-NEXT: ConstantExpr {{.*}} 'const char[6]' lvalue +// CHECK-NEXT: value: LValue +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr3" +// CHECK-NEXT: ConstantExpr {{.*}} 'const char[6]' lvalue +// CHECK-NEXT: value: LValue +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr2" +// CHECK-NEXT: ConstantExpr {{.*}} 'const char[6]' lvalue +// CHECK-NEXT: value: LValue +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr1" +// CHECK-NEXT: ConstantExpr {{.*}} 'bool' +// CHECK-NEXT: value: Int 0 +// CHECK-NEXT: CXXBoolLiteralExpr {{.*}} 'bool' false +// CHECK-NEXT: ConstantExpr {{.*}} 'bool' +// CHECK-NEXT: value: Int 1 +// CHECK-NEXT: CXXBoolLiteralExpr {{.*}} 'bool' true +// CHECK-NEXT: ConstantExpr {{.*}} 'int' +// CHECK-NEXT: value: Int 1 +// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 1 +// CHECK-NEXT: CompoundStmt +// CHECK-NEXT: CXXMethodDecl {{.*}} implicit operator= 'SpecialClassStruct1 &(const SpecialClassStruct1 &)' +// CHECK-NEXT: ParmVarDecl {{.*}} 'const SpecialClassStruct1 &' +// CHECK-NEXT: CXXMethodDecl {{.*}} implicit operator= 'SpecialClassStruct1 &(SpecialClassStruct1 &&)' +// CHECK-NEXT: ParmVarDecl {{.*}} 'SpecialClassStruct1 &&' +// CHECK-NEXT: CXXDestructorDecl {{.*}} implicit ~SpecialClassStruct1 'void ()' +struct __attribute__((sycl_special_class)) SpecialClassStruct1 { + virtual void __init( + [[__sycl_detail__::add_ir_attributes_kernel_parameter("Attr1", "Attr2", 1, true)]] + [[__sycl_detail__::add_ir_attributes_kernel_parameter("Attr2", "Attr1", true, 1)]] + [[__sycl_detail__::add_ir_attributes_kernel_parameter("Attr3", false)]] + int x) {} +}; + +// CHECK: CXXRecordDecl {{.*}} struct SpecialClassStruct2 definition +// CHECK-NEXT: DefinitionData +// CHECK-NEXT: DefaultConstructor +// CHECK-NEXT: CopyConstructor +// CHECK-NEXT: MoveConstructor +// CHECK-NEXT: CopyAssignment +// CHECK-NEXT: MoveAssignment +// CHECK-NEXT: Destructor +// CHECK-NEXT: SYCLSpecialClassAttr {{.*}} +// CHECK-NEXT: CXXRecordDecl {{.*}} implicit struct SpecialClassStruct2 +// CHECK-NEXT: CXXMethodDecl {{.*}} __init 'void (int)' +// CHECK-NEXT: ParmVarDecl {{.*}} x 'int' +// CHECK-NEXT: SYCLAddIRAttributesKernelParameterAttr {{.*}} +// CHECK-NEXT: InitListExpr {{.*}} 'void' +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr1" +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr3" +// CHECK-NEXT: ConstantExpr {{.*}} 'const char[6]' lvalue +// CHECK-NEXT: value: LValue +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr3" +// CHECK-NEXT: ConstantExpr {{.*}} 'const char[6]' lvalue +// CHECK-NEXT: value: LValue +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr2" +// CHECK-NEXT: ConstantExpr {{.*}} 'const char[6]' lvalue +// CHECK-NEXT: value: LValue +// CHECK-NEXT: StringLiteral {{.*}} 'const char[6]' lvalue "Attr1" +// CHECK-NEXT: ConstantExpr {{.*}} 'bool' +// CHECK-NEXT: value: Int 0 +// CHECK-NEXT: CXXBoolLiteralExpr {{.*}} 'bool' false +// CHECK-NEXT: ConstantExpr {{.*}} 'bool' +// CHECK-NEXT: value: Int 1 +// CHECK-NEXT: CXXBoolLiteralExpr {{.*}} 'bool' true +// CHECK-NEXT: ConstantExpr {{.*}} 'int' +// CHECK-NEXT: value: Int 1 +// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 1 +// CHECK-NEXT: CompoundStmt {{.*}} +// CHECK-NEXT: CXXMethodDecl {{.*}} implicit operator= 'SpecialClassStruct2 &(const SpecialClassStruct2 &)' +// CHECK-NEXT: ParmVarDecl {{.*}} 'const SpecialClassStruct2 &' +// CHECK-NEXT: CXXMethodDecl {{.*}} implicit operator= 'SpecialClassStruct2 &(SpecialClassStruct2 &&)' +// CHECK-NEXT: ParmVarDecl {{.*}} 'SpecialClassStruct2 &&' +// CHECK-NEXT: CXXDestructorDecl {{.*}} implicit ~SpecialClassStruct2 'void ()' +struct __attribute__((sycl_special_class)) SpecialClassStruct2 { + virtual void __init( + [[__sycl_detail__::add_ir_attributes_kernel_parameter({"Attr1", "Attr3"}, "Attr1", "Attr2", 1, true)]] + [[__sycl_detail__::add_ir_attributes_kernel_parameter({"Attr1", "Attr3"}, "Attr2", "Attr1", true, 1)]] + [[__sycl_detail__::add_ir_attributes_kernel_parameter({"Attr1", "Attr3"}, "Attr3", false)]] + int x) {} +}; diff --git a/clang/test/SemaSYCL/attr-add-ir-attributes-merge.cpp b/clang/test/SemaSYCL/attr-add-ir-attributes-merge.cpp index 05d355afe3ffd..8ab66673bd2c8 100644 --- a/clang/test/SemaSYCL/attr-add-ir-attributes-merge.cpp +++ b/clang/test/SemaSYCL/attr-add-ir-attributes-merge.cpp @@ -4,43 +4,143 @@ // attributes to generate are the same. void FunctionRedecl1(); +[[__sycl_detail__::add_ir_attributes_function("Attr1", "Attr2", 1, true)]] void FunctionRedecl1(); // expected-note {{conflicting attribute is here}} [[__sycl_detail__::add_ir_attributes_function("Attr1", "Attr2", 1, true)]] void FunctionRedecl1(); -[[__sycl_detail__::add_ir_attributes_function("Attr1", "Attr2", 1, true)]] void FunctionRedecl1(); -[[__sycl_detail__::add_ir_attributes_function("Attr2", "Attr1", true, 1)]] void FunctionRedecl1(); // expected-note {{conflicting attribute is here}} -[[__sycl_detail__::add_ir_attributes_function("Attr1", "Attr2", 1, false)]] void FunctionRedecl1(); // expected-error {{attribute '__sycl_detail__::add_ir_attributes_function' is already applied with different arguments}} expected-note {{conflicting attribute is here}} -[[__sycl_detail__::add_ir_attributes_function("Attr3", false)]] void FunctionRedecl1(){}; // expected-error {{attribute '__sycl_detail__::add_ir_attributes_function' is already applied with different arguments}} +[[__sycl_detail__::add_ir_attributes_function("Attr2", "Attr1", true, 1)]] void FunctionRedecl1(); +[[__sycl_detail__::add_ir_attributes_function("Attr1", "Attr2", 1, false)]] void FunctionRedecl1(); // expected-error {{attribute '__sycl_detail__::add_ir_attributes_function' is already applied with different arguments}} +[[__sycl_detail__::add_ir_attributes_function("Attr3", false)]] void FunctionRedecl1(){}; [[__sycl_detail__::add_ir_attributes_function("Attr1", "Attr2", 1, true)]] void FunctionRedecl2(); void FunctionRedecl2(); void FunctionRedecl3(); -[[__sycl_detail__::add_ir_attributes_function({"Attr1", "Attr3"}, "Attr1", "Attr2", 1, true)]] void FunctionRedecl3(); +[[__sycl_detail__::add_ir_attributes_function({"Attr1", "Attr3"}, "Attr1", "Attr2", 1, true)]] void FunctionRedecl3(); // expected-note {{conflicting attribute is here}} [[__sycl_detail__::add_ir_attributes_function({"Attr1", "Attr3"}, "Attr1", "Attr2", 1, true)]] void FunctionRedecl3(); [[__sycl_detail__::add_ir_attributes_function({"Attr1", "Attr3"}, "Attr2", "Attr1", true, 1)]] void FunctionRedecl3(); -[[__sycl_detail__::add_ir_attributes_function({"Attr3", "Attr1"}, "Attr1", "Attr2", 1, true)]] void FunctionRedecl3(); // expected-note {{conflicting attribute is here}} +[[__sycl_detail__::add_ir_attributes_function({"Attr3", "Attr1"}, "Attr1", "Attr2", 1, true)]] void FunctionRedecl3(); [[__sycl_detail__::add_ir_attributes_function({"Attr1", "Attr3"}, "Attr1", "Attr2", 1, false)]] void FunctionRedecl3(); // expected-error {{attribute '__sycl_detail__::add_ir_attributes_function' is already applied with different arguments}} expected-note {{conflicting attribute is here}} [[__sycl_detail__::add_ir_attributes_function({"Attr1"}, "Attr1", "Attr2", 1, true)]] void FunctionRedecl3(); // expected-error {{attribute '__sycl_detail__::add_ir_attributes_function' is already applied with different arguments}} expected-note {{conflicting attribute is here}} [[__sycl_detail__::add_ir_attributes_function("Attr1", "Attr2", 1, true)]] void FunctionRedecl3(){}; // expected-error {{attribute '__sycl_detail__::add_ir_attributes_function' is already applied with different arguments}} +void FunctionRedecl4(); +[[__sycl_detail__::add_ir_attributes_function("Attr1", "Attr2", 1, true)]] void FunctionRedecl4(); +[[__sycl_detail__::add_ir_attributes_function("Attr1", "Attr2", 1, true)]] void FunctionRedecl4(); +[[__sycl_detail__::add_ir_attributes_function("Attr2", "Attr1", true, 1)]] void FunctionRedecl4(); +[[__sycl_detail__::add_ir_attributes_function("Attr3", false)]] void FunctionRedecl4(){}; + +[[__sycl_detail__::add_ir_attributes_function({"Attr3"}, "Attr1", "Attr2", 1, true)]] void FunctionRedecl5(); +void FunctionRedecl5(); + +void FunctionRedecl6(); +[[__sycl_detail__::add_ir_attributes_function({"Attr1", "Attr3"}, "Attr1", "Attr2", 1, true)]] void FunctionRedecl6(); +[[__sycl_detail__::add_ir_attributes_function({"Attr1", "Attr3"}, "Attr1", "Attr2", 1, true)]] void FunctionRedecl6(); +[[__sycl_detail__::add_ir_attributes_function({"Attr1", "Attr3"}, "Attr2", "Attr1", true, 1)]] void FunctionRedecl6(); +[[__sycl_detail__::add_ir_attributes_function({"Attr3", "Attr1"}, "Attr1", "Attr2", 1, true)]] void FunctionRedecl6(); +[[__sycl_detail__::add_ir_attributes_function({"Attr1", "Attr3"}, "Attr3", false)]] void FunctionRedecl6(){}; + +[[__sycl_detail__::add_ir_attributes_function("Attr1", "Attr2", 1, true)]] +[[__sycl_detail__::add_ir_attributes_function("Attr1", "Attr2", 1, true)]] +[[__sycl_detail__::add_ir_attributes_function("Attr2", "Attr1", true, 1)]] // expected-error {{attribute '__sycl_detail__::add_ir_attributes_function' is already applied with different arguments}} +[[__sycl_detail__::add_ir_attributes_function("Attr1", "Attr2", 1, false)]] // expected-note {{conflicting attribute is here}} +[[__sycl_detail__::add_ir_attributes_function("Attr3", false)]] +void FunctionDecl1(){}; + +[[__sycl_detail__::add_ir_attributes_function({"Attr1", "Attr3"}, "Attr1", "Attr2", 1, true)]] +[[__sycl_detail__::add_ir_attributes_function({"Attr1", "Attr3"}, "Attr1", "Attr2", 1, true)]] +[[__sycl_detail__::add_ir_attributes_function({"Attr1", "Attr3"}, "Attr2", "Attr1", true, 1)]] +[[__sycl_detail__::add_ir_attributes_function({"Attr3", "Attr1"}, "Attr1", "Attr2", 1, true)]] // expected-error 3{{attribute '__sycl_detail__::add_ir_attributes_function' is already applied with different arguments}} +[[__sycl_detail__::add_ir_attributes_function({"Attr1", "Attr3"}, "Attr1", "Attr2", 1, false)]] // expected-note {{conflicting attribute is here}} +[[__sycl_detail__::add_ir_attributes_function({"Attr1"}, "Attr1", "Attr2", 1, true)]] // expected-note {{conflicting attribute is here}} +[[__sycl_detail__::add_ir_attributes_function("Attr1", "Attr2", 1, true)]] // expected-note {{conflicting attribute is here}} +void FunctionDecl2(){}; + +[[__sycl_detail__::add_ir_attributes_function("Attr1", "Attr2", 1, true)]] +[[__sycl_detail__::add_ir_attributes_function("Attr1", "Attr2", 1, true)]] +[[__sycl_detail__::add_ir_attributes_function("Attr2", "Attr1", true, 1)]] +[[__sycl_detail__::add_ir_attributes_function("Attr3", false)]] +void FunctionDecl3(){}; + +[[__sycl_detail__::add_ir_attributes_function({"Attr3"}, "Attr1", "Attr2", 1, true)]] +void FunctionDecl4(){}; + +[[__sycl_detail__::add_ir_attributes_function({"Attr1", "Attr3"}, "Attr1", "Attr2", 1, true)]] +[[__sycl_detail__::add_ir_attributes_function({"Attr1", "Attr3"}, "Attr1", "Attr2", 1, true)]] +[[__sycl_detail__::add_ir_attributes_function({"Attr1", "Attr3"}, "Attr2", "Attr1", true, 1)]] +[[__sycl_detail__::add_ir_attributes_function({"Attr3", "Attr1"}, "Attr1", "Attr2", 1, true)]] +[[__sycl_detail__::add_ir_attributes_function({"Attr1", "Attr3"}, "Attr3", false)]] +void FunctionDecl5(){}; + struct GlobalVarStructRedecl1; +struct [[__sycl_detail__::add_ir_attributes_global_variable("Attr1", "Attr2", 1, true)]] GlobalVarStructRedecl1; // expected-note {{conflicting attribute is here}} struct [[__sycl_detail__::add_ir_attributes_global_variable("Attr1", "Attr2", 1, true)]] GlobalVarStructRedecl1; -struct [[__sycl_detail__::add_ir_attributes_global_variable("Attr1", "Attr2", 1, true)]] GlobalVarStructRedecl1; -struct [[__sycl_detail__::add_ir_attributes_global_variable("Attr2", "Attr1", true, 1)]] GlobalVarStructRedecl1; // expected-note {{conflicting attribute is here}} -struct [[__sycl_detail__::add_ir_attributes_global_variable("Attr1", "Attr2", 1, false)]] GlobalVarStructRedecl1; // expected-error {{attribute '__sycl_detail__::add_ir_attributes_global_variable' is already applied with different arguments}} expected-note {{conflicting attribute is here}} -struct [[__sycl_detail__::add_ir_attributes_global_variable("Attr3", false)]] GlobalVarStructRedecl1{}; // expected-error {{attribute '__sycl_detail__::add_ir_attributes_global_variable' is already applied with different arguments}} +struct [[__sycl_detail__::add_ir_attributes_global_variable("Attr2", "Attr1", true, 1)]] GlobalVarStructRedecl1; +struct [[__sycl_detail__::add_ir_attributes_global_variable("Attr1", "Attr2", 1, false)]] GlobalVarStructRedecl1; // expected-error {{attribute '__sycl_detail__::add_ir_attributes_global_variable' is already applied with different arguments}} +struct [[__sycl_detail__::add_ir_attributes_global_variable("Attr3", false)]] GlobalVarStructRedecl1{}; struct [[__sycl_detail__::add_ir_attributes_global_variable("Attr1", "Attr2", 1, true)]] GlobalVarStructRedecl2; struct GlobalVarStructRedecl2; struct GlobalVarStructRedecl3; -struct [[__sycl_detail__::add_ir_attributes_global_variable({"Attr1", "Attr3"}, "Attr1", "Attr2", 1, true)]] GlobalVarStructRedecl3; +struct [[__sycl_detail__::add_ir_attributes_global_variable({"Attr1", "Attr3"}, "Attr1", "Attr2", 1, true)]] GlobalVarStructRedecl3; // expected-note {{conflicting attribute is here}} struct [[__sycl_detail__::add_ir_attributes_global_variable({"Attr1", "Attr3"}, "Attr1", "Attr2", 1, true)]] GlobalVarStructRedecl3; struct [[__sycl_detail__::add_ir_attributes_global_variable({"Attr1", "Attr3"}, "Attr2", "Attr1", true, 1)]] GlobalVarStructRedecl3; -struct [[__sycl_detail__::add_ir_attributes_global_variable({"Attr1", "Attr3"}, "Attr1", "Attr2", 1, true)]] GlobalVarStructRedecl3; // expected-note {{conflicting attribute is here}} +struct [[__sycl_detail__::add_ir_attributes_global_variable({"Attr1", "Attr3"}, "Attr1", "Attr2", 1, true)]] GlobalVarStructRedecl3; struct [[__sycl_detail__::add_ir_attributes_global_variable({"Attr1", "Attr3"}, "Attr1", "Attr2", 1, false)]] GlobalVarStructRedecl3; // expected-error {{attribute '__sycl_detail__::add_ir_attributes_global_variable' is already applied with different arguments}} expected-note {{conflicting attribute is here}} struct [[__sycl_detail__::add_ir_attributes_global_variable({"Attr1"}, "Attr1", "Attr2", 1, true)]] GlobalVarStructRedecl3; // expected-error {{attribute '__sycl_detail__::add_ir_attributes_global_variable' is already applied with different arguments}} expected-note {{conflicting attribute is here}} struct [[__sycl_detail__::add_ir_attributes_global_variable("Attr1", "Attr2", 1, true)]] GlobalVarStructRedecl3{}; // expected-error {{attribute '__sycl_detail__::add_ir_attributes_global_variable' is already applied with different arguments}} +struct GlobalVarStructRedecl4; +struct [[__sycl_detail__::add_ir_attributes_global_variable("Attr1", "Attr2", 1, true)]] GlobalVarStructRedecl4; +struct [[__sycl_detail__::add_ir_attributes_global_variable("Attr1", "Attr2", 1, true)]] GlobalVarStructRedecl4; +struct [[__sycl_detail__::add_ir_attributes_global_variable("Attr2", "Attr1", true, 1)]] GlobalVarStructRedecl4; +struct [[__sycl_detail__::add_ir_attributes_global_variable("Attr3", false)]] GlobalVarStructRedecl4{}; + +struct GlobalVarStructRedecl5; +struct [[__sycl_detail__::add_ir_attributes_global_variable("Attr1", "Attr2", 1, true)]] GlobalVarStructRedecl5; +struct [[__sycl_detail__::add_ir_attributes_global_variable("Attr1", "Attr2", 1, true)]] GlobalVarStructRedecl5; +struct [[__sycl_detail__::add_ir_attributes_global_variable("Attr2", "Attr1", true, 1)]] GlobalVarStructRedecl5; +struct [[__sycl_detail__::add_ir_attributes_global_variable("Attr3", false)]] GlobalVarStructRedecl5{}; + +struct [[__sycl_detail__::add_ir_attributes_global_variable({"Attr3"}, "Attr1", "Attr2", 1, true)]] GlobalVarStructRedecl6; +struct GlobalVarStructRedecl6{}; + +struct +[[__sycl_detail__::add_ir_attributes_global_variable("Attr1", "Attr2", 1, true)]] +[[__sycl_detail__::add_ir_attributes_global_variable("Attr1", "Attr2", 1, true)]] +[[__sycl_detail__::add_ir_attributes_global_variable("Attr2", "Attr1", true, 1)]] // expected-error {{attribute '__sycl_detail__::add_ir_attributes_global_variable' is already applied with different arguments}} +[[__sycl_detail__::add_ir_attributes_global_variable("Attr1", "Attr2", 1, false)]] // expected-note {{conflicting attribute is here}} +[[__sycl_detail__::add_ir_attributes_global_variable("Attr3", false)]] +GlobalVarStructDecl1{}; + +struct +[[__sycl_detail__::add_ir_attributes_global_variable({"Attr1", "Attr3"}, "Attr1", "Attr2", 1, true)]] +[[__sycl_detail__::add_ir_attributes_global_variable({"Attr1", "Attr3"}, "Attr1", "Attr2", 1, true)]] +[[__sycl_detail__::add_ir_attributes_global_variable({"Attr1", "Attr3"}, "Attr2", "Attr1", true, 1)]] +[[__sycl_detail__::add_ir_attributes_global_variable({"Attr1", "Attr3"}, "Attr1", "Attr2", 1, true)]] // expected-error 3{{attribute '__sycl_detail__::add_ir_attributes_global_variable' is already applied with different arguments}} +[[__sycl_detail__::add_ir_attributes_global_variable({"Attr1", "Attr3"}, "Attr1", "Attr2", 1, false)]] // expected-note {{conflicting attribute is here}} +[[__sycl_detail__::add_ir_attributes_global_variable({"Attr1"}, "Attr1", "Attr2", 1, true)]] // expected-note {{conflicting attribute is here}} +[[__sycl_detail__::add_ir_attributes_global_variable("Attr1", "Attr2", 1, true)]] // expected-note {{conflicting attribute is here}} +GlobalVarStructDecl2{}; + +struct +[[__sycl_detail__::add_ir_attributes_global_variable("Attr1", "Attr2", 1, true)]] +[[__sycl_detail__::add_ir_attributes_global_variable("Attr1", "Attr2", 1, true)]] +[[__sycl_detail__::add_ir_attributes_global_variable("Attr2", "Attr1", true, 1)]] +[[__sycl_detail__::add_ir_attributes_global_variable("Attr3", false)]] +GlobalVarStructDecl3{}; + +struct +[[__sycl_detail__::add_ir_attributes_global_variable({"Attr3"}, "Attr1", "Attr2", 1, true)]] +GlobalVarStructDecl4{}; + +struct +[[__sycl_detail__::add_ir_attributes_global_variable({"Attr1", "Attr3"}, "Attr1", "Attr2", 1, true)]] +[[__sycl_detail__::add_ir_attributes_global_variable({"Attr1", "Attr3"}, "Attr1", "Attr2", 1, true)]] +[[__sycl_detail__::add_ir_attributes_global_variable({"Attr1", "Attr3"}, "Attr2", "Attr1", true, 1)]] +[[__sycl_detail__::add_ir_attributes_global_variable({"Attr3", "Attr1"}, "Attr1", "Attr2", 1, true)]] +[[__sycl_detail__::add_ir_attributes_global_variable({"Attr1", "Attr3"}, "Attr3", false)]] +GlobalVarStructDecl5{}; + struct GlobalVarStructBase {}; struct [[__sycl_detail__::add_ir_attributes_global_variable("Attr1", "Attr2", 1, true)]] GlobalVarStructInherit1 : GlobalVarStructBase{}; struct GlobalVarStructInherit2 : GlobalVarStructInherit1 {}; @@ -55,3 +155,28 @@ struct __attribute__((sycl_special_class)) SpecialClassStructInherit1 : SpecialC struct __attribute__((sycl_special_class)) SpecialClassStructInherit2 : SpecialClassStructInherit1 { void __init([[__sycl_detail__::add_ir_attributes_kernel_parameter("Attr3", false)]] int x) override {} }; + +struct __attribute__((sycl_special_class)) SpecialClassStruct1 { + virtual void __init( + [[__sycl_detail__::add_ir_attributes_kernel_parameter("Attr1", "Attr2", 1, true)]] + [[__sycl_detail__::add_ir_attributes_kernel_parameter("Attr2", "Attr1", true, 1)]] // expected-error {{attribute '__sycl_detail__::add_ir_attributes_kernel_parameter' is already applied with different arguments}} + [[__sycl_detail__::add_ir_attributes_kernel_parameter("Attr1", "Attr2", 1, false)]] // expected-note {{conflicting attribute is here}} + [[__sycl_detail__::add_ir_attributes_kernel_parameter("Attr3", false)]] + int x) {} +}; + +struct __attribute__((sycl_special_class)) SpecialClassStruct2 { + virtual void __init( + [[__sycl_detail__::add_ir_attributes_kernel_parameter("Attr1", "Attr2", 1, true)]] + [[__sycl_detail__::add_ir_attributes_kernel_parameter("Attr2", "Attr1", true, 1)]] + [[__sycl_detail__::add_ir_attributes_kernel_parameter("Attr3", false)]] + int x) {} +}; + +struct __attribute__((sycl_special_class)) SpecialClassStruct3 { + virtual void __init( + [[__sycl_detail__::add_ir_attributes_kernel_parameter({"Attr1", "Attr3"}, "Attr1", "Attr2", 1, true)]] + [[__sycl_detail__::add_ir_attributes_kernel_parameter({"Attr1", "Attr3"}, "Attr2", "Attr1", true, 1)]] + [[__sycl_detail__::add_ir_attributes_kernel_parameter({"Attr1", "Attr3"}, "Attr3", false)]] + int x) {} +};