197 changes: 94 additions & 103 deletions clang/docs/analyzer/checkers.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1462,6 +1462,99 @@ checker).
Default value of the option is ``true``.
.. _unix-Stream:
unix.Stream (C)
"""""""""""""""
Check C stream handling functions:
``fopen, fdopen, freopen, tmpfile, fclose, fread, fwrite, fgetc, fgets, fputc, fputs, fprintf, fscanf, ungetc, getdelim, getline, fseek, fseeko, ftell, ftello, fflush, rewind, fgetpos, fsetpos, clearerr, feof, ferror, fileno``.
The checker maintains information about the C stream objects (``FILE *``) and
can detect error conditions related to use of streams. The following conditions
are detected:
* The ``FILE *`` pointer passed to the function is NULL (the single exception is
``fflush`` where NULL is allowed).
* Use of stream after close.
* Opened stream is not closed.
* Read from a stream after end-of-file. (This is not a fatal error but reported
by the checker. Stream remains in EOF state and the read operation fails.)
* Use of stream when the file position is indeterminate after a previous failed
operation. Some functions (like ``ferror``, ``clearerr``, ``fseek``) are
allowed in this state.
* Invalid 3rd ("``whence``") argument to ``fseek``.
The stream operations are by this checker usually split into two cases, a success
and a failure case. However, in the case of write operations (like ``fwrite``,
``fprintf`` and even ``fsetpos``) this behavior could produce a large amount of
unwanted reports on projects that don't have error checks around the write
operations, so by default the checker assumes that write operations always succeed.
This behavior can be controlled by the ``Pedantic`` flag: With
``-analyzer-config unix.Stream:Pedantic=true`` the checker will model the
cases where a write operation fails and report situations where this leads to
erroneous behavior. (The default is ``Pedantic=false``, where write operations
are assumed to succeed.)
.. code-block:: c
void test1() {
FILE *p = fopen("foo", "r");
} // warn: opened file is never closed
void test2() {
FILE *p = fopen("foo", "r");
fseek(p, 1, SEEK_SET); // warn: stream pointer might be NULL
fclose(p);
}
void test3() {
FILE *p = fopen("foo", "r");
if (p) {
fseek(p, 1, 3); // warn: third arg should be SEEK_SET, SEEK_END, or SEEK_CUR
fclose(p);
}
}
void test4() {
FILE *p = fopen("foo", "r");
if (!p)
return;
fclose(p);
fclose(p); // warn: stream already closed
}
void test5() {
FILE *p = fopen("foo", "r");
if (!p)
return;
fgetc(p);
if (!ferror(p))
fgetc(p); // warn: possible read after end-of-file
fclose(p);
}
void test6() {
FILE *p = fopen("foo", "r");
if (!p)
return;
fgetc(p);
if (!feof(p))
fgetc(p); // warn: file position may be indeterminate after I/O error
fclose(p);
}
**Limitations**
The checker does not track the correspondence between integer file descriptors
and ``FILE *`` pointers. Operations on standard streams like ``stdin`` are not
treated specially and are therefore often not recognized (because these streams
are usually not opened explicitly by the program, and are global variables).
.. _osx-checkers:
osx
Expand Down Expand Up @@ -2940,13 +3033,6 @@ Further examples of injection vulnerabilities this checker can find.
sprintf(buf, s); // warn: untrusted data used as a format string
}
void test() {
size_t ts;
scanf("%zd", &ts); // 'ts' marked as tainted
int *p = (int *)malloc(ts * sizeof(int));
// warn: untrusted data used as buffer size
}
There are built-in sources, propagations and sinks even if no external taint
configuration is provided.
Expand Down Expand Up @@ -2974,9 +3060,7 @@ Default propagations rules:
Default sinks:
``printf``, ``setproctitle``, ``system``, ``popen``, ``execl``, ``execle``,
``execlp``, ``execv``, ``execvp``, ``execvP``, ``execve``, ``dlopen``,
``memcpy``, ``memmove``, ``strncpy``, ``strndup``, ``malloc``, ``calloc``,
``alloca``, ``memccpy``, ``realloc``, ``bcopy``
``execlp``, ``execv``, ``execvp``, ``execvP``, ``execve``, ``dlopen``
Please note that there are no built-in filter functions.
Expand Down Expand Up @@ -3116,99 +3200,6 @@ Check for misuses of stream APIs. Check for misuses of stream APIs: ``fopen, fcl
fclose(F); // warn: closing a previously closed file stream
}
.. _alpha-unix-Stream:
alpha.unix.Stream (C)
"""""""""""""""""""""
Check C stream handling functions:
``fopen, fdopen, freopen, tmpfile, fclose, fread, fwrite, fgetc, fgets, fputc, fputs, fprintf, fscanf, ungetc, getdelim, getline, fseek, fseeko, ftell, ftello, fflush, rewind, fgetpos, fsetpos, clearerr, feof, ferror, fileno``.
The checker maintains information about the C stream objects (``FILE *``) and
can detect error conditions related to use of streams. The following conditions
are detected:
* The ``FILE *`` pointer passed to the function is NULL (the single exception is
``fflush`` where NULL is allowed).
* Use of stream after close.
* Opened stream is not closed.
* Read from a stream after end-of-file. (This is not a fatal error but reported
by the checker. Stream remains in EOF state and the read operation fails.)
* Use of stream when the file position is indeterminate after a previous failed
operation. Some functions (like ``ferror``, ``clearerr``, ``fseek``) are
allowed in this state.
* Invalid 3rd ("``whence``") argument to ``fseek``.
The stream operations are by this checker usually split into two cases, a success
and a failure case. However, in the case of write operations (like ``fwrite``,
``fprintf`` and even ``fsetpos``) this behavior could produce a large amount of
unwanted reports on projects that don't have error checks around the write
operations, so by default the checker assumes that write operations always succeed.
This behavior can be controlled by the ``Pedantic`` flag: With
``-analyzer-config alpha.unix.Stream:Pedantic=true`` the checker will model the
cases where a write operation fails and report situations where this leads to
erroneous behavior. (The default is ``Pedantic=false``, where write operations
are assumed to succeed.)
.. code-block:: c
void test1() {
FILE *p = fopen("foo", "r");
} // warn: opened file is never closed
void test2() {
FILE *p = fopen("foo", "r");
fseek(p, 1, SEEK_SET); // warn: stream pointer might be NULL
fclose(p);
}
void test3() {
FILE *p = fopen("foo", "r");
if (p) {
fseek(p, 1, 3); // warn: third arg should be SEEK_SET, SEEK_END, or SEEK_CUR
fclose(p);
}
}
void test4() {
FILE *p = fopen("foo", "r");
if (!p)
return;
fclose(p);
fclose(p); // warn: stream already closed
}
void test5() {
FILE *p = fopen("foo", "r");
if (!p)
return;
fgetc(p);
if (!ferror(p))
fgetc(p); // warn: possible read after end-of-file
fclose(p);
}
void test6() {
FILE *p = fopen("foo", "r");
if (!p)
return;
fgetc(p);
if (!feof(p))
fgetc(p); // warn: file position may be indeterminate after I/O error
fclose(p);
}
**Limitations**
The checker does not track the correspondence between integer file descriptors
and ``FILE *`` pointers. Operations on standard streams like ``stdin`` are not
treated specially and are therefore often not recognized (because these streams
are usually not opened explicitly by the program, and are global variables).
.. _alpha-unix-cstring-BufferOverlap:
alpha.unix.cstring.BufferOverlap (C)
Expand Down
3 changes: 2 additions & 1 deletion clang/include/clang/AST/ASTContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -1116,7 +1116,8 @@ class ASTContext : public RefCountedBase<ASTContext> {
CanQualType BFloat16Ty;
CanQualType Float16Ty; // C11 extension ISO/IEC TS 18661-3
CanQualType VoidPtrTy, NullPtrTy;
CanQualType DependentTy, OverloadTy, BoundMemberTy, UnknownAnyTy;
CanQualType DependentTy, OverloadTy, BoundMemberTy, UnresolvedTemplateTy,
UnknownAnyTy;
CanQualType BuiltinFnTy;
CanQualType PseudoObjectTy, ARCUnbridgedCastTy;
CanQualType ObjCBuiltinIdTy, ObjCBuiltinClassTy, ObjCBuiltinSelTy;
Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/AST/BuiltinTypes.def
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,9 @@ PLACEHOLDER_TYPE(Overload, OverloadTy)
// x->foo # if only contains non-static members
PLACEHOLDER_TYPE(BoundMember, BoundMemberTy)

// The type of an unresolved template. Used in UnresolvedLookupExpr.
PLACEHOLDER_TYPE(UnresolvedTemplate, UnresolvedTemplateTy)

// The type of an expression which refers to a pseudo-object,
// such as those introduced by Objective C's @property or
// VS.NET's __property declarations. A placeholder type. The
Expand Down
5 changes: 5 additions & 0 deletions clang/include/clang/AST/Decl.h
Original file line number Diff line number Diff line change
Expand Up @@ -5049,6 +5049,11 @@ static constexpr StringRef getOpenMPVariantManglingSeparatorStr() {
return "$ompvariant";
}

/// Returns whether the given FunctionDecl has an __arm[_locally]_streaming
/// attribute.
bool IsArmStreamingFunction(const FunctionDecl *FD,
bool IncludeLocallyStreaming);

} // namespace clang

#endif // LLVM_CLANG_AST_DECL_H
24 changes: 24 additions & 0 deletions clang/include/clang/AST/ExprCXX.h
Original file line number Diff line number Diff line change
Expand Up @@ -1482,6 +1482,8 @@ class CXXTemporary {
/// const S &s_ref = S(); // Requires a CXXBindTemporaryExpr.
/// }
/// \endcode
///
/// Destructor might be null if destructor declaration is not valid.
class CXXBindTemporaryExpr : public Expr {
CXXTemporary *Temp = nullptr;
Stmt *SubExpr = nullptr;
Expand Down Expand Up @@ -3161,8 +3163,30 @@ class OverloadExpr : public Expr {
/// This arises in several ways:
/// * we might be waiting for argument-dependent lookup;
/// * the name might resolve to an overloaded function;
/// * the name might resolve to a non-function template; for example, in the
/// following snippet, the return expression of the member function
/// 'foo()' might remain unresolved until instantiation:
///
/// \code
/// struct P {
/// template <class T> using I = T;
/// };
///
/// struct Q {
/// template <class T> int foo() {
/// return T::template I<int>;
/// }
/// };
/// \endcode
///
/// ...which is distinct from modeling function overloads, and therefore we use
/// a different builtin type 'UnresolvedTemplate' to avoid confusion. This is
/// done in Sema::BuildTemplateIdExpr.
///
/// and eventually:
/// * the lookup might have included a function template.
/// * the unresolved template gets transformed in an instantiation or gets
/// diagnosed for its direct use.
///
/// These never include UnresolvedUsingValueDecls, which are always class
/// members and therefore appear only in UnresolvedMemberLookupExprs.
Expand Down
307 changes: 280 additions & 27 deletions clang/include/clang/AST/OpenACCClause.h

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions clang/include/clang/Analysis/FlowSensitive/Solver.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,9 @@ class Solver {
///
/// All elements in `Vals` must not be null.
virtual Result solve(llvm::ArrayRef<const Formula *> Vals) = 0;

// Did the solver reach its resource limit?
virtual bool reachedLimit() const = 0;
};

llvm::raw_ostream &operator<<(llvm::raw_ostream &, const Solver::Result &);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,7 @@ class WatchedLiteralsSolver : public Solver {

Result solve(llvm::ArrayRef<const Formula *> Vals) override;

// The solver reached its maximum number of iterations.
bool reachedLimit() const { return MaxIterations == 0; }
bool reachedLimit() const override { return MaxIterations == 0; }
};

} // namespace dataflow
Expand Down
14 changes: 12 additions & 2 deletions clang/include/clang/Basic/AttrDocs.td
Original file line number Diff line number Diff line change
Expand Up @@ -2527,6 +2527,9 @@ Example "subtarget features" from the x86 backend include: "mmx", "sse", "sse4.2
"avx", "xop" and largely correspond to the machine specific options handled by
the front end.

Note that this attribute does not apply transitively to nested functions such
as blocks or C++ lambdas.

Additionally, this attribute supports function multiversioning for ELF based
x86/x86-64 targets, which can be used to create multiple implementations of the
same function that will be resolved at runtime based on the priority of their
Expand Down Expand Up @@ -3782,6 +3785,12 @@ for that function.

This attribute is incompatible with the ``always_inline`` and ``minsize``
attributes.

Note that this attribute does not apply recursively to nested functions such as
lambdas or blocks when using declaration-specific attribute syntaxes such as double
square brackets (``[[]]``) or ``__attribute__``. The ``#pragma`` syntax can be
used to apply the attribute to all functions, including nested functions, in a
range of source code.
}];
}

