65 changes: 47 additions & 18 deletions clang-tools-extra/docs/clang-tidy/Contributing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -127,14 +127,15 @@ Writing a clang-tidy Check

So you have an idea of a useful check for :program:`clang-tidy`.

First, if you're not familiar with LLVM development, read through the `Getting
Started with LLVM`_ document for instructions on setting up your workflow and
First, if you're not familiar with LLVM development, read through the `Getting Started
with the LLVM System`_ document for instructions on setting up your workflow and
the `LLVM Coding Standards`_ document to familiarize yourself with the coding
style used in the project. For code reviews we mostly use `LLVM Phabricator`_.
style used in the project. For code reviews we currently use `LLVM Github`_,
though historically we used Phabricator.

.. _Getting Started with LLVM: https://llvm.org/docs/GettingStarted.html
.. _Getting Started with the LLVM System: https://llvm.org/docs/GettingStarted.html
.. _LLVM Coding Standards: https://llvm.org/docs/CodingStandards.html
.. _LLVM Phabricator: https://llvm.org/docs/Phabricator.html
.. _LLVM Github: https://github.com/llvm/llvm-project

Next, you need to decide which module the check belongs to. Modules
are located in subdirectories of `clang-tidy/
Expand Down Expand Up @@ -336,13 +337,25 @@ a starting point for your test cases. A rough outline of the process looks like
The quickest way to prototype your matcher is to use :program:`clang-query` to
interactively build up your matcher. For complicated matchers, build up a matching
expression incrementally and use :program:`clang-query`'s ``let`` command to save named
matching expressions to simplify your matcher. Just like breaking up a huge function
into smaller chunks with intention-revealing names can help you understand a complex
algorithm, breaking up a matcher into smaller matchers with intention-revealing names
can help you understand a complicated matcher. Once you have a working matcher, the
C++ API will be virtually identical to your interactively constructed matcher. You can
use local variables to preserve your intention-revealing names that you applied to
nested matchers.
matching expressions to simplify your matcher.

.. code-block:: console
clang-query> let c1 cxxRecordDecl()
clang-query> match c1
Alternatively, pressing the tab key after a previous matcher's open parentheses would also
show which matchers can be chained with the previous matcher, though some matchers that work
may not be listed.

Just like breaking up a huge function into smaller chunks with intention-revealing names
can help you understand a complex algorithm, breaking up a matcher into smaller matchers
with intention-revealing names can help you understand a complicated matcher.

Once you have a working clang-query matcher, the C++ API matchers will be the same or similar
to your interactively constructed matcher (there can be cases where they differ slightly).
You can use local variables to preserve your intention-revealing names that you applied
to nested matchers.

Creating private matchers
^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down Expand Up @@ -646,10 +659,13 @@ directory. The path to this directory is available in a lit test with the varia
Out-of-tree check plugins
-------------------------


Developing an out-of-tree check as a plugin largely follows the steps
outlined above. The plugin is a shared library whose code lives outside
outlined above, including creating a new module and doing the hacks to
register the module. The plugin is a shared library whose code lives outside
the clang-tidy build system. Build and link this shared library against
LLVM as done for other kinds of Clang plugins.
LLVM as done for other kinds of Clang plugins. If using CMake, use the keyword
``MODULE`` while invoking ``add_library`` or ``llvm_add_library``.

The plugin can be loaded by passing `-load` to `clang-tidy` in addition to the
names of the checks to enable.
Expand All @@ -664,6 +680,19 @@ compiled against the version of clang-tidy that will be loading the plugin.
The plugins can use threads, TLS, or any other facilities available to in-tree
code which is accessible from the external headers.

Note that testing out-of-tree checks might involve getting ``llvm-lit`` from an LLVM
installation compiled from source. See `Getting Started with the LLVM System`_ for ways
to do so.

Alternatively, get `lit`_ following the `test-suite guide`_ and get the `FileCheck`_ binary,
and write a version of `check_clang_tidy.py`_ to suit your needs.

.. _Getting Started with the LLVM System: https://llvm.org/docs/GettingStarted.html
.. _test-suite guide: https://llvm.org/docs/TestSuiteGuide.html
.. _lit: https://llvm.org/docs/CommandGuide/lit.html
.. _FileCheck: https://llvm.org/docs/CommandGuide/FileCheck.html
.. _check_clang_tidy.py: https://github.com/llvm/llvm-project/blob/main/clang-tools-extra/test/clang-tidy/check_clang_tidy.py

Running clang-tidy on LLVM
--------------------------

Expand All @@ -688,10 +717,10 @@ warnings and errors. The script provides multiple configuration flags.

* To restrict the files examined you can provide one or more regex arguments
that the file names are matched against.
``run-clang-tidy.py clang-tidy/.*Check\.cpp`` will only analyze clang-tidy
``run-clang-tidy.py clang-tidy/.*Check\.cpp`` will only analyze `clang-tidy`
checks. It may also be necessary to restrict the header files that warnings
are displayed from using the ``-header-filter`` flag. It has the same behavior
as the corresponding :program:`clang-tidy` flag.
are displayed from by using the ``-header-filter`` and ``-exclude-header-filter`` flags.
They have the same behavior as the corresponding :program:`clang-tidy` flags.

* To apply suggested fixes ``-fix`` can be passed as an argument. This gathers
all changes in a temporary directory and applies them. Passing ``-format``
Expand Down Expand Up @@ -758,4 +787,4 @@ There is only one argument that controls profile storage:

