Skip to content

Commit de88506

Browse files
committed
Merge from 'master' to 'sycl-web' (#1)
CONFLICT (content): Merge conflict in clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
2 parents b4e34c1 + a134477 commit de88506

File tree

201 files changed

+4036
-1669
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

201 files changed

+4036
-1669
lines changed

.arcconfig

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,6 @@
22
"phabricator.uri" : "https://reviews.llvm.org/",
33
"repository.callsign" : "G",
44
"conduit_uri" : "https://reviews.llvm.org/",
5-
"base": "git:HEAD^"
5+
"base": "git:HEAD^",
6+
"arc.land.onto.default": "main"
67
}

clang/docs/ClangCommandLineReference.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2663,6 +2663,10 @@ Align selected branches (fused, jcc, jmp) within 32-byte boundary
26632663

26642664
Legacy option to specify code object ABI V2 (-mnocode-object-v3) or V3 (-mcode-object-v3) (AMDGPU only)
26652665

2666+
.. option:: -mcode-object-version=<version>
2667+
2668+
Specify code object ABI version. Defaults to 4. (AMDGPU only)
2669+
26662670
.. option:: -mconsole<arg>
26672671

26682672
.. program:: clang1

clang/include/clang-c/Index.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3875,7 +3875,15 @@ enum CXTypeNullabilityKind {
38753875
/**
38763876
* Nullability is not applicable to this type.
38773877
*/
3878-
CXTypeNullability_Invalid = 3
3878+
CXTypeNullability_Invalid = 3,
3879+
3880+
/**
3881+
* Generally behaves like Nullable, except when used in a block parameter that
3882+
* was imported into a swift async method. There, swift will assume that the
3883+
* parameter can get null even if no error occured. _Nullable parameters are
3884+
* assumed to only get null on error.
3885+
*/
3886+
CXTypeNullability_NullableResult = 4
38793887
};
38803888

