Merge llvm-project main llvmorg-14-init-13186-g0c553cc1af2e
This updates llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp to llvmorg-14-init-13186-g0c553cc1af2e. PR: 261742 MFC after: 2 weeks
This commit is contained in:
commit
0eae32dcef
@ -240,7 +240,7 @@ class ObjCContextInfo : public CommonTypeInfo {
|
||||
}
|
||||
void setSwiftImportAsNonGeneric(llvm::Optional<bool> Value) {
|
||||
SwiftImportAsNonGenericSpecified = Value.hasValue();
|
||||
SwiftImportAsNonGeneric = Value.hasValue() ? *Value : false;
|
||||
SwiftImportAsNonGeneric = Value.getValueOr(false);
|
||||
}
|
||||
|
||||
llvm::Optional<bool> getSwiftObjCMembers() const {
|
||||
@ -249,7 +249,7 @@ class ObjCContextInfo : public CommonTypeInfo {
|
||||
}
|
||||
void setSwiftObjCMembers(llvm::Optional<bool> Value) {
|
||||
SwiftObjCMembersSpecified = Value.hasValue();
|
||||
SwiftObjCMembers = Value.hasValue() ? *Value : false;
|
||||
SwiftObjCMembers = Value.getValueOr(false);
|
||||
}
|
||||
|
||||
/// Strip off any information within the class information structure that is
|
||||
@ -368,7 +368,7 @@ class ObjCPropertyInfo : public VariableInfo {
|
||||
}
|
||||
void setSwiftImportAsAccessors(llvm::Optional<bool> Value) {
|
||||
SwiftImportAsAccessorsSpecified = Value.hasValue();
|
||||
SwiftImportAsAccessors = Value.hasValue() ? *Value : false;
|
||||
SwiftImportAsAccessors = Value.getValueOr(false);
|
||||
}
|
||||
|
||||
friend bool operator==(const ObjCPropertyInfo &, const ObjCPropertyInfo &);
|
||||
@ -433,7 +433,7 @@ class ParamInfo : public VariableInfo {
|
||||
}
|
||||
void setNoEscape(llvm::Optional<bool> Value) {
|
||||
NoEscapeSpecified = Value.hasValue();
|
||||
NoEscape = Value.hasValue() ? *Value : false;
|
||||
NoEscape = Value.getValueOr(false);
|
||||
}
|
||||
|
||||
llvm::Optional<RetainCountConventionKind> getRetainCountConvention() const {
|
||||
@ -671,7 +671,7 @@ class TagInfo : public CommonTypeInfo {
|
||||
}
|
||||
void setFlagEnum(llvm::Optional<bool> Value) {
|
||||
HasFlagEnum = Value.hasValue();
|
||||
IsFlagEnum = Value.hasValue() ? *Value : false;
|
||||
IsFlagEnum = Value.getValueOr(false);
|
||||
}
|
||||
|
||||
TagInfo &operator|=(const TagInfo &RHS) {
|
||||
|
@ -248,6 +248,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
mutable llvm::ContextualFoldingSet<TemplateSpecializationType, ASTContext&>
|
||||
TemplateSpecializationTypes;
|
||||
mutable llvm::FoldingSet<ParenType> ParenTypes;
|
||||
mutable llvm::FoldingSet<UsingType> UsingTypes;
|
||||
mutable llvm::FoldingSet<ElaboratedType> ElaboratedTypes;
|
||||
mutable llvm::FoldingSet<DependentNameType> DependentNameTypes;
|
||||
mutable llvm::ContextualFoldingSet<DependentTemplateSpecializationType,
|
||||
@ -264,8 +265,8 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
mutable llvm::FoldingSet<AtomicType> AtomicTypes;
|
||||
llvm::FoldingSet<AttributedType> AttributedTypes;
|
||||
mutable llvm::FoldingSet<PipeType> PipeTypes;
|
||||
mutable llvm::FoldingSet<ExtIntType> ExtIntTypes;
|
||||
mutable llvm::FoldingSet<DependentExtIntType> DependentExtIntTypes;
|
||||
mutable llvm::FoldingSet<BitIntType> BitIntTypes;
|
||||
mutable llvm::FoldingSet<DependentBitIntType> DependentBitIntTypes;
|
||||
|
||||
mutable llvm::FoldingSet<QualifiedTemplateName> QualifiedTemplateNames;
|
||||
mutable llvm::FoldingSet<DependentTemplateName> DependentTemplateNames;
|
||||
@ -1350,13 +1351,13 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
/// Return a write_only pipe type for the specified type.
|
||||
QualType getWritePipeType(QualType T) const;
|
||||
|
||||
/// Return an extended integer type with the specified signedness and bit
|
||||
/// Return a bit-precise integer type with the specified signedness and bit
|
||||
/// count.
|
||||
QualType getExtIntType(bool Unsigned, unsigned NumBits) const;
|
||||
QualType getBitIntType(bool Unsigned, unsigned NumBits) const;
|
||||
|
||||
/// Return a dependent extended integer type with the specified signedness and
|
||||
/// bit count.
|
||||
QualType getDependentExtIntType(bool Unsigned, Expr *BitsExpr) const;
|
||||
/// Return a dependent bit-precise integer type with the specified signedness
|
||||
/// and bit count.
|
||||
QualType getDependentBitIntType(bool Unsigned, Expr *BitsExpr) const;
|
||||
|
||||
/// Gets the struct used to keep track of the extended descriptor for
|
||||
/// pointer to blocks.
|
||||
@ -1555,6 +1556,9 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
return getTypeDeclTypeSlow(Decl);
|
||||
}
|
||||
|
||||
QualType getUsingType(const UsingShadowDecl *Found,
|
||||
QualType Underlying) const;
|
||||
|
||||
/// Return the unique reference to the type for the specified
|
||||
/// typedef-name decl.
|
||||
QualType getTypedefType(const TypedefNameDecl *Decl,
|
||||
@ -1564,6 +1568,9 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
|
||||
QualType getEnumType(const EnumDecl *Decl) const;
|
||||
|
||||
QualType
|
||||
getUnresolvedUsingType(const UnresolvedUsingTypenameDecl *Decl) const;
|
||||
|
||||
QualType getInjectedClassNameType(CXXRecordDecl *Decl, QualType TST) const;
|
||||
|
||||
QualType getAttributedType(attr::Kind attrKind,
|
||||
|
@ -9,6 +9,7 @@
|
||||
#ifndef LLVM_CLANG_AST_ASTDIAGNOSTIC_H
|
||||
#define LLVM_CLANG_AST_ASTDIAGNOSTIC_H
|
||||
|
||||
#include "clang/AST/Type.h"
|
||||
#include "clang/Basic/Diagnostic.h"
|
||||
#include "clang/Basic/DiagnosticAST.h"
|
||||
|
||||
@ -31,6 +32,11 @@ namespace clang {
|
||||
SmallVectorImpl<char> &Output,
|
||||
void *Cookie,
|
||||
ArrayRef<intptr_t> QualTypeVals);
|
||||
|
||||
/// Returns a desugared version of the QualType, and marks ShouldAKA as true
|
||||
/// whenever we remove significant sugar from the type.
|
||||
QualType desugarForDiagnostic(ASTContext &Context, QualType QT,
|
||||
bool &ShouldAKA);
|
||||
} // end namespace clang
|
||||
|
||||
#endif
|
||||
|
@ -75,6 +75,10 @@ class ASTImporterLookupTable {
|
||||
// The function should be called when the old context is definitely different
|
||||
// from the new.
|
||||
void update(NamedDecl *ND, DeclContext *OldDC);
|
||||
// Same as 'update' but allow if 'ND' is not in the table or the old context
|
||||
// is the same as the new.
|
||||
// FIXME: The old redeclaration context is not handled.
|
||||
void updateForced(NamedDecl *ND, DeclContext *OldDC);
|
||||
using LookupResult = DeclList;
|
||||
LookupResult lookup(DeclContext *DC, DeclarationName Name) const;
|
||||
// Check if the `ND` is within the lookup table (with its current name) in
|
||||
|
@ -21,7 +21,7 @@ inline T makeNullableFromOptional(const Optional<T> &value) {
|
||||
|
||||
template <class T>
|
||||
inline T *makePointerFromOptional(Optional<T *> value) {
|
||||
return (value ? *value : nullptr);
|
||||
return value.getValueOr(nullptr);
|
||||
}
|
||||
|
||||
// PropertyReader is a class concept that requires the following method:
|
||||
|
@ -1211,13 +1211,12 @@ class TemplateTypeParmDecl final : public TypeDecl,
|
||||
DefArgStorage DefaultArgument;
|
||||
|
||||
TemplateTypeParmDecl(DeclContext *DC, SourceLocation KeyLoc,
|
||||
SourceLocation IdLoc, IdentifierInfo *Id,
|
||||
bool Typename, bool HasTypeConstraint,
|
||||
Optional<unsigned> NumExpanded)
|
||||
SourceLocation IdLoc, IdentifierInfo *Id, bool Typename,
|
||||
bool HasTypeConstraint, Optional<unsigned> NumExpanded)
|
||||
: TypeDecl(TemplateTypeParm, DC, IdLoc, Id, KeyLoc), Typename(Typename),
|
||||
HasTypeConstraint(HasTypeConstraint), TypeConstraintInitialized(false),
|
||||
ExpandedParameterPack(NumExpanded),
|
||||
NumExpanded(NumExpanded ? *NumExpanded : 0) {}
|
||||
NumExpanded(NumExpanded.getValueOr(0)) {}
|
||||
|
||||
public:
|
||||
static TemplateTypeParmDecl *Create(const ASTContext &C, DeclContext *DC,
|
||||
|
@ -572,6 +572,12 @@ class Expr : public ValueStmt {
|
||||
bool isConstantInitializer(ASTContext &Ctx, bool ForRef,
|
||||
const Expr **Culprit = nullptr) const;
|
||||
|
||||
/// If this expression is an unambiguous reference to a single declaration,
|
||||
/// in the style of __builtin_function_start, return that declaration. Note
|
||||
/// that this may return a non-static member function or field in C++ if this
|
||||
/// expression is a member pointer constant.
|
||||
const ValueDecl *getAsBuiltinConstantDeclRef(const ASTContext &Context) const;
|
||||
|
||||
/// EvalStatus is a struct with detailed info about an evaluation in progress.
|
||||
struct EvalStatus {
|
||||
/// Whether the evaluated expression has side effects.
|
||||
|
@ -2224,6 +2224,47 @@ class OMPCaptureClause : public OMPClause {
|
||||
}
|
||||
};
|
||||
|
||||
/// This represents 'compare' clause in the '#pragma omp atomic'
|
||||
/// directive.
|
||||
///
|
||||
/// \code
|
||||
/// #pragma omp atomic compare
|
||||
/// \endcode
|
||||
/// In this example directive '#pragma omp atomic' has 'compare' clause.
|
||||
class OMPCompareClause final : public OMPClause {
|
||||
public:
|
||||
/// Build 'compare' clause.
|
||||
///
|
||||
/// \param StartLoc Starting location of the clause.
|
||||
/// \param EndLoc Ending location of the clause.
|
||||
OMPCompareClause(SourceLocation StartLoc, SourceLocation EndLoc)
|
||||
: OMPClause(llvm::omp::OMPC_compare, StartLoc, EndLoc) {}
|
||||
|
||||
/// Build an empty clause.
|
||||
OMPCompareClause()
|
||||
: OMPClause(llvm::omp::OMPC_compare, SourceLocation(), SourceLocation()) {
|
||||
}
|
||||
|
||||
child_range children() {
|
||||
return child_range(child_iterator(), child_iterator());
|
||||
}
|
||||
|
||||
const_child_range children() const {
|
||||
return const_child_range(const_child_iterator(), const_child_iterator());
|
||||
}
|
||||
|
||||
child_range used_children() {
|
||||
return child_range(child_iterator(), child_iterator());
|
||||
}
|
||||
const_child_range used_children() const {
|
||||
return const_child_range(const_child_iterator(), const_child_iterator());
|
||||
}
|
||||
|
||||
static bool classof(const OMPClause *T) {
|
||||
return T->getClauseKind() == llvm::omp::OMPC_compare;
|
||||
}
|
||||
};
|
||||
|
||||
/// This represents 'seq_cst' clause in the '#pragma omp atomic'
|
||||
/// directive.
|
||||
///
|
||||
|
@ -107,6 +107,8 @@ def DeclRef : RefPropertyType<"Decl"> { let ConstWhenWriting = 1; }
|
||||
SubclassPropertyType<"TemplateTypeParmDecl", DeclRef>;
|
||||
def TemplateTemplateParmDeclRef :
|
||||
SubclassPropertyType<"TemplateTemplateParmDecl", DeclRef>;
|
||||
def UsingShadowDeclRef :
|
||||
SubclassPropertyType<"UsingShadowDecl", DeclRef>;
|
||||
def ValueDeclRef :
|
||||
SubclassPropertyType<"ValueDecl", DeclRef>;
|
||||
def ElaboratedTypeKeyword : EnumPropertyType;
|
||||
|
@ -981,6 +981,7 @@ DEF_TRAVERSE_TYPE(FunctionProtoType, {
|
||||
TRY_TO(TraverseStmt(NE));
|
||||
})
|
||||
|
||||
DEF_TRAVERSE_TYPE(UsingType, {})
|
||||
DEF_TRAVERSE_TYPE(UnresolvedUsingType, {})
|
||||
DEF_TRAVERSE_TYPE(TypedefType, {})
|
||||
|
||||
@ -1072,8 +1073,8 @@ DEF_TRAVERSE_TYPE(AtomicType, { TRY_TO(TraverseType(T->getValueType())); })
|
||||
|
||||
DEF_TRAVERSE_TYPE(PipeType, { TRY_TO(TraverseType(T->getElementType())); })
|
||||
|
||||
DEF_TRAVERSE_TYPE(ExtIntType, {})
|
||||
DEF_TRAVERSE_TYPE(DependentExtIntType,
|
||||
DEF_TRAVERSE_TYPE(BitIntType, {})
|
||||
DEF_TRAVERSE_TYPE(DependentBitIntType,
|
||||
{ TRY_TO(TraverseStmt(T->getNumBitsExpr())); })
|
||||
|
||||
#undef DEF_TRAVERSE_TYPE
|
||||
@ -1252,6 +1253,7 @@ DEF_TRAVERSE_TYPELOC(FunctionProtoType, {
|
||||
TRY_TO(TraverseStmt(NE));
|
||||
})
|
||||
|
||||
DEF_TRAVERSE_TYPELOC(UsingType, {})
|
||||
DEF_TRAVERSE_TYPELOC(UnresolvedUsingType, {})
|
||||
DEF_TRAVERSE_TYPELOC(TypedefType, {})
|
||||
|
||||
@ -1358,8 +1360,8 @@ DEF_TRAVERSE_TYPELOC(AtomicType, { TRY_TO(TraverseTypeLoc(TL.getValueLoc())); })
|
||||
|
||||
DEF_TRAVERSE_TYPELOC(PipeType, { TRY_TO(TraverseTypeLoc(TL.getValueLoc())); })
|
||||
|
||||
DEF_TRAVERSE_TYPELOC(ExtIntType, {})
|
||||
DEF_TRAVERSE_TYPELOC(DependentExtIntType, {
|
||||
DEF_TRAVERSE_TYPELOC(BitIntType, {})
|
||||
DEF_TRAVERSE_TYPELOC(DependentBitIntType, {
|
||||
TRY_TO(TraverseStmt(TL.getTypePtr()->getNumBitsExpr()));
|
||||
})
|
||||
|
||||
@ -2095,7 +2097,13 @@ bool RecursiveASTVisitor<Derived>::TraverseFunctionHelper(FunctionDecl *D) {
|
||||
}
|
||||
|
||||
if (VisitBody) {
|
||||
TRY_TO(TraverseStmt(D->getBody())); // Function body.
|
||||
TRY_TO(TraverseStmt(D->getBody()));
|
||||
// Body may contain using declarations whose shadows are parented to the
|
||||
// FunctionDecl itself.
|
||||
for (auto *Child : D->decls()) {
|
||||
if (isa<UsingShadowDecl>(Child))
|
||||
TRY_TO(TraverseDecl(Child));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -3226,6 +3234,11 @@ bool RecursiveASTVisitor<Derived>::VisitOMPCaptureClause(OMPCaptureClause *) {
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Derived>
|
||||
bool RecursiveASTVisitor<Derived>::VisitOMPCompareClause(OMPCompareClause *) {
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Derived>
|
||||
bool RecursiveASTVisitor<Derived>::VisitOMPSeqCstClause(OMPSeqCstClause *) {
|
||||
return true;
|
||||
|
@ -311,6 +311,7 @@ class TextNodeDumper
|
||||
void VisitFunctionType(const FunctionType *T);
|
||||
void VisitFunctionProtoType(const FunctionProtoType *T);
|
||||
void VisitUnresolvedUsingType(const UnresolvedUsingType *T);
|
||||
void VisitUsingType(const UsingType *T);
|
||||
void VisitTypedefType(const TypedefType *T);
|
||||
void VisitUnaryTransformType(const UnaryTransformType *T);
|
||||
void VisitTagType(const TagType *T);
|
||||
|
@ -129,6 +129,7 @@ class TemplateArgumentLoc;
|
||||
class TemplateTypeParmDecl;
|
||||
class TypedefNameDecl;
|
||||
class UnresolvedUsingTypenameDecl;
|
||||
class UsingShadowDecl;
|
||||
|
||||
using CanQualType = CanQual<Type>;
|
||||
|
||||
@ -2128,7 +2129,7 @@ class alignas(8) Type : public ExtQualsTypeCommonBase {
|
||||
bool isOCLExtOpaqueType() const; // Any OpenCL extension type
|
||||
|
||||
bool isPipeType() const; // OpenCL pipe type
|
||||
bool isExtIntType() const; // Extended Int Type
|
||||
bool isBitIntType() const; // Bit-precise integer type
|
||||
bool isOpenCLSpecificType() const; // Any OpenCL specific type
|
||||
|
||||
/// Determines if this type, which must satisfy
|
||||
@ -4368,6 +4369,27 @@ class UnresolvedUsingType : public Type {
|
||||
}
|
||||
};
|
||||
|
||||
class UsingType : public Type, public llvm::FoldingSetNode {
|
||||
UsingShadowDecl *Found;
|
||||
friend class ASTContext; // ASTContext creates these.
|
||||
|
||||
UsingType(const UsingShadowDecl *Found, QualType Underlying, QualType Canon);
|
||||
|
||||
public:
|
||||
UsingShadowDecl *getFoundDecl() const { return Found; }
|
||||
QualType getUnderlyingType() const;
|
||||
|
||||
bool isSugared() const { return true; }
|
||||
QualType desugar() const { return getUnderlyingType(); }
|
||||
|
||||
void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, Found); }
|
||||
static void Profile(llvm::FoldingSetNodeID &ID,
|
||||
const UsingShadowDecl *Found) {
|
||||
ID.AddPointer(Found);
|
||||
}
|
||||
static bool classof(const Type *T) { return T->getTypeClass() == Using; }
|
||||
};
|
||||
|
||||
class TypedefType : public Type {
|
||||
TypedefNameDecl *Decl;
|
||||
|
||||
@ -6307,13 +6329,13 @@ class PipeType : public Type, public llvm::FoldingSetNode {
|
||||
};
|
||||
|
||||
/// A fixed int type of a specified bitwidth.
|
||||
class ExtIntType final : public Type, public llvm::FoldingSetNode {
|
||||
class BitIntType final : public Type, public llvm::FoldingSetNode {
|
||||
friend class ASTContext;
|
||||
unsigned IsUnsigned : 1;
|
||||
unsigned NumBits : 24;
|
||||
|
||||
protected:
|
||||
ExtIntType(bool isUnsigned, unsigned NumBits);
|
||||
BitIntType(bool isUnsigned, unsigned NumBits);
|
||||
|
||||
public:
|
||||
bool isUnsigned() const { return IsUnsigned; }
|
||||
@ -6333,16 +6355,16 @@ class ExtIntType final : public Type, public llvm::FoldingSetNode {
|
||||
ID.AddInteger(NumBits);
|
||||
}
|
||||
|
||||
static bool classof(const Type *T) { return T->getTypeClass() == ExtInt; }
|
||||
static bool classof(const Type *T) { return T->getTypeClass() == BitInt; }
|
||||
};
|
||||
|
||||
class DependentExtIntType final : public Type, public llvm::FoldingSetNode {
|
||||
class DependentBitIntType final : public Type, public llvm::FoldingSetNode {
|
||||
friend class ASTContext;
|
||||
const ASTContext &Context;
|
||||
llvm::PointerIntPair<Expr*, 1, bool> ExprAndUnsigned;
|
||||
|
||||
protected:
|
||||
DependentExtIntType(const ASTContext &Context, bool IsUnsigned,
|
||||
DependentBitIntType(const ASTContext &Context, bool IsUnsigned,
|
||||
Expr *NumBits);
|
||||
|
||||
public:
|
||||
@ -6360,7 +6382,7 @@ class DependentExtIntType final : public Type, public llvm::FoldingSetNode {
|
||||
bool IsUnsigned, Expr *NumBitsExpr);
|
||||
|
||||
static bool classof(const Type *T) {
|
||||
return T->getTypeClass() == DependentExtInt;
|
||||
return T->getTypeClass() == DependentBitInt;
|
||||
}
|
||||
};
|
||||
|
||||
@ -6891,8 +6913,8 @@ inline bool Type::isPipeType() const {
|
||||
return isa<PipeType>(CanonicalType);
|
||||
}
|
||||
|
||||
inline bool Type::isExtIntType() const {
|
||||
return isa<ExtIntType>(CanonicalType);
|
||||
inline bool Type::isBitIntType() const {
|
||||
return isa<BitIntType>(CanonicalType);
|
||||
}
|
||||
|
||||
#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
|
||||
@ -6998,7 +7020,7 @@ inline bool Type::isIntegerType() const {
|
||||
return IsEnumDeclComplete(ET->getDecl()) &&
|
||||
!IsEnumDeclScoped(ET->getDecl());
|
||||
}
|
||||
return isExtIntType();
|
||||
return isBitIntType();
|
||||
}
|
||||
|
||||
inline bool Type::isFixedPointType() const {
|
||||
@ -7056,7 +7078,7 @@ inline bool Type::isScalarType() const {
|
||||
isa<MemberPointerType>(CanonicalType) ||
|
||||
isa<ComplexType>(CanonicalType) ||
|
||||
isa<ObjCObjectPointerType>(CanonicalType) ||
|
||||
isExtIntType();
|
||||
isBitIntType();
|
||||
}
|
||||
|
||||
inline bool Type::isIntegralOrEnumerationType() const {
|
||||
@ -7069,7 +7091,7 @@ inline bool Type::isIntegralOrEnumerationType() const {
|
||||
if (const auto *ET = dyn_cast<EnumType>(CanonicalType))
|
||||
return IsEnumDeclComplete(ET->getDecl());
|
||||
|
||||
return isExtIntType();
|
||||
return isBitIntType();
|
||||
}
|
||||
|
||||
inline bool Type::isBooleanType() const {
|
||||
|
@ -665,6 +665,16 @@ class BuiltinTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
|
||||
}
|
||||
};
|
||||
|
||||
/// Wrapper for source info for types used via transparent aliases.
|
||||
class UsingTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
|
||||
UsingTypeLoc, UsingType> {
|
||||
public:
|
||||
QualType getUnderlyingType() const {
|
||||
return getTypePtr()->getUnderlyingType();
|
||||
}
|
||||
UsingShadowDecl *getFoundDecl() const { return getTypePtr()->getFoundDecl(); }
|
||||
};
|
||||
|
||||
/// Wrapper for source info for typedefs.
|
||||
class TypedefTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
|
||||
TypedefTypeLoc,
|
||||
@ -2561,12 +2571,12 @@ inline T TypeLoc::getAsAdjusted() const {
|
||||
}
|
||||
return Cur.getAs<T>();
|
||||
}
|
||||
class ExtIntTypeLoc final
|
||||
: public InheritingConcreteTypeLoc<TypeSpecTypeLoc, ExtIntTypeLoc,
|
||||
ExtIntType> {};
|
||||
class DependentExtIntTypeLoc final
|
||||
: public InheritingConcreteTypeLoc<TypeSpecTypeLoc, DependentExtIntTypeLoc,
|
||||
DependentExtIntType> {};
|
||||
class BitIntTypeLoc final
|
||||
: public InheritingConcreteTypeLoc<TypeSpecTypeLoc, BitIntTypeLoc,
|
||||
BitIntType> {};
|
||||
class DependentBitIntTypeLoc final
|
||||
: public InheritingConcreteTypeLoc<TypeSpecTypeLoc, DependentBitIntTypeLoc,
|
||||
DependentBitIntType> {};
|
||||
|
||||
} // namespace clang
|
||||
|
||||
|
@ -358,7 +358,20 @@ let Class = UnresolvedUsingType in {
|
||||
}
|
||||
|
||||
def : Creator<[{
|
||||
return ctx.getTypeDeclType(cast<UnresolvedUsingTypenameDecl>(declaration));
|
||||
return ctx.getUnresolvedUsingType(cast<UnresolvedUsingTypenameDecl>(declaration));
|
||||
}]>;
|
||||
}
|
||||
|
||||
let Class = UsingType in {
|
||||
def : Property<"foundDeclaration", UsingShadowDeclRef> {
|
||||
let Read = [{ node->getFoundDecl() }];
|
||||
}
|
||||
def : Property<"underlyingType", QualType> {
|
||||
let Read = [{ node->getUnderlyingType() }];
|
||||
}
|
||||
|
||||
def : Creator<[{
|
||||
return ctx.getUsingType(foundDeclaration, underlyingType);
|
||||
}]>;
|
||||
}
|
||||
|
||||
@ -882,7 +895,7 @@ let Class = PipeType in {
|
||||
}]>;
|
||||
}
|
||||
|
||||
let Class = ExtIntType in {
|
||||
let Class = BitIntType in {
|
||||
def : Property<"isUnsigned", Bool> {
|
||||
let Read = [{ node->isUnsigned() }];
|
||||
}
|
||||
@ -891,11 +904,11 @@ let Class = ExtIntType in {
|
||||
}
|
||||
|
||||
def : Creator<[{
|
||||
return ctx.getExtIntType(isUnsigned, numBits);
|
||||
return ctx.getBitIntType(isUnsigned, numBits);
|
||||
}]>;
|
||||
}
|
||||
|
||||
let Class = DependentExtIntType in {
|
||||
let Class = DependentBitIntType in {
|
||||
def : Property<"isUnsigned", Bool> {
|
||||
let Read = [{ node->isUnsigned() }];
|
||||
}
|
||||
@ -903,6 +916,6 @@ let Class = DependentExtIntType in {
|
||||
let Read = [{ node->getNumBitsExpr() }];
|
||||
}
|
||||
def : Creator<[{
|
||||
return ctx.getDependentExtIntType(isUnsigned, numBitsExpr);
|
||||
return ctx.getDependentBitIntType(isUnsigned, numBitsExpr);
|
||||
}]>;
|
||||
}
|
||||
|
@ -4128,25 +4128,34 @@ AST_MATCHER_P(DeclRefExpr, to, internal::Matcher<Decl>,
|
||||
InnerMatcher.matches(*DeclNode, Finder, Builder));
|
||||
}
|
||||
|
||||
/// Matches a \c DeclRefExpr that refers to a declaration through a
|
||||
/// specific using shadow declaration.
|
||||
/// Matches if a node refers to a declaration through a specific
|
||||
/// using shadow declaration.
|
||||
///
|
||||
/// Given
|
||||
/// Examples:
|
||||
/// \code
|
||||
/// namespace a { void f() {} }
|
||||
/// namespace a { int f(); }
|
||||
/// using a::f;
|
||||
/// void g() {
|
||||
/// f(); // Matches this ..
|
||||
/// a::f(); // .. but not this.
|
||||
/// }
|
||||
/// int x = f();
|
||||
/// \endcode
|
||||
/// declRefExpr(throughUsingDecl(anything()))
|
||||
/// matches \c f()
|
||||
AST_MATCHER_P(DeclRefExpr, throughUsingDecl,
|
||||
internal::Matcher<UsingShadowDecl>, InnerMatcher) {
|
||||
/// matches \c f
|
||||
///
|
||||
/// \code
|
||||
/// namespace a { class X{}; }
|
||||
/// using a::X;
|
||||
/// X x;
|
||||
/// \code
|
||||
/// typeLoc(loc(usingType(throughUsingDecl(anything()))))
|
||||
/// matches \c X
|
||||
///
|
||||
/// Usable as: Matcher<DeclRefExpr>, Matcher<UsingType>
|
||||
AST_POLYMORPHIC_MATCHER_P(throughUsingDecl,
|
||||
AST_POLYMORPHIC_SUPPORTED_TYPES(DeclRefExpr,
|
||||
UsingType),
|
||||
internal::Matcher<UsingShadowDecl>, Inner) {
|
||||
const NamedDecl *FoundDecl = Node.getFoundDecl();
|
||||
if (const UsingShadowDecl *UsingDecl = dyn_cast<UsingShadowDecl>(FoundDecl))
|
||||
return InnerMatcher.matches(*UsingDecl, Finder, Builder);
|
||||
return Inner.matches(*UsingDecl, Finder, Builder);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -4872,7 +4881,7 @@ AST_POLYMORPHIC_MATCHER_P2(forEachArgumentWithParamType,
|
||||
}
|
||||
}
|
||||
|
||||
int ParamIndex = 0;
|
||||
unsigned ParamIndex = 0;
|
||||
bool Matched = false;
|
||||
unsigned NumArgs = Node.getNumArgs();
|
||||
if (FProto && FProto->isVariadic())
|
||||
@ -4886,7 +4895,7 @@ AST_POLYMORPHIC_MATCHER_P2(forEachArgumentWithParamType,
|
||||
|
||||
// This test is cheaper compared to the big matcher in the next if.
|
||||
// Therefore, please keep this order.
|
||||
if (FProto) {
|
||||
if (FProto && FProto->getNumParams() > ParamIndex) {
|
||||
QualType ParamType = FProto->getParamType(ParamIndex);
|
||||
if (ParamMatcher.matches(ParamType, Finder, &ParamMatches)) {
|
||||
Result.addMatch(ParamMatches);
|
||||
@ -6843,7 +6852,7 @@ extern const AstTypeMatcher<DecltypeType> decltypeType;
|
||||
AST_TYPE_TRAVERSE_MATCHER(hasDeducedType, getDeducedType,
|
||||
AST_POLYMORPHIC_SUPPORTED_TYPES(AutoType));
|
||||
|
||||
/// Matches \c DecltypeType nodes to find out the underlying type.
|
||||
/// Matches \c DecltypeType or \c UsingType nodes to find the underlying type.
|
||||
///
|
||||
/// Given
|
||||
/// \code
|
||||
@ -6853,9 +6862,10 @@ AST_TYPE_TRAVERSE_MATCHER(hasDeducedType, getDeducedType,
|
||||
/// decltypeType(hasUnderlyingType(isInteger()))
|
||||
/// matches the type of "a"
|
||||
///
|
||||
/// Usable as: Matcher<DecltypeType>
|
||||
/// Usable as: Matcher<DecltypeType>, Matcher<UsingType>
|
||||
AST_TYPE_TRAVERSE_MATCHER(hasUnderlyingType, getUnderlyingType,
|
||||
AST_POLYMORPHIC_SUPPORTED_TYPES(DecltypeType));
|
||||
AST_POLYMORPHIC_SUPPORTED_TYPES(DecltypeType,
|
||||
UsingType));
|
||||
|
||||
/// Matches \c FunctionType nodes.
|
||||
///
|
||||
@ -7183,6 +7193,18 @@ AST_MATCHER_P(ElaboratedType, namesType, internal::Matcher<QualType>,
|
||||
return InnerMatcher.matches(Node.getNamedType(), Finder, Builder);
|
||||
}
|
||||
|
||||
/// Matches types specified through a using declaration.
|
||||
///
|
||||
/// Given
|
||||
/// \code
|
||||
/// namespace a { struct S {}; }
|
||||
/// using a::S;
|
||||
/// S s;
|
||||
/// \endcode
|
||||
///
|
||||
/// \c usingType() matches the type of the variable declaration of \c s.
|
||||
extern const AstTypeMatcher<UsingType> usingType;
|
||||
|
||||
/// Matches types that represent the result of substituting a type for a
|
||||
/// template type parameter.
|
||||
///
|
||||
|
@ -1090,6 +1090,12 @@ class HasDeclarationMatcher : public MatcherInterface<T> {
|
||||
if (const auto *S = dyn_cast<ElaboratedType>(&Node)) {
|
||||
return matchesSpecialized(S->desugar(), Finder, Builder);
|
||||
}
|
||||
// Similarly types found via using declarations.
|
||||
// These are *usually* meaningless sugar, and this matches the historical
|
||||
// behavior prior to the introduction of UsingType.
|
||||
if (const auto *S = dyn_cast<UsingType>(&Node)) {
|
||||
return matchesSpecialized(S->desugar(), Finder, Builder);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -155,7 +155,7 @@ class CFGWalker {
|
||||
return false;
|
||||
|
||||
// Ignore anonymous functions.
|
||||
if (!dyn_cast_or_null<NamedDecl>(AC.getDecl()))
|
||||
if (!isa_and_nonnull<NamedDecl>(AC.getDecl()))
|
||||
return false;
|
||||
|
||||
SortedGraph = AC.getAnalysis<PostOrderCFGView>();
|
||||
|
@ -15,11 +15,20 @@
|
||||
#ifndef LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_DATAFLOWENVIRONMENT_H
|
||||
#define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_DATAFLOWENVIRONMENT_H
|
||||
|
||||
#include "clang/Analysis/FlowSensitive/DataflowLattice.h"
|
||||
|
||||
namespace clang {
|
||||
namespace dataflow {
|
||||
|
||||
/// Holds the state of the program (store and heap) at a given program point.
|
||||
class Environment {};
|
||||
class Environment {
|
||||
public:
|
||||
bool operator==(const Environment &) const { return true; }
|
||||
|
||||
LatticeJoinEffect join(const Environment &) {
|
||||
return LatticeJoinEffect::Unchanged;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace dataflow
|
||||
} // namespace clang
|
||||
|
@ -61,11 +61,12 @@ struct ReversePostOrderCompare {
|
||||
/// the same block multiple times at once.
|
||||
struct ForwardDataflowWorklist
|
||||
: DataflowWorklistBase<ReversePostOrderCompare, 20> {
|
||||
ForwardDataflowWorklist(const CFG &Cfg, PostOrderCFGView *POV)
|
||||
: DataflowWorklistBase(Cfg, POV,
|
||||
ReversePostOrderCompare{POV->getComparator()}) {}
|
||||
|
||||
ForwardDataflowWorklist(const CFG &Cfg, AnalysisDeclContext &Ctx)
|
||||
: DataflowWorklistBase(
|
||||
Cfg, Ctx.getAnalysis<PostOrderCFGView>(),
|
||||
ReversePostOrderCompare{
|
||||
Ctx.getAnalysis<PostOrderCFGView>()->getComparator()}) {}
|
||||
: ForwardDataflowWorklist(Cfg, Ctx.getAnalysis<PostOrderCFGView>()) {}
|
||||
|
||||
void enqueueSuccessors(const CFGBlock *Block) {
|
||||
for (auto B : Block->succs())
|
||||
|
@ -76,6 +76,24 @@ struct TypeErasedDataflowAnalysisState {
|
||||
Environment Env;
|
||||
};
|
||||
|
||||
/// Transfers the state of a basic block by evaluating each of its statements in
|
||||
/// the context of `Analysis` and the states of its predecessors that are
|
||||
/// available in `BlockStates`. `HandleTransferredStmt` (if provided) will be
|
||||
/// applied to each statement in the block, after it is evaluated.
|
||||
///
|
||||
/// Requirements:
|
||||
///
|
||||
/// All predecessors of `Block` except those with loop back edges must have
|
||||
/// already been transferred. States in `BlockStates` that are set to
|
||||
/// `llvm::None` represent basic blocks that are not evaluated yet.
|
||||
TypeErasedDataflowAnalysisState transferBlock(
|
||||
std::vector<llvm::Optional<TypeErasedDataflowAnalysisState>> &BlockStates,
|
||||
const CFGBlock &Block, const Environment &InitEnv,
|
||||
TypeErasedDataflowAnalysis &Analysis,
|
||||
std::function<void(const CFGStmt &,
|
||||
const TypeErasedDataflowAnalysisState &)>
|
||||
HandleTransferredStmt = nullptr);
|
||||
|
||||
/// Performs dataflow analysis and returns a mapping from basic block IDs to
|
||||
/// dataflow analysis states that model the respective basic blocks. Indices
|
||||
/// of the returned vector correspond to basic block IDs.
|
||||
|
@ -3865,6 +3865,14 @@ def ReleaseHandle : InheritableParamAttr {
|
||||
let Documentation = [ReleaseHandleDocs];
|
||||
}
|
||||
|
||||
def DiagnoseAsBuiltin : InheritableAttr {
|
||||
let Spellings = [Clang<"diagnose_as_builtin">];
|
||||
let Args = [DeclArgument<Function, "Function">,
|
||||
VariadicUnsignedArgument<"ArgIndices">];
|
||||
let Subjects = SubjectList<[Function]>;
|
||||
let Documentation = [DiagnoseAsBuiltinDocs];
|
||||
}
|
||||
|
||||
def Builtin : InheritableAttr {
|
||||
let Spellings = [];
|
||||
let Args = [UnsignedArgument<"ID">];
|
||||
|
@ -187,6 +187,10 @@ primary use is for COFF object files which explicitly specify what interfaces
|
||||
are imported from external modules. See the dllimport_ documentation on MSDN
|
||||
for more information.
|
||||
|
||||
Note that a dllimport function may still be inlined, if its definition is
|
||||
available and it doesn't reference any non-dllimport functions or global
|
||||
variables.
|
||||
|
||||
.. _dllimport: https://msdn.microsoft.com/en-us/library/3y1sfaz2.aspx
|
||||
}];
|
||||
}
|
||||
@ -5980,6 +5984,50 @@ attribute requires a string literal argument to identify the handle being releas
|
||||
}];
|
||||
}
|
||||
|
||||
def DiagnoseAsBuiltinDocs : Documentation {
|
||||
let Category = DocCatFunction;
|
||||
let Content = [{
|
||||
The ``diagnose_as_builtin` attribute indicates that Fortify diagnostics are to
|
||||
be applied to the declared function as if it were the function specified by the
|
||||
attribute. The builtin function whose diagnostics are to be mimicked should be
|
||||
given. In addition, the order in which arguments should be applied must also
|
||||
be given.
|
||||
|
||||
For example, the attribute can be used as follows.
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
__attribute__((diagnose_as_builtin(__builtin_memset, 3, 2, 1)))
|
||||
void *mymemset(int n, int c, void *s) {
|
||||
// ...
|
||||
}
|
||||
|
||||
This indicates that calls to ``mymemset`` should be diagnosed as if they were
|
||||
calls to ``__builtin_memset``. The arguments ``3, 2, 1`` indicate by index the
|
||||
order in which arguments of ``mymemset`` should be applied to
|
||||
``__builtin_memset``. The third argument should be applied first, then the
|
||||
second, and then the first. Thus (when Fortify warnings are enabled) the call
|
||||
``mymemset(n, c, s)`` will diagnose overflows as if it were the call
|
||||
``__builtin_memset(s, c, n)``.
|
||||
|
||||
For variadic functions, the variadic arguments must come in the same order as
|
||||
they would to the builtin function, after all normal arguments. For instance,
|
||||
to diagnose a new function as if it were `sscanf`, we can use the attribute as
|
||||
follows.
|
||||
|
||||
.. code-block:: c
|
||||
__attribute__((diagnose_as_builtin(sscanf, 1, 2)))
|
||||
int mysscanf(const char *str, const char *format, ...) {
|
||||
// ...
|
||||
}
|
||||
|
||||
Then the call `mysscanf("abc def", "%4s %4s", buf1, buf2)` will be diagnosed as
|
||||
if it were the call `sscanf("abc def", "%4s %4s", buf1, buf2)`.
|
||||
|
||||
This attribute cannot be applied to non-static member functions.
|
||||
}];
|
||||
}
|
||||
|
||||
def ArmSveVectorBitsDocs : Documentation {
|
||||
let Category = DocCatType;
|
||||
let Content = [{
|
||||
|
@ -646,8 +646,10 @@ BUILTIN(__builtin_call_with_static_chain, "v.", "nt")
|
||||
BUILTIN(__builtin_elementwise_abs, "v.", "nct")
|
||||
BUILTIN(__builtin_elementwise_max, "v.", "nct")
|
||||
BUILTIN(__builtin_elementwise_min, "v.", "nct")
|
||||
BUILTIN(__builtin_elementwise_ceil, "v.", "nct")
|
||||
BUILTIN(__builtin_reduce_max, "v.", "nct")
|
||||
BUILTIN(__builtin_reduce_min, "v.", "nct")
|
||||
BUILTIN(__builtin_reduce_xor, "v.", "nct")
|
||||
|
||||
BUILTIN(__builtin_matrix_transpose, "v.", "nFt")
|
||||
BUILTIN(__builtin_matrix_column_major_load, "v.", "nFt")
|
||||
@ -1574,6 +1576,7 @@ BUILTIN(__builtin_smulll_overflow, "bSLLiCSLLiCSLLi*", "n")
|
||||
|
||||
// Clang builtins (not available in GCC).
|
||||
BUILTIN(__builtin_addressof, "v*v&", "nct")
|
||||
BUILTIN(__builtin_function_start, "v*v&", "nct")
|
||||
BUILTIN(__builtin_operator_new, "v*z", "tc")
|
||||
BUILTIN(__builtin_operator_delete, "vv*", "tn")
|
||||
BUILTIN(__builtin_char_memchr, "c*cC*iz", "n")
|
||||
@ -1611,7 +1614,6 @@ LANGBUILTIN(__builtin_coro_alloc, "b", "n", COR_LANG)
|
||||
LANGBUILTIN(__builtin_coro_begin, "v*v*", "n", COR_LANG)
|
||||
LANGBUILTIN(__builtin_coro_end, "bv*Ib", "n", COR_LANG)
|
||||
LANGBUILTIN(__builtin_coro_suspend, "cIb", "n", COR_LANG)
|
||||
LANGBUILTIN(__builtin_coro_param, "bv*v*", "n", COR_LANG)
|
||||
|
||||
// OpenCL v2.0 s6.13.16, s9.17.3.5 - Pipe functions.
|
||||
// We need the generic prototype, since the packet type could be anything.
|
||||
|
@ -0,0 +1,39 @@
|
||||
#ifdef GET_SVE_BUILTINS
|
||||
BUILTIN(__builtin_sve_svget_neonq_s8, "V16Scq16Sc", "n")
|
||||
BUILTIN(__builtin_sve_svget_neonq_s16, "V8sq8s", "n")
|
||||
BUILTIN(__builtin_sve_svget_neonq_s32, "V4iq4i", "n")
|
||||
BUILTIN(__builtin_sve_svget_neonq_s64, "V2Wiq2Wi", "n")
|
||||
BUILTIN(__builtin_sve_svget_neonq_u8, "V16Ucq16Uc", "n")
|
||||
BUILTIN(__builtin_sve_svget_neonq_u16, "V16Usq16Us", "n")
|
||||
BUILTIN(__builtin_sve_svget_neonq_u32, "V4Uiq4Ui", "n")
|
||||
BUILTIN(__builtin_sve_svget_neonq_u64, "V2UWiq2UWi", "n")
|
||||
BUILTIN(__builtin_sve_svget_neonq_f16, "V8hq8h", "n")
|
||||
BUILTIN(__builtin_sve_svget_neonq_f32, "V4fq4f", "n")
|
||||
BUILTIN(__builtin_sve_svget_neonq_f64, "V2dq2d", "n")
|
||||
BUILTIN(__builtin_sve_svget_neonq_bf16, "V8yq8y", "n")
|
||||
BUILTIN(__builtin_sve_svset_neonq_s8, "q16Scq16ScV16Sc", "n")
|
||||
BUILTIN(__builtin_sve_svset_neonq_s16, "q8sq8sV8s", "n")
|
||||
BUILTIN(__builtin_sve_svset_neonq_s32, "q4iq4iV4i", "n")
|
||||
BUILTIN(__builtin_sve_svset_neonq_s64, "q2Wiq2WiV2Wi", "n")
|
||||
BUILTIN(__builtin_sve_svset_neonq_u8, "q16Ucq16UcV16Uc", "n")
|
||||
BUILTIN(__builtin_sve_svset_neonq_u16, "q8Usq8UsV8s", "n")
|
||||
BUILTIN(__builtin_sve_svset_neonq_u32, "q4Uiq4UiV4Ui", "n")
|
||||
BUILTIN(__builtin_sve_svset_neonq_u64, "q2UWiq2UWiV2UWi", "n")
|
||||
BUILTIN(__builtin_sve_svset_neonq_f16, "q8hq8hV8h", "n")
|
||||
BUILTIN(__builtin_sve_svset_neonq_f32, "q4fq4fV4f", "n")
|
||||
BUILTIN(__builtin_sve_svset_neonq_f64, "q2dq2dV2d", "n")
|
||||
BUILTIN(__builtin_sve_svset_neonq_bf16, "q8yq8yV8y", "n")
|
||||
BUILTIN(__builtin_sve_svdup_neonq_s8, "q16ScV16Sc", "n")
|
||||
BUILTIN(__builtin_sve_svdup_neonq_s16, "q8sV8s", "n")
|
||||
BUILTIN(__builtin_sve_svdup_neonq_s32, "q4iV4i", "n")
|
||||
BUILTIN(__builtin_sve_svdup_neonq_s64, "q4iV4i", "n")
|
||||
BUILTIN(__builtin_sve_svdup_neonq_u8, "q16UcV16Uc", "n")
|
||||
BUILTIN(__builtin_sve_svdup_neonq_u16, "q8UsV8Us", "n")
|
||||
BUILTIN(__builtin_sve_svdup_neonq_u32, "q4UiV4Ui", "n")
|
||||
BUILTIN(__builtin_sve_svdup_neonq_u64, "q2UWiV2UWi", "n")
|
||||
BUILTIN(__builtin_sve_svdup_neonq_f16, "q8hV8h", "n")
|
||||
BUILTIN(__builtin_sve_svdup_neonq_f32, "q4fV4f", "n")
|
||||
BUILTIN(__builtin_sve_svdup_neonq_f64, "q2dV2d", "n")
|
||||
BUILTIN(__builtin_sve_svdup_neonq_bf16, "q8yV8y", "n")
|
||||
#endif
|
||||
|
@ -0,0 +1,39 @@
|
||||
#ifdef GET_SVE_LLVM_INTRINSIC_MAP
|
||||
SVEMAP2(svget_neonq_s8, SVETypeFlags::EltTyInt8),
|
||||
SVEMAP2(svget_neonq_s16, SVETypeFlags::EltTyInt16),
|
||||
SVEMAP2(svget_neonq_s32, SVETypeFlags::EltTyInt32),
|
||||
SVEMAP2(svget_neonq_s64, SVETypeFlags::EltTyInt64),
|
||||
SVEMAP2(svget_neonq_u8, SVETypeFlags::EltTyInt8),
|
||||
SVEMAP2(svget_neonq_u16, SVETypeFlags::EltTyInt16),
|
||||
SVEMAP2(svget_neonq_u32, SVETypeFlags::EltTyInt32),
|
||||
SVEMAP2(svget_neonq_u64, SVETypeFlags::EltTyInt64),
|
||||
SVEMAP2(svget_neonq_f16, SVETypeFlags::EltTyFloat16),
|
||||
SVEMAP2(svget_neonq_f32, SVETypeFlags::EltTyFloat32),
|
||||
SVEMAP2(svget_neonq_f64, SVETypeFlags::EltTyFloat64),
|
||||
SVEMAP2(svget_neonq_bf16, SVETypeFlags::EltTyBFloat16),
|
||||
SVEMAP2(svset_neonq_s8, SVETypeFlags::EltTyInt8),
|
||||
SVEMAP2(svset_neonq_s16, SVETypeFlags::EltTyInt16),
|
||||
SVEMAP2(svset_neonq_s32, SVETypeFlags::EltTyInt32),
|
||||
SVEMAP2(svset_neonq_s64, SVETypeFlags::EltTyInt64),
|
||||
SVEMAP2(svset_neonq_u8, SVETypeFlags::EltTyInt8),
|
||||
SVEMAP2(svset_neonq_u16, SVETypeFlags::EltTyInt16),
|
||||
SVEMAP2(svset_neonq_u32, SVETypeFlags::EltTyInt32),
|
||||
SVEMAP2(svset_neonq_u64, SVETypeFlags::EltTyInt64),
|
||||
SVEMAP2(svset_neonq_f16, SVETypeFlags::EltTyFloat16),
|
||||
SVEMAP2(svset_neonq_f32, SVETypeFlags::EltTyFloat32),
|
||||
SVEMAP2(svset_neonq_f64, SVETypeFlags::EltTyFloat64),
|
||||
SVEMAP2(svset_neonq_bf16, SVETypeFlags::EltTyBFloat16),
|
||||
SVEMAP2(svdup_neonq_s8, SVETypeFlags::EltTyInt8),
|
||||
SVEMAP2(svdup_neonq_s16, SVETypeFlags::EltTyInt16),
|
||||
SVEMAP2(svdup_neonq_s32, SVETypeFlags::EltTyInt32),
|
||||
SVEMAP2(svdup_neonq_s64, SVETypeFlags::EltTyInt64),
|
||||
SVEMAP2(svdup_neonq_u8, SVETypeFlags::EltTyInt8),
|
||||
SVEMAP2(svdup_neonq_u16, SVETypeFlags::EltTyInt16),
|
||||
SVEMAP2(svdup_neonq_u32, SVETypeFlags::EltTyInt32),
|
||||
SVEMAP2(svdup_neonq_u64, SVETypeFlags::EltTyInt64),
|
||||
SVEMAP2(svdup_neonq_f16, SVETypeFlags::EltTyFloat16),
|
||||
SVEMAP2(svdup_neonq_f32, SVETypeFlags::EltTyFloat32),
|
||||
SVEMAP2(svdup_neonq_f64, SVETypeFlags::EltTyFloat64),
|
||||
SVEMAP2(svdup_neonq_bf16, SVETypeFlags::EltTyBFloat16),
|
||||
#endif
|
||||
|
@ -17,8 +17,10 @@
|
||||
# define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) BUILTIN(ID, TYPE, ATTRS)
|
||||
#endif
|
||||
|
||||
#pragma push_macro("V69")
|
||||
#define V69 "v69"
|
||||
#pragma push_macro("V68")
|
||||
#define V68 "v68"
|
||||
#define V68 "v68|" V69
|
||||
#pragma push_macro("V67")
|
||||
#define V67 "v67|" V68
|
||||
#pragma push_macro("V66")
|
||||
@ -34,8 +36,10 @@
|
||||
#pragma push_macro("V5")
|
||||
#define V5 "v5|" V55
|
||||
|
||||
#pragma push_macro("HVXV69")
|
||||
#define HVXV69 "hvxv69"
|
||||
#pragma push_macro("HVXV68")
|
||||
#define HVXV68 "hvxv68"
|
||||
#define HVXV68 "hvxv68|" HVXV69
|
||||
#pragma push_macro("HVXV67")
|
||||
#define HVXV67 "hvxv67|" HVXV68
|
||||
#pragma push_macro("HVXV66")
|
||||
@ -128,6 +132,7 @@ TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpyub_rtt_acc_128B,"V64iV64iV32iLLi","", "
|
||||
#pragma pop_macro("HVXV66")
|
||||
#pragma pop_macro("HVXV67")
|
||||
#pragma pop_macro("HVXV68")
|
||||
#pragma pop_macro("HVXV69")
|
||||
|
||||
#pragma pop_macro("V5")
|
||||
#pragma pop_macro("V55")
|
||||
@ -137,6 +142,7 @@ TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpyub_rtt_acc_128B,"V64iV64iV32iLLi","", "
|
||||
#pragma pop_macro("V66")
|
||||
#pragma pop_macro("V67")
|
||||
#pragma pop_macro("V68")
|
||||
#pragma pop_macro("V69")
|
||||
|
||||
#undef BUILTIN
|
||||
#undef TARGET_BUILTIN
|
||||
|
@ -1739,3 +1739,150 @@ TARGET_BUILTIN(__builtin_HEXAGON_V6_v6mpyvubs10, "V32iV32iV32iUIi", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_v6mpyvubs10_128B, "V64iV64iV64iUIi", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_v6mpyvubs10_vxx, "V32iV32iV32iV32iUIi", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_v6mpyvubs10_vxx_128B, "V64iV64iV64iV64iUIi", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vabs_hf, "V16iV16i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vabs_hf_128B, "V32iV32i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vabs_sf, "V16iV16i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vabs_sf_128B, "V32iV32i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vadd_hf, "V16iV16iV16i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vadd_hf_128B, "V32iV32iV32i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vadd_hf_hf, "V16iV16iV16i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vadd_hf_hf_128B, "V32iV32iV32i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vadd_qf16, "V16iV16iV16i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vadd_qf16_128B, "V32iV32iV32i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vadd_qf16_mix, "V16iV16iV16i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vadd_qf16_mix_128B, "V32iV32iV32i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vadd_qf32, "V16iV16iV16i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vadd_qf32_128B, "V32iV32iV32i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vadd_qf32_mix, "V16iV16iV16i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vadd_qf32_mix_128B, "V32iV32iV32i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vadd_sf, "V16iV16iV16i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vadd_sf_128B, "V32iV32iV32i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vadd_sf_hf, "V32iV16iV16i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vadd_sf_hf_128B, "V64iV32iV32i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vadd_sf_sf, "V16iV16iV16i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vadd_sf_sf_128B, "V32iV32iV32i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vassign_fp, "V16iV16i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vassign_fp_128B, "V32iV32i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vconv_hf_qf16, "V16iV16i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vconv_hf_qf16_128B, "V32iV32i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vconv_hf_qf32, "V16iV32i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vconv_hf_qf32_128B, "V32iV64i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vconv_sf_qf32, "V16iV16i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vconv_sf_qf32_128B, "V32iV32i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vcvt_b_hf, "V16iV16iV16i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vcvt_b_hf_128B, "V32iV32iV32i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vcvt_h_hf, "V16iV16i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vcvt_h_hf_128B, "V32iV32i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vcvt_hf_b, "V32iV16i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vcvt_hf_b_128B, "V64iV32i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vcvt_hf_h, "V16iV16i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vcvt_hf_h_128B, "V32iV32i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vcvt_hf_sf, "V16iV16iV16i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vcvt_hf_sf_128B, "V32iV32iV32i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vcvt_hf_ub, "V32iV16i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vcvt_hf_ub_128B, "V64iV32i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vcvt_hf_uh, "V16iV16i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vcvt_hf_uh_128B, "V32iV32i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vcvt_sf_hf, "V32iV16i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vcvt_sf_hf_128B, "V64iV32i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vcvt_ub_hf, "V16iV16iV16i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vcvt_ub_hf_128B, "V32iV32iV32i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vcvt_uh_hf, "V16iV16i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vcvt_uh_hf_128B, "V32iV32i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpy_sf_hf, "V16iV16iV16i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpy_sf_hf_128B, "V32iV32iV32i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpy_sf_hf_acc, "V16iV16iV16iV16i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpy_sf_hf_acc_128B, "V32iV32iV32iV32i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vfmax_hf, "V16iV16iV16i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vfmax_hf_128B, "V32iV32iV32i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vfmax_sf, "V16iV16iV16i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vfmax_sf_128B, "V32iV32iV32i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vfmin_hf, "V16iV16iV16i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vfmin_hf_128B, "V32iV32iV32i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vfmin_sf, "V16iV16iV16i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vfmin_sf_128B, "V32iV32iV32i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vfneg_hf, "V16iV16i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vfneg_hf_128B, "V32iV32i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vfneg_sf, "V16iV16i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vfneg_sf_128B, "V32iV32i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vgthf, "V64bV16iV16i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vgthf_128B, "V128bV32iV32i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vgthf_and, "V64bV64bV16iV16i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vgthf_and_128B, "V128bV128bV32iV32i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vgthf_or, "V64bV64bV16iV16i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vgthf_or_128B, "V128bV128bV32iV32i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vgthf_xor, "V64bV64bV16iV16i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vgthf_xor_128B, "V128bV128bV32iV32i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtsf, "V64bV16iV16i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtsf_128B, "V128bV32iV32i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtsf_and, "V64bV64bV16iV16i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtsf_and_128B, "V128bV128bV32iV32i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtsf_or, "V64bV64bV16iV16i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtsf_or_128B, "V128bV128bV32iV32i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtsf_xor, "V64bV64bV16iV16i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtsf_xor_128B, "V128bV128bV32iV32i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vmax_hf, "V16iV16iV16i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vmax_hf_128B, "V32iV32iV32i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vmax_sf, "V16iV16iV16i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vmax_sf_128B, "V32iV32iV32i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vmin_hf, "V16iV16iV16i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vmin_hf_128B, "V32iV32iV32i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vmin_sf, "V16iV16iV16i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vmin_sf_128B, "V32iV32iV32i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_hf_hf, "V16iV16iV16i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_hf_hf_128B, "V32iV32iV32i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_hf_hf_acc, "V16iV16iV16iV16i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_hf_hf_acc_128B, "V32iV32iV32iV32i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_qf16, "V16iV16iV16i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_qf16_128B, "V32iV32iV32i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_qf16_hf, "V16iV16iV16i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_qf16_hf_128B, "V32iV32iV32i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_qf16_mix_hf, "V16iV16iV16i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_qf16_mix_hf_128B, "V32iV32iV32i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_qf32, "V16iV16iV16i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_qf32_128B, "V32iV32iV32i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_qf32_hf, "V32iV16iV16i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_qf32_hf_128B, "V64iV32iV32i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_qf32_mix_hf, "V32iV16iV16i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_qf32_mix_hf_128B, "V64iV32iV32i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_qf32_qf16, "V32iV16iV16i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_qf32_qf16_128B, "V64iV32iV32i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_qf32_sf, "V16iV16iV16i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_qf32_sf_128B, "V32iV32iV32i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_sf_hf, "V32iV16iV16i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_sf_hf_128B, "V64iV32iV32i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_sf_hf_acc, "V32iV32iV16iV16i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_sf_hf_acc_128B, "V64iV64iV32iV32i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_sf_sf, "V16iV16iV16i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_sf_sf_128B, "V32iV32iV32i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vsub_hf, "V16iV16iV16i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vsub_hf_128B, "V32iV32iV32i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vsub_hf_hf, "V16iV16iV16i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vsub_hf_hf_128B, "V32iV32iV32i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vsub_qf16, "V16iV16iV16i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vsub_qf16_128B, "V32iV32iV32i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vsub_qf16_mix, "V16iV16iV16i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vsub_qf16_mix_128B, "V32iV32iV32i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vsub_qf32, "V16iV16iV16i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vsub_qf32_128B, "V32iV32iV32i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vsub_qf32_mix, "V16iV16iV16i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vsub_qf32_mix_128B, "V32iV32iV32i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vsub_sf, "V16iV16iV16i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vsub_sf_128B, "V32iV32iV32i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vsub_sf_hf, "V32iV16iV16i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vsub_sf_hf_128B, "V64iV32iV32i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vsub_sf_sf, "V16iV16iV16i", "", HVXV68)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vsub_sf_sf_128B, "V32iV32iV32i", "", HVXV68)
|
||||
|
||||
// V69 HVX Instructions.
|
||||
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrvuhubrndsat, "V16iV32iV16i", "", HVXV69)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrvuhubrndsat_128B, "V32iV64iV32i", "", HVXV69)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrvuhubsat, "V16iV32iV16i", "", HVXV69)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrvuhubsat_128B, "V32iV64iV32i", "", HVXV69)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrvwuhrndsat, "V16iV32iV16i", "", HVXV69)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrvwuhrndsat_128B, "V32iV64iV32i", "", HVXV69)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrvwuhsat, "V16iV32iV16i", "", HVXV69)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrvwuhsat_128B, "V32iV64iV32i", "", HVXV69)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyuhvs, "V16iV16iV16i", "", HVXV69)
|
||||
TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyuhvs_128B, "V32iV32iV32i", "", HVXV69)
|
||||
|
@ -8,199 +8,7 @@
|
||||
// Automatically generated file, do not edit!
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
CUSTOM_BUILTIN_MAPPING(A2_add, 0)
|
||||
CUSTOM_BUILTIN_MAPPING(A2_addi, 0)
|
||||
CUSTOM_BUILTIN_MAPPING(A2_addp, 0)
|
||||
CUSTOM_BUILTIN_MAPPING(A2_and, 0)
|
||||
CUSTOM_BUILTIN_MAPPING(A2_andir, 0)
|
||||
CUSTOM_BUILTIN_MAPPING(A2_neg, 0)
|
||||
CUSTOM_BUILTIN_MAPPING(A2_not, 0)
|
||||
CUSTOM_BUILTIN_MAPPING(A2_or, 0)
|
||||
CUSTOM_BUILTIN_MAPPING(A2_orir, 0)
|
||||
CUSTOM_BUILTIN_MAPPING(A2_sub, 0)
|
||||
CUSTOM_BUILTIN_MAPPING(A2_subp, 0)
|
||||
CUSTOM_BUILTIN_MAPPING(A2_subri, 0)
|
||||
CUSTOM_BUILTIN_MAPPING(A2_sxtb, 0)
|
||||
CUSTOM_BUILTIN_MAPPING(A2_sxth, 0)
|
||||
CUSTOM_BUILTIN_MAPPING(A2_xor, 0)
|
||||
CUSTOM_BUILTIN_MAPPING(A2_zxtb, 0)
|
||||
CUSTOM_BUILTIN_MAPPING(A2_zxth, 0)
|
||||
CUSTOM_BUILTIN_MAPPING(M2_dpmpyss_s0, 0)
|
||||
CUSTOM_BUILTIN_MAPPING(M2_dpmpyuu_s0, 0)
|
||||
CUSTOM_BUILTIN_MAPPING(M2_mpyi, 0)
|
||||
CUSTOM_BUILTIN_MAPPING(M2_mpysmi, 0)
|
||||
CUSTOM_BUILTIN_MAPPING(M2_mpyui, 0)
|
||||
CUSTOM_BUILTIN_MAPPING(S2_asl_i_p, 0)
|
||||
CUSTOM_BUILTIN_MAPPING(S2_asl_i_r, 0)
|
||||
CUSTOM_BUILTIN_MAPPING(S2_asr_i_p, 0)
|
||||
CUSTOM_BUILTIN_MAPPING(S2_asr_i_r, 0)
|
||||
CUSTOM_BUILTIN_MAPPING(S2_lsr_i_p, 0)
|
||||
CUSTOM_BUILTIN_MAPPING(S2_lsr_i_r, 0)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_pred_and, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_pred_and_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_pred_and_n, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_pred_and_n_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_pred_not, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_pred_not_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_pred_or, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_pred_or_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_pred_or_n, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_pred_or_n_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_pred_scalar2, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_pred_scalar2_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_pred_xor, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_pred_xor_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vS32b_nqpred_ai, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vS32b_nqpred_ai_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vS32b_nt_nqpred_ai, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vS32b_nt_nqpred_ai_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vS32b_nt_qpred_ai, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vS32b_nt_qpred_ai_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vS32b_qpred_ai, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vS32b_qpred_ai_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vaddbnq, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vaddbnq_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vaddbq, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vaddbq_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vaddhnq, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vaddhnq_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vaddhq, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vaddhq_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vaddwnq, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vaddwnq_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vaddwq, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vaddwq_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vandqrt, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vandqrt_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vandqrt_acc, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vandqrt_acc_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vandvrt, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vandvrt_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vandvrt_acc, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vandvrt_acc_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_veqb, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_veqb_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_veqb_and, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_veqb_and_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_veqb_or, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_veqb_or_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_veqb_xor, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_veqb_xor_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_veqh, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_veqh_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_veqh_and, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_veqh_and_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_veqh_or, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_veqh_or_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_veqh_xor, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_veqh_xor_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_veqw, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_veqw_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_veqw_and, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_veqw_and_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_veqw_or, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_veqw_or_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_veqw_xor, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_veqw_xor_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vgtb, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vgtb_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vgtb_and, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vgtb_and_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vgtb_or, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vgtb_or_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vgtb_xor, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vgtb_xor_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vgth, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vgth_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vgth_and, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vgth_and_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vgth_or, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vgth_or_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vgth_xor, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vgth_xor_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vgtub, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vgtub_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vgtub_and, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vgtub_and_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vgtub_or, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vgtub_or_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vgtub_xor, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vgtub_xor_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vgtuh, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vgtuh_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vgtuh_and, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vgtuh_and_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vgtuh_or, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vgtuh_or_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vgtuh_xor, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vgtuh_xor_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vgtuw, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vgtuw_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vgtuw_and, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vgtuw_and_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vgtuw_or, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vgtuw_or_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vgtuw_xor, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vgtuw_xor_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vgtw, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vgtw_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vgtw_and, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vgtw_and_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vgtw_or, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vgtw_or_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vgtw_xor, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vgtw_xor_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vmux, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vmux_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vsubbnq, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vsubbnq_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vsubbq, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vsubbq_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vsubhnq, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vsubhnq_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vsubhq, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vsubhq_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vsubwnq, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vsubwnq_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vsubwq, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vsubwq_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vswap, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vswap_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_pred_scalar2v2, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_pred_scalar2v2_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_shuffeqh, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_shuffeqh_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_shuffeqw, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_shuffeqw_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vaddcarry, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vaddcarry_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vandnqrt, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vandnqrt_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vandnqrt_acc, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vandnqrt_acc_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vandvnqv, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vandvnqv_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vandvqv, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vandvqv_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vsubcarry, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vsubcarry_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vgathermhq, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vgathermhq_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vgathermhwq, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vgathermhwq_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vgathermwq, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vgathermwq_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vprefixqb, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vprefixqb_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vprefixqh, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vprefixqh_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vprefixqw, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vprefixqw_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vscattermhq, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vscattermhq_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vscattermhwq, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vscattermhwq_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vscattermwq, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vscattermwq_128B, 128)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vaddcarrysat, 64)
|
||||
CUSTOM_BUILTIN_MAPPING(V6_vaddcarrysat_128B, 128)
|
||||
|
@ -15,6 +15,7 @@
|
||||
|
||||
#define GET_SVE_BUILTINS
|
||||
#include "clang/Basic/arm_sve_builtins.inc"
|
||||
#include "clang/Basic/BuiltinsAArch64NeonSVEBridge.def"
|
||||
#undef GET_SVE_BUILTINS
|
||||
|
||||
#undef BUILTIN
|
||||
|
@ -368,9 +368,6 @@ ENUM_CODEGENOPT(DebuggerTuning, llvm::DebuggerKind, 3,
|
||||
/// emitted.
|
||||
VALUE_CODEGENOPT(DwarfVersion, 3, 0)
|
||||
|
||||
/// Whether to use experimental new variable location tracking.
|
||||
CODEGENOPT(ValueTrackingVariableLocations, 1, 0)
|
||||
|
||||
/// Whether we should emit CodeView debug information. It's possible to emit
|
||||
/// CodeView and DWARF into the same object.
|
||||
CODEGENOPT(EmitCodeView, 1, 0)
|
||||
|
@ -227,6 +227,9 @@ class CodeGenOptions : public CodeGenOptionsBase {
|
||||
/// Output filename for the split debug info, not used in the skeleton CU.
|
||||
std::string SplitDwarfOutput;
|
||||
|
||||
/// Output filename used in the COFF debug information.
|
||||
std::string ObjectFilenameForDebug;
|
||||
|
||||
/// The name of the relocation model to use.
|
||||
llvm::Reloc::Model RelocationModel;
|
||||
|
||||
@ -395,7 +398,7 @@ class CodeGenOptions : public CodeGenOptionsBase {
|
||||
/// Executable and command-line used to create a given CompilerInvocation.
|
||||
/// Most of the time this will be the full -cc1 command.
|
||||
const char *Argv0 = nullptr;
|
||||
ArrayRef<const char *> CommandLineArgs;
|
||||
std::vector<std::string> CommandLineArgs;
|
||||
|
||||
/// The minimum hotness value a diagnostic needs in order to be included in
|
||||
/// optimization diagnostics.
|
||||
|
@ -95,6 +95,8 @@ enum class CudaArch {
|
||||
GFX1033,
|
||||
GFX1034,
|
||||
GFX1035,
|
||||
Generic, // A processor model named 'generic' if the target backend defines a
|
||||
// public one.
|
||||
LAST,
|
||||
};
|
||||
|
||||
@ -103,7 +105,8 @@ static inline bool IsNVIDIAGpuArch(CudaArch A) {
|
||||
}
|
||||
|
||||
static inline bool IsAMDGpuArch(CudaArch A) {
|
||||
return A >= CudaArch::GFX600 && A < CudaArch::LAST;
|
||||
// Generic processor model is for testing only.
|
||||
return A >= CudaArch::GFX600 && A < CudaArch::Generic;
|
||||
}
|
||||
|
||||
const char *CudaArchToString(CudaArch A);
|
||||
|
@ -74,6 +74,14 @@ def err_drv_no_hip_runtime : Error<
|
||||
"cannot find HIP runtime; provide its path via '--rocm-path', or pass "
|
||||
"'-nogpuinc' to build without HIP runtime">;
|
||||
|
||||
def err_drv_no_hipspv_device_lib : Error<
|
||||
"cannot find HIP device library%select{| for %1}0; provide its path via "
|
||||
"'--hip-path' or '--hip-device-lib-path', or pass '-nogpulib' to build "
|
||||
"without HIP device library">;
|
||||
def err_drv_hipspv_no_hip_path : Error<
|
||||
"'--hip-path' must be specified when offloading to "
|
||||
"SPIR-V%select{| unless %1 is given}0.">;
|
||||
|
||||
def err_drv_undetermined_amdgpu_arch : Error<
|
||||
"cannot determine AMDGPU architecture: %0; consider passing it via "
|
||||
"'--march'">;
|
||||
@ -108,6 +116,10 @@ def warn_drv_unsupported_option_for_target : Warning<
|
||||
"ignoring '%0' option as it is not currently supported for target '%1'">,
|
||||
InGroup<OptionIgnored>;
|
||||
|
||||
def warn_drv_spirv_linking_multiple_inputs_unsupported: Warning<
|
||||
"Linking multiple input files is not supported for SPIR-V yet">,
|
||||
InGroup<OptionIgnored>;
|
||||
|
||||
def err_drv_invalid_thread_model_for_target : Error<
|
||||
"invalid thread model '%0' in '%1' for this target">;
|
||||
def err_drv_invalid_linker_name : Error<
|
||||
@ -431,11 +443,13 @@ def err_analyzer_checker_option_invalid_input : Error<
|
||||
def err_analyzer_checker_incompatible_analyzer_option : Error<
|
||||
"checker cannot be enabled with analyzer option '%0' == %1">;
|
||||
|
||||
def err_drv_invalid_hvx_length : Error<
|
||||
"-mhvx-length is not supported without a -mhvx/-mhvx= flag">;
|
||||
def warn_drv_vectorize_needs_hvx : Warning<
|
||||
"auto-vectorization requires HVX, use -mhvx to enable it">,
|
||||
def warn_drv_needs_hvx : Warning<
|
||||
"%0 requires HVX, use -mhvx/-mhvx= to enable it">,
|
||||
InGroup<OptionIgnored>;
|
||||
def err_drv_needs_hvx : Error<
|
||||
"%0 requires HVX, use -mhvx/-mhvx= to enable it">;
|
||||
def err_drv_needs_hvx_version : Error<
|
||||
"%0 is not supported on HVX %1">;
|
||||
|
||||
def err_drv_module_header_wrong_kind : Error<
|
||||
"header file '%0' input type '%1' does not match type of prior input "
|
||||
@ -551,7 +565,7 @@ def warn_drv_moutline_unsupported_opt : Warning<
|
||||
InGroup<OptionIgnored>;
|
||||
|
||||
def warn_drv_moutline_atomics_unsupported_opt : Warning<
|
||||
"'%0' does not support '-moutline-atomics'; flag ignored">,
|
||||
"'%0' does not support '-%1'; flag ignored">,
|
||||
InGroup<OptionIgnored>;
|
||||
|
||||
def warn_drv_darwin_sdk_invalid_settings : Warning<
|
||||
@ -608,7 +622,14 @@ def err_cc1_round_trip_ok_then_fail : Error<
|
||||
"generated arguments parse failed in round-trip">;
|
||||
def err_cc1_round_trip_mismatch : Error<
|
||||
"generated arguments do not match in round-trip">;
|
||||
def err_cc1_unbounded_vscale_min : Error<
|
||||
"minimum vscale must be an unsigned integer greater than 0">;
|
||||
|
||||
def err_drv_ssp_missing_offset_argument : Error<
|
||||
"'%0' is used without '-mstack-protector-guard-offset', and there is no default">;
|
||||
|
||||
def err_drv_only_one_offload_target_supported_in : Error<
|
||||
"Only one offload target is supported in %0.">;
|
||||
def err_drv_invalid_or_unsupported_offload_target : Error<
|
||||
"Invalid or unsupported offload target: '%0'.">;
|
||||
}
|
||||
|
@ -191,6 +191,7 @@ def DeprecatedVolatile : DiagGroup<"deprecated-volatile">;
|
||||
def DeprecatedWritableStr : DiagGroup<"deprecated-writable-strings",
|
||||
[CXX11CompatDeprecatedWritableStr]>;
|
||||
def DeprecatedPragma : DiagGroup<"deprecated-pragma">;
|
||||
def DeprecatedType : DiagGroup<"deprecated-type">;
|
||||
// FIXME: Why is DeprecatedImplementations not in this group?
|
||||
def Deprecated : DiagGroup<"deprecated", [DeprecatedAnonEnumEnumConversion,
|
||||
DeprecatedArrayCompare,
|
||||
@ -208,6 +209,7 @@ def Deprecated : DiagGroup<"deprecated", [DeprecatedAnonEnumEnumConversion,
|
||||
DeprecatedPragma,
|
||||
DeprecatedRegister,
|
||||
DeprecatedThisCapture,
|
||||
DeprecatedType,
|
||||
DeprecatedVolatile,
|
||||
DeprecatedWritableStr]>,
|
||||
DiagCategory<"Deprecations">;
|
||||
@ -1044,6 +1046,13 @@ def : DiagGroup<"unused-local-typedefs", [UnusedLocalTypedef]>;
|
||||
def NonGCC : DiagGroup<"non-gcc",
|
||||
[SignCompare, Conversion, LiteralRange]>;
|
||||
|
||||
def CXX14Attrs : DiagGroup<"c++14-attribute-extensions">;
|
||||
def CXX17Attrs : DiagGroup<"c++17-attribute-extensions">;
|
||||
def CXX20Attrs : DiagGroup<"c++20-attribute-extensions">;
|
||||
def FutureAttrs : DiagGroup<"future-attribute-extensions", [CXX14Attrs,
|
||||
CXX17Attrs,
|
||||
CXX20Attrs]>;
|
||||
|
||||
// A warning group for warnings about using C++11 features as extensions in
|
||||
// earlier C++ versions.
|
||||
def CXX11 : DiagGroup<"c++11-extensions", [CXX11ExtraSemi, CXX11InlineNamespace,
|
||||
@ -1051,15 +1060,15 @@ def CXX11 : DiagGroup<"c++11-extensions", [CXX11ExtraSemi, CXX11InlineNamespace,
|
||||
|
||||
// A warning group for warnings about using C++14 features as extensions in
|
||||
// earlier C++ versions.
|
||||
def CXX14 : DiagGroup<"c++14-extensions", [CXX14BinaryLiteral]>;
|
||||
def CXX14 : DiagGroup<"c++14-extensions", [CXX14BinaryLiteral, CXX14Attrs]>;
|
||||
|
||||
// A warning group for warnings about using C++17 features as extensions in
|
||||
// earlier C++ versions.
|
||||
def CXX17 : DiagGroup<"c++17-extensions">;
|
||||
def CXX17 : DiagGroup<"c++17-extensions", [CXX17Attrs]>;
|
||||
|
||||
// A warning group for warnings about using C++20 features as extensions in
|
||||
// earlier C++ versions.
|
||||
def CXX20 : DiagGroup<"c++20-extensions", [CXX20Designator]>;
|
||||
def CXX20 : DiagGroup<"c++20-extensions", [CXX20Designator, CXX20Attrs]>;
|
||||
|
||||
// A warning group for warnings about using C++2b features as extensions in
|
||||
// earlier C++ versions.
|
||||
|
@ -1503,6 +1503,15 @@ def warn_pragma_force_cuda_host_device_bad_arg : Warning<
|
||||
def err_pragma_cannot_end_force_cuda_host_device : Error<
|
||||
"force_cuda_host_device end pragma without matching "
|
||||
"force_cuda_host_device begin">;
|
||||
|
||||
def warn_ext_int_deprecated : Warning<
|
||||
"'_ExtInt' is deprecated; use '_BitInt' instead">, InGroup<DeprecatedType>;
|
||||
def ext_bit_int : Extension<
|
||||
"'_BitInt' in %select{C17 and earlier|C++}0 is a Clang extension">,
|
||||
InGroup<DiagGroup<"bit-int-extension">>;
|
||||
def warn_c17_compat_bit_int : Warning<
|
||||
"'_BitInt' is incompatible with C standards before C2x">,
|
||||
InGroup<CPre2xCompat>, DefaultIgnore;
|
||||
} // end of Parse Issue category.
|
||||
|
||||
let CategoryName = "Modules Issue" in {
|
||||
|
@ -838,6 +838,9 @@ def warn_fortify_scanf_overflow : Warning<
|
||||
"%2, but the corresponding specifier may require size %3">,
|
||||
InGroup<FortifySource>;
|
||||
|
||||
def err_function_start_invalid_type: Error<
|
||||
"argument must be a function">;
|
||||
|
||||
/// main()
|
||||
// static main() is not an error in C, just in C++.
|
||||
def warn_static_main : Warning<"'main' should not be declared static">,
|
||||
@ -2956,6 +2959,17 @@ def err_attribute_invalid_argument : Error<
|
||||
def err_attribute_wrong_number_arguments : Error<
|
||||
"%0 attribute %plural{0:takes no arguments|1:takes one argument|"
|
||||
":requires exactly %1 arguments}1">;
|
||||
def err_attribute_wrong_number_arguments_for : Error <
|
||||
"%0 attribute references function %1, which %plural{0:takes no arguments|1:takes one argument|"
|
||||
":takes exactly %2 arguments}2">;
|
||||
def err_attribute_bounds_for_function : Error<
|
||||
"%0 attribute references parameter %1, but the function %2 has only %3 parameters">;
|
||||
def err_attribute_no_member_function : Error<
|
||||
"%0 attribute cannot be applied to non-static member functions">;
|
||||
def err_attribute_parameter_types : Error<
|
||||
"%0 attribute parameter types do not match: parameter %1 of function %2 has type %3, "
|
||||
"but parameter %4 of function %5 has type %6">;
|
||||
|
||||
def err_attribute_too_many_arguments : Error<
|
||||
"%0 attribute takes no more than %1 argument%s1">;
|
||||
def err_attribute_too_few_arguments : Error<
|
||||
@ -3013,7 +3027,7 @@ def err_attribute_sizeless_type : Error<
|
||||
"%0 attribute cannot be applied to sizeless type %1">;
|
||||
def err_attribute_argument_n_type : Error<
|
||||
"%0 attribute requires parameter %1 to be %select{int or bool|an integer "
|
||||
"constant|a string|an identifier|a constant expression}2">;
|
||||
"constant|a string|an identifier|a constant expression|a builtin function}2">;
|
||||
def err_attribute_argument_type : Error<
|
||||
"%0 attribute requires %select{int or bool|an integer "
|
||||
"constant|a string|an identifier}1">;
|
||||
@ -8337,8 +8351,8 @@ def err_atomic_exclusive_builtin_pointer_size : Error<
|
||||
" 1,2,4 or 8 byte type (%0 invalid)">;
|
||||
def err_atomic_builtin_ext_int_size : Error<
|
||||
"Atomic memory operand must have a power-of-two size">;
|
||||
def err_atomic_builtin_ext_int_prohibit : Error<
|
||||
"argument to atomic builtin of type '_ExtInt' is not supported">;
|
||||
def err_atomic_builtin_bit_int_prohibit : Error<
|
||||
"argument to atomic builtin of type '_BitInt' is not supported">;
|
||||
def err_atomic_op_needs_atomic : Error<
|
||||
"address argument to atomic operation must be a pointer to _Atomic "
|
||||
"type (%0 invalid)">;
|
||||
@ -8374,8 +8388,8 @@ def err_overflow_builtin_must_be_int : Error<
|
||||
def err_overflow_builtin_must_be_ptr_int : Error<
|
||||
"result argument to overflow builtin must be a pointer "
|
||||
"to a non-const integer (%0 invalid)">;
|
||||
def err_overflow_builtin_ext_int_max_size : Error<
|
||||
"__builtin_mul_overflow does not support signed _ExtInt operands of more "
|
||||
def err_overflow_builtin_bit_int_max_size : Error<
|
||||
"__builtin_mul_overflow does not support 'signed _BitInt' operands of more "
|
||||
"than %0 bits">;
|
||||
|
||||
def err_atomic_load_store_uses_lib : Error<
|
||||
@ -8626,11 +8640,11 @@ def warn_unused_volatile : Warning<
|
||||
InGroup<DiagGroup<"unused-volatile-lvalue">>;
|
||||
|
||||
def ext_cxx14_attr : Extension<
|
||||
"use of the %0 attribute is a C++14 extension">, InGroup<CXX14>;
|
||||
"use of the %0 attribute is a C++14 extension">, InGroup<CXX14Attrs>;
|
||||
def ext_cxx17_attr : Extension<
|
||||
"use of the %0 attribute is a C++17 extension">, InGroup<CXX17>;
|
||||
"use of the %0 attribute is a C++17 extension">, InGroup<CXX17Attrs>;
|
||||
def ext_cxx20_attr : Extension<
|
||||
"use of the %0 attribute is a C++20 extension">, InGroup<CXX20>;
|
||||
"use of the %0 attribute is a C++20 extension">, InGroup<CXX20Attrs>;
|
||||
|
||||
def warn_unused_comparison : Warning<
|
||||
"%select{equality|inequality|relational|three-way}0 comparison result unused">,
|
||||
@ -9140,15 +9154,22 @@ def warn_cxx17_compat_defaulted_comparison : Warning<
|
||||
"before C++20">, InGroup<CXXPre20Compat>, DefaultIgnore;
|
||||
def err_defaulted_comparison_template : Error<
|
||||
"comparison operator template cannot be defaulted">;
|
||||
def err_defaulted_comparison_out_of_class : Error<
|
||||
"%sub{select_defaulted_comparison_kind}0 can only be defaulted in a class "
|
||||
"definition">;
|
||||
def err_defaulted_comparison_num_args : Error<
|
||||
"%select{non-member|member}0 %sub{select_defaulted_comparison_kind}1"
|
||||
" comparison operator must have %select{2|1}0 parameters">;
|
||||
def err_defaulted_comparison_param : Error<
|
||||
"invalid parameter type for defaulted %sub{select_defaulted_comparison_kind}0"
|
||||
"; found %1, expected %2%select{| or %4}3">;
|
||||
def err_defaulted_comparison_param_unknown : Error<
|
||||
"invalid parameter type for non-member defaulted"
|
||||
" %sub{select_defaulted_comparison_kind}0"
|
||||
"; found %1, expected class or reference to a constant class">;
|
||||
def err_defaulted_comparison_param_mismatch : Error<
|
||||
"parameters for defaulted %sub{select_defaulted_comparison_kind}0 "
|
||||
"must have the same type%diff{ (found $ vs $)|}1,2">;
|
||||
def err_defaulted_comparison_not_friend : Error<
|
||||
"%sub{select_defaulted_comparison_kind}0 is not a friend of"
|
||||
" %select{|incomplete class }1%2">;
|
||||
def err_defaulted_comparison_non_const : Error<
|
||||
"defaulted member %sub{select_defaulted_comparison_kind}0 must be "
|
||||
"const-qualified">;
|
||||
@ -9811,6 +9832,8 @@ def err_ppc_builtin_only_on_arch : Error<
|
||||
"this builtin is only valid on POWER%0 or later CPUs">;
|
||||
def err_ppc_builtin_requires_vsx : Error<
|
||||
"this builtin requires VSX to be enabled">;
|
||||
def err_ppc_builtin_requires_htm : Error<
|
||||
"this builtin requires HTM to be enabled">;
|
||||
def err_ppc_builtin_requires_abi : Error<
|
||||
"this builtin requires ABI -mabi=%0">;
|
||||
def err_ppc_invalid_use_mma_type : Error<
|
||||
@ -10486,7 +10509,7 @@ def err_omp_atomic_capture_not_compound_statement : Error<
|
||||
def note_omp_atomic_capture: Note<
|
||||
"%select{expected assignment expression|expected compound statement|expected exactly two expression statements|expected in right hand side of the first expression}0">;
|
||||
def err_omp_atomic_several_clauses : Error<
|
||||
"directive '#pragma omp atomic' cannot contain more than one 'read', 'write', 'update' or 'capture' clause">;
|
||||
"directive '#pragma omp atomic' cannot contain more than one 'read', 'write', 'update', 'capture', or 'compare' clause">;
|
||||
def err_omp_several_mem_order_clauses : Error<
|
||||
"directive '#pragma omp %0' cannot contain more than one %select{'seq_cst', 'relaxed', |}1'acq_rel', 'acquire' or 'release' clause">;
|
||||
def err_omp_atomic_incompatible_mem_order_clause : Error<
|
||||
@ -11020,14 +11043,12 @@ def err_implied_coroutine_type_not_found : Error<
|
||||
"a coroutine; include <experimental/coroutine> if your version "
|
||||
"of libcxx is less than 14.0">;
|
||||
def warn_deprecated_coroutine_namespace : Warning<
|
||||
"Please move from std::experimental::%0 to std::%0. "
|
||||
"Support for std::experimental::%0 will be removed in LLVM 15.">,
|
||||
"support for std::experimental::%0 will be removed in LLVM 15; "
|
||||
"use std::%0 instead">,
|
||||
InGroup<DeprecatedExperimentalCoroutine>;
|
||||
def err_mixed_use_std_and_experimental_namespace_for_coroutine : Error <
|
||||
"Found mixed use of std namespace and std::experimental namespace for "
|
||||
"coroutine, which is disallowed. The coroutine components in "
|
||||
"std::experimental namespace is deprecated. Please use coroutine components "
|
||||
"under std namespace.">;
|
||||
def err_mixed_use_std_and_experimental_namespace_for_coroutine : Error<
|
||||
"mixed use of std and std::experimental namespaces for "
|
||||
"coroutine components">;
|
||||
def err_implicit_coroutine_std_nothrow_type_not_found : Error<
|
||||
"std::nothrow was not found; include <new> before defining a coroutine which "
|
||||
"uses get_return_object_on_allocation_failure()">;
|
||||
@ -11050,8 +11071,6 @@ def err_coroutine_type_missing_specialization : Error<
|
||||
"specialization %0">;
|
||||
def err_coroutine_promise_incompatible_return_functions : Error<
|
||||
"the coroutine promise type %0 declares both 'return_value' and 'return_void'">;
|
||||
def err_coroutine_promise_requires_return_function : Error<
|
||||
"the coroutine promise type %0 must declare either 'return_value' or 'return_void'">;
|
||||
def note_coroutine_promise_implicit_await_transform_required_here : Note<
|
||||
"call to 'await_transform' implicitly required by 'co_await' here">;
|
||||
def note_coroutine_promise_suspend_implicitly_required : Note<
|
||||
@ -11356,7 +11375,9 @@ def err_builtin_invalid_arg_type: Error <
|
||||
"%ordinal0 argument must be a "
|
||||
"%select{vector, integer or floating point type|matrix|"
|
||||
"pointer to a valid matrix element type|"
|
||||
"signed integer or floating point type|vector type}1 (was %2)">;
|
||||
"signed integer or floating point type|vector type|"
|
||||
"floating point type|"
|
||||
"vector of integers}1 (was %2)">;
|
||||
|
||||
def err_builtin_matrix_disabled: Error<
|
||||
"matrix types extension is disabled. Pass -fenable-matrix to enable it">;
|
||||
@ -11423,9 +11444,9 @@ def warn_sycl_kernel_return_type : Warning<
|
||||
"function template with 'sycl_kernel' attribute must have a 'void' return type">,
|
||||
InGroup<IgnoredAttributes>;
|
||||
|
||||
def err_ext_int_bad_size : Error<"%select{signed|unsigned}0 _ExtInt must "
|
||||
def err_bit_int_bad_size : Error<"%select{signed|unsigned}0 _BitInt must "
|
||||
"have a bit size of at least %select{2|1}0">;
|
||||
def err_ext_int_max_size : Error<"%select{signed|unsigned}0 _ExtInt of bit "
|
||||
def err_bit_int_max_size : Error<"%select{signed|unsigned}0 _BitInt of bit "
|
||||
"sizes greater than %1 not supported">;
|
||||
|
||||
// errors of expect.with.probability
|
||||
|
@ -153,6 +153,10 @@ class Module {
|
||||
return Kind == ModuleInterfaceUnit || Kind == PrivateModuleFragment;
|
||||
}
|
||||
|
||||
/// Does this Module scope describe a fragment of the global module within
|
||||
/// some C++ module.
|
||||
bool isGlobalModule() const { return Kind == GlobalModuleFragment; }
|
||||
|
||||
private:
|
||||
/// The submodules of this module, indexed by name.
|
||||
std::vector<Module *> SubModules;
|
||||
|
@ -59,7 +59,7 @@ namespace clang {
|
||||
TST_char32, // C++11 char32_t
|
||||
TST_int,
|
||||
TST_int128,
|
||||
TST_extint, // Extended Int types.
|
||||
TST_bitint, // Bit-precise integer types.
|
||||
TST_half, // OpenCL half, ARM NEON __fp16
|
||||
TST_Float16, // C11 extension ISO/IEC TS 18661-3
|
||||
TST_Accum, // ISO/IEC JTC1 SC22 WG14 N1169 Extension
|
||||
|
@ -582,9 +582,13 @@ class TargetInfo : public virtual TransferrableTargetInfo,
|
||||
return (getPointerWidth(0) >= 64) || getTargetOpts().ForceEnableInt128;
|
||||
} // FIXME
|
||||
|
||||
/// Determine whether the _ExtInt type is supported on this target. This
|
||||
/// Determine whether the _BitInt type is supported on this target. This
|
||||
/// limitation is put into place for ABI reasons.
|
||||
virtual bool hasExtIntType() const {
|
||||
/// FIXME: _BitInt is a required type in C23, so there's not much utility in
|
||||
/// asking whether the target supported it or not; I think this should be
|
||||
/// removed once backends have been alerted to the type and have had the
|
||||
/// chance to do implementation work if needed.
|
||||
virtual bool hasBitIntType() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -300,6 +300,7 @@ KEYWORD(if , KEYALL)
|
||||
KEYWORD(inline , KEYC99|KEYCXX|KEYGNU)
|
||||
KEYWORD(int , KEYALL)
|
||||
KEYWORD(_ExtInt , KEYALL)
|
||||
KEYWORD(_BitInt , KEYALL)
|
||||
KEYWORD(long , KEYALL)
|
||||
KEYWORD(register , KEYALL)
|
||||
KEYWORD(restrict , KEYC99)
|
||||
|
@ -75,6 +75,7 @@ def DependentSizedMatrixType : TypeNode<MatrixType>, AlwaysDependent;
|
||||
def FunctionType : TypeNode<Type, 1>;
|
||||
def FunctionProtoType : TypeNode<FunctionType>;
|
||||
def FunctionNoProtoType : TypeNode<FunctionType>;
|
||||
def UsingType : TypeNode<Type>, NeverCanonical;
|
||||
def UnresolvedUsingType : TypeNode<Type>, AlwaysDependent;
|
||||
def ParenType : TypeNode<Type>, NeverCanonical;
|
||||
def TypedefType : TypeNode<Type>, NeverCanonical;
|
||||
@ -107,5 +108,5 @@ def ObjCInterfaceType : TypeNode<ObjCObjectType>, LeafType;
|
||||
def ObjCObjectPointerType : TypeNode<Type>;
|
||||
def PipeType : TypeNode<Type>;
|
||||
def AtomicType : TypeNode<Type>;
|
||||
def ExtIntType : TypeNode<Type>;
|
||||
def DependentExtIntType : TypeNode<Type>, AlwaysDependent;
|
||||
def BitIntType : TypeNode<Type>;
|
||||
def DependentBitIntType : TypeNode<Type>, AlwaysDependent;
|
||||
|
@ -595,6 +595,21 @@ class Driver {
|
||||
|
||||
/// @}
|
||||
|
||||
/// Retrieves a ToolChain for a particular device \p Target triple
|
||||
///
|
||||
/// \param[in] HostTC is the host ToolChain paired with the device
|
||||
///
|
||||
/// \param[in] Action (e.g. OFK_Cuda/OFK_OpenMP/OFK_SYCL) is an Offloading
|
||||
/// action that is optionally passed to a ToolChain (used by CUDA, to specify
|
||||
/// if it's used in conjunction with OpenMP)
|
||||
///
|
||||
/// Will cache ToolChains for the life of the driver object, and create them
|
||||
/// on-demand.
|
||||
const ToolChain &getOffloadingDeviceToolChain(
|
||||
const llvm::opt::ArgList &Args, const llvm::Triple &Target,
|
||||
const ToolChain &HostTC,
|
||||
const Action::OffloadKind &TargetDeviceOffloadKind) const;
|
||||
|
||||
/// Get bitmasks for which option flags to include and exclude based on
|
||||
/// the driver mode.
|
||||
std::pair<unsigned, unsigned> getIncludeExcludeOptionFlagMasks(bool IsClCompatMode) const;
|
||||
|
@ -204,6 +204,10 @@ class Command {
|
||||
/// from the parent process will be used.
|
||||
virtual void setEnvironment(llvm::ArrayRef<const char *> NewEnvironment);
|
||||
|
||||
void replaceArguments(llvm::opt::ArgStringList List) {
|
||||
Arguments = std::move(List);
|
||||
}
|
||||
|
||||
const char *getExecutable() const { return Executable; }
|
||||
|
||||
const llvm::opt::ArgStringList &getArguments() const { return Arguments; }
|
||||
|
@ -985,6 +985,9 @@ defm hip_fp32_correctly_rounded_divide_sqrt : BoolFOption<"hip-fp32-correctly-ro
|
||||
BothFlags<[], " that single precision floating-point divide and sqrt used in "
|
||||
"the program source are correctly rounded (HIP device compilation only)">>,
|
||||
ShouldParseIf<hip.KeyPath>;
|
||||
def hipspv_pass_plugin_EQ : Joined<["--"], "hipspv-pass-plugin=">,
|
||||
Group<Link_Group>, MetaVarName<"<dsopath>">,
|
||||
HelpText<"path to a pass plugin for HIP to SPIR-V passes.">;
|
||||
defm gpu_allow_device_init : BoolFOption<"gpu-allow-device-init",
|
||||
LangOpts<"GPUAllowDeviceInit">, DefaultFalse,
|
||||
PosFlag<SetTrue, [CC1Option], "Allow">, NegFlag<SetFalse, [], "Don't allow">,
|
||||
@ -1132,6 +1135,13 @@ defm autolink : BoolFOption<"autolink",
|
||||
NegFlag<SetFalse, [CC1Option], "Disable generation of linker directives for automatic library linking">,
|
||||
PosFlag<SetTrue>>;
|
||||
|
||||
// In the future this option will be supported by other offloading
|
||||
// languages and accept other values such as CPU/GPU architectures,
|
||||
// offload kinds and target aliases.
|
||||
def offload_EQ : CommaJoined<["--"], "offload=">, Flags<[NoXarchOption]>,
|
||||
HelpText<"Specify comma-separated list of offloading target triples"
|
||||
" (HIP only)">;
|
||||
|
||||
// C++ Coroutines TS
|
||||
defm coroutines_ts : BoolFOption<"coroutines-ts",
|
||||
LangOpts<"Coroutines">, Default<cpp20.KeyPath>,
|
||||
@ -2392,7 +2402,8 @@ def fomit_frame_pointer : Flag<["-"], "fomit-frame-pointer">, Group<f_Group>;
|
||||
def fopenmp : Flag<["-"], "fopenmp">, Group<f_Group>, Flags<[CC1Option, NoArgumentUnused, FlangOption, FC1Option]>,
|
||||
HelpText<"Parse OpenMP pragmas and generate parallel code.">;
|
||||
def fno_openmp : Flag<["-"], "fno-openmp">, Group<f_Group>, Flags<[NoArgumentUnused]>;
|
||||
def fopenmp_version_EQ : Joined<["-"], "fopenmp-version=">, Group<f_Group>, Flags<[CC1Option, NoArgumentUnused]>;
|
||||
def fopenmp_version_EQ : Joined<["-"], "fopenmp-version=">, Group<f_Group>, Flags<[CC1Option, NoArgumentUnused]>,
|
||||
HelpText<"Set OpenMP version (e.g. 45 for OpenMP 4.5, 50 for OpenMP 5.0). Default value is 50.">;
|
||||
defm openmp_extensions: BoolFOption<"openmp-extensions",
|
||||
LangOpts<"OpenMPExtensions">, DefaultTrue,
|
||||
PosFlag<SetTrue, [CC1Option, NoArgumentUnused],
|
||||
@ -2442,7 +2453,7 @@ def fno_openmp_assume_teams_oversubscription : Flag<["-"], "fno-openmp-assume-te
|
||||
def fno_openmp_assume_threads_oversubscription : Flag<["-"], "fno-openmp-assume-threads-oversubscription">,
|
||||
Group<f_Group>, Flags<[CC1Option, NoArgumentUnused, HelpHidden]>;
|
||||
defm openmp_target_new_runtime: BoolFOption<"openmp-target-new-runtime",
|
||||
LangOpts<"OpenMPTargetNewRuntime">, DefaultFalse,
|
||||
LangOpts<"OpenMPTargetNewRuntime">, DefaultTrue,
|
||||
PosFlag<SetTrue, [CC1Option], "Use the new bitcode library for OpenMP offloading">,
|
||||
NegFlag<SetFalse>>;
|
||||
defm openmp_optimistic_collapse : BoolFOption<"openmp-optimistic-collapse",
|
||||
@ -3338,6 +3349,11 @@ def mno_fix_cortex_a53_835769 : Flag<["-"], "mno-fix-cortex-a53-835769">,
|
||||
def mmark_bti_property : Flag<["-"], "mmark-bti-property">,
|
||||
Group<m_aarch64_Features_Group>,
|
||||
HelpText<"Add .note.gnu.property with BTI to assembly files (AArch64 only)">;
|
||||
def mno_bti_at_return_twice : Flag<["-"], "mno-bti-at-return-twice">,
|
||||
Group<m_arm_Features_Group>,
|
||||
HelpText<"Do not add a BTI instruction after a setjmp or other"
|
||||
" return-twice construct (Arm only)">;
|
||||
|
||||
foreach i = {1-31} in
|
||||
def ffixed_x#i : Flag<["-"], "ffixed-x"#i>, Group<m_Group>,
|
||||
HelpText<"Reserve the x"#i#" register (AArch64/RISC-V only)">;
|
||||
@ -3352,8 +3368,7 @@ def msve_vector_bits_EQ : Joined<["-"], "msve-vector-bits=">, Group<m_aarch64_Fe
|
||||
|
||||
def mvscale_min_EQ : Joined<["-"], "mvscale-min=">,
|
||||
Group<m_aarch64_Features_Group>, Flags<[NoXarchOption,CC1Option]>,
|
||||
HelpText<"Specify the vscale minimum. Defaults to the"
|
||||
" vector length agnostic value of \"0\". (AArch64 only)">,
|
||||
HelpText<"Specify the vscale minimum. Defaults to \"1\". (AArch64 only)">,
|
||||
MarshallingInfoInt<LangOpts<"VScaleMin">>;
|
||||
def mvscale_max_EQ : Joined<["-"], "mvscale-max=">,
|
||||
Group<m_aarch64_Features_Group>, Flags<[NoXarchOption,CC1Option]>,
|
||||
@ -3759,6 +3774,8 @@ def nobuiltininc : Flag<["-"], "nobuiltininc">, Flags<[CC1Option, CoreOption]>,
|
||||
MarshallingInfoNegativeFlag<HeaderSearchOpts<"UseBuiltinIncludes">>;
|
||||
def nogpuinc : Flag<["-"], "nogpuinc">, HelpText<"Do not add include paths for CUDA/HIP and"
|
||||
" do not include the default CUDA/HIP wrapper headers">;
|
||||
def nohipwrapperinc : Flag<["-"], "nohipwrapperinc">,
|
||||
HelpText<"Do not include the default HIP wrapper headers and include paths">;
|
||||
def : Flag<["-"], "nocudainc">, Alias<nogpuinc>;
|
||||
def nogpulib : Flag<["-"], "nogpulib">,
|
||||
HelpText<"Do not link device library for CUDA/HIP device compilation">;
|
||||
@ -3785,6 +3802,11 @@ def o : JoinedOrSeparate<["-"], "o">, Flags<[NoXarchOption, RenderAsInput,
|
||||
CC1Option, CC1AsOption, FC1Option, FlangOption]>,
|
||||
HelpText<"Write output to <file>">, MetaVarName<"<file>">,
|
||||
MarshallingInfoString<FrontendOpts<"OutputFile">>;
|
||||
def object_file_name_EQ : Joined<["-"], "object-file-name=">, Flags<[CC1Option, CC1AsOption, CoreOption]>,
|
||||
HelpText<"Set the output <file> for debug infos">, MetaVarName<"<file>">,
|
||||
MarshallingInfoString<CodeGenOpts<"ObjectFilenameForDebug">>;
|
||||
def object_file_name : Separate<["-"], "object-file-name">, Flags<[CC1Option, CC1AsOption, CoreOption]>,
|
||||
Alias<object_file_name_EQ>;
|
||||
def pagezero__size : JoinedOrSeparate<["-"], "pagezero_size">;
|
||||
def pass_exit_codes : Flag<["-", "--"], "pass-exit-codes">, Flags<[Unsupported]>;
|
||||
def pedantic_errors : Flag<["-", "--"], "pedantic-errors">, Group<pedantic_Group>, Flags<[CC1Option]>,
|
||||
@ -4138,6 +4160,8 @@ def mv67t : Flag<["-"], "mv67t">, Group<m_hexagon_Features_Group>,
|
||||
Alias<mcpu_EQ>, AliasArgs<["hexagonv67t"]>;
|
||||
def mv68 : Flag<["-"], "mv68">, Group<m_hexagon_Features_Group>,
|
||||
Alias<mcpu_EQ>, AliasArgs<["hexagonv68"]>;
|
||||
def mv69 : Flag<["-"], "mv69">, Group<m_hexagon_Features_Group>,
|
||||
Alias<mcpu_EQ>, AliasArgs<["hexagonv69"]>;
|
||||
def mhexagon_hvx : Flag<["-"], "mhvx">, Group<m_hexagon_Features_HVX_Group>,
|
||||
HelpText<"Enable Hexagon Vector eXtensions">;
|
||||
def mhexagon_hvx_EQ : Joined<["-"], "mhvx=">,
|
||||
@ -4149,6 +4173,18 @@ def mno_hexagon_hvx : Flag<["-"], "mno-hvx">,
|
||||
def mhexagon_hvx_length_EQ : Joined<["-"], "mhvx-length=">,
|
||||
Group<m_hexagon_Features_HVX_Group>, HelpText<"Set Hexagon Vector Length">,
|
||||
Values<"64B,128B">;
|
||||
def mhexagon_hvx_qfloat : Flag<["-"], "mhvx-qfloat">,
|
||||
Group<m_hexagon_Features_HVX_Group>,
|
||||
HelpText<"Enable Hexagon HVX QFloat instructions">;
|
||||
def mno_hexagon_hvx_qfloat : Flag<["-"], "mno-hvx-qfloat">,
|
||||
Group<m_hexagon_Features_HVX_Group>,
|
||||
HelpText<"Disable Hexagon HVX QFloat instructions">;
|
||||
def mhexagon_hvx_ieee_fp : Flag<["-"], "mhvx-ieee-fp">,
|
||||
Group<m_hexagon_Features_Group>,
|
||||
HelpText<"Enable Hexagon HVX IEEE floating-point">;
|
||||
def mno_hexagon_hvx_ieee_fp : Flag<["-"], "mno-hvx-ieee-fp">,
|
||||
Group<m_hexagon_Features_Group>,
|
||||
HelpText<"Disable Hexagon HVX IEEE floating-point">;
|
||||
def ffixed_r19: Flag<["-"], "ffixed-r19">,
|
||||
HelpText<"Reserve register r19 (Hexagon only)">;
|
||||
def mmemops : Flag<["-"], "mmemops">, Group<m_hexagon_Features_Group>,
|
||||
|
@ -52,6 +52,7 @@ class Tool {
|
||||
const ToolChain &getToolChain() const { return TheToolChain; }
|
||||
|
||||
virtual bool hasIntegratedAssembler() const { return false; }
|
||||
virtual bool hasIntegratedBackend() const { return true; }
|
||||
virtual bool canEmitIR() const { return false; }
|
||||
virtual bool hasIntegratedCPP() const = 0;
|
||||
virtual bool isLinkJob() const { return false; }
|
||||
|
@ -348,10 +348,7 @@ class ToolChain {
|
||||
/// is LLD. If it's set, it can be assumed that the linker is LLD built
|
||||
/// at the same revision as clang, and clang can make assumptions about
|
||||
/// LLD's supported flags, error output, etc.
|
||||
/// If LinkerIsLLDDarwinNew is non-nullptr, it's set if the linker is
|
||||
/// the new version in lld/MachO.
|
||||
std::string GetLinkerPath(bool *LinkerIsLLD = nullptr,
|
||||
bool *LinkerIsLLDDarwinNew = nullptr) const;
|
||||
std::string GetLinkerPath(bool *LinkerIsLLD = nullptr) const;
|
||||
|
||||
/// Returns the linker path for emitting a static library.
|
||||
std::string GetStaticLibToolPath() const;
|
||||
@ -387,6 +384,9 @@ class ToolChain {
|
||||
/// Check if the toolchain should use the integrated assembler.
|
||||
virtual bool useIntegratedAs() const;
|
||||
|
||||
/// Check if the toolchain should use the integrated backend.
|
||||
virtual bool useIntegratedBackend() const { return true; }
|
||||
|
||||
/// Check if the toolchain should use AsmParser to parse inlineAsm when
|
||||
/// integrated assembler is not default.
|
||||
virtual bool parseInlineAsmUsingAsmParser() const { return false; }
|
||||
|
@ -2669,6 +2669,7 @@ struct FormatStyle {
|
||||
bool isCpp() const { return Language == LK_Cpp || Language == LK_ObjC; }
|
||||
bool isCSharp() const { return Language == LK_CSharp; }
|
||||
bool isJson() const { return Language == LK_Json; }
|
||||
bool isJavaScript() const { return Language == LK_JavaScript; }
|
||||
|
||||
/// Language, this format style is targeted at.
|
||||
/// \version 3.5
|
||||
|
@ -538,8 +538,11 @@ class ModuleMap {
|
||||
///
|
||||
/// We model the global module fragment as a submodule of the module
|
||||
/// interface unit. Unfortunately, we can't create the module interface
|
||||
/// unit's Module until later, because we don't know what it will be called.
|
||||
Module *createGlobalModuleFragmentForModuleUnit(SourceLocation Loc);
|
||||
/// unit's Module until later, because we don't know what it will be called
|
||||
/// usually. See C++20 [module.unit]/7.2 for the case we could know its
|
||||
/// parent.
|
||||
Module *createGlobalModuleFragmentForModuleUnit(SourceLocation Loc,
|
||||
Module *Parent = nullptr);
|
||||
|
||||
/// Create a global module fragment for a C++ module interface unit.
|
||||
Module *createPrivateModuleFragmentForInterfaceUnit(Module *Parent,
|
||||
|
@ -2564,6 +2564,10 @@ class Parser : public CodeCompletionHandler {
|
||||
/// full validation of the syntactic structure of attributes.
|
||||
bool TrySkipAttributes();
|
||||
|
||||
/// Diagnoses use of _ExtInt as being deprecated, and diagnoses use of
|
||||
/// _BitInt as an extension when appropriate.
|
||||
void DiagnoseBitIntUse(const Token &Tok);
|
||||
|
||||
public:
|
||||
TypeResult
|
||||
ParseTypeName(SourceRange *Range = nullptr,
|
||||
|
@ -266,7 +266,7 @@ class DeclSpec {
|
||||
static const TST TST_char32 = clang::TST_char32;
|
||||
static const TST TST_int = clang::TST_int;
|
||||
static const TST TST_int128 = clang::TST_int128;
|
||||
static const TST TST_extint = clang::TST_extint;
|
||||
static const TST TST_bitint = clang::TST_bitint;
|
||||
static const TST TST_half = clang::TST_half;
|
||||
static const TST TST_BFloat16 = clang::TST_BFloat16;
|
||||
static const TST TST_float = clang::TST_float;
|
||||
@ -404,7 +404,7 @@ class DeclSpec {
|
||||
T == TST_underlyingType || T == TST_atomic);
|
||||
}
|
||||
static bool isExprRep(TST T) {
|
||||
return (T == TST_typeofExpr || T == TST_decltype || T == TST_extint);
|
||||
return (T == TST_typeofExpr || T == TST_decltype || T == TST_bitint);
|
||||
}
|
||||
static bool isTemplateIdRep(TST T) {
|
||||
return (T == TST_auto || T == TST_decltype_auto);
|
||||
@ -703,7 +703,7 @@ class DeclSpec {
|
||||
bool SetTypePipe(bool isPipe, SourceLocation Loc,
|
||||
const char *&PrevSpec, unsigned &DiagID,
|
||||
const PrintingPolicy &Policy);
|
||||
bool SetExtIntType(SourceLocation KWLoc, Expr *BitWidth,
|
||||
bool SetBitIntType(SourceLocation KWLoc, Expr *BitWidth,
|
||||
const char *&PrevSpec, unsigned &DiagID,
|
||||
const PrintingPolicy &Policy);
|
||||
bool SetTypeSpecSat(SourceLocation Loc, const char *&PrevSpec,
|
||||
|
@ -1097,6 +1097,7 @@ enum AttributeArgumentNType {
|
||||
AANT_ArgumentString,
|
||||
AANT_ArgumentIdentifier,
|
||||
AANT_ArgumentConstantExpr,
|
||||
AANT_ArgumentBuiltinFunction,
|
||||
};
|
||||
|
||||
/// These constants match the enumerated choices of
|
||||
|
@ -1324,12 +1324,15 @@ class Sema final {
|
||||
|
||||
bool isImmediateFunctionContext() const {
|
||||
return Context == ExpressionEvaluationContext::ImmediateFunctionContext ||
|
||||
InImmediateFunctionContext;
|
||||
(Context == ExpressionEvaluationContext::DiscardedStatement &&
|
||||
InImmediateFunctionContext);
|
||||
}
|
||||
|
||||
bool isDiscardedStatementContext() const {
|
||||
return Context == ExpressionEvaluationContext::DiscardedStatement ||
|
||||
InDiscardedStatement;
|
||||
(Context ==
|
||||
ExpressionEvaluationContext::ImmediateFunctionContext &&
|
||||
InDiscardedStatement);
|
||||
}
|
||||
};
|
||||
|
||||
@ -2043,7 +2046,7 @@ class Sema final {
|
||||
SourceLocation Loc);
|
||||
QualType BuildWritePipeType(QualType T,
|
||||
SourceLocation Loc);
|
||||
QualType BuildExtIntType(bool IsUnsigned, Expr *BitWidth, SourceLocation Loc);
|
||||
QualType BuildBitIntType(bool IsUnsigned, Expr *BitWidth, SourceLocation Loc);
|
||||
|
||||
TypeSourceInfo *GetTypeForDeclarator(Declarator &D, Scope *S);
|
||||
TypeSourceInfo *GetTypeForDeclaratorCast(Declarator &D, QualType FromTy);
|
||||
@ -2219,6 +2222,17 @@ class Sema final {
|
||||
return ModuleScopes.empty() ? nullptr : ModuleScopes.back().Module;
|
||||
}
|
||||
|
||||
/// Helper function to judge if we are in module purview.
|
||||
/// Return false if we are not in a module.
|
||||
bool isCurrentModulePurview() const {
|
||||
return getCurrentModule() ? getCurrentModule()->isModulePurview() : false;
|
||||
}
|
||||
|
||||
/// Enter the scope of the global module.
|
||||
Module *PushGlobalModuleFragment(SourceLocation BeginLoc, bool IsImplicit);
|
||||
/// Leave the scope of the global module.
|
||||
void PopGlobalModuleFragment();
|
||||
|
||||
VisibleModuleSet VisibleModules;
|
||||
|
||||
public:
|
||||
@ -11176,6 +11190,9 @@ class Sema final {
|
||||
/// Called on well-formed 'capture' clause.
|
||||
OMPClause *ActOnOpenMPCaptureClause(SourceLocation StartLoc,
|
||||
SourceLocation EndLoc);
|
||||
/// Called on well-formed 'compare' clause.
|
||||
OMPClause *ActOnOpenMPCompareClause(SourceLocation StartLoc,
|
||||
SourceLocation EndLoc);
|
||||
/// Called on well-formed 'seq_cst' clause.
|
||||
OMPClause *ActOnOpenMPSeqCstClause(SourceLocation StartLoc,
|
||||
SourceLocation EndLoc);
|
||||
@ -12769,8 +12786,8 @@ class Sema final {
|
||||
bool CheckPPCMMAType(QualType Type, SourceLocation TypeLoc);
|
||||
|
||||
bool SemaBuiltinElementwiseMath(CallExpr *TheCall);
|
||||
bool SemaBuiltinElementwiseMathOneArg(CallExpr *TheCall);
|
||||
bool SemaBuiltinReduceMath(CallExpr *TheCall);
|
||||
bool PrepareBuiltinElementwiseMathOneArgCall(CallExpr *TheCall);
|
||||
bool PrepareBuiltinReduceMathOneArgCall(CallExpr *TheCall);
|
||||
|
||||
// Matrix builtin handling.
|
||||
ExprResult SemaBuiltinMatrixTranspose(CallExpr *TheCall,
|
||||
|
@ -58,9 +58,10 @@ TYPE_BIT_CODE(DependentSizedExtVector, DEPENDENT_SIZED_EXT_VECTOR, 46)
|
||||
TYPE_BIT_CODE(DependentAddressSpace, DEPENDENT_ADDRESS_SPACE, 47)
|
||||
TYPE_BIT_CODE(DependentVector, DEPENDENT_SIZED_VECTOR, 48)
|
||||
TYPE_BIT_CODE(MacroQualified, MACRO_QUALIFIED, 49)
|
||||
TYPE_BIT_CODE(ExtInt, EXT_INT, 50)
|
||||
TYPE_BIT_CODE(DependentExtInt, DEPENDENT_EXT_INT, 51)
|
||||
TYPE_BIT_CODE(BitInt, BIT_INT, 50)
|
||||
TYPE_BIT_CODE(DependentBitInt, DEPENDENT_BIT_INT, 51)
|
||||
TYPE_BIT_CODE(ConstantMatrix, CONSTANT_MATRIX, 52)
|
||||
TYPE_BIT_CODE(DependentSizedMatrix, DEPENDENT_SIZE_MATRIX, 53)
|
||||
TYPE_BIT_CODE(Using, USING, 54)
|
||||
|
||||
#undef TYPE_BIT_CODE
|
||||
|
@ -32,7 +32,7 @@ class SValExplainer : public FullSValVisitor<SValExplainer, std::string> {
|
||||
std::string Str;
|
||||
llvm::raw_string_ostream OS(Str);
|
||||
S->printPretty(OS, nullptr, PrintingPolicy(ACtx.getLangOpts()));
|
||||
return OS.str();
|
||||
return Str;
|
||||
}
|
||||
|
||||
bool isThisObject(const SymbolicRegion *R) {
|
||||
@ -69,7 +69,7 @@ class SValExplainer : public FullSValVisitor<SValExplainer, std::string> {
|
||||
std::string Str;
|
||||
llvm::raw_string_ostream OS(Str);
|
||||
OS << "concrete memory address '" << I << "'";
|
||||
return OS.str();
|
||||
return Str;
|
||||
}
|
||||
|
||||
std::string VisitNonLocSymbolVal(nonloc::SymbolVal V) {
|
||||
@ -82,7 +82,7 @@ class SValExplainer : public FullSValVisitor<SValExplainer, std::string> {
|
||||
llvm::raw_string_ostream OS(Str);
|
||||
OS << (I.isSigned() ? "signed " : "unsigned ") << I.getBitWidth()
|
||||
<< "-bit integer '" << I << "'";
|
||||
return OS.str();
|
||||
return Str;
|
||||
}
|
||||
|
||||
std::string VisitNonLocLazyCompoundVal(nonloc::LazyCompoundVal V) {
|
||||
@ -123,7 +123,7 @@ class SValExplainer : public FullSValVisitor<SValExplainer, std::string> {
|
||||
OS << "(" << Visit(S->getLHS()) << ") "
|
||||
<< std::string(BinaryOperator::getOpcodeStr(S->getOpcode())) << " "
|
||||
<< S->getRHS();
|
||||
return OS.str();
|
||||
return Str;
|
||||
}
|
||||
|
||||
// TODO: IntSymExpr doesn't appear in practice.
|
||||
@ -177,7 +177,7 @@ class SValExplainer : public FullSValVisitor<SValExplainer, std::string> {
|
||||
else
|
||||
OS << "'" << Visit(R->getIndex()) << "'";
|
||||
OS << " of " + Visit(R->getSuperRegion());
|
||||
return OS.str();
|
||||
return Str;
|
||||
}
|
||||
|
||||
std::string VisitNonParamVarRegion(const NonParamVarRegion *R) {
|
||||
|
@ -336,6 +336,18 @@ ANALYZER_OPTION(
|
||||
"might be modeled by the analyzer to never return NULL.",
|
||||
false)
|
||||
|
||||
ANALYZER_OPTION(
|
||||
bool, ShouldIgnoreBisonGeneratedFiles, "ignore-bison-generated-files",
|
||||
"If enabled, any files containing the \"/* A Bison parser, made by\" "
|
||||
"won't be analyzed.",
|
||||
true)
|
||||
|
||||
ANALYZER_OPTION(
|
||||
bool, ShouldIgnoreFlexGeneratedFiles, "ignore-flex-generated-files",
|
||||
"If enabled, any files containing the \"/* A lexical scanner generated by "
|
||||
"flex\" won't be analyzed.",
|
||||
true)
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Unsigned analyzer options.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -134,6 +134,9 @@ template <typename T> class CallDescriptionMap {
|
||||
std::initializer_list<std::pair<CallDescription, T>> &&List)
|
||||
: LinearMap(List) {}
|
||||
|
||||
template <typename InputIt>
|
||||
CallDescriptionMap(InputIt First, InputIt Last) : LinearMap(First, Last) {}
|
||||
|
||||
~CallDescriptionMap() = default;
|
||||
|
||||
// These maps are usually stored once per checker, so let's make sure
|
||||
@ -141,6 +144,9 @@ template <typename T> class CallDescriptionMap {
|
||||
CallDescriptionMap(const CallDescriptionMap &) = delete;
|
||||
CallDescriptionMap &operator=(const CallDescription &) = delete;
|
||||
|
||||
CallDescriptionMap(CallDescriptionMap &&) = default;
|
||||
CallDescriptionMap &operator=(CallDescriptionMap &&) = default;
|
||||
|
||||
LLVM_NODISCARD const T *lookup(const CallEvent &Call) const {
|
||||
// Slow path: linear lookup.
|
||||
// TODO: Implement some sort of fast path.
|
||||
|
@ -140,6 +140,30 @@ class RangeSet {
|
||||
/// Complexity: O(N)
|
||||
/// where N = size(Original)
|
||||
RangeSet add(RangeSet Original, const llvm::APSInt &Point);
|
||||
/// Create a new set which is a union of two given ranges.
|
||||
/// Possible intersections are not checked here.
|
||||
///
|
||||
/// Complexity: O(N + M)
|
||||
/// where N = size(LHS), M = size(RHS)
|
||||
RangeSet unite(RangeSet LHS, RangeSet RHS);
|
||||
/// Create a new set by uniting given range set with the given range.
|
||||
/// All intersections and adjacent ranges are handled here.
|
||||
///
|
||||
/// Complexity: O(N)
|
||||
/// where N = size(Original)
|
||||
RangeSet unite(RangeSet Original, Range Element);
|
||||
/// Create a new set by uniting given range set with the given point.
|
||||
/// All intersections and adjacent ranges are handled here.
|
||||
///
|
||||
/// Complexity: O(N)
|
||||
/// where N = size(Original)
|
||||
RangeSet unite(RangeSet Original, llvm::APSInt Point);
|
||||
/// Create a new set by uniting given range set with the given range
|
||||
/// between points. All intersections and adjacent ranges are handled here.
|
||||
///
|
||||
/// Complexity: O(N)
|
||||
/// where N = size(Original)
|
||||
RangeSet unite(RangeSet Original, llvm::APSInt From, llvm::APSInt To);
|
||||
|
||||
RangeSet getEmptySet() { return &EmptySet; }
|
||||
|
||||
@ -224,6 +248,9 @@ class RangeSet {
|
||||
ContainerType *construct(ContainerType &&From);
|
||||
|
||||
RangeSet intersect(const ContainerType &LHS, const ContainerType &RHS);
|
||||
/// NOTE: This function relies on the fact that all values in the
|
||||
/// containers are persistent (created via BasicValueFactory::getValue).
|
||||
ContainerType unite(const ContainerType &LHS, const ContainerType &RHS);
|
||||
|
||||
// Many operations include producing new APSInt values and that's why
|
||||
// we need this factory.
|
||||
|
@ -172,9 +172,9 @@ class StoreManager {
|
||||
/// dynamic_cast.
|
||||
/// - We don't know (base is a symbolic region and we don't have
|
||||
/// enough info to determine if the cast will succeed at run time).
|
||||
/// The function returns an SVal representing the derived class; it's
|
||||
/// valid only if Failed flag is set to false.
|
||||
SVal attemptDownCast(SVal Base, QualType DerivedPtrType, bool &Failed);
|
||||
/// The function returns an optional with SVal representing the derived class
|
||||
/// in case of a successful cast and `None` otherwise.
|
||||
Optional<SVal> evalBaseToDerived(SVal Base, QualType DerivedPtrType);
|
||||
|
||||
const ElementRegion *GetElementZeroRegion(const SubRegion *R, QualType T);
|
||||
|
||||
|
@ -73,7 +73,7 @@ struct TestClangConfig {
|
||||
std::string Result;
|
||||
llvm::raw_string_ostream OS(Result);
|
||||
OS << "{ Language=" << Language << ", Target=" << Target << " }";
|
||||
return OS.str();
|
||||
return Result;
|
||||
}
|
||||
|
||||
friend std::ostream &operator<<(std::ostream &OS,
|
||||
|
@ -26,57 +26,83 @@ namespace dependencies {
|
||||
/// the dependency scanning filesystem.
|
||||
///
|
||||
/// It represents one of the following:
|
||||
/// - an opened source file with minimized contents and a stat value.
|
||||
/// - an opened source file with original contents and a stat value.
|
||||
/// - a directory entry with its stat value.
|
||||
/// - an error value to represent a file system error.
|
||||
/// - a placeholder with an invalid stat indicating a not yet initialized entry.
|
||||
/// - opened file with original contents and a stat value,
|
||||
/// - opened file with original contents, minimized contents and a stat value,
|
||||
/// - directory entry with its stat value,
|
||||
/// - filesystem error,
|
||||
/// - uninitialized entry with unknown status.
|
||||
class CachedFileSystemEntry {
|
||||
public:
|
||||
/// Default constructor creates an entry with an invalid stat.
|
||||
CachedFileSystemEntry() : MaybeStat(llvm::vfs::Status()) {}
|
||||
/// Creates an uninitialized entry.
|
||||
CachedFileSystemEntry()
|
||||
: MaybeStat(llvm::vfs::Status()), MinimizedContentsAccess(nullptr) {}
|
||||
|
||||
CachedFileSystemEntry(std::error_code Error) : MaybeStat(std::move(Error)) {}
|
||||
/// Initialize the cached file system entry.
|
||||
void init(llvm::ErrorOr<llvm::vfs::Status> &&MaybeStatus, StringRef Filename,
|
||||
llvm::vfs::FileSystem &FS);
|
||||
|
||||
/// Create an entry that represents an opened source file with minimized or
|
||||
/// original contents.
|
||||
/// Initialize the entry as file with minimized or original contents.
|
||||
///
|
||||
/// The filesystem opens the file even for `stat` calls open to avoid the
|
||||
/// issues with stat + open of minimized files that might lead to a
|
||||
/// mismatching size of the file. If file is not minimized, the full file is
|
||||
/// read and copied into memory to ensure that it's not memory mapped to avoid
|
||||
/// running out of file descriptors.
|
||||
static CachedFileSystemEntry createFileEntry(StringRef Filename,
|
||||
llvm::vfs::FileSystem &FS,
|
||||
bool Minimize = true);
|
||||
/// mismatching size of the file.
|
||||
llvm::ErrorOr<llvm::vfs::Status> initFile(StringRef Filename,
|
||||
llvm::vfs::FileSystem &FS);
|
||||
|
||||
/// Create an entry that represents a directory on the filesystem.
|
||||
static CachedFileSystemEntry createDirectoryEntry(llvm::vfs::Status &&Stat);
|
||||
/// Minimize contents of the file.
|
||||
void minimizeFile();
|
||||
|
||||
/// \returns True if the entry is valid.
|
||||
bool isValid() const { return !MaybeStat || MaybeStat->isStatusKnown(); }
|
||||
/// \returns True if the entry is initialized.
|
||||
bool isInitialized() const {
|
||||
return !MaybeStat || MaybeStat->isStatusKnown();
|
||||
}
|
||||
|
||||
/// \returns True if the current entry points to a directory.
|
||||
bool isDirectory() const { return MaybeStat && MaybeStat->isDirectory(); }
|
||||
|
||||
/// \returns The error or the file's contents.
|
||||
llvm::ErrorOr<StringRef> getContents() const {
|
||||
/// \returns The error or the file's original contents.
|
||||
llvm::ErrorOr<StringRef> getOriginalContents() const {
|
||||
if (!MaybeStat)
|
||||
return MaybeStat.getError();
|
||||
assert(!MaybeStat->isDirectory() && "not a file");
|
||||
assert(isValid() && "not initialized");
|
||||
return Contents.str();
|
||||
assert(isInitialized() && "not initialized");
|
||||
assert(OriginalContents && "not read");
|
||||
return OriginalContents->getBuffer();
|
||||
}
|
||||
|
||||
/// \returns The error or the file's minimized contents.
|
||||
llvm::ErrorOr<StringRef> getMinimizedContents() const {
|
||||
if (!MaybeStat)
|
||||
return MaybeStat.getError();
|
||||
assert(!MaybeStat->isDirectory() && "not a file");
|
||||
assert(isInitialized() && "not initialized");
|
||||
llvm::MemoryBuffer *Buffer = MinimizedContentsAccess.load();
|
||||
assert(Buffer && "not minimized");
|
||||
return Buffer->getBuffer();
|
||||
}
|
||||
|
||||
/// \returns True if this entry represents a file that can be read.
|
||||
bool isReadable() const { return MaybeStat && !MaybeStat->isDirectory(); }
|
||||
|
||||
/// \returns True if this cached entry needs to be updated.
|
||||
bool needsUpdate(bool ShouldBeMinimized) const {
|
||||
return isReadable() && needsMinimization(ShouldBeMinimized);
|
||||
}
|
||||
|
||||
/// \returns True if the contents of this entry need to be minimized.
|
||||
bool needsMinimization(bool ShouldBeMinimized) const {
|
||||
return ShouldBeMinimized && !MinimizedContentsAccess.load();
|
||||
}
|
||||
|
||||
/// \returns The error or the status of the entry.
|
||||
llvm::ErrorOr<llvm::vfs::Status> getStatus() const {
|
||||
assert(isValid() && "not initialized");
|
||||
assert(isInitialized() && "not initialized");
|
||||
return MaybeStat;
|
||||
}
|
||||
|
||||
/// \returns the name of the file.
|
||||
StringRef getName() const {
|
||||
assert(isValid() && "not initialized");
|
||||
assert(isInitialized() && "not initialized");
|
||||
return MaybeStat->getName();
|
||||
}
|
||||
|
||||
@ -86,19 +112,16 @@ class CachedFileSystemEntry {
|
||||
return PPSkippedRangeMapping;
|
||||
}
|
||||
|
||||
CachedFileSystemEntry(CachedFileSystemEntry &&) = default;
|
||||
CachedFileSystemEntry &operator=(CachedFileSystemEntry &&) = default;
|
||||
|
||||
CachedFileSystemEntry(const CachedFileSystemEntry &) = delete;
|
||||
CachedFileSystemEntry &operator=(const CachedFileSystemEntry &) = delete;
|
||||
|
||||
private:
|
||||
llvm::ErrorOr<llvm::vfs::Status> MaybeStat;
|
||||
// Store the contents in a small string to allow a
|
||||
// move from the small string for the minimized contents.
|
||||
// Note: small size of 1 allows us to store an empty string with an implicit
|
||||
// null terminator without any allocations.
|
||||
llvm::SmallString<1> Contents;
|
||||
std::unique_ptr<llvm::MemoryBuffer> OriginalContents;
|
||||
|
||||
/// Owning storage for the minimized file contents.
|
||||
std::unique_ptr<llvm::MemoryBuffer> MinimizedContentsStorage;
|
||||
/// Atomic view of the minimized file contents.
|
||||
/// This prevents data races when multiple threads call `needsMinimization`.
|
||||
std::atomic<llvm::MemoryBuffer *> MinimizedContentsAccess;
|
||||
|
||||
PreprocessorSkippedRangeMapping PPSkippedRangeMapping;
|
||||
};
|
||||
|
||||
@ -115,61 +138,70 @@ class DependencyScanningFilesystemSharedCache {
|
||||
CachedFileSystemEntry Value;
|
||||
};
|
||||
|
||||
DependencyScanningFilesystemSharedCache();
|
||||
|
||||
/// Returns a cache entry for the corresponding key.
|
||||
///
|
||||
/// A new cache entry is created if the key is not in the cache. This is a
|
||||
/// thread safe call.
|
||||
SharedFileSystemEntry &get(StringRef Key, bool Minimized);
|
||||
|
||||
private:
|
||||
class SingleCache {
|
||||
public:
|
||||
SingleCache();
|
||||
|
||||
SharedFileSystemEntry &get(StringRef Key);
|
||||
|
||||
private:
|
||||
private:
|
||||
struct CacheShard {
|
||||
std::mutex CacheLock;
|
||||
llvm::StringMap<SharedFileSystemEntry, llvm::BumpPtrAllocator> Cache;
|
||||
};
|
||||
std::unique_ptr<CacheShard[]> CacheShards;
|
||||
unsigned NumShards;
|
||||
};
|
||||
|
||||
SingleCache CacheMinimized;
|
||||
SingleCache CacheOriginal;
|
||||
};
|
||||
|
||||
/// This class is a local cache, that caches the 'stat' and 'open' calls to the
|
||||
/// underlying real file system. It distinguishes between minimized and original
|
||||
/// files.
|
||||
class DependencyScanningFilesystemLocalCache {
|
||||
private:
|
||||
using SingleCache =
|
||||
llvm::StringMap<const CachedFileSystemEntry *, llvm::BumpPtrAllocator>;
|
||||
|
||||
SingleCache CacheMinimized;
|
||||
SingleCache CacheOriginal;
|
||||
|
||||
SingleCache &selectCache(bool Minimized) {
|
||||
return Minimized ? CacheMinimized : CacheOriginal;
|
||||
}
|
||||
llvm::StringMap<const CachedFileSystemEntry *, llvm::BumpPtrAllocator> Cache;
|
||||
|
||||
public:
|
||||
void setCachedEntry(StringRef Filename, bool Minimized,
|
||||
const CachedFileSystemEntry *Entry) {
|
||||
SingleCache &Cache = selectCache(Minimized);
|
||||
bool IsInserted = Cache.try_emplace(Filename, Entry).second;
|
||||
(void)IsInserted;
|
||||
assert(IsInserted && "local cache is updated more than once");
|
||||
const CachedFileSystemEntry *getCachedEntry(StringRef Filename) {
|
||||
return Cache[Filename];
|
||||
}
|
||||
};
|
||||
|
||||
/// Reference to a CachedFileSystemEntry.
|
||||
/// If the underlying entry is an opened file, this wrapper returns the correct
|
||||
/// contents (original or minimized) and ensures consistency with file size
|
||||
/// reported by status.
|
||||
class EntryRef {
|
||||
/// For entry that is an opened file, this bit signifies whether its contents
|
||||
/// are minimized.
|
||||
bool Minimized;
|
||||
|
||||
/// The underlying cached entry.
|
||||
const CachedFileSystemEntry &Entry;
|
||||
|
||||
public:
|
||||
EntryRef(bool Minimized, const CachedFileSystemEntry &Entry)
|
||||
: Minimized(Minimized), Entry(Entry) {}
|
||||
|
||||
llvm::ErrorOr<llvm::vfs::Status> getStatus() const {
|
||||
auto MaybeStat = Entry.getStatus();
|
||||
if (!MaybeStat || MaybeStat->isDirectory())
|
||||
return MaybeStat;
|
||||
return llvm::vfs::Status::copyWithNewSize(*MaybeStat,
|
||||
getContents()->size());
|
||||
}
|
||||
|
||||
const CachedFileSystemEntry *getCachedEntry(StringRef Filename,
|
||||
bool Minimized) {
|
||||
SingleCache &Cache = selectCache(Minimized);
|
||||
auto It = Cache.find(Filename);
|
||||
return It == Cache.end() ? nullptr : It->getValue();
|
||||
bool isDirectory() const { return Entry.isDirectory(); }
|
||||
|
||||
StringRef getName() const { return Entry.getName(); }
|
||||
|
||||
llvm::ErrorOr<StringRef> getContents() const {
|
||||
return Minimized ? Entry.getMinimizedContents()
|
||||
: Entry.getOriginalContents();
|
||||
}
|
||||
|
||||
const PreprocessorSkippedRangeMapping *getPPSkippedRangeMapping() const {
|
||||
return Minimized ? &Entry.getPPSkippedRangeMapping() : nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
@ -204,19 +236,13 @@ class DependencyScanningWorkerFilesystem : public llvm::vfs::ProxyFileSystem {
|
||||
/// Check whether the file should be minimized.
|
||||
bool shouldMinimize(StringRef Filename);
|
||||
|
||||
llvm::ErrorOr<const CachedFileSystemEntry *>
|
||||
getOrCreateFileSystemEntry(const StringRef Filename);
|
||||
|
||||
/// Create a cached file system entry based on the initial status result.
|
||||
CachedFileSystemEntry
|
||||
createFileSystemEntry(llvm::ErrorOr<llvm::vfs::Status> &&MaybeStatus,
|
||||
StringRef Filename, bool ShouldMinimize);
|
||||
llvm::ErrorOr<EntryRef> getOrCreateFileSystemEntry(StringRef Filename);
|
||||
|
||||
/// The global cache shared between worker threads.
|
||||
DependencyScanningFilesystemSharedCache &SharedCache;
|
||||
/// The local cache is used by the worker thread to cache file system queries
|
||||
/// locally instead of querying the global cache every time.
|
||||
DependencyScanningFilesystemLocalCache Cache;
|
||||
DependencyScanningFilesystemLocalCache LocalCache;
|
||||
/// The optional mapping structure which records information about the
|
||||
/// excluded conditional directive skip mappings that are used by the
|
||||
/// currently active preprocessor.
|
||||
|
@ -106,7 +106,7 @@ struct IncludeStyle {
|
||||
/// Priority: 2
|
||||
/// SortPriority: 2
|
||||
/// CaseSensitive: true
|
||||
/// - Regex: '^(<|"(gtest|gmock|isl|json)/)'
|
||||
/// - Regex: '^((<|")(gtest|gmock|isl|json)/)'
|
||||
/// Priority: 3
|
||||
/// - Regex: '<[[:alnum:].]+>'
|
||||
/// Priority: 4
|
||||
|
@ -34,6 +34,8 @@ module Clang_Basic {
|
||||
textual header "Basic/AArch64SVEACLETypes.def"
|
||||
textual header "Basic/BuiltinsAArch64.def"
|
||||
textual header "Basic/BuiltinsAMDGPU.def"
|
||||
textual header "Basic/BuiltinsAArch64NeonSVEBridge.def"
|
||||
textual header "Basic/BuiltinsAArch64NeonSVEBridge_cg.def"
|
||||
textual header "Basic/BuiltinsARM.def"
|
||||
textual header "Basic/BuiltinsBPF.def"
|
||||
textual header "Basic/Builtins.def"
|
||||
|
@ -162,9 +162,7 @@ static bool HasARCRuntime(CompilerInvocation &origCI) {
|
||||
return triple.getOSMajorVersion() >= 11;
|
||||
|
||||
if (triple.getOS() == llvm::Triple::MacOSX) {
|
||||
unsigned Major, Minor, Micro;
|
||||
triple.getOSVersion(Major, Minor, Micro);
|
||||
return Major > 10 || (Major == 10 && Minor >= 7);
|
||||
return triple.getOSVersion() >= VersionTuple(10, 7);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -2286,8 +2286,8 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
|
||||
Align = toBits(Layout.getAlignment());
|
||||
break;
|
||||
}
|
||||
case Type::ExtInt: {
|
||||
const auto *EIT = cast<ExtIntType>(T);
|
||||
case Type::BitInt: {
|
||||
const auto *EIT = cast<BitIntType>(T);
|
||||
Align =
|
||||
std::min(static_cast<unsigned>(std::max(
|
||||
getCharWidth(), llvm::PowerOf2Ceil(EIT->getNumBits()))),
|
||||
@ -2349,6 +2349,9 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
|
||||
case Type::ObjCTypeParam:
|
||||
return getTypeInfo(cast<ObjCTypeParamType>(T)->desugar().getTypePtr());
|
||||
|
||||
case Type::Using:
|
||||
return getTypeInfo(cast<UsingType>(T)->desugar().getTypePtr());
|
||||
|
||||
case Type::Typedef: {
|
||||
const TypedefNameDecl *Typedef = cast<TypedefType>(T)->getDecl();
|
||||
TypeInfo Info = getTypeInfo(Typedef->getUnderlyingType().getTypePtr());
|
||||
@ -3569,8 +3572,8 @@ QualType ASTContext::getVariableArrayDecayedType(QualType type) const {
|
||||
case Type::Auto:
|
||||
case Type::DeducedTemplateSpecialization:
|
||||
case Type::PackExpansion:
|
||||
case Type::ExtInt:
|
||||
case Type::DependentExtInt:
|
||||
case Type::BitInt:
|
||||
case Type::DependentBitInt:
|
||||
llvm_unreachable("type should never be variably-modified");
|
||||
|
||||
// These types can be variably-modified but should never need to
|
||||
@ -4482,34 +4485,34 @@ QualType ASTContext::getWritePipeType(QualType T) const {
|
||||
return getPipeType(T, false);
|
||||
}
|
||||
|
||||
QualType ASTContext::getExtIntType(bool IsUnsigned, unsigned NumBits) const {
|
||||
QualType ASTContext::getBitIntType(bool IsUnsigned, unsigned NumBits) const {
|
||||
llvm::FoldingSetNodeID ID;
|
||||
ExtIntType::Profile(ID, IsUnsigned, NumBits);
|
||||
BitIntType::Profile(ID, IsUnsigned, NumBits);
|
||||
|
||||
void *InsertPos = nullptr;
|
||||
if (ExtIntType *EIT = ExtIntTypes.FindNodeOrInsertPos(ID, InsertPos))
|
||||
if (BitIntType *EIT = BitIntTypes.FindNodeOrInsertPos(ID, InsertPos))
|
||||
return QualType(EIT, 0);
|
||||
|
||||
auto *New = new (*this, TypeAlignment) ExtIntType(IsUnsigned, NumBits);
|
||||
ExtIntTypes.InsertNode(New, InsertPos);
|
||||
auto *New = new (*this, TypeAlignment) BitIntType(IsUnsigned, NumBits);
|
||||
BitIntTypes.InsertNode(New, InsertPos);
|
||||
Types.push_back(New);
|
||||
return QualType(New, 0);
|
||||
}
|
||||
|
||||
QualType ASTContext::getDependentExtIntType(bool IsUnsigned,
|
||||
QualType ASTContext::getDependentBitIntType(bool IsUnsigned,
|
||||
Expr *NumBitsExpr) const {
|
||||
assert(NumBitsExpr->isInstantiationDependent() && "Only good for dependent");
|
||||
llvm::FoldingSetNodeID ID;
|
||||
DependentExtIntType::Profile(ID, *this, IsUnsigned, NumBitsExpr);
|
||||
DependentBitIntType::Profile(ID, *this, IsUnsigned, NumBitsExpr);
|
||||
|
||||
void *InsertPos = nullptr;
|
||||
if (DependentExtIntType *Existing =
|
||||
DependentExtIntTypes.FindNodeOrInsertPos(ID, InsertPos))
|
||||
if (DependentBitIntType *Existing =
|
||||
DependentBitIntTypes.FindNodeOrInsertPos(ID, InsertPos))
|
||||
return QualType(Existing, 0);
|
||||
|
||||
auto *New = new (*this, TypeAlignment)
|
||||
DependentExtIntType(*this, IsUnsigned, NumBitsExpr);
|
||||
DependentExtIntTypes.InsertNode(New, InsertPos);
|
||||
DependentBitIntType(*this, IsUnsigned, NumBitsExpr);
|
||||
DependentBitIntTypes.InsertNode(New, InsertPos);
|
||||
|
||||
Types.push_back(New);
|
||||
return QualType(New, 0);
|
||||
@ -4568,9 +4571,7 @@ QualType ASTContext::getTypeDeclTypeSlow(const TypeDecl *Decl) const {
|
||||
assert(Enum->isFirstDecl() && "enum has previous declaration");
|
||||
return getEnumType(Enum);
|
||||
} else if (const auto *Using = dyn_cast<UnresolvedUsingTypenameDecl>(Decl)) {
|
||||
Type *newType = new (*this, TypeAlignment) UnresolvedUsingType(Using);
|
||||
Decl->TypeForDecl = newType;
|
||||
Types.push_back(newType);
|
||||
return getUnresolvedUsingType(Using);
|
||||
} else
|
||||
llvm_unreachable("TypeDecl without a type?");
|
||||
|
||||
@ -4593,6 +4594,27 @@ QualType ASTContext::getTypedefType(const TypedefNameDecl *Decl,
|
||||
return QualType(newType, 0);
|
||||
}
|
||||
|
||||
QualType ASTContext::getUsingType(const UsingShadowDecl *Found,
|
||||
QualType Underlying) const {
|
||||
llvm::FoldingSetNodeID ID;
|
||||
UsingType::Profile(ID, Found);
|
||||
|
||||
void *InsertPos = nullptr;
|
||||
UsingType *T = UsingTypes.FindNodeOrInsertPos(ID, InsertPos);
|
||||
if (T)
|
||||
return QualType(T, 0);
|
||||
|
||||
assert(!Underlying.hasLocalQualifiers());
|
||||
assert(Underlying == getTypeDeclType(cast<TypeDecl>(Found->getTargetDecl())));
|
||||
QualType Canon = Underlying.getCanonicalType();
|
||||
|
||||
UsingType *NewType =
|
||||
new (*this, TypeAlignment) UsingType(Found, Underlying, Canon);
|
||||
Types.push_back(NewType);
|
||||
UsingTypes.InsertNode(NewType, InsertPos);
|
||||
return QualType(NewType, 0);
|
||||
}
|
||||
|
||||
QualType ASTContext::getRecordType(const RecordDecl *Decl) const {
|
||||
if (Decl->TypeForDecl) return QualType(Decl->TypeForDecl, 0);
|
||||
|
||||
@ -4619,6 +4641,22 @@ QualType ASTContext::getEnumType(const EnumDecl *Decl) const {
|
||||
return QualType(newType, 0);
|
||||
}
|
||||
|
||||
QualType ASTContext::getUnresolvedUsingType(
|
||||
const UnresolvedUsingTypenameDecl *Decl) const {
|
||||
if (Decl->TypeForDecl)
|
||||
return QualType(Decl->TypeForDecl, 0);
|
||||
|
||||
if (const UnresolvedUsingTypenameDecl *CanonicalDecl =
|
||||
Decl->getCanonicalDecl())
|
||||
if (CanonicalDecl->TypeForDecl)
|
||||
return QualType(Decl->TypeForDecl = CanonicalDecl->TypeForDecl, 0);
|
||||
|
||||
Type *newType = new (*this, TypeAlignment) UnresolvedUsingType(Decl);
|
||||
Decl->TypeForDecl = newType;
|
||||
Types.push_back(newType);
|
||||
return QualType(newType, 0);
|
||||
}
|
||||
|
||||
QualType ASTContext::getAttributedType(attr::Kind attrKind,
|
||||
QualType modifiedType,
|
||||
QualType equivalentType) {
|
||||
@ -6444,7 +6482,7 @@ unsigned ASTContext::getIntegerRank(const Type *T) const {
|
||||
|
||||
// Results in this 'losing' to any type of the same size, but winning if
|
||||
// larger.
|
||||
if (const auto *EIT = dyn_cast<ExtIntType>(T))
|
||||
if (const auto *EIT = dyn_cast<BitIntType>(T))
|
||||
return 0 + (EIT->getNumBits() << 3);
|
||||
|
||||
switch (cast<BuiltinType>(T)->getKind()) {
|
||||
@ -7885,7 +7923,7 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string &S,
|
||||
return;
|
||||
|
||||
case Type::Pipe:
|
||||
case Type::ExtInt:
|
||||
case Type::BitInt:
|
||||
#define ABSTRACT_TYPE(KIND, BASE)
|
||||
#define TYPE(KIND, BASE)
|
||||
#define DEPENDENT_TYPE(KIND, BASE) \
|
||||
@ -9232,7 +9270,7 @@ void getIntersectionOfProtocols(ASTContext &Context,
|
||||
// Remove any implied protocols from the list of inherited protocols.
|
||||
if (!ImpliedProtocols.empty()) {
|
||||
llvm::erase_if(IntersectionSet, [&](ObjCProtocolDecl *proto) -> bool {
|
||||
return ImpliedProtocols.count(proto) > 0;
|
||||
return ImpliedProtocols.contains(proto);
|
||||
});
|
||||
}
|
||||
|
||||
@ -10099,12 +10137,12 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS,
|
||||
assert(LHS != RHS &&
|
||||
"Equivalent pipe types should have already been handled!");
|
||||
return {};
|
||||
case Type::ExtInt: {
|
||||
// Merge two ext-int types, while trying to preserve typedef info.
|
||||
bool LHSUnsigned = LHS->castAs<ExtIntType>()->isUnsigned();
|
||||
bool RHSUnsigned = RHS->castAs<ExtIntType>()->isUnsigned();
|
||||
unsigned LHSBits = LHS->castAs<ExtIntType>()->getNumBits();
|
||||
unsigned RHSBits = RHS->castAs<ExtIntType>()->getNumBits();
|
||||
case Type::BitInt: {
|
||||
// Merge two bit-precise int types, while trying to preserve typedef info.
|
||||
bool LHSUnsigned = LHS->castAs<BitIntType>()->isUnsigned();
|
||||
bool RHSUnsigned = RHS->castAs<BitIntType>()->isUnsigned();
|
||||
unsigned LHSBits = LHS->castAs<BitIntType>()->getNumBits();
|
||||
unsigned RHSBits = RHS->castAs<BitIntType>()->getNumBits();
|
||||
|
||||
// Like unsigned/int, shouldn't have a type if they don't match.
|
||||
if (LHSUnsigned != RHSUnsigned)
|
||||
@ -10254,7 +10292,7 @@ unsigned ASTContext::getIntWidth(QualType T) const {
|
||||
T = ET->getDecl()->getIntegerType();
|
||||
if (T->isBooleanType())
|
||||
return 1;
|
||||
if(const auto *EIT = T->getAs<ExtIntType>())
|
||||
if (const auto *EIT = T->getAs<BitIntType>())
|
||||
return EIT->getNumBits();
|
||||
// For builtin types, just use the standard type sizing method
|
||||
return (unsigned)getTypeSize(T);
|
||||
@ -10269,9 +10307,9 @@ QualType ASTContext::getCorrespondingUnsignedType(QualType T) const {
|
||||
return getVectorType(getCorrespondingUnsignedType(VTy->getElementType()),
|
||||
VTy->getNumElements(), VTy->getVectorKind());
|
||||
|
||||
// For _ExtInt, return an unsigned _ExtInt with same width.
|
||||
if (const auto *EITy = T->getAs<ExtIntType>())
|
||||
return getExtIntType(/*IsUnsigned=*/true, EITy->getNumBits());
|
||||
// For _BitInt, return an unsigned _BitInt with same width.
|
||||
if (const auto *EITy = T->getAs<BitIntType>())
|
||||
return getBitIntType(/*IsUnsigned=*/true, EITy->getNumBits());
|
||||
|
||||
// For enums, get the underlying integer type of the enum, and let the general
|
||||
// integer type signchanging code handle it.
|
||||
@ -10337,9 +10375,9 @@ QualType ASTContext::getCorrespondingSignedType(QualType T) const {
|
||||
return getVectorType(getCorrespondingSignedType(VTy->getElementType()),
|
||||
VTy->getNumElements(), VTy->getVectorKind());
|
||||
|
||||
// For _ExtInt, return a signed _ExtInt with same width.
|
||||
if (const auto *EITy = T->getAs<ExtIntType>())
|
||||
return getExtIntType(/*IsUnsigned=*/false, EITy->getNumBits());
|
||||
// For _BitInt, return a signed _BitInt with same width.
|
||||
if (const auto *EITy = T->getAs<BitIntType>())
|
||||
return getBitIntType(/*IsUnsigned=*/false, EITy->getNumBits());
|
||||
|
||||
// For enums, get the underlying integer type of the enum, and let the general
|
||||
// integer type signchanging code handle it.
|
||||
|
@ -26,7 +26,8 @@ using namespace clang;
|
||||
|
||||
// Returns a desugared version of the QualType, and marks ShouldAKA as true
|
||||
// whenever we remove significant sugar from the type.
|
||||
static QualType Desugar(ASTContext &Context, QualType QT, bool &ShouldAKA) {
|
||||
QualType clang::desugarForDiagnostic(ASTContext &Context, QualType QT,
|
||||
bool &ShouldAKA) {
|
||||
QualifierCollector QC;
|
||||
|
||||
while (true) {
|
||||
@ -37,6 +38,11 @@ static QualType Desugar(ASTContext &Context, QualType QT, bool &ShouldAKA) {
|
||||
QT = ET->desugar();
|
||||
continue;
|
||||
}
|
||||
// ... or a using type ...
|
||||
if (const UsingType *UT = dyn_cast<UsingType>(Ty)) {
|
||||
QT = UT->desugar();
|
||||
continue;
|
||||
}
|
||||
// ... or a paren type ...
|
||||
if (const ParenType *PT = dyn_cast<ParenType>(Ty)) {
|
||||
QT = PT->desugar();
|
||||
@ -76,7 +82,7 @@ static QualType Desugar(ASTContext &Context, QualType QT, bool &ShouldAKA) {
|
||||
if (const FunctionType *FT = dyn_cast<FunctionType>(Ty)) {
|
||||
bool DesugarReturn = false;
|
||||
QualType SugarRT = FT->getReturnType();
|
||||
QualType RT = Desugar(Context, SugarRT, DesugarReturn);
|
||||
QualType RT = desugarForDiagnostic(Context, SugarRT, DesugarReturn);
|
||||
if (auto nullability = AttributedType::stripOuterNullability(SugarRT)) {
|
||||
RT = Context.getAttributedType(
|
||||
AttributedType::getNullabilityAttrKind(*nullability), RT, RT);
|
||||
@ -87,7 +93,7 @@ static QualType Desugar(ASTContext &Context, QualType QT, bool &ShouldAKA) {
|
||||
const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(FT);
|
||||
if (FPT) {
|
||||
for (QualType SugarPT : FPT->param_types()) {
|
||||
QualType PT = Desugar(Context, SugarPT, DesugarArgument);
|
||||
QualType PT = desugarForDiagnostic(Context, SugarPT, DesugarArgument);
|
||||
if (auto nullability =
|
||||
AttributedType::stripOuterNullability(SugarPT)) {
|
||||
PT = Context.getAttributedType(
|
||||
@ -115,7 +121,8 @@ static QualType Desugar(ASTContext &Context, QualType QT, bool &ShouldAKA) {
|
||||
for (unsigned I = 0, N = TST->getNumArgs(); I != N; ++I) {
|
||||
const TemplateArgument &Arg = TST->getArg(I);
|
||||
if (Arg.getKind() == TemplateArgument::Type)
|
||||
Args.push_back(Desugar(Context, Arg.getAsType(), DesugarArgument));
|
||||
Args.push_back(desugarForDiagnostic(Context, Arg.getAsType(),
|
||||
DesugarArgument));
|
||||
else
|
||||
Args.push_back(Arg);
|
||||
}
|
||||
@ -129,6 +136,29 @@ static QualType Desugar(ASTContext &Context, QualType QT, bool &ShouldAKA) {
|
||||
}
|
||||
}
|
||||
|
||||
if (const auto *AT = dyn_cast<ArrayType>(Ty)) {
|
||||
QualType ElementTy =
|
||||
desugarForDiagnostic(Context, AT->getElementType(), ShouldAKA);
|
||||
if (const auto *CAT = dyn_cast<ConstantArrayType>(AT))
|
||||
QT = Context.getConstantArrayType(
|
||||
ElementTy, CAT->getSize(), CAT->getSizeExpr(),
|
||||
CAT->getSizeModifier(), CAT->getIndexTypeCVRQualifiers());
|
||||
else if (const auto *VAT = dyn_cast<VariableArrayType>(AT))
|
||||
QT = Context.getVariableArrayType(
|
||||
ElementTy, VAT->getSizeExpr(), VAT->getSizeModifier(),
|
||||
VAT->getIndexTypeCVRQualifiers(), VAT->getBracketsRange());
|
||||
else if (const auto *DSAT = dyn_cast<DependentSizedArrayType>(AT))
|
||||
QT = Context.getDependentSizedArrayType(
|
||||
ElementTy, DSAT->getSizeExpr(), DSAT->getSizeModifier(),
|
||||
DSAT->getIndexTypeCVRQualifiers(), DSAT->getBracketsRange());
|
||||
else if (const auto *IAT = dyn_cast<IncompleteArrayType>(AT))
|
||||
QT = Context.getIncompleteArrayType(ElementTy, IAT->getSizeModifier(),
|
||||
IAT->getIndexTypeCVRQualifiers());
|
||||
else
|
||||
llvm_unreachable("Unhandled array type");
|
||||
break;
|
||||
}
|
||||
|
||||
// Don't desugar magic Objective-C types.
|
||||
if (QualType(Ty,0) == Context.getObjCIdType() ||
|
||||
QualType(Ty,0) == Context.getObjCClassType() ||
|
||||
@ -181,23 +211,24 @@ break; \
|
||||
// If we have a pointer-like type, desugar the pointee as well.
|
||||
// FIXME: Handle other pointer-like types.
|
||||
if (const PointerType *Ty = QT->getAs<PointerType>()) {
|
||||
QT = Context.getPointerType(Desugar(Context, Ty->getPointeeType(),
|
||||
ShouldAKA));
|
||||
QT = Context.getPointerType(
|
||||
desugarForDiagnostic(Context, Ty->getPointeeType(), ShouldAKA));
|
||||
} else if (const auto *Ty = QT->getAs<ObjCObjectPointerType>()) {
|
||||
QT = Context.getObjCObjectPointerType(Desugar(Context, Ty->getPointeeType(),
|
||||
ShouldAKA));
|
||||
QT = Context.getObjCObjectPointerType(
|
||||
desugarForDiagnostic(Context, Ty->getPointeeType(), ShouldAKA));
|
||||
} else if (const LValueReferenceType *Ty = QT->getAs<LValueReferenceType>()) {
|
||||
QT = Context.getLValueReferenceType(Desugar(Context, Ty->getPointeeType(),
|
||||
ShouldAKA));
|
||||
QT = Context.getLValueReferenceType(
|
||||
desugarForDiagnostic(Context, Ty->getPointeeType(), ShouldAKA));
|
||||
} else if (const RValueReferenceType *Ty = QT->getAs<RValueReferenceType>()) {
|
||||
QT = Context.getRValueReferenceType(Desugar(Context, Ty->getPointeeType(),
|
||||
ShouldAKA));
|
||||
QT = Context.getRValueReferenceType(
|
||||
desugarForDiagnostic(Context, Ty->getPointeeType(), ShouldAKA));
|
||||
} else if (const auto *Ty = QT->getAs<ObjCObjectType>()) {
|
||||
if (Ty->getBaseType().getTypePtr() != Ty && !ShouldAKA) {
|
||||
QualType BaseType = Desugar(Context, Ty->getBaseType(), ShouldAKA);
|
||||
QT = Context.getObjCObjectType(BaseType, Ty->getTypeArgsAsWritten(),
|
||||
llvm::makeArrayRef(Ty->qual_begin(),
|
||||
Ty->getNumProtocols()),
|
||||
QualType BaseType =
|
||||
desugarForDiagnostic(Context, Ty->getBaseType(), ShouldAKA);
|
||||
QT = Context.getObjCObjectType(
|
||||
BaseType, Ty->getTypeArgsAsWritten(),
|
||||
llvm::makeArrayRef(Ty->qual_begin(), Ty->getNumProtocols()),
|
||||
Ty->isKindOfTypeAsWritten());
|
||||
}
|
||||
}
|
||||
@ -251,7 +282,8 @@ ConvertTypeToDiagnosticString(ASTContext &Context, QualType Ty,
|
||||
continue; // Same canonical types
|
||||
std::string CompareS = CompareTy.getAsString(Context.getPrintingPolicy());
|
||||
bool ShouldAKA = false;
|
||||
QualType CompareDesugar = Desugar(Context, CompareTy, ShouldAKA);
|
||||
QualType CompareDesugar =
|
||||
desugarForDiagnostic(Context, CompareTy, ShouldAKA);
|
||||
std::string CompareDesugarStr =
|
||||
CompareDesugar.getAsString(Context.getPrintingPolicy());
|
||||
if (CompareS != S && CompareDesugarStr != S)
|
||||
@ -286,7 +318,7 @@ ConvertTypeToDiagnosticString(ASTContext &Context, QualType Ty,
|
||||
// sugar gives us something "significantly different".
|
||||
if (!Repeated) {
|
||||
bool ShouldAKA = false;
|
||||
QualType DesugaredTy = Desugar(Context, Ty, ShouldAKA);
|
||||
QualType DesugaredTy = desugarForDiagnostic(Context, Ty, ShouldAKA);
|
||||
if (ShouldAKA || ForceAKA) {
|
||||
if (DesugaredTy == Ty) {
|
||||
DesugaredTy = Ty.getCanonicalType();
|
||||
@ -308,7 +340,7 @@ ConvertTypeToDiagnosticString(ASTContext &Context, QualType Ty,
|
||||
OS << "'" << S << "' (vector of " << VTy->getNumElements() << " '"
|
||||
<< VTy->getElementType().getAsString(Context.getPrintingPolicy())
|
||||
<< "' " << Values << ")";
|
||||
return OS.str();
|
||||
return DecoratedString;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -354,6 +354,7 @@ namespace clang {
|
||||
ExpectedType VisitTypeOfExprType(const TypeOfExprType *T);
|
||||
// FIXME: DependentTypeOfExprType
|
||||
ExpectedType VisitTypeOfType(const TypeOfType *T);
|
||||
ExpectedType VisitUsingType(const UsingType *T);
|
||||
ExpectedType VisitDecltypeType(const DecltypeType *T);
|
||||
ExpectedType VisitUnaryTransformType(const UnaryTransformType *T);
|
||||
ExpectedType VisitAutoType(const AutoType *T);
|
||||
@ -1340,6 +1341,17 @@ ExpectedType ASTNodeImporter::VisitTypeOfType(const TypeOfType *T) {
|
||||
return Importer.getToContext().getTypeOfType(*ToUnderlyingTypeOrErr);
|
||||
}
|
||||
|
||||
ExpectedType ASTNodeImporter::VisitUsingType(const UsingType *T) {
|
||||
Expected<UsingShadowDecl *> FoundOrErr = import(T->getFoundDecl());
|
||||
if (!FoundOrErr)
|
||||
return FoundOrErr.takeError();
|
||||
Expected<QualType> UnderlyingOrErr = import(T->getUnderlyingType());
|
||||
if (!UnderlyingOrErr)
|
||||
return UnderlyingOrErr.takeError();
|
||||
|
||||
return Importer.getToContext().getUsingType(*FoundOrErr, *UnderlyingOrErr);
|
||||
}
|
||||
|
||||
ExpectedType ASTNodeImporter::VisitDecltypeType(const DecltypeType *T) {
|
||||
// FIXME: Make sure that the "to" context supports C++0x!
|
||||
ExpectedExpr ToExprOrErr = import(T->getUnderlyingExpr());
|
||||
@ -6066,20 +6078,24 @@ ASTNodeImporter::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
|
||||
if (Error Err = importInto(TemplatedFD, D->getTemplatedDecl()))
|
||||
return std::move(Err);
|
||||
|
||||
// Template parameters of the ClassTemplateDecl and FunctionTemplateDecl are
|
||||
// shared, if the FunctionTemplateDecl is a deduction guide for the class.
|
||||
// At import the ClassTemplateDecl object is always created first (FIXME: is
|
||||
// this really true?) because the dependency, then the FunctionTemplateDecl.
|
||||
// The DeclContext of the template parameters is changed when the
|
||||
// FunctionTemplateDecl is created, but was set already when the class
|
||||
// template was created. So here it is not the TU (default value) any more.
|
||||
// FIXME: The DeclContext of the parameters is now set finally to the
|
||||
// CXXDeductionGuideDecl object that was imported later. This may not be the
|
||||
// same that is in the original AST, specially if there are multiple deduction
|
||||
// guides.
|
||||
DeclContext *OldParamDC = nullptr;
|
||||
if (Params->size() > 0)
|
||||
OldParamDC = Params->getParam(0)->getDeclContext();
|
||||
// At creation of the template the template parameters are "adopted"
|
||||
// (DeclContext is changed). After this possible change the lookup table
|
||||
// must be updated.
|
||||
// At deduction guides the DeclContext of the template parameters may be
|
||||
// different from what we would expect, it may be the class template, or a
|
||||
// probably different CXXDeductionGuideDecl. This may come from the fact that
|
||||
// the template parameter objects may be shared between deduction guides or
|
||||
// the class template, and at creation of multiple FunctionTemplateDecl
|
||||
// objects (for deduction guides) the same parameters are re-used. The
|
||||
// "adoption" happens multiple times with different parent, even recursively
|
||||
// for TemplateTemplateParmDecl. The same happens at import when the
|
||||
// FunctionTemplateDecl objects are created, but in different order.
|
||||
// In this way the DeclContext of these template parameters is not necessarily
|
||||
// the same as in the "from" context.
|
||||
SmallVector<DeclContext *, 2> OldParamDC;
|
||||
OldParamDC.reserve(Params->size());
|
||||
llvm::transform(*Params, std::back_inserter(OldParamDC),
|
||||
[](NamedDecl *ND) { return ND->getDeclContext(); });
|
||||
|
||||
FunctionTemplateDecl *ToFunc;
|
||||
if (GetImportedOrCreateDecl(ToFunc, D, Importer.getToContext(), DC, Loc, Name,
|
||||
@ -6091,7 +6107,12 @@ ASTNodeImporter::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
|
||||
ToFunc->setAccess(D->getAccess());
|
||||
ToFunc->setLexicalDeclContext(LexicalDC);
|
||||
LexicalDC->addDeclInternal(ToFunc);
|
||||
updateLookupTableForTemplateParameters(*Params, OldParamDC);
|
||||
|
||||
ASTImporterLookupTable *LT = Importer.SharedState->getLookupTable();
|
||||
if (LT && !OldParamDC.empty()) {
|
||||
for (unsigned int I = 0; I < OldParamDC.size(); ++I)
|
||||
LT->updateForced(Params->getParam(I), OldParamDC[I]);
|
||||
}
|
||||
|
||||
if (FoundByLookup) {
|
||||
auto *Recent =
|
||||
|
@ -140,6 +140,11 @@ void ASTImporterLookupTable::update(NamedDecl *ND, DeclContext *OldDC) {
|
||||
add(ND);
|
||||
}
|
||||
|
||||
void ASTImporterLookupTable::updateForced(NamedDecl *ND, DeclContext *OldDC) {
|
||||
LookupTable[OldDC][ND->getDeclName()].remove(ND);
|
||||
add(ND);
|
||||
}
|
||||
|
||||
ASTImporterLookupTable::LookupResult
|
||||
ASTImporterLookupTable::lookup(DeclContext *DC, DeclarationName Name) const {
|
||||
auto DCI = LookupTable.find(DC->getPrimaryContext());
|
||||
|
@ -945,6 +945,12 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
|
||||
return false;
|
||||
break;
|
||||
|
||||
case Type::Using:
|
||||
if (!IsStructurallyEquivalent(Context, cast<UsingType>(T1)->getFoundDecl(),
|
||||
cast<UsingType>(T2)->getFoundDecl()))
|
||||
return false;
|
||||
break;
|
||||
|
||||
case Type::Typedef:
|
||||
if (!IsStructurallyEquivalent(Context, cast<TypedefType>(T1)->getDecl(),
|
||||
cast<TypedefType>(T2)->getDecl()))
|
||||
@ -1205,18 +1211,18 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
|
||||
cast<PipeType>(T2)->getElementType()))
|
||||
return false;
|
||||
break;
|
||||
case Type::ExtInt: {
|
||||
const auto *Int1 = cast<ExtIntType>(T1);
|
||||
const auto *Int2 = cast<ExtIntType>(T2);
|
||||
case Type::BitInt: {
|
||||
const auto *Int1 = cast<BitIntType>(T1);
|
||||
const auto *Int2 = cast<BitIntType>(T2);
|
||||
|
||||
if (Int1->isUnsigned() != Int2->isUnsigned() ||
|
||||
Int1->getNumBits() != Int2->getNumBits())
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
case Type::DependentExtInt: {
|
||||
const auto *Int1 = cast<DependentExtIntType>(T1);
|
||||
const auto *Int2 = cast<DependentExtIntType>(T2);
|
||||
case Type::DependentBitInt: {
|
||||
const auto *Int1 = cast<DependentBitIntType>(T1);
|
||||
const auto *Int2 = cast<DependentBitIntType>(T2);
|
||||
|
||||
if (Int1->isUnsigned() != Int2->isUnsigned() ||
|
||||
!IsStructurallyEquivalent(Context, Int1->getNumBitsExpr(),
|
||||
|
@ -60,7 +60,7 @@ std::string LoopHintAttr::getValueString(const PrintingPolicy &Policy) const {
|
||||
else
|
||||
OS << "disable";
|
||||
OS << ")";
|
||||
return OS.str();
|
||||
return ValueName;
|
||||
}
|
||||
|
||||
// Return a string suitable for identifying this attribute in diagnostics.
|
||||
|
@ -108,12 +108,7 @@ Comment::child_iterator Comment::child_end() const {
|
||||
}
|
||||
|
||||
bool TextComment::isWhitespaceNoCache() const {
|
||||
for (StringRef::const_iterator I = Text.begin(), E = Text.end();
|
||||
I != E; ++I) {
|
||||
if (!clang::isWhitespace(*I))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return llvm::all_of(Text, clang::isWhitespace);
|
||||
}
|
||||
|
||||
bool ParagraphComment::isWhitespaceNoCache() const {
|
||||
|
@ -8,15 +8,12 @@
|
||||
|
||||
#include "clang/AST/CommentBriefParser.h"
|
||||
#include "clang/AST/CommentCommandTraits.h"
|
||||
#include "clang/Basic/CharInfo.h"
|
||||
|
||||
namespace clang {
|
||||
namespace comments {
|
||||
|
||||
namespace {
|
||||
inline bool isWhitespace(char C) {
|
||||
return C == ' ' || C == '\n' || C == '\r' ||
|
||||
C == '\t' || C == '\f' || C == '\v';
|
||||
}
|
||||
|
||||
/// Convert all whitespace into spaces, remove leading and trailing spaces,
|
||||
/// compress multiple spaces into one.
|
||||
@ -26,12 +23,11 @@ void cleanupBrief(std::string &S) {
|
||||
for (std::string::iterator I = S.begin(), E = S.end();
|
||||
I != E; ++I) {
|
||||
const char C = *I;
|
||||
if (isWhitespace(C)) {
|
||||
if (clang::isWhitespace(C)) {
|
||||
if (!PrevWasSpace) {
|
||||
*O++ = ' ';
|
||||
PrevWasSpace = true;
|
||||
}
|
||||
continue;
|
||||
} else {
|
||||
*O++ = C;
|
||||
PrevWasSpace = false;
|
||||
@ -44,12 +40,7 @@ void cleanupBrief(std::string &S) {
|
||||
}
|
||||
|
||||
bool isWhitespace(StringRef Text) {
|
||||
for (StringRef::const_iterator I = Text.begin(), E = Text.end();
|
||||
I != E; ++I) {
|
||||
if (!isWhitespace(*I))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return llvm::all_of(Text, clang::isWhitespace);
|
||||
}
|
||||
} // unnamed namespace
|
||||
|
||||
|
@ -604,8 +604,14 @@ static LinkageInfo getExternalLinkageFor(const NamedDecl *D) {
|
||||
// - A name declared at namespace scope that does not have internal linkage
|
||||
// by the previous rules and that is introduced by a non-exported
|
||||
// declaration has module linkage.
|
||||
if (isInModulePurview(D) && !isExportedFromModuleInterfaceUnit(
|
||||
cast<NamedDecl>(D->getCanonicalDecl())))
|
||||
//
|
||||
// [basic.namespace.general]/p2
|
||||
// A namespace is never attached to a named module and never has a name with
|
||||
// module linkage.
|
||||
if (isInModulePurview(D) &&
|
||||
!isExportedFromModuleInterfaceUnit(
|
||||
cast<NamedDecl>(D->getCanonicalDecl())) &&
|
||||
!isa<NamespaceDecl>(D))
|
||||
return LinkageInfo(ModuleLinkage, DefaultVisibility, false);
|
||||
|
||||
return LinkageInfo::external();
|
||||
@ -1583,7 +1589,7 @@ std::string NamedDecl::getQualifiedNameAsString() const {
|
||||
std::string QualName;
|
||||
llvm::raw_string_ostream OS(QualName);
|
||||
printQualifiedName(OS, getASTContext().getPrintingPolicy());
|
||||
return OS.str();
|
||||
return QualName;
|
||||
}
|
||||
|
||||
void NamedDecl::printQualifiedName(raw_ostream &OS) const {
|
||||
|
@ -236,7 +236,7 @@ std::string DeclarationName::getAsString() const {
|
||||
std::string Result;
|
||||
llvm::raw_string_ostream OS(Result);
|
||||
OS << *this;
|
||||
return OS.str();
|
||||
return Result;
|
||||
}
|
||||
|
||||
void *DeclarationName::getFETokenInfoSlow() const {
|
||||
@ -460,7 +460,7 @@ std::string DeclarationNameInfo::getAsString() const {
|
||||
std::string Result;
|
||||
llvm::raw_string_ostream OS(Result);
|
||||
OS << *this;
|
||||
return OS.str();
|
||||
return Result;
|
||||
}
|
||||
|
||||
raw_ostream &clang::operator<<(raw_ostream &OS, DeclarationNameInfo DNInfo) {
|
||||
|
@ -202,6 +202,23 @@ bool Expr::isKnownToHaveBooleanValue(bool Semantic) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
const ValueDecl *
|
||||
Expr::getAsBuiltinConstantDeclRef(const ASTContext &Context) const {
|
||||
Expr::EvalResult Eval;
|
||||
|
||||
if (EvaluateAsConstantExpr(Eval, Context)) {
|
||||
APValue &Value = Eval.Val;
|
||||
|
||||
if (Value.isMemberPointer())
|
||||
return Value.getMemberPointerDecl();
|
||||
|
||||
if (Value.isLValue() && Value.getLValueOffset().isZero())
|
||||
return Value.getLValueBase().dyn_cast<const ValueDecl *>();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Amusing macro metaprogramming hack: check whether a class provides
|
||||
// a more specific implementation of getExprLoc().
|
||||
//
|
||||
|
@ -1954,11 +1954,12 @@ static bool EvaluateIgnoredValue(EvalInfo &Info, const Expr *E) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Should this call expression be treated as a string literal?
|
||||
static bool IsStringLiteralCall(const CallExpr *E) {
|
||||
/// Should this call expression be treated as a constant?
|
||||
static bool IsConstantCall(const CallExpr *E) {
|
||||
unsigned Builtin = E->getBuiltinCallee();
|
||||
return (Builtin == Builtin::BI__builtin___CFStringMakeConstantString ||
|
||||
Builtin == Builtin::BI__builtin___NSStringMakeConstantString);
|
||||
Builtin == Builtin::BI__builtin___NSStringMakeConstantString ||
|
||||
Builtin == Builtin::BI__builtin_function_start);
|
||||
}
|
||||
|
||||
static bool IsGlobalLValue(APValue::LValueBase B) {
|
||||
@ -2004,7 +2005,7 @@ static bool IsGlobalLValue(APValue::LValueBase B) {
|
||||
case Expr::ObjCBoxedExprClass:
|
||||
return cast<ObjCBoxedExpr>(E)->isExpressibleAsConstantInitializer();
|
||||
case Expr::CallExprClass:
|
||||
return IsStringLiteralCall(cast<CallExpr>(E));
|
||||
return IsConstantCall(cast<CallExpr>(E));
|
||||
// For GCC compatibility, &&label has static storage duration.
|
||||
case Expr::AddrLabelExprClass:
|
||||
return true;
|
||||
@ -2931,6 +2932,11 @@ handleCompareOpForVectorHelper(const APTy &LHSValue, BinaryOperatorKind Opcode,
|
||||
break;
|
||||
}
|
||||
|
||||
// The boolean operations on these vector types use an instruction that
|
||||
// results in a mask of '-1' for the 'truth' value. Ensure that we negate 1
|
||||
// to -1 to make sure that we produce the correct value.
|
||||
Result.negate();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -8965,7 +8971,7 @@ bool PointerExprEvaluator::visitNonBuiltinCallExpr(const CallExpr *E) {
|
||||
}
|
||||
|
||||
bool PointerExprEvaluator::VisitCallExpr(const CallExpr *E) {
|
||||
if (IsStringLiteralCall(E))
|
||||
if (IsConstantCall(E))
|
||||
return Success(E);
|
||||
|
||||
if (unsigned BuiltinOp = E->getBuiltinCallee())
|
||||
@ -10182,7 +10188,8 @@ namespace {
|
||||
bool VisitInitListExpr(const InitListExpr *E);
|
||||
bool VisitUnaryImag(const UnaryOperator *E);
|
||||
bool VisitBinaryOperator(const BinaryOperator *E);
|
||||
// FIXME: Missing: unary -, unary ~, conditional operator (for GNU
|
||||
bool VisitUnaryOperator(const UnaryOperator *E);
|
||||
// FIXME: Missing: conditional operator (for GNU
|
||||
// conditional select), shufflevector, ExtVectorElementExpr
|
||||
};
|
||||
} // end anonymous namespace
|
||||
@ -10367,6 +10374,83 @@ bool VectorExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
|
||||
return Success(LHSValue, E);
|
||||
}
|
||||
|
||||
static llvm::Optional<APValue> handleVectorUnaryOperator(ASTContext &Ctx,
|
||||
QualType ResultTy,
|
||||
UnaryOperatorKind Op,
|
||||
APValue Elt) {
|
||||
switch (Op) {
|
||||
case UO_Plus:
|
||||
// Nothing to do here.
|
||||
return Elt;
|
||||
case UO_Minus:
|
||||
if (Elt.getKind() == APValue::Int) {
|
||||
Elt.getInt().negate();
|
||||
} else {
|
||||
assert(Elt.getKind() == APValue::Float &&
|
||||
"Vector can only be int or float type");
|
||||
Elt.getFloat().changeSign();
|
||||
}
|
||||
return Elt;
|
||||
case UO_Not:
|
||||
// This is only valid for integral types anyway, so we don't have to handle
|
||||
// float here.
|
||||
assert(Elt.getKind() == APValue::Int &&
|
||||
"Vector operator ~ can only be int");
|
||||
Elt.getInt().flipAllBits();
|
||||
return Elt;
|
||||
case UO_LNot: {
|
||||
if (Elt.getKind() == APValue::Int) {
|
||||
Elt.getInt() = !Elt.getInt();
|
||||
// operator ! on vectors returns -1 for 'truth', so negate it.
|
||||
Elt.getInt().negate();
|
||||
return Elt;
|
||||
}
|
||||
assert(Elt.getKind() == APValue::Float &&
|
||||
"Vector can only be int or float type");
|
||||
// Float types result in an int of the same size, but -1 for true, or 0 for
|
||||
// false.
|
||||
APSInt EltResult{Ctx.getIntWidth(ResultTy),
|
||||
ResultTy->isUnsignedIntegerType()};
|
||||
if (Elt.getFloat().isZero())
|
||||
EltResult.setAllBits();
|
||||
else
|
||||
EltResult.clearAllBits();
|
||||
|
||||
return APValue{EltResult};
|
||||
}
|
||||
default:
|
||||
// FIXME: Implement the rest of the unary operators.
|
||||
return llvm::None;
|
||||
}
|
||||
}
|
||||
|
||||
bool VectorExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) {
|
||||
Expr *SubExpr = E->getSubExpr();
|
||||
const auto *VD = SubExpr->getType()->castAs<VectorType>();
|
||||
// This result element type differs in the case of negating a floating point
|
||||
// vector, since the result type is the a vector of the equivilant sized
|
||||
// integer.
|
||||
const QualType ResultEltTy = VD->getElementType();
|
||||
UnaryOperatorKind Op = E->getOpcode();
|
||||
|
||||
APValue SubExprValue;
|
||||
if (!Evaluate(SubExprValue, Info, SubExpr))
|
||||
return false;
|
||||
|
||||
assert(SubExprValue.getVectorLength() == VD->getNumElements() &&
|
||||
"Vector length doesn't match type?");
|
||||
|
||||
SmallVector<APValue, 4> ResultElements;
|
||||
for (unsigned EltNum = 0; EltNum < VD->getNumElements(); ++EltNum) {
|
||||
llvm::Optional<APValue> Elt = handleVectorUnaryOperator(
|
||||
Info.Ctx, ResultEltTy, Op, SubExprValue.getVectorElt(EltNum));
|
||||
if (!Elt)
|
||||
return false;
|
||||
ResultElements.push_back(*Elt);
|
||||
}
|
||||
return Success(APValue(ResultElements.data(), ResultElements.size()), E);
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Array Evaluation
|
||||
//===----------------------------------------------------------------------===//
|
||||
@ -11080,7 +11164,7 @@ EvaluateBuiltinClassifyType(QualType T, const LangOptions &LangOpts) {
|
||||
case Type::ObjCInterface:
|
||||
case Type::ObjCObjectPointer:
|
||||
case Type::Pipe:
|
||||
case Type::ExtInt:
|
||||
case Type::BitInt:
|
||||
// GCC classifies vectors as None. We follow its lead and classify all
|
||||
// other types that don't fit into the regular classification the same way.
|
||||
return GCCTypeClass::None;
|
||||
|
@ -2263,8 +2263,8 @@ bool CXXNameMangler::mangleUnresolvedTypeOrSimpleId(QualType Ty,
|
||||
case Type::Atomic:
|
||||
case Type::Pipe:
|
||||
case Type::MacroQualified:
|
||||
case Type::ExtInt:
|
||||
case Type::DependentExtInt:
|
||||
case Type::BitInt:
|
||||
case Type::DependentBitInt:
|
||||
llvm_unreachable("type is illegal as a nested name specifier");
|
||||
|
||||
case Type::SubstTemplateTypeParmPack:
|
||||
@ -2380,6 +2380,9 @@ bool CXXNameMangler::mangleUnresolvedTypeOrSimpleId(QualType Ty,
|
||||
break;
|
||||
}
|
||||
|
||||
case Type::Using:
|
||||
return mangleUnresolvedTypeOrSimpleId(cast<UsingType>(Ty)->desugar(),
|
||||
Prefix);
|
||||
case Type::Elaborated:
|
||||
return mangleUnresolvedTypeOrSimpleId(
|
||||
cast<ElaboratedType>(Ty)->getNamedType(), Prefix);
|
||||
@ -3967,26 +3970,20 @@ void CXXNameMangler::mangleType(const PipeType *T) {
|
||||
Out << "8ocl_pipe";
|
||||
}
|
||||
|
||||
void CXXNameMangler::mangleType(const ExtIntType *T) {
|
||||
Out << "U7_ExtInt";
|
||||
llvm::APSInt BW(32, true);
|
||||
BW = T->getNumBits();
|
||||
TemplateArgument TA(Context.getASTContext(), BW, getASTContext().IntTy);
|
||||
mangleTemplateArgs(TemplateName(), &TA, 1);
|
||||
if (T->isUnsigned())
|
||||
Out << "j";
|
||||
else
|
||||
Out << "i";
|
||||
void CXXNameMangler::mangleType(const BitIntType *T) {
|
||||
// 5.1.5.2 Builtin types
|
||||
// <type> ::= DB <number | instantiation-dependent expression> _
|
||||
// ::= DU <number | instantiation-dependent expression> _
|
||||
Out << "D" << (T->isUnsigned() ? "U" : "B") << T->getNumBits() << "_";
|
||||
}
|
||||
|
||||
void CXXNameMangler::mangleType(const DependentExtIntType *T) {
|
||||
Out << "U7_ExtInt";
|
||||
TemplateArgument TA(T->getNumBitsExpr());
|
||||
mangleTemplateArgs(TemplateName(), &TA, 1);
|
||||
if (T->isUnsigned())
|
||||
Out << "j";
|
||||
else
|
||||
Out << "i";
|
||||
void CXXNameMangler::mangleType(const DependentBitIntType *T) {
|
||||
// 5.1.5.2 Builtin types
|
||||
// <type> ::= DB <number | instantiation-dependent expression> _
|
||||
// ::= DU <number | instantiation-dependent expression> _
|
||||
Out << "D" << (T->isUnsigned() ? "U" : "B");
|
||||
mangleExpression(T->getNumBitsExpr());
|
||||
Out << "_";
|
||||
}
|
||||
|
||||
void CXXNameMangler::mangleIntegerLiteral(QualType T,
|
||||
|
@ -744,12 +744,19 @@ void JSONNodeDumper::VisitNamedDecl(const NamedDecl *ND) {
|
||||
JOS.attribute("name", ND->getNameAsString());
|
||||
// FIXME: There are likely other contexts in which it makes no sense to ask
|
||||
// for a mangled name.
|
||||
if (!isa<RequiresExprBodyDecl>(ND->getDeclContext())) {
|
||||
if (isa<RequiresExprBodyDecl>(ND->getDeclContext()))
|
||||
return;
|
||||
|
||||
// Mangled names are not meaningful for locals, and may not be well-defined
|
||||
// in the case of VLAs.
|
||||
auto *VD = dyn_cast<VarDecl>(ND);
|
||||
if (VD && VD->hasLocalStorage())
|
||||
return;
|
||||
|
||||
std::string MangledName = ASTNameGen.getName(ND);
|
||||
if (!MangledName.empty())
|
||||
JOS.attribute("mangledName", MangledName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void JSONNodeDumper::VisitTypedefDecl(const TypedefDecl *TD) {
|
||||
|
@ -3365,26 +3365,26 @@ void MicrosoftMangleContextImpl::mangleCXXName(GlobalDecl GD,
|
||||
return Mangler.mangle(GD);
|
||||
}
|
||||
|
||||
void MicrosoftCXXNameMangler::mangleType(const ExtIntType *T, Qualifiers,
|
||||
void MicrosoftCXXNameMangler::mangleType(const BitIntType *T, Qualifiers,
|
||||
SourceRange Range) {
|
||||
llvm::SmallString<64> TemplateMangling;
|
||||
llvm::raw_svector_ostream Stream(TemplateMangling);
|
||||
MicrosoftCXXNameMangler Extra(Context, Stream);
|
||||
Stream << "?$";
|
||||
if (T->isUnsigned())
|
||||
Extra.mangleSourceName("_UExtInt");
|
||||
Extra.mangleSourceName("_UBitInt");
|
||||
else
|
||||
Extra.mangleSourceName("_ExtInt");
|
||||
Extra.mangleSourceName("_BitInt");
|
||||
Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(T->getNumBits()));
|
||||
|
||||
mangleArtificialTagType(TTK_Struct, TemplateMangling, {"__clang"});
|
||||
}
|
||||
|
||||
void MicrosoftCXXNameMangler::mangleType(const DependentExtIntType *T,
|
||||
void MicrosoftCXXNameMangler::mangleType(const DependentBitIntType *T,
|
||||
Qualifiers, SourceRange Range) {
|
||||
DiagnosticsEngine &Diags = Context.getDiags();
|
||||
unsigned DiagID = Diags.getCustomDiagID(
|
||||
DiagnosticsEngine::Error, "cannot mangle this DependentExtInt type yet");
|
||||
DiagnosticsEngine::Error, "cannot mangle this DependentBitInt type yet");
|
||||
Diags.Report(Range.getBegin(), DiagID) << Range;
|
||||
}
|
||||
|
||||
|
@ -126,6 +126,7 @@ const OMPClauseWithPreInit *OMPClauseWithPreInit::get(const OMPClause *C) {
|
||||
case OMPC_write:
|
||||
case OMPC_update:
|
||||
case OMPC_capture:
|
||||
case OMPC_compare:
|
||||
case OMPC_seq_cst:
|
||||
case OMPC_acq_rel:
|
||||
case OMPC_acquire:
|
||||
@ -217,6 +218,7 @@ const OMPClauseWithPostUpdate *OMPClauseWithPostUpdate::get(const OMPClause *C)
|
||||
case OMPC_write:
|
||||
case OMPC_update:
|
||||
case OMPC_capture:
|
||||
case OMPC_compare:
|
||||
case OMPC_seq_cst:
|
||||
case OMPC_acq_rel:
|
||||
case OMPC_acquire:
|
||||
@ -1792,6 +1794,10 @@ void OMPClausePrinter::VisitOMPCaptureClause(OMPCaptureClause *) {
|
||||
OS << "capture";
|
||||
}
|
||||
|
||||
void OMPClausePrinter::VisitOMPCompareClause(OMPCompareClause *) {
|
||||
OS << "compare";
|
||||
}
|
||||
|
||||
void OMPClausePrinter::VisitOMPSeqCstClause(OMPSeqCstClause *) {
|
||||
OS << "seq_cst";
|
||||
}
|
||||
@ -2454,7 +2460,7 @@ std::string OMPTraitInfo::getMangledName() const {
|
||||
Property.RawString);
|
||||
}
|
||||
}
|
||||
return OS.str();
|
||||
return MangledName;
|
||||
}
|
||||
|
||||
OMPTraitInfo::OMPTraitInfo(StringRef MangledName) {
|
||||
|
@ -133,8 +133,7 @@ void ParentMap::setParent(const Stmt *S, const Stmt *Parent) {
|
||||
|
||||
Stmt* ParentMap::getParent(Stmt* S) const {
|
||||
MapTy* M = (MapTy*) Impl;
|
||||
MapTy::iterator I = M->find(S);
|
||||
return I == M->end() ? nullptr : I->second;
|
||||
return M->lookup(S);
|
||||
}
|
||||
|
||||
Stmt *ParentMap::getParentIgnoreParens(Stmt *S) const {
|
||||
|
@ -418,6 +418,13 @@ QualType getFullyQualifiedType(QualType QT, const ASTContext &Ctx,
|
||||
return QT;
|
||||
}
|
||||
|
||||
// We don't consider the alias introduced by `using a::X` as a new type.
|
||||
// The qualified name is still a::X.
|
||||
if (isa<UsingType>(QT.getTypePtr())) {
|
||||
return getFullyQualifiedType(QT.getSingleStepDesugaredType(Ctx), Ctx,
|
||||
WithGlobalNsPrefix);
|
||||
}
|
||||
|
||||
// Remove the part of the type related to the type being a template
|
||||
// parameter (we won't report it as part of the 'type name' and it
|
||||
// is actually make the code below to be more complex (to handle
|
||||
|
@ -551,6 +551,8 @@ void OMPClauseProfiler::VisitOMPUpdateClause(const OMPUpdateClause *) {}
|
||||
|
||||
void OMPClauseProfiler::VisitOMPCaptureClause(const OMPCaptureClause *) {}
|
||||
|
||||
void OMPClauseProfiler::VisitOMPCompareClause(const OMPCompareClause *) {}
|
||||
|
||||
void OMPClauseProfiler::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
|
||||
|
||||
void OMPClauseProfiler::VisitOMPAcqRelClause(const OMPAcqRelClause *) {}
|
||||
|
@ -1534,6 +1534,10 @@ void TextNodeDumper::VisitUnresolvedUsingType(const UnresolvedUsingType *T) {
|
||||
dumpDeclRef(T->getDecl());
|
||||
}
|
||||
|
||||
void TextNodeDumper::VisitUsingType(const UsingType *T) {
|
||||
dumpDeclRef(T->getFoundDecl());
|
||||
}
|
||||
|
||||
void TextNodeDumper::VisitTypedefType(const TypedefType *T) {
|
||||
dumpDeclRef(T->getDecl());
|
||||
}
|
||||
|
@ -338,25 +338,25 @@ VectorType::VectorType(TypeClass tc, QualType vecType, unsigned nElements,
|
||||
VectorTypeBits.NumElements = nElements;
|
||||
}
|
||||
|
||||
ExtIntType::ExtIntType(bool IsUnsigned, unsigned NumBits)
|
||||
: Type(ExtInt, QualType{}, TypeDependence::None), IsUnsigned(IsUnsigned),
|
||||
BitIntType::BitIntType(bool IsUnsigned, unsigned NumBits)
|
||||
: Type(BitInt, QualType{}, TypeDependence::None), IsUnsigned(IsUnsigned),
|
||||
NumBits(NumBits) {}
|
||||
|
||||
DependentExtIntType::DependentExtIntType(const ASTContext &Context,
|
||||
DependentBitIntType::DependentBitIntType(const ASTContext &Context,
|
||||
bool IsUnsigned, Expr *NumBitsExpr)
|
||||
: Type(DependentExtInt, QualType{},
|
||||
: Type(DependentBitInt, QualType{},
|
||||
toTypeDependence(NumBitsExpr->getDependence())),
|
||||
Context(Context), ExprAndUnsigned(NumBitsExpr, IsUnsigned) {}
|
||||
|
||||
bool DependentExtIntType::isUnsigned() const {
|
||||
bool DependentBitIntType::isUnsigned() const {
|
||||
return ExprAndUnsigned.getInt();
|
||||
}
|
||||
|
||||
clang::Expr *DependentExtIntType::getNumBitsExpr() const {
|
||||
clang::Expr *DependentBitIntType::getNumBitsExpr() const {
|
||||
return ExprAndUnsigned.getPointer();
|
||||
}
|
||||
|
||||
void DependentExtIntType::Profile(llvm::FoldingSetNodeID &ID,
|
||||
void DependentBitIntType::Profile(llvm::FoldingSetNodeID &ID,
|
||||
const ASTContext &Context, bool IsUnsigned,
|
||||
Expr *NumBitsExpr) {
|
||||
ID.AddBoolean(IsUnsigned);
|
||||
@ -1932,7 +1932,7 @@ bool Type::isIntegralType(const ASTContext &Ctx) const {
|
||||
if (const auto *ET = dyn_cast<EnumType>(CanonicalType))
|
||||
return ET->getDecl()->isComplete();
|
||||
|
||||
return isExtIntType();
|
||||
return isBitIntType();
|
||||
}
|
||||
|
||||
bool Type::isIntegralOrUnscopedEnumerationType() const {
|
||||
@ -1940,7 +1940,7 @@ bool Type::isIntegralOrUnscopedEnumerationType() const {
|
||||
return BT->getKind() >= BuiltinType::Bool &&
|
||||
BT->getKind() <= BuiltinType::Int128;
|
||||
|
||||
if (isExtIntType())
|
||||
if (isBitIntType())
|
||||
return true;
|
||||
|
||||
return isUnscopedEnumerationType();
|
||||
@ -2023,7 +2023,9 @@ bool Type::isSignedIntegerType() const {
|
||||
return ET->getDecl()->getIntegerType()->isSignedIntegerType();
|
||||
}
|
||||
|
||||
if (const ExtIntType *IT = dyn_cast<ExtIntType>(CanonicalType))
|
||||
if (const auto *IT = dyn_cast<BitIntType>(CanonicalType))
|
||||
return IT->isSigned();
|
||||
if (const auto *IT = dyn_cast<DependentBitIntType>(CanonicalType))
|
||||
return IT->isSigned();
|
||||
|
||||
return false;
|
||||
@ -2040,9 +2042,10 @@ bool Type::isSignedIntegerOrEnumerationType() const {
|
||||
return ET->getDecl()->getIntegerType()->isSignedIntegerType();
|
||||
}
|
||||
|
||||
if (const ExtIntType *IT = dyn_cast<ExtIntType>(CanonicalType))
|
||||
if (const auto *IT = dyn_cast<BitIntType>(CanonicalType))
|
||||
return IT->isSigned();
|
||||
if (const auto *IT = dyn_cast<DependentBitIntType>(CanonicalType))
|
||||
return IT->isSigned();
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
@ -2070,7 +2073,9 @@ bool Type::isUnsignedIntegerType() const {
|
||||
return ET->getDecl()->getIntegerType()->isUnsignedIntegerType();
|
||||
}
|
||||
|
||||
if (const ExtIntType *IT = dyn_cast<ExtIntType>(CanonicalType))
|
||||
if (const auto *IT = dyn_cast<BitIntType>(CanonicalType))
|
||||
return IT->isUnsigned();
|
||||
if (const auto *IT = dyn_cast<DependentBitIntType>(CanonicalType))
|
||||
return IT->isUnsigned();
|
||||
|
||||
return false;
|
||||
@ -2087,7 +2092,9 @@ bool Type::isUnsignedIntegerOrEnumerationType() const {
|
||||
return ET->getDecl()->getIntegerType()->isUnsignedIntegerType();
|
||||
}
|
||||
|
||||
if (const ExtIntType *IT = dyn_cast<ExtIntType>(CanonicalType))
|
||||
if (const auto *IT = dyn_cast<BitIntType>(CanonicalType))
|
||||
return IT->isUnsigned();
|
||||
if (const auto *IT = dyn_cast<DependentBitIntType>(CanonicalType))
|
||||
return IT->isUnsigned();
|
||||
|
||||
return false;
|
||||
@ -2129,7 +2136,7 @@ bool Type::isRealType() const {
|
||||
BT->getKind() <= BuiltinType::Ibm128;
|
||||
if (const auto *ET = dyn_cast<EnumType>(CanonicalType))
|
||||
return ET->getDecl()->isComplete() && !ET->getDecl()->isScoped();
|
||||
return isExtIntType();
|
||||
return isBitIntType();
|
||||
}
|
||||
|
||||
bool Type::isArithmeticType() const {
|
||||
@ -2145,7 +2152,7 @@ bool Type::isArithmeticType() const {
|
||||
// false for scoped enumerations since that will disable any
|
||||
// unwanted implicit conversions.
|
||||
return !ET->getDecl()->isScoped() && ET->getDecl()->isComplete();
|
||||
return isa<ComplexType>(CanonicalType) || isExtIntType();
|
||||
return isa<ComplexType>(CanonicalType) || isBitIntType();
|
||||
}
|
||||
|
||||
Type::ScalarTypeKind Type::getScalarTypeKind() const {
|
||||
@ -2174,7 +2181,7 @@ Type::ScalarTypeKind Type::getScalarTypeKind() const {
|
||||
if (CT->getElementType()->isRealFloatingType())
|
||||
return STK_FloatingComplex;
|
||||
return STK_IntegralComplex;
|
||||
} else if (isExtIntType()) {
|
||||
} else if (isBitIntType()) {
|
||||
return STK_Integral;
|
||||
}
|
||||
|
||||
@ -2381,7 +2388,7 @@ bool QualType::isCXX98PODType(const ASTContext &Context) const {
|
||||
case Type::MemberPointer:
|
||||
case Type::Vector:
|
||||
case Type::ExtVector:
|
||||
case Type::ExtInt:
|
||||
case Type::BitInt:
|
||||
return true;
|
||||
|
||||
case Type::Enum:
|
||||
@ -3400,6 +3407,17 @@ QualType TypedefType::desugar() const {
|
||||
return getDecl()->getUnderlyingType();
|
||||
}
|
||||
|
||||
UsingType::UsingType(const UsingShadowDecl *Found, QualType Underlying,
|
||||
QualType Canon)
|
||||
: Type(Using, Canon, Underlying->getDependence()),
|
||||
Found(const_cast<UsingShadowDecl *>(Found)) {
|
||||
assert(Underlying == getUnderlyingType());
|
||||
}
|
||||
|
||||
QualType UsingType::getUnderlyingType() const {
|
||||
return QualType(cast<TypeDecl>(Found->getTargetDecl())->getTypeForDecl(), 0);
|
||||
}
|
||||
|
||||
QualType MacroQualifiedType::desugar() const { return getUnderlyingType(); }
|
||||
|
||||
QualType MacroQualifiedType::getModifiedType() const {
|
||||
@ -3849,7 +3867,7 @@ static CachedProperties computeCachedProperties(const Type *T) {
|
||||
// here in error recovery.
|
||||
return CachedProperties(ExternalLinkage, false);
|
||||
|
||||
case Type::ExtInt:
|
||||
case Type::BitInt:
|
||||
case Type::Builtin:
|
||||
// C++ [basic.link]p8:
|
||||
// A type is said to have linkage if and only if:
|
||||
@ -3949,7 +3967,7 @@ LinkageInfo LinkageComputer::computeTypeLinkageInfo(const Type *T) {
|
||||
assert(T->isInstantiationDependentType());
|
||||
return LinkageInfo::external();
|
||||
|
||||
case Type::ExtInt:
|
||||
case Type::BitInt:
|
||||
case Type::Builtin:
|
||||
return LinkageInfo::external();
|
||||
|
||||
@ -4169,8 +4187,8 @@ bool Type::canHaveNullability(bool ResultIfUnknown) const {
|
||||
case Type::ObjCInterface:
|
||||
case Type::Atomic:
|
||||
case Type::Pipe:
|
||||
case Type::ExtInt:
|
||||
case Type::DependentExtInt:
|
||||
case Type::BitInt:
|
||||
case Type::DependentBitInt:
|
||||
return false;
|
||||
}
|
||||
llvm_unreachable("bad type kind!");
|
||||
|
@ -212,6 +212,7 @@ bool TypePrinter::canPrefixQualifiers(const Type *T,
|
||||
case Type::Builtin:
|
||||
case Type::Complex:
|
||||
case Type::UnresolvedUsing:
|
||||
case Type::Using:
|
||||
case Type::Typedef:
|
||||
case Type::TypeOfExpr:
|
||||
case Type::TypeOf:
|
||||
@ -232,8 +233,8 @@ bool TypePrinter::canPrefixQualifiers(const Type *T,
|
||||
case Type::ObjCInterface:
|
||||
case Type::Atomic:
|
||||
case Type::Pipe:
|
||||
case Type::ExtInt:
|
||||
case Type::DependentExtInt:
|
||||
case Type::BitInt:
|
||||
case Type::DependentBitInt:
|
||||
CanPrefixQualifiers = true;
|
||||
break;
|
||||
|
||||
@ -1046,6 +1047,21 @@ void TypePrinter::printUnresolvedUsingBefore(const UnresolvedUsingType *T,
|
||||
void TypePrinter::printUnresolvedUsingAfter(const UnresolvedUsingType *T,
|
||||
raw_ostream &OS) {}
|
||||
|
||||
void TypePrinter::printUsingBefore(const UsingType *T, raw_ostream &OS) {
|
||||
// After `namespace b { using a::X }`, is the type X within B a::X or b::X?
|
||||
//
|
||||
// - b::X is more formally correct given the UsingType model
|
||||
// - b::X makes sense if "re-exporting" a symbol in a new namespace
|
||||
// - a::X makes sense if "importing" a symbol for convenience
|
||||
//
|
||||
// The "importing" use seems much more common, so we print a::X.
|
||||
// This could be a policy option, but the right choice seems to rest more
|
||||
// with the intent of the code than the caller.
|
||||
printTypeSpec(T->getFoundDecl()->getUnderlyingDecl(), OS);
|
||||
}
|
||||
|
||||
void TypePrinter::printUsingAfter(const UsingType *T, raw_ostream &OS) {}
|
||||
|
||||
void TypePrinter::printTypedefBefore(const TypedefType *T, raw_ostream &OS) {
|
||||
printTypeSpec(T->getDecl(), OS);
|
||||
}
|
||||
@ -1200,26 +1216,26 @@ void TypePrinter::printPipeBefore(const PipeType *T, raw_ostream &OS) {
|
||||
|
||||
void TypePrinter::printPipeAfter(const PipeType *T, raw_ostream &OS) {}
|
||||
|
||||
void TypePrinter::printExtIntBefore(const ExtIntType *T, raw_ostream &OS) {
|
||||
void TypePrinter::printBitIntBefore(const BitIntType *T, raw_ostream &OS) {
|
||||
if (T->isUnsigned())
|
||||
OS << "unsigned ";
|
||||
OS << "_ExtInt(" << T->getNumBits() << ")";
|
||||
OS << "_BitInt(" << T->getNumBits() << ")";
|
||||
spaceBeforePlaceHolder(OS);
|
||||
}
|
||||
|
||||
void TypePrinter::printExtIntAfter(const ExtIntType *T, raw_ostream &OS) {}
|
||||
void TypePrinter::printBitIntAfter(const BitIntType *T, raw_ostream &OS) {}
|
||||
|
||||
void TypePrinter::printDependentExtIntBefore(const DependentExtIntType *T,
|
||||
void TypePrinter::printDependentBitIntBefore(const DependentBitIntType *T,
|
||||
raw_ostream &OS) {
|
||||
if (T->isUnsigned())
|
||||
OS << "unsigned ";
|
||||
OS << "_ExtInt(";
|
||||
OS << "_BitInt(";
|
||||
T->getNumBitsExpr()->printPretty(OS, nullptr, Policy);
|
||||
OS << ")";
|
||||
spaceBeforePlaceHolder(OS);
|
||||
}
|
||||
|
||||
void TypePrinter::printDependentExtIntAfter(const DependentExtIntType *T,
|
||||
void TypePrinter::printDependentBitIntAfter(const DependentBitIntType *T,
|
||||
raw_ostream &OS) {}
|
||||
|
||||
/// Appends the given scope to the end of a string.
|
||||
|
@ -1059,6 +1059,7 @@ const AstTypeMatcher<UnaryTransformType> unaryTransformType;
|
||||
const AstTypeMatcher<RecordType> recordType;
|
||||
const AstTypeMatcher<TagType> tagType;
|
||||
const AstTypeMatcher<ElaboratedType> elaboratedType;
|
||||
const AstTypeMatcher<UsingType> usingType;
|
||||
const AstTypeMatcher<SubstTemplateTypeParmType> substTemplateTypeParmType;
|
||||
const AstTypeMatcher<TemplateTypeParmType> templateTypeParmType;
|
||||
const AstTypeMatcher<InjectedClassNameType> injectedClassNameType;
|
||||
|
@ -204,7 +204,7 @@ std::string Diagnostics::toString() const {
|
||||
std::string S;
|
||||
llvm::raw_string_ostream OS(S);
|
||||
printToStream(OS);
|
||||
return OS.str();
|
||||
return S;
|
||||
}
|
||||
|
||||
void Diagnostics::printToStreamFull(llvm::raw_ostream &OS) const {
|
||||
@ -223,7 +223,7 @@ std::string Diagnostics::toStringFull() const {
|
||||
std::string S;
|
||||
llvm::raw_string_ostream OS(S);
|
||||
printToStreamFull(OS);
|
||||
return OS.str();
|
||||
return S;
|
||||
}
|
||||
|
||||
} // namespace dynamic
|
||||
|
@ -1035,7 +1035,6 @@ class MapAnyOfBuilderDescriptor : public MatcherDescriptor {
|
||||
void getArgKinds(ASTNodeKind ThisKind, unsigned,
|
||||
std::vector<ArgKind> &ArgKinds) const override {
|
||||
ArgKinds.push_back(ArgKind::MakeNodeArg(ThisKind));
|
||||
return;
|
||||
}
|
||||
bool isConvertibleTo(ASTNodeKind Kind, unsigned *Specificity = nullptr,
|
||||
ASTNodeKind *LeastDerivedKind = nullptr) const override {
|
||||
|
@ -645,7 +645,7 @@ bool Parser::parseMatcherExpressionImpl(const TokenInfo &NameToken,
|
||||
Tokenizer->SkipNewlines();
|
||||
|
||||
{
|
||||
ScopedContextEntry SCE(this, Ctor ? *Ctor : nullptr);
|
||||
ScopedContextEntry SCE(this, Ctor.getValueOr(nullptr));
|
||||
|
||||
while (Tokenizer->nextTokenKind() != TokenInfo::TK_Eof) {
|
||||
if (Tokenizer->nextTokenKind() == TokenInfo::TK_CloseParen) {
|
||||
|
@ -228,6 +228,7 @@ RegistryMaps::RegistryMaps() {
|
||||
REGISTER_MATCHER(eachOf);
|
||||
REGISTER_MATCHER(elaboratedType);
|
||||
REGISTER_MATCHER(elaboratedTypeLoc);
|
||||
REGISTER_MATCHER(usingType);
|
||||
REGISTER_MATCHER(enumConstantDecl);
|
||||
REGISTER_MATCHER(enumDecl);
|
||||
REGISTER_MATCHER(enumType);
|
||||
|
@ -387,7 +387,7 @@ std::string AnalysisDeclContext::getFunctionName(const Decl *D) {
|
||||
OS << ' ' << OMD->getSelector().getAsString() << ']';
|
||||
}
|
||||
|
||||
return OS.str();
|
||||
return Str;
|
||||
}
|
||||
|
||||
LocationContextManager &AnalysisDeclContext::getLocationContextManager() {
|
||||
|
@ -1820,8 +1820,6 @@ void CFGBuilder::addScopesEnd(LocalScope::const_iterator B,
|
||||
|
||||
for (VarDecl *VD : llvm::reverse(DeclsWithEndedScope))
|
||||
appendScopeEnd(Block, VD, S);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/// addAutomaticObjDtors - Add to current block automatic objects destructors
|
||||
|
@ -11,15 +11,82 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "clang/Analysis/Analyses/PostOrderCFGView.h"
|
||||
#include "clang/Analysis/CFG.h"
|
||||
#include "clang/Analysis/FlowSensitive/DataflowEnvironment.h"
|
||||
#include "clang/Analysis/FlowSensitive/DataflowWorklist.h"
|
||||
#include "clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h"
|
||||
#include "llvm/ADT/None.h"
|
||||
#include "llvm/ADT/Optional.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
||||
using namespace clang;
|
||||
using namespace dataflow;
|
||||
namespace clang {
|
||||
namespace dataflow {
|
||||
|
||||
/// Computes the input state for a given basic block by joining the output
|
||||
/// states of its predecessors.
|
||||
///
|
||||
/// Requirements:
|
||||
///
|
||||
/// All predecessors of `Block` except those with loop back edges must have
|
||||
/// already been transferred. States in `BlockStates` that are set to
|
||||
/// `llvm::None` represent basic blocks that are not evaluated yet.
|
||||
static TypeErasedDataflowAnalysisState computeBlockInputState(
|
||||
std::vector<llvm::Optional<TypeErasedDataflowAnalysisState>> &BlockStates,
|
||||
const CFGBlock &Block, const Environment &InitEnv,
|
||||
TypeErasedDataflowAnalysis &Analysis) {
|
||||
// FIXME: Consider passing `Block` to `Analysis.typeErasedInitialElement()`
|
||||
// to enable building analyses like computation of dominators that initialize
|
||||
// the state of each basic block differently.
|
||||
TypeErasedDataflowAnalysisState State = {Analysis.typeErasedInitialElement(),
|
||||
InitEnv};
|
||||
for (const CFGBlock *Pred : Block.preds()) {
|
||||
// Skip if the `Block` is unreachable or control flow cannot get past it.
|
||||
if (!Pred || Pred->hasNoReturnElement())
|
||||
continue;
|
||||
|
||||
// Skip if `Pred` was not evaluated yet. This could happen if `Pred` has a
|
||||
// loop back edge to `Block`.
|
||||
const llvm::Optional<TypeErasedDataflowAnalysisState> &MaybePredState =
|
||||
BlockStates[Pred->getBlockID()];
|
||||
if (!MaybePredState.hasValue())
|
||||
continue;
|
||||
|
||||
const TypeErasedDataflowAnalysisState &PredState =
|
||||
MaybePredState.getValue();
|
||||
Analysis.joinTypeErased(State.Lattice, PredState.Lattice);
|
||||
State.Env.join(PredState.Env);
|
||||
}
|
||||
return State;
|
||||
}
|
||||
|
||||
TypeErasedDataflowAnalysisState transferBlock(
|
||||
std::vector<llvm::Optional<TypeErasedDataflowAnalysisState>> &BlockStates,
|
||||
const CFGBlock &Block, const Environment &InitEnv,
|
||||
TypeErasedDataflowAnalysis &Analysis,
|
||||
std::function<void(const CFGStmt &,
|
||||
const TypeErasedDataflowAnalysisState &)>
|
||||
HandleTransferredStmt) {
|
||||
TypeErasedDataflowAnalysisState State =
|
||||
computeBlockInputState(BlockStates, Block, InitEnv, Analysis);
|
||||
for (const CFGElement &Element : Block) {
|
||||
// FIXME: Evaluate other kinds of `CFGElement`.
|
||||
const llvm::Optional<CFGStmt> Stmt = Element.getAs<CFGStmt>();
|
||||
if (!Stmt.hasValue())
|
||||
continue;
|
||||
|
||||
// FIXME: Evaluate the statement contained in `Stmt`.
|
||||
|
||||
State.Lattice = Analysis.transferTypeErased(Stmt.getValue().getStmt(),
|
||||
State.Lattice, State.Env);
|
||||
if (HandleTransferredStmt != nullptr)
|
||||
HandleTransferredStmt(Stmt.getValue(), State);
|
||||
}
|
||||
return State;
|
||||
}
|
||||
|
||||
std::vector<llvm::Optional<TypeErasedDataflowAnalysisState>>
|
||||
runTypeErasedDataflowAnalysis(const CFG &Cfg,
|
||||
@ -29,7 +96,59 @@ runTypeErasedDataflowAnalysis(const CFG &Cfg,
|
||||
// are specified in the header. This could be done by remembering
|
||||
// what options were used to build `Cfg` and asserting on them here.
|
||||
|
||||
// FIXME: Implement work list-based algorithm to compute the fixed
|
||||
// point of `Analysis::transform` for every basic block in `Cfg`.
|
||||
return {};
|
||||
PostOrderCFGView POV(&Cfg);
|
||||
ForwardDataflowWorklist Worklist(Cfg, &POV);
|
||||
|
||||
std::vector<llvm::Optional<TypeErasedDataflowAnalysisState>> BlockStates;
|
||||
BlockStates.resize(Cfg.size(), llvm::None);
|
||||
|
||||
// The entry basic block doesn't contain statements so it can be skipped.
|
||||
const CFGBlock &Entry = Cfg.getEntry();
|
||||
BlockStates[Entry.getBlockID()] = {Analysis.typeErasedInitialElement(),
|
||||
InitEnv};
|
||||
Worklist.enqueueSuccessors(&Entry);
|
||||
|
||||
// Bugs in lattices and transfer functions can prevent the analysis from
|
||||
// converging. To limit the damage (infinite loops) that these bugs can cause,
|
||||
// limit the number of iterations.
|
||||
// FIXME: Consider making the maximum number of iterations configurable.
|
||||
// FIXME: Set up statistics (see llvm/ADT/Statistic.h) to count average number
|
||||
// of iterations, number of functions that time out, etc.
|
||||
unsigned Iterations = 0;
|
||||
static constexpr unsigned MaxIterations = 1 << 16;
|
||||
while (const CFGBlock *Block = Worklist.dequeue()) {
|
||||
if (++Iterations > MaxIterations) {
|
||||
llvm::errs() << "Maximum number of iterations reached, giving up.\n";
|
||||
break;
|
||||
}
|
||||
|
||||
const llvm::Optional<TypeErasedDataflowAnalysisState> &OldBlockState =
|
||||
BlockStates[Block->getBlockID()];
|
||||
TypeErasedDataflowAnalysisState NewBlockState =
|
||||
transferBlock(BlockStates, *Block, InitEnv, Analysis);
|
||||
|
||||
if (OldBlockState.hasValue() &&
|
||||
Analysis.isEqualTypeErased(OldBlockState.getValue().Lattice,
|
||||
NewBlockState.Lattice) &&
|
||||
OldBlockState->Env == NewBlockState.Env) {
|
||||
// The state of `Block` didn't change after transfer so there's no need to
|
||||
// revisit its successors.
|
||||
continue;
|
||||
}
|
||||
|
||||
BlockStates[Block->getBlockID()] = std::move(NewBlockState);
|
||||
|
||||
// Do not add unreachable successor blocks to `Worklist`.
|
||||
if (Block->hasNoReturnElement())
|
||||
continue;
|
||||
|
||||
Worklist.enqueueSuccessors(Block);
|
||||
}
|
||||
// FIXME: Consider evaluating unreachable basic blocks (those that have a
|
||||
// state set to `llvm::None` at this point) to also analyze dead code.
|
||||
|
||||
return BlockStates;
|
||||
}
|
||||
|
||||
} // namespace dataflow
|
||||
} // namespace clang
|
||||
|
@ -418,7 +418,6 @@ class LocalVariableMap {
|
||||
private:
|
||||
Context::Factory ContextFactory;
|
||||
std::vector<VarDefinition> VarDefinitions;
|
||||
std::vector<unsigned> CtxIndices;
|
||||
std::vector<std::pair<const Stmt *, Context>> SavedContexts;
|
||||
|
||||
public:
|
||||
@ -731,8 +730,6 @@ void LocalVariableMap::traverseCFG(CFG *CFGraph,
|
||||
std::vector<CFGBlockInfo> &BlockInfo) {
|
||||
PostOrderCFGView::CFGBlockSet VisitedBlocks(CFGraph);
|
||||
|
||||
CtxIndices.resize(CFGraph->getNumBlockIDs());
|
||||
|
||||
for (const auto *CurrBlock : *SortedGraph) {
|
||||
unsigned CurrBlockID = CurrBlock->getBlockID();
|
||||
CFGBlockInfo *CurrBlockInfo = &BlockInfo[CurrBlockID];
|
||||
|
@ -591,8 +591,8 @@ class TransferFunctions : public StmtVisitor<TransferFunctions> {
|
||||
|
||||
if (AtPredExit == MayUninitialized) {
|
||||
// If the predecessor's terminator is an "asm goto" that initializes
|
||||
// the variable, then it won't be counted as "initialized" on the
|
||||
// non-fallthrough paths.
|
||||
// the variable, then don't count it as "initialized" on the indirect
|
||||
// paths.
|
||||
CFGTerminator term = Pred->getTerminator();
|
||||
if (const auto *as = dyn_cast_or_null<GCCAsmStmt>(term.getStmt())) {
|
||||
const CFGBlock *fallthrough = *Pred->succ_begin();
|
||||
@ -810,13 +810,22 @@ void TransferFunctions::VisitGCCAsmStmt(GCCAsmStmt *as) {
|
||||
if (!as->isAsmGoto())
|
||||
return;
|
||||
|
||||
for (const Expr *o : as->outputs())
|
||||
if (const VarDecl *VD = findVar(o).getDecl())
|
||||
ASTContext &C = ac.getASTContext();
|
||||
for (const Expr *O : as->outputs()) {
|
||||
const Expr *Ex = stripCasts(C, O);
|
||||
|
||||
// Strip away any unary operators. Invalid l-values are reported by other
|
||||
// semantic analysis passes.
|
||||
while (const auto *UO = dyn_cast<UnaryOperator>(Ex))
|
||||
Ex = stripCasts(C, UO->getSubExpr());
|
||||
|
||||
if (const VarDecl *VD = findVar(Ex).getDecl())
|
||||
if (vals[VD] != Initialized)
|
||||
// If the variable isn't initialized by the time we get here, then we
|
||||
// mark it as potentially uninitialized for those cases where it's used
|
||||
// on an indirect path, where it's not guaranteed to be defined.
|
||||
vals[VD] = MayUninitialized;
|
||||
}
|
||||
}
|
||||
|
||||
void TransferFunctions::VisitObjCMessageExpr(ObjCMessageExpr *ME) {
|
||||
|
@ -123,6 +123,7 @@ static const CudaArchToStringMap arch_names[] = {
|
||||
GFX(1033), // gfx1033
|
||||
GFX(1034), // gfx1034
|
||||
GFX(1035), // gfx1035
|
||||
{CudaArch::Generic, "generic", ""},
|
||||
// clang-format on
|
||||
};
|
||||
#undef SM
|
||||
|
@ -163,6 +163,7 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, StringRef Str,
|
||||
case OMPC_read:
|
||||
case OMPC_write:
|
||||
case OMPC_capture:
|
||||
case OMPC_compare:
|
||||
case OMPC_seq_cst:
|
||||
case OMPC_acq_rel:
|
||||
case OMPC_acquire:
|
||||
@ -428,6 +429,7 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind,
|
||||
case OMPC_read:
|
||||
case OMPC_write:
|
||||
case OMPC_capture:
|
||||
case OMPC_compare:
|
||||
case OMPC_seq_cst:
|
||||
case OMPC_acq_rel:
|
||||
case OMPC_acquire:
|
||||
|
@ -90,7 +90,7 @@ SourceLocation::printToString(const SourceManager &SM) const {
|
||||
std::string S;
|
||||
llvm::raw_string_ostream OS(S);
|
||||
print(OS, SM);
|
||||
return OS.str();
|
||||
return S;
|
||||
}
|
||||
|
||||
LLVM_DUMP_METHOD void SourceLocation::dump(const SourceManager &SM) const {
|
||||
@ -149,7 +149,7 @@ SourceRange::printToString(const SourceManager &SM) const {
|
||||
std::string S;
|
||||
llvm::raw_string_ostream OS(S);
|
||||
print(OS, SM);
|
||||
return OS.str();
|
||||
return S;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -307,6 +307,9 @@ void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts,
|
||||
if (FPU & SveMode)
|
||||
Builder.defineMacro("__ARM_FEATURE_SVE", "1");
|
||||
|
||||
if ((FPU & NeonMode) && (FPU & SveMode))
|
||||
Builder.defineMacro("__ARM_NEON_SVE_BRIDGE", "1");
|
||||
|
||||
if (HasSVE2)
|
||||
Builder.defineMacro("__ARM_FEATURE_SVE2", "1");
|
||||
|
||||
@ -474,10 +477,12 @@ ArrayRef<Builtin::Info> AArch64TargetInfo::getTargetBuiltins() const {
|
||||
Optional<std::pair<unsigned, unsigned>>
|
||||
AArch64TargetInfo::getVScaleRange(const LangOptions &LangOpts) const {
|
||||
if (LangOpts.VScaleMin || LangOpts.VScaleMax)
|
||||
return std::pair<unsigned, unsigned>(LangOpts.VScaleMin,
|
||||
LangOpts.VScaleMax);
|
||||
return std::pair<unsigned, unsigned>(
|
||||
LangOpts.VScaleMin ? LangOpts.VScaleMin : 1, LangOpts.VScaleMax);
|
||||
|
||||
if (hasFeature("sve"))
|
||||
return std::pair<unsigned, unsigned>(0, 16);
|
||||
return std::pair<unsigned, unsigned>(1, 16);
|
||||
|
||||
return None;
|
||||
}
|
||||
|
||||
|
@ -150,7 +150,7 @@ class LLVM_LIBRARY_VISIBILITY AArch64TargetInfo : public TargetInfo {
|
||||
const char *getBFloat16Mangling() const override { return "u6__bf16"; };
|
||||
bool hasInt128Type() const override;
|
||||
|
||||
bool hasExtIntType() const override { return true; }
|
||||
bool hasBitIntType() const override { return true; }
|
||||
};
|
||||
|
||||
class LLVM_LIBRARY_VISIBILITY AArch64leTargetInfo : public AArch64TargetInfo {
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user