Expand Down Expand Up @@ -5654,11 +5663,12 @@ The ``preserve_none`` calling convention tries to preserve as few general
registers as possible. So all general registers are caller saved registers. It
also uses more general registers to pass arguments. This attribute doesn't
impact floating-point registers (XMMs/YMMs). Floating-point registers still
follow the c calling convention.
follow the c calling convention. ``preserve_none``'s ABI is still unstable, and
may be changed in the future.

- Only RSP and RBP are preserved by callee.

- Register RDI, RSI, RDX, RCX, R8, R9, R11, R12, R13, R14, R15 and RAX now can
- Register R12, R13, R14, R15, RDI, RSI, RDX, RCX, R8, R9, R11, and RAX now can
be used to pass function arguments.
}];
}
Expand Down
6 changes: 6 additions & 0 deletions clang/include/clang/Basic/Builtins.td
Original file line number Diff line number Diff line change
Expand Up @@ -1326,6 +1326,12 @@ def ElementwiseSqrt : Builtin {
let Prototype = "void(...)";
}

def ElementwiseTan : Builtin {
let Spellings = ["__builtin_elementwise_tan"];
let Attributes = [NoThrow, Const, CustomTypeChecking];
let Prototype = "void(...)";
}

def ElementwiseTrunc : Builtin {
let Spellings = ["__builtin_elementwise_trunc"];
let Attributes = [NoThrow, Const, CustomTypeChecking];
Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/Basic/BuiltinsWebAssembly.def
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,9 @@ TARGET_BUILTIN(__builtin_wasm_relaxed_dot_i8x16_i7x16_s_i16x8, "V8sV16ScV16Sc",
TARGET_BUILTIN(__builtin_wasm_relaxed_dot_i8x16_i7x16_add_s_i32x4, "V4iV16ScV16ScV4i", "nc", "relaxed-simd")
TARGET_BUILTIN(__builtin_wasm_relaxed_dot_bf16x8_add_f32_f32x4, "V4fV8UsV8UsV4f", "nc", "relaxed-simd")

// Half-Precision (fp16)
TARGET_BUILTIN(__builtin_wasm_loadf16_f32, "fh*", "nU", "half-precision")

// Reference Types builtins
// Some builtins are custom type-checked - see 't' as part of the third argument,
// in which case the argument spec (second argument) is unused.
Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/Basic/CodeGenOptions.def
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ CODEGENOPT(UniqueSectionNames, 1, 1) ///< Set for -funique-section-names.
CODEGENOPT(UniqueBasicBlockSectionNames, 1, 1) ///< Set for -funique-basic-block-section-names,
///< Produce unique section names with
///< basic block sections.
CODEGENOPT(SeparateNamedSections, 1, 0) ///< Set for -fseparate-named-sections.
CODEGENOPT(EnableAIXExtendedAltivecABI, 1, 0) ///< Set for -mabi=vec-extabi. Enables the extended Altivec ABI on AIX.
CODEGENOPT(XCOFFReadOnlyPointers, 1, 0) ///< Set for -mxcoff-roptr.
CODEGENOPT(AllTocData, 1, 0) ///< AIX -mtocdata
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/Basic/DiagnosticDriverKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -435,7 +435,7 @@ def warn_drv_diagnostics_misexpect_requires_pgo : Warning<
def warn_drv_clang_unsupported : Warning<
"the clang compiler does not support '%0'">;
def warn_drv_deprecated_arg : Warning<
"argument '%0' is deprecated, use '%1' instead">, InGroup<Deprecated>;
"argument '%0' is deprecated%select{|, use '%2' instead}1">, InGroup<Deprecated>;
def warn_drv_deprecated_custom : Warning<
"argument '%0' is deprecated, %1">, InGroup<Deprecated>;
def warn_drv_assuming_mfloat_abi_is : Warning<
Expand Down
2 changes: 2 additions & 0 deletions clang/include/clang/Basic/DiagnosticFrontendKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,8 @@ def err_fe_no_pch_in_dir : Error<
"no suitable precompiled header file found in directory '%0'">;
def err_fe_action_not_available : Error<
"action %0 not compiled in">;
def err_fe_invalid_multiple_actions : Error<
"'%0' action ignored; '%1' action specified previously">;
def err_fe_invalid_alignment : Error<
"invalid value '%1' in '%0'; alignment must be a power of 2">;
def err_fe_invalid_exception_model
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/Basic/DiagnosticInstallAPIKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def err_no_matching_target : Error<"no matching target found for target variant
def err_unsupported_vendor : Error<"vendor '%0' is not supported: '%1'">;
def err_unsupported_environment : Error<"environment '%0' is not supported: '%1'">;
def err_unsupported_os : Error<"os '%0' is not supported: '%1'">;
def err_cannot_read_alias_list : Error<"could not read alias list '%0': %1">;
def err_cannot_read_input_list : Error<"could not read %select{alias list|filelist}0 '%1': %2">;
} // end of command line category.

let CategoryName = "Verification" in {
Expand Down
44 changes: 42 additions & 2 deletions clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,8 @@ def err_invalid_vector_long_long_decl_spec : Error <
"POWER7 or later) to be enabled">;
def err_invalid_vector_long_double_decl_spec : Error<
"cannot use 'long double' with '__vector'">;
def err_invalid_vector_complex_decl_spec : Error<
"cannot use '_Complex' with '__vector'">;
def warn_vector_long_decl_spec_combination : Warning<
"Use of 'long' with '__vector' is deprecated">, InGroup<Deprecated>;

Expand Down Expand Up @@ -5435,6 +5437,11 @@ def note_function_template_spec_matched : Note<
def err_function_template_partial_spec : Error<
"function template partial specialization is not allowed">;

def err_function_member_spec_ambiguous : Error<
"ambiguous member function specialization %q0 of %q1">;
def note_function_member_spec_matched : Note<
"member function specialization matches %0">;

// C++ Template Instantiation
def err_template_recursion_depth_exceeded : Error<
"recursive template instantiation exceeded maximum depth of %0">,
Expand Down Expand Up @@ -7509,6 +7516,9 @@ def err_nested_non_static_member_use : Error<
def warn_cxx98_compat_non_static_member_use : Warning<
"use of non-static data member %0 in an unevaluated context is "
"incompatible with C++98">, InGroup<CXX98Compat>, DefaultIgnore;
def err_form_ptr_to_member_from_parenthesized_expr : Error<
"cannot form pointer to member from a parenthesized expression; "
"did you mean to remove the parentheses?">;
def err_invalid_incomplete_type_use : Error<
"invalid use of incomplete type %0">;
def err_builtin_func_cast_more_than_one_arg : Error<
Expand Down Expand Up @@ -12289,8 +12299,8 @@ def warn_acc_if_self_conflict
"evaluates to true">,
InGroup<DiagGroup<"openacc-self-if-potential-conflict">>;
def err_acc_int_expr_requires_integer
: Error<"OpenACC %select{clause|directive}0 '%1' requires expression of "
"integer type (%2 invalid)">;
: Error<"OpenACC %select{clause '%1'|directive '%2'|sub-array bound}0 "
"requires expression of integer type (%3 invalid)">;
def err_acc_int_expr_incomplete_class_type
: Error<"OpenACC integer expression has incomplete class type %0">;
def err_acc_int_expr_explicit_conversion
Expand All @@ -12305,4 +12315,34 @@ def err_acc_num_gangs_num_args
"OpenACC 'num_gangs' "
"%select{|clause: '%1' directive expects maximum of %2, %3 were "
"provided}0">;
def err_acc_not_a_var_ref
: Error<"OpenACC variable is not a valid variable name, sub-array, array "
"element, or composite variable member">;
def err_acc_typecheck_subarray_value
: Error<"OpenACC sub-array subscripted value is not an array or pointer">;
def err_acc_subarray_function_type
: Error<"OpenACC sub-array cannot be of function type %0">;
def err_acc_subarray_incomplete_type
: Error<"OpenACC sub-array base is of incomplete type %0">;
def err_acc_subarray_no_length
: Error<"OpenACC sub-array length is unspecified and cannot be inferred "
"because the subscripted value is %select{not an array|an array of "
"unknown bound}0">;
def err_acc_subarray_negative
: Error<"OpenACC sub-array %select{lower bound|length}0 evaluated to "
"negative value %1">;
def err_acc_subarray_out_of_range
: Error<"OpenACC sub-array %select{lower bound|length}0 evaluated to a "
"value (%1) that would be out of the range of the subscripted "
"array size of %2">;
def err_acc_subarray_base_plus_length_out_of_range
: Error<"OpenACC sub-array specified range [%0:%1] would be out of the "
"range of the subscripted array size of %2">;
def warn_acc_deprecated_alias_name
: Warning<"OpenACC clause name '%0' is a deprecated clause name and is "
"now an alias for '%1'">,
InGroup<DiagGroup<"openacc-deprecated-clause-alias">>;
def err_acc_var_not_pointer_type
: Error<"expected pointer in '%0' clause, type is %1">;
def note_acc_expected_pointer_var : Note<"expected variable of pointer type">;
} // end of sema component.
2 changes: 1 addition & 1 deletion clang/include/clang/Basic/LangOptions.def
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ LANGOPT(GNUAsm , 1, 1, "GNU-style inline assembly")
LANGOPT(Coroutines , 1, 0, "C++20 coroutines")
LANGOPT(CoroAlignedAllocation, 1, 0, "prefer Aligned Allocation according to P2014 Option 2")
LANGOPT(DllExportInlines , 1, 1, "dllexported classes dllexport inline methods")
LANGOPT(RelaxedTemplateTemplateArgs, 1, 0, "C++17 relaxed matching of template template arguments")
LANGOPT(RelaxedTemplateTemplateArgs, 1, 1, "C++17 relaxed matching of template template arguments")
LANGOPT(ExperimentalLibrary, 1, 0, "enable unstable and experimental library features")

LANGOPT(PointerAuthIntrinsics, 1, 0, "pointer authentication intrinsics")
Expand Down
5 changes: 1 addition & 4 deletions clang/include/clang/Basic/LangOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -968,10 +968,7 @@ class FPOptionsOverride {
setAllowFPContractAcrossStatement();
}

void setDisallowOptimizations() {
setFPPreciseEnabled(true);
setDisallowFPContract();
}
void setDisallowOptimizations() { setFPPreciseEnabled(true); }

storage_type getAsOpaqueInt() const {
return (static_cast<storage_type>(Options.getAsOpaqueInt())
Expand Down
583 changes: 500 additions & 83 deletions clang/include/clang/Basic/MSP430Target.def

Large diffs are not rendered by default.

7 changes: 4 additions & 3 deletions clang/include/clang/Basic/Module.h
Original file line number Diff line number Diff line change
Expand Up @@ -284,9 +284,10 @@ class alignas(8) Module {
/// found on the file system.
SmallVector<UnresolvedHeaderDirective, 1> MissingHeaders;

/// An individual requirement: a feature name and a flag indicating
/// the required state of that feature.
using Requirement = std::pair<std::string, bool>;
struct Requirement {
std::string FeatureName;
bool RequiredState;
};

/// The set of language features required to use this module.
///
Expand Down
28 changes: 27 additions & 1 deletion clang/include/clang/Basic/OpenACCClauses.def
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,38 @@
// as used in Clang source (so `Default` instead of `default`).
//
// VISIT_CLAUSE(CLAUSE_NAME)
//
// CLAUSE_ALIAS(ALIAS_NAME, CLAUSE_NAME)

#ifndef CLAUSE_ALIAS
#define CLAUSE_ALIAS(ALIAS_NAME, CLAUSE_NAME)
#endif

VISIT_CLAUSE(Async)
VISIT_CLAUSE(Attach)
VISIT_CLAUSE(Copy)
CLAUSE_ALIAS(PCopy, Copy)
CLAUSE_ALIAS(PresentOrCopy, Copy)
VISIT_CLAUSE(CopyIn)
CLAUSE_ALIAS(PCopyIn, CopyIn)
CLAUSE_ALIAS(PresentOrCopyIn, CopyIn)
VISIT_CLAUSE(CopyOut)
CLAUSE_ALIAS(PCopyOut, CopyOut)
CLAUSE_ALIAS(PresentOrCopyOut, CopyOut)
VISIT_CLAUSE(Create)
CLAUSE_ALIAS(PCreate, Create)
CLAUSE_ALIAS(PresentOrCreate, Create)
VISIT_CLAUSE(Default)
VISIT_CLAUSE(DevicePtr)
VISIT_CLAUSE(FirstPrivate)
VISIT_CLAUSE(If)
VISIT_CLAUSE(Self)
VISIT_CLAUSE(NoCreate)
VISIT_CLAUSE(NumGangs)
VISIT_CLAUSE(NumWorkers)
VISIT_CLAUSE(Present)
VISIT_CLAUSE(Private)
VISIT_CLAUSE(Self)
VISIT_CLAUSE(VectorLength)

#undef VISIT_CLAUSE
#undef CLAUSE_ALIAS
45 changes: 44 additions & 1 deletion clang/include/clang/Basic/OpenACCKinds.h
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,10 @@ enum class OpenACCClauseKind {
/// 'copy' clause, allowed on Compute and Combined Constructs, plus 'data' and
/// 'declare'.
Copy,
/// 'copy' clause alias 'pcopy'. Preserved for diagnostic purposes.
PCopy,
/// 'copy' clause alias 'present_or_copy'. Preserved for diagnostic purposes.
PresentOrCopy,
/// 'use_device' clause, allowed on 'host_data' construct.
UseDevice,
/// 'attach' clause, allowed on Compute and Combined constructs, plus 'data'
Expand Down Expand Up @@ -224,12 +228,27 @@ enum class OpenACCClauseKind {
/// 'copyout' clause, allowed on Compute and Combined constructs, plus 'data',
/// 'exit data', and 'declare'.
CopyOut,
/// 'copyout' clause alias 'pcopyout'. Preserved for diagnostic purposes.
PCopyOut,
/// 'copyout' clause alias 'present_or_copyout'. Preserved for diagnostic
/// purposes.
PresentOrCopyOut,
/// 'copyin' clause, allowed on Compute and Combined constructs, plus 'data',
/// 'enter data', and 'declare'.
CopyIn,
/// 'copyin' clause, allowed on Compute and Combined constructs, plus 'data',
/// 'copyin' clause alias 'pcopyin'. Preserved for diagnostic purposes.
PCopyIn,
/// 'copyin' clause alias 'present_or_copyin'. Preserved for diagnostic
/// purposes.
PresentOrCopyIn,
/// 'create' clause, allowed on Compute and Combined constructs, plus 'data',
/// 'enter data', and 'declare'.
Create,
/// 'create' clause alias 'pcreate'. Preserved for diagnostic purposes.
PCreate,
/// 'create' clause alias 'present_or_create'. Preserved for diagnostic
/// purposes.
PresentOrCreate,
/// 'reduction' clause, allowed on Parallel, Serial, Loop, and the combined
/// constructs.
Reduction,
Expand Down Expand Up @@ -310,6 +329,12 @@ inline StreamTy &printOpenACCClauseKind(StreamTy &Out, OpenACCClauseKind K) {
case OpenACCClauseKind::Copy:
return Out << "copy";

case OpenACCClauseKind::PCopy:
return Out << "pcopy";

case OpenACCClauseKind::PresentOrCopy:
return Out << "present_or_copy";

case OpenACCClauseKind::UseDevice:
return Out << "use_device";

Expand Down Expand Up @@ -352,12 +377,30 @@ inline StreamTy &printOpenACCClauseKind(StreamTy &Out, OpenACCClauseKind K) {
case OpenACCClauseKind::CopyOut:
return Out << "copyout";

case OpenACCClauseKind::PCopyOut:
return Out << "pcopyout";

case OpenACCClauseKind::PresentOrCopyOut:
return Out << "present_or_copyout";

case OpenACCClauseKind::CopyIn:
return Out << "copyin";

case OpenACCClauseKind::PCopyIn:
return Out << "pcopyin";

case OpenACCClauseKind::PresentOrCopyIn:
return Out << "present_or_copyin";

case OpenACCClauseKind::Create:
return Out << "create";

case OpenACCClauseKind::PCreate:
return Out << "pcreate";

case OpenACCClauseKind::PresentOrCreate:
return Out << "present_or_create";

case OpenACCClauseKind::Reduction:
return Out << "reduction";

Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/Basic/SourceLocation.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ class SourceLocation {
friend class ASTWriter;
friend class SourceManager;
friend struct llvm::FoldingSetTrait<SourceLocation, void>;
friend class SourceLocationEncoding;

public:
using UIntTy = uint32_t;
Expand Down
126 changes: 126 additions & 0 deletions clang/include/clang/Basic/Target/MSP430/gen-msp430-def.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
#!/usr/bin/env python3
# ===----------------------------------------------------------------------===##
#
# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
# See https://llvm.org/LICENSE.txt for license information.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#
# ===----------------------------------------------------------------------===##
"""
Script to generate MSP430 definitions from TI's devices.csv
Download the devices.csv from [1] using the link "Header and Support Files".
[1]: https://www.ti.com/tool/MSP430-GCC-OPENSOURCE#downloads
"""
import csv
import sys

DEVICE_COLUMN = 0
MULTIPLIER_COLUMN = 3

MULTIPLIER_SW = "0"
MULTIPLIER_HW_16 = ("1", "2")
MULTIPLIER_HW_32 = ("4", "8")

PREFIX = """//===--- MSP430Target.def - MSP430 Feature/Processor Database----*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file defines the MSP430 devices and their features.
//
// Generated from TI's devices.csv in version {} using the script in
// Target/MSP430/gen-msp430-def.py - use this tool rather than adding
// new MCUs by hand.
//
//===----------------------------------------------------------------------===//
#ifndef MSP430_MCU_FEAT
#define MSP430_MCU_FEAT(NAME, HWMULT) MSP430_MCU(NAME)
#endif
#ifndef MSP430_MCU
#define MSP430_MCU(NAME)
#endif
"""

SUFFIX = """
// Generic MCUs
MSP430_MCU("msp430i2xxgeneric")
#undef MSP430_MCU
#undef MSP430_MCU_FEAT
"""


def csv2def(csv_path, def_path):
"""
Parse the devices.csv file at the given path, generate the definitions and
write them to the given path.
:param csv_path: Path to the devices.csv to parse
:type csv_path: str
:param def_path: Path to the output file to write the definitions to
"type def_path: str
"""

mcus_multiplier_sw = []
mcus_multiplier_hw_16 = []
mcus_multiplier_hw_32 = []
version = "unknown"

with open(csv_path) as csv_file:
csv_reader = csv.reader(csv_file)
while True:
row = next(csv_reader)
if len(row) < MULTIPLIER_COLUMN:
continue

if row[DEVICE_COLUMN] == "# Device Name":
assert row[MULTIPLIER_COLUMN] == "MPY_TYPE", "File format changed"
break

if row[0] == "Version:":
version = row[1]

for row in csv_reader:
if row[DEVICE_COLUMN].endswith("generic"):
continue
if row[MULTIPLIER_COLUMN] == MULTIPLIER_SW:
mcus_multiplier_sw.append(row[DEVICE_COLUMN])
elif row[MULTIPLIER_COLUMN] in MULTIPLIER_HW_16:
mcus_multiplier_hw_16.append(row[DEVICE_COLUMN])
elif row[MULTIPLIER_COLUMN] in MULTIPLIER_HW_32:
mcus_multiplier_hw_32.append(row[DEVICE_COLUMN])
else:
assert 0, "Unknown multiplier type"

with open(def_path, "w") as def_file:
def_file.write(PREFIX.format(version))

for mcu in mcus_multiplier_sw:
def_file.write(f'MSP430_MCU("{mcu}")\n')

def_file.write("\n// With 16-bit hardware multiplier\n")

for mcu in mcus_multiplier_hw_16:
def_file.write(f'MSP430_MCU_FEAT("{mcu}", "16bit")\n')

def_file.write("\n// With 32-bit hardware multiplier\n")

for mcu in mcus_multiplier_hw_32:
def_file.write(f'MSP430_MCU_FEAT("{mcu}", "32bit")\n')

def_file.write(SUFFIX)


if __name__ == "__main__":
if len(sys.argv) != 3:
sys.exit(f"Usage: {sys.argv[0]} <CSV_FILE> <DEF_FILE>")

csv2def(sys.argv[1], sys.argv[2])
3 changes: 2 additions & 1 deletion clang/include/clang/Driver/Distro.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ class Distro {
UbuntuLunar,
UbuntuMantic,
UbuntuNoble,
UbuntuOracular,
UnknownDistro
};

Expand Down Expand Up @@ -130,7 +131,7 @@ class Distro {
}

bool IsUbuntu() const {
return DistroVal >= UbuntuHardy && DistroVal <= UbuntuNoble;
return DistroVal >= UbuntuHardy && DistroVal <= UbuntuOracular;
}

bool IsAlpineLinux() const { return DistroVal == AlpineLinux; }
Expand Down
61 changes: 33 additions & 28 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -3383,10 +3383,10 @@ defm application_extension : BoolFOption<"application-extension",
"Restrict code to those available for App Extensions">,
NegFlag<SetFalse>>;
defm relaxed_template_template_args : BoolFOption<"relaxed-template-template-args",
LangOpts<"RelaxedTemplateTemplateArgs">, DefaultFalse,
PosFlag<SetTrue, [], [ClangOption, CC1Option],
"Enable C++17 relaxed template template argument matching">,
NegFlag<SetFalse>>;
LangOpts<"RelaxedTemplateTemplateArgs">, DefaultTrue,
PosFlag<SetTrue, [], [], "Enable">,
NegFlag<SetFalse, [], [CC1Option], "Disable">,
BothFlags<[], [ClangOption], " C++17 relaxed template template argument matching">>;
defm sized_deallocation : BoolFOption<"sized-deallocation",
LangOpts<"SizedDeallocation">, DefaultFalse,
PosFlag<SetTrue, [], [ClangOption, CC1Option],
Expand Down Expand Up @@ -3663,14 +3663,14 @@ defm rwpi : BoolFOption<"rwpi",
"Generate read-write position independent code (ARM only)">,
NegFlag<SetFalse, [], [ClangOption, FlangOption, CC1Option]>>;
def fplugin_EQ : Joined<["-"], "fplugin=">, Group<f_Group>,
Flags<[NoXarchOption]>, MetaVarName<"<dsopath>">,
Flags<[NoXarchOption, NoArgumentUnused]>, MetaVarName<"<dsopath>">,
HelpText<"Load the named plugin (dynamic shared object)">;
def fplugin_arg : Joined<["-"], "fplugin-arg-">,
MetaVarName<"<name>-<arg>">,
MetaVarName<"<name>-<arg>">, Flags<[NoArgumentUnused]>,
HelpText<"Pass <arg> to plugin <name>">;
def fpass_plugin_EQ : Joined<["-"], "fpass-plugin=">,
Group<f_Group>, Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>,
MetaVarName<"<dsopath>">,
MetaVarName<"<dsopath>">, Flags<[NoArgumentUnused]>,
HelpText<"Load pass plugin from a dynamic shared object file (only with new pass manager).">,
MarshallingInfoStringVector<CodeGenOpts<"PassPlugins">>;
defm tocdata : BoolOption<"m","tocdata",
Expand Down Expand Up @@ -3971,7 +3971,7 @@ def funroll_loops : Flag<["-"], "funroll-loops">, Group<f_Group>,
def fno_unroll_loops : Flag<["-"], "fno-unroll-loops">, Group<f_Group>,
HelpText<"Turn off loop unroller">, Visibility<[ClangOption, CC1Option]>;
def ffinite_loops: Flag<["-"], "ffinite-loops">, Group<f_Group>,
HelpText<"Assume all loops are finite.">, Visibility<[ClangOption, CC1Option]>;
HelpText<"Assume all non-trivial loops are finite.">, Visibility<[ClangOption, CC1Option]>;
def fno_finite_loops: Flag<["-"], "fno-finite-loops">, Group<f_Group>,
HelpText<"Do not assume that any loop is finite.">,
Visibility<[ClangOption, CC1Option]>;
Expand Down Expand Up @@ -4159,6 +4159,11 @@ defm unique_section_names : BoolFOption<"unique-section-names",
NegFlag<SetFalse, [], [ClangOption, CC1Option],
"Don't use unique names for text and data sections">,
PosFlag<SetTrue>>;
defm separate_named_sections : BoolFOption<"separate-named-sections",
CodeGenOpts<"SeparateNamedSections">, DefaultFalse,
PosFlag<SetTrue, [], [ClangOption, CC1Option],
"Use separate unique sections for named sections (ELF Only)">,
NegFlag<SetFalse>>;

defm split_machine_functions: BoolFOption<"split-machine-functions",
CodeGenOpts<"SplitMachineFunctions">, DefaultFalse,
Expand Down Expand Up @@ -4895,34 +4900,34 @@ def mharden_sls_EQ : Joined<["-"], "mharden-sls=">, Group<m_Group>,
" blr(ARM/AArch64), comdat(ARM/AArch64), nocomdat(ARM/AArch64),"
" return(X86), indirect-jmp(X86)">;

def msimd128 : Flag<["-"], "msimd128">, Group<m_wasm_Features_Group>;
def mno_simd128 : Flag<["-"], "mno-simd128">, Group<m_wasm_Features_Group>;
def mrelaxed_simd : Flag<["-"], "mrelaxed-simd">, Group<m_wasm_Features_Group>;
def mno_relaxed_simd : Flag<["-"], "mno-relaxed-simd">, Group<m_wasm_Features_Group>;
def mhalf_precision : Flag<["-"], "mhalf-precision">, Group<m_wasm_Features_Group>;
def mno_half_precision : Flag<["-"], "mno-half-precision">, Group<m_wasm_Features_Group>;
def mnontrapping_fptoint : Flag<["-"], "mnontrapping-fptoint">, Group<m_wasm_Features_Group>;
def mno_nontrapping_fptoint : Flag<["-"], "mno-nontrapping-fptoint">, Group<m_wasm_Features_Group>;
def msign_ext : Flag<["-"], "msign-ext">, Group<m_wasm_Features_Group>;
def mno_sign_ext : Flag<["-"], "mno-sign-ext">, Group<m_wasm_Features_Group>;
def mexception_handing : Flag<["-"], "mexception-handling">, Group<m_wasm_Features_Group>;
def mno_exception_handing : Flag<["-"], "mno-exception-handling">, Group<m_wasm_Features_Group>;
def matomics : Flag<["-"], "matomics">, Group<m_wasm_Features_Group>;
def mno_atomics : Flag<["-"], "mno-atomics">, Group<m_wasm_Features_Group>;
def mbulk_memory : Flag<["-"], "mbulk-memory">, Group<m_wasm_Features_Group>;
def mno_bulk_memory : Flag<["-"], "mno-bulk-memory">, Group<m_wasm_Features_Group>;
def mmutable_globals : Flag<["-"], "mmutable-globals">, Group<m_wasm_Features_Group>;
def mno_mutable_globals : Flag<["-"], "mno-mutable-globals">, Group<m_wasm_Features_Group>;
def mmultivalue : Flag<["-"], "mmultivalue">, Group<m_wasm_Features_Group>;
def mno_multivalue : Flag<["-"], "mno-multivalue">, Group<m_wasm_Features_Group>;
def mtail_call : Flag<["-"], "mtail-call">, Group<m_wasm_Features_Group>;
def mno_tail_call : Flag<["-"], "mno-tail-call">, Group<m_wasm_Features_Group>;
def mreference_types : Flag<["-"], "mreference-types">, Group<m_wasm_Features_Group>;
def mno_reference_types : Flag<["-"], "mno-reference-types">, Group<m_wasm_Features_Group>;
def mexception_handing : Flag<["-"], "mexception-handling">, Group<m_wasm_Features_Group>;
def mno_exception_handing : Flag<["-"], "mno-exception-handling">, Group<m_wasm_Features_Group>;
def mextended_const : Flag<["-"], "mextended-const">, Group<m_wasm_Features_Group>;
def mno_extended_const : Flag<["-"], "mno-extended-const">, Group<m_wasm_Features_Group>;
def mhalf_precision : Flag<["-"], "mhalf-precision">, Group<m_wasm_Features_Group>;
def mno_half_precision : Flag<["-"], "mno-half-precision">, Group<m_wasm_Features_Group>;
def mmultimemory : Flag<["-"], "mmultimemory">, Group<m_wasm_Features_Group>;
def mno_multimemory : Flag<["-"], "mno-multimemory">, Group<m_wasm_Features_Group>;
def mmultivalue : Flag<["-"], "mmultivalue">, Group<m_wasm_Features_Group>;
def mno_multivalue : Flag<["-"], "mno-multivalue">, Group<m_wasm_Features_Group>;
def mmutable_globals : Flag<["-"], "mmutable-globals">, Group<m_wasm_Features_Group>;
def mno_mutable_globals : Flag<["-"], "mno-mutable-globals">, Group<m_wasm_Features_Group>;
def mnontrapping_fptoint : Flag<["-"], "mnontrapping-fptoint">, Group<m_wasm_Features_Group>;
def mno_nontrapping_fptoint : Flag<["-"], "mno-nontrapping-fptoint">, Group<m_wasm_Features_Group>;
def mreference_types : Flag<["-"], "mreference-types">, Group<m_wasm_Features_Group>;
def mno_reference_types : Flag<["-"], "mno-reference-types">, Group<m_wasm_Features_Group>;
def mrelaxed_simd : Flag<["-"], "mrelaxed-simd">, Group<m_wasm_Features_Group>;
def mno_relaxed_simd : Flag<["-"], "mno-relaxed-simd">, Group<m_wasm_Features_Group>;
def msign_ext : Flag<["-"], "msign-ext">, Group<m_wasm_Features_Group>;
def mno_sign_ext : Flag<["-"], "mno-sign-ext">, Group<m_wasm_Features_Group>;
def msimd128 : Flag<["-"], "msimd128">, Group<m_wasm_Features_Group>;
def mno_simd128 : Flag<["-"], "mno-simd128">, Group<m_wasm_Features_Group>;
def mtail_call : Flag<["-"], "mtail-call">, Group<m_wasm_Features_Group>;
def mno_tail_call : Flag<["-"], "mno-tail-call">, Group<m_wasm_Features_Group>;
def mexec_model_EQ : Joined<["-"], "mexec-model=">, Group<m_wasm_Features_Driver_Group>,
Values<"command,reactor">,
HelpText<"Execution model (WebAssembly only)">,
Expand Down
40 changes: 37 additions & 3 deletions clang/include/clang/Format/Format.h
Original file line number Diff line number Diff line change
Expand Up @@ -375,8 +375,25 @@ struct FormatStyle {
/// }
/// \endcode
bool AcrossComments;
/// Whether aligned case labels are aligned on the colon, or on the
/// , or on the tokens after the colon.
/// Whether to align the case arrows when aligning short case expressions.
/// \code{.java}
/// true:
/// i = switch (day) {
/// case THURSDAY, SATURDAY -> 8;
/// case WEDNESDAY -> 9;
/// default -> 0;
/// };
///
/// false:
/// i = switch (day) {
/// case THURSDAY, SATURDAY -> 8;
/// case WEDNESDAY -> 9;
/// default -> 0;
/// };
/// \endcode
bool AlignCaseArrows;
/// Whether aligned case labels are aligned on the colon, or on the tokens
/// after the colon.
/// \code
/// true:
/// switch (level) {
Expand All @@ -396,12 +413,14 @@ struct FormatStyle {
bool operator==(const ShortCaseStatementsAlignmentStyle &R) const {
return Enabled == R.Enabled && AcrossEmptyLines == R.AcrossEmptyLines &&
AcrossComments == R.AcrossComments &&
AlignCaseArrows == R.AlignCaseArrows &&
AlignCaseColons == R.AlignCaseColons;
}
};

/// Style of aligning consecutive short case labels.
/// Only applies if ``AllowShortCaseLabelsOnASingleLine`` is ``true``.
/// Only applies if ``AllowShortCaseExpressionOnASingleLine`` or
/// ``AllowShortCaseLabelsOnASingleLine`` is ``true``.
///
/// \code{.yaml}
/// # Example of usage:
Expand Down Expand Up @@ -724,6 +743,19 @@ struct FormatStyle {
/// \version 3.5
ShortBlockStyle AllowShortBlocksOnASingleLine;

/// Whether to merge a short switch labeled rule into a single line.
/// \code{.java}
/// true: false:
/// switch (a) { vs. switch (a) {
/// case 1 -> 1; case 1 ->
/// default -> 0; 1;
/// }; default ->
/// 0;
/// };
/// \endcode
/// \version 19
bool AllowShortCaseExpressionOnASingleLine;

/// If ``true``, short case labels will be contracted to a single line.
/// \code
/// true: false:
Expand Down Expand Up @@ -4923,6 +4955,8 @@ struct FormatStyle {
AllowBreakBeforeNoexceptSpecifier ==
R.AllowBreakBeforeNoexceptSpecifier &&
AllowShortBlocksOnASingleLine == R.AllowShortBlocksOnASingleLine &&
AllowShortCaseExpressionOnASingleLine ==
R.AllowShortCaseExpressionOnASingleLine &&
AllowShortCaseLabelsOnASingleLine ==
R.AllowShortCaseLabelsOnASingleLine &&
AllowShortCompoundRequirementOnASingleLine ==
Expand Down
3 changes: 2 additions & 1 deletion clang/include/clang/InstallAPI/FileList.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,10 @@ class FileListReader {
///
/// \param InputBuffer JSON input data.
/// \param Destination Container to load headers into.
/// \param FM Optional File Manager to validate input files exist.
static llvm::Error
loadHeaders(std::unique_ptr<llvm::MemoryBuffer> InputBuffer,
HeaderSeq &Destination);
HeaderSeq &Destination, clang::FileManager *FM = nullptr);

FileListReader() = delete;
};
Expand Down
13 changes: 8 additions & 5 deletions clang/include/clang/Parse/Parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -3654,11 +3654,12 @@ class Parser : public CodeCompletionHandler {
ExprResult ParseOpenACCIDExpression();
/// Parses the variable list for the `cache` construct.
void ParseOpenACCCacheVarList();

using OpenACCVarParseResult = std::pair<ExprResult, OpenACCParseCanContinue>;
/// Parses a single variable in a variable list for OpenACC.
bool ParseOpenACCVar();
/// Parses the variable list for the variety of clauses that take a var-list,
/// including the optional Special Token listed for some,based on clause type.
bool ParseOpenACCClauseVarList(OpenACCClauseKind Kind);
OpenACCVarParseResult ParseOpenACCVar();
/// Parses the variable list for the variety of places that take a var-list.
llvm::SmallVector<Expr *> ParseOpenACCVarList();
/// Parses any parameters for an OpenACC Clause, including required/optional
/// parens.
OpenACCClauseParseResult
Expand Down Expand Up @@ -3697,7 +3698,9 @@ class Parser : public CodeCompletionHandler {
bool ParseOpenACCDeviceTypeList();
/// Parses the 'async-argument', which is an integral value with two
/// 'special' values that are likely negative (but come from Macros).
ExprResult ParseOpenACCAsyncArgument();
OpenACCIntExprParseResult ParseOpenACCAsyncArgument(OpenACCDirectiveKind DK,
OpenACCClauseKind CK,
SourceLocation Loc);
/// Parses the 'size-expr', which is an integral value, or an asterisk.
bool ParseOpenACCSizeExpr();
/// Parses a comma delimited list of 'size-expr's.
Expand Down
4 changes: 3 additions & 1 deletion clang/include/clang/Sema/Lookup.h
Original file line number Diff line number Diff line change
Expand Up @@ -499,7 +499,9 @@ class LookupResult {
/// Note that while no result was found in the current instantiation,
/// there were dependent base classes that could not be searched.
void setNotFoundInCurrentInstantiation() {
assert(ResultKind == NotFound && Decls.empty());
assert((ResultKind == NotFound ||
ResultKind == NotFoundInCurrentInstantiation) &&
Decls.empty());
ResultKind = NotFoundInCurrentInstantiation;
}

Expand Down
43 changes: 22 additions & 21 deletions clang/include/clang/Sema/Sema.h
Original file line number Diff line number Diff line change
Expand Up @@ -4097,12 +4097,12 @@ class Sema final : public SemaBase {
SmallVectorImpl<QualType> &Exceptions,
FunctionProtoType::ExceptionSpecInfo &ESI);

/// Add an exception-specification to the given member function
/// (or member function template). The exception-specification was parsed
/// after the method itself was declared.
/// Add an exception-specification to the given member or friend function
/// (or function template). The exception-specification was parsed
/// after the function itself was declared.
void actOnDelayedExceptionSpecification(
Decl *Method, ExceptionSpecificationType EST,
SourceRange SpecificationRange, ArrayRef<ParsedType> DynamicExceptions,
Decl *D, ExceptionSpecificationType EST, SourceRange SpecificationRange,
ArrayRef<ParsedType> DynamicExceptions,
ArrayRef<SourceRange> DynamicExceptionRanges, Expr *NoexceptExpr);

class InheritedConstructorInfo;
Expand Down Expand Up @@ -6978,12 +6978,6 @@ class Sema final : public SemaBase {
SourceLocation TemplateKWLoc,
UnqualifiedId &Member, Decl *ObjCImpDecl);

MemberExpr *BuildMemberExpr(
Expr *Base, bool IsArrow, SourceLocation OpLoc, const CXXScopeSpec *SS,
SourceLocation TemplateKWLoc, ValueDecl *Member, DeclAccessPair FoundDecl,
bool HadMultipleCandidates, const DeclarationNameInfo &MemberNameInfo,
QualType Ty, ExprValueKind VK, ExprObjectKind OK,
const TemplateArgumentListInfo *TemplateArgs = nullptr);
MemberExpr *
BuildMemberExpr(Expr *Base, bool IsArrow, SourceLocation OpLoc,
NestedNameSpecifierLoc NNS, SourceLocation TemplateKWLoc,
Expand Down Expand Up @@ -7472,7 +7466,7 @@ class Sema final : public SemaBase {
bool LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx,
CXXScopeSpec &SS);
bool LookupParsedName(LookupResult &R, Scope *S, CXXScopeSpec *SS,
bool AllowBuiltinCreation = false,
QualType ObjectType, bool AllowBuiltinCreation = false,
bool EnteringContext = false);
ObjCProtocolDecl *LookupProtocol(
IdentifierInfo *II, SourceLocation IdLoc,
Expand Down Expand Up @@ -8881,11 +8875,13 @@ class Sema final : public SemaBase {
/// functions (but no function templates).
FoundFunctions,
};
bool LookupTemplateName(
LookupResult &R, Scope *S, CXXScopeSpec &SS, QualType ObjectType,
bool EnteringContext, bool &MemberOfUnknownSpecialization,
RequiredTemplateKind RequiredTemplate = SourceLocation(),
AssumedTemplateKind *ATK = nullptr, bool AllowTypoCorrection = true);

bool
LookupTemplateName(LookupResult &R, Scope *S, CXXScopeSpec &SS,
QualType ObjectType, bool EnteringContext,
RequiredTemplateKind RequiredTemplate = SourceLocation(),
AssumedTemplateKind *ATK = nullptr,
bool AllowTypoCorrection = true);

TemplateNameKind isTemplateName(Scope *S, CXXScopeSpec &SS,
bool hasTemplateKeyword,
Expand Down Expand Up @@ -9249,7 +9245,8 @@ class Sema final : public SemaBase {
void NoteTemplateParameterLocation(const NamedDecl &Decl);

ExprResult BuildExpressionFromDeclTemplateArgument(
const TemplateArgument &Arg, QualType ParamType, SourceLocation Loc);
const TemplateArgument &Arg, QualType ParamType, SourceLocation Loc,
NamedDecl *TemplateParam = nullptr);
ExprResult
BuildExpressionFromNonTypeTemplateArgument(const TemplateArgument &Arg,
SourceLocation Loc);
Expand Down Expand Up @@ -9572,9 +9569,10 @@ class Sema final : public SemaBase {

bool isSameOrCompatibleFunctionType(QualType Param, QualType Arg);

TemplateArgumentLoc getTrivialTemplateArgumentLoc(const TemplateArgument &Arg,
QualType NTTPType,
SourceLocation Loc);
TemplateArgumentLoc
getTrivialTemplateArgumentLoc(const TemplateArgument &Arg, QualType NTTPType,
SourceLocation Loc,
NamedDecl *TemplateParam = nullptr);

/// Get a template argument mapping the given template parameter to itself,
/// e.g. for X in \c template<int X>, this would return an expression template
Expand Down Expand Up @@ -9741,6 +9739,9 @@ class Sema final : public SemaBase {
const PartialDiagnostic &CandidateDiag,
bool Complain = true, QualType TargetType = QualType());

FunctionDecl *getMoreConstrainedFunction(FunctionDecl *FD1,
FunctionDecl *FD2);

///@}

//
Expand Down
145 changes: 143 additions & 2 deletions clang/include/clang/Sema/SemaOpenACC.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,14 @@ class SemaOpenACC : public SemaBase {
SmallVector<Expr *> IntExprs;
};

struct VarListDetails {
SmallVector<Expr *> VarList;
bool IsReadOnly;
bool IsZero;
};

std::variant<std::monostate, DefaultDetails, ConditionDetails,
IntExprDetails>
IntExprDetails, VarListDetails>
Details = std::monostate{};

public:
Expand Down Expand Up @@ -95,23 +101,77 @@ class SemaOpenACC : public SemaBase {
unsigned getNumIntExprs() const {
assert((ClauseKind == OpenACCClauseKind::NumGangs ||
ClauseKind == OpenACCClauseKind::NumWorkers ||
ClauseKind == OpenACCClauseKind::Async ||
ClauseKind == OpenACCClauseKind::VectorLength) &&
"Parsed clause kind does not have a int exprs");
//
// 'async' has an optional IntExpr, so be tolerant of that.
if (ClauseKind == OpenACCClauseKind::Async &&
std::holds_alternative<std::monostate>(Details))
return 0;
return std::get<IntExprDetails>(Details).IntExprs.size();
}

ArrayRef<Expr *> getIntExprs() {
assert((ClauseKind == OpenACCClauseKind::NumGangs ||
ClauseKind == OpenACCClauseKind::NumWorkers ||
ClauseKind == OpenACCClauseKind::Async ||
ClauseKind == OpenACCClauseKind::VectorLength) &&
"Parsed clause kind does not have a int exprs");

return std::get<IntExprDetails>(Details).IntExprs;
}

ArrayRef<Expr *> getIntExprs() const {
return const_cast<OpenACCParsedClause *>(this)->getIntExprs();
}

ArrayRef<Expr *> getVarList() {
assert((ClauseKind == OpenACCClauseKind::Private ||
ClauseKind == OpenACCClauseKind::NoCreate ||
ClauseKind == OpenACCClauseKind::Present ||
ClauseKind == OpenACCClauseKind::Copy ||
ClauseKind == OpenACCClauseKind::PCopy ||
ClauseKind == OpenACCClauseKind::PresentOrCopy ||
ClauseKind == OpenACCClauseKind::CopyIn ||
ClauseKind == OpenACCClauseKind::PCopyIn ||
ClauseKind == OpenACCClauseKind::PresentOrCopyIn ||
ClauseKind == OpenACCClauseKind::CopyOut ||
ClauseKind == OpenACCClauseKind::PCopyOut ||
ClauseKind == OpenACCClauseKind::PresentOrCopyOut ||
ClauseKind == OpenACCClauseKind::Create ||
ClauseKind == OpenACCClauseKind::PCreate ||
ClauseKind == OpenACCClauseKind::PresentOrCreate ||
ClauseKind == OpenACCClauseKind::Attach ||
ClauseKind == OpenACCClauseKind::DevicePtr ||
ClauseKind == OpenACCClauseKind::FirstPrivate) &&
"Parsed clause kind does not have a var-list");
return std::get<VarListDetails>(Details).VarList;
}

ArrayRef<Expr *> getVarList() const {
return const_cast<OpenACCParsedClause *>(this)->getVarList();
}

bool isReadOnly() const {
assert((ClauseKind == OpenACCClauseKind::CopyIn ||
ClauseKind == OpenACCClauseKind::PCopyIn ||
ClauseKind == OpenACCClauseKind::PresentOrCopyIn) &&
"Only copyin accepts 'readonly:' tag");
return std::get<VarListDetails>(Details).IsReadOnly;
}

bool isZero() const {
assert((ClauseKind == OpenACCClauseKind::CopyOut ||
ClauseKind == OpenACCClauseKind::PCopyOut ||
ClauseKind == OpenACCClauseKind::PresentOrCopyOut ||
ClauseKind == OpenACCClauseKind::Create ||
ClauseKind == OpenACCClauseKind::PCreate ||
ClauseKind == OpenACCClauseKind::PresentOrCreate) &&
"Only copyout/create accepts 'zero' tag");
return std::get<VarListDetails>(Details).IsZero;
}

void setLParenLoc(SourceLocation EndLoc) { LParenLoc = EndLoc; }
void setEndLoc(SourceLocation EndLoc) { ClauseRange.setEnd(EndLoc); }

Expand All @@ -138,16 +198,89 @@ class SemaOpenACC : public SemaBase {
void setIntExprDetails(ArrayRef<Expr *> IntExprs) {
assert((ClauseKind == OpenACCClauseKind::NumGangs ||
ClauseKind == OpenACCClauseKind::NumWorkers ||
ClauseKind == OpenACCClauseKind::Async ||
ClauseKind == OpenACCClauseKind::VectorLength) &&
"Parsed clause kind does not have a int exprs");
Details = IntExprDetails{{IntExprs.begin(), IntExprs.end()}};
}
void setIntExprDetails(llvm::SmallVector<Expr *> &&IntExprs) {
assert((ClauseKind == OpenACCClauseKind::NumGangs ||
ClauseKind == OpenACCClauseKind::NumWorkers ||
ClauseKind == OpenACCClauseKind::Async ||
ClauseKind == OpenACCClauseKind::VectorLength) &&
"Parsed clause kind does not have a int exprs");
Details = IntExprDetails{IntExprs};
Details = IntExprDetails{std::move(IntExprs)};
}

void setVarListDetails(ArrayRef<Expr *> VarList, bool IsReadOnly,
bool IsZero) {
assert((ClauseKind == OpenACCClauseKind::Private ||
ClauseKind == OpenACCClauseKind::NoCreate ||
ClauseKind == OpenACCClauseKind::Present ||
ClauseKind == OpenACCClauseKind::Copy ||
ClauseKind == OpenACCClauseKind::PCopy ||
ClauseKind == OpenACCClauseKind::PresentOrCopy ||
ClauseKind == OpenACCClauseKind::CopyIn ||
ClauseKind == OpenACCClauseKind::PCopyIn ||
ClauseKind == OpenACCClauseKind::PresentOrCopyIn ||
ClauseKind == OpenACCClauseKind::CopyOut ||
ClauseKind == OpenACCClauseKind::PCopyOut ||
ClauseKind == OpenACCClauseKind::PresentOrCopyOut ||
ClauseKind == OpenACCClauseKind::Create ||
ClauseKind == OpenACCClauseKind::PCreate ||
ClauseKind == OpenACCClauseKind::PresentOrCreate ||
ClauseKind == OpenACCClauseKind::Attach ||
ClauseKind == OpenACCClauseKind::DevicePtr ||
ClauseKind == OpenACCClauseKind::FirstPrivate) &&
"Parsed clause kind does not have a var-list");
assert((!IsReadOnly || ClauseKind == OpenACCClauseKind::CopyIn ||
ClauseKind == OpenACCClauseKind::PCopyIn ||
ClauseKind == OpenACCClauseKind::PresentOrCopyIn) &&
"readonly: tag only valid on copyin");
assert((!IsZero || ClauseKind == OpenACCClauseKind::CopyOut ||
ClauseKind == OpenACCClauseKind::PCopyOut ||
ClauseKind == OpenACCClauseKind::PresentOrCopyOut ||
ClauseKind == OpenACCClauseKind::Create ||
ClauseKind == OpenACCClauseKind::PCreate ||
ClauseKind == OpenACCClauseKind::PresentOrCreate) &&
"zero: tag only valid on copyout/create");
Details =
VarListDetails{{VarList.begin(), VarList.end()}, IsReadOnly, IsZero};
}

void setVarListDetails(llvm::SmallVector<Expr *> &&VarList, bool IsReadOnly,
bool IsZero) {
assert((ClauseKind == OpenACCClauseKind::Private ||
ClauseKind == OpenACCClauseKind::NoCreate ||
ClauseKind == OpenACCClauseKind::Present ||
ClauseKind == OpenACCClauseKind::Copy ||
ClauseKind == OpenACCClauseKind::PCopy ||
ClauseKind == OpenACCClauseKind::PresentOrCopy ||
ClauseKind == OpenACCClauseKind::CopyIn ||
ClauseKind == OpenACCClauseKind::PCopyIn ||
ClauseKind == OpenACCClauseKind::PresentOrCopyIn ||
ClauseKind == OpenACCClauseKind::CopyOut ||
ClauseKind == OpenACCClauseKind::PCopyOut ||
ClauseKind == OpenACCClauseKind::PresentOrCopyOut ||
ClauseKind == OpenACCClauseKind::Create ||
ClauseKind == OpenACCClauseKind::PCreate ||
ClauseKind == OpenACCClauseKind::PresentOrCreate ||
ClauseKind == OpenACCClauseKind::Attach ||
ClauseKind == OpenACCClauseKind::DevicePtr ||
ClauseKind == OpenACCClauseKind::FirstPrivate) &&
"Parsed clause kind does not have a var-list");
assert((!IsReadOnly || ClauseKind == OpenACCClauseKind::CopyIn ||
ClauseKind == OpenACCClauseKind::PCopyIn ||
ClauseKind == OpenACCClauseKind::PresentOrCopyIn) &&
"readonly: tag only valid on copyin");
assert((!IsZero || ClauseKind == OpenACCClauseKind::CopyOut ||
ClauseKind == OpenACCClauseKind::PCopyOut ||
ClauseKind == OpenACCClauseKind::PresentOrCopyOut ||
ClauseKind == OpenACCClauseKind::Create ||
ClauseKind == OpenACCClauseKind::PCreate ||
ClauseKind == OpenACCClauseKind::PresentOrCreate) &&
"zero: tag only valid on copyout/create");
Details = VarListDetails{std::move(VarList), IsReadOnly, IsZero};
}
};

Expand Down Expand Up @@ -194,6 +327,14 @@ class SemaOpenACC : public SemaBase {
ExprResult ActOnIntExpr(OpenACCDirectiveKind DK, OpenACCClauseKind CK,
SourceLocation Loc, Expr *IntExpr);

/// Called when encountering a 'var' for OpenACC, ensures it is actually a
/// declaration reference to a variable of the correct type.
ExprResult ActOnVar(Expr *VarExpr);

/// Called to check the 'var' type is a variable of pointer type, necessary
/// for 'deviceptr' and 'attach' clauses. Returns true on success.
bool CheckVarIsPointerType(OpenACCClauseKind ClauseKind, Expr *VarExpr);

/// Checks and creates an Array Section used in an OpenACC construct/clause.
ExprResult ActOnArraySectionExpr(Expr *Base, SourceLocation LBLoc,
Expr *LowerBound,
Expand Down
122 changes: 61 additions & 61 deletions clang/include/clang/Serialization/ASTBitCodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/OperatorKinds.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Serialization/SourceLocationEncoding.h"
#include "llvm/ADT/DenseMapInfo.h"
#include "llvm/Bitstream/BitCodes.h"
#include <cassert>
Expand Down Expand Up @@ -165,99 +166,95 @@ using SubmoduleID = uint32_t;
/// The number of predefined submodule IDs.
const unsigned int NUM_PREDEF_SUBMODULE_IDS = 1;

/// 32 aligned uint64_t in the AST file. Use splitted 64-bit integer into
/// low/high parts to keep structure alignment 32-bit (it is important
/// because blobs in bitstream are 32-bit aligned). This structure is
/// serialized "as is" to the AST file.
class UnalignedUInt64 {
uint32_t BitLow = 0;
uint32_t BitHigh = 0;

public:
UnalignedUInt64() = default;
UnalignedUInt64(uint64_t BitOffset) { set(BitOffset); }

void set(uint64_t Offset) {
BitLow = Offset;
BitHigh = Offset >> 32;
}

uint64_t get() const { return BitLow | (uint64_t(BitHigh) << 32); }
};

/// Source range/offset of a preprocessed entity.
struct PPEntityOffset {
class PPEntityOffset {
using RawLocEncoding = SourceLocationEncoding::RawLocEncoding;

/// Raw source location of beginning of range.
SourceLocation::UIntTy Begin;
UnalignedUInt64 Begin;

/// Raw source location of end of range.
SourceLocation::UIntTy End;
UnalignedUInt64 End;

/// Offset in the AST file relative to ModuleFile::MacroOffsetsBase.
uint32_t BitOffset;

PPEntityOffset(SourceRange R, uint32_t BitOffset)
: Begin(R.getBegin().getRawEncoding()), End(R.getEnd().getRawEncoding()),
BitOffset(BitOffset) {}
public:
PPEntityOffset(RawLocEncoding Begin, RawLocEncoding End, uint32_t BitOffset)
: Begin(Begin), End(End), BitOffset(BitOffset) {}

SourceLocation getBegin() const {
return SourceLocation::getFromRawEncoding(Begin);
}
RawLocEncoding getBegin() const { return Begin.get(); }
RawLocEncoding getEnd() const { return End.get(); }

SourceLocation getEnd() const {
return SourceLocation::getFromRawEncoding(End);
}
uint32_t getOffset() const { return BitOffset; }
};

/// Source range of a skipped preprocessor region
struct PPSkippedRange {
class PPSkippedRange {
using RawLocEncoding = SourceLocationEncoding::RawLocEncoding;

/// Raw source location of beginning of range.
SourceLocation::UIntTy Begin;
UnalignedUInt64 Begin;
/// Raw source location of end of range.
SourceLocation::UIntTy End;
UnalignedUInt64 End;

PPSkippedRange(SourceRange R)
: Begin(R.getBegin().getRawEncoding()), End(R.getEnd().getRawEncoding()) {
}
public:
PPSkippedRange(RawLocEncoding Begin, RawLocEncoding End)
: Begin(Begin), End(End) {}

SourceLocation getBegin() const {
return SourceLocation::getFromRawEncoding(Begin);
}
SourceLocation getEnd() const {
return SourceLocation::getFromRawEncoding(End);
}
RawLocEncoding getBegin() const { return Begin.get(); }
RawLocEncoding getEnd() const { return End.get(); }
};

/// Offset in the AST file. Use splitted 64-bit integer into low/high
/// parts to keep structure alignment 32-bit (it is important because
/// blobs in bitstream are 32-bit aligned). This structure is serialized
/// "as is" to the AST file.
struct UnderalignedInt64 {
uint32_t BitOffsetLow = 0;
uint32_t BitOffsetHigh = 0;

UnderalignedInt64() = default;
UnderalignedInt64(uint64_t BitOffset) { setBitOffset(BitOffset); }

void setBitOffset(uint64_t Offset) {
BitOffsetLow = Offset;
BitOffsetHigh = Offset >> 32;
}

uint64_t getBitOffset() const {
return BitOffsetLow | (uint64_t(BitOffsetHigh) << 32);
}
};
/// Source location and bit offset of a declaration. Keep
/// structure alignment 32-bit since the blob is assumed as 32-bit aligned.
class DeclOffset {
using RawLocEncoding = SourceLocationEncoding::RawLocEncoding;

/// Source location and bit offset of a declaration.
struct DeclOffset {
/// Raw source location.
SourceLocation::UIntTy Loc = 0;
UnalignedUInt64 RawLoc;

/// Offset relative to the start of the DECLTYPES_BLOCK block. Keep
/// structure alignment 32-bit and avoid padding gap because undefined
/// value in the padding affects AST hash.
UnderalignedInt64 BitOffset;
/// Offset relative to the start of the DECLTYPES_BLOCK block.
UnalignedUInt64 BitOffset;

public:
DeclOffset() = default;
DeclOffset(SourceLocation Loc, uint64_t BitOffset,
uint64_t DeclTypesBlockStartOffset) {
setLocation(Loc);
DeclOffset(RawLocEncoding RawLoc, uint64_t BitOffset,
uint64_t DeclTypesBlockStartOffset)
: RawLoc(RawLoc) {
setBitOffset(BitOffset, DeclTypesBlockStartOffset);
}

void setLocation(SourceLocation L) { Loc = L.getRawEncoding(); }
void setRawLoc(RawLocEncoding Loc) { RawLoc = Loc; }

SourceLocation getLocation() const {
return SourceLocation::getFromRawEncoding(Loc);
}
RawLocEncoding getRawLoc() const { return RawLoc.get(); }

void setBitOffset(uint64_t Offset, const uint64_t DeclTypesBlockStartOffset) {
BitOffset.setBitOffset(Offset - DeclTypesBlockStartOffset);
BitOffset.set(Offset - DeclTypesBlockStartOffset);
}

uint64_t getBitOffset(const uint64_t DeclTypesBlockStartOffset) const {
return BitOffset.getBitOffset() + DeclTypesBlockStartOffset;
return BitOffset.get() + DeclTypesBlockStartOffset;
}
};

Expand Down Expand Up @@ -1091,6 +1088,9 @@ enum PredefinedTypeIDs {
// \brief WebAssembly reference types with auto numeration
#define WASM_TYPE(Name, Id, SingletonId) PREDEF_TYPE_##Id##_ID,
#include "clang/Basic/WebAssemblyReferenceTypes.def"

/// The placeholder type for unresolved templates.
PREDEF_TYPE_UNRESOLVED_TEMPLATE,
// Sentinel value. Considered a predefined type but not useable as one.
PREDEF_TYPE_LAST_ID
};
Expand All @@ -1100,7 +1100,7 @@ enum PredefinedTypeIDs {
///
/// Type IDs for non-predefined types will start at
/// NUM_PREDEF_TYPE_IDs.
const unsigned NUM_PREDEF_TYPE_IDS = 502;
const unsigned NUM_PREDEF_TYPE_IDS = 503;

// Ensure we do not overrun the predefined types we reserved
// in the enum PredefinedTypeIDs above.
Expand Down
48 changes: 31 additions & 17 deletions clang/include/clang/Serialization/ASTReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -1771,6 +1771,7 @@ class ASTReader

/// Retrieve the module manager.
ModuleManager &getModuleManager() { return ModuleMgr; }
const ModuleManager &getModuleManager() const { return ModuleMgr; }

/// Retrieve the preprocessor.
Preprocessor &getPreprocessor() const { return PP; }
Expand Down Expand Up @@ -2177,8 +2178,8 @@ class ASTReader

/// Retrieve the global submodule ID given a module and its local ID
/// number.
serialization::SubmoduleID
getGlobalSubmoduleID(ModuleFile &M, unsigned LocalID);
serialization::SubmoduleID getGlobalSubmoduleID(ModuleFile &M,
unsigned LocalID) const;

/// Retrieve the submodule that corresponds to a global submodule ID.
///
Expand All @@ -2191,7 +2192,7 @@ class ASTReader

/// Retrieve the module file with a given local ID within the specified
/// ModuleFile.
ModuleFile *getLocalModuleFile(ModuleFile &M, unsigned ID);
ModuleFile *getLocalModuleFile(ModuleFile &M, unsigned ID) const;

/// Get an ID for the given module file.
unsigned getModuleFileID(ModuleFile *M);
Expand Down Expand Up @@ -2227,33 +2228,46 @@ class ASTReader
return Sema::AlignPackInfo::getFromRawEncoding(Raw);
}

using RawLocEncoding = SourceLocationEncoding::RawLocEncoding;

/// Read a source location from raw form and return it in its
/// originating module file's source location space.
SourceLocation ReadUntranslatedSourceLocation(SourceLocation::UIntTy Raw,
LocSeq *Seq = nullptr) const {
std::pair<SourceLocation, unsigned>
ReadUntranslatedSourceLocation(RawLocEncoding Raw,
LocSeq *Seq = nullptr) const {
return SourceLocationEncoding::decode(Raw, Seq);
}

/// Read a source location from raw form.
SourceLocation ReadSourceLocation(ModuleFile &ModuleFile,
SourceLocation::UIntTy Raw,
SourceLocation ReadSourceLocation(ModuleFile &MF, RawLocEncoding Raw,
LocSeq *Seq = nullptr) const {
SourceLocation Loc = ReadUntranslatedSourceLocation(Raw, Seq);
return TranslateSourceLocation(ModuleFile, Loc);
if (!MF.ModuleOffsetMap.empty())
ReadModuleOffsetMap(MF);

auto [Loc, ModuleFileIndex] = ReadUntranslatedSourceLocation(Raw, Seq);
ModuleFile *OwningModuleFile =
ModuleFileIndex == 0 ? &MF : MF.DependentModules[ModuleFileIndex - 1];

assert(!SourceMgr.isLoadedSourceLocation(Loc) &&
"Run out source location space");

return TranslateSourceLocation(*OwningModuleFile, Loc);
}

/// Translate a source location from another module file's source
/// location space into ours.
SourceLocation TranslateSourceLocation(ModuleFile &ModuleFile,
SourceLocation Loc) const {
if (!ModuleFile.ModuleOffsetMap.empty())
ReadModuleOffsetMap(ModuleFile);
assert(ModuleFile.SLocRemap.find(Loc.getOffset()) !=
ModuleFile.SLocRemap.end() &&
"Cannot find offset to remap.");
SourceLocation::IntTy Remap =
ModuleFile.SLocRemap.find(Loc.getOffset())->second;
return Loc.getLocWithOffset(Remap);
if (Loc.isInvalid())
return Loc;

// FIXME: TranslateSourceLocation is not re-enterable. It is problematic
// to call TranslateSourceLocation on a translated source location.
// We either need a method to know whether or not a source location is
// translated or refactor the code to make it clear that
// TranslateSourceLocation won't be called with translated source location.

return Loc.getLocWithOffset(ModuleFile.SLocEntryBaseOffset - 2);
}

/// Read a source location.
Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/Serialization/ASTRecordReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,9 @@ class ASTRecordReader
/// Read an OpenMP children, advancing Idx.
void readOMPChildren(OMPChildren *Data);

/// Read a list of Exprs used for a var-list.
llvm::SmallVector<Expr *> readOpenACCVarList();

/// Read an OpenACC clause, advancing Idx.
OpenACCClause *readOpenACCClause();

Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/Serialization/ASTRecordWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#define LLVM_CLANG_SERIALIZATION_ASTRECORDWRITER_H

#include "clang/AST/AbstractBasicWriter.h"
#include "clang/AST/OpenACCClause.h"
#include "clang/AST/OpenMPClause.h"
#include "clang/Serialization/ASTWriter.h"
#include "clang/Serialization/SourceLocationEncoding.h"
Expand Down Expand Up @@ -293,6 +294,8 @@ class ASTRecordWriter
/// Writes data related to the OpenMP directives.
void writeOMPChildren(OMPChildren *Data);

void writeOpenACCVarList(const OpenACCClauseWithVarList *C);

/// Writes out a single OpenACC Clause.
void writeOpenACCClause(const OpenACCClause *C);

Expand Down
29 changes: 28 additions & 1 deletion clang/include/clang/Serialization/ASTWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,10 @@ class StoredDeclsList;
class SwitchCase;
class Token;

namespace SrcMgr {
class FileInfo;
} // namespace SrcMgr

/// Writes an AST file containing the contents of a translation unit.
///
/// The ASTWriter class produces a bitstream containing the serialized
Expand Down Expand Up @@ -270,7 +274,7 @@ class ASTWriter : public ASTDeserializationListener,

/// Offset of each type in the bitstream, indexed by
/// the type's ID.
std::vector<serialization::UnderalignedInt64> TypeOffsets;
std::vector<serialization::UnalignedUInt64> TypeOffsets;

/// The first ID number we can use for our own identifiers.
serialization::IdentID FirstIdentID = serialization::NUM_PREDEF_IDENT_IDS;
Expand Down Expand Up @@ -353,6 +357,13 @@ class ASTWriter : public ASTDeserializationListener,
/// contexts.
llvm::DenseMap<const Decl *, unsigned> AnonymousDeclarationNumbers;

/// The external top level module during the writing process. Used to
/// generate signature for the module file being written.
///
/// Only meaningful for standard C++ named modules. See the comments in
/// createSignatureForNamedModule() for details.
llvm::DenseSet<Module *> TouchedTopLevelModules;

/// An update to a Decl.
class DeclUpdate {
/// A DeclUpdateKind.
Expand Down Expand Up @@ -490,6 +501,11 @@ class ASTWriter : public ASTDeserializationListener,
/// during \c SourceManager serialization.
void computeNonAffectingInputFiles();

/// Some affecting files can be included from files that are not affecting.
/// This function erases source locations pointing into such files.
SourceLocation getAffectingIncludeLoc(const SourceManager &SourceMgr,
const SrcMgr::FileInfo &File);

/// Returns an adjusted \c FileID, accounting for any non-affecting input
/// files.
FileID getAdjustedFileID(FileID FID) const;
Expand Down Expand Up @@ -525,6 +541,7 @@ class ASTWriter : public ASTDeserializationListener,

/// Calculate hash of the pcm content.
std::pair<ASTFileSignature, ASTFileSignature> createSignature() const;
ASTFileSignature createSignatureForNamedModule() const;

void WriteInputFiles(SourceManager &SourceMgr, HeaderSearchOptions &HSOpts);
void WriteSourceManagerBlock(SourceManager &SourceMgr,
Expand Down Expand Up @@ -666,6 +683,10 @@ class ASTWriter : public ASTDeserializationListener,
void AddSourceLocation(SourceLocation Loc, RecordDataImpl &Record,
LocSeq *Seq = nullptr);

/// Return the raw encodings for source locations.
SourceLocationEncoding::RawLocEncoding
getRawSourceLocationEncoding(SourceLocation Loc, LocSeq *Seq = nullptr);

/// Emit a source range.
void AddSourceRange(SourceRange Range, RecordDataImpl &Record,
LocSeq *Seq = nullptr);
Expand Down Expand Up @@ -885,6 +906,8 @@ class ASTWriter : public ASTDeserializationListener,
/// AST and semantic-analysis consumer that generates a
/// precompiled header from the parsed source code.
class PCHGenerator : public SemaConsumer {
void anchor() override;

Preprocessor &PP;
std::string OutputFile;
std::string isysroot;
Expand Down Expand Up @@ -929,6 +952,8 @@ class PCHGenerator : public SemaConsumer {
};

class CXX20ModulesGenerator : public PCHGenerator {
void anchor() override;

protected:
virtual Module *getEmittingModule(ASTContext &Ctx) override;

Expand All @@ -945,6 +970,8 @@ class CXX20ModulesGenerator : public PCHGenerator {
};

class ReducedBMIGenerator : public CXX20ModulesGenerator {
void anchor() override;

public:
ReducedBMIGenerator(Preprocessor &PP, InMemoryModuleCache &ModuleCache,
StringRef OutputFile)
Expand Down
16 changes: 10 additions & 6 deletions clang/include/clang/Serialization/ModuleFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -295,10 +295,6 @@ class ModuleFile {
/// AST file.
const uint32_t *SLocEntryOffsets = nullptr;

/// Remapping table for source locations in this module.
ContinuousRangeMap<SourceLocation::UIntTy, SourceLocation::IntTy, 2>
SLocRemap;

// === Identifiers ===

/// The number of identifiers in this AST file.
Expand Down Expand Up @@ -495,7 +491,7 @@ class ModuleFile {

/// Offset of each type within the bitstream, indexed by the
/// type ID, or the representation of a Type*.
const UnderalignedInt64 *TypeOffsets = nullptr;
const UnalignedUInt64 *TypeOffsets = nullptr;

/// Base type ID for types local to this module as represented in
/// the global type ID space.
Expand All @@ -512,9 +508,17 @@ class ModuleFile {
/// List of modules which depend on this module
llvm::SetVector<ModuleFile *> ImportedBy;

/// List of modules which this module depends on
/// List of modules which this module directly imported
llvm::SetVector<ModuleFile *> Imports;

/// List of modules which this modules dependent on. Different
/// from `Imports`, this includes indirectly imported modules too.
/// The order of DependentModules is significant. It should keep
/// the same order with that module file manager when we write
/// the current module file. The value of the member will be initialized
/// in `ASTReader::ReadModuleOffsetMap`.
llvm::SmallVector<ModuleFile *, 16> DependentModules;

/// Determine whether this module was directly imported at
/// any point during translation.
bool isDirectlyImported() const { return DirectlyImported; }
Expand Down
91 changes: 65 additions & 26 deletions clang/include/clang/Serialization/SourceLocationEncoding.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,33 @@
//
//===----------------------------------------------------------------------===//
//
// Source locations are stored pervasively in the AST, making up a third of
// the size of typical serialized files. Storing them efficiently is important.
// We wish to encode the SourceLocation from other module file not dependent
// on the other module file. So that the source location changes from other
// module file may not affect the contents of the current module file. Then the
// users don't need to recompile the whole project due to a new line in a module
// unit in the root of the dependency graph.
//
// We use integers optimized by VBR-encoding, because:
// - when abbreviations cannot be used, VBR6 encoding is our only choice
// - in the worst case a SourceLocation can be ~any 32-bit number, but in
// practice they are highly predictable
// To achieve this, we need to encode the index of the module file into the
// encoding of the source location. The encoding of the source location may be:
//
// We encode the integer so that likely values encode as small numbers that
// turn into few VBR chunks:
// - the invalid sentinel location is a very common value: it encodes as 0
// - the "macro or not" bit is stored at the bottom of the integer
// (rather than at the top, as in memory), so macro locations can have
// small representations.
// - related locations (e.g. of a left and right paren pair) are usually
// similar, so when encoding a sequence of locations we store only
// differences between successive elements.
// |-----------------------|-----------------------|
// | A | B | C |
//
// * A: 32 bit. The index of the module file in the module manager + 1. The +1
// here is necessary since we wish 0 stands for the current module file.
// * B: 31 bit. The offset of the source location to the module file containing
// it.
// * C: The macro bit. We rotate it to the lowest bit so that we can save some
// space in case the index of the module file is 0.
//
// Specially, if the index of the module file is 0, we allow to encode a
// sequence of locations we store only differences between successive elements.
//
//===----------------------------------------------------------------------===//

#include <climits>
#include "clang/Basic/SourceLocation.h"
#include "llvm/Support/MathExtras.h"
#include <climits>

#ifndef LLVM_CLANG_SERIALIZATION_SOURCELOCATIONENCODING_H
#define LLVM_CLANG_SERIALIZATION_SOURCELOCATIONENCODING_H
Expand All @@ -52,9 +57,13 @@ class SourceLocationEncoding {
friend SourceLocationSequence;

public:
static uint64_t encode(SourceLocation Loc,
SourceLocationSequence * = nullptr);
static SourceLocation decode(uint64_t, SourceLocationSequence * = nullptr);
using RawLocEncoding = uint64_t;

static RawLocEncoding encode(SourceLocation Loc, UIntTy BaseOffset,
unsigned BaseModuleFileIndex,
SourceLocationSequence * = nullptr);
static std::pair<SourceLocation, unsigned>
decode(RawLocEncoding, SourceLocationSequence * = nullptr);
};

/// Serialized encoding of a sequence of SourceLocations.
Expand Down Expand Up @@ -149,14 +158,44 @@ class SourceLocationSequence::State {
operator SourceLocationSequence *() { return &Seq; }
};

inline uint64_t SourceLocationEncoding::encode(SourceLocation Loc,
SourceLocationSequence *Seq) {
return Seq ? Seq->encode(Loc) : encodeRaw(Loc.getRawEncoding());
inline SourceLocationEncoding::RawLocEncoding
SourceLocationEncoding::encode(SourceLocation Loc, UIntTy BaseOffset,
unsigned BaseModuleFileIndex,
SourceLocationSequence *Seq) {
// If the source location is a local source location, we can try to optimize
// the similar sequences to only record the differences.
if (!BaseOffset)
return Seq ? Seq->encode(Loc) : encodeRaw(Loc.getRawEncoding());

if (Loc.isInvalid())
return 0;

// Otherwise, the higher bits are used to store the module file index,
// so it is meaningless to optimize the source locations into small
// integers. Let's try to always use the raw encodings.
assert(Loc.getOffset() >= BaseOffset);
Loc = Loc.getLocWithOffset(-BaseOffset);
RawLocEncoding Encoded = encodeRaw(Loc.getRawEncoding());

// 16 bits should be sufficient to store the module file index.
assert(BaseModuleFileIndex < (1 << 16));
Encoded |= (RawLocEncoding)BaseModuleFileIndex << 32;
return Encoded;
}
inline SourceLocation
SourceLocationEncoding::decode(uint64_t Encoded, SourceLocationSequence *Seq) {
return Seq ? Seq->decode(Encoded)
: SourceLocation::getFromRawEncoding(decodeRaw(Encoded));
inline std::pair<SourceLocation, unsigned>
SourceLocationEncoding::decode(RawLocEncoding Encoded,
SourceLocationSequence *Seq) {
unsigned ModuleFileIndex = Encoded >> 32;

if (!ModuleFileIndex)
return {Seq ? Seq->decode(Encoded)
: SourceLocation::getFromRawEncoding(decodeRaw(Encoded)),
ModuleFileIndex};

Encoded &= llvm::maskTrailingOnes<RawLocEncoding>(32);
SourceLocation Loc = SourceLocation::getFromRawEncoding(decodeRaw(Encoded));

return {Loc, ModuleFileIndex};
}

} // namespace clang
Expand Down
33 changes: 17 additions & 16 deletions clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
Original file line number Diff line number Diff line change
Expand Up @@ -563,6 +563,20 @@ def MismatchedDeallocatorChecker : Checker<"MismatchedDeallocator">,
Dependencies<[DynamicMemoryModeling]>,
Documentation<HasDocumentation>;

// This must appear before StdCLibraryFunctionsChecker because a dependency.
def StreamChecker : Checker<"Stream">,
HelpText<"Check stream handling functions">,
WeakDependencies<[NonNullParamChecker]>,
CheckerOptions<[
CmdLineOption<Boolean,
"Pedantic",
"If false, assume that stream operations which are often not "
"checked for error do not fail.",
"false",
InAlpha>
]>,
Documentation<HasDocumentation>;

def StdCLibraryFunctionsChecker : Checker<"StdCLibraryFunctions">,
HelpText<"Check for invalid arguments of C standard library functions, "
"and apply relations between arguments and return value">,
Expand All @@ -581,7 +595,7 @@ def StdCLibraryFunctionsChecker : Checker<"StdCLibraryFunctions">,
"true",
InAlpha>
]>,
WeakDependencies<[CallAndMessageChecker, NonNullParamChecker]>,
WeakDependencies<[CallAndMessageChecker, NonNullParamChecker, StreamChecker]>,
Documentation<HasDocumentation>;

def VforkChecker : Checker<"Vfork">,
Expand All @@ -601,20 +615,6 @@ def PthreadLockChecker : Checker<"PthreadLock">,
Dependencies<[PthreadLockBase]>,
Documentation<HasDocumentation>;

def StreamChecker : Checker<"Stream">,
HelpText<"Check stream handling functions">,
WeakDependencies<[NonNullParamChecker]>,
CheckerOptions<[
CmdLineOption<Boolean,
"Pedantic",
"If false, assume that stream operations which are often not "
"checked for error do not fail."
"fail.",
"false",
InAlpha>
]>,
Documentation<HasDocumentation>;

def SimpleStreamChecker : Checker<"SimpleStream">,
HelpText<"Check for misuses of stream APIs">,
Documentation<HasDocumentation>;
Expand Down Expand Up @@ -1397,7 +1397,7 @@ def CastValueChecker : Checker<"CastValue">,
Documentation<NotDocumented>;

def ReturnValueChecker : Checker<"ReturnValue">,
HelpText<"Model the guaranteed boolean return value of function calls">,
HelpText<"Model certain Error() methods that always return true by convention">,
Documentation<NotDocumented>;

} // end "apiModeling.llvm"
Expand Down Expand Up @@ -1628,6 +1628,7 @@ def TaintTesterChecker : Checker<"TaintTest">,
def StreamTesterChecker : Checker<"StreamTester">,
HelpText<"Add test functions to StreamChecker for test and debugging "
"purposes.">,
WeakDependencies<[StreamChecker]>,
Documentation<NotDocumented>;

def ErrnoTesterChecker : Checker<"ErrnoTest">,
Expand Down
15 changes: 10 additions & 5 deletions clang/include/clang/Tooling/CommonOptionsParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,17 +49,22 @@ namespace tooling {
/// using namespace clang::tooling;
/// using namespace llvm;
///
/// static cl::OptionCategory MyToolCategory("My tool options");
/// static cl::OptionCategory MyToolCategory("my-tool options");
/// static cl::extrahelp CommonHelp(CommonOptionsParser::HelpMessage);
/// static cl::extrahelp MoreHelp("\nMore help text...\n");
/// static cl::opt<bool> YourOwnOption(...);
/// ...
///
/// int main(int argc, const char **argv) {
/// CommonOptionsParser OptionsParser(argc, argv, MyToolCategory);
/// auto ExpectedParser =
/// CommonOptionsParser::create(argc, argv, MyToolCategory);
/// if (!ExpectedParser) {
/// llvm::errs() << ExpectedParser.takeError();
/// return 1;
/// }
/// CommonOptionsParser& OptionsParser = ExpectedParser.get();
/// ClangTool Tool(OptionsParser.getCompilations(),
/// OptionsParser.getSourcePathList());
/// return Tool.run(newFrontendActionFactory<SyntaxOnlyAction>().get());
/// return Tool.run(
/// newFrontendActionFactory<clang::SyntaxOnlyAction>().get());
/// }
/// \endcode
class CommonOptionsParser {
Expand Down
57 changes: 21 additions & 36 deletions clang/lib/AST/ASTContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1307,6 +1307,9 @@ void ASTContext::InitBuiltinTypes(const TargetInfo &Target,
// Placeholder type for bound members.
InitBuiltinType(BoundMemberTy, BuiltinType::BoundMember);

// Placeholder type for unresolved templates.
InitBuiltinType(UnresolvedTemplateTy, BuiltinType::UnresolvedTemplate);

// Placeholder type for pseudo-objects.
InitBuiltinType(PseudoObjectTy, BuiltinType::PseudoObject);

Expand Down Expand Up @@ -1612,15 +1615,7 @@ const llvm::fltSemantics &ASTContext::getFloatTypeSemantics(QualType T) const {
case BuiltinType::Float16:
return Target->getHalfFormat();
case BuiltinType::Half:
// For HLSL, when the native half type is disabled, half will be treat as
// float.
if (getLangOpts().HLSL)
if (getLangOpts().NativeHalfType)
return Target->getHalfFormat();
else
return Target->getFloatFormat();
else
return Target->getHalfFormat();
return Target->getHalfFormat();
case BuiltinType::Float: return Target->getFloatFormat();
case BuiltinType::Double: return Target->getDoubleFormat();
case BuiltinType::Ibm128:
Expand Down Expand Up @@ -3802,33 +3797,33 @@ QualType ASTContext::getDependentSizedArrayType(QualType elementType,
numElements->isValueDependent()) &&
"Size must be type- or value-dependent!");

SplitQualType canonElementType = getCanonicalType(elementType).split();

void *insertPos = nullptr;
llvm::FoldingSetNodeID ID;
DependentSizedArrayType::Profile(
ID, *this, numElements ? QualType(canonElementType.Ty, 0) : elementType,
ASM, elementTypeQuals, numElements);

// Look for an existing type with these properties.
DependentSizedArrayType *canonTy =
DependentSizedArrayTypes.FindNodeOrInsertPos(ID, insertPos);

// Dependently-sized array types that do not have a specified number
// of elements will have their sizes deduced from a dependent
// initializer. We do no canonicalization here at all, which is okay
// because they can't be used in most locations.
// initializer.
if (!numElements) {
if (canonTy)
return QualType(canonTy, 0);

auto *newType = new (*this, alignof(DependentSizedArrayType))
DependentSizedArrayType(elementType, QualType(), numElements, ASM,
elementTypeQuals, brackets);
DependentSizedArrayTypes.InsertNode(newType, insertPos);
Types.push_back(newType);
return QualType(newType, 0);
}

// Otherwise, we actually build a new type every time, but we
// also build a canonical type.

SplitQualType canonElementType = getCanonicalType(elementType).split();

void *insertPos = nullptr;
llvm::FoldingSetNodeID ID;
DependentSizedArrayType::Profile(ID, *this,
QualType(canonElementType.Ty, 0),
ASM, elementTypeQuals, numElements);

// Look for an existing type with these properties.
DependentSizedArrayType *canonTy =
DependentSizedArrayTypes.FindNodeOrInsertPos(ID, insertPos);

// If we don't have one, build one.
if (!canonTy) {
canonTy = new (*this, alignof(DependentSizedArrayType))
Expand Down Expand Up @@ -9554,11 +9549,6 @@ static uint64_t getSVETypeSize(ASTContext &Context, const BuiltinType *Ty) {

bool ASTContext::areCompatibleSveTypes(QualType FirstType,
QualType SecondType) {
assert(
((FirstType->isSVESizelessBuiltinType() && SecondType->isVectorType()) ||
(FirstType->isVectorType() && SecondType->isSVESizelessBuiltinType())) &&
"Expected SVE builtin type and vector type!");

auto IsValidCast = [this](QualType FirstType, QualType SecondType) {
if (const auto *BT = FirstType->getAs<BuiltinType>()) {
if (const auto *VT = SecondType->getAs<VectorType>()) {
Expand All @@ -9584,11 +9574,6 @@ bool ASTContext::areCompatibleSveTypes(QualType FirstType,

bool ASTContext::areLaxCompatibleSveTypes(QualType FirstType,
QualType SecondType) {
assert(
((FirstType->isSVESizelessBuiltinType() && SecondType->isVectorType()) ||
(FirstType->isVectorType() && SecondType->isSVESizelessBuiltinType())) &&
"Expected SVE builtin type and vector type!");

auto IsLaxCompatible = [this](QualType FirstType, QualType SecondType) {
const auto *BT = FirstType->getAs<BuiltinType>();
if (!BT)
Expand Down
15 changes: 15 additions & 0 deletions clang/lib/AST/Decl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5758,3 +5758,18 @@ ExportDecl *ExportDecl::Create(ASTContext &C, DeclContext *DC,
ExportDecl *ExportDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {
return new (C, ID) ExportDecl(nullptr, SourceLocation());
}

bool clang::IsArmStreamingFunction(const FunctionDecl *FD,
bool IncludeLocallyStreaming) {
if (IncludeLocallyStreaming)
if (FD->hasAttr<ArmLocallyStreamingAttr>())
return true;

if (const Type *Ty = FD->getType().getTypePtrOrNull())
if (const auto *FPT = Ty->getAs<FunctionProtoType>())
if (FPT->getAArch64SMEAttributes() &
FunctionType::SME_PStateSMEnabledMask)
return true;

return false;
}
13 changes: 9 additions & 4 deletions clang/lib/AST/Expr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ const Expr *Expr::skipRValueSubobjectAdjustments(
}
} else if (const auto *ME = dyn_cast<MemberExpr>(E)) {
if (!ME->isArrow()) {
assert(ME->getBase()->getType()->isRecordType());
assert(ME->getBase()->getType()->getAsRecordDecl());
if (const auto *Field = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
if (!Field->isBitField() && !Field->getType()->isReferenceType()) {
E = ME->getBase();
Expand Down Expand Up @@ -3893,9 +3893,14 @@ namespace {
}

void VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *E) {
if (E->getTemporary()->getDestructor()->isTrivial()) {
Inherited::VisitStmt(E);
return;
// Destructor of the temporary might be null if destructor declaration
// is not valid.
if (const CXXDestructorDecl *DtorDecl =
E->getTemporary()->getDestructor()) {
if (DtorDecl->isTrivial()) {
Inherited::VisitStmt(E);
return;
}
}

NonTrivial = true;
Expand Down
7 changes: 6 additions & 1 deletion clang/lib/AST/ExprClassification.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -216,8 +216,13 @@ static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) {
return ClassifyInternal(Ctx,
cast<SubstNonTypeTemplateParmExpr>(E)->getReplacement());

case Expr::PackIndexingExprClass:
case Expr::PackIndexingExprClass: {
// A pack-index-expression always expands to an id-expression.
// Consider it as an LValue expression.
if (cast<PackIndexingExpr>(E)->isInstantiationDependent())
return Cl::CL_LValue;
return ClassifyInternal(Ctx, cast<PackIndexingExpr>(E)->getSelectedExpr());
}

// C, C++98 [expr.sub]p1: The result is an lvalue of type "T".
// C++11 (DR1213): in the case of an array operand, the result is an lvalue
Expand Down
12 changes: 7 additions & 5 deletions clang/lib/AST/Interp/ByteCodeEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,11 +82,13 @@ Function *ByteCodeEmitter::compileFunc(const FunctionDecl *FuncDecl) {
// InterpStack when calling the function.
bool HasThisPointer = false;
if (const auto *MD = dyn_cast<CXXMethodDecl>(FuncDecl)) {
if (MD->isImplicitObjectMemberFunction() && !IsLambdaStaticInvoker) {
HasThisPointer = true;
ParamTypes.push_back(PT_Ptr);
ParamOffsets.push_back(ParamOffset);
ParamOffset += align(primSize(PT_Ptr));
if (!IsLambdaStaticInvoker) {
HasThisPointer = MD->isInstance();
if (MD->isImplicitObjectMemberFunction()) {
ParamTypes.push_back(PT_Ptr);
ParamOffsets.push_back(ParamOffset);
ParamOffset += align(primSize(PT_Ptr));
}
}

// Set up lambda capture to closure record field mapping.
Expand Down
Loading