38813889
/**

clang/include/clang/AST/Expr.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1284,7 +1284,7 @@ class DeclRefExpr final
12841284

12851285
ValueDecl *getDecl() { return D; }
12861286
const ValueDecl *getDecl() const { return D; }
1287-
void setDecl(ValueDecl *NewD) { D = NewD; }
1287+
void setDecl(ValueDecl *NewD);
12881288

12891289
DeclarationNameInfo getNameInfo() const {
12901290
return DeclarationNameInfo(getDecl()->getDeclName(), getLocation(), DNLoc);
@@ -3232,7 +3232,7 @@ class MemberExpr final
32323232
/// The returned declaration will be a FieldDecl or (in C++) a VarDecl (for
32333233
/// static data members), a CXXMethodDecl, or an EnumConstantDecl.
32343234
ValueDecl *getMemberDecl() const { return MemberDecl; }
3235-
void setMemberDecl(ValueDecl *D) { MemberDecl = D; }
3235+
void setMemberDecl(ValueDecl *D);
32363236

32373237
/// Retrieves the declaration found by lookup.
32383238
DeclAccessPair getFoundDecl() const {

clang/include/clang/AST/Type.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4733,6 +4733,9 @@ class AttributedType : public Type, public llvm::FoldingSetNode {
47334733
case NullabilityKind::Nullable:
47344734
return attr::TypeNullable;
47354735

4736+
case NullabilityKind::NullableResult:
4737+
return attr::TypeNullableResult;
4738+
47364739
case NullabilityKind::Unspecified:
47374740
return attr::TypeNullUnspecified;
47384741
}

clang/include/clang/Basic/Attr.td

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -126,9 +126,6 @@ def FunctionTmpl
126126
FunctionDecl::TK_FunctionTemplate}],
127127
"function templates">;
128128

129-
def ClassTmpl : SubsetSubject<CXXRecord, [{S->getDescribedClassTemplate()}],
130-
"class templates">;
131-
132129
// FIXME: this hack is needed because DeclNodes.td defines the base Decl node
133130
// type to be a class, not a definition. This makes it impossible to create an
134131
// attribute subject which accepts a Decl. Normally, this is not a problem,
@@ -2379,6 +2376,11 @@ def TypeNullable : TypeAttr {
23792376
let Documentation = [TypeNullableDocs];
23802377
}
23812378

2379+
def TypeNullableResult : TypeAttr {
2380+
let Spellings = [Keyword<"_Nullable_result">];
2381+
let Documentation = [TypeNullableResultDocs];
2382+
}
2383+
23822384
def TypeNullUnspecified : TypeAttr {
23832385
let Spellings = [Keyword<"_Null_unspecified">];
23842386
let Documentation = [TypeNullUnspecifiedDocs];
@@ -2924,6 +2926,16 @@ def SwiftIndirectResult : ParameterABIAttr {
29242926
let Documentation = [SwiftIndirectResultDocs];
29252927
}
29262928

2929+
def SwiftAsync : InheritableAttr {
2930+
let Spellings = [Clang<"swift_async">];
2931+
let Subjects = SubjectList<[Function, ObjCMethod]>;
2932+
let Args = [EnumArgument<"Kind", "Kind",
2933+
["none", "swift_private", "not_swift_private"],
2934+
["None", "SwiftPrivate", "NotSwiftPrivate"]>,
2935+
ParamIdxArgument<"CompletionHandlerIndex", /*opt=*/1>];
2936+
let Documentation = [SwiftAsyncDocs];
2937+
}
2938+
29272939
def Suppress : StmtAttr {
29282940
let Spellings = [CXX11<"gsl", "suppress">];
29292941
let Args = [VariadicStringArgument<"DiagnosticIdentifiers">];
@@ -2956,16 +2968,6 @@ def Pascal : DeclOrTypeAttr {
29562968
let Documentation = [Undocumented];
29572969
}
29582970

2959-
def PreferredName : InheritableAttr {
2960-
let Spellings = [Clang<"preferred_name", /*AllowInC*/0>];
2961-
let Subjects = SubjectList<[ClassTmpl]>;
2962-
let Args = [TypeArgument<"TypedefType">];
2963-
let Documentation = [PreferredNameDocs];
2964-
let InheritEvenIfAlreadyPresent = 1;
2965-
let MeaningfulToClassTemplateDefinition = 1;
2966-
let TemplateDependent = 1;
2967-
}
2968-
29692971
def PreserveMost : DeclOrTypeAttr {
29702972
let Spellings = [Clang<"preserve_most">];
29712973
let Documentation = [PreserveMostDocs];

clang/include/clang/Basic/AttrDocs.td

Lines changed: 54 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -4166,6 +4166,29 @@ a caller of ``fetch_or_zero`` can provide null.
41664166
}];
41674167
}
41684168

4169+
def TypeNullableResultDocs : Documentation {
4170+
let Category = NullabilityDocs;
4171+
let Content = [{
4172+
The ``_Nullable_result`` nullability qualifier means that a value of the
4173+
``_Nullable_result`` pointer can be ``nil``, just like ``_Nullable``. Where this
4174+
attribute differs from ``_Nullable`` is when it's used on a parameter to a
4175+
completion handler in a Swift async method. For instance, here:
4176+
4177+
.. code-block:: objc
4178+
4179+
-(void)fetchSomeDataWithID:(int)identifier
4180+
completionHandler:(void (^)(Data *_Nullable_result result, NSError *error))completionHandler;
4181+
4182+
This method asynchronously calls ``completionHandler`` when the data is
4183+
available, or calls it with an error. ``_Nullable_result`` indicates to the
4184+
Swift importer that this is the uncommon case where ``result`` can get ``nil``
4185+
even if no error has occured, and will therefore import it as a Swift optional
4186+
type. Otherwise, if ``result`` was annotated with ``_Nullable``, the Swift
4187+
importer will assume that ``result`` will always be non-nil unless an error
4188+
occured.
4189+
}];
4190+
}
4191+
41694192
def TypeNullUnspecifiedDocs : Documentation {
41704193
let Category = NullabilityDocs;
41714194
let Content = [{
@@ -5035,6 +5058,37 @@ optimizations like C++'s named return value optimization (NRVO).
50355058
}];
50365059
}
50375060