* If you run :program:`clang-tidy` from within ``/foo`` directory, and specify
``-store-check-profile=.``, then the profile will still be saved to
``/foo/<ISO8601-like timestamp>-example.cpp.json``
``/foo/<ISO8601-like timestamp>-example.cpp.json``
7 changes: 6 additions & 1 deletion clang-tools-extra/include-cleaner/lib/WalkAST.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,12 @@ class ASTWalker : public RecursiveASTVisitor<ASTWalker> {
bool VisitUsingDecl(UsingDecl *UD) {
for (const auto *Shadow : UD->shadows()) {
auto *TD = Shadow->getTargetDecl();
auto IsUsed = TD->isUsed() || TD->isReferenced();
// For function-decls, we might have overloads brought in due to
// transitive dependencies. Hence we only want to report explicit
// references for those if they're used.
// But for record decls, spelling of the type always refers to primary
// decl non-ambiguously. Hence spelling is already a use.
auto IsUsed = TD->isUsed() || TD->isReferenced() || !TD->getAsFunction();
report(UD->getLocation(), TD,
IsUsed ? RefType::Explicit : RefType::Ambiguous);

Expand Down
11 changes: 8 additions & 3 deletions clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ TEST(WalkAST, TemplateSpecializationsFromUsingDecl) {
// Class templates
testWalk(R"cpp(
namespace ns {
template<class T> class $ambiguous^Z {}; // primary template
template<class T> class $explicit^Z {}; // primary template
template<class T> class $ambiguous^Z<T*> {}; // partial specialization
template<> class $ambiguous^Z<int> {}; // full specialization
}
Expand All @@ -265,7 +265,7 @@ template<> class $ambiguous^Z<int> {}; // full specialization
// Var templates
testWalk(R"cpp(
namespace ns {
template<class T> T $ambiguous^foo; // primary template
template<class T> T $explicit^foo; // primary template
template<class T> T $ambiguous^foo<T*>; // partial specialization
template<> int* $ambiguous^foo<int>; // full specialization
}
Expand Down Expand Up @@ -335,7 +335,12 @@ TEST(WalkAST, Using) {
testWalk(R"cpp(
namespace ns {
template<class T>
class $ambiguous^Y {};
class $explicit^Y {};
})cpp",
"using ns::^Y;");
testWalk(R"cpp(
namespace ns {
class $explicit^Y {};
})cpp",
"using ns::^Y;");
testWalk(R"cpp(
Expand Down
7 changes: 5 additions & 2 deletions clang/cmake/caches/Release.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,14 @@ set(LLVM_TARGETS_TO_BUILD Native CACHE STRING "")
set(CLANG_ENABLE_BOOTSTRAP ON CACHE BOOL "")

set(STAGE1_PROJECTS "clang")
set(STAGE1_RUNTIMES "")

# Building Flang on Windows requires compiler-rt, so we need to build it in
# stage1. compiler-rt is also required for building the Flang tests on
# macOS.
set(STAGE1_RUNTIMES "compiler-rt")

if (LLVM_RELEASE_ENABLE_PGO)
list(APPEND STAGE1_PROJECTS "lld")
list(APPEND STAGE1_RUNTIMES "compiler-rt")
set(CLANG_BOOTSTRAP_TARGETS
generate-profdata
stage2-package
Expand Down
10 changes: 10 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,13 @@ Bug Fixes in This Version
Bug Fixes to Compiler Builtins
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

- Fix crash when atomic builtins are called with pointer to zero-size struct (#GH90330)

- Clang now allows pointee types of atomic builtin arguments to be complete template types
that was not instantiated elsewhere.

- ``__noop`` can now be used in a constant expression. (#GH102064)

Bug Fixes to Attribute Support
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Expand Down Expand Up @@ -326,6 +333,9 @@ Bug Fixes to C++ Support
- Fix evaluation of the index of dependent pack indexing expressions/types specifiers (#GH105900)
- Correctly handle subexpressions of an immediate invocation in the presence of implicit casts. (#GH105558)
- Clang now correctly handles direct-list-initialization of a structured bindings from an array. (#GH31813)
- Mangle placeholders for deduced types as a template-prefix, such that mangling
of template template parameters uses the correct production. (#GH106182)
- Fixed an assertion failure when converting vectors to int/float with invalid expressions. (#GH105486)

Bug Fixes to AST Handling
^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down
6 changes: 2 additions & 4 deletions clang/docs/tools/generate_formatted_state.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,6 @@ def get_style(count, passed):
- {style2}`{percent}%`
"""

FNULL = open(os.devnull, "w")


with open(DOC_FILE, "wb") as output:
cleanfiles = open(CLEAN_FILE, "wb")
Expand All @@ -101,8 +99,8 @@ def get_style(count, passed):
# interested in it, just the return code.
git_check = subprocess.Popen(
["git", "ls-files", "--error-unmatch", act_sub_dir],
stdout=FNULL,
stderr=FNULL,
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
)
if git_check.wait() != 0:
print("Skipping directory: ", act_sub_dir)
Expand Down
5 changes: 3 additions & 2 deletions clang/include/clang-c/Index.h
Original file line number Diff line number Diff line change
Expand Up @@ -2980,8 +2980,9 @@ enum CXTypeKind {
CXType_Atomic = 177,
CXType_BTFTagAttributed = 178,

// HLSL Intangible Types
CXType_HLSLResource = 179
// HLSL Types
CXType_HLSLResource = 179,
CXType_HLSLAttributedResource = 180
};

/**
Expand Down
5 changes: 5 additions & 0 deletions clang/include/clang/AST/ASTContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
mutable llvm::ContextualFoldingSet<DependentBitIntType, ASTContext &>
DependentBitIntTypes;
llvm::FoldingSet<BTFTagAttributedType> BTFTagAttributedTypes;
llvm::FoldingSet<HLSLAttributedResourceType> HLSLAttributedResourceTypes;

mutable llvm::FoldingSet<CountAttributedType> CountAttributedTypes;

Expand Down Expand Up @@ -1671,6 +1672,10 @@ class ASTContext : public RefCountedBase<ASTContext> {
QualType getBTFTagAttributedType(const BTFTypeTagAttr *BTFAttr,
QualType Wrapped);

QualType getHLSLAttributedResourceType(
QualType Wrapped, QualType Contained,
const HLSLAttributedResourceType::Attributes &Attrs);

QualType
getSubstTemplateTypeParmType(QualType Replacement, Decl *AssociatedDecl,
unsigned Index,
Expand Down
5 changes: 5 additions & 0 deletions clang/include/clang/AST/ASTNodeTraverser.h
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,11 @@ class ASTNodeTraverser
void VisitBTFTagAttributedType(const BTFTagAttributedType *T) {
Visit(T->getWrappedType());
}
void VisitHLSLAttributedResourceType(const HLSLAttributedResourceType *T) {
QualType Contained = T->getContainedType();
if (!Contained.isNull())
Visit(Contained);
}
void VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *) {}
void
VisitSubstTemplateTypeParmPackType(const SubstTemplateTypeParmPackType *T) {
Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/AST/Decl.h
Original file line number Diff line number Diff line change
Expand Up @@ -3366,6 +3366,7 @@ class IndirectFieldDecl : public ValueDecl,
/// Represents a declaration of a type.
class TypeDecl : public NamedDecl {
friend class ASTContext;
friend class ASTReader;

/// This indicates the Type object that represents
/// this TypeDecl. It is a cache maintained by
Expand Down
6 changes: 6 additions & 0 deletions clang/include/clang/AST/RecursiveASTVisitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -1146,6 +1146,9 @@ DEF_TRAVERSE_TYPE(CountAttributedType, {
DEF_TRAVERSE_TYPE(BTFTagAttributedType,
{ TRY_TO(TraverseType(T->getWrappedType())); })

DEF_TRAVERSE_TYPE(HLSLAttributedResourceType,
{ TRY_TO(TraverseType(T->getWrappedType())); })

DEF_TRAVERSE_TYPE(ParenType, { TRY_TO(TraverseType(T->getInnerType())); })

DEF_TRAVERSE_TYPE(MacroQualifiedType,
Expand Down Expand Up @@ -1445,6 +1448,9 @@ DEF_TRAVERSE_TYPELOC(CountAttributedType,
DEF_TRAVERSE_TYPELOC(BTFTagAttributedType,
{ TRY_TO(TraverseTypeLoc(TL.getWrappedLoc())); })

DEF_TRAVERSE_TYPELOC(HLSLAttributedResourceType,
{ TRY_TO(TraverseTypeLoc(TL.getWrappedLoc())); })

DEF_TRAVERSE_TYPELOC(ElaboratedType, {
if (TL.getQualifierLoc()) {
TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
Expand Down
52 changes: 52 additions & 0 deletions clang/include/clang/AST/Type.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
#include "llvm/ADT/iterator_range.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/DXILABI.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/PointerLikeTypeTraits.h"
#include "llvm/Support/TrailingObjects.h"
Expand Down Expand Up @@ -1684,6 +1685,7 @@ class ExtQualsTypeCommonBase {
friend class ExtQuals;
friend class QualType;
friend class Type;
friend class ASTReader;

/// The "base" type of an extended qualifiers type (\c ExtQuals) or
/// a self-referential pointer (for \c Type).
Expand Down Expand Up @@ -6155,6 +6157,54 @@ class BTFTagAttributedType : public Type, public llvm::FoldingSetNode {
}
};

class HLSLAttributedResourceType : public Type, public llvm::FoldingSetNode {
public:
struct Attributes {
// Data gathered from HLSL resource attributes
llvm::dxil::ResourceClass ResourceClass;
uint8_t IsROV : 1;
Attributes(llvm::dxil::ResourceClass ResourceClass, bool IsROV)
: ResourceClass(ResourceClass), IsROV(IsROV) {}
Attributes() : ResourceClass(llvm::dxil::ResourceClass::UAV), IsROV(0) {}
};

private:
friend class ASTContext; // ASTContext creates these

QualType WrappedType;
QualType ContainedType;
const Attributes Attrs;

HLSLAttributedResourceType(QualType Canon, QualType Wrapped,
QualType Contained, const Attributes &Attrs)
: Type(HLSLAttributedResource, Canon, Wrapped->getDependence()),
WrappedType(Wrapped), ContainedType(Contained), Attrs(Attrs) {}

public:
QualType getWrappedType() const { return WrappedType; }
QualType getContainedType() const { return ContainedType; }
const Attributes &getAttrs() const { return Attrs; }

bool isSugared() const { return true; }
QualType desugar() const { return getWrappedType(); }

void Profile(llvm::FoldingSetNodeID &ID) {
Profile(ID, WrappedType, ContainedType, Attrs);
}

static void Profile(llvm::FoldingSetNodeID &ID, QualType Wrapped,
QualType Contained, const Attributes &Attrs) {
ID.AddPointer(Wrapped.getAsOpaquePtr());
ID.AddPointer(Contained.getAsOpaquePtr());
ID.AddInteger(static_cast<uint32_t>(Attrs.ResourceClass));
ID.AddBoolean(Attrs.IsROV);
}

static bool classof(const Type *T) {
return T->getTypeClass() == HLSLAttributedResource;
}
};

class TemplateTypeParmType : public Type, public llvm::FoldingSetNode {
friend class ASTContext; // ASTContext creates these

Expand Down Expand Up @@ -8578,6 +8628,8 @@ template <typename T> const T *Type::getAsAdjusted() const {
Ty = A->getModifiedType().getTypePtr();
else if (const auto *A = dyn_cast<BTFTagAttributedType>(Ty))
Ty = A->getWrappedType().getTypePtr();
else if (const auto *A = dyn_cast<HLSLAttributedResourceType>(Ty))
Ty = A->getWrappedType().getTypePtr();
else if (const auto *E = dyn_cast<ElaboratedType>(Ty))
Ty = E->desugar().getTypePtr();
else if (const auto *P = dyn_cast<ParenType>(Ty))
Expand Down
21 changes: 21 additions & 0 deletions clang/include/clang/AST/TypeLoc.h
Original file line number Diff line number Diff line change
Expand Up @@ -940,6 +940,25 @@ class BTFTagAttributedTypeLoc
QualType getInnerType() const { return getTypePtr()->getWrappedType(); }
};

struct HLSLAttributedResourceLocInfo {
SourceRange Range;
};

/// Type source information for HLSL attributed resource type.
class HLSLAttributedResourceTypeLoc
: public ConcreteTypeLoc<UnqualTypeLoc, HLSLAttributedResourceTypeLoc,
HLSLAttributedResourceType,
HLSLAttributedResourceLocInfo> {
public:
TypeLoc getWrappedLoc() const { return getInnerTypeLoc(); }
void setSourceRange(const SourceRange &R) { getLocalData()->Range = R; }
SourceRange getLocalSourceRange() const { return getLocalData()->Range; }
void initializeLocal(ASTContext &Context, SourceLocation loc) {
setSourceRange(SourceRange());
}
QualType getInnerType() const { return getTypePtr()->getWrappedType(); }
};

struct ObjCObjectTypeLocInfo {
SourceLocation TypeArgsLAngleLoc;
SourceLocation TypeArgsRAngleLoc;
Expand Down Expand Up @@ -2690,6 +2709,8 @@ inline T TypeLoc::getAsAdjusted() const {
Cur = ATL.getModifiedLoc();
else if (auto ATL = Cur.getAs<BTFTagAttributedTypeLoc>())
Cur = ATL.getWrappedLoc();
else if (auto ATL = Cur.getAs<HLSLAttributedResourceTypeLoc>())
Cur = ATL.getWrappedLoc();
else if (auto ETL = Cur.getAs<ElaboratedTypeLoc>())
Cur = ETL.getNamedTypeLoc();
else if (auto ATL = Cur.getAs<AdjustedTypeLoc>())
Expand Down
19 changes: 19 additions & 0 deletions clang/include/clang/AST/TypeProperties.td
Original file line number Diff line number Diff line change
Expand Up @@ -687,6 +687,25 @@ let Class = BTFTagAttributedType in {
}]>;
}

let Class = HLSLAttributedResourceType in {
def : Property<"resClass", UInt32> {
let Read = [{ static_cast<uint32_t>(node->getAttrs().ResourceClass) }];
}
def : Property<"isROV", Bool> {
let Read = [{ node->getAttrs().IsROV }];
}
def : Property<"wrappedTy", QualType> {
let Read = [{ node->getWrappedType() }];
}
def : Property<"containedTy", QualType> {
let Read = [{ node->getContainedType() }];
}
def : Creator<[{
HLSLAttributedResourceType::Attributes attrs(static_cast<llvm::dxil::ResourceClass>(resClass), isROV);
return ctx.getHLSLAttributedResourceType(wrappedTy, containedTy, attrs);
}]>;
}

let Class = DependentAddressSpaceType in {
def : Property<"pointeeType", QualType> {
let Read = [{ node->getPointeeType() }];
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/Basic/Builtins.td
Original file line number Diff line number Diff line change
Expand Up @@ -2518,7 +2518,7 @@ def IsoVolatileStore : MSLangBuiltin, Int8_16_32_64Template {

def Noop : MSLangBuiltin {
let Spellings = ["__noop"];
let Attributes = [NoThrow];
let Attributes = [NoThrow, Constexpr];
let Prototype = "int(...)";
}

Expand Down
9 changes: 9 additions & 0 deletions clang/include/clang/Basic/BuiltinsWebAssembly.def
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ TARGET_BUILTIN(__builtin_wasm_bitmask_i16x8, "UiV8s", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_bitmask_i32x4, "UiV4i", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_bitmask_i64x2, "UiV2LLi", "nc", "simd128")

TARGET_BUILTIN(__builtin_wasm_abs_f16x8, "V8hV8h", "nc", "fp16")
TARGET_BUILTIN(__builtin_wasm_abs_f32x4, "V4fV4f", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_abs_f64x2, "V2dV2d", "nc", "simd128")

Expand All @@ -140,6 +141,10 @@ TARGET_BUILTIN(__builtin_wasm_max_f16x8, "V8hV8hV8h", "nc", "fp16")
TARGET_BUILTIN(__builtin_wasm_pmin_f16x8, "V8hV8hV8h", "nc", "fp16")
TARGET_BUILTIN(__builtin_wasm_pmax_f16x8, "V8hV8hV8h", "nc", "fp16")

TARGET_BUILTIN(__builtin_wasm_ceil_f16x8, "V8hV8h", "nc", "fp16")
TARGET_BUILTIN(__builtin_wasm_floor_f16x8, "V8hV8h", "nc", "fp16")
TARGET_BUILTIN(__builtin_wasm_trunc_f16x8, "V8hV8h", "nc", "fp16")
TARGET_BUILTIN(__builtin_wasm_nearest_f16x8, "V8hV8h", "nc", "fp16")
TARGET_BUILTIN(__builtin_wasm_ceil_f32x4, "V4fV4f", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_floor_f32x4, "V4fV4f", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_trunc_f32x4, "V4fV4f", "nc", "simd128")
Expand All @@ -151,9 +156,13 @@ TARGET_BUILTIN(__builtin_wasm_nearest_f64x2, "V2dV2d", "nc", "simd128")

TARGET_BUILTIN(__builtin_wasm_dot_s_i32x4_i16x8, "V4iV8sV8s", "nc", "simd128")

TARGET_BUILTIN(__builtin_wasm_sqrt_f16x8, "V8hV8h", "nc", "fp16")
TARGET_BUILTIN(__builtin_wasm_sqrt_f32x4, "V4fV4f", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_sqrt_f64x2, "V2dV2d", "nc", "simd128")

TARGET_BUILTIN(__builtin_wasm_trunc_saturate_s_i16x8_f16x8, "V8sV8h", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_trunc_saturate_u_i16x8_f16x8, "V8sV8h", "nc", "simd128")

TARGET_BUILTIN(__builtin_wasm_trunc_saturate_s_i32x4_f32x4, "V4iV4f", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_trunc_saturate_u_i32x4_f32x4, "V4iV4f", "nc", "simd128")

Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/Basic/TypeNodes.td
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ def EnumType : TypeNode<TagType>, LeafType;
def ElaboratedType : TypeNode<Type>, NeverCanonical;
def AttributedType : TypeNode<Type>, NeverCanonical;
def BTFTagAttributedType : TypeNode<Type>, NeverCanonical;
def HLSLAttributedResourceType : TypeNode<Type>, NeverCanonical;
def TemplateTypeParmType : TypeNode<Type>, AlwaysDependent, LeafType;
def SubstTemplateTypeParmType : TypeNode<Type>, NeverCanonical;
def SubstTemplateTypeParmPackType : TypeNode<Type>, AlwaysDependent;
Expand Down
18 changes: 9 additions & 9 deletions clang/include/clang/Basic/riscv_vector.td
Original file line number Diff line number Diff line change
Expand Up @@ -2688,7 +2688,7 @@ multiclass RVVSignedWidenBinBuiltinSetVwsll

let UnMaskedPolicyScheme = HasPassthruOperand in {
// zvkb
let RequiredFeatures = ["Zvkb", "Experimental"] in {
let RequiredFeatures = ["Zvkb"] in {
defm vandn : RVVUnsignedBinBuiltinSet;
defm vbrev8 : RVVOutBuiltinSetZvbb;
defm vrev8 : RVVOutBuiltinSetZvbb;
Expand All @@ -2697,7 +2697,7 @@ let UnMaskedPolicyScheme = HasPassthruOperand in {
}

// zvbb
let RequiredFeatures = ["Zvbb", "Experimental"] in {
let RequiredFeatures = ["Zvbb"] in {
defm vbrev : RVVOutBuiltinSetZvbb;
defm vclz : RVVOutBuiltinSetZvbb;
defm vctz : RVVOutBuiltinSetZvbb;
Expand All @@ -2708,21 +2708,21 @@ let UnMaskedPolicyScheme = HasPassthruOperand in {
}

// zvbc
let RequiredFeatures = ["Zvbc", "Experimental"] in {
let RequiredFeatures = ["Zvbc"] in {
defm vclmul : RVVInt64BinBuiltinSet;
defm vclmulh : RVVInt64BinBuiltinSet;
}
}

let UnMaskedPolicyScheme = HasPolicyOperand, HasMasked = false in {
// zvkg
let RequiredFeatures = ["Zvkg", "Experimental"] in {
let RequiredFeatures = ["Zvkg"] in {
defm vghsh : RVVOutOp2BuiltinSetVVZvk;
defm vgmul : RVVOutBuiltinSetZvk<HasVV=1, HasVS=0>;
}

// zvkned
let RequiredFeatures = ["Zvkned", "Experimental"] in {
let RequiredFeatures = ["Zvkned"] in {
defm vaesdf : RVVOutBuiltinSetZvk;
defm vaesdm : RVVOutBuiltinSetZvk;
defm vaesef : RVVOutBuiltinSetZvk;
Expand All @@ -2734,28 +2734,28 @@ let UnMaskedPolicyScheme = HasPolicyOperand, HasMasked = false in {
}

// zvknha
let RequiredFeatures = ["Zvknha", "Experimental"] in {
let RequiredFeatures = ["Zvknha"] in {
defm vsha2ch : RVVOutOp2BuiltinSetVVZvk<"i">;
defm vsha2cl : RVVOutOp2BuiltinSetVVZvk<"i">;
defm vsha2ms : RVVOutOp2BuiltinSetVVZvk<"i">;
}

// zvknhb
let RequiredFeatures = ["Zvknhb", "Experimental"] in {
let RequiredFeatures = ["Zvknhb"] in {
defm vsha2ch : RVVOutOp2BuiltinSetVVZvk<"il">;
defm vsha2cl : RVVOutOp2BuiltinSetVVZvk<"il">;
defm vsha2ms : RVVOutOp2BuiltinSetVVZvk<"il">;
}

// zvksed
let RequiredFeatures = ["Zvksed", "Experimental"] in {
let RequiredFeatures = ["Zvksed"] in {
let UnMaskedPolicyScheme = HasPassthruOperand in
defm vsm4k : RVVOutOp1BuiltinSet<"vsm4k", "i", [["vi", "Uv", "UvUvKz"]]>;
defm vsm4r : RVVOutBuiltinSetZvk;
}

// zvksh
let RequiredFeatures = ["Zvksh", "Experimental"] in {
let RequiredFeatures = ["Zvksh"] in {
defm vsm3c : RVVOutOp2BuiltinSetVIZvk;
let UnMaskedPolicyScheme = HasPassthruOperand in
defm vsm3me : RVVOutOp1BuiltinSet<"vsm3me", "i", [["vv", "Uv", "UvUvUv"]]>;
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/CodeGen/CodeGenAction.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ class CodeGenAction : public ASTFrontendAction {
bool loadLinkModules(CompilerInstance &CI);

protected:
bool BeginSourceFileAction(CompilerInstance &CI) override;
bool BeginInvocation(CompilerInstance &CI) override;

/// Create a new code generation action. If the optional \p _VMContext
/// parameter is supplied, the action uses it without taking ownership,
Expand Down
11 changes: 5 additions & 6 deletions clang/include/clang/ExtractAPI/API.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
#include "clang/AST/RawCommentList.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/ExtractAPI/DeclarationFragments.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Casting.h"
#include "llvm/TargetParser/Triple.h"
Expand Down Expand Up @@ -1420,9 +1420,8 @@ class APISet {
typename std::enable_if_t<std::is_base_of_v<APIRecord, RecordTy>, RecordTy> *
createRecord(StringRef USR, StringRef Name, CtorArgsContTy &&...CtorArgs);

auto getTopLevelRecords() const {
return llvm::iterator_range<decltype(TopLevelRecords)::iterator>(
TopLevelRecords);
ArrayRef<const APIRecord *> getTopLevelRecords() const {
return TopLevelRecords;
}

void removeRecord(StringRef USR);
Expand Down Expand Up @@ -1455,7 +1454,7 @@ class APISet {
// lives in the BumpPtrAllocator.
using APIRecordStoredPtr = std::unique_ptr<APIRecord, APIRecordDeleter>;
llvm::DenseMap<StringRef, APIRecordStoredPtr> USRBasedLookupTable;
llvm::SmallPtrSet<const APIRecord *, 32> TopLevelRecords;
llvm::SmallVector<const APIRecord *, 32> TopLevelRecords;

public:
const std::string ProductName;
Expand All @@ -1481,7 +1480,7 @@ APISet::createRecord(StringRef USR, StringRef Name,
dyn_cast_if_present<RecordContext>(Record->Parent.Record))
ParentContext->addToRecordChain(Record);
else
TopLevelRecords.insert(Record);
TopLevelRecords.push_back(Record);
} else {
Record = dyn_cast<RecordTy>(Result.first->second.get());
}
Expand Down
4 changes: 3 additions & 1 deletion clang/include/clang/Frontend/FrontendActions.h
Original file line number Diff line number Diff line change
Expand Up @@ -152,11 +152,13 @@ class GenerateModuleFromModuleMapAction : public GenerateModuleAction {
CreateOutputFile(CompilerInstance &CI, StringRef InFile) override;
};

bool BeginInvocationForModules(CompilerInstance &CI);

/// Generates full BMI (which contains full information to generate the object
/// files) for C++20 Named Modules.
class GenerateModuleInterfaceAction : public GenerateModuleAction {
protected:
bool BeginSourceFileAction(CompilerInstance &CI) override;
bool BeginInvocation(CompilerInstance &CI) override;

std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
StringRef InFile) override;
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/Sema/ExternalSemaSource.h
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ class ExternalSemaSource : public ExternalASTSource {
/// Notify the external source that a lambda was assigned a mangling number.
/// This enables the external source to track the correspondence between
/// lambdas and mangling numbers if necessary.
virtual void AssignedLambdaNumbering(const CXXRecordDecl *Lambda) {}
virtual void AssignedLambdaNumbering(CXXRecordDecl *Lambda) {}

/// LLVM-style RTTI.
/// \{
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/Sema/MultiplexExternalSemaSource.h
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,7 @@ class MultiplexExternalSemaSource : public ExternalSemaSource {
QualType T) override;

// Inform all attached sources that a mangling number was assigned.
void AssignedLambdaNumbering(const CXXRecordDecl *Lambda) override;
void AssignedLambdaNumbering(CXXRecordDecl *Lambda) override;

/// LLVM-style RTTI.
/// \{
Expand Down
31 changes: 18 additions & 13 deletions clang/include/clang/Sema/Sema.h
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,24 @@ class SemaPPCallbacks;
class TemplateDeductionInfo;
} // namespace sema

// AssignmentAction - This is used by all the assignment diagnostic functions
// to represent what is actually causing the operation
enum class AssignmentAction {
Assigning,
Passing,
Returning,
Converting,
Initializing,
Sending,
Casting,
Passing_CFAudited
};
inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
const AssignmentAction &AA) {
DB << llvm::to_underlying(AA);
return DB;
}

namespace threadSafety {
class BeforeSet;
void threadSafetyCleanup(BeforeSet *Cache);
Expand Down Expand Up @@ -6493,19 +6511,6 @@ class Sema final : public SemaBase {
/// cleanup that are created by the current full expression.
SmallVector<ExprWithCleanups::CleanupObject, 8> ExprCleanupObjects;

// AssignmentAction - This is used by all the assignment diagnostic functions
// to represent what is actually causing the operation
enum AssignmentAction {
AA_Assigning,
AA_Passing,
AA_Returning,
AA_Converting,
AA_Initializing,
AA_Sending,
AA_Casting,
AA_Passing_CFAudited
};

/// Determine whether the use of this declaration is valid, without
/// emitting diagnostics.
bool CanUseDecl(NamedDecl *D, bool TreatUnavailableAsInvalid);
Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/Sema/SemaHLSL.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,11 @@ class SemaHLSL : public SemaBase {
void handleResourceClassAttr(Decl *D, const ParsedAttr &AL);
void handleResourceBindingAttr(Decl *D, const ParsedAttr &AL);
void handleParamModifierAttr(Decl *D, const ParsedAttr &AL);
bool handleResourceTypeAttr(const ParsedAttr &AL);

bool CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
QualType ProcessResourceTypeAttributes(QualType Wrapped);
SourceLocation TakeLocForHLSLAttribute(const HLSLAttributedResourceType *RT);

// HLSL Type trait implementations
bool IsScalarizedLayoutCompatible(QualType T1, QualType T2) const;
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/Serialization/ASTReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -2149,7 +2149,7 @@ class ASTReader
llvm::MapVector<const FunctionDecl *, std::unique_ptr<LateParsedTemplate>>
&LPTMap) override;

void AssignedLambdaNumbering(const CXXRecordDecl *Lambda) override;
void AssignedLambdaNumbering(CXXRecordDecl *Lambda) override;

/// Load a selector from disk, registering its ID if it exists.
void LoadSelector(Selector Sel);
Expand Down
4 changes: 2 additions & 2 deletions clang/include/clang/Serialization/ASTWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -500,8 +500,8 @@ class ASTWriter : public ASTDeserializationListener,
std::vector<SourceRange> NonAffectingRanges;
std::vector<SourceLocation::UIntTy> NonAffectingOffsetAdjustments;

/// A list of classes which need to emit the VTable in the corresponding
/// object file.
/// A list of classes in named modules which need to emit the VTable in
/// the corresponding object file.
llvm::SmallVector<CXXRecordDecl *> PendingEmittingVTables;

/// Computes input files that didn't affect compilation of the current module,
Expand Down
10 changes: 5 additions & 5 deletions clang/include/clang/Serialization/ModuleFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,13 +88,13 @@ class InputFile {

InputFile(FileEntryRef File, bool isOverridden = false,
bool isOutOfDate = false) {
assert(!(isOverridden && isOutOfDate) &&
"an overridden cannot be out-of-date");
unsigned intVal = 0;
if (isOverridden)
intVal = Overridden;
else if (isOutOfDate)
// Make isOutOfDate with higher priority than isOverridden.
// It is possible if the recorded hash value mismatches.
if (isOutOfDate)
intVal = OutOfDate;
else if (isOverridden)
intVal = Overridden;
Val.setPointerAndInt(&File.getMapEntry(), intVal);
}

Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/Serialization/TypeBitCodes.def
Original file line number Diff line number Diff line change
Expand Up @@ -67,5 +67,6 @@ TYPE_BIT_CODE(BTFTagAttributed, BTFTAG_ATTRIBUTED, 55)
TYPE_BIT_CODE(PackIndexing, PACK_INDEXING, 56)
TYPE_BIT_CODE(CountAttributed, COUNT_ATTRIBUTED, 57)
TYPE_BIT_CODE(ArrayParameter, ARRAY_PARAMETER, 58)
TYPE_BIT_CODE(HLSLAttributedResource, HLSLRESOURCE_ATTRIBUTED, 59)

#undef TYPE_BIT_CODE
27 changes: 27 additions & 0 deletions clang/lib/AST/ASTContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2406,6 +2406,10 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
return getTypeInfo(
cast<BTFTagAttributedType>(T)->getWrappedType().getTypePtr());

case Type::HLSLAttributedResource:
return getTypeInfo(
cast<HLSLAttributedResourceType>(T)->getWrappedType().getTypePtr());

case Type::Atomic: {
// Start with the base type information.
TypeInfo Info = getTypeInfo(cast<AtomicType>(T)->getValueType());
Expand Down Expand Up @@ -5219,6 +5223,28 @@ QualType ASTContext::getBTFTagAttributedType(const BTFTypeTagAttr *BTFAttr,
return QualType(Ty, 0);
}

QualType ASTContext::getHLSLAttributedResourceType(
QualType Wrapped, QualType Contained,
const HLSLAttributedResourceType::Attributes &Attrs) {

llvm::FoldingSetNodeID ID;
HLSLAttributedResourceType::Profile(ID, Wrapped, Contained, Attrs);

void *InsertPos = nullptr;
HLSLAttributedResourceType *Ty =
HLSLAttributedResourceTypes.FindNodeOrInsertPos(ID, InsertPos);
if (Ty)
return QualType(Ty, 0);

QualType Canon = getCanonicalType(Wrapped);
Ty = new (*this, alignof(HLSLAttributedResourceType))
HLSLAttributedResourceType(Canon, Wrapped, Contained, Attrs);

Types.push_back(Ty);
HLSLAttributedResourceTypes.InsertNode(Ty, InsertPos);

return QualType(Ty, 0);
}
/// Retrieve a substitution-result type.
QualType ASTContext::getSubstTemplateTypeParmType(
QualType Replacement, Decl *AssociatedDecl, unsigned Index,
Expand Down Expand Up @@ -13584,6 +13610,7 @@ static QualType getCommonSugarTypeNode(ASTContext &Ctx, const Type *X,
CANONICAL_TYPE(FunctionNoProto)
CANONICAL_TYPE(FunctionProto)
CANONICAL_TYPE(IncompleteArray)
CANONICAL_TYPE(HLSLAttributedResource)
CANONICAL_TYPE(LValueReference)
CANONICAL_TYPE(MemberPointer)
CANONICAL_TYPE(ObjCInterface)
Expand Down
13 changes: 13 additions & 0 deletions clang/lib/AST/ASTImporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1832,6 +1832,19 @@ ExpectedType clang::ASTNodeImporter::VisitBTFTagAttributedType(
ToWrappedType);
}

ExpectedType clang::ASTNodeImporter::VisitHLSLAttributedResourceType(
const clang::HLSLAttributedResourceType *T) {
Error Err = Error::success();
const HLSLAttributedResourceType::Attributes &ToAttrs = T->getAttrs();
QualType ToWrappedType = importChecked(Err, T->getWrappedType());
QualType ToContainedType = importChecked(Err, T->getContainedType());
if (Err)
return std::move(Err);

return Importer.getToContext().getHLSLAttributedResourceType(
ToWrappedType, ToContainedType, ToAttrs);
}

ExpectedType clang::ASTNodeImporter::VisitConstantMatrixType(
const clang::ConstantMatrixType *T) {
ExpectedType ToElementTypeOrErr = import(T->getElementType());
Expand Down
25 changes: 25 additions & 0 deletions clang/lib/AST/ASTStructuralEquivalence.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -799,6 +799,16 @@ static bool IsEquivalentExceptionSpec(StructuralEquivalenceContext &Context,
return true;
}

// Determine structural equivalence of two instances of
// HLSLAttributedResourceType::Attributes
static bool
IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
const HLSLAttributedResourceType::Attributes &Attrs1,
const HLSLAttributedResourceType::Attributes &Attrs2) {
return std::tie(Attrs1.ResourceClass, Attrs1.IsROV) ==
std::tie(Attrs2.ResourceClass, Attrs2.IsROV);
}

/// Determine structural equivalence of two types.
static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
QualType T1, QualType T2) {
Expand Down Expand Up @@ -1093,6 +1103,21 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
return false;
break;

case Type::HLSLAttributedResource:
if (!IsStructurallyEquivalent(
Context, cast<HLSLAttributedResourceType>(T1)->getWrappedType(),
cast<HLSLAttributedResourceType>(T2)->getWrappedType()))
return false;
if (!IsStructurallyEquivalent(
Context, cast<HLSLAttributedResourceType>(T1)->getContainedType(),
cast<HLSLAttributedResourceType>(T2)->getContainedType()))
return false;
if (!IsStructurallyEquivalent(
Context, cast<HLSLAttributedResourceType>(T1)->getAttrs(),
cast<HLSLAttributedResourceType>(T2)->getAttrs()))
return false;
break;

case Type::Paren:
if (!IsStructurallyEquivalent(Context, cast<ParenType>(T1)->getInnerType(),
cast<ParenType>(T2)->getInnerType()))
Expand Down
106 changes: 106 additions & 0 deletions clang/lib/AST/ByteCode/Compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4991,6 +4991,8 @@ bool Compiler<Emitter>::VisitUnaryOperator(const UnaryOperator *E) {
const Expr *SubExpr = E->getSubExpr();
if (SubExpr->getType()->isAnyComplexType())
return this->VisitComplexUnaryOperator(E);
if (SubExpr->getType()->isVectorType())
return this->VisitVectorUnaryOperator(E);
std::optional<PrimType> T = classify(SubExpr->getType());

switch (E->getOpcode()) {
Expand Down Expand Up @@ -5312,6 +5314,110 @@ bool Compiler<Emitter>::VisitComplexUnaryOperator(const UnaryOperator *E) {
return true;
}

template <class Emitter>
bool Compiler<Emitter>::VisitVectorUnaryOperator(const UnaryOperator *E) {
const Expr *SubExpr = E->getSubExpr();
assert(SubExpr->getType()->isVectorType());

if (DiscardResult)
return this->discard(SubExpr);

auto UnaryOp = E->getOpcode();
if (UnaryOp != UO_Plus && UnaryOp != UO_Minus && UnaryOp != UO_LNot &&
UnaryOp != UO_Not && UnaryOp != UO_AddrOf)
return this->emitInvalid(E);

// Nothing to do here.
if (UnaryOp == UO_Plus || UnaryOp == UO_AddrOf)
return this->delegate(SubExpr);

if (!Initializing) {
std::optional<unsigned> LocalIndex = allocateLocal(SubExpr);
if (!LocalIndex)
return false;
if (!this->emitGetPtrLocal(*LocalIndex, E))
return false;
}

// The offset of the temporary, if we created one.
unsigned SubExprOffset =
this->allocateLocalPrimitive(SubExpr, PT_Ptr, true, false);
if (!this->visit(SubExpr))
return false;
if (!this->emitSetLocal(PT_Ptr, SubExprOffset, E))
return false;

const auto *VecTy = SubExpr->getType()->getAs<VectorType>();
PrimType ElemT = classifyVectorElementType(SubExpr->getType());
auto getElem = [=](unsigned Offset, unsigned Index) -> bool {
if (!this->emitGetLocal(PT_Ptr, Offset, E))
return false;
return this->emitArrayElemPop(ElemT, Index, E);
};

switch (UnaryOp) {
case UO_Minus:
for (unsigned I = 0; I != VecTy->getNumElements(); ++I) {
if (!getElem(SubExprOffset, I))
return false;
if (!this->emitNeg(ElemT, E))
return false;
if (!this->emitInitElem(ElemT, I, E))
return false;
}
break;
case UO_LNot: { // !x
// In C++, the logic operators !, &&, || are available for vectors. !v is
// equivalent to v == 0.
//
// The result of the comparison is a vector of the same width and number of
// elements as the comparison operands with a signed integral element type.
//
// https://gcc.gnu.org/onlinedocs/gcc/Vector-Extensions.html
QualType ResultVecTy = E->getType();
PrimType ResultVecElemT =
classifyPrim(ResultVecTy->getAs<VectorType>()->getElementType());
for (unsigned I = 0; I != VecTy->getNumElements(); ++I) {
if (!getElem(SubExprOffset, I))
return false;
// operator ! on vectors returns -1 for 'truth', so negate it.
if (!this->emitPrimCast(ElemT, PT_Bool, Ctx.getASTContext().BoolTy, E))
return false;
if (!this->emitInv(E))
return false;
if (!this->emitPrimCast(PT_Bool, ElemT, VecTy->getElementType(), E))
return false;
if (!this->emitNeg(ElemT, E))
return false;
if (ElemT != ResultVecElemT &&
!this->emitPrimCast(ElemT, ResultVecElemT, ResultVecTy, E))
return false;
if (!this->emitInitElem(ResultVecElemT, I, E))
return false;
}
break;
}
case UO_Not: // ~x
for (unsigned I = 0; I != VecTy->getNumElements(); ++I) {
if (!getElem(SubExprOffset, I))
return false;
if (ElemT == PT_Bool) {
if (!this->emitInv(E))
return false;
} else {
if (!this->emitComp(ElemT, E))
return false;
}
if (!this->emitInitElem(ElemT, I, E))
return false;
}
break;
default:
llvm_unreachable("Unsupported unary operators should be handled up front");
}
return true;
}

template <class Emitter>
bool Compiler<Emitter>::visitDeclRef(const ValueDecl *D, const Expr *E) {
if (DiscardResult)
Expand Down
6 changes: 6 additions & 0 deletions clang/lib/AST/ByteCode/Compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ class Compiler : public ConstStmtVisitor<Compiler<Emitter>, bool>,
bool VisitGNUNullExpr(const GNUNullExpr *E);
bool VisitCXXThisExpr(const CXXThisExpr *E);
bool VisitUnaryOperator(const UnaryOperator *E);
bool VisitVectorUnaryOperator(const UnaryOperator *E);
bool VisitComplexUnaryOperator(const UnaryOperator *E);
bool VisitDeclRefExpr(const DeclRefExpr *E);
bool VisitImplicitValueInitExpr(const ImplicitValueInitExpr *E);
Expand Down Expand Up @@ -349,6 +350,11 @@ class Compiler : public ConstStmtVisitor<Compiler<Emitter>, bool>,
return *this->classify(ElemType);
}

PrimType classifyVectorElementType(QualType T) const {
assert(T->isVectorType());
return *this->classify(T->getAs<VectorType>()->getElementType());
}

bool emitComplexReal(const Expr *SubExpr);
bool emitComplexBoolCast(const Expr *E);
bool emitComplexComparison(const Expr *LHS, const Expr *RHS,
Expand Down
78 changes: 49 additions & 29 deletions clang/lib/AST/ByteCode/Interp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -305,14 +305,18 @@ bool CheckLive(InterpState &S, CodePtr OpPC, const Pointer &Ptr,

if (!Ptr.isLive()) {
const auto &Src = S.Current->getSource(OpPC);
bool IsTemp = Ptr.isTemporary();

S.FFDiag(Src, diag::note_constexpr_lifetime_ended, 1) << AK << !IsTemp;
if (Ptr.isDynamic()) {
S.FFDiag(Src, diag::note_constexpr_access_deleted_object) << AK;
} else {
bool IsTemp = Ptr.isTemporary();
S.FFDiag(Src, diag::note_constexpr_lifetime_ended, 1) << AK << !IsTemp;

if (IsTemp)
S.Note(Ptr.getDeclLoc(), diag::note_constexpr_temporary_here);
else
S.Note(Ptr.getDeclLoc(), diag::note_declared_at);
if (IsTemp)
S.Note(Ptr.getDeclLoc(), diag::note_constexpr_temporary_here);
else
S.Note(Ptr.getDeclLoc(), diag::note_declared_at);
}

return false;
}
Expand All @@ -323,36 +327,52 @@ bool CheckLive(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
bool CheckConstant(InterpState &S, CodePtr OpPC, const Descriptor *Desc) {
assert(Desc);

auto IsConstType = [&S](const VarDecl *VD) -> bool {
QualType T = VD->getType();

if (T.isConstant(S.getASTContext()))
return true;

if (S.getLangOpts().CPlusPlus && !S.getLangOpts().CPlusPlus11)
return (T->isSignedIntegerOrEnumerationType() ||
T->isUnsignedIntegerOrEnumerationType()) &&
T.isConstQualified();
const auto *D = Desc->asVarDecl();
if (!D || !D->hasGlobalStorage())
return true;

if (T.isConstQualified())
return true;
if (D == S.EvaluatingDecl)
return true;

if (const auto *RT = T->getAs<ReferenceType>())
return RT->getPointeeType().isConstQualified();
if (D->isConstexpr())
return true;

if (const auto *PT = T->getAs<PointerType>())
return PT->getPointeeType().isConstQualified();
QualType T = D->getType();
bool IsConstant = T.isConstant(S.getASTContext());
if (T->isIntegralOrEnumerationType()) {
if (!IsConstant) {
diagnoseNonConstVariable(S, OpPC, D);
return false;
}
return true;
}

return false;
};
if (IsConstant) {
if (S.getLangOpts().CPlusPlus) {
S.CCEDiag(S.Current->getLocation(OpPC),
S.getLangOpts().CPlusPlus11
? diag::note_constexpr_ltor_non_constexpr
: diag::note_constexpr_ltor_non_integral,
1)
<< D << T;
S.Note(D->getLocation(), diag::note_declared_at);
} else {
S.CCEDiag(S.Current->getLocation(OpPC));
}
return true;
}

if (const auto *D = Desc->asVarDecl();
D && D->hasGlobalStorage() && D != S.EvaluatingDecl && !IsConstType(D)) {
diagnoseNonConstVariable(S, OpPC, D);
return false;
if (T->isPointerOrReferenceType()) {
if (!T->getPointeeType().isConstant(S.getASTContext()) ||
!S.getLangOpts().CPlusPlus11) {
diagnoseNonConstVariable(S, OpPC, D);
return false;
}
return true;
}

return true;
diagnoseNonConstVariable(S, OpPC, D);
return false;
}

static bool CheckConstant(InterpState &S, CodePtr OpPC, const Pointer &Ptr) {
Expand Down
6 changes: 5 additions & 1 deletion clang/lib/AST/ByteCode/Interp.h
Original file line number Diff line number Diff line change
Expand Up @@ -2630,7 +2630,11 @@ inline bool Call(InterpState &S, CodePtr OpPC, const Function *Func,
if (!CheckCallable(S, OpPC, Func))
return false;

if (Func->hasThisPointer() && S.checkingPotentialConstantExpression())
// FIXME: The isConstructor() check here is not always right. The current
// constant evaluator is somewhat inconsistent in when it allows a function
// call when checking for a constant expression.
if (Func->hasThisPointer() && S.checkingPotentialConstantExpression() &&
!Func->isConstructor())
return false;

if (!CheckCallDepth(S, OpPC))
Expand Down
2 changes: 2 additions & 0 deletions clang/lib/AST/ByteCode/InterpBlock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ DeadBlock::DeadBlock(DeadBlock *&Root, Block *Blk)
Prev = nullptr;
Root = this;

B.IsDynamic = Blk->IsDynamic;

// Transfer pointers.
B.Pointers = Blk->Pointers;
for (Pointer *P = Blk->Pointers; P; P = P->Next)
Expand Down
8 changes: 8 additions & 0 deletions clang/lib/AST/ByteCode/Pointer.h
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,14 @@ class Pointer {
}
return false;
}
/// Checks if the storage has been dynamically allocated.
bool isDynamic() const {
if (isBlockPointer()) {
assert(asBlockPointer().Pointee);
return asBlockPointer().Pointee->isDynamic();
}
return false;
}
/// Checks if the storage is a static temporary.
bool isStaticTemporary() const { return isStatic() && isTemporary(); }

Expand Down
4 changes: 4 additions & 0 deletions clang/lib/AST/ExprConstant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12719,6 +12719,10 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
return false;
}

case Builtin::BI__noop:
// __noop always evaluates successfully
return true;

case Builtin::BI__builtin_is_constant_evaluated: {
const auto *Callee = Info.CurrentCall->getCallee();
if (Info.InConstantContext && !Info.CheckingPotentialConstantExpression &&
Expand Down
13 changes: 5 additions & 8 deletions clang/lib/AST/ItaniumMangle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2419,6 +2419,7 @@ bool CXXNameMangler::mangleUnresolvedTypeOrSimpleId(QualType Ty,
case Type::Paren:
case Type::Attributed:
case Type::BTFTagAttributed:
case Type::HLSLAttributedResource:
case Type::Auto:
case Type::DeducedTemplateSpecialization:
case Type::PackExpansion:
Expand Down Expand Up @@ -4442,14 +4443,10 @@ void CXXNameMangler::mangleType(const DeducedTemplateSpecializationType *T) {
if (!Deduced.isNull())
return mangleType(Deduced);

TemplateDecl *TD = T->getTemplateName().getAsTemplateDecl();
assert(TD && "shouldn't form deduced TST unless we know we have a template");

if (mangleSubstitution(TD))
return;

mangleName(GlobalDecl(TD));
addSubstitution(TD);
TemplateName TN = T->getTemplateName();
assert(TN.getAsTemplateDecl() &&
"shouldn't form deduced TST unless we know we have a template");
mangleType(TN);
}

void CXXNameMangler::mangleType(const AtomicType *T) {
Expand Down
5 changes: 5 additions & 0 deletions clang/lib/AST/TypeLoc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -726,6 +726,11 @@ namespace {
return Visit(T.getWrappedLoc());
}

TypeLoc
VisitHLSLAttributedResourceTypeLoc(HLSLAttributedResourceTypeLoc T) {
return Visit(T.getWrappedLoc());
}

TypeLoc VisitMacroQualifiedTypeLoc(MacroQualifiedTypeLoc T) {
return Visit(T.getInnerLoc());
}
Expand Down
18 changes: 18 additions & 0 deletions clang/lib/AST/TypePrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,7 @@ bool TypePrinter::canPrefixQualifiers(const Type *T,
case Type::BitInt:
case Type::DependentBitInt:
case Type::BTFTagAttributed:
case Type::HLSLAttributedResource:
CanPrefixQualifiers = true;
break;

Expand Down Expand Up @@ -2048,6 +2049,23 @@ void TypePrinter::printBTFTagAttributedAfter(const BTFTagAttributedType *T,
printAfter(T->getWrappedType(), OS);
}

void TypePrinter::printHLSLAttributedResourceBefore(
const HLSLAttributedResourceType *T, raw_ostream &OS) {
printBefore(T->getWrappedType(), OS);

const HLSLAttributedResourceType::Attributes &Attrs = T->getAttrs();
OS << " [[hlsl::resource_class("
<< HLSLResourceClassAttr::ConvertResourceClassToStr(Attrs.ResourceClass)
<< ")]]";
if (Attrs.IsROV)
OS << " [[hlsl::is_rov()]]";
}

void TypePrinter::printHLSLAttributedResourceAfter(
const HLSLAttributedResourceType *T, raw_ostream &OS) {
printAfter(T->getWrappedType(), OS);
}

void TypePrinter::printObjCInterfaceBefore(const ObjCInterfaceType *T,
raw_ostream &OS) {
OS << T->getDecl()->getName();
Expand Down
1 change: 1 addition & 0 deletions clang/lib/Basic/SourceManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,7 @@ void SourceManager::clearIDTables() {
LastLineNoContentCache = nullptr;
LastFileIDLookup = FileID();

IncludedLocMap.clear();
if (LineTable)
LineTable->clear();

Expand Down
7 changes: 7 additions & 0 deletions clang/lib/Basic/Targets/DirectX.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,13 @@ class LLVM_LIBRARY_VISIBILITY DirectXTargetInfo : public TargetInfo {
BuiltinVaListKind getBuiltinVaListKind() const override {
return TargetInfo::VoidPtrBuiltinVaList;
}

void adjust(DiagnosticsEngine &Diags, LangOptions &Opts) override {
TargetInfo::adjust(Diags, Opts);
// The static values this addresses do not apply outside of the same thread
// This protection is neither available nor needed
Opts.ThreadsafeStatics = false;
}
};

} // namespace targets
Expand Down
2 changes: 2 additions & 0 deletions clang/lib/CodeGen/BackendUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1095,6 +1095,8 @@ void EmitAssemblyHelper::RunOptimizationPipeline(
TheModule->addModuleFlag(llvm::Module::Error, "UnifiedLTO", uint32_t(1));
}

// FIXME: This should eventually be replaced by a first-class driver option.
// This should be done for both clang and flang simultaneously.
// Print a textual, '-passes=' compatible, representation of pipeline if
// requested.
if (PrintPipelinePasses) {
Expand Down
12 changes: 12 additions & 0 deletions clang/lib/CodeGen/CGBuiltin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21211,6 +21211,7 @@ Value *CodeGenFunction::EmitWebAssemblyBuiltinExpr(unsigned BuiltinID,
case WebAssembly::BI__builtin_wasm_trunc_saturate_s_i32_f64:
case WebAssembly::BI__builtin_wasm_trunc_saturate_s_i64_f32:
case WebAssembly::BI__builtin_wasm_trunc_saturate_s_i64_f64:
case WebAssembly::BI__builtin_wasm_trunc_saturate_s_i16x8_f16x8:
case WebAssembly::BI__builtin_wasm_trunc_saturate_s_i32x4_f32x4: {
Value *Src = EmitScalarExpr(E->getArg(0));
llvm::Type *ResT = ConvertType(E->getType());
Expand All @@ -21222,6 +21223,7 @@ Value *CodeGenFunction::EmitWebAssemblyBuiltinExpr(unsigned BuiltinID,
case WebAssembly::BI__builtin_wasm_trunc_saturate_u_i32_f64:
case WebAssembly::BI__builtin_wasm_trunc_saturate_u_i64_f32:
case WebAssembly::BI__builtin_wasm_trunc_saturate_u_i64_f64:
case WebAssembly::BI__builtin_wasm_trunc_saturate_u_i16x8_f16x8:
case WebAssembly::BI__builtin_wasm_trunc_saturate_u_i32x4_f32x4: {
Value *Src = EmitScalarExpr(E->getArg(0));
llvm::Type *ResT = ConvertType(E->getType());
Expand Down Expand Up @@ -21269,6 +21271,10 @@ Value *CodeGenFunction::EmitWebAssemblyBuiltinExpr(unsigned BuiltinID,
CGM.getIntrinsic(Intrinsic::wasm_pmax, ConvertType(E->getType()));
return Builder.CreateCall(Callee, {LHS, RHS});
}
case WebAssembly::BI__builtin_wasm_ceil_f16x8:
case WebAssembly::BI__builtin_wasm_floor_f16x8:
case WebAssembly::BI__builtin_wasm_trunc_f16x8:
case WebAssembly::BI__builtin_wasm_nearest_f16x8:
case WebAssembly::BI__builtin_wasm_ceil_f32x4:
case WebAssembly::BI__builtin_wasm_floor_f32x4:
case WebAssembly::BI__builtin_wasm_trunc_f32x4:
Expand All @@ -21279,18 +21285,22 @@ Value *CodeGenFunction::EmitWebAssemblyBuiltinExpr(unsigned BuiltinID,
case WebAssembly::BI__builtin_wasm_nearest_f64x2: {
unsigned IntNo;
switch (BuiltinID) {
case WebAssembly::BI__builtin_wasm_ceil_f16x8:
case WebAssembly::BI__builtin_wasm_ceil_f32x4:
case WebAssembly::BI__builtin_wasm_ceil_f64x2:
IntNo = Intrinsic::ceil;
break;
case WebAssembly::BI__builtin_wasm_floor_f16x8:
case WebAssembly::BI__builtin_wasm_floor_f32x4:
case WebAssembly::BI__builtin_wasm_floor_f64x2:
IntNo = Intrinsic::floor;
break;
case WebAssembly::BI__builtin_wasm_trunc_f16x8:
case WebAssembly::BI__builtin_wasm_trunc_f32x4:
case WebAssembly::BI__builtin_wasm_trunc_f64x2:
IntNo = Intrinsic::trunc;
break;
case WebAssembly::BI__builtin_wasm_nearest_f16x8:
case WebAssembly::BI__builtin_wasm_nearest_f32x4:
case WebAssembly::BI__builtin_wasm_nearest_f64x2:
IntNo = Intrinsic::nearbyint;
Expand Down Expand Up @@ -21489,12 +21499,14 @@ Value *CodeGenFunction::EmitWebAssemblyBuiltinExpr(unsigned BuiltinID,
CGM.getIntrinsic(Intrinsic::wasm_bitmask, Vec->getType());
return Builder.CreateCall(Callee, {Vec});
}
case WebAssembly::BI__builtin_wasm_abs_f16x8:
case WebAssembly::BI__builtin_wasm_abs_f32x4:
case WebAssembly::BI__builtin_wasm_abs_f64x2: {
Value *Vec = EmitScalarExpr(E->getArg(0));
Function *Callee = CGM.getIntrinsic(Intrinsic::fabs, Vec->getType());
return Builder.CreateCall(Callee, {Vec});
}
case WebAssembly::BI__builtin_wasm_sqrt_f16x8:
case WebAssembly::BI__builtin_wasm_sqrt_f32x4:
case WebAssembly::BI__builtin_wasm_sqrt_f64x2: {
Value *Vec = EmitScalarExpr(E->getArg(0));
Expand Down
1 change: 1 addition & 0 deletions clang/lib/CodeGen/CGDebugInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3851,6 +3851,7 @@ llvm::DIType *CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile *Unit) {
case Type::Auto:
case Type::Attributed:
case Type::BTFTagAttributed:
case Type::HLSLAttributedResource:
case Type::Adjusted:
case Type::Decayed:
case Type::DeducedTemplateSpecialization:
Expand Down
5 changes: 3 additions & 2 deletions clang/lib/CodeGen/CodeGenAction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -969,9 +969,10 @@ CodeGenerator *CodeGenAction::getCodeGenerator() const {
return BEConsumer->getCodeGenerator();
}

bool CodeGenAction::BeginSourceFileAction(CompilerInstance &CI) {
bool CodeGenAction::BeginInvocation(CompilerInstance &CI) {
if (CI.getFrontendOpts().GenReducedBMI)
CI.getLangOpts().setCompilingModule(LangOptions::CMK_ModuleInterface);
return BeginInvocationForModules(CI);

return true;
}

Expand Down
11 changes: 8 additions & 3 deletions clang/lib/CodeGen/CodeGenFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1064,13 +1064,17 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy,
// OpenCL C 2.0 v2.2-11 s6.9.i:
// Recursion is not supported.
//
// HLSL
// Recursion is not supported.
//
// SYCL v1.2.1 s3.10:
// kernels cannot include RTTI information, exception classes,
// recursive code, virtual functions or make use of C++ libraries that
// are not compiled for the device.
if (FD && ((getLangOpts().CPlusPlus && FD->isMain()) ||
getLangOpts().OpenCL || getLangOpts().SYCLIsDevice ||
(getLangOpts().CUDA && FD->hasAttr<CUDAGlobalAttr>())))
if (FD &&
((getLangOpts().CPlusPlus && FD->isMain()) || getLangOpts().OpenCL ||
getLangOpts().HLSL || getLangOpts().SYCLIsDevice ||
(getLangOpts().CUDA && FD->hasAttr<CUDAGlobalAttr>())))
Fn->addFnAttr(llvm::Attribute::NoRecurse);

llvm::RoundingMode RM = getLangOpts().getDefaultRoundingMode();
Expand Down Expand Up @@ -2489,6 +2493,7 @@ void CodeGenFunction::EmitVariablyModifiedType(QualType type) {
case Type::UnaryTransform:
case Type::Attributed:
case Type::BTFTagAttributed:
case Type::HLSLAttributedResource:
case Type::SubstTemplateTypeParm:
case Type::MacroQualified:
case Type::CountAttributed:
Expand Down
12 changes: 12 additions & 0 deletions clang/lib/Driver/ToolChain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,12 @@ static void getAArch64MultilibFlags(const Driver &D,
assert(!ArchName.empty() && "at least one architecture should be found");
MArch.insert(MArch.begin(), ("-march=" + ArchName).str());
Result.push_back(llvm::join(MArch, "+"));

const Arg *BranchProtectionArg =
Args.getLastArgNoClaim(options::OPT_mbranch_protection_EQ);
if (BranchProtectionArg) {
Result.push_back(BranchProtectionArg->getAsString(Args));
}
}

static void getARMMultilibFlags(const Driver &D,
Expand Down Expand Up @@ -268,6 +274,12 @@ static void getARMMultilibFlags(const Driver &D,
case arm::FloatABI::Invalid:
llvm_unreachable("Invalid float ABI");
}

const Arg *BranchProtectionArg =
Args.getLastArgNoClaim(options::OPT_mbranch_protection_EQ);
if (BranchProtectionArg) {
Result.push_back(BranchProtectionArg->getAsString(Args));
}
}

static void getRISCVMultilibFlags(const Driver &D, const llvm::Triple &Triple,
Expand Down
6 changes: 4 additions & 2 deletions clang/lib/ExtractAPI/API.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -150,11 +150,13 @@ void APISet::removeRecord(StringRef USR) {
if (auto *RecordAsCtx = llvm::dyn_cast<RecordContext>(Record))
ParentCtx->stealRecordChain(*RecordAsCtx);
} else {
TopLevelRecords.erase(Record);
auto *It = llvm::find(TopLevelRecords, Record);
if (It != TopLevelRecords.end())
TopLevelRecords.erase(It);
if (auto *RecordAsCtx = llvm::dyn_cast<RecordContext>(Record)) {
for (const auto *Child = RecordAsCtx->First; Child != nullptr;
Child = Child->getNextInContext())
TopLevelRecords.insert(Child);
TopLevelRecords.push_back(Child);
}
}
USRBasedLookupTable.erase(Result);
Expand Down
10 changes: 4 additions & 6 deletions clang/lib/Format/ContinuationIndenter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -894,10 +894,8 @@ void ContinuationIndenter::addTokenOnCurrentLine(LineState &State, bool DryRun,
CurrentState.ContainsUnwrappedBuilder = true;
}

if (Current.is(TT_TrailingReturnArrow) &&
Style.Language == FormatStyle::LK_Java) {
if (Current.is(TT_LambdaArrow) && Style.Language == FormatStyle::LK_Java)
CurrentState.NoLineBreak = true;
}
if (Current.isMemberAccess() && Previous.is(tok::r_paren) &&
(Previous.MatchingParen &&
(Previous.TotalLength - Previous.MatchingParen->TotalLength > 10))) {
Expand Down Expand Up @@ -1052,7 +1050,7 @@ unsigned ContinuationIndenter::addTokenOnNewLine(LineState &State,
//
// is common and should be formatted like a free-standing function. The same
// goes for wrapping before the lambda return type arrow.
if (Current.isNot(TT_TrailingReturnArrow) &&
if (Current.isNot(TT_LambdaArrow) &&
(!Style.isJavaScript() || Current.NestingLevel != 0 ||
!PreviousNonComment || PreviousNonComment->isNot(tok::equal) ||
!Current.isOneOf(Keywords.kw_async, Keywords.kw_function))) {
Expand Down Expand Up @@ -1312,7 +1310,7 @@ unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) {
}
return CurrentState.Indent;
}
if (Current.is(TT_TrailingReturnArrow) &&
if (Current.is(TT_LambdaArrow) &&
Previous.isOneOf(tok::kw_noexcept, tok::kw_mutable, tok::kw_constexpr,
tok::kw_consteval, tok::kw_static, TT_AttributeSquare)) {
return ContinuationIndent;
Expand Down Expand Up @@ -1646,7 +1644,7 @@ unsigned ContinuationIndenter::moveStateToNextToken(LineState &State,
}
if (Current.isOneOf(TT_BinaryOperator, TT_ConditionalExpr) && Newline)
CurrentState.NestedBlockIndent = State.Column + Current.ColumnWidth + 1;
if (Current.isOneOf(TT_LambdaLSquare, TT_TrailingReturnArrow))
if (Current.isOneOf(TT_LambdaLSquare, TT_LambdaArrow))
CurrentState.LastSpace = State.Column;
if (Current.is(TT_RequiresExpression) &&
Style.RequiresExpressionIndentation == FormatStyle::REI_Keyword) {
Expand Down
3 changes: 2 additions & 1 deletion clang/lib/Format/FormatToken.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ namespace format {
TYPE(JsTypeColon) \
TYPE(JsTypeOperator) \
TYPE(JsTypeOptionalQuestion) \
TYPE(LambdaArrow) \
TYPE(LambdaDefinitionLParen) \
TYPE(LambdaLBrace) \
TYPE(LambdaLSquare) \
Expand Down Expand Up @@ -726,7 +727,7 @@ struct FormatToken {
bool isMemberAccess() const {
return isOneOf(tok::arrow, tok::period, tok::arrowstar) &&
!isOneOf(TT_DesignatedInitializerPeriod, TT_TrailingReturnArrow,
TT_LeadingJavaAnnotation);
TT_LambdaArrow, TT_LeadingJavaAnnotation);
}

bool isPointerOrReference() const {
Expand Down
33 changes: 18 additions & 15 deletions clang/lib/Format/TokenAnnotator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -833,7 +833,7 @@ class AnnotatingParser {
}
// An arrow after an ObjC method expression is not a lambda arrow.
if (CurrentToken->is(TT_ObjCMethodExpr) && CurrentToken->Next &&
CurrentToken->Next->is(TT_TrailingReturnArrow)) {
CurrentToken->Next->is(TT_LambdaArrow)) {
CurrentToken->Next->overwriteFixedType(TT_Unknown);
}
Left->MatchingParen = CurrentToken;
Expand Down Expand Up @@ -1770,8 +1770,10 @@ class AnnotatingParser {
}
break;
case tok::arrow:
if (Tok->Previous && Tok->Previous->is(tok::kw_noexcept))
if (Tok->isNot(TT_LambdaArrow) && Tok->Previous &&
Tok->Previous->is(tok::kw_noexcept)) {
Tok->setType(TT_TrailingReturnArrow);
}
break;
case tok::equal:
// In TableGen, there must be a value after "=";
Expand Down Expand Up @@ -2057,11 +2059,11 @@ class AnnotatingParser {
TT_LambdaLSquare, TT_LambdaLBrace, TT_AttributeMacro, TT_IfMacro,
TT_ForEachMacro, TT_TypenameMacro, TT_FunctionLBrace,
TT_ImplicitStringLiteral, TT_InlineASMBrace, TT_FatArrow,
TT_NamespaceMacro, TT_OverloadedOperator, TT_RegexLiteral,
TT_TemplateString, TT_ObjCStringLiteral, TT_UntouchableMacroFunc,
TT_StatementAttributeLikeMacro, TT_FunctionLikeOrFreestandingMacro,
TT_ClassLBrace, TT_EnumLBrace, TT_RecordLBrace, TT_StructLBrace,
TT_UnionLBrace, TT_RequiresClause,
TT_LambdaArrow, TT_NamespaceMacro, TT_OverloadedOperator,
TT_RegexLiteral, TT_TemplateString, TT_ObjCStringLiteral,
TT_UntouchableMacroFunc, TT_StatementAttributeLikeMacro,
TT_FunctionLikeOrFreestandingMacro, TT_ClassLBrace, TT_EnumLBrace,
TT_RecordLBrace, TT_StructLBrace, TT_UnionLBrace, TT_RequiresClause,
TT_RequiresClauseInARequiresExpression, TT_RequiresExpression,
TT_RequiresExpressionLParen, TT_RequiresExpressionLBrace,
TT_BracedListLBrace)) {
Expand Down Expand Up @@ -2247,7 +2249,7 @@ class AnnotatingParser {
Contexts.back().IsExpression = true;
} else if (Current.is(TT_TrailingReturnArrow)) {
Contexts.back().IsExpression = false;
} else if (Current.is(Keywords.kw_assert)) {
} else if (Current.isOneOf(TT_LambdaArrow, Keywords.kw_assert)) {
Contexts.back().IsExpression = Style.Language == FormatStyle::LK_Java;
} else if (Current.Previous &&
Current.Previous->is(TT_CtorInitializerColon)) {
Expand Down Expand Up @@ -2382,7 +2384,7 @@ class AnnotatingParser {
AutoFound = true;
} else if (Current.is(tok::arrow) &&
Style.Language == FormatStyle::LK_Java) {
Current.setType(TT_TrailingReturnArrow);
Current.setType(TT_LambdaArrow);
} else if (Current.is(tok::arrow) && Style.isVerilog()) {
// The implication operator.
Current.setType(TT_BinaryOperator);
Expand Down Expand Up @@ -3288,7 +3290,7 @@ class ExpressionParser {
}
if (Current->is(TT_JsComputedPropertyName))
return prec::Assignment;
if (Current->is(TT_TrailingReturnArrow))
if (Current->is(TT_LambdaArrow))
return prec::Comma;
if (Current->is(TT_FatArrow))
return prec::Assignment;
Expand Down Expand Up @@ -4213,7 +4215,7 @@ unsigned TokenAnnotator::splitPenalty(const AnnotatedLine &Line,
}
if (Right.is(TT_PointerOrReference))
return 190;
if (Right.is(TT_TrailingReturnArrow))
if (Right.is(TT_LambdaArrow))
return 110;
if (Left.is(tok::equal) && Right.is(tok::l_brace))
return 160;
Expand Down Expand Up @@ -5293,9 +5295,10 @@ bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line,
return false;
}

if (Right.is(TT_TrailingReturnArrow) || Left.is(TT_TrailingReturnArrow))
if (Right.isOneOf(TT_TrailingReturnArrow, TT_LambdaArrow) ||
Left.isOneOf(TT_TrailingReturnArrow, TT_LambdaArrow)) {
return true;

}
if (Left.is(tok::comma) && Right.isNot(TT_OverloadedOperatorLParen) &&
// In an unexpanded macro call we only find the parentheses and commas
// in a line; the commas and closing parenthesis do not require a space.
Expand Down Expand Up @@ -6330,8 +6333,8 @@ bool TokenAnnotator::canBreakBefore(const AnnotatedLine &Line,
return Left.isOneOf(tok::comma, tok::coloncolon, tok::semi, tok::l_brace,
tok::kw_class, tok::kw_struct, tok::comment) ||
Right.isMemberAccess() ||
Right.isOneOf(TT_TrailingReturnArrow, tok::lessless, tok::colon,
tok::l_square, tok::at) ||
Right.isOneOf(TT_TrailingReturnArrow, TT_LambdaArrow, tok::lessless,
tok::colon, tok::l_square, tok::at) ||
(Left.is(tok::r_paren) &&
Right.isOneOf(tok::identifier, tok::kw_const)) ||
(Left.is(tok::l_paren) && Right.isNot(tok::r_paren)) ||
Expand Down
3 changes: 2 additions & 1 deletion clang/lib/Format/UnwrappedLineParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2326,7 +2326,7 @@ bool UnwrappedLineParser::tryToParseLambda() {
// This might or might not actually be a lambda arrow (this could be an
// ObjC method invocation followed by a dereferencing arrow). We might
// reset this back to TT_Unknown in TokenAnnotator.
FormatTok->setFinalizedType(TT_TrailingReturnArrow);
FormatTok->setFinalizedType(TT_LambdaArrow);
SeenArrow = true;
nextToken();
break;
Expand Down Expand Up @@ -4029,6 +4029,7 @@ void UnwrappedLineParser::parseRecord(bool ParseAsExpr) {
}
break;
case tok::coloncolon:
case tok::hashhash:
break;
default:
if (!JSPastExtendsOrImplements && !ClassName &&
Expand Down
15 changes: 12 additions & 3 deletions clang/lib/Frontend/FrontendActions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -262,11 +262,20 @@ GenerateModuleFromModuleMapAction::CreateOutputFile(CompilerInstance &CI,
/*ForceUseTemporary=*/true);
}

bool GenerateModuleInterfaceAction::BeginSourceFileAction(
CompilerInstance &CI) {
bool clang::BeginInvocationForModules(CompilerInstance &CI) {
// Embed all module files for named modules.
// See https://github.com/llvm/llvm-project/issues/72383 for discussion.
CI.getFrontendOpts().ModulesEmbedAllFiles = true;
CI.getLangOpts().setCompilingModule(LangOptions::CMK_ModuleInterface);
return true;
}

return GenerateModuleAction::BeginSourceFileAction(CI);
bool GenerateModuleInterfaceAction::BeginInvocation(
CompilerInstance &CI) {
if (!BeginInvocationForModules(CI))
return false;

return GenerateModuleAction::BeginInvocation(CI);
}

std::unique_ptr<ASTConsumer>
Expand Down
147 changes: 147 additions & 0 deletions clang/lib/Headers/wasm_simd128.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ typedef unsigned long long __u64x2
__attribute__((__vector_size__(16), __aligned__(16)));
typedef float __f32x4 __attribute__((__vector_size__(16), __aligned__(16)));
typedef double __f64x2 __attribute__((__vector_size__(16), __aligned__(16)));
typedef __fp16 __f16x8 __attribute__((__vector_size__(16), __aligned__(16)));

typedef signed char __i8x8 __attribute__((__vector_size__(8), __aligned__(8)));
typedef unsigned char __u8x8
Expand Down Expand Up @@ -1878,6 +1879,152 @@ wasm_i32x4_relaxed_dot_i8x16_i7x16_add(v128_t __a, v128_t __b, v128_t __c) {
(__i8x16)__a, (__i8x16)__b, (__i32x4)__c);
}

// FP16 intrinsics
#define __FP16_FN_ATTRS \
__attribute__((__always_inline__, __nodebug__, __target__("fp16"), \
__min_vector_width__(128)))

static __inline__ v128_t __FP16_FN_ATTRS wasm_f16x8_splat(float __a) {
return (v128_t)__builtin_wasm_splat_f16x8(__a);
}

static __inline__ float __FP16_FN_ATTRS wasm_f16x8_extract_lane(v128_t __a,
int __i)
__REQUIRE_CONSTANT(__i) {
return __builtin_wasm_extract_lane_f16x8((__f16x8)__a, __i);
}

static __inline__ v128_t __FP16_FN_ATTRS wasm_f16x8_replace_lane(v128_t __a,
int __i,
float __b)
__REQUIRE_CONSTANT(__i) {
return (v128_t)__builtin_wasm_replace_lane_f16x8((__f16x8)__a, __i, __b);
}

static __inline__ v128_t __FP16_FN_ATTRS wasm_f16x8_abs(v128_t __a) {
return (v128_t)__builtin_wasm_abs_f16x8((__f16x8)__a);
}

static __inline__ v128_t __FP16_FN_ATTRS wasm_f16x8_neg(v128_t __a) {
return (v128_t)(-(__f16x8)__a);
}

static __inline__ v128_t __FP16_FN_ATTRS wasm_f16x8_sqrt(v128_t __a) {
return (v128_t)__builtin_wasm_sqrt_f16x8((__f16x8)__a);
}

static __inline__ v128_t __FP16_FN_ATTRS wasm_f16x8_ceil(v128_t __a) {
return (v128_t)__builtin_wasm_ceil_f16x8((__f16x8)__a);
}

static __inline__ v128_t __FP16_FN_ATTRS wasm_f16x8_floor(v128_t __a) {
return (v128_t)__builtin_wasm_floor_f16x8((__f16x8)__a);
}

static __inline__ v128_t __FP16_FN_ATTRS wasm_f16x8_trunc(v128_t __a) {
return (v128_t)__builtin_wasm_trunc_f16x8((__f16x8)__a);
}

static __inline__ v128_t __FP16_FN_ATTRS wasm_f16x8_nearest(v128_t __a) {
return (v128_t)__builtin_wasm_nearest_f16x8((__f16x8)__a);
}

static __inline__ v128_t __FP16_FN_ATTRS wasm_f16x8_eq(v128_t __a, v128_t __b) {
return (v128_t)((__f16x8)__a == (__f16x8)__b);
}

static __inline__ v128_t __FP16_FN_ATTRS wasm_f16x8_ne(v128_t __a, v128_t __b) {
return (v128_t)((__f16x8)__a != (__f16x8)__b);
}

static __inline__ v128_t __FP16_FN_ATTRS wasm_f16x8_lt(v128_t __a, v128_t __b) {
return (v128_t)((__f16x8)__a < (__f16x8)__b);
}

static __inline__ v128_t __FP16_FN_ATTRS wasm_f16x8_gt(v128_t __a, v128_t __b) {
return (v128_t)((__f16x8)__a > (__f16x8)__b);
}

static __inline__ v128_t __FP16_FN_ATTRS wasm_f16x8_le(v128_t __a, v128_t __b) {
return (v128_t)((__f16x8)__a <= (__f16x8)__b);
}

static __inline__ v128_t __FP16_FN_ATTRS wasm_f16x8_ge(v128_t __a, v128_t __b) {
return (v128_t)((__f16x8)__a >= (__f16x8)__b);
}

static __inline__ v128_t __FP16_FN_ATTRS wasm_f16x8_add(v128_t __a,
v128_t __b) {
return (v128_t)((__f16x8)__a + (__f16x8)__b);
}

static __inline__ v128_t __FP16_FN_ATTRS wasm_f16x8_sub(v128_t __a,
v128_t __b) {
return (v128_t)((__f16x8)__a - (__f16x8)__b);
}

static __inline__ v128_t __FP16_FN_ATTRS wasm_f16x8_mul(v128_t __a,
v128_t __b) {
return (v128_t)((__f16x8)__a * (__f16x8)__b);
}

static __inline__ v128_t __FP16_FN_ATTRS wasm_f16x8_div(v128_t __a,
v128_t __b) {
return (v128_t)((__f16x8)__a / (__f16x8)__b);
}

static __inline__ v128_t __FP16_FN_ATTRS wasm_f16x8_min(v128_t __a,
v128_t __b) {
return (v128_t)__builtin_wasm_min_f16x8((__f16x8)__a, (__f16x8)__b);
}

static __inline__ v128_t __FP16_FN_ATTRS wasm_f16x8_max(v128_t __a,
v128_t __b) {
return (v128_t)__builtin_wasm_max_f16x8((__f16x8)__a, (__f16x8)__b);
}

static __inline__ v128_t __FP16_FN_ATTRS wasm_f16x8_pmin(v128_t __a,
v128_t __b) {
return (v128_t)__builtin_wasm_pmin_f16x8((__f16x8)__a, (__f16x8)__b);
}

static __inline__ v128_t __FP16_FN_ATTRS wasm_f16x8_pmax(v128_t __a,
v128_t __b) {
return (v128_t)__builtin_wasm_pmax_f16x8((__f16x8)__a, (__f16x8)__b);
}

static __inline__ v128_t __FP16_FN_ATTRS
wasm_i16x8_trunc_sat_f16x8(v128_t __a) {
return (v128_t)__builtin_wasm_trunc_saturate_s_i16x8_f16x8((__f16x8)__a);
}

static __inline__ v128_t __FP16_FN_ATTRS
wasm_u16x8_trunc_sat_f16x8(v128_t __a) {
return (v128_t)__builtin_wasm_trunc_saturate_u_i16x8_f16x8((__f16x8)__a);
}

static __inline__ v128_t __FP16_FN_ATTRS wasm_f16x8_convert_i16x8(v128_t __a) {
return (v128_t) __builtin_convertvector((__i16x8)__a, __f16x8);
}

static __inline__ v128_t __FP16_FN_ATTRS wasm_f16x8_convert_u16x8(v128_t __a) {
return (v128_t) __builtin_convertvector((__u16x8)__a, __f16x8);
}

static __inline__ v128_t __FP16_FN_ATTRS wasm_f16x8_relaxed_madd(v128_t __a,
v128_t __b,
v128_t __c) {
return (v128_t)__builtin_wasm_relaxed_madd_f16x8((__f16x8)__a, (__f16x8)__b,
(__f16x8)__c);
}

static __inline__ v128_t __FP16_FN_ATTRS wasm_f16x8_relaxed_nmadd(v128_t __a,
v128_t __b,
v128_t __c) {
return (v128_t)__builtin_wasm_relaxed_nmadd_f16x8((__f16x8)__a, (__f16x8)__b,
(__f16x8)__c);
}

// Deprecated intrinsics

static __inline__ v128_t __DEPRECATED_FN_ATTRS("wasm_i8x16_swizzle")
Expand Down
2 changes: 0 additions & 2 deletions clang/lib/Parse/ParseOpenMP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2954,8 +2954,6 @@ StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
}
break;
}
case OMPD_reverse:
case OMPD_interchange:
case OMPD_declare_target: {
SourceLocation DTLoc = ConsumeAnyToken();
bool HasClauses = Tok.isNot(tok::annot_pragma_openmp_end);
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Sema/MultiplexExternalSemaSource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,7 @@ bool MultiplexExternalSemaSource::MaybeDiagnoseMissingCompleteType(
}

void MultiplexExternalSemaSource::AssignedLambdaNumbering(
const CXXRecordDecl *Lambda) {
CXXRecordDecl *Lambda) {
for (auto *Source : Sources)
Source->AssignedLambdaNumbering(Lambda);
}
5 changes: 3 additions & 2 deletions clang/lib/Sema/SemaARM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -795,7 +795,8 @@ bool SemaARM::CheckNeonBuiltinFunctionCall(const TargetInfo &TI,
if (RHS.isInvalid())
return true;
if (SemaRef.DiagnoseAssignmentResult(ConvTy, Arg->getBeginLoc(), LHSTy,
RHSTy, RHS.get(), Sema::AA_Assigning))
RHSTy, RHS.get(),
AssignmentAction::Assigning))
return true;
}

Expand Down Expand Up @@ -921,7 +922,7 @@ bool SemaARM::CheckARMBuiltinExclusiveCall(unsigned BuiltinID,
CastNeeded = CK_BitCast;
Diag(DRE->getBeginLoc(), diag::ext_typecheck_convert_discards_qualifiers)
<< PointerArg->getType() << Context.getPointerType(AddrType)
<< Sema::AA_Passing << PointerArg->getSourceRange();
<< AssignmentAction::Passing << PointerArg->getSourceRange();
}

// Finally, do the cast and replace the argument with the corrected version.
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/Sema/SemaCast.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2673,7 +2673,7 @@ void CastOperation::checkAddressSpaceCast(QualType SrcType, QualType DestType) {
? DestPPointee.getAddressSpace() != SrcPPointee.getAddressSpace()
: !DestPPointee.isAddressSpaceOverlapping(SrcPPointee)) {
Self.Diag(OpRange.getBegin(), DiagID)
<< SrcType << DestType << Sema::AA_Casting
<< SrcType << DestType << AssignmentAction::Casting
<< SrcExpr.get()->getSourceRange();
if (!Nested)
SrcExpr = ExprError();
Expand Down Expand Up @@ -3213,7 +3213,7 @@ void CastOperation::CheckCStyleCast() {
!CastQuals.compatiblyIncludesObjCLifetime(ExprQuals)) {
Self.Diag(SrcExpr.get()->getBeginLoc(),
diag::err_typecheck_incompatible_ownership)
<< SrcType << DestType << Sema::AA_Casting
<< SrcType << DestType << AssignmentAction::Casting
<< SrcExpr.get()->getSourceRange();
return;
}
Expand Down
3 changes: 2 additions & 1 deletion clang/lib/Sema/SemaChecking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4880,7 +4880,8 @@ bool Sema::BuiltinFPClassification(CallExpr *TheCall, unsigned NumArgs,
if (Arg->isTypeDependent())
return false;

ExprResult Res = PerformImplicitConversion(Arg, Context.IntTy, AA_Passing);
ExprResult Res = PerformImplicitConversion(Arg, Context.IntTy,
AssignmentAction::Passing);

if (Res.isInvalid())
return true;
Expand Down
15 changes: 7 additions & 8 deletions clang/lib/Sema/SemaDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13319,8 +13319,7 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) {
}

// WebAssembly tables can't be used to initialise a variable.
if (Init && !Init->getType().isNull() &&
Init->getType()->isWebAssemblyTableType()) {
if (!Init->getType().isNull() && Init->getType()->isWebAssemblyTableType()) {
Diag(Init->getExprLoc(), diag::err_wasm_table_art) << 0;
VDecl->setInvalidDecl();
return;
Expand Down Expand Up @@ -13463,7 +13462,7 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) {
if (getLangOpts().DebuggerCastResultToId && DclT->isObjCObjectPointerType() &&
Init->getType() == Context.UnknownAnyTy) {
ExprResult Result = forceUnknownAnyToType(Init, Context.getObjCIdType());
if (Result.isInvalid()) {
if (!Result.isUsable()) {
VDecl->setInvalidDecl();
return;
}
Expand Down Expand Up @@ -13491,7 +13490,7 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) {
InitializationSequence Init(*this, Entity, Kind, MultiExprArg(E));
return Init.Failed() ? ExprError() : E;
});
if (Res.isInvalid()) {
if (!Res.isUsable()) {
VDecl->setInvalidDecl();
} else if (Res.get() != Args[Idx]) {
Args[Idx] = Res.get();
Expand All @@ -13504,7 +13503,7 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) {
/*TopLevelOfInitList=*/false,
/*TreatUnavailableAsInvalid=*/false);
ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Args, &DclT);
if (Result.isInvalid()) {
if (!Result.isUsable()) {
// If the provided initializer fails to initialize the var decl,
// we attach a recovery expr for better recovery.
auto RecoveryExpr =
Expand All @@ -13528,8 +13527,8 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) {
InitSeq.step_begin()->Kind ==
InitializationSequence::SK_ParenthesizedListInit;
QualType VDeclType = VDecl->getType();
if (Init && !Init->getType().isNull() &&
!Init->getType()->isDependentType() && !VDeclType->isDependentType() &&
if (!Init->getType().isNull() && !Init->getType()->isDependentType() &&
!VDeclType->isDependentType() &&
Context.getAsIncompleteArrayType(VDeclType) &&
Context.getAsIncompleteArrayType(Init->getType())) {
// Bail out if it is not possible to deduce array size from the
Expand Down Expand Up @@ -13592,7 +13591,7 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) {
ExprResult Result =
ActOnFinishFullExpr(Init, VDecl->getLocation(),
/*DiscardedValue*/ false, VDecl->isConstexpr());
if (Result.isInvalid()) {
if (!Result.isUsable()) {
VDecl->setInvalidDecl();
return;
}
Expand Down
3 changes: 2 additions & 1 deletion clang/lib/Sema/SemaDeclCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10871,7 +10871,8 @@ bool Sema::CheckDestructor(CXXDestructorDecl *Destructor) {
ExprResult This =
ActOnCXXThis(OperatorDelete->getParamDecl(0)->getLocation());
assert(!This.isInvalid() && "couldn't form 'this' expr in dtor?");
This = PerformImplicitConversion(This.get(), ParamType, AA_Passing);
This = PerformImplicitConversion(This.get(), ParamType,
AssignmentAction::Passing);
if (This.isInvalid()) {
// FIXME: Register this as a context note so that it comes out
// in the right order.
Expand Down
39 changes: 23 additions & 16 deletions clang/lib/Sema/SemaExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4467,6 +4467,7 @@ static void captureVariablyModifiedType(ASTContext &Context, QualType T,
case Type::UnaryTransform:
case Type::Attributed:
case Type::BTFTagAttributed:
case Type::HLSLAttributedResource:
case Type::SubstTemplateTypeParm:
case Type::MacroQualified:
case Type::CountAttributed:
Expand Down Expand Up @@ -9586,7 +9587,7 @@ Sema::CheckSingleAssignmentConstraints(QualType LHSType, ExprResult &CallerRHS,
QualType RHSType = RHS.get()->getType();
if (Diagnose) {
RHS = PerformImplicitConversion(RHS.get(), LHSType.getUnqualifiedType(),
AA_Assigning);
AssignmentAction::Assigning);
} else {
ImplicitConversionSequence ICS =
TryImplicitConversion(RHS.get(), LHSType.getUnqualifiedType(),
Expand All @@ -9598,7 +9599,7 @@ Sema::CheckSingleAssignmentConstraints(QualType LHSType, ExprResult &CallerRHS,
if (ICS.isFailure())
return Incompatible;
RHS = PerformImplicitConversion(RHS.get(), LHSType.getUnqualifiedType(),
ICS, AA_Assigning);
ICS, AssignmentAction::Assigning);
}
if (RHS.isInvalid())
return Incompatible;
Expand Down Expand Up @@ -9888,6 +9889,9 @@ static ExprResult convertVector(Expr *E, QualType ElementType, Sema &S) {
/// IntTy without losing precision.
static bool canConvertIntToOtherIntTy(Sema &S, ExprResult *Int,
QualType OtherIntTy) {
if (Int->get()->containsErrors())
return false;

QualType IntTy = Int->get()->getType().getUnqualifiedType();

// Reject cases where the value of the Int is unknown as that would
Expand Down Expand Up @@ -9926,6 +9930,9 @@ static bool canConvertIntToOtherIntTy(Sema &S, ExprResult *Int,
/// FloatTy without losing precision.
static bool canConvertIntTyToFloatTy(Sema &S, ExprResult *Int,
QualType FloatTy) {
if (Int->get()->containsErrors())
return false;

QualType IntTy = Int->get()->getType().getUnqualifiedType();

// Determine if the integer constant can be expressed as a floating point
Expand Down Expand Up @@ -13654,8 +13661,8 @@ QualType Sema::CheckAssignmentOperands(Expr *LHSExpr, ExprResult &RHS,
ConvTy = CheckAssignmentConstraints(Loc, LHSType, RHSType);
}

if (DiagnoseAssignmentResult(ConvTy, Loc, LHSType, RHSType,
RHS.get(), AA_Assigning))
if (DiagnoseAssignmentResult(ConvTy, Loc, LHSType, RHSType, RHS.get(),
AssignmentAction::Assigning))
return QualType();

CheckForNullPointerDereference(*this, LHSExpr);
Expand Down Expand Up @@ -16663,7 +16670,7 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy,
MayHaveConvFixit = true;
break;
case IncompatiblePointer:
if (Action == AA_Passing_CFAudited) {
if (Action == AssignmentAction::Passing_CFAudited) {
DiagKind = diag::err_arc_typecheck_convert_incompatible_pointer;
} else if (getLangOpts().CPlusPlus) {
DiagKind = diag::err_typecheck_convert_incompatible_pointer;
Expand Down Expand Up @@ -16817,19 +16824,19 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy,

QualType FirstType, SecondType;
switch (Action) {
case AA_Assigning:
case AA_Initializing:
case AssignmentAction::Assigning:
case AssignmentAction::Initializing:
// The destination type comes first.
FirstType = DstType;
SecondType = SrcType;
break;

case AA_Returning:
case AA_Passing:
case AA_Passing_CFAudited:
case AA_Converting:
case AA_Sending:
case AA_Casting:
case AssignmentAction::Returning:
case AssignmentAction::Passing:
case AssignmentAction::Passing_CFAudited:
case AssignmentAction::Converting:
case AssignmentAction::Sending:
case AssignmentAction::Casting:
// The source type comes first.
FirstType = SrcType;
SecondType = DstType;
Expand All @@ -16838,8 +16845,8 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy,

PartialDiagnostic FDiag = PDiag(DiagKind);
AssignmentAction ActionForDiag = Action;
if (Action == AA_Passing_CFAudited)
ActionForDiag = AA_Passing;
if (Action == AssignmentAction::Passing_CFAudited)
ActionForDiag = AssignmentAction::Passing;

FDiag << FirstType << SecondType << ActionForDiag
<< SrcExpr->getSourceRange();
Expand Down Expand Up @@ -16879,7 +16886,7 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy,
if (CheckInferredResultType)
ObjC().EmitRelatedResultTypeNote(SrcExpr);

if (Action == AA_Returning && ConvTy == IncompatiblePointer)
if (Action == AssignmentAction::Returning && ConvTy == IncompatiblePointer)
ObjC().EmitRelatedResultTypeNoteForReturn(DstType);

if (Complained)
Expand Down
47 changes: 24 additions & 23 deletions clang/lib/Sema/SemaExprCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2199,8 +2199,8 @@ ExprResult Sema::BuildCXXNew(SourceRange Range, bool UseGlobal,
if (getLangOpts().CPlusPlus14) {
assert(Context.getTargetInfo().getIntWidth() && "Builtin type of size 0?");

ConvertedSize = PerformImplicitConversion(*ArraySize, Context.getSizeType(),
AA_Converting);
ConvertedSize = PerformImplicitConversion(
*ArraySize, Context.getSizeType(), AssignmentAction::Converting);

if (!ConvertedSize.isInvalid() &&
(*ArraySize)->getType()->getAs<RecordType>())
Expand Down Expand Up @@ -3851,7 +3851,8 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal,
Context.getQualifiedType(Pointee.getUnqualifiedType(), Qs));
Ex = ImpCastExprToType(Ex.get(), Unqual, CK_NoOp);
}
Ex = PerformImplicitConversion(Ex.get(), ParamType, AA_Passing);
Ex = PerformImplicitConversion(Ex.get(), ParamType,
AssignmentAction::Passing);
if (Ex.isInvalid())
return ExprError();
}
Expand Down Expand Up @@ -4256,10 +4257,9 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType,
}
// Watch out for ellipsis conversion.
if (!ICS.UserDefined.EllipsisConversion) {
ExprResult Res =
PerformImplicitConversion(From, BeforeToType,
ICS.UserDefined.Before, AA_Converting,
CCK);
ExprResult Res = PerformImplicitConversion(
From, BeforeToType, ICS.UserDefined.Before,
AssignmentAction::Converting, CCK);
if (Res.isInvalid())
return ExprError();
From = Res.get();
Expand All @@ -4282,7 +4282,7 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType,
return From;

return PerformImplicitConversion(From, ToType, ICS.UserDefined.After,
AA_Converting, CCK);
AssignmentAction::Converting, CCK);
}

case ImplicitConversionSequence::AmbiguousConversion:
Expand Down Expand Up @@ -4451,19 +4451,19 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType,
// target entity shall allow at least the exceptions allowed by the
// source value in the assignment or initialization.
switch (Action) {
case AA_Assigning:
case AA_Initializing:
case AssignmentAction::Assigning:
case AssignmentAction::Initializing:
// Note, function argument passing and returning are initialization.
case AA_Passing:
case AA_Returning:
case AA_Sending:
case AA_Passing_CFAudited:
case AssignmentAction::Passing:
case AssignmentAction::Returning:
case AssignmentAction::Sending:
case AssignmentAction::Passing_CFAudited:
if (CheckExceptionSpecCompatibility(From, ToType))
return ExprError();
break;

case AA_Casting:
case AA_Converting:
case AssignmentAction::Casting:
case AssignmentAction::Converting:
// Casts and implicit conversions are not initialization, so are not
// checked for exception specification mismatches.
break;
Expand Down Expand Up @@ -4577,9 +4577,10 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType,

case ICK_Writeback_Conversion:
case ICK_Pointer_Conversion: {
if (SCS.IncompatibleObjC && Action != AA_Casting) {
if (SCS.IncompatibleObjC && Action != AssignmentAction::Casting) {
// Diagnose incompatible Objective-C conversions
if (Action == AA_Initializing || Action == AA_Assigning)
if (Action == AssignmentAction::Initializing ||
Action == AssignmentAction::Assigning)
Diag(From->getBeginLoc(),
diag::ext_typecheck_convert_incompatible_pointer)
<< ToType << From->getType() << Action << From->getSourceRange()
Expand All @@ -4596,12 +4597,12 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType,
} else if (getLangOpts().allowsNonTrivialObjCLifetimeQualifiers() &&
!ObjC().CheckObjCARCUnavailableWeakConversion(ToType,
From->getType())) {
if (Action == AA_Initializing)
if (Action == AssignmentAction::Initializing)
Diag(From->getBeginLoc(), diag::err_arc_weak_unavailable_assign);
else
Diag(From->getBeginLoc(), diag::err_arc_convesion_of_weak_unavailable)
<< (Action == AA_Casting) << From->getType() << ToType
<< From->getSourceRange();
<< (Action == AssignmentAction::Casting) << From->getType()
<< ToType << From->getSourceRange();
}

// Defer address space conversion to the third conversion.
Expand Down Expand Up @@ -6666,14 +6667,14 @@ static bool FindConditionalOverload(Sema &Self, ExprResult &LHS, ExprResult &RHS
// We found a match. Perform the conversions on the arguments and move on.
ExprResult LHSRes = Self.PerformImplicitConversion(
LHS.get(), Best->BuiltinParamTypes[0], Best->Conversions[0],
Sema::AA_Converting);
AssignmentAction::Converting);
if (LHSRes.isInvalid())
break;
LHS = LHSRes;

ExprResult RHSRes = Self.PerformImplicitConversion(
RHS.get(), Best->BuiltinParamTypes[1], Best->Conversions[1],
Sema::AA_Converting);
AssignmentAction::Converting);
if (RHSRes.isInvalid())
break;
RHS = RHSRes;
Expand Down
22 changes: 22 additions & 0 deletions clang/lib/Sema/SemaHLSL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/Basic/DiagnosticSema.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Sema/ParsedAttr.h"
#include "clang/Sema/Sema.h"
Expand Down Expand Up @@ -467,6 +468,27 @@ void SemaHLSL::handleResourceClassAttr(Decl *D, const ParsedAttr &AL) {
D->addAttr(HLSLResourceClassAttr::Create(getASTContext(), RC, ArgLoc));
}

// Validates HLSL resource type attribute and adds it to the list to be
// processed into a single HLSLAttributedResourceType later on.
// Returns false if the attribute is invalid.
bool SemaHLSL::handleResourceTypeAttr(const ParsedAttr &AL) {
// FIXME: placeholder - not yet implemented
return true;
}

// Combines all resource type attributes and create HLSLAttributedResourceType.
QualType SemaHLSL::ProcessResourceTypeAttributes(QualType CurrentType) {
// FIXME: placeholder - not yet implemented
return CurrentType;
}

// Returns source location for the HLSLAttributedResourceType
SourceLocation
SemaHLSL::TakeLocForHLSLAttribute(const HLSLAttributedResourceType *RT) {
// FIXME: placeholder - not yet implemented
return SourceLocation();
}

struct RegisterBindingFlags {
bool Resource = false;
bool UDT = false;
Expand Down
23 changes: 12 additions & 11 deletions clang/lib/Sema/SemaInit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6799,43 +6799,44 @@ InitializationSequence::~InitializationSequence() {
//===----------------------------------------------------------------------===//
// Perform initialization
//===----------------------------------------------------------------------===//
static Sema::AssignmentAction
getAssignmentAction(const InitializedEntity &Entity, bool Diagnose = false) {
static AssignmentAction getAssignmentAction(const InitializedEntity &Entity,
bool Diagnose = false) {
switch(Entity.getKind()) {
case InitializedEntity::EK_Variable:
case InitializedEntity::EK_New:
case InitializedEntity::EK_Exception:
case InitializedEntity::EK_Base:
case InitializedEntity::EK_Delegating:
return Sema::AA_Initializing;
return AssignmentAction::Initializing;

case InitializedEntity::EK_Parameter:
if (Entity.getDecl() &&
isa<ObjCMethodDecl>(Entity.getDecl()->getDeclContext()))
return Sema::AA_Sending;
return AssignmentAction::Sending;

return Sema::AA_Passing;
return AssignmentAction::Passing;

case InitializedEntity::EK_Parameter_CF_Audited:
if (Entity.getDecl() &&
isa<ObjCMethodDecl>(Entity.getDecl()->getDeclContext()))
return Sema::AA_Sending;
return AssignmentAction::Sending;

return !Diagnose ? Sema::AA_Passing : Sema::AA_Passing_CFAudited;
return !Diagnose ? AssignmentAction::Passing
: AssignmentAction::Passing_CFAudited;

case InitializedEntity::EK_Result:
case InitializedEntity::EK_StmtExprResult: // FIXME: Not quite right.
return Sema::AA_Returning;
return AssignmentAction::Returning;

case InitializedEntity::EK_Temporary:
case InitializedEntity::EK_RelatedResult:
// FIXME: Can we tell apart casting vs. converting?
return Sema::AA_Casting;
return AssignmentAction::Casting;

case InitializedEntity::EK_TemplateParameter:
// This is really initialization, but refer to it as conversion for
// consistency with CheckConvertedConstantExpression.
return Sema::AA_Converting;
return AssignmentAction::Converting;

case InitializedEntity::EK_Member:
case InitializedEntity::EK_ParenAggInitMember:
Expand All @@ -6847,7 +6848,7 @@ getAssignmentAction(const InitializedEntity &Entity, bool Diagnose = false) {
case InitializedEntity::EK_LambdaToBlockConversionBlockElement:
case InitializedEntity::EK_LambdaCapture:
case InitializedEntity::EK_CompoundLiteralInit:
return Sema::AA_Initializing;
return AssignmentAction::Initializing;
}

llvm_unreachable("Invalid EntityKind!");
Expand Down
Loading