mirror of
https://github.com/freebsd/freebsd-src.git
synced 2024-11-27 09:12:44 +00:00
Merge llvm-project main llvmorg-18-init-18359-g93248729cfae
This updates llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and
openmp to llvm-project main llvmorg-18-init-18359-g93248729cfae, the
last commit before the upstream release/18.x branch was created.
PR: 276104
MFC after: 1 month
(cherry picked from commit 7a6dacaca1
)
This commit is contained in:
parent
412542983a
commit
ab50317e96
@ -4,6 +4,7 @@
|
||||
.clang-format
|
||||
.clang-tidy
|
||||
.git-blame-ignore-revs
|
||||
.gitattributes
|
||||
.github/
|
||||
.gitignore
|
||||
.mailmap
|
||||
@ -266,7 +267,6 @@ libcxx/include/__config_site.in
|
||||
libcxx/include/__support/
|
||||
libcxx/lib/
|
||||
libcxx/modules/CMakeLists.txt
|
||||
libcxx/modules/CMakeLists.txt.in
|
||||
libcxx/modules/README.md
|
||||
libcxx/src/CMakeLists.txt
|
||||
libcxx/src/support/win32/
|
||||
@ -549,7 +549,8 @@ llvm/lib/CodeGen/MIRParser/CMakeLists.txt
|
||||
llvm/lib/CodeGen/README.txt
|
||||
llvm/lib/CodeGen/SelectionDAG/CMakeLists.txt
|
||||
llvm/lib/DWARFLinker/CMakeLists.txt
|
||||
llvm/lib/DWARFLinkerParallel/CMakeLists.txt
|
||||
llvm/lib/DWARFLinker/Classic/CMakeLists.txt
|
||||
llvm/lib/DWARFLinker/Parallel/CMakeLists.txt
|
||||
llvm/lib/DWP/CMakeLists.txt
|
||||
llvm/lib/DebugInfo/BTF/CMakeLists.txt
|
||||
llvm/lib/DebugInfo/CMakeLists.txt
|
||||
@ -751,6 +752,7 @@ llvm/lib/TargetParser/CMakeLists.txt
|
||||
llvm/lib/Testing/Annotations/CMakeLists.txt
|
||||
llvm/lib/Testing/CMakeLists.txt
|
||||
llvm/lib/Testing/Support/CMakeLists.txt
|
||||
llvm/lib/TextAPI/BinaryReader/CMakeLists.txt
|
||||
llvm/lib/TextAPI/CMakeLists.txt
|
||||
llvm/lib/ToolDrivers/CMakeLists.txt
|
||||
llvm/lib/ToolDrivers/llvm-dlltool/CMakeLists.txt
|
||||
@ -936,6 +938,7 @@ llvm/utils/llvm-native-gxx
|
||||
llvm/utils/llvm-original-di-preservation.py
|
||||
llvm/utils/llvm.grm
|
||||
llvm/utils/merge-stats.py
|
||||
llvm/utils/mlgo-utils/
|
||||
llvm/utils/not/
|
||||
llvm/utils/pipeline.py
|
||||
llvm/utils/prepare-code-coverage-artifact.py
|
||||
|
@ -0,0 +1,71 @@
|
||||
//===--- APNumericStorage.h - Store APInt/APFloat in ASTContext -*- C++ -*-===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_AST_APNUMERICSTORAGE_H
|
||||
#define LLVM_CLANG_AST_APNUMERICSTORAGE_H
|
||||
|
||||
#include "llvm/ADT/APFloat.h"
|
||||
#include "llvm/ADT/APInt.h"
|
||||
|
||||
namespace clang {
|
||||
class ASTContext;
|
||||
|
||||
/// Used by IntegerLiteral/FloatingLiteral/EnumConstantDecl to store the
|
||||
/// numeric without leaking memory.
|
||||
///
|
||||
/// For large floats/integers, APFloat/APInt will allocate memory from the heap
|
||||
/// to represent these numbers. Unfortunately, when we use a BumpPtrAllocator
|
||||
/// to allocate IntegerLiteral/FloatingLiteral nodes the memory associated with
|
||||
/// the APFloat/APInt values will never get freed. APNumericStorage uses
|
||||
/// ASTContext's allocator for memory allocation.
|
||||
class APNumericStorage {
|
||||
union {
|
||||
uint64_t VAL; ///< Used to store the <= 64 bits integer value.
|
||||
uint64_t *pVal; ///< Used to store the >64 bits integer value.
|
||||
};
|
||||
unsigned BitWidth;
|
||||
|
||||
bool hasAllocation() const { return llvm::APInt::getNumWords(BitWidth) > 1; }
|
||||
|
||||
APNumericStorage(const APNumericStorage &) = delete;
|
||||
void operator=(const APNumericStorage &) = delete;
|
||||
|
||||
protected:
|
||||
APNumericStorage() : VAL(0), BitWidth(0) {}
|
||||
|
||||
llvm::APInt getIntValue() const {
|
||||
unsigned NumWords = llvm::APInt::getNumWords(BitWidth);
|
||||
if (NumWords > 1)
|
||||
return llvm::APInt(BitWidth, NumWords, pVal);
|
||||
else
|
||||
return llvm::APInt(BitWidth, VAL);
|
||||
}
|
||||
void setIntValue(const ASTContext &C, const llvm::APInt &Val);
|
||||
};
|
||||
|
||||
class APIntStorage : private APNumericStorage {
|
||||
public:
|
||||
llvm::APInt getValue() const { return getIntValue(); }
|
||||
void setValue(const ASTContext &C, const llvm::APInt &Val) {
|
||||
setIntValue(C, Val);
|
||||
}
|
||||
};
|
||||
|
||||
class APFloatStorage : private APNumericStorage {
|
||||
public:
|
||||
llvm::APFloat getValue(const llvm::fltSemantics &Semantics) const {
|
||||
return llvm::APFloat(Semantics, getIntValue());
|
||||
}
|
||||
void setValue(const ASTContext &C, const llvm::APFloat &Val) {
|
||||
setIntValue(C, Val.bitcastToAPInt());
|
||||
}
|
||||
};
|
||||
|
||||
} // end namespace clang
|
||||
|
||||
#endif // LLVM_CLANG_AST_APNUMERICSTORAGE_H
|
@ -13,6 +13,7 @@
|
||||
#ifndef LLVM_CLANG_AST_DECL_H
|
||||
#define LLVM_CLANG_AST_DECL_H
|
||||
|
||||
#include "clang/AST/APNumericStorage.h"
|
||||
#include "clang/AST/APValue.h"
|
||||
#include "clang/AST/ASTContextAllocate.h"
|
||||
#include "clang/AST/DeclAccessPair.h"
|
||||
@ -2293,8 +2294,8 @@ public:
|
||||
|
||||
/// Whether this virtual function is pure, i.e. makes the containing class
|
||||
/// abstract.
|
||||
bool isPure() const { return FunctionDeclBits.IsPure; }
|
||||
void setPure(bool P = true);
|
||||
bool isPureVirtual() const { return FunctionDeclBits.IsPureVirtual; }
|
||||
void setIsPureVirtual(bool P = true);
|
||||
|
||||
/// Whether this templated function will be late parsed.
|
||||
bool isLateTemplateParsed() const {
|
||||
@ -3251,15 +3252,16 @@ public:
|
||||
/// that is defined. For example, in "enum X {a,b}", each of a/b are
|
||||
/// EnumConstantDecl's, X is an instance of EnumDecl, and the type of a/b is a
|
||||
/// TagType for the X EnumDecl.
|
||||
class EnumConstantDecl : public ValueDecl, public Mergeable<EnumConstantDecl> {
|
||||
class EnumConstantDecl : public ValueDecl,
|
||||
public Mergeable<EnumConstantDecl>,
|
||||
public APIntStorage {
|
||||
Stmt *Init; // an integer constant expression
|
||||
llvm::APSInt Val; // The value.
|
||||
bool IsUnsigned;
|
||||
|
||||
protected:
|
||||
EnumConstantDecl(DeclContext *DC, SourceLocation L,
|
||||
EnumConstantDecl(const ASTContext &C, DeclContext *DC, SourceLocation L,
|
||||
IdentifierInfo *Id, QualType T, Expr *E,
|
||||
const llvm::APSInt &V)
|
||||
: ValueDecl(EnumConstant, DC, L, Id, T), Init((Stmt*)E), Val(V) {}
|
||||
const llvm::APSInt &V);
|
||||
|
||||
public:
|
||||
friend class StmtIteratorBase;
|
||||
@ -3272,10 +3274,15 @@ public:
|
||||
|
||||
const Expr *getInitExpr() const { return (const Expr*) Init; }
|
||||
Expr *getInitExpr() { return (Expr*) Init; }
|
||||
const llvm::APSInt &getInitVal() const { return Val; }
|
||||
llvm::APSInt getInitVal() const {
|
||||
return llvm::APSInt(getValue(), IsUnsigned);
|
||||
}
|
||||
|
||||
void setInitExpr(Expr *E) { Init = (Stmt*) E; }
|
||||
void setInitVal(const llvm::APSInt &V) { Val = V; }
|
||||
void setInitVal(const ASTContext &C, const llvm::APSInt &V) {
|
||||
setValue(C, V);
|
||||
IsUnsigned = V.isUnsigned();
|
||||
}
|
||||
|
||||
SourceRange getSourceRange() const override LLVM_READONLY;
|
||||
|
||||
|
@ -548,17 +548,18 @@ public:
|
||||
return hasAttrs() ? getAttrs().end() : nullptr;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void dropAttr() {
|
||||
template <typename... Ts> void dropAttrs() {
|
||||
if (!HasAttrs) return;
|
||||
|
||||
AttrVec &Vec = getAttrs();
|
||||
llvm::erase_if(Vec, [](Attr *A) { return isa<T>(A); });
|
||||
llvm::erase_if(Vec, [](Attr *A) { return isa<Ts...>(A); });
|
||||
|
||||
if (Vec.empty())
|
||||
HasAttrs = false;
|
||||
}
|
||||
|
||||
template <typename T> void dropAttr() { dropAttrs<T>(); }
|
||||
|
||||
template <typename T>
|
||||
llvm::iterator_range<specific_attr_iterator<T>> specific_attrs() const {
|
||||
return llvm::make_range(specific_attr_begin<T>(), specific_attr_end<T>());
|
||||
@ -1707,7 +1708,7 @@ class DeclContext {
|
||||
LLVM_PREFERRED_TYPE(bool)
|
||||
uint64_t IsVirtualAsWritten : 1;
|
||||
LLVM_PREFERRED_TYPE(bool)
|
||||
uint64_t IsPure : 1;
|
||||
uint64_t IsPureVirtual : 1;
|
||||
LLVM_PREFERRED_TYPE(bool)
|
||||
uint64_t HasInheritedPrototype : 1;
|
||||
LLVM_PREFERRED_TYPE(bool)
|
||||
|
@ -266,7 +266,7 @@ class CXXRecordDecl : public RecordDecl {
|
||||
friend class LambdaExpr;
|
||||
friend class ODRDiagsEmitter;
|
||||
|
||||
friend void FunctionDecl::setPure(bool);
|
||||
friend void FunctionDecl::setIsPureVirtual(bool);
|
||||
friend void TagDecl::startDefinition();
|
||||
|
||||
/// Values used in DefinitionData fields to represent special members.
|
||||
@ -1439,31 +1439,20 @@ public:
|
||||
|
||||
/// Determine whether this class is a literal type.
|
||||
///
|
||||
/// C++11 [basic.types]p10:
|
||||
/// C++20 [basic.types]p10:
|
||||
/// A class type that has all the following properties:
|
||||
/// - it has a trivial destructor
|
||||
/// - every constructor call and full-expression in the
|
||||
/// brace-or-equal-intializers for non-static data members (if any) is
|
||||
/// a constant expression.
|
||||
/// - it is an aggregate type or has at least one constexpr constructor
|
||||
/// or constructor template that is not a copy or move constructor, and
|
||||
/// - all of its non-static data members and base classes are of literal
|
||||
/// types
|
||||
///
|
||||
/// We resolve DR1361 by ignoring the second bullet. We resolve DR1452 by
|
||||
/// treating types with trivial default constructors as literal types.
|
||||
///
|
||||
/// Only in C++17 and beyond, are lambdas literal types.
|
||||
bool isLiteral() const {
|
||||
const LangOptions &LangOpts = getLangOpts();
|
||||
return (LangOpts.CPlusPlus20 ? hasConstexprDestructor()
|
||||
: hasTrivialDestructor()) &&
|
||||
(!isLambda() || LangOpts.CPlusPlus17) &&
|
||||
!hasNonLiteralTypeFieldsOrBases() &&
|
||||
(isAggregate() || isLambda() ||
|
||||
hasConstexprNonCopyMoveConstructor() ||
|
||||
hasTrivialDefaultConstructor());
|
||||
}
|
||||
/// - it has a constexpr destructor
|
||||
/// - all of its non-static non-variant data members and base classes
|
||||
/// are of non-volatile literal types, and it:
|
||||
/// - is a closure type
|
||||
/// - is an aggregate union type that has either no variant members
|
||||
/// or at least one variant member of non-volatile literal type
|
||||
/// - is a non-union aggregate type for which each of its anonymous
|
||||
/// union members satisfies the above requirements for an aggregate
|
||||
/// union type, or
|
||||
/// - has at least one constexpr constructor or constructor template
|
||||
/// that is not a copy or move constructor.
|
||||
bool isLiteral() const;
|
||||
|
||||
/// Determine whether this is a structural type.
|
||||
bool isStructural() const {
|
||||
@ -2121,7 +2110,7 @@ public:
|
||||
|
||||
// Member function is virtual if it is marked explicitly so, or if it is
|
||||
// declared in __interface -- then it is automatically pure virtual.
|
||||
if (CD->isVirtualAsWritten() || CD->isPure())
|
||||
if (CD->isVirtualAsWritten() || CD->isPureVirtual())
|
||||
return true;
|
||||
|
||||
return CD->size_overridden_methods() != 0;
|
||||
|
@ -13,6 +13,7 @@
|
||||
#ifndef LLVM_CLANG_AST_EXPR_H
|
||||
#define LLVM_CLANG_AST_EXPR_H
|
||||
|
||||
#include "clang/AST/APNumericStorage.h"
|
||||
#include "clang/AST/APValue.h"
|
||||
#include "clang/AST/ASTVector.h"
|
||||
#include "clang/AST/ComputeDependence.h"
|
||||
@ -1135,7 +1136,6 @@ public:
|
||||
return ConstantExprBits.APValueKind != APValue::None;
|
||||
}
|
||||
APValue getAPValueResult() const;
|
||||
APValue &getResultAsAPValue() const { return APValueResult(); }
|
||||
llvm::APSInt getResultAsAPSInt() const;
|
||||
// Iterators
|
||||
child_range children() { return child_range(&SubExpr, &SubExpr+1); }
|
||||
@ -1479,57 +1479,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
/// Used by IntegerLiteral/FloatingLiteral to store the numeric without
|
||||
/// leaking memory.
|
||||
///
|
||||
/// For large floats/integers, APFloat/APInt will allocate memory from the heap
|
||||
/// to represent these numbers. Unfortunately, when we use a BumpPtrAllocator
|
||||
/// to allocate IntegerLiteral/FloatingLiteral nodes the memory associated with
|
||||
/// the APFloat/APInt values will never get freed. APNumericStorage uses
|
||||
/// ASTContext's allocator for memory allocation.
|
||||
class APNumericStorage {
|
||||
union {
|
||||
uint64_t VAL; ///< Used to store the <= 64 bits integer value.
|
||||
uint64_t *pVal; ///< Used to store the >64 bits integer value.
|
||||
};
|
||||
unsigned BitWidth;
|
||||
|
||||
bool hasAllocation() const { return llvm::APInt::getNumWords(BitWidth) > 1; }
|
||||
|
||||
APNumericStorage(const APNumericStorage &) = delete;
|
||||
void operator=(const APNumericStorage &) = delete;
|
||||
|
||||
protected:
|
||||
APNumericStorage() : VAL(0), BitWidth(0) { }
|
||||
|
||||
llvm::APInt getIntValue() const {
|
||||
unsigned NumWords = llvm::APInt::getNumWords(BitWidth);
|
||||
if (NumWords > 1)
|
||||
return llvm::APInt(BitWidth, NumWords, pVal);
|
||||
else
|
||||
return llvm::APInt(BitWidth, VAL);
|
||||
}
|
||||
void setIntValue(const ASTContext &C, const llvm::APInt &Val);
|
||||
};
|
||||
|
||||
class APIntStorage : private APNumericStorage {
|
||||
public:
|
||||
llvm::APInt getValue() const { return getIntValue(); }
|
||||
void setValue(const ASTContext &C, const llvm::APInt &Val) {
|
||||
setIntValue(C, Val);
|
||||
}
|
||||
};
|
||||
|
||||
class APFloatStorage : private APNumericStorage {
|
||||
public:
|
||||
llvm::APFloat getValue(const llvm::fltSemantics &Semantics) const {
|
||||
return llvm::APFloat(Semantics, getIntValue());
|
||||
}
|
||||
void setValue(const ASTContext &C, const llvm::APFloat &Val) {
|
||||
setIntValue(C, Val.bitcastToAPInt());
|
||||
}
|
||||
};
|
||||
|
||||
class IntegerLiteral : public Expr, public APIntStorage {
|
||||
SourceLocation Loc;
|
||||
|
||||
@ -4806,6 +4755,17 @@ public:
|
||||
return T->getStmtClass() == SourceLocExprClass;
|
||||
}
|
||||
|
||||
static bool MayBeDependent(SourceLocIdentKind Kind) {
|
||||
switch (Kind) {
|
||||
case SourceLocIdentKind::Function:
|
||||
case SourceLocIdentKind::FuncSig:
|
||||
case SourceLocIdentKind::SourceLocStruct:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
friend class ASTStmtReader;
|
||||
};
|
||||
|
@ -2210,14 +2210,11 @@ enum class CXXNewInitializationStyle {
|
||||
/// New-expression has no initializer as written.
|
||||
None,
|
||||
|
||||
/// New-expression has no written initializer, but has an implicit one.
|
||||
Implicit,
|
||||
|
||||
/// New-expression has a C++98 paren-delimited initializer.
|
||||
Call,
|
||||
Parens,
|
||||
|
||||
/// New-expression has a C++11 list-initializer.
|
||||
List
|
||||
Braces
|
||||
};
|
||||
|
||||
/// Represents a new-expression for memory allocation and constructor
|
||||
@ -2388,17 +2385,7 @@ public:
|
||||
bool isGlobalNew() const { return CXXNewExprBits.IsGlobalNew; }
|
||||
|
||||
/// Whether this new-expression has any initializer at all.
|
||||
bool hasInitializer() const {
|
||||
switch (getInitializationStyle()) {
|
||||
case CXXNewInitializationStyle::None:
|
||||
return false;
|
||||
case CXXNewInitializationStyle::Implicit:
|
||||
case CXXNewInitializationStyle::Call:
|
||||
case CXXNewInitializationStyle::List:
|
||||
return true;
|
||||
}
|
||||
llvm_unreachable("Unknown initializer");
|
||||
}
|
||||
bool hasInitializer() const { return CXXNewExprBits.HasInitializer; }
|
||||
|
||||
/// The kind of initializer this new-expression has.
|
||||
CXXNewInitializationStyle getInitializationStyle() const {
|
||||
|
@ -25,6 +25,7 @@
|
||||
|
||||
namespace clang {
|
||||
|
||||
class APValue;
|
||||
class Decl;
|
||||
class IdentifierInfo;
|
||||
class NestedNameSpecifier;
|
||||
@ -101,6 +102,8 @@ public:
|
||||
// Save booleans until the end to lower the size of data to process.
|
||||
void AddBoolean(bool value);
|
||||
|
||||
void AddStructuralValue(const APValue &);
|
||||
|
||||
static bool isSubDeclToBeProcessed(const Decl *D, const DeclContext *Parent);
|
||||
|
||||
private:
|
||||
|
@ -808,6 +808,20 @@ let Class = PropertyTypeCase<TemplateArgument, "Integral"> in {
|
||||
return TemplateArgument(ctx, value, type, isDefaulted);
|
||||
}]>;
|
||||
}
|
||||
let Class = PropertyTypeCase<TemplateArgument, "StructuralValue"> in {
|
||||
def : Property<"value", APValue> {
|
||||
let Read = [{ node.getAsStructuralValue() }];
|
||||
}
|
||||
def : Property<"type", QualType> {
|
||||
let Read = [{ node.getStructuralValueType() }];
|
||||
}
|
||||
def : Property<"isDefaulted", Bool> {
|
||||
let Read = [{ node.getIsDefaulted() }];
|
||||
}
|
||||
def : Creator<[{
|
||||
return TemplateArgument(ctx, type, value, isDefaulted);
|
||||
}]>;
|
||||
}
|
||||
let Class = PropertyTypeCase<TemplateArgument, "Template"> in {
|
||||
def : Property<"name", TemplateName> {
|
||||
let Read = [{ node.getAsTemplateOrTemplatePattern() }];
|
||||
|
@ -850,6 +850,7 @@ bool RecursiveASTVisitor<Derived>::TraverseTemplateArgument(
|
||||
case TemplateArgument::Declaration:
|
||||
case TemplateArgument::Integral:
|
||||
case TemplateArgument::NullPtr:
|
||||
case TemplateArgument::StructuralValue:
|
||||
return true;
|
||||
|
||||
case TemplateArgument::Type:
|
||||
@ -882,6 +883,7 @@ bool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLoc(
|
||||
case TemplateArgument::Declaration:
|
||||
case TemplateArgument::Integral:
|
||||
case TemplateArgument::NullPtr:
|
||||
case TemplateArgument::StructuralValue:
|
||||
return true;
|
||||
|
||||
case TemplateArgument::Type: {
|
||||
|
@ -868,9 +868,11 @@ protected:
|
||||
LLVM_PREFERRED_TYPE(bool)
|
||||
unsigned UsualArrayDeleteWantsSize : 1;
|
||||
|
||||
/// What kind of initializer do we have? Could be none, parens, or braces.
|
||||
/// In storage, we distinguish between "none, and no initializer expr", and
|
||||
/// "none, but an implicit initializer expr".
|
||||
// Is initializer expr present?
|
||||
LLVM_PREFERRED_TYPE(bool)
|
||||
unsigned HasInitializer : 1;
|
||||
|
||||
/// What kind of initializer syntax used? Could be none, parens, or braces.
|
||||
LLVM_PREFERRED_TYPE(CXXNewInitializationStyle)
|
||||
unsigned StoredInitializationStyle : 2;
|
||||
|
||||
|
@ -37,6 +37,7 @@ public:
|
||||
DISPATCH(Declaration);
|
||||
DISPATCH(NullPtr);
|
||||
DISPATCH(Integral);
|
||||
DISPATCH(StructuralValue);
|
||||
DISPATCH(Template);
|
||||
DISPATCH(TemplateExpansion);
|
||||
DISPATCH(Expression);
|
||||
@ -59,6 +60,7 @@ public:
|
||||
VISIT_METHOD(Declaration);
|
||||
VISIT_METHOD(NullPtr);
|
||||
VISIT_METHOD(Integral);
|
||||
VISIT_METHOD(StructuralValue);
|
||||
VISIT_METHOD(Template);
|
||||
VISIT_METHOD(TemplateExpansion);
|
||||
VISIT_METHOD(Expression);
|
||||
|
@ -50,6 +50,7 @@ template <> struct PointerLikeTypeTraits<clang::Expr *> {
|
||||
|
||||
namespace clang {
|
||||
|
||||
class APValue;
|
||||
class ASTContext;
|
||||
class Expr;
|
||||
struct PrintingPolicy;
|
||||
@ -80,6 +81,13 @@ public:
|
||||
/// that was provided for an integral non-type template parameter.
|
||||
Integral,
|
||||
|
||||
/// The template argument is a non-type template argument that can't be
|
||||
/// represented by the special-case Declaration, NullPtr, or Integral
|
||||
/// forms. These values are only ever produced by constant evaluation,
|
||||
/// so cannot be dependent.
|
||||
/// TODO: merge Declaration, NullPtr and Integral into this?
|
||||
StructuralValue,
|
||||
|
||||
/// The template argument is a template name that was provided for a
|
||||
/// template template parameter.
|
||||
Template,
|
||||
@ -130,6 +138,14 @@ private:
|
||||
};
|
||||
void *Type;
|
||||
};
|
||||
struct V {
|
||||
LLVM_PREFERRED_TYPE(ArgKind)
|
||||
unsigned Kind : 31;
|
||||
LLVM_PREFERRED_TYPE(bool)
|
||||
unsigned IsDefaulted : 1;
|
||||
APValue *Value;
|
||||
void *Type;
|
||||
};
|
||||
struct A {
|
||||
LLVM_PREFERRED_TYPE(ArgKind)
|
||||
unsigned Kind : 31;
|
||||
@ -156,11 +172,19 @@ private:
|
||||
union {
|
||||
struct DA DeclArg;
|
||||
struct I Integer;
|
||||
struct V Value;
|
||||
struct A Args;
|
||||
struct TA TemplateArg;
|
||||
struct TV TypeOrValue;
|
||||
};
|
||||
|
||||
void initFromType(QualType T, bool IsNullPtr, bool IsDefaulted);
|
||||
void initFromDeclaration(ValueDecl *D, QualType QT, bool IsDefaulted);
|
||||
void initFromIntegral(const ASTContext &Ctx, const llvm::APSInt &Value,
|
||||
QualType Type, bool IsDefaulted);
|
||||
void initFromStructural(const ASTContext &Ctx, QualType Type,
|
||||
const APValue &V, bool IsDefaulted);
|
||||
|
||||
public:
|
||||
/// Construct an empty, invalid template argument.
|
||||
constexpr TemplateArgument() : TypeOrValue({Null, 0, /* IsDefaulted */ 0}) {}
|
||||
@ -168,25 +192,22 @@ public:
|
||||
/// Construct a template type argument.
|
||||
TemplateArgument(QualType T, bool isNullPtr = false,
|
||||
bool IsDefaulted = false) {
|
||||
TypeOrValue.Kind = isNullPtr ? NullPtr : Type;
|
||||
TypeOrValue.IsDefaulted = IsDefaulted;
|
||||
TypeOrValue.V = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());
|
||||
initFromType(T, isNullPtr, IsDefaulted);
|
||||
}
|
||||
|
||||
/// Construct a template argument that refers to a
|
||||
/// declaration, which is either an external declaration or a
|
||||
/// template declaration.
|
||||
/// Construct a template argument that refers to a (non-dependent)
|
||||
/// declaration.
|
||||
TemplateArgument(ValueDecl *D, QualType QT, bool IsDefaulted = false) {
|
||||
assert(D && "Expected decl");
|
||||
DeclArg.Kind = Declaration;
|
||||
DeclArg.IsDefaulted = IsDefaulted;
|
||||
DeclArg.QT = QT.getAsOpaquePtr();
|
||||
DeclArg.D = D;
|
||||
initFromDeclaration(D, QT, IsDefaulted);
|
||||
}
|
||||
|
||||
/// Construct an integral constant template argument. The memory to
|
||||
/// store the value is allocated with Ctx.
|
||||
TemplateArgument(ASTContext &Ctx, const llvm::APSInt &Value, QualType Type,
|
||||
TemplateArgument(const ASTContext &Ctx, const llvm::APSInt &Value,
|
||||
QualType Type, bool IsDefaulted = false);
|
||||
|
||||
/// Construct a template argument from an arbitrary constant value.
|
||||
TemplateArgument(const ASTContext &Ctx, QualType Type, const APValue &Value,
|
||||
bool IsDefaulted = false);
|
||||
|
||||
/// Construct an integral constant template argument with the same
|
||||
@ -297,7 +318,7 @@ public:
|
||||
/// Retrieve the type for a type template argument.
|
||||
QualType getAsType() const {
|
||||
assert(getKind() == Type && "Unexpected kind");
|
||||
return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue.V));
|
||||
return QualType::getFromOpaquePtr(reinterpret_cast<void *>(TypeOrValue.V));
|
||||
}
|
||||
|
||||
/// Retrieve the declaration for a declaration non-type
|
||||
@ -315,7 +336,7 @@ public:
|
||||
/// Retrieve the type for null non-type template argument.
|
||||
QualType getNullPtrType() const {
|
||||
assert(getKind() == NullPtr && "Unexpected kind");
|
||||
return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue.V));
|
||||
return QualType::getFromOpaquePtr(reinterpret_cast<void *>(TypeOrValue.V));
|
||||
}
|
||||
|
||||
/// Retrieve the template name for a template name argument.
|
||||
@ -371,6 +392,14 @@ public:
|
||||
/// default template parameter.
|
||||
bool getIsDefaulted() const { return (bool)TypeOrValue.IsDefaulted; }
|
||||
|
||||
/// Get the value of a StructuralValue.
|
||||
const APValue &getAsStructuralValue() const { return *Value.Value; }
|
||||
|
||||
/// Get the type of a StructuralValue.
|
||||
QualType getStructuralValueType() const {
|
||||
return QualType::getFromOpaquePtr(Value.Type);
|
||||
}
|
||||
|
||||
/// If this is a non-type template argument, get its type. Otherwise,
|
||||
/// returns a null QualType.
|
||||
QualType getNonTypeTemplateArgumentType() const;
|
||||
@ -516,6 +545,7 @@ public:
|
||||
assert(Argument.getKind() == TemplateArgument::NullPtr ||
|
||||
Argument.getKind() == TemplateArgument::Integral ||
|
||||
Argument.getKind() == TemplateArgument::Declaration ||
|
||||
Argument.getKind() == TemplateArgument::StructuralValue ||
|
||||
Argument.getKind() == TemplateArgument::Expression);
|
||||
}
|
||||
|
||||
@ -541,13 +571,9 @@ public:
|
||||
/// - Fetches the full source range of the argument.
|
||||
SourceRange getSourceRange() const LLVM_READONLY;
|
||||
|
||||
const TemplateArgument &getArgument() const {
|
||||
return Argument;
|
||||
}
|
||||
const TemplateArgument &getArgument() const { return Argument; }
|
||||
|
||||
TemplateArgumentLocInfo getLocInfo() const {
|
||||
return LocInfo;
|
||||
}
|
||||
TemplateArgumentLocInfo getLocInfo() const { return LocInfo; }
|
||||
|
||||
TypeSourceInfo *getTypeSourceInfo() const {
|
||||
if (Argument.getKind() != TemplateArgument::Type)
|
||||
@ -575,6 +601,11 @@ public:
|
||||
return LocInfo.getAsExpr();
|
||||
}
|
||||
|
||||
Expr *getSourceStructuralValueExpression() const {
|
||||
assert(Argument.getKind() == TemplateArgument::StructuralValue);
|
||||
return LocInfo.getAsExpr();
|
||||
}
|
||||
|
||||
NestedNameSpecifierLoc getTemplateQualifierLoc() const {
|
||||
if (Argument.getKind() != TemplateArgument::Template &&
|
||||
Argument.getKind() != TemplateArgument::TemplateExpansion)
|
||||
@ -606,8 +637,7 @@ class TemplateArgumentListInfo {
|
||||
public:
|
||||
TemplateArgumentListInfo() = default;
|
||||
|
||||
TemplateArgumentListInfo(SourceLocation LAngleLoc,
|
||||
SourceLocation RAngleLoc)
|
||||
TemplateArgumentListInfo(SourceLocation LAngleLoc, SourceLocation RAngleLoc)
|
||||
: LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc) {}
|
||||
|
||||
// This can leak if used in an AST node, use ASTTemplateArgumentListInfo
|
||||
@ -626,21 +656,15 @@ public:
|
||||
return Arguments.data();
|
||||
}
|
||||
|
||||
llvm::ArrayRef<TemplateArgumentLoc> arguments() const {
|
||||
return Arguments;
|
||||
}
|
||||
llvm::ArrayRef<TemplateArgumentLoc> arguments() const { return Arguments; }
|
||||
|
||||
const TemplateArgumentLoc &operator[](unsigned I) const {
|
||||
return Arguments[I];
|
||||
}
|
||||
|
||||
TemplateArgumentLoc &operator[](unsigned I) {
|
||||
return Arguments[I];
|
||||
}
|
||||
TemplateArgumentLoc &operator[](unsigned I) { return Arguments[I]; }
|
||||
|
||||
void addArgument(const TemplateArgumentLoc &Loc) {
|
||||
Arguments.push_back(Loc);
|
||||
}
|
||||
void addArgument(const TemplateArgumentLoc &Loc) { Arguments.push_back(Loc); }
|
||||
};
|
||||
|
||||
/// Represents an explicit template argument list in C++, e.g.,
|
||||
|
@ -4029,19 +4029,6 @@ public:
|
||||
/// because TrailingObjects cannot handle repeated types.
|
||||
struct ExceptionType { QualType Type; };
|
||||
|
||||
/// The AArch64 SME ACLE (Arm C/C++ Language Extensions) define a number
|
||||
/// of function type attributes that can be set on function types, including
|
||||
/// function pointers.
|
||||
enum AArch64SMETypeAttributes : unsigned {
|
||||
SME_NormalFunction = 0,
|
||||
SME_PStateSMEnabledMask = 1 << 0,
|
||||
SME_PStateSMCompatibleMask = 1 << 1,
|
||||
SME_PStateZASharedMask = 1 << 2,
|
||||
SME_PStateZAPreservedMask = 1 << 3,
|
||||
SME_AttributeMask = 0b111'111 // We only support maximum 6 bits because of the
|
||||
// bitmask in FunctionTypeExtraBitfields.
|
||||
};
|
||||
|
||||
/// A simple holder for various uncommon bits which do not fit in
|
||||
/// FunctionTypeBitfields. Aligned to alignof(void *) to maintain the
|
||||
/// alignment of subsequent objects in TrailingObjects.
|
||||
@ -4051,11 +4038,57 @@ public:
|
||||
/// [implimits] 8 bits would be enough here.
|
||||
unsigned NumExceptionType : 10;
|
||||
|
||||
LLVM_PREFERRED_TYPE(bool)
|
||||
unsigned HasArmTypeAttributes : 1;
|
||||
|
||||
FunctionTypeExtraBitfields()
|
||||
: NumExceptionType(0), HasArmTypeAttributes(false) {}
|
||||
};
|
||||
|
||||
/// The AArch64 SME ACLE (Arm C/C++ Language Extensions) define a number
|
||||
/// of function type attributes that can be set on function types, including
|
||||
/// function pointers.
|
||||
enum AArch64SMETypeAttributes : unsigned {
|
||||
SME_NormalFunction = 0,
|
||||
SME_PStateSMEnabledMask = 1 << 0,
|
||||
SME_PStateSMCompatibleMask = 1 << 1,
|
||||
|
||||
// Describes the value of the state using ArmStateValue.
|
||||
SME_ZAShift = 2,
|
||||
SME_ZAMask = 0b111 << SME_ZAShift,
|
||||
SME_ZT0Shift = 5,
|
||||
SME_ZT0Mask = 0b111 << SME_ZT0Shift,
|
||||
|
||||
SME_AttributeMask =
|
||||
0b111'111'11 // We can't support more than 8 bits because of
|
||||
// the bitmask in FunctionTypeExtraBitfields.
|
||||
};
|
||||
|
||||
enum ArmStateValue : unsigned {
|
||||
ARM_None = 0,
|
||||
ARM_Preserves = 1,
|
||||
ARM_In = 2,
|
||||
ARM_Out = 3,
|
||||
ARM_InOut = 4,
|
||||
};
|
||||
|
||||
static ArmStateValue getArmZAState(unsigned AttrBits) {
|
||||
return (ArmStateValue)((AttrBits & SME_ZAMask) >> SME_ZAShift);
|
||||
}
|
||||
|
||||
static ArmStateValue getArmZT0State(unsigned AttrBits) {
|
||||
return (ArmStateValue)((AttrBits & SME_ZT0Mask) >> SME_ZT0Shift);
|
||||
}
|
||||
|
||||
/// A holder for Arm type attributes as described in the Arm C/C++
|
||||
/// Language extensions which are not particularly common to all
|
||||
/// types and therefore accounted separately from FunctionTypeBitfields.
|
||||
struct alignas(void *) FunctionTypeArmAttributes {
|
||||
/// Any AArch64 SME ACLE type attributes that need to be propagated
|
||||
/// on declarations and function pointers.
|
||||
unsigned AArch64SMEAttributes : 6;
|
||||
FunctionTypeExtraBitfields()
|
||||
: NumExceptionType(0), AArch64SMEAttributes(SME_NormalFunction) {}
|
||||
unsigned AArch64SMEAttributes : 8;
|
||||
|
||||
FunctionTypeArmAttributes() : AArch64SMEAttributes(SME_NormalFunction) {}
|
||||
};
|
||||
|
||||
protected:
|
||||
@ -4154,7 +4187,8 @@ class FunctionProtoType final
|
||||
public llvm::FoldingSetNode,
|
||||
private llvm::TrailingObjects<
|
||||
FunctionProtoType, QualType, SourceLocation,
|
||||
FunctionType::FunctionTypeExtraBitfields, FunctionType::ExceptionType,
|
||||
FunctionType::FunctionTypeExtraBitfields,
|
||||
FunctionType::FunctionTypeArmAttributes, FunctionType::ExceptionType,
|
||||
Expr *, FunctionDecl *, FunctionType::ExtParameterInfo, Qualifiers> {
|
||||
friend class ASTContext; // ASTContext creates these.
|
||||
friend TrailingObjects;
|
||||
@ -4238,7 +4272,7 @@ public:
|
||||
FunctionType::ExtInfo ExtInfo;
|
||||
unsigned Variadic : 1;
|
||||
unsigned HasTrailingReturn : 1;
|
||||
unsigned AArch64SMEAttributes : 6;
|
||||
unsigned AArch64SMEAttributes : 8;
|
||||
Qualifiers TypeQuals;
|
||||
RefQualifierKind RefQualifier = RQ_None;
|
||||
ExceptionSpecInfo ExceptionSpec;
|
||||
@ -4261,7 +4295,11 @@ public:
|
||||
|
||||
bool requiresFunctionProtoTypeExtraBitfields() const {
|
||||
return ExceptionSpec.Type == EST_Dynamic ||
|
||||
AArch64SMEAttributes != SME_NormalFunction;
|
||||
requiresFunctionProtoTypeArmAttributes();
|
||||
}
|
||||
|
||||
bool requiresFunctionProtoTypeArmAttributes() const {
|
||||
return AArch64SMEAttributes != SME_NormalFunction;
|
||||
}
|
||||
|
||||
void setArmSMEAttribute(AArch64SMETypeAttributes Kind, bool Enable = true) {
|
||||
@ -4281,6 +4319,10 @@ private:
|
||||
return isVariadic();
|
||||
}
|
||||
|
||||
unsigned numTrailingObjects(OverloadToken<FunctionTypeArmAttributes>) const {
|
||||
return hasArmTypeAttributes();
|
||||
}
|
||||
|
||||
unsigned numTrailingObjects(OverloadToken<FunctionTypeExtraBitfields>) const {
|
||||
return hasExtraBitfields();
|
||||
}
|
||||
@ -4369,6 +4411,12 @@ private:
|
||||
|
||||
}
|
||||
|
||||
bool hasArmTypeAttributes() const {
|
||||
return FunctionTypeBits.HasExtraBitfields &&
|
||||
getTrailingObjects<FunctionTypeExtraBitfields>()
|
||||
->HasArmTypeAttributes;
|
||||
}
|
||||
|
||||
bool hasExtQualifiers() const {
|
||||
return FunctionTypeBits.HasExtQuals;
|
||||
}
|
||||
@ -4580,9 +4628,9 @@ public:
|
||||
/// Return a bitmask describing the SME attributes on the function type, see
|
||||
/// AArch64SMETypeAttributes for their values.
|
||||
unsigned getAArch64SMEAttributes() const {
|
||||
if (!hasExtraBitfields())
|
||||
if (!hasArmTypeAttributes())
|
||||
return SME_NormalFunction;
|
||||
return getTrailingObjects<FunctionTypeExtraBitfields>()
|
||||
return getTrailingObjects<FunctionTypeArmAttributes>()
|
||||
->AArch64SMEAttributes;
|
||||
}
|
||||
|
||||
|
@ -2062,6 +2062,18 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXDefaultArgExpr>
|
||||
extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXOperatorCallExpr>
|
||||
cxxOperatorCallExpr;
|
||||
|
||||
/// Matches C++17 fold expressions.
|
||||
///
|
||||
/// Example matches `(0 + ... + args)`:
|
||||
/// \code
|
||||
/// template <typename... Args>
|
||||
/// auto sum(Args... args) {
|
||||
/// return (0 + ... + args);
|
||||
/// }
|
||||
/// \endcode
|
||||
extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXFoldExpr>
|
||||
cxxFoldExpr;
|
||||
|
||||
/// Matches rewritten binary operators
|
||||
///
|
||||
/// Example matches use of "<":
|
||||
@ -3881,7 +3893,7 @@ AST_MATCHER_P(ObjCMessageExpr, numSelectorArgs, unsigned, N) {
|
||||
return Node.getSelector().getNumArgs() == N;
|
||||
}
|
||||
|
||||
/// Matches if the call expression's callee expression matches.
|
||||
/// Matches if the call or fold expression's callee expression matches.
|
||||
///
|
||||
/// Given
|
||||
/// \code
|
||||
@ -3893,13 +3905,32 @@ AST_MATCHER_P(ObjCMessageExpr, numSelectorArgs, unsigned, N) {
|
||||
/// with callee(...)
|
||||
/// matching this->x, x, y.x, f respectively
|
||||
///
|
||||
/// Given
|
||||
/// \code
|
||||
/// template <typename... Args>
|
||||
/// auto sum(Args... args) {
|
||||
/// return (0 + ... + args);
|
||||
/// }
|
||||
///
|
||||
/// template <typename... Args>
|
||||
/// auto multiply(Args... args) {
|
||||
/// return (args * ... * 1);
|
||||
/// }
|
||||
/// \endcode
|
||||
/// cxxFoldExpr(callee(expr()))
|
||||
/// matches (args * ... * 1)
|
||||
/// with callee(...)
|
||||
/// matching *
|
||||
///
|
||||
/// Note: Callee cannot take the more general internal::Matcher<Expr>
|
||||
/// because this introduces ambiguous overloads with calls to Callee taking a
|
||||
/// internal::Matcher<Decl>, as the matcher hierarchy is purely
|
||||
/// implemented in terms of implicit casts.
|
||||
AST_MATCHER_P(CallExpr, callee, internal::Matcher<Stmt>,
|
||||
InnerMatcher) {
|
||||
const Expr *ExprNode = Node.getCallee();
|
||||
AST_POLYMORPHIC_MATCHER_P_OVERLOAD(callee,
|
||||
AST_POLYMORPHIC_SUPPORTED_TYPES(CallExpr,
|
||||
CXXFoldExpr),
|
||||
internal::Matcher<Stmt>, InnerMatcher, 0) {
|
||||
const auto *ExprNode = Node.getCallee();
|
||||
return (ExprNode != nullptr &&
|
||||
InnerMatcher.matches(*ExprNode, Finder, Builder));
|
||||
}
|
||||
@ -4532,6 +4563,121 @@ AST_POLYMORPHIC_MATCHER_P2(hasArgument,
|
||||
return InnerMatcher.matches(*Arg->IgnoreParenImpCasts(), Finder, Builder);
|
||||
}
|
||||
|
||||
/// Matches the operand that does not contain the parameter pack.
|
||||
///
|
||||
/// Example matches `(0 + ... + args)` and `(args * ... * 1)`
|
||||
/// (matcher = cxxFoldExpr(hasFoldInit(expr())))
|
||||
/// with hasFoldInit(...)
|
||||
/// matching `0` and `1` respectively
|
||||
/// \code
|
||||
/// template <typename... Args>
|
||||
/// auto sum(Args... args) {
|
||||
/// return (0 + ... + args);
|
||||
/// }
|
||||
///
|
||||
/// template <typename... Args>
|
||||
/// auto multiply(Args... args) {
|
||||
/// return (args * ... * 1);
|
||||
/// }
|
||||
/// \endcode
|
||||
AST_MATCHER_P(CXXFoldExpr, hasFoldInit, ast_matchers::internal::Matcher<Expr>,
|
||||
InnerMacher) {
|
||||
const auto *const Init = Node.getInit();
|
||||
return Init && InnerMacher.matches(*Init, Finder, Builder);
|
||||
}
|
||||
|
||||
/// Matches the operand that contains the parameter pack.
|
||||
///
|
||||
/// Example matches `(0 + ... + args)`
|
||||
/// (matcher = cxxFoldExpr(hasPattern(expr())))
|
||||
/// with hasPattern(...)
|
||||
/// matching `args`
|
||||
/// \code
|
||||
/// template <typename... Args>
|
||||
/// auto sum(Args... args) {
|
||||
/// return (0 + ... + args);
|
||||
/// }
|
||||
///
|
||||
/// template <typename... Args>
|
||||
/// auto multiply(Args... args) {
|
||||
/// return (args * ... * 1);
|
||||
/// }
|
||||
/// \endcode
|
||||
AST_MATCHER_P(CXXFoldExpr, hasPattern, ast_matchers::internal::Matcher<Expr>,
|
||||
InnerMacher) {
|
||||
const Expr *const Pattern = Node.getPattern();
|
||||
return Pattern && InnerMacher.matches(*Pattern, Finder, Builder);
|
||||
}
|
||||
|
||||
/// Matches right-folding fold expressions.
|
||||
///
|
||||
/// Example matches `(args * ... * 1)`
|
||||
/// (matcher = cxxFoldExpr(isRightFold()))
|
||||
/// \code
|
||||
/// template <typename... Args>
|
||||
/// auto sum(Args... args) {
|
||||
/// return (0 + ... + args);
|
||||
/// }
|
||||
///
|
||||
/// template <typename... Args>
|
||||
/// auto multiply(Args... args) {
|
||||
/// return (args * ... * 1);
|
||||
/// }
|
||||
/// \endcode
|
||||
AST_MATCHER(CXXFoldExpr, isRightFold) { return Node.isRightFold(); }
|
||||
|
||||
/// Matches left-folding fold expressions.
|
||||
///
|
||||
/// Example matches `(0 + ... + args)`
|
||||
/// (matcher = cxxFoldExpr(isLeftFold()))
|
||||
/// \code
|
||||
/// template <typename... Args>
|
||||
/// auto sum(Args... args) {
|
||||
/// return (0 + ... + args);
|
||||
/// }
|
||||
///
|
||||
/// template <typename... Args>
|
||||
/// auto multiply(Args... args) {
|
||||
/// return (args * ... * 1);
|
||||
/// }
|
||||
/// \endcode
|
||||
AST_MATCHER(CXXFoldExpr, isLeftFold) { return Node.isLeftFold(); }
|
||||
|
||||
/// Matches unary fold expressions, i.e. fold expressions without an
|
||||
/// initializer.
|
||||
///
|
||||
/// Example matches `(args * ...)`
|
||||
/// (matcher = cxxFoldExpr(isUnaryFold()))
|
||||
/// \code
|
||||
/// template <typename... Args>
|
||||
/// auto sum(Args... args) {
|
||||
/// return (0 + ... + args);
|
||||
/// }
|
||||
///
|
||||
/// template <typename... Args>
|
||||
/// auto multiply(Args... args) {
|
||||
/// return (args * ...);
|
||||
/// }
|
||||
/// \endcode
|
||||
AST_MATCHER(CXXFoldExpr, isUnaryFold) { return Node.getInit() == nullptr; }
|
||||
|
||||
/// Matches binary fold expressions, i.e. fold expressions with an initializer.
|
||||
///
|
||||
/// Example matches `(0 + ... + args)`
|
||||
/// (matcher = cxxFoldExpr(isBinaryFold()))
|
||||
/// \code
|
||||
/// template <typename... Args>
|
||||
/// auto sum(Args... args) {
|
||||
/// return (0 + ... + args);
|
||||
/// }
|
||||
///
|
||||
/// template <typename... Args>
|
||||
/// auto multiply(Args... args) {
|
||||
/// return (args * ...);
|
||||
/// }
|
||||
/// \endcode
|
||||
AST_MATCHER(CXXFoldExpr, isBinaryFold) { return Node.getInit() != nullptr; }
|
||||
|
||||
/// Matches the n'th item of an initializer list expression.
|
||||
///
|
||||
/// Example matches y.
|
||||
@ -5709,17 +5855,27 @@ AST_POLYMORPHIC_MATCHER_P_OVERLOAD(equals,
|
||||
.matchesNode(Node);
|
||||
}
|
||||
|
||||
/// Matches the operator Name of operator expressions (binary or
|
||||
/// unary).
|
||||
/// Matches the operator Name of operator expressions and fold expressions
|
||||
/// (binary or unary).
|
||||
///
|
||||
/// Example matches a || b (matcher = binaryOperator(hasOperatorName("||")))
|
||||
/// \code
|
||||
/// !(a || b)
|
||||
/// \endcode
|
||||
///
|
||||
/// Example matches `(0 + ... + args)`
|
||||
/// (matcher = cxxFoldExpr(hasOperatorName("+")))
|
||||
/// \code
|
||||
/// template <typename... Args>
|
||||
/// auto sum(Args... args) {
|
||||
/// return (0 + ... + args);
|
||||
/// }
|
||||
/// \endcode
|
||||
AST_POLYMORPHIC_MATCHER_P(
|
||||
hasOperatorName,
|
||||
AST_POLYMORPHIC_SUPPORTED_TYPES(BinaryOperator, CXXOperatorCallExpr,
|
||||
CXXRewrittenBinaryOperator, UnaryOperator),
|
||||
CXXRewrittenBinaryOperator, CXXFoldExpr,
|
||||
UnaryOperator),
|
||||
std::string, Name) {
|
||||
if (std::optional<StringRef> OpName = internal::getOpName(Node))
|
||||
return *OpName == Name;
|
||||
@ -5789,11 +5945,12 @@ AST_POLYMORPHIC_MATCHER(
|
||||
/// \code
|
||||
/// a || b
|
||||
/// \endcode
|
||||
AST_POLYMORPHIC_MATCHER_P(hasLHS,
|
||||
AST_POLYMORPHIC_SUPPORTED_TYPES(
|
||||
BinaryOperator, CXXOperatorCallExpr,
|
||||
CXXRewrittenBinaryOperator, ArraySubscriptExpr),
|
||||
internal::Matcher<Expr>, InnerMatcher) {
|
||||
AST_POLYMORPHIC_MATCHER_P(
|
||||
hasLHS,
|
||||
AST_POLYMORPHIC_SUPPORTED_TYPES(BinaryOperator, CXXOperatorCallExpr,
|
||||
CXXRewrittenBinaryOperator,
|
||||
ArraySubscriptExpr, CXXFoldExpr),
|
||||
internal::Matcher<Expr>, InnerMatcher) {
|
||||
const Expr *LeftHandSide = internal::getLHS(Node);
|
||||
return (LeftHandSide != nullptr &&
|
||||
InnerMatcher.matches(*LeftHandSide, Finder, Builder));
|
||||
@ -5805,29 +5962,31 @@ AST_POLYMORPHIC_MATCHER_P(hasLHS,
|
||||
/// \code
|
||||
/// a || b
|
||||
/// \endcode
|
||||
AST_POLYMORPHIC_MATCHER_P(hasRHS,
|
||||
AST_POLYMORPHIC_SUPPORTED_TYPES(
|
||||
BinaryOperator, CXXOperatorCallExpr,
|
||||
CXXRewrittenBinaryOperator, ArraySubscriptExpr),
|
||||
internal::Matcher<Expr>, InnerMatcher) {
|
||||
AST_POLYMORPHIC_MATCHER_P(
|
||||
hasRHS,
|
||||
AST_POLYMORPHIC_SUPPORTED_TYPES(BinaryOperator, CXXOperatorCallExpr,
|
||||
CXXRewrittenBinaryOperator,
|
||||
ArraySubscriptExpr, CXXFoldExpr),
|
||||
internal::Matcher<Expr>, InnerMatcher) {
|
||||
const Expr *RightHandSide = internal::getRHS(Node);
|
||||
return (RightHandSide != nullptr &&
|
||||
InnerMatcher.matches(*RightHandSide, Finder, Builder));
|
||||
}
|
||||
|
||||
/// Matches if either the left hand side or the right hand side of a
|
||||
/// binary operator matches.
|
||||
/// binary operator or fold expression matches.
|
||||
AST_POLYMORPHIC_MATCHER_P(
|
||||
hasEitherOperand,
|
||||
AST_POLYMORPHIC_SUPPORTED_TYPES(BinaryOperator, CXXOperatorCallExpr,
|
||||
CXXRewrittenBinaryOperator),
|
||||
CXXFoldExpr, CXXRewrittenBinaryOperator),
|
||||
internal::Matcher<Expr>, InnerMatcher) {
|
||||
return internal::VariadicDynCastAllOfMatcher<Stmt, NodeType>()(
|
||||
anyOf(hasLHS(InnerMatcher), hasRHS(InnerMatcher)))
|
||||
.matches(Node, Finder, Builder);
|
||||
}
|
||||
|
||||
/// Matches if both matchers match with opposite sides of the binary operator.
|
||||
/// Matches if both matchers match with opposite sides of the binary operator
|
||||
/// or fold expression.
|
||||
///
|
||||
/// Example matcher = binaryOperator(hasOperands(integerLiteral(equals(1),
|
||||
/// integerLiteral(equals(2)))
|
||||
@ -5840,7 +5999,7 @@ AST_POLYMORPHIC_MATCHER_P(
|
||||
AST_POLYMORPHIC_MATCHER_P2(
|
||||
hasOperands,
|
||||
AST_POLYMORPHIC_SUPPORTED_TYPES(BinaryOperator, CXXOperatorCallExpr,
|
||||
CXXRewrittenBinaryOperator),
|
||||
CXXFoldExpr, CXXRewrittenBinaryOperator),
|
||||
internal::Matcher<Expr>, Matcher1, internal::Matcher<Expr>, Matcher2) {
|
||||
return internal::VariadicDynCastAllOfMatcher<Stmt, NodeType>()(
|
||||
anyOf(allOf(hasLHS(Matcher1), hasRHS(Matcher2)),
|
||||
@ -6192,9 +6351,7 @@ AST_POLYMORPHIC_MATCHER(isFinal,
|
||||
/// };
|
||||
/// \endcode
|
||||
/// matches A::x
|
||||
AST_MATCHER(CXXMethodDecl, isPure) {
|
||||
return Node.isPure();
|
||||
}
|
||||
AST_MATCHER(CXXMethodDecl, isPure) { return Node.isPureVirtual(); }
|
||||
|
||||
/// Matches if the given method declaration is const.
|
||||
///
|
||||
|
@ -2195,6 +2195,9 @@ inline std::optional<StringRef> getOpName(const CXXOperatorCallExpr &Node) {
|
||||
}
|
||||
return BinaryOperator::getOpcodeStr(*optBinaryOpcode);
|
||||
}
|
||||
inline StringRef getOpName(const CXXFoldExpr &Node) {
|
||||
return BinaryOperator::getOpcodeStr(Node.getOperator());
|
||||
}
|
||||
|
||||
/// Matches overloaded operators with a specific name.
|
||||
///
|
||||
|
@ -32,7 +32,8 @@ namespace dataflow {
|
||||
class ControlFlowContext {
|
||||
public:
|
||||
/// Builds a ControlFlowContext from a `FunctionDecl`.
|
||||
/// `Func.hasBody()` must be true, and `Func.isTemplated()` must be false.
|
||||
/// `Func.doesThisDeclarationHaveABody()` must be true, and
|
||||
/// `Func.isTemplated()` must be false.
|
||||
static llvm::Expected<ControlFlowContext> build(const FunctionDecl &Func);
|
||||
|
||||
/// Builds a ControlFlowContext from an AST node. `D` is the function in which
|
||||
|
@ -186,6 +186,12 @@ template <typename LatticeT> struct DataflowAnalysisState {
|
||||
/// the dataflow analysis cannot be performed successfully. Otherwise, calls
|
||||
/// `PostVisitCFG` on each CFG element with the final analysis results at that
|
||||
/// program point.
|
||||
///
|
||||
/// `MaxBlockVisits` caps the number of block visits during analysis. See
|
||||
/// `runTypeErasedDataflowAnalysis` for a full description. The default value is
|
||||
/// essentially arbitrary -- large enough to accommodate what seems like any
|
||||
/// reasonable CFG, but still small enough to limit the cost of hitting the
|
||||
/// limit.
|
||||
template <typename AnalysisT>
|
||||
llvm::Expected<std::vector<
|
||||
std::optional<DataflowAnalysisState<typename AnalysisT::Lattice>>>>
|
||||
@ -194,7 +200,8 @@ runDataflowAnalysis(
|
||||
const Environment &InitEnv,
|
||||
std::function<void(const CFGElement &, const DataflowAnalysisState<
|
||||
typename AnalysisT::Lattice> &)>
|
||||
PostVisitCFG = nullptr) {
|
||||
PostVisitCFG = nullptr,
|
||||
std::int32_t MaxBlockVisits = 20'000) {
|
||||
std::function<void(const CFGElement &,
|
||||
const TypeErasedDataflowAnalysisState &)>
|
||||
PostVisitCFGClosure = nullptr;
|
||||
@ -212,7 +219,7 @@ runDataflowAnalysis(
|
||||
}
|
||||
|
||||
auto TypeErasedBlockStates = runTypeErasedDataflowAnalysis(
|
||||
CFCtx, Analysis, InitEnv, PostVisitCFGClosure);
|
||||
CFCtx, Analysis, InitEnv, PostVisitCFGClosure, MaxBlockVisits);
|
||||
if (!TypeErasedBlockStates)
|
||||
return TypeErasedBlockStates.takeError();
|
||||
|
||||
@ -261,6 +268,10 @@ auto createAnalysis(ASTContext &ASTCtx, Environment &Env)
|
||||
/// iterations.
|
||||
/// - This limit is still low enough to keep runtimes acceptable (on typical
|
||||
/// machines) in cases where we hit the limit.
|
||||
///
|
||||
/// `MaxBlockVisits` caps the number of block visits during analysis. See
|
||||
/// `runDataflowAnalysis` for a full description and explanation of the default
|
||||
/// value.
|
||||
template <typename AnalysisT, typename Diagnostic>
|
||||
llvm::Expected<llvm::SmallVector<Diagnostic>> diagnoseFunction(
|
||||
const FunctionDecl &FuncDecl, ASTContext &ASTCtx,
|
||||
@ -268,7 +279,8 @@ llvm::Expected<llvm::SmallVector<Diagnostic>> diagnoseFunction(
|
||||
const CFGElement &, ASTContext &,
|
||||
const TransferStateForDiagnostics<typename AnalysisT::Lattice> &)>
|
||||
Diagnoser,
|
||||
std::int64_t MaxSATIterations = 1'000'000'000) {
|
||||
std::int64_t MaxSATIterations = 1'000'000'000,
|
||||
std::int32_t MaxBlockVisits = 20'000) {
|
||||
llvm::Expected<ControlFlowContext> Context =
|
||||
ControlFlowContext::build(FuncDecl);
|
||||
if (!Context)
|
||||
@ -293,7 +305,8 @@ llvm::Expected<llvm::SmallVector<Diagnostic>> diagnoseFunction(
|
||||
State.Lattice.Value),
|
||||
State.Env));
|
||||
llvm::move(EltDiagnostics, std::back_inserter(Diagnostics));
|
||||
})
|
||||
},
|
||||
MaxBlockVisits)
|
||||
.takeError())
|
||||
return std::move(Err);
|
||||
|
||||
|
@ -172,7 +172,8 @@ public:
|
||||
///
|
||||
/// Requirements:
|
||||
///
|
||||
/// The function must have a body.
|
||||
/// The function must have a body, i.e.
|
||||
/// `FunctionDecl::doesThisDecalarationHaveABody()` must be true.
|
||||
void initialize();
|
||||
|
||||
/// Returns a new environment that is a copy of this one.
|
||||
|
@ -75,6 +75,10 @@ public:
|
||||
return static_cast<bool>(Value);
|
||||
}
|
||||
|
||||
bool isLiteral(bool b) const {
|
||||
return kind() == Literal && static_cast<bool>(Value) == b;
|
||||
}
|
||||
|
||||
ArrayRef<const Formula *> operands() const {
|
||||
return ArrayRef(reinterpret_cast<Formula *const *>(this + 1),
|
||||
numOperands(kind()));
|
||||
|
@ -25,10 +25,17 @@ namespace dataflow {
|
||||
/// Maps statements to the environments of basic blocks that contain them.
|
||||
class StmtToEnvMap {
|
||||
public:
|
||||
// `CurBlockID` is the ID of the block currently being processed, and
|
||||
// `CurState` is the pending state currently associated with this block. These
|
||||
// are supplied separately as the pending state for the current block may not
|
||||
// yet be represented in `BlockToState`.
|
||||
StmtToEnvMap(const ControlFlowContext &CFCtx,
|
||||
llvm::ArrayRef<std::optional<TypeErasedDataflowAnalysisState>>
|
||||
BlockToState)
|
||||
: CFCtx(CFCtx), BlockToState(BlockToState) {}
|
||||
BlockToState,
|
||||
unsigned CurBlockID,
|
||||
const TypeErasedDataflowAnalysisState &CurState)
|
||||
: CFCtx(CFCtx), BlockToState(BlockToState), CurBlockID(CurBlockID),
|
||||
CurState(CurState) {}
|
||||
|
||||
/// Returns the environment of the basic block that contains `S`.
|
||||
/// The result is guaranteed never to be null.
|
||||
@ -37,6 +44,8 @@ public:
|
||||
private:
|
||||
const ControlFlowContext &CFCtx;
|
||||
llvm::ArrayRef<std::optional<TypeErasedDataflowAnalysisState>> BlockToState;
|
||||
unsigned CurBlockID;
|
||||
const TypeErasedDataflowAnalysisState &CurState;
|
||||
};
|
||||
|
||||
/// Evaluates `S` and updates `Env` accordingly.
|
||||
|
@ -138,13 +138,20 @@ struct TypeErasedDataflowAnalysisState {
|
||||
/// dataflow analysis cannot be performed successfully. Otherwise, calls
|
||||
/// `PostVisitCFG` on each CFG element with the final analysis results at that
|
||||
/// program point.
|
||||
///
|
||||
/// `MaxBlockVisits` caps the number of block visits during analysis. It doesn't
|
||||
/// distinguish between repeat visits to the same block and visits to distinct
|
||||
/// blocks. This parameter is a backstop to prevent infinite loops, in the case
|
||||
/// of bugs in the lattice and/or transfer functions that prevent the analysis
|
||||
/// from converging.
|
||||
llvm::Expected<std::vector<std::optional<TypeErasedDataflowAnalysisState>>>
|
||||
runTypeErasedDataflowAnalysis(
|
||||
const ControlFlowContext &CFCtx, TypeErasedDataflowAnalysis &Analysis,
|
||||
const Environment &InitEnv,
|
||||
std::function<void(const CFGElement &,
|
||||
const TypeErasedDataflowAnalysisState &)>
|
||||
PostVisitCFG = nullptr);
|
||||
PostVisitCFG,
|
||||
std::int32_t MaxBlockVisits);
|
||||
|
||||
} // namespace dataflow
|
||||
} // namespace clang
|
||||
|
@ -306,6 +306,9 @@ class VariadicEnumArgument<string name, string type, list<string> values,
|
||||
bit IsExternalType = isExternalType;
|
||||
}
|
||||
|
||||
// Represents an attribute wrapped by another attribute.
|
||||
class WrappedAttr<string name, bit opt = 0> : Argument<name, opt>;
|
||||
|
||||
// This handles one spelling of an attribute.
|
||||
class Spelling<string name, string variety, int version = 1> {
|
||||
string Name = name;
|
||||
@ -2291,7 +2294,7 @@ def ObjCBridgeRelated : InheritableAttr {
|
||||
def NSErrorDomain : InheritableAttr {
|
||||
let Spellings = [GNU<"ns_error_domain">];
|
||||
let Subjects = SubjectList<[Enum], ErrorDiag>;
|
||||
let Args = [DeclArgument<Var, "ErrorDomain">];
|
||||
let Args = [IdentifierArgument<"ErrorDomain">];
|
||||
let Documentation = [NSErrorDomainDocs];
|
||||
}
|
||||
|
||||
@ -2539,16 +2542,48 @@ def ArmStreamingCompatible : TypeAttr, TargetSpecificAttr<TargetAArch64> {
|
||||
let Documentation = [ArmSmeStreamingCompatibleDocs];
|
||||
}
|
||||
|
||||
def ArmSharedZA : TypeAttr, TargetSpecificAttr<TargetAArch64> {
|
||||
let Spellings = [RegularKeyword<"__arm_shared_za">];
|
||||
let Subjects = SubjectList<[HasFunctionProto], ErrorDiag>;
|
||||
let Documentation = [ArmSmeSharedZADocs];
|
||||
def ArmNew : InheritableAttr, TargetSpecificAttr<TargetAArch64> {
|
||||
let Spellings = [RegularKeyword<"__arm_new">];
|
||||
let Args = [VariadicStringArgument<"NewArgs">];
|
||||
let Subjects = SubjectList<[Function], ErrorDiag>;
|
||||
let Documentation = [ArmNewDocs];
|
||||
|
||||
let AdditionalMembers = [{
|
||||
bool isNewZA() const {
|
||||
return llvm::is_contained(newArgs(), "za");
|
||||
}
|
||||
bool isNewZT0() const {
|
||||
return llvm::is_contained(newArgs(), "zt0");
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
def ArmPreservesZA : TypeAttr, TargetSpecificAttr<TargetAArch64> {
|
||||
let Spellings = [RegularKeyword<"__arm_preserves_za">];
|
||||
def ArmIn : TypeAttr, TargetSpecificAttr<TargetAArch64> {
|
||||
let Spellings = [RegularKeyword<"__arm_in">];
|
||||
let Args = [VariadicStringArgument<"InArgs">];
|
||||
let Subjects = SubjectList<[HasFunctionProto], ErrorDiag>;
|
||||
let Documentation = [ArmSmePreservesZADocs];
|
||||
let Documentation = [ArmInDocs];
|
||||
}
|
||||
|
||||
def ArmOut : TypeAttr, TargetSpecificAttr<TargetAArch64> {
|
||||
let Spellings = [RegularKeyword<"__arm_out">];
|
||||
let Args = [VariadicStringArgument<"OutArgs">];
|
||||
let Subjects = SubjectList<[HasFunctionProto], ErrorDiag>;
|
||||
let Documentation = [ArmOutDocs];
|
||||
}
|
||||
|
||||
def ArmInOut : TypeAttr, TargetSpecificAttr<TargetAArch64> {
|
||||
let Spellings = [RegularKeyword<"__arm_inout">];
|
||||
let Args = [VariadicStringArgument<"InOutArgs">];
|
||||
let Subjects = SubjectList<[HasFunctionProto], ErrorDiag>;
|
||||
let Documentation = [ArmInOutDocs];
|
||||
}
|
||||
|
||||
def ArmPreserves : TypeAttr, TargetSpecificAttr<TargetAArch64> {
|
||||
let Spellings = [RegularKeyword<"__arm_preserves">];
|
||||
let Args = [VariadicStringArgument<"PreserveArgs">];
|
||||
let Subjects = SubjectList<[HasFunctionProto], ErrorDiag>;
|
||||
let Documentation = [ArmPreservesDocs];
|
||||
}
|
||||
|
||||
def ArmLocallyStreaming : InheritableAttr, TargetSpecificAttr<TargetAArch64> {
|
||||
@ -2557,14 +2592,6 @@ def ArmLocallyStreaming : InheritableAttr, TargetSpecificAttr<TargetAArch64> {
|
||||
let Documentation = [ArmSmeLocallyStreamingDocs];
|
||||
}
|
||||
|
||||
def ArmNewZA : InheritableAttr, TargetSpecificAttr<TargetAArch64> {
|
||||
let Spellings = [RegularKeyword<"__arm_new_za">];
|
||||
let Subjects = SubjectList<[Function], ErrorDiag>;
|
||||
let Documentation = [ArmSmeNewZADocs];
|
||||
}
|
||||
def : MutualExclusions<[ArmNewZA, ArmSharedZA]>;
|
||||
def : MutualExclusions<[ArmNewZA, ArmPreservesZA]>;
|
||||
|
||||
|
||||
def Pure : InheritableAttr {
|
||||
let Spellings = [GCC<"pure">];
|
||||
@ -2627,6 +2654,22 @@ def SwiftError : InheritableAttr {
|
||||
let Documentation = [SwiftErrorDocs];
|
||||
}
|
||||
|
||||
def SwiftImportAsNonGeneric : InheritableAttr {
|
||||
// This attribute has no spellings as it is only ever created implicitly
|
||||
// from API notes.
|
||||
let Spellings = [];
|
||||
let SemaHandler = 0;
|
||||
let Documentation = [InternalOnly];
|
||||
}
|
||||
|
||||
def SwiftImportPropertyAsAccessors : InheritableAttr {
|
||||
// This attribute has no spellings as it is only ever created implicitly
|
||||
// from API notes.
|
||||
let Spellings = [];
|
||||
let SemaHandler = 0;
|
||||
let Documentation = [InternalOnly];
|
||||
}
|
||||
|
||||
def SwiftName : InheritableAttr {
|
||||
let Spellings = [GNU<"swift_name">];
|
||||
let Args = [StringArgument<"Name">];
|
||||
@ -2648,6 +2691,31 @@ def SwiftPrivate : InheritableAttr {
|
||||
let SimpleHandler = 1;
|
||||
}
|
||||
|
||||
def SwiftVersionedAddition : Attr {
|
||||
// This attribute has no spellings as it is only ever created implicitly
|
||||
// from API notes.
|
||||
let Spellings = [];
|
||||
let Args = [VersionArgument<"Version">, WrappedAttr<"AdditionalAttr">,
|
||||
BoolArgument<"IsReplacedByActive">];
|
||||
let SemaHandler = 0;
|
||||
let Documentation = [InternalOnly];
|
||||
}
|
||||
|
||||
def SwiftVersionedRemoval : Attr {
|
||||
// This attribute has no spellings as it is only ever created implicitly
|
||||
// from API notes.
|
||||
let Spellings = [];
|
||||
let Args = [VersionArgument<"Version">, UnsignedArgument<"RawKind">,
|
||||
BoolArgument<"IsReplacedByActive">];
|
||||
let SemaHandler = 0;
|
||||
let Documentation = [InternalOnly];
|
||||
let AdditionalMembers = [{
|
||||
attr::Kind getAttrKindToRemove() const {
|
||||
return static_cast<attr::Kind>(getRawKind());
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
def NoDeref : TypeAttr {
|
||||
let Spellings = [Clang<"noderef">];
|
||||
let Documentation = [NoDerefDocs];
|
||||
|
@ -3621,7 +3621,7 @@ Attribute ``trivial_abi`` has no effect in the following cases:
|
||||
|
||||
def MSInheritanceDocs : Documentation {
|
||||
let Category = DocCatDecl;
|
||||
let Heading = "__single_inhertiance, __multiple_inheritance, __virtual_inheritance";
|
||||
let Heading = "__single_inheritance, __multiple_inheritance, __virtual_inheritance";
|
||||
let Content = [{
|
||||
This collection of keywords is enabled under ``-fms-extensions`` and controls
|
||||
the pointer-to-member representation used on ``*-*-win32`` targets.
|
||||
@ -6861,30 +6861,73 @@ without changing modes.
|
||||
}];
|
||||
}
|
||||
|
||||
def ArmSmeSharedZADocs : Documentation {
|
||||
def ArmInDocs : Documentation {
|
||||
let Category = DocCatArmSmeAttributes;
|
||||
let Content = [{
|
||||
The ``__arm_shared_za`` keyword applies to prototyped function types and specifies
|
||||
that the function shares SME's matrix storage (ZA) with its caller. This
|
||||
means that:
|
||||
The ``__arm_in`` keyword applies to prototyped function types and specifies
|
||||
that the function shares a given state S with its caller. For ``__arm_in``, the
|
||||
function takes the state S as input and returns with the state S unchanged.
|
||||
|
||||
* the function requires that the processor implements the Scalable Matrix
|
||||
Extension (SME).
|
||||
The attribute takes string arguments to instruct the compiler which state
|
||||
is shared. The supported states for S are:
|
||||
|
||||
* the function enters with ZA in an active state.
|
||||
* ``"za"`` for Matrix Storage (requires SME)
|
||||
|
||||
* the function returns with ZA in an active state.
|
||||
The attributes ``__arm_in(S)``, ``__arm_out(S)``, ``__arm_inout(S)`` and
|
||||
``__arm_preserves(S)`` are all mutually exclusive for the same state S.
|
||||
}];
|
||||
}
|
||||
|
||||
def ArmSmePreservesZADocs : Documentation {
|
||||
def ArmOutDocs : Documentation {
|
||||
let Category = DocCatArmSmeAttributes;
|
||||
let Content = [{
|
||||
The ``__arm_preserves_za`` keyword applies to prototyped function types and
|
||||
specifies that the function does not modify ZA state.
|
||||
The ``__arm_out`` keyword applies to prototyped function types and specifies
|
||||
that the function shares a given state S with its caller. For ``__arm_out``,
|
||||
the function ignores the incoming state for S and returns new state for S.
|
||||
|
||||
The attribute takes string arguments to instruct the compiler which state
|
||||
is shared. The supported states for S are:
|
||||
|
||||
* ``"za"`` for Matrix Storage (requires SME)
|
||||
|
||||
The attributes ``__arm_in(S)``, ``__arm_out(S)``, ``__arm_inout(S)`` and
|
||||
``__arm_preserves(S)`` are all mutually exclusive for the same state S.
|
||||
}];
|
||||
}
|
||||
|
||||
def ArmInOutDocs : Documentation {
|
||||
let Category = DocCatArmSmeAttributes;
|
||||
let Content = [{
|
||||
The ``__arm_inout`` keyword applies to prototyped function types and specifies
|
||||
that the function shares a given state S with its caller. For ``__arm_inout``,
|
||||
the function takes the state S as input and returns new state for S.
|
||||
|
||||
The attribute takes string arguments to instruct the compiler which state
|
||||
is shared. The supported states for S are:
|
||||
|
||||
* ``"za"`` for Matrix Storage (requires SME)
|
||||
|
||||
The attributes ``__arm_in(S)``, ``__arm_out(S)``, ``__arm_inout(S)`` and
|
||||
``__arm_preserves(S)`` are all mutually exclusive for the same state S.
|
||||
}];
|
||||
}
|
||||
|
||||
def ArmPreservesDocs : Documentation {
|
||||
let Category = DocCatArmSmeAttributes;
|
||||
let Content = [{
|
||||
The ``__arm_preserves`` keyword applies to prototyped function types and
|
||||
specifies that the function does not read a given state S and returns
|
||||
with state S unchanged.
|
||||
|
||||
The attribute takes string arguments to instruct the compiler which state
|
||||
is shared. The supported states for S are:
|
||||
|
||||
* ``"za"`` for Matrix Storage (requires SME)
|
||||
|
||||
The attributes ``__arm_in(S)``, ``__arm_out(S)``, ``__arm_inout(S)`` and
|
||||
``__arm_preserves(S)`` are all mutually exclusive for the same state S.
|
||||
}];
|
||||
}
|
||||
|
||||
def ArmSmeLocallyStreamingDocs : Documentation {
|
||||
let Category = DocCatArmSmeAttributes;
|
||||
@ -6907,13 +6950,18 @@ at the end of the function.
|
||||
}];
|
||||
}
|
||||
|
||||
def ArmSmeNewZADocs : Documentation {
|
||||
def ArmNewDocs : Documentation {
|
||||
let Category = DocCatArmSmeAttributes;
|
||||
let Content = [{
|
||||
The ``__arm_new_za`` keyword applies to function declarations and specifies
|
||||
that the function will be set up with a fresh ZA context.
|
||||
The ``__arm_new`` keyword applies to function declarations and specifies
|
||||
that the function will create a new scope for state S.
|
||||
|
||||
This means that:
|
||||
The attribute takes string arguments to instruct the compiler for which state
|
||||
to create new scope. The supported states for S are:
|
||||
|
||||
* ``"za"`` for Matrix Storage (requires SME)
|
||||
|
||||
For state ``"za"``, this means that:
|
||||
|
||||
* the function requires that the target processor implements the Scalable Matrix
|
||||
Extension (SME).
|
||||
@ -6924,8 +6972,8 @@ This means that:
|
||||
|
||||
* the function will disable PSTATE.ZA (by setting it to 0) before returning.
|
||||
|
||||
For ``__arm_new_za`` functions Clang will set up the ZA context automatically
|
||||
on entry to the function, and disable it before returning. For example, if ZA is
|
||||
For ``__arm_new("za")`` functions Clang will set up the ZA context automatically
|
||||
on entry to the function and disable it before returning. For example, if ZA is
|
||||
in a dormant state Clang will generate the code to commit a lazy-save and set up
|
||||
a new ZA state before executing user code.
|
||||
}];
|
||||
|
@ -255,6 +255,19 @@ protected:
|
||||
return SpellingIndex != SpellingNotCalculated;
|
||||
}
|
||||
};
|
||||
|
||||
inline bool doesKeywordAttributeTakeArgs(tok::TokenKind Kind) {
|
||||
switch (Kind) {
|
||||
default:
|
||||
return false;
|
||||
#define KEYWORD_ATTRIBUTE(NAME, HASARG, ...) \
|
||||
case tok::kw_##NAME: \
|
||||
return HASARG;
|
||||
#include "clang/Basic/RegularKeywordAttrInfo.inc"
|
||||
#undef KEYWORD_ATTRIBUTE
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace clang
|
||||
|
||||
#endif // LLVM_CLANG_BASIC_ATTRIBUTECOMMONINFO_H
|
||||
|
@ -255,6 +255,10 @@ TARGET_BUILTIN(__builtin_amdgcn_sudot4, "iIbiIbiiIb", "nc", "dot8-insts")
|
||||
TARGET_BUILTIN(__builtin_amdgcn_sdot8, "SiSiSiSiIb", "nc", "dot1-insts")
|
||||
TARGET_BUILTIN(__builtin_amdgcn_udot8, "UiUiUiUiIb", "nc", "dot7-insts")
|
||||
TARGET_BUILTIN(__builtin_amdgcn_sudot8, "iIbiIbiiIb", "nc", "dot8-insts")
|
||||
TARGET_BUILTIN(__builtin_amdgcn_dot4_f32_fp8_bf8, "fUiUif", "nc", "gfx12-insts")
|
||||
TARGET_BUILTIN(__builtin_amdgcn_dot4_f32_bf8_fp8, "fUiUif", "nc", "gfx12-insts")
|
||||
TARGET_BUILTIN(__builtin_amdgcn_dot4_f32_fp8_fp8, "fUiUif", "nc", "gfx12-insts")
|
||||
TARGET_BUILTIN(__builtin_amdgcn_dot4_f32_bf8_bf8, "fUiUif", "nc", "gfx12-insts")
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// GFX10+ only builtins.
|
||||
@ -397,19 +401,20 @@ TARGET_BUILTIN(__builtin_amdgcn_smfmac_f32_32x32x32_bf8_fp8, "V16fV2iV4iV16fiIiI
|
||||
TARGET_BUILTIN(__builtin_amdgcn_smfmac_f32_32x32x32_fp8_bf8, "V16fV2iV4iV16fiIiIi", "nc", "fp8-insts")
|
||||
TARGET_BUILTIN(__builtin_amdgcn_smfmac_f32_32x32x32_fp8_fp8, "V16fV2iV4iV16fiIiIi", "nc", "fp8-insts")
|
||||
|
||||
TARGET_BUILTIN(__builtin_amdgcn_cvt_f32_bf8, "fiIi", "nc", "fp8-insts")
|
||||
TARGET_BUILTIN(__builtin_amdgcn_cvt_f32_fp8, "fiIi", "nc", "fp8-insts")
|
||||
TARGET_BUILTIN(__builtin_amdgcn_cvt_pk_f32_bf8, "V2fiIb", "nc", "fp8-insts")
|
||||
TARGET_BUILTIN(__builtin_amdgcn_cvt_pk_f32_fp8, "V2fiIb", "nc", "fp8-insts")
|
||||
TARGET_BUILTIN(__builtin_amdgcn_cvt_pk_bf8_f32, "iffiIb", "nc", "fp8-insts")
|
||||
TARGET_BUILTIN(__builtin_amdgcn_cvt_pk_fp8_f32, "iffiIb", "nc", "fp8-insts")
|
||||
TARGET_BUILTIN(__builtin_amdgcn_cvt_sr_bf8_f32, "ifiiIi", "nc", "fp8-insts")
|
||||
TARGET_BUILTIN(__builtin_amdgcn_cvt_sr_fp8_f32, "ifiiIi", "nc", "fp8-insts")
|
||||
TARGET_BUILTIN(__builtin_amdgcn_cvt_f32_bf8, "fiIi", "nc", "fp8-conversion-insts")
|
||||
TARGET_BUILTIN(__builtin_amdgcn_cvt_f32_fp8, "fiIi", "nc", "fp8-conversion-insts")
|
||||
TARGET_BUILTIN(__builtin_amdgcn_cvt_pk_f32_bf8, "V2fiIb", "nc", "fp8-conversion-insts")
|
||||
TARGET_BUILTIN(__builtin_amdgcn_cvt_pk_f32_fp8, "V2fiIb", "nc", "fp8-conversion-insts")
|
||||
TARGET_BUILTIN(__builtin_amdgcn_cvt_pk_bf8_f32, "iffiIb", "nc", "fp8-conversion-insts")
|
||||
TARGET_BUILTIN(__builtin_amdgcn_cvt_pk_fp8_f32, "iffiIb", "nc", "fp8-conversion-insts")
|
||||
TARGET_BUILTIN(__builtin_amdgcn_cvt_sr_bf8_f32, "ifiiIi", "nc", "fp8-conversion-insts")
|
||||
TARGET_BUILTIN(__builtin_amdgcn_cvt_sr_fp8_f32, "ifiiIi", "nc", "fp8-conversion-insts")
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// GFX12+ only builtins.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
TARGET_BUILTIN(__builtin_amdgcn_s_sleep_var, "vUi", "n", "gfx12-insts")
|
||||
TARGET_BUILTIN(__builtin_amdgcn_permlane16_var, "UiUiUiUiIbIb", "nc", "gfx12-insts")
|
||||
TARGET_BUILTIN(__builtin_amdgcn_permlanex16_var, "UiUiUiUiIbIb", "nc", "gfx12-insts")
|
||||
TARGET_BUILTIN(__builtin_amdgcn_s_barrier_signal, "vIi", "n", "gfx12-insts")
|
||||
@ -423,6 +428,13 @@ TARGET_BUILTIN(__builtin_amdgcn_s_wakeup_barrier, "vi", "n", "gfx12-insts")
|
||||
TARGET_BUILTIN(__builtin_amdgcn_s_barrier_leave, "b", "n", "gfx12-insts")
|
||||
TARGET_BUILTIN(__builtin_amdgcn_s_get_barrier_state, "Uii", "n", "gfx12-insts")
|
||||
|
||||
TARGET_BUILTIN(__builtin_amdgcn_global_load_tr_v2i32, "V2iV2i*1", "nc", "gfx12-insts,wavefrontsize32")
|
||||
TARGET_BUILTIN(__builtin_amdgcn_global_load_tr_v8i16, "V8sV8s*1", "nc", "gfx12-insts,wavefrontsize32")
|
||||
TARGET_BUILTIN(__builtin_amdgcn_global_load_tr_v8f16, "V8hV8h*1", "nc", "gfx12-insts,wavefrontsize32")
|
||||
|
||||
TARGET_BUILTIN(__builtin_amdgcn_global_load_tr_i32, "ii*1", "nc", "gfx12-insts,wavefrontsize64")
|
||||
TARGET_BUILTIN(__builtin_amdgcn_global_load_tr_v4i16, "V4sV4s*1", "nc", "gfx12-insts,wavefrontsize64")
|
||||
TARGET_BUILTIN(__builtin_amdgcn_global_load_tr_v4f16, "V4hV4h*1", "nc", "gfx12-insts,wavefrontsize64")
|
||||
|
||||
#undef BUILTIN
|
||||
#undef TARGET_BUILTIN
|
||||
|
@ -51,3 +51,8 @@ TARGET_BUILTIN(__builtin_loongarch_iocsrwr_d, "vUWiUi", "nc", "64bit")
|
||||
|
||||
TARGET_BUILTIN(__builtin_loongarch_lddir_d, "WiWiIUWi", "nc", "64bit")
|
||||
TARGET_BUILTIN(__builtin_loongarch_ldpte_d, "vWiIUWi", "nc", "64bit")
|
||||
|
||||
TARGET_BUILTIN(__builtin_loongarch_frecipe_s, "ff", "nc", "f,frecipe")
|
||||
TARGET_BUILTIN(__builtin_loongarch_frecipe_d, "dd", "nc", "d,frecipe")
|
||||
TARGET_BUILTIN(__builtin_loongarch_frsqrte_s, "ff", "nc", "f,frecipe")
|
||||
TARGET_BUILTIN(__builtin_loongarch_frsqrte_d, "dd", "nc", "d,frecipe")
|
||||
|
@ -657,9 +657,15 @@ TARGET_BUILTIN(__builtin_lasx_xvfsqrt_d, "V4dV4d", "nc", "lasx")
|
||||
TARGET_BUILTIN(__builtin_lasx_xvfrecip_s, "V8fV8f", "nc", "lasx")
|
||||
TARGET_BUILTIN(__builtin_lasx_xvfrecip_d, "V4dV4d", "nc", "lasx")
|
||||
|
||||
TARGET_BUILTIN(__builtin_lasx_xvfrecipe_s, "V8fV8f", "nc", "lasx,frecipe")
|
||||
TARGET_BUILTIN(__builtin_lasx_xvfrecipe_d, "V4dV4d", "nc", "lasx,frecipe")
|
||||
|
||||
TARGET_BUILTIN(__builtin_lasx_xvfrsqrt_s, "V8fV8f", "nc", "lasx")
|
||||
TARGET_BUILTIN(__builtin_lasx_xvfrsqrt_d, "V4dV4d", "nc", "lasx")
|
||||
|
||||
TARGET_BUILTIN(__builtin_lasx_xvfrsqrte_s, "V8fV8f", "nc", "lasx,frecipe")
|
||||
TARGET_BUILTIN(__builtin_lasx_xvfrsqrte_d, "V4dV4d", "nc", "lasx,frecipe")
|
||||
|
||||
TARGET_BUILTIN(__builtin_lasx_xvfcvtl_s_h, "V8fV16s", "nc", "lasx")
|
||||
TARGET_BUILTIN(__builtin_lasx_xvfcvth_s_h, "V8fV16s", "nc", "lasx")
|
||||
TARGET_BUILTIN(__builtin_lasx_xvfcvtl_d_s, "V4dV8f", "nc", "lasx")
|
||||
|
@ -641,9 +641,15 @@ TARGET_BUILTIN(__builtin_lsx_vfsqrt_d, "V2dV2d", "nc", "lsx")
|
||||
TARGET_BUILTIN(__builtin_lsx_vfrecip_s, "V4fV4f", "nc", "lsx")
|
||||
TARGET_BUILTIN(__builtin_lsx_vfrecip_d, "V2dV2d", "nc", "lsx")
|
||||
|
||||
TARGET_BUILTIN(__builtin_lsx_vfrecipe_s, "V4fV4f", "nc", "lsx,frecipe")
|
||||
TARGET_BUILTIN(__builtin_lsx_vfrecipe_d, "V2dV2d", "nc", "lsx,frecipe")
|
||||
|
||||
TARGET_BUILTIN(__builtin_lsx_vfrsqrt_s, "V4fV4f", "nc", "lsx")
|
||||
TARGET_BUILTIN(__builtin_lsx_vfrsqrt_d, "V2dV2d", "nc", "lsx")
|
||||
|
||||
TARGET_BUILTIN(__builtin_lsx_vfrsqrte_s, "V4fV4f", "nc", "lsx,frecipe")
|
||||
TARGET_BUILTIN(__builtin_lsx_vfrsqrte_d, "V2dV2d", "nc", "lsx,frecipe")
|
||||
|
||||
TARGET_BUILTIN(__builtin_lsx_vfcvtl_s_h, "V4fV8s", "nc", "lsx")
|
||||
TARGET_BUILTIN(__builtin_lsx_vfcvtl_d_s, "V2dV4f", "nc", "lsx")
|
||||
|
||||
|
@ -110,6 +110,10 @@ BUILTIN(__builtin_ppc_fctiw, "dd", "")
|
||||
BUILTIN(__builtin_ppc_fctiwz, "dd", "")
|
||||
BUILTIN(__builtin_ppc_fctudz, "dd", "")
|
||||
BUILTIN(__builtin_ppc_fctuwz, "dd", "")
|
||||
|
||||
// fence builtin prevents all instructions moved across it
|
||||
BUILTIN(__builtin_ppc_fence, "v", "")
|
||||
|
||||
BUILTIN(__builtin_ppc_swdiv_nochk, "ddd", "")
|
||||
BUILTIN(__builtin_ppc_swdivs_nochk, "fff", "")
|
||||
BUILTIN(__builtin_ppc_alignx, "vIivC*", "nc")
|
||||
|
@ -12,6 +12,9 @@
|
||||
// that have enumeration type and VALUE_CODEGENOPT is a code
|
||||
// generation option that describes a value rather than a flag.
|
||||
//
|
||||
// AFFECTING_VALUE_CODEGENOPT is used for code generation options that can
|
||||
// affect the AST.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
#ifndef CODEGENOPT
|
||||
# error Define the CODEGENOPT macro to handle language options
|
||||
@ -27,6 +30,11 @@ CODEGENOPT(Name, Bits, Default)
|
||||
CODEGENOPT(Name, Bits, Default)
|
||||
#endif
|
||||
|
||||
#ifndef AFFECTING_VALUE_CODEGENOPT
|
||||
# define AFFECTING_VALUE_CODEGENOPT(Name, Bits, Default) \
|
||||
VALUE_CODEGENOPT(Name, Bits, Default)
|
||||
#endif
|
||||
|
||||
CODEGENOPT(DisableIntegratedAS, 1, 0) ///< -no-integrated-as
|
||||
CODEGENOPT(RelaxELFRelocations, 1, 1) ///< -Wa,-mrelax-relocations={yes,no}
|
||||
CODEGENOPT(AsmVerbose , 1, 0) ///< -dA, -fverbose-asm.
|
||||
@ -193,8 +201,10 @@ ENUM_CODEGENOPT(ObjCDispatchMethod, ObjCDispatchMethodKind, 2, Legacy)
|
||||
CODEGENOPT(ObjCConvertMessagesToRuntimeCalls , 1, 1)
|
||||
CODEGENOPT(ObjCAvoidHeapifyLocalBlocks, 1, 0)
|
||||
|
||||
VALUE_CODEGENOPT(OptimizationLevel, 2, 0) ///< The -O[0-3] option specified.
|
||||
VALUE_CODEGENOPT(OptimizeSize, 2, 0) ///< If -Os (==1) or -Oz (==2) is specified.
|
||||
|
||||
// The optimization options affect frontend options, whicn in turn do affect the AST.
|
||||
AFFECTING_VALUE_CODEGENOPT(OptimizationLevel, 2, 0) ///< The -O[0-3] option specified.
|
||||
AFFECTING_VALUE_CODEGENOPT(OptimizeSize, 2, 0) ///< If -Os (==1) or -Oz (==2) is specified.
|
||||
|
||||
CODEGENOPT(AtomicProfileUpdate , 1, 0) ///< Set -fprofile-update=atomic
|
||||
/// Choose profile instrumenation kind or no instrumentation.
|
||||
@ -437,3 +447,4 @@ CODEGENOPT(CtorDtorReturnThis, 1, 0)
|
||||
#undef CODEGENOPT
|
||||
#undef ENUM_CODEGENOPT
|
||||
#undef VALUE_CODEGENOPT
|
||||
#undef AFFECTING_VALUE_CODEGENOPT
|
||||
|
@ -494,6 +494,9 @@ public:
|
||||
return getProfileInstr() == ProfileCSIRInstr;
|
||||
}
|
||||
|
||||
/// Check if any form of instrumentation is on.
|
||||
bool hasProfileInstr() const { return getProfileInstr() != ProfileNone; }
|
||||
|
||||
/// Check if Clang profile use is on.
|
||||
bool hasProfileClangUse() const {
|
||||
return getProfileUse() == ProfileClangInstr;
|
||||
|
@ -70,6 +70,10 @@ def warn_pragma_debug_missing_argument : Warning<
|
||||
def warn_pragma_debug_unexpected_argument : Warning<
|
||||
"unexpected argument to debug command">, InGroup<IgnoredPragmas>;
|
||||
|
||||
def warn_fp_nan_inf_when_disabled : Warning<
|
||||
"use of %select{infinity|NaN}0%select{| via a macro}1 is undefined behavior "
|
||||
"due to the currently enabled floating-point options">,
|
||||
InGroup<DiagGroup<"nan-infinity-disabled">>;
|
||||
}
|
||||
|
||||
// Parse && Sema
|
||||
@ -358,9 +362,9 @@ def err_cannot_open_file : Error<"cannot open file '%0': %1">, DefaultFatal;
|
||||
def err_file_modified : Error<
|
||||
"file '%0' modified since it was first processed">, DefaultFatal;
|
||||
def err_file_too_large : Error<
|
||||
"sorry, unsupported: file '%0' is too large for Clang to process">;
|
||||
"file '%0' is too large for Clang to process">;
|
||||
def err_sloc_space_too_large : Error<
|
||||
"sorry, the translation unit is too large for Clang to process: ran out of source locations">, DefaultFatal;
|
||||
"translation unit is too large for Clang to process: ran out of source locations">, DefaultFatal;
|
||||
def err_unsupported_bom : Error<"%0 byte order mark detected in '%1', but "
|
||||
"encoding is not supported">, DefaultFatal;
|
||||
def err_unable_to_rename_temp : Error<
|
||||
|
@ -427,6 +427,8 @@ def warn_drv_clang_unsupported : Warning<
|
||||
"the clang compiler does not support '%0'">;
|
||||
def warn_drv_deprecated_arg : Warning<
|
||||
"argument '%0' is deprecated, use '%1' instead">, InGroup<Deprecated>;
|
||||
def warn_drv_deprecated_custom : Warning<
|
||||
"argument '%0' is deprecated, %1">, InGroup<Deprecated>;
|
||||
def warn_drv_assuming_mfloat_abi_is : Warning<
|
||||
"unknown platform, assuming -mfloat-abi=%0">;
|
||||
def warn_drv_unsupported_float_abi_by_lib : Warning<
|
||||
@ -472,7 +474,7 @@ def warn_unsupported_branch_protection: Warning <
|
||||
def err_sls_hardening_arm_not_supported : Error<
|
||||
"-mharden-sls is only supported on armv7-a or later">;
|
||||
def warn_drv_large_data_threshold_invalid_code_model: Warning<
|
||||
"'%0' only applies to medium code model">,
|
||||
"'%0' only applies to medium and large code models">,
|
||||
InGroup<UnusedCommandLineArgument>;
|
||||
|
||||
def note_drv_command_failed_diag_msg : Note<
|
||||
@ -656,6 +658,13 @@ def err_drv_trivial_auto_var_init_stop_after_missing_dependency : Error<
|
||||
def err_drv_trivial_auto_var_init_stop_after_invalid_value : Error<
|
||||
"'-ftrivial-auto-var-init-stop-after=*' only accepts positive integers">;
|
||||
|
||||
def err_drv_trivial_auto_var_init_max_size_missing_dependency : Error<
|
||||
"'-ftrivial-auto-var-init-max-size=*' is used without "
|
||||
"'-ftrivial-auto-var-init=zero' or '-ftrivial-auto-var-init=pattern'">;
|
||||
|
||||
def err_drv_trivial_auto_var_init_max_size_invalid_value : Error<
|
||||
"'-ftrivial-auto-var-init-max-size=*' only accepts positive integers (in bytes)">;
|
||||
|
||||
def warn_drv_msp430_hwmult_unsupported : Warning<
|
||||
"the given MCU does not support hardware multiply, but '-mhwmult' is set to "
|
||||
"%0">, InGroup<InvalidCommandLineArgument>;
|
||||
@ -735,10 +744,10 @@ def err_drv_dxc_missing_target_profile : Error<
|
||||
def err_drv_hlsl_unsupported_target : Error<
|
||||
"HLSL code generation is unsupported for target '%0'">;
|
||||
def err_drv_hlsl_bad_shader_required_in_target : Error<
|
||||
"shader %select{model|stage}0 is required in target '%1' for HLSL code generation">;
|
||||
"%select{shader model|Vulkan environment|shader stage}0 is required as %select{OS|environment}1 in target '%2' for HLSL code generation">;
|
||||
|
||||
def err_drv_hlsl_bad_shader_unsupported : Error<
|
||||
"shader %select{model|stage}0 '%1' in target '%2' is invalid for HLSL code generation">;
|
||||
"%select{shader model|Vulkan environment|shader stage}0 '%1' in target '%2' is invalid for HLSL code generation">;
|
||||
def warn_drv_dxc_missing_dxv : Warning<"dxv not found. "
|
||||
"Resulting DXIL will not be validated or signed for use in release environments.">,
|
||||
InGroup<DXILValidation>;
|
||||
|
@ -1366,6 +1366,15 @@ def err_acc_invalid_open_paren
|
||||
: Error<"expected clause-list or newline in OpenACC directive">;
|
||||
def err_acc_invalid_default_clause_kind
|
||||
: Error<"invalid value for 'default' clause; expected 'present' or 'none'">;
|
||||
def err_acc_invalid_tag_kind
|
||||
: Error<"invalid tag %0 on '%1' %select{directive|clause}2">;
|
||||
def err_acc_expected_reduction_operator
|
||||
: Error<"missing reduction operator, expected '+', '*', 'max', 'min', '&', "
|
||||
"'|', '^', '&&', or '||', follwed by a ':'">;
|
||||
def err_acc_invalid_reduction_operator
|
||||
: Error<"invalid reduction operator, expected '+', '*', 'max', 'min', "
|
||||
"'&', '|', '^', '&&', or '||'">;
|
||||
def err_acc_incorrect_bind_arg : Error<"expected identifier or string literal">;
|
||||
|
||||
// OpenMP support.
|
||||
def warn_pragma_omp_ignored : Warning<
|
||||
@ -1609,6 +1618,9 @@ def err_pragma_invalid_keyword : Error<
|
||||
def err_pragma_pipeline_invalid_keyword : Error<
|
||||
"invalid argument; expected 'disable'">;
|
||||
|
||||
// API notes.
|
||||
def err_type_unparsed : Error<"unparsed tokens following type">;
|
||||
|
||||
// Pragma unroll support.
|
||||
def warn_pragma_unroll_cuda_value_in_parens : Warning<
|
||||
"argument to '#pragma unroll' should not be in parentheses in CUDA C/C++">,
|
||||
|
@ -692,6 +692,13 @@ def warn_maybe_falloff_nonvoid_function : Warning<
|
||||
def warn_falloff_nonvoid_function : Warning<
|
||||
"non-void function does not return a value">,
|
||||
InGroup<ReturnType>;
|
||||
def warn_const_attr_with_pure_attr : Warning<
|
||||
"'const' attribute imposes more restrictions; 'pure' attribute ignored">,
|
||||
InGroup<IgnoredAttributes>;
|
||||
def warn_pure_function_returns_void : Warning<
|
||||
"'%select{pure|const}0' attribute on function returning 'void'; attribute ignored">,
|
||||
InGroup<IgnoredAttributes>;
|
||||
|
||||
def err_maybe_falloff_nonvoid_block : Error<
|
||||
"non-void block does not return a value in all control paths">;
|
||||
def err_falloff_nonvoid_block : Error<
|
||||
@ -2411,7 +2418,8 @@ def err_auto_not_allowed : Error<
|
||||
"|in type allocated by 'new'|in K&R-style function parameter"
|
||||
"|in template parameter|in friend declaration|in function prototype that is "
|
||||
"not a function declaration|in requires expression parameter"
|
||||
"|in array declaration}1">;
|
||||
"|in array declaration"
|
||||
"|in declaration of conversion function template}1">;
|
||||
def err_dependent_deduced_tst : Error<
|
||||
"typename specifier refers to "
|
||||
"%select{class template|function template|variable template|alias template|"
|
||||
@ -3113,6 +3121,8 @@ def err_musttail_scope : Error<
|
||||
"cannot perform a tail call from this return statement">;
|
||||
def err_musttail_no_variadic : Error<
|
||||
"%0 attribute may not be used with variadic functions">;
|
||||
def err_musttail_no_return : Error<
|
||||
"%0 attribute may not be used with no-return-attribute functions">;
|
||||
|
||||
def err_nsobject_attribute : Error<
|
||||
"'NSObject' attribute is for pointer types only">;
|
||||
@ -3160,6 +3170,9 @@ def warn_attribute_arm_sm_incompat_builtin : Warning<
|
||||
def warn_attribute_arm_za_builtin_no_za_state : Warning<
|
||||
"builtin call is not valid when calling from a function without active ZA state">,
|
||||
InGroup<DiagGroup<"undefined-arm-za">>;
|
||||
def warn_attribute_arm_zt0_builtin_no_zt0_state : Warning<
|
||||
"builtin call is not valid when calling from a function without active ZT0 state">,
|
||||
InGroup<DiagGroup<"undefined-arm-zt0">>;
|
||||
def err_sve_vector_in_non_sve_target : Error<
|
||||
"SVE vector type %0 cannot be used in a target without sve">;
|
||||
def err_attribute_riscv_rvv_bits_unsupported : Error<
|
||||
@ -3696,10 +3709,20 @@ def err_sme_call_in_non_sme_target : Error<
|
||||
"call to a streaming function requires 'sme'">;
|
||||
def err_sme_za_call_no_za_state : Error<
|
||||
"call to a shared ZA function requires the caller to have ZA state">;
|
||||
def err_sme_zt0_call_no_zt0_state : Error<
|
||||
"call to a shared ZT0 function requires the caller to have ZT0 state">;
|
||||
def err_sme_definition_using_sm_in_non_sme_target : Error<
|
||||
"function executed in streaming-SVE mode requires 'sme'">;
|
||||
def err_sme_definition_using_za_in_non_sme_target : Error<
|
||||
"function using ZA state requires 'sme'">;
|
||||
def err_sme_definition_using_zt0_in_non_sme2_target : Error<
|
||||
"function using ZT0 state requires 'sme2'">;
|
||||
def err_conflicting_attributes_arm_state : Error<
|
||||
"conflicting attributes for state '%0'">;
|
||||
def err_unknown_arm_state : Error<
|
||||
"unknown state '%0'">;
|
||||
def err_missing_arm_state : Error<
|
||||
"missing state for %0">;
|
||||
def err_cconv_change : Error<
|
||||
"function declared '%0' here was previously declared "
|
||||
"%select{'%2'|without calling convention}1">;
|
||||
@ -5138,8 +5161,6 @@ def err_non_type_template_arg_subobject : Error<
|
||||
"non-type template argument refers to subobject '%0'">;
|
||||
def err_non_type_template_arg_addr_label_diff : Error<
|
||||
"template argument / label address difference / what did you expect?">;
|
||||
def err_non_type_template_arg_unsupported : Error<
|
||||
"sorry, non-type template argument of type %0 is not yet supported">;
|
||||
def err_template_arg_not_convertible : Error<
|
||||
"non-type template argument of type %0 cannot be converted to a value "
|
||||
"of type %1">;
|
||||
@ -5191,9 +5212,6 @@ def err_template_arg_not_object_or_func : Error<
|
||||
"non-type template argument does not refer to an object or function">;
|
||||
def err_template_arg_not_pointer_to_member_form : Error<
|
||||
"non-type template argument is not a pointer to member constant">;
|
||||
def err_template_arg_member_ptr_base_derived_not_supported : Error<
|
||||
"sorry, non-type template argument of pointer-to-member type %1 that refers "
|
||||
"to member %q0 of a different class is not supported yet">;
|
||||
def err_template_arg_invalid : Error<
|
||||
"non-type template argument '%0' is invalid">;
|
||||
def ext_template_arg_extra_parens : ExtWarn<
|
||||
@ -7000,6 +7018,11 @@ def err_member_decl_does_not_match : Error<
|
||||
"does not match any declaration in %1">;
|
||||
def err_friend_decl_with_def_arg_must_be_def : Error<
|
||||
"friend declaration specifying a default argument must be a definition">;
|
||||
def err_friend_decl_with_enclosing_temp_constraint_must_be_def : Error<
|
||||
"friend declaration with a constraint that depends on an enclosing "
|
||||
"template parameter must be a definition">;
|
||||
def err_non_temp_friend_decl_with_requires_clause_must_be_def : Error<
|
||||
"non-template friend declaration with a requires clause must be a definition">;
|
||||
def err_friend_decl_with_def_arg_redeclared : Error<
|
||||
"friend declaration specifying a default argument must be the only declaration">;
|
||||
def err_friend_decl_does_not_match : Error<
|
||||
@ -9926,10 +9949,10 @@ def warn_new_dangling_initializer_list : Warning<
|
||||
"will be destroyed at the end of the full-expression">,
|
||||
InGroup<DanglingInitializerList>;
|
||||
def warn_unsupported_lifetime_extension : Warning<
|
||||
"sorry, lifetime extension of "
|
||||
"lifetime extension of "
|
||||
"%select{temporary|backing array of initializer list}0 created "
|
||||
"by aggregate initialization using default member initializer "
|
||||
"is not supported; lifetime of %select{temporary|backing array}0 "
|
||||
"by aggregate initialization using a default member initializer "
|
||||
"is not yet supported; lifetime of %select{temporary|backing array}0 "
|
||||
"will end at the end of the full-expression">, InGroup<Dangling>;
|
||||
|
||||
// For non-floating point, expressions of the form x == x or x != x
|
||||
|
@ -129,10 +129,8 @@ def warn_module_system_bit_conflict : Warning<
|
||||
"as a non-system module; any difference in diagnostic options will be ignored">,
|
||||
InGroup<ModuleConflict>;
|
||||
|
||||
def warn_reading_std_cxx_module_by_implicit_paths : Warning<
|
||||
"it is deprecated to read module '%0' implicitly; it is going to be removed in clang 18; "
|
||||
"consider to specify the dependencies explicitly">,
|
||||
InGroup<DiagGroup<"read-modules-implicitly">>;
|
||||
def err_failed_to_find_module_file : Error<
|
||||
"failed to find module file for module '%0'">;
|
||||
} // let CategoryName
|
||||
|
||||
let CategoryName = "AST Serialization Issue" in {
|
||||
|
@ -269,6 +269,10 @@ EXTENSION(cxx_fixed_enum, true)
|
||||
EXTENSION(cxx_binary_literals, true)
|
||||
EXTENSION(cxx_init_captures, LangOpts.CPlusPlus11)
|
||||
EXTENSION(cxx_variable_templates, LangOpts.CPlusPlus)
|
||||
//C++20
|
||||
EXTENSION(cxx_generalized_nttp, LangOpts.CPlusPlus20)
|
||||
//C++23
|
||||
EXTENSION(cxx_explicit_this_parameter, LangOpts.CPlusPlus23)
|
||||
// Miscellaneous language extensions
|
||||
EXTENSION(overloadable_unmarked, true)
|
||||
EXTENSION(pragma_clang_attribute_namespaces, true)
|
||||
|
@ -220,7 +220,7 @@ BENIGN_LANGOPT(NoSignedZero , 1, 0, "Permit Floating Point optimization wit
|
||||
BENIGN_LANGOPT(AllowRecip , 1, 0, "Permit Floating Point reciprocal")
|
||||
BENIGN_LANGOPT(ApproxFunc , 1, 0, "Permit Floating Point approximation")
|
||||
|
||||
ENUM_LANGOPT(ComplexRange, ComplexRangeKind, 2, CX_Full, "Enable use of range reduction for complex arithmetics.")
|
||||
ENUM_LANGOPT(ComplexRange, ComplexRangeKind, 2, CX_None, "Enable use of range reduction for complex arithmetics.")
|
||||
|
||||
BENIGN_LANGOPT(ObjCGCBitmapPrint , 1, 0, "printing of GC's bitmap layout for __weak/__strong ivars")
|
||||
|
||||
@ -260,6 +260,7 @@ LANGOPT(OpenMPTeamSubscription , 1, 0, "Assume distributed loops do not have mo
|
||||
LANGOPT(OpenMPNoThreadState , 1, 0, "Assume that no thread in a parallel region will modify an ICV.")
|
||||
LANGOPT(OpenMPNoNestedParallelism , 1, 0, "Assume that no thread in a parallel region will encounter a parallel region")
|
||||
LANGOPT(OpenMPOffloadMandatory , 1, 0, "Assert that offloading is mandatory and do not create a host fallback.")
|
||||
LANGOPT(OpenMPForceUSM , 1, 0, "Enable OpenMP unified shared memory mode via compiler.")
|
||||
LANGOPT(NoGPULib , 1, 0, "Indicate a build without the standard GPU libraries.")
|
||||
LANGOPT(RenderScript , 1, 0, "RenderScript")
|
||||
|
||||
@ -308,7 +309,8 @@ BENIGN_LANGOPT(IgnoreXCOFFVisibility, 1, 0, "All the visibility attributes that
|
||||
BENIGN_LANGOPT(VisibilityInlinesHiddenStaticLocalVar, 1, 0,
|
||||
"hidden visibility for static local variables in inline C++ "
|
||||
"methods when -fvisibility-inlines hidden is enabled")
|
||||
LANGOPT(GlobalAllocationFunctionVisibilityHidden , 1, 0, "hidden visibility for global operator new and delete declaration")
|
||||
ENUM_LANGOPT(GlobalAllocationFunctionVisibility, VisibilityForcedKinds, 3, VisibilityForcedKinds::ForceDefault,
|
||||
"How to apply visibility to global operator new and delete declarations")
|
||||
LANGOPT(NewInfallible , 1, 0, "Treats throwing global C++ operator new as always returning valid memory (annotates with __attribute__((returns_nonnull)) and throw()). This is detectable in source.")
|
||||
BENIGN_LANGOPT(ParseUnknownAnytype, 1, 0, "__unknown_anytype")
|
||||
BENIGN_LANGOPT(DebuggerSupport , 1, 0, "debugger support")
|
||||
@ -359,16 +361,16 @@ BENIGN_ENUM_LANGOPT(TypeVisibilityMode, Visibility, 3, DefaultVisibility,
|
||||
"default visibility for types [-ftype-visibility]")
|
||||
LANGOPT(SetVisibilityForExternDecls, 1, 0,
|
||||
"apply global symbol visibility to external declarations without an explicit visibility")
|
||||
LANGOPT(VisibilityFromDLLStorageClass, 1, 0,
|
||||
"set the visiblity of globals from their DLL storage class [-fvisibility-from-dllstorageclass]")
|
||||
ENUM_LANGOPT(DLLExportVisibility, Visibility, 3, DefaultVisibility,
|
||||
"visibility for functions and variables with dllexport annotations [-fvisibility-from-dllstorageclass]")
|
||||
ENUM_LANGOPT(NoDLLStorageClassVisibility, Visibility, 3, HiddenVisibility,
|
||||
"visibility for functions and variables without an explicit DLL storage class [-fvisibility-from-dllstorageclass]")
|
||||
ENUM_LANGOPT(ExternDeclDLLImportVisibility, Visibility, 3, DefaultVisibility,
|
||||
"visibility for external declarations with dllimport annotations [-fvisibility-from-dllstorageclass]")
|
||||
ENUM_LANGOPT(ExternDeclNoDLLStorageClassVisibility, Visibility, 3, HiddenVisibility,
|
||||
"visibility for external declarations without an explicit DLL storage class [-fvisibility-from-dllstorageclass]")
|
||||
BENIGN_LANGOPT(VisibilityFromDLLStorageClass, 1, 0,
|
||||
"override the visibility of globals based on their final DLL storage class [-fvisibility-from-dllstorageclass]")
|
||||
BENIGN_ENUM_LANGOPT(DLLExportVisibility, VisibilityFromDLLStorageClassKinds, 3, VisibilityFromDLLStorageClassKinds::Default,
|
||||
"how to adjust the visibility for functions and variables with dllexport annotations [-fvisibility-dllexport]")
|
||||
BENIGN_ENUM_LANGOPT(NoDLLStorageClassVisibility, VisibilityFromDLLStorageClassKinds, 3, VisibilityFromDLLStorageClassKinds::Hidden,
|
||||
"how to adjust the visibility for functions and variables without an explicit DLL storage class [-fvisibility-nodllstorageclass]")
|
||||
BENIGN_ENUM_LANGOPT(ExternDeclDLLImportVisibility, VisibilityFromDLLStorageClassKinds, 3, VisibilityFromDLLStorageClassKinds::Default,
|
||||
"how to adjust the visibility for external declarations with dllimport annotations [-fvisibility-externs-dllimport]")
|
||||
BENIGN_ENUM_LANGOPT(ExternDeclNoDLLStorageClassVisibility, VisibilityFromDLLStorageClassKinds, 3, VisibilityFromDLLStorageClassKinds::Hidden,
|
||||
"how to adjust the visibility for external declarations without an explicit DLL storage class [-fvisibility-externs-nodllstorageclass]")
|
||||
BENIGN_LANGOPT(SemanticInterposition , 1, 0, "semantic interposition")
|
||||
BENIGN_LANGOPT(HalfNoSemanticInterposition, 1, 0,
|
||||
"Like -fno-semantic-interposition but don't use local aliases")
|
||||
@ -378,6 +380,8 @@ ENUM_LANGOPT(TrivialAutoVarInit, TrivialAutoVarInitKind, 2, TrivialAutoVarInitKi
|
||||
"trivial automatic variable initialization")
|
||||
VALUE_LANGOPT(TrivialAutoVarInitStopAfter, 32, 0,
|
||||
"stop trivial automatic variable initialization after the specified number of instances. Must be greater than 0.")
|
||||
VALUE_LANGOPT(TrivialAutoVarInitMaxSize, 32, 0,
|
||||
"stop trivial automatic variable initialization if var size exceeds the specified size (in bytes). Must be greater than 0.")
|
||||
ENUM_LANGOPT(SignedOverflowBehavior, SignedOverflowBehaviorTy, 2, SOB_Undefined,
|
||||
"signed integer overflow handling")
|
||||
ENUM_LANGOPT(ThreadModel , ThreadModelKind, 2, ThreadModelKind::POSIX, "Thread Model")
|
||||
|
@ -381,6 +381,28 @@ public:
|
||||
All,
|
||||
};
|
||||
|
||||
enum class VisibilityForcedKinds {
|
||||
/// Force hidden visibility
|
||||
ForceHidden,
|
||||
/// Force protected visibility
|
||||
ForceProtected,
|
||||
/// Force default visibility
|
||||
ForceDefault,
|
||||
/// Don't alter the visibility
|
||||
Source,
|
||||
};
|
||||
|
||||
enum class VisibilityFromDLLStorageClassKinds {
|
||||
/// Keep the IR-gen assigned visibility.
|
||||
Keep,
|
||||
/// Override the IR-gen assigned visibility with default visibility.
|
||||
Default,
|
||||
/// Override the IR-gen assigned visibility with hidden visibility.
|
||||
Hidden,
|
||||
/// Override the IR-gen assigned visibility with protected visibility.
|
||||
Protected,
|
||||
};
|
||||
|
||||
enum class StrictFlexArraysLevelKind {
|
||||
/// Any trailing array member is a FAM.
|
||||
Default = 0,
|
||||
@ -392,7 +414,7 @@ public:
|
||||
IncompleteOnly = 3,
|
||||
};
|
||||
|
||||
enum ComplexRangeKind { CX_Full, CX_Limited, CX_Fortran };
|
||||
enum ComplexRangeKind { CX_Full, CX_Limited, CX_Fortran, CX_None };
|
||||
|
||||
public:
|
||||
/// The used language standard.
|
||||
@ -662,6 +684,26 @@ public:
|
||||
DefaultVisiblityExportMapping::All;
|
||||
}
|
||||
|
||||
bool hasGlobalAllocationFunctionVisibility() const {
|
||||
return getGlobalAllocationFunctionVisibility() !=
|
||||
VisibilityForcedKinds::Source;
|
||||
}
|
||||
|
||||
bool hasDefaultGlobalAllocationFunctionVisibility() const {
|
||||
return getGlobalAllocationFunctionVisibility() ==
|
||||
VisibilityForcedKinds::ForceDefault;
|
||||
}
|
||||
|
||||
bool hasProtectedGlobalAllocationFunctionVisibility() const {
|
||||
return getGlobalAllocationFunctionVisibility() ==
|
||||
VisibilityForcedKinds::ForceProtected;
|
||||
}
|
||||
|
||||
bool hasHiddenGlobalAllocationFunctionVisibility() const {
|
||||
return getGlobalAllocationFunctionVisibility() ==
|
||||
VisibilityForcedKinds::ForceHidden;
|
||||
}
|
||||
|
||||
/// Remap path prefix according to -fmacro-prefix-path option.
|
||||
void remapPathPrefix(SmallVectorImpl<char> &Path) const;
|
||||
|
||||
|
@ -211,7 +211,13 @@ public:
|
||||
case GCC:
|
||||
return false;
|
||||
case GNUstep:
|
||||
return false;
|
||||
// This could be enabled for all versions, except for the fact that the
|
||||
// implementation of `objc_retain` and friends prior to 2.2 call [object
|
||||
// retain] in their fall-back paths, which leads to infinite recursion if
|
||||
// the runtime is built with this enabled. Since distributions typically
|
||||
// build all Objective-C things with the same compiler version and flags,
|
||||
// it's better to be conservative here.
|
||||
return (getVersion() >= VersionTuple(2, 2));
|
||||
case ObjFW:
|
||||
return false;
|
||||
}
|
||||
@ -248,7 +254,7 @@ public:
|
||||
case GCC:
|
||||
return false;
|
||||
case GNUstep:
|
||||
return false;
|
||||
return getVersion() >= VersionTuple(2, 2);
|
||||
case ObjFW:
|
||||
return false;
|
||||
}
|
||||
@ -266,6 +272,8 @@ public:
|
||||
return getVersion() >= VersionTuple(12, 2);
|
||||
case WatchOS:
|
||||
return getVersion() >= VersionTuple(5, 2);
|
||||
case GNUstep:
|
||||
return getVersion() >= VersionTuple(2, 2);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
@ -463,7 +471,8 @@ public:
|
||||
case iOS: return true;
|
||||
case WatchOS: return true;
|
||||
case GCC: return false;
|
||||
case GNUstep: return false;
|
||||
case GNUstep:
|
||||
return (getVersion() >= VersionTuple(2, 2));
|
||||
case ObjFW: return false;
|
||||
}
|
||||
llvm_unreachable("bad kind");
|
||||
|
@ -14,6 +14,9 @@
|
||||
#ifndef LLVM_CLANG_BASIC_OPENACCKINDS_H
|
||||
#define LLVM_CLANG_BASIC_OPENACCKINDS_H
|
||||
|
||||
#include "clang/Basic/Diagnostic.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
|
||||
namespace clang {
|
||||
// Represents the Construct/Directive kind of a pragma directive. Note the
|
||||
// OpenACC standard is inconsistent between calling these Construct vs
|
||||
@ -62,6 +65,75 @@ enum class OpenACCDirectiveKind {
|
||||
Invalid,
|
||||
};
|
||||
|
||||
inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &Out,
|
||||
OpenACCDirectiveKind K) {
|
||||
switch (K) {
|
||||
case OpenACCDirectiveKind::Parallel:
|
||||
return Out << "parallel";
|
||||
|
||||
case OpenACCDirectiveKind::Serial:
|
||||
return Out << "serial";
|
||||
|
||||
case OpenACCDirectiveKind::Kernels:
|
||||
return Out << "kernels";
|
||||
|
||||
case OpenACCDirectiveKind::Data:
|
||||
return Out << "data";
|
||||
|
||||
case OpenACCDirectiveKind::EnterData:
|
||||
return Out << "enter data";
|
||||
|
||||
case OpenACCDirectiveKind::ExitData:
|
||||
return Out << "exit data";
|
||||
|
||||
case OpenACCDirectiveKind::HostData:
|
||||
return Out << "host_data";
|
||||
|
||||
case OpenACCDirectiveKind::Loop:
|
||||
return Out << "loop";
|
||||
|
||||
case OpenACCDirectiveKind::Cache:
|
||||
return Out << "cache";
|
||||
|
||||
case OpenACCDirectiveKind::ParallelLoop:
|
||||
return Out << "parallel loop";
|
||||
|
||||
case OpenACCDirectiveKind::SerialLoop:
|
||||
return Out << "serial loop";
|
||||
|
||||
case OpenACCDirectiveKind::KernelsLoop:
|
||||
return Out << "kernels loop";
|
||||
|
||||
case OpenACCDirectiveKind::Atomic:
|
||||
return Out << "atomic";
|
||||
|
||||
case OpenACCDirectiveKind::Declare:
|
||||
return Out << "declare";
|
||||
|
||||
case OpenACCDirectiveKind::Init:
|
||||
return Out << "init";
|
||||
|
||||
case OpenACCDirectiveKind::Shutdown:
|
||||
return Out << "shutdown";
|
||||
|
||||
case OpenACCDirectiveKind::Set:
|
||||
return Out << "set";
|
||||
|
||||
case OpenACCDirectiveKind::Update:
|
||||
return Out << "update";
|
||||
|
||||
case OpenACCDirectiveKind::Wait:
|
||||
return Out << "wait";
|
||||
|
||||
case OpenACCDirectiveKind::Routine:
|
||||
return Out << "routine";
|
||||
|
||||
case OpenACCDirectiveKind::Invalid:
|
||||
return Out << "<invalid>";
|
||||
}
|
||||
llvm_unreachable("Uncovered directive kind");
|
||||
}
|
||||
|
||||
enum class OpenACCAtomicKind {
|
||||
Read,
|
||||
Write,
|
||||
@ -82,11 +154,9 @@ enum class OpenACCClauseKind {
|
||||
Independent,
|
||||
/// 'auto' clause, allowed on 'loop' directives.
|
||||
Auto,
|
||||
/// 'worker' clause, allowed on 'loop' and 'routine' directives.
|
||||
/// 'worker' clause, allowed on 'loop', Combined, and 'routine' directives.
|
||||
Worker,
|
||||
/// 'vector' clause, allowed on 'loop' and 'routine' directives. Takes no
|
||||
/// arguments for 'routine', so the 'loop' version is not yet implemented
|
||||
/// completely.
|
||||
/// 'vector' clause, allowed on 'loop', Combined, and 'routine' directives.
|
||||
Vector,
|
||||
/// 'nohost' clause, allowed on 'routine' directives.
|
||||
NoHost,
|
||||
@ -98,10 +168,203 @@ enum class OpenACCClauseKind {
|
||||
If,
|
||||
/// 'self' clause, allowed on Compute and Combined Constructs, plus 'update'.
|
||||
Self,
|
||||
/// 'copy' clause, allowed on Compute and Combined Constructs, plus 'data' and
|
||||
/// 'declare'.
|
||||
Copy,
|
||||
/// 'use_device' clause, allowed on 'host_data' construct.
|
||||
UseDevice,
|
||||
/// 'attach' clause, allowed on Compute and Combined constructs, plus 'data'
|
||||
/// and 'enter data'.
|
||||
Attach,
|
||||
/// 'delete' clause, allowed on the 'exit data' construct.
|
||||
Delete,
|
||||
/// 'detach' clause, allowed on the 'exit data' construct.
|
||||
Detach,
|
||||
/// 'device' clause, allowed on the 'update' construct.
|
||||
Device,
|
||||
/// 'deviceptr' clause, allowed on Compute and Combined Constructs, plus
|
||||
/// 'data' and 'declare'.
|
||||
DevicePtr,
|
||||
/// 'device_resident' clause, allowed on the 'declare' construct.
|
||||
DeviceResident,
|
||||
/// 'firstprivate' clause, allowed on 'parallel', 'serial', 'parallel loop',
|
||||
/// and 'serial loop' constructs.
|
||||
FirstPrivate,
|
||||
/// 'host' clause, allowed on 'update' construct.
|
||||
Host,
|
||||
/// 'link' clause, allowed on 'declare' construct.
|
||||
Link,
|
||||
/// 'no_create' clause, allowed on allowed on Compute and Combined constructs,
|
||||
/// plus 'data'.
|
||||
NoCreate,
|
||||
/// 'present' clause, allowed on Compute and Combined constructs, plus 'data'
|
||||
/// and 'declare'.
|
||||
Present,
|
||||
/// 'private' clause, allowed on 'parallel', 'serial', 'loop', 'parallel
|
||||
/// loop', and 'serial loop' constructs.
|
||||
Private,
|
||||
/// 'copyout' clause, allowed on Compute and Combined constructs, plus 'data',
|
||||
/// 'exit data', and 'declare'.
|
||||
CopyOut,
|
||||
/// 'copyin' clause, allowed on Compute and Combined constructs, plus 'data',
|
||||
/// 'enter data', and 'declare'.
|
||||
CopyIn,
|
||||
/// 'copyin' clause, allowed on Compute and Combined constructs, plus 'data',
|
||||
/// 'enter data', and 'declare'.
|
||||
Create,
|
||||
/// 'reduction' clause, allowed on Parallel, Serial, Loop, and the combined
|
||||
/// constructs.
|
||||
Reduction,
|
||||
/// 'collapse' clause, allowed on 'loop' and Combined constructs.
|
||||
Collapse,
|
||||
/// 'bind' clause, allowed on routine constructs.
|
||||
Bind,
|
||||
/// 'vector_length' clause, allowed on 'parallel', 'kernels', 'parallel loop',
|
||||
/// and 'kernels loop' constructs.
|
||||
VectorLength,
|
||||
/// 'num_gangs' clause, allowed on 'parallel', 'kernels', parallel loop', and
|
||||
/// 'kernels loop' constructs.
|
||||
NumGangs,
|
||||
/// 'num_workers' clause, allowed on 'parallel', 'kernels', parallel loop',
|
||||
/// and 'kernels loop' constructs.
|
||||
NumWorkers,
|
||||
/// 'device_num' clause, allowed on 'init', 'shutdown', and 'set' constructs.
|
||||
DeviceNum,
|
||||
/// 'default_async' clause, allowed on 'set' construct.
|
||||
DefaultAsync,
|
||||
/// 'device_type' clause, allowed on Constructs, 'data', 'init', 'shutdown',
|
||||
/// 'set', update', 'loop', 'routine', and Combined constructs.
|
||||
DeviceType,
|
||||
/// 'dtype' clause, an alias for 'device_type', stored separately for
|
||||
/// diagnostic purposes.
|
||||
DType,
|
||||
|
||||
/// Represents an invalid clause, for the purposes of parsing.
|
||||
Invalid,
|
||||
};
|
||||
|
||||
inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &Out,
|
||||
OpenACCClauseKind K) {
|
||||
switch (K) {
|
||||
case OpenACCClauseKind::Finalize:
|
||||
return Out << "finalize";
|
||||
|
||||
case OpenACCClauseKind::IfPresent:
|
||||
return Out << "if_present";
|
||||
|
||||
case OpenACCClauseKind::Seq:
|
||||
return Out << "seq";
|
||||
|
||||
case OpenACCClauseKind::Independent:
|
||||
return Out << "independent";
|
||||
|
||||
case OpenACCClauseKind::Auto:
|
||||
return Out << "auto";
|
||||
|
||||
case OpenACCClauseKind::Worker:
|
||||
return Out << "worker";
|
||||
|
||||
case OpenACCClauseKind::Vector:
|
||||
return Out << "vector";
|
||||
|
||||
case OpenACCClauseKind::NoHost:
|
||||
return Out << "nohost";
|
||||
|
||||
case OpenACCClauseKind::Default:
|
||||
return Out << "default";
|
||||
|
||||
case OpenACCClauseKind::If:
|
||||
return Out << "if";
|
||||
|
||||
case OpenACCClauseKind::Self:
|
||||
return Out << "self";
|
||||
|
||||
case OpenACCClauseKind::Copy:
|
||||
return Out << "copy";
|
||||
|
||||
case OpenACCClauseKind::UseDevice:
|
||||
return Out << "use_device";
|
||||
|
||||
case OpenACCClauseKind::Attach:
|
||||
return Out << "attach";
|
||||
|
||||
case OpenACCClauseKind::Delete:
|
||||
return Out << "delete";
|
||||
|
||||
case OpenACCClauseKind::Detach:
|
||||
return Out << "detach";
|
||||
|
||||
case OpenACCClauseKind::Device:
|
||||
return Out << "device";
|
||||
|
||||
case OpenACCClauseKind::DevicePtr:
|
||||
return Out << "deviceptr";
|
||||
|
||||
case OpenACCClauseKind::DeviceResident:
|
||||
return Out << "device_resident";
|
||||
|
||||
case OpenACCClauseKind::FirstPrivate:
|
||||
return Out << "firstprivate";
|
||||
|
||||
case OpenACCClauseKind::Host:
|
||||
return Out << "host";
|
||||
|
||||
case OpenACCClauseKind::Link:
|
||||
return Out << "link";
|
||||
|
||||
case OpenACCClauseKind::NoCreate:
|
||||
return Out << "no_create";
|
||||
|
||||
case OpenACCClauseKind::Present:
|
||||
return Out << "present";
|
||||
|
||||
case OpenACCClauseKind::Private:
|
||||
return Out << "private";
|
||||
|
||||
case OpenACCClauseKind::CopyOut:
|
||||
return Out << "copyout";
|
||||
|
||||
case OpenACCClauseKind::CopyIn:
|
||||
return Out << "copyin";
|
||||
|
||||
case OpenACCClauseKind::Create:
|
||||
return Out << "create";
|
||||
|
||||
case OpenACCClauseKind::Reduction:
|
||||
return Out << "reduction";
|
||||
|
||||
case OpenACCClauseKind::Collapse:
|
||||
return Out << "collapse";
|
||||
|
||||
case OpenACCClauseKind::Bind:
|
||||
return Out << "bind";
|
||||
|
||||
case OpenACCClauseKind::VectorLength:
|
||||
return Out << "vector_length";
|
||||
|
||||
case OpenACCClauseKind::NumGangs:
|
||||
return Out << "num_gangs";
|
||||
|
||||
case OpenACCClauseKind::NumWorkers:
|
||||
return Out << "num_workers";
|
||||
|
||||
case OpenACCClauseKind::DeviceNum:
|
||||
return Out << "device_num";
|
||||
|
||||
case OpenACCClauseKind::DefaultAsync:
|
||||
return Out << "default_async";
|
||||
|
||||
case OpenACCClauseKind::DeviceType:
|
||||
return Out << "device_type";
|
||||
|
||||
case OpenACCClauseKind::DType:
|
||||
return Out << "dtype";
|
||||
|
||||
case OpenACCClauseKind::Invalid:
|
||||
return Out << "<invalid>";
|
||||
}
|
||||
llvm_unreachable("Uncovered clause kind");
|
||||
}
|
||||
enum class OpenACCDefaultClauseKind {
|
||||
/// 'none' option.
|
||||
None,
|
||||
@ -110,6 +373,29 @@ enum class OpenACCDefaultClauseKind {
|
||||
/// Not a valid option.
|
||||
Invalid,
|
||||
};
|
||||
|
||||
enum class OpenACCReductionOperator {
|
||||
/// '+'.
|
||||
Addition,
|
||||
/// '*'.
|
||||
Multiplication,
|
||||
/// 'max'.
|
||||
Max,
|
||||
/// 'min'.
|
||||
Min,
|
||||
/// '&'.
|
||||
BitwiseAnd,
|
||||
/// '|'.
|
||||
BitwiseOr,
|
||||
/// '^'.
|
||||
BitwiseXOr,
|
||||
/// '&&'.
|
||||
And,
|
||||
/// '||'.
|
||||
Or,
|
||||
/// Invalid Reduction Clause Kind.
|
||||
Invalid,
|
||||
};
|
||||
} // namespace clang
|
||||
|
||||
#endif // LLVM_CLANG_BASIC_OPENACCKINDS_H
|
||||
|
@ -291,7 +291,9 @@ namespace clang {
|
||||
bool isZExtReturn() const { return Flags & IsZExtReturn; }
|
||||
bool isByteIndexed() const { return Flags & IsByteIndexed; }
|
||||
bool isOverloadNone() const { return Flags & IsOverloadNone; }
|
||||
bool isOverloadWhile() const { return Flags & IsOverloadWhile; }
|
||||
bool isOverloadWhileOrMultiVecCvt() const {
|
||||
return Flags & IsOverloadWhileOrMultiVecCvt;
|
||||
}
|
||||
bool isOverloadDefault() const { return !(Flags & OverloadKindMask); }
|
||||
bool isOverloadWhileRW() const { return Flags & IsOverloadWhileRW; }
|
||||
bool isOverloadCvt() const { return Flags & IsOverloadCvt; }
|
||||
|
@ -760,10 +760,11 @@ KEYWORD(__builtin_available , KEYALL)
|
||||
KEYWORD(__builtin_sycl_unique_stable_name, KEYSYCL)
|
||||
|
||||
// Keywords defined by Attr.td.
|
||||
// The "EMPTY ## X" is used to prevent early macro-expansion of the keyword.
|
||||
#ifndef KEYWORD_ATTRIBUTE
|
||||
#define KEYWORD_ATTRIBUTE(X) KEYWORD(X, KEYALL)
|
||||
#define KEYWORD_ATTRIBUTE(X, HASARG, EMPTY) KEYWORD(EMPTY ## X, KEYALL)
|
||||
#endif
|
||||
#include "clang/Basic/AttrTokenKinds.inc"
|
||||
#include "clang/Basic/RegularKeywordAttrInfo.inc"
|
||||
|
||||
// Clang-specific keywords enabled only in testing.
|
||||
TESTING_KEYWORD(__unknown_anytype , KEYALL)
|
||||
|
@ -109,8 +109,8 @@ bool isPragmaAnnotation(TokenKind K);
|
||||
|
||||
inline constexpr bool isRegularKeywordAttribute(TokenKind K) {
|
||||
return (false
|
||||
#define KEYWORD_ATTRIBUTE(X) || (K == tok::kw_##X)
|
||||
#include "clang/Basic/AttrTokenKinds.inc"
|
||||
#define KEYWORD_ATTRIBUTE(X, ...) || (K == tok::kw_##X)
|
||||
#include "clang/Basic/RegularKeywordAttrInfo.inc"
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -21,19 +21,19 @@ include "arm_sve_sme_incl.td"
|
||||
multiclass ZALoad<string n_suffix, string t, string i_prefix, list<ImmCheck> ch> {
|
||||
let TargetGuard = "sme" in {
|
||||
def NAME # _H : MInst<"svld1_hor_" # n_suffix, "vimPQ", t,
|
||||
[IsLoad, IsOverloadNone, IsStreaming, IsSharedZA],
|
||||
[IsLoad, IsOverloadNone, IsStreaming, IsInOutZA],
|
||||
MemEltTyDefault, i_prefix # "_horiz", ch>;
|
||||
|
||||
def NAME # _H_VNUM : MInst<"svld1_hor_vnum_" # n_suffix, "vimPQl", t,
|
||||
[IsLoad, IsOverloadNone, IsStreaming, IsSharedZA],
|
||||
[IsLoad, IsOverloadNone, IsStreaming, IsInOutZA],
|
||||
MemEltTyDefault, i_prefix # "_horiz", ch>;
|
||||
|
||||
def NAME # _V : MInst<"svld1_ver_" # n_suffix, "vimPQ", t,
|
||||
[IsLoad, IsOverloadNone, IsStreaming, IsSharedZA],
|
||||
[IsLoad, IsOverloadNone, IsStreaming, IsInOutZA],
|
||||
MemEltTyDefault, i_prefix # "_vert", ch>;
|
||||
|
||||
def NAME # _V_VNUM : MInst<"svld1_ver_vnum_" # n_suffix, "vimPQl", t,
|
||||
[IsLoad, IsOverloadNone, IsStreaming, IsSharedZA],
|
||||
[IsLoad, IsOverloadNone, IsStreaming, IsInOutZA],
|
||||
MemEltTyDefault, i_prefix # "_vert", ch>;
|
||||
}
|
||||
}
|
||||
@ -45,11 +45,11 @@ defm SVLD1_ZA64 : ZALoad<"za64", "l", "aarch64_sme_ld1d", [ImmCheck<0, ImmCheck0
|
||||
defm SVLD1_ZA128 : ZALoad<"za128", "q", "aarch64_sme_ld1q", [ImmCheck<0, ImmCheck0_15>]>;
|
||||
|
||||
def SVLDR_VNUM_ZA : MInst<"svldr_vnum_za", "vmQl", "",
|
||||
[IsOverloadNone, IsStreamingCompatible, IsSharedZA],
|
||||
[IsOverloadNone, IsStreamingCompatible, IsInOutZA],
|
||||
MemEltTyDefault, "aarch64_sme_ldr">;
|
||||
|
||||
def SVLDR_ZA : MInst<"svldr_za", "vmQ", "",
|
||||
[IsOverloadNone, IsStreamingCompatible, IsSharedZA],
|
||||
[IsOverloadNone, IsStreamingCompatible, IsInOutZA],
|
||||
MemEltTyDefault, "aarch64_sme_ldr", []>;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -58,19 +58,19 @@ def SVLDR_ZA : MInst<"svldr_za", "vmQ", "",
|
||||
multiclass ZAStore<string n_suffix, string t, string i_prefix, list<ImmCheck> ch> {
|
||||
let TargetGuard = "sme" in {
|
||||
def NAME # _H : MInst<"svst1_hor_" # n_suffix, "vimP%", t,
|
||||
[IsStore, IsOverloadNone, IsStreaming, IsSharedZA, IsPreservesZA],
|
||||
[IsStore, IsOverloadNone, IsStreaming, IsInZA],
|
||||
MemEltTyDefault, i_prefix # "_horiz", ch>;
|
||||
|
||||
def NAME # _H_VNUM : MInst<"svst1_hor_vnum_" # n_suffix, "vimP%l", t,
|
||||
[IsStore, IsOverloadNone, IsStreaming, IsSharedZA, IsPreservesZA],
|
||||
[IsStore, IsOverloadNone, IsStreaming, IsInZA],
|
||||
MemEltTyDefault, i_prefix # "_horiz", ch>;
|
||||
|
||||
def NAME # _V : MInst<"svst1_ver_" # n_suffix, "vimP%", t,
|
||||
[IsStore, IsOverloadNone, IsStreaming, IsSharedZA, IsPreservesZA],
|
||||
[IsStore, IsOverloadNone, IsStreaming, IsInZA],
|
||||
MemEltTyDefault, i_prefix # "_vert", ch>;
|
||||
|
||||
def NAME # _V_VNUM : MInst<"svst1_ver_vnum_" # n_suffix, "vimP%l", t,
|
||||
[IsStore, IsOverloadNone, IsStreaming, IsSharedZA, IsPreservesZA],
|
||||
[IsStore, IsOverloadNone, IsStreaming, IsInZA],
|
||||
MemEltTyDefault, i_prefix # "_vert", ch>;
|
||||
}
|
||||
}
|
||||
@ -82,11 +82,11 @@ defm SVST1_ZA64 : ZAStore<"za64", "l", "aarch64_sme_st1d", [ImmCheck<0, ImmCheck
|
||||
defm SVST1_ZA128 : ZAStore<"za128", "q", "aarch64_sme_st1q", [ImmCheck<0, ImmCheck0_15>]>;
|
||||
|
||||
def SVSTR_VNUM_ZA : MInst<"svstr_vnum_za", "vm%l", "",
|
||||
[IsOverloadNone, IsStreamingCompatible, IsSharedZA, IsPreservesZA],
|
||||
[IsOverloadNone, IsStreamingCompatible, IsInZA],
|
||||
MemEltTyDefault, "aarch64_sme_str">;
|
||||
|
||||
def SVSTR_ZA : MInst<"svstr_za", "vm%", "",
|
||||
[IsOverloadNone, IsStreamingCompatible, IsSharedZA, IsPreservesZA],
|
||||
[IsOverloadNone, IsStreamingCompatible, IsInZA],
|
||||
MemEltTyDefault, "aarch64_sme_str", []>;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -96,11 +96,11 @@ multiclass ZARead<string n_suffix, string t, string i_prefix, list<ImmCheck> ch>
|
||||
let TargetGuard = "sme" in {
|
||||
def NAME # _H : SInst<"svread_hor_" # n_suffix # "[_{d}]", "ddPim", t,
|
||||
MergeOp1, i_prefix # "_horiz",
|
||||
[IsReadZA, IsStreaming, IsSharedZA, IsPreservesZA], ch>;
|
||||
[IsReadZA, IsStreaming, IsInZA], ch>;
|
||||
|
||||
def NAME # _V : SInst<"svread_ver_" # n_suffix # "[_{d}]", "ddPim", t,
|
||||
MergeOp1, i_prefix # "_vert",
|
||||
[IsReadZA, IsStreaming, IsSharedZA, IsPreservesZA], ch>;
|
||||
[IsReadZA, IsStreaming, IsInZA], ch>;
|
||||
}
|
||||
}
|
||||
|
||||
@ -117,11 +117,11 @@ multiclass ZAWrite<string n_suffix, string t, string i_prefix, list<ImmCheck> ch
|
||||
let TargetGuard = "sme" in {
|
||||
def NAME # _H : SInst<"svwrite_hor_" # n_suffix # "[_{d}]", "vimPd", t,
|
||||
MergeOp1, i_prefix # "_horiz",
|
||||
[IsWriteZA, IsStreaming, IsSharedZA], ch>;
|
||||
[IsWriteZA, IsStreaming, IsInOutZA], ch>;
|
||||
|
||||
def NAME # _V : SInst<"svwrite_ver_" # n_suffix # "[_{d}]", "vimPd", t,
|
||||
MergeOp1, i_prefix # "_vert",
|
||||
[IsWriteZA, IsStreaming, IsSharedZA], ch>;
|
||||
[IsWriteZA, IsStreaming, IsInOutZA], ch>;
|
||||
}
|
||||
}
|
||||
|
||||
@ -136,10 +136,10 @@ defm SVWRITE_ZA128 : ZAWrite<"za128", "csilUcUsUiUlhbfd", "aarch64_sme_writeq",
|
||||
|
||||
let TargetGuard = "sme" in {
|
||||
def SVZERO_MASK_ZA : SInst<"svzero_mask_za", "vi", "", MergeNone, "aarch64_sme_zero",
|
||||
[IsOverloadNone, IsStreamingCompatible, IsSharedZA],
|
||||
[IsOverloadNone, IsStreamingCompatible, IsInOutZA],
|
||||
[ImmCheck<0, ImmCheck0_255>]>;
|
||||
def SVZERO_ZA : SInst<"svzero_za", "v", "", MergeNone, "aarch64_sme_zero",
|
||||
[IsOverloadNone, IsStreamingCompatible, IsSharedZA]>;
|
||||
[IsOverloadNone, IsStreamingCompatible, IsOutZA]>;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -149,7 +149,7 @@ multiclass ZACount<string n_suffix> {
|
||||
let TargetGuard = "sme" in {
|
||||
def NAME : SInst<"sv" # n_suffix, "nv", "", MergeNone,
|
||||
"aarch64_sme_" # n_suffix,
|
||||
[IsOverloadNone, IsStreamingCompatible, IsPreservesZA]>;
|
||||
[IsOverloadNone, IsStreamingCompatible]>;
|
||||
}
|
||||
}
|
||||
|
||||
@ -164,13 +164,13 @@ defm SVCNTSD : ZACount<"cntsd">;
|
||||
multiclass ZAAdd<string n_suffix> {
|
||||
let TargetGuard = "sme" in {
|
||||
def NAME # _ZA32: SInst<"sv" # n_suffix # "_za32[_{d}]", "viPPd", "iUi", MergeOp1,
|
||||
"aarch64_sme_" # n_suffix, [IsStreaming, IsSharedZA],
|
||||
"aarch64_sme_" # n_suffix, [IsStreaming, IsInOutZA],
|
||||
[ImmCheck<0, ImmCheck0_3>]>;
|
||||
}
|
||||
|
||||
let TargetGuard = "sme-i16i64" in {
|
||||
def NAME # _ZA64: SInst<"sv" # n_suffix # "_za64[_{d}]", "viPPd", "lUl", MergeOp1,
|
||||
"aarch64_sme_" # n_suffix, [IsStreaming, IsSharedZA],
|
||||
"aarch64_sme_" # n_suffix, [IsStreaming, IsInOutZA],
|
||||
[ImmCheck<0, ImmCheck0_7>]>;
|
||||
}
|
||||
}
|
||||
@ -186,7 +186,7 @@ multiclass ZAIntOuterProd<string n_suffix1, string n_suffix2> {
|
||||
def NAME # _ZA32_B: SInst<"sv" # n_suffix2 # "_za32[_{d}]",
|
||||
"viPPdd", !cond(!eq(n_suffix1, "s") : "", true: "U") # "c",
|
||||
MergeOp1, "aarch64_sme_" # n_suffix1 # n_suffix2 # "_wide",
|
||||
[IsStreaming, IsSharedZA],
|
||||
[IsStreaming, IsInOutZA],
|
||||
[ImmCheck<0, ImmCheck0_3>]>;
|
||||
}
|
||||
|
||||
@ -194,7 +194,7 @@ multiclass ZAIntOuterProd<string n_suffix1, string n_suffix2> {
|
||||
def NAME # _ZA64_H: SInst<"sv" # n_suffix2 # "_za64[_{d}]",
|
||||
"viPPdd", !cond(!eq(n_suffix1, "s") : "", true: "U") # "s",
|
||||
MergeOp1, "aarch64_sme_" # n_suffix1 # n_suffix2 # "_wide",
|
||||
[IsStreaming, IsSharedZA],
|
||||
[IsStreaming, IsInOutZA],
|
||||
[ImmCheck<0, ImmCheck0_7>]>;
|
||||
}
|
||||
}
|
||||
@ -213,7 +213,7 @@ multiclass ZAIntOuterProdMixedSigns<string n_suffix1, string n_suffix2> {
|
||||
"viPPd" # !cond(!eq(n_suffix1, "su") : "u", true: "x"),
|
||||
!cond(!eq(n_suffix1, "su") : "", true: "U") # "c",
|
||||
MergeOp1, "aarch64_sme_" # n_suffix1 # n_suffix2 # "_wide",
|
||||
[IsStreaming, IsSharedZA],
|
||||
[IsStreaming, IsInOutZA],
|
||||
[ImmCheck<0, ImmCheck0_3>]>;
|
||||
}
|
||||
|
||||
@ -222,7 +222,7 @@ multiclass ZAIntOuterProdMixedSigns<string n_suffix1, string n_suffix2> {
|
||||
"viPPd" # !cond(!eq(n_suffix1, "su") : "u", true: "x"),
|
||||
!cond(!eq(n_suffix1, "su") : "", true: "U") # "s",
|
||||
MergeOp1, "aarch64_sme_" # n_suffix1 # n_suffix2 # "_wide",
|
||||
[IsStreaming, IsSharedZA],
|
||||
[IsStreaming, IsInOutZA],
|
||||
[ImmCheck<0, ImmCheck0_7>]>;
|
||||
}
|
||||
}
|
||||
@ -239,24 +239,24 @@ multiclass ZAFPOuterProd<string n_suffix> {
|
||||
let TargetGuard = "sme" in {
|
||||
def NAME # _ZA32_B: SInst<"sv" # n_suffix # "_za32[_{d}]", "viPPdd", "h",
|
||||
MergeOp1, "aarch64_sme_" # n_suffix # "_wide",
|
||||
[IsStreaming, IsSharedZA],
|
||||
[IsStreaming, IsInOutZA],
|
||||
[ImmCheck<0, ImmCheck0_3>]>;
|
||||
|
||||
def NAME # _ZA32_H: SInst<"sv" # n_suffix # "_za32[_{d}]", "viPPdd", "b",
|
||||
MergeOp1, "aarch64_sme_" # n_suffix # "_wide",
|
||||
[IsStreaming, IsSharedZA],
|
||||
[IsStreaming, IsInOutZA],
|
||||
[ImmCheck<0, ImmCheck0_3>]>;
|
||||
|
||||
def NAME # _ZA32_S: SInst<"sv" # n_suffix # "_za32[_{d}]", "viPPdd", "f",
|
||||
MergeOp1, "aarch64_sme_" # n_suffix,
|
||||
[IsStreaming, IsSharedZA],
|
||||
[IsStreaming, IsInOutZA],
|
||||
[ImmCheck<0, ImmCheck0_3>]>;
|
||||
}
|
||||
|
||||
let TargetGuard = "sme-f64f64" in {
|
||||
def NAME # _ZA64_D: SInst<"sv" # n_suffix # "_za64[_{d}]", "viPPdd", "d",
|
||||
MergeOp1, "aarch64_sme_" # n_suffix,
|
||||
[IsStreaming, IsSharedZA],
|
||||
[IsStreaming, IsInOutZA],
|
||||
[ImmCheck<0, ImmCheck0_7>]>;
|
||||
}
|
||||
}
|
||||
@ -269,29 +269,29 @@ defm SVMOPS : ZAFPOuterProd<"mops">;
|
||||
|
||||
multiclass ZAAddSub<string n_suffix> {
|
||||
let TargetGuard = "sme2" in {
|
||||
def NAME # _WRITE_SINGLE_ZA32_VG1X2_I32 : Inst<"sv" # n_suffix # "_write[_single]_za32[_{d}]_vg1x2", "vm2d", "iUi", MergeNone, "aarch64_sme_" # n_suffix # "_write_single_za_vg1x2", [IsStreaming, IsSharedZA], []>;
|
||||
def NAME # _WRITE_SINGLE_ZA32_VG1X4_I32 : Inst<"sv" # n_suffix # "_write[_single]_za32[_{d}]_vg1x4", "vm4d", "iUi", MergeNone, "aarch64_sme_" # n_suffix # "_write_single_za_vg1x4", [IsStreaming, IsSharedZA], []>;
|
||||
def NAME # _WRITE_SINGLE_ZA32_VG1X2_I32 : Inst<"sv" # n_suffix # "_write[_single]_za32[_{d}]_vg1x2", "vm2d", "iUi", MergeNone, "aarch64_sme_" # n_suffix # "_write_single_za_vg1x2", [IsStreaming, IsInOutZA], []>;
|
||||
def NAME # _WRITE_SINGLE_ZA32_VG1X4_I32 : Inst<"sv" # n_suffix # "_write[_single]_za32[_{d}]_vg1x4", "vm4d", "iUi", MergeNone, "aarch64_sme_" # n_suffix # "_write_single_za_vg1x4", [IsStreaming, IsInOutZA], []>;
|
||||
|
||||
def NAME # _WRITE_ZA32_VG1X2_I32 : Inst<"sv" # n_suffix # "_write_za32[_{d}]_vg1x2", "vm22", "iUi", MergeNone, "aarch64_sme_" # n_suffix # "_write_za_vg1x2", [IsStreaming, IsSharedZA], []>;
|
||||
def NAME # _WRITE_ZA32_VG1X4_I32 : Inst<"sv" # n_suffix # "_write_za32[_{d}]_vg1x4", "vm44", "iUi", MergeNone, "aarch64_sme_" # n_suffix # "_write_za_vg1x4", [IsStreaming, IsSharedZA], []>;
|
||||
def NAME # _WRITE_ZA32_VG1X2_I32 : Inst<"sv" # n_suffix # "_write_za32[_{d}]_vg1x2", "vm22", "iUi", MergeNone, "aarch64_sme_" # n_suffix # "_write_za_vg1x2", [IsStreaming, IsInOutZA], []>;
|
||||
def NAME # _WRITE_ZA32_VG1X4_I32 : Inst<"sv" # n_suffix # "_write_za32[_{d}]_vg1x4", "vm44", "iUi", MergeNone, "aarch64_sme_" # n_suffix # "_write_za_vg1x4", [IsStreaming, IsInOutZA], []>;
|
||||
|
||||
def NAME # _ZA32_VG1x2_I32 : Inst<"sv" # n_suffix # "_za32[_{d}]_vg1x2", "vm2", "iUif", MergeNone, "aarch64_sme_" # n_suffix # "_za32_vg1x2", [IsStreaming, IsSharedZA], []>;
|
||||
def NAME # _ZA32_VG1X4_I32 : Inst<"sv" # n_suffix # "_za32[_{d}]_vg1x4", "vm4", "iUif", MergeNone, "aarch64_sme_" # n_suffix # "_za32_vg1x4", [IsStreaming, IsSharedZA], []>;
|
||||
def NAME # _ZA32_VG1x2_I32 : Inst<"sv" # n_suffix # "_za32[_{d}]_vg1x2", "vm2", "iUif", MergeNone, "aarch64_sme_" # n_suffix # "_za32_vg1x2", [IsStreaming, IsInOutZA], []>;
|
||||
def NAME # _ZA32_VG1X4_I32 : Inst<"sv" # n_suffix # "_za32[_{d}]_vg1x4", "vm4", "iUif", MergeNone, "aarch64_sme_" # n_suffix # "_za32_vg1x4", [IsStreaming, IsInOutZA], []>;
|
||||
|
||||
let TargetGuard = "sme-i16i64" in {
|
||||
def NAME # _WRITE_SINGLE_ZA64_VG1X2_I64 : Inst<"sv" # n_suffix # "_write[_single]_za64[_{d}]_vg1x2", "vm2d", "lUl", MergeNone, "aarch64_sme_" # n_suffix # "_write_single_za_vg1x2", [IsStreaming, IsSharedZA], []>;
|
||||
def NAME # _WRITE_SINGLE_ZA64_VG1X4_I64 : Inst<"sv" # n_suffix # "_write[_single]_za64[_{d}]_vg1x4", "vm4d", "lUl", MergeNone, "aarch64_sme_" # n_suffix # "_write_single_za_vg1x4", [IsStreaming, IsSharedZA], []>;
|
||||
def NAME # _WRITE_SINGLE_ZA64_VG1X2_I64 : Inst<"sv" # n_suffix # "_write[_single]_za64[_{d}]_vg1x2", "vm2d", "lUl", MergeNone, "aarch64_sme_" # n_suffix # "_write_single_za_vg1x2", [IsStreaming, IsInOutZA], []>;
|
||||
def NAME # _WRITE_SINGLE_ZA64_VG1X4_I64 : Inst<"sv" # n_suffix # "_write[_single]_za64[_{d}]_vg1x4", "vm4d", "lUl", MergeNone, "aarch64_sme_" # n_suffix # "_write_single_za_vg1x4", [IsStreaming, IsInOutZA], []>;
|
||||
|
||||
def NAME # _WRITE_ZA64_VG1x2_I64 : Inst<"sv" # n_suffix # "_write_za64[_{d}]_vg1x2", "vm22", "lUl", MergeNone, "aarch64_sme_" # n_suffix # "_write_za_vg1x2", [IsStreaming, IsSharedZA], []>;
|
||||
def NAME # _WRITE_ZA64_VG1x4_I64 : Inst<"sv" # n_suffix # "_write_za64[_{d}]_vg1x4", "vm44", "lUl", MergeNone, "aarch64_sme_" # n_suffix # "_write_za_vg1x4", [IsStreaming, IsSharedZA], []>;
|
||||
def NAME # _WRITE_ZA64_VG1x2_I64 : Inst<"sv" # n_suffix # "_write_za64[_{d}]_vg1x2", "vm22", "lUl", MergeNone, "aarch64_sme_" # n_suffix # "_write_za_vg1x2", [IsStreaming, IsInOutZA], []>;
|
||||
def NAME # _WRITE_ZA64_VG1x4_I64 : Inst<"sv" # n_suffix # "_write_za64[_{d}]_vg1x4", "vm44", "lUl", MergeNone, "aarch64_sme_" # n_suffix # "_write_za_vg1x4", [IsStreaming, IsInOutZA], []>;
|
||||
|
||||
def NAME # _ZA64_VG1X2_I64 : Inst<"sv" # n_suffix # "_za64[_{d}]_vg1x2", "vm2", "lUl", MergeNone, "aarch64_sme_" # n_suffix # "_za64_vg1x2", [IsStreaming, IsSharedZA], []>;
|
||||
def NAME # _ZA64_VG1X4_I64 : Inst<"sv" # n_suffix # "_za64[_{d}]_vg1x4", "vm4", "lUl", MergeNone, "aarch64_sme_" # n_suffix # "_za64_vg1x4", [IsStreaming, IsSharedZA], []>;
|
||||
def NAME # _ZA64_VG1X2_I64 : Inst<"sv" # n_suffix # "_za64[_{d}]_vg1x2", "vm2", "lUl", MergeNone, "aarch64_sme_" # n_suffix # "_za64_vg1x2", [IsStreaming, IsInOutZA], []>;
|
||||
def NAME # _ZA64_VG1X4_I64 : Inst<"sv" # n_suffix # "_za64[_{d}]_vg1x4", "vm4", "lUl", MergeNone, "aarch64_sme_" # n_suffix # "_za64_vg1x4", [IsStreaming, IsInOutZA], []>;
|
||||
}
|
||||
|
||||
let TargetGuard = "sme-f64f64" in {
|
||||
def NAME # _ZA64_VG1X2_F64 : Inst<"sv" # n_suffix # "_za64[_{d}]_vg1x2", "vm2", "d", MergeNone, "aarch64_sme_" # n_suffix # "_za64_vg1x2", [IsStreaming, IsSharedZA], []>;
|
||||
def NAME # _ZA64_VG1X4_F64 : Inst<"sv" # n_suffix # "_za64[_{d}]_vg1x4", "vm4", "d", MergeNone, "aarch64_sme_" # n_suffix # "_za64_vg1x4", [IsStreaming, IsSharedZA], []>;
|
||||
def NAME # _ZA64_VG1X2_F64 : Inst<"sv" # n_suffix # "_za64[_{d}]_vg1x2", "vm2", "d", MergeNone, "aarch64_sme_" # n_suffix # "_za64_vg1x2", [IsStreaming, IsInOutZA], []>;
|
||||
def NAME # _ZA64_VG1X4_F64 : Inst<"sv" # n_suffix # "_za64[_{d}]_vg1x4", "vm4", "d", MergeNone, "aarch64_sme_" # n_suffix # "_za64_vg1x4", [IsStreaming, IsInOutZA], []>;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -306,12 +306,12 @@ defm SVSUB : ZAAddSub<"sub">;
|
||||
//
|
||||
|
||||
multiclass ZAWrite_VG<string n, string t, string i, list<ImmCheck> checks> {
|
||||
def NAME # _VG2_H : Inst<"svwrite_hor_" # n # "[_{d}]_vg2", "vim2", t, MergeNone, i # "_hor_vg2", [IsSharedZA, IsStreaming], checks>;
|
||||
def NAME # _VG2_V : Inst<"svwrite_ver_" # n # "[_{d}]_vg2", "vim2", t, MergeNone, i # "_ver_vg2", [IsSharedZA, IsStreaming], checks>;
|
||||
def NAME # _VG4_H : Inst<"svwrite_hor_" # n # "[_{d}]_vg4", "vim4", t, MergeNone, i # "_hor_vg4", [IsSharedZA, IsStreaming], checks>;
|
||||
def NAME # _VG4_V : Inst<"svwrite_ver_" # n # "[_{d}]_vg4", "vim4", t, MergeNone, i # "_ver_vg4", [IsSharedZA, IsStreaming], checks>;
|
||||
def NAME # _VG1x2 : Inst<"svwrite_" # n # "[_{d}]_vg1x2", "vm2", t, MergeNone, i # "_vg1x2", [IsSharedZA, IsStreaming], []>;
|
||||
def NAME # _VG1x4 : Inst<"svwrite_" # n # "[_{d}]_vg1x4", "vm4", t, MergeNone, i # "_vg1x4", [IsSharedZA, IsStreaming], []>;
|
||||
def NAME # _VG2_H : Inst<"svwrite_hor_" # n # "[_{d}]_vg2", "vim2", t, MergeNone, i # "_hor_vg2", [IsInOutZA, IsStreaming], checks>;
|
||||
def NAME # _VG2_V : Inst<"svwrite_ver_" # n # "[_{d}]_vg2", "vim2", t, MergeNone, i # "_ver_vg2", [IsInOutZA, IsStreaming], checks>;
|
||||
def NAME # _VG4_H : Inst<"svwrite_hor_" # n # "[_{d}]_vg4", "vim4", t, MergeNone, i # "_hor_vg4", [IsInOutZA, IsStreaming], checks>;
|
||||
def NAME # _VG4_V : Inst<"svwrite_ver_" # n # "[_{d}]_vg4", "vim4", t, MergeNone, i # "_ver_vg4", [IsInOutZA, IsStreaming], checks>;
|
||||
def NAME # _VG1x2 : Inst<"svwrite_" # n # "[_{d}]_vg1x2", "vm2", t, MergeNone, i # "_vg1x2", [IsInOutZA, IsStreaming], []>;
|
||||
def NAME # _VG1x4 : Inst<"svwrite_" # n # "[_{d}]_vg1x4", "vm4", t, MergeNone, i # "_vg1x4", [IsInOutZA, IsStreaming], []>;
|
||||
}
|
||||
|
||||
let TargetGuard = "sme2" in {
|
||||
@ -322,12 +322,12 @@ let TargetGuard = "sme2" in {
|
||||
}
|
||||
|
||||
multiclass ZARead_VG<string n, string t, string i, list<ImmCheck> checks> {
|
||||
def NAME # _VG2_H : Inst<"svread_hor_" # n # "_{d}_vg2", "2im", t, MergeNone, i # "_hor_vg2", [IsSharedZA, IsPreservesZA, IsStreaming], checks>;
|
||||
def NAME # _VG2_V : Inst<"svread_ver_" # n # "_{d}_vg2", "2im", t, MergeNone, i # "_ver_vg2", [IsSharedZA, IsPreservesZA, IsStreaming], checks>;
|
||||
def NAME # _VG4_H : Inst<"svread_hor_" # n # "_{d}_vg4", "4im", t, MergeNone, i # "_hor_vg4", [IsSharedZA, IsPreservesZA, IsStreaming], checks>;
|
||||
def NAME # _VG4_V : Inst<"svread_ver_" # n # "_{d}_vg4", "4im", t, MergeNone, i # "_ver_vg4", [IsSharedZA, IsPreservesZA, IsStreaming], checks>;
|
||||
def NAME # _VG1x2 : Inst<"svread_" # n # "_{d}_vg1x2", "2m", t, MergeNone, i # "_vg1x2", [IsSharedZA, IsPreservesZA, IsStreaming], []>;
|
||||
def NAME # _VG1x4 : Inst<"svread_" # n # "_{d}_vg1x4", "4m", t, MergeNone, i # "_vg1x4", [IsSharedZA, IsPreservesZA, IsStreaming], []>;
|
||||
def NAME # _VG2_H : Inst<"svread_hor_" # n # "_{d}_vg2", "2im", t, MergeNone, i # "_hor_vg2", [IsInZA, IsStreaming], checks>;
|
||||
def NAME # _VG2_V : Inst<"svread_ver_" # n # "_{d}_vg2", "2im", t, MergeNone, i # "_ver_vg2", [IsInZA, IsStreaming], checks>;
|
||||
def NAME # _VG4_H : Inst<"svread_hor_" # n # "_{d}_vg4", "4im", t, MergeNone, i # "_hor_vg4", [IsInZA, IsStreaming], checks>;
|
||||
def NAME # _VG4_V : Inst<"svread_ver_" # n # "_{d}_vg4", "4im", t, MergeNone, i # "_ver_vg4", [IsInZA, IsStreaming], checks>;
|
||||
def NAME # _VG1x2 : Inst<"svread_" # n # "_{d}_vg1x2", "2m", t, MergeNone, i # "_vg1x2", [IsInZA, IsStreaming], []>;
|
||||
def NAME # _VG1x4 : Inst<"svread_" # n # "_{d}_vg1x4", "4m", t, MergeNone, i # "_vg1x4", [IsInZA, IsStreaming], []>;
|
||||
}
|
||||
|
||||
let TargetGuard = "sme2" in {
|
||||
@ -342,331 +342,331 @@ let TargetGuard = "sme2" in {
|
||||
//
|
||||
|
||||
let TargetGuard = "sme2" in {
|
||||
def SVSMOPA : Inst<"svmopa_za32[_{d}]_m", "viPPdd", "s", MergeNone, "aarch64_sme_smopa_za32", [IsSharedZA, IsStreaming], [ImmCheck<0, ImmCheck0_3>]>;
|
||||
def SVUSMOPA : Inst<"svmopa_za32[_{d}]_m", "viPPdd", "Us", MergeNone, "aarch64_sme_umopa_za32", [IsSharedZA, IsStreaming], [ImmCheck<0, ImmCheck0_3>]>;
|
||||
def SVSMOPA : Inst<"svmopa_za32[_{d}]_m", "viPPdd", "s", MergeNone, "aarch64_sme_smopa_za32", [IsInOutZA, IsStreaming], [ImmCheck<0, ImmCheck0_3>]>;
|
||||
def SVUSMOPA : Inst<"svmopa_za32[_{d}]_m", "viPPdd", "Us", MergeNone, "aarch64_sme_umopa_za32", [IsInOutZA, IsStreaming], [ImmCheck<0, ImmCheck0_3>]>;
|
||||
|
||||
def SVSMOPS : Inst<"svmops_za32[_{d}]_m", "viPPdd", "s", MergeNone, "aarch64_sme_smops_za32", [IsSharedZA, IsStreaming], [ImmCheck<0, ImmCheck0_3>]>;
|
||||
def SVUSMOPS : Inst<"svmops_za32[_{d}]_m", "viPPdd", "Us", MergeNone, "aarch64_sme_umops_za32", [IsSharedZA, IsStreaming], [ImmCheck<0, ImmCheck0_3>]>;
|
||||
def SVSMOPS : Inst<"svmops_za32[_{d}]_m", "viPPdd", "s", MergeNone, "aarch64_sme_smops_za32", [IsInOutZA, IsStreaming], [ImmCheck<0, ImmCheck0_3>]>;
|
||||
def SVUSMOPS : Inst<"svmops_za32[_{d}]_m", "viPPdd", "Us", MergeNone, "aarch64_sme_umops_za32", [IsInOutZA, IsStreaming], [ImmCheck<0, ImmCheck0_3>]>;
|
||||
|
||||
def SVBMOPA : Inst<"svbmopa_za32[_{d}]_m", "viPPdd", "iUi", MergeNone, "aarch64_sme_bmopa_za32", [IsSharedZA, IsStreaming], [ImmCheck<0, ImmCheck0_3>]>;
|
||||
def SVBMOPA : Inst<"svbmopa_za32[_{d}]_m", "viPPdd", "iUi", MergeNone, "aarch64_sme_bmopa_za32", [IsInOutZA, IsStreaming], [ImmCheck<0, ImmCheck0_3>]>;
|
||||
|
||||
def SVBMOPS : Inst<"svbmops_za32[_{d}]_m", "viPPdd", "iUi", MergeNone, "aarch64_sme_bmops_za32", [IsSharedZA, IsStreaming], [ImmCheck<0, ImmCheck0_3>]>;
|
||||
def SVBMOPS : Inst<"svbmops_za32[_{d}]_m", "viPPdd", "iUi", MergeNone, "aarch64_sme_bmops_za32", [IsInOutZA, IsStreaming], [ImmCheck<0, ImmCheck0_3>]>;
|
||||
|
||||
// VERTICAL DOT-PRODUCT
|
||||
def SVVDOT_LANE_ZA32_VG1x2_S : Inst<"svvdot_lane_za32[_{d}]_vg1x2", "vm2di", "s", MergeNone, "aarch64_sme_svdot_lane_za32_vg1x2", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_3>]>;
|
||||
def SVVDOT_LANE_ZA32_VG1x4_S : Inst<"svvdot_lane_za32[_{d}]_vg1x4", "vm4di", "c", MergeNone, "aarch64_sme_svdot_lane_za32_vg1x4", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_3>]>;
|
||||
def SVVDOT_LANE_ZA32_VG1x2_U : Inst<"svvdot_lane_za32[_{d}]_vg1x2", "vm2di", "Us", MergeNone, "aarch64_sme_uvdot_lane_za32_vg1x2", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_3>]>;
|
||||
def SVVDOT_LANE_ZA32_VG1x4_U : Inst<"svvdot_lane_za32[_{d}]_vg1x4", "vm4di", "Uc", MergeNone, "aarch64_sme_uvdot_lane_za32_vg1x4", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_3>]>;
|
||||
def SVVDOT_LANE_ZA32_VG1x2_F : Inst<"svvdot_lane_za32[_{d}]_vg1x2", "vm2di", "hb", MergeNone, "aarch64_sme_fvdot_lane_za32_vg1x2", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_3>]>;
|
||||
def SVSUVDOT_LANE_ZA32_VG1x4 : Inst<"svsuvdot_lane_za32[_{d}]_vg1x4", "vm4di", "c", MergeNone, "aarch64_sme_suvdot_lane_za32_vg1x4", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_3>]>;
|
||||
def SVUSVDOT_LANE_ZA32_VG1x4 : Inst<"svusvdot_lane_za32[_{d}]_vg1x4", "vm4di", "Uc", MergeNone, "aarch64_sme_usvdot_lane_za32_vg1x4", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_3>]>;
|
||||
def SVVDOT_LANE_ZA32_VG1x2_S : Inst<"svvdot_lane_za32[_{d}]_vg1x2", "vm2di", "s", MergeNone, "aarch64_sme_svdot_lane_za32_vg1x2", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_3>]>;
|
||||
def SVVDOT_LANE_ZA32_VG1x4_S : Inst<"svvdot_lane_za32[_{d}]_vg1x4", "vm4di", "c", MergeNone, "aarch64_sme_svdot_lane_za32_vg1x4", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_3>]>;
|
||||
def SVVDOT_LANE_ZA32_VG1x2_U : Inst<"svvdot_lane_za32[_{d}]_vg1x2", "vm2di", "Us", MergeNone, "aarch64_sme_uvdot_lane_za32_vg1x2", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_3>]>;
|
||||
def SVVDOT_LANE_ZA32_VG1x4_U : Inst<"svvdot_lane_za32[_{d}]_vg1x4", "vm4di", "Uc", MergeNone, "aarch64_sme_uvdot_lane_za32_vg1x4", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_3>]>;
|
||||
def SVVDOT_LANE_ZA32_VG1x2_F : Inst<"svvdot_lane_za32[_{d}]_vg1x2", "vm2di", "hb", MergeNone, "aarch64_sme_fvdot_lane_za32_vg1x2", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_3>]>;
|
||||
def SVSUVDOT_LANE_ZA32_VG1x4 : Inst<"svsuvdot_lane_za32[_{d}]_vg1x4", "vm4di", "c", MergeNone, "aarch64_sme_suvdot_lane_za32_vg1x4", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_3>]>;
|
||||
def SVUSVDOT_LANE_ZA32_VG1x4 : Inst<"svusvdot_lane_za32[_{d}]_vg1x4", "vm4di", "Uc", MergeNone, "aarch64_sme_usvdot_lane_za32_vg1x4", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_3>]>;
|
||||
|
||||
// Multi-vector signed & unsigned integer dot-product
|
||||
def SVDOT_MULTI_ZA32_VG1x2_S : Inst<"svdot_za32[_{d}]_vg1x2", "vm22", "cs", MergeNone, "aarch64_sme_sdot_za32_vg1x2", [IsStreaming, IsSharedZA], []>;
|
||||
def SVDOT_MULTI_ZA32_VG1x4_S : Inst<"svdot_za32[_{d}]_vg1x4", "vm44", "cs", MergeNone, "aarch64_sme_sdot_za32_vg1x4", [IsStreaming, IsSharedZA], []>;
|
||||
def SVDOT_MULTI_ZA32_VG1x2_U : Inst<"svdot_za32[_{d}]_vg1x2", "vm22", "UcUs", MergeNone, "aarch64_sme_udot_za32_vg1x2", [IsStreaming, IsSharedZA], []>;
|
||||
def SVDOT_MULTI_ZA32_VG1x4_U : Inst<"svdot_za32[_{d}]_vg1x4", "vm44", "UcUs", MergeNone, "aarch64_sme_udot_za32_vg1x4", [IsStreaming, IsSharedZA], []>;
|
||||
def SVDOT_SINGLE_ZA32_VG1x2_S : Inst<"svdot[_single]_za32[_{d}]_vg1x2", "vm2d", "cs", MergeNone, "aarch64_sme_sdot_single_za32_vg1x2", [IsStreaming, IsSharedZA], []>;
|
||||
def SVDOT_SINGLE_ZA32_VG1x4_S : Inst<"svdot[_single]_za32[_{d}]_vg1x4", "vm4d", "cs", MergeNone, "aarch64_sme_sdot_single_za32_vg1x4", [IsStreaming, IsSharedZA], []>;
|
||||
def SVDOT_SINGLE_ZA32_VG1x2_U : Inst<"svdot[_single]_za32[_{d}]_vg1x2", "vm2d", "UcUs", MergeNone, "aarch64_sme_udot_single_za32_vg1x2", [IsStreaming, IsSharedZA], []>;
|
||||
def SVDOT_SINGLE_ZA32_VG1x4_U : Inst<"svdot[_single]_za32[_{d}]_vg1x4", "vm4d", "UcUs", MergeNone, "aarch64_sme_udot_single_za32_vg1x4", [IsStreaming, IsSharedZA], []>;
|
||||
def SVDOT_LANE_ZA32_VG1x2_S : Inst<"svdot_lane_za32[_{d}]_vg1x2", "vm2di", "cs", MergeNone, "aarch64_sme_sdot_lane_za32_vg1x2", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_3>]>;
|
||||
def SVDOT_LANE_ZA32_VG1x4_S : Inst<"svdot_lane_za32[_{d}]_vg1x4", "vm4di", "cs", MergeNone, "aarch64_sme_sdot_lane_za32_vg1x4", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_3>]>;
|
||||
def SVDOT_LANE_ZA32_VG1x2_U : Inst<"svdot_lane_za32[_{d}]_vg1x2", "vm2di", "UcUs", MergeNone, "aarch64_sme_udot_lane_za32_vg1x2", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_3>]>;
|
||||
def SVDOT_LANE_ZA32_VG1x4_U : Inst<"svdot_lane_za32[_{d}]_vg1x4", "vm4di", "UcUs", MergeNone, "aarch64_sme_udot_lane_za32_vg1x4", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_3>]>;
|
||||
def SVDOT_MULTI_ZA32_VG1x2_S : Inst<"svdot_za32[_{d}]_vg1x2", "vm22", "cs", MergeNone, "aarch64_sme_sdot_za32_vg1x2", [IsStreaming, IsInOutZA], []>;
|
||||
def SVDOT_MULTI_ZA32_VG1x4_S : Inst<"svdot_za32[_{d}]_vg1x4", "vm44", "cs", MergeNone, "aarch64_sme_sdot_za32_vg1x4", [IsStreaming, IsInOutZA], []>;
|
||||
def SVDOT_MULTI_ZA32_VG1x2_U : Inst<"svdot_za32[_{d}]_vg1x2", "vm22", "UcUs", MergeNone, "aarch64_sme_udot_za32_vg1x2", [IsStreaming, IsInOutZA], []>;
|
||||
def SVDOT_MULTI_ZA32_VG1x4_U : Inst<"svdot_za32[_{d}]_vg1x4", "vm44", "UcUs", MergeNone, "aarch64_sme_udot_za32_vg1x4", [IsStreaming, IsInOutZA], []>;
|
||||
def SVDOT_SINGLE_ZA32_VG1x2_S : Inst<"svdot[_single]_za32[_{d}]_vg1x2", "vm2d", "cs", MergeNone, "aarch64_sme_sdot_single_za32_vg1x2", [IsStreaming, IsInOutZA], []>;
|
||||
def SVDOT_SINGLE_ZA32_VG1x4_S : Inst<"svdot[_single]_za32[_{d}]_vg1x4", "vm4d", "cs", MergeNone, "aarch64_sme_sdot_single_za32_vg1x4", [IsStreaming, IsInOutZA], []>;
|
||||
def SVDOT_SINGLE_ZA32_VG1x2_U : Inst<"svdot[_single]_za32[_{d}]_vg1x2", "vm2d", "UcUs", MergeNone, "aarch64_sme_udot_single_za32_vg1x2", [IsStreaming, IsInOutZA], []>;
|
||||
def SVDOT_SINGLE_ZA32_VG1x4_U : Inst<"svdot[_single]_za32[_{d}]_vg1x4", "vm4d", "UcUs", MergeNone, "aarch64_sme_udot_single_za32_vg1x4", [IsStreaming, IsInOutZA], []>;
|
||||
def SVDOT_LANE_ZA32_VG1x2_S : Inst<"svdot_lane_za32[_{d}]_vg1x2", "vm2di", "cs", MergeNone, "aarch64_sme_sdot_lane_za32_vg1x2", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_3>]>;
|
||||
def SVDOT_LANE_ZA32_VG1x4_S : Inst<"svdot_lane_za32[_{d}]_vg1x4", "vm4di", "cs", MergeNone, "aarch64_sme_sdot_lane_za32_vg1x4", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_3>]>;
|
||||
def SVDOT_LANE_ZA32_VG1x2_U : Inst<"svdot_lane_za32[_{d}]_vg1x2", "vm2di", "UcUs", MergeNone, "aarch64_sme_udot_lane_za32_vg1x2", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_3>]>;
|
||||
def SVDOT_LANE_ZA32_VG1x4_U : Inst<"svdot_lane_za32[_{d}]_vg1x4", "vm4di", "UcUs", MergeNone, "aarch64_sme_udot_lane_za32_vg1x4", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_3>]>;
|
||||
|
||||
def SVUSDOT_SINGLE_ZA32_VG1x2 : Inst<"svusdot[_single]_za32[_{d}]_vg1x2", "vm2.dx", "Uc", MergeNone, "aarch64_sme_usdot_single_za32_vg1x2", [IsStreaming, IsSharedZA], []>;
|
||||
def SVUSDOT_SINGLE_ZA32_VG1x4 : Inst<"svusdot[_single]_za32[_{d}]_vg1x4", "vm4.dx", "Uc", MergeNone, "aarch64_sme_usdot_single_za32_vg1x4", [IsStreaming, IsSharedZA], []>;
|
||||
def SVUSDOT_MULTI_ZA32_VG1x2 : Inst<"svusdot_za32[_{d}]_vg1x2", "vm2.d2.x", "Uc", MergeNone, "aarch64_sme_usdot_za32_vg1x2", [IsStreaming, IsSharedZA], []>;
|
||||
def SVUSDOT_MULTI_ZA32_VG1x4 : Inst<"svusdot_za32[_{d}]_vg1x4", "vm4.d4.x", "Uc", MergeNone, "aarch64_sme_usdot_za32_vg1x4", [IsStreaming, IsSharedZA], []>;
|
||||
def SVUSDOT_LANE_ZA32_VG1x2 : Inst<"svusdot_lane_za32[_{d}]_vg1x2", "vm2.dxi", "Uc", MergeNone, "aarch64_sme_usdot_lane_za32_vg1x2", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_3>]>;
|
||||
def SVUSDOT_LANE_ZA32_VG1x4 : Inst<"svusdot_lane_za32[_{d}]_vg1x4", "vm4.dxi", "Uc", MergeNone, "aarch64_sme_usdot_lane_za32_vg1x4", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_3>]>;
|
||||
def SVUSDOT_SINGLE_ZA32_VG1x2 : Inst<"svusdot[_single]_za32[_{d}]_vg1x2", "vm2.dx", "Uc", MergeNone, "aarch64_sme_usdot_single_za32_vg1x2", [IsStreaming, IsInOutZA], []>;
|
||||
def SVUSDOT_SINGLE_ZA32_VG1x4 : Inst<"svusdot[_single]_za32[_{d}]_vg1x4", "vm4.dx", "Uc", MergeNone, "aarch64_sme_usdot_single_za32_vg1x4", [IsStreaming, IsInOutZA], []>;
|
||||
def SVUSDOT_MULTI_ZA32_VG1x2 : Inst<"svusdot_za32[_{d}]_vg1x2", "vm2.d2.x", "Uc", MergeNone, "aarch64_sme_usdot_za32_vg1x2", [IsStreaming, IsInOutZA], []>;
|
||||
def SVUSDOT_MULTI_ZA32_VG1x4 : Inst<"svusdot_za32[_{d}]_vg1x4", "vm4.d4.x", "Uc", MergeNone, "aarch64_sme_usdot_za32_vg1x4", [IsStreaming, IsInOutZA], []>;
|
||||
def SVUSDOT_LANE_ZA32_VG1x2 : Inst<"svusdot_lane_za32[_{d}]_vg1x2", "vm2.dxi", "Uc", MergeNone, "aarch64_sme_usdot_lane_za32_vg1x2", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_3>]>;
|
||||
def SVUSDOT_LANE_ZA32_VG1x4 : Inst<"svusdot_lane_za32[_{d}]_vg1x4", "vm4.dxi", "Uc", MergeNone, "aarch64_sme_usdot_lane_za32_vg1x4", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_3>]>;
|
||||
|
||||
def SVSUDOT_SINGLE_ZA32_VG1x2 : Inst<"svsudot[_single]_za32[_{d}]_vg1x2", "vm2.du", "c", MergeNone, "aarch64_sme_sudot_single_za32_vg1x2", [IsStreaming, IsSharedZA], []>;
|
||||
def SVSUDOT_SINGLE_ZA32_VG1x4 : Inst<"svsudot[_single]_za32[_{d}]_vg1x4", "vm4.du", "c", MergeNone, "aarch64_sme_sudot_single_za32_vg1x4", [IsStreaming, IsSharedZA], []>;
|
||||
def SVSUDOT_SINGLE_ZA32_VG1x2 : Inst<"svsudot[_single]_za32[_{d}]_vg1x2", "vm2.du", "c", MergeNone, "aarch64_sme_sudot_single_za32_vg1x2", [IsStreaming, IsInOutZA], []>;
|
||||
def SVSUDOT_SINGLE_ZA32_VG1x4 : Inst<"svsudot[_single]_za32[_{d}]_vg1x4", "vm4.du", "c", MergeNone, "aarch64_sme_sudot_single_za32_vg1x4", [IsStreaming, IsInOutZA], []>;
|
||||
|
||||
// Multi-multi sudot builtins are mapped to usdot, with zn & zm operands swapped
|
||||
def SVSUDOT_MULTI_ZA32_VG1x2 : Inst<"svsudot_za32[_{d}]_vg1x2", "vm2.d2.u", "c", MergeNone, "aarch64_sme_usdot_za32_vg1x2", [IsStreaming, IsSharedZA], []>;
|
||||
def SVSUDOT_MULTI_ZA32_VG1x4 : Inst<"svsudot_za32[_{d}]_vg1x4", "vm4.d4.u", "c", MergeNone, "aarch64_sme_usdot_za32_vg1x4", [IsStreaming, IsSharedZA], []>;
|
||||
def SVSUDOT_MULTI_ZA32_VG1x2 : Inst<"svsudot_za32[_{d}]_vg1x2", "vm2.d2.u", "c", MergeNone, "aarch64_sme_usdot_za32_vg1x2", [IsStreaming, IsInOutZA], []>;
|
||||
def SVSUDOT_MULTI_ZA32_VG1x4 : Inst<"svsudot_za32[_{d}]_vg1x4", "vm4.d4.u", "c", MergeNone, "aarch64_sme_usdot_za32_vg1x4", [IsStreaming, IsInOutZA], []>;
|
||||
|
||||
def SVSUDOT_LANE_ZA32_VG1x2 : Inst<"svsudot_lane_za32[_{d}]_vg1x2", "vm2.dui", "c", MergeNone, "aarch64_sme_sudot_lane_za32_vg1x2", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_3>]>;
|
||||
def SVSUDOT_LANE_ZA32_VG1x4 : Inst<"svsudot_lane_za32[_{d}]_vg1x4", "vm4.dui", "c", MergeNone, "aarch64_sme_sudot_lane_za32_vg1x4", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_3>]>;
|
||||
def SVSUDOT_LANE_ZA32_VG1x2 : Inst<"svsudot_lane_za32[_{d}]_vg1x2", "vm2.dui", "c", MergeNone, "aarch64_sme_sudot_lane_za32_vg1x2", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_3>]>;
|
||||
def SVSUDOT_LANE_ZA32_VG1x4 : Inst<"svsudot_lane_za32[_{d}]_vg1x4", "vm4.dui", "c", MergeNone, "aarch64_sme_sudot_lane_za32_vg1x4", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_3>]>;
|
||||
|
||||
// Multi-vector half-precision/BFloat16 floating-point dot-product
|
||||
def SVDOT_MULTI_ZA32_VG1x2_F16 : Inst<"svdot_za32[_{d}]_vg1x2", "vm22", "bh", MergeNone, "aarch64_sme_fdot_za32_vg1x2", [IsStreaming, IsSharedZA], []>;
|
||||
def SVDOT_MULTI_ZA32_VG1x4_F16 : Inst<"svdot_za32[_{d}]_vg1x4", "vm44", "bh", MergeNone, "aarch64_sme_fdot_za32_vg1x4", [IsStreaming, IsSharedZA], []>;
|
||||
def SVDOT_SINGLE_ZA32_VG1x2_F16 : Inst<"svdot[_single]_za32[_{d}]_vg1x2", "vm2d", "bh", MergeNone, "aarch64_sme_fdot_single_za32_vg1x2", [IsStreaming, IsSharedZA], []>;
|
||||
def SVDOT_SINGLE_ZA32_VG1x4_F16 : Inst<"svdot[_single]_za32[_{d}]_vg1x4", "vm4d", "bh", MergeNone, "aarch64_sme_fdot_single_za32_vg1x4", [IsStreaming, IsSharedZA], []>;
|
||||
def SVDOT_LANE_ZA32_VG1x2_F16 : Inst<"svdot_lane_za32[_{d}]_vg1x2", "vm2di", "bh", MergeNone, "aarch64_sme_fdot_lane_za32_vg1x2", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_3>]>;
|
||||
def SVDOT_LANE_ZA32_VG1x4_F16 : Inst<"svdot_lane_za32[_{d}]_vg1x4", "vm4di", "bh", MergeNone, "aarch64_sme_fdot_lane_za32_vg1x4", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_3>]>;
|
||||
def SVDOT_MULTI_ZA32_VG1x2_F16 : Inst<"svdot_za32[_{d}]_vg1x2", "vm22", "bh", MergeNone, "aarch64_sme_fdot_za32_vg1x2", [IsStreaming, IsInOutZA], []>;
|
||||
def SVDOT_MULTI_ZA32_VG1x4_F16 : Inst<"svdot_za32[_{d}]_vg1x4", "vm44", "bh", MergeNone, "aarch64_sme_fdot_za32_vg1x4", [IsStreaming, IsInOutZA], []>;
|
||||
def SVDOT_SINGLE_ZA32_VG1x2_F16 : Inst<"svdot[_single]_za32[_{d}]_vg1x2", "vm2d", "bh", MergeNone, "aarch64_sme_fdot_single_za32_vg1x2", [IsStreaming, IsInOutZA], []>;
|
||||
def SVDOT_SINGLE_ZA32_VG1x4_F16 : Inst<"svdot[_single]_za32[_{d}]_vg1x4", "vm4d", "bh", MergeNone, "aarch64_sme_fdot_single_za32_vg1x4", [IsStreaming, IsInOutZA], []>;
|
||||
def SVDOT_LANE_ZA32_VG1x2_F16 : Inst<"svdot_lane_za32[_{d}]_vg1x2", "vm2di", "bh", MergeNone, "aarch64_sme_fdot_lane_za32_vg1x2", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_3>]>;
|
||||
def SVDOT_LANE_ZA32_VG1x4_F16 : Inst<"svdot_lane_za32[_{d}]_vg1x4", "vm4di", "bh", MergeNone, "aarch64_sme_fdot_lane_za32_vg1x4", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_3>]>;
|
||||
}
|
||||
|
||||
let TargetGuard = "sme2,sme-i16i64" in {
|
||||
def SVVDOT_LANE_ZA64_VG1x4_S : Inst<"svvdot_lane_za64[_{d}]_vg1x4", "vm4di", "s", MergeNone, "aarch64_sme_svdot_lane_za64_vg1x4", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_1>]>;
|
||||
def SVVDOT_LANE_ZA64_VG1x4_U : Inst<"svvdot_lane_za64[_{d}]_vg1x4", "vm4di", "Us", MergeNone, "aarch64_sme_uvdot_lane_za64_vg1x4", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_1>]>;
|
||||
def SVVDOT_LANE_ZA64_VG1x4_S : Inst<"svvdot_lane_za64[_{d}]_vg1x4", "vm4di", "s", MergeNone, "aarch64_sme_svdot_lane_za64_vg1x4", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_1>]>;
|
||||
def SVVDOT_LANE_ZA64_VG1x4_U : Inst<"svvdot_lane_za64[_{d}]_vg1x4", "vm4di", "Us", MergeNone, "aarch64_sme_uvdot_lane_za64_vg1x4", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_1>]>;
|
||||
|
||||
def SVDOT_MULTI_ZA64_VG1x2_S16 : Inst<"svdot_za64[_{d}]_vg1x2", "vm22", "s", MergeNone, "aarch64_sme_sdot_za64_vg1x2", [IsStreaming, IsSharedZA], []>;
|
||||
def SVDOT_MULTI_ZA64_VG1x4_S16 : Inst<"svdot_za64[_{d}]_vg1x4", "vm44", "s", MergeNone, "aarch64_sme_sdot_za64_vg1x4", [IsStreaming, IsSharedZA], []>;
|
||||
def SVDOT_MULTI_ZA64_VG1x2_U16 : Inst<"svdot_za64[_{d}]_vg1x2", "vm22", "Us", MergeNone, "aarch64_sme_udot_za64_vg1x2", [IsStreaming, IsSharedZA], []>;
|
||||
def SVDOT_MULTI_ZA64_VG1x4_U16 : Inst<"svdot_za64[_{d}]_vg1x4", "vm44", "Us", MergeNone, "aarch64_sme_udot_za64_vg1x4", [IsStreaming, IsSharedZA], []>;
|
||||
def SVDOT_SINGLE_ZA64_VG1x2_S16 : Inst<"svdot[_single]_za64[_{d}]_vg1x2", "vm2d", "s", MergeNone, "aarch64_sme_sdot_single_za64_vg1x2", [IsStreaming, IsSharedZA], []>;
|
||||
def SVDOT_SINGLE_ZA64_VG1x4_S16 : Inst<"svdot[_single]_za64[_{d}]_vg1x4", "vm4d", "s", MergeNone, "aarch64_sme_sdot_single_za64_vg1x4", [IsStreaming, IsSharedZA], []>;
|
||||
def SVDOT_SINGLE_ZA64_VG1x2_U16 : Inst<"svdot[_single]_za64[_{d}]_vg1x2", "vm2d", "Us", MergeNone, "aarch64_sme_udot_single_za64_vg1x2", [IsStreaming, IsSharedZA], []>;
|
||||
def SVDOT_SINGLE_ZA64_VG1x4_U16 : Inst<"svdot[_single]_za64[_{d}]_vg1x4", "vm4d", "Us", MergeNone, "aarch64_sme_udot_single_za64_vg1x4", [IsStreaming, IsSharedZA], []>;
|
||||
def SVDOT_LANE_ZA64_VG1x2_S16 : Inst<"svdot_lane_za64[_{d}]_vg1x2", "vm2di", "s", MergeNone, "aarch64_sme_sdot_lane_za64_vg1x2", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_1>]>;
|
||||
def SVDOT_LANE_ZA64_VG1x4_S16 : Inst<"svdot_lane_za64[_{d}]_vg1x4", "vm4di", "s", MergeNone, "aarch64_sme_sdot_lane_za64_vg1x4", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_1>]>;
|
||||
def SVDOT_LANE_ZA64_VG1x2_U16 : Inst<"svdot_lane_za64[_{d}]_vg1x2", "vm2di", "Us", MergeNone, "aarch64_sme_udot_lane_za64_vg1x2", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_1>]>;
|
||||
def SVDOT_LANE_ZA64_VG1x4_U16 : Inst<"svdot_lane_za64[_{d}]_vg1x4", "vm4di", "Us", MergeNone, "aarch64_sme_udot_lane_za64_vg1x4", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_1>]>;
|
||||
def SVDOT_MULTI_ZA64_VG1x2_S16 : Inst<"svdot_za64[_{d}]_vg1x2", "vm22", "s", MergeNone, "aarch64_sme_sdot_za64_vg1x2", [IsStreaming, IsInOutZA], []>;
|
||||
def SVDOT_MULTI_ZA64_VG1x4_S16 : Inst<"svdot_za64[_{d}]_vg1x4", "vm44", "s", MergeNone, "aarch64_sme_sdot_za64_vg1x4", [IsStreaming, IsInOutZA], []>;
|
||||
def SVDOT_MULTI_ZA64_VG1x2_U16 : Inst<"svdot_za64[_{d}]_vg1x2", "vm22", "Us", MergeNone, "aarch64_sme_udot_za64_vg1x2", [IsStreaming, IsInOutZA], []>;
|
||||
def SVDOT_MULTI_ZA64_VG1x4_U16 : Inst<"svdot_za64[_{d}]_vg1x4", "vm44", "Us", MergeNone, "aarch64_sme_udot_za64_vg1x4", [IsStreaming, IsInOutZA], []>;
|
||||
def SVDOT_SINGLE_ZA64_VG1x2_S16 : Inst<"svdot[_single]_za64[_{d}]_vg1x2", "vm2d", "s", MergeNone, "aarch64_sme_sdot_single_za64_vg1x2", [IsStreaming, IsInOutZA], []>;
|
||||
def SVDOT_SINGLE_ZA64_VG1x4_S16 : Inst<"svdot[_single]_za64[_{d}]_vg1x4", "vm4d", "s", MergeNone, "aarch64_sme_sdot_single_za64_vg1x4", [IsStreaming, IsInOutZA], []>;
|
||||
def SVDOT_SINGLE_ZA64_VG1x2_U16 : Inst<"svdot[_single]_za64[_{d}]_vg1x2", "vm2d", "Us", MergeNone, "aarch64_sme_udot_single_za64_vg1x2", [IsStreaming, IsInOutZA], []>;
|
||||
def SVDOT_SINGLE_ZA64_VG1x4_U16 : Inst<"svdot[_single]_za64[_{d}]_vg1x4", "vm4d", "Us", MergeNone, "aarch64_sme_udot_single_za64_vg1x4", [IsStreaming, IsInOutZA], []>;
|
||||
def SVDOT_LANE_ZA64_VG1x2_S16 : Inst<"svdot_lane_za64[_{d}]_vg1x2", "vm2di", "s", MergeNone, "aarch64_sme_sdot_lane_za64_vg1x2", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_1>]>;
|
||||
def SVDOT_LANE_ZA64_VG1x4_S16 : Inst<"svdot_lane_za64[_{d}]_vg1x4", "vm4di", "s", MergeNone, "aarch64_sme_sdot_lane_za64_vg1x4", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_1>]>;
|
||||
def SVDOT_LANE_ZA64_VG1x2_U16 : Inst<"svdot_lane_za64[_{d}]_vg1x2", "vm2di", "Us", MergeNone, "aarch64_sme_udot_lane_za64_vg1x2", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_1>]>;
|
||||
def SVDOT_LANE_ZA64_VG1x4_U16 : Inst<"svdot_lane_za64[_{d}]_vg1x4", "vm4di", "Us", MergeNone, "aarch64_sme_udot_lane_za64_vg1x4", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_1>]>;
|
||||
}
|
||||
|
||||
// FMLA/FMLS
|
||||
let TargetGuard = "sme2" in {
|
||||
def SVMLA_MULTI_VG1x2_F32 : Inst<"svmla_za32[_{d}]_vg1x2", "vm22", "f", MergeNone, "aarch64_sme_fmla_vg1x2", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLA_MULTI_VG1x4_F32 : Inst<"svmla_za32[_{d}]_vg1x4", "vm44", "f", MergeNone, "aarch64_sme_fmla_vg1x4", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLS_MULTI_VG1x2_F32 : Inst<"svmls_za32[_{d}]_vg1x2", "vm22", "f", MergeNone, "aarch64_sme_fmls_vg1x2", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLS_MULTI_VG1x4_F32 : Inst<"svmls_za32[_{d}]_vg1x4", "vm44", "f", MergeNone, "aarch64_sme_fmls_vg1x4", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLA_MULTI_VG1x2_F32 : Inst<"svmla_za32[_{d}]_vg1x2", "vm22", "f", MergeNone, "aarch64_sme_fmla_vg1x2", [IsStreaming, IsInOutZA], []>;
|
||||
def SVMLA_MULTI_VG1x4_F32 : Inst<"svmla_za32[_{d}]_vg1x4", "vm44", "f", MergeNone, "aarch64_sme_fmla_vg1x4", [IsStreaming, IsInOutZA], []>;
|
||||
def SVMLS_MULTI_VG1x2_F32 : Inst<"svmls_za32[_{d}]_vg1x2", "vm22", "f", MergeNone, "aarch64_sme_fmls_vg1x2", [IsStreaming, IsInOutZA], []>;
|
||||
def SVMLS_MULTI_VG1x4_F32 : Inst<"svmls_za32[_{d}]_vg1x4", "vm44", "f", MergeNone, "aarch64_sme_fmls_vg1x4", [IsStreaming, IsInOutZA], []>;
|
||||
|
||||
def SVMLA_SINGLE_VG1x2_F32 : Inst<"svmla[_single]_za32[_{d}]_vg1x2", "vm2d", "f", MergeNone, "aarch64_sme_fmla_single_vg1x2", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLA_SINGLE_VG1x4_F32 : Inst<"svmla[_single]_za32[_{d}]_vg1x4", "vm4d", "f", MergeNone, "aarch64_sme_fmla_single_vg1x4", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLS_SINGLE_VG1x2_F32 : Inst<"svmls[_single]_za32[_{d}]_vg1x2", "vm2d", "f", MergeNone, "aarch64_sme_fmls_single_vg1x2", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLS_SINGLE_VG1x4_F32 : Inst<"svmls[_single]_za32[_{d}]_vg1x4", "vm4d", "f", MergeNone, "aarch64_sme_fmls_single_vg1x4", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLA_SINGLE_VG1x2_F32 : Inst<"svmla[_single]_za32[_{d}]_vg1x2", "vm2d", "f", MergeNone, "aarch64_sme_fmla_single_vg1x2", [IsStreaming, IsInOutZA], []>;
|
||||
def SVMLA_SINGLE_VG1x4_F32 : Inst<"svmla[_single]_za32[_{d}]_vg1x4", "vm4d", "f", MergeNone, "aarch64_sme_fmla_single_vg1x4", [IsStreaming, IsInOutZA], []>;
|
||||
def SVMLS_SINGLE_VG1x2_F32 : Inst<"svmls[_single]_za32[_{d}]_vg1x2", "vm2d", "f", MergeNone, "aarch64_sme_fmls_single_vg1x2", [IsStreaming, IsInOutZA], []>;
|
||||
def SVMLS_SINGLE_VG1x4_F32 : Inst<"svmls[_single]_za32[_{d}]_vg1x4", "vm4d", "f", MergeNone, "aarch64_sme_fmls_single_vg1x4", [IsStreaming, IsInOutZA], []>;
|
||||
|
||||
def SVMLA_LANE_VG1x2_F32 : Inst<"svmla_lane_za32[_{d}]_vg1x2", "vm2di", "f", MergeNone, "aarch64_sme_fmla_lane_vg1x2", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_3>]>;
|
||||
def SVMLA_LANE_VG1x4_F32 : Inst<"svmla_lane_za32[_{d}]_vg1x4", "vm4di", "f", MergeNone, "aarch64_sme_fmla_lane_vg1x4", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_3>]>;
|
||||
def SVMLS_LANE_VG1x2_F32 : Inst<"svmls_lane_za32[_{d}]_vg1x2", "vm2di", "f", MergeNone, "aarch64_sme_fmls_lane_vg1x2", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_3>]>;
|
||||
def SVMLS_LANE_VG1x4_F32 : Inst<"svmls_lane_za32[_{d}]_vg1x4", "vm4di", "f", MergeNone, "aarch64_sme_fmls_lane_vg1x4", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_3>]>;
|
||||
def SVMLA_LANE_VG1x2_F32 : Inst<"svmla_lane_za32[_{d}]_vg1x2", "vm2di", "f", MergeNone, "aarch64_sme_fmla_lane_vg1x2", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_3>]>;
|
||||
def SVMLA_LANE_VG1x4_F32 : Inst<"svmla_lane_za32[_{d}]_vg1x4", "vm4di", "f", MergeNone, "aarch64_sme_fmla_lane_vg1x4", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_3>]>;
|
||||
def SVMLS_LANE_VG1x2_F32 : Inst<"svmls_lane_za32[_{d}]_vg1x2", "vm2di", "f", MergeNone, "aarch64_sme_fmls_lane_vg1x2", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_3>]>;
|
||||
def SVMLS_LANE_VG1x4_F32 : Inst<"svmls_lane_za32[_{d}]_vg1x4", "vm4di", "f", MergeNone, "aarch64_sme_fmls_lane_vg1x4", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_3>]>;
|
||||
}
|
||||
|
||||
let TargetGuard = "sme2,sme-f64f64" in {
|
||||
def SVMLA_MULTI_VG1x2_F64 : Inst<"svmla_za64[_{d}]_vg1x2", "vm22", "d", MergeNone, "aarch64_sme_fmla_vg1x2", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLA_MULTI_VG1x4_F64 : Inst<"svmla_za64[_{d}]_vg1x4", "vm44", "d", MergeNone, "aarch64_sme_fmla_vg1x4", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLS_MULTI_VG1x2_F64 : Inst<"svmls_za64[_{d}]_vg1x2", "vm22", "d", MergeNone, "aarch64_sme_fmls_vg1x2", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLS_MULTI_VG1x4_F64 : Inst<"svmls_za64[_{d}]_vg1x4", "vm44", "d", MergeNone, "aarch64_sme_fmls_vg1x4", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLA_MULTI_VG1x2_F64 : Inst<"svmla_za64[_{d}]_vg1x2", "vm22", "d", MergeNone, "aarch64_sme_fmla_vg1x2", [IsStreaming, IsInOutZA], []>;
|
||||
def SVMLA_MULTI_VG1x4_F64 : Inst<"svmla_za64[_{d}]_vg1x4", "vm44", "d", MergeNone, "aarch64_sme_fmla_vg1x4", [IsStreaming, IsInOutZA], []>;
|
||||
def SVMLS_MULTI_VG1x2_F64 : Inst<"svmls_za64[_{d}]_vg1x2", "vm22", "d", MergeNone, "aarch64_sme_fmls_vg1x2", [IsStreaming, IsInOutZA], []>;
|
||||
def SVMLS_MULTI_VG1x4_F64 : Inst<"svmls_za64[_{d}]_vg1x4", "vm44", "d", MergeNone, "aarch64_sme_fmls_vg1x4", [IsStreaming, IsInOutZA], []>;
|
||||
|
||||
def SVMLA_SINGLE_VG1x2_F64 : Inst<"svmla[_single]_za64[_{d}]_vg1x2", "vm2d", "d", MergeNone, "aarch64_sme_fmla_single_vg1x2", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLA_SINGLE_VG1x4_F64 : Inst<"svmla[_single]_za64[_{d}]_vg1x4", "vm4d", "d", MergeNone, "aarch64_sme_fmla_single_vg1x4", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLS_SINGLE_VG1x2_F64 : Inst<"svmls[_single]_za64[_{d}]_vg1x2", "vm2d", "d", MergeNone, "aarch64_sme_fmls_single_vg1x2", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLS_SINGLE_VG1x4_F64 : Inst<"svmls[_single]_za64[_{d}]_vg1x4", "vm4d", "d", MergeNone, "aarch64_sme_fmls_single_vg1x4", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLA_SINGLE_VG1x2_F64 : Inst<"svmla[_single]_za64[_{d}]_vg1x2", "vm2d", "d", MergeNone, "aarch64_sme_fmla_single_vg1x2", [IsStreaming, IsInOutZA], []>;
|
||||
def SVMLA_SINGLE_VG1x4_F64 : Inst<"svmla[_single]_za64[_{d}]_vg1x4", "vm4d", "d", MergeNone, "aarch64_sme_fmla_single_vg1x4", [IsStreaming, IsInOutZA], []>;
|
||||
def SVMLS_SINGLE_VG1x2_F64 : Inst<"svmls[_single]_za64[_{d}]_vg1x2", "vm2d", "d", MergeNone, "aarch64_sme_fmls_single_vg1x2", [IsStreaming, IsInOutZA], []>;
|
||||
def SVMLS_SINGLE_VG1x4_F64 : Inst<"svmls[_single]_za64[_{d}]_vg1x4", "vm4d", "d", MergeNone, "aarch64_sme_fmls_single_vg1x4", [IsStreaming, IsInOutZA], []>;
|
||||
|
||||
def SVMLA_LANE_VG1x2_F64 : Inst<"svmla_lane_za64[_{d}]_vg1x2", "vm2di", "d", MergeNone, "aarch64_sme_fmla_lane_vg1x2", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_1>]>;
|
||||
def SVMLA_LANE_VG1x4_F64 : Inst<"svmla_lane_za64[_{d}]_vg1x4", "vm4di", "d", MergeNone, "aarch64_sme_fmla_lane_vg1x4", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_1>]>;
|
||||
def SVMLS_LANE_VG1x2_F64 : Inst<"svmls_lane_za64[_{d}]_vg1x2", "vm2di", "d", MergeNone, "aarch64_sme_fmls_lane_vg1x2", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_1>]>;
|
||||
def SVMLS_LANE_VG1x4_F64 : Inst<"svmls_lane_za64[_{d}]_vg1x4", "vm4di", "d", MergeNone, "aarch64_sme_fmls_lane_vg1x4", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_1>]>;
|
||||
def SVMLA_LANE_VG1x2_F64 : Inst<"svmla_lane_za64[_{d}]_vg1x2", "vm2di", "d", MergeNone, "aarch64_sme_fmla_lane_vg1x2", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_1>]>;
|
||||
def SVMLA_LANE_VG1x4_F64 : Inst<"svmla_lane_za64[_{d}]_vg1x4", "vm4di", "d", MergeNone, "aarch64_sme_fmla_lane_vg1x4", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_1>]>;
|
||||
def SVMLS_LANE_VG1x2_F64 : Inst<"svmls_lane_za64[_{d}]_vg1x2", "vm2di", "d", MergeNone, "aarch64_sme_fmls_lane_vg1x2", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_1>]>;
|
||||
def SVMLS_LANE_VG1x4_F64 : Inst<"svmls_lane_za64[_{d}]_vg1x4", "vm4di", "d", MergeNone, "aarch64_sme_fmls_lane_vg1x4", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_1>]>;
|
||||
}
|
||||
|
||||
// FMLAL/FMLSL/UMLAL/SMLAL
|
||||
// SMLALL/UMLALL/USMLALL/SUMLALL
|
||||
let TargetGuard = "sme2" in {
|
||||
// MULTI MLAL
|
||||
def SVMLAL_MULTI_VG2x2_F16 : Inst<"svmla_za32[_{d}]_vg2x2", "vm22", "bh", MergeNone, "aarch64_sme_fmlal_vg2x2", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLAL_MULTI_VG2x4_F16 : Inst<"svmla_za32[_{d}]_vg2x4", "vm44", "bh", MergeNone, "aarch64_sme_fmlal_vg2x4", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLAL_MULTI_VG2x2_S16 : Inst<"svmla_za32[_{d}]_vg2x2", "vm22", "s", MergeNone, "aarch64_sme_smlal_vg2x2", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLAL_MULTI_VG2x4_S16 : Inst<"svmla_za32[_{d}]_vg2x4", "vm44", "s", MergeNone, "aarch64_sme_smlal_vg2x4", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLAL_MULTI_VG2x2_U16 : Inst<"svmla_za32[_{d}]_vg2x2", "vm22", "Us", MergeNone, "aarch64_sme_umlal_vg2x2", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLAL_MULTI_VG2x4_U16 : Inst<"svmla_za32[_{d}]_vg2x4", "vm44", "Us", MergeNone, "aarch64_sme_umlal_vg2x4", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLAL_MULTI_VG2x2_F16 : Inst<"svmla_za32[_{d}]_vg2x2", "vm22", "bh", MergeNone, "aarch64_sme_fmlal_vg2x2", [IsStreaming, IsInOutZA], []>;
|
||||
def SVMLAL_MULTI_VG2x4_F16 : Inst<"svmla_za32[_{d}]_vg2x4", "vm44", "bh", MergeNone, "aarch64_sme_fmlal_vg2x4", [IsStreaming, IsInOutZA], []>;
|
||||
def SVMLAL_MULTI_VG2x2_S16 : Inst<"svmla_za32[_{d}]_vg2x2", "vm22", "s", MergeNone, "aarch64_sme_smlal_vg2x2", [IsStreaming, IsInOutZA], []>;
|
||||
def SVMLAL_MULTI_VG2x4_S16 : Inst<"svmla_za32[_{d}]_vg2x4", "vm44", "s", MergeNone, "aarch64_sme_smlal_vg2x4", [IsStreaming, IsInOutZA], []>;
|
||||
def SVMLAL_MULTI_VG2x2_U16 : Inst<"svmla_za32[_{d}]_vg2x2", "vm22", "Us", MergeNone, "aarch64_sme_umlal_vg2x2", [IsStreaming, IsInOutZA], []>;
|
||||
def SVMLAL_MULTI_VG2x4_U16 : Inst<"svmla_za32[_{d}]_vg2x4", "vm44", "Us", MergeNone, "aarch64_sme_umlal_vg2x4", [IsStreaming, IsInOutZA], []>;
|
||||
|
||||
def SVMLAL_MULTI_VG4x2_S8 : Inst<"svmla_za32[_{d}]_vg4x2", "vm22", "c", MergeNone, "aarch64_sme_smla_za32_vg4x2", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLAL_MULTI_VG4x2_U8 : Inst<"svmla_za32[_{d}]_vg4x2", "vm22", "Uc", MergeNone, "aarch64_sme_umla_za32_vg4x2", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLAL_MULTI_VG4x4_S8 : Inst<"svmla_za32[_{d}]_vg4x4", "vm44", "c", MergeNone, "aarch64_sme_smla_za32_vg4x4", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLAL_MULTI_VG4x4_U8 : Inst<"svmla_za32[_{d}]_vg4x4", "vm44", "Uc", MergeNone, "aarch64_sme_umla_za32_vg4x4", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLAL_MULTI_VG4x2_S8 : Inst<"svmla_za32[_{d}]_vg4x2", "vm22", "c", MergeNone, "aarch64_sme_smla_za32_vg4x2", [IsStreaming, IsInOutZA], []>;
|
||||
def SVMLAL_MULTI_VG4x2_U8 : Inst<"svmla_za32[_{d}]_vg4x2", "vm22", "Uc", MergeNone, "aarch64_sme_umla_za32_vg4x2", [IsStreaming, IsInOutZA], []>;
|
||||
def SVMLAL_MULTI_VG4x4_S8 : Inst<"svmla_za32[_{d}]_vg4x4", "vm44", "c", MergeNone, "aarch64_sme_smla_za32_vg4x4", [IsStreaming, IsInOutZA], []>;
|
||||
def SVMLAL_MULTI_VG4x4_U8 : Inst<"svmla_za32[_{d}]_vg4x4", "vm44", "Uc", MergeNone, "aarch64_sme_umla_za32_vg4x4", [IsStreaming, IsInOutZA], []>;
|
||||
|
||||
// MULTI MLSL
|
||||
def SVMLSL_MULTI_VG2x2_F16 : Inst<"svmls_za32[_{d}]_vg2x2", "vm22", "bh", MergeNone, "aarch64_sme_fmlsl_vg2x2", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLSL_MULTI_VG2x4_F16 : Inst<"svmls_za32[_{d}]_vg2x4", "vm44", "bh", MergeNone, "aarch64_sme_fmlsl_vg2x4", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLSL_MULTI_VG2x2_S16 : Inst<"svmls_za32[_{d}]_vg2x2", "vm22", "s", MergeNone, "aarch64_sme_smlsl_vg2x2", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLSL_MULTI_VG2x4_S16 : Inst<"svmls_za32[_{d}]_vg2x4", "vm44", "s", MergeNone, "aarch64_sme_smlsl_vg2x4", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLSL_MULTI_VG2x2_U16 : Inst<"svmls_za32[_{d}]_vg2x2", "vm22", "Us", MergeNone, "aarch64_sme_umlsl_vg2x2", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLSL_MULTI_VG2x4_U16 : Inst<"svmls_za32[_{d}]_vg2x4", "vm44", "Us", MergeNone, "aarch64_sme_umlsl_vg2x4", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLSL_MULTI_VG2x2_F16 : Inst<"svmls_za32[_{d}]_vg2x2", "vm22", "bh", MergeNone, "aarch64_sme_fmlsl_vg2x2", [IsStreaming, IsInOutZA], []>;
|
||||
def SVMLSL_MULTI_VG2x4_F16 : Inst<"svmls_za32[_{d}]_vg2x4", "vm44", "bh", MergeNone, "aarch64_sme_fmlsl_vg2x4", [IsStreaming, IsInOutZA], []>;
|
||||
def SVMLSL_MULTI_VG2x2_S16 : Inst<"svmls_za32[_{d}]_vg2x2", "vm22", "s", MergeNone, "aarch64_sme_smlsl_vg2x2", [IsStreaming, IsInOutZA], []>;
|
||||
def SVMLSL_MULTI_VG2x4_S16 : Inst<"svmls_za32[_{d}]_vg2x4", "vm44", "s", MergeNone, "aarch64_sme_smlsl_vg2x4", [IsStreaming, IsInOutZA], []>;
|
||||
def SVMLSL_MULTI_VG2x2_U16 : Inst<"svmls_za32[_{d}]_vg2x2", "vm22", "Us", MergeNone, "aarch64_sme_umlsl_vg2x2", [IsStreaming, IsInOutZA], []>;
|
||||
def SVMLSL_MULTI_VG2x4_U16 : Inst<"svmls_za32[_{d}]_vg2x4", "vm44", "Us", MergeNone, "aarch64_sme_umlsl_vg2x4", [IsStreaming, IsInOutZA], []>;
|
||||
|
||||
def SVMLSL_MULTI_VG4x2_S8 : Inst<"svmls_za32[_{d}]_vg4x2", "vm22", "c", MergeNone, "aarch64_sme_smls_za32_vg4x2", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLSL_MULTI_VG4x2_U8 : Inst<"svmls_za32[_{d}]_vg4x2", "vm22", "Uc", MergeNone, "aarch64_sme_umls_za32_vg4x2", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLSL_MULTI_VG4x4_S8 : Inst<"svmls_za32[_{d}]_vg4x4", "vm44", "c", MergeNone, "aarch64_sme_smls_za32_vg4x4", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLSL_MULTI_VG4x4_U8 : Inst<"svmls_za32[_{d}]_vg4x4", "vm44", "Uc", MergeNone, "aarch64_sme_umls_za32_vg4x4", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLSL_MULTI_VG4x2_S8 : Inst<"svmls_za32[_{d}]_vg4x2", "vm22", "c", MergeNone, "aarch64_sme_smls_za32_vg4x2", [IsStreaming, IsInOutZA], []>;
|
||||
def SVMLSL_MULTI_VG4x2_U8 : Inst<"svmls_za32[_{d}]_vg4x2", "vm22", "Uc", MergeNone, "aarch64_sme_umls_za32_vg4x2", [IsStreaming, IsInOutZA], []>;
|
||||
def SVMLSL_MULTI_VG4x4_S8 : Inst<"svmls_za32[_{d}]_vg4x4", "vm44", "c", MergeNone, "aarch64_sme_smls_za32_vg4x4", [IsStreaming, IsInOutZA], []>;
|
||||
def SVMLSL_MULTI_VG4x4_U8 : Inst<"svmls_za32[_{d}]_vg4x4", "vm44", "Uc", MergeNone, "aarch64_sme_umls_za32_vg4x4", [IsStreaming, IsInOutZA], []>;
|
||||
|
||||
// SINGLE MLAL
|
||||
def SVMLAL_SINGLE_VG2x1_F16 : Inst<"svmla_za32[_{d}]_vg2x1", "vmdd", "bh", MergeNone, "aarch64_sme_fmlal_single_vg2x1", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLAL_SINGLE_VG2x2_F16 : Inst<"svmla[_single]_za32[_{d}]_vg2x2", "vm2d", "bh", MergeNone, "aarch64_sme_fmlal_single_vg2x2", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLAL_SINGLE_VG2x4_F16 : Inst<"svmla[_single]_za32[_{d}]_vg2x4", "vm4d", "bh", MergeNone, "aarch64_sme_fmlal_single_vg2x4", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLAL_SINGLE_VG2x1_S16 : Inst<"svmla_za32[_{d}]_vg2x1", "vmdd", "s", MergeNone, "aarch64_sme_smlal_single_vg2x1", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLAL_SINGLE_VG2x2_S16 : Inst<"svmla[_single]_za32[_{d}]_vg2x2", "vm2d", "s", MergeNone, "aarch64_sme_smlal_single_vg2x2", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLAL_SINGLE_VG2x4_S16 : Inst<"svmla[_single]_za32[_{d}]_vg2x4", "vm4d", "s", MergeNone, "aarch64_sme_smlal_single_vg2x4", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLAL_SINGLE_VG2x1_U16 : Inst<"svmla_za32[_{d}]_vg2x1", "vmdd", "Us", MergeNone, "aarch64_sme_umlal_single_vg2x1", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLAL_SINGLE_VG2x2_U16 : Inst<"svmla[_single]_za32[_{d}]_vg2x2", "vm2d", "Us", MergeNone, "aarch64_sme_umlal_single_vg2x2", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLAL_SINGLE_VG2x4_U16 : Inst<"svmla[_single]_za32[_{d}]_vg2x4", "vm4d", "Us", MergeNone, "aarch64_sme_umlal_single_vg2x4", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLAL_SINGLE_VG2x1_F16 : Inst<"svmla_za32[_{d}]_vg2x1", "vmdd", "bh", MergeNone, "aarch64_sme_fmlal_single_vg2x1", [IsStreaming, IsInOutZA], []>;
|
||||
def SVMLAL_SINGLE_VG2x2_F16 : Inst<"svmla[_single]_za32[_{d}]_vg2x2", "vm2d", "bh", MergeNone, "aarch64_sme_fmlal_single_vg2x2", [IsStreaming, IsInOutZA], []>;
|
||||
def SVMLAL_SINGLE_VG2x4_F16 : Inst<"svmla[_single]_za32[_{d}]_vg2x4", "vm4d", "bh", MergeNone, "aarch64_sme_fmlal_single_vg2x4", [IsStreaming, IsInOutZA], []>;
|
||||
def SVMLAL_SINGLE_VG2x1_S16 : Inst<"svmla_za32[_{d}]_vg2x1", "vmdd", "s", MergeNone, "aarch64_sme_smlal_single_vg2x1", [IsStreaming, IsInOutZA], []>;
|
||||
def SVMLAL_SINGLE_VG2x2_S16 : Inst<"svmla[_single]_za32[_{d}]_vg2x2", "vm2d", "s", MergeNone, "aarch64_sme_smlal_single_vg2x2", [IsStreaming, IsInOutZA], []>;
|
||||
def SVMLAL_SINGLE_VG2x4_S16 : Inst<"svmla[_single]_za32[_{d}]_vg2x4", "vm4d", "s", MergeNone, "aarch64_sme_smlal_single_vg2x4", [IsStreaming, IsInOutZA], []>;
|
||||
def SVMLAL_SINGLE_VG2x1_U16 : Inst<"svmla_za32[_{d}]_vg2x1", "vmdd", "Us", MergeNone, "aarch64_sme_umlal_single_vg2x1", [IsStreaming, IsInOutZA], []>;
|
||||
def SVMLAL_SINGLE_VG2x2_U16 : Inst<"svmla[_single]_za32[_{d}]_vg2x2", "vm2d", "Us", MergeNone, "aarch64_sme_umlal_single_vg2x2", [IsStreaming, IsInOutZA], []>;
|
||||
def SVMLAL_SINGLE_VG2x4_U16 : Inst<"svmla[_single]_za32[_{d}]_vg2x4", "vm4d", "Us", MergeNone, "aarch64_sme_umlal_single_vg2x4", [IsStreaming, IsInOutZA], []>;
|
||||
|
||||
def SVMLAL_SINGLE_VG4x1_S8 : Inst<"svmla_za32[_{d}]_vg4x1", "vmdd", "c", MergeNone, "aarch64_sme_smla_za32_single_vg4x1", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLAL_SINGLE_VG4x1_U8 : Inst<"svmla_za32[_{d}]_vg4x1", "vmdd", "Uc", MergeNone, "aarch64_sme_umla_za32_single_vg4x1", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLAL_SINGLE_VG4x2_S8 : Inst<"svmla[_single]_za32[_{d}]_vg4x2", "vm2d", "c", MergeNone, "aarch64_sme_smla_za32_single_vg4x2", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLAL_SINGLE_VG4x2_U8 : Inst<"svmla[_single]_za32[_{d}]_vg4x2", "vm2d", "Uc", MergeNone, "aarch64_sme_umla_za32_single_vg4x2", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLAL_SINGLE_VG4x4_S8 : Inst<"svmla[_single]_za32[_{d}]_vg4x4", "vm4d", "c", MergeNone, "aarch64_sme_smla_za32_single_vg4x4", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLAL_SINGLE_VG4x4_U8 : Inst<"svmla[_single]_za32[_{d}]_vg4x4", "vm4d", "Uc", MergeNone, "aarch64_sme_umla_za32_single_vg4x4", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLAL_SINGLE_VG4x1_S8 : Inst<"svmla_za32[_{d}]_vg4x1", "vmdd", "c", MergeNone, "aarch64_sme_smla_za32_single_vg4x1", [IsStreaming, IsInOutZA], []>;
|
||||
def SVMLAL_SINGLE_VG4x1_U8 : Inst<"svmla_za32[_{d}]_vg4x1", "vmdd", "Uc", MergeNone, "aarch64_sme_umla_za32_single_vg4x1", [IsStreaming, IsInOutZA], []>;
|
||||
def SVMLAL_SINGLE_VG4x2_S8 : Inst<"svmla[_single]_za32[_{d}]_vg4x2", "vm2d", "c", MergeNone, "aarch64_sme_smla_za32_single_vg4x2", [IsStreaming, IsInOutZA], []>;
|
||||
def SVMLAL_SINGLE_VG4x2_U8 : Inst<"svmla[_single]_za32[_{d}]_vg4x2", "vm2d", "Uc", MergeNone, "aarch64_sme_umla_za32_single_vg4x2", [IsStreaming, IsInOutZA], []>;
|
||||
def SVMLAL_SINGLE_VG4x4_S8 : Inst<"svmla[_single]_za32[_{d}]_vg4x4", "vm4d", "c", MergeNone, "aarch64_sme_smla_za32_single_vg4x4", [IsStreaming, IsInOutZA], []>;
|
||||
def SVMLAL_SINGLE_VG4x4_U8 : Inst<"svmla[_single]_za32[_{d}]_vg4x4", "vm4d", "Uc", MergeNone, "aarch64_sme_umla_za32_single_vg4x4", [IsStreaming, IsInOutZA], []>;
|
||||
|
||||
// SINGLE MLSL
|
||||
def SVMLSL_SINGLE_VG2x1_F16 : Inst<"svmls_za32[_{d}]_vg2x1", "vmdd", "bh", MergeNone, "aarch64_sme_fmlsl_single_vg2x1", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLSL_SINGLE_VG2x2_F16 : Inst<"svmls[_single]_za32[_{d}]_vg2x2", "vm2d", "bh", MergeNone, "aarch64_sme_fmlsl_single_vg2x2", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLSL_SINGLE_VG2x4_F16 : Inst<"svmls[_single]_za32[_{d}]_vg2x4", "vm4d", "bh", MergeNone, "aarch64_sme_fmlsl_single_vg2x4", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLSL_SINGLE_VG2x1_S16 : Inst<"svmls_za32[_{d}]_vg2x1", "vmdd", "s", MergeNone, "aarch64_sme_smlsl_single_vg2x1", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLSL_SINGLE_VG2x2_S16 : Inst<"svmls[_single]_za32[_{d}]_vg2x2", "vm2d", "s", MergeNone, "aarch64_sme_smlsl_single_vg2x2", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLSL_SINGLE_VG2x4_S16 : Inst<"svmls[_single]_za32[_{d}]_vg2x4", "vm4d", "s", MergeNone, "aarch64_sme_smlsl_single_vg2x4", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLSL_SINGLE_VG2x1_U16 : Inst<"svmls_za32[_{d}]_vg2x1", "vmdd", "Us", MergeNone, "aarch64_sme_umlsl_single_vg2x1", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLSL_SINGLE_VG2x2_U16 : Inst<"svmls[_single]_za32[_{d}]_vg2x2", "vm2d", "Us", MergeNone, "aarch64_sme_umlsl_single_vg2x2", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLSL_SINGLE_VG2x4_U16 : Inst<"svmls[_single]_za32[_{d}]_vg2x4", "vm4d", "Us", MergeNone, "aarch64_sme_umlsl_single_vg2x4", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLSL_SINGLE_VG2x1_F16 : Inst<"svmls_za32[_{d}]_vg2x1", "vmdd", "bh", MergeNone, "aarch64_sme_fmlsl_single_vg2x1", [IsStreaming, IsInOutZA], []>;
|
||||
def SVMLSL_SINGLE_VG2x2_F16 : Inst<"svmls[_single]_za32[_{d}]_vg2x2", "vm2d", "bh", MergeNone, "aarch64_sme_fmlsl_single_vg2x2", [IsStreaming, IsInOutZA], []>;
|
||||
def SVMLSL_SINGLE_VG2x4_F16 : Inst<"svmls[_single]_za32[_{d}]_vg2x4", "vm4d", "bh", MergeNone, "aarch64_sme_fmlsl_single_vg2x4", [IsStreaming, IsInOutZA], []>;
|
||||
def SVMLSL_SINGLE_VG2x1_S16 : Inst<"svmls_za32[_{d}]_vg2x1", "vmdd", "s", MergeNone, "aarch64_sme_smlsl_single_vg2x1", [IsStreaming, IsInOutZA], []>;
|
||||
def SVMLSL_SINGLE_VG2x2_S16 : Inst<"svmls[_single]_za32[_{d}]_vg2x2", "vm2d", "s", MergeNone, "aarch64_sme_smlsl_single_vg2x2", [IsStreaming, IsInOutZA], []>;
|
||||
def SVMLSL_SINGLE_VG2x4_S16 : Inst<"svmls[_single]_za32[_{d}]_vg2x4", "vm4d", "s", MergeNone, "aarch64_sme_smlsl_single_vg2x4", [IsStreaming, IsInOutZA], []>;
|
||||
def SVMLSL_SINGLE_VG2x1_U16 : Inst<"svmls_za32[_{d}]_vg2x1", "vmdd", "Us", MergeNone, "aarch64_sme_umlsl_single_vg2x1", [IsStreaming, IsInOutZA], []>;
|
||||
def SVMLSL_SINGLE_VG2x2_U16 : Inst<"svmls[_single]_za32[_{d}]_vg2x2", "vm2d", "Us", MergeNone, "aarch64_sme_umlsl_single_vg2x2", [IsStreaming, IsInOutZA], []>;
|
||||
def SVMLSL_SINGLE_VG2x4_U16 : Inst<"svmls[_single]_za32[_{d}]_vg2x4", "vm4d", "Us", MergeNone, "aarch64_sme_umlsl_single_vg2x4", [IsStreaming, IsInOutZA], []>;
|
||||
|
||||
def SVMLSL_SINGLE_VG4x1_S8 : Inst<"svmls_za32[_{d}]_vg4x1", "vmdd", "c", MergeNone, "aarch64_sme_smls_za32_single_vg4x1", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLSL_SINGLE_VG4x1_U8 : Inst<"svmls_za32[_{d}]_vg4x1", "vmdd", "Uc", MergeNone, "aarch64_sme_umls_za32_single_vg4x1", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLSL_SINGLE_VG4x2_S8 : Inst<"svmls[_single]_za32[_{d}]_vg4x2", "vm2d", "c", MergeNone, "aarch64_sme_smls_za32_single_vg4x2", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLSL_SINGLE_VG4x2_U8 : Inst<"svmls[_single]_za32[_{d}]_vg4x2", "vm2d", "Uc", MergeNone, "aarch64_sme_umls_za32_single_vg4x2", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLSL_SINGLE_VG4x4_S8 : Inst<"svmls[_single]_za32[_{d}]_vg4x4", "vm4d", "c", MergeNone, "aarch64_sme_smls_za32_single_vg4x4", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLSL_SINGLE_VG4x4_U8 : Inst<"svmls[_single]_za32[_{d}]_vg4x4", "vm4d", "Uc", MergeNone, "aarch64_sme_umls_za32_single_vg4x4", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLSL_SINGLE_VG4x1_S8 : Inst<"svmls_za32[_{d}]_vg4x1", "vmdd", "c", MergeNone, "aarch64_sme_smls_za32_single_vg4x1", [IsStreaming, IsInOutZA], []>;
|
||||
def SVMLSL_SINGLE_VG4x1_U8 : Inst<"svmls_za32[_{d}]_vg4x1", "vmdd", "Uc", MergeNone, "aarch64_sme_umls_za32_single_vg4x1", [IsStreaming, IsInOutZA], []>;
|
||||
def SVMLSL_SINGLE_VG4x2_S8 : Inst<"svmls[_single]_za32[_{d}]_vg4x2", "vm2d", "c", MergeNone, "aarch64_sme_smls_za32_single_vg4x2", [IsStreaming, IsInOutZA], []>;
|
||||
def SVMLSL_SINGLE_VG4x2_U8 : Inst<"svmls[_single]_za32[_{d}]_vg4x2", "vm2d", "Uc", MergeNone, "aarch64_sme_umls_za32_single_vg4x2", [IsStreaming, IsInOutZA], []>;
|
||||
def SVMLSL_SINGLE_VG4x4_S8 : Inst<"svmls[_single]_za32[_{d}]_vg4x4", "vm4d", "c", MergeNone, "aarch64_sme_smls_za32_single_vg4x4", [IsStreaming, IsInOutZA], []>;
|
||||
def SVMLSL_SINGLE_VG4x4_U8 : Inst<"svmls[_single]_za32[_{d}]_vg4x4", "vm4d", "Uc", MergeNone, "aarch64_sme_umls_za32_single_vg4x4", [IsStreaming, IsInOutZA], []>;
|
||||
|
||||
// INDEXED MLAL
|
||||
def SVMLAL_LANE_VG2x1_F16 : Inst<"svmla_lane_za32[_{d}]_vg2x1", "vmddi", "bh", MergeNone, "aarch64_sme_fmlal_lane_vg2x1", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_7>]>;
|
||||
def SVMLAL_LANE_VG2x2_F16 : Inst<"svmla_lane_za32[_{d}]_vg2x2", "vm2di", "bh", MergeNone, "aarch64_sme_fmlal_lane_vg2x2", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_7>]>;
|
||||
def SVMLAL_LANE_VG2x4_F16 : Inst<"svmla_lane_za32[_{d}]_vg2x4", "vm4di", "bh", MergeNone, "aarch64_sme_fmlal_lane_vg2x4", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_7>]>;
|
||||
def SVMLAL_LANE_VG2x1_S16 : Inst<"svmla_lane_za32[_{d}]_vg2x1", "vmddi", "s", MergeNone, "aarch64_sme_smlal_lane_vg2x1", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_7>]>;
|
||||
def SVMLAL_LANE_VG2x2_S16 : Inst<"svmla_lane_za32[_{d}]_vg2x2", "vm2di", "s", MergeNone, "aarch64_sme_smlal_lane_vg2x2", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_7>]>;
|
||||
def SVMLAL_LANE_VG2x4_S16 : Inst<"svmla_lane_za32[_{d}]_vg2x4", "vm4di", "s", MergeNone, "aarch64_sme_smlal_lane_vg2x4", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_7>]>;
|
||||
def SVMLAL_LANE_VG2x1_U16 : Inst<"svmla_lane_za32[_{d}]_vg2x1", "vmddi", "Us", MergeNone, "aarch64_sme_umlal_lane_vg2x1", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_7>]>;
|
||||
def SVMLAL_LANE_VG2x2_U16 : Inst<"svmla_lane_za32[_{d}]_vg2x2", "vm2di", "Us", MergeNone, "aarch64_sme_umlal_lane_vg2x2", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_7>]>;
|
||||
def SVMLAL_LANE_VG2x4_U16 : Inst<"svmla_lane_za32[_{d}]_vg2x4", "vm4di", "Us", MergeNone, "aarch64_sme_umlal_lane_vg2x4", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_7>]>;
|
||||
def SVMLAL_LANE_VG2x1_F16 : Inst<"svmla_lane_za32[_{d}]_vg2x1", "vmddi", "bh", MergeNone, "aarch64_sme_fmlal_lane_vg2x1", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_7>]>;
|
||||
def SVMLAL_LANE_VG2x2_F16 : Inst<"svmla_lane_za32[_{d}]_vg2x2", "vm2di", "bh", MergeNone, "aarch64_sme_fmlal_lane_vg2x2", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_7>]>;
|
||||
def SVMLAL_LANE_VG2x4_F16 : Inst<"svmla_lane_za32[_{d}]_vg2x4", "vm4di", "bh", MergeNone, "aarch64_sme_fmlal_lane_vg2x4", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_7>]>;
|
||||
def SVMLAL_LANE_VG2x1_S16 : Inst<"svmla_lane_za32[_{d}]_vg2x1", "vmddi", "s", MergeNone, "aarch64_sme_smlal_lane_vg2x1", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_7>]>;
|
||||
def SVMLAL_LANE_VG2x2_S16 : Inst<"svmla_lane_za32[_{d}]_vg2x2", "vm2di", "s", MergeNone, "aarch64_sme_smlal_lane_vg2x2", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_7>]>;
|
||||
def SVMLAL_LANE_VG2x4_S16 : Inst<"svmla_lane_za32[_{d}]_vg2x4", "vm4di", "s", MergeNone, "aarch64_sme_smlal_lane_vg2x4", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_7>]>;
|
||||
def SVMLAL_LANE_VG2x1_U16 : Inst<"svmla_lane_za32[_{d}]_vg2x1", "vmddi", "Us", MergeNone, "aarch64_sme_umlal_lane_vg2x1", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_7>]>;
|
||||
def SVMLAL_LANE_VG2x2_U16 : Inst<"svmla_lane_za32[_{d}]_vg2x2", "vm2di", "Us", MergeNone, "aarch64_sme_umlal_lane_vg2x2", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_7>]>;
|
||||
def SVMLAL_LANE_VG2x4_U16 : Inst<"svmla_lane_za32[_{d}]_vg2x4", "vm4di", "Us", MergeNone, "aarch64_sme_umlal_lane_vg2x4", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_7>]>;
|
||||
|
||||
def SVMLAL_LANE_VG4x1_S8 : Inst<"svmla_lane_za32[_{d}]_vg4x1", "vmddi", "c", MergeNone, "aarch64_sme_smla_za32_lane_vg4x1", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_15>]>;
|
||||
def SVMLAL_LANE_VG4x1_U8 : Inst<"svmla_lane_za32[_{d}]_vg4x1", "vmddi", "Uc", MergeNone, "aarch64_sme_umla_za32_lane_vg4x1", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_15>]>;
|
||||
def SVMLAL_LANE_VG4x2_S8 : Inst<"svmla_lane_za32[_{d}]_vg4x2", "vm2di", "c", MergeNone, "aarch64_sme_smla_za32_lane_vg4x2", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_15>]>;
|
||||
def SVMLAL_LANE_VG4x2_U8 : Inst<"svmla_lane_za32[_{d}]_vg4x2", "vm2di", "Uc", MergeNone, "aarch64_sme_umla_za32_lane_vg4x2", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_15>]>;
|
||||
def SVMLAL_LANE_VG4x4_S8 : Inst<"svmla_lane_za32[_{d}]_vg4x4", "vm4di", "c", MergeNone, "aarch64_sme_smla_za32_lane_vg4x4", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_15>]>;
|
||||
def SVMLAL_LANE_VG4x4_U8 : Inst<"svmla_lane_za32[_{d}]_vg4x4", "vm4di", "Uc", MergeNone, "aarch64_sme_umla_za32_lane_vg4x4", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_15>]>;
|
||||
def SVMLAL_LANE_VG4x1_S8 : Inst<"svmla_lane_za32[_{d}]_vg4x1", "vmddi", "c", MergeNone, "aarch64_sme_smla_za32_lane_vg4x1", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_15>]>;
|
||||
def SVMLAL_LANE_VG4x1_U8 : Inst<"svmla_lane_za32[_{d}]_vg4x1", "vmddi", "Uc", MergeNone, "aarch64_sme_umla_za32_lane_vg4x1", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_15>]>;
|
||||
def SVMLAL_LANE_VG4x2_S8 : Inst<"svmla_lane_za32[_{d}]_vg4x2", "vm2di", "c", MergeNone, "aarch64_sme_smla_za32_lane_vg4x2", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_15>]>;
|
||||
def SVMLAL_LANE_VG4x2_U8 : Inst<"svmla_lane_za32[_{d}]_vg4x2", "vm2di", "Uc", MergeNone, "aarch64_sme_umla_za32_lane_vg4x2", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_15>]>;
|
||||
def SVMLAL_LANE_VG4x4_S8 : Inst<"svmla_lane_za32[_{d}]_vg4x4", "vm4di", "c", MergeNone, "aarch64_sme_smla_za32_lane_vg4x4", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_15>]>;
|
||||
def SVMLAL_LANE_VG4x4_U8 : Inst<"svmla_lane_za32[_{d}]_vg4x4", "vm4di", "Uc", MergeNone, "aarch64_sme_umla_za32_lane_vg4x4", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_15>]>;
|
||||
|
||||
// INDEXED MLSL
|
||||
def SVMLSL_LANE_VG2x1_F16 : Inst<"svmls_lane_za32[_{d}]_vg2x1", "vmddi", "bh", MergeNone, "aarch64_sme_fmlsl_lane_vg2x1", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_7>]>;
|
||||
def SVMLSL_LANE_VG2x2_F16 : Inst<"svmls_lane_za32[_{d}]_vg2x2", "vm2di", "bh", MergeNone, "aarch64_sme_fmlsl_lane_vg2x2", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_7>]>;
|
||||
def SVMLSL_LANE_VG2x4_F16 : Inst<"svmls_lane_za32[_{d}]_vg2x4", "vm4di", "bh", MergeNone, "aarch64_sme_fmlsl_lane_vg2x4", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_7>]>;
|
||||
def SVMLSL_LANE_VG2x1_S16 : Inst<"svmls_lane_za32[_{d}]_vg2x1", "vmddi", "s", MergeNone, "aarch64_sme_smlsl_lane_vg2x1", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_7>]>;
|
||||
def SVMLSL_LANE_VG2x2_S16 : Inst<"svmls_lane_za32[_{d}]_vg2x2", "vm2di", "s", MergeNone, "aarch64_sme_smlsl_lane_vg2x2", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_7>]>;
|
||||
def SVMLSL_LANE_VG2x4_S16 : Inst<"svmls_lane_za32[_{d}]_vg2x4", "vm4di", "s", MergeNone, "aarch64_sme_smlsl_lane_vg2x4", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_7>]>;
|
||||
def SVMLSL_LANE_VG2x1_U16 : Inst<"svmls_lane_za32[_{d}]_vg2x1", "vmddi", "Us", MergeNone, "aarch64_sme_umlsl_lane_vg2x1", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_7>]>;
|
||||
def SVMLSL_LANE_VG2x2_U16 : Inst<"svmls_lane_za32[_{d}]_vg2x2", "vm2di", "Us", MergeNone, "aarch64_sme_umlsl_lane_vg2x2", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_7>]>;
|
||||
def SVMLSL_LANE_VG2x4_U16 : Inst<"svmls_lane_za32[_{d}]_vg2x4", "vm4di", "Us", MergeNone, "aarch64_sme_umlsl_lane_vg2x4", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_7>]>;
|
||||
def SVMLSL_LANE_VG2x1_F16 : Inst<"svmls_lane_za32[_{d}]_vg2x1", "vmddi", "bh", MergeNone, "aarch64_sme_fmlsl_lane_vg2x1", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_7>]>;
|
||||
def SVMLSL_LANE_VG2x2_F16 : Inst<"svmls_lane_za32[_{d}]_vg2x2", "vm2di", "bh", MergeNone, "aarch64_sme_fmlsl_lane_vg2x2", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_7>]>;
|
||||
def SVMLSL_LANE_VG2x4_F16 : Inst<"svmls_lane_za32[_{d}]_vg2x4", "vm4di", "bh", MergeNone, "aarch64_sme_fmlsl_lane_vg2x4", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_7>]>;
|
||||
def SVMLSL_LANE_VG2x1_S16 : Inst<"svmls_lane_za32[_{d}]_vg2x1", "vmddi", "s", MergeNone, "aarch64_sme_smlsl_lane_vg2x1", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_7>]>;
|
||||
def SVMLSL_LANE_VG2x2_S16 : Inst<"svmls_lane_za32[_{d}]_vg2x2", "vm2di", "s", MergeNone, "aarch64_sme_smlsl_lane_vg2x2", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_7>]>;
|
||||
def SVMLSL_LANE_VG2x4_S16 : Inst<"svmls_lane_za32[_{d}]_vg2x4", "vm4di", "s", MergeNone, "aarch64_sme_smlsl_lane_vg2x4", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_7>]>;
|
||||
def SVMLSL_LANE_VG2x1_U16 : Inst<"svmls_lane_za32[_{d}]_vg2x1", "vmddi", "Us", MergeNone, "aarch64_sme_umlsl_lane_vg2x1", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_7>]>;
|
||||
def SVMLSL_LANE_VG2x2_U16 : Inst<"svmls_lane_za32[_{d}]_vg2x2", "vm2di", "Us", MergeNone, "aarch64_sme_umlsl_lane_vg2x2", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_7>]>;
|
||||
def SVMLSL_LANE_VG2x4_U16 : Inst<"svmls_lane_za32[_{d}]_vg2x4", "vm4di", "Us", MergeNone, "aarch64_sme_umlsl_lane_vg2x4", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_7>]>;
|
||||
|
||||
def SVMLSL_LANE_VG4x1_S8 : Inst<"svmls_lane_za32[_{d}]_vg4x1", "vmddi", "c", MergeNone, "aarch64_sme_smls_za32_lane_vg4x1", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_15>]>;
|
||||
def SVMLSL_LANE_VG4x1_U8 : Inst<"svmls_lane_za32[_{d}]_vg4x1", "vmddi", "Uc", MergeNone, "aarch64_sme_umls_za32_lane_vg4x1", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_15>]>;
|
||||
def SVMLSL_LANE_VG4x2_S8 : Inst<"svmls_lane_za32[_{d}]_vg4x2", "vm2di", "c", MergeNone, "aarch64_sme_smls_za32_lane_vg4x2", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_15>]>;
|
||||
def SVMLSL_LANE_VG4x2_U8 : Inst<"svmls_lane_za32[_{d}]_vg4x2", "vm2di", "Uc", MergeNone, "aarch64_sme_umls_za32_lane_vg4x2", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_15>]>;
|
||||
def SVMLSL_LANE_VG4x4_S8 : Inst<"svmls_lane_za32[_{d}]_vg4x4", "vm4di", "c", MergeNone, "aarch64_sme_smls_za32_lane_vg4x4", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_15>]>;
|
||||
def SVMLSL_LANE_VG4x4_U8 : Inst<"svmls_lane_za32[_{d}]_vg4x4", "vm4di", "Uc", MergeNone, "aarch64_sme_umls_za32_lane_vg4x4", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_15>]>;
|
||||
def SVMLSL_LANE_VG4x1_S8 : Inst<"svmls_lane_za32[_{d}]_vg4x1", "vmddi", "c", MergeNone, "aarch64_sme_smls_za32_lane_vg4x1", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_15>]>;
|
||||
def SVMLSL_LANE_VG4x1_U8 : Inst<"svmls_lane_za32[_{d}]_vg4x1", "vmddi", "Uc", MergeNone, "aarch64_sme_umls_za32_lane_vg4x1", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_15>]>;
|
||||
def SVMLSL_LANE_VG4x2_S8 : Inst<"svmls_lane_za32[_{d}]_vg4x2", "vm2di", "c", MergeNone, "aarch64_sme_smls_za32_lane_vg4x2", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_15>]>;
|
||||
def SVMLSL_LANE_VG4x2_U8 : Inst<"svmls_lane_za32[_{d}]_vg4x2", "vm2di", "Uc", MergeNone, "aarch64_sme_umls_za32_lane_vg4x2", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_15>]>;
|
||||
def SVMLSL_LANE_VG4x4_S8 : Inst<"svmls_lane_za32[_{d}]_vg4x4", "vm4di", "c", MergeNone, "aarch64_sme_smls_za32_lane_vg4x4", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_15>]>;
|
||||
def SVMLSL_LANE_VG4x4_U8 : Inst<"svmls_lane_za32[_{d}]_vg4x4", "vm4di", "Uc", MergeNone, "aarch64_sme_umls_za32_lane_vg4x4", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_15>]>;
|
||||
|
||||
// SINGLE SUMLALL
|
||||
// Single sumla maps to usmla, with zn & zm operands swapped
|
||||
def SVSUMLALL_SINGLE_VG4x1 : Inst<"svsumla_za32[_{d}]_vg4x1", "vmdu", "c", MergeNone, "aarch64_sme_usmla_za32_single_vg4x1", [IsStreaming, IsSharedZA], []>;
|
||||
def SVSUMLALL_SINGLE_VG4x1 : Inst<"svsumla_za32[_{d}]_vg4x1", "vmdu", "c", MergeNone, "aarch64_sme_usmla_za32_single_vg4x1", [IsStreaming, IsInOutZA], []>;
|
||||
|
||||
def SVSUMLALL_SINGLE_VG4x2 : Inst<"svsumla[_single]_za32[_{d}]_vg4x2", "vm2.du", "c", MergeNone, "aarch64_sme_sumla_za32_single_vg4x2", [IsStreaming, IsSharedZA], []>;
|
||||
def SVSUMLALL_SINGLE_VG4x4 : Inst<"svsumla[_single]_za32[_{d}]_vg4x4", "vm4.du", "c", MergeNone, "aarch64_sme_sumla_za32_single_vg4x4", [IsStreaming, IsSharedZA], []>;
|
||||
def SVSUMLALL_SINGLE_VG4x2 : Inst<"svsumla[_single]_za32[_{d}]_vg4x2", "vm2.du", "c", MergeNone, "aarch64_sme_sumla_za32_single_vg4x2", [IsStreaming, IsInOutZA], []>;
|
||||
def SVSUMLALL_SINGLE_VG4x4 : Inst<"svsumla[_single]_za32[_{d}]_vg4x4", "vm4.du", "c", MergeNone, "aarch64_sme_sumla_za32_single_vg4x4", [IsStreaming, IsInOutZA], []>;
|
||||
|
||||
// Multi-multi sumla builtins are mapped to usmla, with zn & zm operands swapped
|
||||
def SVSUMLALL_MULTI_VG4x2 : Inst<"svsumla_za32[_{d}]_vg4x2", "vm2.d2.u", "c", MergeNone, "aarch64_sme_usmla_za32_vg4x2", [IsStreaming, IsSharedZA], []>;
|
||||
def SVSUMLALL_MULTI_VG4x4 : Inst<"svsumla_za32[_{d}]_vg4x4", "vm4.d4.u", "c", MergeNone, "aarch64_sme_usmla_za32_vg4x4", [IsStreaming, IsSharedZA], []>;
|
||||
def SVSUMLALL_MULTI_VG4x2 : Inst<"svsumla_za32[_{d}]_vg4x2", "vm2.d2.u", "c", MergeNone, "aarch64_sme_usmla_za32_vg4x2", [IsStreaming, IsInOutZA], []>;
|
||||
def SVSUMLALL_MULTI_VG4x4 : Inst<"svsumla_za32[_{d}]_vg4x4", "vm4.d4.u", "c", MergeNone, "aarch64_sme_usmla_za32_vg4x4", [IsStreaming, IsInOutZA], []>;
|
||||
|
||||
// INDEXED SUMLALL
|
||||
def SVSUMLALL_LANE_VG4x1 : Inst<"svsumla_lane_za32[_{d}]_vg4x1", "vmdui", "c", MergeNone, "aarch64_sme_sumla_za32_lane_vg4x1", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_15>]>;
|
||||
def SVSUMLALL_LANE_VG4x2 : Inst<"svsumla_lane_za32[_{d}]_vg4x2", "vm2ui", "c", MergeNone, "aarch64_sme_sumla_za32_lane_vg4x2", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_15>]>;
|
||||
def SVSUMLALL_LANE_VG4x4 : Inst<"svsumla_lane_za32[_{d}]_vg4x4", "vm4ui", "c", MergeNone, "aarch64_sme_sumla_za32_lane_vg4x4", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_15>]>;
|
||||
def SVSUMLALL_LANE_VG4x1 : Inst<"svsumla_lane_za32[_{d}]_vg4x1", "vmdui", "c", MergeNone, "aarch64_sme_sumla_za32_lane_vg4x1", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_15>]>;
|
||||
def SVSUMLALL_LANE_VG4x2 : Inst<"svsumla_lane_za32[_{d}]_vg4x2", "vm2ui", "c", MergeNone, "aarch64_sme_sumla_za32_lane_vg4x2", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_15>]>;
|
||||
def SVSUMLALL_LANE_VG4x4 : Inst<"svsumla_lane_za32[_{d}]_vg4x4", "vm4ui", "c", MergeNone, "aarch64_sme_sumla_za32_lane_vg4x4", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_15>]>;
|
||||
|
||||
// SINGLE USMLALL
|
||||
def SVUSMLALL_SINGLE_VG4x1 : Inst<"svusmla_za32[_{d}]_vg4x1", "vmdx", "Uc", MergeNone, "aarch64_sme_usmla_za32_single_vg4x1", [IsStreaming, IsSharedZA], []>;
|
||||
def SVUSMLALL_SINGLE_VG4x2 : Inst<"svusmla[_single]_za32[_{d}]_vg4x2", "vm2.dx", "Uc", MergeNone, "aarch64_sme_usmla_za32_single_vg4x2", [IsStreaming, IsSharedZA], []>;
|
||||
def SVUSMLALL_SINGLE_VG4x4 : Inst<"svusmla[_single]_za32[_{d}]_vg4x4", "vm4.dx", "Uc", MergeNone, "aarch64_sme_usmla_za32_single_vg4x4", [IsStreaming, IsSharedZA], []>;
|
||||
def SVUSMLALL_SINGLE_VG4x1 : Inst<"svusmla_za32[_{d}]_vg4x1", "vmdx", "Uc", MergeNone, "aarch64_sme_usmla_za32_single_vg4x1", [IsStreaming, IsInOutZA], []>;
|
||||
def SVUSMLALL_SINGLE_VG4x2 : Inst<"svusmla[_single]_za32[_{d}]_vg4x2", "vm2.dx", "Uc", MergeNone, "aarch64_sme_usmla_za32_single_vg4x2", [IsStreaming, IsInOutZA], []>;
|
||||
def SVUSMLALL_SINGLE_VG4x4 : Inst<"svusmla[_single]_za32[_{d}]_vg4x4", "vm4.dx", "Uc", MergeNone, "aarch64_sme_usmla_za32_single_vg4x4", [IsStreaming, IsInOutZA], []>;
|
||||
|
||||
// MULTI USMLALL
|
||||
def SVUSMLALL_MULTI_VG4x2 : Inst<"svusmla_za32[_{d}]_vg4x2", "vm2.d2.x", "Uc", MergeNone, "aarch64_sme_usmla_za32_vg4x2", [IsStreaming, IsSharedZA], []>;
|
||||
def SVUSMLALL_MULTI_VG4x4 : Inst<"svusmla_za32[_{d}]_vg4x4", "vm4.d4.x", "Uc", MergeNone, "aarch64_sme_usmla_za32_vg4x4", [IsStreaming, IsSharedZA], []>;
|
||||
def SVUSMLALL_MULTI_VG4x2 : Inst<"svusmla_za32[_{d}]_vg4x2", "vm2.d2.x", "Uc", MergeNone, "aarch64_sme_usmla_za32_vg4x2", [IsStreaming, IsInOutZA], []>;
|
||||
def SVUSMLALL_MULTI_VG4x4 : Inst<"svusmla_za32[_{d}]_vg4x4", "vm4.d4.x", "Uc", MergeNone, "aarch64_sme_usmla_za32_vg4x4", [IsStreaming, IsInOutZA], []>;
|
||||
|
||||
// INDEXED USMLALL
|
||||
def SVUSMLALL_LANE_VG4x1 : Inst<"svusmla_lane_za32[_{d}]_vg4x1", "vmdxi", "Uc", MergeNone, "aarch64_sme_usmla_za32_lane_vg4x1", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_15>]>;
|
||||
def SVUSMLALL_LANE_VG4x2 : Inst<"svusmla_lane_za32[_{d}]_vg4x2", "vm2xi", "Uc", MergeNone, "aarch64_sme_usmla_za32_lane_vg4x2", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_15>]>;
|
||||
def SVUSMLALL_LANE_VG4x4 : Inst<"svusmla_lane_za32[_{d}]_vg4x4", "vm4xi", "Uc", MergeNone, "aarch64_sme_usmla_za32_lane_vg4x4", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_15>]>;
|
||||
def SVUSMLALL_LANE_VG4x1 : Inst<"svusmla_lane_za32[_{d}]_vg4x1", "vmdxi", "Uc", MergeNone, "aarch64_sme_usmla_za32_lane_vg4x1", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_15>]>;
|
||||
def SVUSMLALL_LANE_VG4x2 : Inst<"svusmla_lane_za32[_{d}]_vg4x2", "vm2xi", "Uc", MergeNone, "aarch64_sme_usmla_za32_lane_vg4x2", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_15>]>;
|
||||
def SVUSMLALL_LANE_VG4x4 : Inst<"svusmla_lane_za32[_{d}]_vg4x4", "vm4xi", "Uc", MergeNone, "aarch64_sme_usmla_za32_lane_vg4x4", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_15>]>;
|
||||
}
|
||||
|
||||
let TargetGuard = "sme2,sme-i16i64" in {
|
||||
// MULTI MLAL
|
||||
def SVMLAL_MULTI_VG4x2_S16 : Inst<"svmla_za64[_{d}]_vg4x2", "vm22", "s", MergeNone, "aarch64_sme_smla_za64_vg4x2", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLAL_MULTI_VG4x2_U16 : Inst<"svmla_za64[_{d}]_vg4x2", "vm22", "Us", MergeNone, "aarch64_sme_umla_za64_vg4x2", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLAL_MULTI_VG4x4_S16 : Inst<"svmla_za64[_{d}]_vg4x4", "vm44", "s", MergeNone, "aarch64_sme_smla_za64_vg4x4", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLAL_MULTI_VG4x4_U16 : Inst<"svmla_za64[_{d}]_vg4x4", "vm44", "Us", MergeNone, "aarch64_sme_umla_za64_vg4x4", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLAL_MULTI_VG4x2_S16 : Inst<"svmla_za64[_{d}]_vg4x2", "vm22", "s", MergeNone, "aarch64_sme_smla_za64_vg4x2", [IsStreaming, IsInOutZA], []>;
|
||||
def SVMLAL_MULTI_VG4x2_U16 : Inst<"svmla_za64[_{d}]_vg4x2", "vm22", "Us", MergeNone, "aarch64_sme_umla_za64_vg4x2", [IsStreaming, IsInOutZA], []>;
|
||||
def SVMLAL_MULTI_VG4x4_S16 : Inst<"svmla_za64[_{d}]_vg4x4", "vm44", "s", MergeNone, "aarch64_sme_smla_za64_vg4x4", [IsStreaming, IsInOutZA], []>;
|
||||
def SVMLAL_MULTI_VG4x4_U16 : Inst<"svmla_za64[_{d}]_vg4x4", "vm44", "Us", MergeNone, "aarch64_sme_umla_za64_vg4x4", [IsStreaming, IsInOutZA], []>;
|
||||
|
||||
// MULTI MLSL
|
||||
def SVMLSL_MULTI_VG4x2_S16 : Inst<"svmls_za64[_{d}]_vg4x2", "vm22", "s", MergeNone, "aarch64_sme_smls_za64_vg4x2", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLSL_MULTI_VG4x2_U16 : Inst<"svmls_za64[_{d}]_vg4x2", "vm22", "Us", MergeNone, "aarch64_sme_umls_za64_vg4x2", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLSL_MULTI_VG4x4_S16 : Inst<"svmls_za64[_{d}]_vg4x4", "vm44", "s", MergeNone, "aarch64_sme_smls_za64_vg4x4", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLSL_MULTI_VG4x4_U16 : Inst<"svmls_za64[_{d}]_vg4x4", "vm44", "Us", MergeNone, "aarch64_sme_umls_za64_vg4x4", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLSL_MULTI_VG4x2_S16 : Inst<"svmls_za64[_{d}]_vg4x2", "vm22", "s", MergeNone, "aarch64_sme_smls_za64_vg4x2", [IsStreaming, IsInOutZA], []>;
|
||||
def SVMLSL_MULTI_VG4x2_U16 : Inst<"svmls_za64[_{d}]_vg4x2", "vm22", "Us", MergeNone, "aarch64_sme_umls_za64_vg4x2", [IsStreaming, IsInOutZA], []>;
|
||||
def SVMLSL_MULTI_VG4x4_S16 : Inst<"svmls_za64[_{d}]_vg4x4", "vm44", "s", MergeNone, "aarch64_sme_smls_za64_vg4x4", [IsStreaming, IsInOutZA], []>;
|
||||
def SVMLSL_MULTI_VG4x4_U16 : Inst<"svmls_za64[_{d}]_vg4x4", "vm44", "Us", MergeNone, "aarch64_sme_umls_za64_vg4x4", [IsStreaming, IsInOutZA], []>;
|
||||
|
||||
// SINGLE MLAL
|
||||
def SVMLAL_SINGLE_VG4x1_S16 : Inst<"svmla_za64[_{d}]_vg4x1", "vmdd", "s", MergeNone, "aarch64_sme_smla_za64_single_vg4x1", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLAL_SINGLE_VG4x1_U16 : Inst<"svmla_za64[_{d}]_vg4x1", "vmdd", "Us", MergeNone, "aarch64_sme_umla_za64_single_vg4x1", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLAL_SINGLE_VG4x2_S16 : Inst<"svmla[_single]_za64[_{d}]_vg4x2", "vm2d", "s", MergeNone, "aarch64_sme_smla_za64_single_vg4x2", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLAL_SINGLE_VG4x2_U16 : Inst<"svmla[_single]_za64[_{d}]_vg4x2", "vm2d", "Us", MergeNone, "aarch64_sme_umla_za64_single_vg4x2", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLAL_SINGLE_VG4x4_S16 : Inst<"svmla[_single]_za64[_{d}]_vg4x4", "vm4d", "s", MergeNone, "aarch64_sme_smla_za64_single_vg4x4", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLAL_SINGLE_VG4x4_U16 : Inst<"svmla[_single]_za64[_{d}]_vg4x4", "vm4d", "Us", MergeNone, "aarch64_sme_umla_za64_single_vg4x4", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLAL_SINGLE_VG4x1_S16 : Inst<"svmla_za64[_{d}]_vg4x1", "vmdd", "s", MergeNone, "aarch64_sme_smla_za64_single_vg4x1", [IsStreaming, IsInOutZA], []>;
|
||||
def SVMLAL_SINGLE_VG4x1_U16 : Inst<"svmla_za64[_{d}]_vg4x1", "vmdd", "Us", MergeNone, "aarch64_sme_umla_za64_single_vg4x1", [IsStreaming, IsInOutZA], []>;
|
||||
def SVMLAL_SINGLE_VG4x2_S16 : Inst<"svmla[_single]_za64[_{d}]_vg4x2", "vm2d", "s", MergeNone, "aarch64_sme_smla_za64_single_vg4x2", [IsStreaming, IsInOutZA], []>;
|
||||
def SVMLAL_SINGLE_VG4x2_U16 : Inst<"svmla[_single]_za64[_{d}]_vg4x2", "vm2d", "Us", MergeNone, "aarch64_sme_umla_za64_single_vg4x2", [IsStreaming, IsInOutZA], []>;
|
||||
def SVMLAL_SINGLE_VG4x4_S16 : Inst<"svmla[_single]_za64[_{d}]_vg4x4", "vm4d", "s", MergeNone, "aarch64_sme_smla_za64_single_vg4x4", [IsStreaming, IsInOutZA], []>;
|
||||
def SVMLAL_SINGLE_VG4x4_U16 : Inst<"svmla[_single]_za64[_{d}]_vg4x4", "vm4d", "Us", MergeNone, "aarch64_sme_umla_za64_single_vg4x4", [IsStreaming, IsInOutZA], []>;
|
||||
|
||||
// SINGLE MLSL
|
||||
def SVMLSL_SINGLE_VG4x1_S16 : Inst<"svmls_za64[_{d}]_vg4x1", "vmdd", "s", MergeNone, "aarch64_sme_smls_za64_single_vg4x1", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLSL_SINGLE_VG4x1_U16 : Inst<"svmls_za64[_{d}]_vg4x1", "vmdd", "Us", MergeNone, "aarch64_sme_umls_za64_single_vg4x1", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLSL_SINGLE_VG4x2_S16 : Inst<"svmls[_single]_za64[_{d}]_vg4x2", "vm2d", "s", MergeNone, "aarch64_sme_smls_za64_single_vg4x2", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLSL_SINGLE_VG4x2_U16 : Inst<"svmls[_single]_za64[_{d}]_vg4x2", "vm2d", "Us", MergeNone, "aarch64_sme_umls_za64_single_vg4x2", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLSL_SINGLE_VG4x4_S16 : Inst<"svmls[_single]_za64[_{d}]_vg4x4", "vm4d", "s", MergeNone, "aarch64_sme_smls_za64_single_vg4x4", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLSL_SINGLE_VG4x4_U16 : Inst<"svmls[_single]_za64[_{d}]_vg4x4", "vm4d", "Us", MergeNone, "aarch64_sme_umls_za64_single_vg4x4", [IsStreaming, IsSharedZA], []>;
|
||||
def SVMLSL_SINGLE_VG4x1_S16 : Inst<"svmls_za64[_{d}]_vg4x1", "vmdd", "s", MergeNone, "aarch64_sme_smls_za64_single_vg4x1", [IsStreaming, IsInOutZA], []>;
|
||||
def SVMLSL_SINGLE_VG4x1_U16 : Inst<"svmls_za64[_{d}]_vg4x1", "vmdd", "Us", MergeNone, "aarch64_sme_umls_za64_single_vg4x1", [IsStreaming, IsInOutZA], []>;
|
||||
def SVMLSL_SINGLE_VG4x2_S16 : Inst<"svmls[_single]_za64[_{d}]_vg4x2", "vm2d", "s", MergeNone, "aarch64_sme_smls_za64_single_vg4x2", [IsStreaming, IsInOutZA], []>;
|
||||
def SVMLSL_SINGLE_VG4x2_U16 : Inst<"svmls[_single]_za64[_{d}]_vg4x2", "vm2d", "Us", MergeNone, "aarch64_sme_umls_za64_single_vg4x2", [IsStreaming, IsInOutZA], []>;
|
||||
def SVMLSL_SINGLE_VG4x4_S16 : Inst<"svmls[_single]_za64[_{d}]_vg4x4", "vm4d", "s", MergeNone, "aarch64_sme_smls_za64_single_vg4x4", [IsStreaming, IsInOutZA], []>;
|
||||
def SVMLSL_SINGLE_VG4x4_U16 : Inst<"svmls[_single]_za64[_{d}]_vg4x4", "vm4d", "Us", MergeNone, "aarch64_sme_umls_za64_single_vg4x4", [IsStreaming, IsInOutZA], []>;
|
||||
|
||||
// INDEXED MLAL
|
||||
def SVMLAL_LANE_VG4x1_S16 : Inst<"svmla_lane_za64[_{d}]_vg4x1", "vmddi", "s", MergeNone, "aarch64_sme_smla_za64_lane_vg4x1", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_7>]>;
|
||||
def SVMLAL_LANE_VG4x1_U16 : Inst<"svmla_lane_za64[_{d}]_vg4x1", "vmddi", "Us", MergeNone, "aarch64_sme_umla_za64_lane_vg4x1", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_7>]>;
|
||||
def SVMLAL_LANE_VG4x2_S16 : Inst<"svmla_lane_za64[_{d}]_vg4x2", "vm2di", "s", MergeNone, "aarch64_sme_smla_za64_lane_vg4x2", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_7>]>;
|
||||
def SVMLAL_LANE_VG4x2_U16 : Inst<"svmla_lane_za64[_{d}]_vg4x2", "vm2di", "Us", MergeNone, "aarch64_sme_umla_za64_lane_vg4x2", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_7>]>;
|
||||
def SVMLAL_LANE_VG4x4_S16 : Inst<"svmla_lane_za64[_{d}]_vg4x4", "vm4di", "s", MergeNone, "aarch64_sme_smla_za64_lane_vg4x4", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_7>]>;
|
||||
def SVMLAL_LANE_VG4x4_U16 : Inst<"svmla_lane_za64[_{d}]_vg4x4", "vm4di", "Us", MergeNone, "aarch64_sme_umla_za64_lane_vg4x4", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_7>]>;
|
||||
def SVMLAL_LANE_VG4x1_S16 : Inst<"svmla_lane_za64[_{d}]_vg4x1", "vmddi", "s", MergeNone, "aarch64_sme_smla_za64_lane_vg4x1", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_7>]>;
|
||||
def SVMLAL_LANE_VG4x1_U16 : Inst<"svmla_lane_za64[_{d}]_vg4x1", "vmddi", "Us", MergeNone, "aarch64_sme_umla_za64_lane_vg4x1", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_7>]>;
|
||||
def SVMLAL_LANE_VG4x2_S16 : Inst<"svmla_lane_za64[_{d}]_vg4x2", "vm2di", "s", MergeNone, "aarch64_sme_smla_za64_lane_vg4x2", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_7>]>;
|
||||
def SVMLAL_LANE_VG4x2_U16 : Inst<"svmla_lane_za64[_{d}]_vg4x2", "vm2di", "Us", MergeNone, "aarch64_sme_umla_za64_lane_vg4x2", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_7>]>;
|
||||
def SVMLAL_LANE_VG4x4_S16 : Inst<"svmla_lane_za64[_{d}]_vg4x4", "vm4di", "s", MergeNone, "aarch64_sme_smla_za64_lane_vg4x4", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_7>]>;
|
||||
def SVMLAL_LANE_VG4x4_U16 : Inst<"svmla_lane_za64[_{d}]_vg4x4", "vm4di", "Us", MergeNone, "aarch64_sme_umla_za64_lane_vg4x4", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_7>]>;
|
||||
|
||||
// INDEXED MLSL
|
||||
def SVMLSL_LANE_VG4x1_S16 : Inst<"svmls_lane_za64[_{d}]_vg4x1", "vmddi", "s", MergeNone, "aarch64_sme_smls_za64_lane_vg4x1", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_7>]>;
|
||||
def SVMLSL_LANE_VG4x1_U16 : Inst<"svmls_lane_za64[_{d}]_vg4x1", "vmddi", "Us", MergeNone, "aarch64_sme_umls_za64_lane_vg4x1", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_7>]>;
|
||||
def SVMLSL_LANE_VG4x2_S16 : Inst<"svmls_lane_za64[_{d}]_vg4x2", "vm2di", "s", MergeNone, "aarch64_sme_smls_za64_lane_vg4x2", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_7>]>;
|
||||
def SVMLSL_LANE_VG4x2_U16 : Inst<"svmls_lane_za64[_{d}]_vg4x2", "vm2di", "Us", MergeNone, "aarch64_sme_umls_za64_lane_vg4x2", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_7>]>;
|
||||
def SVMLSL_LANE_VG4x4_S16 : Inst<"svmls_lane_za64[_{d}]_vg4x4", "vm4di", "s", MergeNone, "aarch64_sme_smls_za64_lane_vg4x4", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_7>]>;
|
||||
def SVMLSL_LANE_VG4x4_U16 : Inst<"svmls_lane_za64[_{d}]_vg4x4", "vm4di", "Us", MergeNone, "aarch64_sme_umls_za64_lane_vg4x4", [IsStreaming, IsSharedZA], [ImmCheck<3, ImmCheck0_7>]>;
|
||||
def SVMLSL_LANE_VG4x1_S16 : Inst<"svmls_lane_za64[_{d}]_vg4x1", "vmddi", "s", MergeNone, "aarch64_sme_smls_za64_lane_vg4x1", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_7>]>;
|
||||
def SVMLSL_LANE_VG4x1_U16 : Inst<"svmls_lane_za64[_{d}]_vg4x1", "vmddi", "Us", MergeNone, "aarch64_sme_umls_za64_lane_vg4x1", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_7>]>;
|
||||
def SVMLSL_LANE_VG4x2_S16 : Inst<"svmls_lane_za64[_{d}]_vg4x2", "vm2di", "s", MergeNone, "aarch64_sme_smls_za64_lane_vg4x2", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_7>]>;
|
||||
def SVMLSL_LANE_VG4x2_U16 : Inst<"svmls_lane_za64[_{d}]_vg4x2", "vm2di", "Us", MergeNone, "aarch64_sme_umls_za64_lane_vg4x2", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_7>]>;
|
||||
def SVMLSL_LANE_VG4x4_S16 : Inst<"svmls_lane_za64[_{d}]_vg4x4", "vm4di", "s", MergeNone, "aarch64_sme_smls_za64_lane_vg4x4", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_7>]>;
|
||||
def SVMLSL_LANE_VG4x4_U16 : Inst<"svmls_lane_za64[_{d}]_vg4x4", "vm4di", "Us", MergeNone, "aarch64_sme_umls_za64_lane_vg4x4", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_7>]>;
|
||||
}
|
||||
|
||||
//
|
||||
// Spill and fill of ZT0
|
||||
//
|
||||
let TargetGuard = "sme2" in {
|
||||
def SVLDR_ZT : Inst<"svldr_zt", "viQ", "", MergeNone, "aarch64_sme_ldr_zt", [IsOverloadNone, IsStreamingCompatible, IsSharedZA], [ImmCheck<0, ImmCheck0_0>]>;
|
||||
def SVSTR_ZT : Inst<"svstr_zt", "vi%", "", MergeNone, "aarch64_sme_str_zt", [IsOverloadNone, IsStreamingCompatible, IsSharedZA, IsPreservesZA], [ImmCheck<0, ImmCheck0_0>]>;
|
||||
def SVLDR_ZT : Inst<"svldr_zt", "viQ", "", MergeNone, "aarch64_sme_ldr_zt", [IsOverloadNone, IsStreamingCompatible, IsInOutZT0], [ImmCheck<0, ImmCheck0_0>]>;
|
||||
def SVSTR_ZT : Inst<"svstr_zt", "vi%", "", MergeNone, "aarch64_sme_str_zt", [IsOverloadNone, IsStreamingCompatible, IsInZT0], [ImmCheck<0, ImmCheck0_0>]>;
|
||||
}
|
||||
|
||||
//
|
||||
// Zero ZT0
|
||||
//
|
||||
let TargetGuard = "sme2" in {
|
||||
def SVZERO_ZT : Inst<"svzero_zt", "vi", "", MergeNone, "aarch64_sme_zero_zt", [IsOverloadNone, IsStreamingCompatible, IsSharedZA], [ImmCheck<0, ImmCheck0_0>]>;
|
||||
def SVZERO_ZT : Inst<"svzero_zt", "vi", "", MergeNone, "aarch64_sme_zero_zt", [IsOverloadNone, IsStreamingCompatible, IsOutZT0], [ImmCheck<0, ImmCheck0_0>]>;
|
||||
}
|
||||
|
||||
//
|
||||
// lookup table expand four contiguous registers
|
||||
//
|
||||
let TargetGuard = "sme2" in {
|
||||
def SVLUTI2_LANE_ZT_X4 : Inst<"svluti2_lane_zt_{d}_x4", "4.di[i", "cUcsUsiUibhf", MergeNone, "aarch64_sme_luti2_lane_zt_x4", [IsStreaming, IsSharedZA, IsPreservesZA], [ImmCheck<0, ImmCheck0_0>, ImmCheck<2, ImmCheck0_3>]>;
|
||||
def SVLUTI4_LANE_ZT_X4 : Inst<"svluti4_lane_zt_{d}_x4", "4.di[i", "sUsiUibhf", MergeNone, "aarch64_sme_luti4_lane_zt_x4", [IsStreaming, IsSharedZA, IsPreservesZA], [ImmCheck<0, ImmCheck0_0>, ImmCheck<2, ImmCheck0_1>]>;
|
||||
def SVLUTI2_LANE_ZT_X4 : Inst<"svluti2_lane_zt_{d}_x4", "4.di[i", "cUcsUsiUibhf", MergeNone, "aarch64_sme_luti2_lane_zt_x4", [IsStreaming, IsInZT0], [ImmCheck<0, ImmCheck0_0>, ImmCheck<2, ImmCheck0_3>]>;
|
||||
def SVLUTI4_LANE_ZT_X4 : Inst<"svluti4_lane_zt_{d}_x4", "4.di[i", "sUsiUibhf", MergeNone, "aarch64_sme_luti4_lane_zt_x4", [IsStreaming, IsInZT0], [ImmCheck<0, ImmCheck0_0>, ImmCheck<2, ImmCheck0_1>]>;
|
||||
}
|
||||
|
||||
//
|
||||
// lookup table expand one register
|
||||
//
|
||||
let TargetGuard = "sme2" in {
|
||||
def SVLUTI2_LANE_ZT : Inst<"svluti2_lane_zt_{d}", "di[i", "cUcsUsiUibhf", MergeNone, "aarch64_sme_luti2_lane_zt", [IsStreaming, IsSharedZA, IsPreservesZA], [ImmCheck<0, ImmCheck0_0>, ImmCheck<2, ImmCheck0_15>]>;
|
||||
def SVLUTI4_LANE_ZT : Inst<"svluti4_lane_zt_{d}", "di[i", "cUcsUsiUibhf", MergeNone, "aarch64_sme_luti4_lane_zt", [IsStreaming, IsSharedZA, IsPreservesZA], [ImmCheck<0, ImmCheck0_0>, ImmCheck<2, ImmCheck0_7>]>;
|
||||
def SVLUTI2_LANE_ZT : Inst<"svluti2_lane_zt_{d}", "di[i", "cUcsUsiUibhf", MergeNone, "aarch64_sme_luti2_lane_zt", [IsStreaming, IsInZT0], [ImmCheck<0, ImmCheck0_0>, ImmCheck<2, ImmCheck0_15>]>;
|
||||
def SVLUTI4_LANE_ZT : Inst<"svluti4_lane_zt_{d}", "di[i", "cUcsUsiUibhf", MergeNone, "aarch64_sme_luti4_lane_zt", [IsStreaming, IsInZT0], [ImmCheck<0, ImmCheck0_0>, ImmCheck<2, ImmCheck0_7>]>;
|
||||
}
|
||||
|
||||
//
|
||||
// lookup table expand two contiguous registers
|
||||
//
|
||||
let TargetGuard = "sme2" in {
|
||||
def SVLUTI2_LANE_ZT_X2 : Inst<"svluti2_lane_zt_{d}_x2", "2.di[i", "cUcsUsiUibhf", MergeNone, "aarch64_sme_luti2_lane_zt_x2", [IsStreaming, IsSharedZA, IsPreservesZA], [ImmCheck<0, ImmCheck0_0>, ImmCheck<2, ImmCheck0_7>]>;
|
||||
def SVLUTI4_LANE_ZT_X2 : Inst<"svluti4_lane_zt_{d}_x2", "2.di[i", "cUcsUsiUibhf", MergeNone, "aarch64_sme_luti4_lane_zt_x2", [IsStreaming, IsSharedZA, IsPreservesZA], [ImmCheck<0, ImmCheck0_0>, ImmCheck<2, ImmCheck0_3>]>;
|
||||
def SVLUTI2_LANE_ZT_X2 : Inst<"svluti2_lane_zt_{d}_x2", "2.di[i", "cUcsUsiUibhf", MergeNone, "aarch64_sme_luti2_lane_zt_x2", [IsStreaming, IsInZT0], [ImmCheck<0, ImmCheck0_0>, ImmCheck<2, ImmCheck0_7>]>;
|
||||
def SVLUTI4_LANE_ZT_X2 : Inst<"svluti4_lane_zt_{d}_x2", "2.di[i", "cUcsUsiUibhf", MergeNone, "aarch64_sme_luti4_lane_zt_x2", [IsStreaming, IsInZT0], [ImmCheck<0, ImmCheck0_0>, ImmCheck<2, ImmCheck0_3>]>;
|
||||
}
|
||||
|
@ -543,13 +543,13 @@ def SVADRD : SInst<"svadrd[_{0}base]_[{2}]index", "uud", "ilUiUl", MergeNone, "
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Scalar to vector
|
||||
|
||||
def SVDUPQ_8 : SInst<"svdupq[_n]_{d}", "dssssssssssssssss", "cUc", MergeNone>;
|
||||
def SVDUPQ_16 : SInst<"svdupq[_n]_{d}", "dssssssss", "sUsh", MergeNone>;
|
||||
def SVDUPQ_8 : SInst<"svdupq[_n]_{d}", "dssssssssssssssss", "cUc", MergeNone, "", [IsStreamingCompatible]>;
|
||||
def SVDUPQ_16 : SInst<"svdupq[_n]_{d}", "dssssssss", "sUsh", MergeNone, "", [IsStreamingCompatible]>;
|
||||
let TargetGuard = "sve,bf16" in {
|
||||
def SVDUPQ_BF16 : SInst<"svdupq[_n]_{d}", "dssssssss", "b", MergeNone>;
|
||||
def SVDUPQ_BF16 : SInst<"svdupq[_n]_{d}", "dssssssss", "b", MergeNone, "", [IsStreamingCompatible]>;
|
||||
}
|
||||
def SVDUPQ_32 : SInst<"svdupq[_n]_{d}", "dssss", "iUif", MergeNone>;
|
||||
def SVDUPQ_64 : SInst<"svdupq[_n]_{d}", "dss", "lUld", MergeNone>;
|
||||
def SVDUPQ_32 : SInst<"svdupq[_n]_{d}", "dssss", "iUif", MergeNone, "", [IsStreamingCompatible]>;
|
||||
def SVDUPQ_64 : SInst<"svdupq[_n]_{d}", "dss", "lUld", MergeNone, "", [IsStreamingCompatible]>;
|
||||
|
||||
multiclass svdup_base<string n, string p, MergeType mt, string i> {
|
||||
def NAME : SInst<n, p, "csilUcUsUiUlhfd", mt, i, [IsStreamingCompatible]>;
|
||||
@ -638,8 +638,8 @@ def SVQADD_N_U : SInst<"svqadd[_n_{d}]", "dda", "UcUsUiUl", MergeNone, "aarch64
|
||||
def SVQSUB_N_S : SInst<"svqsub[_n_{d}]", "dda", "csil", MergeNone, "aarch64_sve_sqsub_x", [IsStreamingCompatible]>;
|
||||
def SVQSUB_N_U : SInst<"svqsub[_n_{d}]", "dda", "UcUsUiUl", MergeNone, "aarch64_sve_uqsub_x", [IsStreamingCompatible]>;
|
||||
|
||||
def SVDOT_LANE_S : SInst<"svdot_lane[_{d}]", "ddqqi", "il", MergeNone, "aarch64_sve_sdot_lane", [], [ImmCheck<3, ImmCheckLaneIndexDot, 2>]>;
|
||||
def SVDOT_LANE_U : SInst<"svdot_lane[_{d}]", "ddqqi", "UiUl", MergeNone, "aarch64_sve_udot_lane", [], [ImmCheck<3, ImmCheckLaneIndexDot, 2>]>;
|
||||
def SVDOT_LANE_S : SInst<"svdot_lane[_{d}]", "ddqqi", "il", MergeNone, "aarch64_sve_sdot_lane", [IsStreamingCompatible], [ImmCheck<3, ImmCheckLaneIndexDot, 2>]>;
|
||||
def SVDOT_LANE_U : SInst<"svdot_lane[_{d}]", "ddqqi", "UiUl", MergeNone, "aarch64_sve_udot_lane", [IsStreamingCompatible], [ImmCheck<3, ImmCheckLaneIndexDot, 2>]>;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Logical operations
|
||||
@ -749,14 +749,14 @@ def SVCMPLS_WIDE_N : SInst<"svcmple_wide[_n_{d}]", "PPdj", "UcUsUi", MergeNone,
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// While comparisons
|
||||
|
||||
def SVWHILELE_S32 : SInst<"svwhilele_{d}[_{1}]", "Pkk", "PcPsPiPl", MergeNone, "aarch64_sve_whilele", [IsOverloadWhile, IsStreamingCompatible]>;
|
||||
def SVWHILELE_S64 : SInst<"svwhilele_{d}[_{1}]", "Pll", "PcPsPiPl", MergeNone, "aarch64_sve_whilele", [IsOverloadWhile, IsStreamingCompatible]>;
|
||||
def SVWHILELO_U32 : SInst<"svwhilelt_{d}[_{1}]", "Pmm", "PUcPUsPUiPUl", MergeNone, "aarch64_sve_whilelo", [IsOverloadWhile, IsStreamingCompatible]>;
|
||||
def SVWHILELO_U64 : SInst<"svwhilelt_{d}[_{1}]", "Pnn", "PUcPUsPUiPUl", MergeNone, "aarch64_sve_whilelo", [IsOverloadWhile, IsStreamingCompatible]>;
|
||||
def SVWHILELS_U32 : SInst<"svwhilele_{d}[_{1}]", "Pmm", "PUcPUsPUiPUl", MergeNone, "aarch64_sve_whilels", [IsOverloadWhile, IsStreamingCompatible]>;
|
||||
def SVWHILELS_U64 : SInst<"svwhilele_{d}[_{1}]", "Pnn", "PUcPUsPUiPUl", MergeNone, "aarch64_sve_whilels", [IsOverloadWhile, IsStreamingCompatible]>;
|
||||
def SVWHILELT_S32 : SInst<"svwhilelt_{d}[_{1}]", "Pkk", "PcPsPiPl", MergeNone, "aarch64_sve_whilelt", [IsOverloadWhile, IsStreamingCompatible]>;
|
||||
def SVWHILELT_S64 : SInst<"svwhilelt_{d}[_{1}]", "Pll", "PcPsPiPl", MergeNone, "aarch64_sve_whilelt", [IsOverloadWhile, IsStreamingCompatible]>;
|
||||
def SVWHILELE_S32 : SInst<"svwhilele_{d}[_{1}]", "Pkk", "PcPsPiPl", MergeNone, "aarch64_sve_whilele", [IsOverloadWhileOrMultiVecCvt, IsStreamingCompatible]>;
|
||||
def SVWHILELE_S64 : SInst<"svwhilele_{d}[_{1}]", "Pll", "PcPsPiPl", MergeNone, "aarch64_sve_whilele", [IsOverloadWhileOrMultiVecCvt, IsStreamingCompatible]>;
|
||||
def SVWHILELO_U32 : SInst<"svwhilelt_{d}[_{1}]", "Pmm", "PUcPUsPUiPUl", MergeNone, "aarch64_sve_whilelo", [IsOverloadWhileOrMultiVecCvt, IsStreamingCompatible]>;
|
||||
def SVWHILELO_U64 : SInst<"svwhilelt_{d}[_{1}]", "Pnn", "PUcPUsPUiPUl", MergeNone, "aarch64_sve_whilelo", [IsOverloadWhileOrMultiVecCvt, IsStreamingCompatible]>;
|
||||
def SVWHILELS_U32 : SInst<"svwhilele_{d}[_{1}]", "Pmm", "PUcPUsPUiPUl", MergeNone, "aarch64_sve_whilels", [IsOverloadWhileOrMultiVecCvt, IsStreamingCompatible]>;
|
||||
def SVWHILELS_U64 : SInst<"svwhilele_{d}[_{1}]", "Pnn", "PUcPUsPUiPUl", MergeNone, "aarch64_sve_whilels", [IsOverloadWhileOrMultiVecCvt, IsStreamingCompatible]>;
|
||||
def SVWHILELT_S32 : SInst<"svwhilelt_{d}[_{1}]", "Pkk", "PcPsPiPl", MergeNone, "aarch64_sve_whilelt", [IsOverloadWhileOrMultiVecCvt, IsStreamingCompatible]>;
|
||||
def SVWHILELT_S64 : SInst<"svwhilelt_{d}[_{1}]", "Pll", "PcPsPiPl", MergeNone, "aarch64_sve_whilelt", [IsOverloadWhileOrMultiVecCvt, IsStreamingCompatible]>;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Counting bit
|
||||
@ -835,14 +835,14 @@ def SVSCALE_N_M : SInst<"svscale[_n_{d}]", "dPdK", "hfd", MergeOp1, "aarch64_sv
|
||||
def SVSCALE_N_X : SInst<"svscale[_n_{d}]", "dPdK", "hfd", MergeAny, "aarch64_sve_fscale", [IsStreamingCompatible]>;
|
||||
def SVSCALE_N_Z : SInst<"svscale[_n_{d}]", "dPdK", "hfd", MergeZero, "aarch64_sve_fscale", [IsStreamingCompatible]>;
|
||||
|
||||
defm SVMAD_F : SInstZPZZZ<"svmad", "hfd", "aarch64_sve_fmad", "aarch64_sve_fmla_u", [ReverseMergeAnyAccOp]>;
|
||||
defm SVMLA_F : SInstZPZZZ<"svmla", "hfd", "aarch64_sve_fmla", "aarch64_sve_fmla_u">;
|
||||
defm SVMLS_F : SInstZPZZZ<"svmls", "hfd", "aarch64_sve_fmls", "aarch64_sve_fmls_u">;
|
||||
defm SVMSB_F : SInstZPZZZ<"svmsb", "hfd", "aarch64_sve_fmsb", "aarch64_sve_fmls_u", [ReverseMergeAnyAccOp]>;
|
||||
defm SVNMAD_F : SInstZPZZZ<"svnmad", "hfd", "aarch64_sve_fnmad", "aarch64_sve_fnmla_u", [ReverseMergeAnyAccOp]>;
|
||||
defm SVNMLA_F : SInstZPZZZ<"svnmla", "hfd", "aarch64_sve_fnmla", "aarch64_sve_fnmla_u">;
|
||||
defm SVNMLS_F : SInstZPZZZ<"svnmls", "hfd", "aarch64_sve_fnmls", "aarch64_sve_fnmls_u">;
|
||||
defm SVNMSB_F : SInstZPZZZ<"svnmsb", "hfd", "aarch64_sve_fnmsb", "aarch64_sve_fnmls_u", [ReverseMergeAnyAccOp]>;
|
||||
defm SVMAD_F : SInstZPZZZ<"svmad", "hfd", "aarch64_sve_fmad", "aarch64_sve_fmla_u", [IsStreamingCompatible, ReverseMergeAnyAccOp]>;
|
||||
defm SVMLA_F : SInstZPZZZ<"svmla", "hfd", "aarch64_sve_fmla", "aarch64_sve_fmla_u", [IsStreamingCompatible]>;
|
||||
defm SVMLS_F : SInstZPZZZ<"svmls", "hfd", "aarch64_sve_fmls", "aarch64_sve_fmls_u", [IsStreamingCompatible]>;
|
||||
defm SVMSB_F : SInstZPZZZ<"svmsb", "hfd", "aarch64_sve_fmsb", "aarch64_sve_fmls_u", [IsStreamingCompatible, ReverseMergeAnyAccOp]>;
|
||||
defm SVNMAD_F : SInstZPZZZ<"svnmad", "hfd", "aarch64_sve_fnmad", "aarch64_sve_fnmla_u", [IsStreamingCompatible, ReverseMergeAnyAccOp]>;
|
||||
defm SVNMLA_F : SInstZPZZZ<"svnmla", "hfd", "aarch64_sve_fnmla", "aarch64_sve_fnmla_u", [IsStreamingCompatible]>;
|
||||
defm SVNMLS_F : SInstZPZZZ<"svnmls", "hfd", "aarch64_sve_fnmls", "aarch64_sve_fnmls_u", [IsStreamingCompatible]>;
|
||||
defm SVNMSB_F : SInstZPZZZ<"svnmsb", "hfd", "aarch64_sve_fnmsb", "aarch64_sve_fnmls_u", [IsStreamingCompatible, ReverseMergeAnyAccOp]>;
|
||||
|
||||
def SVCADD_M : SInst<"svcadd[_{d}]", "dPddi", "hfd", MergeOp1, "aarch64_sve_fcadd", [IsStreamingCompatible], [ImmCheck<3, ImmCheckComplexRot90_270>]>;
|
||||
def SVCADD_X : SInst<"svcadd[_{d}]", "dPddi", "hfd", MergeAny, "aarch64_sve_fcadd", [IsStreamingCompatible], [ImmCheck<3, ImmCheckComplexRot90_270>]>;
|
||||
@ -881,11 +881,11 @@ def SVACLE : SInst<"svacle[_{d}]", "PPdd", "hfd", MergeNone, "aarch64_sve_facg
|
||||
def SVACLT : SInst<"svaclt[_{d}]", "PPdd", "hfd", MergeNone, "aarch64_sve_facgt", [ReverseCompare, IsStreamingCompatible]>;
|
||||
def SVCMPUO : SInst<"svcmpuo[_{d}]", "PPdd", "hfd", MergeNone, "aarch64_sve_fcmpuo", [IsStreamingCompatible]>;
|
||||
|
||||
def SVACGE_N : SInst<"svacge[_n_{d}]", "PPda", "hfd", MergeNone, "aarch64_sve_facge">;
|
||||
def SVACGT_N : SInst<"svacgt[_n_{d}]", "PPda", "hfd", MergeNone, "aarch64_sve_facgt">;
|
||||
def SVACLE_N : SInst<"svacle[_n_{d}]", "PPda", "hfd", MergeNone, "aarch64_sve_facge", [ReverseCompare]>;
|
||||
def SVACLT_N : SInst<"svaclt[_n_{d}]", "PPda", "hfd", MergeNone, "aarch64_sve_facgt", [ReverseCompare]>;
|
||||
def SVCMPUO_N : SInst<"svcmpuo[_n_{d}]", "PPda", "hfd", MergeNone, "aarch64_sve_fcmpuo">;
|
||||
def SVACGE_N : SInst<"svacge[_n_{d}]", "PPda", "hfd", MergeNone, "aarch64_sve_facge", [IsStreamingCompatible]>;
|
||||
def SVACGT_N : SInst<"svacgt[_n_{d}]", "PPda", "hfd", MergeNone, "aarch64_sve_facgt", [IsStreamingCompatible]>;
|
||||
def SVACLE_N : SInst<"svacle[_n_{d}]", "PPda", "hfd", MergeNone, "aarch64_sve_facge", [ReverseCompare, IsStreamingCompatible]>;
|
||||
def SVACLT_N : SInst<"svaclt[_n_{d}]", "PPda", "hfd", MergeNone, "aarch64_sve_facgt", [ReverseCompare, IsStreamingCompatible]>;
|
||||
def SVCMPUO_N : SInst<"svcmpuo[_n_{d}]", "PPda", "hfd", MergeNone, "aarch64_sve_fcmpuo", [IsStreamingCompatible]>;
|
||||
|
||||
def SVCMPEQ_F : SInst<"svcmpeq[_{d}]", "PPdd", "hfd", MergeNone, "aarch64_sve_fcmpeq", [IsStreamingCompatible]>;
|
||||
def SVCMPNE_F : SInst<"svcmpne[_{d}]", "PPdd", "hfd", MergeNone, "aarch64_sve_fcmpne", [IsStreamingCompatible]>;
|
||||
@ -1023,15 +1023,15 @@ def SVCOMPACT : SInst<"svcompact[_{d}]", "dPd", "ilUiUlfd", MergeNo
|
||||
// splat of any possible lane. It is upto LLVM to pick a more efficient
|
||||
// instruction such as DUP (indexed) if the lane index fits the range of the
|
||||
// instruction's immediate.
|
||||
def SVDUP_LANE : SInst<"svdup_lane[_{d}]", "ddL", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_tbl">;
|
||||
def SVDUP_LANE : SInst<"svdup_lane[_{d}]", "ddL", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_tbl", [IsStreamingCompatible]>;
|
||||
let TargetGuard = "sve,bf16" in {
|
||||
def SVDUP_LANE_BF16 :
|
||||
SInst<"svdup_lane[_{d}]", "ddL", "b", MergeNone, "aarch64_sve_tbl">;
|
||||
SInst<"svdup_lane[_{d}]", "ddL", "b", MergeNone, "aarch64_sve_tbl", [IsStreamingCompatible]>;
|
||||
}
|
||||
|
||||
def SVDUPQ_LANE : SInst<"svdupq_lane[_{d}]", "ddn", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_dupq_lane">;
|
||||
def SVDUPQ_LANE : SInst<"svdupq_lane[_{d}]", "ddn", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_dupq_lane", [IsStreamingCompatible]>;
|
||||
let TargetGuard = "sve,bf16" in {
|
||||
def SVDUPQ_LANE_BF16 : SInst<"svdupq_lane[_{d}]", "ddn", "b", MergeNone, "aarch64_sve_dupq_lane">;
|
||||
def SVDUPQ_LANE_BF16 : SInst<"svdupq_lane[_{d}]", "ddn", "b", MergeNone, "aarch64_sve_dupq_lane", [IsStreamingCompatible]>;
|
||||
}
|
||||
def SVEXT : SInst<"svext[_{d}]", "dddi", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_ext", [IsStreamingCompatible], [ImmCheck<2, ImmCheckExtract, 1>]>;
|
||||
defm SVLASTA : SVEPerm<"svlasta[_{d}]", "sPd", "aarch64_sve_lasta">;
|
||||
@ -1109,11 +1109,11 @@ def SVPFALSE : SInst<"svpfalse[_b]", "Pv", "", MergeNone, "", [IsOverloadNone, I
|
||||
def SVPTRUE_PAT : SInst<"svptrue_pat_{d}", "PI", "PcPsPiPl", MergeNone, "aarch64_sve_ptrue", [IsStreamingCompatible]>;
|
||||
def SVPTRUE : SInst<"svptrue_{d}", "Pv", "PcPsPiPl", MergeNone, "aarch64_sve_ptrue", [IsAppendSVALL, IsStreamingCompatible]>;
|
||||
|
||||
def SVDUPQ_B8 : SInst<"svdupq[_n]_{d}", "Pssssssssssssssss", "Pc", MergeNone>;
|
||||
def SVDUPQ_B16 : SInst<"svdupq[_n]_{d}", "Pssssssss", "Ps", MergeNone>;
|
||||
def SVDUPQ_B32 : SInst<"svdupq[_n]_{d}", "Pssss", "Pi", MergeNone>;
|
||||
def SVDUPQ_B64 : SInst<"svdupq[_n]_{d}", "Pss", "Pl", MergeNone>;
|
||||
def SVDUP_N_B : SInst<"svdup[_n]_{d}", "Ps", "PcPsPiPl", MergeNone>;
|
||||
def SVDUPQ_B8 : SInst<"svdupq[_n]_{d}", "Pssssssssssssssss", "Pc", MergeNone, "", [IsStreamingCompatible]>;
|
||||
def SVDUPQ_B16 : SInst<"svdupq[_n]_{d}", "Pssssssss", "Ps", MergeNone, "", [IsStreamingCompatible]>;
|
||||
def SVDUPQ_B32 : SInst<"svdupq[_n]_{d}", "Pssss", "Pi", MergeNone, "", [IsStreamingCompatible]>;
|
||||
def SVDUPQ_B64 : SInst<"svdupq[_n]_{d}", "Pss", "Pl", MergeNone, "", [IsStreamingCompatible]>;
|
||||
def SVDUP_N_B : SInst<"svdup[_n]_{d}", "Ps", "PcPsPiPl", MergeNone, "", [IsStreamingCompatible]>;
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -1268,10 +1268,10 @@ def SVZIP2Q : SInst<"svzip2q[_{d}]", "ddd", "csilUcUsUiUlhfd", MergeNo
|
||||
let TargetGuard = "sve,bf16,f64mm" in {
|
||||
def SVTRN1Q_BF16 : SInst<"svtrn1q[_{d}]", "ddd", "b", MergeNone, "aarch64_sve_trn1q">;
|
||||
def SVTRN2Q_BF16 : SInst<"svtrn2q[_{d}]", "ddd", "b", MergeNone, "aarch64_sve_trn2q">;
|
||||
def SVUZP1Q_BF16 : SInst<"svuzp1q[_{d}]", "ddd", "b", MergeNone, "aarch64_sve_uzp1q">;
|
||||
def SVUZP2Q_BF16 : SInst<"svuzp2q[_{d}]", "ddd", "b", MergeNone, "aarch64_sve_uzp2q">;
|
||||
def SVZIP1Q_BF16 : SInst<"svzip1q[_{d}]", "ddd", "b", MergeNone, "aarch64_sve_zip1q">;
|
||||
def SVZIP2Q_BF16 : SInst<"svzip2q[_{d}]", "ddd", "b", MergeNone, "aarch64_sve_zip2q">;
|
||||
def SVUZP1Q_BF16 : SInst<"svuzp1q[_{d}]", "ddd", "b", MergeNone, "aarch64_sve_uzp1q", [IsStreamingCompatible]>;
|
||||
def SVUZP2Q_BF16 : SInst<"svuzp2q[_{d}]", "ddd", "b", MergeNone, "aarch64_sve_uzp2q", [IsStreamingCompatible]>;
|
||||
def SVZIP1Q_BF16 : SInst<"svzip1q[_{d}]", "ddd", "b", MergeNone, "aarch64_sve_zip1q", [IsStreamingCompatible]>;
|
||||
def SVZIP2Q_BF16 : SInst<"svzip2q[_{d}]", "ddd", "b", MergeNone, "aarch64_sve_zip2q", [IsStreamingCompatible]>;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -1281,9 +1281,9 @@ def SVUNDEF_2 : SInst<"svundef2_{d}", "2v", "csilUcUsUiUlhfd", MergeNone, "", [I
|
||||
def SVUNDEF_3 : SInst<"svundef3_{d}", "3v", "csilUcUsUiUlhfd", MergeNone, "", [IsUndef, IsStreamingCompatible]>;
|
||||
def SVUNDEF_4 : SInst<"svundef4_{d}", "4v", "csilUcUsUiUlhfd", MergeNone, "", [IsUndef, IsStreamingCompatible]>;
|
||||
|
||||
def SVCREATE_2 : SInst<"svcreate2[_{d}]", "2dd", "csilUcUsUiUlhfd", MergeNone, "", [IsTupleCreate]>;
|
||||
def SVCREATE_3 : SInst<"svcreate3[_{d}]", "3ddd", "csilUcUsUiUlhfd", MergeNone, "", [IsTupleCreate]>;
|
||||
def SVCREATE_4 : SInst<"svcreate4[_{d}]", "4dddd", "csilUcUsUiUlhfd", MergeNone, "", [IsTupleCreate]>;
|
||||
def SVCREATE_2 : SInst<"svcreate2[_{d}]", "2dd", "csilUcUsUiUlhfd", MergeNone, "", [IsTupleCreate, IsStreamingCompatible]>;
|
||||
def SVCREATE_3 : SInst<"svcreate3[_{d}]", "3ddd", "csilUcUsUiUlhfd", MergeNone, "", [IsTupleCreate, IsStreamingCompatible]>;
|
||||
def SVCREATE_4 : SInst<"svcreate4[_{d}]", "4dddd", "csilUcUsUiUlhfd", MergeNone, "", [IsTupleCreate, IsStreamingCompatible]>;
|
||||
|
||||
let TargetGuard = "sve,bf16" in {
|
||||
def SVUNDEF_1_BF16 : SInst<"svundef_{d}", "dv", "b", MergeNone, "", [IsUndef, IsStreamingCompatible]>;
|
||||
@ -1291,65 +1291,70 @@ def SVUNDEF_2_BF16 : SInst<"svundef2_{d}", "2v", "b", MergeNone, "", [IsUndef, I
|
||||
def SVUNDEF_3_BF16 : SInst<"svundef3_{d}", "3v", "b", MergeNone, "", [IsUndef, IsStreamingCompatible]>;
|
||||
def SVUNDEF_4_BF16 : SInst<"svundef4_{d}", "4v", "b", MergeNone, "", [IsUndef, IsStreamingCompatible]>;
|
||||
|
||||
def SVCREATE_2_BF16 : SInst<"svcreate2[_{d}]", "2dd", "b", MergeNone, "", [IsTupleCreate]>;
|
||||
def SVCREATE_3_BF16 : SInst<"svcreate3[_{d}]", "3ddd", "b", MergeNone, "", [IsTupleCreate]>;
|
||||
def SVCREATE_4_BF16 : SInst<"svcreate4[_{d}]", "4dddd", "b", MergeNone, "", [IsTupleCreate]>;
|
||||
def SVCREATE_2_BF16 : SInst<"svcreate2[_{d}]", "2dd", "b", MergeNone, "", [IsTupleCreate, IsStreamingCompatible]>;
|
||||
def SVCREATE_3_BF16 : SInst<"svcreate3[_{d}]", "3ddd", "b", MergeNone, "", [IsTupleCreate, IsStreamingCompatible]>;
|
||||
def SVCREATE_4_BF16 : SInst<"svcreate4[_{d}]", "4dddd", "b", MergeNone, "", [IsTupleCreate, IsStreamingCompatible]>;
|
||||
}
|
||||
|
||||
let TargetGuard = "sve2p1" in {
|
||||
def SVCREATE_2_B : SInst<"svcreate2[_{d}]", "2dd", "Pc", MergeNone, "", [IsTupleCreate]>;
|
||||
def SVCREATE_4_B : SInst<"svcreate4[_{d}]", "4dddd", "Pc", MergeNone, "", [IsTupleCreate]>;
|
||||
let TargetGuard = "sve2p1|sme2" in {
|
||||
def SVCREATE_2_B : SInst<"svcreate2[_b]", "2dd", "Pc", MergeNone, "", [IsTupleCreate, IsStreamingCompatible]>;
|
||||
def SVCREATE_4_B : SInst<"svcreate4[_b]", "4dddd", "Pc", MergeNone, "", [IsTupleCreate, IsStreamingCompatible]>;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Vector insertion and extraction
|
||||
def SVGET_2 : SInst<"svget2[_{d}]", "d2i", "csilUcUsUiUlhfd", MergeNone, "", [IsTupleGet], [ImmCheck<1, ImmCheck0_1>]>;
|
||||
def SVGET_3 : SInst<"svget3[_{d}]", "d3i", "csilUcUsUiUlhfd", MergeNone, "", [IsTupleGet], [ImmCheck<1, ImmCheck0_2>]>;
|
||||
def SVGET_4 : SInst<"svget4[_{d}]", "d4i", "csilUcUsUiUlhfd", MergeNone, "", [IsTupleGet], [ImmCheck<1, ImmCheck0_3>]>;
|
||||
def SVGET_2 : SInst<"svget2[_{d}]", "d2i", "csilUcUsUiUlhfd", MergeNone, "", [IsTupleGet, IsStreamingCompatible], [ImmCheck<1, ImmCheck0_1>]>;
|
||||
def SVGET_3 : SInst<"svget3[_{d}]", "d3i", "csilUcUsUiUlhfd", MergeNone, "", [IsTupleGet, IsStreamingCompatible], [ImmCheck<1, ImmCheck0_2>]>;
|
||||
def SVGET_4 : SInst<"svget4[_{d}]", "d4i", "csilUcUsUiUlhfd", MergeNone, "", [IsTupleGet, IsStreamingCompatible], [ImmCheck<1, ImmCheck0_3>]>;
|
||||
|
||||
def SVSET_2 : SInst<"svset2[_{d}]", "22id", "csilUcUsUiUlhfd", MergeNone, "", [IsTupleSet], [ImmCheck<1, ImmCheck0_1>]>;
|
||||
def SVSET_3 : SInst<"svset3[_{d}]", "33id", "csilUcUsUiUlhfd", MergeNone, "", [IsTupleSet], [ImmCheck<1, ImmCheck0_2>]>;
|
||||
def SVSET_4 : SInst<"svset4[_{d}]", "44id", "csilUcUsUiUlhfd", MergeNone, "", [IsTupleSet], [ImmCheck<1, ImmCheck0_3>]>;
|
||||
def SVSET_2 : SInst<"svset2[_{d}]", "22id", "csilUcUsUiUlhfd", MergeNone, "", [IsTupleSet, IsStreamingCompatible], [ImmCheck<1, ImmCheck0_1>]>;
|
||||
def SVSET_3 : SInst<"svset3[_{d}]", "33id", "csilUcUsUiUlhfd", MergeNone, "", [IsTupleSet, IsStreamingCompatible], [ImmCheck<1, ImmCheck0_2>]>;
|
||||
def SVSET_4 : SInst<"svset4[_{d}]", "44id", "csilUcUsUiUlhfd", MergeNone, "", [IsTupleSet, IsStreamingCompatible], [ImmCheck<1, ImmCheck0_3>]>;
|
||||
|
||||
let TargetGuard = "sve,bf16" in {
|
||||
def SVGET_2_BF16 : SInst<"svget2[_{d}]", "d2i", "b", MergeNone, "", [IsTupleGet], [ImmCheck<1, ImmCheck0_1>]>;
|
||||
def SVGET_3_BF16 : SInst<"svget3[_{d}]", "d3i", "b", MergeNone, "", [IsTupleGet], [ImmCheck<1, ImmCheck0_2>]>;
|
||||
def SVGET_4_BF16 : SInst<"svget4[_{d}]", "d4i", "b", MergeNone, "", [IsTupleGet], [ImmCheck<1, ImmCheck0_3>]>;
|
||||
def SVGET_2_BF16 : SInst<"svget2[_{d}]", "d2i", "b", MergeNone, "", [IsTupleGet, IsStreamingCompatible], [ImmCheck<1, ImmCheck0_1>]>;
|
||||
def SVGET_3_BF16 : SInst<"svget3[_{d}]", "d3i", "b", MergeNone, "", [IsTupleGet, IsStreamingCompatible], [ImmCheck<1, ImmCheck0_2>]>;
|
||||
def SVGET_4_BF16 : SInst<"svget4[_{d}]", "d4i", "b", MergeNone, "", [IsTupleGet, IsStreamingCompatible], [ImmCheck<1, ImmCheck0_3>]>;
|
||||
|
||||
def SVSET_2_BF16 : SInst<"svset2[_{d}]", "22id", "b", MergeNone, "", [IsTupleSet], [ImmCheck<1, ImmCheck0_1>]>;
|
||||
def SVSET_3_BF16 : SInst<"svset3[_{d}]", "33id", "b", MergeNone, "", [IsTupleSet], [ImmCheck<1, ImmCheck0_2>]>;
|
||||
def SVSET_4_BF16 : SInst<"svset4[_{d}]", "44id", "b", MergeNone, "", [IsTupleSet], [ImmCheck<1, ImmCheck0_3>]>;
|
||||
def SVSET_2_BF16 : SInst<"svset2[_{d}]", "22id", "b", MergeNone, "", [IsTupleSet, IsStreamingCompatible], [ImmCheck<1, ImmCheck0_1>]>;
|
||||
def SVSET_3_BF16 : SInst<"svset3[_{d}]", "33id", "b", MergeNone, "", [IsTupleSet, IsStreamingCompatible], [ImmCheck<1, ImmCheck0_2>]>;
|
||||
def SVSET_4_BF16 : SInst<"svset4[_{d}]", "44id", "b", MergeNone, "", [IsTupleSet, IsStreamingCompatible], [ImmCheck<1, ImmCheck0_3>]>;
|
||||
}
|
||||
|
||||
let TargetGuard = "sve2p1" in {
|
||||
def SVGET_2_B : SInst<"svget2[_{d}]", "d2i", "Pc", MergeNone, "", [IsTupleGet], [ImmCheck<1, ImmCheck0_1>]>;
|
||||
def SVGET_4_B : SInst<"svget4[_{d}]", "d4i", "Pc", MergeNone, "", [IsTupleGet], [ImmCheck<1, ImmCheck0_3>]>;
|
||||
let TargetGuard = "sve2p1|sme2" in {
|
||||
def SVGET_2_B : SInst<"svget2[_b]", "d2i", "Pc", MergeNone, "", [IsTupleGet, IsStreamingCompatible], [ImmCheck<1, ImmCheck0_1>]>;
|
||||
def SVGET_4_B : SInst<"svget4[_b]", "d4i", "Pc", MergeNone, "", [IsTupleGet, IsStreamingCompatible], [ImmCheck<1, ImmCheck0_3>]>;
|
||||
|
||||
def SVSET_2_B : SInst<"svset2[_{d}]", "22id", "Pc", MergeNone, "", [IsTupleSet], [ImmCheck<1, ImmCheck0_1>]>;
|
||||
def SVSET_4_B : SInst<"svset4[_{d}]", "44id", "Pc", MergeNone, "", [IsTupleSet], [ImmCheck<1, ImmCheck0_3>]>;
|
||||
def SVSET_2_B : SInst<"svset2[_b]", "22id", "Pc", MergeNone, "", [IsTupleSet, IsStreamingCompatible], [ImmCheck<1, ImmCheck0_1>]>;
|
||||
def SVSET_4_B : SInst<"svset4[_b]", "44id", "Pc", MergeNone, "", [IsTupleSet, IsStreamingCompatible], [ImmCheck<1, ImmCheck0_3>]>;
|
||||
}
|
||||
|
||||
let TargetGuard = "sve2p1|sme2" in {
|
||||
def SVUNDEF_2_B: Inst<"svundef2_b", "2", "Pc", MergeNone, "", [IsUndef, IsStreamingCompatible], []>;
|
||||
def SVUNDEF_4_B: Inst<"svundef4_b", "4", "Pc", MergeNone, "", [IsUndef, IsStreamingCompatible], []>;
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// SVE2 WhileGE/GT
|
||||
let TargetGuard = "sve2" in {
|
||||
def SVWHILEGE_S32 : SInst<"svwhilege_{d}[_{1}]", "Pkk", "PcPsPiPl", MergeNone, "aarch64_sve_whilege", [IsOverloadWhile, IsStreamingCompatible]>;
|
||||
def SVWHILEGE_S64 : SInst<"svwhilege_{d}[_{1}]", "Pll", "PcPsPiPl", MergeNone, "aarch64_sve_whilege", [IsOverloadWhile, IsStreamingCompatible]>;
|
||||
def SVWHILEGT_S32 : SInst<"svwhilegt_{d}[_{1}]", "Pkk", "PcPsPiPl", MergeNone, "aarch64_sve_whilegt", [IsOverloadWhile, IsStreamingCompatible]>;
|
||||
def SVWHILEGT_S64 : SInst<"svwhilegt_{d}[_{1}]", "Pll", "PcPsPiPl", MergeNone, "aarch64_sve_whilegt", [IsOverloadWhile, IsStreamingCompatible]>;
|
||||
def SVWHILEHI_U32 : SInst<"svwhilegt_{d}[_{1}]", "Pmm", "PUcPUsPUiPUl", MergeNone, "aarch64_sve_whilehi", [IsOverloadWhile, IsStreamingCompatible]>;
|
||||
def SVWHILEHI_U64 : SInst<"svwhilegt_{d}[_{1}]", "Pnn", "PUcPUsPUiPUl", MergeNone, "aarch64_sve_whilehi", [IsOverloadWhile, IsStreamingCompatible]>;
|
||||
def SVWHILEHS_U32 : SInst<"svwhilege_{d}[_{1}]", "Pmm", "PUcPUsPUiPUl", MergeNone, "aarch64_sve_whilehs", [IsOverloadWhile, IsStreamingCompatible]>;
|
||||
def SVWHILEHS_U64 : SInst<"svwhilege_{d}[_{1}]", "Pnn", "PUcPUsPUiPUl", MergeNone, "aarch64_sve_whilehs", [IsOverloadWhile, IsStreamingCompatible]>;
|
||||
def SVWHILEGE_S32 : SInst<"svwhilege_{d}[_{1}]", "Pkk", "PcPsPiPl", MergeNone, "aarch64_sve_whilege", [IsOverloadWhileOrMultiVecCvt, IsStreamingCompatible]>;
|
||||
def SVWHILEGE_S64 : SInst<"svwhilege_{d}[_{1}]", "Pll", "PcPsPiPl", MergeNone, "aarch64_sve_whilege", [IsOverloadWhileOrMultiVecCvt, IsStreamingCompatible]>;
|
||||
def SVWHILEGT_S32 : SInst<"svwhilegt_{d}[_{1}]", "Pkk", "PcPsPiPl", MergeNone, "aarch64_sve_whilegt", [IsOverloadWhileOrMultiVecCvt, IsStreamingCompatible]>;
|
||||
def SVWHILEGT_S64 : SInst<"svwhilegt_{d}[_{1}]", "Pll", "PcPsPiPl", MergeNone, "aarch64_sve_whilegt", [IsOverloadWhileOrMultiVecCvt, IsStreamingCompatible]>;
|
||||
def SVWHILEHI_U32 : SInst<"svwhilegt_{d}[_{1}]", "Pmm", "PUcPUsPUiPUl", MergeNone, "aarch64_sve_whilehi", [IsOverloadWhileOrMultiVecCvt, IsStreamingCompatible]>;
|
||||
def SVWHILEHI_U64 : SInst<"svwhilegt_{d}[_{1}]", "Pnn", "PUcPUsPUiPUl", MergeNone, "aarch64_sve_whilehi", [IsOverloadWhileOrMultiVecCvt, IsStreamingCompatible]>;
|
||||
def SVWHILEHS_U32 : SInst<"svwhilege_{d}[_{1}]", "Pmm", "PUcPUsPUiPUl", MergeNone, "aarch64_sve_whilehs", [IsOverloadWhileOrMultiVecCvt, IsStreamingCompatible]>;
|
||||
def SVWHILEHS_U64 : SInst<"svwhilege_{d}[_{1}]", "Pnn", "PUcPUsPUiPUl", MergeNone, "aarch64_sve_whilehs", [IsOverloadWhileOrMultiVecCvt, IsStreamingCompatible]>;
|
||||
}
|
||||
|
||||
let TargetGuard = "sve2p1|sme2" in {
|
||||
def SVWHILEGE_S64_X2 : SInst<"svwhilege_{d}[_{1}]_x2", "2ll", "PcPsPiPl", MergeNone, "aarch64_sve_whilege_x2">;
|
||||
def SVWHILEGT_S64_X2 : SInst<"svwhilegt_{d}[_{1}]_x2", "2ll", "PcPsPiPl", MergeNone, "aarch64_sve_whilegt_x2">;
|
||||
def SVWHILEHI_U64_X2 : SInst<"svwhilegt_{d}[_{1}]_x2", "2nn", "PcPsPiPl", MergeNone, "aarch64_sve_whilehi_x2">;
|
||||
def SVWHILEHS_U64_X2 : SInst<"svwhilege_{d}[_{1}]_x2", "2nn", "PcPsPiPl", MergeNone, "aarch64_sve_whilehs_x2">;
|
||||
def SVWHILELE_S64_X2 : SInst<"svwhilele_{d}[_{1}]_x2", "2ll", "PcPsPiPl", MergeNone, "aarch64_sve_whilele_x2">;
|
||||
def SVWHILELT_S64_X2 : SInst<"svwhilelt_{d}[_{1}]_x2", "2ll", "PcPsPiPl", MergeNone, "aarch64_sve_whilelt_x2">;
|
||||
def SVWHILELO_U64_X2 : SInst<"svwhilelt_{d}[_{1}]_x2", "2nn", "PcPsPiPl", MergeNone, "aarch64_sve_whilelo_x2">;
|
||||
def SVWHILELS_U64_X2 : SInst<"svwhilele_{d}[_{1}]_x2", "2nn", "PcPsPiPl", MergeNone, "aarch64_sve_whilels_x2">;
|
||||
def SVWHILEGE_S64_X2 : SInst<"svwhilege_{d}[_{1}]_x2", "2ll", "PcPsPiPl", MergeNone, "aarch64_sve_whilege_x2", [IsStreamingOrSVE2p1]>;
|
||||
def SVWHILEGT_S64_X2 : SInst<"svwhilegt_{d}[_{1}]_x2", "2ll", "PcPsPiPl", MergeNone, "aarch64_sve_whilegt_x2", [IsStreamingOrSVE2p1]>;
|
||||
def SVWHILEHI_U64_X2 : SInst<"svwhilegt_{d}[_{1}]_x2", "2nn", "PcPsPiPl", MergeNone, "aarch64_sve_whilehi_x2", [IsStreamingOrSVE2p1]>;
|
||||
def SVWHILEHS_U64_X2 : SInst<"svwhilege_{d}[_{1}]_x2", "2nn", "PcPsPiPl", MergeNone, "aarch64_sve_whilehs_x2", [IsStreamingOrSVE2p1]>;
|
||||
def SVWHILELE_S64_X2 : SInst<"svwhilele_{d}[_{1}]_x2", "2ll", "PcPsPiPl", MergeNone, "aarch64_sve_whilele_x2", [IsStreamingOrSVE2p1]>;
|
||||
def SVWHILELT_S64_X2 : SInst<"svwhilelt_{d}[_{1}]_x2", "2ll", "PcPsPiPl", MergeNone, "aarch64_sve_whilelt_x2", [IsStreamingOrSVE2p1]>;
|
||||
def SVWHILELO_U64_X2 : SInst<"svwhilelt_{d}[_{1}]_x2", "2nn", "PcPsPiPl", MergeNone, "aarch64_sve_whilelo_x2", [IsStreamingOrSVE2p1]>;
|
||||
def SVWHILELS_U64_X2 : SInst<"svwhilele_{d}[_{1}]_x2", "2nn", "PcPsPiPl", MergeNone, "aarch64_sve_whilels_x2", [IsStreamingOrSVE2p1]>;
|
||||
|
||||
}
|
||||
|
||||
@ -1826,8 +1831,8 @@ def SVPMULLB_PAIR : SInst<"svpmullb_pair[_{d}]", "ddd", "UcUi", Mer
|
||||
def SVPMULLB_PAIR_N : SInst<"svpmullb_pair[_n_{d}]", "dda", "UcUi", MergeNone, "aarch64_sve_pmullb_pair", [IsStreamingCompatible]>;
|
||||
def SVPMULLT : SInst<"svpmullt[_{d}]", "dhh", "UsUl", MergeNone, "", [IsStreamingCompatible]>;
|
||||
def SVPMULLT_N : SInst<"svpmullt[_n_{d}]", "dhR", "UsUl", MergeNone, "", [IsStreamingCompatible]>;
|
||||
def SVPMULLT_PAIR : SInst<"svpmullt_pair[_{d}]", "ddd", "UcUi", MergeNone, "aarch64_sve_pmullt_pair">;
|
||||
def SVPMULLT_PAIR_N : SInst<"svpmullt_pair[_n_{d}]", "dda", "UcUi", MergeNone, "aarch64_sve_pmullt_pair">;
|
||||
def SVPMULLT_PAIR : SInst<"svpmullt_pair[_{d}]", "ddd", "UcUi", MergeNone, "aarch64_sve_pmullt_pair", [IsStreamingCompatible]>;
|
||||
def SVPMULLT_PAIR_N : SInst<"svpmullt_pair[_n_{d}]", "dda", "UcUi", MergeNone, "aarch64_sve_pmullt_pair", [IsStreamingCompatible]>;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -1948,14 +1953,10 @@ def SVBGRP_N : SInst<"svbgrp[_n_{d}]", "dda", "UcUsUiUl", MergeNone, "aarch64_sv
|
||||
}
|
||||
|
||||
let TargetGuard = "sve2p1|sme" in {
|
||||
def SVPSEL_B : SInst<"svpsel_lane_b8", "PPPm", "Pc", MergeNone, "", [IsStreamingCompatible], []>;
|
||||
def SVPSEL_H : SInst<"svpsel_lane_b16", "PPPm", "Ps", MergeNone, "", [IsStreamingCompatible], []>;
|
||||
def SVPSEL_S : SInst<"svpsel_lane_b32", "PPPm", "Pi", MergeNone, "", [IsStreamingCompatible], []>;
|
||||
def SVPSEL_D : SInst<"svpsel_lane_b64", "PPPm", "Pl", MergeNone, "", [IsStreamingCompatible], []>;
|
||||
def SVPSEL_COUNT_ALIAS_B : SInst<"svpsel_lane_c8", "}}Pm", "Pc", MergeNone, "", [IsStreamingCompatible], []>;
|
||||
def SVPSEL_COUNT_ALIAS_H : SInst<"svpsel_lane_c16", "}}Pm", "Ps", MergeNone, "", [IsStreamingCompatible], []>;
|
||||
def SVPSEL_COUNT_ALIAS_S : SInst<"svpsel_lane_c32", "}}Pm", "Pi", MergeNone, "", [IsStreamingCompatible], []>;
|
||||
def SVPSEL_COUNT_ALIAS_D : SInst<"svpsel_lane_c64", "}}Pm", "Pl", MergeNone, "", [IsStreamingCompatible], []>;
|
||||
def SVPSEL_B : SInst<"svpsel_lane_b8", "PPPm", "Pc", MergeNone, "", [IsStreamingOrSVE2p1], []>;
|
||||
def SVPSEL_H : SInst<"svpsel_lane_b16", "PPPm", "Ps", MergeNone, "", [IsStreamingOrSVE2p1], []>;
|
||||
def SVPSEL_S : SInst<"svpsel_lane_b32", "PPPm", "Pi", MergeNone, "", [IsStreamingOrSVE2p1], []>;
|
||||
def SVPSEL_D : SInst<"svpsel_lane_b64", "PPPm", "Pl", MergeNone, "", [IsStreamingOrSVE2p1], []>;
|
||||
}
|
||||
|
||||
// Standalone sve2.1 builtins
|
||||
@ -1979,6 +1980,11 @@ let TargetGuard = "sve2p1|sme2" in {
|
||||
def SVPEXT_SINGLE : SInst<"svpext_lane_{d}", "P}i", "QcQsQiQl", MergeNone, "aarch64_sve_pext", [IsStreamingOrSVE2p1], [ImmCheck<1, ImmCheck0_3>]>;
|
||||
def SVPEXT_X2 : SInst<"svpext_lane_{d}_x2", "2.P}i", "QcQsQiQl", MergeNone, "aarch64_sve_pext_x2", [IsStreamingOrSVE2p1], [ImmCheck<1, ImmCheck0_1>]>;
|
||||
|
||||
def SVPSEL_COUNT_ALIAS_B : SInst<"svpsel_lane_c8", "}}Pm", "Pc", MergeNone, "", [IsStreamingOrSVE2p1], []>;
|
||||
def SVPSEL_COUNT_ALIAS_H : SInst<"svpsel_lane_c16", "}}Pm", "Ps", MergeNone, "", [IsStreamingOrSVE2p1], []>;
|
||||
def SVPSEL_COUNT_ALIAS_S : SInst<"svpsel_lane_c32", "}}Pm", "Pi", MergeNone, "", [IsStreamingOrSVE2p1], []>;
|
||||
def SVPSEL_COUNT_ALIAS_D : SInst<"svpsel_lane_c64", "}}Pm", "Pl", MergeNone, "", [IsStreamingOrSVE2p1], []>;
|
||||
|
||||
def SVWHILEGE_COUNT : SInst<"svwhilege_{d}[_{1}]", "}lli", "QcQsQiQl", MergeNone, "aarch64_sve_whilege_{d}", [IsOverloadNone, IsStreamingOrSVE2p1], [ImmCheck<2, ImmCheck2_4_Mul2>]>;
|
||||
def SVWHILEGT_COUNT : SInst<"svwhilegt_{d}[_{1}]", "}lli", "QcQsQiQl", MergeNone, "aarch64_sve_whilegt_{d}", [IsOverloadNone, IsStreamingOrSVE2p1], [ImmCheck<2, ImmCheck2_4_Mul2>]>;
|
||||
def SVWHILELE_COUNT : SInst<"svwhilele_{d}[_{1}]", "}lli", "QcQsQiQl", MergeNone, "aarch64_sve_whilele_{d}", [IsOverloadNone, IsStreamingOrSVE2p1], [ImmCheck<2, ImmCheck2_4_Mul2>]>;
|
||||
@ -2039,13 +2045,13 @@ let TargetGuard = "sve2p1|sme2" in {
|
||||
defm STNT1 : MultiVecStore<"stnt1">;
|
||||
}
|
||||
|
||||
let TargetGuard = "sve2p1" in {
|
||||
def SVDOT_X2_S : SInst<"svdot[_{d}_{2}]", "ddhh", "i", MergeNone, "aarch64_sve_sdot_x2", [], []>;
|
||||
def SVDOT_X2_U : SInst<"svdot[_{d}_{2}]", "ddhh", "Ui", MergeNone, "aarch64_sve_udot_x2", [], []>;
|
||||
def SVDOT_X2_F : SInst<"svdot[_{d}_{2}]", "ddhh", "f", MergeNone, "aarch64_sve_fdot_x2", [], []>;
|
||||
def SVDOT_LANE_X2_S : SInst<"svdot_lane[_{d}_{2}]", "ddhhi", "i", MergeNone, "aarch64_sve_sdot_lane_x2", [], [ImmCheck<3, ImmCheck0_3>]>;
|
||||
def SVDOT_LANE_X2_U : SInst<"svdot_lane[_{d}_{2}]", "ddhhi", "Ui", MergeNone, "aarch64_sve_udot_lane_x2", [], [ImmCheck<3, ImmCheck0_3>]>;
|
||||
def SVDOT_LANE_X2_F : SInst<"svdot_lane[_{d}_{2}]", "ddhhi", "f", MergeNone, "aarch64_sve_fdot_lane_x2", [], [ImmCheck<3, ImmCheck0_3>]>;
|
||||
let TargetGuard = "sve2p1|sme2" in {
|
||||
def SVDOT_X2_S : SInst<"svdot[_{d}_{2}]", "ddhh", "i", MergeNone, "aarch64_sve_sdot_x2", [IsStreamingOrSVE2p1], []>;
|
||||
def SVDOT_X2_U : SInst<"svdot[_{d}_{2}]", "ddhh", "Ui", MergeNone, "aarch64_sve_udot_x2", [IsStreamingOrSVE2p1], []>;
|
||||
def SVDOT_X2_F : SInst<"svdot[_{d}_{2}]", "ddhh", "f", MergeNone, "aarch64_sve_fdot_x2", [IsStreamingOrSVE2p1], []>;
|
||||
def SVDOT_LANE_X2_S : SInst<"svdot_lane[_{d}_{2}]", "ddhhi", "i", MergeNone, "aarch64_sve_sdot_lane_x2", [IsStreamingOrSVE2p1], [ImmCheck<3, ImmCheck0_3>]>;
|
||||
def SVDOT_LANE_X2_U : SInst<"svdot_lane[_{d}_{2}]", "ddhhi", "Ui", MergeNone, "aarch64_sve_udot_lane_x2", [IsStreamingOrSVE2p1], [ImmCheck<3, ImmCheck0_3>]>;
|
||||
def SVDOT_LANE_X2_F : SInst<"svdot_lane[_{d}_{2}]", "ddhhi", "f", MergeNone, "aarch64_sve_fdot_lane_x2", [IsStreamingOrSVE2p1], [ImmCheck<3, ImmCheck0_3>]>;
|
||||
}
|
||||
|
||||
let TargetGuard = "sve2p1|sme2" in {
|
||||
@ -2238,15 +2244,15 @@ let TargetGuard = "sme2" in {
|
||||
def SVCVT_F16_X2 : SInst<"svcvt_f16[_f32_x2]", "e2", "f", MergeNone, "aarch64_sve_fcvt_x2", [IsStreaming],[]>;
|
||||
def SVCVT_BF16_X2 : SInst<"svcvt_bf16[_f32_x2]", "$2", "f", MergeNone, "aarch64_sve_bfcvt_x2", [IsOverloadNone, IsStreaming],[]>;
|
||||
|
||||
def SVCVT_F32_U32_X2 : SInst<"svcvt_{d}[_u32_x2]", "2.d2.u", "f", MergeNone, "aarch64_sve_fcvtu_x2", [IsStreaming], []>;
|
||||
def SVCVT_U32_F32_X2 : SInst<"svcvt_u32[_{d}_x2]", "2.u2.d", "f", MergeNone, "aarch64_sve_ucvtf_x2", [IsStreaming], []>;
|
||||
def SVCVT_F32_S32_X2 : SInst<"svcvt_{d}[_s32_x2]", "2.d2.x", "f", MergeNone, "aarch64_sve_fcvts_x2", [IsStreaming], []>;
|
||||
def SVCVT_S32_F32_X2 : SInst<"svcvt_s32[_{d}_x2]", "2.x2.d", "f", MergeNone, "aarch64_sve_scvtf_x2", [IsStreaming], []>;
|
||||
def SVCVT_F32_U32_X2 : SInst<"svcvt_{d}[_u32_x2]", "2.d2.u", "f", MergeNone, "aarch64_sve_ucvtf_x2", [IsStreaming, IsOverloadWhileOrMultiVecCvt], []>;
|
||||
def SVCVT_U32_F32_X2 : SInst<"svcvt_{d}[_f32_x2]", "2.d2.M", "Ui", MergeNone, "aarch64_sve_fcvtzu_x2", [IsStreaming, IsOverloadWhileOrMultiVecCvt], []>;
|
||||
def SVCVT_F32_S32_X2 : SInst<"svcvt_{d}[_s32_x2]", "2.d2.x", "f", MergeNone, "aarch64_sve_scvtf_x2", [IsStreaming, IsOverloadWhileOrMultiVecCvt], []>;
|
||||
def SVCVT_S32_F32_X2 : SInst<"svcvt_{d}[_f32_x2]", "2.d2.M", "i", MergeNone, "aarch64_sve_fcvtzs_x2", [IsStreaming, IsOverloadWhileOrMultiVecCvt], []>;
|
||||
|
||||
def SVCVT_F32_U32_X4 : SInst<"svcvt_{d}[_u32_x4]", "4.d4.u", "f", MergeNone, "aarch64_sve_fcvtu_x4", [IsStreaming], []>;
|
||||
def SVCVT_U32_F32_X4 : SInst<"svcvt_u32[_{d}_x4]", "4.u4.d", "f", MergeNone, "aarch64_sve_ucvtf_x4", [IsStreaming], []>;
|
||||
def SVCVT_F32_S32_X4 : SInst<"svcvt_{d}[_s32_x4]", "4.d4.x", "f", MergeNone, "aarch64_sve_fcvts_x4", [IsStreaming], []>;
|
||||
def SVCVT_S32_F32_X4 : SInst<"svcvt_s32[_{d}_x4]", "4.x4.d", "f", MergeNone, "aarch64_sve_scvtf_x4", [IsStreaming], []>;
|
||||
def SVCVT_F32_U32_X4 : SInst<"svcvt_{d}[_u32_x4]", "4.d4.u", "f", MergeNone, "aarch64_sve_ucvtf_x4", [IsStreaming, IsOverloadWhileOrMultiVecCvt], []>;
|
||||
def SVCVT_U32_F32_X4 : SInst<"svcvt_{d}[_f32_x4]", "4.d4.M", "Ui", MergeNone, "aarch64_sve_fcvtzu_x4", [IsStreaming, IsOverloadWhileOrMultiVecCvt], []>;
|
||||
def SVCVT_F32_S32_X4 : SInst<"svcvt_{d}[_s32_x4]", "4.d4.x", "f", MergeNone, "aarch64_sve_scvtf_x4", [IsStreaming, IsOverloadWhileOrMultiVecCvt], []>;
|
||||
def SVCVT_S32_F32_X4 : SInst<"svcvt_{d}[_f32_x4]", "4.d4.M", "i", MergeNone, "aarch64_sve_fcvtzs_x4", [IsStreaming, IsOverloadWhileOrMultiVecCvt], []>;
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -194,40 +194,44 @@ def FirstSplatOperand : FlagType<0x00000400>;
|
||||
// These flags are used to specify which scalar operand
|
||||
// needs to be duplicated/splatted into a vector.
|
||||
// : :
|
||||
def SplatOperandMask : FlagType<0x00001C00>;
|
||||
def IsLoad : FlagType<0x00002000>;
|
||||
def IsStore : FlagType<0x00004000>;
|
||||
def IsGatherLoad : FlagType<0x00008000>;
|
||||
def IsScatterStore : FlagType<0x00010000>;
|
||||
def IsStructLoad : FlagType<0x00020000>;
|
||||
def IsStructStore : FlagType<0x00040000>;
|
||||
def IsZExtReturn : FlagType<0x00080000>; // Return value is sign-extend by default
|
||||
def IsOverloadNone : FlagType<0x00100000>; // Intrinsic does not take any overloaded types.
|
||||
def IsOverloadWhile : FlagType<0x00200000>; // Use {default type, typeof(operand1)} as overloaded types.
|
||||
def IsOverloadWhileRW : FlagType<0x00400000>; // Use {pred(default type), typeof(operand0)} as overloaded types.
|
||||
def IsOverloadCvt : FlagType<0x00800000>; // Use {typeof(operand0), typeof(last operand)} as overloaded types.
|
||||
def OverloadKindMask : FlagType<0x00E00000>; // When the masked values are all '0', the default type is used as overload type.
|
||||
def IsByteIndexed : FlagType<0x01000000>;
|
||||
def IsAppendSVALL : FlagType<0x02000000>; // Appends SV_ALL as the last operand.
|
||||
def IsInsertOp1SVALL : FlagType<0x04000000>; // Inserts SV_ALL as the second operand.
|
||||
def IsPrefetch : FlagType<0x08000000>; // Contiguous prefetches.
|
||||
def IsGatherPrefetch : FlagType<0x10000000>;
|
||||
def ReverseCompare : FlagType<0x20000000>; // Compare operands must be swapped.
|
||||
def ReverseUSDOT : FlagType<0x40000000>; // Unsigned/signed operands must be swapped.
|
||||
def IsUndef : FlagType<0x80000000>; // Codegen `undef` of given type.
|
||||
def IsTupleCreate : FlagType<0x100000000>;
|
||||
def IsTupleGet : FlagType<0x200000000>;
|
||||
def IsTupleSet : FlagType<0x400000000>;
|
||||
def ReverseMergeAnyBinOp : FlagType<0x800000000>; // e.g. Implement SUBR_X using SUB_X.
|
||||
def ReverseMergeAnyAccOp : FlagType<0x1000000000>; // e.g. Implement MSB_X using MLS_X.
|
||||
def IsStreaming : FlagType<0x2000000000>;
|
||||
def IsStreamingCompatible : FlagType<0x4000000000>;
|
||||
def IsSharedZA : FlagType<0x8000000000>;
|
||||
def IsPreservesZA : FlagType<0x10000000000>;
|
||||
def IsReadZA : FlagType<0x20000000000>;
|
||||
def IsWriteZA : FlagType<0x40000000000>;
|
||||
def IsReductionQV : FlagType<0x80000000000>;
|
||||
def IsStreamingOrSVE2p1 : FlagType<0x80000000000>; // Use for intrinsics that are common between sme/sme2 and sve2p1.
|
||||
def SplatOperandMask : FlagType<0x00001C00>;
|
||||
def IsLoad : FlagType<0x00002000>;
|
||||
def IsStore : FlagType<0x00004000>;
|
||||
def IsGatherLoad : FlagType<0x00008000>;
|
||||
def IsScatterStore : FlagType<0x00010000>;
|
||||
def IsStructLoad : FlagType<0x00020000>;
|
||||
def IsStructStore : FlagType<0x00040000>;
|
||||
def IsZExtReturn : FlagType<0x00080000>; // Return value is sign-extend by default
|
||||
def IsOverloadNone : FlagType<0x00100000>; // Intrinsic does not take any overloaded types.
|
||||
def IsOverloadWhileOrMultiVecCvt : FlagType<0x00200000>; // Use {default type, typeof(operand1)} as overloaded types.
|
||||
def IsOverloadWhileRW : FlagType<0x00400000>; // Use {pred(default type), typeof(operand0)} as overloaded types.
|
||||
def IsOverloadCvt : FlagType<0x00800000>; // Use {typeof(operand0), typeof(last operand)} as overloaded types.
|
||||
def OverloadKindMask : FlagType<0x00E00000>; // When the masked values are all '0', the default type is used as overload type.
|
||||
def IsByteIndexed : FlagType<0x01000000>;
|
||||
def IsAppendSVALL : FlagType<0x02000000>; // Appends SV_ALL as the last operand.
|
||||
def IsInsertOp1SVALL : FlagType<0x04000000>; // Inserts SV_ALL as the second operand.
|
||||
def IsPrefetch : FlagType<0x08000000>; // Contiguous prefetches.
|
||||
def IsGatherPrefetch : FlagType<0x10000000>;
|
||||
def ReverseCompare : FlagType<0x20000000>; // Compare operands must be swapped.
|
||||
def ReverseUSDOT : FlagType<0x40000000>; // Unsigned/signed operands must be swapped.
|
||||
def IsUndef : FlagType<0x80000000>; // Codegen `undef` of given type.
|
||||
def IsTupleCreate : FlagType<0x100000000>;
|
||||
def IsTupleGet : FlagType<0x200000000>;
|
||||
def IsTupleSet : FlagType<0x400000000>;
|
||||
def ReverseMergeAnyBinOp : FlagType<0x800000000>; // e.g. Implement SUBR_X using SUB_X.
|
||||
def ReverseMergeAnyAccOp : FlagType<0x1000000000>; // e.g. Implement MSB_X using MLS_X.
|
||||
def IsStreaming : FlagType<0x2000000000>;
|
||||
def IsStreamingCompatible : FlagType<0x4000000000>;
|
||||
def IsReadZA : FlagType<0x8000000000>;
|
||||
def IsWriteZA : FlagType<0x10000000000>;
|
||||
def IsReductionQV : FlagType<0x20000000000>;
|
||||
def IsStreamingOrSVE2p1 : FlagType<0x40000000000>; // Use for intrinsics that are common between sme/sme2 and sve2p1.
|
||||
def IsInZA : FlagType<0x80000000000>;
|
||||
def IsOutZA : FlagType<0x100000000000>;
|
||||
def IsInOutZA : FlagType<0x200000000000>;
|
||||
def IsInZT0 : FlagType<0x400000000000>;
|
||||
def IsOutZT0 : FlagType<0x800000000000>;
|
||||
def IsInOutZT0 : FlagType<0x1000000000000>;
|
||||
|
||||
// These must be kept in sync with the flags in include/clang/Basic/TargetBuiltins.h
|
||||
class ImmCheckType<int val> {
|
||||
|
@ -117,7 +117,7 @@ multiclass RVVIndexedLoad<string op> {
|
||||
defvar eew = eew_list[0];
|
||||
defvar eew_type = eew_list[1];
|
||||
let Name = op # eew # "_v", IRName = op, MaskedIRName = op # "_mask",
|
||||
RequiredFeatures = !if(!eq(type, "x"), ["ZvfhminOrZvfh"],
|
||||
RequiredFeatures = !if(!eq(type, "x"), ["Zvfhmin"],
|
||||
[]<string>) in {
|
||||
def: RVVOutOp1Builtin<"v", "vPCe" # eew_type # "Uv", type>;
|
||||
if !not(IsFloat<type>.val) then {
|
||||
@ -128,7 +128,7 @@ multiclass RVVIndexedLoad<string op> {
|
||||
defvar eew64 = "64";
|
||||
defvar eew64_type = "(Log2EEW:6)";
|
||||
let Name = op # eew64 # "_v", IRName = op, MaskedIRName = op # "_mask",
|
||||
RequiredFeatures = !if(!eq(type, "x"), ["ZvfhminOrZvfh", "RV64"],
|
||||
RequiredFeatures = !if(!eq(type, "x"), ["Zvfhmin", "RV64"],
|
||||
["RV64"]) in {
|
||||
def: RVVOutOp1Builtin<"v", "vPCe" # eew64_type # "Uv", type>;
|
||||
if !not(IsFloat<type>.val) then {
|
||||
@ -222,7 +222,7 @@ multiclass RVVIndexedStore<string op> {
|
||||
defvar eew = eew_list[0];
|
||||
defvar eew_type = eew_list[1];
|
||||
let Name = op # eew # "_v", IRName = op, MaskedIRName = op # "_mask",
|
||||
RequiredFeatures = !if(!eq(type, "x"), ["ZvfhminOrZvfh"],
|
||||
RequiredFeatures = !if(!eq(type, "x"), ["Zvfhmin"],
|
||||
[]<string>) in {
|
||||
def : RVVBuiltin<"v", "0Pe" # eew_type # "Uvv", type>;
|
||||
if !not(IsFloat<type>.val) then {
|
||||
@ -233,7 +233,7 @@ multiclass RVVIndexedStore<string op> {
|
||||
defvar eew64 = "64";
|
||||
defvar eew64_type = "(Log2EEW:6)";
|
||||
let Name = op # eew64 # "_v", IRName = op, MaskedIRName = op # "_mask",
|
||||
RequiredFeatures = !if(!eq(type, "x"), ["ZvfhminOrZvfh", "RV64"],
|
||||
RequiredFeatures = !if(!eq(type, "x"), ["Zvfhmin", "RV64"],
|
||||
["RV64"]) in {
|
||||
def : RVVBuiltin<"v", "0Pe" # eew64_type # "Uvv", type>;
|
||||
if !not(IsFloat<type>.val) then {
|
||||
@ -681,7 +681,7 @@ let HasBuiltinAlias = false,
|
||||
def vlm: RVVVLEMaskBuiltin;
|
||||
defm vle8: RVVVLEBuiltin<["c"]>;
|
||||
defm vle16: RVVVLEBuiltin<["s"]>;
|
||||
let Name = "vle16_v", RequiredFeatures = ["ZvfhminOrZvfh"] in
|
||||
let Name = "vle16_v", RequiredFeatures = ["Zvfhmin"] in
|
||||
defm vle16_h: RVVVLEBuiltin<["x"]>;
|
||||
defm vle32: RVVVLEBuiltin<["i","f"]>;
|
||||
defm vle64: RVVVLEBuiltin<["l","d"]>;
|
||||
@ -689,7 +689,7 @@ defm vle64: RVVVLEBuiltin<["l","d"]>;
|
||||
def vsm : RVVVSEMaskBuiltin;
|
||||
defm vse8 : RVVVSEBuiltin<["c"]>;
|
||||
defm vse16: RVVVSEBuiltin<["s"]>;
|
||||
let Name = "vse16_v", RequiredFeatures = ["ZvfhminOrZvfh"] in
|
||||
let Name = "vse16_v", RequiredFeatures = ["Zvfhmin"] in
|
||||
defm vse16_h: RVVVSEBuiltin<["x"]>;
|
||||
defm vse32: RVVVSEBuiltin<["i","f"]>;
|
||||
defm vse64: RVVVSEBuiltin<["l","d"]>;
|
||||
@ -697,14 +697,14 @@ defm vse64: RVVVSEBuiltin<["l","d"]>;
|
||||
// 7.5. Vector Strided Instructions
|
||||
defm vlse8: RVVVLSEBuiltin<["c"]>;
|
||||
defm vlse16: RVVVLSEBuiltin<["s"]>;
|
||||
let Name = "vlse16_v", RequiredFeatures = ["ZvfhminOrZvfh"] in
|
||||
let Name = "vlse16_v", RequiredFeatures = ["Zvfhmin"] in
|
||||
defm vlse16_h: RVVVLSEBuiltin<["x"]>;
|
||||
defm vlse32: RVVVLSEBuiltin<["i","f"]>;
|
||||
defm vlse64: RVVVLSEBuiltin<["l","d"]>;
|
||||
|
||||
defm vsse8 : RVVVSSEBuiltin<["c"]>;
|
||||
defm vsse16: RVVVSSEBuiltin<["s"]>;
|
||||
let Name = "vsse16_v", RequiredFeatures = ["ZvfhminOrZvfh"] in
|
||||
let Name = "vsse16_v", RequiredFeatures = ["Zvfhmin"] in
|
||||
defm vsse16_h: RVVVSSEBuiltin<["x"]>;
|
||||
defm vsse32: RVVVSSEBuiltin<["i","f"]>;
|
||||
defm vsse64: RVVVSSEBuiltin<["l","d"]>;
|
||||
@ -719,7 +719,7 @@ defm : RVVIndexedStore<"vsoxei">;
|
||||
// 7.7. Unit-stride Fault-Only-First Loads
|
||||
defm vle8ff: RVVVLEFFBuiltin<["c"]>;
|
||||
defm vle16ff: RVVVLEFFBuiltin<["s"]>;
|
||||
let Name = "vle16ff_v", RequiredFeatures = ["ZvfhminOrZvfh"] in
|
||||
let Name = "vle16ff_v", RequiredFeatures = ["Zvfhmin"] in
|
||||
defm vle16ff: RVVVLEFFBuiltin<["x"]>;
|
||||
defm vle32ff: RVVVLEFFBuiltin<["i", "f"]>;
|
||||
defm vle64ff: RVVVLEFFBuiltin<["l", "d"]>;
|
||||
@ -738,7 +738,7 @@ multiclass RVVUnitStridedSegLoadTuple<string op> {
|
||||
IRName = op # nf,
|
||||
MaskedIRName = op # nf # "_mask",
|
||||
NF = nf,
|
||||
RequiredFeatures = !if(!eq(type, "x"), ["ZvfhminOrZvfh"],
|
||||
RequiredFeatures = !if(!eq(type, "x"), ["Zvfhmin"],
|
||||
[]<string>),
|
||||
ManualCodegen = [{
|
||||
{
|
||||
@ -800,7 +800,7 @@ multiclass RVVUnitStridedSegStoreTuple<string op> {
|
||||
MaskedIRName = op # nf # "_mask",
|
||||
NF = nf,
|
||||
HasMaskedOffOperand = false,
|
||||
RequiredFeatures = !if(!eq(type, "x"), ["ZvfhminOrZvfh"],
|
||||
RequiredFeatures = !if(!eq(type, "x"), ["Zvfhmin"],
|
||||
[]<string>),
|
||||
ManualCodegen = [{
|
||||
{
|
||||
@ -852,7 +852,7 @@ multiclass RVVUnitStridedSegLoadFFTuple<string op> {
|
||||
IRName = op # nf # "ff",
|
||||
MaskedIRName = op # nf # "ff_mask",
|
||||
NF = nf,
|
||||
RequiredFeatures = !if(!eq(type, "x"), ["ZvfhminOrZvfh"],
|
||||
RequiredFeatures = !if(!eq(type, "x"), ["Zvfhmin"],
|
||||
[]<string>),
|
||||
ManualCodegen = [{
|
||||
{
|
||||
@ -927,7 +927,7 @@ multiclass RVVStridedSegLoadTuple<string op> {
|
||||
IRName = op # nf,
|
||||
MaskedIRName = op # nf # "_mask",
|
||||
NF = nf,
|
||||
RequiredFeatures = !if(!eq(type, "x"), ["ZvfhminOrZvfh"],
|
||||
RequiredFeatures = !if(!eq(type, "x"), ["Zvfhmin"],
|
||||
[]<string>),
|
||||
ManualCodegen = [{
|
||||
{
|
||||
@ -991,7 +991,7 @@ multiclass RVVStridedSegStoreTuple<string op> {
|
||||
NF = nf,
|
||||
HasMaskedOffOperand = false,
|
||||
MaskedPolicyScheme = NonePolicy,
|
||||
RequiredFeatures = !if(!eq(type, "x"), ["ZvfhminOrZvfh"],
|
||||
RequiredFeatures = !if(!eq(type, "x"), ["Zvfhmin"],
|
||||
[]<string>),
|
||||
ManualCodegen = [{
|
||||
{
|
||||
@ -1040,7 +1040,7 @@ multiclass RVVIndexedSegLoadTuple<string op> {
|
||||
IRName = op # nf,
|
||||
MaskedIRName = op # nf # "_mask",
|
||||
NF = nf,
|
||||
RequiredFeatures = !if(!eq(type, "x"), ["ZvfhminOrZvfh"],
|
||||
RequiredFeatures = !if(!eq(type, "x"), ["Zvfhmin"],
|
||||
[]<string>),
|
||||
ManualCodegen = [{
|
||||
{
|
||||
@ -1103,7 +1103,7 @@ multiclass RVVIndexedSegStoreTuple<string op> {
|
||||
NF = nf,
|
||||
HasMaskedOffOperand = false,
|
||||
MaskedPolicyScheme = NonePolicy,
|
||||
RequiredFeatures = !if(!eq(type, "x"), ["ZvfhminOrZvfh"],
|
||||
RequiredFeatures = !if(!eq(type, "x"), ["Zvfhmin"],
|
||||
[]<string>),
|
||||
ManualCodegen = [{
|
||||
{
|
||||
@ -1345,7 +1345,7 @@ let HasMasked = false,
|
||||
[["v", "Uv", "UvUv"]]>;
|
||||
defm vmv_v : RVVOutBuiltinSet<"vmv_v_v", "csilfd",
|
||||
[["v", "v", "vv"]]>;
|
||||
let RequiredFeatures = ["ZvfhminOrZvfh"] in
|
||||
let RequiredFeatures = ["Zvfhmin"] in
|
||||
defm vmv_v : RVVOutBuiltinSet<"vmv_v_v", "x",
|
||||
[["v", "v", "vv"]]>;
|
||||
let SupportOverloading = false in
|
||||
@ -1841,7 +1841,7 @@ let HasMasked = false,
|
||||
}] in {
|
||||
defm vmerge : RVVOutOp1BuiltinSet<"vmerge", "fd",
|
||||
[["vvm", "v", "vvvm"]]>;
|
||||
let RequiredFeatures = ["ZvfhminOrZvfh"] in
|
||||
let RequiredFeatures = ["Zvfhmin"] in
|
||||
defm vmerge : RVVOutOp1BuiltinSet<"vmerge", "x",
|
||||
[["vvm", "v", "vvvm"]]>;
|
||||
defm vfmerge : RVVOutOp1BuiltinSet<"vfmerge", "xfd",
|
||||
@ -1869,7 +1869,7 @@ let Log2LMUL = [-3, -2, -1, 0, 1, 2] in {
|
||||
def vfwcvt_f_xu_v : RVVConvBuiltin<"Fw", "FwUv", "csi", "vfwcvt_f">;
|
||||
def vfwcvt_f_x_v : RVVConvBuiltin<"Fw", "Fwv", "csi", "vfwcvt_f">;
|
||||
def vfwcvt_f_f_v : RVVConvBuiltin<"w", "wv", "f", "vfwcvt_f">;
|
||||
let RequiredFeatures = ["ZvfhminOrZvfh"] in
|
||||
let RequiredFeatures = ["Zvfhmin"] in
|
||||
def vfwcvt_f_f_v_fp16 : RVVConvBuiltin<"w", "wv", "x", "vfwcvt_f"> {
|
||||
let Name = "vfwcvt_f_f_v";
|
||||
let IRName = "vfwcvt_f_f_v";
|
||||
@ -1966,7 +1966,7 @@ let ManualCodegen = [{
|
||||
}
|
||||
let OverloadedName = "vfncvt_f" in {
|
||||
defm : RVVConvBuiltinSet<"vfncvt_f_f_w", "f", [["v", "vwu"]]>;
|
||||
let RequiredFeatures = ["ZvfhminOrZvfh"] in
|
||||
let RequiredFeatures = ["Zvfhmin"] in
|
||||
defm : RVVConvBuiltinSet<"vfncvt_f_f_w", "x", [["v", "vwu"]]>;
|
||||
}
|
||||
}
|
||||
@ -2011,7 +2011,7 @@ let ManualCodegen = [{
|
||||
}
|
||||
let OverloadedName = "vfncvt_f" in {
|
||||
defm : RVVConvBuiltinSet<"vfncvt_f_f_w", "f", [["v", "vw"]]>;
|
||||
let RequiredFeatures = ["ZvfhminOrZvfh"] in
|
||||
let RequiredFeatures = ["Zvfhmin"] in
|
||||
defm : RVVConvBuiltinSet<"vfncvt_f_f_w", "x", [["v", "vw"]]>;
|
||||
}
|
||||
}
|
||||
@ -2271,7 +2271,7 @@ let HasMasked = false, HasVL = false, IRName = "" in {
|
||||
def vreinterpret_u_f : RVVBuiltin<"FvUv", "UvFv", "il", "Uv">;
|
||||
def vreinterpret_f_i : RVVBuiltin<"vFv", "Fvv", "il", "Fv">;
|
||||
def vreinterpret_f_u : RVVBuiltin<"UvFv", "FvUv", "il", "Fv">;
|
||||
let RequiredFeatures = ["ZvfhminOrZvfh"] in {
|
||||
let RequiredFeatures = ["Zvfhmin"] in {
|
||||
def vreinterpret_i_h : RVVBuiltin<"Fvv", "vFv", "s", "v">;
|
||||
def vreinterpret_u_h : RVVBuiltin<"FvUv", "UvFv", "s", "Uv">;
|
||||
def vreinterpret_h_i : RVVBuiltin<"vFv", "Fvv", "s", "Fv">;
|
||||
|
@ -3459,6 +3459,10 @@ def fopenmp_offload_mandatory : Flag<["-"], "fopenmp-offload-mandatory">, Group<
|
||||
Flags<[NoArgumentUnused]>, Visibility<[ClangOption, CC1Option]>,
|
||||
HelpText<"Do not create a host fallback if offloading to the device fails.">,
|
||||
MarshallingInfoFlag<LangOpts<"OpenMPOffloadMandatory">>;
|
||||
def fopenmp_force_usm : Flag<["-"], "fopenmp-force-usm">, Group<f_Group>,
|
||||
Flags<[NoArgumentUnused]>, Visibility<[ClangOption, CC1Option]>,
|
||||
HelpText<"Force behvaior as if the user specified pragma omp requires unified_shared_memory.">,
|
||||
MarshallingInfoFlag<LangOpts<"OpenMPForceUSM">>;
|
||||
def fopenmp_target_jit : Flag<["-"], "fopenmp-target-jit">, Group<f_Group>,
|
||||
Flags<[NoArgumentUnused]>, Visibility<[ClangOption, CLOption]>,
|
||||
HelpText<"Emit code that can be JIT compiled for OpenMP offloading. Implies -foffload-lto=full">;
|
||||
@ -3664,6 +3668,10 @@ def ftrivial_auto_var_init_stop_after : Joined<["-"], "ftrivial-auto-var-init-st
|
||||
Visibility<[ClangOption, CC1Option, CLOption, DXCOption]>,
|
||||
HelpText<"Stop initializing trivial automatic stack variables after the specified number of instances">,
|
||||
MarshallingInfoInt<LangOpts<"TrivialAutoVarInitStopAfter">>;
|
||||
def ftrivial_auto_var_init_max_size : Joined<["-"], "ftrivial-auto-var-init-max-size=">, Group<f_Group>,
|
||||
Visibility<[ClangOption, CC1Option, CLOption, DXCOption]>,
|
||||
HelpText<"Stop initializing trivial automatic stack variables if var size exceeds the specified number of instances (in bytes)">,
|
||||
MarshallingInfoInt<LangOpts<"TrivialAutoVarInitMaxSize">>;
|
||||
def fstandalone_debug : Flag<["-"], "fstandalone-debug">, Group<f_Group>,
|
||||
Visibility<[ClangOption, CLOption, DXCOption]>,
|
||||
HelpText<"Emit full debug info for all types used by the program">;
|
||||
@ -3858,27 +3866,32 @@ def dA : Flag<["-"], "dA">, Alias<fverbose_asm>;
|
||||
defm visibility_from_dllstorageclass : BoolFOption<"visibility-from-dllstorageclass",
|
||||
LangOpts<"VisibilityFromDLLStorageClass">, DefaultFalse,
|
||||
PosFlag<SetTrue, [], [ClangOption, CC1Option],
|
||||
"Set the visibility of symbols in the generated code from their DLL storage class">,
|
||||
"Override the visibility of globals based on their final DLL storage class.">,
|
||||
NegFlag<SetFalse>>;
|
||||
class MarshallingInfoVisibilityFromDLLStorage<KeyPathAndMacro kpm, code default>
|
||||
: MarshallingInfoEnum<kpm, default>,
|
||||
Values<"keep,hidden,protected,default">,
|
||||
NormalizedValuesScope<"LangOptions::VisibilityFromDLLStorageClassKinds">,
|
||||
NormalizedValues<["Keep", "Hidden", "Protected", "Default"]> {}
|
||||
def fvisibility_dllexport_EQ : Joined<["-"], "fvisibility-dllexport=">, Group<f_Group>,
|
||||
Visibility<[ClangOption, CC1Option]>,
|
||||
HelpText<"The visibility for dllexport definitions [-fvisibility-from-dllstorageclass]">,
|
||||
MarshallingInfoVisibility<LangOpts<"DLLExportVisibility">, "DefaultVisibility">,
|
||||
HelpText<"The visibility for dllexport definitions. If Keep is specified the visibility is not adjusted [-fvisibility-from-dllstorageclass]">,
|
||||
MarshallingInfoVisibilityFromDLLStorage<LangOpts<"DLLExportVisibility">, "Default">,
|
||||
ShouldParseIf<fvisibility_from_dllstorageclass.KeyPath>;
|
||||
def fvisibility_nodllstorageclass_EQ : Joined<["-"], "fvisibility-nodllstorageclass=">, Group<f_Group>,
|
||||
Visibility<[ClangOption, CC1Option]>,
|
||||
HelpText<"The visibility for definitions without an explicit DLL export class [-fvisibility-from-dllstorageclass]">,
|
||||
MarshallingInfoVisibility<LangOpts<"NoDLLStorageClassVisibility">, "HiddenVisibility">,
|
||||
HelpText<"The visibility for definitions without an explicit DLL storage class. If Keep is specified the visibility is not adjusted [-fvisibility-from-dllstorageclass]">,
|
||||
MarshallingInfoVisibilityFromDLLStorage<LangOpts<"NoDLLStorageClassVisibility">, "Hidden">,
|
||||
ShouldParseIf<fvisibility_from_dllstorageclass.KeyPath>;
|
||||
def fvisibility_externs_dllimport_EQ : Joined<["-"], "fvisibility-externs-dllimport=">, Group<f_Group>,
|
||||
Visibility<[ClangOption, CC1Option]>,
|
||||
HelpText<"The visibility for dllimport external declarations [-fvisibility-from-dllstorageclass]">,
|
||||
MarshallingInfoVisibility<LangOpts<"ExternDeclDLLImportVisibility">, "DefaultVisibility">,
|
||||
HelpText<"The visibility for dllimport external declarations. If Keep is specified the visibility is not adjusted [-fvisibility-from-dllstorageclass]">,
|
||||
MarshallingInfoVisibilityFromDLLStorage<LangOpts<"ExternDeclDLLImportVisibility">, "Default">,
|
||||
ShouldParseIf<fvisibility_from_dllstorageclass.KeyPath>;
|
||||
def fvisibility_externs_nodllstorageclass_EQ : Joined<["-"], "fvisibility-externs-nodllstorageclass=">, Group<f_Group>,
|
||||
Visibility<[ClangOption, CC1Option]>,
|
||||
HelpText<"The visibility for external declarations without an explicit DLL dllstorageclass [-fvisibility-from-dllstorageclass]">,
|
||||
MarshallingInfoVisibility<LangOpts<"ExternDeclNoDLLStorageClassVisibility">, "HiddenVisibility">,
|
||||
HelpText<"The visibility for external declarations without an explicit DLL storage class. If Keep is specified the visibility is not adjusted [-fvisibility-from-dllstorageclass]">,
|
||||
MarshallingInfoVisibilityFromDLLStorage<LangOpts<"ExternDeclNoDLLStorageClassVisibility">, "Hidden">,
|
||||
ShouldParseIf<fvisibility_from_dllstorageclass.KeyPath>;
|
||||
def fvisibility_EQ : Joined<["-"], "fvisibility=">, Group<f_Group>,
|
||||
Visibility<[ClangOption, CC1Option]>,
|
||||
@ -3901,9 +3914,16 @@ def fvisibility_ms_compat : Flag<["-"], "fvisibility-ms-compat">, Group<f_Group>
|
||||
HelpText<"Give global types 'default' visibility and global functions and "
|
||||
"variables 'hidden' visibility by default">;
|
||||
def fvisibility_global_new_delete_hidden : Flag<["-"], "fvisibility-global-new-delete-hidden">, Group<f_Group>,
|
||||
HelpText<"Give global C++ operator new and delete declarations hidden visibility">,
|
||||
HelpText<"Give global C++ operator new and delete declarations hidden visibility">;
|
||||
class MarshallingInfoVisibilityGlobalNewDelete<KeyPathAndMacro kpm, code default>
|
||||
: MarshallingInfoEnum<kpm, default>,
|
||||
Values<"force-default,force-protected,force-hidden,source">,
|
||||
NormalizedValuesScope<"LangOptions::VisibilityForcedKinds">,
|
||||
NormalizedValues<["ForceDefault", "ForceProtected", "ForceHidden", "Source"]> {}
|
||||
def fvisibility_global_new_delete_EQ : Joined<["-"], "fvisibility-global-new-delete=">, Group<f_Group>,
|
||||
Visibility<[ClangOption, CC1Option]>,
|
||||
MarshallingInfoFlag<LangOpts<"GlobalAllocationFunctionVisibilityHidden">>;
|
||||
HelpText<"The visibility for global C++ operator new and delete declarations. If 'source' is specified the visibility is not adjusted">,
|
||||
MarshallingInfoVisibilityGlobalNewDelete<LangOpts<"GlobalAllocationFunctionVisibility">, "ForceDefault">;
|
||||
def mdefault_visibility_export_mapping_EQ : Joined<["-"], "mdefault-visibility-export-mapping=">,
|
||||
Values<"none,explicit,all">,
|
||||
NormalizedValuesScope<"LangOptions::DefaultVisiblityExportMapping">,
|
||||
@ -4392,8 +4412,8 @@ def mcmodel_EQ : Joined<["-"], "mcmodel=">, Group<m_Group>,
|
||||
Visibility<[ClangOption, CC1Option]>,
|
||||
MarshallingInfoString<TargetOpts<"CodeModel">, [{"default"}]>;
|
||||
def mlarge_data_threshold_EQ : Joined<["-"], "mlarge-data-threshold=">, Group<m_Group>,
|
||||
Visibility<[ClangOption, CC1Option]>,
|
||||
MarshallingInfoInt<TargetOpts<"LargeDataThreshold">, "65535">;
|
||||
Flags<[TargetSpecific]>, Visibility<[ClangOption, CC1Option]>,
|
||||
MarshallingInfoInt<TargetOpts<"LargeDataThreshold">, "0">;
|
||||
def mtls_size_EQ : Joined<["-"], "mtls-size=">, Group<m_Group>,
|
||||
Visibility<[ClangOption, CC1Option]>,
|
||||
HelpText<"Specify bit size of immediate TLS offsets (AArch64 ELF only): "
|
||||
@ -4761,12 +4781,12 @@ defm amdgpu_ieee : BoolOption<"m", "amdgpu-ieee",
|
||||
NegFlag<SetFalse, [], [ClangOption, CC1Option]>>, Group<m_Group>;
|
||||
|
||||
def mcode_object_version_EQ : Joined<["-"], "mcode-object-version=">, Group<m_Group>,
|
||||
HelpText<"Specify code object ABI version. Defaults to 4. (AMDGPU only)">,
|
||||
HelpText<"Specify code object ABI version. Defaults to 5. (AMDGPU only)">,
|
||||
Visibility<[ClangOption, FlangOption, CC1Option, FC1Option]>,
|
||||
Values<"none,4,5">,
|
||||
NormalizedValuesScope<"llvm::CodeObjectVersionKind">,
|
||||
NormalizedValues<["COV_None", "COV_4", "COV_5"]>,
|
||||
MarshallingInfoEnum<TargetOpts<"CodeObjectVersion">, "COV_4">;
|
||||
MarshallingInfoEnum<TargetOpts<"CodeObjectVersion">, "COV_5">;
|
||||
|
||||
defm cumode : SimpleMFlag<"cumode",
|
||||
"Specify CU wavefront", "Specify WGP wavefront",
|
||||
@ -5172,7 +5192,7 @@ def module_file_info : Flag<["-"], "module-file-info">, Flags<[]>,
|
||||
HelpText<"Provide information about a particular module file">;
|
||||
def mthumb : Flag<["-"], "mthumb">, Group<m_Group>;
|
||||
def mtune_EQ : Joined<["-"], "mtune=">, Group<m_Group>,
|
||||
HelpText<"Only supported on AArch64, PowerPC, RISC-V, SystemZ, and X86">;
|
||||
HelpText<"Only supported on AArch64, PowerPC, RISC-V, SPARC, SystemZ, and X86">;
|
||||
def multi__module : Flag<["-"], "multi_module">;
|
||||
def multiply__defined__unused : Separate<["-"], "multiply_defined_unused">;
|
||||
def multiply__defined : Separate<["-"], "multiply_defined">;
|
||||
@ -5307,7 +5327,8 @@ def pthreads : Flag<["-"], "pthreads">;
|
||||
defm pthread : BoolOption<"", "pthread",
|
||||
LangOpts<"POSIXThreads">, DefaultFalse,
|
||||
PosFlag<SetTrue, [], [ClangOption], "Support POSIX threads in generated code">,
|
||||
NegFlag<SetFalse>, BothFlags<[], [ClangOption, CC1Option]>>;
|
||||
NegFlag<SetFalse>,
|
||||
BothFlags<[], [ClangOption, CC1Option, FlangOption, FC1Option]>>;
|
||||
def pie : Flag<["-"], "pie">, Group<Link_Group>;
|
||||
def static_pie : Flag<["-"], "static-pie">, Group<Link_Group>;
|
||||
def read__only__relocs : Separate<["-"], "read_only_relocs">;
|
||||
@ -6043,11 +6064,11 @@ def mapx_features_EQ : CommaJoined<["-"], "mapx-features=">, Group<m_x86_Feature
|
||||
HelpText<"Enable features of APX">, Values<"egpr,push2pop2,ppx,ndd,ccmp,cf">;
|
||||
def mno_apx_features_EQ : CommaJoined<["-"], "mno-apx-features=">, Group<m_x86_Features_Group>,
|
||||
HelpText<"Disable features of APX">, Values<"egpr,push2pop2,ppx,ndd,ccmp,cf">;
|
||||
// Features egpr, push2pop2 and ppx are validated with llvm-test-suite && cpu2017 on Intel SDE.
|
||||
// Features egpr, push2pop2, ppx and ndd are validated with llvm-test-suite && cpu2017 on Intel SDE.
|
||||
// For stability, we turn on these features only for -mapxf. After a feature pass the validation,
|
||||
// we will add it to -mapxf.
|
||||
def mapxf : Flag<["-"], "mapxf">, Alias<mapx_features_EQ>, AliasArgs<["egpr","push2pop2","ppx"]>;
|
||||
def mno_apxf : Flag<["-"], "mno-apxf">, Alias<mno_apx_features_EQ>, AliasArgs<["egpr","push2pop2","ppx"]>;
|
||||
def mapxf : Flag<["-"], "mapxf">, Alias<mapx_features_EQ>, AliasArgs<["egpr","push2pop2","ppx", "ndd"]>;
|
||||
def mno_apxf : Flag<["-"], "mno-apxf">, Alias<mno_apx_features_EQ>, AliasArgs<["egpr","push2pop2","ppx","ndd"]>;
|
||||
} // let Flags = [TargetSpecific]
|
||||
|
||||
// VE feature flags
|
||||
@ -6297,6 +6318,11 @@ def fno_sycl : Flag<["-"], "fno-sycl">,
|
||||
Visibility<[ClangOption, CLOption]>,
|
||||
Group<sycl_Group>, HelpText<"Disables SYCL kernels compilation for device">;
|
||||
|
||||
// OS-specific options
|
||||
let Flags = [TargetSpecific] in {
|
||||
defm android_pad_segment : BooleanFFlag<"android-pad-segment">, Group<f_Group>;
|
||||
} // let Flags = [TargetSpecific]
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// FLangOption + NoXarchOption
|
||||
//===----------------------------------------------------------------------===//
|
||||
@ -8457,3 +8483,6 @@ def : Option<["/", "-"], "Qembed_debug", KIND_FLAG>, Group<dxc_Group>,
|
||||
HelpText<"Embed PDB in shader container (ignored)">;
|
||||
def spirv : DXCFlag<"spirv">,
|
||||
HelpText<"Generate SPIR-V code">;
|
||||
def fspv_target_env_EQ : Joined<["-"], "fspv-target-env=">, Group<dxc_Group>,
|
||||
HelpText<"Specify the target environment">,
|
||||
Values<"vulkan1.2, vulkan1.3">;
|
||||
|
@ -37,8 +37,10 @@
|
||||
// C family source language (with and without preprocessing).
|
||||
TYPE("cpp-output", PP_C, INVALID, "i", phases::Compile, phases::Backend, phases::Assemble, phases::Link)
|
||||
TYPE("c", C, PP_C, "c", phases::Preprocess, phases::Compile, phases::Backend, phases::Assemble, phases::Link)
|
||||
TYPE("cl", CL, PP_C, "cl", phases::Preprocess, phases::Compile, phases::Backend, phases::Assemble, phases::Link)
|
||||
TYPE("clcpp", CLCXX, PP_CXX, "clcpp", phases::Preprocess, phases::Compile, phases::Backend, phases::Assemble, phases::Link)
|
||||
TYPE("cl", CL, PP_CL, "cl", phases::Preprocess, phases::Compile, phases::Backend, phases::Assemble, phases::Link)
|
||||
TYPE("cl-cpp-output", PP_CL, INVALID, "cli", phases::Compile, phases::Backend, phases::Assemble, phases::Link)
|
||||
TYPE("clcpp", CLCXX, PP_CLCXX, "clcpp", phases::Preprocess, phases::Compile, phases::Backend, phases::Assemble, phases::Link)
|
||||
TYPE("clcpp-cpp-output", PP_CLCXX, INVALID, "clii", phases::Compile, phases::Backend, phases::Assemble, phases::Link)
|
||||
TYPE("cuda-cpp-output", PP_CUDA, INVALID, "cui", phases::Compile, phases::Backend, phases::Assemble, phases::Link)
|
||||
TYPE("cuda", CUDA, PP_CUDA, "cu", phases::Preprocess, phases::Compile, phases::Backend, phases::Assemble, phases::Link)
|
||||
TYPE("cuda", CUDA_DEVICE, PP_CUDA, "cu", phases::Preprocess, phases::Compile, phases::Backend, phases::Assemble, phases::Link)
|
||||
|
@ -169,6 +169,7 @@ struct APIRecord {
|
||||
RK_Enum,
|
||||
RK_StructField,
|
||||
RK_Struct,
|
||||
RK_UnionField,
|
||||
RK_Union,
|
||||
RK_StaticField,
|
||||
RK_CXXField,
|
||||
@ -224,7 +225,7 @@ struct APIRecord {
|
||||
StringRef USR;
|
||||
StringRef Name;
|
||||
PresumedLoc Location;
|
||||
AvailabilitySet Availabilities;
|
||||
AvailabilityInfo Availability;
|
||||
LinkageInfo Linkage;
|
||||
|
||||
/// Documentation comment lines attached to this symbol declaration.
|
||||
@ -256,12 +257,12 @@ public:
|
||||
APIRecord() = delete;
|
||||
|
||||
APIRecord(RecordKind Kind, StringRef USR, StringRef Name,
|
||||
PresumedLoc Location, AvailabilitySet Availabilities,
|
||||
PresumedLoc Location, AvailabilityInfo Availability,
|
||||
LinkageInfo Linkage, const DocComment &Comment,
|
||||
DeclarationFragments Declaration, DeclarationFragments SubHeading,
|
||||
bool IsFromSystemHeader)
|
||||
: USR(USR), Name(Name), Location(Location),
|
||||
Availabilities(std::move(Availabilities)), Linkage(Linkage),
|
||||
Availability(std::move(Availability)), Linkage(Linkage),
|
||||
Comment(Comment), Declaration(Declaration), SubHeading(SubHeading),
|
||||
IsFromSystemHeader(IsFromSystemHeader), Kind(Kind) {}
|
||||
|
||||
@ -274,10 +275,10 @@ public:
|
||||
|
||||
struct NamespaceRecord : APIRecord {
|
||||
NamespaceRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
|
||||
AvailabilitySet Availabilities, LinkageInfo Linkage,
|
||||
AvailabilityInfo Availability, LinkageInfo Linkage,
|
||||
const DocComment &Comment, DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading, bool IsFromSystemHeader)
|
||||
: APIRecord(RK_Namespace, USR, Name, Loc, std::move(Availabilities),
|
||||
: APIRecord(RK_Namespace, USR, Name, Loc, std::move(Availability),
|
||||
Linkage, Comment, Declaration, SubHeading,
|
||||
IsFromSystemHeader) {}
|
||||
|
||||
@ -291,23 +292,23 @@ struct GlobalFunctionRecord : APIRecord {
|
||||
FunctionSignature Signature;
|
||||
|
||||
GlobalFunctionRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
|
||||
AvailabilitySet Availabilities, LinkageInfo Linkage,
|
||||
AvailabilityInfo Availability, LinkageInfo Linkage,
|
||||
const DocComment &Comment,
|
||||
DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading,
|
||||
FunctionSignature Signature, bool IsFromSystemHeader)
|
||||
: APIRecord(RK_GlobalFunction, USR, Name, Loc, std::move(Availabilities),
|
||||
: APIRecord(RK_GlobalFunction, USR, Name, Loc, std::move(Availability),
|
||||
Linkage, Comment, Declaration, SubHeading,
|
||||
IsFromSystemHeader),
|
||||
Signature(Signature) {}
|
||||
|
||||
GlobalFunctionRecord(RecordKind Kind, StringRef USR, StringRef Name,
|
||||
PresumedLoc Loc, AvailabilitySet Availabilities,
|
||||
PresumedLoc Loc, AvailabilityInfo Availability,
|
||||
LinkageInfo Linkage, const DocComment &Comment,
|
||||
DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading,
|
||||
FunctionSignature Signature, bool IsFromSystemHeader)
|
||||
: APIRecord(Kind, USR, Name, Loc, std::move(Availabilities), Linkage,
|
||||
: APIRecord(Kind, USR, Name, Loc, std::move(Availability), Linkage,
|
||||
Comment, Declaration, SubHeading, IsFromSystemHeader),
|
||||
Signature(Signature) {}
|
||||
|
||||
@ -323,14 +324,14 @@ struct GlobalFunctionTemplateRecord : GlobalFunctionRecord {
|
||||
Template Templ;
|
||||
|
||||
GlobalFunctionTemplateRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
|
||||
AvailabilitySet Availabilities,
|
||||
AvailabilityInfo Availability,
|
||||
LinkageInfo Linkage, const DocComment &Comment,
|
||||
DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading,
|
||||
FunctionSignature Signature, Template Template,
|
||||
bool IsFromSystemHeader)
|
||||
: GlobalFunctionRecord(RK_GlobalFunctionTemplate, USR, Name, Loc,
|
||||
std::move(Availabilities), Linkage, Comment,
|
||||
std::move(Availability), Linkage, Comment,
|
||||
Declaration, SubHeading, Signature,
|
||||
IsFromSystemHeader),
|
||||
Templ(Template) {}
|
||||
@ -343,12 +344,12 @@ struct GlobalFunctionTemplateRecord : GlobalFunctionRecord {
|
||||
struct GlobalFunctionTemplateSpecializationRecord : GlobalFunctionRecord {
|
||||
GlobalFunctionTemplateSpecializationRecord(
|
||||
StringRef USR, StringRef Name, PresumedLoc Loc,
|
||||
AvailabilitySet Availabilities, LinkageInfo Linkage,
|
||||
AvailabilityInfo Availability, LinkageInfo Linkage,
|
||||
const DocComment &Comment, DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading, FunctionSignature Signature,
|
||||
bool IsFromSystemHeader)
|
||||
: GlobalFunctionRecord(RK_GlobalFunctionTemplateSpecialization, USR, Name,
|
||||
Loc, std::move(Availabilities), Linkage, Comment,
|
||||
Loc, std::move(Availability), Linkage, Comment,
|
||||
Declaration, SubHeading, Signature,
|
||||
IsFromSystemHeader) {}
|
||||
|
||||
@ -360,20 +361,20 @@ struct GlobalFunctionTemplateSpecializationRecord : GlobalFunctionRecord {
|
||||
/// This holds information associated with global functions.
|
||||
struct GlobalVariableRecord : APIRecord {
|
||||
GlobalVariableRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
|
||||
AvailabilitySet Availabilities, LinkageInfo Linkage,
|
||||
AvailabilityInfo Availability, LinkageInfo Linkage,
|
||||
const DocComment &Comment,
|
||||
DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading, bool IsFromSystemHeader)
|
||||
: APIRecord(RK_GlobalVariable, USR, Name, Loc, std::move(Availabilities),
|
||||
: APIRecord(RK_GlobalVariable, USR, Name, Loc, std::move(Availability),
|
||||
Linkage, Comment, Declaration, SubHeading,
|
||||
IsFromSystemHeader) {}
|
||||
|
||||
GlobalVariableRecord(RecordKind Kind, StringRef USR, StringRef Name,
|
||||
PresumedLoc Loc, AvailabilitySet Availabilities,
|
||||
PresumedLoc Loc, AvailabilityInfo Availability,
|
||||
LinkageInfo Linkage, const DocComment &Comment,
|
||||
DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading, bool IsFromSystemHeader)
|
||||
: APIRecord(Kind, USR, Name, Loc, std::move(Availabilities), Linkage,
|
||||
: APIRecord(Kind, USR, Name, Loc, std::move(Availability), Linkage,
|
||||
Comment, Declaration, SubHeading, IsFromSystemHeader) {}
|
||||
|
||||
static bool classof(const APIRecord *Record) {
|
||||
@ -388,13 +389,13 @@ struct GlobalVariableTemplateRecord : GlobalVariableRecord {
|
||||
Template Templ;
|
||||
|
||||
GlobalVariableTemplateRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
|
||||
AvailabilitySet Availabilities,
|
||||
AvailabilityInfo Availability,
|
||||
LinkageInfo Linkage, const DocComment &Comment,
|
||||
DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading,
|
||||
class Template Template, bool IsFromSystemHeader)
|
||||
: GlobalVariableRecord(RK_GlobalVariableTemplate, USR, Name, Loc,
|
||||
std::move(Availabilities), Linkage, Comment,
|
||||
std::move(Availability), Linkage, Comment,
|
||||
Declaration, SubHeading, IsFromSystemHeader),
|
||||
Templ(Template) {}
|
||||
|
||||
@ -406,11 +407,11 @@ struct GlobalVariableTemplateRecord : GlobalVariableRecord {
|
||||
struct GlobalVariableTemplateSpecializationRecord : GlobalVariableRecord {
|
||||
GlobalVariableTemplateSpecializationRecord(
|
||||
StringRef USR, StringRef Name, PresumedLoc Loc,
|
||||
AvailabilitySet Availabilities, LinkageInfo Linkage,
|
||||
AvailabilityInfo Availability, LinkageInfo Linkage,
|
||||
const DocComment &Comment, DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading, bool IsFromSystemHeader)
|
||||
: GlobalVariableRecord(RK_GlobalVariableTemplateSpecialization, USR, Name,
|
||||
Loc, std::move(Availabilities), Linkage, Comment,
|
||||
Loc, std::move(Availability), Linkage, Comment,
|
||||
Declaration, SubHeading, IsFromSystemHeader) {}
|
||||
|
||||
static bool classof(const APIRecord *Record) {
|
||||
@ -424,12 +425,12 @@ struct GlobalVariableTemplatePartialSpecializationRecord
|
||||
|
||||
GlobalVariableTemplatePartialSpecializationRecord(
|
||||
StringRef USR, StringRef Name, PresumedLoc Loc,
|
||||
AvailabilitySet Availabilities, LinkageInfo Linkage,
|
||||
AvailabilityInfo Availability, LinkageInfo Linkage,
|
||||
const DocComment &Comment, DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading, class Template Template,
|
||||
bool IsFromSystemHeader)
|
||||
: GlobalVariableRecord(RK_GlobalVariableTemplatePartialSpecialization,
|
||||
USR, Name, Loc, std::move(Availabilities), Linkage,
|
||||
USR, Name, Loc, std::move(Availability), Linkage,
|
||||
Comment, Declaration, SubHeading,
|
||||
IsFromSystemHeader),
|
||||
Templ(Template) {}
|
||||
@ -442,10 +443,10 @@ struct GlobalVariableTemplatePartialSpecializationRecord
|
||||
/// This holds information associated with enum constants.
|
||||
struct EnumConstantRecord : APIRecord {
|
||||
EnumConstantRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
|
||||
AvailabilitySet Availabilities, const DocComment &Comment,
|
||||
AvailabilityInfo Availability, const DocComment &Comment,
|
||||
DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading, bool IsFromSystemHeader)
|
||||
: APIRecord(RK_EnumConstant, USR, Name, Loc, std::move(Availabilities),
|
||||
: APIRecord(RK_EnumConstant, USR, Name, Loc, std::move(Availability),
|
||||
LinkageInfo::none(), Comment, Declaration, SubHeading,
|
||||
IsFromSystemHeader) {}
|
||||
|
||||
@ -462,10 +463,10 @@ struct EnumRecord : APIRecord {
|
||||
SmallVector<std::unique_ptr<EnumConstantRecord>> Constants;
|
||||
|
||||
EnumRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
|
||||
AvailabilitySet Availabilities, const DocComment &Comment,
|
||||
AvailabilityInfo Availability, const DocComment &Comment,
|
||||
DeclarationFragments Declaration, DeclarationFragments SubHeading,
|
||||
bool IsFromSystemHeader)
|
||||
: APIRecord(RK_Enum, USR, Name, Loc, std::move(Availabilities),
|
||||
: APIRecord(RK_Enum, USR, Name, Loc, std::move(Availability),
|
||||
LinkageInfo::none(), Comment, Declaration, SubHeading,
|
||||
IsFromSystemHeader) {}
|
||||
|
||||
@ -478,17 +479,19 @@ private:
|
||||
};
|
||||
|
||||
/// This holds information associated with struct fields.
|
||||
struct StructFieldRecord : APIRecord {
|
||||
StructFieldRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
|
||||
AvailabilitySet Availabilities, const DocComment &Comment,
|
||||
struct RecordFieldRecord : APIRecord {
|
||||
RecordFieldRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
|
||||
AvailabilityInfo Availability, const DocComment &Comment,
|
||||
DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading, bool IsFromSystemHeader)
|
||||
: APIRecord(RK_StructField, USR, Name, Loc, std::move(Availabilities),
|
||||
DeclarationFragments SubHeading, RecordKind Kind,
|
||||
bool IsFromSystemHeader)
|
||||
: APIRecord(Kind, USR, Name, Loc, std::move(Availability),
|
||||
LinkageInfo::none(), Comment, Declaration, SubHeading,
|
||||
IsFromSystemHeader) {}
|
||||
|
||||
static bool classof(const APIRecord *Record) {
|
||||
return Record->getKind() == RK_StructField;
|
||||
return Record->getKind() == RK_StructField ||
|
||||
Record->getKind() == RK_UnionField;
|
||||
}
|
||||
|
||||
private:
|
||||
@ -496,19 +499,20 @@ private:
|
||||
};
|
||||
|
||||
/// This holds information associated with structs.
|
||||
struct StructRecord : APIRecord {
|
||||
SmallVector<std::unique_ptr<StructFieldRecord>> Fields;
|
||||
struct RecordRecord : APIRecord {
|
||||
SmallVector<std::unique_ptr<RecordFieldRecord>> Fields;
|
||||
|
||||
StructRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
|
||||
AvailabilitySet Availabilities, const DocComment &Comment,
|
||||
RecordRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
|
||||
AvailabilityInfo Availability, const DocComment &Comment,
|
||||
DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading, bool IsFromSystemHeader)
|
||||
: APIRecord(RK_Struct, USR, Name, Loc, std::move(Availabilities),
|
||||
DeclarationFragments SubHeading, RecordKind Kind,
|
||||
bool IsFromSystemHeader)
|
||||
: APIRecord(Kind, USR, Name, Loc, std::move(Availability),
|
||||
LinkageInfo::none(), Comment, Declaration, SubHeading,
|
||||
IsFromSystemHeader) {}
|
||||
|
||||
static bool classof(const APIRecord *Record) {
|
||||
return Record->getKind() == RK_Struct;
|
||||
return Record->getKind() == RK_Struct || Record->getKind() == RK_Union;
|
||||
}
|
||||
|
||||
private:
|
||||
@ -519,21 +523,21 @@ struct CXXFieldRecord : APIRecord {
|
||||
AccessControl Access;
|
||||
|
||||
CXXFieldRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
|
||||
AvailabilitySet Availabilities, const DocComment &Comment,
|
||||
AvailabilityInfo Availability, const DocComment &Comment,
|
||||
DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading, AccessControl Access,
|
||||
bool IsFromSystemHeader)
|
||||
: APIRecord(RK_CXXField, USR, Name, Loc, std::move(Availabilities),
|
||||
: APIRecord(RK_CXXField, USR, Name, Loc, std::move(Availability),
|
||||
LinkageInfo::none(), Comment, Declaration, SubHeading,
|
||||
IsFromSystemHeader),
|
||||
Access(Access) {}
|
||||
|
||||
CXXFieldRecord(RecordKind Kind, StringRef USR, StringRef Name,
|
||||
PresumedLoc Loc, AvailabilitySet Availabilities,
|
||||
PresumedLoc Loc, AvailabilityInfo Availability,
|
||||
const DocComment &Comment, DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading, AccessControl Access,
|
||||
bool IsFromSystemHeader)
|
||||
: APIRecord(Kind, USR, Name, Loc, std::move(Availabilities),
|
||||
: APIRecord(Kind, USR, Name, Loc, std::move(Availability),
|
||||
LinkageInfo::none(), Comment, Declaration, SubHeading,
|
||||
IsFromSystemHeader),
|
||||
Access(Access) {}
|
||||
@ -550,13 +554,13 @@ struct CXXFieldTemplateRecord : CXXFieldRecord {
|
||||
Template Templ;
|
||||
|
||||
CXXFieldTemplateRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
|
||||
AvailabilitySet Availabilities,
|
||||
AvailabilityInfo Availability,
|
||||
const DocComment &Comment,
|
||||
DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading, AccessControl Access,
|
||||
Template Template, bool IsFromSystemHeader)
|
||||
: CXXFieldRecord(RK_CXXFieldTemplate, USR, Name, Loc,
|
||||
std::move(Availabilities), Comment, Declaration,
|
||||
std::move(Availability), Comment, Declaration,
|
||||
SubHeading, Access, IsFromSystemHeader),
|
||||
Templ(Template) {}
|
||||
|
||||
@ -572,11 +576,11 @@ struct CXXMethodRecord : APIRecord {
|
||||
CXXMethodRecord() = delete;
|
||||
|
||||
CXXMethodRecord(RecordKind Kind, StringRef USR, StringRef Name,
|
||||
PresumedLoc Loc, AvailabilitySet Availabilities,
|
||||
PresumedLoc Loc, AvailabilityInfo Availability,
|
||||
const DocComment &Comment, DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading, FunctionSignature Signature,
|
||||
AccessControl Access, bool IsFromSystemHeader)
|
||||
: APIRecord(Kind, USR, Name, Loc, std::move(Availabilities),
|
||||
: APIRecord(Kind, USR, Name, Loc, std::move(Availability),
|
||||
LinkageInfo::none(), Comment, Declaration, SubHeading,
|
||||
IsFromSystemHeader),
|
||||
Signature(Signature), Access(Access) {}
|
||||
@ -586,14 +590,13 @@ struct CXXMethodRecord : APIRecord {
|
||||
|
||||
struct CXXConstructorRecord : CXXMethodRecord {
|
||||
CXXConstructorRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
|
||||
AvailabilitySet Availabilities,
|
||||
const DocComment &Comment,
|
||||
AvailabilityInfo Availability, const DocComment &Comment,
|
||||
DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading,
|
||||
FunctionSignature Signature, AccessControl Access,
|
||||
bool IsFromSystemHeader)
|
||||
: CXXMethodRecord(RK_CXXConstructorMethod, USR, Name, Loc,
|
||||
std::move(Availabilities), Comment, Declaration,
|
||||
std::move(Availability), Comment, Declaration,
|
||||
SubHeading, Signature, Access, IsFromSystemHeader) {}
|
||||
static bool classof(const APIRecord *Record) {
|
||||
return Record->getKind() == RK_CXXConstructorMethod;
|
||||
@ -605,13 +608,13 @@ private:
|
||||
|
||||
struct CXXDestructorRecord : CXXMethodRecord {
|
||||
CXXDestructorRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
|
||||
AvailabilitySet Availabilities, const DocComment &Comment,
|
||||
AvailabilityInfo Availability, const DocComment &Comment,
|
||||
DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading,
|
||||
FunctionSignature Signature, AccessControl Access,
|
||||
bool IsFromSystemHeader)
|
||||
: CXXMethodRecord(RK_CXXDestructorMethod, USR, Name, Loc,
|
||||
std::move(Availabilities), Comment, Declaration,
|
||||
std::move(Availability), Comment, Declaration,
|
||||
SubHeading, Signature, Access, IsFromSystemHeader) {}
|
||||
static bool classof(const APIRecord *Record) {
|
||||
return Record->getKind() == RK_CXXDestructorMethod;
|
||||
@ -623,14 +626,14 @@ private:
|
||||
|
||||
struct CXXStaticMethodRecord : CXXMethodRecord {
|
||||
CXXStaticMethodRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
|
||||
AvailabilitySet Availabilities,
|
||||
AvailabilityInfo Availability,
|
||||
const DocComment &Comment,
|
||||
DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading,
|
||||
FunctionSignature Signature, AccessControl Access,
|
||||
bool IsFromSystemHeader)
|
||||
: CXXMethodRecord(RK_CXXStaticMethod, USR, Name, Loc,
|
||||
std::move(Availabilities), Comment, Declaration,
|
||||
std::move(Availability), Comment, Declaration,
|
||||
SubHeading, Signature, Access, IsFromSystemHeader) {}
|
||||
static bool classof(const APIRecord *Record) {
|
||||
return Record->getKind() == RK_CXXStaticMethod;
|
||||
@ -642,14 +645,14 @@ private:
|
||||
|
||||
struct CXXInstanceMethodRecord : CXXMethodRecord {
|
||||
CXXInstanceMethodRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
|
||||
AvailabilitySet Availabilities,
|
||||
AvailabilityInfo Availability,
|
||||
const DocComment &Comment,
|
||||
DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading,
|
||||
FunctionSignature Signature, AccessControl Access,
|
||||
bool IsFromSystemHeader)
|
||||
: CXXMethodRecord(RK_CXXInstanceMethod, USR, Name, Loc,
|
||||
std::move(Availabilities), Comment, Declaration,
|
||||
std::move(Availability), Comment, Declaration,
|
||||
SubHeading, Signature, Access, IsFromSystemHeader) {}
|
||||
|
||||
static bool classof(const APIRecord *Record) {
|
||||
@ -664,14 +667,14 @@ struct CXXMethodTemplateRecord : CXXMethodRecord {
|
||||
Template Templ;
|
||||
|
||||
CXXMethodTemplateRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
|
||||
AvailabilitySet Availabilities,
|
||||
AvailabilityInfo Availability,
|
||||
const DocComment &Comment,
|
||||
DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading,
|
||||
FunctionSignature Signature, AccessControl Access,
|
||||
Template Template, bool IsFromSystemHeader)
|
||||
: CXXMethodRecord(RK_CXXMethodTemplate, USR, Name, Loc,
|
||||
std::move(Availabilities), Comment, Declaration,
|
||||
std::move(Availability), Comment, Declaration,
|
||||
SubHeading, Signature, Access, IsFromSystemHeader),
|
||||
Templ(Template) {}
|
||||
|
||||
@ -683,12 +686,12 @@ struct CXXMethodTemplateRecord : CXXMethodRecord {
|
||||
struct CXXMethodTemplateSpecializationRecord : CXXMethodRecord {
|
||||
CXXMethodTemplateSpecializationRecord(
|
||||
StringRef USR, StringRef Name, PresumedLoc Loc,
|
||||
AvailabilitySet Availabilities, const DocComment &Comment,
|
||||
AvailabilityInfo Availability, const DocComment &Comment,
|
||||
DeclarationFragments Declaration, DeclarationFragments SubHeading,
|
||||
FunctionSignature Signature, AccessControl Access,
|
||||
bool IsFromSystemHeader)
|
||||
: CXXMethodRecord(RK_CXXMethodTemplateSpecialization, USR, Name, Loc,
|
||||
std::move(Availabilities), Comment, Declaration,
|
||||
std::move(Availability), Comment, Declaration,
|
||||
SubHeading, Signature, Access, IsFromSystemHeader) {}
|
||||
|
||||
static bool classof(const APIRecord *Record) {
|
||||
@ -711,13 +714,13 @@ struct ObjCPropertyRecord : APIRecord {
|
||||
bool IsOptional;
|
||||
|
||||
ObjCPropertyRecord(RecordKind Kind, StringRef USR, StringRef Name,
|
||||
PresumedLoc Loc, AvailabilitySet Availabilities,
|
||||
PresumedLoc Loc, AvailabilityInfo Availability,
|
||||
const DocComment &Comment,
|
||||
DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading, AttributeKind Attributes,
|
||||
StringRef GetterName, StringRef SetterName,
|
||||
bool IsOptional, bool IsFromSystemHeader)
|
||||
: APIRecord(Kind, USR, Name, Loc, std::move(Availabilities),
|
||||
: APIRecord(Kind, USR, Name, Loc, std::move(Availability),
|
||||
LinkageInfo::none(), Comment, Declaration, SubHeading,
|
||||
IsFromSystemHeader),
|
||||
Attributes(Attributes), GetterName(GetterName), SetterName(SetterName),
|
||||
@ -731,7 +734,7 @@ struct ObjCPropertyRecord : APIRecord {
|
||||
|
||||
struct ObjCInstancePropertyRecord : ObjCPropertyRecord {
|
||||
ObjCInstancePropertyRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
|
||||
AvailabilitySet Availabilities,
|
||||
AvailabilityInfo Availability,
|
||||
const DocComment &Comment,
|
||||
DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading,
|
||||
@ -739,7 +742,7 @@ struct ObjCInstancePropertyRecord : ObjCPropertyRecord {
|
||||
StringRef SetterName, bool IsOptional,
|
||||
bool IsFromSystemHeader)
|
||||
: ObjCPropertyRecord(RK_ObjCInstanceProperty, USR, Name, Loc,
|
||||
std::move(Availabilities), Comment, Declaration,
|
||||
std::move(Availability), Comment, Declaration,
|
||||
SubHeading, Attributes, GetterName, SetterName,
|
||||
IsOptional, IsFromSystemHeader) {}
|
||||
|
||||
@ -753,7 +756,7 @@ private:
|
||||
|
||||
struct ObjCClassPropertyRecord : ObjCPropertyRecord {
|
||||
ObjCClassPropertyRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
|
||||
AvailabilitySet Availabilities,
|
||||
AvailabilityInfo Availability,
|
||||
const DocComment &Comment,
|
||||
DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading,
|
||||
@ -761,7 +764,7 @@ struct ObjCClassPropertyRecord : ObjCPropertyRecord {
|
||||
StringRef SetterName, bool IsOptional,
|
||||
bool IsFromSystemHeader)
|
||||
: ObjCPropertyRecord(RK_ObjCClassProperty, USR, Name, Loc,
|
||||
std::move(Availabilities), Comment, Declaration,
|
||||
std::move(Availability), Comment, Declaration,
|
||||
SubHeading, Attributes, GetterName, SetterName,
|
||||
IsOptional, IsFromSystemHeader) {}
|
||||
|
||||
@ -779,12 +782,12 @@ struct ObjCInstanceVariableRecord : APIRecord {
|
||||
AccessControl Access;
|
||||
|
||||
ObjCInstanceVariableRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
|
||||
AvailabilitySet Availabilities,
|
||||
AvailabilityInfo Availability,
|
||||
const DocComment &Comment,
|
||||
DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading,
|
||||
AccessControl Access, bool IsFromSystemHeader)
|
||||
: APIRecord(RK_ObjCIvar, USR, Name, Loc, std::move(Availabilities),
|
||||
: APIRecord(RK_ObjCIvar, USR, Name, Loc, std::move(Availability),
|
||||
LinkageInfo::none(), Comment, Declaration, SubHeading,
|
||||
IsFromSystemHeader),
|
||||
Access(Access) {}
|
||||
@ -804,11 +807,11 @@ struct ObjCMethodRecord : APIRecord {
|
||||
ObjCMethodRecord() = delete;
|
||||
|
||||
ObjCMethodRecord(RecordKind Kind, StringRef USR, StringRef Name,
|
||||
PresumedLoc Loc, AvailabilitySet Availabilities,
|
||||
PresumedLoc Loc, AvailabilityInfo Availability,
|
||||
const DocComment &Comment, DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading, FunctionSignature Signature,
|
||||
bool IsFromSystemHeader)
|
||||
: APIRecord(Kind, USR, Name, Loc, std::move(Availabilities),
|
||||
: APIRecord(Kind, USR, Name, Loc, std::move(Availability),
|
||||
LinkageInfo::none(), Comment, Declaration, SubHeading,
|
||||
IsFromSystemHeader),
|
||||
Signature(Signature) {}
|
||||
@ -818,13 +821,13 @@ struct ObjCMethodRecord : APIRecord {
|
||||
|
||||
struct ObjCInstanceMethodRecord : ObjCMethodRecord {
|
||||
ObjCInstanceMethodRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
|
||||
AvailabilitySet Availabilities,
|
||||
AvailabilityInfo Availability,
|
||||
const DocComment &Comment,
|
||||
DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading,
|
||||
FunctionSignature Signature, bool IsFromSystemHeader)
|
||||
: ObjCMethodRecord(RK_ObjCInstanceMethod, USR, Name, Loc,
|
||||
std::move(Availabilities), Comment, Declaration,
|
||||
std::move(Availability), Comment, Declaration,
|
||||
SubHeading, Signature, IsFromSystemHeader) {}
|
||||
static bool classof(const APIRecord *Record) {
|
||||
return Record->getKind() == RK_ObjCInstanceMethod;
|
||||
@ -836,13 +839,13 @@ private:
|
||||
|
||||
struct ObjCClassMethodRecord : ObjCMethodRecord {
|
||||
ObjCClassMethodRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
|
||||
AvailabilitySet Availabilities,
|
||||
AvailabilityInfo Availability,
|
||||
const DocComment &Comment,
|
||||
DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading,
|
||||
FunctionSignature Signature, bool IsFromSystemHeader)
|
||||
: ObjCMethodRecord(RK_ObjCClassMethod, USR, Name, Loc,
|
||||
std::move(Availabilities), Comment, Declaration,
|
||||
std::move(Availability), Comment, Declaration,
|
||||
SubHeading, Signature, IsFromSystemHeader) {}
|
||||
|
||||
static bool classof(const APIRecord *Record) {
|
||||
@ -880,13 +883,13 @@ struct StaticFieldRecord : CXXFieldRecord {
|
||||
SymbolReference Context;
|
||||
|
||||
StaticFieldRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
|
||||
AvailabilitySet Availabilities, LinkageInfo Linkage,
|
||||
AvailabilityInfo Availability, LinkageInfo Linkage,
|
||||
const DocComment &Comment, DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading, SymbolReference Context,
|
||||
AccessControl Access, bool IsFromSystemHeader)
|
||||
: CXXFieldRecord(RK_StaticField, USR, Name, Loc,
|
||||
std::move(Availabilities), Comment, Declaration,
|
||||
SubHeading, Access, IsFromSystemHeader),
|
||||
: CXXFieldRecord(RK_StaticField, USR, Name, Loc, std::move(Availability),
|
||||
Comment, Declaration, SubHeading, Access,
|
||||
IsFromSystemHeader),
|
||||
Context(Context) {}
|
||||
|
||||
static bool classof(const APIRecord *Record) {
|
||||
@ -905,11 +908,11 @@ struct ObjCContainerRecord : APIRecord {
|
||||
ObjCContainerRecord() = delete;
|
||||
|
||||
ObjCContainerRecord(RecordKind Kind, StringRef USR, StringRef Name,
|
||||
PresumedLoc Loc, AvailabilitySet Availabilities,
|
||||
PresumedLoc Loc, AvailabilityInfo Availability,
|
||||
LinkageInfo Linkage, const DocComment &Comment,
|
||||
DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading, bool IsFromSystemHeader)
|
||||
: APIRecord(Kind, USR, Name, Loc, std::move(Availabilities), Linkage,
|
||||
: APIRecord(Kind, USR, Name, Loc, std::move(Availability), Linkage,
|
||||
Comment, Declaration, SubHeading, IsFromSystemHeader) {}
|
||||
|
||||
virtual ~ObjCContainerRecord() = 0;
|
||||
@ -922,11 +925,11 @@ struct CXXClassRecord : APIRecord {
|
||||
AccessControl Access;
|
||||
|
||||
CXXClassRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
|
||||
AvailabilitySet Availabilities, const DocComment &Comment,
|
||||
AvailabilityInfo Availability, const DocComment &Comment,
|
||||
DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading, RecordKind Kind,
|
||||
AccessControl Access, bool IsFromSystemHeader)
|
||||
: APIRecord(Kind, USR, Name, Loc, std::move(Availabilities),
|
||||
: APIRecord(Kind, USR, Name, Loc, std::move(Availability),
|
||||
LinkageInfo::none(), Comment, Declaration, SubHeading,
|
||||
IsFromSystemHeader),
|
||||
Access(Access) {}
|
||||
@ -943,11 +946,11 @@ struct ClassTemplateRecord : CXXClassRecord {
|
||||
Template Templ;
|
||||
|
||||
ClassTemplateRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
|
||||
AvailabilitySet Availabilities, const DocComment &Comment,
|
||||
AvailabilityInfo Availability, const DocComment &Comment,
|
||||
DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading, Template Template,
|
||||
AccessControl Access, bool IsFromSystemHeader)
|
||||
: CXXClassRecord(USR, Name, Loc, std::move(Availabilities), Comment,
|
||||
: CXXClassRecord(USR, Name, Loc, std::move(Availability), Comment,
|
||||
Declaration, SubHeading, RK_ClassTemplate, Access,
|
||||
IsFromSystemHeader),
|
||||
Templ(Template) {}
|
||||
@ -960,10 +963,10 @@ struct ClassTemplateRecord : CXXClassRecord {
|
||||
struct ClassTemplateSpecializationRecord : CXXClassRecord {
|
||||
ClassTemplateSpecializationRecord(
|
||||
StringRef USR, StringRef Name, PresumedLoc Loc,
|
||||
AvailabilitySet Availabilities, const DocComment &Comment,
|
||||
AvailabilityInfo Availability, const DocComment &Comment,
|
||||
DeclarationFragments Declaration, DeclarationFragments SubHeading,
|
||||
AccessControl Access, bool IsFromSystemHeader)
|
||||
: CXXClassRecord(USR, Name, Loc, std::move(Availabilities), Comment,
|
||||
: CXXClassRecord(USR, Name, Loc, std::move(Availability), Comment,
|
||||
Declaration, SubHeading, RK_ClassTemplateSpecialization,
|
||||
Access, IsFromSystemHeader) {}
|
||||
|
||||
@ -976,10 +979,10 @@ struct ClassTemplatePartialSpecializationRecord : CXXClassRecord {
|
||||
Template Templ;
|
||||
ClassTemplatePartialSpecializationRecord(
|
||||
StringRef USR, StringRef Name, PresumedLoc Loc,
|
||||
AvailabilitySet Availabilities, const DocComment &Comment,
|
||||
AvailabilityInfo Availability, const DocComment &Comment,
|
||||
DeclarationFragments Declaration, DeclarationFragments SubHeading,
|
||||
Template Template, AccessControl Access, bool IsFromSystemHeader)
|
||||
: CXXClassRecord(USR, Name, Loc, std::move(Availabilities), Comment,
|
||||
: CXXClassRecord(USR, Name, Loc, std::move(Availability), Comment,
|
||||
Declaration, SubHeading, RK_ClassTemplateSpecialization,
|
||||
Access, IsFromSystemHeader),
|
||||
Templ(Template) {}
|
||||
@ -993,11 +996,11 @@ struct ConceptRecord : APIRecord {
|
||||
Template Templ;
|
||||
|
||||
ConceptRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
|
||||
AvailabilitySet Availabilities, const DocComment &Comment,
|
||||
AvailabilityInfo Availability, const DocComment &Comment,
|
||||
DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading, Template Template,
|
||||
bool IsFromSystemHeader)
|
||||
: APIRecord(RK_Concept, USR, Name, Loc, std::move(Availabilities),
|
||||
: APIRecord(RK_Concept, USR, Name, Loc, std::move(Availability),
|
||||
LinkageInfo::none(), Comment, Declaration, SubHeading,
|
||||
IsFromSystemHeader),
|
||||
Templ(Template) {}
|
||||
@ -1010,12 +1013,12 @@ struct ObjCCategoryRecord : ObjCContainerRecord {
|
||||
bool IsFromExternalModule = false;
|
||||
|
||||
ObjCCategoryRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
|
||||
AvailabilitySet Availabilities, const DocComment &Comment,
|
||||
AvailabilityInfo Availability, const DocComment &Comment,
|
||||
DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading, SymbolReference Interface,
|
||||
bool IsFromSystemHeader)
|
||||
: ObjCContainerRecord(RK_ObjCCategory, USR, Name, Loc,
|
||||
std::move(Availabilities), LinkageInfo::none(),
|
||||
std::move(Availability), LinkageInfo::none(),
|
||||
Comment, Declaration, SubHeading,
|
||||
IsFromSystemHeader),
|
||||
Interface(Interface) {}
|
||||
@ -1035,13 +1038,13 @@ struct ObjCInterfaceRecord : ObjCContainerRecord {
|
||||
SmallVector<ObjCCategoryRecord *> Categories;
|
||||
|
||||
ObjCInterfaceRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
|
||||
AvailabilitySet Availabilities, LinkageInfo Linkage,
|
||||
AvailabilityInfo Availability, LinkageInfo Linkage,
|
||||
const DocComment &Comment,
|
||||
DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading,
|
||||
SymbolReference SuperClass, bool IsFromSystemHeader)
|
||||
: ObjCContainerRecord(RK_ObjCInterface, USR, Name, Loc,
|
||||
std::move(Availabilities), Linkage, Comment,
|
||||
std::move(Availability), Linkage, Comment,
|
||||
Declaration, SubHeading, IsFromSystemHeader),
|
||||
SuperClass(SuperClass) {}
|
||||
|
||||
@ -1056,11 +1059,11 @@ private:
|
||||
/// This holds information associated with Objective-C protocols.
|
||||
struct ObjCProtocolRecord : ObjCContainerRecord {
|
||||
ObjCProtocolRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
|
||||
AvailabilitySet Availabilities, const DocComment &Comment,
|
||||
AvailabilityInfo Availability, const DocComment &Comment,
|
||||
DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading, bool IsFromSystemHeader)
|
||||
: ObjCContainerRecord(RK_ObjCProtocol, USR, Name, Loc,
|
||||
std::move(Availabilities), LinkageInfo::none(),
|
||||
std::move(Availability), LinkageInfo::none(),
|
||||
Comment, Declaration, SubHeading,
|
||||
IsFromSystemHeader) {}
|
||||
|
||||
@ -1078,7 +1081,7 @@ struct MacroDefinitionRecord : APIRecord {
|
||||
DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading,
|
||||
bool IsFromSystemHeader)
|
||||
: APIRecord(RK_MacroDefinition, USR, Name, Loc, AvailabilitySet(),
|
||||
: APIRecord(RK_MacroDefinition, USR, Name, Loc, AvailabilityInfo(),
|
||||
LinkageInfo(), {}, Declaration, SubHeading,
|
||||
IsFromSystemHeader) {}
|
||||
|
||||
@ -1099,11 +1102,11 @@ struct TypedefRecord : APIRecord {
|
||||
SymbolReference UnderlyingType;
|
||||
|
||||
TypedefRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
|
||||
AvailabilitySet Availabilities, const DocComment &Comment,
|
||||
AvailabilityInfo Availability, const DocComment &Comment,
|
||||
DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading, SymbolReference UnderlyingType,
|
||||
bool IsFromSystemHeader)
|
||||
: APIRecord(RK_Typedef, USR, Name, Loc, std::move(Availabilities),
|
||||
: APIRecord(RK_Typedef, USR, Name, Loc, std::move(Availability),
|
||||
LinkageInfo(), Comment, Declaration, SubHeading,
|
||||
IsFromSystemHeader),
|
||||
UnderlyingType(UnderlyingType) {}
|
||||
@ -1191,7 +1194,7 @@ class APISet {
|
||||
public:
|
||||
NamespaceRecord *addNamespace(APIRecord *Parent, StringRef Name,
|
||||
StringRef USR, PresumedLoc Loc,
|
||||
AvailabilitySet Availability,
|
||||
AvailabilityInfo Availability,
|
||||
LinkageInfo Linkage, const DocComment &Comment,
|
||||
DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading,
|
||||
@ -1204,13 +1207,13 @@ public:
|
||||
/// to generate the USR for \c D and keep it alive in APISet.
|
||||
GlobalVariableRecord *
|
||||
addGlobalVar(StringRef Name, StringRef USR, PresumedLoc Loc,
|
||||
AvailabilitySet Availability, LinkageInfo Linkage,
|
||||
AvailabilityInfo Availability, LinkageInfo Linkage,
|
||||
const DocComment &Comment, DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeadin, bool IsFromSystemHeaderg);
|
||||
|
||||
GlobalVariableTemplateRecord *
|
||||
addGlobalVariableTemplate(StringRef Name, StringRef USR, PresumedLoc Loc,
|
||||
AvailabilitySet Availability, LinkageInfo Linkage,
|
||||
AvailabilityInfo Availability, LinkageInfo Linkage,
|
||||
const DocComment &Comment,
|
||||
DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading, Template Template,
|
||||
@ -1224,14 +1227,14 @@ public:
|
||||
/// to generate the USR for \c D and keep it alive in APISet.
|
||||
GlobalFunctionRecord *
|
||||
addGlobalFunction(StringRef Name, StringRef USR, PresumedLoc Loc,
|
||||
AvailabilitySet Availability, LinkageInfo Linkage,
|
||||
AvailabilityInfo Availability, LinkageInfo Linkage,
|
||||
const DocComment &Comment, DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading,
|
||||
FunctionSignature Signature, bool IsFromSystemHeader);
|
||||
|
||||
GlobalFunctionTemplateRecord *addGlobalFunctionTemplate(
|
||||
StringRef Name, StringRef USR, PresumedLoc Loc,
|
||||
AvailabilitySet Availability, LinkageInfo Linkage,
|
||||
AvailabilityInfo Availability, LinkageInfo Linkage,
|
||||
const DocComment &Comment, DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading, FunctionSignature Signature,
|
||||
Template Template, bool IsFromSystemHeader);
|
||||
@ -1239,7 +1242,7 @@ public:
|
||||
GlobalFunctionTemplateSpecializationRecord *
|
||||
addGlobalFunctionTemplateSpecialization(
|
||||
StringRef Name, StringRef USR, PresumedLoc Loc,
|
||||
AvailabilitySet Availability, LinkageInfo Linkage,
|
||||
AvailabilityInfo Availability, LinkageInfo Linkage,
|
||||
const DocComment &Comment, DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading, FunctionSignature Signature,
|
||||
bool IsFromSystemHeader);
|
||||
@ -1252,7 +1255,7 @@ public:
|
||||
/// to generate the USR for \c D and keep it alive in APISet.
|
||||
EnumConstantRecord *
|
||||
addEnumConstant(EnumRecord *Enum, StringRef Name, StringRef USR,
|
||||
PresumedLoc Loc, AvailabilitySet Availability,
|
||||
PresumedLoc Loc, AvailabilityInfo Availability,
|
||||
const DocComment &Comment, DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading, bool IsFromSystemHeader);
|
||||
|
||||
@ -1263,45 +1266,46 @@ public:
|
||||
/// APISet itself, and APISet::recordUSR(const Decl *D) is a helper method
|
||||
/// to generate the USR for \c D and keep it alive in APISet.
|
||||
EnumRecord *addEnum(StringRef Name, StringRef USR, PresumedLoc Loc,
|
||||
AvailabilitySet Availability, const DocComment &Comment,
|
||||
AvailabilityInfo Availability, const DocComment &Comment,
|
||||
DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading, bool IsFromSystemHeader);
|
||||
|
||||
/// Create and add a struct field record into the API set.
|
||||
/// Create and add a record field record into the API set.
|
||||
///
|
||||
/// Note: the caller is responsible for keeping the StringRef \p Name and
|
||||
/// \p USR alive. APISet::copyString provides a way to copy strings into
|
||||
/// APISet itself, and APISet::recordUSR(const Decl *D) is a helper method
|
||||
/// to generate the USR for \c D and keep it alive in APISet.
|
||||
StructFieldRecord *
|
||||
addStructField(StructRecord *Struct, StringRef Name, StringRef USR,
|
||||
PresumedLoc Loc, AvailabilitySet Availability,
|
||||
RecordFieldRecord *
|
||||
addRecordField(RecordRecord *Record, StringRef Name, StringRef USR,
|
||||
PresumedLoc Loc, AvailabilityInfo Availability,
|
||||
const DocComment &Comment, DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading, bool IsFromSystemHeader);
|
||||
DeclarationFragments SubHeading, APIRecord::RecordKind Kind,
|
||||
bool IsFromSystemHeader);
|
||||
|
||||
/// Create and add a struct record into the API set.
|
||||
/// Create and add a record record into the API set.
|
||||
///
|
||||
/// Note: the caller is responsible for keeping the StringRef \p Name and
|
||||
/// \p USR alive. APISet::copyString provides a way to copy strings into
|
||||
/// APISet itself, and APISet::recordUSR(const Decl *D) is a helper method
|
||||
/// to generate the USR for \c D and keep it alive in APISet.
|
||||
StructRecord *addStruct(StringRef Name, StringRef USR, PresumedLoc Loc,
|
||||
AvailabilitySet Availability,
|
||||
RecordRecord *addRecord(StringRef Name, StringRef USR, PresumedLoc Loc,
|
||||
AvailabilityInfo Availability,
|
||||
const DocComment &Comment,
|
||||
DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading,
|
||||
bool IsFromSystemHeader);
|
||||
APIRecord::RecordKind Kind, bool IsFromSystemHeader);
|
||||
|
||||
StaticFieldRecord *
|
||||
addStaticField(StringRef Name, StringRef USR, PresumedLoc Loc,
|
||||
AvailabilitySet Availabilities, LinkageInfo Linkage,
|
||||
AvailabilityInfo Availability, LinkageInfo Linkage,
|
||||
const DocComment &Comment, DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading, SymbolReference Context,
|
||||
AccessControl Access, bool IsFromSystemHeaderg);
|
||||
|
||||
CXXFieldRecord *addCXXField(APIRecord *CXXClass, StringRef Name,
|
||||
StringRef USR, PresumedLoc Loc,
|
||||
AvailabilitySet Availabilities,
|
||||
AvailabilityInfo Availability,
|
||||
const DocComment &Comment,
|
||||
DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading,
|
||||
@ -1309,12 +1313,12 @@ public:
|
||||
|
||||
CXXFieldTemplateRecord *addCXXFieldTemplate(
|
||||
APIRecord *Parent, StringRef Name, StringRef USR, PresumedLoc Loc,
|
||||
AvailabilitySet Availability, const DocComment &Comment,
|
||||
AvailabilityInfo Availability, const DocComment &Comment,
|
||||
DeclarationFragments Declaration, DeclarationFragments SubHeading,
|
||||
AccessControl Access, Template Template, bool IsFromSystemHeader);
|
||||
|
||||
CXXClassRecord *addCXXClass(APIRecord *Parent, StringRef Name, StringRef USR,
|
||||
PresumedLoc Loc, AvailabilitySet Availability,
|
||||
PresumedLoc Loc, AvailabilityInfo Availability,
|
||||
const DocComment &Comment,
|
||||
DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading,
|
||||
@ -1323,76 +1327,76 @@ public:
|
||||
|
||||
ClassTemplateRecord *
|
||||
addClassTemplate(APIRecord *Parent, StringRef Name, StringRef USR,
|
||||
PresumedLoc Loc, AvailabilitySet Availability,
|
||||
PresumedLoc Loc, AvailabilityInfo Availability,
|
||||
const DocComment &Comment, DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading, Template Template,
|
||||
AccessControl Access, bool IsFromSystemHeader);
|
||||
|
||||
ClassTemplateSpecializationRecord *addClassTemplateSpecialization(
|
||||
APIRecord *Parent, StringRef Name, StringRef USR, PresumedLoc Loc,
|
||||
AvailabilitySet Availability, const DocComment &Comment,
|
||||
AvailabilityInfo Availability, const DocComment &Comment,
|
||||
DeclarationFragments Declaration, DeclarationFragments SubHeading,
|
||||
AccessControl Access, bool IsFromSystemHeader);
|
||||
|
||||
ClassTemplatePartialSpecializationRecord *
|
||||
addClassTemplatePartialSpecialization(
|
||||
APIRecord *Parent, StringRef Name, StringRef USR, PresumedLoc Loc,
|
||||
AvailabilitySet Availability, const DocComment &Comment,
|
||||
AvailabilityInfo Availability, const DocComment &Comment,
|
||||
DeclarationFragments Declaration, DeclarationFragments SubHeading,
|
||||
Template Template, AccessControl Access, bool IsFromSystemHeader);
|
||||
|
||||
GlobalVariableTemplateSpecializationRecord *
|
||||
addGlobalVariableTemplateSpecialization(
|
||||
StringRef Name, StringRef USR, PresumedLoc Loc,
|
||||
AvailabilitySet Availability, LinkageInfo Linkage,
|
||||
AvailabilityInfo Availability, LinkageInfo Linkage,
|
||||
const DocComment &Comment, DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading, bool IsFromSystemHeader);
|
||||
|
||||
GlobalVariableTemplatePartialSpecializationRecord *
|
||||
addGlobalVariableTemplatePartialSpecialization(
|
||||
StringRef Name, StringRef USR, PresumedLoc Loc,
|
||||
AvailabilitySet Availability, LinkageInfo Linkage,
|
||||
AvailabilityInfo Availability, LinkageInfo Linkage,
|
||||
const DocComment &Comment, DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading, Template Template,
|
||||
bool IsFromSystemHeader);
|
||||
|
||||
CXXMethodRecord *addCXXInstanceMethod(
|
||||
APIRecord *Parent, StringRef Name, StringRef USR, PresumedLoc Loc,
|
||||
AvailabilitySet Availability, const DocComment &Comment,
|
||||
AvailabilityInfo Availability, const DocComment &Comment,
|
||||
DeclarationFragments Declaration, DeclarationFragments SubHeading,
|
||||
FunctionSignature Signature, AccessControl Access,
|
||||
bool IsFromSystemHeader);
|
||||
|
||||
CXXMethodRecord *addCXXStaticMethod(
|
||||
APIRecord *Parent, StringRef Name, StringRef USR, PresumedLoc Loc,
|
||||
AvailabilitySet Availability, const DocComment &Comment,
|
||||
AvailabilityInfo Availability, const DocComment &Comment,
|
||||
DeclarationFragments Declaration, DeclarationFragments SubHeading,
|
||||
FunctionSignature Signature, AccessControl Access,
|
||||
bool IsFromSystemHeader);
|
||||
|
||||
CXXMethodRecord *addCXXSpecialMethod(
|
||||
APIRecord *Parent, StringRef Name, StringRef USR, PresumedLoc Loc,
|
||||
AvailabilitySet Availability, const DocComment &Comment,
|
||||
AvailabilityInfo Availability, const DocComment &Comment,
|
||||
DeclarationFragments Declaration, DeclarationFragments SubHeading,
|
||||
FunctionSignature Signature, AccessControl Access,
|
||||
bool IsFromSystemHeader);
|
||||
|
||||
CXXMethodTemplateRecord *addCXXMethodTemplate(
|
||||
APIRecord *Parent, StringRef Name, StringRef USR, PresumedLoc Loc,
|
||||
AvailabilitySet Availability, const DocComment &Comment,
|
||||
AvailabilityInfo Availability, const DocComment &Comment,
|
||||
DeclarationFragments Declaration, DeclarationFragments SubHeading,
|
||||
FunctionSignature Signature, AccessControl Access, Template Template,
|
||||
bool IsFromSystemHeader);
|
||||
|
||||
CXXMethodTemplateSpecializationRecord *addCXXMethodTemplateSpec(
|
||||
APIRecord *Parent, StringRef Name, StringRef USR, PresumedLoc Loc,
|
||||
AvailabilitySet Availability, const DocComment &Comment,
|
||||
AvailabilityInfo Availability, const DocComment &Comment,
|
||||
DeclarationFragments Declaration, DeclarationFragments SubHeading,
|
||||
FunctionSignature Signature, AccessControl Access,
|
||||
bool IsFromSystemHeader);
|
||||
|
||||
ConceptRecord *addConcept(StringRef Name, StringRef USR, PresumedLoc Loc,
|
||||
AvailabilitySet Availability,
|
||||
AvailabilityInfo Availability,
|
||||
const DocComment &Comment,
|
||||
DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading, Template Template,
|
||||
@ -1406,7 +1410,7 @@ public:
|
||||
/// to generate the USR for \c D and keep it alive in APISet.
|
||||
ObjCCategoryRecord *
|
||||
addObjCCategory(StringRef Name, StringRef USR, PresumedLoc Loc,
|
||||
AvailabilitySet Availability, const DocComment &Comment,
|
||||
AvailabilityInfo Availability, const DocComment &Comment,
|
||||
DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading, SymbolReference Interface,
|
||||
bool IsFromSystemHeader, bool IsFromExternalModule);
|
||||
@ -1419,7 +1423,7 @@ public:
|
||||
/// to generate the USR for \c D and keep it alive in APISet.
|
||||
ObjCInterfaceRecord *
|
||||
addObjCInterface(StringRef Name, StringRef USR, PresumedLoc Loc,
|
||||
AvailabilitySet Availability, LinkageInfo Linkage,
|
||||
AvailabilityInfo Availability, LinkageInfo Linkage,
|
||||
const DocComment &Comment, DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading, SymbolReference SuperClass,
|
||||
bool IsFromSystemHeader);
|
||||
@ -1432,7 +1436,7 @@ public:
|
||||
/// to generate the USR for \c D and keep it alive in APISet.
|
||||
ObjCMethodRecord *
|
||||
addObjCMethod(ObjCContainerRecord *Container, StringRef Name, StringRef USR,
|
||||
PresumedLoc Loc, AvailabilitySet Availability,
|
||||
PresumedLoc Loc, AvailabilityInfo Availability,
|
||||
const DocComment &Comment, DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading, FunctionSignature Signature,
|
||||
bool IsInstanceMethod, bool IsFromSystemHeader);
|
||||
@ -1445,7 +1449,7 @@ public:
|
||||
/// to generate the USR for \c D and keep it alive in APISet.
|
||||
ObjCPropertyRecord *
|
||||
addObjCProperty(ObjCContainerRecord *Container, StringRef Name, StringRef USR,
|
||||
PresumedLoc Loc, AvailabilitySet Availability,
|
||||
PresumedLoc Loc, AvailabilityInfo Availability,
|
||||
const DocComment &Comment, DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading,
|
||||
ObjCPropertyRecord::AttributeKind Attributes,
|
||||
@ -1460,7 +1464,7 @@ public:
|
||||
/// to generate the USR for \c D and keep it alive in APISet.
|
||||
ObjCInstanceVariableRecord *addObjCInstanceVariable(
|
||||
ObjCContainerRecord *Container, StringRef Name, StringRef USR,
|
||||
PresumedLoc Loc, AvailabilitySet Availability, const DocComment &Comment,
|
||||
PresumedLoc Loc, AvailabilityInfo Availability, const DocComment &Comment,
|
||||
DeclarationFragments Declaration, DeclarationFragments SubHeading,
|
||||
ObjCInstanceVariableRecord::AccessControl Access,
|
||||
bool IsFromSystemHeader);
|
||||
@ -1473,7 +1477,7 @@ public:
|
||||
/// to generate the USR for \c D and keep it alive in APISet.
|
||||
ObjCProtocolRecord *
|
||||
addObjCProtocol(StringRef Name, StringRef USR, PresumedLoc Loc,
|
||||
AvailabilitySet Availability, const DocComment &Comment,
|
||||
AvailabilityInfo Availability, const DocComment &Comment,
|
||||
DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading, bool IsFromSystemHeader);
|
||||
|
||||
@ -1498,7 +1502,7 @@ public:
|
||||
/// to generate the USR for \c D and keep it alive in APISet.
|
||||
TypedefRecord *
|
||||
addTypedef(StringRef Name, StringRef USR, PresumedLoc Loc,
|
||||
AvailabilitySet Availability, const DocComment &Comment,
|
||||
AvailabilityInfo Availability, const DocComment &Comment,
|
||||
DeclarationFragments Declaration, DeclarationFragments SubHeading,
|
||||
SymbolReference UnderlyingType, bool IsFromSystemHeader);
|
||||
|
||||
@ -1545,7 +1549,7 @@ public:
|
||||
return GlobalVariableTemplatePartialSpecializations;
|
||||
}
|
||||
const RecordMap<EnumRecord> &getEnums() const { return Enums; }
|
||||
const RecordMap<StructRecord> &getStructs() const { return Structs; }
|
||||
const RecordMap<RecordRecord> &getRecords() const { return Records; }
|
||||
const RecordMap<CXXClassRecord> &getCXXClasses() const { return CXXClasses; }
|
||||
const RecordMap<CXXMethodTemplateRecord> &getCXXMethodTemplates() const {
|
||||
return CXXMethodTemplates;
|
||||
@ -1564,7 +1568,6 @@ public:
|
||||
const RecordMap<CXXFieldTemplateRecord> &getCXXFieldTemplates() const {
|
||||
return CXXFieldTemplates;
|
||||
}
|
||||
const RecordMap<ConceptRecord> &getConcepts() const { return Concepts; }
|
||||
const RecordMap<ClassTemplateRecord> &getClassTemplates() const {
|
||||
return ClassTemplates;
|
||||
}
|
||||
@ -1576,7 +1579,7 @@ public:
|
||||
getClassTemplatePartialSpecializations() const {
|
||||
return ClassTemplatePartialSpecializations;
|
||||
}
|
||||
const RecordMap<ConceptRecord> &getRecords() const { return Concepts; }
|
||||
const RecordMap<ConceptRecord> &getConcepts() const { return Concepts; }
|
||||
const RecordMap<ObjCCategoryRecord> &getObjCCategories() const {
|
||||
return ObjCCategories;
|
||||
}
|
||||
@ -1642,7 +1645,7 @@ private:
|
||||
RecordMap<ConceptRecord> Concepts;
|
||||
RecordMap<StaticFieldRecord> StaticFields;
|
||||
RecordMap<EnumRecord> Enums;
|
||||
RecordMap<StructRecord> Structs;
|
||||
RecordMap<RecordRecord> Records;
|
||||
RecordMap<CXXClassRecord> CXXClasses;
|
||||
RecordMap<CXXFieldRecord> CXXFields;
|
||||
RecordMap<CXXMethodRecord> CXXMethods;
|
||||
|
@ -16,56 +16,31 @@
|
||||
#define LLVM_CLANG_EXTRACTAPI_AVAILABILITY_INFO_H
|
||||
|
||||
#include "clang/AST/Decl.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/Support/Error.h"
|
||||
#include "llvm/Support/VersionTuple.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
||||
using llvm::VersionTuple;
|
||||
|
||||
namespace clang {
|
||||
namespace extractapi {
|
||||
|
||||
/// Stores availability attributes of a symbol in a given domain.
|
||||
/// Stores availability attributes of a symbol.
|
||||
struct AvailabilityInfo {
|
||||
/// The domain for which this availability info item applies
|
||||
std::string Domain;
|
||||
VersionTuple Introduced;
|
||||
VersionTuple Deprecated;
|
||||
VersionTuple Obsoleted;
|
||||
bool Unavailable;
|
||||
|
||||
AvailabilityInfo() = default;
|
||||
|
||||
AvailabilityInfo(StringRef Domain, VersionTuple I, VersionTuple D,
|
||||
VersionTuple O, bool U)
|
||||
: Domain(Domain), Introduced(I), Deprecated(D), Obsoleted(O),
|
||||
Unavailable(U) {}
|
||||
};
|
||||
|
||||
class AvailabilitySet {
|
||||
private:
|
||||
using AvailabilityList = llvm::SmallVector<AvailabilityInfo, 4>;
|
||||
AvailabilityList Availabilities;
|
||||
|
||||
bool UnconditionallyDeprecated = false;
|
||||
bool UnconditionallyUnavailable = false;
|
||||
|
||||
public:
|
||||
AvailabilitySet(const Decl *Decl);
|
||||
AvailabilitySet() = default;
|
||||
|
||||
AvailabilityList::const_iterator begin() const {
|
||||
return Availabilities.begin();
|
||||
}
|
||||
|
||||
AvailabilityList::const_iterator end() const { return Availabilities.end(); }
|
||||
AvailabilityInfo() = default;
|
||||
|
||||
/// Determine if this AvailabilityInfo represents the default availability.
|
||||
bool isDefault() const { return *this == AvailabilityInfo(); }
|
||||
/// Check if the symbol is unconditionally deprecated.
|
||||
///
|
||||
/// i.e. \code __attribute__((deprecated)) \endcode
|
||||
bool isUnconditionallyDeprecated() const { return UnconditionallyDeprecated; }
|
||||
|
||||
/// Check if the symbol is unconditionally unavailable.
|
||||
///
|
||||
/// i.e. \code __attribute__((unavailable)) \endcode
|
||||
@ -73,10 +48,28 @@ public:
|
||||
return UnconditionallyUnavailable;
|
||||
}
|
||||
|
||||
/// Determine if this AvailabilitySet represents default availability.
|
||||
bool isDefault() const { return Availabilities.empty(); }
|
||||
AvailabilityInfo(StringRef Domain, VersionTuple I, VersionTuple D,
|
||||
VersionTuple O, bool UD, bool UU)
|
||||
: Domain(Domain), Introduced(I), Deprecated(D), Obsoleted(O),
|
||||
UnconditionallyDeprecated(UD), UnconditionallyUnavailable(UU) {}
|
||||
|
||||
friend bool operator==(const AvailabilityInfo &Lhs,
|
||||
const AvailabilityInfo &Rhs);
|
||||
|
||||
public:
|
||||
static AvailabilityInfo createFromDecl(const Decl *Decl);
|
||||
};
|
||||
|
||||
inline bool operator==(const AvailabilityInfo &Lhs,
|
||||
const AvailabilityInfo &Rhs) {
|
||||
return std::tie(Lhs.Introduced, Lhs.Deprecated, Lhs.Obsoleted,
|
||||
Lhs.UnconditionallyDeprecated,
|
||||
Lhs.UnconditionallyUnavailable) ==
|
||||
std::tie(Rhs.Introduced, Rhs.Deprecated, Rhs.Obsoleted,
|
||||
Rhs.UnconditionallyDeprecated,
|
||||
Rhs.UnconditionallyUnavailable);
|
||||
}
|
||||
|
||||
} // namespace extractapi
|
||||
} // namespace clang
|
||||
|
||||
|
@ -295,8 +295,9 @@ public:
|
||||
/// Build DeclarationFragments for a field declaration FieldDecl.
|
||||
static DeclarationFragments getFragmentsForField(const FieldDecl *);
|
||||
|
||||
/// Build DeclarationFragments for a struct record declaration RecordDecl.
|
||||
static DeclarationFragments getFragmentsForStruct(const RecordDecl *);
|
||||
/// Build DeclarationFragments for a struct/union record declaration
|
||||
/// RecordDecl.
|
||||
static DeclarationFragments getFragmentsForRecordDecl(const RecordDecl *);
|
||||
|
||||
static DeclarationFragments getFragmentsForCXXClass(const CXXRecordDecl *);
|
||||
|
||||
|
@ -14,10 +14,12 @@
|
||||
#ifndef LLVM_CLANG_EXTRACTAPI_EXTRACT_API_VISITOR_H
|
||||
#define LLVM_CLANG_EXTRACTAPI_EXTRACT_API_VISITOR_H
|
||||
|
||||
#include "clang/AST/Decl.h"
|
||||
#include "clang/AST/DeclCXX.h"
|
||||
#include "clang/AST/DeclTemplate.h"
|
||||
#include "clang/Basic/OperatorKinds.h"
|
||||
#include "clang/Basic/Specifiers.h"
|
||||
#include "clang/ExtractAPI/AvailabilityInfo.h"
|
||||
#include "clang/ExtractAPI/DeclarationFragments.h"
|
||||
#include "llvm/ADT/FunctionExtras.h"
|
||||
|
||||
@ -128,9 +130,10 @@ protected:
|
||||
void recordEnumConstants(EnumRecord *EnumRecord,
|
||||
const EnumDecl::enumerator_range Constants);
|
||||
|
||||
/// Collect API information for the struct fields and associate with the
|
||||
/// Collect API information for the record fields and associate with the
|
||||
/// parent struct.
|
||||
void recordStructFields(StructRecord *StructRecord,
|
||||
void recordRecordFields(RecordRecord *RecordRecord,
|
||||
APIRecord::RecordKind FieldKind,
|
||||
const RecordDecl::field_range Fields);
|
||||
|
||||
/// Collect API information for the Objective-C methods and associate with the
|
||||
@ -263,7 +266,6 @@ bool ExtractAPIVisitorBase<Derived>::VisitVarDecl(const VarDecl *Decl) {
|
||||
DeclarationFragmentsBuilder::getFragmentsForVar(Decl);
|
||||
DeclarationFragments SubHeading =
|
||||
DeclarationFragmentsBuilder::getSubHeading(Decl);
|
||||
|
||||
if (Decl->isStaticDataMember()) {
|
||||
SymbolReference Context;
|
||||
// getDeclContext() should return a RecordDecl since we
|
||||
@ -272,13 +274,14 @@ bool ExtractAPIVisitorBase<Derived>::VisitVarDecl(const VarDecl *Decl) {
|
||||
Context.Name = Record->getName();
|
||||
Context.USR = API.recordUSR(Record);
|
||||
auto Access = DeclarationFragmentsBuilder::getAccessControl(Decl);
|
||||
API.addStaticField(Name, USR, Loc, AvailabilitySet(Decl), Linkage, Comment,
|
||||
Declaration, SubHeading, Context, Access,
|
||||
isInSystemHeader(Decl));
|
||||
API.addStaticField(Name, USR, Loc, AvailabilityInfo::createFromDecl(Decl),
|
||||
Linkage, Comment, Declaration, SubHeading, Context,
|
||||
Access, isInSystemHeader(Decl));
|
||||
} else
|
||||
// Add the global variable record to the API set.
|
||||
API.addGlobalVar(Name, USR, Loc, AvailabilitySet(Decl), Linkage, Comment,
|
||||
Declaration, SubHeading, isInSystemHeader(Decl));
|
||||
API.addGlobalVar(Name, USR, Loc, AvailabilityInfo::createFromDecl(Decl),
|
||||
Linkage, Comment, Declaration, SubHeading,
|
||||
isInSystemHeader(Decl));
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -333,19 +336,19 @@ bool ExtractAPIVisitorBase<Derived>::VisitFunctionDecl(
|
||||
DeclarationFragmentsBuilder::getSubHeading(Decl);
|
||||
FunctionSignature Signature =
|
||||
DeclarationFragmentsBuilder::getFunctionSignature(Decl);
|
||||
|
||||
if (Decl->getTemplateSpecializationInfo())
|
||||
API.addGlobalFunctionTemplateSpecialization(
|
||||
Name, USR, Loc, AvailabilitySet(Decl), Linkage, Comment,
|
||||
Name, USR, Loc, AvailabilityInfo::createFromDecl(Decl), Linkage,
|
||||
Comment,
|
||||
DeclarationFragmentsBuilder::
|
||||
getFragmentsForFunctionTemplateSpecialization(Decl),
|
||||
SubHeading, Signature, isInSystemHeader(Decl));
|
||||
else
|
||||
// Add the function record to the API set.
|
||||
API.addGlobalFunction(
|
||||
Name, USR, Loc, AvailabilitySet(Decl), Linkage, Comment,
|
||||
DeclarationFragmentsBuilder::getFragmentsForFunction(Decl), SubHeading,
|
||||
Signature, isInSystemHeader(Decl));
|
||||
Name, USR, Loc, AvailabilityInfo::createFromDecl(Decl), Linkage,
|
||||
Comment, DeclarationFragmentsBuilder::getFragmentsForFunction(Decl),
|
||||
SubHeading, Signature, isInSystemHeader(Decl));
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -379,10 +382,9 @@ bool ExtractAPIVisitorBase<Derived>::VisitEnumDecl(const EnumDecl *Decl) {
|
||||
DeclarationFragmentsBuilder::getFragmentsForEnum(Decl);
|
||||
DeclarationFragments SubHeading =
|
||||
DeclarationFragmentsBuilder::getSubHeading(Decl);
|
||||
|
||||
EnumRecord *EnumRecord =
|
||||
API.addEnum(API.copyString(Name), USR, Loc, AvailabilitySet(Decl),
|
||||
Comment, Declaration, SubHeading, isInSystemHeader(Decl));
|
||||
EnumRecord *EnumRecord = API.addEnum(
|
||||
API.copyString(Name), USR, Loc, AvailabilityInfo::createFromDecl(Decl),
|
||||
Comment, Declaration, SubHeading, isInSystemHeader(Decl));
|
||||
|
||||
// Now collect information about the enumerators in this enum.
|
||||
getDerivedExtractAPIVisitor().recordEnumConstants(EnumRecord,
|
||||
@ -496,8 +498,9 @@ bool ExtractAPIVisitorBase<Derived>::VisitNamespaceDecl(
|
||||
DeclarationFragments SubHeading =
|
||||
DeclarationFragmentsBuilder::getSubHeading(Decl);
|
||||
APIRecord *Parent = determineParentRecord(Decl->getDeclContext());
|
||||
API.addNamespace(Parent, Name, USR, Loc, AvailabilitySet(Decl), Linkage,
|
||||
Comment, Declaration, SubHeading, isInSystemHeader(Decl));
|
||||
API.addNamespace(Parent, Name, USR, Loc,
|
||||
AvailabilityInfo::createFromDecl(Decl), Linkage, Comment,
|
||||
Declaration, SubHeading, isInSystemHeader(Decl));
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -524,17 +527,25 @@ bool ExtractAPIVisitorBase<Derived>::VisitRecordDecl(const RecordDecl *Decl) {
|
||||
|
||||
// Build declaration fragments and sub-heading for the struct.
|
||||
DeclarationFragments Declaration =
|
||||
DeclarationFragmentsBuilder::getFragmentsForStruct(Decl);
|
||||
DeclarationFragmentsBuilder::getFragmentsForRecordDecl(Decl);
|
||||
DeclarationFragments SubHeading =
|
||||
DeclarationFragmentsBuilder::getSubHeading(Decl);
|
||||
|
||||
StructRecord *StructRecord =
|
||||
API.addStruct(Name, USR, Loc, AvailabilitySet(Decl), Comment, Declaration,
|
||||
SubHeading, isInSystemHeader(Decl));
|
||||
auto RecordKind = APIRecord::RK_Struct;
|
||||
auto FieldRecordKind = APIRecord::RK_StructField;
|
||||
|
||||
if (Decl->isUnion()) {
|
||||
RecordKind = APIRecord::RK_Union;
|
||||
FieldRecordKind = APIRecord::RK_UnionField;
|
||||
}
|
||||
|
||||
RecordRecord *RecordRecord = API.addRecord(
|
||||
Name, USR, Loc, AvailabilityInfo::createFromDecl(Decl), Comment,
|
||||
Declaration, SubHeading, RecordKind, isInSystemHeader(Decl));
|
||||
|
||||
// Now collect information about the fields in this struct.
|
||||
getDerivedExtractAPIVisitor().recordStructFields(StructRecord,
|
||||
Decl->fields());
|
||||
getDerivedExtractAPIVisitor().recordRecordFields(
|
||||
RecordRecord, FieldRecordKind, Decl->fields());
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -578,13 +589,13 @@ bool ExtractAPIVisitorBase<Derived>::VisitCXXRecordDecl(
|
||||
DeclarationFragmentsBuilder::getFragmentsForRedeclarableTemplate(
|
||||
Decl->getDescribedClassTemplate()));
|
||||
CXXClassRecord = API.addClassTemplate(
|
||||
Parent, Name, USR, Loc, AvailabilitySet(Decl), Comment, Declaration,
|
||||
SubHeading, Template(Decl->getDescribedClassTemplate()), Access,
|
||||
isInSystemHeader(Decl));
|
||||
Parent, Name, USR, Loc, AvailabilityInfo::createFromDecl(Decl), Comment,
|
||||
Declaration, SubHeading, Template(Decl->getDescribedClassTemplate()),
|
||||
Access, isInSystemHeader(Decl));
|
||||
} else
|
||||
CXXClassRecord = API.addCXXClass(
|
||||
Parent, Name, USR, Loc, AvailabilitySet(Decl), Comment, Declaration,
|
||||
SubHeading, Kind, Access, isInSystemHeader(Decl));
|
||||
Parent, Name, USR, Loc, AvailabilityInfo::createFromDecl(Decl), Comment,
|
||||
Declaration, SubHeading, Kind, Access, isInSystemHeader(Decl));
|
||||
|
||||
CXXClassRecord->Bases = getBases(Decl);
|
||||
|
||||
@ -624,7 +635,7 @@ bool ExtractAPIVisitorBase<Derived>::VisitCXXMethodDecl(
|
||||
FunctionTemplateDecl *TemplateDecl = Decl->getDescribedFunctionTemplate();
|
||||
API.addCXXMethodTemplate(
|
||||
API.findRecordForUSR(ParentUSR), Decl->getName(), USR, Loc,
|
||||
AvailabilitySet(Decl), Comment,
|
||||
AvailabilityInfo::createFromDecl(Decl), Comment,
|
||||
DeclarationFragmentsBuilder::getFragmentsForFunctionTemplate(
|
||||
TemplateDecl),
|
||||
SubHeading, DeclarationFragmentsBuilder::getFunctionSignature(Decl),
|
||||
@ -632,24 +643,27 @@ bool ExtractAPIVisitorBase<Derived>::VisitCXXMethodDecl(
|
||||
Template(TemplateDecl), isInSystemHeader(Decl));
|
||||
} else if (Decl->getTemplateSpecializationInfo())
|
||||
API.addCXXMethodTemplateSpec(
|
||||
Parent, Decl->getName(), USR, Loc, AvailabilitySet(Decl), Comment,
|
||||
Parent, Decl->getName(), USR, Loc,
|
||||
AvailabilityInfo::createFromDecl(Decl), Comment,
|
||||
DeclarationFragmentsBuilder::
|
||||
getFragmentsForFunctionTemplateSpecialization(Decl),
|
||||
SubHeading, Signature, Access, isInSystemHeader(Decl));
|
||||
else if (Decl->isOverloadedOperator())
|
||||
API.addCXXInstanceMethod(
|
||||
Parent, API.copyString(Decl->getNameAsString()), USR, Loc,
|
||||
AvailabilitySet(Decl), Comment,
|
||||
AvailabilityInfo::createFromDecl(Decl), Comment,
|
||||
DeclarationFragmentsBuilder::getFragmentsForOverloadedOperator(Decl),
|
||||
SubHeading, Signature, Access, isInSystemHeader(Decl));
|
||||
else if (Decl->isStatic())
|
||||
API.addCXXStaticMethod(
|
||||
Parent, Decl->getName(), USR, Loc, AvailabilitySet(Decl), Comment,
|
||||
Parent, Decl->getName(), USR, Loc,
|
||||
AvailabilityInfo::createFromDecl(Decl), Comment,
|
||||
DeclarationFragmentsBuilder::getFragmentsForCXXMethod(Decl), SubHeading,
|
||||
Signature, Access, isInSystemHeader(Decl));
|
||||
else
|
||||
API.addCXXInstanceMethod(
|
||||
Parent, Decl->getName(), USR, Loc, AvailabilitySet(Decl), Comment,
|
||||
Parent, Decl->getName(), USR, Loc,
|
||||
AvailabilityInfo::createFromDecl(Decl), Comment,
|
||||
DeclarationFragmentsBuilder::getFragmentsForCXXMethod(Decl), SubHeading,
|
||||
Signature, Access, isInSystemHeader(Decl));
|
||||
|
||||
@ -678,13 +692,12 @@ bool ExtractAPIVisitorBase<Derived>::VisitCXXConstructorDecl(
|
||||
FunctionSignature Signature =
|
||||
DeclarationFragmentsBuilder::getFunctionSignature(Decl);
|
||||
AccessControl Access = DeclarationFragmentsBuilder::getAccessControl(Decl);
|
||||
|
||||
SmallString<128> ParentUSR;
|
||||
index::generateUSRForDecl(dyn_cast<CXXRecordDecl>(Decl->getDeclContext()),
|
||||
ParentUSR);
|
||||
API.addCXXInstanceMethod(API.findRecordForUSR(ParentUSR), Name, USR, Loc,
|
||||
AvailabilitySet(Decl), Comment, Declaration,
|
||||
SubHeading, Signature, Access,
|
||||
AvailabilityInfo::createFromDecl(Decl), Comment,
|
||||
Declaration, SubHeading, Signature, Access,
|
||||
isInSystemHeader(Decl));
|
||||
return true;
|
||||
}
|
||||
@ -711,13 +724,12 @@ bool ExtractAPIVisitorBase<Derived>::VisitCXXDestructorDecl(
|
||||
FunctionSignature Signature =
|
||||
DeclarationFragmentsBuilder::getFunctionSignature(Decl);
|
||||
AccessControl Access = DeclarationFragmentsBuilder::getAccessControl(Decl);
|
||||
|
||||
SmallString<128> ParentUSR;
|
||||
index::generateUSRForDecl(dyn_cast<CXXRecordDecl>(Decl->getDeclContext()),
|
||||
ParentUSR);
|
||||
API.addCXXInstanceMethod(API.findRecordForUSR(ParentUSR), Name, USR, Loc,
|
||||
AvailabilitySet(Decl), Comment, Declaration,
|
||||
SubHeading, Signature, Access,
|
||||
AvailabilityInfo::createFromDecl(Decl), Comment,
|
||||
Declaration, SubHeading, Signature, Access,
|
||||
isInSystemHeader(Decl));
|
||||
return true;
|
||||
}
|
||||
@ -740,8 +752,9 @@ bool ExtractAPIVisitorBase<Derived>::VisitConceptDecl(const ConceptDecl *Decl) {
|
||||
DeclarationFragmentsBuilder::getFragmentsForConcept(Decl);
|
||||
DeclarationFragments SubHeading =
|
||||
DeclarationFragmentsBuilder::getSubHeading(Decl);
|
||||
API.addConcept(Name, USR, Loc, AvailabilitySet(Decl), Comment, Declaration,
|
||||
SubHeading, Template(Decl), isInSystemHeader(Decl));
|
||||
API.addConcept(Name, USR, Loc, AvailabilityInfo::createFromDecl(Decl),
|
||||
Comment, Declaration, SubHeading, Template(Decl),
|
||||
isInSystemHeader(Decl));
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -768,8 +781,9 @@ bool ExtractAPIVisitorBase<Derived>::VisitClassTemplateSpecializationDecl(
|
||||
|
||||
APIRecord *Parent = determineParentRecord(Decl->getDeclContext());
|
||||
auto *ClassTemplateSpecializationRecord = API.addClassTemplateSpecialization(
|
||||
Parent, Name, USR, Loc, AvailabilitySet(Decl), Comment, Declaration,
|
||||
SubHeading, DeclarationFragmentsBuilder::getAccessControl(Decl),
|
||||
Parent, Name, USR, Loc, AvailabilityInfo::createFromDecl(Decl), Comment,
|
||||
Declaration, SubHeading,
|
||||
DeclarationFragmentsBuilder::getAccessControl(Decl),
|
||||
isInSystemHeader(Decl));
|
||||
|
||||
ClassTemplateSpecializationRecord->Bases = getBases(Decl);
|
||||
@ -797,12 +811,11 @@ bool ExtractAPIVisitorBase<Derived>::
|
||||
getFragmentsForClassTemplatePartialSpecialization(Decl);
|
||||
DeclarationFragments SubHeading =
|
||||
DeclarationFragmentsBuilder::getSubHeading(Decl);
|
||||
|
||||
APIRecord *Parent = determineParentRecord(Decl->getDeclContext());
|
||||
auto *ClassTemplatePartialSpecRecord =
|
||||
API.addClassTemplatePartialSpecialization(
|
||||
Parent, Name, USR, Loc, AvailabilitySet(Decl), Comment, Declaration,
|
||||
SubHeading, Template(Decl),
|
||||
Parent, Name, USR, Loc, AvailabilityInfo::createFromDecl(Decl),
|
||||
Comment, Declaration, SubHeading, Template(Decl),
|
||||
DeclarationFragmentsBuilder::getAccessControl(Decl),
|
||||
isInSystemHeader(Decl));
|
||||
|
||||
@ -845,12 +858,13 @@ bool ExtractAPIVisitorBase<Derived>::VisitVarTemplateDecl(
|
||||
ParentUSR);
|
||||
if (Decl->getDeclContext()->getDeclKind() == Decl::CXXRecord)
|
||||
API.addCXXFieldTemplate(API.findRecordForUSR(ParentUSR), Name, USR, Loc,
|
||||
AvailabilitySet(Decl), Comment, Declaration,
|
||||
SubHeading,
|
||||
AvailabilityInfo::createFromDecl(Decl), Comment,
|
||||
Declaration, SubHeading,
|
||||
DeclarationFragmentsBuilder::getAccessControl(Decl),
|
||||
Template(Decl), isInSystemHeader(Decl));
|
||||
else
|
||||
API.addGlobalVariableTemplate(Name, USR, Loc, AvailabilitySet(Decl),
|
||||
API.addGlobalVariableTemplate(Name, USR, Loc,
|
||||
AvailabilityInfo::createFromDecl(Decl),
|
||||
Linkage, Comment, Declaration, SubHeading,
|
||||
Template(Decl), isInSystemHeader(Decl));
|
||||
return true;
|
||||
@ -880,10 +894,9 @@ bool ExtractAPIVisitorBase<Derived>::VisitVarTemplateSpecializationDecl(
|
||||
Decl);
|
||||
DeclarationFragments SubHeading =
|
||||
DeclarationFragmentsBuilder::getSubHeading(Decl);
|
||||
|
||||
API.addGlobalVariableTemplateSpecialization(
|
||||
Name, USR, Loc, AvailabilitySet(Decl), Linkage, Comment, Declaration,
|
||||
SubHeading, isInSystemHeader(Decl));
|
||||
Name, USR, Loc, AvailabilityInfo::createFromDecl(Decl), Linkage, Comment,
|
||||
Declaration, SubHeading, isInSystemHeader(Decl));
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -910,10 +923,9 @@ bool ExtractAPIVisitorBase<Derived>::VisitVarTemplatePartialSpecializationDecl(
|
||||
getFragmentsForVarTemplatePartialSpecialization(Decl);
|
||||
DeclarationFragments SubHeading =
|
||||
DeclarationFragmentsBuilder::getSubHeading(Decl);
|
||||
|
||||
API.addGlobalVariableTemplatePartialSpecialization(
|
||||
Name, USR, Loc, AvailabilitySet(Decl), Linkage, Comment, Declaration,
|
||||
SubHeading, Template(Decl), isInSystemHeader(Decl));
|
||||
Name, USR, Loc, AvailabilityInfo::createFromDecl(Decl), Linkage, Comment,
|
||||
Declaration, SubHeading, Template(Decl), isInSystemHeader(Decl));
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -942,9 +954,8 @@ bool ExtractAPIVisitorBase<Derived>::VisitFunctionTemplateDecl(
|
||||
FunctionSignature Signature =
|
||||
DeclarationFragmentsBuilder::getFunctionSignature(
|
||||
Decl->getTemplatedDecl());
|
||||
|
||||
API.addGlobalFunctionTemplate(
|
||||
Name, USR, Loc, AvailabilitySet(Decl), Linkage, Comment,
|
||||
Name, USR, Loc, AvailabilityInfo::createFromDecl(Decl), Linkage, Comment,
|
||||
DeclarationFragmentsBuilder::getFragmentsForFunctionTemplate(Decl),
|
||||
SubHeading, Signature, Template(Decl), isInSystemHeader(Decl));
|
||||
|
||||
@ -983,8 +994,8 @@ bool ExtractAPIVisitorBase<Derived>::VisitObjCInterfaceDecl(
|
||||
}
|
||||
|
||||
ObjCInterfaceRecord *ObjCInterfaceRecord = API.addObjCInterface(
|
||||
Name, USR, Loc, AvailabilitySet(Decl), Linkage, Comment, Declaration,
|
||||
SubHeading, SuperClass, isInSystemHeader(Decl));
|
||||
Name, USR, Loc, AvailabilityInfo::createFromDecl(Decl), Linkage, Comment,
|
||||
Declaration, SubHeading, SuperClass, isInSystemHeader(Decl));
|
||||
|
||||
// Record all methods (selectors). This doesn't include automatically
|
||||
// synthesized property methods.
|
||||
@ -1023,9 +1034,9 @@ bool ExtractAPIVisitorBase<Derived>::VisitObjCProtocolDecl(
|
||||
DeclarationFragments SubHeading =
|
||||
DeclarationFragmentsBuilder::getSubHeading(Decl);
|
||||
|
||||
ObjCProtocolRecord *ObjCProtocolRecord =
|
||||
API.addObjCProtocol(Name, USR, Loc, AvailabilitySet(Decl), Comment,
|
||||
Declaration, SubHeading, isInSystemHeader(Decl));
|
||||
ObjCProtocolRecord *ObjCProtocolRecord = API.addObjCProtocol(
|
||||
Name, USR, Loc, AvailabilityInfo::createFromDecl(Decl), Comment,
|
||||
Declaration, SubHeading, isInSystemHeader(Decl));
|
||||
|
||||
getDerivedExtractAPIVisitor().recordObjCMethods(ObjCProtocolRecord,
|
||||
Decl->methods());
|
||||
@ -1055,8 +1066,8 @@ bool ExtractAPIVisitorBase<Derived>::VisitTypedefNameDecl(
|
||||
dyn_cast<ElaboratedType>(Decl->getUnderlyingType())) {
|
||||
if (const TagType *TagTy = dyn_cast<TagType>(ET->desugar())) {
|
||||
if (Decl->getName() == TagTy->getDecl()->getName()) {
|
||||
if (TagTy->getDecl()->isStruct()) {
|
||||
modifyRecords(API.getStructs(), Decl->getName());
|
||||
if (isa<RecordDecl>(TagTy->getDecl())) {
|
||||
modifyRecords(API.getRecords(), Decl->getName());
|
||||
}
|
||||
if (TagTy->getDecl()->isEnum()) {
|
||||
modifyRecords(API.getEnums(), Decl->getName());
|
||||
@ -1080,7 +1091,8 @@ bool ExtractAPIVisitorBase<Derived>::VisitTypedefNameDecl(
|
||||
TypedefUnderlyingTypeResolver(Context).getSymbolReferenceForType(Type,
|
||||
API);
|
||||
|
||||
API.addTypedef(Name, USR, Loc, AvailabilitySet(Decl), Comment,
|
||||
API.addTypedef(Name, USR, Loc, AvailabilityInfo::createFromDecl(Decl),
|
||||
Comment,
|
||||
DeclarationFragmentsBuilder::getFragmentsForTypedef(Decl),
|
||||
DeclarationFragmentsBuilder::getSubHeading(Decl), SymRef,
|
||||
isInSystemHeader(Decl));
|
||||
@ -1122,8 +1134,9 @@ bool ExtractAPIVisitorBase<Derived>::VisitObjCCategoryDecl(
|
||||
}
|
||||
|
||||
ObjCCategoryRecord *ObjCCategoryRecord = API.addObjCCategory(
|
||||
Name, USR, Loc, AvailabilitySet(Decl), Comment, Declaration, SubHeading,
|
||||
Interface, isInSystemHeader(Decl), IsFromExternalModule);
|
||||
Name, USR, Loc, AvailabilityInfo::createFromDecl(Decl), Comment,
|
||||
Declaration, SubHeading, Interface, isInSystemHeader(Decl),
|
||||
IsFromExternalModule);
|
||||
|
||||
getDerivedExtractAPIVisitor().recordObjCMethods(ObjCCategoryRecord,
|
||||
Decl->methods());
|
||||
@ -1160,17 +1173,18 @@ void ExtractAPIVisitorBase<Derived>::recordEnumConstants(
|
||||
DeclarationFragments SubHeading =
|
||||
DeclarationFragmentsBuilder::getSubHeading(Constant);
|
||||
|
||||
API.addEnumConstant(EnumRecord, Name, USR, Loc, AvailabilitySet(Constant),
|
||||
Comment, Declaration, SubHeading,
|
||||
isInSystemHeader(Constant));
|
||||
API.addEnumConstant(EnumRecord, Name, USR, Loc,
|
||||
AvailabilityInfo::createFromDecl(Constant), Comment,
|
||||
Declaration, SubHeading, isInSystemHeader(Constant));
|
||||
}
|
||||
}
|
||||
|
||||
/// Collect API information for the struct fields and associate with the
|
||||
/// parent struct.
|
||||
template <typename Derived>
|
||||
void ExtractAPIVisitorBase<Derived>::recordStructFields(
|
||||
StructRecord *StructRecord, const RecordDecl::field_range Fields) {
|
||||
void ExtractAPIVisitorBase<Derived>::recordRecordFields(
|
||||
RecordRecord *RecordRecord, APIRecord::RecordKind FieldKind,
|
||||
const RecordDecl::field_range Fields) {
|
||||
for (const auto *Field : Fields) {
|
||||
// Collect symbol information.
|
||||
StringRef Name = Field->getName();
|
||||
@ -1189,9 +1203,9 @@ void ExtractAPIVisitorBase<Derived>::recordStructFields(
|
||||
DeclarationFragments SubHeading =
|
||||
DeclarationFragmentsBuilder::getSubHeading(Field);
|
||||
|
||||
API.addStructField(StructRecord, Name, USR, Loc, AvailabilitySet(Field),
|
||||
Comment, Declaration, SubHeading,
|
||||
isInSystemHeader(Field));
|
||||
API.addRecordField(
|
||||
RecordRecord, Name, USR, Loc, AvailabilityInfo::createFromDecl(Field),
|
||||
Comment, Declaration, SubHeading, FieldKind, isInSystemHeader(Field));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1223,8 +1237,8 @@ bool ExtractAPIVisitorBase<Derived>::VisitFieldDecl(const FieldDecl *Decl) {
|
||||
index::generateUSRForDecl(dyn_cast<CXXRecordDecl>(Decl->getDeclContext()),
|
||||
ParentUSR);
|
||||
API.addCXXField(API.findRecordForUSR(ParentUSR), Name, USR, Loc,
|
||||
AvailabilitySet(Decl), Comment, Declaration, SubHeading,
|
||||
Access, isInSystemHeader(Decl));
|
||||
AvailabilityInfo::createFromDecl(Decl), Comment, Declaration,
|
||||
SubHeading, Access, isInSystemHeader(Decl));
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1255,13 +1269,13 @@ bool ExtractAPIVisitorBase<Derived>::VisitCXXConversionDecl(
|
||||
ParentUSR);
|
||||
if (Decl->isStatic())
|
||||
API.addCXXStaticMethod(API.findRecordForUSR(ParentUSR), Name, USR, Loc,
|
||||
AvailabilitySet(Decl), Comment, Declaration,
|
||||
SubHeading, Signature, Access,
|
||||
AvailabilityInfo::createFromDecl(Decl), Comment,
|
||||
Declaration, SubHeading, Signature, Access,
|
||||
isInSystemHeader(Decl));
|
||||
else
|
||||
API.addCXXInstanceMethod(API.findRecordForUSR(ParentUSR), Name, USR, Loc,
|
||||
AvailabilitySet(Decl), Comment, Declaration,
|
||||
SubHeading, Signature, Access,
|
||||
AvailabilityInfo::createFromDecl(Decl), Comment,
|
||||
Declaration, SubHeading, Signature, Access,
|
||||
isInSystemHeader(Decl));
|
||||
return true;
|
||||
}
|
||||
@ -1295,8 +1309,9 @@ void ExtractAPIVisitorBase<Derived>::recordObjCMethods(
|
||||
FunctionSignature Signature =
|
||||
DeclarationFragmentsBuilder::getFunctionSignature(Method);
|
||||
|
||||
API.addObjCMethod(Container, Name, USR, Loc, AvailabilitySet(Method),
|
||||
Comment, Declaration, SubHeading, Signature,
|
||||
API.addObjCMethod(Container, Name, USR, Loc,
|
||||
AvailabilityInfo::createFromDecl(Method), Comment,
|
||||
Declaration, SubHeading, Signature,
|
||||
Method->isInstanceMethod(), isInSystemHeader(Method));
|
||||
}
|
||||
}
|
||||
@ -1334,8 +1349,8 @@ void ExtractAPIVisitorBase<Derived>::recordObjCProperties(
|
||||
Attributes |= ObjCPropertyRecord::ReadOnly;
|
||||
|
||||
API.addObjCProperty(
|
||||
Container, Name, USR, Loc, AvailabilitySet(Property), Comment,
|
||||
Declaration, SubHeading,
|
||||
Container, Name, USR, Loc, AvailabilityInfo::createFromDecl(Property),
|
||||
Comment, Declaration, SubHeading,
|
||||
static_cast<ObjCPropertyRecord::AttributeKind>(Attributes), GetterName,
|
||||
SetterName, Property->isOptional(),
|
||||
!(Property->getPropertyAttributes() &
|
||||
@ -1370,9 +1385,9 @@ void ExtractAPIVisitorBase<Derived>::recordObjCInstanceVariables(
|
||||
ObjCInstanceVariableRecord::AccessControl Access =
|
||||
Ivar->getCanonicalAccessControl();
|
||||
|
||||
API.addObjCInstanceVariable(Container, Name, USR, Loc,
|
||||
AvailabilitySet(Ivar), Comment, Declaration,
|
||||
SubHeading, Access, isInSystemHeader(Ivar));
|
||||
API.addObjCInstanceVariable(
|
||||
Container, Name, USR, Loc, AvailabilityInfo::createFromDecl(Ivar),
|
||||
Comment, Declaration, SubHeading, Access, isInSystemHeader(Ivar));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -65,7 +65,7 @@ public:
|
||||
|
||||
getDerived()->traverseGlobalFunctionTemplateSpecializationRecords();
|
||||
|
||||
getDerived()->traverseStructRecords();
|
||||
getDerived()->traverseRecordRecords();
|
||||
|
||||
getDerived()->traverseObjCInterfaces();
|
||||
|
||||
@ -98,9 +98,9 @@ public:
|
||||
getDerived()->visitEnumRecord(*Enum.second);
|
||||
}
|
||||
|
||||
void traverseStructRecords() {
|
||||
for (const auto &Struct : API.getStructs())
|
||||
getDerived()->visitStructRecord(*Struct.second);
|
||||
void traverseRecordRecords() {
|
||||
for (const auto &Record : API.getRecords())
|
||||
getDerived()->visitRecordRecord(*Record.second);
|
||||
}
|
||||
|
||||
void traverseStaticFieldRecords() {
|
||||
@ -238,8 +238,8 @@ public:
|
||||
/// Visit an enum record.
|
||||
void visitEnumRecord(const EnumRecord &Record){};
|
||||
|
||||
/// Visit a struct record.
|
||||
void visitStructRecord(const StructRecord &Record){};
|
||||
/// Visit a record record.
|
||||
void visitRecordRecord(const RecordRecord &Record){};
|
||||
|
||||
void visitStaticFieldRecord(const StaticFieldRecord &Record){};
|
||||
|
||||
|
@ -170,8 +170,8 @@ public:
|
||||
/// Visit an enum record.
|
||||
void visitEnumRecord(const EnumRecord &Record);
|
||||
|
||||
/// Visit a struct record.
|
||||
void visitStructRecord(const StructRecord &Record);
|
||||
/// Visit a record record.
|
||||
void visitRecordRecord(const RecordRecord &Record);
|
||||
|
||||
void visitStaticFieldRecord(const StaticFieldRecord &Record);
|
||||
|
||||
|
@ -3055,6 +3055,7 @@ struct FormatStyle {
|
||||
bool isProto() const {
|
||||
return Language == LK_Proto || Language == LK_TextProto;
|
||||
}
|
||||
bool isTableGen() const { return Language == LK_TableGen; }
|
||||
|
||||
/// Language, this format style is targeted at.
|
||||
/// \version 3.5
|
||||
@ -3397,6 +3398,10 @@ struct FormatStyle {
|
||||
/// \version 14
|
||||
unsigned PenaltyBreakOpenParenthesis;
|
||||
|
||||
/// The penalty for breaking after ``::``.
|
||||
/// \version 18
|
||||
unsigned PenaltyBreakScopeResolution;
|
||||
|
||||
/// The penalty for each line break introduced inside a string literal.
|
||||
/// \version 3.7
|
||||
unsigned PenaltyBreakString;
|
||||
@ -3927,6 +3932,10 @@ struct FormatStyle {
|
||||
/// \version 13
|
||||
unsigned ShortNamespaceLines;
|
||||
|
||||
/// Do not format macro definition body.
|
||||
/// \version 18
|
||||
bool SkipMacroDefinitionBody;
|
||||
|
||||
/// Include sorting options.
|
||||
enum SortIncludesOptions : int8_t {
|
||||
/// Includes are never sorted.
|
||||
@ -4872,6 +4881,7 @@ struct FormatStyle {
|
||||
PenaltyBreakComment == R.PenaltyBreakComment &&
|
||||
PenaltyBreakFirstLessLess == R.PenaltyBreakFirstLessLess &&
|
||||
PenaltyBreakOpenParenthesis == R.PenaltyBreakOpenParenthesis &&
|
||||
PenaltyBreakScopeResolution == R.PenaltyBreakScopeResolution &&
|
||||
PenaltyBreakString == R.PenaltyBreakString &&
|
||||
PenaltyBreakTemplateDeclaration ==
|
||||
R.PenaltyBreakTemplateDeclaration &&
|
||||
@ -4889,6 +4899,7 @@ struct FormatStyle {
|
||||
RequiresExpressionIndentation == R.RequiresExpressionIndentation &&
|
||||
SeparateDefinitionBlocks == R.SeparateDefinitionBlocks &&
|
||||
ShortNamespaceLines == R.ShortNamespaceLines &&
|
||||
SkipMacroDefinitionBody == R.SkipMacroDefinitionBody &&
|
||||
SortIncludes == R.SortIncludes &&
|
||||
SortJavaStaticImport == R.SortJavaStaticImport &&
|
||||
SpaceAfterCStyleCast == R.SpaceAfterCStyleCast &&
|
||||
|
@ -902,7 +902,7 @@ public:
|
||||
SourceManager &SourceMgr, FileManager &FileMgr,
|
||||
SmallVectorImpl<StoredDiagnostic> &StoredDiagnostics,
|
||||
SmallVectorImpl<const llvm::MemoryBuffer *> &OwnedBuffers,
|
||||
std::unique_ptr<SyntaxOnlyAction> Act = nullptr);
|
||||
std::unique_ptr<SyntaxOnlyAction> Act);
|
||||
|
||||
/// Save this translation unit to a file with the given name.
|
||||
///
|
||||
|
@ -43,12 +43,14 @@ class PCHContainerReader;
|
||||
class Preprocessor;
|
||||
class PreprocessorOptions;
|
||||
class PreprocessorOutputOptions;
|
||||
class CodeGenOptions;
|
||||
|
||||
/// InitializePreprocessor - Initialize the preprocessor getting it and the
|
||||
/// environment ready to process a single file.
|
||||
void InitializePreprocessor(Preprocessor &PP, const PreprocessorOptions &PPOpts,
|
||||
const PCHContainerReader &PCHContainerRdr,
|
||||
const FrontendOptions &FEOpts);
|
||||
const FrontendOptions &FEOpts,
|
||||
const CodeGenOptions &CodeGenOpts);
|
||||
|
||||
/// DoPrintPreprocessedInput - Implement -E mode.
|
||||
void DoPrintPreprocessedInput(Preprocessor &PP, raw_ostream *OS,
|
||||
|
@ -129,7 +129,7 @@ public:
|
||||
llvm::Expected<llvm::orc::ExecutorAddr>
|
||||
getSymbolAddressFromLinkerName(llvm::StringRef LinkerName) const;
|
||||
|
||||
enum InterfaceKind { NoAlloc, WithAlloc, CopyArray };
|
||||
enum InterfaceKind { NoAlloc, WithAlloc, CopyArray, NewTag };
|
||||
|
||||
const llvm::SmallVectorImpl<Expr *> &getValuePrintingInfo() const {
|
||||
return ValuePrintingInfo;
|
||||
@ -144,7 +144,7 @@ private:
|
||||
|
||||
llvm::DenseMap<CXXRecordDecl *, llvm::orc::ExecutorAddr> Dtors;
|
||||
|
||||
llvm::SmallVector<Expr *, 3> ValuePrintingInfo;
|
||||
llvm::SmallVector<Expr *, 4> ValuePrintingInfo;
|
||||
};
|
||||
} // namespace clang
|
||||
|
||||
|
@ -198,11 +198,11 @@ public:
|
||||
/// from. Currently this is only used by _Pragma handling.
|
||||
SourceLocation getFileLoc() const { return FileLoc; }
|
||||
|
||||
private:
|
||||
/// Lex - Return the next token in the file. If this is the end of file, it
|
||||
/// return the tok::eof token. This implicitly involves the preprocessor.
|
||||
bool Lex(Token &Result);
|
||||
|
||||
private:
|
||||
/// Called when the preprocessor is in 'dependency scanning lexing mode'.
|
||||
bool LexDependencyDirectiveToken(Token &Result);
|
||||
|
||||
|
@ -2829,12 +2829,20 @@ public:
|
||||
}
|
||||
|
||||
void emitMacroExpansionWarnings(const Token &Identifier) const {
|
||||
if (Identifier.getIdentifierInfo()->isDeprecatedMacro())
|
||||
IdentifierInfo *Info = Identifier.getIdentifierInfo();
|
||||
if (Info->isDeprecatedMacro())
|
||||
emitMacroDeprecationWarning(Identifier);
|
||||
|
||||
if (Identifier.getIdentifierInfo()->isRestrictExpansion() &&
|
||||
if (Info->isRestrictExpansion() &&
|
||||
!SourceMgr.isInMainFile(Identifier.getLocation()))
|
||||
emitRestrictExpansionWarning(Identifier);
|
||||
|
||||
if (Info->getName() == "INFINITY")
|
||||
if (getLangOpts().NoHonorInfs)
|
||||
emitRestrictInfNaNWarning(Identifier, 0);
|
||||
if (Info->getName() == "NAN")
|
||||
if (getLangOpts().NoHonorNaNs)
|
||||
emitRestrictInfNaNWarning(Identifier, 1);
|
||||
}
|
||||
|
||||
static void processPathForFileMacro(SmallVectorImpl<char> &Path,
|
||||
@ -2850,6 +2858,8 @@ private:
|
||||
void emitMacroDeprecationWarning(const Token &Identifier) const;
|
||||
void emitRestrictExpansionWarning(const Token &Identifier) const;
|
||||
void emitFinalMacroWarning(const Token &Identifier, bool IsUndef) const;
|
||||
void emitRestrictInfNaNWarning(const Token &Identifier,
|
||||
unsigned DiagSelection) const;
|
||||
|
||||
/// This boolean state keeps track if the current scanned token (by this PP)
|
||||
/// is in an "-Wunsafe-buffer-usage" opt-out region. Assuming PP scans a
|
||||
|
@ -13,6 +13,7 @@
|
||||
#ifndef LLVM_CLANG_PARSE_PARSER_H
|
||||
#define LLVM_CLANG_PARSE_PARSER_H
|
||||
|
||||
#include "clang/Basic/OpenACCKinds.h"
|
||||
#include "clang/Basic/OperatorPrecedence.h"
|
||||
#include "clang/Lex/CodeCompletionHandler.h"
|
||||
#include "clang/Lex/Preprocessor.h"
|
||||
@ -3568,7 +3569,26 @@ private:
|
||||
void ParseOpenACCCacheVarList();
|
||||
/// Parses a single variable in a variable list for OpenACC.
|
||||
bool ParseOpenACCVar();
|
||||
/// Parses the variable list for the variety of clauses that take a var-list,
|
||||
/// including the optional Special Token listed for some,based on clause type.
|
||||
bool ParseOpenACCClauseVarList(OpenACCClauseKind Kind);
|
||||
/// Parses any parameters for an OpenACC Clause, including required/optional
|
||||
/// parens.
|
||||
bool ParseOpenACCClauseParams(OpenACCDirectiveKind DirKind,
|
||||
OpenACCClauseKind Kind);
|
||||
/// Parses a single clause in a clause-list for OpenACC.
|
||||
bool ParseOpenACCClause(OpenACCDirectiveKind DirKind);
|
||||
/// Parses the clause-list for an OpenACC directive.
|
||||
void ParseOpenACCClauseList(OpenACCDirectiveKind DirKind);
|
||||
bool ParseOpenACCWaitArgument();
|
||||
/// Parses the clause of the 'bind' argument, which can be a string literal or
|
||||
/// an ID expression.
|
||||
ExprResult ParseOpenACCBindClauseArgument();
|
||||
/// Parses the clause kind of 'int-expr', which can be any integral
|
||||
/// expression.
|
||||
ExprResult ParseOpenACCIntExpr();
|
||||
/// Parses the 'device-type-list', which is a list of identifiers.
|
||||
bool ParseOpenACCDeviceTypeList();
|
||||
|
||||
private:
|
||||
//===--------------------------------------------------------------------===//
|
||||
@ -3644,6 +3664,18 @@ private:
|
||||
ParseConceptDefinition(const ParsedTemplateInfo &TemplateInfo,
|
||||
SourceLocation &DeclEnd);
|
||||
|
||||
/// Parse the given string as a type.
|
||||
///
|
||||
/// This is a dangerous utility function currently employed only by API notes.
|
||||
/// It is not a general entry-point for safely parsing types from strings.
|
||||
///
|
||||
/// \param TypeStr The string to be parsed as a type.
|
||||
/// \param Context The name of the context in which this string is being
|
||||
/// parsed, which will be used in diagnostics.
|
||||
/// \param IncludeLoc The location at which this parse was triggered.
|
||||
TypeResult ParseTypeFromString(StringRef TypeStr, StringRef Context,
|
||||
SourceLocation IncludeLoc);
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Modules
|
||||
DeclGroupPtrTy ParseModuleDecl(Sema::ModuleImportState &ImportState);
|
||||
|
@ -66,7 +66,7 @@ namespace sema {
|
||||
/// parsed.
|
||||
class CompoundScopeInfo {
|
||||
public:
|
||||
/// Whether this compound stamement contains `for' or `while' loops
|
||||
/// Whether this compound statement contains `for' or `while' loops
|
||||
/// with empty bodies.
|
||||
bool HasEmptyLoopBodies = false;
|
||||
|
||||
@ -168,7 +168,7 @@ public:
|
||||
/// to build, the initial and final coroutine suspend points
|
||||
bool NeedsCoroutineSuspends : 1;
|
||||
|
||||
/// An enumeration represeting the kind of the first coroutine statement
|
||||
/// An enumeration representing the kind of the first coroutine statement
|
||||
/// in the function. One of co_return, co_await, or co_yield.
|
||||
unsigned char FirstCoroutineStmtKind : 2;
|
||||
|
||||
@ -220,7 +220,7 @@ public:
|
||||
/// The initial and final coroutine suspend points.
|
||||
std::pair<Stmt *, Stmt *> CoroutineSuspends;
|
||||
|
||||
/// The stack of currently active compound stamement scopes in the
|
||||
/// The stack of currently active compound statement scopes in the
|
||||
/// function.
|
||||
SmallVector<CompoundScopeInfo, 4> CompoundScopes;
|
||||
|
||||
|
@ -955,6 +955,10 @@ public:
|
||||
OpaqueParser = P;
|
||||
}
|
||||
|
||||
/// Callback to the parser to parse a type expressed as a string.
|
||||
std::function<TypeResult(StringRef, StringRef, SourceLocation)>
|
||||
ParseTypeFromStringCallback;
|
||||
|
||||
class DelayedDiagnostics;
|
||||
|
||||
class DelayedDiagnosticsState {
|
||||
@ -2108,6 +2112,10 @@ public:
|
||||
|
||||
bool CheckFunctionReturnType(QualType T, SourceLocation Loc);
|
||||
|
||||
/// Check an argument list for placeholders that we won't try to
|
||||
/// handle later.
|
||||
bool CheckArgsForPlaceholders(MultiExprArg args);
|
||||
|
||||
/// Build a function type.
|
||||
///
|
||||
/// This routine checks the function type according to C++ rules and
|
||||
@ -2153,7 +2161,7 @@ public:
|
||||
SourceLocation Loc);
|
||||
QualType BuildBitIntType(bool IsUnsigned, Expr *BitWidth, SourceLocation Loc);
|
||||
|
||||
TypeSourceInfo *GetTypeForDeclarator(Declarator &D, Scope *S);
|
||||
TypeSourceInfo *GetTypeForDeclarator(Declarator &D);
|
||||
TypeSourceInfo *GetTypeForDeclaratorCast(Declarator &D, QualType FromTy);
|
||||
|
||||
/// Package the given type and TSI into a ParsedType.
|
||||
@ -2194,7 +2202,7 @@ public:
|
||||
SourceLocation TargetLoc, const FunctionProtoType *Source,
|
||||
bool SkipSourceFirstParameter, SourceLocation SourceLoc);
|
||||
|
||||
TypeResult ActOnTypeName(Scope *S, Declarator &D);
|
||||
TypeResult ActOnTypeName(Declarator &D);
|
||||
|
||||
/// The parser has parsed the context-sensitive type 'instancetype'
|
||||
/// in an Objective-C message declaration. Return the appropriate type.
|
||||
@ -3017,6 +3025,9 @@ public:
|
||||
ParmVarDecl *BuildParmVarDeclForTypedef(DeclContext *DC,
|
||||
SourceLocation Loc,
|
||||
QualType T);
|
||||
QualType AdjustParameterTypeForObjCAutoRefCount(QualType T,
|
||||
SourceLocation NameLoc,
|
||||
TypeSourceInfo *TSInfo);
|
||||
ParmVarDecl *CheckParameter(DeclContext *DC, SourceLocation StartLoc,
|
||||
SourceLocation NameLoc, IdentifierInfo *Name,
|
||||
QualType T, TypeSourceInfo *TSInfo,
|
||||
@ -4816,6 +4827,29 @@ public:
|
||||
/// Valid types should not have multiple attributes with different CCs.
|
||||
const AttributedType *getCallingConvAttributedType(QualType T) const;
|
||||
|
||||
/// Check whether a nullability type specifier can be added to the given
|
||||
/// type through some means not written in source (e.g. API notes).
|
||||
///
|
||||
/// \param Type The type to which the nullability specifier will be
|
||||
/// added. On success, this type will be updated appropriately.
|
||||
///
|
||||
/// \param Nullability The nullability specifier to add.
|
||||
///
|
||||
/// \param DiagLoc The location to use for diagnostics.
|
||||
///
|
||||
/// \param AllowArrayTypes Whether to accept nullability specifiers on an
|
||||
/// array type (e.g., because it will decay to a pointer).
|
||||
///
|
||||
/// \param OverrideExisting Whether to override an existing, locally-specified
|
||||
/// nullability specifier rather than complaining about the conflict.
|
||||
///
|
||||
/// \returns true if nullability cannot be applied, false otherwise.
|
||||
bool CheckImplicitNullabilityTypeSpecifier(QualType &Type,
|
||||
NullabilityKind Nullability,
|
||||
SourceLocation DiagLoc,
|
||||
bool AllowArrayTypes,
|
||||
bool OverrideExisting);
|
||||
|
||||
/// Process the attributes before creating an attributed statement. Returns
|
||||
/// the semantic attributes that have been processed.
|
||||
void ProcessStmtAttributes(Stmt *Stmt, const ParsedAttributes &InAttrs,
|
||||
@ -7110,15 +7144,7 @@ public:
|
||||
NestedNameSpecInfo &IdInfo,
|
||||
bool EnteringContext);
|
||||
|
||||
/// The kind of conversion to check for. Either all attributes must match exactly,
|
||||
/// or the converted type may add/drop '__arm_preserves_za'.
|
||||
enum class AArch64SMECallConversionKind {
|
||||
MatchExactly,
|
||||
MayAddPreservesZA,
|
||||
MayDropPreservesZA,
|
||||
};
|
||||
bool IsInvalidSMECallConversion(QualType FromType, QualType ToType,
|
||||
AArch64SMECallConversionKind C);
|
||||
bool IsInvalidSMECallConversion(QualType FromType, QualType ToType);
|
||||
|
||||
/// The parser has parsed a nested-name-specifier
|
||||
/// 'template[opt] template-name < template-args >::'.
|
||||
@ -8569,8 +8595,8 @@ public:
|
||||
QualType ParamType,
|
||||
SourceLocation Loc);
|
||||
ExprResult
|
||||
BuildExpressionFromIntegralTemplateArgument(const TemplateArgument &Arg,
|
||||
SourceLocation Loc);
|
||||
BuildExpressionFromNonTypeTemplateArgument(const TemplateArgument &Arg,
|
||||
SourceLocation Loc);
|
||||
|
||||
/// Enumeration describing how template parameter lists are compared
|
||||
/// for equality.
|
||||
@ -11223,6 +11249,11 @@ public:
|
||||
VarDecl *buildCoroutinePromise(SourceLocation Loc);
|
||||
void CheckCompletedCoroutineBody(FunctionDecl *FD, Stmt *&Body);
|
||||
|
||||
// Heuristically tells if the function is `get_return_object` member of a
|
||||
// coroutine promise_type by matching the function name.
|
||||
static bool CanBeGetReturnObject(const FunctionDecl *FD);
|
||||
static bool CanBeGetReturnTypeOnAllocFailure(const FunctionDecl *FD);
|
||||
|
||||
// As a clang extension, enforces that a non-coroutine function must be marked
|
||||
// with [[clang::coro_wrapper]] if it returns a type marked with
|
||||
// [[clang::coro_return_type]].
|
||||
@ -13901,8 +13932,9 @@ private:
|
||||
|
||||
bool SemaBuiltinVAStart(unsigned BuiltinID, CallExpr *TheCall);
|
||||
bool SemaBuiltinVAStartARMMicrosoft(CallExpr *Call);
|
||||
bool SemaBuiltinUnorderedCompare(CallExpr *TheCall);
|
||||
bool SemaBuiltinFPClassification(CallExpr *TheCall, unsigned NumArgs);
|
||||
bool SemaBuiltinUnorderedCompare(CallExpr *TheCall, unsigned BuiltinID);
|
||||
bool SemaBuiltinFPClassification(CallExpr *TheCall, unsigned NumArgs,
|
||||
unsigned BuiltinID);
|
||||
bool SemaBuiltinComplex(CallExpr *TheCall);
|
||||
bool SemaBuiltinVSX(CallExpr *TheCall);
|
||||
bool SemaBuiltinOSLogFormat(CallExpr *TheCall);
|
||||
@ -14006,6 +14038,8 @@ private:
|
||||
SourceRange range,
|
||||
llvm::SmallBitVector &CheckedVarArgs);
|
||||
|
||||
void CheckInfNaNFunction(const CallExpr *Call, const FunctionDecl *FDecl);
|
||||
|
||||
void CheckAbsoluteValueFunction(const CallExpr *Call,
|
||||
const FunctionDecl *FDecl);
|
||||
|
||||
|
@ -550,6 +550,10 @@ private:
|
||||
/// declaration and the value is the deduced return type.
|
||||
llvm::SmallMapVector<FunctionDecl *, QualType, 4> PendingDeducedTypeUpdates;
|
||||
|
||||
/// Functions has undededuced return type and we wish we can find the deduced
|
||||
/// return type by iterating the redecls in other modules.
|
||||
llvm::SmallVector<FunctionDecl *, 4> PendingUndeducedFunctionDecls;
|
||||
|
||||
/// Declarations that have been imported and have typedef names for
|
||||
/// linkage purposes.
|
||||
llvm::DenseMap<std::pair<DeclContext *, IdentifierInfo *>, NamedDecl *>
|
||||
|
@ -488,7 +488,7 @@ public:
|
||||
enum RVVRequire : uint32_t {
|
||||
RVV_REQ_None = 0,
|
||||
RVV_REQ_RV64 = 1 << 0,
|
||||
RVV_REQ_ZvfhminOrZvfh = 1 << 1,
|
||||
RVV_REQ_Zvfhmin = 1 << 1,
|
||||
RVV_REQ_Xsfvcp = 1 << 2,
|
||||
RVV_REQ_Xsfvfnrclipxfqf = 1 << 3,
|
||||
RVV_REQ_Xsfvfwmaccqqq = 1 << 4,
|
||||
|
@ -43,7 +43,7 @@ std::string FileRemapper::getRemapInfoFile(StringRef outputDir) {
|
||||
assert(!outputDir.empty());
|
||||
SmallString<128> InfoFile = outputDir;
|
||||
llvm::sys::path::append(InfoFile, "remap");
|
||||
return std::string(InfoFile.str());
|
||||
return std::string(InfoFile);
|
||||
}
|
||||
|
||||
bool FileRemapper::initFromDisk(StringRef outputDir, DiagnosticsEngine &Diag,
|
||||
|
@ -2201,7 +2201,7 @@ static std::string applyEditsToTemp(FileEntryRef FE,
|
||||
TmpOut.write(NewText.data(), NewText.size());
|
||||
TmpOut.close();
|
||||
|
||||
return std::string(TempPath.str());
|
||||
return std::string(TempPath);
|
||||
}
|
||||
|
||||
bool arcmt::getFileRemappingsFromFileList(
|
||||
|
@ -4484,10 +4484,11 @@ QualType ASTContext::getFunctionTypeInternal(
|
||||
EPI.ExceptionSpec.Type, EPI.ExceptionSpec.Exceptions.size());
|
||||
size_t Size = FunctionProtoType::totalSizeToAlloc<
|
||||
QualType, SourceLocation, FunctionType::FunctionTypeExtraBitfields,
|
||||
FunctionType::ExceptionType, Expr *, FunctionDecl *,
|
||||
FunctionProtoType::ExtParameterInfo, Qualifiers>(
|
||||
FunctionType::FunctionTypeArmAttributes, FunctionType::ExceptionType,
|
||||
Expr *, FunctionDecl *, FunctionProtoType::ExtParameterInfo, Qualifiers>(
|
||||
NumArgs, EPI.Variadic, EPI.requiresFunctionProtoTypeExtraBitfields(),
|
||||
ESH.NumExceptionType, ESH.NumExprPtr, ESH.NumFunctionDeclPtr,
|
||||
EPI.requiresFunctionProtoTypeArmAttributes(), ESH.NumExceptionType,
|
||||
ESH.NumExprPtr, ESH.NumFunctionDeclPtr,
|
||||
EPI.ExtParameterInfos ? NumArgs : 0,
|
||||
EPI.TypeQuals.hasNonFastQualifiers() ? 1 : 0);
|
||||
|
||||
@ -6753,6 +6754,11 @@ ASTContext::getCanonicalTemplateArgument(const TemplateArgument &Arg) const {
|
||||
case TemplateArgument::Integral:
|
||||
return TemplateArgument(Arg, getCanonicalType(Arg.getIntegralType()));
|
||||
|
||||
case TemplateArgument::StructuralValue:
|
||||
return TemplateArgument(*this,
|
||||
getCanonicalType(Arg.getStructuralValueType()),
|
||||
Arg.getAsStructuralValue());
|
||||
|
||||
case TemplateArgument::Type:
|
||||
return TemplateArgument(getCanonicalType(Arg.getAsType()),
|
||||
/*isNullPtr*/ false, Arg.getIsDefaulted());
|
||||
|
@ -823,6 +823,17 @@ ASTNodeImporter::import(const TemplateArgument &From) {
|
||||
From.getIsDefaulted());
|
||||
}
|
||||
|
||||
case TemplateArgument::StructuralValue: {
|
||||
ExpectedType ToTypeOrErr = import(From.getStructuralValueType());
|
||||
if (!ToTypeOrErr)
|
||||
return ToTypeOrErr.takeError();
|
||||
Expected<APValue> ToValueOrErr = import(From.getAsStructuralValue());
|
||||
if (!ToValueOrErr)
|
||||
return ToValueOrErr.takeError();
|
||||
return TemplateArgument(Importer.getToContext(), *ToTypeOrErr,
|
||||
*ToValueOrErr);
|
||||
}
|
||||
|
||||
case TemplateArgument::Template: {
|
||||
Expected<TemplateName> ToTemplateOrErr = import(From.getAsTemplate());
|
||||
if (!ToTemplateOrErr)
|
||||
@ -3572,6 +3583,8 @@ private:
|
||||
case TemplateArgument::NullPtr:
|
||||
// FIXME: The type is not allowed to be in the function?
|
||||
return CheckType(Arg.getNullPtrType());
|
||||
case TemplateArgument::StructuralValue:
|
||||
return CheckType(Arg.getStructuralValueType());
|
||||
case TemplateArgument::Pack:
|
||||
for (const auto &PackArg : Arg.getPackAsArray())
|
||||
if (checkTemplateArgument(PackArg))
|
||||
@ -3896,7 +3909,7 @@ ExpectedDecl ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
|
||||
ToFunction->setLexicalDeclContext(LexicalDC);
|
||||
ToFunction->setVirtualAsWritten(D->isVirtualAsWritten());
|
||||
ToFunction->setTrivial(D->isTrivial());
|
||||
ToFunction->setPure(D->isPure());
|
||||
ToFunction->setIsPureVirtual(D->isPureVirtual());
|
||||
ToFunction->setDefaulted(D->isDefaulted());
|
||||
ToFunction->setExplicitlyDefaulted(D->isExplicitlyDefaulted());
|
||||
ToFunction->setDeletedAsWritten(D->isDeletedAsWritten());
|
||||
@ -6280,17 +6293,21 @@ ExpectedDecl ASTNodeImporter::VisitVarTemplateDecl(VarTemplateDecl *D) {
|
||||
D->getTemplatedDecl()))
|
||||
continue;
|
||||
if (IsStructuralMatch(D, FoundTemplate)) {
|
||||
// The Decl in the "From" context has a definition, but in the
|
||||
// "To" context we already have a definition.
|
||||
// FIXME Check for ODR error if the two definitions have
|
||||
// different initializers?
|
||||
VarTemplateDecl *FoundDef = getTemplateDefinition(FoundTemplate);
|
||||
if (D->isThisDeclarationADefinition() && FoundDef)
|
||||
// FIXME Check for ODR error if the two definitions have
|
||||
// different initializers?
|
||||
return Importer.MapImported(D, FoundDef);
|
||||
if (FoundTemplate->getDeclContext()->isRecord() &&
|
||||
D->getDeclContext()->isRecord())
|
||||
return Importer.MapImported(D, FoundTemplate);
|
||||
|
||||
if (D->getDeclContext()->isRecord()) {
|
||||
assert(FoundTemplate->getDeclContext()->isRecord() &&
|
||||
"Member variable template imported as non-member, "
|
||||
"inconsistent imported AST?");
|
||||
if (FoundDef)
|
||||
return Importer.MapImported(D, FoundDef);
|
||||
if (!D->isThisDeclarationADefinition())
|
||||
return Importer.MapImported(D, FoundTemplate);
|
||||
} else {
|
||||
if (FoundDef && D->isThisDeclarationADefinition())
|
||||
return Importer.MapImported(D, FoundDef);
|
||||
}
|
||||
FoundByLookup = FoundTemplate;
|
||||
break;
|
||||
}
|
||||
|
@ -98,6 +98,8 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
|
||||
QualType T1, QualType T2);
|
||||
static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
|
||||
Decl *D1, Decl *D2);
|
||||
static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
|
||||
const Stmt *S1, const Stmt *S2);
|
||||
static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
|
||||
const TemplateArgument &Arg1,
|
||||
const TemplateArgument &Arg2);
|
||||
@ -437,12 +439,67 @@ public:
|
||||
};
|
||||
} // namespace
|
||||
|
||||
static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
|
||||
const UnaryOperator *E1,
|
||||
const CXXOperatorCallExpr *E2) {
|
||||
return UnaryOperator::getOverloadedOperator(E1->getOpcode()) ==
|
||||
E2->getOperator() &&
|
||||
IsStructurallyEquivalent(Context, E1->getSubExpr(), E2->getArg(0));
|
||||
}
|
||||
|
||||
static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
|
||||
const CXXOperatorCallExpr *E1,
|
||||
const UnaryOperator *E2) {
|
||||
return E1->getOperator() ==
|
||||
UnaryOperator::getOverloadedOperator(E2->getOpcode()) &&
|
||||
IsStructurallyEquivalent(Context, E1->getArg(0), E2->getSubExpr());
|
||||
}
|
||||
|
||||
static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
|
||||
const BinaryOperator *E1,
|
||||
const CXXOperatorCallExpr *E2) {
|
||||
return BinaryOperator::getOverloadedOperator(E1->getOpcode()) ==
|
||||
E2->getOperator() &&
|
||||
IsStructurallyEquivalent(Context, E1->getLHS(), E2->getArg(0)) &&
|
||||
IsStructurallyEquivalent(Context, E1->getRHS(), E2->getArg(1));
|
||||
}
|
||||
|
||||
static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
|
||||
const CXXOperatorCallExpr *E1,
|
||||
const BinaryOperator *E2) {
|
||||
return E1->getOperator() ==
|
||||
BinaryOperator::getOverloadedOperator(E2->getOpcode()) &&
|
||||
IsStructurallyEquivalent(Context, E1->getArg(0), E2->getLHS()) &&
|
||||
IsStructurallyEquivalent(Context, E1->getArg(1), E2->getRHS());
|
||||
}
|
||||
|
||||
/// Determine structural equivalence of two statements.
|
||||
static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
|
||||
const Stmt *S1, const Stmt *S2) {
|
||||
if (!S1 || !S2)
|
||||
return S1 == S2;
|
||||
|
||||
// Check for statements with similar syntax but different AST.
|
||||
// A UnaryOperator node is more lightweight than a CXXOperatorCallExpr node.
|
||||
// The more heavyweight node is only created if the definition-time name
|
||||
// lookup had any results. The lookup results are stored CXXOperatorCallExpr
|
||||
// only. The lookup results can be different in a "From" and "To" AST even if
|
||||
// the compared structure is otherwise equivalent. For this reason we must
|
||||
// treat a similar unary/binary operator node and CXXOperatorCall node as
|
||||
// equivalent.
|
||||
if (const auto *E2CXXOperatorCall = dyn_cast<CXXOperatorCallExpr>(S2)) {
|
||||
if (const auto *E1Unary = dyn_cast<UnaryOperator>(S1))
|
||||
return IsStructurallyEquivalent(Context, E1Unary, E2CXXOperatorCall);
|
||||
if (const auto *E1Binary = dyn_cast<BinaryOperator>(S1))
|
||||
return IsStructurallyEquivalent(Context, E1Binary, E2CXXOperatorCall);
|
||||
}
|
||||
if (const auto *E1CXXOperatorCall = dyn_cast<CXXOperatorCallExpr>(S1)) {
|
||||
if (const auto *E2Unary = dyn_cast<UnaryOperator>(S2))
|
||||
return IsStructurallyEquivalent(Context, E1CXXOperatorCall, E2Unary);
|
||||
if (const auto *E2Binary = dyn_cast<BinaryOperator>(S2))
|
||||
return IsStructurallyEquivalent(Context, E1CXXOperatorCall, E2Binary);
|
||||
}
|
||||
|
||||
// Compare the statements itself.
|
||||
StmtComparer Comparer(Context);
|
||||
if (!Comparer.IsEquivalent(S1, S2))
|
||||
@ -628,6 +685,9 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
|
||||
return IsStructurallyEquivalent(Context, Arg1.getAsExpr(),
|
||||
Arg2.getAsExpr());
|
||||
|
||||
case TemplateArgument::StructuralValue:
|
||||
return Arg1.structurallyEquals(Arg2);
|
||||
|
||||
case TemplateArgument::Pack:
|
||||
return IsStructurallyEquivalent(Context, Arg1.pack_elements(),
|
||||
Arg2.pack_elements());
|
||||
@ -1410,7 +1470,7 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
|
||||
Method1->isConst() == Method2->isConst() &&
|
||||
Method1->isVolatile() == Method2->isVolatile() &&
|
||||
Method1->isVirtual() == Method2->isVirtual() &&
|
||||
Method1->isPure() == Method2->isPure() &&
|
||||
Method1->isPureVirtual() == Method2->isPureVirtual() &&
|
||||
Method1->isDefaulted() == Method2->isDefaulted() &&
|
||||
Method1->isDeleted() == Method2->isDeleted();
|
||||
if (!PropertiesEqual)
|
||||
|
@ -343,6 +343,10 @@ LinkageComputer::getLVForTemplateArgumentList(ArrayRef<TemplateArgument> Args,
|
||||
LV.merge(getTypeLinkageAndVisibility(Arg.getNullPtrType()));
|
||||
continue;
|
||||
|
||||
case TemplateArgument::StructuralValue:
|
||||
LV.merge(getLVForValue(Arg.getAsStructuralValue(), computation));
|
||||
continue;
|
||||
|
||||
case TemplateArgument::Template:
|
||||
case TemplateArgument::TemplateExpansion:
|
||||
if (TemplateDecl *Template =
|
||||
@ -3036,7 +3040,7 @@ FunctionDecl::FunctionDecl(Kind DK, ASTContext &C, DeclContext *DC,
|
||||
FunctionDeclBits.IsInline = isInlineSpecified;
|
||||
FunctionDeclBits.IsInlineSpecified = isInlineSpecified;
|
||||
FunctionDeclBits.IsVirtualAsWritten = false;
|
||||
FunctionDeclBits.IsPure = false;
|
||||
FunctionDeclBits.IsPureVirtual = false;
|
||||
FunctionDeclBits.HasInheritedPrototype = false;
|
||||
FunctionDeclBits.HasWrittenPrototype = true;
|
||||
FunctionDeclBits.IsDeleted = false;
|
||||
@ -3203,8 +3207,8 @@ void FunctionDecl::setBody(Stmt *B) {
|
||||
EndRangeLoc = B->getEndLoc();
|
||||
}
|
||||
|
||||
void FunctionDecl::setPure(bool P) {
|
||||
FunctionDeclBits.IsPure = P;
|
||||
void FunctionDecl::setIsPureVirtual(bool P) {
|
||||
FunctionDeclBits.IsPureVirtual = P;
|
||||
if (P)
|
||||
if (auto *Parent = dyn_cast<CXXRecordDecl>(getDeclContext()))
|
||||
Parent->markedVirtualFunctionPure();
|
||||
@ -5369,16 +5373,23 @@ void CapturedDecl::setBody(Stmt *B) { BodyAndNothrow.setPointer(B); }
|
||||
bool CapturedDecl::isNothrow() const { return BodyAndNothrow.getInt(); }
|
||||
void CapturedDecl::setNothrow(bool Nothrow) { BodyAndNothrow.setInt(Nothrow); }
|
||||
|
||||
EnumConstantDecl::EnumConstantDecl(const ASTContext &C, DeclContext *DC,
|
||||
SourceLocation L, IdentifierInfo *Id,
|
||||
QualType T, Expr *E, const llvm::APSInt &V)
|
||||
: ValueDecl(EnumConstant, DC, L, Id, T), Init((Stmt *)E) {
|
||||
setInitVal(C, V);
|
||||
}
|
||||
|
||||
EnumConstantDecl *EnumConstantDecl::Create(ASTContext &C, EnumDecl *CD,
|
||||
SourceLocation L,
|
||||
IdentifierInfo *Id, QualType T,
|
||||
Expr *E, const llvm::APSInt &V) {
|
||||
return new (C, CD) EnumConstantDecl(CD, L, Id, T, E, V);
|
||||
return new (C, CD) EnumConstantDecl(C, CD, L, Id, T, E, V);
|
||||
}
|
||||
|
||||
EnumConstantDecl *
|
||||
EnumConstantDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
|
||||
return new (C, ID) EnumConstantDecl(nullptr, SourceLocation(), nullptr,
|
||||
return new (C, ID) EnumConstantDecl(C, nullptr, SourceLocation(), nullptr,
|
||||
QualType(), nullptr, llvm::APSInt());
|
||||
}
|
||||
|
||||
|
@ -1383,6 +1383,31 @@ void CXXRecordDecl::addedMember(Decl *D) {
|
||||
}
|
||||
}
|
||||
|
||||
bool CXXRecordDecl::isLiteral() const {
|
||||
const LangOptions &LangOpts = getLangOpts();
|
||||
if (!(LangOpts.CPlusPlus20 ? hasConstexprDestructor()
|
||||
: hasTrivialDestructor()))
|
||||
return false;
|
||||
|
||||
if (hasNonLiteralTypeFieldsOrBases()) {
|
||||
// CWG2598
|
||||
// is an aggregate union type that has either no variant
|
||||
// members or at least one variant member of non-volatile literal type,
|
||||
if (!isUnion())
|
||||
return false;
|
||||
bool HasAtLeastOneLiteralMember =
|
||||
fields().empty() || any_of(fields(), [this](const FieldDecl *D) {
|
||||
return !D->getType().isVolatileQualified() &&
|
||||
D->getType()->isLiteralType(getASTContext());
|
||||
});
|
||||
if (!HasAtLeastOneLiteralMember)
|
||||
return false;
|
||||
}
|
||||
|
||||
return isAggregate() || (isLambda() && LangOpts.CPlusPlus17) ||
|
||||
hasConstexprNonCopyMoveConstructor() || hasTrivialDefaultConstructor();
|
||||
}
|
||||
|
||||
void CXXRecordDecl::addedSelectedDestructor(CXXDestructorDecl *DD) {
|
||||
DD->setIneligibleOrNotSelected(false);
|
||||
addedEligibleSpecialMemberFunction(DD, SMF_Destructor);
|
||||
@ -2054,7 +2079,7 @@ void CXXRecordDecl::completeDefinition(CXXFinalOverriderMap *FinalOverriders) {
|
||||
// A class is abstract if it contains or inherits at least one
|
||||
// pure virtual function for which the final overrider is pure
|
||||
// virtual.
|
||||
if (SO->second.front().Method->isPure()) {
|
||||
if (SO->second.front().Method->isPureVirtual()) {
|
||||
data().Abstract = true;
|
||||
Done = true;
|
||||
break;
|
||||
@ -2273,7 +2298,7 @@ CXXMethodDecl *CXXMethodDecl::getDevirtualizedMethod(const Expr *Base,
|
||||
// If the member function is marked 'final', we know that it can't be
|
||||
// overridden and can therefore devirtualize it unless it's pure virtual.
|
||||
if (hasAttr<FinalAttr>())
|
||||
return isPure() ? nullptr : this;
|
||||
return isPureVirtual() ? nullptr : this;
|
||||
|
||||
// If Base is unknown, we cannot devirtualize.
|
||||
if (!Base)
|
||||
@ -2302,7 +2327,7 @@ CXXMethodDecl *CXXMethodDecl::getDevirtualizedMethod(const Expr *Base,
|
||||
// If that method is pure virtual, we can't devirtualize. If this code is
|
||||
// reached, the result would be UB, not a direct call to the derived class
|
||||
// function, and we can't assume the derived class function is defined.
|
||||
if (DevirtualizedMethod->isPure())
|
||||
if (DevirtualizedMethod->isPureVirtual())
|
||||
return nullptr;
|
||||
|
||||
// If that method is marked final, we can devirtualize it.
|
||||
|
@ -871,7 +871,7 @@ void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) {
|
||||
|
||||
prettyPrintAttributes(D, Out, AttrPrintLoc::Right);
|
||||
|
||||
if (D->isPure())
|
||||
if (D->isPureVirtual())
|
||||
Out << " = 0";
|
||||
else if (D->isDeletedAsWritten())
|
||||
Out << " = delete";
|
||||
|
@ -690,7 +690,7 @@ std::string PredefinedExpr::ComputeName(PredefinedIdentKind IK,
|
||||
|
||||
if (!Buffer.empty() && Buffer.front() == '\01')
|
||||
return std::string(Buffer.substr(1));
|
||||
return std::string(Buffer.str());
|
||||
return std::string(Buffer);
|
||||
}
|
||||
return std::string(ND->getIdentifier()->getName());
|
||||
}
|
||||
@ -986,7 +986,7 @@ std::string FixedPointLiteral::getValueAsString(unsigned Radix) const {
|
||||
SmallString<64> S;
|
||||
FixedPointValueToString(
|
||||
S, llvm::APSInt::getUnsigned(getValue().getZExtValue()), Scale);
|
||||
return std::string(S.str());
|
||||
return std::string(S);
|
||||
}
|
||||
|
||||
void CharacterLiteral::print(unsigned Val, CharacterLiteralKind Kind,
|
||||
@ -2219,7 +2219,10 @@ SourceLocExpr::SourceLocExpr(const ASTContext &Ctx, SourceLocIdentKind Kind,
|
||||
: Expr(SourceLocExprClass, ResultTy, VK_PRValue, OK_Ordinary),
|
||||
BuiltinLoc(BLoc), RParenLoc(RParenLoc), ParentContext(ParentContext) {
|
||||
SourceLocExprBits.Kind = llvm::to_underlying(Kind);
|
||||
setDependence(ExprDependence::None);
|
||||
// In dependent contexts, function names may change.
|
||||
setDependence(MayBeDependent(Kind) && ParentContext->isDependentContext()
|
||||
? ExprDependence::Value
|
||||
: ExprDependence::None);
|
||||
}
|
||||
|
||||
StringRef SourceLocExpr::getBuiltinStr() const {
|
||||
|
@ -194,14 +194,14 @@ CXXNewExpr::CXXNewExpr(bool IsGlobalNew, FunctionDecl *OperatorNew,
|
||||
DirectInitRange(DirectInitRange) {
|
||||
|
||||
assert((Initializer != nullptr ||
|
||||
InitializationStyle == CXXNewInitializationStyle::None ||
|
||||
InitializationStyle == CXXNewInitializationStyle::Implicit) &&
|
||||
"Only NoInit can have no initializer!");
|
||||
InitializationStyle == CXXNewInitializationStyle::None) &&
|
||||
"Only CXXNewInitializationStyle::None can have no initializer!");
|
||||
|
||||
CXXNewExprBits.IsGlobalNew = IsGlobalNew;
|
||||
CXXNewExprBits.IsArray = ArraySize.has_value();
|
||||
CXXNewExprBits.ShouldPassAlignment = ShouldPassAlignment;
|
||||
CXXNewExprBits.UsualArrayDeleteWantsSize = UsualArrayDeleteWantsSize;
|
||||
CXXNewExprBits.HasInitializer = Initializer != nullptr;
|
||||
CXXNewExprBits.StoredInitializationStyle =
|
||||
llvm::to_underlying(InitializationStyle);
|
||||
bool IsParenTypeId = TypeIdParens.isValid();
|
||||
@ -219,10 +219,10 @@ CXXNewExpr::CXXNewExpr(bool IsGlobalNew, FunctionDecl *OperatorNew,
|
||||
getTrailingObjects<SourceRange>()[0] = TypeIdParens;
|
||||
|
||||
switch (getInitializationStyle()) {
|
||||
case CXXNewInitializationStyle::Call:
|
||||
case CXXNewInitializationStyle::Parens:
|
||||
this->Range.setEnd(DirectInitRange.getEnd());
|
||||
break;
|
||||
case CXXNewInitializationStyle::List:
|
||||
case CXXNewInitializationStyle::Braces:
|
||||
this->Range.setEnd(getInitializer()->getSourceRange().getEnd());
|
||||
break;
|
||||
default:
|
||||
|
@ -5839,7 +5839,7 @@ static const CXXMethodDecl *HandleVirtualDispatch(
|
||||
// C++2a [class.abstract]p6:
|
||||
// the effect of making a virtual call to a pure virtual function [...] is
|
||||
// undefined
|
||||
if (Callee->isPure()) {
|
||||
if (Callee->isPureVirtual()) {
|
||||
Info.FFDiag(E, diag::note_constexpr_pure_virtual_call, 1) << Callee;
|
||||
Info.Note(Callee->getLocation(), diag::note_declared_at);
|
||||
return nullptr;
|
||||
@ -15439,11 +15439,13 @@ static bool EvaluateAsRValue(EvalInfo &Info, const Expr *E, APValue &Result) {
|
||||
if (Info.EnableNewConstInterp) {
|
||||
if (!Info.Ctx.getInterpContext().evaluateAsRValue(Info, E, Result))
|
||||
return false;
|
||||
} else {
|
||||
if (!::Evaluate(Result, Info, E))
|
||||
return false;
|
||||
return CheckConstantExpression(Info, E->getExprLoc(), E->getType(), Result,
|
||||
ConstantExprKind::Normal);
|
||||
}
|
||||
|
||||
if (!::Evaluate(Result, Info, E))
|
||||
return false;
|
||||
|
||||
// Implicit lvalue-to-rvalue cast.
|
||||
if (E->isGLValue()) {
|
||||
LValue LV;
|
||||
@ -15671,6 +15673,13 @@ bool Expr::EvaluateAsConstantExpr(EvalResult &Result, const ASTContext &Ctx,
|
||||
EvalInfo Info(Ctx, Result, EM);
|
||||
Info.InConstantContext = true;
|
||||
|
||||
if (Info.EnableNewConstInterp) {
|
||||
if (!Info.Ctx.getInterpContext().evaluate(Info, this, Result.Val))
|
||||
return false;
|
||||
return CheckConstantExpression(Info, getExprLoc(),
|
||||
getStorageType(Ctx, this), Result.Val, Kind);
|
||||
}
|
||||
|
||||
// The type of the object we're initializing is 'const T' for a class NTTP.
|
||||
QualType T = getType();
|
||||
if (Kind == ConstantExprKind::ClassTemplateArgument)
|
||||
@ -15746,18 +15755,36 @@ bool Expr::EvaluateAsInitializer(APValue &Value, const ASTContext &Ctx,
|
||||
Info.setEvaluatingDecl(VD, Value);
|
||||
Info.InConstantContext = IsConstantInitialization;
|
||||
|
||||
SourceLocation DeclLoc = VD->getLocation();
|
||||
QualType DeclTy = VD->getType();
|
||||
|
||||
if (Info.EnableNewConstInterp) {
|
||||
auto &InterpCtx = const_cast<ASTContext &>(Ctx).getInterpContext();
|
||||
if (!InterpCtx.evaluateAsInitializer(Info, VD, Value))
|
||||
return false;
|
||||
|
||||
return CheckConstantExpression(Info, DeclLoc, DeclTy, Value,
|
||||
ConstantExprKind::Normal);
|
||||
} else {
|
||||
LValue LVal;
|
||||
LVal.set(VD);
|
||||
|
||||
if (!EvaluateInPlace(Value, Info, LVal, this,
|
||||
/*AllowNonLiteralTypes=*/true) ||
|
||||
EStatus.HasSideEffects)
|
||||
return false;
|
||||
{
|
||||
// C++23 [intro.execution]/p5
|
||||
// A full-expression is ... an init-declarator ([dcl.decl]) or a
|
||||
// mem-initializer.
|
||||
// So we need to make sure temporary objects are destroyed after having
|
||||
// evaluated the expression (per C++23 [class.temporary]/p4).
|
||||
//
|
||||
// FIXME: Otherwise this may break test/Modules/pr68702.cpp because the
|
||||
// serialization code calls ParmVarDecl::getDefaultArg() which strips the
|
||||
// outermost FullExpr, such as ExprWithCleanups.
|
||||
FullExpressionRAII Scope(Info);
|
||||
if (!EvaluateInPlace(Value, Info, LVal, this,
|
||||
/*AllowNonLiteralTypes=*/true) ||
|
||||
EStatus.HasSideEffects)
|
||||
return false;
|
||||
}
|
||||
|
||||
// At this point, any lifetime-extended temporaries are completely
|
||||
// initialized.
|
||||
@ -15767,8 +15794,6 @@ bool Expr::EvaluateAsInitializer(APValue &Value, const ASTContext &Ctx,
|
||||
llvm_unreachable("Unhandled cleanup; missing full expression marker?");
|
||||
}
|
||||
|
||||
SourceLocation DeclLoc = VD->getLocation();
|
||||
QualType DeclTy = VD->getType();
|
||||
return CheckConstantExpression(Info, DeclLoc, DeclTy, Value,
|
||||
ConstantExprKind::Normal) &&
|
||||
CheckMemoryLeaks(Info);
|
||||
|
@ -20,8 +20,7 @@
|
||||
using namespace clang;
|
||||
using namespace clang::interp;
|
||||
|
||||
Expected<Function *>
|
||||
ByteCodeEmitter::compileFunc(const FunctionDecl *FuncDecl) {
|
||||
Function *ByteCodeEmitter::compileFunc(const FunctionDecl *FuncDecl) {
|
||||
// Set up argument indices.
|
||||
unsigned ParamOffset = 0;
|
||||
SmallVector<PrimType, 8> ParamTypes;
|
||||
@ -120,10 +119,6 @@ ByteCodeEmitter::compileFunc(const FunctionDecl *FuncDecl) {
|
||||
|
||||
// Compile the function body.
|
||||
if (!IsEligibleForCompilation || !visitFunc(FuncDecl)) {
|
||||
// Return a dummy function if compilation failed.
|
||||
if (BailLocation)
|
||||
return llvm::make_error<ByteCodeGenError>(*BailLocation);
|
||||
|
||||
Func->setIsFullyCompiled(true);
|
||||
return Func;
|
||||
}
|
||||
@ -183,12 +178,6 @@ int32_t ByteCodeEmitter::getOffset(LabelTy Label) {
|
||||
return 0ull;
|
||||
}
|
||||
|
||||
bool ByteCodeEmitter::bail(const SourceLocation &Loc) {
|
||||
if (!BailLocation)
|
||||
BailLocation = Loc;
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Helper to write bytecode and bail out if 32-bit offsets become invalid.
|
||||
/// Pointers will be automatically marshalled as 32-bit IDs.
|
||||
template <typename T>
|
||||
|
@ -17,7 +17,6 @@
|
||||
#include "PrimType.h"
|
||||
#include "Program.h"
|
||||
#include "Source.h"
|
||||
#include "llvm/Support/Error.h"
|
||||
|
||||
namespace clang {
|
||||
namespace interp {
|
||||
@ -32,7 +31,7 @@ protected:
|
||||
|
||||
public:
|
||||
/// Compiles the function into the module.
|
||||
llvm::Expected<Function *> compileFunc(const FunctionDecl *FuncDecl);
|
||||
Function *compileFunc(const FunctionDecl *FuncDecl);
|
||||
|
||||
protected:
|
||||
ByteCodeEmitter(Context &Ctx, Program &P) : Ctx(Ctx), P(P) {}
|
||||
@ -49,11 +48,6 @@ protected:
|
||||
virtual bool visitExpr(const Expr *E) = 0;
|
||||
virtual bool visitDecl(const VarDecl *E) = 0;
|
||||
|
||||
/// Bails out if a given node cannot be compiled.
|
||||
bool bail(const Stmt *S) { return bail(S->getBeginLoc()); }
|
||||
bool bail(const Decl *D) { return bail(D->getBeginLoc()); }
|
||||
bool bail(const SourceLocation &Loc);
|
||||
|
||||
/// Emits jumps.
|
||||
bool jumpTrue(const LabelTy &Label);
|
||||
bool jumpFalse(const LabelTy &Label);
|
||||
@ -81,8 +75,6 @@ private:
|
||||
LabelTy NextLabel = 0;
|
||||
/// Offset of the next local variable.
|
||||
unsigned NextLocalOffset = 0;
|
||||
/// Location of a failure.
|
||||
std::optional<SourceLocation> BailLocation;
|
||||
/// Label information for linker.
|
||||
llvm::DenseMap<LabelTy, unsigned> LabelOffsets;
|
||||
/// Location of label relocations.
|
||||
|
@ -287,6 +287,33 @@ bool ByteCodeExprGen<Emitter>::VisitCastExpr(const CastExpr *CE) {
|
||||
return true;
|
||||
}
|
||||
|
||||
case CK_IntegralComplexToReal:
|
||||
case CK_FloatingComplexToReal:
|
||||
return this->emitComplexReal(SubExpr);
|
||||
|
||||
case CK_IntegralRealToComplex:
|
||||
case CK_FloatingRealToComplex: {
|
||||
// We're creating a complex value here, so we need to
|
||||
// allocate storage for it.
|
||||
if (!Initializing) {
|
||||
std::optional<unsigned> LocalIndex =
|
||||
allocateLocal(CE, /*IsExtended=*/true);
|
||||
if (!LocalIndex)
|
||||
return false;
|
||||
if (!this->emitGetPtrLocal(*LocalIndex, CE))
|
||||
return false;
|
||||
}
|
||||
|
||||
// Init the complex value to {SubExpr, 0}.
|
||||
if (!this->visitArrayElemInit(0, SubExpr))
|
||||
return false;
|
||||
// Zero-init the second element.
|
||||
PrimType T = classifyPrim(SubExpr->getType());
|
||||
if (!this->visitZeroInitializer(T, SubExpr->getType(), SubExpr))
|
||||
return false;
|
||||
return this->emitInitElem(T, 1, SubExpr);
|
||||
}
|
||||
|
||||
case CK_ToVoid:
|
||||
return discard(SubExpr);
|
||||
|
||||
@ -371,7 +398,7 @@ bool ByteCodeExprGen<Emitter>::VisitBinaryOperator(const BinaryOperator *BO) {
|
||||
}
|
||||
|
||||
if (!LT || !RT || !T)
|
||||
return this->bail(BO);
|
||||
return false;
|
||||
|
||||
// Pointer arithmetic special case.
|
||||
if (BO->getOpcode() == BO_Add || BO->getOpcode() == BO_Sub) {
|
||||
@ -451,7 +478,7 @@ bool ByteCodeExprGen<Emitter>::VisitBinaryOperator(const BinaryOperator *BO) {
|
||||
case BO_LAnd:
|
||||
llvm_unreachable("Already handled earlier");
|
||||
default:
|
||||
return this->bail(BO);
|
||||
return false;
|
||||
}
|
||||
|
||||
llvm_unreachable("Unhandled binary op");
|
||||
@ -504,7 +531,7 @@ bool ByteCodeExprGen<Emitter>::VisitPointerArithBinOp(const BinaryOperator *E) {
|
||||
else if (Op == BO_Sub)
|
||||
return this->emitSubOffset(OffsetType, E);
|
||||
|
||||
return this->bail(E);
|
||||
return false;
|
||||
}
|
||||
|
||||
template <class Emitter>
|
||||
@ -842,6 +869,10 @@ bool ByteCodeExprGen<Emitter>::VisitInitListExpr(const InitListExpr *E) {
|
||||
|
||||
if (T->isAnyComplexType()) {
|
||||
unsigned NumInits = E->getNumInits();
|
||||
|
||||
if (NumInits == 1)
|
||||
return this->delegate(E->inits()[0]);
|
||||
|
||||
QualType ElemQT = E->getType()->getAs<ComplexType>()->getElementType();
|
||||
PrimType ElemT = classifyPrim(ElemQT);
|
||||
if (NumInits == 0) {
|
||||
@ -2030,7 +2061,7 @@ bool ByteCodeExprGen<Emitter>::dereference(
|
||||
}
|
||||
|
||||
if (LV->getType()->isAnyComplexType())
|
||||
return visit(LV);
|
||||
return this->delegate(LV);
|
||||
|
||||
return false;
|
||||
}
|
||||
@ -2337,7 +2368,7 @@ bool ByteCodeExprGen<Emitter>::visitDecl(const VarDecl *VD) {
|
||||
auto GlobalIndex = P.getGlobal(VD);
|
||||
assert(GlobalIndex); // visitVarDecl() didn't return false.
|
||||
if (VarT) {
|
||||
if (!this->emitGetGlobal(*VarT, *GlobalIndex, VD))
|
||||
if (!this->emitGetGlobalUnchecked(*VarT, *GlobalIndex, VD))
|
||||
return false;
|
||||
} else {
|
||||
if (!this->emitGetPtrGlobal(*GlobalIndex, VD))
|
||||
@ -2358,7 +2389,9 @@ bool ByteCodeExprGen<Emitter>::visitDecl(const VarDecl *VD) {
|
||||
// Return the value
|
||||
if (VarT)
|
||||
return this->emitRet(*VarT, VD);
|
||||
return this->emitRetValue(VD);
|
||||
|
||||
// Return non-primitive values as pointers here.
|
||||
return this->emitRet(PT_Ptr, VD);
|
||||
}
|
||||
|
||||
template <class Emitter>
|
||||
@ -2378,7 +2411,7 @@ bool ByteCodeExprGen<Emitter>::visitVarDecl(const VarDecl *VD) {
|
||||
std::optional<unsigned> GlobalIndex = P.createGlobal(VD, Init);
|
||||
|
||||
if (!GlobalIndex)
|
||||
return this->bail(VD);
|
||||
return false;
|
||||
|
||||
assert(Init);
|
||||
{
|
||||
@ -2767,23 +2800,16 @@ bool ByteCodeExprGen<Emitter>::VisitUnaryOperator(const UnaryOperator *E) {
|
||||
if (!this->visit(SubExpr))
|
||||
return false;
|
||||
return DiscardResult ? this->emitPop(*T, E) : this->emitComp(*T, E);
|
||||
case UO_Real: { // __real x
|
||||
assert(!T);
|
||||
if (!this->visit(SubExpr))
|
||||
return false;
|
||||
if (!this->emitConstUint8(0, E))
|
||||
return false;
|
||||
if (!this->emitArrayElemPtrPopUint8(E))
|
||||
return false;
|
||||
|
||||
// Since our _Complex implementation does not map to a primitive type,
|
||||
// we sometimes have to do the lvalue-to-rvalue conversion here manually.
|
||||
if (!SubExpr->isLValue())
|
||||
return this->emitLoadPop(classifyPrim(E->getType()), E);
|
||||
return true;
|
||||
}
|
||||
case UO_Real: // __real x
|
||||
if (T)
|
||||
return this->delegate(SubExpr);
|
||||
return this->emitComplexReal(SubExpr);
|
||||
case UO_Imag: { // __imag x
|
||||
assert(!T);
|
||||
if (T) {
|
||||
if (!this->discard(SubExpr))
|
||||
return false;
|
||||
return this->visitZeroInitializer(*T, SubExpr->getType(), SubExpr);
|
||||
}
|
||||
if (!this->visit(SubExpr))
|
||||
return false;
|
||||
if (!this->emitConstUint8(1, E))
|
||||
@ -2948,10 +2974,32 @@ bool ByteCodeExprGen<Emitter>::emitPrimCast(PrimType FromT, PrimType ToT,
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Emits __real(SubExpr)
|
||||
template <class Emitter>
|
||||
bool ByteCodeExprGen<Emitter>::emitComplexReal(const Expr *SubExpr) {
|
||||
assert(SubExpr->getType()->isAnyComplexType());
|
||||
|
||||
if (DiscardResult)
|
||||
return this->discard(SubExpr);
|
||||
|
||||
if (!this->visit(SubExpr))
|
||||
return false;
|
||||
if (!this->emitConstUint8(0, SubExpr))
|
||||
return false;
|
||||
if (!this->emitArrayElemPtrPopUint8(SubExpr))
|
||||
return false;
|
||||
|
||||
// Since our _Complex implementation does not map to a primitive type,
|
||||
// we sometimes have to do the lvalue-to-rvalue conversion here manually.
|
||||
if (!SubExpr->isLValue())
|
||||
return this->emitLoadPop(*classifyComplexElementType(SubExpr->getType()),
|
||||
SubExpr);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// When calling this, we have a pointer of the local-to-destroy
|
||||
/// on the stack.
|
||||
/// Emit destruction of record types (or arrays of record types).
|
||||
/// FIXME: Handle virtual destructors.
|
||||
template <class Emitter>
|
||||
bool ByteCodeExprGen<Emitter>::emitRecordDestruction(const Descriptor *Desc) {
|
||||
assert(Desc);
|
||||
|
@ -191,10 +191,6 @@ protected:
|
||||
if (!visitInitializer(Init))
|
||||
return false;
|
||||
|
||||
if ((Init->getType()->isArrayType() || Init->getType()->isRecordType()) &&
|
||||
!this->emitCheckGlobalCtor(Init))
|
||||
return false;
|
||||
|
||||
return this->emitPopPtr(Init);
|
||||
}
|
||||
|
||||
@ -294,6 +290,8 @@ private:
|
||||
return this->classify(ElemType);
|
||||
}
|
||||
|
||||
bool emitComplexReal(const Expr *SubExpr);
|
||||
|
||||
bool emitRecordDestruction(const Descriptor *Desc);
|
||||
unsigned collectBaseOffset(const RecordType *BaseType,
|
||||
const RecordType *DerivedType);
|
||||
|
@ -142,6 +142,27 @@ bool ByteCodeStmtGen<Emitter>::visitFunc(const FunctionDecl *F) {
|
||||
// Classify the return type.
|
||||
ReturnType = this->classify(F->getReturnType());
|
||||
|
||||
auto emitFieldInitializer = [&](const Record::Field *F, unsigned FieldOffset,
|
||||
const Expr *InitExpr) -> bool {
|
||||
if (std::optional<PrimType> T = this->classify(InitExpr)) {
|
||||
if (!this->visit(InitExpr))
|
||||
return false;
|
||||
|
||||
if (F->isBitField())
|
||||
return this->emitInitThisBitField(*T, F, FieldOffset, InitExpr);
|
||||
return this->emitInitThisField(*T, FieldOffset, InitExpr);
|
||||
}
|
||||
// Non-primitive case. Get a pointer to the field-to-initialize
|
||||
// on the stack and call visitInitialzer() for it.
|
||||
if (!this->emitGetPtrThisField(FieldOffset, InitExpr))
|
||||
return false;
|
||||
|
||||
if (!this->visitInitializer(InitExpr))
|
||||
return false;
|
||||
|
||||
return this->emitPopPtr(InitExpr);
|
||||
};
|
||||
|
||||
// Emit custom code if this is a lambda static invoker.
|
||||
if (const auto *MD = dyn_cast<CXXMethodDecl>(F);
|
||||
MD && MD->isLambdaStaticInvoker())
|
||||
@ -162,29 +183,8 @@ bool ByteCodeStmtGen<Emitter>::visitFunc(const FunctionDecl *F) {
|
||||
if (const FieldDecl *Member = Init->getMember()) {
|
||||
const Record::Field *F = R->getField(Member);
|
||||
|
||||
if (std::optional<PrimType> T = this->classify(InitExpr)) {
|
||||
if (!this->visit(InitExpr))
|
||||
return false;
|
||||
|
||||
if (F->isBitField()) {
|
||||
if (!this->emitInitThisBitField(*T, F, InitExpr))
|
||||
return false;
|
||||
} else {
|
||||
if (!this->emitInitThisField(*T, F->Offset, InitExpr))
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// Non-primitive case. Get a pointer to the field-to-initialize
|
||||
// on the stack and call visitInitialzer() for it.
|
||||
if (!this->emitGetPtrThisField(F->Offset, InitExpr))
|
||||
return false;
|
||||
|
||||
if (!this->visitInitializer(InitExpr))
|
||||
return false;
|
||||
|
||||
if (!this->emitPopPtr(InitExpr))
|
||||
return false;
|
||||
}
|
||||
if (!emitFieldInitializer(F, F->Offset, InitExpr))
|
||||
return false;
|
||||
} else if (const Type *Base = Init->getBaseClass()) {
|
||||
// Base class initializer.
|
||||
// Get This Base and call initializer on it.
|
||||
@ -198,6 +198,26 @@ bool ByteCodeStmtGen<Emitter>::visitFunc(const FunctionDecl *F) {
|
||||
return false;
|
||||
if (!this->emitInitPtrPop(InitExpr))
|
||||
return false;
|
||||
} else if (const IndirectFieldDecl *IFD = Init->getIndirectMember()) {
|
||||
assert(IFD->getChainingSize() >= 2);
|
||||
|
||||
unsigned NestedFieldOffset = 0;
|
||||
const Record::Field *NestedField = nullptr;
|
||||
for (const NamedDecl *ND : IFD->chain()) {
|
||||
const auto *FD = cast<FieldDecl>(ND);
|
||||
const Record *FieldRecord =
|
||||
this->P.getOrCreateRecord(FD->getParent());
|
||||
assert(FieldRecord);
|
||||
|
||||
NestedField = FieldRecord->getField(FD);
|
||||
assert(NestedField);
|
||||
|
||||
NestedFieldOffset += NestedField->Offset;
|
||||
}
|
||||
assert(NestedField);
|
||||
|
||||
if (!emitFieldInitializer(NestedField, NestedFieldOffset, InitExpr))
|
||||
return false;
|
||||
} else {
|
||||
assert(Init->isDelegatingInitializer());
|
||||
if (!this->emitThis(InitExpr))
|
||||
@ -262,7 +282,7 @@ bool ByteCodeStmtGen<Emitter>::visitStmt(const Stmt *S) {
|
||||
default: {
|
||||
if (auto *Exp = dyn_cast<Expr>(S))
|
||||
return this->discard(Exp);
|
||||
return this->bail(S);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -30,18 +30,8 @@ Context::~Context() {}
|
||||
bool Context::isPotentialConstantExpr(State &Parent, const FunctionDecl *FD) {
|
||||
assert(Stk.empty());
|
||||
Function *Func = P->getFunction(FD);
|
||||
if (!Func || !Func->hasBody()) {
|
||||
if (auto R = ByteCodeStmtGen<ByteCodeEmitter>(*this, *P).compileFunc(FD)) {
|
||||
Func = *R;
|
||||
} else {
|
||||
handleAllErrors(R.takeError(), [&Parent](ByteCodeGenError &Err) {
|
||||
Parent.FFDiag(Err.getRange().getBegin(),
|
||||
diag::err_experimental_clang_interp_failed)
|
||||
<< Err.getRange();
|
||||
});
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (!Func || !Func->hasBody())
|
||||
Func = ByteCodeStmtGen<ByteCodeEmitter>(*this, *P).compileFunc(FD);
|
||||
|
||||
APValue DummyResult;
|
||||
if (!Run(Parent, Func, DummyResult)) {
|
||||
@ -54,36 +44,90 @@ bool Context::isPotentialConstantExpr(State &Parent, const FunctionDecl *FD) {
|
||||
bool Context::evaluateAsRValue(State &Parent, const Expr *E, APValue &Result) {
|
||||
assert(Stk.empty());
|
||||
ByteCodeExprGen<EvalEmitter> C(*this, *P, Parent, Stk, Result);
|
||||
if (Check(Parent, C.interpretExpr(E))) {
|
||||
assert(Stk.empty());
|
||||
#ifndef NDEBUG
|
||||
// Make sure we don't rely on some value being still alive in
|
||||
// InterpStack memory.
|
||||
|
||||
auto Res = C.interpretExpr(E);
|
||||
|
||||
if (Res.isInvalid()) {
|
||||
Stk.clear();
|
||||
#endif
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
assert(Stk.empty());
|
||||
#ifndef NDEBUG
|
||||
// Make sure we don't rely on some value being still alive in
|
||||
// InterpStack memory.
|
||||
Stk.clear();
|
||||
return false;
|
||||
#endif
|
||||
|
||||
// Implicit lvalue-to-rvalue conversion.
|
||||
if (E->isGLValue()) {
|
||||
std::optional<APValue> RValueResult = Res.toRValue();
|
||||
if (!RValueResult) {
|
||||
return false;
|
||||
}
|
||||
Result = *RValueResult;
|
||||
} else {
|
||||
Result = Res.toAPValue();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Context::evaluate(State &Parent, const Expr *E, APValue &Result) {
|
||||
assert(Stk.empty());
|
||||
ByteCodeExprGen<EvalEmitter> C(*this, *P, Parent, Stk, Result);
|
||||
|
||||
auto Res = C.interpretExpr(E);
|
||||
if (Res.isInvalid()) {
|
||||
Stk.clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
assert(Stk.empty());
|
||||
#ifndef NDEBUG
|
||||
// Make sure we don't rely on some value being still alive in
|
||||
// InterpStack memory.
|
||||
Stk.clear();
|
||||
#endif
|
||||
Result = Res.toAPValue();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Context::evaluateAsInitializer(State &Parent, const VarDecl *VD,
|
||||
APValue &Result) {
|
||||
assert(Stk.empty());
|
||||
ByteCodeExprGen<EvalEmitter> C(*this, *P, Parent, Stk, Result);
|
||||
if (Check(Parent, C.interpretDecl(VD))) {
|
||||
assert(Stk.empty());
|
||||
#ifndef NDEBUG
|
||||
// Make sure we don't rely on some value being still alive in
|
||||
// InterpStack memory.
|
||||
|
||||
auto Res = C.interpretDecl(VD);
|
||||
if (Res.isInvalid()) {
|
||||
Stk.clear();
|
||||
#endif
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
assert(Stk.empty());
|
||||
#ifndef NDEBUG
|
||||
// Make sure we don't rely on some value being still alive in
|
||||
// InterpStack memory.
|
||||
Stk.clear();
|
||||
return false;
|
||||
#endif
|
||||
|
||||
// Ensure global variables are fully initialized.
|
||||
if (shouldBeGloballyIndexed(VD) && !Res.isInvalid() &&
|
||||
(VD->getType()->isRecordType() || VD->getType()->isArrayType())) {
|
||||
assert(Res.isLValue());
|
||||
|
||||
if (!Res.checkFullyInitialized(C.getState()))
|
||||
return false;
|
||||
|
||||
// lvalue-to-rvalue conversion.
|
||||
std::optional<APValue> RValueResult = Res.toRValue();
|
||||
if (!RValueResult)
|
||||
return false;
|
||||
Result = *RValueResult;
|
||||
|
||||
} else
|
||||
Result = Res.toAPValue();
|
||||
return true;
|
||||
}
|
||||
|
||||
const LangOptions &Context::getLangOpts() const { return Ctx.getLangOpts(); }
|
||||
@ -234,12 +278,8 @@ const Function *Context::getOrCreateFunction(const FunctionDecl *FD) {
|
||||
return Func;
|
||||
|
||||
if (!Func || WasNotDefined) {
|
||||
if (auto R = ByteCodeStmtGen<ByteCodeEmitter>(*this, *P).compileFunc(FD))
|
||||
Func = *R;
|
||||
else {
|
||||
llvm::consumeError(R.takeError());
|
||||
return nullptr;
|
||||
}
|
||||
if (auto F = ByteCodeStmtGen<ByteCodeEmitter>(*this, *P).compileFunc(FD))
|
||||
Func = F;
|
||||
}
|
||||
|
||||
return Func;
|
||||
|
@ -51,6 +51,9 @@ public:
|
||||
/// Evaluates a toplevel expression as an rvalue.
|
||||
bool evaluateAsRValue(State &Parent, const Expr *E, APValue &Result);
|
||||
|
||||
/// Like evaluateAsRvalue(), but does no implicit lvalue-to-rvalue conversion.
|
||||
bool evaluate(State &Parent, const Expr *E, APValue &Result);
|
||||
|
||||
/// Evaluates a toplevel initializer.
|
||||
bool evaluateAsInitializer(State &Parent, const VarDecl *VD, APValue &Result);
|
||||
|
||||
|
@ -19,7 +19,7 @@ using namespace clang::interp;
|
||||
|
||||
EvalEmitter::EvalEmitter(Context &Ctx, Program &P, State &Parent,
|
||||
InterpStack &Stk, APValue &Result)
|
||||
: Ctx(Ctx), P(P), S(Parent, P, Stk, Ctx, this), Result(Result) {
|
||||
: Ctx(Ctx), P(P), S(Parent, P, Stk, Ctx, this), EvalResult(&Ctx) {
|
||||
// Create a dummy frame for the interpreter which does not have locals.
|
||||
S.Current =
|
||||
new InterpFrame(S, /*Func=*/nullptr, /*Caller=*/nullptr, CodePtr());
|
||||
@ -33,20 +33,22 @@ EvalEmitter::~EvalEmitter() {
|
||||
}
|
||||
}
|
||||
|
||||
llvm::Expected<bool> EvalEmitter::interpretExpr(const Expr *E) {
|
||||
if (this->visitExpr(E))
|
||||
return true;
|
||||
if (BailLocation)
|
||||
return llvm::make_error<ByteCodeGenError>(*BailLocation);
|
||||
return false;
|
||||
EvaluationResult EvalEmitter::interpretExpr(const Expr *E) {
|
||||
EvalResult.setSource(E);
|
||||
|
||||
if (!this->visitExpr(E))
|
||||
EvalResult.setInvalid();
|
||||
|
||||
return std::move(this->EvalResult);
|
||||
}
|
||||
|
||||
llvm::Expected<bool> EvalEmitter::interpretDecl(const VarDecl *VD) {
|
||||
if (this->visitDecl(VD))
|
||||
return true;
|
||||
if (BailLocation)
|
||||
return llvm::make_error<ByteCodeGenError>(*BailLocation);
|
||||
return false;
|
||||
EvaluationResult EvalEmitter::interpretDecl(const VarDecl *VD) {
|
||||
EvalResult.setSource(VD);
|
||||
|
||||
if (!this->visitDecl(VD))
|
||||
EvalResult.setInvalid();
|
||||
|
||||
return std::move(this->EvalResult);
|
||||
}
|
||||
|
||||
void EvalEmitter::emitLabel(LabelTy Label) {
|
||||
@ -77,12 +79,6 @@ Scope::Local EvalEmitter::createLocal(Descriptor *D) {
|
||||
return {Off, D};
|
||||
}
|
||||
|
||||
bool EvalEmitter::bail(const SourceLocation &Loc) {
|
||||
if (!BailLocation)
|
||||
BailLocation = Loc;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool EvalEmitter::jumpTrue(const LabelTy &Label) {
|
||||
if (isActive()) {
|
||||
if (S.Stk.pop<bool>())
|
||||
@ -116,125 +112,37 @@ template <PrimType OpType> bool EvalEmitter::emitRet(const SourceInfo &Info) {
|
||||
if (!isActive())
|
||||
return true;
|
||||
using T = typename PrimConv<OpType>::T;
|
||||
return ReturnValue<T>(S.Stk.pop<T>(), Result);
|
||||
EvalResult.setValue(S.Stk.pop<T>().toAPValue());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EvalEmitter::emitRetVoid(const SourceInfo &Info) { return true; }
|
||||
template <> bool EvalEmitter::emitRet<PT_Ptr>(const SourceInfo &Info) {
|
||||
if (!isActive())
|
||||
return true;
|
||||
EvalResult.setPointer(S.Stk.pop<Pointer>());
|
||||
return true;
|
||||
}
|
||||
template <> bool EvalEmitter::emitRet<PT_FnPtr>(const SourceInfo &Info) {
|
||||
if (!isActive())
|
||||
return true;
|
||||
EvalResult.setFunctionPointer(S.Stk.pop<FunctionPointer>());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EvalEmitter::emitRetVoid(const SourceInfo &Info) {
|
||||
EvalResult.setValid();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EvalEmitter::emitRetValue(const SourceInfo &Info) {
|
||||
// Method to recursively traverse composites.
|
||||
std::function<bool(QualType, const Pointer &, APValue &)> Composite;
|
||||
Composite = [this, &Composite](QualType Ty, const Pointer &Ptr, APValue &R) {
|
||||
if (const auto *AT = Ty->getAs<AtomicType>())
|
||||
Ty = AT->getValueType();
|
||||
|
||||
if (const auto *RT = Ty->getAs<RecordType>()) {
|
||||
const auto *Record = Ptr.getRecord();
|
||||
assert(Record && "Missing record descriptor");
|
||||
|
||||
bool Ok = true;
|
||||
if (RT->getDecl()->isUnion()) {
|
||||
const FieldDecl *ActiveField = nullptr;
|
||||
APValue Value;
|
||||
for (const auto &F : Record->fields()) {
|
||||
const Pointer &FP = Ptr.atField(F.Offset);
|
||||
QualType FieldTy = F.Decl->getType();
|
||||
if (FP.isActive()) {
|
||||
if (std::optional<PrimType> T = Ctx.classify(FieldTy)) {
|
||||
TYPE_SWITCH(*T, Ok &= ReturnValue<T>(FP.deref<T>(), Value));
|
||||
} else {
|
||||
Ok &= Composite(FieldTy, FP, Value);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
R = APValue(ActiveField, Value);
|
||||
} else {
|
||||
unsigned NF = Record->getNumFields();
|
||||
unsigned NB = Record->getNumBases();
|
||||
unsigned NV = Ptr.isBaseClass() ? 0 : Record->getNumVirtualBases();
|
||||
|
||||
R = APValue(APValue::UninitStruct(), NB, NF);
|
||||
|
||||
for (unsigned I = 0; I < NF; ++I) {
|
||||
const Record::Field *FD = Record->getField(I);
|
||||
QualType FieldTy = FD->Decl->getType();
|
||||
const Pointer &FP = Ptr.atField(FD->Offset);
|
||||
APValue &Value = R.getStructField(I);
|
||||
|
||||
if (std::optional<PrimType> T = Ctx.classify(FieldTy)) {
|
||||
TYPE_SWITCH(*T, Ok &= ReturnValue<T>(FP.deref<T>(), Value));
|
||||
} else {
|
||||
Ok &= Composite(FieldTy, FP, Value);
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned I = 0; I < NB; ++I) {
|
||||
const Record::Base *BD = Record->getBase(I);
|
||||
QualType BaseTy = Ctx.getASTContext().getRecordType(BD->Decl);
|
||||
const Pointer &BP = Ptr.atField(BD->Offset);
|
||||
Ok &= Composite(BaseTy, BP, R.getStructBase(I));
|
||||
}
|
||||
|
||||
for (unsigned I = 0; I < NV; ++I) {
|
||||
const Record::Base *VD = Record->getVirtualBase(I);
|
||||
QualType VirtBaseTy = Ctx.getASTContext().getRecordType(VD->Decl);
|
||||
const Pointer &VP = Ptr.atField(VD->Offset);
|
||||
Ok &= Composite(VirtBaseTy, VP, R.getStructBase(NB + I));
|
||||
}
|
||||
}
|
||||
return Ok;
|
||||
}
|
||||
|
||||
if (Ty->isIncompleteArrayType()) {
|
||||
R = APValue(APValue::UninitArray(), 0, 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (const auto *AT = Ty->getAsArrayTypeUnsafe()) {
|
||||
const size_t NumElems = Ptr.getNumElems();
|
||||
QualType ElemTy = AT->getElementType();
|
||||
R = APValue(APValue::UninitArray{}, NumElems, NumElems);
|
||||
|
||||
bool Ok = true;
|
||||
for (unsigned I = 0; I < NumElems; ++I) {
|
||||
APValue &Slot = R.getArrayInitializedElt(I);
|
||||
const Pointer &EP = Ptr.atIndex(I);
|
||||
if (std::optional<PrimType> T = Ctx.classify(ElemTy)) {
|
||||
TYPE_SWITCH(*T, Ok &= ReturnValue<T>(EP.deref<T>(), Slot));
|
||||
} else {
|
||||
Ok &= Composite(ElemTy, EP.narrow(), Slot);
|
||||
}
|
||||
}
|
||||
return Ok;
|
||||
}
|
||||
|
||||
// Complex types.
|
||||
if (const auto *CT = Ty->getAs<ComplexType>()) {
|
||||
QualType ElemTy = CT->getElementType();
|
||||
std::optional<PrimType> ElemT = Ctx.classify(ElemTy);
|
||||
assert(ElemT);
|
||||
|
||||
if (ElemTy->isIntegerType()) {
|
||||
INT_TYPE_SWITCH(*ElemT, {
|
||||
auto V1 = Ptr.atIndex(0).deref<T>();
|
||||
auto V2 = Ptr.atIndex(1).deref<T>();
|
||||
Result = APValue(V1.toAPSInt(), V2.toAPSInt());
|
||||
return true;
|
||||
});
|
||||
} else if (ElemTy->isFloatingType()) {
|
||||
Result = APValue(Ptr.atIndex(0).deref<Floating>().getAPFloat(),
|
||||
Ptr.atIndex(1).deref<Floating>().getAPFloat());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
llvm_unreachable("invalid value to return");
|
||||
};
|
||||
|
||||
// Return the composite type.
|
||||
const auto &Ptr = S.Stk.pop<Pointer>();
|
||||
return Composite(Ptr.getType(), Ptr, Result);
|
||||
if (std::optional<APValue> APV = Ptr.toRValue(S.getCtx())) {
|
||||
EvalResult.setValue(*APV);
|
||||
return true;
|
||||
}
|
||||
|
||||
EvalResult.setInvalid();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool EvalEmitter::emitGetPtrLocal(uint32_t I, const SourceInfo &Info) {
|
||||
|
@ -13,6 +13,7 @@
|
||||
#ifndef LLVM_CLANG_AST_INTERP_EVALEMITTER_H
|
||||
#define LLVM_CLANG_AST_INTERP_EVALEMITTER_H
|
||||
|
||||
#include "EvaluationResult.h"
|
||||
#include "InterpState.h"
|
||||
#include "PrimType.h"
|
||||
#include "Source.h"
|
||||
@ -33,8 +34,10 @@ public:
|
||||
using AddrTy = uintptr_t;
|
||||
using Local = Scope::Local;
|
||||
|
||||
llvm::Expected<bool> interpretExpr(const Expr *E);
|
||||
llvm::Expected<bool> interpretDecl(const VarDecl *VD);
|
||||
EvaluationResult interpretExpr(const Expr *E);
|
||||
EvaluationResult interpretDecl(const VarDecl *VD);
|
||||
|
||||
InterpState &getState() { return S; }
|
||||
|
||||
protected:
|
||||
EvalEmitter(Context &Ctx, Program &P, State &Parent, InterpStack &Stk,
|
||||
@ -51,10 +54,6 @@ protected:
|
||||
virtual bool visitExpr(const Expr *E) = 0;
|
||||
virtual bool visitDecl(const VarDecl *VD) = 0;
|
||||
|
||||
bool bail(const Stmt *S) { return bail(S->getBeginLoc()); }
|
||||
bool bail(const Decl *D) { return bail(D->getBeginLoc()); }
|
||||
bool bail(const SourceLocation &Loc);
|
||||
|
||||
/// Emits jumps.
|
||||
bool jumpTrue(const LabelTy &Label);
|
||||
bool jumpFalse(const LabelTy &Label);
|
||||
@ -86,7 +85,7 @@ private:
|
||||
/// Callee evaluation state.
|
||||
InterpState S;
|
||||
/// Location to write the result to.
|
||||
APValue &Result;
|
||||
EvaluationResult EvalResult;
|
||||
|
||||
/// Temporaries which require storage.
|
||||
llvm::DenseMap<unsigned, std::unique_ptr<char[]>> Locals;
|
||||
@ -100,8 +99,6 @@ private:
|
||||
// The emitter always tracks the current instruction and sets OpPC to a token
|
||||
// value which is mapped to the location of the opcode being evaluated.
|
||||
CodePtr OpPC;
|
||||
/// Location of a failure.
|
||||
std::optional<SourceLocation> BailLocation;
|
||||
/// Location of the current instruction.
|
||||
SourceInfo CurrentSource;
|
||||
|
||||
|
196
contrib/llvm-project/clang/lib/AST/Interp/EvaluationResult.cpp
Normal file
196
contrib/llvm-project/clang/lib/AST/Interp/EvaluationResult.cpp
Normal file
@ -0,0 +1,196 @@
|
||||
//===----- EvaluationResult.cpp - Result class for the VM ------*- C++ -*-===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "EvaluationResult.h"
|
||||
#include "Context.h"
|
||||
#include "InterpState.h"
|
||||
#include "Record.h"
|
||||
#include "clang/AST/ExprCXX.h"
|
||||
|
||||
namespace clang {
|
||||
namespace interp {
|
||||
|
||||
APValue EvaluationResult::toAPValue() const {
|
||||
assert(!empty());
|
||||
switch (Kind) {
|
||||
case LValue:
|
||||
// Either a pointer or a function pointer.
|
||||
if (const auto *P = std::get_if<Pointer>(&Value))
|
||||
return P->toAPValue();
|
||||
else if (const auto *FP = std::get_if<FunctionPointer>(&Value))
|
||||
return FP->toAPValue();
|
||||
else
|
||||
llvm_unreachable("Unhandled LValue type");
|
||||
break;
|
||||
case RValue:
|
||||
return std::get<APValue>(Value);
|
||||
case Valid:
|
||||
return APValue();
|
||||
default:
|
||||
llvm_unreachable("Unhandled result kind?");
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<APValue> EvaluationResult::toRValue() const {
|
||||
if (Kind == RValue)
|
||||
return toAPValue();
|
||||
|
||||
assert(Kind == LValue);
|
||||
|
||||
// We have a pointer and want an RValue.
|
||||
if (const auto *P = std::get_if<Pointer>(&Value))
|
||||
return P->toRValue(*Ctx);
|
||||
else if (const auto *FP = std::get_if<FunctionPointer>(&Value)) // Nope
|
||||
return FP->toAPValue();
|
||||
llvm_unreachable("Unhandled lvalue kind");
|
||||
}
|
||||
|
||||
static void DiagnoseUninitializedSubobject(InterpState &S, SourceLocation Loc,
|
||||
const FieldDecl *SubObjDecl) {
|
||||
assert(SubObjDecl && "Subobject declaration does not exist");
|
||||
S.FFDiag(Loc, diag::note_constexpr_uninitialized)
|
||||
<< /*(name)*/ 1 << SubObjDecl;
|
||||
S.Note(SubObjDecl->getLocation(),
|
||||
diag::note_constexpr_subobject_declared_here);
|
||||
}
|
||||
|
||||
static bool CheckFieldsInitialized(InterpState &S, SourceLocation Loc,
|
||||
const Pointer &BasePtr, const Record *R);
|
||||
|
||||
static bool CheckArrayInitialized(InterpState &S, SourceLocation Loc,
|
||||
const Pointer &BasePtr,
|
||||
const ConstantArrayType *CAT) {
|
||||
bool Result = true;
|
||||
size_t NumElems = CAT->getSize().getZExtValue();
|
||||
QualType ElemType = CAT->getElementType();
|
||||
|
||||
if (ElemType->isRecordType()) {
|
||||
const Record *R = BasePtr.getElemRecord();
|
||||
for (size_t I = 0; I != NumElems; ++I) {
|
||||
Pointer ElemPtr = BasePtr.atIndex(I).narrow();
|
||||
Result &= CheckFieldsInitialized(S, Loc, ElemPtr, R);
|
||||
}
|
||||
} else if (const auto *ElemCAT = dyn_cast<ConstantArrayType>(ElemType)) {
|
||||
for (size_t I = 0; I != NumElems; ++I) {
|
||||
Pointer ElemPtr = BasePtr.atIndex(I).narrow();
|
||||
Result &= CheckArrayInitialized(S, Loc, ElemPtr, ElemCAT);
|
||||
}
|
||||
} else {
|
||||
for (size_t I = 0; I != NumElems; ++I) {
|
||||
if (!BasePtr.atIndex(I).isInitialized()) {
|
||||
DiagnoseUninitializedSubobject(S, Loc, BasePtr.getField());
|
||||
Result = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
static bool CheckFieldsInitialized(InterpState &S, SourceLocation Loc,
|
||||
const Pointer &BasePtr, const Record *R) {
|
||||
assert(R);
|
||||
bool Result = true;
|
||||
// Check all fields of this record are initialized.
|
||||
for (const Record::Field &F : R->fields()) {
|
||||
Pointer FieldPtr = BasePtr.atField(F.Offset);
|
||||
QualType FieldType = F.Decl->getType();
|
||||
|
||||
if (FieldType->isRecordType()) {
|
||||
Result &= CheckFieldsInitialized(S, Loc, FieldPtr, FieldPtr.getRecord());
|
||||
} else if (FieldType->isIncompleteArrayType()) {
|
||||
// Nothing to do here.
|
||||
} else if (FieldType->isArrayType()) {
|
||||
const auto *CAT =
|
||||
cast<ConstantArrayType>(FieldType->getAsArrayTypeUnsafe());
|
||||
Result &= CheckArrayInitialized(S, Loc, FieldPtr, CAT);
|
||||
} else if (!FieldPtr.isInitialized()) {
|
||||
DiagnoseUninitializedSubobject(S, Loc, F.Decl);
|
||||
Result = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Check Fields in all bases
|
||||
for (const Record::Base &B : R->bases()) {
|
||||
Pointer P = BasePtr.atField(B.Offset);
|
||||
if (!P.isInitialized()) {
|
||||
S.FFDiag(BasePtr.getDeclDesc()->asDecl()->getLocation(),
|
||||
diag::note_constexpr_uninitialized_base)
|
||||
<< B.Desc->getType();
|
||||
return false;
|
||||
}
|
||||
Result &= CheckFieldsInitialized(S, Loc, P, B.R);
|
||||
}
|
||||
|
||||
// TODO: Virtual bases
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
bool EvaluationResult::checkFullyInitialized(InterpState &S) const {
|
||||
assert(Source);
|
||||
assert(isLValue());
|
||||
|
||||
// Our Source must be a VarDecl.
|
||||
const Decl *SourceDecl = Source.dyn_cast<const Decl *>();
|
||||
assert(SourceDecl);
|
||||
const auto *VD = cast<VarDecl>(SourceDecl);
|
||||
assert(VD->getType()->isRecordType() || VD->getType()->isArrayType());
|
||||
SourceLocation InitLoc = VD->getAnyInitializer()->getExprLoc();
|
||||
|
||||
const Pointer &Ptr = *std::get_if<Pointer>(&Value);
|
||||
assert(!Ptr.isZero());
|
||||
|
||||
if (const Record *R = Ptr.getRecord())
|
||||
return CheckFieldsInitialized(S, InitLoc, Ptr, R);
|
||||
const auto *CAT =
|
||||
cast<ConstantArrayType>(Ptr.getType()->getAsArrayTypeUnsafe());
|
||||
return CheckArrayInitialized(S, InitLoc, Ptr, CAT);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void EvaluationResult::dump() const {
|
||||
assert(Ctx);
|
||||
auto &OS = llvm::errs();
|
||||
const ASTContext &ASTCtx = Ctx->getASTContext();
|
||||
|
||||
switch (Kind) {
|
||||
case Empty:
|
||||
OS << "Empty\n";
|
||||
break;
|
||||
case RValue:
|
||||
OS << "RValue: ";
|
||||
std::get<APValue>(Value).dump(OS, ASTCtx);
|
||||
break;
|
||||
case LValue: {
|
||||
assert(Source);
|
||||
QualType SourceType;
|
||||
if (const auto *D = Source.dyn_cast<const Decl *>()) {
|
||||
if (const auto *VD = dyn_cast<ValueDecl>(D))
|
||||
SourceType = VD->getType();
|
||||
} else if (const auto *E = Source.dyn_cast<const Expr *>()) {
|
||||
SourceType = E->getType();
|
||||
}
|
||||
|
||||
OS << "LValue: ";
|
||||
if (const auto *P = std::get_if<Pointer>(&Value))
|
||||
P->toAPValue().printPretty(OS, ASTCtx, SourceType);
|
||||
else if (const auto *FP = std::get_if<FunctionPointer>(&Value)) // Nope
|
||||
FP->toAPValue().printPretty(OS, ASTCtx, SourceType);
|
||||
OS << "\n";
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
llvm_unreachable("Can't print that.");
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace interp
|
||||
} // namespace clang
|
111
contrib/llvm-project/clang/lib/AST/Interp/EvaluationResult.h
Normal file
111
contrib/llvm-project/clang/lib/AST/Interp/EvaluationResult.h
Normal file
@ -0,0 +1,111 @@
|
||||
//===------ EvaluationResult.h - Result class for the VM -------*- C++ -*-===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_AST_INTERP_EVALUATION_RESULT_H
|
||||
#define LLVM_CLANG_AST_INTERP_EVALUATION_RESULT_H
|
||||
|
||||
#include "FunctionPointer.h"
|
||||
#include "Pointer.h"
|
||||
#include "clang/AST/APValue.h"
|
||||
#include "clang/AST/Decl.h"
|
||||
#include "clang/AST/Expr.h"
|
||||
#include <optional>
|
||||
#include <variant>
|
||||
|
||||
namespace clang {
|
||||
namespace interp {
|
||||
class EvalEmitter;
|
||||
class Context;
|
||||
|
||||
/// Defines the result of an evaluation.
|
||||
///
|
||||
/// The result might be in different forms--one of the pointer types,
|
||||
/// an APValue, or nothing.
|
||||
///
|
||||
/// We use this class to inspect and diagnose the result, as well as
|
||||
/// convert it to the requested form.
|
||||
class EvaluationResult final {
|
||||
public:
|
||||
enum ResultKind {
|
||||
Empty, // Initial state.
|
||||
LValue, // Result is an lvalue/pointer.
|
||||
RValue, // Result is an rvalue.
|
||||
Invalid, // Result is invalid.
|
||||
Valid, // Result is valid and empty.
|
||||
};
|
||||
|
||||
using DeclTy = llvm::PointerUnion<const Decl *, const Expr *>;
|
||||
|
||||
private:
|
||||
const Context *Ctx = nullptr;
|
||||
std::variant<std::monostate, Pointer, FunctionPointer, APValue> Value;
|
||||
ResultKind Kind = Empty;
|
||||
DeclTy Source = nullptr; // Currently only needed for dump().
|
||||
|
||||
EvaluationResult(ResultKind Kind) : Kind(Kind) {
|
||||
// Leave everything empty. Can be used as an
|
||||
// error marker or for void return values.
|
||||
assert(Kind == Valid || Kind == Invalid);
|
||||
}
|
||||
|
||||
void setSource(DeclTy D) { Source = D; }
|
||||
|
||||
void setValue(const APValue &V) {
|
||||
assert(empty());
|
||||
assert(!V.isLValue());
|
||||
Value = std::move(V);
|
||||
Kind = RValue;
|
||||
}
|
||||
void setPointer(const Pointer P) {
|
||||
assert(empty());
|
||||
Value = P;
|
||||
Kind = LValue;
|
||||
}
|
||||
void setFunctionPointer(const FunctionPointer &P) {
|
||||
assert(empty());
|
||||
Value = P;
|
||||
Kind = LValue;
|
||||
}
|
||||
void setInvalid() {
|
||||
assert(empty());
|
||||
Kind = Invalid;
|
||||
}
|
||||
void setValid() {
|
||||
assert(empty());
|
||||
Kind = Valid;
|
||||
}
|
||||
|
||||
public:
|
||||
EvaluationResult(const Context *Ctx) : Ctx(Ctx) {}
|
||||
|
||||
bool empty() const { return Kind == Empty; }
|
||||
bool isInvalid() const { return Kind == Invalid; }
|
||||
bool isLValue() const { return Kind == LValue; }
|
||||
bool isRValue() const { return Kind == RValue; }
|
||||
|
||||
/// Returns an APValue for the evaluation result. The returned
|
||||
/// APValue might be an LValue or RValue.
|
||||
APValue toAPValue() const;
|
||||
|
||||
/// If the result is an LValue, convert that to an RValue
|
||||
/// and return it. This may fail, e.g. if the result is an
|
||||
/// LValue and we can't read from it.
|
||||
std::optional<APValue> toRValue() const;
|
||||
|
||||
bool checkFullyInitialized(InterpState &S) const;
|
||||
|
||||
/// Dump to stderr.
|
||||
void dump() const;
|
||||
|
||||
friend class EvalEmitter;
|
||||
};
|
||||
|
||||
} // namespace interp
|
||||
} // namespace clang
|
||||
|
||||
#endif
|
@ -204,14 +204,18 @@ public:
|
||||
}
|
||||
|
||||
static bool rem(IntegralAP A, IntegralAP B, unsigned OpBits, IntegralAP *R) {
|
||||
// FIXME: Implement.
|
||||
assert(false);
|
||||
if constexpr (Signed)
|
||||
*R = IntegralAP(A.V.srem(B.V));
|
||||
else
|
||||
*R = IntegralAP(A.V.urem(B.V));
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool div(IntegralAP A, IntegralAP B, unsigned OpBits, IntegralAP *R) {
|
||||
// FIXME: Implement.
|
||||
assert(false);
|
||||
if constexpr (Signed)
|
||||
*R = IntegralAP(A.V.sdiv(B.V));
|
||||
else
|
||||
*R = IntegralAP(A.V.udiv(B.V));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -53,6 +53,25 @@ static bool Jf(InterpState &S, CodePtr &PC, int32_t Offset) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static void diagnoseNonConstVariable(InterpState &S, CodePtr OpPC,
|
||||
const ValueDecl *VD) {
|
||||
if (!S.getLangOpts().CPlusPlus)
|
||||
return;
|
||||
|
||||
const SourceInfo &Loc = S.Current->getSource(OpPC);
|
||||
|
||||
if (VD->getType()->isIntegralOrEnumerationType())
|
||||
S.FFDiag(Loc, diag::note_constexpr_ltor_non_const_int, 1) << VD;
|
||||
else
|
||||
S.FFDiag(Loc,
|
||||
S.getLangOpts().CPlusPlus11
|
||||
? diag::note_constexpr_ltor_non_constexpr
|
||||
: diag::note_constexpr_ltor_non_integral,
|
||||
1)
|
||||
<< VD << VD->getType();
|
||||
S.Note(VD->getLocation(), diag::note_declared_at);
|
||||
}
|
||||
|
||||
static bool CheckActive(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
|
||||
AccessKinds AK) {
|
||||
if (Ptr.isActive())
|
||||
@ -171,9 +190,7 @@ bool CheckExtern(InterpState &S, CodePtr OpPC, const Pointer &Ptr) {
|
||||
|
||||
if (!S.checkingPotentialConstantExpression() && S.getLangOpts().CPlusPlus) {
|
||||
const auto *VD = Ptr.getDeclDesc()->asValueDecl();
|
||||
const SourceInfo &Loc = S.Current->getSource(OpPC);
|
||||
S.FFDiag(Loc, diag::note_constexpr_ltor_non_constexpr, 1) << VD;
|
||||
S.Note(VD->getLocation(), diag::note_declared_at);
|
||||
diagnoseNonConstVariable(S, OpPC, VD);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -216,6 +233,44 @@ bool CheckLive(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CheckConstant(InterpState &S, CodePtr OpPC, const Descriptor *Desc) {
|
||||
assert(Desc);
|
||||
|
||||
auto IsConstType = [&S](const VarDecl *VD) -> bool {
|
||||
if (VD->isConstexpr())
|
||||
return true;
|
||||
|
||||
if (S.getLangOpts().CPlusPlus && !S.getLangOpts().CPlusPlus11)
|
||||
return false;
|
||||
|
||||
QualType T = VD->getType();
|
||||
if (T.isConstQualified())
|
||||
return true;
|
||||
|
||||
if (const auto *RT = T->getAs<ReferenceType>())
|
||||
return RT->getPointeeType().isConstQualified();
|
||||
|
||||
if (const auto *PT = T->getAs<PointerType>())
|
||||
return PT->getPointeeType().isConstQualified();
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
if (const auto *D = Desc->asValueDecl()) {
|
||||
if (const auto *VD = dyn_cast<VarDecl>(D);
|
||||
VD && VD->hasGlobalStorage() && !IsConstType(VD)) {
|
||||
diagnoseNonConstVariable(S, OpPC, VD);
|
||||
return S.inConstantContext();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool CheckConstant(InterpState &S, CodePtr OpPC, const Pointer &Ptr) {
|
||||
return CheckConstant(S, OpPC, Ptr.getDeclDesc());
|
||||
}
|
||||
|
||||
bool CheckDummy(InterpState &S, CodePtr OpPC, const Pointer &Ptr) {
|
||||
return !Ptr.isZero() && !Ptr.isDummy();
|
||||
}
|
||||
@ -304,6 +359,9 @@ bool CheckInitialized(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
|
||||
bool CheckLoad(InterpState &S, CodePtr OpPC, const Pointer &Ptr) {
|
||||
if (!CheckLive(S, OpPC, Ptr, AK_Read))
|
||||
return false;
|
||||
if (!CheckConstant(S, OpPC, Ptr))
|
||||
return false;
|
||||
|
||||
if (!CheckDummy(S, OpPC, Ptr))
|
||||
return false;
|
||||
if (!CheckExtern(S, OpPC, Ptr))
|
||||
@ -432,7 +490,7 @@ bool CheckThis(InterpState &S, CodePtr OpPC, const Pointer &This) {
|
||||
}
|
||||
|
||||
bool CheckPure(InterpState &S, CodePtr OpPC, const CXXMethodDecl *MD) {
|
||||
if (!MD->isPure())
|
||||
if (!MD->isPureVirtual())
|
||||
return true;
|
||||
const SourceInfo &E = S.Current->getSource(OpPC);
|
||||
S.FFDiag(E, diag::note_constexpr_pure_virtual_call, 1) << MD;
|
||||
@ -440,98 +498,6 @@ bool CheckPure(InterpState &S, CodePtr OpPC, const CXXMethodDecl *MD) {
|
||||
return false;
|
||||
}
|
||||
|
||||
static void DiagnoseUninitializedSubobject(InterpState &S, const SourceInfo &SI,
|
||||
const FieldDecl *SubObjDecl) {
|
||||
assert(SubObjDecl && "Subobject declaration does not exist");
|
||||
S.FFDiag(SI, diag::note_constexpr_uninitialized)
|
||||
<< /*(name)*/ 1 << SubObjDecl;
|
||||
S.Note(SubObjDecl->getLocation(),
|
||||
diag::note_constexpr_subobject_declared_here);
|
||||
}
|
||||
|
||||
static bool CheckFieldsInitialized(InterpState &S, CodePtr OpPC,
|
||||
const Pointer &BasePtr, const Record *R);
|
||||
|
||||
static bool CheckArrayInitialized(InterpState &S, CodePtr OpPC,
|
||||
const Pointer &BasePtr,
|
||||
const ConstantArrayType *CAT) {
|
||||
bool Result = true;
|
||||
size_t NumElems = CAT->getSize().getZExtValue();
|
||||
QualType ElemType = CAT->getElementType();
|
||||
|
||||
if (ElemType->isRecordType()) {
|
||||
const Record *R = BasePtr.getElemRecord();
|
||||
for (size_t I = 0; I != NumElems; ++I) {
|
||||
Pointer ElemPtr = BasePtr.atIndex(I).narrow();
|
||||
Result &= CheckFieldsInitialized(S, OpPC, ElemPtr, R);
|
||||
}
|
||||
} else if (const auto *ElemCAT = dyn_cast<ConstantArrayType>(ElemType)) {
|
||||
for (size_t I = 0; I != NumElems; ++I) {
|
||||
Pointer ElemPtr = BasePtr.atIndex(I).narrow();
|
||||
Result &= CheckArrayInitialized(S, OpPC, ElemPtr, ElemCAT);
|
||||
}
|
||||
} else {
|
||||
for (size_t I = 0; I != NumElems; ++I) {
|
||||
if (!BasePtr.atIndex(I).isInitialized()) {
|
||||
DiagnoseUninitializedSubobject(S, S.Current->getSource(OpPC),
|
||||
BasePtr.getField());
|
||||
Result = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
static bool CheckFieldsInitialized(InterpState &S, CodePtr OpPC,
|
||||
const Pointer &BasePtr, const Record *R) {
|
||||
assert(R);
|
||||
bool Result = true;
|
||||
// Check all fields of this record are initialized.
|
||||
for (const Record::Field &F : R->fields()) {
|
||||
Pointer FieldPtr = BasePtr.atField(F.Offset);
|
||||
QualType FieldType = F.Decl->getType();
|
||||
|
||||
if (FieldType->isRecordType()) {
|
||||
Result &= CheckFieldsInitialized(S, OpPC, FieldPtr, FieldPtr.getRecord());
|
||||
} else if (FieldType->isIncompleteArrayType()) {
|
||||
// Nothing to do here.
|
||||
} else if (FieldType->isArrayType()) {
|
||||
const auto *CAT =
|
||||
cast<ConstantArrayType>(FieldType->getAsArrayTypeUnsafe());
|
||||
Result &= CheckArrayInitialized(S, OpPC, FieldPtr, CAT);
|
||||
} else if (!FieldPtr.isInitialized()) {
|
||||
DiagnoseUninitializedSubobject(S, S.Current->getSource(OpPC), F.Decl);
|
||||
Result = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Check Fields in all bases
|
||||
for (const Record::Base &B : R->bases()) {
|
||||
Pointer P = BasePtr.atField(B.Offset);
|
||||
if (!P.isInitialized()) {
|
||||
S.FFDiag(BasePtr.getDeclDesc()->asDecl()->getLocation(),
|
||||
diag::note_constexpr_uninitialized_base)
|
||||
<< B.Desc->getType();
|
||||
return false;
|
||||
}
|
||||
Result &= CheckFieldsInitialized(S, OpPC, P, B.R);
|
||||
}
|
||||
|
||||
// TODO: Virtual bases
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
bool CheckCtorCall(InterpState &S, CodePtr OpPC, const Pointer &This) {
|
||||
assert(!This.isZero());
|
||||
if (const Record *R = This.getRecord())
|
||||
return CheckFieldsInitialized(S, OpPC, This, R);
|
||||
const auto *CAT =
|
||||
cast<ConstantArrayType>(This.getType()->getAsArrayTypeUnsafe());
|
||||
return CheckArrayInitialized(S, OpPC, This, CAT);
|
||||
}
|
||||
|
||||
bool CheckPotentialReinterpretCast(InterpState &S, CodePtr OpPC,
|
||||
const Pointer &Ptr) {
|
||||
if (!S.inConstantContext())
|
||||
@ -605,13 +571,7 @@ bool CheckDeclRef(InterpState &S, CodePtr OpPC, const DeclRefExpr *DR) {
|
||||
}
|
||||
} else if (const auto *VD = dyn_cast<VarDecl>(D)) {
|
||||
if (!VD->getType().isConstQualified()) {
|
||||
S.FFDiag(E,
|
||||
VD->getType()->isIntegralOrEnumerationType()
|
||||
? diag::note_constexpr_ltor_non_const_int
|
||||
: diag::note_constexpr_ltor_non_constexpr,
|
||||
1)
|
||||
<< VD;
|
||||
S.Note(VD->getLocation(), diag::note_declared_at) << VD->getSourceRange();
|
||||
diagnoseNonConstVariable(S, OpPC, VD);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -77,6 +77,9 @@ bool CheckSubobject(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
|
||||
/// Checks if a pointer points to const storage.
|
||||
bool CheckConst(InterpState &S, CodePtr OpPC, const Pointer &Ptr);
|
||||
|
||||
/// Checks if the Descriptor is of a constexpr or const global variable.
|
||||
bool CheckConstant(InterpState &S, CodePtr OpPC, const Descriptor *Desc);
|
||||
|
||||
/// Checks if a pointer points to a mutable field.
|
||||
bool CheckMutable(InterpState &S, CodePtr OpPC, const Pointer &Ptr);
|
||||
|
||||
@ -108,9 +111,6 @@ bool CheckThis(InterpState &S, CodePtr OpPC, const Pointer &This);
|
||||
/// Checks if a method is pure virtual.
|
||||
bool CheckPure(InterpState &S, CodePtr OpPC, const CXXMethodDecl *MD);
|
||||
|
||||
/// Checks that all fields are initialized after a constructor call.
|
||||
bool CheckCtorCall(InterpState &S, CodePtr OpPC, const Pointer &This);
|
||||
|
||||
/// Checks if reinterpret casts are legal in the current context.
|
||||
bool CheckPotentialReinterpretCast(InterpState &S, CodePtr OpPC,
|
||||
const Pointer &Ptr);
|
||||
@ -1004,12 +1004,23 @@ bool SetThisField(InterpState &S, CodePtr OpPC, uint32_t I) {
|
||||
template <PrimType Name, class T = typename PrimConv<Name>::T>
|
||||
bool GetGlobal(InterpState &S, CodePtr OpPC, uint32_t I) {
|
||||
const Block *B = S.P.getGlobal(I);
|
||||
|
||||
if (!CheckConstant(S, OpPC, B->getDescriptor()))
|
||||
return false;
|
||||
if (B->isExtern())
|
||||
return false;
|
||||
S.Stk.push<T>(B->deref<T>());
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Same as GetGlobal, but without the checks.
|
||||
template <PrimType Name, class T = typename PrimConv<Name>::T>
|
||||
bool GetGlobalUnchecked(InterpState &S, CodePtr OpPC, uint32_t I) {
|
||||
auto *B = S.P.getGlobal(I);
|
||||
S.Stk.push<T>(B->deref<T>());
|
||||
return true;
|
||||
}
|
||||
|
||||
template <PrimType Name, class T = typename PrimConv<Name>::T>
|
||||
bool SetGlobal(InterpState &S, CodePtr OpPC, uint32_t I) {
|
||||
// TODO: emit warning.
|
||||
@ -1047,8 +1058,12 @@ inline bool InitGlobalTempComp(InterpState &S, CodePtr OpPC,
|
||||
const Pointer &P = S.Stk.peek<Pointer>();
|
||||
APValue *Cached = Temp->getOrCreateValue(true);
|
||||
|
||||
*Cached = P.toRValue(S.getCtx());
|
||||
return true;
|
||||
if (std::optional<APValue> APV = P.toRValue(S.getCtx())) {
|
||||
*Cached = *APV;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
template <PrimType Name, class T = typename PrimConv<Name>::T>
|
||||
@ -1064,15 +1079,18 @@ bool InitThisField(InterpState &S, CodePtr OpPC, uint32_t I) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// FIXME: The Field pointer here is too much IMO and we could instead just
|
||||
// pass an Offset + BitWidth pair.
|
||||
template <PrimType Name, class T = typename PrimConv<Name>::T>
|
||||
bool InitThisBitField(InterpState &S, CodePtr OpPC, const Record::Field *F) {
|
||||
bool InitThisBitField(InterpState &S, CodePtr OpPC, const Record::Field *F,
|
||||
uint32_t FieldOffset) {
|
||||
assert(F->isBitField());
|
||||
if (S.checkingPotentialConstantExpression())
|
||||
return false;
|
||||
const Pointer &This = S.Current->getThis();
|
||||
if (!CheckThis(S, OpPC, This))
|
||||
return false;
|
||||
const Pointer &Field = This.atField(F->Offset);
|
||||
const Pointer &Field = This.atField(FieldOffset);
|
||||
const auto &Value = S.Stk.pop<T>();
|
||||
Field.deref<T>() = Value.truncate(F->Decl->getBitWidthValue(S.getCtx()));
|
||||
Field.initialize();
|
||||
@ -1846,11 +1864,6 @@ inline bool ArrayElemPtrPop(InterpState &S, CodePtr OpPC) {
|
||||
return NarrowPtr(S, OpPC);
|
||||
}
|
||||
|
||||
inline bool CheckGlobalCtor(InterpState &S, CodePtr OpPC) {
|
||||
const Pointer &Obj = S.Stk.peek<Pointer>();
|
||||
return CheckCtorCall(S, OpPC, Obj);
|
||||
}
|
||||
|
||||
inline bool Call(InterpState &S, CodePtr OpPC, const Function *Func) {
|
||||
if (Func->hasThisPointer()) {
|
||||
size_t ThisOffset =
|
||||
|
@ -375,10 +375,9 @@ def GetLocal : AccessOpcode { let HasCustomEval = 1; }
|
||||
// [] -> [Pointer]
|
||||
def SetLocal : AccessOpcode { let HasCustomEval = 1; }
|
||||
|
||||
def CheckGlobalCtor : Opcode {}
|
||||
|
||||
// [] -> [Value]
|
||||
def GetGlobal : AccessOpcode;
|
||||
def GetGlobalUnchecked : AccessOpcode;
|
||||
// [Value] -> []
|
||||
def InitGlobal : AccessOpcode;
|
||||
// [Value] -> []
|
||||
@ -416,7 +415,11 @@ def InitThisField : AccessOpcode;
|
||||
// [Value] -> []
|
||||
def InitThisFieldActive : AccessOpcode;
|
||||
// [Value] -> []
|
||||
def InitThisBitField : BitFieldOpcode;
|
||||
def InitThisBitField : Opcode {
|
||||
let Types = [AluTypeClass];
|
||||
let Args = [ArgRecordField, ArgUint32];
|
||||
let HasGroup = 1;
|
||||
}
|
||||
// [Pointer, Value] -> []
|
||||
def InitField : AccessOpcode;
|
||||
// [Pointer, Value] -> []
|
||||
|
@ -231,33 +231,143 @@ bool Pointer::hasSameArray(const Pointer &A, const Pointer &B) {
|
||||
return hasSameBase(A, B) && A.Base == B.Base && A.getFieldDesc()->IsArray;
|
||||
}
|
||||
|
||||
APValue Pointer::toRValue(const Context &Ctx) const {
|
||||
// Primitives.
|
||||
if (getFieldDesc()->isPrimitive()) {
|
||||
PrimType PT = *Ctx.classify(getType());
|
||||
TYPE_SWITCH(PT, return deref<T>().toAPValue());
|
||||
llvm_unreachable("Unhandled PrimType?");
|
||||
}
|
||||
std::optional<APValue> Pointer::toRValue(const Context &Ctx) const {
|
||||
// Method to recursively traverse composites.
|
||||
std::function<bool(QualType, const Pointer &, APValue &)> Composite;
|
||||
Composite = [&Composite, &Ctx](QualType Ty, const Pointer &Ptr, APValue &R) {
|
||||
if (const auto *AT = Ty->getAs<AtomicType>())
|
||||
Ty = AT->getValueType();
|
||||
|
||||
// Invalid pointers.
|
||||
if (Ptr.isDummy() || !Ptr.isLive() ||
|
||||
(!Ptr.isUnknownSizeArray() && Ptr.isOnePastEnd()))
|
||||
return false;
|
||||
|
||||
// Primitive values.
|
||||
if (std::optional<PrimType> T = Ctx.classify(Ty)) {
|
||||
if (T == PT_Ptr || T == PT_FnPtr) {
|
||||
R = Ptr.toAPValue();
|
||||
} else {
|
||||
TYPE_SWITCH(*T, R = Ptr.deref<T>().toAPValue());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (const auto *RT = Ty->getAs<RecordType>()) {
|
||||
const auto *Record = Ptr.getRecord();
|
||||
assert(Record && "Missing record descriptor");
|
||||
|
||||
bool Ok = true;
|
||||
if (RT->getDecl()->isUnion()) {
|
||||
const FieldDecl *ActiveField = nullptr;
|
||||
APValue Value;
|
||||
for (const auto &F : Record->fields()) {
|
||||
const Pointer &FP = Ptr.atField(F.Offset);
|
||||
QualType FieldTy = F.Decl->getType();
|
||||
if (FP.isActive()) {
|
||||
if (std::optional<PrimType> T = Ctx.classify(FieldTy)) {
|
||||
TYPE_SWITCH(*T, Value = FP.deref<T>().toAPValue());
|
||||
} else {
|
||||
Ok &= Composite(FieldTy, FP, Value);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
R = APValue(ActiveField, Value);
|
||||
} else {
|
||||
unsigned NF = Record->getNumFields();
|
||||
unsigned NB = Record->getNumBases();
|
||||
unsigned NV = Ptr.isBaseClass() ? 0 : Record->getNumVirtualBases();
|
||||
|
||||
R = APValue(APValue::UninitStruct(), NB, NF);
|
||||
|
||||
for (unsigned I = 0; I < NF; ++I) {
|
||||
const Record::Field *FD = Record->getField(I);
|
||||
QualType FieldTy = FD->Decl->getType();
|
||||
const Pointer &FP = Ptr.atField(FD->Offset);
|
||||
APValue &Value = R.getStructField(I);
|
||||
|
||||
if (std::optional<PrimType> T = Ctx.classify(FieldTy)) {
|
||||
TYPE_SWITCH(*T, Value = FP.deref<T>().toAPValue());
|
||||
} else {
|
||||
Ok &= Composite(FieldTy, FP, Value);
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned I = 0; I < NB; ++I) {
|
||||
const Record::Base *BD = Record->getBase(I);
|
||||
QualType BaseTy = Ctx.getASTContext().getRecordType(BD->Decl);
|
||||
const Pointer &BP = Ptr.atField(BD->Offset);
|
||||
Ok &= Composite(BaseTy, BP, R.getStructBase(I));
|
||||
}
|
||||
|
||||
for (unsigned I = 0; I < NV; ++I) {
|
||||
const Record::Base *VD = Record->getVirtualBase(I);
|
||||
QualType VirtBaseTy = Ctx.getASTContext().getRecordType(VD->Decl);
|
||||
const Pointer &VP = Ptr.atField(VD->Offset);
|
||||
Ok &= Composite(VirtBaseTy, VP, R.getStructBase(NB + I));
|
||||
}
|
||||
}
|
||||
return Ok;
|
||||
}
|
||||
|
||||
if (Ty->isIncompleteArrayType()) {
|
||||
R = APValue(APValue::UninitArray(), 0, 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (const auto *AT = Ty->getAsArrayTypeUnsafe()) {
|
||||
const size_t NumElems = Ptr.getNumElems();
|
||||
QualType ElemTy = AT->getElementType();
|
||||
R = APValue(APValue::UninitArray{}, NumElems, NumElems);
|
||||
|
||||
bool Ok = true;
|
||||
for (unsigned I = 0; I < NumElems; ++I) {
|
||||
APValue &Slot = R.getArrayInitializedElt(I);
|
||||
const Pointer &EP = Ptr.atIndex(I);
|
||||
if (std::optional<PrimType> T = Ctx.classify(ElemTy)) {
|
||||
TYPE_SWITCH(*T, Slot = EP.deref<T>().toAPValue());
|
||||
} else {
|
||||
Ok &= Composite(ElemTy, EP.narrow(), Slot);
|
||||
}
|
||||
}
|
||||
return Ok;
|
||||
}
|
||||
|
||||
// Complex types.
|
||||
if (const auto *CT = Ty->getAs<ComplexType>()) {
|
||||
QualType ElemTy = CT->getElementType();
|
||||
std::optional<PrimType> ElemT = Ctx.classify(ElemTy);
|
||||
assert(ElemT);
|
||||
|
||||
if (ElemTy->isIntegerType()) {
|
||||
INT_TYPE_SWITCH(*ElemT, {
|
||||
auto V1 = Ptr.atIndex(0).deref<T>();
|
||||
auto V2 = Ptr.atIndex(1).deref<T>();
|
||||
R = APValue(V1.toAPSInt(), V2.toAPSInt());
|
||||
return true;
|
||||
});
|
||||
} else if (ElemTy->isFloatingType()) {
|
||||
R = APValue(Ptr.atIndex(0).deref<Floating>().getAPFloat(),
|
||||
Ptr.atIndex(1).deref<Floating>().getAPFloat());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
llvm_unreachable("invalid value to return");
|
||||
};
|
||||
|
||||
if (isZero())
|
||||
return APValue(static_cast<Expr *>(nullptr), CharUnits::Zero(), {}, false,
|
||||
true);
|
||||
|
||||
if (isDummy() || !isLive())
|
||||
return std::nullopt;
|
||||
|
||||
// Return the composite type.
|
||||
APValue Result;
|
||||
// Records.
|
||||
if (getFieldDesc()->isRecord()) {
|
||||
const Record *R = getRecord();
|
||||
Result =
|
||||
APValue(APValue::UninitStruct(), R->getNumBases(), R->getNumFields());
|
||||
|
||||
for (unsigned I = 0; I != R->getNumFields(); ++I) {
|
||||
const Pointer &FieldPtr = this->atField(R->getField(I)->Offset);
|
||||
Result.getStructField(I) = FieldPtr.toRValue(Ctx);
|
||||
}
|
||||
|
||||
for (unsigned I = 0; I != R->getNumBases(); ++I) {
|
||||
const Pointer &BasePtr = this->atField(R->getBase(I)->Offset);
|
||||
Result.getStructBase(I) = BasePtr.toRValue(Ctx);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Arrays
|
||||
|
||||
if (!Composite(getType(), *this, Result))
|
||||
return std::nullopt;
|
||||
return Result;
|
||||
}
|
||||
|
@ -98,7 +98,7 @@ public:
|
||||
}
|
||||
|
||||
/// Converts the pointer to an APValue that is an rvalue.
|
||||
APValue toRValue(const Context &Ctx) const;
|
||||
std::optional<APValue> toRValue(const Context &Ctx) const;
|
||||
|
||||
/// Offsets a pointer inside an array.
|
||||
[[nodiscard]] Pointer atIndex(unsigned Idx) const {
|
||||
@ -379,6 +379,7 @@ public:
|
||||
return *reinterpret_cast<T *>(Pointee->rawData() + Base +
|
||||
sizeof(InitMapPtr));
|
||||
|
||||
assert(Offset + sizeof(T) <= Pointee->getDescriptor()->getAllocSize());
|
||||
return *reinterpret_cast<T *>(Pointee->rawData() + Offset);
|
||||
}
|
||||
|
||||
|
@ -4833,9 +4833,23 @@ recurse:
|
||||
E = cast<CXXStdInitializerListExpr>(E)->getSubExpr();
|
||||
goto recurse;
|
||||
|
||||
case Expr::SubstNonTypeTemplateParmExprClass:
|
||||
case Expr::SubstNonTypeTemplateParmExprClass: {
|
||||
// Mangle a substituted parameter the same way we mangle the template
|
||||
// argument.
|
||||
auto *SNTTPE = cast<SubstNonTypeTemplateParmExpr>(E);
|
||||
if (auto *CE = dyn_cast<ConstantExpr>(SNTTPE->getReplacement())) {
|
||||
// Pull out the constant value and mangle it as a template argument.
|
||||
QualType ParamType = SNTTPE->getParameterType(Context.getASTContext());
|
||||
assert(CE->hasAPValueResult() && "expected the NTTP to have an APValue");
|
||||
mangleValueInTemplateArg(ParamType, CE->getAPValueResult(), false,
|
||||
/*NeedExactType=*/true);
|
||||
break;
|
||||
}
|
||||
// The remaining cases all happen to be substituted with expressions that
|
||||
// mangle the same as a corresponding template argument anyway.
|
||||
E = cast<SubstNonTypeTemplateParmExpr>(E)->getReplacement();
|
||||
goto recurse;
|
||||
}
|
||||
|
||||
case Expr::UserDefinedLiteralClass:
|
||||
// We follow g++'s approach of mangling a UDL as a call to the literal
|
||||
@ -4883,7 +4897,7 @@ recurse:
|
||||
Out << '_';
|
||||
mangleType(New->getAllocatedType());
|
||||
if (New->hasInitializer()) {
|
||||
if (New->getInitializationStyle() == CXXNewInitializationStyle::List)
|
||||
if (New->getInitializationStyle() == CXXNewInitializationStyle::Braces)
|
||||
Out << "il";
|
||||
else
|
||||
Out << "pi";
|
||||
@ -4898,7 +4912,7 @@ recurse:
|
||||
for (unsigned i = 0, e = PLE->getNumExprs(); i != e; ++i)
|
||||
mangleExpression(PLE->getExpr(i));
|
||||
} else if (New->getInitializationStyle() ==
|
||||
CXXNewInitializationStyle::List &&
|
||||
CXXNewInitializationStyle::Braces &&
|
||||
isa<InitListExpr>(Init)) {
|
||||
// Only take InitListExprs apart for list-initialization.
|
||||
mangleInitListElements(cast<InitListExpr>(Init));
|
||||
@ -6064,6 +6078,11 @@ void CXXNameMangler::mangleTemplateArg(TemplateArgument A, bool NeedExactType) {
|
||||
mangleNullPointer(A.getNullPtrType());
|
||||
break;
|
||||
}
|
||||
case TemplateArgument::StructuralValue:
|
||||
mangleValueInTemplateArg(A.getStructuralValueType(),
|
||||
A.getAsStructuralValue(),
|
||||
/*TopLevel=*/true, NeedExactType);
|
||||
break;
|
||||
case TemplateArgument::Pack: {
|
||||
// <template-arg> ::= J <template-arg>* E
|
||||
Out << 'J';
|
||||
@ -6472,7 +6491,20 @@ void CXXNameMangler::mangleValueInTemplateArg(QualType T, const APValue &V,
|
||||
Out << "plcvPcad";
|
||||
Kind = Offset;
|
||||
} else {
|
||||
if (!V.getLValuePath().empty() || V.isLValueOnePastTheEnd()) {
|
||||
// Clang 11 and before mangled an array subject to array-to-pointer decay
|
||||
// as if it were the declaration itself.
|
||||
bool IsArrayToPointerDecayMangledAsDecl = false;
|
||||
if (TopLevel && Ctx.getLangOpts().getClangABICompat() <=
|
||||
LangOptions::ClangABI::Ver11) {
|
||||
QualType BType = B.getType();
|
||||
IsArrayToPointerDecayMangledAsDecl =
|
||||
BType->isArrayType() && V.getLValuePath().size() == 1 &&
|
||||
V.getLValuePath()[0].getAsArrayIndex() == 0 &&
|
||||
Ctx.hasSimilarType(T, Ctx.getDecayedType(BType));
|
||||
}
|
||||
|
||||
if ((!V.getLValuePath().empty() || V.isLValueOnePastTheEnd()) &&
|
||||
!IsArrayToPointerDecayMangledAsDecl) {
|
||||
NotPrimaryExpr();
|
||||
// A final conversion to the template parameter's type is usually
|
||||
// folded into the 'so' mangling, but we can't do that for 'void*'
|
||||
|
@ -930,7 +930,7 @@ void JSONNodeDumper::VisitFunctionDecl(const FunctionDecl *FD) {
|
||||
JOS.attribute("storageClass", VarDecl::getStorageClassSpecifierString(SC));
|
||||
attributeOnlyIfTrue("inline", FD->isInlineSpecified());
|
||||
attributeOnlyIfTrue("virtual", FD->isVirtualAsWritten());
|
||||
attributeOnlyIfTrue("pure", FD->isPure());
|
||||
attributeOnlyIfTrue("pure", FD->isPureVirtual());
|
||||
attributeOnlyIfTrue("explicitlyDeleted", FD->isDeletedAsWritten());
|
||||
attributeOnlyIfTrue("constexpr", FD->isConstexpr());
|
||||
attributeOnlyIfTrue("variadic", FD->isVariadic());
|
||||
@ -1356,12 +1356,11 @@ void JSONNodeDumper::VisitCXXNewExpr(const CXXNewExpr *NE) {
|
||||
attributeOnlyIfTrue("isPlacement", NE->getNumPlacementArgs() != 0);
|
||||
switch (NE->getInitializationStyle()) {
|
||||
case CXXNewInitializationStyle::None:
|
||||
case CXXNewInitializationStyle::Implicit:
|
||||
break;
|
||||
case CXXNewInitializationStyle::Call:
|
||||
case CXXNewInitializationStyle::Parens:
|
||||
JOS.attribute("initStyle", "call");
|
||||
break;
|
||||
case CXXNewInitializationStyle::List:
|
||||
case CXXNewInitializationStyle::Braces:
|
||||
JOS.attribute("initStyle", "list");
|
||||
break;
|
||||
}
|
||||
|
@ -464,7 +464,7 @@ public:
|
||||
SmallString<40> Mangled;
|
||||
auto Prefix = getClassSymbolPrefix(Kind, OCD->getASTContext());
|
||||
llvm::Mangler::getNameWithPrefix(Mangled, Prefix + ClassName, DL);
|
||||
return std::string(Mangled.str());
|
||||
return std::string(Mangled);
|
||||
};
|
||||
|
||||
return {
|
||||
|
@ -337,6 +337,7 @@ class MicrosoftCXXNameMangler {
|
||||
|
||||
public:
|
||||
enum QualifierMangleMode { QMM_Drop, QMM_Mangle, QMM_Escape, QMM_Result };
|
||||
enum class TplArgKind { ClassNTTP, StructuralValue };
|
||||
|
||||
MicrosoftCXXNameMangler(MicrosoftMangleContextImpl &C, raw_ostream &Out_)
|
||||
: Context(C), Out(Out_), Structor(nullptr), StructorType(-1),
|
||||
@ -453,7 +454,7 @@ private:
|
||||
const TemplateArgumentList &TemplateArgs);
|
||||
void mangleTemplateArg(const TemplateDecl *TD, const TemplateArgument &TA,
|
||||
const NamedDecl *Parm);
|
||||
void mangleTemplateArgValue(QualType T, const APValue &V,
|
||||
void mangleTemplateArgValue(QualType T, const APValue &V, TplArgKind,
|
||||
bool WithScalarType = false);
|
||||
|
||||
void mangleObjCProtocol(const ObjCProtocolDecl *PD);
|
||||
@ -1088,7 +1089,7 @@ void MicrosoftCXXNameMangler::mangleUnqualifiedName(GlobalDecl GD,
|
||||
if (const auto *TPO = dyn_cast<TemplateParamObjectDecl>(ND)) {
|
||||
Out << "?__N";
|
||||
mangleTemplateArgValue(TPO->getType().getUnqualifiedType(),
|
||||
TPO->getValue());
|
||||
TPO->getValue(), TplArgKind::ClassNTTP);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1604,6 +1605,22 @@ void MicrosoftCXXNameMangler::mangleTemplateArgs(
|
||||
}
|
||||
}
|
||||
|
||||
/// If value V (with type T) represents a decayed pointer to the first element
|
||||
/// of an array, return that array.
|
||||
static ValueDecl *getAsArrayToPointerDecayedDecl(QualType T, const APValue &V) {
|
||||
// Must be a pointer...
|
||||
if (!T->isPointerType() || !V.isLValue() || !V.hasLValuePath() ||
|
||||
!V.getLValueBase())
|
||||
return nullptr;
|
||||
// ... to element 0 of an array.
|
||||
QualType BaseT = V.getLValueBase().getType();
|
||||
if (!BaseT->isArrayType() || V.getLValuePath().size() != 1 ||
|
||||
V.getLValuePath()[0].getAsArrayIndex() != 0)
|
||||
return nullptr;
|
||||
return const_cast<ValueDecl *>(
|
||||
V.getLValueBase().dyn_cast<const ValueDecl *>());
|
||||
}
|
||||
|
||||
void MicrosoftCXXNameMangler::mangleTemplateArg(const TemplateDecl *TD,
|
||||
const TemplateArgument &TA,
|
||||
const NamedDecl *Parm) {
|
||||
@ -1669,7 +1686,7 @@ void MicrosoftCXXNameMangler::mangleTemplateArg(const TemplateDecl *TD,
|
||||
Out << "$";
|
||||
auto *TPO = cast<TemplateParamObjectDecl>(ND);
|
||||
mangleTemplateArgValue(TPO->getType().getUnqualifiedType(),
|
||||
TPO->getValue());
|
||||
TPO->getValue(), TplArgKind::ClassNTTP);
|
||||
} else {
|
||||
mangle(ND, "$1?");
|
||||
}
|
||||
@ -1712,6 +1729,27 @@ void MicrosoftCXXNameMangler::mangleTemplateArg(const TemplateDecl *TD,
|
||||
cast<NonTypeTemplateParmDecl>(Parm), T);
|
||||
break;
|
||||
}
|
||||
case TemplateArgument::StructuralValue:
|
||||
if (ValueDecl *D = getAsArrayToPointerDecayedDecl(
|
||||
TA.getStructuralValueType(), TA.getAsStructuralValue())) {
|
||||
// Mangle the result of array-to-pointer decay as if it were a reference
|
||||
// to the original declaration, to match MSVC's behavior. This can result
|
||||
// in mangling collisions in some cases!
|
||||
return mangleTemplateArg(
|
||||
TD, TemplateArgument(D, TA.getStructuralValueType()), Parm);
|
||||
}
|
||||
Out << "$";
|
||||
if (cast<NonTypeTemplateParmDecl>(Parm)
|
||||
->getType()
|
||||
->getContainedDeducedType()) {
|
||||
Out << "M";
|
||||
mangleType(TA.getNonTypeTemplateArgumentType(), SourceRange(), QMM_Drop);
|
||||
}
|
||||
mangleTemplateArgValue(TA.getStructuralValueType(),
|
||||
TA.getAsStructuralValue(),
|
||||
TplArgKind::StructuralValue,
|
||||
/*WithScalarType=*/false);
|
||||
break;
|
||||
case TemplateArgument::Expression:
|
||||
mangleExpression(TA.getAsExpr(), cast<NonTypeTemplateParmDecl>(Parm));
|
||||
break;
|
||||
@ -1754,6 +1792,7 @@ void MicrosoftCXXNameMangler::mangleTemplateArg(const TemplateDecl *TD,
|
||||
|
||||
void MicrosoftCXXNameMangler::mangleTemplateArgValue(QualType T,
|
||||
const APValue &V,
|
||||
TplArgKind TAK,
|
||||
bool WithScalarType) {
|
||||
switch (V.getKind()) {
|
||||
case APValue::None:
|
||||
@ -1806,7 +1845,7 @@ void MicrosoftCXXNameMangler::mangleTemplateArgValue(QualType T,
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (T->isPointerType())
|
||||
if (TAK == TplArgKind::ClassNTTP && T->isPointerType())
|
||||
Out << "5";
|
||||
|
||||
SmallVector<char, 2> EntryTypes;
|
||||
@ -1850,12 +1889,12 @@ void MicrosoftCXXNameMangler::mangleTemplateArgValue(QualType T,
|
||||
auto *VD = Base.dyn_cast<const ValueDecl*>();
|
||||
if (!VD)
|
||||
break;
|
||||
Out << "E";
|
||||
Out << (TAK == TplArgKind::ClassNTTP ? 'E' : '1');
|
||||
mangle(VD);
|
||||
|
||||
for (const std::function<void()> &Mangler : EntryManglers)
|
||||
Mangler();
|
||||
if (T->isPointerType())
|
||||
if (TAK == TplArgKind::ClassNTTP && T->isPointerType())
|
||||
Out << '@';
|
||||
}
|
||||
|
||||
@ -1869,11 +1908,18 @@ void MicrosoftCXXNameMangler::mangleTemplateArgValue(QualType T,
|
||||
const CXXRecordDecl *RD =
|
||||
T->castAs<MemberPointerType>()->getMostRecentCXXRecordDecl();
|
||||
const ValueDecl *D = V.getMemberPointerDecl();
|
||||
if (T->isMemberDataPointerType())
|
||||
mangleMemberDataPointerInClassNTTP(RD, D);
|
||||
else
|
||||
mangleMemberFunctionPointerInClassNTTP(RD,
|
||||
cast_or_null<CXXMethodDecl>(D));
|
||||
if (TAK == TplArgKind::ClassNTTP) {
|
||||
if (T->isMemberDataPointerType())
|
||||
mangleMemberDataPointerInClassNTTP(RD, D);
|
||||
else
|
||||
mangleMemberFunctionPointerInClassNTTP(RD,
|
||||
cast_or_null<CXXMethodDecl>(D));
|
||||
} else {
|
||||
if (T->isMemberDataPointerType())
|
||||
mangleMemberDataPointer(RD, D, "");
|
||||
else
|
||||
mangleMemberFunctionPointer(RD, cast_or_null<CXXMethodDecl>(D), "");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1885,11 +1931,11 @@ void MicrosoftCXXNameMangler::mangleTemplateArgValue(QualType T,
|
||||
|
||||
unsigned BaseIndex = 0;
|
||||
for (const CXXBaseSpecifier &B : RD->bases())
|
||||
mangleTemplateArgValue(B.getType(), V.getStructBase(BaseIndex++));
|
||||
mangleTemplateArgValue(B.getType(), V.getStructBase(BaseIndex++), TAK);
|
||||
for (const FieldDecl *FD : RD->fields())
|
||||
if (!FD->isUnnamedBitfield())
|
||||
mangleTemplateArgValue(FD->getType(),
|
||||
V.getStructField(FD->getFieldIndex()),
|
||||
V.getStructField(FD->getFieldIndex()), TAK,
|
||||
/*WithScalarType*/ true);
|
||||
Out << '@';
|
||||
return;
|
||||
@ -1900,7 +1946,7 @@ void MicrosoftCXXNameMangler::mangleTemplateArgValue(QualType T,
|
||||
mangleType(T, SourceRange(), QMM_Escape);
|
||||
if (const FieldDecl *FD = V.getUnionField()) {
|
||||
mangleUnqualifiedName(FD);
|
||||
mangleTemplateArgValue(FD->getType(), V.getUnionValue());
|
||||
mangleTemplateArgValue(FD->getType(), V.getUnionValue(), TAK);
|
||||
}
|
||||
Out << '@';
|
||||
return;
|
||||
@ -1932,7 +1978,7 @@ void MicrosoftCXXNameMangler::mangleTemplateArgValue(QualType T,
|
||||
const APValue &ElemV = I < V.getArrayInitializedElts()
|
||||
? V.getArrayInitializedElt(I)
|
||||
: V.getArrayFiller();
|
||||
mangleTemplateArgValue(ElemT, ElemV);
|
||||
mangleTemplateArgValue(ElemT, ElemV, TAK);
|
||||
Out << '@';
|
||||
}
|
||||
Out << '@';
|
||||
@ -1949,7 +1995,7 @@ void MicrosoftCXXNameMangler::mangleTemplateArgValue(QualType T,
|
||||
mangleType(ElemT, SourceRange(), QMM_Escape);
|
||||
for (unsigned I = 0, N = V.getVectorLength(); I != N; ++I) {
|
||||
const APValue &ElemV = V.getVectorElt(I);
|
||||
mangleTemplateArgValue(ElemT, ElemV);
|
||||
mangleTemplateArgValue(ElemT, ElemV, TAK);
|
||||
Out << '@';
|
||||
}
|
||||
Out << "@@";
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user