5061+
def SwiftAsyncDocs : Documentation {
5062+
let Category = SwiftDocs;
5063+
let Heading = "swift_async";
5064+
let Content = [{
5065+
The ``swift_async`` attribute specifies if and how a particular function or
5066+
Objective-C method is imported into a swift async method. For instance:
5067+
5068+
.. code-block:: objc
5069+
5070+
@interface MyClass : NSObject
5071+
-(void)notActuallyAsync:(int)p1 withCompletionHandler:(void (^)())handler
5072+
__attribute__((swift_async(none)));
5073+
5074+
-(void)actuallyAsync:(int)p1 callThisAsync:(void (^)())fun
5075+
__attribute__((swift_async(swift_private, 1)));
5076+
@end
5077+
5078+
Here, ``notActuallyAsync:withCompletionHandler`` would have been imported as
5079+
``async`` (because it's last parameter's selector piece is
5080+
``withCompletionHandler``) if not for the ``swift_async(none)`` attribute.
5081+
Conversely, ``actuallyAsync:callThisAsync`` wouldn't have been imported as
5082+
``async`` if not for the ``swift_async`` attribute because it doesn't match the
5083+
naming convention.
5084+
5085+
When using ``swift_async`` to enable importing, the first argument to the
5086+
attribute is either ``swift_private`` or ``not_swift_private`` to indicate
5087+
whether the function/method is private to the current framework, and the second
5088+
argument is the index of the completion handler parameter.
5089+
}];
5090+
}
5091+
50385092
def SuppressDocs : Documentation {
50395093
let Category = DocCatStmt;
50405094
let Content = [{
@@ -5075,30 +5129,6 @@ the old mangled name and the new code will use the new mangled name with tags.
50755129
}];
50765130
}
50775131

5078-
def PreferredNameDocs : Documentation {
5079-
let Category = DocCatDecl;
5080-
let Content = [{
5081-
The ``preferred_name`` attribute can be applied to a class template, and
5082-
specifies a preferred way of naming a specialization of the template. The
5083-
preferred name will be used whenever the corresponding template specialization
5084-
would otherwise be printed in a diagnostic or similar context.
5085-
5086-
The preferred name must be a typedef or type alias declaration that refers to a
5087-
specialization of the class template (not including any type qualifiers). In
5088-
general this requires the template to be declared at least twice. For example:
5089-
5090-
.. code-block:: c++
5091-
5092-
template<typename T> struct basic_string;
5093-
using string = basic_string<char>;
5094-
using wstring = basic_string<wchar_t>;
5095-
template<typename T> struct [[clang::preferred_name(string),
5096-
clang::preferred_name(wstring)]] basic_string {
5097-
// ...
5098-
};
5099-
}];
5100-
}
5101-
51025132
def PreserveMostDocs : Documentation {
51035133
let Category = DocCatCallingConvs;
51045134
let Content = [{

clang/include/clang/Basic/BuiltinsPPC.def

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -638,6 +638,11 @@ BUILTIN(__builtin_cfuged, "ULLiULLiULLi", "")
638638
BUILTIN(__builtin_cntlzdm, "ULLiULLiULLi", "")
639639
BUILTIN(__builtin_cnttzdm, "ULLiULLiULLi", "")
640640

641+
// Generate random number
642+
BUILTIN(__builtin_darn, "LLi", "")
643+
BUILTIN(__builtin_darn_raw, "LLi", "")
644+
BUILTIN(__builtin_darn_32, "i", "")
645+
641646
// Vector int128 (un)pack
642647
BUILTIN(__builtin_unpack_vector_int128, "ULLiV1LLLii", "")
643648
BUILTIN(__builtin_pack_vector_int128, "V1LLLiULLiULLi", "")

clang/include/clang/Basic/DiagnosticDriverKinds.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ def err_drv_no_sycl_libspirv : Error<
8282
def err_drv_mix_cuda_hip : Error<"Mixed Cuda and HIP compilation is not supported.">;
8383
def err_drv_bad_target_id : Error<"Invalid target ID: %0 (A target ID is a processor name "
8484
"followed by an optional list of predefined features post-fixed by a plus or minus sign deliminated "
85-
"by colon, e.g. 'gfx908:sram-ecc+:xnack-')">;
85+
"by colon, e.g. 'gfx908:sramecc+:xnack-')">;
8686
def err_drv_bad_offload_arch_combo : Error<"Invalid offload arch combinations: %0 and %1 (For a specific "
8787
"processor, a feature should either exist in all offload archs, or not exist in any offload archs)">;
8888
def err_drv_invalid_thread_model_for_target : Error<

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3982,9 +3982,6 @@ def note_protocol_decl : Note<
39823982
"protocol is declared here">;
39833983
def note_protocol_decl_undefined : Note<
39843984
"protocol %0 has no definition">;
3985-
def err_attribute_preferred_name_arg_invalid : Error<
3986-
"argument %0 to 'preferred_name' attribute is not a typedef for "
3987-
"a specialization of %1">;
39883985

39893986
// objc_designated_initializer attribute diagnostics.
39903987
def warn_objc_designated_init_missing_super_call : Warning<
@@ -4091,6 +4088,13 @@ def err_attr_swift_error_return_type : Error<
40914088
"%0 attribute with '%1' convention can only be applied to a "
40924089
"%select{function|method}2 returning %select{an integral type|a pointer}3">;
40934090

4091+
def err_swift_async_no_access : Error<
4092+
"first argument to 'swift_async' must be either 'none', 'swift_private', or "
4093+
"'not_swift_private'">;
4094+
def err_swift_async_bad_block_type : Error<
4095+
"'swift_async' completion handler parameter must have block type returning"
4096+
" 'void', type here is %0">;
4097+
40944098
def warn_ignored_objc_externally_retained : Warning<
40954099
"'objc_externally_retained' can only be applied to local variables "
40964100
"%select{of retainable type|with strong ownership}0">,

clang/include/clang/Basic/Features.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ FEATURE(cxx_rtti, LangOpts.RTTI &&LangOpts.RTTIData)
8585
FEATURE(enumerator_attributes, true)
8686
FEATURE(nullability, true)
8787
FEATURE(nullability_on_arrays, true)
88+
FEATURE(nullability_nullable_result, true)
8889
FEATURE(memory_sanitizer,
8990
LangOpts.Sanitize.hasOneOf(SanitizerKind::Memory |
9091
SanitizerKind::KernelMemory))

clang/include/clang/Basic/Specifiers.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,12 @@ namespace clang {
309309
/// unspecified. This captures a (fairly rare) case where we
310310
/// can't conclude anything about the nullability of the type even
311311
/// though it has been considered.
312-
Unspecified
312+
Unspecified,
313+
// Generally behaves like Nullable, except when used in a block parameter
314+
// that was imported into a swift async method. There, swift will assume
315+
// that the parameter can get null even if no error occured. _Nullable
316+
// parameters are assumed to only get null on error.
317+
NullableResult,
313318
};
314319

315320
/// Return true if \p L has a weaker nullability annotation than \p R. The

clang/include/clang/Basic/TargetID.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ namespace clang {
1919
/// Get all feature strings that can be used in target ID for \p Processor.
2020
/// Target ID is a processor name with optional feature strings
2121
/// postfixed by a plus or minus sign delimited by colons, e.g.
22-
/// gfx908:xnack+:sram-ecc-. Each processor have a limited
22+
/// gfx908:xnack+:sramecc-. Each processor have a limited
2323
/// number of predefined features when showing up in a target ID.
2424
const llvm::SmallVector<llvm::StringRef, 4>
2525
getAllPossibleTargetIDFeatures(const llvm::Triple &T,

clang/include/clang/Basic/TokenKinds.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -651,6 +651,7 @@ ALIAS("__volatile__" , volatile , KEYALL)
651651
// Type nullability.
652652
KEYWORD(_Nonnull , KEYALL)
653653
KEYWORD(_Nullable , KEYALL)
654+
KEYWORD(_Nullable_result , KEYALL)
654655
KEYWORD(_Null_unspecified , KEYALL)
655656

656657
// Microsoft extensions which should be disabled in strict conformance mode

clang/include/clang/Driver/Options.td

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -686,7 +686,7 @@ def no_cuda_include_ptx_EQ : Joined<["--"], "no-cuda-include-ptx=">, Flags<[NoXa
686686
def offload_arch_EQ : Joined<["--"], "offload-arch=">, Flags<[NoXarchOption]>,
687687
HelpText<"CUDA offloading device architecture (e.g. sm_35), or HIP offloading target ID in the form of a "
688688
"device architecture followed by target ID features delimited by a colon. Each target ID feature "
689-
"is a pre-defined string followed by a plus or minus sign (e.g. gfx908:xnack+:sram-ecc-). May be "
689+
"is a pre-defined string followed by a plus or minus sign (e.g. gfx908:xnack+:sramecc-). May be "
690690
"specified more than once.">;
691691
def cuda_gpu_arch_EQ : Joined<["--"], "cuda-gpu-arch=">, Flags<[NoXarchOption]>,
692692
Alias<offload_arch_EQ>;
@@ -2626,6 +2626,10 @@ def mexec_model_EQ : Joined<["-"], "mexec-model=">, Group<m_wasm_Features_Driver
26262626
Values<"command,reactor">,
26272627
HelpText<"Execution model (WebAssembly only)">;
26282628

2629+
def mcode_object_version_EQ : Joined<["-"], "mcode-object-version=">, Group<m_Group>,
2630+
HelpText<"Specify code object ABI version. Defaults to 4. (AMDGPU only)">,
2631+
MetaVarName<"<version>">, Values<"2,3,4">;
2632+
26292633
def mcode_object_v3_legacy : Flag<["-"], "mcode-object-v3">, Group<m_Group>,
26302634
HelpText<"Legacy option to specify code object ABI V2 (-mnocode-object-v3) or V3 (-mcode-object-v3) (AMDGPU only)">;
26312635
def mno_code_object_v3_legacy : Flag<["-"], "mno-code-object-v3">, Group<m_Group>;
@@ -2634,19 +2638,11 @@ def mcumode : Flag<["-"], "mcumode">, Group<m_amdgpu_Features_Group>,
26342638
HelpText<"Specify CU (-mcumode) or WGP (-mno-cumode) wavefront execution mode (AMDGPU only)">;
26352639
def mno_cumode : Flag<["-"], "mno-cumode">, Group<m_amdgpu_Features_Group>;
26362640

2637-
def msram_ecc : Flag<["-"], "msram-ecc">, Group<m_amdgpu_Features_Group>,
2638-
HelpText<"Specify SRAM ECC mode (AMDGPU only)">;
2639-
def mno_sram_ecc : Flag<["-"], "mno-sram-ecc">, Group<m_amdgpu_Features_Group>;
2640-
26412641
def mwavefrontsize64 : Flag<["-"], "mwavefrontsize64">, Group<m_Group>,
26422642
HelpText<"Specify wavefront size 64 mode (AMDGPU only)">;
26432643
def mno_wavefrontsize64 : Flag<["-"], "mno-wavefrontsize64">, Group<m_Group>,
26442644
HelpText<"Specify wavefront size 32 mode (AMDGPU only)">;
26452645

2646-
def mxnack : Flag<["-"], "mxnack">, Group<m_amdgpu_Features_Group>,
2647-
HelpText<"Specify XNACK mode (AMDGPU only)">;
2648-
def mno_xnack : Flag<["-"], "mno-xnack">, Group<m_amdgpu_Features_Group>;
2649-
26502646
def munsafe_fp_atomics : Flag<["-"], "munsafe-fp-atomics">, Group<m_Group>,
26512647
HelpText<"Enable unsafe floating point atomic instructions (AMDGPU only)">,
26522648
Flags<[CC1Option]>;

clang/include/clang/Sema/Sema.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12621,6 +12621,7 @@ class Sema final {
1262112621
/// Nullability type specifiers.
1262212622
IdentifierInfo *Ident__Nonnull = nullptr;
1262312623
IdentifierInfo *Ident__Nullable = nullptr;
12624+
IdentifierInfo *Ident__Nullable_result = nullptr;
1262412625
IdentifierInfo *Ident__Null_unspecified = nullptr;
1262512626

1262612627
IdentifierInfo *Ident_NSError = nullptr;

clang/lib/APINotes/APINotesYAMLCompiler.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ template <> struct ScalarEnumerationTraits<NullabilityKind> {
8989
IO.enumCase(NK, "Nonnull", NullabilityKind::NonNull);
9090
IO.enumCase(NK, "Optional", NullabilityKind::Nullable);
9191
IO.enumCase(NK, "Unspecified", NullabilityKind::Unspecified);
92+
IO.enumCase(NK, "NullableResult", NullabilityKind::NullableResult);
9293
// TODO: Mapping this to it's own value would allow for better cross
9394
// checking. Also the default should be Unknown.
9495
IO.enumCase(NK, "Scalar", NullabilityKind::Unspecified);

clang/lib/AST/Expr.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,11 @@ DeclRefExpr *DeclRefExpr::CreateEmpty(const ASTContext &Context,
486486
return new (Mem) DeclRefExpr(EmptyShell());
487487
}
488488

489+
void DeclRefExpr::setDecl(ValueDecl *NewD) {
490+
D = NewD;
491+
setDependence(computeDependence(this, NewD->getASTContext()));
492+
}
493+
489494
SourceLocation DeclRefExpr::getBeginLoc() const {
490495
if (hasQualifier())
491496
return getQualifierLoc().getBeginLoc();
@@ -1645,6 +1650,11 @@ MemberExpr *MemberExpr::CreateEmpty(const ASTContext &Context,
16451650
return new (Mem) MemberExpr(EmptyShell());
16461651
}
16471652

1653+
void MemberExpr::setMemberDecl(ValueDecl *D) {
1654+
MemberDecl = D;
1655+
setDependence(computeDependence(this));
1656+
}
1657+
16481658
SourceLocation MemberExpr::getBeginLoc() const {
16491659
if (isImplicitAccess()) {
16501660
if (hasQualifier())

clang/lib/AST/Type.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3518,6 +3518,7 @@ bool AttributedType::isQualifier() const {
35183518
case attr::ObjCInertUnsafeUnretained:
35193519
case attr::TypeNonNull:
35203520
case attr::TypeNullable:
3521+
case attr::TypeNullableResult:
35213522
case attr::TypeNullUnspecified:
35223523
case attr::LifetimeBound:
35233524
case attr::AddressSpace:
@@ -4170,6 +4171,8 @@ AttributedType::getImmediateNullability() const {
41704171
return NullabilityKind::Nullable;
41714172
if (getAttrKind() == attr::TypeNullUnspecified)
41724173
return NullabilityKind::Unspecified;
4174+
if (getAttrKind() == attr::TypeNullableResult)
4175+
return NullabilityKind::NullableResult;
41734176
return None;
41744177
}
41754178

0 commit comments

Comments
 (0)